botmux 3.10.0 → 3.23.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.
- package/README.en.md +57 -4
- package/README.md +89 -4
- package/package.json +47 -31
- package/scripts/install-path-entry.mjs +263 -0
- package/scripts/postinstall-bin.mjs +388 -0
- package/dist/.runtime-build-id +0 -1
- package/dist/adapters/adopt-route.d.ts +0 -63
- package/dist/adapters/adopt-route.d.ts.map +0 -1
- package/dist/adapters/adopt-route.js +0 -196
- package/dist/adapters/adopt-route.js.map +0 -1
- package/dist/adapters/backend/capabilities.d.ts +0 -17
- package/dist/adapters/backend/capabilities.d.ts.map +0 -1
- package/dist/adapters/backend/capabilities.js +0 -22
- package/dist/adapters/backend/capabilities.js.map +0 -1
- package/dist/adapters/backend/critical-control-key.d.ts +0 -19
- package/dist/adapters/backend/critical-control-key.d.ts.map +0 -1
- package/dist/adapters/backend/critical-control-key.js +0 -34
- package/dist/adapters/backend/critical-control-key.js.map +0 -1
- package/dist/adapters/backend/herdr-backend.d.ts +0 -164
- package/dist/adapters/backend/herdr-backend.d.ts.map +0 -1
- package/dist/adapters/backend/herdr-backend.js +0 -1073
- package/dist/adapters/backend/herdr-backend.js.map +0 -1
- package/dist/adapters/backend/liveness-gate.d.ts +0 -38
- package/dist/adapters/backend/liveness-gate.d.ts.map +0 -1
- package/dist/adapters/backend/liveness-gate.js +0 -53
- package/dist/adapters/backend/liveness-gate.js.map +0 -1
- package/dist/adapters/backend/pty-backend.d.ts +0 -23
- package/dist/adapters/backend/pty-backend.d.ts.map +0 -1
- package/dist/adapters/backend/pty-backend.js +0 -70
- package/dist/adapters/backend/pty-backend.js.map +0 -1
- package/dist/adapters/backend/reproduce-command.d.ts +0 -39
- package/dist/adapters/backend/reproduce-command.d.ts.map +0 -1
- package/dist/adapters/backend/reproduce-command.js +0 -63
- package/dist/adapters/backend/reproduce-command.js.map +0 -1
- package/dist/adapters/backend/riff-backend.d.ts +0 -272
- package/dist/adapters/backend/riff-backend.d.ts.map +0 -1
- package/dist/adapters/backend/riff-backend.js +0 -1017
- package/dist/adapters/backend/riff-backend.js.map +0 -1
- package/dist/adapters/backend/sandbox.d.ts +0 -298
- package/dist/adapters/backend/sandbox.d.ts.map +0 -1
- package/dist/adapters/backend/sandbox.js +0 -1196
- package/dist/adapters/backend/sandbox.js.map +0 -1
- package/dist/adapters/backend/session-backend-selector.d.ts +0 -113
- package/dist/adapters/backend/session-backend-selector.d.ts.map +0 -1
- package/dist/adapters/backend/session-backend-selector.js +0 -344
- package/dist/adapters/backend/session-backend-selector.js.map +0 -1
- package/dist/adapters/backend/tmux-backend.d.ts +0 -292
- package/dist/adapters/backend/tmux-backend.d.ts.map +0 -1
- package/dist/adapters/backend/tmux-backend.js +0 -821
- package/dist/adapters/backend/tmux-backend.js.map +0 -1
- package/dist/adapters/backend/tmux-pipe-backend.d.ts +0 -237
- package/dist/adapters/backend/tmux-pipe-backend.d.ts.map +0 -1
- package/dist/adapters/backend/tmux-pipe-backend.js +0 -786
- package/dist/adapters/backend/tmux-pipe-backend.js.map +0 -1
- package/dist/adapters/backend/types.d.ts +0 -183
- package/dist/adapters/backend/types.d.ts.map +0 -1
- package/dist/adapters/backend/types.js +0 -19
- package/dist/adapters/backend/types.js.map +0 -1
- package/dist/adapters/backend/zellij-backend.d.ts +0 -173
- package/dist/adapters/backend/zellij-backend.d.ts.map +0 -1
- package/dist/adapters/backend/zellij-backend.js +0 -466
- package/dist/adapters/backend/zellij-backend.js.map +0 -1
- package/dist/adapters/backend/zellij-observe-backend.d.ts +0 -95
- package/dist/adapters/backend/zellij-observe-backend.d.ts.map +0 -1
- package/dist/adapters/backend/zellij-observe-backend.js +0 -301
- package/dist/adapters/backend/zellij-observe-backend.js.map +0 -1
- package/dist/adapters/backend/zellij-socket-probe.d.ts +0 -18
- package/dist/adapters/backend/zellij-socket-probe.d.ts.map +0 -1
- package/dist/adapters/backend/zellij-socket-probe.js +0 -146
- package/dist/adapters/backend/zellij-socket-probe.js.map +0 -1
- package/dist/adapters/backend/zmx-backend.d.ts +0 -284
- package/dist/adapters/backend/zmx-backend.d.ts.map +0 -1
- package/dist/adapters/backend/zmx-backend.js +0 -2387
- package/dist/adapters/backend/zmx-backend.js.map +0 -1
- package/dist/adapters/cli/aiden.d.ts +0 -4
- package/dist/adapters/cli/aiden.d.ts.map +0 -1
- package/dist/adapters/cli/aiden.js +0 -46
- package/dist/adapters/cli/aiden.js.map +0 -1
- package/dist/adapters/cli/antigravity.d.ts +0 -4
- package/dist/adapters/cli/antigravity.d.ts.map +0 -1
- package/dist/adapters/cli/antigravity.js +0 -274
- package/dist/adapters/cli/antigravity.js.map +0 -1
- package/dist/adapters/cli/claude-code.d.ts +0 -121
- package/dist/adapters/cli/claude-code.d.ts.map +0 -1
- package/dist/adapters/cli/claude-code.js +0 -1128
- package/dist/adapters/cli/claude-code.js.map +0 -1
- package/dist/adapters/cli/coco.d.ts +0 -4
- package/dist/adapters/cli/coco.d.ts.map +0 -1
- package/dist/adapters/cli/coco.js +0 -315
- package/dist/adapters/cli/coco.js.map +0 -1
- package/dist/adapters/cli/codex-app-turn.d.ts +0 -59
- package/dist/adapters/cli/codex-app-turn.d.ts.map +0 -1
- package/dist/adapters/cli/codex-app-turn.js +0 -136
- package/dist/adapters/cli/codex-app-turn.js.map +0 -1
- package/dist/adapters/cli/codex-app.d.ts +0 -4
- package/dist/adapters/cli/codex-app.d.ts.map +0 -1
- package/dist/adapters/cli/codex-app.js +0 -88
- package/dist/adapters/cli/codex-app.js.map +0 -1
- package/dist/adapters/cli/codex.d.ts +0 -4
- package/dist/adapters/cli/codex.d.ts.map +0 -1
- package/dist/adapters/cli/codex.js +0 -439
- package/dist/adapters/cli/codex.js.map +0 -1
- package/dist/adapters/cli/copilot.d.ts +0 -10
- package/dist/adapters/cli/copilot.d.ts.map +0 -1
- package/dist/adapters/cli/copilot.js +0 -73
- package/dist/adapters/cli/copilot.js.map +0 -1
- package/dist/adapters/cli/cursor.d.ts +0 -4
- package/dist/adapters/cli/cursor.d.ts.map +0 -1
- package/dist/adapters/cli/cursor.js +0 -104
- package/dist/adapters/cli/cursor.js.map +0 -1
- package/dist/adapters/cli/fs-policy.d.ts +0 -385
- package/dist/adapters/cli/fs-policy.d.ts.map +0 -1
- package/dist/adapters/cli/fs-policy.js +0 -889
- package/dist/adapters/cli/fs-policy.js.map +0 -1
- package/dist/adapters/cli/gemini.d.ts +0 -4
- package/dist/adapters/cli/gemini.d.ts.map +0 -1
- package/dist/adapters/cli/gemini.js +0 -53
- package/dist/adapters/cli/gemini.js.map +0 -1
- package/dist/adapters/cli/genius.d.ts +0 -4
- package/dist/adapters/cli/genius.d.ts.map +0 -1
- package/dist/adapters/cli/genius.js +0 -230
- package/dist/adapters/cli/genius.js.map +0 -1
- package/dist/adapters/cli/grok.d.ts +0 -76
- package/dist/adapters/cli/grok.d.ts.map +0 -1
- package/dist/adapters/cli/grok.js +0 -310
- package/dist/adapters/cli/grok.js.map +0 -1
- package/dist/adapters/cli/hermes.d.ts +0 -4
- package/dist/adapters/cli/hermes.d.ts.map +0 -1
- package/dist/adapters/cli/hermes.js +0 -83
- package/dist/adapters/cli/hermes.js.map +0 -1
- package/dist/adapters/cli/kimi.d.ts +0 -4
- package/dist/adapters/cli/kimi.d.ts.map +0 -1
- package/dist/adapters/cli/kimi.js +0 -54
- package/dist/adapters/cli/kimi.js.map +0 -1
- package/dist/adapters/cli/kiro-cli.d.ts +0 -4
- package/dist/adapters/cli/kiro-cli.d.ts.map +0 -1
- package/dist/adapters/cli/kiro-cli.js +0 -73
- package/dist/adapters/cli/kiro-cli.js.map +0 -1
- package/dist/adapters/cli/mir.d.ts +0 -4
- package/dist/adapters/cli/mir.d.ts.map +0 -1
- package/dist/adapters/cli/mir.js +0 -81
- package/dist/adapters/cli/mir.js.map +0 -1
- package/dist/adapters/cli/mira.d.ts +0 -4
- package/dist/adapters/cli/mira.d.ts.map +0 -1
- package/dist/adapters/cli/mira.js +0 -54
- package/dist/adapters/cli/mira.js.map +0 -1
- package/dist/adapters/cli/mtr.d.ts +0 -5
- package/dist/adapters/cli/mtr.d.ts.map +0 -1
- package/dist/adapters/cli/mtr.js +0 -69
- package/dist/adapters/cli/mtr.js.map +0 -1
- package/dist/adapters/cli/oh-my-pi.d.ts +0 -5
- package/dist/adapters/cli/oh-my-pi.d.ts.map +0 -1
- package/dist/adapters/cli/oh-my-pi.js +0 -186
- package/dist/adapters/cli/oh-my-pi.js.map +0 -1
- package/dist/adapters/cli/opencode.d.ts +0 -4
- package/dist/adapters/cli/opencode.d.ts.map +0 -1
- package/dist/adapters/cli/opencode.js +0 -305
- package/dist/adapters/cli/opencode.js.map +0 -1
- package/dist/adapters/cli/pi-initial-prompt-extension.d.ts +0 -27
- package/dist/adapters/cli/pi-initial-prompt-extension.d.ts.map +0 -1
- package/dist/adapters/cli/pi-initial-prompt-extension.js +0 -38
- package/dist/adapters/cli/pi-initial-prompt-extension.js.map +0 -1
- package/dist/adapters/cli/pi-initial-prompt.d.ts +0 -21
- package/dist/adapters/cli/pi-initial-prompt.d.ts.map +0 -1
- package/dist/adapters/cli/pi-initial-prompt.js +0 -59
- package/dist/adapters/cli/pi-initial-prompt.js.map +0 -1
- package/dist/adapters/cli/pi.d.ts +0 -58
- package/dist/adapters/cli/pi.d.ts.map +0 -1
- package/dist/adapters/cli/pi.js +0 -121
- package/dist/adapters/cli/pi.js.map +0 -1
- package/dist/adapters/cli/read-isolation.d.ts +0 -198
- package/dist/adapters/cli/read-isolation.d.ts.map +0 -1
- package/dist/adapters/cli/read-isolation.js +0 -335
- package/dist/adapters/cli/read-isolation.js.map +0 -1
- package/dist/adapters/cli/reasonix.d.ts +0 -35
- package/dist/adapters/cli/reasonix.d.ts.map +0 -1
- package/dist/adapters/cli/reasonix.js +0 -236
- package/dist/adapters/cli/reasonix.js.map +0 -1
- package/dist/adapters/cli/registry.d.ts +0 -51
- package/dist/adapters/cli/registry.d.ts.map +0 -1
- package/dist/adapters/cli/registry.js +0 -192
- package/dist/adapters/cli/registry.js.map +0 -1
- package/dist/adapters/cli/relay.d.ts +0 -26
- package/dist/adapters/cli/relay.d.ts.map +0 -1
- package/dist/adapters/cli/relay.js +0 -55
- package/dist/adapters/cli/relay.js.map +0 -1
- package/dist/adapters/cli/riff.d.ts +0 -14
- package/dist/adapters/cli/riff.d.ts.map +0 -1
- package/dist/adapters/cli/riff.js +0 -35
- package/dist/adapters/cli/riff.js.map +0 -1
- package/dist/adapters/cli/runner-control-channel.d.ts +0 -32
- package/dist/adapters/cli/runner-control-channel.d.ts.map +0 -1
- package/dist/adapters/cli/runner-control-channel.js +0 -104
- package/dist/adapters/cli/runner-control-channel.js.map +0 -1
- package/dist/adapters/cli/runner-input.d.ts +0 -67
- package/dist/adapters/cli/runner-input.d.ts.map +0 -1
- package/dist/adapters/cli/runner-input.js +0 -131
- package/dist/adapters/cli/runner-input.js.map +0 -1
- package/dist/adapters/cli/runtime.d.ts +0 -81
- package/dist/adapters/cli/runtime.d.ts.map +0 -1
- package/dist/adapters/cli/runtime.js +0 -243
- package/dist/adapters/cli/runtime.js.map +0 -1
- package/dist/adapters/cli/seed.d.ts +0 -29
- package/dist/adapters/cli/seed.d.ts.map +0 -1
- package/dist/adapters/cli/seed.js +0 -68
- package/dist/adapters/cli/seed.js.map +0 -1
- package/dist/adapters/cli/shared-hints.d.ts +0 -45
- package/dist/adapters/cli/shared-hints.d.ts.map +0 -1
- package/dist/adapters/cli/shared-hints.js +0 -144
- package/dist/adapters/cli/shared-hints.js.map +0 -1
- package/dist/adapters/cli/strict-input-handle.d.ts +0 -13
- package/dist/adapters/cli/strict-input-handle.d.ts.map +0 -1
- package/dist/adapters/cli/strict-input-handle.js +0 -39
- package/dist/adapters/cli/strict-input-handle.js.map +0 -1
- package/dist/adapters/cli/traex.d.ts +0 -28
- package/dist/adapters/cli/traex.d.ts.map +0 -1
- package/dist/adapters/cli/traex.js +0 -343
- package/dist/adapters/cli/traex.js.map +0 -1
- package/dist/adapters/cli/types.d.ts +0 -460
- package/dist/adapters/cli/types.d.ts.map +0 -1
- package/dist/adapters/cli/types.js +0 -2
- package/dist/adapters/cli/types.js.map +0 -1
- package/dist/adapters/coco-ask-plugin.d.ts +0 -25
- package/dist/adapters/coco-ask-plugin.d.ts.map +0 -1
- package/dist/adapters/coco-ask-plugin.js +0 -73
- package/dist/adapters/coco-ask-plugin.js.map +0 -1
- package/dist/adapters/hook-command.d.ts +0 -27
- package/dist/adapters/hook-command.d.ts.map +0 -1
- package/dist/adapters/hook-command.js +0 -50
- package/dist/adapters/hook-command.js.map +0 -1
- package/dist/adapters/hook-installer.d.ts +0 -37
- package/dist/adapters/hook-installer.d.ts.map +0 -1
- package/dist/adapters/hook-installer.js +0 -494
- package/dist/adapters/hook-installer.js.map +0 -1
- package/dist/autostart.d.ts +0 -14
- package/dist/autostart.d.ts.map +0 -1
- package/dist/autostart.js +0 -516
- package/dist/autostart.js.map +0 -1
- package/dist/bot-registry.d.ts +0 -942
- package/dist/bot-registry.d.ts.map +0 -1
- package/dist/bot-registry.js +0 -1909
- package/dist/bot-registry.js.map +0 -1
- package/dist/cli/arg-utils.d.ts +0 -11
- package/dist/cli/arg-utils.d.ts.map +0 -1
- package/dist/cli/arg-utils.js +0 -25
- package/dist/cli/arg-utils.js.map +0 -1
- package/dist/cli/bots-list-output.d.ts +0 -29
- package/dist/cli/bots-list-output.d.ts.map +0 -1
- package/dist/cli/bots-list-output.js +0 -32
- package/dist/cli/bots-list-output.js.map +0 -1
- package/dist/cli/capabilities.d.ts +0 -24
- package/dist/cli/capabilities.d.ts.map +0 -1
- package/dist/cli/capabilities.js +0 -25
- package/dist/cli/capabilities.js.map +0 -1
- package/dist/cli/create-group-resolver.d.ts +0 -75
- package/dist/cli/create-group-resolver.d.ts.map +0 -1
- package/dist/cli/create-group-resolver.js +0 -123
- package/dist/cli/create-group-resolver.js.map +0 -1
- package/dist/cli/daemon-lifecycle-env.d.ts +0 -9
- package/dist/cli/daemon-lifecycle-env.d.ts.map +0 -1
- package/dist/cli/daemon-lifecycle-env.js +0 -43
- package/dist/cli/daemon-lifecycle-env.js.map +0 -1
- package/dist/cli/dashboard-endpoint.d.ts +0 -76
- package/dist/cli/dashboard-endpoint.d.ts.map +0 -1
- package/dist/cli/dashboard-endpoint.js +0 -161
- package/dist/cli/dashboard-endpoint.js.map +0 -1
- package/dist/cli/deferred-topic-send.d.ts +0 -48
- package/dist/cli/deferred-topic-send.d.ts.map +0 -1
- package/dist/cli/deferred-topic-send.js +0 -86
- package/dist/cli/deferred-topic-send.js.map +0 -1
- package/dist/cli/exact-chat-grant-client.d.ts +0 -48
- package/dist/cli/exact-chat-grant-client.d.ts.map +0 -1
- package/dist/cli/exact-chat-grant-client.js +0 -108
- package/dist/cli/exact-chat-grant-client.js.map +0 -1
- package/dist/cli/exact-chat-grant.d.ts +0 -18
- package/dist/cli/exact-chat-grant.d.ts.map +0 -1
- package/dist/cli/exact-chat-grant.js +0 -97
- package/dist/cli/exact-chat-grant.js.map +0 -1
- package/dist/cli/pm2-command.d.ts +0 -7
- package/dist/cli/pm2-command.d.ts.map +0 -1
- package/dist/cli/pm2-command.js +0 -25
- package/dist/cli/pm2-command.js.map +0 -1
- package/dist/cli/quoted-render.d.ts +0 -41
- package/dist/cli/quoted-render.d.ts.map +0 -1
- package/dist/cli/quoted-render.js +0 -44
- package/dist/cli/quoted-render.js.map +0 -1
- package/dist/cli/saved-workflow.d.ts +0 -25
- package/dist/cli/saved-workflow.d.ts.map +0 -1
- package/dist/cli/saved-workflow.js +0 -338
- package/dist/cli/saved-workflow.js.map +0 -1
- package/dist/cli/send-dispatch.d.ts +0 -125
- package/dist/cli/send-dispatch.d.ts.map +0 -1
- package/dist/cli/send-dispatch.js +0 -320
- package/dist/cli/send-dispatch.js.map +0 -1
- package/dist/cli/session-list-liveness.d.ts +0 -41
- package/dist/cli/session-list-liveness.d.ts.map +0 -1
- package/dist/cli/session-list-liveness.js +0 -48
- package/dist/cli/session-list-liveness.js.map +0 -1
- package/dist/cli/stdin-encoding.d.ts +0 -24
- package/dist/cli/stdin-encoding.d.ts.map +0 -1
- package/dist/cli/stdin-encoding.js +0 -56
- package/dist/cli/stdin-encoding.js.map +0 -1
- package/dist/cli/v3-run-cancel.d.ts +0 -47
- package/dist/cli/v3-run-cancel.d.ts.map +0 -1
- package/dist/cli/v3-run-cancel.js +0 -96
- package/dist/cli/v3-run-cancel.js.map +0 -1
- package/dist/cli/vc-agent.d.ts +0 -2
- package/dist/cli/vc-agent.d.ts.map +0 -1
- package/dist/cli/vc-agent.js +0 -384
- package/dist/cli/vc-agent.js.map +0 -1
- package/dist/cli/workflow-migration.d.ts +0 -39
- package/dist/cli/workflow-migration.d.ts.map +0 -1
- package/dist/cli/workflow-migration.js +0 -302
- package/dist/cli/workflow-migration.js.map +0 -1
- package/dist/cli/workflow-run-archive.d.ts +0 -29
- package/dist/cli/workflow-run-archive.d.ts.map +0 -1
- package/dist/cli/workflow-run-archive.js +0 -183
- package/dist/cli/workflow-run-archive.js.map +0 -1
- package/dist/cli/workflow.d.ts +0 -8
- package/dist/cli/workflow.d.ts.map +0 -1
- package/dist/cli/workflow.js +0 -109
- package/dist/cli/workflow.js.map +0 -1
- package/dist/cli/zmx-managed-attach.d.ts +0 -41
- package/dist/cli/zmx-managed-attach.d.ts.map +0 -1
- package/dist/cli/zmx-managed-attach.js +0 -72
- package/dist/cli/zmx-managed-attach.js.map +0 -1
- package/dist/cli.d.ts +0 -35
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js +0 -10769
- package/dist/cli.js.map +0 -1
- package/dist/codex-app-runner.d.ts +0 -3
- package/dist/codex-app-runner.d.ts.map +0 -1
- package/dist/codex-app-runner.js +0 -565
- package/dist/codex-app-runner.js.map +0 -1
- package/dist/codex-rpc-engine.d.ts +0 -136
- package/dist/codex-rpc-engine.d.ts.map +0 -1
- package/dist/codex-rpc-engine.js +0 -640
- package/dist/codex-rpc-engine.js.map +0 -1
- package/dist/codex-rpc-lifecycle.d.ts +0 -157
- package/dist/codex-rpc-lifecycle.d.ts.map +0 -1
- package/dist/codex-rpc-lifecycle.js +0 -238
- package/dist/codex-rpc-lifecycle.js.map +0 -1
- package/dist/config.d.ts +0 -146
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js +0 -293
- package/dist/config.js.map +0 -1
- package/dist/core/ask-api.d.ts +0 -29
- package/dist/core/ask-api.d.ts.map +0 -1
- package/dist/core/ask-api.js +0 -116
- package/dist/core/ask-api.js.map +0 -1
- package/dist/core/ask-args.d.ts +0 -53
- package/dist/core/ask-args.d.ts.map +0 -1
- package/dist/core/ask-args.js +0 -122
- package/dist/core/ask-args.js.map +0 -1
- package/dist/core/ask-broker.d.ts +0 -166
- package/dist/core/ask-broker.d.ts.map +0 -1
- package/dist/core/ask-broker.js +0 -451
- package/dist/core/ask-broker.js.map +0 -1
- package/dist/core/ask-hook/claude-code.d.ts +0 -50
- package/dist/core/ask-hook/claude-code.d.ts.map +0 -1
- package/dist/core/ask-hook/claude-code.js +0 -151
- package/dist/core/ask-hook/claude-code.js.map +0 -1
- package/dist/core/ask-hook/coco.d.ts +0 -22
- package/dist/core/ask-hook/coco.d.ts.map +0 -1
- package/dist/core/ask-hook/coco.js +0 -35
- package/dist/core/ask-hook/coco.js.map +0 -1
- package/dist/core/ask-hook/codex.d.ts +0 -43
- package/dist/core/ask-hook/codex.d.ts.map +0 -1
- package/dist/core/ask-hook/codex.js +0 -70
- package/dist/core/ask-hook/codex.js.map +0 -1
- package/dist/core/ask-hook/opencode.d.ts +0 -39
- package/dist/core/ask-hook/opencode.d.ts.map +0 -1
- package/dist/core/ask-hook/opencode.js +0 -109
- package/dist/core/ask-hook/opencode.js.map +0 -1
- package/dist/core/ask-hook/registry.d.ts +0 -3
- package/dist/core/ask-hook/registry.d.ts.map +0 -1
- package/dist/core/ask-hook/registry.js +0 -25
- package/dist/core/ask-hook/registry.js.map +0 -1
- package/dist/core/ask-hook/types.d.ts +0 -28
- package/dist/core/ask-hook/types.d.ts.map +0 -1
- package/dist/core/ask-hook/types.js +0 -2
- package/dist/core/ask-hook/types.js.map +0 -1
- package/dist/core/ask-types.d.ts +0 -157
- package/dist/core/ask-types.d.ts.map +0 -1
- package/dist/core/ask-types.js +0 -28
- package/dist/core/ask-types.js.map +0 -1
- package/dist/core/attachment-path.d.ts +0 -3
- package/dist/core/attachment-path.d.ts.map +0 -1
- package/dist/core/attachment-path.js +0 -8
- package/dist/core/attachment-path.js.map +0 -1
- package/dist/core/auto-start.d.ts +0 -84
- package/dist/core/auto-start.d.ts.map +0 -1
- package/dist/core/auto-start.js +0 -92
- package/dist/core/auto-start.js.map +0 -1
- package/dist/core/bot-live-control.d.ts +0 -41
- package/dist/core/bot-live-control.d.ts.map +0 -1
- package/dist/core/bot-live-control.js +0 -135
- package/dist/core/bot-live-control.js.map +0 -1
- package/dist/core/bot-turn-mutation-gate.d.ts +0 -24
- package/dist/core/bot-turn-mutation-gate.d.ts.map +0 -1
- package/dist/core/bot-turn-mutation-gate.js +0 -369
- package/dist/core/bot-turn-mutation-gate.js.map +0 -1
- package/dist/core/botmux-wrapper.d.ts +0 -41
- package/dist/core/botmux-wrapper.d.ts.map +0 -1
- package/dist/core/botmux-wrapper.js +0 -63
- package/dist/core/botmux-wrapper.js.map +0 -1
- package/dist/core/chat-rename.d.ts +0 -27
- package/dist/core/chat-rename.d.ts.map +0 -1
- package/dist/core/chat-rename.js +0 -53
- package/dist/core/chat-rename.js.map +0 -1
- package/dist/core/cli-runtime-display.d.ts +0 -19
- package/dist/core/cli-runtime-display.d.ts.map +0 -1
- package/dist/core/cli-runtime-display.js +0 -28
- package/dist/core/cli-runtime-display.js.map +0 -1
- package/dist/core/cli-runtime-update.d.ts +0 -129
- package/dist/core/cli-runtime-update.d.ts.map +0 -1
- package/dist/core/cli-runtime-update.js +0 -737
- package/dist/core/cli-runtime-update.js.map +0 -1
- package/dist/core/closed-session-card.d.ts +0 -16
- package/dist/core/closed-session-card.d.ts.map +0 -1
- package/dist/core/closed-session-card.js +0 -80
- package/dist/core/closed-session-card.js.map +0 -1
- package/dist/core/coco-picker-keys.d.ts +0 -31
- package/dist/core/coco-picker-keys.d.ts.map +0 -1
- package/dist/core/coco-picker-keys.js +0 -60
- package/dist/core/coco-picker-keys.js.map +0 -1
- package/dist/core/command-discovery.d.ts +0 -33
- package/dist/core/command-discovery.d.ts.map +0 -1
- package/dist/core/command-discovery.js +0 -261
- package/dist/core/command-discovery.js.map +0 -1
- package/dist/core/command-handler.d.ts +0 -163
- package/dist/core/command-handler.d.ts.map +0 -1
- package/dist/core/command-handler.js +0 -4108
- package/dist/core/command-handler.js.map +0 -1
- package/dist/core/cost-calculator.d.ts +0 -69
- package/dist/core/cost-calculator.d.ts.map +0 -1
- package/dist/core/cost-calculator.js +0 -603
- package/dist/core/cost-calculator.js.map +0 -1
- package/dist/core/current-turn-provenance.d.ts +0 -39
- package/dist/core/current-turn-provenance.d.ts.map +0 -1
- package/dist/core/current-turn-provenance.js +0 -122
- package/dist/core/current-turn-provenance.js.map +0 -1
- package/dist/core/daemon-config-fence.d.ts +0 -8
- package/dist/core/daemon-config-fence.d.ts.map +0 -1
- package/dist/core/daemon-config-fence.js +0 -13
- package/dist/core/daemon-config-fence.js.map +0 -1
- package/dist/core/daemon-heartbeat.d.ts +0 -15
- package/dist/core/daemon-heartbeat.d.ts.map +0 -1
- package/dist/core/daemon-heartbeat.js +0 -83
- package/dist/core/daemon-heartbeat.js.map +0 -1
- package/dist/core/daemon-ipc-auth.d.ts +0 -20
- package/dist/core/daemon-ipc-auth.d.ts.map +0 -1
- package/dist/core/daemon-ipc-auth.js +0 -44
- package/dist/core/daemon-ipc-auth.js.map +0 -1
- package/dist/core/daemon-ipc-session-auth.d.ts +0 -37
- package/dist/core/daemon-ipc-session-auth.d.ts.map +0 -1
- package/dist/core/daemon-ipc-session-auth.js +0 -35
- package/dist/core/daemon-ipc-session-auth.js.map +0 -1
- package/dist/core/dashboard-command/groups.d.ts +0 -20
- package/dist/core/dashboard-command/groups.d.ts.map +0 -1
- package/dist/core/dashboard-command/groups.js +0 -52
- package/dist/core/dashboard-command/groups.js.map +0 -1
- package/dist/core/dashboard-command/index.d.ts +0 -28
- package/dist/core/dashboard-command/index.d.ts.map +0 -1
- package/dist/core/dashboard-command/index.js +0 -81
- package/dist/core/dashboard-command/index.js.map +0 -1
- package/dist/core/dashboard-command/overview.d.ts +0 -29
- package/dist/core/dashboard-command/overview.d.ts.map +0 -1
- package/dist/core/dashboard-command/overview.js +0 -61
- package/dist/core/dashboard-command/overview.js.map +0 -1
- package/dist/core/dashboard-command/owner-gate.d.ts +0 -41
- package/dist/core/dashboard-command/owner-gate.d.ts.map +0 -1
- package/dist/core/dashboard-command/owner-gate.js +0 -40
- package/dist/core/dashboard-command/owner-gate.js.map +0 -1
- package/dist/core/dashboard-command/schedules.d.ts +0 -20
- package/dist/core/dashboard-command/schedules.d.ts.map +0 -1
- package/dist/core/dashboard-command/schedules.js +0 -47
- package/dist/core/dashboard-command/schedules.js.map +0 -1
- package/dist/core/dashboard-command/sessions.d.ts +0 -22
- package/dist/core/dashboard-command/sessions.d.ts.map +0 -1
- package/dist/core/dashboard-command/sessions.js +0 -43
- package/dist/core/dashboard-command/sessions.js.map +0 -1
- package/dist/core/dashboard-command/settings.d.ts +0 -21
- package/dist/core/dashboard-command/settings.d.ts.map +0 -1
- package/dist/core/dashboard-command/settings.js +0 -55
- package/dist/core/dashboard-command/settings.js.map +0 -1
- package/dist/core/dashboard-command/stub.d.ts +0 -16
- package/dist/core/dashboard-command/stub.d.ts.map +0 -1
- package/dist/core/dashboard-command/stub.js +0 -27
- package/dist/core/dashboard-command/stub.js.map +0 -1
- package/dist/core/dashboard-events.d.ts +0 -67
- package/dist/core/dashboard-events.d.ts.map +0 -1
- package/dist/core/dashboard-events.js +0 -23
- package/dist/core/dashboard-events.js.map +0 -1
- package/dist/core/dashboard-images.d.ts +0 -29
- package/dist/core/dashboard-images.d.ts.map +0 -1
- package/dist/core/dashboard-images.js +0 -113
- package/dist/core/dashboard-images.js.map +0 -1
- package/dist/core/dashboard-ipc-server.d.ts +0 -114
- package/dist/core/dashboard-ipc-server.d.ts.map +0 -1
- package/dist/core/dashboard-ipc-server.js +0 -4398
- package/dist/core/dashboard-ipc-server.js.map +0 -1
- package/dist/core/dashboard-locate.d.ts +0 -20
- package/dist/core/dashboard-locate.d.ts.map +0 -1
- package/dist/core/dashboard-locate.js +0 -26
- package/dist/core/dashboard-locate.js.map +0 -1
- package/dist/core/dashboard-rows.d.ts +0 -117
- package/dist/core/dashboard-rows.d.ts.map +0 -1
- package/dist/core/dashboard-rows.js +0 -206
- package/dist/core/dashboard-rows.js.map +0 -1
- package/dist/core/dashboard-secret.d.ts +0 -3
- package/dist/core/dashboard-secret.d.ts.map +0 -1
- package/dist/core/dashboard-secret.js +0 -7
- package/dist/core/dashboard-secret.js.map +0 -1
- package/dist/core/dashboard-url.d.ts +0 -79
- package/dist/core/dashboard-url.d.ts.map +0 -1
- package/dist/core/dashboard-url.js +0 -107
- package/dist/core/dashboard-url.js.map +0 -1
- package/dist/core/data-dir.d.ts +0 -24
- package/dist/core/data-dir.d.ts.map +0 -1
- package/dist/core/data-dir.js +0 -48
- package/dist/core/data-dir.js.map +0 -1
- package/dist/core/deferred-schedule-settlement.d.ts +0 -20
- package/dist/core/deferred-schedule-settlement.d.ts.map +0 -1
- package/dist/core/deferred-schedule-settlement.js +0 -18
- package/dist/core/deferred-schedule-settlement.js.map +0 -1
- package/dist/core/deferred-topic-binding.d.ts +0 -19
- package/dist/core/deferred-topic-binding.d.ts.map +0 -1
- package/dist/core/deferred-topic-binding.js +0 -55
- package/dist/core/deferred-topic-binding.js.map +0 -1
- package/dist/core/device-isolation-activation.d.ts +0 -56
- package/dist/core/device-isolation-activation.d.ts.map +0 -1
- package/dist/core/device-isolation-activation.js +0 -110
- package/dist/core/device-isolation-activation.js.map +0 -1
- package/dist/core/device-isolation-daemon.d.ts +0 -106
- package/dist/core/device-isolation-daemon.d.ts.map +0 -1
- package/dist/core/device-isolation-daemon.js +0 -674
- package/dist/core/device-isolation-daemon.js.map +0 -1
- package/dist/core/dispatch-registry.d.ts +0 -12
- package/dist/core/dispatch-registry.d.ts.map +0 -1
- package/dist/core/dispatch-registry.js +0 -33
- package/dist/core/dispatch-registry.js.map +0 -1
- package/dist/core/dispatch.d.ts +0 -364
- package/dist/core/dispatch.d.ts.map +0 -1
- package/dist/core/dispatch.js +0 -527
- package/dist/core/dispatch.js.map +0 -1
- package/dist/core/doc-comment-poller.d.ts +0 -36
- package/dist/core/doc-comment-poller.d.ts.map +0 -1
- package/dist/core/doc-comment-poller.js +0 -60
- package/dist/core/doc-comment-poller.js.map +0 -1
- package/dist/core/doc-comment-prompt.d.ts +0 -90
- package/dist/core/doc-comment-prompt.d.ts.map +0 -1
- package/dist/core/doc-comment-prompt.js +0 -252
- package/dist/core/doc-comment-prompt.js.map +0 -1
- package/dist/core/doc-watch-command.d.ts +0 -22
- package/dist/core/doc-watch-command.d.ts.map +0 -1
- package/dist/core/doc-watch-command.js +0 -41
- package/dist/core/doc-watch-command.js.map +0 -1
- package/dist/core/github-auth.d.ts +0 -13
- package/dist/core/github-auth.d.ts.map +0 -1
- package/dist/core/github-auth.js +0 -82
- package/dist/core/github-auth.js.map +0 -1
- package/dist/core/host-overload-alert.d.ts +0 -232
- package/dist/core/host-overload-alert.d.ts.map +0 -1
- package/dist/core/host-overload-alert.js +0 -354
- package/dist/core/host-overload-alert.js.map +0 -1
- package/dist/core/idle-worker-sweeper.d.ts +0 -39
- package/dist/core/idle-worker-sweeper.d.ts.map +0 -1
- package/dist/core/idle-worker-sweeper.js +0 -63
- package/dist/core/idle-worker-sweeper.js.map +0 -1
- package/dist/core/inflight-input-tracker.d.ts +0 -54
- package/dist/core/inflight-input-tracker.d.ts.map +0 -1
- package/dist/core/inflight-input-tracker.js +0 -64
- package/dist/core/inflight-input-tracker.js.map +0 -1
- package/dist/core/inherit-peer.d.ts +0 -19
- package/dist/core/inherit-peer.d.ts.map +0 -1
- package/dist/core/inherit-peer.js +0 -55
- package/dist/core/inherit-peer.js.map +0 -1
- package/dist/core/initial-user-turn.d.ts +0 -14
- package/dist/core/initial-user-turn.d.ts.map +0 -1
- package/dist/core/initial-user-turn.js +0 -65
- package/dist/core/initial-user-turn.js.map +0 -1
- package/dist/core/inject-queue-policy.d.ts +0 -70
- package/dist/core/inject-queue-policy.d.ts.map +0 -1
- package/dist/core/inject-queue-policy.js +0 -30
- package/dist/core/inject-queue-policy.js.map +0 -1
- package/dist/core/input-turn-dedupe.d.ts +0 -20
- package/dist/core/input-turn-dedupe.d.ts.map +0 -1
- package/dist/core/input-turn-dedupe.js +0 -57
- package/dist/core/input-turn-dedupe.js.map +0 -1
- package/dist/core/local-terminal-opener.d.ts +0 -43
- package/dist/core/local-terminal-opener.d.ts.map +0 -1
- package/dist/core/local-terminal-opener.js +0 -230
- package/dist/core/local-terminal-opener.js.map +0 -1
- package/dist/core/maintenance-schedule.d.ts +0 -34
- package/dist/core/maintenance-schedule.d.ts.map +0 -1
- package/dist/core/maintenance-schedule.js +0 -72
- package/dist/core/maintenance-schedule.js.map +0 -1
- package/dist/core/maintenance.d.ts +0 -114
- package/dist/core/maintenance.d.ts.map +0 -1
- package/dist/core/maintenance.js +0 -340
- package/dist/core/maintenance.js.map +0 -1
- package/dist/core/managed-origin-capability.d.ts +0 -37
- package/dist/core/managed-origin-capability.d.ts.map +0 -1
- package/dist/core/managed-origin-capability.js +0 -100
- package/dist/core/managed-origin-capability.js.map +0 -1
- package/dist/core/passthrough-commands.d.ts +0 -56
- package/dist/core/passthrough-commands.d.ts.map +0 -1
- package/dist/core/passthrough-commands.js +0 -120
- package/dist/core/passthrough-commands.js.map +0 -1
- package/dist/core/pending-response.d.ts +0 -4
- package/dist/core/pending-response.d.ts.map +0 -1
- package/dist/core/pending-response.js +0 -11
- package/dist/core/pending-response.js.map +0 -1
- package/dist/core/per-bot-env.d.ts +0 -38
- package/dist/core/per-bot-env.d.ts.map +0 -1
- package/dist/core/per-bot-env.js +0 -94
- package/dist/core/per-bot-env.js.map +0 -1
- package/dist/core/persistent-backend.d.ts +0 -107
- package/dist/core/persistent-backend.d.ts.map +0 -1
- package/dist/core/persistent-backend.js +0 -235
- package/dist/core/persistent-backend.js.map +0 -1
- package/dist/core/plugins/cli-generation.d.ts +0 -30
- package/dist/core/plugins/cli-generation.d.ts.map +0 -1
- package/dist/core/plugins/cli-generation.js +0 -62
- package/dist/core/plugins/cli-generation.js.map +0 -1
- package/dist/core/plugins/convention-scanner.d.ts +0 -4
- package/dist/core/plugins/convention-scanner.d.ts.map +0 -1
- package/dist/core/plugins/convention-scanner.js +0 -202
- package/dist/core/plugins/convention-scanner.js.map +0 -1
- package/dist/core/plugins/dependencies.d.ts +0 -5
- package/dist/core/plugins/dependencies.d.ts.map +0 -1
- package/dist/core/plugins/dependencies.js +0 -50
- package/dist/core/plugins/dependencies.js.map +0 -1
- package/dist/core/plugins/effective.d.ts +0 -5
- package/dist/core/plugins/effective.d.ts.map +0 -1
- package/dist/core/plugins/effective.js +0 -16
- package/dist/core/plugins/effective.js.map +0 -1
- package/dist/core/plugins/ids.d.ts +0 -4
- package/dist/core/plugins/ids.d.ts.map +0 -1
- package/dist/core/plugins/ids.js +0 -30
- package/dist/core/plugins/ids.js.map +0 -1
- package/dist/core/plugins/init.d.ts +0 -23
- package/dist/core/plugins/init.d.ts.map +0 -1
- package/dist/core/plugins/init.js +0 -332
- package/dist/core/plugins/init.js.map +0 -1
- package/dist/core/plugins/install.d.ts +0 -14
- package/dist/core/plugins/install.d.ts.map +0 -1
- package/dist/core/plugins/install.js +0 -234
- package/dist/core/plugins/install.js.map +0 -1
- package/dist/core/plugins/manifest.d.ts +0 -4
- package/dist/core/plugins/manifest.d.ts.map +0 -1
- package/dist/core/plugins/manifest.js +0 -78
- package/dist/core/plugins/manifest.js.map +0 -1
- package/dist/core/plugins/materializer.d.ts +0 -16
- package/dist/core/plugins/materializer.d.ts.map +0 -1
- package/dist/core/plugins/materializer.js +0 -73
- package/dist/core/plugins/materializer.js.map +0 -1
- package/dist/core/plugins/mcp/environment.d.ts +0 -12
- package/dist/core/plugins/mcp/environment.d.ts.map +0 -1
- package/dist/core/plugins/mcp/environment.js +0 -17
- package/dist/core/plugins/mcp/environment.js.map +0 -1
- package/dist/core/plugins/mcp/gateway-installer.d.ts +0 -16
- package/dist/core/plugins/mcp/gateway-installer.d.ts.map +0 -1
- package/dist/core/plugins/mcp/gateway-installer.js +0 -273
- package/dist/core/plugins/mcp/gateway-installer.js.map +0 -1
- package/dist/core/plugins/mcp/gateway.d.ts +0 -63
- package/dist/core/plugins/mcp/gateway.d.ts.map +0 -1
- package/dist/core/plugins/mcp/gateway.js +0 -620
- package/dist/core/plugins/mcp/gateway.js.map +0 -1
- package/dist/core/plugins/mcp/host.d.ts +0 -18
- package/dist/core/plugins/mcp/host.d.ts.map +0 -1
- package/dist/core/plugins/mcp/host.js +0 -126
- package/dist/core/plugins/mcp/host.js.map +0 -1
- package/dist/core/plugins/mcp/private-store.d.ts +0 -15
- package/dist/core/plugins/mcp/private-store.d.ts.map +0 -1
- package/dist/core/plugins/mcp/private-store.js +0 -162
- package/dist/core/plugins/mcp/private-store.js.map +0 -1
- package/dist/core/plugins/mcp/session-runtime.d.ts +0 -25
- package/dist/core/plugins/mcp/session-runtime.d.ts.map +0 -1
- package/dist/core/plugins/mcp/session-runtime.js +0 -76
- package/dist/core/plugins/mcp/session-runtime.js.map +0 -1
- package/dist/core/plugins/mcp/socket-auth.d.ts +0 -9
- package/dist/core/plugins/mcp/socket-auth.d.ts.map +0 -1
- package/dist/core/plugins/mcp/socket-auth.js +0 -94
- package/dist/core/plugins/mcp/socket-auth.js.map +0 -1
- package/dist/core/plugins/paths.d.ts +0 -17
- package/dist/core/plugins/paths.d.ts.map +0 -1
- package/dist/core/plugins/paths.js +0 -71
- package/dist/core/plugins/paths.js.map +0 -1
- package/dist/core/plugins/pm2.d.ts +0 -13
- package/dist/core/plugins/pm2.d.ts.map +0 -1
- package/dist/core/plugins/pm2.js +0 -73
- package/dist/core/plugins/pm2.js.map +0 -1
- package/dist/core/plugins/runtime.d.ts +0 -54
- package/dist/core/plugins/runtime.d.ts.map +0 -1
- package/dist/core/plugins/runtime.js +0 -158
- package/dist/core/plugins/runtime.js.map +0 -1
- package/dist/core/plugins/service-manager.d.ts +0 -46
- package/dist/core/plugins/service-manager.d.ts.map +0 -1
- package/dist/core/plugins/service-manager.js +0 -403
- package/dist/core/plugins/service-manager.js.map +0 -1
- package/dist/core/plugins/session-manifest.d.ts +0 -25
- package/dist/core/plugins/session-manifest.d.ts.map +0 -1
- package/dist/core/plugins/session-manifest.js +0 -58
- package/dist/core/plugins/session-manifest.js.map +0 -1
- package/dist/core/plugins/skills.d.ts +0 -7
- package/dist/core/plugins/skills.d.ts.map +0 -1
- package/dist/core/plugins/skills.js +0 -36
- package/dist/core/plugins/skills.js.map +0 -1
- package/dist/core/plugins/types.d.ts +0 -139
- package/dist/core/plugins/types.d.ts.map +0 -1
- package/dist/core/plugins/types.js +0 -2
- package/dist/core/plugins/types.js.map +0 -1
- package/dist/core/reply-target.d.ts +0 -62
- package/dist/core/reply-target.d.ts.map +0 -1
- package/dist/core/reply-target.js +0 -122
- package/dist/core/reply-target.js.map +0 -1
- package/dist/core/resource-monitor/attribution.d.ts +0 -70
- package/dist/core/resource-monitor/attribution.d.ts.map +0 -1
- package/dist/core/resource-monitor/attribution.js +0 -238
- package/dist/core/resource-monitor/attribution.js.map +0 -1
- package/dist/core/resource-monitor/darwin.d.ts +0 -145
- package/dist/core/resource-monitor/darwin.d.ts.map +0 -1
- package/dist/core/resource-monitor/darwin.js +0 -360
- package/dist/core/resource-monitor/darwin.js.map +0 -1
- package/dist/core/resource-monitor/procfs.d.ts +0 -22
- package/dist/core/resource-monitor/procfs.d.ts.map +0 -1
- package/dist/core/resource-monitor/procfs.js +0 -140
- package/dist/core/resource-monitor/procfs.js.map +0 -1
- package/dist/core/resource-monitor/ring-buffer.d.ts +0 -15
- package/dist/core/resource-monitor/ring-buffer.d.ts.map +0 -1
- package/dist/core/resource-monitor/ring-buffer.js +0 -61
- package/dist/core/resource-monitor/ring-buffer.js.map +0 -1
- package/dist/core/resource-monitor/runtime.d.ts +0 -31
- package/dist/core/resource-monitor/runtime.d.ts.map +0 -1
- package/dist/core/resource-monitor/runtime.js +0 -92
- package/dist/core/resource-monitor/runtime.js.map +0 -1
- package/dist/core/resource-monitor/top-selector.d.ts +0 -18
- package/dist/core/resource-monitor/top-selector.d.ts.map +0 -1
- package/dist/core/resource-monitor/top-selector.js +0 -57
- package/dist/core/resource-monitor/top-selector.js.map +0 -1
- package/dist/core/resource-monitor/types.d.ts +0 -181
- package/dist/core/resource-monitor/types.d.ts.map +0 -1
- package/dist/core/resource-monitor/types.js +0 -2
- package/dist/core/resource-monitor/types.js.map +0 -1
- package/dist/core/restart-coordinator.d.ts +0 -28
- package/dist/core/restart-coordinator.d.ts.map +0 -1
- package/dist/core/restart-coordinator.js +0 -82
- package/dist/core/restart-coordinator.js.map +0 -1
- package/dist/core/restart-followup-policy.d.ts +0 -112
- package/dist/core/restart-followup-policy.d.ts.map +0 -1
- package/dist/core/restart-followup-policy.js +0 -49
- package/dist/core/restart-followup-policy.js.map +0 -1
- package/dist/core/restart-report.d.ts +0 -63
- package/dist/core/restart-report.d.ts.map +0 -1
- package/dist/core/restart-report.js +0 -122
- package/dist/core/restart-report.js.map +0 -1
- package/dist/core/role-library.d.ts +0 -62
- package/dist/core/role-library.d.ts.map +0 -1
- package/dist/core/role-library.js +0 -183
- package/dist/core/role-library.js.map +0 -1
- package/dist/core/role-resolver.d.ts +0 -81
- package/dist/core/role-resolver.d.ts.map +0 -1
- package/dist/core/role-resolver.js +0 -306
- package/dist/core/role-resolver.js.map +0 -1
- package/dist/core/scheduler.d.ts +0 -173
- package/dist/core/scheduler.d.ts.map +0 -1
- package/dist/core/scheduler.js +0 -799
- package/dist/core/scheduler.js.map +0 -1
- package/dist/core/session-activity.d.ts +0 -43
- package/dist/core/session-activity.d.ts.map +0 -1
- package/dist/core/session-activity.js +0 -131
- package/dist/core/session-activity.js.map +0 -1
- package/dist/core/session-board.d.ts +0 -13
- package/dist/core/session-board.d.ts.map +0 -1
- package/dist/core/session-board.js +0 -28
- package/dist/core/session-board.js.map +0 -1
- package/dist/core/session-create.d.ts +0 -109
- package/dist/core/session-create.d.ts.map +0 -1
- package/dist/core/session-create.js +0 -183
- package/dist/core/session-create.js.map +0 -1
- package/dist/core/session-cwd.d.ts +0 -14
- package/dist/core/session-cwd.d.ts.map +0 -1
- package/dist/core/session-cwd.js +0 -25
- package/dist/core/session-cwd.js.map +0 -1
- package/dist/core/session-discovery.d.ts +0 -241
- package/dist/core/session-discovery.d.ts.map +0 -1
- package/dist/core/session-discovery.js +0 -1127
- package/dist/core/session-discovery.js.map +0 -1
- package/dist/core/session-liveness.d.ts +0 -41
- package/dist/core/session-liveness.d.ts.map +0 -1
- package/dist/core/session-liveness.js +0 -50
- package/dist/core/session-liveness.js.map +0 -1
- package/dist/core/session-manager.d.ts +0 -383
- package/dist/core/session-manager.d.ts.map +0 -1
- package/dist/core/session-manager.js +0 -2545
- package/dist/core/session-manager.js.map +0 -1
- package/dist/core/session-marker.d.ts +0 -56
- package/dist/core/session-marker.d.ts.map +0 -1
- package/dist/core/session-marker.js +0 -240
- package/dist/core/session-marker.js.map +0 -1
- package/dist/core/session-message-preview.d.ts +0 -20
- package/dist/core/session-message-preview.d.ts.map +0 -1
- package/dist/core/session-message-preview.js +0 -188
- package/dist/core/session-message-preview.js.map +0 -1
- package/dist/core/session-ready-handshake.d.ts +0 -11
- package/dist/core/session-ready-handshake.d.ts.map +0 -1
- package/dist/core/session-ready-handshake.js +0 -41
- package/dist/core/session-ready-handshake.js.map +0 -1
- package/dist/core/session-rename.d.ts +0 -25
- package/dist/core/session-rename.d.ts.map +0 -1
- package/dist/core/session-rename.js +0 -43
- package/dist/core/session-rename.js.map +0 -1
- package/dist/core/session-row-enrichment.d.ts +0 -15
- package/dist/core/session-row-enrichment.d.ts.map +0 -1
- package/dist/core/session-row-enrichment.js +0 -93
- package/dist/core/session-row-enrichment.js.map +0 -1
- package/dist/core/session-title.d.ts +0 -23
- package/dist/core/session-title.d.ts.map +0 -1
- package/dist/core/session-title.js +0 -88
- package/dist/core/session-title.js.map +0 -1
- package/dist/core/silent-schedule-turns.d.ts +0 -5
- package/dist/core/silent-schedule-turns.d.ts.map +0 -1
- package/dist/core/silent-schedule-turns.js +0 -47
- package/dist/core/silent-schedule-turns.js.map +0 -1
- package/dist/core/skills/claude-plugin-delivery.d.ts +0 -6
- package/dist/core/skills/claude-plugin-delivery.d.ts.map +0 -1
- package/dist/core/skills/claude-plugin-delivery.js +0 -21
- package/dist/core/skills/claude-plugin-delivery.js.map +0 -1
- package/dist/core/skills/cli-admin-command.d.ts +0 -7
- package/dist/core/skills/cli-admin-command.d.ts.map +0 -1
- package/dist/core/skills/cli-admin-command.js +0 -359
- package/dist/core/skills/cli-admin-command.js.map +0 -1
- package/dist/core/skills/cli-session-command.d.ts +0 -7
- package/dist/core/skills/cli-session-command.d.ts.map +0 -1
- package/dist/core/skills/cli-session-command.js +0 -72
- package/dist/core/skills/cli-session-command.js.map +0 -1
- package/dist/core/skills/delivery.d.ts +0 -11
- package/dist/core/skills/delivery.d.ts.map +0 -1
- package/dist/core/skills/delivery.js +0 -22
- package/dist/core/skills/delivery.js.map +0 -1
- package/dist/core/skills/discovery.d.ts +0 -26
- package/dist/core/skills/discovery.d.ts.map +0 -1
- package/dist/core/skills/discovery.js +0 -131
- package/dist/core/skills/discovery.js.map +0 -1
- package/dist/core/skills/frontmatter.d.ts +0 -9
- package/dist/core/skills/frontmatter.d.ts.map +0 -1
- package/dist/core/skills/frontmatter.js +0 -42
- package/dist/core/skills/frontmatter.js.map +0 -1
- package/dist/core/skills/im-command.d.ts +0 -9
- package/dist/core/skills/im-command.d.ts.map +0 -1
- package/dist/core/skills/im-command.js +0 -109
- package/dist/core/skills/im-command.js.map +0 -1
- package/dist/core/skills/manifest-store.d.ts +0 -5
- package/dist/core/skills/manifest-store.d.ts.map +0 -1
- package/dist/core/skills/manifest-store.js +0 -29
- package/dist/core/skills/manifest-store.js.map +0 -1
- package/dist/core/skills/package.d.ts +0 -13
- package/dist/core/skills/package.d.ts.map +0 -1
- package/dist/core/skills/package.js +0 -35
- package/dist/core/skills/package.js.map +0 -1
- package/dist/core/skills/policy.d.ts +0 -19
- package/dist/core/skills/policy.d.ts.map +0 -1
- package/dist/core/skills/policy.js +0 -73
- package/dist/core/skills/policy.js.map +0 -1
- package/dist/core/skills/prompt.d.ts +0 -3
- package/dist/core/skills/prompt.d.ts.map +0 -1
- package/dist/core/skills/prompt.js +0 -25
- package/dist/core/skills/prompt.js.map +0 -1
- package/dist/core/skills/references.d.ts +0 -21
- package/dist/core/skills/references.d.ts.map +0 -1
- package/dist/core/skills/references.js +0 -27
- package/dist/core/skills/references.js.map +0 -1
- package/dist/core/skills/registry-paths.d.ts +0 -5
- package/dist/core/skills/registry-paths.d.ts.map +0 -1
- package/dist/core/skills/registry-paths.js +0 -15
- package/dist/core/skills/registry-paths.js.map +0 -1
- package/dist/core/skills/resource-reader.d.ts +0 -9
- package/dist/core/skills/resource-reader.d.ts.map +0 -1
- package/dist/core/skills/resource-reader.js +0 -97
- package/dist/core/skills/resource-reader.js.map +0 -1
- package/dist/core/skills/session-resolver.d.ts +0 -15
- package/dist/core/skills/session-resolver.d.ts.map +0 -1
- package/dist/core/skills/session-resolver.js +0 -25
- package/dist/core/skills/session-resolver.js.map +0 -1
- package/dist/core/skills/session-runtime.d.ts +0 -15
- package/dist/core/skills/session-runtime.d.ts.map +0 -1
- package/dist/core/skills/session-runtime.js +0 -37
- package/dist/core/skills/session-runtime.js.map +0 -1
- package/dist/core/skills/sources.d.ts +0 -53
- package/dist/core/skills/sources.d.ts.map +0 -1
- package/dist/core/skills/sources.js +0 -257
- package/dist/core/skills/sources.js.map +0 -1
- package/dist/core/skills/types.d.ts +0 -83
- package/dist/core/skills/types.d.ts.map +0 -1
- package/dist/core/skills/types.js +0 -2
- package/dist/core/skills/types.js.map +0 -1
- package/dist/core/slash-inject.d.ts +0 -15
- package/dist/core/slash-inject.d.ts.map +0 -1
- package/dist/core/slash-inject.js +0 -25
- package/dist/core/slash-inject.js.map +0 -1
- package/dist/core/startup-commands.d.ts +0 -57
- package/dist/core/startup-commands.d.ts.map +0 -1
- package/dist/core/startup-commands.js +0 -85
- package/dist/core/startup-commands.js.map +0 -1
- package/dist/core/terminal-proxy.d.ts +0 -39
- package/dist/core/terminal-proxy.d.ts.map +0 -1
- package/dist/core/terminal-proxy.js +0 -160
- package/dist/core/terminal-proxy.js.map +0 -1
- package/dist/core/terminal-url.d.ts +0 -47
- package/dist/core/terminal-url.d.ts.map +0 -1
- package/dist/core/terminal-url.js +0 -87
- package/dist/core/terminal-url.js.map +0 -1
- package/dist/core/terminal-write-auth.d.ts +0 -75
- package/dist/core/terminal-write-auth.d.ts.map +0 -1
- package/dist/core/terminal-write-auth.js +0 -149
- package/dist/core/terminal-write-auth.js.map +0 -1
- package/dist/core/tmux-recovery.d.ts +0 -11
- package/dist/core/tmux-recovery.d.ts.map +0 -1
- package/dist/core/tmux-recovery.js +0 -19
- package/dist/core/tmux-recovery.js.map +0 -1
- package/dist/core/trigger-final-suppression.d.ts +0 -24
- package/dist/core/trigger-final-suppression.d.ts.map +0 -1
- package/dist/core/trigger-final-suppression.js +0 -97
- package/dist/core/trigger-final-suppression.js.map +0 -1
- package/dist/core/trigger-session.d.ts +0 -56
- package/dist/core/trigger-session.d.ts.map +0 -1
- package/dist/core/trigger-session.js +0 -637
- package/dist/core/trigger-session.js.map +0 -1
- package/dist/core/types.d.ts +0 -441
- package/dist/core/types.d.ts.map +0 -1
- package/dist/core/types.js +0 -128
- package/dist/core/types.js.map +0 -1
- package/dist/core/update-check.d.ts +0 -94
- package/dist/core/update-check.d.ts.map +0 -1
- package/dist/core/update-check.js +0 -216
- package/dist/core/update-check.js.map +0 -1
- package/dist/core/vc-meeting-prepare-command.d.ts +0 -22
- package/dist/core/vc-meeting-prepare-command.d.ts.map +0 -1
- package/dist/core/vc-meeting-prepare-command.js +0 -50
- package/dist/core/vc-meeting-prepare-command.js.map +0 -1
- package/dist/core/worker-ipc.d.ts +0 -11
- package/dist/core/worker-ipc.d.ts.map +0 -1
- package/dist/core/worker-ipc.js +0 -26
- package/dist/core/worker-ipc.js.map +0 -1
- package/dist/core/worker-pool.d.ts +0 -788
- package/dist/core/worker-pool.d.ts.map +0 -1
- package/dist/core/worker-pool.js +0 -6914
- package/dist/core/worker-pool.js.map +0 -1
- package/dist/core/working-dir.d.ts +0 -27
- package/dist/core/working-dir.d.ts.map +0 -1
- package/dist/core/working-dir.js +0 -52
- package/dist/core/working-dir.js.map +0 -1
- package/dist/core/zellij-adopt-discovery.d.ts +0 -42
- package/dist/core/zellij-adopt-discovery.d.ts.map +0 -1
- package/dist/core/zellij-adopt-discovery.js +0 -259
- package/dist/core/zellij-adopt-discovery.js.map +0 -1
- package/dist/core/zellij-session-discovery.d.ts +0 -76
- package/dist/core/zellij-session-discovery.d.ts.map +0 -1
- package/dist/core/zellij-session-discovery.js +0 -260
- package/dist/core/zellij-session-discovery.js.map +0 -1
- package/dist/daemon-internal-client-wrapper.d.ts +0 -41
- package/dist/daemon-internal-client-wrapper.d.ts.map +0 -1
- package/dist/daemon-internal-client-wrapper.js +0 -65
- package/dist/daemon-internal-client-wrapper.js.map +0 -1
- package/dist/daemon.d.ts +0 -610
- package/dist/daemon.d.ts.map +0 -1
- package/dist/daemon.js +0 -16756
- package/dist/daemon.js.map +0 -1
- package/dist/dashboard/aggregator.d.ts +0 -59
- package/dist/dashboard/aggregator.d.ts.map +0 -1
- package/dist/dashboard/aggregator.js +0 -176
- package/dist/dashboard/aggregator.js.map +0 -1
- package/dist/dashboard/auth.d.ts +0 -106
- package/dist/dashboard/auth.d.ts.map +0 -1
- package/dist/dashboard/auth.js +0 -253
- package/dist/dashboard/auth.js.map +0 -1
- package/dist/dashboard/bot-onboarding.d.ts +0 -320
- package/dist/dashboard/bot-onboarding.d.ts.map +0 -1
- package/dist/dashboard/bot-onboarding.js +0 -1666
- package/dist/dashboard/bot-onboarding.js.map +0 -1
- package/dist/dashboard/bot-payload.d.ts +0 -94
- package/dist/dashboard/bot-payload.d.ts.map +0 -1
- package/dist/dashboard/bot-payload.js +0 -96
- package/dist/dashboard/bot-payload.js.map +0 -1
- package/dist/dashboard/card-model-types.d.ts +0 -50
- package/dist/dashboard/card-model-types.d.ts.map +0 -1
- package/dist/dashboard/card-model-types.js +0 -9
- package/dist/dashboard/card-model-types.js.map +0 -1
- package/dist/dashboard/compat.d.ts +0 -119
- package/dist/dashboard/compat.d.ts.map +0 -1
- package/dist/dashboard/compat.js +0 -102
- package/dist/dashboard/compat.js.map +0 -1
- package/dist/dashboard/connector-api.d.ts +0 -3
- package/dist/dashboard/connector-api.d.ts.map +0 -1
- package/dist/dashboard/connector-api.js +0 -453
- package/dist/dashboard/connector-api.js.map +0 -1
- package/dist/dashboard/daemon-internal-api.d.ts +0 -88
- package/dist/dashboard/daemon-internal-api.d.ts.map +0 -1
- package/dist/dashboard/daemon-internal-api.js +0 -476
- package/dist/dashboard/daemon-internal-api.js.map +0 -1
- package/dist/dashboard/daemon-internal-auth.d.ts +0 -124
- package/dist/dashboard/daemon-internal-auth.d.ts.map +0 -1
- package/dist/dashboard/daemon-internal-auth.js +0 -188
- package/dist/dashboard/daemon-internal-auth.js.map +0 -1
- package/dist/dashboard/daemon-internal-client.d.ts +0 -67
- package/dist/dashboard/daemon-internal-client.d.ts.map +0 -1
- package/dist/dashboard/daemon-internal-client.js +0 -156
- package/dist/dashboard/daemon-internal-client.js.map +0 -1
- package/dist/dashboard/dashboard-admins.d.ts +0 -8
- package/dist/dashboard/dashboard-admins.d.ts.map +0 -1
- package/dist/dashboard/dashboard-admins.js +0 -15
- package/dist/dashboard/dashboard-admins.js.map +0 -1
- package/dist/dashboard/debug-terminal.d.ts +0 -18
- package/dist/dashboard/debug-terminal.d.ts.map +0 -1
- package/dist/dashboard/debug-terminal.js +0 -338
- package/dist/dashboard/debug-terminal.js.map +0 -1
- package/dist/dashboard/desktop-asks.d.ts +0 -21
- package/dist/dashboard/desktop-asks.d.ts.map +0 -1
- package/dist/dashboard/desktop-asks.js +0 -49
- package/dist/dashboard/desktop-asks.js.map +0 -1
- package/dist/dashboard/federated-group-core.d.ts +0 -75
- package/dist/dashboard/federated-group-core.d.ts.map +0 -1
- package/dist/dashboard/federated-group-core.js +0 -236
- package/dist/dashboard/federated-group-core.js.map +0 -1
- package/dist/dashboard/federation-api.d.ts +0 -43
- package/dist/dashboard/federation-api.d.ts.map +0 -1
- package/dist/dashboard/federation-api.js +0 -580
- package/dist/dashboard/federation-api.js.map +0 -1
- package/dist/dashboard/federation-spoke-api.d.ts +0 -129
- package/dist/dashboard/federation-spoke-api.d.ts.map +0 -1
- package/dist/dashboard/federation-spoke-api.js +0 -809
- package/dist/dashboard/federation-spoke-api.js.map +0 -1
- package/dist/dashboard/feishu-login.d.ts +0 -64
- package/dist/dashboard/feishu-login.d.ts.map +0 -1
- package/dist/dashboard/feishu-login.js +0 -99
- package/dist/dashboard/feishu-login.js.map +0 -1
- package/dist/dashboard/groups-action-helpers.d.ts +0 -71
- package/dist/dashboard/groups-action-helpers.d.ts.map +0 -1
- package/dist/dashboard/groups-action-helpers.js +0 -150
- package/dist/dashboard/groups-action-helpers.js.map +0 -1
- package/dist/dashboard/groups-card-model.d.ts +0 -120
- package/dist/dashboard/groups-card-model.d.ts.map +0 -1
- package/dist/dashboard/groups-card-model.js +0 -175
- package/dist/dashboard/groups-card-model.js.map +0 -1
- package/dist/dashboard/groups-matrix-snapshot.d.ts +0 -56
- package/dist/dashboard/groups-matrix-snapshot.d.ts.map +0 -1
- package/dist/dashboard/groups-matrix-snapshot.js +0 -127
- package/dist/dashboard/groups-matrix-snapshot.js.map +0 -1
- package/dist/dashboard/hd2d-assets.d.ts +0 -20
- package/dist/dashboard/hd2d-assets.d.ts.map +0 -1
- package/dist/dashboard/hd2d-assets.js +0 -216
- package/dist/dashboard/hd2d-assets.js.map +0 -1
- package/dist/dashboard/history-senders.d.ts +0 -40
- package/dist/dashboard/history-senders.d.ts.map +0 -1
- package/dist/dashboard/history-senders.js +0 -60
- package/dist/dashboard/history-senders.js.map +0 -1
- package/dist/dashboard/http.d.ts +0 -4
- package/dist/dashboard/http.d.ts.map +0 -1
- package/dist/dashboard/http.js +0 -6
- package/dist/dashboard/http.js.map +0 -1
- package/dist/dashboard/operator-selector.d.ts +0 -20
- package/dist/dashboard/operator-selector.d.ts.map +0 -1
- package/dist/dashboard/operator-selector.js +0 -39
- package/dist/dashboard/operator-selector.js.map +0 -1
- package/dist/dashboard/public-redact.d.ts +0 -32
- package/dist/dashboard/public-redact.d.ts.map +0 -1
- package/dist/dashboard/public-redact.js +0 -137
- package/dist/dashboard/public-redact.js.map +0 -1
- package/dist/dashboard/registry.d.ts +0 -56
- package/dist/dashboard/registry.d.ts.map +0 -1
- package/dist/dashboard/registry.js +0 -99
- package/dist/dashboard/registry.js.map +0 -1
- package/dist/dashboard/resource-monitor-service.d.ts +0 -56
- package/dist/dashboard/resource-monitor-service.d.ts.map +0 -1
- package/dist/dashboard/resource-monitor-service.js +0 -462
- package/dist/dashboard/resource-monitor-service.js.map +0 -1
- package/dist/dashboard/roles-batch.d.ts +0 -31
- package/dist/dashboard/roles-batch.d.ts.map +0 -1
- package/dist/dashboard/roles-batch.js +0 -87
- package/dist/dashboard/roles-batch.js.map +0 -1
- package/dist/dashboard/schedule-card-model.d.ts +0 -185
- package/dist/dashboard/schedule-card-model.d.ts.map +0 -1
- package/dist/dashboard/schedule-card-model.js +0 -320
- package/dist/dashboard/schedule-card-model.js.map +0 -1
- package/dist/dashboard/session-card-model.d.ts +0 -83
- package/dist/dashboard/session-card-model.d.ts.map +0 -1
- package/dist/dashboard/session-card-model.js +0 -207
- package/dist/dashboard/session-card-model.js.map +0 -1
- package/dist/dashboard/session-cleanup.d.ts +0 -31
- package/dist/dashboard/session-cleanup.d.ts.map +0 -1
- package/dist/dashboard/session-cleanup.js +0 -49
- package/dist/dashboard/session-cleanup.js.map +0 -1
- package/dist/dashboard/session-presentation.d.ts +0 -16
- package/dist/dashboard/session-presentation.d.ts.map +0 -1
- package/dist/dashboard/session-presentation.js +0 -62
- package/dist/dashboard/session-presentation.js.map +0 -1
- package/dist/dashboard/settings-card-model.d.ts +0 -76
- package/dist/dashboard/settings-card-model.d.ts.map +0 -1
- package/dist/dashboard/settings-card-model.js +0 -109
- package/dist/dashboard/settings-card-model.js.map +0 -1
- package/dist/dashboard/settings-owner-resolver.d.ts +0 -32
- package/dist/dashboard/settings-owner-resolver.d.ts.map +0 -1
- package/dist/dashboard/settings-owner-resolver.js +0 -43
- package/dist/dashboard/settings-owner-resolver.js.map +0 -1
- package/dist/dashboard/settings-write-applier.d.ts +0 -219
- package/dist/dashboard/settings-write-applier.d.ts.map +0 -1
- package/dist/dashboard/settings-write-applier.js +0 -467
- package/dist/dashboard/settings-write-applier.js.map +0 -1
- package/dist/dashboard/skill-install-request.d.ts +0 -46
- package/dist/dashboard/skill-install-request.d.ts.map +0 -1
- package/dist/dashboard/skill-install-request.js +0 -150
- package/dist/dashboard/skill-install-request.js.map +0 -1
- package/dist/dashboard/stale-chunk-module.d.ts +0 -3
- package/dist/dashboard/stale-chunk-module.d.ts.map +0 -1
- package/dist/dashboard/stale-chunk-module.js +0 -55
- package/dist/dashboard/stale-chunk-module.js.map +0 -1
- package/dist/dashboard/team-group.d.ts +0 -39
- package/dist/dashboard/team-group.d.ts.map +0 -1
- package/dist/dashboard/team-group.js +0 -23
- package/dist/dashboard/team-group.js.map +0 -1
- package/dist/dashboard/trigger-api.d.ts +0 -25
- package/dist/dashboard/trigger-api.d.ts.map +0 -1
- package/dist/dashboard/trigger-api.js +0 -153
- package/dist/dashboard/trigger-api.js.map +0 -1
- package/dist/dashboard/v3-runs-api.d.ts +0 -29
- package/dist/dashboard/v3-runs-api.d.ts.map +0 -1
- package/dist/dashboard/v3-runs-api.js +0 -184
- package/dist/dashboard/v3-runs-api.js.map +0 -1
- package/dist/dashboard/vc-consumer-profiles-api.d.ts +0 -110
- package/dist/dashboard/vc-consumer-profiles-api.d.ts.map +0 -1
- package/dist/dashboard/vc-consumer-profiles-api.js +0 -325
- package/dist/dashboard/vc-consumer-profiles-api.js.map +0 -1
- package/dist/dashboard/web/app.d.ts +0 -3
- package/dist/dashboard/web/app.d.ts.map +0 -1
- package/dist/dashboard/web/app.js +0 -962
- package/dist/dashboard/web/app.js.map +0 -1
- package/dist/dashboard/web/auth-login.d.ts +0 -3
- package/dist/dashboard/web/auth-login.d.ts.map +0 -1
- package/dist/dashboard/web/auth-login.js +0 -19
- package/dist/dashboard/web/auth-login.js.map +0 -1
- package/dist/dashboard/web/bot-defaults-page.d.ts +0 -78
- package/dist/dashboard/web/bot-defaults-page.d.ts.map +0 -1
- package/dist/dashboard/web/bot-defaults-page.js +0 -2486
- package/dist/dashboard/web/bot-defaults-page.js.map +0 -1
- package/dist/dashboard/web/bot-defaults.d.ts +0 -163
- package/dist/dashboard/web/bot-defaults.d.ts.map +0 -1
- package/dist/dashboard/web/bot-defaults.js +0 -127
- package/dist/dashboard/web/bot-defaults.js.map +0 -1
- package/dist/dashboard/web/bot-onboarding.d.ts +0 -9
- package/dist/dashboard/web/bot-onboarding.d.ts.map +0 -1
- package/dist/dashboard/web/bot-onboarding.js +0 -421
- package/dist/dashboard/web/bot-onboarding.js.map +0 -1
- package/dist/dashboard/web/client-shell.d.ts +0 -29
- package/dist/dashboard/web/client-shell.d.ts.map +0 -1
- package/dist/dashboard/web/client-shell.js +0 -89
- package/dist/dashboard/web/client-shell.js.map +0 -1
- package/dist/dashboard/web/clipboard.d.ts +0 -2
- package/dist/dashboard/web/clipboard.d.ts.map +0 -1
- package/dist/dashboard/web/clipboard.js +0 -42
- package/dist/dashboard/web/clipboard.js.map +0 -1
- package/dist/dashboard/web/connectors-page.d.ts +0 -23
- package/dist/dashboard/web/connectors-page.d.ts.map +0 -1
- package/dist/dashboard/web/connectors-page.js +0 -516
- package/dist/dashboard/web/connectors-page.js.map +0 -1
- package/dist/dashboard/web/create-session-composer.d.ts +0 -35
- package/dist/dashboard/web/create-session-composer.d.ts.map +0 -1
- package/dist/dashboard/web/create-session-composer.js +0 -70
- package/dist/dashboard/web/create-session-composer.js.map +0 -1
- package/dist/dashboard/web/create-session-entry.d.ts +0 -4
- package/dist/dashboard/web/create-session-entry.d.ts.map +0 -1
- package/dist/dashboard/web/create-session-entry.js +0 -17
- package/dist/dashboard/web/create-session-entry.js.map +0 -1
- package/dist/dashboard/web/cyber-fx.d.ts +0 -6
- package/dist/dashboard/web/cyber-fx.d.ts.map +0 -1
- package/dist/dashboard/web/cyber-fx.js +0 -289
- package/dist/dashboard/web/cyber-fx.js.map +0 -1
- package/dist/dashboard/web/dashboard-api.d.ts +0 -9
- package/dist/dashboard/web/dashboard-api.d.ts.map +0 -1
- package/dist/dashboard/web/dashboard-api.js +0 -18
- package/dist/dashboard/web/dashboard-api.js.map +0 -1
- package/dist/dashboard/web/dashboard-components.d.ts +0 -105
- package/dist/dashboard/web/dashboard-components.d.ts.map +0 -1
- package/dist/dashboard/web/dashboard-components.js +0 -284
- package/dist/dashboard/web/dashboard-components.js.map +0 -1
- package/dist/dashboard/web/dashboard-routes.d.ts +0 -14
- package/dist/dashboard/web/dashboard-routes.d.ts.map +0 -1
- package/dist/dashboard/web/dashboard-routes.js +0 -49
- package/dist/dashboard/web/dashboard-routes.js.map +0 -1
- package/dist/dashboard/web/floating-scrollbars.d.ts +0 -2
- package/dist/dashboard/web/floating-scrollbars.d.ts.map +0 -1
- package/dist/dashboard/web/floating-scrollbars.js +0 -264
- package/dist/dashboard/web/floating-scrollbars.js.map +0 -1
- package/dist/dashboard/web/groups-api.d.ts +0 -36
- package/dist/dashboard/web/groups-api.d.ts.map +0 -1
- package/dist/dashboard/web/groups-api.js +0 -44
- package/dist/dashboard/web/groups-api.js.map +0 -1
- package/dist/dashboard/web/groups-page.d.ts +0 -3
- package/dist/dashboard/web/groups-page.d.ts.map +0 -1
- package/dist/dashboard/web/groups-page.js +0 -761
- package/dist/dashboard/web/groups-page.js.map +0 -1
- package/dist/dashboard/web/groups.d.ts +0 -58
- package/dist/dashboard/web/groups.d.ts.map +0 -1
- package/dist/dashboard/web/groups.js +0 -203
- package/dist/dashboard/web/groups.js.map +0 -1
- package/dist/dashboard/web/i18n.d.ts +0 -7
- package/dist/dashboard/web/i18n.d.ts.map +0 -1
- package/dist/dashboard/web/i18n.js +0 -4295
- package/dist/dashboard/web/i18n.js.map +0 -1
- package/dist/dashboard/web/icon-tooltip.d.ts +0 -3
- package/dist/dashboard/web/icon-tooltip.d.ts.map +0 -1
- package/dist/dashboard/web/icon-tooltip.js +0 -123
- package/dist/dashboard/web/icon-tooltip.js.map +0 -1
- package/dist/dashboard/web/insights-page.d.ts +0 -3
- package/dist/dashboard/web/insights-page.d.ts.map +0 -1
- package/dist/dashboard/web/insights-page.js +0 -1059
- package/dist/dashboard/web/insights-page.js.map +0 -1
- package/dist/dashboard/web/insights.d.ts +0 -189
- package/dist/dashboard/web/insights.d.ts.map +0 -1
- package/dist/dashboard/web/insights.js +0 -519
- package/dist/dashboard/web/insights.js.map +0 -1
- package/dist/dashboard/web/kanban-model.d.ts +0 -19
- package/dist/dashboard/web/kanban-model.d.ts.map +0 -1
- package/dist/dashboard/web/kanban-model.js +0 -40
- package/dist/dashboard/web/kanban-model.js.map +0 -1
- package/dist/dashboard/web/listener-filters.d.ts +0 -54
- package/dist/dashboard/web/listener-filters.d.ts.map +0 -1
- package/dist/dashboard/web/listener-filters.js +0 -94
- package/dist/dashboard/web/listener-filters.js.map +0 -1
- package/dist/dashboard/web/monitor-room-store.d.ts +0 -20
- package/dist/dashboard/web/monitor-room-store.d.ts.map +0 -1
- package/dist/dashboard/web/monitor-room-store.js +0 -80
- package/dist/dashboard/web/monitor-room-store.js.map +0 -1
- package/dist/dashboard/web/monitor-room.d.ts +0 -31
- package/dist/dashboard/web/monitor-room.d.ts.map +0 -1
- package/dist/dashboard/web/monitor-room.js +0 -395
- package/dist/dashboard/web/monitor-room.js.map +0 -1
- package/dist/dashboard/web/monitoring-page.d.ts +0 -155
- package/dist/dashboard/web/monitoring-page.d.ts.map +0 -1
- package/dist/dashboard/web/monitoring-page.js +0 -363
- package/dist/dashboard/web/monitoring-page.js.map +0 -1
- package/dist/dashboard/web/office-page.d.ts +0 -3
- package/dist/dashboard/web/office-page.d.ts.map +0 -1
- package/dist/dashboard/web/office-page.js +0 -137
- package/dist/dashboard/web/office-page.js.map +0 -1
- package/dist/dashboard/web/overview-page.d.ts +0 -3
- package/dist/dashboard/web/overview-page.d.ts.map +0 -1
- package/dist/dashboard/web/overview-page.js +0 -253
- package/dist/dashboard/web/overview-page.js.map +0 -1
- package/dist/dashboard/web/overview.d.ts +0 -23
- package/dist/dashboard/web/overview.d.ts.map +0 -1
- package/dist/dashboard/web/overview.js +0 -81
- package/dist/dashboard/web/overview.js.map +0 -1
- package/dist/dashboard/web/plugin-events.d.ts +0 -2
- package/dist/dashboard/web/plugin-events.d.ts.map +0 -1
- package/dist/dashboard/web/plugin-events.js +0 -2
- package/dist/dashboard/web/plugin-events.js.map +0 -1
- package/dist/dashboard/web/plugin-page.d.ts +0 -3
- package/dist/dashboard/web/plugin-page.d.ts.map +0 -1
- package/dist/dashboard/web/plugin-page.js +0 -467
- package/dist/dashboard/web/plugin-page.js.map +0 -1
- package/dist/dashboard/web/preferences.d.ts +0 -42
- package/dist/dashboard/web/preferences.d.ts.map +0 -1
- package/dist/dashboard/web/preferences.js +0 -162
- package/dist/dashboard/web/preferences.js.map +0 -1
- package/dist/dashboard/web/preview-markdown.d.ts +0 -5
- package/dist/dashboard/web/preview-markdown.d.ts.map +0 -1
- package/dist/dashboard/web/preview-markdown.js +0 -52
- package/dist/dashboard/web/preview-markdown.js.map +0 -1
- package/dist/dashboard/web/react-hooks.d.ts +0 -8
- package/dist/dashboard/web/react-hooks.d.ts.map +0 -1
- package/dist/dashboard/web/react-hooks.js +0 -43
- package/dist/dashboard/web/react-hooks.js.map +0 -1
- package/dist/dashboard/web/react-mount.d.ts +0 -4
- package/dist/dashboard/web/react-mount.d.ts.map +0 -1
- package/dist/dashboard/web/react-mount.js +0 -7
- package/dist/dashboard/web/react-mount.js.map +0 -1
- package/dist/dashboard/web/role-batch.d.ts +0 -9
- package/dist/dashboard/web/role-batch.d.ts.map +0 -1
- package/dist/dashboard/web/role-batch.js +0 -42
- package/dist/dashboard/web/role-batch.js.map +0 -1
- package/dist/dashboard/web/role-profile-match.d.ts +0 -31
- package/dist/dashboard/web/role-profile-match.d.ts.map +0 -1
- package/dist/dashboard/web/role-profile-match.js +0 -58
- package/dist/dashboard/web/role-profile-match.js.map +0 -1
- package/dist/dashboard/web/roles-page.d.ts +0 -4
- package/dist/dashboard/web/roles-page.d.ts.map +0 -1
- package/dist/dashboard/web/roles-page.js +0 -1120
- package/dist/dashboard/web/roles-page.js.map +0 -1
- package/dist/dashboard/web/roles.d.ts +0 -177
- package/dist/dashboard/web/roles.d.ts.map +0 -1
- package/dist/dashboard/web/roles.js +0 -272
- package/dist/dashboard/web/roles.js.map +0 -1
- package/dist/dashboard/web/route-lifecycle.d.ts +0 -14
- package/dist/dashboard/web/route-lifecycle.d.ts.map +0 -1
- package/dist/dashboard/web/route-lifecycle.js +0 -29
- package/dist/dashboard/web/route-lifecycle.js.map +0 -1
- package/dist/dashboard/web/schedules-page.d.ts +0 -16
- package/dist/dashboard/web/schedules-page.d.ts.map +0 -1
- package/dist/dashboard/web/schedules-page.js +0 -303
- package/dist/dashboard/web/schedules-page.js.map +0 -1
- package/dist/dashboard/web/session-terminal.d.ts +0 -7
- package/dist/dashboard/web/session-terminal.d.ts.map +0 -1
- package/dist/dashboard/web/session-terminal.js +0 -23
- package/dist/dashboard/web/session-terminal.js.map +0 -1
- package/dist/dashboard/web/sessions-kanban.d.ts +0 -70
- package/dist/dashboard/web/sessions-kanban.d.ts.map +0 -1
- package/dist/dashboard/web/sessions-kanban.js +0 -481
- package/dist/dashboard/web/sessions-kanban.js.map +0 -1
- package/dist/dashboard/web/sessions-page.d.ts +0 -27
- package/dist/dashboard/web/sessions-page.d.ts.map +0 -1
- package/dist/dashboard/web/sessions-page.js +0 -2085
- package/dist/dashboard/web/sessions-page.js.map +0 -1
- package/dist/dashboard/web/sessions.d.ts +0 -116
- package/dist/dashboard/web/sessions.d.ts.map +0 -1
- package/dist/dashboard/web/sessions.js +0 -390
- package/dist/dashboard/web/sessions.js.map +0 -1
- package/dist/dashboard/web/settings-page.d.ts +0 -119
- package/dist/dashboard/web/settings-page.d.ts.map +0 -1
- package/dist/dashboard/web/settings-page.js +0 -772
- package/dist/dashboard/web/settings-page.js.map +0 -1
- package/dist/dashboard/web/skills-page.d.ts +0 -90
- package/dist/dashboard/web/skills-page.d.ts.map +0 -1
- package/dist/dashboard/web/skills-page.js +0 -1004
- package/dist/dashboard/web/skills-page.js.map +0 -1
- package/dist/dashboard/web/stale-chunk-reload.d.ts +0 -16
- package/dist/dashboard/web/stale-chunk-reload.d.ts.map +0 -1
- package/dist/dashboard/web/stale-chunk-reload.js +0 -51
- package/dist/dashboard/web/stale-chunk-reload.js.map +0 -1
- package/dist/dashboard/web/store.d.ts +0 -39
- package/dist/dashboard/web/store.d.ts.map +0 -1
- package/dist/dashboard/web/store.js +0 -177
- package/dist/dashboard/web/store.js.map +0 -1
- package/dist/dashboard/web/substitute-targets.d.ts +0 -30
- package/dist/dashboard/web/substitute-targets.d.ts.map +0 -1
- package/dist/dashboard/web/substitute-targets.js +0 -99
- package/dist/dashboard/web/substitute-targets.js.map +0 -1
- package/dist/dashboard/web/team-federation-page.d.ts +0 -4
- package/dist/dashboard/web/team-federation-page.d.ts.map +0 -1
- package/dist/dashboard/web/team-federation-page.js +0 -465
- package/dist/dashboard/web/team-federation-page.js.map +0 -1
- package/dist/dashboard/web/team-federation.d.ts +0 -92
- package/dist/dashboard/web/team-federation.d.ts.map +0 -1
- package/dist/dashboard/web/team-federation.js +0 -106
- package/dist/dashboard/web/team-federation.js.map +0 -1
- package/dist/dashboard/web/theme-menu.d.ts +0 -4
- package/dist/dashboard/web/theme-menu.d.ts.map +0 -1
- package/dist/dashboard/web/theme-menu.js +0 -173
- package/dist/dashboard/web/theme-menu.js.map +0 -1
- package/dist/dashboard/web/ui.d.ts +0 -81
- package/dist/dashboard/web/ui.d.ts.map +0 -1
- package/dist/dashboard/web/ui.js +0 -330
- package/dist/dashboard/web/ui.js.map +0 -1
- package/dist/dashboard/web/update-action.d.ts +0 -16
- package/dist/dashboard/web/update-action.d.ts.map +0 -1
- package/dist/dashboard/web/update-action.js +0 -64
- package/dist/dashboard/web/update-action.js.map +0 -1
- package/dist/dashboard/web/v3-api.d.ts +0 -26
- package/dist/dashboard/web/v3-api.d.ts.map +0 -1
- package/dist/dashboard/web/v3-api.js +0 -49
- package/dist/dashboard/web/v3-api.js.map +0 -1
- package/dist/dashboard/web/v3-components.d.ts +0 -9
- package/dist/dashboard/web/v3-components.d.ts.map +0 -1
- package/dist/dashboard/web/v3-components.js +0 -333
- package/dist/dashboard/web/v3-components.js.map +0 -1
- package/dist/dashboard/web/v3-model.d.ts +0 -80
- package/dist/dashboard/web/v3-model.d.ts.map +0 -1
- package/dist/dashboard/web/v3-model.js +0 -240
- package/dist/dashboard/web/v3-model.js.map +0 -1
- package/dist/dashboard/web/v3-page.d.ts +0 -3
- package/dist/dashboard/web/v3-page.d.ts.map +0 -1
- package/dist/dashboard/web/v3-page.js +0 -7
- package/dist/dashboard/web/v3-page.js.map +0 -1
- package/dist/dashboard/web/v3-terminal.d.ts +0 -25
- package/dist/dashboard/web/v3-terminal.d.ts.map +0 -1
- package/dist/dashboard/web/v3-terminal.js +0 -155
- package/dist/dashboard/web/v3-terminal.js.map +0 -1
- package/dist/dashboard/web/vc-consumer-profiles-section.d.ts +0 -29
- package/dist/dashboard/web/vc-consumer-profiles-section.d.ts.map +0 -1
- package/dist/dashboard/web/vc-consumer-profiles-section.js +0 -459
- package/dist/dashboard/web/vc-consumer-profiles-section.js.map +0 -1
- package/dist/dashboard/web/webhook-logs-page.d.ts +0 -17
- package/dist/dashboard/web/webhook-logs-page.d.ts.map +0 -1
- package/dist/dashboard/web/webhook-logs-page.js +0 -198
- package/dist/dashboard/web/webhook-logs-page.js.map +0 -1
- package/dist/dashboard/web/whiteboards-page.d.ts +0 -3
- package/dist/dashboard/web/whiteboards-page.d.ts.map +0 -1
- package/dist/dashboard/web/whiteboards-page.js +0 -198
- package/dist/dashboard/web/whiteboards-page.js.map +0 -1
- package/dist/dashboard/webhook-routes.d.ts +0 -19
- package/dist/dashboard/webhook-routes.d.ts.map +0 -1
- package/dist/dashboard/webhook-routes.js +0 -618
- package/dist/dashboard/webhook-routes.js.map +0 -1
- package/dist/dashboard-web/app.js +0 -1
- package/dist/dashboard-web/apple-touch-icon.png +0 -0
- package/dist/dashboard-web/brand-logo.png +0 -0
- package/dist/dashboard-web/chunks/bot-defaults-page-LTVOUDIS.js +0 -10
- package/dist/dashboard-web/chunks/chunk-3UE7S77S.js +0 -1
- package/dist/dashboard-web/chunks/chunk-5CJMHTT4.js +0 -1
- package/dist/dashboard-web/chunks/chunk-5THX4DI2.js +0 -66
- package/dist/dashboard-web/chunks/chunk-7SZRL6FY.js +0 -1
- package/dist/dashboard-web/chunks/chunk-AGCPF6MT.js +0 -1
- package/dist/dashboard-web/chunks/chunk-BD3PZGH2.js +0 -1
- package/dist/dashboard-web/chunks/chunk-DCS35UMD.js +0 -1
- package/dist/dashboard-web/chunks/chunk-EVK77ASG.js +0 -1
- package/dist/dashboard-web/chunks/chunk-FDZ7WOBW.js +0 -16
- package/dist/dashboard-web/chunks/chunk-MFQPCVHY.js +0 -51
- package/dist/dashboard-web/chunks/chunk-R3FXBFQH.js +0 -1
- package/dist/dashboard-web/chunks/chunk-SYC6D5XU.js +0 -1
- package/dist/dashboard-web/chunks/chunk-XJ7BGPJH.js +0 -1
- package/dist/dashboard-web/chunks/chunk-ZJVTGU5X.js +0 -1
- package/dist/dashboard-web/chunks/chunk-ZU3UUKAR.js +0 -1
- package/dist/dashboard-web/chunks/connectors-page-5KWDIMKC.js +0 -1
- package/dist/dashboard-web/chunks/groups-page-FHOKYXMW.js +0 -8
- package/dist/dashboard-web/chunks/insights-page-T2ZX2RWL.js +0 -7
- package/dist/dashboard-web/chunks/monitor-room-YNVBAGR6.js +0 -53
- package/dist/dashboard-web/chunks/monitoring-page-LHM55YWN.js +0 -2
- package/dist/dashboard-web/chunks/office-page-ATXVP7PW.js +0 -1
- package/dist/dashboard-web/chunks/overview-page-QYI3KBDD.js +0 -1
- package/dist/dashboard-web/chunks/plugin-page-VEGTCEAS.js +0 -1
- package/dist/dashboard-web/chunks/roles-page-56VWM6CD.js +0 -1
- package/dist/dashboard-web/chunks/schedules-page-S5K6U4EO.js +0 -1
- package/dist/dashboard-web/chunks/sessions-page-WBP4N7D2.js +0 -6
- package/dist/dashboard-web/chunks/settings-page-QUZDQARR.js +0 -2
- package/dist/dashboard-web/chunks/skills-page-IFY7AEND.js +0 -4
- package/dist/dashboard-web/chunks/team-federation-page-C7FJQPFZ.js +0 -1
- package/dist/dashboard-web/chunks/v3-page-2LMF3WWR.js +0 -94
- package/dist/dashboard-web/chunks/whiteboards-page-3XC6QRMY.js +0 -1
- package/dist/dashboard-web/favicon.png +0 -0
- package/dist/dashboard-web/game/index.apple-touch-icon.png +0 -0
- package/dist/dashboard-web/game/index.audio.position.worklet.js +0 -66
- package/dist/dashboard-web/game/index.audio.worklet.js +0 -213
- package/dist/dashboard-web/game/index.html +0 -224
- package/dist/dashboard-web/game/index.icon.png +0 -0
- package/dist/dashboard-web/game/index.js +0 -909
- package/dist/dashboard-web/game/index.png +0 -0
- package/dist/dashboard-web/index.html +0 -17
- package/dist/dashboard-web/skins/fallout-vaultboy.webp +0 -0
- package/dist/dashboard-web/style.css +0 -25771
- package/dist/dashboard.d.ts +0 -2
- package/dist/dashboard.d.ts.map +0 -1
- package/dist/dashboard.js +0 -5487
- package/dist/dashboard.js.map +0 -1
- package/dist/desktop/main/auto-start.d.ts +0 -19
- package/dist/desktop/main/auto-start.d.ts.map +0 -1
- package/dist/desktop/main/auto-start.js +0 -41
- package/dist/desktop/main/auto-start.js.map +0 -1
- package/dist/desktop/main/bundled-runtime.d.ts +0 -12
- package/dist/desktop/main/bundled-runtime.d.ts.map +0 -1
- package/dist/desktop/main/bundled-runtime.js +0 -30
- package/dist/desktop/main/bundled-runtime.js.map +0 -1
- package/dist/desktop/main/dashboard-compat.d.ts +0 -25
- package/dist/desktop/main/dashboard-compat.d.ts.map +0 -1
- package/dist/desktop/main/dashboard-compat.js +0 -117
- package/dist/desktop/main/dashboard-compat.js.map +0 -1
- package/dist/desktop/main/device-status.d.ts +0 -15
- package/dist/desktop/main/device-status.d.ts.map +0 -1
- package/dist/desktop/main/device-status.js +0 -94
- package/dist/desktop/main/device-status.js.map +0 -1
- package/dist/desktop/main/external-runtime.d.ts +0 -38
- package/dist/desktop/main/external-runtime.d.ts.map +0 -1
- package/dist/desktop/main/external-runtime.js +0 -272
- package/dist/desktop/main/external-runtime.js.map +0 -1
- package/dist/desktop/main/ipc.d.ts +0 -20
- package/dist/desktop/main/ipc.d.ts.map +0 -1
- package/dist/desktop/main/ipc.js +0 -242
- package/dist/desktop/main/ipc.js.map +0 -1
- package/dist/desktop/main/log-service.d.ts +0 -4
- package/dist/desktop/main/log-service.d.ts.map +0 -1
- package/dist/desktop/main/log-service.js +0 -53
- package/dist/desktop/main/log-service.js.map +0 -1
- package/dist/desktop/main/login-item.d.ts +0 -10
- package/dist/desktop/main/login-item.d.ts.map +0 -1
- package/dist/desktop/main/login-item.js +0 -11
- package/dist/desktop/main/login-item.js.map +0 -1
- package/dist/desktop/main/node-command.d.ts +0 -43
- package/dist/desktop/main/node-command.d.ts.map +0 -1
- package/dist/desktop/main/node-command.js +0 -97
- package/dist/desktop/main/node-command.js.map +0 -1
- package/dist/desktop/main/paths.d.ts +0 -11
- package/dist/desktop/main/paths.d.ts.map +0 -1
- package/dist/desktop/main/paths.js +0 -13
- package/dist/desktop/main/paths.js.map +0 -1
- package/dist/desktop/main/pm2-apps.d.ts +0 -17
- package/dist/desktop/main/pm2-apps.d.ts.map +0 -1
- package/dist/desktop/main/pm2-apps.js +0 -105
- package/dist/desktop/main/pm2-apps.js.map +0 -1
- package/dist/desktop/main/runtime-service.d.ts +0 -65
- package/dist/desktop/main/runtime-service.d.ts.map +0 -1
- package/dist/desktop/main/runtime-service.js +0 -381
- package/dist/desktop/main/runtime-service.js.map +0 -1
- package/dist/desktop/main/runtime-source.d.ts +0 -19
- package/dist/desktop/main/runtime-source.d.ts.map +0 -1
- package/dist/desktop/main/runtime-source.js +0 -67
- package/dist/desktop/main/runtime-source.js.map +0 -1
- package/dist/desktop/main/tray.d.ts +0 -11
- package/dist/desktop/main/tray.d.ts.map +0 -1
- package/dist/desktop/main/tray.js +0 -27
- package/dist/desktop/main/tray.js.map +0 -1
- package/dist/desktop/main/window.d.ts +0 -16
- package/dist/desktop/main/window.d.ts.map +0 -1
- package/dist/desktop/main/window.js +0 -113
- package/dist/desktop/main/window.js.map +0 -1
- package/dist/desktop/main.d.ts +0 -2
- package/dist/desktop/main.d.ts.map +0 -1
- package/dist/desktop/main.js +0 -195
- package/dist/desktop/main.js.map +0 -1
- package/dist/desktop/preload.d.ts +0 -2
- package/dist/desktop/preload.d.ts.map +0 -1
- package/dist/desktop/preload.js +0 -27
- package/dist/desktop/preload.js.map +0 -1
- package/dist/desktop/renderer/app.d.ts +0 -36
- package/dist/desktop/renderer/app.d.ts.map +0 -1
- package/dist/desktop/renderer/app.js +0 -950
- package/dist/desktop/renderer/app.js.map +0 -1
- package/dist/desktop/renderer/dashboard-url.d.ts +0 -13
- package/dist/desktop/renderer/dashboard-url.d.ts.map +0 -1
- package/dist/desktop/renderer/dashboard-url.js +0 -98
- package/dist/desktop/renderer/dashboard-url.js.map +0 -1
- package/dist/desktop/renderer/runtime-state.d.ts +0 -8
- package/dist/desktop/renderer/runtime-state.d.ts.map +0 -1
- package/dist/desktop/renderer/runtime-state.js +0 -69
- package/dist/desktop/renderer/runtime-state.js.map +0 -1
- package/dist/desktop/shared/shell-path-probes.d.ts +0 -24
- package/dist/desktop/shared/shell-path-probes.d.ts.map +0 -1
- package/dist/desktop/shared/shell-path-probes.js +0 -38
- package/dist/desktop/shared/shell-path-probes.js.map +0 -1
- package/dist/desktop/shared/types.d.ts +0 -68
- package/dist/desktop/shared/types.d.ts.map +0 -1
- package/dist/desktop/shared/types.js +0 -2
- package/dist/desktop/shared/types.js.map +0 -1
- package/dist/desktop/smoke.d.ts +0 -29
- package/dist/desktop/smoke.d.ts.map +0 -1
- package/dist/desktop/smoke.js +0 -273
- package/dist/desktop/smoke.js.map +0 -1
- package/dist/features/codex-notifier/adoption.d.ts +0 -11
- package/dist/features/codex-notifier/adoption.d.ts.map +0 -1
- package/dist/features/codex-notifier/adoption.js +0 -11
- package/dist/features/codex-notifier/adoption.js.map +0 -1
- package/dist/features/codex-notifier/app-opener.d.ts +0 -21
- package/dist/features/codex-notifier/app-opener.d.ts.map +0 -1
- package/dist/features/codex-notifier/app-opener.js +0 -33
- package/dist/features/codex-notifier/app-opener.js.map +0 -1
- package/dist/features/codex-notifier/card-action.d.ts +0 -27
- package/dist/features/codex-notifier/card-action.d.ts.map +0 -1
- package/dist/features/codex-notifier/card-action.js +0 -84
- package/dist/features/codex-notifier/card-action.js.map +0 -1
- package/dist/features/codex-notifier/card.d.ts +0 -12
- package/dist/features/codex-notifier/card.d.ts.map +0 -1
- package/dist/features/codex-notifier/card.js +0 -150
- package/dist/features/codex-notifier/card.js.map +0 -1
- package/dist/features/codex-notifier/codex-context.d.ts +0 -12
- package/dist/features/codex-notifier/codex-context.d.ts.map +0 -1
- package/dist/features/codex-notifier/codex-context.js +0 -161
- package/dist/features/codex-notifier/codex-context.js.map +0 -1
- package/dist/features/codex-notifier/config.d.ts +0 -9
- package/dist/features/codex-notifier/config.d.ts.map +0 -1
- package/dist/features/codex-notifier/config.js +0 -11
- package/dist/features/codex-notifier/config.js.map +0 -1
- package/dist/features/codex-notifier/confirmed-turn.d.ts +0 -20
- package/dist/features/codex-notifier/confirmed-turn.d.ts.map +0 -1
- package/dist/features/codex-notifier/confirmed-turn.js +0 -130
- package/dist/features/codex-notifier/confirmed-turn.js.map +0 -1
- package/dist/features/codex-notifier/emitter.d.ts +0 -13
- package/dist/features/codex-notifier/emitter.d.ts.map +0 -1
- package/dist/features/codex-notifier/emitter.js +0 -33
- package/dist/features/codex-notifier/emitter.js.map +0 -1
- package/dist/features/codex-notifier/event-store.d.ts +0 -29
- package/dist/features/codex-notifier/event-store.d.ts.map +0 -1
- package/dist/features/codex-notifier/event-store.js +0 -217
- package/dist/features/codex-notifier/event-store.js.map +0 -1
- package/dist/features/codex-notifier/event.d.ts +0 -46
- package/dist/features/codex-notifier/event.d.ts.map +0 -1
- package/dist/features/codex-notifier/event.js +0 -188
- package/dist/features/codex-notifier/event.js.map +0 -1
- package/dist/features/codex-notifier/hook-cli.d.ts +0 -23
- package/dist/features/codex-notifier/hook-cli.d.ts.map +0 -1
- package/dist/features/codex-notifier/hook-cli.js +0 -130
- package/dist/features/codex-notifier/hook-cli.js.map +0 -1
- package/dist/features/codex-notifier/hook-installer.d.ts +0 -19
- package/dist/features/codex-notifier/hook-installer.d.ts.map +0 -1
- package/dist/features/codex-notifier/hook-installer.js +0 -158
- package/dist/features/codex-notifier/hook-installer.js.map +0 -1
- package/dist/features/codex-notifier/index.d.ts +0 -21
- package/dist/features/codex-notifier/index.d.ts.map +0 -1
- package/dist/features/codex-notifier/index.js +0 -19
- package/dist/features/codex-notifier/index.js.map +0 -1
- package/dist/features/codex-notifier/internal-turn.d.ts +0 -5
- package/dist/features/codex-notifier/internal-turn.d.ts.map +0 -1
- package/dist/features/codex-notifier/internal-turn.js +0 -43
- package/dist/features/codex-notifier/internal-turn.js.map +0 -1
- package/dist/features/codex-notifier/outbox-worker.d.ts +0 -71
- package/dist/features/codex-notifier/outbox-worker.d.ts.map +0 -1
- package/dist/features/codex-notifier/outbox-worker.js +0 -290
- package/dist/features/codex-notifier/outbox-worker.js.map +0 -1
- package/dist/features/codex-notifier/outbox.d.ts +0 -25
- package/dist/features/codex-notifier/outbox.d.ts.map +0 -1
- package/dist/features/codex-notifier/outbox.js +0 -225
- package/dist/features/codex-notifier/outbox.js.map +0 -1
- package/dist/features/codex-notifier/paths.d.ts +0 -7
- package/dist/features/codex-notifier/paths.d.ts.map +0 -1
- package/dist/features/codex-notifier/paths.js +0 -20
- package/dist/features/codex-notifier/paths.js.map +0 -1
- package/dist/features/codex-notifier/screen-lock.d.ts +0 -12
- package/dist/features/codex-notifier/screen-lock.d.ts.map +0 -1
- package/dist/features/codex-notifier/screen-lock.js +0 -47
- package/dist/features/codex-notifier/screen-lock.js.map +0 -1
- package/dist/features/codex-notifier/side-conversation-monitor.d.ts +0 -102
- package/dist/features/codex-notifier/side-conversation-monitor.d.ts.map +0 -1
- package/dist/features/codex-notifier/side-conversation-monitor.js +0 -774
- package/dist/features/codex-notifier/side-conversation-monitor.js.map +0 -1
- package/dist/features/codex-notifier/types.d.ts +0 -42
- package/dist/features/codex-notifier/types.d.ts.map +0 -1
- package/dist/features/codex-notifier/types.js +0 -2
- package/dist/features/codex-notifier/types.js.map +0 -1
- package/dist/features/codex-notifier/worker-lock.d.ts +0 -8
- package/dist/features/codex-notifier/worker-lock.d.ts.map +0 -1
- package/dist/features/codex-notifier/worker-lock.js +0 -108
- package/dist/features/codex-notifier/worker-lock.js.map +0 -1
- package/dist/global-config.d.ts +0 -264
- package/dist/global-config.d.ts.map +0 -1
- package/dist/global-config.js +0 -504
- package/dist/global-config.js.map +0 -1
- package/dist/i18n/en.d.ts +0 -3
- package/dist/i18n/en.d.ts.map +0 -1
- package/dist/i18n/en.js +0 -1211
- package/dist/i18n/en.js.map +0 -1
- package/dist/i18n/index.d.ts +0 -33
- package/dist/i18n/index.d.ts.map +0 -1
- package/dist/i18n/index.js +0 -74
- package/dist/i18n/index.js.map +0 -1
- package/dist/i18n/types.d.ts +0 -4
- package/dist/i18n/types.d.ts.map +0 -1
- package/dist/i18n/types.js +0 -5
- package/dist/i18n/types.js.map +0 -1
- package/dist/i18n/zh.d.ts +0 -6
- package/dist/i18n/zh.d.ts.map +0 -1
- package/dist/i18n/zh.js +0 -1212
- package/dist/i18n/zh.js.map +0 -1
- package/dist/im/lark/ask-card.d.ts +0 -55
- package/dist/im/lark/ask-card.d.ts.map +0 -1
- package/dist/im/lark/ask-card.js +0 -392
- package/dist/im/lark/ask-card.js.map +0 -1
- package/dist/im/lark/brand-template.d.ts +0 -15
- package/dist/im/lark/brand-template.d.ts.map +0 -1
- package/dist/im/lark/brand-template.js +0 -114
- package/dist/im/lark/brand-template.js.map +0 -1
- package/dist/im/lark/callback-button-marker.d.ts +0 -34
- package/dist/im/lark/callback-button-marker.d.ts.map +0 -1
- package/dist/im/lark/callback-button-marker.js +0 -99
- package/dist/im/lark/callback-button-marker.js.map +0 -1
- package/dist/im/lark/card-builder.d.ts +0 -367
- package/dist/im/lark/card-builder.d.ts.map +0 -1
- package/dist/im/lark/card-builder.js +0 -2238
- package/dist/im/lark/card-builder.js.map +0 -1
- package/dist/im/lark/card-handler.d.ts +0 -158
- package/dist/im/lark/card-handler.d.ts.map +0 -1
- package/dist/im/lark/card-handler.js +0 -2923
- package/dist/im/lark/card-handler.js.map +0 -1
- package/dist/im/lark/client.d.ts +0 -471
- package/dist/im/lark/client.d.ts.map +0 -1
- package/dist/im/lark/client.js +0 -1943
- package/dist/im/lark/client.js.map +0 -1
- package/dist/im/lark/doc-comment.d.ts +0 -164
- package/dist/im/lark/doc-comment.d.ts.map +0 -1
- package/dist/im/lark/doc-comment.js +0 -611
- package/dist/im/lark/doc-comment.js.map +0 -1
- package/dist/im/lark/event-dispatcher.d.ts +0 -420
- package/dist/im/lark/event-dispatcher.d.ts.map +0 -1
- package/dist/im/lark/event-dispatcher.js +0 -3274
- package/dist/im/lark/event-dispatcher.js.map +0 -1
- package/dist/im/lark/forward-followup-buffer.d.ts +0 -26
- package/dist/im/lark/forward-followup-buffer.d.ts.map +0 -1
- package/dist/im/lark/forward-followup-buffer.js +0 -48
- package/dist/im/lark/forward-followup-buffer.js.map +0 -1
- package/dist/im/lark/forward-followup-content.d.ts +0 -6
- package/dist/im/lark/forward-followup-content.d.ts.map +0 -1
- package/dist/im/lark/forward-followup-content.js +0 -46
- package/dist/im/lark/forward-followup-content.js.map +0 -1
- package/dist/im/lark/forward-followup-store.d.ts +0 -9
- package/dist/im/lark/forward-followup-store.d.ts.map +0 -1
- package/dist/im/lark/forward-followup-store.js +0 -48
- package/dist/im/lark/forward-followup-store.js.map +0 -1
- package/dist/im/lark/forwarded-renderer.d.ts +0 -23
- package/dist/im/lark/forwarded-renderer.d.ts.map +0 -1
- package/dist/im/lark/forwarded-renderer.js +0 -112
- package/dist/im/lark/forwarded-renderer.js.map +0 -1
- package/dist/im/lark/grant-command.d.ts +0 -51
- package/dist/im/lark/grant-command.d.ts.map +0 -1
- package/dist/im/lark/grant-command.js +0 -215
- package/dist/im/lark/grant-command.js.map +0 -1
- package/dist/im/lark/grant-pending.d.ts +0 -31
- package/dist/im/lark/grant-pending.d.ts.map +0 -1
- package/dist/im/lark/grant-pending.js +0 -122
- package/dist/im/lark/grant-pending.js.map +0 -1
- package/dist/im/lark/groups-card.d.ts +0 -90
- package/dist/im/lark/groups-card.d.ts.map +0 -1
- package/dist/im/lark/groups-card.js +0 -832
- package/dist/im/lark/groups-card.js.map +0 -1
- package/dist/im/lark/identity-cache.d.ts +0 -88
- package/dist/im/lark/identity-cache.d.ts.map +0 -1
- package/dist/im/lark/identity-cache.js +0 -310
- package/dist/im/lark/identity-cache.js.map +0 -1
- package/dist/im/lark/inline-mentions.d.ts +0 -42
- package/dist/im/lark/inline-mentions.d.ts.map +0 -1
- package/dist/im/lark/inline-mentions.js +0 -27
- package/dist/im/lark/inline-mentions.js.map +0 -1
- package/dist/im/lark/invite-command.d.ts +0 -20
- package/dist/im/lark/invite-command.d.ts.map +0 -1
- package/dist/im/lark/invite-command.js +0 -292
- package/dist/im/lark/invite-command.js.map +0 -1
- package/dist/im/lark/issue-card.d.ts +0 -223
- package/dist/im/lark/issue-card.d.ts.map +0 -1
- package/dist/im/lark/issue-card.js +0 -542
- package/dist/im/lark/issue-card.js.map +0 -1
- package/dist/im/lark/issue-command-deps.d.ts +0 -41
- package/dist/im/lark/issue-command-deps.d.ts.map +0 -1
- package/dist/im/lark/issue-command-deps.js +0 -195
- package/dist/im/lark/issue-command-deps.js.map +0 -1
- package/dist/im/lark/issue-command.d.ts +0 -137
- package/dist/im/lark/issue-command.d.ts.map +0 -1
- package/dist/im/lark/issue-command.js +0 -335
- package/dist/im/lark/issue-command.js.map +0 -1
- package/dist/im/lark/lark-hosts.d.ts +0 -49
- package/dist/im/lark/lark-hosts.d.ts.map +0 -1
- package/dist/im/lark/lark-hosts.js +0 -59
- package/dist/im/lark/lark-hosts.js.map +0 -1
- package/dist/im/lark/md-card.d.ts +0 -192
- package/dist/im/lark/md-card.d.ts.map +0 -1
- package/dist/im/lark/md-card.js +0 -872
- package/dist/im/lark/md-card.js.map +0 -1
- package/dist/im/lark/mention-targets.d.ts +0 -43
- package/dist/im/lark/mention-targets.d.ts.map +0 -1
- package/dist/im/lark/mention-targets.js +0 -190
- package/dist/im/lark/mention-targets.js.map +0 -1
- package/dist/im/lark/merge-forward.d.ts +0 -32
- package/dist/im/lark/merge-forward.d.ts.map +0 -1
- package/dist/im/lark/merge-forward.js +0 -140
- package/dist/im/lark/merge-forward.js.map +0 -1
- package/dist/im/lark/message-parser.d.ts +0 -272
- package/dist/im/lark/message-parser.d.ts.map +0 -1
- package/dist/im/lark/message-parser.js +0 -1261
- package/dist/im/lark/message-parser.js.map +0 -1
- package/dist/im/lark/overload-nonce.d.ts +0 -19
- package/dist/im/lark/overload-nonce.d.ts.map +0 -1
- package/dist/im/lark/overload-nonce.js +0 -72
- package/dist/im/lark/overload-nonce.js.map +0 -1
- package/dist/im/lark/overview-card.d.ts +0 -100
- package/dist/im/lark/overview-card.d.ts.map +0 -1
- package/dist/im/lark/overview-card.js +0 -428
- package/dist/im/lark/overview-card.js.map +0 -1
- package/dist/im/lark/quote-hint.d.ts +0 -19
- package/dist/im/lark/quote-hint.d.ts.map +0 -1
- package/dist/im/lark/quote-hint.js +0 -24
- package/dist/im/lark/quote-hint.js.map +0 -1
- package/dist/im/lark/relay-target-routing.d.ts +0 -17
- package/dist/im/lark/relay-target-routing.d.ts.map +0 -1
- package/dist/im/lark/relay-target-routing.js +0 -74
- package/dist/im/lark/relay-target-routing.js.map +0 -1
- package/dist/im/lark/reply-card-footer-signature.d.ts +0 -7
- package/dist/im/lark/reply-card-footer-signature.d.ts.map +0 -1
- package/dist/im/lark/reply-card-footer-signature.js +0 -7
- package/dist/im/lark/reply-card-footer-signature.js.map +0 -1
- package/dist/im/lark/reply-mode-command.d.ts +0 -2
- package/dist/im/lark/reply-mode-command.d.ts.map +0 -1
- package/dist/im/lark/reply-mode-command.js +0 -108
- package/dist/im/lark/reply-mode-command.js.map +0 -1
- package/dist/im/lark/schedules-card.d.ts +0 -96
- package/dist/im/lark/schedules-card.d.ts.map +0 -1
- package/dist/im/lark/schedules-card.js +0 -910
- package/dist/im/lark/schedules-card.js.map +0 -1
- package/dist/im/lark/sessions-card.d.ts +0 -117
- package/dist/im/lark/sessions-card.d.ts.map +0 -1
- package/dist/im/lark/sessions-card.js +0 -876
- package/dist/im/lark/sessions-card.js.map +0 -1
- package/dist/im/lark/settings-card.d.ts +0 -125
- package/dist/im/lark/settings-card.d.ts.map +0 -1
- package/dist/im/lark/settings-card.js +0 -434
- package/dist/im/lark/settings-card.js.map +0 -1
- package/dist/im/lark/substitute-command.d.ts +0 -2
- package/dist/im/lark/substitute-command.d.ts.map +0 -1
- package/dist/im/lark/substitute-command.js +0 -68
- package/dist/im/lark/substitute-command.js.map +0 -1
- package/dist/im/lark/summary-command.d.ts +0 -21
- package/dist/im/lark/summary-command.d.ts.map +0 -1
- package/dist/im/lark/summary-command.js +0 -335
- package/dist/im/lark/summary-command.js.map +0 -1
- package/dist/im/lark/topic-root-context.d.ts +0 -35
- package/dist/im/lark/topic-root-context.d.ts.map +0 -1
- package/dist/im/lark/topic-root-context.js +0 -37
- package/dist/im/lark/topic-root-context.js.map +0 -1
- package/dist/im/lark/v3-blocked-card-handler.d.ts +0 -28
- package/dist/im/lark/v3-blocked-card-handler.d.ts.map +0 -1
- package/dist/im/lark/v3-blocked-card-handler.js +0 -134
- package/dist/im/lark/v3-blocked-card-handler.js.map +0 -1
- package/dist/im/lark/v3-blocked-card.d.ts +0 -76
- package/dist/im/lark/v3-blocked-card.d.ts.map +0 -1
- package/dist/im/lark/v3-blocked-card.js +0 -224
- package/dist/im/lark/v3-blocked-card.js.map +0 -1
- package/dist/im/lark/v3-distillation-card-handler.d.ts +0 -12
- package/dist/im/lark/v3-distillation-card-handler.d.ts.map +0 -1
- package/dist/im/lark/v3-distillation-card-handler.js +0 -107
- package/dist/im/lark/v3-distillation-card-handler.js.map +0 -1
- package/dist/im/lark/v3-distillation-card.d.ts +0 -42
- package/dist/im/lark/v3-distillation-card.d.ts.map +0 -1
- package/dist/im/lark/v3-distillation-card.js +0 -206
- package/dist/im/lark/v3-distillation-card.js.map +0 -1
- package/dist/im/lark/v3-gate-card-handler.d.ts +0 -31
- package/dist/im/lark/v3-gate-card-handler.d.ts.map +0 -1
- package/dist/im/lark/v3-gate-card-handler.js +0 -111
- package/dist/im/lark/v3-gate-card-handler.js.map +0 -1
- package/dist/im/lark/v3-gate-card.d.ts +0 -56
- package/dist/im/lark/v3-gate-card.d.ts.map +0 -1
- package/dist/im/lark/v3-gate-card.js +0 -153
- package/dist/im/lark/v3-gate-card.js.map +0 -1
- package/dist/im/lark/v3-loop-grant-card-handler.d.ts +0 -28
- package/dist/im/lark/v3-loop-grant-card-handler.d.ts.map +0 -1
- package/dist/im/lark/v3-loop-grant-card-handler.js +0 -89
- package/dist/im/lark/v3-loop-grant-card-handler.js.map +0 -1
- package/dist/im/lark/v3-loop-grant-card.d.ts +0 -46
- package/dist/im/lark/v3-loop-grant-card.d.ts.map +0 -1
- package/dist/im/lark/v3-loop-grant-card.js +0 -120
- package/dist/im/lark/v3-loop-grant-card.js.map +0 -1
- package/dist/im/lark/v3-progress-card-manager.d.ts +0 -79
- package/dist/im/lark/v3-progress-card-manager.d.ts.map +0 -1
- package/dist/im/lark/v3-progress-card-manager.js +0 -444
- package/dist/im/lark/v3-progress-card-manager.js.map +0 -1
- package/dist/im/lark/v3-progress-card.d.ts +0 -26
- package/dist/im/lark/v3-progress-card.d.ts.map +0 -1
- package/dist/im/lark/v3-progress-card.js +0 -217
- package/dist/im/lark/v3-progress-card.js.map +0 -1
- package/dist/im/lark/v3-revisit-grant-card-handler.d.ts +0 -29
- package/dist/im/lark/v3-revisit-grant-card-handler.d.ts.map +0 -1
- package/dist/im/lark/v3-revisit-grant-card-handler.js +0 -95
- package/dist/im/lark/v3-revisit-grant-card-handler.js.map +0 -1
- package/dist/im/lark/v3-revisit-grant-card.d.ts +0 -52
- package/dist/im/lark/v3-revisit-grant-card.d.ts.map +0 -1
- package/dist/im/lark/v3-revisit-grant-card.js +0 -124
- package/dist/im/lark/v3-revisit-grant-card.js.map +0 -1
- package/dist/im/lark/v3-run-save-card-handler.d.ts +0 -12
- package/dist/im/lark/v3-run-save-card-handler.d.ts.map +0 -1
- package/dist/im/lark/v3-run-save-card-handler.js +0 -160
- package/dist/im/lark/v3-run-save-card-handler.js.map +0 -1
- package/dist/im/lark/v3-run-save-card.d.ts +0 -38
- package/dist/im/lark/v3-run-save-card.d.ts.map +0 -1
- package/dist/im/lark/v3-run-save-card.js +0 -125
- package/dist/im/lark/v3-run-save-card.js.map +0 -1
- package/dist/im/lark/v3-saved-workflow-command.d.ts +0 -36
- package/dist/im/lark/v3-saved-workflow-command.d.ts.map +0 -1
- package/dist/im/lark/v3-saved-workflow-command.js +0 -186
- package/dist/im/lark/v3-saved-workflow-command.js.map +0 -1
- package/dist/im/lark/v3-saved-workflow-handler.d.ts +0 -89
- package/dist/im/lark/v3-saved-workflow-handler.d.ts.map +0 -1
- package/dist/im/lark/v3-saved-workflow-handler.js +0 -212
- package/dist/im/lark/v3-saved-workflow-handler.js.map +0 -1
- package/dist/im/lark/workflow-slash-command.d.ts +0 -18
- package/dist/im/lark/workflow-slash-command.d.ts.map +0 -1
- package/dist/im/lark/workflow-slash-command.js +0 -36
- package/dist/im/lark/workflow-slash-command.js.map +0 -1
- package/dist/im/types.d.ts +0 -79
- package/dist/im/types.d.ts.map +0 -1
- package/dist/im/types.js +0 -2
- package/dist/im/types.js.map +0 -1
- package/dist/index-core-only.d.ts +0 -3
- package/dist/index-core-only.d.ts.map +0 -1
- package/dist/index-core-only.js +0 -118
- package/dist/index-core-only.js.map +0 -1
- package/dist/index-daemon.d.ts +0 -3
- package/dist/index-daemon.d.ts.map +0 -1
- package/dist/index-daemon.js +0 -64
- package/dist/index-daemon.js.map +0 -1
- package/dist/mir-local-runtime.d.ts +0 -60
- package/dist/mir-local-runtime.d.ts.map +0 -1
- package/dist/mir-local-runtime.js +0 -362
- package/dist/mir-local-runtime.js.map +0 -1
- package/dist/mir-prompt.d.ts +0 -16
- package/dist/mir-prompt.d.ts.map +0 -1
- package/dist/mir-prompt.js +0 -170
- package/dist/mir-prompt.js.map +0 -1
- package/dist/mir-runner.d.ts +0 -3
- package/dist/mir-runner.d.ts.map +0 -1
- package/dist/mir-runner.js +0 -369
- package/dist/mir-runner.js.map +0 -1
- package/dist/mira-output.d.ts +0 -3
- package/dist/mira-output.d.ts.map +0 -1
- package/dist/mira-output.js +0 -136
- package/dist/mira-output.js.map +0 -1
- package/dist/mira-runner.d.ts +0 -3
- package/dist/mira-runner.d.ts.map +0 -1
- package/dist/mira-runner.js +0 -530
- package/dist/mira-runner.js.map +0 -1
- package/dist/platform/bind.d.ts +0 -5
- package/dist/platform/bind.d.ts.map +0 -1
- package/dist/platform/bind.js +0 -157
- package/dist/platform/bind.js.map +0 -1
- package/dist/platform/binding.d.ts +0 -47
- package/dist/platform/binding.d.ts.map +0 -1
- package/dist/platform/binding.js +0 -84
- package/dist/platform/binding.js.map +0 -1
- package/dist/platform/device-command.d.ts +0 -35
- package/dist/platform/device-command.d.ts.map +0 -1
- package/dist/platform/device-command.js +0 -187
- package/dist/platform/device-command.js.map +0 -1
- package/dist/platform/device-enroll.d.ts +0 -156
- package/dist/platform/device-enroll.d.ts.map +0 -1
- package/dist/platform/device-enroll.js +0 -781
- package/dist/platform/device-enroll.js.map +0 -1
- package/dist/platform/device-isolation-activation-client.d.ts +0 -28
- package/dist/platform/device-isolation-activation-client.d.ts.map +0 -1
- package/dist/platform/device-isolation-activation-client.js +0 -279
- package/dist/platform/device-isolation-activation-client.js.map +0 -1
- package/dist/platform/device-isolation.d.ts +0 -35
- package/dist/platform/device-isolation.d.ts.map +0 -1
- package/dist/platform/device-isolation.js +0 -90
- package/dist/platform/device-isolation.js.map +0 -1
- package/dist/platform/device-paths.d.ts +0 -9
- package/dist/platform/device-paths.d.ts.map +0 -1
- package/dist/platform/device-paths.js +0 -14
- package/dist/platform/device-paths.js.map +0 -1
- package/dist/platform/device.d.ts +0 -77
- package/dist/platform/device.d.ts.map +0 -1
- package/dist/platform/device.js +0 -212
- package/dist/platform/device.js.map +0 -1
- package/dist/platform/host-command-context.d.ts +0 -15
- package/dist/platform/host-command-context.d.ts.map +0 -1
- package/dist/platform/host-command-context.js +0 -26
- package/dist/platform/host-command-context.js.map +0 -1
- package/dist/platform/issue-client.d.ts +0 -201
- package/dist/platform/issue-client.d.ts.map +0 -1
- package/dist/platform/issue-client.js +0 -142
- package/dist/platform/issue-client.js.map +0 -1
- package/dist/platform/platform-http.d.ts +0 -15
- package/dist/platform/platform-http.d.ts.map +0 -1
- package/dist/platform/platform-http.js +0 -77
- package/dist/platform/platform-http.js.map +0 -1
- package/dist/platform/secure-host-file.d.ts +0 -12
- package/dist/platform/secure-host-file.d.ts.map +0 -1
- package/dist/platform/secure-host-file.js +0 -301
- package/dist/platform/secure-host-file.js.map +0 -1
- package/dist/platform/tunnel-client.d.ts +0 -41
- package/dist/platform/tunnel-client.d.ts.map +0 -1
- package/dist/platform/tunnel-client.js +0 -493
- package/dist/platform/tunnel-client.js.map +0 -1
- package/dist/pm2-graceful-exit.d.ts +0 -28
- package/dist/pm2-graceful-exit.d.ts.map +0 -1
- package/dist/pm2-graceful-exit.js +0 -39
- package/dist/pm2-graceful-exit.js.map +0 -1
- package/dist/services/adopt-picker.d.ts +0 -41
- package/dist/services/adopt-picker.d.ts.map +0 -1
- package/dist/services/adopt-picker.js +0 -70
- package/dist/services/adopt-picker.js.map +0 -1
- package/dist/services/aiden-checkpoints.d.ts +0 -5
- package/dist/services/aiden-checkpoints.d.ts.map +0 -1
- package/dist/services/aiden-checkpoints.js +0 -91
- package/dist/services/aiden-checkpoints.js.map +0 -1
- package/dist/services/allowed-chat-groups.d.ts +0 -11
- package/dist/services/allowed-chat-groups.d.ts.map +0 -1
- package/dist/services/allowed-chat-groups.js +0 -20
- package/dist/services/allowed-chat-groups.js.map +0 -1
- package/dist/services/async-trigger-state.d.ts +0 -90
- package/dist/services/async-trigger-state.d.ts.map +0 -1
- package/dist/services/async-trigger-state.js +0 -96
- package/dist/services/async-trigger-state.js.map +0 -1
- package/dist/services/async-trigger-store.d.ts +0 -36
- package/dist/services/async-trigger-store.d.ts.map +0 -1
- package/dist/services/async-trigger-store.js +0 -121
- package/dist/services/async-trigger-store.js.map +0 -1
- package/dist/services/backend-availability.d.ts +0 -29
- package/dist/services/backend-availability.d.ts.map +0 -1
- package/dist/services/backend-availability.js +0 -55
- package/dist/services/backend-availability.js.map +0 -1
- package/dist/services/backend-type-store.d.ts +0 -33
- package/dist/services/backend-type-store.d.ts.map +0 -1
- package/dist/services/backend-type-store.js +0 -43
- package/dist/services/backend-type-store.js.map +0 -1
- package/dist/services/bot-config-store.d.ts +0 -155
- package/dist/services/bot-config-store.d.ts.map +0 -1
- package/dist/services/bot-config-store.js +0 -384
- package/dist/services/bot-config-store.js.map +0 -1
- package/dist/services/bot-owner-store.d.ts +0 -28
- package/dist/services/bot-owner-store.d.ts.map +0 -1
- package/dist/services/bot-owner-store.js +0 -82
- package/dist/services/bot-owner-store.js.map +0 -1
- package/dist/services/bot-profile-store.d.ts +0 -16
- package/dist/services/bot-profile-store.d.ts.map +0 -1
- package/dist/services/bot-profile-store.js +0 -98
- package/dist/services/bot-profile-store.js.map +0 -1
- package/dist/services/bot-union-ids-store.d.ts +0 -24
- package/dist/services/bot-union-ids-store.d.ts.map +0 -1
- package/dist/services/bot-union-ids-store.js +0 -79
- package/dist/services/bot-union-ids-store.js.map +0 -1
- package/dist/services/brand-store.d.ts +0 -15
- package/dist/services/brand-store.d.ts.map +0 -1
- package/dist/services/brand-store.js +0 -47
- package/dist/services/brand-store.js.map +0 -1
- package/dist/services/bridge-fallback-gate.d.ts +0 -72
- package/dist/services/bridge-fallback-gate.d.ts.map +0 -1
- package/dist/services/bridge-fallback-gate.js +0 -190
- package/dist/services/bridge-fallback-gate.js.map +0 -1
- package/dist/services/bridge-rotation-policy.d.ts +0 -179
- package/dist/services/bridge-rotation-policy.d.ts.map +0 -1
- package/dist/services/bridge-rotation-policy.js +0 -163
- package/dist/services/bridge-rotation-policy.js.map +0 -1
- package/dist/services/bridge-turn-queue.d.ts +0 -198
- package/dist/services/bridge-turn-queue.d.ts.map +0 -1
- package/dist/services/bridge-turn-queue.js +0 -430
- package/dist/services/bridge-turn-queue.js.map +0 -1
- package/dist/services/card-mode-store.d.ts +0 -13
- package/dist/services/card-mode-store.d.ts.map +0 -1
- package/dist/services/card-mode-store.js +0 -52
- package/dist/services/card-mode-store.js.map +0 -1
- package/dist/services/card-prefs-store.d.ts +0 -55
- package/dist/services/card-prefs-store.d.ts.map +0 -1
- package/dist/services/card-prefs-store.js +0 -269
- package/dist/services/card-prefs-store.js.map +0 -1
- package/dist/services/chat-first-seen-store.d.ts +0 -27
- package/dist/services/chat-first-seen-store.d.ts.map +0 -1
- package/dist/services/chat-first-seen-store.js +0 -114
- package/dist/services/chat-first-seen-store.js.map +0 -1
- package/dist/services/chat-reply-mode-store.d.ts +0 -30
- package/dist/services/chat-reply-mode-store.d.ts.map +0 -1
- package/dist/services/chat-reply-mode-store.js +0 -135
- package/dist/services/chat-reply-mode-store.js.map +0 -1
- package/dist/services/claude-transcript.d.ts +0 -323
- package/dist/services/claude-transcript.d.ts.map +0 -1
- package/dist/services/claude-transcript.js +0 -930
- package/dist/services/claude-transcript.js.map +0 -1
- package/dist/services/coco-paths.d.ts +0 -10
- package/dist/services/coco-paths.d.ts.map +0 -1
- package/dist/services/coco-paths.js +0 -16
- package/dist/services/coco-paths.js.map +0 -1
- package/dist/services/coco-transcript.d.ts +0 -35
- package/dist/services/coco-transcript.d.ts.map +0 -1
- package/dist/services/coco-transcript.js +0 -183
- package/dist/services/coco-transcript.js.map +0 -1
- package/dist/services/codex-app-runner-protocol.d.ts +0 -70
- package/dist/services/codex-app-runner-protocol.d.ts.map +0 -1
- package/dist/services/codex-app-runner-protocol.js +0 -187
- package/dist/services/codex-app-runner-protocol.js.map +0 -1
- package/dist/services/codex-app-threads.d.ts +0 -67
- package/dist/services/codex-app-threads.d.ts.map +0 -1
- package/dist/services/codex-app-threads.js +0 -657
- package/dist/services/codex-app-threads.js.map +0 -1
- package/dist/services/codex-app-token-usage.d.ts +0 -93
- package/dist/services/codex-app-token-usage.d.ts.map +0 -1
- package/dist/services/codex-app-token-usage.js +0 -190
- package/dist/services/codex-app-token-usage.js.map +0 -1
- package/dist/services/codex-app-turn-controller.d.ts +0 -72
- package/dist/services/codex-app-turn-controller.d.ts.map +0 -1
- package/dist/services/codex-app-turn-controller.js +0 -524
- package/dist/services/codex-app-turn-controller.js.map +0 -1
- package/dist/services/codex-bridge-queue.d.ts +0 -73
- package/dist/services/codex-bridge-queue.d.ts.map +0 -1
- package/dist/services/codex-bridge-queue.js +0 -273
- package/dist/services/codex-bridge-queue.js.map +0 -1
- package/dist/services/codex-composer-state.d.ts +0 -27
- package/dist/services/codex-composer-state.d.ts.map +0 -1
- package/dist/services/codex-composer-state.js +0 -53
- package/dist/services/codex-composer-state.js.map +0 -1
- package/dist/services/codex-paths.d.ts +0 -7
- package/dist/services/codex-paths.d.ts.map +0 -1
- package/dist/services/codex-paths.js +0 -19
- package/dist/services/codex-paths.js.map +0 -1
- package/dist/services/codex-runner-freshness.d.ts +0 -39
- package/dist/services/codex-runner-freshness.d.ts.map +0 -1
- package/dist/services/codex-runner-freshness.js +0 -78
- package/dist/services/codex-runner-freshness.js.map +0 -1
- package/dist/services/codex-service-tier.d.ts +0 -44
- package/dist/services/codex-service-tier.d.ts.map +0 -1
- package/dist/services/codex-service-tier.js +0 -63
- package/dist/services/codex-service-tier.js.map +0 -1
- package/dist/services/codex-transcript.d.ts +0 -140
- package/dist/services/codex-transcript.d.ts.map +0 -1
- package/dist/services/codex-transcript.js +0 -631
- package/dist/services/codex-transcript.js.map +0 -1
- package/dist/services/config-store.d.ts +0 -19
- package/dist/services/config-store.d.ts.map +0 -1
- package/dist/services/config-store.js +0 -52
- package/dist/services/config-store.js.map +0 -1
- package/dist/services/connector-store.d.ts +0 -71
- package/dist/services/connector-store.d.ts.map +0 -1
- package/dist/services/connector-store.js +0 -79
- package/dist/services/connector-store.js.map +0 -1
- package/dist/services/cursor-resume-policy.d.ts +0 -12
- package/dist/services/cursor-resume-policy.d.ts.map +0 -1
- package/dist/services/cursor-resume-policy.js +0 -15
- package/dist/services/cursor-resume-policy.js.map +0 -1
- package/dist/services/cursor-transcript.d.ts +0 -47
- package/dist/services/cursor-transcript.d.ts.map +0 -1
- package/dist/services/cursor-transcript.js +0 -324
- package/dist/services/cursor-transcript.js.map +0 -1
- package/dist/services/default-worktree.d.ts +0 -28
- package/dist/services/default-worktree.d.ts.map +0 -1
- package/dist/services/default-worktree.js +0 -102
- package/dist/services/default-worktree.js.map +0 -1
- package/dist/services/deployment-identity.d.ts +0 -22
- package/dist/services/deployment-identity.d.ts.map +0 -1
- package/dist/services/deployment-identity.js +0 -67
- package/dist/services/deployment-identity.js.map +0 -1
- package/dist/services/doc-subs-store.d.ts +0 -63
- package/dist/services/doc-subs-store.d.ts.map +0 -1
- package/dist/services/doc-subs-store.js +0 -95
- package/dist/services/doc-subs-store.js.map +0 -1
- package/dist/services/exact-chat-grant.d.ts +0 -83
- package/dist/services/exact-chat-grant.d.ts.map +0 -1
- package/dist/services/exact-chat-grant.js +0 -249
- package/dist/services/exact-chat-grant.js.map +0 -1
- package/dist/services/federation-membership-store.d.ts +0 -23
- package/dist/services/federation-membership-store.d.ts.map +0 -1
- package/dist/services/federation-membership-store.js +0 -66
- package/dist/services/federation-membership-store.js.map +0 -1
- package/dist/services/federation-roster.d.ts +0 -58
- package/dist/services/federation-roster.d.ts.map +0 -1
- package/dist/services/federation-roster.js +0 -59
- package/dist/services/federation-roster.js.map +0 -1
- package/dist/services/federation-store.d.ts +0 -87
- package/dist/services/federation-store.d.ts.map +0 -1
- package/dist/services/federation-store.js +0 -143
- package/dist/services/federation-store.js.map +0 -1
- package/dist/services/file-bridge-path.d.ts +0 -8
- package/dist/services/file-bridge-path.d.ts.map +0 -1
- package/dist/services/file-bridge-path.js +0 -75
- package/dist/services/file-bridge-path.js.map +0 -1
- package/dist/services/frozen-card-store.d.ts +0 -8
- package/dist/services/frozen-card-store.d.ts.map +0 -1
- package/dist/services/frozen-card-store.js +0 -66
- package/dist/services/frozen-card-store.js.map +0 -1
- package/dist/services/git-worktree.d.ts +0 -63
- package/dist/services/git-worktree.d.ts.map +0 -1
- package/dist/services/git-worktree.js +0 -246
- package/dist/services/git-worktree.js.map +0 -1
- package/dist/services/grant-policy.d.ts +0 -13
- package/dist/services/grant-policy.d.ts.map +0 -1
- package/dist/services/grant-policy.js +0 -40
- package/dist/services/grant-policy.js.map +0 -1
- package/dist/services/grant-prefs-store.d.ts +0 -26
- package/dist/services/grant-prefs-store.d.ts.map +0 -1
- package/dist/services/grant-prefs-store.js +0 -109
- package/dist/services/grant-prefs-store.js.map +0 -1
- package/dist/services/grant-store.d.ts +0 -103
- package/dist/services/grant-store.d.ts.map +0 -1
- package/dist/services/grant-store.js +0 -580
- package/dist/services/grant-store.js.map +0 -1
- package/dist/services/grok-paths.d.ts +0 -27
- package/dist/services/grok-paths.d.ts.map +0 -1
- package/dist/services/grok-paths.js +0 -106
- package/dist/services/grok-paths.js.map +0 -1
- package/dist/services/grok-transcript.d.ts +0 -68
- package/dist/services/grok-transcript.d.ts.map +0 -1
- package/dist/services/grok-transcript.js +0 -681
- package/dist/services/grok-transcript.js.map +0 -1
- package/dist/services/group-creator.d.ts +0 -87
- package/dist/services/group-creator.d.ts.map +0 -1
- package/dist/services/group-creator.js +0 -288
- package/dist/services/group-creator.js.map +0 -1
- package/dist/services/groups-store.d.ts +0 -194
- package/dist/services/groups-store.d.ts.map +0 -1
- package/dist/services/groups-store.js +0 -493
- package/dist/services/groups-store.js.map +0 -1
- package/dist/services/hermes-session-filter.d.ts +0 -28
- package/dist/services/hermes-session-filter.d.ts.map +0 -1
- package/dist/services/hermes-session-filter.js +0 -53
- package/dist/services/hermes-session-filter.js.map +0 -1
- package/dist/services/hermes-transcript.d.ts +0 -11
- package/dist/services/hermes-transcript.d.ts.map +0 -1
- package/dist/services/hermes-transcript.js +0 -184
- package/dist/services/hermes-transcript.js.map +0 -1
- package/dist/services/hook-runner.d.ts +0 -53
- package/dist/services/hook-runner.d.ts.map +0 -1
- package/dist/services/hook-runner.js +0 -451
- package/dist/services/hook-runner.js.map +0 -1
- package/dist/services/insight/antigravity-span-reader.d.ts +0 -3
- package/dist/services/insight/antigravity-span-reader.d.ts.map +0 -1
- package/dist/services/insight/antigravity-span-reader.js +0 -249
- package/dist/services/insight/antigravity-span-reader.js.map +0 -1
- package/dist/services/insight/classify.d.ts +0 -9
- package/dist/services/insight/classify.d.ts.map +0 -1
- package/dist/services/insight/classify.js +0 -71
- package/dist/services/insight/classify.js.map +0 -1
- package/dist/services/insight/claude-span-reader.d.ts +0 -3
- package/dist/services/insight/claude-span-reader.d.ts.map +0 -1
- package/dist/services/insight/claude-span-reader.js +0 -276
- package/dist/services/insight/claude-span-reader.js.map +0 -1
- package/dist/services/insight/codex-span-reader.d.ts +0 -3
- package/dist/services/insight/codex-span-reader.d.ts.map +0 -1
- package/dist/services/insight/codex-span-reader.js +0 -306
- package/dist/services/insight/codex-span-reader.js.map +0 -1
- package/dist/services/insight/intent.d.ts +0 -5
- package/dist/services/insight/intent.d.ts.map +0 -1
- package/dist/services/insight/intent.js +0 -145
- package/dist/services/insight/intent.js.map +0 -1
- package/dist/services/insight/jsonl.d.ts +0 -10
- package/dist/services/insight/jsonl.d.ts.map +0 -1
- package/dist/services/insight/jsonl.js +0 -36
- package/dist/services/insight/jsonl.js.map +0 -1
- package/dist/services/insight/prompt.d.ts +0 -3
- package/dist/services/insight/prompt.d.ts.map +0 -1
- package/dist/services/insight/prompt.js +0 -99
- package/dist/services/insight/prompt.js.map +0 -1
- package/dist/services/insight/redact.d.ts +0 -4
- package/dist/services/insight/redact.d.ts.map +0 -1
- package/dist/services/insight/redact.js +0 -67
- package/dist/services/insight/redact.js.map +0 -1
- package/dist/services/insight/report.d.ts +0 -29
- package/dist/services/insight/report.d.ts.map +0 -1
- package/dist/services/insight/report.js +0 -1247
- package/dist/services/insight/report.js.map +0 -1
- package/dist/services/insight/safe-detail.d.ts +0 -5
- package/dist/services/insight/safe-detail.d.ts.map +0 -1
- package/dist/services/insight/safe-detail.js +0 -59
- package/dist/services/insight/safe-detail.js.map +0 -1
- package/dist/services/insight/scrub.d.ts +0 -22
- package/dist/services/insight/scrub.d.ts.map +0 -1
- package/dist/services/insight/scrub.js +0 -70
- package/dist/services/insight/scrub.js.map +0 -1
- package/dist/services/insight/subagent-reader.d.ts +0 -19
- package/dist/services/insight/subagent-reader.d.ts.map +0 -1
- package/dist/services/insight/subagent-reader.js +0 -111
- package/dist/services/insight/subagent-reader.js.map +0 -1
- package/dist/services/insight/types.d.ts +0 -448
- package/dist/services/insight/types.d.ts.map +0 -1
- package/dist/services/insight/types.js +0 -2
- package/dist/services/insight/types.js.map +0 -1
- package/dist/services/invite-store.d.ts +0 -28
- package/dist/services/invite-store.d.ts.map +0 -1
- package/dist/services/invite-store.js +0 -85
- package/dist/services/invite-store.js.map +0 -1
- package/dist/services/issue-board-store.d.ts +0 -214
- package/dist/services/issue-board-store.d.ts.map +0 -1
- package/dist/services/issue-board-store.js +0 -472
- package/dist/services/issue-board-store.js.map +0 -1
- package/dist/services/issue-claim-flow.d.ts +0 -160
- package/dist/services/issue-claim-flow.d.ts.map +0 -1
- package/dist/services/issue-claim-flow.js +0 -222
- package/dist/services/issue-claim-flow.js.map +0 -1
- package/dist/services/issue-outbox-pump.d.ts +0 -25
- package/dist/services/issue-outbox-pump.d.ts.map +0 -1
- package/dist/services/issue-outbox-pump.js +0 -102
- package/dist/services/issue-outbox-pump.js.map +0 -1
- package/dist/services/issue-release.d.ts +0 -78
- package/dist/services/issue-release.d.ts.map +0 -1
- package/dist/services/issue-release.js +0 -89
- package/dist/services/issue-release.js.map +0 -1
- package/dist/services/issue-report.d.ts +0 -72
- package/dist/services/issue-report.d.ts.map +0 -1
- package/dist/services/issue-report.js +0 -84
- package/dist/services/issue-report.js.map +0 -1
- package/dist/services/issue-status-view.d.ts +0 -52
- package/dist/services/issue-status-view.d.ts.map +0 -1
- package/dist/services/issue-status-view.js +0 -42
- package/dist/services/issue-status-view.js.map +0 -1
- package/dist/services/issue-status-writer.d.ts +0 -98
- package/dist/services/issue-status-writer.d.ts.map +0 -1
- package/dist/services/issue-status-writer.js +0 -123
- package/dist/services/issue-status-writer.js.map +0 -1
- package/dist/services/jsonl-cursor.d.ts +0 -24
- package/dist/services/jsonl-cursor.d.ts.map +0 -1
- package/dist/services/jsonl-cursor.js +0 -110
- package/dist/services/jsonl-cursor.js.map +0 -1
- package/dist/services/kiro-session.d.ts +0 -2
- package/dist/services/kiro-session.d.ts.map +0 -1
- package/dist/services/kiro-session.js +0 -19
- package/dist/services/kiro-session.js.map +0 -1
- package/dist/services/local-cli-opener.d.ts +0 -65
- package/dist/services/local-cli-opener.d.ts.map +0 -1
- package/dist/services/local-cli-opener.js +0 -426
- package/dist/services/local-cli-opener.js.map +0 -1
- package/dist/services/message-listener-run-preview-store.d.ts +0 -43
- package/dist/services/message-listener-run-preview-store.d.ts.map +0 -1
- package/dist/services/message-listener-run-preview-store.js +0 -152
- package/dist/services/message-listener-run-preview-store.js.map +0 -1
- package/dist/services/message-listener-store.d.ts +0 -44
- package/dist/services/message-listener-store.d.ts.map +0 -1
- package/dist/services/message-listener-store.js +0 -179
- package/dist/services/message-listener-store.js.map +0 -1
- package/dist/services/message-listener.d.ts +0 -129
- package/dist/services/message-listener.d.ts.map +0 -1
- package/dist/services/message-listener.js +0 -441
- package/dist/services/message-listener.js.map +0 -1
- package/dist/services/message-queue.d.ts +0 -9
- package/dist/services/message-queue.d.ts.map +0 -1
- package/dist/services/message-queue.js +0 -79
- package/dist/services/message-queue.js.map +0 -1
- package/dist/services/mtr-transcript.d.ts +0 -14
- package/dist/services/mtr-transcript.d.ts.map +0 -1
- package/dist/services/mtr-transcript.js +0 -291
- package/dist/services/mtr-transcript.js.map +0 -1
- package/dist/services/observed-bots-store.d.ts +0 -33
- package/dist/services/observed-bots-store.d.ts.map +0 -1
- package/dist/services/observed-bots-store.js +0 -103
- package/dist/services/observed-bots-store.js.map +0 -1
- package/dist/services/oncall-store.d.ts +0 -140
- package/dist/services/oncall-store.d.ts.map +0 -1
- package/dist/services/oncall-store.js +0 -403
- package/dist/services/oncall-store.js.map +0 -1
- package/dist/services/open-platform-rename.d.ts +0 -73
- package/dist/services/open-platform-rename.d.ts.map +0 -1
- package/dist/services/open-platform-rename.js +0 -396
- package/dist/services/open-platform-rename.js.map +0 -1
- package/dist/services/opencode-paths.d.ts +0 -7
- package/dist/services/opencode-paths.d.ts.map +0 -1
- package/dist/services/opencode-paths.js +0 -18
- package/dist/services/opencode-paths.js.map +0 -1
- package/dist/services/overload-alert-migration.d.ts +0 -15
- package/dist/services/overload-alert-migration.d.ts.map +0 -1
- package/dist/services/overload-alert-migration.js +0 -115
- package/dist/services/overload-alert-migration.js.map +0 -1
- package/dist/services/pairing-store.d.ts +0 -47
- package/dist/services/pairing-store.d.ts.map +0 -1
- package/dist/services/pairing-store.js +0 -132
- package/dist/services/pairing-store.js.map +0 -1
- package/dist/services/pi-transcript.d.ts +0 -26
- package/dist/services/pi-transcript.d.ts.map +0 -1
- package/dist/services/pi-transcript.js +0 -327
- package/dist/services/pi-transcript.js.map +0 -1
- package/dist/services/platform-team-store.d.ts +0 -52
- package/dist/services/platform-team-store.d.ts.map +0 -1
- package/dist/services/platform-team-store.js +0 -159
- package/dist/services/platform-team-store.js.map +0 -1
- package/dist/services/plugin-registry-store.d.ts +0 -8
- package/dist/services/plugin-registry-store.d.ts.map +0 -1
- package/dist/services/plugin-registry-store.js +0 -153
- package/dist/services/plugin-registry-store.js.map +0 -1
- package/dist/services/project-scanner.d.ts +0 -28
- package/dist/services/project-scanner.d.ts.map +0 -1
- package/dist/services/project-scanner.js +0 -203
- package/dist/services/project-scanner.js.map +0 -1
- package/dist/services/quota-dedup.d.ts +0 -33
- package/dist/services/quota-dedup.d.ts.map +0 -1
- package/dist/services/quota-dedup.js +0 -67
- package/dist/services/quota-dedup.js.map +0 -1
- package/dist/services/relay-picker.d.ts +0 -27
- package/dist/services/relay-picker.d.ts.map +0 -1
- package/dist/services/relay-picker.js +0 -88
- package/dist/services/relay-picker.js.map +0 -1
- package/dist/services/restart-intent-store.d.ts +0 -41
- package/dist/services/restart-intent-store.d.ts.map +0 -1
- package/dist/services/restart-intent-store.js +0 -194
- package/dist/services/restart-intent-store.js.map +0 -1
- package/dist/services/resumable-session-discovery.d.ts +0 -15
- package/dist/services/resumable-session-discovery.d.ts.map +0 -1
- package/dist/services/resumable-session-discovery.js +0 -357
- package/dist/services/resumable-session-discovery.js.map +0 -1
- package/dist/services/role-profile-store.d.ts +0 -25
- package/dist/services/role-profile-store.d.ts.map +0 -1
- package/dist/services/role-profile-store.js +0 -176
- package/dist/services/role-profile-store.js.map +0 -1
- package/dist/services/sandbox-migration.d.ts +0 -14
- package/dist/services/sandbox-migration.d.ts.map +0 -1
- package/dist/services/sandbox-migration.js +0 -85
- package/dist/services/sandbox-migration.js.map +0 -1
- package/dist/services/sandbox-store.d.ts +0 -50
- package/dist/services/sandbox-store.d.ts.map +0 -1
- package/dist/services/sandbox-store.js +0 -155
- package/dist/services/sandbox-store.js.map +0 -1
- package/dist/services/schedule-split-migration.d.ts +0 -2
- package/dist/services/schedule-split-migration.d.ts.map +0 -1
- package/dist/services/schedule-split-migration.js +0 -159
- package/dist/services/schedule-split-migration.js.map +0 -1
- package/dist/services/schedule-store.d.ts +0 -138
- package/dist/services/schedule-store.d.ts.map +0 -1
- package/dist/services/schedule-store.js +0 -619
- package/dist/services/schedule-store.js.map +0 -1
- package/dist/services/seen-message-store.d.ts +0 -12
- package/dist/services/seen-message-store.d.ts.map +0 -1
- package/dist/services/seen-message-store.js +0 -119
- package/dist/services/seen-message-store.js.map +0 -1
- package/dist/services/send-policy.d.ts +0 -182
- package/dist/services/send-policy.d.ts.map +0 -1
- package/dist/services/send-policy.js +0 -189
- package/dist/services/send-policy.js.map +0 -1
- package/dist/services/session-lifecycle-hooks.d.ts +0 -10
- package/dist/services/session-lifecycle-hooks.d.ts.map +0 -1
- package/dist/services/session-lifecycle-hooks.js +0 -78
- package/dist/services/session-lifecycle-hooks.js.map +0 -1
- package/dist/services/session-store.d.ts +0 -68
- package/dist/services/session-store.d.ts.map +0 -1
- package/dist/services/session-store.js +0 -419
- package/dist/services/session-store.js.map +0 -1
- package/dist/services/skill-registry-store.d.ts +0 -121
- package/dist/services/skill-registry-store.d.ts.map +0 -1
- package/dist/services/skill-registry-store.js +0 -1240
- package/dist/services/skill-registry-store.js.map +0 -1
- package/dist/services/structured-bridge-clis.d.ts +0 -29
- package/dist/services/structured-bridge-clis.d.ts.map +0 -1
- package/dist/services/structured-bridge-clis.js +0 -76
- package/dist/services/structured-bridge-clis.js.map +0 -1
- package/dist/services/submit-confirmation.d.ts +0 -22
- package/dist/services/submit-confirmation.d.ts.map +0 -1
- package/dist/services/submit-confirmation.js +0 -12
- package/dist/services/submit-confirmation.js.map +0 -1
- package/dist/services/substitute-chat-toggle-store.d.ts +0 -3
- package/dist/services/substitute-chat-toggle-store.d.ts.map +0 -1
- package/dist/services/substitute-chat-toggle-store.js +0 -58
- package/dist/services/substitute-chat-toggle-store.js.map +0 -1
- package/dist/services/substitute-mode-normalize.d.ts +0 -25
- package/dist/services/substitute-mode-normalize.d.ts.map +0 -1
- package/dist/services/substitute-mode-normalize.js +0 -80
- package/dist/services/substitute-mode-normalize.js.map +0 -1
- package/dist/services/substitute-mode-store.d.ts +0 -69
- package/dist/services/substitute-mode-store.d.ts.map +0 -1
- package/dist/services/substitute-mode-store.js +0 -142
- package/dist/services/substitute-mode-store.js.map +0 -1
- package/dist/services/summary-range-store.d.ts +0 -21
- package/dist/services/summary-range-store.d.ts.map +0 -1
- package/dist/services/summary-range-store.js +0 -89
- package/dist/services/summary-range-store.js.map +0 -1
- package/dist/services/team-board-store.d.ts +0 -33
- package/dist/services/team-board-store.d.ts.map +0 -1
- package/dist/services/team-board-store.js +0 -88
- package/dist/services/team-board-store.js.map +0 -1
- package/dist/services/team-bot-directory.d.ts +0 -29
- package/dist/services/team-bot-directory.d.ts.map +0 -1
- package/dist/services/team-bot-directory.js +0 -118
- package/dist/services/team-bot-directory.js.map +0 -1
- package/dist/services/team-bots-store.d.ts +0 -34
- package/dist/services/team-bots-store.d.ts.map +0 -1
- package/dist/services/team-bots-store.js +0 -111
- package/dist/services/team-bots-store.js.map +0 -1
- package/dist/services/team-groups-store.d.ts +0 -29
- package/dist/services/team-groups-store.d.ts.map +0 -1
- package/dist/services/team-groups-store.js +0 -70
- package/dist/services/team-groups-store.js.map +0 -1
- package/dist/services/team-roster.d.ts +0 -64
- package/dist/services/team-roster.d.ts.map +0 -1
- package/dist/services/team-roster.js +0 -108
- package/dist/services/team-roster.js.map +0 -1
- package/dist/services/team-store.d.ts +0 -54
- package/dist/services/team-store.d.ts.map +0 -1
- package/dist/services/team-store.js +0 -156
- package/dist/services/team-store.js.map +0 -1
- package/dist/services/traex-paths.d.ts +0 -26
- package/dist/services/traex-paths.d.ts.map +0 -1
- package/dist/services/traex-paths.js +0 -40
- package/dist/services/traex-paths.js.map +0 -1
- package/dist/services/traex-transcript.d.ts +0 -59
- package/dist/services/traex-transcript.d.ts.map +0 -1
- package/dist/services/traex-transcript.js +0 -370
- package/dist/services/traex-transcript.js.map +0 -1
- package/dist/services/traex-user-input.d.ts +0 -19
- package/dist/services/traex-user-input.d.ts.map +0 -1
- package/dist/services/traex-user-input.js +0 -57
- package/dist/services/traex-user-input.js.map +0 -1
- package/dist/services/transcript-resolver.d.ts +0 -35
- package/dist/services/transcript-resolver.d.ts.map +0 -1
- package/dist/services/transcript-resolver.js +0 -297
- package/dist/services/transcript-resolver.js.map +0 -1
- package/dist/services/trigger-log-store.d.ts +0 -105
- package/dist/services/trigger-log-store.d.ts.map +0 -1
- package/dist/services/trigger-log-store.js +0 -203
- package/dist/services/trigger-log-store.js.map +0 -1
- package/dist/services/trigger-types.d.ts +0 -124
- package/dist/services/trigger-types.d.ts.map +0 -1
- package/dist/services/trigger-types.js +0 -72
- package/dist/services/trigger-types.js.map +0 -1
- package/dist/services/turn-terminal-deduper.d.ts +0 -14
- package/dist/services/turn-terminal-deduper.d.ts.map +0 -1
- package/dist/services/turn-terminal-deduper.js +0 -34
- package/dist/services/turn-terminal-deduper.js.map +0 -1
- package/dist/services/usage-ledger.d.ts +0 -112
- package/dist/services/usage-ledger.d.ts.map +0 -1
- package/dist/services/usage-ledger.js +0 -485
- package/dist/services/usage-ledger.js.map +0 -1
- package/dist/services/vc-meeting-action-gate.d.ts +0 -246
- package/dist/services/vc-meeting-action-gate.d.ts.map +0 -1
- package/dist/services/vc-meeting-action-gate.js +0 -756
- package/dist/services/vc-meeting-action-gate.js.map +0 -1
- package/dist/services/vc-meeting-action-store.d.ts +0 -222
- package/dist/services/vc-meeting-action-store.d.ts.map +0 -1
- package/dist/services/vc-meeting-action-store.js +0 -806
- package/dist/services/vc-meeting-action-store.js.map +0 -1
- package/dist/services/vc-meeting-consumer-isolation.d.ts +0 -29
- package/dist/services/vc-meeting-consumer-isolation.d.ts.map +0 -1
- package/dist/services/vc-meeting-consumer-isolation.js +0 -39
- package/dist/services/vc-meeting-consumer-isolation.js.map +0 -1
- package/dist/services/vc-meeting-consumer-profile-bootstrap.d.ts +0 -72
- package/dist/services/vc-meeting-consumer-profile-bootstrap.d.ts.map +0 -1
- package/dist/services/vc-meeting-consumer-profile-bootstrap.js +0 -343
- package/dist/services/vc-meeting-consumer-profile-bootstrap.js.map +0 -1
- package/dist/services/vc-meeting-consumer-profile-store.d.ts +0 -39
- package/dist/services/vc-meeting-consumer-profile-store.d.ts.map +0 -1
- package/dist/services/vc-meeting-consumer-profile-store.js +0 -191
- package/dist/services/vc-meeting-consumer-profile-store.js.map +0 -1
- package/dist/services/vc-meeting-consumer-profile-templates.d.ts +0 -32
- package/dist/services/vc-meeting-consumer-profile-templates.d.ts.map +0 -1
- package/dist/services/vc-meeting-consumer-profile-templates.js +0 -106
- package/dist/services/vc-meeting-consumer-profile-templates.js.map +0 -1
- package/dist/services/vc-meeting-daemon-auth.d.ts +0 -29
- package/dist/services/vc-meeting-daemon-auth.d.ts.map +0 -1
- package/dist/services/vc-meeting-daemon-auth.js +0 -117
- package/dist/services/vc-meeting-daemon-auth.js.map +0 -1
- package/dist/services/vc-meeting-delivery-feed.d.ts +0 -52
- package/dist/services/vc-meeting-delivery-feed.d.ts.map +0 -1
- package/dist/services/vc-meeting-delivery-feed.js +0 -232
- package/dist/services/vc-meeting-delivery-feed.js.map +0 -1
- package/dist/services/vc-meeting-delivery-hub-store.d.ts +0 -215
- package/dist/services/vc-meeting-delivery-hub-store.d.ts.map +0 -1
- package/dist/services/vc-meeting-delivery-hub-store.js +0 -1241
- package/dist/services/vc-meeting-delivery-hub-store.js.map +0 -1
- package/dist/services/vc-meeting-delivery-protocol.d.ts +0 -166
- package/dist/services/vc-meeting-delivery-protocol.d.ts.map +0 -1
- package/dist/services/vc-meeting-delivery-protocol.js +0 -452
- package/dist/services/vc-meeting-delivery-protocol.js.map +0 -1
- package/dist/services/vc-meeting-delivery-receiver.d.ts +0 -80
- package/dist/services/vc-meeting-delivery-receiver.d.ts.map +0 -1
- package/dist/services/vc-meeting-delivery-receiver.js +0 -552
- package/dist/services/vc-meeting-delivery-receiver.js.map +0 -1
- package/dist/services/vc-meeting-delivery-store.d.ts +0 -349
- package/dist/services/vc-meeting-delivery-store.d.ts.map +0 -1
- package/dist/services/vc-meeting-delivery-store.js +0 -1036
- package/dist/services/vc-meeting-delivery-store.js.map +0 -1
- package/dist/services/vc-meeting-feed-metadata-store.d.ts +0 -58
- package/dist/services/vc-meeting-feed-metadata-store.d.ts.map +0 -1
- package/dist/services/vc-meeting-feed-metadata-store.js +0 -356
- package/dist/services/vc-meeting-feed-metadata-store.js.map +0 -1
- package/dist/services/vc-meeting-im-reply.d.ts +0 -56
- package/dist/services/vc-meeting-im-reply.d.ts.map +0 -1
- package/dist/services/vc-meeting-im-reply.js +0 -295
- package/dist/services/vc-meeting-im-reply.js.map +0 -1
- package/dist/services/vc-meeting-im-routing.d.ts +0 -131
- package/dist/services/vc-meeting-im-routing.d.ts.map +0 -1
- package/dist/services/vc-meeting-im-routing.js +0 -449
- package/dist/services/vc-meeting-im-routing.js.map +0 -1
- package/dist/services/vc-meeting-listener-message-store.d.ts +0 -23
- package/dist/services/vc-meeting-listener-message-store.d.ts.map +0 -1
- package/dist/services/vc-meeting-listener-message-store.js +0 -142
- package/dist/services/vc-meeting-listener-message-store.js.map +0 -1
- package/dist/services/vc-meeting-listener-output-protocol.d.ts +0 -27
- package/dist/services/vc-meeting-listener-output-protocol.d.ts.map +0 -1
- package/dist/services/vc-meeting-listener-output-protocol.js +0 -58
- package/dist/services/vc-meeting-listener-output-protocol.js.map +0 -1
- package/dist/services/vc-meeting-listener-topic-store.d.ts +0 -31
- package/dist/services/vc-meeting-listener-topic-store.d.ts.map +0 -1
- package/dist/services/vc-meeting-listener-topic-store.js +0 -120
- package/dist/services/vc-meeting-listener-topic-store.js.map +0 -1
- package/dist/services/vc-meeting-member-policy.d.ts +0 -37
- package/dist/services/vc-meeting-member-policy.d.ts.map +0 -1
- package/dist/services/vc-meeting-member-policy.js +0 -102
- package/dist/services/vc-meeting-member-policy.js.map +0 -1
- package/dist/services/vc-meeting-preparations-store.d.ts +0 -22
- package/dist/services/vc-meeting-preparations-store.d.ts.map +0 -1
- package/dist/services/vc-meeting-preparations-store.js +0 -131
- package/dist/services/vc-meeting-preparations-store.js.map +0 -1
- package/dist/services/vc-meeting-profile-instructions.d.ts +0 -22
- package/dist/services/vc-meeting-profile-instructions.d.ts.map +0 -1
- package/dist/services/vc-meeting-profile-instructions.js +0 -64
- package/dist/services/vc-meeting-profile-instructions.js.map +0 -1
- package/dist/services/vc-meeting-runtime-store.d.ts +0 -132
- package/dist/services/vc-meeting-runtime-store.d.ts.map +0 -1
- package/dist/services/vc-meeting-runtime-store.js +0 -852
- package/dist/services/vc-meeting-runtime-store.js.map +0 -1
- package/dist/services/vc-meeting-send-policy.d.ts +0 -96
- package/dist/services/vc-meeting-send-policy.d.ts.map +0 -1
- package/dist/services/vc-meeting-send-policy.js +0 -158
- package/dist/services/vc-meeting-send-policy.js.map +0 -1
- package/dist/services/vc-meeting-terminal-reconciler.d.ts +0 -93
- package/dist/services/vc-meeting-terminal-reconciler.d.ts.map +0 -1
- package/dist/services/vc-meeting-terminal-reconciler.js +0 -198
- package/dist/services/vc-meeting-terminal-reconciler.js.map +0 -1
- package/dist/services/voice/audio.d.ts +0 -32
- package/dist/services/voice/audio.d.ts.map +0 -1
- package/dist/services/voice/audio.js +0 -114
- package/dist/services/voice/audio.js.map +0 -1
- package/dist/services/voice/index.d.ts +0 -37
- package/dist/services/voice/index.d.ts.map +0 -1
- package/dist/services/voice/index.js +0 -105
- package/dist/services/voice/index.js.map +0 -1
- package/dist/services/voice/openai.d.ts +0 -24
- package/dist/services/voice/openai.d.ts.map +0 -1
- package/dist/services/voice/openai.js +0 -47
- package/dist/services/voice/openai.js.map +0 -1
- package/dist/services/voice/sami.d.ts +0 -22
- package/dist/services/voice/sami.d.ts.map +0 -1
- package/dist/services/voice/sami.js +0 -128
- package/dist/services/voice/sami.js.map +0 -1
- package/dist/services/voice/types.d.ts +0 -32
- package/dist/services/voice/types.d.ts.map +0 -1
- package/dist/services/voice/types.js +0 -2
- package/dist/services/voice/types.js.map +0 -1
- package/dist/services/webhook-audit.d.ts +0 -10
- package/dist/services/webhook-audit.d.ts.map +0 -1
- package/dist/services/webhook-audit.js +0 -116
- package/dist/services/webhook-audit.js.map +0 -1
- package/dist/services/webhook-key.d.ts +0 -16
- package/dist/services/webhook-key.d.ts.map +0 -1
- package/dist/services/webhook-key.js +0 -123
- package/dist/services/webhook-key.js.map +0 -1
- package/dist/services/webhook-lifecycle-extractors.d.ts +0 -6
- package/dist/services/webhook-lifecycle-extractors.d.ts.map +0 -1
- package/dist/services/webhook-lifecycle-extractors.js +0 -44
- package/dist/services/webhook-lifecycle-extractors.js.map +0 -1
- package/dist/services/webhook-lifecycle-store.d.ts +0 -45
- package/dist/services/webhook-lifecycle-store.d.ts.map +0 -1
- package/dist/services/webhook-lifecycle-store.js +0 -159
- package/dist/services/webhook-lifecycle-store.js.map +0 -1
- package/dist/services/whiteboard-store.d.ts +0 -67
- package/dist/services/whiteboard-store.d.ts.map +0 -1
- package/dist/services/whiteboard-store.js +0 -450
- package/dist/services/whiteboard-store.js.map +0 -1
- package/dist/services/worktree-slug-ai.d.ts +0 -3
- package/dist/services/worktree-slug-ai.d.ts.map +0 -1
- package/dist/services/worktree-slug-ai.js +0 -82
- package/dist/services/worktree-slug-ai.js.map +0 -1
- package/dist/setup/agent-preset.d.ts +0 -78
- package/dist/setup/agent-preset.d.ts.map +0 -1
- package/dist/setup/agent-preset.js +0 -127
- package/dist/setup/agent-preset.js.map +0 -1
- package/dist/setup/app-name.d.ts +0 -7
- package/dist/setup/app-name.d.ts.map +0 -1
- package/dist/setup/app-name.js +0 -10
- package/dist/setup/app-name.js.map +0 -1
- package/dist/setup/bot-config-editor.d.ts +0 -160
- package/dist/setup/bot-config-editor.d.ts.map +0 -1
- package/dist/setup/bot-config-editor.js +0 -459
- package/dist/setup/bot-config-editor.js.map +0 -1
- package/dist/setup/bots-store.d.ts +0 -3
- package/dist/setup/bots-store.d.ts.map +0 -1
- package/dist/setup/bots-store.js +0 -24
- package/dist/setup/bots-store.js.map +0 -1
- package/dist/setup/cli-availability.d.ts +0 -26
- package/dist/setup/cli-availability.d.ts.map +0 -1
- package/dist/setup/cli-availability.js +0 -77
- package/dist/setup/cli-availability.js.map +0 -1
- package/dist/setup/cli-selection.d.ts +0 -145
- package/dist/setup/cli-selection.d.ts.map +0 -1
- package/dist/setup/cli-selection.js +0 -402
- package/dist/setup/cli-selection.js.map +0 -1
- package/dist/setup/detect-platform.d.ts +0 -14
- package/dist/setup/detect-platform.d.ts.map +0 -1
- package/dist/setup/detect-platform.js +0 -139
- package/dist/setup/detect-platform.js.map +0 -1
- package/dist/setup/ensure-fonts.d.ts +0 -13
- package/dist/setup/ensure-fonts.d.ts.map +0 -1
- package/dist/setup/ensure-fonts.js +0 -225
- package/dist/setup/ensure-fonts.js.map +0 -1
- package/dist/setup/ensure-herdr-integrations.d.ts +0 -102
- package/dist/setup/ensure-herdr-integrations.d.ts.map +0 -1
- package/dist/setup/ensure-herdr-integrations.js +0 -432
- package/dist/setup/ensure-herdr-integrations.js.map +0 -1
- package/dist/setup/ensure-herdr.d.ts +0 -12
- package/dist/setup/ensure-herdr.d.ts.map +0 -1
- package/dist/setup/ensure-herdr.js +0 -70
- package/dist/setup/ensure-herdr.js.map +0 -1
- package/dist/setup/ensure-opus.d.ts +0 -13
- package/dist/setup/ensure-opus.d.ts.map +0 -1
- package/dist/setup/ensure-opus.js +0 -64
- package/dist/setup/ensure-opus.js.map +0 -1
- package/dist/setup/ensure-tmux.d.ts +0 -91
- package/dist/setup/ensure-tmux.d.ts.map +0 -1
- package/dist/setup/ensure-tmux.js +0 -418
- package/dist/setup/ensure-tmux.js.map +0 -1
- package/dist/setup/ensure-zellij.d.ts +0 -48
- package/dist/setup/ensure-zellij.d.ts.map +0 -1
- package/dist/setup/ensure-zellij.js +0 -94
- package/dist/setup/ensure-zellij.js.map +0 -1
- package/dist/setup/ensure-zmx.d.ts +0 -31
- package/dist/setup/ensure-zmx.d.ts.map +0 -1
- package/dist/setup/ensure-zmx.js +0 -161
- package/dist/setup/ensure-zmx.js.map +0 -1
- package/dist/setup/index.d.ts +0 -38
- package/dist/setup/index.d.ts.map +0 -1
- package/dist/setup/index.js +0 -194
- package/dist/setup/index.js.map +0 -1
- package/dist/setup/interactive-select.d.ts +0 -52
- package/dist/setup/interactive-select.d.ts.map +0 -1
- package/dist/setup/interactive-select.js +0 -271
- package/dist/setup/interactive-select.js.map +0 -1
- package/dist/setup/lark-scopes.json +0 -305
- package/dist/setup/open-platform-automation.d.ts +0 -417
- package/dist/setup/open-platform-automation.d.ts.map +0 -1
- package/dist/setup/open-platform-automation.js +0 -1610
- package/dist/setup/open-platform-automation.js.map +0 -1
- package/dist/setup/open-platform-outcome.d.ts +0 -50
- package/dist/setup/open-platform-outcome.d.ts.map +0 -1
- package/dist/setup/open-platform-outcome.js +0 -56
- package/dist/setup/open-platform-outcome.js.map +0 -1
- package/dist/setup/register-app.d.ts +0 -52
- package/dist/setup/register-app.d.ts.map +0 -1
- package/dist/setup/register-app.js +0 -91
- package/dist/setup/register-app.js.map +0 -1
- package/dist/setup/setup-args.d.ts +0 -89
- package/dist/setup/setup-args.d.ts.map +0 -1
- package/dist/setup/setup-args.js +0 -387
- package/dist/setup/setup-args.js.map +0 -1
- package/dist/setup/verify-permissions.d.ts +0 -150
- package/dist/setup/verify-permissions.d.ts.map +0 -1
- package/dist/setup/verify-permissions.js +0 -353
- package/dist/setup/verify-permissions.js.map +0 -1
- package/dist/skills/definitions.d.ts +0 -31
- package/dist/skills/definitions.d.ts.map +0 -1
- package/dist/skills/definitions.js +0 -1510
- package/dist/skills/definitions.js.map +0 -1
- package/dist/skills/injection-mode.d.ts +0 -93
- package/dist/skills/injection-mode.d.ts.map +0 -1
- package/dist/skills/injection-mode.js +0 -204
- package/dist/skills/injection-mode.js.map +0 -1
- package/dist/skills/installer.d.ts +0 -60
- package/dist/skills/installer.d.ts.map +0 -1
- package/dist/skills/installer.js +0 -217
- package/dist/skills/installer.js.map +0 -1
- package/dist/types.d.ts +0 -1131
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -2
- package/dist/types.js.map +0 -1
- package/dist/utils/allowed-users-apply.d.ts +0 -76
- package/dist/utils/allowed-users-apply.d.ts.map +0 -1
- package/dist/utils/allowed-users-apply.js +0 -124
- package/dist/utils/allowed-users-apply.js.map +0 -1
- package/dist/utils/allowed-users-cache.d.ts +0 -29
- package/dist/utils/allowed-users-cache.d.ts.map +0 -1
- package/dist/utils/allowed-users-cache.js +0 -82
- package/dist/utils/allowed-users-cache.js.map +0 -1
- package/dist/utils/anchor-serializer.d.ts +0 -12
- package/dist/utils/anchor-serializer.d.ts.map +0 -1
- package/dist/utils/anchor-serializer.js +0 -64
- package/dist/utils/anchor-serializer.js.map +0 -1
- package/dist/utils/atomic-write.d.ts +0 -34
- package/dist/utils/atomic-write.d.ts.map +0 -1
- package/dist/utils/atomic-write.js +0 -183
- package/dist/utils/atomic-write.js.map +0 -1
- package/dist/utils/bot-routing.d.ts +0 -80
- package/dist/utils/bot-routing.d.ts.map +0 -1
- package/dist/utils/bot-routing.js +0 -167
- package/dist/utils/bot-routing.js.map +0 -1
- package/dist/utils/bounded-map.d.ts +0 -15
- package/dist/utils/bounded-map.d.ts.map +0 -1
- package/dist/utils/bounded-map.js +0 -29
- package/dist/utils/bounded-map.js.map +0 -1
- package/dist/utils/canonical-input-hash.d.ts +0 -5
- package/dist/utils/canonical-input-hash.d.ts.map +0 -1
- package/dist/utils/canonical-input-hash.js +0 -43
- package/dist/utils/canonical-input-hash.js.map +0 -1
- package/dist/utils/canonical-json.d.ts +0 -10
- package/dist/utils/canonical-json.d.ts.map +0 -1
- package/dist/utils/canonical-json.js +0 -23
- package/dist/utils/canonical-json.js.map +0 -1
- package/dist/utils/child-env.d.ts +0 -147
- package/dist/utils/child-env.d.ts.map +0 -1
- package/dist/utils/child-env.js +0 -299
- package/dist/utils/child-env.js.map +0 -1
- package/dist/utils/cli-usage-limit.d.ts +0 -62
- package/dist/utils/cli-usage-limit.d.ts.map +0 -1
- package/dist/utils/cli-usage-limit.js +0 -169
- package/dist/utils/cli-usage-limit.js.map +0 -1
- package/dist/utils/codex-app-context.d.ts +0 -9
- package/dist/utils/codex-app-context.d.ts.map +0 -1
- package/dist/utils/codex-app-context.js +0 -47
- package/dist/utils/codex-app-context.js.map +0 -1
- package/dist/utils/codex-update-dialog.d.ts +0 -17
- package/dist/utils/codex-update-dialog.d.ts.map +0 -1
- package/dist/utils/codex-update-dialog.js +0 -33
- package/dist/utils/codex-update-dialog.js.map +0 -1
- package/dist/utils/crash-log.d.ts +0 -22
- package/dist/utils/crash-log.d.ts.map +0 -1
- package/dist/utils/crash-log.js +0 -37
- package/dist/utils/crash-log.js.map +0 -1
- package/dist/utils/daemon-discovery.d.ts +0 -25
- package/dist/utils/daemon-discovery.d.ts.map +0 -1
- package/dist/utils/daemon-discovery.js +0 -86
- package/dist/utils/daemon-discovery.js.map +0 -1
- package/dist/utils/effort-confirm-dialog.d.ts +0 -40
- package/dist/utils/effort-confirm-dialog.d.ts.map +0 -1
- package/dist/utils/effort-confirm-dialog.js +0 -74
- package/dist/utils/effort-confirm-dialog.js.map +0 -1
- package/dist/utils/executable.d.ts +0 -3
- package/dist/utils/executable.d.ts.map +0 -1
- package/dist/utils/executable.js +0 -24
- package/dist/utils/executable.js.map +0 -1
- package/dist/utils/file-lock.d.ts +0 -19
- package/dist/utils/file-lock.d.ts.map +0 -1
- package/dist/utils/file-lock.js +0 -1038
- package/dist/utils/file-lock.js.map +0 -1
- package/dist/utils/font-installer.d.ts +0 -2
- package/dist/utils/font-installer.d.ts.map +0 -1
- package/dist/utils/font-installer.js +0 -60
- package/dist/utils/font-installer.js.map +0 -1
- package/dist/utils/fs-durability.d.ts +0 -20
- package/dist/utils/fs-durability.d.ts.map +0 -1
- package/dist/utils/fs-durability.js +0 -84
- package/dist/utils/fs-durability.js.map +0 -1
- package/dist/utils/global-install.d.ts +0 -27
- package/dist/utils/global-install.d.ts.map +0 -1
- package/dist/utils/global-install.js +0 -184
- package/dist/utils/global-install.js.map +0 -1
- package/dist/utils/herdr-web-history.d.ts +0 -12
- package/dist/utils/herdr-web-history.d.ts.map +0 -1
- package/dist/utils/herdr-web-history.js +0 -74
- package/dist/utils/herdr-web-history.js.map +0 -1
- package/dist/utils/herdr-web-terminal-binding.d.ts +0 -39
- package/dist/utils/herdr-web-terminal-binding.d.ts.map +0 -1
- package/dist/utils/herdr-web-terminal-binding.js +0 -56
- package/dist/utils/herdr-web-terminal-binding.js.map +0 -1
- package/dist/utils/idle-detector.d.ts +0 -39
- package/dist/utils/idle-detector.d.ts.map +0 -1
- package/dist/utils/idle-detector.js +0 -159
- package/dist/utils/idle-detector.js.map +0 -1
- package/dist/utils/input-gate.d.ts +0 -103
- package/dist/utils/input-gate.d.ts.map +0 -1
- package/dist/utils/input-gate.js +0 -96
- package/dist/utils/input-gate.js.map +0 -1
- package/dist/utils/install-diagnostics.d.ts +0 -52
- package/dist/utils/install-diagnostics.d.ts.map +0 -1
- package/dist/utils/install-diagnostics.js +0 -157
- package/dist/utils/install-diagnostics.js.map +0 -1
- package/dist/utils/install-info.d.ts +0 -19
- package/dist/utils/install-info.d.ts.map +0 -1
- package/dist/utils/install-info.js +0 -68
- package/dist/utils/install-info.js.map +0 -1
- package/dist/utils/lark-upload.d.ts +0 -3
- package/dist/utils/lark-upload.d.ts.map +0 -1
- package/dist/utils/lark-upload.js +0 -31
- package/dist/utils/lark-upload.js.map +0 -1
- package/dist/utils/listen-with-probe.d.ts +0 -47
- package/dist/utils/listen-with-probe.d.ts.map +0 -1
- package/dist/utils/listen-with-probe.js +0 -142
- package/dist/utils/listen-with-probe.js.map +0 -1
- package/dist/utils/logger.d.ts +0 -17
- package/dist/utils/logger.d.ts.map +0 -1
- package/dist/utils/logger.js +0 -80
- package/dist/utils/logger.js.map +0 -1
- package/dist/utils/pending-input-queue.d.ts +0 -122
- package/dist/utils/pending-input-queue.d.ts.map +0 -1
- package/dist/utils/pending-input-queue.js +0 -170
- package/dist/utils/pending-input-queue.js.map +0 -1
- package/dist/utils/process-identity.d.ts +0 -7
- package/dist/utils/process-identity.d.ts.map +0 -1
- package/dist/utils/process-identity.js +0 -62
- package/dist/utils/process-identity.js.map +0 -1
- package/dist/utils/ready-gate.d.ts +0 -90
- package/dist/utils/ready-gate.d.ts.map +0 -1
- package/dist/utils/ready-gate.js +0 -104
- package/dist/utils/ready-gate.js.map +0 -1
- package/dist/utils/render-dimensions.d.ts +0 -56
- package/dist/utils/render-dimensions.d.ts.map +0 -1
- package/dist/utils/render-dimensions.js +0 -65
- package/dist/utils/render-dimensions.js.map +0 -1
- package/dist/utils/runtime-build-id.d.ts +0 -21
- package/dist/utils/runtime-build-id.d.ts.map +0 -1
- package/dist/utils/runtime-build-id.js +0 -83
- package/dist/utils/runtime-build-id.js.map +0 -1
- package/dist/utils/screenshot-renderer.d.ts +0 -11
- package/dist/utils/screenshot-renderer.d.ts.map +0 -1
- package/dist/utils/screenshot-renderer.js +0 -267
- package/dist/utils/screenshot-renderer.js.map +0 -1
- package/dist/utils/stdio-epipe-guard.d.ts +0 -39
- package/dist/utils/stdio-epipe-guard.d.ts.map +0 -1
- package/dist/utils/stdio-epipe-guard.js +0 -67
- package/dist/utils/stdio-epipe-guard.js.map +0 -1
- package/dist/utils/stuck-detector.d.ts +0 -45
- package/dist/utils/stuck-detector.d.ts.map +0 -1
- package/dist/utils/stuck-detector.js +0 -188
- package/dist/utils/stuck-detector.js.map +0 -1
- package/dist/utils/stuck-key-guard.d.ts +0 -76
- package/dist/utils/stuck-key-guard.d.ts.map +0 -1
- package/dist/utils/stuck-key-guard.js +0 -77
- package/dist/utils/stuck-key-guard.js.map +0 -1
- package/dist/utils/terminal-favicon.d.ts +0 -2
- package/dist/utils/terminal-favicon.d.ts.map +0 -1
- package/dist/utils/terminal-favicon.js +0 -5
- package/dist/utils/terminal-favicon.js.map +0 -1
- package/dist/utils/terminal-renderer.d.ts +0 -59
- package/dist/utils/terminal-renderer.d.ts.map +0 -1
- package/dist/utils/terminal-renderer.js +0 -121
- package/dist/utils/terminal-renderer.js.map +0 -1
- package/dist/utils/timezone.d.ts +0 -51
- package/dist/utils/timezone.d.ts.map +0 -1
- package/dist/utils/timezone.js +0 -110
- package/dist/utils/timezone.js.map +0 -1
- package/dist/utils/timing.d.ts +0 -30
- package/dist/utils/timing.d.ts.map +0 -1
- package/dist/utils/timing.js +0 -41
- package/dist/utils/timing.js.map +0 -1
- package/dist/utils/transient-snapshot.d.ts +0 -53
- package/dist/utils/transient-snapshot.d.ts.map +0 -1
- package/dist/utils/transient-snapshot.js +0 -123
- package/dist/utils/transient-snapshot.js.map +0 -1
- package/dist/utils/tui-input-delivery.d.ts +0 -32
- package/dist/utils/tui-input-delivery.d.ts.map +0 -1
- package/dist/utils/tui-input-delivery.js +0 -53
- package/dist/utils/tui-input-delivery.js.map +0 -1
- package/dist/utils/user-token.d.ts +0 -53
- package/dist/utils/user-token.d.ts.map +0 -1
- package/dist/utils/user-token.js +0 -296
- package/dist/utils/user-token.js.map +0 -1
- package/dist/utils/version-info.d.ts +0 -25
- package/dist/utils/version-info.d.ts.map +0 -1
- package/dist/utils/version-info.js +0 -48
- package/dist/utils/version-info.js.map +0 -1
- package/dist/utils/web-terminal-listen.d.ts +0 -30
- package/dist/utils/web-terminal-listen.d.ts.map +0 -1
- package/dist/utils/web-terminal-listen.js +0 -81
- package/dist/utils/web-terminal-listen.js.map +0 -1
- package/dist/utils/web-terminal-seed.d.ts +0 -40
- package/dist/utils/web-terminal-seed.d.ts.map +0 -1
- package/dist/utils/web-terminal-seed.js +0 -46
- package/dist/utils/web-terminal-seed.js.map +0 -1
- package/dist/utils/worker-http.d.ts +0 -7
- package/dist/utils/worker-http.d.ts.map +0 -1
- package/dist/utils/worker-http.js +0 -27
- package/dist/utils/worker-http.js.map +0 -1
- package/dist/utils/working-dir.d.ts +0 -11
- package/dist/utils/working-dir.d.ts.map +0 -1
- package/dist/utils/working-dir.js +0 -45
- package/dist/utils/working-dir.js.map +0 -1
- package/dist/utils/xml.d.ts +0 -19
- package/dist/utils/xml.d.ts.map +0 -1
- package/dist/utils/xml.js +0 -26
- package/dist/utils/xml.js.map +0 -1
- package/dist/vc-agent/cards.d.ts +0 -94
- package/dist/vc-agent/cards.d.ts.map +0 -1
- package/dist/vc-agent/cards.js +0 -927
- package/dist/vc-agent/cards.js.map +0 -1
- package/dist/vc-agent/meeting-state.d.ts +0 -39
- package/dist/vc-agent/meeting-state.d.ts.map +0 -1
- package/dist/vc-agent/meeting-state.js +0 -186
- package/dist/vc-agent/meeting-state.js.map +0 -1
- package/dist/vc-agent/normalizer.d.ts +0 -13
- package/dist/vc-agent/normalizer.d.ts.map +0 -1
- package/dist/vc-agent/normalizer.js +0 -470
- package/dist/vc-agent/normalizer.js.map +0 -1
- package/dist/vc-agent/polling-source.d.ts +0 -69
- package/dist/vc-agent/polling-source.d.ts.map +0 -1
- package/dist/vc-agent/polling-source.js +0 -194
- package/dist/vc-agent/polling-source.js.map +0 -1
- package/dist/vc-agent/push-source.d.ts +0 -13
- package/dist/vc-agent/push-source.d.ts.map +0 -1
- package/dist/vc-agent/push-source.js +0 -109
- package/dist/vc-agent/push-source.js.map +0 -1
- package/dist/vc-agent/realtime/audio-source.d.ts +0 -6
- package/dist/vc-agent/realtime/audio-source.d.ts.map +0 -1
- package/dist/vc-agent/realtime/audio-source.js +0 -17
- package/dist/vc-agent/realtime/audio-source.js.map +0 -1
- package/dist/vc-agent/realtime/endpoint.d.ts +0 -6
- package/dist/vc-agent/realtime/endpoint.d.ts.map +0 -1
- package/dist/vc-agent/realtime/endpoint.js +0 -25
- package/dist/vc-agent/realtime/endpoint.js.map +0 -1
- package/dist/vc-agent/realtime/errors.d.ts +0 -9
- package/dist/vc-agent/realtime/errors.d.ts.map +0 -1
- package/dist/vc-agent/realtime/errors.js +0 -17
- package/dist/vc-agent/realtime/errors.js.map +0 -1
- package/dist/vc-agent/realtime/events.d.ts +0 -24
- package/dist/vc-agent/realtime/events.d.ts.map +0 -1
- package/dist/vc-agent/realtime/events.js +0 -190
- package/dist/vc-agent/realtime/events.js.map +0 -1
- package/dist/vc-agent/realtime/frontier.d.ts +0 -34
- package/dist/vc-agent/realtime/frontier.d.ts.map +0 -1
- package/dist/vc-agent/realtime/frontier.js +0 -40
- package/dist/vc-agent/realtime/frontier.js.map +0 -1
- package/dist/vc-agent/realtime/index.d.ts +0 -11
- package/dist/vc-agent/realtime/index.d.ts.map +0 -1
- package/dist/vc-agent/realtime/index.js +0 -11
- package/dist/vc-agent/realtime/index.js.map +0 -1
- package/dist/vc-agent/realtime/pacer.d.ts +0 -21
- package/dist/vc-agent/realtime/pacer.d.ts.map +0 -1
- package/dist/vc-agent/realtime/pacer.js +0 -80
- package/dist/vc-agent/realtime/pacer.js.map +0 -1
- package/dist/vc-agent/realtime/protobuf.d.ts +0 -33
- package/dist/vc-agent/realtime/protobuf.d.ts.map +0 -1
- package/dist/vc-agent/realtime/protobuf.js +0 -159
- package/dist/vc-agent/realtime/protobuf.js.map +0 -1
- package/dist/vc-agent/realtime/protocol.d.ts +0 -4
- package/dist/vc-agent/realtime/protocol.d.ts.map +0 -1
- package/dist/vc-agent/realtime/protocol.js +0 -59
- package/dist/vc-agent/realtime/protocol.js.map +0 -1
- package/dist/vc-agent/realtime/session.d.ts +0 -39
- package/dist/vc-agent/realtime/session.d.ts.map +0 -1
- package/dist/vc-agent/realtime/session.js +0 -221
- package/dist/vc-agent/realtime/session.js.map +0 -1
- package/dist/vc-agent/realtime/transport.d.ts +0 -23
- package/dist/vc-agent/realtime/transport.d.ts.map +0 -1
- package/dist/vc-agent/realtime/transport.js +0 -112
- package/dist/vc-agent/realtime/transport.js.map +0 -1
- package/dist/vc-agent/realtime/types.d.ts +0 -84
- package/dist/vc-agent/realtime/types.d.ts.map +0 -1
- package/dist/vc-agent/realtime/types.js +0 -5
- package/dist/vc-agent/realtime/types.js.map +0 -1
- package/dist/vc-agent/types.d.ts +0 -143
- package/dist/vc-agent/types.d.ts.map +0 -1
- package/dist/vc-agent/types.js +0 -2
- package/dist/vc-agent/types.js.map +0 -1
- package/dist/worker.d.ts +0 -3
- package/dist/worker.d.ts.map +0 -1
- package/dist/worker.js +0 -12831
- package/dist/worker.js.map +0 -1
- package/dist/workflows/attempt-terminal.d.ts +0 -25
- package/dist/workflows/attempt-terminal.d.ts.map +0 -1
- package/dist/workflows/attempt-terminal.js +0 -7
- package/dist/workflows/attempt-terminal.js.map +0 -1
- package/dist/workflows/definition.d.ts +0 -1705
- package/dist/workflows/definition.d.ts.map +0 -1
- package/dist/workflows/definition.js +0 -552
- package/dist/workflows/definition.js.map +0 -1
- package/dist/workflows/events/payloads.d.ts +0 -1116
- package/dist/workflows/events/payloads.d.ts.map +0 -1
- package/dist/workflows/events/payloads.js +0 -397
- package/dist/workflows/events/payloads.js.map +0 -1
- package/dist/workflows/events/replay.d.ts +0 -265
- package/dist/workflows/events/replay.d.ts.map +0 -1
- package/dist/workflows/events/replay.js +0 -716
- package/dist/workflows/events/replay.js.map +0 -1
- package/dist/workflows/events/schema.d.ts +0 -6093
- package/dist/workflows/events/schema.d.ts.map +0 -1
- package/dist/workflows/events/schema.js +0 -328
- package/dist/workflows/events/schema.js.map +0 -1
- package/dist/workflows/events/types.d.ts +0 -38
- package/dist/workflows/events/types.d.ts.map +0 -1
- package/dist/workflows/events/types.js +0 -2
- package/dist/workflows/events/types.js.map +0 -1
- package/dist/workflows/hostExecutors/botmux-schedule.d.ts +0 -47
- package/dist/workflows/hostExecutors/botmux-schedule.d.ts.map +0 -1
- package/dist/workflows/hostExecutors/botmux-schedule.js +0 -198
- package/dist/workflows/hostExecutors/botmux-schedule.js.map +0 -1
- package/dist/workflows/hostExecutors/feishu-im.d.ts +0 -12
- package/dist/workflows/hostExecutors/feishu-im.d.ts.map +0 -1
- package/dist/workflows/hostExecutors/feishu-im.js +0 -49
- package/dist/workflows/hostExecutors/feishu-im.js.map +0 -1
- package/dist/workflows/hostExecutors/feishu-reply.d.ts +0 -24
- package/dist/workflows/hostExecutors/feishu-reply.d.ts.map +0 -1
- package/dist/workflows/hostExecutors/feishu-reply.js +0 -88
- package/dist/workflows/hostExecutors/feishu-reply.js.map +0 -1
- package/dist/workflows/hostExecutors/feishu-send.d.ts +0 -23
- package/dist/workflows/hostExecutors/feishu-send.d.ts.map +0 -1
- package/dist/workflows/hostExecutors/feishu-send.js +0 -124
- package/dist/workflows/hostExecutors/feishu-send.js.map +0 -1
- package/dist/workflows/hostExecutors/index.d.ts +0 -7
- package/dist/workflows/hostExecutors/index.d.ts.map +0 -1
- package/dist/workflows/hostExecutors/index.js +0 -7
- package/dist/workflows/hostExecutors/index.js.map +0 -1
- package/dist/workflows/hostExecutors/registry.d.ts +0 -5
- package/dist/workflows/hostExecutors/registry.d.ts.map +0 -1
- package/dist/workflows/hostExecutors/registry.js +0 -36
- package/dist/workflows/hostExecutors/registry.js.map +0 -1
- package/dist/workflows/hostExecutors/types.d.ts +0 -70
- package/dist/workflows/hostExecutors/types.d.ts.map +0 -1
- package/dist/workflows/hostExecutors/types.js +0 -2
- package/dist/workflows/hostExecutors/types.js.map +0 -1
- package/dist/workflows/migration/v2-definition-paths.d.ts +0 -3
- package/dist/workflows/migration/v2-definition-paths.d.ts.map +0 -1
- package/dist/workflows/migration/v2-definition-paths.js +0 -10
- package/dist/workflows/migration/v2-definition-paths.js.map +0 -1
- package/dist/workflows/migration/v2-ledger.d.ts +0 -138
- package/dist/workflows/migration/v2-ledger.d.ts.map +0 -1
- package/dist/workflows/migration/v2-ledger.js +0 -599
- package/dist/workflows/migration/v2-ledger.js.map +0 -1
- package/dist/workflows/migration/v2-migration-service.d.ts +0 -40
- package/dist/workflows/migration/v2-migration-service.d.ts.map +0 -1
- package/dist/workflows/migration/v2-migration-service.js +0 -454
- package/dist/workflows/migration/v2-migration-service.js.map +0 -1
- package/dist/workflows/migration/v2-read-only-ids.d.ts +0 -7
- package/dist/workflows/migration/v2-read-only-ids.d.ts.map +0 -1
- package/dist/workflows/migration/v2-read-only-ids.js +0 -9
- package/dist/workflows/migration/v2-read-only-ids.js.map +0 -1
- package/dist/workflows/migration/v2-run-archive-schema.d.ts +0 -976
- package/dist/workflows/migration/v2-run-archive-schema.d.ts.map +0 -1
- package/dist/workflows/migration/v2-run-archive-schema.js +0 -113
- package/dist/workflows/migration/v2-run-archive-schema.js.map +0 -1
- package/dist/workflows/migration/v2-run-archive.d.ts +0 -92
- package/dist/workflows/migration/v2-run-archive.d.ts.map +0 -1
- package/dist/workflows/migration/v2-run-archive.js +0 -1220
- package/dist/workflows/migration/v2-run-archive.js.map +0 -1
- package/dist/workflows/migration/v2-scanner.d.ts +0 -22
- package/dist/workflows/migration/v2-scanner.d.ts.map +0 -1
- package/dist/workflows/migration/v2-scanner.js +0 -114
- package/dist/workflows/migration/v2-scanner.js.map +0 -1
- package/dist/workflows/migration/v2-to-v3.d.ts +0 -32
- package/dist/workflows/migration/v2-to-v3.d.ts.map +0 -1
- package/dist/workflows/migration/v2-to-v3.js +0 -498
- package/dist/workflows/migration/v2-to-v3.js.map +0 -1
- package/dist/workflows/ops-projection.d.ts +0 -226
- package/dist/workflows/ops-projection.d.ts.map +0 -1
- package/dist/workflows/ops-projection.js +0 -804
- package/dist/workflows/ops-projection.js.map +0 -1
- package/dist/workflows/shared/idempotency-key.d.ts +0 -19
- package/dist/workflows/shared/idempotency-key.d.ts.map +0 -1
- package/dist/workflows/shared/idempotency-key.js +0 -23
- package/dist/workflows/shared/idempotency-key.js.map +0 -1
- package/dist/workflows/shared/params.d.ts +0 -97
- package/dist/workflows/shared/params.d.ts.map +0 -1
- package/dist/workflows/shared/params.js +0 -282
- package/dist/workflows/shared/params.js.map +0 -1
- package/dist/workflows/shared/provider-reconciler.d.ts +0 -18
- package/dist/workflows/shared/provider-reconciler.d.ts.map +0 -1
- package/dist/workflows/shared/provider-reconciler.js +0 -17
- package/dist/workflows/shared/provider-reconciler.js.map +0 -1
- package/dist/workflows/shared/sandbox-policy.d.ts +0 -23
- package/dist/workflows/shared/sandbox-policy.d.ts.map +0 -1
- package/dist/workflows/shared/sandbox-policy.js +0 -21
- package/dist/workflows/shared/sandbox-policy.js.map +0 -1
- package/dist/workflows/shared/worker-process.d.ts +0 -29
- package/dist/workflows/shared/worker-process.d.ts.map +0 -1
- package/dist/workflows/shared/worker-process.js +0 -56
- package/dist/workflows/shared/worker-process.js.map +0 -1
- package/dist/workflows/v3/architect.d.ts +0 -37
- package/dist/workflows/v3/architect.d.ts.map +0 -1
- package/dist/workflows/v3/architect.js +0 -239
- package/dist/workflows/v3/architect.js.map +0 -1
- package/dist/workflows/v3/artifact-contract.d.ts +0 -41
- package/dist/workflows/v3/artifact-contract.d.ts.map +0 -1
- package/dist/workflows/v3/artifact-contract.js +0 -20
- package/dist/workflows/v3/artifact-contract.js.map +0 -1
- package/dist/workflows/v3/attempt-ledger.d.ts +0 -23
- package/dist/workflows/v3/attempt-ledger.d.ts.map +0 -1
- package/dist/workflows/v3/attempt-ledger.js +0 -74
- package/dist/workflows/v3/attempt-ledger.js.map +0 -1
- package/dist/workflows/v3/bot-resolve.d.ts +0 -39
- package/dist/workflows/v3/bot-resolve.d.ts.map +0 -1
- package/dist/workflows/v3/bot-resolve.js +0 -214
- package/dist/workflows/v3/bot-resolve.js.map +0 -1
- package/dist/workflows/v3/botmux-attempt-lease.d.ts +0 -7
- package/dist/workflows/v3/botmux-attempt-lease.d.ts.map +0 -1
- package/dist/workflows/v3/botmux-attempt-lease.js +0 -189
- package/dist/workflows/v3/botmux-attempt-lease.js.map +0 -1
- package/dist/workflows/v3/botmux-host-policy.d.ts +0 -7
- package/dist/workflows/v3/botmux-host-policy.d.ts.map +0 -1
- package/dist/workflows/v3/botmux-host-policy.js +0 -34
- package/dist/workflows/v3/botmux-host-policy.js.map +0 -1
- package/dist/workflows/v3/cli-daemon-command-authority.d.ts +0 -59
- package/dist/workflows/v3/cli-daemon-command-authority.d.ts.map +0 -1
- package/dist/workflows/v3/cli-daemon-command-authority.js +0 -175
- package/dist/workflows/v3/cli-daemon-command-authority.js.map +0 -1
- package/dist/workflows/v3/cli-run.d.ts +0 -60
- package/dist/workflows/v3/cli-run.d.ts.map +0 -1
- package/dist/workflows/v3/cli-run.js +0 -368
- package/dist/workflows/v3/cli-run.js.map +0 -1
- package/dist/workflows/v3/contract.d.ts +0 -243
- package/dist/workflows/v3/contract.d.ts.map +0 -1
- package/dist/workflows/v3/contract.js +0 -89
- package/dist/workflows/v3/contract.js.map +0 -1
- package/dist/workflows/v3/core-control.d.ts +0 -16
- package/dist/workflows/v3/core-control.d.ts.map +0 -1
- package/dist/workflows/v3/core-control.js +0 -60
- package/dist/workflows/v3/core-control.js.map +0 -1
- package/dist/workflows/v3/daemon-ipc-auth.d.ts +0 -113
- package/dist/workflows/v3/daemon-ipc-auth.d.ts.map +0 -1
- package/dist/workflows/v3/daemon-ipc-auth.js +0 -294
- package/dist/workflows/v3/daemon-ipc-auth.js.map +0 -1
- package/dist/workflows/v3/daemon-ipc-body.d.ts +0 -30
- package/dist/workflows/v3/daemon-ipc-body.d.ts.map +0 -1
- package/dist/workflows/v3/daemon-ipc-body.js +0 -65
- package/dist/workflows/v3/daemon-ipc-body.js.map +0 -1
- package/dist/workflows/v3/daemon-ipc-client.d.ts +0 -32
- package/dist/workflows/v3/daemon-ipc-client.d.ts.map +0 -1
- package/dist/workflows/v3/daemon-ipc-client.js +0 -74
- package/dist/workflows/v3/daemon-ipc-client.js.map +0 -1
- package/dist/workflows/v3/daemon-run.d.ts +0 -396
- package/dist/workflows/v3/daemon-run.d.ts.map +0 -1
- package/dist/workflows/v3/daemon-run.js +0 -1573
- package/dist/workflows/v3/daemon-run.js.map +0 -1
- package/dist/workflows/v3/dag-loader.d.ts +0 -5
- package/dist/workflows/v3/dag-loader.d.ts.map +0 -1
- package/dist/workflows/v3/dag-loader.js +0 -22
- package/dist/workflows/v3/dag-loader.js.map +0 -1
- package/dist/workflows/v3/dag.d.ts +0 -342
- package/dist/workflows/v3/dag.d.ts.map +0 -1
- package/dist/workflows/v3/dag.js +0 -1210
- package/dist/workflows/v3/dag.js.map +0 -1
- package/dist/workflows/v3/distillation-compiler.d.ts +0 -36
- package/dist/workflows/v3/distillation-compiler.d.ts.map +0 -1
- package/dist/workflows/v3/distillation-compiler.js +0 -704
- package/dist/workflows/v3/distillation-compiler.js.map +0 -1
- package/dist/workflows/v3/distillation-private-root.d.ts +0 -10
- package/dist/workflows/v3/distillation-private-root.d.ts.map +0 -1
- package/dist/workflows/v3/distillation-private-root.js +0 -34
- package/dist/workflows/v3/distillation-private-root.js.map +0 -1
- package/dist/workflows/v3/distillation-runner.d.ts +0 -68
- package/dist/workflows/v3/distillation-runner.d.ts.map +0 -1
- package/dist/workflows/v3/distillation-runner.js +0 -1030
- package/dist/workflows/v3/distillation-runner.js.map +0 -1
- package/dist/workflows/v3/distillation-schema.d.ts +0 -63
- package/dist/workflows/v3/distillation-schema.d.ts.map +0 -1
- package/dist/workflows/v3/distillation-schema.js +0 -184
- package/dist/workflows/v3/distillation-schema.js.map +0 -1
- package/dist/workflows/v3/distillation-service.d.ts +0 -78
- package/dist/workflows/v3/distillation-service.d.ts.map +0 -1
- package/dist/workflows/v3/distillation-service.js +0 -416
- package/dist/workflows/v3/distillation-service.js.map +0 -1
- package/dist/workflows/v3/distillation-source.d.ts +0 -35
- package/dist/workflows/v3/distillation-source.d.ts.map +0 -1
- package/dist/workflows/v3/distillation-source.js +0 -118
- package/dist/workflows/v3/distillation-source.js.map +0 -1
- package/dist/workflows/v3/distillation-store.d.ts +0 -185
- package/dist/workflows/v3/distillation-store.d.ts.map +0 -1
- package/dist/workflows/v3/distillation-store.js +0 -1127
- package/dist/workflows/v3/distillation-store.js.map +0 -1
- package/dist/workflows/v3/drive-lease.d.ts +0 -7
- package/dist/workflows/v3/drive-lease.d.ts.map +0 -1
- package/dist/workflows/v3/drive-lease.js +0 -10
- package/dist/workflows/v3/drive-lease.js.map +0 -1
- package/dist/workflows/v3/ephemeral-pool.d.ts +0 -29
- package/dist/workflows/v3/ephemeral-pool.d.ts.map +0 -1
- package/dist/workflows/v3/ephemeral-pool.js +0 -536
- package/dist/workflows/v3/ephemeral-pool.js.map +0 -1
- package/dist/workflows/v3/event-contract.d.ts +0 -273
- package/dist/workflows/v3/event-contract.d.ts.map +0 -1
- package/dist/workflows/v3/event-contract.js +0 -8
- package/dist/workflows/v3/event-contract.js.map +0 -1
- package/dist/workflows/v3/gate-policy.d.ts +0 -12
- package/dist/workflows/v3/gate-policy.d.ts.map +0 -1
- package/dist/workflows/v3/gate-policy.js +0 -20
- package/dist/workflows/v3/gate-policy.js.map +0 -1
- package/dist/workflows/v3/gate-wait-store.d.ts +0 -99
- package/dist/workflows/v3/gate-wait-store.d.ts.map +0 -1
- package/dist/workflows/v3/gate-wait-store.js +0 -263
- package/dist/workflows/v3/gate-wait-store.js.map +0 -1
- package/dist/workflows/v3/goal-cli.d.ts +0 -58
- package/dist/workflows/v3/goal-cli.d.ts.map +0 -1
- package/dist/workflows/v3/goal-cli.js +0 -430
- package/dist/workflows/v3/goal-cli.js.map +0 -1
- package/dist/workflows/v3/grill-state.d.ts +0 -107
- package/dist/workflows/v3/grill-state.d.ts.map +0 -1
- package/dist/workflows/v3/grill-state.js +0 -168
- package/dist/workflows/v3/grill-state.js.map +0 -1
- package/dist/workflows/v3/host-bindings.d.ts +0 -40
- package/dist/workflows/v3/host-bindings.d.ts.map +0 -1
- package/dist/workflows/v3/host-bindings.js +0 -272
- package/dist/workflows/v3/host-bindings.js.map +0 -1
- package/dist/workflows/v3/host-effect-ledger.d.ts +0 -22
- package/dist/workflows/v3/host-effect-ledger.d.ts.map +0 -1
- package/dist/workflows/v3/host-effect-ledger.js +0 -110
- package/dist/workflows/v3/host-effect-ledger.js.map +0 -1
- package/dist/workflows/v3/host-execution.d.ts +0 -142
- package/dist/workflows/v3/host-execution.d.ts.map +0 -1
- package/dist/workflows/v3/host-execution.js +0 -424
- package/dist/workflows/v3/host-execution.js.map +0 -1
- package/dist/workflows/v3/host.d.ts +0 -124
- package/dist/workflows/v3/host.d.ts.map +0 -1
- package/dist/workflows/v3/host.js +0 -628
- package/dist/workflows/v3/host.js.map +0 -1
- package/dist/workflows/v3/human-gate.d.ts +0 -8
- package/dist/workflows/v3/human-gate.d.ts.map +0 -1
- package/dist/workflows/v3/human-gate.js +0 -8
- package/dist/workflows/v3/human-gate.js.map +0 -1
- package/dist/workflows/v3/in-process-attempt-lease.d.ts +0 -10
- package/dist/workflows/v3/in-process-attempt-lease.d.ts.map +0 -1
- package/dist/workflows/v3/in-process-attempt-lease.js +0 -47
- package/dist/workflows/v3/in-process-attempt-lease.js.map +0 -1
- package/dist/workflows/v3/journal.d.ts +0 -52
- package/dist/workflows/v3/journal.d.ts.map +0 -1
- package/dist/workflows/v3/journal.js +0 -190
- package/dist/workflows/v3/journal.js.map +0 -1
- package/dist/workflows/v3/library-materialize.d.ts +0 -88
- package/dist/workflows/v3/library-materialize.d.ts.map +0 -1
- package/dist/workflows/v3/library-materialize.js +0 -298
- package/dist/workflows/v3/library-materialize.js.map +0 -1
- package/dist/workflows/v3/library-schema.d.ts +0 -159
- package/dist/workflows/v3/library-schema.d.ts.map +0 -1
- package/dist/workflows/v3/library-schema.js +0 -667
- package/dist/workflows/v3/library-schema.js.map +0 -1
- package/dist/workflows/v3/library-service.d.ts +0 -126
- package/dist/workflows/v3/library-service.d.ts.map +0 -1
- package/dist/workflows/v3/library-service.js +0 -542
- package/dist/workflows/v3/library-service.js.map +0 -1
- package/dist/workflows/v3/library-store.d.ts +0 -124
- package/dist/workflows/v3/library-store.d.ts.map +0 -1
- package/dist/workflows/v3/library-store.js +0 -665
- package/dist/workflows/v3/library-store.js.map +0 -1
- package/dist/workflows/v3/manifest.d.ts +0 -17
- package/dist/workflows/v3/manifest.d.ts.map +0 -1
- package/dist/workflows/v3/manifest.js +0 -266
- package/dist/workflows/v3/manifest.js.map +0 -1
- package/dist/workflows/v3/ops-projection.d.ts +0 -110
- package/dist/workflows/v3/ops-projection.d.ts.map +0 -1
- package/dist/workflows/v3/ops-projection.js +0 -0
- package/dist/workflows/v3/ops-projection.js.map +0 -1
- package/dist/workflows/v3/orchestrator.d.ts +0 -175
- package/dist/workflows/v3/orchestrator.d.ts.map +0 -1
- package/dist/workflows/v3/orchestrator.js +0 -418
- package/dist/workflows/v3/orchestrator.js.map +0 -1
- package/dist/workflows/v3/portable-artifact-snapshot.d.ts +0 -15
- package/dist/workflows/v3/portable-artifact-snapshot.d.ts.map +0 -1
- package/dist/workflows/v3/portable-artifact-snapshot.js +0 -76
- package/dist/workflows/v3/portable-artifact-snapshot.js.map +0 -1
- package/dist/workflows/v3/portable-final-outputs.d.ts +0 -37
- package/dist/workflows/v3/portable-final-outputs.d.ts.map +0 -1
- package/dist/workflows/v3/portable-final-outputs.js +0 -137
- package/dist/workflows/v3/portable-final-outputs.js.map +0 -1
- package/dist/workflows/v3/portable-run-snapshot.d.ts +0 -14
- package/dist/workflows/v3/portable-run-snapshot.d.ts.map +0 -1
- package/dist/workflows/v3/portable-run-snapshot.js +0 -176
- package/dist/workflows/v3/portable-run-snapshot.js.map +0 -1
- package/dist/workflows/v3/portable-runtime.d.ts +0 -83
- package/dist/workflows/v3/portable-runtime.d.ts.map +0 -1
- package/dist/workflows/v3/portable-runtime.js +0 -135
- package/dist/workflows/v3/portable-runtime.js.map +0 -1
- package/dist/workflows/v3/progress-projection.d.ts +0 -102
- package/dist/workflows/v3/progress-projection.d.ts.map +0 -1
- package/dist/workflows/v3/progress-projection.js +0 -219
- package/dist/workflows/v3/progress-projection.js.map +0 -1
- package/dist/workflows/v3/run-envelope.d.ts +0 -1324
- package/dist/workflows/v3/run-envelope.d.ts.map +0 -1
- package/dist/workflows/v3/run-envelope.js +0 -712
- package/dist/workflows/v3/run-envelope.js.map +0 -1
- package/dist/workflows/v3/runtime-host-contract.d.ts +0 -182
- package/dist/workflows/v3/runtime-host-contract.d.ts.map +0 -1
- package/dist/workflows/v3/runtime-host-contract.js +0 -9
- package/dist/workflows/v3/runtime-host-contract.js.map +0 -1
- package/dist/workflows/v3/runtime.d.ts +0 -16
- package/dist/workflows/v3/runtime.d.ts.map +0 -1
- package/dist/workflows/v3/runtime.js +0 -18
- package/dist/workflows/v3/runtime.js.map +0 -1
- package/dist/workflows/v3/session-relay-client.d.ts +0 -61
- package/dist/workflows/v3/session-relay-client.d.ts.map +0 -1
- package/dist/workflows/v3/session-relay-client.js +0 -92
- package/dist/workflows/v3/session-relay-client.js.map +0 -1
- package/dist/workflows/v3/session-relay.d.ts +0 -66
- package/dist/workflows/v3/session-relay.d.ts.map +0 -1
- package/dist/workflows/v3/session-relay.js +0 -157
- package/dist/workflows/v3/session-relay.js.map +0 -1
- package/dist/workflows/v3/shared-node-runtime.d.ts +0 -203
- package/dist/workflows/v3/shared-node-runtime.d.ts.map +0 -1
- package/dist/workflows/v3/shared-node-runtime.js +0 -2978
- package/dist/workflows/v3/shared-node-runtime.js.map +0 -1
- package/dist/workflows/v3/shared-runtime.d.ts +0 -17
- package/dist/workflows/v3/shared-runtime.d.ts.map +0 -1
- package/dist/workflows/v3/shared-runtime.js +0 -12
- package/dist/workflows/v3/shared-runtime.js.map +0 -1
- package/dist/workflows/v3/spec.d.ts +0 -32
- package/dist/workflows/v3/spec.d.ts.map +0 -1
- package/dist/workflows/v3/spec.js +0 -173
- package/dist/workflows/v3/spec.js.map +0 -1
- package/dist/workflows/v3/start-intent.d.ts +0 -8
- package/dist/workflows/v3/start-intent.d.ts.map +0 -1
- package/dist/workflows/v3/start-intent.js +0 -34
- package/dist/workflows/v3/start-intent.js.map +0 -1
- package/dist/workflows/v3/state.d.ts +0 -83
- package/dist/workflows/v3/state.d.ts.map +0 -1
- package/dist/workflows/v3/state.js +0 -525
- package/dist/workflows/v3/state.js.map +0 -1
- package/dist/workflows/v3/template-bindings.d.ts +0 -22
- package/dist/workflows/v3/template-bindings.d.ts.map +0 -1
- package/dist/workflows/v3/template-bindings.js +0 -204
- package/dist/workflows/v3/template-bindings.js.map +0 -1
- package/dist/workflows/v3/worker-fence.d.ts +0 -158
- package/dist/workflows/v3/worker-fence.d.ts.map +0 -1
- package/dist/workflows/v3/worker-fence.js +0 -690
- package/dist/workflows/v3/worker-fence.js.map +0 -1
- package/ecosystem.config.cjs +0 -15
|
@@ -1,4398 +0,0 @@
|
|
|
1
|
-
// src/core/dashboard-ipc-server.ts
|
|
2
|
-
import { createServer } from 'node:http';
|
|
3
|
-
import { execFileSync } from 'node:child_process';
|
|
4
|
-
import { readFileSync } from 'node:fs';
|
|
5
|
-
import { join } from 'node:path';
|
|
6
|
-
import { logger } from '../utils/logger.js';
|
|
7
|
-
import { cliAuthBind, verifyHmac } from '../dashboard/auth.js';
|
|
8
|
-
import { WORKFLOW_DAEMON_IPC_ROUTE_PREFIX } from '../workflows/v3/daemon-ipc-auth.js';
|
|
9
|
-
import { V3_SESSION_RUN_MUTATION_ROUTE_PREFIX } from '../workflows/v3/session-relay.js';
|
|
10
|
-
import { listenWithProbe } from '../utils/listen-with-probe.js';
|
|
11
|
-
import { dashboardSecretPath } from './dashboard-secret.js';
|
|
12
|
-
import * as sessionStore from '../services/session-store.js';
|
|
13
|
-
import { cliSupportsNativeUsage } from '../services/transcript-resolver.js';
|
|
14
|
-
import * as asyncTriggerStore from '../services/async-trigger-store.js';
|
|
15
|
-
import { resolveAsyncTriggerState, decideAsyncOwnership } from '../services/async-trigger-state.js';
|
|
16
|
-
import * as scheduleStore from '../services/schedule-store.js';
|
|
17
|
-
import * as groupsStore from '../services/groups-store.js';
|
|
18
|
-
import { createGroupWithBots, transferGroupOwner } from '../services/group-creator.js';
|
|
19
|
-
import * as oncallStore from '../services/oncall-store.js';
|
|
20
|
-
import * as brandStore from '../services/brand-store.js';
|
|
21
|
-
import * as sandboxStore from '../services/sandbox-store.js';
|
|
22
|
-
import * as backendTypeStore from '../services/backend-type-store.js';
|
|
23
|
-
import { isValidRiffBaseUrl, isValidRiffSandboxCluster } from '../adapters/backend/riff-backend.js';
|
|
24
|
-
import { ensureBackendAvailable } from '../services/backend-availability.js';
|
|
25
|
-
import * as cardPrefsStore from '../services/card-prefs-store.js';
|
|
26
|
-
import * as substituteModeStore from '../services/substitute-mode-store.js';
|
|
27
|
-
import { createCliAdapterSync } from '../adapters/cli/registry.js';
|
|
28
|
-
import { normalizeCliRuntimeConfig } from '../adapters/cli/runtime.js';
|
|
29
|
-
import { evaluateReadIsolationGate } from '../adapters/cli/read-isolation.js';
|
|
30
|
-
/** Whether read isolation can actually be ENFORCED for this bot right now — the
|
|
31
|
-
* SAME gate the worker fail-closes on (adapter support + no wrapperCli + macOS).
|
|
32
|
-
* The dashboard uses it to disable the toggle and to reject persisting an
|
|
33
|
-
* unenforceable flag, so flipping it on can never brick the bot's next session
|
|
34
|
-
* (the worker would otherwise refuse to start). Turning it OFF is always allowed. */
|
|
35
|
-
function readIsolationEnforceableFor(cfg) {
|
|
36
|
-
let adapterSupports = false;
|
|
37
|
-
try {
|
|
38
|
-
adapterSupports = createCliAdapterSync(cfg.cliId, cfg.cliPathOverride).supportsReadIsolation === true;
|
|
39
|
-
}
|
|
40
|
-
catch { /* CLI missing / unknown adapter → treat as unenforceable */ }
|
|
41
|
-
return evaluateReadIsolationGate({
|
|
42
|
-
configured: true,
|
|
43
|
-
adapterSupports,
|
|
44
|
-
wrapperCliSet: !!cfg.wrapperCli,
|
|
45
|
-
platform: process.platform,
|
|
46
|
-
sessionDataDirSet: true,
|
|
47
|
-
}).enabled;
|
|
48
|
-
}
|
|
49
|
-
function readIsolationEnforceable(larkAppId) {
|
|
50
|
-
try {
|
|
51
|
-
return readIsolationEnforceableFor(getBot(larkAppId).config);
|
|
52
|
-
}
|
|
53
|
-
catch {
|
|
54
|
-
return false;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
import * as observedBotsStore from '../services/observed-bots-store.js';
|
|
58
|
-
import { getDeploymentIdentity } from '../services/deployment-identity.js';
|
|
59
|
-
import { getBotUnionId } from '../services/bot-union-ids-store.js';
|
|
60
|
-
import * as grantPrefsStore from '../services/grant-prefs-store.js';
|
|
61
|
-
import { applyExactChatGrantRequest } from '../services/exact-chat-grant.js';
|
|
62
|
-
import { findConfigField, applyConfigField, coerceConfigValue } from '../services/bot-config-store.js';
|
|
63
|
-
import { globalBuiltinSkillInjectionDefault, resolveSkillInjectionSupport } from '../skills/injection-mode.js';
|
|
64
|
-
import { summaryRangeFromBotConfig, updateDashboardSummaryRange } from '../services/summary-range-store.js';
|
|
65
|
-
import { config } from '../config.js';
|
|
66
|
-
import { buildSafeInsightConversation, buildSafeInsightOverview, buildSafeInsightReport, buildSafeInsightTurnDetail } from '../services/insight/report.js';
|
|
67
|
-
import { readRawConfig, findEntryIndex, requireConfigPath, rmwBotEntry } from '../services/config-store.js';
|
|
68
|
-
import { setDefaultLocale, localeForBot, t } from '../i18n/index.js';
|
|
69
|
-
import { isLocale } from '../i18n/types.js';
|
|
70
|
-
import { readGlobalConfig } from '../global-config.js';
|
|
71
|
-
import { normalizeChatReplyMode, setChatReplyMode } from '../services/chat-reply-mode-store.js';
|
|
72
|
-
import * as chatFirstSeenStore from '../services/chat-first-seen-store.js';
|
|
73
|
-
import * as scheduler from './scheduler.js';
|
|
74
|
-
import { listActiveSessions, findActiveBySessionId, closeSession, getActiveSessionsRegistry, transferSession, deliverWriteLinkCardToOwners, forkWorker, suspendWorker, killWorker, latestPerBotEnvForRestart, getDaemonReplyCardUsageSnapshot, sessionSupportsWebTerminal, sendWorkerSessionInput, isSessionTransferring } from './worker-pool.js';
|
|
75
|
-
import { listOnlineDaemons } from '../utils/daemon-discovery.js';
|
|
76
|
-
import { isSessionStopped } from './session-liveness.js';
|
|
77
|
-
import { isSuspendableBackendType } from './persistent-backend.js';
|
|
78
|
-
import { getChatMode, replyMessage, sendMessage, resolveUnionIdFromOpenId, listThreadMessages, listChatMessages, listChatMessagesUntil, listChatBotMembers, getUserProfile, getUserProfileStrict, resolveAllowedUsersWithMap } from '../im/lark/client.js';
|
|
79
|
-
import { parseApiMessage, cardContentHasUpgradeFallback, resolveMergedCardContent, messageMentionsBot } from '../im/lark/message-parser.js';
|
|
80
|
-
import { resumeSession, spawnDashboardSession, activateQueuedSession, closeCliMismatchedSessionsForBot, suspendActiveSessionsForBot } from './session-manager.js';
|
|
81
|
-
import { parseSpawnRequest } from './session-create.js';
|
|
82
|
-
import { cleanupMaterializedDashboardImages, materializeDashboardImages } from './dashboard-images.js';
|
|
83
|
-
import { getCliDisplayName } from '../im/lark/card-builder.js';
|
|
84
|
-
import { sessionConfiguredRuntimeDisplayName } from './cli-runtime-display.js';
|
|
85
|
-
import { locateLimiter } from './dashboard-locate.js';
|
|
86
|
-
import { buildTerminalUrl } from './terminal-url.js';
|
|
87
|
-
import { dashboardEventBus } from './dashboard-events.js';
|
|
88
|
-
import { validateWorkingDir } from './working-dir.js';
|
|
89
|
-
import { isValidRoleChatId, resolveRole, resolveRoleFile, writeRoleFile, deleteRoleFile, readRoleInjectMode, writeRoleInjectMode, deleteRoleInjectMode } from './role-resolver.js';
|
|
90
|
-
import { deleteRoleProfileEntry, deleteRoleProfileIfEmpty, isValidRoleProfileId, listRoleProfileEntries, listRoleProfiles, MAX_ROLE_PROFILE_ENTRY_BYTES, readRoleProfileEntry, writeRoleProfileEntry, } from '../services/role-profile-store.js';
|
|
91
|
-
import { triggerSessionTurn } from './trigger-session.js';
|
|
92
|
-
import { validateTriggerRequest } from '../services/trigger-types.js';
|
|
93
|
-
import { resolveCliSelection, selectionKeyForBot } from '../setup/cli-selection.js';
|
|
94
|
-
import { checkCliAvailability } from '../setup/cli-availability.js';
|
|
95
|
-
import { enrichHistorySenders } from '../dashboard/history-senders.js';
|
|
96
|
-
import { listPendingAsks, submitAskFromDesktop } from './ask-broker.js';
|
|
97
|
-
import { getMessageListenerConfig, sanitizeMessageListenerUpdate, updateMessageListenerConfig, validateMessageListenerUpdate } from '../services/message-listener-store.js';
|
|
98
|
-
import { MAX_MESSAGE_LISTENER_PROMPT_BYTES, normalizeMessageListenerPreviewLimit, previewMessageListenerMatches, buildListenerBotAppIdToOpenId, collectListenerBotAppIds, renderMessageListenerInstruction, } from '../services/message-listener.js';
|
|
99
|
-
import { createMessageListenerRunPreview, createMessageListenerRunPreviewTurnId, getMessageListenerRunPreview, markMessageListenerRunPreviewFailed, markMessageListenerRunPreviewTriggered, } from '../services/message-listener-run-preview-store.js';
|
|
100
|
-
import { listChatMemberDisplays } from '../services/groups-store.js';
|
|
101
|
-
const MESSAGE_LISTENER_PREVIEW_WINDOW_MS = 24 * 60 * 60 * 1000;
|
|
102
|
-
let exactChatGrantHandler = applyExactChatGrantRequest;
|
|
103
|
-
/** Test seam: replace the exact-grant service without touching live Feishu/config state. */
|
|
104
|
-
export function setExactChatGrantHandler(handler) {
|
|
105
|
-
exactChatGrantHandler = handler ?? applyExactChatGrantRequest;
|
|
106
|
-
}
|
|
107
|
-
let botRenamer = null;
|
|
108
|
-
export function setBotRenamer(fn) {
|
|
109
|
-
botRenamer = fn;
|
|
110
|
-
}
|
|
111
|
-
let botAvatarChanger = null;
|
|
112
|
-
export function setBotAvatarChanger(fn) {
|
|
113
|
-
botAvatarChanger = fn;
|
|
114
|
-
}
|
|
115
|
-
import { composeRowFromActive, composeRowFromClosed, composeRowFromPersistedActive, feishuChatLink, setBotName as setRowsBotName, getBotName, } from './dashboard-rows.js';
|
|
116
|
-
import { getBotBrand, getBot, getBotOpenId, loadBotConfigs, readBotSkillPolicy, getBotTuiSlashAllow } from '../bot-registry.js';
|
|
117
|
-
import { normalizeKanbanColumn, normalizeKanbanPosition, normalizeSessionTitle } from './session-board.js';
|
|
118
|
-
import { validateSlashInjection } from './slash-inject.js';
|
|
119
|
-
import { validateRoleLibraryPath } from './role-library.js';
|
|
120
|
-
import { repinSessionWorkingDir } from './session-cwd.js';
|
|
121
|
-
import { authorizeSessionScopedIpc } from './daemon-ipc-session-auth.js';
|
|
122
|
-
import { normalizeSessionTitleSource, updateSessionTitle } from './session-title.js';
|
|
123
|
-
import { requestAgentSessionRename } from './session-rename.js';
|
|
124
|
-
import { ChatRenameCooldown, ChatRenameSerialQueue, normalizeLarkChatName } from './chat-rename.js';
|
|
125
|
-
import { sessionAnchorId, larkTransportEnabled } from './types.js';
|
|
126
|
-
import { attachSkillPolicy, detachSkillPolicy } from './skills/im-command.js';
|
|
127
|
-
import { readSkillRegistry } from '../services/skill-registry-store.js';
|
|
128
|
-
import { commitDeviceIsolationActivation, DEVICE_ISOLATION_COMMIT_PATH, DEVICE_ISOLATION_PREPARE_PATH, DEVICE_ISOLATION_RELEASE_PATH, logDeviceIsolationActivationError, prepareDeviceIsolationActivation, releaseDeviceIsolationActivation, } from './device-isolation-daemon.js';
|
|
129
|
-
// Daemon process start (module load ≈ daemon boot). Used by the SSE snapshot
|
|
130
|
-
// replay to bound the "recently closed" set to sessions that flipped
|
|
131
|
-
// active→closed during THIS run — i.e. restore-time zombies — without replaying
|
|
132
|
-
// the entire closed-session history on every connect.
|
|
133
|
-
const PROCESS_START_MS = Date.now();
|
|
134
|
-
const routes = [];
|
|
135
|
-
/** Requests that crossed the server-wide trusted-host gate. The legacy
|
|
136
|
-
* write-link handlers consult this marker so they do not verify (and consume)
|
|
137
|
-
* the same one-shot nonce twice. */
|
|
138
|
-
const trustedHostRequests = new WeakSet();
|
|
139
|
-
export function isTrustedHostIpcRequest(req) {
|
|
140
|
-
return trustedHostRequests.has(req);
|
|
141
|
-
}
|
|
142
|
-
/** Register a handler. Path supports `:name` segments captured into the params object. */
|
|
143
|
-
export function ipcRoute(method, path, handler) {
|
|
144
|
-
const keys = [];
|
|
145
|
-
const pattern = new RegExp('^' + path.replace(/:([a-zA-Z]+)/g, (_, k) => { keys.push(k); return '([^/]+)'; }) + '$');
|
|
146
|
-
routes.push({ method: method.toUpperCase(), pattern, keys, handler });
|
|
147
|
-
}
|
|
148
|
-
export function jsonRes(res, status, body) {
|
|
149
|
-
res.writeHead(status, { 'content-type': 'application/json' });
|
|
150
|
-
res.end(JSON.stringify(body));
|
|
151
|
-
}
|
|
152
|
-
export class JsonBodyTooLargeError extends Error {
|
|
153
|
-
maxBytes;
|
|
154
|
-
constructor(maxBytes) {
|
|
155
|
-
super(`JSON request body exceeds ${maxBytes} bytes`);
|
|
156
|
-
this.maxBytes = maxBytes;
|
|
157
|
-
this.name = 'JsonBodyTooLargeError';
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
export class AbortDeadlineError extends Error {
|
|
161
|
-
label;
|
|
162
|
-
timeoutMs;
|
|
163
|
-
constructor(label, timeoutMs) {
|
|
164
|
-
super(`${label} timed out after ${timeoutMs}ms`);
|
|
165
|
-
this.label = label;
|
|
166
|
-
this.timeoutMs = timeoutMs;
|
|
167
|
-
this.name = 'AbortDeadlineError';
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
/** 校验跨进程 JSON envelope,只接受普通对象和完整、精确的自有字段集合。 */
|
|
171
|
-
export function hasExactSafeJsonKeys(value, expectedKeys) {
|
|
172
|
-
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
173
|
-
return false;
|
|
174
|
-
const prototype = Object.getPrototypeOf(value);
|
|
175
|
-
if (prototype !== Object.prototype && prototype !== null)
|
|
176
|
-
return false;
|
|
177
|
-
const keys = Object.keys(value);
|
|
178
|
-
if (keys.length !== expectedKeys.length)
|
|
179
|
-
return false;
|
|
180
|
-
if (['__proto__', 'prototype', 'constructor'].some(key => Object.hasOwn(value, key))) {
|
|
181
|
-
return false;
|
|
182
|
-
}
|
|
183
|
-
const expected = new Set(expectedKeys);
|
|
184
|
-
return keys.every(key => expected.has(key));
|
|
185
|
-
}
|
|
186
|
-
/**
|
|
187
|
-
* 为支持 AbortSignal 的底层操作设置硬截止时间。Promise.race 保证调用方按时释放
|
|
188
|
-
* in-flight 状态,AbortController 同时取消仍在执行的网络或子进程操作。
|
|
189
|
-
*/
|
|
190
|
-
export async function runWithAbortDeadline(label, timeoutMs, task) {
|
|
191
|
-
if (!Number.isSafeInteger(timeoutMs) || timeoutMs <= 0) {
|
|
192
|
-
throw new RangeError('timeoutMs must be a positive safe integer');
|
|
193
|
-
}
|
|
194
|
-
const controller = new AbortController();
|
|
195
|
-
const deadlineAt = Date.now() + timeoutMs;
|
|
196
|
-
let timer;
|
|
197
|
-
const timeout = new Promise((_resolve, reject) => {
|
|
198
|
-
timer = setTimeout(() => {
|
|
199
|
-
const error = new AbortDeadlineError(label, timeoutMs);
|
|
200
|
-
controller.abort(error);
|
|
201
|
-
reject(error);
|
|
202
|
-
}, timeoutMs);
|
|
203
|
-
timer.unref?.();
|
|
204
|
-
});
|
|
205
|
-
try {
|
|
206
|
-
return await Promise.race([task(controller.signal, deadlineAt), timeout]);
|
|
207
|
-
}
|
|
208
|
-
finally {
|
|
209
|
-
if (timer)
|
|
210
|
-
clearTimeout(timer);
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
export async function readJsonBody(req, maxBytes) {
|
|
214
|
-
if (maxBytes !== undefined && (!Number.isSafeInteger(maxBytes) || maxBytes <= 0)) {
|
|
215
|
-
throw new RangeError('maxBytes must be a positive safe integer');
|
|
216
|
-
}
|
|
217
|
-
if (maxBytes !== undefined) {
|
|
218
|
-
const declared = req.headers?.['content-length'];
|
|
219
|
-
const declaredBytes = typeof declared === 'string' && /^\d+$/.test(declared)
|
|
220
|
-
? Number(declared)
|
|
221
|
-
: undefined;
|
|
222
|
-
if (declaredBytes !== undefined && declaredBytes > maxBytes) {
|
|
223
|
-
req.once('error', () => { });
|
|
224
|
-
req.resume();
|
|
225
|
-
throw new JsonBodyTooLargeError(maxBytes);
|
|
226
|
-
}
|
|
227
|
-
const body = await new Promise((resolve, reject) => {
|
|
228
|
-
const chunks = [];
|
|
229
|
-
let totalBytes = 0;
|
|
230
|
-
let settled = false;
|
|
231
|
-
const cleanup = () => {
|
|
232
|
-
req.off('data', onData);
|
|
233
|
-
req.off('end', onEnd);
|
|
234
|
-
req.off('error', onError);
|
|
235
|
-
req.off('aborted', onAborted);
|
|
236
|
-
};
|
|
237
|
-
const rejectOnce = (error, drain = false) => {
|
|
238
|
-
if (settled)
|
|
239
|
-
return;
|
|
240
|
-
settled = true;
|
|
241
|
-
cleanup();
|
|
242
|
-
if (drain) {
|
|
243
|
-
// 不销毁 keep-alive socket,只丢弃剩余正文,让调用方仍能返回 413。
|
|
244
|
-
req.once('error', () => { });
|
|
245
|
-
req.resume();
|
|
246
|
-
}
|
|
247
|
-
reject(error);
|
|
248
|
-
};
|
|
249
|
-
const onData = (raw) => {
|
|
250
|
-
if (settled)
|
|
251
|
-
return;
|
|
252
|
-
const chunk = Buffer.isBuffer(raw) ? raw : Buffer.from(raw);
|
|
253
|
-
totalBytes += chunk.byteLength;
|
|
254
|
-
if (totalBytes > maxBytes) {
|
|
255
|
-
chunks.length = 0;
|
|
256
|
-
rejectOnce(new JsonBodyTooLargeError(maxBytes), true);
|
|
257
|
-
return;
|
|
258
|
-
}
|
|
259
|
-
chunks.push(chunk);
|
|
260
|
-
};
|
|
261
|
-
const onEnd = () => {
|
|
262
|
-
if (settled)
|
|
263
|
-
return;
|
|
264
|
-
settled = true;
|
|
265
|
-
cleanup();
|
|
266
|
-
resolve(Buffer.concat(chunks, totalBytes));
|
|
267
|
-
};
|
|
268
|
-
const onError = (error) => rejectOnce(error);
|
|
269
|
-
const onAborted = () => rejectOnce(new Error('request aborted'));
|
|
270
|
-
req.on('data', onData);
|
|
271
|
-
req.once('end', onEnd);
|
|
272
|
-
req.once('error', onError);
|
|
273
|
-
req.once('aborted', onAborted);
|
|
274
|
-
});
|
|
275
|
-
if (body.byteLength === 0)
|
|
276
|
-
return {};
|
|
277
|
-
return JSON.parse(body.toString('utf8'));
|
|
278
|
-
}
|
|
279
|
-
const chunks = [];
|
|
280
|
-
for await (const c of req) {
|
|
281
|
-
const chunk = Buffer.isBuffer(c) ? c : Buffer.from(c);
|
|
282
|
-
chunks.push(chunk);
|
|
283
|
-
}
|
|
284
|
-
if (chunks.length === 0)
|
|
285
|
-
return {};
|
|
286
|
-
return JSON.parse(Buffer.concat(chunks).toString('utf8'));
|
|
287
|
-
}
|
|
288
|
-
// ─── Trusted-host auth (loopback + route-bound HMAC) ────────────────────────
|
|
289
|
-
//
|
|
290
|
-
// Production start enables a server-wide gate: loopback is connectivity, not
|
|
291
|
-
// identity, because a Linux bwrap CLI keeps host networking for model egress.
|
|
292
|
-
// Every data/read or mutation route therefore requires proof that the caller
|
|
293
|
-
// can read ~/.botmux/.dashboard-secret. Only health and a tiny set of handlers
|
|
294
|
-
// with their own exact live-worker capability checks are admitted without it.
|
|
295
|
-
// The two write-link handlers retain their historical local check for unit-test
|
|
296
|
-
// compatibility; production requests arrive pre-authorized and are marked in
|
|
297
|
-
// trustedHostRequests so the one-shot nonce is not consumed twice.
|
|
298
|
-
let injectedIpcSecret = null;
|
|
299
|
-
/** Test seam: override the secret used to verify token-route HMAC. */
|
|
300
|
-
export function setIpcAuthSecret(secret) { injectedIpcSecret = secret; }
|
|
301
|
-
function ipcAuthSecret() {
|
|
302
|
-
if (injectedIpcSecret)
|
|
303
|
-
return injectedIpcSecret;
|
|
304
|
-
try {
|
|
305
|
-
return readFileSync(dashboardSecretPath(), 'utf8').trim() || null;
|
|
306
|
-
}
|
|
307
|
-
catch {
|
|
308
|
-
return null;
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
/** Authenticate legacy terminal-token routes with the machine-local dashboard
|
|
312
|
-
* secret. Workflow v3 mutations intentionally use their separate, full-request
|
|
313
|
-
* protocol (`workflows/v3/daemon-ipc-auth`) and must never call this bare
|
|
314
|
-
* ts:nonce verifier. */
|
|
315
|
-
export function ipcHmacAuthorized(req, bind) {
|
|
316
|
-
if (trustedHostRequests.has(req))
|
|
317
|
-
return true;
|
|
318
|
-
const secret = ipcAuthSecret();
|
|
319
|
-
if (!secret)
|
|
320
|
-
return false; // fail-closed: no secret on disk → nobody can sign
|
|
321
|
-
const ts = req.headers['x-botmux-cli-ts'];
|
|
322
|
-
const nonce = req.headers['x-botmux-cli-nonce'];
|
|
323
|
-
const sig = req.headers['x-botmux-cli-auth'];
|
|
324
|
-
if (typeof ts !== 'string' || typeof nonce !== 'string' || typeof sig !== 'string')
|
|
325
|
-
return false;
|
|
326
|
-
return verifyHmac(secret, { ts, nonce, sig }, req.socket.remoteAddress ?? '', bind).ok;
|
|
327
|
-
}
|
|
328
|
-
function tokenRouteAuthorized(req, bind) {
|
|
329
|
-
return ipcHmacAuthorized(req, bind);
|
|
330
|
-
}
|
|
331
|
-
function routeHasPublicAccess(method, pathname) {
|
|
332
|
-
// Liveness contains no data and performs no mutation. /healthz is the
|
|
333
|
-
// core-only public alias of /__health (riff's sandbox launcher polls it).
|
|
334
|
-
return method === 'GET' && (pathname === '/__health' || pathname === '/healthz');
|
|
335
|
-
}
|
|
336
|
-
/**
|
|
337
|
-
* Core-only ONLY: the exact riff-facing routes that bypass the trusted-host HMAC
|
|
338
|
-
* when the daemon runs headless in riff's sandbox. Everything else STILL requires
|
|
339
|
-
* the HMAC (codex P1: authRequired:false opened all 96 IPC routes — a co-resident
|
|
340
|
-
* model turn could read/perturb sessions, scheduler, mutations). This is a tight
|
|
341
|
-
* allowlist of drive-my-own-turn + poll-my-own-output surfaces:
|
|
342
|
-
* POST /api/trigger (start a turn)
|
|
343
|
-
* GET /api/sessions/:id/trigger-result (poll final)
|
|
344
|
-
* GET /api/sessions/:id/insight (poll conversation/progress)
|
|
345
|
-
* `/api/asks/answer` is deliberately EXCLUDED — it is askId-keyed with no
|
|
346
|
-
* session/turn binding, so exposing it would let any co-resident turn hijack
|
|
347
|
-
* another pending ask (codex). riff's async main-link needs no awaiting_input;
|
|
348
|
-
* a future clarify path must be a sessionId+interaction-bound endpoint.
|
|
349
|
-
*/
|
|
350
|
-
function routeIsCoreOnlyPublic(method, pathname) {
|
|
351
|
-
if (method === 'POST' && pathname === '/api/trigger')
|
|
352
|
-
return true;
|
|
353
|
-
if (method === 'GET') {
|
|
354
|
-
return /^\/api\/sessions\/[^/]+\/trigger-result$/.test(pathname)
|
|
355
|
-
|| /^\/api\/sessions\/[^/]+\/insight$/.test(pathname);
|
|
356
|
-
}
|
|
357
|
-
return false;
|
|
358
|
-
}
|
|
359
|
-
function routeHasNarrowUntrustedAuth(method, pathname) {
|
|
360
|
-
// The receiver action endpoint performs its own rotating worker-capability
|
|
361
|
-
// verification and then enters the durable action ledger. Keeping this one
|
|
362
|
-
// aperture is what preserves managed meeting actions from inside bwrap.
|
|
363
|
-
if (method === 'POST' && pathname === '/api/vc-meetings/action-request')
|
|
364
|
-
return true;
|
|
365
|
-
// These two CLI-in-sandbox endpoints verify the same rotating capability in
|
|
366
|
-
// their handlers and bind it to body.sessionId. They cannot be bare loopback
|
|
367
|
-
// exceptions: a receiver that learned another session id could otherwise
|
|
368
|
-
// forge readiness or an ask for that session.
|
|
369
|
-
if (method === 'POST' && pathname === '/api/session-ready')
|
|
370
|
-
return true;
|
|
371
|
-
if (method === 'POST' && pathname === '/api/asks')
|
|
372
|
-
return true;
|
|
373
|
-
// botmux slash / botmux role switch(角色切换)/ botmux delete(关闭自身):合法调用方
|
|
374
|
-
// 是会话内的 CLI 自身,沙箱 / 读隔离下读不到 host secret。handler 内验证
|
|
375
|
-
// 该会话的 rotating per-turn
|
|
376
|
-
// capability 并绑定到 URL 里的 sessionId(同 /api/asks 姿势)——capability 只
|
|
377
|
-
// 证明「我是这个会话当前这一轮的 CLI」,选不了别的会话。
|
|
378
|
-
if (method === 'POST' && /^\/api\/sessions\/[^/]+\/(?:slash|cd|close|chat-rename)$/.test(pathname))
|
|
379
|
-
return true;
|
|
380
|
-
if (method === 'POST' && pathname === '/api/hooks/emit')
|
|
381
|
-
return true;
|
|
382
|
-
if (method === 'POST' && pathname === '/api/attention')
|
|
383
|
-
return true;
|
|
384
|
-
// Workflow v3 mutations carry their own domain-separated full-envelope
|
|
385
|
-
// protocol (request signature over method/path/exact body with nonce
|
|
386
|
-
// anti-replay + boot audience, signed response), keyed on the same host
|
|
387
|
-
// secret as the outer gate. The handler fail-closes on that envelope, which
|
|
388
|
-
// is strictly stronger binding than the outer ts:nonce HMAC, so the prefix
|
|
389
|
-
// is admitted here instead of being double-signed with the same secret.
|
|
390
|
-
if (method === 'POST' && pathname.startsWith(`${WORKFLOW_DAEMON_IPC_ROUTE_PREFIX}/`))
|
|
391
|
-
return true;
|
|
392
|
-
// Workflow v3 session relay: sandboxed / read-isolated chat CLIs cannot read
|
|
393
|
-
// the host secret, so these handlers verify the session's rotating per-turn
|
|
394
|
-
// capability and re-derive the caller tuple from the daemon's own live
|
|
395
|
-
// session record (same posture as /api/asks above).
|
|
396
|
-
if (method === 'POST' && pathname.startsWith(`${V3_SESSION_RUN_MUTATION_ROUTE_PREFIX}/`))
|
|
397
|
-
return true;
|
|
398
|
-
return false;
|
|
399
|
-
}
|
|
400
|
-
function trustedHostAuthorized(req, pathname, port, secret) {
|
|
401
|
-
const ts = req.headers['x-botmux-cli-ts'];
|
|
402
|
-
const nonce = req.headers['x-botmux-cli-nonce'];
|
|
403
|
-
const sig = req.headers['x-botmux-cli-auth'];
|
|
404
|
-
if (typeof ts !== 'string' || typeof nonce !== 'string' || typeof sig !== 'string') {
|
|
405
|
-
return { ok: false, reason: 'missing_headers' };
|
|
406
|
-
}
|
|
407
|
-
const bind = cliAuthBind(req.method ?? 'GET', pathname, port);
|
|
408
|
-
const verified = verifyHmac(secret, { ts, nonce, sig }, req.socket.remoteAddress ?? '', bind);
|
|
409
|
-
return verified.ok
|
|
410
|
-
? { ok: true }
|
|
411
|
-
: { ok: false, reason: verified.reason ?? 'unauthorized' };
|
|
412
|
-
}
|
|
413
|
-
ipcRoute('GET', '/__health', (_req, res) => {
|
|
414
|
-
jsonRes(res, 200, { ok: true });
|
|
415
|
-
});
|
|
416
|
-
// Core-only readiness barrier (codex P1-3): the daemon binds its HTTP port BEFORE
|
|
417
|
-
// restoreActiveSessions / v3 cold-attach / scheduler finish, so a launcher that
|
|
418
|
-
// triggers the instant the port answers would race durable restore (transient
|
|
419
|
-
// not_found / re-fire). /healthz returns 503 until the daemon marks itself ready
|
|
420
|
-
// (setCoreOnlyReady, called AFTER restore in daemon.ts). Non-core-only daemons
|
|
421
|
-
// never set this gate, so /healthz stays an unconditional 200 there.
|
|
422
|
-
let coreOnlyReadinessGate = false; // true only in core-only, until ready
|
|
423
|
-
let coreOnlyReady = false;
|
|
424
|
-
export function armCoreOnlyReadinessGate() { coreOnlyReadinessGate = true; }
|
|
425
|
-
export function setCoreOnlyReady() { coreOnlyReady = true; }
|
|
426
|
-
/** @internal test-only: reset the core-only readiness gate between cases. */
|
|
427
|
-
export function __testOnly_resetCoreOnlyReadiness() { coreOnlyReadinessGate = false; coreOnlyReady = false; }
|
|
428
|
-
/** True when the readiness gate is armed (core-only) but restore hasn't finished.
|
|
429
|
-
* The server-level gate returns 503 for the public control routes in this state,
|
|
430
|
-
* and /healthz reports 'starting' — a barrier so riff can't trigger into a racing
|
|
431
|
-
* durable restore even if it skips the healthz probe (codex P1). */
|
|
432
|
-
function coreOnlyNotReady() { return coreOnlyReadinessGate && !coreOnlyReady; }
|
|
433
|
-
// Public alias for core-only: riff's sandbox launcher polls GET /healthz to know
|
|
434
|
-
// the service is FULLY up (bound AND restore-complete). 200 {ok:true} once ready;
|
|
435
|
-
// 503 {ok:false,status:'starting'} while the readiness gate is armed but not ready.
|
|
436
|
-
ipcRoute('GET', '/healthz', (_req, res) => {
|
|
437
|
-
if (coreOnlyNotReady()) {
|
|
438
|
-
return jsonRes(res, 503, { ok: false, status: 'starting' });
|
|
439
|
-
}
|
|
440
|
-
jsonRes(res, 200, { ok: true });
|
|
441
|
-
});
|
|
442
|
-
export { composeRowFromActive, composeRowFromClosed, composeRowFromPersistedActive };
|
|
443
|
-
// Re-export setBotName for backwards-compatible imports (daemon.ts). Both
|
|
444
|
-
// callers (this module's cachedBotName + dashboard-rows' cachedBotName) need
|
|
445
|
-
// to be primed; here we forward to the rows module which is the canonical
|
|
446
|
-
// holder.
|
|
447
|
-
export function setBotName(name) { setRowsBotName(name); }
|
|
448
|
-
function composeDashboardSessionRows() {
|
|
449
|
-
const active = listActiveSessions().map(composeRowFromActive);
|
|
450
|
-
const activeIds = new Set(active.map(row => row.sessionId));
|
|
451
|
-
const persisted = sessionStore.listSessions();
|
|
452
|
-
const unregisteredActive = persisted
|
|
453
|
-
.filter(session => session.status === 'active' && !activeIds.has(session.sessionId))
|
|
454
|
-
.map(composeRowFromPersistedActive);
|
|
455
|
-
const closed = persisted
|
|
456
|
-
.filter(session => session.status === 'closed' && !activeIds.has(session.sessionId))
|
|
457
|
-
.map(composeRowFromClosed);
|
|
458
|
-
return [...active, ...unregisteredActive, ...closed];
|
|
459
|
-
}
|
|
460
|
-
// The daemon's own larkAppId, primed at startup. Required for the groups
|
|
461
|
-
// endpoints below which proxy calls into groups-store on this bot's behalf.
|
|
462
|
-
let cachedLarkAppId = '';
|
|
463
|
-
export function setLarkAppId(id) { cachedLarkAppId = id; }
|
|
464
|
-
async function handleDeviceIsolationActivationRoute(req, res, handler) {
|
|
465
|
-
// Keep this explicit even though production enables the server-wide gate:
|
|
466
|
-
// unit-test/dev servers must not accidentally turn this authority-bearing
|
|
467
|
-
// transition into a bare-loopback endpoint.
|
|
468
|
-
if (!ipcHmacAuthorized(req)) {
|
|
469
|
-
return jsonRes(res, 401, { ok: false, error: 'unauthorized' });
|
|
470
|
-
}
|
|
471
|
-
try {
|
|
472
|
-
const body = await readJsonBody(req);
|
|
473
|
-
const result = await handler(body);
|
|
474
|
-
jsonRes(res, result.status, result.body);
|
|
475
|
-
}
|
|
476
|
-
catch (error) {
|
|
477
|
-
logDeviceIsolationActivationError(error);
|
|
478
|
-
jsonRes(res, 503, { ok: false, error: 'activation_unavailable' });
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
|
-
ipcRoute('POST', DEVICE_ISOLATION_PREPARE_PATH, (req, res) => handleDeviceIsolationActivationRoute(req, res, prepareDeviceIsolationActivation));
|
|
482
|
-
ipcRoute('POST', DEVICE_ISOLATION_COMMIT_PATH, (req, res) => handleDeviceIsolationActivationRoute(req, res, commitDeviceIsolationActivation));
|
|
483
|
-
ipcRoute('POST', DEVICE_ISOLATION_RELEASE_PATH, (req, res) => handleDeviceIsolationActivationRoute(req, res, releaseDeviceIsolationActivation));
|
|
484
|
-
// ─── Pending asks (trusted Desktop/dashboard operator only) ─────────────────
|
|
485
|
-
ipcRoute('GET', '/api/asks/pending', (req, res) => {
|
|
486
|
-
if (!isTrustedHostIpcRequest(req)) {
|
|
487
|
-
return jsonRes(res, 403, { ok: false, error: 'trusted_host_required' });
|
|
488
|
-
}
|
|
489
|
-
const asks = listPendingAsks().map((ask) => ({
|
|
490
|
-
askId: ask.askId,
|
|
491
|
-
sessionId: ask.sessionId,
|
|
492
|
-
larkAppId: ask.larkAppId,
|
|
493
|
-
chatId: ask.chatId,
|
|
494
|
-
rootMessageId: ask.rootMessageId,
|
|
495
|
-
questions: ask.questions,
|
|
496
|
-
deadlineAt: ask.deadlineAt,
|
|
497
|
-
createdAt: ask.createdAt,
|
|
498
|
-
}));
|
|
499
|
-
return jsonRes(res, 200, { asks });
|
|
500
|
-
});
|
|
501
|
-
ipcRoute('POST', '/api/asks/answer', async (req, res) => {
|
|
502
|
-
if (!isTrustedHostIpcRequest(req)) {
|
|
503
|
-
return jsonRes(res, 403, { ok: false, error: 'trusted_host_required' });
|
|
504
|
-
}
|
|
505
|
-
let body;
|
|
506
|
-
try {
|
|
507
|
-
body = await readJsonBody(req);
|
|
508
|
-
}
|
|
509
|
-
catch {
|
|
510
|
-
return jsonRes(res, 400, { ok: false, error: 'bad_json' });
|
|
511
|
-
}
|
|
512
|
-
if (!body.askId || !Array.isArray(body.selections)) {
|
|
513
|
-
return jsonRes(res, 400, { ok: false, error: 'askId_and_selections_required' });
|
|
514
|
-
}
|
|
515
|
-
const outcome = submitAskFromDesktop({
|
|
516
|
-
askId: body.askId,
|
|
517
|
-
selections: body.selections,
|
|
518
|
-
by: typeof body.by === 'string' ? body.by : 'desktop',
|
|
519
|
-
});
|
|
520
|
-
if (outcome !== 'accepted') {
|
|
521
|
-
return jsonRes(res, 409, { ok: false, error: outcome });
|
|
522
|
-
}
|
|
523
|
-
return jsonRes(res, 200, { ok: true, outcome });
|
|
524
|
-
});
|
|
525
|
-
ipcRoute('GET', '/api/sessions', (_req, res) => {
|
|
526
|
-
// Runtime active first, then persisted active rows that restore deliberately
|
|
527
|
-
// left detached, then closed history. Persisted-active must never be projected
|
|
528
|
-
// through composeRowFromClosed: teardown uncertainty is not a close.
|
|
529
|
-
jsonRes(res, 200, { sessions: composeDashboardSessionRows() });
|
|
530
|
-
});
|
|
531
|
-
ipcRoute('GET', '/api/sessions/:sessionId', (_req, res, params) => {
|
|
532
|
-
const ds = findActiveBySessionId(params.sessionId);
|
|
533
|
-
if (ds)
|
|
534
|
-
return jsonRes(res, 200, { session: composeRowFromActive(ds) });
|
|
535
|
-
const persisted = sessionStore.listSessions().find(s => s.sessionId === params.sessionId);
|
|
536
|
-
if (persisted) {
|
|
537
|
-
return jsonRes(res, 200, {
|
|
538
|
-
session: persisted.status === 'active'
|
|
539
|
-
? composeRowFromPersistedActive(persisted)
|
|
540
|
-
: composeRowFromClosed(persisted),
|
|
541
|
-
});
|
|
542
|
-
}
|
|
543
|
-
jsonRes(res, 404, { error: 'not_found' });
|
|
544
|
-
});
|
|
545
|
-
/** Low-frequency card-display read used by `botmux send`. Keeping the
|
|
546
|
-
* transcript reader and per-bot visibility decision in the resident daemon
|
|
547
|
-
* preserves its incremental cache and live config instead of making every
|
|
548
|
-
* short-lived CLI process rescan the Session or guess from sandboxed files. */
|
|
549
|
-
ipcRoute('GET', '/api/sessions/:sessionId/usage', (_req, res, params) => {
|
|
550
|
-
const ds = findActiveBySessionId(params.sessionId);
|
|
551
|
-
if (!ds)
|
|
552
|
-
return jsonRes(res, 404, { error: 'not_found' });
|
|
553
|
-
jsonRes(res, 200, { usage: getDaemonReplyCardUsageSnapshot(ds) });
|
|
554
|
-
});
|
|
555
|
-
/** Canonical daemon-side close used by the dashboard and `botmux delete`.
|
|
556
|
-
* Host callers authenticate with HMAC; a read-isolated CLI may close only its
|
|
557
|
-
* exact live session with the rotating per-turn capability. */
|
|
558
|
-
ipcRoute('POST', '/api/sessions/:sessionId/close', async (req, res, params) => {
|
|
559
|
-
const body = await readJsonBody(req)
|
|
560
|
-
.catch(() => ({}));
|
|
561
|
-
const ds = findActiveBySessionId(params.sessionId);
|
|
562
|
-
const auth = sessionCliIpcAuth(req, ds, params.sessionId, body);
|
|
563
|
-
if (!auth.ok)
|
|
564
|
-
return jsonRes(res, 403, { ok: false, error: auth.error });
|
|
565
|
-
const r = await closeSession(params.sessionId);
|
|
566
|
-
jsonRes(res, 200, r);
|
|
567
|
-
});
|
|
568
|
-
/** Post a scope-aware "restarting" notice into the session's Lark thread/chat,
|
|
569
|
-
* mirroring the /resume route — so a Feishu-side observer sees why the CLI just
|
|
570
|
-
* restarted under them (the IM `/restart` command and the card button notify
|
|
571
|
-
* too; the dashboard was the lone silent path). `fresh` = the worker was gone
|
|
572
|
-
* and we re-forked it (revive) rather than doing an in-place CLI restart.
|
|
573
|
-
* Best-effort and fire-and-forget; never blocks the HTTP response. */
|
|
574
|
-
function postRestartNotice(ds, fresh) {
|
|
575
|
-
if (!ds.larkAppId)
|
|
576
|
-
return;
|
|
577
|
-
// No-transport session (apiOnly bot or HTTP virtual chat) has no Feishu chat
|
|
578
|
-
// to post a restart notice into — skip (the raw sendMessage/replyMessage below
|
|
579
|
-
// bypass sessionReply's gate). Best-effort path; a silent skip is correct.
|
|
580
|
-
if (!larkTransportEnabled({ chatId: ds.chatId, apiOnly: getBot(ds.larkAppId).config.apiOnly }))
|
|
581
|
-
return;
|
|
582
|
-
const loc = localeForBot(ds.larkAppId);
|
|
583
|
-
const botCfg = getBot(ds.larkAppId).config;
|
|
584
|
-
const cliName = sessionConfiguredRuntimeDisplayName(ds.session, botCfg.cliRuntime)
|
|
585
|
-
?? getCliDisplayName(ds.session.cliId ?? botCfg.cliId ?? 'claude-code');
|
|
586
|
-
const text = fresh
|
|
587
|
-
? t('card.action.restarted_fresh', { cliName }, loc)
|
|
588
|
-
: t('cmd.restart.in_progress', { cliName }, loc);
|
|
589
|
-
const notice = JSON.stringify({ text });
|
|
590
|
-
if (ds.scope === 'chat' && ds.chatId) {
|
|
591
|
-
getChatMode(ds.larkAppId, ds.chatId, { forceRefresh: true })
|
|
592
|
-
.then((mode) => mode === 'topic' && ds.session.rootMessageId
|
|
593
|
-
? replyMessage(ds.larkAppId, ds.session.rootMessageId, notice, 'text', true)
|
|
594
|
-
: sendMessage(ds.larkAppId, ds.chatId, notice, 'text'))
|
|
595
|
-
.catch(err => logger.debug(`[restart] failed to post chat-scope restart notice: ${err}`));
|
|
596
|
-
}
|
|
597
|
-
else if (ds.session.rootMessageId) {
|
|
598
|
-
replyMessage(ds.larkAppId, ds.session.rootMessageId, notice, 'text', true)
|
|
599
|
-
.catch(err => logger.debug(`[restart] failed to post thread-scope restart notice: ${err}`));
|
|
600
|
-
}
|
|
601
|
-
}
|
|
602
|
-
ipcRoute('POST', '/api/sessions/:sessionId/restart', (_req, res, params) => {
|
|
603
|
-
const ds = findActiveBySessionId(params.sessionId);
|
|
604
|
-
if (!ds)
|
|
605
|
-
return jsonRes(res, 404, { ok: false, error: 'session_not_active' });
|
|
606
|
-
if (isSessionTransferring(ds)) {
|
|
607
|
-
return jsonRes(res, 409, { ok: false, error: 'session_transferring' });
|
|
608
|
-
}
|
|
609
|
-
// Adopt/observed sessions: botmux never owned the CLI — restarting would kill
|
|
610
|
-
// the user's real tmux/zellij pane. Hard-reject (the worker self-guards too).
|
|
611
|
-
if (ds.adoptedFrom || ds.initConfig?.adoptMode) {
|
|
612
|
-
return jsonRes(res, 409, { ok: false, error: 'adopt_restart_unsupported' });
|
|
613
|
-
}
|
|
614
|
-
const cliId = ds.session.cliId ?? 'unknown';
|
|
615
|
-
if (ds.worker && !ds.worker.killed) {
|
|
616
|
-
// Live worker → in-place CLI restart (kills the CLI, respawns with --resume).
|
|
617
|
-
// 捎带最新 per-bot env:dashboard 改完 env 后重启才真正生效(与 /restart 同逻辑)。
|
|
618
|
-
try {
|
|
619
|
-
ds.workerReady = false;
|
|
620
|
-
ds.worker.send({ type: 'restart', env: latestPerBotEnvForRestart(ds) });
|
|
621
|
-
}
|
|
622
|
-
catch (err) {
|
|
623
|
-
return jsonRes(res, 502, { ok: false, error: String(err) });
|
|
624
|
-
}
|
|
625
|
-
postRestartNotice(ds, false);
|
|
626
|
-
return jsonRes(res, 200, { ok: true, sessionId: params.sessionId, cliId, revived: false });
|
|
627
|
-
}
|
|
628
|
-
// Worker is gone but the session is still active — idle-suspended (over the
|
|
629
|
-
// per-bot cap), lazy-restored after a daemon restart, or crash-loop-stopped.
|
|
630
|
-
// Revive it the same way the Feishu card restart does (forkWorker), so the
|
|
631
|
-
// dashboard isn't a dead-end: a 409 here would leave NO working control to
|
|
632
|
-
// bring the CLI back (the resume button only shows for closed sessions).
|
|
633
|
-
forkWorker(ds, '', ds.hasHistory);
|
|
634
|
-
postRestartNotice(ds, true);
|
|
635
|
-
jsonRes(res, 200, { ok: true, sessionId: params.sessionId, cliId, revived: true });
|
|
636
|
-
});
|
|
637
|
-
/** Manually suspend one active session: kill the worker + CLI/pane, session
|
|
638
|
-
* stays active and cold-resumes from its transcript on the next message —
|
|
639
|
-
* the same semantics the idle-worker sweeper applies over the live cap.
|
|
640
|
-
* Primary use: `botmux suspend --isolated` after a credential rotation, so
|
|
641
|
-
* isolated bots' next cold spawn re-provisions the freshest creds. */
|
|
642
|
-
ipcRoute('POST', '/api/sessions/:sessionId/suspend', (_req, res, params) => {
|
|
643
|
-
const ds = findActiveBySessionId(params.sessionId);
|
|
644
|
-
if (!ds)
|
|
645
|
-
return jsonRes(res, 404, { ok: false, error: 'session_not_active' });
|
|
646
|
-
if (isSessionTransferring(ds)) {
|
|
647
|
-
return jsonRes(res, 409, { ok: false, error: 'session_transferring' });
|
|
648
|
-
}
|
|
649
|
-
// Adopt/observed sessions: botmux never owned the CLI — suspending would kill
|
|
650
|
-
// the user's real tmux/zellij pane. Same guard as /restart.
|
|
651
|
-
if (ds.adoptedFrom || ds.initConfig?.adoptMode) {
|
|
652
|
-
return jsonRes(res, 409, { ok: false, error: 'adopt_suspend_unsupported' });
|
|
653
|
-
}
|
|
654
|
-
if (!ds.worker || ds.worker.killed) {
|
|
655
|
-
// Worker already gone (idle-suspended / crash-stopped) — the goal state is
|
|
656
|
-
// already reached, so report idempotent success without a live kill.
|
|
657
|
-
return jsonRes(res, 200, { ok: true, sessionId: params.sessionId, suspended: false, reason: 'no_live_worker' });
|
|
658
|
-
}
|
|
659
|
-
if (!suspendWorker(ds, 'manual_suspend')) {
|
|
660
|
-
// Live worker but a non-suspendable (pty) backend: killing it would drop the
|
|
661
|
-
// in-memory conversation with no persistent pane to resume from lazily.
|
|
662
|
-
return jsonRes(res, 409, { ok: false, error: 'backend_not_suspendable' });
|
|
663
|
-
}
|
|
664
|
-
jsonRes(res, 200, { ok: true, sessionId: params.sessionId, suspended: true });
|
|
665
|
-
});
|
|
666
|
-
/**
|
|
667
|
-
* Count host-overload降压 candidates for THIS daemon's scope, so the alert card
|
|
668
|
-
* can show "僵尸 N / 闲置 M" before the owner clicks. Both counts are local to
|
|
669
|
-
* THIS daemon: its session store is bot-scoped, and live workers only exist in
|
|
670
|
-
* their owning process. The card handler sums every daemon's response. Mirrors
|
|
671
|
-
* the exact classification the sweep uses so the preview matches a click.
|
|
672
|
-
*/
|
|
673
|
-
ipcRoute('GET', '/api/host-overload/counts', (_req, res) => {
|
|
674
|
-
const stopped = sessionStore.listSessions().filter(s => s.status === 'active' && isSessionStopped(s)).length;
|
|
675
|
-
let idle = 0;
|
|
676
|
-
for (const ds of listActiveSessions()) {
|
|
677
|
-
if (!ds.worker || ds.worker.killed)
|
|
678
|
-
continue;
|
|
679
|
-
if (ds.adoptedFrom || ds.initConfig?.adoptMode)
|
|
680
|
-
continue;
|
|
681
|
-
if (!isSuspendableBackendType(ds.initConfig?.backendType))
|
|
682
|
-
continue;
|
|
683
|
-
if (ds.lastScreenStatus !== 'idle')
|
|
684
|
-
continue;
|
|
685
|
-
idle++;
|
|
686
|
-
}
|
|
687
|
-
jsonRes(res, 200, { ok: true, stopped, idle });
|
|
688
|
-
});
|
|
689
|
-
/**
|
|
690
|
-
* Bulk host-overload降压 sweep, driven by the overload-alert card buttons.
|
|
691
|
-
* `mode`:
|
|
692
|
-
* - `clean_stopped`: close stopped zombie sessions (dead CLI + no exact
|
|
693
|
-
* persistent backing) from THIS daemon's bot-scoped session store. The
|
|
694
|
-
* card handler fans this mode out to every online daemon.
|
|
695
|
-
* - `suspend_idle`: suspend THIS daemon's own idle (non-busy, suspendable,
|
|
696
|
-
* non-adopt) live workers. Live workers only exist in their owning daemon's
|
|
697
|
-
* process, so the card handler fans this mode out to every online daemon.
|
|
698
|
-
* Returns `{ ok, mode, affected }` — `affected` counts sessions acted on here.
|
|
699
|
-
*/
|
|
700
|
-
ipcRoute('POST', '/api/host-overload/sweep', async (req, res) => {
|
|
701
|
-
let body;
|
|
702
|
-
try {
|
|
703
|
-
body = await readJsonBody(req);
|
|
704
|
-
}
|
|
705
|
-
catch {
|
|
706
|
-
return jsonRes(res, 400, { ok: false, error: 'bad_json' });
|
|
707
|
-
}
|
|
708
|
-
const mode = body?.mode;
|
|
709
|
-
if (mode === 'clean_stopped') {
|
|
710
|
-
const stopped = sessionStore.listSessions().filter(s => s.status === 'active' && isSessionStopped(s));
|
|
711
|
-
let affected = 0;
|
|
712
|
-
for (const s of stopped) {
|
|
713
|
-
try {
|
|
714
|
-
const r = await closeSession(s.sessionId);
|
|
715
|
-
// Only count sessions this call actually closed. A concurrent action in
|
|
716
|
-
// this daemon may already have closed the same record.
|
|
717
|
-
if (r.ok && !r.alreadyClosed)
|
|
718
|
-
affected++;
|
|
719
|
-
}
|
|
720
|
-
catch (err) {
|
|
721
|
-
logger.warn(`[overload-sweep] close failed for ${s.sessionId.slice(0, 8)}: ${err instanceof Error ? err.message : String(err)}`);
|
|
722
|
-
}
|
|
723
|
-
}
|
|
724
|
-
logger.info(`[overload-sweep] clean_stopped: closed ${affected}/${stopped.length} zombie session(s)`);
|
|
725
|
-
return jsonRes(res, 200, { ok: true, mode, affected });
|
|
726
|
-
}
|
|
727
|
-
if (mode === 'suspend_idle') {
|
|
728
|
-
// This daemon's own idle live workers only. Correctness guards mirror the
|
|
729
|
-
// idle-worker sweeper: never touch adopt sessions or mid-turn (busy) ones.
|
|
730
|
-
let affected = 0;
|
|
731
|
-
for (const ds of listActiveSessions()) {
|
|
732
|
-
if (!ds.worker || ds.worker.killed)
|
|
733
|
-
continue; // no live worker
|
|
734
|
-
if (ds.adoptedFrom || ds.initConfig?.adoptMode)
|
|
735
|
-
continue; // never suspend adopt
|
|
736
|
-
if (!isSuspendableBackendType(ds.initConfig?.backendType))
|
|
737
|
-
continue;
|
|
738
|
-
if (ds.lastScreenStatus !== 'idle')
|
|
739
|
-
continue; // never cut an in-flight reply
|
|
740
|
-
try {
|
|
741
|
-
if (suspendWorker(ds, 'host_overload_suspend'))
|
|
742
|
-
affected++;
|
|
743
|
-
}
|
|
744
|
-
catch (err) {
|
|
745
|
-
logger.warn(`[overload-sweep] suspend failed for ${ds.session.sessionId.slice(0, 8)}: ${err instanceof Error ? err.message : String(err)}`);
|
|
746
|
-
}
|
|
747
|
-
}
|
|
748
|
-
logger.info(`[overload-sweep] suspend_idle: suspended ${affected} idle worker(s)`);
|
|
749
|
-
return jsonRes(res, 200, { ok: true, mode, affected });
|
|
750
|
-
}
|
|
751
|
-
return jsonRes(res, 400, { ok: false, error: 'bad_mode' });
|
|
752
|
-
});
|
|
753
|
-
/** 会话级 CLI IPC(slash/cd)的调用方证明:trusted-host(.dashboard-secret HMAC,
|
|
754
|
-
* 外层 gate 已验)直接放行;否则(沙箱/读隔离 CLI 读不到 secret,走
|
|
755
|
-
* routeHasNarrowUntrustedAuth 窄孔进来)必须出示该会话当前轮换的 capability,
|
|
756
|
-
* 与 daemon 活跃记录里的 managedTurnOrigin 比对(/api/asks 同款姿势)。
|
|
757
|
-
* capability 只证明「我是这个会话当前这一轮的 CLI」——绑定 URL sessionId,
|
|
758
|
-
* 拿到别的 sessionId 也伪造不了它的 capability。会话不存在时对未签名调用方
|
|
759
|
-
* 同样回 origin_unproven,不提供「哪些 sessionId 活跃」的探针。 */
|
|
760
|
-
function sessionCliIpcAuth(req, ds, sessionId, body) {
|
|
761
|
-
const claimedAttempt = typeof body?.originDispatchAttempt === 'number'
|
|
762
|
-
&& Number.isSafeInteger(body.originDispatchAttempt)
|
|
763
|
-
&& body.originDispatchAttempt > 0
|
|
764
|
-
? body.originDispatchAttempt
|
|
765
|
-
: undefined;
|
|
766
|
-
const decision = authorizeSessionScopedIpc({
|
|
767
|
-
trustedHost: isTrustedHostIpcRequest(req),
|
|
768
|
-
sessionExists: !!ds,
|
|
769
|
-
receiverSession: !!ds?.session.vcMeetingReceiver,
|
|
770
|
-
allowReceiver: false,
|
|
771
|
-
sessionId,
|
|
772
|
-
liveOrigin: ds?.managedTurnOrigin,
|
|
773
|
-
claimedCapability: typeof body?.originCapability === 'string' ? body.originCapability : undefined,
|
|
774
|
-
claimedTurnId: typeof body?.originTurnId === 'string' ? body.originTurnId : undefined,
|
|
775
|
-
claimedDispatchAttempt: claimedAttempt,
|
|
776
|
-
});
|
|
777
|
-
return decision.ok ? { ok: true } : { ok: false, error: decision.error };
|
|
778
|
-
}
|
|
779
|
-
/** 向本会话 CLI 注入一条 allowlist 内的原生斜杠命令(idle 后生效)。
|
|
780
|
-
* 鉴权双路径(见 sessionCliIpcAuth):trusted-host 签名或本会话 rotating
|
|
781
|
-
* capability;命令面由 allowlist(默认空=全拒)承担。 */
|
|
782
|
-
ipcRoute('POST', '/api/sessions/:sessionId/slash', async (req, res, params) => {
|
|
783
|
-
const body = await readJsonBody(req)
|
|
784
|
-
.catch(() => ({}));
|
|
785
|
-
const ds = findActiveBySessionId(params.sessionId);
|
|
786
|
-
const auth = sessionCliIpcAuth(req, ds, params.sessionId, body);
|
|
787
|
-
if (!auth.ok)
|
|
788
|
-
return jsonRes(res, 403, { ok: false, error: auth.error });
|
|
789
|
-
if (!ds)
|
|
790
|
-
return jsonRes(res, 404, { ok: false, error: 'session_not_active' });
|
|
791
|
-
// Adopt/observed 会话是收编的用户自有 pane,用户可能正在里面打字——机器注入
|
|
792
|
-
// 会与人的输入交错。与 /suspend、/restart 同款排除。
|
|
793
|
-
if (ds.adoptedFrom || ds.initConfig?.adoptMode) {
|
|
794
|
-
return jsonRes(res, 409, { ok: false, error: 'adopt_inject_unsupported' });
|
|
795
|
-
}
|
|
796
|
-
if ((!ds.worker || ds.worker.killed) && !isSessionTransferring(ds)) {
|
|
797
|
-
return jsonRes(res, 409, { ok: false, error: 'no_live_worker' });
|
|
798
|
-
}
|
|
799
|
-
const allow = getBotTuiSlashAllow(ds.larkAppId);
|
|
800
|
-
const v = validateSlashInjection(body?.command ?? '', allow);
|
|
801
|
-
if (!v.ok)
|
|
802
|
-
return jsonRes(res, 403, { ok: false, error: v.error });
|
|
803
|
-
try {
|
|
804
|
-
if (!sendWorkerSessionInput(ds, { type: 'inject_command', command: v.command })) {
|
|
805
|
-
return jsonRes(res, 409, { ok: false, error: 'no_live_worker' });
|
|
806
|
-
}
|
|
807
|
-
}
|
|
808
|
-
catch {
|
|
809
|
-
// slash 注入无状态(不像 /cd 那样已 repin 记录),send 失败不需要杀进程
|
|
810
|
-
// 冷启动——直接把失败面报给调用方即可。
|
|
811
|
-
return jsonRes(res, 502, { ok: false, error: 'worker_send_failed' });
|
|
812
|
-
}
|
|
813
|
-
jsonRes(res, 200, { ok: true, sessionId: params.sessionId, queued: v.command });
|
|
814
|
-
});
|
|
815
|
-
const proactiveChatRenameCooldown = new ChatRenameCooldown();
|
|
816
|
-
const chatRenameSerialQueue = new ChatRenameSerialQueue();
|
|
817
|
-
/** Session-scoped external mutation used by the botmux-chat-rename Skill. */
|
|
818
|
-
ipcRoute('POST', '/api/sessions/:sessionId/chat-rename', async (req, res, params) => {
|
|
819
|
-
const body = await readJsonBody(req)
|
|
820
|
-
.catch(() => ({}));
|
|
821
|
-
const ds = findActiveBySessionId(params.sessionId);
|
|
822
|
-
const auth = sessionCliIpcAuth(req, ds, params.sessionId, body);
|
|
823
|
-
if (!auth.ok)
|
|
824
|
-
return jsonRes(res, 403, { ok: false, error: auth.error });
|
|
825
|
-
if (!ds)
|
|
826
|
-
return jsonRes(res, 404, { ok: false, error: 'session_not_active' });
|
|
827
|
-
if (sessionTransportDisabled(ds))
|
|
828
|
-
return jsonRes(res, 200, { ok: false, error: 'no_feishu_transport' });
|
|
829
|
-
if (ds.chatType !== 'group')
|
|
830
|
-
return jsonRes(res, 400, { ok: false, error: 'not_group_chat' });
|
|
831
|
-
const normalized = normalizeLarkChatName(body.name);
|
|
832
|
-
if (!normalized.ok)
|
|
833
|
-
return jsonRes(res, 400, normalized);
|
|
834
|
-
const proactive = body.proactive === true;
|
|
835
|
-
const trigger = proactive ? 'ai_proactive' : 'user_explicit';
|
|
836
|
-
const cooldownKey = `${ds.larkAppId}:${ds.chatId}`;
|
|
837
|
-
await chatRenameSerialQueue.run(cooldownKey, async () => {
|
|
838
|
-
const result = await groupsStore.renameChat(ds.larkAppId, ds.chatId, normalized.name, {
|
|
839
|
-
beforeUpdate: proactive
|
|
840
|
-
? () => {
|
|
841
|
-
const cooldown = proactiveChatRenameCooldown.check(cooldownKey);
|
|
842
|
-
return cooldown.ok
|
|
843
|
-
? cooldown
|
|
844
|
-
: { ...cooldown, error: 'rate_limited' };
|
|
845
|
-
}
|
|
846
|
-
: undefined,
|
|
847
|
-
});
|
|
848
|
-
const botOpenId = getBotOpenId(ds.larkAppId) ?? '-';
|
|
849
|
-
if (!result.ok) {
|
|
850
|
-
const status = result.error === 'bot_not_in_chat' ? 403
|
|
851
|
-
: result.error === 'permission_denied' ? 403
|
|
852
|
-
: result.error === 'rate_limited' ? 429
|
|
853
|
-
: 502;
|
|
854
|
-
logger.warn(`[chat-rename:audit] result=failed session=${ds.session.sessionId} chat=${ds.chatId} `
|
|
855
|
-
+ `app=${ds.larkAppId} botOpenId=${botOpenId} trigger=${trigger} `
|
|
856
|
-
+ `old=${JSON.stringify(result.oldName ?? null)} new=${JSON.stringify(result.newName ?? normalized.name)} `
|
|
857
|
-
+ `error=${result.error} larkCode=${result.larkCode ?? '-'} detail=${result.detail ?? '-'}`);
|
|
858
|
-
return jsonRes(res, status, result);
|
|
859
|
-
}
|
|
860
|
-
if (result.changed) {
|
|
861
|
-
if (proactive)
|
|
862
|
-
proactiveChatRenameCooldown.record(cooldownKey);
|
|
863
|
-
// FR-7: the Lark write already succeeded, so a local cache-refresh
|
|
864
|
-
// failure (ENOSPC/EACCES on the session store) must NOT reverse the
|
|
865
|
-
// outcome into an HTTP 500 — best-effort per session, warn and keep the
|
|
866
|
-
// rename a success. Catch per-session so one bad write can't skip the rest.
|
|
867
|
-
for (const active of getActiveSessionsRegistry()?.values() ?? []) {
|
|
868
|
-
if (active.chatId !== ds.chatId)
|
|
869
|
-
continue;
|
|
870
|
-
active.session.chatDisplayName = result.newName;
|
|
871
|
-
try {
|
|
872
|
-
sessionStore.updateSession(active.session);
|
|
873
|
-
}
|
|
874
|
-
catch (e) {
|
|
875
|
-
logger.warn(`[chat-rename:audit] cache_refresh_failed session=${active.session.sessionId} chat=${ds.chatId} app=${ds.larkAppId} detail=${e instanceof Error ? e.message : String(e)}`);
|
|
876
|
-
}
|
|
877
|
-
}
|
|
878
|
-
logger.info(`[chat-rename:audit] result=success session=${ds.session.sessionId} chat=${ds.chatId} `
|
|
879
|
-
+ `app=${ds.larkAppId} botOpenId=${botOpenId} trigger=${trigger} `
|
|
880
|
-
+ `old=${JSON.stringify(result.oldName)} new=${JSON.stringify(result.newName)} larkCode=0`);
|
|
881
|
-
}
|
|
882
|
-
return jsonRes(res, 200, { ...result, chatId: ds.chatId });
|
|
883
|
-
});
|
|
884
|
-
});
|
|
885
|
-
/** 会话内切换工作目录(角色切换专用):硬校验角色库根 → 更新记录落盘(唯一事实源)
|
|
886
|
-
* → 活 worker 走「带 --resume 的进程重启、respawn 在新 cwd」,无活 worker 杀残留
|
|
887
|
-
* pane 让下条消息冷启动。
|
|
888
|
-
*
|
|
889
|
-
* 为什么是 respawn 而不是向活进程注入 /cd(旧实现):CLI 的系统上下文(CLAUDE.md、
|
|
890
|
-
* 记忆路径/索引)是开场按启动 cwd 注入一次的静态快照,/cd 只改 cwd 不重刷——注入
|
|
891
|
-
* 切换后模型仍拿着旧角色的记忆索引读写(读旧索引、写错桶)。respawn 让「开场」在
|
|
892
|
-
* 新 cwd 重新发生:新角色的 CLAUDE.md/记忆索引开场即注入,--resume 回放对话历史
|
|
893
|
-
* 保留上下文(“换角色外壳、留对话内核”)。旧桶 transcript 由 claude-code 适配器的
|
|
894
|
-
* resume 预检 syncClaudeResumeTargetToCwd(worker.ts 每次 resume respawn、probe 之前
|
|
895
|
-
* 把最新 <sid>.jsonl COPY 进新 cwd 的 project 目录,已在 master)接住,不会探空丢
|
|
896
|
-
* 上下文。故本改动可独立部署,不硬依赖任何跨桶迁移专项 PR。
|
|
897
|
-
*
|
|
898
|
-
* 鉴权双路径(见 sessionCliIpcAuth):trusted-host 签名或本会话 rotating
|
|
899
|
-
* capability;目录面由 validateRoleLibraryPath 硬校验承担(realpath 归一 +
|
|
900
|
-
* dev/ino 包含判断,角色库根之外一律拒)。
|
|
901
|
-
* 不发话题消息(AI 自己发角色化确认)。 */
|
|
902
|
-
ipcRoute('POST', '/api/sessions/:sessionId/cd', async (req, res, params) => {
|
|
903
|
-
const body = await readJsonBody(req)
|
|
904
|
-
.catch(() => ({}));
|
|
905
|
-
const ds = findActiveBySessionId(params.sessionId);
|
|
906
|
-
const auth = sessionCliIpcAuth(req, ds, params.sessionId, body);
|
|
907
|
-
if (!auth.ok)
|
|
908
|
-
return jsonRes(res, 403, { ok: false, error: auth.error });
|
|
909
|
-
if (!ds)
|
|
910
|
-
return jsonRes(res, 404, { ok: false, error: 'session_not_active' });
|
|
911
|
-
if (isSessionTransferring(ds)) {
|
|
912
|
-
return jsonRes(res, 409, { ok: false, error: 'session_transferring' });
|
|
913
|
-
}
|
|
914
|
-
// Adopt/observed 会话是收编的用户自有 pane——注入或冷重启都会打断用户自己的
|
|
915
|
-
// 终端会话。与 /suspend、/restart、/slash 同款排除。
|
|
916
|
-
if (ds.adoptedFrom || ds.initConfig?.adoptMode) {
|
|
917
|
-
return jsonRes(res, 409, { ok: false, error: 'adopt_cd_unsupported' });
|
|
918
|
-
}
|
|
919
|
-
// ownAppId 收窄到本 bot 自己的角色库子树:不收窄就能切进别的 bot 的角色目录,
|
|
920
|
-
// 下面 repinSessionWorkingDir 把 ds.workingDir 钉过去之后,那个 bot 的沙盒会话
|
|
921
|
-
// 就拿到了对方整棵角色库的 readWrite(打穿 fs-policy 的跨 bot 隔离)。
|
|
922
|
-
const v = validateRoleLibraryPath(body?.dir ?? '', undefined, ds.larkAppId);
|
|
923
|
-
if (!v.ok) {
|
|
924
|
-
const forbidden = v.error === 'outside_role_library' || v.error === 'outside_own_role_library';
|
|
925
|
-
// own_role_library_missing:本 bot 的 `<角色库根>/<appId>` 不是真目录(存量用
|
|
926
|
-
// 人类 slug 命名这一层,未按 deploy-runbook §8 迁移)。FAIL-CLOSED——不回落全局
|
|
927
|
-
// 根(回落是 fail-open,会让存量部署继续能跨 bot 切并经 workingDir 拿 rw)。回
|
|
928
|
-
// 409 + 迁移指引,让运营看得见查得到,而不是静默放行或静默拒绝。
|
|
929
|
-
if (v.error === 'own_role_library_missing') {
|
|
930
|
-
logger.warn(`[role] 角色库每-bot 目录名不是 appId(期望 ~/botmux-roles/${ds.larkAppId})——`
|
|
931
|
-
+ 'role switch 已 fail-closed 拒绝,避免跨 bot 越权。按 docs/roles/deploy-runbook.md '
|
|
932
|
-
+ '§8「迁移:每-bot 目录名改为 appId」重命名该目录即恢复。');
|
|
933
|
-
return jsonRes(res, 409, { ok: false, error: v.error });
|
|
934
|
-
}
|
|
935
|
-
return jsonRes(res, forbidden ? 403 : 400, { ok: false, error: v.error });
|
|
936
|
-
}
|
|
937
|
-
repinSessionWorkingDir(ds, v.resolvedPath);
|
|
938
|
-
// ds.initConfig 与 repin 同步,且**无条件**(不只在 live-worker 分支里):下次
|
|
939
|
-
// forkWorker 用 initConfig 重建 init 消息,只在有活 worker 时更新的话,no-worker /
|
|
940
|
-
// worker.killed 两条分支会留下「记录新、initConfig 旧」的分裂状态,冷启动把会话
|
|
941
|
-
// 带回旧 cwd(= 旧角色,连记忆桶都是旧的)。codex review 抓出的既有 bug,与本 PR
|
|
942
|
-
// 的收窄同一处理,顺手修掉。
|
|
943
|
-
if (ds.initConfig)
|
|
944
|
-
ds.initConfig.workingDir = v.resolvedPath;
|
|
945
|
-
if (ds.worker && !ds.worker.killed) {
|
|
946
|
-
// updateWorkingDir 随 restart 带给 worker:respawn 必须收敛到新目录,而不是
|
|
947
|
-
// 陈旧的 lastInitConfig.workingDir(daemon 侧 initConfig 已在上面同步)。
|
|
948
|
-
try {
|
|
949
|
-
ds.workerReady = false;
|
|
950
|
-
ds.worker.send({ type: 'restart', updateWorkingDir: v.resolvedPath, env: latestPerBotEnvForRestart(ds) });
|
|
951
|
-
}
|
|
952
|
-
catch {
|
|
953
|
-
// send() 抛异常:worker 进程实际上已经不可达(管道已断),但 above 的
|
|
954
|
-
// repinSessionWorkingDir 已经把记录改成了新目录——绝不能留下「记录新、
|
|
955
|
-
// 进程仍在旧目录」的分裂状态。杀掉 worker 让下一条消息冷启动进新目录。
|
|
956
|
-
killWorker(ds);
|
|
957
|
-
return jsonRes(res, 200, { ok: true, mode: 'cold-restart', dir: v.resolvedPath });
|
|
958
|
-
}
|
|
959
|
-
return jsonRes(res, 200, { ok: true, mode: 'respawn-resume', dir: v.resolvedPath });
|
|
960
|
-
}
|
|
961
|
-
// Unconditional (no `ds.worker` guard), matching the IM `/cd` command handler
|
|
962
|
-
// (src/core/command-handler.ts) — killWorker() already no-ops safely when there
|
|
963
|
-
// is no live worker. That "no worker" branch is exactly what must run here for a
|
|
964
|
-
// lazy-restored-after-daemon-restart or crash-stopped TmuxBackend/HerdrBackend/
|
|
965
|
-
// ZellijBackend session: the persistent backing pane survives the worker's death
|
|
966
|
-
// and still binds the OLD cwd, so it must be torn down via
|
|
967
|
-
// destroyOrphanedBackingSession (called from inside killWorker) or the next
|
|
968
|
-
// resume would silently reattach to it and ignore the just-repinned workingDir.
|
|
969
|
-
killWorker(ds);
|
|
970
|
-
jsonRes(res, 200, { ok: true, mode: 'cold-restart', dir: v.resolvedPath });
|
|
971
|
-
});
|
|
972
|
-
/** 解析 session(活跃优先,已关闭兜底)。活跃会话取 ds.session —— registry 与
|
|
973
|
-
* store 持有同一对象,改字段后 updateSession 即落盘。 */
|
|
974
|
-
function findSessionRecord(sessionId) {
|
|
975
|
-
return findActiveBySessionId(sessionId)?.session ?? sessionStore.getSession(sessionId);
|
|
976
|
-
}
|
|
977
|
-
/** True when a session-bound IPC route must NOT touch Feishu: the owning bot is
|
|
978
|
-
* core-only (apiOnly) OR the session is an HTTP virtual chat. Central guard for
|
|
979
|
-
* every session-write route (chat-rename / write-link-card / resume-notice /
|
|
980
|
-
* locate / restart-notice …) — the daemon owns the authoritative bot config,
|
|
981
|
-
* so gating here catches the normal-bot-in-virtual-session case that
|
|
982
|
-
* getBotClient (which only throws for apiOnly) cannot. Accepts a live
|
|
983
|
-
* DaemonSession or a stored Session record. Never throws. */
|
|
984
|
-
function sessionTransportDisabled(s) {
|
|
985
|
-
const appId = s.larkAppId;
|
|
986
|
-
let apiOnly = false;
|
|
987
|
-
if (appId) {
|
|
988
|
-
try {
|
|
989
|
-
apiOnly = getBot(appId).config.apiOnly === true;
|
|
990
|
-
}
|
|
991
|
-
catch { /* unknown bot → not apiOnly */ }
|
|
992
|
-
}
|
|
993
|
-
return !larkTransportEnabled({ chatId: s.chatId ?? '', apiOnly });
|
|
994
|
-
}
|
|
995
|
-
/** Mutating IPC routes may only touch this daemon's own bot-partitioned store. */
|
|
996
|
-
function findOwnedSessionRecord(sessionId) {
|
|
997
|
-
return findActiveBySessionId(sessionId)?.session ?? sessionStore.getOwnedSession(sessionId);
|
|
998
|
-
}
|
|
999
|
-
/** Four-state async lookup with durable fallback (design A).
|
|
1000
|
-
*
|
|
1001
|
-
* In-memory `asyncTriggerResults` lives only on the active DaemonSession and is
|
|
1002
|
-
* lost on daemon restart / idle-suspend. To keep a poller from misreading an
|
|
1003
|
-
* already-completed turn as `not_found`, this resolves against BOTH the live
|
|
1004
|
-
* session and the on-disk stores:
|
|
1005
|
-
* - completed (mem or disk) → completed + output.content + finishedAt
|
|
1006
|
-
* - pending in mem / session active → running
|
|
1007
|
-
* - session record closed, no output → failed (no_output; soft terminal —
|
|
1008
|
-
* may be a real failure OR a caller close)
|
|
1009
|
-
* - no session record AND no result → not_found (never existed / invalid id)
|
|
1010
|
-
*
|
|
1011
|
-
* Legacy `action`/`async` fields are still populated so existing webhook
|
|
1012
|
-
* consumers keep working; new callers branch on `state`. */
|
|
1013
|
-
function buildAsyncTriggerLookupResponse(sessionId, triggerId) {
|
|
1014
|
-
const ds = findActiveBySessionId(sessionId);
|
|
1015
|
-
const storedRaw = ds?.session ?? sessionStore.getSession(sessionId);
|
|
1016
|
-
const persistedRaw = asyncTriggerStore.lookup(sessionId, triggerId);
|
|
1017
|
-
// Cross-bot isolation (fail-closed / positive-proof) — see decideAsyncOwnership.
|
|
1018
|
-
// Both sessionStore.getSession() (cross-scans every bot's sessions-*.json) and
|
|
1019
|
-
// the async store (machine-wide shared dir) can surface another bot's data for
|
|
1020
|
-
// a sessionId routed to THIS daemon; keep only sources positively proven ours.
|
|
1021
|
-
const decision = decideAsyncOwnership({
|
|
1022
|
-
owner: cachedLarkAppId,
|
|
1023
|
-
liveDs: !!ds,
|
|
1024
|
-
storedOwner: storedRaw?.larkAppId,
|
|
1025
|
-
storedExists: !!storedRaw,
|
|
1026
|
-
persistedOwner: persistedRaw?.ownerLarkAppId,
|
|
1027
|
-
persistedExists: !!persistedRaw,
|
|
1028
|
-
});
|
|
1029
|
-
const stored = decision.keepStored ? storedRaw : undefined;
|
|
1030
|
-
const persisted = decision.keepPersisted ? persistedRaw : undefined;
|
|
1031
|
-
if (decision.foreignLeak) {
|
|
1032
|
-
return {
|
|
1033
|
-
ok: true,
|
|
1034
|
-
state: 'not_found',
|
|
1035
|
-
triggerId,
|
|
1036
|
-
errorCode: 'session_not_found',
|
|
1037
|
-
error: `no session record for: ${sessionId}`,
|
|
1038
|
-
message: 'no session found',
|
|
1039
|
-
};
|
|
1040
|
-
}
|
|
1041
|
-
const memTriggerId = triggerId || ds?.latestAsyncTriggerId;
|
|
1042
|
-
const memResult = ds && memTriggerId ? ds.asyncTriggerResults?.get(memTriggerId) : undefined;
|
|
1043
|
-
const resolved = resolveAsyncTriggerState({
|
|
1044
|
-
sessionId,
|
|
1045
|
-
liveActive: !!ds,
|
|
1046
|
-
chatId: ds?.chatId ?? stored?.chatId,
|
|
1047
|
-
memResult: memResult ? { status: memResult.status, content: memResult.content, completedAt: memResult.completedAt, usage: memResult.usage } : undefined,
|
|
1048
|
-
memTriggerId: memResult ? memTriggerId : undefined,
|
|
1049
|
-
persisted,
|
|
1050
|
-
storedStatus: stored ? (stored.status === 'closed' ? 'closed' : 'open') : undefined,
|
|
1051
|
-
closedAt: stored?.closedAt,
|
|
1052
|
-
requestedTriggerId: triggerId,
|
|
1053
|
-
});
|
|
1054
|
-
// Form C: attach the read-only web-terminal URL ONLY in core-only mode, and
|
|
1055
|
-
// only when a LIVE worker terminal exists (workerPort bound + view capability
|
|
1056
|
-
// minted). Core-only is the single-tenant loopback path where trigger-result
|
|
1057
|
-
// is a public (no-HMAC) route and riff's in-sandbox runner polls it to open
|
|
1058
|
-
// the visible CLI TUI. Gating on BOTMUX_CORE_ONLY keeps this OFF the normal/
|
|
1059
|
-
// mixed fleet: there trigger-result is HMAC-gated, but we still must not widen
|
|
1060
|
-
// the token surface by minting a terminal read-capability into a poll response
|
|
1061
|
-
// that historically carried none (the dashboard mints view/write tokens only
|
|
1062
|
-
// on explicit /write-link request). buildTerminalUrl carries ?viewToken=
|
|
1063
|
-
// inline; the write token is never included. Closed/restored sessions have no
|
|
1064
|
-
// live worker terminal, so no stale URL is ever advertised.
|
|
1065
|
-
if (process.env.BOTMUX_CORE_ONLY === '1' && ds && ds.workerPort && ds.workerViewToken) {
|
|
1066
|
-
resolved.readOnlyUrl = buildTerminalUrl(ds);
|
|
1067
|
-
resolved.viewToken = ds.workerViewToken;
|
|
1068
|
-
}
|
|
1069
|
-
return resolved;
|
|
1070
|
-
}
|
|
1071
|
-
// 看板放置:dashboard 看板视图拖拽卡片后持久化列 + 列内排序位置。
|
|
1072
|
-
// 改完广播 session.update,所有打开的 dashboard 实时同步。
|
|
1073
|
-
ipcRoute('POST', '/api/sessions/:sessionId/board', async (req, res, params) => {
|
|
1074
|
-
let body;
|
|
1075
|
-
try {
|
|
1076
|
-
body = await readJsonBody(req);
|
|
1077
|
-
}
|
|
1078
|
-
catch {
|
|
1079
|
-
return jsonRes(res, 400, { ok: false, error: 'bad_json' });
|
|
1080
|
-
}
|
|
1081
|
-
const column = normalizeKanbanColumn(body.column);
|
|
1082
|
-
const position = normalizeKanbanPosition(body.position);
|
|
1083
|
-
if (!column && position === null)
|
|
1084
|
-
return jsonRes(res, 400, { ok: false, error: 'bad_request' });
|
|
1085
|
-
const session = findOwnedSessionRecord(params.sessionId);
|
|
1086
|
-
if (!session)
|
|
1087
|
-
return jsonRes(res, 404, { ok: false, error: 'session_not_found' });
|
|
1088
|
-
// 待办池(queued)会话被拖到「进行中」= 激活:把暂存内容当首轮发给 CLI 开跑。
|
|
1089
|
-
// activateQueuedSession 内部会清 queued + 把列设成 in_progress + forkWorker。
|
|
1090
|
-
const activeDs = findActiveBySessionId(params.sessionId);
|
|
1091
|
-
if (column === 'in_progress' && activeDs?.session.queued) {
|
|
1092
|
-
await activateQueuedSession(activeDs);
|
|
1093
|
-
}
|
|
1094
|
-
else if (column) {
|
|
1095
|
-
session.kanbanColumn = column;
|
|
1096
|
-
}
|
|
1097
|
-
if (position !== null)
|
|
1098
|
-
session.kanbanPosition = position;
|
|
1099
|
-
sessionStore.updateSession(session);
|
|
1100
|
-
dashboardEventBus.publish({
|
|
1101
|
-
type: 'session.update',
|
|
1102
|
-
body: {
|
|
1103
|
-
sessionId: params.sessionId,
|
|
1104
|
-
// queued 一并下发:激活后 session.queued 已为 false,前端浅合并若不带这个字段
|
|
1105
|
-
// 会残留 queued=true(卡片仍显示「开始」、再点 409)。!!session.queued 始终反映现态。
|
|
1106
|
-
patch: { kanbanColumn: session.kanbanColumn, kanbanPosition: session.kanbanPosition, queued: !!session.queued },
|
|
1107
|
-
},
|
|
1108
|
-
});
|
|
1109
|
-
jsonRes(res, 200, { ok: true });
|
|
1110
|
-
});
|
|
1111
|
-
// 待办池会话「开始」:把 parked 会话激活(发首轮、起 CLI),与拖到「进行中」同义。
|
|
1112
|
-
ipcRoute('POST', '/api/sessions/:sessionId/start', async (_req, res, params) => {
|
|
1113
|
-
const ds = findActiveBySessionId(params.sessionId);
|
|
1114
|
-
if (!ds)
|
|
1115
|
-
return jsonRes(res, 404, { ok: false, error: 'session_not_found' });
|
|
1116
|
-
if (!ds.session.queued)
|
|
1117
|
-
return jsonRes(res, 409, { ok: false, error: 'not_queued' });
|
|
1118
|
-
const r = await activateQueuedSession(ds);
|
|
1119
|
-
if (!r.ok)
|
|
1120
|
-
return jsonRes(res, 500, r);
|
|
1121
|
-
sessionStore.updateSession(ds.session);
|
|
1122
|
-
dashboardEventBus.publish({
|
|
1123
|
-
type: 'session.update',
|
|
1124
|
-
body: { sessionId: params.sessionId, patch: { kanbanColumn: ds.session.kanbanColumn, queued: false } },
|
|
1125
|
-
});
|
|
1126
|
-
jsonRes(res, 200, { ok: true });
|
|
1127
|
-
});
|
|
1128
|
-
// Dashboard「创建会话」spawn:在新建的群里为本 daemon 的 bot 拉起/暂存一条 chat-scope
|
|
1129
|
-
// 会话。aggregator 建完群后按模式(一起开工/lead 分配)对每个目标 bot 的 daemon 调一次。
|
|
1130
|
-
ipcRoute('POST', '/api/sessions/spawn', async (req, res) => {
|
|
1131
|
-
if (!cachedLarkAppId)
|
|
1132
|
-
return jsonRes(res, 503, { ok: false, error: 'bot_not_found' });
|
|
1133
|
-
const activeSessions = getActiveSessionsRegistry();
|
|
1134
|
-
if (!activeSessions)
|
|
1135
|
-
return jsonRes(res, 503, { ok: false, error: 'registry_unavailable' });
|
|
1136
|
-
let body;
|
|
1137
|
-
try {
|
|
1138
|
-
body = await readJsonBody(req);
|
|
1139
|
-
}
|
|
1140
|
-
catch {
|
|
1141
|
-
return jsonRes(res, 400, { ok: false, error: 'invalid_json' });
|
|
1142
|
-
}
|
|
1143
|
-
const parsed = parseSpawnRequest(body);
|
|
1144
|
-
if (!parsed.ok)
|
|
1145
|
-
return jsonRes(res, 400, { ok: false, error: parsed.error });
|
|
1146
|
-
const postBanner = !!body.postBanner;
|
|
1147
|
-
let attachments;
|
|
1148
|
-
try {
|
|
1149
|
-
attachments = materializeDashboardImages(cachedLarkAppId, parsed.value.images);
|
|
1150
|
-
}
|
|
1151
|
-
catch (err) {
|
|
1152
|
-
logger.error(`[createSession] failed to persist Dashboard images: ${err?.message ?? err}`);
|
|
1153
|
-
return jsonRes(res, 500, { ok: false, error: 'image_store_failed' });
|
|
1154
|
-
}
|
|
1155
|
-
const r = await spawnDashboardSession(activeSessions, undefined, {
|
|
1156
|
-
larkAppId: cachedLarkAppId,
|
|
1157
|
-
chatId: parsed.value.chatId,
|
|
1158
|
-
content: parsed.value.content,
|
|
1159
|
-
column: parsed.value.column,
|
|
1160
|
-
role: parsed.value.role,
|
|
1161
|
-
coworkers: parsed.value.coworkers,
|
|
1162
|
-
attachments,
|
|
1163
|
-
title: parsed.value.title,
|
|
1164
|
-
postBanner,
|
|
1165
|
-
ownerOpenId: parsed.value.ownerOpenId,
|
|
1166
|
-
ownerUnionId: parsed.value.ownerUnionId,
|
|
1167
|
-
});
|
|
1168
|
-
if (!r.ok) {
|
|
1169
|
-
cleanupMaterializedDashboardImages(cachedLarkAppId, attachments);
|
|
1170
|
-
return jsonRes(res, r.error === 'session_exists' ? 409 : 500, r);
|
|
1171
|
-
}
|
|
1172
|
-
jsonRes(res, 200, r);
|
|
1173
|
-
});
|
|
1174
|
-
ipcRoute('POST', '/api/chat-reply-mode', async (req, res) => {
|
|
1175
|
-
if (!cachedLarkAppId)
|
|
1176
|
-
return jsonRes(res, 503, { ok: false, reason: 'larkAppId_not_set' });
|
|
1177
|
-
let body;
|
|
1178
|
-
try {
|
|
1179
|
-
body = await readJsonBody(req);
|
|
1180
|
-
}
|
|
1181
|
-
catch {
|
|
1182
|
-
return jsonRes(res, 400, { ok: false, reason: 'invalid_json' });
|
|
1183
|
-
}
|
|
1184
|
-
const chatId = typeof body?.chatId === 'string' ? body.chatId.trim() : '';
|
|
1185
|
-
const mode = normalizeChatReplyMode(typeof body?.mode === 'string' ? body.mode : undefined);
|
|
1186
|
-
if (!chatId)
|
|
1187
|
-
return jsonRes(res, 400, { ok: false, reason: 'chatId_required' });
|
|
1188
|
-
if (!mode)
|
|
1189
|
-
return jsonRes(res, 400, { ok: false, reason: 'invalid_mode' });
|
|
1190
|
-
const result = await setChatReplyMode(cachedLarkAppId, chatId, mode);
|
|
1191
|
-
if (!result.ok)
|
|
1192
|
-
return jsonRes(res, 500, { ok: false, reason: result.reason });
|
|
1193
|
-
jsonRes(res, 200, { ok: true, mode: result.mode });
|
|
1194
|
-
});
|
|
1195
|
-
// 会话历史:实时拉取该会话所在话题/群的飞书消息(与 botmux history 同链路,
|
|
1196
|
-
// 消息体不落盘),给 dashboard 的会话历史弹窗。复杂卡片的「请升级」兜底文本
|
|
1197
|
-
// 用 message.get 的完整表示补齐;merge_forward 保持占位符(原型不展开)。
|
|
1198
|
-
ipcRoute('GET', '/api/sessions/:sessionId/history', async (req, res, params) => {
|
|
1199
|
-
const session = findSessionRecord(params.sessionId);
|
|
1200
|
-
if (!session)
|
|
1201
|
-
return jsonRes(res, 404, { ok: false, error: 'session_not_found' });
|
|
1202
|
-
const appId = session.larkAppId || cachedLarkAppId;
|
|
1203
|
-
if (!appId)
|
|
1204
|
-
return jsonRes(res, 422, { ok: false, error: 'no_lark_app' });
|
|
1205
|
-
// No-transport session (apiOnly bot or HTTP virtual chat) has no Feishu chat
|
|
1206
|
-
// history — listChatMessages/listThreadMessages would dial Feishu with a
|
|
1207
|
-
// synthetic chatId. Return empty history instead of making the network call.
|
|
1208
|
-
if (!larkTransportEnabled({ chatId: session.chatId, apiOnly: getBot(appId).config.apiOnly })) {
|
|
1209
|
-
return jsonRes(res, 200, { ok: true, messages: [], hint: 'no_feishu_transport' });
|
|
1210
|
-
}
|
|
1211
|
-
const url = new URL(req.url ?? '/', 'http://localhost');
|
|
1212
|
-
const limit = Math.min(Math.max(parseInt(url.searchParams.get('limit') ?? '80', 10) || 80, 1), 200);
|
|
1213
|
-
try {
|
|
1214
|
-
const raw = session.scope === 'chat'
|
|
1215
|
-
? await listChatMessages(appId, session.chatId, limit)
|
|
1216
|
-
: await listThreadMessages(appId, session.chatId, session.rootMessageId, limit);
|
|
1217
|
-
const messages = await Promise.all(raw.map(async (m) => {
|
|
1218
|
-
const parsed = parseApiMessage(m);
|
|
1219
|
-
if (parsed.msgType === 'interactive' && cardContentHasUpgradeFallback(parsed.content)) {
|
|
1220
|
-
const merged = await resolveMergedCardContent(appId, parsed.messageId).catch(() => null);
|
|
1221
|
-
if (merged)
|
|
1222
|
-
parsed.content = merged.text;
|
|
1223
|
-
}
|
|
1224
|
-
return {
|
|
1225
|
-
messageId: parsed.messageId,
|
|
1226
|
-
senderId: parsed.senderId,
|
|
1227
|
-
senderType: parsed.senderType,
|
|
1228
|
-
// 服务端返回的发送者名(with_sender_name=true,bot 也有)。enrich 阶段
|
|
1229
|
-
// 本地花名册/contact 解析不到时兜底用它——第三方 bot 不再是一串 open_id。
|
|
1230
|
-
...(parsed.senderName ? { senderName: parsed.senderName } : {}),
|
|
1231
|
-
msgType: parsed.msgType,
|
|
1232
|
-
content: parsed.content,
|
|
1233
|
-
// Lark create_time 是毫秒 epoch 字符串——规范成数字,前端 new Date 直接用
|
|
1234
|
-
createTime: Number(parsed.createTime) || undefined,
|
|
1235
|
-
};
|
|
1236
|
-
}));
|
|
1237
|
-
// 真人发送者补名字+头像(contact API,带缓存;不在可见范围的回退占位)
|
|
1238
|
-
const senders = new Map();
|
|
1239
|
-
await Promise.all([...new Set(messages.filter(m => m.senderType === 'user' && m.senderId).map(m => m.senderId))]
|
|
1240
|
-
.map(async (id) => { senders.set(id, await getUserProfile(appId, id)); }));
|
|
1241
|
-
// Bot sender ids are scoped to the observing app. Reuse the chat-member
|
|
1242
|
-
// resolver (cross-ref + observed bot roster) instead of assuming every
|
|
1243
|
-
// non-user message came from the bot that owns this dashboard session.
|
|
1244
|
-
const botMembers = await listChatBotMembers(appId, session.chatId).catch(() => []);
|
|
1245
|
-
let botInfos = [];
|
|
1246
|
-
try {
|
|
1247
|
-
const parsed = JSON.parse(readFileSync(join(config.session.dataDir, 'bots-info.json'), 'utf8'));
|
|
1248
|
-
if (Array.isArray(parsed))
|
|
1249
|
-
botInfos = parsed;
|
|
1250
|
-
}
|
|
1251
|
-
catch { /* missing/corrupt cache degrades to name/open_id placeholders */ }
|
|
1252
|
-
// listChatBotMembers can be temporarily unavailable during startup. Always
|
|
1253
|
-
// retain a local self-bot fallback so its own messages still have identity.
|
|
1254
|
-
try {
|
|
1255
|
-
const self = getBot(appId);
|
|
1256
|
-
if (self.botOpenId && !botMembers.some(member => member.openId === self.botOpenId)) {
|
|
1257
|
-
const selfName = self.botName || appId;
|
|
1258
|
-
botMembers.push({
|
|
1259
|
-
openId: self.botOpenId,
|
|
1260
|
-
displayName: selfName,
|
|
1261
|
-
name: selfName,
|
|
1262
|
-
larkAppId: appId,
|
|
1263
|
-
source: 'configured',
|
|
1264
|
-
mentionable: true,
|
|
1265
|
-
mentionSource: 'self',
|
|
1266
|
-
hasTeamRole: false,
|
|
1267
|
-
});
|
|
1268
|
-
}
|
|
1269
|
-
if (!botInfos.some(info => info.larkAppId === appId)) {
|
|
1270
|
-
botInfos.push({ larkAppId: appId, botOpenId: self.botOpenId, botName: self.botName, botAvatarUrl: self.botAvatarUrl });
|
|
1271
|
-
}
|
|
1272
|
-
}
|
|
1273
|
-
catch { /* session record may outlive a removed bot config */ }
|
|
1274
|
-
jsonRes(res, 200, {
|
|
1275
|
-
ok: true,
|
|
1276
|
-
scope: session.scope ?? 'thread',
|
|
1277
|
-
ownerOpenId: session.ownerOpenId,
|
|
1278
|
-
messages: enrichHistorySenders(messages, senders, botMembers, botInfos),
|
|
1279
|
-
});
|
|
1280
|
-
}
|
|
1281
|
-
catch (err) {
|
|
1282
|
-
jsonRes(res, 502, { ok: false, error: String(err?.message ?? err) });
|
|
1283
|
-
}
|
|
1284
|
-
});
|
|
1285
|
-
ipcRoute('GET', '/api/sessions/:sessionId/trigger-result', (req, res, params) => {
|
|
1286
|
-
const url = new URL(req.url ?? '/', 'http://localhost');
|
|
1287
|
-
const triggerId = url.searchParams.get('triggerId') ?? undefined;
|
|
1288
|
-
const result = buildAsyncTriggerLookupResponse(params.sessionId, triggerId);
|
|
1289
|
-
// Four-state semantics: the query itself succeeds (HTTP 200) for every
|
|
1290
|
-
// resolved state including not_found — task state lives in `result.state`,
|
|
1291
|
-
// not the HTTP status. Only a malformed lookup (ok:false) maps to non-200.
|
|
1292
|
-
jsonRes(res, result.ok ? 200 : 400, result);
|
|
1293
|
-
});
|
|
1294
|
-
// 会话 insight:只读解析本会话的 transcript,产出动作 span / 失败聚合 / 规则建议
|
|
1295
|
-
// (SafeInsightReport)。底层 services/insight 已做 fail-closed 脱敏投影——raw 命令
|
|
1296
|
-
// 与输出永不进结构。detail=summary 只返聚合+建议(/insight 卡片、抽屉概览用);
|
|
1297
|
-
// detail=spans 才带脱敏 span(详情 tab 用)。owner-only 由 dashboard 外层 authed-only
|
|
1298
|
-
// 路由 + /insight 命令层把关,IPC 自身 loopback-trusted。
|
|
1299
|
-
ipcRoute('GET', '/api/sessions/:sessionId/insight', (req, res, params) => {
|
|
1300
|
-
const session = findSessionRecord(params.sessionId);
|
|
1301
|
-
if (!session)
|
|
1302
|
-
return jsonRes(res, 404, { ok: false, error: 'session_not_found' });
|
|
1303
|
-
const url = new URL(req.url ?? '/', 'http://localhost');
|
|
1304
|
-
if (url.searchParams.get('detail') === 'conversation') {
|
|
1305
|
-
const offset = parseInt(url.searchParams.get('offset') ?? '0', 10) || 0;
|
|
1306
|
-
const limit = parseInt(url.searchParams.get('limit') ?? '50', 10) || 50;
|
|
1307
|
-
const role = url.searchParams.get('role');
|
|
1308
|
-
const severity = url.searchParams.get('severity');
|
|
1309
|
-
const tag = url.searchParams.get('tag');
|
|
1310
|
-
const turnIndexes = url.searchParams.getAll('turnIndexes')
|
|
1311
|
-
.flatMap(v => v.split(','))
|
|
1312
|
-
.map(v => parseInt(v, 10))
|
|
1313
|
-
.filter(Number.isFinite);
|
|
1314
|
-
const conversation = buildSafeInsightConversation({
|
|
1315
|
-
cliId: session.cliId ?? 'unknown',
|
|
1316
|
-
sessionId: session.sessionId,
|
|
1317
|
-
cliSessionId: session.cliSessionId,
|
|
1318
|
-
cwd: session.workingDir,
|
|
1319
|
-
larkAppId: session.larkAppId,
|
|
1320
|
-
}, {
|
|
1321
|
-
offset,
|
|
1322
|
-
limit,
|
|
1323
|
-
q: url.searchParams.get('q') ?? undefined,
|
|
1324
|
-
role: role && ['user', 'a2a_agent', 'system', 'agent'].includes(role) ? role : undefined,
|
|
1325
|
-
severity: severity && ['bad', 'warn', 'info'].includes(severity) ? severity : undefined,
|
|
1326
|
-
tag: tag && ['failure', 'slow', 'retry', 'read_write_imbalance', 'diagnostic', 'normal'].includes(tag) ? tag : undefined,
|
|
1327
|
-
turnIndexes: turnIndexes.length ? turnIndexes : undefined,
|
|
1328
|
-
});
|
|
1329
|
-
return jsonRes(res, 200, { ok: true, conversation });
|
|
1330
|
-
}
|
|
1331
|
-
const detail = url.searchParams.get('detail') === 'spans' ? 'spans' : 'summary';
|
|
1332
|
-
try {
|
|
1333
|
-
const report = buildSafeInsightReport({
|
|
1334
|
-
cliId: session.cliId ?? 'unknown',
|
|
1335
|
-
sessionId: session.sessionId,
|
|
1336
|
-
cliSessionId: session.cliSessionId,
|
|
1337
|
-
cwd: session.workingDir,
|
|
1338
|
-
larkAppId: session.larkAppId,
|
|
1339
|
-
}, { detail });
|
|
1340
|
-
jsonRes(res, 200, { ok: true, report });
|
|
1341
|
-
}
|
|
1342
|
-
catch (err) {
|
|
1343
|
-
jsonRes(res, 500, { ok: false, error: String(err?.message ?? err) });
|
|
1344
|
-
}
|
|
1345
|
-
});
|
|
1346
|
-
ipcRoute('GET', '/api/sessions/:sessionId/insight/turn/:turnIndex', (req, res, params) => {
|
|
1347
|
-
const session = findSessionRecord(params.sessionId);
|
|
1348
|
-
if (!session)
|
|
1349
|
-
return jsonRes(res, 404, { ok: false, error: 'session_not_found' });
|
|
1350
|
-
const url = new URL(req.url ?? '/', 'http://localhost');
|
|
1351
|
-
const offset = parseInt(url.searchParams.get('offset') ?? '0', 10) || 0;
|
|
1352
|
-
const limit = parseInt(url.searchParams.get('limit') ?? '4000', 10) || 4000;
|
|
1353
|
-
try {
|
|
1354
|
-
const turn = buildSafeInsightTurnDetail({
|
|
1355
|
-
cliId: session.cliId ?? 'unknown',
|
|
1356
|
-
sessionId: session.sessionId,
|
|
1357
|
-
cliSessionId: session.cliSessionId,
|
|
1358
|
-
cwd: session.workingDir,
|
|
1359
|
-
larkAppId: session.larkAppId,
|
|
1360
|
-
}, parseInt(params.turnIndex, 10) || 0, { offset, limit });
|
|
1361
|
-
jsonRes(res, 200, { ok: true, turn });
|
|
1362
|
-
}
|
|
1363
|
-
catch (err) {
|
|
1364
|
-
jsonRes(res, 500, { ok: false, error: String(err?.message ?? err) });
|
|
1365
|
-
}
|
|
1366
|
-
});
|
|
1367
|
-
// 跨会话 insight 总览:仍然只读、按需、owner-only(外层 dashboard route
|
|
1368
|
-
// 不在 public-read 白名单)。只聚合本 daemon registry 里的 botmux 会话;
|
|
1369
|
-
// 不扫整机 transcript,不返回 raw span/input/output。
|
|
1370
|
-
ipcRoute('GET', '/api/insights/summary', async (req, res) => {
|
|
1371
|
-
const url = new URL(req.url ?? '/', 'http://localhost');
|
|
1372
|
-
const limit = Math.min(Math.max(parseInt(url.searchParams.get('limit') ?? '200', 10) || 200, 1), 500);
|
|
1373
|
-
const rows = composeDashboardSessionRows();
|
|
1374
|
-
const overview = await buildSafeInsightOverview(rows.map(row => {
|
|
1375
|
-
const session = findSessionRecord(row.sessionId);
|
|
1376
|
-
return {
|
|
1377
|
-
cliId: row.cliId,
|
|
1378
|
-
sessionId: row.sessionId,
|
|
1379
|
-
cliSessionId: session?.cliSessionId,
|
|
1380
|
-
cwd: row.workingDir,
|
|
1381
|
-
workingDir: row.workingDir,
|
|
1382
|
-
title: row.title,
|
|
1383
|
-
botName: row.botName,
|
|
1384
|
-
larkAppId: row.larkAppId,
|
|
1385
|
-
status: row.status,
|
|
1386
|
-
lastMessageAt: row.lastMessageAt,
|
|
1387
|
-
};
|
|
1388
|
-
}), { limit });
|
|
1389
|
-
jsonRes(res, 200, { ok: true, overview });
|
|
1390
|
-
});
|
|
1391
|
-
// 部署 owner 的资料(名字 + 头像)——dashboard 左上角和历史弹窗展示「我」。
|
|
1392
|
-
// owner 身份来自 deployment identity(ownerUnionId),头像经 contact API 查询
|
|
1393
|
-
// (带缓存);未绑定 owner 或查不到时回退名字/null。
|
|
1394
|
-
ipcRoute('GET', '/api/owner-profile', async (_req, res) => {
|
|
1395
|
-
if (!cachedLarkAppId)
|
|
1396
|
-
return jsonRes(res, 503, { ok: false, error: 'larkAppId_not_set' });
|
|
1397
|
-
const me = getDeploymentIdentity(config.session.dataDir);
|
|
1398
|
-
if (!me.ownerUnionId)
|
|
1399
|
-
return jsonRes(res, 200, { ok: false, error: 'owner_unbound', name: me.ownerName ?? null });
|
|
1400
|
-
const p = await getUserProfile(cachedLarkAppId, me.ownerUnionId, 'union_id');
|
|
1401
|
-
jsonRes(res, 200, { ok: true, name: p?.name ?? me.ownerName ?? null, avatarUrl: p?.avatarUrl ?? null });
|
|
1402
|
-
});
|
|
1403
|
-
// 会话重命名:dashboard 看板卡片就地编辑 Botmux 的 canonical title;运行中的
|
|
1404
|
-
// Codex/Claude Code 再收到一条 best-effort 原生 /rename,同步其 resume picker。
|
|
1405
|
-
// 飞书话题标题不受影响。全视图(看板/状态板/表格/抽屉)读同一字段。
|
|
1406
|
-
ipcRoute('POST', '/api/sessions/:sessionId/rename', async (req, res, params) => {
|
|
1407
|
-
let body;
|
|
1408
|
-
try {
|
|
1409
|
-
body = await readJsonBody(req);
|
|
1410
|
-
}
|
|
1411
|
-
catch {
|
|
1412
|
-
return jsonRes(res, 400, { ok: false, error: 'bad_json' });
|
|
1413
|
-
}
|
|
1414
|
-
const active = findActiveBySessionId(params.sessionId);
|
|
1415
|
-
const auth = sessionCliIpcAuth(req, active, params.sessionId, body);
|
|
1416
|
-
if (!auth.ok)
|
|
1417
|
-
return jsonRes(res, 403, { ok: false, error: auth.error });
|
|
1418
|
-
const title = normalizeSessionTitle(body.title);
|
|
1419
|
-
if (!title)
|
|
1420
|
-
return jsonRes(res, 400, { ok: false, error: 'bad_title' });
|
|
1421
|
-
const session = active?.session ?? sessionStore.getOwnedSession(params.sessionId);
|
|
1422
|
-
if (!session)
|
|
1423
|
-
return jsonRes(res, 404, { ok: false, error: 'session_not_found' });
|
|
1424
|
-
const source = normalizeSessionTitleSource(body.source, 'dashboard');
|
|
1425
|
-
const updated = updateSessionTitle(session, title, source);
|
|
1426
|
-
if (!updated.ok)
|
|
1427
|
-
return jsonRes(res, 400, { ok: false, error: updated.error });
|
|
1428
|
-
const agentSync = active
|
|
1429
|
-
? requestAgentSessionRename(active, updated.title)
|
|
1430
|
-
: { status: 'not_running' };
|
|
1431
|
-
jsonRes(res, 200, {
|
|
1432
|
-
ok: true,
|
|
1433
|
-
title: updated.title,
|
|
1434
|
-
titleUpdatedAt: updated.updatedAt,
|
|
1435
|
-
titleSource: updated.source,
|
|
1436
|
-
agentSync: agentSync.status,
|
|
1437
|
-
});
|
|
1438
|
-
});
|
|
1439
|
-
// 会话锁定:保护被锁定会话不被 dashboard「清理空闲」批量关闭。锁定是会话元数据,
|
|
1440
|
-
// 不影响用户显式点击关闭/批量关闭,避免把会话变成不可管理状态。
|
|
1441
|
-
ipcRoute('POST', '/api/sessions/:sessionId/lock', async (req, res, params) => {
|
|
1442
|
-
let body;
|
|
1443
|
-
try {
|
|
1444
|
-
body = await readJsonBody(req);
|
|
1445
|
-
}
|
|
1446
|
-
catch {
|
|
1447
|
-
return jsonRes(res, 400, { ok: false, error: 'bad_json' });
|
|
1448
|
-
}
|
|
1449
|
-
if (typeof body.locked !== 'boolean')
|
|
1450
|
-
return jsonRes(res, 400, { ok: false, error: 'bad_locked' });
|
|
1451
|
-
const session = findOwnedSessionRecord(params.sessionId);
|
|
1452
|
-
if (!session)
|
|
1453
|
-
return jsonRes(res, 404, { ok: false, error: 'session_not_found' });
|
|
1454
|
-
if (body.locked)
|
|
1455
|
-
session.locked = true;
|
|
1456
|
-
else
|
|
1457
|
-
delete session.locked;
|
|
1458
|
-
sessionStore.updateSession(session);
|
|
1459
|
-
const locked = !!session.locked;
|
|
1460
|
-
dashboardEventBus.publish({
|
|
1461
|
-
type: 'session.update',
|
|
1462
|
-
body: { sessionId: params.sessionId, patch: { locked } },
|
|
1463
|
-
});
|
|
1464
|
-
jsonRes(res, 200, { ok: true, locked });
|
|
1465
|
-
});
|
|
1466
|
-
/**
|
|
1467
|
-
* Mint the WRITABLE web-terminal link for a live session — the dashboard
|
|
1468
|
-
* counterpart to the Lark card's "🔑 获取操作链接" button. Returns the URL with
|
|
1469
|
-
* the worker's write `?token=` appended, built daemon-side via buildTerminalUrl
|
|
1470
|
-
* so it picks up this process's live terminal-proxy state (the dashboard
|
|
1471
|
-
* aggregator can't see it). The token is returned ONLY here, on demand —
|
|
1472
|
-
* deliberately never embedded in /api/sessions rows or the SSE stream.
|
|
1473
|
-
*
|
|
1474
|
-
* Two gates protect it: at the dashboard's HTTP boundary this path is absent
|
|
1475
|
-
* from the public allow-list, so an anonymous browser 401s; and here on the
|
|
1476
|
-
* daemon IPC, ipcHmacAuthorized requires a loopback-HMAC signed with
|
|
1477
|
-
* .dashboard-secret, so a local process that merely knows the ipcPort still
|
|
1478
|
-
* can't pull a write token.
|
|
1479
|
-
*/
|
|
1480
|
-
ipcRoute('GET', '/api/sessions/:sessionId/write-link', (req, res, params) => {
|
|
1481
|
-
if (!ipcHmacAuthorized(req))
|
|
1482
|
-
return jsonRes(res, 401, { ok: false, error: 'unauthorized' });
|
|
1483
|
-
const ds = findActiveBySessionId(params.sessionId);
|
|
1484
|
-
if (!ds)
|
|
1485
|
-
return jsonRes(res, 404, { ok: false, error: 'session_not_active' });
|
|
1486
|
-
if (!sessionSupportsWebTerminal(ds)) {
|
|
1487
|
-
return jsonRes(res, 409, { ok: false, error: 'terminal_unsupported' });
|
|
1488
|
-
}
|
|
1489
|
-
// Riff backend: the sandbox URL is the writable link — no local worker needed.
|
|
1490
|
-
if (ds.riffAccessUrl) {
|
|
1491
|
-
jsonRes(res, 200, { ok: true, url: ds.riffAccessUrl });
|
|
1492
|
-
return;
|
|
1493
|
-
}
|
|
1494
|
-
const port = ds.workerPort ?? ds.session.webPort;
|
|
1495
|
-
if (!port || !ds.workerToken)
|
|
1496
|
-
return jsonRes(res, 409, { ok: false, error: 'terminal_unavailable' });
|
|
1497
|
-
jsonRes(res, 200, { ok: true, url: buildTerminalUrl(ds, { write: true }) });
|
|
1498
|
-
});
|
|
1499
|
-
/**
|
|
1500
|
-
* Dashboard「复现命令」:返回该 active session 本次冷启的**近似**可复现 CLI 调用
|
|
1501
|
-
* (bin + argv + cwd + 权威注入 env),供用户粘到调试终端改参数复现。命令原样保留
|
|
1502
|
-
* (含 write token / --append-system-prompt / 凭证 env),与 write-link 同一把
|
|
1503
|
-
* loopback-HMAC 锁:匿名浏览器在 dashboard HTTP 边界就 401(该路径不在 allow-list),
|
|
1504
|
-
* 本机知道 ipcPort 的进程也过不了 ipcHmacAuthorized。仅持管理 cookie 的写权限视图能取。
|
|
1505
|
-
*
|
|
1506
|
-
* 只读 active session 的**内存**字段(DaemonSession.spawnCommand):命令含凭证,
|
|
1507
|
-
* 绝不落盘,也绝不从 closed/持久化 session 取(那既无值也避免误暴露)。daemon 重启后
|
|
1508
|
-
* 到 worker 再次 ready 之前返回 unavailable——可接受。warm reattach 不重算命令,此时
|
|
1509
|
-
* 亦为空。riff 后端无本地 bin/args,worker 侧不产出命令,这里同样 unavailable。
|
|
1510
|
-
*/
|
|
1511
|
-
ipcRoute('GET', '/api/sessions/:sessionId/spawn-command', (req, res, params) => {
|
|
1512
|
-
if (!ipcHmacAuthorized(req))
|
|
1513
|
-
return jsonRes(res, 401, { ok: false, error: 'unauthorized' });
|
|
1514
|
-
const ds = findActiveBySessionId(params.sessionId);
|
|
1515
|
-
if (!ds)
|
|
1516
|
-
return jsonRes(res, 404, { ok: false, error: 'session_not_active' });
|
|
1517
|
-
const cmd = ds.spawnCommand;
|
|
1518
|
-
if (!cmd)
|
|
1519
|
-
return jsonRes(res, 404, { ok: false, error: 'spawn_command_unavailable' });
|
|
1520
|
-
jsonRes(res, 200, { ok: true, command: cmd });
|
|
1521
|
-
});
|
|
1522
|
-
/**
|
|
1523
|
-
* Deliver the writable-terminal card privately to the bot's owner(s) — the
|
|
1524
|
-
* `botmux term-link <id>` CLI command's backend. Unlike the GET route above
|
|
1525
|
-
* (which returns the URL to its single authenticated caller), this POSTs the
|
|
1526
|
-
* card into the owners' private Lark channels (ephemeral → DM fallback) and
|
|
1527
|
-
* returns ONLY delivery counts: the write token never crosses back to the CLI /
|
|
1528
|
-
* stdout. Same loopback-HMAC gate as write-link — it still hands out a control
|
|
1529
|
-
* credential, just into Lark rather than into the HTTP response.
|
|
1530
|
-
*/
|
|
1531
|
-
ipcRoute('POST', '/api/sessions/:sessionId/write-link-card', async (req, res, params) => {
|
|
1532
|
-
if (!ipcHmacAuthorized(req))
|
|
1533
|
-
return jsonRes(res, 401, { ok: false, error: 'unauthorized' });
|
|
1534
|
-
const ds = findActiveBySessionId(params.sessionId);
|
|
1535
|
-
if (!ds)
|
|
1536
|
-
return jsonRes(res, 404, { ok: false, error: 'session_not_active' });
|
|
1537
|
-
if (sessionTransportDisabled(ds))
|
|
1538
|
-
return jsonRes(res, 200, { ok: false, error: 'no_feishu_transport' });
|
|
1539
|
-
const r = await deliverWriteLinkCardToOwners(ds);
|
|
1540
|
-
const status = r.ok ? 200
|
|
1541
|
-
: r.error === 'terminal_unavailable' || r.error === 'terminal_unsupported' ? 409
|
|
1542
|
-
: r.error === 'no_owner' ? 422
|
|
1543
|
-
: 502;
|
|
1544
|
-
jsonRes(res, status, r);
|
|
1545
|
-
});
|
|
1546
|
-
// ─── Sandbox landing (owner reviews the clone's diff then applies it back) ───
|
|
1547
|
-
function workingDirForSession(sessionId) {
|
|
1548
|
-
const ds = findActiveBySessionId(sessionId);
|
|
1549
|
-
if (ds)
|
|
1550
|
-
return ds.session.workingDir;
|
|
1551
|
-
return sessionStore.listSessions().find(s => s.sessionId === sessionId)?.workingDir;
|
|
1552
|
-
}
|
|
1553
|
-
/**
|
|
1554
|
-
* Reactivate a closed session — counterpart to `/close`. Used by both the
|
|
1555
|
-
* "▶️ 恢复会话" card button (via card-handler) and the `botmux resume <id>`
|
|
1556
|
-
* CLI command (via this HTTP route). The CLI route also drops a notice into
|
|
1557
|
-
* the original Lark thread so users see why the session is alive again.
|
|
1558
|
-
*/
|
|
1559
|
-
ipcRoute('POST', '/api/sessions/:sessionId/resume', async (req, res, params) => {
|
|
1560
|
-
const sessionId = params.sessionId;
|
|
1561
|
-
const reg = getActiveSessionsRegistry();
|
|
1562
|
-
if (!reg)
|
|
1563
|
-
return jsonRes(res, 503, { ok: false, error: 'registry_unavailable' });
|
|
1564
|
-
const result = await resumeSession(sessionId, reg);
|
|
1565
|
-
if (!result.ok) {
|
|
1566
|
-
const status = result.error === 'not_found' ? 404 : 409;
|
|
1567
|
-
return jsonRes(res, status, { ok: false, error: result.error, activeSessionId: result.activeSessionId });
|
|
1568
|
-
}
|
|
1569
|
-
const ds = result.ds;
|
|
1570
|
-
// `?wake=1` is an opt-in operational hook (no UI/CLI caller wires it today —
|
|
1571
|
-
// it's meant for direct `curl` recovery): instead of the default lazy
|
|
1572
|
-
// cold-resume on the next inbound message, fork the worker immediately so the
|
|
1573
|
-
// session is usable right away. Off by default keeps every existing caller's
|
|
1574
|
-
// behaviour unchanged.
|
|
1575
|
-
const wake = new URL(req.url ?? '/', 'http://localhost').searchParams.get('wake') === '1';
|
|
1576
|
-
// Tell the dashboard the row flipped back to active (mirror of session.update
|
|
1577
|
-
// emitted by closeSession). Use `null` for closedAt — `undefined` would be
|
|
1578
|
-
// dropped by JSON.stringify on the SSE wire and the aggregator's spread
|
|
1579
|
-
// (`{...cur, ...patch}`) would leave the stale closedAt in place.
|
|
1580
|
-
dashboardEventBus.publish({
|
|
1581
|
-
type: 'session.update',
|
|
1582
|
-
body: {
|
|
1583
|
-
sessionId,
|
|
1584
|
-
patch: { status: 'active', closedAt: null },
|
|
1585
|
-
},
|
|
1586
|
-
});
|
|
1587
|
-
// Notify the original chat so humans see why the session is alive again.
|
|
1588
|
-
// Routing follows session.scope — thread-scope replies into the thread root
|
|
1589
|
-
// (reply_in_thread=true), chat-scope posts a plain message to the chat (any
|
|
1590
|
-
// reply_in_thread call would silently get rejected or land on a stale root).
|
|
1591
|
-
const cliId = ds.session.cliId;
|
|
1592
|
-
const botCfg = ds.larkAppId ? getBot(ds.larkAppId).config : undefined;
|
|
1593
|
-
const cliName = sessionConfiguredRuntimeDisplayName(ds.session, botCfg?.cliRuntime)
|
|
1594
|
-
?? getCliDisplayName(cliId ?? botCfg?.cliId ?? 'claude-code');
|
|
1595
|
-
const notice = JSON.stringify({ text: `🔄 会话已通过命令行恢复,发条消息继续与 ${cliName} 对话。` });
|
|
1596
|
-
if (ds.larkAppId && !sessionTransportDisabled(ds)) {
|
|
1597
|
-
if (ds.scope === 'chat' && ds.chatId) {
|
|
1598
|
-
getChatMode(ds.larkAppId, ds.chatId, { forceRefresh: true })
|
|
1599
|
-
.then((mode) => mode === 'topic' && ds.session.rootMessageId
|
|
1600
|
-
? replyMessage(ds.larkAppId, ds.session.rootMessageId, notice, 'text', true)
|
|
1601
|
-
: sendMessage(ds.larkAppId, ds.chatId, notice, 'text'))
|
|
1602
|
-
.catch(err => logger.debug(`[resume] failed to post chat-scope resume notice: ${err}`));
|
|
1603
|
-
}
|
|
1604
|
-
else if (ds.session.rootMessageId) {
|
|
1605
|
-
replyMessage(ds.larkAppId, ds.session.rootMessageId, notice, 'text', true)
|
|
1606
|
-
.catch(err => logger.debug(`[resume] failed to post thread-scope resume notice: ${err}`));
|
|
1607
|
-
}
|
|
1608
|
-
}
|
|
1609
|
-
// Report the EFFECTIVE action, not the raw request flag: only fork when wake
|
|
1610
|
-
// was asked AND there's no live worker to clobber. (resumeSession always hands
|
|
1611
|
-
// back a worker:null ds today, so this matches `wake` in practice — but
|
|
1612
|
-
// reporting the action keeps the response honest if the guard ever broadens.)
|
|
1613
|
-
const woke = wake && (!ds.worker || ds.worker.killed);
|
|
1614
|
-
if (woke) {
|
|
1615
|
-
forkWorker(ds, '', true);
|
|
1616
|
-
}
|
|
1617
|
-
jsonRes(res, 200, {
|
|
1618
|
-
ok: true,
|
|
1619
|
-
sessionId,
|
|
1620
|
-
wake: woke,
|
|
1621
|
-
title: ds.session.title,
|
|
1622
|
-
chatId: ds.chatId,
|
|
1623
|
-
rootMessageId: ds.session.rootMessageId,
|
|
1624
|
-
workingDir: ds.session.workingDir,
|
|
1625
|
-
cliId,
|
|
1626
|
-
});
|
|
1627
|
-
});
|
|
1628
|
-
/**
|
|
1629
|
-
* Cross-daemon session transfer endpoint.
|
|
1630
|
-
*
|
|
1631
|
-
* Called by a *leader* daemon during `/relay --create` to instruct *peer*
|
|
1632
|
-
* daemons to migrate their own session (located by `sourceAnchor`) into a
|
|
1633
|
-
* newly-created chat. The peer daemon authenticates the request and runs its
|
|
1634
|
-
* own `transferSession()` internally — the leader never touches another
|
|
1635
|
-
* daemon's process / tmux / jsonl directly.
|
|
1636
|
-
*
|
|
1637
|
-
* Security:
|
|
1638
|
-
* - Only accepts requests from 127.0.0.1 (no remote daemon coordination).
|
|
1639
|
-
* - `requesterLarkAppId` must be a known bot in this machine's bots
|
|
1640
|
-
* registry. The threat model assumes a malicious bot daemon process is
|
|
1641
|
-
* already root-equivalent on the box; this check just prevents random
|
|
1642
|
-
* other 127.0.0.1 processes from forging migrations.
|
|
1643
|
-
* - `sourceAnchor` must match a session currently owned by *this* daemon
|
|
1644
|
-
* (peer can only move its own sessions — never anybody else's).
|
|
1645
|
-
* - Owner-only: only the original session owner may relocate the session.
|
|
1646
|
-
*
|
|
1647
|
-
* The leader passes `targetRootMessageId` — typically the leader's M1
|
|
1648
|
-
* notification message — so the peer's session lands anchored on a real
|
|
1649
|
-
* message in the new chat. Since the new chat is always chat-scope, the
|
|
1650
|
-
* rootMessageId is only used for audit / display, not routing.
|
|
1651
|
-
*/
|
|
1652
|
-
ipcRoute('POST', '/api/sessions/migrate-to-chat', async (req, res) => {
|
|
1653
|
-
const remote = req.socket.remoteAddress;
|
|
1654
|
-
// node may report '127.0.0.1' or '::ffff:127.0.0.1' (IPv4 mapped) or '::1'.
|
|
1655
|
-
const localish = remote === '127.0.0.1' || remote === '::1' || remote === '::ffff:127.0.0.1';
|
|
1656
|
-
if (!localish)
|
|
1657
|
-
return jsonRes(res, 403, { ok: false, error: 'not_local' });
|
|
1658
|
-
let body;
|
|
1659
|
-
try {
|
|
1660
|
-
body = await readJsonBody(req);
|
|
1661
|
-
}
|
|
1662
|
-
catch {
|
|
1663
|
-
return jsonRes(res, 400, { ok: false, error: 'invalid_json' });
|
|
1664
|
-
}
|
|
1665
|
-
const { sourceAnchor, targetChatId, targetRootMessageId, requesterLarkAppId, requestingUserOpenId, requestingUserUnionId } = body;
|
|
1666
|
-
if (!sourceAnchor || !targetChatId || !targetRootMessageId || !requesterLarkAppId || !requestingUserOpenId) {
|
|
1667
|
-
return jsonRes(res, 400, { ok: false, error: 'missing_field' });
|
|
1668
|
-
}
|
|
1669
|
-
// Requester must be a live botmux daemon — not a random localhost process
|
|
1670
|
-
// pretending to be one. We check the cross-process daemon registry
|
|
1671
|
-
// (~/.botmux/data/dashboard-daemons/<larkAppId>.json + heartbeat) rather
|
|
1672
|
-
// than this process's local bot list: in production each bot has its own
|
|
1673
|
-
// daemon process, and a per-process `getAllBots()` only sees its OWN bot
|
|
1674
|
-
// (botmux is one-daemon-per-bot at boot, daemon.ts:2367). Using the
|
|
1675
|
-
// registry lets the peer recognise the leader bot.
|
|
1676
|
-
const requesterKnown = listOnlineDaemons().some(d => d.larkAppId === requesterLarkAppId);
|
|
1677
|
-
if (!requesterKnown)
|
|
1678
|
-
return jsonRes(res, 403, { ok: false, error: 'unknown_requester' });
|
|
1679
|
-
// Locate this daemon's own session at the given source anchor. We match
|
|
1680
|
-
// by anchor (rootMessageId for thread-scope, chatId for chat-scope) AND
|
|
1681
|
-
// larkAppId — multi-bot threads share a rootMessageId but each bot's
|
|
1682
|
-
// session is uniquely keyed by (anchor, larkAppId).
|
|
1683
|
-
const reg = getActiveSessionsRegistry();
|
|
1684
|
-
if (!reg)
|
|
1685
|
-
return jsonRes(res, 503, { ok: false, error: 'registry_unavailable' });
|
|
1686
|
-
let ds = undefined;
|
|
1687
|
-
for (const candidate of reg.values()) {
|
|
1688
|
-
const candAnchor = sessionAnchorId(candidate);
|
|
1689
|
-
if (candAnchor === sourceAnchor && candidate.larkAppId === cachedLarkAppId) {
|
|
1690
|
-
ds = candidate;
|
|
1691
|
-
break;
|
|
1692
|
-
}
|
|
1693
|
-
}
|
|
1694
|
-
if (!ds)
|
|
1695
|
-
return jsonRes(res, 404, { ok: false, error: 'no_session_at_anchor' });
|
|
1696
|
-
// Owner-only: the user who triggered /relay --create must own this peer's
|
|
1697
|
-
// session too. If a peer's session is owned by someone else, we refuse —
|
|
1698
|
-
// the leader summarises this as "skipped: not your session" rather than
|
|
1699
|
-
// forcing a transfer of someone else's work.
|
|
1700
|
-
//
|
|
1701
|
-
// Cross-app identity: Lark `open_id` is app-scoped — the same user has a
|
|
1702
|
-
// different open_id in each bot's namespace, so leader's senderOpenId
|
|
1703
|
-
// and peer's stored ownerOpenId cannot be compared directly. Prefer
|
|
1704
|
-
// `union_id` (stable across apps within a tenant) when both sides have
|
|
1705
|
-
// it. Sessions persisted before ownerUnionId existed fall through to a
|
|
1706
|
-
// lazy backfill: resolve peer's stored open_id → union_id via Lark API
|
|
1707
|
-
// (using PEER's bot client, so the open_id is in the right namespace),
|
|
1708
|
-
// persist for next time, and compare.
|
|
1709
|
-
if (ds.session.ownerOpenId) {
|
|
1710
|
-
let peerOwnerUnionId = ds.session.ownerUnionId;
|
|
1711
|
-
if (!peerOwnerUnionId && requestingUserUnionId) {
|
|
1712
|
-
// Backfill: legacy session, look up the union_id via Lark API once
|
|
1713
|
-
// and persist it so subsequent comparisons (and any other code path
|
|
1714
|
-
// that grows to read it) are fast.
|
|
1715
|
-
const looked = await resolveUnionIdFromOpenId(ds.larkAppId, ds.session.ownerOpenId);
|
|
1716
|
-
if (looked) {
|
|
1717
|
-
peerOwnerUnionId = looked;
|
|
1718
|
-
ds.session.ownerUnionId = looked;
|
|
1719
|
-
sessionStore.updateSession(ds.session);
|
|
1720
|
-
}
|
|
1721
|
-
}
|
|
1722
|
-
const ownerMatch = (peerOwnerUnionId && requestingUserUnionId)
|
|
1723
|
-
? peerOwnerUnionId === requestingUserUnionId
|
|
1724
|
-
// Same-bot fallback (no union_id on either side): open_id namespaces
|
|
1725
|
-
// match, so direct compare works.
|
|
1726
|
-
: ds.session.ownerOpenId === requestingUserOpenId;
|
|
1727
|
-
if (!ownerMatch) {
|
|
1728
|
-
return jsonRes(res, 403, { ok: false, error: 'not_session_owner' });
|
|
1729
|
-
}
|
|
1730
|
-
}
|
|
1731
|
-
// Target chat was built by the leader's /relay --create — by
|
|
1732
|
-
// construction a regular group, chat-scope (M1 is the audit anchor).
|
|
1733
|
-
const result = await transferSession(ds.session.sessionId, targetChatId, targetRootMessageId, 'group', 'chat');
|
|
1734
|
-
if (!result.ok) {
|
|
1735
|
-
return jsonRes(res, 500, { ok: false, error: result.error });
|
|
1736
|
-
}
|
|
1737
|
-
jsonRes(res, 200, { ok: true, sessionId: ds.session.sessionId });
|
|
1738
|
-
});
|
|
1739
|
-
ipcRoute('POST', '/api/sessions/:sessionId/locate', async (_req, res, params) => {
|
|
1740
|
-
const sid = params.sessionId;
|
|
1741
|
-
const acq = locateLimiter.tryAcquire(sid);
|
|
1742
|
-
if (!acq.ok) {
|
|
1743
|
-
res.writeHead(429, {
|
|
1744
|
-
'content-type': 'application/json',
|
|
1745
|
-
'retry-after': String(Math.ceil(acq.retryAfterMs / 1000)),
|
|
1746
|
-
});
|
|
1747
|
-
res.end(JSON.stringify({ ok: false, error: 'rate_limited', retryAfterMs: acq.retryAfterMs }));
|
|
1748
|
-
return;
|
|
1749
|
-
}
|
|
1750
|
-
// Resolve owning session (active first, then closed-store fallback). The
|
|
1751
|
-
// locate marker is a bare @-mention of the session's owner — no other text,
|
|
1752
|
-
// no AppLink redirect on the frontend. The notification on the user's
|
|
1753
|
-
// device is enough to navigate them back to the topic.
|
|
1754
|
-
const ds = findActiveBySessionId(sid);
|
|
1755
|
-
const closed = ds ? null : sessionStore.getSession(sid);
|
|
1756
|
-
const ctx = ds
|
|
1757
|
-
? {
|
|
1758
|
-
larkAppId: ds.larkAppId,
|
|
1759
|
-
rootMessageId: ds.session.rootMessageId,
|
|
1760
|
-
ownerOpenId: ds.session.ownerOpenId,
|
|
1761
|
-
}
|
|
1762
|
-
: closed
|
|
1763
|
-
? {
|
|
1764
|
-
larkAppId: closed.larkAppId ?? '',
|
|
1765
|
-
rootMessageId: closed.rootMessageId,
|
|
1766
|
-
ownerOpenId: closed.ownerOpenId,
|
|
1767
|
-
}
|
|
1768
|
-
: null;
|
|
1769
|
-
if (!ctx || !ctx.larkAppId) {
|
|
1770
|
-
return jsonRes(res, 404, { ok: false, error: 'session_not_found' });
|
|
1771
|
-
}
|
|
1772
|
-
if (!ctx.ownerOpenId) {
|
|
1773
|
-
return jsonRes(res, 422, { ok: false, error: 'no_owner' });
|
|
1774
|
-
}
|
|
1775
|
-
// No-transport session (apiOnly bot or HTTP virtual chat) has no Feishu thread
|
|
1776
|
-
// to @-locate the owner in — the replyMessage below would dial Feishu.
|
|
1777
|
-
if (sessionTransportDisabled({ chatId: ds?.chatId ?? closed?.chatId, larkAppId: ctx.larkAppId })) {
|
|
1778
|
-
return jsonRes(res, 200, { ok: false, error: 'no_feishu_transport' });
|
|
1779
|
-
}
|
|
1780
|
-
try {
|
|
1781
|
-
const messageId = await replyMessage(ctx.larkAppId, ctx.rootMessageId, `<at user_id="${ctx.ownerOpenId}"></at>`, 'text', true);
|
|
1782
|
-
jsonRes(res, 200, { ok: true, messageId });
|
|
1783
|
-
}
|
|
1784
|
-
catch (err) {
|
|
1785
|
-
jsonRes(res, 502, { ok: false, error: String(err) });
|
|
1786
|
-
}
|
|
1787
|
-
});
|
|
1788
|
-
function composeScheduleRow(t) {
|
|
1789
|
-
return {
|
|
1790
|
-
id: t.id,
|
|
1791
|
-
name: t.name,
|
|
1792
|
-
schedule: t.schedule,
|
|
1793
|
-
parsed: t.parsed,
|
|
1794
|
-
prompt: t.prompt,
|
|
1795
|
-
workingDir: t.workingDir,
|
|
1796
|
-
chatId: t.chatId,
|
|
1797
|
-
rootMessageId: t.rootMessageId,
|
|
1798
|
-
scope: t.scope,
|
|
1799
|
-
executionPosition: scheduler.resolveTaskExecutionPosition(t),
|
|
1800
|
-
topicTitle: t.topicTitle,
|
|
1801
|
-
larkAppId: t.larkAppId,
|
|
1802
|
-
botName: getBotName(),
|
|
1803
|
-
enabled: t.enabled,
|
|
1804
|
-
createdAt: t.createdAt,
|
|
1805
|
-
lastRunAt: t.lastRunAt,
|
|
1806
|
-
nextRunAt: t.nextRunAt,
|
|
1807
|
-
lastStatus: t.lastStatus,
|
|
1808
|
-
lastError: t.lastError,
|
|
1809
|
-
repeat: t.repeat,
|
|
1810
|
-
deliver: t.deliver ?? 'origin',
|
|
1811
|
-
silent: t.silent,
|
|
1812
|
-
feishuChatLink: feishuChatLink(t.chatId, getBotBrand(t.larkAppId)),
|
|
1813
|
-
};
|
|
1814
|
-
}
|
|
1815
|
-
ipcRoute('GET', '/api/schedules', (_req, res) => {
|
|
1816
|
-
// Filter to tasks owned by this daemon's bot (multi-bot setups run one
|
|
1817
|
-
// daemon per bot — each only manages its own schedules). belongsToOwner
|
|
1818
|
-
// falls through to "all tasks" when no owner filter is configured (tests).
|
|
1819
|
-
const all = scheduleStore.listTasks().filter(t => scheduler.belongsToOwner(t));
|
|
1820
|
-
jsonRes(res, 200, { schedules: all.map(composeScheduleRow) });
|
|
1821
|
-
});
|
|
1822
|
-
ipcRoute('POST', '/api/schedules/:id/run', (_req, res, p) => jsonRes(res, 200, scheduler.runNow(p.id)));
|
|
1823
|
-
ipcRoute('POST', '/api/schedules/:id/pause', (_req, res, p) => jsonRes(res, 200, scheduler.setEnabled(p.id, false)));
|
|
1824
|
-
ipcRoute('POST', '/api/schedules/:id/resume', (_req, res, p) => jsonRes(res, 200, scheduler.setEnabled(p.id, true)));
|
|
1825
|
-
// Backward-compatible route used by Lark cards and cached dashboard clients.
|
|
1826
|
-
// Modern callers send an exact target; body-less legacy callers keep the
|
|
1827
|
-
// historical toggle behavior, now cycling topic → top-level → fresh topic.
|
|
1828
|
-
ipcRoute('POST', '/api/schedules/:id/delivery', async (req, res, p) => {
|
|
1829
|
-
let body;
|
|
1830
|
-
try {
|
|
1831
|
-
body = await readJsonBody(req);
|
|
1832
|
-
}
|
|
1833
|
-
catch {
|
|
1834
|
-
return jsonRes(res, 400, { ok: false, error: 'invalid_json' });
|
|
1835
|
-
}
|
|
1836
|
-
const requested = body && typeof body === 'object'
|
|
1837
|
-
? body.executionPosition
|
|
1838
|
-
: undefined;
|
|
1839
|
-
if (requested !== undefined) {
|
|
1840
|
-
if (requested !== 'top-level' && requested !== 'topic' && requested !== 'new-topic') {
|
|
1841
|
-
return jsonRes(res, 400, { ok: false, error: 'invalid_execution_position', field: 'executionPosition' });
|
|
1842
|
-
}
|
|
1843
|
-
const result = scheduler.updateTask(p.id, { executionPosition: requested });
|
|
1844
|
-
return jsonRes(res, 200, result.ok ? { ...result, executionPosition: requested } : result);
|
|
1845
|
-
}
|
|
1846
|
-
return jsonRes(res, 200, scheduler.toggleDelivery(p.id));
|
|
1847
|
-
});
|
|
1848
|
-
// Create a new scheduled task from the dashboard. chatId selects which chat
|
|
1849
|
-
// the task fires into; workingDir defaults to the daemon's cwd.
|
|
1850
|
-
ipcRoute('POST', '/api/schedules', async (req, res) => {
|
|
1851
|
-
if (!cachedLarkAppId)
|
|
1852
|
-
return jsonRes(res, 503, { ok: false, error: 'larkAppId_not_set' });
|
|
1853
|
-
let body;
|
|
1854
|
-
try {
|
|
1855
|
-
body = await readJsonBody(req);
|
|
1856
|
-
}
|
|
1857
|
-
catch {
|
|
1858
|
-
return jsonRes(res, 400, { ok: false, error: 'invalid_json' });
|
|
1859
|
-
}
|
|
1860
|
-
if (body === null || typeof body !== 'object') {
|
|
1861
|
-
return jsonRes(res, 400, { ok: false, error: 'body_must_be_object' });
|
|
1862
|
-
}
|
|
1863
|
-
const b = body;
|
|
1864
|
-
// Runtime validation — never trust the TS cast alone.
|
|
1865
|
-
const name = typeof b.name === 'string' ? b.name.trim() : '';
|
|
1866
|
-
const schedule = typeof b.schedule === 'string' ? b.schedule.trim() : '';
|
|
1867
|
-
const prompt = typeof b.prompt === 'string' ? b.prompt : '';
|
|
1868
|
-
const chatId = typeof b.chatId === 'string' ? b.chatId.trim() : '';
|
|
1869
|
-
const rootMessageId = typeof b.rootMessageId === 'string' ? b.rootMessageId.trim() : '';
|
|
1870
|
-
// Validate silent type — if present, must be boolean (no silent degradation).
|
|
1871
|
-
let silent = false;
|
|
1872
|
-
if (b.silent !== undefined) {
|
|
1873
|
-
if (typeof b.silent !== 'boolean') {
|
|
1874
|
-
return jsonRes(res, 400, { ok: false, error: 'invalid_field', field: 'silent' });
|
|
1875
|
-
}
|
|
1876
|
-
silent = b.silent;
|
|
1877
|
-
}
|
|
1878
|
-
let executionPosition = 'top-level';
|
|
1879
|
-
if (b.executionPosition !== undefined) {
|
|
1880
|
-
if (b.executionPosition !== 'top-level' && b.executionPosition !== 'topic' && b.executionPosition !== 'new-topic') {
|
|
1881
|
-
return jsonRes(res, 400, { ok: false, error: 'invalid_execution_position', field: 'executionPosition' });
|
|
1882
|
-
}
|
|
1883
|
-
executionPosition = b.executionPosition;
|
|
1884
|
-
}
|
|
1885
|
-
const topicTitle = typeof b.topicTitle === 'string' ? b.topicTitle.trim() : '';
|
|
1886
|
-
if (b.topicTitle !== undefined && typeof b.topicTitle !== 'string') {
|
|
1887
|
-
return jsonRes(res, 400, { ok: false, error: 'invalid_field', field: 'topicTitle' });
|
|
1888
|
-
}
|
|
1889
|
-
if (Array.from(topicTitle).length > 200) {
|
|
1890
|
-
return jsonRes(res, 400, { ok: false, error: 'topic_title_too_long', field: 'topicTitle' });
|
|
1891
|
-
}
|
|
1892
|
-
// Legacy clients sending deliver:new-topic retain the historical meaning:
|
|
1893
|
-
// open a fresh topic/session on every run.
|
|
1894
|
-
let deliver = 'origin';
|
|
1895
|
-
if (b.deliver !== undefined) {
|
|
1896
|
-
if (b.deliver !== 'origin' && b.deliver !== 'new-topic') {
|
|
1897
|
-
return jsonRes(res, 400, { ok: false, error: 'invalid_deliver', field: 'deliver' });
|
|
1898
|
-
}
|
|
1899
|
-
deliver = b.deliver;
|
|
1900
|
-
if (b.executionPosition === undefined && deliver === 'new-topic')
|
|
1901
|
-
executionPosition = 'new-topic';
|
|
1902
|
-
}
|
|
1903
|
-
// Validate required fields are present AND non-empty after trim.
|
|
1904
|
-
if (!name)
|
|
1905
|
-
return jsonRes(res, 400, { ok: false, error: 'invalid_field', field: 'name' });
|
|
1906
|
-
if (!schedule)
|
|
1907
|
-
return jsonRes(res, 400, { ok: false, error: 'invalid_field', field: 'schedule' });
|
|
1908
|
-
if (!prompt.trim())
|
|
1909
|
-
return jsonRes(res, 400, { ok: false, error: 'invalid_field', field: 'prompt' });
|
|
1910
|
-
if (!chatId)
|
|
1911
|
-
return jsonRes(res, 400, { ok: false, error: 'invalid_field', field: 'chatId' });
|
|
1912
|
-
if (executionPosition === 'topic' && !rootMessageId) {
|
|
1913
|
-
return jsonRes(res, 400, { ok: false, error: 'topic_root_required', field: 'rootMessageId' });
|
|
1914
|
-
}
|
|
1915
|
-
// Note: bot↔chat membership is intentionally NOT validated here.
|
|
1916
|
-
// listChatBotMembers returns [] both when the API is unavailable and when
|
|
1917
|
-
// no bot has been observed in the chat yet, so we cannot reliably tell
|
|
1918
|
-
// "bot not in chat" (should 400) from "unknown" (should fail-open).
|
|
1919
|
-
// A task whose bot is not in the target chat will fail at fire time with
|
|
1920
|
-
// a clear lastError, which is the pre-existing behavior for CLI-created
|
|
1921
|
-
// tasks. Adding a flaky gate here would block valid creates.
|
|
1922
|
-
try {
|
|
1923
|
-
const task = scheduler.addTask({
|
|
1924
|
-
name,
|
|
1925
|
-
schedule,
|
|
1926
|
-
prompt,
|
|
1927
|
-
workingDir: typeof b.workingDir === 'string' ? b.workingDir : process.cwd(),
|
|
1928
|
-
chatId,
|
|
1929
|
-
rootMessageId: rootMessageId || undefined,
|
|
1930
|
-
scope: executionPosition === 'topic' ? 'thread' : 'chat',
|
|
1931
|
-
executionPosition,
|
|
1932
|
-
topicTitle: topicTitle || undefined,
|
|
1933
|
-
chatType: 'group',
|
|
1934
|
-
larkAppId: cachedLarkAppId,
|
|
1935
|
-
deliver,
|
|
1936
|
-
silent,
|
|
1937
|
-
});
|
|
1938
|
-
dashboardEventBus.publish({ type: 'schedule.created', body: { schedule: composeScheduleRow(task) } });
|
|
1939
|
-
jsonRes(res, 200, { ok: true, task: composeScheduleRow(task) });
|
|
1940
|
-
}
|
|
1941
|
-
catch (err) {
|
|
1942
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
1943
|
-
jsonRes(res, 400, { ok: false, error: msg });
|
|
1944
|
-
}
|
|
1945
|
-
});
|
|
1946
|
-
// Update editable fields of an existing task. Execution position is explicit;
|
|
1947
|
-
// topic execution requires a retained/provided topic root message id.
|
|
1948
|
-
ipcRoute('PATCH', '/api/schedules/:id', async (req, res, p) => {
|
|
1949
|
-
let body;
|
|
1950
|
-
try {
|
|
1951
|
-
body = await readJsonBody(req);
|
|
1952
|
-
}
|
|
1953
|
-
catch {
|
|
1954
|
-
return jsonRes(res, 400, { ok: false, error: 'invalid_json' });
|
|
1955
|
-
}
|
|
1956
|
-
if (body === null || typeof body !== 'object') {
|
|
1957
|
-
return jsonRes(res, 400, { ok: false, error: 'body_must_be_object' });
|
|
1958
|
-
}
|
|
1959
|
-
const b = body;
|
|
1960
|
-
const updates = {};
|
|
1961
|
-
// If a field is present, it must be the correct type and (for strings)
|
|
1962
|
-
// non-empty after trim — otherwise 400, never silently ignore.
|
|
1963
|
-
if (b.name !== undefined) {
|
|
1964
|
-
if (typeof b.name !== 'string' || !b.name.trim()) {
|
|
1965
|
-
return jsonRes(res, 400, { ok: false, error: 'invalid_field', field: 'name' });
|
|
1966
|
-
}
|
|
1967
|
-
updates.name = b.name.trim();
|
|
1968
|
-
}
|
|
1969
|
-
if (b.prompt !== undefined) {
|
|
1970
|
-
if (typeof b.prompt !== 'string' || !b.prompt.trim()) {
|
|
1971
|
-
return jsonRes(res, 400, { ok: false, error: 'invalid_field', field: 'prompt' });
|
|
1972
|
-
}
|
|
1973
|
-
updates.prompt = b.prompt;
|
|
1974
|
-
}
|
|
1975
|
-
if (b.schedule !== undefined) {
|
|
1976
|
-
if (typeof b.schedule !== 'string' || !b.schedule.trim()) {
|
|
1977
|
-
return jsonRes(res, 400, { ok: false, error: 'invalid_field', field: 'schedule' });
|
|
1978
|
-
}
|
|
1979
|
-
updates.schedule = b.schedule.trim();
|
|
1980
|
-
}
|
|
1981
|
-
if (b.deliver !== undefined) {
|
|
1982
|
-
if (b.deliver !== 'origin' && b.deliver !== 'new-topic') {
|
|
1983
|
-
return jsonRes(res, 400, { ok: false, error: 'invalid_deliver', field: 'deliver' });
|
|
1984
|
-
}
|
|
1985
|
-
updates.deliver = b.deliver;
|
|
1986
|
-
}
|
|
1987
|
-
if (b.executionPosition !== undefined) {
|
|
1988
|
-
if (b.executionPosition !== 'top-level' && b.executionPosition !== 'topic' && b.executionPosition !== 'new-topic') {
|
|
1989
|
-
return jsonRes(res, 400, { ok: false, error: 'invalid_execution_position', field: 'executionPosition' });
|
|
1990
|
-
}
|
|
1991
|
-
updates.executionPosition = b.executionPosition;
|
|
1992
|
-
}
|
|
1993
|
-
if (b.rootMessageId !== undefined) {
|
|
1994
|
-
if (typeof b.rootMessageId !== 'string') {
|
|
1995
|
-
return jsonRes(res, 400, { ok: false, error: 'invalid_field', field: 'rootMessageId' });
|
|
1996
|
-
}
|
|
1997
|
-
updates.rootMessageId = b.rootMessageId.trim();
|
|
1998
|
-
}
|
|
1999
|
-
if (b.topicTitle !== undefined) {
|
|
2000
|
-
if (typeof b.topicTitle !== 'string') {
|
|
2001
|
-
return jsonRes(res, 400, { ok: false, error: 'invalid_field', field: 'topicTitle' });
|
|
2002
|
-
}
|
|
2003
|
-
const topicTitle = b.topicTitle.trim();
|
|
2004
|
-
if (Array.from(topicTitle).length > 200) {
|
|
2005
|
-
return jsonRes(res, 400, { ok: false, error: 'topic_title_too_long', field: 'topicTitle' });
|
|
2006
|
-
}
|
|
2007
|
-
updates.topicTitle = topicTitle;
|
|
2008
|
-
}
|
|
2009
|
-
if (b.silent !== undefined) {
|
|
2010
|
-
if (typeof b.silent !== 'boolean') {
|
|
2011
|
-
return jsonRes(res, 400, { ok: false, error: 'invalid_field', field: 'silent' });
|
|
2012
|
-
}
|
|
2013
|
-
updates.silent = b.silent;
|
|
2014
|
-
}
|
|
2015
|
-
const result = scheduler.updateTask(p.id, updates);
|
|
2016
|
-
if (!result.ok)
|
|
2017
|
-
return jsonRes(res, 400, result);
|
|
2018
|
-
const task = scheduleStore.getTask(p.id);
|
|
2019
|
-
jsonRes(res, 200, { ok: true, task: task ? composeScheduleRow(task) : undefined });
|
|
2020
|
-
});
|
|
2021
|
-
// Delete a scheduled task.
|
|
2022
|
-
ipcRoute('DELETE', '/api/schedules/:id', (_req, res, p) => {
|
|
2023
|
-
jsonRes(res, 200, scheduler.removeTaskForDashboard(p.id));
|
|
2024
|
-
});
|
|
2025
|
-
ipcRoute('POST', '/api/trigger', async (req, res) => {
|
|
2026
|
-
if (!cachedLarkAppId)
|
|
2027
|
-
return jsonRes(res, 503, { ok: false, errorCode: 'bot_not_found', error: 'larkAppId_not_set' });
|
|
2028
|
-
const activeSessions = getActiveSessionsRegistry();
|
|
2029
|
-
if (!activeSessions)
|
|
2030
|
-
return jsonRes(res, 503, { ok: false, errorCode: 'trigger_failed', error: 'active session registry unavailable' });
|
|
2031
|
-
let body;
|
|
2032
|
-
try {
|
|
2033
|
-
body = await readJsonBody(req);
|
|
2034
|
-
}
|
|
2035
|
-
catch {
|
|
2036
|
-
return jsonRes(res, 400, { ok: false, errorCode: 'bad_json', error: 'invalid JSON body' });
|
|
2037
|
-
}
|
|
2038
|
-
const valid = validateTriggerRequest(body);
|
|
2039
|
-
if (!valid.ok)
|
|
2040
|
-
return jsonRes(res, valid.status, valid.body);
|
|
2041
|
-
if (valid.request.target.botId && valid.request.target.botId !== cachedLarkAppId) {
|
|
2042
|
-
return jsonRes(res, 400, {
|
|
2043
|
-
ok: false,
|
|
2044
|
-
errorCode: 'bot_not_found',
|
|
2045
|
-
error: `request target botId ${valid.request.target.botId} does not match daemon ${cachedLarkAppId}`,
|
|
2046
|
-
});
|
|
2047
|
-
}
|
|
2048
|
-
if (valid.request.target.kind === 'turn' && valid.request.target.sessionId) {
|
|
2049
|
-
const receiverTarget = [...activeSessions.values()].find((candidate) => candidate.session.sessionId === valid.request.target.sessionId);
|
|
2050
|
-
if (receiverTarget?.session.vcMeetingReceiver) {
|
|
2051
|
-
return jsonRes(res, 403, {
|
|
2052
|
-
ok: false,
|
|
2053
|
-
errorCode: 'managed_receiver_requires_delivery_endpoint',
|
|
2054
|
-
error: 'dedicated meeting receiver sessions accept only fenced delivery or explicit IM routing',
|
|
2055
|
-
});
|
|
2056
|
-
}
|
|
2057
|
-
}
|
|
2058
|
-
try {
|
|
2059
|
-
if (valid.request.target.kind === 'workflow') {
|
|
2060
|
-
return jsonRes(res, 410, {
|
|
2061
|
-
ok: false,
|
|
2062
|
-
errorCode: 'legacy_workflow_retired',
|
|
2063
|
-
error: 'v2 workflow trigger targets are retired; migrate the definition and run it through /workflow',
|
|
2064
|
-
});
|
|
2065
|
-
}
|
|
2066
|
-
const activeSessions = getActiveSessionsRegistry();
|
|
2067
|
-
if (!activeSessions) {
|
|
2068
|
-
return jsonRes(res, 503, {
|
|
2069
|
-
ok: false,
|
|
2070
|
-
errorCode: 'trigger_failed',
|
|
2071
|
-
error: 'active session registry unavailable',
|
|
2072
|
-
});
|
|
2073
|
-
}
|
|
2074
|
-
const result = await triggerSessionTurn(valid.request, { larkAppId: cachedLarkAppId, activeSessions });
|
|
2075
|
-
const status = result.ok
|
|
2076
|
-
? 200
|
|
2077
|
-
: result.errorCode === 'bot_not_in_chat'
|
|
2078
|
-
? 403
|
|
2079
|
-
: result.errorCode === 'session_not_found'
|
|
2080
|
-
? 404
|
|
2081
|
-
: result.errorCode === 'wait_timeout'
|
|
2082
|
-
? 504
|
|
2083
|
-
: result.errorCode === 'target_required' || result.errorCode === 'bad_request'
|
|
2084
|
-
? 400
|
|
2085
|
-
: 500;
|
|
2086
|
-
return jsonRes(res, status, result);
|
|
2087
|
-
}
|
|
2088
|
-
catch (e) {
|
|
2089
|
-
return jsonRes(res, 500, { ok: false, errorCode: 'trigger_failed', error: e?.message ?? String(e) });
|
|
2090
|
-
}
|
|
2091
|
-
});
|
|
2092
|
-
// ─── Exact chat grants (talk-only) ─────────────────────────────────────────
|
|
2093
|
-
/**
|
|
2094
|
-
* Apply/read/revoke a receiver-scoped chatGrant. The receiver identity comes
|
|
2095
|
-
* from this daemon's cached larkAppId, never from the caller. The body repeats
|
|
2096
|
-
* it only as an anti-misrouting assertion (e.g. a stale daemon descriptor).
|
|
2097
|
-
*
|
|
2098
|
-
* This permission write is loopback-HMAC protected: a sandboxed worker that
|
|
2099
|
-
* merely discovers an ipcPort must not be able to grant itself access.
|
|
2100
|
-
*/
|
|
2101
|
-
ipcRoute('POST', '/api/grants/chat', async (req, res) => {
|
|
2102
|
-
const localPort = req.socket.localPort;
|
|
2103
|
-
const authBind = localPort ? cliAuthBind('POST', '/api/grants/chat', localPort) : undefined;
|
|
2104
|
-
if (!authBind || !tokenRouteAuthorized(req, authBind)) {
|
|
2105
|
-
return jsonRes(res, 401, { ok: false, error: 'unauthorized' });
|
|
2106
|
-
}
|
|
2107
|
-
if (!cachedLarkAppId) {
|
|
2108
|
-
return jsonRes(res, 503, { ok: false, error: 'larkAppId_not_set' });
|
|
2109
|
-
}
|
|
2110
|
-
let body;
|
|
2111
|
-
try {
|
|
2112
|
-
body = await readJsonBody(req);
|
|
2113
|
-
}
|
|
2114
|
-
catch {
|
|
2115
|
-
return jsonRes(res, 400, { ok: false, error: 'bad_json' });
|
|
2116
|
-
}
|
|
2117
|
-
if (body.receiverLarkAppId !== cachedLarkAppId) {
|
|
2118
|
-
return jsonRes(res, 409, {
|
|
2119
|
-
ok: false,
|
|
2120
|
-
error: 'receiver_mismatch',
|
|
2121
|
-
receiverLarkAppId: cachedLarkAppId,
|
|
2122
|
-
});
|
|
2123
|
-
}
|
|
2124
|
-
const hasSubjectOpenIds = Object.prototype.hasOwnProperty.call(body, 'subjectOpenIds');
|
|
2125
|
-
const hasSubjectLarkAppIds = Object.prototype.hasOwnProperty.call(body, 'subjectLarkAppIds');
|
|
2126
|
-
if (hasSubjectOpenIds === hasSubjectLarkAppIds) {
|
|
2127
|
-
return jsonRes(res, 400, {
|
|
2128
|
-
ok: false,
|
|
2129
|
-
error: 'exactly_one_subject_identity_required',
|
|
2130
|
-
message: 'Provide exactly one of subjectOpenIds or subjectLarkAppIds',
|
|
2131
|
-
});
|
|
2132
|
-
}
|
|
2133
|
-
if (hasSubjectLarkAppIds && body.operation !== 'grant') {
|
|
2134
|
-
return jsonRes(res, 400, {
|
|
2135
|
-
ok: false,
|
|
2136
|
-
error: 'subject_lark_app_ids_grant_only',
|
|
2137
|
-
message: 'subjectLarkAppIds may only be used with operation=grant',
|
|
2138
|
-
});
|
|
2139
|
-
}
|
|
2140
|
-
const result = hasSubjectLarkAppIds
|
|
2141
|
-
? await exactChatGrantHandler({
|
|
2142
|
-
operation: body.operation,
|
|
2143
|
-
receiverLarkAppId: cachedLarkAppId,
|
|
2144
|
-
chatId: body.chatId,
|
|
2145
|
-
subjectLarkAppIds: body.subjectLarkAppIds,
|
|
2146
|
-
})
|
|
2147
|
-
: await exactChatGrantHandler({
|
|
2148
|
-
operation: body.operation,
|
|
2149
|
-
receiverLarkAppId: cachedLarkAppId,
|
|
2150
|
-
chatId: body.chatId,
|
|
2151
|
-
subjectOpenIds: body.subjectOpenIds,
|
|
2152
|
-
});
|
|
2153
|
-
if (!result.ok) {
|
|
2154
|
-
const { status, ...responseBody } = result;
|
|
2155
|
-
return jsonRes(res, status, responseBody);
|
|
2156
|
-
}
|
|
2157
|
-
return jsonRes(res, 200, result);
|
|
2158
|
-
});
|
|
2159
|
-
// ─── Groups (Phase B) ──────────────────────────────────────────────────────
|
|
2160
|
-
ipcRoute('GET', '/api/groups', async (_req, res) => {
|
|
2161
|
-
if (!cachedLarkAppId)
|
|
2162
|
-
return jsonRes(res, 503, { error: 'larkAppId_not_set' });
|
|
2163
|
-
try {
|
|
2164
|
-
const chats = await groupsStore.listChats(cachedLarkAppId);
|
|
2165
|
-
// Stamp a firstSeenAt timestamp for every chat (preserve existing values,
|
|
2166
|
-
// backfill new ones with Date.now()). Lark doesn't expose chat create_time
|
|
2167
|
-
// anywhere, so the dashboard sorts by this client-side proxy instead.
|
|
2168
|
-
const seenMap = chatFirstSeenStore.markSeenBulk(chats.map(c => c.chatId));
|
|
2169
|
-
// Annotate each chat with its oncall binding (if any) so the dashboard
|
|
2170
|
-
// matrix can show toggle state without a second round-trip.
|
|
2171
|
-
const enriched = chats.map(c => {
|
|
2172
|
-
const oncall = oncallStore.getOncallStatus(cachedLarkAppId, c.chatId);
|
|
2173
|
-
const hasRole = resolveRoleFile(cachedLarkAppId, c.chatId) !== null;
|
|
2174
|
-
const hasMessageListener = getMessageListenerConfig(cachedLarkAppId, c.chatId)?.enabled === true;
|
|
2175
|
-
// /introduce 记录的外部 botmux 机器人(按名字)——dashboard 团队看板用
|
|
2176
|
-
// 它识别「介绍过同团队机器人的协作群」。
|
|
2177
|
-
const observedBotNames = observedBotsStore
|
|
2178
|
-
.listObservedBots(config.session.dataDir, cachedLarkAppId, c.chatId)
|
|
2179
|
-
.map(b => b.name);
|
|
2180
|
-
return { ...c, oncallChat: oncall ?? null, firstSeenAt: seenMap.get(c.chatId) ?? null, hasRole, hasMessageListener, observedBotNames };
|
|
2181
|
-
});
|
|
2182
|
-
jsonRes(res, 200, { chats: enriched });
|
|
2183
|
-
}
|
|
2184
|
-
catch (e) {
|
|
2185
|
-
jsonRes(res, 502, { error: String(e) });
|
|
2186
|
-
}
|
|
2187
|
-
});
|
|
2188
|
-
ipcRoute('GET', '/api/groups/:chatId/membership', async (_req, res, p) => {
|
|
2189
|
-
if (!cachedLarkAppId)
|
|
2190
|
-
return jsonRes(res, 503, { error: 'larkAppId_not_set' });
|
|
2191
|
-
try {
|
|
2192
|
-
const inChat = await groupsStore.isInChat(cachedLarkAppId, p.chatId);
|
|
2193
|
-
jsonRes(res, 200, { inChat });
|
|
2194
|
-
}
|
|
2195
|
-
catch (e) {
|
|
2196
|
-
jsonRes(res, 502, { error: String(e) });
|
|
2197
|
-
}
|
|
2198
|
-
});
|
|
2199
|
-
ipcRoute('POST', '/api/groups/:chatId/add-bots', async (req, res, p) => {
|
|
2200
|
-
if (!cachedLarkAppId)
|
|
2201
|
-
return jsonRes(res, 503, { error: 'larkAppId_not_set' });
|
|
2202
|
-
let body;
|
|
2203
|
-
try {
|
|
2204
|
-
body = await readJsonBody(req);
|
|
2205
|
-
}
|
|
2206
|
-
catch {
|
|
2207
|
-
return jsonRes(res, 400, { error: 'bad_json' });
|
|
2208
|
-
}
|
|
2209
|
-
if (!Array.isArray(body.larkAppIds) || !body.larkAppIds.every(x => typeof x === 'string')) {
|
|
2210
|
-
return jsonRes(res, 400, { error: 'larkAppIds_required' });
|
|
2211
|
-
}
|
|
2212
|
-
try {
|
|
2213
|
-
const result = await groupsStore.addBotToChat(cachedLarkAppId, p.chatId, body.larkAppIds);
|
|
2214
|
-
jsonRes(res, 200, { result });
|
|
2215
|
-
}
|
|
2216
|
-
catch (e) {
|
|
2217
|
-
jsonRes(res, 502, { error: String(e) });
|
|
2218
|
-
}
|
|
2219
|
-
});
|
|
2220
|
-
// Disband (delete) a chat from this bot's identity. Public route picks an
|
|
2221
|
-
// in-chat bot as the executor; this just performs the call.
|
|
2222
|
-
ipcRoute('POST', '/api/groups/:chatId/disband', async (_req, res, p) => {
|
|
2223
|
-
if (!cachedLarkAppId)
|
|
2224
|
-
return jsonRes(res, 503, { error: 'larkAppId_not_set' });
|
|
2225
|
-
const r = await groupsStore.disbandChat(cachedLarkAppId, p.chatId);
|
|
2226
|
-
jsonRes(res, 200, r);
|
|
2227
|
-
});
|
|
2228
|
-
// Make this bot leave the chat. Always works on a member bot per Lark docs.
|
|
2229
|
-
ipcRoute('POST', '/api/groups/:chatId/leave', async (_req, res, p) => {
|
|
2230
|
-
if (!cachedLarkAppId)
|
|
2231
|
-
return jsonRes(res, 503, { error: 'larkAppId_not_set' });
|
|
2232
|
-
const r = await groupsStore.leaveChat(cachedLarkAppId, p.chatId);
|
|
2233
|
-
jsonRes(res, 200, r);
|
|
2234
|
-
});
|
|
2235
|
-
// 平台团队大厅打卡:dashboard 在 team-sync 后编排本机 bot 往大厅(bot-only 群)
|
|
2236
|
-
// 发登记消息。实测大厅只有「直接点名 @」会投递(普通消息/自 @/@all 全部静默),
|
|
2237
|
-
// 所以打卡消息点名 @ 本机其他未入册 bot(mentionNames,open_id 由本 app 的
|
|
2238
|
-
// cross-ref 解析——open_id 是 per-app 的,只有发送方自己能解析),被点到的 bot
|
|
2239
|
-
// 从 mentions 学到自己的 union_id。回声路径保留(有 receive-all scope 的应用仍可
|
|
2240
|
-
// 从自家消息学)。已入册且无人可教时幂等跳过。
|
|
2241
|
-
ipcRoute('POST', '/api/platform/hall-announce', async (req, res) => {
|
|
2242
|
-
if (!cachedLarkAppId)
|
|
2243
|
-
return jsonRes(res, 503, { ok: false, error: 'larkAppId_not_set' });
|
|
2244
|
-
let body;
|
|
2245
|
-
try {
|
|
2246
|
-
body = await readJsonBody(req);
|
|
2247
|
-
}
|
|
2248
|
-
catch {
|
|
2249
|
-
return jsonRes(res, 400, { ok: false, error: 'bad_json' });
|
|
2250
|
-
}
|
|
2251
|
-
const chatId = typeof body.chatId === 'string' ? body.chatId.trim() : '';
|
|
2252
|
-
if (!/^oc_[0-9a-f]+$/i.test(chatId))
|
|
2253
|
-
return jsonRes(res, 400, { ok: false, error: 'bad_chat_id' });
|
|
2254
|
-
const mentionNames = Array.isArray(body.mentionNames)
|
|
2255
|
-
? body.mentionNames.filter((x) => typeof x === 'string' && !!x.trim())
|
|
2256
|
-
: [];
|
|
2257
|
-
// 解析点名目标:name → 本 app 视角的 open_id(cross-ref,来自历史 @ 事件)。解析不到的跳过。
|
|
2258
|
-
const resolved = [];
|
|
2259
|
-
if (mentionNames.length) {
|
|
2260
|
-
try {
|
|
2261
|
-
const map = JSON.parse(readFileSync(join(config.session.dataDir, `bot-openids-${cachedLarkAppId}.json`), 'utf-8'));
|
|
2262
|
-
for (const name of mentionNames) {
|
|
2263
|
-
const openId = map[name];
|
|
2264
|
-
if (typeof openId === 'string' && openId.startsWith('ou_'))
|
|
2265
|
-
resolved.push({ name, openId });
|
|
2266
|
-
}
|
|
2267
|
-
}
|
|
2268
|
-
catch { /* 无 cross-ref → 全部解析失败,退化为普通打卡 */ }
|
|
2269
|
-
}
|
|
2270
|
-
if (getBotUnionId(config.session.dataDir, cachedLarkAppId) && resolved.length === 0) {
|
|
2271
|
-
return jsonRes(res, 200, { ok: true, skipped: 'already_learned' });
|
|
2272
|
-
}
|
|
2273
|
-
try {
|
|
2274
|
-
const atPrefix = resolved.map((r) => `<at user_id="${r.openId}">${r.name}</at> `).join('');
|
|
2275
|
-
// 自己还没入册 → 带 #hall-echo 请求回执:被点到的 bot 会 @ 回我们一次,
|
|
2276
|
-
// 我们从回执的 mentions[] 学到自己的 union_id(见 event-dispatcher hall 分支)。
|
|
2277
|
-
const echoTag = getBotUnionId(config.session.dataDir, cachedLarkAppId) ? '' : ' #hall-echo';
|
|
2278
|
-
await sendMessage(cachedLarkAppId, chatId, atPrefix + t('platform.hall_announce', undefined, localeForBot(cachedLarkAppId)) + echoTag, 'text');
|
|
2279
|
-
jsonRes(res, 200, { ok: true, mentioned: resolved.map((r) => r.name), unresolved: mentionNames.filter((n) => !resolved.some((r) => r.name === n)) });
|
|
2280
|
-
}
|
|
2281
|
-
catch (e) {
|
|
2282
|
-
jsonRes(res, 502, { ok: false, error: `send_failed: ${e.message}` });
|
|
2283
|
-
}
|
|
2284
|
-
});
|
|
2285
|
-
// ─── Oncall bindings (dashboard) ───────────────────────────────────────────
|
|
2286
|
-
// PUT /api/oncall/:chatId body: {workingDir} — bind or update workingDir
|
|
2287
|
-
// DELETE /api/oncall/:chatId — unbind
|
|
2288
|
-
//
|
|
2289
|
-
// Auth: dashboard's loopback token is the gate. No per-chat owner concept —
|
|
2290
|
-
// allowedUsers governs who can operate via Lark too (see canOperate).
|
|
2291
|
-
ipcRoute('PUT', '/api/oncall/:chatId', async (req, res, p) => {
|
|
2292
|
-
if (!cachedLarkAppId)
|
|
2293
|
-
return jsonRes(res, 503, { error: 'larkAppId_not_set' });
|
|
2294
|
-
let body;
|
|
2295
|
-
try {
|
|
2296
|
-
body = await readJsonBody(req);
|
|
2297
|
-
}
|
|
2298
|
-
catch {
|
|
2299
|
-
return jsonRes(res, 400, { ok: false, error: 'bad_json' });
|
|
2300
|
-
}
|
|
2301
|
-
const workingDir = typeof body.workingDir === 'string' ? body.workingDir.trim() : '';
|
|
2302
|
-
if (!workingDir)
|
|
2303
|
-
return jsonRes(res, 400, { ok: false, error: 'workingDir_required' });
|
|
2304
|
-
// Same validation as /oncall bind in Lark — exists + is a directory.
|
|
2305
|
-
const v = validateWorkingDir(workingDir);
|
|
2306
|
-
if (!v.ok)
|
|
2307
|
-
return jsonRes(res, 400, { ok: false, error: v.error });
|
|
2308
|
-
const resolvedPath = v.resolvedPath;
|
|
2309
|
-
const r = await oncallStore.bindOncall(cachedLarkAppId, p.chatId, workingDir);
|
|
2310
|
-
if (!r.ok)
|
|
2311
|
-
return jsonRes(res, 400, r);
|
|
2312
|
-
jsonRes(res, 200, { ok: true, entry: r.entry, created: r.created, resolvedPath });
|
|
2313
|
-
});
|
|
2314
|
-
ipcRoute('DELETE', '/api/oncall/:chatId', async (_req, res, p) => {
|
|
2315
|
-
if (!cachedLarkAppId)
|
|
2316
|
-
return jsonRes(res, 503, { error: 'larkAppId_not_set' });
|
|
2317
|
-
// Idempotent: always succeeds. unbindOncall writes a tombstone into
|
|
2318
|
-
// defaultOncallAutoboundChats so the auto-bind judge won't reinstate this
|
|
2319
|
-
// chat on the next observation, even if it had no prior binding.
|
|
2320
|
-
const r = await oncallStore.unbindOncall(cachedLarkAppId, p.chatId);
|
|
2321
|
-
if (!r.ok)
|
|
2322
|
-
return jsonRes(res, 400, r);
|
|
2323
|
-
jsonRes(res, 200, { ok: true, wasBound: r.wasBound });
|
|
2324
|
-
});
|
|
2325
|
-
// ─── Role management (dashboard) ───────────────────────────────────────────
|
|
2326
|
-
// POST /api/roles/batch body: {chatIds: string[]} → role snapshots
|
|
2327
|
-
// GET /api/roles/:chatId → { chatId, content, byteLength, injectMode, effectiveContent, effectiveSource }
|
|
2328
|
-
// PUT /api/roles/:chatId body: {content?, injectMode?} → write role file and/or injection mode
|
|
2329
|
-
// DELETE /api/roles/:chatId → remove role file (and injection-mode sidecar)
|
|
2330
|
-
const MAX_ROLE_BATCH_CHAT_IDS = 1_000;
|
|
2331
|
-
function dashboardRolePayload(larkAppId, chatId) {
|
|
2332
|
-
const content = resolveRoleFile(larkAppId, chatId);
|
|
2333
|
-
const effective = resolveRole(larkAppId, chatId);
|
|
2334
|
-
return {
|
|
2335
|
-
chatId,
|
|
2336
|
-
content,
|
|
2337
|
-
byteLength: content ? Buffer.byteLength(content, 'utf-8') : 0,
|
|
2338
|
-
hasRole: content !== null,
|
|
2339
|
-
injectMode: readRoleInjectMode(larkAppId, chatId),
|
|
2340
|
-
effectiveContent: effective.content,
|
|
2341
|
-
effectiveSource: effective.source,
|
|
2342
|
-
effectiveByteLength: effective.content ? Buffer.byteLength(effective.content, 'utf-8') : 0,
|
|
2343
|
-
hasEffectiveRole: effective.content !== null,
|
|
2344
|
-
};
|
|
2345
|
-
}
|
|
2346
|
-
ipcRoute('POST', '/api/roles/batch', async (req, res) => {
|
|
2347
|
-
if (!cachedLarkAppId)
|
|
2348
|
-
return jsonRes(res, 503, { error: 'larkAppId_not_set' });
|
|
2349
|
-
let body;
|
|
2350
|
-
try {
|
|
2351
|
-
body = await readJsonBody(req);
|
|
2352
|
-
}
|
|
2353
|
-
catch {
|
|
2354
|
-
return jsonRes(res, 400, { ok: false, error: 'bad_json' });
|
|
2355
|
-
}
|
|
2356
|
-
if (!Array.isArray(body.chatIds))
|
|
2357
|
-
return jsonRes(res, 400, { ok: false, error: 'chat_ids_required' });
|
|
2358
|
-
if (body.chatIds.length > MAX_ROLE_BATCH_CHAT_IDS) {
|
|
2359
|
-
return jsonRes(res, 400, { ok: false, error: 'too_many_chat_ids' });
|
|
2360
|
-
}
|
|
2361
|
-
if (body.chatIds.some(chatId => typeof chatId !== 'string' || !isValidRoleChatId(chatId))) {
|
|
2362
|
-
return jsonRes(res, 400, { ok: false, error: 'invalid_chat_id' });
|
|
2363
|
-
}
|
|
2364
|
-
const chatIds = [...new Set(body.chatIds)];
|
|
2365
|
-
jsonRes(res, 200, { roles: chatIds.map(chatId => dashboardRolePayload(cachedLarkAppId, chatId)) });
|
|
2366
|
-
});
|
|
2367
|
-
ipcRoute('GET', '/api/roles/:chatId', async (_req, res, p) => {
|
|
2368
|
-
if (!cachedLarkAppId)
|
|
2369
|
-
return jsonRes(res, 503, { error: 'larkAppId_not_set' });
|
|
2370
|
-
if (!isValidRoleChatId(p.chatId))
|
|
2371
|
-
return jsonRes(res, 400, { ok: false, error: 'invalid_chat_id' });
|
|
2372
|
-
jsonRes(res, 200, dashboardRolePayload(cachedLarkAppId, p.chatId));
|
|
2373
|
-
});
|
|
2374
|
-
ipcRoute('PUT', '/api/roles/:chatId', async (req, res, p) => {
|
|
2375
|
-
if (!cachedLarkAppId)
|
|
2376
|
-
return jsonRes(res, 503, { error: 'larkAppId_not_set' });
|
|
2377
|
-
if (!isValidRoleChatId(p.chatId))
|
|
2378
|
-
return jsonRes(res, 400, { ok: false, error: 'invalid_chat_id' });
|
|
2379
|
-
let body;
|
|
2380
|
-
try {
|
|
2381
|
-
body = await readJsonBody(req);
|
|
2382
|
-
}
|
|
2383
|
-
catch {
|
|
2384
|
-
return jsonRes(res, 400, { ok: false, error: 'bad_json' });
|
|
2385
|
-
}
|
|
2386
|
-
// injectMode is a per-chat setting that can be updated on its own (no content)
|
|
2387
|
-
// — e.g. toggling "inject once" for a chat whose effective role is the team
|
|
2388
|
-
// default. Only 'every'/'once' are accepted; anything else is ignored.
|
|
2389
|
-
const injectMode = body.injectMode === 'once' ? 'once' : body.injectMode === 'every' ? 'every' : undefined;
|
|
2390
|
-
const hasContentField = typeof body.content === 'string';
|
|
2391
|
-
const content = hasContentField ? body.content.trim() : '';
|
|
2392
|
-
if (!hasContentField && injectMode === undefined) {
|
|
2393
|
-
return jsonRes(res, 400, { ok: false, error: 'content_or_inject_mode_required' });
|
|
2394
|
-
}
|
|
2395
|
-
if (hasContentField && !content)
|
|
2396
|
-
return jsonRes(res, 400, { ok: false, error: 'content_required' });
|
|
2397
|
-
try {
|
|
2398
|
-
if (hasContentField)
|
|
2399
|
-
writeRoleFile(cachedLarkAppId, p.chatId, content);
|
|
2400
|
-
if (injectMode !== undefined)
|
|
2401
|
-
writeRoleInjectMode(cachedLarkAppId, p.chatId, injectMode);
|
|
2402
|
-
// `changed` reflects whether the role FILE (→ hasRole in the groups matrix)
|
|
2403
|
-
// was written. An injectMode-only PUT touches just the .meta.json sidecar and
|
|
2404
|
-
// leaves hasRole untouched, so it reports changed:false — the dashboard uses
|
|
2405
|
-
// this to avoid needlessly busting its 30s groups-matrix snapshot on the
|
|
2406
|
-
// common inject-mode toggle.
|
|
2407
|
-
jsonRes(res, 200, { ok: true, changed: hasContentField });
|
|
2408
|
-
}
|
|
2409
|
-
catch (e) {
|
|
2410
|
-
jsonRes(res, 500, { ok: false, error: String(e) });
|
|
2411
|
-
}
|
|
2412
|
-
});
|
|
2413
|
-
ipcRoute('DELETE', '/api/roles/:chatId', async (_req, res, p) => {
|
|
2414
|
-
if (!cachedLarkAppId)
|
|
2415
|
-
return jsonRes(res, 503, { error: 'larkAppId_not_set' });
|
|
2416
|
-
if (!isValidRoleChatId(p.chatId))
|
|
2417
|
-
return jsonRes(res, 400, { ok: false, error: 'invalid_chat_id' });
|
|
2418
|
-
const existed = deleteRoleFile(cachedLarkAppId, p.chatId);
|
|
2419
|
-
deleteRoleInjectMode(cachedLarkAppId, p.chatId);
|
|
2420
|
-
// `changed` mirrors `existed`: a DELETE that removed nothing didn't flip
|
|
2421
|
-
// hasRole, so the dashboard skips invalidating its groups-matrix snapshot.
|
|
2422
|
-
jsonRes(res, 200, { ok: true, existed, changed: existed });
|
|
2423
|
-
});
|
|
2424
|
-
ipcRoute('GET', '/api/message-listeners/:chatId', async (_req, res, p) => {
|
|
2425
|
-
if (!cachedLarkAppId)
|
|
2426
|
-
return jsonRes(res, 503, { error: 'larkAppId_not_set' });
|
|
2427
|
-
if (!isValidRoleChatId(p.chatId))
|
|
2428
|
-
return jsonRes(res, 400, { ok: false, error: 'invalid_chat_id' });
|
|
2429
|
-
jsonRes(res, 200, {
|
|
2430
|
-
chatId: p.chatId,
|
|
2431
|
-
listener: getMessageListenerConfig(cachedLarkAppId, p.chatId),
|
|
2432
|
-
maxPromptBytes: MAX_MESSAGE_LISTENER_PROMPT_BYTES,
|
|
2433
|
-
});
|
|
2434
|
-
});
|
|
2435
|
-
ipcRoute('PUT', '/api/message-listeners/:chatId', async (req, res, p) => {
|
|
2436
|
-
if (!cachedLarkAppId)
|
|
2437
|
-
return jsonRes(res, 503, { error: 'larkAppId_not_set' });
|
|
2438
|
-
if (!isValidRoleChatId(p.chatId))
|
|
2439
|
-
return jsonRes(res, 400, { ok: false, error: 'invalid_chat_id' });
|
|
2440
|
-
let body;
|
|
2441
|
-
try {
|
|
2442
|
-
body = await readJsonBody(req);
|
|
2443
|
-
}
|
|
2444
|
-
catch {
|
|
2445
|
-
return jsonRes(res, 400, { ok: false, error: 'bad_json' });
|
|
2446
|
-
}
|
|
2447
|
-
const update = sanitizeMessageListenerUpdate(body);
|
|
2448
|
-
if (!update)
|
|
2449
|
-
return jsonRes(res, 400, { ok: false, error: 'invalid_listener' });
|
|
2450
|
-
const validation = validateMessageListenerUpdate(update);
|
|
2451
|
-
if (!validation.ok)
|
|
2452
|
-
return jsonRes(res, 400, { ok: false, error: validation.reason });
|
|
2453
|
-
if (update.prompt && Buffer.byteLength(update.prompt, 'utf-8') > MAX_MESSAGE_LISTENER_PROMPT_BYTES) {
|
|
2454
|
-
return jsonRes(res, 400, { ok: false, error: 'prompt_too_large' });
|
|
2455
|
-
}
|
|
2456
|
-
const result = await updateMessageListenerConfig(cachedLarkAppId, p.chatId, update);
|
|
2457
|
-
if (!result.ok)
|
|
2458
|
-
return jsonRes(res, ['prompt_required', 'sender_required'].includes(result.reason) ? 400 : 500, { ok: false, error: result.reason });
|
|
2459
|
-
jsonRes(res, 200, { ok: true, listener: result.listener });
|
|
2460
|
-
});
|
|
2461
|
-
function dashboardHistoryMessageSender(message) {
|
|
2462
|
-
const sender = message?.sender ?? {};
|
|
2463
|
-
// Prefer `open_bot_id` (present on bot senders when with_sender_name=true): it
|
|
2464
|
-
// is the bot's per-app open_id, matching /members/bots and the stored sender
|
|
2465
|
-
// filters. Mirrors historyMessageSender in event-dispatcher so preview and the
|
|
2466
|
-
// 30s poll resolve a third-party bot identically. See that fn for detail.
|
|
2467
|
-
const senderId = sender.open_bot_id ?? sender.id ?? sender.open_id ?? sender.user_id ?? sender.app_id
|
|
2468
|
-
?? message?.sender_id?.open_id ?? message?.sender_id?.user_id ?? message?.sender_id?.app_id;
|
|
2469
|
-
const senderName = sender.sender_name ?? sender.name ?? sender.user_name ?? message?.sender_name;
|
|
2470
|
-
const rawIdType = sender.id_type ?? sender.sender_id_type;
|
|
2471
|
-
const senderIdType = sender.open_bot_id ? 'open_id' : rawIdType;
|
|
2472
|
-
const senderTypeRaw = sender.sender_type ?? message?.sender_type ?? (rawIdType === 'app_id' ? 'app' : undefined);
|
|
2473
|
-
return {
|
|
2474
|
-
senderOpenId: typeof senderId === 'string' ? senderId : undefined,
|
|
2475
|
-
senderName: typeof senderName === 'string' && senderName.trim() ? senderName.trim() : undefined,
|
|
2476
|
-
senderTypeRaw: typeof senderTypeRaw === 'string' ? senderTypeRaw : undefined,
|
|
2477
|
-
senderIdType: typeof senderIdType === 'string' ? senderIdType : undefined,
|
|
2478
|
-
};
|
|
2479
|
-
}
|
|
2480
|
-
function dashboardMessageCreateTimeMs(message) {
|
|
2481
|
-
const value = Number(message?.create_time ?? message?.createTime);
|
|
2482
|
-
return Number.isFinite(value) ? value : undefined;
|
|
2483
|
-
}
|
|
2484
|
-
async function readMessageListenerPreviewRequest(req) {
|
|
2485
|
-
let body;
|
|
2486
|
-
try {
|
|
2487
|
-
body = await readJsonBody(req);
|
|
2488
|
-
}
|
|
2489
|
-
catch {
|
|
2490
|
-
return { ok: false, status: 400, error: 'bad_json' };
|
|
2491
|
-
}
|
|
2492
|
-
const raw = body && typeof body === 'object' && !Array.isArray(body) ? body : {};
|
|
2493
|
-
const listener = sanitizeMessageListenerUpdate(raw.listener ?? raw);
|
|
2494
|
-
if (!listener)
|
|
2495
|
-
return { ok: false, status: 400, error: 'invalid_listener' };
|
|
2496
|
-
const validation = validateMessageListenerUpdate(listener);
|
|
2497
|
-
if (!validation.ok)
|
|
2498
|
-
return { ok: false, status: 400, error: validation.reason };
|
|
2499
|
-
if (listener.prompt && Buffer.byteLength(listener.prompt, 'utf-8') > MAX_MESSAGE_LISTENER_PROMPT_BYTES) {
|
|
2500
|
-
return { ok: false, status: 400, error: 'prompt_too_large' };
|
|
2501
|
-
}
|
|
2502
|
-
return { ok: true, listener, limit: normalizeMessageListenerPreviewLimit(raw.limit) };
|
|
2503
|
-
}
|
|
2504
|
-
async function collectMessageListenerPreviewMatches(larkAppId, chatId, listener, limit) {
|
|
2505
|
-
const bot = getBot(larkAppId);
|
|
2506
|
-
const previewListener = {
|
|
2507
|
-
enabled: true,
|
|
2508
|
-
...(listener.name ? { name: listener.name } : {}),
|
|
2509
|
-
...(listener.replyCardTitle ? { replyCardTitle: listener.replyCardTitle } : {}),
|
|
2510
|
-
...(listener.workingDir ? { workingDir: listener.workingDir } : {}),
|
|
2511
|
-
prompt: listener.prompt,
|
|
2512
|
-
...(listener.senderPolicy && Object.keys(listener.senderPolicy).length > 0 ? { senderPolicy: listener.senderPolicy } : {}),
|
|
2513
|
-
...(listener.messagePolicy ? { messagePolicy: { ...listener.messagePolicy, scope: 'top_level' } } : { messagePolicy: { scope: 'top_level' } }),
|
|
2514
|
-
replyPolicy: { mode: 'thread', sessionMode: 'per_message' },
|
|
2515
|
-
};
|
|
2516
|
-
const previewBot = {
|
|
2517
|
-
...bot,
|
|
2518
|
-
config: {
|
|
2519
|
-
...bot.config,
|
|
2520
|
-
messageListeners: {
|
|
2521
|
-
...(bot.config.messageListeners ?? {}),
|
|
2522
|
-
[chatId]: previewListener,
|
|
2523
|
-
},
|
|
2524
|
-
},
|
|
2525
|
-
};
|
|
2526
|
-
const cutoff = Date.now() - MESSAGE_LISTENER_PREVIEW_WINDOW_MS;
|
|
2527
|
-
const messages = await listChatMessagesUntil(larkAppId, chatId, {
|
|
2528
|
-
pageSize: 50,
|
|
2529
|
-
stopAfter: (message, seenCount) => {
|
|
2530
|
-
const createdAt = dashboardMessageCreateTimeMs(message);
|
|
2531
|
-
return seenCount >= Math.max(100, limit * 5) ||
|
|
2532
|
-
(Number.isFinite(createdAt) && createdAt < cutoff);
|
|
2533
|
-
},
|
|
2534
|
-
});
|
|
2535
|
-
const candidateBotAppIds = collectListenerBotAppIds(messages, dashboardHistoryMessageSender);
|
|
2536
|
-
const appIdToOpenId = await buildListenerBotAppIdToOpenId(larkAppId, chatId, candidateBotAppIds);
|
|
2537
|
-
const matches = previewMessageListenerMatches({
|
|
2538
|
-
bot: previewBot,
|
|
2539
|
-
chatId,
|
|
2540
|
-
messages,
|
|
2541
|
-
limit,
|
|
2542
|
-
senderForMessage: dashboardHistoryMessageSender,
|
|
2543
|
-
appIdToOpenId,
|
|
2544
|
-
// Mirror realtime/poll routing: a message that explicitly @mentions this bot
|
|
2545
|
-
// hands off to normal @-routing, NOT the listener — so preview/run-preview
|
|
2546
|
-
// must apply the same gate (else preview over-counts and run-preview would
|
|
2547
|
-
// spawn a session for a message live routing never sends to the listener).
|
|
2548
|
-
explicitlyMentionedThisBot: (message) => messageMentionsBot(message, larkAppId, bot.botOpenId),
|
|
2549
|
-
});
|
|
2550
|
-
// The listener matcher extracts card text from the SIMPLIFIED history view,
|
|
2551
|
-
// which drops button jump URLs. The live delivery path (handleNewTopic) fixes
|
|
2552
|
-
// this by re-extracting after resolveNonsupportMessage merges the card's two
|
|
2553
|
-
// representations. Preview/run-preview do NOT go through handleNewTopic, so
|
|
2554
|
-
// apply the equivalent merge here: run-preview spawns REAL turns off
|
|
2555
|
-
// match.messageText, and preview display should show the same links the live
|
|
2556
|
-
// listener will. Only interactive cards need it; a resolver miss keeps the
|
|
2557
|
-
// match-time text. Resolve concurrently — each match is an independent fetch.
|
|
2558
|
-
await Promise.all(matches.map(async (match) => {
|
|
2559
|
-
if (match.msgType !== 'interactive')
|
|
2560
|
-
return;
|
|
2561
|
-
const merged = await resolveMergedCardContent(larkAppId, match.messageId).catch(() => null);
|
|
2562
|
-
if (merged?.text?.trim())
|
|
2563
|
-
match.messageText = merged.text;
|
|
2564
|
-
}));
|
|
2565
|
-
return matches;
|
|
2566
|
-
}
|
|
2567
|
-
function publicMessageListenerMatch(match) {
|
|
2568
|
-
return {
|
|
2569
|
-
messageId: match.messageId,
|
|
2570
|
-
createTime: match.createTime,
|
|
2571
|
-
messageText: match.messageText,
|
|
2572
|
-
messageTitle: match.messageTitle,
|
|
2573
|
-
msgType: match.msgType,
|
|
2574
|
-
senderOpenId: match.senderOpenId,
|
|
2575
|
-
senderName: match.senderName,
|
|
2576
|
-
senderType: match.senderType,
|
|
2577
|
-
};
|
|
2578
|
-
}
|
|
2579
|
-
ipcRoute('POST', '/api/message-listeners/:chatId/preview', async (req, res, p) => {
|
|
2580
|
-
if (!cachedLarkAppId)
|
|
2581
|
-
return jsonRes(res, 503, { ok: false, error: 'larkAppId_not_set' });
|
|
2582
|
-
if (!isValidRoleChatId(p.chatId))
|
|
2583
|
-
return jsonRes(res, 400, { ok: false, error: 'invalid_chat_id' });
|
|
2584
|
-
const parsed = await readMessageListenerPreviewRequest(req);
|
|
2585
|
-
if (!parsed.ok)
|
|
2586
|
-
return jsonRes(res, parsed.status, { ok: false, error: parsed.error });
|
|
2587
|
-
try {
|
|
2588
|
-
const matches = await collectMessageListenerPreviewMatches(cachedLarkAppId, p.chatId, parsed.listener, parsed.limit);
|
|
2589
|
-
jsonRes(res, 200, {
|
|
2590
|
-
ok: true,
|
|
2591
|
-
requestedLimit: parsed.limit,
|
|
2592
|
-
matches: matches.map(publicMessageListenerMatch),
|
|
2593
|
-
});
|
|
2594
|
-
}
|
|
2595
|
-
catch (err) {
|
|
2596
|
-
jsonRes(res, 502, { ok: false, error: err instanceof Error ? err.message : String(err) });
|
|
2597
|
-
}
|
|
2598
|
-
});
|
|
2599
|
-
ipcRoute('POST', '/api/message-listeners/:chatId/run-preview', async (req, res, p) => {
|
|
2600
|
-
if (!cachedLarkAppId)
|
|
2601
|
-
return jsonRes(res, 503, { ok: false, error: 'larkAppId_not_set' });
|
|
2602
|
-
if (!isValidRoleChatId(p.chatId))
|
|
2603
|
-
return jsonRes(res, 400, { ok: false, error: 'invalid_chat_id' });
|
|
2604
|
-
const activeSessions = getActiveSessionsRegistry();
|
|
2605
|
-
if (!activeSessions)
|
|
2606
|
-
return jsonRes(res, 503, { ok: false, error: 'active session registry unavailable' });
|
|
2607
|
-
const parsed = await readMessageListenerPreviewRequest(req);
|
|
2608
|
-
if (!parsed.ok)
|
|
2609
|
-
return jsonRes(res, parsed.status, { ok: false, error: parsed.error });
|
|
2610
|
-
try {
|
|
2611
|
-
const matches = await collectMessageListenerPreviewMatches(cachedLarkAppId, p.chatId, parsed.listener, parsed.limit);
|
|
2612
|
-
const run = createMessageListenerRunPreview(cachedLarkAppId, p.chatId, matches.map(match => match.messageId));
|
|
2613
|
-
const results = [];
|
|
2614
|
-
for (const match of matches) {
|
|
2615
|
-
const triggerId = createMessageListenerRunPreviewTurnId();
|
|
2616
|
-
try {
|
|
2617
|
-
const result = await triggerSessionTurn({
|
|
2618
|
-
source: {
|
|
2619
|
-
type: 'ui',
|
|
2620
|
-
connectorId: 'message-listener-preview',
|
|
2621
|
-
requestId: `listener-preview:${match.messageId}`,
|
|
2622
|
-
receivedAt: new Date().toISOString(),
|
|
2623
|
-
},
|
|
2624
|
-
target: {
|
|
2625
|
-
kind: 'turn',
|
|
2626
|
-
botId: cachedLarkAppId,
|
|
2627
|
-
chatId: p.chatId,
|
|
2628
|
-
rootMessageId: match.messageId,
|
|
2629
|
-
},
|
|
2630
|
-
envelope: {
|
|
2631
|
-
format: 'message_listener',
|
|
2632
|
-
sourceName: match.name || 'Message Listener Preview',
|
|
2633
|
-
trusted: false,
|
|
2634
|
-
payload: publicMessageListenerMatch(match),
|
|
2635
|
-
rawText: match.messageText,
|
|
2636
|
-
},
|
|
2637
|
-
instruction: renderMessageListenerInstruction(match),
|
|
2638
|
-
presentation: { topicMessage: null },
|
|
2639
|
-
}, { larkAppId: cachedLarkAppId, activeSessions }, { stableTurnId: triggerId });
|
|
2640
|
-
const tracked = result.ok
|
|
2641
|
-
? markMessageListenerRunPreviewTriggered(run.runId, match.messageId, {
|
|
2642
|
-
action: result.action,
|
|
2643
|
-
sessionId: result.target?.sessionId,
|
|
2644
|
-
triggerId: result.triggerId ?? triggerId,
|
|
2645
|
-
})
|
|
2646
|
-
: markMessageListenerRunPreviewFailed(run.runId, {
|
|
2647
|
-
messageId: match.messageId,
|
|
2648
|
-
sessionId: result.target?.sessionId,
|
|
2649
|
-
error: result.error,
|
|
2650
|
-
});
|
|
2651
|
-
results.push(tracked ?? {
|
|
2652
|
-
runId: run.runId,
|
|
2653
|
-
messageId: match.messageId,
|
|
2654
|
-
ok: result.ok,
|
|
2655
|
-
state: result.ok ? 'triggered' : 'failed',
|
|
2656
|
-
action: result.action,
|
|
2657
|
-
sessionId: result.target?.sessionId,
|
|
2658
|
-
triggerId: result.triggerId ?? triggerId,
|
|
2659
|
-
error: result.error,
|
|
2660
|
-
});
|
|
2661
|
-
}
|
|
2662
|
-
catch (err) {
|
|
2663
|
-
const error = err instanceof Error ? err.message : String(err);
|
|
2664
|
-
const tracked = markMessageListenerRunPreviewFailed(run.runId, {
|
|
2665
|
-
messageId: match.messageId,
|
|
2666
|
-
error,
|
|
2667
|
-
});
|
|
2668
|
-
results.push(tracked ?? {
|
|
2669
|
-
runId: run.runId,
|
|
2670
|
-
messageId: match.messageId,
|
|
2671
|
-
ok: false,
|
|
2672
|
-
state: 'failed',
|
|
2673
|
-
error,
|
|
2674
|
-
});
|
|
2675
|
-
}
|
|
2676
|
-
}
|
|
2677
|
-
jsonRes(res, 200, {
|
|
2678
|
-
ok: results.every(result => result.ok),
|
|
2679
|
-
runId: run.runId,
|
|
2680
|
-
requestedLimit: parsed.limit,
|
|
2681
|
-
matches: matches.map(publicMessageListenerMatch),
|
|
2682
|
-
results,
|
|
2683
|
-
});
|
|
2684
|
-
}
|
|
2685
|
-
catch (err) {
|
|
2686
|
-
jsonRes(res, 502, { ok: false, error: err instanceof Error ? err.message : String(err) });
|
|
2687
|
-
}
|
|
2688
|
-
});
|
|
2689
|
-
ipcRoute('GET', '/api/message-listeners/:chatId/run-preview/:runId', async (_req, res, p) => {
|
|
2690
|
-
if (!cachedLarkAppId)
|
|
2691
|
-
return jsonRes(res, 503, { ok: false, error: 'larkAppId_not_set' });
|
|
2692
|
-
if (!isValidRoleChatId(p.chatId))
|
|
2693
|
-
return jsonRes(res, 400, { ok: false, error: 'invalid_chat_id' });
|
|
2694
|
-
const run = getMessageListenerRunPreview(p.runId);
|
|
2695
|
-
if (!run || run.larkAppId !== cachedLarkAppId || run.chatId !== p.chatId) {
|
|
2696
|
-
return jsonRes(res, 404, { ok: false, error: 'not_found' });
|
|
2697
|
-
}
|
|
2698
|
-
jsonRes(res, 200, {
|
|
2699
|
-
ok: true,
|
|
2700
|
-
runId: run.runId,
|
|
2701
|
-
createdAt: run.createdAt,
|
|
2702
|
-
updatedAt: run.updatedAt,
|
|
2703
|
-
results: run.results,
|
|
2704
|
-
});
|
|
2705
|
-
});
|
|
2706
|
-
ipcRoute('DELETE', '/api/message-listeners/:chatId', async (_req, res, p) => {
|
|
2707
|
-
if (!cachedLarkAppId)
|
|
2708
|
-
return jsonRes(res, 503, { error: 'larkAppId_not_set' });
|
|
2709
|
-
if (!isValidRoleChatId(p.chatId))
|
|
2710
|
-
return jsonRes(res, 400, { ok: false, error: 'invalid_chat_id' });
|
|
2711
|
-
const result = await updateMessageListenerConfig(cachedLarkAppId, p.chatId, { enabled: false, prompt: '' });
|
|
2712
|
-
if (!result.ok)
|
|
2713
|
-
return jsonRes(res, 500, { ok: false, error: result.reason });
|
|
2714
|
-
jsonRes(res, 200, { ok: true });
|
|
2715
|
-
});
|
|
2716
|
-
ipcRoute('GET', '/api/groups/:chatId/members-display', async (_req, res, p) => {
|
|
2717
|
-
if (!cachedLarkAppId)
|
|
2718
|
-
return jsonRes(res, 503, { error: 'larkAppId_not_set' });
|
|
2719
|
-
if (!isValidRoleChatId(p.chatId))
|
|
2720
|
-
return jsonRes(res, 400, { ok: false, error: 'invalid_chat_id' });
|
|
2721
|
-
try {
|
|
2722
|
-
const members = await listChatMemberDisplays(cachedLarkAppId, p.chatId);
|
|
2723
|
-
jsonRes(res, 200, { members });
|
|
2724
|
-
}
|
|
2725
|
-
catch (err) {
|
|
2726
|
-
jsonRes(res, 502, { ok: false, error: err instanceof Error ? err.message : String(err) });
|
|
2727
|
-
}
|
|
2728
|
-
});
|
|
2729
|
-
// ─── Role profile management (dashboard) ──────────────────────────────────
|
|
2730
|
-
// Profiles are authoring/storage helpers only; applying one writes this bot's
|
|
2731
|
-
// entry into the selected chat role and does not alter runtime role layering.
|
|
2732
|
-
ipcRoute('GET', '/api/role-profiles', async (_req, res) => {
|
|
2733
|
-
if (!cachedLarkAppId)
|
|
2734
|
-
return jsonRes(res, 503, { error: 'larkAppId_not_set' });
|
|
2735
|
-
const profiles = listRoleProfiles(config.session.dataDir).map(p => ({
|
|
2736
|
-
...p,
|
|
2737
|
-
hasCurrentBotEntry: readRoleProfileEntry(config.session.dataDir, p.profileId, cachedLarkAppId) !== null,
|
|
2738
|
-
}));
|
|
2739
|
-
jsonRes(res, 200, { profiles, larkAppId: cachedLarkAppId });
|
|
2740
|
-
});
|
|
2741
|
-
ipcRoute('GET', '/api/role-profiles/:profileId', async (_req, res, p) => {
|
|
2742
|
-
if (!cachedLarkAppId)
|
|
2743
|
-
return jsonRes(res, 503, { error: 'larkAppId_not_set' });
|
|
2744
|
-
if (!isValidRoleProfileId(p.profileId))
|
|
2745
|
-
return jsonRes(res, 400, { ok: false, error: 'invalid_role_profile_id' });
|
|
2746
|
-
const entries = listRoleProfileEntries(config.session.dataDir, p.profileId);
|
|
2747
|
-
jsonRes(res, 200, { profileId: p.profileId, entries });
|
|
2748
|
-
});
|
|
2749
|
-
ipcRoute('GET', '/api/role-profiles/:profileId/:larkAppId', async (_req, res, p) => {
|
|
2750
|
-
if (!cachedLarkAppId)
|
|
2751
|
-
return jsonRes(res, 503, { error: 'larkAppId_not_set' });
|
|
2752
|
-
if (p.larkAppId !== cachedLarkAppId)
|
|
2753
|
-
return jsonRes(res, 403, { ok: false, error: 'wrong_daemon' });
|
|
2754
|
-
if (!isValidRoleProfileId(p.profileId))
|
|
2755
|
-
return jsonRes(res, 400, { ok: false, error: 'invalid_role_profile_id' });
|
|
2756
|
-
const content = readRoleProfileEntry(config.session.dataDir, p.profileId, cachedLarkAppId);
|
|
2757
|
-
jsonRes(res, 200, {
|
|
2758
|
-
profileId: p.profileId,
|
|
2759
|
-
larkAppId: cachedLarkAppId,
|
|
2760
|
-
content,
|
|
2761
|
-
byteLength: content ? Buffer.byteLength(content, 'utf-8') : 0,
|
|
2762
|
-
hasEntry: content !== null,
|
|
2763
|
-
});
|
|
2764
|
-
});
|
|
2765
|
-
ipcRoute('PUT', '/api/role-profiles/:profileId/:larkAppId', async (req, res, p) => {
|
|
2766
|
-
if (!cachedLarkAppId)
|
|
2767
|
-
return jsonRes(res, 503, { error: 'larkAppId_not_set' });
|
|
2768
|
-
if (p.larkAppId !== cachedLarkAppId)
|
|
2769
|
-
return jsonRes(res, 403, { ok: false, error: 'wrong_daemon' });
|
|
2770
|
-
if (!isValidRoleProfileId(p.profileId))
|
|
2771
|
-
return jsonRes(res, 400, { ok: false, error: 'invalid_role_profile_id' });
|
|
2772
|
-
let body;
|
|
2773
|
-
try {
|
|
2774
|
-
body = await readJsonBody(req);
|
|
2775
|
-
}
|
|
2776
|
-
catch {
|
|
2777
|
-
return jsonRes(res, 400, { ok: false, error: 'bad_json' });
|
|
2778
|
-
}
|
|
2779
|
-
const content = typeof body.content === 'string' ? body.content.trim() : '';
|
|
2780
|
-
const allowEmpty = body.allowEmpty === true;
|
|
2781
|
-
if (!content && !allowEmpty)
|
|
2782
|
-
return jsonRes(res, 400, { ok: false, error: 'content_required' });
|
|
2783
|
-
try {
|
|
2784
|
-
writeRoleProfileEntry(config.session.dataDir, p.profileId, cachedLarkAppId, content, { allowEmpty });
|
|
2785
|
-
jsonRes(res, 200, { ok: true, byteLength: Math.min(Buffer.byteLength(content, 'utf-8'), MAX_ROLE_PROFILE_ENTRY_BYTES) });
|
|
2786
|
-
}
|
|
2787
|
-
catch (e) {
|
|
2788
|
-
jsonRes(res, 500, { ok: false, error: String(e) });
|
|
2789
|
-
}
|
|
2790
|
-
});
|
|
2791
|
-
ipcRoute('DELETE', '/api/role-profiles/:profileId/:larkAppId', async (_req, res, p) => {
|
|
2792
|
-
if (!cachedLarkAppId)
|
|
2793
|
-
return jsonRes(res, 503, { error: 'larkAppId_not_set' });
|
|
2794
|
-
if (p.larkAppId !== cachedLarkAppId)
|
|
2795
|
-
return jsonRes(res, 403, { ok: false, error: 'wrong_daemon' });
|
|
2796
|
-
if (!isValidRoleProfileId(p.profileId))
|
|
2797
|
-
return jsonRes(res, 400, { ok: false, error: 'invalid_role_profile_id' });
|
|
2798
|
-
const existed = deleteRoleProfileEntry(config.session.dataDir, p.profileId, cachedLarkAppId);
|
|
2799
|
-
deleteRoleProfileIfEmpty(config.session.dataDir, p.profileId);
|
|
2800
|
-
jsonRes(res, 200, { ok: true, existed });
|
|
2801
|
-
});
|
|
2802
|
-
ipcRoute('POST', '/api/role-profiles/:profileId/apply', async (req, res, p) => {
|
|
2803
|
-
if (!cachedLarkAppId)
|
|
2804
|
-
return jsonRes(res, 503, { error: 'larkAppId_not_set' });
|
|
2805
|
-
if (!isValidRoleProfileId(p.profileId))
|
|
2806
|
-
return jsonRes(res, 400, { ok: false, error: 'invalid_role_profile_id' });
|
|
2807
|
-
let body;
|
|
2808
|
-
try {
|
|
2809
|
-
body = await readJsonBody(req);
|
|
2810
|
-
}
|
|
2811
|
-
catch {
|
|
2812
|
-
return jsonRes(res, 400, { ok: false, error: 'bad_json' });
|
|
2813
|
-
}
|
|
2814
|
-
const chatId = typeof body.chatId === 'string' && body.chatId.trim() ? body.chatId.trim() : '';
|
|
2815
|
-
const larkAppId = typeof body.larkAppId === 'string' && body.larkAppId.trim() ? body.larkAppId.trim() : '';
|
|
2816
|
-
if (!chatId || !larkAppId)
|
|
2817
|
-
return jsonRes(res, 400, { ok: false, error: 'chatId_and_larkAppId_required' });
|
|
2818
|
-
if (!isValidRoleChatId(chatId))
|
|
2819
|
-
return jsonRes(res, 400, { ok: false, error: 'invalid_chat_id' });
|
|
2820
|
-
if (larkAppId !== cachedLarkAppId)
|
|
2821
|
-
return jsonRes(res, 403, { ok: false, error: 'wrong_daemon' });
|
|
2822
|
-
const content = readRoleProfileEntry(config.session.dataDir, p.profileId, cachedLarkAppId);
|
|
2823
|
-
if (content === null)
|
|
2824
|
-
return jsonRes(res, 200, { ok: false, error: 'missing_entry', changed: false });
|
|
2825
|
-
const existing = resolveRoleFile(cachedLarkAppId, chatId);
|
|
2826
|
-
const preview = body.preview === true;
|
|
2827
|
-
const force = body.force === true;
|
|
2828
|
-
if (preview) {
|
|
2829
|
-
return jsonRes(res, 200, {
|
|
2830
|
-
ok: true,
|
|
2831
|
-
preview: true,
|
|
2832
|
-
changed: false,
|
|
2833
|
-
wouldOverwrite: existing !== null,
|
|
2834
|
-
wouldRefuse: existing !== null && !force,
|
|
2835
|
-
content,
|
|
2836
|
-
byteLength: Buffer.byteLength(content, 'utf-8'),
|
|
2837
|
-
});
|
|
2838
|
-
}
|
|
2839
|
-
if (existing && !force)
|
|
2840
|
-
return jsonRes(res, 409, { ok: false, error: 'chat_role_exists', changed: false });
|
|
2841
|
-
if (!content) {
|
|
2842
|
-
const existed = deleteRoleFile(cachedLarkAppId, chatId);
|
|
2843
|
-
return jsonRes(res, 200, { ok: true, changed: existed, byteLength: 0, deleted: existed });
|
|
2844
|
-
}
|
|
2845
|
-
writeRoleFile(cachedLarkAppId, chatId, content);
|
|
2846
|
-
jsonRes(res, 200, { ok: true, changed: true, byteLength: Buffer.byteLength(content, 'utf-8') });
|
|
2847
|
-
});
|
|
2848
|
-
// ─── Per-bot defaultOncall (dashboard) ─────────────────────────────────────
|
|
2849
|
-
// GET /api/bot-default-oncall → returns this daemon's current config
|
|
2850
|
-
// PUT /api/bot-default-oncall body: { enabled, workingDir }
|
|
2851
|
-
//
|
|
2852
|
-
// Forward-only policy: enabling does not backfill or distinguish "old vs new"
|
|
2853
|
-
// chats. Any group the bot is in — present or future — auto-binds on its
|
|
2854
|
-
// next observed topic if it has no existing oncall binding and is not in
|
|
2855
|
-
// the tombstone list. `since` is stamped purely as informational metadata
|
|
2856
|
-
// (UI shows "上次启用时间").
|
|
2857
|
-
ipcRoute('GET', '/api/bot-default-oncall', async (_req, res) => {
|
|
2858
|
-
if (!cachedLarkAppId)
|
|
2859
|
-
return jsonRes(res, 503, { error: 'larkAppId_not_set' });
|
|
2860
|
-
const { defaultOncall, autoboundChats } = oncallStore.getBotDefaultOncall(cachedLarkAppId);
|
|
2861
|
-
const cardPrefs = cardPrefsStore.getBotCardPrefs(cachedLarkAppId);
|
|
2862
|
-
const grantPrefs = grantPrefsStore.getBotGrantPrefs(cachedLarkAppId);
|
|
2863
|
-
let p2pMode = 'chat';
|
|
2864
|
-
try {
|
|
2865
|
-
if (getBot(cachedLarkAppId).config.p2pMode === 'thread')
|
|
2866
|
-
p2pMode = 'thread';
|
|
2867
|
-
}
|
|
2868
|
-
catch { /* default chat */ }
|
|
2869
|
-
let skillInjection = null;
|
|
2870
|
-
// How this bot's CLI delivers botmux skills, so the dashboard can render the
|
|
2871
|
-
// control correctly: 'dynamic' = per-session --plugin-dir (claude-family, not
|
|
2872
|
-
// configurable); 'global' = global skills dir (codex-family, prompt/global/off
|
|
2873
|
-
// selectable); 'none' = CLI has no skill dir at all (control hidden).
|
|
2874
|
-
let skillInjectionSupport = 'none';
|
|
2875
|
-
try {
|
|
2876
|
-
const cfg = getBot(cachedLarkAppId).config;
|
|
2877
|
-
const s = cfg.skillInjection;
|
|
2878
|
-
if (s === 'global' || s === 'prompt' || s === 'off')
|
|
2879
|
-
skillInjection = s;
|
|
2880
|
-
skillInjectionSupport = resolveSkillInjectionSupport(cfg.cliId, cfg.cliPathOverride);
|
|
2881
|
-
}
|
|
2882
|
-
catch { /* unset → machine default; support → none */ }
|
|
2883
|
-
let cliId = '';
|
|
2884
|
-
let cliRuntime = null;
|
|
2885
|
-
let cliPathOverride = null;
|
|
2886
|
-
let wrapperCli = null;
|
|
2887
|
-
let model = null;
|
|
2888
|
-
let agentSelectionKey = '';
|
|
2889
|
-
try {
|
|
2890
|
-
const cfg = getBot(cachedLarkAppId).config;
|
|
2891
|
-
cliId = cfg.cliId;
|
|
2892
|
-
cliRuntime = cfg.cliRuntime ?? null;
|
|
2893
|
-
// Parsed structured runtimes mirror their executable into cliPathOverride
|
|
2894
|
-
// for legacy adapter call sites. Expose only a genuine legacy path here so
|
|
2895
|
-
// the Dashboard can render an explicit migration state instead of
|
|
2896
|
-
// misclassifying every structured runtime as legacy.
|
|
2897
|
-
cliPathOverride = !cfg.cliRuntime && typeof cfg.cliPathOverride === 'string' && cfg.cliPathOverride.trim()
|
|
2898
|
-
? cfg.cliPathOverride
|
|
2899
|
-
: null;
|
|
2900
|
-
wrapperCli = typeof cfg.wrapperCli === 'string' && cfg.wrapperCli.trim() ? cfg.wrapperCli : null;
|
|
2901
|
-
model = typeof cfg.model === 'string' && cfg.model.trim() ? cfg.model : null;
|
|
2902
|
-
agentSelectionKey = selectionKeyForBot(cliId, wrapperCli ?? undefined);
|
|
2903
|
-
}
|
|
2904
|
-
catch { /* no registered bot */ }
|
|
2905
|
-
let maxLiveWorkers = null;
|
|
2906
|
-
try {
|
|
2907
|
-
const m = getBot(cachedLarkAppId).config.maxLiveWorkers;
|
|
2908
|
-
if (typeof m === 'number' && Number.isInteger(m) && m > 0)
|
|
2909
|
-
maxLiveWorkers = m;
|
|
2910
|
-
}
|
|
2911
|
-
catch { /* default unlimited */ }
|
|
2912
|
-
let logicalSessionCount = 0;
|
|
2913
|
-
let residentSessionCount = 0;
|
|
2914
|
-
let dormantSessionCount = 0;
|
|
2915
|
-
const registry = getActiveSessionsRegistry();
|
|
2916
|
-
if (registry) {
|
|
2917
|
-
logicalSessionCount = registry.size;
|
|
2918
|
-
for (const ds of registry.values()) {
|
|
2919
|
-
if (ds.worker && !ds.worker.killed)
|
|
2920
|
-
residentSessionCount++;
|
|
2921
|
-
else if (!ds.session.queued)
|
|
2922
|
-
dormantSessionCount++;
|
|
2923
|
-
}
|
|
2924
|
-
}
|
|
2925
|
-
// startupCommands → newline-joined for the dashboard textarea (one per line).
|
|
2926
|
-
let startupCommands = '';
|
|
2927
|
-
try {
|
|
2928
|
-
const sc = getBot(cachedLarkAppId).config.startupCommands;
|
|
2929
|
-
if (Array.isArray(sc) && sc.length)
|
|
2930
|
-
startupCommands = sc.join('\n');
|
|
2931
|
-
}
|
|
2932
|
-
catch { /* none */ }
|
|
2933
|
-
// customPassthroughCommands / canTalkDaemonCommands → space-joined for the
|
|
2934
|
-
// dashboard slash-command editors. Empty string = not configured (回默认).
|
|
2935
|
-
let customPassthroughCommands = '';
|
|
2936
|
-
let canTalkDaemonCommands = '';
|
|
2937
|
-
try {
|
|
2938
|
-
const cfg = getBot(cachedLarkAppId).config;
|
|
2939
|
-
if (Array.isArray(cfg.customPassthroughCommands) && cfg.customPassthroughCommands.length) {
|
|
2940
|
-
customPassthroughCommands = cfg.customPassthroughCommands.join(' ');
|
|
2941
|
-
}
|
|
2942
|
-
if (Array.isArray(cfg.canTalkDaemonCommands) && cfg.canTalkDaemonCommands.length) {
|
|
2943
|
-
canTalkDaemonCommands = cfg.canTalkDaemonCommands.join(' ');
|
|
2944
|
-
}
|
|
2945
|
-
}
|
|
2946
|
-
catch { /* none */ }
|
|
2947
|
-
// Per-bot env → pretty JSON for the dashboard textarea. The dashboard is
|
|
2948
|
-
// owner-authenticated, so showing the real values here is acceptable (same
|
|
2949
|
-
// as editing bots.json directly); the chat-facing /config get masks them.
|
|
2950
|
-
let env = '';
|
|
2951
|
-
try {
|
|
2952
|
-
const e = getBot(cachedLarkAppId).config.env;
|
|
2953
|
-
if (e && typeof e === 'object' && Object.keys(e).length)
|
|
2954
|
-
env = JSON.stringify(e, null, 2);
|
|
2955
|
-
}
|
|
2956
|
-
catch { /* none */ }
|
|
2957
|
-
// defaultWorkingDir — the "仅默认目录" mode source. Mutually exclusive with
|
|
2958
|
-
// defaultOncall in the dashboard 3-way selector; the frontend derives the
|
|
2959
|
-
// current mode from (defaultOncall.enabled ? oncall : defaultWorkingDir ? default : off).
|
|
2960
|
-
let defaultWorkingDir = null;
|
|
2961
|
-
let defaultWorkingDirAutoWorktree = false;
|
|
2962
|
-
try {
|
|
2963
|
-
const cfg = getBot(cachedLarkAppId).config;
|
|
2964
|
-
if (typeof cfg.defaultWorkingDir === 'string' && cfg.defaultWorkingDir.trim())
|
|
2965
|
-
defaultWorkingDir = cfg.defaultWorkingDir;
|
|
2966
|
-
defaultWorkingDirAutoWorktree = cfg.defaultWorkingDirAutoWorktree === true;
|
|
2967
|
-
}
|
|
2968
|
-
catch { /* none */ }
|
|
2969
|
-
// 展示名编辑框数据:displayName = 自定义备注名(null = 未设,跟随飞书名称);
|
|
2970
|
-
// larkBotName = 飞书探测到的应用名(供 placeholder /「恢复默认」提示用)。
|
|
2971
|
-
let displayName = null;
|
|
2972
|
-
let larkBotName = null;
|
|
2973
|
-
try {
|
|
2974
|
-
const bot = getBot(cachedLarkAppId);
|
|
2975
|
-
displayName = bot.config.displayName ?? null;
|
|
2976
|
-
larkBotName = bot.botName ?? null;
|
|
2977
|
-
}
|
|
2978
|
-
catch { /* none */ }
|
|
2979
|
-
jsonRes(res, 200, {
|
|
2980
|
-
larkAppId: cachedLarkAppId,
|
|
2981
|
-
botName: getBotName(),
|
|
2982
|
-
displayName,
|
|
2983
|
-
larkBotName,
|
|
2984
|
-
cliId,
|
|
2985
|
-
cliRuntime,
|
|
2986
|
-
cliPathOverride,
|
|
2987
|
-
wrapperCli,
|
|
2988
|
-
model,
|
|
2989
|
-
agentSelectionKey,
|
|
2990
|
-
defaultOncall: defaultOncall ?? { enabled: false, workingDir: '', since: 0 },
|
|
2991
|
-
defaultWorkingDir,
|
|
2992
|
-
defaultWorkingDirAutoWorktree,
|
|
2993
|
-
autoboundChatCount: autoboundChats.length,
|
|
2994
|
-
brandLabel: brandStore.getBotBrandLabel(cachedLarkAppId) ?? null,
|
|
2995
|
-
sandbox: sandboxStore.getBotSandbox(cachedLarkAppId),
|
|
2996
|
-
sandboxPaths: sandboxStore.getBotSandboxPaths(cachedLarkAppId) ?? null,
|
|
2997
|
-
readIsolation: sandboxStore.getBotReadIsolation(cachedLarkAppId),
|
|
2998
|
-
// Full enforceability (adapter support + no wrapperCli + macOS) — the UI
|
|
2999
|
-
// disables the toggle wherever the worker would fail-close on it.
|
|
3000
|
-
readIsolationSupported: readIsolationEnforceable(cachedLarkAppId),
|
|
3001
|
-
backendType: backendTypeStore.getBotBackendType(cachedLarkAppId) ?? null,
|
|
3002
|
-
usageDisplay: cardPrefs.usageDisplay,
|
|
3003
|
-
// Whether this bot's CLI can produce native usage at all. When false the
|
|
3004
|
-
// dashboard hides the usage-display control (offering it would be a knob
|
|
3005
|
-
// that is always empty — the CLI has no resolvable transcript).
|
|
3006
|
-
usageSupported: cliSupportsNativeUsage(cliId),
|
|
3007
|
-
disableStreamingCard: cardPrefs.disableStreamingCard,
|
|
3008
|
-
silentTurnReactions: cardPrefs.silentTurnReactions,
|
|
3009
|
-
codexAppCleanInput: cardPrefs.codexAppCleanInput,
|
|
3010
|
-
writableTerminalLinkInCard: cardPrefs.writableTerminalLinkInCard,
|
|
3011
|
-
privateCard: cardPrefs.privateCard,
|
|
3012
|
-
overloadAlert: cardPrefs.overloadAlert,
|
|
3013
|
-
botToBotSameDir: cardPrefs.botToBotSameDir,
|
|
3014
|
-
autoStartOnGroupJoin: cardPrefs.autoStartOnGroupJoin,
|
|
3015
|
-
autoStartOnGroupJoinPrompt: cardPrefs.autoStartOnGroupJoinPrompt,
|
|
3016
|
-
autoStartOnNewTopic: cardPrefs.autoStartOnNewTopic,
|
|
3017
|
-
regularGroupReplyMode: cardPrefs.regularGroupReplyMode,
|
|
3018
|
-
regularGroupMentionMode: cardPrefs.regularGroupMentionMode,
|
|
3019
|
-
substituteMode: substituteModeStore.getBotSubstituteMode(cachedLarkAppId) ?? null,
|
|
3020
|
-
docSubscribeDefaultMode: cardPrefs.docSubscribeDefaultMode,
|
|
3021
|
-
restrictGrantCommands: grantPrefs.restrictGrantCommands,
|
|
3022
|
-
autoGrantRequestCards: grantPrefs.autoGrantRequestCards,
|
|
3023
|
-
messageQuotaDefaultLimit: grantPrefs.messageQuotaDefaultLimit,
|
|
3024
|
-
p2pMode,
|
|
3025
|
-
skillInjection,
|
|
3026
|
-
skillInjectionSupport,
|
|
3027
|
-
// Resolved machine-wide default → the dashboard shows it as the pre-selected
|
|
3028
|
-
// value when this bot has no explicit override (prompt/global/off).
|
|
3029
|
-
skillInjectionDefault: globalBuiltinSkillInjectionDefault(),
|
|
3030
|
-
maxLiveWorkers,
|
|
3031
|
-
logicalSessionCount,
|
|
3032
|
-
residentSessionCount,
|
|
3033
|
-
dormantSessionCount,
|
|
3034
|
-
startupCommands,
|
|
3035
|
-
customPassthroughCommands,
|
|
3036
|
-
canTalkDaemonCommands,
|
|
3037
|
-
launchShell: getBot(cachedLarkAppId).config.launchShell ?? '',
|
|
3038
|
-
env,
|
|
3039
|
-
riff: redactRiffForClient(getBot(cachedLarkAppId).config.riff),
|
|
3040
|
-
summaryRange: summaryRangeFromBotConfig(getBot(cachedLarkAppId).config),
|
|
3041
|
-
skills: getBot(cachedLarkAppId).config.skills ?? null,
|
|
3042
|
-
});
|
|
3043
|
-
});
|
|
3044
|
-
// Per-bot card-behaviour toggles. Body may carry any subset of booleans; only
|
|
3045
|
-
// present keys are applied.
|
|
3046
|
-
ipcRoute('PUT', '/api/bot-card-prefs', async (req, res) => {
|
|
3047
|
-
if (!cachedLarkAppId)
|
|
3048
|
-
return jsonRes(res, 503, { error: 'larkAppId_not_set' });
|
|
3049
|
-
let body;
|
|
3050
|
-
try {
|
|
3051
|
-
body = await readJsonBody(req);
|
|
3052
|
-
}
|
|
3053
|
-
catch {
|
|
3054
|
-
return jsonRes(res, 400, { ok: false, error: 'bad_json' });
|
|
3055
|
-
}
|
|
3056
|
-
const patch = {};
|
|
3057
|
-
if (body.usageDisplay === 'streaming' || body.usageDisplay === 'footer' || body.usageDisplay === 'off')
|
|
3058
|
-
patch.usageDisplay = body.usageDisplay;
|
|
3059
|
-
if (typeof body.disableStreamingCard === 'boolean')
|
|
3060
|
-
patch.disableStreamingCard = body.disableStreamingCard;
|
|
3061
|
-
if (typeof body.botToBotSameDir === 'boolean')
|
|
3062
|
-
patch.botToBotSameDir = body.botToBotSameDir;
|
|
3063
|
-
if (typeof body.silentTurnReactions === 'boolean')
|
|
3064
|
-
patch.silentTurnReactions = body.silentTurnReactions;
|
|
3065
|
-
if (typeof body.codexAppCleanInput === 'boolean')
|
|
3066
|
-
patch.codexAppCleanInput = body.codexAppCleanInput;
|
|
3067
|
-
if (typeof body.writableTerminalLinkInCard === 'boolean')
|
|
3068
|
-
patch.writableTerminalLinkInCard = body.writableTerminalLinkInCard;
|
|
3069
|
-
if (typeof body.privateCard === 'boolean')
|
|
3070
|
-
patch.privateCard = body.privateCard;
|
|
3071
|
-
if (typeof body.overloadAlert === 'boolean')
|
|
3072
|
-
patch.overloadAlert = body.overloadAlert;
|
|
3073
|
-
if (typeof body.summaryMemory === 'boolean')
|
|
3074
|
-
patch.summaryMemory = body.summaryMemory;
|
|
3075
|
-
if (typeof body.summaryMemoryPath === 'string')
|
|
3076
|
-
patch.summaryMemoryPath = body.summaryMemoryPath;
|
|
3077
|
-
if (typeof body.autoStartOnGroupJoin === 'boolean')
|
|
3078
|
-
patch.autoStartOnGroupJoin = body.autoStartOnGroupJoin;
|
|
3079
|
-
if (typeof body.autoStartOnGroupJoinPrompt === 'string')
|
|
3080
|
-
patch.autoStartOnGroupJoinPrompt = body.autoStartOnGroupJoinPrompt;
|
|
3081
|
-
if (typeof body.autoStartOnNewTopic === 'boolean')
|
|
3082
|
-
patch.autoStartOnNewTopic = body.autoStartOnNewTopic;
|
|
3083
|
-
if (typeof body.regularGroupReplyMode === 'string') {
|
|
3084
|
-
const m = normalizeChatReplyMode(body.regularGroupReplyMode);
|
|
3085
|
-
if (m)
|
|
3086
|
-
patch.regularGroupReplyMode = m;
|
|
3087
|
-
}
|
|
3088
|
-
if (body.regularGroupMentionMode === 'always' || body.regularGroupMentionMode === 'topic' || body.regularGroupMentionMode === 'never' || body.regularGroupMentionMode === 'ambient') {
|
|
3089
|
-
patch.regularGroupMentionMode = body.regularGroupMentionMode;
|
|
3090
|
-
}
|
|
3091
|
-
if (body.docSubscribeDefaultMode === 'mention-only' || body.docSubscribeDefaultMode === 'all') {
|
|
3092
|
-
patch.docSubscribeDefaultMode = body.docSubscribeDefaultMode;
|
|
3093
|
-
}
|
|
3094
|
-
if (Object.keys(patch).length === 0)
|
|
3095
|
-
return jsonRes(res, 400, { ok: false, error: 'no_valid_fields' });
|
|
3096
|
-
const r = await cardPrefsStore.updateBotCardPrefs(cachedLarkAppId, patch);
|
|
3097
|
-
if (!r.ok)
|
|
3098
|
-
return jsonRes(res, 400, { ok: false, error: r.reason });
|
|
3099
|
-
jsonRes(res, 200, { ok: true, ...r.prefs });
|
|
3100
|
-
});
|
|
3101
|
-
ipcRoute('PUT', '/api/bot-substitute-mode', async (req, res) => {
|
|
3102
|
-
if (!cachedLarkAppId)
|
|
3103
|
-
return jsonRes(res, 503, { error: 'larkAppId_not_set' });
|
|
3104
|
-
let body;
|
|
3105
|
-
try {
|
|
3106
|
-
body = await readJsonBody(req);
|
|
3107
|
-
}
|
|
3108
|
-
catch {
|
|
3109
|
-
return jsonRes(res, 400, { ok: false, error: 'bad_json' });
|
|
3110
|
-
}
|
|
3111
|
-
const rec = body && typeof body === 'object' && !Array.isArray(body) ? body : {};
|
|
3112
|
-
// Resolve the submitted email / union_id entries into runtime-matchable
|
|
3113
|
-
// open_ids (+ fresh display names) using this bot's own credentials before
|
|
3114
|
-
// persisting; unresolvable entries are dropped but reported back for the UI.
|
|
3115
|
-
const { targets, resolution } = await substituteModeStore.resolveSubstituteTargets(cachedLarkAppId, rec.targets, { resolveRaw: resolveAllowedUsersWithMap, getProfile: getUserProfileStrict });
|
|
3116
|
-
const chats = Array.isArray(rec.chats)
|
|
3117
|
-
? [...new Set(rec.chats.map(String).map(s => s.trim()).filter(Boolean))]
|
|
3118
|
-
: [];
|
|
3119
|
-
const excludedChats = Array.isArray(rec.excludedChats)
|
|
3120
|
-
? [...new Set(rec.excludedChats.map(String).map(s => s.trim()).filter(Boolean))]
|
|
3121
|
-
: [];
|
|
3122
|
-
const r = await substituteModeStore.updateBotSubstituteMode(cachedLarkAppId, {
|
|
3123
|
-
enabled: rec.enabled === true,
|
|
3124
|
-
targets,
|
|
3125
|
-
disclosure: rec.disclosure === 'none' ? 'none' : 'prefix',
|
|
3126
|
-
replyMode: rec.replyMode === 'quote' ? 'quote' : 'thread',
|
|
3127
|
-
disableControlCard: rec.disableControlCard === true,
|
|
3128
|
-
...(chats.length ? { chats } : {}),
|
|
3129
|
-
...(excludedChats.length ? { excludedChats } : {}),
|
|
3130
|
-
// 话题群开关:显式 false 才关(旧客户端不带字段 → normalize 缺省开)。
|
|
3131
|
-
topicGroups: rec.topicGroups,
|
|
3132
|
-
topicActiveSessionTrigger: rec.topicActiveSessionTrigger,
|
|
3133
|
-
});
|
|
3134
|
-
if (!r.ok)
|
|
3135
|
-
return jsonRes(res, 400, { ok: false, error: r.reason, resolution });
|
|
3136
|
-
jsonRes(res, 200, { ok: true, substituteMode: r.substituteMode, resolution });
|
|
3137
|
-
});
|
|
3138
|
-
// Preview resolution for a single substitute target without persisting anything.
|
|
3139
|
-
// Used by the dashboard to auto-fill name/avatar while the user is typing.
|
|
3140
|
-
ipcRoute('POST', '/api/bot-substitute-targets/resolve', async (req, res) => {
|
|
3141
|
-
if (!cachedLarkAppId)
|
|
3142
|
-
return jsonRes(res, 503, { error: 'larkAppId_not_set' });
|
|
3143
|
-
let body;
|
|
3144
|
-
try {
|
|
3145
|
-
body = await readJsonBody(req);
|
|
3146
|
-
}
|
|
3147
|
-
catch {
|
|
3148
|
-
return jsonRes(res, 400, { ok: false, error: 'bad_json' });
|
|
3149
|
-
}
|
|
3150
|
-
const rec = body && typeof body === 'object' && !Array.isArray(body) ? body : {};
|
|
3151
|
-
const target = rec.target && typeof rec.target === 'object' && !Array.isArray(rec.target) ? rec.target : {};
|
|
3152
|
-
const { resolution } = await substituteModeStore.resolveSubstituteTargets(cachedLarkAppId, [target], { resolveRaw: resolveAllowedUsersWithMap, getProfile: getUserProfileStrict });
|
|
3153
|
-
jsonRes(res, 200, { ok: true, resolution: resolution[0] ?? null });
|
|
3154
|
-
});
|
|
3155
|
-
// Per-bot explicit `/summary` history range. Body `{ limit, sinceHours }`.
|
|
3156
|
-
ipcRoute('PUT', '/api/bot-summary-range', async (req, res) => {
|
|
3157
|
-
if (!cachedLarkAppId)
|
|
3158
|
-
return jsonRes(res, 503, { error: 'larkAppId_not_set' });
|
|
3159
|
-
let raw;
|
|
3160
|
-
try {
|
|
3161
|
-
raw = await readJsonBody(req);
|
|
3162
|
-
}
|
|
3163
|
-
catch {
|
|
3164
|
-
return jsonRes(res, 400, { ok: false, error: 'bad_json' });
|
|
3165
|
-
}
|
|
3166
|
-
const r = await updateDashboardSummaryRange(cachedLarkAppId, raw);
|
|
3167
|
-
if (!r.ok)
|
|
3168
|
-
return jsonRes(res, 400, { ok: false, error: r.reason });
|
|
3169
|
-
jsonRes(res, 200, { ok: true, summaryRange: r.summaryRange });
|
|
3170
|
-
});
|
|
3171
|
-
// Backward-compatible dashboard endpoint from the short-lived keyword-trigger UI.
|
|
3172
|
-
ipcRoute('PUT', '/api/bot-summary-trigger', async (req, res) => {
|
|
3173
|
-
if (!cachedLarkAppId)
|
|
3174
|
-
return jsonRes(res, 503, { error: 'larkAppId_not_set' });
|
|
3175
|
-
let raw;
|
|
3176
|
-
try {
|
|
3177
|
-
raw = await readJsonBody(req);
|
|
3178
|
-
}
|
|
3179
|
-
catch {
|
|
3180
|
-
return jsonRes(res, 400, { ok: false, error: 'bad_json' });
|
|
3181
|
-
}
|
|
3182
|
-
const body = raw && typeof raw === 'object' && !Array.isArray(raw)
|
|
3183
|
-
? { limit: raw.limit, sinceHours: raw.sinceHours }
|
|
3184
|
-
: raw;
|
|
3185
|
-
const r = await updateDashboardSummaryRange(cachedLarkAppId, body);
|
|
3186
|
-
if (!r.ok)
|
|
3187
|
-
return jsonRes(res, 400, { ok: false, error: r.reason });
|
|
3188
|
-
jsonRes(res, 200, { ok: true, summaryRange: r.summaryRange });
|
|
3189
|
-
});
|
|
3190
|
-
// Per-bot 授权偏好。Body 任意子集:
|
|
3191
|
-
// • restrictGrantCommands: boolean — 限制被授权人只能纯对话
|
|
3192
|
-
// • autoGrantRequestCards: boolean — 未授权 @ 被挡住时是否发 grant 申请卡
|
|
3193
|
-
// • messageQuotaDefaultLimit: number|null — 卡片默认额度覆盖(null = 产品默认 3 条)
|
|
3194
|
-
ipcRoute('PUT', '/api/bot-grant-prefs', async (req, res) => {
|
|
3195
|
-
if (!cachedLarkAppId)
|
|
3196
|
-
return jsonRes(res, 503, { error: 'larkAppId_not_set' });
|
|
3197
|
-
let raw;
|
|
3198
|
-
try {
|
|
3199
|
-
raw = await readJsonBody(req);
|
|
3200
|
-
}
|
|
3201
|
-
catch {
|
|
3202
|
-
return jsonRes(res, 400, { ok: false, error: 'bad_json' });
|
|
3203
|
-
}
|
|
3204
|
-
// 顶层必须是对象:JSON `null` / 数字 / 字符串等都拒(null 解引用会抛 → 500)。
|
|
3205
|
-
if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) {
|
|
3206
|
-
return jsonRes(res, 400, { ok: false, error: 'no_valid_fields' });
|
|
3207
|
-
}
|
|
3208
|
-
const body = raw;
|
|
3209
|
-
const patch = {};
|
|
3210
|
-
if (typeof body.restrictGrantCommands === 'boolean')
|
|
3211
|
-
patch.restrictGrantCommands = body.restrictGrantCommands;
|
|
3212
|
-
if (typeof body.autoGrantRequestCards === 'boolean')
|
|
3213
|
-
patch.autoGrantRequestCards = body.autoGrantRequestCards;
|
|
3214
|
-
// null(含 JSON null)= 关闭默认额度;number = 设定(store 内再校验正整数)。
|
|
3215
|
-
if (body.messageQuotaDefaultLimit === null)
|
|
3216
|
-
patch.messageQuotaDefaultLimit = null;
|
|
3217
|
-
else if (typeof body.messageQuotaDefaultLimit === 'number')
|
|
3218
|
-
patch.messageQuotaDefaultLimit = body.messageQuotaDefaultLimit;
|
|
3219
|
-
if (Object.keys(patch).length === 0)
|
|
3220
|
-
return jsonRes(res, 400, { ok: false, error: 'no_valid_fields' });
|
|
3221
|
-
const r = await grantPrefsStore.updateBotGrantPrefs(cachedLarkAppId, patch);
|
|
3222
|
-
if (!r.ok)
|
|
3223
|
-
return jsonRes(res, 400, { ok: false, error: r.reason });
|
|
3224
|
-
jsonRes(res, 200, { ok: true, ...r.prefs });
|
|
3225
|
-
});
|
|
3226
|
-
// Per-bot card footer brand label. Body `{ brandLabel: string | null }`:
|
|
3227
|
-
// • string (incl. '') → store verbatim ('' = brand off)
|
|
3228
|
-
// • null / absent → clear the key (revert to default botmux brand)
|
|
3229
|
-
ipcRoute('PUT', '/api/bot-brand-label', async (req, res) => {
|
|
3230
|
-
if (!cachedLarkAppId)
|
|
3231
|
-
return jsonRes(res, 503, { error: 'larkAppId_not_set' });
|
|
3232
|
-
let body;
|
|
3233
|
-
try {
|
|
3234
|
-
body = await readJsonBody(req);
|
|
3235
|
-
}
|
|
3236
|
-
catch {
|
|
3237
|
-
return jsonRes(res, 400, { ok: false, error: 'bad_json' });
|
|
3238
|
-
}
|
|
3239
|
-
const next = typeof body.brandLabel === 'string' ? body.brandLabel : null;
|
|
3240
|
-
const r = await brandStore.updateBotBrandLabel(cachedLarkAppId, next);
|
|
3241
|
-
if (!r.ok)
|
|
3242
|
-
return jsonRes(res, 400, { ok: false, error: r.reason });
|
|
3243
|
-
jsonRes(res, 200, { ok: true, brandLabel: r.brandLabel });
|
|
3244
|
-
});
|
|
3245
|
-
// 机器人改名(dashboard 档案头 ✎ 入口)。Body `{ name: string }`。
|
|
3246
|
-
// 主路径:daemon 注册的 renamer 走开放平台自动化真改飞书应用名(改基础信息 +
|
|
3247
|
-
// 建版发布,群内显示名生效);失败(Web 登录态过期 / 非协作者 / lark 租户等)
|
|
3248
|
-
// 自动降级为仅改 botmux 展示名 displayName,并把原因作为 warning 返回给前端。
|
|
3249
|
-
// 响应:{ ok, mode: 'feishu'|'local', botName, warning?, message? }。
|
|
3250
|
-
ipcRoute('PUT', '/api/bot-rename', async (req, res) => {
|
|
3251
|
-
if (!cachedLarkAppId)
|
|
3252
|
-
return jsonRes(res, 503, { error: 'larkAppId_not_set' });
|
|
3253
|
-
let body;
|
|
3254
|
-
try {
|
|
3255
|
-
body = await readJsonBody(req);
|
|
3256
|
-
}
|
|
3257
|
-
catch {
|
|
3258
|
-
return jsonRes(res, 400, { ok: false, error: 'bad_json' });
|
|
3259
|
-
}
|
|
3260
|
-
const spec = findConfigField('displayName');
|
|
3261
|
-
if (!spec)
|
|
3262
|
-
return jsonRes(res, 500, { ok: false, error: 'spec_missing' });
|
|
3263
|
-
const raw = typeof body.name === 'string' ? body.name.trim() : '';
|
|
3264
|
-
if (!raw)
|
|
3265
|
-
return jsonRes(res, 400, { ok: false, error: 'name_required' });
|
|
3266
|
-
// 长度等校验与 IM /config 入口共用(字段 spec 的 maxLen,coerceConfigValue 执行)。
|
|
3267
|
-
const c = coerceConfigValue(spec, raw);
|
|
3268
|
-
if (!c.ok)
|
|
3269
|
-
return jsonRes(res, 400, { ok: false, error: c.reason });
|
|
3270
|
-
const name = c.value;
|
|
3271
|
-
// 主路径:开放平台真改名(daemon 注册;成功时 daemon 侧已同步 botName /
|
|
3272
|
-
// descriptor / bots-info 并清掉冗余的 displayName)。
|
|
3273
|
-
if (botRenamer) {
|
|
3274
|
-
let renamed;
|
|
3275
|
-
try {
|
|
3276
|
-
renamed = await botRenamer(name);
|
|
3277
|
-
}
|
|
3278
|
-
catch (err) {
|
|
3279
|
-
renamed = { ok: false, reason: 'api_error', message: err instanceof Error ? err.message : String(err) };
|
|
3280
|
-
}
|
|
3281
|
-
if (renamed.ok) {
|
|
3282
|
-
return jsonRes(res, 200, { ok: true, mode: 'feishu', botName: getBotName() });
|
|
3283
|
-
}
|
|
3284
|
-
// 降级:仅改 botmux 展示名,带上飞书侧失败原因让前端明示。
|
|
3285
|
-
const fallback = await applyConfigField(cachedLarkAppId, spec, name);
|
|
3286
|
-
if (!fallback.ok)
|
|
3287
|
-
return jsonRes(res, 400, { ok: false, error: fallback.reason, warning: renamed.reason, message: renamed.message });
|
|
3288
|
-
return jsonRes(res, 200, { ok: true, mode: 'local', botName: getBotName(), warning: renamed.reason, message: renamed.message });
|
|
3289
|
-
}
|
|
3290
|
-
// 无 renamer(daemon 未注册,理论上只在测试环境出现)→ 直接走本地展示名。
|
|
3291
|
-
const r = await applyConfigField(cachedLarkAppId, spec, name);
|
|
3292
|
-
if (!r.ok)
|
|
3293
|
-
return jsonRes(res, 400, { ok: false, error: r.reason });
|
|
3294
|
-
jsonRes(res, 200, { ok: true, mode: 'local', botName: getBotName(), warning: 'renamer_not_wired' });
|
|
3295
|
-
});
|
|
3296
|
-
// 机器人改头像(dashboard 档案头头像入口)。Body `{ imageBase64: string }`——
|
|
3297
|
-
// 512×512 PNG 的 base64(可带 data URL 前缀,前端 canvas 归一化产出)。走开放
|
|
3298
|
-
// 平台自动化真改飞书应用头像(上传图片 + 改基础信息 + 建版发布,群内头像生效)。
|
|
3299
|
-
// 头像没有本地降级等价物:失败直接把结构化原因返回(no_session / session_expired
|
|
3300
|
-
// 时前端引导扫码重登)。响应:{ ok, avatarUrl?, versionId? } | { ok:false, error, message }。
|
|
3301
|
-
ipcRoute('PUT', '/api/bot-avatar', async (req, res) => {
|
|
3302
|
-
if (!cachedLarkAppId)
|
|
3303
|
-
return jsonRes(res, 503, { error: 'larkAppId_not_set' });
|
|
3304
|
-
let body;
|
|
3305
|
-
try {
|
|
3306
|
-
body = await readJsonBody(req);
|
|
3307
|
-
}
|
|
3308
|
-
catch {
|
|
3309
|
-
return jsonRes(res, 400, { ok: false, error: 'bad_json' });
|
|
3310
|
-
}
|
|
3311
|
-
// JSON 顶层可以是 null / 数组 / 标量——属性访问前先收窄成普通对象(400 而非 500)。
|
|
3312
|
-
const rawB64 = typeof body?.imageBase64 === 'string'
|
|
3313
|
-
? body.imageBase64.replace(/^data:image\/[a-z+.-]+;base64,/i, '').trim()
|
|
3314
|
-
: '';
|
|
3315
|
-
if (!rawB64)
|
|
3316
|
-
return jsonRes(res, 400, { ok: false, error: 'image_required' });
|
|
3317
|
-
// 512×512 PNG 远小于此上限;超出即拒,避免把任意大 payload 灌进 console 上传。
|
|
3318
|
-
if (rawB64.length > 3_000_000)
|
|
3319
|
-
return jsonRes(res, 413, { ok: false, error: 'image_too_large' });
|
|
3320
|
-
const image = Buffer.from(rawB64, 'base64');
|
|
3321
|
-
if (!botAvatarChanger)
|
|
3322
|
-
return jsonRes(res, 501, { ok: false, error: 'avatar_not_wired' });
|
|
3323
|
-
let changed;
|
|
3324
|
-
try {
|
|
3325
|
-
changed = await botAvatarChanger(image);
|
|
3326
|
-
}
|
|
3327
|
-
catch (err) {
|
|
3328
|
-
changed = { ok: false, reason: 'api_error', message: err instanceof Error ? err.message : String(err) };
|
|
3329
|
-
}
|
|
3330
|
-
if (changed.ok) {
|
|
3331
|
-
return jsonRes(res, 200, { ok: true, avatarUrl: changed.avatarUrl, versionId: changed.versionId });
|
|
3332
|
-
}
|
|
3333
|
-
// invalid_image 是调用方参数问题(4xx),其余是飞书侧/环境失败(502)。
|
|
3334
|
-
const status = changed.reason === 'invalid_image' ? 400 : 502;
|
|
3335
|
-
jsonRes(res, status, { ok: false, error: changed.reason, message: changed.message });
|
|
3336
|
-
});
|
|
3337
|
-
// Per-bot agent launch settings. Body `{ cliId, model, cliRuntime? }` where `cliId` is the
|
|
3338
|
-
// dashboard selection key (plain adapter id or a wrapper option such as
|
|
3339
|
-
// `ttadk-x-codex`). Changes affect the next spawned CLI session; existing
|
|
3340
|
-
// sessions frozen on a different cliId/wrapperCli are closed immediately, so
|
|
3341
|
-
// a later lazy resume can't resurrect the old CLI (#346 covered the restart
|
|
3342
|
-
// path; this covers the hot-switch path).
|
|
3343
|
-
ipcRoute('PUT', '/api/bot-agent', async (req, res) => {
|
|
3344
|
-
if (!cachedLarkAppId)
|
|
3345
|
-
return jsonRes(res, 503, { error: 'larkAppId_not_set' });
|
|
3346
|
-
let body;
|
|
3347
|
-
try {
|
|
3348
|
-
body = await readJsonBody(req);
|
|
3349
|
-
}
|
|
3350
|
-
catch {
|
|
3351
|
-
return jsonRes(res, 400, { ok: false, error: 'bad_json' });
|
|
3352
|
-
}
|
|
3353
|
-
const key = typeof body.cliId === 'string' && body.cliId.trim() ? body.cliId.trim() : '';
|
|
3354
|
-
if (!key)
|
|
3355
|
-
return jsonRes(res, 400, { ok: false, error: 'cli_required' });
|
|
3356
|
-
let selected;
|
|
3357
|
-
try {
|
|
3358
|
-
selected = resolveCliSelection(key);
|
|
3359
|
-
}
|
|
3360
|
-
catch (err) {
|
|
3361
|
-
return jsonRes(res, 400, { ok: false, error: 'invalid_cli', message: err?.message ?? String(err) });
|
|
3362
|
-
}
|
|
3363
|
-
const model = typeof body.model === 'string' ? body.model.trim() : '';
|
|
3364
|
-
const currentBotConfig = getBot(cachedLarkAppId).config;
|
|
3365
|
-
const runtimeFieldPresent = Object.prototype.hasOwnProperty.call(body, 'cliRuntime');
|
|
3366
|
-
const currentSelectionKey = selectionKeyForBot(currentBotConfig.cliId, currentBotConfig.wrapperCli);
|
|
3367
|
-
const selectionChanged = key !== currentSelectionKey;
|
|
3368
|
-
let nextRuntime;
|
|
3369
|
-
let nextLegacyPath;
|
|
3370
|
-
if (runtimeFieldPresent) {
|
|
3371
|
-
if (body.cliRuntime !== null) {
|
|
3372
|
-
if (selected.cliId !== 'codex') {
|
|
3373
|
-
return jsonRes(res, 400, { ok: false, error: 'runtime_requires_codex' });
|
|
3374
|
-
}
|
|
3375
|
-
if (selected.wrapperCli) {
|
|
3376
|
-
return jsonRes(res, 400, { ok: false, error: 'runtime_wrapper_conflict' });
|
|
3377
|
-
}
|
|
3378
|
-
try {
|
|
3379
|
-
nextRuntime = normalizeCliRuntimeConfig(body.cliRuntime, 'cliRuntime');
|
|
3380
|
-
}
|
|
3381
|
-
catch (err) {
|
|
3382
|
-
return jsonRes(res, 400, {
|
|
3383
|
-
ok: false,
|
|
3384
|
-
error: 'invalid_cli_runtime',
|
|
3385
|
-
message: err instanceof Error ? err.message : String(err),
|
|
3386
|
-
});
|
|
3387
|
-
}
|
|
3388
|
-
}
|
|
3389
|
-
// null explicitly means built-in runtime; both structured and legacy
|
|
3390
|
-
// executable overrides are cleared.
|
|
3391
|
-
}
|
|
3392
|
-
else if (!selectionChanged) {
|
|
3393
|
-
// Old dashboard clients know only `{cliId, model}`. Preserve the runtime on
|
|
3394
|
-
// same-agent saves so editing a model cannot silently erase new config.
|
|
3395
|
-
nextRuntime = currentBotConfig.cliRuntime;
|
|
3396
|
-
nextLegacyPath = nextRuntime ? undefined : currentBotConfig.cliPathOverride;
|
|
3397
|
-
}
|
|
3398
|
-
const effectivePath = nextRuntime?.executable ?? nextLegacyPath;
|
|
3399
|
-
const availability = checkCliAvailability({
|
|
3400
|
-
cliId: selected.cliId,
|
|
3401
|
-
wrapperCli: selected.wrapperCli,
|
|
3402
|
-
cliPathOverride: effectivePath,
|
|
3403
|
-
});
|
|
3404
|
-
let runtimeProbe;
|
|
3405
|
-
if (runtimeFieldPresent && nextRuntime) {
|
|
3406
|
-
if (!availability.available) {
|
|
3407
|
-
return jsonRes(res, 400, {
|
|
3408
|
-
ok: false,
|
|
3409
|
-
error: 'runtime_unavailable',
|
|
3410
|
-
message: availability.reason ?? 'runtime executable is unavailable',
|
|
3411
|
-
});
|
|
3412
|
-
}
|
|
3413
|
-
try {
|
|
3414
|
-
const raw = execFileSync(availability.resolvedPath ?? nextRuntime.executable, ['--version'], {
|
|
3415
|
-
encoding: 'utf8',
|
|
3416
|
-
timeout: 5_000,
|
|
3417
|
-
stdio: ['ignore', 'pipe', 'pipe'],
|
|
3418
|
-
maxBuffer: 2 * 1024 * 1024,
|
|
3419
|
-
}).trim();
|
|
3420
|
-
const version = raw.match(/\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?/)?.[0];
|
|
3421
|
-
if (!version)
|
|
3422
|
-
throw new Error(`无法识别 --version 输出:${raw.slice(0, 120)}`);
|
|
3423
|
-
runtimeProbe = { version, updateProvider: nextRuntime.update?.provider ?? 'auto' };
|
|
3424
|
-
}
|
|
3425
|
-
catch (err) {
|
|
3426
|
-
return jsonRes(res, 400, {
|
|
3427
|
-
ok: false,
|
|
3428
|
-
error: 'runtime_version_probe_failed',
|
|
3429
|
-
message: err instanceof Error ? err.message : String(err),
|
|
3430
|
-
});
|
|
3431
|
-
}
|
|
3432
|
-
}
|
|
3433
|
-
// Existing Bot edits remain saveable (operators may intentionally configure
|
|
3434
|
-
// first and install second), but the response is explicit so Dashboard never
|
|
3435
|
-
// claims a missing Agent was saved successfully without qualification.
|
|
3436
|
-
const availabilityWarning = availability.available
|
|
3437
|
-
? undefined
|
|
3438
|
-
: `配置已保存,但所选 Agent 当前无法启动:${availability.reason ?? '本地启动依赖不可用'}。请先在 daemon 所在机器安装或修正 PATH / CLI 路径。`;
|
|
3439
|
-
// If the new CLI/wrapper can no longer enforce a currently-on read isolation,
|
|
3440
|
-
// auto-clear the flag here so the next session doesn't fail-close on it. (The
|
|
3441
|
-
// read-isolation toggle validates at enable time; changing the agent afterwards
|
|
3442
|
-
// is the other way a bot could end up configured-but-unenforceable.)
|
|
3443
|
-
let readIsolationCleared = false;
|
|
3444
|
-
const r = await rmwBotEntry(cachedLarkAppId, (entry) => {
|
|
3445
|
-
entry.cliId = selected.cliId;
|
|
3446
|
-
if (selected.wrapperCli)
|
|
3447
|
-
entry.wrapperCli = selected.wrapperCli;
|
|
3448
|
-
else
|
|
3449
|
-
delete entry.wrapperCli;
|
|
3450
|
-
if (nextRuntime) {
|
|
3451
|
-
entry.cliRuntime = nextRuntime;
|
|
3452
|
-
// Downgrade shadow: older BotMux versions ignore cliRuntime but retain
|
|
3453
|
-
// cliPathOverride, so a rollback still launches this distribution.
|
|
3454
|
-
entry.cliPathOverride = nextRuntime.executable;
|
|
3455
|
-
}
|
|
3456
|
-
else if (nextLegacyPath) {
|
|
3457
|
-
entry.cliPathOverride = nextLegacyPath;
|
|
3458
|
-
delete entry.cliRuntime;
|
|
3459
|
-
}
|
|
3460
|
-
else {
|
|
3461
|
-
delete entry.cliRuntime;
|
|
3462
|
-
delete entry.cliPathOverride;
|
|
3463
|
-
}
|
|
3464
|
-
if (model)
|
|
3465
|
-
entry.model = model;
|
|
3466
|
-
else
|
|
3467
|
-
delete entry.model;
|
|
3468
|
-
if (entry.readIsolation === true &&
|
|
3469
|
-
!readIsolationEnforceableFor({ cliId: selected.cliId, cliPathOverride: effectivePath, wrapperCli: selected.wrapperCli })) {
|
|
3470
|
-
delete entry.readIsolation;
|
|
3471
|
-
readIsolationCleared = true;
|
|
3472
|
-
}
|
|
3473
|
-
// cliId=riff → backendType 自动设为 riff(否则 spawn 走 pty 后端找不到本地二进制)。
|
|
3474
|
-
if (selected.cliId === 'riff') {
|
|
3475
|
-
entry.backendType = 'riff';
|
|
3476
|
-
}
|
|
3477
|
-
else if (entry.backendType === 'riff') {
|
|
3478
|
-
// 从 riff 切回其它 CLI:清掉这个自动配对的 backend override,回落 daemon
|
|
3479
|
-
// 默认后端——否则新 CLI 会跑在 RiffBackend 上(PTY 分块输入被当成一串 riff
|
|
3480
|
-
// 任务)。手动的 pty/tmux/herdr/zellij override 不受影响(它们不会是 riff)。
|
|
3481
|
-
delete entry.backendType;
|
|
3482
|
-
}
|
|
3483
|
-
return { write: true, result: null };
|
|
3484
|
-
});
|
|
3485
|
-
if (!r.ok)
|
|
3486
|
-
return jsonRes(res, 400, { ok: false, error: r.reason });
|
|
3487
|
-
const bot = getBot(cachedLarkAppId);
|
|
3488
|
-
bot.config.cliId = selected.cliId;
|
|
3489
|
-
bot.config.cliRuntime = nextRuntime;
|
|
3490
|
-
bot.config.cliPathOverride = nextRuntime?.executable ?? nextLegacyPath;
|
|
3491
|
-
if (selected.wrapperCli)
|
|
3492
|
-
bot.config.wrapperCli = selected.wrapperCli;
|
|
3493
|
-
else
|
|
3494
|
-
bot.config.wrapperCli = undefined;
|
|
3495
|
-
bot.config.model = model || undefined;
|
|
3496
|
-
if (readIsolationCleared)
|
|
3497
|
-
bot.config.readIsolation = false;
|
|
3498
|
-
if (selected.cliId === 'riff') {
|
|
3499
|
-
bot.config.backendType = 'riff';
|
|
3500
|
-
}
|
|
3501
|
-
else if (bot.config.backendType === 'riff') {
|
|
3502
|
-
bot.config.backendType = undefined;
|
|
3503
|
-
}
|
|
3504
|
-
// 热切后立刻清掉本 bot 名下失配的存量会话——否则它们冻结的旧 CLI 会被下一条
|
|
3505
|
-
// 消息 lazy resume 复活,要等下次 daemon 重启才被 restore 守卫清理。
|
|
3506
|
-
const closedMismatchedSessions = await closeCliMismatchedSessionsForBot(cachedLarkAppId);
|
|
3507
|
-
const selectionKey = selectionKeyForBot(selected.cliId, selected.wrapperCli);
|
|
3508
|
-
jsonRes(res, 200, {
|
|
3509
|
-
ok: true,
|
|
3510
|
-
cliId: selected.cliId,
|
|
3511
|
-
cliRuntime: nextRuntime ?? null,
|
|
3512
|
-
cliPathOverride: nextRuntime ? null : nextLegacyPath ?? null,
|
|
3513
|
-
wrapperCli: selected.wrapperCli ?? null,
|
|
3514
|
-
model: model || null,
|
|
3515
|
-
selectionKey,
|
|
3516
|
-
closedMismatchedSessions,
|
|
3517
|
-
// Report the (possibly auto-cleared) read-isolation state + whether the new
|
|
3518
|
-
// agent can still enforce it, so the dashboard updates its toggle immediately
|
|
3519
|
-
// instead of showing a stale enabled/supported state until a full refetch.
|
|
3520
|
-
readIsolation: bot.config.readIsolation === true,
|
|
3521
|
-
readIsolationSupported: readIsolationEnforceableFor(bot.config),
|
|
3522
|
-
readIsolationCleared,
|
|
3523
|
-
agentAvailable: availability.available,
|
|
3524
|
-
availabilityWarning,
|
|
3525
|
-
requiredCommand: availability.command,
|
|
3526
|
-
runtimeProbe,
|
|
3527
|
-
});
|
|
3528
|
-
});
|
|
3529
|
-
// Per-bot 私聊单聊模式 p2pMode。Body `{ p2pMode: 'chat' | 'thread' }`:
|
|
3530
|
-
// • 'chat'(默认) → 私聊走扁平连续 chat-scope 会话
|
|
3531
|
-
// • 'thread' → 显式回到每条 DM 独立 thread-scope 会话
|
|
3532
|
-
// 走 applyConfigField(与 /botconfig 同一写盘 + 热更新路径),保证一致。
|
|
3533
|
-
ipcRoute('PUT', '/api/bot-p2p-mode', async (req, res) => {
|
|
3534
|
-
if (!cachedLarkAppId)
|
|
3535
|
-
return jsonRes(res, 503, { error: 'larkAppId_not_set' });
|
|
3536
|
-
let body;
|
|
3537
|
-
try {
|
|
3538
|
-
body = await readJsonBody(req);
|
|
3539
|
-
}
|
|
3540
|
-
catch {
|
|
3541
|
-
return jsonRes(res, 400, { ok: false, error: 'bad_json' });
|
|
3542
|
-
}
|
|
3543
|
-
const spec = findConfigField('p2pMode');
|
|
3544
|
-
if (!spec)
|
|
3545
|
-
return jsonRes(res, 500, { ok: false, error: 'spec_missing' });
|
|
3546
|
-
// 只有 'thread' 有意义;其它(含 'chat',新默认)一律清回默认,bots.json 保持干净。
|
|
3547
|
-
const value = body.p2pMode === 'thread' ? 'thread' : null;
|
|
3548
|
-
const r = await applyConfigField(cachedLarkAppId, spec, value);
|
|
3549
|
-
if (!r.ok)
|
|
3550
|
-
return jsonRes(res, 400, { ok: false, error: r.reason });
|
|
3551
|
-
jsonRes(res, 200, { ok: true, p2pMode: value ?? 'chat' });
|
|
3552
|
-
});
|
|
3553
|
-
// Per-bot 内置技能注入模式 skillInjection。Body `{ skillInjection: 'global'|'prompt'|'off'|'' }`:
|
|
3554
|
-
// • 'global'|'prompt'|'off' → 显式覆盖本 bot
|
|
3555
|
-
// • ''/其它 → 清回机器级默认(config.json skills.builtinInjection)
|
|
3556
|
-
// 走 applyConfigField(与 /config 同一写盘 + 热更新路径)。next-session 生效;
|
|
3557
|
-
// 切到/离开 global 的全局盘安装受 once-cache 限,需重启 daemon 才完全生效。
|
|
3558
|
-
ipcRoute('PUT', '/api/bot-skill-injection', async (req, res) => {
|
|
3559
|
-
if (!cachedLarkAppId)
|
|
3560
|
-
return jsonRes(res, 503, { error: 'larkAppId_not_set' });
|
|
3561
|
-
let body;
|
|
3562
|
-
try {
|
|
3563
|
-
body = await readJsonBody(req);
|
|
3564
|
-
}
|
|
3565
|
-
catch {
|
|
3566
|
-
return jsonRes(res, 400, { ok: false, error: 'bad_json' });
|
|
3567
|
-
}
|
|
3568
|
-
const spec = findConfigField('skillInjection');
|
|
3569
|
-
if (!spec)
|
|
3570
|
-
return jsonRes(res, 500, { ok: false, error: 'spec_missing' });
|
|
3571
|
-
const v = body.skillInjection;
|
|
3572
|
-
const value = v === 'global' || v === 'prompt' || v === 'off' ? v : null;
|
|
3573
|
-
const r = await applyConfigField(cachedLarkAppId, spec, value);
|
|
3574
|
-
if (!r.ok)
|
|
3575
|
-
return jsonRes(res, 400, { ok: false, error: r.reason });
|
|
3576
|
-
jsonRes(res, 200, { ok: true, skillInjection: value });
|
|
3577
|
-
});
|
|
3578
|
-
// Per-bot 启动命令 startupCommands。Body `{ startupCommands: string }`(原始文本,
|
|
3579
|
-
// 逗号/换行分隔,每条可带参数如 `/effort ultracode`):空白 → 清除(不发任何命令)。
|
|
3580
|
-
// 走 applyConfigField(与 /botconfig 文本子卡同一写盘 + 内存热更新路径),next-session
|
|
3581
|
-
// 生效(下个会话起按序自动发)。
|
|
3582
|
-
ipcRoute('PUT', '/api/bot-startup-commands', async (req, res) => {
|
|
3583
|
-
if (!cachedLarkAppId)
|
|
3584
|
-
return jsonRes(res, 503, { error: 'larkAppId_not_set' });
|
|
3585
|
-
let body;
|
|
3586
|
-
try {
|
|
3587
|
-
body = await readJsonBody(req);
|
|
3588
|
-
}
|
|
3589
|
-
catch {
|
|
3590
|
-
return jsonRes(res, 400, { ok: false, error: 'bad_json' });
|
|
3591
|
-
}
|
|
3592
|
-
const spec = findConfigField('startupCommands');
|
|
3593
|
-
if (!spec)
|
|
3594
|
-
return jsonRes(res, 500, { ok: false, error: 'spec_missing' });
|
|
3595
|
-
const raw = typeof body.startupCommands === 'string' ? body.startupCommands : '';
|
|
3596
|
-
let value;
|
|
3597
|
-
if (!raw.trim()) {
|
|
3598
|
-
value = null; // 清除
|
|
3599
|
-
}
|
|
3600
|
-
else {
|
|
3601
|
-
const coerced = coerceConfigValue(spec, raw);
|
|
3602
|
-
if (!coerced.ok)
|
|
3603
|
-
return jsonRes(res, 400, { ok: false, error: coerced.reason });
|
|
3604
|
-
value = coerced.value;
|
|
3605
|
-
}
|
|
3606
|
-
const r = await applyConfigField(cachedLarkAppId, spec, value);
|
|
3607
|
-
if (!r.ok)
|
|
3608
|
-
return jsonRes(res, 400, { ok: false, error: r.reason });
|
|
3609
|
-
jsonRes(res, 200, { ok: true, startupCommands: (value ?? []).join('\n') });
|
|
3610
|
-
});
|
|
3611
|
-
// Per-bot 透传 slash 命令 customPassthroughCommands。Body `{ customPassthroughCommands: string }`
|
|
3612
|
-
// (原始文本,逗号/空格分隔;空白=清除→回仅内置白名单)。走 stringList 的
|
|
3613
|
-
// coerceConfigValue(用字段自带 parseList,与 /botconfig 同口径)+ applyConfigField
|
|
3614
|
-
// (写盘 + 内存热更新),immediate 生效。回包 space-joined 供输入框回填。
|
|
3615
|
-
ipcRoute('PUT', '/api/bot-custom-passthrough', async (req, res) => {
|
|
3616
|
-
if (!cachedLarkAppId)
|
|
3617
|
-
return jsonRes(res, 503, { error: 'larkAppId_not_set' });
|
|
3618
|
-
let body;
|
|
3619
|
-
try {
|
|
3620
|
-
body = await readJsonBody(req);
|
|
3621
|
-
}
|
|
3622
|
-
catch {
|
|
3623
|
-
return jsonRes(res, 400, { ok: false, error: 'bad_json' });
|
|
3624
|
-
}
|
|
3625
|
-
const spec = findConfigField('customPassthroughCommands');
|
|
3626
|
-
if (!spec)
|
|
3627
|
-
return jsonRes(res, 500, { ok: false, error: 'spec_missing' });
|
|
3628
|
-
const raw = typeof body.customPassthroughCommands === 'string' ? body.customPassthroughCommands : '';
|
|
3629
|
-
let value;
|
|
3630
|
-
if (!raw.trim()) {
|
|
3631
|
-
value = null; // 清除 → 回仅内置白名单
|
|
3632
|
-
}
|
|
3633
|
-
else {
|
|
3634
|
-
const coerced = coerceConfigValue(spec, raw);
|
|
3635
|
-
if (!coerced.ok)
|
|
3636
|
-
return jsonRes(res, 400, { ok: false, error: coerced.reason });
|
|
3637
|
-
value = coerced.value;
|
|
3638
|
-
}
|
|
3639
|
-
const r = await applyConfigField(cachedLarkAppId, spec, value);
|
|
3640
|
-
if (!r.ok)
|
|
3641
|
-
return jsonRes(res, 400, { ok: false, error: r.reason });
|
|
3642
|
-
jsonRes(res, 200, { ok: true, customPassthroughCommands: (value ?? []).join(' ') });
|
|
3643
|
-
});
|
|
3644
|
-
// Per-bot daemon 命令降权名单 canTalkDaemonCommands。Body
|
|
3645
|
-
// `{ canTalkDaemonCommands: string }`(原始文本,逗号/空格分隔;空白=清除→回全部
|
|
3646
|
-
// 仅管理员)。走 stringList 的 coerceConfigValue(字段自带 parseList 只认 daemon
|
|
3647
|
-
// 命令,透传/拼错条目被滤掉)+ applyConfigField(写盘 + 内存热更新),immediate 生效。
|
|
3648
|
-
ipcRoute('PUT', '/api/bot-cantalk-daemon-commands', async (req, res) => {
|
|
3649
|
-
if (!cachedLarkAppId)
|
|
3650
|
-
return jsonRes(res, 503, { error: 'larkAppId_not_set' });
|
|
3651
|
-
let body;
|
|
3652
|
-
try {
|
|
3653
|
-
body = await readJsonBody(req);
|
|
3654
|
-
}
|
|
3655
|
-
catch {
|
|
3656
|
-
return jsonRes(res, 400, { ok: false, error: 'bad_json' });
|
|
3657
|
-
}
|
|
3658
|
-
const spec = findConfigField('canTalkDaemonCommands');
|
|
3659
|
-
if (!spec)
|
|
3660
|
-
return jsonRes(res, 500, { ok: false, error: 'spec_missing' });
|
|
3661
|
-
const raw = typeof body.canTalkDaemonCommands === 'string' ? body.canTalkDaemonCommands : '';
|
|
3662
|
-
let value;
|
|
3663
|
-
if (!raw.trim()) {
|
|
3664
|
-
value = null; // 清除 → 回全部仅管理员
|
|
3665
|
-
}
|
|
3666
|
-
else {
|
|
3667
|
-
const coerced = coerceConfigValue(spec, raw);
|
|
3668
|
-
if (!coerced.ok)
|
|
3669
|
-
return jsonRes(res, 400, { ok: false, error: coerced.reason });
|
|
3670
|
-
value = coerced.value;
|
|
3671
|
-
}
|
|
3672
|
-
const r = await applyConfigField(cachedLarkAppId, spec, value);
|
|
3673
|
-
if (!r.ok)
|
|
3674
|
-
return jsonRes(res, 400, { ok: false, error: r.reason });
|
|
3675
|
-
jsonRes(res, 200, { ok: true, canTalkDaemonCommands: (value ?? []).join(' ') });
|
|
3676
|
-
});
|
|
3677
|
-
// Per-bot launch-shell override launchShell。Body `{ launchShell: string }`:
|
|
3678
|
-
// 空字符串=清除(回 $SHELL)。走 applyConfigField(与 /config launchShell 同一写盘
|
|
3679
|
-
// + 内存热更新路径),next-session 生效(下个会话起用新 shell 启动 CLI)。
|
|
3680
|
-
ipcRoute('PUT', '/api/bot-launch-shell', async (req, res) => {
|
|
3681
|
-
if (!cachedLarkAppId)
|
|
3682
|
-
return jsonRes(res, 503, { error: 'larkAppId_not_set' });
|
|
3683
|
-
let body;
|
|
3684
|
-
try {
|
|
3685
|
-
body = await readJsonBody(req);
|
|
3686
|
-
}
|
|
3687
|
-
catch {
|
|
3688
|
-
return jsonRes(res, 400, { ok: false, error: 'bad_json' });
|
|
3689
|
-
}
|
|
3690
|
-
const spec = findConfigField('launchShell');
|
|
3691
|
-
if (!spec)
|
|
3692
|
-
return jsonRes(res, 500, { ok: false, error: 'spec_missing' });
|
|
3693
|
-
const raw = typeof body.launchShell === 'string' ? body.launchShell : '';
|
|
3694
|
-
let value;
|
|
3695
|
-
if (!raw.trim()) {
|
|
3696
|
-
value = null; // 清除 → 回 $SHELL
|
|
3697
|
-
}
|
|
3698
|
-
else {
|
|
3699
|
-
const coerced = coerceConfigValue(spec, raw);
|
|
3700
|
-
if (!coerced.ok)
|
|
3701
|
-
return jsonRes(res, 400, { ok: false, error: coerced.reason });
|
|
3702
|
-
value = coerced.value;
|
|
3703
|
-
}
|
|
3704
|
-
const r = await applyConfigField(cachedLarkAppId, spec, value);
|
|
3705
|
-
if (!r.ok)
|
|
3706
|
-
return jsonRes(res, 400, { ok: false, error: r.reason });
|
|
3707
|
-
jsonRes(res, 200, { ok: true, launchShell: value ?? '' });
|
|
3708
|
-
});
|
|
3709
|
-
// Per-bot 环境变量 env。Body `{ env: string }`(原始 JSON 文本,如
|
|
3710
|
-
// `{"ANTHROPIC_BASE_URL":"…","ANTHROPIC_AUTH_TOKEN":"…"}` 让本 bot 走 GLM/第三方
|
|
3711
|
-
// 服务商):空白 → 清除;否则按 json kind 解析 + sanitizePerBotEnv 过滤后落盘。
|
|
3712
|
-
// 走 applyConfigField(与 /botconfig 同一写盘 + 内存热更新路径),next-session 生效
|
|
3713
|
-
// (下个会话起注入到 CLI 进程)。回包返回脱敏后的 pretty JSON 供 textarea 回填。
|
|
3714
|
-
ipcRoute('PUT', '/api/bot-env', async (req, res) => {
|
|
3715
|
-
if (!cachedLarkAppId)
|
|
3716
|
-
return jsonRes(res, 503, { error: 'larkAppId_not_set' });
|
|
3717
|
-
let body;
|
|
3718
|
-
try {
|
|
3719
|
-
body = await readJsonBody(req);
|
|
3720
|
-
}
|
|
3721
|
-
catch {
|
|
3722
|
-
return jsonRes(res, 400, { ok: false, error: 'bad_json' });
|
|
3723
|
-
}
|
|
3724
|
-
const spec = findConfigField('env');
|
|
3725
|
-
if (!spec)
|
|
3726
|
-
return jsonRes(res, 500, { ok: false, error: 'spec_missing' });
|
|
3727
|
-
const raw = typeof body.env === 'string' ? body.env : '';
|
|
3728
|
-
let value;
|
|
3729
|
-
if (!raw.trim()) {
|
|
3730
|
-
value = null; // 清除
|
|
3731
|
-
}
|
|
3732
|
-
else {
|
|
3733
|
-
const coerced = coerceConfigValue(spec, raw);
|
|
3734
|
-
if (!coerced.ok)
|
|
3735
|
-
return jsonRes(res, 400, { ok: false, error: coerced.reason });
|
|
3736
|
-
value = coerced.value;
|
|
3737
|
-
}
|
|
3738
|
-
const r = await applyConfigField(cachedLarkAppId, spec, value);
|
|
3739
|
-
if (!r.ok)
|
|
3740
|
-
return jsonRes(res, 400, { ok: false, error: r.reason });
|
|
3741
|
-
jsonRes(res, 200, { ok: true, env: value ? JSON.stringify(value, null, 2) : '' });
|
|
3742
|
-
});
|
|
3743
|
-
// Per-bot riff 后端配置。Body `{ riff: string }`(原始 JSON 文本,如
|
|
3744
|
-
// `{"baseUrl":"https://...","model":"gpt-5.5","reasoningEffort":"high"}`):
|
|
3745
|
-
// 空白 → 清除;否则按 json kind 解析后落盘。走 applyConfigField(与 /botconfig
|
|
3746
|
-
// 同一写盘 + 内存热更新路径),next-session 生效。仅 backendType=riff 时使用。
|
|
3747
|
-
/** riff 配置里 dashboard 可编辑的字段——PUT /bot-riff 只覆盖这些,其余保留。 */
|
|
3748
|
-
// injectStatusLines 已从 dashboard UI 移除(恒默认开启)——不在此集合中意味着
|
|
3749
|
-
// 存量 bots.json 值按「隐藏字段」原样保留。
|
|
3750
|
-
const RIFF_UI_EDITABLE_KEYS = new Set(['baseUrl', 'sandboxCluster', 'model', 'reasoningEffort', 'jwtEnv', 'systemPrompt', 'setupCommands']);
|
|
3751
|
-
/** 发给浏览器前脱敏:明文 jwt / env(可能含各类密钥)绝不进 dashboard 响应。 */
|
|
3752
|
-
function redactRiffForClient(riff) {
|
|
3753
|
-
if (!riff || typeof riff !== 'object')
|
|
3754
|
-
return null;
|
|
3755
|
-
const { jwt: _jwt, env: _env, ...safe } = riff;
|
|
3756
|
-
return safe;
|
|
3757
|
-
}
|
|
3758
|
-
ipcRoute('PUT', '/api/bot-riff', async (req, res) => {
|
|
3759
|
-
if (!cachedLarkAppId)
|
|
3760
|
-
return jsonRes(res, 503, { error: 'larkAppId_not_set' });
|
|
3761
|
-
let body;
|
|
3762
|
-
try {
|
|
3763
|
-
body = await readJsonBody(req);
|
|
3764
|
-
}
|
|
3765
|
-
catch {
|
|
3766
|
-
return jsonRes(res, 400, { ok: false, error: 'bad_json' });
|
|
3767
|
-
}
|
|
3768
|
-
const spec = findConfigField('riff');
|
|
3769
|
-
if (!spec)
|
|
3770
|
-
return jsonRes(res, 500, { ok: false, error: 'spec_missing' });
|
|
3771
|
-
const raw = typeof body.riff === 'string' ? body.riff : '';
|
|
3772
|
-
let value;
|
|
3773
|
-
if (!raw.trim()) {
|
|
3774
|
-
value = null; // 清除(显式清空整份 riff 配置,含隐藏字段)
|
|
3775
|
-
}
|
|
3776
|
-
else {
|
|
3777
|
-
const coerced = coerceConfigValue(spec, raw);
|
|
3778
|
-
if (!coerced.ok)
|
|
3779
|
-
return jsonRes(res, 400, { ok: false, error: coerced.reason });
|
|
3780
|
-
value = coerced.value;
|
|
3781
|
-
// 合并保存:dashboard 只回写 UI 展示的字段;接口支持但 UI 未展示的字段
|
|
3782
|
-
// (templateId / jwt / env / logLevel / repos…)必须原样保留,否则用户只改
|
|
3783
|
-
// 一个 model 就会静默删掉认证等隐藏配置。
|
|
3784
|
-
const prev = (getBot(cachedLarkAppId).config.riff ?? {});
|
|
3785
|
-
const preserved = Object.fromEntries(Object.entries(prev).filter(([k]) => !RIFF_UI_EDITABLE_KEYS.has(k)));
|
|
3786
|
-
// Older dashboard clients do not send sandboxCluster. Preserve a valid
|
|
3787
|
-
// existing selection for them; a brand-new config follows Riff's BOE
|
|
3788
|
-
// default. New clients always submit the explicit dropdown value.
|
|
3789
|
-
const sandboxCluster = value.sandboxCluster ?? prev.sandboxCluster ?? 'boe';
|
|
3790
|
-
if (!isValidRiffSandboxCluster(sandboxCluster)) {
|
|
3791
|
-
return jsonRes(res, 400, { ok: false, error: 'invalid_sandbox_cluster' });
|
|
3792
|
-
}
|
|
3793
|
-
value = { ...preserved, ...value, sandboxCluster };
|
|
3794
|
-
if (!isValidRiffBaseUrl(value.baseUrl)) {
|
|
3795
|
-
return jsonRes(res, 400, { ok: false, error: 'invalid_base_url' });
|
|
3796
|
-
}
|
|
3797
|
-
}
|
|
3798
|
-
const r = await applyConfigField(cachedLarkAppId, spec, value);
|
|
3799
|
-
if (!r.ok)
|
|
3800
|
-
return jsonRes(res, 400, { ok: false, error: r.reason });
|
|
3801
|
-
jsonRes(res, 200, { ok: true, riff: value ? JSON.stringify(redactRiffForClient(value), null, 2) : '' });
|
|
3802
|
-
});
|
|
3803
|
-
// Per-bot 最大同时活跃会话数 maxLiveWorkers。Body `{ maxLiveWorkers: number | null }`:
|
|
3804
|
-
// • 正整数 → 设上限;超过后 idle-worker sweeper 把最久未用的会话休眠到上限内
|
|
3805
|
-
// • null → 清除(回落到内置默认 30)
|
|
3806
|
-
// 走 applyConfigField(与 /config 同一写盘 + 内存热更新路径):sweeper 每分钟读
|
|
3807
|
-
// 实时 bot.config.maxLiveWorkers,免重启即生效。
|
|
3808
|
-
ipcRoute('PUT', '/api/bot-max-live-workers', async (req, res) => {
|
|
3809
|
-
if (!cachedLarkAppId)
|
|
3810
|
-
return jsonRes(res, 503, { error: 'larkAppId_not_set' });
|
|
3811
|
-
let raw;
|
|
3812
|
-
try {
|
|
3813
|
-
raw = await readJsonBody(req);
|
|
3814
|
-
}
|
|
3815
|
-
catch {
|
|
3816
|
-
return jsonRes(res, 400, { ok: false, error: 'bad_json' });
|
|
3817
|
-
}
|
|
3818
|
-
if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) {
|
|
3819
|
-
return jsonRes(res, 400, { ok: false, error: 'no_valid_fields' });
|
|
3820
|
-
}
|
|
3821
|
-
const body = raw;
|
|
3822
|
-
const spec = findConfigField('maxLiveWorkers');
|
|
3823
|
-
if (!spec)
|
|
3824
|
-
return jsonRes(res, 500, { ok: false, error: 'spec_missing' });
|
|
3825
|
-
// null(含 JSON null)= 清除上限;number 走 coerce 校验正整数。
|
|
3826
|
-
let value;
|
|
3827
|
-
if (body.maxLiveWorkers === null || body.maxLiveWorkers === undefined) {
|
|
3828
|
-
value = null;
|
|
3829
|
-
}
|
|
3830
|
-
else {
|
|
3831
|
-
const c = coerceConfigValue(spec, body.maxLiveWorkers);
|
|
3832
|
-
if (!c.ok || typeof c.value !== 'number')
|
|
3833
|
-
return jsonRes(res, 400, { ok: false, error: 'invalid_number' });
|
|
3834
|
-
value = c.value;
|
|
3835
|
-
}
|
|
3836
|
-
const r = await applyConfigField(cachedLarkAppId, spec, value);
|
|
3837
|
-
if (!r.ok)
|
|
3838
|
-
return jsonRes(res, 400, { ok: false, error: r.reason });
|
|
3839
|
-
jsonRes(res, 200, { ok: true, maxLiveWorkers: value });
|
|
3840
|
-
});
|
|
3841
|
-
// Per-bot skill policy. Dashboard uses this for attach/detach; JSON policy
|
|
3842
|
-
// still shares the same applyConfigField path as /botconfig.
|
|
3843
|
-
ipcRoute('PUT', '/api/bot-skills', async (req, res) => {
|
|
3844
|
-
if (!cachedLarkAppId)
|
|
3845
|
-
return jsonRes(res, 503, { error: 'larkAppId_not_set' });
|
|
3846
|
-
let raw;
|
|
3847
|
-
try {
|
|
3848
|
-
raw = await readJsonBody(req);
|
|
3849
|
-
}
|
|
3850
|
-
catch {
|
|
3851
|
-
return jsonRes(res, 400, { ok: false, error: 'bad_json' });
|
|
3852
|
-
}
|
|
3853
|
-
if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {
|
|
3854
|
-
return jsonRes(res, 400, { ok: false, error: 'bad_json' });
|
|
3855
|
-
}
|
|
3856
|
-
const body = raw;
|
|
3857
|
-
const spec = findConfigField('skills');
|
|
3858
|
-
if (!spec)
|
|
3859
|
-
return jsonRes(res, 500, { ok: false, error: 'spec_missing' });
|
|
3860
|
-
const current = getBot(cachedLarkAppId).config.skills;
|
|
3861
|
-
let next = current;
|
|
3862
|
-
if (body.action === 'attach') {
|
|
3863
|
-
const name = typeof body.name === 'string' ? body.name.trim() : '';
|
|
3864
|
-
if (!name)
|
|
3865
|
-
return jsonRes(res, 400, { ok: false, error: 'name_required' });
|
|
3866
|
-
if (!readSkillRegistry().skills[name])
|
|
3867
|
-
return jsonRes(res, 400, { ok: false, error: 'skill_not_installed' });
|
|
3868
|
-
next = attachSkillPolicy(current, name);
|
|
3869
|
-
}
|
|
3870
|
-
else if (body.action === 'detach') {
|
|
3871
|
-
const name = typeof body.name === 'string' ? body.name.trim() : '';
|
|
3872
|
-
if (!name)
|
|
3873
|
-
return jsonRes(res, 400, { ok: false, error: 'name_required' });
|
|
3874
|
-
next = detachSkillPolicy(current, name);
|
|
3875
|
-
}
|
|
3876
|
-
else if (body.action === 'set') {
|
|
3877
|
-
if (body.policy === null) {
|
|
3878
|
-
next = undefined;
|
|
3879
|
-
}
|
|
3880
|
-
else {
|
|
3881
|
-
const parsed = readBotSkillPolicy(body.policy);
|
|
3882
|
-
if (!parsed)
|
|
3883
|
-
return jsonRes(res, 400, { ok: false, error: 'invalid_policy' });
|
|
3884
|
-
next = parsed;
|
|
3885
|
-
}
|
|
3886
|
-
}
|
|
3887
|
-
else {
|
|
3888
|
-
return jsonRes(res, 400, { ok: false, error: 'invalid_action' });
|
|
3889
|
-
}
|
|
3890
|
-
const r = await applyConfigField(cachedLarkAppId, spec, next ?? null);
|
|
3891
|
-
if (!r.ok)
|
|
3892
|
-
return jsonRes(res, 400, { ok: false, error: r.reason });
|
|
3893
|
-
jsonRes(res, 200, { ok: true, skills: getBot(cachedLarkAppId).config.skills ?? null });
|
|
3894
|
-
});
|
|
3895
|
-
// Per-bot file-sandbox toggle. Body `{ enabled: boolean }`. When on, this bot's
|
|
3896
|
-
// CLI sessions run inside a per-session bwrap file sandbox (Linux). For oncall
|
|
3897
|
-
// bots shared with semi-trusted users.
|
|
3898
|
-
ipcRoute('PUT', '/api/bot-sandbox', async (req, res) => {
|
|
3899
|
-
if (!cachedLarkAppId)
|
|
3900
|
-
return jsonRes(res, 503, { error: 'larkAppId_not_set' });
|
|
3901
|
-
let body;
|
|
3902
|
-
try {
|
|
3903
|
-
body = await readJsonBody(req);
|
|
3904
|
-
}
|
|
3905
|
-
catch {
|
|
3906
|
-
return jsonRes(res, 400, { ok: false, error: 'bad_json' });
|
|
3907
|
-
}
|
|
3908
|
-
const r = await sandboxStore.updateBotSandbox(cachedLarkAppId, body.enabled === true);
|
|
3909
|
-
if (!r.ok)
|
|
3910
|
-
return jsonRes(res, 400, { ok: false, error: r.reason });
|
|
3911
|
-
jsonRes(res, 200, { ok: true, sandbox: r.sandbox });
|
|
3912
|
-
});
|
|
3913
|
-
// Per-bot sandboxPaths (three-tier whitelist: readWrite / readOnly / deny).
|
|
3914
|
-
// Body `{ readWrite?: string[]; readOnly?: string[]; deny?: string[] }`. Highest-
|
|
3915
|
-
// precedence layer of the FsPolicy — an empty/absent tier falls back to the
|
|
3916
|
-
// deny-by-default baseline. Passing all-empty CLEARS the field. next-session
|
|
3917
|
-
// 生效:running sessions keep their spawn-time policy, only new spawns re-read it.
|
|
3918
|
-
ipcRoute('PUT', '/api/bot-sandbox-paths', async (req, res) => {
|
|
3919
|
-
if (!cachedLarkAppId)
|
|
3920
|
-
return jsonRes(res, 503, { error: 'larkAppId_not_set' });
|
|
3921
|
-
let body;
|
|
3922
|
-
try {
|
|
3923
|
-
body = await readJsonBody(req);
|
|
3924
|
-
}
|
|
3925
|
-
catch {
|
|
3926
|
-
return jsonRes(res, 400, { ok: false, error: 'bad_json' });
|
|
3927
|
-
}
|
|
3928
|
-
const asList = (v) => Array.isArray(v) ? v.filter((x) => typeof x === 'string') : undefined;
|
|
3929
|
-
const r = await sandboxStore.updateBotSandboxPaths(cachedLarkAppId, {
|
|
3930
|
-
readWrite: asList(body.readWrite),
|
|
3931
|
-
readOnly: asList(body.readOnly),
|
|
3932
|
-
deny: asList(body.deny),
|
|
3933
|
-
});
|
|
3934
|
-
if (!r.ok)
|
|
3935
|
-
return jsonRes(res, 400, { ok: false, error: r.reason });
|
|
3936
|
-
jsonRes(res, 200, { ok: true, sandboxPaths: r.sandboxPaths ?? null });
|
|
3937
|
-
});
|
|
3938
|
-
// Per-bot read-isolation toggle. Body `{ enabled: boolean }`. When on, this bot's
|
|
3939
|
-
// CLI sessions run under macOS Seatbelt read-deny (siblings' creds/sessions/content
|
|
3940
|
-
// unreadable). The macOS counterpart of the file sandbox above.
|
|
3941
|
-
ipcRoute('PUT', '/api/bot-read-isolation', async (req, res) => {
|
|
3942
|
-
if (!cachedLarkAppId)
|
|
3943
|
-
return jsonRes(res, 503, { error: 'larkAppId_not_set' });
|
|
3944
|
-
let body;
|
|
3945
|
-
try {
|
|
3946
|
-
body = await readJsonBody(req);
|
|
3947
|
-
}
|
|
3948
|
-
catch {
|
|
3949
|
-
return jsonRes(res, 400, { ok: false, error: 'bad_json' });
|
|
3950
|
-
}
|
|
3951
|
-
const enable = body.enabled === true;
|
|
3952
|
-
// The worker FAIL-CLOSES (refuses to start the session) for a configured
|
|
3953
|
-
// readIsolation that can't be enforced: non-darwin, an adapter without
|
|
3954
|
-
// supportsReadIsolation, or a wrapperCli gateway. Reject enabling it in exactly
|
|
3955
|
-
// those cases so the toggle can never brick the bot's next session. (Turning it
|
|
3956
|
-
// OFF is always allowed — recovers a flag that became unenforceable.)
|
|
3957
|
-
if (enable && !readIsolationEnforceable(cachedLarkAppId)) {
|
|
3958
|
-
return jsonRes(res, 400, { ok: false, error: 'read_isolation_unenforceable' });
|
|
3959
|
-
}
|
|
3960
|
-
const r = await sandboxStore.updateBotReadIsolation(cachedLarkAppId, enable);
|
|
3961
|
-
if (!r.ok)
|
|
3962
|
-
return jsonRes(res, 400, { ok: false, error: r.reason });
|
|
3963
|
-
// Read isolation only takes effect at COLD spawn (provisionIsolatedBotHome +
|
|
3964
|
-
// Seatbelt wrapper run then). Suspend this bot's active sessions so the next
|
|
3965
|
-
// message cold-restarts under the new state — otherwise close+resume would keep
|
|
3966
|
-
// running the old, un-provisioned state and the toggle would silently no-op.
|
|
3967
|
-
const suspendedSessions = await suspendActiveSessionsForBot(cachedLarkAppId);
|
|
3968
|
-
jsonRes(res, 200, { ok: true, readIsolation: r.readIsolation, suspendedSessions });
|
|
3969
|
-
});
|
|
3970
|
-
// Per-bot session backend override (pty | tmux | herdr | zellij | zmx), or clear it
|
|
3971
|
-
// ('' / 'auto' / null → follow the daemon default). next-session 生效:running
|
|
3972
|
-
// sessions keep their spawn-time backend (Session.backendType stamp), only new
|
|
3973
|
-
// spawns read the new value — so switching here can't strand live sessions.
|
|
3974
|
-
ipcRoute('PUT', '/api/bot-backend-type', async (req, res) => {
|
|
3975
|
-
if (!cachedLarkAppId)
|
|
3976
|
-
return jsonRes(res, 503, { error: 'larkAppId_not_set' });
|
|
3977
|
-
let body;
|
|
3978
|
-
try {
|
|
3979
|
-
body = await readJsonBody(req);
|
|
3980
|
-
}
|
|
3981
|
-
catch {
|
|
3982
|
-
return jsonRes(res, 400, { ok: false, error: 'bad_json' });
|
|
3983
|
-
}
|
|
3984
|
-
const raw = body.backendType;
|
|
3985
|
-
let next;
|
|
3986
|
-
if (raw == null || raw === '' || raw === 'auto')
|
|
3987
|
-
next = null;
|
|
3988
|
-
else if (backendTypeStore.isEditableBackendType(raw))
|
|
3989
|
-
next = raw;
|
|
3990
|
-
else
|
|
3991
|
-
return jsonRes(res, 400, { ok: false, error: 'invalid_backendType' });
|
|
3992
|
-
const effectiveBackendType = next ?? config.daemon.backendType;
|
|
3993
|
-
const availability = await ensureBackendAvailable(effectiveBackendType);
|
|
3994
|
-
if (!availability.ok) {
|
|
3995
|
-
return jsonRes(res, 409, {
|
|
3996
|
-
ok: false,
|
|
3997
|
-
error: 'backend_unavailable',
|
|
3998
|
-
backendType: effectiveBackendType,
|
|
3999
|
-
reason: availability.reason,
|
|
4000
|
-
manualCommand: availability.manualCommand,
|
|
4001
|
-
});
|
|
4002
|
-
}
|
|
4003
|
-
const r = await backendTypeStore.updateBotBackendType(cachedLarkAppId, next);
|
|
4004
|
-
if (!r.ok)
|
|
4005
|
-
return jsonRes(res, 400, { ok: false, error: r.reason });
|
|
4006
|
-
jsonRes(res, 200, { ok: true, backendType: r.backendType, effectiveBackendType, version: availability.version });
|
|
4007
|
-
});
|
|
4008
|
-
// 实时切换 UI 语言(locale),无需重启 daemon。`botmux lang` / Dashboard 语言开关
|
|
4009
|
-
// 写盘后 POST 这个端点,让本 daemon 从磁盘重新读 locale 并热更新:
|
|
4010
|
-
// • 全局默认(~/.botmux/config.json 的 `lang`)→ setDefaultLocale(缺省回落 'zh');
|
|
4011
|
-
// • 本 bot 的 per-bot 覆盖(bots.json 的 `lang`)→ 同步进内存 bot.config.lang
|
|
4012
|
-
// (与 applyConfigField 同口径),让 `botmux lang --bot N` 跨进程写入也免重启。
|
|
4013
|
-
// 卡片都在 daemon 端按消息实时渲染(localeForBot),所以下一条消息/卡片立即生效。
|
|
4014
|
-
// 文件是单一事实源,本端点只是“立即重读”信号——不在此落盘(写入方已落盘)。
|
|
4015
|
-
ipcRoute('POST', '/api/locale/reload', async (_req, res) => {
|
|
4016
|
-
const globalLang = readGlobalConfig().lang;
|
|
4017
|
-
const resolvedDefault = isLocale(globalLang) ? globalLang : 'zh';
|
|
4018
|
-
setDefaultLocale(resolvedDefault);
|
|
4019
|
-
let botLang = null;
|
|
4020
|
-
if (cachedLarkAppId) {
|
|
4021
|
-
try {
|
|
4022
|
-
const raw = await readRawConfig(requireConfigPath());
|
|
4023
|
-
const idx = findEntryIndex(raw, cachedLarkAppId);
|
|
4024
|
-
const entryLang = idx >= 0 ? raw[idx]?.lang : undefined;
|
|
4025
|
-
botLang = isLocale(entryLang) ? entryLang : null;
|
|
4026
|
-
getBot(cachedLarkAppId).config.lang = botLang ?? undefined;
|
|
4027
|
-
}
|
|
4028
|
-
catch { /* bot 未注册 / 读盘失败:全局已应用,per-bot 维持原值 */ }
|
|
4029
|
-
}
|
|
4030
|
-
// Push the resolved locale to this bot's live workers too. Cards render on the
|
|
4031
|
-
// daemon (already switched above), but a few user-facing strings originate in
|
|
4032
|
-
// the worker process (submit notices, CoCo adopt notes) — without this they'd
|
|
4033
|
-
// stay in the spawn-time language until the session restarts.
|
|
4034
|
-
const workerLocale = botLang ?? resolvedDefault;
|
|
4035
|
-
const reg = getActiveSessionsRegistry();
|
|
4036
|
-
if (cachedLarkAppId && reg) {
|
|
4037
|
-
for (const ds of reg.values()) {
|
|
4038
|
-
if (ds.larkAppId !== cachedLarkAppId || !ds.worker || ds.worker.killed)
|
|
4039
|
-
continue;
|
|
4040
|
-
try {
|
|
4041
|
-
ds.worker.send({ type: 'set_locale', locale: workerLocale });
|
|
4042
|
-
}
|
|
4043
|
-
catch { /* worker gone */ }
|
|
4044
|
-
}
|
|
4045
|
-
}
|
|
4046
|
-
jsonRes(res, 200, { ok: true, defaultLocale: resolvedDefault, botLang });
|
|
4047
|
-
});
|
|
4048
|
-
// Hot-reload the current daemon's per-bot config from bots.json after another
|
|
4049
|
-
// process edits the shared config file. Keep the live Lark client / resolved
|
|
4050
|
-
// allowlist intact; VC listener routing only needs the vcMeetingAgent block.
|
|
4051
|
-
ipcRoute('POST', '/api/bot-config/reload', async (_req, res) => {
|
|
4052
|
-
if (!cachedLarkAppId)
|
|
4053
|
-
return jsonRes(res, 503, { ok: false, error: 'larkAppId_not_set' });
|
|
4054
|
-
try {
|
|
4055
|
-
const latest = loadBotConfigs().find(bot => bot.larkAppId === cachedLarkAppId);
|
|
4056
|
-
if (!latest)
|
|
4057
|
-
return jsonRes(res, 404, { ok: false, error: 'bot_not_in_config' });
|
|
4058
|
-
getBot(cachedLarkAppId).config.vcMeetingAgent = latest.vcMeetingAgent;
|
|
4059
|
-
jsonRes(res, 200, { ok: true, larkAppId: cachedLarkAppId, vcMeetingAgentEnabled: latest.vcMeetingAgent?.enabled === true });
|
|
4060
|
-
}
|
|
4061
|
-
catch (err) {
|
|
4062
|
-
jsonRes(res, 500, { ok: false, error: err?.message ?? String(err) });
|
|
4063
|
-
}
|
|
4064
|
-
});
|
|
4065
|
-
ipcRoute('PUT', '/api/bot-default-oncall', async (req, res) => {
|
|
4066
|
-
if (!cachedLarkAppId)
|
|
4067
|
-
return jsonRes(res, 503, { error: 'larkAppId_not_set' });
|
|
4068
|
-
let body;
|
|
4069
|
-
try {
|
|
4070
|
-
body = await readJsonBody(req);
|
|
4071
|
-
}
|
|
4072
|
-
catch {
|
|
4073
|
-
return jsonRes(res, 400, { ok: false, error: 'bad_json' });
|
|
4074
|
-
}
|
|
4075
|
-
const enabled = body.enabled === true;
|
|
4076
|
-
const workingDir = typeof body.workingDir === 'string' ? body.workingDir.trim() : '';
|
|
4077
|
-
// Validate workingDir when enabling. Allow blank workingDir only when
|
|
4078
|
-
// disabling — the on-disk record keeps the last value so the UI can
|
|
4079
|
-
// round-trip after a disable.
|
|
4080
|
-
let resolvedPath = '';
|
|
4081
|
-
if (enabled) {
|
|
4082
|
-
if (!workingDir)
|
|
4083
|
-
return jsonRes(res, 400, { ok: false, error: 'workingDir_required' });
|
|
4084
|
-
const v = validateWorkingDir(workingDir);
|
|
4085
|
-
if (!v.ok)
|
|
4086
|
-
return jsonRes(res, 400, { ok: false, error: v.error });
|
|
4087
|
-
resolvedPath = v.resolvedPath;
|
|
4088
|
-
}
|
|
4089
|
-
const r = await oncallStore.updateBotDefaultOncall(cachedLarkAppId, { enabled, workingDir });
|
|
4090
|
-
if (!r.ok)
|
|
4091
|
-
return jsonRes(res, 400, r);
|
|
4092
|
-
jsonRes(res, 200, { ok: true, defaultOncall: r.defaultOncall, resolvedPath: resolvedPath || undefined });
|
|
4093
|
-
});
|
|
4094
|
-
// Per-bot「默认工作目录模式」三选一(dashboard 单选;两个底层字段互斥):
|
|
4095
|
-
// • off → 清 defaultWorkingDir + 关 defaultOncall(新会话弹「选仓库」卡)
|
|
4096
|
-
// • default → 写 defaultWorkingDir + 关 defaultOncall(钉目录、跳过选仓库、不改权限)
|
|
4097
|
-
// • oncall → 开 defaultOncall(+dir) + 清 defaultWorkingDir(新群自动绑+开放对话;
|
|
4098
|
-
// 该目录经 resolveBotDefaultWorkingDir 的 layer-4 兜底覆盖该 bot 所有会话)
|
|
4099
|
-
// 两字段在 oncallStore.setWorkingDirMode 的**同一个 rmwBotEntry 锁内**一次性原子写盘 +
|
|
4100
|
-
// 同步内存:否则两个并发请求分别加锁写各自字段会交错,最终留下 defaultOncall.enabled 与
|
|
4101
|
-
// defaultWorkingDir 同时存在的不一致态(GET/前端按 enabled 显示 oncall,但 runtime 的
|
|
4102
|
-
// effectiveDefaultWorkingDir 优先用 defaultWorkingDir → UI 与实际目录背离;PR #311 Codex 评审)。
|
|
4103
|
-
// next-session 生效(运行中会话需 /restart)。
|
|
4104
|
-
ipcRoute('PUT', '/api/bot-working-dir-mode', async (req, res) => {
|
|
4105
|
-
if (!cachedLarkAppId)
|
|
4106
|
-
return jsonRes(res, 503, { error: 'larkAppId_not_set' });
|
|
4107
|
-
let body;
|
|
4108
|
-
try {
|
|
4109
|
-
body = await readJsonBody(req);
|
|
4110
|
-
}
|
|
4111
|
-
catch {
|
|
4112
|
-
return jsonRes(res, 400, { ok: false, error: 'bad_json' });
|
|
4113
|
-
}
|
|
4114
|
-
const mode = body.mode;
|
|
4115
|
-
if (mode !== 'off' && mode !== 'default' && mode !== 'oncall') {
|
|
4116
|
-
return jsonRes(res, 400, { ok: false, error: 'invalid_mode' });
|
|
4117
|
-
}
|
|
4118
|
-
const workingDir = typeof body.workingDir === 'string' ? body.workingDir.trim() : '';
|
|
4119
|
-
// 「仅默认目录」模式下的「自动创建 worktree」开关;其余模式 setWorkingDirMode 会强制清掉。
|
|
4120
|
-
const autoWorktree = body.autoWorktree === true;
|
|
4121
|
-
// 非「关闭」模式必须给一个真实存在的目录。
|
|
4122
|
-
let resolvedPath = '';
|
|
4123
|
-
if (mode !== 'off') {
|
|
4124
|
-
if (!workingDir)
|
|
4125
|
-
return jsonRes(res, 400, { ok: false, error: 'workingDir_required' });
|
|
4126
|
-
const v = validateWorkingDir(workingDir);
|
|
4127
|
-
if (!v.ok)
|
|
4128
|
-
return jsonRes(res, 400, { ok: false, error: v.error });
|
|
4129
|
-
resolvedPath = v.resolvedPath;
|
|
4130
|
-
}
|
|
4131
|
-
const r = await oncallStore.setWorkingDirMode(cachedLarkAppId, mode, workingDir, autoWorktree);
|
|
4132
|
-
if (!r.ok)
|
|
4133
|
-
return jsonRes(res, 400, r);
|
|
4134
|
-
return jsonRes(res, 200, {
|
|
4135
|
-
ok: true, mode,
|
|
4136
|
-
defaultWorkingDir: r.defaultWorkingDir,
|
|
4137
|
-
defaultWorkingDirAutoWorktree: r.defaultWorkingDirAutoWorktree,
|
|
4138
|
-
defaultOncall: r.defaultOncall,
|
|
4139
|
-
resolvedPath: resolvedPath || undefined,
|
|
4140
|
-
});
|
|
4141
|
-
});
|
|
4142
|
-
// Create a brand-new chat with this bot as creator/owner and `larkAppIds` as
|
|
4143
|
-
// initial bot members. The dashboard's public route picks any online daemon
|
|
4144
|
-
// to act as creator, then forwards here.
|
|
4145
|
-
ipcRoute('POST', '/api/groups/create', async (req, res) => {
|
|
4146
|
-
if (!cachedLarkAppId)
|
|
4147
|
-
return jsonRes(res, 503, { error: 'larkAppId_not_set' });
|
|
4148
|
-
let body;
|
|
4149
|
-
try {
|
|
4150
|
-
body = await readJsonBody(req);
|
|
4151
|
-
}
|
|
4152
|
-
catch {
|
|
4153
|
-
return jsonRes(res, 400, { error: 'bad_json' });
|
|
4154
|
-
}
|
|
4155
|
-
const name = typeof body.name === 'string' && body.name.trim() ? body.name.trim() : undefined;
|
|
4156
|
-
if (!Array.isArray(body.larkAppIds) || !body.larkAppIds.every(x => typeof x === 'string')) {
|
|
4157
|
-
return jsonRes(res, 400, { error: 'larkAppIds_required' });
|
|
4158
|
-
}
|
|
4159
|
-
// userOpenIds, transferOwnerTo, notifyOwnerOpenId are optional; pre-validated
|
|
4160
|
-
// upstream by the dashboard route. All open_ids MUST be in the calling bot's
|
|
4161
|
-
// app scope (caller is responsible — Lark open_ids are app-scoped, see
|
|
4162
|
-
// dashboard/operator-selector.ts).
|
|
4163
|
-
const userIds = Array.isArray(body.userOpenIds) && body.userOpenIds.every(x => typeof x === 'string')
|
|
4164
|
-
? body.userOpenIds
|
|
4165
|
-
: [];
|
|
4166
|
-
// Owner union_ids (tenant-stable) to pull bot owners into a federated group.
|
|
4167
|
-
const ownerUnionIds = Array.isArray(body.ownerUnionIds) && body.ownerUnionIds.every(x => typeof x === 'string')
|
|
4168
|
-
? body.ownerUnionIds
|
|
4169
|
-
: [];
|
|
4170
|
-
const transferOwnerUnionId = typeof body.transferOwnerUnionId === 'string' && body.transferOwnerUnionId.trim()
|
|
4171
|
-
? body.transferOwnerUnionId.trim()
|
|
4172
|
-
: null;
|
|
4173
|
-
if (body.transferOwnerUnionId !== undefined
|
|
4174
|
-
&& (!transferOwnerUnionId || !transferOwnerUnionId.startsWith('on_') || !ownerUnionIds.includes(transferOwnerUnionId))) {
|
|
4175
|
-
return jsonRes(res, 400, { ok: false, error: 'invalid_transfer_owner_union_id' });
|
|
4176
|
-
}
|
|
4177
|
-
const transferTo = typeof body.transferOwnerTo === 'string' && body.transferOwnerTo.trim()
|
|
4178
|
-
? body.transferOwnerTo.trim()
|
|
4179
|
-
: null;
|
|
4180
|
-
const notifyTo = typeof body.notifyOwnerOpenId === 'string' && body.notifyOwnerOpenId.trim()
|
|
4181
|
-
? body.notifyOwnerOpenId.trim()
|
|
4182
|
-
: null;
|
|
4183
|
-
const roleProfileId = typeof body.roleProfileId === 'string' && body.roleProfileId.trim()
|
|
4184
|
-
? body.roleProfileId.trim()
|
|
4185
|
-
: null;
|
|
4186
|
-
if (roleProfileId && !isValidRoleProfileId(roleProfileId)) {
|
|
4187
|
-
return jsonRes(res, 400, { ok: false, error: 'invalid_role_profile_id' });
|
|
4188
|
-
}
|
|
4189
|
-
const bindWorkingDir = typeof body.bindWorkingDir === 'string' ? body.bindWorkingDir.trim() : '';
|
|
4190
|
-
let bindResolvedPath;
|
|
4191
|
-
if (bindWorkingDir) {
|
|
4192
|
-
const v = validateWorkingDir(bindWorkingDir);
|
|
4193
|
-
if (!v.ok)
|
|
4194
|
-
return jsonRes(res, 400, { ok: false, error: v.error });
|
|
4195
|
-
bindResolvedPath = v.resolvedPath;
|
|
4196
|
-
}
|
|
4197
|
-
try {
|
|
4198
|
-
const r = await createGroupWithBots({
|
|
4199
|
-
creatorLarkAppId: cachedLarkAppId,
|
|
4200
|
-
larkAppIds: body.larkAppIds,
|
|
4201
|
-
name,
|
|
4202
|
-
userOpenIds: userIds,
|
|
4203
|
-
ownerUnionIds,
|
|
4204
|
-
transferOwnerUnionId: transferOwnerUnionId ?? undefined,
|
|
4205
|
-
transferOwnerTo: transferTo ?? undefined,
|
|
4206
|
-
notifyOwnerOpenId: notifyTo ?? undefined,
|
|
4207
|
-
bindWorkingDir: bindWorkingDir || undefined,
|
|
4208
|
-
roleProfileId: roleProfileId ?? undefined,
|
|
4209
|
-
});
|
|
4210
|
-
jsonRes(res, 200, bindResolvedPath ? { ...r, bindResolvedPath } : r);
|
|
4211
|
-
}
|
|
4212
|
-
catch (e) {
|
|
4213
|
-
jsonRes(res, 502, { ok: false, error: String(e.message ?? e) });
|
|
4214
|
-
}
|
|
4215
|
-
});
|
|
4216
|
-
// Complete a deferred team-group owner transfer after another deployment has
|
|
4217
|
-
// added the operator to the chat. The caller sends union_id so no app-scoped
|
|
4218
|
-
// open_id crosses the dashboard/daemon or federation boundary.
|
|
4219
|
-
ipcRoute('POST', '/api/groups/transfer-owner', async (req, res) => {
|
|
4220
|
-
if (!cachedLarkAppId)
|
|
4221
|
-
return jsonRes(res, 503, { error: 'larkAppId_not_set' });
|
|
4222
|
-
let body;
|
|
4223
|
-
try {
|
|
4224
|
-
body = await readJsonBody(req);
|
|
4225
|
-
}
|
|
4226
|
-
catch {
|
|
4227
|
-
return jsonRes(res, 400, { ok: false, error: 'bad_json' });
|
|
4228
|
-
}
|
|
4229
|
-
const chatId = typeof body.chatId === 'string' ? body.chatId.trim() : '';
|
|
4230
|
-
const ownerUnionId = typeof body.ownerUnionId === 'string' ? body.ownerUnionId.trim() : '';
|
|
4231
|
-
if (!chatId.startsWith('oc_') || !ownerUnionId.startsWith('on_')) {
|
|
4232
|
-
return jsonRes(res, 400, { ok: false, error: 'invalid_owner_transfer' });
|
|
4233
|
-
}
|
|
4234
|
-
const transferred = await transferGroupOwner({
|
|
4235
|
-
creatorLarkAppId: cachedLarkAppId,
|
|
4236
|
-
chatId,
|
|
4237
|
-
ownerId: ownerUnionId,
|
|
4238
|
-
ownerIdType: 'union_id',
|
|
4239
|
-
});
|
|
4240
|
-
let notifyMessageId = null;
|
|
4241
|
-
let notifyError = null;
|
|
4242
|
-
if (transferred.ownerTransferredTo) {
|
|
4243
|
-
try {
|
|
4244
|
-
// Feishu accepts union_id in an @ tag; keeping it stable avoids a second
|
|
4245
|
-
// app-scope lookup after the owner was added by another deployment.
|
|
4246
|
-
notifyMessageId = await sendMessage(cachedLarkAppId, chatId, `<at user_id="${ownerUnionId}"></at>`, 'text');
|
|
4247
|
-
}
|
|
4248
|
-
catch (e) {
|
|
4249
|
-
notifyError = e?.message ?? String(e);
|
|
4250
|
-
}
|
|
4251
|
-
}
|
|
4252
|
-
return jsonRes(res, 200, {
|
|
4253
|
-
ok: true,
|
|
4254
|
-
...transferred,
|
|
4255
|
-
notifyMessageId,
|
|
4256
|
-
notifyError,
|
|
4257
|
-
});
|
|
4258
|
-
});
|
|
4259
|
-
// ─── SSE event stream ──────────────────────────────────────────────────────
|
|
4260
|
-
ipcRoute('GET', '/api/events', (_req, res) => {
|
|
4261
|
-
res.writeHead(200, {
|
|
4262
|
-
'content-type': 'text/event-stream',
|
|
4263
|
-
'cache-control': 'no-cache, no-transform',
|
|
4264
|
-
'connection': 'keep-alive',
|
|
4265
|
-
});
|
|
4266
|
-
// Initial flush so the client sees the connection alive immediately.
|
|
4267
|
-
res.write('retry: 5000\n\n');
|
|
4268
|
-
// Subscribe BEFORE snapshotting so no event published in the gap is missed.
|
|
4269
|
-
const off = dashboardEventBus.subscribe(ev => {
|
|
4270
|
-
res.write(`event: ${ev.type}\ndata: ${JSON.stringify(ev.body)}\n\n`);
|
|
4271
|
-
});
|
|
4272
|
-
// Replay the current active sessions as `session.spawned` right after
|
|
4273
|
-
// subscribing. `DashboardEventBus` has no buffer/replay, and the daemon
|
|
4274
|
-
// publishes its discovery descriptor BEFORE restoreActiveSessions() runs
|
|
4275
|
-
// (daemon.ts) — so a dashboard that hydrates (GET /api/sessions) during the
|
|
4276
|
-
// descriptor→restore window gets an EMPTY snapshot, and any restore-time
|
|
4277
|
-
// `announceSessionRow()` that fires before THIS subscription is established is
|
|
4278
|
-
// dropped. Without this replay the aggregator would then have neither a
|
|
4279
|
-
// snapshot row nor a spawned row, and later session.update/close patches would
|
|
4280
|
-
// be discarded as unknown-row. Replaying here makes SSE attach deterministic:
|
|
4281
|
-
// a row registered before subscribe arrives via this snapshot; one registered
|
|
4282
|
-
// after arrives via the live subscription above. Idempotent — both the
|
|
4283
|
-
// aggregator and the browser store upsert by sessionId, so any row also
|
|
4284
|
-
// delivered live just refreshes the same entry.
|
|
4285
|
-
try {
|
|
4286
|
-
const activeIds = new Set();
|
|
4287
|
-
for (const ds of listActiveSessions()) {
|
|
4288
|
-
activeIds.add(ds.session.sessionId);
|
|
4289
|
-
res.write(`event: session.spawned\ndata: ${JSON.stringify({ session: composeRowFromActive(ds) })}\n\n`);
|
|
4290
|
-
}
|
|
4291
|
-
// Persisted active rows may be intentionally absent from the runtime Map
|
|
4292
|
-
// after an inconclusive exact-backend teardown. Replay them as dormant
|
|
4293
|
-
// upserts so SSE reconnects retain the same truthful state as GET
|
|
4294
|
-
// /api/sessions and never synthesize a closed row.
|
|
4295
|
-
for (const s of sessionStore.listSessions()) {
|
|
4296
|
-
if (s.status !== 'active' || activeIds.has(s.sessionId))
|
|
4297
|
-
continue;
|
|
4298
|
-
res.write(`event: session.spawned\ndata: ${JSON.stringify({ session: composeRowFromPersistedActive(s) })}\n\n`);
|
|
4299
|
-
}
|
|
4300
|
-
// Also replay sessions CLOSED during this run as `session.spawned` carrying a
|
|
4301
|
-
// closed row. The active-only replay above can't cover a restore-time zombie:
|
|
4302
|
-
// restoreActiveSessions registers it, announces it, then immediately probes it
|
|
4303
|
-
// 'missing' and closeSession()s it (evicting it from the active Map) — all
|
|
4304
|
-
// before a racing dashboard's SSE subscription exists. By connect time it is
|
|
4305
|
-
// neither in the active Map nor was it a closed row at the dashboard's early
|
|
4306
|
-
// (pre-restore) hydrate, so without this it stays invisible (or, if the
|
|
4307
|
-
// dashboard cached it active from before the restart, lingers as a stale
|
|
4308
|
-
// active row — hydrateSessions only upserts, never deletes absent rows).
|
|
4309
|
-
// Bounded to closedAt >= PROCESS_START_MS so we replay only this run's
|
|
4310
|
-
// closures (the full closed history is already served by GET /api/sessions
|
|
4311
|
-
// on hydrate). `session.spawned` (not session.update) because the row may be
|
|
4312
|
-
// unknown to the client — both consumers upsert by sessionId, and the closed
|
|
4313
|
-
// row's status:'closed' overwrites any stale active entry.
|
|
4314
|
-
for (const s of sessionStore.listSessions()) {
|
|
4315
|
-
if (s.status !== 'closed' || activeIds.has(s.sessionId))
|
|
4316
|
-
continue;
|
|
4317
|
-
const closedMs = s.closedAt ? Date.parse(s.closedAt) : NaN;
|
|
4318
|
-
if (!Number.isFinite(closedMs) || closedMs < PROCESS_START_MS)
|
|
4319
|
-
continue;
|
|
4320
|
-
res.write(`event: session.spawned\ndata: ${JSON.stringify({ session: composeRowFromClosed(s) })}\n\n`);
|
|
4321
|
-
}
|
|
4322
|
-
}
|
|
4323
|
-
catch (err) {
|
|
4324
|
-
logger.warn(`[dashboard-ipc] /api/events snapshot replay failed: ${err}`);
|
|
4325
|
-
}
|
|
4326
|
-
const hb = setInterval(() => {
|
|
4327
|
-
res.write(`event: heartbeat\ndata: ${JSON.stringify({ ts: Date.now() })}\n\n`);
|
|
4328
|
-
}, 15_000);
|
|
4329
|
-
res.on('close', () => { off(); clearInterval(hb); });
|
|
4330
|
-
});
|
|
4331
|
-
export function startIpcServer(opts) {
|
|
4332
|
-
let boundPort = opts.port;
|
|
4333
|
-
const server = createServer(async (req, res) => {
|
|
4334
|
-
try {
|
|
4335
|
-
const url = new URL(req.url ?? '/', `http://${req.headers.host ?? 'localhost'}`);
|
|
4336
|
-
const method = req.method ?? 'GET';
|
|
4337
|
-
const coreOnlyPublic = opts.coreOnlyPublicRoutes === true && routeIsCoreOnlyPublic(method, url.pathname);
|
|
4338
|
-
const publicRoute = routeHasPublicAccess(method, url.pathname) || coreOnlyPublic;
|
|
4339
|
-
// Readiness barrier (codex P1): the core-only public control routes
|
|
4340
|
-
// (trigger / trigger-result / insight) must NOT enter their handlers until
|
|
4341
|
-
// restore completes — a trigger during 'starting' races durable restore.
|
|
4342
|
-
// Gate them at the server level so it doesn't depend on the caller probing
|
|
4343
|
-
// /healthz first. /healthz itself reports 503 via its own handler.
|
|
4344
|
-
if (coreOnlyPublic && coreOnlyNotReady()) {
|
|
4345
|
-
return jsonRes(res, 503, { ok: false, status: 'starting', error: 'core-only service is still restoring; retry after /healthz returns 200' });
|
|
4346
|
-
}
|
|
4347
|
-
const capabilityRoute = routeHasNarrowUntrustedAuth(method, url.pathname);
|
|
4348
|
-
if (opts.authRequired && !publicRoute) {
|
|
4349
|
-
const secret = ipcAuthSecret();
|
|
4350
|
-
const auth = secret
|
|
4351
|
-
? trustedHostAuthorized(req, url.pathname, boundPort, secret)
|
|
4352
|
-
: { ok: false, reason: 'secret_unavailable' };
|
|
4353
|
-
if (auth.ok) {
|
|
4354
|
-
trustedHostRequests.add(req);
|
|
4355
|
-
}
|
|
4356
|
-
else if (!capabilityRoute) {
|
|
4357
|
-
return jsonRes(res, 401, { ok: false, error: 'unauthorized', reason: auth.reason });
|
|
4358
|
-
}
|
|
4359
|
-
}
|
|
4360
|
-
for (const r of routes) {
|
|
4361
|
-
if (r.method !== req.method)
|
|
4362
|
-
continue;
|
|
4363
|
-
const m = r.pattern.exec(url.pathname);
|
|
4364
|
-
if (!m)
|
|
4365
|
-
continue;
|
|
4366
|
-
const params = {};
|
|
4367
|
-
r.keys.forEach((k, i) => { params[k] = decodeURIComponent(m[i + 1]); });
|
|
4368
|
-
await r.handler(req, res, params);
|
|
4369
|
-
return;
|
|
4370
|
-
}
|
|
4371
|
-
jsonRes(res, 404, { error: 'not_found', path: url.pathname });
|
|
4372
|
-
}
|
|
4373
|
-
catch (err) {
|
|
4374
|
-
logger.error('[dashboard-ipc] handler error', err);
|
|
4375
|
-
if (!res.headersSent)
|
|
4376
|
-
jsonRes(res, 500, { error: String(err) });
|
|
4377
|
-
}
|
|
4378
|
-
});
|
|
4379
|
-
// Probe upward on EADDRINUSE instead of a single fixed bind: a second botmux
|
|
4380
|
-
// instance resolving the same IPC port (BOTMUX_DAEMON_IPC_BASE_PORT + idx)
|
|
4381
|
-
// would otherwise reject and take the whole daemon down at startup (the caller
|
|
4382
|
-
// in daemon.ts awaits this unguarded). The daemon republishes the returned
|
|
4383
|
-
// (bound) port into its descriptor so the dashboard still discovers it.
|
|
4384
|
-
return listenWithProbe({
|
|
4385
|
-
server,
|
|
4386
|
-
port: opts.port,
|
|
4387
|
-
host: opts.host,
|
|
4388
|
-
maxProbe: opts.maxProbe,
|
|
4389
|
-
log: (m) => logger.warn(`[dashboard-ipc] ${m}`),
|
|
4390
|
-
}).then((port) => {
|
|
4391
|
-
boundPort = port;
|
|
4392
|
-
return {
|
|
4393
|
-
port,
|
|
4394
|
-
close: () => new Promise(r => server.close(() => r())),
|
|
4395
|
-
};
|
|
4396
|
-
});
|
|
4397
|
-
}
|
|
4398
|
-
//# sourceMappingURL=dashboard-ipc-server.js.map
|