botmux 2.49.0 → 2.50.0

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 CHANGED
@@ -72,7 +72,7 @@ Compared to OpenClaw-style approaches built on Agent SDKs:
72
72
 
73
73
  ## 5-Minute Setup
74
74
 
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.
75
+ > 💡 **TL;DR**: `npm i -g botmux` → `botmux setup` and **scan two QR codes** to get a working bot → `botmux start`. The 1st scan creates the app and saves the AppID/AppSecret (event subscriptions + bot capability pre-configured); the 2nd scan lets botmux's built-in Feishu Web login **import permissions, configure the redirect URL, and create + submit a publish version automatically**. Steps 4 (permissions) / 5 (redirect) / 6 (publish) below are all done automatically by setup and folded as a manual fallback; pass `--no-open-platform-auto` to skip the second auto-config step.
76
76
 
77
77
  ### Step 1: Install botmux
78
78
 
@@ -107,6 +107,11 @@ botmux start
107
107
 
108
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
109
 
110
+ <details>
111
+ <summary><b>Manual Open Platform config: permissions / redirect / publish (fallback)</b> —— botmux setup does these automatically (during the 2nd scan); expand only if auto-config failed or you want to verify manually</summary>
112
+
113
+ <br>
114
+
110
115
  ### Step 4: Add Permissions
111
116
 
112
117
  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.
@@ -144,6 +149,8 @@ Go to "Version Management & Release", click "Create Version" and publish. Set av
144
149
 
145
150
  ![Publish](docs/setup/publish.png)
146
151
 
152
+ </details>
153
+
147
154
  ### Step 7: Create a Group and Start Chatting
148
155
 
149
156
  1. Create a **topic-enabled group** in Lark
package/README.md CHANGED
@@ -179,7 +179,7 @@ CLI 进入 botmux 会话时自动获得 `~/.botmux/bin` 在 PATH 中,以及一
179
179
 
180
180
  ## 5 分钟快速接入
181
181
 
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 文件 + 打印一键复制命令 + 各步骤的深链。
182
+ > 💡 **TL;DR**:`npm i -g botmux` → `botmux setup`,**扫两次码**就能建好一个可用机器人 → `botmux start`。第 1 次扫码建应用、拿到 AppID/AppSecret(事件订阅 + bot 能力默认已配好);第 2 次扫码让 botmux 内置的飞书 Web 登录**自动导入权限、配置重定向 URL、创建并提交发布版本**。下面的 Step 4 权限 / Step 5 重定向 / Step 6 发版都已由 setup 默认自动完成、折叠为手动备用;加 `--no-open-platform-auto` 可跳过第二次自动配置、改走手动。
183
183
 
184
184
  ### Step 1: 安装 botmux
185
185
 
@@ -214,6 +214,11 @@ botmux start
214
214
 
215
215
  > start 前再校验一次凭证;权限未配齐不会阻塞 daemon,只 WARN。如果之后需要确认事件订阅,飞书后台会要求 daemon 已在跑才能识别长连接。
216
216
 
217
+ <details>
218
+ <summary><b>手动配置开放平台:权限 / 重定向 / 发版(备用)</b> —— 这三步 botmux setup 默认已自动完成(扫第二次码时),仅在自动配置失败、或想手动核对时展开</summary>
219
+
220
+ <br>
221
+
217
222
  ### Step 4: 添加权限
218
223
 
219
224
  setup 完成后,按 terminal 提示的一键复制命令把权限 JSON 复制到剪贴板,进入「权限管理」→「批量导入/导出权限」粘贴 → 提交审批。可用性范围选「仅自己可见」会自动通过:
@@ -251,6 +256,8 @@ http://127.0.0.1:9768/callback
251
256
 
252
257
  ![发版](docs/setup/publish.png)
253
258
 
259
+ </details>
260
+
254
261
  ### Step 7: 建群开聊
255
262
 
256
263
  1. 飞书中创建一个**话题群**
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
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"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAo/GA;;;;;;;;;;;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
@@ -4,6 +4,7 @@
4
4
  *
5
5
  * Usage:
6
6
  * botmux setup — interactive first-time configuration
7
+ * botmux setup --no-open-platform-auto — skip Feishu Open Platform automation
7
8
  * botmux start — start daemon (pm2)
8
9
  * botmux stop — stop daemon
9
10
  * botmux restart — restart daemon (auto-restores sessions)
@@ -262,7 +263,22 @@ function hasConfig() {
262
263
  return existsSync(BOTS_JSON_FILE) || existsSync(ENV_FILE);
263
264
  }
264
265
  function ask(rl, question) {
265
- return new Promise(resolve => rl.question(question, resolve));
266
+ return new Promise((resolve, reject) => {
267
+ const onError = (err) => {
268
+ rl.off("error", onError);
269
+ if (err?.code === "EIO") {
270
+ console.warn("\nWarning: interactive input stream closed (EIO); continuing with empty input.");
271
+ resolve("");
272
+ return;
273
+ }
274
+ reject(err);
275
+ };
276
+ rl.once("error", onError);
277
+ rl.question(question, answer => {
278
+ rl.off("error", onError);
279
+ resolve(answer);
280
+ });
281
+ });
266
282
  }
267
283
  // ─── Setup helpers ──────────────────────────────────────────────────────────
268
284
  function printInputHelp(title, lines) {
@@ -425,6 +441,43 @@ function printRemainingSteps(appId, brand) {
425
441
  console.log(' 完成后 `botmux start` (或 `botmux restart`),启动检查不会卡住,');
426
442
  console.log(' 缺权限只 WARN,去开放平台补齐后 daemon 自动恢复。\n');
427
443
  }
444
+ async function finishOpenPlatformSetup(appId, brand) {
445
+ const { parseSetupOpenPlatformAutoFlag, automateOpenPlatformSetup } = await import('./setup/open-platform-automation.js');
446
+ if (!parseSetupOpenPlatformAutoFlag(process.argv.slice(3))) {
447
+ console.log('\n已跳过开放平台自动配置 (--no-open-platform-auto)。');
448
+ printRemainingSteps(appId, brand);
449
+ return;
450
+ }
451
+ console.log('\n── 开放平台自动配置 ──\n');
452
+ console.log('将使用 botmux 内置 Feishu Web QR 登录获取/复用 Web session,自动导入权限、配置 redirect URL 并创建/发布版本。');
453
+ console.log('如失败会自动回退到手动步骤提示,不影响已写入的 botmux 配置。\n');
454
+ const result = await automateOpenPlatformSetup({ appId, brand });
455
+ if (result.ok) {
456
+ console.log('✅ 开放平台自动配置完成');
457
+ console.log(` Session 来源: ${result.sessionSource}`);
458
+ const skipped = result.skippedScopeCount ?? 0;
459
+ console.log(` 已导入权限数: ${result.scopeCount}${skipped > 0 ? `(另有 ${skipped} 项当前租户目录中没有,已跳过)` : ''}`);
460
+ if (result.scopeWarning) {
461
+ console.log(` ⚠️ 权限注册未全部成功(部分租户对个别权限有限制):${result.scopeWarning}`);
462
+ console.log(' 可稍后到开放平台「权限管理」手动补齐缺失权限。');
463
+ }
464
+ else if (result.scopeCount === 0) {
465
+ console.log(' ⚠️ 本次没有成功导入任何权限,请到开放平台「权限管理」手动导入 ~/.botmux/lark-scopes.json。');
466
+ }
467
+ console.log(` 已配置 redirect URL: http://127.0.0.1:9768/callback`);
468
+ if (result.versionId)
469
+ console.log(` 已提交发布版本: ${result.versionId}`);
470
+ else
471
+ console.log(' 已创建版本;未从响应中解析到 versionId,请到开放平台确认是否需要手动发布。');
472
+ console.log('');
473
+ return;
474
+ }
475
+ console.log(`⚠️ 开放平台自动配置失败 (${result.reason}): ${result.message}`);
476
+ if (result.sessionFile)
477
+ console.log(` botmux session 文件: ${result.sessionFile}`);
478
+ console.log(' 请按下面的手动步骤继续完成开放平台配置。');
479
+ printRemainingSteps(appId, brand);
480
+ }
428
481
  /**
429
482
  * 让用户选"扫码建应用"还是"手动粘 AppID/Secret".
430
483
  *
@@ -763,7 +816,7 @@ async function writeSingleBotConfig() {
763
816
  return false;
764
817
  writeBotsJsonAtomic([bot]);
765
818
  console.log(`\n✅ 配置已写入: ${BOTS_JSON_FILE}`);
766
- printRemainingSteps(bot.larkAppId, botBrand(bot));
819
+ await finishOpenPlatformSetup(bot.larkAppId, botBrand(bot));
767
820
  console.log(`下一步:`);
768
821
  console.log(` 1. botmux start 启动 daemon`);
769
822
  console.log(` 2. botmux autostart enable 注册开机自启(推荐:${process.platform === 'darwin' ? 'mac launchd' : process.platform === 'linux' ? 'linux user systemd' : '当前平台暂不支持'},无需 sudo)`);
@@ -800,7 +853,7 @@ async function cmdSetup() {
800
853
  console.log(`旧配置已备份: ${BOTS_JSON_FILE}.bak`);
801
854
  writeBotsJsonAtomic([newBot]);
802
855
  console.log(`✅ 配置已写入: ${BOTS_JSON_FILE}`);
803
- printRemainingSteps(newBot.larkAppId, botBrand(newBot));
856
+ await finishOpenPlatformSetup(newBot.larkAppId, botBrand(newBot));
804
857
  console.log(`下一步: botmux restart\n`);
805
858
  return;
806
859
  }
@@ -855,7 +908,7 @@ async function cmdSetup() {
855
908
  // appId 切换 = 换了一个飞书应用, 新 appId 大概率需要重新申请权限 + 配重定向 URL.
856
909
  // 把 printRemainingSteps 的深链端给用户, 比 README 警告里那句"历史数据不迁移"更可操作.
857
910
  if (appIdChanged) {
858
- printRemainingSteps(edited.larkAppId, botBrand(edited));
911
+ await finishOpenPlatformSetup(edited.larkAppId, botBrand(edited));
859
912
  }
860
913
  console.log(`下一步: botmux restart\n`);
861
914
  return;
@@ -892,7 +945,7 @@ async function cmdSetup() {
892
945
  writeBotsJsonAtomic([...bots, newBot]);
893
946
  console.log(`\n✅ 已添加机器人 ${newBot.larkAppId},共 ${bots.length + 1} 个`);
894
947
  console.log(` 配置文件: ${BOTS_JSON_FILE}`);
895
- printRemainingSteps(newBot.larkAppId, botBrand(newBot));
948
+ await finishOpenPlatformSetup(newBot.larkAppId, botBrand(newBot));
896
949
  console.log(`下一步: botmux restart\n`);
897
950
  }
898
951
  else if (hasEnv) {
@@ -931,7 +984,7 @@ async function cmdSetup() {
931
984
  console.log(`\n✅ 已迁移到多机器人配置`);
932
985
  console.log(` 配置文件: ${BOTS_JSON_FILE}`);
933
986
  console.log(` 旧配置已备份: ${ENV_FILE}.bak`);
934
- printRemainingSteps(newBot.larkAppId, botBrand(newBot));
987
+ await finishOpenPlatformSetup(newBot.larkAppId, botBrand(newBot));
935
988
  console.log(`下一步: botmux restart\n`);
936
989
  }
937
990
  else {
@@ -2087,6 +2140,7 @@ botmux v${getVersion()} — IM ↔ AI 编程 CLI 桥接
2087
2140
 
2088
2141
  命令:
2089
2142
  setup 交互式配置(首次使用 / 添加机器人)
2143
+ 默认使用 botmux 内置 Feishu Web QR 登录尝试自动导入权限/redirect/发布版本;可加 --no-open-platform-auto 跳过
2090
2144
  start 启动 daemon
2091
2145
  stop 停止 daemon
2092
2146
  restart 重启 daemon(自动恢复活跃会话)