botmux 2.48.1 → 2.48.3

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 (46) hide show
  1. package/README.en.md +20 -22
  2. package/README.md +20 -21
  3. package/dist/cli.d.ts.map +1 -1
  4. package/dist/cli.js +23 -4
  5. package/dist/cli.js.map +1 -1
  6. package/dist/core/worker-pool.d.ts.map +1 -1
  7. package/dist/core/worker-pool.js +12 -1
  8. package/dist/core/worker-pool.js.map +1 -1
  9. package/dist/daemon.d.ts.map +1 -1
  10. package/dist/daemon.js +10 -6
  11. package/dist/daemon.js.map +1 -1
  12. package/dist/dashboard/bot-onboarding.d.ts.map +1 -1
  13. package/dist/dashboard/bot-onboarding.js +24 -2
  14. package/dist/dashboard/bot-onboarding.js.map +1 -1
  15. package/dist/dashboard/federation-spoke-api.d.ts +10 -4
  16. package/dist/dashboard/federation-spoke-api.d.ts.map +1 -1
  17. package/dist/dashboard/federation-spoke-api.js +38 -11
  18. package/dist/dashboard/federation-spoke-api.js.map +1 -1
  19. package/dist/dashboard/web/app.d.ts +1 -1
  20. package/dist/dashboard/web/app.d.ts.map +1 -1
  21. package/dist/dashboard/web/app.js +36 -0
  22. package/dist/dashboard/web/app.js.map +1 -1
  23. package/dist/dashboard/web/bot-defaults.d.ts.map +1 -1
  24. package/dist/dashboard/web/bot-defaults.js +131 -0
  25. package/dist/dashboard/web/bot-defaults.js.map +1 -1
  26. package/dist/dashboard/web/i18n.d.ts.map +1 -1
  27. package/dist/dashboard/web/i18n.js +16 -0
  28. package/dist/dashboard/web/i18n.js.map +1 -1
  29. package/dist/dashboard/web/team-federation.d.ts.map +1 -1
  30. package/dist/dashboard/web/team-federation.js +10 -12
  31. package/dist/dashboard/web/team-federation.js.map +1 -1
  32. package/dist/dashboard-web/app.js +226 -214
  33. package/dist/im/lark/client.d.ts.map +1 -1
  34. package/dist/im/lark/client.js +37 -2
  35. package/dist/im/lark/client.js.map +1 -1
  36. package/dist/services/mtr-transcript.d.ts +14 -0
  37. package/dist/services/mtr-transcript.d.ts.map +1 -0
  38. package/dist/services/mtr-transcript.js +291 -0
  39. package/dist/services/mtr-transcript.js.map +1 -0
  40. package/dist/setup/bot-config-editor.d.ts +5 -2
  41. package/dist/setup/bot-config-editor.d.ts.map +1 -1
  42. package/dist/setup/bot-config-editor.js +7 -4
  43. package/dist/setup/bot-config-editor.js.map +1 -1
  44. package/dist/worker.js +117 -5
  45. package/dist/worker.js.map +1 -1
  46. package/package.json +1 -1
package/README.en.md CHANGED
@@ -72,43 +72,41 @@ Compared to OpenClaw-style approaches built on Agent SDKs:
72
72
 
73
73
  ## 5-Minute Setup
74
74
 
75
- > 💡 **TL;DR**: run `botmux setup` and pick "scan-to-create" to finish Steps 1+2 in one shot (the official `@larksuiteoapi/node-sdk` device flow gives you the AppID/AppSecret). PersonalAgent apps come with event subscriptions and bot capability pre-configured, so only Step 4 (permissions) + Step 5 (optional redirect URL) + Step 6 (publish) require browser clicks; the setup wizard writes a JSON file with a one-line clipboard copy command and prints deep-links to each remaining step.
75
+ > 💡 **TL;DR**: `npm i -g botmux` → `botmux setup` and pick "scan-to-create" to get the AppID/AppSecret in one shot (Step 2) `botmux start`. PersonalAgent apps come with event subscriptions and bot capability pre-configured, so only Step 4 (permissions) + Step 5 (optional redirect URL) + Step 6 (publish) require browser clicks; the setup wizard writes a JSON file with a one-line clipboard copy command and prints deep-links to each remaining step.
76
76
 
77
- ### Step 1: Create a Lark App
77
+ ### Step 1: Install botmux
78
78
 
79
- **Recommended**: `botmux setup` → pick "1) Scan-to-create app". Scan with the Lark mobile app and the AppID/AppSecret are persisted automatically; no manual browser navigation. Falls back to manual paste on cancel/timeout/network error.
79
+ ```bash
80
+ npm install -g botmux
81
+ ```
80
82
 
81
- > ⚠️ **Currently only Feishu (feishu.cn) tenants are supported.** If scan detects a Lark international (larksuite.com) tenant, setup aborts — the daemon runtime (Lark Client/WSClient/event-dispatcher) hasn't been wired up for the `larksuite.com` domain yet, so accepting Lark credentials would land users in a half-working state. A follow-up PR will add full Lark support.
83
+ > Requires **Node.js 20**, with at least one AI coding CLI installed and authenticated (`claude` / `codex` / `cursor-agent` / `gemini` / `opencode` / `coco` / `agy` on your PATH). Installing **tmux** too is recommended (enables session persistence automatically).
82
84
 
83
- **Manual**: go to the [Lark Open Platform](https://open.larkoffice.com/app) and click "Create Custom App".
85
+ ### Step 2: Create the App & Configure (`botmux setup`)
84
86
 
85
- ![Create App](docs/setup/create-app.png)
87
+ Run `botmux setup` and follow the interactive menu:
86
88
 
87
- ### Step 2: Get Credentials
89
+ 1. **New config**: type `1` and press Enter (with an existing config, type `2` to add a bot).
90
+ 2. **Create the bot**:
91
+ - Type `1` → **Scan-to-create (recommended)**: scan with the Lark mobile app and a PersonalAgent app is created with AppID/AppSecret persisted automatically, **with event subscriptions + bot capability pre-configured** — no manual browser navigation. Uses the official `@larksuiteoapi/node-sdk` device flow.
92
+ - Type `2` → **Manual**: go to the [Lark Open Platform](https://open.larkoffice.com/app), create a "Custom App", copy **App ID / App Secret** from "Credentials & Basic Info", and paste them back.
93
+ 3. **Pick the CLI**: choose the CLI to bridge (e.g. type `1` for Claude Code).
94
+ 4. **Default working dir**: usually the **parent directory** of your git projects (e.g. `~/projects`); new topics scan **downward** for git repos (up to 3 levels). Avoid `~` (too many folders to traverse).
88
95
 
89
- > The scan-to-create path completes this step automatically; skip to Step 3.
96
+ > ⚠️ **Currently only Feishu (feishu.cn) tenants are supported.** If scan detects a Lark international (larksuite.com) tenant, setup aborts — the daemon runtime (Lark Client/WSClient/event-dispatcher) hasn't been wired up for the `larksuite.com` domain yet. A follow-up PR will add full Lark support.
90
97
 
91
- Open the app details page "Credentials & Basic Info", and copy the **App ID** and **App Secret**.
98
+ At the end, setup validates credentials with a `tenant_access_token` call (only writing `bots.json` on success), writes the full scope JSON to `~/.botmux/lark-scopes.json`, and prints a one-line clipboard copy command plus deep-links to each remaining step.
92
99
 
93
- ![Get Credentials](docs/setup/credentials.png)
100
+ ![Create App](docs/setup/create-app.png)
94
101
 
95
- ### Step 3: Install & Start botmux
102
+ ### Step 3: Start
96
103
 
97
104
  ```bash
98
- # Install
99
- npm install -g botmux
100
-
101
- # Interactive setup — pick "1) Scan-to-create app" or "2) Paste AppID/Secret manually".
102
- # Credentials are validated with a tenant_access_token call before bots.json is written.
103
- # At the end of setup the wizard writes the full scope JSON to ~/.botmux/lark-scopes.json
104
- # and prints a one-line clipboard copy command for your platform.
105
- botmux setup
106
-
107
- # Start (if you ever need to verify the event subscription, Lark requires the daemon to be running so it can detect the WebSocket connection)
108
- # Re-validates credentials before forking workers; missing scopes only WARN, do not block the daemon.
109
105
  botmux start
110
106
  ```
111
107
 
108
+ > `start` re-validates credentials before forking workers; missing scopes only WARN, they don't block the daemon. If you later need to verify the event subscription, Lark requires the daemon to be running so it can detect the WebSocket connection.
109
+
112
110
  ### Step 4: Add Permissions
113
111
 
114
112
  Run the copy-to-clipboard command setup printed, then go to "Permissions & Scopes" → "Batch Import/Export" and paste. Submit for review — visibility "only me" auto-approves.
package/README.md CHANGED
@@ -179,42 +179,41 @@ CLI 进入 botmux 会话时自动获得 `~/.botmux/bin` 在 PATH 中,以及一
179
179
 
180
180
  ## 5 分钟快速接入
181
181
 
182
- > 💡 **TL;DR**:跑 `botmux setup` 选「扫码建应用」一步完成 Step 1+2(拿 AppID/AppSecret)。PersonalAgent 应用建出来时事件订阅和 bot 能力都已默认配好,只剩 Step 4 权限申请 + Step 5(按需)重定向 URL + Step 6 发版三步要在浏览器手动点;setup 完成后会自动写 JSON 文件 + 打印一键复制命令 + 各步骤的深链。
182
+ > 💡 **TL;DR**:`npm i -g botmux` → `botmux setup` 选「扫码建应用」一步拿到 AppID/AppSecret(Step 2)→ `botmux start`。PersonalAgent 应用建出来时事件订阅和 bot 能力都已默认配好,只剩 Step 4 权限申请 + Step 5(按需)重定向 URL + Step 6 发版三步要在浏览器手动点;setup 完成后会自动写 JSON 文件 + 打印一键复制命令 + 各步骤的深链。
183
183
 
184
- ### Step 1: 创建飞书应用
184
+ ### Step 1: 安装 botmux
185
185
 
186
- **推荐路径**:`botmux setup` 选「1) 扫码建应用」,飞书扫码完成后自动落盘 AppID/AppSecret,无需手动浏览器创建。底层走 `@larksuiteoapi/node-sdk` 的官方 device flow。
186
+ ```bash
187
+ npm install -g botmux
188
+ ```
187
189
 
188
- > ⚠️ **目前仅支持飞书 (feishu.cn) 租户**。扫码检测到 Lark 国际版 (larksuite.com) 会中止 setup —— daemon runtime (Lark Client/WSClient/event-dispatcher 等) 需要一并接入 lark 域,会在单独 PR 跟进。
190
+ > 要求 **Node.js 20**,且本地已装好并登录至少一种 AI 编程 CLI(`claude` / `codex` / `cursor-agent` / `gemini` / `opencode` / `coco` / `agy` 等在 PATH 中)。推荐顺手装 **tmux**(装了自动启用会话常驻)。
189
191
 
190
- **手动路径**:打开 [飞书开放平台](https://open.larkoffice.com/app),点击「创建企业自建应用」。
192
+ ### Step 2: 创建应用并配置(`botmux setup`)
191
193
 
192
- ![创建应用](docs/setup/create-app.png)
194
+ 跑 `botmux setup`,按交互菜单一步步选:
193
195
 
194
- ### Step 2: 获取凭证
196
+ 1. **新建配置**:输入 `1` 回车(已有配置时输入 `2` 添加机器人)。
197
+ 2. **创建机器人**:
198
+ - 输入 `1` → **扫码创建(推荐)**:飞书扫码完成后自动建出 PersonalAgent 应用并落盘 AppID/AppSecret,**事件订阅 + bot 能力默认已配好**,无需手动浏览器创建。底层走 `@larksuiteoapi/node-sdk` 官方 device flow。
199
+ - 输入 `2` → **手动创建**:去 [飞书开放平台](https://open.larkoffice.com/app) 建「企业自建应用」,在「凭证与基础信息」复制 **App ID / App Secret** 回来粘贴。
200
+ 3. **选择 CLI**:选本次要接入的 CLI(如接 Claude Code 就选 `1`)。
201
+ 4. **默认工作目录**:通常填 git 项目的**父级目录**(如 `~/projects`),新话题会从该目录**向下**查找 git 仓库(最多 3 层);尽量别填 `~`(要遍历太多文件夹)。
195
202
 
196
- > 扫码路径自动完成此步,可直接跳到 Step 3。
203
+ > ⚠️ **目前仅支持飞书 (feishu.cn) 租户**。扫码检测到 Lark 国际版 (larksuite.com) 会中止 setup —— daemon runtime (Lark Client/WSClient/event-dispatcher 等) 需要一并接入 lark 域,会在单独 PR 跟进。
197
204
 
198
- 进入应用详情 →「凭证与基础信息」,复制 **App ID** **App Secret**。
205
+ setup 末尾会用 `tenant_access_token` 校验凭证(通过才落盘 `bots.json`),并把完整权限 JSON 写到 `~/.botmux/lark-scopes.json` + 打印一键复制命令 + 各步骤深链。
199
206
 
200
- ![获取凭证](docs/setup/credentials.png)
207
+ ![扫码建应用](docs/setup/create-app.png)
201
208
 
202
- ### Step 3: 安装 & 启动 botmux
209
+ ### Step 3: 启动
203
210
 
204
211
  ```bash
205
- # 安装
206
- npm install -g botmux
207
-
208
- # 交互式配置 — 选「1) 扫码建应用」或「2) 手动粘 AppID/Secret」
209
- # 凭证拿到后自动取一次 tenant_access_token 校验,通过才落盘 bots.json
210
- # setup 末尾会把完整权限 JSON 写到 ~/.botmux/lark-scopes.json 并打印一键复制命令
211
- botmux setup
212
-
213
- # 启动(如果之后需要确认事件订阅,飞书后台会要求 daemon 已在跑才能识别长连接)
214
- # start 前再校验一次凭证;权限未配齐不会阻塞 daemon,只 WARN
215
212
  botmux start
216
213
  ```
217
214
 
215
+ > start 前再校验一次凭证;权限未配齐不会阻塞 daemon,只 WARN。如果之后需要确认事件订阅,飞书后台会要求 daemon 已在跑才能识别长连接。
216
+
218
217
  ### Step 4: 添加权限
219
218
 
220
219
  setup 完成后,按 terminal 提示的一键复制命令把权限 JSON 复制到剪贴板,进入「权限管理」→「批量导入/导出权限」粘贴 → 提交审批。可用性范围选「仅自己可见」会自动通过:
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AA46GA;;;;;;;;;;;GAWG;AACH,wBAAsB,OAAO,CAC3B,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,EACvC,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,OAAO,qBAAqB,EAAE,SAAS,CAAC,EAC9F,KAAK,EAAE,MAAM,EACb,mBAAmB,CAAC,EAAE,MAAM,OAAO,CAAC,OAAO,2BAA2B,EAAE,UAAU,GAAG,IAAI,CAAC,GACzF,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CA+F7B"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AA87GA;;;;;;;;;;;GAWG;AACH,wBAAsB,OAAO,CAC3B,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,EACvC,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,OAAO,qBAAqB,EAAE,SAAS,CAAC,EAC9F,KAAK,EAAE,MAAM,EACb,mBAAmB,CAAC,EAAE,MAAM,OAAO,CAAC,OAAO,2BAA2B,EAAE,UAAU,GAAG,IAAI,CAAC,GACzF,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CA+F7B"}
package/dist/cli.js CHANGED
@@ -493,15 +493,33 @@ async function obtainCredentials(rl) {
493
493
  }
494
494
  return { ok: true, appId, appSecret, brand: 'feishu' };
495
495
  }
496
+ /**
497
+ * 用指定应用凭证把 open_id (ou_) 解析成 union_id (on_,跨应用稳定)。
498
+ * 查询失败(无 contact 权限 / API 错误)则 fallback 返回原 open_id。
499
+ */
500
+ async function resolveOpenIdToUnionId(appId, appSecret, openId) {
501
+ try {
502
+ const { Client } = await import('@larksuiteoapi/node-sdk');
503
+ const client = new Client({ appId, appSecret });
504
+ const res = await client.contact.v3.user.get({
505
+ path: { user_id: openId },
506
+ params: { user_id_type: 'open_id' },
507
+ });
508
+ if (res.code === 0 && res.data?.user?.union_id)
509
+ return res.data.user.union_id;
510
+ }
511
+ catch { /* fallback */ }
512
+ return openId;
513
+ }
496
514
  /**
497
515
  * 手动建 bot 时(没有扫码人 open_id)必须指定至少一个 owner.
498
- * 循环追问直到给出合法条目(完整邮箱或 ou_ open_id),拒绝裸邮箱前缀与空输入.
516
+ * 循环追问直到给出合法条目(邮箱、union_id on_xxx open_id ou_xxx),拒绝裸邮箱前缀与空输入.
499
517
  * setup 不允许没有 owner —— 没 owner 的配置一旦叠加 allowedChatGroups 即成权限黑洞.
500
518
  */
501
519
  async function promptRequiredOwner(rl) {
502
520
  printInputHelp('管理员 (owner)', [
503
- '必填。至少一个能操作机器人的管理员,支持完整邮箱(如 alice@example.com)或 open_id(ou_xxx),多个值用逗号分隔。',
504
- '第一个 open_id(或可解析的邮箱)将作为 owner —— /restart、/close、/grant 等敏感操作只对 allowedUsers 开放。',
521
+ '必填。至少一个能操作机器人的管理员,多个值用逗号分隔。',
522
+ '推荐格式(优先级高到低):完整邮箱(alice@example.com)> union_id(on_xxx,跨应用稳定)> open_id(ou_xxx,仅限同一应用)。',
505
523
  '注意:必须是完整邮箱,邮箱前缀(如 alice)无法解析、不接受。',
506
524
  ]);
507
525
  for (;;) {
@@ -573,11 +591,12 @@ async function promptBotConfig(rl) {
573
591
  bot.model = modelChoice;
574
592
  }
575
593
  // 扫码场景默认填扫码人自己 (registerApp 返回里有 open_id), 天然就是 owner.
594
+ // 优先解析成 union_id (on_,跨应用稳定);失败则 fallback 到 open_id (ou_)。
576
595
  // 手动 fallback 场景没 open_id —— 必须显式指定 owner, 否则配置无 owner:
577
596
  // allowedUsers 为空时虽然"全开放", 但一旦后续加了 allowedChatGroups 就会变成
578
597
  // "群成员能对话却没人能做敏感操作 / 用 /grant". setup 阶段强制收口, 不允许没 owner.
579
598
  if (creds.userOpenId) {
580
- bot.allowedUsers = [creds.userOpenId];
599
+ bot.allowedUsers = [await resolveOpenIdToUnionId(creds.appId, creds.appSecret, creds.userOpenId)];
581
600
  }
582
601
  else {
583
602
  bot.allowedUsers = await promptRequiredOwner(rl);