diff --git a/cli.js b/cli.js index ab9858f7..ac9aeb53 100644 --- a/cli.js +++ b/cli.js @@ -909,8 +909,8 @@ function isPlainObject(value) { return !!value && typeof value === 'object' && !Array.isArray(value); } -const TOOL_CONFIG_PERMISSION_TARGETS = new Set(['codex', 'claude', 'opencode', 'kilocode']); -const TOOL_CONFIG_PERMISSION_DEFAULTS = Object.freeze({ codex: false, claude: false, opencode: false, kilocode: false }); +const TOOL_CONFIG_PERMISSION_TARGETS = new Set(['codex', 'claude', 'opencode', 'kilocode', 'openclaw']); +const TOOL_CONFIG_PERMISSION_DEFAULTS = Object.freeze({ codex: false, claude: false, opencode: false, kilocode: false, openclaw: false }); let toolConfigWriteGuardDepth = 0; function enterToolConfigWriteGuard() { @@ -938,7 +938,8 @@ function normalizeToolConfigPermissions(value) { codex: source.codex === true, claude: source.claude === true, opencode: source.opencode === true, - kilocode: source.kilocode === true + kilocode: source.kilocode === true, + openclaw: source.openclaw === true }; } @@ -1197,10 +1198,16 @@ function getApiToolConfigWriteTarget(action) { 'apply-kilocode-config', 'start-kilocode' ]); + const openclawWriteActions = new Set([ + 'apply-openclaw-config', + 'apply-openclaw-agents-file', + 'apply-openclaw-workspace-file' + ]); if (codexWriteActions.has(name)) return 'codex'; if (claudeWriteActions.has(name)) return 'claude'; if (opencodeWriteActions.has(name)) return 'opencode'; if (kilocodeWriteActions.has(name)) return 'kilocode'; + if (openclawWriteActions.has(name)) return 'openclaw'; return ''; } diff --git a/package-lock.json b/package-lock.json index cf223c43..2c4da6ec 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "codexmate", - "version": "0.1.3", + "version": "0.1.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "codexmate", - "version": "0.1.3", + "version": "0.1.4", "license": "Apache-2.0", "dependencies": { "@iarna/toml": "^2.2.5", diff --git a/package.json b/package.json index 75074576..f44dc619 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "codexmate", - "version": "0.1.3", + "version": "0.1.4", "description": "Codex/Claude Code/OpenClaw 配置、会话与任务编排 CLI + Web 工具", "main": "cli.js", "bin": { diff --git a/tests/e2e/test-openclaw.js b/tests/e2e/test-openclaw.js index ad84b3de..2f1d2e48 100644 --- a/tests/e2e/test-openclaw.js +++ b/tests/e2e/test-openclaw.js @@ -30,6 +30,9 @@ module.exports = async function testOpenclaw(ctx) { assert(openclawReadEmpty.authProfilesByProvider['openai-codex'].editable === true, 'get-openclaw-config missing editable auth profile flag'); // ========== Apply OpenClaw Config Tests ========== + const enableOpenclawWrites = await api('set-tool-config-permission', { target: 'openclaw', allowWrite: true }); + assert(enableOpenclawWrites.success === true, 'set-tool-config-permission(openclaw) should succeed'); + const openclawInvalid = await api('apply-openclaw-config', { content: '', lineEnding: '\n' }); assert(openclawInvalid.success === false, 'apply-openclaw-config should reject empty content'); diff --git a/tests/unit/config-tabs-ui.test.mjs b/tests/unit/config-tabs-ui.test.mjs index af89f49b..c89b8f63 100644 --- a/tests/unit/config-tabs-ui.test.mjs +++ b/tests/unit/config-tabs-ui.test.mjs @@ -501,7 +501,7 @@ test('config template keeps expected config tabs in top and side navigation', () ); assert.match( html, - /:class="\['card', \{ active: currentOpenclawConfig === name \}\]"[\s\S]*@click="applyOpenclawConfig\(name\)"[\s\S]*@keydown\.enter\.self\.prevent="applyOpenclawConfig\(name\)"[\s\S]*@keydown\.space\.self\.prevent="applyOpenclawConfig\(name\)"[\s\S]*tabindex="0"[\s\S]*role="button"[\s\S]*:aria-current="currentOpenclawConfig === name \? 'true' : null"/ + /:class="\['card', \{ active: currentOpenclawConfig === name, disabled: !isToolConfigWriteAllowed\('openclaw'\) \}\]"[\s\S]*@click="isToolConfigWriteAllowed\('openclaw'\) && applyOpenclawConfig\(name\)"[\s\S]*@keydown\.enter\.self\.prevent="isToolConfigWriteAllowed\('openclaw'\) && applyOpenclawConfig\(name\)"[\s\S]*@keydown\.space\.self\.prevent="isToolConfigWriteAllowed\('openclaw'\) && applyOpenclawConfig\(name\)"[\s\S]*:tabindex="isToolConfigWriteAllowed\('openclaw'\) \? 0 : -1"[\s\S]*role="button"[\s\S]*:aria-disabled="!isToolConfigWriteAllowed\('openclaw'\) \? 'true' : null"[\s\S]*:aria-current="currentOpenclawConfig === name \? 'true' : null"/ ); assert.match(html, /class="session-item-copy session-item-pin"/); assert.doesNotMatch(sessionsPanel, /sessionsViewMode/); diff --git a/tests/unit/opencode-config-ui.test.mjs b/tests/unit/opencode-config-ui.test.mjs index afadc829..17e1d563 100644 --- a/tests/unit/opencode-config-ui.test.mjs +++ b/tests/unit/opencode-config-ui.test.mjs @@ -117,7 +117,7 @@ test('opencode backend actions are permission guarded in cli source', () => { const cli = readProjectFile('cli.js'); assert.match(cli, /const OPENCODE_GLOBAL_JSONC_CONFIG_FILE = path\.join\(OPENCODE_CONFIG_DIR, 'opencode\.jsonc'\)/); assert.match(cli, /const OPENCODE_CONFIG_ENV_FILE = process\.env\.OPENCODE_CONFIG/); - assert.match(cli, /const TOOL_CONFIG_PERMISSION_TARGETS = new Set\(\['codex', 'claude', 'opencode', 'kilocode'\]\)/); + assert.match(cli, /const TOOL_CONFIG_PERMISSION_TARGETS = new Set\(\['codex', 'claude', 'opencode', 'kilocode', 'openclaw'\]\)/); assert.match(cli, /function applyOpencodeConfigRaw\(params = \{\}\) \{[\s\S]*assertToolConfigWriteAllowed\('opencode'\)/); assert.match(cli, /function updateOpencodeSelection\(params = \{\}\) \{[\s\S]*assertToolConfigWriteAllowed\('opencode'\)/); assert.match(cli, /case 'get-opencode-config':/); diff --git a/tests/unit/web-ui-behavior-parity.test.mjs b/tests/unit/web-ui-behavior-parity.test.mjs index 2c6e54f5..fe530e95 100644 --- a/tests/unit/web-ui-behavior-parity.test.mjs +++ b/tests/unit/web-ui-behavior-parity.test.mjs @@ -461,6 +461,7 @@ test('captured bundled app skeleton only exposes expected data key drift versus 'showPromptTemplateVarModal', 'brandHovered', 'promptsHint', + 'currentInstalledCommandCards', ]; allowedExtraCurrentKeys.push( 'lang', @@ -991,7 +992,8 @@ test('captured bundled app skeleton only exposes expected data key drift versus 'localProxyUpstreamOptions', 'currentClaudeHaikuModel', 'currentClaudeSonnetModel', - 'currentClaudeOpusModel' + 'currentClaudeOpusModel', + 'currentInstalledCommandCards' ]; if (parityAgainstHead) { const allowedExtraComputedKeySet = new Set(allowedExtraCurrentComputedKeys); diff --git a/tests/unit/web-ui-preferences.test.mjs b/tests/unit/web-ui-preferences.test.mjs index 49741d99..2aa7c62f 100644 --- a/tests/unit/web-ui-preferences.test.mjs +++ b/tests/unit/web-ui-preferences.test.mjs @@ -219,14 +219,15 @@ test('web UI preference debounce preserves nested pending overrides', async () = test('web UI preferences preserve KiloCode write permission on reload', () => { const context = createContext([], createMemoryStorage()); context.applyWebUiPreferences({ - toolConfigPermissions: { codex: false, claude: false, opencode: false, kilocode: true } + toolConfigPermissions: { codex: false, claude: false, opencode: false, kilocode: true, openclaw: false } }, { applyNavigation: false }); assert.deepStrictEqual(context.toolConfigPermissions, { codex: false, claude: false, opencode: false, - kilocode: true + kilocode: true, + openclaw: false }); }); diff --git a/web-ui/app.js b/web-ui/app.js index 3cc152c7..8f2b0562 100644 --- a/web-ui/app.js +++ b/web-ui/app.js @@ -396,8 +396,8 @@ document.addEventListener('DOMContentLoaded', () => { providerCacheError: '', providerCacheRequestSeq: 0, settingsTab: 'general', - toolConfigPermissions: { codex: false, claude: false, opencode: false, kilocode: false }, - toolConfigPermissionSaving: { codex: false, claude: false, opencode: false, kilocode: false }, + toolConfigPermissions: { codex: false, claude: false, opencode: false, kilocode: false, openclaw: false }, + toolConfigPermissionSaving: { codex: false, claude: false, opencode: false, kilocode: false, openclaw: false }, sessionTrashEnabled: true, sessionTrashItems: [], sessionTrashVisibleCount: SESSION_TRASH_PAGE_SIZE, diff --git a/web-ui/modules/app.computed.dashboard.mjs b/web-ui/modules/app.computed.dashboard.mjs index f531f525..92d169d2 100644 --- a/web-ui/modules/app.computed.dashboard.mjs +++ b/web-ui/modules/app.computed.dashboard.mjs @@ -174,10 +174,6 @@ export function createDashboardComputed() { }; }); }, - currentInstalledCommandCards() { - const targets = Array.isArray(this.installTargetCards) ? this.installTargetCards : []; - return targets.filter((target) => target && target.installed === true); - }, installRegistryPreview() { return this.resolveInstallRegistryUrl(this.installRegistryPreset, this.installRegistryCustom); }, diff --git a/web-ui/modules/app.methods.startup-claude.mjs b/web-ui/modules/app.methods.startup-claude.mjs index 07993a25..8a3a46ce 100644 --- a/web-ui/modules/app.methods.startup-claude.mjs +++ b/web-ui/modules/app.methods.startup-claude.mjs @@ -144,7 +144,8 @@ export function createStartupClaudeMethods(options = {}) { codex: statusRes.toolConfigPermissions.codex === true, claude: statusRes.toolConfigPermissions.claude === true, opencode: statusRes.toolConfigPermissions.opencode === true, - kilocode: statusRes.toolConfigPermissions.kilocode === true + kilocode: statusRes.toolConfigPermissions.kilocode === true, + openclaw: statusRes.toolConfigPermissions.openclaw === true }; } this.providersList = listRes.providers; diff --git a/web-ui/modules/app.methods.tool-config-permissions.mjs b/web-ui/modules/app.methods.tool-config-permissions.mjs index 2f64feb2..1fb99697 100644 --- a/web-ui/modules/app.methods.tool-config-permissions.mjs +++ b/web-ui/modules/app.methods.tool-config-permissions.mjs @@ -3,7 +3,7 @@ export function createToolConfigPermissionMethods(options = {}) { function normalizeTarget(value) { const target = typeof value === 'string' ? value.trim().toLowerCase() : ''; - return target === 'codex' || target === 'claude' || target === 'opencode' || target === 'kilocode' ? target : ''; + return target === 'codex' || target === 'claude' || target === 'opencode' || target === 'kilocode' || target === 'openclaw' ? target : ''; } function normalizePermissions(value) { @@ -12,7 +12,8 @@ export function createToolConfigPermissionMethods(options = {}) { codex: source.codex === true, claude: source.claude === true, opencode: source.opencode === true, - kilocode: source.kilocode === true + kilocode: source.kilocode === true, + openclaw: source.openclaw === true }; } diff --git a/web-ui/modules/app.methods.web-ui-preferences.mjs b/web-ui/modules/app.methods.web-ui-preferences.mjs index 510fce67..20164c11 100644 --- a/web-ui/modules/app.methods.web-ui-preferences.mjs +++ b/web-ui/modules/app.methods.web-ui-preferences.mjs @@ -439,7 +439,8 @@ export function createWebUiPreferencesMethods(options = {}) { codex: source.toolConfigPermissions.codex === true, claude: source.toolConfigPermissions.claude === true, opencode: source.toolConfigPermissions.opencode === true, - kilocode: source.toolConfigPermissions.kilocode === true + kilocode: source.toolConfigPermissions.kilocode === true, + openclaw: source.toolConfigPermissions.openclaw === true }; } if (Array.isArray(source.deletedClaudeSettingsImports)) { diff --git a/web-ui/modules/i18n/locales/en.mjs b/web-ui/modules/i18n/locales/en.mjs index 262b2da3..067023e1 100644 --- a/web-ui/modules/i18n/locales/en.mjs +++ b/web-ui/modules/i18n/locales/en.mjs @@ -619,14 +619,8 @@ const en = Object.freeze({ // Docs panel 'docs.title': 'CLI Install', - 'docs.subtitle': 'Install commands for Claude Code / Gemini CLI / CodeBuddy Code / Codex CLI / KiloCode CLI.', 'docs.section.commands': 'Commands', - 'docs.section.commandsNote': 'Copy and run directly.', - 'docs.installed.title': 'Currently installed commands', - 'docs.installed.count': '{count} installed', - 'docs.installed.empty': 'No installed commands detected', 'docs.section.faq': 'FAQ', - 'docs.section.faqNote': 'Common issues and tips.', 'docs.command.aria': '{name} command', 'docs.registryHintPrefix': 'Command will append:', 'docs.registryHintCustom': 'Enter a full URL (http/https) to append as registry.', @@ -634,8 +628,6 @@ const en = Object.freeze({ 'docs.meta.bin': 'bin: {bin}', 'docs.termuxLabel': 'Termux', 'docs.termuxAria': 'Termux Codex CLI command', - 'docs.rule.1': 'Commands depend on package manager, registry and action.', - 'docs.rule.2': 'Custom registry is used for install/update only.', 'docs.tip.win.1': 'If PowerShell reports permission errors (EACCES/EPERM), run the install command as Administrator.', 'docs.tip.win.2': 'If the command is still not found after install, reopen the terminal and run: where codex / where claude / where gemini / where codebuddy.', 'docs.tip.win.3': 'If your network blocks npm, try switching registry presets (npmmirror / Tencent / Custom).', @@ -1544,6 +1536,11 @@ const en = Object.freeze({ 'toolConfig.kilocode.lockedTitle': 'Read-only mode', 'toolConfig.kilocode.lockedDesc': 'Enable write access to auto-sync config or launch KiloCode.', 'toolConfig.kilocode.confirmMessage': 'When enabled, actions in the KiloCode tab can write ~/.config/kilo/kilo.jsonc or an existing kilo.json, and can launch local KiloCode.', + 'toolConfig.openclaw.title': 'OpenClaw config writes', + 'toolConfig.openclaw.desc': 'Read-only by default; enable to apply OpenClaw configs and write AGENTS.md and other workspace files.', + 'toolConfig.openclaw.confirmMessage': 'When enabled, actions in the OpenClaw tab can write openclaw.json and OpenClaw workspace files (AGENTS.md, SOUL.md, etc.).', + 'toolConfig.openclaw.lockedTitle': 'OpenClaw is read-only', + 'toolConfig.openclaw.lockedDesc': 'OpenClaw config is not written here. To apply configs or edit workspace files, enable write access on this tab first.', 'kilocode.providerModel.title': 'KiloCode provider / model', 'kilocode.connection.title': 'KiloCode connection', 'kilocode.targetFile': 'Active KiloCode config: {path} · {status}', diff --git a/web-ui/modules/i18n/locales/ja.mjs b/web-ui/modules/i18n/locales/ja.mjs index fba2ab2a..6df3d364 100644 --- a/web-ui/modules/i18n/locales/ja.mjs +++ b/web-ui/modules/i18n/locales/ja.mjs @@ -621,14 +621,8 @@ const ja = Object.freeze({ // Docs panel 'docs.title': 'CLI インストールドキュメント', - 'docs.subtitle': 'Claude Code / Gemini CLI / CodeBuddy Code / Codex CLI / KiloCode CLI コマンドを表示。', 'docs.section.commands': 'インストールコマンド', - 'docs.section.commandsNote': 'コマンドは直接コピーできます。', - 'docs.installed.title': '現在インストール済みのコマンド', - 'docs.installed.count': '{count} 個インストール済み', - 'docs.installed.empty': 'インストール済みコマンドは検出されていません', 'docs.section.faq': 'よくある質問', - 'docs.section.faqNote': 'よくある質問は以下をご覧ください。', 'docs.command.aria': '{name} コマンド', 'docs.registryHintPrefix': 'コマンドに付加:', 'docs.registryHintCustom': '完全な URL(http/https 含む)を入力してください。コマンドに自動付加されます。', @@ -636,8 +630,6 @@ const ja = Object.freeze({ 'docs.meta.bin': 'bin: {bin}', 'docs.termuxLabel': 'Termux', 'docs.termuxAria': 'Termux Codex CLI command', - 'docs.rule.1': 'コマンドは現在のパッケージマネージャー、ミラー、操作に基づいて生成されます。', - 'docs.rule.2': 'カスタムミラーはインストールとアップグレードにのみ使用されます。', 'docs.tip.win.1': 'PowerShell で権限不足(EACCES/EPERM)エラーが発生した場合は、管理者としてインストールコマンドを実行してください。', 'docs.tip.win.2': 'インストール後にコマンドが見つからない場合は、ターミナルを再起動して実行:where codex / where claude / where gemini / where codebuddy。', 'docs.tip.win.3': '企業ネットワークで制限がある場合は、ミラーソース(npmmirror / Tencent Cloud / カスタム)を切り替えてください。', @@ -1531,6 +1523,11 @@ const ja = Object.freeze({ 'toolConfig.kilocode.lockedTitle': '読み取り専用モード', 'toolConfig.kilocode.lockedDesc': '書き込み権限を有効化すると、設定の自動同期または KiloCode の起動ができます。', 'toolConfig.kilocode.confirmMessage': '有効化すると、KiloCode タブ内の操作が ~/.config/kilo/kilo.jsonc または既存の kilo.json に書き込み、ローカル KiloCode を起動できます。', + 'toolConfig.openclaw.title': 'OpenClaw 設定の書き込み', + 'toolConfig.openclaw.desc': '既定は読み取り専用。有効化すると OpenClaw 設定を適用し、AGENTS.md などのワークスペースファイルを書き込みできます。', + 'toolConfig.openclaw.confirmMessage': '有効化すると、OpenClaw タブ内の操作が openclaw.json およびワークスペースファイル(AGENTS.md、SOUL.md など)に書き込みできます。', + 'toolConfig.openclaw.lockedTitle': 'OpenClaw は読み取り専用です', + 'toolConfig.openclaw.lockedDesc': 'ここでは OpenClaw 設定を書き込みません。設定を適用またはワークスペースファイルを編集するには、このタブの書き込みスイッチを有効化してください。', 'kilocode.providerModel.title': 'KiloCode プロバイダー / モデル', 'kilocode.connection.title': 'KiloCode 接続', 'kilocode.targetFile': '有効な KiloCode 設定:{path} · {status}', diff --git a/web-ui/modules/i18n/locales/vi.mjs b/web-ui/modules/i18n/locales/vi.mjs index a4c882a4..83a6f778 100644 --- a/web-ui/modules/i18n/locales/vi.mjs +++ b/web-ui/modules/i18n/locales/vi.mjs @@ -826,14 +826,8 @@ const vi = Object.freeze({ 'modal.openclaw.quick.optionsHint': 'Khi tắt ghi đè, chỉ điền các trường còn thiếu.', 'modal.openclaw.quick.writeToEditor': 'Ghi vào editor', 'docs.title': 'Cài CLI', - 'docs.subtitle': 'Lệnh cài đặt cho Claude Code / Gemini CLI / CodeBuddy Code / Codex CLI / KiloCode CLI.', 'docs.section.commands': 'Lệnh', - 'docs.section.commandsNote': 'Sao chép và chạy trực tiếp.', - 'docs.installed.title': 'Lệnh hiện đã cài đặt', - 'docs.installed.count': 'Đã cài {count}', - 'docs.installed.empty': 'Chưa phát hiện lệnh đã cài', 'docs.section.faq': 'FAQ', - 'docs.section.faqNote': 'Vấn đề phổ biến và mẹo.', 'docs.command.aria': 'Lệnh {name}', 'docs.registryHintPrefix': 'Lệnh sẽ thêm:', 'docs.registryHintCustom': 'Nhập URL đầy đủ (http/https) để thêm làm registry.', @@ -841,8 +835,6 @@ const vi = Object.freeze({ 'docs.meta.bin': 'bin: {bin}', 'docs.termuxLabel': 'Termux', 'docs.termuxAria': 'Lệnh Codex CLI cho Termux', - 'docs.rule.1': 'Lệnh phụ thuộc vào trình quản lý gói, registry và hành động.', - 'docs.rule.2': 'Registry tùy chỉnh chỉ dùng cho cài đặt/cập nhật.', 'docs.tip.win.1': 'Nếu PowerShell báo lỗi quyền (EACCES/EPERM), chạy lệnh cài đặt với quyền Administrator.', 'docs.tip.win.2': 'Nếu lệnh không tìm thấy sau cài đặt, mở lại terminal và chạy: where codex / where claude.', 'docs.tip.win.3': 'Nếu mạng chặn npm, thử chuyển registry (npmmirror / Tencent / Tùy chỉnh).', @@ -1516,6 +1508,11 @@ const vi = Object.freeze({ 'toolConfig.kilocode.lockedTitle': 'Chế độ chỉ đọc', 'toolConfig.kilocode.lockedDesc': 'Bật quyền ghi để tự động đồng bộ cấu hình hoặc khởi chạy KiloCode.', 'toolConfig.kilocode.confirmMessage': 'Khi bật, các thao tác trong tab KiloCode có thể ghi ~/.config/kilo/kilo.jsonc hoặc kilo.json hiện có, và có thể khởi chạy KiloCode cục bộ.', + 'toolConfig.openclaw.title': 'Ghi cấu hình OpenClaw', + 'toolConfig.openclaw.desc': 'Mặc định chỉ đọc; bật để áp dụng cấu hình OpenClaw và ghi AGENTS.md cùng các tệp workspace khác.', + 'toolConfig.openclaw.confirmMessage': 'Khi bật, các thao tác trong tab OpenClaw có thể ghi openclaw.json và các tệp workspace (AGENTS.md, SOUL.md, v.v.).', + 'toolConfig.openclaw.lockedTitle': 'OpenClaw đang ở chế độ chỉ đọc', + 'toolConfig.openclaw.lockedDesc': 'Không ghi cấu hình OpenClaw ở đây. Để áp dụng cấu hình hoặc sửa tệp workspace, hãy bật quyền ghi trên tab này trước.', 'kilocode.providerModel.title': 'Nhà cung cấp / mô hình KiloCode', 'kilocode.connection.title': 'Kết nối KiloCode', 'kilocode.targetFile': 'Cấu hình KiloCode đang dùng: {path} · {status}', diff --git a/web-ui/modules/i18n/locales/zh-tw.mjs b/web-ui/modules/i18n/locales/zh-tw.mjs index 9f05bae0..a6405f09 100644 --- a/web-ui/modules/i18n/locales/zh-tw.mjs +++ b/web-ui/modules/i18n/locales/zh-tw.mjs @@ -619,14 +619,8 @@ const zhTw = Object.freeze({ // Docs panel 'docs.title': 'CLI 安裝文檔', - 'docs.subtitle': '查看 Claude Code / Gemini CLI / CodeBuddy Code / Codex CLI / KiloCode CLI 命令。', 'docs.section.commands': '安裝命令', - 'docs.section.commandsNote': '命令可直接複製。', - 'docs.installed.title': '目前已安裝命令', - 'docs.installed.count': '已安裝 {count} 個', - 'docs.installed.empty': '未偵測到已安裝命令', 'docs.section.faq': '常見問題', - 'docs.section.faqNote': '常見問題見下。', 'docs.command.aria': '{name} 命令', 'docs.registryHintPrefix': '命令將附加:', 'docs.registryHintCustom': '請輸入完整 URL(含 http/https),將自動附加到命令。', @@ -634,8 +628,6 @@ const zhTw = Object.freeze({ 'docs.meta.bin': 'bin: {bin}', 'docs.termuxLabel': 'Termux', 'docs.termuxAria': 'Termux Codex CLI command', - 'docs.rule.1': '命令按目前包管理器、鏡像與操作生成。', - 'docs.rule.2': '自訂鏡像僅用於安裝與升級。', 'docs.tip.win.1': 'PowerShell 報權限不足(EACCES/EPERM)時,請以管理員身份執行安裝命令。', 'docs.tip.win.2': '安裝後若仍提示找不到命令,重開終端並執行:where codex / where claude / where gemini / where codebuddy。', 'docs.tip.win.3': '公司網路受限時,可先切換鏡像源快捷項(npmmirror / 騰訊雲 / 自訂)。', @@ -1544,6 +1536,11 @@ const zhTw = Object.freeze({ 'toolConfig.kilocode.lockedTitle': '唯讀模式', 'toolConfig.kilocode.lockedDesc': '啟用寫入權限後可自動同步設定或啟動 KiloCode。', 'toolConfig.kilocode.confirmMessage': '開啟後,KiloCode tab 內的操作會寫入 ~/.config/kilo/kilo.jsonc 或既有的 kilo.json,並可啟動本機 KiloCode。', + 'toolConfig.openclaw.title': 'OpenClaw 設定寫入', + 'toolConfig.openclaw.desc': '預設唯讀;啟用後可套用 OpenClaw 設定並寫入 AGENTS.md 與其他工作區檔案。', + 'toolConfig.openclaw.confirmMessage': '開啟後,OpenClaw tab 內的操作會寫入 openclaw.json 及 OpenClaw 工作區檔案(AGENTS.md、SOUL.md 等)。', + 'toolConfig.openclaw.lockedTitle': 'OpenClaw 目前為唯讀', + 'toolConfig.openclaw.lockedDesc': '這裡不會寫入 OpenClaw 設定。要套用設定或編輯工作區檔案,請先開啟本 tab 的寫入開關。', 'kilocode.providerModel.title': 'KiloCode provider / 模型', 'kilocode.connection.title': 'KiloCode 連線', 'kilocode.targetFile': 'KiloCode 生效設定:{path} · {status}', diff --git a/web-ui/modules/i18n/locales/zh.mjs b/web-ui/modules/i18n/locales/zh.mjs index fad8ce5d..e145cf09 100644 --- a/web-ui/modules/i18n/locales/zh.mjs +++ b/web-ui/modules/i18n/locales/zh.mjs @@ -619,14 +619,8 @@ const zh = Object.freeze({ // Docs panel 'docs.title': 'CLI 安装文档', - 'docs.subtitle': '查看 Claude Code / Gemini CLI / CodeBuddy Code / Codex CLI / KiloCode CLI 命令。', 'docs.section.commands': '安装命令', - 'docs.section.commandsNote': '命令可直接复制。', - 'docs.installed.title': '当前已安装命令', - 'docs.installed.count': '已安装 {count} 个', - 'docs.installed.empty': '未检测到已安装命令', 'docs.section.faq': '常见问题', - 'docs.section.faqNote': '常见问题见下。', 'docs.command.aria': '{name} 命令', 'docs.registryHintPrefix': '命令将附加:', 'docs.registryHintCustom': '请输入完整 URL(含 http/https),将自动附加到命令。', @@ -634,8 +628,6 @@ const zh = Object.freeze({ 'docs.meta.bin': 'bin: {bin}', 'docs.termuxLabel': 'Termux', 'docs.termuxAria': 'Termux Codex CLI command', - 'docs.rule.1': '命令按当前包管理器、镜像与操作生成。', - 'docs.rule.2': '自定义镜像仅用于安装与升级。', 'docs.tip.win.1': 'PowerShell 报权限不足(EACCES/EPERM)时,请以管理员身份执行安装命令。', 'docs.tip.win.2': '安装后若仍提示找不到命令,重开终端并执行:where codex / where claude / where gemini / where codebuddy。', 'docs.tip.win.3': '公司网络受限时,可先切换镜像源快捷项(npmmirror / 腾讯云 / 自定义)。', @@ -1544,6 +1536,11 @@ const zh = Object.freeze({ 'toolConfig.kilocode.lockedTitle': '只读模式', 'toolConfig.kilocode.lockedDesc': '开启写入权限后可保存配置或启动 KiloCode。', 'toolConfig.kilocode.confirmMessage': '打开后,KiloCode tab 内的操作会写入 ~/.config/kilo/kilo.jsonc 或已存在的 kilo.json,并可启动本机 KiloCode。', + 'toolConfig.openclaw.title': 'OpenClaw 配置写入', + 'toolConfig.openclaw.desc': '默认只读;开启后可应用 OpenClaw 配置、写入 AGENTS.md 与其他工作区文件。', + 'toolConfig.openclaw.confirmMessage': '打开后,OpenClaw tab 内的操作会写入 openclaw.json 及 OpenClaw 工作区文件(AGENTS.md、SOUL.md 等)。', + 'toolConfig.openclaw.lockedTitle': 'OpenClaw 当前为只读', + 'toolConfig.openclaw.lockedDesc': '这里不会写入 OpenClaw 配置。要应用配置或编辑工作区文件,请先打开本 tab 的写入开关。', 'kilocode.providerModel.title': 'KiloCode provider / model', 'kilocode.connection.title': 'KiloCode 连接', 'kilocode.targetFile': 'KiloCode 生效配置:{path} · {status}', diff --git a/web-ui/partials/index/panel-config-openclaw.html b/web-ui/partials/index/panel-config-openclaw.html index 755da4e0..7b4bf7b2 100644 --- a/web-ui/partials/index/panel-config-openclaw.html +++ b/web-ui/partials/index/panel-config-openclaw.html @@ -11,6 +11,23 @@
{{ t('toolConfig.openclaw.desc') }}
+