@ai-setting/roy-agent-core 1.7.58 → 1.7.61

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 (120) hide show
  1. package/dist/config/index.js +8 -8
  2. package/dist/env/agent/index.js +14 -14
  3. package/dist/env/commands/index.js +8 -8
  4. package/dist/env/context/index.js +4 -4
  5. package/dist/env/debug/index.js +8 -8
  6. package/dist/env/event-source/cli-command-handler.d.ts +90 -0
  7. package/dist/env/event-source/event-source-handlers.d.ts +12 -1
  8. package/dist/env/event-source/index.d.ts +4 -2
  9. package/dist/env/event-source/index.js +30 -20
  10. package/dist/env/event-source/types.d.ts +89 -1
  11. package/dist/env/hook/index.js +6 -6
  12. package/dist/env/index.d.ts +1 -1
  13. package/dist/env/index.js +46 -46
  14. package/dist/env/llm/index.js +9 -9
  15. package/dist/env/log-trace/index.d.ts +1 -1
  16. package/dist/env/log-trace/index.js +12 -8
  17. package/dist/env/log-trace/logger.d.ts +2 -0
  18. package/dist/env/mcp/index.js +9 -9
  19. package/dist/env/mcp/tool/index.js +2 -2
  20. package/dist/env/memory/index.js +9 -9
  21. package/dist/env/memory/plugin/index.js +2 -2
  22. package/dist/env/plugin/index.js +8 -8
  23. package/dist/env/prompt/index.js +8 -8
  24. package/dist/env/session/index.js +11 -11
  25. package/dist/env/session/storage/index.js +5 -5
  26. package/dist/env/skill/index.js +8 -8
  27. package/dist/env/task/delegate/index.js +9 -9
  28. package/dist/env/task/index.js +16 -16
  29. package/dist/env/task/mcp/index.d.ts +16 -0
  30. package/dist/env/task/mcp/index.js +222 -0
  31. package/dist/env/task/mcp/task-mcp-server.d.ts +142 -0
  32. package/dist/env/task/plugins/index.d.ts +1 -0
  33. package/dist/env/task/plugins/index.js +47 -12
  34. package/dist/env/task/storage/index.js +4 -4
  35. package/dist/env/task/storage/migrations/log-migration.d.ts +19 -0
  36. package/dist/env/task/storage/sqlite-task-store.d.ts +29 -0
  37. package/dist/env/task/task-component.d.ts +48 -3
  38. package/dist/env/task/tools/index.js +4 -4
  39. package/dist/env/task/tools/task-types.d.ts +60 -11
  40. package/dist/env/tool/built-in/index.js +4 -4
  41. package/dist/env/tool/index.js +11 -11
  42. package/dist/env/workflow/engine/index.js +13 -13
  43. package/dist/env/workflow/hooks/index.js +8 -8
  44. package/dist/env/workflow/index.js +23 -23
  45. package/dist/env/workflow/nodes/index.js +3 -3
  46. package/dist/env/workflow/plugins/index.js +9 -9
  47. package/dist/env/workflow/service/index.js +3 -3
  48. package/dist/env/workflow/storage/index.js +4 -4
  49. package/dist/env/workflow/tools/index.js +15 -15
  50. package/dist/env/workflow/tools/run-workflow.d.ts +30 -0
  51. package/dist/env/workflow/utils/index.js +5 -5
  52. package/dist/env/workflow/utils/session-recovery.d.ts +27 -0
  53. package/dist/index.js +81 -71
  54. package/dist/shared/@ai-setting/{roy-agent-core-tze5596n.js → roy-agent-core-0f989bnp.js} +3 -3
  55. package/dist/shared/@ai-setting/{roy-agent-core-e250355z.js → roy-agent-core-22r4zmkw.js} +3 -3
  56. package/dist/shared/@ai-setting/{roy-agent-core-8p63s836.js → roy-agent-core-2qkrpc7m.js} +1 -1
  57. package/dist/shared/@ai-setting/{roy-agent-core-47s81t6g.js → roy-agent-core-3bpntd80.js} +2 -2
  58. package/dist/shared/@ai-setting/{roy-agent-core-rcgvmtms.js → roy-agent-core-3p59ap0x.js} +1 -1
  59. package/dist/shared/@ai-setting/{roy-agent-core-en2xqxs9.js → roy-agent-core-4m5spt7m.js} +39 -14
  60. package/dist/shared/@ai-setting/{roy-agent-core-5f7myqnb.js → roy-agent-core-5565cvw8.js} +11 -5
  61. package/dist/shared/@ai-setting/{roy-agent-core-2fk8c9ax.js → roy-agent-core-5knpegzr.js} +3 -3
  62. package/dist/shared/@ai-setting/{roy-agent-core-08njdcpj.js → roy-agent-core-60p2380d.js} +1 -1
  63. package/dist/shared/@ai-setting/{roy-agent-core-0yn7a78e.js → roy-agent-core-6cyjps72.js} +14 -14
  64. package/dist/shared/@ai-setting/{roy-agent-core-89sxsrc7.js → roy-agent-core-8fy467qs.js} +1 -1
  65. package/dist/shared/@ai-setting/{roy-agent-core-x6c45yqd.js → roy-agent-core-99nwgj84.js} +1 -1
  66. package/dist/shared/@ai-setting/{roy-agent-core-20m8je6e.js → roy-agent-core-9k8ms63r.js} +1 -1
  67. package/dist/shared/@ai-setting/{roy-agent-core-0kn3zt1t.js → roy-agent-core-9s3payp1.js} +2 -2
  68. package/dist/shared/@ai-setting/{roy-agent-core-hefarcp0.js → roy-agent-core-a5nh5q6v.js} +1 -1
  69. package/dist/shared/@ai-setting/{roy-agent-core-hs41gx9w.js → roy-agent-core-aa514zm8.js} +5 -5
  70. package/dist/shared/@ai-setting/{roy-agent-core-yphwdm9x.js → roy-agent-core-ajmgyawx.js} +2 -2
  71. package/dist/shared/@ai-setting/{roy-agent-core-caevk7xd.js → roy-agent-core-arx535cs.js} +30 -8
  72. package/dist/shared/@ai-setting/{roy-agent-core-vath15kt.js → roy-agent-core-bc3v8pw4.js} +6 -6
  73. package/dist/shared/@ai-setting/{roy-agent-core-m97jn2ra.js → roy-agent-core-bdzdw1g3.js} +1 -1
  74. package/dist/shared/@ai-setting/{roy-agent-core-ck60j1q9.js → roy-agent-core-bxkjk7zx.js} +2 -1
  75. package/dist/shared/@ai-setting/{roy-agent-core-6bradb0j.js → roy-agent-core-cndvj1hv.js} +8 -8
  76. package/dist/shared/@ai-setting/{roy-agent-core-d75t8gea.js → roy-agent-core-dg286rpd.js} +1 -1
  77. package/dist/shared/@ai-setting/{roy-agent-core-q4gdfypk.js → roy-agent-core-dp1hp24k.js} +3 -3
  78. package/dist/shared/@ai-setting/{roy-agent-core-ygn5tzt1.js → roy-agent-core-dythsgkn.js} +2 -2
  79. package/dist/shared/@ai-setting/{roy-agent-core-em4hks9t.js → roy-agent-core-e6k448ka.js} +4 -4
  80. package/dist/shared/@ai-setting/{roy-agent-core-ytd5eztz.js → roy-agent-core-expvav8a.js} +1 -1
  81. package/dist/shared/@ai-setting/{roy-agent-core-vgdhxbx3.js → roy-agent-core-g44nbgtt.js} +2 -2
  82. package/dist/shared/@ai-setting/{roy-agent-core-14bq77wr.js → roy-agent-core-g5sw19fa.js} +1 -1
  83. package/dist/shared/@ai-setting/{roy-agent-core-991pk4ss.js → roy-agent-core-gtb4fj8j.js} +16 -16
  84. package/dist/shared/@ai-setting/{roy-agent-core-gksw1gjb.js → roy-agent-core-hf0t8agb.js} +1 -1
  85. package/dist/shared/@ai-setting/{roy-agent-core-txwptxk1.js → roy-agent-core-j0x9yf96.js} +3 -3
  86. package/dist/shared/@ai-setting/{roy-agent-core-84rs0c8d.js → roy-agent-core-jrksyqb6.js} +7 -7
  87. package/dist/shared/@ai-setting/{roy-agent-core-ge87xbas.js → roy-agent-core-jsdqzfbj.js} +1 -1
  88. package/dist/shared/@ai-setting/{roy-agent-core-m68z3pw1.js → roy-agent-core-jsn21cb9.js} +1 -1
  89. package/dist/shared/@ai-setting/{roy-agent-core-n0p0hwgd.js → roy-agent-core-kfmrfaft.js} +1 -1
  90. package/dist/shared/@ai-setting/{roy-agent-core-7q4wdze2.js → roy-agent-core-khc23qs1.js} +1 -1
  91. package/dist/shared/@ai-setting/{roy-agent-core-e1w17tht.js → roy-agent-core-m2tv4pj0.js} +2 -2
  92. package/dist/shared/@ai-setting/{roy-agent-core-4096f575.js → roy-agent-core-mhppywse.js} +4 -4
  93. package/dist/shared/@ai-setting/{roy-agent-core-t64nmayv.js → roy-agent-core-mw0bc9g6.js} +2 -2
  94. package/dist/shared/@ai-setting/{roy-agent-core-8bngppw0.js → roy-agent-core-n1ck0x1r.js} +13 -13
  95. package/dist/shared/@ai-setting/{roy-agent-core-w93z6a42.js → roy-agent-core-nd5171pv.js} +12 -12
  96. package/dist/shared/@ai-setting/{roy-agent-core-geh6j7bw.js → roy-agent-core-p2dpcyrz.js} +2 -2
  97. package/dist/shared/@ai-setting/{roy-agent-core-fw6k4w1h.js → roy-agent-core-pj5tfmn5.js} +6 -6
  98. package/dist/shared/@ai-setting/{roy-agent-core-029r8kdw.js → roy-agent-core-q212q0w1.js} +4 -4
  99. package/dist/shared/@ai-setting/{roy-agent-core-psg6f1v6.js → roy-agent-core-qgapy83x.js} +6 -6
  100. package/dist/shared/@ai-setting/{roy-agent-core-jjxdmedn.js → roy-agent-core-qpqqx1wd.js} +2 -2
  101. package/dist/shared/@ai-setting/{roy-agent-core-syyw58p9.js → roy-agent-core-qrjs2500.js} +2 -2
  102. package/dist/shared/@ai-setting/{roy-agent-core-84xtww7d.js → roy-agent-core-qw5fpa24.js} +3 -3
  103. package/dist/shared/@ai-setting/{roy-agent-core-kq9pz2a7.js → roy-agent-core-rnzm0tpf.js} +4 -4
  104. package/dist/shared/@ai-setting/{roy-agent-core-7nb23tdd.js → roy-agent-core-s7w47mnn.js} +1 -1
  105. package/dist/shared/@ai-setting/{roy-agent-core-t4x089js.js → roy-agent-core-sf9tsj0g.js} +1 -1
  106. package/dist/shared/@ai-setting/{roy-agent-core-jjhw9am6.js → roy-agent-core-tn96n4wz.js} +4 -4
  107. package/dist/shared/@ai-setting/{roy-agent-core-c7w2h47a.js → roy-agent-core-vmfk4m1v.js} +3 -3
  108. package/dist/shared/@ai-setting/{roy-agent-core-cyefe8z5.js → roy-agent-core-x1m0gs0q.js} +1 -1
  109. package/dist/shared/@ai-setting/{roy-agent-core-baaa4wtp.js → roy-agent-core-xc0es9zc.js} +2 -2
  110. package/dist/shared/@ai-setting/{roy-agent-core-fbjd7bt6.js → roy-agent-core-xeqp659x.js} +64 -29
  111. package/dist/shared/@ai-setting/{roy-agent-core-rt115qfc.js → roy-agent-core-y0k9kaxz.js} +14 -4
  112. package/dist/shared/@ai-setting/{roy-agent-core-c36335nw.js → roy-agent-core-yd85623y.js} +15 -3
  113. package/dist/shared/@ai-setting/{roy-agent-core-9zhkdg6w.js → roy-agent-core-ygfjgk9b.js} +2 -2
  114. package/dist/shared/@ai-setting/{roy-agent-core-vh0qzb24.js → roy-agent-core-ymcvsdzn.js} +36 -15
  115. package/dist/shared/@ai-setting/{roy-agent-core-eanq305k.js → roy-agent-core-yr5eqyhz.js} +11 -11
  116. package/dist/shared/@ai-setting/{roy-agent-core-fy4mcj6x.js → roy-agent-core-ytnedzks.js} +292 -105
  117. package/dist/shared/@ai-setting/{roy-agent-core-2ctyjy62.js → roy-agent-core-z51jktet.js} +1 -1
  118. package/dist/utils/temp-file-manager/index.js +2 -2
  119. package/package.json +16 -1
  120. /package/dist/shared/@ai-setting/{roy-agent-core-3ztzc83c.js → roy-agent-core-5enxfga2.js} +0 -0
@@ -1,23 +1,23 @@
1
1
  import {
2
2
  defaultLarkCliRunner
3
- } from "./roy-agent-core-ck60j1q9.js";
3
+ } from "./roy-agent-core-bxkjk7zx.js";
4
4
  import {
5
5
  TaskTagPlugin,
6
6
  createLarkCliTaskNotifyHook,
7
7
  createPerTaskGroupChatPlugin,
8
8
  extractPerTaskChatId,
9
9
  extractPerTaskChatName
10
- } from "./roy-agent-core-8bngppw0.js";
10
+ } from "./roy-agent-core-n1ck0x1r.js";
11
11
  import {
12
12
  getSharedEventStore
13
- } from "./roy-agent-core-2ctyjy62.js";
13
+ } from "./roy-agent-core-z51jktet.js";
14
14
  import {
15
15
  createLarkCliWorkflowNotifyHook
16
- } from "./roy-agent-core-psg6f1v6.js";
16
+ } from "./roy-agent-core-qgapy83x.js";
17
17
  import {
18
18
  LarkCardPatchNotifier,
19
19
  buildTaskCard
20
- } from "./roy-agent-core-c36335nw.js";
20
+ } from "./roy-agent-core-yd85623y.js";
21
21
  import {
22
22
  normalizeLarkAtMentions
23
23
  } from "./roy-agent-core-64f22h1g.js";
@@ -26,29 +26,29 @@ import {
26
26
  } from "./roy-agent-core-7hh0brvs.js";
27
27
  import {
28
28
  BaseComponent
29
- } from "./roy-agent-core-0kn3zt1t.js";
29
+ } from "./roy-agent-core-9s3payp1.js";
30
30
  import {
31
31
  globalHookManager,
32
32
  init_global_hook_manager
33
- } from "./roy-agent-core-yphwdm9x.js";
33
+ } from "./roy-agent-core-ajmgyawx.js";
34
34
  import {
35
35
  init_context
36
- } from "./roy-agent-core-m97jn2ra.js";
36
+ } from "./roy-agent-core-bdzdw1g3.js";
37
37
  import {
38
38
  createEnvContext,
39
39
  normalizeParentTaskId,
40
40
  runWithEnvContext
41
- } from "./roy-agent-core-syyw58p9.js";
41
+ } from "./roy-agent-core-qrjs2500.js";
42
42
  import {
43
43
  TracedAs,
44
44
  init_decorator,
45
45
  wrapFunction
46
- } from "./roy-agent-core-8p63s836.js";
46
+ } from "./roy-agent-core-2qkrpc7m.js";
47
47
  import {
48
48
  createLogger,
49
49
  getTracerProvider,
50
50
  init_logger
51
- } from "./roy-agent-core-rt115qfc.js";
51
+ } from "./roy-agent-core-y0k9kaxz.js";
52
52
  import {
53
53
  __legacyDecorateClassTS,
54
54
  __require
@@ -609,6 +609,155 @@ var bountyIMHandler = {
609
609
  }
610
610
  };
611
611
 
612
+ // src/env/event-source/cli-command-handler.ts
613
+ init_logger();
614
+ var logger = createLogger("cli-command:event-source");
615
+ var CLI_COMMAND_ES_TYPE = "cli-command";
616
+ var CLI_SESSION_CHAT_ID_PREFIX = "cli:";
617
+ function buildCliReplyChannel(params) {
618
+ const sid = params.sessionId?.trim() ? params.sessionId.trim() : "default";
619
+ return {
620
+ type: CLI_COMMAND_ES_TYPE,
621
+ chatId: `${CLI_SESSION_CHAT_ID_PREFIX}${sid}`,
622
+ params: { sink: "stdout", cliSessionId: sid }
623
+ };
624
+ }
625
+ function parseCliSessionChatId(chatId) {
626
+ if (!chatId || !chatId.startsWith(CLI_SESSION_CHAT_ID_PREFIX))
627
+ return;
628
+ const sid = chatId.slice(CLI_SESSION_CHAT_ID_PREFIX.length);
629
+ return sid.length > 0 ? sid : undefined;
630
+ }
631
+ function describeNotifyEvent(type, taskLabel, desc) {
632
+ const actionable = new Set([
633
+ "task.background.completed",
634
+ "task.background.failed",
635
+ "task.background.timeout",
636
+ "task.background.stopped"
637
+ ]).has(type);
638
+ switch (type) {
639
+ case "task.background.completed":
640
+ return { headline: `Sub-agent 完成了 ${taskLabel}「${desc}」。`, actionable };
641
+ case "task.background.failed":
642
+ return { headline: `Sub-agent 执行 ${taskLabel}「${desc}」失败。`, actionable };
643
+ case "task.background.timeout":
644
+ return { headline: `Sub-agent 执行 ${taskLabel}「${desc}」**超时**(未跑完)。`, actionable };
645
+ case "task.background.stopped":
646
+ return { headline: `Sub-agent 已停止 ${taskLabel}「${desc}」。`, actionable };
647
+ case "task.background.ask_user":
648
+ return { headline: `Sub-agent 在 ${taskLabel}「${desc}」中请求用户输入。`, actionable };
649
+ case "task.background.started":
650
+ return { headline: `Sub-agent 已启动 ${taskLabel}「${desc}」(后台运行中)。`, actionable };
651
+ case "task.background.progress":
652
+ return { headline: `Sub-agent 仍在执行 ${taskLabel}「${desc}」(进行中)。`, actionable };
653
+ default:
654
+ return { headline: `Sub-agent 更新了 ${taskLabel}「${desc}」。`, actionable };
655
+ }
656
+ }
657
+ function renderRuleNoticeSectionForCli(ruleNotice, headline) {
658
+ if (!ruleNotice || !ruleNotice.attempted) {
659
+ return `(本事件不直发规则回执)
660
+ ` + `→ 你的回复要把结果讲**完整**(终端用户只能从你这条输出知道结论)。`;
661
+ }
662
+ if (ruleNotice.delivered) {
663
+ const when = ruleNotice.sentAt ? new Date(ruleNotice.sentAt).toLocaleTimeString("zh-CN", {
664
+ hour12: false,
665
+ hour: "2-digit",
666
+ minute: "2-digit"
667
+ }) : "";
668
+ const sent = ruleNotice.text ? `:「${ruleNotice.text.replace(/\s*\n+\s*/g, " ")}」` : "";
669
+ return `✅ 系统已于 ${when || "刚才"} 向终端输出过下面这条${sent}
670
+ ` + `→ 你的回复**只发增量**:不要再重复「任务已结束」这类回执原文,` + `直接讲结论/交付 + 下一步选项。`;
671
+ }
672
+ return `❌ **回执未送达**(原因:${ruleNotice.error ?? "unknown"})
673
+ ` + `→ 用户目前**还不知道**「${headline}」这件事,必须由你在回复里讲清楚,` + `并且不要假装系统已经通知过。`;
674
+ }
675
+ var cliCommandHandler = {
676
+ type: CLI_COMMAND_ES_TYPE,
677
+ validateConfig(_config) {
678
+ return [];
679
+ },
680
+ createInstance(config) {
681
+ return {
682
+ config,
683
+ start: async () => {},
684
+ stop: async () => {},
685
+ isRunning: () => false,
686
+ getStatus: () => ({
687
+ id: config.id,
688
+ type: CLI_COMMAND_ES_TYPE,
689
+ running: false
690
+ })
691
+ };
692
+ },
693
+ async emitTriggerEvent(payload, store) {
694
+ const eventId = await store.insertTriggerEvent(payload, CLI_COMMAND_ES_TYPE);
695
+ logger.info(`[cliCommandHandler] emitTriggerEvent: id=${eventId}`, {
696
+ sessionId: payload.metadata?.sessionId,
697
+ cwd: payload.metadata?.cwd
698
+ });
699
+ return eventId;
700
+ },
701
+ extractReplyContext(event, profile) {
702
+ const meta = event.metadata ?? {};
703
+ return {
704
+ esType: CLI_COMMAND_ES_TYPE,
705
+ chatId: typeof meta.chatId === "string" ? meta.chatId : "",
706
+ messageId: typeof meta.messageId === "string" ? meta.messageId : "",
707
+ senderOpenId: typeof meta.senderId === "string" ? meta.senderId : "",
708
+ profile: profile ?? (typeof meta.profile === "string" ? meta.profile : undefined)
709
+ };
710
+ },
711
+ buildNotifyHandlePrompt(input) {
712
+ const { notifyEvent, triggerEvent, ruleNotice, subAgentResult, channel } = input;
713
+ const triggerMeta = triggerEvent.metadata ?? {};
714
+ const legacyPayload = notifyEvent.payload ?? {};
715
+ const rawTaskId = notifyEvent.taskId ?? legacyPayload.associatedTaskId;
716
+ const bgId = notifyEvent.backgroundTaskId ?? legacyPayload.backgroundTaskId;
717
+ const shortBgId = bgId ? bgId.split("_").pop() : undefined;
718
+ const taskLabel = rawTaskId !== undefined ? `Task #${rawTaskId}` : shortBgId ? `后台任务 ${shortBgId}` : "后台任务";
719
+ const desc = notifyEvent.description ?? legacyPayload.description ?? "后台任务";
720
+ const result = (subAgentResult?.summary && subAgentResult.summary.trim() ? subAgentResult.summary : undefined) ?? notifyEvent.result ?? notifyEvent.error ?? legacyPayload.result ?? legacyPayload.error ?? "(无结果)";
721
+ const cwd = typeof triggerMeta.cwd === "string" ? triggerMeta.cwd : "(未知)";
722
+ const cliSession = typeof triggerMeta.sessionId === "string" ? triggerMeta.sessionId : "(未知)";
723
+ const query = typeof triggerEvent.text === "string" && triggerEvent.text ? triggerEvent.text : "(未记录)";
724
+ const { headline } = describeNotifyEvent(notifyEvent.type, taskLabel, desc);
725
+ const channelLabel = channel?.esType ?? CLI_COMMAND_ES_TYPE;
726
+ return {
727
+ promptText: [
728
+ `# 后台任务通知(渠道:CLI 命令行)`,
729
+ ``,
730
+ `## 触发渠道`,
731
+ `- 渠道类型: \`${channelLabel}\`(用户在**终端**直接输入 query 触发,不是飞书消息)`,
732
+ `- 工作目录: \`${cwd}\``,
733
+ `- CLI session: \`${cliSession}\``,
734
+ `- 用户原始 query: ${query.length > 400 ? query.slice(0, 400) + "…" : query}`,
735
+ `- **回复方式: 直接输出到 stdout(终端)**。`,
736
+ ``,
737
+ `⚠️ **本渠道没有 IM 通道,不要调用 lark-cli**。`,
738
+ ` 不要尝试 \`lark-cli im +messages-send\` / \`+messages-reply\`,`,
739
+ ` 不要编造 chatId(\`cli:*\` 不是真实飞书会话,发过去必然失败),`,
740
+ ` 也不要调用任何飞书相关工具。用户就在终端前等你的文字输出。`,
741
+ ``,
742
+ `## 系统回执`,
743
+ renderRuleNoticeSectionForCli(ruleNotice, headline),
744
+ ``,
745
+ `## 事件`,
746
+ headline,
747
+ ``,
748
+ `## Sub-agent 输出`,
749
+ result,
750
+ ``,
751
+ `## 你要做什么`,
752
+ `1. 把上面 Sub-agent 的结论整理成**给终端用户直接读的一段话**。`,
753
+ `2. **直接输出这段文字**(它就是用户看到的内容),不要包 JSON、不要写文件。`,
754
+ `3. 若「系统回执」显示已送达,只讲**增量**;未送达则把结论讲完整。`
755
+ ].join(`
756
+ `)
757
+ };
758
+ }
759
+ };
760
+
612
761
  // src/env/event-source/event-source-handlers.ts
613
762
  import { spawn as spawn3, exec as execSync } from "child_process";
614
763
  import { promisify as promisify2 } from "node:util";
@@ -619,7 +768,7 @@ init_context();
619
768
  init_logger();
620
769
  import { exec } from "node:child_process";
621
770
  import { promisify } from "node:util";
622
- var logger = createLogger("lark-card-action-handler");
771
+ var logger2 = createLogger("lark-card-action-handler");
623
772
  var execAsync = promisify(exec);
624
773
  var CTX_FIELD_CHAT_ID = "larkPerTaskChatId";
625
774
  var CTX_FIELD_CHAT_NAME = "larkPerTaskChatName";
@@ -639,7 +788,7 @@ async function handleCardAction(event, ports) {
639
788
  const inflightKey = `${event.profile ?? "-"}:${event.messageId || String(taskId)}:${action}`;
640
789
  const inflight = cardActionInflight.get(inflightKey);
641
790
  if (inflight) {
642
- logger.warn(`handleCardAction: ${inflightKey} 已有同操作在处理中(疑似用户重复点击),本次忽略。`);
791
+ logger2.warn(`handleCardAction: ${inflightKey} 已有同操作在处理中(疑似用户重复点击),本次忽略。`);
643
792
  return { ok: false, action, error: `重复点击:${inflightKey} 正在处理中,已忽略` };
644
793
  }
645
794
  const pending = handleCardActionInner(event, ports, taskId);
@@ -670,10 +819,10 @@ function buildCardAfterGroupChange(event, ports, task, perTaskChatId, perTaskCha
670
819
  const meta = buildTaskMetaFromTask(task, perTaskChatId, perTaskChatName);
671
820
  const preserved = ports.notifier?.updateMetaAndBuildCard?.(event.messageId, meta, { clearPerTaskChat: !perTaskChatId });
672
821
  if (preserved) {
673
- logger.debug(`buildCardAfterGroupChange: 复用 notifier 累积状态(里程碑历史保留)messageId=${event.messageId}`);
822
+ logger2.debug(`buildCardAfterGroupChange: 复用 notifier 累积状态(里程碑历史保留)messageId=${event.messageId}`);
674
823
  return preserved;
675
824
  }
676
- logger.warn(`buildCardAfterGroupChange: notifier 无 messageId=${event.messageId} 的状态,` + `fallback 重建卡片(该卡片的历史里程碑可能丢失)`);
825
+ logger2.warn(`buildCardAfterGroupChange: notifier 无 messageId=${event.messageId} 的状态,` + `fallback 重建卡片(该卡片的历史里程碑可能丢失)`);
677
826
  return buildTaskCard({
678
827
  status: "running",
679
828
  meta,
@@ -685,7 +834,7 @@ function buildCardAfterGroupChange(event, ports, task, perTaskChatId, perTaskCha
685
834
  async function handleCreateGroup(event, ports, task, existingChatId) {
686
835
  if (existingChatId) {
687
836
  const existingName = extractPerTaskChatName(task.context);
688
- logger.info(`handleCreateGroup: Task #${task.id} 已有专属群 ${existingChatId}(幂等命中,不重复建群)`);
837
+ logger2.info(`handleCreateGroup: Task #${task.id} 已有专属群 ${existingChatId}(幂等命中,不重复建群)`);
689
838
  return {
690
839
  ok: true,
691
840
  action: "create_group",
@@ -711,17 +860,17 @@ async function handleCreateGroup(event, ports, task, existingChatId) {
711
860
  if (operatorOpenId) {
712
861
  if (initialUserIds) {
713
862
  invitedOpenIds = [operatorOpenId];
714
- logger.debug(`handleCreateGroup: ${operatorOpenId} 已在建群时邀请(initialUserIds 路径)`);
863
+ logger2.debug(`handleCreateGroup: ${operatorOpenId} 已在建群时邀请(initialUserIds 路径)`);
715
864
  } else if (ports.inviteUser) {
716
865
  try {
717
866
  await ports.inviteUser(chatId, operatorOpenId, event.profile);
718
867
  invitedOpenIds = [operatorOpenId];
719
- logger.debug(`handleCreateGroup: 走 inviteUser 端口邀请 ${operatorOpenId} 进 ${chatId}`);
868
+ logger2.debug(`handleCreateGroup: 走 inviteUser 端口邀请 ${operatorOpenId} 进 ${chatId}`);
720
869
  } catch (err) {
721
- logger.warn(`handleCreateGroup: inviteUser(${chatId}, ${operatorOpenId}) 失败(不阻断主流程): ${err.message}`);
870
+ logger2.warn(`handleCreateGroup: inviteUser(${chatId}, ${operatorOpenId}) 失败(不阻断主流程): ${err.message}`);
722
871
  }
723
872
  } else {
724
- logger.warn(`handleCreateGroup: createGroupChat 不支持 initialUserIds 且 inviteUser 未注入,` + `${operatorOpenId} 未被拉进群 ${chatId}。` + `需升级 caller(bridge/real impl)使用 ports.inviteUser 或实现 createGroupChat.initialUserIds 参数。`);
873
+ logger2.warn(`handleCreateGroup: createGroupChat 不支持 initialUserIds 且 inviteUser 未注入,` + `${operatorOpenId} 未被拉进群 ${chatId}。` + `需升级 caller(bridge/real impl)使用 ports.inviteUser 或实现 createGroupChat.initialUserIds 参数。`);
725
874
  }
726
875
  }
727
876
  const newContext = patchContext(task.context ?? "{}", {
@@ -737,7 +886,7 @@ async function handleCreateGroup(event, ports, task, existingChatId) {
737
886
  const cardUpdate = buildCardAfterGroupChange(event, ports, task, chatId, renderedName);
738
887
  return { ok: true, action: "create_group", newChatId: chatId, cardUpdate };
739
888
  } catch (err) {
740
- logger.error(`handleCardAction.create_group failed: ${err.message}`);
889
+ logger2.error(`handleCardAction.create_group failed: ${err.message}`);
741
890
  return { ok: false, action: "create_group", error: err.message };
742
891
  }
743
892
  }
@@ -775,7 +924,7 @@ async function handleDisbandGroup(event, ports, task, existingChatId) {
775
924
  const cardUpdate = buildCardAfterGroupChange(event, ports, task, undefined, undefined);
776
925
  return { ok: true, action: "disband_group", cardUpdate };
777
926
  } catch (err) {
778
- logger.error(`handleCardAction.disband_group failed: ${err.message}`);
927
+ logger2.error(`handleCardAction.disband_group failed: ${err.message}`);
779
928
  return { ok: false, action: "disband_group", error: err.message };
780
929
  }
781
930
  }
@@ -824,9 +973,9 @@ async function deleteGroupChatViaLarkCli(chatId, profile) {
824
973
  }
825
974
  const cmd = `lark-cli ${profileFlag}api DELETE /open-apis/im/v1/chats/${chatId}/members ` + `--params '{"member_id_type":"app_id"}' ` + `--data ${shellQuote(JSON.stringify({ id_list: [appId] }))} ` + `--as bot`;
826
975
  const { stdout, stderr } = await execAsync(cmd, { timeout: 30000 });
827
- logger.debug(`deleteGroupChatViaLarkCli(${chatId}) bot 退群 ok: ` + `stdout=${stdout?.slice(0, 300)} stderr=${stderr?.slice(0, 300)}`);
976
+ logger2.debug(`deleteGroupChatViaLarkCli(${chatId}) bot 退群 ok: ` + `stdout=${stdout?.slice(0, 300)} stderr=${stderr?.slice(0, 300)}`);
828
977
  } catch (err) {
829
- logger.warn(`deleteGroupChatViaLarkCli(${chatId}) bot 退群失败(task.context 仍会清掉,` + `飞书侧群会保留):${err.message}`);
978
+ logger2.warn(`deleteGroupChatViaLarkCli(${chatId}) bot 退群失败(task.context 仍会清掉,` + `飞书侧群会保留):${err.message}`);
830
979
  }
831
980
  }
832
981
  function shellQuote(s) {
@@ -1089,7 +1238,7 @@ init_logger();
1089
1238
  // src/env/error-reply.ts
1090
1239
  init_logger();
1091
1240
  import { spawn as spawn2 } from "node:child_process";
1092
- var logger2 = createLogger("env:error-reply");
1241
+ var logger3 = createLogger("env:error-reply");
1093
1242
  var UPSTREAM_RETRY_PATTERNS = [
1094
1243
  /failed after \d+ attempts/i,
1095
1244
  /endpoint is unavailable/i,
@@ -1447,7 +1596,7 @@ function spawnLarkReply(options) {
1447
1596
  async function notifyReactFailure(options) {
1448
1597
  const info = classifyReactFailure(options.error);
1449
1598
  if (!info.notify) {
1450
- logger2.debug(`[#4418] 命中规则 ${info.ruleId}(非失败),不发失败说明` + (options.sessionId ? ` (session=${options.sessionId})` : ""));
1599
+ logger3.debug(`[#4418] 命中规则 ${info.ruleId}(非失败),不发失败说明` + (options.sessionId ? ` (session=${options.sessionId})` : ""));
1451
1600
  return { sent: false, kind: info.kind, info, skipped: "not_a_failure" };
1452
1601
  }
1453
1602
  const channel = (isUsableChannel(options.replyChannel) ? options.replyChannel : undefined) ?? extractReplyChannelFromEvent(options.envEvent);
@@ -1455,14 +1604,14 @@ async function notifyReactFailure(options) {
1455
1604
  const hasTrigger = Boolean(options.envEvent);
1456
1605
  const noChannelMsg = `[#4418] React 中断(${info.kind}/${info.ruleId})无法定位 replyChannel,` + `飞书端收不到失败说明` + (hasTrigger ? " —— triggerEvent 存在但缺少 metadata.replyChannel" : "(本地执行,无 triggerEvent)") + (options.sessionId ? ` (session=${options.sessionId})` : "");
1457
1606
  if (hasTrigger)
1458
- logger2.warn(noChannelMsg);
1607
+ logger3.warn(noChannelMsg);
1459
1608
  else
1460
- logger2.debug(noChannelMsg);
1609
+ logger3.debug(noChannelMsg);
1461
1610
  return { sent: false, kind: info.kind, info, skipped: "no_channel" };
1462
1611
  }
1463
1612
  const dedupKey = makeDedupKey(channel, info, options.dedupKey);
1464
1613
  if (isDuplicate(dedupKey)) {
1465
- logger2.info(`[#4418] React 中断(${info.kind})已回复过 ${dedupKey},跳过`);
1614
+ logger3.info(`[#4418] React 中断(${info.kind})已回复过 ${dedupKey},跳过`);
1466
1615
  return { sent: false, kind: info.kind, info, skipped: "duplicate" };
1467
1616
  }
1468
1617
  rememberTrigger(dedupKey);
@@ -1475,19 +1624,18 @@ async function notifyReactFailure(options) {
1475
1624
  profile: channel.profile,
1476
1625
  timeoutMs: options.replyTimeoutMs
1477
1626
  });
1478
- logger2.info(`[#4418] React 中断(${info.kind}/${info.ruleId})已回飞书 ` + `(${channel.messageId ?? channel.chatId})`);
1627
+ logger3.info(`[#4418] React 中断(${info.kind}/${info.ruleId})已回飞书 ` + `(${channel.messageId ?? channel.chatId})`);
1479
1628
  return { sent: true, kind: info.kind, info };
1480
1629
  } catch (err) {
1481
1630
  const errorMsg = err instanceof Error ? err.message : String(err);
1482
1631
  repliedTriggers.delete(dedupKey);
1483
- logger2.warn(`[#4418] React 中断(${info.kind}/${info.ruleId})回飞书失败(已忽略): ${errorMsg}`);
1632
+ logger3.warn(`[#4418] React 中断(${info.kind}/${info.ruleId})回飞书失败(已忽略): ${errorMsg}`);
1484
1633
  return { sent: false, kind: info.kind, info, error: errorMsg };
1485
1634
  }
1486
1635
  }
1487
-
1488
1636
  // src/env/event-source/event-source-handlers.ts
1489
1637
  var execAsync2 = promisify2(execSync);
1490
- var logger3 = createLogger("lark-cli:event-source");
1638
+ var logger4 = createLogger("lark-cli:event-source");
1491
1639
  var CHILD_READY_TIMEOUT_MS = 5000;
1492
1640
  var GRACEFUL_STOP_TIMEOUT_MS = 5000;
1493
1641
  var CARD_ACTION_EVENT_TYPE = "card.action.trigger";
@@ -1716,8 +1864,8 @@ class LarkCliInstance {
1716
1864
  cardActionPorts;
1717
1865
  setCardActionPorts(ports) {
1718
1866
  this.cardActionPorts = ports;
1719
- if (typeof logger3 !== "undefined" && logger3?.debug) {
1720
- logger3.debug(`[LarkCliInstance] CardActionPorts injected: ` + `getTask=${typeof ports.getTask}, updateTaskContext=${typeof ports.updateTaskContext}, ` + `createGroupChat=${typeof ports.createGroupChat}, deleteGroupChat=${typeof ports.deleteGroupChat}, ` + `notifier=${typeof ports.notifier}`);
1867
+ if (typeof logger4 !== "undefined" && logger4?.debug) {
1868
+ logger4.debug(`[LarkCliInstance] CardActionPorts injected: ` + `getTask=${typeof ports.getTask}, updateTaskContext=${typeof ports.updateTaskContext}, ` + `createGroupChat=${typeof ports.createGroupChat}, deleteGroupChat=${typeof ports.deleteGroupChat}, ` + `notifier=${typeof ports.notifier}`);
1721
1869
  }
1722
1870
  }
1723
1871
  hasCardActionPorts() {
@@ -1744,7 +1892,7 @@ class LarkCliInstance {
1744
1892
  if (this.status === "running")
1745
1893
  return;
1746
1894
  if (this.starting) {
1747
- logger3.warn(`[LarkCliInstance] start() 已在执行中,忽略重复调用`);
1895
+ logger4.warn(`[LarkCliInstance] start() 已在执行中,忽略重复调用`);
1748
1896
  return;
1749
1897
  }
1750
1898
  this.starting = true;
@@ -1774,9 +1922,9 @@ class LarkCliInstance {
1774
1922
  if (!consumesCardAction)
1775
1923
  return;
1776
1924
  if (this.config.eventTypes?.length && !matchEventType(CARD_ACTION_EVENT_TYPE, this.config.eventTypes)) {
1777
- logger3.warn(`[LarkCliInstance] eventKeys 含 ${CARD_ACTION_EVENT_TYPE},但 eventTypes=` + `${JSON.stringify(this.config.eventTypes)} 不含它 → 卡片点击会被**静默丢弃**。` + `请把 ${CARD_ACTION_EVENT_TYPE} 加进 eventTypes,或清空 eventTypes。`);
1925
+ logger4.warn(`[LarkCliInstance] eventKeys 含 ${CARD_ACTION_EVENT_TYPE},但 eventTypes=` + `${JSON.stringify(this.config.eventTypes)} 不含它 → 卡片点击会被**静默丢弃**。` + `请把 ${CARD_ACTION_EVENT_TYPE} 加进 eventTypes,或清空 eventTypes。`);
1778
1926
  }
1779
- logger3.info(`[LarkCliInstance] 已监听 ${CARD_ACTION_EVENT_TYPE}。` + `⚠️ 若点击卡片无反应,先确认飞书开发者后台「事件与回调 → 回调配置」已开启该事件。`);
1927
+ logger4.info(`[LarkCliInstance] 已监听 ${CARD_ACTION_EVENT_TYPE}。` + `⚠️ 若点击卡片无反应,先确认飞书开发者后台「事件与回调 → 回调配置」已开启该事件。`);
1780
1928
  }
1781
1929
  spawnConsumeChild(command) {
1782
1930
  return spawn3("exec " + command, [], {
@@ -1816,7 +1964,7 @@ class LarkCliInstance {
1816
1964
  const conflicts = keys.filter((k) => busy.has(k));
1817
1965
  if (conflicts.length > 0) {
1818
1966
  const profile = this.config.profile;
1819
- logger3.warn(`[LarkCliInstance] eventKey 已被其它 consumer 占用(lark-cli 一个 key 只允许一个 consumer):` + `${conflicts.join(", ")}。本 event-source 启动后可能 exit 2。` + `用 \`lark-cli${profile ? ` --profile ${profile}` : ""} event status\` 查看,必要时 \`event stop\`。`);
1967
+ logger4.warn(`[LarkCliInstance] eventKey 已被其它 consumer 占用(lark-cli 一个 key 只允许一个 consumer):` + `${conflicts.join(", ")}。本 event-source 启动后可能 exit 2。` + `用 \`lark-cli${profile ? ` --profile ${profile}` : ""} event status\` 查看,必要时 \`event stop\`。`);
1820
1968
  }
1821
1969
  }
1822
1970
  async probeBusyEventKeys() {
@@ -1867,16 +2015,16 @@ class LarkCliInstance {
1867
2015
  });
1868
2016
  const handleExit = (code, source) => {
1869
2017
  if (code !== 0 && code !== null) {
1870
- logger3.warn(`[LarkCliInstance] consume 子进程异常退出 code=${code} (${source}) cmd="${command}"`);
2018
+ logger4.warn(`[LarkCliInstance] consume 子进程异常退出 code=${code} (${source}) cmd="${command}"`);
1871
2019
  this.status = "error";
1872
2020
  } else {
1873
- logger3.info(`[LarkCliInstance] consume 子进程已退出 code=${code} (${source}) cmd="${command}"`);
2021
+ logger4.info(`[LarkCliInstance] consume 子进程已退出 code=${code} (${source}) cmd="${command}"`);
1874
2022
  }
1875
2023
  settle();
1876
2024
  queueMicrotask(() => {
1877
2025
  if (this.children.length > 0 && this.children.every((c) => !isChildAlive(c))) {
1878
2026
  if (this.status !== "error") {
1879
- logger3.warn(`[LarkCliInstance] 所有 consume 子进程都已退出,状态从 running 改为 stopped`);
2027
+ logger4.warn(`[LarkCliInstance] 所有 consume 子进程都已退出,状态从 running 改为 stopped`);
1880
2028
  this.status = "stopped";
1881
2029
  }
1882
2030
  }
@@ -1885,12 +2033,12 @@ class LarkCliInstance {
1885
2033
  child.on("exit", (code) => handleExit(code, "exit"));
1886
2034
  child.on("close", (code) => handleExit(code, "close"));
1887
2035
  child.on("error", (error) => {
1888
- logger3.error(`[LarkCliInstance] consume 子进程 error: ${error.message}`);
2036
+ logger4.error(`[LarkCliInstance] consume 子进程 error: ${error.message}`);
1889
2037
  this.status = "error";
1890
2038
  settle();
1891
2039
  });
1892
2040
  const timer = setTimeout(() => {
1893
- logger3.warn(`[LarkCliInstance] consume 子进程 ${CHILD_READY_TIMEOUT_MS}ms 内未见 ready marker: cmd="${command}"`);
2041
+ logger4.warn(`[LarkCliInstance] consume 子进程 ${CHILD_READY_TIMEOUT_MS}ms 内未见 ready marker: cmd="${command}"`);
1894
2042
  settle();
1895
2043
  }, CHILD_READY_TIMEOUT_MS);
1896
2044
  ready.then(() => clearTimeout(timer));
@@ -1913,7 +2061,7 @@ class LarkCliInstance {
1913
2061
  try {
1914
2062
  child.kill("SIGTERM");
1915
2063
  } catch (error) {
1916
- logger3.warn(`[LarkCliInstance] Error sending SIGTERM to ${child.pid}: ${error}`);
2064
+ logger4.warn(`[LarkCliInstance] Error sending SIGTERM to ${child.pid}: ${error}`);
1917
2065
  }
1918
2066
  }
1919
2067
  const allExited = Promise.all(children.map((child) => new Promise((resolve) => {
@@ -1968,12 +2116,12 @@ class LarkCliInstance {
1968
2116
  }
1969
2117
  wireCardActionPorts() {
1970
2118
  if (this.cardActionPorts) {
1971
- logger3.debug("[LarkCliInstance] cardActionPorts 已由外部注入,跳过默认 cross-wire");
2119
+ logger4.debug("[LarkCliInstance] cardActionPorts 已由外部注入,跳过默认 cross-wire");
1972
2120
  return;
1973
2121
  }
1974
2122
  const taskComponent = this.environment?.getComponent?.("task");
1975
2123
  if (!taskComponent?.getTask || !taskComponent?.updateTask) {
1976
- logger3.debug(`[LarkCliInstance] card.action.trigger 端口未注入:taskComponent 不可用` + `(getTask=${typeof taskComponent?.getTask}, updateTask=${typeof taskComponent?.updateTask})。` + `卡片按钮点击会被跳过。`);
2124
+ logger4.debug(`[LarkCliInstance] card.action.trigger 端口未注入:taskComponent 不可用` + `(getTask=${typeof taskComponent?.getTask}, updateTask=${typeof taskComponent?.updateTask})。` + `卡片按钮点击会被跳过。`);
1977
2125
  return;
1978
2126
  }
1979
2127
  const sharedNotifier = this.pluginInstances.get("LarkCliTaskNotifyPlugin")?.cardNotifier ?? this.pluginInstances.get("PerTaskGroupChatPlugin")?.cardNotifier;
@@ -2002,7 +2150,7 @@ class LarkCliInstance {
2002
2150
  deleteGroupChat: (chatId, profile) => deleteGroupChatViaLarkCli(chatId, profile),
2003
2151
  notifier: sharedNotifier ?? new LarkCardPatchNotifier
2004
2152
  });
2005
- logger3.info(`[LarkCliInstance] card.action.trigger 端口已注入` + `(notifier ${sharedNotifier ? "复用插件共享实例" : "新建实例"})`);
2153
+ logger4.info(`[LarkCliInstance] card.action.trigger 端口已注入` + `(notifier ${sharedNotifier ? "复用插件共享实例" : "新建实例"})`);
2006
2154
  }
2007
2155
  getPluginHookPoints(plugin) {
2008
2156
  if (Array.isArray(plugin.hooks)) {
@@ -2200,7 +2348,7 @@ class LarkCliInstance {
2200
2348
  }
2201
2349
  return null;
2202
2350
  } catch (err) {
2203
- logger3.warn(`[LarkCliInstance] resolveChatTaskBinding failed for chatId=${chatId}: ${err}. ` + `群消息将不会注入 parentTaskId。`);
2351
+ logger4.warn(`[LarkCliInstance] resolveChatTaskBinding failed for chatId=${chatId}: ${err}. ` + `群消息将不会注入 parentTaskId。`);
2204
2352
  return null;
2205
2353
  }
2206
2354
  }
@@ -2222,7 +2370,7 @@ class LarkCliInstance {
2222
2370
  processStreamWith(data, buffer, opts = {}) {
2223
2371
  buffer.value += data;
2224
2372
  if (buffer.value.length > 2 * 1024 * 1024) {
2225
- logger3.warn(`[LarkCliInstance] stream 行缓冲超过 2MB 仍无换行,丢弃(疑似非 NDJSON 输出)`);
2373
+ logger4.warn(`[LarkCliInstance] stream 行缓冲超过 2MB 仍无换行,丢弃(疑似非 NDJSON 输出)`);
2226
2374
  buffer.value = "";
2227
2375
  return;
2228
2376
  }
@@ -2258,12 +2406,12 @@ class LarkCliInstance {
2258
2406
  const now = Date.now();
2259
2407
  const lastShared = LarkCliInstance.SHARED_SEEN.get(dedupKey);
2260
2408
  if (lastShared !== undefined && now - lastShared < LarkCliInstance.SHARED_MSG_TTL_MS) {
2261
- logger3.warn(`[LarkCliInstance] duplicate lark-cli event suppressed across instances (event_id=${dedupKey}, ` + `lastSeen=${now - lastShared}ms ago). ` + `Task #4137: SHARED_SEEN 跨实例去重。`);
2409
+ logger4.warn(`[LarkCliInstance] duplicate lark-cli event suppressed across instances (event_id=${dedupKey}, ` + `lastSeen=${now - lastShared}ms ago). ` + `Task #4137: SHARED_SEEN 跨实例去重。`);
2262
2410
  return;
2263
2411
  }
2264
2412
  const last = this.recentEventIds.get(dedupKey);
2265
2413
  if (last !== undefined && now - last < this.DEDUP_WINDOW_MS) {
2266
- logger3.warn(`[LarkCliInstance] duplicate lark-cli event suppressed (event_id=${dedupKey}, ` + `lastSeen=${now - last}ms ago). ` + `Task #3977/3978: 防止同一飞书事件触发两次任务创建。`);
2414
+ logger4.warn(`[LarkCliInstance] duplicate lark-cli event suppressed (event_id=${dedupKey}, ` + `lastSeen=${now - last}ms ago). ` + `Task #3977/3978: 防止同一飞书事件触发两次任务创建。`);
2267
2415
  return;
2268
2416
  }
2269
2417
  LarkCliInstance.SHARED_SEEN.set(dedupKey, now);
@@ -2443,11 +2591,11 @@ class LarkCliInstance {
2443
2591
  const chatId = event.chat_id || "";
2444
2592
  const operatorId = event.operator_id?.open_id ?? event.operator_id ?? undefined;
2445
2593
  if (!token || !messageId || !chatId) {
2446
- logger3.warn(`[LarkCliInstance] handleCardActionEvent: missing token/messageId/chatId, skip`);
2594
+ logger4.warn(`[LarkCliInstance] handleCardActionEvent: missing token/messageId/chatId, skip`);
2447
2595
  return;
2448
2596
  }
2449
2597
  if (!this.cardActionPorts) {
2450
- logger3.warn(`[LarkCliInstance] handleCardActionEvent: cardActionPorts 未注入,` + `card.action.trigger 事件被跳过。` + `调 instance.setCardActionPorts({getTask, updateTaskContext, createGroupChat, deleteGroupChat, notifier}) 注入。`);
2598
+ logger4.warn(`[LarkCliInstance] handleCardActionEvent: cardActionPorts 未注入,` + `card.action.trigger 事件被跳过。` + `调 instance.setCardActionPorts({getTask, updateTaskContext, createGroupChat, deleteGroupChat, notifier}) 注入。`);
2451
2599
  return;
2452
2600
  }
2453
2601
  const result = await handleCardAction({
@@ -2462,10 +2610,10 @@ class LarkCliInstance {
2462
2610
  const patch = this.cardActionPorts.patchByToken ?? patchCardByLarkCli;
2463
2611
  await patch(token, result.cardUpdate, profile);
2464
2612
  } else {
2465
- logger3.warn(`[LarkCliInstance] handleCardActionEvent failed: ${result.error ?? "unknown"}`);
2613
+ logger4.warn(`[LarkCliInstance] handleCardActionEvent failed: ${result.error ?? "unknown"}`);
2466
2614
  }
2467
2615
  } catch (err) {
2468
- logger3.error(`[LarkCliInstance] handleCardActionEvent error: ${err.message}`);
2616
+ logger4.error(`[LarkCliInstance] handleCardActionEvent error: ${err.message}`);
2469
2617
  }
2470
2618
  }
2471
2619
  async patchCardByToken(token, card, profile) {
@@ -2600,7 +2748,7 @@ var NOTIFY_TERMINAL_TYPES = new Set([
2600
2748
  "task.background.timeout",
2601
2749
  "task.background.stopped"
2602
2750
  ]);
2603
- function describeNotifyEvent(type, taskId, desc) {
2751
+ function describeNotifyEvent2(type, taskId, desc) {
2604
2752
  const actionable = NOTIFY_TERMINAL_TYPES.has(type);
2605
2753
  switch (type) {
2606
2754
  case "task.background.completed":
@@ -2621,6 +2769,24 @@ function describeNotifyEvent(type, taskId, desc) {
2621
2769
  return { headline: `Sub-agent 更新了 Task #${taskId}「${desc}」。`, actionable };
2622
2770
  }
2623
2771
  }
2772
+ function renderRuleNoticeSection(ruleNotice, headline) {
2773
+ if (!ruleNotice || !ruleNotice.attempted) {
2774
+ return `(本事件不直发规则回执)
2775
+ ` + `→ 你的回复要把结果讲**完整**(用户只能从你这条消息知道结论)。`;
2776
+ }
2777
+ if (ruleNotice.delivered) {
2778
+ const when = ruleNotice.sentAt ? new Date(ruleNotice.sentAt).toLocaleTimeString("zh-CN", {
2779
+ hour12: false,
2780
+ hour: "2-digit",
2781
+ minute: "2-digit"
2782
+ }) : "";
2783
+ const sent = ruleNotice.text ? `:「${ruleNotice.text.replace(/\s*\n+\s*/g, " ")}」` : "";
2784
+ return `✅ 系统已于 ${when || "刚才"} 把下面这条发到群里${sent}
2785
+ ` + `→ 你的回复**只发增量**:不要再重复「任务已结束」这类回执原文,` + `直接讲结论/交付 + 下一步选项。`;
2786
+ }
2787
+ return `❌ **回执未送达**(原因:${ruleNotice.error ?? "unknown"})
2788
+ ` + `→ 用户目前**还不知道**「${headline}」这件事,必须由你在回复里讲清楚,` + `并且不要假装系统已经通知过。`;
2789
+ }
2624
2790
  var larkCliHandler = {
2625
2791
  type: "lark-cli",
2626
2792
  validateConfig(config) {
@@ -2632,7 +2798,7 @@ var larkCliHandler = {
2632
2798
  },
2633
2799
  async emitTriggerEvent(payload, store) {
2634
2800
  const eventId = await store.insertTriggerEvent(payload, "lark-cli");
2635
- logger3.info(`[larkCliHandler] emitTriggerEvent: id=${eventId}`, {
2801
+ logger4.info(`[larkCliHandler] emitTriggerEvent: id=${eventId}`, {
2636
2802
  chatId: payload.metadata?.chatId,
2637
2803
  senderId: payload.senderId
2638
2804
  });
@@ -2647,7 +2813,7 @@ var larkCliHandler = {
2647
2813
  try {
2648
2814
  const result = await runner.run(command);
2649
2815
  if (result.code !== 0) {
2650
- logger3.error(`[larkCliHandler] replyMessage non-zero exit`, {
2816
+ logger4.error(`[larkCliHandler] replyMessage non-zero exit`, {
2651
2817
  code: result.code,
2652
2818
  stderr: result.stderr
2653
2819
  });
@@ -2661,7 +2827,7 @@ var larkCliHandler = {
2661
2827
  return { success: true, messageId: replyMessageId };
2662
2828
  } catch (err) {
2663
2829
  const errMsg = err instanceof Error ? err.message : String(err);
2664
- logger3.error(`[larkCliHandler] replyMessage spawn error`, { error: errMsg });
2830
+ logger4.error(`[larkCliHandler] replyMessage spawn error`, { error: errMsg });
2665
2831
  return { success: false, error: errMsg };
2666
2832
  }
2667
2833
  },
@@ -2683,47 +2849,67 @@ var larkCliHandler = {
2683
2849
  senderOpenId: input.triggerEvent.metadata?.senderId ?? input.triggerEvent.senderId,
2684
2850
  profile: input.profile
2685
2851
  };
2686
- const profileFlag = ctx.profile ? `--profile ${ctx.profile} ` : "";
2852
+ const esType = input.channel?.esType ?? ctx.esType ?? "lark-cli";
2853
+ const chatId = input.channel?.chatId || ctx.chatId;
2854
+ const messageId = input.channel?.messageId || ctx.messageId;
2855
+ const senderId = input.channel?.senderId || ctx.senderOpenId;
2856
+ const chatType = input.channel?.chatType ?? "unknown";
2857
+ const profile = input.channel?.profile ?? ctx.profile;
2858
+ const profileFlag = profile ? `--profile ${profile} ` : "";
2687
2859
  const desc = input.notifyEvent.description ?? "(未命名任务)";
2688
2860
  const result = input.subAgentResult.summary ?? input.notifyEvent.result ?? "";
2689
2861
  const notifyType = input.notifyEvent.type;
2690
2862
  const taskId = input.notifyEvent.taskId ?? "?";
2691
- const { headline, actionable } = describeNotifyEvent(notifyType, taskId, desc);
2863
+ const { headline, actionable } = describeNotifyEvent2(notifyType, taskId, desc);
2864
+ const chatTypeLabel = chatType === "group" ? "群聊" : chatType === "p2p" ? "私聊" : "会话类型未知";
2865
+ const canReply = Boolean(chatId);
2866
+ const receiptSection = renderRuleNoticeSection(input.ruleNotice, headline);
2867
+ const replyCommand = messageId ? `lark-cli ${profileFlag}im +messages-reply --message-id ${messageId} --chat-id ${chatId} --as bot --markdown '<你的回复>'` : `lark-cli ${profileFlag}im +messages-send --chat-id ${chatId} --as bot --markdown '<你的回复>'`;
2868
+ const scopeWord = chatType === "group" ? "群聊" : chatType === "p2p" ? "私聊" : "会话";
2692
2869
  const promptText = actionable ? `
2693
2870
  ## Notify Event: ${notifyType}
2694
2871
 
2695
2872
  ${headline}
2696
2873
 
2697
- ### Trigger event(原始飞书消息,来自 EventStore 反查)
2698
- - ES: lark-cli
2699
- - **chatId: ${ctx.chatId}** ← 关键!必须回复到这里
2700
- - **messageId: ${ctx.messageId}** ← 必须 reply 这条
2701
- - sender: ${ctx.senderOpenId}
2702
- ${ctx.profile ? `- profile: ${ctx.profile} ← 调用 lark-cli 必须带 --profile
2874
+ ### 触发渠道(EventSource)
2875
+ - ES: ${esType}(飞书,${chatTypeLabel})
2876
+ - **chatId: ${chatId || "(缺失)"}** ← 关键!必须发到这里
2877
+ - **messageId: ${messageId || "(缺失)"}** ← ${messageId ? "reply 这条,保持话题线索" : "无触发消息,用 +messages-send"}
2878
+ - sender: ${senderId || "(未知)"}
2879
+ ${input.notifyEvent.subSessionId ? `- 子 session: ${input.notifyEvent.subSessionId} ← 如需续跑:delegate_task(existingSubSessionId=<此值>, prompt=<新要求>)
2880
+ ` : ""}${profile ? `- profile: ${profile} ← 调用 lark-cli 必须带 --profile
2703
2881
  ` : ""}
2882
+ ### 系统回执(rule-based 直发)
2883
+ ${receiptSection}
2884
+
2704
2885
  ### Sub-agent 输出
2705
2886
  ${result}
2706
2887
 
2707
- ### \uD83D\uDC49 你应该这样做
2708
- 用 lark-cli 调 im +messages-reply:
2709
- lark-cli ${profileFlag}im +messages-reply --message-id ${ctx.messageId} --chat-id ${ctx.chatId} --as bot --msg-type text --content '<你的回复>'
2888
+ ### \uD83D\uDC49 你要做什么
2889
+ 1. 用 2~5 行总结:这次完成了什么 / 卡在哪(依据上面的输出与子 session)
2890
+ 2. 给出 1~3 个下一步选项(继续推进 / 拆小 / 放弃),并**问用户选哪个**
2891
+ 3. 用 lark-cli 把回复发到上面的${scopeWord}(见下)
2892
+
2893
+ ### 发送方式(渠道 = lark-cli)
2894
+ ${canReply ? ` ${replyCommand}` : `⚠️ 没有可用的 chatId —— 无法投递到触发会话。请在会话内汇报,并说明「未投递」的原因。`}
2710
2895
 
2711
2896
  ⚠️ 不要 fallback 到 lastReplyChannel 或 metadata.replyChannel — 那个 chatId
2712
2897
  可能跟用户原始消息的 chatId 不一致(参见 #4035/#4038/#4039 bug)。
2898
+ ⚠️ 必须 --as bot(否则会被自己的 lark-cli consumer 当用户消息回灌);不要用 user 身份。
2713
2899
  ` : `
2714
2900
  ## Notify Event: ${notifyType}
2715
2901
 
2716
2902
  ${headline}
2717
2903
 
2718
- ### Trigger event
2719
- - ES: lark-cli
2720
- - chatId: ${ctx.chatId}
2721
- - messageId: ${ctx.messageId}
2904
+ ### 触发渠道(EventSource)
2905
+ - ES: ${esType}(${chatTypeLabel})
2906
+ - chatId: ${chatId || "(缺失)"}
2907
+ - messageId: ${messageId || "(缺失)"}
2722
2908
 
2723
2909
  (这是中间态通知:仅作状态同步,**不要**回复用户,也不要调用 lark-cli 发消息。
2724
2910
  等收到 task.background.completed / failed / timeout / stopped 终态通知后再回复。)
2725
2911
  `;
2726
- const systemHint = actionable ? `回复必须用 lark-cli im +messages-reply(${profileFlag.trim() ? `带 ${profileFlag.trim()};` : ""}` + `chatId=${ctx.chatId} / messageId=${ctx.messageId} 来自 trigger event,不要 fallback。` : `这是 ${notifyType} 中间态通知,不要回复用户;仅等待终态通知。`;
2912
+ const systemHint = actionable ? `回复必须用 lark-cli im +messages-reply(${profileFlag.trim() ? `带 ${profileFlag.trim()};` : ""}` + `chatId=${chatId} / messageId=${messageId} 来自 trigger event(esType=${esType}),不要 fallback。` + (input.ruleNotice?.delivered ? "系统回执已送达,只发增量。" : "") : `这是 ${notifyType} 中间态通知,不要回复用户;仅等待终态通知。`;
2727
2913
  return { promptText, systemHint };
2728
2914
  },
2729
2915
  setRunner(runner) {
@@ -2748,16 +2934,17 @@ async function patchCardByLarkCli(token, card, profile) {
2748
2934
  const cmd = `lark-cli ${profileFlag}api POST /open-apis/interactive/v1/card/update ` + `--data '${JSON.stringify({ token, card }).replace(/'/g, "'\\''")}' --as bot`;
2749
2935
  try {
2750
2936
  const { stdout } = await execAsync2(cmd, { timeout: 30000 });
2751
- logger3.debug(`patchCardByLarkCli ok: ${stdout?.slice(0, 200)}`);
2937
+ logger4.debug(`patchCardByLarkCli ok: ${stdout?.slice(0, 200)}`);
2752
2938
  } catch (err) {
2753
- logger3.error(`patchCardByLarkCli failed: ${err.message}`);
2939
+ logger4.error(`patchCardByLarkCli failed: ${err.message}`);
2754
2940
  }
2755
2941
  }
2756
2942
  var builtInHandlers = [
2757
2943
  larkCliHandler,
2758
2944
  timerHandler,
2759
2945
  bountyIMHandler,
2760
- bountyCliHandler
2946
+ bountyCliHandler,
2947
+ cliCommandHandler
2761
2948
  ];
2762
2949
  function getBuiltInHandler(type) {
2763
2950
  return builtInHandlers.find((h) => h.type === type);
@@ -2787,7 +2974,7 @@ var EVENT_SOURCE_CONFIG_REGISTRATION = {
2787
2974
  };
2788
2975
 
2789
2976
  // src/env/event-source/event-source-component.ts
2790
- var logger4 = createLogger("event-source");
2977
+ var logger5 = createLogger("event-source");
2791
2978
 
2792
2979
  class EventSourceComponent extends BaseComponent {
2793
2980
  name = "event-source";
@@ -2854,25 +3041,25 @@ class EventSourceComponent extends BaseComponent {
2854
3041
  for (const handler of builtInHandlers) {
2855
3042
  if (!this.handlers.has(handler.type)) {
2856
3043
  this.handlers.set(handler.type, handler);
2857
- logger4.debug(`Registered built-in handler: ${handler.type}`);
3044
+ logger5.debug(`Registered built-in handler: ${handler.type}`);
2858
3045
  }
2859
3046
  }
2860
3047
  }
2861
3048
  async executeInitHooks() {
2862
- const { EventSourceInitHooks } = await import("./roy-agent-core-x6c45yqd.js");
3049
+ const { EventSourceInitHooks } = await import("./roy-agent-core-99nwgj84.js");
2863
3050
  await EventSourceInitHooks.execute(this);
2864
3051
  }
2865
3052
  registerHandler(handler) {
2866
3053
  if (this.handlers.has(handler.type)) {
2867
- logger4.warn(`Handler already registered for type: ${handler.type}, overwriting`);
3054
+ logger5.warn(`Handler already registered for type: ${handler.type}, overwriting`);
2868
3055
  }
2869
3056
  this.handlers.set(handler.type, handler);
2870
- logger4.debug(`Handler registered: ${handler.type}`);
3057
+ logger5.debug(`Handler registered: ${handler.type}`);
2871
3058
  }
2872
3059
  unregisterHandler(type) {
2873
3060
  const deleted = this.handlers.delete(type);
2874
3061
  if (deleted) {
2875
- logger4.debug(`Handler unregistered: ${type}`);
3062
+ logger5.debug(`Handler unregistered: ${type}`);
2876
3063
  }
2877
3064
  return deleted;
2878
3065
  }
@@ -2962,7 +3149,7 @@ class EventSourceComponent extends BaseComponent {
2962
3149
  });
2963
3150
  }
2964
3151
  onConfigChange(event) {
2965
- logger4.info(`EventSource config changed: ${event.key}`, {
3152
+ logger5.info(`EventSource config changed: ${event.key}`, {
2966
3153
  oldValue: event.oldValue,
2967
3154
  newValue: event.newValue
2968
3155
  });
@@ -2981,9 +3168,9 @@ class EventSourceComponent extends BaseComponent {
2981
3168
  }
2982
3169
  this.sources.set(config.id, config);
2983
3170
  this.statuses.set(config.id, "created");
2984
- logger4.debug(`EventSource registered: ${config.id} (${config.type})`);
3171
+ logger5.debug(`EventSource registered: ${config.id} (${config.type})`);
2985
3172
  this.saveConfig().catch((err) => {
2986
- logger4.error(`Failed to save config after registering ${config.id}:`, err);
3173
+ logger5.error(`Failed to save config after registering ${config.id}:`, err);
2987
3174
  });
2988
3175
  }
2989
3176
  unregister(id) {
@@ -2998,9 +3185,9 @@ class EventSourceComponent extends BaseComponent {
2998
3185
  this.eventHandlers.delete(id);
2999
3186
  this.buffers.delete(id);
3000
3187
  if (existed) {
3001
- logger4.debug(`EventSource unregistered: ${id}`);
3188
+ logger5.debug(`EventSource unregistered: ${id}`);
3002
3189
  this.saveConfig().catch((err) => {
3003
- logger4.error(`Failed to save config after unregistering ${id}:`, err);
3190
+ logger5.error(`Failed to save config after unregistering ${id}:`, err);
3004
3191
  });
3005
3192
  }
3006
3193
  return existed;
@@ -3038,13 +3225,13 @@ class EventSourceComponent extends BaseComponent {
3038
3225
  }
3039
3226
  }
3040
3227
  this.sources.set(id, updated);
3041
- logger4.info(`EventSource updated: ${id}`, {
3228
+ logger5.info(`EventSource updated: ${id}`, {
3042
3229
  fields: Object.keys(partial)
3043
3230
  });
3044
3231
  try {
3045
3232
  await this.saveConfig();
3046
3233
  } catch (err) {
3047
- logger4.error(`Failed to save config after updating ${id}:`, err);
3234
+ logger5.error(`Failed to save config after updating ${id}:`, err);
3048
3235
  throw err;
3049
3236
  }
3050
3237
  return {
@@ -3113,18 +3300,18 @@ class EventSourceComponent extends BaseComponent {
3113
3300
  type: "event-source.started",
3114
3301
  payload: { sourceId: id, sourceType: config.type }
3115
3302
  });
3116
- logger4.info(`EventSource started: ${id} (${config.type})`);
3303
+ logger5.info(`EventSource started: ${id} (${config.type})`);
3117
3304
  } catch (error) {
3118
3305
  this.statuses.set(id, "error");
3119
- logger4.error(`EventSource failed to start: ${id}`, error);
3306
+ logger5.error(`EventSource failed to start: ${id}`, error);
3120
3307
  throw error;
3121
3308
  }
3122
3309
  }
3123
3310
  async stopSource(id) {
3124
3311
  const status = this.statuses.get(id);
3125
- logger4.info(`[EventSource ${id}] stopSource called, current status: ${status}`);
3312
+ logger5.info(`[EventSource ${id}] stopSource called, current status: ${status}`);
3126
3313
  if (status === "stopped" || status === "created") {
3127
- logger4.info(`[EventSource ${id}] already stopped/created, skipping`);
3314
+ logger5.info(`[EventSource ${id}] already stopped/created, skipping`);
3128
3315
  return;
3129
3316
  }
3130
3317
  this.statuses.set(id, "stopping");
@@ -3140,10 +3327,10 @@ class EventSourceComponent extends BaseComponent {
3140
3327
  type: "event-source.stopped",
3141
3328
  payload: { sourceId: id, sourceType: config?.type }
3142
3329
  });
3143
- logger4.info(`EventSource stopped: ${id}`);
3330
+ logger5.info(`EventSource stopped: ${id}`);
3144
3331
  } catch (error) {
3145
3332
  this.statuses.set(id, "error");
3146
- logger4.error(`EventSource failed to stop: ${id}`, error);
3333
+ logger5.error(`EventSource failed to stop: ${id}`, error);
3147
3334
  throw error;
3148
3335
  }
3149
3336
  }
@@ -3168,9 +3355,9 @@ class EventSourceComponent extends BaseComponent {
3168
3355
  sources: Array.from(this.sources.values())
3169
3356
  };
3170
3357
  writeFileSync(configPath, JSON.stringify(config, null, 2), "utf-8");
3171
- logger4.debug(`Saved ${this.sources.size} event source configurations`);
3358
+ logger5.debug(`Saved ${this.sources.size} event source configurations`);
3172
3359
  } catch (error) {
3173
- logger4.error("Failed to save event source configurations:", error);
3360
+ logger5.error("Failed to save event source configurations:", error);
3174
3361
  throw error;
3175
3362
  }
3176
3363
  }
@@ -3180,13 +3367,13 @@ class EventSourceComponent extends BaseComponent {
3180
3367
  try {
3181
3368
  const configPath = this.getConfigFilePath();
3182
3369
  if (!existsSync(configPath)) {
3183
- logger4.debug(`No event source config file found at ${configPath}`);
3370
+ logger5.debug(`No event source config file found at ${configPath}`);
3184
3371
  return;
3185
3372
  }
3186
3373
  const content = readFileSync(configPath, "utf-8");
3187
3374
  const config = JSON.parse(content);
3188
3375
  if (!config.sources || !Array.isArray(config.sources)) {
3189
- logger4.warn("Invalid event source config format, skipping load");
3376
+ logger5.warn("Invalid event source config format, skipping load");
3190
3377
  return;
3191
3378
  }
3192
3379
  let loadedCount = 0;
@@ -3197,9 +3384,9 @@ class EventSourceComponent extends BaseComponent {
3197
3384
  loadedCount++;
3198
3385
  }
3199
3386
  }
3200
- logger4.info(`Loaded ${loadedCount} event source configurations`);
3387
+ logger5.info(`Loaded ${loadedCount} event source configurations`);
3201
3388
  } catch (error) {
3202
- logger4.error("Failed to load event source configurations:", error);
3389
+ logger5.error("Failed to load event source configurations:", error);
3203
3390
  }
3204
3391
  }
3205
3392
  }
@@ -3213,4 +3400,4 @@ __legacyDecorateClassTS([
3213
3400
  TracedAs("event_source.stop", { recordParams: true, recordResult: false })
3214
3401
  ], EventSourceComponent.prototype, "stopSource", null);
3215
3402
 
3216
- export { TimerInstance, timerHandler, buildDefaultBountyIMSystemPrompt, resolveBountyIMSystemPrompt, BountyIMInstance, bountyIMHandler, extractMetadata, larkCliHandler, builtInHandlers, getBuiltInHandler, EventSourceComponent };
3403
+ export { TimerInstance, timerHandler, buildDefaultBountyIMSystemPrompt, resolveBountyIMSystemPrompt, BountyIMInstance, bountyIMHandler, CLI_COMMAND_ES_TYPE, CLI_SESSION_CHAT_ID_PREFIX, buildCliReplyChannel, parseCliSessionChatId, cliCommandHandler, extractMetadata, larkCliHandler, builtInHandlers, getBuiltInHandler, EventSourceComponent };