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.
- package/README.en.md +4 -4
- package/README.md +3 -3
- package/dist/adapters/backend/tmux-backend.d.ts.map +1 -1
- package/dist/adapters/backend/tmux-backend.js +6 -10
- package/dist/adapters/backend/tmux-backend.js.map +1 -1
- package/dist/adapters/cli/kimi.d.ts +4 -0
- package/dist/adapters/cli/kimi.d.ts.map +1 -0
- package/dist/adapters/cli/kimi.js +54 -0
- package/dist/adapters/cli/kimi.js.map +1 -0
- package/dist/adapters/cli/registry.d.ts +2 -1
- package/dist/adapters/cli/registry.d.ts.map +1 -1
- package/dist/adapters/cli/registry.js +6 -20
- package/dist/adapters/cli/registry.js.map +1 -1
- package/dist/adapters/cli/types.d.ts +1 -1
- package/dist/adapters/cli/types.d.ts.map +1 -1
- package/dist/adapters/hook-installer.d.ts.map +1 -1
- package/dist/adapters/hook-installer.js +138 -28
- package/dist/adapters/hook-installer.js.map +1 -1
- package/dist/bot-registry.d.ts +61 -4
- package/dist/bot-registry.d.ts.map +1 -1
- package/dist/bot-registry.js +164 -3
- package/dist/bot-registry.js.map +1 -1
- package/dist/cli/stdin-encoding.d.ts +21 -0
- package/dist/cli/stdin-encoding.d.ts.map +1 -1
- package/dist/cli/stdin-encoding.js +37 -0
- package/dist/cli/stdin-encoding.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +14 -4
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +18 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +27 -0
- package/dist/config.js.map +1 -1
- package/dist/core/ask-hook/opencode.d.ts +15 -17
- package/dist/core/ask-hook/opencode.d.ts.map +1 -1
- package/dist/core/ask-hook/opencode.js +17 -19
- package/dist/core/ask-hook/opencode.js.map +1 -1
- package/dist/core/command-handler.d.ts.map +1 -1
- package/dist/core/command-handler.js +1 -0
- package/dist/core/command-handler.js.map +1 -1
- package/dist/core/dashboard-ipc-server.d.ts.map +1 -1
- package/dist/core/dashboard-ipc-server.js +193 -5
- package/dist/core/dashboard-ipc-server.js.map +1 -1
- package/dist/core/dashboard-rows.d.ts +2 -0
- package/dist/core/dashboard-rows.d.ts.map +1 -1
- package/dist/core/dashboard-rows.js +2 -0
- package/dist/core/dashboard-rows.js.map +1 -1
- package/dist/core/trigger-session.d.ts.map +1 -1
- package/dist/core/trigger-session.js +99 -7
- package/dist/core/trigger-session.js.map +1 -1
- package/dist/core/types.d.ts +16 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/core/worker-pool.d.ts +1 -1
- package/dist/core/worker-pool.d.ts.map +1 -1
- package/dist/core/worker-pool.js +68 -11
- package/dist/core/worker-pool.js.map +1 -1
- package/dist/dashboard/bot-payload.d.ts +7 -0
- package/dist/dashboard/bot-payload.d.ts.map +1 -1
- package/dist/dashboard/bot-payload.js +7 -1
- package/dist/dashboard/bot-payload.js.map +1 -1
- package/dist/dashboard/session-cleanup.d.ts +1 -0
- package/dist/dashboard/session-cleanup.d.ts.map +1 -1
- package/dist/dashboard/session-cleanup.js +2 -0
- package/dist/dashboard/session-cleanup.js.map +1 -1
- package/dist/dashboard/settings-write-applier.d.ts +2 -1
- package/dist/dashboard/settings-write-applier.d.ts.map +1 -1
- package/dist/dashboard/settings-write-applier.js +6 -0
- package/dist/dashboard/settings-write-applier.js.map +1 -1
- package/dist/dashboard/trigger-api.d.ts +4 -0
- package/dist/dashboard/trigger-api.d.ts.map +1 -1
- package/dist/dashboard/trigger-api.js +20 -0
- package/dist/dashboard/trigger-api.js.map +1 -1
- package/dist/dashboard/web/bot-defaults.d.ts +1 -0
- package/dist/dashboard/web/bot-defaults.d.ts.map +1 -1
- package/dist/dashboard/web/bot-defaults.js +247 -4
- package/dist/dashboard/web/bot-defaults.js.map +1 -1
- package/dist/dashboard/web/connectors.d.ts +11 -0
- package/dist/dashboard/web/connectors.d.ts.map +1 -1
- package/dist/dashboard/web/connectors.js +45 -1
- package/dist/dashboard/web/connectors.js.map +1 -1
- package/dist/dashboard/web/groups.d.ts +7 -0
- package/dist/dashboard/web/groups.d.ts.map +1 -1
- package/dist/dashboard/web/groups.js +62 -15
- package/dist/dashboard/web/groups.js.map +1 -1
- package/dist/dashboard/web/i18n.d.ts.map +1 -1
- package/dist/dashboard/web/i18n.js +58 -2
- package/dist/dashboard/web/i18n.js.map +1 -1
- package/dist/dashboard/web/sessions.d.ts.map +1 -1
- package/dist/dashboard/web/sessions.js +149 -5
- package/dist/dashboard/web/sessions.js.map +1 -1
- package/dist/dashboard/web/settings.d.ts.map +1 -1
- package/dist/dashboard/web/settings.js +10 -0
- package/dist/dashboard/web/settings.js.map +1 -1
- package/dist/dashboard/webhook-routes.d.ts.map +1 -1
- package/dist/dashboard/webhook-routes.js +126 -6
- package/dist/dashboard/webhook-routes.js.map +1 -1
- package/dist/dashboard-web/app.js +827 -751
- package/dist/dashboard-web/style.css +47 -0
- package/dist/dashboard.js +85 -6
- package/dist/dashboard.js.map +1 -1
- package/dist/global-config.d.ts +4 -0
- package/dist/global-config.d.ts.map +1 -1
- package/dist/global-config.js +2 -0
- package/dist/global-config.js.map +1 -1
- package/dist/i18n/en.d.ts.map +1 -1
- package/dist/i18n/en.js +1 -0
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/zh.d.ts.map +1 -1
- package/dist/i18n/zh.js +1 -0
- package/dist/i18n/zh.js.map +1 -1
- package/dist/im/lark/card-builder.d.ts.map +1 -1
- package/dist/im/lark/card-builder.js +1 -0
- package/dist/im/lark/card-builder.js.map +1 -1
- package/dist/im/lark/client.d.ts +12 -0
- package/dist/im/lark/client.d.ts.map +1 -1
- package/dist/im/lark/client.js +154 -9
- package/dist/im/lark/client.js.map +1 -1
- package/dist/im/lark/event-dispatcher.d.ts +13 -0
- package/dist/im/lark/event-dispatcher.d.ts.map +1 -1
- package/dist/im/lark/event-dispatcher.js +200 -16
- package/dist/im/lark/event-dispatcher.js.map +1 -1
- package/dist/im/lark/message-parser.d.ts +11 -0
- package/dist/im/lark/message-parser.d.ts.map +1 -1
- package/dist/im/lark/message-parser.js +2 -1
- package/dist/im/lark/message-parser.js.map +1 -1
- package/dist/im/lark/summary-command.d.ts +19 -0
- package/dist/im/lark/summary-command.d.ts.map +1 -0
- package/dist/im/lark/summary-command.js +276 -0
- package/dist/im/lark/summary-command.js.map +1 -0
- package/dist/mir-local-runtime.d.ts +40 -0
- package/dist/mir-local-runtime.d.ts.map +1 -1
- package/dist/mir-local-runtime.js +246 -52
- package/dist/mir-local-runtime.js.map +1 -1
- package/dist/mir-runner.js +26 -1
- package/dist/mir-runner.js.map +1 -1
- package/dist/services/card-prefs-store.d.ts +2 -2
- package/dist/services/card-prefs-store.d.ts.map +1 -1
- package/dist/services/card-prefs-store.js +5 -5
- package/dist/services/card-prefs-store.js.map +1 -1
- package/dist/services/chat-reply-mode-store.d.ts +6 -4
- package/dist/services/chat-reply-mode-store.d.ts.map +1 -1
- package/dist/services/chat-reply-mode-store.js +6 -4
- package/dist/services/chat-reply-mode-store.js.map +1 -1
- package/dist/services/pi-transcript.d.ts +19 -0
- package/dist/services/pi-transcript.d.ts.map +1 -0
- package/dist/services/pi-transcript.js +222 -0
- package/dist/services/pi-transcript.js.map +1 -0
- package/dist/services/seen-message-store.d.ts +12 -0
- package/dist/services/seen-message-store.d.ts.map +1 -0
- package/dist/services/seen-message-store.js +119 -0
- package/dist/services/seen-message-store.js.map +1 -0
- package/dist/services/summary-range-store.d.ts +21 -0
- package/dist/services/summary-range-store.d.ts.map +1 -0
- package/dist/services/summary-range-store.js +89 -0
- package/dist/services/summary-range-store.js.map +1 -0
- package/dist/services/trigger-types.d.ts +14 -2
- package/dist/services/trigger-types.d.ts.map +1 -1
- package/dist/services/trigger-types.js +15 -1
- package/dist/services/trigger-types.js.map +1 -1
- package/dist/setup/bot-config-editor.d.ts.map +1 -1
- package/dist/setup/bot-config-editor.js +2 -0
- package/dist/setup/bot-config-editor.js.map +1 -1
- package/dist/types.d.ts +20 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/executable.d.ts +3 -0
- package/dist/utils/executable.d.ts.map +1 -0
- package/dist/utils/executable.js +24 -0
- package/dist/utils/executable.js.map +1 -0
- package/dist/worker.js +75 -6
- package/dist/worker.js.map +1 -1
- package/dist/workflows/definition.d.ts +8 -8
- package/dist/workflows/events/payloads.d.ts +10 -10
- package/dist/workflows/events/schema.d.ts +28 -28
- 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
|
-
*
|
|
143
|
-
* OpenCode
|
|
144
|
-
*
|
|
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
|
-
//
|
|
152
|
-
//
|
|
153
|
-
import {
|
|
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
|
-
|
|
156
|
-
|
|
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
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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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"}
|
package/dist/bot-registry.d.ts
CHANGED
|
@@ -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
|
|
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-@
|
|
343
|
-
* where the bot has talk access
|
|
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":"AAAA,OAAO,KAAK,IAAI,MAAM,yBAAyB,CAAC;AAIhD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAC;AAErD,OAAO,EAA0B,KAAK,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACtE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,KAAK,KAAK,EAA6B,MAAM,yBAAyB,CAAC;AAChF,OAAO,KAAK,EAAE,cAAc,EAAiB,MAAM,wBAAwB,CAAC;AAI5E,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,WAAW,GAAG,QAAQ,GAAG,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"bot-registry.d.ts","sourceRoot":"","sources":["../src/bot-registry.ts"],"names":[],"mappings":"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"}
|
package/dist/bot-registry.js
CHANGED
|
@@ -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
|
-
//
|
|
593
|
-
// default) and anything else normalize to undefined so
|
|
594
|
-
|
|
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
|
}
|