botmux 2.104.0 → 2.105.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 +10 -10
- package/README.md +10 -10
- package/dist/adapters/backend/sandbox.d.ts +5 -1
- package/dist/adapters/backend/sandbox.d.ts.map +1 -1
- package/dist/adapters/backend/sandbox.js +54 -5
- package/dist/adapters/backend/sandbox.js.map +1 -1
- package/dist/adapters/backend/tmux-pipe-backend.d.ts +1 -1
- package/dist/adapters/backend/tmux-pipe-backend.js +1 -1
- package/dist/adapters/backend/zellij-observe-backend.d.ts +1 -1
- package/dist/adapters/backend/zellij-observe-backend.js +1 -1
- package/dist/adapters/cli/claude-code.d.ts +1 -1
- package/dist/adapters/cli/relay.d.ts +2 -2
- package/dist/adapters/cli/relay.js +2 -2
- package/dist/adapters/cli/seed.d.ts +2 -2
- package/dist/adapters/cli/seed.js +2 -2
- package/dist/adapters/cli/shared-hints.d.ts.map +1 -1
- package/dist/adapters/cli/shared-hints.js +1 -0
- package/dist/adapters/cli/shared-hints.js.map +1 -1
- package/dist/bot-registry.d.ts +65 -1
- package/dist/bot-registry.d.ts.map +1 -1
- package/dist/bot-registry.js +145 -0
- package/dist/bot-registry.js.map +1 -1
- package/dist/cli/send-dispatch.d.ts +44 -0
- package/dist/cli/send-dispatch.d.ts.map +1 -1
- package/dist/cli/send-dispatch.js +79 -0
- package/dist/cli/send-dispatch.js.map +1 -1
- package/dist/cli/vc-agent.d.ts +2 -0
- package/dist/cli/vc-agent.d.ts.map +1 -0
- package/dist/cli/vc-agent.js +331 -0
- package/dist/cli/vc-agent.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +106 -24
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +8 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +13 -1
- package/dist/config.js.map +1 -1
- package/dist/core/auto-start.d.ts +2 -2
- package/dist/core/auto-start.js +2 -2
- package/dist/core/command-handler.d.ts.map +1 -1
- package/dist/core/command-handler.js +2 -1
- package/dist/core/command-handler.js.map +1 -1
- package/dist/core/dashboard-events.d.ts +5 -0
- package/dist/core/dashboard-events.d.ts.map +1 -1
- package/dist/core/dashboard-events.js.map +1 -1
- package/dist/core/dashboard-ipc-server.d.ts.map +1 -1
- package/dist/core/dashboard-ipc-server.js +47 -2
- package/dist/core/dashboard-ipc-server.js.map +1 -1
- package/dist/core/idle-worker-sweeper.d.ts +1 -1
- package/dist/core/idle-worker-sweeper.js +1 -1
- package/dist/core/passthrough-commands.d.ts.map +1 -1
- package/dist/core/passthrough-commands.js +1 -0
- package/dist/core/passthrough-commands.js.map +1 -1
- package/dist/core/scheduler.d.ts +12 -0
- package/dist/core/scheduler.d.ts.map +1 -1
- package/dist/core/scheduler.js +67 -7
- package/dist/core/scheduler.js.map +1 -1
- package/dist/core/session-discovery.js +1 -1
- package/dist/core/session-discovery.js.map +1 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +33 -7
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/trigger-session.d.ts.map +1 -1
- package/dist/core/trigger-session.js +78 -23
- package/dist/core/trigger-session.js.map +1 -1
- package/dist/core/worker-pool.d.ts +4 -1
- package/dist/core/worker-pool.d.ts.map +1 -1
- package/dist/core/worker-pool.js +4 -0
- package/dist/core/worker-pool.js.map +1 -1
- package/dist/core/zellij-adopt-discovery.js +1 -1
- package/dist/core/zellij-adopt-discovery.js.map +1 -1
- package/dist/daemon.d.ts +121 -0
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +2644 -2
- package/dist/daemon.js.map +1 -1
- package/dist/dashboard/federated-group-core.js +1 -1
- package/dist/dashboard/federated-group-core.js.map +1 -1
- package/dist/dashboard/federation-api.js +1 -1
- package/dist/dashboard/schedule-card-model.d.ts +4 -3
- package/dist/dashboard/schedule-card-model.d.ts.map +1 -1
- package/dist/dashboard/schedule-card-model.js +5 -4
- package/dist/dashboard/schedule-card-model.js.map +1 -1
- package/dist/dashboard/settings-write-applier.d.ts +37 -3
- package/dist/dashboard/settings-write-applier.d.ts.map +1 -1
- package/dist/dashboard/settings-write-applier.js +63 -0
- package/dist/dashboard/settings-write-applier.js.map +1 -1
- package/dist/dashboard/web/i18n.d.ts.map +1 -1
- package/dist/dashboard/web/i18n.js +28 -0
- package/dist/dashboard/web/i18n.js.map +1 -1
- package/dist/dashboard/web/insights.js +19 -19
- package/dist/dashboard/web/insights.js.map +1 -1
- package/dist/dashboard/web/overview-page.d.ts.map +1 -1
- package/dist/dashboard/web/overview-page.js +7 -4
- package/dist/dashboard/web/overview-page.js.map +1 -1
- package/dist/dashboard/web/schedules-page.d.ts +1 -1
- package/dist/dashboard/web/schedules-page.d.ts.map +1 -1
- package/dist/dashboard/web/schedules-page.js +7 -3
- package/dist/dashboard/web/schedules-page.js.map +1 -1
- package/dist/dashboard/web/sessions.js +2 -2
- package/dist/dashboard/web/settings-page.d.ts +9 -0
- package/dist/dashboard/web/settings-page.d.ts.map +1 -1
- package/dist/dashboard/web/settings-page.js +132 -43
- package/dist/dashboard/web/settings-page.js.map +1 -1
- package/dist/dashboard/web/store.d.ts +6 -0
- package/dist/dashboard/web/store.d.ts.map +1 -1
- package/dist/dashboard/web/store.js +18 -1
- package/dist/dashboard/web/store.js.map +1 -1
- package/dist/dashboard/webhook-routes.d.ts.map +1 -1
- package/dist/dashboard/webhook-routes.js +24 -0
- package/dist/dashboard/webhook-routes.js.map +1 -1
- package/dist/dashboard-web/app.js +3 -3
- package/dist/dashboard-web/chunks/{bot-defaults-page-Z36I5CKM.js → bot-defaults-page-3OIY7N76.js} +1 -1
- package/dist/dashboard-web/chunks/{chunk-2BBCKWNO.js → chunk-BNEXMNQD.js} +3 -3
- package/dist/dashboard-web/chunks/{chunk-QDKIUULH.js → chunk-DKKOGZCG.js} +1 -1
- package/dist/dashboard-web/chunks/chunk-LXIK7OUJ.js +1 -0
- package/dist/dashboard-web/chunks/{chunk-BAMNP73K.js → chunk-VFCACTRF.js} +1 -1
- package/dist/dashboard-web/chunks/{connectors-I3MGERCM.js → connectors-VDOAKUW3.js} +1 -1
- package/dist/dashboard-web/chunks/{groups-page-DTP2L4FQ.js → groups-page-CX5AN4XG.js} +1 -1
- package/dist/dashboard-web/chunks/{insights-page-FNI24WYF.js → insights-page-DOMRL4S6.js} +1 -1
- package/dist/dashboard-web/chunks/overview-page-AZBAXVZ7.js +1 -0
- package/dist/dashboard-web/chunks/{roles-page-A5DZ7Q6U.js → roles-page-3FEAH6S4.js} +1 -1
- package/dist/dashboard-web/chunks/schedules-CTQEA7IE.js +1 -0
- package/dist/dashboard-web/chunks/{sessions-YJ735IH4.js → sessions-LVZCXO2Z.js} +1 -1
- package/dist/dashboard-web/chunks/{sessions-page-2REIJ56C.js → sessions-page-NHBJDSBC.js} +1 -1
- package/dist/dashboard-web/chunks/settings-page-CRDIHRNE.js +2 -0
- package/dist/dashboard-web/chunks/{skills-page-ZCCLHWMJ.js → skills-page-VUG3EPWX.js} +1 -1
- package/dist/dashboard-web/chunks/{team-federation-page-4FCGO3WW.js → team-federation-page-ZKL3YMGN.js} +1 -1
- package/dist/dashboard-web/chunks/{workflows-KFJ7O57L.js → workflows-4BYQQBFP.js} +1 -1
- package/dist/dashboard-web/index.html +1 -1
- package/dist/dashboard-web/style.css +111 -16
- package/dist/dashboard.js +196 -2
- package/dist/dashboard.js.map +1 -1
- package/dist/global-config.d.ts +30 -0
- package/dist/global-config.d.ts.map +1 -1
- package/dist/global-config.js +64 -1
- package/dist/global-config.js.map +1 -1
- package/dist/i18n/en.d.ts.map +1 -1
- package/dist/i18n/en.js +10 -7
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/zh.d.ts.map +1 -1
- package/dist/i18n/zh.js +10 -7
- package/dist/i18n/zh.js.map +1 -1
- package/dist/im/lark/card-builder.d.ts +1 -1
- package/dist/im/lark/card-builder.js +1 -1
- package/dist/im/lark/card-handler.d.ts +3 -0
- package/dist/im/lark/card-handler.d.ts.map +1 -1
- package/dist/im/lark/card-handler.js +8 -0
- package/dist/im/lark/card-handler.js.map +1 -1
- package/dist/im/lark/client.d.ts +1 -0
- package/dist/im/lark/client.d.ts.map +1 -1
- package/dist/im/lark/client.js +19 -0
- package/dist/im/lark/client.js.map +1 -1
- package/dist/im/lark/event-dispatcher.d.ts +10 -0
- package/dist/im/lark/event-dispatcher.d.ts.map +1 -1
- package/dist/im/lark/event-dispatcher.js +100 -21
- package/dist/im/lark/event-dispatcher.js.map +1 -1
- package/dist/im/lark/grant-command.d.ts +1 -1
- package/dist/im/lark/grant-command.js +1 -1
- package/dist/im/lark/workflow-slash-command.js +4 -0
- package/dist/im/lark/workflow-slash-command.js.map +1 -1
- package/dist/mir-prompt.d.ts +16 -0
- package/dist/mir-prompt.d.ts.map +1 -0
- package/dist/mir-prompt.js +170 -0
- package/dist/mir-prompt.js.map +1 -0
- package/dist/mir-runner.js +1 -149
- package/dist/mir-runner.js.map +1 -1
- package/dist/platform/bind.d.ts.map +1 -1
- package/dist/platform/bind.js +3 -11
- package/dist/platform/bind.js.map +1 -1
- package/dist/platform/binding.d.ts +4 -5
- package/dist/platform/binding.d.ts.map +1 -1
- package/dist/platform/binding.js +0 -11
- package/dist/platform/binding.js.map +1 -1
- package/dist/platform/tunnel-client.d.ts.map +1 -1
- package/dist/platform/tunnel-client.js +37 -28
- package/dist/platform/tunnel-client.js.map +1 -1
- package/dist/services/deployment-identity.d.ts +1 -1
- package/dist/services/deployment-identity.d.ts.map +1 -1
- package/dist/services/deployment-identity.js +1 -1
- package/dist/services/deployment-identity.js.map +1 -1
- package/dist/services/doc-subs-store.js +1 -1
- package/dist/services/team-board-store.js +1 -1
- package/dist/services/team-board-store.js.map +1 -1
- package/dist/services/trigger-types.d.ts +2 -1
- package/dist/services/trigger-types.d.ts.map +1 -1
- package/dist/services/trigger-types.js +11 -2
- package/dist/services/trigger-types.js.map +1 -1
- package/dist/services/vc-meeting-runtime-store.d.ts +55 -0
- package/dist/services/vc-meeting-runtime-store.d.ts.map +1 -0
- package/dist/services/vc-meeting-runtime-store.js +313 -0
- package/dist/services/vc-meeting-runtime-store.js.map +1 -0
- package/dist/services/voice/index.d.ts +6 -1
- package/dist/services/voice/index.d.ts.map +1 -1
- package/dist/services/voice/index.js +12 -5
- package/dist/services/voice/index.js.map +1 -1
- package/dist/services/voice/sami.js +1 -1
- package/dist/setup/lark-scopes.json +5 -0
- package/dist/setup/verify-permissions.d.ts +6 -0
- package/dist/setup/verify-permissions.d.ts.map +1 -1
- package/dist/setup/verify-permissions.js +17 -0
- package/dist/setup/verify-permissions.js.map +1 -1
- package/dist/skills/definitions.d.ts.map +1 -1
- package/dist/skills/definitions.js +10 -0
- package/dist/skills/definitions.js.map +1 -1
- package/dist/utils/daemon-discovery.d.ts +2 -0
- package/dist/utils/daemon-discovery.d.ts.map +1 -1
- package/dist/utils/daemon-discovery.js +2 -0
- package/dist/utils/daemon-discovery.js.map +1 -1
- package/dist/utils/timezone.d.ts +51 -0
- package/dist/utils/timezone.d.ts.map +1 -0
- package/dist/utils/timezone.js +110 -0
- package/dist/utils/timezone.js.map +1 -0
- package/dist/vc-agent/cards.d.ts +47 -0
- package/dist/vc-agent/cards.d.ts.map +1 -0
- package/dist/vc-agent/cards.js +489 -0
- package/dist/vc-agent/cards.js.map +1 -0
- package/dist/vc-agent/meeting-state.d.ts +39 -0
- package/dist/vc-agent/meeting-state.d.ts.map +1 -0
- package/dist/vc-agent/meeting-state.js +186 -0
- package/dist/vc-agent/meeting-state.js.map +1 -0
- package/dist/vc-agent/normalizer.d.ts +13 -0
- package/dist/vc-agent/normalizer.d.ts.map +1 -0
- package/dist/vc-agent/normalizer.js +411 -0
- package/dist/vc-agent/normalizer.js.map +1 -0
- package/dist/vc-agent/polling-source.d.ts +36 -0
- package/dist/vc-agent/polling-source.d.ts.map +1 -0
- package/dist/vc-agent/polling-source.js +129 -0
- package/dist/vc-agent/polling-source.js.map +1 -0
- package/dist/vc-agent/push-source.d.ts +13 -0
- package/dist/vc-agent/push-source.d.ts.map +1 -0
- package/dist/vc-agent/push-source.js +109 -0
- package/dist/vc-agent/push-source.js.map +1 -0
- package/dist/vc-agent/realtime/audio-source.d.ts +6 -0
- package/dist/vc-agent/realtime/audio-source.d.ts.map +1 -0
- package/dist/vc-agent/realtime/audio-source.js +17 -0
- package/dist/vc-agent/realtime/audio-source.js.map +1 -0
- package/dist/vc-agent/realtime/endpoint.d.ts +6 -0
- package/dist/vc-agent/realtime/endpoint.d.ts.map +1 -0
- package/dist/vc-agent/realtime/endpoint.js +25 -0
- package/dist/vc-agent/realtime/endpoint.js.map +1 -0
- package/dist/vc-agent/realtime/errors.d.ts +9 -0
- package/dist/vc-agent/realtime/errors.d.ts.map +1 -0
- package/dist/vc-agent/realtime/errors.js +17 -0
- package/dist/vc-agent/realtime/errors.js.map +1 -0
- package/dist/vc-agent/realtime/events.d.ts +24 -0
- package/dist/vc-agent/realtime/events.d.ts.map +1 -0
- package/dist/vc-agent/realtime/events.js +190 -0
- package/dist/vc-agent/realtime/events.js.map +1 -0
- package/dist/vc-agent/realtime/frontier.d.ts +34 -0
- package/dist/vc-agent/realtime/frontier.d.ts.map +1 -0
- package/dist/vc-agent/realtime/frontier.js +40 -0
- package/dist/vc-agent/realtime/frontier.js.map +1 -0
- package/dist/vc-agent/realtime/index.d.ts +11 -0
- package/dist/vc-agent/realtime/index.d.ts.map +1 -0
- package/dist/vc-agent/realtime/index.js +11 -0
- package/dist/vc-agent/realtime/index.js.map +1 -0
- package/dist/vc-agent/realtime/pacer.d.ts +21 -0
- package/dist/vc-agent/realtime/pacer.d.ts.map +1 -0
- package/dist/vc-agent/realtime/pacer.js +80 -0
- package/dist/vc-agent/realtime/pacer.js.map +1 -0
- package/dist/vc-agent/realtime/protobuf.d.ts +33 -0
- package/dist/vc-agent/realtime/protobuf.d.ts.map +1 -0
- package/dist/vc-agent/realtime/protobuf.js +159 -0
- package/dist/vc-agent/realtime/protobuf.js.map +1 -0
- package/dist/vc-agent/realtime/protocol.d.ts +4 -0
- package/dist/vc-agent/realtime/protocol.d.ts.map +1 -0
- package/dist/vc-agent/realtime/protocol.js +59 -0
- package/dist/vc-agent/realtime/protocol.js.map +1 -0
- package/dist/vc-agent/realtime/session.d.ts +39 -0
- package/dist/vc-agent/realtime/session.d.ts.map +1 -0
- package/dist/vc-agent/realtime/session.js +221 -0
- package/dist/vc-agent/realtime/session.js.map +1 -0
- package/dist/vc-agent/realtime/transport.d.ts +23 -0
- package/dist/vc-agent/realtime/transport.d.ts.map +1 -0
- package/dist/vc-agent/realtime/transport.js +112 -0
- package/dist/vc-agent/realtime/transport.js.map +1 -0
- package/dist/vc-agent/realtime/types.d.ts +84 -0
- package/dist/vc-agent/realtime/types.d.ts.map +1 -0
- package/dist/vc-agent/realtime/types.js +5 -0
- package/dist/vc-agent/realtime/types.js.map +1 -0
- package/dist/vc-agent/types.d.ts +142 -0
- package/dist/vc-agent/types.d.ts.map +1 -0
- package/dist/vc-agent/types.js +2 -0
- package/dist/vc-agent/types.js.map +1 -0
- package/dist/worker.js +3 -3
- package/dist/worker.js.map +1 -1
- package/dist/workflows/attempt-resume.d.ts +4 -0
- package/dist/workflows/attempt-resume.d.ts.map +1 -1
- package/dist/workflows/attempt-resume.js +2 -0
- package/dist/workflows/attempt-resume.js.map +1 -1
- package/dist/workflows/attempt-terminal.d.ts +4 -0
- package/dist/workflows/attempt-terminal.d.ts.map +1 -1
- package/dist/workflows/attempt-terminal.js.map +1 -1
- package/dist/workflows/daemon-spawn.d.ts.map +1 -1
- package/dist/workflows/daemon-spawn.js +7 -0
- package/dist/workflows/daemon-spawn.js.map +1 -1
- package/dist/workflows/events/payloads.d.ts +32 -0
- package/dist/workflows/events/payloads.d.ts.map +1 -1
- package/dist/workflows/events/payloads.js +4 -0
- package/dist/workflows/events/payloads.js.map +1 -1
- package/dist/workflows/events/schema.d.ts +56 -0
- package/dist/workflows/events/schema.d.ts.map +1 -1
- package/dist/workflows/runtime.d.ts +4 -0
- package/dist/workflows/runtime.d.ts.map +1 -1
- package/dist/workflows/runtime.js.map +1 -1
- package/dist/workflows/spawn-policy.d.ts +14 -0
- package/dist/workflows/spawn-policy.d.ts.map +1 -0
- package/dist/workflows/spawn-policy.js +9 -0
- package/dist/workflows/spawn-policy.js.map +1 -0
- package/dist/workflows/v3/bot-resolve.d.ts.map +1 -1
- package/dist/workflows/v3/bot-resolve.js +4 -0
- package/dist/workflows/v3/bot-resolve.js.map +1 -1
- package/dist/workflows/v3/cli-run.d.ts.map +1 -1
- package/dist/workflows/v3/cli-run.js +4 -0
- package/dist/workflows/v3/cli-run.js.map +1 -1
- package/dist/workflows/v3/contract.d.ts +9 -3
- package/dist/workflows/v3/contract.d.ts.map +1 -1
- package/dist/workflows/v3/contract.js +3 -3
- package/dist/workflows/v3/contract.js.map +1 -1
- package/dist/workflows/v3/ephemeral-pool.d.ts.map +1 -1
- package/dist/workflows/v3/ephemeral-pool.js +2 -0
- package/dist/workflows/v3/ephemeral-pool.js.map +1 -1
- package/dist/workflows/v3/runtime.js +1 -1
- package/dist/workflows/v3/runtime.js.map +1 -1
- package/package.json +1 -1
- package/dist/dashboard-web/chunks/chunk-76J7PNZI.js +0 -1
- package/dist/dashboard-web/chunks/overview-page-EHCZJBWY.js +0 -1
- package/dist/dashboard-web/chunks/schedules-RSXALJU4.js +0 -1
- package/dist/dashboard-web/chunks/settings-page-XKFTXTDE.js +0 -2
package/dist/dashboard.js
CHANGED
|
@@ -30,6 +30,7 @@ import { FeishuLoginManager } from './dashboard/feishu-login.js';
|
|
|
30
30
|
import { CLI_SELECT_OPTIONS, resolveCliSelection, isTtadkWrapper, ttadkAcceptsModel, TTADK_DEFAULT_MODEL, TTADK_MODEL_SUGGESTIONS, } from './setup/cli-selection.js';
|
|
31
31
|
import { invalidWorkingDirs } from './utils/working-dir.js';
|
|
32
32
|
import { invalidateGlobalConfigCache, mergeGlobalConfig, readGlobalConfig } from './global-config.js';
|
|
33
|
+
import { hostLocalTimeZone, scheduleTimeZone } from './utils/timezone.js';
|
|
33
34
|
import { buildDashboardUrls } from './core/dashboard-url.js';
|
|
34
35
|
import { deleteWhiteboard, listWhiteboards, readWhiteboard, whiteboardEnabled } from './services/whiteboard-store.js';
|
|
35
36
|
import { isLocalDevInstall, botmuxVersion, botmuxCliEntry } from './utils/install-info.js';
|
|
@@ -49,7 +50,8 @@ import { listTeamReports, readTeamBoard, setTeamBoardEntry } from './services/te
|
|
|
49
50
|
import { hd2dAssetPath, hd2dStatus, startHd2dDownload } from './dashboard/hd2d-assets.js';
|
|
50
51
|
import { installLocalSkillLinks, readSkillRegistry, removeInstalledSkill, updateInstalledSkillAsync, } from './services/skill-registry-store.js';
|
|
51
52
|
import { redactGitUrlCredentials } from './core/skills/sources.js';
|
|
52
|
-
import { loadBotConfigs } from './bot-registry.js';
|
|
53
|
+
import { getBot, loadBotConfigs } from './bot-registry.js';
|
|
54
|
+
import { findEntryIndex, readRawConfig, requireConfigPath, writeRawConfigAtomic } from './services/config-store.js';
|
|
53
55
|
import { discoverNativeCliSkillGroups } from './core/skills/discovery.js';
|
|
54
56
|
import { analyzeSkillReferences } from './core/skills/references.js';
|
|
55
57
|
import { discoverDashboardSkills, installDashboardSkill, parseDashboardSkillInstallRequest, parseInstallLocalLinksSources, MAX_LOCAL_LINK_SOURCES } from './dashboard/skill-install-request.js';
|
|
@@ -61,6 +63,8 @@ import { startPlatformTunnelClient } from './platform/tunnel-client.js';
|
|
|
61
63
|
import { applyPlatformTeamSync, getPlatformTeamSyncRev, listPlatformTeams } from './services/platform-team-store.js';
|
|
62
64
|
import { getBotUnionId } from './services/bot-union-ids-store.js';
|
|
63
65
|
import { cleanupIdleSessions, parseIdleCleanupHours } from './dashboard/session-cleanup.js';
|
|
66
|
+
import { larkHosts } from './im/lark/lark-hosts.js';
|
|
67
|
+
import { VC_MEETING_FEATURE_SCOPES, VC_MEETING_REALTIME_VOICE_SCOPES, } from './setup/verify-permissions.js';
|
|
64
68
|
const SECRET_PATH = join(homedir(), '.botmux', '.dashboard-secret');
|
|
65
69
|
const TOKEN_PATH = join(homedir(), '.botmux', '.dashboard-token');
|
|
66
70
|
/** Per-daemon budget for the cross-daemon insight overview fan-out — bounds
|
|
@@ -242,6 +246,183 @@ const botOnboarding = new BotOnboardingManager({
|
|
|
242
246
|
const feishuLogin = new FeishuLoginManager();
|
|
243
247
|
const subs = new Map();
|
|
244
248
|
const attaching = new Set(); // dedup concurrent attaches per appId
|
|
249
|
+
function vcMeetingListenerBotOptions() {
|
|
250
|
+
try {
|
|
251
|
+
const onlineByAppId = new Map(registry.list().map(bot => [bot.larkAppId, bot]));
|
|
252
|
+
return loadBotConfigs().map(bot => ({
|
|
253
|
+
larkAppId: bot.larkAppId,
|
|
254
|
+
botName: bot.displayName ?? onlineByAppId.get(bot.larkAppId)?.botName ?? bot.name ?? null,
|
|
255
|
+
cliId: onlineByAppId.get(bot.larkAppId)?.cliId ?? bot.cliId,
|
|
256
|
+
vcMeetingAgentEnabled: bot.vcMeetingAgent?.enabled === true,
|
|
257
|
+
hasLarkCliProfile: typeof bot.vcMeetingAgent?.larkCliProfile === 'string' && bot.vcMeetingAgent.larkCliProfile.trim().length > 0,
|
|
258
|
+
}));
|
|
259
|
+
}
|
|
260
|
+
catch {
|
|
261
|
+
return [];
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
async function fetchGrantedScopesForBotConfig(bot) {
|
|
265
|
+
const brand = bot.brand === 'lark' ? 'lark' : 'feishu';
|
|
266
|
+
const openApi = larkHosts(brand).openApi;
|
|
267
|
+
const ac = new AbortController();
|
|
268
|
+
const timer = setTimeout(() => ac.abort(), 10_000);
|
|
269
|
+
try {
|
|
270
|
+
const tokenRes = await fetch(`${openApi}/open-apis/auth/v3/tenant_access_token/internal`, {
|
|
271
|
+
method: 'POST',
|
|
272
|
+
headers: { 'Content-Type': 'application/json' },
|
|
273
|
+
body: JSON.stringify({ app_id: bot.larkAppId, app_secret: bot.larkAppSecret }),
|
|
274
|
+
signal: ac.signal,
|
|
275
|
+
});
|
|
276
|
+
const tokenData = await tokenRes.json();
|
|
277
|
+
if (tokenData?.code !== 0 || typeof tokenData?.tenant_access_token !== 'string') {
|
|
278
|
+
return { ok: false, error: `vcMeetingAgent_listenerBot_invalid_credentials: code=${tokenData?.code ?? '?'} msg=${tokenData?.msg ?? ''}` };
|
|
279
|
+
}
|
|
280
|
+
const infoRes = await fetch(`${openApi}/open-apis/application/v6/applications/${bot.larkAppId}?lang=zh_cn`, { headers: { Authorization: `Bearer ${tokenData.tenant_access_token}` }, signal: ac.signal });
|
|
281
|
+
const infoData = await infoRes.json();
|
|
282
|
+
if (infoData?.code === 99991672) {
|
|
283
|
+
return { ok: false, error: 'vcMeetingAgent_listenerBot_scope_check_unavailable: missing application:application:self_manage' };
|
|
284
|
+
}
|
|
285
|
+
if (infoData?.code !== 0) {
|
|
286
|
+
return { ok: false, error: `vcMeetingAgent_listenerBot_scope_check_failed: code=${infoData?.code ?? '?'} msg=${infoData?.msg ?? ''}` };
|
|
287
|
+
}
|
|
288
|
+
const scopesRaw = infoData.data?.app?.scopes
|
|
289
|
+
?? infoData.data?.application?.scopes
|
|
290
|
+
?? infoData.data?.scopes
|
|
291
|
+
?? [];
|
|
292
|
+
if (!Array.isArray(scopesRaw) || scopesRaw.length === 0) {
|
|
293
|
+
return { ok: false, error: 'vcMeetingAgent_listenerBot_scope_check_failed: empty scopes' };
|
|
294
|
+
}
|
|
295
|
+
const granted = new Set(scopesRaw.map(s => typeof s === 'string' ? s : s?.scope).filter(Boolean));
|
|
296
|
+
return { ok: true, granted };
|
|
297
|
+
}
|
|
298
|
+
catch (err) {
|
|
299
|
+
return {
|
|
300
|
+
ok: false,
|
|
301
|
+
error: ac.signal.aborted
|
|
302
|
+
? 'vcMeetingAgent_listenerBot_scope_check_timeout'
|
|
303
|
+
: `vcMeetingAgent_listenerBot_scope_check_failed: ${err?.message ?? err}`,
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
finally {
|
|
307
|
+
clearTimeout(timer);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
async function validateVcMeetingListenerBotAppId(appId) {
|
|
311
|
+
let bots;
|
|
312
|
+
try {
|
|
313
|
+
bots = loadBotConfigs();
|
|
314
|
+
}
|
|
315
|
+
catch (err) {
|
|
316
|
+
return { ok: false, error: `vcMeetingAgent_listenerBot_config_unavailable: ${err?.message ?? err}` };
|
|
317
|
+
}
|
|
318
|
+
const bot = bots.find(b => b.larkAppId === appId);
|
|
319
|
+
if (!bot)
|
|
320
|
+
return { ok: false, error: 'vcMeetingAgent_listenerBot_unknown' };
|
|
321
|
+
const cfg = bot.vcMeetingAgent ?? {};
|
|
322
|
+
if (!cfg.larkCliProfile)
|
|
323
|
+
return { ok: false, error: 'vcMeetingAgent_listenerBot_missing_larkCliProfile' };
|
|
324
|
+
const granted = await fetchGrantedScopesForBotConfig(bot);
|
|
325
|
+
if (!granted.ok)
|
|
326
|
+
return granted;
|
|
327
|
+
const required = cfg.realtimeVoice?.enabled === true
|
|
328
|
+
? [...VC_MEETING_FEATURE_SCOPES, ...VC_MEETING_REALTIME_VOICE_SCOPES]
|
|
329
|
+
: VC_MEETING_FEATURE_SCOPES;
|
|
330
|
+
const missing = required.filter(scope => !granted.granted.has(scope.name));
|
|
331
|
+
if (missing.length > 0) {
|
|
332
|
+
return { ok: false, error: `vcMeetingAgent_listenerBot_missing_scopes: ${missing.map(s => s.name).join(',')}` };
|
|
333
|
+
}
|
|
334
|
+
return { ok: true };
|
|
335
|
+
}
|
|
336
|
+
function normalizeVcMeetingAgentRecord(raw) {
|
|
337
|
+
return raw && typeof raw === 'object' && !Array.isArray(raw)
|
|
338
|
+
? { ...raw }
|
|
339
|
+
: {};
|
|
340
|
+
}
|
|
341
|
+
function compactVcMeetingAgentEntry(entry, next) {
|
|
342
|
+
if (Object.keys(next).length > 0)
|
|
343
|
+
entry.vcMeetingAgent = next;
|
|
344
|
+
else
|
|
345
|
+
delete entry.vcMeetingAgent;
|
|
346
|
+
}
|
|
347
|
+
function refreshLocalVcMeetingAgentConfig(appId) {
|
|
348
|
+
try {
|
|
349
|
+
const latest = loadBotConfigs().find(bot => bot.larkAppId === appId);
|
|
350
|
+
const live = getBot(appId);
|
|
351
|
+
live.config.vcMeetingAgent = latest?.vcMeetingAgent;
|
|
352
|
+
}
|
|
353
|
+
catch {
|
|
354
|
+
// This dashboard process may not host the target bot daemon.
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
async function reloadVcMeetingBotConfigOnDaemons(appIds) {
|
|
358
|
+
const unique = [...new Set(appIds.filter(Boolean))];
|
|
359
|
+
for (const appId of unique)
|
|
360
|
+
refreshLocalVcMeetingAgentConfig(appId);
|
|
361
|
+
await Promise.all(unique.map(async (appId) => {
|
|
362
|
+
const d = registry.getByAppId(appId);
|
|
363
|
+
if (!d)
|
|
364
|
+
return;
|
|
365
|
+
await fetch(`http://127.0.0.1:${d.ipcPort}/api/bot-config/reload`, {
|
|
366
|
+
method: 'POST',
|
|
367
|
+
signal: AbortSignal.timeout(10_000),
|
|
368
|
+
}).catch(() => undefined);
|
|
369
|
+
}));
|
|
370
|
+
}
|
|
371
|
+
async function syncVcMeetingListenerBotConfig(listenerBotAppId, previousListenerBotAppId) {
|
|
372
|
+
const nextAppId = listenerBotAppId?.trim() || null;
|
|
373
|
+
const prevAppId = previousListenerBotAppId?.trim() || null;
|
|
374
|
+
if (!nextAppId && !prevAppId)
|
|
375
|
+
return { ok: true };
|
|
376
|
+
const changedAppIds = new Set();
|
|
377
|
+
try {
|
|
378
|
+
const path = requireConfigPath();
|
|
379
|
+
await withFileLock(path, async () => {
|
|
380
|
+
const raw = await readRawConfig(path);
|
|
381
|
+
let changed = false;
|
|
382
|
+
if (nextAppId) {
|
|
383
|
+
const idx = findEntryIndex(raw, nextAppId);
|
|
384
|
+
if (idx < 0)
|
|
385
|
+
throw new Error('bot_not_in_config');
|
|
386
|
+
const entry = raw[idx];
|
|
387
|
+
const next = normalizeVcMeetingAgentRecord(entry.vcMeetingAgent);
|
|
388
|
+
let entryChanged = false;
|
|
389
|
+
if (next.enabled !== true) {
|
|
390
|
+
next.enabled = true;
|
|
391
|
+
next.dashboardManagedListener = true;
|
|
392
|
+
entryChanged = true;
|
|
393
|
+
}
|
|
394
|
+
if (entryChanged) {
|
|
395
|
+
compactVcMeetingAgentEntry(entry, next);
|
|
396
|
+
changed = true;
|
|
397
|
+
changedAppIds.add(nextAppId);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
if (prevAppId && prevAppId !== nextAppId) {
|
|
401
|
+
const idx = findEntryIndex(raw, prevAppId);
|
|
402
|
+
if (idx >= 0) {
|
|
403
|
+
const entry = raw[idx];
|
|
404
|
+
const next = normalizeVcMeetingAgentRecord(entry.vcMeetingAgent);
|
|
405
|
+
if (next.dashboardManagedListener === true) {
|
|
406
|
+
delete next.dashboardManagedListener;
|
|
407
|
+
if (next.enabled === true)
|
|
408
|
+
delete next.enabled;
|
|
409
|
+
compactVcMeetingAgentEntry(entry, next);
|
|
410
|
+
changed = true;
|
|
411
|
+
changedAppIds.add(prevAppId);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
if (changed)
|
|
416
|
+
await writeRawConfigAtomic(path, raw);
|
|
417
|
+
});
|
|
418
|
+
}
|
|
419
|
+
catch (err) {
|
|
420
|
+
return { ok: false, error: `vcMeetingAgent_listenerBot_config_write_failed: ${err?.message ?? err}` };
|
|
421
|
+
}
|
|
422
|
+
if (changedAppIds.size > 0)
|
|
423
|
+
await reloadVcMeetingBotConfigOnDaemons([...changedAppIds]);
|
|
424
|
+
return { ok: true };
|
|
425
|
+
}
|
|
245
426
|
function resolveDashboardSettings() {
|
|
246
427
|
const global = readGlobalConfig();
|
|
247
428
|
const dashboard = global.dashboard ?? {};
|
|
@@ -249,11 +430,19 @@ function resolveDashboardSettings() {
|
|
|
249
430
|
publicReadOnly: dashboard.publicReadOnly ?? config.dashboard.publicReadOnly,
|
|
250
431
|
openTerminalInFeishu: dashboard.openTerminalInFeishu === true,
|
|
251
432
|
chatBotDiscovery: dashboard.chatBotDiscovery !== false, // default ON
|
|
433
|
+
vcMeetingAgent: {
|
|
434
|
+
enabled: global.vcMeetingAgent?.enabled !== false,
|
|
435
|
+
listenerBotAppId: global.vcMeetingAgent?.listenerBotAppId ?? null,
|
|
436
|
+
listenerBotOptions: vcMeetingListenerBotOptions(),
|
|
437
|
+
},
|
|
252
438
|
repoPickerMode: global.repoPickerMode ?? 'all',
|
|
253
439
|
maintenance: global.maintenance ?? {},
|
|
254
440
|
localDevInstall: isLocalDevInstall(),
|
|
255
441
|
whiteboard: { enabled: global.whiteboard?.enabled === true },
|
|
256
442
|
remoteAccess: global.remoteAccess === true,
|
|
443
|
+
scheduleTimeZone: global.scheduleTimeZone ?? null,
|
|
444
|
+
hostTimeZone: hostLocalTimeZone(),
|
|
445
|
+
effectiveScheduleTimeZone: scheduleTimeZone(),
|
|
257
446
|
};
|
|
258
447
|
}
|
|
259
448
|
// Single shared deps object for `applySettingsWrite` — both the browser
|
|
@@ -263,6 +452,8 @@ async function reloadLocaleOnAllDaemons() {
|
|
|
263
452
|
await Promise.all(registry.list().map(d => fetch(`http://127.0.0.1:${d.ipcPort}/api/locale/reload`, { method: 'POST' }).catch(() => undefined)));
|
|
264
453
|
}
|
|
265
454
|
const settingsWriteApplierDeps = defaultSettingsWriteApplierDeps(resolveDashboardSettings, reloadLocaleOnAllDaemons);
|
|
455
|
+
settingsWriteApplierDeps.syncVcMeetingListenerBotConfig = syncVcMeetingListenerBotConfig;
|
|
456
|
+
settingsWriteApplierDeps.validateVcMeetingListenerBotAppId = validateVcMeetingListenerBotAppId;
|
|
266
457
|
/** Helper to render a {status, body} HandlerResult through `res`. */
|
|
267
458
|
function writeHandlerResult(res, result) {
|
|
268
459
|
const headers = { 'content-type': 'application/json', ...(result.headers ?? {}) };
|
|
@@ -1232,7 +1423,10 @@ const server = createServer(async (req, res) => {
|
|
|
1232
1423
|
const schedules = authed
|
|
1233
1424
|
? aggregator.getSchedules()
|
|
1234
1425
|
: redactSchedulesForPublic(aggregator.getSchedules());
|
|
1235
|
-
|
|
1426
|
+
// Effective schedule timezone: nextRunAt/lastRunAt instants must be
|
|
1427
|
+
// rendered in the zone the scheduler fires in (not the viewer's browser
|
|
1428
|
+
// zone), so the web schedule/overview lists match cron/card/CLI displays.
|
|
1429
|
+
return jsonRes(res, 200, { schedules, timezone: scheduleTimeZone() });
|
|
1236
1430
|
}
|
|
1237
1431
|
if (req.method === 'GET' && url.pathname === '/api/settings') {
|
|
1238
1432
|
// `authed` lets the Settings page disable toggles for read-only
|