coding-tool-x 3.4.3 → 3.4.5

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.
Files changed (63) hide show
  1. package/dist/web/assets/{Analytics-CbGxotgz.js → Analytics-DFWyPf5C.js} +1 -1
  2. package/dist/web/assets/{ConfigTemplates-oP6nrFEb.js → ConfigTemplates-BFE7hmKd.js} +1 -1
  3. package/dist/web/assets/{Home-DMntmEvh.js → Home-DZUuCrxk.js} +1 -1
  4. package/dist/web/assets/{PluginManager-BUC_c7nH.js → PluginManager-WyGY2BQN.js} +1 -1
  5. package/dist/web/assets/{ProjectList-CW8J49n7.js → ProjectList-CBc0QawN.js} +1 -1
  6. package/dist/web/assets/{ProjectList-oJIyIRkP.css → ProjectList-DL4JK6ci.css} +1 -1
  7. package/dist/web/assets/{SessionList-7lYnF92v.js → SessionList-CdPR7QLq.js} +1 -1
  8. package/dist/web/assets/{SkillManager-Cs08216i.js → SkillManager-B5-DxQOS.js} +1 -1
  9. package/dist/web/assets/{WorkspaceManager-CY-oGtyB.js → WorkspaceManager-C7yqFjpi.js} +1 -1
  10. package/dist/web/assets/index-BDsmoSfO.js +2 -0
  11. package/dist/web/assets/{index-5qy5NMIP.css → index-C1pzEgmj.css} +1 -1
  12. package/dist/web/index.html +2 -2
  13. package/package.json +2 -2
  14. package/src/commands/channels.js +13 -13
  15. package/src/commands/cli-type.js +5 -5
  16. package/src/commands/daemon.js +31 -31
  17. package/src/commands/doctor.js +14 -14
  18. package/src/commands/export-config.js +23 -23
  19. package/src/commands/list.js +4 -4
  20. package/src/commands/logs.js +19 -19
  21. package/src/commands/plugin.js +62 -62
  22. package/src/commands/port-config.js +4 -4
  23. package/src/commands/proxy-control.js +35 -35
  24. package/src/commands/proxy.js +28 -28
  25. package/src/commands/resume.js +4 -4
  26. package/src/commands/search.js +9 -9
  27. package/src/commands/security.js +5 -5
  28. package/src/commands/stats.js +18 -18
  29. package/src/commands/switch.js +1 -1
  30. package/src/commands/toggle-proxy.js +18 -18
  31. package/src/commands/ui.js +11 -11
  32. package/src/commands/update.js +9 -9
  33. package/src/commands/workspace.js +11 -11
  34. package/src/index.js +24 -24
  35. package/src/plugins/plugin-installer.js +1 -1
  36. package/src/reset-config.js +9 -9
  37. package/src/server/api/channels.js +1 -1
  38. package/src/server/api/claude-hooks.js +3 -2
  39. package/src/server/api/plugins.js +165 -14
  40. package/src/server/api/pm2-autostart.js +2 -2
  41. package/src/server/api/proxy.js +6 -6
  42. package/src/server/api/skills.js +66 -7
  43. package/src/server/codex-proxy-server.js +10 -2
  44. package/src/server/dev-server.js +2 -2
  45. package/src/server/gemini-proxy-server.js +10 -2
  46. package/src/server/index.js +37 -37
  47. package/src/server/opencode-proxy-server.js +10 -2
  48. package/src/server/proxy-server.js +14 -6
  49. package/src/server/services/codex-channels.js +64 -21
  50. package/src/server/services/codex-env-manager.js +44 -28
  51. package/src/server/services/config-export-service.js +1 -1
  52. package/src/server/services/mcp-service.js +2 -1
  53. package/src/server/services/model-detector.js +2 -2
  54. package/src/server/services/native-keychain.js +1 -0
  55. package/src/server/services/plugins-service.js +1066 -261
  56. package/src/server/services/proxy-runtime.js +129 -5
  57. package/src/server/services/server-shutdown.js +79 -0
  58. package/src/server/services/settings-manager.js +3 -3
  59. package/src/server/services/skill-service.js +146 -29
  60. package/src/server/websocket-server.js +8 -8
  61. package/src/ui/menu.js +2 -2
  62. package/src/ui/prompts.js +5 -5
  63. package/dist/web/assets/index-ClCqKpvX.js +0 -2
@@ -5,14 +5,14 @@
5
5
  <link rel="icon" href="/favicon.ico">
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
7
  <title>CC-TOOL - ClaudeCode增强工作助手</title>
8
- <script type="module" crossorigin src="/assets/index-ClCqKpvX.js"></script>
8
+ <script type="module" crossorigin src="/assets/index-BDsmoSfO.js"></script>
9
9
  <link rel="modulepreload" crossorigin href="/assets/markdown-DyTJGI4N.js">
10
10
  <link rel="modulepreload" crossorigin href="/assets/vue-vendor-3bf-fPGP.js">
11
11
  <link rel="modulepreload" crossorigin href="/assets/vendors-CKPV1OAU.js">
12
12
  <link rel="modulepreload" crossorigin href="/assets/naive-ui-Bdxp09n2.js">
13
13
  <link rel="modulepreload" crossorigin href="/assets/icons-B5Pl4lrD.js">
14
14
  <link rel="stylesheet" crossorigin href="/assets/markdown-BfC0goYb.css">
15
- <link rel="stylesheet" crossorigin href="/assets/index-5qy5NMIP.css">
15
+ <link rel="stylesheet" crossorigin href="/assets/index-C1pzEgmj.css">
16
16
  </head>
17
17
  <body>
18
18
  <div id="app"></div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "coding-tool-x",
3
- "version": "3.4.3",
3
+ "version": "3.4.5",
4
4
  "description": "Vibe Coding 增强工作助手 - 智能会话管理、动态渠道切换、全局搜索、实时监控",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -9,7 +9,7 @@
9
9
  "scripts": {
10
10
  "start": "node bin/ctx.js",
11
11
  "test": "npm run test:basic && npm run test:api && npm run test:codex-agents && npm run test:skills && npm run test:plugins-market",
12
- "test:basic": "node scripts/test-basic.js",
12
+ "test:basic": "node scripts/test-basic.js && npm run test:unit",
13
13
  "test:api": "node scripts/test-api-consistency.js",
14
14
  "test:codex-agents": "node scripts/test-codex-agents.js",
15
15
  "test:skills": "node scripts/test-skill-providers.js",
@@ -71,9 +71,9 @@ function getChannelServices(cliType) {
71
71
  */
72
72
  async function handleChannelManagement() {
73
73
  console.clear();
74
- console.log(chalk.bold.cyan('\n╔═══════════════════════════════════════╗'));
74
+ console.log(chalk.bold.cyan('\n╔=======================================╗'));
75
75
  console.log(chalk.bold.cyan('║ 渠道管理 ║'));
76
- console.log(chalk.bold.cyan('╚═══════════════════════════════════════╝\n'));
76
+ console.log(chalk.bold.cyan('╚=======================================╝\n'));
77
77
 
78
78
  const config = loadConfig();
79
79
  const cliType = config.currentCliType || 'claude';
@@ -124,9 +124,9 @@ async function handleChannelManagement() {
124
124
  */
125
125
  async function handleAddChannel() {
126
126
  console.clear();
127
- console.log(chalk.bold.cyan('\n╔═══════════════════════════════════════╗'));
127
+ console.log(chalk.bold.cyan('\n╔=======================================╗'));
128
128
  console.log(chalk.bold.cyan('║ 添加渠道 ║'));
129
- console.log(chalk.bold.cyan('╚═══════════════════════════════════════╝\n'));
129
+ console.log(chalk.bold.cyan('╚=======================================╝\n'));
130
130
 
131
131
  const config = loadConfig();
132
132
  const cliType = config.currentCliType || 'claude';
@@ -248,7 +248,7 @@ async function handleAddChannel() {
248
248
  );
249
249
  }
250
250
 
251
- console.log(chalk.green(`\n 渠道添加成功: ${channel.name}\n`));
251
+ console.log(chalk.green(`\n[OK] 渠道添加成功: ${channel.name}\n`));
252
252
  console.log(chalk.gray('提示: 使用"渠道管理"功能来启用此渠道\n'));
253
253
  broadcastSchedulerSnapshot(cliType);
254
254
 
@@ -260,7 +260,7 @@ async function handleAddChannel() {
260
260
  },
261
261
  ]);
262
262
  } catch (error) {
263
- console.log(chalk.red(`\n 添加失败: ${error.message}\n`));
263
+ console.log(chalk.red(`\n[ERROR] 添加失败: ${error.message}\n`));
264
264
 
265
265
  await inquirer.prompt([
266
266
  {
@@ -274,9 +274,9 @@ async function handleAddChannel() {
274
274
 
275
275
  async function handleChannelStatus() {
276
276
  console.clear();
277
- console.log(chalk.bold.cyan('\n╔═══════════════════════════════════════╗'));
277
+ console.log(chalk.bold.cyan('\n╔=======================================╗'));
278
278
  console.log(chalk.bold.cyan('║ 调度状态查看 ║'));
279
- console.log(chalk.bold.cyan('╚═══════════════════════════════════════╝\n'));
279
+ console.log(chalk.bold.cyan('╚=======================================╝\n'));
280
280
 
281
281
  try {
282
282
  const { getSchedulerState } = require('../server/services/channel-scheduler');
@@ -370,7 +370,7 @@ async function handleChannelToggle(channels, services, cliType) {
370
370
  ]);
371
371
 
372
372
  if (!selectedIds.length) {
373
- console.log(chalk.red('\n 至少需要启用一个渠道。\n'));
373
+ console.log(chalk.red('\n[ERROR] 至少需要启用一个渠道。\n'));
374
374
  await inquirer.prompt([{ type: 'input', name: 'continue', message: '按回车返回...' }]);
375
375
  return;
376
376
  }
@@ -382,7 +382,7 @@ async function handleChannelToggle(channels, services, cliType) {
382
382
  if (shouldEnable !== currentEnabled) {
383
383
  await services.updateChannel(channel.id, { enabled: shouldEnable });
384
384
  console.log(
385
- `${shouldEnable ? chalk.green(' 启用') : chalk.yellow(' 停用')} ${chalk.bold(channel.name)}`
385
+ `${shouldEnable ? chalk.green('[OK] 启用') : chalk.yellow('[PAUSE] 停用')} ${chalk.bold(channel.name)}`
386
386
  );
387
387
  hasChanged = true;
388
388
  }
@@ -524,7 +524,7 @@ async function handleLegacySwitch(channels, services) {
524
524
  });
525
525
 
526
526
  choices.push(new inquirer.Separator(chalk.gray('─'.repeat(14))));
527
- choices.push({ name: chalk.blue('↩️ 返回主菜单'), value: 'back' });
527
+ choices.push({ name: chalk.blue('[<-] 返回主菜单'), value: 'back' });
528
528
 
529
529
  const { channelId } = await inquirer.prompt([
530
530
  {
@@ -542,9 +542,9 @@ async function handleLegacySwitch(channels, services) {
542
542
 
543
543
  try {
544
544
  await services.activateChannel(channelId);
545
- console.log(chalk.green('\n 渠道已切换\n'));
545
+ console.log(chalk.green('\n[OK] 渠道已切换\n'));
546
546
  } catch (error) {
547
- console.log(chalk.red(`\n 操作失败: ${error.message}\n`));
547
+ console.log(chalk.red(`\n[ERROR] 操作失败: ${error.message}\n`));
548
548
  }
549
549
 
550
550
  await inquirer.prompt([{ type: 'input', name: 'continue', message: '按回车返回...' }]);
@@ -15,9 +15,9 @@ const CLI_TYPES = {
15
15
  */
16
16
  async function handleSwitchCliType() {
17
17
  console.clear();
18
- console.log(chalk.bold.cyan('\n╔═══════════════════════════════════════╗'));
18
+ console.log(chalk.bold.cyan('\n╔=======================================╗'));
19
19
  console.log(chalk.bold.cyan('║ 切换 CLI 类型 ║'));
20
- console.log(chalk.bold.cyan('╚═══════════════════════════════════════╝\n'));
20
+ console.log(chalk.bold.cyan('╚=======================================╝\n'));
21
21
 
22
22
  const config = loadConfig();
23
23
  const currentType = config.currentCliType || 'claude';
@@ -29,9 +29,9 @@ async function handleSwitchCliType() {
29
29
  const choices = Object.entries(CLI_TYPES).map(([type, info]) => {
30
30
  let name = '';
31
31
 
32
- // 如果是当前类型,添加✓标记
32
+ // 如果是当前类型,添加[v]标记
33
33
  if (type === currentType) {
34
- name += chalk.green(' ');
34
+ name += chalk.green('[v] ');
35
35
  } else {
36
36
  name += ' ';
37
37
  }
@@ -81,7 +81,7 @@ async function handleSwitchCliType() {
81
81
  config.currentCliType = selectedType;
82
82
  saveConfig(config);
83
83
 
84
- console.log(chalk.green(`\n 已切换到 ${CLI_TYPES[selectedType].name}\n`));
84
+ console.log(chalk.green(`\n[OK] 已切换到 ${CLI_TYPES[selectedType].name}\n`));
85
85
  console.log(chalk.gray('下次启动时将使用新的类型\n'));
86
86
 
87
87
  await inquirer.prompt([
@@ -73,7 +73,7 @@ function printPortToolIssue(issue = getPortToolIssue()) {
73
73
  return;
74
74
  }
75
75
 
76
- console.log(chalk.yellow(`\n⚠️ ${lines[0]}`));
76
+ console.log(chalk.yellow(`\n[WARN] ${lines[0]}`));
77
77
  lines.slice(1).forEach((line) => {
78
78
  console.log(chalk.gray(` ${line}`));
79
79
  });
@@ -135,7 +135,7 @@ async function handleStart() {
135
135
  // 检查是否已经在运行
136
136
  const existing = await getCCToolProcess();
137
137
  if (existing && existing.pm2_env.status === 'online') {
138
- console.log(chalk.yellow('\n⚠️ 服务已在运行中\n'));
138
+ console.log(chalk.yellow('\n[WARN] 服务已在运行中\n'));
139
139
  console.log(chalk.gray(`进程 ID: ${existing.pid}`));
140
140
  console.log(chalk.gray(`运行时长: ${formatUptime(existing.pm2_env.pm_uptime)}`));
141
141
  console.log(chalk.gray('\n使用 ') + chalk.cyan('ctx status') + chalk.gray(' 查看详细状态'));
@@ -168,12 +168,12 @@ async function handleStart() {
168
168
  CC_TOOL_PORT: port
169
169
  },
170
170
  output: path.join(PATHS.logs, 'cc-tool-out.log'),
171
- error: path.join(PATHS.logs, 'cc-tool-error.log'),
171
+ error: path.join(PATHS.logs, 'cc-tool-out.log'),
172
172
  merge_logs: true,
173
173
  log_date_format: 'YYYY-MM-DD HH:mm:ss'
174
174
  }, async (err) => {
175
175
  if (err) {
176
- console.error(chalk.red('\n 启动服务失败:'), err.message);
176
+ console.error(chalk.red('\n[ERROR] 启动服务失败:'), err.message);
177
177
  disconnectPM2();
178
178
  process.exit(1);
179
179
  }
@@ -183,10 +183,10 @@ async function handleStart() {
183
183
  readyState = await waitForServiceReady(port);
184
184
  if (!readyState.ready) {
185
185
  const statusText = readyState.process?.pm2_env?.status || 'unknown';
186
- console.error(chalk.red('\n Coding-Tool 服务启动失败,进程未就绪\n'));
186
+ console.error(chalk.red('\n[ERROR] Coding-Tool 服务启动失败,进程未就绪\n'));
187
187
  console.error(chalk.gray(`PM2 状态: ${statusText}`));
188
188
  printPortToolIssue(readyState.degradedPortCheckIssue);
189
- console.error(chalk.yellow('💡 请使用 ctx logs ui 查看详细日志\n'));
189
+ console.error(chalk.yellow('[TIP] 请使用 ctx logs ui 查看详细日志\n'));
190
190
 
191
191
  pm2.delete(PM2_APP_NAME, () => {
192
192
  pm2.dump(() => {
@@ -197,16 +197,16 @@ async function handleStart() {
197
197
  return;
198
198
  }
199
199
  } catch (checkError) {
200
- console.error(chalk.red('\n 启动后健康检查失败:'), checkError.message);
200
+ console.error(chalk.red('\n[ERROR] 启动后健康检查失败:'), checkError.message);
201
201
  disconnectPM2();
202
202
  process.exit(1);
203
203
  }
204
204
 
205
- console.log(chalk.green('\n Coding-Tool 服务已启动(后台运行)\n'));
205
+ console.log(chalk.green('\n[OK] Coding-Tool 服务已启动(后台运行)\n'));
206
206
  console.log(chalk.gray(`Web UI: http://localhost:${port}`));
207
207
  printPortToolIssue(readyState.degradedPortCheckIssue);
208
208
  if (enableHost) {
209
- console.log(chalk.yellow(`⚠️ LAN 访问已启用 (http://<your-ip>:${port})`));
209
+ console.log(chalk.yellow(`[WARN] LAN 访问已启用 (http://<your-ip>:${port})`));
210
210
  }
211
211
  console.log(chalk.gray('\n可以安全关闭此终端窗口'));
212
212
  console.log(chalk.gray('\n常用命令:'));
@@ -235,14 +235,14 @@ async function handleStop() {
235
235
 
236
236
  const existing = await getCCToolProcess();
237
237
  if (!existing) {
238
- console.log(chalk.yellow('\n⚠️ 服务未在运行\n'));
238
+ console.log(chalk.yellow('\n[WARN] 服务未在运行\n'));
239
239
  disconnectPM2();
240
240
  return;
241
241
  }
242
242
 
243
243
  pm2.stop(PM2_APP_NAME, (err) => {
244
244
  if (err) {
245
- console.error(chalk.red('\n 停止服务失败:'), err.message);
245
+ console.error(chalk.red('\n[ERROR] 停止服务失败:'), err.message);
246
246
  disconnectPM2();
247
247
  process.exit(1);
248
248
  }
@@ -252,7 +252,7 @@ async function handleStop() {
252
252
  if (err) {
253
253
  console.error(chalk.red('删除进程失败:'), err.message);
254
254
  } else {
255
- console.log(chalk.green('\n Coding-Tool 服务已停止\n'));
255
+ console.log(chalk.green('\n[OK] Coding-Tool 服务已停止\n'));
256
256
  }
257
257
 
258
258
  pm2.dump((err) => {
@@ -276,19 +276,19 @@ async function handleRestart() {
276
276
 
277
277
  const existing = await getCCToolProcess();
278
278
  if (!existing) {
279
- console.log(chalk.yellow('\n⚠️ 服务未在运行,请使用 ') + chalk.cyan('ctx start') + chalk.yellow(' 启动\n'));
279
+ console.log(chalk.yellow('\n[WARN] 服务未在运行,请使用 ') + chalk.cyan('ctx start') + chalk.yellow(' 启动\n'));
280
280
  disconnectPM2();
281
281
  return;
282
282
  }
283
283
 
284
284
  pm2.restart(PM2_APP_NAME, (err) => {
285
285
  if (err) {
286
- console.error(chalk.red('\n 重启服务失败:'), err.message);
286
+ console.error(chalk.red('\n[ERROR] 重启服务失败:'), err.message);
287
287
  disconnectPM2();
288
288
  process.exit(1);
289
289
  }
290
290
 
291
- console.log(chalk.green('\n Coding-Tool 服务已重启\n'));
291
+ console.log(chalk.green('\n[OK] Coding-Tool 服务已重启\n'));
292
292
 
293
293
  pm2.dump((err) => {
294
294
  disconnectPM2();
@@ -311,21 +311,21 @@ async function handleStatus() {
311
311
  const existing = await getCCToolProcess();
312
312
  const config = loadConfig();
313
313
 
314
- console.log(chalk.bold.cyan('\n╔══════════════════════════════════════╗'));
314
+ console.log(chalk.bold.cyan('\n╔======================================╗'));
315
315
  console.log(chalk.bold.cyan('║ Coding-Tool 服务状态 ║'));
316
- console.log(chalk.bold.cyan('╚══════════════════════════════════════╝\n'));
316
+ console.log(chalk.bold.cyan('╚======================================╝\n'));
317
317
 
318
318
  // UI 服务状态
319
- console.log(chalk.bold('📱 Web UI 服务:'));
319
+ console.log(chalk.bold('[UI] Web UI 服务:'));
320
320
  if (existing && existing.pm2_env.status === 'online') {
321
- console.log(chalk.green(' 状态: 运行中'));
322
- console.log(chalk.gray(` 🌐 地址: http://localhost:${config.ports?.webUI || 19999}`));
323
- console.log(chalk.gray(` 🔑 进程 ID: ${existing.pid}`));
324
- console.log(chalk.gray(` ⏱️ 运行时长: ${formatUptime(existing.pm2_env.pm_uptime)}`));
325
- console.log(chalk.gray(` 💾 内存使用: ${formatMemory(existing.monit?.memory)}`));
326
- console.log(chalk.gray(` 🔄 重启次数: ${existing.pm2_env.restart_time}`));
321
+ console.log(chalk.green(' [OK] 状态: 运行中'));
322
+ console.log(chalk.gray(` [NET] 地址: http://localhost:${config.ports?.webUI || 19999}`));
323
+ console.log(chalk.gray(` [KEY] 进程 ID: ${existing.pid}`));
324
+ console.log(chalk.gray(` [TIMER] 运行时长: ${formatUptime(existing.pm2_env.pm_uptime)}`));
325
+ console.log(chalk.gray(` [SAVE] 内存使用: ${formatMemory(existing.monit?.memory)}`));
326
+ console.log(chalk.gray(` [SYNC] 重启次数: ${existing.pm2_env.restart_time}`));
327
327
  } else {
328
- console.log(chalk.gray(' 状态: 未运行'));
328
+ console.log(chalk.gray(' [ERROR] 状态: 未运行'));
329
329
  }
330
330
 
331
331
  // 代理服务状态(从运行时文件检测)
@@ -336,21 +336,21 @@ async function handleStatus() {
336
336
  const geminiActive = fs.existsSync(PATHS.activeChannel.gemini);
337
337
  const opencodeActive = fs.existsSync(PATHS.activeChannel.opencode);
338
338
 
339
- console.log(chalk.bold('\n🔌 代理服务:'));
339
+ console.log(chalk.bold('\n[PROXY] 代理服务:'));
340
340
 
341
- console.log(chalk.gray(' Claude: ') + (claudeActive ? chalk.green(' 运行中') : chalk.gray('⏹️ 未启动')) +
341
+ console.log(chalk.gray(' Claude: ') + (claudeActive ? chalk.green('[OK] 运行中') : chalk.gray('[STOP] 未启动')) +
342
342
  chalk.gray(` (http://localhost:${config.ports?.proxy || 20088})`));
343
343
 
344
- console.log(chalk.gray(' Codex: ') + (codexActive ? chalk.green(' 运行中') : chalk.gray('⏹️ 未启动')) +
344
+ console.log(chalk.gray(' Codex: ') + (codexActive ? chalk.green('[OK] 运行中') : chalk.gray('[STOP] 未启动')) +
345
345
  chalk.gray(` (http://localhost:${config.ports?.codexProxy || 20089})`));
346
346
 
347
- console.log(chalk.gray(' Gemini: ') + (geminiActive ? chalk.green(' 运行中') : chalk.gray('⏹️ 未启动')) +
347
+ console.log(chalk.gray(' Gemini: ') + (geminiActive ? chalk.green('[OK] 运行中') : chalk.gray('[STOP] 未启动')) +
348
348
  chalk.gray(` (http://localhost:${config.ports?.geminiProxy || 20090})`));
349
349
 
350
- console.log(chalk.gray(' OpenCode:') + (opencodeActive ? chalk.green(' 运行中') : chalk.gray('⏹️ 未启动')) +
350
+ console.log(chalk.gray(' OpenCode:') + (opencodeActive ? chalk.green('[OK] 运行中') : chalk.gray('[STOP] 未启动')) +
351
351
  chalk.gray(` (http://localhost:${config.ports?.opencodeProxy || 20091})`));
352
352
 
353
- console.log(chalk.bold('\n💡 提示:'));
353
+ console.log(chalk.bold('\n[TIP] 提示:'));
354
354
  console.log(chalk.gray(' • 代理服务通过 Web UI 界面控制'));
355
355
  console.log(chalk.gray(' • 使用 ') + chalk.cyan('ctx logs [type]') + chalk.gray(' 查看日志'));
356
356
  console.log(chalk.gray(' • 使用 ') + chalk.cyan('ctx stats [type]') + chalk.gray(' 查看统计信息\n'));
@@ -13,9 +13,9 @@ const execAsync = promisify(exec);
13
13
  * 诊断系统
14
14
  */
15
15
  async function handleDoctor() {
16
- console.log(chalk.bold.cyan('\n╔══════════════════════════════════════╗'));
16
+ console.log(chalk.bold.cyan('\n╔======================================╗'));
17
17
  console.log(chalk.bold.cyan('║ Coding-Tool 系统诊断 ║'));
18
- console.log(chalk.bold.cyan('╚══════════════════════════════════════╝\n'));
18
+ console.log(chalk.bold.cyan('╚======================================╝\n'));
19
19
 
20
20
  const checks = [];
21
21
 
@@ -41,23 +41,23 @@ async function handleDoctor() {
41
41
  checks.push(await checkDiskSpace());
42
42
 
43
43
  // 显示结果
44
- console.log(chalk.bold('\n📋 诊断结果:\n'));
44
+ console.log(chalk.bold('\n[LOG] 诊断结果:\n'));
45
45
 
46
46
  let passedCount = 0;
47
47
  let warningCount = 0;
48
48
  let failedCount = 0;
49
49
 
50
50
  checks.forEach(check => {
51
- const icon = check.status === 'pass' ? chalk.green('') :
52
- check.status === 'warning' ? chalk.yellow('⚠️') :
53
- chalk.red('');
51
+ const icon = check.status === 'pass' ? chalk.green('[OK]') :
52
+ check.status === 'warning' ? chalk.yellow('[WARN]') :
53
+ chalk.red('[ERROR]');
54
54
 
55
55
  console.log(`${icon} ${check.name}`);
56
56
  if (check.message) {
57
57
  console.log(chalk.gray(` ${check.message}`));
58
58
  }
59
59
  if (check.suggestion) {
60
- console.log(chalk.cyan(` 💡 ${check.suggestion}`));
60
+ console.log(chalk.cyan(` [TIP] ${check.suggestion}`));
61
61
  }
62
62
  console.log('');
63
63
 
@@ -67,23 +67,23 @@ async function handleDoctor() {
67
67
  });
68
68
 
69
69
  // 总结
70
- console.log(chalk.bold('📊 总结:'));
71
- console.log(chalk.green(` 通过: ${passedCount}`));
70
+ console.log(chalk.bold('[STATS] 总结:'));
71
+ console.log(chalk.green(` [OK] 通过: ${passedCount}`));
72
72
  if (warningCount > 0) {
73
- console.log(chalk.yellow(` ⚠️ 警告: ${warningCount}`));
73
+ console.log(chalk.yellow(` [WARN] 警告: ${warningCount}`));
74
74
  }
75
75
  if (failedCount > 0) {
76
- console.log(chalk.red(` 失败: ${failedCount}`));
76
+ console.log(chalk.red(` [ERROR] 失败: ${failedCount}`));
77
77
  }
78
78
 
79
79
  console.log('');
80
80
 
81
81
  if (failedCount > 0) {
82
- console.log(chalk.red('⚠️ 发现问题,请根据上述建议进行修复\n'));
82
+ console.log(chalk.red('[WARN] 发现问题,请根据上述建议进行修复\n'));
83
83
  } else if (warningCount > 0) {
84
- console.log(chalk.yellow('⚠️ 发现一些警告,建议查看并处理\n'));
84
+ console.log(chalk.yellow('[WARN] 发现一些警告,建议查看并处理\n'));
85
85
  } else {
86
- console.log(chalk.green(' 系统运行正常!\n'));
86
+ console.log(chalk.green('[OK] 系统运行正常!\n'));
87
87
  }
88
88
  }
89
89
 
@@ -12,7 +12,7 @@ async function exportConfig(options = {}) {
12
12
  const { output = 'claude-config.zip', includeProjects = true } = options;
13
13
 
14
14
  try {
15
- console.log(chalk.blue('🚀 开始导出 Claude Code 配置...'));
15
+ console.log(chalk.blue('[START] 开始导出 Claude Code 配置...'));
16
16
 
17
17
  const homeDir = HOME_DIR;
18
18
  const claudeDir = path.join(homeDir, '.claude');
@@ -20,7 +20,7 @@ async function exportConfig(options = {}) {
20
20
 
21
21
  // 检查 .claude 目录是否存在
22
22
  if (!fs.existsSync(claudeDir)) {
23
- console.log(chalk.red(' 未找到 .claude 配置目录'));
23
+ console.log(chalk.red('[ERROR] 未找到 .claude 配置目录'));
24
24
  return;
25
25
  }
26
26
 
@@ -36,7 +36,7 @@ async function exportConfig(options = {}) {
36
36
 
37
37
  // 监听完成
38
38
  archive.on('end', () => {
39
- console.log(chalk.green(`\n 配置导出成功!`));
39
+ console.log(chalk.green(`\n[OK] 配置导出成功!`));
40
40
  console.log(chalk.gray(` 文件位置: ${outputPath}`));
41
41
  console.log(chalk.gray(` 文件大小: ${(archive.pointer() / 1024 / 1024).toFixed(2)} MB`));
42
42
  });
@@ -59,7 +59,7 @@ async function exportConfig(options = {}) {
59
59
  archive.file(globalClaudeMd, { name: 'global/CLAUDE.md' });
60
60
  manifest.globalConfig.claudeMd = true;
61
61
  manifest.enabledConfigs.push('global/CLAUDE.md');
62
- console.log(chalk.gray(' 全局 CLAUDE.md'));
62
+ console.log(chalk.gray(' [v] 全局 CLAUDE.md'));
63
63
  }
64
64
 
65
65
  // 2. 导出 settings.json
@@ -68,7 +68,7 @@ async function exportConfig(options = {}) {
68
68
  archive.file(settingsJson, { name: 'global/settings.json' });
69
69
  manifest.globalConfig.settings = true;
70
70
  manifest.enabledConfigs.push('global/settings.json');
71
- console.log(chalk.gray(' settings.json'));
71
+ console.log(chalk.gray(' [v] settings.json'));
72
72
 
73
73
  // 解析 MCP 服务器配置
74
74
  try {
@@ -84,7 +84,7 @@ async function exportConfig(options = {}) {
84
84
  manifest.globalConfig.statusLine = true;
85
85
  }
86
86
  } catch (e) {
87
- console.log(chalk.yellow(' settings.json 解析失败'));
87
+ console.log(chalk.yellow(' [!] settings.json 解析失败'));
88
88
  }
89
89
  }
90
90
 
@@ -96,7 +96,7 @@ async function exportConfig(options = {}) {
96
96
  archive.directory(skillsDir, 'global/skills');
97
97
  manifest.globalConfig.skills = skills;
98
98
  manifest.enabledConfigs.push('global/skills');
99
- console.log(chalk.gray(` Skills (${skills.length} 个)`));
99
+ console.log(chalk.gray(` [v] Skills (${skills.length} 个)`));
100
100
  }
101
101
  }
102
102
 
@@ -108,7 +108,7 @@ async function exportConfig(options = {}) {
108
108
  archive.file(projectClaudeMd, { name: 'project/CLAUDE.md' });
109
109
  manifest.projectConfig.claudeMd = true;
110
110
  manifest.enabledConfigs.push('project/CLAUDE.md');
111
- console.log(chalk.gray(' 项目 CLAUDE.md'));
111
+ console.log(chalk.gray(' [v] 项目 CLAUDE.md'));
112
112
  }
113
113
 
114
114
  // 项目级 settings.local.json
@@ -117,7 +117,7 @@ async function exportConfig(options = {}) {
117
117
  archive.file(projectSettings, { name: 'project/.claude/settings.local.json' });
118
118
  manifest.projectConfig.settingsLocal = true;
119
119
  manifest.enabledConfigs.push('project/.claude/settings.local.json');
120
- console.log(chalk.gray(' 项目 settings.local.json'));
120
+ console.log(chalk.gray(' [v] 项目 settings.local.json'));
121
121
  }
122
122
 
123
123
  // 项目级 workspace CLAUDE.md
@@ -126,24 +126,24 @@ async function exportConfig(options = {}) {
126
126
  archive.file(workspaceClaudeMd, { name: 'workspace/CLAUDE.md' });
127
127
  manifest.projectConfig.workspaceClaudeMd = true;
128
128
  manifest.enabledConfigs.push('workspace/CLAUDE.md');
129
- console.log(chalk.gray(' workspace CLAUDE.md'));
129
+ console.log(chalk.gray(' [v] workspace CLAUDE.md'));
130
130
  }
131
131
  }
132
132
 
133
133
  // 5. 添加配置清单
134
134
  archive.append(JSON.stringify(manifest, null, 2), { name: 'manifest.json' });
135
- console.log(chalk.gray(' manifest.json'));
135
+ console.log(chalk.gray(' [v] manifest.json'));
136
136
 
137
137
  // 6. 添加 README
138
138
  const readme = generateReadme(manifest);
139
139
  archive.append(readme, { name: 'README.md' });
140
- console.log(chalk.gray(' README.md'));
140
+ console.log(chalk.gray(' [v] README.md'));
141
141
 
142
142
  // 完成打包
143
143
  await archive.finalize();
144
144
 
145
145
  } catch (error) {
146
- console.error(chalk.red(' 导出失败:'), error.message);
146
+ console.error(chalk.red('[ERROR] 导出失败:'), error.message);
147
147
  throw error;
148
148
  }
149
149
  }
@@ -157,21 +157,21 @@ function generateReadme(manifest) {
157
157
  导出时间: ${new Date(manifest.exportTime).toLocaleString('zh-CN')}
158
158
  版本: ${manifest.version}
159
159
 
160
- ## 📦 包含内容
160
+ ## [PKG] 包含内容
161
161
 
162
162
  ### 全局配置
163
- ${manifest.globalConfig.claudeMd ? '- 全局 CLAUDE.md(AI 行为指令)' : ''}
164
- ${manifest.globalConfig.settings ? '- settings.json(包含 MCP 服务器、Hooks 等)' : ''}
163
+ ${manifest.globalConfig.claudeMd ? '- [OK] 全局 CLAUDE.md(AI 行为指令)' : ''}
164
+ ${manifest.globalConfig.settings ? '- [OK] settings.json(包含 MCP 服务器、Hooks 等)' : ''}
165
165
  ${manifest.globalConfig.mcpServers ? ` - MCP 服务器: ${manifest.globalConfig.mcpServers.join(', ')}` : ''}
166
166
  ${manifest.globalConfig.hooks ? ` - Hooks: ${manifest.globalConfig.hooks.join(', ')}` : ''}
167
- ${manifest.globalConfig.skills ? `- Skills (${manifest.globalConfig.skills.length} 个): ${manifest.globalConfig.skills.join(', ')}` : ''}
167
+ ${manifest.globalConfig.skills ? `- [OK] Skills (${manifest.globalConfig.skills.length} 个): ${manifest.globalConfig.skills.join(', ')}` : ''}
168
168
 
169
169
  ### 项目配置
170
- ${manifest.projectConfig.claudeMd ? '- 项目 CLAUDE.md' : ''}
171
- ${manifest.projectConfig.settingsLocal ? '- 项目 settings.local.json' : ''}
172
- ${manifest.projectConfig.workspaceClaudeMd ? '- workspace CLAUDE.md' : ''}
170
+ ${manifest.projectConfig.claudeMd ? '- [OK] 项目 CLAUDE.md' : ''}
171
+ ${manifest.projectConfig.settingsLocal ? '- [OK] 项目 settings.local.json' : ''}
172
+ ${manifest.projectConfig.workspaceClaudeMd ? '- [OK] workspace CLAUDE.md' : ''}
173
173
 
174
- ## 📥 如何导入
174
+ ## [IMPORT] 如何导入
175
175
 
176
176
  ### 方法 1:手动导入
177
177
  1. 解压此 ZIP 文件
@@ -184,14 +184,14 @@ ${manifest.projectConfig.workspaceClaudeMd ? '- ✅ workspace CLAUDE.md' : ''}
184
184
  ctx import-config claude-config.zip
185
185
  \`\`\`
186
186
 
187
- ## ⚠️ 注意事项
187
+ ## [WARN] 注意事项
188
188
 
189
189
  1. **备份现有配置**:导入前请备份现有的 \`.claude\` 目录
190
190
  2. **敏感信息**:此配置包可能包含 API Keys、代理配置等敏感信息,请妥善保管
191
191
  3. **路径适配**:某些路径可能需要根据你的系统调整(如 hooks 中的脚本路径)
192
192
  4. **MCP 服务器**:需要确保目标环境已安装对应的 MCP 服务器
193
193
 
194
- ## 📝 配置清单
194
+ ## [NOTE] 配置清单
195
195
 
196
196
  已启用的配置项:
197
197
  ${manifest.enabledConfigs.map(c => `- ${c}`).join('\n')}
@@ -77,7 +77,7 @@ async function listSessions(config, limit = null) {
77
77
 
78
78
  // 清屏并重新显示,避免之前的输出干扰
79
79
  console.clear();
80
- console.log(chalk.green(`\n 找到 ${sessions.length} 个会话\n`));
80
+ console.log(chalk.green(`\n[NEW] 找到 ${sessions.length} 个会话\n`));
81
81
 
82
82
  return choices;
83
83
  }
@@ -150,7 +150,7 @@ async function listRecentSessionsAcrossProjects(config, limit = null) {
150
150
 
151
151
  // 清屏并重新显示,避免之前的输出干扰
152
152
  console.clear();
153
- console.log(chalk.green(`\n 找到 ${sessions.length} 个最新对话(跨所有项目)\n`));
153
+ console.log(chalk.green(`\n[NEW] 找到 ${sessions.length} 个最新对话(跨所有项目)\n`));
154
154
 
155
155
  return choices;
156
156
  }
@@ -171,11 +171,11 @@ async function handleList(config, switchProjectCallback, crossProject = false) {
171
171
 
172
172
  // 添加操作选项
173
173
  choices.push(new inquirer.Separator(chalk.gray('─'.repeat(50))));
174
- choices.push({ name: chalk.blue('↩️ 返回主菜单'), value: 'back' });
174
+ choices.push({ name: chalk.blue('[<-] 返回主菜单'), value: 'back' });
175
175
 
176
176
  // 跨项目模式不显示切换项目选项(因为已经是跨所有项目了)
177
177
  if (!crossProject) {
178
- choices.push({ name: chalk.magenta('🔀 切换项目'), value: 'switch' });
178
+ choices.push({ name: chalk.magenta('[SWITCH] 切换项目'), value: 'switch' });
179
179
  }
180
180
 
181
181
  const selected = await promptSelectSession(choices);