agent-tower 0.5.2-beta.0 → 0.5.2-beta.2

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 (136) hide show
  1. package/dist/mcp/http-client.d.ts +12 -3
  2. package/dist/mcp/http-client.d.ts.map +1 -1
  3. package/dist/mcp/http-client.js +6 -6
  4. package/dist/mcp/http-client.js.map +1 -1
  5. package/dist/mcp/server.d.ts.map +1 -1
  6. package/dist/mcp/server.js +48 -5
  7. package/dist/mcp/server.js.map +1 -1
  8. package/dist/mcp/tools/workspaces.d.ts.map +1 -1
  9. package/dist/mcp/tools/workspaces.js +4 -1
  10. package/dist/mcp/tools/workspaces.js.map +1 -1
  11. package/dist/mcp/types.d.ts +3 -0
  12. package/dist/mcp/types.d.ts.map +1 -1
  13. package/dist/mcp/types.js +2 -0
  14. package/dist/mcp/types.js.map +1 -1
  15. package/dist/routes/git.d.ts.map +1 -1
  16. package/dist/routes/git.js +6 -1
  17. package/dist/routes/git.js.map +1 -1
  18. package/dist/routes/system.d.ts.map +1 -1
  19. package/dist/routes/system.js +21 -5
  20. package/dist/routes/system.js.map +1 -1
  21. package/dist/routes/team-runs.d.ts.map +1 -1
  22. package/dist/routes/team-runs.js +92 -2
  23. package/dist/routes/team-runs.js.map +1 -1
  24. package/dist/routes/workspaces.d.ts.map +1 -1
  25. package/dist/routes/workspaces.js +11 -4
  26. package/dist/routes/workspaces.js.map +1 -1
  27. package/dist/services/__tests__/task.service.test.js +65 -1
  28. package/dist/services/__tests__/task.service.test.js.map +1 -1
  29. package/dist/services/__tests__/team-reconciler.service.test.js +171 -3
  30. package/dist/services/__tests__/team-reconciler.service.test.js.map +1 -1
  31. package/dist/services/__tests__/team-run.service.test.js +87 -0
  32. package/dist/services/__tests__/team-run.service.test.js.map +1 -1
  33. package/dist/services/__tests__/team-scheduler.service.test.js +131 -0
  34. package/dist/services/__tests__/team-scheduler.service.test.js.map +1 -1
  35. package/dist/services/__tests__/workspace.service.test.js +55 -0
  36. package/dist/services/__tests__/workspace.service.test.js.map +1 -1
  37. package/dist/services/commit-message.service.d.ts.map +1 -1
  38. package/dist/services/commit-message.service.js +3 -0
  39. package/dist/services/commit-message.service.js.map +1 -1
  40. package/dist/services/project.service.d.ts.map +1 -1
  41. package/dist/services/project.service.js +3 -2
  42. package/dist/services/project.service.js.map +1 -1
  43. package/dist/services/session-manager.d.ts +8 -0
  44. package/dist/services/session-manager.d.ts.map +1 -1
  45. package/dist/services/session-manager.js +20 -6
  46. package/dist/services/session-manager.js.map +1 -1
  47. package/dist/services/task-cleanup.service.d.ts +2 -0
  48. package/dist/services/task-cleanup.service.d.ts.map +1 -1
  49. package/dist/services/task-cleanup.service.js +8 -1
  50. package/dist/services/task-cleanup.service.js.map +1 -1
  51. package/dist/services/task.service.d.ts +4 -0
  52. package/dist/services/task.service.d.ts.map +1 -1
  53. package/dist/services/task.service.js +3 -0
  54. package/dist/services/task.service.js.map +1 -1
  55. package/dist/services/team-run.service.d.ts +16 -0
  56. package/dist/services/team-run.service.d.ts.map +1 -1
  57. package/dist/services/team-run.service.js +196 -4
  58. package/dist/services/team-run.service.js.map +1 -1
  59. package/dist/services/team-scheduler.service.d.ts +8 -4
  60. package/dist/services/team-scheduler.service.d.ts.map +1 -1
  61. package/dist/services/team-scheduler.service.js +26 -9
  62. package/dist/services/team-scheduler.service.js.map +1 -1
  63. package/dist/services/workspace-kind.d.ts +13 -0
  64. package/dist/services/workspace-kind.d.ts.map +1 -0
  65. package/dist/services/workspace-kind.js +16 -0
  66. package/dist/services/workspace-kind.js.map +1 -0
  67. package/dist/services/workspace.service.d.ts +18 -0
  68. package/dist/services/workspace.service.d.ts.map +1 -1
  69. package/dist/services/workspace.service.js +104 -12
  70. package/dist/services/workspace.service.js.map +1 -1
  71. package/dist/types/index.d.ts +4 -0
  72. package/dist/types/index.d.ts.map +1 -1
  73. package/dist/types/index.js +6 -0
  74. package/dist/types/index.js.map +1 -1
  75. package/dist/utils/process-launch.d.ts.map +1 -1
  76. package/dist/utils/process-launch.js +52 -9
  77. package/dist/utils/process-launch.js.map +1 -1
  78. package/dist/utils/process-launch.test.js +65 -1
  79. package/dist/utils/process-launch.test.js.map +1 -1
  80. package/dist/web/assets/{AgentDemoPage-CWcu7-P7.js → AgentDemoPage-Co63rtls.js} +1 -1
  81. package/dist/web/assets/{DemoPage-6hMli_sP.js → DemoPage-PD8AX5pI.js} +1 -1
  82. package/dist/web/assets/{GeneralSettingsPage-DUaFSgCY.js → GeneralSettingsPage-C5eiEeTZ.js} +1 -1
  83. package/dist/web/assets/{MemberAvatar-S-eJAdWH.js → MemberAvatar-BDXmryjB.js} +1 -1
  84. package/dist/web/assets/{NotificationSettingsPage-Cl5x8F4G.js → NotificationSettingsPage-BjjPan2M.js} +1 -1
  85. package/dist/web/assets/{ProfileSettingsPage-QFN9385l.js → ProfileSettingsPage-BRpeNq6u.js} +1 -1
  86. package/dist/web/assets/ProjectKanbanPage-DUUu2EYy.js +89 -0
  87. package/dist/web/assets/{ProjectSettingsPage-Do3Q1_r4.js → ProjectSettingsPage-avctMKfk.js} +1 -1
  88. package/dist/web/assets/{ProviderSettingsPage-DYOb33XQ.js → ProviderSettingsPage-BIUYN2e0.js} +14 -14
  89. package/dist/web/assets/{SettingsSection-D0Zzbbhp.js → SettingsSection-pLJ3msrT.js} +1 -1
  90. package/dist/web/assets/{TeamSettingsPage-Dq_DU1S8.js → TeamSettingsPage-BjKW9nT8.js} +1 -1
  91. package/dist/web/assets/{arrow-left-D0xGRsQG.js → arrow-left-lFz8nyZM.js} +1 -1
  92. package/dist/web/assets/{button-C-IDw2d8.js → button-BUA8P726.js} +1 -1
  93. package/dist/web/assets/check-BYuuXc71.js +1 -0
  94. package/dist/web/assets/{chevron-down-C735lPj9.js → chevron-down-B931AgE2.js} +1 -1
  95. package/dist/web/assets/{chevron-right-DfFiWY3R.js → chevron-right-F9i4wey6.js} +1 -1
  96. package/dist/web/assets/{chevron-up-DqGc0SsZ.js → chevron-up-BEHjZ-SB.js} +1 -1
  97. package/dist/web/assets/{circle-check-CSlvn06a.js → circle-check-C7xXtl8B.js} +1 -1
  98. package/dist/web/assets/{code-block-OCS4YCEC-BRT1Nrpy.js → code-block-OCS4YCEC-6FHTyCN2.js} +1 -1
  99. package/dist/web/assets/{confirm-dialog-BtsxywSG.js → confirm-dialog-B_wk_zqm.js} +1 -1
  100. package/dist/web/assets/{folder-picker-BuvfyaHB.js → folder-picker-BEHS3b2Q.js} +1 -1
  101. package/dist/web/assets/index-DEQhT5sD.css +1 -0
  102. package/dist/web/assets/{index-BAz6UxmL.js → index-RxbHMWXV.js} +7 -7
  103. package/dist/web/assets/{loader-circle-BLO3w-ze.js → loader-circle-stJcjnm-.js} +1 -1
  104. package/dist/web/assets/log-adapter-CtvxzS4j.js +1 -0
  105. package/dist/web/assets/{mermaid-NOHMQCX5-BLfGHrOE.js → mermaid-NOHMQCX5-fubZbKyF.js} +3 -3
  106. package/dist/web/assets/{message-square-CIyucdyo.js → message-square-C8lb-TDo.js} +1 -1
  107. package/dist/web/assets/modal-UGrjU63G.js +1 -0
  108. package/dist/web/assets/{pencil-CdJXJig-.js → pencil-uRBgB4qA.js} +1 -1
  109. package/dist/web/assets/{rotate-ccw-B42Jf1RW.js → rotate-ccw-CWaMrTz4.js} +1 -1
  110. package/dist/web/assets/{select-kVmZCXo9.js → select-BMlH2AuL.js} +1 -1
  111. package/dist/web/assets/upload-B-Mpvu9j.js +1 -0
  112. package/dist/web/assets/{use-profiles-Bvj_EW-7.js → use-profiles-D6cZwU1R.js} +1 -1
  113. package/dist/web/assets/{use-providers-CcFzAUyf.js → use-providers-DVP6emIi.js} +1 -1
  114. package/dist/web/index.html +2 -2
  115. package/node_modules/@agent-tower/shared/dist/socket/events.d.ts +1 -1
  116. package/node_modules/@agent-tower/shared/dist/socket/events.d.ts.map +1 -1
  117. package/node_modules/@agent-tower/shared/dist/types.d.ts +14 -1
  118. package/node_modules/@agent-tower/shared/dist/types.d.ts.map +1 -1
  119. package/node_modules/@agent-tower/shared/dist/types.js +6 -0
  120. package/node_modules/@agent-tower/shared/dist/types.js.map +1 -1
  121. package/node_modules/@prisma/client/.prisma/client/edge.js +8 -5
  122. package/node_modules/@prisma/client/.prisma/client/index-browser.js +3 -0
  123. package/node_modules/@prisma/client/.prisma/client/index.d.ts +161 -0
  124. package/node_modules/@prisma/client/.prisma/client/index.js +8 -5
  125. package/node_modules/@prisma/client/.prisma/client/package.json +1 -1
  126. package/node_modules/@prisma/client/.prisma/client/schema.prisma +8 -1
  127. package/node_modules/@prisma/client/.prisma/client/wasm.js +3 -0
  128. package/package.json +1 -1
  129. package/prisma/migrations/20260609000000_add_team_member_membership_status/migration.sql +3 -0
  130. package/prisma/migrations/20260609000000_add_workspace_kind_working_dir/migration.sql +7 -0
  131. package/prisma/schema.prisma +8 -1
  132. package/dist/web/assets/ProjectKanbanPage-Dye8K5K1.js +0 -89
  133. package/dist/web/assets/check-KjbNKANU.js +0 -1
  134. package/dist/web/assets/index-r8en4dlI.css +0 -1
  135. package/dist/web/assets/log-adapter-i7kNXXup.js +0 -1
  136. package/dist/web/assets/modal-D_VShm6D.js +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,OAAO;AACP,MAAM,CAAN,IAAY,UAMX;AAND,WAAY,UAAU;IACpB,2BAAa,CAAA;IACb,yCAA2B,CAAA;IAC3B,qCAAuB,CAAA;IACvB,2BAAa,CAAA;IACb,qCAAuB,CAAA;AACzB,CAAC,EANW,UAAU,KAAV,UAAU,QAMrB;AAED,SAAS;AACT,MAAM,CAAN,IAAY,eAKX;AALD,WAAY,eAAe;IACzB,oCAAiB,CAAA;IACjB,oCAAiB,CAAA;IACjB,0CAAuB,CAAA;IACvB,4CAAyB,CAAA;AAC3B,CAAC,EALW,eAAe,KAAf,eAAe,QAK1B;AAED,UAAU;AACV,MAAM,CAAN,IAAY,SAKX;AALD,WAAY,SAAS;IACnB,wCAA2B,CAAA;IAC3B,sCAAyB,CAAA;IACzB,0CAA6B,CAAA;IAC7B,4BAAe,CAAA;AACjB,CAAC,EALW,SAAS,KAAT,SAAS,QAKpB;AAED,OAAO;AACP,MAAM,CAAN,IAAY,aAMX;AAND,WAAY,aAAa;IACvB,oCAAmB,CAAA;IACnB,oCAAmB,CAAA;IACnB,wCAAuB,CAAA;IACvB,kCAAiB,CAAA;IACjB,wCAAuB,CAAA;AACzB,CAAC,EANW,aAAa,KAAb,aAAa,QAMxB;AAED,OAAO;AACP,MAAM,CAAN,IAAY,cAKX;AALD,WAAY,cAAc;IACxB,eAAe;IACf,+BAAa,CAAA;IACb,2BAA2B;IAC3B,2CAAyB,CAAA;AAC3B,CAAC,EALW,cAAc,KAAd,cAAc,QAKzB"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,OAAO;AACP,MAAM,CAAN,IAAY,UAMX;AAND,WAAY,UAAU;IACpB,2BAAa,CAAA;IACb,yCAA2B,CAAA;IAC3B,qCAAuB,CAAA;IACvB,2BAAa,CAAA;IACb,qCAAuB,CAAA;AACzB,CAAC,EANW,UAAU,KAAV,UAAU,QAMrB;AAED,SAAS;AACT,MAAM,CAAN,IAAY,eAKX;AALD,WAAY,eAAe;IACzB,oCAAiB,CAAA;IACjB,oCAAiB,CAAA;IACjB,0CAAuB,CAAA;IACvB,4CAAyB,CAAA;AAC3B,CAAC,EALW,eAAe,KAAf,eAAe,QAK1B;AAED,WAAW;AACX,MAAM,CAAN,IAAY,aAGX;AAHD,WAAY,aAAa;IACvB,sCAAqB,CAAA;IACrB,kDAAiC,CAAA;AACnC,CAAC,EAHW,aAAa,KAAb,aAAa,QAGxB;AAED,UAAU;AACV,MAAM,CAAN,IAAY,SAKX;AALD,WAAY,SAAS;IACnB,wCAA2B,CAAA;IAC3B,sCAAyB,CAAA;IACzB,0CAA6B,CAAA;IAC7B,4BAAe,CAAA;AACjB,CAAC,EALW,SAAS,KAAT,SAAS,QAKpB;AAED,OAAO;AACP,MAAM,CAAN,IAAY,aAMX;AAND,WAAY,aAAa;IACvB,oCAAmB,CAAA;IACnB,oCAAmB,CAAA;IACnB,wCAAuB,CAAA;IACvB,kCAAiB,CAAA;IACjB,wCAAuB,CAAA;AACzB,CAAC,EANW,aAAa,KAAb,aAAa,QAMxB;AAED,OAAO;AACP,MAAM,CAAN,IAAY,cAKX;AALD,WAAY,cAAc;IACxB,eAAe;IACf,+BAAa,CAAA;IACb,2BAA2B;IAC3B,2CAAyB,CAAA;AAC3B,CAAC,EALW,cAAc,KAAd,cAAc,QAKzB"}
@@ -1 +1 @@
1
- {"version":3,"file":"process-launch.d.ts","sourceRoot":"","sources":["../../src/utils/process-launch.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AA6FD,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,iBAAiB,CAK5E;AAED,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,iBAAiB,CAKtF;AAED,wBAAgB,wBAAwB,CACtC,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,EAAE,EACd,SAAS,EAAE,MAAM,GAChB,iBAAiB,CAKnB;AAED,wBAAgB,uBAAuB,CACrC,QAAQ,GAAE,MAAM,CAAC,QAA2B,EAC5C,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,iBAAiB,CAYnB;AAED,wBAAgB,iBAAiB,CAAC,MAAM,GAAE,MAAoB,GAAG,MAAM,CAEtE;AAED,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAkB1E"}
1
+ {"version":3,"file":"process-launch.d.ts","sourceRoot":"","sources":["../../src/utils/process-launch.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAwID,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,iBAAiB,CAK5E;AAED,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,iBAAiB,CAKtF;AAED,wBAAgB,wBAAwB,CACtC,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,EAAE,EACd,SAAS,EAAE,MAAM,GAChB,iBAAiB,CAKnB;AAED,wBAAgB,uBAAuB,CACrC,QAAQ,GAAE,MAAM,CAAC,QAA2B,EAC5C,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,iBAAiB,CAYnB;AAED,wBAAgB,iBAAiB,CAAC,MAAM,GAAE,MAAoB,GAAG,MAAM,CAEtE;AAED,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAkB1E"}
@@ -5,10 +5,13 @@ const { spawn } = require('node:child_process');
5
5
  const { createReadStream, unlink } = require('node:fs');
6
6
 
7
7
  const [mode, programPath, ...rest] = process.argv.slice(1);
8
- const isCmdBat = process.platform === 'win32' && /\.(cmd|bat)$/i.test(programPath);
8
+ const isWin = process.platform === 'win32';
9
+ const isCmdBat = isWin && /\.(cmd|bat)$/i.test(programPath);
9
10
 
10
11
  let child;
11
12
  let cleanupTarget = null;
13
+ const sentSignals = new Set();
14
+ let forceKillTimer = null;
12
15
 
13
16
  function cleanup() {
14
17
  if (!cleanupTarget) return;
@@ -17,8 +20,43 @@ function cleanup() {
17
20
  unlink(target, () => {});
18
21
  }
19
22
 
23
+ // 终止 child 及其整个进程组。
24
+ // Unix 下 child 以 detached 启动(pgid === child.pid),组播信号可覆盖
25
+ // child 派生的整棵子树(pnpm dev、tsc --watch 等),防止孙进程被 init
26
+ // 收养成为孤儿。同一信号只发送一次;进程组已消失时退回单进程击杀。
27
+ // Windows 没有进程组信号语义,维持单进程击杀。
28
+ function killTree(signal) {
29
+ if (!child || sentSignals.has(signal)) return;
30
+ sentSignals.add(signal);
31
+ if (isWin) {
32
+ if (!child.killed) {
33
+ try { child.kill(signal); } catch {}
34
+ }
35
+ return;
36
+ }
37
+ try {
38
+ process.kill(-child.pid, signal);
39
+ } catch {
40
+ if (!child.killed) {
41
+ try { child.kill(signal); } catch {}
42
+ }
43
+ }
44
+ }
45
+
46
+ // 收到终止信号后兜底:5 秒内进程组未退干净则升级为 SIGKILL。
47
+ function scheduleForceKill() {
48
+ if (forceKillTimer) return;
49
+ forceKillTimer = setTimeout(() => {
50
+ killTree('SIGKILL');
51
+ }, 5000);
52
+ if (forceKillTimer.unref) forceKillTimer.unref();
53
+ }
54
+
20
55
  function exitWithChildResult(code, signal) {
21
56
  cleanup();
57
+ // child 已退出:清扫其进程组内残留的后台孙进程(dev server、watch 等)。
58
+ // SIGHUP 与 PTY 关闭语义一致;组内无进程时 killTree 内部忽略 ESRCH。
59
+ killTree('SIGHUP');
22
60
  if (typeof code === 'number') {
23
61
  process.exit(code);
24
62
  }
@@ -50,21 +88,27 @@ function spawnCmd(args, stdioOpt) {
50
88
  });
51
89
  }
52
90
 
91
+ // Unix: detached 使 child 自成进程组组长,便于整组击杀。
92
+ // stdio 继承的 PTY fd 不受影响(isatty 仍为 true);终止信号统一由
93
+ // 本 wrapper 经 killTree 显式转发。Windows 下 detached 会脱离 ConPTY,
94
+ // 保持默认行为。
95
+ function spawnChild(args, stdioOpt) {
96
+ return spawn(programPath, args, { stdio: stdioOpt, detached: !isWin });
97
+ }
98
+
53
99
  if (mode === 'pipe-file') {
54
100
  const [stdinFile, ...args] = rest;
55
101
  cleanupTarget = stdinFile;
56
102
  child = isCmdBat
57
103
  ? spawnCmd(args, ['pipe', 'inherit', 'inherit'])
58
- : spawn(programPath, args, { stdio: ['pipe', 'inherit', 'inherit'] });
104
+ : spawnChild(args, ['pipe', 'inherit', 'inherit']);
59
105
 
60
106
  child.on('error', exitWithError);
61
107
  child.on('exit', exitWithChildResult);
62
108
 
63
109
  const stream = createReadStream(stdinFile);
64
110
  stream.on('error', (error) => {
65
- if (child && !child.killed) {
66
- child.kill();
67
- }
111
+ killTree('SIGTERM');
68
112
  exitWithError(error);
69
113
  });
70
114
  stream.pipe(child.stdin);
@@ -76,7 +120,7 @@ if (mode === 'pipe-file') {
76
120
  } else {
77
121
  child = isCmdBat
78
122
  ? spawnCmd(rest, 'inherit')
79
- : spawn(programPath, rest, { stdio: 'inherit' });
123
+ : spawnChild(rest, 'inherit');
80
124
 
81
125
  child.on('error', exitWithError);
82
126
  child.on('exit', exitWithChildResult);
@@ -84,9 +128,8 @@ if (mode === 'pipe-file') {
84
128
 
85
129
  ['SIGINT', 'SIGTERM', 'SIGHUP'].forEach((signal) => {
86
130
  process.on(signal, () => {
87
- if (child && !child.killed) {
88
- child.kill(signal);
89
- }
131
+ killTree(signal);
132
+ scheduleForceKill();
90
133
  });
91
134
  });
92
135
  `;
@@ -1 +1 @@
1
- {"version":3,"file":"process-launch.js","sourceRoot":"","sources":["../../src/utils/process-launch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAO7B,MAAM,kBAAkB,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyFpC,CAAC;AAEF,MAAM,UAAU,uBAAuB,CAAC,SAAiB;IACvD,OAAO;QACL,OAAO,EAAE,OAAO,CAAC,QAAQ;QACzB,IAAI,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,uCAAuC,CAAC,CAAC;KACzE,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,WAAmB,EAAE,IAAc;IACjE,OAAO;QACL,OAAO,EAAE,OAAO,CAAC,QAAQ;QACzB,IAAI,EAAE,CAAC,IAAI,EAAE,kBAAkB,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC;KAChE,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,wBAAwB,CACtC,WAAmB,EACnB,IAAc,EACd,SAAiB;IAEjB,OAAO;QACL,OAAO,EAAE,OAAO,CAAC,QAAQ;QACzB,IAAI,EAAE,CAAC,IAAI,EAAE,kBAAkB,EAAE,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC;KAC/E,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,uBAAuB,CACrC,WAA4B,OAAO,CAAC,QAAQ,EAC5C,MAAyB,OAAO,CAAC,GAAG;IAEpC,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QACzB,OAAO;YACL,OAAO,EAAE,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,OAAO,IAAI,SAAS;YAChD,IAAI,EAAE,EAAE;SACT,CAAC;IACJ,CAAC;IAED,OAAO;QACL,OAAO,EAAE,GAAG,CAAC,KAAK,IAAI,UAAU;QAChC,IAAI,EAAE,EAAE;KACT,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,SAAiB,EAAE,CAAC,MAAM,EAAE;IAC5D,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,4BAA4B,CAAC,MAAc;IACzD,MAAM,KAAK,GAAG,MAAM;SACjB,KAAK,CAAC,OAAO,CAAC;SACd,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SAC1B,MAAM,CAAC,OAAO,CAAC,CAAC;IAEnB,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEpC,6EAA6E;IAC7E,4EAA4E;IAC5E,6EAA6E;IAC7E,iFAAiF;IACjF,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrD,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QACjE,IAAI,SAAS;YAAE,OAAO,SAAS,CAAC;IAClC,CAAC;IAED,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC"}
1
+ {"version":3,"file":"process-launch.js","sourceRoot":"","sources":["../../src/utils/process-launch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAO7B,MAAM,kBAAkB,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoIpC,CAAC;AAEF,MAAM,UAAU,uBAAuB,CAAC,SAAiB;IACvD,OAAO;QACL,OAAO,EAAE,OAAO,CAAC,QAAQ;QACzB,IAAI,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,uCAAuC,CAAC,CAAC;KACzE,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,WAAmB,EAAE,IAAc;IACjE,OAAO;QACL,OAAO,EAAE,OAAO,CAAC,QAAQ;QACzB,IAAI,EAAE,CAAC,IAAI,EAAE,kBAAkB,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC;KAChE,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,wBAAwB,CACtC,WAAmB,EACnB,IAAc,EACd,SAAiB;IAEjB,OAAO;QACL,OAAO,EAAE,OAAO,CAAC,QAAQ;QACzB,IAAI,EAAE,CAAC,IAAI,EAAE,kBAAkB,EAAE,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC;KAC/E,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,uBAAuB,CACrC,WAA4B,OAAO,CAAC,QAAQ,EAC5C,MAAyB,OAAO,CAAC,GAAG;IAEpC,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QACzB,OAAO;YACL,OAAO,EAAE,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,OAAO,IAAI,SAAS;YAChD,IAAI,EAAE,EAAE;SACT,CAAC;IACJ,CAAC;IAED,OAAO;QACL,OAAO,EAAE,GAAG,CAAC,KAAK,IAAI,UAAU;QAChC,IAAI,EAAE,EAAE;KACT,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,SAAiB,EAAE,CAAC,MAAM,EAAE;IAC5D,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,4BAA4B,CAAC,MAAc;IACzD,MAAM,KAAK,GAAG,MAAM;SACjB,KAAK,CAAC,OAAO,CAAC;SACd,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SAC1B,MAAM,CAAC,OAAO,CAAC,CAAC;IAEnB,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEpC,6EAA6E;IAC7E,4EAA4E;IAC5E,6EAA6E;IAC7E,iFAAiF;IACjF,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrD,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QACjE,IAAI,SAAS;YAAE,OAAO,SAAS,CAAC;IAClC,CAAC;IAED,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC"}
@@ -1,9 +1,45 @@
1
- import { execFileSync } from 'node:child_process';
1
+ import { execFileSync, spawn } from 'node:child_process';
2
2
  import { existsSync, writeFileSync } from 'node:fs';
3
3
  import os from 'node:os';
4
4
  import path from 'node:path';
5
5
  import { describe, expect, it } from 'vitest';
6
6
  import { buildPtyCommand, buildPtyCommandWithStdin, getDefaultTerminalShell, normalizeCommandLookupOutput, } from './process-launch.js';
7
+ function isAlive(pid) {
8
+ try {
9
+ process.kill(pid, 0);
10
+ return true;
11
+ }
12
+ catch {
13
+ return false;
14
+ }
15
+ }
16
+ async function waitUntil(predicate, timeoutMs) {
17
+ const deadline = Date.now() + timeoutMs;
18
+ while (Date.now() < deadline) {
19
+ if (predicate())
20
+ return true;
21
+ await new Promise((resolve) => setTimeout(resolve, 50));
22
+ }
23
+ return predicate();
24
+ }
25
+ /** 启动 wrapper 运行 childScript,等待 child 打印的孙进程 PID */
26
+ function spawnWrapperWithGrandchild(childScript) {
27
+ const invocation = buildPtyCommand(process.execPath, ['-e', childScript]);
28
+ const wrapper = spawn(invocation.command, invocation.args, {
29
+ stdio: ['ignore', 'pipe', 'inherit'],
30
+ });
31
+ const grandPid = new Promise((resolve, reject) => {
32
+ let buf = '';
33
+ wrapper.stdout.on('data', (chunk) => {
34
+ buf += String(chunk);
35
+ const match = buf.match(/GRAND:(\d+)/);
36
+ if (match)
37
+ resolve(Number(match[1]));
38
+ });
39
+ setTimeout(() => reject(new Error('timed out waiting for grandchild pid')), 5000).unref();
40
+ });
41
+ return { wrapper, grandPid };
42
+ }
7
43
  describe('process-launch', () => {
8
44
  it('should preserve arguments through the PTY wrapper', () => {
9
45
  const invocation = buildPtyCommand(process.execPath, [
@@ -51,5 +87,33 @@ describe('process-launch', () => {
51
87
  args: [],
52
88
  });
53
89
  });
90
+ it.skipIf(process.platform === 'win32')('should kill grandchild processes when the wrapper receives a termination signal', async () => {
91
+ // child 启动一个长睡眠孙进程后自己也保持运行
92
+ const { wrapper, grandPid } = spawnWrapperWithGrandchild(`
93
+ const { spawn } = require('node:child_process');
94
+ const grand = spawn(process.execPath, ['-e', 'setTimeout(() => {}, 60000)'], { stdio: 'ignore' });
95
+ process.stdout.write('GRAND:' + grand.pid + '\\n');
96
+ setTimeout(() => {}, 60000);
97
+ `);
98
+ const pid = await grandPid;
99
+ expect(isAlive(pid)).toBe(true);
100
+ wrapper.kill('SIGTERM');
101
+ await new Promise((resolve) => wrapper.on('exit', resolve));
102
+ // killTree 应通过进程组信号清掉孙进程,而不仅是直接 child
103
+ expect(await waitUntil(() => !isAlive(pid), 3000)).toBe(true);
104
+ });
105
+ it.skipIf(process.platform === 'win32')('should sweep leftover grandchildren after the child exits normally', async () => {
106
+ // child 留下一个后台孙进程后立即正常退出
107
+ const { wrapper, grandPid } = spawnWrapperWithGrandchild(`
108
+ const { spawn } = require('node:child_process');
109
+ const grand = spawn(process.execPath, ['-e', 'setTimeout(() => {}, 60000)'], { stdio: 'ignore' });
110
+ grand.unref();
111
+ process.stdout.write('GRAND:' + grand.pid + '\\n');
112
+ `);
113
+ const pid = await grandPid;
114
+ await new Promise((resolve) => wrapper.on('exit', resolve));
115
+ // exitWithChildResult 应在退出前对 child 进程组发 SIGHUP 清扫残留
116
+ expect(await waitUntil(() => !isAlive(pid), 3000)).toBe(true);
117
+ });
54
118
  });
55
119
  //# sourceMappingURL=process-launch.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"process-launch.test.js","sourceRoot":"","sources":["../../src/utils/process-launch.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"process-launch.test.js","sourceRoot":"","sources":["../../src/utils/process-launch.test.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- import{e as H,u as Q,r as n,i as b,j as e,L as X,x as Y}from"./index-BAz6UxmL.js";import{u as Z,a as ee,b as L,c as te,d as se,e as ne,T as re,P as ae,A as le,G as ie,S as oe}from"./mermaid-NOHMQCX5-BLfGHrOE.js";import{B as y}from"./button-C-IDw2d8.js";import{d as ce}from"./use-profiles-Bvj_EW-7.js";import{C as de}from"./chevron-up-DqGc0SsZ.js";import{C as xe}from"./chevron-down-C735lPj9.js";import"./log-adapter-i7kNXXup.js";import"./chevron-right-DfFiWY3R.js";import"./check-KjbNKANU.js";const me=[["line",{x1:"4",x2:"20",y1:"9",y2:"9",key:"4lhtct"}],["line",{x1:"4",x2:"20",y1:"15",y2:"15",key:"vyu0kd"}],["line",{x1:"10",x2:"8",y1:"3",y2:"21",key:"1ggp8o"}],["line",{x1:"16",x2:"14",y1:"3",y2:"21",key:"weycgp"}]],ue=H("hash",me);const pe=[["path",{d:"M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z",key:"1ffxy3"}],["path",{d:"m21.854 2.147-10.94 10.939",key:"12cjpa"}]],he=H("send",pe),ge=!0;function ke(){const{t:s}=Q(),[w,U]=n.useState([]),[i,S]=n.useState(""),[x,A]=n.useState("DEFAULT"),[o,k]=n.useState(""),[a,D]=n.useState(null),[l,c]=n.useState("idle"),[g,E]=n.useState(!1),[m,j]=n.useState(""),C=n.useRef(null),$=n.useRef(null),u=n.useRef(null),{data:p}=ce(i),F=p?Object.keys(p):["DEFAULT"],V=t=>{S(t),A("DEFAULT")},_=n.useCallback(t=>{c(t===0?"stopped":"error")},[]),B=n.useCallback(t=>{console.error("Agent error:",t),c("error")},[]),{isConnected:h,isAttached:f,logs:v,entries:G,agentSessionId:I,attach:z,clearLogs:P}=Z({sessionId:a||"",onExit:_,onError:B}),{todos:R}=ee(G);n.useEffect(()=>{b.get("/demo/agents").then(t=>{U(t.agents);const r=t.agents.find(N=>N.available);r&&S(r.type)})},[]),n.useEffect(()=>{C.current?.scrollToBottom("smooth")},[v]),n.useEffect(()=>{console.log(`[AgentDemoPage:useEffect] t=${Date.now()} sessionId=${a} isConnected=${h} isAttached=${f}`),a&&h&&!f&&(console.log(`[AgentDemoPage:useEffect] t=${Date.now()} calling attach()`),z())},[a,h,f,z]);const M=t=>{if(j(t.target.value),u.current){u.current.style.height="auto";const N=Math.min(u.current.scrollHeight,210);u.current.style.height=`${N}px`}},O=async()=>{if(!i||!o.trim())return;const t=Date.now();console.log(`[AgentDemoPage:handleStart] t=${t} starting...`),c("starting"),P();try{const r=await b.post("/demo/start",{agentType:i,prompt:o.trim(),variant:x});ge&&console.log(`[AgentDemoPage:handleStart] t=${Date.now()} apiTime=${Date.now()-t}ms sessionId=${r.sessionId}`),D(r.sessionId),c("running")}catch(r){console.error("Start failed:",r),c("error")}},T=async()=>{if(!a||!m.trim())return;const t=m.trim();j("");try{await b.post(`/demo/${a}/message`,{message:t})}catch(r){console.error("Send failed:",r)}},K=async()=>{if(a)try{await b.post(`/demo/${a}/stop`),c("stopped")}catch(t){console.error("Stop failed:",t)}},q=()=>{D(null),c("idle"),k(""),j(""),P()},J=l==="running",d=a!==null,W=w.find(t=>t.type===i);return e.jsxs("div",{className:"flex flex-col h-full bg-white",children:[e.jsxs("div",{className:"px-8 py-5 border-b border-neutral-100 bg-white transition-all duration-300",children:[e.jsxs("div",{className:"flex items-center flex-wrap gap-3",children:[e.jsxs("div",{className:"flex items-baseline gap-2",children:[e.jsx("span",{className:"text-base font-medium text-blue-600",children:"Agent Demo"}),e.jsx("span",{className:"text-neutral-300 text-sm",children:"/"}),e.jsx("span",{className:"text-xl font-bold text-neutral-900 tracking-tight",children:d?o.slice(0,50)+(o.length>50?"...":""):s("新会话")})]}),e.jsxs("div",{className:"flex items-center",children:[l==="running"&&e.jsxs("div",{className:"flex items-center gap-1.5 px-2.5 py-0.5 bg-blue-50 text-blue-700 rounded-full text-xs font-medium border border-blue-100",children:[e.jsx(L,{className:"w-3.5 h-3.5 animate-pulse"}),e.jsx("span",{children:"Running"})]}),l==="stopped"&&e.jsxs("div",{className:"flex items-center gap-1.5 px-2.5 py-0.5 bg-emerald-50 text-emerald-700 rounded-full text-xs font-medium border border-emerald-100",children:[e.jsx(te,{className:"w-3.5 h-3.5"}),e.jsx("span",{children:"Done"})]}),l==="idle"&&e.jsxs("div",{className:"flex items-center gap-1.5 px-2.5 py-0.5 bg-neutral-100 text-neutral-600 rounded-full text-xs font-medium border border-neutral-200",children:[e.jsx(se,{className:"w-3.5 h-3.5"}),e.jsx("span",{children:"Idle"})]}),l==="starting"&&e.jsxs("div",{className:"flex items-center gap-1.5 px-2.5 py-0.5 bg-amber-50 text-amber-700 rounded-full text-xs font-medium border border-amber-100",children:[e.jsx(L,{className:"w-3.5 h-3.5 animate-spin"}),e.jsx("span",{children:"Starting..."})]}),l==="error"&&e.jsx("div",{className:"flex items-center gap-1.5 px-2.5 py-0.5 bg-red-50 text-red-700 rounded-full text-xs font-medium border border-red-100",children:e.jsx("span",{children:"Error"})})]})]}),d&&e.jsxs("div",{className:"mt-1.5 flex items-start gap-2 group max-w-4xl",children:[e.jsx("div",{className:`text-sm text-neutral-600 leading-relaxed cursor-pointer transition-all ${g?"":"truncate"}`,onClick:()=>E(!g),children:o}),e.jsx("button",{onClick:()=>E(!g),className:"mt-0.5 text-neutral-400 opacity-0 group-hover:opacity-100 hover:text-neutral-600 transition-opacity",children:g?e.jsx(de,{size:14}):e.jsx(xe,{size:14})})]}),e.jsxs("div",{className:"flex items-center gap-6 mt-3",children:[e.jsxs("div",{className:"flex items-center gap-2 text-xs",children:[e.jsx("span",{className:"text-neutral-400 font-medium",children:"Agent"}),e.jsx("div",{className:"flex items-center gap-1.5 text-neutral-900 font-medium bg-neutral-50 px-2 py-1 rounded border border-neutral-100",children:W?.name||i||s("未选择")})]}),x!=="DEFAULT"&&e.jsxs("div",{className:"flex items-center gap-2 text-xs",children:[e.jsx("span",{className:"text-neutral-400 font-medium",children:"Variant"}),e.jsx("div",{className:"flex items-center gap-1.5 text-neutral-700 font-medium bg-blue-50 px-2 py-1 rounded border border-blue-100",children:x})]}),I&&e.jsxs("div",{className:"flex items-center gap-2 text-xs",children:[e.jsx("span",{className:"text-neutral-400 font-medium",children:"Session"}),e.jsxs("div",{className:"flex items-center gap-1.5 text-neutral-700 font-mono bg-neutral-50 px-2 py-1 rounded border border-neutral-100",children:[I.slice(0,8),"..."]})]}),e.jsxs("div",{className:"flex items-center gap-2 text-xs",children:[e.jsx("span",{className:"text-neutral-400 font-medium",children:s("连接")}),e.jsx("div",{className:`flex items-center gap-1.5 font-medium px-2 py-1 rounded border ${h?"text-emerald-700 bg-emerald-50 border-emerald-100":"text-neutral-500 bg-neutral-50 border-neutral-100"}`,children:s(h?f?"已连接":"连接中...":"未连接")})]}),d&&e.jsx(y,{variant:"outline",size:"sm",onClick:q,className:"ml-auto",children:s("新会话")}),e.jsxs(X,{to:"/settings/profiles",className:`flex items-center gap-1.5 text-xs text-neutral-500 hover:text-neutral-900 transition-colors ${d?"":"ml-auto"}`,children:[e.jsx(Y,{size:14}),e.jsx("span",{children:s("Profiles 设置")})]})]})]}),e.jsx("div",{ref:$,className:"flex-1 overflow-y-auto px-8 py-6",children:d?e.jsx("div",{className:"min-h-[200px]",children:v.length===0?e.jsx("div",{className:"text-neutral-400 text-center py-8",children:s("等待 Agent 响应...")}):e.jsx(ne,{ref:C,logs:v,scrollElementRef:$})}):e.jsxs("div",{className:"max-w-2xl mx-auto space-y-6",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-semibold mb-3 text-neutral-900",children:s("选择 Agent")}),e.jsx("div",{className:"flex gap-2 flex-wrap",children:w.map(t=>e.jsxs(y,{variant:i===t.type?"default":"outline",disabled:!t.available,onClick:()=>V(t.type),children:[t.name,t.available&&t.version&&` (${t.version})`,!t.available&&s(" (不可用)")]},t.type))})]}),e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-semibold mb-3 text-neutral-900",children:s("配置变体 (Profile Variant)")}),e.jsx("div",{className:"flex gap-2 flex-wrap",children:F.map(t=>e.jsx("button",{onClick:()=>A(t),className:`px-3 py-1.5 rounded-full text-sm font-medium border transition-colors ${x===t?"bg-neutral-900 text-white border-neutral-900":"bg-white text-neutral-600 border-neutral-200 hover:border-neutral-400"}`,children:t},t))}),p&&p[x]&&e.jsx("p",{className:"mt-2 text-xs text-neutral-500 font-mono",children:Object.entries(p[x]).map(([t,r])=>`${t}: ${JSON.stringify(r)}`).join(", ")})]}),e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-semibold mb-3 text-neutral-900",children:s("输入任务")}),e.jsxs("div",{className:"relative border border-neutral-200 rounded-xl shadow-sm bg-white focus-within:ring-1 focus-within:ring-neutral-300 focus-within:border-neutral-300 transition-all duration-200",children:[e.jsx("textarea",{value:o,onChange:t=>k(t.target.value),rows:4,placeholder:s("描述你想让 Agent 完成的任务..."),className:"w-full px-4 py-3 bg-transparent border-none focus:outline-none focus:ring-0 resize-none text-neutral-900 placeholder-neutral-400 leading-relaxed text-sm"}),e.jsx("div",{className:"flex items-center justify-end px-3 pb-3 pt-1",children:e.jsx(y,{onClick:O,disabled:l==="starting"||!i||!o.trim(),children:s(l==="starting"?"启动中...":"开始")})})]})]})]})}),d&&R.length>0&&e.jsx("div",{className:"px-8 py-2 bg-white border-t border-neutral-100",children:e.jsx(re,{todos:R})}),d&&e.jsx("div",{className:"px-8 py-6 border-t border-neutral-100 bg-white",children:e.jsxs("div",{className:"relative border border-neutral-200 rounded-xl shadow-sm bg-white focus-within:ring-1 focus-within:ring-neutral-300 focus-within:border-neutral-300 transition-all duration-200",children:[e.jsx("textarea",{ref:u,value:m,onChange:M,rows:3,placeholder:s("发送消息给 Agent..."),className:"w-full px-4 py-3 bg-transparent border-none focus:outline-none focus:ring-0 resize-none text-neutral-900 placeholder-neutral-400 leading-relaxed text-sm scrollbar-thin scrollbar-thumb-neutral-200 scrollbar-track-transparent",style:{minHeight:"80px",maxHeight:"210px"},onKeyDown:t=>{t.key==="Enter"&&!t.shiftKey&&!t.repeat&&!t.nativeEvent.isComposing&&t.nativeEvent.keyCode!==229&&(t.preventDefault(),T())}}),e.jsxs("div",{className:"flex items-center justify-between px-3 pb-3 pt-1 border-t border-transparent",children:[e.jsxs("div",{className:"flex items-center gap-1 text-neutral-400",children:[e.jsx("button",{className:"p-2 hover:bg-neutral-100 hover:text-neutral-600 rounded-lg transition-colors",title:"Attach File",children:e.jsx(ae,{size:18})}),e.jsx("button",{className:"p-2 hover:bg-neutral-100 hover:text-neutral-600 rounded-lg transition-colors",title:"Mention",children:e.jsx(le,{size:18})}),e.jsx("button",{className:"p-2 hover:bg-neutral-100 hover:text-neutral-600 rounded-lg transition-colors",title:"Reference Issue",children:e.jsx(ue,{size:18})}),e.jsx("div",{className:"w-px h-4 bg-neutral-200 mx-1"}),e.jsx("button",{className:"p-2 hover:bg-neutral-100 hover:text-neutral-600 rounded-lg transition-colors",title:"Search Web",children:e.jsx(ie,{size:18})})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[J&&e.jsxs("button",{onClick:K,className:"flex items-center gap-2 px-3 py-2 text-xs font-semibold text-red-600 bg-red-50 hover:bg-red-100 rounded-lg transition-colors",children:[e.jsx(oe,{size:12,fill:"currentColor"}),e.jsx("span",{children:s("停止")})]}),e.jsxs("button",{onClick:T,disabled:!m.trim(),className:`flex items-center gap-2 px-3 py-2 text-xs font-semibold rounded-lg transition-all ${m.trim()?"bg-neutral-900 text-white hover:bg-black shadow-sm":"bg-neutral-100 text-neutral-400 cursor-not-allowed"}`,children:[e.jsx("span",{children:s("发送")}),e.jsx(he,{size:14})]})]})]})]})})]})}export{ke as AgentDemoPage};
1
+ import{e as H,u as Q,r as n,i as b,j as e,L as X,x as Y}from"./index-RxbHMWXV.js";import{u as Z,a as ee,b as L,c as te,d as se,e as ne,T as re,P as ae,A as le,G as ie,S as oe}from"./mermaid-NOHMQCX5-fubZbKyF.js";import{B as y}from"./button-BUA8P726.js";import{d as ce}from"./use-profiles-D6cZwU1R.js";import{C as de}from"./chevron-up-BEHjZ-SB.js";import{C as xe}from"./chevron-down-B931AgE2.js";import"./log-adapter-CtvxzS4j.js";import"./chevron-right-F9i4wey6.js";import"./check-BYuuXc71.js";const me=[["line",{x1:"4",x2:"20",y1:"9",y2:"9",key:"4lhtct"}],["line",{x1:"4",x2:"20",y1:"15",y2:"15",key:"vyu0kd"}],["line",{x1:"10",x2:"8",y1:"3",y2:"21",key:"1ggp8o"}],["line",{x1:"16",x2:"14",y1:"3",y2:"21",key:"weycgp"}]],ue=H("hash",me);const pe=[["path",{d:"M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z",key:"1ffxy3"}],["path",{d:"m21.854 2.147-10.94 10.939",key:"12cjpa"}]],he=H("send",pe),ge=!0;function ke(){const{t:s}=Q(),[w,U]=n.useState([]),[i,S]=n.useState(""),[x,A]=n.useState("DEFAULT"),[o,k]=n.useState(""),[a,D]=n.useState(null),[l,c]=n.useState("idle"),[g,E]=n.useState(!1),[m,j]=n.useState(""),C=n.useRef(null),$=n.useRef(null),u=n.useRef(null),{data:p}=ce(i),F=p?Object.keys(p):["DEFAULT"],V=t=>{S(t),A("DEFAULT")},_=n.useCallback(t=>{c(t===0?"stopped":"error")},[]),B=n.useCallback(t=>{console.error("Agent error:",t),c("error")},[]),{isConnected:h,isAttached:f,logs:v,entries:G,agentSessionId:I,attach:z,clearLogs:P}=Z({sessionId:a||"",onExit:_,onError:B}),{todos:R}=ee(G);n.useEffect(()=>{b.get("/demo/agents").then(t=>{U(t.agents);const r=t.agents.find(N=>N.available);r&&S(r.type)})},[]),n.useEffect(()=>{C.current?.scrollToBottom("smooth")},[v]),n.useEffect(()=>{console.log(`[AgentDemoPage:useEffect] t=${Date.now()} sessionId=${a} isConnected=${h} isAttached=${f}`),a&&h&&!f&&(console.log(`[AgentDemoPage:useEffect] t=${Date.now()} calling attach()`),z())},[a,h,f,z]);const M=t=>{if(j(t.target.value),u.current){u.current.style.height="auto";const N=Math.min(u.current.scrollHeight,210);u.current.style.height=`${N}px`}},O=async()=>{if(!i||!o.trim())return;const t=Date.now();console.log(`[AgentDemoPage:handleStart] t=${t} starting...`),c("starting"),P();try{const r=await b.post("/demo/start",{agentType:i,prompt:o.trim(),variant:x});ge&&console.log(`[AgentDemoPage:handleStart] t=${Date.now()} apiTime=${Date.now()-t}ms sessionId=${r.sessionId}`),D(r.sessionId),c("running")}catch(r){console.error("Start failed:",r),c("error")}},T=async()=>{if(!a||!m.trim())return;const t=m.trim();j("");try{await b.post(`/demo/${a}/message`,{message:t})}catch(r){console.error("Send failed:",r)}},K=async()=>{if(a)try{await b.post(`/demo/${a}/stop`),c("stopped")}catch(t){console.error("Stop failed:",t)}},q=()=>{D(null),c("idle"),k(""),j(""),P()},J=l==="running",d=a!==null,W=w.find(t=>t.type===i);return e.jsxs("div",{className:"flex flex-col h-full bg-white",children:[e.jsxs("div",{className:"px-8 py-5 border-b border-neutral-100 bg-white transition-all duration-300",children:[e.jsxs("div",{className:"flex items-center flex-wrap gap-3",children:[e.jsxs("div",{className:"flex items-baseline gap-2",children:[e.jsx("span",{className:"text-base font-medium text-blue-600",children:"Agent Demo"}),e.jsx("span",{className:"text-neutral-300 text-sm",children:"/"}),e.jsx("span",{className:"text-xl font-bold text-neutral-900 tracking-tight",children:d?o.slice(0,50)+(o.length>50?"...":""):s("新会话")})]}),e.jsxs("div",{className:"flex items-center",children:[l==="running"&&e.jsxs("div",{className:"flex items-center gap-1.5 px-2.5 py-0.5 bg-blue-50 text-blue-700 rounded-full text-xs font-medium border border-blue-100",children:[e.jsx(L,{className:"w-3.5 h-3.5 animate-pulse"}),e.jsx("span",{children:"Running"})]}),l==="stopped"&&e.jsxs("div",{className:"flex items-center gap-1.5 px-2.5 py-0.5 bg-emerald-50 text-emerald-700 rounded-full text-xs font-medium border border-emerald-100",children:[e.jsx(te,{className:"w-3.5 h-3.5"}),e.jsx("span",{children:"Done"})]}),l==="idle"&&e.jsxs("div",{className:"flex items-center gap-1.5 px-2.5 py-0.5 bg-neutral-100 text-neutral-600 rounded-full text-xs font-medium border border-neutral-200",children:[e.jsx(se,{className:"w-3.5 h-3.5"}),e.jsx("span",{children:"Idle"})]}),l==="starting"&&e.jsxs("div",{className:"flex items-center gap-1.5 px-2.5 py-0.5 bg-amber-50 text-amber-700 rounded-full text-xs font-medium border border-amber-100",children:[e.jsx(L,{className:"w-3.5 h-3.5 animate-spin"}),e.jsx("span",{children:"Starting..."})]}),l==="error"&&e.jsx("div",{className:"flex items-center gap-1.5 px-2.5 py-0.5 bg-red-50 text-red-700 rounded-full text-xs font-medium border border-red-100",children:e.jsx("span",{children:"Error"})})]})]}),d&&e.jsxs("div",{className:"mt-1.5 flex items-start gap-2 group max-w-4xl",children:[e.jsx("div",{className:`text-sm text-neutral-600 leading-relaxed cursor-pointer transition-all ${g?"":"truncate"}`,onClick:()=>E(!g),children:o}),e.jsx("button",{onClick:()=>E(!g),className:"mt-0.5 text-neutral-400 opacity-0 group-hover:opacity-100 hover:text-neutral-600 transition-opacity",children:g?e.jsx(de,{size:14}):e.jsx(xe,{size:14})})]}),e.jsxs("div",{className:"flex items-center gap-6 mt-3",children:[e.jsxs("div",{className:"flex items-center gap-2 text-xs",children:[e.jsx("span",{className:"text-neutral-400 font-medium",children:"Agent"}),e.jsx("div",{className:"flex items-center gap-1.5 text-neutral-900 font-medium bg-neutral-50 px-2 py-1 rounded border border-neutral-100",children:W?.name||i||s("未选择")})]}),x!=="DEFAULT"&&e.jsxs("div",{className:"flex items-center gap-2 text-xs",children:[e.jsx("span",{className:"text-neutral-400 font-medium",children:"Variant"}),e.jsx("div",{className:"flex items-center gap-1.5 text-neutral-700 font-medium bg-blue-50 px-2 py-1 rounded border border-blue-100",children:x})]}),I&&e.jsxs("div",{className:"flex items-center gap-2 text-xs",children:[e.jsx("span",{className:"text-neutral-400 font-medium",children:"Session"}),e.jsxs("div",{className:"flex items-center gap-1.5 text-neutral-700 font-mono bg-neutral-50 px-2 py-1 rounded border border-neutral-100",children:[I.slice(0,8),"..."]})]}),e.jsxs("div",{className:"flex items-center gap-2 text-xs",children:[e.jsx("span",{className:"text-neutral-400 font-medium",children:s("连接")}),e.jsx("div",{className:`flex items-center gap-1.5 font-medium px-2 py-1 rounded border ${h?"text-emerald-700 bg-emerald-50 border-emerald-100":"text-neutral-500 bg-neutral-50 border-neutral-100"}`,children:s(h?f?"已连接":"连接中...":"未连接")})]}),d&&e.jsx(y,{variant:"outline",size:"sm",onClick:q,className:"ml-auto",children:s("新会话")}),e.jsxs(X,{to:"/settings/profiles",className:`flex items-center gap-1.5 text-xs text-neutral-500 hover:text-neutral-900 transition-colors ${d?"":"ml-auto"}`,children:[e.jsx(Y,{size:14}),e.jsx("span",{children:s("Profiles 设置")})]})]})]}),e.jsx("div",{ref:$,className:"flex-1 overflow-y-auto px-8 py-6",children:d?e.jsx("div",{className:"min-h-[200px]",children:v.length===0?e.jsx("div",{className:"text-neutral-400 text-center py-8",children:s("等待 Agent 响应...")}):e.jsx(ne,{ref:C,logs:v,scrollElementRef:$})}):e.jsxs("div",{className:"max-w-2xl mx-auto space-y-6",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-semibold mb-3 text-neutral-900",children:s("选择 Agent")}),e.jsx("div",{className:"flex gap-2 flex-wrap",children:w.map(t=>e.jsxs(y,{variant:i===t.type?"default":"outline",disabled:!t.available,onClick:()=>V(t.type),children:[t.name,t.available&&t.version&&` (${t.version})`,!t.available&&s(" (不可用)")]},t.type))})]}),e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-semibold mb-3 text-neutral-900",children:s("配置变体 (Profile Variant)")}),e.jsx("div",{className:"flex gap-2 flex-wrap",children:F.map(t=>e.jsx("button",{onClick:()=>A(t),className:`px-3 py-1.5 rounded-full text-sm font-medium border transition-colors ${x===t?"bg-neutral-900 text-white border-neutral-900":"bg-white text-neutral-600 border-neutral-200 hover:border-neutral-400"}`,children:t},t))}),p&&p[x]&&e.jsx("p",{className:"mt-2 text-xs text-neutral-500 font-mono",children:Object.entries(p[x]).map(([t,r])=>`${t}: ${JSON.stringify(r)}`).join(", ")})]}),e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-semibold mb-3 text-neutral-900",children:s("输入任务")}),e.jsxs("div",{className:"relative border border-neutral-200 rounded-xl shadow-sm bg-white focus-within:ring-1 focus-within:ring-neutral-300 focus-within:border-neutral-300 transition-all duration-200",children:[e.jsx("textarea",{value:o,onChange:t=>k(t.target.value),rows:4,placeholder:s("描述你想让 Agent 完成的任务..."),className:"w-full px-4 py-3 bg-transparent border-none focus:outline-none focus:ring-0 resize-none text-neutral-900 placeholder-neutral-400 leading-relaxed text-sm"}),e.jsx("div",{className:"flex items-center justify-end px-3 pb-3 pt-1",children:e.jsx(y,{onClick:O,disabled:l==="starting"||!i||!o.trim(),children:s(l==="starting"?"启动中...":"开始")})})]})]})]})}),d&&R.length>0&&e.jsx("div",{className:"px-8 py-2 bg-white border-t border-neutral-100",children:e.jsx(re,{todos:R})}),d&&e.jsx("div",{className:"px-8 py-6 border-t border-neutral-100 bg-white",children:e.jsxs("div",{className:"relative border border-neutral-200 rounded-xl shadow-sm bg-white focus-within:ring-1 focus-within:ring-neutral-300 focus-within:border-neutral-300 transition-all duration-200",children:[e.jsx("textarea",{ref:u,value:m,onChange:M,rows:3,placeholder:s("发送消息给 Agent..."),className:"w-full px-4 py-3 bg-transparent border-none focus:outline-none focus:ring-0 resize-none text-neutral-900 placeholder-neutral-400 leading-relaxed text-sm scrollbar-thin scrollbar-thumb-neutral-200 scrollbar-track-transparent",style:{minHeight:"80px",maxHeight:"210px"},onKeyDown:t=>{t.key==="Enter"&&!t.shiftKey&&!t.repeat&&!t.nativeEvent.isComposing&&t.nativeEvent.keyCode!==229&&(t.preventDefault(),T())}}),e.jsxs("div",{className:"flex items-center justify-between px-3 pb-3 pt-1 border-t border-transparent",children:[e.jsxs("div",{className:"flex items-center gap-1 text-neutral-400",children:[e.jsx("button",{className:"p-2 hover:bg-neutral-100 hover:text-neutral-600 rounded-lg transition-colors",title:"Attach File",children:e.jsx(ae,{size:18})}),e.jsx("button",{className:"p-2 hover:bg-neutral-100 hover:text-neutral-600 rounded-lg transition-colors",title:"Mention",children:e.jsx(le,{size:18})}),e.jsx("button",{className:"p-2 hover:bg-neutral-100 hover:text-neutral-600 rounded-lg transition-colors",title:"Reference Issue",children:e.jsx(ue,{size:18})}),e.jsx("div",{className:"w-px h-4 bg-neutral-200 mx-1"}),e.jsx("button",{className:"p-2 hover:bg-neutral-100 hover:text-neutral-600 rounded-lg transition-colors",title:"Search Web",children:e.jsx(ie,{size:18})})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[J&&e.jsxs("button",{onClick:K,className:"flex items-center gap-2 px-3 py-2 text-xs font-semibold text-red-600 bg-red-50 hover:bg-red-100 rounded-lg transition-colors",children:[e.jsx(oe,{size:12,fill:"currentColor"}),e.jsx("span",{children:s("停止")})]}),e.jsxs("button",{onClick:T,disabled:!m.trim(),className:`flex items-center gap-2 px-3 py-2 text-xs font-semibold rounded-lg transition-all ${m.trim()?"bg-neutral-900 text-white hover:bg-black shadow-sm":"bg-neutral-100 text-neutral-400 cursor-not-allowed"}`,children:[e.jsx("span",{children:s("发送")}),e.jsx(he,{size:14})]})]})]})]})})]})}export{ke as AgentDemoPage};
@@ -1,4 +1,4 @@
1
- import{r as a,w as j,S as E,C as T,j as t,d as M,u as U,i as I}from"./index-BAz6UxmL.js";import{B as O}from"./button-C-IDw2d8.js";function P(s){const{sessionId:c,onOutput:k,onExit:x,onError:b}=s,[p,g]=a.useState(()=>j.isConnected()),[r,d]=a.useState(!1),m=a.useRef({onOutput:k,onExit:x,onError:b});m.current={onOutput:k,onExit:x,onError:b},a.useEffect(()=>{const n=j.getSocket();g(n.connected);const u=()=>g(!0),v=()=>{g(!1),d(!1)},N=l=>{l.sessionId===c&&m.current.onOutput?.(l.data)},w=l=>{l.sessionId===c&&(d(!1),m.current.onExit?.(l.exitCode))},S=l=>{l.sessionId===c&&m.current.onError?.(l.message)};return n.on("connect",u),n.on("disconnect",v),n.on(E.SESSION_STDOUT,N),n.on(E.SESSION_EXIT,w),n.on(E.SESSION_ERROR,S),g(n.connected),()=>{n.off("connect",u),n.off("disconnect",v),n.off(E.SESSION_STDOUT,N),n.off(E.SESSION_EXIT,w),n.off(E.SESSION_ERROR,S),d(!1)}},[c]);const i=a.useCallback(()=>new Promise(n=>{if(!j.getSocket().connected){n(!1);return}d(!0),n(!0)}),[]),y=a.useCallback(()=>{d(!1)},[]),C=a.useCallback(n=>{j.getSocket().emit(T.INPUT,{sessionId:c,data:n})},[c]),h=a.useCallback((n,u)=>{j.getSocket().emit(T.RESIZE,{sessionId:c,cols:n,rows:u})},[c]);return{isConnected:p,isAttached:r,attach:i,detach:y,sendInput:C,resize:h}}function $({className:s,...c}){return t.jsx("div",{"data-slot":"card",className:M("bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm",s),...c})}function K(){const{t:s}=U(),[c,k]=a.useState([]),[x,b]=a.useState(""),[p,g]=a.useState(""),[r,d]=a.useState(null),[m,i]=a.useState([]),[y,C]=a.useState(!1),[h,n]=a.useState(""),u=a.useRef(null),v=a.useCallback(e=>{i(o=>{const f=o[o.length-1];return f&&f.role==="agent"?[...o.slice(0,-1),{...f,content:f.content+e}]:[...o,{role:"agent",content:e,timestamp:new Date}]})},[]),N=a.useCallback(e=>{i(o=>[...o,{role:"agent",content:`
1
+ import{r as a,w as j,S as E,C as T,j as t,d as M,u as U,i as I}from"./index-RxbHMWXV.js";import{B as O}from"./button-BUA8P726.js";function P(s){const{sessionId:c,onOutput:k,onExit:x,onError:b}=s,[p,g]=a.useState(()=>j.isConnected()),[r,d]=a.useState(!1),m=a.useRef({onOutput:k,onExit:x,onError:b});m.current={onOutput:k,onExit:x,onError:b},a.useEffect(()=>{const n=j.getSocket();g(n.connected);const u=()=>g(!0),v=()=>{g(!1),d(!1)},N=l=>{l.sessionId===c&&m.current.onOutput?.(l.data)},w=l=>{l.sessionId===c&&(d(!1),m.current.onExit?.(l.exitCode))},S=l=>{l.sessionId===c&&m.current.onError?.(l.message)};return n.on("connect",u),n.on("disconnect",v),n.on(E.SESSION_STDOUT,N),n.on(E.SESSION_EXIT,w),n.on(E.SESSION_ERROR,S),g(n.connected),()=>{n.off("connect",u),n.off("disconnect",v),n.off(E.SESSION_STDOUT,N),n.off(E.SESSION_EXIT,w),n.off(E.SESSION_ERROR,S),d(!1)}},[c]);const i=a.useCallback(()=>new Promise(n=>{if(!j.getSocket().connected){n(!1);return}d(!0),n(!0)}),[]),y=a.useCallback(()=>{d(!1)},[]),C=a.useCallback(n=>{j.getSocket().emit(T.INPUT,{sessionId:c,data:n})},[c]),h=a.useCallback((n,u)=>{j.getSocket().emit(T.RESIZE,{sessionId:c,cols:n,rows:u})},[c]);return{isConnected:p,isAttached:r,attach:i,detach:y,sendInput:C,resize:h}}function $({className:s,...c}){return t.jsx("div",{"data-slot":"card",className:M("bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm",s),...c})}function K(){const{t:s}=U(),[c,k]=a.useState([]),[x,b]=a.useState(""),[p,g]=a.useState(""),[r,d]=a.useState(null),[m,i]=a.useState([]),[y,C]=a.useState(!1),[h,n]=a.useState(""),u=a.useRef(null),v=a.useCallback(e=>{i(o=>{const f=o[o.length-1];return f&&f.role==="agent"?[...o.slice(0,-1),{...f,content:f.content+e}]:[...o,{role:"agent",content:e,timestamp:new Date}]})},[]),N=a.useCallback(e=>{i(o=>[...o,{role:"agent",content:`
2
2
  [进程退出,退出码: ${e}]`,timestamp:new Date}]),d(null)},[]),w=a.useCallback(e=>{i(o=>[...o,{role:"agent",content:`
3
3
  [错误: ${e}]`,timestamp:new Date}])},[]),{isConnected:S,isAttached:l,attach:D}=P({sessionId:r||"",onOutput:v,onExit:N,onError:w});a.useEffect(()=>{I.get("/demo/agents").then(e=>{k(e.agents);const o=e.agents.find(f=>f.available);o&&b(o.type)})},[]),a.useEffect(()=>{u.current?.scrollIntoView({behavior:"smooth"})},[m]),a.useEffect(()=>{r&&S&&!l&&D()},[r,S,l,D]);const R=async()=>{if(!(!x||!p.trim())){C(!0),i([{role:"user",content:p,timestamp:new Date}]);try{const e=await I.post("/demo/start",{agentType:x,prompt:p.trim()});d(e.sessionId),g("")}catch(e){i(o=>[...o,{role:"agent",content:s("启动失败: {message}",{message:e instanceof Error?e.message:s("未知错误")}),timestamp:new Date}])}finally{C(!1)}}},A=async()=>{if(!r||!h.trim())return;const e=h.trim();i(o=>[...o,{role:"user",content:e,timestamp:new Date}]),n("");try{await I.post(`/demo/${r}/message`,{message:e})}catch(o){i(f=>[...f,{role:"agent",content:s("发送失败: {message}",{message:o instanceof Error?o.message:s("未知错误")}),timestamp:new Date}])}},_=async()=>{if(r)try{await I.post(`/demo/${r}/stop`),i(e=>[...e,{role:"agent",content:`
4
4
  [${s("会话已停止")}]`,timestamp:new Date}]),d(null)}catch(e){console.error("Stop failed:",e)}};return t.jsxs("div",{className:"flex flex-col h-full max-w-4xl mx-auto p-4 gap-4",children:[t.jsx("h1",{className:"text-2xl font-bold",children:s("Agent 交互演示")}),!r&&t.jsxs($,{className:"p-4",children:[t.jsx("h2",{className:"text-lg font-semibold mb-3",children:s("选择 Agent")}),t.jsx("div",{className:"flex gap-2 flex-wrap mb-4",children:c.map(e=>t.jsxs(O,{variant:x===e.type?"default":"outline",disabled:!e.available,onClick:()=>b(e.type),children:[e.name,e.available&&e.version&&` (${e.version})`,!e.available&&s(" (不可用)")]},e.type))}),t.jsxs("div",{className:"flex gap-2",children:[t.jsx("input",{type:"text",value:p,onChange:e=>g(e.target.value),onKeyDown:e=>e.key==="Enter"&&!e.nativeEvent.isComposing&&e.nativeEvent.keyCode!==229&&R(),placeholder:s("输入你的问题或任务..."),className:"flex-1 px-3 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"}),t.jsx(O,{onClick:R,disabled:y||!x||!p.trim(),children:s(y?"启动中...":"开始")})]})]}),t.jsxs($,{className:"flex-1 p-4 overflow-hidden flex flex-col",children:[t.jsxs("div",{className:"flex justify-between items-center mb-3",children:[t.jsx("h2",{className:"text-lg font-semibold",children:s("对话")}),r&&t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx("span",{className:"text-sm text-gray-500",children:s(S?l?"已连接":"连接中...":"未连接")}),t.jsx(O,{variant:"outline",size:"sm",onClick:_,children:s("停止")})]})]}),t.jsxs("div",{className:"flex-1 overflow-y-auto space-y-3",children:[m.length===0?t.jsx("div",{className:"text-gray-400 text-center py-8",children:s("选择 Agent 并输入问题开始对话")}):m.map((e,o)=>t.jsxs("div",{className:`p-3 rounded-lg ${e.role==="user"?"bg-blue-100 ml-8":"bg-gray-100 mr-8"}`,children:[t.jsx("div",{className:"text-xs text-gray-500 mb-1",children:e.role==="user"?s("你"):"Agent"}),t.jsx("pre",{className:"whitespace-pre-wrap font-mono text-sm",children:e.content})]},o)),t.jsx("div",{ref:u})]}),r&&t.jsxs("div",{className:"flex gap-2 mt-3 pt-3 border-t",children:[t.jsx("input",{type:"text",value:h,onChange:e=>n(e.target.value),onKeyDown:e=>e.key==="Enter"&&!e.repeat&&!e.nativeEvent.isComposing&&e.nativeEvent.keyCode!==229&&A(),placeholder:s("发送后续消息..."),className:"flex-1 px-3 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"}),t.jsx(O,{onClick:A,disabled:!h.trim(),children:s("发送")})]})]})]})}export{K as DemoPage};
@@ -1 +1 @@
1
- import{u as w,a as y,b as C,c as _,r as o,t as u,j as e}from"./index-BAz6UxmL.js";import{S as f}from"./select-kVmZCXo9.js";import{u as A}from"./use-providers-CcFzAUyf.js";import{S as E}from"./SettingsSection-D0Zzbbhp.js";import"./chevron-down-C735lPj9.js";import"./check-KjbNKANU.js";const k=[{value:"zh-CN",label:"简体中文"},{value:"en",label:"English"}],c="__follow_task__";function x({label:d,description:n,children:t,border:a=!0}){return e.jsxs("div",{className:`flex flex-col gap-3 py-5 sm:flex-row sm:items-start sm:justify-between sm:gap-8 ${a?"border-b border-neutral-100":""}`,children:[e.jsxs("div",{className:"min-w-0 sm:max-w-[360px]",children:[e.jsx("div",{className:"text-[13px] font-medium text-neutral-900",children:d}),n&&e.jsx("p",{className:"mt-0.5 text-[12px] leading-relaxed text-neutral-500",children:n})]}),e.jsx("div",{className:"w-full sm:w-[260px] shrink-0",children:t})]})}function G(){const{locale:d,setLocale:n,t}=w(),{data:a}=y(),{data:b}=A(),{data:l}=C(),r=_(),[h,g]=o.useState(c),[m,p]=o.useState(""),[v,i]=o.useState(!1);o.useEffect(()=>{!a||!l||(g(a.commitMessageProviderId||c),p(a.commitMessagePrompt||l.prompt),i(!1))},[a,l]);const j=[{value:c,label:t("跟随任务")},...(b??[]).filter(s=>s.availability.type!=="NOT_FOUND").map(s=>({value:s.provider.id,label:s.provider.name}))],N=o.useCallback(s=>{g(s);const P=s===c?null:s;r.mutate({commitMessageProviderId:P},{onError:()=>u.error(t("保存失败"))})},[r,t]),S=o.useCallback(()=>{const s=m.trim()||null;r.mutate({commitMessagePrompt:s},{onSuccess:()=>{i(!1),u.success(t("已保存"))},onError:()=>u.error(t("保存失败"))})},[m,r,t]);return e.jsxs(E,{children:[e.jsx("div",{className:"mb-1",children:e.jsx("h2",{className:"text-base font-semibold text-neutral-900",children:t("通用设置")})}),e.jsx(x,{label:t("显示语言"),description:t("界面语言会保存到本地数据库,重启后继续生效。"),children:e.jsx(f,{value:d,onChange:s=>n(s),options:k})}),e.jsx("div",{className:"mt-8 mb-2",children:e.jsx("h3",{className:"text-[13px] font-semibold text-neutral-900 uppercase tracking-wide text-neutral-500",children:t("Git Commit Message")})}),e.jsx(x,{label:t("Agent 渠道"),description:t('"跟随任务"表示使用当前任务所用的 Agent 渠道。选择具体渠道可使用更经济的模型。'),children:e.jsx(f,{value:h,onChange:N,options:j})}),e.jsx(x,{label:t("提示词模板"),description:t("自定义生成 commit message 的提示词。留空则使用内置默认模板。"),border:!1,children:e.jsxs("div",{className:"space-y-2",children:[e.jsx("textarea",{value:m,onChange:s=>{p(s.target.value),i(!0)},rows:5,className:"w-full rounded-lg border border-neutral-200 bg-neutral-50/50 px-3 py-2 text-sm font-mono leading-relaxed transition-colors focus:border-neutral-400 focus:bg-white focus:outline-none resize-y"}),v&&e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("button",{onClick:S,disabled:r.isPending,className:"rounded-lg bg-neutral-900 px-3.5 py-1.5 text-xs font-medium text-white transition-colors hover:bg-neutral-800 disabled:opacity-50",children:r.isPending?t("保存中..."):t("保存")}),e.jsx("button",{onClick:()=>{p(a?.commitMessagePrompt||l?.prompt||""),i(!1)},className:"rounded-lg px-3 py-1.5 text-xs text-neutral-500 transition-colors hover:text-neutral-900",children:t("取消")})]})]})})]})}export{G as GeneralSettingsPage};
1
+ import{u as w,a as y,b as C,c as _,r as o,t as u,j as e}from"./index-RxbHMWXV.js";import{S as f}from"./select-BMlH2AuL.js";import{u as A}from"./use-providers-DVP6emIi.js";import{S as E}from"./SettingsSection-pLJ3msrT.js";import"./chevron-down-B931AgE2.js";import"./check-BYuuXc71.js";const k=[{value:"zh-CN",label:"简体中文"},{value:"en",label:"English"}],c="__follow_task__";function x({label:d,description:n,children:t,border:a=!0}){return e.jsxs("div",{className:`flex flex-col gap-3 py-5 sm:flex-row sm:items-start sm:justify-between sm:gap-8 ${a?"border-b border-neutral-100":""}`,children:[e.jsxs("div",{className:"min-w-0 sm:max-w-[360px]",children:[e.jsx("div",{className:"text-[13px] font-medium text-neutral-900",children:d}),n&&e.jsx("p",{className:"mt-0.5 text-[12px] leading-relaxed text-neutral-500",children:n})]}),e.jsx("div",{className:"w-full sm:w-[260px] shrink-0",children:t})]})}function G(){const{locale:d,setLocale:n,t}=w(),{data:a}=y(),{data:b}=A(),{data:l}=C(),r=_(),[h,g]=o.useState(c),[m,p]=o.useState(""),[v,i]=o.useState(!1);o.useEffect(()=>{!a||!l||(g(a.commitMessageProviderId||c),p(a.commitMessagePrompt||l.prompt),i(!1))},[a,l]);const j=[{value:c,label:t("跟随任务")},...(b??[]).filter(s=>s.availability.type!=="NOT_FOUND").map(s=>({value:s.provider.id,label:s.provider.name}))],N=o.useCallback(s=>{g(s);const P=s===c?null:s;r.mutate({commitMessageProviderId:P},{onError:()=>u.error(t("保存失败"))})},[r,t]),S=o.useCallback(()=>{const s=m.trim()||null;r.mutate({commitMessagePrompt:s},{onSuccess:()=>{i(!1),u.success(t("已保存"))},onError:()=>u.error(t("保存失败"))})},[m,r,t]);return e.jsxs(E,{children:[e.jsx("div",{className:"mb-1",children:e.jsx("h2",{className:"text-base font-semibold text-neutral-900",children:t("通用设置")})}),e.jsx(x,{label:t("显示语言"),description:t("界面语言会保存到本地数据库,重启后继续生效。"),children:e.jsx(f,{value:d,onChange:s=>n(s),options:k})}),e.jsx("div",{className:"mt-8 mb-2",children:e.jsx("h3",{className:"text-[13px] font-semibold text-neutral-900 uppercase tracking-wide text-neutral-500",children:t("Git Commit Message")})}),e.jsx(x,{label:t("Agent 渠道"),description:t('"跟随任务"表示使用当前任务所用的 Agent 渠道。选择具体渠道可使用更经济的模型。'),children:e.jsx(f,{value:h,onChange:N,options:j})}),e.jsx(x,{label:t("提示词模板"),description:t("自定义生成 commit message 的提示词。留空则使用内置默认模板。"),border:!1,children:e.jsxs("div",{className:"space-y-2",children:[e.jsx("textarea",{value:m,onChange:s=>{p(s.target.value),i(!0)},rows:5,className:"w-full rounded-lg border border-neutral-200 bg-neutral-50/50 px-3 py-2 text-sm font-mono leading-relaxed transition-colors focus:border-neutral-400 focus:bg-white focus:outline-none resize-y"}),v&&e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("button",{onClick:S,disabled:r.isPending,className:"rounded-lg bg-neutral-900 px-3.5 py-1.5 text-xs font-medium text-white transition-colors hover:bg-neutral-800 disabled:opacity-50",children:r.isPending?t("保存中..."):t("保存")}),e.jsx("button",{onClick:()=>{p(a?.commitMessagePrompt||l?.prompt||""),i(!1)},className:"rounded-lg px-3 py-1.5 text-xs text-neutral-500 transition-colors hover:text-neutral-900",children:t("取消")})]})]})})]})}export{G as GeneralSettingsPage};
@@ -1 +1 @@
1
- import{r as i,j as n,d as o}from"./index-BAz6UxmL.js";function d(r){const t=r.trim();if(!t)return"?";const e=t.split(/\s+/).filter(Boolean);return e.length>=2?`${e[0][0]??""}${e[1][0]??""}`.toUpperCase():Array.from(t).slice(0,2).join("").toUpperCase()}function a(r){const t=r.trim();return/^#([0-9a-f]{3,8})$/i.test(t)||/^rgba?\(/i.test(t)||/^hsla?\(/i.test(t)}function l(r){const t=r.trim();return t.startsWith("/")||t.startsWith("http://")||t.startsWith("https://")||t.startsWith("data:image/")||t.startsWith("blob:")}function h(r,t){const e=r?.trim()??"";return!e||a(e)||l(e)?d(t):e.length<=2?e.toUpperCase():e.slice(0,2).toUpperCase()}function p(r){const t=r?.trim()??"";if(!(!t||!a(t)))return{backgroundColor:t,color:"#ffffff"}}function g({name:r,avatar:t,className:e}){const[u,c]=i.useState(null),s=t?.trim()??"",f=!!s&&l(s)&&u!==s,m=i.useMemo(()=>h(s,r),[r,s]);return f?n.jsx("img",{src:s,alt:r,loading:"lazy",onError:()=>c(s),className:o("h-7 w-7 shrink-0 rounded-full border border-neutral-200 bg-white object-cover",e)}):n.jsx("div",{className:o("flex h-7 w-7 shrink-0 items-center justify-center rounded-full border border-neutral-200 bg-neutral-100 text-[10px] font-semibold text-neutral-600",e),style:p(s),"aria-label":r,children:m})}export{g as M};
1
+ import{r as i,j as n,d as o}from"./index-RxbHMWXV.js";function d(r){const t=r.trim();if(!t)return"?";const e=t.split(/\s+/).filter(Boolean);return e.length>=2?`${e[0][0]??""}${e[1][0]??""}`.toUpperCase():Array.from(t).slice(0,2).join("").toUpperCase()}function a(r){const t=r.trim();return/^#([0-9a-f]{3,8})$/i.test(t)||/^rgba?\(/i.test(t)||/^hsla?\(/i.test(t)}function l(r){const t=r.trim();return t.startsWith("/")||t.startsWith("http://")||t.startsWith("https://")||t.startsWith("data:image/")||t.startsWith("blob:")}function h(r,t){const e=r?.trim()??"";return!e||a(e)||l(e)?d(t):e.length<=2?e.toUpperCase():e.slice(0,2).toUpperCase()}function p(r){const t=r?.trim()??"";if(!(!t||!a(t)))return{backgroundColor:t,color:"#ffffff"}}function g({name:r,avatar:t,className:e}){const[u,c]=i.useState(null),s=t?.trim()??"",f=!!s&&l(s)&&u!==s,m=i.useMemo(()=>h(s,r),[r,s]);return f?n.jsx("img",{src:s,alt:r,loading:"lazy",onError:()=>c(s),className:o("h-7 w-7 shrink-0 rounded-full border border-neutral-200 bg-white object-cover",e)}):n.jsx("div",{className:o("flex h-7 w-7 shrink-0 items-center justify-center rounded-full border border-neutral-200 bg-neutral-100 text-[10px] font-semibold text-neutral-600",e),style:p(s),"aria-label":r,children:m})}export{g as M};
@@ -1 +1 @@
1
- import{e as q,f as E,g as z,h as v,q as k,i as x,u as B,r as i,j as e,B as R,d as j}from"./index-BAz6UxmL.js";import{B as g}from"./button-C-IDw2d8.js";import{S as L}from"./select-kVmZCXo9.js";import{S as N}from"./SettingsSection-D0Zzbbhp.js";import{M as F}from"./message-square-CIyucdyo.js";import{L as M,C as W}from"./loader-circle-BLO3w-ze.js";import{C as A}from"./circle-check-CSlvn06a.js";import"./chevron-down-C735lPj9.js";import"./check-KjbNKANU.js";const K=[["path",{d:"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71",key:"1cjeqo"}],["path",{d:"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71",key:"19qd67"}]],Q=q("link",K);function O(){return E({queryKey:k.notifications.settings,queryFn:()=>x.get("/notifications/settings")})}function _(){const t=z();return v({mutationFn:n=>x.put("/notifications/settings",n),onSuccess:()=>{t.invalidateQueries({queryKey:k.notifications.settings})}})}function D(){return v({mutationFn:t=>x.post("/notifications/test",t)})}function te(){const{t}=B(),{data:n,isLoading:y}=O(),r=_(),l=D(),w=[{value:"none",label:t("关闭")},{value:"feishu",label:t("飞书 Webhook")}],[a,h]=i.useState({webhookUrl:"",baseUrl:"",titleTemplate:"",bodyTemplate:""}),[d,p]=i.useState(!1),[b,o]=i.useState("idle"),u=i.useRef(void 0);if(i.useEffect(()=>{n&&!d&&h({webhookUrl:n.feishuWebhookUrl??"",baseUrl:n.thirdPartyBaseUrl??"",titleTemplate:n.taskInReviewTitleTemplate??"",bodyTemplate:n.taskInReviewBodyTemplate??""})},[n,d]),i.useEffect(()=>(l.isSuccess?(o("success"),u.current=setTimeout(()=>o("idle"),3e3)):l.isError&&(o("error"),u.current=setTimeout(()=>o("idle"),5e3)),()=>clearTimeout(u.current)),[l.isSuccess,l.isError]),y)return e.jsx(N,{children:e.jsx("div",{className:"flex items-center justify-center py-20",children:e.jsx("div",{className:"h-5 w-5 animate-spin rounded-full border-2 border-neutral-200 border-t-neutral-600"})})});const m=n?.osNotificationEnabled??!0,f=n?.thirdPartyChannel??"none",c=(s,I)=>{h(P=>({...P,[s]:I})),p(!0)},T=()=>{r.mutate({osNotificationEnabled:!m})},C=s=>{r.mutate({thirdPartyChannel:s})},U=()=>{r.mutate({feishuWebhookUrl:a.webhookUrl.trim()||null,thirdPartyBaseUrl:a.baseUrl.trim()||null,taskInReviewTitleTemplate:a.titleTemplate.trim()||"Agent Tower",taskInReviewBodyTemplate:a.bodyTemplate.trim()||t('✅ "{taskTitle}" 已完成,等待审查')},{onSuccess:()=>p(!1)})},S=()=>{a.webhookUrl.trim()&&l.mutate({channel:"feishu",webhookUrl:a.webhookUrl.trim(),baseUrl:a.baseUrl.trim()||void 0})};return e.jsxs(N,{children:[e.jsx("h2",{className:"text-base font-semibold text-neutral-900 mb-1",children:t("通知设置")}),e.jsxs("div",{className:"flex items-center justify-between py-5 border-b border-neutral-100",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"flex h-8 w-8 items-center justify-center rounded-lg bg-neutral-100 text-neutral-600",children:e.jsx(R,{size:15})}),e.jsxs("div",{children:[e.jsx("div",{className:"text-[13px] font-medium text-neutral-900",children:t("桌面通知")}),e.jsx("div",{className:"text-[12px] text-neutral-500",children:t("任务完成时弹出系统通知")})]})]}),e.jsx("button",{onClick:T,className:j("relative inline-flex h-5 w-9 items-center rounded-full transition-colors",m?"bg-neutral-900":"bg-neutral-200"),children:e.jsx("span",{className:j("inline-block h-3.5 w-3.5 rounded-full bg-white transition-transform",m?"translate-x-[18px]":"translate-x-[3px]")})})]}),e.jsxs("div",{className:"py-5 border-b border-neutral-100",children:[e.jsxs("div",{className:"flex items-center gap-3 mb-4",children:[e.jsx("div",{className:"flex h-8 w-8 items-center justify-center rounded-lg bg-neutral-100 text-neutral-600",children:e.jsx(F,{size:15})}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("div",{className:"text-[13px] font-medium text-neutral-900",children:t("第三方通知")}),e.jsx("div",{className:"text-[12px] text-neutral-500",children:t("推送到外部渠道(飞书群机器人等)")})]}),e.jsx("div",{className:"shrink-0 w-[160px]",children:e.jsx(L,{value:f,onChange:s=>C(s),options:w})})]}),f==="feishu"&&e.jsxs("div",{className:"ml-11 space-y-4",children:[e.jsxs("div",{children:[e.jsx("label",{className:"block text-[12px] font-medium text-neutral-600 mb-1.5",children:"Webhook URL"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx("input",{type:"text",value:a.webhookUrl,onChange:s=>c("webhookUrl",s.target.value),placeholder:"https://open.feishu.cn/open-apis/bot/v2/hook/...",className:"flex-1 min-w-0 rounded-lg border border-neutral-200 bg-white px-3 py-2 text-sm font-mono transition-colors focus:border-neutral-400 focus:outline-none"}),e.jsxs(g,{size:"sm",variant:"outline",onClick:S,disabled:!a.webhookUrl.trim()||l.isPending,className:"shrink-0",children:[l.isPending&&e.jsx(M,{size:12,className:"animate-spin mr-1"}),t("测试")]})]}),b==="success"&&e.jsxs("div",{className:"flex items-center gap-1.5 mt-2 text-xs text-emerald-600",children:[e.jsx(A,{size:12}),t("测试消息发送成功")]}),b==="error"&&e.jsxs("div",{className:"flex items-center gap-1.5 mt-2 text-xs text-red-500",children:[e.jsx(W,{size:12}),t("发送失败,请检查 Webhook 地址")]})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-[12px] font-medium text-neutral-600 mb-1.5",children:e.jsxs("span",{className:"flex items-center gap-1.5",children:[e.jsx(Q,{size:11,className:"text-neutral-400"}),t("跳转地址")]})}),e.jsx("input",{type:"text",value:a.baseUrl,onChange:s=>c("baseUrl",s.target.value),placeholder:"http://localhost:5173",className:"w-full rounded-lg border border-neutral-200 bg-white px-3 py-2 text-sm font-mono transition-colors focus:border-neutral-400 focus:outline-none"}),e.jsx("p",{className:"mt-1 text-[11px] text-neutral-400",children:t('通知卡片中的"查看任务"按钮跳转地址前缀')})]})]})]}),e.jsxs("div",{className:"py-5",children:[e.jsxs("div",{className:"mb-4",children:[e.jsx("h3",{className:"text-[12px] font-semibold uppercase tracking-wide text-neutral-400",children:t("通知模板")}),e.jsx("p",{className:"mt-1 text-[11px] text-neutral-400",children:t("支持变量: {taskTitle}, {taskId}, {projectId}, {projectName}, {status}",{taskTitle:"{taskTitle}",taskId:"{taskId}",projectId:"{projectId}",projectName:"{projectName}",status:"{status}"})})]}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsxs("div",{children:[e.jsx("label",{className:"block text-[12px] font-medium text-neutral-600 mb-1.5",children:t("标题")}),e.jsx("input",{type:"text",value:a.titleTemplate,onChange:s=>c("titleTemplate",s.target.value),placeholder:"Agent Tower",className:"w-full rounded-lg border border-neutral-200 bg-white px-3 py-2 text-sm transition-colors focus:border-neutral-400 focus:outline-none"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-[12px] font-medium text-neutral-600 mb-1.5",children:t("内容")}),e.jsx("input",{type:"text",value:a.bodyTemplate,onChange:s=>c("bodyTemplate",s.target.value),placeholder:t('✅ "{taskTitle}" 已完成,等待审查'),className:"w-full rounded-lg border border-neutral-200 bg-white px-3 py-2 text-sm transition-colors focus:border-neutral-400 focus:outline-none"})]})]})]}),d&&e.jsx("div",{className:"sticky bottom-0 -mx-5 sm:-mx-8 px-5 sm:px-8 py-3 bg-white/90 backdrop-blur border-t border-neutral-100",children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-xs text-neutral-500",children:t("有未保存的更改")}),e.jsx(g,{size:"sm",onClick:U,disabled:r.isPending,children:r.isPending?t("保存中..."):t("保存")})]})})]})}export{te as NotificationSettingsPage};
1
+ import{e as q,f as E,g as z,h as v,q as k,i as x,u as B,r as i,j as e,B as R,d as j}from"./index-RxbHMWXV.js";import{B as g}from"./button-BUA8P726.js";import{S as L}from"./select-BMlH2AuL.js";import{S as N}from"./SettingsSection-pLJ3msrT.js";import{M as F}from"./message-square-C8lb-TDo.js";import{L as M,C as W}from"./loader-circle-stJcjnm-.js";import{C as A}from"./circle-check-C7xXtl8B.js";import"./chevron-down-B931AgE2.js";import"./check-BYuuXc71.js";const K=[["path",{d:"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71",key:"1cjeqo"}],["path",{d:"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71",key:"19qd67"}]],Q=q("link",K);function O(){return E({queryKey:k.notifications.settings,queryFn:()=>x.get("/notifications/settings")})}function _(){const t=z();return v({mutationFn:n=>x.put("/notifications/settings",n),onSuccess:()=>{t.invalidateQueries({queryKey:k.notifications.settings})}})}function D(){return v({mutationFn:t=>x.post("/notifications/test",t)})}function te(){const{t}=B(),{data:n,isLoading:y}=O(),r=_(),l=D(),w=[{value:"none",label:t("关闭")},{value:"feishu",label:t("飞书 Webhook")}],[a,h]=i.useState({webhookUrl:"",baseUrl:"",titleTemplate:"",bodyTemplate:""}),[d,p]=i.useState(!1),[b,o]=i.useState("idle"),u=i.useRef(void 0);if(i.useEffect(()=>{n&&!d&&h({webhookUrl:n.feishuWebhookUrl??"",baseUrl:n.thirdPartyBaseUrl??"",titleTemplate:n.taskInReviewTitleTemplate??"",bodyTemplate:n.taskInReviewBodyTemplate??""})},[n,d]),i.useEffect(()=>(l.isSuccess?(o("success"),u.current=setTimeout(()=>o("idle"),3e3)):l.isError&&(o("error"),u.current=setTimeout(()=>o("idle"),5e3)),()=>clearTimeout(u.current)),[l.isSuccess,l.isError]),y)return e.jsx(N,{children:e.jsx("div",{className:"flex items-center justify-center py-20",children:e.jsx("div",{className:"h-5 w-5 animate-spin rounded-full border-2 border-neutral-200 border-t-neutral-600"})})});const m=n?.osNotificationEnabled??!0,f=n?.thirdPartyChannel??"none",c=(s,I)=>{h(P=>({...P,[s]:I})),p(!0)},T=()=>{r.mutate({osNotificationEnabled:!m})},C=s=>{r.mutate({thirdPartyChannel:s})},U=()=>{r.mutate({feishuWebhookUrl:a.webhookUrl.trim()||null,thirdPartyBaseUrl:a.baseUrl.trim()||null,taskInReviewTitleTemplate:a.titleTemplate.trim()||"Agent Tower",taskInReviewBodyTemplate:a.bodyTemplate.trim()||t('✅ "{taskTitle}" 已完成,等待审查')},{onSuccess:()=>p(!1)})},S=()=>{a.webhookUrl.trim()&&l.mutate({channel:"feishu",webhookUrl:a.webhookUrl.trim(),baseUrl:a.baseUrl.trim()||void 0})};return e.jsxs(N,{children:[e.jsx("h2",{className:"text-base font-semibold text-neutral-900 mb-1",children:t("通知设置")}),e.jsxs("div",{className:"flex items-center justify-between py-5 border-b border-neutral-100",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"flex h-8 w-8 items-center justify-center rounded-lg bg-neutral-100 text-neutral-600",children:e.jsx(R,{size:15})}),e.jsxs("div",{children:[e.jsx("div",{className:"text-[13px] font-medium text-neutral-900",children:t("桌面通知")}),e.jsx("div",{className:"text-[12px] text-neutral-500",children:t("任务完成时弹出系统通知")})]})]}),e.jsx("button",{onClick:T,className:j("relative inline-flex h-5 w-9 items-center rounded-full transition-colors",m?"bg-neutral-900":"bg-neutral-200"),children:e.jsx("span",{className:j("inline-block h-3.5 w-3.5 rounded-full bg-white transition-transform",m?"translate-x-[18px]":"translate-x-[3px]")})})]}),e.jsxs("div",{className:"py-5 border-b border-neutral-100",children:[e.jsxs("div",{className:"flex items-center gap-3 mb-4",children:[e.jsx("div",{className:"flex h-8 w-8 items-center justify-center rounded-lg bg-neutral-100 text-neutral-600",children:e.jsx(F,{size:15})}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("div",{className:"text-[13px] font-medium text-neutral-900",children:t("第三方通知")}),e.jsx("div",{className:"text-[12px] text-neutral-500",children:t("推送到外部渠道(飞书群机器人等)")})]}),e.jsx("div",{className:"shrink-0 w-[160px]",children:e.jsx(L,{value:f,onChange:s=>C(s),options:w})})]}),f==="feishu"&&e.jsxs("div",{className:"ml-11 space-y-4",children:[e.jsxs("div",{children:[e.jsx("label",{className:"block text-[12px] font-medium text-neutral-600 mb-1.5",children:"Webhook URL"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx("input",{type:"text",value:a.webhookUrl,onChange:s=>c("webhookUrl",s.target.value),placeholder:"https://open.feishu.cn/open-apis/bot/v2/hook/...",className:"flex-1 min-w-0 rounded-lg border border-neutral-200 bg-white px-3 py-2 text-sm font-mono transition-colors focus:border-neutral-400 focus:outline-none"}),e.jsxs(g,{size:"sm",variant:"outline",onClick:S,disabled:!a.webhookUrl.trim()||l.isPending,className:"shrink-0",children:[l.isPending&&e.jsx(M,{size:12,className:"animate-spin mr-1"}),t("测试")]})]}),b==="success"&&e.jsxs("div",{className:"flex items-center gap-1.5 mt-2 text-xs text-emerald-600",children:[e.jsx(A,{size:12}),t("测试消息发送成功")]}),b==="error"&&e.jsxs("div",{className:"flex items-center gap-1.5 mt-2 text-xs text-red-500",children:[e.jsx(W,{size:12}),t("发送失败,请检查 Webhook 地址")]})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-[12px] font-medium text-neutral-600 mb-1.5",children:e.jsxs("span",{className:"flex items-center gap-1.5",children:[e.jsx(Q,{size:11,className:"text-neutral-400"}),t("跳转地址")]})}),e.jsx("input",{type:"text",value:a.baseUrl,onChange:s=>c("baseUrl",s.target.value),placeholder:"http://localhost:5173",className:"w-full rounded-lg border border-neutral-200 bg-white px-3 py-2 text-sm font-mono transition-colors focus:border-neutral-400 focus:outline-none"}),e.jsx("p",{className:"mt-1 text-[11px] text-neutral-400",children:t('通知卡片中的"查看任务"按钮跳转地址前缀')})]})]})]}),e.jsxs("div",{className:"py-5",children:[e.jsxs("div",{className:"mb-4",children:[e.jsx("h3",{className:"text-[12px] font-semibold uppercase tracking-wide text-neutral-400",children:t("通知模板")}),e.jsx("p",{className:"mt-1 text-[11px] text-neutral-400",children:t("支持变量: {taskTitle}, {taskId}, {projectId}, {projectName}, {status}",{taskTitle:"{taskTitle}",taskId:"{taskId}",projectId:"{projectId}",projectName:"{projectName}",status:"{status}"})})]}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsxs("div",{children:[e.jsx("label",{className:"block text-[12px] font-medium text-neutral-600 mb-1.5",children:t("标题")}),e.jsx("input",{type:"text",value:a.titleTemplate,onChange:s=>c("titleTemplate",s.target.value),placeholder:"Agent Tower",className:"w-full rounded-lg border border-neutral-200 bg-white px-3 py-2 text-sm transition-colors focus:border-neutral-400 focus:outline-none"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-[12px] font-medium text-neutral-600 mb-1.5",children:t("内容")}),e.jsx("input",{type:"text",value:a.bodyTemplate,onChange:s=>c("bodyTemplate",s.target.value),placeholder:t('✅ "{taskTitle}" 已完成,等待审查'),className:"w-full rounded-lg border border-neutral-200 bg-white px-3 py-2 text-sm transition-colors focus:border-neutral-400 focus:outline-none"})]})]})]}),d&&e.jsx("div",{className:"sticky bottom-0 -mx-5 sm:-mx-8 px-5 sm:px-8 py-3 bg-white/90 backdrop-blur border-t border-neutral-100",children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-xs text-neutral-500",children:t("有未保存的更改")}),e.jsx(g,{size:"sm",onClick:U,disabled:r.isPending,children:r.isPending?t("保存中..."):t("保存")})]})})]})}export{te as NotificationSettingsPage};
@@ -1,3 +1,3 @@
1
- import{u as E,r as x,j as e,d as C}from"./index-BAz6UxmL.js";import{u as I,a as J,b as L,c as M}from"./use-profiles-Bvj_EW-7.js";import{B as S}from"./button-C-IDw2d8.js";import{M as U,P as z,T as B}from"./modal-D_VShm6D.js";import{C as G}from"./confirm-dialog-BtsxywSG.js";import{S as w}from"./SettingsSection-D0Zzbbhp.js";import{C as _}from"./chevron-down-C735lPj9.js";import{P as $}from"./pencil-CdJXJig-.js";function R(t){const d=Object.entries(t);return d.length===0?"(empty)":d.map(([m,p])=>`${m}: ${JSON.stringify(p)}`).join(", ")}const v={CLAUDE_CODE:"Claude Code",GEMINI_CLI:"Gemini CLI",CURSOR_AGENT:"Cursor Agent"};function F({agentType:t,variants:d,isBuiltIn:m,onEdit:p,onNew:h,onDelete:f}){const{t:s}=E(),[a,g]=x.useState(!0),c=Object.entries(d);return e.jsxs("div",{className:"rounded-lg border border-neutral-200 overflow-hidden",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3 px-4 py-3 bg-neutral-50/60",children:[e.jsxs("button",{type:"button",onClick:()=>g(r=>!r),className:"flex items-center gap-3 hover:opacity-80 transition-opacity",children:[e.jsx("h3",{className:"text-[13px] font-semibold text-neutral-900",children:v[t]??t}),e.jsxs("span",{className:"text-[11px] text-neutral-400",children:[c.length," ",s("个变体")]}),e.jsx(_,{size:14,className:C("text-neutral-400 transition-transform",a&&"rotate-180")})]}),e.jsxs("button",{type:"button",onClick:h,className:"flex items-center gap-1 rounded-md px-2 py-1 text-[11px] text-neutral-500 hover:text-neutral-900 hover:bg-white transition-colors",children:[e.jsx(z,{size:12}),s("新增")]})]}),a&&e.jsxs("div",{className:"divide-y divide-neutral-100",children:[c.map(([r,u])=>{const b=m(r);return e.jsxs("div",{className:"flex items-center gap-3 px-4 py-2.5 hover:bg-neutral-50/50 transition-colors",children:[e.jsx("span",{className:C("inline-flex items-center px-2 py-0.5 rounded text-[11px] font-semibold tracking-wide shrink-0",r==="DEFAULT"?"bg-blue-50 text-blue-600":"bg-neutral-100 text-neutral-600"),children:r}),e.jsx("span",{className:"flex-1 min-w-0 text-[12px] text-neutral-400 font-mono truncate",children:R(u)}),b&&e.jsx("span",{className:"shrink-0 text-[10px] text-neutral-300 font-medium",children:s("内置")}),e.jsxs("div",{className:"flex items-center gap-1 shrink-0",children:[e.jsx("button",{onClick:()=>p(r,u),className:"flex h-6 w-6 items-center justify-center rounded text-neutral-400 hover:text-neutral-700 hover:bg-neutral-100 transition-colors",title:s("编辑"),children:e.jsx($,{size:12})}),!b&&e.jsx("button",{onClick:()=>f(r),className:"flex h-6 w-6 items-center justify-center rounded text-neutral-400 hover:text-red-500 hover:bg-red-50 transition-colors",title:s("删除"),children:e.jsx(B,{size:12})})]})]},r)}),c.length===0&&e.jsx("div",{className:"px-4 py-4 text-center text-[12px] text-neutral-400",children:s("暂无变体")})]})]})}function ee(){const{t}=E(),{data:d,isLoading:m}=I(),{data:p}=J(),h=L(),f=M(),[s,a]=x.useState(null),[g,c]=x.useState(""),[r,u]=x.useState(""),[b,j]=x.useState(""),[i,N]=x.useState(null),P=(n,l,o)=>{a({agentType:n,variant:l,config:o,isNew:!1}),u(l),c(JSON.stringify(o,null,2)),j("")},T=n=>{a({agentType:n,variant:"",config:{},isNew:!0}),u(""),c(`{
1
+ import{u as E,r as x,j as e,d as C}from"./index-RxbHMWXV.js";import{u as I,a as J,b as L,c as M}from"./use-profiles-D6cZwU1R.js";import{B as S}from"./button-BUA8P726.js";import{M as U,P as z,T as B}from"./modal-UGrjU63G.js";import{C as G}from"./confirm-dialog-B_wk_zqm.js";import{S as w}from"./SettingsSection-pLJ3msrT.js";import{C as _}from"./chevron-down-B931AgE2.js";import{P as $}from"./pencil-uRBgB4qA.js";function R(t){const d=Object.entries(t);return d.length===0?"(empty)":d.map(([m,p])=>`${m}: ${JSON.stringify(p)}`).join(", ")}const v={CLAUDE_CODE:"Claude Code",GEMINI_CLI:"Gemini CLI",CURSOR_AGENT:"Cursor Agent"};function F({agentType:t,variants:d,isBuiltIn:m,onEdit:p,onNew:h,onDelete:f}){const{t:s}=E(),[a,g]=x.useState(!0),c=Object.entries(d);return e.jsxs("div",{className:"rounded-lg border border-neutral-200 overflow-hidden",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3 px-4 py-3 bg-neutral-50/60",children:[e.jsxs("button",{type:"button",onClick:()=>g(r=>!r),className:"flex items-center gap-3 hover:opacity-80 transition-opacity",children:[e.jsx("h3",{className:"text-[13px] font-semibold text-neutral-900",children:v[t]??t}),e.jsxs("span",{className:"text-[11px] text-neutral-400",children:[c.length," ",s("个变体")]}),e.jsx(_,{size:14,className:C("text-neutral-400 transition-transform",a&&"rotate-180")})]}),e.jsxs("button",{type:"button",onClick:h,className:"flex items-center gap-1 rounded-md px-2 py-1 text-[11px] text-neutral-500 hover:text-neutral-900 hover:bg-white transition-colors",children:[e.jsx(z,{size:12}),s("新增")]})]}),a&&e.jsxs("div",{className:"divide-y divide-neutral-100",children:[c.map(([r,u])=>{const b=m(r);return e.jsxs("div",{className:"flex items-center gap-3 px-4 py-2.5 hover:bg-neutral-50/50 transition-colors",children:[e.jsx("span",{className:C("inline-flex items-center px-2 py-0.5 rounded text-[11px] font-semibold tracking-wide shrink-0",r==="DEFAULT"?"bg-blue-50 text-blue-600":"bg-neutral-100 text-neutral-600"),children:r}),e.jsx("span",{className:"flex-1 min-w-0 text-[12px] text-neutral-400 font-mono truncate",children:R(u)}),b&&e.jsx("span",{className:"shrink-0 text-[10px] text-neutral-300 font-medium",children:s("内置")}),e.jsxs("div",{className:"flex items-center gap-1 shrink-0",children:[e.jsx("button",{onClick:()=>p(r,u),className:"flex h-6 w-6 items-center justify-center rounded text-neutral-400 hover:text-neutral-700 hover:bg-neutral-100 transition-colors",title:s("编辑"),children:e.jsx($,{size:12})}),!b&&e.jsx("button",{onClick:()=>f(r),className:"flex h-6 w-6 items-center justify-center rounded text-neutral-400 hover:text-red-500 hover:bg-red-50 transition-colors",title:s("删除"),children:e.jsx(B,{size:12})})]})]},r)}),c.length===0&&e.jsx("div",{className:"px-4 py-4 text-center text-[12px] text-neutral-400",children:s("暂无变体")})]})]})}function ee(){const{t}=E(),{data:d,isLoading:m}=I(),{data:p}=J(),h=L(),f=M(),[s,a]=x.useState(null),[g,c]=x.useState(""),[r,u]=x.useState(""),[b,j]=x.useState(""),[i,N]=x.useState(null),P=(n,l,o)=>{a({agentType:n,variant:l,config:o,isNew:!1}),u(l),c(JSON.stringify(o,null,2)),j("")},T=n=>{a({agentType:n,variant:"",config:{},isNew:!0}),u(""),c(`{
2
2
 
3
3
  }`),j("")},O=()=>{if(!(!s||!r.trim()))try{const n=JSON.parse(g);j(""),h.mutate({agentType:s.agentType,variant:r.trim().toUpperCase(),config:n},{onSuccess:()=>a(null)})}catch{j(t("JSON 格式错误"))}},k=(n,l)=>{N({agentType:n,variant:l})},D=()=>{i&&f.mutate({agentType:i.agentType,variant:i.variant},{onSettled:()=>N(null)})},V=(n,l)=>!!p?.executors[n]?.[l];if(m)return e.jsx(w,{children:e.jsx("div",{className:"flex items-center justify-center py-20",children:e.jsx("div",{className:"h-5 w-5 animate-spin rounded-full border-2 border-neutral-200 border-t-neutral-600"})})});const y=d?.executors??{};return e.jsxs(w,{children:[e.jsxs("div",{className:"mb-4",children:[e.jsx("h2",{className:"text-base font-semibold text-neutral-900",children:t("Profile 配置")}),e.jsx("p",{className:"mt-0.5 text-[12px] text-neutral-500",children:t("管理 Agent 执行器的配置变体。每个变体定义一组运行参数。")})]}),e.jsx("div",{className:"space-y-3",children:Object.entries(y).map(([n,l])=>e.jsx(F,{agentType:n,variants:l,isBuiltIn:o=>V(n,o),onEdit:(o,A)=>P(n,o,A),onNew:()=>T(n),onDelete:o=>k(n,o)},n))}),Object.keys(y).length===0&&e.jsx("div",{className:"rounded-xl border border-dashed border-neutral-200 bg-neutral-50/50 py-12 text-center",children:e.jsx("p",{className:"text-sm text-neutral-400",children:t("暂无 Profile 配置")})}),e.jsx(U,{isOpen:!!s,onClose:()=>a(null),title:s?.isNew?t("新增 Variant — {agentType}",{agentType:v[s.agentType]??s.agentType}):t("编辑 {variant}",{variant:s?.variant??""}),action:e.jsxs(e.Fragment,{children:[e.jsx(S,{variant:"outline",onClick:()=>a(null),children:t("取消")}),e.jsx(S,{onClick:O,disabled:h.isPending,children:h.isPending?t("保存中..."):t("保存")})]}),children:e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx("label",{className:"block text-[13px] font-medium text-neutral-700 mb-1",children:t("Variant 名称")}),e.jsx("input",{type:"text",value:r,onChange:n=>u(n.target.value),disabled:!s?.isNew,placeholder:t("例如: CUSTOM"),className:"w-full rounded-lg border border-neutral-200 bg-white px-3 py-2 text-sm font-mono transition-colors focus:border-neutral-400 focus:outline-none disabled:bg-neutral-50 disabled:text-neutral-500"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-[13px] font-medium text-neutral-700 mb-1",children:t("配置 (JSON)")}),e.jsx("textarea",{value:g,onChange:n=>{c(n.target.value),j("")},rows:6,className:"w-full rounded-lg border border-neutral-200 bg-neutral-50/50 px-3 py-2 text-sm font-mono transition-colors focus:border-neutral-400 focus:bg-white focus:outline-none resize-none"}),b&&e.jsx("p",{className:"mt-1 text-xs text-red-500",children:b})]})]})}),e.jsx(G,{isOpen:i!==null,onClose:()=>{f.isPending||N(null)},onConfirm:D,title:t("删除 Profile Variant"),description:i?t('确定删除 "{name}"?此操作不可撤销。',{name:`${v[i.agentType]??i.agentType} / ${i.variant}`}):"",confirmText:t("删除"),cancelText:t("取消"),variant:"danger",isLoading:f.isPending})]})}export{ee as ProfileSettingsPage};