botmux 2.95.0 → 2.96.1

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 (175) hide show
  1. package/README.en.md +4 -4
  2. package/README.md +3 -3
  3. package/dist/adapters/backend/tmux-backend.d.ts.map +1 -1
  4. package/dist/adapters/backend/tmux-backend.js +6 -10
  5. package/dist/adapters/backend/tmux-backend.js.map +1 -1
  6. package/dist/adapters/cli/kimi.d.ts +4 -0
  7. package/dist/adapters/cli/kimi.d.ts.map +1 -0
  8. package/dist/adapters/cli/kimi.js +54 -0
  9. package/dist/adapters/cli/kimi.js.map +1 -0
  10. package/dist/adapters/cli/registry.d.ts +2 -1
  11. package/dist/adapters/cli/registry.d.ts.map +1 -1
  12. package/dist/adapters/cli/registry.js +6 -20
  13. package/dist/adapters/cli/registry.js.map +1 -1
  14. package/dist/adapters/cli/types.d.ts +1 -1
  15. package/dist/adapters/cli/types.d.ts.map +1 -1
  16. package/dist/adapters/hook-installer.d.ts.map +1 -1
  17. package/dist/adapters/hook-installer.js +138 -28
  18. package/dist/adapters/hook-installer.js.map +1 -1
  19. package/dist/bot-registry.d.ts +61 -4
  20. package/dist/bot-registry.d.ts.map +1 -1
  21. package/dist/bot-registry.js +164 -3
  22. package/dist/bot-registry.js.map +1 -1
  23. package/dist/cli/stdin-encoding.d.ts +21 -0
  24. package/dist/cli/stdin-encoding.d.ts.map +1 -1
  25. package/dist/cli/stdin-encoding.js +37 -0
  26. package/dist/cli/stdin-encoding.js.map +1 -1
  27. package/dist/cli.d.ts.map +1 -1
  28. package/dist/cli.js +14 -4
  29. package/dist/cli.js.map +1 -1
  30. package/dist/config.d.ts +18 -0
  31. package/dist/config.d.ts.map +1 -1
  32. package/dist/config.js +27 -0
  33. package/dist/config.js.map +1 -1
  34. package/dist/core/ask-hook/opencode.d.ts +15 -17
  35. package/dist/core/ask-hook/opencode.d.ts.map +1 -1
  36. package/dist/core/ask-hook/opencode.js +17 -19
  37. package/dist/core/ask-hook/opencode.js.map +1 -1
  38. package/dist/core/command-handler.d.ts.map +1 -1
  39. package/dist/core/command-handler.js +1 -0
  40. package/dist/core/command-handler.js.map +1 -1
  41. package/dist/core/dashboard-ipc-server.d.ts.map +1 -1
  42. package/dist/core/dashboard-ipc-server.js +193 -5
  43. package/dist/core/dashboard-ipc-server.js.map +1 -1
  44. package/dist/core/dashboard-rows.d.ts +2 -0
  45. package/dist/core/dashboard-rows.d.ts.map +1 -1
  46. package/dist/core/dashboard-rows.js +2 -0
  47. package/dist/core/dashboard-rows.js.map +1 -1
  48. package/dist/core/trigger-session.d.ts.map +1 -1
  49. package/dist/core/trigger-session.js +99 -7
  50. package/dist/core/trigger-session.js.map +1 -1
  51. package/dist/core/types.d.ts +16 -0
  52. package/dist/core/types.d.ts.map +1 -1
  53. package/dist/core/types.js.map +1 -1
  54. package/dist/core/worker-pool.d.ts +1 -1
  55. package/dist/core/worker-pool.d.ts.map +1 -1
  56. package/dist/core/worker-pool.js +68 -11
  57. package/dist/core/worker-pool.js.map +1 -1
  58. package/dist/dashboard/bot-payload.d.ts +7 -0
  59. package/dist/dashboard/bot-payload.d.ts.map +1 -1
  60. package/dist/dashboard/bot-payload.js +7 -1
  61. package/dist/dashboard/bot-payload.js.map +1 -1
  62. package/dist/dashboard/session-cleanup.d.ts +1 -0
  63. package/dist/dashboard/session-cleanup.d.ts.map +1 -1
  64. package/dist/dashboard/session-cleanup.js +2 -0
  65. package/dist/dashboard/session-cleanup.js.map +1 -1
  66. package/dist/dashboard/settings-write-applier.d.ts +2 -1
  67. package/dist/dashboard/settings-write-applier.d.ts.map +1 -1
  68. package/dist/dashboard/settings-write-applier.js +6 -0
  69. package/dist/dashboard/settings-write-applier.js.map +1 -1
  70. package/dist/dashboard/trigger-api.d.ts +4 -0
  71. package/dist/dashboard/trigger-api.d.ts.map +1 -1
  72. package/dist/dashboard/trigger-api.js +20 -0
  73. package/dist/dashboard/trigger-api.js.map +1 -1
  74. package/dist/dashboard/web/bot-defaults.d.ts +1 -0
  75. package/dist/dashboard/web/bot-defaults.d.ts.map +1 -1
  76. package/dist/dashboard/web/bot-defaults.js +247 -4
  77. package/dist/dashboard/web/bot-defaults.js.map +1 -1
  78. package/dist/dashboard/web/connectors.d.ts +11 -0
  79. package/dist/dashboard/web/connectors.d.ts.map +1 -1
  80. package/dist/dashboard/web/connectors.js +45 -1
  81. package/dist/dashboard/web/connectors.js.map +1 -1
  82. package/dist/dashboard/web/groups.d.ts +7 -0
  83. package/dist/dashboard/web/groups.d.ts.map +1 -1
  84. package/dist/dashboard/web/groups.js +62 -15
  85. package/dist/dashboard/web/groups.js.map +1 -1
  86. package/dist/dashboard/web/i18n.d.ts.map +1 -1
  87. package/dist/dashboard/web/i18n.js +58 -2
  88. package/dist/dashboard/web/i18n.js.map +1 -1
  89. package/dist/dashboard/web/sessions.d.ts.map +1 -1
  90. package/dist/dashboard/web/sessions.js +149 -5
  91. package/dist/dashboard/web/sessions.js.map +1 -1
  92. package/dist/dashboard/web/settings.d.ts.map +1 -1
  93. package/dist/dashboard/web/settings.js +10 -0
  94. package/dist/dashboard/web/settings.js.map +1 -1
  95. package/dist/dashboard/webhook-routes.d.ts.map +1 -1
  96. package/dist/dashboard/webhook-routes.js +126 -6
  97. package/dist/dashboard/webhook-routes.js.map +1 -1
  98. package/dist/dashboard-web/app.js +827 -751
  99. package/dist/dashboard-web/style.css +47 -0
  100. package/dist/dashboard.js +85 -6
  101. package/dist/dashboard.js.map +1 -1
  102. package/dist/global-config.d.ts +4 -0
  103. package/dist/global-config.d.ts.map +1 -1
  104. package/dist/global-config.js +2 -0
  105. package/dist/global-config.js.map +1 -1
  106. package/dist/i18n/en.d.ts.map +1 -1
  107. package/dist/i18n/en.js +1 -0
  108. package/dist/i18n/en.js.map +1 -1
  109. package/dist/i18n/zh.d.ts.map +1 -1
  110. package/dist/i18n/zh.js +1 -0
  111. package/dist/i18n/zh.js.map +1 -1
  112. package/dist/im/lark/card-builder.d.ts.map +1 -1
  113. package/dist/im/lark/card-builder.js +1 -0
  114. package/dist/im/lark/card-builder.js.map +1 -1
  115. package/dist/im/lark/client.d.ts +12 -0
  116. package/dist/im/lark/client.d.ts.map +1 -1
  117. package/dist/im/lark/client.js +154 -9
  118. package/dist/im/lark/client.js.map +1 -1
  119. package/dist/im/lark/event-dispatcher.d.ts +13 -0
  120. package/dist/im/lark/event-dispatcher.d.ts.map +1 -1
  121. package/dist/im/lark/event-dispatcher.js +200 -16
  122. package/dist/im/lark/event-dispatcher.js.map +1 -1
  123. package/dist/im/lark/message-parser.d.ts +11 -0
  124. package/dist/im/lark/message-parser.d.ts.map +1 -1
  125. package/dist/im/lark/message-parser.js +2 -1
  126. package/dist/im/lark/message-parser.js.map +1 -1
  127. package/dist/im/lark/summary-command.d.ts +19 -0
  128. package/dist/im/lark/summary-command.d.ts.map +1 -0
  129. package/dist/im/lark/summary-command.js +276 -0
  130. package/dist/im/lark/summary-command.js.map +1 -0
  131. package/dist/mir-local-runtime.d.ts +40 -0
  132. package/dist/mir-local-runtime.d.ts.map +1 -1
  133. package/dist/mir-local-runtime.js +246 -52
  134. package/dist/mir-local-runtime.js.map +1 -1
  135. package/dist/mir-runner.js +26 -1
  136. package/dist/mir-runner.js.map +1 -1
  137. package/dist/services/card-prefs-store.d.ts +2 -2
  138. package/dist/services/card-prefs-store.d.ts.map +1 -1
  139. package/dist/services/card-prefs-store.js +5 -5
  140. package/dist/services/card-prefs-store.js.map +1 -1
  141. package/dist/services/chat-reply-mode-store.d.ts +6 -4
  142. package/dist/services/chat-reply-mode-store.d.ts.map +1 -1
  143. package/dist/services/chat-reply-mode-store.js +6 -4
  144. package/dist/services/chat-reply-mode-store.js.map +1 -1
  145. package/dist/services/pi-transcript.d.ts +19 -0
  146. package/dist/services/pi-transcript.d.ts.map +1 -0
  147. package/dist/services/pi-transcript.js +222 -0
  148. package/dist/services/pi-transcript.js.map +1 -0
  149. package/dist/services/seen-message-store.d.ts +12 -0
  150. package/dist/services/seen-message-store.d.ts.map +1 -0
  151. package/dist/services/seen-message-store.js +119 -0
  152. package/dist/services/seen-message-store.js.map +1 -0
  153. package/dist/services/summary-range-store.d.ts +21 -0
  154. package/dist/services/summary-range-store.d.ts.map +1 -0
  155. package/dist/services/summary-range-store.js +89 -0
  156. package/dist/services/summary-range-store.js.map +1 -0
  157. package/dist/services/trigger-types.d.ts +14 -2
  158. package/dist/services/trigger-types.d.ts.map +1 -1
  159. package/dist/services/trigger-types.js +15 -1
  160. package/dist/services/trigger-types.js.map +1 -1
  161. package/dist/setup/bot-config-editor.d.ts.map +1 -1
  162. package/dist/setup/bot-config-editor.js +2 -0
  163. package/dist/setup/bot-config-editor.js.map +1 -1
  164. package/dist/types.d.ts +20 -1
  165. package/dist/types.d.ts.map +1 -1
  166. package/dist/utils/executable.d.ts +3 -0
  167. package/dist/utils/executable.d.ts.map +1 -0
  168. package/dist/utils/executable.js +24 -0
  169. package/dist/utils/executable.js.map +1 -0
  170. package/dist/worker.js +75 -6
  171. package/dist/worker.js.map +1 -1
  172. package/dist/workflows/definition.d.ts +8 -8
  173. package/dist/workflows/events/payloads.d.ts +10 -10
  174. package/dist/workflows/events/schema.d.ts +28 -28
  175. package/package.json +1 -1
@@ -59,14 +59,16 @@ function regularGroupDefaultMode(larkAppId) {
59
59
  }
60
60
  /**
61
61
  * Per-bot (bot-global) @-requirement policy for regular groups, default 'always'.
62
- * • always — @ required everywhere (incl. inside shared topics).
63
- * • topic — @ required at top level, but non-@ continues inside shared topics.
64
- * • never — non-@ messages are answered too (where the bot has talk access).
62
+ * • always — @ required everywhere (incl. inside shared topics).
63
+ * • topic — @ required at top level, but non-@ continues inside shared topics.
64
+ * • never — non-@ messages are always answered (where the bot has talk access).
65
+ * • ambient — like never, but stays quiet when the message @mentions another
66
+ * specific member (person/bot) without @ing this bot (redirect).
65
67
  */
66
68
  export function resolveGroupMentionMode(larkAppId) {
67
69
  try {
68
70
  const m = getBot(larkAppId).config.regularGroupMentionMode;
69
- return m === 'topic' || m === 'never' ? m : 'always';
71
+ return m === 'topic' || m === 'never' || m === 'ambient' ? m : 'always';
70
72
  }
71
73
  catch {
72
74
  return 'always';
@@ -1 +1 @@
1
- {"version":3,"file":"chat-reply-mode-store.js","sourceRoot":"","sources":["../../src/services/chat-reply-mode-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,MAAM,EAAsB,MAAM,oBAAoB,CAAC;AAChE,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAI5C,MAAM,UAAU,sBAAsB,CAAC,GAAuB;IAC5D,MAAM,CAAC,GAAG,GAAG,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACpC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IAC3C,IAAI,CAAC,KAAK,MAAM;QAAE,OAAO,MAAM,CAAC;IAChC,IAAI,CAAC,KAAK,YAAY,IAAI,CAAC,KAAK,WAAW,IAAI,CAAC,KAAK,YAAY;QAAE,OAAO,YAAY,CAAC;IACvF,IAAI,CAAC,KAAK,WAAW,IAAI,CAAC,KAAK,UAAU,IAAI,CAAC,KAAK,QAAQ;QAAE,OAAO,WAAW,CAAC;IAChF,IAAI,CAAC,KAAK,OAAO,IAAI,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,OAAO,IAAI,CAAC,KAAK,OAAO,IAAI,CAAC,KAAK,aAAa,IAAI,CAAC,KAAK,aAAa;QAAE,OAAO,QAAQ,CAAC;IACrI,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,mEAAmE;AACnE,MAAM,UAAU,cAAc,CAAC,IAAmB;IAChD,IAAI,IAAI,KAAK,QAAQ;QAAE,OAAO,OAAO,CAAC;IACtC,IAAI,IAAI,KAAK,WAAW;QAAE,OAAO,WAAW,CAAC;IAC7C,IAAI,IAAI,KAAK,YAAY;QAAE,OAAO,YAAY,CAAC;IAC/C,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,oFAAoF;AACpF,SAAS,uBAAuB,CAAC,SAAiB;IAChD,IAAI,CAAC;QACH,OAAO,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,qBAAqB,IAAI,MAAM,CAAC;IAClE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,MAAM,CAAC;IAChB,CAAC;AACH,CAAC;AAID;;;;;GAKG;AACH,MAAM,UAAU,uBAAuB,CAAC,SAAiB;IACvD,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,uBAAuB,CAAC;QAC3D,OAAO,CAAC,KAAK,OAAO,IAAI,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;IACvD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,QAAQ,CAAC;IAClB,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,uBAAuB,CAAC,SAAiB,EAAE,MAA0B;IACnF,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACvF,IAAI,OAAO;YAAE,OAAO,OAAO,CAAC;IAC9B,CAAC;IAAC,MAAM,CAAC,CAAC,6BAA6B,CAAC,CAAC;IACzC,OAAO,uBAAuB,CAAC,SAAS,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,SAAiB,EACjB,MAAc,EACd,IAAmB;IAEnB,IAAI,GAAG,CAAC;IACR,IAAI,CAAC;QAAC,GAAG,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,oBAAoB,EAAE,CAAC;IAAC,CAAC;IAE9F,2EAA2E;IAC3E,wEAAwE;IACxE,0EAA0E;IAC1E,kDAAkD;IAClD,MAAM,SAAS,GAAG,IAAI,KAAK,uBAAuB,CAAC,SAAS,CAAC,CAAC;IAE9D,MAAM,CAAC,GAAG,MAAM,WAAW,CAAgB,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE;QAC9D,IAAI,CAAC,KAAK,CAAC,cAAc,IAAI,OAAO,KAAK,CAAC,cAAc,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,EAAE,CAAC;YAC7G,KAAK,CAAC,cAAc,GAAG,EAAE,CAAC;QAC5B,CAAC;QACD,IAAI,SAAS,EAAE,CAAC;YACd,OAAO,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;YACpC,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,KAAK,CAAC,cAAc,CAAC;QAClF,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;QACtC,CAAC;QACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IACvC,CAAC,CAAC,CAAC;IACH,IAAI,CAAC,CAAC,CAAC,EAAE;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;IAElD,MAAM,IAAI,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,cAAc,IAAI,EAAE,CAAC,EAAE,CAAC;IACtD,IAAI,SAAS;QAAE,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC;;QAC9B,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;IACzB,GAAG,CAAC,MAAM,CAAC,cAAc,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;IAC5E,MAAM,CAAC,IAAI,CAAC,eAAe,SAAS,UAAU,MAAM,SAAS,IAAI,EAAE,CAAC,CAAC;IACrE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AAC5B,CAAC"}
1
+ {"version":3,"file":"chat-reply-mode-store.js","sourceRoot":"","sources":["../../src/services/chat-reply-mode-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ export interface PiBridgeEvent {
2
+ uuid: string;
3
+ timestampMs: number;
4
+ kind: 'user' | 'assistant_final';
5
+ text: string;
6
+ sourceSessionId?: string;
7
+ }
8
+ export interface PiDrainResult {
9
+ events: PiBridgeEvent[];
10
+ newOffset: number;
11
+ pendingTail: string;
12
+ }
13
+ export declare function findPiTranscriptBySessionId(cliSessionId: string, cwd?: string): string | undefined;
14
+ export declare function findPiTranscriptByPid(pid: number): {
15
+ path: string;
16
+ cliSessionId: string;
17
+ } | undefined;
18
+ export declare function drainPiTranscript(path: string, fromOffset: number): PiDrainResult;
19
+ //# sourceMappingURL=pi-transcript.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pi-transcript.d.ts","sourceRoot":"","sources":["../../src/services/pi-transcript.ts"],"names":[],"mappings":"AAsBA,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,GAAG,iBAAiB,CAAC;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB;AAgCD,wBAAgB,2BAA2B,CAAC,YAAY,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAwBlG;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAgCrG;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,aAAa,CAuEjF"}
@@ -0,0 +1,222 @@
1
+ /**
2
+ * Reader for Pi agent's per-session JSONL transcript.
3
+ *
4
+ * Pi stores sessions under:
5
+ * ~/.pi/agent/sessions/<workspace-encoded>/<timestamp>_<sessionId>.jsonl
6
+ *
7
+ * For botmux wait-mode fallback we only care about:
8
+ * - user messages (`message.role === "user"`)
9
+ * - final assistant answers (`message.role === "assistant"` + `stopReason === "stop"`)
10
+ *
11
+ * Mid-turn assistant tool-use records are intentionally ignored so the worker
12
+ * only emits the terminal answer, matching the Codex-family bridge contract.
13
+ */
14
+ import { existsSync, statSync, openSync, readSync, closeSync, readdirSync, readlinkSync } from 'node:fs';
15
+ import { execSync } from 'node:child_process';
16
+ import { homedir, platform } from 'node:os';
17
+ import { join } from 'node:path';
18
+ const PI_SESSIONS_ROOT = join(homedir(), '.pi', 'agent', 'sessions');
19
+ const SESSION_UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
20
+ const IS_LINUX = platform() === 'linux';
21
+ function piSessionsDirForCwd(cwd) {
22
+ const normalized = cwd === '/' ? '--root--' : cwd.replace(/\//g, '--');
23
+ return join(PI_SESSIONS_ROOT, normalized);
24
+ }
25
+ function piSessionIdFromPath(path) {
26
+ const m = /_([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\.jsonl$/i.exec(path);
27
+ return m ? m[1] : undefined;
28
+ }
29
+ function matchPiTranscriptPath(target) {
30
+ if (!target.endsWith('.jsonl'))
31
+ return undefined;
32
+ if (!target.includes('/.pi/agent/sessions/'))
33
+ return undefined;
34
+ const sid = piSessionIdFromPath(target);
35
+ if (!sid)
36
+ return undefined;
37
+ return { path: target, cliSessionId: sid };
38
+ }
39
+ function joinTextContent(content) {
40
+ if (!Array.isArray(content))
41
+ return '';
42
+ const parts = [];
43
+ for (const item of content) {
44
+ if (!item || typeof item !== 'object')
45
+ continue;
46
+ if (item.type === 'text' && typeof item.text === 'string') {
47
+ parts.push(item.text);
48
+ }
49
+ }
50
+ return parts.join('\n').trim();
51
+ }
52
+ export function findPiTranscriptBySessionId(cliSessionId, cwd) {
53
+ if (!cliSessionId || !SESSION_UUID_RE.test(cliSessionId))
54
+ return undefined;
55
+ const suffix = `_${cliSessionId}.jsonl`;
56
+ const roots = cwd ? [piSessionsDirForCwd(cwd), PI_SESSIONS_ROOT] : [PI_SESSIONS_ROOT];
57
+ for (const root of roots) {
58
+ if (!existsSync(root))
59
+ continue;
60
+ const stack = [root];
61
+ while (stack.length > 0) {
62
+ const dir = stack.pop();
63
+ let entries;
64
+ try {
65
+ entries = readdirSync(dir);
66
+ }
67
+ catch {
68
+ continue;
69
+ }
70
+ for (const name of entries) {
71
+ const full = join(dir, name);
72
+ let st;
73
+ try {
74
+ st = statSync(full);
75
+ }
76
+ catch {
77
+ continue;
78
+ }
79
+ if (st.isDirectory()) {
80
+ stack.push(full);
81
+ }
82
+ else if (st.isFile() && name.endsWith(suffix)) {
83
+ return full;
84
+ }
85
+ }
86
+ }
87
+ }
88
+ return undefined;
89
+ }
90
+ export function findPiTranscriptByPid(pid) {
91
+ if (!Number.isInteger(pid) || pid <= 0)
92
+ return undefined;
93
+ if (IS_LINUX) {
94
+ const fdDir = `/proc/${pid}/fd`;
95
+ if (existsSync(fdDir)) {
96
+ let entries;
97
+ try {
98
+ entries = readdirSync(fdDir);
99
+ }
100
+ catch {
101
+ return undefined;
102
+ }
103
+ for (const fd of entries) {
104
+ let target;
105
+ try {
106
+ target = readlinkSync(join(fdDir, fd));
107
+ }
108
+ catch {
109
+ continue;
110
+ }
111
+ const hit = matchPiTranscriptPath(target);
112
+ if (hit)
113
+ return hit;
114
+ }
115
+ return undefined;
116
+ }
117
+ }
118
+ let out;
119
+ try {
120
+ out = execSync(`lsof -p ${pid} -Fn`, {
121
+ encoding: 'utf-8',
122
+ stdio: ['pipe', 'pipe', 'pipe'],
123
+ });
124
+ }
125
+ catch {
126
+ return undefined;
127
+ }
128
+ for (const line of out.split('\n')) {
129
+ if (!line.startsWith('n/'))
130
+ continue;
131
+ const target = line.slice(1);
132
+ const hit = matchPiTranscriptPath(target);
133
+ if (hit)
134
+ return hit;
135
+ }
136
+ return undefined;
137
+ }
138
+ export function drainPiTranscript(path, fromOffset) {
139
+ if (!existsSync(path))
140
+ return { events: [], newOffset: 0, pendingTail: '' };
141
+ let size;
142
+ try {
143
+ size = statSync(path).size;
144
+ }
145
+ catch {
146
+ return { events: [], newOffset: fromOffset, pendingTail: '' };
147
+ }
148
+ let start = fromOffset;
149
+ if (size < start)
150
+ start = 0;
151
+ if (size === start)
152
+ return { events: [], newOffset: start, pendingTail: '' };
153
+ const len = size - start;
154
+ const buf = Buffer.alloc(len);
155
+ const fd = openSync(path, 'r');
156
+ try {
157
+ readSync(fd, buf, 0, len, start);
158
+ }
159
+ finally {
160
+ closeSync(fd);
161
+ }
162
+ const text = buf.toString('utf8');
163
+ const lastNl = text.lastIndexOf('\n');
164
+ const completeText = lastNl >= 0 ? text.slice(0, lastNl + 1) : '';
165
+ const pendingTail = lastNl >= 0 ? text.slice(lastNl + 1) : text;
166
+ const newOffset = start + Buffer.byteLength(completeText, 'utf8');
167
+ const sessionId = piSessionIdFromPath(path);
168
+ const events = [];
169
+ let cursor = start;
170
+ for (const line of completeText.split('\n')) {
171
+ if (line.length === 0) {
172
+ cursor += 1;
173
+ continue;
174
+ }
175
+ const lineStart = cursor;
176
+ cursor += Buffer.byteLength(line, 'utf8') + 1;
177
+ let obj;
178
+ try {
179
+ obj = JSON.parse(line);
180
+ }
181
+ catch {
182
+ continue;
183
+ }
184
+ if (obj?.type !== 'message' || !obj.message || typeof obj.message !== 'object')
185
+ continue;
186
+ const ts = typeof obj.timestamp === 'string' ? Date.parse(obj.timestamp) : NaN;
187
+ const timestampMs = Number.isFinite(ts) ? ts : Date.now();
188
+ const role = obj.message.role;
189
+ if (role === 'user') {
190
+ const content = joinTextContent(obj.message.content);
191
+ if (!content)
192
+ continue;
193
+ events.push({
194
+ uuid: `${path}:${lineStart}`,
195
+ timestampMs,
196
+ kind: 'user',
197
+ text: content,
198
+ sourceSessionId: sessionId,
199
+ });
200
+ continue;
201
+ }
202
+ const stopReason = typeof obj.stopReason === 'string'
203
+ ? obj.stopReason
204
+ : typeof obj.message.stopReason === 'string'
205
+ ? obj.message.stopReason
206
+ : undefined;
207
+ if (role === 'assistant' && stopReason === 'stop') {
208
+ const content = joinTextContent(obj.message.content);
209
+ if (!content)
210
+ continue;
211
+ events.push({
212
+ uuid: `${path}:${lineStart}`,
213
+ timestampMs,
214
+ kind: 'assistant_final',
215
+ text: content,
216
+ sourceSessionId: sessionId,
217
+ });
218
+ }
219
+ }
220
+ return { events, newOffset, pendingTail };
221
+ }
222
+ //# sourceMappingURL=pi-transcript.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pi-transcript.js","sourceRoot":"","sources":["../../src/services/pi-transcript.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * 首次见到此 `messageId` → 记录 + 落盘,返回 `true`(调用方应处理这条消息)。
3
+ * 8h 内重复命中(飞书重推 / at-least-once 重复)→ 返回 `false`(重投,应丢弃)。
4
+ * 空 `messageId` 无法去重 → 永远 `true`(绝不因缺 id 而误吞真实消息)。
5
+ */
6
+ export declare function claimMessageOnce(larkAppId: string, messageId: string, now?: number): boolean;
7
+ /**
8
+ * Test-only:清空进程内缓存(**不删盘**),用于模拟「daemon 重启」后从盘重新载入,
9
+ * 验证去重跨重启仍生效。
10
+ */
11
+ export declare function _resetCacheForTest(): void;
12
+ //# sourceMappingURL=seen-message-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seen-message-store.d.ts","sourceRoot":"","sources":["../../src/services/seen-message-store.ts"],"names":[],"mappings":"AAoGA;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,SAAa,GAAG,OAAO,CAShG;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC"}
@@ -0,0 +1,119 @@
1
+ /**
2
+ * seen-message-store.ts — 跨重启的入站消息去重(按 message_id 持久化)。
3
+ *
4
+ * 为什么需要它:飞书长连接 (WS) 是 at-least-once,且每个事件只回**一帧** ACK——
5
+ * 一旦 ACK 没及时回达(主机内存压力把事件循环卡住超过 ~3s 预算 / 网络抖动把那帧
6
+ * ACK 丢了),飞书就按 15s / 5min / 1h / 6h(最多 4 次)重推同一条消息事件。
7
+ *
8
+ * event-dispatcher 原有的内存去重 (`eventClaims`, key=event_id, TTL 2h) 有两个缺口:
9
+ * 1. **纯内存** —— daemon 重启 / 崩溃循环 / 被 OOM 杀掉一次,去重表就清空,之后任何
10
+ * 重推都当新消息重新触发;
11
+ * 2. **2h TTL** —— 盖不住 6h 那一档重推。
12
+ * 此外它 key 用 `event_id ?? message_id`:`event_id` 标识「一次投递事件」,跨连接重投
13
+ * 可能变;`message_id` 标识「消息」本身,对同一条逻辑消息恒定不变。要做「同一条消息
14
+ * 只处理一次」,`message_id` 才是正确且充分的幂等键。
15
+ *
16
+ * 本 store 因此按 `message_id` **落盘**去重,TTL 8h 覆盖整条重推梯度 + 余量,重启后
17
+ * 仍能挡住旧消息重放。每个 larkAppId 一份文件(key 已隐含 app 维度,且多 bot 各自
18
+ * 独立、无跨进程写竞争)。
19
+ *
20
+ * 同步落盘的理由:`claimMessageOnce` 必须**全同步**返回(event-dispatcher 在 ACK 前的
21
+ * 同步段里调用它,且依赖「claim + setImmediate 之间不 await」来保住同 anchor 消息的
22
+ * 到达序)。落盘走 `atomicWriteFileSync`(tmp + rename,崩溃安全、无半截读),只在
23
+ * 见到**新** message_id 时写一次快照;重复命中直接返回、不写盘。聊天桥接是人类节奏,
24
+ * 每条新消息一次小快照写(个位数 ms)远在 3s ACK 预算之内。
25
+ */
26
+ import { existsSync, readFileSync, mkdirSync } from 'node:fs';
27
+ import { dirname, join } from 'node:path';
28
+ import { atomicWriteFileSync } from '../utils/atomic-write.js';
29
+ import { config } from '../config.js';
30
+ import { logger } from '../utils/logger.js';
31
+ /** 8h —— 覆盖飞书 15s/5min/1h/6h 的全部重推档,外加余量。 */
32
+ const TTL_MS = 8 * 60 * 60_000;
33
+ /** 有界:超限按最旧(Map 迭代序即插入序)淘汰,防文件无界增长。 */
34
+ const MAX_ENTRIES = 5000;
35
+ const caches = new Map();
36
+ function fileFor(larkAppId) {
37
+ return join(config.session.dataDir, 'dedup', `seen-messages-${larkAppId}.json`);
38
+ }
39
+ /** 懒加载:进程内首次用到某 app 时从盘载入(已过期的条目载入时即丢弃)。 */
40
+ function load(larkAppId) {
41
+ const existing = caches.get(larkAppId);
42
+ if (existing?.loaded)
43
+ return existing;
44
+ const map = new Map();
45
+ const file = fileFor(larkAppId);
46
+ try {
47
+ if (existsSync(file)) {
48
+ const parsed = JSON.parse(readFileSync(file, 'utf-8'));
49
+ // 兜底:只接受 `{ key: number }` 形态;数组/损坏内容当空表,绝不抛。
50
+ if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
51
+ const now = Date.now();
52
+ for (const [k, exp] of Object.entries(parsed)) {
53
+ if (typeof exp === 'number' && exp > now)
54
+ map.set(k, exp);
55
+ }
56
+ }
57
+ }
58
+ }
59
+ catch (err) {
60
+ logger.warn(`[seen-message-store] load failed (${file}): ${err}`);
61
+ }
62
+ const cache = { map, loaded: true };
63
+ caches.set(larkAppId, cache);
64
+ return cache;
65
+ }
66
+ function persist(larkAppId, map) {
67
+ const file = fileFor(larkAppId);
68
+ try {
69
+ mkdirSync(dirname(file), { recursive: true });
70
+ const obj = {};
71
+ for (const [k, v] of map)
72
+ obj[k] = v;
73
+ atomicWriteFileSync(file, JSON.stringify(obj));
74
+ }
75
+ catch (err) {
76
+ // 落盘失败不阻断处理:退化为「本进程内仍去重,但重启后这条不再被挡」,
77
+ // 与未持久化前的旧行为一致,绝不因写盘失败丢消息。
78
+ logger.warn(`[seen-message-store] persist failed (${file}): ${err}`);
79
+ }
80
+ }
81
+ /** 删过期 + 超限淘汰最旧,保持 map / 文件有界。 */
82
+ function pruneAndCap(map, now) {
83
+ for (const [k, exp] of map)
84
+ if (exp <= now)
85
+ map.delete(k);
86
+ if (map.size > MAX_ENTRIES) {
87
+ let drop = map.size - MAX_ENTRIES;
88
+ for (const k of map.keys()) {
89
+ map.delete(k);
90
+ if (--drop <= 0)
91
+ break;
92
+ }
93
+ }
94
+ }
95
+ /**
96
+ * 首次见到此 `messageId` → 记录 + 落盘,返回 `true`(调用方应处理这条消息)。
97
+ * 8h 内重复命中(飞书重推 / at-least-once 重复)→ 返回 `false`(重投,应丢弃)。
98
+ * 空 `messageId` 无法去重 → 永远 `true`(绝不因缺 id 而误吞真实消息)。
99
+ */
100
+ export function claimMessageOnce(larkAppId, messageId, now = Date.now()) {
101
+ if (!messageId)
102
+ return true;
103
+ const cache = load(larkAppId);
104
+ const exp = cache.map.get(messageId);
105
+ if (exp && exp > now)
106
+ return false; // 命中未过期记录 → 重投
107
+ pruneAndCap(cache.map, now);
108
+ cache.map.set(messageId, now + TTL_MS);
109
+ persist(larkAppId, cache.map);
110
+ return true;
111
+ }
112
+ /**
113
+ * Test-only:清空进程内缓存(**不删盘**),用于模拟「daemon 重启」后从盘重新载入,
114
+ * 验证去重跨重启仍生效。
115
+ */
116
+ export function _resetCacheForTest() {
117
+ caches.clear();
118
+ }
119
+ //# sourceMappingURL=seen-message-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seen-message-store.js","sourceRoot":"","sources":["../../src/services/seen-message-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import { type BotConfig, type ContentTriggerConfig } from '../bot-registry.js';
2
+ export declare const LEGACY_DASHBOARD_SUMMARY_TRIGGER_NAME = "dashboard-default-summary-trigger";
3
+ export declare const DEFAULT_SUMMARY_LIMIT = 50;
4
+ export declare const DEFAULT_SUMMARY_SINCE_HOURS = 24;
5
+ export declare const DEFAULT_SUMMARY_PROMPT = "\u8BF7\u6839\u636E\u5F53\u524D\u4F1A\u8BDD\u5386\u53F2\u751F\u6210\u603B\u7ED3\u3002\u82E5\u662F\u8BDD\u9898\u7FA4\uFF0C\u8BF7\u603B\u7ED3\u5F53\u524D\u8BDD\u9898\uFF1B\u82E5\u662F\u666E\u901A\u7FA4\uFF0C\u8BF7\u603B\u7ED3\u914D\u7F6E\u8303\u56F4\u5185\u7684\u7FA4\u804A\u5386\u53F2\u3002\u603B\u7ED3\u9700\u5305\u542B\uFF1A\u80CC\u666F\u3001\u5173\u952E\u8BA8\u8BBA\u3001\u7ED3\u8BBA\u3001\u5F85\u529E\u4E8B\u9879\u3002\u907F\u514D\u6CC4\u9732\u65E0\u5173\u9690\u79C1\u4FE1\u606F\u3002";
6
+ export interface SummaryRangePrefs {
7
+ limit: number;
8
+ sinceHours: number;
9
+ }
10
+ export type SummaryRangeUpdateResult = {
11
+ ok: true;
12
+ summaryRange: SummaryRangePrefs;
13
+ } | {
14
+ ok: false;
15
+ reason: string;
16
+ };
17
+ export declare function defaultSummaryRangePrefs(): SummaryRangePrefs;
18
+ export declare function summaryRangeFromLegacyContentTriggers(triggers: readonly ContentTriggerConfig[] | undefined): SummaryRangePrefs | undefined;
19
+ export declare function summaryRangeFromBotConfig(config: Pick<BotConfig, 'summaryRange' | 'contentTriggers'>): SummaryRangePrefs;
20
+ export declare function updateDashboardSummaryRange(larkAppId: string, rawBody: unknown): Promise<SummaryRangeUpdateResult>;
21
+ //# sourceMappingURL=summary-range-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summary-range-store.d.ts","sourceRoot":"","sources":["../../src/services/summary-range-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,SAAS,EACd,KAAK,oBAAoB,EAE1B,MAAM,oBAAoB,CAAC;AAI5B,eAAO,MAAM,qCAAqC,sCAAsC,CAAC;AACzF,eAAO,MAAM,qBAAqB,KAAK,CAAC;AACxC,eAAO,MAAM,2BAA2B,KAAK,CAAC;AAC9C,eAAO,MAAM,sBAAsB,2eACkD,CAAC;AAEtF,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,wBAAwB,GAAG;IACrC,EAAE,EAAE,IAAI,CAAC;IACT,YAAY,EAAE,iBAAiB,CAAC;CACjC,GAAG;IACF,EAAE,EAAE,KAAK,CAAC;IACV,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAcF,wBAAgB,wBAAwB,IAAI,iBAAiB,CAK5D;AAED,wBAAgB,qCAAqC,CACnD,QAAQ,EAAE,SAAS,oBAAoB,EAAE,GAAG,SAAS,GACpD,iBAAiB,GAAG,SAAS,CAO/B;AAED,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,cAAc,GAAG,iBAAiB,CAAC,GAAG,iBAAiB,CAIxH;AA0BD,wBAAsB,2BAA2B,CAC/C,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,wBAAwB,CAAC,CA0BnC"}
@@ -0,0 +1,89 @@
1
+ import { getBot, } from '../bot-registry.js';
2
+ import { rmwBotEntry } from './config-store.js';
3
+ import { logger } from '../utils/logger.js';
4
+ export const LEGACY_DASHBOARD_SUMMARY_TRIGGER_NAME = 'dashboard-default-summary-trigger';
5
+ export const DEFAULT_SUMMARY_LIMIT = 50;
6
+ export const DEFAULT_SUMMARY_SINCE_HOURS = 24;
7
+ export const DEFAULT_SUMMARY_PROMPT = '请根据当前会话历史生成总结。若是话题群,请总结当前话题;若是普通群,请总结配置范围内的群聊历史。总结需包含:背景、关键讨论、结论、待办事项。避免泄露无关隐私信息。';
8
+ function toNonNegativeInt(raw, fallback) {
9
+ return typeof raw === 'number' && Number.isInteger(raw) && raw >= 0 ? raw : fallback;
10
+ }
11
+ function normalizedRangeFromConfig(raw) {
12
+ if (!raw)
13
+ return undefined;
14
+ return {
15
+ limit: toNonNegativeInt(raw.limit, DEFAULT_SUMMARY_LIMIT),
16
+ sinceHours: toNonNegativeInt(raw.sinceHours, DEFAULT_SUMMARY_SINCE_HOURS),
17
+ };
18
+ }
19
+ export function defaultSummaryRangePrefs() {
20
+ return {
21
+ limit: DEFAULT_SUMMARY_LIMIT,
22
+ sinceHours: DEFAULT_SUMMARY_SINCE_HOURS,
23
+ };
24
+ }
25
+ export function summaryRangeFromLegacyContentTriggers(triggers) {
26
+ const trigger = triggers?.find(t => t.name === LEGACY_DASHBOARD_SUMMARY_TRIGGER_NAME);
27
+ if (!trigger)
28
+ return undefined;
29
+ return {
30
+ limit: toNonNegativeInt(trigger.history.regularGroup.limit, DEFAULT_SUMMARY_LIMIT),
31
+ sinceHours: toNonNegativeInt(trigger.history.regularGroup.sinceHours, DEFAULT_SUMMARY_SINCE_HOURS),
32
+ };
33
+ }
34
+ export function summaryRangeFromBotConfig(config) {
35
+ return normalizedRangeFromConfig(config.summaryRange)
36
+ ?? summaryRangeFromLegacyContentTriggers(config.contentTriggers)
37
+ ?? defaultSummaryRangePrefs();
38
+ }
39
+ function normalizeSummaryRangePrefs(raw) {
40
+ if (!raw || typeof raw !== 'object' || Array.isArray(raw))
41
+ return { ok: false, reason: 'bad_json' };
42
+ const body = raw;
43
+ const limit = body.limit;
44
+ if (typeof limit !== 'number' || !Number.isInteger(limit) || limit < 0)
45
+ return { ok: false, reason: 'invalid_limit' };
46
+ const sinceHours = body.sinceHours;
47
+ if (typeof sinceHours !== 'number' || !Number.isInteger(sinceHours) || sinceHours < 0) {
48
+ return { ok: false, reason: 'invalid_since_hours' };
49
+ }
50
+ return { ok: true, prefs: { limit, sinceHours } };
51
+ }
52
+ function withoutLegacyDashboardSummaryTrigger(triggers) {
53
+ if (!triggers)
54
+ return undefined;
55
+ const next = triggers.filter(t => t.name !== LEGACY_DASHBOARD_SUMMARY_TRIGGER_NAME);
56
+ return next.length > 0 ? next : undefined;
57
+ }
58
+ export async function updateDashboardSummaryRange(larkAppId, rawBody) {
59
+ const normalized = normalizeSummaryRangePrefs(rawBody);
60
+ if (!normalized.ok)
61
+ return normalized;
62
+ const prefs = normalized.prefs;
63
+ let bot;
64
+ try {
65
+ bot = getBot(larkAppId);
66
+ }
67
+ catch {
68
+ return { ok: false, reason: 'bot_not_registered' };
69
+ }
70
+ const nextLegacyTriggers = withoutLegacyDashboardSummaryTrigger(bot.config.contentTriggers);
71
+ const r = await rmwBotEntry(larkAppId, (entry) => {
72
+ entry.summaryRange = { limit: prefs.limit, sinceHours: prefs.sinceHours };
73
+ if (Array.isArray(entry.contentTriggers)) {
74
+ const nextRaw = entry.contentTriggers.filter((t) => !t || typeof t !== 'object' || Array.isArray(t) || t.name !== LEGACY_DASHBOARD_SUMMARY_TRIGGER_NAME);
75
+ if (nextRaw.length > 0)
76
+ entry.contentTriggers = nextRaw;
77
+ else
78
+ delete entry.contentTriggers;
79
+ }
80
+ return { write: true, result: prefs };
81
+ });
82
+ if (!r.ok)
83
+ return { ok: false, reason: r.reason };
84
+ bot.config.summaryRange = { limit: prefs.limit, sinceHours: prefs.sinceHours };
85
+ bot.config.contentTriggers = nextLegacyTriggers;
86
+ logger.info(`[summary-range:${larkAppId}] dashboard summary range saved limit=${prefs.limit} sinceHours=${prefs.sinceHours}`);
87
+ return { ok: true, summaryRange: summaryRangeFromBotConfig(bot.config) };
88
+ }
89
+ //# sourceMappingURL=summary-range-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summary-range-store.js","sourceRoot":"","sources":["../../src/services/summary-range-store.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,MAAM,GAIP,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,MAAM,CAAC,MAAM,qCAAqC,GAAG,mCAAmC,CAAC;AACzF,MAAM,CAAC,MAAM,qBAAqB,GAAG,EAAE,CAAC;AACxC,MAAM,CAAC,MAAM,2BAA2B,GAAG,EAAE,CAAC;AAC9C,MAAM,CAAC,MAAM,sBAAsB,GACjC,mFAAmF,CAAC;AAetF,SAAS,gBAAgB,CAAC,GAAY,EAAE,QAAgB;IACtD,OAAO,OAAO,GAAG,KAAK,QAAQ,IAAI,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC;AACvF,CAAC;AAED,SAAS,yBAAyB,CAAC,GAAmC;IACpE,IAAI,CAAC,GAAG;QAAE,OAAO,SAAS,CAAC;IAC3B,OAAO;QACL,KAAK,EAAE,gBAAgB,CAAC,GAAG,CAAC,KAAK,EAAE,qBAAqB,CAAC;QACzD,UAAU,EAAE,gBAAgB,CAAC,GAAG,CAAC,UAAU,EAAE,2BAA2B,CAAC;KAC1E,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,wBAAwB;IACtC,OAAO;QACL,KAAK,EAAE,qBAAqB;QAC5B,UAAU,EAAE,2BAA2B;KACxC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,qCAAqC,CACnD,QAAqD;IAErD,MAAM,OAAO,GAAG,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,qCAAqC,CAAC,CAAC;IACtF,IAAI,CAAC,OAAO;QAAE,OAAO,SAAS,CAAC;IAC/B,OAAO;QACL,KAAK,EAAE,gBAAgB,CAAC,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,KAAK,EAAE,qBAAqB,CAAC;QAClF,UAAU,EAAE,gBAAgB,CAAC,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,UAAU,EAAE,2BAA2B,CAAC;KACnG,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,MAA2D;IACnG,OAAO,yBAAyB,CAAC,MAAM,CAAC,YAAY,CAAC;WAChD,qCAAqC,CAAC,MAAM,CAAC,eAAe,CAAC;WAC7D,wBAAwB,EAAE,CAAC;AAClC,CAAC;AAMD,SAAS,0BAA0B,CAAC,GAAY;IAC9C,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;IACpG,MAAM,IAAI,GAAG,GAA8B,CAAC;IAC5C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;IACzB,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC;IACtH,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;IACnC,IAAI,OAAO,UAAU,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;QACtF,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,qBAAqB,EAAE,CAAC;IACtD,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE,CAAC;AACpD,CAAC;AAED,SAAS,oCAAoC,CAC3C,QAAqD;IAErD,IAAI,CAAC,QAAQ;QAAE,OAAO,SAAS,CAAC;IAChC,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,qCAAqC,CAAC,CAAC;IACpF,OAAO,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;AAC5C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAC/C,SAAiB,EACjB,OAAgB;IAEhB,MAAM,UAAU,GAAG,0BAA0B,CAAC,OAAO,CAAC,CAAC;IACvD,IAAI,CAAC,UAAU,CAAC,EAAE;QAAE,OAAO,UAAU,CAAC;IACtC,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC;IAE/B,IAAI,GAAG,CAAC;IACR,IAAI,CAAC;QAAC,GAAG,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,oBAAoB,EAAE,CAAC;IAAC,CAAC;IAE9F,MAAM,kBAAkB,GAAG,oCAAoC,CAAC,GAAG,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;IAC5F,MAAM,CAAC,GAAG,MAAM,WAAW,CAAoB,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE;QAClE,KAAK,CAAC,YAAY,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,CAAC;QAC1E,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,eAAe,CAAC,EAAE,CAAC;YACzC,MAAM,OAAO,GAAG,KAAK,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAU,EAAE,EAAE,CAC1D,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAK,CAA6B,CAAC,IAAI,KAAK,qCAAqC,CACjI,CAAC;YACF,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;gBAAE,KAAK,CAAC,eAAe,GAAG,OAAO,CAAC;;gBACnD,OAAO,KAAK,CAAC,eAAe,CAAC;QACpC,CAAC;QACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IACxC,CAAC,CAAC,CAAC;IACH,IAAI,CAAC,CAAC,CAAC,EAAE;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;IAElD,GAAG,CAAC,MAAM,CAAC,YAAY,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,CAAC;IAC/E,GAAG,CAAC,MAAM,CAAC,eAAe,GAAG,kBAAkB,CAAC;IAChD,MAAM,CAAC,IAAI,CAAC,kBAAkB,SAAS,yCAAyC,KAAK,CAAC,KAAK,eAAe,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC;IAC9H,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,yBAAyB,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;AAC3E,CAAC"}
@@ -1,6 +1,7 @@
1
1
  export type TriggerSourceType = 'webhook' | 'ui' | 'workflow' | 'schedule';
2
2
  export type TriggerTargetKind = 'turn' | 'workflow';
3
- export type TriggerAction = 'queued' | 'delivered' | 'dry_run' | 'ignored';
3
+ export type TriggerAction = 'queued' | 'delivered' | 'dry_run' | 'ignored' | 'completed';
4
+ export type TriggerAsyncStatus = 'pending' | 'completed';
4
5
  export interface TriggerRequest {
5
6
  source: {
6
7
  type: TriggerSourceType;
@@ -28,9 +29,12 @@ export interface TriggerRequest {
28
29
  dryRun?: boolean;
29
30
  dedupKey?: string;
30
31
  status?: 'firing' | 'resolved' | string;
32
+ waitForFinalOutput?: boolean;
33
+ asyncReturnSessionId?: boolean;
34
+ timeoutMs?: number;
31
35
  };
32
36
  }
33
- export type TriggerErrorCode = 'bad_json' | 'bad_request' | 'bot_not_found' | 'bot_not_in_chat' | 'daemon_offline' | 'dry_run' | 'invalid_signature' | 'chat_not_allowed' | 'group_create_failed' | 'lifecycle_extract_failed' | 'rate_limited' | 'replay' | 'session_not_found' | 'target_required' | 'trigger_failed' | 'workflow_trigger_not_implemented';
37
+ export type TriggerErrorCode = 'bad_json' | 'bad_request' | 'bot_not_found' | 'bot_not_in_chat' | 'daemon_offline' | 'dry_run' | 'invalid_signature' | 'chat_not_allowed' | 'group_create_failed' | 'lifecycle_extract_failed' | 'rate_limited' | 'replay' | 'session_not_found' | 'target_required' | 'trigger_failed' | 'wait_timeout' | 'workflow_trigger_not_implemented';
34
38
  export interface TriggerResponse {
35
39
  ok: boolean;
36
40
  triggerId?: string;
@@ -45,6 +49,14 @@ export interface TriggerResponse {
45
49
  errorCode?: TriggerErrorCode;
46
50
  error?: string;
47
51
  promptPreview?: string;
52
+ output?: {
53
+ content: string;
54
+ };
55
+ async?: {
56
+ status: TriggerAsyncStatus;
57
+ sessionId?: string;
58
+ completedAt?: string;
59
+ };
48
60
  }
49
61
  export declare function isRecord(v: unknown): v is Record<string, unknown>;
50
62
  export declare function validateTriggerRequest(raw: unknown): {
@@ -1 +1 @@
1
- {"version":3,"file":"trigger-types.d.ts","sourceRoot":"","sources":["../../src/services/trigger-types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,IAAI,GAAG,UAAU,GAAG,UAAU,CAAC;AAC3E,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,UAAU,CAAC;AACpD,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,WAAW,GAAG,SAAS,GAAG,SAAS,CAAC;AAE3E,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE;QACN,IAAI,EAAE,iBAAiB,CAAC;QACxB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,MAAM,EAAE;QACN,IAAI,EAAE,iBAAiB,CAAC;QACxB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,QAAQ,EAAE;QACR,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,EAAE,MAAM,CAAC;QACnB,OAAO,EAAE,KAAK,CAAC;QACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAClC,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;IAIF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE;QACR,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,MAAM,CAAC,EAAE,QAAQ,GAAG,UAAU,GAAG,MAAM,CAAC;KACzC,CAAC;CACH;AAED,MAAM,MAAM,gBAAgB,GACxB,UAAU,GACV,aAAa,GACb,eAAe,GACf,iBAAiB,GACjB,gBAAgB,GAChB,SAAS,GACT,mBAAmB,GACnB,kBAAkB,GAClB,qBAAqB,GACrB,0BAA0B,GAC1B,cAAc,GACd,QAAQ,GACR,mBAAmB,GACnB,iBAAiB,GACjB,gBAAgB,GAChB,kCAAkC,CAAC;AAEvC,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,OAAO,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,MAAM,CAAC,EAAE;QACP,IAAI,EAAE,iBAAiB,CAAC;QACxB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,wBAAgB,QAAQ,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEjE;AAED,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,OAAO,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,cAAc,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,eAAe,CAAA;CAAE,CAuBjJ"}
1
+ {"version":3,"file":"trigger-types.d.ts","sourceRoot":"","sources":["../../src/services/trigger-types.ts"],"names":[],"mappings":"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"}