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
@@ -13,12 +13,12 @@ const chalk = require('chalk');
13
13
  const config = loadConfig();
14
14
  const port = config.ports?.webUI || 19999;
15
15
 
16
- console.log(chalk.cyan('\n🔧 开发模式:启动后端 API 服务器...\n'));
16
+ console.log(chalk.cyan('\n[FIX] 开发模式:启动后端 API 服务器...\n'));
17
17
 
18
18
  (async () => {
19
19
  await startServer(port);
20
20
 
21
- console.log(chalk.yellow('💡 开发提示:'));
21
+ console.log(chalk.yellow('[TIP] 开发提示:'));
22
22
  console.log(chalk.gray(` - 后端 API: http://localhost:${port}/api`));
23
23
  console.log(chalk.gray(' - 前端开发服务器: http://localhost:5000'));
24
24
  console.log(chalk.gray(' - 修改后端代码会自动重启 (nodemon)'));
@@ -36,7 +36,7 @@ function isInteractivePortConflictMode(options = {}) {
36
36
  }
37
37
 
38
38
  function printPortConflictHelp(port) {
39
- console.log(chalk.yellow('\n💡 解决方案:'));
39
+ console.log(chalk.yellow('\n[TIP] 解决方案:'));
40
40
  console.log(chalk.gray(' 1. 运行 ctx 命令,选择"配置端口"修改端口'));
41
41
  console.log(chalk.gray(` 2. 或手动关闭占用端口 ${port} 的程序\n`));
42
42
  }
@@ -47,7 +47,7 @@ function printPortToolIssue(issue = getPortToolIssue()) {
47
47
  return;
48
48
  }
49
49
 
50
- console.error(chalk.yellow(`\n💡 ${lines[0]}`));
50
+ console.error(chalk.yellow(`\n[TIP] ${lines[0]}`));
51
51
  lines.slice(1).forEach((line) => {
52
52
  console.error(chalk.gray(` ${line}`));
53
53
  });
@@ -64,7 +64,7 @@ async function startServer(port, host = '127.0.0.1', options = {}) {
64
64
  // 检查端口是否被占用
65
65
  const portInUse = await isPortInUse(port, host);
66
66
  if (portInUse) {
67
- console.log(chalk.yellow(`\n⚠️ 端口 ${port} 已被占用\n`));
67
+ console.log(chalk.yellow(`\n[WARN] 端口 ${port} 已被占用\n`));
68
68
 
69
69
  const interactiveMode = isInteractivePortConflictMode(options);
70
70
  let shouldKill = false;
@@ -87,7 +87,7 @@ async function startServer(port, host = '127.0.0.1', options = {}) {
87
87
  ]);
88
88
  shouldKill = answer.shouldKill;
89
89
  } else {
90
- console.error(chalk.red(' 当前为非交互模式,无法确认端口清理操作,已取消启动。'));
90
+ console.error(chalk.red('[ERROR] 当前为非交互模式,无法确认端口清理操作,已取消启动。'));
91
91
  printPortConflictHelp(port);
92
92
  process.exit(1);
93
93
  }
@@ -107,9 +107,9 @@ async function startServer(port, host = '127.0.0.1', options = {}) {
107
107
  if (toolIssue) {
108
108
  printPortToolIssue(toolIssue);
109
109
  } else {
110
- console.error(chalk.red('\n 无法关闭占用端口的进程'));
110
+ console.error(chalk.red('\n[ERROR] 无法关闭占用端口的进程'));
111
111
  }
112
- console.error(chalk.yellow('\n💡 请手动关闭占用端口的程序,或使用其他端口\n'));
112
+ console.error(chalk.yellow('\n[TIP] 请手动关闭占用端口的程序,或使用其他端口\n'));
113
113
  process.exit(1);
114
114
  }
115
115
 
@@ -118,12 +118,12 @@ async function startServer(port, host = '127.0.0.1', options = {}) {
118
118
  const released = await waitForPortRelease(port, 3000, host);
119
119
 
120
120
  if (!released) {
121
- console.error(chalk.red('\n 端口释放超时'));
122
- console.error(chalk.yellow('\n💡 请稍后重试,或手动检查端口占用情况\n'));
121
+ console.error(chalk.red('\n[ERROR] 端口释放超时'));
122
+ console.error(chalk.yellow('\n[TIP] 请稍后重试,或手动检查端口占用情况\n'));
123
123
  process.exit(1);
124
124
  }
125
125
 
126
- console.log(chalk.green(' 端口已释放\n'));
126
+ console.log(chalk.green('[v] 端口已释放\n'));
127
127
  }
128
128
 
129
129
  const app = express();
@@ -249,12 +249,12 @@ async function startServer(port, host = '127.0.0.1', options = {}) {
249
249
  const onError = (err) => {
250
250
  server.off('listening', onListening);
251
251
  if (err.code === 'EADDRINUSE') {
252
- console.error(chalk.red(`\n 端口 ${port} 已被占用`));
253
- console.error(chalk.yellow('\n💡 解决方案:'));
252
+ console.error(chalk.red(`\n[ERROR] 端口 ${port} 已被占用`));
253
+ console.error(chalk.yellow('\n[TIP] 解决方案:'));
254
254
  console.error(chalk.gray(' 1. 运行 ctx 命令,选择"配置端口"修改端口'));
255
255
  console.error(chalk.gray(` 2. 或关闭占用端口 ${port} 的程序\n`));
256
256
  } else {
257
- console.error(chalk.red(`\n 启动服务器失败: ${err.message}\n`));
257
+ console.error(chalk.red(`\n[ERROR] 启动服务器失败: ${err.message}\n`));
258
258
  }
259
259
  process.exit(1);
260
260
  };
@@ -263,9 +263,9 @@ async function startServer(port, host = '127.0.0.1', options = {}) {
263
263
  server.once('error', onError);
264
264
  });
265
265
 
266
- console.log(`\n🚀 Coding-Tool Web UI running at:`);
266
+ console.log(`\n[START] Coding-Tool Web UI running at:`);
267
267
  if (host === '0.0.0.0') {
268
- console.log(chalk.yellow(` ⚠️ 警告: 服务正在监听所有网络接口 (LAN 可访问)`));
268
+ console.log(chalk.yellow(` [WARN] 警告: 服务正在监听所有网络接口 (LAN 可访问)`));
269
269
  console.log(` http://localhost:${port}`);
270
270
  console.log(chalk.gray(` http://<your-ip>:${port} (LAN 访问)`));
271
271
  } else {
@@ -277,7 +277,7 @@ async function startServer(port, host = '127.0.0.1', options = {}) {
277
277
  console.log(` ws://localhost:${port}/ws\n`);
278
278
 
279
279
  if (host === '0.0.0.0' && !allowRemoteMutation) {
280
- console.log(chalk.yellow(' 🔒 已启用 LAN 安全保护:远程写操作默认禁用'));
280
+ console.log(chalk.yellow(' [LOCK] 已启用 LAN 安全保护:远程写操作默认禁用'));
281
281
  }
282
282
  // 自动恢复代理状态
283
283
  autoRestoreProxies();
@@ -296,26 +296,26 @@ function autoRestoreProxies() {
296
296
  // 检查 Claude 代理状态文件
297
297
  const claudeActiveFile = PATHS.activeChannel.claude;
298
298
  if (fs.existsSync(claudeActiveFile)) {
299
- console.log(chalk.cyan('\n🔄 检测到 Claude 代理状态文件,正在自动启动...'));
299
+ console.log(chalk.cyan('\n[SYNC] 检测到 Claude 代理状态文件,正在自动启动...'));
300
300
  const proxyPort = config.ports?.proxy || 20088;
301
301
  startProxyServer(proxyPort)
302
302
  .then(() => {
303
- console.log(chalk.green(`✅ Claude 代理已自动启动,端口: ${proxyPort}`));
303
+ console.log(chalk.green(`[OK] Claude 代理已自动启动,端口: ${proxyPort}`));
304
304
  })
305
305
  .catch((err) => {
306
- console.error(chalk.red(`❌ Claude 代理启动失败: ${err.message}`));
306
+ console.error(chalk.red(`[ERROR] Claude 代理启动失败: ${err.message}`));
307
307
  });
308
308
  }
309
309
 
310
310
  // 检查 Codex 代理状态文件
311
311
  const codexActiveFile = PATHS.activeChannel.codex;
312
312
  if (fs.existsSync(codexActiveFile)) {
313
- console.log(chalk.cyan('\n🔄 检测到 Codex 代理状态文件,正在自动启动...'));
313
+ console.log(chalk.cyan('\n[SYNC] 检测到 Codex 代理状态文件,正在自动启动...'));
314
314
  const codexProxyPort = config.ports?.codexProxy || 20089;
315
315
  startCodexProxyServer(codexProxyPort)
316
316
  .then((result) => {
317
317
  const port = result?.port || codexProxyPort;
318
- console.log(chalk.green(`✅ Codex 代理已自动启动,端口: ${port}`));
318
+ console.log(chalk.green(`[OK] Codex 代理已自动启动,端口: ${port}`));
319
319
 
320
320
  // 重启后重新写入 cc-proxy 配置与环境变量,避免缺少 provider/env 导致报错
321
321
  try {
@@ -324,43 +324,43 @@ function autoRestoreProxies() {
324
324
  console.log(chalk.gray(' 已同步 codex config.toml 与 CC_PROXY_KEY'));
325
325
  }
326
326
  } catch (err) {
327
- console.error(chalk.red(`❌ Codex 代理配置同步失败: ${err.message}`));
327
+ console.error(chalk.red(`[ERROR] Codex 代理配置同步失败: ${err.message}`));
328
328
  }
329
329
  })
330
330
  .catch((err) => {
331
- console.error(chalk.red(`❌ Codex 代理启动失败: ${err.message}`));
331
+ console.error(chalk.red(`[ERROR] Codex 代理启动失败: ${err.message}`));
332
332
  });
333
333
  }
334
334
 
335
335
  // 检查 Gemini 代理状态文件
336
336
  const geminiActiveFile = PATHS.activeChannel.gemini;
337
337
  if (fs.existsSync(geminiActiveFile)) {
338
- console.log(chalk.cyan('\n🔄 检测到 Gemini 代理状态文件,正在自动启动...'));
338
+ console.log(chalk.cyan('\n[SYNC] 检测到 Gemini 代理状态文件,正在自动启动...'));
339
339
  const geminiProxyPort = config.ports?.geminiProxy || 20090;
340
340
  startGeminiProxyServer(geminiProxyPort)
341
341
  .then((result) => {
342
342
  if (result.success) {
343
- console.log(chalk.green(`✅ Gemini 代理已自动启动,端口: ${result.port}`));
343
+ console.log(chalk.green(`[OK] Gemini 代理已自动启动,端口: ${result.port}`));
344
344
  } else {
345
- console.error(chalk.red(`❌ Gemini 代理启动失败: ${result.error || 'Unknown error'}`));
345
+ console.error(chalk.red(`[ERROR] Gemini 代理启动失败: ${result.error || 'Unknown error'}`));
346
346
  }
347
347
  })
348
348
  .catch((err) => {
349
- console.error(chalk.red(`❌ Gemini 代理启动失败: ${err.message}`));
349
+ console.error(chalk.red(`[ERROR] Gemini 代理启动失败: ${err.message}`));
350
350
  });
351
351
  } else {
352
- console.log(chalk.gray('\n💡 提示: 如需使用 Gemini 代理,请在前端界面激活 Gemini 渠道'));
352
+ console.log(chalk.gray('\n[TIP] 提示: 如需使用 Gemini 代理,请在前端界面激活 Gemini 渠道'));
353
353
  }
354
354
 
355
355
  // 检查 OpenCode 代理状态文件
356
356
  const opencodeActiveFile = PATHS.activeChannel.opencode;
357
357
  if (fs.existsSync(opencodeActiveFile)) {
358
- console.log(chalk.cyan('\n🔄 检测到 OpenCode 代理状态文件,正在自动启动...'));
358
+ console.log(chalk.cyan('\n[SYNC] 检测到 OpenCode 代理状态文件,正在自动启动...'));
359
359
  const opencodeProxyPort = config.ports?.opencodeProxy || 20091;
360
360
  startOpenCodeProxyServer(opencodeProxyPort)
361
361
  .then(async (result) => {
362
362
  if (result.success) {
363
- console.log(chalk.green(`✅ OpenCode 代理已自动启动,端口: ${result.port}`));
363
+ console.log(chalk.green(`[OK] OpenCode 代理已自动启动,端口: ${result.port}`));
364
364
  try {
365
365
  const { getEnabledChannels: getEnabledOpenCodeChannels } = require('./services/opencode-channels');
366
366
  const enabledChs = getEnabledOpenCodeChannels();
@@ -390,14 +390,14 @@ function autoRestoreProxies() {
390
390
  console.log(chalk.gray(' 已同步 OpenCode 配置文件'));
391
391
  }
392
392
  } catch (err) {
393
- console.error(chalk.red(`❌ OpenCode 代理配置同步失败: ${err.message}`));
393
+ console.error(chalk.red(`[ERROR] OpenCode 代理配置同步失败: ${err.message}`));
394
394
  }
395
395
  } else {
396
- console.error(chalk.red(`❌ OpenCode 代理启动失败: ${result.error || 'Unknown error'}`));
396
+ console.error(chalk.red(`[ERROR] OpenCode 代理启动失败: ${result.error || 'Unknown error'}`));
397
397
  }
398
398
  })
399
399
  .catch((err) => {
400
- console.error(chalk.red(`❌ OpenCode 代理启动失败: ${err.message}`));
400
+ console.error(chalk.red(`[ERROR] OpenCode 代理启动失败: ${err.message}`));
401
401
  });
402
402
  }
403
403
  }
@@ -408,7 +408,7 @@ async function performStartupHealthCheck() {
408
408
  const { getProjects } = require('./services/sessions');
409
409
 
410
410
  try {
411
- console.log(chalk.cyan('\n🔍 正在进行启动健康检查...'));
411
+ console.log(chalk.cyan('\n[SEARCH] 正在进行启动健康检查...'));
412
412
 
413
413
  // 获取所有项目
414
414
  const config = loadConfig();
@@ -423,20 +423,20 @@ async function performStartupHealthCheck() {
423
423
  const healthResult = healthCheckAllProjects(projects);
424
424
 
425
425
  if (healthResult.summary.created > 0) {
426
- console.log(chalk.green(` 已为 ${healthResult.summary.created} 个项目创建 .claude/sessions 目录`));
426
+ console.log(chalk.green(` [v] 已为 ${healthResult.summary.created} 个项目创建 .claude/sessions 目录`));
427
427
  }
428
428
 
429
429
  if (healthResult.summary.errors > 0) {
430
- console.log(chalk.yellow(` ${healthResult.summary.errors} 个项目检查失败`));
430
+ console.log(chalk.yellow(` [!] ${healthResult.summary.errors} 个项目检查失败`));
431
431
  }
432
432
 
433
433
  if (healthResult.summary.created === 0 && healthResult.summary.errors === 0) {
434
- console.log(chalk.green(` 所有 ${healthResult.summary.healthy} 个项目状态正常`));
434
+ console.log(chalk.green(` [v] 所有 ${healthResult.summary.healthy} 个项目状态正常`));
435
435
  }
436
436
 
437
437
  console.log('');
438
438
  } catch (err) {
439
- console.error(chalk.red(' 健康检查失败:'), err.message);
439
+ console.error(chalk.red(' [x] 健康检查失败:'), err.message);
440
440
  }
441
441
  }
442
442
 
@@ -544,7 +544,7 @@ async function startProxyServer(options = {}) {
544
544
 
545
545
  return new Promise((resolve, reject) => {
546
546
  proxyServer.listen(port, '127.0.0.1', () => {
547
- console.log(`✅ Proxy server started on http://127.0.0.1:${port}`);
547
+ console.log(`[OK] Proxy server started on http://127.0.0.1:${port}`);
548
548
  saveProxyStartTime('claude', preserveStartTime);
549
549
  eventBus.emitSync('proxy:start', { channel: 'claude', port });
550
550
  resolve({ success: true, port });
@@ -552,8 +552,8 @@ async function startProxyServer(options = {}) {
552
552
 
553
553
  proxyServer.on('error', (err) => {
554
554
  if (err.code === 'EADDRINUSE') {
555
- console.error(chalk.red(`\n 代理服务端口 ${port} 已被占用`));
556
- console.error(chalk.yellow('\n💡 解决方案:'));
555
+ console.error(chalk.red(`\n[ERROR] 代理服务端口 ${port} 已被占用`));
556
+ console.error(chalk.yellow('\n[TIP] 解决方案:'));
557
557
  console.error(chalk.gray(' 1. 运行 ctx 命令,选择"配置端口"修改端口'));
558
558
  console.error(chalk.gray(` 2. 或关闭占用端口 ${port} 的程序\n`));
559
559
  } else {
@@ -582,7 +582,7 @@ async function stopProxyServer(options = {}) {
582
582
 
583
583
  return new Promise((resolve) => {
584
584
  proxyServer.close(() => {
585
- console.log(' Proxy server stopped');
585
+ console.log('[OK] Proxy server stopped');
586
586
  if (clearStartTime) {
587
587
  clearProxyStartTime('claude');
588
588
  }
@@ -214,7 +214,7 @@ function buildExportReadme(exportData) {
214
214
  导出时间: ${exportedAt}
215
215
  版本: ${exportData.version || CONFIG_VERSION}
216
216
 
217
- ## 📦 包含内容
217
+ ## [PKG] 包含内容
218
218
  - 配置模板、频道配置、工作区、收藏
219
219
  - Agents / Skills / Commands
220
220
  - 插件 (Plugins)
@@ -1380,7 +1380,8 @@ async function testStdioServer(spec) {
1380
1380
  child = spawn(resolvedCommand, args, {
1381
1381
  env: mergedEnv,
1382
1382
  stdio: ['pipe', 'pipe', 'pipe'],
1383
- cwd
1383
+ cwd,
1384
+ windowsHide: true
1384
1385
  });
1385
1386
 
1386
1387
  child.stdout.on('data', (data) => {
@@ -890,12 +890,12 @@ async function probeModelAvailability(channel, channelType, options = {}) {
890
890
 
891
891
  if (isAvailable) {
892
892
  availableModels.push(model);
893
- console.log(`[ModelDetector] ${model} available`);
893
+ console.log(`[ModelDetector] [v] ${model} available`);
894
894
  if (stopOnFirstAvailable) {
895
895
  break;
896
896
  }
897
897
  } else {
898
- console.log(`[ModelDetector] ${model} not available${formatProbeFailureDetail(probeResult.failureDetail)}`);
898
+ console.log(`[ModelDetector] [x] ${model} not available${formatProbeFailureDetail(probeResult.failureDetail)}`);
899
899
  }
900
900
  }
901
901
 
@@ -4,6 +4,7 @@ function runCommand(command, args, options = {}) {
4
4
  const result = spawnSync(command, args, {
5
5
  encoding: 'utf8',
6
6
  maxBuffer: 10 * 1024 * 1024,
7
+ windowsHide: true,
7
8
  ...options
8
9
  });
9
10
 
@@ -18,32 +18,7 @@ const CLAUDE_MARKETPLACES_FILE = path.join(CLAUDE_PLUGINS_DIR, 'known_marketplac
18
18
  const OPENCODE_CONFIG_DIR = NATIVE_PATHS.opencode.config;
19
19
  const DEFAULT_REPOS_BY_PLATFORM = {
20
20
  claude: [],
21
- opencode: [
22
- {
23
- owner: 'Tommertom',
24
- name: 'opencode-plugin-marketplace',
25
- url: 'https://github.com/Tommertom/opencode-plugin-marketplace',
26
- branch: 'main',
27
- enabled: true,
28
- source: 'opencode-default'
29
- },
30
- {
31
- owner: 'avifenesh',
32
- name: 'awesome-slash',
33
- url: 'https://github.com/avifenesh/awesome-slash',
34
- branch: 'main',
35
- enabled: true,
36
- source: 'opencode-default'
37
- },
38
- {
39
- owner: 'NeoLabHQ',
40
- name: 'context-engineering-kit',
41
- url: 'https://github.com/NeoLabHQ/context-engineering-kit',
42
- branch: 'master',
43
- enabled: true,
44
- source: 'opencode-default'
45
- }
46
- ]
21
+ opencode: []
47
22
  };
48
23
 
49
24
  function cloneRepos(repos = []) {
@@ -1249,6 +1224,8 @@ class PluginsService {
1249
1224
  let repoFailureCount = 0;
1250
1225
 
1251
1226
  for (const repo of repos) {
1227
+ const repoLabel = repo.owner ? `${repo.owner}/${repo.name}` : repo.url;
1228
+ const pluginsBefore = marketPlugins.length;
1252
1229
  try {
1253
1230
  const branch = repo.branch || 'main';
1254
1231
 
@@ -1340,8 +1317,11 @@ class PluginsService {
1340
1317
  }
1341
1318
  } catch (err) {
1342
1319
  repoFailureCount++;
1343
- console.error(`[PluginsService] Failed to fetch plugins from ${repo.owner}/${repo.name}:`, err.message);
1320
+ console.error(`[PluginsService] Failed to fetch plugins from ${repoLabel}:`, err.message);
1321
+ continue;
1344
1322
  }
1323
+ const added = marketPlugins.length - pluginsBefore;
1324
+ console.log(`[PluginsService] ${repoLabel}: ${added} plugins loaded`);
1345
1325
  }
1346
1326
 
1347
1327
  const preparedPlugins = this.prepareMarketPlugins(marketPlugins);
@@ -57,7 +57,7 @@ function backupSettings() {
57
57
  const content = fs.readFileSync(getSettingsPath(), 'utf8');
58
58
  fs.writeFileSync(getBackupPath(), content, 'utf8');
59
59
 
60
- console.log(' Settings backed up to:', getBackupPath());
60
+ console.log('[OK] Settings backed up to:', getBackupPath());
61
61
  return { success: true, alreadyExists: false };
62
62
  } catch (err) {
63
63
  throw new Error('Failed to backup settings: ' + err.message);
@@ -77,7 +77,7 @@ function restoreSettings() {
77
77
  // 删除备份文件
78
78
  fs.unlinkSync(getBackupPath());
79
79
 
80
- console.log(' Settings restored from backup');
80
+ console.log('[OK] Settings restored from backup');
81
81
  return { success: true };
82
82
  } catch (err) {
83
83
  throw new Error('Failed to restore settings: ' + err.message);
@@ -118,7 +118,7 @@ function setProxyConfig(proxyPort) {
118
118
  // 写入
119
119
  writeSettings(settings);
120
120
 
121
- console.log(`✅ Settings updated to use proxy on port ${proxyPort}`);
121
+ console.log(`[OK] Settings updated to use proxy on port ${proxyPort}`);
122
122
  return { success: true, port: proxyPort };
123
123
  } catch (err) {
124
124
  throw new Error('Failed to set proxy config: ' + err.message);
@@ -153,18 +153,10 @@ function isRootSkillFile(filePath = '') {
153
153
  }
154
154
 
155
155
  const DEFAULT_REPOS_BY_PLATFORM = {
156
- claude: [
157
- { owner: 'anthropics', name: 'skills', branch: 'main', directory: '', enabled: true }
158
- ],
159
- codex: [
160
- { owner: 'openai', name: 'skills', branch: 'main', directory: 'skills/.curated', enabled: true }
161
- ],
162
- gemini: [
163
- { owner: 'google-gemini', name: 'gemini-cli', branch: 'main', directory: '.gemini/skills', enabled: true }
164
- ],
165
- opencode: [
166
- { owner: 'Shakudo-io', name: 'opencode-skills', branch: 'main', directory: '', enabled: true }
167
- ]
156
+ claude: [],
157
+ codex: [],
158
+ gemini: [],
159
+ opencode: []
168
160
  };
169
161
 
170
162
  const PLATFORM_CONFIG = {
@@ -291,7 +291,7 @@ function startWebSocketServer(httpServer, options = {}) {
291
291
  acc[source] = (acc[source] || 0) + 1;
292
292
  return acc;
293
293
  }, {});
294
- console.log(`📝 Loaded ${logsCache.length} persisted logs today ->`, counts);
294
+ console.log(`[NOTE] Loaded ${logsCache.length} persisted logs today ->`, counts);
295
295
 
296
296
  try {
297
297
  // 如果传入的是 HTTP server,则附加到该服务器;否则创建独立的 WebSocket 服务器
@@ -301,7 +301,7 @@ function startWebSocketServer(httpServer, options = {}) {
301
301
  path: '/ws' // 指定 WebSocket 路径
302
302
  });
303
303
  installOriginGuard(wss);
304
- console.log(`✅ WebSocket server attached to HTTP server at /ws`);
304
+ console.log(`[OK] WebSocket server attached to HTTP server at /ws`);
305
305
  } else {
306
306
  // 创建独立的 WebSocket 服务器,使用配置的 webUI 端口
307
307
  const config = loadConfig();
@@ -311,7 +311,7 @@ function startWebSocketServer(httpServer, options = {}) {
311
311
  path: '/ws'
312
312
  });
313
313
  installOriginGuard(wss);
314
- console.log(`✅ WebSocket server started on ws://127.0.0.1:${port}/ws`);
314
+ console.log(`[OK] WebSocket server started on ws://127.0.0.1:${port}/ws`);
315
315
  }
316
316
 
317
317
  wss.on('connection', (ws, req) => {
@@ -352,7 +352,7 @@ function startWebSocketServer(httpServer, options = {}) {
352
352
  wsClients.forEach(ws => {
353
353
  if (ws.isAlive === false) {
354
354
  // 客户端没有响应 pong,断开连接
355
- console.log(' WebSocket client timeout, terminating');
355
+ console.log('[ERROR] WebSocket client timeout, terminating');
356
356
  wsClients.delete(ws);
357
357
  return ws.terminate();
358
358
  }
@@ -369,8 +369,8 @@ function startWebSocketServer(httpServer, options = {}) {
369
369
  wss.on('error', (error) => {
370
370
  console.error('WebSocket server error:', error);
371
371
  if (error.code === 'EADDRINUSE') {
372
- console.error(chalk.red('\n WebSocket 端口已被占用'));
373
- console.error(chalk.yellow('\n💡 请检查端口配置\n'));
372
+ console.error(chalk.red('\n[ERROR] WebSocket 端口已被占用'));
373
+ console.error(chalk.yellow('\n[TIP] 请检查端口配置\n'));
374
374
  wss = null;
375
375
  }
376
376
  });
@@ -400,7 +400,7 @@ function stopWebSocketServer() {
400
400
 
401
401
  // 关闭服务器
402
402
  wss.close(() => {
403
- console.log(' WebSocket server stopped');
403
+ console.log('[OK] WebSocket server stopped');
404
404
  });
405
405
 
406
406
  wss = null;
@@ -443,7 +443,7 @@ function broadcastLog(logData) {
443
443
  function clearAllLogs() {
444
444
  logsCache = [];
445
445
  saveLogsToFile([]);
446
- console.log(' All logs cleared');
446
+ console.log('[OK] All logs cleared');
447
447
  }
448
448
 
449
449
  // 去掉敏感字段
package/src/ui/menu.js CHANGED
@@ -50,9 +50,9 @@ function getChannelAndProxyStatus(cliType) {
50
50
  * 显示主菜单
51
51
  */
52
52
  async function showMainMenu(config) {
53
- console.log(chalk.bold.cyan('\n╔═══════════════════════════════════════════════╗'));
53
+ console.log(chalk.bold.cyan('\n╔===============================================╗'));
54
54
  console.log(chalk.bold.cyan(`║ Claude Code 会话管理工具 v${packageInfo.version} ║`));
55
- console.log(chalk.bold.cyan('╚═══════════════════════════════════════════════╝\n'));
55
+ console.log(chalk.bold.cyan('╚===============================================╝\n'));
56
56
 
57
57
  // 显示当前CLI类型
58
58
  const cliTypes = {
package/src/ui/prompts.js CHANGED
@@ -31,15 +31,15 @@ async function promptForkConfirm() {
31
31
  default: 'continue',
32
32
  choices: [
33
33
  {
34
- name: chalk.green('📝 继续原会话 (推荐) - 在原会话上继续对话,所有内容会追加到原文件'),
34
+ name: chalk.green('[NOTE] 继续原会话 (推荐) - 在原会话上继续对话,所有内容会追加到原文件'),
35
35
  value: 'continue',
36
36
  },
37
37
  {
38
- name: chalk.yellow('🌿 创建新分支 (Fork) - 基于原会话创建新会话,保留原会话不变'),
38
+ name: chalk.yellow('[FORK] 创建新分支 (Fork) - 基于原会话创建新会话,保留原会话不变'),
39
39
  value: 'fork',
40
40
  },
41
41
  new inquirer.Separator(chalk.gray('─'.repeat(14))),
42
- { name: chalk.blue('↩️ 返回重新选择'), value: 'back' },
42
+ { name: chalk.blue('[<-] 返回重新选择'), value: 'back' },
43
43
  ],
44
44
  },
45
45
  ]);
@@ -55,7 +55,7 @@ async function promptSearchKeyword() {
55
55
  {
56
56
  type: 'input',
57
57
  name: 'keyword',
58
- message: chalk.cyan('🔎 输入搜索关键词:'),
58
+ message: chalk.cyan('[SEARCH] 输入搜索关键词:'),
59
59
  validate: (input) => {
60
60
  if (!input.trim()) {
61
61
  return '请输入搜索关键词';
@@ -76,7 +76,7 @@ async function promptSelectProject(projects) {
76
76
  const choices = [
77
77
  ...projects,
78
78
  new inquirer.Separator(chalk.gray('─'.repeat(14))),
79
- { name: chalk.gray('↩️ 取消切换'), value: null }
79
+ { name: chalk.gray('[<-] 取消切换'), value: null }
80
80
  ];
81
81
 
82
82
  const { project } = await inquirer.prompt([