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.
- package/dist/core/dashboard-url.d.ts +22 -0
- package/dist/core/dashboard-url.d.ts.map +1 -0
- package/dist/core/dashboard-url.js +24 -0
- package/dist/core/dashboard-url.js.map +1 -0
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +13 -9
- package/dist/daemon.js.map +1 -1
- package/dist/dashboard/federation-spoke-api.d.ts.map +1 -1
- package/dist/dashboard/federation-spoke-api.js +10 -3
- package/dist/dashboard/federation-spoke-api.js.map +1 -1
- package/dist/dashboard.js +11 -3
- package/dist/dashboard.js.map +1 -1
- package/dist/global-config.d.ts +6 -0
- package/dist/global-config.d.ts.map +1 -1
- package/dist/global-config.js +8 -0
- package/dist/global-config.js.map +1 -1
- package/dist/im/lark/event-dispatcher.d.ts +18 -1
- package/dist/im/lark/event-dispatcher.d.ts.map +1 -1
- package/dist/im/lark/event-dispatcher.js +47 -3
- package/dist/im/lark/event-dispatcher.js.map +1 -1
- package/dist/platform/bind.d.ts.map +1 -1
- package/dist/platform/bind.js +22 -1
- package/dist/platform/bind.js.map +1 -1
- package/dist/platform/tunnel-client.d.ts.map +1 -1
- package/dist/platform/tunnel-client.js +75 -29
- package/dist/platform/tunnel-client.js.map +1 -1
- package/dist/services/team-bots-store.d.ts +34 -0
- package/dist/services/team-bots-store.d.ts.map +1 -0
- package/dist/services/team-bots-store.js +111 -0
- package/dist/services/team-bots-store.js.map +1 -0
- package/dist/services/team-groups-store.d.ts +8 -0
- package/dist/services/team-groups-store.d.ts.map +1 -1
- package/dist/services/team-groups-store.js +12 -0
- package/dist/services/team-groups-store.js.map +1 -1
- 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"}
|
package/dist/daemon.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"
|
|
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
|
|
3365
|
-
|
|
3366
|
-
|
|
3367
|
-
|
|
3368
|
-
|
|
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;
|