@kafca/agentdock 0.1.36 → 0.1.38

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 (63) hide show
  1. package/README.md +11 -0
  2. package/dist/renderer/assets/{Badge-DUa4J-09.js → Badge-PKJavQmQ.js} +1 -1
  3. package/dist/renderer/assets/{Chat-B1FWuTWV.js → Chat-DWm4h9aa.js} +1 -1
  4. package/dist/renderer/assets/{ChatMarkdown-DqOgFSgI.js → ChatMarkdown-DKxW2GbO.js} +1 -1
  5. package/dist/renderer/assets/{Config-CM5bqUrV.js → Config-Bqn3cy0z.js} +1 -1
  6. package/dist/renderer/assets/{CronList-CfXE7S0M.js → CronList-CPI_C7FW.js} +1 -1
  7. package/dist/renderer/assets/{Dashboard-D5Dwbotu.js → Dashboard-0e9JS5t7.js} +2 -2
  8. package/dist/renderer/assets/{EmptyState-Bs_6ISc0.js → EmptyState-CuA0koT7.js} +1 -1
  9. package/dist/renderer/assets/{KnowledgeDetail-0kdWnKyy.js → KnowledgeDetail-B1YSDbFa.js} +1 -1
  10. package/dist/renderer/assets/{KnowledgeHome-Bg8xbRe2.js → KnowledgeHome-KHYwWGDu.js} +1 -1
  11. package/dist/renderer/assets/{Logs-BfgvW7qZ.js → Logs-X4LJw-00.js} +1 -1
  12. package/dist/renderer/assets/{Modal-BkuKCDDx.js → Modal-BzEv4CK6.js} +1 -1
  13. package/dist/renderer/assets/{Page-ddaAS_jP.js → Page-BrZMoKtK.js} +1 -1
  14. package/dist/renderer/assets/{ProjectDetail-C9x-Ib5p.js → ProjectDetail-DpO00Ozx.js} +1 -1
  15. package/dist/renderer/assets/{ProjectList-XIIikxrj.js → ProjectList-DFtJHTic.js} +1 -1
  16. package/dist/renderer/assets/{Select-BBL_5aa5.js → Select-DMrwDcus.js} +1 -1
  17. package/dist/renderer/assets/{SessionChat-BFsTM0c7.js → SessionChat-Bh9AfkK5.js} +1 -1
  18. package/dist/renderer/assets/{SessionList-DWh6n10K.js → SessionList-Y3gWAe96.js} +1 -1
  19. package/dist/renderer/assets/{ThreadChat-CzPiDA92.js → ThreadChat-Cq0ZRNOh.js} +1 -1
  20. package/dist/renderer/assets/{Workspace-BW8v3Nia.js → Workspace-DMSPypFO.js} +1 -1
  21. package/dist/renderer/assets/{arrow-left-CcoHvwbx.js → arrow-left-CgYQZlK9.js} +1 -1
  22. package/dist/renderer/assets/{book-open-RweyWxPq.js → book-open-cAfg0BWS.js} +1 -1
  23. package/dist/renderer/assets/{check-B5YOrBNT.js → check-BNRlfwZx.js} +1 -1
  24. package/dist/renderer/assets/{chevron-down-HjaPrxdd.js → chevron-down-B9vVz3wf.js} +1 -1
  25. package/dist/renderer/assets/{circle-C-aaO7LR.js → circle-TBXQ38et.js} +1 -1
  26. package/dist/renderer/assets/{desktop-DUWkNnbA.js → desktop-DfkCIN1l.js} +1 -1
  27. package/dist/renderer/assets/{funnel-IWZmi-_V.js → funnel-BdZjZcqK.js} +1 -1
  28. package/dist/renderer/assets/{heart-DM5_F2nX.js → heart-CBPXb4dq.js} +1 -1
  29. package/dist/renderer/assets/{index-Bin2xyBS.js → index-CXrYAFUE.js} +2 -2
  30. package/dist/renderer/assets/{index-DvIUdsAm.js → index-C_Yr2rQ1.js} +1 -1
  31. package/dist/renderer/assets/{pencil-DcxwCYPi.js → pencil-BlLIWP1h.js} +1 -1
  32. package/dist/renderer/assets/{play-DUdnnxLC.js → play-F-oO0VwG.js} +1 -1
  33. package/dist/renderer/assets/{plug-B-rDbk24.js → plug-B5BduKTi.js} +1 -1
  34. package/dist/renderer/assets/{plus-DslMGvrO.js → plus-Bbe6vc8z.js} +1 -1
  35. package/dist/renderer/assets/projects-CGLECySt.js +1 -0
  36. package/dist/renderer/assets/{save-DlkR3jLs.js → save-CbX1ymi_.js} +1 -1
  37. package/dist/renderer/assets/{search-ULTp3p_0.js → search-KyB8P1Ie.js} +1 -1
  38. package/dist/renderer/assets/{server-DBdiKfv9.js → server-D2EQ0I-I.js} +1 -1
  39. package/dist/renderer/assets/{session-utils-BPyVVONo.js → session-utils-C4Eq8h8o.js} +1 -1
  40. package/dist/renderer/assets/{sessions-B0NecMYO.js → sessions-CchD99QT.js} +1 -1
  41. package/dist/renderer/assets/{shield-check-BNSk8nza.js → shield-check-BTTXqP3n.js} +1 -1
  42. package/dist/renderer/assets/{trash-2-CGydl763.js → trash-2-CDOrVaia.js} +1 -1
  43. package/dist/renderer/assets/{user-D1xkQo35.js → user-BR0zEuV_.js} +1 -1
  44. package/dist/renderer/assets/{wifi-off-Iy1XPeZ3.js → wifi-off-W_cPAMcl.js} +1 -1
  45. package/dist/renderer/index.html +1 -1
  46. package/dist-electron/services/local-ai-core/src/acp/local-core-acp-store.js +22 -7
  47. package/dist-electron/services/local-ai-core/src/acp/local-core-acp-turn-coordinator.js +2 -1
  48. package/dist-electron/services/local-ai-core/src/channel/lark/local-core-lark-gateway.js +59 -9
  49. package/dist-electron/services/local-ai-core/src/channel/lark/runtime-state.js +9 -6
  50. package/dist-electron/services/local-ai-core/src/channel/weixin/local-core-weixin-gateway.js +31 -1
  51. package/dist-electron/services/local-ai-core/src/scheduler/channel-execution-policy.js +79 -0
  52. package/dist-electron/services/local-ai-core/src/scheduler/lark-execution-policies.js +7 -61
  53. package/dist-electron/services/local-ai-core/src/scheduler/lark-schedule-adapter.js +3 -12
  54. package/dist-electron/services/local-ai-core/src/scheduler/local-schedule-adapter.js +23 -30
  55. package/dist-electron/services/local-ai-core/src/scheduler/scheduled-bridge-session.js +55 -0
  56. package/dist-electron/services/local-ai-core/src/scheduler/scheduler-run-lifecycle.js +13 -1
  57. package/dist-electron/services/local-ai-core/src/scheduler/scheduler-service.js +1 -1
  58. package/dist-electron/services/local-ai-core/src/scheduler/weixin-execution-policies.js +7 -61
  59. package/dist-electron/services/local-ai-core/src/scheduler/weixin-schedule-adapter.js +3 -12
  60. package/dist-electron/tests/electron/workspace-task-store.test.js +188 -28
  61. package/dist-electron/tests/integration/local-core-refactor.test.js +140 -50
  62. package/package.json +1 -1
  63. package/dist/renderer/assets/projects-JFuOB4DM.js +0 -1
@@ -24,6 +24,17 @@ const local_core_acp_progress_js_1 = require("../../services/local-ai-core/src/a
24
24
  const local_core_acp_permission_lifecycle_js_1 = require("../../services/local-ai-core/src/acp/local-core-acp-permission-lifecycle.js");
25
25
  const workspace_acp_permissions_js_1 = require("../../services/local-ai-core/src/acp/workspace-acp-permissions.js");
26
26
  const server_routes_js_1 = require("../../services/local-ai-core/src/runtime/server-routes.js");
27
+ function extractLarkCreatedMessage(request) {
28
+ const msgType = String(request.data?.msg_type || '');
29
+ const content = JSON.parse(String(request.data?.content || '{}'));
30
+ return {
31
+ msgType,
32
+ content,
33
+ text: msgType === 'interactive'
34
+ ? String(content.elements?.[0]?.content || '')
35
+ : String(content.text || ''),
36
+ };
37
+ }
27
38
  (0, node_test_1.default)('local core route parser separates runtime refresh and runtime detail routes', () => {
28
39
  strict_1.default.deepEqual((0, server_routes_js_1.parseLocalAiCoreRoute)('GET', '/api/local/v1/logs'), { name: 'logs.list' });
29
40
  strict_1.default.deepEqual((0, server_routes_js_1.parseLocalAiCoreRoute)('GET', '/api/local/v1/runtimes'), { name: 'runtimes.list' });
@@ -1829,18 +1840,19 @@ const server_routes_js_1 = require("../../services/local-ai-core/src/runtime/ser
1829
1840
  strict_1.default.deepEqual(logs, []);
1830
1841
  });
1831
1842
  (0, node_test_1.default)('lark bridge sends completed thought once before final answer', async () => {
1832
- const createdCards = [];
1843
+ const createdMessages = [];
1833
1844
  const patchedCards = [];
1834
1845
  const storedMessageIds = [];
1835
1846
  const client = {
1836
1847
  im: {
1837
1848
  message: {
1838
1849
  create: async (request) => {
1839
- const messageId = `lark-msg-${createdCards.length + 1}`;
1840
- const card = JSON.parse(String(request.data.content || '{}'));
1841
- createdCards.push({
1850
+ const messageId = `lark-msg-${createdMessages.length + 1}`;
1851
+ const message = extractLarkCreatedMessage(request);
1852
+ createdMessages.push({
1842
1853
  messageId,
1843
- text: String(card.elements?.[0]?.content || ''),
1854
+ msgType: message.msgType,
1855
+ text: message.text,
1844
1856
  });
1845
1857
  return { data: { message_id: messageId } };
1846
1858
  },
@@ -1909,25 +1921,26 @@ const server_routes_js_1 = require("../../services/local-ai-core/src/runtime/ser
1909
1921
  replyCtx: 'run-1',
1910
1922
  content: '最终回答',
1911
1923
  });
1912
- strict_1.default.equal(createdCards.length, 2);
1913
- strict_1.default.equal(createdCards[0]?.text, '先理解问题,再检查代码');
1914
- strict_1.default.equal(createdCards[1]?.text, '最终回答');
1924
+ strict_1.default.deepEqual(createdMessages.map((message) => message.msgType), ['interactive', 'text']);
1925
+ strict_1.default.equal(createdMessages[0]?.text, '先理解问题,再检查代码');
1926
+ strict_1.default.equal(createdMessages[1]?.text, '最终回答');
1915
1927
  strict_1.default.equal(patchedCards.length, 0);
1916
1928
  strict_1.default.deepEqual(storedMessageIds, ['lark-msg-2']);
1917
1929
  });
1918
- (0, node_test_1.default)('lark bridge sends final reply as its own card instead of streaming draft', async () => {
1919
- const createdCards = [];
1930
+ (0, node_test_1.default)('lark bridge sends final reply as its own plain text message instead of streaming draft', async () => {
1931
+ const createdMessages = [];
1920
1932
  const patchedCards = [];
1921
1933
  const storedMessageIds = [];
1922
1934
  const client = {
1923
1935
  im: {
1924
1936
  message: {
1925
1937
  create: async (request) => {
1926
- const messageId = `lark-msg-${createdCards.length + 1}`;
1927
- const card = JSON.parse(String(request.data.content || '{}'));
1928
- createdCards.push({
1938
+ const messageId = `lark-msg-${createdMessages.length + 1}`;
1939
+ const message = extractLarkCreatedMessage(request);
1940
+ createdMessages.push({
1929
1941
  messageId,
1930
- text: String(card.elements?.[0]?.content || ''),
1942
+ msgType: message.msgType,
1943
+ text: message.text,
1931
1944
  });
1932
1945
  return { data: { message_id: messageId } };
1933
1946
  },
@@ -1986,22 +1999,24 @@ const server_routes_js_1 = require("../../services/local-ai-core/src/runtime/ser
1986
1999
  replyCtx: 'run-1',
1987
2000
  content: '真正最终回答',
1988
2001
  });
1989
- strict_1.default.deepEqual(createdCards.map((card) => card.text), ['真正最终回答']);
2002
+ strict_1.default.deepEqual(createdMessages.map((message) => message.msgType), ['text']);
2003
+ strict_1.default.deepEqual(createdMessages.map((message) => message.text), ['真正最终回答']);
1990
2004
  strict_1.default.deepEqual(patchedCards, []);
1991
2005
  strict_1.default.deepEqual(storedMessageIds, ['lark-msg-1']);
1992
2006
  });
1993
- (0, node_test_1.default)('lark bridge creates final replies without patching prior final cards', async () => {
1994
- const createdCards = [];
2007
+ (0, node_test_1.default)('lark bridge creates final replies without patching prior final messages', async () => {
2008
+ const createdMessages = [];
1995
2009
  const patchedCards = [];
1996
2010
  const client = {
1997
2011
  im: {
1998
2012
  message: {
1999
2013
  create: async (request) => {
2000
- const messageId = `lark-msg-${createdCards.length + 1}`;
2001
- const card = JSON.parse(String(request.data.content || '{}'));
2002
- createdCards.push({
2014
+ const messageId = `lark-msg-${createdMessages.length + 1}`;
2015
+ const message = extractLarkCreatedMessage(request);
2016
+ createdMessages.push({
2003
2017
  messageId,
2004
- text: String(card.elements?.[0]?.content || ''),
2018
+ msgType: message.msgType,
2019
+ text: message.text,
2005
2020
  });
2006
2021
  return { data: { message_id: messageId } };
2007
2022
  },
@@ -2058,22 +2073,24 @@ const server_routes_js_1 = require("../../services/local-ai-core/src/runtime/ser
2058
2073
  replyCtx: 'run-2',
2059
2074
  content: 'second final',
2060
2075
  });
2061
- strict_1.default.deepEqual(createdCards.map((card) => card.text), ['first final', 'second final']);
2076
+ strict_1.default.deepEqual(createdMessages.map((message) => message.msgType), ['text', 'text']);
2077
+ strict_1.default.deepEqual(createdMessages.map((message) => message.text), ['first final', 'second final']);
2062
2078
  strict_1.default.deepEqual(patchedCards, []);
2063
2079
  });
2064
- (0, node_test_1.default)('lark bridge sends tool and final as separate cards without patching tool progress', async () => {
2065
- const createdCards = [];
2080
+ (0, node_test_1.default)('lark bridge sends tool and final as separate plain text messages without patching tool progress', async () => {
2081
+ const createdMessages = [];
2066
2082
  const patchedCards = [];
2067
2083
  const storedMessageIds = [];
2068
2084
  const client = {
2069
2085
  im: {
2070
2086
  message: {
2071
2087
  create: async (request) => {
2072
- const messageId = `lark-msg-${createdCards.length + 1}`;
2073
- const card = JSON.parse(String(request.data.content || '{}'));
2074
- createdCards.push({
2088
+ const messageId = `lark-msg-${createdMessages.length + 1}`;
2089
+ const message = extractLarkCreatedMessage(request);
2090
+ createdMessages.push({
2075
2091
  messageId,
2076
- text: String(card.elements?.[0]?.content || ''),
2092
+ msgType: message.msgType,
2093
+ text: message.text,
2077
2094
  });
2078
2095
  return { data: { message_id: messageId } };
2079
2096
  },
@@ -2146,7 +2163,8 @@ const server_routes_js_1 = require("../../services/local-ai-core/src/runtime/ser
2146
2163
  replyCtx: 'run-1',
2147
2164
  content: '好的,文件存在,现在发送给你:已发送!`CLAUDE.md` 文件已经发出去了,请查收',
2148
2165
  });
2149
- strict_1.default.deepEqual(createdCards.map((card) => card.text), [
2166
+ strict_1.default.deepEqual(createdMessages.map((message) => message.msgType), ['text', 'text']);
2167
+ strict_1.default.deepEqual(createdMessages.map((message) => message.text), [
2150
2168
  '🔧 bash',
2151
2169
  '好的,文件存在,现在发送给你:已发送!`CLAUDE.md` 文件已经发出去了,请查收',
2152
2170
  ]);
@@ -2154,18 +2172,19 @@ const server_routes_js_1 = require("../../services/local-ai-core/src/runtime/ser
2154
2172
  strict_1.default.deepEqual(storedMessageIds, ['lark-msg-2']);
2155
2173
  });
2156
2174
  (0, node_test_1.default)('lark bridge flushes interleaved thought segments before tools and final', async () => {
2157
- const createdCards = [];
2175
+ const createdMessages = [];
2158
2176
  const patchedCards = [];
2159
2177
  const storedMessageIds = [];
2160
2178
  const client = {
2161
2179
  im: {
2162
2180
  message: {
2163
2181
  create: async (request) => {
2164
- const messageId = `lark-msg-${createdCards.length + 1}`;
2165
- const card = JSON.parse(String(request.data.content || '{}'));
2166
- createdCards.push({
2182
+ const messageId = `lark-msg-${createdMessages.length + 1}`;
2183
+ const message = extractLarkCreatedMessage(request);
2184
+ createdMessages.push({
2167
2185
  messageId,
2168
- text: String(card.elements?.[0]?.content || ''),
2186
+ msgType: message.msgType,
2187
+ text: message.text,
2169
2188
  });
2170
2189
  return { data: { message_id: messageId } };
2171
2190
  },
@@ -2272,9 +2291,10 @@ const server_routes_js_1 = require("../../services/local-ai-core/src/runtime/ser
2272
2291
  replyCtx: 'run-1',
2273
2292
  content: '最终回答',
2274
2293
  });
2275
- strict_1.default.deepEqual(createdCards.map((card) => card.text), [
2294
+ strict_1.default.deepEqual(createdMessages.map((message) => message.msgType), ['interactive', 'text', 'interactive', 'text']);
2295
+ strict_1.default.deepEqual(createdMessages.map((message) => message.text), [
2276
2296
  '先理解用户需求',
2277
- '🔧 Terminal\n\n参数:`{"command":"uname -a","description":"Get system info"}`',
2297
+ '🔧 Terminal\n\n```json\n{\n "command": "uname -a",\n "description": "Get system info"\n}\n```',
2278
2298
  '看到了 Linux',
2279
2299
  '最终回答',
2280
2300
  ]);
@@ -2488,7 +2508,7 @@ const server_routes_js_1 = require("../../services/local-ai-core/src/runtime/ser
2488
2508
  strict_1.default.equal(patchedCards[0]?.card?.elements?.some((element) => element.tag === 'action'), false);
2489
2509
  });
2490
2510
  (0, node_test_1.default)('lark allow all card action preserves the final reply after tool execution', async () => {
2491
- const createdCards = [];
2511
+ const createdMessages = [];
2492
2512
  const patchedCards = [];
2493
2513
  let nextMessageId = 1;
2494
2514
  let gateway;
@@ -2497,9 +2517,12 @@ const server_routes_js_1 = require("../../services/local-ai-core/src/runtime/ser
2497
2517
  message: {
2498
2518
  create: async (request) => {
2499
2519
  const messageId = `card-${nextMessageId++}`;
2500
- createdCards.push({
2520
+ const message = extractLarkCreatedMessage(request);
2521
+ createdMessages.push({
2501
2522
  messageId,
2502
- card: JSON.parse(String(request.data.content || '{}')),
2523
+ msgType: message.msgType,
2524
+ text: message.text,
2525
+ content: message.content,
2503
2526
  });
2504
2527
  return { data: { message_id: messageId } };
2505
2528
  },
@@ -2595,17 +2618,18 @@ const server_routes_js_1 = require("../../services/local-ai-core/src/runtime/ser
2595
2618
  });
2596
2619
  strict_1.default.equal(patchedCards[0]?.messageId, 'permission-msg-1');
2597
2620
  strict_1.default.match(patchedCards[0]?.card?.elements?.[0]?.content || '', /工具确认已处理/);
2598
- strict_1.default.equal(createdCards.length, 1);
2599
- strict_1.default.match(createdCards[0]?.card?.elements?.[0]?.content || '', /桌面文件列表/);
2621
+ strict_1.default.equal(createdMessages.length, 1);
2622
+ strict_1.default.equal(createdMessages[0]?.msgType, 'text');
2623
+ strict_1.default.match(createdMessages[0]?.text || '', /桌面文件列表/);
2600
2624
  });
2601
2625
  (0, node_test_1.default)('lark channel sends tool name and parameters once without streaming output', async () => {
2602
- const createdCards = [];
2626
+ const createdMessages = [];
2603
2627
  const patchedCards = [];
2604
2628
  const client = {
2605
2629
  im: {
2606
2630
  message: {
2607
2631
  create: async (request) => {
2608
- createdCards.push(JSON.parse(String(request.data.content || '{}')));
2632
+ createdMessages.push(extractLarkCreatedMessage(request));
2609
2633
  return { data: { message_id: 'tool-msg-1' } };
2610
2634
  },
2611
2635
  patch: async (request) => {
@@ -2674,9 +2698,11 @@ const server_routes_js_1 = require("../../services/local-ai-core/src/runtime/ser
2674
2698
  output: 'secret terminal output',
2675
2699
  },
2676
2700
  });
2677
- const text = createdCards[0]?.elements?.[0]?.content || '';
2701
+ const text = createdMessages[0]?.text || '';
2702
+ strict_1.default.equal(createdMessages[0]?.msgType, 'text');
2678
2703
  strict_1.default.match(text, /🔧 Terminal/);
2679
- strict_1.default.match(text, /参数:`\{"command":"ls ~\/Desktop"\}`/);
2704
+ strict_1.default.match(text, /```json\n{\n "command": "ls ~\/Desktop"\n}\n```/);
2705
+ strict_1.default.doesNotMatch(text, /参数/);
2680
2706
  strict_1.default.equal(patchedCards.length, 0);
2681
2707
  strict_1.default.doesNotMatch(text, /completed/);
2682
2708
  strict_1.default.doesNotMatch(text, /secret terminal output/);
@@ -3362,6 +3388,7 @@ const server_routes_js_1 = require("../../services/local-ai-core/src/runtime/ser
3362
3388
  },
3363
3389
  });
3364
3390
  strict_1.default.equal(completed.text, '🔧 bash: Tool update');
3391
+ strict_1.default.equal(completed.delivery, 'message');
3365
3392
  });
3366
3393
  (0, node_test_1.default)('ACP skips empty generic running tool updates', () => {
3367
3394
  const appended = [];
@@ -3628,6 +3655,8 @@ const server_routes_js_1 = require("../../services/local-ai-core/src/runtime/ser
3628
3655
  strict_1.default.equal(result.runId, 'run-local-1');
3629
3656
  strict_1.default.equal(result.replyText, 'local done');
3630
3657
  strict_1.default.equal(result.platformMessageId, undefined);
3658
+ strict_1.default.equal(result.deliveryMode, 'thread-only');
3659
+ strict_1.default.equal(result.deliveryStatus, 'succeeded');
3631
3660
  });
3632
3661
  (0, node_test_1.default)('scheduler run lifecycle updates run and job state through explicit transitions', () => {
3633
3662
  const emittedRuns = [];
@@ -3678,6 +3707,10 @@ const server_routes_js_1 = require("../../services/local-ai-core/src/runtime/ser
3678
3707
  threadId: 'thread-1',
3679
3708
  runId: 'run-1',
3680
3709
  platformMessageId: 'msg-1',
3710
+ platformMessageIds: ['msg-1', 'msg-2'],
3711
+ deliveryMode: 'bridge-stream',
3712
+ deliveryStatus: 'succeeded',
3713
+ lastBridgeEventAt: '2026-04-22T06:00:03.000Z',
3681
3714
  }, true);
3682
3715
  strict_1.default.deepEqual(emittedRuns, [
3683
3716
  'run-1:queued',
@@ -3685,6 +3718,23 @@ const server_routes_js_1 = require("../../services/local-ai-core/src/runtime/ser
3685
3718
  'run-1:succeeded',
3686
3719
  ]);
3687
3720
  strict_1.default.deepEqual(emittedJobs, ['job-1:false']);
3721
+ strict_1.default.deepEqual(runs.get(queued.id), {
3722
+ id: 'run-1',
3723
+ jobId: 'job-1',
3724
+ status: 'succeeded',
3725
+ triggeredAt: '2026-04-22T06:00:00.000Z',
3726
+ deliveryStatus: 'succeeded',
3727
+ startedAt: runs.get(queued.id).startedAt,
3728
+ finishedAt: runs.get(queued.id).finishedAt,
3729
+ threadId: 'thread-1',
3730
+ runId: 'run-1',
3731
+ platformMessageId: 'msg-1',
3732
+ platformMessageIds: ['msg-1', 'msg-2'],
3733
+ deliveryMode: 'bridge-stream',
3734
+ deliveryError: '',
3735
+ lastBridgeEventAt: '2026-04-22T06:00:03.000Z',
3736
+ error: '',
3737
+ });
3688
3738
  });
3689
3739
  (0, node_test_1.default)('lark side-thread execution policy reuses a dedicated scheduled thread', async () => {
3690
3740
  const job = {
@@ -3702,19 +3752,46 @@ const server_routes_js_1 = require("../../services/local-ai-core/src/runtime/ser
3702
3752
  createdAt: '2026-04-22T06:00:00.000Z',
3703
3753
  updatedAt: '2026-04-22T06:00:00.000Z',
3704
3754
  };
3755
+ let registeredBridge;
3756
+ const bridgeEvents = [];
3757
+ let unregisteredBridge = false;
3705
3758
  const policy = (0, lark_execution_policies_js_1.createLarkExecutionPolicy)(job, {
3706
3759
  store: {},
3707
3760
  workspaceRouter: {
3761
+ getThreadSessionKey: (threadId) => `session:${threadId}`,
3708
3762
  listThreads: async () => [{ id: 'thread-scheduled', title: '[Scheduled] two-minute ping' }],
3709
3763
  createThread: async () => ({ id: 'thread-new' }),
3710
3764
  },
3711
3765
  getChannelRuntime: () => ({
3712
- muteThreadBridge: () => { },
3713
- unmuteThreadBridge: () => { },
3766
+ onBridgeEvent: async (event) => {
3767
+ bridgeEvents.push(event);
3768
+ },
3769
+ registerScheduledThreadBridge: (input) => {
3770
+ registeredBridge = input;
3771
+ return () => {
3772
+ unregisteredBridge = true;
3773
+ };
3774
+ },
3714
3775
  }),
3715
3776
  }, async () => 'thread-origin');
3716
3777
  const target = await policy.resolveTarget(job);
3717
3778
  strict_1.default.equal(target.threadId, 'thread-scheduled');
3779
+ await policy.beforeExecute?.(target, job);
3780
+ strict_1.default.deepEqual(registeredBridge, {
3781
+ workspaceId: '知识库',
3782
+ platform: 'lark',
3783
+ route: { type: 'channel.chat', channelId: 'chat-1', participantId: 'user-1', threadId: 'thread-origin' },
3784
+ threadId: 'thread-scheduled',
3785
+ sessionKey: 'session:thread-scheduled',
3786
+ });
3787
+ strict_1.default.deepEqual(bridgeEvents[0], {
3788
+ type: 'status',
3789
+ sessionKey: 'session:thread-scheduled',
3790
+ bridgeKind: 'status',
3791
+ content: '⏰ two-minute ping',
3792
+ });
3793
+ policy.afterExecute?.(target, job);
3794
+ strict_1.default.equal(unregisteredBridge, true);
3718
3795
  });
3719
3796
  (0, node_test_1.default)('lark same-thread execution policy keeps the original thread target', async () => {
3720
3797
  const job = {
@@ -3732,16 +3809,29 @@ const server_routes_js_1 = require("../../services/local-ai-core/src/runtime/ser
3732
3809
  createdAt: '2026-04-22T06:00:00.000Z',
3733
3810
  updatedAt: '2026-04-22T06:00:00.000Z',
3734
3811
  };
3812
+ let registeredBridge;
3735
3813
  const policy = (0, lark_execution_policies_js_1.createLarkExecutionPolicy)(job, {
3736
3814
  store: {},
3737
- workspaceRouter: {},
3815
+ workspaceRouter: {
3816
+ getThreadSessionKey: (threadId) => `session:${threadId}`,
3817
+ },
3738
3818
  getChannelRuntime: () => ({
3739
- muteThreadBridge: () => { },
3740
- unmuteThreadBridge: () => { },
3819
+ registerScheduledThreadBridge: (input) => {
3820
+ registeredBridge = input;
3821
+ return () => { };
3822
+ },
3741
3823
  }),
3742
3824
  }, async () => 'thread-origin');
3743
3825
  const target = await policy.resolveTarget(job);
3744
3826
  strict_1.default.equal(target.threadId, 'thread-origin');
3827
+ await policy.beforeExecute?.(target, job);
3828
+ strict_1.default.deepEqual(registeredBridge, {
3829
+ workspaceId: '知识库',
3830
+ platform: 'lark',
3831
+ route: { type: 'channel.chat', channelId: 'chat-1', participantId: 'user-1', threadId: 'thread-origin' },
3832
+ threadId: 'thread-origin',
3833
+ sessionKey: 'session:thread-origin',
3834
+ });
3745
3835
  });
3746
3836
  (0, node_test_1.default)('weixin channel can request a QR code without platform options', async () => {
3747
3837
  const originalFetch = globalThis.fetch;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kafca/agentdock",
3
- "version": "0.1.36",
3
+ "version": "0.1.38",
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{z as t}from"./index-Bin2xyBS.js";const e=()=>t.get("/projects"),r=o=>t.get(`/projects/${o}`);export{r as g,e as l};