@kafca/agentdock 0.1.42 → 0.1.43

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 (98) hide show
  1. package/README.md +4 -0
  2. package/dist/renderer/assets/{Badge-D-WU4kUV.js → Badge-CbG6yRSm.js} +1 -1
  3. package/dist/renderer/assets/{Chat-BGkC5tAe.js → Chat-BvNNWGGX.js} +1 -1
  4. package/dist/renderer/assets/{ChatMarkdown-CfbC1jRd.js → ChatMarkdown-Ct-PvJB8.js} +1 -1
  5. package/dist/renderer/assets/{Config-qQb4bX5D.js → Config-lQX2qVVV.js} +2 -2
  6. package/dist/renderer/assets/CronList-Dj_3muVG.js +1 -0
  7. package/dist/renderer/assets/{Dashboard-xn6cUy_n.js → Dashboard-eh_RhGYb.js} +2 -2
  8. package/dist/renderer/assets/{EmptyState-BdKBBUpr.js → EmptyState-Bn2Qh14U.js} +1 -1
  9. package/dist/renderer/assets/{KnowledgeDetail-Duk8IQP3.js → KnowledgeDetail-Bsz6Ou41.js} +2 -2
  10. package/dist/renderer/assets/{KnowledgeHome-BfjX_4Sv.js → KnowledgeHome-Cgj4XFXn.js} +2 -2
  11. package/dist/renderer/assets/{Logs-Bfq61QMn.js → Logs-Dp-NF6GN.js} +1 -1
  12. package/dist/renderer/assets/{Modal-B3vlBmBr.js → Modal-B6YPPBN6.js} +1 -1
  13. package/dist/renderer/assets/MonitorList-xEZWg460.js +1 -0
  14. package/dist/renderer/assets/{Page-CPsLOP3z.js → Page-Bn7RjGOS.js} +1 -1
  15. package/dist/renderer/assets/{ProjectDetail-D-g46wyF.js → ProjectDetail-Cv_jIE61.js} +2 -2
  16. package/dist/renderer/assets/{ProjectList-BrQEKDQ8.js → ProjectList-BDk5_gqY.js} +1 -1
  17. package/dist/renderer/assets/{Select-C4CFMQmF.js → Select-xshfMIEQ.js} +1 -1
  18. package/dist/renderer/assets/SessionChat-BkHy90z3.js +1 -0
  19. package/dist/renderer/assets/{SessionList-DPWIUbOg.js → SessionList-BZyXT92L.js} +1 -1
  20. package/dist/renderer/assets/{ThreadChat-BjtU-j9q.js → ThreadChat-DUOIyXrS.js} +7 -7
  21. package/dist/renderer/assets/{Workspace-BcNmHuJx.js → Workspace-Dl80fNEC.js} +1 -1
  22. package/dist/renderer/assets/{arrow-left-DPzSmidS.js → arrow-left-C54ZI-AS.js} +1 -1
  23. package/dist/renderer/assets/{book-open-B0xhoRqZ.js → book-open-Dl7GO0zn.js} +1 -1
  24. package/dist/renderer/assets/{check-BTJTyd0C.js → check-CiqgtrOL.js} +1 -1
  25. package/dist/renderer/assets/{chevron-down-B6jJXlhi.js → chevron-down-DTL2OuVh.js} +1 -1
  26. package/dist/renderer/assets/{circle-qRhJR9qR.js → circle-DaVKfa3P.js} +1 -1
  27. package/dist/renderer/assets/desktop-C6q6wBae.js +5 -0
  28. package/dist/renderer/assets/desktop-jaAiayNB.js +1 -0
  29. package/dist/renderer/assets/en-D2SkCrhG.js +1 -0
  30. package/dist/renderer/assets/{funnel-CbYKGTn8.js → funnel-CrmnLMJI.js} +1 -1
  31. package/dist/renderer/assets/{heart-DjwWJfkz.js → heart-BMfQI7y_.js} +1 -1
  32. package/dist/renderer/assets/{index-BWmHJRhe.js → index-HPNb1zfx.js} +39 -34
  33. package/dist/renderer/assets/{index-CyZs_2NJ.js → index-nreiKY1f.js} +3 -3
  34. package/dist/renderer/assets/{pencil-1dfAivmj.js → pencil-wTQ4l465.js} +1 -1
  35. package/dist/renderer/assets/{play-CB3w1G6S.js → play-BK--MXmw.js} +1 -1
  36. package/dist/renderer/assets/{plug-Bvep5o3r.js → plug-BIx9fjip.js} +1 -1
  37. package/dist/renderer/assets/{plus-DJVg9m09.js → plus-Dn7JFWQ8.js} +1 -1
  38. package/dist/renderer/assets/projects-brJZgwEJ.js +1 -0
  39. package/dist/renderer/assets/{save-xjJn3qf2.js → save-CC3zOSWb.js} +1 -1
  40. package/dist/renderer/assets/{search-BK3UrQxM.js → search-CDTy9Czu.js} +1 -1
  41. package/dist/renderer/assets/{server-Dyd2eXJu.js → server-DtQk3t2a.js} +1 -1
  42. package/dist/renderer/assets/{session-utils-eXC0020s.js → session-utils-4ep5D66T.js} +1 -1
  43. package/dist/renderer/assets/{sessions-WLYpkyUt.js → sessions-Dor1LteH.js} +1 -1
  44. package/dist/renderer/assets/{shield-check-C0N6aWzF.js → shield-check-Cz2LpU6r.js} +1 -1
  45. package/dist/renderer/assets/{trash-2-BGMTNJA6.js → trash-2-C2EmWFZV.js} +1 -1
  46. package/dist/renderer/assets/{user-BcGMLyhu.js → user-I8B-cs5A.js} +1 -1
  47. package/dist/renderer/assets/{wifi-off-FhcQx0HK.js → wifi-off-CPevTQJn.js} +1 -1
  48. package/dist/renderer/assets/zh-DIcdHycM.js +1 -0
  49. package/dist/renderer/index.html +1 -1
  50. package/dist-electron/packages/contracts/src/local-core.js +28 -0
  51. package/dist-electron/packages/core-sdk/src/index.js +32 -0
  52. package/dist-electron/services/local-ai-core/src/acp/local-core-acp-backend.js +51 -0
  53. package/dist-electron/services/local-ai-core/src/acp/local-core-acp-store.js +4 -1364
  54. package/dist-electron/services/local-ai-core/src/acp/store/agent-task-store.js +166 -0
  55. package/dist-electron/services/local-ai-core/src/acp/store/automation-monitor-store.js +231 -0
  56. package/dist-electron/services/local-ai-core/src/acp/store/local-core-acp-store.js +263 -0
  57. package/dist-electron/services/local-ai-core/src/acp/store/platform-store.js +186 -0
  58. package/dist-electron/services/local-ai-core/src/acp/store/scheduler-store.js +201 -0
  59. package/dist-electron/services/local-ai-core/src/acp/store/schema.js +275 -0
  60. package/dist-electron/services/local-ai-core/src/acp/store/security-store.js +266 -0
  61. package/dist-electron/services/local-ai-core/src/acp/store/thread-store.js +232 -0
  62. package/dist-electron/services/local-ai-core/src/acp/store/utils.js +47 -0
  63. package/dist-electron/services/local-ai-core/src/acp/store/workspace-registry-store.js +109 -0
  64. package/dist-electron/services/local-ai-core/src/automation/automation-conversation-executor.js +136 -0
  65. package/dist-electron/services/local-ai-core/src/automation/automation-monitor-repository.js +56 -0
  66. package/dist-electron/services/local-ai-core/src/automation/automation-monitor-service.js +359 -0
  67. package/dist-electron/services/local-ai-core/src/automation/condition-evaluator.js +77 -0
  68. package/dist-electron/services/local-ai-core/src/automation/mock-stock-provider.js +40 -0
  69. package/dist-electron/services/local-ai-core/src/automation/monitor-id.js +10 -0
  70. package/dist-electron/services/local-ai-core/src/channel/lark/cards.js +55 -0
  71. package/dist-electron/services/local-ai-core/src/channel/lark/local-core-lark-gateway.js +101 -29
  72. package/dist-electron/services/local-ai-core/src/channel/shared/session-command-runtime.js +53 -0
  73. package/dist-electron/services/local-ai-core/src/channel/weixin/local-core-weixin-gateway.js +51 -33
  74. package/dist-electron/services/local-ai-core/src/cli/lac.js +196 -0
  75. package/dist-electron/services/local-ai-core/src/cli/monitor-cli-parsers.js +37 -0
  76. package/dist-electron/services/local-ai-core/src/kernel/bootstrap.js +43 -0
  77. package/dist-electron/services/local-ai-core/src/kernel/capability-registry.js +12 -0
  78. package/dist-electron/services/local-ai-core/src/plugins/builtin/monitor-stock-plugin.js +30 -0
  79. package/dist-electron/services/local-ai-core/src/runtime/local-core-controller.js +41 -0
  80. package/dist-electron/services/local-ai-core/src/runtime/server-routes.js +31 -0
  81. package/dist-electron/services/local-ai-core/src/runtime/server.js +36 -0
  82. package/dist-electron/services/local-ai-core/src/scheduler/scheduled-bridge-session.js +25 -11
  83. package/dist-electron/services/local-ai-core/src/thread/session-command-service.js +275 -0
  84. package/dist-electron/services/local-ai-core/src/thread/slash-command-registry.js +27 -0
  85. package/dist-electron/services/local-ai-core/src/thread/thread-command-service.js +15 -15
  86. package/dist-electron/shared/desktop.js +21 -1
  87. package/dist-electron/tests/contracts/local-core-contracts.test.js +9 -0
  88. package/dist-electron/tests/electron/automation-monitor.test.js +38 -0
  89. package/dist-electron/tests/electron/lac-cli.test.js +146 -0
  90. package/dist-electron/tests/integration/local-core-refactor.test.js +194 -0
  91. package/package.json +1 -1
  92. package/dist/renderer/assets/CronList-CKhggzYk.js +0 -1
  93. package/dist/renderer/assets/SessionChat-06Jny5_G.js +0 -1
  94. package/dist/renderer/assets/desktop-DXmXjjUR.js +0 -1
  95. package/dist/renderer/assets/desktop-O8_6ZCVZ.js +0 -4
  96. package/dist/renderer/assets/en-CKhCF6St.js +0 -1
  97. package/dist/renderer/assets/projects-xnW0fTtq.js +0 -1
  98. package/dist/renderer/assets/zh-Dz5FLTBV.js +0 -1
@@ -326,6 +326,152 @@ function createIo() {
326
326
  });
327
327
  strict_1.default.match(read().stdout, /Sent file absolute\.pdf to chat-1: msg-file-2/);
328
328
  });
329
+ (0, node_test_1.default)('lac monitor add posts thread context and stock source config', async () => {
330
+ let capturedBody = null;
331
+ const server = (0, node_http_1.createServer)(async (req, res) => {
332
+ if (req.method === 'POST' && req.url === '/api/local/v1/automation/monitors') {
333
+ const chunks = [];
334
+ for await (const chunk of req) {
335
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
336
+ }
337
+ capturedBody = Buffer.concat(chunks).toString('utf8');
338
+ res.setHeader('content-type', 'application/json');
339
+ res.end(JSON.stringify({
340
+ ok: true,
341
+ data: {
342
+ id: 'monitor:826aff79-570b-4308-822e-18318e2c96ba',
343
+ workspaceId: '知识库',
344
+ title: 'AAPL swing',
345
+ sourceType: 'stock.quote',
346
+ sourceConfig: { symbol: 'AAPL', price: 188.5 },
347
+ condition: { metric: 'abs_change_percent', operator: '>=', value: 3 },
348
+ promptTemplate: 'analyze AAPL',
349
+ platform: 'lark',
350
+ route: { type: 'channel.chat', channelId: 'chat-1', participantId: 'user-1' },
351
+ executionMode: 'side-thread',
352
+ enabled: true,
353
+ cooldownMs: 900000,
354
+ concurrencyPolicy: 'skip_if_running',
355
+ createdAt: '2026-04-22T06:00:00.000Z',
356
+ updatedAt: '2026-04-22T06:00:00.000Z',
357
+ },
358
+ }));
359
+ return;
360
+ }
361
+ res.statusCode = 404;
362
+ res.end(JSON.stringify({ ok: false, error: 'not found' }));
363
+ });
364
+ await new Promise((resolve) => server.listen(0, '127.0.0.1', resolve));
365
+ const address = server.address();
366
+ (0, strict_1.default)(address && typeof address === 'object');
367
+ const { io, read } = createIo();
368
+ const exitCode = await (0, lac_js_1.runCli)([
369
+ 'monitor',
370
+ 'add',
371
+ '--title',
372
+ 'AAPL swing',
373
+ '--source',
374
+ 'stock.quote',
375
+ '--symbol',
376
+ 'aapl',
377
+ '--price',
378
+ '188.5',
379
+ '--condition',
380
+ 'abs_change_percent >= 3',
381
+ '--message',
382
+ 'analyze AAPL',
383
+ ], {
384
+ LOCAL_AI_CORE_BASE: `http://127.0.0.1:${address.port}/api/local/v1`,
385
+ LOCAL_AI_WORKSPACE_ID: '知识库',
386
+ LOCAL_AI_THREAD_ID: 'thread-1',
387
+ LOCAL_AI_PLATFORM: 'lark',
388
+ LOCAL_AI_CHAT_ID: 'chat-1',
389
+ LOCAL_AI_PLATFORM_USER_ID: 'user-1',
390
+ }, io);
391
+ server.close();
392
+ strict_1.default.equal(exitCode, 0);
393
+ (0, strict_1.default)(capturedBody);
394
+ strict_1.default.deepEqual(JSON.parse(capturedBody), {
395
+ workspaceId: '知识库',
396
+ threadId: 'thread-1',
397
+ title: 'AAPL swing',
398
+ sourceType: 'stock.quote',
399
+ sourceConfig: { symbol: 'AAPL', price: 188.5 },
400
+ condition: { metric: 'abs_change_percent', operator: '>=', value: 3 },
401
+ promptTemplate: 'analyze AAPL',
402
+ executionMode: 'side-thread',
403
+ cooldownMs: 900000,
404
+ enabled: true,
405
+ });
406
+ strict_1.default.match(read().stdout, /Created monitor 826aff79/);
407
+ });
408
+ (0, node_test_1.default)('lac monitor list filters by current thread context', async () => {
409
+ const server = (0, node_http_1.createServer)((req, res) => {
410
+ if (req.method === 'GET' && req.url === '/api/local/v1/automation/monitors?workspace_id=%E7%9F%A5%E8%AF%86%E5%BA%93') {
411
+ res.setHeader('content-type', 'application/json');
412
+ res.end(JSON.stringify({
413
+ ok: true,
414
+ data: {
415
+ monitors: [
416
+ {
417
+ id: 'monitor-1',
418
+ workspaceId: '知识库',
419
+ title: 'current',
420
+ sourceType: 'stock.quote',
421
+ sourceConfig: { symbol: 'AAPL' },
422
+ condition: { metric: 'abs_change_percent', operator: '>=', value: 3 },
423
+ promptTemplate: 'ping',
424
+ platform: 'lark',
425
+ route: { type: 'channel.chat', channelId: 'chat-1', participantId: 'user-1' },
426
+ executionMode: 'side-thread',
427
+ enabled: true,
428
+ cooldownMs: 900000,
429
+ concurrencyPolicy: 'skip_if_running',
430
+ createdAt: '2026-04-22T06:00:00.000Z',
431
+ updatedAt: '2026-04-22T06:00:00.000Z',
432
+ },
433
+ {
434
+ id: 'monitor-2',
435
+ workspaceId: '知识库',
436
+ title: 'other',
437
+ sourceType: 'stock.quote',
438
+ sourceConfig: { symbol: 'MSFT' },
439
+ condition: { metric: 'abs_change_percent', operator: '>=', value: 3 },
440
+ promptTemplate: 'pong',
441
+ platform: 'lark',
442
+ route: { type: 'channel.chat', channelId: 'chat-2', participantId: 'user-2' },
443
+ executionMode: 'side-thread',
444
+ enabled: true,
445
+ cooldownMs: 900000,
446
+ concurrencyPolicy: 'skip_if_running',
447
+ createdAt: '2026-04-22T06:00:00.000Z',
448
+ updatedAt: '2026-04-22T06:00:00.000Z',
449
+ },
450
+ ],
451
+ },
452
+ }));
453
+ return;
454
+ }
455
+ res.statusCode = 404;
456
+ res.end(JSON.stringify({ ok: false, error: 'not found' }));
457
+ });
458
+ await new Promise((resolve) => server.listen(0, '127.0.0.1', resolve));
459
+ const address = server.address();
460
+ (0, strict_1.default)(address && typeof address === 'object');
461
+ const { io, read } = createIo();
462
+ const exitCode = await (0, lac_js_1.runCli)(['monitor', 'list', '--thread'], {
463
+ LOCAL_AI_CORE_BASE: `http://127.0.0.1:${address.port}/api/local/v1`,
464
+ LOCAL_AI_WORKSPACE_ID: '知识库',
465
+ LOCAL_AI_THREAD_ID: 'thread-1',
466
+ LOCAL_AI_PLATFORM: 'lark',
467
+ LOCAL_AI_CHAT_ID: 'chat-1',
468
+ LOCAL_AI_PLATFORM_USER_ID: 'user-1',
469
+ }, io);
470
+ server.close();
471
+ strict_1.default.equal(exitCode, 0);
472
+ strict_1.default.match(read().stdout, /monitor-1/);
473
+ strict_1.default.doesNotMatch(read().stdout, /monitor-2/);
474
+ });
329
475
  (0, node_test_1.default)('lac scheduler list shows workspace jobs by default', async () => {
330
476
  const server = (0, node_http_1.createServer)((req, res) => {
331
477
  if (req.method === 'GET' && req.url === '/api/local/v1/scheduler/jobs?workspace_id=%E7%9F%A5%E8%AF%86%E5%BA%93') {
@@ -17,10 +17,12 @@ const lark_execution_policies_js_1 = require("../../services/local-ai-core/src/s
17
17
  const local_schedule_adapter_js_1 = require("../../services/local-ai-core/src/scheduler/local-schedule-adapter.js");
18
18
  const local_core_weixin_gateway_js_1 = require("../../services/local-ai-core/src/channel/weixin/local-core-weixin-gateway.js");
19
19
  const local_core_lark_gateway_js_1 = require("../../services/local-ai-core/src/channel/lark/local-core-lark-gateway.js");
20
+ const cards_js_1 = require("../../services/local-ai-core/src/channel/lark/cards.js");
20
21
  const runtime_state_js_1 = require("../../services/local-ai-core/src/channel/lark/runtime-state.js");
21
22
  const local_core_acp_backend_js_1 = require("../../services/local-ai-core/src/acp/local-core-acp-backend.js");
22
23
  const local_core_acp_turn_coordinator_js_1 = require("../../services/local-ai-core/src/acp/local-core-acp-turn-coordinator.js");
23
24
  const local_core_acp_store_js_1 = require("../../services/local-ai-core/src/acp/local-core-acp-store.js");
25
+ const session_command_service_js_1 = require("../../services/local-ai-core/src/thread/session-command-service.js");
24
26
  const thread_command_service_js_1 = require("../../services/local-ai-core/src/thread/thread-command-service.js");
25
27
  const local_core_acp_progress_js_1 = require("../../services/local-ai-core/src/acp/local-core-acp-progress.js");
26
28
  const local_core_acp_permission_lifecycle_js_1 = require("../../services/local-ai-core/src/acp/local-core-acp-permission-lifecycle.js");
@@ -3899,6 +3901,198 @@ function findLarkPostMdText(content) {
3899
3901
  (0, node_fs_1.rmSync)(dir, { recursive: true, force: true });
3900
3902
  }
3901
3903
  });
3904
+ (0, node_test_1.default)('session command matcher resolves by number, id, title, and excerpt in order', () => {
3905
+ const threads = [
3906
+ { id: 'thread-alpha-123', title: 'Alpha notes', excerpt: 'budget review', historyCount: 2, updatedAt: '2026-05-11T08:00:00.000Z' },
3907
+ { id: 'thread-beta-456', title: 'Beta plan', excerpt: 'alpha appears here', historyCount: 1, updatedAt: '2026-05-11T07:00:00.000Z' },
3908
+ { id: 'thread-gamma-789', title: 'Gamma', excerpt: 'release checklist', historyCount: 4, updatedAt: '2026-05-11T06:00:00.000Z' },
3909
+ ];
3910
+ strict_1.default.equal((0, session_command_service_js_1.matchThread)(threads, '2')?.id, 'thread-beta-456');
3911
+ strict_1.default.equal((0, session_command_service_js_1.matchThread)(threads, 'thread-gamma')?.id, 'thread-gamma-789');
3912
+ strict_1.default.equal((0, session_command_service_js_1.matchThread)(threads, 'Beta plan')?.id, 'thread-beta-456');
3913
+ strict_1.default.equal((0, session_command_service_js_1.matchThread)(threads, 'Alpha')?.id, 'thread-alpha-123');
3914
+ strict_1.default.equal((0, session_command_service_js_1.matchThread)(threads, 'release')?.id, 'thread-gamma-789');
3915
+ });
3916
+ (0, node_test_1.default)('session slash commands manage thread sessions through shared operations', async () => {
3917
+ const dir = (0, node_fs_1.mkdtempSync)((0, node_path_1.join)((0, node_os_1.tmpdir)(), 'agentdock-session-command-'));
3918
+ try {
3919
+ const store = new local_core_acp_store_js_1.LocalCoreAcpStore(dir);
3920
+ const current = store.createThread('workspace-a', 'Current', 'codex');
3921
+ const other = store.createThread('workspace-a', 'Other session', 'codex');
3922
+ store.appendMessage(current.id, 'user', 'ping', 'final');
3923
+ store.appendMessage(current.id, 'assistant', 'pong', 'final');
3924
+ const service = new session_command_service_js_1.SessionCommandService({
3925
+ listThreads: (workspaceId) => store.listThreadSummaries(workspaceId),
3926
+ getThread: (threadId) => store.getThread(threadId, []),
3927
+ createThread: (workspaceId, title) => store.createThread(workspaceId, title, 'codex'),
3928
+ renameThread: (threadId, title) => {
3929
+ store.renameThread(threadId, title);
3930
+ return store.getThread(threadId, []);
3931
+ },
3932
+ deleteThread: (threadId) => {
3933
+ store.deleteThread(threadId);
3934
+ return { deleted: true };
3935
+ },
3936
+ });
3937
+ const context = { workspaceId: 'workspace-a', currentThreadId: current.id, defaultTitle: 'Untitled' };
3938
+ const listResult = await service.execute('/list', context);
3939
+ strict_1.default.equal(listResult.handled, true);
3940
+ strict_1.default.match(listResult.displayText, /会话列表/);
3941
+ strict_1.default.ok(listResult.card?.actions.flat().some((action) => action.command.startsWith('/switch ')));
3942
+ const historyResult = await service.execute('/history 2', context);
3943
+ strict_1.default.match(historyResult.displayText, /ping/);
3944
+ strict_1.default.match(historyResult.displayText, /pong/);
3945
+ const newResult = await service.execute('/new Scratch session', context);
3946
+ const createdThreadEffect = newResult.effects?.find((effect) => effect.type === 'created_thread');
3947
+ const activatedCreatedEffect = newResult.effects?.find((effect) => effect.type === 'activate_thread' && effect.reason === 'created');
3948
+ strict_1.default.equal(createdThreadEffect?.threadId, activatedCreatedEffect?.threadId);
3949
+ strict_1.default.equal(store.getThread(createdThreadEffect?.threadId || '', []).title, 'Scratch session');
3950
+ const switchResult = await service.execute('/switch Other session', context);
3951
+ strict_1.default.equal(switchResult.effects?.find((effect) => effect.type === 'activate_thread')?.threadId, other.id);
3952
+ strict_1.default.match(switchResult.displayText, /后续消息将发送到该会话/);
3953
+ const renameResult = await service.execute('/name Renamed current', context);
3954
+ strict_1.default.match(renameResult.displayText, /Renamed current/);
3955
+ strict_1.default.equal(store.getThread(current.id, []).title, 'Renamed current');
3956
+ const currentDeleteResult = await service.execute('/del Renamed current --confirm', context);
3957
+ strict_1.default.match(currentDeleteResult.displayText, /不能删除当前正在使用的会话/);
3958
+ const deletePrompt = await service.execute('/del Other session', context);
3959
+ strict_1.default.match(deletePrompt.displayText, /确认删除会话/);
3960
+ strict_1.default.ok(deletePrompt.card?.actions.flat().some((action) => action.command.includes('--confirm')));
3961
+ const deleteResult = await service.execute('/del Other session --confirm', context);
3962
+ strict_1.default.equal(deleteResult.effects?.find((effect) => effect.type === 'deleted_thread')?.threadId, other.id);
3963
+ strict_1.default.equal(store.listThreadSummaries('workspace-a').some((thread) => thread.id === other.id), false);
3964
+ store.close();
3965
+ }
3966
+ finally {
3967
+ (0, node_fs_1.rmSync)(dir, { recursive: true, force: true });
3968
+ }
3969
+ });
3970
+ (0, node_test_1.default)('store deleteThread clears channel references without backend help', () => {
3971
+ const dir = (0, node_fs_1.mkdtempSync)((0, node_path_1.join)((0, node_os_1.tmpdir)(), 'agentdock-store-delete-thread-'));
3972
+ try {
3973
+ const store = new local_core_acp_store_js_1.LocalCoreAcpStore(dir);
3974
+ const thread = store.createThread('workspace-a', 'Bound thread', 'codex');
3975
+ const now = new Date().toISOString();
3976
+ store.createAuthorizedUser({
3977
+ id: 'lark-user-store',
3978
+ workspace_id: 'workspace-a',
3979
+ platform: 'lark',
3980
+ platform_user_id: 'user-store',
3981
+ chat_id: 'chat-store',
3982
+ display_name: 'User',
3983
+ thread_id: thread.id,
3984
+ authorized_at: now,
3985
+ });
3986
+ store.upsertPlatformThreadBinding({
3987
+ workspace_id: 'workspace-a',
3988
+ platform: 'lark',
3989
+ chat_id: 'chat-store',
3990
+ platform_user_id: 'user-store',
3991
+ thread_id: thread.id,
3992
+ last_platform_message_id: 'msg-store',
3993
+ created_at: now,
3994
+ updated_at: now,
3995
+ });
3996
+ store.deleteThread(thread.id);
3997
+ strict_1.default.equal(store.getThreadRow(thread.id), undefined);
3998
+ strict_1.default.equal(store.getAuthorizedUser('workspace-a', 'user-store', 'lark')?.thread_id, null);
3999
+ strict_1.default.equal(store.getPlatformThreadBinding('workspace-a', 'chat-store', 'user-store', 'lark'), undefined);
4000
+ store.close();
4001
+ }
4002
+ finally {
4003
+ (0, node_fs_1.rmSync)(dir, { recursive: true, force: true });
4004
+ }
4005
+ });
4006
+ (0, node_test_1.default)('backend session delete command clears channel bindings for deleted threads', async () => {
4007
+ const dir = (0, node_fs_1.mkdtempSync)((0, node_path_1.join)((0, node_os_1.tmpdir)(), 'agentdock-session-delete-'));
4008
+ try {
4009
+ const store = new local_core_acp_store_js_1.LocalCoreAcpStore(dir);
4010
+ const current = store.createThread('workspace-a', 'Current', 'codex');
4011
+ const other = store.createThread('workspace-a', 'Other session', 'codex');
4012
+ const now = new Date().toISOString();
4013
+ store.createAuthorizedUser({
4014
+ id: 'lark-user-1',
4015
+ workspace_id: 'workspace-a',
4016
+ platform: 'lark',
4017
+ platform_user_id: 'user-1',
4018
+ chat_id: 'chat-1',
4019
+ display_name: 'User',
4020
+ thread_id: other.id,
4021
+ authorized_at: now,
4022
+ });
4023
+ store.upsertPlatformThreadBinding({
4024
+ workspace_id: 'workspace-a',
4025
+ platform: 'lark',
4026
+ chat_id: 'chat-1',
4027
+ platform_user_id: 'user-1',
4028
+ thread_id: other.id,
4029
+ last_platform_message_id: 'msg-1',
4030
+ created_at: now,
4031
+ updated_at: now,
4032
+ });
4033
+ const events = [];
4034
+ const backend = new local_core_acp_backend_js_1.LocalCoreAcpBackend({
4035
+ store,
4036
+ runThreadMap: new Map(),
4037
+ emitBridge: () => { },
4038
+ eventBus: {
4039
+ emit: (event) => events.push(event),
4040
+ on: () => () => { },
4041
+ },
4042
+ scheduler: {
4043
+ createJob: async () => { throw new Error('not used'); },
4044
+ listJobsForThread: async () => [],
4045
+ deleteJob: async () => { },
4046
+ },
4047
+ getAgentTypes: () => ['codex'],
4048
+ });
4049
+ await backend.sendThreadMessage(current.id, '/del Other session --confirm', {
4050
+ workspaceId: 'workspace-a',
4051
+ agentType: 'codex',
4052
+ workDir: dir,
4053
+ command: process.execPath,
4054
+ args: ['-e', ''],
4055
+ env: {},
4056
+ model: '',
4057
+ });
4058
+ strict_1.default.equal(store.getThreadRow(other.id), undefined);
4059
+ strict_1.default.equal(store.getAuthorizedUser('workspace-a', 'user-1', 'lark')?.thread_id, null);
4060
+ strict_1.default.equal(store.getPlatformThreadBinding('workspace-a', 'chat-1', 'user-1', 'lark'), undefined);
4061
+ const created = await backend.createThread('workspace-a', 'Switch target', 'codex');
4062
+ await backend.sendThreadMessage(current.id, '/switch Switch target', {
4063
+ workspaceId: 'workspace-a',
4064
+ agentType: 'codex',
4065
+ workDir: dir,
4066
+ command: process.execPath,
4067
+ args: ['-e', ''],
4068
+ env: {},
4069
+ model: '',
4070
+ });
4071
+ strict_1.default.deepEqual(events.find((event) => event.type === 'thread.session.activated')?.payload, {
4072
+ workspaceId: 'workspace-a',
4073
+ threadId: created.id,
4074
+ previousThreadId: current.id,
4075
+ reason: 'switched',
4076
+ });
4077
+ backend.close();
4078
+ store.close();
4079
+ }
4080
+ finally {
4081
+ (0, node_fs_1.rmSync)(dir, { recursive: true, force: true });
4082
+ }
4083
+ });
4084
+ (0, node_test_1.default)('Lark session command cards round-trip slash command action values', () => {
4085
+ const card = (0, cards_js_1.buildSessionCommandCard)('会话列表', [[
4086
+ { label: '1. Current', command: '/switch 1', type: 'primary' },
4087
+ { label: '删除', command: '/del 1', type: 'danger' },
4088
+ ]], 'session-key-1', 'thread-1');
4089
+ const actionElement = card.elements.find((element) => element.tag === 'action');
4090
+ const value = actionElement.actions[0].value;
4091
+ const extracted = (0, cards_js_1.extractSessionCommandActionValue)({ event: { action: { value } } });
4092
+ strict_1.default.equal(extracted?.command, '/switch 1');
4093
+ strict_1.default.equal(extracted?.threadId, 'thread-1');
4094
+ strict_1.default.equal(extracted?.sessionKey, 'session-key-1');
4095
+ });
3902
4096
  (0, node_test_1.default)('scheduled conversation executor uses execution policy hooks around a thread run', async () => {
3903
4097
  const calls = [];
3904
4098
  let runtimeEnv;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kafca/agentdock",
3
- "version": "0.1.42",
3
+ "version": "0.1.43",
4
4
  "license": "PolyForm-Noncommercial-1.0.0",
5
5
  "type": "module",
6
6
  "main": "dist-electron/electron/main.js",
@@ -1 +0,0 @@
1
- import{H as R,l as b,J as z,K as D,N as W,O,u as B,r as n,j as t,P as F,B as c,E as L,C as U,D as k,I as f,T as H}from"./index-BWmHJRhe.js";import{B as u}from"./Badge-D-WU4kUV.js";import{M as K}from"./Modal-B3vlBmBr.js";import{S as w}from"./Select-C4CFMQmF.js";import{E as _}from"./EmptyState-BdKBBUpr.js";import{P as q}from"./Page-CPsLOP3z.js";import{P as G}from"./plus-DJVg9m09.js";import{P as Q}from"./play-CB3w1G6S.js";import{P as V}from"./pencil-1dfAivmj.js";import{T as X}from"./trash-2-BGMTNJA6.js";import"./index-CyZs_2NJ.js";import"./chevron-down-B6jJXlhi.js";import"./check-BTJTyd0C.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(q,{title:a("cron.title"),description:"Create simple scheduled prompts for a workspace.",actions:t.jsxs(c,{onClick:J,children:[t.jsx(G,{size:16})," ",a("cron.add")]})}),o.length===0?t.jsx(_,{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(K,{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(H,{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 +0,0 @@
1
- import{u as C,A as z,r as a,j as e,L as S,B as g,g as j,T as B}from"./index-BWmHJRhe.js";import{B as b}from"./Badge-D-WU4kUV.js";import{g as E,a as L}from"./sessions-WLYpkyUt.js";import{C as _,A}from"./ChatMarkdown-CfbC1jRd.js";import{A as I}from"./arrow-left-DPzSmidS.js";import{C as M}from"./circle-qRhJR9qR.js";import{W as y,R}from"./wifi-off-FhcQx0HK.js";import{B as T,U}from"./user-BcGMLyhu.js";import"./check-BTJTyd0C.js";function G(){var p;const{t:r}=C(),{project:i,id:l}=z(),[s,v]=a.useState(null),[d,m]=a.useState(""),[c,x]=a.useState(!1),[w,u]=a.useState(!0),f=a.useRef(null),o=a.useCallback(async()=>{if(!(!i||!l))try{u(!0);const t=await E(i,l,200);v(t)}finally{u(!1)}},[i,l]);a.useEffect(()=>{o()},[o]),a.useEffect(()=>{var t;(t=f.current)==null||t.scrollIntoView({behavior:"smooth"})},[s==null?void 0:s.history]);const h=async()=>{if(!d.trim()||!i||!s)return;const t=d.trim();m(""),x(!0);try{await L(i,{session_key:s.session_key,message:t}),setTimeout(o,1500)}finally{x(!1)}},N=t=>{t.key==="Enter"&&!t.shiftKey&&(t.preventDefault(),h())};return w&&!s?e.jsx("div",{className:"flex items-center justify-center h-64 text-muted-foreground animate-pulse",children:"Loading..."}):e.jsxs("div",{className:"flex flex-col h-[calc(100vh-8rem)] animate-fade-in",children:[e.jsxs("div",{className:"flex items-center justify-between pb-4 border-b",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(S,{to:"/sessions",className:"p-2 rounded-md hover:bg-accent/10 transition-colors",children:e.jsx(I,{size:18,className:"text-muted-foreground"})}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("h2",{className:"text-lg font-semibold text-foreground",children:(s==null?void 0:s.name)||l}),s!=null&&s.live?e.jsxs("span",{className:"flex items-center gap-1 text-[10px] text-primary bg-primary/10 px-1.5 py-0.5 rounded-full",children:[e.jsx(M,{size:5,className:"fill-current"})," live"]}):e.jsxs("span",{className:"flex items-center gap-1 text-[10px] text-muted-foreground bg-muted px-1.5 py-0.5 rounded-full",children:[e.jsx(y,{size:9})," ",r("sessions.offline")]})]}),e.jsxs("div",{className:"flex items-center gap-2 mt-0.5",children:[e.jsx(b,{children:i}),(s==null?void 0:s.platform)&&e.jsx(b,{variant:"info",children:s.platform}),e.jsx("span",{className:"text-xs text-muted-foreground",children:s==null?void 0:s.session_key})]})]})]}),e.jsxs(g,{size:"sm",variant:"ghost",onClick:o,children:[e.jsx(R,{size:14})," ",r("common.refresh")]})]}),e.jsxs("div",{className:"flex-1 overflow-y-auto py-6 space-y-5",children:[(!(s!=null&&s.history)||s.history.length===0)&&e.jsx("p",{className:"text-center text-sm text-muted-foreground py-12",children:r("sessions.noMessages")}),(p=s==null?void 0:s.history)==null?void 0:p.map((t,k)=>{const n=t.role==="user";return e.jsxs("div",{className:j("flex gap-3",n?"justify-end":"justify-start"),children:[!n&&e.jsx("div",{className:"w-8 h-8 rounded-md bg-primary/10 flex items-center justify-center shrink-0 mt-1",children:e.jsx(T,{size:16,className:"text-primary"})}),e.jsx("div",{className:j("rounded-lg px-5 py-3.5 text-sm",n?"max-w-[70%] bg-primary text-primary-foreground rounded-br-md":"max-w-[85%] bg-card border text-card-foreground rounded-bl-md shadow-sm"),children:e.jsx(_,{content:t.content,isUser:n})}),n&&e.jsx("div",{className:"w-8 h-8 rounded-md bg-muted flex items-center justify-center shrink-0 mt-1",children:e.jsx(U,{size:16,className:"text-muted-foreground"})})]},k)}),e.jsx("div",{ref:f})]}),e.jsx("div",{className:"border-t pt-4",children:s!=null&&s.live?e.jsxs("div",{className:"relative",children:[e.jsx(B,{value:d,onChange:t=>m(t.target.value),onKeyDown:N,placeholder:r("sessions.messageInput"),rows:2,className:"min-h-[88px] rounded-[24px] border-gray-200 bg-white px-4 pb-14 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-[96px] sm:px-5 sm:pt-4",disabled:c}),e.jsx(g,{onClick:h,disabled:c||!d.trim(),size:"icon","aria-label":r("sessions.messageInput"),className:"absolute bottom-3 right-3 h-10 w-10 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-11 sm:w-11",children:c?e.jsxs("svg",{className:"animate-spin h-4 w-4",viewBox:"0 0 24 24",children:[e.jsx("circle",{className:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor",strokeWidth:"4",fill:"none"}),e.jsx("path",{className:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"})]}):e.jsx(A,{size:20,strokeWidth:2.2})})]}):e.jsxs("div",{className:"flex items-center gap-2 px-4 py-3 text-sm text-muted-foreground bg-muted rounded-lg",children:[e.jsx(y,{size:14}),e.jsx("span",{children:r("sessions.notLiveHint")})]})})]})}export{G as default};
@@ -1 +0,0 @@
1
- import{V as l,P as d,X as c,Y as u,_ as h,$ as C,a0 as k,a1 as w,a2 as p,a3 as v,a4 as S,a5 as m,a6 as L,a7 as y,a8 as P,a9 as f,aa as R,ab as b,ac as G,ad as Q,ae as B,af as A,ag as F,ah as E,ai as I,aj as W,ak as D,al as K,am as T,an as x,ao as $,ap as j,aq as U,o as i,m as z,ar as _,as as q,at as M,au as V,av as X,aw as Y,ax as H,ay as J,i as N}from"./index-BWmHJRhe.js";function s(){if(!window.desktop)throw new Error("Desktop APIs are unavailable in the browser build");return window.desktop}const O={getRuntimeStatus:()=>s().getRuntimeStatus(),startService:()=>s().startService(),stopService:()=>s().stopService(),restartService:()=>s().restartService(),getLogs:e=>s().getLogs(e),listInstalledAgentRuntimes:()=>x().then(e=>e.runtimes),refreshInstalledAgentRuntimes:()=>T().then(e=>e.runtimes),readConfigFile:()=>s().readConfigFile(),saveRawConfigFile:e=>s().saveRawConfigFile(e),saveStructuredConfigFile:e=>s().saveStructuredConfigFile(e),getThreadKnowledgeBases:(e,a)=>s().getThreadKnowledgeBases(e,a),updateThreadKnowledgeBases:(e,a,t)=>s().updateThreadKnowledgeBases(e,a,t),deleteThreadKnowledgeBases:(e,a)=>s().deleteThreadKnowledgeBases(e,a),saveSettings:e=>s().saveSettings(e),getCapabilitySnapshot:()=>K(),getPluginDiagnostics:()=>D(),listChannelGateways:e=>W(e).then(a=>a.gateways),getChannelGatewayStatus:(e,a,t)=>I(e,a,t),testChannelConnection:(e,a,t)=>E(e,a,t),enableChannelGateway:(e,a,t)=>F(e,a,t),disableChannelGateway:(e,a,t)=>A(e,a,t),listChannelPendingPairings:(e,a)=>B(e,a).then(t=>t.pairings),approveChannelPairing:(e,a)=>Q(e,a),rejectChannelPairing:(e,a)=>G(e,a),listChannelAuthorizedUsers:(e,a)=>b(e,a).then(t=>t.users),getChannelQrCode:(e,a,t)=>R(e,a,t),checkChannelQrCodeStatus:(e,a,t,r)=>f(e,a,t,r),getWeixinQrCode:(e,a)=>P(e,a),checkWeixinQrCodeStatus:(e,a,t)=>y(e,a,t),getLarkQrCode:(e,a)=>L(e,a),checkLarkQrCodeStatus:(e,a,t)=>m(e,a,t),listLarkGateways:()=>S().then(e=>e.gateways),getLarkGatewayStatus:(e,a)=>v(e,a),testLarkConnection:(e,a)=>p(e,a),enableLarkGateway:(e,a)=>w(e,a),disableLarkGateway:(e,a)=>k(e,a),listLarkPendingPairings:e=>C(e).then(a=>a.pairings),approveLarkPairing:e=>h(e),rejectLarkPairing:e=>u(e),listLarkAuthorizedUsers:e=>c(e).then(a=>a.users),probeWorkspaceStreaming:e=>s().probeWorkspaceStreaming(e),onRuntimeEvent:e=>s().onRuntimeEvent(e),onRuntimeDetectionEvent:e=>d(a=>{(a.type.startsWith("runtime.detect.")||a.type==="runtime.status.changed")&&e(a)}),onBridgeEvent:e=>l(e)},o={getRuntimeStatus:()=>J(),startService:()=>H(),stopService:()=>Y(),restartService:()=>X(),getLogs:e=>V(e),listInstalledAgentRuntimes:()=>x().then(e=>e.runtimes),refreshInstalledAgentRuntimes:()=>T().then(e=>e.runtimes),readConfigFile:()=>M(),saveRawConfigFile:e=>q(e),saveStructuredConfigFile:e=>_(e),getThreadKnowledgeBases:(e,a)=>z(a).then(t=>t.selectedKnowledgeBaseIds||[]),updateThreadKnowledgeBases:(e,a,t)=>i(a,t).then(r=>r.knowledgeBaseIds),deleteThreadKnowledgeBases:(e,a)=>i(a,[]).then(()=>({deleted:!0})),saveSettings:e=>U(e),getCapabilitySnapshot:()=>K(),getPluginDiagnostics:()=>D(),listChannelGateways:e=>W(e).then(a=>a.gateways),getChannelGatewayStatus:(e,a,t)=>I(e,a,t),testChannelConnection:(e,a,t)=>E(e,a,t),enableChannelGateway:(e,a,t)=>F(e,a,t),disableChannelGateway:(e,a,t)=>A(e,a,t),listChannelPendingPairings:(e,a)=>B(e,a).then(t=>t.pairings),approveChannelPairing:(e,a)=>Q(e,a),rejectChannelPairing:(e,a)=>G(e,a),listChannelAuthorizedUsers:(e,a)=>b(e,a).then(t=>t.users),getChannelQrCode:(e,a,t)=>R(e,a,t),checkChannelQrCodeStatus:(e,a,t,r)=>f(e,a,t,r),getWeixinQrCode:(e,a)=>P(e,a),checkWeixinQrCodeStatus:(e,a,t)=>y(e,a,t),getLarkQrCode:(e,a)=>L(e,a),checkLarkQrCodeStatus:(e,a,t)=>m(e,a,t),listLarkGateways:()=>S().then(e=>e.gateways),getLarkGatewayStatus:(e,a)=>v(e,a),testLarkConnection:(e,a)=>p(e,a),enableLarkGateway:(e,a)=>w(e,a),disableLarkGateway:(e,a)=>k(e,a),listLarkPendingPairings:e=>C(e).then(a=>a.pairings),approveLarkPairing:e=>h(e),rejectLarkPairing:e=>u(e),listLarkAuthorizedUsers:e=>c(e).then(a=>a.users),probeWorkspaceStreaming:e=>j(e),onRuntimeEvent:e=>$(e),onRuntimeDetectionEvent:e=>d(a=>{(a.type.startsWith("runtime.detect.")||a.type==="runtime.status.changed")&&e(a)}),onBridgeEvent:e=>l(e)};let g=null;function Z(e){return e==="electron"&&window.desktop?O:o}function n(){const e=g||Z(N());if(!e)throw new Error("Managed desktop APIs are unavailable in this build");return g=e,e}const ae=()=>n().getRuntimeStatus(),te=()=>n().startService(),ne=()=>n().listInstalledAgentRuntimes(),se=()=>n().refreshInstalledAgentRuntimes(),re=()=>n().readConfigFile(),ie=e=>n().saveStructuredConfigFile(e),oe=(e,a,t)=>n().updateThreadKnowledgeBases(e,a,t),ge=e=>n().saveSettings(e),le=()=>n().getPluginDiagnostics(),de=(e,a)=>n().getWeixinQrCode(e,a),ce=(e,a,t)=>n().checkWeixinQrCodeStatus(e,a,t),ue=(e,a)=>n().getLarkQrCode(e,a),he=(e,a,t)=>n().checkLarkQrCodeStatus(e,a,t),Ce=(e,a)=>n().testLarkConnection(e,a),ke=(e,a)=>n().enableLarkGateway(e,a),we=e=>n().onRuntimeEvent(e),pe=e=>n().onRuntimeDetectionEvent(e),ve=e=>n().onBridgeEvent(e);export{pe as a,ve as b,re as c,ie as d,ke as e,de as f,ae as g,ue as h,ce as i,he as j,le as k,ne as l,ge as m,we as o,se as r,te as s,Ce as t,oe as u};
@@ -1,4 +0,0 @@
1
- const h="pi",s="opencode/minimax-m2.5-free";const w=["pi","opencode","codex","claudecode","cursor","gemini","qoder","iflow","hermes","localcore-acp"],f=["telegram","feishu","lark","discord","slack","dingtalk","wecom","weixin","qq","qqbot","line"],n=["pi","opencode","codex","claudecode","hermes","acp","localcore-acp"],c="localcore-acp",i=["[Scheduler Tools]","If the user asks to create, view, edit, delete, or manually run a scheduled task for this conversation, use the Bash tool to run the local scheduler CLI.","Use these commands:",'lac scheduler add --cron "<5-field cron>" --message "<exact message to send>" --desc "<short label>" [--execution-mode same-thread|side-thread]',"lac scheduler list","lac scheduler list --thread","lac scheduler info <short-job-id>",'lac scheduler edit <short-job-id> [--cron "<5-field cron>"] [--message "<exact message>"] [--desc "<short label>"] [--enabled true|false] [--execution-mode same-thread|side-thread]',"lac scheduler del <short-job-id>","lac scheduler run <short-job-id>","Environment variables LOCAL_AI_WORKSPACE_ID, LOCAL_AI_THREAD_ID, LOCAL_AI_PLATFORM, LOCAL_AI_CHAT_ID, and LOCAL_AI_PLATFORM_USER_ID are already set when available.","Prefer relying on those variables instead of inventing your own route or creating session-only cron jobs.","By default, `lac scheduler list` shows all scheduled tasks in the current workspace. Use `lac scheduler list --thread` to show only the current conversation thread.","Use the short job id shown by `lac scheduler list`; do not add a `job:` prefix or expand it to a full UUID.","Use `--execution-mode same-thread` to reuse the current thread, or `--execution-mode side-thread` to run in a dedicated scheduled thread.","Only use the scheduler CLI when the user explicitly asks for scheduled automation.","[/Scheduler Tools]"].join(`
2
- `),d=["[Channel Tools]","If the user asks you to send a local file back through the current channel conversation, use the Bash tool to run the local channel CLI.","Use this command:",'lac channel send-file --path "<absolute-or-workdir-relative-file-path>" [--target "<channel-chat-or-user-id>"]',"By default, the file is sent to the current platform conversation from LOCAL_AI_CHAT_ID.","Use --target only when the user explicitly names a different channel chat or user id.","The CLI accepts absolute paths. Check that the file exists before sending when practical.","Only use the channel CLI when the user explicitly asks to send a file through the channel.","[/Channel Tools]"].join(`
3
- `),u={allow:"allow",deny:"deny","allow all":"allow all",allowall:"allow all",allow_all:"allow all",allow_always:"allow all",always:"allow all",always_allow:"allow all","always allow":"allow all","allow always":"allow all",始终允许:"allow all",永久允许:"allow all","perm:allow":"allow","perm:deny":"deny","perm:allow_all":"allow all","perm:allow_always":"allow all","perm:always":"allow all"};function _(l,e=[]){return[i,"",d,...e.flatMap(a=>a?["",a]:[]),"","[User Message]",l,"[/User Message]"].join(`
4
- `)}function m(l){switch(String(l||"").trim().toLowerCase()){case"opencode":return s;case"claudecode":return"";default:return""}}function p(l,e){const a=String(l||"").trim().toLowerCase(),t=String(e||"").trim();return a?a==="opencode"?t||s:a==="claudecode"&&t.startsWith("opencode/")?"":t:t}function r(l){if(!l)return null;const e=String(l).trim().toLowerCase(),a=u[e];return a||(e.includes("allow_all")||e.includes("allow-always")||e.includes("allow_always")||e.includes("allow always")||e.includes("always allow")||e.includes("allow all")||e.includes("始终允许")||e.includes("永久允许")?"allow all":e.startsWith("reject")||e.startsWith("deny")?"deny":e.startsWith("allow")?"allow":null)}function O(l){return!!r(l==null?void 0:l.data)}function T(l){if(!l||typeof l!="object")return null;const e=l,a=typeof e.text=="string"?e.text:typeof e.Text=="string"?e.Text:"",t=typeof e.data=="string"?e.data:typeof e.Data=="string"?e.Data:"";if(!a||!t)return null;const o=r(t);return o?{text:o,data:o}:{text:a,data:t}}function E(l){return l?n.includes(String(l).trim().toLowerCase()):!1}function L(l){const e=String(l||"").trim().toLowerCase();return e==="acp"||e==="pi"||e==="opencode"||e==="codex"||e==="claudecode"||e==="hermes"||e===c}export{w as D,r as a,L as b,p as c,f as d,h as e,m as g,O as i,T as n,E as s,_ as w};
@@ -1 +0,0 @@
1
- const e={dashboard:"Dashboard",chat:"Chat",chatDesktop:"Desktop Chat",chatWeb:"Chat",workspace:"Workspace",knowledge:"Knowledge",projects:"Projects",sessions:"Sessions",cron:"Cron",bridge:"Bridge",system:"System"},t={title:"Dashboard",version:"Version",uptime:"Uptime",platforms:"Platforms",projects:"Projects",bridgeAdapters:"Bridge adapters",noData:"No data available"},s={title:"Projects",name:"Name",agent:"Agent",platforms:"Platforms",sessions:"Sessions",heartbeat:"Heartbeat",settings:"Settings",quiet:"Quiet mode",language:"Language",adminFrom:"Admin from",disabledCommands:"Disabled commands",save:"Save",detail:"Details",noProjects:"No projects configured",tabs:{overview:"Overview",providers:"Providers",heartbeat:"Heartbeat",settings:"Settings"}},o={title:"Sessions",id:"ID",sessionKey:"Session key",name:"Name",platform:"Platform",active:"Active",createdAt:"Created at",history:"History",send:"Send",messageInput:"Message",delete:"Delete",noSessions:"No sessions",noMessages:"No messages yet",notLiveHint:"This chat target is offline right now, so replies are temporarily unavailable. When new activity arrives, sending will become available again.",offline:"offline",justNow:"just now",allProjects:"All projects",chat:"Chat",enterSession:"Open session",newChat:"New chat",selectProject:"Select a project",projectRequired:"Choose a project before starting a chat.",noAvailableChatTarget:"There is no conversation ready to chat in this project yet. Open an available session from the sessions view first.",noReadyChats:"There are no chat-ready sessions right now. Use the Sessions page to review history.",emptyProject:"This project does not have any sessions yet.",emptySelection:"Pick a project and start a new chat to begin.",activeChat:"Active chat",sendHint:"Messages will be sent to the selected project.",waitingForReply:"Waiting for the assistant reply…",preparingChat:"Preparing the chat…",pollTimeout:"The assistant did not finish responding before the refresh timeout.",createFailed:"Failed to create a new chat session.",loadFailed:"Failed to load the selected session.",sendFailed:"Failed to send the message.",sessionUnavailable:"This chat target is offline right now, so replies are temporarily unavailable. Try again after new activity arrives.",deleteConfirmTitle:"Delete session",deleteConfirmBody:"This removes the saved conversation history for the selected session.",renameTitle:"Rename session",renamePlaceholder:"Session name",loadSession:"Open",historyTitle:"Conversation history",availableNow:"Ready to chat",waitingActivation:"Waiting to become available"},a={title:"Providers",name:"Name",model:"Model",baseUrl:"Base URL",active:"Active",add:"Add provider",remove:"Remove",activate:"Activate",setModel:"Set model",models:"Models"},i={title:"Scheduled jobs",expression:"Cron expression",prompt:"Prompt",exec:"Execute",description:"Description",enabled:"Enabled",silent:"Silent",lastRun:"Last run",lastError:"Last error",add:"Add job",delete:"Delete",noJobs:"No scheduled jobs",workDir:"Working directory",sessionKey:"Session key",project:"Project"},n={title:"Heartbeat",status:"Status",interval:"Interval",paused:"Paused",running:"Running",pause:"Pause",resume:"Resume",trigger:"Run now",setInterval:"Set interval",runCount:"Run count",errorCount:"Error count",skippedBusy:"Skipped (busy)",lastRun:"Last run"},r={title:"Bridge",platform:"Platform",capabilities:"Capabilities",connectedAt:"Connected at",noAdapters:"No bridge adapters"},l={title:"System",config:"Configuration",logs:"Logs",restart:"Restart",reload:"Reload config",restartConfirm:"Restart the service? Active sessions may be interrupted.",reloadConfirm:"Reload configuration from disk?",level:"Log level",limit:"Line limit"},c={title:"AgentDock",subtitle:"Connect to your AgentDock instance",token:"API token",serverUrl:"Server URL",connect:"Connect",invalidToken:"Invalid or expired token",logout:"Log out"},d={loading:"Loading…",error:"Error",success:"Success",confirm:"Confirm",cancel:"Cancel",save:"Save",delete:"Delete",back:"Back",refresh:"Refresh",search:"Search",noData:"No data",actions:"Actions",viewAll:"View all",optional:"optional",confirmDelete:"Are you sure you want to delete this?"},h={light:"Light",dark:"Dark",system:"System"},m={nav:e,dashboard:t,projects:s,sessions:o,providers:a,cron:i,heartbeat:n,bridge:r,system:l,login:c,common:d,theme:h};export{r as bridge,d as common,i as cron,t as dashboard,m as default,n as heartbeat,c as login,e as nav,s as projects,a as providers,o as sessions,l as system,h as theme};
@@ -1 +0,0 @@
1
- import{z as t}from"./index-BWmHJRhe.js";const e=()=>t.get("/projects"),r=o=>t.get(`/projects/${o}`);export{r as g,e as l};
@@ -1 +0,0 @@
1
- const e={dashboard:"概览",chat:"聊天",chatDesktop:"桌面聊天",chatWeb:"聊天",workspace:"工作区",knowledge:"知识库",projects:"项目",sessions:"会话",cron:"定时任务",bridge:"桥接",system:"系统"},t={title:"概览",version:"版本",uptime:"运行时间",platforms:"平台",projects:"项目",bridgeAdapters:"桥接适配器",noData:"暂无数据"},s={title:"项目",name:"名称",agent:"智能体",platforms:"平台",sessions:"会话",heartbeat:"心跳",settings:"设置",quiet:"静默模式",language:"语言",adminFrom:"管理来源",disabledCommands:"已禁用命令",save:"保存",detail:"详情",noProjects:"尚未配置项目",tabs:{overview:"概览",providers:"服务商",heartbeat:"心跳",settings:"设置"}},o={title:"会话",id:"编号",sessionKey:"会话键",name:"名称",platform:"平台",active:"活跃",createdAt:"创建时间",history:"历史",send:"发送",messageInput:"消息",delete:"删除",noSessions:"暂无会话",noMessages:"暂无消息",notLiveHint:"当前聊天对象现在不在线,暂时不能继续回复。等有新消息进来后,这里会自动恢复可发送。",offline:"离线",justNow:"刚刚",allProjects:"全部项目",chat:"对话",enterSession:"进入会话",newChat:"新建聊天",selectProject:"选择项目",projectRequired:"开始聊天前请先选择一个项目。",noAvailableChatTarget:"当前项目还没有可直接聊天的会话,请先从会话列表打开一个可用会话。",noReadyChats:"当前没有可立即聊天的会话,请到“会话”页查看历史记录。",emptyProject:"这个项目下还没有任何会话。",emptySelection:"选择一个项目,然后开始新的聊天。",activeChat:"当前聊天",sendHint:"消息会发送到当前选中的项目。",waitingForReply:"正在等待助手回复…",preparingChat:"正在准备聊天…",pollTimeout:"刷新超时前未收到完整回复。",createFailed:"创建新聊天会话失败。",loadFailed:"加载所选会话失败。",sendFailed:"发送消息失败。",sessionUnavailable:"当前聊天对象现在不在线,暂时不能继续回复。等有新消息进来后再试。",deleteConfirmTitle:"删除会话",deleteConfirmBody:"这会移除该会话保存的历史对话。",renameTitle:"重命名会话",renamePlaceholder:"会话名称",loadSession:"打开",historyTitle:"历史会话",availableNow:"可发送消息",waitingActivation:"等待激活"},a={title:"模型提供方",name:"名称",model:"模型",baseUrl:"基础 URL",active:"当前使用",add:"添加提供方",remove:"移除",activate:"启用",setModel:"设置模型",models:"可用模型"},n={title:"定时任务",expression:"Cron 表达式",prompt:"提示词",exec:"执行",description:"描述",enabled:"已启用",silent:"静默",lastRun:"上次运行",lastError:"上次错误",add:"添加任务",delete:"删除",noJobs:"暂无定时任务",workDir:"工作目录",sessionKey:"会话键",project:"项目"},i={title:"心跳",status:"状态",interval:"间隔",paused:"已暂停",running:"运行中",pause:"暂停",resume:"恢复",trigger:"立即执行",setInterval:"设置间隔",runCount:"执行次数",errorCount:"错误次数",skippedBusy:"跳过(忙碌)",lastRun:"上次运行"},r={title:"桥接",platform:"平台",capabilities:"能力",connectedAt:"连接时间",noAdapters:"暂无桥接适配器"},l={title:"系统",config:"配置",logs:"日志",restart:"重启",reload:"重载配置",restartConfirm:"确定要重启服务吗?进行中的会话可能会中断。",reloadConfirm:"从磁盘重新加载配置?",level:"日志级别",limit:"行数限制"},c={title:"AgentDock",subtitle:"连接到您的 AgentDock 实例",token:"API 令牌",serverUrl:"服务器地址",connect:"连接",invalidToken:"令牌无效或已过期",logout:"退出登录"},d={loading:"加载中…",error:"错误",success:"成功",confirm:"确认",cancel:"取消",save:"保存",delete:"删除",back:"返回",refresh:"刷新",search:"搜索",noData:"无数据",actions:"操作",viewAll:"查看全部",optional:"可选",confirmDelete:"确定要删除吗?"},m={light:"浅色",dark:"深色",system:"跟随系统"},p={nav:e,dashboard:t,projects:s,sessions:o,providers:a,cron:n,heartbeat:i,bridge:r,system:l,login:c,common:d,theme:m};export{r as bridge,d as common,n as cron,t as dashboard,p as default,i as heartbeat,c as login,e as nav,s as projects,a as providers,o as sessions,l as system,m as theme};