coding-tool-x 3.4.12 → 3.5.0

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "coding-tool-x",
3
- "version": "3.4.12",
3
+ "version": "3.5.0",
4
4
  "description": "Vibe Coding 增强工作助手 - 智能会话管理、动态渠道切换、全局搜索、实时监控",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -205,6 +205,7 @@ async function startServer(port, host = '127.0.0.1', options = {}) {
205
205
 
206
206
  // 初始化 Claude hooks 默认配置(自动开启任务完成通知)
207
207
  notificationHooks.initDefaultHooks();
208
+ notificationHooks.syncManagedNotificationAssets();
208
209
 
209
210
  // Claude Code 专有功能 API
210
211
  app.use('/api/commands', require('./api/commands'));
@@ -3,7 +3,7 @@ const path = require('path');
3
3
  const os = require('os');
4
4
  const http = require('http');
5
5
  const https = require('https');
6
- const { execSync } = require('child_process');
6
+ const { execSync, execFileSync } = require('child_process');
7
7
  const { PATHS, NATIVE_PATHS } = require('../../config/paths');
8
8
  const { loadUIConfig, saveUIConfig } = require('./ui-config');
9
9
  const codexSettingsManager = require('./codex-settings-manager');
@@ -422,7 +422,15 @@ function buildWindowsPopupCommand(title, message) {
422
422
  '[void]$form.ShowDialog()',
423
423
  '}'
424
424
  ].join('; ');
425
- return `powershell -NoProfile -STA -Command ${JSON.stringify(script)}`;
425
+ return script;
426
+ }
427
+
428
+ function runWindowsPowerShellCommand(command) {
429
+ // Invoke PowerShell directly so the styled popup script doesn't hit cmd.exe's 8191-char limit.
430
+ execFileSync('powershell', ['-NoProfile', '-STA', '-Command', command], {
431
+ stdio: 'ignore',
432
+ windowsHide: true
433
+ });
426
434
  }
427
435
 
428
436
  function generateNotifyScript(feishu = {}) {
@@ -434,7 +442,7 @@ const fs = require('fs')
434
442
  const os = require('os')
435
443
  const http = require('http')
436
444
  const https = require('https')
437
- const { execSync } = require('child_process')
445
+ const { execSync, execFileSync } = require('child_process')
438
446
 
439
447
  const FEISHU_ENABLED = ${feishuEnabled ? 'true' : 'false'}
440
448
  const FEISHU_WEBHOOK_URL = ${JSON.stringify(feishuEnabled ? feishu.webhookUrl : '')}
@@ -529,10 +537,13 @@ function notify(mode, message) {
529
537
  const ps = "Add-Type -AssemblyName PresentationFramework; [System.Windows.MessageBox]::Show('" +
530
538
  escapeForPowerShellSingleQuote(message) + "', '" +
531
539
  escapeForPowerShellSingleQuote(title) + "', 'OK', 'Information')"
532
- const command = 'powershell -NoProfile -STA -Command ' + JSON.stringify(ps) + ' || ' + popupCommand
533
- execSync(command, { stdio: 'ignore', windowsHide: true })
540
+ try {
541
+ runWindowsPowerShellCommand(ps)
542
+ } catch (dialogError) {
543
+ runWindowsPowerShellCommand(popupCommand)
544
+ }
534
545
  } else {
535
- execSync(popupCommand, { stdio: 'ignore', windowsHide: true })
546
+ runWindowsPowerShellCommand(popupCommand)
536
547
  }
537
548
  return
538
549
  }
@@ -832,7 +843,15 @@ function buildWindowsPopupCommand(title, message) {
832
843
  '[void]$form.ShowDialog()',
833
844
  '}'
834
845
  ].join('; ')
835
- return 'powershell -NoProfile -STA -Command ' + JSON.stringify(script)
846
+ return script
847
+ }
848
+
849
+ function runWindowsPowerShellCommand(command) {
850
+ // Invoke PowerShell directly so the styled popup script doesn't hit cmd.exe's 8191-char limit.
851
+ execFileSync('powershell', ['-NoProfile', '-STA', '-Command', command], {
852
+ stdio: 'ignore',
853
+ windowsHide: true
854
+ })
836
855
  }
837
856
  `;
838
857
  }
@@ -1476,12 +1495,78 @@ function generateSystemNotificationCommand(type, message, platformOverride = os.
1476
1495
  return `notify-send "Coding Tool" "${String(message || '').replace(/"/g, '\\"')}"`;
1477
1496
  }
1478
1497
 
1498
+ function runSystemNotification(type, message, platformOverride = os.platform()) {
1499
+ const normalizedType = normalizeType(type);
1500
+ const title = 'Coding Tool';
1501
+ const platform = platformOverride;
1502
+
1503
+ if (platform === 'darwin') {
1504
+ if (normalizedType === 'dialog') {
1505
+ const appleScript = 'display dialog "' + escapeForAppleScript(message) +
1506
+ '" with title "' + escapeForAppleScript(title) +
1507
+ '" buttons {"好的"} default button 1 with icon note';
1508
+ execSync('osascript -e ' + JSON.stringify(appleScript), { stdio: 'ignore', windowsHide: true });
1509
+ } else {
1510
+ const fallbackScript = 'display notification "' + escapeForAppleScript(message) +
1511
+ '" with title "' + escapeForAppleScript(title) + '" sound name "Glass"';
1512
+ const command = 'if command -v terminal-notifier >/dev/null 2>&1; then ' +
1513
+ 'terminal-notifier -title ' + JSON.stringify(title) +
1514
+ ' -message ' + JSON.stringify(message) +
1515
+ ' -sound Glass -activate com.apple.Terminal; ' +
1516
+ 'else osascript -e ' + JSON.stringify(fallbackScript) + '; fi';
1517
+ execSync(command, { stdio: 'ignore', windowsHide: true });
1518
+ }
1519
+ return;
1520
+ }
1521
+
1522
+ if (platform === 'win32') {
1523
+ const popupCommand = buildWindowsPopupCommand(title, message);
1524
+ if (normalizedType === 'dialog') {
1525
+ const dialogScript = "Add-Type -AssemblyName PresentationFramework; [System.Windows.MessageBox]::Show('" +
1526
+ escapeForPowerShellSingleQuote(message) + "', '" +
1527
+ escapeForPowerShellSingleQuote(title) + "', 'OK', 'Information')";
1528
+ try {
1529
+ runWindowsPowerShellCommand(dialogScript);
1530
+ } catch (dialogError) {
1531
+ runWindowsPowerShellCommand(popupCommand);
1532
+ }
1533
+ } else {
1534
+ runWindowsPowerShellCommand(popupCommand);
1535
+ }
1536
+ return;
1537
+ }
1538
+
1539
+ const escapedMessage = String(message || '').replace(/"/g, '\\"');
1540
+ if (normalizedType === 'dialog') {
1541
+ execSync(
1542
+ `zenity --info --title="Coding Tool" --text="${escapedMessage}" 2>/dev/null || notify-send "Coding Tool" "${escapedMessage}"`,
1543
+ { stdio: 'ignore', windowsHide: true }
1544
+ );
1545
+ return;
1546
+ }
1547
+
1548
+ execSync(`notify-send "Coding Tool" "${escapedMessage}"`, { stdio: 'ignore', windowsHide: true });
1549
+ }
1550
+
1551
+ function syncManagedNotificationAssets() {
1552
+ const settings = getNotificationSettings();
1553
+ const hasManagedPlatform = Object.values(settings?.platforms || {}).some((platform) => platform?.enabled === true);
1554
+
1555
+ if (hasManagedPlatform) {
1556
+ writeNotifyScript(settings.feishu || {});
1557
+ } else {
1558
+ removeNotifyScript();
1559
+ }
1560
+
1561
+ return settings;
1562
+ }
1563
+
1479
1564
  function testNotification({ type, testFeishu, webhookUrl } = {}) {
1480
1565
  if (testFeishu && webhookUrl) {
1481
1566
  return sendFeishuTest(webhookUrl);
1482
1567
  }
1483
1568
 
1484
- execSync(generateSystemNotificationCommand(type || 'notification', '这是一条测试通知'), { stdio: 'ignore', windowsHide: true });
1569
+ runSystemNotification(type || 'notification', '这是一条测试通知');
1485
1570
  }
1486
1571
 
1487
1572
  module.exports = {
@@ -1492,6 +1577,7 @@ module.exports = {
1492
1577
  saveLegacyClaudeHookSettings,
1493
1578
  testNotification,
1494
1579
  initDefaultHooks,
1580
+ syncManagedNotificationAssets,
1495
1581
  getOpenCodeManagedPluginPath,
1496
1582
  buildOpenCodePluginContent,
1497
1583
  buildCodexNotifyCommand,