botmux 2.97.0 → 2.98.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.
Files changed (35) hide show
  1. package/dist/core/dashboard-url.d.ts +22 -0
  2. package/dist/core/dashboard-url.d.ts.map +1 -0
  3. package/dist/core/dashboard-url.js +24 -0
  4. package/dist/core/dashboard-url.js.map +1 -0
  5. package/dist/daemon.d.ts.map +1 -1
  6. package/dist/daemon.js +13 -9
  7. package/dist/daemon.js.map +1 -1
  8. package/dist/dashboard/federation-spoke-api.d.ts.map +1 -1
  9. package/dist/dashboard/federation-spoke-api.js +10 -3
  10. package/dist/dashboard/federation-spoke-api.js.map +1 -1
  11. package/dist/dashboard.js +11 -3
  12. package/dist/dashboard.js.map +1 -1
  13. package/dist/global-config.d.ts +6 -0
  14. package/dist/global-config.d.ts.map +1 -1
  15. package/dist/global-config.js +8 -0
  16. package/dist/global-config.js.map +1 -1
  17. package/dist/im/lark/event-dispatcher.d.ts +18 -1
  18. package/dist/im/lark/event-dispatcher.d.ts.map +1 -1
  19. package/dist/im/lark/event-dispatcher.js +47 -3
  20. package/dist/im/lark/event-dispatcher.js.map +1 -1
  21. package/dist/platform/bind.d.ts.map +1 -1
  22. package/dist/platform/bind.js +22 -1
  23. package/dist/platform/bind.js.map +1 -1
  24. package/dist/platform/tunnel-client.d.ts.map +1 -1
  25. package/dist/platform/tunnel-client.js +75 -29
  26. package/dist/platform/tunnel-client.js.map +1 -1
  27. package/dist/services/team-bots-store.d.ts +34 -0
  28. package/dist/services/team-bots-store.d.ts.map +1 -0
  29. package/dist/services/team-bots-store.js +111 -0
  30. package/dist/services/team-bots-store.js.map +1 -0
  31. package/dist/services/team-groups-store.d.ts +8 -0
  32. package/dist/services/team-groups-store.d.ts.map +1 -1
  33. package/dist/services/team-groups-store.js +12 -0
  34. package/dist/services/team-groups-store.js.map +1 -1
  35. package/package.json +1 -1
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Builds the public URL for the web dashboard, given a token.
3
+ *
4
+ * When 远程访问 is enabled AND this machine is bound to the central platform, the
5
+ * URL routes through the machine subdomain
6
+ * (`https://m-<machineId>.<platformHost>/?t=<token>`): the platform
7
+ * reverse-proxies that subdomain to this host's local dashboard, which still
8
+ * enforces the `?t=` token itself, so the link is reachable centrally with no
9
+ * `:port`. When 远程访问 is off (or the machine isn't bound) the platform base is
10
+ * null and we fall back to the local `http://<externalHost>:<port>/` form.
11
+ *
12
+ * Mirrors buildTerminalUrl (terminal-url.ts) and publicWebhookUrl
13
+ * (dashboard/connector-api.ts) so dashboard, terminal, and webhook links all
14
+ * flip to the platform together under the single 远程访问 switch — instead of the
15
+ * dashboard link being the one place that always stays local.
16
+ */
17
+ export declare function buildDashboardUrl(opts: {
18
+ host: string;
19
+ port: number | string;
20
+ token?: string;
21
+ }): string;
22
+ //# sourceMappingURL=dashboard-url.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard-url.d.ts","sourceRoot":"","sources":["../../src/core/dashboard-url.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAIvG"}
@@ -0,0 +1,24 @@
1
+ import { platformMachineBaseUrl } from '../platform/binding.js';
2
+ import { isRemoteAccessEnabled } from '../global-config.js';
3
+ /**
4
+ * Builds the public URL for the web dashboard, given a token.
5
+ *
6
+ * When 远程访问 is enabled AND this machine is bound to the central platform, the
7
+ * URL routes through the machine subdomain
8
+ * (`https://m-<machineId>.<platformHost>/?t=<token>`): the platform
9
+ * reverse-proxies that subdomain to this host's local dashboard, which still
10
+ * enforces the `?t=` token itself, so the link is reachable centrally with no
11
+ * `:port`. When 远程访问 is off (or the machine isn't bound) the platform base is
12
+ * null and we fall back to the local `http://<externalHost>:<port>/` form.
13
+ *
14
+ * Mirrors buildTerminalUrl (terminal-url.ts) and publicWebhookUrl
15
+ * (dashboard/connector-api.ts) so dashboard, terminal, and webhook links all
16
+ * flip to the platform together under the single 远程访问 switch — instead of the
17
+ * dashboard link being the one place that always stays local.
18
+ */
19
+ export function buildDashboardUrl(opts) {
20
+ const platformBase = isRemoteAccessEnabled() ? platformMachineBaseUrl() : null;
21
+ const origin = platformBase ?? `http://${opts.host}:${opts.port}`;
22
+ return opts.token ? `${origin}/?t=${opts.token}` : `${origin}/`;
23
+ }
24
+ //# sourceMappingURL=dashboard-url.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard-url.js","sourceRoot":"","sources":["../../src/core/dashboard-url.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAE5D;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAA6D;IAC7F,MAAM,YAAY,GAAG,qBAAqB,EAAE,CAAC,CAAC,CAAC,sBAAsB,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAC/E,MAAM,MAAM,GAAG,YAAY,IAAI,UAAU,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;IAClE,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,OAAO,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,MAAM,GAAG,CAAC;AAClE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"AAkBA,OAAO,EAA8G,KAAK,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAkBhK,YAAY,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAiGrD,OAAO,EAAE,oBAAoB,EAA6B,MAAM,uBAAuB,CAAC;AACxF,OAAO,KAAK,EAAE,sBAAsB,EAAiB,MAAM,wBAAwB,CAAC;AAqPpF,wBAAsB,gBAAgB,CAAC,EAAE,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAmClK;AAED,iBAAe,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,MAAe,EAAE,SAAS,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA8D3I;AAMD,eAAO,MAAM,uBAAuB,qBAAe,CAAC;AACpD,eAAO,MAAM,yBAAyB,4BAAiB,CAAC;AAqCxD,wBAAsB,8BAA8B,CAClD,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,OAAO,CAAC,CA6ClB;AAED,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,GAAG,EAAE,MAAM,GACV,MAAM,GAAG,SAAS,CAIpB;AAED,wBAAgB,+BAA+B,CAC7C,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,GAAG,EAAE,MAAM,GACV,MAAM,GAAG,SAAS,CAMpB;AAoKD,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,sBAAsB,GAAG,oBAAoB,CA0C5G;AA65CD;;;;;;;;;;;GAWG;AACH,iBAAe,uBAAuB,CAAC,GAAG,EAAE;IAC1C,KAAK,EAAE,QAAQ,GAAG,MAAM,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,GAAG,KAAK,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;CACnB;;;;GAiBA;AAED,eAAO,MAAM,kCAAkC,gCAA0B,CAAC;AAq/C1E,wBAAsB,WAAW,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAidlE"}
1
+ {"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"AAmBA,OAAO,EAA8G,KAAK,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAkBhK,YAAY,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAiGrD,OAAO,EAAE,oBAAoB,EAA6B,MAAM,uBAAuB,CAAC;AACxF,OAAO,KAAK,EAAE,sBAAsB,EAAiB,MAAM,wBAAwB,CAAC;AAqPpF,wBAAsB,gBAAgB,CAAC,EAAE,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAmClK;AAED,iBAAe,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,MAAe,EAAE,SAAS,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA8D3I;AAMD,eAAO,MAAM,uBAAuB,qBAAe,CAAC;AACpD,eAAO,MAAM,yBAAyB,4BAAiB,CAAC;AAqCxD,wBAAsB,8BAA8B,CAClD,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,OAAO,CAAC,CA6ClB;AAED,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,GAAG,EAAE,MAAM,GACV,MAAM,GAAG,SAAS,CAIpB;AAED,wBAAgB,+BAA+B,CAC7C,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,GAAG,EAAE,MAAM,GACV,MAAM,GAAG,SAAS,CAMpB;AAoKD,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,sBAAsB,GAAG,oBAAoB,CA0C5G;AA65CD;;;;;;;;;;;GAWG;AACH,iBAAe,uBAAuB,CAAC,GAAG,EAAE;IAC1C,KAAK,EAAE,QAAQ,GAAG,MAAM,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,GAAG,KAAK,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;CACnB;;;;GAiBA;AAED,eAAO,MAAM,kCAAkC,gCAA0B,CAAC;AAy/C1E,wBAAsB,WAAW,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAidlE"}
package/dist/daemon.js CHANGED
@@ -8,6 +8,7 @@ const __filename = fileURLToPath(import.meta.url);
8
8
  const __dirname = dirname(__filename);
9
9
  import { config, getDashboardExternalHost } from './config.js';
10
10
  import { repoPickerScanOptions } from './global-config.js';
11
+ import { buildDashboardUrl } from './core/dashboard-url.js';
11
12
  import { writeHeartbeat } from './core/daemon-heartbeat.js';
12
13
  import { botmuxWrapperFiles } from './core/botmux-wrapper.js';
13
14
  import { startMaintenance, stopMaintenance } from './core/maintenance.js';
@@ -2173,7 +2174,7 @@ async function handleNewTopic(data, ctx) {
2173
2174
  // chat-granted users (who only pass canTalk) management commands like
2174
2175
  // /cd /restart /oncall bind. Previously this gate only fired in oncall chats,
2175
2176
  // which left a hole once per-chat grants flow through canTalk.
2176
- if (!canOperate(larkAppId, chatId, senderOpenId)) {
2177
+ if (!canOperate(larkAppId, chatId, senderOpenId, senderUnionId)) {
2177
2178
  await sessionReply(anchor, tr('daemon.cmd_allowed_users_only', { cmd }, localeForBot(larkAppId)), 'text', larkAppId);
2178
2179
  return;
2179
2180
  }
@@ -2675,6 +2676,11 @@ async function handleThreadReply(data, ctx) {
2675
2676
  // Strip leading @<bot> mentions so "@bot /restart" is recognized as a command.
2676
2677
  const cmdContent = stripLeadingMentions(content, parsed.mentions);
2677
2678
  const threadSenderOpenId = parsed.senderId || data?.sender?.sender_id?.open_id;
2679
+ // Tenant-stable union_id of the thread sender — lets canOperate recognise a
2680
+ // cross-deployment TEAM peer bot (isTeamBot) and grant it daemon-command
2681
+ // operate, parity with same-deployment siblings (option B). undefined for
2682
+ // senders Lark didn't stamp a union_id on → no team-operate, falls back.
2683
+ const threadSenderUnionId = data?.sender?.sender_id?.union_id;
2678
2684
  const threadChatId = ctxChatId ?? data?.message?.chat_id;
2679
2685
  const clearAgentAttentionForHumanInbound = () => {
2680
2686
  if (isForeignBot || isBotSenderType)
@@ -2796,7 +2802,7 @@ async function handleThreadReply(data, ctx) {
2796
2802
  }
2797
2803
  // canOperate gate for thread-reply daemon commands — required in every chat
2798
2804
  // (see spawn-path gate above). Denies chat-granted users management commands.
2799
- if (!canOperate(larkAppId, effectiveThreadChatId, threadSenderOpenId)) {
2805
+ if (!canOperate(larkAppId, effectiveThreadChatId, threadSenderOpenId, threadSenderUnionId)) {
2800
2806
  sessionReply(anchor, tr('daemon.cmd_allowed_users_only', { cmd }, localeForBot(larkAppId)), 'text', larkAppId);
2801
2807
  return;
2802
2808
  }
@@ -3361,13 +3367,11 @@ function dashboardUrlForReport() {
3361
3367
  const portFile = join(dir, '.dashboard-port');
3362
3368
  const tokenFile = join(dir, '.dashboard-token');
3363
3369
  const port = existsSync(portFile) ? readFileSync(portFile, 'utf8').trim() : String(config.dashboard.port);
3364
- const base = `http://${getDashboardExternalHost()}:${port}/`;
3365
- if (existsSync(tokenFile)) {
3366
- const tok = readFileSync(tokenFile, 'utf8').trim();
3367
- if (tok)
3368
- return `${base}?t=${tok}`;
3369
- }
3370
- return base;
3370
+ const tok = existsSync(tokenFile) ? readFileSync(tokenFile, 'utf8').trim() : '';
3371
+ // buildDashboardUrl swaps in the central-platform machine subdomain when
3372
+ // 远程访问 is on and this host is bound, so the restart-report DM links to the
3373
+ // platform dashboard instead of an unreachable local host:port.
3374
+ return buildDashboardUrl({ host: getDashboardExternalHost(), port, token: tok || undefined });
3371
3375
  }
3372
3376
  catch {
3373
3377
  return undefined;