From 9af6866a9d0e4b18520ac1458b0367ec4b6c979b Mon Sep 17 00:00:00 2001 From: Kacper Date: Thu, 11 Dec 2025 00:24:36 +0100 Subject: [PATCH] refactor(settings): remove empty hooks directory --- .../settings-view/appearance-section.tsx | 61 ++++ .../settings-view/cli-status-section.tsx | 304 ++++++++++++++++++ .../settings-view/danger-zone-section.tsx | 57 ++++ .../feature-defaults-section.tsx | 134 ++++++++ .../settings-view/kanban-display-section.tsx | 96 ++++++ .../keyboard-shortcuts-section.tsx | 60 ++++ .../settings-view/shared/theme-options.ts | 88 +++++ .../components/views/settings-view/types.ts | 47 +++ 8 files changed, 847 insertions(+) create mode 100644 app/src/components/views/settings-view/appearance-section.tsx create mode 100644 app/src/components/views/settings-view/cli-status-section.tsx create mode 100644 app/src/components/views/settings-view/danger-zone-section.tsx create mode 100644 app/src/components/views/settings-view/feature-defaults-section.tsx create mode 100644 app/src/components/views/settings-view/kanban-display-section.tsx create mode 100644 app/src/components/views/settings-view/keyboard-shortcuts-section.tsx create mode 100644 app/src/components/views/settings-view/shared/theme-options.ts create mode 100644 app/src/components/views/settings-view/types.ts diff --git a/app/src/components/views/settings-view/appearance-section.tsx b/app/src/components/views/settings-view/appearance-section.tsx new file mode 100644 index 00000000..ed60b135 --- /dev/null +++ b/app/src/components/views/settings-view/appearance-section.tsx @@ -0,0 +1,61 @@ +import { Button } from "@/components/ui/button"; +import { Label } from "@/components/ui/label"; +import { Palette } from "lucide-react"; +import { themeOptions } from "./shared/theme-options"; +import type { Theme, Project } from "./types"; + +interface AppearanceSectionProps { + effectiveTheme: Theme; + currentProject: Project | null; + onThemeChange: (theme: Theme) => void; +} + +export function AppearanceSection({ + effectiveTheme, + currentProject, + onThemeChange, +}: AppearanceSectionProps) { + return ( +
+
+
+ +

Appearance

+
+

+ Customize the look and feel of your application. +

+
+
+
+ +
+ {themeOptions.map(({ value, label, Icon, testId }) => { + const isActive = effectiveTheme === value; + return ( + + ); + })} +
+
+
+
+ ); +} diff --git a/app/src/components/views/settings-view/cli-status-section.tsx b/app/src/components/views/settings-view/cli-status-section.tsx new file mode 100644 index 00000000..050453b8 --- /dev/null +++ b/app/src/components/views/settings-view/cli-status-section.tsx @@ -0,0 +1,304 @@ +import { Button } from "@/components/ui/button"; +import { + Terminal, + CheckCircle2, + AlertCircle, + RefreshCw, + Atom, +} from "lucide-react"; +import type { CliStatus } from "./types"; + +interface CliStatusProps { + status: CliStatus | null; + isChecking: boolean; + onRefresh: () => void; +} + +export function ClaudeCliStatus({ + status, + isChecking, + onRefresh, +}: CliStatusProps) { + if (!status) return null; + + return ( +
+
+
+
+ +

+ Claude Code CLI +

+
+ +
+

+ Claude Code CLI provides better performance for long-running tasks, + especially with ultrathink. +

+
+
+ {status.success && status.status === "installed" ? ( +
+
+ +
+

+ Claude Code CLI Installed +

+
+ {status.method && ( +

+ Method: {status.method} +

+ )} + {status.version && ( +

+ Version:{" "} + {status.version} +

+ )} + {status.path && ( +

+ Path:{" "} + + {status.path} + +

+ )} +
+
+
+ {status.recommendation && ( +

+ {status.recommendation} +

+ )} +
+ ) : ( +
+
+ +
+

+ Claude Code CLI Not Detected +

+

+ {status.recommendation || + "Consider installing Claude Code CLI for optimal performance with ultrathink."} +

+
+
+ {status.installCommands && ( +
+

+ Installation Commands: +

+
+ {status.installCommands.npm && ( +
+

npm:

+ + {status.installCommands.npm} + +
+ )} + {status.installCommands.macos && ( +
+

+ macOS/Linux: +

+ + {status.installCommands.macos} + +
+ )} + {status.installCommands.windows && ( +
+

+ Windows (PowerShell): +

+ + {status.installCommands.windows} + +
+ )} +
+
+ )} +
+ )} +
+
+ ); +} + +export function CodexCliStatus({ + status, + isChecking, + onRefresh, +}: CliStatusProps) { + if (!status) return null; + + return ( +
+
+
+
+ +

+ OpenAI Codex CLI +

+
+ +
+

+ Codex CLI enables GPT-5.1 Codex models for autonomous coding tasks. +

+
+
+ {status.success && status.status === "installed" ? ( +
+
+ +
+

+ Codex CLI Installed +

+
+ {status.method && ( +

+ Method: {status.method} +

+ )} + {status.version && ( +

+ Version:{" "} + {status.version} +

+ )} + {status.path && ( +

+ Path:{" "} + + {status.path} + +

+ )} +
+
+
+ {status.recommendation && ( +

+ {status.recommendation} +

+ )} +
+ ) : status.status === "api_key_only" ? ( +
+
+ +
+

+ API Key Detected - CLI Not Installed +

+

+ {status.recommendation || + "OPENAI_API_KEY found but Codex CLI not installed. Install the CLI for full agentic capabilities."} +

+
+
+ {status.installCommands && ( +
+

+ Installation Commands: +

+
+ {status.installCommands.npm && ( +
+

npm:

+ + {status.installCommands.npm} + +
+ )} +
+
+ )} +
+ ) : ( +
+
+ +
+

+ Codex CLI Not Detected +

+

+ {status.recommendation || + "Install OpenAI Codex CLI to use GPT-5.1 Codex models for autonomous coding."} +

+
+
+ {status.installCommands && ( +
+

+ Installation Commands: +

+
+ {status.installCommands.npm && ( +
+

npm:

+ + {status.installCommands.npm} + +
+ )} + {status.installCommands.macos && ( +
+

+ macOS (Homebrew): +

+ + {status.installCommands.macos} + +
+ )} +
+
+ )} +
+ )} +
+
+ ); +} diff --git a/app/src/components/views/settings-view/danger-zone-section.tsx b/app/src/components/views/settings-view/danger-zone-section.tsx new file mode 100644 index 00000000..f791d763 --- /dev/null +++ b/app/src/components/views/settings-view/danger-zone-section.tsx @@ -0,0 +1,57 @@ +import { Button } from "@/components/ui/button"; +import { Trash2, Folder } from "lucide-react"; +import type { Project } from "./types"; + +interface DangerZoneSectionProps { + project: Project | null; + onDeleteClick: () => void; +} + +export function DangerZoneSection({ + project, + onDeleteClick, +}: DangerZoneSectionProps) { + if (!project) return null; + + return ( +
+
+
+ +

Danger Zone

+
+

+ Permanently remove this project from Automaker. +

+
+
+
+
+
+ +
+
+

+ {project.name} +

+

+ {project.path} +

+
+
+ +
+
+
+ ); +} diff --git a/app/src/components/views/settings-view/feature-defaults-section.tsx b/app/src/components/views/settings-view/feature-defaults-section.tsx new file mode 100644 index 00000000..e7c78582 --- /dev/null +++ b/app/src/components/views/settings-view/feature-defaults-section.tsx @@ -0,0 +1,134 @@ +import { Label } from "@/components/ui/label"; +import { Checkbox } from "@/components/ui/checkbox"; +import { FlaskConical, Settings2, TestTube, GitBranch } from "lucide-react"; + +interface FeatureDefaultsSectionProps { + showProfilesOnly: boolean; + defaultSkipTests: boolean; + useWorktrees: boolean; + onShowProfilesOnlyChange: (value: boolean) => void; + onDefaultSkipTestsChange: (value: boolean) => void; + onUseWorktreesChange: (value: boolean) => void; +} + +export function FeatureDefaultsSection({ + showProfilesOnly, + defaultSkipTests, + useWorktrees, + onShowProfilesOnlyChange, + onDefaultSkipTestsChange, + onUseWorktreesChange, +}: FeatureDefaultsSectionProps) { + return ( +
+
+
+ +

+ Feature Defaults +

+
+

+ Configure default settings for new features. +

+
+
+ {/* Profiles Only Setting */} +
+
+ + onShowProfilesOnlyChange(checked === true) + } + className="mt-0.5" + data-testid="show-profiles-only-checkbox" + /> +
+ +

+ When enabled, the Add Feature dialog will show only AI profiles + and hide advanced model tweaking options (Claude SDK, thinking + levels, and OpenAI Codex CLI). This creates a cleaner, less + overwhelming UI. You can always disable this to access advanced + settings. +

+
+
+
+ + {/* Separator */} +
+ + {/* Skip Tests Setting */} +
+
+ + onDefaultSkipTestsChange(checked === true) + } + className="mt-0.5" + data-testid="default-skip-tests-checkbox" + /> +
+ +

+ When enabled, new features will default to manual verification + instead of TDD (test-driven development). You can still override + this for individual features. +

+
+
+
+ + {/* Worktree Isolation Setting */} +
+
+ + onUseWorktreesChange(checked === true) + } + className="mt-0.5" + data-testid="use-worktrees-checkbox" + /> +
+ +

+ Creates isolated git branches for each feature. When disabled, + agents work directly in the main project directory. This feature + is experimental and may require additional setup like branch + selection and merge configuration. +

+
+
+
+
+
+ ); +} diff --git a/app/src/components/views/settings-view/kanban-display-section.tsx b/app/src/components/views/settings-view/kanban-display-section.tsx new file mode 100644 index 00000000..0f22ee3c --- /dev/null +++ b/app/src/components/views/settings-view/kanban-display-section.tsx @@ -0,0 +1,96 @@ +import { Button } from "@/components/ui/button"; +import { Label } from "@/components/ui/label"; +import { LayoutGrid, Minimize2, Square, Maximize2 } from "lucide-react"; +import type { KanbanDetailLevel } from "./types"; + +interface KanbanDisplaySectionProps { + detailLevel: KanbanDetailLevel; + onChange: (level: KanbanDetailLevel) => void; +} + +export function KanbanDisplaySection({ + detailLevel, + onChange, +}: KanbanDisplaySectionProps) { + return ( +
+
+
+ +

+ Kanban Card Display +

+
+

+ Control how much information is displayed on Kanban cards. +

+
+
+
+ +
+ + + +
+

+ Minimal: Shows only title and category +
+ Standard: Adds steps preview and progress bar +
+ Detailed: Shows all info including model, tool + calls, task list, and summaries +

+
+
+
+ ); +} diff --git a/app/src/components/views/settings-view/keyboard-shortcuts-section.tsx b/app/src/components/views/settings-view/keyboard-shortcuts-section.tsx new file mode 100644 index 00000000..2baf9320 --- /dev/null +++ b/app/src/components/views/settings-view/keyboard-shortcuts-section.tsx @@ -0,0 +1,60 @@ +import { Button } from "@/components/ui/button"; +import { Label } from "@/components/ui/label"; +import { Settings2, Keyboard } from "lucide-react"; + +interface KeyboardShortcutsSectionProps { + onOpenKeyboardMap: () => void; +} + +export function KeyboardShortcutsSection({ + onOpenKeyboardMap, +}: KeyboardShortcutsSectionProps) { + return ( +
+
+
+ +

+ Keyboard Shortcuts +

+
+

+ Customize keyboard shortcuts for navigation and actions using the + visual keyboard map. +

+
+
+ {/* Centered message directing to keyboard map */} +
+
+ +
+
+
+

+ Use the Visual Keyboard Map +

+

+ Click the "View Keyboard Map" button above to customize + your keyboard shortcuts. The visual interface shows all available + keys and lets you easily edit shortcuts with single-modifier + restrictions. +

+
+ +
+
+
+ ); +} diff --git a/app/src/components/views/settings-view/shared/theme-options.ts b/app/src/components/views/settings-view/shared/theme-options.ts new file mode 100644 index 00000000..e59da056 --- /dev/null +++ b/app/src/components/views/settings-view/shared/theme-options.ts @@ -0,0 +1,88 @@ +import { + type LucideIcon, + Atom, + Cat, + Eclipse, + Flame, + Ghost, + Moon, + Radio, + Snowflake, + Sparkles, + Sun, + Terminal, + Trees, +} from "lucide-react"; +import { Theme } from "../types"; + +export interface ThemeOption { + value: Theme; + label: string; + Icon: LucideIcon; + testId: string; +} + +export const themeOptions: ReadonlyArray = [ + { value: "dark", label: "Dark", Icon: Moon, testId: "dark-mode-button" }, + { value: "light", label: "Light", Icon: Sun, testId: "light-mode-button" }, + { + value: "retro", + label: "Retro", + Icon: Terminal, + testId: "retro-mode-button", + }, + { + value: "dracula", + label: "Dracula", + Icon: Ghost, + testId: "dracula-mode-button", + }, + { + value: "nord", + label: "Nord", + Icon: Snowflake, + testId: "nord-mode-button", + }, + { + value: "monokai", + label: "Monokai", + Icon: Flame, + testId: "monokai-mode-button", + }, + { + value: "tokyonight", + label: "Tokyo Night", + Icon: Sparkles, + testId: "tokyonight-mode-button", + }, + { + value: "solarized", + label: "Solarized", + Icon: Eclipse, + testId: "solarized-mode-button", + }, + { + value: "gruvbox", + label: "Gruvbox", + Icon: Trees, + testId: "gruvbox-mode-button", + }, + { + value: "catppuccin", + label: "Catppuccin", + Icon: Cat, + testId: "catppuccin-mode-button", + }, + { + value: "onedark", + label: "One Dark", + Icon: Atom, + testId: "onedark-mode-button", + }, + { + value: "synthwave", + label: "Synthwave", + Icon: Radio, + testId: "synthwave-mode-button", + }, +]; diff --git a/app/src/components/views/settings-view/types.ts b/app/src/components/views/settings-view/types.ts new file mode 100644 index 00000000..e28966a6 --- /dev/null +++ b/app/src/components/views/settings-view/types.ts @@ -0,0 +1,47 @@ +// Shared TypeScript types for settings view components + +export interface CliStatus { + success: boolean; + status?: string; + method?: string; + version?: string; + path?: string; + hasApiKey?: boolean; + recommendation?: string; + installCommands?: { + macos?: string; + windows?: string; + linux?: string; + npm?: string; + }; + error?: string; +} + +export type Theme = + | "dark" + | "light" + | "retro" + | "dracula" + | "nord" + | "monokai" + | "tokyonight" + | "solarized" + | "gruvbox" + | "catppuccin" + | "onedark" + | "synthwave"; + +export type KanbanDetailLevel = "minimal" | "standard" | "detailed"; + +export interface Project { + id: string; + name: string; + path: string; + theme?: Theme; +} + +export interface ApiKeys { + anthropic: string; + google: string; + openai: string; +}