Merge main into massive-terminal-upgrade

Resolves merge conflicts:
- apps/server/src/routes/terminal/common.ts: Keep randomBytes import, use @automaker/utils for createLogger
- apps/ui/eslint.config.mjs: Use main's explicit globals list with XMLHttpRequest and MediaQueryListEvent additions
- apps/ui/src/components/views/terminal-view.tsx: Keep our terminal improvements (killAllSessions, beforeunload, better error handling)
- apps/ui/src/config/terminal-themes.ts: Keep our search highlight colors for all themes
- apps/ui/src/store/app-store.ts: Keep our terminal settings persistence improvements (merge function)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
SuperComboGamer
2025-12-21 20:27:44 -05:00
393 changed files with 32473 additions and 17974 deletions

View File

@@ -1,8 +1,7 @@
import type { Dispatch, SetStateAction } from "react";
import type { LucideIcon } from "lucide-react";
import type { ApiKeys } from "@/store/app-store";
import type { Dispatch, SetStateAction } from 'react';
import type { ApiKeys } from '@/store/app-store';
export type ProviderKey = "anthropic" | "google";
export type ProviderKey = 'anthropic' | 'google';
export interface ProviderConfig {
key: ProviderKey;
@@ -56,33 +55,32 @@ export interface ProviderConfigParams {
export const buildProviderConfigs = ({
apiKeys,
anthropic,
google,
}: ProviderConfigParams): ProviderConfig[] => [
{
key: "anthropic",
label: "Anthropic API Key",
inputId: "anthropic-key",
placeholder: "sk-ant-...",
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",
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",
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: ".",
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",

View File

@@ -6,48 +6,12 @@
* - 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;
// Import shared model constants and types
import { CLAUDE_MODEL_MAP, DEFAULT_MODELS } from '@automaker/types';
import { resolveModelString } from '@automaker/model-resolver';
/**
* 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;
}
// Re-export for backward compatibility
export { CLAUDE_MODEL_MAP, DEFAULT_MODELS, resolveModelString };
/**
* Get the model for chat operations
@@ -63,32 +27,30 @@ export function getChatModel(explicitModel?: string): string {
return resolveModelString(explicitModel);
}
const envModel =
process.env.AUTOMAKER_MODEL_CHAT || process.env.AUTOMAKER_MODEL_DEFAULT;
const envModel = import.meta.env.AUTOMAKER_MODEL_CHAT || import.meta.env.AUTOMAKER_MODEL_DEFAULT;
if (envModel) {
return resolveModelString(envModel);
}
return DEFAULT_MODELS.chat;
return DEFAULT_MODELS.claude;
}
/**
* Default allowed tools for chat interactions
*/
export const CHAT_TOOLS = [
"Read",
"Write",
"Edit",
"Glob",
"Grep",
"Bash",
"WebSearch",
"WebFetch",
'Read',
'Write',
'Edit',
'Glob',
'Grep',
'Bash',
'WebSearch',
'WebFetch',
] as const;
/**
* Default max turns for chat
*/
export const CHAT_MAX_TURNS = 1000;

View File

@@ -2,115 +2,342 @@ import {
type LucideIcon,
Atom,
Cat,
Cherry,
CloudSun,
Coffee,
Eclipse,
Feather,
Flame,
Flower2,
Ghost,
Github,
Heart,
Leaf,
Moon,
Palmtree,
Radio,
Scroll,
Snowflake,
Sparkles,
Square,
Sun,
Sunrise,
Terminal,
Trees,
} from "lucide-react";
import { Theme } from "@/components/views/settings-view/shared/types";
Waves,
Wind,
} from 'lucide-react';
// Theme value type - all available themes
export type Theme =
// Dark themes (16)
| 'dark'
| 'retro'
| 'dracula'
| 'nord'
| 'monokai'
| 'tokyonight'
| 'solarized'
| 'gruvbox'
| 'catppuccin'
| 'onedark'
| 'synthwave'
| 'red'
| 'sunset'
| 'gray'
| 'forest'
| 'ocean'
// Light themes (16)
| 'light'
| 'cream'
| 'solarizedlight'
| 'github'
| 'paper'
| 'rose'
| 'mint'
| 'lavender'
| 'sand'
| 'sky'
| 'peach'
| 'snow'
| 'sepia'
| 'gruvboxlight'
| 'nordlight'
| 'blossom';
export interface ThemeOption {
value: Theme;
label: string;
Icon: LucideIcon;
testId: string;
isDark: boolean;
color: string; // Primary/brand color for icon display
}
// All theme options with dark/light categorization
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" },
// Dark themes (16)
{
value: "retro",
label: "Retro",
value: 'dark',
label: 'Dark',
Icon: Moon,
testId: 'dark-mode-button',
isDark: true,
color: '#3b82f6',
},
{
value: 'retro',
label: 'Retro',
Icon: Terminal,
testId: "retro-mode-button",
testId: 'retro-mode-button',
isDark: true,
color: '#22c55e',
},
{
value: "dracula",
label: "Dracula",
value: 'dracula',
label: 'Dracula',
Icon: Ghost,
testId: "dracula-mode-button",
testId: 'dracula-mode-button',
isDark: true,
color: '#bd93f9',
},
{
value: "nord",
label: "Nord",
value: 'nord',
label: 'Nord',
Icon: Snowflake,
testId: "nord-mode-button",
testId: 'nord-mode-button',
isDark: true,
color: '#88c0d0',
},
{
value: "monokai",
label: "Monokai",
value: 'monokai',
label: 'Monokai',
Icon: Flame,
testId: "monokai-mode-button",
testId: 'monokai-mode-button',
isDark: true,
color: '#f92672',
},
{
value: "tokyonight",
label: "Tokyo Night",
value: 'tokyonight',
label: 'Tokyo Night',
Icon: Sparkles,
testId: "tokyonight-mode-button",
testId: 'tokyonight-mode-button',
isDark: true,
color: '#bb9af7',
},
{
value: "solarized",
label: "Solarized",
value: 'solarized',
label: 'Solarized Dark',
Icon: Eclipse,
testId: "solarized-mode-button",
testId: 'solarized-mode-button',
isDark: true,
color: '#268bd2',
},
{
value: "gruvbox",
label: "Gruvbox",
value: 'gruvbox',
label: 'Gruvbox',
Icon: Trees,
testId: "gruvbox-mode-button",
testId: 'gruvbox-mode-button',
isDark: true,
color: '#fe8019',
},
{
value: "catppuccin",
label: "Catppuccin",
value: 'catppuccin',
label: 'Catppuccin',
Icon: Cat,
testId: "catppuccin-mode-button",
testId: 'catppuccin-mode-button',
isDark: true,
color: '#cba6f7',
},
{
value: "onedark",
label: "One Dark",
value: 'onedark',
label: 'One Dark',
Icon: Atom,
testId: "onedark-mode-button",
testId: 'onedark-mode-button',
isDark: true,
color: '#61afef',
},
{
value: "synthwave",
label: "Synthwave",
value: 'synthwave',
label: 'Synthwave',
Icon: Radio,
testId: "synthwave-mode-button",
testId: 'synthwave-mode-button',
isDark: true,
color: '#ff7edb',
},
{
value: "red",
label: "Red",
value: 'red',
label: 'Red',
Icon: Heart,
testId: "red-mode-button",
testId: 'red-mode-button',
isDark: true,
color: '#ef4444',
},
{
value: "cream",
label: "Cream",
Icon: Coffee,
testId: "cream-mode-button",
},
{
value: "sunset",
label: "Sunset",
value: 'sunset',
label: 'Sunset',
Icon: CloudSun,
testId: "sunset-mode-button",
testId: 'sunset-mode-button',
isDark: true,
color: '#f97316',
},
{
value: "gray",
label: "Gray",
value: 'gray',
label: 'Gray',
Icon: Square,
testId: "gray-mode-button",
testId: 'gray-mode-button',
isDark: true,
color: '#6b7280',
},
{
value: 'forest',
label: 'Forest',
Icon: Leaf,
testId: 'forest-mode-button',
isDark: true,
color: '#22c55e',
},
{
value: 'ocean',
label: 'Ocean',
Icon: Waves,
testId: 'ocean-mode-button',
isDark: true,
color: '#06b6d4',
},
// Light themes (16)
{
value: 'light',
label: 'Light',
Icon: Sun,
testId: 'light-mode-button',
isDark: false,
color: '#3b82f6',
},
{
value: 'cream',
label: 'Cream',
Icon: Coffee,
testId: 'cream-mode-button',
isDark: false,
color: '#b45309',
},
{
value: 'solarizedlight',
label: 'Solarized Light',
Icon: Sunrise,
testId: 'solarizedlight-mode-button',
isDark: false,
color: '#268bd2',
},
{
value: 'github',
label: 'GitHub',
Icon: Github,
testId: 'github-mode-button',
isDark: false,
color: '#0969da',
},
{
value: 'paper',
label: 'Paper',
Icon: Scroll,
testId: 'paper-mode-button',
isDark: false,
color: '#374151',
},
{
value: 'rose',
label: 'Rose',
Icon: Flower2,
testId: 'rose-mode-button',
isDark: false,
color: '#e11d48',
},
{
value: 'mint',
label: 'Mint',
Icon: Wind,
testId: 'mint-mode-button',
isDark: false,
color: '#0d9488',
},
{
value: 'lavender',
label: 'Lavender',
Icon: Feather,
testId: 'lavender-mode-button',
isDark: false,
color: '#8b5cf6',
},
{
value: 'sand',
label: 'Sand',
Icon: Palmtree,
testId: 'sand-mode-button',
isDark: false,
color: '#d97706',
},
{
value: 'sky',
label: 'Sky',
Icon: Sun,
testId: 'sky-mode-button',
isDark: false,
color: '#0284c7',
},
{
value: 'peach',
label: 'Peach',
Icon: Cherry,
testId: 'peach-mode-button',
isDark: false,
color: '#ea580c',
},
{
value: 'snow',
label: 'Snow',
Icon: Snowflake,
testId: 'snow-mode-button',
isDark: false,
color: '#3b82f6',
},
{
value: 'sepia',
label: 'Sepia',
Icon: Coffee,
testId: 'sepia-mode-button',
isDark: false,
color: '#92400e',
},
{
value: 'gruvboxlight',
label: 'Gruvbox Light',
Icon: Trees,
testId: 'gruvboxlight-mode-button',
isDark: false,
color: '#d65d0e',
},
{
value: 'nordlight',
label: 'Nord Light',
Icon: Snowflake,
testId: 'nordlight-mode-button',
isDark: false,
color: '#5e81ac',
},
{
value: 'blossom',
label: 'Blossom',
Icon: Cherry,
testId: 'blossom-mode-button',
isDark: false,
color: '#ec4899',
},
];
// Helper: Get only dark themes
export const darkThemes = themeOptions.filter((t) => t.isDark);
// Helper: Get only light themes
export const lightThemes = themeOptions.filter((t) => !t.isDark);