feat(coding-agent): 语音 Agent 设置 UI(开关 + Claude/OpenCode 选择 + 双热键 + 模型/权限/工作目录)
- UserPreferences 新增 7 字段(coding_agent_*):启用开关、后端 provider、模型、 权限模式、工作目录、面板热键、快取用热键;贯穿 struct/Wire/双向转换/默认。 - 前端 types.ts/ipc.ts 同步类型与 mock;CodingAgentPermissionMode 收敛到 types.ts 单一来源。 - 新增 CodingAgentSection(设置→高级):启用开关、Claude/OpenCode 选择、两个 ShortcutRecorder(可启用/停用)、权限模式、模型、工作目录。 - i18n 全 5 语言新增 settings.codingAgent.*。 热键实时注册与触发执行链路(coordinator 接线)随后续提交。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
d5756db8a6
commit
d8dc54695d
11 files changed
+352
-5
No files matched your search
@@ -611,6 +611,27 @@ pub struct UserPreferences {
|
||||
/// 「唤起 App」全局快捷键。`None` = 停用;`Some(...)` = 注册。默认 `Some(默认键)`。
|
||||
#[serde(default = "default_open_app_hotkey")]
|
||||
pub open_app_hotkey: Option<ShortcutBinding>,
|
||||
/// 快速 Agent(Voice Coding Agent):是否启用。默认关闭,需用户在高级设置开启。
|
||||
#[serde(default)]
|
||||
pub coding_agent_enabled: bool,
|
||||
/// Agent 后端:`claude-code-cli`(默认)或 `opencode-cli`。
|
||||
#[serde(default = "default_coding_agent_provider")]
|
||||
pub coding_agent_provider: String,
|
||||
/// Agent 模型(`None` = 运行时取便宜默认 sonnet)。
|
||||
#[serde(default)]
|
||||
pub coding_agent_model: Option<String>,
|
||||
/// 权限模式:plan/default/acceptEdits/bypassPermissions。默认 acceptEdits(放行+护栏)。
|
||||
#[serde(default = "default_coding_agent_permission_mode")]
|
||||
pub coding_agent_permission_mode: String,
|
||||
/// Agent 工作目录(`None` = 临时目录)。
|
||||
#[serde(default)]
|
||||
pub coding_agent_workdir: Option<String>,
|
||||
/// 热键 1:语音 Agent 面板键。默认 Cmd/Ctrl+Shift+Enter。`None` = 停用。
|
||||
#[serde(default = "default_coding_agent_panel_hotkey")]
|
||||
pub coding_agent_panel_hotkey: Option<ShortcutBinding>,
|
||||
/// 热键 2:快取用键(选中→Claude→回插)。默认 `None`(用户自配)。
|
||||
#[serde(default)]
|
||||
pub coding_agent_quick_hotkey: Option<ShortcutBinding>,
|
||||
/// 本地 Qwen3-ASR 当前激活的模型 id("qwen3-asr-0.6b" / "qwen3-asr-1.7b")。
|
||||
/// 仅在 active_asr_provider == "local-qwen3" 时有意义。
|
||||
#[serde(default = "default_local_asr_model")]
|
||||
@@ -809,6 +830,20 @@ struct UserPreferencesWire {
|
||||
translation_hotkey: Option<ShortcutBinding>,
|
||||
switch_style_hotkey: Option<ShortcutBinding>,
|
||||
open_app_hotkey: Option<ShortcutBinding>,
|
||||
#[serde(default)]
|
||||
coding_agent_enabled: bool,
|
||||
#[serde(default = "default_coding_agent_provider")]
|
||||
coding_agent_provider: String,
|
||||
#[serde(default)]
|
||||
coding_agent_model: Option<String>,
|
||||
#[serde(default = "default_coding_agent_permission_mode")]
|
||||
coding_agent_permission_mode: String,
|
||||
#[serde(default)]
|
||||
coding_agent_workdir: Option<String>,
|
||||
#[serde(default = "default_coding_agent_panel_hotkey")]
|
||||
coding_agent_panel_hotkey: Option<ShortcutBinding>,
|
||||
#[serde(default)]
|
||||
coding_agent_quick_hotkey: Option<ShortcutBinding>,
|
||||
#[serde(default = "default_local_asr_model")]
|
||||
local_asr_active_model: String,
|
||||
#[serde(default = "default_local_asr_mirror")]
|
||||
@@ -892,6 +927,13 @@ impl Default for UserPreferencesWire {
|
||||
// 默认携带默认键(Some),保证缺字段时仍是启用状态;None 专表「用户主动停用」。
|
||||
switch_style_hotkey: prefs.switch_style_hotkey,
|
||||
open_app_hotkey: prefs.open_app_hotkey,
|
||||
coding_agent_enabled: prefs.coding_agent_enabled,
|
||||
coding_agent_provider: prefs.coding_agent_provider,
|
||||
coding_agent_model: prefs.coding_agent_model,
|
||||
coding_agent_permission_mode: prefs.coding_agent_permission_mode,
|
||||
coding_agent_workdir: prefs.coding_agent_workdir,
|
||||
coding_agent_panel_hotkey: prefs.coding_agent_panel_hotkey,
|
||||
coding_agent_quick_hotkey: prefs.coding_agent_quick_hotkey,
|
||||
local_asr_active_model: prefs.local_asr_active_model,
|
||||
local_asr_mirror: prefs.local_asr_mirror,
|
||||
local_asr_keep_loaded_secs: prefs.local_asr_keep_loaded_secs,
|
||||
@@ -968,6 +1010,13 @@ impl<'de> Deserialize<'de> for UserPreferences {
|
||||
output_language_preference: wire.output_language_preference,
|
||||
qa_hotkey: wire.qa_hotkey,
|
||||
qa_save_history: wire.qa_save_history,
|
||||
coding_agent_enabled: wire.coding_agent_enabled,
|
||||
coding_agent_provider: wire.coding_agent_provider,
|
||||
coding_agent_model: wire.coding_agent_model,
|
||||
coding_agent_permission_mode: wire.coding_agent_permission_mode,
|
||||
coding_agent_workdir: wire.coding_agent_workdir,
|
||||
coding_agent_panel_hotkey: wire.coding_agent_panel_hotkey,
|
||||
coding_agent_quick_hotkey: wire.coding_agent_quick_hotkey,
|
||||
custom_combo_hotkey: wire.custom_combo_hotkey,
|
||||
translation_hotkey: wire
|
||||
.translation_hotkey
|
||||
@@ -1012,6 +1061,21 @@ fn default_qa_hotkey() -> Option<ShortcutBinding> {
|
||||
Some(ShortcutBinding::default_qa())
|
||||
}
|
||||
|
||||
fn default_coding_agent_provider() -> String {
|
||||
"claude-code-cli".to_string()
|
||||
}
|
||||
|
||||
fn default_coding_agent_permission_mode() -> String {
|
||||
"acceptEdits".to_string()
|
||||
}
|
||||
|
||||
fn default_coding_agent_panel_hotkey() -> Option<ShortcutBinding> {
|
||||
Some(ShortcutBinding {
|
||||
primary: "Enter".into(),
|
||||
modifiers: vec!["cmd".into(), "shift".into()],
|
||||
})
|
||||
}
|
||||
|
||||
fn default_translation_hotkey() -> ShortcutBinding {
|
||||
ShortcutBinding {
|
||||
primary: "Shift".into(),
|
||||
@@ -1670,6 +1734,13 @@ impl Default for UserPreferences {
|
||||
translation_hotkey: default_translation_hotkey(),
|
||||
switch_style_hotkey: default_switch_style_hotkey(),
|
||||
open_app_hotkey: default_open_app_hotkey(),
|
||||
coding_agent_enabled: false,
|
||||
coding_agent_provider: default_coding_agent_provider(),
|
||||
coding_agent_model: None,
|
||||
coding_agent_permission_mode: default_coding_agent_permission_mode(),
|
||||
coding_agent_workdir: None,
|
||||
coding_agent_panel_hotkey: default_coding_agent_panel_hotkey(),
|
||||
coding_agent_quick_hotkey: None,
|
||||
local_asr_active_model: default_local_asr_model(),
|
||||
local_asr_mirror: default_local_asr_mirror(),
|
||||
local_asr_keep_loaded_secs: default_local_asr_keep_loaded_secs(),
|
||||
|
||||
@@ -535,6 +535,20 @@ export const en: typeof zhCN = {
|
||||
cancelled: 'Cancelled',
|
||||
outputPlaceholder: 'Output streams here…',
|
||||
},
|
||||
codingAgent: {
|
||||
title: 'Voice Coding Agent',
|
||||
desc: 'Trigger Claude Code (or OpenCode) by a global hotkey to run quick tasks. Off by default; configure it here.',
|
||||
enable: 'Enable Voice Coding Agent',
|
||||
comingSoonNote: 'Config is saved now; hotkey triggering and the execution flow land in a later version.',
|
||||
provider: 'Agent backend',
|
||||
providerOpenCodeSoon: 'OpenCode (coming soon)',
|
||||
panelHotkey: 'Panel hotkey (voice agent)',
|
||||
panelHotkeyDesc: 'Record voice → ASR → Claude → streamed into a panel. Default Cmd/Ctrl+Shift+Enter.',
|
||||
quickHotkey: 'Quick-take hotkey',
|
||||
quickHotkeyDesc: 'Take selected text → Claude → result back at the cursor. No panel, faster.',
|
||||
model: 'Model',
|
||||
modelPlaceholder: 'Default: sonnet',
|
||||
},
|
||||
debug: {
|
||||
title: 'Debug tools',
|
||||
desc: 'For troubleshooting recognition issues; off by default.',
|
||||
|
||||
@@ -537,6 +537,20 @@ export const ja: typeof zhCN = {
|
||||
cancelled: 'キャンセル済み',
|
||||
outputPlaceholder: '出力はここにストリーミング表示されます…',
|
||||
},
|
||||
codingAgent: {
|
||||
title: '音声 Agent(クイック Agent)',
|
||||
desc: 'グローバルホットキーで Claude Code(または OpenCode)を直接起動してクイックタスクを実行。デフォルト無効、ここで設定。',
|
||||
enable: '音声 Agent を有効化',
|
||||
comingSoonNote: '設定はすぐ保存されます。ホットキー起動と実行フローは今後のバージョンで対応。',
|
||||
provider: 'Agent バックエンド',
|
||||
providerOpenCodeSoon: 'OpenCode(近日対応)',
|
||||
panelHotkey: 'パネルキー(音声 Agent)',
|
||||
panelHotkeyDesc: '録音 → ASR → Claude → パネルにストリーミング表示。デフォルト Cmd/Ctrl+Shift+Enter。',
|
||||
quickHotkey: 'クイック取得キー',
|
||||
quickHotkeyDesc: '選択テキストを取得 → Claude → 結果をカーソル位置へ。パネルなし、より高速。',
|
||||
model: 'モデル',
|
||||
modelPlaceholder: 'デフォルト: sonnet',
|
||||
},
|
||||
debug: {
|
||||
title: 'デバッグツール',
|
||||
desc: '認識の問題を調査するときに使用。通常はオフのままで構いません。',
|
||||
|
||||
@@ -537,6 +537,20 @@ export const ko: typeof zhCN = {
|
||||
cancelled: '취소됨',
|
||||
outputPlaceholder: '출력이 여기에 스트리밍됩니다…',
|
||||
},
|
||||
codingAgent: {
|
||||
title: '음성 Agent(빠른 Agent)',
|
||||
desc: '전역 단축키로 Claude Code(또는 OpenCode)를 바로 실행해 빠른 작업 수행. 기본 비활성, 여기서 설정.',
|
||||
enable: '음성 Agent 활성화',
|
||||
comingSoonNote: '설정은 즉시 저장됩니다. 단축키 트리거와 실행 흐름은 이후 버전에서 제공됩니다.',
|
||||
provider: 'Agent 백엔드',
|
||||
providerOpenCodeSoon: 'OpenCode(곧 지원)',
|
||||
panelHotkey: '패널 키(음성 Agent)',
|
||||
panelHotkeyDesc: '녹음 → ASR → Claude → 패널에 스트리밍. 기본 Cmd/Ctrl+Shift+Enter.',
|
||||
quickHotkey: '빠른 가져오기 키',
|
||||
quickHotkeyDesc: '선택한 텍스트 → Claude → 결과를 커서 위치로. 패널 없이 더 빠름.',
|
||||
model: '모델',
|
||||
modelPlaceholder: '기본: sonnet',
|
||||
},
|
||||
debug: {
|
||||
title: '디버그 도구',
|
||||
desc: '인식 문제를 진단할 때 사용합니다. 평소에는 꺼두어도 됩니다.',
|
||||
|
||||
@@ -533,6 +533,20 @@ export const zhCN = {
|
||||
cancelled: '已取消',
|
||||
outputPlaceholder: '输出会流式显示在这里…',
|
||||
},
|
||||
codingAgent: {
|
||||
title: '语音 Agent(快速 Agent)',
|
||||
desc: '按全局热键直接触发 Claude Code(或 OpenCode)执行快速任务。默认关闭,在此配置。',
|
||||
enable: '启用语音 Agent',
|
||||
comingSoonNote: '配置即时保存;热键触发与执行链路随后续版本生效。',
|
||||
provider: 'Agent 后端',
|
||||
providerOpenCodeSoon: 'OpenCode(即将支持)',
|
||||
panelHotkey: '面板键(语音 Agent)',
|
||||
panelHotkeyDesc: '录音 → ASR → Claude → 结果流式进面板。默认 Cmd/Ctrl+Shift+Enter。',
|
||||
quickHotkey: '快取用键',
|
||||
quickHotkeyDesc: '拿当前选中文本 → Claude → 结果回插光标处。不开面板、更快。',
|
||||
model: '模型',
|
||||
modelPlaceholder: '默认 sonnet',
|
||||
},
|
||||
debug: {
|
||||
title: '调试工具',
|
||||
desc: '排查识别问题时使用,平时无需开启。',
|
||||
|
||||
@@ -535,6 +535,20 @@ export const zhTW: typeof zhCN = {
|
||||
cancelled: '已取消',
|
||||
outputPlaceholder: '輸出會串流顯示在這裡…',
|
||||
},
|
||||
codingAgent: {
|
||||
title: '語音 Agent(快速 Agent)',
|
||||
desc: '按全域熱鍵直接觸發 Claude Code(或 OpenCode)執行快速任務。預設關閉,在此設定。',
|
||||
enable: '啟用語音 Agent',
|
||||
comingSoonNote: '設定即時儲存;熱鍵觸發與執行鏈路隨後續版本生效。',
|
||||
provider: 'Agent 後端',
|
||||
providerOpenCodeSoon: 'OpenCode(即將支援)',
|
||||
panelHotkey: '面板鍵(語音 Agent)',
|
||||
panelHotkeyDesc: '錄音 → ASR → Claude → 結果串流進面板。預設 Cmd/Ctrl+Shift+Enter。',
|
||||
quickHotkey: '快取用鍵',
|
||||
quickHotkeyDesc: '取目前選取文字 → Claude → 結果回插游標處。不開面板、更快。',
|
||||
model: '模型',
|
||||
modelPlaceholder: '預設 sonnet',
|
||||
},
|
||||
debug: {
|
||||
title: '除錯工具',
|
||||
desc: '排查辨識問題時使用,平時無需開啟。',
|
||||
|
||||
@@ -15,6 +15,7 @@ import type {
|
||||
HotkeyStatus,
|
||||
MicrophoneDevice,
|
||||
PermissionStatus,
|
||||
CodingAgentPermissionMode,
|
||||
PolishMode,
|
||||
QaHotkeyBinding,
|
||||
ShortcutBinding,
|
||||
@@ -100,6 +101,13 @@ let mockSettings: UserPreferences = {
|
||||
modifiers: defaultAppShortcutModifiers(),
|
||||
},
|
||||
openAppHotkey: { primary: "O", modifiers: defaultAppShortcutModifiers() },
|
||||
codingAgentEnabled: false,
|
||||
codingAgentProvider: "claude-code-cli",
|
||||
codingAgentModel: null,
|
||||
codingAgentPermissionMode: "acceptEdits",
|
||||
codingAgentWorkdir: null,
|
||||
codingAgentPanelHotkey: { primary: "Enter", modifiers: ["cmd", "shift"] },
|
||||
codingAgentQuickHotkey: null,
|
||||
localAsrActiveModel: "qwen3-asr-0.6b",
|
||||
localAsrMirror: "huggingface",
|
||||
localAsrKeepLoadedSecs: 300,
|
||||
@@ -1153,11 +1161,7 @@ export async function exportErrorLog(
|
||||
export { isTauri }
|
||||
|
||||
// ── Coding Agent / Claude 控制台 ───────────────────────────────────────
|
||||
export type CodingAgentPermissionMode =
|
||||
| "plan"
|
||||
| "default"
|
||||
| "acceptEdits"
|
||||
| "bypassPermissions"
|
||||
export type { CodingAgentPermissionMode }
|
||||
|
||||
export type McpHealth = "connected" | "failed" | "needs_auth" | "unknown"
|
||||
|
||||
|
||||
@@ -49,6 +49,13 @@ const previousPrefs: UserPreferences = {
|
||||
translationHotkey: { primary: 'Shift', modifiers: [] },
|
||||
switchStyleHotkey: { primary: 'S', modifiers: ['alt'] },
|
||||
openAppHotkey: { primary: 'O', modifiers: ['alt'] },
|
||||
codingAgentEnabled: false,
|
||||
codingAgentProvider: 'claude-code-cli',
|
||||
codingAgentModel: null,
|
||||
codingAgentPermissionMode: 'acceptEdits',
|
||||
codingAgentWorkdir: null,
|
||||
codingAgentPanelHotkey: { primary: 'Enter', modifiers: ['cmd', 'shift'] },
|
||||
codingAgentQuickHotkey: null,
|
||||
localAsrActiveModel: '',
|
||||
localAsrMirror: 'huggingface',
|
||||
localAsrKeepLoadedSecs: 300,
|
||||
|
||||
@@ -117,6 +117,13 @@ export type QaHotkeyBinding = ShortcutBinding;
|
||||
/** 自定义录音组合键绑定。当 hotkey.trigger == 'custom' 时使用。 */
|
||||
export type ComboBinding = ShortcutBinding;
|
||||
|
||||
export type CodingAgentProviderId = "claude-code-cli" | "opencode-cli";
|
||||
export type CodingAgentPermissionMode =
|
||||
| "plan"
|
||||
| "default"
|
||||
| "acceptEdits"
|
||||
| "bypassPermissions";
|
||||
|
||||
/** 模拟粘贴时按下的快捷键。仅 Windows/Linux 生效;macOS 走 AX 直写。
|
||||
* - ctrlV : 标准粘贴(默认;大多数编辑器、浏览器、IDE)
|
||||
* - ctrlShiftV : kitty / alacritty / wezterm / gnome-terminal / foot 等终端
|
||||
@@ -259,6 +266,20 @@ export interface UserPreferences {
|
||||
switchStyleHotkey: ShortcutBinding | null;
|
||||
/** 打开 OpenLess 主窗口的全局快捷键。null = 用户已停用(issue #576)。 */
|
||||
openAppHotkey: ShortcutBinding | null;
|
||||
/** 快速 Agent(Voice Coding Agent):是否启用。默认关闭。 */
|
||||
codingAgentEnabled: boolean;
|
||||
/** Agent 后端:claude-code-cli(默认)/ opencode-cli。 */
|
||||
codingAgentProvider: CodingAgentProviderId;
|
||||
/** Agent 模型,null = 运行时取便宜默认(sonnet)。 */
|
||||
codingAgentModel: string | null;
|
||||
/** 权限模式:plan/default/acceptEdits/bypassPermissions。 */
|
||||
codingAgentPermissionMode: CodingAgentPermissionMode;
|
||||
/** Agent 工作目录,null = 临时目录。 */
|
||||
codingAgentWorkdir: string | null;
|
||||
/** 热键 1:语音 Agent 面板键。null = 停用。 */
|
||||
codingAgentPanelHotkey: ShortcutBinding | null;
|
||||
/** 热键 2:快取用键(选中→Claude→回插)。null = 未配置。 */
|
||||
codingAgentQuickHotkey: ShortcutBinding | null;
|
||||
/** 本地 Qwen3-ASR 当前激活的模型 id。仅在 activeAsrProvider === 'local-qwen3' 时有意义。 */
|
||||
localAsrActiveModel: string;
|
||||
/** 本地模型下载源镜像('huggingface' / 'hf-mirror')。 */
|
||||
|
||||
@@ -0,0 +1,172 @@
|
||||
// 高级 → 语音 Agent(快速 Agent)配置:启用开关、后端(Claude / OpenCode)、
|
||||
// 两个全局热键、模型 / 权限模式 / 工作目录。配置经 UserPreferences 持久化;
|
||||
// 热键的实时注册与触发链路由 coordinator 接线(随后续版本生效)。
|
||||
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import type { CodingAgentPermissionMode, CodingAgentProviderId, ShortcutBinding } from '../../lib/types'
|
||||
import { useHotkeySettings } from '../../state/HotkeySettingsContext'
|
||||
import { ShortcutRecorder } from '../../components/ShortcutRecorder'
|
||||
import { Btn, Card } from '../_atoms'
|
||||
import { SectionDesc, SectionTitle, SettingRow, Toggle, inputStyle } from './shared'
|
||||
|
||||
const PERMISSION_MODES: CodingAgentPermissionMode[] = [
|
||||
'acceptEdits',
|
||||
'plan',
|
||||
'default',
|
||||
'bypassPermissions',
|
||||
]
|
||||
|
||||
const DEFAULT_PANEL_HOTKEY: ShortcutBinding = { primary: 'Enter', modifiers: ['cmd', 'shift'] }
|
||||
const DEFAULT_QUICK_HOTKEY: ShortcutBinding = { primary: 'J', modifiers: ['cmd', 'shift'] }
|
||||
|
||||
export function CodingAgentSection() {
|
||||
const { t } = useTranslation()
|
||||
const { prefs, updatePrefs: savePrefs } = useHotkeySettings()
|
||||
|
||||
if (!prefs) {
|
||||
return (
|
||||
<Card>
|
||||
<div style={{ fontSize: 12, color: 'var(--ol-ink-4)' }}>{t('common.loading')}</div>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
const enabled = prefs.codingAgentEnabled
|
||||
|
||||
const setHotkey = (
|
||||
key: 'codingAgentPanelHotkey' | 'codingAgentQuickHotkey',
|
||||
binding: ShortcutBinding | null,
|
||||
) => savePrefs({ ...prefs, [key]: binding })
|
||||
|
||||
const hotkeyRow = (
|
||||
key: 'codingAgentPanelHotkey' | 'codingAgentQuickHotkey',
|
||||
label: string,
|
||||
desc: string,
|
||||
fallback: ShortcutBinding,
|
||||
) => {
|
||||
const value = prefs[key]
|
||||
return (
|
||||
<SettingRow label={label} desc={desc}>
|
||||
{value ? (
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 6, width: '100%' }}>
|
||||
<ShortcutRecorder value={value} alignRecordButton onSave={b => setHotkey(key, b)} />
|
||||
<button
|
||||
onClick={() => void setHotkey(key, null)}
|
||||
style={{
|
||||
alignSelf: 'flex-start',
|
||||
fontSize: 11,
|
||||
padding: '3px 10px',
|
||||
background: 'transparent',
|
||||
color: 'var(--ol-ink-4)',
|
||||
border: '0.5px solid var(--ol-line-strong)',
|
||||
borderRadius: 6,
|
||||
fontFamily: 'inherit',
|
||||
cursor: 'default',
|
||||
}}
|
||||
>
|
||||
{t('settings.shortcuts.disable', 'Disable')}
|
||||
</button>
|
||||
</div>
|
||||
) : (
|
||||
<Btn variant="blue" size="sm" onClick={() => void setHotkey(key, fallback)}>
|
||||
{t('settings.shortcuts.enable', 'Enable')}
|
||||
</Btn>
|
||||
)}
|
||||
</SettingRow>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<SectionTitle>{t('settings.codingAgent.title')}</SectionTitle>
|
||||
<SectionDesc>{t('settings.codingAgent.desc')}</SectionDesc>
|
||||
|
||||
<SettingRow label={t('settings.codingAgent.enable')} desc={t('settings.codingAgent.comingSoonNote')}>
|
||||
<Toggle
|
||||
on={enabled}
|
||||
onToggle={next => void savePrefs({ ...prefs, codingAgentEnabled: next })}
|
||||
/>
|
||||
</SettingRow>
|
||||
|
||||
{enabled && (
|
||||
<>
|
||||
<SettingRow label={t('settings.codingAgent.provider')}>
|
||||
<select
|
||||
value={prefs.codingAgentProvider}
|
||||
onChange={e =>
|
||||
void savePrefs({
|
||||
...prefs,
|
||||
codingAgentProvider: e.target.value as CodingAgentProviderId,
|
||||
})
|
||||
}
|
||||
style={{ ...inputStyle, maxWidth: 240, cursor: 'pointer' }}
|
||||
>
|
||||
<option value="claude-code-cli">Claude Code</option>
|
||||
<option value="opencode-cli">{t('settings.codingAgent.providerOpenCodeSoon')}</option>
|
||||
</select>
|
||||
</SettingRow>
|
||||
|
||||
{hotkeyRow(
|
||||
'codingAgentPanelHotkey',
|
||||
t('settings.codingAgent.panelHotkey'),
|
||||
t('settings.codingAgent.panelHotkeyDesc'),
|
||||
DEFAULT_PANEL_HOTKEY,
|
||||
)}
|
||||
{hotkeyRow(
|
||||
'codingAgentQuickHotkey',
|
||||
t('settings.codingAgent.quickHotkey'),
|
||||
t('settings.codingAgent.quickHotkeyDesc'),
|
||||
DEFAULT_QUICK_HOTKEY,
|
||||
)}
|
||||
|
||||
<SettingRow label={t('settings.codingConsole.permissionMode')}>
|
||||
<select
|
||||
value={prefs.codingAgentPermissionMode}
|
||||
onChange={e =>
|
||||
void savePrefs({
|
||||
...prefs,
|
||||
codingAgentPermissionMode: e.target.value as CodingAgentPermissionMode,
|
||||
})
|
||||
}
|
||||
style={{ ...inputStyle, maxWidth: 240, cursor: 'pointer' }}
|
||||
>
|
||||
{PERMISSION_MODES.map(m => (
|
||||
<option key={m} value={m}>
|
||||
{t(`settings.codingConsole.mode.${m}`)}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</SettingRow>
|
||||
|
||||
<SettingRow label={t('settings.codingAgent.model')}>
|
||||
<input
|
||||
type="text"
|
||||
value={prefs.codingAgentModel ?? ''}
|
||||
placeholder={t('settings.codingAgent.modelPlaceholder')}
|
||||
spellCheck={false}
|
||||
onChange={e => {
|
||||
const v = e.target.value.trim()
|
||||
void savePrefs({ ...prefs, codingAgentModel: v === '' ? null : v })
|
||||
}}
|
||||
style={inputStyle}
|
||||
/>
|
||||
</SettingRow>
|
||||
|
||||
<SettingRow label={t('settings.codingConsole.workdir')} desc={t('settings.codingConsole.workdirDesc')}>
|
||||
<input
|
||||
type="text"
|
||||
value={prefs.codingAgentWorkdir ?? ''}
|
||||
placeholder={t('settings.codingConsole.workdirPlaceholder')}
|
||||
spellCheck={false}
|
||||
onChange={e => {
|
||||
const v = e.target.value.trim()
|
||||
void savePrefs({ ...prefs, codingAgentWorkdir: v === '' ? null : v })
|
||||
}}
|
||||
style={inputStyle}
|
||||
/>
|
||||
</SettingRow>
|
||||
</>
|
||||
)}
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -11,6 +11,7 @@ import { PermissionsSection } from './PermissionsSection';
|
||||
import { DataStorageSection } from './DataStorageSection';
|
||||
import { LocalModelSection } from './LocalModelSection';
|
||||
import { DebugToolsSection } from './DebugToolsSection';
|
||||
import { CodingAgentSection } from './CodingAgentSection';
|
||||
import { ClaudeConsoleSection } from './ClaudeConsoleSection';
|
||||
import { BetaChannelSection } from './BetaChannelSection';
|
||||
|
||||
@@ -73,6 +74,7 @@ export function AdvancedTab() {
|
||||
<>
|
||||
<LocalModelSection />
|
||||
<DebugToolsSection />
|
||||
<CodingAgentSection />
|
||||
<ClaudeConsoleSection />
|
||||
<BetaChannelSection />
|
||||
</>
|
||||
|
||||
Reference in new issue
Block a user