refactor: move from next js to vite and tanstack router

This commit is contained in:
Kacper
2025-12-17 20:11:16 +01:00
parent 9954feafd8
commit 5136c32b68
263 changed files with 11148 additions and 10276 deletions

View File

@@ -0,0 +1,113 @@
import type { Dispatch, SetStateAction } from "react";
import type { LucideIcon } from "lucide-react";
import type { ApiKeys } from "@/store/app-store";
export type ProviderKey = "anthropic" | "google";
export interface ProviderConfig {
key: ProviderKey;
label: string;
inputId: string;
placeholder: string;
value: string;
setValue: Dispatch<SetStateAction<string>>;
showValue: boolean;
setShowValue: Dispatch<SetStateAction<boolean>>;
hasStoredKey: string | null | undefined;
inputTestId: string;
toggleTestId: string;
testButton: {
onClick: () => Promise<void> | void;
disabled: boolean;
loading: boolean;
testId: string;
};
result: { success: boolean; message: string } | null;
resultTestId: string;
resultMessageTestId: string;
descriptionPrefix: string;
descriptionLinkHref: string;
descriptionLinkText: string;
descriptionSuffix?: string;
}
export interface ProviderConfigParams {
apiKeys: ApiKeys;
anthropic: {
value: string;
setValue: Dispatch<SetStateAction<string>>;
show: boolean;
setShow: Dispatch<SetStateAction<boolean>>;
testing: boolean;
onTest: () => Promise<void>;
result: { success: boolean; message: string } | null;
};
google: {
value: string;
setValue: Dispatch<SetStateAction<string>>;
show: boolean;
setShow: Dispatch<SetStateAction<boolean>>;
testing: boolean;
onTest: () => Promise<void>;
result: { success: boolean; message: string } | null;
};
}
export const buildProviderConfigs = ({
apiKeys,
anthropic,
google,
}: ProviderConfigParams): ProviderConfig[] => [
{
key: "anthropic",
label: "Anthropic API Key",
inputId: "anthropic-key",
placeholder: "sk-ant-...",
value: anthropic.value,
setValue: anthropic.setValue,
showValue: anthropic.show,
setShowValue: anthropic.setShow,
hasStoredKey: apiKeys.anthropic,
inputTestId: "anthropic-api-key-input",
toggleTestId: "toggle-anthropic-visibility",
testButton: {
onClick: anthropic.onTest,
disabled: !anthropic.value || anthropic.testing,
loading: anthropic.testing,
testId: "test-claude-connection",
},
result: anthropic.result,
resultTestId: "test-connection-result",
resultMessageTestId: "test-connection-message",
descriptionPrefix: "Used for Claude AI features. Get your key at",
descriptionLinkHref: "https://console.anthropic.com/account/keys",
descriptionLinkText: "console.anthropic.com",
descriptionSuffix: ".",
},
// {
// key: "google",
// label: "Google API Key (Gemini)",
// inputId: "google-key",
// placeholder: "AIza...",
// value: google.value,
// setValue: google.setValue,
// showValue: google.show,
// setShowValue: google.setShow,
// hasStoredKey: apiKeys.google,
// inputTestId: "google-api-key-input",
// toggleTestId: "toggle-google-visibility",
// testButton: {
// onClick: google.onTest,
// disabled: !google.value || google.testing,
// loading: google.testing,
// testId: "test-gemini-connection",
// },
// result: google.result,
// resultTestId: "gemini-test-connection-result",
// resultMessageTestId: "gemini-test-connection-message",
// descriptionPrefix:
// "Used for Gemini AI features (including image/design prompts). Get your key at",
// descriptionLinkHref: "https://makersuite.google.com/app/apikey",
// descriptionLinkText: "makersuite.google.com",
// },
];

View File

View File

@@ -0,0 +1,94 @@
/**
* Model Configuration - Centralized model settings for the app
*
* Models can be overridden via environment variables:
* - AUTOMAKER_MODEL_CHAT: Model for chat interactions
* - AUTOMAKER_MODEL_DEFAULT: Fallback model for all operations
*/
/**
* Claude model aliases for convenience
*/
export const CLAUDE_MODEL_MAP: Record<string, string> = {
haiku: "claude-haiku-4-5",
sonnet: "claude-sonnet-4-20250514",
opus: "claude-opus-4-5-20251101",
} as const;
/**
* Default models per use case
*/
export const DEFAULT_MODELS = {
chat: "claude-opus-4-5-20251101",
default: "claude-opus-4-5-20251101",
} as const;
/**
* Resolve a model alias to a full model string
*/
export function resolveModelString(
modelKey?: string,
defaultModel: string = DEFAULT_MODELS.default
): string {
if (!modelKey) {
return defaultModel;
}
// Full Claude model string - pass through
if (modelKey.includes("claude-")) {
return modelKey;
}
// Check alias map
const resolved = CLAUDE_MODEL_MAP[modelKey];
if (resolved) {
return resolved;
}
// Unknown key - use default
return defaultModel;
}
/**
* Get the model for chat operations
*
* Priority:
* 1. Explicit model parameter
* 2. AUTOMAKER_MODEL_CHAT environment variable
* 3. AUTOMAKER_MODEL_DEFAULT environment variable
* 4. Default chat model
*/
export function getChatModel(explicitModel?: string): string {
if (explicitModel) {
return resolveModelString(explicitModel);
}
const envModel =
process.env.AUTOMAKER_MODEL_CHAT || process.env.AUTOMAKER_MODEL_DEFAULT;
if (envModel) {
return resolveModelString(envModel);
}
return DEFAULT_MODELS.chat;
}
/**
* Default allowed tools for chat interactions
*/
export const CHAT_TOOLS = [
"Read",
"Write",
"Edit",
"Glob",
"Grep",
"Bash",
"WebSearch",
"WebFetch",
] as const;
/**
* Default max turns for chat
*/
export const CHAT_MAX_TURNS = 1000;

View File

@@ -0,0 +1,393 @@
/**
* Terminal themes that match the app themes
* Each theme provides colors for xterm.js terminal emulator
*/
import type { ThemeMode } from "@/store/app-store";
export interface TerminalTheme {
background: string;
foreground: string;
cursor: string;
cursorAccent: string;
selectionBackground: string;
selectionForeground?: string;
black: string;
red: string;
green: string;
yellow: string;
blue: string;
magenta: string;
cyan: string;
white: string;
brightBlack: string;
brightRed: string;
brightGreen: string;
brightYellow: string;
brightBlue: string;
brightMagenta: string;
brightCyan: string;
brightWhite: string;
}
// Dark theme (default)
const darkTheme: TerminalTheme = {
background: "#0a0a0a",
foreground: "#d4d4d4",
cursor: "#d4d4d4",
cursorAccent: "#0a0a0a",
selectionBackground: "#264f78",
black: "#1e1e1e",
red: "#f44747",
green: "#6a9955",
yellow: "#dcdcaa",
blue: "#569cd6",
magenta: "#c586c0",
cyan: "#4ec9b0",
white: "#d4d4d4",
brightBlack: "#808080",
brightRed: "#f44747",
brightGreen: "#6a9955",
brightYellow: "#dcdcaa",
brightBlue: "#569cd6",
brightMagenta: "#c586c0",
brightCyan: "#4ec9b0",
brightWhite: "#ffffff",
};
// Light theme
const lightTheme: TerminalTheme = {
background: "#ffffff",
foreground: "#383a42",
cursor: "#383a42",
cursorAccent: "#ffffff",
selectionBackground: "#add6ff",
black: "#383a42",
red: "#e45649",
green: "#50a14f",
yellow: "#c18401",
blue: "#4078f2",
magenta: "#a626a4",
cyan: "#0184bc",
white: "#fafafa",
brightBlack: "#4f525e",
brightRed: "#e06c75",
brightGreen: "#98c379",
brightYellow: "#e5c07b",
brightBlue: "#61afef",
brightMagenta: "#c678dd",
brightCyan: "#56b6c2",
brightWhite: "#ffffff",
};
// Retro / Cyberpunk theme - neon green on black
const retroTheme: TerminalTheme = {
background: "#000000",
foreground: "#39ff14",
cursor: "#39ff14",
cursorAccent: "#000000",
selectionBackground: "#39ff14",
selectionForeground: "#000000",
black: "#000000",
red: "#ff0055",
green: "#39ff14",
yellow: "#ffff00",
blue: "#00ffff",
magenta: "#ff00ff",
cyan: "#00ffff",
white: "#39ff14",
brightBlack: "#555555",
brightRed: "#ff5555",
brightGreen: "#55ff55",
brightYellow: "#ffff55",
brightBlue: "#55ffff",
brightMagenta: "#ff55ff",
brightCyan: "#55ffff",
brightWhite: "#ffffff",
};
// Dracula theme
const draculaTheme: TerminalTheme = {
background: "#282a36",
foreground: "#f8f8f2",
cursor: "#f8f8f2",
cursorAccent: "#282a36",
selectionBackground: "#44475a",
black: "#21222c",
red: "#ff5555",
green: "#50fa7b",
yellow: "#f1fa8c",
blue: "#bd93f9",
magenta: "#ff79c6",
cyan: "#8be9fd",
white: "#f8f8f2",
brightBlack: "#6272a4",
brightRed: "#ff6e6e",
brightGreen: "#69ff94",
brightYellow: "#ffffa5",
brightBlue: "#d6acff",
brightMagenta: "#ff92df",
brightCyan: "#a4ffff",
brightWhite: "#ffffff",
};
// Nord theme
const nordTheme: TerminalTheme = {
background: "#2e3440",
foreground: "#d8dee9",
cursor: "#d8dee9",
cursorAccent: "#2e3440",
selectionBackground: "#434c5e",
black: "#3b4252",
red: "#bf616a",
green: "#a3be8c",
yellow: "#ebcb8b",
blue: "#81a1c1",
magenta: "#b48ead",
cyan: "#88c0d0",
white: "#e5e9f0",
brightBlack: "#4c566a",
brightRed: "#bf616a",
brightGreen: "#a3be8c",
brightYellow: "#ebcb8b",
brightBlue: "#81a1c1",
brightMagenta: "#b48ead",
brightCyan: "#8fbcbb",
brightWhite: "#eceff4",
};
// Monokai theme
const monokaiTheme: TerminalTheme = {
background: "#272822",
foreground: "#f8f8f2",
cursor: "#f8f8f2",
cursorAccent: "#272822",
selectionBackground: "#49483e",
black: "#272822",
red: "#f92672",
green: "#a6e22e",
yellow: "#f4bf75",
blue: "#66d9ef",
magenta: "#ae81ff",
cyan: "#a1efe4",
white: "#f8f8f2",
brightBlack: "#75715e",
brightRed: "#f92672",
brightGreen: "#a6e22e",
brightYellow: "#f4bf75",
brightBlue: "#66d9ef",
brightMagenta: "#ae81ff",
brightCyan: "#a1efe4",
brightWhite: "#f9f8f5",
};
// Tokyo Night theme
const tokyonightTheme: TerminalTheme = {
background: "#1a1b26",
foreground: "#a9b1d6",
cursor: "#c0caf5",
cursorAccent: "#1a1b26",
selectionBackground: "#33467c",
black: "#15161e",
red: "#f7768e",
green: "#9ece6a",
yellow: "#e0af68",
blue: "#7aa2f7",
magenta: "#bb9af7",
cyan: "#7dcfff",
white: "#a9b1d6",
brightBlack: "#414868",
brightRed: "#f7768e",
brightGreen: "#9ece6a",
brightYellow: "#e0af68",
brightBlue: "#7aa2f7",
brightMagenta: "#bb9af7",
brightCyan: "#7dcfff",
brightWhite: "#c0caf5",
};
// Solarized Dark theme
const solarizedTheme: TerminalTheme = {
background: "#002b36",
foreground: "#839496",
cursor: "#839496",
cursorAccent: "#002b36",
selectionBackground: "#073642",
black: "#073642",
red: "#dc322f",
green: "#859900",
yellow: "#b58900",
blue: "#268bd2",
magenta: "#d33682",
cyan: "#2aa198",
white: "#eee8d5",
brightBlack: "#002b36",
brightRed: "#cb4b16",
brightGreen: "#586e75",
brightYellow: "#657b83",
brightBlue: "#839496",
brightMagenta: "#6c71c4",
brightCyan: "#93a1a1",
brightWhite: "#fdf6e3",
};
// Gruvbox Dark theme
const gruvboxTheme: TerminalTheme = {
background: "#282828",
foreground: "#ebdbb2",
cursor: "#ebdbb2",
cursorAccent: "#282828",
selectionBackground: "#504945",
black: "#282828",
red: "#cc241d",
green: "#98971a",
yellow: "#d79921",
blue: "#458588",
magenta: "#b16286",
cyan: "#689d6a",
white: "#a89984",
brightBlack: "#928374",
brightRed: "#fb4934",
brightGreen: "#b8bb26",
brightYellow: "#fabd2f",
brightBlue: "#83a598",
brightMagenta: "#d3869b",
brightCyan: "#8ec07c",
brightWhite: "#ebdbb2",
};
// Catppuccin Mocha theme
const catppuccinTheme: TerminalTheme = {
background: "#1e1e2e",
foreground: "#cdd6f4",
cursor: "#f5e0dc",
cursorAccent: "#1e1e2e",
selectionBackground: "#45475a",
black: "#45475a",
red: "#f38ba8",
green: "#a6e3a1",
yellow: "#f9e2af",
blue: "#89b4fa",
magenta: "#cba6f7",
cyan: "#94e2d5",
white: "#bac2de",
brightBlack: "#585b70",
brightRed: "#f38ba8",
brightGreen: "#a6e3a1",
brightYellow: "#f9e2af",
brightBlue: "#89b4fa",
brightMagenta: "#cba6f7",
brightCyan: "#94e2d5",
brightWhite: "#a6adc8",
};
// One Dark theme
const onedarkTheme: TerminalTheme = {
background: "#282c34",
foreground: "#abb2bf",
cursor: "#528bff",
cursorAccent: "#282c34",
selectionBackground: "#3e4451",
black: "#282c34",
red: "#e06c75",
green: "#98c379",
yellow: "#e5c07b",
blue: "#61afef",
magenta: "#c678dd",
cyan: "#56b6c2",
white: "#abb2bf",
brightBlack: "#5c6370",
brightRed: "#e06c75",
brightGreen: "#98c379",
brightYellow: "#e5c07b",
brightBlue: "#61afef",
brightMagenta: "#c678dd",
brightCyan: "#56b6c2",
brightWhite: "#ffffff",
};
// Synthwave '84 theme
const synthwaveTheme: TerminalTheme = {
background: "#262335",
foreground: "#ffffff",
cursor: "#ff7edb",
cursorAccent: "#262335",
selectionBackground: "#463465",
black: "#262335",
red: "#fe4450",
green: "#72f1b8",
yellow: "#fede5d",
blue: "#03edf9",
magenta: "#ff7edb",
cyan: "#03edf9",
white: "#ffffff",
brightBlack: "#614d85",
brightRed: "#fe4450",
brightGreen: "#72f1b8",
brightYellow: "#f97e72",
brightBlue: "#03edf9",
brightMagenta: "#ff7edb",
brightCyan: "#03edf9",
brightWhite: "#ffffff",
};
// Red theme - Dark theme with red accents
const redTheme: TerminalTheme = {
background: "#1a0a0a",
foreground: "#c8b0b0",
cursor: "#ff4444",
cursorAccent: "#1a0a0a",
selectionBackground: "#5a2020",
black: "#2a1010",
red: "#ff4444",
green: "#6a9a6a",
yellow: "#ccaa55",
blue: "#6688aa",
magenta: "#aa5588",
cyan: "#558888",
white: "#b0a0a0",
brightBlack: "#6a4040",
brightRed: "#ff6666",
brightGreen: "#88bb88",
brightYellow: "#ddbb66",
brightBlue: "#88aacc",
brightMagenta: "#cc77aa",
brightCyan: "#77aaaa",
brightWhite: "#d0c0c0",
};
// Theme mapping
const terminalThemes: Record<ThemeMode, TerminalTheme> = {
light: lightTheme,
dark: darkTheme,
system: darkTheme, // Will be resolved at runtime
retro: retroTheme,
dracula: draculaTheme,
nord: nordTheme,
monokai: monokaiTheme,
tokyonight: tokyonightTheme,
solarized: solarizedTheme,
gruvbox: gruvboxTheme,
catppuccin: catppuccinTheme,
onedark: onedarkTheme,
synthwave: synthwaveTheme,
red: redTheme,
};
/**
* Get terminal theme for the given app theme
* For "system" theme, it checks the user's system preference
*/
export function getTerminalTheme(theme: ThemeMode): TerminalTheme {
if (theme === "system") {
// Check system preference
if (typeof window !== "undefined") {
const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
return prefersDark ? darkTheme : lightTheme;
}
return darkTheme; // Default to dark for SSR
}
return terminalThemes[theme] || darkTheme;
}
export default terminalThemes;

View File

@@ -0,0 +1,95 @@
import {
type LucideIcon,
Atom,
Cat,
Eclipse,
Flame,
Ghost,
Heart,
Moon,
Radio,
Snowflake,
Sparkles,
Sun,
Terminal,
Trees,
} from "lucide-react";
import { Theme } from "@/components/views/settings-view/shared/types";
export interface ThemeOption {
value: Theme;
label: string;
Icon: LucideIcon;
testId: string;
}
export const themeOptions: ReadonlyArray<ThemeOption> = [
{ 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",
},
{
value: "red",
label: "Red",
Icon: Heart,
testId: "red-mode-button",
},
];