codexmate 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,164 @@
1
+ function normalizeKilocodeProviderName(value) {
2
+ const name = typeof value === 'string' ? value.trim() : '';
3
+ return /^[a-zA-Z0-9_.-]+$/.test(name) ? name : '';
4
+ }
5
+
6
+ const DEFAULT_KILOCODE_PROVIDER = 'codexmate';
7
+ const DEFAULT_KILOCODE_MODEL = 'gpt-5.3';
8
+
9
+ export function createKilocodeConfigMethods(options = {}) {
10
+ const { api } = options;
11
+ return {
12
+ normalizeKilocodeProviderNameForUi(value) {
13
+ return normalizeKilocodeProviderName(value);
14
+ },
15
+
16
+ refreshKilocodeSelectionFromSummary(res = {}) {
17
+ const providers = Array.isArray(res.providers) ? res.providers : [];
18
+ this.kilocodeProviders = providers;
19
+ this.kilocodeConfigPath = typeof res.targetPath === 'string' ? res.targetPath : '';
20
+ this.kilocodeConfigExists = res.exists === true;
21
+ this.kilocodeContent = typeof res.content === 'string' ? res.content : '{}\n';
22
+ const firstProvider = providers.find(item => item && item.name);
23
+ this.kilocodeProvider = normalizeKilocodeProviderName(res.currentProvider)
24
+ || normalizeKilocodeProviderName(firstProvider && firstProvider.name)
25
+ || DEFAULT_KILOCODE_PROVIDER;
26
+ const selected = providers.find(item => normalizeKilocodeProviderName(item && item.name) === this.kilocodeProvider);
27
+ this.kilocodeBaseUrl = typeof (selected && (selected.baseURL || selected.api)) === 'string'
28
+ ? (selected.baseURL || selected.api)
29
+ : this.kilocodeBaseUrl;
30
+ const model = typeof res.currentModel === 'string' ? res.currentModel.trim() : '';
31
+ this.kilocodeModel = model || (selected && Array.isArray(selected.models) ? (selected.models[0] || '') : this.kilocodeModel) || DEFAULT_KILOCODE_MODEL;
32
+ },
33
+
34
+ async loadKilocodeConfig(options = {}) {
35
+ if (this.kilocodeLoading) return;
36
+ this.kilocodeLoading = true;
37
+ this.kilocodeError = '';
38
+ try {
39
+ const res = await api('get-kilocode-config');
40
+ if (res && res.error) {
41
+ this.kilocodeError = res.error;
42
+ return;
43
+ }
44
+ this.refreshKilocodeSelectionFromSummary(res || {});
45
+ if (options.toast === true) this.showMessage('KiloCode 配置已刷新', 'success');
46
+ } catch (e) {
47
+ this.kilocodeError = e && e.message ? e.message : '读取 KiloCode 配置失败';
48
+ } finally {
49
+ this.kilocodeLoading = false;
50
+ }
51
+ },
52
+
53
+ hasKilocodeStoredKey(provider) {
54
+ const normalizedProvider = normalizeKilocodeProviderName(provider || this.kilocodeProvider);
55
+ return (this.kilocodeProviders || []).some(item => normalizeKilocodeProviderName(item && item.name) === normalizedProvider && item.hasKey === true);
56
+ },
57
+
58
+ kilocodeConfigSignature(provider, url, model, apiKey) {
59
+ const keyMarker = apiKey ? `key:${apiKey}` : (this.hasKilocodeStoredKey(provider) ? 'key:<stored>' : 'key:<empty>');
60
+ return [provider, url, model, keyMarker].join('\u0000');
61
+ },
62
+
63
+ async selectKilocodeProvider(provider = {}) {
64
+ const name = normalizeKilocodeProviderName(provider && provider.name);
65
+ if (!name) return false;
66
+ const url = typeof (provider.baseURL || provider.api) === 'string' ? (provider.baseURL || provider.api).trim() : '';
67
+ const model = Array.isArray(provider.models) && provider.models.length
68
+ ? String(provider.models[0] || '').trim()
69
+ : DEFAULT_KILOCODE_MODEL;
70
+ this.kilocodeProvider = name;
71
+ if (url) this.kilocodeBaseUrl = url;
72
+ this.kilocodeModel = model || DEFAULT_KILOCODE_MODEL;
73
+ this.kilocodeApiKey = '';
74
+ this.kilocodeAutoSaveSignature = '';
75
+ if (!this.isToolConfigWriteAllowed('kilocode') || !url || !this.hasKilocodeStoredKey(name)) return true;
76
+ return this.saveKilocodeConfig({ auto: true });
77
+ },
78
+
79
+ async autoSaveKilocodeConfig() {
80
+ if (!this.isToolConfigWriteAllowed('kilocode') || this.kilocodeSaving || this.kilocodeLoading) return false;
81
+ const provider = normalizeKilocodeProviderName(this.kilocodeProvider) || DEFAULT_KILOCODE_PROVIDER;
82
+ const url = typeof this.kilocodeBaseUrl === 'string' ? this.kilocodeBaseUrl.trim() : '';
83
+ const model = (typeof this.kilocodeModel === 'string' ? this.kilocodeModel.trim() : '') || DEFAULT_KILOCODE_MODEL;
84
+ const apiKey = typeof this.kilocodeApiKey === 'string' ? this.kilocodeApiKey.trim() : '';
85
+ if (!url || (!apiKey && !this.hasKilocodeStoredKey(provider))) return false;
86
+ const signature = this.kilocodeConfigSignature(provider, url, model, apiKey);
87
+ if (signature === this.kilocodeAutoSaveSignature) return false;
88
+ return this.saveKilocodeConfig({ auto: true, signature });
89
+ },
90
+
91
+ async saveKilocodeConfig(options = {}) {
92
+ if (this.kilocodeSaving) return false;
93
+ const auto = options && options.auto === true;
94
+ if (!this.isToolConfigWriteAllowed('kilocode')) {
95
+ if (!auto) this.showMessage(this.t ? this.t('kilocode.writeRequired') : '请先打开 KiloCode 写入开关', 'error');
96
+ return false;
97
+ }
98
+ const provider = normalizeKilocodeProviderName(this.kilocodeProvider) || DEFAULT_KILOCODE_PROVIDER;
99
+ const url = typeof this.kilocodeBaseUrl === 'string' ? this.kilocodeBaseUrl.trim() : '';
100
+ const model = (typeof this.kilocodeModel === 'string' ? this.kilocodeModel.trim() : '') || DEFAULT_KILOCODE_MODEL;
101
+ const apiKey = typeof this.kilocodeApiKey === 'string' ? this.kilocodeApiKey.trim() : '';
102
+ if (!url || (!apiKey && !this.hasKilocodeStoredKey(provider))) {
103
+ if (!auto) this.showMessage(this.t ? this.t('kilocode.fillRequired') : '请填写 KiloCode URL 和 API Key', 'error');
104
+ return false;
105
+ }
106
+ this.kilocodeProvider = provider;
107
+ this.kilocodeModel = model;
108
+ this.kilocodeSaving = true;
109
+ this.kilocodeError = '';
110
+ try {
111
+ const res = await api('apply-kilocode-config', { provider, url, model, apiKey });
112
+ if (res && res.error) {
113
+ this.kilocodeError = res.error;
114
+ this.showMessage(res.error, 'error');
115
+ return false;
116
+ }
117
+ this.kilocodeApiKey = '';
118
+ this.refreshKilocodeSelectionFromSummary(res || {});
119
+ this.kilocodeAutoSaveSignature = options && options.signature ? options.signature : this.kilocodeConfigSignature(provider, url, model, '');
120
+ this.showMessage(this.t ? this.t(auto ? 'kilocode.autoSaved' : 'kilocode.saved') : 'KiloCode 配置已保存', 'success');
121
+ return true;
122
+ } catch (e) {
123
+ this.kilocodeError = e && e.message ? e.message : (this.t ? this.t('kilocode.saveFailed') : '保存 KiloCode 配置失败');
124
+ this.showMessage(this.kilocodeError, 'error');
125
+ return false;
126
+ } finally {
127
+ this.kilocodeSaving = false;
128
+ }
129
+ },
130
+
131
+ async startKilocode(configure = false) {
132
+ if (this.kilocodeStarting) return;
133
+ if (!this.isToolConfigWriteAllowed('kilocode')) {
134
+ this.showMessage('请先打开 KiloCode 写入开关', 'error');
135
+ return;
136
+ }
137
+ this.kilocodeStarting = true;
138
+ this.kilocodeError = '';
139
+ try {
140
+ const payload = configure ? {
141
+ configure: true,
142
+ provider: this.kilocodeProvider,
143
+ url: this.kilocodeBaseUrl,
144
+ model: this.kilocodeModel,
145
+ apiKey: this.kilocodeApiKey
146
+ } : {};
147
+ const res = await api('start-kilocode', payload);
148
+ if (res && res.error) {
149
+ this.kilocodeError = res.error;
150
+ this.showMessage(res.error, 'error');
151
+ return;
152
+ }
153
+ this.kilocodeApiKey = '';
154
+ this.showMessage(`KiloCode 已启动${res && res.pid ? `(PID ${res.pid})` : ''}`, 'success');
155
+ await this.loadKilocodeConfig();
156
+ } catch (e) {
157
+ this.kilocodeError = e && e.message ? e.message : '启动 KiloCode 失败';
158
+ this.showMessage(this.kilocodeError, 'error');
159
+ } finally {
160
+ this.kilocodeStarting = false;
161
+ }
162
+ }
163
+ };
164
+ }
@@ -148,6 +148,9 @@
148
148
  }
149
149
  this.configMode = configModeSet.has(normalizedMode) ? normalizedMode : 'codex';
150
150
  if (this.mainTab === 'config') {
151
+ if (this.configMode === 'kilocode' && typeof this.loadKilocodeConfig === 'function') {
152
+ this.loadKilocodeConfig();
153
+ }
151
154
  if (this.configMode === 'claude') {
152
155
  const expectedMainTab = 'config';
153
156
  const expectedConfigMode = 'claude';
@@ -458,6 +461,9 @@
458
461
  if (targetTab === previousTab) {
459
462
  switchState.ticket += 1;
460
463
  switchState.pendingTarget = '';
464
+ if (targetTab === 'config' && this.configMode === 'kilocode' && typeof this.loadKilocodeConfig === 'function') {
465
+ void this.loadKilocodeConfig();
466
+ }
461
467
  if (targetTab === 'dashboard' && !this.__doctorLoadedOnce) {
462
468
  void loadDoctorOverview(this);
463
469
  }
@@ -490,6 +496,9 @@
490
496
  switchState.pendingTarget = '';
491
497
  const result = switchMainTabHelper.call(this, targetTab);
492
498
  persistNavState(this);
499
+ if (targetTab === 'config' && this.configMode === 'kilocode' && typeof this.loadKilocodeConfig === 'function') {
500
+ void this.loadKilocodeConfig();
501
+ }
493
502
  if (targetTab === 'dashboard') {
494
503
  void loadDoctorOverview(this);
495
504
  }
@@ -508,6 +517,9 @@
508
517
  liveState.pendingTarget = '';
509
518
  switchMainTabHelper.call(this, pendingTarget);
510
519
  persistNavState(this);
520
+ if (pendingTarget === 'config' && this.configMode === 'kilocode' && typeof this.loadKilocodeConfig === 'function') {
521
+ void this.loadKilocodeConfig();
522
+ }
511
523
  if (pendingTarget === 'dashboard') {
512
524
  void loadDoctorOverview(this);
513
525
  }
@@ -143,7 +143,9 @@ export function createStartupClaudeMethods(options = {}) {
143
143
  this.toolConfigPermissions = {
144
144
  codex: statusRes.toolConfigPermissions.codex === true,
145
145
  claude: statusRes.toolConfigPermissions.claude === true,
146
- opencode: statusRes.toolConfigPermissions.opencode === true
146
+ opencode: statusRes.toolConfigPermissions.opencode === true,
147
+ kilocode: statusRes.toolConfigPermissions.kilocode === true,
148
+ openclaw: statusRes.toolConfigPermissions.openclaw === true
147
149
  };
148
150
  }
149
151
  this.providersList = listRes.providers;
@@ -3,7 +3,7 @@ export function createToolConfigPermissionMethods(options = {}) {
3
3
 
4
4
  function normalizeTarget(value) {
5
5
  const target = typeof value === 'string' ? value.trim().toLowerCase() : '';
6
- return target === 'codex' || target === 'claude' || target === 'opencode' ? target : '';
6
+ return target === 'codex' || target === 'claude' || target === 'opencode' || target === 'kilocode' || target === 'openclaw' ? target : '';
7
7
  }
8
8
 
9
9
  function normalizePermissions(value) {
@@ -11,7 +11,9 @@ export function createToolConfigPermissionMethods(options = {}) {
11
11
  return {
12
12
  codex: source.codex === true,
13
13
  claude: source.claude === true,
14
- opencode: source.opencode === true
14
+ opencode: source.opencode === true,
15
+ kilocode: source.kilocode === true,
16
+ openclaw: source.openclaw === true
15
17
  };
16
18
  }
17
19
 
@@ -438,7 +438,9 @@ export function createWebUiPreferencesMethods(options = {}) {
438
438
  this.toolConfigPermissions = {
439
439
  codex: source.toolConfigPermissions.codex === true,
440
440
  claude: source.toolConfigPermissions.claude === true,
441
- opencode: source.toolConfigPermissions.opencode === true
441
+ opencode: source.toolConfigPermissions.opencode === true,
442
+ kilocode: source.toolConfigPermissions.kilocode === true,
443
+ openclaw: source.toolConfigPermissions.openclaw === true
442
444
  };
443
445
  }
444
446
  if (Array.isArray(source.deletedClaudeSettingsImports)) {
@@ -11,7 +11,8 @@ export const CONFIG_MODE_SET = new Set([
11
11
  ...Object.keys(PROVIDER_CONFIG_MODE_META),
12
12
  'claude',
13
13
  'openclaw',
14
- 'opencode'
14
+ 'opencode',
15
+ 'kilocode'
15
16
  ]);
16
17
 
17
18
  export function getProviderConfigModeMeta(mode) {
@@ -63,6 +64,7 @@ export function createConfigModeComputed() {
63
64
  if (this.configMode === 'claude') return 'Claude Code';
64
65
  if (this.configMode === 'openclaw') return 'OpenClaw';
65
66
  if (this.configMode === 'opencode') return 'OpenCode';
67
+ if (this.configMode === 'kilocode') return 'KiloCode';
66
68
  return '未选择';
67
69
  },
68
70
  inspectorCurrentConfigLabel() {
@@ -82,6 +84,10 @@ export function createConfigModeComputed() {
82
84
  const provider = typeof this.opencodeProvider === 'string' ? this.opencodeProvider.trim() : '';
83
85
  return provider || '未选择';
84
86
  }
87
+ if (this.configMode === 'kilocode') {
88
+ const provider = typeof this.kilocodeProvider === 'string' ? this.kilocodeProvider.trim() : '';
89
+ return provider || '未选择';
90
+ }
85
91
  return '未选择';
86
92
  },
87
93
  inspectorCurrentModelLabel() {
@@ -103,6 +109,10 @@ export function createConfigModeComputed() {
103
109
  const model = typeof this.opencodeModel === 'string' ? this.opencodeModel.trim() : '';
104
110
  return model || '未选择';
105
111
  }
112
+ if (this.configMode === 'kilocode') {
113
+ const model = typeof this.kilocodeModel === 'string' ? this.kilocodeModel.trim() : '';
114
+ return model || '未选择';
115
+ }
106
116
  return '未选择';
107
117
  },
108
118
  inspectorTemplateStatus() {
@@ -142,6 +142,7 @@ const en = Object.freeze({
142
142
  'side.docs': 'Docs',
143
143
  'side.config': 'Config',
144
144
  'side.sessions': 'Sessions',
145
+ 'side.workspace': 'Workspace',
145
146
  'side.prompts': 'Prompts',
146
147
  'side.prompts.meta': 'Prompt files and presets',
147
148
  'side.plugins': 'Plugins',
@@ -172,7 +173,7 @@ const en = Object.freeze({
172
173
  'side.config.claude': 'Claude Code',
173
174
  'side.config.claude.meta': 'Settings',
174
175
  'side.config.openclaw': 'OpenClaw',
175
- 'side.config.openclaw.meta': 'JSON5 · AGENTS',
176
+ 'side.config.openclaw.meta': 'Config',
176
177
  'side.config.opencode': 'OpenCode',
177
178
  'side.config.opencode.meta': 'Provider',
178
179
  'side.sessions.browser': 'Session Browser',
@@ -618,11 +619,8 @@ const en = Object.freeze({
618
619
 
619
620
  // Docs panel
620
621
  'docs.title': 'CLI Install',
621
- 'docs.subtitle': 'Install commands for Claude Code / Gemini CLI / CodeBuddy Code / Codex CLI.',
622
622
  'docs.section.commands': 'Commands',
623
- 'docs.section.commandsNote': 'Copy and run directly.',
624
623
  'docs.section.faq': 'FAQ',
625
- 'docs.section.faqNote': 'Common issues and tips.',
626
624
  'docs.command.aria': '{name} command',
627
625
  'docs.registryHintPrefix': 'Command will append:',
628
626
  'docs.registryHintCustom': 'Enter a full URL (http/https) to append as registry.',
@@ -630,8 +628,6 @@ const en = Object.freeze({
630
628
  'docs.meta.bin': 'bin: {bin}',
631
629
  'docs.termuxLabel': 'Termux',
632
630
  'docs.termuxAria': 'Termux Codex CLI command',
633
- 'docs.rule.1': 'Commands depend on package manager, registry and action.',
634
- 'docs.rule.2': 'Custom registry is used for install/update only.',
635
631
  'docs.tip.win.1': 'If PowerShell reports permission errors (EACCES/EPERM), run the install command as Administrator.',
636
632
  '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.',
637
633
  'docs.tip.win.3': 'If your network blocks npm, try switching registry presets (npmmirror / Tencent / Custom).',
@@ -1530,6 +1526,36 @@ const en = Object.freeze({
1530
1526
  'openclaw.action.applyAria': 'Apply OpenClaw config: {name}',
1531
1527
  'openclaw.action.editAria': 'Edit OpenClaw config: {name}',
1532
1528
  'openclaw.action.deleteAria': 'Delete OpenClaw config: {name}'
1529
+ ,
1530
+
1531
+ 'tab.config.kilocode': 'KiloCode',
1532
+ 'side.config.kilocode': 'KiloCode',
1533
+ 'side.config.kilocode.meta': 'Provider',
1534
+ 'toolConfig.kilocode.title': 'KiloCode config writes and launch',
1535
+ 'toolConfig.kilocode.desc': 'Read-only by default; enable writes to sync KiloCode config and launch it from the Web UI.',
1536
+ 'toolConfig.kilocode.lockedTitle': 'Read-only mode',
1537
+ 'toolConfig.kilocode.lockedDesc': 'Enable write access to auto-sync config or launch KiloCode.',
1538
+ '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.',
1539
+ 'toolConfig.openclaw.title': 'OpenClaw config writes',
1540
+ 'toolConfig.openclaw.desc': 'Read-only by default; enable to apply OpenClaw configs and write AGENTS.md and other workspace files.',
1541
+ 'toolConfig.openclaw.confirmMessage': 'When enabled, actions in the OpenClaw tab can write openclaw.json and OpenClaw workspace files (AGENTS.md, SOUL.md, etc.).',
1542
+ 'toolConfig.openclaw.lockedTitle': 'OpenClaw is read-only',
1543
+ 'toolConfig.openclaw.lockedDesc': 'OpenClaw config is not written here. To apply configs or edit workspace files, enable write access on this tab first.',
1544
+ 'kilocode.providerModel.title': 'KiloCode provider / model',
1545
+ 'kilocode.connection.title': 'KiloCode connection',
1546
+ 'kilocode.targetFile': 'Active KiloCode config: {path} · {status}',
1547
+ 'kilocode.saveConfig': 'Save config',
1548
+ 'kilocode.start': 'Launch KiloCode',
1549
+ 'kilocode.starting': 'Launching',
1550
+ 'kilocode.saveAndStart': 'Save and launch',
1551
+ 'kilocode.summary.title': 'Current KiloCode provider',
1552
+ 'kilocode.configPreview.title': 'KiloCode config preview',
1553
+ 'kilocode.configPreview.hint': 'API Key is redacted; auto-sync writes the real key.',
1554
+ 'kilocode.saveFailed': 'Failed to save KiloCode config',
1555
+ 'kilocode.fillRequired': 'Fill KiloCode URL and API Key',
1556
+ 'kilocode.writeRequired': 'Enable KiloCode write access first',
1557
+ 'kilocode.saved': 'KiloCode config saved',
1558
+ 'kilocode.autoSaved': 'KiloCode config synced',
1533
1559
  });
1534
1560
 
1535
1561
  export { en };
@@ -143,7 +143,8 @@ const ja = Object.freeze({
143
143
  'side.docs': 'ドキュメント',
144
144
  'side.config': '設定',
145
145
  'side.sessions': 'セッション',
146
- 'side.prompts': 'Prompts',
146
+ 'side.workspace': 'ワークスペース',
147
+ 'side.prompts': 'プロンプト',
147
148
  'side.prompts.meta': 'プロンプトファイルとプリセット',
148
149
  'side.plugins': 'プラグイン',
149
150
  'side.system': 'システム',
@@ -169,13 +170,13 @@ const ja = Object.freeze({
169
170
  'side.update.currentOnly': '現在 v{current}',
170
171
  'side.update.retry': 'バージョン確認を再試行',
171
172
  'side.config.codex': 'Codex',
172
- 'side.config.codex.meta': 'Provider · Model',
173
+ 'side.config.codex.meta': 'プロバイダー · モデル',
173
174
  'side.config.claude': 'Claude Code',
174
- 'side.config.claude.meta': 'Settings',
175
+ 'side.config.claude.meta': '設定',
175
176
  'side.config.openclaw': 'OpenClaw',
176
- 'side.config.openclaw.meta': 'JSON5 · AGENTS',
177
+ 'side.config.openclaw.meta': '設定',
177
178
  'side.config.opencode': 'OpenCode',
178
- 'side.config.opencode.meta': 'Provider',
179
+ 'side.config.opencode.meta': 'プロバイダー',
179
180
  'side.sessions.browser': 'セッション閲覧',
180
181
  'side.sessions.browser.meta': '閲覧 / エクスポート / クリーンアップ',
181
182
  'side.prompts.agents': 'AGENTS.md',
@@ -620,11 +621,8 @@ const ja = Object.freeze({
620
621
 
621
622
  // Docs panel
622
623
  'docs.title': 'CLI インストールドキュメント',
623
- 'docs.subtitle': 'Claude Code / Gemini CLI / CodeBuddy Code / Codex CLI コマンドを表示。',
624
624
  'docs.section.commands': 'インストールコマンド',
625
- 'docs.section.commandsNote': 'コマンドは直接コピーできます。',
626
625
  'docs.section.faq': 'よくある質問',
627
- 'docs.section.faqNote': 'よくある質問は以下をご覧ください。',
628
626
  'docs.command.aria': '{name} コマンド',
629
627
  'docs.registryHintPrefix': 'コマンドに付加:',
630
628
  'docs.registryHintCustom': '完全な URL(http/https 含む)を入力してください。コマンドに自動付加されます。',
@@ -632,8 +630,6 @@ const ja = Object.freeze({
632
630
  'docs.meta.bin': 'bin: {bin}',
633
631
  'docs.termuxLabel': 'Termux',
634
632
  'docs.termuxAria': 'Termux Codex CLI command',
635
- 'docs.rule.1': 'コマンドは現在のパッケージマネージャー、ミラー、操作に基づいて生成されます。',
636
- 'docs.rule.2': 'カスタムミラーはインストールとアップグレードにのみ使用されます。',
637
633
  'docs.tip.win.1': 'PowerShell で権限不足(EACCES/EPERM)エラーが発生した場合は、管理者としてインストールコマンドを実行してください。',
638
634
  'docs.tip.win.2': 'インストール後にコマンドが見つからない場合は、ターミナルを再起動して実行:where codex / where claude / where gemini / where codebuddy。',
639
635
  'docs.tip.win.3': '企業ネットワークで制限がある場合は、ミラーソース(npmmirror / Tencent Cloud / カスタム)を切り替えてください。',
@@ -1518,6 +1514,35 @@ const ja = Object.freeze({
1518
1514
  'openclaw.action.applyAria': 'OpenClaw 設定を適用:{name}',
1519
1515
  'openclaw.action.editAria': 'OpenClaw 設定を編集:{name}',
1520
1516
  'openclaw.action.deleteAria': 'OpenClaw 設定を削除:{name}',
1517
+
1518
+ 'tab.config.kilocode': 'KiloCode',
1519
+ 'side.config.kilocode': 'KiloCode',
1520
+ 'side.config.kilocode.meta': 'プロバイダー',
1521
+ 'toolConfig.kilocode.title': 'KiloCode 設定の書き込みと起動',
1522
+ 'toolConfig.kilocode.desc': '既定は読み取り専用。有効化すると KiloCode 設定を同期し、Web から起動できます。',
1523
+ 'toolConfig.kilocode.lockedTitle': '読み取り専用モード',
1524
+ 'toolConfig.kilocode.lockedDesc': '書き込み権限を有効化すると、設定の自動同期または KiloCode の起動ができます。',
1525
+ 'toolConfig.kilocode.confirmMessage': '有効化すると、KiloCode タブ内の操作が ~/.config/kilo/kilo.jsonc または既存の kilo.json に書き込み、ローカル KiloCode を起動できます。',
1526
+ 'toolConfig.openclaw.title': 'OpenClaw 設定の書き込み',
1527
+ 'toolConfig.openclaw.desc': '既定は読み取り専用。有効化すると OpenClaw 設定を適用し、AGENTS.md などのワークスペースファイルを書き込みできます。',
1528
+ 'toolConfig.openclaw.confirmMessage': '有効化すると、OpenClaw タブ内の操作が openclaw.json およびワークスペースファイル(AGENTS.md、SOUL.md など)に書き込みできます。',
1529
+ 'toolConfig.openclaw.lockedTitle': 'OpenClaw は読み取り専用です',
1530
+ 'toolConfig.openclaw.lockedDesc': 'ここでは OpenClaw 設定を書き込みません。設定を適用またはワークスペースファイルを編集するには、このタブの書き込みスイッチを有効化してください。',
1531
+ 'kilocode.providerModel.title': 'KiloCode プロバイダー / モデル',
1532
+ 'kilocode.connection.title': 'KiloCode 接続',
1533
+ 'kilocode.targetFile': '有効な KiloCode 設定:{path} · {status}',
1534
+ 'kilocode.saveConfig': '設定を保存',
1535
+ 'kilocode.start': 'KiloCode を起動',
1536
+ 'kilocode.starting': '起動中',
1537
+ 'kilocode.saveAndStart': '保存して起動',
1538
+ 'kilocode.summary.title': '現在の KiloCode プロバイダー',
1539
+ 'kilocode.configPreview.title': 'KiloCode 設定プレビュー',
1540
+ 'kilocode.configPreview.hint': 'API Key はマスク済みです。自動同期では実際の key が書き込まれます。',
1541
+ 'kilocode.saveFailed': 'KiloCode 設定の保存に失敗しました',
1542
+ 'kilocode.fillRequired': 'KiloCode URL と API Key を入力してください',
1543
+ 'kilocode.writeRequired': '先に KiloCode の書き込みを有効化してください',
1544
+ 'kilocode.saved': 'KiloCode 設定を保存しました',
1545
+ 'kilocode.autoSaved': 'KiloCode 設定を同期しました',
1521
1546
  });
1522
1547
 
1523
1548
  export { ja };
@@ -103,8 +103,9 @@ const vi = Object.freeze({
103
103
  'side.docs': 'Tài liệu',
104
104
  'side.config': 'Cấu hình',
105
105
  'side.sessions': 'Phiên',
106
- 'side.prompts': 'Prompts',
107
- 'side.prompts.meta': 'Tệp prompt và preset',
106
+ 'side.workspace': 'Không gian làm việc',
107
+ 'side.prompts': 'Lời nhắc',
108
+ 'side.prompts.meta': 'Tệp lời nhắc và preset',
108
109
  'side.plugins': 'Plugin',
109
110
  'side.system': 'Hệ thống',
110
111
  'side.orchestration': 'Tác vụ',
@@ -129,13 +130,13 @@ const vi = Object.freeze({
129
130
  'side.update.currentOnly': 'Hiện tại v{current}',
130
131
  'side.update.retry': 'Thử kiểm tra phiên bản lại',
131
132
  'side.config.codex': 'Codex',
132
- 'side.config.codex.meta': 'Provider · Model',
133
+ 'side.config.codex.meta': 'Nhà cung cấp · Mô hình',
133
134
  'side.config.claude': 'Claude Code',
134
- 'side.config.claude.meta': 'Settings',
135
+ 'side.config.claude.meta': 'Cài đặt',
135
136
  'side.config.openclaw': 'OpenClaw',
136
- 'side.config.openclaw.meta': 'JSON5 · AGENTS',
137
+ 'side.config.openclaw.meta': 'Cấu hình',
137
138
  'side.config.opencode': 'OpenCode',
138
- 'side.config.opencode.meta': 'Provider',
139
+ 'side.config.opencode.meta': 'Nhà cung cấp',
139
140
  'side.sessions.browser': 'Trình duyệt phiên',
140
141
  'side.sessions.browser.meta': 'Duyệt / Xuất / Dọn dẹp',
141
142
  'side.prompts.agents': 'AGENTS.md',
@@ -825,11 +826,8 @@ const vi = Object.freeze({
825
826
  'modal.openclaw.quick.optionsHint': 'Khi tắt ghi đè, chỉ điền các trường còn thiếu.',
826
827
  'modal.openclaw.quick.writeToEditor': 'Ghi vào editor',
827
828
  'docs.title': 'Cài CLI',
828
- 'docs.subtitle': 'Lệnh cài đặt cho Claude Code / Gemini CLI / CodeBuddy Code / Codex CLI.',
829
829
  'docs.section.commands': 'Lệnh',
830
- 'docs.section.commandsNote': 'Sao chép và chạy trực tiếp.',
831
830
  'docs.section.faq': 'FAQ',
832
- 'docs.section.faqNote': 'Vấn đề phổ biến và mẹo.',
833
831
  'docs.command.aria': 'Lệnh {name}',
834
832
  'docs.registryHintPrefix': 'Lệnh sẽ thêm:',
835
833
  'docs.registryHintCustom': 'Nhập URL đầy đủ (http/https) để thêm làm registry.',
@@ -837,8 +835,6 @@ const vi = Object.freeze({
837
835
  'docs.meta.bin': 'bin: {bin}',
838
836
  'docs.termuxLabel': 'Termux',
839
837
  'docs.termuxAria': 'Lệnh Codex CLI cho Termux',
840
- 'docs.rule.1': 'Lệnh phụ thuộc vào trình quản lý gói, registry và hành động.',
841
- 'docs.rule.2': 'Registry tùy chỉnh chỉ dùng cho cài đặt/cập nhật.',
842
838
  '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.',
843
839
  '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.',
844
840
  'docs.tip.win.3': 'Nếu mạng chặn npm, thử chuyển registry (npmmirror / Tencent / Tùy chỉnh).',
@@ -1503,6 +1499,35 @@ const vi = Object.freeze({
1503
1499
  'openclaw.action.applyAria': 'Áp dụng cấu hình OpenClaw: {name}',
1504
1500
  'openclaw.action.editAria': 'Chỉnh sửa cấu hình OpenClaw: {name}',
1505
1501
  'openclaw.action.deleteAria': 'Xóa cấu hình OpenClaw: {name}',
1502
+
1503
+ 'tab.config.kilocode': 'KiloCode',
1504
+ 'side.config.kilocode': 'KiloCode',
1505
+ 'side.config.kilocode.meta': 'Nhà cung cấp',
1506
+ 'toolConfig.kilocode.title': 'Ghi cấu hình và khởi chạy KiloCode',
1507
+ 'toolConfig.kilocode.desc': 'Mặc định chỉ đọc; bật ghi để đồng bộ cấu hình KiloCode và khởi chạy từ Web.',
1508
+ 'toolConfig.kilocode.lockedTitle': 'Chế độ chỉ đọc',
1509
+ 'toolConfig.kilocode.lockedDesc': 'Bật quyền ghi để tự động đồng bộ cấu hình hoặc khởi chạy KiloCode.',
1510
+ '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ộ.',
1511
+ 'toolConfig.openclaw.title': 'Ghi cấu hình OpenClaw',
1512
+ '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.',
1513
+ '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.).',
1514
+ 'toolConfig.openclaw.lockedTitle': 'OpenClaw đang ở chế độ chỉ đọc',
1515
+ '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.',
1516
+ 'kilocode.providerModel.title': 'Nhà cung cấp / mô hình KiloCode',
1517
+ 'kilocode.connection.title': 'Kết nối KiloCode',
1518
+ 'kilocode.targetFile': 'Cấu hình KiloCode đang dùng: {path} · {status}',
1519
+ 'kilocode.saveConfig': 'Lưu cấu hình',
1520
+ 'kilocode.start': 'Khởi chạy KiloCode',
1521
+ 'kilocode.starting': 'Đang khởi chạy',
1522
+ 'kilocode.saveAndStart': 'Lưu và khởi chạy',
1523
+ 'kilocode.summary.title': 'Nhà cung cấp KiloCode hiện tại',
1524
+ 'kilocode.configPreview.title': 'Xem trước cấu hình KiloCode',
1525
+ 'kilocode.configPreview.hint': 'API Key đã được che; tự động đồng bộ sẽ ghi key thật.',
1526
+ 'kilocode.saveFailed': 'Không thể lưu cấu hình KiloCode',
1527
+ 'kilocode.fillRequired': 'Điền URL và API Key KiloCode',
1528
+ 'kilocode.writeRequired': 'Hãy bật quyền ghi KiloCode trước',
1529
+ 'kilocode.saved': 'Đã lưu cấu hình KiloCode',
1530
+ 'kilocode.autoSaved': 'Đã đồng bộ cấu hình KiloCode',
1506
1531
  });
1507
1532
 
1508
1533
  export { vi };
@@ -142,8 +142,9 @@ const zhTw = Object.freeze({
142
142
  'side.docs': '文檔',
143
143
  'side.config': '設定',
144
144
  'side.sessions': '會話',
145
- 'side.prompts': 'Prompts',
146
- 'side.prompts.meta': 'Prompt 文件與預設',
145
+ 'side.workspace': '工作區',
146
+ 'side.prompts': '提示詞',
147
+ 'side.prompts.meta': '提示詞文件與預設',
147
148
  'side.plugins': '插件',
148
149
  'side.system': '系統',
149
150
  'side.orchestration': '任務',
@@ -168,13 +169,13 @@ const zhTw = Object.freeze({
168
169
  'side.update.currentOnly': '目前 v{current}',
169
170
  'side.update.retry': '重試版本檢查',
170
171
  'side.config.codex': 'Codex',
171
- 'side.config.codex.meta': 'Provider · Model',
172
+ 'side.config.codex.meta': '提供者 · 模型',
172
173
  'side.config.claude': 'Claude Code',
173
- 'side.config.claude.meta': 'Settings',
174
+ 'side.config.claude.meta': '設定',
174
175
  'side.config.openclaw': 'OpenClaw',
175
- 'side.config.openclaw.meta': 'JSON5 · AGENTS',
176
+ 'side.config.openclaw.meta': '設定',
176
177
  'side.config.opencode': 'OpenCode',
177
- 'side.config.opencode.meta': 'Provider',
178
+ 'side.config.opencode.meta': '提供者',
178
179
  'side.sessions.browser': '會話瀏覽',
179
180
  'side.sessions.browser.meta': '瀏覽 / 匯出 / 清理',
180
181
  'side.prompts.agents': 'AGENTS.md',
@@ -618,11 +619,8 @@ const zhTw = Object.freeze({
618
619
 
619
620
  // Docs panel
620
621
  'docs.title': 'CLI 安裝文檔',
621
- 'docs.subtitle': '查看 Claude Code / Gemini CLI / CodeBuddy Code / Codex CLI 命令。',
622
622
  'docs.section.commands': '安裝命令',
623
- 'docs.section.commandsNote': '命令可直接複製。',
624
623
  'docs.section.faq': '常見問題',
625
- 'docs.section.faqNote': '常見問題見下。',
626
624
  'docs.command.aria': '{name} 命令',
627
625
  'docs.registryHintPrefix': '命令將附加:',
628
626
  'docs.registryHintCustom': '請輸入完整 URL(含 http/https),將自動附加到命令。',
@@ -630,8 +628,6 @@ const zhTw = Object.freeze({
630
628
  'docs.meta.bin': 'bin: {bin}',
631
629
  'docs.termuxLabel': 'Termux',
632
630
  'docs.termuxAria': 'Termux Codex CLI command',
633
- 'docs.rule.1': '命令按目前包管理器、鏡像與操作生成。',
634
- 'docs.rule.2': '自訂鏡像僅用於安裝與升級。',
635
631
  'docs.tip.win.1': 'PowerShell 報權限不足(EACCES/EPERM)時,請以管理員身份執行安裝命令。',
636
632
  'docs.tip.win.2': '安裝後若仍提示找不到命令,重開終端並執行:where codex / where claude / where gemini / where codebuddy。',
637
633
  'docs.tip.win.3': '公司網路受限時,可先切換鏡像源快捷項(npmmirror / 騰訊雲 / 自訂)。',
@@ -1530,6 +1526,36 @@ const zhTw = Object.freeze({
1530
1526
  'openclaw.action.applyAria': '應用 OpenClaw 設定:{name}',
1531
1527
  'openclaw.action.editAria': '編輯 OpenClaw 設定:{name}',
1532
1528
  'openclaw.action.deleteAria': '刪除 OpenClaw 設定:{name}'
1529
+ ,
1530
+
1531
+ 'tab.config.kilocode': 'KiloCode',
1532
+ 'side.config.kilocode': 'KiloCode',
1533
+ 'side.config.kilocode.meta': '提供者',
1534
+ 'toolConfig.kilocode.title': 'KiloCode 設定寫入與啟動',
1535
+ 'toolConfig.kilocode.desc': '預設唯讀;啟用後可寫入 KiloCode 設定並從 Web 啟動。',
1536
+ 'toolConfig.kilocode.lockedTitle': '唯讀模式',
1537
+ 'toolConfig.kilocode.lockedDesc': '啟用寫入權限後可自動同步設定或啟動 KiloCode。',
1538
+ 'toolConfig.kilocode.confirmMessage': '開啟後,KiloCode tab 內的操作會寫入 ~/.config/kilo/kilo.jsonc 或既有的 kilo.json,並可啟動本機 KiloCode。',
1539
+ 'toolConfig.openclaw.title': 'OpenClaw 設定寫入',
1540
+ 'toolConfig.openclaw.desc': '預設唯讀;啟用後可套用 OpenClaw 設定並寫入 AGENTS.md 與其他工作區檔案。',
1541
+ 'toolConfig.openclaw.confirmMessage': '開啟後,OpenClaw tab 內的操作會寫入 openclaw.json 及 OpenClaw 工作區檔案(AGENTS.md、SOUL.md 等)。',
1542
+ 'toolConfig.openclaw.lockedTitle': 'OpenClaw 目前為唯讀',
1543
+ 'toolConfig.openclaw.lockedDesc': '這裡不會寫入 OpenClaw 設定。要套用設定或編輯工作區檔案,請先開啟本 tab 的寫入開關。',
1544
+ 'kilocode.providerModel.title': 'KiloCode provider / 模型',
1545
+ 'kilocode.connection.title': 'KiloCode 連線',
1546
+ 'kilocode.targetFile': 'KiloCode 生效設定:{path} · {status}',
1547
+ 'kilocode.saveConfig': '儲存設定',
1548
+ 'kilocode.start': '啟動 KiloCode',
1549
+ 'kilocode.starting': '啟動中',
1550
+ 'kilocode.saveAndStart': '儲存並啟動',
1551
+ 'kilocode.summary.title': '目前 KiloCode provider',
1552
+ 'kilocode.configPreview.title': 'KiloCode 設定預覽',
1553
+ 'kilocode.configPreview.hint': 'API Key 已遮罩;自動同步會寫入真實 key。',
1554
+ 'kilocode.saveFailed': '儲存 KiloCode 設定失敗',
1555
+ 'kilocode.fillRequired': '請填寫 KiloCode URL 與 API Key',
1556
+ 'kilocode.writeRequired': '請先開啟 KiloCode 寫入開關',
1557
+ 'kilocode.saved': 'KiloCode 設定已儲存',
1558
+ 'kilocode.autoSaved': 'KiloCode 設定已同步',
1533
1559
  });
1534
1560
 
1535
1561
  export { zhTw };