diff --git a/src/components/chat/hooks/useChatProviderState.ts b/src/components/chat/hooks/useChatProviderState.ts index 6d39d22a..7842ecb7 100644 --- a/src/components/chat/hooks/useChatProviderState.ts +++ b/src/components/chat/hooks/useChatProviderState.ts @@ -4,6 +4,16 @@ import { CLAUDE_MODELS, CODEX_MODELS, CURSOR_MODELS, GEMINI_MODELS } from '../.. import type { PendingPermissionRequest, PermissionMode } from '../types/types'; import type { ProjectSession, LLMProvider } from '../../../types/app'; +const getPermissionModesForProvider = (provider: LLMProvider): PermissionMode[] => { + if (provider === 'codex') { + return ['default', 'acceptEdits', 'bypassPermissions']; + } + if (provider === 'claude') { + return ['default', 'auto', 'acceptEdits', 'bypassPermissions', 'plan']; + } + return ['default', 'acceptEdits', 'bypassPermissions', 'plan']; +}; + interface UseChatProviderStateArgs { selectedSession: ProjectSession | null; } @@ -34,9 +44,10 @@ export function useChatProviderState({ selectedSession }: UseChatProviderStateAr return; } - const savedMode = localStorage.getItem(`permissionMode-${selectedSession.id}`); - setPermissionMode((savedMode as PermissionMode) || 'default'); - }, [selectedSession?.id]); + const savedMode = localStorage.getItem(`permissionMode-${selectedSession.id}`) as PermissionMode | null; + const validModes = getPermissionModesForProvider(provider); + setPermissionMode(savedMode && validModes.includes(savedMode) ? savedMode : 'default'); + }, [selectedSession?.id, provider]); useEffect(() => { if (!selectedSession?.__provider || selectedSession.__provider === provider) { @@ -84,10 +95,7 @@ export function useChatProviderState({ selectedSession }: UseChatProviderStateAr }, [provider]); const cyclePermissionMode = useCallback(() => { - const modes: PermissionMode[] = - provider === 'codex' - ? ['default', 'acceptEdits', 'bypassPermissions'] - : ['default', 'acceptEdits', 'bypassPermissions', 'plan']; + const modes = getPermissionModesForProvider(provider); const currentIndex = modes.indexOf(permissionMode); const nextIndex = (currentIndex + 1) % modes.length; diff --git a/src/components/chat/types/types.ts b/src/components/chat/types/types.ts index 900028c0..526b8cc7 100644 --- a/src/components/chat/types/types.ts +++ b/src/components/chat/types/types.ts @@ -2,7 +2,7 @@ import type { Project, ProjectSession, LLMProvider } from '../../../types/app'; export type Provider = LLMProvider; -export type PermissionMode = 'default' | 'acceptEdits' | 'bypassPermissions' | 'plan'; +export type PermissionMode = 'default' | 'acceptEdits' | 'auto' | 'bypassPermissions' | 'plan'; export interface ChatImage { data: string; diff --git a/src/components/chat/view/subcomponents/ChatComposer.tsx b/src/components/chat/view/subcomponents/ChatComposer.tsx index e67ee64b..d9ae186e 100644 --- a/src/components/chat/view/subcomponents/ChatComposer.tsx +++ b/src/components/chat/view/subcomponents/ChatComposer.tsx @@ -325,9 +325,11 @@ export default function ChatComposer({ ? 'border-border/60 bg-muted/50 text-muted-foreground hover:bg-muted' : permissionMode === 'acceptEdits' ? 'border-green-300/60 bg-green-50 text-green-700 hover:bg-green-100 dark:border-green-600/40 dark:bg-green-900/15 dark:text-green-300 dark:hover:bg-green-900/25' - : permissionMode === 'bypassPermissions' - ? 'border-orange-300/60 bg-orange-50 text-orange-700 hover:bg-orange-100 dark:border-orange-600/40 dark:bg-orange-900/15 dark:text-orange-300 dark:hover:bg-orange-900/25' - : 'border-primary/20 bg-primary/5 text-primary hover:bg-primary/10' + : permissionMode === 'auto' + ? 'border-amber-300/60 bg-amber-50 text-amber-700 hover:bg-amber-100 dark:border-amber-600/40 dark:bg-amber-900/15 dark:text-amber-300 dark:hover:bg-amber-900/25' + : permissionMode === 'bypassPermissions' + ? 'border-orange-300/60 bg-orange-50 text-orange-700 hover:bg-orange-100 dark:border-orange-600/40 dark:bg-orange-900/15 dark:text-orange-300 dark:hover:bg-orange-900/25' + : 'border-primary/20 bg-primary/5 text-primary hover:bg-primary/10' }`} title={t('input.clickToChangeMode')} > @@ -338,14 +340,17 @@ export default function ChatComposer({ ? 'bg-muted-foreground' : permissionMode === 'acceptEdits' ? 'bg-green-500' - : permissionMode === 'bypassPermissions' - ? 'bg-orange-500' - : 'bg-primary' + : permissionMode === 'auto' + ? 'bg-amber-500' + : permissionMode === 'bypassPermissions' + ? 'bg-orange-500' + : 'bg-primary' }`} /> {permissionMode === 'default' && t('codex.modes.default')} {permissionMode === 'acceptEdits' && t('codex.modes.acceptEdits')} + {permissionMode === 'auto' && t('codex.modes.auto')} {permissionMode === 'bypassPermissions' && t('codex.modes.bypassPermissions')} {permissionMode === 'plan' && t('codex.modes.plan')} diff --git a/src/i18n/locales/de/chat.json b/src/i18n/locales/de/chat.json index b8a2d586..1737114a 100644 --- a/src/i18n/locales/de/chat.json +++ b/src/i18n/locales/de/chat.json @@ -89,12 +89,14 @@ "permissionMode": "Berechtigungsmodus", "modes": { "default": "Standardmodus", + "auto": "Auto Mode", "acceptEdits": "Bearbeitungen akzeptieren", "bypassPermissions": "Berechtigungen umgehen", "plan": "Planungsmodus" }, "descriptions": { "default": "Nur vertrauenswürdige Befehle (ls, cat, grep, git status usw.) werden automatisch ausgeführt. Andere Befehle werden übersprungen. Kann in den Arbeitsbereich schreiben.", + "auto": "A model classifier decides per tool call whether to approve or deny. Hands-off, but safer than Bypass — denials still happen.", "acceptEdits": "Alle Befehle werden automatisch innerhalb des Arbeitsbereichs ausgeführt. Vollautomatischer Modus mit isolierter Ausführung.", "bypassPermissions": "Vollständiger Systemzugriff ohne Einschränkungen. Alle Befehle werden automatisch mit vollem Festplatten- und Netzwerkzugriff ausgeführt. Mit Vorsicht verwenden.", "plan": "Planungsmodus – keine Befehle werden ausgeführt" diff --git a/src/i18n/locales/en/chat.json b/src/i18n/locales/en/chat.json index 32e756a2..6db4d751 100644 --- a/src/i18n/locales/en/chat.json +++ b/src/i18n/locales/en/chat.json @@ -89,12 +89,14 @@ "permissionMode": "Permission Mode", "modes": { "default": "Default Mode", + "auto": "Auto Mode", "acceptEdits": "Accept Edits", "bypassPermissions": "Bypass Permissions", "plan": "Plan Mode" }, "descriptions": { "default": "Only trusted commands (ls, cat, grep, git status, etc.) run automatically. Other commands are skipped. Can write to workspace.", + "auto": "A model classifier decides per tool call whether to approve or deny. Hands-off, but safer than Bypass — denials still happen.", "acceptEdits": "All commands run automatically within the workspace. Full auto mode with sandboxed execution.", "bypassPermissions": "Full system access with no restrictions. All commands run automatically with full disk and network access. Use with caution.", "plan": "Planning mode - no commands are executed" diff --git a/src/i18n/locales/it/chat.json b/src/i18n/locales/it/chat.json index 06f18b08..848e5bfb 100644 --- a/src/i18n/locales/it/chat.json +++ b/src/i18n/locales/it/chat.json @@ -89,12 +89,14 @@ "permissionMode": "Modalità permessi", "modes": { "default": "Modalità predefinita", + "auto": "Auto Mode", "acceptEdits": "Accetta modifiche", "bypassPermissions": "Ignora permessi", "plan": "Modalità piano" }, "descriptions": { "default": "Solo i comandi attendibili (ls, cat, grep, git status, ecc.) vengono eseguiti automaticamente. Gli altri comandi vengono saltati. Può scrivere nell'area di lavoro.", + "auto": "A model classifier decides per tool call whether to approve or deny. Hands-off, but safer than Bypass — denials still happen.", "acceptEdits": "Tutti i comandi vengono eseguiti automaticamente nell'area di lavoro. Modalità completamente automatica con esecuzione sandboxed.", "bypassPermissions": "Accesso completo al sistema senza restrizioni. Tutti i comandi vengono eseguiti automaticamente con accesso completo a disco e rete. Usa con cautela.", "plan": "Modalità pianificazione - nessun comando viene eseguito" diff --git a/src/i18n/locales/ja/chat.json b/src/i18n/locales/ja/chat.json index eb878aa6..780bf76c 100644 --- a/src/i18n/locales/ja/chat.json +++ b/src/i18n/locales/ja/chat.json @@ -88,12 +88,14 @@ "permissionMode": "権限モード", "modes": { "default": "デフォルトモード", + "auto": "Auto Mode", "acceptEdits": "編集を許可", "bypassPermissions": "権限をバイパス", "plan": "プランモード" }, "descriptions": { "default": "信頼されたコマンド(ls、cat、grep、git statusなど)のみ自動実行。その他のコマンドはスキップ。ワークスペースへの書き込みは可能。", + "auto": "A model classifier decides per tool call whether to approve or deny. Hands-off, but safer than Bypass — denials still happen.", "acceptEdits": "ワークスペース内ですべてのコマンドを自動実行。サンドボックス環境での完全自動モード。", "bypassPermissions": "制限なしの完全なシステムアクセス。すべてのコマンドがディスクとネットワークへの完全なアクセスで自動実行されます。注意して使用してください。", "plan": "プランニングモード - コマンドは実行されません" diff --git a/src/i18n/locales/ko/chat.json b/src/i18n/locales/ko/chat.json index bc4775b8..545f35ce 100644 --- a/src/i18n/locales/ko/chat.json +++ b/src/i18n/locales/ko/chat.json @@ -89,12 +89,14 @@ "permissionMode": "권한 모드", "modes": { "default": "기본 모드", + "auto": "Auto Mode", "acceptEdits": "편집 허용", "bypassPermissions": "권한 우회", "plan": "Plan 모드" }, "descriptions": { "default": "신뢰할 수 있는 명령어(ls, cat, grep, git status 등)만 자동 실행됩니다. 다른 명령어는 건너뜁니다. 워크스페이스에 쓰기 가능.", + "auto": "A model classifier decides per tool call whether to approve or deny. Hands-off, but safer than Bypass — denials still happen.", "acceptEdits": "워크스페이스 내에서 모든 명령어가 자동 실행됩니다. 샌드박스 내 완전 자동 모드.", "bypassPermissions": "제한 없는 전체 시스템 접근. 모든 명령어가 전체 디스크 및 네트워크 접근 권한으로 자동 실행됩니다. 주의해서 사용하세요.", "plan": "계획 모드 - 명령어가 실행되지 않습니다" diff --git a/src/i18n/locales/ru/chat.json b/src/i18n/locales/ru/chat.json index 4fd1a0b4..4be43572 100644 --- a/src/i18n/locales/ru/chat.json +++ b/src/i18n/locales/ru/chat.json @@ -89,12 +89,14 @@ "permissionMode": "Режим разрешений", "modes": { "default": "Режим по умолчанию", + "auto": "Auto Mode", "acceptEdits": "Принимать правки", "bypassPermissions": "Обход разрешений", "plan": "Режим планирования" }, "descriptions": { "default": "Только доверенные команды (ls, cat, grep, git status и т.д.) выполняются автоматически. Другие команды пропускаются. Может записывать в рабочее пространство.", + "auto": "A model classifier decides per tool call whether to approve or deny. Hands-off, but safer than Bypass — denials still happen.", "acceptEdits": "Все команды выполняются автоматически в рабочем пространстве. Полный автоматический режим с изолированным выполнением.", "bypassPermissions": "Полный системный доступ без ограничений. Все команды выполняются автоматически с полным доступом к диску и сети. Используйте с осторожностью.", "plan": "Режим планирования - команды не выполняются" diff --git a/src/i18n/locales/tr/chat.json b/src/i18n/locales/tr/chat.json index 2f60b91c..fb2cde17 100644 --- a/src/i18n/locales/tr/chat.json +++ b/src/i18n/locales/tr/chat.json @@ -89,12 +89,14 @@ "permissionMode": "İzin Modu", "modes": { "default": "Varsayılan Mod", + "auto": "Auto Mode", "acceptEdits": "Düzenlemeleri Kabul Et", "bypassPermissions": "İzinleri Atla", "plan": "Plan Modu" }, "descriptions": { "default": "Sadece güvenilir komutlar (ls, cat, grep, git status, vb.) otomatik çalışır. Diğer komutlar atlanır. Çalışma alanına yazabilir.", + "auto": "A model classifier decides per tool call whether to approve or deny. Hands-off, but safer than Bypass — denials still happen.", "acceptEdits": "Tüm komutlar çalışma alanı içinde otomatik çalışır. Sandbox'lu çalıştırma ile tam otomatik mod.", "bypassPermissions": "Kısıtlama olmadan tam sistem erişimi. Tüm komutlar tam disk ve ağ erişimiyle otomatik çalışır. Dikkatli kullan.", "plan": "Planlama modu — hiçbir komut çalıştırılmaz" diff --git a/src/i18n/locales/zh-CN/chat.json b/src/i18n/locales/zh-CN/chat.json index a478f18a..7f882281 100644 --- a/src/i18n/locales/zh-CN/chat.json +++ b/src/i18n/locales/zh-CN/chat.json @@ -89,12 +89,14 @@ "permissionMode": "权限模式", "modes": { "default": "默认模式", + "auto": "Auto Mode", "acceptEdits": "编辑模式", "bypassPermissions": "无限制模式", "plan": "计划模式" }, "descriptions": { "default": "只有受信任的命令(ls、cat、grep、git status 等)自动运行。其他命令将被跳过。可以写入工作区。", + "auto": "A model classifier decides per tool call whether to approve or deny. Hands-off, but safer than Bypass — denials still happen.", "acceptEdits": "工作区内的所有命令自动运行。完全自动模式,具有沙盒执行功能。", "bypassPermissions": "完全的系统访问,无限制。所有命令自动运行,具有完整的磁盘和网络访问权限。请谨慎使用。", "plan": "计划模式 - 不执行任何命令"