botmux 3.9.2 → 3.10.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 +1 -1
- package/README.md +1 -1
- package/dist/.runtime-build-id +1 -1
- package/dist/adapters/cli/codex.d.ts.map +1 -1
- package/dist/adapters/cli/codex.js +6 -0
- package/dist/adapters/cli/codex.js.map +1 -1
- package/dist/adapters/cli/opencode.d.ts.map +1 -1
- package/dist/adapters/cli/opencode.js +7 -1
- package/dist/adapters/cli/opencode.js.map +1 -1
- package/dist/adapters/cli/reasonix.d.ts +35 -0
- package/dist/adapters/cli/reasonix.d.ts.map +1 -0
- package/dist/adapters/cli/reasonix.js +236 -0
- package/dist/adapters/cli/reasonix.js.map +1 -0
- package/dist/adapters/cli/registry.d.ts +2 -1
- package/dist/adapters/cli/registry.d.ts.map +1 -1
- package/dist/adapters/cli/registry.js +4 -1
- package/dist/adapters/cli/registry.js.map +1 -1
- package/dist/adapters/cli/types.d.ts +5 -1
- package/dist/adapters/cli/types.d.ts.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +168 -62
- package/dist/cli.js.map +1 -1
- package/dist/core/command-handler.d.ts +18 -4
- package/dist/core/command-handler.d.ts.map +1 -1
- package/dist/core/command-handler.js +234 -26
- package/dist/core/command-handler.js.map +1 -1
- package/dist/core/dashboard-ipc-server.d.ts +1 -0
- package/dist/core/dashboard-ipc-server.d.ts.map +1 -1
- package/dist/core/dashboard-ipc-server.js +27 -3
- package/dist/core/dashboard-ipc-server.js.map +1 -1
- package/dist/core/dispatch.d.ts +54 -24
- package/dist/core/dispatch.d.ts.map +1 -1
- package/dist/core/dispatch.js +81 -27
- package/dist/core/dispatch.js.map +1 -1
- package/dist/core/input-turn-dedupe.d.ts +20 -0
- package/dist/core/input-turn-dedupe.d.ts.map +1 -0
- package/dist/core/input-turn-dedupe.js +57 -0
- package/dist/core/input-turn-dedupe.js.map +1 -0
- package/dist/core/local-terminal-opener.d.ts.map +1 -1
- package/dist/core/local-terminal-opener.js +10 -1
- package/dist/core/local-terminal-opener.js.map +1 -1
- package/dist/core/passthrough-commands.d.ts.map +1 -1
- package/dist/core/passthrough-commands.js +1 -1
- package/dist/core/passthrough-commands.js.map +1 -1
- package/dist/core/plugins/pm2.d.ts.map +1 -1
- package/dist/core/plugins/pm2.js +7 -1
- package/dist/core/plugins/pm2.js.map +1 -1
- package/dist/core/resource-monitor/attribution.d.ts.map +1 -1
- package/dist/core/resource-monitor/attribution.js +17 -1
- package/dist/core/resource-monitor/attribution.js.map +1 -1
- package/dist/core/resource-monitor/darwin.d.ts +145 -0
- package/dist/core/resource-monitor/darwin.d.ts.map +1 -0
- package/dist/core/resource-monitor/darwin.js +360 -0
- package/dist/core/resource-monitor/darwin.js.map +1 -0
- package/dist/core/resource-monitor/procfs.d.ts.map +1 -1
- package/dist/core/resource-monitor/procfs.js +6 -0
- package/dist/core/resource-monitor/procfs.js.map +1 -1
- package/dist/core/resource-monitor/types.d.ts +1 -1
- package/dist/core/resource-monitor/types.d.ts.map +1 -1
- package/dist/core/scheduler.d.ts.map +1 -1
- package/dist/core/scheduler.js +5 -2
- package/dist/core/scheduler.js.map +1 -1
- package/dist/core/session-discovery.d.ts.map +1 -1
- package/dist/core/session-discovery.js +3 -0
- package/dist/core/session-discovery.js.map +1 -1
- package/dist/core/session-manager.d.ts +3 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +46 -0
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/session-marker.d.ts +1 -8
- package/dist/core/session-marker.d.ts.map +1 -1
- package/dist/core/session-marker.js +2 -50
- package/dist/core/session-marker.js.map +1 -1
- package/dist/core/types.d.ts +3 -1
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/core/worker-pool.d.ts +17 -0
- package/dist/core/worker-pool.d.ts.map +1 -1
- package/dist/core/worker-pool.js +292 -9
- package/dist/core/worker-pool.js.map +1 -1
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +27 -12
- package/dist/daemon.js.map +1 -1
- package/dist/dashboard/daemon-internal-api.d.ts.map +1 -1
- package/dist/dashboard/daemon-internal-api.js +11 -2
- package/dist/dashboard/daemon-internal-api.js.map +1 -1
- package/dist/dashboard/groups-action-helpers.d.ts +2 -0
- package/dist/dashboard/groups-action-helpers.d.ts.map +1 -1
- package/dist/dashboard/groups-action-helpers.js +9 -0
- package/dist/dashboard/groups-action-helpers.js.map +1 -1
- package/dist/dashboard/groups-matrix-snapshot.d.ts +56 -0
- package/dist/dashboard/groups-matrix-snapshot.d.ts.map +1 -0
- package/dist/dashboard/groups-matrix-snapshot.js +127 -0
- package/dist/dashboard/groups-matrix-snapshot.js.map +1 -0
- package/dist/dashboard/resource-monitor-service.d.ts.map +1 -1
- package/dist/dashboard/resource-monitor-service.js +18 -2
- package/dist/dashboard/resource-monitor-service.js.map +1 -1
- package/dist/dashboard/web/app.d.ts.map +1 -1
- package/dist/dashboard/web/app.js +45 -4
- package/dist/dashboard/web/app.js.map +1 -1
- package/dist/dashboard/web/groups-api.js +1 -1
- package/dist/dashboard/web/groups-api.js.map +1 -1
- package/dist/dashboard/web/i18n.js +10 -10
- package/dist/dashboard/web/i18n.js.map +1 -1
- package/dist/dashboard/web/roles-page.d.ts.map +1 -1
- package/dist/dashboard/web/roles-page.js +26 -11
- package/dist/dashboard/web/roles-page.js.map +1 -1
- package/dist/dashboard-web/app.js +1 -1
- package/dist/dashboard-web/chunks/{bot-defaults-page-BHTQEWCH.js → bot-defaults-page-LTVOUDIS.js} +1 -1
- package/dist/dashboard-web/chunks/{chunk-KLZCQAHF.js → chunk-3UE7S77S.js} +1 -1
- package/dist/dashboard-web/chunks/{chunk-W77TPKZH.js → chunk-DCS35UMD.js} +1 -1
- package/dist/dashboard-web/chunks/{chunk-E3HZZXK5.js → chunk-MFQPCVHY.js} +4 -4
- package/dist/dashboard-web/chunks/{chunk-EZH56JCI.js → chunk-ZU3UUKAR.js} +1 -1
- package/dist/dashboard-web/chunks/{connectors-page-BP255CAX.js → connectors-page-5KWDIMKC.js} +1 -1
- package/dist/dashboard-web/chunks/{groups-page-CDHVXBUT.js → groups-page-FHOKYXMW.js} +1 -1
- package/dist/dashboard-web/chunks/{insights-page-57BFE6GT.js → insights-page-T2ZX2RWL.js} +1 -1
- package/dist/dashboard-web/chunks/{monitor-room-UTOYGQVF.js → monitor-room-YNVBAGR6.js} +1 -1
- package/dist/dashboard-web/chunks/{monitoring-page-WTHYAIUM.js → monitoring-page-LHM55YWN.js} +1 -1
- package/dist/dashboard-web/chunks/{office-page-JSMIB353.js → office-page-ATXVP7PW.js} +1 -1
- package/dist/dashboard-web/chunks/{overview-page-3VDBOH7L.js → overview-page-QYI3KBDD.js} +1 -1
- package/dist/dashboard-web/chunks/roles-page-56VWM6CD.js +1 -0
- package/dist/dashboard-web/chunks/{schedules-page-HHN736H6.js → schedules-page-S5K6U4EO.js} +1 -1
- package/dist/dashboard-web/chunks/{sessions-page-EIWOZD7A.js → sessions-page-WBP4N7D2.js} +1 -1
- package/dist/dashboard-web/chunks/{settings-page-2IUT5LS4.js → settings-page-QUZDQARR.js} +1 -1
- package/dist/dashboard-web/chunks/{skills-page-JKFKMUEM.js → skills-page-IFY7AEND.js} +1 -1
- package/dist/dashboard-web/chunks/{team-federation-page-Q2PXC3UY.js → team-federation-page-C7FJQPFZ.js} +1 -1
- package/dist/dashboard-web/chunks/{v3-page-EBQCD4AO.js → v3-page-2LMF3WWR.js} +1 -1
- package/dist/dashboard-web/chunks/{whiteboards-page-QZRMVNZN.js → whiteboards-page-3XC6QRMY.js} +1 -1
- package/dist/dashboard-web/style.css +2 -4
- package/dist/dashboard.js +65 -9
- package/dist/dashboard.js.map +1 -1
- package/dist/i18n/en.d.ts.map +1 -1
- package/dist/i18n/en.js +33 -7
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/zh.d.ts.map +1 -1
- package/dist/i18n/zh.js +31 -7
- package/dist/i18n/zh.js.map +1 -1
- package/dist/im/lark/card-builder.d.ts +7 -0
- package/dist/im/lark/card-builder.d.ts.map +1 -1
- package/dist/im/lark/card-builder.js +56 -0
- package/dist/im/lark/card-builder.js.map +1 -1
- package/dist/im/lark/card-handler.d.ts.map +1 -1
- package/dist/im/lark/card-handler.js +42 -19
- package/dist/im/lark/card-handler.js.map +1 -1
- package/dist/im/lark/client.d.ts +10 -0
- package/dist/im/lark/client.d.ts.map +1 -1
- package/dist/im/lark/client.js +79 -0
- package/dist/im/lark/client.js.map +1 -1
- package/dist/im/lark/event-dispatcher.d.ts +14 -1
- package/dist/im/lark/event-dispatcher.d.ts.map +1 -1
- package/dist/im/lark/event-dispatcher.js +171 -15
- package/dist/im/lark/event-dispatcher.js.map +1 -1
- package/dist/im/lark/lark-hosts.d.ts +5 -0
- package/dist/im/lark/lark-hosts.d.ts.map +1 -1
- package/dist/im/lark/lark-hosts.js +10 -0
- package/dist/im/lark/lark-hosts.js.map +1 -1
- package/dist/im/lark/message-parser.d.ts.map +1 -1
- package/dist/im/lark/message-parser.js +24 -7
- package/dist/im/lark/message-parser.js.map +1 -1
- package/dist/pm2-graceful-exit.d.ts +28 -0
- package/dist/pm2-graceful-exit.d.ts.map +1 -0
- package/dist/pm2-graceful-exit.js +39 -0
- package/dist/pm2-graceful-exit.js.map +1 -0
- package/dist/services/bridge-fallback-gate.d.ts +9 -2
- package/dist/services/bridge-fallback-gate.d.ts.map +1 -1
- package/dist/services/bridge-fallback-gate.js +31 -19
- package/dist/services/bridge-fallback-gate.js.map +1 -1
- package/dist/services/message-listener-store.d.ts +18 -0
- package/dist/services/message-listener-store.d.ts.map +1 -1
- package/dist/services/message-listener-store.js +35 -10
- package/dist/services/message-listener-store.js.map +1 -1
- package/dist/services/message-listener.d.ts +17 -0
- package/dist/services/message-listener.d.ts.map +1 -1
- package/dist/services/message-listener.js +26 -0
- package/dist/services/message-listener.js.map +1 -1
- package/dist/setup/bot-config-editor.d.ts.map +1 -1
- package/dist/setup/bot-config-editor.js +2 -0
- package/dist/setup/bot-config-editor.js.map +1 -1
- package/dist/setup/lark-scopes.json +1 -0
- package/dist/setup/verify-permissions.d.ts.map +1 -1
- package/dist/setup/verify-permissions.js +8 -0
- package/dist/setup/verify-permissions.js.map +1 -1
- package/dist/types.d.ts +34 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/child-env.d.ts +1 -1
- package/dist/utils/child-env.d.ts.map +1 -1
- package/dist/utils/child-env.js +13 -0
- package/dist/utils/child-env.js.map +1 -1
- package/dist/utils/file-lock.d.ts.map +1 -1
- package/dist/utils/file-lock.js +1 -1
- package/dist/utils/file-lock.js.map +1 -1
- package/dist/utils/global-install.d.ts.map +1 -1
- package/dist/utils/global-install.js +56 -10
- package/dist/utils/global-install.js.map +1 -1
- package/dist/utils/idle-detector.d.ts +4 -0
- package/dist/utils/idle-detector.d.ts.map +1 -1
- package/dist/utils/idle-detector.js +25 -0
- package/dist/utils/idle-detector.js.map +1 -1
- package/dist/utils/process-identity.d.ts +7 -0
- package/dist/utils/process-identity.d.ts.map +1 -0
- package/dist/utils/process-identity.js +62 -0
- package/dist/utils/process-identity.js.map +1 -0
- package/dist/worker.js +123 -9
- package/dist/worker.js.map +1 -1
- package/dist/workflows/events/payloads.d.ts +10 -10
- package/dist/workflows/events/schema.d.ts +28 -28
- package/dist/workflows/hostExecutors/registry.d.ts +2 -7
- package/dist/workflows/hostExecutors/registry.d.ts.map +1 -1
- package/dist/workflows/hostExecutors/registry.js.map +1 -1
- package/dist/workflows/shared/provider-reconciler.d.ts +1 -30
- package/dist/workflows/shared/provider-reconciler.d.ts.map +1 -1
- package/dist/workflows/shared/provider-reconciler.js.map +1 -1
- package/dist/workflows/v3/artifact-contract.d.ts +41 -0
- package/dist/workflows/v3/artifact-contract.d.ts.map +1 -0
- package/dist/workflows/v3/artifact-contract.js +20 -0
- package/dist/workflows/v3/artifact-contract.js.map +1 -0
- package/dist/workflows/v3/botmux-attempt-lease.d.ts +7 -0
- package/dist/workflows/v3/botmux-attempt-lease.d.ts.map +1 -0
- package/dist/workflows/v3/botmux-attempt-lease.js +189 -0
- package/dist/workflows/v3/botmux-attempt-lease.js.map +1 -0
- package/dist/workflows/v3/botmux-host-policy.d.ts +7 -0
- package/dist/workflows/v3/botmux-host-policy.d.ts.map +1 -0
- package/dist/workflows/v3/botmux-host-policy.js +34 -0
- package/dist/workflows/v3/botmux-host-policy.js.map +1 -0
- package/dist/workflows/v3/cli-run.d.ts +1 -1
- package/dist/workflows/v3/cli-run.d.ts.map +1 -1
- package/dist/workflows/v3/cli-run.js +1 -1
- package/dist/workflows/v3/cli-run.js.map +1 -1
- package/dist/workflows/v3/contract.d.ts +8 -89
- package/dist/workflows/v3/contract.d.ts.map +1 -1
- package/dist/workflows/v3/contract.js +2 -8
- package/dist/workflows/v3/contract.js.map +1 -1
- package/dist/workflows/v3/core-control.d.ts +16 -0
- package/dist/workflows/v3/core-control.d.ts.map +1 -0
- package/dist/workflows/v3/core-control.js +60 -0
- package/dist/workflows/v3/core-control.js.map +1 -0
- package/dist/workflows/v3/daemon-run.d.ts.map +1 -1
- package/dist/workflows/v3/daemon-run.js +2 -1
- package/dist/workflows/v3/daemon-run.js.map +1 -1
- package/dist/workflows/v3/dag-loader.d.ts +5 -0
- package/dist/workflows/v3/dag-loader.d.ts.map +1 -0
- package/dist/workflows/v3/dag-loader.js +22 -0
- package/dist/workflows/v3/dag-loader.js.map +1 -0
- package/dist/workflows/v3/dag.d.ts +2 -6
- package/dist/workflows/v3/dag.d.ts.map +1 -1
- package/dist/workflows/v3/dag.js +2 -24
- package/dist/workflows/v3/dag.js.map +1 -1
- package/dist/workflows/v3/ephemeral-pool.d.ts.map +1 -1
- package/dist/workflows/v3/ephemeral-pool.js +22 -12
- package/dist/workflows/v3/ephemeral-pool.js.map +1 -1
- package/dist/workflows/v3/event-contract.d.ts +273 -0
- package/dist/workflows/v3/event-contract.d.ts.map +1 -0
- package/dist/workflows/v3/event-contract.js +8 -0
- package/dist/workflows/v3/event-contract.js.map +1 -0
- package/dist/workflows/v3/gate-policy.d.ts +12 -0
- package/dist/workflows/v3/gate-policy.d.ts.map +1 -0
- package/dist/workflows/v3/gate-policy.js +20 -0
- package/dist/workflows/v3/gate-policy.js.map +1 -0
- package/dist/workflows/v3/gate-wait-store.d.ts +99 -0
- package/dist/workflows/v3/gate-wait-store.d.ts.map +1 -0
- package/dist/workflows/v3/gate-wait-store.js +263 -0
- package/dist/workflows/v3/gate-wait-store.js.map +1 -0
- package/dist/workflows/v3/host.js +1 -1
- package/dist/workflows/v3/host.js.map +1 -1
- package/dist/workflows/v3/human-gate.d.ts +4 -99
- package/dist/workflows/v3/human-gate.d.ts.map +1 -1
- package/dist/workflows/v3/human-gate.js +4 -275
- package/dist/workflows/v3/human-gate.js.map +1 -1
- package/dist/workflows/v3/in-process-attempt-lease.d.ts +10 -0
- package/dist/workflows/v3/in-process-attempt-lease.d.ts.map +1 -0
- package/dist/workflows/v3/in-process-attempt-lease.js +47 -0
- package/dist/workflows/v3/in-process-attempt-lease.js.map +1 -0
- package/dist/workflows/v3/journal.d.ts +2 -275
- package/dist/workflows/v3/journal.d.ts.map +1 -1
- package/dist/workflows/v3/journal.js.map +1 -1
- package/dist/workflows/v3/library-service.js +1 -1
- package/dist/workflows/v3/library-service.js.map +1 -1
- package/dist/workflows/v3/orchestrator.d.ts +1 -2
- package/dist/workflows/v3/orchestrator.d.ts.map +1 -1
- package/dist/workflows/v3/orchestrator.js.map +1 -1
- package/dist/workflows/v3/portable-artifact-snapshot.d.ts +15 -0
- package/dist/workflows/v3/portable-artifact-snapshot.d.ts.map +1 -0
- package/dist/workflows/v3/portable-artifact-snapshot.js +76 -0
- package/dist/workflows/v3/portable-artifact-snapshot.js.map +1 -0
- package/dist/workflows/v3/portable-final-outputs.d.ts +37 -0
- package/dist/workflows/v3/portable-final-outputs.d.ts.map +1 -0
- package/dist/workflows/v3/portable-final-outputs.js +137 -0
- package/dist/workflows/v3/portable-final-outputs.js.map +1 -0
- package/dist/workflows/v3/portable-run-snapshot.d.ts +14 -0
- package/dist/workflows/v3/portable-run-snapshot.d.ts.map +1 -0
- package/dist/workflows/v3/portable-run-snapshot.js +176 -0
- package/dist/workflows/v3/portable-run-snapshot.js.map +1 -0
- package/dist/workflows/v3/portable-runtime.d.ts +83 -0
- package/dist/workflows/v3/portable-runtime.d.ts.map +1 -0
- package/dist/workflows/v3/portable-runtime.js +135 -0
- package/dist/workflows/v3/portable-runtime.js.map +1 -0
- package/dist/workflows/v3/runtime-host-contract.d.ts +182 -0
- package/dist/workflows/v3/runtime-host-contract.d.ts.map +1 -0
- package/dist/workflows/v3/runtime-host-contract.js +9 -0
- package/dist/workflows/v3/runtime-host-contract.js.map +1 -0
- package/dist/workflows/v3/runtime.d.ts +12 -226
- package/dist/workflows/v3/runtime.d.ts.map +1 -1
- package/dist/workflows/v3/runtime.js +14 -3173
- package/dist/workflows/v3/runtime.js.map +1 -1
- package/dist/workflows/v3/shared-node-runtime.d.ts +203 -0
- package/dist/workflows/v3/shared-node-runtime.d.ts.map +1 -0
- package/dist/workflows/v3/shared-node-runtime.js +2978 -0
- package/dist/workflows/v3/shared-node-runtime.js.map +1 -0
- package/dist/workflows/v3/shared-runtime.d.ts +17 -0
- package/dist/workflows/v3/shared-runtime.d.ts.map +1 -0
- package/dist/workflows/v3/shared-runtime.js +12 -0
- package/dist/workflows/v3/shared-runtime.js.map +1 -0
- package/package.json +4 -1
- package/dist/dashboard-web/chunks/roles-page-LHVAU2BI.js +0 -1
|
@@ -8,7 +8,7 @@ import { ProxyAgent } from 'proxy-agent';
|
|
|
8
8
|
import { readFileSync, mkdirSync, existsSync } from 'node:fs';
|
|
9
9
|
import { atomicWriteFileSync } from '../../utils/atomic-write.js';
|
|
10
10
|
import { join } from 'node:path';
|
|
11
|
-
import { getBot, getAllBots, findOncallChat, getOwnerOpenId } from '../../bot-registry.js';
|
|
11
|
+
import { getBot, getAllBots, findOncallChat, getOwnerOpenId, loadBotConfigs } from '../../bot-registry.js';
|
|
12
12
|
import { config, isVcMeetingAgentGloballyEnabled, vcMeetingAgentGlobalListenerBotAppId } from '../../config.js';
|
|
13
13
|
import { getChatInfo, getChatMode, getCachedChatMode, getUserProfile, listChatMessagesUntil, resolveSiblingBotBySenderOpenId, replyMessage, sendMessage, sendUserMessage, isHumanOpenId, updateMessage } from './client.js';
|
|
14
14
|
import { logger } from '../../utils/logger.js';
|
|
@@ -21,7 +21,7 @@ import { recordObservedBots, listObservedBots } from '../../services/observed-bo
|
|
|
21
21
|
import { isTeamBot, recordTeamBot } from '../../services/team-bots-store.js';
|
|
22
22
|
import { isTeamGroupChat } from '../../services/team-groups-store.js';
|
|
23
23
|
import { isPlatformTeamBot, isPlatformHallChat, isPlatformTeamMemberChat } from '../../services/platform-team-store.js';
|
|
24
|
-
import { recordBotUnionId, recordBotUnionIdFromMentions } from '../../services/bot-union-ids-store.js';
|
|
24
|
+
import { getBotUnionId, recordBotUnionId, recordBotUnionIdFromMentions } from '../../services/bot-union-ids-store.js';
|
|
25
25
|
import { getDocSubscription, putDocSubscription, removeDocSubscription, listAllDocSubscriptions } from '../../services/doc-subs-store.js';
|
|
26
26
|
import { getDocComment, isBotAuthoredReply, hasBotSentinel, commentTriggerAllowed, BOT_REPLY_SENTINEL } from './doc-comment.js';
|
|
27
27
|
import { BOTMUX_REQUIRED_SCOPES, DOC_FEATURE_SCOPES, DOC_WATCH_SCOPES, DOC_COMMENT_EVENT, VC_MEETING_BOT_EVENTS, VC_MEETING_FEATURE_SCOPES, VC_MEETING_REALTIME_VOICE_SCOPES, buildEventSubDeepLink, buildScopeDeepLink, } from '../../setup/verify-permissions.js';
|
|
@@ -198,16 +198,27 @@ async function dmAdmin(larkAppId, adminOpenId, content, contextTag) {
|
|
|
198
198
|
*
|
|
199
199
|
* Returns `true` if scopes were successfully applied (caller should stop),
|
|
200
200
|
* `false` to fall through to the manual DM warning.
|
|
201
|
+
*
|
|
202
|
+
* `opts.disableQrLogin` — when the only thing missing is a non-critical scope,
|
|
203
|
+
* we still try to grab it (the automation imports the full manifest), but must
|
|
204
|
+
* NOT pop a second QR code if the cached session is gone. Passing this makes a
|
|
205
|
+
* missing/expired session fail cleanly (reason `invalid_session`) instead of
|
|
206
|
+
* prompting a login.
|
|
207
|
+
* `opts.silent` — suppress the admin success DM (used for the opt-in / optional
|
|
208
|
+
* path so a bot that never asked for the feature isn't pinged; the log line is
|
|
209
|
+
* enough). Failures are always silent here regardless.
|
|
201
210
|
*/
|
|
202
|
-
async function tryAutoFixScopes(larkAppId, bot, brand, missingCritical, missingOptional) {
|
|
211
|
+
async function tryAutoFixScopes(larkAppId, bot, brand, missingCritical, missingOptional, opts) {
|
|
203
212
|
if (brand !== 'feishu')
|
|
204
213
|
return false;
|
|
205
214
|
try {
|
|
206
|
-
|
|
215
|
+
const totalMissing = missingCritical.length + missingOptional.length;
|
|
216
|
+
logger.info(`[${larkAppId}] attempting auto-fix for ${totalMissing} missing scopes via Open Platform...`);
|
|
207
217
|
const result = await automateOpenPlatformSetup({
|
|
208
218
|
appId: bot.config.larkAppId,
|
|
209
219
|
brand,
|
|
210
220
|
maxWaitMs: 60_000,
|
|
221
|
+
disableQrLogin: opts?.disableQrLogin,
|
|
211
222
|
onStatus: (msg) => logger.info(`[${larkAppId}] auto-fix: ${msg}`),
|
|
212
223
|
onQrCode: (info) => {
|
|
213
224
|
logger.warn(`[${larkAppId}] auto-fix: cached Feishu web session expired, QR login needed. ` +
|
|
@@ -222,21 +233,26 @@ async function tryAutoFixScopes(larkAppId, bot, brand, missingCritical, missingO
|
|
|
222
233
|
logger.info(`[${larkAppId}] auto-fix succeeded: ${scopeDetail}, ` +
|
|
223
234
|
`version ${result.versionId ?? 'n/a'} published, ` +
|
|
224
235
|
`${result.subscribedEventCount} events subscribed`);
|
|
236
|
+
// opt-in / optional-only path: succeeded silently, no admin DM (a bot that
|
|
237
|
+
// never enabled the feature must not be pinged just because a non-critical
|
|
238
|
+
// scope was topped up in the background). The log line above is the record.
|
|
239
|
+
if (opts?.silent)
|
|
240
|
+
return true;
|
|
225
241
|
// Notify admin that auto-fix worked — even if im:message was missing before,
|
|
226
242
|
// the newly published version should now have it.
|
|
227
243
|
const adminOpenId = getAdminOpenId(bot);
|
|
228
244
|
if (adminOpenId) {
|
|
229
|
-
const
|
|
230
|
-
const
|
|
231
|
-
? `\n\n另有 ${missingOptional.length} 项可选权限未开通:${missingOptional.map(s => s.name).join('、')}`
|
|
232
|
-
: '';
|
|
245
|
+
const fixedList = [...missingCritical, ...missingOptional];
|
|
246
|
+
const missingList = fixedList.map(s => `• ${s.desc} (\`${s.name}\`)`).join('\n');
|
|
233
247
|
await dmAdmin(larkAppId, adminOpenId, `✅ botmux 已自动为机器人 "${bot.botName ?? larkAppId}" 修复了缺失的权限:\n\n${missingList}\n\n` +
|
|
234
248
|
`${scopeDetail},新版本已发布。\n` +
|
|
235
|
-
`权限变更可能需要 1-2 分钟生效。如仍有问题执行 \`botmux restart
|
|
249
|
+
`权限变更可能需要 1-2 分钟生效。如仍有问题执行 \`botmux restart\`。`, `auto-fixed ${fixedList.length} scopes`);
|
|
236
250
|
}
|
|
237
251
|
return true;
|
|
238
252
|
}
|
|
239
|
-
// Auto-fix failed — log reason
|
|
253
|
+
// Auto-fix failed — log reason. Critical path falls through to a manual
|
|
254
|
+
// deep-link DM; the silent optional-scope top-up path does NOT DM (it just
|
|
255
|
+
// leaves the opt-in scope ungranted), so don't claim a DM fallback there.
|
|
240
256
|
const reasons = {
|
|
241
257
|
missing_session: '无可用的 Feishu Web session',
|
|
242
258
|
invalid_session: 'Web session 已失效',
|
|
@@ -250,11 +266,12 @@ async function tryAutoFixScopes(larkAppId, bot, brand, missingCritical, missingO
|
|
|
250
266
|
api_error: '开放平台 API 错误',
|
|
251
267
|
};
|
|
252
268
|
logger.warn(`[${larkAppId}] auto-fix not possible (${result.reason}: ${reasons[result.reason] ?? result.message}). ` +
|
|
253
|
-
|
|
269
|
+
(opts?.silent ? 'Leaving opt-in scope ungranted (no DM).' : 'Falling back to manual deep-link DM.'));
|
|
254
270
|
return false;
|
|
255
271
|
}
|
|
256
272
|
catch (err) {
|
|
257
|
-
logger.warn(`[${larkAppId}] auto-fix error: ${err?.message ?? err}
|
|
273
|
+
logger.warn(`[${larkAppId}] auto-fix error: ${err?.message ?? err}` +
|
|
274
|
+
(opts?.silent ? ' — leaving opt-in scope ungranted (no DM)' : ' — falling back to manual DM'));
|
|
258
275
|
return false;
|
|
259
276
|
}
|
|
260
277
|
}
|
|
@@ -403,6 +420,22 @@ export async function checkRequiredScopes(larkAppId) {
|
|
|
403
420
|
const missingCritical = BOTMUX_REQUIRED_SCOPES.filter(s => s.critical && !grantedScopes.has(s.name));
|
|
404
421
|
const missingOptional = BOTMUX_REQUIRED_SCOPES.filter(s => !s.critical && !grantedScopes.has(s.name));
|
|
405
422
|
if (missingCritical.length === 0) {
|
|
423
|
+
// All critical scopes present. If an opt-in feature added a non-critical
|
|
424
|
+
// scope that isn't granted yet, top it up SILENTLY — but only when a cached
|
|
425
|
+
// Feishu web session already exists (disableQrLogin makes a missing session
|
|
426
|
+
// fail cleanly with no second QR code and no DM). This makes `botmux restart`
|
|
427
|
+
// actually pick up newly-declared optional scopes (e.g. the foreign-bot
|
|
428
|
+
// group-message scope) without the admin having to visit the Open Platform,
|
|
429
|
+
// while a bot with nothing missing — or no web session — behaves exactly as
|
|
430
|
+
// before (no API call / no prompt / no nag).
|
|
431
|
+
if (missingOptional.length > 0 && brand === 'feishu') {
|
|
432
|
+
const toppedUp = await tryAutoFixScopes(larkAppId, bot, brand, [], missingOptional, { disableQrLogin: true, silent: true });
|
|
433
|
+
if (toppedUp) {
|
|
434
|
+
logger.info(`[${larkAppId}] auto-topped-up ${missingOptional.length} optional scope(s): ${missingOptional.map(s => s.name).join('、')}`);
|
|
435
|
+
return;
|
|
436
|
+
}
|
|
437
|
+
logger.debug(`[${larkAppId}] optional scope(s) missing (${missingOptional.map(s => s.name).join('、')}); no cached web session to auto-apply — leaving to opt-in feature owner`);
|
|
438
|
+
}
|
|
406
439
|
logger.info(`[${larkAppId}] all critical scopes granted (${BOTMUX_REQUIRED_SCOPES.filter(s => s.critical).length} checked)`);
|
|
407
440
|
return;
|
|
408
441
|
}
|
|
@@ -732,6 +765,38 @@ export function isKnownPeerBot(dataDir, larkAppId, senderOpenId) {
|
|
|
732
765
|
}
|
|
733
766
|
return false;
|
|
734
767
|
}
|
|
768
|
+
/**
|
|
769
|
+
* Auth-grade local sibling check for the narrow `/repo` exception.
|
|
770
|
+
*
|
|
771
|
+
* Cross-ref proves only "this receiver has seen this sender open_id as some
|
|
772
|
+
* peer" and may be stale or name-poisoned. For authorization we additionally
|
|
773
|
+
* require the Lark-stamped sender union_id to match exactly one currently
|
|
774
|
+
* configured, transport-enabled sibling app's learned own union_id.
|
|
775
|
+
*/
|
|
776
|
+
export function isVerifiedLocalSiblingBot(dataDir, larkAppId, senderOpenId, senderUnionId) {
|
|
777
|
+
const openId = (senderOpenId ?? '').trim();
|
|
778
|
+
const unionId = (senderUnionId ?? '').trim();
|
|
779
|
+
if (!openId || !unionId)
|
|
780
|
+
return false;
|
|
781
|
+
if (!isKnownPeerBot(dataDir, larkAppId, openId))
|
|
782
|
+
return false;
|
|
783
|
+
let matchingConfiguredSiblings = 0;
|
|
784
|
+
try {
|
|
785
|
+
for (const cfg of loadBotConfigs()) {
|
|
786
|
+
const appId = (cfg.larkAppId ?? '').trim();
|
|
787
|
+
if (!appId || appId === larkAppId || cfg.apiOnly === true)
|
|
788
|
+
continue;
|
|
789
|
+
if (getBotUnionId(dataDir, appId) === unionId)
|
|
790
|
+
matchingConfiguredSiblings += 1;
|
|
791
|
+
if (matchingConfiguredSiblings > 1)
|
|
792
|
+
return false;
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
catch {
|
|
796
|
+
return false;
|
|
797
|
+
}
|
|
798
|
+
return matchingConfiguredSiblings === 1;
|
|
799
|
+
}
|
|
735
800
|
/**
|
|
736
801
|
* Should a FOREIGN bot sender be trusted to collaborate (route/spawn a session)
|
|
737
802
|
* WITHOUT `/grant`, because it's a teammate? Two trust sources, both rooted in
|
|
@@ -1304,10 +1369,18 @@ export function canOperate(larkAppId, _chatId, senderOpenId, senderUnionId) {
|
|
|
1304
1369
|
* union_id 的情况);否则「团队拉群里外部 bot 能 talk 却执行不了降权到 canTalk 的命令
|
|
1305
1370
|
* (如 /status)」——单一 talk 谓词在这道 daemon 命令闸继续分叉。不传(人的路径)→
|
|
1306
1371
|
* 原样走 canTalk / evaluateTalk,语义不变。canOperate 那段人/bot 通用,不受影响。
|
|
1372
|
+
*
|
|
1373
|
+
* `/repo` 另有一个更窄的同部署 sibling bot 例外:仅当飞书事件把发送方盖章为 bot,
|
|
1374
|
+
* receiver cross-ref 命中 sender open_id,且 sender union_id 精确匹配当前仍配置的唯一
|
|
1375
|
+
* 本机 sibling app 已学习的自身 union_id 时放行;不把 sibling 提升为 canOperate,也不把其他 daemon 命令降权。
|
|
1307
1376
|
*/
|
|
1308
|
-
export function canRunDaemonCommand(larkAppId, chatId, senderOpenId, senderUnionId, cmd, memberUnionId, chatType, botSender) {
|
|
1377
|
+
export function canRunDaemonCommand(larkAppId, chatId, senderOpenId, senderUnionId, cmd, memberUnionId, chatType, botSender, larkStampedBotSender) {
|
|
1309
1378
|
if (canOperate(larkAppId, chatId, senderOpenId, senderUnionId))
|
|
1310
1379
|
return true;
|
|
1380
|
+
if (cmd === '/repo' && larkStampedBotSender === true
|
|
1381
|
+
&& isVerifiedLocalSiblingBot(config.session.dataDir, larkAppId, senderOpenId, senderUnionId)) {
|
|
1382
|
+
return true;
|
|
1383
|
+
}
|
|
1311
1384
|
const list = getBot(larkAppId).config.canTalkDaemonCommands;
|
|
1312
1385
|
if (!list?.includes(cmd))
|
|
1313
1386
|
return false;
|
|
@@ -2256,9 +2329,92 @@ export function startLarkEventDispatcher(larkAppId, larkAppSecret, handlers, bra
|
|
|
2256
2329
|
})).catch(err => logger.error(`Error handling bot message listener event: ${err}`));
|
|
2257
2330
|
return;
|
|
2258
2331
|
}
|
|
2259
|
-
// Foreign bot: only route on @mention of us.
|
|
2260
|
-
|
|
2332
|
+
// Foreign bot: only route on @mention of us — with one exception.
|
|
2333
|
+
//
|
|
2334
|
+
// 主动开工 — 场景② (bot sender): 「话题群新话题自动开工」(autoStartOnNewTopic)
|
|
2335
|
+
// 覆盖到「其他机器人开的新话题」。人分支在 3271 对非 @ 的话题群新话题种子做
|
|
2336
|
+
// 同一判定;bot 消息走本分支,若不在这里补一个等价出口,就会在下面这行 return
|
|
2337
|
+
// 掉——所以 bot 开的新话题永远到不了人分支的场景②。判定复用同一个纯函数
|
|
2338
|
+
// shouldAutoStartOnNewTopic(形态门:thread-scope + anchor===本消息 + 无会话
|
|
2339
|
+
// 占用,天然只认「全新话题种子」,不认话题内回复,故不会自我循环——回复锚定在
|
|
2340
|
+
// 话题根 anchor≠messageId),并要求飞书真的把这条非 @ 的 bot 消息推过来
|
|
2341
|
+
//(依赖 im:message.group_msg.include_bot:read scope;缺则事件根本不到,静默降级)。
|
|
2342
|
+
// sender 受授权门约束(与人分支 + 下游 enforceMessageQuotaForCliInput 同源):
|
|
2343
|
+
// 授权/peer/团队/oncall/开放腿放行的 sender 才自动开工,restricted 下未授权陌生
|
|
2344
|
+
// bot 改发授权卡(详见下方 autoTopic 分支)。
|
|
2345
|
+
//
|
|
2346
|
+
// 收到 im:message.group_msg.include_bot:read 推来的「其他用户/机器人发的群消息」后,
|
|
2347
|
+
// 只有满足形态门才免 @ 自动开工;否则保持原有「未 @ 即忽略」语义。
|
|
2348
|
+
if (!isBotMentioned(larkAppId, message, undefined)) {
|
|
2349
|
+
if (getBot(larkAppId).config.autoStartOnNewTopic === true && chatType === 'group') {
|
|
2350
|
+
const seedDecision = await decideRoutingWithSource(larkAppId, message);
|
|
2351
|
+
// P3 — 镜像人分支「话题群 → 普通群 (reverse conversion)」那道 forceRefresh
|
|
2352
|
+
// 守卫:decideRoutingWithSource 判 topic-chat 种子靠的是**缓存** chat_mode
|
|
2353
|
+
//(5min TTL)。管理员把话题群翻回普通群后缓存可能仍是 'topic',于是一条本该
|
|
2354
|
+
// 是普通群顶层的 bot 消息被误判成话题种子,起 thread-scope 会话把回复裹进
|
|
2355
|
+
//「其实已是普通群」的新 Lark 话题。无真实 thread_id(= 种子形态,非既有话题内
|
|
2356
|
+
// 回复,权威信号不会 stale)时用 forceRefresh 再确认;飞书现在报 'group' 就当
|
|
2357
|
+
// 它不是话题种子(降级),不自动开工。这道 API 往返只落在「已呈现 topic 种子
|
|
2358
|
+
// 形态的 opt-in 候选」上——与人分支同样的成本取舍(宁可多一次调用,也不用
|
|
2359
|
+
// 一个 5min 错建 session 的窗口换省一次调用)。
|
|
2360
|
+
let seedIsTopicChat = seedDecision.source === 'topic-chat';
|
|
2361
|
+
if (seedIsTopicChat && !message.thread_id) {
|
|
2362
|
+
const freshMode = await getChatMode(larkAppId, chatId, { forceRefresh: true });
|
|
2363
|
+
if (freshMode === 'group') {
|
|
2364
|
+
logger.info(`[chat-mode-converted] ${chatId.substring(0, 12)} chat_mode flipped 'topic' → 'group'; ` +
|
|
2365
|
+
`跳过 bot 新话题自动开工 msg=${messageId.substring(0, 12)}`);
|
|
2366
|
+
seedIsTopicChat = false;
|
|
2367
|
+
}
|
|
2368
|
+
}
|
|
2369
|
+
// 与人分支同源:只有真正的话题群顶层种子(source==='topic-chat' 且经 forceRefresh
|
|
2370
|
+
// 复核仍是话题群)才是自动开工候选;普通群 /t / 新话题模式产生的同形
|
|
2371
|
+
// {thread, anchor=msg} 不算。
|
|
2372
|
+
const seedScope = seedIsTopicChat ? seedDecision.scope : 'chat';
|
|
2373
|
+
const seedAnchor = seedIsTopicChat ? seedDecision.anchor : chatId;
|
|
2374
|
+
const seedOwnsSession = seedScope === 'thread'
|
|
2375
|
+
? (handlers.isSessionOwner?.(seedAnchor, larkAppId) ?? false)
|
|
2376
|
+
: false;
|
|
2377
|
+
const autoTopic = shouldAutoStartOnNewTopic({
|
|
2378
|
+
enabled: true,
|
|
2379
|
+
scope: seedScope,
|
|
2380
|
+
anchor: seedAnchor,
|
|
2381
|
+
messageId,
|
|
2382
|
+
chatType,
|
|
2383
|
+
ownsSession: seedOwnsSession,
|
|
2384
|
+
});
|
|
2385
|
+
// Sender 授权门(与人分支 + 下游 enforceMessageQuotaForCliInput 一致):
|
|
2386
|
+
// 自动开工最终仍要经 handleNewTopic 里的 enforceMessageQuotaForCliInput →
|
|
2387
|
+
// evaluateBotTalk 复查,restricted 模式(配了 allowlist)下未授权的陌生 bot
|
|
2388
|
+
// 会在那里被静默 drop、session 根本不建。所以在这里**先判同一个谓词**:
|
|
2389
|
+
// • allowed → 正常免 @ 自动开工(open 模式 / oncall / 整群授权 / peer /
|
|
2390
|
+
// 团队 bot 等任一放行腿命中,与人/下游同源)。
|
|
2391
|
+
// • !allowed(restricted 下的陌生 bot)→ 不建 session,改发一次授权申请卡
|
|
2392
|
+
// 给 owner(节流复用 maybeSendGrantRequestCard 内的 isThrottled),让
|
|
2393
|
+
// owner 决定是否把它加进 allowlist——与人分支 @bot 被挡时的 not_allowed
|
|
2394
|
+
// 体验一致、可发现,而不是静默吞掉。
|
|
2395
|
+
// 只在「真未授权」发卡;已授权但额度耗尽是另一回事(走下游 quota exhausted
|
|
2396
|
+
// 语义),不在这里混。授权卡的申请对象是触发 bot 的 open_id,但审批/操作权限
|
|
2397
|
+
// 仍只归 owner;此刻不建 session,绝不把触发 bot 写成 owner,也不 --mention-back
|
|
2398
|
+
// 回唤它(dispatchHumanMessage 那条才建 session,本分支只发卡后 return)。
|
|
2399
|
+
if (autoTopic) {
|
|
2400
|
+
const seedBotTalk = evaluateBotTalk(larkAppId, chatId, senderOpenId, senderUnionId);
|
|
2401
|
+
if (!seedBotTalk.allowed) {
|
|
2402
|
+
logger.info(`[auto-start:新话题] ${chatId.substring(0, 12)} 其他机器人开新话题但未授权(restricted)→ 发授权卡不自动开工 ` +
|
|
2403
|
+
`msg=${messageId.substring(0, 12)} sender=${senderOpenId?.substring(0, 12) ?? '-'}`);
|
|
2404
|
+
await maybeSendGrantRequestCard(larkAppId, message, chatId, senderOpenId, data)
|
|
2405
|
+
.catch(err => logger.error(`Error sending grant card for foreign-bot new topic: ${err}`));
|
|
2406
|
+
return;
|
|
2407
|
+
}
|
|
2408
|
+
logger.info(`[auto-start:新话题] ${chatId.substring(0, 12)} 其他机器人开新话题免@自动开工 ` +
|
|
2409
|
+
`msg=${messageId.substring(0, 12)} sender=${senderOpenId?.substring(0, 12) ?? '-'} reason=${seedBotTalk.reason}`);
|
|
2410
|
+
const seedCtx = { chatId, messageId, chatType, larkAppId, scope: seedScope, anchor: seedAnchor };
|
|
2411
|
+
await dispatchHumanMessage({ data, ctx: seedCtx, ownsSession: false })
|
|
2412
|
+
.catch(err => logger.error(`Error auto-starting on foreign-bot new topic: ${err}`));
|
|
2413
|
+
return;
|
|
2414
|
+
}
|
|
2415
|
+
}
|
|
2261
2416
|
return;
|
|
2417
|
+
}
|
|
2262
2418
|
const decision = await decideRoutingWithSource(larkAppId, message);
|
|
2263
2419
|
const ctx = { scope: decision.scope, anchor: decision.anchor };
|
|
2264
2420
|
// Honor `/t` / `/topic` from bot senders too, aligning with the human
|