coding-tool-x 3.6.7 → 3.6.8

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 (54) hide show
  1. package/dist/web/assets/{Analytics-CKycBI0G.js → Analytics-C57ZRDq5.js} +1 -1
  2. package/dist/web/assets/{ConfigTemplates-CACLQb8e.js → ConfigTemplates-B3qqqL05.js} +1 -1
  3. package/dist/web/assets/Home-CG5XrTNc.js +1 -0
  4. package/dist/web/assets/Home-CIua-b-o.css +1 -0
  5. package/dist/web/assets/{PluginManager-CQJl_uso.js → PluginManager-BhX0LUzr.js} +1 -1
  6. package/dist/web/assets/{ProjectList-DSkvQFEP.js → ProjectList-BQ01OZn9.js} +1 -1
  7. package/dist/web/assets/{SessionList-Czjs1GN1.js → SessionList-DPv2IOXG.js} +1 -1
  8. package/dist/web/assets/{SkillManager-Cg1xZ5Cv.js → SkillManager-D5CfQm2O.js} +1 -1
  9. package/dist/web/assets/{WorkspaceManager-COjYeKvN.js → WorkspaceManager-Ce8ggteK.js} +1 -1
  10. package/dist/web/assets/index-CpnFNWqC.js +2 -0
  11. package/dist/web/assets/index-DJ9VFidd.css +1 -0
  12. package/dist/web/assets/{naive-ui-DM897mIP.js → naive-ui-kcWDeJwl.js} +1 -1
  13. package/dist/web/index.html +3 -3
  14. package/package.json +1 -1
  15. package/src/commands/stats.js +1 -1
  16. package/src/config/channel-preset-websites.js +2 -1
  17. package/src/config/paths.js +8 -0
  18. package/src/server/api/agents.js +16 -54
  19. package/src/server/api/claude-hooks.js +1 -1
  20. package/src/server/api/claude-statistics.js +57 -0
  21. package/src/server/api/commands.js +16 -54
  22. package/src/server/api/dashboard.js +2 -2
  23. package/src/server/api/gemini-channels.js +2 -0
  24. package/src/server/api/hooks.js +4 -1
  25. package/src/server/api/plugins.js +40 -65
  26. package/src/server/api/skills.js +21 -77
  27. package/src/server/api/validation-errors.js +34 -0
  28. package/src/server/gemini-proxy-server.js +205 -21
  29. package/src/server/index.js +1 -0
  30. package/src/server/services/agents-service.js +166 -75
  31. package/src/server/services/base/base-channel-service.js +15 -0
  32. package/src/server/services/base/response-usage-parser.js +44 -0
  33. package/src/server/services/channel-balance.js +86 -1
  34. package/src/server/services/claude-statistics-service.js +139 -0
  35. package/src/server/services/commands-service.js +203 -121
  36. package/src/server/services/config-artifact-paths.js +116 -0
  37. package/src/server/services/config-export-service.js +7 -6
  38. package/src/server/services/config-registry-service.js +2 -2
  39. package/src/server/services/config-sync-manager.js +45 -11
  40. package/src/server/services/config-templates-service.js +21 -19
  41. package/src/server/services/format-converter.js +42 -4
  42. package/src/server/services/gemini-channels.js +30 -1
  43. package/src/server/services/gemini-sessions.js +347 -61
  44. package/src/server/services/mcp-client.js +236 -49
  45. package/src/server/services/mcp-service.js +51 -64
  46. package/src/server/services/notification-hooks.js +659 -88
  47. package/src/server/services/opencode-channels.js +15 -0
  48. package/src/server/services/plugins-service.js +771 -63
  49. package/src/server/services/repo-scanner-base.js +6 -29
  50. package/src/server/services/skill-service.js +187 -63
  51. package/dist/web/assets/Home-BeGkC4bb.css +0 -1
  52. package/dist/web/assets/Home-Bk6sP5Ed.js +0 -1
  53. package/dist/web/assets/index-0isNzXNY.css +0 -1
  54. package/dist/web/assets/index-fWgvlZQx.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>coding-tool-x · AI 编程工作台</title>
8
- <script type="module" crossorigin src="/assets/index-fWgvlZQx.js"></script>
8
+ <script type="module" crossorigin src="/assets/index-CpnFNWqC.js"></script>
9
9
  <link rel="modulepreload" crossorigin href="/assets/markdown-BNJfEgCA.js">
10
10
  <link rel="modulepreload" crossorigin href="/assets/vue-vendor-B5RqjEjQ.js">
11
- <link rel="modulepreload" crossorigin href="/assets/naive-ui-DM897mIP.js">
11
+ <link rel="modulepreload" crossorigin href="/assets/naive-ui-kcWDeJwl.js">
12
12
  <link rel="modulepreload" crossorigin href="/assets/icons-QFXzEgqM.js">
13
13
  <link rel="modulepreload" crossorigin href="/assets/vendors-DQA4Hw9v.js">
14
14
  <link rel="stylesheet" crossorigin href="/assets/markdown-BfC0goYb.css">
15
- <link rel="stylesheet" crossorigin href="/assets/index-0isNzXNY.css">
15
+ <link rel="stylesheet" crossorigin href="/assets/index-DJ9VFidd.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.6.7",
3
+ "version": "3.6.8",
4
4
  "description": "Vibe Coding 增强工作助手 - 智能会话管理、动态渠道切换、全局搜索、实时监控",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -4,7 +4,7 @@ const { loadConfig } = require('../config/loader');
4
4
 
5
5
  const TOOL_TYPES = ['claude', 'codex', 'gemini', 'opencode'];
6
6
  const TOOL_ENDPOINTS = {
7
- claude: '/api/statistics',
7
+ claude: '/api/claude/statistics',
8
8
  codex: '/api/codex/statistics',
9
9
  gemini: '/api/gemini/statistics',
10
10
  opencode: '/api/opencode/statistics'
@@ -13,7 +13,8 @@ const PRESET_WEBSITE_SOURCES = {
13
13
  { presetId: 'openai', baseUrl: 'https://api.openai.com/v1', websiteUrl: 'https://platform.openai.com' }
14
14
  ],
15
15
  gemini: [
16
- { presetId: 'google', baseUrl: 'https://generativelanguage.googleapis.com/v1beta', websiteUrl: 'https://ai.google.dev' }
16
+ { presetId: 'google', baseUrl: 'https://generativelanguage.googleapis.com/v1beta', websiteUrl: 'https://ai.google.dev' },
17
+ { presetId: 'vertex_ai_v1', baseUrl: 'https://LOCATION-aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/publishers/google', websiteUrl: 'https://cloud.google.com/vertex-ai/generative-ai/docs' }
17
18
  ],
18
19
  opencode: [
19
20
  { presetId: 'openrouter', baseUrl: 'https://openrouter.ai/api/v1', websiteUrl: 'https://openrouter.ai' },
@@ -473,10 +473,14 @@ const PATHS = {
473
473
  },
474
474
  pluginRepos: {
475
475
  claude: path.join(REPOS_PLUGINS_DIR, 'claude.json'),
476
+ codex: path.join(REPOS_PLUGINS_DIR, 'codex.json'),
477
+ gemini: path.join(REPOS_PLUGINS_DIR, 'gemini.json'),
476
478
  opencode: path.join(REPOS_PLUGINS_DIR, 'opencode.json')
477
479
  },
478
480
  pluginMarketCache: {
479
481
  claude: path.join(CACHE_PLUGINS_DIR, 'claude-market.json'),
482
+ codex: path.join(CACHE_PLUGINS_DIR, 'codex-market.json'),
483
+ gemini: path.join(CACHE_PLUGINS_DIR, 'gemini-market.json'),
480
484
  opencode: path.join(CACHE_PLUGINS_DIR, 'opencode-market.json')
481
485
  },
482
486
 
@@ -575,8 +579,12 @@ const LEGACY_STORAGE_RELOCATIONS = [
575
579
 
576
580
  // 插件仓库缓存
577
581
  { source: rootEntry('plugin-repos.json'), target: PATHS.pluginRepos.claude },
582
+ { source: rootEntry('codex-plugin-repos.json'), target: PATHS.pluginRepos.codex },
583
+ { source: rootEntry('gemini-plugin-repos.json'), target: PATHS.pluginRepos.gemini },
578
584
  { source: rootEntry('opencode-plugin-repos.json'), target: PATHS.pluginRepos.opencode },
579
585
  { source: rootEntry('plugins-market-cache.json'), target: PATHS.pluginMarketCache.claude },
586
+ { source: rootEntry('codex-plugins-market-cache.json'), target: PATHS.pluginMarketCache.codex },
587
+ { source: rootEntry('gemini-plugins-market-cache.json'), target: PATHS.pluginMarketCache.gemini },
580
588
  { source: rootEntry('opencode-plugins-market-cache.json'), target: PATHS.pluginMarketCache.opencode },
581
589
 
582
590
  // 已废弃但需要保留的数据
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Agents API 路由
3
3
  *
4
- * 管理 Claude Code 自定义代理
4
+ * 管理 Claude/Codex/Gemini/OpenCode 自定义代理
5
5
  */
6
6
 
7
7
  const express = require('express');
@@ -9,9 +9,10 @@ const fs = require('fs');
9
9
  const path = require('path');
10
10
  const { AgentsService } = require('../services/agents-service');
11
11
  const { PATHS, HOME_DIR } = require('../../config/paths');
12
+ const { sendApiError } = require('./validation-errors');
12
13
 
13
14
  const router = express.Router();
14
- const SUPPORTED_PLATFORMS = ['claude', 'codex', 'opencode'];
15
+ const SUPPORTED_PLATFORMS = ['claude', 'codex', 'gemini', 'opencode'];
15
16
  const agentServices = new Map();
16
17
  const DEFAULT_PROJECT_ALLOWED_ROOTS = [HOME_DIR, process.cwd()];
17
18
 
@@ -245,10 +246,7 @@ router.get('/', (req, res) => {
245
246
  });
246
247
  } catch (err) {
247
248
  console.error('[Agents API] List agents error:', err);
248
- res.status(500).json({
249
- success: false,
250
- message: err.message
251
- });
249
+ sendApiError(res, err);
252
250
  }
253
251
  });
254
252
 
@@ -276,10 +274,7 @@ router.get('/stats', (req, res) => {
276
274
  });
277
275
  } catch (err) {
278
276
  console.error('[Agents API] Get stats error:', err);
279
- res.status(500).json({
280
- success: false,
281
- message: err.message
282
- });
277
+ sendApiError(res, err);
283
278
  }
284
279
  });
285
280
 
@@ -333,10 +328,7 @@ router.get('/:scope/:fileName', (req, res) => {
333
328
  });
334
329
  } catch (err) {
335
330
  console.error('[Agents API] Get agent error:', err);
336
- res.status(500).json({
337
- success: false,
338
- message: err.message
339
- });
331
+ sendApiError(res, err);
340
332
  }
341
333
  });
342
334
 
@@ -419,10 +411,7 @@ router.post('/', (req, res) => {
419
411
  });
420
412
  } catch (err) {
421
413
  console.error('[Agents API] Create agent error:', err);
422
- res.status(500).json({
423
- success: false,
424
- message: err.message
425
- });
414
+ sendApiError(res, err);
426
415
  }
427
416
  });
428
417
 
@@ -496,10 +485,7 @@ router.put('/:scope/:fileName', (req, res) => {
496
485
  });
497
486
  } catch (err) {
498
487
  console.error('[Agents API] Update agent error:', err);
499
- res.status(500).json({
500
- success: false,
501
- message: err.message
502
- });
488
+ sendApiError(res, err);
503
489
  }
504
490
  });
505
491
 
@@ -546,10 +532,7 @@ router.delete('/:scope/:fileName', (req, res) => {
546
532
  });
547
533
  } catch (err) {
548
534
  console.error('[Agents API] Delete agent error:', err);
549
- res.status(500).json({
550
- success: false,
551
- message: err.message
552
- });
535
+ sendApiError(res, err);
553
536
  }
554
537
  });
555
538
 
@@ -581,10 +564,7 @@ router.get('/all', async (req, res) => {
581
564
  });
582
565
  } catch (err) {
583
566
  console.error('[Agents API] List all agents error:', err);
584
- res.status(500).json({
585
- success: false,
586
- message: err.message
587
- });
567
+ sendApiError(res, err);
588
568
  }
589
569
  });
590
570
 
@@ -609,10 +589,7 @@ router.get('/repos', (req, res) => {
609
589
  });
610
590
  } catch (err) {
611
591
  console.error('[Agents API] Get repos error:', err);
612
- res.status(500).json({
613
- success: false,
614
- message: err.message
615
- });
592
+ sendApiError(res, err);
616
593
  }
617
594
  });
618
595
 
@@ -648,10 +625,7 @@ router.post('/repos', (req, res) => {
648
625
  });
649
626
  } catch (err) {
650
627
  console.error('[Agents API] Add repo error:', err);
651
- res.status(500).json({
652
- success: false,
653
- message: err.message
654
- });
628
+ sendApiError(res, err);
655
629
  }
656
630
  });
657
631
 
@@ -680,10 +654,7 @@ router.delete('/repos/:owner/:name', (req, res) => {
680
654
  });
681
655
  } catch (err) {
682
656
  console.error('[Agents API] Remove repo error:', err);
683
- res.status(500).json({
684
- success: false,
685
- message: err.message
686
- });
657
+ sendApiError(res, err);
687
658
  }
688
659
  });
689
660
 
@@ -713,10 +684,7 @@ router.put('/repos/:owner/:name/toggle', (req, res) => {
713
684
  });
714
685
  } catch (err) {
715
686
  console.error('[Agents API] Toggle repo error:', err);
716
- res.status(500).json({
717
- success: false,
718
- message: err.message
719
- });
687
+ sendApiError(res, err);
720
688
  }
721
689
  });
722
690
 
@@ -768,10 +736,7 @@ router.post('/install', async (req, res) => {
768
736
  });
769
737
  } catch (err) {
770
738
  console.error('[Agents API] Install agent error:', err);
771
- res.status(500).json({
772
- success: false,
773
- message: err.message
774
- });
739
+ sendApiError(res, err);
775
740
  }
776
741
  });
777
742
 
@@ -815,10 +780,7 @@ router.post('/uninstall', (req, res) => {
815
780
  });
816
781
  } catch (err) {
817
782
  console.error('[Agents API] Uninstall agent error:', err);
818
- res.status(500).json({
819
- success: false,
820
- message: err.message
821
- });
783
+ sendApiError(res, err);
822
784
  }
823
785
  });
824
786
 
@@ -35,7 +35,7 @@ router.post('/test', async (req, res) => {
35
35
  await notificationHooks.testNotification(req.body || {});
36
36
  res.json({
37
37
  success: true,
38
- message: req.body?.testFeishu ? '飞书测试通知已发送' : '系统测试通知已发送'
38
+ message: '系统测试通知已发送'
39
39
  });
40
40
  } catch (error) {
41
41
  console.error('Error testing notification:', error);
@@ -0,0 +1,57 @@
1
+ const express = require('express');
2
+ const router = express.Router();
3
+ const {
4
+ getStatistics,
5
+ getDailyStatistics,
6
+ getTodayStatistics
7
+ } = require('../services/claude-statistics-service');
8
+
9
+ /**
10
+ * 获取 Claude Code 总体统计数据
11
+ * GET /api/claude/statistics/summary
12
+ */
13
+ router.get('/summary', (req, res) => {
14
+ try {
15
+ const stats = getStatistics();
16
+ res.json(stats);
17
+ } catch (error) {
18
+ console.error('[Claude] Failed to get statistics:', error);
19
+ res.status(500).json({ error: 'Failed to get statistics' });
20
+ }
21
+ });
22
+
23
+ /**
24
+ * 获取 Claude Code 今日统计数据
25
+ * GET /api/claude/statistics/today
26
+ */
27
+ router.get('/today', (req, res) => {
28
+ try {
29
+ const stats = getTodayStatistics();
30
+ res.json(stats);
31
+ } catch (error) {
32
+ console.error('[Claude] Failed to get today statistics:', error);
33
+ res.status(500).json({ error: 'Failed to get today statistics' });
34
+ }
35
+ });
36
+
37
+ /**
38
+ * 获取 Claude Code 指定日期的统计数据
39
+ * GET /api/claude/statistics/daily/:date
40
+ */
41
+ router.get('/daily/:date', (req, res) => {
42
+ try {
43
+ const { date } = req.params;
44
+
45
+ if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) {
46
+ return res.status(400).json({ error: 'Invalid date format. Expected YYYY-MM-DD' });
47
+ }
48
+
49
+ const stats = getDailyStatistics(date);
50
+ res.json(stats);
51
+ } catch (error) {
52
+ console.error('[Claude] Failed to get daily statistics:', error);
53
+ res.status(500).json({ error: 'Failed to get daily statistics' });
54
+ }
55
+ });
56
+
57
+ module.exports = router;
@@ -1,14 +1,15 @@
1
1
  /**
2
2
  * Commands API 路由
3
3
  *
4
- * 管理 Claude Code 自定义命令
4
+ * 管理 Claude/Codex/Gemini/OpenCode 自定义命令
5
5
  */
6
6
 
7
7
  const express = require('express');
8
8
  const { CommandsService } = require('../services/commands-service');
9
+ const { sendApiError } = require('./validation-errors');
9
10
 
10
11
  const router = express.Router();
11
- const SUPPORTED_PLATFORMS = ['claude', 'opencode'];
12
+ const SUPPORTED_PLATFORMS = ['claude', 'codex', 'gemini', 'opencode'];
12
13
  const commandServices = new Map();
13
14
 
14
15
  function resolvePlatform(rawPlatform) {
@@ -45,10 +46,7 @@ router.get('/', (req, res) => {
45
46
  });
46
47
  } catch (err) {
47
48
  console.error('[Commands API] List commands error:', err);
48
- res.status(500).json({
49
- success: false,
50
- message: err.message
51
- });
49
+ sendApiError(res, err);
52
50
  }
53
51
  });
54
52
 
@@ -69,10 +67,7 @@ router.get('/stats', (req, res) => {
69
67
  });
70
68
  } catch (err) {
71
69
  console.error('[Commands API] Get stats error:', err);
72
- res.status(500).json({
73
- success: false,
74
- message: err.message
75
- });
70
+ sendApiError(res, err);
76
71
  }
77
72
  });
78
73
 
@@ -117,10 +112,7 @@ router.get('/:scope/:name', (req, res) => {
117
112
  });
118
113
  } catch (err) {
119
114
  console.error('[Commands API] Get command error:', err);
120
- res.status(500).json({
121
- success: false,
122
- message: err.message
123
- });
115
+ sendApiError(res, err);
124
116
  }
125
117
  });
126
118
 
@@ -177,10 +169,7 @@ router.post('/', (req, res) => {
177
169
  });
178
170
  } catch (err) {
179
171
  console.error('[Commands API] Create command error:', err);
180
- res.status(500).json({
181
- success: false,
182
- message: err.message
183
- });
172
+ sendApiError(res, err);
184
173
  }
185
174
  });
186
175
 
@@ -230,10 +219,7 @@ router.put('/:scope/:name', (req, res) => {
230
219
  });
231
220
  } catch (err) {
232
221
  console.error('[Commands API] Update command error:', err);
233
- res.status(500).json({
234
- success: false,
235
- message: err.message
236
- });
222
+ sendApiError(res, err);
237
223
  }
238
224
  });
239
225
 
@@ -270,10 +256,7 @@ router.delete('/:scope/:name', (req, res) => {
270
256
  });
271
257
  } catch (err) {
272
258
  console.error('[Commands API] Delete command error:', err);
273
- res.status(500).json({
274
- success: false,
275
- message: err.message
276
- });
259
+ sendApiError(res, err);
277
260
  }
278
261
  });
279
262
 
@@ -298,10 +281,7 @@ router.get('/all', async (req, res) => {
298
281
  });
299
282
  } catch (err) {
300
283
  console.error('[Commands API] List all commands error:', err);
301
- res.status(500).json({
302
- success: false,
303
- message: err.message
304
- });
284
+ sendApiError(res, err);
305
285
  }
306
286
  });
307
287
 
@@ -320,10 +300,7 @@ router.get('/repos', (req, res) => {
320
300
  });
321
301
  } catch (err) {
322
302
  console.error('[Commands API] Get repos error:', err);
323
- res.status(500).json({
324
- success: false,
325
- message: err.message
326
- });
303
+ sendApiError(res, err);
327
304
  }
328
305
  });
329
306
 
@@ -353,10 +330,7 @@ router.post('/repos', (req, res) => {
353
330
  });
354
331
  } catch (err) {
355
332
  console.error('[Commands API] Add repo error:', err);
356
- res.status(500).json({
357
- success: false,
358
- message: err.message
359
- });
333
+ sendApiError(res, err);
360
334
  }
361
335
  });
362
336
 
@@ -379,10 +353,7 @@ router.delete('/repos/:owner/:name', (req, res) => {
379
353
  });
380
354
  } catch (err) {
381
355
  console.error('[Commands API] Remove repo error:', err);
382
- res.status(500).json({
383
- success: false,
384
- message: err.message
385
- });
356
+ sendApiError(res, err);
386
357
  }
387
358
  });
388
359
 
@@ -406,10 +377,7 @@ router.put('/repos/:owner/:name/toggle', (req, res) => {
406
377
  });
407
378
  } catch (err) {
408
379
  console.error('[Commands API] Toggle repo error:', err);
409
- res.status(500).json({
410
- success: false,
411
- message: err.message
412
- });
380
+ sendApiError(res, err);
413
381
  }
414
382
  });
415
383
 
@@ -439,10 +407,7 @@ router.post('/install', async (req, res) => {
439
407
  });
440
408
  } catch (err) {
441
409
  console.error('[Commands API] Install command error:', err);
442
- res.status(500).json({
443
- success: false,
444
- message: err.message
445
- });
410
+ sendApiError(res, err);
446
411
  }
447
412
  });
448
413
 
@@ -472,10 +437,7 @@ router.post('/uninstall', (req, res) => {
472
437
  });
473
438
  } catch (err) {
474
439
  console.error('[Commands API] Uninstall command error:', err);
475
- res.status(500).json({
476
- success: false,
477
- message: err.message
478
- });
440
+ sendApiError(res, err);
479
441
  }
480
442
  });
481
443
 
@@ -21,7 +21,7 @@ const { getChannels: getGeminiChannels } = require('../services/gemini-channels'
21
21
  const { getChannels: getOpenCodeChannels } = require('../services/opencode-channels');
22
22
 
23
23
  // Statistics
24
- const { getTodayStatistics } = require('../services/statistics-service');
24
+ const { getTodayStatistics: getClaudeTodayStatistics } = require('../services/claude-statistics-service');
25
25
  const { getTodayStatistics: getCodexTodayStatistics } = require('../services/codex-statistics-service');
26
26
  const { getTodayStatistics: getGeminiTodayStatistics } = require('../services/gemini-statistics-service');
27
27
  const { getTodayStatistics: getOpenCodeTodayStatistics } = require('../services/opencode-statistics-service');
@@ -74,7 +74,7 @@ router.get('/init', async (req, res) => {
74
74
  Promise.resolve(getOpenCodeProxyStatus()),
75
75
 
76
76
  // Today Stats (所有平台)
77
- Promise.resolve(getTodayStatistics()),
77
+ Promise.resolve(getClaudeTodayStatistics()),
78
78
  Promise.resolve(getCodexTodayStatistics()),
79
79
  Promise.resolve(getGeminiTodayStatistics()),
80
80
  Promise.resolve(getOpenCodeTodayStatistics()),
@@ -122,6 +122,7 @@ module.exports = (config) => {
122
122
  modelRedirects,
123
123
  speedTestModel,
124
124
  presetId,
125
+ apiFormat,
125
126
  gatewaySourceType,
126
127
  balanceToken,
127
128
  balanceUserId
@@ -143,6 +144,7 @@ module.exports = (config) => {
143
144
  modelRedirects: modelRedirects || [],
144
145
  speedTestModel: speedTestModel || null,
145
146
  presetId: presetId || null,
147
+ apiFormat: apiFormat || 'gemini_api',
146
148
  gatewaySourceType,
147
149
  balanceToken: balanceToken || '',
148
150
  balanceUserId: balanceUserId || null
@@ -32,9 +32,12 @@ router.post('/', (req, res) => {
32
32
  router.post('/test', async (req, res) => {
33
33
  try {
34
34
  await notificationHooks.testNotification(req.body || {});
35
+ const providerName = req.body?.provider?.name || req.body?.provider?.type;
35
36
  res.json({
36
37
  success: true,
37
- message: req.body?.testFeishu ? '飞书测试通知已发送' : '系统测试通知已发送'
38
+ message: providerName
39
+ ? `${providerName} 测试通知已发送`
40
+ : '系统测试通知已发送'
38
41
  });
39
42
  } catch (error) {
40
43
  console.error('Error testing notification hook settings:', error);