coding-tool-x 3.4.3 → 3.4.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.
Files changed (56) hide show
  1. package/dist/web/assets/{Analytics-CbGxotgz.js → Analytics-_Byi9M6y.js} +1 -1
  2. package/dist/web/assets/{ConfigTemplates-oP6nrFEb.js → ConfigTemplates-DIwosdtG.js} +1 -1
  3. package/dist/web/assets/{Home-DMntmEvh.js → Home-DdNMuQ9c.js} +1 -1
  4. package/dist/web/assets/{PluginManager-BUC_c7nH.js → PluginManager-iuY24cnW.js} +1 -1
  5. package/dist/web/assets/{ProjectList-oJIyIRkP.css → ProjectList-DL4JK6ci.css} +1 -1
  6. package/dist/web/assets/{ProjectList-CW8J49n7.js → ProjectList-DSkMulzL.js} +1 -1
  7. package/dist/web/assets/{SessionList-7lYnF92v.js → SessionList-B6pGquIr.js} +1 -1
  8. package/dist/web/assets/{SkillManager-Cs08216i.js → SkillManager-CHtQX5r8.js} +1 -1
  9. package/dist/web/assets/{WorkspaceManager-CY-oGtyB.js → WorkspaceManager-gNPs-VaI.js} +1 -1
  10. package/dist/web/assets/index-DGjGCo37.js +2 -0
  11. package/dist/web/assets/{index-5qy5NMIP.css → index-pMqqe9ei.css} +1 -1
  12. package/dist/web/index.html +2 -2
  13. package/package.json +1 -1
  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 +2 -2
  39. package/src/server/api/plugins.js +4 -0
  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 +4 -0
  43. package/src/server/dev-server.js +2 -2
  44. package/src/server/index.js +37 -37
  45. package/src/server/proxy-server.js +4 -4
  46. package/src/server/services/config-export-service.js +1 -1
  47. package/src/server/services/mcp-service.js +2 -1
  48. package/src/server/services/model-detector.js +2 -2
  49. package/src/server/services/native-keychain.js +1 -0
  50. package/src/server/services/plugins-service.js +7 -27
  51. package/src/server/services/settings-manager.js +3 -3
  52. package/src/server/services/skill-service.js +4 -12
  53. package/src/server/websocket-server.js +8 -8
  54. package/src/ui/menu.js +2 -2
  55. package/src/ui/prompts.js +5 -5
  56. package/dist/web/assets/index-ClCqKpvX.js +0 -2
@@ -151,7 +151,7 @@ async function handleToggleProxy() {
151
151
  const cliType = config.currentCliType || 'claude';
152
152
  const services = getProxyServices(cliType);
153
153
  if (!services) {
154
- console.log(chalk.red(`\n 当前 CLI 类型 (${cliType}) 暂不支持动态切换\n`));
154
+ console.log(chalk.red(`\n[ERROR] 当前 CLI 类型 (${cliType}) 暂不支持动态切换\n`));
155
155
  return;
156
156
  }
157
157
 
@@ -171,9 +171,9 @@ async function handleToggleProxy() {
171
171
  */
172
172
  async function handleStartProxy(cliType, services) {
173
173
  console.clear();
174
- console.log(chalk.bold.cyan('\n╔═══════════════════════════════════════╗'));
174
+ console.log(chalk.bold.cyan('\n╔=======================================╗'));
175
175
  console.log(chalk.bold.cyan('║ 开启动态切换 ║'));
176
- console.log(chalk.bold.cyan('╚═══════════════════════════════════════╝\n'));
176
+ console.log(chalk.bold.cyan('╚=======================================╝\n'));
177
177
 
178
178
  const toolNameMap = {
179
179
  claude: 'Claude Code',
@@ -190,7 +190,7 @@ async function handleStartProxy(cliType, services) {
190
190
  console.log(chalk.gray('• 通过 Web UI 或"渠道管理"功能快速调整启用的线路'));
191
191
  console.log(chalk.gray(`• 代理服务地址: http://127.0.0.1:${defaultPort}\n`));
192
192
 
193
- console.log(chalk.yellow('⚠️ 重要提示:'));
193
+ console.log(chalk.yellow('[WARN] 重要提示:'));
194
194
  console.log(chalk.yellow('• 开启期间请勿关闭 CLI 终端窗口'));
195
195
  console.log(chalk.yellow('• 如果异常关闭导致代理失效,请运行: ctx reset'));
196
196
  console.log(chalk.yellow('• 或使用主菜单的"恢复默认配置"功能\n'));
@@ -210,7 +210,7 @@ async function handleStartProxy(cliType, services) {
210
210
  }
211
211
 
212
212
  try {
213
- console.log(chalk.cyan('\n🚀 正在启动代理服务...\n'));
213
+ console.log(chalk.cyan('\n[START] 正在启动代理服务...\n'));
214
214
 
215
215
  // 启动代理服务器
216
216
  const proxyResult = await services.startProxyServer();
@@ -219,19 +219,19 @@ async function handleStartProxy(cliType, services) {
219
219
  throw new Error('代理服务器启动失败');
220
220
  }
221
221
 
222
- console.log(chalk.green(`✅ 代理服务已启动: http://127.0.0.1:${proxyResult.port}`));
222
+ console.log(chalk.green(`[OK] 代理服务已启动: http://127.0.0.1:${proxyResult.port}`));
223
223
 
224
224
  // 修改配置文件
225
225
  const settingsManager = getSettingsManager(cliType);
226
226
  clearNativeOAuth(cliType);
227
227
  settingsManager.setProxyConfig(proxyResult.port);
228
- console.log(chalk.green(' 配置文件已更新'));
228
+ console.log(chalk.green('[OK] 配置文件已更新'));
229
229
 
230
230
  if (settingsManager.hasBackup()) {
231
- console.log(chalk.green(' 原配置已备份'));
231
+ console.log(chalk.green('[OK] 原配置已备份'));
232
232
  }
233
233
 
234
- console.log(chalk.cyan('\n💡 动态切换已启用!'));
234
+ console.log(chalk.cyan('\n[TIP] 动态切换已启用!'));
235
235
  console.log(chalk.gray(` 现在可以通过"渠道管理"功能快速调整,无需重启 ${toolName}\n`));
236
236
 
237
237
  await inquirer.prompt([
@@ -242,7 +242,7 @@ async function handleStartProxy(cliType, services) {
242
242
  },
243
243
  ]);
244
244
  } catch (error) {
245
- console.log(chalk.red(`\n 启动失败: ${error.message}\n`));
245
+ console.log(chalk.red(`\n[ERROR] 启动失败: ${error.message}\n`));
246
246
 
247
247
  await inquirer.prompt([
248
248
  {
@@ -259,9 +259,9 @@ async function handleStartProxy(cliType, services) {
259
259
  */
260
260
  async function handleStopProxy(cliType, services) {
261
261
  console.clear();
262
- console.log(chalk.bold.cyan('\n╔═══════════════════════════════════════╗'));
262
+ console.log(chalk.bold.cyan('\n╔=======================================╗'));
263
263
  console.log(chalk.bold.cyan('║ 关闭动态切换 ║'));
264
- console.log(chalk.bold.cyan('╚═══════════════════════════════════════╝\n'));
264
+ console.log(chalk.bold.cyan('╚=======================================╝\n'));
265
265
 
266
266
  const toolNameMap = {
267
267
  claude: 'Claude Code',
@@ -297,11 +297,11 @@ async function handleStopProxy(cliType, services) {
297
297
  }
298
298
 
299
299
  try {
300
- console.log(chalk.cyan('\n⏹️ 正在停止代理服务...\n'));
300
+ console.log(chalk.cyan('\n[STOP] 正在停止代理服务...\n'));
301
301
 
302
302
  // 停止代理服务器
303
303
  await services.stopProxyServer();
304
- console.log(chalk.green(' 代理服务已停止'));
304
+ console.log(chalk.green('[OK] 代理服务已停止'));
305
305
 
306
306
  // 恢复配置文件
307
307
  const settingsManager = getSettingsManager(cliType);
@@ -309,12 +309,12 @@ async function handleStopProxy(cliType, services) {
309
309
  const restoredChannel = restoreSingleChannelMode(cliType);
310
310
  removeActiveChannelMarker(cliType);
311
311
  if (restoredChannel?.name) {
312
- console.log(chalk.green(`✅ 已恢复到渠道: ${restoredChannel.name}`));
312
+ console.log(chalk.green(`[OK] 已恢复到渠道: ${restoredChannel.name}`));
313
313
  } else {
314
- console.log(chalk.green(' 已清理代理接管状态'));
314
+ console.log(chalk.green('[OK] 已清理代理接管状态'));
315
315
  }
316
316
 
317
- console.log(chalk.cyan('\n💡 动态切换已关闭'));
317
+ console.log(chalk.cyan('\n[TIP] 动态切换已关闭'));
318
318
  console.log(chalk.gray(` 现在调整渠道需要重启 ${toolName} 才能生效\n`));
319
319
 
320
320
  await inquirer.prompt([
@@ -325,7 +325,7 @@ async function handleStopProxy(cliType, services) {
325
325
  },
326
326
  ]);
327
327
  } catch (error) {
328
- console.log(chalk.red(`\n 停止失败: ${error.message}\n`));
328
+ console.log(chalk.red(`\n[ERROR] 停止失败: ${error.message}\n`));
329
329
 
330
330
  await inquirer.prompt([
331
331
  {
@@ -14,9 +14,9 @@ async function handleUI() {
14
14
 
15
15
  if (!isDaemon) {
16
16
  console.clear();
17
- console.log(chalk.cyan.bold('\n🌐 启动 Coding-Tool Web UI...\n'));
17
+ console.log(chalk.cyan.bold('\n[NET] 启动 Coding-Tool Web UI...\n'));
18
18
  if (enableHost) {
19
- console.log(chalk.yellow('⚠️ LAN 访问已启用 (--host)\n'));
19
+ console.log(chalk.yellow('[WARN] LAN 访问已启用 (--host)\n'));
20
20
  }
21
21
  }
22
22
 
@@ -33,9 +33,9 @@ async function handleUI() {
33
33
  setTimeout(async () => {
34
34
  try {
35
35
  await open(url);
36
- console.log(chalk.green(`✅ 已在浏览器中打开: ${url}\n`));
36
+ console.log(chalk.green(`[OK] 已在浏览器中打开: ${url}\n`));
37
37
  } catch (err) {
38
- console.log(chalk.yellow(`💡 请手动打开: ${url}\n`));
38
+ console.log(chalk.yellow(`[TIP] 请手动打开: ${url}\n`));
39
39
  }
40
40
  }, 1000);
41
41
  }
@@ -43,18 +43,18 @@ async function handleUI() {
43
43
  // 处理退出信号(仅非 daemon 模式)
44
44
  if (!isDaemon) {
45
45
  process.on('SIGINT', async () => {
46
- console.log(chalk.yellow('\n\n👋 正在停止服务器...\n'));
46
+ console.log(chalk.yellow('\n\n[BYE] 正在停止服务器...\n'));
47
47
 
48
48
  // 检查代理状态并询问是否停止
49
49
  try {
50
50
  const proxyStatus = getProxyStatus();
51
51
  if (proxyStatus.running) {
52
- console.log(chalk.yellow('⚠️ 检测到代理服务正在运行'));
52
+ console.log(chalk.yellow('[WARN] 检测到代理服务正在运行'));
53
53
  console.log(chalk.gray(' - 代理端口: ' + proxyStatus.port));
54
54
  console.log(chalk.gray(' - 如需保持代理运行,请直接关闭此窗口\n'));
55
55
 
56
56
  // 自动停止代理(3秒后)
57
- console.log(chalk.cyan(' 将在 3 秒后自动停止代理服务...'));
57
+ console.log(chalk.cyan('[WAIT] 将在 3 秒后自动停止代理服务...'));
58
58
  console.log(chalk.gray(' 按 Ctrl+C 再次可立即退出并保持代理运行\n'));
59
59
 
60
60
  let stopProxy = true;
@@ -70,9 +70,9 @@ async function handleUI() {
70
70
  if (stopProxy) {
71
71
  const { stopProxyServer } = require('../server/proxy-server');
72
72
  await stopProxyServer();
73
- console.log(chalk.green(' 代理服务已停止\n'));
73
+ console.log(chalk.green('[OK] 代理服务已停止\n'));
74
74
  } else {
75
- console.log(chalk.yellow('⚠️ 代理服务保持运行状态'));
75
+ console.log(chalk.yellow('[WARN] 代理服务保持运行状态'));
76
76
  console.log(chalk.gray(' - 如需停止,请运行: ctx proxy stop\n'));
77
77
  }
78
78
  }
@@ -80,14 +80,14 @@ async function handleUI() {
80
80
  // 忽略错误
81
81
  }
82
82
 
83
- console.log(chalk.green(' Web UI 已停止\n'));
83
+ console.log(chalk.green('[OK] Web UI 已停止\n'));
84
84
  process.exit(0);
85
85
  });
86
86
 
87
87
  console.log(chalk.gray('按 Ctrl+C 停止服务器'));
88
88
  } else {
89
89
  // Daemon 模式:保持运行
90
- console.log(chalk.green(`✅ Coding-Tool 服务已在后台启动 (端口: ${port})`));
90
+ console.log(chalk.green(`[OK] Coding-Tool 服务已在后台启动 (端口: ${port})`));
91
91
  }
92
92
 
93
93
  } catch (error) {
@@ -55,7 +55,7 @@ async function handleUpdate(options = {}) {
55
55
  ].filter(Boolean)));
56
56
  const currentVersion = packageInfo.version;
57
57
 
58
- console.log(chalk.cyan('\n🔍 检查更新中...\n'));
58
+ console.log(chalk.cyan('\n[SEARCH] 检查更新中...\n'));
59
59
 
60
60
  let latestVersion;
61
61
  let packageName = packageCandidates[0];
@@ -75,18 +75,18 @@ async function handleUpdate(options = {}) {
75
75
  throw lastError || new Error('无法获取最新版本');
76
76
  }
77
77
  } catch (error) {
78
- console.error(chalk.red(`❌ 检查更新失败: ${error.message}`));
79
- console.log(chalk.gray('💡 可手动执行: npm view coding-tool-x version'));
78
+ console.error(chalk.red(`[ERROR] 检查更新失败: ${error.message}`));
79
+ console.log(chalk.gray('[TIP] 可手动执行: npm view coding-tool-x version'));
80
80
  return;
81
81
  }
82
82
 
83
83
  if (!semver.valid(currentVersion) || !semver.valid(latestVersion)) {
84
- console.log(chalk.yellow(`⚠️ 版本格式异常,当前: ${currentVersion}, 最新: ${latestVersion}`));
84
+ console.log(chalk.yellow(`[WARN] 版本格式异常,当前: ${currentVersion}, 最新: ${latestVersion}`));
85
85
  return;
86
86
  }
87
87
 
88
88
  if (!semver.gt(latestVersion, currentVersion)) {
89
- console.log(chalk.green(`✅ 已是最新版本: ${currentVersion}\n`));
89
+ console.log(chalk.green(`[OK] 已是最新版本: ${currentVersion}\n`));
90
90
  return;
91
91
  }
92
92
 
@@ -96,15 +96,15 @@ async function handleUpdate(options = {}) {
96
96
  return;
97
97
  }
98
98
 
99
- console.log(chalk.cyan('\n⬇️ 正在更新...\n'));
99
+ console.log(chalk.cyan('\n[DOWN] 正在更新...\n'));
100
100
 
101
101
  try {
102
102
  await runNpmInstall(packageName, latestVersion);
103
- console.log(chalk.green(`\n 更新完成: ${latestVersion}`));
103
+ console.log(chalk.green(`\n[OK] 更新完成: ${latestVersion}`));
104
104
  console.log(chalk.gray('请重新打开终端或重新执行 ctx --version 验证版本。\n'));
105
105
  } catch (error) {
106
- console.error(chalk.red(`\n 更新失败: ${error.message}`));
107
- console.log(chalk.gray(`💡 可手动执行: npm install -g ${packageName}@${latestVersion}\n`));
106
+ console.error(chalk.red(`\n[ERROR] 更新失败: ${error.message}`));
107
+ console.log(chalk.gray(`[TIP] 可手动执行: npm install -g ${packageName}@${latestVersion}\n`));
108
108
  }
109
109
  }
110
110
 
@@ -22,7 +22,7 @@ async function listWorkspaces() {
22
22
  console.log(chalk.bold.cyan('\n工作区列表:\n'));
23
23
 
24
24
  workspaces.forEach((ws, index) => {
25
- const status = ws.exists ? chalk.green('') : chalk.red('');
25
+ const status = ws.exists ? chalk.green('[v]') : chalk.red('[x]');
26
26
  console.log(`${index + 1}. ${status} ${chalk.bold(ws.name)}`);
27
27
 
28
28
  if (ws.description) {
@@ -35,7 +35,7 @@ async function listWorkspaces() {
35
35
  console.log('');
36
36
  });
37
37
  } catch (error) {
38
- console.error(chalk.red(`\n ${error.message}\n`));
38
+ console.error(chalk.red(`\n[ERROR] ${error.message}\n`));
39
39
  }
40
40
  }
41
41
 
@@ -132,7 +132,7 @@ async function createWorkspace() {
132
132
 
133
133
  projectChoices.push(
134
134
  new inquirer.Separator(chalk.gray('─'.repeat(14))),
135
- { name: chalk.gray(' 完成选择'), value: null }
135
+ { name: chalk.gray('[v] 完成选择'), value: null }
136
136
  );
137
137
 
138
138
  const { selectedProject } = await inquirer.prompt([
@@ -226,7 +226,7 @@ async function createWorkspace() {
226
226
  branch
227
227
  });
228
228
 
229
- console.log(chalk.green(`\n 已添加: ${linkName}\n`));
229
+ console.log(chalk.green(`\n[v] 已添加: ${linkName}\n`));
230
230
  }
231
231
 
232
232
  if (projects.length === 0) {
@@ -274,12 +274,12 @@ async function createWorkspace() {
274
274
  projects
275
275
  });
276
276
 
277
- console.log(chalk.green(`\n 工作区创建成功!\n`));
277
+ console.log(chalk.green(`\n[OK] 工作区创建成功!\n`));
278
278
  console.log(chalk.gray(`工作区路径: ${workspace.path}\n`));
279
279
  console.log(chalk.gray(`提示: 可以在此路径下启动 Claude Code 以访问所有项目\n`));
280
280
 
281
281
  } catch (error) {
282
- console.error(chalk.red(`\n ${error.message}\n`));
282
+ console.error(chalk.red(`\n[ERROR] ${error.message}\n`));
283
283
  }
284
284
  }
285
285
 
@@ -324,8 +324,8 @@ async function viewWorkspace() {
324
324
  console.log(chalk.bold.cyan(`\n包含项目 (${detail.projects.length}):\n`));
325
325
 
326
326
  detail.projects.forEach((proj, index) => {
327
- const linkStatus = proj.linkExists ? chalk.green('') : chalk.red('');
328
- const sourceStatus = proj.sourceExists ? chalk.green('') : chalk.red('');
327
+ const linkStatus = proj.linkExists ? chalk.green('[v]') : chalk.red('[x]');
328
+ const sourceStatus = proj.sourceExists ? chalk.green('[v]') : chalk.red('[x]');
329
329
 
330
330
  console.log(`${index + 1}. ${linkStatus} ${chalk.bold(proj.name)}`);
331
331
  console.log(chalk.gray(` 源路径: ${sourceStatus} ${proj.sourcePath}`));
@@ -341,7 +341,7 @@ async function viewWorkspace() {
341
341
  });
342
342
 
343
343
  } catch (error) {
344
- console.error(chalk.red(`\n ${error.message}\n`));
344
+ console.error(chalk.red(`\n[ERROR] ${error.message}\n`));
345
345
  }
346
346
  }
347
347
 
@@ -394,10 +394,10 @@ async function deleteWorkspace() {
394
394
  }
395
395
 
396
396
  workspaceService.deleteWorkspace(workspace.id, removeFiles);
397
- console.log(chalk.green('\n 工作区删除成功\n'));
397
+ console.log(chalk.green('\n[OK] 工作区删除成功\n'));
398
398
 
399
399
  } catch (error) {
400
- console.error(chalk.red(`\n ${error.message}\n`));
400
+ console.error(chalk.red(`\n[ERROR] ${error.message}\n`));
401
401
  }
402
402
  }
403
403
 
package/src/index.js CHANGED
@@ -43,13 +43,13 @@ function showHelp() {
43
43
  console.log(chalk.cyan.bold(`\nCODING-TOOL v${version}`));
44
44
  console.log(chalk.gray('Vibe Coding 增强工作助手 - 智能会话管理、动态渠道切换、全局搜索、实时监控\n'));
45
45
 
46
- console.log(chalk.yellow('🚀 服务管理:'));
46
+ console.log(chalk.yellow('[START] 服务管理:'));
47
47
  console.log(' ctx start 启动所有服务(后台运行)');
48
48
  console.log(' ctx stop 停止所有服务');
49
49
  console.log(' ctx restart 重启所有服务');
50
50
  console.log(' ctx status 查看服务状态\n');
51
51
 
52
- console.log(chalk.yellow('📱 UI 管理:'));
52
+ console.log(chalk.yellow('[UI] UI 管理:'));
53
53
  console.log(' ctx ui 前台启动 Web UI(仅本地访问)');
54
54
  console.log(' ctx ui --host 前台启动 Web UI(允许 LAN 访问)');
55
55
  console.log(' ctx ui start 后台启动 Web UI');
@@ -57,7 +57,7 @@ function showHelp() {
57
57
  console.log(' ctx ui stop 停止 Web UI');
58
58
  console.log(' ctx ui restart 重启 Web UI\n');
59
59
 
60
- console.log(chalk.yellow('🔌 代理管理:'));
60
+ console.log(chalk.yellow('[PROXY] 代理管理:'));
61
61
  console.log(' ctx claude start 启动 Claude 代理');
62
62
  console.log(' ctx claude stop 停止 Claude 代理');
63
63
  console.log(' ctx claude status 查看 Claude 代理状态');
@@ -66,7 +66,7 @@ function showHelp() {
66
66
  console.log(' ctx opencode start 启动 OpenCode 代理');
67
67
  console.log(chalk.gray(' (codex/gemini/opencode 命令与 claude 类似)\n'));
68
68
 
69
- console.log(chalk.yellow('📋 日志管理:'));
69
+ console.log(chalk.yellow('[LOG] 日志管理:'));
70
70
  console.log(' ctx logs 查看所有日志');
71
71
  console.log(' ctx logs ui 查看 UI 日志');
72
72
  console.log(' ctx logs claude 查看 Claude 日志');
@@ -74,13 +74,13 @@ function showHelp() {
74
74
  console.log(' ctx logs --follow 实时跟踪日志');
75
75
  console.log(' ctx logs --clear 清空日志\n');
76
76
 
77
- console.log(chalk.yellow('📊 统计信息:'));
77
+ console.log(chalk.yellow('[STATS] 统计信息:'));
78
78
  console.log(' ctx stats 查看总体统计');
79
79
  console.log(' ctx stats claude 查看 Claude 统计');
80
80
  console.log(' ctx stats --today 查看今日统计');
81
81
  console.log(' ctx stats export 导出统计数据\n');
82
82
 
83
- console.log(chalk.yellow('🛠️ 其他命令:'));
83
+ console.log(chalk.yellow('[TOOL] 其他命令:'));
84
84
  console.log(' ctx update 检查并更新到最新版本');
85
85
  console.log(' ctx doctor 系统诊断');
86
86
  console.log(' ctx port 配置端口');
@@ -89,7 +89,7 @@ function showHelp() {
89
89
  console.log(' ctx --version, -v 显示版本');
90
90
  console.log(' ctx --help, -h 显示帮助\n');
91
91
 
92
- console.log(chalk.yellow('🔌 插件管理:'));
92
+ console.log(chalk.yellow('[PROXY] 插件管理:'));
93
93
  console.log(' ctx plugin list 列出已安装插件');
94
94
  console.log(' ctx plugin install <url> 从 Git 安装插件');
95
95
  console.log(' ctx plugin remove <name> 卸载插件');
@@ -100,13 +100,13 @@ function showHelp() {
100
100
  console.log(' ctx plugin update <name> 更新插件');
101
101
  console.log(' ctx plugin update --all 更新所有插件\n');
102
102
 
103
- console.log(chalk.yellow('💡 快速开始:'));
103
+ console.log(chalk.yellow('[TIP] 快速开始:'));
104
104
  console.log(chalk.gray(' $ ctx start # 后台启动服务(推荐)'));
105
105
  console.log(chalk.gray(' $ ctx status # 查看服务状态'));
106
106
  console.log(chalk.gray(' $ ctx logs # 查看实时日志'));
107
107
  console.log(chalk.gray(' $ ctx stop # 停止服务\n'));
108
108
 
109
- console.log(chalk.yellow(' 开机自启(可选):'));
109
+ console.log(chalk.yellow('[STAR] 开机自启(可选):'));
110
110
  console.log(chalk.gray(' $ pm2 startup # 启用开机自启'));
111
111
  console.log(chalk.gray(' $ pm2 save # 保存配置'));
112
112
  console.log(chalk.gray(' $ pm2 unstartup # 禁用开机自启\n'));
@@ -190,7 +190,7 @@ async function main() {
190
190
  return;
191
191
  }
192
192
 
193
- console.log(chalk.red(`\n 未知 daemon 子命令: ${subCommand}\n`));
193
+ console.log(chalk.red(`\n[ERROR] 未知 daemon 子命令: ${subCommand}\n`));
194
194
  console.log(chalk.gray('支持的命令: start, stop, restart, status, logs\n'));
195
195
  return;
196
196
  }
@@ -275,7 +275,7 @@ async function main() {
275
275
  await proxyStatus(channel);
276
276
  break;
277
277
  default:
278
- console.log(chalk.red(`\n 未知操作: ${action}\n`));
278
+ console.log(chalk.red(`\n[ERROR] 未知操作: ${action}\n`));
279
279
  console.log(chalk.gray('支持的操作: start, stop, restart, status\n'));
280
280
  }
281
281
  return;
@@ -491,14 +491,14 @@ async function main() {
491
491
  name: 'action',
492
492
  message: chalk.cyan('选择插件操作:'),
493
493
  choices: [
494
- { name: '📋 列出已安装插件', value: 'list' },
495
- { name: '📦 安装插件', value: 'install' },
496
- { name: '🗑️ 卸载插件', value: 'remove' },
497
- { name: '🔄 启用/禁用插件', value: 'toggle' },
498
- { name: 'ℹ️ 查看插件信息', value: 'info' },
499
- { name: '⬆️ 更新插件', value: 'update' },
500
- { name: '⚙️ 配置插件', value: 'config' },
501
- { name: '◀️ 返回主菜单', value: 'back' }
494
+ { name: '[LOG] 列出已安装插件', value: 'list' },
495
+ { name: '[PKG] 安装插件', value: 'install' },
496
+ { name: '[DEL] 卸载插件', value: 'remove' },
497
+ { name: '[SYNC] 启用/禁用插件', value: 'toggle' },
498
+ { name: '[INFO] 查看插件信息', value: 'info' },
499
+ { name: '[UP] 更新插件', value: 'update' },
500
+ { name: '[CFG] 配置插件', value: 'config' },
501
+ { name: '[BACK] 返回主菜单', value: 'back' }
502
502
  ]
503
503
  }]);
504
504
 
@@ -558,8 +558,8 @@ async function main() {
558
558
  name: 'operation',
559
559
  message: '选择操作:',
560
560
  choices: [
561
- { name: ' 启用插件', value: 'enable' },
562
- { name: ' 禁用插件', value: 'disable' }
561
+ { name: '[OK] 启用插件', value: 'enable' },
562
+ { name: '[ERROR] 禁用插件', value: 'disable' }
563
563
  ]
564
564
  }]);
565
565
 
@@ -603,8 +603,8 @@ async function main() {
603
603
  name: 'option',
604
604
  message: '选择更新选项:',
605
605
  choices: [
606
- { name: '🔄 更新指定插件', value: 'single' },
607
- { name: '🔄 更新所有插件', value: 'all' }
606
+ { name: '[SYNC] 更新指定插件', value: 'single' },
607
+ { name: '[SYNC] 更新所有插件', value: 'all' }
608
608
  ]
609
609
  }]);
610
610
 
@@ -656,7 +656,7 @@ async function main() {
656
656
  }
657
657
 
658
658
  case 'exit':
659
- console.log('\n👋 再见!\n');
659
+ console.log('\n[BYE] 再见!\n');
660
660
  eventBus.emitSync('cli:shutdown', {});
661
661
  PluginManager.shutdownPlugins();
662
662
  process.exit(0);
@@ -214,7 +214,7 @@ async function installPlugin(gitUrl) {
214
214
  }
215
215
 
216
216
  // Step 2: Security warning and user confirmation
217
- console.warn('\n⚠️ WARNING: Plugins have full system access!');
217
+ console.warn('\n[WARN] WARNING: Plugins have full system access!');
218
218
  console.warn('Only install plugins from trusted sources.');
219
219
  console.warn(`Source: ${gitUrl}\n`);
220
220
 
@@ -15,7 +15,7 @@ async function resetConfig() {
15
15
  if (status.running) {
16
16
  console.log('检测到代理服务正在运行,正在停止...');
17
17
  await stopProxyServer();
18
- console.log(' 代理服务已停止');
18
+ console.log('[OK] 代理服务已停止');
19
19
  }
20
20
  } catch (err) {
21
21
  // 代理服务未运行或模块加载失败,继续处理本地文件
@@ -31,7 +31,7 @@ async function resetConfig() {
31
31
  const backupContent = fs.readFileSync(backupPath, 'utf8');
32
32
  fs.writeFileSync(settingsPath, backupContent, 'utf8');
33
33
  fs.unlinkSync(backupPath);
34
- console.log(' 已从备份恢复 settings.json');
34
+ console.log('[OK] 已从备份恢复 settings.json');
35
35
  } else if (fs.existsSync(settingsPath)) {
36
36
  // 检查是否是代理配置
37
37
  const settings = JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
@@ -59,28 +59,28 @@ async function resetConfig() {
59
59
  settings.apiKeyHelper = `echo '${activeChannel.apiKey}'`;
60
60
 
61
61
  fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2), 'utf8');
62
- console.log(`✅ 已恢复到渠道: ${activeChannel.name}`);
62
+ console.log(`[OK] 已恢复到渠道: ${activeChannel.name}`);
63
63
 
64
64
  // 清理 active-channel.json
65
65
  fs.unlinkSync(activeChannelPath);
66
66
  } else {
67
- console.log('⚠️ 无法找到激活的渠道,请手动配置 Claude Code');
67
+ console.log('[WARN] 无法找到激活的渠道,请手动配置 Claude Code');
68
68
  }
69
69
  }
70
70
  } else {
71
- console.log('⚠️ 未找到激活渠道信息,但已清除代理配置');
71
+ console.log('[WARN] 未找到激活渠道信息,但已清除代理配置');
72
72
  console.log('请手动配置 Claude Code 或通过 Web UI 管理渠道');
73
73
  }
74
74
  } else {
75
- console.log(' 配置文件正常,无需恢复');
75
+ console.log('[OK] 配置文件正常,无需恢复');
76
76
  }
77
77
  } else {
78
- console.log('⚠️ 未找到 settings.json 文件');
78
+ console.log('[WARN] 未找到 settings.json 文件');
79
79
  }
80
80
 
81
- console.log('\n 配置恢复完成!\n');
81
+ console.log('\n[OK] 配置恢复完成!\n');
82
82
  } catch (err) {
83
- console.error(' 恢复配置时出错:', err.message);
83
+ console.error('[ERROR] 恢复配置时出错:', err.message);
84
84
  console.log('\n您可以尝试手动恢复:');
85
85
  console.log('1. 检查 ~/.claude/settings.json 文件');
86
86
  console.log('2. 如果有 settings.json.cc-tool-backup 备份文件,手动恢复');
@@ -199,7 +199,7 @@ router.post('/:id/apply-to-settings', async (req, res) => {
199
199
  // (stopProxyServer restores backup, then we overwrite it with current channel)
200
200
  updateClaudeSettingsWithModelConfig(channel);
201
201
 
202
- console.log(`✅ 已停���动态切换,默认使用当前渠道`);
202
+ console.log(`[OK] 已停���动态切换,默认使用当前渠道`);
203
203
  broadcastLog({
204
204
  type: 'action',
205
205
  action: 'stop_proxy',
@@ -148,7 +148,7 @@ const feishuData = JSON.stringify({
148
148
  msg_type: 'interactive',
149
149
  card: {
150
150
  header: {
151
- title: { tag: 'plain_text', content: '🎉 Coding Tool - 任务完成' },
151
+ title: { tag: 'plain_text', content: '[DONE] Coding Tool - 任务完成' },
152
152
  template: 'green'
153
153
  },
154
154
  elements: [
@@ -491,7 +491,7 @@ router.post('/test', (req, res) => {
491
491
  msg_type: 'interactive',
492
492
  card: {
493
493
  header: {
494
- title: { tag: 'plain_text', content: '🧪 Coding Tool - 测试通知' },
494
+ title: { tag: 'plain_text', content: '[TEST] Coding Tool - 测试通知' },
495
495
  template: 'blue'
496
496
  },
497
497
  elements: [
@@ -58,7 +58,11 @@ router.get('/market', async (req, res) => {
58
58
  try {
59
59
  const { platform, service } = getPluginsService(req);
60
60
  const forceRefresh = req.query.refresh === '1';
61
+ if (forceRefresh) {
62
+ console.log(`[Plugins API] Refreshing market plugins for ${platform}...`);
63
+ }
61
64
  const plugins = await service.getMarketPlugins(forceRefresh);
65
+ console.log(`[Plugins API] ${platform}: ${plugins.length} market plugins loaded (refresh=${forceRefresh})`);
62
66
 
63
67
  res.json({
64
68
  success: true,
@@ -10,9 +10,9 @@ const execAsync = promisify(exec);
10
10
 
11
11
  function getExecOptions(timeout = 30000, runtimePlatform = process.platform) {
12
12
  if (runtimePlatform === 'win32') {
13
- return { timeout };
13
+ return { timeout, windowsHide: true };
14
14
  }
15
- return { shell: '/bin/bash', timeout };
15
+ return { shell: '/bin/bash', timeout, windowsHide: true };
16
16
  }
17
17
 
18
18
  /**
@@ -208,7 +208,7 @@ router.post('/start', async (req, res) => {
208
208
 
209
209
  // 3. 保存当前激活渠道ID(用于代理模式)
210
210
  saveActiveChannelId(currentChannel.id);
211
- console.log(`✅ Saved active channel: ${currentChannel.name} (${currentChannel.id})`);
211
+ console.log(`[OK] Saved active channel: ${currentChannel.name} (${currentChannel.id})`);
212
212
 
213
213
  // 4. 启动代理服务器
214
214
  const proxyResult = await startProxyServer();
@@ -256,11 +256,11 @@ router.post('/stop', async (req, res) => {
256
256
  if (restoredChannel) {
257
257
  if (hadBackup) {
258
258
  deleteBackup();
259
- console.log(' Discarded backup snapshot');
259
+ console.log('[OK] Discarded backup snapshot');
260
260
  }
261
261
  } else if (hadBackup) {
262
262
  restoreSettings();
263
- console.log(' Restored settings from backup');
263
+ console.log('[OK] Restored settings from backup');
264
264
  const channels = getAllChannels();
265
265
  const currentSettings = require('../services/channels').getCurrentSettings();
266
266
  if (currentSettings) {
@@ -274,7 +274,7 @@ router.post('/stop', async (req, res) => {
274
274
  if (restoredChannel) {
275
275
  const { applyChannelToSettings } = require('../services/channels');
276
276
  applyChannelToSettings(restoredChannel.id);
277
- console.log(`✅ Single-channel mode restored: ${restoredChannel.name}`);
277
+ console.log(`[OK] Single-channel mode restored: ${restoredChannel.name}`);
278
278
  }
279
279
 
280
280
  // 3. 删除备份文件和active-channel.json
@@ -282,14 +282,14 @@ router.post('/stop', async (req, res) => {
282
282
  const backupPath = NATIVE_PATHS.claude.settingsBackup;
283
283
  if (fs.existsSync(backupPath)) {
284
284
  fs.unlinkSync(backupPath);
285
- console.log(' Removed backup file');
285
+ console.log('[OK] Removed backup file');
286
286
  }
287
287
  }
288
288
 
289
289
  const activeChannelPath = PATHS.activeChannel.claude;
290
290
  if (fs.existsSync(activeChannelPath)) {
291
291
  fs.unlinkSync(activeChannelPath);
292
- console.log(' Removed active-channel.json');
292
+ console.log('[OK] Removed active-channel.json');
293
293
  }
294
294
 
295
295
  // 4. 通过 WebSocket 推送代理状态更新
@@ -50,7 +50,11 @@ router.get('/', async (req, res) => {
50
50
  try {
51
51
  const { platform, service } = getSkillService(req);
52
52
  const forceRefresh = req.query.refresh === '1';
53
+ if (forceRefresh) {
54
+ console.log(`[Skills API] Refreshing skills for ${platform}...`);
55
+ }
53
56
  const skills = await service.listSkills(forceRefresh);
57
+ console.log(`[Skills API] ${platform}: ${skills.length} skills loaded (refresh=${forceRefresh})`);
54
58
  res.json({
55
59
  success: true,
56
60
  platform,