botmux 2.85.0 → 2.85.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 (47) hide show
  1. package/dist/cli.d.ts.map +1 -1
  2. package/dist/cli.js +22 -13
  3. package/dist/cli.js.map +1 -1
  4. package/dist/daemon.d.ts.map +1 -1
  5. package/dist/daemon.js +4 -1
  6. package/dist/daemon.js.map +1 -1
  7. package/dist/dashboard/bot-onboarding.d.ts +24 -8
  8. package/dist/dashboard/bot-onboarding.d.ts.map +1 -1
  9. package/dist/dashboard/bot-onboarding.js +170 -49
  10. package/dist/dashboard/bot-onboarding.js.map +1 -1
  11. package/dist/dashboard/bot-payload.d.ts +43 -0
  12. package/dist/dashboard/bot-payload.d.ts.map +1 -0
  13. package/dist/dashboard/bot-payload.js +44 -0
  14. package/dist/dashboard/bot-payload.js.map +1 -0
  15. package/dist/dashboard/registry.d.ts +2 -0
  16. package/dist/dashboard/registry.d.ts.map +1 -1
  17. package/dist/dashboard/registry.js.map +1 -1
  18. package/dist/dashboard/web/bot-defaults.d.ts +1 -0
  19. package/dist/dashboard/web/bot-defaults.d.ts.map +1 -1
  20. package/dist/dashboard/web/bot-defaults.js +6 -3
  21. package/dist/dashboard/web/bot-defaults.js.map +1 -1
  22. package/dist/dashboard/web/bot-onboarding.d.ts.map +1 -1
  23. package/dist/dashboard/web/bot-onboarding.js +60 -4
  24. package/dist/dashboard/web/bot-onboarding.js.map +1 -1
  25. package/dist/dashboard/web/i18n.d.ts.map +1 -1
  26. package/dist/dashboard/web/i18n.js +14 -0
  27. package/dist/dashboard/web/i18n.js.map +1 -1
  28. package/dist/dashboard/web/overview.d.ts +22 -0
  29. package/dist/dashboard/web/overview.d.ts.map +1 -1
  30. package/dist/dashboard/web/overview.js +6 -1
  31. package/dist/dashboard/web/overview.js.map +1 -1
  32. package/dist/dashboard-web/app.js +261 -250
  33. package/dist/dashboard.js +58 -36
  34. package/dist/dashboard.js.map +1 -1
  35. package/dist/im/lark/client.d.ts.map +1 -1
  36. package/dist/im/lark/client.js +23 -1
  37. package/dist/im/lark/client.js.map +1 -1
  38. package/dist/im/lark/event-dispatcher.d.ts.map +1 -1
  39. package/dist/im/lark/event-dispatcher.js +16 -9
  40. package/dist/im/lark/event-dispatcher.js.map +1 -1
  41. package/dist/setup/cli-selection.d.ts +20 -1
  42. package/dist/setup/cli-selection.d.ts.map +1 -1
  43. package/dist/setup/cli-selection.js +45 -5
  44. package/dist/setup/cli-selection.js.map +1 -1
  45. package/dist/worker.js +10 -1
  46. package/dist/worker.js.map +1 -1
  47. package/package.json +1 -1
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AA86IA;;;;;;;;;;;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,CA8F7B"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AA47IA;;;;;;;;;;;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,CA8F7B"}
package/dist/cli.js CHANGED
@@ -531,10 +531,11 @@ async function obtainCredentials(rl) {
531
531
  return { ok: true, appId, appSecret, brand };
532
532
  }
533
533
  /**
534
- * 用指定应用凭证把 open_id (ou_) 解析成 union_id (on_,跨应用稳定)
535
- * 查询失败(无 contact 权限 / API 错误)则 fallback 返回原 open_id
534
+ * 用新应用自身凭证验证扫码链路拿到的 open_id。
535
+ * 能解析 union_id 时写 on_;没有 union_id open_id 对当前 app 有效时写 ou_
536
+ * 查询失败或用户不在当前 app 视角时返回 undefined,调用方不得 fallback 写入该 ou_。
536
537
  */
537
- async function resolveOpenIdToUnionId(appId, appSecret, openId, brand = 'feishu') {
538
+ async function resolveScannerAllowedUser(appId, appSecret, openId, brand = 'feishu') {
538
539
  try {
539
540
  const { Client } = await import('@larksuiteoapi/node-sdk');
540
541
  // brand → 域名。Lark 扫码人 ou_→on_ 必须打 larksuite.com,否则失败丢掉 cross-app 稳定性。
@@ -543,11 +544,12 @@ async function resolveOpenIdToUnionId(appId, appSecret, openId, brand = 'feishu'
543
544
  path: { user_id: openId },
544
545
  params: { user_id_type: 'open_id' },
545
546
  });
546
- if (res.code === 0 && res.data?.user?.union_id)
547
- return res.data.user.union_id;
547
+ if (res.code === 0 && res.data?.user) {
548
+ return res.data.user.union_id ?? openId;
549
+ }
548
550
  }
549
- catch { /* fallback */ }
550
- return openId;
551
+ catch { /* do not trust scanner open_id when verification fails */ }
552
+ return undefined;
551
553
  }
552
554
  /**
553
555
  * 手动建 bot 时(没有扫码人 open_id)必须指定至少一个 owner.
@@ -569,11 +571,11 @@ async function promptRequiredOwner(rl) {
569
571
  }
570
572
  const invalid = findInvalidAllowedUserEntries(entries);
571
573
  if (invalid.length > 0) {
572
- console.log(` ❌ 以下不是完整邮箱或 open_id(邮箱前缀不接受): ${invalid.join(', ')}`);
574
+ console.log(` ❌ 以下不是完整邮箱、union_id open_id(邮箱前缀不接受): ${invalid.join(', ')}`);
573
575
  continue;
574
576
  }
575
577
  if (!hasOwnerEntry(entries)) {
576
- console.log(' ❌ 至少需要一个 open_id 或完整邮箱作为 owner。');
578
+ console.log(' ❌ 至少需要一个完整邮箱、union_id open_id 作为 owner。');
577
579
  continue;
578
580
  }
579
581
  return entries;
@@ -633,13 +635,20 @@ async function promptBotConfig(rl) {
633
635
  }
634
636
  // setup 不再询问 model(用户常选到无权限的 model,setup 完一发消息就 spawn
635
637
  // 报错,排查成本高)。需要指定 model 走 /config 卡片或手动编辑 bots.json。
636
- // 扫码场景默认填扫码人自己 (registerApp 返回里有 open_id), 天然就是 owner.
637
- // 优先解析成 union_id (on_,跨应用稳定);失败则 fallback 到 open_id (ou_)
638
+ // 扫码场景默认填扫码人自己,但 registerApp 返回的 open_id 不能直接信任:
639
+ // 只有新 app 自身能验证时才写入 allowedUsers;验证失败则要求手动填写 owner
638
640
  // 手动 fallback 场景没 open_id —— 必须显式指定 owner, 否则配置无 owner:
639
641
  // allowedUsers 为空时虽然"全开放", 但一旦后续加了 allowedChatGroups 就会变成
640
642
  // "群成员能对话却没人能做敏感操作 / 用 /grant". setup 阶段强制收口, 不允许没 owner.
641
643
  if (creds.userOpenId) {
642
- bot.allowedUsers = [await resolveOpenIdToUnionId(creds.appId, creds.appSecret, creds.userOpenId, creds.brand)];
644
+ const owner = await resolveScannerAllowedUser(creds.appId, creds.appSecret, creds.userOpenId, creds.brand);
645
+ if (owner) {
646
+ bot.allowedUsers = [owner];
647
+ }
648
+ else {
649
+ console.log('⚠️ 无法确认扫码人的 open_id 属于当前新应用,请手动填写 owner。');
650
+ bot.allowedUsers = await promptRequiredOwner(rl);
651
+ }
643
652
  }
644
653
  else {
645
654
  bot.allowedUsers = await promptRequiredOwner(rl);
@@ -738,7 +747,7 @@ async function promptEditBotConfig(rl, bot) {
738
747
  ]);
739
748
  input.workingDir = await ask(rl, `默认工作目录 [${formatOptionalValue(bot.workingDir)}]: `);
740
749
  printInputHelp('允许的用户', [
741
- '可选。限制哪些飞书用户可以操作机器人,支持完整邮箱(如 alice@example.com)或 open_id(ou_xxx),多个值用逗号分隔。',
750
+ '可选。限制哪些飞书用户可以操作机器人,支持完整邮箱(如 alice@example.com)、union_id(on_xxx)或 open_id(ou_xxx),多个值用逗号分隔。',
742
751
  '注意:必须是完整邮箱,邮箱前缀(如 alice)无法解析、会被丢弃。',
743
752
  '留空保留当前值;输入 - 清空限制。',
744
753
  ]);