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
@@ -136,45 +136,155 @@ function installClaudeSettings(configPath, hookCommand, sessionStartCommand) {
136
136
  // ─── OpenCode plugin 格式 ─────────────────────────────────────────────────────
137
137
  /**
138
138
  * 构造 botmux ask 的 OpenCode 插件内容。
139
- * 插件监听 question.asked 事件,将 payload JSON 写入 botmux hook opencode 的 stdin,
140
- * 读取 stdout 作为回答,返回给 OpenCode。
141
139
  *
142
- * TODO(dogfood): 校验 OpenCode 插件 question.asked API
143
- * OpenCode 插件 API 目前处于 dogfood 阶段,`question.asked` 钩子形状和返回值约定
144
- * 需要在真实会话中实测确认(stdin/stdout 格式、同步/异步、返回值结构等)。
140
+ * 机制(已在 OpenCode 1.17.x 实机验证):
141
+ * - OpenCode 自带原生 `question` 工具(= Claude AskUserQuestion 等价物),模型会原生
142
+ * 调用,无需我们注入。它被调用时,服务端发布 `question.asked` 事件并阻塞,等客户端
143
+ * 把答案提交到 `/question/{id}/reply`(body `{ answers }`)后才解阻塞、返回给模型。
144
+ * - OpenCode 插件 API 没有 `question.asked` 这种专用钩子;要拦截只能用通用 `event` 钩子
145
+ * 按 `event.type === 'question.asked'` 过滤(plugin 导出必须是「函数」而非对象)。
146
+ *
147
+ * 事件 payload 形状:
148
+ * { type:'question.asked', properties:{ id:'que_…', sessionID:'ses_…',
149
+ * questions:[{ question, header, options:[{label,description}], multiple? }] } }
150
+ *
151
+ * 转发策略:把 questions 规范成 `botmux hook opencode` 认识的 payload 喂给它(复用现有
152
+ * 飞书问答链路:daemon /api/asks → 飞书卡片 → 用户作答 → directive),拿到 stdout 里的
153
+ * `{ answers }` 后回传给 OpenCode 解阻塞。
154
+ * - **回传必须走 OpenCode 注入给插件的 client(`client._client`)**,不能用裸 fetch:
155
+ * OpenCode 是「单 server 多 worktree 实例」模型,client 自带 `x-opencode-directory`
156
+ * 头把 reply 路由到发起 question 的那个实例,且其传输在 daemon 里实际可达
157
+ * (裸 fetch 到 `localhost:4096` 在 daemon 里连不上 + 缺 directory 头 → 永远卡 picker)。
158
+ * - **异步**作答:飞书侧作答可能耗时很久(默认上限 1h),绝不能用 spawnSync 同步阻塞
159
+ * OpenCode 的单线程事件总线(会冻结整个 TUI)。改用异步 spawn + fire-and-forget。
160
+ * - stdout 为空(passthrough:daemon 不可达 / 超时 / 非 botmux 会话)→ 不 reply,把问题
161
+ * 留给 OpenCode 原生 picker(botmux web 终端里仍可人工作答)。
145
162
  */
146
163
  function buildOpenCodePlugin(parts) {
147
164
  // 用 argv 形式嵌入(不拼 shell 字符串、不 split):含空格/引号的路径也不会被拆坏。
148
165
  const cmdLit = JSON.stringify(parts.cmd);
149
166
  const argsLit = JSON.stringify(parts.args);
150
167
  return `// botmux-ask opencode plugin
151
- // OpenCode question.asked 事件转发到 botmux hook opencode。
152
- // TODO(dogfood): 校验 OpenCode 插件 question.asked API
153
- import { spawnSync } from "child_process";
168
+ // 监听 OpenCode 原生 \`question\` 工具触发的 \`question.asked\` 事件,转发到
169
+ // \`botmux hook opencode\`(飞书问答),再把答案 POST OpenCode 解阻塞。
170
+ import { spawn } from "child_process";
171
+ import { appendFileSync } from "fs";
172
+ import { homedir } from "os";
173
+ import { join } from "path";
154
174
 
155
- export default {
156
- name: "botmux-ask",
175
+ const CMD = ${cmdLit};
176
+ const ARGS = ${argsLit};
177
+
178
+ // 诊断日志:默认关闭,设 BOTMUX_OPENCODE_ASK_DEBUG=1 后每步落盘到
179
+ // ~/.botmux/opencode-ask-debug.log,用于排查 ask 链路(事件→转发→reply)。
180
+ const DBG_ON = !!process.env.BOTMUX_OPENCODE_ASK_DEBUG;
181
+ const DBG = join(homedir(), ".botmux", "opencode-ask-debug.log");
182
+ function dbg(m) {
183
+ if (!DBG_ON) return;
184
+ try { appendFileSync(DBG, new Date().toISOString() + " " + m + "\\n"); } catch {}
185
+ }
157
186
 
158
- // question.asked: OpenCode 向用户提问时触发。
159
- // payload 形状待实测(见 TODO 注释)。
160
- // 返回值 { type:'answer', answers } undefined(undefined = 由 OpenCode 自行处理)。
161
- "question.asked"(payload) {
187
+ // 异步 spawn \`botmux hook opencode\`:stdin 喂 payload,收集 stdout。
188
+ // 任何失败都 resolve("")(= passthrough 放行)。child 自带超时(hook 客户端按
189
+ // BOTMUX_ASK_TIMEOUT_MS 自限),这里再加 25h 兜底 kill 防僵尸(unref 不拖住事件循环)。
190
+ function askBotmux(payload) {
191
+ return new Promise((resolve) => {
192
+ let out = "";
193
+ let settled = false;
194
+ const done = (v) => { if (!settled) { settled = true; resolve(v); } };
195
+ let child;
162
196
  try {
163
- const input = JSON.stringify(payload);
164
- const result = spawnSync(${cmdLit}, ${argsLit}, {
165
- input,
166
- encoding: "utf-8",
167
- timeout: 86400000, // 24h,等待用户在飞书回答
168
- });
169
- // stdout 为空 = hook 客户端 passthrough(放行)→ 返回 undefined,OpenCode 原生处理。
170
- if (result.status === 0 && result.stdout && result.stdout.trim()) {
171
- return JSON.parse(result.stdout.trim());
172
- }
197
+ child = spawn(CMD, ARGS, { stdio: ["pipe", "pipe", "ignore"] });
173
198
  } catch {
174
- // 任何失败都降级放行:返回 undefined 让 OpenCode 回退原生终端提问
199
+ return done("");
200
+ }
201
+ const backstop = setTimeout(() => { try { child.kill(); } catch {} done(""); }, 90000000);
202
+ if (typeof backstop.unref === "function") backstop.unref();
203
+ child.stdout.on("data", (d) => { out += d.toString("utf-8"); });
204
+ child.on("error", () => { clearTimeout(backstop); done(""); });
205
+ child.on("close", (code) => { clearTimeout(backstop); done(code === 0 ? out : ""); });
206
+ try { child.stdin.write(payload); child.stdin.end(); } catch { clearTimeout(backstop); done(""); }
207
+ });
208
+ }
209
+
210
+ // 把答案回传给 OpenCode 解阻塞。
211
+ // 必须走 OpenCode 自带的 client(client._client = 已配置的 hey-api client)——
212
+ // 它带着 \`x-opencode-directory\` 头与正确的 baseUrl/传输。OpenCode 用「单 server 多
213
+ // worktree 实例」模型,该头用于把 reply 路由到发起 question 的那个实例;裸 fetch 缺这个
214
+ // 头会打到错误实例(question 找不到 → 永远卡在 picker)。失败再回落裸 fetch(复制其 headers)。
215
+ function safeStr(x) {
216
+ try { return String(JSON.stringify(x)).slice(0, 120); } catch { return String(x); }
217
+ }
218
+
219
+ async function postReply(client, serverUrl, id, answers) {
220
+ const body = { answers };
221
+ // 1) 经 client._client(带 directory 头 + 正确传输)。这是 daemon 多实例下唯一可达的路径:
222
+ // 裸 fetch 到 localhost:4096 在 daemon 里根本连不上(OpenCode 用 interceptor 传输)。
223
+ try {
224
+ const c = client && client._client;
225
+ if (c && typeof c.post === "function") {
226
+ const res = await c.post({ url: "/question/" + id + "/reply", body });
227
+ const st = res && res.response && res.response.status;
228
+ const success = (res && res.data === true) || (st && st >= 200 && st < 300);
229
+ dbg("CLIENT_POST id=" + id + " status=" + st + " data=" + safeStr(res && res.data) + " err=" + safeStr(res && res.error));
230
+ if (success) return true;
231
+ } else {
232
+ dbg("CLIENT_POST_UNAVAILABLE id=" + id);
175
233
  }
176
- return undefined;
177
- },
234
+ } catch (e) { dbg("CLIENT_POST_THREW id=" + id + " err=" + String(e)); }
235
+ // 2) 回落裸 fetch,尽量复制 client 的 headers(含 directory)与 baseUrl
236
+ try {
237
+ let base = String(serverUrl).replace(/\\/+$/, "");
238
+ let headers = { "content-type": "application/json" };
239
+ try {
240
+ const cfg = client && client._client && client._client.getConfig && client._client.getConfig();
241
+ if (cfg) {
242
+ if (cfg.baseUrl) base = String(cfg.baseUrl).replace(/\\/+$/, "");
243
+ if (cfg.headers) headers = Object.assign({}, cfg.headers, { "content-type": "application/json" });
244
+ }
245
+ } catch {}
246
+ const url = base + "/question/" + id + "/reply";
247
+ dbg("FETCH_POST url=" + url + " headers=" + Object.keys(headers).join(","));
248
+ const r = await fetch(url, { method: "POST", headers, body: JSON.stringify(body) });
249
+ let txt = ""; try { txt = await r.text(); } catch {}
250
+ dbg("FETCH_POST_RESULT id=" + id + " status=" + r.status + " body=" + txt.slice(0, 150));
251
+ return r.ok;
252
+ } catch (e) { dbg("FETCH_POST_THREW id=" + id + " err=" + String(e)); return false; }
253
+ }
254
+
255
+ export const BotmuxAsk = async ({ client, serverUrl }) => {
256
+ dbg("PLUGIN_LOADED serverUrl=" + serverUrl + " hasClient=" + !!(client && client._client));
257
+ return {
258
+ event: async ({ event }) => {
259
+ if (!event || event.type !== "question.asked") return;
260
+ const props = event.properties || {};
261
+ const id = props.id;
262
+ const questions = props.questions;
263
+ dbg("EVENT question.asked id=" + id + " sessionID=" + props.sessionID + " nQ=" + (Array.isArray(questions) ? questions.length : "?"));
264
+ if (!id || !Array.isArray(questions) || questions.length === 0) { dbg("SKIP missing id/questions"); return; }
265
+ // fire-and-forget:不 await,避免阻塞事件总线(飞书作答可能很久)。
266
+ // 问题在服务端独立阻塞,答案经 reply 回去即可解阻塞。
267
+ (async () => {
268
+ const payload = JSON.stringify({
269
+ hook_event_name: "question.asked",
270
+ question_id: id,
271
+ session_id: props.sessionID,
272
+ tool_input: { questions },
273
+ });
274
+ dbg("SPAWN botmux hook opencode id=" + id);
275
+ const stdout = (await askBotmux(payload)).trim();
276
+ dbg("HOOK_STDOUT id=" + id + " len=" + stdout.length + " body=" + stdout.slice(0, 300));
277
+ if (!stdout) { dbg("PASSTHROUGH empty stdout id=" + id); return; } // passthrough/超时 → 不应答,留给原生 picker
278
+ let directive;
279
+ try { directive = JSON.parse(stdout); } catch (e) { dbg("PARSE_FAIL id=" + id + " err=" + String(e)); return; }
280
+ const answers = directive && directive.answers;
281
+ if (!Array.isArray(answers)) { dbg("NO_ANSWERS id=" + id + " directive=" + JSON.stringify(directive).slice(0, 200)); return; }
282
+ dbg("REPLY id=" + id + " answers=" + JSON.stringify(answers));
283
+ const ok = await postReply(client, serverUrl, id, answers);
284
+ dbg("REPLY_DONE id=" + id + " ok=" + ok);
285
+ })().catch((e) => { dbg("HANDLER_ERR id=" + id + " err=" + String(e)); });
286
+ },
287
+ };
178
288
  };
179
289
  `;
180
290
  }
@@ -208,7 +318,7 @@ export function installHook(cliId, hookInstall, hookCommand) {
208
318
  installClaudeSettings(configPath, hookCommand, hookInstall.sessionStartCommand);
209
319
  break;
210
320
  case 'opencode-plugin':
211
- // OpenCode 插件走 argv parts(spawnSync),不复用 shell 字符串,避免被 split 拆坏。
321
+ // OpenCode 插件走 argv parts(异步 spawn),不复用 shell 字符串,避免被 split 拆坏。
212
322
  installOpenCodePlugin(configPath, hookCommandParts(cliId));
213
323
  break;
214
324
  default: {
@@ -1 +1 @@
1
- {"version":3,"file":"hook-installer.js","sourceRoot":"","sources":["../../src/adapters/hook-installer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"hook-installer.js","sourceRoot":"","sources":["../../src/adapters/hook-installer.ts"],"names":[],"mappings":"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"}
@@ -6,6 +6,46 @@ import type { VoiceConfig } from './services/voice/types.js';
6
6
  import { type Brand } from './im/lark/lark-hosts.js';
7
7
  import type { BotSkillPolicy } from './core/skills/types.js';
8
8
  export type ChatReplyMode = 'chat' | 'new-topic' | 'shared' | 'chat-topic';
9
+ export type ContentTriggerScope = 'topic' | 'regularGroup' | 'both';
10
+ export type ContentTriggerMatchType = 'keyword' | 'regex';
11
+ export type ContentTriggerActionType = 'start-or-wake-session';
12
+ export interface SummaryRangeConfig {
13
+ /** 0 means no count limit; omitted defaults to 50. */
14
+ limit?: number;
15
+ /** 0 means no time limit; omitted defaults to 24 hours. */
16
+ sinceHours?: number;
17
+ }
18
+ export interface ContentTriggerConfig {
19
+ name: string;
20
+ enabled: boolean;
21
+ scope: ContentTriggerScope;
22
+ /**
23
+ * Default false. When true, this trigger may be matched by non-@ messages
24
+ * authored by other bots. The current bot's own messages are still ignored.
25
+ */
26
+ allowBotMessages?: boolean;
27
+ match: {
28
+ type: ContentTriggerMatchType;
29
+ pattern: string;
30
+ caseSensitive: boolean;
31
+ };
32
+ history: {
33
+ topic: {
34
+ mode: 'current-thread';
35
+ };
36
+ regularGroup: {
37
+ mode: 'recent-messages';
38
+ /** 0 means no count limit; omitted defaults to 50. */
39
+ limit?: number;
40
+ /** 0 means no time limit; omitted means no time limit. */
41
+ sinceHours?: number;
42
+ };
43
+ };
44
+ action: {
45
+ type: ContentTriggerActionType;
46
+ prompt: string;
47
+ };
48
+ }
9
49
  export interface OncallChat {
10
50
  /** Lark chat_id (oc_xxx) the bot was pulled into. */
11
51
  chatId: string;
@@ -333,19 +373,28 @@ export interface BotConfig {
333
373
  regularGroupReplyMode?: ChatReplyMode;
334
374
  /**
335
375
  * Per-bot (bot-global) policy for when an @mention is required to get a reply
336
- * in regular Lark groups — a 3-tier ladder:
376
+ * in regular Lark groups — a 4-tier ladder:
337
377
  * • 'always' (or undefined) — @ required everywhere, including inside the
338
378
  * bot's own shared topics (the safe default).
339
379
  * • 'topic' — @ required to start / at top level, but NOT
340
380
  * inside the bot's shared topics (non-@ replies
341
381
  * there continue the session).
342
- * • 'never' — @ never required: non-@ messages in groups
343
- * where the bot has talk access are answered too.
382
+ * • 'never' — @ never required: every non-@ message in groups
383
+ * where the bot has talk access is answered too,
384
+ * unconditionally. For dedicated / on-call groups.
385
+ * • 'ambient' — like 'never' (non-@ messages answered), EXCEPT
386
+ * when the message @mentions another specific
387
+ * member (person/bot) without @ing this bot —
388
+ * that is a redirect to someone else, so the bot
389
+ * stays quiet (@all is not a redirect). Best for
390
+ * multi-bot / multi-person groups: a default
391
+ * responder that yields when you address someone
392
+ * else.
344
393
  * Governs the shared-topic fold-back + the top-level @ gate. `new-topic` /
345
394
  * 话题群 topics own their own thread and continue without @ regardless (that
346
395
  * is the mode's defining behavior, not affected by this policy).
347
396
  */
348
- regularGroupMentionMode?: 'always' | 'topic' | 'never';
397
+ regularGroupMentionMode?: 'always' | 'topic' | 'never' | 'ambient';
349
398
  /**
350
399
  * 飞书文档订阅入口(/subscribe-lark-doc)新订阅的默认评论触发范围:
351
400
  * • 'mention-only'(或 undefined)— 仅评论里 @bot 才触发(默认,防噪声)
@@ -353,6 +402,13 @@ export interface BotConfig {
353
402
  * 单条订阅的触发范围之后可在 dashboard 逐文档改(doc-subscriptions 表)。
354
403
  */
355
404
  docSubscribeDefaultMode?: 'mention-only' | 'all';
405
+ /** Per-bot range for explicit `@bot /summary`; defaults to 50 messages / 24h. */
406
+ summaryRange?: SummaryRangeConfig;
407
+ /**
408
+ * Legacy content/keyword trigger config. Kept parseable for config
409
+ * compatibility, but message routing no longer fires non-@ content triggers.
410
+ */
411
+ contentTriggers?: ContentTriggerConfig[];
356
412
  /**
357
413
  * Per-bot voice-engine override for the voice-summary feature. Merged OVER
358
414
  * the global `voice` block in ~/.botmux/config.json (per-bot wins field by
@@ -371,6 +427,7 @@ export interface BotState {
371
427
  /** raw allowedUsers 条目 → 解析后的 open_id。供 /revoke 反查并删除 email 形式的 raw 条目。 */
372
428
  rawAllowedUserResolution: Map<string, string>;
373
429
  }
430
+ export declare function __testOnly_resetBotRegistry(): void;
374
431
  export declare function getLoadedConfigPath(): string | undefined;
375
432
  /**
376
433
  * Condense a Lark SDK error into one readable line, preserving just the fields
@@ -1 +1 @@
1
- {"version":3,"file":"bot-registry.d.ts","sourceRoot":"","sources":["../src/bot-registry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bot-registry.d.ts","sourceRoot":"","sources":["../src/bot-registry.ts"],"names":[],"mappings":"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"}
@@ -21,7 +21,161 @@ function normalizeChatReplyModeConfig(raw) {
21
21
  return 'shared';
22
22
  return undefined;
23
23
  }
24
+ function normalizeContentTriggerScope(raw) {
25
+ if (typeof raw !== 'string')
26
+ return undefined;
27
+ const v = raw.trim().toLowerCase();
28
+ if (v === 'both' || v === 'all')
29
+ return 'both';
30
+ if (v === 'topic' || v === 'thread' || v === 'topic-group' || v === 'topic_group')
31
+ return 'topic';
32
+ if (v === 'regulargroup' || v === 'regular-group' || v === 'regular_group' || v === 'group')
33
+ return 'regularGroup';
34
+ return undefined;
35
+ }
36
+ function normalizeNonNegativeInt(raw) {
37
+ if (typeof raw !== 'number')
38
+ return undefined;
39
+ if (!Number.isInteger(raw) || raw < 0)
40
+ return undefined;
41
+ return raw;
42
+ }
43
+ function normalizeSummaryRange(raw) {
44
+ if (!raw || typeof raw !== 'object' || Array.isArray(raw))
45
+ return undefined;
46
+ const entry = raw;
47
+ const out = {};
48
+ const limit = normalizeNonNegativeInt(entry.limit);
49
+ const sinceHours = normalizeNonNegativeInt(entry.sinceHours);
50
+ if (limit !== undefined)
51
+ out.limit = limit;
52
+ if (sinceHours !== undefined)
53
+ out.sinceHours = sinceHours;
54
+ return Object.keys(out).length > 0 ? out : undefined;
55
+ }
56
+ function normalizeContentTriggers(raw, botIndex) {
57
+ if (!Array.isArray(raw))
58
+ return undefined;
59
+ const out = [];
60
+ raw.forEach((item, triggerIndex) => {
61
+ const loc = `Bot config [${botIndex}] contentTriggers[${triggerIndex}]`;
62
+ const drop = (reason) => logger.warn(`${loc} ignored: ${reason}`);
63
+ if (!item || typeof item !== 'object' || Array.isArray(item)) {
64
+ drop('must be an object');
65
+ return;
66
+ }
67
+ const entry = item;
68
+ const name = typeof entry.name === 'string' && entry.name.trim()
69
+ ? entry.name.trim()
70
+ : `content-trigger-${triggerIndex + 1}`;
71
+ const enabled = entry.enabled !== false;
72
+ const scope = normalizeContentTriggerScope(entry.scope);
73
+ if (!scope) {
74
+ drop(`invalid scope ${JSON.stringify(entry.scope)}`);
75
+ return;
76
+ }
77
+ const matchRaw = entry.match;
78
+ if (!matchRaw || typeof matchRaw !== 'object' || Array.isArray(matchRaw)) {
79
+ drop('match must be an object');
80
+ return;
81
+ }
82
+ const match = matchRaw;
83
+ const type = match.type === 'keyword' || match.type === 'regex' ? match.type : undefined;
84
+ if (!type) {
85
+ drop(`invalid match.type ${JSON.stringify(match.type)}`);
86
+ return;
87
+ }
88
+ const pattern = typeof match.pattern === 'string' ? match.pattern : '';
89
+ if (!pattern) {
90
+ drop('match.pattern must be a non-empty string');
91
+ return;
92
+ }
93
+ const caseSensitive = match.caseSensitive === true;
94
+ if (type === 'regex') {
95
+ try {
96
+ // Validate only. Runtime recompiles defensively in case an in-memory
97
+ // config is mutated after startup.
98
+ new RegExp(pattern, caseSensitive ? 'u' : 'iu');
99
+ }
100
+ catch (err) {
101
+ drop(`invalid regex ${JSON.stringify(pattern)} (${err instanceof Error ? err.message : String(err)})`);
102
+ return;
103
+ }
104
+ }
105
+ const actionRaw = entry.action;
106
+ if (!actionRaw || typeof actionRaw !== 'object' || Array.isArray(actionRaw)) {
107
+ drop('action must be an object');
108
+ return;
109
+ }
110
+ const action = actionRaw;
111
+ if (action.type !== 'start-or-wake-session') {
112
+ drop(`invalid action.type ${JSON.stringify(action.type)}`);
113
+ return;
114
+ }
115
+ const prompt = typeof action.prompt === 'string' ? action.prompt.trim() : '';
116
+ if (!prompt) {
117
+ drop('action.prompt must be a non-empty string');
118
+ return;
119
+ }
120
+ const historyRaw = entry.history && typeof entry.history === 'object' && !Array.isArray(entry.history)
121
+ ? entry.history
122
+ : {};
123
+ const topicRaw = historyRaw.topic && typeof historyRaw.topic === 'object' && !Array.isArray(historyRaw.topic)
124
+ ? historyRaw.topic
125
+ : {};
126
+ const regularRaw = historyRaw.regularGroup && typeof historyRaw.regularGroup === 'object' && !Array.isArray(historyRaw.regularGroup)
127
+ ? historyRaw.regularGroup
128
+ : {};
129
+ const topicMode = topicRaw.mode === undefined || topicRaw.mode === 'current-thread'
130
+ ? 'current-thread'
131
+ : undefined;
132
+ if (!topicMode) {
133
+ drop(`invalid history.topic.mode ${JSON.stringify(topicRaw.mode)}`);
134
+ return;
135
+ }
136
+ const regularMode = regularRaw.mode === undefined || regularRaw.mode === 'recent-messages'
137
+ ? 'recent-messages'
138
+ : undefined;
139
+ if (!regularMode) {
140
+ drop(`invalid history.regularGroup.mode ${JSON.stringify(regularRaw.mode)}`);
141
+ return;
142
+ }
143
+ const limit = regularRaw.limit === undefined ? 50 : normalizeNonNegativeInt(regularRaw.limit);
144
+ if (limit === undefined) {
145
+ drop(`invalid history.regularGroup.limit ${JSON.stringify(regularRaw.limit)}`);
146
+ return;
147
+ }
148
+ const sinceHours = regularRaw.sinceHours === undefined ? undefined : normalizeNonNegativeInt(regularRaw.sinceHours);
149
+ if (regularRaw.sinceHours !== undefined && sinceHours === undefined) {
150
+ drop(`invalid history.regularGroup.sinceHours ${JSON.stringify(regularRaw.sinceHours)}`);
151
+ return;
152
+ }
153
+ out.push({
154
+ name,
155
+ enabled,
156
+ scope,
157
+ ...(entry.allowBotMessages === true ? { allowBotMessages: true } : {}),
158
+ match: { type, pattern, caseSensitive },
159
+ history: {
160
+ topic: { mode: 'current-thread' },
161
+ regularGroup: {
162
+ mode: 'recent-messages',
163
+ limit,
164
+ sinceHours,
165
+ },
166
+ },
167
+ action: { type: 'start-or-wake-session', prompt },
168
+ });
169
+ });
170
+ return out.length > 0 ? out : undefined;
171
+ }
24
172
  const bots = new Map();
173
+ export function __testOnly_resetBotRegistry() {
174
+ bots.clear();
175
+ loadedConfigPath = undefined;
176
+ oncallChatCache = null;
177
+ brandLabelCache = null;
178
+ }
25
179
  // Wire the i18n lookup so `localeForBot()` can resolve per-bot locale without
26
180
  // a hard import cycle between `i18n` and `bot-registry`.
27
181
  setBotLookup((id) => bots.get(id));
@@ -480,6 +634,8 @@ export function parseBotConfigsFromText(jsonText) {
480
634
  const sanitizedEnv = sanitizePerBotEnv(entry.env);
481
635
  const env = Object.keys(sanitizedEnv).length > 0 ? sanitizedEnv : undefined;
482
636
  const skills = readBotSkillPolicy(entry.skills);
637
+ const summaryRange = normalizeSummaryRange(entry.summaryRange ?? entry.summary);
638
+ const contentTriggers = normalizeContentTriggers(entry.contentTriggers, i);
483
639
  // voice:per-bot 语音引擎覆盖。结构化保留(engine ∈ sami|openai,sami/openai
484
640
  // 为对象,speaker/rate 透传);非对象或 engine 非法 → undefined。深度校验
485
641
  // (凭证是否可用)在 resolveVoiceConfig 做,这里只挡明显垃圾。
@@ -589,14 +745,19 @@ export function parseBotConfigsFromText(jsonText) {
589
745
  const mode = normalizeChatReplyModeConfig(entry.regularGroupReplyMode);
590
746
  return mode === 'new-topic' || mode === 'shared' || mode === 'chat-topic' ? mode : undefined;
591
747
  })(),
592
- // 3-tier @ policy. Only 'topic' | 'never' are meaningful; 'always' (the
593
- // default) and anything else normalize to undefined so bots.json stays clean.
594
- regularGroupMentionMode: entry.regularGroupMentionMode === 'topic' || entry.regularGroupMentionMode === 'never'
748
+ // 4-tier @ policy. Only 'topic' | 'never' | 'ambient' are meaningful;
749
+ // 'always' (the default) and anything else normalize to undefined so
750
+ // bots.json stays clean.
751
+ regularGroupMentionMode: entry.regularGroupMentionMode === 'topic'
752
+ || entry.regularGroupMentionMode === 'never'
753
+ || entry.regularGroupMentionMode === 'ambient'
595
754
  ? entry.regularGroupMentionMode
596
755
  : undefined,
597
756
  // 文档订阅默认触发范围。只 'all' 有意义;'mention-only'(默认)归一化为
598
757
  // undefined 让 bots.json 保持干净。
599
758
  docSubscribeDefaultMode: entry.docSubscribeDefaultMode === 'all' ? 'all' : undefined,
759
+ summaryRange,
760
+ contentTriggers,
600
761
  voice,
601
762
  });
602
763
  }