@kafca/agentdock 0.1.44 → 0.1.46

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 (126) hide show
  1. package/README.md +76 -11
  2. package/bin/agentdock.mjs +5 -5
  3. package/dist/renderer/assets/{Badge-Qk9qHovH.js → Badge-BIesaDYG.js} +1 -1
  4. package/dist/renderer/assets/Chat-CpataoDh.js +2 -0
  5. package/dist/renderer/assets/{ChatMarkdown-BKdW8OON.js → ChatMarkdown-_Mdmltgv.js} +1 -1
  6. package/dist/renderer/assets/Config-Pe5-zKZk.js +21 -0
  7. package/dist/renderer/assets/CronList-BnaOSPT8.js +1 -0
  8. package/dist/renderer/assets/Dashboard-D05l8GKE.js +26 -0
  9. package/dist/renderer/assets/{EmptyState-kD9yAwtw.js → EmptyState-BDBavDll.js} +1 -1
  10. package/dist/renderer/assets/{KnowledgeDetail-BAMCLrjz.js → KnowledgeDetail-DvR798l_.js} +2 -2
  11. package/dist/renderer/assets/KnowledgeHome-r2ZuvU8-.js +11 -0
  12. package/dist/renderer/assets/Logs-BaljtmAV.js +1 -0
  13. package/dist/renderer/assets/{Modal-DwY4lecS.js → Modal-CXhD_OWR.js} +1 -1
  14. package/dist/renderer/assets/MonitorList-D7tyipbx.js +1 -0
  15. package/dist/renderer/assets/{Page-CnB9ePsb.js → Page-KUuFYgjg.js} +1 -1
  16. package/dist/renderer/assets/ProjectDetail-Ddq94-yu.js +11 -0
  17. package/dist/renderer/assets/ProjectList-CbdHd5Ev.js +1 -0
  18. package/dist/renderer/assets/{Select-zfoksLGB.js → Select-Djc8BXMC.js} +1 -1
  19. package/dist/renderer/assets/SessionChat-DOy0iKQR.js +1 -0
  20. package/dist/renderer/assets/SessionList-DHgl1s1D.js +1 -0
  21. package/dist/renderer/assets/ThreadChat-I7dYibDc.js +23 -0
  22. package/dist/renderer/assets/Workspace-DTocqY-F.js +19 -0
  23. package/dist/renderer/assets/{arrow-left-CNEAuElg.js → arrow-left-CXyya3hP.js} +1 -1
  24. package/dist/renderer/assets/{book-open-BNJMhNI-.js → book-open-9n4Kxc7E.js} +1 -1
  25. package/dist/renderer/assets/bot-C9HBk5XH.js +6 -0
  26. package/dist/renderer/assets/{check-BnclClRU.js → check-CutSg9a5.js} +1 -1
  27. package/dist/renderer/assets/{chevron-down-Bh53e0O-.js → chevron-down-DrydR4i3.js} +1 -1
  28. package/dist/renderer/assets/{circle-ClZTWCWO.js → circle-BEjtahw6.js} +1 -1
  29. package/dist/renderer/assets/desktop-DATgk_ka.js +1 -0
  30. package/dist/renderer/assets/{desktop-C6q6wBae.js → desktop-JQkhNOF4.js} +5 -5
  31. package/dist/renderer/assets/en-CmAr_0e6.js +1 -0
  32. package/dist/renderer/assets/es-Cs9x52ca.js +1 -0
  33. package/dist/renderer/assets/{funnel-_5hsz0xI.js → funnel-BhqZpS4f.js} +1 -1
  34. package/dist/renderer/assets/{heart-u4Q1aOqj.js → heart-Dp8Vs-7_.js} +1 -1
  35. package/dist/renderer/assets/{index-BNFx4uYv.js → index-BKpv0P0s.js} +2 -2
  36. package/dist/renderer/assets/index-CO4fGqmv.css +11 -0
  37. package/dist/renderer/assets/{index-B36eowj-.js → index-cI3pWBnN.js} +36 -36
  38. package/dist/renderer/assets/ja-DtvtBRTW.js +1 -0
  39. package/dist/renderer/assets/{pencil-DLh9QNmT.js → pencil-ywcJzeOo.js} +1 -1
  40. package/dist/renderer/assets/{play-BDTk9Scm.js → play-AtN492Cx.js} +1 -1
  41. package/dist/renderer/assets/{plus-BSc8POsz.js → plus-BEj14BBV.js} +1 -1
  42. package/dist/renderer/assets/projects-Clar8lgb.js +1 -0
  43. package/dist/renderer/assets/save-D6ov4CNv.js +11 -0
  44. package/dist/renderer/assets/{search-CniPk7Ey.js → search-C3bvw7AR.js} +1 -1
  45. package/dist/renderer/assets/{server-GsXyQAZm.js → server-C1Uyedyx.js} +1 -1
  46. package/dist/renderer/assets/{session-utils-BDxzgTBC.js → session-utils-DpRwJ6Nh.js} +1 -1
  47. package/dist/renderer/assets/{sessions-CLcKA1Tt.js → sessions-BWmAppwK.js} +1 -1
  48. package/dist/renderer/assets/{shield-check-4i0E3hmf.js → shield-check-CVx1mEs2.js} +1 -1
  49. package/dist/renderer/assets/{trash-2-DhtOCsO5.js → trash-2-o-heXOgs.js} +1 -1
  50. package/dist/renderer/assets/user-dPOzUqIc.js +6 -0
  51. package/dist/renderer/assets/{wifi-off-BHPzPY_B.js → wifi-off-Fz5c3_x_.js} +1 -1
  52. package/dist/renderer/assets/zh-CcJ9vBZj.js +1 -0
  53. package/dist/renderer/assets/zh-TW-elI72AC1.js +1 -0
  54. package/dist/renderer/index.html +2 -2
  55. package/dist-electron/electron/main.js +26 -1
  56. package/dist-electron/packages/core-sdk/src/index.js +28 -0
  57. package/dist-electron/services/local-ai-core/src/acp/local-core-acp-backend.js +111 -62
  58. package/dist-electron/services/local-ai-core/src/acp/local-core-acp-session-coordinator.js +80 -7
  59. package/dist-electron/services/local-ai-core/src/acp/local-core-acp-transport.js +78 -5
  60. package/dist-electron/services/local-ai-core/src/acp/store/external-store.js +98 -0
  61. package/dist-electron/services/local-ai-core/src/acp/store/local-core-acp-store.js +33 -0
  62. package/dist-electron/services/local-ai-core/src/acp/store/model-provider-store.js +88 -0
  63. package/dist-electron/services/local-ai-core/src/acp/store/schema.js +43 -0
  64. package/dist-electron/services/local-ai-core/src/agents/pi/launch.js +2 -119
  65. package/dist-electron/services/local-ai-core/src/agents/pi/provider-materializer.js +148 -0
  66. package/dist-electron/services/local-ai-core/src/channel/lark/inbound.js +55 -1
  67. package/dist-electron/services/local-ai-core/src/channel/lark/local-core-lark-gateway.js +65 -10
  68. package/dist-electron/services/local-ai-core/src/channel/shared/session-command-runtime.js +4 -2
  69. package/dist-electron/services/local-ai-core/src/channel/weixin/local-core-weixin-gateway.js +139 -29
  70. package/dist-electron/services/local-ai-core/src/execution/agent-execution-backend.js +56 -0
  71. package/dist-electron/services/local-ai-core/src/kernel/bootstrap.js +18 -57
  72. package/dist-electron/services/local-ai-core/src/kernel/local-core-errors.js +255 -0
  73. package/dist-electron/services/local-ai-core/src/plugins/builtin/catalog.js +78 -0
  74. package/dist-electron/services/local-ai-core/src/router/workspace-route-config.js +3 -1
  75. package/dist-electron/services/local-ai-core/src/router/workspace-router.js +64 -9
  76. package/dist-electron/services/local-ai-core/src/runtime/agent-runtime-detector.js +5 -2
  77. package/dist-electron/services/local-ai-core/src/runtime/config-migration.js +152 -0
  78. package/dist-electron/services/local-ai-core/src/runtime/deployment-diagnostics.js +175 -0
  79. package/dist-electron/services/local-ai-core/src/runtime/local-core-controller.js +330 -3
  80. package/dist-electron/services/local-ai-core/src/runtime/local-core-runtime-state.js +11 -2
  81. package/dist-electron/services/local-ai-core/src/runtime/provider-config-migration.js +32 -0
  82. package/dist-electron/services/local-ai-core/src/runtime/runtime-detection-service.js +76 -8
  83. package/dist-electron/services/local-ai-core/src/runtime/server-routes.js +62 -0
  84. package/dist-electron/services/local-ai-core/src/runtime/server.js +708 -4
  85. package/dist-electron/services/local-ai-core/src/runtime/standalone.js +13 -3
  86. package/dist-electron/services/local-ai-core/src/sandbox/opensandbox-client.js +113 -0
  87. package/dist-electron/services/local-ai-core/src/sandbox/sandbox-config.js +273 -0
  88. package/dist-electron/services/local-ai-core/src/sandbox/sandbox-manager.js +215 -0
  89. package/dist-electron/services/local-ai-core/src/sandbox/sandbox-stdio-proxy.js +188 -0
  90. package/dist-electron/services/local-ai-core/src/thread/slash-command-registry.js +3 -0
  91. package/dist-electron/services/local-ai-core/src/thread/thread-command-service.js +32 -0
  92. package/dist-electron/services/local-ai-core/src/thread/thread-slash-command-dispatcher.js +71 -0
  93. package/dist-electron/shared/desktop.js +85 -1
  94. package/dist-electron/tests/contracts/architecture-docs.test.js +83 -0
  95. package/dist-electron/tests/electron/plugin-kernel.test.js +225 -18
  96. package/dist-electron/tests/electron/runtime-detection-service.test.js +57 -5
  97. package/dist-electron/tests/electron/sandbox-config.test.js +541 -0
  98. package/dist-electron/tests/electron/workspace-task-store.test.js +257 -0
  99. package/dist-electron/tests/integration/lark-gateway.test.js +139 -0
  100. package/dist-electron/tests/integration/local-core-refactor.test.js +183 -20
  101. package/dist-electron/tests/integration/local-core-routes.test.js +34 -0
  102. package/package.json +2 -3
  103. package/dist/renderer/assets/Chat-BK-fm0Xr.js +0 -2
  104. package/dist/renderer/assets/Config-B93CQGvY.js +0 -16
  105. package/dist/renderer/assets/CronList-Z3TvSRKP.js +0 -1
  106. package/dist/renderer/assets/Dashboard-Ch3QkWwf.js +0 -26
  107. package/dist/renderer/assets/KnowledgeHome-ChvjOfrc.js +0 -11
  108. package/dist/renderer/assets/Logs-Cv0nth3j.js +0 -1
  109. package/dist/renderer/assets/MonitorList-JEvMoWUm.js +0 -1
  110. package/dist/renderer/assets/ProjectDetail-DJa3sMmU.js +0 -11
  111. package/dist/renderer/assets/ProjectList-D6CXumR_.js +0 -1
  112. package/dist/renderer/assets/SessionChat-DUTh4WoM.js +0 -1
  113. package/dist/renderer/assets/SessionList-D9o-lUst.js +0 -1
  114. package/dist/renderer/assets/ThreadChat-BYXlT-Kc.js +0 -23
  115. package/dist/renderer/assets/Workspace-BrhSwRQ-.js +0 -14
  116. package/dist/renderer/assets/desktop-C5vBT0yM.js +0 -1
  117. package/dist/renderer/assets/en-D2SkCrhG.js +0 -1
  118. package/dist/renderer/assets/es-C8UBPhxM.js +0 -1
  119. package/dist/renderer/assets/index-CaQZSRbg.css +0 -11
  120. package/dist/renderer/assets/ja-ChF4vbBL.js +0 -1
  121. package/dist/renderer/assets/plug-BG0JHW6B.js +0 -6
  122. package/dist/renderer/assets/projects-DwfZwxDW.js +0 -1
  123. package/dist/renderer/assets/save-D5AO_G6a.js +0 -6
  124. package/dist/renderer/assets/user-BtC_pVXV.js +0 -11
  125. package/dist/renderer/assets/zh-DIcdHycM.js +0 -1
  126. package/dist/renderer/assets/zh-TW-BtRwreY_.js +0 -1
@@ -15,10 +15,11 @@ const scheduler_run_lifecycle_js_1 = require("../../services/local-ai-core/src/s
15
15
  const lark_execution_policies_js_1 = require("../../services/local-ai-core/src/scheduler/lark-execution-policies.js");
16
16
  const local_schedule_adapter_js_1 = require("../../services/local-ai-core/src/scheduler/local-schedule-adapter.js");
17
17
  const cards_js_1 = require("../../services/local-ai-core/src/channel/lark/cards.js");
18
+ const session_command_runtime_js_1 = require("../../services/local-ai-core/src/channel/shared/session-command-runtime.js");
18
19
  const local_core_acp_backend_js_1 = require("../../services/local-ai-core/src/acp/local-core-acp-backend.js");
19
20
  const local_core_acp_store_js_1 = require("../../services/local-ai-core/src/acp/local-core-acp-store.js");
20
21
  const session_command_service_js_1 = require("../../services/local-ai-core/src/thread/session-command-service.js");
21
- const thread_command_service_js_1 = require("../../services/local-ai-core/src/thread/thread-command-service.js");
22
+ const thread_slash_command_dispatcher_js_1 = require("../../services/local-ai-core/src/thread/thread-slash-command-dispatcher.js");
22
23
  (0, node_test_1.default)('response processor derives slash fallback replies and cron system responses', async () => {
23
24
  const processor = new local_core_acp_response_processor_js_1.LocalCoreAcpResponseProcessor({
24
25
  getScheduledDeliveryBinding: (threadId) => threadId === 'thread-1'
@@ -76,7 +77,15 @@ const thread_command_service_js_1 = require("../../services/local-ai-core/src/th
76
77
  availableAgents: ['codex', 'pi', 'hermes'],
77
78
  }), /当前线程 Agent:pi/);
78
79
  });
79
- (0, node_test_1.default)('thread command service handles local slash commands without ACP transport', async () => {
80
+ (0, node_test_1.default)('slash help command exposes global local command help', () => {
81
+ const help = (0, thread_slash_command_dispatcher_js_1.slashHelpText)();
82
+ strict_1.default.match(help, /`\/help`/);
83
+ strict_1.default.match(help, /`\/stop`/);
84
+ strict_1.default.match(help, /`\/mode /);
85
+ strict_1.default.match(help, /`\/agent /);
86
+ strict_1.default.match(help, /`\/list`/);
87
+ });
88
+ (0, node_test_1.default)('thread slash command dispatcher handles local slash commands without ACP transport', async () => {
80
89
  const row = {
81
90
  id: 'thread-1',
82
91
  workspace_id: 'workspace-a',
@@ -95,24 +104,39 @@ const thread_command_service_js_1 = require("../../services/local-ai-core/src/th
95
104
  const audits = [];
96
105
  const syncedModes = [];
97
106
  const closedThreads = [];
98
- const service = new thread_command_service_js_1.ThreadCommandService({
99
- getThreadRow: () => row,
100
- updateThreadAgentMode: (_threadId, mode) => {
101
- row.agent_mode = mode;
102
- },
103
- updateThreadAgentType: (_threadId, agentType) => {
104
- row.agent_type = agentType;
105
- },
106
- getLatestRunForThread: () => undefined,
107
- createAuditEvent: (input) => {
108
- audits.push(input);
109
- },
110
- getAgentTypes: () => ['codex', 'pi', 'hermes', 'claudecode'],
111
- setThreadMode: async (_threadId, mode) => {
112
- syncedModes.push(mode);
107
+ const interruptedRuns = [];
108
+ let latestRun;
109
+ const service = new thread_slash_command_dispatcher_js_1.ThreadSlashCommandDispatcher({
110
+ session: {
111
+ listThreads: () => [],
112
+ getThread: () => ({ id: row.id, title: row.title, messages: [] }),
113
+ createThread: () => ({ id: 'created-thread', title: 'Created', messages: [] }),
114
+ renameThread: () => ({ id: row.id, title: 'Renamed', messages: [] }),
115
+ deleteThread: () => ({ deleted: true }),
113
116
  },
114
- closeThreadSession: (threadId) => {
115
- closedThreads.push(threadId);
117
+ thread: {
118
+ getThreadRow: () => row,
119
+ updateThreadAgentMode: (_threadId, mode) => {
120
+ row.agent_mode = mode;
121
+ },
122
+ updateThreadAgentType: (_threadId, agentType) => {
123
+ row.agent_type = agentType;
124
+ },
125
+ getLatestRunForThread: () => latestRun,
126
+ createAuditEvent: (input) => {
127
+ audits.push(input);
128
+ },
129
+ getAgentTypes: () => ['codex', 'pi', 'hermes', 'claudecode'],
130
+ setThreadMode: async (_threadId, mode) => {
131
+ syncedModes.push(mode);
132
+ },
133
+ closeThreadSession: (threadId) => {
134
+ closedThreads.push(threadId);
135
+ },
136
+ interruptRun: async (runId) => {
137
+ interruptedRuns.push(runId);
138
+ return { interrupted: true };
139
+ },
116
140
  },
117
141
  });
118
142
  strict_1.default.deepEqual(await service.execute({
@@ -121,6 +145,32 @@ const thread_command_service_js_1 = require("../../services/local-ai-core/src/th
121
145
  content: '/not-local',
122
146
  defaultAgentType: 'codex',
123
147
  }), { handled: false, displayText: '' });
148
+ const inactiveStopResult = await service.execute({
149
+ threadId: row.id,
150
+ workspaceId: row.workspace_id,
151
+ content: '/stop',
152
+ defaultAgentType: 'codex',
153
+ });
154
+ strict_1.default.equal(inactiveStopResult.handled, true);
155
+ strict_1.default.match(inactiveStopResult.displayText, /没有正在运行的任务/);
156
+ latestRun = {
157
+ id: 'run-active',
158
+ thread_id: row.id,
159
+ status: 'running',
160
+ started_at: '2026-05-11T00:00:00.000Z',
161
+ updated_at: '2026-05-11T00:00:00.000Z',
162
+ };
163
+ const stopResult = await service.execute({
164
+ threadId: row.id,
165
+ workspaceId: row.workspace_id,
166
+ content: '/stop',
167
+ defaultAgentType: 'codex',
168
+ });
169
+ strict_1.default.equal(stopResult.handled, true);
170
+ strict_1.default.match(stopResult.displayText, /已请求停止当前任务/);
171
+ strict_1.default.deepEqual(interruptedRuns, ['run-active']);
172
+ strict_1.default.equal(audits.at(-1)?.type, 'task.updated');
173
+ latestRun = undefined;
124
174
  const modeResult = await service.execute({
125
175
  threadId: row.id,
126
176
  workspaceId: row.workspace_id,
@@ -153,6 +203,111 @@ const thread_command_service_js_1 = require("../../services/local-ai-core/src/th
153
203
  strict_1.default.match(resetResult.displayText, /回到默认 Agent:codex/);
154
204
  strict_1.default.deepEqual(closedThreads, ['thread-1', 'thread-1']);
155
205
  });
206
+ (0, node_test_1.default)('channel session command runtime uses unified slash dispatcher for thread commands', async () => {
207
+ const row = {
208
+ id: 'thread-1',
209
+ workspace_id: 'workspace-a',
210
+ session_id: 'session-1',
211
+ bridge_session_key: 'bridge-1',
212
+ title: 'Channel command',
213
+ agent_type: 'codex',
214
+ created_at: '2026-05-11T00:00:00.000Z',
215
+ updated_at: '2026-05-11T00:00:00.000Z',
216
+ history_count: 0,
217
+ excerpt: '',
218
+ acp_session_id: null,
219
+ acp_supports_load: 0,
220
+ agent_mode: 'default',
221
+ };
222
+ const sentResults = [];
223
+ const interruptedRuns = [];
224
+ const routes = new Map();
225
+ const dispatcher = new thread_slash_command_dispatcher_js_1.ThreadSlashCommandDispatcher({
226
+ session: {
227
+ listThreads: () => [],
228
+ getThread: (threadId) => ({ id: threadId, title: row.title, messages: [] }),
229
+ createThread: () => ({ id: 'created-thread', title: 'Created channel thread', messages: [] }),
230
+ renameThread: (threadId, title) => ({ id: threadId, title, messages: [] }),
231
+ deleteThread: () => ({ deleted: true }),
232
+ },
233
+ thread: {
234
+ getThreadRow: () => row,
235
+ updateThreadAgentMode: (_threadId, mode) => {
236
+ row.agent_mode = mode;
237
+ },
238
+ updateThreadAgentType: (_threadId, agentType) => {
239
+ row.agent_type = agentType;
240
+ },
241
+ getLatestRunForThread: () => ({
242
+ id: 'run-channel',
243
+ thread_id: row.id,
244
+ status: 'running',
245
+ started_at: '2026-05-11T00:00:00.000Z',
246
+ updated_at: '2026-05-11T00:00:00.000Z',
247
+ }),
248
+ createAuditEvent: () => { },
249
+ getAgentTypes: () => ['codex', 'pi'],
250
+ interruptRun: async (runId) => {
251
+ interruptedRuns.push(runId);
252
+ return { interrupted: true };
253
+ },
254
+ },
255
+ });
256
+ const runtime = new session_command_runtime_js_1.ChannelSessionCommandRuntime({
257
+ dispatcher,
258
+ store: {
259
+ getThreadRow: () => row,
260
+ updateThreadAgentMode: (_threadId, mode) => {
261
+ row.agent_mode = mode;
262
+ },
263
+ updateAuthorizedUserThread: () => { },
264
+ upsertPlatformThreadBinding: () => { },
265
+ },
266
+ getThreadSessionKey: (threadId) => `session:${threadId}`,
267
+ setThreadRoute: (sessionKey, route) => {
268
+ routes.set(sessionKey, route);
269
+ },
270
+ createRoute: (input, threadId) => ({
271
+ workspaceId: input.workspaceId,
272
+ instanceId: input.instanceId,
273
+ platformKey: input.platformKey,
274
+ platformUserId: input.platformUserId,
275
+ chatId: input.chatId,
276
+ threadId,
277
+ }),
278
+ sendResult: async (_input, result) => {
279
+ sentResults.push(result);
280
+ },
281
+ });
282
+ const stopResult = await runtime.execute({
283
+ workspaceId: 'workspace-a',
284
+ currentThreadId: row.id,
285
+ text: '/stop',
286
+ defaultTitle: 'Channel thread',
287
+ defaultAgentType: 'codex',
288
+ chatId: 'chat-1',
289
+ platformUserId: 'user-1',
290
+ platformKey: 'lark',
291
+ instanceId: 'default',
292
+ });
293
+ strict_1.default.equal(stopResult.handled, true);
294
+ strict_1.default.deepEqual(interruptedRuns, ['run-channel']);
295
+ strict_1.default.match(sentResults.at(-1)?.displayText || '', /已请求停止当前任务/);
296
+ const newResult = await runtime.execute({
297
+ workspaceId: 'workspace-a',
298
+ currentThreadId: row.id,
299
+ text: '/new Follow up',
300
+ defaultTitle: 'Channel thread',
301
+ defaultAgentType: 'codex',
302
+ chatId: 'chat-1',
303
+ platformUserId: 'user-1',
304
+ platformKey: 'lark',
305
+ instanceId: 'default',
306
+ });
307
+ strict_1.default.equal(newResult.handled, true);
308
+ strict_1.default.equal(newResult.threadId, 'created-thread');
309
+ strict_1.default.equal(routes.get('session:created-thread')?.threadId, 'created-thread');
310
+ });
156
311
  (0, node_test_1.default)('thread agent mode persists with thread state', () => {
157
312
  const dir = (0, node_fs_1.mkdtempSync)((0, node_path_1.join)((0, node_os_1.tmpdir)(), 'agentdock-mode-'));
158
313
  try {
@@ -193,9 +348,10 @@ const thread_command_service_js_1 = require("../../services/local-ai-core/src/th
193
348
  const thread = store.createThread('workspace-a', 'Agent command', 'codex');
194
349
  const bridgeEvents = [];
195
350
  const acceptedMessages = [];
351
+ const runThreadMap = new Map();
196
352
  const backend = new local_core_acp_backend_js_1.LocalCoreAcpBackend({
197
353
  store,
198
- runThreadMap: new Map(),
354
+ runThreadMap,
199
355
  emitBridge: (event) => bridgeEvents.push(event),
200
356
  eventBus: {
201
357
  emit: (event) => acceptedMessages.push(event),
@@ -236,6 +392,13 @@ const thread_command_service_js_1 = require("../../services/local-ai-core/src/th
236
392
  await backend.sendThreadMessage(thread.id, '/agent use hermes', config);
237
393
  strict_1.default.equal(store.getThreadRow(thread.id)?.agent_type, 'hermes');
238
394
  strict_1.default.match(store.getThread(thread.id, []).messages.at(-1)?.content || '', /下一轮开始生效/);
395
+ store.updateRun('run-stop', thread.id, 'running');
396
+ runThreadMap.set('run-stop', thread.id);
397
+ await backend.sendThreadMessage(thread.id, '/stop', config);
398
+ strict_1.default.equal(store.getRun('run-stop')?.status, 'interrupted');
399
+ strict_1.default.match(store.getThread(thread.id, []).messages.at(-1)?.content || '', /已将当前任务标记为停止|已请求停止当前任务/);
400
+ await backend.sendThreadMessage(thread.id, '/help', config);
401
+ strict_1.default.match(store.getThread(thread.id, []).messages.at(-1)?.content || '', /`\/stop`/);
239
402
  strict_1.default.ok(acceptedMessages.length >= 8);
240
403
  backend.close();
241
404
  store.close();
@@ -81,6 +81,40 @@ const server_routes_js_1 = require("../../services/local-ai-core/src/runtime/ser
81
81
  strict_1.default.equal((0, server_routes_js_1.parseLocalAiCoreRoute)('POST', '/api/local/v1/workspace-security/workspace-1'), null);
82
82
  strict_1.default.equal((0, server_routes_js_1.parseLocalAiCoreRoute)('GET', '/api/local/v1/workspaces/workspace-1/streaming-probe'), null);
83
83
  });
84
+ (0, node_test_1.default)('local core route parser handles shared model provider routes', () => {
85
+ strict_1.default.deepEqual((0, server_routes_js_1.parseLocalAiCoreRoute)('GET', '/api/local/v1/providers'), { name: 'providers.list' });
86
+ strict_1.default.deepEqual((0, server_routes_js_1.parseLocalAiCoreRoute)('POST', '/api/local/v1/providers'), { name: 'providers.create' });
87
+ strict_1.default.deepEqual((0, server_routes_js_1.parseLocalAiCoreRoute)('PUT', '/api/local/v1/providers/deepseek'), {
88
+ name: 'provider.update',
89
+ providerId: 'deepseek',
90
+ });
91
+ strict_1.default.deepEqual((0, server_routes_js_1.parseLocalAiCoreRoute)('DELETE', '/api/local/v1/providers/deepseek'), {
92
+ name: 'provider.delete',
93
+ providerId: 'deepseek',
94
+ });
95
+ strict_1.default.equal((0, server_routes_js_1.parseLocalAiCoreRoute)('GET', '/api/local/v1/providers/deepseek/extra'), null);
96
+ });
97
+ (0, node_test_1.default)('local core route parser handles external project and run routes', () => {
98
+ strict_1.default.deepEqual((0, server_routes_js_1.parseLocalAiCoreRoute)('POST', '/api/local/v1/external/projects'), {
99
+ name: 'external.project.ensure',
100
+ });
101
+ strict_1.default.deepEqual((0, server_routes_js_1.parseLocalAiCoreRoute)('POST', '/api/local/v1/external/runs'), {
102
+ name: 'external.run.create',
103
+ });
104
+ strict_1.default.deepEqual((0, server_routes_js_1.parseLocalAiCoreRoute)('GET', '/api/local/v1/external/runs/run%2Fone/events'), {
105
+ name: 'external.run.events',
106
+ runId: 'run/one',
107
+ });
108
+ strict_1.default.equal((0, server_routes_js_1.parseLocalAiCoreRoute)('GET', '/api/local/v1/external/projects'), null);
109
+ strict_1.default.equal((0, server_routes_js_1.parseLocalAiCoreRoute)('POST', '/api/local/v1/external/runs/run-1/events'), null);
110
+ });
111
+ (0, node_test_1.default)('local core route parser handles OpenAI-compatible chat completions route', () => {
112
+ strict_1.default.deepEqual((0, server_routes_js_1.parseLocalAiCoreRoute)('POST', '/api/local/v1/openai/chat/completions'), {
113
+ name: 'openai.chat.completions',
114
+ });
115
+ strict_1.default.equal((0, server_routes_js_1.parseLocalAiCoreRoute)('GET', '/api/local/v1/openai/chat/completions'), null);
116
+ strict_1.default.equal((0, server_routes_js_1.parseLocalAiCoreRoute)('POST', '/api/local/v1/openai/completions'), null);
117
+ });
84
118
  (0, node_test_1.default)('local core route parser keeps approval resolution separate from approval detail', () => {
85
119
  strict_1.default.deepEqual((0, server_routes_js_1.parseLocalAiCoreRoute)('GET', '/api/local/v1/approvals'), { name: 'approvals.list' });
86
120
  strict_1.default.deepEqual((0, server_routes_js_1.parseLocalAiCoreRoute)('POST', '/api/local/v1/approvals'), { name: 'approvals.create' });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kafca/agentdock",
3
- "version": "0.1.44",
3
+ "version": "0.1.46",
4
4
  "license": "PolyForm-Noncommercial-1.0.0",
5
5
  "type": "module",
6
6
  "main": "dist-electron/electron/main.js",
@@ -34,6 +34,7 @@
34
34
  "build:core": "pnpm build:electron",
35
35
  "test": "pnpm build:renderer && pnpm build:electron && node --test dist-electron/tests/electron/*.test.js dist-electron/tests/contracts/*.test.js dist-electron/tests/integration/*.test.js dist-electron/packages/knowledge-api/test/*.test.js dist-electron/src/pages/Threads/thread-chat-permission.test.js",
36
36
  "e2e:smoke": "pnpm build && node scripts/e2e-smoke.mjs",
37
+ "e2e:compose": "node scripts/e2e-compose.mjs",
37
38
  "dist:mac": "pnpm build && electron-builder --mac dmg zip --arm64",
38
39
  "dist:win": "pnpm build && electron-builder --win nsis zip --x64",
39
40
  "start": "node scripts/dev.mjs",
@@ -65,14 +66,12 @@
65
66
  "react-router-dom": "^7.5.0",
66
67
  "rehype-highlight": "^7.0.2",
67
68
  "remark-gfm": "^4.0.1",
68
- "ws": "^8.18.1",
69
69
  "zustand": "^5.0.5"
70
70
  },
71
71
  "devDependencies": {
72
72
  "@types/node": "^24.0.0",
73
73
  "@types/react": "^19.1.2",
74
74
  "@types/react-dom": "^19.1.2",
75
- "@types/ws": "^8.18.1",
76
75
  "@vitejs/plugin-react": "^4.4.1",
77
76
  "autoprefixer": "^10.4.21",
78
77
  "electron": "^35.0.2",
@@ -1,2 +0,0 @@
1
- import{u as ze,x as Me,r,j as s,C as pe,I as ye,M as U,B as C,g as ee,R as De,T as Ae}from"./index-B36eowj-.js";import{M as je}from"./Modal-DwY4lecS.js";import{E as $}from"./EmptyState-kD9yAwtw.js";import{C as Le,A as Be}from"./ChatMarkdown-BKdW8OON.js";import{l as Ke}from"./projects-DwfZwxDW.js";import{l as Ue,g as $e,s as qe,a as be,r as Fe,d as Oe}from"./sessions-CLcKA1Tt.js";import{s as We,a as we,b as w,L as P,t as He}from"./session-utils-BDxzgTBC.js";import{S as Ve}from"./search-CniPk7Ey.js";import{P as Ge}from"./pencil-DLh9QNmT.js";import{T as Je}from"./trash-2-DhtOCsO5.js";import{B as Qe,U as Xe}from"./user-BtC_pVXV.js";import"./index-BNFx4uYv.js";import"./check-BnclClRU.js";const Ye=1500,Ze=9e4;function es(a){return String(a||"").startsWith("web:")}function ss(a){return(a||[]).map((c,y)=>({id:`${c.timestamp||y}-${c.role}-${y}`,role:c.role==="user"?"user":"assistant",content:c.content,timestamp:c.timestamp,kind:c.kind}))}function ts(a){return a.map(c=>`${c.role}:${c.kind||"final"}:${c.timestamp||""}:${c.content}`).join(`
2
- `)}function as(a){return a.filter(c=>c.role!=="user").length}function ns(a,c){var y;return(y=a.last_message)!=null&&y.content?a.last_message.content.replace(/\n/g," "):c("sessions.noMessages")}function ve(a){return(a instanceof Error?a.message:String(a||"")).trim().toLowerCase().includes("no active session found")}function rs(a,c){return(a instanceof Error?a.message:String(a||"")).trim().toLowerCase()?ve(a)?c("sessions.sessionUnavailable"):a instanceof Error?a.message:c("sessions.sendFailed"):c("sessions.sendFailed")}function js(){const{t:a}=ze(),[c,y]=Me(),[se,ke]=r.useState([]),[te,ae]=r.useState({}),[i,G]=r.useState(c.get("project")||""),[j,R]=r.useState([]),[n,h]=r.useState(null),[I,v]=r.useState([]),[J,ne]=r.useState(""),[T,Q]=r.useState(""),[Ne,re]=r.useState(!0),[Se,ie]=r.useState(!1),[Ce,le]=r.useState(!1),[X,oe]=r.useState(!1),[_,E]=r.useState("idle"),[ce,k]=r.useState(""),[z,q]=r.useState(null),[F,Y]=r.useState(""),[M,O]=r.useState(null),[de,W]=r.useState(null),me=r.useRef(null),x=r.useRef({project:"",sessionId:""}),H=r.useRef(null),V=r.useRef(null),b=c.get("project")||"",D=c.get("session")||"",ue=r.useMemo(()=>new Set(Object.values(te)),[te]),N=r.useMemo(()=>{const e=J.trim().toLowerCase();return e?j.filter(t=>We(t,e)):j},[J,j]),A=!!(n&&(n.live||ue.has(n.id))),_e=!!(i&&A&&T.trim()&&!X&&_!=="sending"&&_!=="activating"&&_!=="polling"),f=r.useCallback((e,t)=>{const l=new URLSearchParams;e&&l.set("project",e),t&&l.set("session",t),y(l,{replace:!0})},[y]),d=r.useCallback((e="idle")=>{H.current&&(window.clearTimeout(H.current),H.current=null),V.current=null,E(e)},[]),xe=r.useCallback(e=>{R(t=>{const l=t.some(o=>o.id===e.id)?t.map(o=>o.id===e.id?{...o,...e}:o):[...t,e];return we(l)})},[]),fe=r.useCallback(async()=>{re(!0);try{const{projects:e}=await Ke();ke(e||[])}finally{re(!1)}},[]),u=r.useCallback(async e=>{if(!e)return R([]),ae({}),[];ie(!0);try{const{sessions:t,active_keys:l}=await Ue(e),o=we((t||[]).filter(m=>!es(m.session_key)));return ae(l||{}),x.current.project===e&&R(o),o}finally{ie(!1)}},[]),S=r.useCallback(async(e,t,l)=>{if(!e||!t)return h(null),v([]),null;l!=null&&l.silent||le(!0);try{const o=await $e(e,t,200);return x.current.project!==e||x.current.sessionId!==t||(xe(o),h({id:o.id,project:e,sessionKey:o.session_key,name:o.name||w(o),live:o.live,isDraft:!1,detail:o}),v(ss(o.history)),k("")),o}catch(o){return x.current.project===e&&x.current.sessionId===t&&k(o instanceof Error?o.message:a("sessions.loadFailed")),null}finally{l!=null&&l.silent||le(!1)}},[xe,a]),Z=r.useCallback(e=>{V.current=e,H.current=window.setTimeout(async()=>{const t=V.current;if(!t)return;if(Date.now()-t.startedAt>=Ze){d("timed_out"),k(a("sessions.pollTimeout")),await u(t.project);return}const l=await S(t.project,t.sessionId,{silent:!0});if(!l||!V.current){d(),await u(t.project);return}if(x.current.project!==t.project||x.current.sessionId!==t.sessionId){d();return}const o=ts(l.history),m=as(l.history)>t.assistantCountBefore,g=m&&o===t.lastSignature?t.stableCount+1:0,K={...t,lastSignature:o,stableCount:g};if(m&&g>=2){d(),await u(t.project);return}E("polling"),Z(K)},Ye)},[S,u,d,a]),he=r.useCallback((e,t,l)=>{d(),E("polling"),Z({project:e,sessionId:t,assistantCountBefore:l,stableCount:0,lastSignature:"",startedAt:Date.now()})},[Z,d]),Ee=r.useCallback(async e=>{if(d(),G(e),ne(""),k(""),Q(""),!e){x.current={project:"",sessionId:""},h(null),v([]),R([]),f("");return}x.current={project:e,sessionId:""},h(null),v([]),f(e),await u(e)},[u,d,f]),L=r.useCallback(async e=>{if(e.isDraft||e.live||!e.id)return e;E("activating");try{await qe(e.project,{session_key:e.sessionKey,session_id:e.id}),await u(e.project);const t=await S(e.project,e.id,{silent:!0}),l={...e,live:(t==null?void 0:t.live)??!0,isDraft:!1,detail:t??e.detail,name:(t==null?void 0:t.name)||e.name};return h(l),l}finally{E("idle")}},[S,u]),B=r.useCallback(async(e,t)=>{d(),k(""),x.current={project:e,sessionId:t.id},G(e),f(e,t.id),h({id:t.id,project:e,sessionKey:t.session_key,name:w(t),live:t.live,isDraft:!1,detail:null});const l=await S(e,t.id);l&&!l.live&&await L({id:l.id,project:e,sessionKey:l.session_key,name:l.name||w(l),live:l.live,isDraft:!1,detail:l})},[L,S,d,f]),Pe=r.useCallback(async()=>{d(),i&&(await u(i),n!=null&&n.id&&(x.current={project:i,sessionId:n.id},await S(i,n.id)))},[n==null?void 0:n.id,S,u,i,d]),ge=r.useCallback(async()=>{if(!T.trim()||!i)return;if(!A){k(a("sessions.sessionUnavailable"));return}const e=T.trim(),t=`${crypto.randomUUID()}-user`,l={id:t,role:"user",content:e,timestamp:new Date().toISOString()};Q(""),oe(!0),E("sending"),k("");try{const o=n||N[0];if(!o)throw new Error(a("sessions.noAvailableChatTarget"));let m=n&&n.id===o.id?n:{id:o.id,project:i,sessionKey:"session_key"in o?o.session_key:o.sessionKey,name:"session_key"in o?w(o):o.name,live:o.live,isDraft:!1,detail:null};(!n||n.id!==m.id)&&(x.current={project:i,sessionId:m.id},f(i,m.id),h(m)),m=await L(m),v(p=>[...p,l]);try{await be(i,{session_key:m.sessionKey,message:e})}catch(p){if(!ve(p)||!m.id)throw p;m=await L({...m,live:!1}),await be(i,{session_key:m.sessionKey,message:e})}const g=m.id;if(!g)throw new Error(a("sessions.createFailed"));const K=I.filter(p=>p.role!=="user").length;x.current={project:i,sessionId:g},h(p=>p&&{...p,id:g,isDraft:!1}),f(i,g),he(i,g,K),await u(i)}catch(o){d(),v(g=>g.filter(K=>K.id!==t));const m=rs(o,a);k(m)}finally{oe(!1)}},[n,A,L,T,N,I,u,i,he,d,a,f]),Re=r.useCallback(async()=>{if(!(!z||!i||!F.trim())){W("rename");try{await Fe(i,z.id,{name:F.trim()});const t=(await u(i)).find(l=>l.id===z.id);t&&(n==null?void 0:n.id)===t.id&&h(l=>l&&{...l,name:w(t)}),q(null),Y("")}finally{W(null)}}},[n==null?void 0:n.id,u,F,z,i]),Ie=r.useCallback(async()=>{if(!(!M||!i)){W("delete");try{await Oe(i,M.id);const e=await u(i);(n==null?void 0:n.id)===M.id&&(d(),x.current={project:i,sessionId:""},h(null),v([]),f(i)),e.length===0&&v([]),O(null)}finally{W(null)}}},[n==null?void 0:n.id,M,u,i,d,f]);r.useEffect(()=>{fe()},[fe]),r.useEffect(()=>{b&&(i&&i===b||G(b))},[b,i]),r.useEffect(()=>{if(!i){R([]);return}x.current.project=i,u(i)},[u,i]),r.useEffect(()=>{!i||D||n!=null&&n.id||N.length===0||B(i,N[0])},[n==null?void 0:n.id,N,B,D,i]),r.useEffect(()=>{if(!b||!D||i!==b)return;const e=j.find(t=>t.id===D);if(!e){j.length>0&&f(b,j[0].id);return}(n==null?void 0:n.id)!==e.id&&B(b,e)},[n==null?void 0:n.id,B,b,D,i,j,f]),r.useEffect(()=>{var e;(e=me.current)==null||e.scrollIntoView({behavior:"smooth"})},[I]),r.useEffect(()=>()=>d(),[d]);const Te=(n==null?void 0:n.name)||a("sessions.activeChat");return s.jsxs("div",{className:"grid min-h-[calc(100vh-8rem)] grid-cols-1 gap-4 xl:grid-cols-[22rem_minmax(0,1fr)] animate-fade-in",children:[s.jsxs(pe,{className:"flex flex-col gap-4 p-4 xl:h-[calc(100vh-8rem)] xl:overflow-hidden",children:[s.jsx("div",{className:"flex items-center gap-3",children:s.jsxs("div",{className:"flex-1",children:[s.jsx("p",{className:"text-xs font-medium uppercase tracking-[0.2em] text-gray-400",children:a("sessions.selectProject")}),s.jsxs("select",{value:i,onChange:e=>void Ee(e.target.value),className:"mt-2 w-full rounded-xl border border-gray-300/90 bg-white/90 px-3 py-2 text-sm text-gray-900 transition-all focus:border-accent focus:outline-none focus:ring-2 focus:ring-accent/45 dark:border-white/[0.1] dark:bg-[rgba(0,0,0,0.45)] dark:text-white",children:[s.jsx("option",{value:"",children:a("sessions.allProjects")}),se.map(e=>s.jsx("option",{value:e.name,children:e.name},e.name))]})]})}),s.jsxs("div",{className:"relative",children:[s.jsx(ye,{value:J,onChange:e=>ne(e.target.value),placeholder:a("common.search"),className:"pl-9","aria-label":a("common.search")}),s.jsx(Ve,{size:16,className:"pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-gray-400"})]}),s.jsxs("div",{className:"flex min-h-0 flex-1 flex-col overflow-hidden",children:[s.jsxs("div",{className:"mb-3 flex items-center justify-between text-xs text-gray-500 dark:text-gray-400",children:[s.jsx("span",{children:a("sessions.historyTitle")}),s.jsx("span",{children:N.length})]}),s.jsx("div",{className:"min-h-0 flex-1 overflow-y-auto space-y-2 pr-1",children:Ne?s.jsx("div",{className:"flex h-32 items-center justify-center text-gray-400",children:s.jsx(P,{className:"animate-spin",size:18})}):i?Se&&j.length===0?s.jsx("div",{className:"flex h-32 items-center justify-center text-gray-400",children:s.jsx(P,{className:"animate-spin",size:18})}):j.length===0?s.jsx($,{message:a("sessions.noSessions"),icon:U}):N.length===0?s.jsx($,{message:a("sessions.noSessions"),icon:U}):N.map(e=>{const t=e.id===(n==null?void 0:n.id);return s.jsxs("div",{className:ee("rounded-2xl border p-3 transition-all",t?"border-accent/45 bg-accent/10 shadow-[0_0_20px_-12px_rgba(139,92,246,0.55)]":"border-gray-200/80 bg-white/70 hover:border-accent/30 dark:border-white/[0.08] dark:bg-white/[0.03]"),children:[s.jsxs("button",{type:"button",onClick:()=>void B(i,e),className:"w-full text-left","data-testid":"web-chat-session-open",children:[s.jsxs("div",{className:"flex items-start justify-between gap-2",children:[s.jsxs("div",{className:"min-w-0",children:[s.jsxs("div",{className:"flex items-center gap-2",children:[s.jsx("span",{className:"truncate text-sm font-medium text-gray-900 dark:text-white",children:w(e)}),e.live||ue.has(e.id)?s.jsx("span",{className:"rounded-full bg-violet-50 px-2 py-0.5 text-[10px] text-violet-600 dark:bg-violet-950/20 dark:text-violet-300",children:"live"}):s.jsx("span",{className:"rounded-full bg-gray-100 px-2 py-0.5 text-[10px] text-gray-400 dark:bg-white/[0.06] dark:text-gray-500",children:"history"})]}),s.jsx("p",{className:"mt-1 truncate text-xs text-gray-500 dark:text-gray-400",children:He(e.updated_at||e.created_at,a("sessions.justNow"))})]}),s.jsx("span",{className:"shrink-0 text-[10px] text-gray-400",children:e.history_count})]}),s.jsx("p",{className:"mt-2 line-clamp-2 text-xs text-gray-500 dark:text-gray-400",children:ns(e,a)})]}),s.jsxs("div",{className:"mt-3 flex items-center justify-end gap-1",children:[s.jsx(C,{size:"sm",variant:"ghost",onClick:()=>{q({id:e.id,name:w(e)}),Y(w(e))},"data-testid":"web-chat-session-rename",children:s.jsx(Ge,{size:14})}),s.jsx(C,{size:"sm",variant:"ghost",onClick:()=>O({id:e.id,name:w(e)}),"data-testid":"web-chat-session-delete",children:s.jsx(Je,{size:14})})]})]},e.id)}):s.jsx($,{message:a("sessions.projectRequired"),icon:U})})]})]}),s.jsxs(pe,{className:"flex min-h-[32rem] flex-col p-0 xl:h-[calc(100vh-8rem)]",children:[s.jsxs("div",{className:"flex items-center justify-between gap-3 border-b border-gray-200/80 px-5 py-4 dark:border-white/[0.08]",children:[s.jsxs("div",{className:"min-w-0",children:[s.jsx("div",{className:"flex items-center gap-2",children:s.jsx("h2",{className:"truncate text-lg font-semibold text-gray-900 dark:text-white",children:Te})}),s.jsx("p",{className:"mt-1 truncate text-sm text-gray-500 dark:text-gray-400",children:n?n.project:a("sessions.sendHint")})]}),s.jsxs(C,{size:"sm",variant:"secondary",onClick:()=>void Pe(),"data-testid":"web-chat-refresh",children:[s.jsx(De,{size:14})," ",a("common.refresh")]})]}),s.jsx("div",{className:"flex-1 overflow-y-auto px-5 py-5",children:i?Ce?s.jsx("div",{className:"flex h-full items-center justify-center text-gray-400",children:s.jsx(P,{className:"animate-spin",size:22})}):I.length===0?s.jsx("div",{className:"flex h-full items-center justify-center",children:s.jsx($,{message:a(n?"sessions.noMessages":"sessions.sendHint"),icon:U})}):s.jsxs("div",{className:"space-y-5",children:[I.map(e=>{const t=e.role==="user";return s.jsxs("div",{className:ee("flex gap-3",t?"justify-end":"justify-start"),children:[!t&&s.jsx("div",{className:"mt-1 flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-accent/10",children:s.jsx(Qe,{size:16,className:"text-accent"})}),s.jsx("div",{className:ee("max-w-[85%] rounded-2xl px-5 py-3.5 text-sm",t?"bg-accent text-white rounded-br-md":"border border-gray-200 bg-white text-gray-900 shadow-sm dark:border-white/[0.08] dark:bg-[rgba(0,0,0,0.42)] dark:text-gray-100 rounded-bl-md"),children:s.jsx(Le,{content:e.content,isUser:t})}),t&&s.jsx("div",{className:"mt-1 flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-gray-200 dark:bg-white/[0.08]",children:s.jsx(Xe,{size:16,className:"text-gray-500 dark:text-gray-300"})})]},e.id)}),s.jsx("div",{ref:me})]}):s.jsx("div",{className:"flex h-full items-center justify-center",children:s.jsx($,{message:a("sessions.emptySelection"),icon:U})})}),s.jsxs("div",{className:"border-t border-gray-200/80 px-5 py-4 dark:border-white/[0.08]",children:[ce&&s.jsx("div",{className:"mb-3 rounded-xl border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-600 dark:border-red-900/40 dark:bg-red-950/20 dark:text-red-300",children:ce}),_==="polling"&&s.jsxs("div",{className:"mb-3 flex items-center gap-2 text-sm text-gray-500 dark:text-gray-400",children:[s.jsx(P,{size:14,className:"animate-spin"}),s.jsx("span",{children:a("sessions.waitingForReply")})]}),_==="activating"&&s.jsxs("div",{className:"mb-3 flex items-center gap-2 text-sm text-gray-500 dark:text-gray-400",children:[s.jsx(P,{size:14,className:"animate-spin"}),s.jsx("span",{children:a("sessions.preparingChat")})]}),s.jsxs("div",{className:"relative",children:[s.jsx(Ae,{value:T,onChange:e=>Q(e.target.value),onKeyDown:e=>{e.key==="Enter"&&!e.shiftKey&&(e.preventDefault(),ge())},rows:3,placeholder:a(i?"sessions.messageInput":"sessions.projectRequired"),disabled:!i||!A||X||_==="polling"||_==="activating",className:"min-h-[104px] rounded-[24px] border-gray-200 bg-white px-4 pb-16 pt-3 text-[15px] leading-6 shadow-[0_12px_34px_rgba(15,23,42,0.08)] dark:border-white/[0.08] dark:bg-[rgba(0,0,0,0.42)] sm:min-h-[112px] sm:px-5 sm:pt-4","data-testid":"web-chat-input"}),s.jsx(C,{onClick:()=>void ge(),disabled:!_e,size:"icon","aria-label":a("sessions.send"),className:"absolute bottom-3 right-3 h-11 w-11 rounded-full bg-slate-900 px-0 text-white shadow-none hover:bg-slate-800 disabled:bg-slate-300 disabled:text-white disabled:opacity-100 dark:bg-slate-100 dark:text-slate-950 dark:hover:bg-white dark:disabled:bg-white/20 dark:disabled:text-white/55 sm:h-12 sm:w-12","data-testid":"web-chat-send",children:X?s.jsx(P,{size:18,className:"animate-spin"}):s.jsx(Be,{size:22,strokeWidth:2.2})})]}),!A&&n&&s.jsx("div",{className:"mt-3 rounded-xl border border-gray-200 bg-gray-50 px-4 py-3 text-sm text-gray-500 dark:border-white/[0.08] dark:bg-white/[0.03] dark:text-gray-400",children:a("sessions.notLiveHint")})]})]}),s.jsx(je,{open:!!z,onClose:()=>q(null),title:a("sessions.renameTitle"),children:s.jsxs("div",{className:"space-y-4",children:[s.jsx(ye,{value:F,onChange:e=>Y(e.target.value),placeholder:a("sessions.renamePlaceholder"),"data-testid":"web-chat-rename-input"}),s.jsxs("div",{className:"flex justify-end gap-2",children:[s.jsx(C,{variant:"secondary",onClick:()=>q(null),children:a("common.cancel")}),s.jsx(C,{onClick:()=>void Re(),loading:de==="rename","data-testid":"web-chat-rename-save",children:a("common.save")})]})]})}),s.jsx(je,{open:!!M,onClose:()=>O(null),title:a("sessions.deleteConfirmTitle"),children:s.jsxs("div",{className:"space-y-4",children:[s.jsx("p",{className:"text-sm text-gray-500 dark:text-gray-400",children:a("sessions.deleteConfirmBody")}),s.jsxs("div",{className:"flex justify-end gap-2",children:[s.jsx(C,{variant:"secondary",onClick:()=>O(null),children:a("common.cancel")}),s.jsx(C,{variant:"danger",onClick:()=>void Ie(),loading:de==="delete","data-testid":"web-chat-delete-confirm",children:a("common.delete")})]})]})})]})}export{js as default};
@@ -1,16 +0,0 @@
1
- import{c as m,u as R,r as n,j as e,B as c,R as P,L as M,I as U,$ as z,a0 as K}from"./index-B36eowj-.js";import{g as L,k as B,m as I}from"./desktop-C5vBT0yM.js";import{B as _}from"./Badge-Qk9qHovH.js";import{P as A,S as d,a as H}from"./Page-CnB9ePsb.js";import{S as $}from"./save-D5AO_G6a.js";import{P as D}from"./plug-BG0JHW6B.js";/**
2
- * @license lucide-react v0.487.0 - ISC
3
- *
4
- * This source code is licensed under the ISC license.
5
- * See the LICENSE file in the root directory of this source tree.
6
- */const q=[["path",{d:"M10 12.5 8 15l2 2.5",key:"1tg20x"}],["path",{d:"m14 12.5 2 2.5-2 2.5",key:"yinavb"}],["path",{d:"M14 2v4a2 2 0 0 0 2 2h4",key:"tnqrlb"}],["path",{d:"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7z",key:"1mlx9k"}]],E=m("file-code",q);/**
7
- * @license lucide-react v0.487.0 - ISC
8
- *
9
- * This source code is licensed under the ISC license.
10
- * See the LICENSE file in the root directory of this source tree.
11
- */const F=[["path",{d:"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8",key:"1357e3"}],["path",{d:"M3 3v5h5",key:"1xhq8a"}]],T=m("rotate-ccw",F);/**
12
- * @license lucide-react v0.487.0 - ISC
13
- *
14
- * This source code is licensed under the ISC license.
15
- * See the LICENSE file in the root directory of this source tree.
16
- */const V=[["path",{d:"M15 12h-5",key:"r7krc0"}],["path",{d:"M15 8h-5",key:"1khuty"}],["path",{d:"M19 17V5a2 2 0 0 0-2-2H4",key:"zz82l3"}],["path",{d:"M8 21h12a2 2 0 0 0 2-2v-1a1 1 0 0 0-1-1H11a1 1 0 0 0-1 1v1a2 2 0 1 1-4 0V5a2 2 0 1 0-4 0v2a1 1 0 0 0 1 1h3",key:"1ph1d7"}]],X=m("scroll-text",V);function G(a){return a==="api_ready"?"success":a==="error"?"danger":a==="starting"?"warning":"neutral"}function ee(){const{t:a}=R(),[s,u]=n.useState(null),[i,j]=n.useState(null),[g,h]=n.useState(""),[k,x]=n.useState(""),[w,f]=n.useState(!0),[p,y]=n.useState(!1),[v,l]=n.useState(""),r=n.useCallback(async()=>{f(!0);try{const[t,o]=await Promise.allSettled([L(),B()]);t.status==="fulfilled"&&(u(t.value),h(t.value.settings.knowledge.baseUrl||""),x(t.value.settings.knowledge.baseUrl||"")),o.status==="fulfilled"&&j(o.value)}finally{f(!1)}},[]);n.useEffect(()=>{r()},[r]);const N=async()=>{if(confirm(a("system.restartConfirm")))try{await z(),l(a("common.success")),await r()}catch(t){l(t.message)}},b=async()=>{if(confirm(a("system.reloadConfirm")))try{await K(),l(a("common.success")),await r()}catch(t){l(t.message)}},S=async()=>{y(!0);try{const t=await I({knowledge:{baseUrl:g,authMode:(s==null?void 0:s.settings.knowledge.authMode)||"none",token:(s==null?void 0:s.settings.knowledge.token)||"",headerName:(s==null?void 0:s.settings.knowledge.headerName)||"X-API-Key",defaultCollection:(s==null?void 0:s.settings.knowledge.defaultCollection)||"personal_knowledge"}});u(o=>o&&{...o,settings:t}),x(t.knowledge.baseUrl||""),l(a("common.success"))}catch(t){l(t.message)}finally{y(!1)}},C=g!==k;return e.jsxs("div",{className:"space-y-6 animate-fade-in",children:[e.jsx(A,{title:a("nav.system"),description:"Runtime health, logs, and plugin diagnostics. Advanced config is available read-only from the diagnostics drawer.",actions:e.jsxs(e.Fragment,{children:[e.jsxs(c,{variant:"secondary",onClick:b,children:[e.jsx(P,{size:16})," ",a("system.reload")]}),e.jsxs(c,{variant:"danger",onClick:N,children:[e.jsx(T,{size:16})," ",a("system.restart")]}),e.jsx(M,{to:"/system/logs",children:e.jsxs(c,{variant:"secondary",children:[e.jsx(X,{size:16})," ",a("system.logs")]})})]})}),v?e.jsx("div",{role:"status",className:"rounded-lg border border-primary/20 bg-primary/10 px-4 py-3 text-sm text-primary",children:v}):null,e.jsxs("div",{className:"grid grid-cols-1 gap-4 lg:grid-cols-3",children:[e.jsxs(d,{title:"Runtime",description:w?"Loading...":"Local service status.",children:[e.jsx(H,{tone:G(s==null?void 0:s.phase),children:(s==null?void 0:s.phase)||"unknown"}),e.jsx("p",{className:"mt-3 text-sm text-muted-foreground",children:s!=null&&s.pendingRestart?"Restart required to apply saved changes.":"No pending restart."})]}),e.jsx(d,{title:"Config",description:"Active config file location.",children:e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx(E,{size:18,className:"mt-0.5 text-primary"}),e.jsx("p",{className:"break-all font-mono text-xs leading-5 text-muted-foreground",children:(s==null?void 0:s.settings.configPath)||(s==null?void 0:s.configFile.path)||"-"})]})}),e.jsxs(d,{title:"Plugins",description:"Health summary only.",children:[e.jsx("p",{className:"text-2xl font-semibold text-foreground",children:i?`${i.enabledPluginCount}/${i.pluginCount}`:"-"}),e.jsx("p",{className:"mt-1 text-sm text-muted-foreground",children:"enabled plugins"})]})]}),e.jsx(d,{title:"Knowledge",description:"System-wide knowledge API connection.",actions:e.jsxs(c,{size:"sm",onClick:()=>void S(),loading:p,disabled:!C&&!p,children:[e.jsx($,{size:14})," Save"]}),children:e.jsx(U,{label:"Knowledge base URL",value:g,onChange:t=>h(t.target.value),placeholder:"http://127.0.0.1:16007"})}),e.jsx(d,{title:a("system.plugins"),description:"Plugin state is read-only in the daily UI. Use backend config for advanced changes.",children:i?i.plugins.length===0?e.jsx("div",{className:"py-8 text-sm text-muted-foreground",children:"No plugins registered."}):e.jsx("div",{className:"divide-y divide-border",children:i.plugins.map(t=>e.jsxs("div",{className:"flex items-start justify-between gap-4 py-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(D,{size:15,className:"text-muted-foreground"}),e.jsx("p",{className:"truncate text-sm font-medium text-foreground",children:t.pluginId})]}),e.jsx("p",{className:"mt-1 text-xs text-muted-foreground",children:t.health.summary||t.manifest.provides.join(", ")||"No declared capabilities"})]}),e.jsx(_,{variant:t.health.status==="healthy"?"success":t.health.status==="failed"?"danger":"warning",children:t.health.status})]},t.pluginId))}):e.jsx("div",{className:"py-8 text-sm text-muted-foreground",children:"Loading..."})})]})}export{ee as default};
@@ -1 +0,0 @@
1
- import{J as R,l as b,K as z,N as D,O as W,P as O,u as B,r as n,j as t,s as F,B as c,G as L,C as U,E as k,I as f,T as G}from"./index-B36eowj-.js";import{B as u}from"./Badge-Qk9qHovH.js";import{M as H}from"./Modal-DwY4lecS.js";import{S as w}from"./Select-zfoksLGB.js";import{E as K}from"./EmptyState-kD9yAwtw.js";import{P as _}from"./Page-CnB9ePsb.js";import{P as q}from"./plus-BSc8POsz.js";import{P as Q}from"./play-BDTk9Scm.js";import{P as V}from"./pencil-DLh9QNmT.js";import{T as X}from"./trash-2-DhtOCsO5.js";import"./index-BNFx4uYv.js";import"./chevron-down-Bh53e0O-.js";import"./check-BnclClRU.js";const Y=a=>R(),Z=a=>D(a),$=(a,o)=>z(a,o),ee=a=>W(a),te=a=>O(a),ae=()=>b().then(a=>a.workspaces),x={workspaceId:"",executionMode:"same-thread",triggerType:"cron",cronExpr:"0 9 * * *",runAt:"",promptTemplate:"",description:"",chatId:"",platformUserId:"",threadId:"",enabled:!0};function se(a){return a?{workspaceId:a.workspaceId,executionMode:a.executionMode,triggerType:a.triggerType,cronExpr:a.cronExpr||"0 9 * * *",runAt:a.runAt?String(a.runAt).slice(0,16):"",promptTemplate:a.promptTemplate,description:a.description,chatId:a.route.channelId,platformUserId:a.route.participantId||"",threadId:a.route.threadId||"",enabled:a.enabled}:x}function re(a){return{workspaceId:a.workspaceId,platform:"local",route:{type:"local.thread",channelId:a.workspaceId||"local",...a.threadId?{threadId:a.threadId}:{}},executionMode:a.executionMode||"same-thread",triggerType:a.triggerType,...a.triggerType==="cron"?{cronExpr:a.cronExpr,runAt:void 0}:{runAt:new Date(a.runAt).toISOString(),cronExpr:void 0},promptTemplate:a.promptTemplate,description:a.description,enabled:a.enabled}}function ye(){const{t:a}=B(),[o,I]=n.useState([]),[m,T]=n.useState([]),[C,y]=n.useState(!0),[S,d]=n.useState(!1),[j,v]=n.useState(!1),[p,h]=n.useState(null),[s,r]=n.useState(x),E=n.useMemo(()=>m.map(e=>t.jsx("option",{value:e.id,children:e.name},e.id)),[m]),i=n.useCallback(async()=>{y(!0);try{const[e,l]=await Promise.all([Y(),ae()]);I(e.jobs||[]),T(l),r(g=>g.workspaceId||l.length===0?g:{...g,workspaceId:l[0].id})}finally{y(!1)}},[]);n.useEffect(()=>{i();const e=F(l=>{(l.type==="scheduler.job.updated"||l.type==="scheduler.run.updated")&&i()});return()=>e()},[i]);const J=()=>{var e;h(null),r({...x,workspaceId:((e=m[0])==null?void 0:e.id)||""}),d(!0)},N=e=>{h(e),r(se(e)),d(!0)},A=async()=>{if(!(!s.workspaceId||!s.promptTemplate.trim())&&!(s.triggerType==="once"&&!s.runAt)){v(!0);try{const e=re(s);p?await $(p.id,e):await Z(e),d(!1),h(null),r(x),await i()}finally{v(!1)}}},M=async e=>{confirm(a("common.confirmDelete"))&&(await ee(e),await i())},P=async e=>{await te(e),await i()};return C&&o.length===0?t.jsx("div",{className:"flex items-center justify-center h-64 text-gray-400 animate-pulse",children:a("common.loading")}):t.jsxs("div",{className:"space-y-4 animate-fade-in",children:[t.jsx(_,{title:a("cron.title"),description:"Create simple scheduled prompts for a workspace.",actions:t.jsxs(c,{onClick:J,children:[t.jsx(q,{size:16})," ",a("cron.add")]})}),o.length===0?t.jsx(K,{message:a("cron.noJobs"),icon:L}):t.jsx("div",{className:"space-y-3",children:o.map(e=>t.jsx(U,{children:t.jsxs("div",{className:"flex items-start justify-between gap-3",children:[t.jsxs("div",{className:"flex-1",children:[t.jsxs("div",{className:"flex items-center gap-2 mb-1 flex-wrap",children:[t.jsx("span",{className:"font-medium text-gray-900 dark:text-white text-sm",children:e.description||e.id}),t.jsx(u,{variant:e.enabled?"success":"default",children:e.enabled?a("cron.enabled"):"disabled"}),t.jsx(u,{variant:"default",children:e.triggerType}),t.jsx(u,{variant:"default",children:e.platform}),e.lastStatus&&t.jsx(u,{variant:e.lastStatus==="failed"?"danger":"default",children:e.lastStatus})]}),t.jsxs("div",{className:"flex flex-wrap gap-x-4 gap-y-1 text-xs text-gray-500 dark:text-gray-400 mt-2",children:[t.jsxs("span",{children:[t.jsx("strong",{children:"Workspace:"})," ",e.workspaceId]}),t.jsxs("span",{children:[t.jsx("strong",{children:"Execution:"})," ",e.executionMode]}),t.jsxs("span",{children:[t.jsx("strong",{children:"Route:"})," ",e.route.channelId," / ",e.route.participantId]}),t.jsxs("span",{children:[t.jsxs("strong",{children:[e.triggerType==="cron"?a("cron.expression"):"Run at",":"]})," ",e.triggerType==="cron"?e.cronExpr:k(e.runAt||"")]}),e.route.threadId&&t.jsxs("span",{children:[t.jsx("strong",{children:"Thread:"})," ",e.route.threadId]}),e.lastRunAt&&t.jsxs("span",{children:[t.jsxs("strong",{children:[a("cron.lastRun"),":"]})," ",k(e.lastRunAt)]})]}),t.jsx("p",{className:"text-sm text-gray-700 dark:text-gray-300 mt-2 whitespace-pre-wrap",children:e.promptTemplate}),e.lastError&&t.jsx("p",{className:"text-xs text-red-500 mt-2",children:e.lastError})]}),t.jsxs("div",{className:"flex gap-2",children:[t.jsx(c,{size:"sm",variant:"secondary",onClick:()=>void P(e.id),children:t.jsx(Q,{size:14})}),t.jsx(c,{size:"sm",variant:"secondary",onClick:()=>N(e),children:t.jsx(V,{size:14})}),t.jsx(c,{size:"sm",variant:"danger",onClick:()=>void M(e.id),children:t.jsx(X,{size:14})})]})]})},e.id))}),t.jsx(H,{open:S,onClose:()=>d(!1),title:p?"Edit scheduler job":a("cron.add"),children:t.jsxs("div",{className:"space-y-3",children:[t.jsxs(w,{label:"Workspace",value:s.workspaceId,onChange:e=>r({...s,workspaceId:e.target.value}),children:[t.jsx("option",{value:"",children:"Select workspace"}),E]}),t.jsxs(w,{label:"Schedule type",value:s.triggerType,onChange:e=>r({...s,triggerType:e.target.value}),children:[t.jsx("option",{value:"cron",children:"Repeating"}),t.jsx("option",{value:"once",children:"One time"})]}),s.triggerType==="cron"?t.jsx(f,{label:a("cron.expression"),value:s.cronExpr,onChange:e=>r({...s,cronExpr:e.target.value}),placeholder:"0 9 * * *"}):t.jsx(f,{label:"Run at",type:"datetime-local",value:s.runAt,onChange:e=>r({...s,runAt:e.target.value})}),t.jsx(f,{label:a("cron.description"),value:s.description,onChange:e=>r({...s,description:e.target.value})}),t.jsx(G,{label:a("cron.prompt"),value:s.promptTemplate,onChange:e=>r({...s,promptTemplate:e.target.value}),rows:4,placeholder:"Summarize today's blockers and post a status update."}),t.jsxs("label",{className:"flex items-center gap-2 text-sm text-gray-700 dark:text-gray-300",children:[t.jsx("input",{type:"checkbox",checked:s.enabled,onChange:e=>r({...s,enabled:e.target.checked})}),a("cron.enabled")]}),t.jsxs("div",{className:"flex justify-end gap-2 pt-2",children:[t.jsx(c,{variant:"secondary",onClick:()=>d(!1),children:a("common.cancel")}),t.jsx(c,{onClick:()=>void A(),disabled:j,children:a(p?"common.save":"cron.add")})]})]})})]})}export{ye as default};
@@ -1,26 +0,0 @@
1
- import{c as j,u as te,r,a as ae,l as re,b as w,d as ie,e as ne,j as e,M as de,W as le,F as W,C as g,B as ce,R as oe,f as me,L as A,S as xe}from"./index-B36eowj-.js";import{B as n}from"./Badge-Qk9qHovH.js";import{E as f}from"./EmptyState-kD9yAwtw.js";import{P as he}from"./Page-CnB9ePsb.js";import{l as ue}from"./projects-DwfZwxDW.js";import{l as pe,r as ge,o as fe,a as je}from"./desktop-C5vBT0yM.js";import{S as be,A as H}from"./server-GsXyQAZm.js";import{B as ke}from"./book-open-BNJMhNI-.js";import{S as U}from"./shield-check-4i0E3hmf.js";/**
2
- * @license lucide-react v0.487.0 - ISC
3
- *
4
- * This source code is licensed under the ISC license.
5
- * See the LICENSE file in the root directory of this source tree.
6
- */const ve=[["path",{d:"M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.25.25 0 0 1-.48 0L9.24 2.18a.25.25 0 0 0-.48 0l-2.35 8.36A2 2 0 0 1 4.49 12H2",key:"169zse"}]],ye=j("activity",ve);/**
7
- * @license lucide-react v0.487.0 - ISC
8
- *
9
- * This source code is licensed under the ISC license.
10
- * See the LICENSE file in the root directory of this source tree.
11
- */const Ne=[["path",{d:"M21 7.5V6a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h3.5",key:"1osxxc"}],["path",{d:"M16 2v4",key:"4m81vk"}],["path",{d:"M8 2v4",key:"1cmpym"}],["path",{d:"M3 10h5",key:"r794hk"}],["path",{d:"M17.5 17.5 16 16.3V14",key:"akvzfd"}],["circle",{cx:"16",cy:"16",r:"6",key:"qoo3c4"}]],we=j("calendar-clock",Ne);/**
12
- * @license lucide-react v0.487.0 - ISC
13
- *
14
- * This source code is licensed under the ISC license.
15
- * See the LICENSE file in the root directory of this source tree.
16
- */const Re=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"m9 12 2 2 4-4",key:"dzmm74"}]],Ae=j("circle-check",Re);/**
17
- * @license lucide-react v0.487.0 - ISC
18
- *
19
- * This source code is licensed under the ISC license.
20
- * See the LICENSE file in the root directory of this source tree.
21
- */const Se=[["rect",{width:"16",height:"16",x:"4",y:"4",rx:"2",key:"14l7u7"}],["rect",{width:"6",height:"6",x:"9",y:"9",rx:"1",key:"5aljv4"}],["path",{d:"M15 2v2",key:"13l42r"}],["path",{d:"M15 20v2",key:"15mkzm"}],["path",{d:"M2 15h2",key:"1gxd5l"}],["path",{d:"M2 9h2",key:"1bbxkp"}],["path",{d:"M20 15h2",key:"19e6y8"}],["path",{d:"M20 9h2",key:"19tzq7"}],["path",{d:"M9 2v2",key:"165o2o"}],["path",{d:"M9 20v2",key:"i2bqo8"}]],F=j("cpu",Se);/**
22
- * @license lucide-react v0.487.0 - ISC
23
- *
24
- * This source code is licensed under the ISC license.
25
- * See the LICENSE file in the root directory of this source tree.
26
- */const _e=[["path",{d:"m3 17 2 2 4-4",key:"1jhpwq"}],["path",{d:"m3 7 2 2 4-4",key:"1obspn"}],["path",{d:"M13 6h8",key:"15sg57"}],["path",{d:"M13 12h8",key:"h98zly"}],["path",{d:"M13 18h8",key:"oe0vm4"}]],Me=j("list-checks",_e);function Le({title:a,description:t,to:o,icon:h,primary:d}){return e.jsxs(A,{to:o,className:["group flex min-h-[118px] flex-col justify-between rounded-2xl p-5 transition-colors duration-200 focus:outline-none focus:ring-2 focus:ring-ring",d?"bg-black/[0.07] text-foreground hover:bg-black/[0.09] dark:bg-white/[0.10] dark:hover:bg-white/[0.13]":"bg-white/54 text-foreground hover:bg-white/72 dark:bg-white/[0.055] dark:hover:bg-white/[0.085]"].join(" "),children:[e.jsxs("div",{className:"flex items-start justify-between gap-4",children:[e.jsx("div",{className:"flex h-10 w-10 shrink-0 items-center justify-center rounded-xl bg-white/70 text-primary shadow-[0_1px_1px_rgba(0,0,0,0.04)] dark:bg-white/[0.08]",children:e.jsx(h,{size:20})}),e.jsx(H,{size:17,className:"mt-1 text-muted-foreground/45 transition-colors group-hover:text-foreground"})]}),e.jsxs("div",{children:[e.jsx("h2",{className:"text-base font-semibold text-foreground",children:a}),e.jsx("p",{className:"mt-2 max-w-sm text-sm leading-5 text-muted-foreground",children:t})]})]})}function R({title:a,description:t,tasks:o,empty:h,urgent:d}){return e.jsxs(g,{className:"overflow-hidden p-0",children:[e.jsx("div",{className:"border-b border-black/[0.08] px-5 py-4 dark:border-white/[0.07]",children:e.jsxs("div",{className:"flex items-start justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-base font-semibold text-foreground",children:a}),e.jsx("p",{className:"mt-1 text-sm text-muted-foreground",children:t})]}),e.jsx(n,{variant:d&&o.length>0?"warning":"secondary",children:o.length})]})}),o.length===0?e.jsx("div",{className:"p-5",children:e.jsx(f,{message:h,icon:Me})}):e.jsx("div",{className:"divide-y divide-black/[0.08] dark:divide-white/[0.07]",children:o.map(l=>e.jsxs("div",{className:"px-5 py-4",children:[e.jsxs("div",{className:"flex items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("p",{className:"truncate text-sm font-medium text-foreground",children:l.title}),e.jsxs("p",{className:"mt-1 truncate text-xs text-muted-foreground",children:[l.workspaceId," · ",l.runtimeId]})]}),e.jsx(n,{variant:l.status==="failed"?"danger":l.status==="completed"?"success":"info",children:l.status})]}),e.jsxs("p",{className:"mt-2 text-xs text-muted-foreground",children:["Updated ",new Date(l.updatedAt).toLocaleString()]})]},l.taskId))})]})}function ze({approvals:a}){return e.jsxs(g,{className:"overflow-hidden p-0",children:[e.jsx("div",{className:"border-b border-black/[0.08] px-5 py-4 dark:border-white/[0.07]",children:e.jsxs("div",{className:"flex items-start justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-base font-semibold text-foreground",children:"待审批"}),e.jsx("p",{className:"mt-1 text-sm text-muted-foreground",children:"高风险操作会在这里等待确认或拒绝。"})]}),e.jsx(n,{variant:a.length>0?"warning":"secondary",children:a.length})]})}),a.length===0?e.jsx("div",{className:"p-5",children:e.jsx(f,{message:"暂无待审批操作",icon:U})}):e.jsx("div",{className:"divide-y divide-black/[0.08] dark:divide-white/[0.07]",children:a.map(t=>e.jsxs("div",{className:"px-5 py-4",children:[e.jsxs("div",{className:"flex items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("p",{className:"truncate text-sm font-medium text-foreground",children:t.title}),e.jsxs("p",{className:"mt-1 truncate text-xs text-muted-foreground",children:[t.workspaceId," · ",t.kind]})]}),e.jsx(n,{variant:t.riskLevel==="high"?"danger":"warning",children:t.riskLevel})]}),e.jsx("p",{className:"mt-2 line-clamp-2 text-xs leading-5 text-muted-foreground",children:t.description})]},t.approvalId))})]})}function Ce({events:a}){return e.jsxs(g,{className:"overflow-hidden p-0",children:[e.jsxs("div",{className:"border-b border-black/[0.08] px-5 py-4 dark:border-white/[0.07]",children:[e.jsx("h2",{className:"text-base font-semibold text-foreground",children:"审计记录"}),e.jsx("p",{className:"mt-1 text-sm text-muted-foreground",children:"最近的任务、审批和权限事件。"})]}),a.length===0?e.jsx("div",{className:"p-5",children:e.jsx(f,{message:"暂无审计记录",icon:U})}):e.jsx("div",{className:"divide-y divide-black/[0.08] dark:divide-white/[0.07]",children:a.map(t=>e.jsxs("div",{className:"px-5 py-4",children:[e.jsxs("div",{className:"flex items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("p",{className:"truncate text-sm font-medium text-foreground",children:t.summary}),e.jsxs("p",{className:"mt-1 truncate text-xs text-muted-foreground",children:[t.type," · ",t.actor||"system"]})]}),t.riskLevel?e.jsx(n,{variant:t.riskLevel==="high"?"danger":"secondary",children:t.riskLevel}):null]}),e.jsx("p",{className:"mt-2 text-xs text-muted-foreground",children:new Date(t.createdAt).toLocaleString()})]},t.auditId))})]})}function Fe(){const{t:a}=te(),[t,o]=r.useState([]),[h,d]=r.useState([]),[l,S]=r.useState([]),[V,_]=r.useState([]),[K,M]=r.useState([]),[O,L]=r.useState([]),[Q,z]=r.useState([]),[G,C]=r.useState(!0),[J,D]=r.useState(!1),[X,u]=r.useState(!1),[E,T]=r.useState(""),[P,p]=r.useState(""),{desktopRuntime:c,desktopWorkspace:I,knowledgeModule:q,schedulerModule:$}=ae(),B=h.filter(s=>s.installed),b=[{title:"继续聊天",description:"打开本地对话,继续当前项目里的 agent 线程。",to:"/chat",icon:de,primary:!0},{title:"工作区",description:"管理项目、平台、模型和本地运行配置。",to:I?"/workspace":"/projects",icon:I?le:W}];q&&b.push({title:"知识库",description:"上传文档,维护可被检索的项目资料。",to:"/knowledge",icon:ke}),$&&b.push({title:"定时任务",description:"查看和管理自动执行的计划任务。",to:"/cron",icon:we}),(!q||!$)&&b.push({title:"系统设置",description:"查看配置、日志和桌面应用偏好。",to:"/system",icon:xe});const k=r.useCallback(async()=>{var s;C(!0),T(""),p("");try{if(c){const[y,i]=await Promise.all([re(),pe().then(x=>({status:"fulfilled",runtimes:x}),x=>({status:"rejected",error:x}))]),[N,v,Z]=await Promise.all([w({status:["created","queued","running"],limit:6}),w({status:"waiting_for_user",limit:6}),w({status:["completed","failed","cancelled"],limit:6})]),[ee,se]=await Promise.all([ie({status:"pending",limit:6}),ne({limit:6})]);S(N.tasks||[]),_(v.tasks||[]),M(Z.tasks||[]),L(ee.approvals||[]),z(se.events||[]),o((y.workspaces||[]).map(x=>({name:x.name,agent_type:x.agentType,platforms:x.platforms,sessions_count:x.sessionsCount,heartbeat_enabled:x.heartbeatEnabled}))),i.status==="fulfilled"?d(i.runtimes):(d([]),p(((s=i.error)==null?void 0:s.message)||String(i.error)));return}const m=await ue();o(m.projects||[]),d([]),S([]),_([]),M([]),L([]),z([])}catch(m){T(m.message||String(m))}finally{C(!1)}},[c]),Y=r.useCallback(async()=>{D(!0),u(!0),p("");try{d(await ge())}catch(s){p(s.message||String(s))}finally{D(!1),u(!1)}},[]);return r.useEffect(()=>{k();const s=()=>k();window.addEventListener("cc:refresh",s);const m=c?fe(()=>{k()}):()=>{},y=c?je(i=>{if(i.type==="runtime.detect.started"){u(!0);return}if(i.type==="runtime.detect.completed"){u(!1),d(i.runtimes);return}if(i.type==="runtime.detect.failed"){u(!1),p(i.error);return}i.type==="runtime.status.changed"&&d(N=>N.map(v=>v.runtimeId===i.runtime.runtimeId?i.runtime:v))}):()=>{};return()=>{window.removeEventListener("cc:refresh",s),m(),y()}},[c,k]),G&&t.length===0?e.jsx("div",{className:"flex h-64 items-center justify-center text-muted-foreground",children:e.jsx(ye,{className:"animate-pulse",size:24})}):e.jsxs("div",{className:"animate-fade-in space-y-8",children:[e.jsx(he,{title:"概览",description:"继续最近的工作,或进入项目、知识和自动化配置。当前版本 v0.1.44"}),E?e.jsx("div",{role:"alert",className:"rounded-lg border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-700 dark:border-amber-400/20 dark:bg-amber-500/10 dark:text-amber-200",children:E}):null,e.jsxs("section",{className:"space-y-3",children:[e.jsx("div",{className:"flex items-end justify-between gap-4",children:e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-semibold tracking-tight text-foreground",children:"快速开始"}),e.jsx("p",{className:"mt-1 text-sm text-muted-foreground",children:"常用入口会保留在最前面。"})]})}),e.jsx("div",{className:"grid grid-cols-1 gap-3 lg:grid-cols-2",children:b.map(s=>e.jsx(Le,{...s},s.to))})]}),c?e.jsxs(g,{className:"overflow-hidden p-0",children:[e.jsxs("div",{className:"flex flex-col gap-3 border-b border-black/[0.08] px-5 py-4 dark:border-white/[0.07] sm:flex-row sm:items-center sm:justify-between",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-base font-semibold text-foreground",children:"本机 Agent Runtime"}),e.jsx("p",{className:"mt-1 text-sm text-muted-foreground",children:"显示本机 runtime 安装检测状态,不执行安装或登录检查。"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(n,{variant:B.length>0?"success":"default",children:[B.length," installed"]}),X?e.jsx(n,{variant:"info",children:"checking"}):null,e.jsxs(ce,{variant:"outline",size:"sm",loading:J,onClick:Y,title:"刷新 runtime 检测",children:[e.jsx(oe,{size:15}),"刷新"]})]})]}),P?e.jsxs("div",{className:"px-5 py-4 text-sm text-amber-700 dark:text-amber-200",children:["检测失败:",P]}):h.length===0?e.jsx("div",{className:"p-5",children:e.jsx(f,{message:"还没有 runtime 检测结果",icon:F})}):e.jsx("div",{className:"grid grid-cols-1 gap-3 p-5 md:grid-cols-2 xl:grid-cols-3",children:h.map(s=>e.jsxs("div",{className:"rounded-2xl border border-black/[0.08] bg-white/50 p-4 shadow-[0_8px_24px_rgba(15,23,42,0.05)] dark:border-white/[0.08] dark:bg-white/[0.055]",children:[e.jsxs("div",{className:"flex items-start justify-between gap-3",children:[e.jsxs("div",{className:"flex min-w-0 items-center gap-3",children:[e.jsx("div",{className:["flex h-10 w-10 shrink-0 items-center justify-center rounded-xl",s.status==="installed"?"bg-emerald-500/10 text-emerald-600 dark:text-emerald-300":s.status==="error"?"bg-red-500/10 text-red-600 dark:text-red-200":"bg-amber-500/10 text-amber-700 dark:text-amber-200"].join(" "),children:e.jsx(F,{size:19})}),e.jsxs("div",{className:"min-w-0",children:[e.jsx("p",{className:"truncate text-sm font-semibold text-foreground",children:s.displayName}),e.jsx("p",{className:"mt-0.5 truncate text-xs text-muted-foreground",children:s.agentType})]})]}),s.status==="installed"?e.jsx(Ae,{size:18,className:"mt-0.5 shrink-0 text-emerald-500"}):e.jsx(me,{size:18,className:"mt-0.5 shrink-0 text-amber-500"})]}),e.jsxs("div",{className:"mt-4 flex flex-wrap items-center gap-2",children:[e.jsx(n,{variant:s.status==="installed"?"success":s.status==="error"?"danger":"warning",children:s.status}),e.jsx(n,{children:s.source}),s.version?e.jsxs(n,{variant:"secondary",children:["v",s.version]}):null]}),e.jsx("p",{className:"mt-3 text-sm leading-5 text-muted-foreground",children:s.summary}),s.issues[0]?e.jsx("p",{className:"mt-2 text-xs leading-5 text-amber-700 dark:text-amber-200",children:s.issues[0].message}):null,s.binaryPath||s.command?e.jsx("p",{className:"mt-3 truncate rounded-lg bg-black/[0.045] px-2.5 py-2 font-mono text-xs text-muted-foreground dark:bg-white/[0.06]",children:s.binaryPath||s.command}):null,s.recommendedActions[0]?e.jsx("p",{className:"mt-3 text-xs leading-5 text-muted-foreground",children:s.recommendedActions[0].description}):null,e.jsxs("p",{className:"mt-3 text-xs text-muted-foreground",children:["Last checked ",new Date(s.detectedAt).toLocaleString()]})]},s.agentType))})]}):null,c?e.jsxs("section",{className:"grid grid-cols-1 gap-4 xl:grid-cols-3",children:[e.jsx(R,{title:"运行中任务",description:"正在排队或执行的 agent 工作。",tasks:l,empty:"暂无运行中的任务"}),e.jsx(R,{title:"等待处理",description:"需要用户输入或审批的任务。",tasks:V,empty:"暂无等待处理的任务",urgent:!0}),e.jsx(R,{title:"最近完成",description:"最近结束、失败或取消的任务。",tasks:K,empty:"暂无最近任务"})]}):null,c?e.jsxs("section",{className:"grid grid-cols-1 gap-4 xl:grid-cols-2",children:[e.jsx(ze,{approvals:O}),e.jsx(Ce,{events:Q})]}):null,e.jsxs(g,{className:"p-0",children:[e.jsxs("div",{className:"flex items-center justify-between gap-4 border-b border-black/[0.08] px-5 py-4 dark:border-white/[0.07]",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-base font-semibold text-foreground",children:a("nav.projects")}),e.jsx("p",{className:"mt-1 text-sm text-muted-foreground",children:"最近配置和会话概览。"})]}),e.jsx(A,{to:c?"/workspace":"/projects",className:"text-sm font-medium text-primary transition-colors hover:text-primary/80",children:a("common.viewAll")})]}),t.length===0?e.jsx("div",{className:"p-5",children:e.jsx(f,{message:a("projects.noProjects"),icon:W})}):e.jsx("div",{className:"divide-y divide-black/[0.08] dark:divide-white/[0.07]",children:t.slice(0,6).map(s=>{var m;return e.jsxs(A,{to:c?`/workspace?project=${encodeURIComponent(s.name)}`:`/projects/${s.name}`,className:"group flex items-center justify-between gap-3 px-5 py-4 transition-colors duration-200 hover:bg-black/[0.04] dark:hover:bg-white/[0.06]",children:[e.jsxs("div",{className:"flex min-w-0 items-center gap-3",children:[e.jsx("div",{className:"flex h-9 w-9 shrink-0 items-center justify-center rounded-xl bg-primary/10 text-primary",children:e.jsx(be,{size:17})}),e.jsxs("div",{className:"min-w-0",children:[e.jsx("p",{className:"truncate text-sm font-medium text-foreground",children:s.name}),e.jsxs("p",{className:"mt-0.5 truncate text-xs text-muted-foreground",children:[s.agent_type," · ",((m=s.platforms)==null?void 0:m.join(", "))||"no platform"," · ",s.sessions_count," sessions"]})]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[s.heartbeat_enabled?e.jsx(n,{variant:"success",children:"heartbeat"}):null,e.jsx(H,{size:16,className:"text-muted-foreground/45 transition-colors group-hover:text-foreground"})]})]},s.name)})})]})]})}export{Fe as default};
@@ -1,11 +0,0 @@
1
- import{c as T,r as a,aH as se,aI as te,y as ae,aJ as re,aK as ne,aL as ie,aM as le,aN as oe,aO as de,j as e,L,B as d,S as ce,C as x,g as $,h as me,I as C,aP as xe,E as ge,T as he}from"./index-B36eowj-.js";import{M as D}from"./Modal-DwY4lecS.js";import{E as P}from"./EmptyState-kD9yAwtw.js";import{P as R}from"./pencil-DLh9QNmT.js";import{T as O}from"./trash-2-DhtOCsO5.js";import{S as ue}from"./search-CniPk7Ey.js";import{P as pe}from"./plus-BSc8POsz.js";import{B as fe}from"./book-open-BNJMhNI-.js";import"./index-BNFx4uYv.js";/**
2
- * @license lucide-react v0.487.0 - ISC
3
- *
4
- * This source code is licensed under the ISC license.
5
- * See the LICENSE file in the root directory of this source tree.
6
- */const ye=[["path",{d:"M12 10v6",key:"1bos4e"}],["path",{d:"M9 13h6",key:"1uhe8q"}],["path",{d:"M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z",key:"1kt360"}]],je=T("folder-plus",ye);/**
7
- * @license lucide-react v0.487.0 - ISC
8
- *
9
- * This source code is licensed under the ISC license.
10
- * See the LICENSE file in the root directory of this source tree.
11
- */const ve=[["path",{d:"M20 17a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2h-3.9a2 2 0 0 1-1.69-.9l-.81-1.2a2 2 0 0 0-1.67-.9H8a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2Z",key:"4u7rpt"}],["path",{d:"M2 8v11a2 2 0 0 0 2 2h14",key:"1eicx1"}]],S=T("folders",ve);function _(o){return o==="success"?"border-violet-200 bg-violet-50 text-violet-700 dark:border-violet-900/30 dark:bg-violet-950/20 dark:text-violet-300":o==="warning"?"border-amber-200 bg-amber-50 text-amber-700 dark:border-amber-900/30 dark:bg-amber-950/20 dark:text-amber-300":"border-red-200 bg-red-50 text-red-700 dark:border-red-900/30 dark:bg-red-950/20 dark:text-red-300"}function be(o){switch(o){case"file":return"bg-blue-500";case"spark":return"bg-amber-500";case"screen":return"bg-fuchsia-500";default:return"bg-indigo-500"}}function we(o){return o.split("/").length-1}function ze(){const[o,F]=a.useState(!0),[m,q]=a.useState([]),[j,A]=a.useState([]),[l,v]=a.useState(null),[g,H]=a.useState(""),[U,V]=a.useState(!1),[Z,h]=a.useState(!1),[G,u]=a.useState(!1),[p,B]=a.useState(""),[f,K]=a.useState(""),[b,E]=a.useState(""),[w,r]=a.useState(null),[M,y]=a.useState(null),n=a.useCallback(async()=>{F(!0);try{const[s,t,i]=await Promise.all([se(),te(),ae()]);V(!!s.baseUrl),q(t.folders||[]),A(i.bases||[])}catch(s){r({tone:"error",message:s instanceof Error?s.message:String(s)})}finally{F(!1)}},[]);a.useEffect(()=>{n()},[n]);const N=a.useMemo(()=>{if(!l)return null;const s=m.find(i=>i.id===l);if(!s)return null;const t=new Set([s.id]);return m.forEach(i=>{i.path.startsWith(`${s.path}/`)&&t.add(i.id)}),t},[m,l]),z=a.useMemo(()=>{const s=g.trim().toLowerCase();return j.filter(t=>(N?N.has(t.folderId||""):!0)?s?[t.name,t.description,t.creatorName].join(" ").toLowerCase().includes(s):!0:!1)},[j,N,g]),J=a.useCallback(async()=>{if(!p.trim()){r({tone:"warning",message:"Folder name is required."});return}y("folder");try{await re({name:p.trim(),parentId:l}),B(""),h(!1),r({tone:"success",message:"Folder created."}),await n()}catch(s){r({tone:"error",message:s instanceof Error?s.message:String(s)})}finally{y(null)}},[p,n,l]),Q=a.useCallback(async()=>{if(!f.trim()){r({tone:"warning",message:"Knowledge base name is required."});return}y("base");try{await ne({name:f.trim(),description:b.trim(),folderId:l}),K(""),E(""),u(!1),r({tone:"success",message:"Knowledge base created."}),await n()}catch(s){r({tone:"error",message:s instanceof Error?s.message:String(s)})}finally{y(null)}},[b,f,n,l]),W=a.useCallback(async s=>{var i;const t=(i=window.prompt("Rename folder",s.name))==null?void 0:i.trim();if(!(!t||t===s.name))try{await ie(s.id,{name:t}),r({tone:"success",message:"Folder updated."}),await n()}catch(c){r({tone:"error",message:c instanceof Error?c.message:String(c)})}},[n]),X=a.useCallback(async s=>{if(window.confirm(`Delete folder "${s.name}"?`))try{await le(s.id),l===s.id&&v(null),r({tone:"success",message:"Folder deleted."}),await n()}catch(t){r({tone:"error",message:t instanceof Error?t.message:String(t)})}},[n,l]),Y=a.useCallback(async s=>{var c,I;const t=(c=window.prompt("Knowledge base name",s.name))==null?void 0:c.trim();if(!t)return;const i=((I=window.prompt("Description",s.description))==null?void 0:I.trim())??s.description;try{await oe(s.id,{name:t,description:i}),r({tone:"success",message:"Knowledge base updated."}),await n()}catch(k){r({tone:"error",message:k instanceof Error?k.message:String(k)})}},[n]),ee=a.useCallback(async s=>{if(window.confirm(`Delete knowledge base "${s.name}"?`))try{await de(s.id),r({tone:"success",message:"Knowledge base deleted."}),await n()}catch(t){r({tone:"error",message:t instanceof Error?t.message:String(t)})}},[n]);return e.jsxs("div",{className:"space-y-6 animate-fade-in",children:[w&&e.jsx("div",{className:`rounded-xl border px-4 py-3 text-sm ${_(w.tone)}`,children:w.message}),!U&&!o&&e.jsx("div",{className:`rounded-2xl border px-5 py-4 ${_("warning")}`,children:e.jsxs("div",{className:"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between",children:[e.jsxs("div",{children:[e.jsx("p",{className:"font-medium",children:"Knowledge search is not configured yet."}),e.jsx("p",{className:"mt-1 text-sm opacity-90",children:"Add the ai_vector base URL in System settings before uploading files or running retrieval."})]}),e.jsx(L,{to:"/system",children:e.jsxs(d,{variant:"secondary",children:[e.jsx(ce,{size:14})," Open System Settings"]})})]})}),e.jsxs("div",{className:"grid grid-cols-1 gap-6 xl:grid-cols-[300px_minmax(0,1fr)]",children:[e.jsxs(x,{className:"p-0 overflow-hidden",children:[e.jsx("div",{className:"border-b border-gray-200/80 px-5 py-4 dark:border-white/[0.08]",children:e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-xl font-semibold text-gray-900 dark:text-white",children:"知识库"}),e.jsx("p",{className:"mt-1 text-sm text-gray-500 dark:text-gray-400",children:"创建目录并管理知识库分类。"})]}),e.jsxs(d,{size:"sm",variant:"secondary",onClick:()=>h(!0),children:[e.jsx(je,{size:14})," 文件夹"]})]})}),e.jsx("div",{className:"px-5 py-4",children:e.jsxs("button",{type:"button",onClick:()=>v(null),className:$("flex w-full items-center justify-between rounded-xl px-3 py-2.5 text-left text-sm transition-colors",l?"hover:bg-gray-100/80 text-gray-600 dark:text-gray-300 dark:hover:bg-white/[0.06]":"bg-accent/10 text-gray-900 ring-1 ring-accent/30 dark:text-white"),children:[e.jsxs("span",{className:"flex items-center gap-2",children:[e.jsx(S,{size:16}),"全部知识库"]}),e.jsx("span",{className:"text-xs opacity-70",children:j.length})]})}),e.jsx("div",{className:"max-h-[70vh] overflow-y-auto px-3 pb-4",children:m.length===0?e.jsx(P,{message:"还没有目录,先创建一个文件夹吧。",icon:S}):e.jsx("div",{className:"space-y-1",children:m.map(s=>{const t=s.id===l;return e.jsx("div",{className:$("group rounded-xl px-2 py-1",t?"bg-accent/10 ring-1 ring-accent/25":"hover:bg-gray-100/80 dark:hover:bg-white/[0.04]"),children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("button",{type:"button",onClick:()=>v(s.id),className:"flex min-w-0 flex-1 items-center gap-2 rounded-lg px-2 py-2 text-left",style:{paddingLeft:`${8+we(s.path)*18}px`},children:[e.jsx(me,{size:14,className:"text-gray-400"}),e.jsx(S,{size:15,className:"text-amber-500"}),e.jsx("span",{className:"truncate text-sm text-gray-800 dark:text-gray-100",children:s.name})]}),e.jsx("button",{type:"button",onClick:()=>void W(s),className:"rounded-md p-1 text-gray-400 transition hover:bg-gray-200/70 hover:text-gray-700 dark:hover:bg-white/[0.08] dark:hover:text-white","aria-label":`Rename ${s.name}`,children:e.jsx(R,{size:14})}),e.jsx("button",{type:"button",onClick:()=>void X(s),className:"rounded-md p-1 text-gray-400 transition hover:bg-red-500/10 hover:text-red-500","aria-label":`Delete ${s.name}`,children:e.jsx(O,{size:14})})]})},s.id)})})})]}),e.jsxs("div",{className:"space-y-5",children:[e.jsx(x,{children:e.jsxs("div",{className:"flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-xl font-semibold text-gray-900 dark:text-white",children:"知识库列表"}),e.jsx("p",{className:"mt-1 text-sm text-gray-500 dark:text-gray-400",children:"目录筛选、本地搜索,以及知识库卡片概览都在这里。"})]}),e.jsxs("div",{className:"flex flex-col gap-3 sm:flex-row",children:[e.jsxs("div",{className:"relative min-w-[260px]",children:[e.jsx(ue,{size:16,className:"pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-gray-400"}),e.jsx(C,{value:g,onChange:s=>H(s.target.value),placeholder:"搜索名称、描述或创建者",className:"pl-9"})]}),e.jsxs(d,{variant:"secondary",onClick:()=>u(!0),children:[e.jsx(pe,{size:14})," 创建知识库"]})]})]})}),o?e.jsx(x,{children:e.jsx("div",{className:"py-16 text-center text-sm text-gray-400",children:"正在加载知识库…"})}):z.length===0?e.jsx(x,{children:e.jsx(P,{message:g?"没有匹配的知识库。":"还没有知识库,先创建一个开始上传文档。",icon:xe})}):e.jsx("div",{className:"grid grid-cols-1 gap-5 md:grid-cols-2 2xl:grid-cols-3",children:z.map(s=>e.jsxs(x,{className:"group relative overflow-hidden border border-gray-200/90 bg-white/90 p-6 shadow-sm hover:border-accent/30 hover:shadow-xl hover:shadow-black/5 dark:border-white/[0.08] dark:bg-[rgba(0,0,0,0.55)]",children:[e.jsxs("div",{className:"absolute right-4 top-4 flex gap-1",children:[e.jsx("button",{type:"button",onClick:()=>void Y(s),className:"rounded-lg p-2 text-gray-400 hover:bg-gray-100/90 hover:text-gray-700 dark:hover:bg-white/[0.08] dark:hover:text-white",children:e.jsx(R,{size:15})}),e.jsx("button",{type:"button",onClick:()=>void ee(s),className:"rounded-lg p-2 text-gray-400 hover:bg-red-500/10 hover:text-red-500",children:e.jsx(O,{size:15})})]}),e.jsxs(L,{to:`/knowledge/${encodeURIComponent(s.id)}`,className:"block space-y-5",children:[e.jsxs("div",{className:"flex items-start gap-4",children:[e.jsx("div",{className:`mt-1 flex h-12 w-12 items-center justify-center rounded-2xl text-white shadow-lg ${be(s.icon)}`,children:e.jsx(fe,{size:22})}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx("h3",{className:"truncate pr-8 text-xl font-semibold text-gray-900 dark:text-white",children:s.name}),e.jsxs("p",{className:"mt-1 text-sm text-gray-500 dark:text-gray-400",children:["创建者: ",s.creatorName||"系统管理员"]})]})]}),e.jsx("div",{className:"min-h-[72px] text-base leading-7 text-gray-600 dark:text-gray-300",children:s.description||"这个知识库还没有描述,点击进入后可以上传文件并开始检索。"}),e.jsxs("div",{className:"flex items-center gap-6 text-sm font-medium text-gray-700 dark:text-gray-200",children:[e.jsxs("span",{children:[s.fileCount," 文档数"]}),e.jsxs("span",{children:[(s.wordCount/1e3).toFixed(s.wordCount>0?1:0),"k 字符"]})]}),e.jsxs("div",{className:"text-xs text-gray-400 dark:text-gray-500",children:["更新于 ",ge(s.updatedAt)]})]})]},s.id))})]})]}),e.jsx(D,{open:Z,onClose:()=>h(!1),title:"创建文件夹",children:e.jsxs("div",{className:"space-y-4",children:[e.jsx(C,{label:"文件夹名称",value:p,onChange:s=>B(s.target.value),placeholder:"例如:产品文档"}),e.jsxs("div",{className:"flex justify-end gap-2",children:[e.jsx(d,{variant:"secondary",onClick:()=>h(!1),children:"取消"}),e.jsx(d,{onClick:()=>void J(),loading:M==="folder",children:"创建"})]})]})}),e.jsx(D,{open:G,onClose:()=>u(!1),title:"创建知识库",children:e.jsxs("div",{className:"space-y-4",children:[e.jsx(C,{label:"名称",value:f,onChange:s=>K(s.target.value),placeholder:"例如:运营文档库"}),e.jsx(he,{label:"描述",rows:4,value:b,onChange:s=>E(s.target.value),placeholder:"一句话说明这个知识库主要收录什么内容"}),e.jsxs("div",{className:"flex justify-end gap-2",children:[e.jsx(d,{variant:"secondary",onClick:()=>u(!1),children:"取消"}),e.jsx(d,{onClick:()=>void Q(),loading:M==="base",children:"创建"})]})]})})]})}export{ze as default};
@@ -1 +0,0 @@
1
- import{u as h,r as t,aF as v,j as e,L as j,B as d,C as y}from"./index-B36eowj-.js";import{B as N}from"./Badge-Qk9qHovH.js";import{S as m}from"./Select-zfoksLGB.js";import{P as b}from"./Page-CnB9ePsb.js";import{A as w}from"./arrow-left-CNEAuElg.js";import{F as L}from"./funnel-_5hsz0xI.js";import"./index-BNFx4uYv.js";import"./chevron-down-Bh53e0O-.js";import"./check-BnclClRU.js";const S={sys:"text-gray-300",debug:"text-gray-400",info:"text-blue-400",warn:"text-amber-400",error:"text-red-400"},C={sys:"default",debug:"default",info:"info",warn:"warning",error:"danger"};function I(){const{t:a}=h(),[l,x]=t.useState([]),[r,u]=t.useState("sys"),[n,f]=t.useState("100"),[g,i]=t.useState(!0),o=t.useCallback(async()=>{i(!0);try{const s=await v({level:r,limit:n});x(s.entries||[])}finally{i(!1)}},[r,n]);return t.useEffect(()=>{o()},[o]),e.jsxs("div",{className:"space-y-4 animate-fade-in",children:[e.jsx(b,{title:a("system.logs"),description:"Filtered runtime logs for troubleshooting.",actions:e.jsx(j,{to:"/system",children:e.jsxs(d,{variant:"secondary",size:"sm",children:[e.jsx(w,{size:14})," ",a("nav.system")]})})}),e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(L,{size:14,className:"text-muted-foreground"}),e.jsxs(m,{value:r,onChange:s=>u(s.target.value),className:"w-auto",children:[e.jsx("option",{value:"sys",children:"Sys"}),e.jsx("option",{value:"debug",children:"Debug"}),e.jsx("option",{value:"info",children:"Info"}),e.jsx("option",{value:"warn",children:"Warn"}),e.jsx("option",{value:"error",children:"Error"})]})]}),e.jsxs(m,{value:n,onChange:s=>f(s.target.value),className:"w-auto",children:[e.jsx("option",{value:"50",children:"50"}),e.jsx("option",{value:"100",children:"100"}),e.jsx("option",{value:"500",children:"500"}),e.jsx("option",{value:"1000",children:"1000"})]}),e.jsx(d,{size:"sm",variant:"secondary",onClick:o,children:a("common.refresh")})]}),e.jsx(y,{children:g?e.jsx("div",{className:"text-muted-foreground animate-pulse text-sm",children:"Loading..."}):l.length===0?e.jsx("p",{className:"text-sm text-muted-foreground text-center py-8",children:a("common.noData")}):e.jsx("div",{className:"space-y-1 max-h-[65vh] overflow-y-auto font-mono text-xs",children:l.map((s,p)=>{var c;return e.jsxs("div",{className:"flex items-start gap-3 py-1.5 border-b last:border-0",children:[e.jsx("span",{className:"text-muted-foreground shrink-0 w-36",children:(c=s.time)==null?void 0:c.slice(0,19)}),e.jsx(N,{variant:C[s.level]||"default",children:s.level}),e.jsx("span",{className:`${S[s.level]||"text-gray-500"} flex-1`,children:s.message})]},p)})})})]})}export{I as default};
@@ -1 +0,0 @@
1
- import{Q as q,l as D,U as W,V as B,X as F,Y as L,u as R,r as i,j as s,s as $,B as u,_ as O,C as U,E as V,I as x,T as H}from"./index-B36eowj-.js";import{B as h}from"./Badge-Qk9qHovH.js";import{M as Q}from"./Modal-DwY4lecS.js";import{S as b}from"./Select-zfoksLGB.js";import{E as X}from"./EmptyState-kD9yAwtw.js";import{P as Y}from"./Page-CnB9ePsb.js";import{P as Z}from"./plus-BSc8POsz.js";import{P as G}from"./play-BDTk9Scm.js";import{P as J}from"./pencil-DLh9QNmT.js";import{T as K}from"./trash-2-DhtOCsO5.js";import"./index-BNFx4uYv.js";import"./chevron-down-Bh53e0O-.js";import"./check-BnclClRU.js";const ee=t=>q(),te=t=>B(t),se=(t,n)=>W(t,n),ae=t=>F(t),ne=t=>L(t),oe=()=>D().then(t=>t.workspaces),g={workspaceId:"",title:"",sourceType:"stock.quote",symbol:"",condition:"abs_change_percent >= 3",promptTemplate:"",cooldownMinutes:"15",executionMode:"side-thread",enabled:!0};function k(t){const n=t.trim();if(n.includes("&&")||n.includes("||"))return{metric:"expression",operator:"==",value:!0,expression:n};const c=n.match(/^([a-zA-Z0-9_.-]+)\s*(>=|<=|==|!=|>|<)\s*(.+)$/);if(!c)return null;const l=String(c[3]||"").trim(),m=Number(l);return{metric:String(c[1]||"").trim(),operator:c[2],value:Number.isFinite(m)&&l!==""?m:l}}function C(t){return t.condition.expression?t.condition.expression:`${t.condition.metric} ${t.condition.operator} ${t.condition.value}`}function ie(t){return t?{workspaceId:t.workspaceId,title:t.title,sourceType:"stock.quote",symbol:String(t.sourceConfig.symbol||""),condition:C(t),promptTemplate:t.promptTemplate,cooldownMinutes:String(Math.round(t.cooldownMs/6e4)),executionMode:t.executionMode,enabled:t.enabled}:g}function re(t){const n=k(t.condition);if(!n)throw new Error("Invalid condition");return{workspaceId:t.workspaceId,title:t.title,sourceType:t.sourceType,sourceConfig:v[t.sourceType].buildConfig(t),condition:n,promptTemplate:t.promptTemplate,executionMode:t.executionMode,cooldownMs:Math.max(0,Number(t.cooldownMinutes||"0")*6e4),enabled:t.enabled}}const v={"stock.quote":{label:"Stock quote",buildConfig:t=>({symbol:t.symbol.toUpperCase()}),renderSummary:t=>String(t.sourceConfig.symbol||"")}};function ve(){const{t}=R(),[n,c]=i.useState([]),[l,m]=i.useState([]),[T,w]=i.useState(!0),[S,p]=i.useState(!1),[N,M]=i.useState(!1),[j,f]=i.useState(null),[a,o]=i.useState(g),I=i.useMemo(()=>l.map(e=>s.jsx("option",{value:e.id,children:e.name},e.id)),[l]),d=i.useCallback(async()=>{w(!0);try{const[e,r]=await Promise.all([ee(),oe()]);c(e.monitors||[]),m(r),o(y=>y.workspaceId||r.length===0?y:{...y,workspaceId:r[0].id})}finally{w(!1)}},[]);i.useEffect(()=>{d();const e=$(r=>{(r.type==="automation.monitor.updated"||r.type==="automation.monitor.run.updated")&&d()});return()=>e()},[d]);const E=()=>{var e;f(null),o({...g,workspaceId:((e=l[0])==null?void 0:e.id)||""}),p(!0)},A=e=>{f(e),o(ie(e)),p(!0)},P=async()=>{if(!(!a.workspaceId||!a.title.trim()||!a.symbol.trim()||!a.promptTemplate.trim()||!k(a.condition))){M(!0);try{const e=re(a);j?await se(j.id,e):await te(e),p(!1),f(null),o(g),await d()}finally{M(!1)}}},z=async e=>{confirm(t("common.confirmDelete"))&&(await ae(e),await d())},_=async e=>{await ne(e),await d()};return T&&n.length===0?s.jsx("div",{className:"flex h-64 items-center justify-center text-gray-400 animate-pulse",children:t("common.loading")}):s.jsxs("div",{className:"space-y-4 animate-fade-in",children:[s.jsx(Y,{title:t("monitors.title"),description:"Create event monitors that trigger agent analysis and stream results back to channels.",actions:s.jsxs(u,{onClick:E,children:[s.jsx(Z,{size:16})," ",t("monitors.add")]})}),n.length===0?s.jsx(X,{message:t("monitors.noMonitors"),icon:O}):s.jsx("div",{className:"space-y-3",children:n.map(e=>s.jsx(U,{children:s.jsxs("div",{className:"flex items-start justify-between gap-3",children:[s.jsxs("div",{className:"min-w-0 flex-1",children:[s.jsxs("div",{className:"mb-1 flex flex-wrap items-center gap-2",children:[s.jsx("span",{className:"text-sm font-medium text-gray-900 dark:text-white",children:e.title}),s.jsx(h,{variant:e.enabled?"success":"default",children:e.enabled?t("monitors.enabled"):"disabled"}),s.jsx(h,{variant:"default",children:e.sourceType}),s.jsx(h,{variant:"default",children:e.platform}),e.lastStatus&&s.jsx(h,{variant:e.lastStatus==="failed"?"danger":"default",children:e.lastStatus})]}),s.jsxs("div",{className:"mt-2 flex flex-wrap gap-x-4 gap-y-1 text-xs text-gray-500 dark:text-gray-400",children:[s.jsxs("span",{children:[s.jsx("strong",{children:"Workspace:"})," ",e.workspaceId]}),s.jsxs("span",{children:[s.jsx("strong",{children:"Subject:"})," ",v["stock.quote"].renderSummary(e)]}),s.jsxs("span",{children:[s.jsx("strong",{children:"Condition:"})," ",C(e)]}),s.jsxs("span",{children:[s.jsx("strong",{children:"Execution:"})," ",e.executionMode]}),s.jsxs("span",{children:[s.jsx("strong",{children:"Cooldown:"})," ",Math.round(e.cooldownMs/6e4),"m"]}),e.lastTriggeredAt&&s.jsxs("span",{children:[s.jsxs("strong",{children:[t("monitors.lastRun"),":"]})," ",V(e.lastTriggeredAt)]})]}),s.jsx("p",{className:"mt-2 whitespace-pre-wrap text-sm text-gray-700 dark:text-gray-300",children:e.promptTemplate}),e.lastError&&s.jsx("p",{className:"mt-2 text-xs text-red-500",children:e.lastError})]}),s.jsxs("div",{className:"flex gap-2",children:[s.jsx(u,{variant:"secondary",size:"sm",onClick:()=>_(e.id),title:t("monitors.run"),children:s.jsx(G,{size:14})}),s.jsx(u,{variant:"secondary",size:"sm",onClick:()=>A(e),title:t("common.save"),children:s.jsx(J,{size:14})}),s.jsx(u,{variant:"danger",size:"sm",onClick:()=>z(e.id),title:t("common.delete"),children:s.jsx(K,{size:14})})]})]})},e.id))}),s.jsx(Q,{open:S,title:t(j?"monitors.edit":"monitors.add"),onClose:()=>p(!1),children:s.jsxs("div",{className:"space-y-4",children:[s.jsx(b,{label:"Workspace",value:a.workspaceId,onChange:e=>o({...a,workspaceId:e.target.value}),children:I}),s.jsx(x,{label:t("monitors.monitorTitle"),value:a.title,onChange:e=>o({...a,title:e.target.value})}),s.jsx(b,{label:"Source",value:a.sourceType,onChange:e=>o({...a,sourceType:e.target.value}),children:Object.entries(v).map(([e,r])=>s.jsx("option",{value:e,children:r.label},e))}),a.sourceType==="stock.quote"&&s.jsx(x,{label:"Symbol",value:a.symbol,onChange:e=>o({...a,symbol:e.target.value}),placeholder:"AAPL"}),s.jsx(x,{label:t("monitors.condition"),value:a.condition,onChange:e=>o({...a,condition:e.target.value}),placeholder:"abs_change_percent >= 3"}),s.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[s.jsx(x,{label:t("monitors.cooldown"),value:a.cooldownMinutes,onChange:e=>o({...a,cooldownMinutes:e.target.value})}),s.jsxs(b,{label:"Execution",value:a.executionMode,onChange:e=>o({...a,executionMode:e.target.value}),children:[s.jsx("option",{value:"side-thread",children:"side-thread"}),s.jsx("option",{value:"same-thread",children:"same-thread"})]})]}),s.jsx(H,{label:t("monitors.prompt"),rows:6,value:a.promptTemplate,onChange:e=>o({...a,promptTemplate:e.target.value})}),s.jsxs("label",{className:"flex items-center gap-2 text-sm text-gray-700 dark:text-gray-300",children:[s.jsx("input",{type:"checkbox",checked:a.enabled,onChange:e=>o({...a,enabled:e.target.checked})}),t("monitors.enabled")]}),s.jsxs("div",{className:"flex justify-end gap-2",children:[s.jsx(u,{variant:"secondary",onClick:()=>p(!1),children:t("common.cancel")}),s.jsx(u,{onClick:P,disabled:N,children:t("common.save")})]})]})})]})}export{ve as default};
@@ -1,11 +0,0 @@
1
- import{c as L,A as i,u as O,D as Q,r,j as e,L as V,B as n,Z as W,g as _,C as m,I as p,E as X,G as Y}from"./index-B36eowj-.js";import{B as f}from"./Badge-Qk9qHovH.js";import{M as S}from"./Modal-DwY4lecS.js";import{E as z}from"./EmptyState-kD9yAwtw.js";import{P as ee,S as $}from"./Page-CnB9ePsb.js";import{g as se}from"./projects-DwfZwxDW.js";import{A as te}from"./arrow-left-CNEAuElg.js";import{H as I}from"./heart-u4Q1aOqj.js";import{P as ae}from"./plug-BG0JHW6B.js";import{P as re}from"./plus-BSc8POsz.js";import{C as ne}from"./check-BnclClRU.js";import{T as oe}from"./trash-2-DhtOCsO5.js";import{P as ie}from"./play-BDTk9Scm.js";import"./index-BNFx4uYv.js";/**
2
- * @license lucide-react v0.487.0 - ISC
3
- *
4
- * This source code is licensed under the ISC license.
5
- * See the LICENSE file in the root directory of this source tree.
6
- */const le=[["path",{d:"M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83z",key:"zw3jo"}],["path",{d:"M2 12a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 12",key:"1wduqc"}],["path",{d:"M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 17",key:"kqbvx6"}]],ce=L("layers",le);/**
7
- * @license lucide-react v0.487.0 - ISC
8
- *
9
- * This source code is licensed under the ISC license.
10
- * See the LICENSE file in the root directory of this source tree.
11
- */const de=[["rect",{x:"14",y:"4",width:"4",height:"16",rx:"1",key:"zuxfzm"}],["rect",{x:"6",y:"4",width:"4",height:"16",rx:"1",key:"1okwgv"}]],me=L("pause",de),xe=s=>i.get(`/projects/${s}/providers`),ue=(s,a)=>i.post(`/projects/${s}/providers`,a),pe=(s,a)=>i.delete(`/projects/${s}/providers/${a}`),he=(s,a)=>i.post(`/projects/${s}/providers/${a}/activate`),ve=s=>i.get(`/projects/${s}/models`),je=(s,a)=>i.post(`/projects/${s}/model`,{model:a}),fe=s=>i.get(`/projects/${s}/heartbeat`),ge=s=>i.post(`/projects/${s}/heartbeat/pause`),be=s=>i.post(`/projects/${s}/heartbeat/resume`),ye=s=>i.post(`/projects/${s}/heartbeat/run`),Ne=(s,a)=>i.post(`/projects/${s}/heartbeat/interval`,{minutes:a});function Te(){var k,C;const{t:s}=O(),{name:a}=Q(),[h,A]=r.useState("overview"),[d,M]=r.useState(null),[b,H]=r.useState([]),[we,E]=r.useState(""),[l,B]=r.useState(null),[y,T]=r.useState([]),[D,q]=r.useState(""),[R,N]=r.useState(!0),[U,v]=r.useState(!1),[c,x]=r.useState({name:"",api_key:"",base_url:"",model:""}),[Z,j]=r.useState(!1),[w,F]=r.useState("30"),o=r.useCallback(async()=>{if(a)try{N(!0);const[t,u,P,g]=await Promise.allSettled([se(a),xe(a),fe(a),ve(a)]);t.status==="fulfilled"&&M(t.value),u.status==="fulfilled"&&(H(u.value.providers||[]),E(u.value.active_provider||"")),P.status==="fulfilled"&&B(P.value),g.status==="fulfilled"&&(T(g.value.models||[]),q(g.value.current||""))}finally{N(!1)}},[a]);r.useEffect(()=>{o();const t=()=>o();return window.addEventListener("cc:refresh",t),()=>window.removeEventListener("cc:refresh",t)},[o]);const G=async()=>{!a||!c.name||(await ue(a,c),v(!1),x({name:"",api_key:"",base_url:"",model:""}),o())},K=async()=>{a&&(await Ne(a,parseInt(w)),j(!1),o())},J=[{key:"overview",icon:ce},{key:"providers",icon:W},{key:"heartbeat",icon:I}];return R&&!d?e.jsx("div",{className:"flex items-center justify-center h-64 text-muted-foreground animate-pulse",children:"Loading..."}):e.jsxs("div",{className:"space-y-6 animate-fade-in",children:[e.jsx(ee,{title:a,description:"Project overview, providers, and heartbeat status. Low-frequency settings are no longer editable in the daily UI.",actions:e.jsx(V,{to:"/projects",children:e.jsxs(n,{variant:"secondary",size:"sm",children:[e.jsx(te,{size:14})," Back"]})})}),d&&e.jsx(f,{variant:"info",children:d.agent_type}),e.jsx("div",{className:"flex gap-2",children:J.map(({key:t,icon:u})=>e.jsxs("button",{onClick:()=>A(t),className:_("flex items-center gap-2 px-4 py-2 rounded-lg text-sm font-medium transition-all",h===t?"bg-primary text-primary-foreground shadow-md":"bg-secondary text-secondary-foreground hover:bg-secondary/80"),children:[e.jsx(u,{size:16}),s(`projects.tabs.${t}`)]},t))}),h==="overview"&&d&&e.jsxs("div",{className:"space-y-4",children:[e.jsx($,{title:s("projects.platforms"),children:e.jsx("div",{className:"flex flex-wrap gap-2",children:(k=d.platforms)==null?void 0:k.map(t=>e.jsxs(f,{variant:t.connected?"success":"danger",children:[e.jsx(ae,{size:12,className:"mr-1"})," ",t.type," ",t.connected?"✓":"✗"]},t.type))})}),e.jsxs($,{title:s("sessions.title"),children:[e.jsxs("p",{className:"text-sm text-muted-foreground",children:[d.sessions_count," ",s("nav.sessions").toLowerCase()]}),((C=d.active_session_keys)==null?void 0:C.length)>0&&e.jsx("div",{className:"mt-2 flex flex-wrap gap-1",children:d.active_session_keys.map(t=>e.jsx(f,{variant:"default",children:t},t))})]})]}),h==="providers"&&e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex justify-between items-center",children:[e.jsx("h3",{className:"text-sm font-semibold text-foreground",children:s("providers.title")}),e.jsxs(n,{size:"sm",onClick:()=>v(!0),children:[e.jsx(re,{size:14})," ",s("providers.add")]})]}),b.length===0?e.jsx(z,{message:s("common.noData")}):e.jsx("div",{className:"space-y-2",children:b.map(t=>e.jsx(m,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"font-medium text-foreground",children:t.name}),t.active&&e.jsx(f,{variant:"success",children:s("providers.active")})]}),e.jsxs("p",{className:"text-xs text-muted-foreground mt-1",children:[t.model," ",t.base_url?`· ${t.base_url}`:""]})]}),e.jsxs("div",{className:"flex gap-2",children:[!t.active&&e.jsxs(n,{size:"sm",variant:"secondary",onClick:()=>{he(a,t.name).then(o)},children:[e.jsx(ne,{size:14})," ",s("providers.activate")]}),!t.active&&e.jsx(n,{size:"sm",variant:"danger",onClick:()=>{pe(a,t.name).then(o)},children:e.jsx(oe,{size:14})})]})]})},t.name))}),y.length>0&&e.jsxs(m,{children:[e.jsx("h3",{className:"text-sm font-semibold text-foreground mb-3",children:s("providers.models")}),e.jsx("div",{className:"flex flex-wrap gap-2",children:y.map(t=>e.jsx("button",{onClick:()=>{je(a,t).then(o)},className:_("px-3 py-1.5 rounded-lg text-xs font-medium transition-all",t===D?"bg-primary/15 text-primary border border-primary/30":"bg-secondary text-secondary-foreground hover:bg-secondary/80"),children:t},t))})]}),e.jsx(S,{open:U,onClose:()=>v(!1),title:s("providers.add"),children:e.jsxs("div",{className:"space-y-3",children:[e.jsx(p,{label:s("providers.name"),value:c.name,onChange:t=>x({...c,name:t.target.value})}),e.jsx(p,{label:"API Key",type:"password",value:c.api_key,onChange:t=>x({...c,api_key:t.target.value})}),e.jsx(p,{label:s("providers.baseUrl"),value:c.base_url,onChange:t=>x({...c,base_url:t.target.value}),placeholder:"https://api.example.com"}),e.jsx(p,{label:s("providers.model"),value:c.model,onChange:t=>x({...c,model:t.target.value})}),e.jsxs("div",{className:"flex justify-end gap-2 pt-2",children:[e.jsx(n,{variant:"secondary",onClick:()=>v(!1),children:s("common.cancel")}),e.jsx(n,{onClick:G,children:s("providers.add")})]})]})})]}),h==="heartbeat"&&e.jsxs("div",{className:"space-y-4",children:[l?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-4 gap-4",children:[e.jsxs(m,{children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:s("heartbeat.status")}),e.jsx("p",{className:"text-lg font-bold text-foreground mt-1",children:l.paused?s("heartbeat.paused"):s("heartbeat.running")})]}),e.jsxs(m,{children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:s("heartbeat.interval")}),e.jsxs("p",{className:"text-lg font-bold text-foreground mt-1",children:[l.interval_mins,"m"]})]}),e.jsxs(m,{children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:s("heartbeat.runCount")}),e.jsx("p",{className:"text-lg font-bold text-foreground mt-1",children:l.run_count})]}),e.jsxs(m,{children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:s("heartbeat.errorCount")}),e.jsx("p",{className:"text-lg font-bold text-foreground mt-1",children:l.error_count})]})]}),e.jsx(m,{children:e.jsxs("div",{className:"space-y-2 text-sm",children:[e.jsxs("p",{className:"text-muted-foreground",children:[s("heartbeat.lastRun"),": ",e.jsx("span",{className:"text-foreground",children:X(l.last_run)})]}),e.jsxs("p",{className:"text-muted-foreground",children:[s("heartbeat.skippedBusy"),": ",e.jsx("span",{className:"text-foreground",children:l.skipped_busy})]}),l.last_error&&e.jsx("p",{className:"text-destructive",children:l.last_error})]})}),e.jsxs("div",{className:"flex gap-2",children:[l.paused?e.jsxs(n,{onClick:()=>{be(a).then(o)},children:[e.jsx(ie,{size:14})," ",s("heartbeat.resume")]}):e.jsxs(n,{variant:"secondary",onClick:()=>{ge(a).then(o)},children:[e.jsx(me,{size:14})," ",s("heartbeat.pause")]}),e.jsxs(n,{variant:"secondary",onClick:()=>{ye(a).then(o)},children:[e.jsx(I,{size:14})," ",s("heartbeat.trigger")]}),e.jsxs(n,{variant:"secondary",onClick:()=>j(!0),children:[e.jsx(Y,{size:14})," ",s("heartbeat.setInterval")]})]})]}):e.jsx(z,{message:s("common.noData")}),e.jsx(S,{open:Z,onClose:()=>j(!1),title:s("heartbeat.setInterval"),children:e.jsxs("div",{className:"space-y-3",children:[e.jsx(p,{label:`${s("heartbeat.interval")} (min)`,type:"number",value:w,onChange:t=>F(t.target.value)}),e.jsxs("div",{className:"flex justify-end gap-2 pt-2",children:[e.jsx(n,{variant:"secondary",onClick:()=>j(!1),children:s("common.cancel")}),e.jsx(n,{onClick:K,children:s("common.save")})]})]})})]})]})}export{Te as default};