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,4108 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Command handler — processes /slash commands from users.
|
|
3
|
-
* Extracted from daemon.ts for modularity.
|
|
4
|
-
*/
|
|
5
|
-
import { existsSync, readFileSync, statSync } from 'node:fs';
|
|
6
|
-
import { join, resolve, basename } from 'node:path';
|
|
7
|
-
import { config } from '../config.js';
|
|
8
|
-
import { buildTerminalUrl } from './terminal-url.js';
|
|
9
|
-
import { getBot, getAllBots, getBotOpenId, getOwnerOpenId, findOncallChat, effectiveDefaultWorkingDir } from '../bot-registry.js';
|
|
10
|
-
import { readGlobalConfig, repoPickerScanOptions } from '../global-config.js';
|
|
11
|
-
import * as sessionStore from '../services/session-store.js';
|
|
12
|
-
import * as scheduleStore from '../services/schedule-store.js';
|
|
13
|
-
import * as scheduler from './scheduler.js';
|
|
14
|
-
import { scanMultipleProjects, describeProjectDir } from '../services/project-scanner.js';
|
|
15
|
-
import { createRepoWorktree, pushWorktreeBranch } from '../services/git-worktree.js';
|
|
16
|
-
import { worktreeSlugFromContextAI } from '../services/worktree-slug-ai.js';
|
|
17
|
-
import { resolvePairedSpawnBackendType } from './persistent-backend.js';
|
|
18
|
-
import { buildRepoSelectCard, buildAdoptSelectCard, buildCodexAppThreadSelectCard, buildSlashListCard, getCliDisplayName, buildConfigCard, buildForkPanelCard, buildAdoptBlockedCard } from '../im/lark/card-builder.js';
|
|
19
|
-
import { handleDashboardCommand } from './dashboard-command/index.js';
|
|
20
|
-
import { createCliAdapterSync } from '../adapters/cli/registry.js';
|
|
21
|
-
import { resolveCliRuntime, runtimeInstallationKey } from '../adapters/cli/runtime.js';
|
|
22
|
-
import { deleteMessage, sendMessage, sendUserMessage, replyMessage, listChatBotMembers, resolveUserUnionId, getChatModeStrict, getMessageThreadId, UserTokenMissingError } from '../im/lark/client.js';
|
|
23
|
-
import { chatAppLink, threadAppLink, normalizeBrand } from '../im/lark/lark-hosts.js';
|
|
24
|
-
import { claimPairing } from '../services/pairing-store.js';
|
|
25
|
-
import { logger } from '../utils/logger.js';
|
|
26
|
-
import { scheduleTimeZone } from '../utils/timezone.js';
|
|
27
|
-
import { closeSession, killWorker, teardownAuthoritativePersistentBackingBeforeClose, suspendWorker, forkWorker, forkAdoptWorker, adoptSandboxBlocked, getCurrentCliVersion, postFreshStreamingCard, postPrivateSnapshotCard, resolvePrivateCardAudience, deliverEphemeralOrReply, deliverWritableTerminalCardTo, requestSessionRestart, isSessionTransferring } from './worker-pool.js';
|
|
28
|
-
import { expandHome, getSessionWorkingDir, getProjectScanDirs, rememberLastCliInput, buildNewTopicCliInput, ensureSessionWhiteboard, getAvailableBots, } from './session-manager.js';
|
|
29
|
-
import { markInitialUserTurnPending } from './initial-user-turn.js';
|
|
30
|
-
import { discoverSlashCommandsForAdapter, listMcpServerNames, supportsFilesystemCommandDiscovery } from './command-discovery.js';
|
|
31
|
-
import { validateWorkingDir } from './working-dir.js';
|
|
32
|
-
import { repinSessionWorkingDir } from './session-cwd.js';
|
|
33
|
-
import { validateAdoptTarget, adoptTargetKey, adoptTargetLabel } from './session-discovery.js';
|
|
34
|
-
import { validateZellijAdoptTarget } from './zellij-adopt-discovery.js';
|
|
35
|
-
import { listCodexAppThreads } from '../services/codex-app-threads.js';
|
|
36
|
-
import { generateAuthUrl, getTokenStatus, resolveUserToken, DOC_COMMENT_OAUTH_SCOPES } from '../utils/user-token.js';
|
|
37
|
-
import { DocSubscriptionPermissionError, listDocComments, resolveDocFile, subscribeDocFile, unsubscribeDocFile } from '../im/lark/doc-comment.js';
|
|
38
|
-
import { parseDocWatchCommand } from './doc-watch-command.js';
|
|
39
|
-
import { parseVcMeetingPrepareCommand } from './vc-meeting-prepare-command.js';
|
|
40
|
-
import { latestDocCommentPollCursor } from './doc-comment-poller.js';
|
|
41
|
-
import { putDocSubscription, removeDocSubscription, listDocSubscriptionsForSession, listAllDocSubscriptions, getDocSubscription, } from '../services/doc-subs-store.js';
|
|
42
|
-
import { findVcMeetingPreparationByChat, getVcMeetingPreparation, listVcMeetingPreparations, putVcMeetingPreparation, removeVcMeetingPreparation, removeVcMeetingPreparationsByChat, } from '../services/vc-meeting-preparations-store.js';
|
|
43
|
-
import { bindOncall, unbindOncall, getOncallStatus } from '../services/oncall-store.js';
|
|
44
|
-
import { CONFIG_FIELDS, findConfigField, settableFieldKeys, parseBooleanValue, applyConfigField, setBotAllowedUsers, getConfigSnapshot, getConfigCardData, coerceConfigValue, } from '../services/bot-config-store.js';
|
|
45
|
-
import { resolveCliId, findInvalidAllowedUserEntries } from '../setup/bot-config-editor.js';
|
|
46
|
-
import { buildClosedSessionCard } from './closed-session-card.js';
|
|
47
|
-
import { ttadkConfigModelChoices } from '../setup/cli-selection.js';
|
|
48
|
-
import { publishAttentionPatch, publishClosedSessionPatch, announcePendingRepoSession } from './session-activity.js';
|
|
49
|
-
import { setCardMode } from '../services/card-mode-store.js';
|
|
50
|
-
import { canOperate } from '../im/lark/event-dispatcher.js';
|
|
51
|
-
import { buildSafeInsightReport } from '../services/insight/report.js';
|
|
52
|
-
import { invalidWorkingDirs } from '../utils/working-dir.js';
|
|
53
|
-
import { writeRoleFile, deleteRoleFile, resolveRole, resolveRoleFile, resolveTeamRoleFile, writeTeamRoleFile, deleteTeamRoleFile, MAX_ROLE_BYTES } from './role-resolver.js';
|
|
54
|
-
import { getBotCapability, setBotCapability, clearBotCapability } from '../services/bot-profile-store.js';
|
|
55
|
-
import { deleteRoleProfileEntry, deleteRoleProfileIfEmpty, isValidRoleProfileId, listRoleProfileEntries, listRoleProfiles, MAX_ROLE_PROFILE_ENTRY_BYTES, readRoleProfileEntry, writeRoleProfileEntry, } from '../services/role-profile-store.js';
|
|
56
|
-
import { sessionKey, sessionAnchorId, markRepoCardConsumed, claimCurrentRepoCard } from './types.js';
|
|
57
|
-
import { t, localeForBot } from '../i18n/index.js';
|
|
58
|
-
import { runSkillsImCommand } from './skills/im-command.js';
|
|
59
|
-
import { fetchDaemonIpc } from './daemon-ipc-auth.js';
|
|
60
|
-
import { updateSessionTitle } from './session-title.js';
|
|
61
|
-
import { requestAgentSessionRename } from './session-rename.js';
|
|
62
|
-
import { configuredRuntimeDisplayName, sessionConfiguredRuntimeDisplayName, } from './cli-runtime-display.js';
|
|
63
|
-
// ─── Exported constants ──────────────────────────────────────────────────────
|
|
64
|
-
// DAEMON_COMMANDS / PASSTHROUGH_COMMANDS / normalizePassthroughCommand now live
|
|
65
|
-
// in the leaf ./passthrough-commands.js so the config store can share the
|
|
66
|
-
// normalization without a circular import; imported for internal use and
|
|
67
|
-
// re-exported to keep callers (daemon.ts, tests) importing from command-handler
|
|
68
|
-
// unchanged.
|
|
69
|
-
import { DAEMON_COMMANDS, PASSTHROUGH_COMMANDS, normalizePassthroughCommand, parseCustomPassthroughInput } from './passthrough-commands.js';
|
|
70
|
-
export { DAEMON_COMMANDS, PASSTHROUGH_COMMANDS };
|
|
71
|
-
/**
|
|
72
|
-
* Daemon commands that act on the chat itself rather than opening a
|
|
73
|
-
* conversation. `/group` (`/g`) just creates a Lark group and replies once —
|
|
74
|
-
* no follow-up turns, no CLI worker. The new-topic spawn path normally
|
|
75
|
-
* pre-creates a sessionStore record so a command can attach state and keep
|
|
76
|
-
* card buttons routable, but for these that record is a phantom conversation
|
|
77
|
-
* that pollutes the dashboard's session list. Handle them without a session.
|
|
78
|
-
*/
|
|
79
|
-
export const SESSIONLESS_DAEMON_COMMANDS = new Set(['/group', '/g', '/list-slash-command', '/slash', '/botconfig', '/dashboard', '/skills', '/vc-auth', '/watch-comment', '/issue']);
|
|
80
|
-
const SLASH_GROUP_NAME_MAX_UTF16_LENGTH = 50;
|
|
81
|
-
/** Apply the machine-wide prefix used only by `/group` and `/g`, then keep the
|
|
82
|
-
* existing Lark headroom. The legacy limit is measured in UTF-16 code units;
|
|
83
|
-
* iterating by code point keeps that limit without slicing an emoji's
|
|
84
|
-
* surrogate pair. */
|
|
85
|
-
export function formatSlashGroupName(name, prefix = '') {
|
|
86
|
-
const prefixed = prefix && !name.startsWith(prefix) ? `${prefix}${name}` : name;
|
|
87
|
-
if (prefixed.length <= SLASH_GROUP_NAME_MAX_UTF16_LENGTH)
|
|
88
|
-
return prefixed;
|
|
89
|
-
let truncated = '';
|
|
90
|
-
for (const character of prefixed) {
|
|
91
|
-
if (truncated.length + character.length > SLASH_GROUP_NAME_MAX_UTF16_LENGTH)
|
|
92
|
-
break;
|
|
93
|
-
truncated += character;
|
|
94
|
-
}
|
|
95
|
-
return `${truncated}…`;
|
|
96
|
-
}
|
|
97
|
-
/**
|
|
98
|
-
* Daemon commands that operate on an ALREADY-EXISTING session and must never
|
|
99
|
-
* pre-create one. With no real session to operate on, the daemon routes must skip their generic
|
|
100
|
-
* "createSession + activeSessions.set(worker:null)" pre-create block and let
|
|
101
|
-
* handleCommand's `!ds` branch reply no_active_session. Without this, one of these commands
|
|
102
|
-
* in a brand-new topic (or a thread with no session) would spawn a phantom
|
|
103
|
-
* worker:null session just to handle it, polluting the dashboard. (Same class
|
|
104
|
-
* of fix as the `/card` / `/term` special cases in daemon.ts.)
|
|
105
|
-
*/
|
|
106
|
-
export const EXISTING_SESSION_ONLY_DAEMON_COMMANDS = new Set(['/rename', '/fork', '/forklist']);
|
|
107
|
-
export function resolveAdapterDefaultPassthroughCommands(larkAppId) {
|
|
108
|
-
if (!larkAppId)
|
|
109
|
-
return [];
|
|
110
|
-
try {
|
|
111
|
-
const bot = getBot(larkAppId);
|
|
112
|
-
const adapter = createCliAdapterSync(bot.config.cliId, bot.config.cliPathOverride);
|
|
113
|
-
const normalized = (adapter.defaultPassthroughCommands ?? [])
|
|
114
|
-
.map(normalizePassthroughCommand)
|
|
115
|
-
.filter((c) => !!c);
|
|
116
|
-
return [...new Set(normalized)];
|
|
117
|
-
}
|
|
118
|
-
catch {
|
|
119
|
-
return [];
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
/**
|
|
123
|
-
* Effective passthrough set for a bot: the fixed {@link PASSTHROUGH_COMMANDS}
|
|
124
|
-
* plus adapter-scoped defaults and the bot's `customPassthroughCommands`
|
|
125
|
-
* (bots.json). Entries that would shadow a botmux daemon command are dropped —
|
|
126
|
-
* daemon commands must keep their daemon semantics, and passthrough is checked
|
|
127
|
-
* BEFORE DAEMON_COMMANDS in the router, so an un-filtered custom `/status`
|
|
128
|
-
* would hijack the daemon's own.
|
|
129
|
-
* Unknown / no bot → falls back to the builtin set unchanged.
|
|
130
|
-
*/
|
|
131
|
-
export function resolvePassthroughCommands(larkAppId) {
|
|
132
|
-
const effective = new Set(PASSTHROUGH_COMMANDS);
|
|
133
|
-
if (!larkAppId)
|
|
134
|
-
return effective;
|
|
135
|
-
for (const c of resolveAdapterDefaultPassthroughCommands(larkAppId)) {
|
|
136
|
-
effective.add(c);
|
|
137
|
-
}
|
|
138
|
-
try {
|
|
139
|
-
for (const c of getBot(larkAppId).config.customPassthroughCommands ?? []) {
|
|
140
|
-
const normalized = normalizePassthroughCommand(c);
|
|
141
|
-
if (normalized)
|
|
142
|
-
effective.add(normalized);
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
catch {
|
|
146
|
-
/* unknown bot — builtin set only */
|
|
147
|
-
}
|
|
148
|
-
return effective;
|
|
149
|
-
}
|
|
150
|
-
const MULTILINE_COMMANDS = new Set(['/schedule', '/role', '/fork']);
|
|
151
|
-
// `validateWorkingDir` now lives in ./working-dir.js (leaf module the CLI can
|
|
152
|
-
// import without the daemon graph); re-exported here for existing callers.
|
|
153
|
-
export { validateWorkingDir };
|
|
154
|
-
/**
|
|
155
|
-
* Resolve a non-numeric `/repo <arg>` into a concrete repo path + display name.
|
|
156
|
-
* `arg` is either a path (absolute or relative) or a first-level project name
|
|
157
|
-
* under one of the bot's scan dirs — letting the user skip the selection card.
|
|
158
|
-
*
|
|
159
|
-
* Resolution:
|
|
160
|
-
* 1. Build candidate absolute paths — absolute / `~` taken as-is; relative or
|
|
161
|
-
* bare names resolved against each scan dir, then the daemon cwd (mirrors
|
|
162
|
-
* how the card's project list is rooted).
|
|
163
|
-
* 2. Return the first directly existing candidate, describing its git ref
|
|
164
|
-
* without scanning unrelated roots. This is lenient like `/cd`, whose trust
|
|
165
|
-
* model is "owner explicitly chose a dir"; the CLI already runs with full
|
|
166
|
-
* FS access.
|
|
167
|
-
* 3. Only for a bare name that did not directly resolve, scan projects and
|
|
168
|
-
* match by basename (covers projects nested deeper than the scan-dir top
|
|
169
|
-
* level).
|
|
170
|
-
* Returns null when nothing resolves to an existing directory.
|
|
171
|
-
*/
|
|
172
|
-
export function resolveRepoSelection(repoArg, scanDirs) {
|
|
173
|
-
const isExplicitPath = repoArg.startsWith('/') ||
|
|
174
|
-
repoArg.startsWith('~') ||
|
|
175
|
-
repoArg.startsWith('.') ||
|
|
176
|
-
repoArg.includes('/');
|
|
177
|
-
const candidates = [];
|
|
178
|
-
if (repoArg.startsWith('/') || repoArg.startsWith('~')) {
|
|
179
|
-
candidates.push(resolve(expandHome(repoArg)));
|
|
180
|
-
}
|
|
181
|
-
else {
|
|
182
|
-
for (const d of scanDirs)
|
|
183
|
-
candidates.push(resolve(d, repoArg));
|
|
184
|
-
candidates.push(resolve(expandHome(repoArg))); // daemon-cwd fallback (matches /cd)
|
|
185
|
-
}
|
|
186
|
-
// Direct candidates must win before any recursive scan. Besides avoiding
|
|
187
|
-
// unnecessary traversal (especially a legacy HOME fallback), describing just
|
|
188
|
-
// the selected directory preserves the same "name (branch)" label for repos.
|
|
189
|
-
for (const cand of candidates) {
|
|
190
|
-
try {
|
|
191
|
-
if (!statSync(cand).isDirectory())
|
|
192
|
-
continue;
|
|
193
|
-
}
|
|
194
|
-
catch {
|
|
195
|
-
continue; // missing / not a dir — try next candidate
|
|
196
|
-
}
|
|
197
|
-
const desc = describeProjectDir(cand);
|
|
198
|
-
return desc
|
|
199
|
-
? { path: cand, displayName: `${desc.name} (${desc.branch})` }
|
|
200
|
-
: { path: cand, displayName: basename(cand) };
|
|
201
|
-
}
|
|
202
|
-
// Explicit and relative paths have no basename-search semantics: when their
|
|
203
|
-
// concrete candidates do not exist, a recursive project scan cannot resolve
|
|
204
|
-
// them. Bare names alone may refer to a repo nested below a scan root.
|
|
205
|
-
if (isExplicitPath)
|
|
206
|
-
return null;
|
|
207
|
-
const existingScanDirs = scanDirs.filter((d) => existsSync(d));
|
|
208
|
-
const projects = existingScanDirs.length > 0 ? scanMultipleProjects(existingScanDirs) : [];
|
|
209
|
-
const byName = projects.find((p) => p.name === repoArg);
|
|
210
|
-
if (byName)
|
|
211
|
-
return { path: byName.path, displayName: `${byName.name} (${byName.branch})` };
|
|
212
|
-
return null;
|
|
213
|
-
}
|
|
214
|
-
/**
|
|
215
|
-
* Parse a force-topic invocation: `/t [prompt]` or `/topic [prompt]`.
|
|
216
|
-
*
|
|
217
|
-
* This is a routing meta-command, distinct from `parseSlashCommandInvocation`
|
|
218
|
-
* (which routes to daemon command handlers). The match conditions are
|
|
219
|
-
* deliberately tighter than the regular slash parser:
|
|
220
|
-
*
|
|
221
|
-
* - exact-prefix match (`/t` / `/topic`, case-insensitive); `/tea` / `/topical`
|
|
222
|
-
* must NOT match, otherwise we'd false-trigger on common /-prefixed words.
|
|
223
|
-
* - tolerates leading whitespace (mention-stripping can leave a space).
|
|
224
|
-
* - prompt is whatever follows the prefix (verbatim, including newlines).
|
|
225
|
-
* - `/t` alone (no args) is allowed → empty prompt; the user can fill it in
|
|
226
|
-
* while the repo selection card is still pending.
|
|
227
|
-
*
|
|
228
|
-
* Returns null for anything else, so callers can fall through to the regular
|
|
229
|
-
* `parseSlashCommandInvocation` / message-handling path.
|
|
230
|
-
*/
|
|
231
|
-
export function parseForceTopicInvocation(content) {
|
|
232
|
-
const trimmed = content.replace(/^\s+/, '');
|
|
233
|
-
const match = /^\/(t|topic)(?:\s+([\s\S]*))?$/i.exec(trimmed);
|
|
234
|
-
if (!match)
|
|
235
|
-
return null;
|
|
236
|
-
return { prompt: (match[2] ?? '').trim() };
|
|
237
|
-
}
|
|
238
|
-
/** Parse a user-authored slash command after leading @mentions have already
|
|
239
|
-
* been stripped. Messages that look like command examples or command lists
|
|
240
|
-
* are intentionally left for the CLI instead of being intercepted by the
|
|
241
|
-
* daemon; otherwise discussion text such as `/adopt <pane>` can accidentally
|
|
242
|
-
* trigger real daemon actions. */
|
|
243
|
-
export function parseSlashCommandInvocation(content) {
|
|
244
|
-
// trim BOTH ends: a trailing newline/space rides into the returned `content`
|
|
245
|
-
// and, for a passthrough command relayed verbatim to the CLI (raw_input), gets
|
|
246
|
-
// typed as a literal trailing newline — which breaks the CLI's slash-command
|
|
247
|
-
// detection (it sees a multi-line message, not a `/cmd`). Internal newlines for
|
|
248
|
-
// MULTILINE_COMMANDS are preserved (trim only touches the ends).
|
|
249
|
-
const trimmed = content.trim();
|
|
250
|
-
if (!trimmed.startsWith('/'))
|
|
251
|
-
return null;
|
|
252
|
-
const lines = trimmed.split(/\r?\n/);
|
|
253
|
-
const firstLine = (lines[0] ?? '').trimEnd();
|
|
254
|
-
const [cmdRaw] = firstLine.split(/\s+/);
|
|
255
|
-
const cmd = cmdRaw?.toLowerCase();
|
|
256
|
-
if (!cmd)
|
|
257
|
-
return null;
|
|
258
|
-
// Treat angle-bracket placeholders as documentation, not an invocation.
|
|
259
|
-
if (/<[^>\r\n]+>/.test(firstLine))
|
|
260
|
-
return null;
|
|
261
|
-
const restNonBlank = lines.slice(1).map(l => l.trim()).filter(Boolean);
|
|
262
|
-
if (restNonBlank.length > 0) {
|
|
263
|
-
// A list of slash commands is almost certainly discussion / planning text.
|
|
264
|
-
if (restNonBlank.some(l => l.startsWith('/')))
|
|
265
|
-
return null;
|
|
266
|
-
if (!MULTILINE_COMMANDS.has(cmd))
|
|
267
|
-
return null;
|
|
268
|
-
}
|
|
269
|
-
return { cmd, content: trimmed };
|
|
270
|
-
}
|
|
271
|
-
function tag(ds) {
|
|
272
|
-
return ds.session.sessionId.substring(0, 8);
|
|
273
|
-
}
|
|
274
|
-
/**
|
|
275
|
-
* Lowercased display names of ALL bots known to the deployment, read from the
|
|
276
|
-
* shared bots-info.json. This is the only globally-complete, process-stable
|
|
277
|
-
* source of "is this @-mention a bot?": production runs one daemon per bot, so
|
|
278
|
-
* getAllBots() only sees this process's own bot, and the live chat-member roster
|
|
279
|
-
* (listChatBotMembers) can transiently miss a bot — either would let competing
|
|
280
|
-
* bot processes disagree on who the first @-mentioned bot is and double-create.
|
|
281
|
-
* bots-info.json is a local file merge-written by every daemon at startup.
|
|
282
|
-
*/
|
|
283
|
-
function globalKnownBotNames() {
|
|
284
|
-
try {
|
|
285
|
-
const p = join(config.session.dataDir, 'bots-info.json');
|
|
286
|
-
if (!existsSync(p))
|
|
287
|
-
return new Set();
|
|
288
|
-
const entries = JSON.parse(readFileSync(p, 'utf-8'));
|
|
289
|
-
return new Set(entries.map(e => e.botName?.toLowerCase()).filter((n) => !!n));
|
|
290
|
-
}
|
|
291
|
-
catch {
|
|
292
|
-
return new Set();
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
/** Human-friendly name for a bot larkAppId — Lark app display name, else cliId, else the raw id. */
|
|
296
|
-
function botDisplayName(larkAppId) {
|
|
297
|
-
try {
|
|
298
|
-
const bot = getBot(larkAppId);
|
|
299
|
-
return bot.botName ?? getCliDisplayName(bot.config.cliId) ?? larkAppId;
|
|
300
|
-
}
|
|
301
|
-
catch {
|
|
302
|
-
return larkAppId;
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
function sessionCliDisplayName(ds) {
|
|
306
|
-
const botCfg = getBot(ds.larkAppId).config;
|
|
307
|
-
const configured = sessionConfiguredRuntimeDisplayName(ds.session, botCfg.cliRuntime);
|
|
308
|
-
if (configured)
|
|
309
|
-
return configured;
|
|
310
|
-
return getCliDisplayName(ds.session.cliId ?? botCfg.cliId);
|
|
311
|
-
}
|
|
312
|
-
function formatUptime(ms) {
|
|
313
|
-
const s = Math.floor(ms / 1000);
|
|
314
|
-
if (s < 60)
|
|
315
|
-
return `${s}s`;
|
|
316
|
-
const m = Math.floor(s / 60);
|
|
317
|
-
if (m < 60)
|
|
318
|
-
return `${m}m${s % 60}s`;
|
|
319
|
-
const h = Math.floor(m / 60);
|
|
320
|
-
return `${h}h${m % 60}m`;
|
|
321
|
-
}
|
|
322
|
-
function codexAppThreadTitle(thread) {
|
|
323
|
-
const raw = (thread.name || thread.preview || thread.threadId).replace(/\s+/g, ' ').trim();
|
|
324
|
-
return raw.length > 80 ? raw.slice(0, 79) + '…' : raw;
|
|
325
|
-
}
|
|
326
|
-
function invalidConfiguredWorkingDirs(ds, larkAppId) {
|
|
327
|
-
if (ds?.workingDir)
|
|
328
|
-
return invalidWorkingDirs({ workingDir: ds.workingDir });
|
|
329
|
-
if (larkAppId) {
|
|
330
|
-
const bot = getBot(larkAppId);
|
|
331
|
-
return invalidWorkingDirs({
|
|
332
|
-
workingDir: bot.config.workingDir ?? '~',
|
|
333
|
-
workingDirs: bot.config.workingDirs,
|
|
334
|
-
});
|
|
335
|
-
}
|
|
336
|
-
return invalidWorkingDirs({
|
|
337
|
-
workingDir: config.daemon.workingDir ?? '~',
|
|
338
|
-
workingDirs: config.daemon.workingDirs,
|
|
339
|
-
});
|
|
340
|
-
}
|
|
341
|
-
// ─── Schedule command ────────────────────────────────────────────────────────
|
|
342
|
-
async function handleRoleCommand(args, rootId, chatId, larkAppId, senderId, deps) {
|
|
343
|
-
const sessionReply = (rid, content, msgType) => deps.sessionReply(rid, content, msgType, larkAppId);
|
|
344
|
-
const trimmed = args.trim();
|
|
345
|
-
const loc = localeForBot(larkAppId);
|
|
346
|
-
const dataDir = config.session.dataDir;
|
|
347
|
-
// /role profile [...] — reusable suites of per-bot chat roles. Profiles are
|
|
348
|
-
// not a runtime role layer; applying one materializes this bot's entry into
|
|
349
|
-
// the current chat role.
|
|
350
|
-
const profileMatch = trimmed.match(/^profile\b([\s\S]*)$/);
|
|
351
|
-
if (profileMatch) {
|
|
352
|
-
const profileArgs = profileMatch[1].trim();
|
|
353
|
-
const subMatch = profileArgs.match(/^(\S+)(?:\s+([\s\S]*))?$/);
|
|
354
|
-
const sub = (subMatch?.[1] ?? '').toLowerCase();
|
|
355
|
-
const subBody = subMatch?.[2]?.trim() ?? '';
|
|
356
|
-
if (!sub || sub === 'help') {
|
|
357
|
-
await sessionReply(rootId, t('role.profile.help', undefined, loc));
|
|
358
|
-
return;
|
|
359
|
-
}
|
|
360
|
-
if (sub === 'list' || sub === 'ls') {
|
|
361
|
-
const profiles = listRoleProfiles(dataDir);
|
|
362
|
-
if (profiles.length === 0) {
|
|
363
|
-
await sessionReply(rootId, t('role.profile.list_empty', undefined, loc));
|
|
364
|
-
return;
|
|
365
|
-
}
|
|
366
|
-
const lines = profiles.map(p => {
|
|
367
|
-
const hasEntry = readRoleProfileEntry(dataDir, p.profileId, larkAppId) !== null;
|
|
368
|
-
const status = hasEntry
|
|
369
|
-
? t('role.profile.current_configured', undefined, loc)
|
|
370
|
-
: t('role.profile.current_missing', undefined, loc);
|
|
371
|
-
return `• ${p.profileId} — ${p.entryCount} ${t('role.profile.entries', undefined, loc)}; ${status}`;
|
|
372
|
-
});
|
|
373
|
-
await sessionReply(rootId, `${t('role.profile.list_header', undefined, loc)}\n${lines.join('\n')}`);
|
|
374
|
-
return;
|
|
375
|
-
}
|
|
376
|
-
const [profileId = '', ...afterProfile] = subBody.split(/\s+/);
|
|
377
|
-
if (!profileId || !isValidRoleProfileId(profileId)) {
|
|
378
|
-
await sessionReply(rootId, t('role.profile.invalid', undefined, loc));
|
|
379
|
-
return;
|
|
380
|
-
}
|
|
381
|
-
if (sub === 'show') {
|
|
382
|
-
const showAll = afterProfile.includes('--all');
|
|
383
|
-
if (showAll) {
|
|
384
|
-
const entries = listRoleProfileEntries(dataDir, profileId);
|
|
385
|
-
if (entries.length === 0) {
|
|
386
|
-
await sessionReply(rootId, t('role.profile.no_entries', { profile: profileId }, loc));
|
|
387
|
-
return;
|
|
388
|
-
}
|
|
389
|
-
const body = entries.map(entry => `### ${entry.larkAppId}\n${t('role.byte_count', { bytes: entry.byteLength, max: MAX_ROLE_PROFILE_ENTRY_BYTES }, loc)}\n\`\`\`markdown\n${entry.content}\n\`\`\``).join('\n\n');
|
|
390
|
-
await sessionReply(rootId, `${t('role.profile.show_all_header', { profile: profileId }, loc)}\n${body}`);
|
|
391
|
-
return;
|
|
392
|
-
}
|
|
393
|
-
const content = readRoleProfileEntry(dataDir, profileId, larkAppId);
|
|
394
|
-
if (content === null) {
|
|
395
|
-
await sessionReply(rootId, t('role.profile.entry_empty', { profile: profileId }, loc));
|
|
396
|
-
return;
|
|
397
|
-
}
|
|
398
|
-
await sessionReply(rootId, `${t('role.profile.entry_current', { profile: profileId }, loc)}\n\`\`\`markdown\n${content}\n\`\`\`\n${t('role.byte_count', { bytes: Buffer.byteLength(content, 'utf-8'), max: MAX_ROLE_PROFILE_ENTRY_BYTES }, loc)}`);
|
|
399
|
-
return;
|
|
400
|
-
}
|
|
401
|
-
if (sub === 'set') {
|
|
402
|
-
const content = subBody.slice(profileId.length).trim();
|
|
403
|
-
if (!content) {
|
|
404
|
-
await sessionReply(rootId, t('role.profile.set_empty', undefined, loc));
|
|
405
|
-
return;
|
|
406
|
-
}
|
|
407
|
-
writeRoleProfileEntry(dataDir, profileId, larkAppId, content);
|
|
408
|
-
await sessionReply(rootId, t('role.profile.entry_saved', {
|
|
409
|
-
profile: profileId,
|
|
410
|
-
bytes: Math.min(Buffer.byteLength(content.trim(), 'utf-8'), MAX_ROLE_PROFILE_ENTRY_BYTES),
|
|
411
|
-
max: MAX_ROLE_PROFILE_ENTRY_BYTES,
|
|
412
|
-
}, loc));
|
|
413
|
-
return;
|
|
414
|
-
}
|
|
415
|
-
if (sub === 'save') {
|
|
416
|
-
const { content, source } = resolveRole(larkAppId, chatId);
|
|
417
|
-
if (!content) {
|
|
418
|
-
await sessionReply(rootId, t('role.profile.save_no_effective', { profile: profileId }, loc));
|
|
419
|
-
return;
|
|
420
|
-
}
|
|
421
|
-
writeRoleProfileEntry(dataDir, profileId, larkAppId, content);
|
|
422
|
-
await sessionReply(rootId, t('role.profile.saved_effective', {
|
|
423
|
-
profile: profileId,
|
|
424
|
-
source,
|
|
425
|
-
bytes: Buffer.byteLength(content, 'utf-8'),
|
|
426
|
-
max: MAX_ROLE_PROFILE_ENTRY_BYTES,
|
|
427
|
-
}, loc));
|
|
428
|
-
return;
|
|
429
|
-
}
|
|
430
|
-
if (sub === 'delete' || sub === 'del' || sub === 'rm' || sub === '删除') {
|
|
431
|
-
const existed = deleteRoleProfileEntry(dataDir, profileId, larkAppId);
|
|
432
|
-
deleteRoleProfileIfEmpty(dataDir, profileId);
|
|
433
|
-
await sessionReply(rootId, existed
|
|
434
|
-
? t('role.profile.entry_deleted', { profile: profileId }, loc)
|
|
435
|
-
: t('role.profile.entry_nothing', { profile: profileId }, loc));
|
|
436
|
-
return;
|
|
437
|
-
}
|
|
438
|
-
if (sub === 'apply') {
|
|
439
|
-
const flags = new Set(afterProfile);
|
|
440
|
-
const preview = flags.has('--preview');
|
|
441
|
-
const force = flags.has('--force');
|
|
442
|
-
const quiet = flags.has('--quiet');
|
|
443
|
-
const content = readRoleProfileEntry(dataDir, profileId, larkAppId);
|
|
444
|
-
if (content === null) {
|
|
445
|
-
await sessionReply(rootId, t('role.profile.apply_missing', { profile: profileId }, loc));
|
|
446
|
-
return;
|
|
447
|
-
}
|
|
448
|
-
const existing = resolveRoleFile(larkAppId, chatId);
|
|
449
|
-
const bytes = Buffer.byteLength(content, 'utf-8');
|
|
450
|
-
if (preview) {
|
|
451
|
-
const overwriteLine = existing && !force
|
|
452
|
-
? `\n${t('role.profile.apply_would_refuse', undefined, loc)}`
|
|
453
|
-
: '';
|
|
454
|
-
await sessionReply(rootId, `${t('role.profile.apply_preview', { profile: profileId, bytes, max: MAX_ROLE_PROFILE_ENTRY_BYTES }, loc)}${overwriteLine}\n\`\`\`markdown\n${content}\n\`\`\``);
|
|
455
|
-
return;
|
|
456
|
-
}
|
|
457
|
-
if (existing && !force) {
|
|
458
|
-
// An empty entry would *clear* the chat role, not overwrite it — phrase
|
|
459
|
-
// the --force refusal accordingly so the intent is not misread.
|
|
460
|
-
const refusedKey = content ? 'role.profile.apply_refused' : 'role.profile.apply_refused_clear';
|
|
461
|
-
await sessionReply(rootId, t(refusedKey, { profile: profileId }, loc));
|
|
462
|
-
return;
|
|
463
|
-
}
|
|
464
|
-
if (!content) {
|
|
465
|
-
deleteRoleFile(larkAppId, chatId);
|
|
466
|
-
if (!quiet) {
|
|
467
|
-
await sessionReply(rootId, t('role.profile.applied', { profile: profileId, bytes, max: MAX_ROLE_PROFILE_ENTRY_BYTES }, loc));
|
|
468
|
-
}
|
|
469
|
-
return;
|
|
470
|
-
}
|
|
471
|
-
writeRoleFile(larkAppId, chatId, content);
|
|
472
|
-
if (!quiet) {
|
|
473
|
-
await sessionReply(rootId, t('role.profile.applied', { profile: profileId, bytes, max: MAX_ROLE_PROFILE_ENTRY_BYTES }, loc));
|
|
474
|
-
}
|
|
475
|
-
return;
|
|
476
|
-
}
|
|
477
|
-
await sessionReply(rootId, t('role.profile.help', undefined, loc));
|
|
478
|
-
return;
|
|
479
|
-
}
|
|
480
|
-
// /role team [...] — manage the team-level (per-bot, cross-chat) role
|
|
481
|
-
const teamMatch = trimmed.match(/^team\b([\s\S]*)$/);
|
|
482
|
-
if (teamMatch) {
|
|
483
|
-
const teamArgs = teamMatch[1].trim();
|
|
484
|
-
const teamSet = teamArgs.match(/^set\s+([\s\S]+)/);
|
|
485
|
-
if (teamSet) {
|
|
486
|
-
const content = teamSet[1].trim();
|
|
487
|
-
if (!content) {
|
|
488
|
-
await sessionReply(rootId, t('role.set_empty', undefined, loc));
|
|
489
|
-
return;
|
|
490
|
-
}
|
|
491
|
-
writeTeamRoleFile(larkAppId, content);
|
|
492
|
-
await sessionReply(rootId, t('role.team_saved', { bytes: Buffer.byteLength(content, 'utf-8'), max: MAX_ROLE_BYTES }, loc));
|
|
493
|
-
return;
|
|
494
|
-
}
|
|
495
|
-
if (teamArgs === 'delete' || teamArgs === '删除') {
|
|
496
|
-
await sessionReply(rootId, deleteTeamRoleFile(larkAppId) ? t('role.team_deleted', undefined, loc) : t('role.team_nothing', undefined, loc));
|
|
497
|
-
return;
|
|
498
|
-
}
|
|
499
|
-
const content = resolveTeamRoleFile(larkAppId);
|
|
500
|
-
if (content) {
|
|
501
|
-
await sessionReply(rootId, `${t('role.team_current', undefined, loc)}\n\`\`\`markdown\n${content}\n\`\`\`\n${t('role.byte_count', { bytes: Buffer.byteLength(content, 'utf-8'), max: MAX_ROLE_BYTES }, loc)}`);
|
|
502
|
-
}
|
|
503
|
-
else {
|
|
504
|
-
await sessionReply(rootId, t('role.team_empty', undefined, loc));
|
|
505
|
-
}
|
|
506
|
-
return;
|
|
507
|
-
}
|
|
508
|
-
// /role cap [...] — manage the short capability label shown in the roster
|
|
509
|
-
const capMatch = trimmed.match(/^cap\b([\s\S]*)$/);
|
|
510
|
-
if (capMatch) {
|
|
511
|
-
const capArgs = capMatch[1].trim();
|
|
512
|
-
const capSet = capArgs.match(/^set\s+([\s\S]+)/);
|
|
513
|
-
if (capSet) {
|
|
514
|
-
const label = capSet[1].trim();
|
|
515
|
-
if (!label) {
|
|
516
|
-
await sessionReply(rootId, t('role.cap_set_empty', undefined, loc));
|
|
517
|
-
return;
|
|
518
|
-
}
|
|
519
|
-
setBotCapability(dataDir, larkAppId, label, senderId);
|
|
520
|
-
await sessionReply(rootId, t('role.cap_saved', { cap: getBotCapability(dataDir, larkAppId) ?? label }, loc));
|
|
521
|
-
return;
|
|
522
|
-
}
|
|
523
|
-
if (capArgs === 'clear' || capArgs === '清除') {
|
|
524
|
-
await sessionReply(rootId, clearBotCapability(dataDir, larkAppId) ? t('role.cap_cleared', undefined, loc) : t('role.cap_empty', undefined, loc));
|
|
525
|
-
return;
|
|
526
|
-
}
|
|
527
|
-
const cap = getBotCapability(dataDir, larkAppId);
|
|
528
|
-
await sessionReply(rootId, cap ? t('role.cap_current', { cap }, loc) : t('role.cap_empty', undefined, loc));
|
|
529
|
-
return;
|
|
530
|
-
}
|
|
531
|
-
// /role → show the EFFECTIVE role + where it comes from (chat override > team > none)
|
|
532
|
-
if (!trimmed) {
|
|
533
|
-
const { content, source } = resolveRole(larkAppId, chatId);
|
|
534
|
-
if (content) {
|
|
535
|
-
const len = Buffer.byteLength(content, 'utf-8');
|
|
536
|
-
const srcLabel = source === 'chat' ? t('role.src_chat', undefined, loc) : t('role.src_team', undefined, loc);
|
|
537
|
-
await sessionReply(rootId, `${t('role.current', undefined, loc)} ${srcLabel}\n\`\`\`markdown\n${content}\n\`\`\`\n${t('role.byte_count', { bytes: len, max: MAX_ROLE_BYTES }, loc)}`);
|
|
538
|
-
}
|
|
539
|
-
else {
|
|
540
|
-
await sessionReply(rootId, t('role.empty', undefined, loc));
|
|
541
|
-
}
|
|
542
|
-
return;
|
|
543
|
-
}
|
|
544
|
-
// /role set <content> — write role file
|
|
545
|
-
const setMatch = trimmed.match(/^set\s+([\s\S]+)/);
|
|
546
|
-
if (setMatch) {
|
|
547
|
-
const content = setMatch[1].trim();
|
|
548
|
-
if (!content) {
|
|
549
|
-
await sessionReply(rootId, t('role.set_empty', undefined, loc));
|
|
550
|
-
return;
|
|
551
|
-
}
|
|
552
|
-
writeRoleFile(larkAppId, chatId, content);
|
|
553
|
-
const len = Buffer.byteLength(content, 'utf-8');
|
|
554
|
-
await sessionReply(rootId, t('role.saved_via_cmd', { bytes: len, max: MAX_ROLE_BYTES }, loc));
|
|
555
|
-
return;
|
|
556
|
-
}
|
|
557
|
-
// /role delete
|
|
558
|
-
if (trimmed === 'delete' || trimmed === '删除') {
|
|
559
|
-
const existed = deleteRoleFile(larkAppId, chatId);
|
|
560
|
-
if (existed) {
|
|
561
|
-
await sessionReply(rootId, t('role.deleted_via_cmd', undefined, loc));
|
|
562
|
-
}
|
|
563
|
-
else {
|
|
564
|
-
await sessionReply(rootId, t('role.nothing_to_delete', undefined, loc));
|
|
565
|
-
}
|
|
566
|
-
return;
|
|
567
|
-
}
|
|
568
|
-
// /role help — fallback
|
|
569
|
-
await sessionReply(rootId, t('role.help', undefined, loc));
|
|
570
|
-
}
|
|
571
|
-
/**
|
|
572
|
-
* Resolve the workingDir for a newly created scheduled task, mirroring the
|
|
573
|
-
* layered lookup used by the normal new-session spawn path (see
|
|
574
|
-
* `resolvePinnedWorkingDir` in daemon.ts) but STRICTLY read-only: it never
|
|
575
|
-
* triggers the defaultOncall auto-bind side effect (which writes to bots.json).
|
|
576
|
-
* Creating a schedule must not mutate oncall binding state.
|
|
577
|
-
*
|
|
578
|
-
* Priority:
|
|
579
|
-
* 1) existing session workingDir (ds.workingDir — already pinned via /cd or
|
|
580
|
-
* a previously-applied oncall bind)
|
|
581
|
-
* 2) this bot/chat oncall binding (read-only findOncallChat, no auto-bind)
|
|
582
|
-
* 3) this bot's effective default working dir (defaultWorkingDir, or
|
|
583
|
-
* defaultOncall.workingDir when Oncall 模式 is on)
|
|
584
|
-
* 4) legacy bot.config.workingDir
|
|
585
|
-
* 5) '~'
|
|
586
|
-
*
|
|
587
|
-
* Deliberate deltas vs `resolvePinnedWorkingDir` (do NOT "sync" them away):
|
|
588
|
-
* - no sibling-inherit layer (findInheritablePeer) — a schedule needs a
|
|
589
|
-
* deterministic dir at create time, not whatever peer session happens to
|
|
590
|
-
* be open at that moment;
|
|
591
|
-
* - extra layers 4/5 — a schedule has no interactive repo-select card to
|
|
592
|
-
* fall back on, so it must always resolve to something;
|
|
593
|
-
* - every layer validates the candidate dir and falls through when it is
|
|
594
|
-
* stale (deleted/renamed): a dead path would otherwise be baked into
|
|
595
|
-
* schedules.json (workingDir is not editable afterwards) and every fire
|
|
596
|
-
* would silently spawn in $HOME. This includes layer 1 — a ds restored
|
|
597
|
-
* by restoreActiveSessions (worker:null) or idle-suspended keeps a
|
|
598
|
-
* workingDir no live process is running in, so it can be stale too.
|
|
599
|
-
*/
|
|
600
|
-
function resolveScheduleWorkingDir(ds, chatId, larkAppId) {
|
|
601
|
-
// Validate candidates and fall through (returning the RAW form — keep `~`;
|
|
602
|
-
// expansion happens at fire time via getSessionWorkingDir), matching the
|
|
603
|
-
// other copies of this ladder (daemon resolveBotDefaultWorkingDir,
|
|
604
|
-
// trigger-session).
|
|
605
|
-
const usable = (dir, layer) => {
|
|
606
|
-
const v = validateWorkingDir(dir);
|
|
607
|
-
if (v.ok)
|
|
608
|
-
return true;
|
|
609
|
-
logger.warn(`[schedule] ${layer} workingDir "${dir}" invalid — falling through: ${v.error}`);
|
|
610
|
-
return false;
|
|
611
|
-
};
|
|
612
|
-
// Layer 1: existing session dir already pinned.
|
|
613
|
-
if (ds?.workingDir && usable(ds.workingDir, 'session'))
|
|
614
|
-
return ds.workingDir;
|
|
615
|
-
const appId = ds?.larkAppId ?? larkAppId;
|
|
616
|
-
// getBot() throws for unregistered ids — degrade to the '~' fallback
|
|
617
|
-
// instead of aborting the whole /schedule command.
|
|
618
|
-
let bot;
|
|
619
|
-
try {
|
|
620
|
-
bot = appId ? getBot(appId) : getAllBots()[0];
|
|
621
|
-
}
|
|
622
|
-
catch {
|
|
623
|
-
bot = undefined;
|
|
624
|
-
}
|
|
625
|
-
if (!bot)
|
|
626
|
-
return '~';
|
|
627
|
-
// Layer 2: oncall binding for this chat (read-only — does NOT auto-bind).
|
|
628
|
-
const oncallEntry = findOncallChat(bot.config.larkAppId, ds?.chatId ?? chatId);
|
|
629
|
-
if (oncallEntry?.workingDir && usable(oncallEntry.workingDir, 'oncall-binding')) {
|
|
630
|
-
return oncallEntry.workingDir;
|
|
631
|
-
}
|
|
632
|
-
// Layer 3: effective default working dir (defaultWorkingDir or
|
|
633
|
-
// defaultOncall.workingDir). Read-only — never writes state.
|
|
634
|
-
const effectiveDefault = effectiveDefaultWorkingDir(bot.config);
|
|
635
|
-
if (effectiveDefault && usable(effectiveDefault, 'effective-default'))
|
|
636
|
-
return effectiveDefault;
|
|
637
|
-
// Layer 4: legacy workingDir field.
|
|
638
|
-
if (bot.config.workingDir && usable(bot.config.workingDir, 'legacy'))
|
|
639
|
-
return bot.config.workingDir;
|
|
640
|
-
// Layer 5: home fallback.
|
|
641
|
-
return '~';
|
|
642
|
-
}
|
|
643
|
-
async function handleScheduleCommand(args, rootId, chatId, deps, larkAppId) {
|
|
644
|
-
const { activeSessions } = deps;
|
|
645
|
-
const sessionReply = (rid, content, msgType) => deps.sessionReply(rid, content, msgType, larkAppId);
|
|
646
|
-
const trimmed = args.trim();
|
|
647
|
-
const loc = localeForBot(larkAppId);
|
|
648
|
-
// Format dates using a locale that matches the user's UI choice. Both
|
|
649
|
-
// forms include the wall-clock components the user cares about; the
|
|
650
|
-
// difference is just punctuation and digit order.
|
|
651
|
-
const timeLocale = loc === 'en' ? 'en-US' : 'zh-CN';
|
|
652
|
-
const timeZone = scheduleTimeZone();
|
|
653
|
-
// /schedule list | /schedule 列表
|
|
654
|
-
if (!trimmed || trimmed === 'list' || trimmed === '列表') {
|
|
655
|
-
const tasks = scheduleStore.listTasks();
|
|
656
|
-
if (tasks.length === 0) {
|
|
657
|
-
await sessionReply(rootId, t('schedule.empty_with_examples', undefined, loc));
|
|
658
|
-
return;
|
|
659
|
-
}
|
|
660
|
-
const lines = tasks.map(task => {
|
|
661
|
-
const status = task.enabled ? '✅' : '⏸️';
|
|
662
|
-
const next = task.enabled ? scheduler.getNextRun(task.id) : null;
|
|
663
|
-
const nextStr = next ? t('schedule.next_label', { time: next.toLocaleString(timeLocale, { timeZone }) }, loc) : '';
|
|
664
|
-
const lastStr = task.lastRunAt ? t('schedule.last_label', { time: new Date(task.lastRunAt).toLocaleString(timeLocale, { timeZone }) }, loc) : '';
|
|
665
|
-
const display = task.parsed?.display ?? task.schedule;
|
|
666
|
-
return `${status} [${task.id}] ${display} | ${task.name}${task.silent ? ' 🔇' : ''}\n prompt: ${task.prompt.substring(0, 50)}${task.prompt.length > 50 ? '...' : ''}${nextStr}${lastStr}`;
|
|
667
|
-
});
|
|
668
|
-
await sessionReply(rootId, `${t('schedule.list_header', { count: tasks.length }, loc)}\n\n${lines.join('\n\n')}`);
|
|
669
|
-
return;
|
|
670
|
-
}
|
|
671
|
-
// /schedule remove <id> | /schedule 删除 <id>
|
|
672
|
-
const removeMatch = trimmed.match(/^(?:remove|删除)\s+(\S+)/);
|
|
673
|
-
if (removeMatch) {
|
|
674
|
-
const id = removeMatch[1];
|
|
675
|
-
if (scheduler.removeTask(id)) {
|
|
676
|
-
await sessionReply(rootId, t('schedule.removed', { id }, loc));
|
|
677
|
-
}
|
|
678
|
-
else {
|
|
679
|
-
await sessionReply(rootId, t('schedule.not_found', { id }, loc));
|
|
680
|
-
}
|
|
681
|
-
return;
|
|
682
|
-
}
|
|
683
|
-
// /schedule enable <id> | /schedule 启用 <id>
|
|
684
|
-
const enableMatch = trimmed.match(/^(?:enable|启用)\s+(\S+)/);
|
|
685
|
-
if (enableMatch) {
|
|
686
|
-
const id = enableMatch[1];
|
|
687
|
-
if (scheduler.enableTask(id)) {
|
|
688
|
-
await sessionReply(rootId, t('schedule.enabled', { id }, loc));
|
|
689
|
-
}
|
|
690
|
-
else {
|
|
691
|
-
await sessionReply(rootId, t('schedule.not_found', { id }, loc));
|
|
692
|
-
}
|
|
693
|
-
return;
|
|
694
|
-
}
|
|
695
|
-
// /schedule disable <id> | /schedule 禁用 <id>
|
|
696
|
-
const disableMatch = trimmed.match(/^(?:disable|禁用)\s+(\S+)/);
|
|
697
|
-
if (disableMatch) {
|
|
698
|
-
const id = disableMatch[1];
|
|
699
|
-
if (scheduler.disableTask(id)) {
|
|
700
|
-
await sessionReply(rootId, t('schedule.disabled', { id }, loc));
|
|
701
|
-
}
|
|
702
|
-
else {
|
|
703
|
-
await sessionReply(rootId, t('schedule.not_found', { id }, loc));
|
|
704
|
-
}
|
|
705
|
-
return;
|
|
706
|
-
}
|
|
707
|
-
// /schedule run <id> | /schedule 执行 <id>
|
|
708
|
-
const runMatch = trimmed.match(/^(?:run|执行)\s+(\S+)/);
|
|
709
|
-
if (runMatch) {
|
|
710
|
-
const id = runMatch[1];
|
|
711
|
-
if (scheduler.runTaskNow(id)) {
|
|
712
|
-
await sessionReply(rootId, t('schedule.triggered_now', { id }, loc));
|
|
713
|
-
}
|
|
714
|
-
else {
|
|
715
|
-
await sessionReply(rootId, t('schedule.not_found', { id }, loc));
|
|
716
|
-
}
|
|
717
|
-
return;
|
|
718
|
-
}
|
|
719
|
-
// Natural language: /schedule 每日17:50给我"帮我看看AI新闻"
|
|
720
|
-
const parsed = scheduler.parseNaturalSchedule(trimmed);
|
|
721
|
-
if (parsed) {
|
|
722
|
-
const ds = larkAppId ? activeSessions.get(sessionKey(rootId, larkAppId)) : undefined;
|
|
723
|
-
const workingDir = resolveScheduleWorkingDir(ds, chatId, larkAppId);
|
|
724
|
-
const capturedScope = ds?.scope === 'chat' ? 'chat' : 'thread';
|
|
725
|
-
const capturedRootMessageId = capturedScope === 'thread' ? rootId : undefined;
|
|
726
|
-
const { executionPosition: requestedPosition, silent, prompt: schedPrompt } = scheduler.extractScheduleModifiers(parsed.prompt);
|
|
727
|
-
const executionPosition = requestedPosition
|
|
728
|
-
?? (capturedScope === 'thread' ? 'topic' : 'top-level');
|
|
729
|
-
const taskScope = executionPosition === 'topic' ? 'thread' : 'chat';
|
|
730
|
-
const schedName = schedPrompt !== parsed.prompt
|
|
731
|
-
? (schedPrompt.length > 20 ? schedPrompt.slice(0, 20) + '...' : schedPrompt)
|
|
732
|
-
: parsed.name;
|
|
733
|
-
const task = scheduler.addTask({
|
|
734
|
-
name: schedName,
|
|
735
|
-
schedule: trimmed,
|
|
736
|
-
parsed: parsed.parsed,
|
|
737
|
-
prompt: schedPrompt,
|
|
738
|
-
workingDir,
|
|
739
|
-
chatId,
|
|
740
|
-
// Retain the captured root even when top-level is selected so the task
|
|
741
|
-
// can later switch back to topic execution without losing its anchor.
|
|
742
|
-
rootMessageId: capturedRootMessageId,
|
|
743
|
-
scope: taskScope,
|
|
744
|
-
executionPosition,
|
|
745
|
-
chatType: ds?.chatType === 'p2p' ? 'p2p' : 'topic_group',
|
|
746
|
-
larkAppId,
|
|
747
|
-
deliver: 'origin',
|
|
748
|
-
silent,
|
|
749
|
-
});
|
|
750
|
-
const next = scheduler.getNextRun(task.id);
|
|
751
|
-
const nextStr = next ? next.toLocaleString(timeLocale, { timeZone }) : 'N/A';
|
|
752
|
-
const createdMsg = t('schedule.created', {
|
|
753
|
-
id: task.id,
|
|
754
|
-
name: task.name,
|
|
755
|
-
rule: parsed.parsed.display,
|
|
756
|
-
prompt: task.prompt,
|
|
757
|
-
dir: expandHome(workingDir),
|
|
758
|
-
next: nextStr,
|
|
759
|
-
}, loc);
|
|
760
|
-
const positionNote = '\n' + t(executionPosition === 'new-topic'
|
|
761
|
-
? 'schedule.deliver_new_topic'
|
|
762
|
-
: executionPosition === 'top-level'
|
|
763
|
-
? 'schedule.position_top_level'
|
|
764
|
-
: 'schedule.position_topic', undefined, loc);
|
|
765
|
-
const silentNote = silent ? '\n' + t('schedule.silent_note', undefined, loc) : '';
|
|
766
|
-
await sessionReply(rootId, createdMsg + positionNote + silentNote);
|
|
767
|
-
return;
|
|
768
|
-
}
|
|
769
|
-
// Unrecognized format
|
|
770
|
-
await sessionReply(rootId, t('schedule.parse_failed', undefined, loc));
|
|
771
|
-
}
|
|
772
|
-
// ─── Config command ──────────────────────────────────────────────────────────
|
|
773
|
-
function configEffectNote(effect, loc) {
|
|
774
|
-
return effect === 'immediate'
|
|
775
|
-
? t('cmd.config.effect_immediate', undefined, loc)
|
|
776
|
-
: t('cmd.config.effect_next_session', undefined, loc);
|
|
777
|
-
}
|
|
778
|
-
/** `/botconfig zh|en`(及常见别名)→ 卡片显示语言;非语言参数 → undefined(按子命令走)。 */
|
|
779
|
-
function cardLocaleArg(sub) {
|
|
780
|
-
if (!sub)
|
|
781
|
-
return undefined;
|
|
782
|
-
if (sub === 'zh' || sub === 'cn' || sub === '中文' || sub === '中')
|
|
783
|
-
return 'zh';
|
|
784
|
-
if (sub === 'en' || sub === 'english' || sub === '英文' || sub === '英')
|
|
785
|
-
return 'en';
|
|
786
|
-
return undefined;
|
|
787
|
-
}
|
|
788
|
-
function buildConfigHelp(loc) {
|
|
789
|
-
const fields = CONFIG_FIELDS.map(f => `• ${f.key} — ${f.hint}`).join('\n');
|
|
790
|
-
return t('cmd.config.help', { fields }, loc);
|
|
791
|
-
}
|
|
792
|
-
function buildConfigSnapshot(larkAppId, loc) {
|
|
793
|
-
const snap = getConfigSnapshot(larkAppId);
|
|
794
|
-
if (!snap.ok)
|
|
795
|
-
return t('cmd.config.no_bot', undefined, loc);
|
|
796
|
-
const lines = snap.rows.map(r => `• ${r.key} = ${r.value}`).join('\n');
|
|
797
|
-
return t('cmd.config.snapshot', {
|
|
798
|
-
cli: snap.info.cliId,
|
|
799
|
-
brand: snap.info.brand,
|
|
800
|
-
admins: snap.info.resolvedAdmins,
|
|
801
|
-
dirs: snap.info.workingDirs.join(', ') || '∅',
|
|
802
|
-
fields: lines,
|
|
803
|
-
}, loc);
|
|
804
|
-
}
|
|
805
|
-
/**
|
|
806
|
-
* `/botconfig set allowedUsers ...` —— 动信任根的敏感路径,与普通字段分开:
|
|
807
|
-
* 末尾的 `确认`/`confirm` 才真正落盘;缺确认 → 回显预览要求二次确认。
|
|
808
|
-
* 非法条目(裸邮箱前缀等)先挡;防自锁 / 解析空由 {@link setBotAllowedUsers} 兜底。
|
|
809
|
-
*/
|
|
810
|
-
async function applyAllowedUsersSet(tokens, rootId, larkAppId, senderId, deps, loc) {
|
|
811
|
-
const reply = (c) => deps.sessionReply(rootId, c, undefined, larkAppId);
|
|
812
|
-
let list = [...tokens];
|
|
813
|
-
let confirmed = false;
|
|
814
|
-
if (list.length && /^(confirm|确认|yes|--yes)$/i.test(list[list.length - 1])) {
|
|
815
|
-
confirmed = true;
|
|
816
|
-
list = list.slice(0, -1);
|
|
817
|
-
}
|
|
818
|
-
const entries = list.join(' ').split(/[,\s]+/).map(s => s.trim()).filter(Boolean);
|
|
819
|
-
if (entries.length === 0) {
|
|
820
|
-
await reply(t('cmd.config.allow_usage', undefined, loc));
|
|
821
|
-
return;
|
|
822
|
-
}
|
|
823
|
-
const invalid = findInvalidAllowedUserEntries(entries);
|
|
824
|
-
if (invalid.length) {
|
|
825
|
-
await reply(t('cmd.config.allow_invalid', { items: invalid.join(', ') }, loc));
|
|
826
|
-
return;
|
|
827
|
-
}
|
|
828
|
-
if (!confirmed) {
|
|
829
|
-
await reply(t('cmd.config.allow_confirm', { list: entries.join(', ') }, loc));
|
|
830
|
-
return;
|
|
831
|
-
}
|
|
832
|
-
const r = await setBotAllowedUsers(larkAppId, entries, senderId);
|
|
833
|
-
if (!r.ok) {
|
|
834
|
-
if (r.reason === 'self_lockout') {
|
|
835
|
-
await reply(t('cmd.config.allow_lockout', undefined, loc));
|
|
836
|
-
return;
|
|
837
|
-
}
|
|
838
|
-
if (r.reason === 'empty_resolved') {
|
|
839
|
-
await reply(t('cmd.config.allow_empty', undefined, loc));
|
|
840
|
-
return;
|
|
841
|
-
}
|
|
842
|
-
await reply(t('cmd.config.write_failed', { reason: r.reason }, loc));
|
|
843
|
-
return;
|
|
844
|
-
}
|
|
845
|
-
await reply(t('cmd.config.allow_ok', { count: r.resolved.length, total: r.raw.length }, loc));
|
|
846
|
-
}
|
|
847
|
-
/**
|
|
848
|
-
* `/botconfig` —— owner/allowedUsers 远程改本 bot 运营字段。sessionless:只认 larkAppId,
|
|
849
|
-
* 不需活跃会话。严格 admin 闸(拒绝开放模式 bot),写盘 + 内存热更新,无需重启。
|
|
850
|
-
*/
|
|
851
|
-
async function handleConfigCommand(message, rootId, larkAppId, deps) {
|
|
852
|
-
const loc = localeForBot(larkAppId);
|
|
853
|
-
const reply = (c) => deps.sessionReply(rootId, c, undefined, larkAppId);
|
|
854
|
-
const senderId = message.senderId;
|
|
855
|
-
// Admin 闸:严格限定 allowedUsers,**拒绝开放模式**(无 allowlist 的 bot 没有可
|
|
856
|
-
// 授权的 owner,不能凭聊天改配置)。上游 canOperate 对开放模式 / 兄弟 bot 也放行,
|
|
857
|
-
// 改配置比一般 daemon 命令敏感,这里收紧到「本 bot 的 allowedUsers」。
|
|
858
|
-
let bot;
|
|
859
|
-
try {
|
|
860
|
-
bot = getBot(larkAppId);
|
|
861
|
-
}
|
|
862
|
-
catch {
|
|
863
|
-
await reply(t('cmd.config.no_bot', undefined, loc));
|
|
864
|
-
return;
|
|
865
|
-
}
|
|
866
|
-
const admins = bot.resolvedAllowedUsers;
|
|
867
|
-
if (admins.length === 0) {
|
|
868
|
-
await reply(t('cmd.config.no_owner', undefined, loc));
|
|
869
|
-
return;
|
|
870
|
-
}
|
|
871
|
-
if (!senderId || !admins.includes(senderId)) {
|
|
872
|
-
await reply(t('cmd.config.not_admin', undefined, loc));
|
|
873
|
-
return;
|
|
874
|
-
}
|
|
875
|
-
const trimmed = message.content.replace(/^\/botconfig\s*/i, '').trim();
|
|
876
|
-
const parts = trimmed ? trimmed.split(/\s+/) : [];
|
|
877
|
-
const sub = parts[0]?.toLowerCase();
|
|
878
|
-
// 裸 /botconfig → 交互配置卡片;`/botconfig zh|en` → 指定卡片显示语言(覆盖 bot 默认)。
|
|
879
|
-
const cardLoc = cardLocaleArg(sub);
|
|
880
|
-
if (!sub || cardLoc) {
|
|
881
|
-
const renderLoc = cardLoc ?? loc;
|
|
882
|
-
// ttadk 网关 bot:模型候选用 ttadk 网关模型(glm-5.1…),不是底层适配器的
|
|
883
|
-
// opus/gpt-5(那会被 worker 注入成 `ttadk -m opus` 用错模型启动失败);CoCo 无候选。
|
|
884
|
-
// 非 ttadk(返回 null)才回落底层适配器自己的 modelChoices。
|
|
885
|
-
const ttadkChoices = ttadkConfigModelChoices(bot.config.wrapperCli);
|
|
886
|
-
let modelChoices = ttadkChoices ?? [];
|
|
887
|
-
if (ttadkChoices === null) {
|
|
888
|
-
try {
|
|
889
|
-
modelChoices = createCliAdapterSync(bot.config.cliId, bot.config.cliPathOverride).modelChoices ?? [];
|
|
890
|
-
}
|
|
891
|
-
catch { /* 无候选 → 不渲染 model 下拉 */ }
|
|
892
|
-
}
|
|
893
|
-
const data = getConfigCardData(larkAppId, modelChoices);
|
|
894
|
-
if (!data) {
|
|
895
|
-
await reply(buildConfigHelp(renderLoc));
|
|
896
|
-
return;
|
|
897
|
-
}
|
|
898
|
-
const cardJson = buildConfigCard(data, renderLoc);
|
|
899
|
-
// 始终把卡片**私信**给 owner,群里不留任何回复:
|
|
900
|
-
// • 私聊(单发给 bot)→ sendUserMessage 落在当前私聊 = 直接返回配置;
|
|
901
|
-
// • 群 / 话题群 → 卡片落在 owner 私聊,群内不产生「话题回复」、也只他可见。
|
|
902
|
-
// 不再依赖 getChatModeStrict(它会偶发 500 → 误判)。
|
|
903
|
-
// 私信失败(owner 从未与 bot 开过单聊等):**绝不**把整张配置卡回退到会话内——
|
|
904
|
-
// 在群/话题群里那会让 owner-only 的运营配置卡全员可见(按钮虽仍重验 admin 无法提权,
|
|
905
|
-
// 但卡片本身就违背「始终私信」意图)。只回一句简短文字引导去单聊后重试。
|
|
906
|
-
try {
|
|
907
|
-
await sendUserMessage(larkAppId, senderId, cardJson, 'interactive');
|
|
908
|
-
}
|
|
909
|
-
catch {
|
|
910
|
-
await reply(t('cmd.config.card_dm_failed', undefined, renderLoc));
|
|
911
|
-
}
|
|
912
|
-
return;
|
|
913
|
-
}
|
|
914
|
-
if (sub === 'help' || sub === '帮助') {
|
|
915
|
-
await reply(buildConfigHelp(loc));
|
|
916
|
-
return;
|
|
917
|
-
}
|
|
918
|
-
if (sub === 'get' || sub === 'show' || sub === 'list' || sub === '查看') {
|
|
919
|
-
await reply(buildConfigSnapshot(larkAppId, loc));
|
|
920
|
-
return;
|
|
921
|
-
}
|
|
922
|
-
if (sub === 'set' || sub === 'unset') {
|
|
923
|
-
const fieldKey = parts[1];
|
|
924
|
-
if (!fieldKey) {
|
|
925
|
-
await reply(t('cmd.config.set_usage', undefined, loc));
|
|
926
|
-
return;
|
|
927
|
-
}
|
|
928
|
-
const spec = findConfigField(fieldKey);
|
|
929
|
-
if (!spec) {
|
|
930
|
-
await reply(t('cmd.config.unknown_field', { field: fieldKey, fields: settableFieldKeys().join(', ') }, loc));
|
|
931
|
-
return;
|
|
932
|
-
}
|
|
933
|
-
if (sub === 'unset') {
|
|
934
|
-
if (!spec.clearable) {
|
|
935
|
-
await reply(t('cmd.config.not_clearable', { field: spec.key }, loc));
|
|
936
|
-
return;
|
|
937
|
-
}
|
|
938
|
-
const r = await applyConfigField(larkAppId, spec, null);
|
|
939
|
-
if (!r.ok) {
|
|
940
|
-
await reply(t('cmd.config.write_failed', { reason: r.reason }, loc));
|
|
941
|
-
return;
|
|
942
|
-
}
|
|
943
|
-
await reply(t('cmd.config.unset_ok', { field: spec.key, old: r.oldText, effect: configEffectNote(r.effect, loc) }, loc));
|
|
944
|
-
return;
|
|
945
|
-
}
|
|
946
|
-
// set
|
|
947
|
-
if (spec.kind === 'allowedUsers') {
|
|
948
|
-
await applyAllowedUsersSet(parts.slice(2), rootId, larkAppId, senderId, deps, loc);
|
|
949
|
-
return;
|
|
950
|
-
}
|
|
951
|
-
const rawValue = parts.slice(2).join(' ').trim();
|
|
952
|
-
if (!rawValue) {
|
|
953
|
-
await reply(t('cmd.config.value_required', { field: spec.key }, loc));
|
|
954
|
-
return;
|
|
955
|
-
}
|
|
956
|
-
let value;
|
|
957
|
-
switch (spec.kind) {
|
|
958
|
-
case 'stringList': {
|
|
959
|
-
// 与 card/config-store 路径(bot-config-store.ts 的 coerce)同口径:优先用
|
|
960
|
-
// 字段自带的 parseList——canTalkDaemonCommands / startupCommands 的解析规则
|
|
961
|
-
// 与默认的 parseCustomPassthroughInput 相反或不同,硬编码默认解析器会把
|
|
962
|
-
// 合法输入静默滤光成"空值"。
|
|
963
|
-
const arr = (spec.parseList ?? parseCustomPassthroughInput)(rawValue);
|
|
964
|
-
if (arr.length === 0) {
|
|
965
|
-
await reply(t('cmd.config.value_required', { field: spec.key }, loc));
|
|
966
|
-
return;
|
|
967
|
-
}
|
|
968
|
-
value = arr;
|
|
969
|
-
break;
|
|
970
|
-
}
|
|
971
|
-
case 'number': {
|
|
972
|
-
// 统一走 coerceConfigValue 的 number 校验(正整数),避免文字路径把 '6'
|
|
973
|
-
// 当字符串写进 maxLiveWorkers(与 card/API 路径同口径)。
|
|
974
|
-
const coerced = coerceConfigValue(spec, rawValue);
|
|
975
|
-
if (!coerced.ok) {
|
|
976
|
-
await reply(t('cmd.config.invalid_number', { field: spec.key, value: rawValue }, loc));
|
|
977
|
-
return;
|
|
978
|
-
}
|
|
979
|
-
value = coerced.value;
|
|
980
|
-
break;
|
|
981
|
-
}
|
|
982
|
-
case 'boolean': {
|
|
983
|
-
const b = parseBooleanValue(rawValue);
|
|
984
|
-
if (b === undefined) {
|
|
985
|
-
await reply(t('cmd.config.invalid_bool', { field: spec.key, value: rawValue }, loc));
|
|
986
|
-
return;
|
|
987
|
-
}
|
|
988
|
-
value = b;
|
|
989
|
-
break;
|
|
990
|
-
}
|
|
991
|
-
case 'enum': {
|
|
992
|
-
const v = rawValue.toLowerCase();
|
|
993
|
-
if (!spec.enumValues?.includes(v)) {
|
|
994
|
-
await reply(t('cmd.config.invalid_enum', { field: spec.key, values: (spec.enumValues ?? []).join('|') }, loc));
|
|
995
|
-
return;
|
|
996
|
-
}
|
|
997
|
-
value = v;
|
|
998
|
-
break;
|
|
999
|
-
}
|
|
1000
|
-
case 'cli': {
|
|
1001
|
-
try {
|
|
1002
|
-
const id = resolveCliId(rawValue);
|
|
1003
|
-
if (!id) {
|
|
1004
|
-
await reply(t('cmd.config.value_required', { field: spec.key }, loc));
|
|
1005
|
-
return;
|
|
1006
|
-
}
|
|
1007
|
-
value = id;
|
|
1008
|
-
}
|
|
1009
|
-
catch (e) {
|
|
1010
|
-
await reply(t('cmd.config.invalid_cli', { msg: e?.message ?? String(e) }, loc));
|
|
1011
|
-
return;
|
|
1012
|
-
}
|
|
1013
|
-
break;
|
|
1014
|
-
}
|
|
1015
|
-
case 'dir': {
|
|
1016
|
-
const v = validateWorkingDir(rawValue, loc);
|
|
1017
|
-
if (!v.ok) {
|
|
1018
|
-
await reply(v.error);
|
|
1019
|
-
return;
|
|
1020
|
-
}
|
|
1021
|
-
value = rawValue; // 存原始(保留 ~),与 workingDir 落盘一致;使用处再 expandHome
|
|
1022
|
-
break;
|
|
1023
|
-
}
|
|
1024
|
-
case 'json': {
|
|
1025
|
-
const coerced = coerceConfigValue(spec, rawValue);
|
|
1026
|
-
if (!coerced.ok) {
|
|
1027
|
-
await reply(t('cmd.config.write_failed', { reason: coerced.reason }, loc));
|
|
1028
|
-
return;
|
|
1029
|
-
}
|
|
1030
|
-
value = coerced.value;
|
|
1031
|
-
break;
|
|
1032
|
-
}
|
|
1033
|
-
default: { // 'string'
|
|
1034
|
-
// 与 dashboard PUT 同口径:string 字段也过 coerceConfigValue(长度上限
|
|
1035
|
-
// maxLen 等约束在 spec 上,避免 IM 文本入口绕过校验)。
|
|
1036
|
-
const coerced = coerceConfigValue(spec, rawValue);
|
|
1037
|
-
if (!coerced.ok) {
|
|
1038
|
-
await reply(t('cmd.config.write_failed', { reason: coerced.reason }, loc));
|
|
1039
|
-
return;
|
|
1040
|
-
}
|
|
1041
|
-
value = coerced.value;
|
|
1042
|
-
}
|
|
1043
|
-
}
|
|
1044
|
-
const r = await applyConfigField(larkAppId, spec, value);
|
|
1045
|
-
if (!r.ok) {
|
|
1046
|
-
await reply(t('cmd.config.write_failed', { reason: r.reason }, loc));
|
|
1047
|
-
return;
|
|
1048
|
-
}
|
|
1049
|
-
await reply(t('cmd.config.set_ok', { field: spec.key, old: r.oldText, new: r.newText, effect: configEffectNote(r.effect, loc) }, loc));
|
|
1050
|
-
return;
|
|
1051
|
-
}
|
|
1052
|
-
await reply(t('cmd.config.unknown_sub', { sub }, loc));
|
|
1053
|
-
}
|
|
1054
|
-
// ─── Main command handler ────────────────────────────────────────────────────
|
|
1055
|
-
/**
|
|
1056
|
-
* Handle `/card` (operator-only). Resolves the active session itself, so off/on
|
|
1057
|
-
* work WITHOUT one -- they only toggle the per-chat `noCardChats` config. A
|
|
1058
|
-
* summon (show/bare) needs a live session.
|
|
1059
|
-
*
|
|
1060
|
-
* off -> suppress the live streaming card for this chat (add to noCardChats);
|
|
1061
|
-
* status falls back to master's pending-card morph.
|
|
1062
|
-
* on -> restore cards for this chat (remove from noCardChats).
|
|
1063
|
-
* ''/show -> summon a live card. privateCard -> private ephemeral snapshot
|
|
1064
|
-
* (fail closed on non-group); otherwise a group-visible live card.
|
|
1065
|
-
* off/on also clear `streamingCardForced` so a prior summon does not
|
|
1066
|
-
* short-circuit `streamingCardDisabled()`.
|
|
1067
|
-
*/
|
|
1068
|
-
export async function handleCardCommand(rootId, larkAppId, chatId, senderOpenId, content, deps) {
|
|
1069
|
-
const loc = localeForBot(larkAppId);
|
|
1070
|
-
const reply = (c) => deps.sessionReply(rootId, c, undefined, larkAppId);
|
|
1071
|
-
// /card is an operator command — gate on canOperate, the same model every other
|
|
1072
|
-
// daemon command uses. Open mode (no owner/allowlist) → canOperate passes for
|
|
1073
|
-
// everyone; configured → any allowedUser (owner or co-owner); talk-only grantees
|
|
1074
|
-
// (chatGrant/globalGrant/oncall members) are never operators.
|
|
1075
|
-
if (!canOperate(larkAppId, chatId, senderOpenId)) {
|
|
1076
|
-
await reply(t('cmd.card.operator_only', undefined, loc));
|
|
1077
|
-
return;
|
|
1078
|
-
}
|
|
1079
|
-
const ds = deps.activeSessions.get(sessionKey(rootId, larkAppId));
|
|
1080
|
-
const sub = content.replace(/^\/card\s*/i, '').trim().toLowerCase();
|
|
1081
|
-
if (sub === 'off') {
|
|
1082
|
-
const r = await setCardMode(larkAppId, chatId, true);
|
|
1083
|
-
if (ds)
|
|
1084
|
-
ds.streamingCardForced = undefined;
|
|
1085
|
-
await reply(r.ok ? t('cmd.card.off_ok', undefined, loc) : t('cmd.card.fail', { reason: r.reason }, loc));
|
|
1086
|
-
return;
|
|
1087
|
-
}
|
|
1088
|
-
if (sub === 'on') {
|
|
1089
|
-
const r = await setCardMode(larkAppId, chatId, false);
|
|
1090
|
-
if (ds)
|
|
1091
|
-
ds.streamingCardForced = undefined;
|
|
1092
|
-
await reply(r.ok ? t('cmd.card.on_ok', undefined, loc) : t('cmd.card.fail', { reason: r.reason }, loc));
|
|
1093
|
-
return;
|
|
1094
|
-
}
|
|
1095
|
-
if (sub === '' || sub === 'show') {
|
|
1096
|
-
if (!ds) {
|
|
1097
|
-
await reply(t('cmd.no_active_session', undefined, loc));
|
|
1098
|
-
return;
|
|
1099
|
-
}
|
|
1100
|
-
if (getBot(ds.larkAppId).config.privateCard) {
|
|
1101
|
-
const mode = await getChatModeStrict(ds.larkAppId, ds.chatId);
|
|
1102
|
-
if (mode !== 'group') {
|
|
1103
|
-
await reply(t('cmd.card.private_not_group', undefined, loc));
|
|
1104
|
-
return;
|
|
1105
|
-
}
|
|
1106
|
-
const audience = resolvePrivateCardAudience(ds);
|
|
1107
|
-
if (audience.length === 0) {
|
|
1108
|
-
await reply(t('cmd.card.private_no_audience', undefined, loc));
|
|
1109
|
-
return;
|
|
1110
|
-
}
|
|
1111
|
-
const r = await postPrivateSnapshotCard(ds, audience);
|
|
1112
|
-
if (r.notReady) {
|
|
1113
|
-
await reply(t('cmd.card.private_not_ready', undefined, loc));
|
|
1114
|
-
}
|
|
1115
|
-
else if (r.sent === 0) {
|
|
1116
|
-
await reply(t('cmd.card.private_failed', undefined, loc));
|
|
1117
|
-
}
|
|
1118
|
-
else if (r.sent < r.total) {
|
|
1119
|
-
await reply(t('cmd.card.private_partial', { sent: r.sent, total: r.total }, loc));
|
|
1120
|
-
}
|
|
1121
|
-
return;
|
|
1122
|
-
}
|
|
1123
|
-
ds.streamingCardForced = true;
|
|
1124
|
-
const posted = await postFreshStreamingCard(ds, deps.sessionReply);
|
|
1125
|
-
if (!posted)
|
|
1126
|
-
await reply(t('cmd.card.not_ready', undefined, loc));
|
|
1127
|
-
return;
|
|
1128
|
-
}
|
|
1129
|
-
await reply(t('cmd.card.usage', undefined, loc));
|
|
1130
|
-
}
|
|
1131
|
-
/**
|
|
1132
|
-
* Handle `/term` (operator-only) — the slash-command twin of the "🔑 获取操作链接"
|
|
1133
|
-
* card button. Privately hands the operator a writable (token-bearing) terminal
|
|
1134
|
-
* card: an in-chat visible-to-you ephemeral card in plain groups, auto-falling back
|
|
1135
|
-
* to a DM in topic / p2p chats. The link rides only that private channel — never the
|
|
1136
|
-
* group. Gated identically to /card (`canOperate`), and strictly needs a live
|
|
1137
|
-
* session whose terminal is up. Routed for both the new-topic path (daemon.ts) and
|
|
1138
|
-
* the existing-session switch below.
|
|
1139
|
-
*/
|
|
1140
|
-
export async function handleTermLinkCommand(rootId, larkAppId, chatId, senderOpenId, _content, deps) {
|
|
1141
|
-
const loc = localeForBot(larkAppId);
|
|
1142
|
-
const reply = (c) => deps.sessionReply(rootId, c, undefined, larkAppId);
|
|
1143
|
-
// /term is an operator command that hands out a *writable* terminal link — gate
|
|
1144
|
-
// on canOperate (same model as other daemon commands). senderOpenId must be
|
|
1145
|
-
// present: open-mode canOperate passes even an undefined sender, but the writable
|
|
1146
|
-
// card is delivered privately to that exact open_id.
|
|
1147
|
-
if (!senderOpenId || !canOperate(larkAppId, chatId, senderOpenId)) {
|
|
1148
|
-
await reply(t('cmd.term.operator_only', undefined, loc));
|
|
1149
|
-
return;
|
|
1150
|
-
}
|
|
1151
|
-
const ds = deps.activeSessions.get(sessionKey(rootId, larkAppId));
|
|
1152
|
-
if (!ds) {
|
|
1153
|
-
await reply(t('cmd.term.no_session', undefined, loc));
|
|
1154
|
-
return;
|
|
1155
|
-
}
|
|
1156
|
-
const channel = await deliverWritableTerminalCardTo(ds, senderOpenId);
|
|
1157
|
-
if (channel === 'unsupported') {
|
|
1158
|
-
await reply(t('cmd.term.unsupported', undefined, loc));
|
|
1159
|
-
}
|
|
1160
|
-
else if (channel === 'not_ready') {
|
|
1161
|
-
await reply(t('cmd.term.not_ready', undefined, loc));
|
|
1162
|
-
}
|
|
1163
|
-
else if (channel === 'failed') {
|
|
1164
|
-
await reply(t('cmd.term.failed', undefined, loc));
|
|
1165
|
-
}
|
|
1166
|
-
else if (channel === 'dm') {
|
|
1167
|
-
// The card landed in DM (topic / p2p) — nothing showed in the topic, so drop a
|
|
1168
|
-
// visible breadcrumb pointing the owner at their DM. (No token, safe to show.)
|
|
1169
|
-
await reply(t('cmd.term.sent_dm', undefined, loc));
|
|
1170
|
-
}
|
|
1171
|
-
// channel === 'ephemeral': the visible-to-you card IS the response; no extra msg.
|
|
1172
|
-
}
|
|
1173
|
-
/** Format a SafeInsightReport into a compact owner-facing summary for the
|
|
1174
|
-
* `/insight` command. Spans are never rendered here — the dashboard Insight tab
|
|
1175
|
-
* owns span detail; the chat card stays a one-glance summary (aggregate + the
|
|
1176
|
-
* severity-sorted rule suggestions, top first). */
|
|
1177
|
-
function formatInsightCard(report, loc) {
|
|
1178
|
-
if (report.status === 'unsupported_cli')
|
|
1179
|
-
return t('cmd.insight.unsupported', undefined, loc);
|
|
1180
|
-
if (report.status === 'transcript_missing')
|
|
1181
|
-
return t('cmd.insight.no_transcript', undefined, loc);
|
|
1182
|
-
if (report.status !== 'ok')
|
|
1183
|
-
return t('cmd.insight.parse_error', undefined, loc);
|
|
1184
|
-
const a = report.agg;
|
|
1185
|
-
if (a.totalSpans === 0)
|
|
1186
|
-
return t('cmd.insight.no_spans', undefined, loc);
|
|
1187
|
-
const icon = (s) => (s === 'bad' ? '🔴' : s === 'warn' ? '🟡' : 'ℹ️');
|
|
1188
|
-
const header = t('cmd.insight.header', undefined, loc);
|
|
1189
|
-
const lines = [report.meta.asOf ? `${header} · ${report.meta.asOf}` : header];
|
|
1190
|
-
lines.push(t('cmd.insight.metrics_line', {
|
|
1191
|
-
total: String(a.totalSpans),
|
|
1192
|
-
failed: String(a.failedSpans),
|
|
1193
|
-
slow: String(a.slowSpans),
|
|
1194
|
-
rw: a.readWriteRatio === null ? '—' : String(a.readWriteRatio),
|
|
1195
|
-
compactions: String(a.compactions),
|
|
1196
|
-
}, loc));
|
|
1197
|
-
lines.push('', `${t('cmd.insight.suggestions_label', undefined, loc)}:`);
|
|
1198
|
-
for (const s of report.suggestions) {
|
|
1199
|
-
lines.push(`${icon(s.severity)} ${s.title} — ${s.action}`);
|
|
1200
|
-
if (s.evidence.length)
|
|
1201
|
-
lines.push(` · ${s.evidence.join(';')}`);
|
|
1202
|
-
}
|
|
1203
|
-
return lines.join('\n');
|
|
1204
|
-
}
|
|
1205
|
-
export async function handleCommand(cmd, rootId, message, deps, larkAppId) {
|
|
1206
|
-
const { activeSessions, getActiveCount, lastRepoScan } = deps;
|
|
1207
|
-
// Command replies carry the triggering messageId as the turnId so a shared
|
|
1208
|
-
// (chat-scope) session triggered from inside a Lark thread anchors them into
|
|
1209
|
-
// that thread (resolveSessionReplyTarget turnId gate) instead of leaking a
|
|
1210
|
-
// plain top-level message.
|
|
1211
|
-
const sessionReply = (rid, content, msgType) => deps.sessionReply(rid, content, msgType, larkAppId, message.messageId);
|
|
1212
|
-
const ds = larkAppId ? activeSessions.get(sessionKey(rootId, larkAppId)) : undefined;
|
|
1213
|
-
const logTag = ds ? tag(ds) : rootId.substring(0, 12);
|
|
1214
|
-
const loc = localeForBot(ds?.larkAppId ?? larkAppId);
|
|
1215
|
-
logger.info(`[${logTag}] Command: ${cmd}`);
|
|
1216
|
-
logger.debug(`repo command`, message);
|
|
1217
|
-
try {
|
|
1218
|
-
switch (cmd) {
|
|
1219
|
-
case '/close': {
|
|
1220
|
-
if (ds) {
|
|
1221
|
-
// Capture the closed-session card BEFORE killWorker/closeSession —
|
|
1222
|
-
// it reads the live session's identity off `ds`.
|
|
1223
|
-
const card = buildClosedSessionCard(ds, loc);
|
|
1224
|
-
const activeKey = sessionKey(rootId, larkAppId);
|
|
1225
|
-
try {
|
|
1226
|
-
await closeSession(ds.session.sessionId);
|
|
1227
|
-
}
|
|
1228
|
-
catch (err) {
|
|
1229
|
-
logger.error(`[${logTag}] Refused /close because backing teardown was not verified: ${err}`);
|
|
1230
|
-
await sessionReply(rootId, `⚠️ 会话关闭失败,已保留 active 记录以便重试:${err instanceof Error ? err.message : String(err)}`);
|
|
1231
|
-
break;
|
|
1232
|
-
}
|
|
1233
|
-
if (activeSessions.get(activeKey) === ds)
|
|
1234
|
-
activeSessions.delete(activeKey);
|
|
1235
|
-
// 「会话已关闭」卡片优先「仅自己可见」:普通群里走 ephemeral 只发给执行
|
|
1236
|
-
// /close 的本人;话题群不支持 ephemeral(18053) 时回退为正常的群内可见回复
|
|
1237
|
-
// ——与流式卡片上「关闭会话」按钮的送达方式保持一致。
|
|
1238
|
-
await deliverEphemeralOrReply(ds, message.senderId, card, 'interactive', () => sessionReply(rootId, card, 'interactive'));
|
|
1239
|
-
logger.info(`[${logTag}] Session closed by /close command`);
|
|
1240
|
-
}
|
|
1241
|
-
else {
|
|
1242
|
-
await sessionReply(rootId, t('cmd.no_active_session', undefined, loc));
|
|
1243
|
-
}
|
|
1244
|
-
break;
|
|
1245
|
-
}
|
|
1246
|
-
case '/insight': {
|
|
1247
|
-
if (!ds) {
|
|
1248
|
-
await sessionReply(rootId, t('cmd.no_active_session', undefined, loc));
|
|
1249
|
-
break;
|
|
1250
|
-
}
|
|
1251
|
-
// owner-only:与 /card /term 同一 operator 门(开放模式下 owner 通过;
|
|
1252
|
-
// 仅对话授权的 grantee 不算 operator)。无权限直接不回内容。
|
|
1253
|
-
if (!canOperate(larkAppId, ds.chatId, message.senderId)) {
|
|
1254
|
-
await sessionReply(rootId, t('cmd.insight.operator_only', undefined, loc));
|
|
1255
|
-
break;
|
|
1256
|
-
}
|
|
1257
|
-
// 卡片只取 summary(聚合 + 规则建议);span 明细留给 dashboard Insight tab。
|
|
1258
|
-
// buildSafeInsightReport 同步、只读、自带 fail-closed 脱敏,raw 永不进结构。
|
|
1259
|
-
const report = buildSafeInsightReport({
|
|
1260
|
-
cliId: ds.session.cliId ?? 'unknown',
|
|
1261
|
-
sessionId: ds.session.sessionId,
|
|
1262
|
-
cliSessionId: ds.session.cliSessionId,
|
|
1263
|
-
cwd: ds.session.workingDir,
|
|
1264
|
-
larkAppId: ds.larkAppId ?? ds.session.larkAppId,
|
|
1265
|
-
}, { detail: 'summary' });
|
|
1266
|
-
await sessionReply(rootId, formatInsightCard(report, loc));
|
|
1267
|
-
break;
|
|
1268
|
-
}
|
|
1269
|
-
case '/detach':
|
|
1270
|
-
case '/disconnect': {
|
|
1271
|
-
// 文字版的"⏏ 断开"按钮:仅 adopt 会话适用——botmux 只是观察用户原本在
|
|
1272
|
-
// 跑的 CLI,断开只清掉 botmux 这一侧的 worker / polling,绝不结束 CLI
|
|
1273
|
-
// 进程本身。等价于 card-handler 里 `actionType === 'disconnect'` 那段。
|
|
1274
|
-
if (!ds) {
|
|
1275
|
-
await sessionReply(rootId, t('cmd.no_active_session', undefined, loc));
|
|
1276
|
-
break;
|
|
1277
|
-
}
|
|
1278
|
-
if (!ds.adoptedFrom) {
|
|
1279
|
-
await sessionReply(rootId, t('cmd.detach.not_adopted', undefined, loc));
|
|
1280
|
-
break;
|
|
1281
|
-
}
|
|
1282
|
-
const closedSessionId = ds.session.sessionId;
|
|
1283
|
-
killWorker(ds);
|
|
1284
|
-
sessionStore.closeSession(closedSessionId);
|
|
1285
|
-
publishClosedSessionPatch(closedSessionId, ds.session.closedAt ? Date.parse(ds.session.closedAt) : undefined);
|
|
1286
|
-
activeSessions.delete(sessionKey(rootId, larkAppId));
|
|
1287
|
-
await sessionReply(rootId, t('cmd.detach.success', undefined, loc));
|
|
1288
|
-
logger.info(`[${logTag}] Detached (adopt) by ${cmd} command`);
|
|
1289
|
-
break;
|
|
1290
|
-
}
|
|
1291
|
-
case '/restart': {
|
|
1292
|
-
if (ds) {
|
|
1293
|
-
if (ds.adoptedFrom) {
|
|
1294
|
-
await sessionReply(rootId, t('card.action.adopt_no_restart', undefined, loc));
|
|
1295
|
-
break;
|
|
1296
|
-
}
|
|
1297
|
-
if (isSessionTransferring(ds)) {
|
|
1298
|
-
await sessionReply(rootId, t('cmd.session.transfer_in_progress', undefined, loc));
|
|
1299
|
-
break;
|
|
1300
|
-
}
|
|
1301
|
-
const cliName = sessionCliDisplayName(ds);
|
|
1302
|
-
requestSessionRestart(ds, {
|
|
1303
|
-
source: 'slash',
|
|
1304
|
-
notify: async (status) => {
|
|
1305
|
-
await sessionReply(rootId, t(`cmd.restart.${status}`, { cliName }, loc));
|
|
1306
|
-
},
|
|
1307
|
-
});
|
|
1308
|
-
logger.info(`[${logTag}] Restart by /restart command`);
|
|
1309
|
-
}
|
|
1310
|
-
else {
|
|
1311
|
-
await sessionReply(rootId, t('cmd.no_active_session', undefined, loc));
|
|
1312
|
-
}
|
|
1313
|
-
break;
|
|
1314
|
-
}
|
|
1315
|
-
case '/cd': {
|
|
1316
|
-
const targetPath = message.content.replace(/^\/cd\s*/, '').trim();
|
|
1317
|
-
if (!targetPath) {
|
|
1318
|
-
await sessionReply(rootId, t('cmd.cd.usage', undefined, loc));
|
|
1319
|
-
break;
|
|
1320
|
-
}
|
|
1321
|
-
if (!ds) {
|
|
1322
|
-
await sessionReply(rootId, t('cmd.no_active_session', undefined, loc));
|
|
1323
|
-
break;
|
|
1324
|
-
}
|
|
1325
|
-
if (isSessionTransferring(ds)) {
|
|
1326
|
-
await sessionReply(rootId, t('cmd.session.transfer_in_progress', undefined, loc));
|
|
1327
|
-
break;
|
|
1328
|
-
}
|
|
1329
|
-
const validation = validateWorkingDir(targetPath, loc, { autoCreate: true });
|
|
1330
|
-
if (!validation.ok) {
|
|
1331
|
-
await sessionReply(rootId, validation.error);
|
|
1332
|
-
break;
|
|
1333
|
-
}
|
|
1334
|
-
const resolvedPath = validation.resolvedPath;
|
|
1335
|
-
// Persistent backends can cold-resume without treating a cwd switch as
|
|
1336
|
-
// a real session close. This also preserves a sandbox upper long enough
|
|
1337
|
-
// for the next worker to relocate Claude's cwd-scoped transcript.
|
|
1338
|
-
// Adopted sessions are observers of a user-owned CLI and keep the old
|
|
1339
|
-
// detach/kill behavior; PTY falls back to killWorker, while its normal
|
|
1340
|
-
// on-disk transcript remains available for the resume-sync preflight.
|
|
1341
|
-
const suspended = !ds.adoptedFrom && suspendWorker(ds, 'working_dir_changed');
|
|
1342
|
-
if (!suspended)
|
|
1343
|
-
killWorker(ds);
|
|
1344
|
-
repinSessionWorkingDir(ds, resolvedPath);
|
|
1345
|
-
if (validation.created) {
|
|
1346
|
-
await sessionReply(rootId, t('cmd.cd.created_switched', { path: resolvedPath }, loc));
|
|
1347
|
-
}
|
|
1348
|
-
else {
|
|
1349
|
-
await sessionReply(rootId, t('cmd.cd.switched', { path: resolvedPath }, loc));
|
|
1350
|
-
}
|
|
1351
|
-
logger.info(`[${logTag}] Working directory changed to ${resolvedPath} by /cd command${validation.created ? ' (auto-created)' : ''}`);
|
|
1352
|
-
break;
|
|
1353
|
-
}
|
|
1354
|
-
case '/rename': {
|
|
1355
|
-
if (!ds) {
|
|
1356
|
-
await sessionReply(rootId, t('cmd.no_active_session', undefined, loc));
|
|
1357
|
-
break;
|
|
1358
|
-
}
|
|
1359
|
-
const rawTitle = message.content.replace(/^\/rename\s*/i, '').trim();
|
|
1360
|
-
if (!rawTitle) {
|
|
1361
|
-
await sessionReply(rootId, t('cmd.rename.usage', undefined, loc));
|
|
1362
|
-
break;
|
|
1363
|
-
}
|
|
1364
|
-
const updated = updateSessionTitle(ds.session, rawTitle, 'user');
|
|
1365
|
-
if (!updated.ok) {
|
|
1366
|
-
await sessionReply(rootId, t('cmd.rename.usage', undefined, loc));
|
|
1367
|
-
break;
|
|
1368
|
-
}
|
|
1369
|
-
const agentSync = requestAgentSessionRename(ds, updated.title);
|
|
1370
|
-
const cliName = sessionCliDisplayName(ds);
|
|
1371
|
-
if (agentSync.status === 'requested') {
|
|
1372
|
-
await sessionReply(rootId, t('cmd.rename.updated_requested', { title: updated.title, cliName }, loc));
|
|
1373
|
-
}
|
|
1374
|
-
else if (agentSync.status === 'not_running') {
|
|
1375
|
-
await sessionReply(rootId, t('cmd.rename.updated_not_running', { title: updated.title }, loc));
|
|
1376
|
-
}
|
|
1377
|
-
else if (agentSync.status === 'unsupported') {
|
|
1378
|
-
await sessionReply(rootId, t('cmd.rename.updated_unsupported', { title: updated.title, cliName }, loc));
|
|
1379
|
-
}
|
|
1380
|
-
else {
|
|
1381
|
-
await sessionReply(rootId, t('cmd.rename.updated_failed', { title: updated.title, cliName }, loc));
|
|
1382
|
-
logger.warn(`[${logTag}] Native session rename request failed for ${cliName}: ${agentSync.error}`);
|
|
1383
|
-
}
|
|
1384
|
-
logger.info(`[${logTag}] Session renamed by /rename: ${updated.title} (agentSync=${agentSync.status})`);
|
|
1385
|
-
break;
|
|
1386
|
-
}
|
|
1387
|
-
case '/repo': {
|
|
1388
|
-
const repoArg = message.content.replace(/^\/repo\s*/, '').trim();
|
|
1389
|
-
// First-spawn fork: consume the buffered prompt/attachments and start the
|
|
1390
|
-
// CLI in whatever workingDir is currently set on the session. Shared by
|
|
1391
|
-
// `commitRepoSelection` (a repo was named) and the bare-`/repo` launch
|
|
1392
|
-
// (use the default workingDir) — both only run while `pendingRepo`.
|
|
1393
|
-
const forkPendingCli = async (replyText, claimAlready = false) => {
|
|
1394
|
-
if (!claimAlready) {
|
|
1395
|
-
if (ds.pendingRepoCommitInFlight) {
|
|
1396
|
-
await sessionReply(rootId, t('cmd.repo.worktree_in_progress', undefined, loc));
|
|
1397
|
-
return false;
|
|
1398
|
-
}
|
|
1399
|
-
ds.pendingRepoCommitInFlight = true;
|
|
1400
|
-
}
|
|
1401
|
-
const selfBot = getBot(ds.larkAppId);
|
|
1402
|
-
const botCfg = selfBot.config;
|
|
1403
|
-
const commitGenSessionId = ds.session.sessionId;
|
|
1404
|
-
let committed = false;
|
|
1405
|
-
try {
|
|
1406
|
-
// Keep pendingRepo=true while prompt context is awaited. Incoming
|
|
1407
|
-
// messages stay in the same buffer and card selections see the
|
|
1408
|
-
// shared in-flight claim instead of treating this as a repo switch.
|
|
1409
|
-
const initiallyBuffered = (ds.pendingPrompt?.trim().length ?? 0) > 0 ||
|
|
1410
|
-
(ds.pendingAttachments?.length ?? 0) > 0 ||
|
|
1411
|
-
(ds.pendingFollowUps?.length ?? 0) > 0 ||
|
|
1412
|
-
ds.pendingChatContext !== undefined;
|
|
1413
|
-
const availableBots = initiallyBuffered
|
|
1414
|
-
? await getAvailableBots(ds.larkAppId, ds.chatId)
|
|
1415
|
-
: [];
|
|
1416
|
-
const stillActive = activeSessions.get(sessionKey(rootId, larkAppId)) === ds;
|
|
1417
|
-
if (!stillActive || ds.session.sessionId !== commitGenSessionId ||
|
|
1418
|
-
!ds.pendingRepo || (ds.worker && !ds.worker.killed)) {
|
|
1419
|
-
logger.warn(`[${logTag}] Session changed while preparing the pending CLI (${commitGenSessionId} → ${ds.session.sessionId}, active=${stillActive}, pending=${!!ds.pendingRepo}, worker=${!!ds.worker})`);
|
|
1420
|
-
return false;
|
|
1421
|
-
}
|
|
1422
|
-
const pendingPrompt = ds.pendingPrompt ?? '';
|
|
1423
|
-
const pendingRawInput = ds.pendingRawInput;
|
|
1424
|
-
const hasBufferedInput = pendingPrompt.trim().length > 0 ||
|
|
1425
|
-
(ds.pendingAttachments?.length ?? 0) > 0 ||
|
|
1426
|
-
(ds.pendingFollowUps?.length ?? 0) > 0 ||
|
|
1427
|
-
ds.pendingChatContext !== undefined;
|
|
1428
|
-
// Nothing to submit at all (bare `/repo`: the message IS the command).
|
|
1429
|
-
// The CLI boots idle, so the user's NEXT real message is its first
|
|
1430
|
-
// turn and must carry the full new-topic opening — see
|
|
1431
|
-
// markInitialUserTurnPending below.
|
|
1432
|
-
const emptyStart = !pendingRawInput && !hasBufferedInput;
|
|
1433
|
-
if (hasBufferedInput)
|
|
1434
|
-
ensureSessionWhiteboard(ds);
|
|
1435
|
-
const wrappedInput = hasBufferedInput
|
|
1436
|
-
? buildNewTopicCliInput(pendingPrompt, ds.session.sessionId, ds.session.cliId ?? botCfg.cliId, ds.session.cliPathOverride ?? botCfg.cliPathOverride, ds.pendingAttachments, ds.pendingMentions, availableBots, ds.pendingFollowUps, { name: selfBot.botName, openId: selfBot.botOpenId }, loc, ds.pendingSender, {
|
|
1437
|
-
larkAppId,
|
|
1438
|
-
chatId: ds.chatId,
|
|
1439
|
-
whiteboardId: ds.session.whiteboardId,
|
|
1440
|
-
substituteTrigger: ds.pendingSubstituteTrigger,
|
|
1441
|
-
codexAppText: ds.pendingCodexAppText,
|
|
1442
|
-
codexAppApplicationContext: ds.pendingCodexAppApplicationContext,
|
|
1443
|
-
codexAppMessageContext: ds.pendingCodexAppMessageContext,
|
|
1444
|
-
codexAppFollowUps: ds.pendingCodexAppFollowUps,
|
|
1445
|
-
codexAppFollowUpContexts: ds.pendingCodexAppFollowUpContexts,
|
|
1446
|
-
chatContext: ds.pendingChatContext,
|
|
1447
|
-
})
|
|
1448
|
-
: { content: '' };
|
|
1449
|
-
const pendingTurnId = ds.pendingTurnId;
|
|
1450
|
-
const previousPendingFollowUpInput = ds.pendingFollowUpInput;
|
|
1451
|
-
if (pendingRawInput && hasBufferedInput) {
|
|
1452
|
-
ds.pendingFollowUpInput = {
|
|
1453
|
-
userPrompt: ds.pendingCodexAppText !== undefined || ds.pendingCodexAppFollowUps
|
|
1454
|
-
? [ds.pendingCodexAppText ?? '', ...(ds.pendingCodexAppFollowUps ?? [])].filter(Boolean).join('\n\n')
|
|
1455
|
-
: pendingPrompt || ds.pendingFollowUps?.join('\n\n') || '',
|
|
1456
|
-
cliInput: wrappedInput.content,
|
|
1457
|
-
...(ds.pendingFollowUpTurnId ? { turnId: ds.pendingFollowUpTurnId } : {}),
|
|
1458
|
-
...((ds.session.cliId ?? botCfg.cliId) === 'codex-app' && botCfg.codexAppCleanInput === true && wrappedInput.codexAppInput
|
|
1459
|
-
? { codexAppInput: wrappedInput.codexAppInput }
|
|
1460
|
-
: {}),
|
|
1461
|
-
codexAppInputGateFrozen: true,
|
|
1462
|
-
};
|
|
1463
|
-
}
|
|
1464
|
-
ds.pendingRepo = false;
|
|
1465
|
-
publishAttentionPatch(ds);
|
|
1466
|
-
try {
|
|
1467
|
-
if (pendingRawInput)
|
|
1468
|
-
forkWorker(ds, '', false);
|
|
1469
|
-
else if (pendingTurnId && hasBufferedInput)
|
|
1470
|
-
forkWorker(ds, wrappedInput, { turnId: pendingTurnId });
|
|
1471
|
-
else if (hasBufferedInput)
|
|
1472
|
-
forkWorker(ds, wrappedInput);
|
|
1473
|
-
else
|
|
1474
|
-
forkWorker(ds, '', false);
|
|
1475
|
-
}
|
|
1476
|
-
catch (e) {
|
|
1477
|
-
ds.pendingRepo = true;
|
|
1478
|
-
ds.pendingFollowUpInput = previousPendingFollowUpInput;
|
|
1479
|
-
publishAttentionPatch(ds);
|
|
1480
|
-
throw e;
|
|
1481
|
-
}
|
|
1482
|
-
if (pendingRawInput || hasBufferedInput) {
|
|
1483
|
-
rememberLastCliInput(ds, pendingRawInput ?? pendingPrompt, pendingRawInput ?? wrappedInput);
|
|
1484
|
-
}
|
|
1485
|
-
// Durable, one-shot: the CLI is up but has never received a real user
|
|
1486
|
-
// turn, so the next business message must be built as a NEW TOPIC
|
|
1487
|
-
// (routing + built-in skill discovery + identity), not a follow-up.
|
|
1488
|
-
// Set after the fork so a throwing fork leaves the session untouched.
|
|
1489
|
-
if (emptyStart)
|
|
1490
|
-
markInitialUserTurnPending(ds);
|
|
1491
|
-
ds.pendingPrompt = undefined;
|
|
1492
|
-
ds.pendingCodexAppText = undefined;
|
|
1493
|
-
ds.pendingCodexAppApplicationContext = undefined;
|
|
1494
|
-
ds.pendingCodexAppMessageContext = undefined;
|
|
1495
|
-
ds.pendingChatContext = undefined;
|
|
1496
|
-
ds.pendingAttachments = undefined;
|
|
1497
|
-
ds.pendingMentions = undefined;
|
|
1498
|
-
ds.pendingSubstituteTrigger = undefined;
|
|
1499
|
-
ds.pendingSender = undefined;
|
|
1500
|
-
ds.pendingFollowUps = undefined;
|
|
1501
|
-
ds.pendingCodexAppFollowUps = undefined;
|
|
1502
|
-
ds.pendingCodexAppFollowUpContexts = undefined;
|
|
1503
|
-
ds.pendingFollowUpTurnId = undefined;
|
|
1504
|
-
ds.pendingTurnId = undefined;
|
|
1505
|
-
committed = true;
|
|
1506
|
-
// Local one-shot consume BEFORE network awaits. Feishu withdraw is
|
|
1507
|
-
// best-effort; stale card clicks must be rejected via this mark even
|
|
1508
|
-
// if sessionReply throws or deleteMessage lags/fails.
|
|
1509
|
-
const cardToWithdraw = ds.repoCardMessageId;
|
|
1510
|
-
markRepoCardConsumed(ds, cardToWithdraw);
|
|
1511
|
-
ds.repoCardMessageId = undefined;
|
|
1512
|
-
// Hold the claim through confirmation + best-effort card withdraw.
|
|
1513
|
-
try {
|
|
1514
|
-
await sessionReply(rootId, replyText);
|
|
1515
|
-
}
|
|
1516
|
-
catch (e) {
|
|
1517
|
-
logger.warn(`[${logTag}] Confirm reply after pending repo commit failed: ${e instanceof Error ? e.message : e}`);
|
|
1518
|
-
}
|
|
1519
|
-
if (cardToWithdraw) {
|
|
1520
|
-
try {
|
|
1521
|
-
await deleteMessage(ds.larkAppId, cardToWithdraw);
|
|
1522
|
-
}
|
|
1523
|
-
catch { /* best-effort */ }
|
|
1524
|
-
}
|
|
1525
|
-
}
|
|
1526
|
-
finally {
|
|
1527
|
-
ds.pendingRepoCommitInFlight = false;
|
|
1528
|
-
}
|
|
1529
|
-
return committed;
|
|
1530
|
-
};
|
|
1531
|
-
// Shared commit path for an already-resolved repo: update the session's
|
|
1532
|
-
// working dir, then either fork into the pending CLI (first spawn) or
|
|
1533
|
-
// close + recreate the session (mid-session switch). Used by both the
|
|
1534
|
-
// numeric `/repo <N>` form and the `/repo <path|name>` form.
|
|
1535
|
-
const commitRepoSelection = async (selectedPath, displayName, how) => {
|
|
1536
|
-
if (ds.pendingRepo) {
|
|
1537
|
-
if (ds.pendingRepoCommitInFlight) {
|
|
1538
|
-
await sessionReply(rootId, t('cmd.repo.worktree_in_progress', undefined, loc));
|
|
1539
|
-
return false;
|
|
1540
|
-
}
|
|
1541
|
-
ds.pendingRepoCommitInFlight = true;
|
|
1542
|
-
try {
|
|
1543
|
-
// Claim before changing cwd so a card selection cannot overwrite
|
|
1544
|
-
// this choice while the pending prompt is prepared.
|
|
1545
|
-
ds.workingDir = selectedPath;
|
|
1546
|
-
ds.session.workingDir = selectedPath;
|
|
1547
|
-
ds.session.riffRepoDirs = undefined;
|
|
1548
|
-
sessionStore.updateSession(ds.session);
|
|
1549
|
-
// forkPendingCli owns claim release + confirm reply + card withdraw.
|
|
1550
|
-
if (!await forkPendingCli(t('cmd.repo.selected_in_pending', { name: displayName }, loc), true)) {
|
|
1551
|
-
return false;
|
|
1552
|
-
}
|
|
1553
|
-
}
|
|
1554
|
-
catch (e) {
|
|
1555
|
-
ds.pendingRepoCommitInFlight = false;
|
|
1556
|
-
throw e;
|
|
1557
|
-
}
|
|
1558
|
-
}
|
|
1559
|
-
else {
|
|
1560
|
-
// Safety net: a mid-session `/repo` switch closes the running
|
|
1561
|
-
// session and spawns a fresh one on the SAME anchor. Without a
|
|
1562
|
-
// trace, the old context silently vanishes (relay/adopt/resume all
|
|
1563
|
-
// hit `anchor_occupied` once the new session holds the anchor).
|
|
1564
|
-
// So, before displacing it, post the same "session closed" card
|
|
1565
|
-
// `/close` emits — it keeps the old session visible and carries the
|
|
1566
|
-
// terminal `claude --resume` command. (Its in-card resume button
|
|
1567
|
-
// still hits anchor_occupied while the new session occupies this
|
|
1568
|
-
// anchor — expected; `/close` the new one first, or use the
|
|
1569
|
-
// command.) Mirrors the `/close` case above.
|
|
1570
|
-
//
|
|
1571
|
-
// ZMX close is identity/generation verified and may refuse. Prove
|
|
1572
|
-
// teardown before claiming the card or mutating any state so a
|
|
1573
|
-
// refusal leaves the current session fully retryable.
|
|
1574
|
-
try {
|
|
1575
|
-
teardownAuthoritativePersistentBackingBeforeClose(ds);
|
|
1576
|
-
}
|
|
1577
|
-
catch (err) {
|
|
1578
|
-
const reason = err instanceof Error ? err.message : String(err);
|
|
1579
|
-
logger.warn(`[${logTag}] Repo switch refused because backing teardown was not proven: ${reason}`);
|
|
1580
|
-
await sessionReply(rootId, t('cmd.repo.switch_close_failed', { error: reason }, loc));
|
|
1581
|
-
return false;
|
|
1582
|
-
}
|
|
1583
|
-
// Claim any open repo card BEFORE killWorker / await so a concurrent
|
|
1584
|
-
// card click cannot double-switch while this text path runs.
|
|
1585
|
-
//
|
|
1586
|
-
// The new cwd is NOT written onto the old session here — it would
|
|
1587
|
-
// pollute the displaced session's stored workingDir (and the closed
|
|
1588
|
-
// card), so `claude --resume` later would reopen the old context in
|
|
1589
|
-
// the new repo's cwd. The new repo is pinned onto the fresh session
|
|
1590
|
-
// below instead.
|
|
1591
|
-
const claimedCard = claimCurrentRepoCard(ds, undefined);
|
|
1592
|
-
const oldSession = ds.session;
|
|
1593
|
-
const oldSessionId = oldSession.sessionId;
|
|
1594
|
-
const closedCard = buildClosedSessionCard(ds, loc);
|
|
1595
|
-
killWorker(ds);
|
|
1596
|
-
sessionStore.closeSession(ds.session.sessionId);
|
|
1597
|
-
publishClosedSessionPatch(ds.session.sessionId, ds.session.closedAt ? Date.parse(ds.session.closedAt) : undefined);
|
|
1598
|
-
await deliverEphemeralOrReply(ds, message.senderId, closedCard, 'interactive', () => sessionReply(rootId, closedCard, 'interactive'));
|
|
1599
|
-
const stillOwnsGeneration = activeSessions.get(sessionKey(rootId, larkAppId)) === ds
|
|
1600
|
-
&& ds.session === oldSession;
|
|
1601
|
-
if (!stillOwnsGeneration) {
|
|
1602
|
-
logger.warn(`[${logTag}] Repo switch cancelled after closing ${oldSessionId.substring(0, 8)}; routing generation changed during card delivery`);
|
|
1603
|
-
return false;
|
|
1604
|
-
}
|
|
1605
|
-
// `rootId` is the routing anchor. For chat-scope sessions it is the
|
|
1606
|
-
// `oc_...` chat id, not the traceable `om_...` message root stored on
|
|
1607
|
-
// Session. Preserve the old identity and explicitly persist scope so
|
|
1608
|
-
// repo switches cannot turn a chat session into a legacy scope-less
|
|
1609
|
-
// record that the CLI later mistakes for a thread.
|
|
1610
|
-
const session = sessionStore.createSession(ds.chatId, ds.scope === 'chat' ? oldSession.rootMessageId : rootId, displayName, ds.chatType, ds.scope);
|
|
1611
|
-
ds.session = session;
|
|
1612
|
-
ds.lastUserPrompt = undefined;
|
|
1613
|
-
ds.lastCliInput = undefined;
|
|
1614
|
-
ds.workingDir = selectedPath;
|
|
1615
|
-
ds.session.workingDir = selectedPath;
|
|
1616
|
-
ds.session.larkAppId = ds.larkAppId;
|
|
1617
|
-
ds.session.chatDisplayName = oldSession.chatDisplayName;
|
|
1618
|
-
ds.session.ownerOpenId = oldSession.ownerOpenId;
|
|
1619
|
-
ds.session.creatorOpenId = oldSession.creatorOpenId;
|
|
1620
|
-
ds.session.lastCallerOpenId = oldSession.lastCallerOpenId;
|
|
1621
|
-
sessionStore.updateSession(ds.session);
|
|
1622
|
-
ds.hasHistory = false;
|
|
1623
|
-
forkWorker(ds, '', false);
|
|
1624
|
-
// Brand-new CLI in a brand-new session record: it has never seen the
|
|
1625
|
-
// botmux opening context either, so the next real business message
|
|
1626
|
-
// is its new-topic first turn (same invariant as the pending path).
|
|
1627
|
-
markInitialUserTurnPending(ds);
|
|
1628
|
-
try {
|
|
1629
|
-
await sessionReply(rootId, t('cmd.repo.switched_to', { name: displayName }, loc));
|
|
1630
|
-
}
|
|
1631
|
-
catch (e) {
|
|
1632
|
-
logger.warn(`[${logTag}] Confirm reply after mid-session repo switch failed: ${e instanceof Error ? e.message : e}`);
|
|
1633
|
-
}
|
|
1634
|
-
if (claimedCard) {
|
|
1635
|
-
try {
|
|
1636
|
-
await deleteMessage(ds.larkAppId, claimedCard);
|
|
1637
|
-
}
|
|
1638
|
-
catch { /* best-effort */ }
|
|
1639
|
-
}
|
|
1640
|
-
}
|
|
1641
|
-
logger.info(`[${logTag}] Repo selected via ${how}: ${selectedPath}`);
|
|
1642
|
-
return true;
|
|
1643
|
-
};
|
|
1644
|
-
// `/repo wt <N|name|path> [branch]` → create a worktree off the repo's
|
|
1645
|
-
// remote default branch and open THAT as the session repo. Without a
|
|
1646
|
-
// branch arg the branch/dir are auto-named from the topic title / first
|
|
1647
|
-
// pending prompt when possible (fallback: wt/N, <repo>-wt-N).
|
|
1648
|
-
if (ds && /^wt(\s|$)/i.test(repoArg)) {
|
|
1649
|
-
const rest = repoArg.replace(/^wt\s*/i, '').trim().split(/\s+/).filter(Boolean);
|
|
1650
|
-
if (rest.length < 1 || rest.length > 2) {
|
|
1651
|
-
await sessionReply(rootId, t('cmd.repo.worktree_usage', undefined, loc));
|
|
1652
|
-
break;
|
|
1653
|
-
}
|
|
1654
|
-
const [targetArg, branchArg] = rest;
|
|
1655
|
-
let repoPath;
|
|
1656
|
-
if (/^\d+$/.test(targetArg)) {
|
|
1657
|
-
const cached = lastRepoScan.get(ds.chatId);
|
|
1658
|
-
if (!cached || cached.length === 0) {
|
|
1659
|
-
await sessionReply(rootId, t('cmd.repo.no_prior_scan', undefined, loc));
|
|
1660
|
-
break;
|
|
1661
|
-
}
|
|
1662
|
-
const repoIndex = parseInt(targetArg, 10);
|
|
1663
|
-
if (repoIndex < 1 || repoIndex > cached.length) {
|
|
1664
|
-
await sessionReply(rootId, t('cmd.repo.index_out_of_range', { max: cached.length }, loc));
|
|
1665
|
-
break;
|
|
1666
|
-
}
|
|
1667
|
-
repoPath = cached[repoIndex - 1].path;
|
|
1668
|
-
}
|
|
1669
|
-
else {
|
|
1670
|
-
const resolved = resolveRepoSelection(targetArg, getProjectScanDirs(ds));
|
|
1671
|
-
if (!resolved) {
|
|
1672
|
-
await sessionReply(rootId, t('cmd.repo.path_not_found', { arg: targetArg }, loc));
|
|
1673
|
-
break;
|
|
1674
|
-
}
|
|
1675
|
-
repoPath = resolved.path;
|
|
1676
|
-
}
|
|
1677
|
-
if (ds.worktreeCreating || ds.pendingRepoCommitInFlight) {
|
|
1678
|
-
await sessionReply(rootId, t('cmd.repo.worktree_in_progress', undefined, loc));
|
|
1679
|
-
break;
|
|
1680
|
-
}
|
|
1681
|
-
ds.worktreeCreating = true;
|
|
1682
|
-
// Session generation snapshot — another selection can land while the
|
|
1683
|
-
// (awaited) git fetch runs; committing afterwards would kill the
|
|
1684
|
-
// session it just spawned. Mirror of the card-side guard.
|
|
1685
|
-
const startSessionId = ds.session.sessionId;
|
|
1686
|
-
const wasPending = !!ds.pendingRepo;
|
|
1687
|
-
// Identity against the active map catches `/close` (which deletes
|
|
1688
|
-
// the entry without touching sessionId/pendingRepo) alongside the
|
|
1689
|
-
// generation snapshots.
|
|
1690
|
-
const wtSessionChanged = () => activeSessions.get(sessionKey(rootId, larkAppId)) !== ds ||
|
|
1691
|
-
ds.session.sessionId !== startSessionId || !!ds.pendingRepo !== wasPending;
|
|
1692
|
-
// Hold the in-flight lock through commit (matching the card path) —
|
|
1693
|
-
// releasing it right after `git` would let a second `/repo wt` start
|
|
1694
|
-
// while this one is still replying/committing.
|
|
1695
|
-
try {
|
|
1696
|
-
await sessionReply(rootId, t('cmd.repo.worktree_creating', { repo: repoPath }, loc));
|
|
1697
|
-
let creation;
|
|
1698
|
-
try {
|
|
1699
|
-
const slug = branchArg ? undefined : await worktreeSlugFromContextAI(ds.session.title, ds.pendingPrompt);
|
|
1700
|
-
creation = await createRepoWorktree(repoPath, {
|
|
1701
|
-
branch: branchArg,
|
|
1702
|
-
slug,
|
|
1703
|
-
});
|
|
1704
|
-
}
|
|
1705
|
-
catch (e) {
|
|
1706
|
-
await sessionReply(rootId, t('cmd.repo.worktree_failed', { error: e instanceof Error ? e.message : String(e) }, loc));
|
|
1707
|
-
break;
|
|
1708
|
-
}
|
|
1709
|
-
if (wtSessionChanged()) {
|
|
1710
|
-
logger.info(`[${logTag}] Worktree ${creation.path} created but session changed mid-flight — not switching`);
|
|
1711
|
-
await sessionReply(rootId, t('cmd.repo.worktree_created_not_switched', { path: creation.path, branch: creation.branch }, loc));
|
|
1712
|
-
break;
|
|
1713
|
-
}
|
|
1714
|
-
const botCfg = getBot(ds.larkAppId).config;
|
|
1715
|
-
const effectiveBackend = resolvePairedSpawnBackendType(wasPending ? (ds.session.cliId ?? botCfg.cliId) : botCfg.cliId, wasPending ? ds.session.backendType : undefined, botCfg.backendType, config.daemon.backendType);
|
|
1716
|
-
if (effectiveBackend === 'riff') {
|
|
1717
|
-
try {
|
|
1718
|
-
await pushWorktreeBranch(creation.path, creation.branch);
|
|
1719
|
-
}
|
|
1720
|
-
catch (e) {
|
|
1721
|
-
const errMsg = e instanceof Error ? e.message : String(e);
|
|
1722
|
-
logger.warn(`[${logTag}] riff worktree branch push failed (${creation.branch}): ${errMsg}`);
|
|
1723
|
-
await sessionReply(rootId, t('card.repo.riff_worktree_push_failed', { branch: creation.branch, error: errMsg }, loc));
|
|
1724
|
-
}
|
|
1725
|
-
}
|
|
1726
|
-
await sessionReply(rootId, t('cmd.repo.worktree_created', {
|
|
1727
|
-
path: creation.path, branch: creation.branch, base: creation.baseRef,
|
|
1728
|
-
}, loc));
|
|
1729
|
-
// The reply above awaited a Lark round-trip — a plain selection
|
|
1730
|
-
// (not gated by worktreeCreating) can land in that window. Re-check
|
|
1731
|
-
// right before committing. Mirror of the card-side double guard.
|
|
1732
|
-
if (wtSessionChanged()) {
|
|
1733
|
-
logger.info(`[${logTag}] Worktree ${creation.path} created but session changed during reply — not switching`);
|
|
1734
|
-
await sessionReply(rootId, t('cmd.repo.worktree_created_not_switched', { path: creation.path, branch: creation.branch }, loc));
|
|
1735
|
-
break;
|
|
1736
|
-
}
|
|
1737
|
-
try {
|
|
1738
|
-
await commitRepoSelection(creation.path, `${basename(creation.path)} (${creation.branch})`, `/repo wt`);
|
|
1739
|
-
}
|
|
1740
|
-
catch (e) {
|
|
1741
|
-
// The worktree DOES exist — only the switch failed. Don't report
|
|
1742
|
-
// it as a creation failure, or a retry trips over "already exists".
|
|
1743
|
-
logger.warn(`[${logTag}] Worktree ${creation.path} created but switching failed: ${e instanceof Error ? e.message : e}`);
|
|
1744
|
-
await sessionReply(rootId, t('cmd.repo.worktree_switch_failed', { path: creation.path, error: e instanceof Error ? e.message : String(e) }, loc));
|
|
1745
|
-
}
|
|
1746
|
-
}
|
|
1747
|
-
finally {
|
|
1748
|
-
ds.worktreeCreating = false;
|
|
1749
|
-
}
|
|
1750
|
-
break;
|
|
1751
|
-
}
|
|
1752
|
-
// Plain selections are blocked while a worktree creation/commit is in
|
|
1753
|
-
// flight: the worktree commit awaits (Lark replies, prompt prep) after
|
|
1754
|
-
// its generation checks, and a plain selection interleaving there
|
|
1755
|
-
// would double-fork. One lock gates both kinds until the commit
|
|
1756
|
-
// settles. (Bare `/repo` without pending only posts the picker card —
|
|
1757
|
-
// harmless, so it stays open.)
|
|
1758
|
-
if ((ds?.worktreeCreating || ds?.pendingRepoCommitInFlight) && (repoArg || ds?.pendingRepo)) {
|
|
1759
|
-
await sessionReply(rootId, t('cmd.repo.worktree_in_progress', undefined, loc));
|
|
1760
|
-
break;
|
|
1761
|
-
}
|
|
1762
|
-
// Numeric arg → pick by 1-based index from the last scan.
|
|
1763
|
-
if (repoArg && ds && /^\d+$/.test(repoArg)) {
|
|
1764
|
-
const repoIndex = parseInt(repoArg, 10);
|
|
1765
|
-
const cached = lastRepoScan.get(ds.chatId);
|
|
1766
|
-
if (!cached || cached.length === 0) {
|
|
1767
|
-
await sessionReply(rootId, t('cmd.repo.no_prior_scan', undefined, loc));
|
|
1768
|
-
break;
|
|
1769
|
-
}
|
|
1770
|
-
if (repoIndex < 1 || repoIndex > cached.length) {
|
|
1771
|
-
await sessionReply(rootId, t('cmd.repo.index_out_of_range', { max: cached.length }, loc));
|
|
1772
|
-
break;
|
|
1773
|
-
}
|
|
1774
|
-
const project = cached[repoIndex - 1];
|
|
1775
|
-
await commitRepoSelection(project.path, `${project.name} (${project.branch})`, `/repo ${repoIndex}`);
|
|
1776
|
-
break;
|
|
1777
|
-
}
|
|
1778
|
-
// Non-numeric arg → a path (relative/absolute) or first-level project
|
|
1779
|
-
// name under workingDir; resolve it directly and skip the card.
|
|
1780
|
-
if (repoArg && ds) {
|
|
1781
|
-
const resolved = resolveRepoSelection(repoArg, getProjectScanDirs(ds));
|
|
1782
|
-
if (!resolved) {
|
|
1783
|
-
await sessionReply(rootId, t('cmd.repo.path_not_found', { arg: repoArg }, loc));
|
|
1784
|
-
break;
|
|
1785
|
-
}
|
|
1786
|
-
await commitRepoSelection(resolved.path, resolved.displayName, `/repo ${repoArg}`);
|
|
1787
|
-
break;
|
|
1788
|
-
}
|
|
1789
|
-
// Bare `/repo` while a repo card is pending → launch right away in the
|
|
1790
|
-
// default workingDir. This is the text-command twin of the card's
|
|
1791
|
-
// "start directly" button (and replaces the old `/skip` command).
|
|
1792
|
-
// Mid-session bare `/repo` (no pending) still falls through to the card.
|
|
1793
|
-
if (!repoArg && ds?.pendingRepo) {
|
|
1794
|
-
// Validate the configured workingDir before spawning — `forkWorker`
|
|
1795
|
-
// doesn't, so a dead cwd would otherwise spawn-and-fail silently. Same
|
|
1796
|
-
// guard the card path runs below. On failure we keep the pending state
|
|
1797
|
-
// so the user can recover with `/repo <valid-path>` (no card here).
|
|
1798
|
-
const invalidDirs = invalidConfiguredWorkingDirs(ds, ds.larkAppId ?? larkAppId);
|
|
1799
|
-
if (invalidDirs.length > 0) {
|
|
1800
|
-
await sessionReply(rootId, t('cmd.repo.working_dir_not_exist', { dirs: invalidDirs.map(d => `\`${d}\``).join(', ') }, loc));
|
|
1801
|
-
break;
|
|
1802
|
-
}
|
|
1803
|
-
const cwd = getSessionWorkingDir(ds);
|
|
1804
|
-
// bare /repo is the text twin of skip_repo: launch in the default
|
|
1805
|
-
// cwd without pinning it (forkPendingCli does not write workingDir).
|
|
1806
|
-
// Confirmation + card withdraw run under the claim inside forkPendingCli.
|
|
1807
|
-
await forkPendingCli(t('cmd.skip.opened', { cwd }, loc));
|
|
1808
|
-
logger.info(`[${logTag}] Bare /repo while pending → launch in workingDir ${cwd}`);
|
|
1809
|
-
break;
|
|
1810
|
-
}
|
|
1811
|
-
if (ds?.worker && !ds.worker.killed) {
|
|
1812
|
-
await sessionReply(rootId, t('cmd.repo.warning_running', undefined, loc));
|
|
1813
|
-
}
|
|
1814
|
-
const scanDirs = getProjectScanDirs(ds);
|
|
1815
|
-
const invalidDirs = invalidConfiguredWorkingDirs(ds, ds?.larkAppId ?? larkAppId);
|
|
1816
|
-
if (invalidDirs.length > 0) {
|
|
1817
|
-
await sessionReply(rootId, t('cmd.repo.working_dir_not_exist', { dirs: invalidDirs.map(d => `\`${d}\``).join(', ') }, loc));
|
|
1818
|
-
break;
|
|
1819
|
-
}
|
|
1820
|
-
const validDirs = scanDirs.filter(d => existsSync(d));
|
|
1821
|
-
if (validDirs.length === 0) {
|
|
1822
|
-
await sessionReply(rootId, t('cmd.repo.scan_dir_not_exist', { dirs: scanDirs.join(', ') }, loc));
|
|
1823
|
-
break;
|
|
1824
|
-
}
|
|
1825
|
-
const projects = scanMultipleProjects(validDirs, 3, repoPickerScanOptions());
|
|
1826
|
-
if (projects.length === 0) {
|
|
1827
|
-
await sessionReply(rootId, t('cmd.repo.no_git_repos', { dirs: validDirs.join(', ') }, loc));
|
|
1828
|
-
break;
|
|
1829
|
-
}
|
|
1830
|
-
if (ds)
|
|
1831
|
-
lastRepoScan.set(ds.chatId, projects);
|
|
1832
|
-
const currentCwd = getSessionWorkingDir(ds);
|
|
1833
|
-
const cardJson = buildRepoSelectCard(projects, currentCwd, rootId, loc, ds ? getBot(ds.larkAppId).config.worktreeMultiPicker : undefined);
|
|
1834
|
-
const repoCardMsgId = await sessionReply(rootId, cardJson, 'interactive');
|
|
1835
|
-
if (ds) {
|
|
1836
|
-
ds.repoCardMessageId = repoCardMsgId;
|
|
1837
|
-
announcePendingRepoSession(ds);
|
|
1838
|
-
}
|
|
1839
|
-
logger.info(`[${logTag}] Sent repo card with ${projects.length} project(s)`);
|
|
1840
|
-
break;
|
|
1841
|
-
}
|
|
1842
|
-
case '/status': {
|
|
1843
|
-
if (ds) {
|
|
1844
|
-
const alive = ds.worker && !ds.worker.killed;
|
|
1845
|
-
const idle = formatUptime(Date.now() - ds.lastMessageAt);
|
|
1846
|
-
const termUrl = ds.workerPort ? buildTerminalUrl(ds) : '-';
|
|
1847
|
-
const botCfg = getBot(ds.larkAppId).config;
|
|
1848
|
-
const migratedFrozenRuntime = ds.session.agentFrozen && !ds.session.cliRuntime
|
|
1849
|
-
? resolveCliRuntime({
|
|
1850
|
-
cliId: ds.session.cliId ?? botCfg.cliId,
|
|
1851
|
-
cliPathOverride: ds.session.cliPathOverride,
|
|
1852
|
-
context: 'status session cliRuntime',
|
|
1853
|
-
})
|
|
1854
|
-
: undefined;
|
|
1855
|
-
const effectiveRuntime = ds.session.cliRuntime
|
|
1856
|
-
?? migratedFrozenRuntime
|
|
1857
|
-
?? (!ds.session.agentFrozen ? botCfg.cliRuntime : undefined);
|
|
1858
|
-
const effectivePath = ds.session.agentFrozen
|
|
1859
|
-
? ds.session.cliPathOverride
|
|
1860
|
-
: ds.session.cliPathOverride ?? botCfg.cliPathOverride;
|
|
1861
|
-
const runtimeName = configuredRuntimeDisplayName(effectiveRuntime)
|
|
1862
|
-
?? getCliDisplayName(ds.session.cliId ?? botCfg.cliId);
|
|
1863
|
-
const latestRuntimeVersion = getCurrentCliVersion(runtimeInstallationKey({
|
|
1864
|
-
cliId: ds.session.cliId ?? botCfg.cliId,
|
|
1865
|
-
cliRuntime: effectiveRuntime,
|
|
1866
|
-
cliPathOverride: effectivePath,
|
|
1867
|
-
}));
|
|
1868
|
-
const lines = [
|
|
1869
|
-
`Session: ${ds.session.sessionId}`,
|
|
1870
|
-
`Status: ${alive ? t('cmd.status.running', undefined, loc) : t('cmd.status.waiting', undefined, loc)}`,
|
|
1871
|
-
`Terminal: ${termUrl}`,
|
|
1872
|
-
`CWD: ${getSessionWorkingDir(ds)}`,
|
|
1873
|
-
`${runtimeName}: v${ds.cliVersion}${latestRuntimeVersion !== 'unknown' && ds.cliVersion !== latestRuntimeVersion ? ` (latest: v${latestRuntimeVersion})` : ''}`,
|
|
1874
|
-
...(alive ? [`Uptime: ${formatUptime(Date.now() - ds.spawnedAt)}`] : []),
|
|
1875
|
-
`Last message: ${idle} ago`,
|
|
1876
|
-
`Active sessions: ${getActiveCount()}`,
|
|
1877
|
-
];
|
|
1878
|
-
await sessionReply(rootId, lines.join('\n'));
|
|
1879
|
-
}
|
|
1880
|
-
else {
|
|
1881
|
-
const fallbackCfg = larkAppId ? getBot(larkAppId).config : undefined;
|
|
1882
|
-
const fallbackCliName = configuredRuntimeDisplayName(fallbackCfg?.cliRuntime)
|
|
1883
|
-
?? (fallbackCfg ? getCliDisplayName(fallbackCfg.cliId) : 'CLI');
|
|
1884
|
-
const fallbackVersion = fallbackCfg
|
|
1885
|
-
? getCurrentCliVersion(runtimeInstallationKey({
|
|
1886
|
-
cliId: fallbackCfg.cliId,
|
|
1887
|
-
cliRuntime: fallbackCfg.cliRuntime,
|
|
1888
|
-
cliPathOverride: fallbackCfg.cliPathOverride,
|
|
1889
|
-
}))
|
|
1890
|
-
: getCurrentCliVersion();
|
|
1891
|
-
await sessionReply(rootId, t('cmd.status.fallback_no_session', {
|
|
1892
|
-
count: getActiveCount(),
|
|
1893
|
-
cliName: fallbackCliName,
|
|
1894
|
-
version: fallbackVersion,
|
|
1895
|
-
}, loc));
|
|
1896
|
-
}
|
|
1897
|
-
break;
|
|
1898
|
-
}
|
|
1899
|
-
case '/schedule': {
|
|
1900
|
-
const scheduleArgs = message.content.replace(/^\/schedule\s*/, '');
|
|
1901
|
-
const chatId = ds?.chatId;
|
|
1902
|
-
await handleScheduleCommand(scheduleArgs, rootId, chatId, deps, larkAppId);
|
|
1903
|
-
logger.info(`[${logTag}] Schedule command handled`);
|
|
1904
|
-
break;
|
|
1905
|
-
}
|
|
1906
|
-
case '/dashboard': {
|
|
1907
|
-
const dashboardArgs = message.content.replace(/^\/dashboard\s*/, '');
|
|
1908
|
-
const chatId = ds?.chatId ?? message.chatId ?? '';
|
|
1909
|
-
await handleDashboardCommand(message, dashboardArgs, rootId, chatId, deps, larkAppId);
|
|
1910
|
-
logger.info(`[${logTag}] Dashboard command handled (sub=${dashboardArgs.trim().split(/\s+/)[0] || 'overview'})`);
|
|
1911
|
-
break;
|
|
1912
|
-
}
|
|
1913
|
-
case '/role': {
|
|
1914
|
-
const chatId = ds?.chatId;
|
|
1915
|
-
if (!chatId || !larkAppId) {
|
|
1916
|
-
await sessionReply(rootId, t('role.no_chat', undefined, loc));
|
|
1917
|
-
break;
|
|
1918
|
-
}
|
|
1919
|
-
const roleArgs = message.content.replace(/^\/role\s*/, '');
|
|
1920
|
-
await handleRoleCommand(roleArgs, rootId, chatId, larkAppId, message.senderId, deps);
|
|
1921
|
-
logger.info(`[${logTag}] Role command handled`);
|
|
1922
|
-
break;
|
|
1923
|
-
}
|
|
1924
|
-
case '/botconfig': {
|
|
1925
|
-
const appId = larkAppId ?? ds?.larkAppId;
|
|
1926
|
-
if (!appId) {
|
|
1927
|
-
await sessionReply(rootId, t('cmd.config.no_bot', undefined, loc));
|
|
1928
|
-
break;
|
|
1929
|
-
}
|
|
1930
|
-
await handleConfigCommand(message, rootId, appId, deps);
|
|
1931
|
-
logger.info(`[${logTag}] Config command handled`);
|
|
1932
|
-
break;
|
|
1933
|
-
}
|
|
1934
|
-
// Issue Board:`/issue` 出看板卡片,后续都在卡片上就地操作(见 issue-command)。
|
|
1935
|
-
// 权限门(allowedUsers + invoker lock)在 handler 里,命令入口和每次回调各跑一遍。
|
|
1936
|
-
case '/issue': {
|
|
1937
|
-
const appId = larkAppId ?? ds?.larkAppId;
|
|
1938
|
-
if (!appId) {
|
|
1939
|
-
await sessionReply(rootId, t('cmd.config.no_bot', undefined, loc));
|
|
1940
|
-
break;
|
|
1941
|
-
}
|
|
1942
|
-
const sub = message.content.replace(/^\/issue\s*/i, '').trim().split(/\s+/, 1)[0]?.toLowerCase();
|
|
1943
|
-
const { handleIssueCommand, handleIssueDone, handleIssueRelease, handleIssueStatus } = await import('../im/lark/issue-command.js');
|
|
1944
|
-
const { buildIssueCommandDeps } = await import('../im/lark/issue-command-deps.js');
|
|
1945
|
-
// 这三个子命令都在**领取时建出来的那个群里**发,锚点从当前会话推。两个候选按
|
|
1946
|
-
// sessionAnchorId 的语义给(拉群 → chatId,话题 → rootMessageId),由 handler 依次试。
|
|
1947
|
-
const anchors = [message.chatId, rootId];
|
|
1948
|
-
if (sub === 'release' || sub === 'done') {
|
|
1949
|
-
const handler = sub === 'done' ? handleIssueDone : handleIssueRelease;
|
|
1950
|
-
const rel = await handler(appId, message.senderId, anchors, buildIssueCommandDeps());
|
|
1951
|
-
await sessionReply(rootId, rel.toast.content);
|
|
1952
|
-
logger.info(`[${logTag}] Issue ${sub} handled: ${rel.toast.type}`);
|
|
1953
|
-
break;
|
|
1954
|
-
}
|
|
1955
|
-
if (sub === 'status') {
|
|
1956
|
-
const st = await handleIssueStatus(appId, message.senderId, anchors, buildIssueCommandDeps());
|
|
1957
|
-
if ('card' in st)
|
|
1958
|
-
await sessionReply(rootId, st.card, 'interactive');
|
|
1959
|
-
else
|
|
1960
|
-
await sessionReply(rootId, st.toast.content);
|
|
1961
|
-
logger.info(`[${logTag}] Issue status handled: ${'card' in st ? 'card' : 'toast'}`);
|
|
1962
|
-
break;
|
|
1963
|
-
}
|
|
1964
|
-
const r = await handleIssueCommand(appId, message.senderId, buildIssueCommandDeps());
|
|
1965
|
-
if ('card' in r)
|
|
1966
|
-
await sessionReply(rootId, r.card, 'interactive');
|
|
1967
|
-
else
|
|
1968
|
-
await sessionReply(rootId, r.toast.content);
|
|
1969
|
-
logger.info(`[${logTag}] Issue command handled: ${'card' in r ? 'card' : 'toast'}`);
|
|
1970
|
-
break;
|
|
1971
|
-
}
|
|
1972
|
-
case '/skills': {
|
|
1973
|
-
const appId = larkAppId ?? ds?.larkAppId;
|
|
1974
|
-
if (!appId) {
|
|
1975
|
-
await sessionReply(rootId, t('cmd.config.no_bot', undefined, loc));
|
|
1976
|
-
break;
|
|
1977
|
-
}
|
|
1978
|
-
const sub = message.content.replace(/^\/skills\s*/i, '').trim().split(/\s+/, 1)[0]?.toLowerCase();
|
|
1979
|
-
if (sub === 'attach' || sub === 'detach') {
|
|
1980
|
-
let bot;
|
|
1981
|
-
try {
|
|
1982
|
-
bot = getBot(appId);
|
|
1983
|
-
}
|
|
1984
|
-
catch {
|
|
1985
|
-
await sessionReply(rootId, t('cmd.config.no_bot', undefined, loc));
|
|
1986
|
-
break;
|
|
1987
|
-
}
|
|
1988
|
-
const admins = bot.resolvedAllowedUsers ?? [];
|
|
1989
|
-
if (admins.length === 0) {
|
|
1990
|
-
await sessionReply(rootId, t('cmd.config.no_owner', undefined, loc));
|
|
1991
|
-
break;
|
|
1992
|
-
}
|
|
1993
|
-
if (!message.senderId || !admins.includes(message.senderId)) {
|
|
1994
|
-
await sessionReply(rootId, t('cmd.config.not_admin', undefined, loc));
|
|
1995
|
-
break;
|
|
1996
|
-
}
|
|
1997
|
-
}
|
|
1998
|
-
const result = await runSkillsImCommand(appId, message.content);
|
|
1999
|
-
await sessionReply(rootId, result.message);
|
|
2000
|
-
logger.info(`[${logTag}] Skills command handled: ${result.ok ? 'ok' : 'error'}`);
|
|
2001
|
-
break;
|
|
2002
|
-
}
|
|
2003
|
-
case '/pair': {
|
|
2004
|
-
const code = message.content.replace(/^\/pair\s*/, '').trim();
|
|
2005
|
-
if (!larkAppId) {
|
|
2006
|
-
await sessionReply(rootId, t('role.no_chat', undefined, loc));
|
|
2007
|
-
break;
|
|
2008
|
-
}
|
|
2009
|
-
if (!code) {
|
|
2010
|
-
await sessionReply(rootId, t('pair.usage', undefined, loc));
|
|
2011
|
-
break;
|
|
2012
|
-
}
|
|
2013
|
-
// Resolve the sender's canonical union_id (best-effort) so the web
|
|
2014
|
-
// session is keyed stably across apps; degrade to open_id-only.
|
|
2015
|
-
const who = await resolveUserUnionId(larkAppId, message.senderId);
|
|
2016
|
-
const result = claimPairing(config.session.dataDir, code, { openId: message.senderId, unionId: who.unionId, name: who.name, larkAppId });
|
|
2017
|
-
if (result.ok)
|
|
2018
|
-
await sessionReply(rootId, t('pair.ok', undefined, loc));
|
|
2019
|
-
else if (result.reason === 'expired')
|
|
2020
|
-
await sessionReply(rootId, t('pair.expired', undefined, loc));
|
|
2021
|
-
else if (result.reason === 'already_claimed')
|
|
2022
|
-
await sessionReply(rootId, t('pair.already', undefined, loc));
|
|
2023
|
-
else
|
|
2024
|
-
await sessionReply(rootId, t('pair.not_found', undefined, loc));
|
|
2025
|
-
logger.info(`[${logTag}] Pair command handled: ${result.ok ? 'ok' : result.reason}`);
|
|
2026
|
-
break;
|
|
2027
|
-
}
|
|
2028
|
-
case '/login': {
|
|
2029
|
-
const subCmd = message.content.replace(/^\/login\s*/, '').trim();
|
|
2030
|
-
// 先定位本 bot 配置——token 状态与 OAuth URL 都按 per-bot appId/brand 走。
|
|
2031
|
-
const botCfg2 = ds ? getBot(ds.larkAppId).config : (larkAppId ? getBot(larkAppId).config : getAllBots()[0]?.config);
|
|
2032
|
-
if (!botCfg2?.larkAppId || !botCfg2?.larkAppSecret) {
|
|
2033
|
-
await sessionReply(rootId, t('cmd.login.no_credentials', undefined, loc));
|
|
2034
|
-
break;
|
|
2035
|
-
}
|
|
2036
|
-
if (subCmd === 'status' || subCmd === '状态') {
|
|
2037
|
-
await sessionReply(rootId, getTokenStatus(botCfg2.larkAppId, normalizeBrand(botCfg2.brand)));
|
|
2038
|
-
break;
|
|
2039
|
-
}
|
|
2040
|
-
const { authUrl } = generateAuthUrl(botCfg2.larkAppId, botCfg2.larkAppSecret, normalizeBrand(botCfg2.brand));
|
|
2041
|
-
await sessionReply(rootId, [
|
|
2042
|
-
t('cmd.login.title', undefined, loc),
|
|
2043
|
-
'',
|
|
2044
|
-
t('cmd.login.step1', undefined, loc),
|
|
2045
|
-
authUrl,
|
|
2046
|
-
'',
|
|
2047
|
-
t('cmd.login.step2', undefined, loc),
|
|
2048
|
-
t('cmd.login.step3', undefined, loc),
|
|
2049
|
-
'',
|
|
2050
|
-
t('cmd.login.footer', undefined, loc),
|
|
2051
|
-
t('cmd.login.status_hint', undefined, loc),
|
|
2052
|
-
].join('\n'));
|
|
2053
|
-
break;
|
|
2054
|
-
}
|
|
2055
|
-
case '/subscribe-lark-doc': {
|
|
2056
|
-
// 保留 origin/master 的既有语义:显式获取文档 scope 的 User Token,调用
|
|
2057
|
-
// 飞书逐文件 subscribe API,再把文档绑定到当前会话。新增的评论监听、自动
|
|
2058
|
-
// 会话和审批能力走独立的 /watch-comment,不改变这个远端已有命令。
|
|
2059
|
-
if (!ds || !larkAppId) {
|
|
2060
|
-
await sessionReply(rootId, t('cmd.subdoc.no_session', undefined, loc));
|
|
2061
|
-
break;
|
|
2062
|
-
}
|
|
2063
|
-
const arg = message.content.replace(/^\/subscribe-lark-doc\s*/i, '').trim();
|
|
2064
|
-
const anchor = sessionAnchorId(ds);
|
|
2065
|
-
const dataDir = config.session.dataDir;
|
|
2066
|
-
const modeLabel = (m) => t(m === 'all' ? 'cmd.subdoc.mode_all' : 'cmd.subdoc.mode_mention', undefined, loc);
|
|
2067
|
-
if (arg === 'list' || arg === '列表') {
|
|
2068
|
-
const subs = listDocSubscriptionsForSession(dataDir, larkAppId, anchor)
|
|
2069
|
-
.filter(s => s.managedBy !== 'watch-comment');
|
|
2070
|
-
if (!subs.length) {
|
|
2071
|
-
await sessionReply(rootId, t('cmd.subdoc.none', undefined, loc));
|
|
2072
|
-
break;
|
|
2073
|
-
}
|
|
2074
|
-
const lines = subs.map(s => `• ${s.docTitle || s.fileToken}(${modeLabel(s.commentTriggerMode)})`);
|
|
2075
|
-
await sessionReply(rootId, [t('cmd.subdoc.list_title', undefined, loc), ...lines].join('\n'));
|
|
2076
|
-
break;
|
|
2077
|
-
}
|
|
2078
|
-
if (arg === 'off' || arg === 'stop' || arg === '退订') {
|
|
2079
|
-
const subs = listDocSubscriptionsForSession(dataDir, larkAppId, anchor)
|
|
2080
|
-
.filter(s => s.managedBy !== 'watch-comment');
|
|
2081
|
-
for (const s of subs) {
|
|
2082
|
-
await unsubscribeDocFile(larkAppId, { fileToken: s.fileToken, fileType: s.fileType });
|
|
2083
|
-
removeDocSubscription(dataDir, larkAppId, s.fileToken);
|
|
2084
|
-
}
|
|
2085
|
-
await sessionReply(rootId, t('cmd.subdoc.unsubscribed', { count: subs.length }, loc));
|
|
2086
|
-
break;
|
|
2087
|
-
}
|
|
2088
|
-
if (!arg) {
|
|
2089
|
-
await sessionReply(rootId, t('cmd.subdoc.usage', undefined, loc));
|
|
2090
|
-
break;
|
|
2091
|
-
}
|
|
2092
|
-
// 旧流程:文档 scope 不污染通用 /login;缺少时由本命令发专用 OAuth 链接。
|
|
2093
|
-
const subCfg = getBot(larkAppId).config;
|
|
2094
|
-
const replyDocLogin = async () => {
|
|
2095
|
-
const { authUrl } = generateAuthUrl(subCfg.larkAppId, subCfg.larkAppSecret, normalizeBrand(subCfg.brand), DOC_COMMENT_OAUTH_SCOPES);
|
|
2096
|
-
await sessionReply(rootId, [
|
|
2097
|
-
t('cmd.subdoc.need_login', undefined, loc),
|
|
2098
|
-
'',
|
|
2099
|
-
t('cmd.login.step1', undefined, loc),
|
|
2100
|
-
authUrl,
|
|
2101
|
-
'',
|
|
2102
|
-
t('cmd.login.step2', undefined, loc),
|
|
2103
|
-
t('cmd.login.step3', undefined, loc),
|
|
2104
|
-
].join('\n'));
|
|
2105
|
-
};
|
|
2106
|
-
const userTok = await resolveUserToken(subCfg.larkAppId, subCfg.larkAppSecret, normalizeBrand(subCfg.brand));
|
|
2107
|
-
if (!userTok) {
|
|
2108
|
-
await replyDocLogin();
|
|
2109
|
-
break;
|
|
2110
|
-
}
|
|
2111
|
-
try {
|
|
2112
|
-
const file = await resolveDocFile(larkAppId, arg);
|
|
2113
|
-
await subscribeDocFile(larkAppId, file);
|
|
2114
|
-
const mode = subCfg.docSubscribeDefaultMode === 'all' ? 'all' : 'mention-only';
|
|
2115
|
-
const { previous } = putDocSubscription(dataDir, larkAppId, {
|
|
2116
|
-
fileToken: file.fileToken,
|
|
2117
|
-
fileType: file.fileType,
|
|
2118
|
-
sessionAnchor: anchor,
|
|
2119
|
-
sessionId: ds.session.sessionId,
|
|
2120
|
-
scope: ds.scope,
|
|
2121
|
-
chatId: ds.chatId,
|
|
2122
|
-
commentTriggerMode: mode,
|
|
2123
|
-
managedBy: 'subscribe-lark-doc',
|
|
2124
|
-
ownerOpenId: message.senderId,
|
|
2125
|
-
createdAt: Date.now(),
|
|
2126
|
-
});
|
|
2127
|
-
const title = file.fileToken.slice(0, 12);
|
|
2128
|
-
const rebound = previous && previous.sessionAnchor !== anchor;
|
|
2129
|
-
await sessionReply(rootId, t(rebound ? 'cmd.subdoc.subscribed_moved' : 'cmd.subdoc.subscribed', { title, mode: modeLabel(mode) }, loc));
|
|
2130
|
-
logger.info(`[${logTag}] /subscribe-lark-doc → ${file.fileType}:${file.fileToken.slice(0, 12)} mode=${mode}${rebound ? ' (rebound)' : ''}`);
|
|
2131
|
-
}
|
|
2132
|
-
catch (err) {
|
|
2133
|
-
// 1069603 重新 OAuth 无法修复;保留实际返回该业务码的身份,避免把
|
|
2134
|
-
// tenant-only 失败误归因到当前用户。只有 token 缺失 / 失效才重新授权。
|
|
2135
|
-
if (err instanceof DocSubscriptionPermissionError) {
|
|
2136
|
-
const identity = err.source === 'user'
|
|
2137
|
-
? t('cmd.subdoc.permission_identity_user', undefined, loc)
|
|
2138
|
-
: err.source === 'tenant'
|
|
2139
|
-
? t('cmd.subdoc.permission_identity_tenant', undefined, loc)
|
|
2140
|
-
: err.source === 'both'
|
|
2141
|
-
? t('cmd.subdoc.permission_identity_both', undefined, loc)
|
|
2142
|
-
: t('cmd.subdoc.permission_identity_unknown', undefined, loc);
|
|
2143
|
-
await sessionReply(rootId, t('cmd.subdoc.manage_required', {
|
|
2144
|
-
code: err.larkCode,
|
|
2145
|
-
identity,
|
|
2146
|
-
}, loc));
|
|
2147
|
-
}
|
|
2148
|
-
else if (err instanceof UserTokenMissingError) {
|
|
2149
|
-
await replyDocLogin();
|
|
2150
|
-
}
|
|
2151
|
-
else {
|
|
2152
|
-
await sessionReply(rootId, t('cmd.subdoc.failed', { err: err instanceof Error ? err.message : String(err) }, loc));
|
|
2153
|
-
}
|
|
2154
|
-
}
|
|
2155
|
-
break;
|
|
2156
|
-
}
|
|
2157
|
-
case '/watch-comment': {
|
|
2158
|
-
if (!larkAppId) {
|
|
2159
|
-
await sessionReply(rootId, t('cmd.watch.no_session', undefined, loc));
|
|
2160
|
-
break;
|
|
2161
|
-
}
|
|
2162
|
-
const request = parseDocWatchCommand(message.content);
|
|
2163
|
-
const dataDir = config.session.dataDir;
|
|
2164
|
-
const modeLabel = (m) => t(m === 'all' ? 'cmd.subdoc.mode_all' : 'cmd.subdoc.mode_mention', undefined, loc);
|
|
2165
|
-
if (request.kind === 'usage' || request.kind === 'invalid') {
|
|
2166
|
-
const prefix = request.kind === 'invalid' && request.reason === 'conflicting_modes'
|
|
2167
|
-
? `${t('cmd.watch.conflicting_modes', undefined, loc)}\n\n`
|
|
2168
|
-
: '';
|
|
2169
|
-
await sessionReply(rootId, prefix + t('cmd.watch.usage', undefined, loc));
|
|
2170
|
-
break;
|
|
2171
|
-
}
|
|
2172
|
-
// 设计:只有 bot owner 能管理文档评论监听(watch / list / off)。非 owner 无法
|
|
2173
|
-
// 主动发起监听,只能在文档里 @bot 触发回复——那条路径会私信通知 owner 审计
|
|
2174
|
-
// (notify-not-approve,见 event-dispatcher.processCommentEvent),不经这里。
|
|
2175
|
-
const ownerOpenId = getOwnerOpenId(larkAppId);
|
|
2176
|
-
if (!ownerOpenId || message.senderId !== ownerOpenId) {
|
|
2177
|
-
await sessionReply(rootId, t('cmd.watch.owner_only', undefined, loc));
|
|
2178
|
-
break;
|
|
2179
|
-
}
|
|
2180
|
-
if (request.kind === 'list') {
|
|
2181
|
-
// 命令已收归 owner-only,无 session 时直接列全部(不再按 ownerOpenId 过滤),
|
|
2182
|
-
// 否则非 owner @bot 触发的 auto-sub 对 owner 不可见。
|
|
2183
|
-
const subs = (ds
|
|
2184
|
-
? listDocSubscriptionsForSession(dataDir, larkAppId, sessionAnchorId(ds))
|
|
2185
|
-
: listAllDocSubscriptions(dataDir, larkAppId))
|
|
2186
|
-
.filter(s => s.managedBy === 'watch-comment');
|
|
2187
|
-
if (!subs.length) {
|
|
2188
|
-
await sessionReply(rootId, t(ds ? 'cmd.watch.none' : 'cmd.watch.none_owned', undefined, loc));
|
|
2189
|
-
break;
|
|
2190
|
-
}
|
|
2191
|
-
const lines = subs.map(s => {
|
|
2192
|
-
const wd = s.workingDir ? ` 📂${s.workingDir}` : '';
|
|
2193
|
-
return `• ${s.docTitle || s.fileToken}(${modeLabel(s.commentTriggerMode)})${wd}`;
|
|
2194
|
-
});
|
|
2195
|
-
await sessionReply(rootId, [t(ds ? 'cmd.watch.list_title' : 'cmd.watch.list_title_owned', undefined, loc), ...lines].join('\n'));
|
|
2196
|
-
break;
|
|
2197
|
-
}
|
|
2198
|
-
if (request.kind === 'off') {
|
|
2199
|
-
if (request.docRef) {
|
|
2200
|
-
try {
|
|
2201
|
-
const file = await resolveDocFile(larkAppId, request.docRef);
|
|
2202
|
-
const existing = getDocSubscription(dataDir, larkAppId, file.fileToken);
|
|
2203
|
-
if (!existing || existing.managedBy !== 'watch-comment') {
|
|
2204
|
-
await sessionReply(rootId, t('cmd.watch.not_found', undefined, loc));
|
|
2205
|
-
break;
|
|
2206
|
-
}
|
|
2207
|
-
removeDocSubscription(dataDir, larkAppId, file.fileToken);
|
|
2208
|
-
await sessionReply(rootId, t('cmd.watch.stopped_one', { title: file.fileToken.slice(0, 12) }, loc));
|
|
2209
|
-
}
|
|
2210
|
-
catch (err) {
|
|
2211
|
-
await sessionReply(rootId, t('cmd.watch.failed', { err: err instanceof Error ? err.message : String(err) }, loc));
|
|
2212
|
-
}
|
|
2213
|
-
break;
|
|
2214
|
-
}
|
|
2215
|
-
// 命令已收归 owner-only,无 session 时直接列全部(不再按 ownerOpenId 过滤)。
|
|
2216
|
-
const subs = (ds
|
|
2217
|
-
? listDocSubscriptionsForSession(dataDir, larkAppId, sessionAnchorId(ds))
|
|
2218
|
-
: listAllDocSubscriptions(dataDir, larkAppId))
|
|
2219
|
-
.filter(s => s.managedBy === 'watch-comment');
|
|
2220
|
-
for (const s of subs) {
|
|
2221
|
-
removeDocSubscription(dataDir, larkAppId, s.fileToken);
|
|
2222
|
-
}
|
|
2223
|
-
await sessionReply(rootId, t(ds ? 'cmd.watch.stopped_all' : 'cmd.watch.stopped_owned', { count: subs.length }, loc));
|
|
2224
|
-
break;
|
|
2225
|
-
}
|
|
2226
|
-
if (request.kind !== 'watch') {
|
|
2227
|
-
await sessionReply(rootId, t('cmd.watch.usage', undefined, loc));
|
|
2228
|
-
break;
|
|
2229
|
-
}
|
|
2230
|
-
let validatedDir;
|
|
2231
|
-
if (request.workingDir) {
|
|
2232
|
-
const v = validateWorkingDir(request.workingDir, loc);
|
|
2233
|
-
if (!v.ok) {
|
|
2234
|
-
await sessionReply(rootId, v.error);
|
|
2235
|
-
break;
|
|
2236
|
-
}
|
|
2237
|
-
validatedDir = v.resolvedPath;
|
|
2238
|
-
}
|
|
2239
|
-
const botCfg = getBot(larkAppId).config;
|
|
2240
|
-
try {
|
|
2241
|
-
const file = await resolveDocFile(larkAppId, request.docRef);
|
|
2242
|
-
const existing = getDocSubscription(dataDir, larkAppId, file.fileToken);
|
|
2243
|
-
const mode = request.requestedMode
|
|
2244
|
-
?? (botCfg.docSubscribeDefaultMode === 'all' ? 'all' : 'mention-only');
|
|
2245
|
-
const anchor = ds ? sessionAnchorId(ds) : `doc:${file.fileToken}`;
|
|
2246
|
-
// Existing chat/thread sessions own their project binding. A watch
|
|
2247
|
-
// without an explicit --dir inherits that binding; session-less
|
|
2248
|
-
// document watches keep their own stored/mapped directory fallback.
|
|
2249
|
-
const effectiveDir = ds
|
|
2250
|
-
? (validatedDir ?? ds.workingDir ?? ds.session.workingDir)
|
|
2251
|
-
: (validatedDir ?? existing?.workingDir ?? botCfg.docRepoMap?.[file.fileToken]);
|
|
2252
|
-
let pollCursorAt;
|
|
2253
|
-
let pollCursorReplyId;
|
|
2254
|
-
let pollBaselineReady;
|
|
2255
|
-
if (mode === 'all') {
|
|
2256
|
-
const canReuseBaseline = existing?.managedBy === 'watch-comment'
|
|
2257
|
-
&& existing.commentTriggerMode === 'all'
|
|
2258
|
-
&& existing.pollBaselineReady === true;
|
|
2259
|
-
if (canReuseBaseline) {
|
|
2260
|
-
pollCursorAt = existing.pollCursorAt;
|
|
2261
|
-
pollCursorReplyId = existing.pollCursorReplyId;
|
|
2262
|
-
pollBaselineReady = true;
|
|
2263
|
-
}
|
|
2264
|
-
else {
|
|
2265
|
-
try {
|
|
2266
|
-
const latest = latestDocCommentPollCursor(await listDocComments(larkAppId, file));
|
|
2267
|
-
pollCursorAt = latest?.createdAt ?? Math.floor(Date.now() / 1000);
|
|
2268
|
-
pollCursorReplyId = latest?.replyId ?? '';
|
|
2269
|
-
pollBaselineReady = true;
|
|
2270
|
-
}
|
|
2271
|
-
catch (err) {
|
|
2272
|
-
// 不让一次读取失败阻塞登记。poller 首次成功时只建立基线,不重放历史。
|
|
2273
|
-
pollBaselineReady = false;
|
|
2274
|
-
logger.warn(`[${logTag}] /watch-comment baseline failed for ${file.fileToken.slice(0, 12)}: ${err instanceof Error ? err.message : String(err)}`);
|
|
2275
|
-
}
|
|
2276
|
-
}
|
|
2277
|
-
}
|
|
2278
|
-
const subscription = {
|
|
2279
|
-
fileToken: file.fileToken,
|
|
2280
|
-
fileType: file.fileType,
|
|
2281
|
-
sessionAnchor: anchor,
|
|
2282
|
-
sessionId: ds?.session.sessionId,
|
|
2283
|
-
scope: ds?.scope ?? 'chat',
|
|
2284
|
-
chatId: ds?.chatId ?? `doc:${file.fileToken}`,
|
|
2285
|
-
commentTriggerMode: mode,
|
|
2286
|
-
managedBy: 'watch-comment',
|
|
2287
|
-
ownerOpenId: message.senderId,
|
|
2288
|
-
workingDir: effectiveDir,
|
|
2289
|
-
pollCursorAt,
|
|
2290
|
-
pollCursorReplyId,
|
|
2291
|
-
pollBaselineReady,
|
|
2292
|
-
createdAt: existing?.createdAt ?? Date.now(),
|
|
2293
|
-
};
|
|
2294
|
-
const { previous } = putDocSubscription(dataDir, larkAppId, subscription);
|
|
2295
|
-
const rebound = previous && previous.sessionAnchor !== anchor;
|
|
2296
|
-
let replyText = t(!ds ? 'cmd.watch.started_lazy' : rebound ? 'cmd.watch.started_moved' : 'cmd.watch.started', {
|
|
2297
|
-
title: file.fileToken.slice(0, 12),
|
|
2298
|
-
mode: modeLabel(mode),
|
|
2299
|
-
}, loc);
|
|
2300
|
-
if (effectiveDir)
|
|
2301
|
-
replyText += `\n📂 ${t('cmd.watch.working_dir', { dir: effectiveDir }, loc)}`;
|
|
2302
|
-
else
|
|
2303
|
-
replyText += `\n\n${t(ds ? 'cmd.watch.project_optional_session' : 'cmd.watch.project_optional_lazy', undefined, loc)}`;
|
|
2304
|
-
if (ds && deps.prewarmDocCommentSession) {
|
|
2305
|
-
try {
|
|
2306
|
-
await deps.prewarmDocCommentSession(ds, subscription);
|
|
2307
|
-
replyText += `\n\n${t('cmd.watch.prewarming', undefined, loc)}`;
|
|
2308
|
-
}
|
|
2309
|
-
catch (err) {
|
|
2310
|
-
logger.warn(`[${logTag}] /watch-comment prewarm failed for ${file.fileToken.slice(0, 12)}: ${err instanceof Error ? err.message : String(err)}`);
|
|
2311
|
-
replyText += `\n\n${t('cmd.watch.prewarm_failed', undefined, loc)}`;
|
|
2312
|
-
}
|
|
2313
|
-
}
|
|
2314
|
-
await sessionReply(rootId, replyText);
|
|
2315
|
-
logger.info(`[${logTag}] /watch-comment → ${file.fileType}:${file.fileToken.slice(0, 12)} mode=${mode}${effectiveDir ? ` wd=${effectiveDir}` : ''}${rebound ? ' (rebound)' : ''}${ds ? '' : ' (doc-native lazy session)'}`);
|
|
2316
|
-
}
|
|
2317
|
-
catch (err) {
|
|
2318
|
-
await sessionReply(rootId, t('cmd.watch.failed', { err: err instanceof Error ? err.message : String(err) }, loc));
|
|
2319
|
-
}
|
|
2320
|
-
break;
|
|
2321
|
-
}
|
|
2322
|
-
case '/vc': {
|
|
2323
|
-
if (!larkAppId) {
|
|
2324
|
-
await sessionReply(rootId, t('cmd.vc.no_session', undefined, loc));
|
|
2325
|
-
break;
|
|
2326
|
-
}
|
|
2327
|
-
const ownerOpenId = getOwnerOpenId(larkAppId);
|
|
2328
|
-
if (!ownerOpenId || message.senderId !== ownerOpenId) {
|
|
2329
|
-
await sessionReply(rootId, t('cmd.vc.owner_only', undefined, loc));
|
|
2330
|
-
break;
|
|
2331
|
-
}
|
|
2332
|
-
const request = parseVcMeetingPrepareCommand(message.content);
|
|
2333
|
-
const dataDir = config.session.dataDir;
|
|
2334
|
-
if (request.kind === 'usage' || request.kind === 'invalid') {
|
|
2335
|
-
const prefix = request.kind === 'invalid'
|
|
2336
|
-
? `${t('cmd.vc.invalid', undefined, loc)}\n\n`
|
|
2337
|
-
: '';
|
|
2338
|
-
await sessionReply(rootId, prefix + t('cmd.vc.usage', undefined, loc));
|
|
2339
|
-
break;
|
|
2340
|
-
}
|
|
2341
|
-
if (request.kind === 'status') {
|
|
2342
|
-
const requestedRecord = request.meetingNo
|
|
2343
|
-
? getVcMeetingPreparation(dataDir, larkAppId, request.meetingNo)
|
|
2344
|
-
: undefined;
|
|
2345
|
-
const records = request.meetingNo
|
|
2346
|
-
? (requestedRecord ? [requestedRecord] : [])
|
|
2347
|
-
: listVcMeetingPreparations(dataDir, larkAppId);
|
|
2348
|
-
if (records.length === 0) {
|
|
2349
|
-
await sessionReply(rootId, t('cmd.vc.none', undefined, loc));
|
|
2350
|
-
break;
|
|
2351
|
-
}
|
|
2352
|
-
const lines = records.map(record => [
|
|
2353
|
-
`• ${record.topic || record.meetingNo}`,
|
|
2354
|
-
` meetingNo: \`${record.meetingNo}\``,
|
|
2355
|
-
` chat: \`${record.prepChatId}\``,
|
|
2356
|
-
` agent: \`${record.agentAppId}\``,
|
|
2357
|
-
` Q&A: ${record.qaMode}`,
|
|
2358
|
-
].join('\n'));
|
|
2359
|
-
await sessionReply(rootId, [t('cmd.vc.status_title', undefined, loc), '', ...lines].join('\n'));
|
|
2360
|
-
break;
|
|
2361
|
-
}
|
|
2362
|
-
if (request.kind === 'off') {
|
|
2363
|
-
let count = 0;
|
|
2364
|
-
if (request.all) {
|
|
2365
|
-
for (const record of listVcMeetingPreparations(dataDir, larkAppId)) {
|
|
2366
|
-
if (removeVcMeetingPreparation(dataDir, larkAppId, record.meetingNo))
|
|
2367
|
-
count += 1;
|
|
2368
|
-
}
|
|
2369
|
-
}
|
|
2370
|
-
else if (request.meetingNo) {
|
|
2371
|
-
count = removeVcMeetingPreparation(dataDir, larkAppId, request.meetingNo) ? 1 : 0;
|
|
2372
|
-
}
|
|
2373
|
-
else if (ds) {
|
|
2374
|
-
count = removeVcMeetingPreparationsByChat(dataDir, larkAppId, ds.chatId);
|
|
2375
|
-
}
|
|
2376
|
-
await sessionReply(rootId, count > 0
|
|
2377
|
-
? t('cmd.vc.stopped', { count }, loc)
|
|
2378
|
-
: t('cmd.vc.none', undefined, loc));
|
|
2379
|
-
break;
|
|
2380
|
-
}
|
|
2381
|
-
if (!ds || ds.chatType !== 'group' || ds.scope !== 'chat') {
|
|
2382
|
-
await sessionReply(rootId, t('cmd.vc.need_group_chat', undefined, loc));
|
|
2383
|
-
break;
|
|
2384
|
-
}
|
|
2385
|
-
const existingInChat = findVcMeetingPreparationByChat(dataDir, larkAppId, ds.chatId);
|
|
2386
|
-
const record = putVcMeetingPreparation(dataDir, {
|
|
2387
|
-
larkAppId,
|
|
2388
|
-
meetingNo: request.meetingNo,
|
|
2389
|
-
...(request.meetingLink ? { meetingLink: request.meetingLink } : {}),
|
|
2390
|
-
prepChatId: ds.chatId,
|
|
2391
|
-
agentAppId: larkAppId,
|
|
2392
|
-
agentSessionId: ds.session.sessionId,
|
|
2393
|
-
ownerOpenId: message.senderId,
|
|
2394
|
-
qaMode: request.qaMode,
|
|
2395
|
-
});
|
|
2396
|
-
const replaced = existingInChat && existingInChat.meetingNo !== record.meetingNo
|
|
2397
|
-
? `\n${t('cmd.vc.replaced', { meetingNo: existingInChat.meetingNo }, loc)}`
|
|
2398
|
-
: '';
|
|
2399
|
-
let preparedText = t('cmd.vc.prepared', {
|
|
2400
|
-
meetingNo: record.meetingNo,
|
|
2401
|
-
qaMode: record.qaMode,
|
|
2402
|
-
}, loc) + replaced;
|
|
2403
|
-
const meetingProjectDir = ds.workingDir ?? ds.session.workingDir;
|
|
2404
|
-
preparedText += meetingProjectDir
|
|
2405
|
-
? `\n\n${t('cmd.vc.project_bound', { dir: meetingProjectDir }, loc)}`
|
|
2406
|
-
: `\n\n${t('cmd.vc.project_optional', undefined, loc)}`;
|
|
2407
|
-
await sessionReply(rootId, preparedText);
|
|
2408
|
-
logger.info(`[${logTag}] /vc prepare meetingNo=${record.meetingNo} chat=${record.prepChatId} agent=${record.agentAppId} qa=${record.qaMode}`);
|
|
2409
|
-
break;
|
|
2410
|
-
}
|
|
2411
|
-
case '/adopt': {
|
|
2412
|
-
const adoptArgs = message.content.replace(/^\/adopt\s*/i, '').trim();
|
|
2413
|
-
if (ds && isSessionTransferring(ds)) {
|
|
2414
|
-
await sessionReply(rootId, t('cmd.session.transfer_in_progress', undefined, loc));
|
|
2415
|
-
break;
|
|
2416
|
-
}
|
|
2417
|
-
if (ds?.adoptedFrom) {
|
|
2418
|
-
const adopted = ds.adoptedFrom;
|
|
2419
|
-
const cliName = sessionCliDisplayName(ds);
|
|
2420
|
-
const project = adopted.cwd ? (adopted.cwd.split('/').pop() || adopted.cwd) : '';
|
|
2421
|
-
const label = project ? `${cliName} · ${project}` : cliName;
|
|
2422
|
-
await sessionReply(rootId, t('cmd.adopt.already_adopted', { label, pane: adoptTargetLabel(adopted) }, loc));
|
|
2423
|
-
break;
|
|
2424
|
-
}
|
|
2425
|
-
const botCfgForAdopt = ds ? getBot(ds.larkAppId).config : (larkAppId ? getBot(larkAppId).config : undefined);
|
|
2426
|
-
if (botCfgForAdopt?.cliId === 'codex-app') {
|
|
2427
|
-
if (!ds) {
|
|
2428
|
-
await sessionReply(rootId, t('cmd.no_active_session', undefined, loc));
|
|
2429
|
-
break;
|
|
2430
|
-
}
|
|
2431
|
-
await handleCodexAppAdoptCommand(adoptArgs, rootId, ds, deps, larkAppId);
|
|
2432
|
-
break;
|
|
2433
|
-
}
|
|
2434
|
-
const botCliId = botCfgForAdopt?.cliId;
|
|
2435
|
-
const adoptSession = ds?.session;
|
|
2436
|
-
const adoptAnchor = ds ? sessionAnchorId(ds) : undefined;
|
|
2437
|
-
// Discover every supported backend, but only offer live sessions for
|
|
2438
|
-
// this bot's configured CLI. A Pi bot must not show Codex/TRAE panes:
|
|
2439
|
-
// adopting one would unexpectedly change the agent behind the bot.
|
|
2440
|
-
// collectAdoptCandidates folds live-pane + disk-resume discovery into
|
|
2441
|
-
// one snapshot; we cache it (by root message id) so the V2 picker's
|
|
2442
|
-
// search / page re-renders don't re-shell-out to tmux each click.
|
|
2443
|
-
const { collectAdoptCandidates, cacheAdoptCandidates } = await import('../services/adopt-picker.js');
|
|
2444
|
-
const candidates = await collectAdoptCandidates(botCliId, botCfgForAdopt?.cliPathOverride, activeSessions, discoverResumableSessionsForBot, ADOPT_RESUME_LIMIT, botCfgForAdopt?.cliRuntime?.executable);
|
|
2445
|
-
const sessions = candidates.sessions;
|
|
2446
|
-
const resumable = candidates.resumable;
|
|
2447
|
-
if (ds
|
|
2448
|
-
&& adoptSession
|
|
2449
|
-
&& adoptAnchor
|
|
2450
|
-
&& (ds.session !== adoptSession
|
|
2451
|
-
|| ds.session.status !== 'active'
|
|
2452
|
-
|| activeSessions.get(sessionKey(adoptAnchor, ds.larkAppId)) !== ds
|
|
2453
|
-
|| isSessionTransferring(ds))) {
|
|
2454
|
-
await sessionReply(rootId, t('cmd.session.transfer_in_progress', undefined, loc));
|
|
2455
|
-
break;
|
|
2456
|
-
}
|
|
2457
|
-
if (sessions.length === 0 && resumable.length === 0) {
|
|
2458
|
-
await sessionReply(rootId, t('cmd.adopt.no_sessions', undefined, loc));
|
|
2459
|
-
break;
|
|
2460
|
-
}
|
|
2461
|
-
const directTarget = adoptArgs;
|
|
2462
|
-
if (directTarget) {
|
|
2463
|
-
// Match a tmux address ("session:window.pane") OR a zellij target
|
|
2464
|
-
// ("session:paneId" / "session/paneId") against the merged list.
|
|
2465
|
-
const zellijNorm = directTarget.replace('/', ':');
|
|
2466
|
-
const target = sessions.find(s => 'zellijPaneId' in s
|
|
2467
|
-
? `${s.zellijSession}:${s.zellijPaneId}` === zellijNorm
|
|
2468
|
-
: adoptTargetLabel(s) === directTarget || adoptTargetKey(s) === directTarget || s.tmuxTarget === directTarget || s.herdrPaneId === directTarget);
|
|
2469
|
-
if (target) {
|
|
2470
|
-
if (ds)
|
|
2471
|
-
await startAdoptSession(target, ds, deps, larkAppId);
|
|
2472
|
-
break;
|
|
2473
|
-
}
|
|
2474
|
-
// Fall back to a resumable session matched by its CLI-native id.
|
|
2475
|
-
const resumeTarget = resumable.find(r => r.cliSessionId === directTarget);
|
|
2476
|
-
if (resumeTarget) {
|
|
2477
|
-
if (ds)
|
|
2478
|
-
await startResumeImportSession(resumeTarget, ds, deps, larkAppId);
|
|
2479
|
-
break;
|
|
2480
|
-
}
|
|
2481
|
-
await sessionReply(rootId, t('cmd.adopt.pane_not_found', { pane: directTarget }, loc));
|
|
2482
|
-
break;
|
|
2483
|
-
}
|
|
2484
|
-
// Cache the snapshot so the picker's search / page clicks reuse it
|
|
2485
|
-
// (confirm re-discovers to re-validate the live pane).
|
|
2486
|
-
cacheAdoptCandidates(rootId, candidates, Date.now());
|
|
2487
|
-
const cardJson = buildAdoptSelectCard(sessions, rootId, loc, resumable, undefined, message.senderId, candidates.resumeLimit, botCliId, ds
|
|
2488
|
-
? sessionConfiguredRuntimeDisplayName(ds.session, getBot(ds.larkAppId).config.cliRuntime)
|
|
2489
|
-
: configuredRuntimeDisplayName(botCfgForAdopt?.cliRuntime));
|
|
2490
|
-
await sessionReply(rootId, cardJson, 'interactive');
|
|
2491
|
-
break;
|
|
2492
|
-
}
|
|
2493
|
-
case '/oncall': {
|
|
2494
|
-
const args = message.content.replace(/^\/oncall\s*/i, '').trim();
|
|
2495
|
-
const [sub, ...rest] = args.length > 0 ? args.split(/\s+/) : [];
|
|
2496
|
-
const appId = larkAppId ?? ds?.larkAppId;
|
|
2497
|
-
const chatId = ds?.chatId;
|
|
2498
|
-
if (!appId || !chatId) {
|
|
2499
|
-
await sessionReply(rootId, t('cmd.oncall.need_group', undefined, loc));
|
|
2500
|
-
break;
|
|
2501
|
-
}
|
|
2502
|
-
if (!sub || sub === 'status' || sub === '状态') {
|
|
2503
|
-
const entry = getOncallStatus(appId, chatId);
|
|
2504
|
-
if (!entry) {
|
|
2505
|
-
await sessionReply(rootId, t('cmd.oncall.not_bound', undefined, loc));
|
|
2506
|
-
}
|
|
2507
|
-
else {
|
|
2508
|
-
await sessionReply(rootId, t('cmd.oncall.bound', { dir: entry.workingDir }, loc));
|
|
2509
|
-
}
|
|
2510
|
-
break;
|
|
2511
|
-
}
|
|
2512
|
-
if (sub === 'bind' || sub === '绑定') {
|
|
2513
|
-
const target = rest.join(' ').trim();
|
|
2514
|
-
if (!target) {
|
|
2515
|
-
await sessionReply(rootId, t('cmd.oncall.bind_usage', undefined, loc));
|
|
2516
|
-
break;
|
|
2517
|
-
}
|
|
2518
|
-
const validation = validateWorkingDir(target, loc, { autoCreate: true });
|
|
2519
|
-
if (!validation.ok) {
|
|
2520
|
-
await sessionReply(rootId, validation.error);
|
|
2521
|
-
break;
|
|
2522
|
-
}
|
|
2523
|
-
const resolvedPath = validation.resolvedPath;
|
|
2524
|
-
const result = await bindOncall(appId, chatId, target);
|
|
2525
|
-
if (!result.ok) {
|
|
2526
|
-
if (result.reason === 'bot_not_in_config') {
|
|
2527
|
-
await sessionReply(rootId, t('cmd.oncall.bind_failed_no_bot', undefined, loc));
|
|
2528
|
-
}
|
|
2529
|
-
else {
|
|
2530
|
-
await sessionReply(rootId, t('cmd.oncall.bind_failed', { reason: result.reason }, loc));
|
|
2531
|
-
}
|
|
2532
|
-
break;
|
|
2533
|
-
}
|
|
2534
|
-
const verb = result.created
|
|
2535
|
-
? t('cmd.oncall.verb_bound', undefined, loc)
|
|
2536
|
-
: t('cmd.oncall.verb_updated', undefined, loc);
|
|
2537
|
-
const createdNote = validation.created ? `\n\n${t('cmd.oncall.bind_created_note', undefined, loc)}` : '';
|
|
2538
|
-
await sessionReply(rootId, t('cmd.oncall.bind_success', {
|
|
2539
|
-
verb,
|
|
2540
|
-
chatId,
|
|
2541
|
-
target,
|
|
2542
|
-
resolved: resolvedPath,
|
|
2543
|
-
}, loc) + createdNote);
|
|
2544
|
-
logger.info(`[${logTag}] /oncall bind chat=${chatId} dir=${target}${validation.created ? ' (auto-created)' : ''}`);
|
|
2545
|
-
break;
|
|
2546
|
-
}
|
|
2547
|
-
if (sub === 'unbind' || sub === '解绑') {
|
|
2548
|
-
const result = await unbindOncall(appId, chatId);
|
|
2549
|
-
if (!result.ok) {
|
|
2550
|
-
await sessionReply(rootId, t('cmd.oncall.unbind_failed', { reason: result.reason }, loc));
|
|
2551
|
-
break;
|
|
2552
|
-
}
|
|
2553
|
-
if (!result.wasBound) {
|
|
2554
|
-
await sessionReply(rootId, t('cmd.oncall.unbind_not_bound', undefined, loc));
|
|
2555
|
-
}
|
|
2556
|
-
else {
|
|
2557
|
-
await sessionReply(rootId, t('cmd.oncall.unbind_success', undefined, loc));
|
|
2558
|
-
}
|
|
2559
|
-
logger.info(`[${logTag}] /oncall unbind chat=${chatId} wasBound=${result.wasBound}`);
|
|
2560
|
-
break;
|
|
2561
|
-
}
|
|
2562
|
-
await sessionReply(rootId, t('cmd.oncall.unknown_sub', { sub }, loc));
|
|
2563
|
-
break;
|
|
2564
|
-
}
|
|
2565
|
-
case '/group':
|
|
2566
|
-
case '/g': {
|
|
2567
|
-
const creatorAppId = larkAppId ?? ds?.larkAppId;
|
|
2568
|
-
if (!creatorAppId) {
|
|
2569
|
-
await sessionReply(rootId, t('cmd.group.no_bot', undefined, loc));
|
|
2570
|
-
break;
|
|
2571
|
-
}
|
|
2572
|
-
const senderOpenId = message.senderId;
|
|
2573
|
-
if (!senderOpenId) {
|
|
2574
|
-
await sessionReply(rootId, t('cmd.group.no_sender', undefined, loc));
|
|
2575
|
-
break;
|
|
2576
|
-
}
|
|
2577
|
-
// Each @-mentioned bot independently receives this same event and reaches
|
|
2578
|
-
// this handler, so exactly one must create the group and the rest must
|
|
2579
|
-
// stay silent. Intent: pull every @-mentioned bot into a new group, with
|
|
2580
|
-
// the FIRST mentioned bot doing the creating.
|
|
2581
|
-
//
|
|
2582
|
-
// Two distinct sources, each used for what it's reliable at:
|
|
2583
|
-
// • DETECTION ("is this @-mention a bot, and which is first?") uses
|
|
2584
|
-
// globalKnownBotNames() from bots-info.json — process-stable and
|
|
2585
|
-
// complete. getAllBots() can't be used (one daemon per bot ⇒ it only
|
|
2586
|
-
// sees self), and the live roster can transiently miss a bot; either
|
|
2587
|
-
// would let competing processes disagree on the first bot → split
|
|
2588
|
-
// brain. The name set + my own open_id give every process the same
|
|
2589
|
-
// leadership verdict with no API/cross-ref dependency.
|
|
2590
|
-
// • RESOLUTION (bot → larkAppId for the invite) uses the live roster
|
|
2591
|
-
// listChatBotMembers(), failing CLOSED on any miss.
|
|
2592
|
-
const mentions = message.mentions ?? [];
|
|
2593
|
-
// `/group` runs without a pre-created session (see
|
|
2594
|
-
// SESSIONLESS_DAEMON_COMMANDS), so the source chat comes from the
|
|
2595
|
-
// message; fall back to the active session when invoked mid-session.
|
|
2596
|
-
const sourceChatId = message.chatId ?? ds?.chatId;
|
|
2597
|
-
const knownBotNames = globalKnownBotNames();
|
|
2598
|
-
// Degraded-state guard: if the user @-mentioned someone but the global bot
|
|
2599
|
-
// registry is empty (bots-info.json missing/corrupt/not-yet-written), we
|
|
2600
|
-
// can't tell bots from users — so we can't elect a creator. Fail CLOSED
|
|
2601
|
-
// rather than fall through to "no bot mentions" → per-bot solo group,
|
|
2602
|
-
// which would let every @-mentioned bot create its own group.
|
|
2603
|
-
if (knownBotNames.size === 0 && mentions.some(m => !!m.name)) {
|
|
2604
|
-
logger.warn(`[${logTag}] /group: global bot registry empty (bots-info.json missing/corrupt); cannot elect a creator`);
|
|
2605
|
-
await sessionReply(rootId, t('cmd.group.resolve_failed', undefined, loc));
|
|
2606
|
-
break;
|
|
2607
|
-
}
|
|
2608
|
-
// The @-mentioned bots, in mention order. The first one is the creator.
|
|
2609
|
-
const botMentions = mentions.filter(m => m.name && knownBotNames.has(m.name.toLowerCase()));
|
|
2610
|
-
// ── Leader election ──────────────────────────────────────────────────
|
|
2611
|
-
const mentionedBotAppIds = [];
|
|
2612
|
-
const appIdToName = new Map();
|
|
2613
|
-
if (botMentions.length > 0) {
|
|
2614
|
-
const firstBot = botMentions[0];
|
|
2615
|
-
const myOpenId = getBotOpenId(creatorAppId);
|
|
2616
|
-
// Am I the first @-mentioned bot? My own open_id is always reliable in
|
|
2617
|
-
// my own app scope (Lark reports a bot its own open_id consistently),
|
|
2618
|
-
// so this needs no cross-ref. Name fallback only when my open_id isn't
|
|
2619
|
-
// probed yet AND my display name is globally unambiguous.
|
|
2620
|
-
const myName = getBot(creatorAppId).botName?.toLowerCase();
|
|
2621
|
-
const myNameAmbiguous = !!myName && botMentions.filter(m => m.name?.toLowerCase() === myName).length > 1;
|
|
2622
|
-
const iAmFirstBot = (!!myOpenId && firstBot.openId === myOpenId) ||
|
|
2623
|
-
(!myOpenId && !!myName && !myNameAmbiguous && firstBot.name?.toLowerCase() === myName);
|
|
2624
|
-
if (!iAmFirstBot) {
|
|
2625
|
-
logger.info(`[${logTag}] /group: not the first @-mentioned bot (first="${firstBot.name}"), staying silent`);
|
|
2626
|
-
break;
|
|
2627
|
-
}
|
|
2628
|
-
// I'm the creator. Resolving invitees needs the chat roster — fail
|
|
2629
|
-
// CLOSED if it's missing rather than fall through to a per-bot solo
|
|
2630
|
-
// group (which would let every mentioned bot create one).
|
|
2631
|
-
if (!sourceChatId) {
|
|
2632
|
-
logger.warn(`[${logTag}] /group: missing source chatId, cannot resolve @-mentioned bots`);
|
|
2633
|
-
await sessionReply(rootId, t('cmd.group.resolve_failed', undefined, loc));
|
|
2634
|
-
break;
|
|
2635
|
-
}
|
|
2636
|
-
let members = [];
|
|
2637
|
-
try {
|
|
2638
|
-
members = await listChatBotMembers(creatorAppId, sourceChatId);
|
|
2639
|
-
}
|
|
2640
|
-
catch (e) {
|
|
2641
|
-
logger.warn(`[${logTag}] /group failed to list chat bot members: ${e?.message ?? e}`);
|
|
2642
|
-
}
|
|
2643
|
-
const memberByOpenId = new Map(members.map(m => [m.openId, m]));
|
|
2644
|
-
for (const m of members) {
|
|
2645
|
-
if (m.larkAppId && m.displayName)
|
|
2646
|
-
appIdToName.set(m.larkAppId, m.displayName);
|
|
2647
|
-
}
|
|
2648
|
-
// Resolve each bot mention → larkAppId by open_id (our scope; reliable
|
|
2649
|
-
// for distinct bots, and disambiguates duplicate display names), in
|
|
2650
|
-
// mention order, deduped. Fail CLOSED on any unresolved bot rather than
|
|
2651
|
-
// build a group missing an intended one.
|
|
2652
|
-
const seen = new Set();
|
|
2653
|
-
let unresolved;
|
|
2654
|
-
for (const bm of botMentions) {
|
|
2655
|
-
const mem = bm.openId ? memberByOpenId.get(bm.openId) : undefined;
|
|
2656
|
-
if (!mem || !mem.larkAppId) {
|
|
2657
|
-
unresolved = bm.name;
|
|
2658
|
-
break;
|
|
2659
|
-
}
|
|
2660
|
-
if (!seen.has(mem.larkAppId)) {
|
|
2661
|
-
seen.add(mem.larkAppId);
|
|
2662
|
-
mentionedBotAppIds.push(mem.larkAppId);
|
|
2663
|
-
}
|
|
2664
|
-
}
|
|
2665
|
-
if (unresolved) {
|
|
2666
|
-
logger.warn(`[${logTag}] /group: could not resolve @-mentioned bot "${unresolved}" to an app id; aborting`);
|
|
2667
|
-
await sessionReply(rootId, t('cmd.group.resolve_failed', undefined, loc));
|
|
2668
|
-
break;
|
|
2669
|
-
}
|
|
2670
|
-
}
|
|
2671
|
-
// Extract the requested group name. Strip whichever alias was used, then
|
|
2672
|
-
// remove any `@<name>` mention tokens that leaked into the body (Lark
|
|
2673
|
-
// renders mentions as literal `@Name` text in content), then take the
|
|
2674
|
-
// first non-blank line so multi-line pastes don't smear into the name.
|
|
2675
|
-
let rawArgs = message.content.replace(/^\/(group|g)\s*/i, '');
|
|
2676
|
-
for (const m of mentions) {
|
|
2677
|
-
if (m.name)
|
|
2678
|
-
rawArgs = rawArgs.split(`@${m.name}`).join(' ');
|
|
2679
|
-
}
|
|
2680
|
-
let roleProfileId;
|
|
2681
|
-
const roleProfileArg = rawArgs.match(/(?:^|\s)--role-profile(?:=|\s+)(\S+)/);
|
|
2682
|
-
if (roleProfileArg) {
|
|
2683
|
-
if (!isValidRoleProfileId(roleProfileArg[1])) {
|
|
2684
|
-
await sessionReply(rootId, t('role.profile.invalid', undefined, loc));
|
|
2685
|
-
break;
|
|
2686
|
-
}
|
|
2687
|
-
roleProfileId = roleProfileArg[1];
|
|
2688
|
-
rawArgs = rawArgs.replace(roleProfileArg[0], ' ');
|
|
2689
|
-
}
|
|
2690
|
-
const firstLine = rawArgs.split(/\r?\n/).map(s => s.trim()).find(Boolean) ?? '';
|
|
2691
|
-
let baseGroupName;
|
|
2692
|
-
if (firstLine) {
|
|
2693
|
-
baseGroupName = firstLine;
|
|
2694
|
-
}
|
|
2695
|
-
else {
|
|
2696
|
-
const now = new Date();
|
|
2697
|
-
const ts = `${String(now.getMonth() + 1).padStart(2, '0')}/${String(now.getDate()).padStart(2, '0')} ${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}`;
|
|
2698
|
-
baseGroupName = t('cmd.group.empty_fallback', { ts }, loc);
|
|
2699
|
-
}
|
|
2700
|
-
const groupName = formatSlashGroupName(baseGroupName, readGlobalConfig().groupNamePrefix);
|
|
2701
|
-
// Bots to invite: every @-mentioned bot (creator filtered out internally
|
|
2702
|
-
// by the service). Empty mentions → solo group (creator only).
|
|
2703
|
-
const larkAppIdsForGroup = mentionedBotAppIds.length > 0 ? mentionedBotAppIds : [creatorAppId];
|
|
2704
|
-
try {
|
|
2705
|
-
const { createGroupWithBots } = await import('../services/group-creator.js');
|
|
2706
|
-
const result = await createGroupWithBots({
|
|
2707
|
-
creatorLarkAppId: creatorAppId,
|
|
2708
|
-
larkAppIds: larkAppIdsForGroup,
|
|
2709
|
-
name: groupName,
|
|
2710
|
-
userOpenIds: [senderOpenId],
|
|
2711
|
-
transferOwnerTo: senderOpenId,
|
|
2712
|
-
notifyOwnerOpenId: senderOpenId,
|
|
2713
|
-
roleProfileId,
|
|
2714
|
-
});
|
|
2715
|
-
// Prefer the shareable join link (others can click to *join*); fall
|
|
2716
|
-
// back to the member-only applink URL when Lark's link API failed.
|
|
2717
|
-
const applink = chatAppLink(result.chatId, normalizeBrand(getBot(creatorAppId).config.brand));
|
|
2718
|
-
const link = result.shareLink ?? applink;
|
|
2719
|
-
// Partial failures are non-fatal — the chat exists; surface them as
|
|
2720
|
-
// hints so the user knows whether to expect to be auto-invited.
|
|
2721
|
-
const hints = [];
|
|
2722
|
-
if (result.invalidUserIds.includes(senderOpenId)) {
|
|
2723
|
-
hints.push(t('cmd.group.warn_invite_rejected', undefined, loc));
|
|
2724
|
-
}
|
|
2725
|
-
else if (result.transferError) {
|
|
2726
|
-
hints.push(t('cmd.group.warn_transfer_failed', { reason: result.transferError }, loc));
|
|
2727
|
-
}
|
|
2728
|
-
// Share-link fetch failed → the displayed link is the member-only
|
|
2729
|
-
// applink; warn the user so they don't expect non-members to join via it.
|
|
2730
|
-
if (!result.shareLink && result.shareLinkError) {
|
|
2731
|
-
logger.warn(`[${logTag}] /group share-link unavailable, using applink: ${result.shareLinkError}`);
|
|
2732
|
-
hints.push(t('cmd.group.warn_share_link_failed', undefined, loc));
|
|
2733
|
-
}
|
|
2734
|
-
// List every bot in the new group (creator included), and warn about
|
|
2735
|
-
// any Feishu rejected. Names come from the chat roster (members) since
|
|
2736
|
-
// getBot() only knows this process's own bot in the one-daemon-per-bot
|
|
2737
|
-
// model; fall back to the registry/raw id for anything not in the map.
|
|
2738
|
-
const nameOf = (id) => appIdToName.get(id) ?? botDisplayName(id);
|
|
2739
|
-
const groupBotIds = larkAppIdsForGroup.filter(id => !result.invalidBotIds.includes(id));
|
|
2740
|
-
if (groupBotIds.length > 1) {
|
|
2741
|
-
hints.push(t('cmd.group.bots_invited', { bots: groupBotIds.map(nameOf).join('、') }, loc));
|
|
2742
|
-
}
|
|
2743
|
-
if (result.invalidBotIds.length > 0) {
|
|
2744
|
-
hints.push(t('cmd.group.warn_bots_rejected', { bots: result.invalidBotIds.map(nameOf).join('、') }, loc));
|
|
2745
|
-
}
|
|
2746
|
-
if (roleProfileId) {
|
|
2747
|
-
if (result.roleProfileBootstrapError) {
|
|
2748
|
-
hints.push(t('cmd.group.role_profile_bootstrap_failed', { profile: roleProfileId, reason: result.roleProfileBootstrapError ?? 'unknown' }, loc));
|
|
2749
|
-
}
|
|
2750
|
-
else {
|
|
2751
|
-
hints.push(t('cmd.group.role_profile_bootstrap_sent', { profile: roleProfileId }, loc));
|
|
2752
|
-
}
|
|
2753
|
-
}
|
|
2754
|
-
const hintsText = hints.length > 0 ? '\n' + hints.join('\n') : '';
|
|
2755
|
-
await sessionReply(rootId, t('cmd.group.created', { name: groupName, link, hints: hintsText }, loc));
|
|
2756
|
-
logger.info(`[${logTag}] /group created chat=${result.chatId} name="${groupName}" bots=[${larkAppIdsForGroup.join(',')}] invitee=${senderOpenId}`);
|
|
2757
|
-
// Intentionally NO auto-bootstrap (repo-select card / chat-scope
|
|
2758
|
-
// session) here: the group name rarely carries enough context to seed
|
|
2759
|
-
// a useful prompt. The user starts a real conversation with the bot in
|
|
2760
|
-
// the new group, which spawns the session on first message.
|
|
2761
|
-
}
|
|
2762
|
-
catch (err) {
|
|
2763
|
-
logger.error(`[${logTag}] /group failed: ${err?.message ?? err}`);
|
|
2764
|
-
await sessionReply(rootId, t('cmd.group.failed', { error: err?.message ?? String(err) }, loc));
|
|
2765
|
-
}
|
|
2766
|
-
break;
|
|
2767
|
-
}
|
|
2768
|
-
/**
|
|
2769
|
-
* `/relay --create <群名> @bot [@bot...]` — create a new chat, invite
|
|
2770
|
-
* the @-mentioned bots, then migrate every bot's session in this
|
|
2771
|
-
* thread (including the leader's) into the new chat.
|
|
2772
|
-
*
|
|
2773
|
-
* p2p (私聊) variant: `/relay --create [群名]` with NO mentions — DMs
|
|
2774
|
-
* have no member roster so @-ing a bot is impossible there. The bot
|
|
2775
|
-
* itself is the sole participant and leader; the new group is user +
|
|
2776
|
-
* this bot, and the DM session migrates over (solo relay, no peers).
|
|
2777
|
-
*
|
|
2778
|
-
* Two-path command:
|
|
2779
|
-
* • `--create` (PR2) — implemented below; creates a new chat.
|
|
2780
|
-
* • no flag (PR3) — picker card listing user's relayable sessions
|
|
2781
|
-
* in OTHER chats so the user can pull one into
|
|
2782
|
-
* the current chat. Stubbed for now.
|
|
2783
|
-
*
|
|
2784
|
-
* Leader election is `mentions[0]` (identical to /group). The leader
|
|
2785
|
-
* is the only daemon that:
|
|
2786
|
-
* 1. Creates the new chat (createGroupWithBots)
|
|
2787
|
-
* 2. Sends the M1 announcement message (its message_id becomes the
|
|
2788
|
-
* shared rootMessageId for all relayed sessions — multi-bot
|
|
2789
|
-
* sessions co-anchor on the same root via different larkAppIds)
|
|
2790
|
-
* 3. Transfers its own session (if any) via local transferSession()
|
|
2791
|
-
* 4. POSTs /api/sessions/migrate-to-chat to every peer daemon to
|
|
2792
|
-
* ask them to transfer their own session at the same anchor
|
|
2793
|
-
* 5. Aggregates results into a single reply in the source thread
|
|
2794
|
-
*
|
|
2795
|
-
* Owner-only: only the source session's `ownerOpenId` may invoke. Peers
|
|
2796
|
-
* enforce the same check independently inside the migrate endpoint.
|
|
2797
|
-
*
|
|
2798
|
-
* Failure mode: best-effort, no rollback. Peers that timeout / fail /
|
|
2799
|
-
* are offline simply appear in the report as "skipped". The new chat
|
|
2800
|
-
* and any successful transfers stand.
|
|
2801
|
-
*/
|
|
2802
|
-
case '/relay': {
|
|
2803
|
-
const argsLine = message.content.replace(/^\/relay\s*/i, '').trim();
|
|
2804
|
-
if (!/^--create\b/i.test(argsLine)) {
|
|
2805
|
-
// ── Pull picker ───────────────────────────────────────────────────
|
|
2806
|
-
// /relay (no flag) lives in the *target* chat — list the operator's
|
|
2807
|
-
// own active sessions in OTHER chats so they can pull one in.
|
|
2808
|
-
//
|
|
2809
|
-
// Filter:
|
|
2810
|
-
// • same bot (this larkAppId)
|
|
2811
|
-
// • session is active (has a worker / appears in activeSessions)
|
|
2812
|
-
// • session NOT in the current chat (can't relay to yourself)
|
|
2813
|
-
// • operator IS the session owner (owner-only access)
|
|
2814
|
-
//
|
|
2815
|
-
// The button's `target_chat_id` / `target_root_id` are the chat we're
|
|
2816
|
-
// pulling INTO (the chat hosting this command). card-handler uses
|
|
2817
|
-
// them to invoke transferSession after sending the M1 announcement.
|
|
2818
|
-
const operatorOpenId = message.senderId;
|
|
2819
|
-
if (!operatorOpenId) {
|
|
2820
|
-
await sessionReply(rootId, t('cmd.relay.no_sender', undefined, loc));
|
|
2821
|
-
break;
|
|
2822
|
-
}
|
|
2823
|
-
const myAppId = larkAppId ?? ds?.larkAppId;
|
|
2824
|
-
if (!myAppId) {
|
|
2825
|
-
await sessionReply(rootId, t('cmd.group.no_bot', undefined, loc));
|
|
2826
|
-
break;
|
|
2827
|
-
}
|
|
2828
|
-
const targetChatId = ds?.chatId;
|
|
2829
|
-
if (!targetChatId) {
|
|
2830
|
-
await sessionReply(rootId, t('cmd.relay.no_session', undefined, loc));
|
|
2831
|
-
break;
|
|
2832
|
-
}
|
|
2833
|
-
// ── Target-routing resolution ─────────────────────────────────────
|
|
2834
|
-
// Resolve the chat mode once, then compute WHERE the relayed session
|
|
2835
|
-
// should land via resolveRelayTargetRouting (mirrors decideRouting;
|
|
2836
|
-
// 话题群 / 线程内 / 普通群 new-topic·shared → thread-scope, 普通群
|
|
2837
|
-
// flat → chat-scope; DM 扁平(p2pMode chat) → chat-scope, DM 话题模式
|
|
2838
|
-
// → thread-scope seeded on the /relay message).
|
|
2839
|
-
// p2p is authoritative from `ds.chatType` (recorded off the Lark
|
|
2840
|
-
// event payload — doesn't drift, and the API's safe-default 'group'
|
|
2841
|
-
// on failure would misclassify a DM); only group chats need the API
|
|
2842
|
-
// call to split topic-vs-regular (both record chatType 'group').
|
|
2843
|
-
const targetIsP2p = ds?.chatType === 'p2p';
|
|
2844
|
-
const targetChatType = targetIsP2p ? 'p2p' : 'group';
|
|
2845
|
-
let targetChatMode = 'p2p';
|
|
2846
|
-
if (!targetIsP2p) {
|
|
2847
|
-
const { getChatNameAndMode } = await import('../im/lark/client.js');
|
|
2848
|
-
const info = await getChatNameAndMode(myAppId, targetChatId).catch(() => null);
|
|
2849
|
-
targetChatMode = info?.mode ?? 'group';
|
|
2850
|
-
}
|
|
2851
|
-
const { resolveRelayTargetRouting } = await import('../im/lark/relay-target-routing.js');
|
|
2852
|
-
const targetRouting = resolveRelayTargetRouting({
|
|
2853
|
-
larkAppId: myAppId,
|
|
2854
|
-
chatId: targetChatId,
|
|
2855
|
-
message: { messageId: message.messageId, rootId: message.rootId || undefined, threadId: message.threadId },
|
|
2856
|
-
chatMode: targetChatMode,
|
|
2857
|
-
});
|
|
2858
|
-
const targetScope = targetRouting.scope;
|
|
2859
|
-
const targetAnchor = targetRouting.anchor;
|
|
2860
|
-
// ── Reply WHERE the user typed /relay ─────────────────────────────
|
|
2861
|
-
// Not through sessionReply: in chat-scope groups (普通群扁平 /
|
|
2862
|
-
// chat-topic / shared) that path either leaks to the chat top level
|
|
2863
|
-
// (the /relay scratch has no turn state to fold back into) or lands
|
|
2864
|
-
// in the CURRENT turn's 话题 (a real chat-scope session) — both away
|
|
2865
|
-
// from the 话题 the user invoked in (申晗 live 反馈). The target
|
|
2866
|
-
// routing already encodes the invocation spot:
|
|
2867
|
-
// thread → reply_in_thread into that 话题 (for 话题群 / DM-thread
|
|
2868
|
-
// top-level this seeds the 话题 on the /relay message —
|
|
2869
|
-
// same place the relayed session will land);
|
|
2870
|
-
// chat → quote-reply the /relay message at the top level.
|
|
2871
|
-
// Fallback to sessionReply if the reply API refuses (e.g. the
|
|
2872
|
-
// command message was withdrawn mid-flight).
|
|
2873
|
-
const replyAtInvocation = async (content, msgType) => {
|
|
2874
|
-
try {
|
|
2875
|
-
await replyMessage(myAppId, targetScope === 'thread' ? targetAnchor : message.messageId, content, msgType ?? 'text',
|
|
2876
|
-
/*replyInThread*/ targetScope === 'thread');
|
|
2877
|
-
}
|
|
2878
|
-
catch (err) {
|
|
2879
|
-
logger.warn(`[${logTag}] /relay reply-at-invocation failed (${err instanceof Error ? err.message : err}); falling back to sessionReply`);
|
|
2880
|
-
await sessionReply(rootId, content, msgType);
|
|
2881
|
-
}
|
|
2882
|
-
};
|
|
2883
|
-
// ── Existing-session guard (anchor-based) ─────────────────────────
|
|
2884
|
-
// A real session already sitting AT the target anchor would collide
|
|
2885
|
-
// on sessionKey(targetAnchor, larkAppId) after transfer — Map.set
|
|
2886
|
-
// would orphan its worker. Scratch placeholders (worker:null, e.g.
|
|
2887
|
-
// the /relay command's own record at this anchor) are NOT a conflict;
|
|
2888
|
-
// transferSession closes them inline. We do NOT exclude `ds`: if
|
|
2889
|
-
// /relay rides an existing real session at the anchor, `ds` itself IS
|
|
2890
|
-
// the conflict. Anchor-based so同群 other-topic sessions (different
|
|
2891
|
-
// anchor) don't false-positive — that's what enables 同群话题间搬运.
|
|
2892
|
-
const conflict = [...activeSessions.values()].find(c => c.larkAppId === myAppId
|
|
2893
|
-
&& sessionAnchorId(c) === targetAnchor
|
|
2894
|
-
&& !!c.worker // real running session, not a placeholder
|
|
2895
|
-
);
|
|
2896
|
-
if (conflict) {
|
|
2897
|
-
await replyAtInvocation(t('cmd.relay.target_has_session', { title: conflict.session.title || conflict.session.sessionId.substring(0, 8) }, loc));
|
|
2898
|
-
break;
|
|
2899
|
-
}
|
|
2900
|
-
// Shared candidate-collection logic — used here at initial render
|
|
2901
|
-
// and again in card-handler when the user clicks a card to switch
|
|
2902
|
-
// selection (the card re-render needs the same filtered list).
|
|
2903
|
-
// Excludes (by anchor) the target itself; keeps cross-group + 同群
|
|
2904
|
-
// other-topic sessions. Resolves friendly chat names + modes.
|
|
2905
|
-
const { collectRelayPickerEntries } = await import('../services/relay-picker.js');
|
|
2906
|
-
const entries = await collectRelayPickerEntries(activeSessions, myAppId, targetAnchor, operatorOpenId);
|
|
2907
|
-
const { buildRelayPickerCard } = await import('../im/lark/card-builder.js');
|
|
2908
|
-
// ── Ephemeral (仅邀请者可见) picker ────────────────────────────────
|
|
2909
|
-
// The picker exposes session metadata — title + source-chat name — to
|
|
2910
|
-
// everyone who can see the message. When the bot runs in privateCard
|
|
2911
|
-
// mode we hide it: send the picker as an ephemeral card visible only to
|
|
2912
|
-
// the invoker.
|
|
2913
|
-
//
|
|
2914
|
-
// Gate on group + privateCard + **chat-scope**. The chat-scope clause
|
|
2915
|
-
// is load-bearing: the ephemeral API (`ephemeral/v1/send`) takes a
|
|
2916
|
-
// `chat_id` only — it has NO thread/root anchor — so a thread-scope
|
|
2917
|
-
// target (话题群 / 话题 inside a 普通群 / new-topic·shared) can't keep the
|
|
2918
|
-
// card in its 话题. A 话题群 rejects with 18053 (→ fall back below), but
|
|
2919
|
-
// a 话题 inside a 普通群 SUCCEEDS and the card escapes to the group top
|
|
2920
|
-
// level. This is the same trap `deliverEphemeralOrReply` (worker-pool)
|
|
2921
|
-
// guards against with a REGRESSION test; PR #164 was the original live
|
|
2922
|
-
// fix. Per 申晗 (2026-07-29): 话题内公开可接受 — so thread-scope pickers
|
|
2923
|
-
// stay on the visible in-thread reply (public card in the 话题), and
|
|
2924
|
-
// ephemeral is scoped to flat 普通群 only, mirroring /card & /close
|
|
2925
|
-
// private cards. p2p has no ephemeral option; an unexpected reject
|
|
2926
|
-
// (18053 etc.) still falls back to the visible reply below.
|
|
2927
|
-
const privatePicker = targetChatType === 'group'
|
|
2928
|
-
&& targetScope === 'chat'
|
|
2929
|
-
&& getBot(myAppId).config.privateCard === true;
|
|
2930
|
-
const card = buildRelayPickerCard(entries, targetChatId, targetAnchor, operatorOpenId, loc, undefined, targetScope, targetChatType, privatePicker ? 'private' : 'public');
|
|
2931
|
-
if (privatePicker) {
|
|
2932
|
-
const { sendEphemeralCard } = await import('../im/lark/client.js');
|
|
2933
|
-
try {
|
|
2934
|
-
await sendEphemeralCard(myAppId, targetChatId, operatorOpenId, card);
|
|
2935
|
-
}
|
|
2936
|
-
catch (err) {
|
|
2937
|
-
// Ephemeral unavailable here (18053 topic / permission / network):
|
|
2938
|
-
// fall back to the visible reply so the picker still works — the
|
|
2939
|
-
// privacy win is best-effort, correctness is not.
|
|
2940
|
-
logger.warn(`[${logTag}] /relay ephemeral picker failed (${err instanceof Error ? err.message : err}); sending visible picker`);
|
|
2941
|
-
const visibleCard = buildRelayPickerCard(entries, targetChatId, targetAnchor, operatorOpenId, loc, undefined, targetScope, targetChatType, 'public');
|
|
2942
|
-
await replyAtInvocation(visibleCard, 'interactive');
|
|
2943
|
-
}
|
|
2944
|
-
}
|
|
2945
|
-
else {
|
|
2946
|
-
await replyAtInvocation(card, 'interactive');
|
|
2947
|
-
}
|
|
2948
|
-
break;
|
|
2949
|
-
}
|
|
2950
|
-
const afterFlag = argsLine.replace(/^--create\s*/i, '').trim();
|
|
2951
|
-
const creatorAppId = larkAppId ?? ds?.larkAppId;
|
|
2952
|
-
if (!creatorAppId) {
|
|
2953
|
-
await sessionReply(rootId, t('cmd.group.no_bot', undefined, loc));
|
|
2954
|
-
break;
|
|
2955
|
-
}
|
|
2956
|
-
const senderOpenId = message.senderId;
|
|
2957
|
-
// Cross-app stable identity — peer daemons can't compare against
|
|
2958
|
-
// leader's open_id directly because the same user has a different
|
|
2959
|
-
// open_id in each bot's namespace. union_id is shared per tenant.
|
|
2960
|
-
// We pass it through the migrate-to-chat HTTP body; peers compare
|
|
2961
|
-
// against their session's `ownerUnionId` (with fallback to
|
|
2962
|
-
// open_id for sessions persisted before this field existed).
|
|
2963
|
-
const senderUnionId = message.senderUnionId;
|
|
2964
|
-
if (!senderOpenId) {
|
|
2965
|
-
await sessionReply(rootId, t('cmd.relay.no_sender', undefined, loc));
|
|
2966
|
-
break;
|
|
2967
|
-
}
|
|
2968
|
-
// `--create` must be invoked inside an existing thread — the source
|
|
2969
|
-
// anchor for peer transfers comes from `ds`. (Picker mode in PR3 is
|
|
2970
|
-
// allowed without a session.)
|
|
2971
|
-
if (!ds) {
|
|
2972
|
-
await sessionReply(rootId, t('cmd.relay.no_session', undefined, loc));
|
|
2973
|
-
break;
|
|
2974
|
-
}
|
|
2975
|
-
// Front-loaded guards — transferSession refuses adoptedFrom /
|
|
2976
|
-
// pendingRepo too, but only after createGroupWithBots has already
|
|
2977
|
-
// built a new chat. Failing here keeps relay clean and avoids
|
|
2978
|
-
// orphan-chat garbage when the operation can't possibly succeed.
|
|
2979
|
-
if (ds.session.adoptedFrom) {
|
|
2980
|
-
await sessionReply(rootId, t('cmd.relay.adopt_not_relayable', undefined, loc));
|
|
2981
|
-
break;
|
|
2982
|
-
}
|
|
2983
|
-
if (ds.pendingRepo) {
|
|
2984
|
-
await sessionReply(rootId, t('cmd.relay.not_started_yet', undefined, loc));
|
|
2985
|
-
break;
|
|
2986
|
-
}
|
|
2987
|
-
// ── p2p (私聊) solo relay: no mention gate, no leader election ──────
|
|
2988
|
-
// 飞书私聊里 @ 不到任何机器人(DM 没有成员列表),mention 门与 leader
|
|
2989
|
-
// 选举在这里没有意义 —— 本 bot 就是唯一参与者兼 leader,新群 = 用户 +
|
|
2990
|
-
// 本 bot,无 peer 协调(peerAppIds 自然为空)。群聊路径语义不变。
|
|
2991
|
-
// chatType 取自 ds(会话创建时从 Lark 事件记录,权威、不漂移)。
|
|
2992
|
-
const sourceIsP2p = ds.chatType === 'p2p';
|
|
2993
|
-
// ── Mention parsing & leader election (mirror of /group) ───────────
|
|
2994
|
-
const mentions = message.mentions ?? [];
|
|
2995
|
-
const knownBotNames = globalKnownBotNames();
|
|
2996
|
-
const botMentions = sourceIsP2p ? [] : mentions.filter(m => m.name && knownBotNames.has(m.name.toLowerCase()));
|
|
2997
|
-
if (!sourceIsP2p) {
|
|
2998
|
-
if (knownBotNames.size === 0 && mentions.some(m => !!m.name)) {
|
|
2999
|
-
logger.warn(`[${logTag}] /relay --create: global bot registry empty; cannot elect a creator`);
|
|
3000
|
-
await sessionReply(rootId, t('cmd.relay.resolve_failed', undefined, loc));
|
|
3001
|
-
break;
|
|
3002
|
-
}
|
|
3003
|
-
if (botMentions.length === 0) {
|
|
3004
|
-
await sessionReply(rootId, t('cmd.relay.no_mentions', undefined, loc));
|
|
3005
|
-
break;
|
|
3006
|
-
}
|
|
3007
|
-
// Am I `mentions[0]`?
|
|
3008
|
-
const firstBot = botMentions[0];
|
|
3009
|
-
const myOpenId = getBotOpenId(creatorAppId);
|
|
3010
|
-
const myName = getBot(creatorAppId).botName?.toLowerCase();
|
|
3011
|
-
const myNameAmbiguous = !!myName
|
|
3012
|
-
&& botMentions.filter(m => m.name?.toLowerCase() === myName).length > 1;
|
|
3013
|
-
const iAmFirstBot = (!!myOpenId && firstBot.openId === myOpenId) ||
|
|
3014
|
-
(!myOpenId && !!myName && !myNameAmbiguous && firstBot.name?.toLowerCase() === myName);
|
|
3015
|
-
if (!iAmFirstBot) {
|
|
3016
|
-
logger.info(`[${logTag}] /relay --create: not the first @-mentioned bot, staying silent`);
|
|
3017
|
-
break;
|
|
3018
|
-
}
|
|
3019
|
-
}
|
|
3020
|
-
// Owner-only — only the source session owner may relay this session.
|
|
3021
|
-
if (ds.session.ownerOpenId && ds.session.ownerOpenId !== senderOpenId) {
|
|
3022
|
-
await sessionReply(rootId, t('cmd.relay.not_owner', undefined, loc));
|
|
3023
|
-
break;
|
|
3024
|
-
}
|
|
3025
|
-
// ── Resolve @-bots to larkAppIds via the source chat's bot roster ──
|
|
3026
|
-
// p2p: 跳过成员表解析(DM 没有 bot roster,listChatBotMembers 会失败),
|
|
3027
|
-
// 参与者就是本 bot 自己;名字兜底走 botDisplayName(nameOf)。
|
|
3028
|
-
const sourceChatId = ds.chatId;
|
|
3029
|
-
const appIdToName = new Map();
|
|
3030
|
-
const mentionedBotAppIds = [];
|
|
3031
|
-
if (sourceIsP2p) {
|
|
3032
|
-
mentionedBotAppIds.push(creatorAppId);
|
|
3033
|
-
}
|
|
3034
|
-
else {
|
|
3035
|
-
let members = [];
|
|
3036
|
-
try {
|
|
3037
|
-
members = await listChatBotMembers(creatorAppId, sourceChatId);
|
|
3038
|
-
}
|
|
3039
|
-
catch (e) {
|
|
3040
|
-
logger.warn(`[${logTag}] /relay --create: failed to list source chat members: ${e?.message ?? e}`);
|
|
3041
|
-
}
|
|
3042
|
-
const memberByOpenId = new Map(members.map(m => [m.openId, m]));
|
|
3043
|
-
for (const m of members) {
|
|
3044
|
-
if (m.larkAppId && m.displayName)
|
|
3045
|
-
appIdToName.set(m.larkAppId, m.displayName);
|
|
3046
|
-
}
|
|
3047
|
-
const seenApp = new Set();
|
|
3048
|
-
let unresolved;
|
|
3049
|
-
for (const bm of botMentions) {
|
|
3050
|
-
const mem = bm.openId ? memberByOpenId.get(bm.openId) : undefined;
|
|
3051
|
-
if (!mem || !mem.larkAppId) {
|
|
3052
|
-
unresolved = bm.name;
|
|
3053
|
-
break;
|
|
3054
|
-
}
|
|
3055
|
-
if (!seenApp.has(mem.larkAppId)) {
|
|
3056
|
-
seenApp.add(mem.larkAppId);
|
|
3057
|
-
mentionedBotAppIds.push(mem.larkAppId);
|
|
3058
|
-
}
|
|
3059
|
-
}
|
|
3060
|
-
if (unresolved) {
|
|
3061
|
-
logger.warn(`[${logTag}] /relay --create: unresolved bot "${unresolved}"`);
|
|
3062
|
-
await sessionReply(rootId, t('cmd.relay.resolve_failed', undefined, loc));
|
|
3063
|
-
break;
|
|
3064
|
-
}
|
|
3065
|
-
}
|
|
3066
|
-
// ── Group name extraction (mirror of /group) ───────────────────────
|
|
3067
|
-
let rawArgs = afterFlag;
|
|
3068
|
-
for (const m of mentions) {
|
|
3069
|
-
if (m.name)
|
|
3070
|
-
rawArgs = rawArgs.split(`@${m.name}`).join(' ');
|
|
3071
|
-
}
|
|
3072
|
-
const firstLine = rawArgs.split(/\r?\n/).map(s => s.trim()).find(Boolean) ?? '';
|
|
3073
|
-
const MAX_NAME = 50;
|
|
3074
|
-
let groupName;
|
|
3075
|
-
if (firstLine) {
|
|
3076
|
-
groupName = firstLine.length > MAX_NAME ? firstLine.slice(0, MAX_NAME) + '…' : firstLine;
|
|
3077
|
-
}
|
|
3078
|
-
else {
|
|
3079
|
-
const now = new Date();
|
|
3080
|
-
const ts = `${String(now.getMonth() + 1).padStart(2, '0')}/${String(now.getDate()).padStart(2, '0')} ${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}`;
|
|
3081
|
-
groupName = t('cmd.relay.empty_group_name', { ts }, loc);
|
|
3082
|
-
}
|
|
3083
|
-
// ── Create the new chat ────────────────────────────────────────────
|
|
3084
|
-
const nameOf = (id) => appIdToName.get(id) ?? botDisplayName(id);
|
|
3085
|
-
let newChatId;
|
|
3086
|
-
let inviteLink;
|
|
3087
|
-
try {
|
|
3088
|
-
const { createGroupWithBots } = await import('../services/group-creator.js');
|
|
3089
|
-
const result = await createGroupWithBots({
|
|
3090
|
-
creatorLarkAppId: creatorAppId,
|
|
3091
|
-
larkAppIds: mentionedBotAppIds,
|
|
3092
|
-
name: groupName,
|
|
3093
|
-
userOpenIds: [senderOpenId],
|
|
3094
|
-
transferOwnerTo: senderOpenId,
|
|
3095
|
-
});
|
|
3096
|
-
newChatId = result.chatId;
|
|
3097
|
-
const applink = chatAppLink(result.chatId, normalizeBrand(getBot(creatorAppId).config.brand));
|
|
3098
|
-
inviteLink = result.shareLink ?? applink;
|
|
3099
|
-
}
|
|
3100
|
-
catch (err) {
|
|
3101
|
-
logger.error(`[${logTag}] /relay --create: createGroup failed: ${err?.message ?? err}`);
|
|
3102
|
-
await sessionReply(rootId, t('cmd.relay.failed', { error: err?.message ?? String(err) }, loc));
|
|
3103
|
-
break;
|
|
3104
|
-
}
|
|
3105
|
-
// Snapshot the pre-transfer source anchor — peers locate their own
|
|
3106
|
-
// session by this value, and `transferSession()` will overwrite
|
|
3107
|
-
// `ds.session.rootMessageId` once it runs. Must capture BEFORE the
|
|
3108
|
-
// leader transfer call (caught in review).
|
|
3109
|
-
const sourceAnchor = ds.session.rootMessageId;
|
|
3110
|
-
// ── M1 deferred: post the announcement AFTER all transfers settle ──
|
|
3111
|
-
// Previous flow sent an optimistic "已接力" M1 before running any
|
|
3112
|
-
// transfer. When leader/peers later failed, that M1 was a lie — and
|
|
3113
|
-
// the --create path had no orphan-cleanup (picker path did).
|
|
3114
|
-
//
|
|
3115
|
-
// New flow: pass `newChatId` as a placeholder for targetRootMessageId
|
|
3116
|
-
// into transferSession. Chat-scope routing ignores rootMessageId
|
|
3117
|
-
// (worker-pool transferSession only stores it for audit/UX), so the
|
|
3118
|
-
// placeholder doesn't break routing. Once all outcomes are in, we
|
|
3119
|
-
// post the real M1 with success/failure breakdown, then patch the
|
|
3120
|
-
// leader's session.rootMessageId to that final M1 id. Peer sessions
|
|
3121
|
-
// keep newChatId as a cosmetic placeholder — fixing them would
|
|
3122
|
-
// require another round-trip; chat-scope doesn't actually care.
|
|
3123
|
-
const placeholderRootMessageId = newChatId;
|
|
3124
|
-
// Resolve friendly source-chat label for the M1 body — falls back to
|
|
3125
|
-
// raw chatId if Lark can't return a name. Mirrors picker-path
|
|
3126
|
-
// (card-handler.ts relay_confirm) so the message reads the same in
|
|
3127
|
-
// both UX entry points; p2p source has no chat name (chat.get often
|
|
3128
|
-
// fails/returns empty for DMs) — use the locale-aware 单聊 label
|
|
3129
|
-
// instead of leaking a raw oc_ id into the M1.
|
|
3130
|
-
const { getChatName } = await import('../im/lark/client.js');
|
|
3131
|
-
const sourceLabel = sourceIsP2p
|
|
3132
|
-
? t('card.relay.type_p2p', undefined, loc)
|
|
3133
|
-
: (await getChatName(creatorAppId, sourceChatId).catch(() => null)) ?? sourceChatId;
|
|
3134
|
-
// ── Step 1: leader transfers its own session (if any) ───────────────
|
|
3135
|
-
// Empty-leader handling: daemon auto-creates a placeholder ds for any
|
|
3136
|
-
// DAEMON_COMMAND (worker:null + hasHistory:false). If the user typed
|
|
3137
|
-
// `/relay --create` in a chat where they never actually chatted with
|
|
3138
|
-
// the bot, ds IS that placeholder — there's no real session to
|
|
3139
|
-
// migrate. Pre-Codex-review we'd happily transferSession the empty
|
|
3140
|
-
// shell and report "已就绪:leader" as a lie. Now we detect this,
|
|
3141
|
-
// skip transferSession, mark leader as `no_session`, and close the
|
|
3142
|
-
// scratch so it doesn't linger as a ghost.
|
|
3143
|
-
//
|
|
3144
|
-
// The new chat is still created (createGroupWithBots already ran
|
|
3145
|
-
// above) — that itself is a valuable product outcome since the
|
|
3146
|
-
// mentioned bots were invited. Peers continue through their normal
|
|
3147
|
-
// path; the final M1 template adapts to "all_fresh" when no bot
|
|
3148
|
-
// actually had a session to bring along.
|
|
3149
|
-
const reportLines = [];
|
|
3150
|
-
const leaderName = nameOf(creatorAppId);
|
|
3151
|
-
const successBotNames = [];
|
|
3152
|
-
const failedBotNames = [];
|
|
3153
|
-
// Use the persisted-marker predicate, not runtime ds.hasHistory:
|
|
3154
|
-
// restoreActiveSessions sets hasHistory:true UNCONDITIONALLY on
|
|
3155
|
-
// restart (session-manager.ts:618), so a scratch that survives a
|
|
3156
|
-
// restart comes back with hasHistory:true and would defeat a
|
|
3157
|
-
// naive `!!ds.worker || ds.hasHistory` check. cliId / lastCliInput
|
|
3158
|
-
// are only written after a real worker started the CLI, so they
|
|
3159
|
-
// survive restart correctly.
|
|
3160
|
-
const { isRelayableRealSession } = await import('./worker-pool.js');
|
|
3161
|
-
const leaderHasRealSession = isRelayableRealSession(ds);
|
|
3162
|
-
if (leaderHasRealSession) {
|
|
3163
|
-
const { transferSession } = await import('./worker-pool.js');
|
|
3164
|
-
// Target chat was just built by createGroupWithBots — by
|
|
3165
|
-
// construction a regular group, chat-scope.
|
|
3166
|
-
const leaderResult = await transferSession(ds.session.sessionId, newChatId, placeholderRootMessageId, 'group', 'chat');
|
|
3167
|
-
if (!leaderResult.ok) {
|
|
3168
|
-
// Real session, real failure (worker busy / unsupported target
|
|
3169
|
-
// / tmux issue). Abort the entire --create flow — the new chat
|
|
3170
|
-
// exists but is empty of any migrated session; we don't post
|
|
3171
|
-
// an M1 because there's nothing to announce.
|
|
3172
|
-
reportLines.push(t('cmd.relay.report_leader_failed', { bot: leaderName, error: leaderResult.error }, loc));
|
|
3173
|
-
await sessionReply(rootId, t('cmd.relay.created', { name: groupName, link: inviteLink, report: reportLines.join('\n') }, loc));
|
|
3174
|
-
break;
|
|
3175
|
-
}
|
|
3176
|
-
reportLines.push(t('cmd.relay.report_leader_ok', { bot: leaderName }, loc));
|
|
3177
|
-
successBotNames.push(leaderName);
|
|
3178
|
-
}
|
|
3179
|
-
else {
|
|
3180
|
-
// Empty leader: no real session to migrate.
|
|
3181
|
-
reportLines.push(t('cmd.relay.report_leader_no_session', { bot: leaderName }, loc));
|
|
3182
|
-
failedBotNames.push(leaderName);
|
|
3183
|
-
// Close the daemon-command scratch so it doesn't linger as a
|
|
3184
|
-
// ghost active row at the source anchor (same hygiene that
|
|
3185
|
-
// transferSession's pre-flight applies to target-chat scratches).
|
|
3186
|
-
const { closeSession } = await import('./worker-pool.js');
|
|
3187
|
-
await closeSession(ds.session.sessionId).catch(err => {
|
|
3188
|
-
logger.warn(`[${logTag}] /relay --create: failed to close empty-leader scratch: ${err instanceof Error ? err.message : err}`);
|
|
3189
|
-
});
|
|
3190
|
-
}
|
|
3191
|
-
// ── Step 2: coordinate peer daemons (parallel) ─────────────────────
|
|
3192
|
-
const { findOnlineDaemon } = await import('../utils/daemon-discovery.js');
|
|
3193
|
-
const peerAppIds = mentionedBotAppIds.filter(id => id !== creatorAppId);
|
|
3194
|
-
const peerOutcomes = await Promise.all(peerAppIds.map(async (peerAppId) => {
|
|
3195
|
-
const botName = nameOf(peerAppId);
|
|
3196
|
-
const daemon = findOnlineDaemon(peerAppId);
|
|
3197
|
-
if (!daemon)
|
|
3198
|
-
return { peerAppId, botName, status: 'offline' };
|
|
3199
|
-
try {
|
|
3200
|
-
const ctrl = new AbortController();
|
|
3201
|
-
const tt = setTimeout(() => ctrl.abort(), 5000);
|
|
3202
|
-
const res = await fetchDaemonIpc(daemon.ipcPort, '/api/sessions/migrate-to-chat', {
|
|
3203
|
-
method: 'POST',
|
|
3204
|
-
headers: { 'content-type': 'application/json' },
|
|
3205
|
-
body: JSON.stringify({
|
|
3206
|
-
sourceAnchor,
|
|
3207
|
-
targetChatId: newChatId,
|
|
3208
|
-
targetRootMessageId: placeholderRootMessageId,
|
|
3209
|
-
requesterLarkAppId: creatorAppId,
|
|
3210
|
-
requestingUserOpenId: senderOpenId,
|
|
3211
|
-
// union_id is cross-app stable within a tenant — peer
|
|
3212
|
-
// compares against its own session.ownerUnionId rather
|
|
3213
|
-
// than translating open_ids per bot. Optional for
|
|
3214
|
-
// backward compat with daemons older than this commit.
|
|
3215
|
-
requestingUserUnionId: senderUnionId,
|
|
3216
|
-
}),
|
|
3217
|
-
signal: ctrl.signal,
|
|
3218
|
-
}).finally(() => clearTimeout(tt));
|
|
3219
|
-
const body = await res.json().catch(() => ({}));
|
|
3220
|
-
if (res.ok && body.ok)
|
|
3221
|
-
return { peerAppId, botName, status: 'ok' };
|
|
3222
|
-
if (body.error === 'no_session_at_anchor')
|
|
3223
|
-
return { peerAppId, botName, status: 'no_session' };
|
|
3224
|
-
if (body.error === 'not_session_owner')
|
|
3225
|
-
return { peerAppId, botName, status: 'not_owner' };
|
|
3226
|
-
if (body.error === 'worker_busy')
|
|
3227
|
-
return { peerAppId, botName, status: 'busy' };
|
|
3228
|
-
return { peerAppId, botName, status: 'failed', error: body.error ?? `http_${res.status}` };
|
|
3229
|
-
}
|
|
3230
|
-
catch (err) {
|
|
3231
|
-
const reason = err?.name === 'AbortError' ? 'busy' : 'failed';
|
|
3232
|
-
return { peerAppId, botName, status: reason, error: err?.message ?? String(err) };
|
|
3233
|
-
}
|
|
3234
|
-
}));
|
|
3235
|
-
// Bucket peer outcomes for the final M1 (success / failure) AND extend the
|
|
3236
|
-
// source-chat report with per-peer detail. Leader was already bucketed
|
|
3237
|
-
// above (real-success → successBotNames; real-fail or empty-leader →
|
|
3238
|
-
// failedBotNames), so we only iterate peers here.
|
|
3239
|
-
for (const r of peerOutcomes) {
|
|
3240
|
-
if (r.status === 'ok') {
|
|
3241
|
-
successBotNames.push(r.botName);
|
|
3242
|
-
reportLines.push(t('cmd.relay.report_peer_ok', { bot: r.botName }, loc));
|
|
3243
|
-
}
|
|
3244
|
-
else {
|
|
3245
|
-
failedBotNames.push(r.botName);
|
|
3246
|
-
switch (r.status) {
|
|
3247
|
-
case 'no_session':
|
|
3248
|
-
reportLines.push(t('cmd.relay.report_peer_no_session', { bot: r.botName }, loc));
|
|
3249
|
-
break;
|
|
3250
|
-
case 'not_owner':
|
|
3251
|
-
reportLines.push(t('cmd.relay.report_peer_not_owner', { bot: r.botName }, loc));
|
|
3252
|
-
break;
|
|
3253
|
-
case 'offline':
|
|
3254
|
-
reportLines.push(t('cmd.relay.report_peer_offline', { bot: r.botName }, loc));
|
|
3255
|
-
break;
|
|
3256
|
-
case 'busy':
|
|
3257
|
-
reportLines.push(t('cmd.relay.report_peer_busy', { bot: r.botName }, loc));
|
|
3258
|
-
break;
|
|
3259
|
-
case 'failed':
|
|
3260
|
-
reportLines.push(t('cmd.relay.report_peer_failed', { bot: r.botName, error: r.error ?? 'unknown' }, loc));
|
|
3261
|
-
break;
|
|
3262
|
-
}
|
|
3263
|
-
}
|
|
3264
|
-
}
|
|
3265
|
-
// ── Step 3: post the real M1 with status breakdown ─────────────────
|
|
3266
|
-
// Three templates:
|
|
3267
|
-
// - all_ok : every bot migrated cleanly
|
|
3268
|
-
// - partial : some migrated, some didn't (failed list explains)
|
|
3269
|
-
// - all_fresh : nobody had a session to migrate (group's still
|
|
3270
|
-
// useful — bots were invited; user just @s to start)
|
|
3271
|
-
// Pass the raw text — sendMessage wraps `'text'` msgType bodies into
|
|
3272
|
-
// { text: content } itself.
|
|
3273
|
-
let finalM1Text;
|
|
3274
|
-
if (successBotNames.length === 0) {
|
|
3275
|
-
finalM1Text = t('cmd.relay.m1_final_all_fresh', { sourceChat: sourceLabel }, loc);
|
|
3276
|
-
}
|
|
3277
|
-
else if (failedBotNames.length === 0) {
|
|
3278
|
-
finalM1Text = t('cmd.relay.m1_final_all_ok', {
|
|
3279
|
-
sourceChat: sourceLabel,
|
|
3280
|
-
successBots: successBotNames.join('、'),
|
|
3281
|
-
}, loc);
|
|
3282
|
-
}
|
|
3283
|
-
else {
|
|
3284
|
-
finalM1Text = t('cmd.relay.m1_final_partial', {
|
|
3285
|
-
sourceChat: sourceLabel,
|
|
3286
|
-
successBots: successBotNames.join('、'),
|
|
3287
|
-
failedBots: failedBotNames.join('、'),
|
|
3288
|
-
}, loc);
|
|
3289
|
-
}
|
|
3290
|
-
try {
|
|
3291
|
-
const finalM1Id = await sendMessage(creatorAppId, newChatId, finalM1Text, 'text');
|
|
3292
|
-
// Patch the leader's session.rootMessageId to the real M1 id, but
|
|
3293
|
-
// only if the leader was actually transferred — for the empty-
|
|
3294
|
-
// leader / all_fresh path, ds was either closed or never moved,
|
|
3295
|
-
// so we don't touch it (would write to a closed/stale record).
|
|
3296
|
-
if (leaderHasRealSession && successBotNames.includes(leaderName)) {
|
|
3297
|
-
ds.session.rootMessageId = finalM1Id;
|
|
3298
|
-
sessionStore.updateSession(ds.session);
|
|
3299
|
-
}
|
|
3300
|
-
}
|
|
3301
|
-
catch (err) {
|
|
3302
|
-
// Non-fatal: transfers already succeeded. The source-chat report
|
|
3303
|
-
// (sessionReply below) is the user's authoritative status.
|
|
3304
|
-
logger.warn(`[${logTag}] /relay --create: final M1 send failed: ${err?.message ?? err}`);
|
|
3305
|
-
}
|
|
3306
|
-
await sessionReply(rootId, t('cmd.relay.created', { name: groupName, link: inviteLink, report: reportLines.join('\n') }, loc));
|
|
3307
|
-
logger.info(`[${logTag}] /relay --create completed: chat=${newChatId} leader=${creatorAppId} peers=[${peerAppIds.join(',')}]`);
|
|
3308
|
-
break;
|
|
3309
|
-
}
|
|
3310
|
-
case '/fork': {
|
|
3311
|
-
// Session fork (Bot 分身): non-destructive copy of a running session
|
|
3312
|
-
// into a SECOND independent session at a new anchor; source untouched.
|
|
3313
|
-
// `/fork <task>` hosts it in a new sub-topic of the same topic group;
|
|
3314
|
-
// `/fork --create <name>` keeps the existing new-group destination.
|
|
3315
|
-
const argsLine = message.content.replace(/^\/fork\s*/i, '').trim();
|
|
3316
|
-
const forkAppId = larkAppId ?? ds?.larkAppId;
|
|
3317
|
-
if (!forkAppId) {
|
|
3318
|
-
await sessionReply(rootId, t('cmd.fork.no_bot', undefined, loc));
|
|
3319
|
-
break;
|
|
3320
|
-
}
|
|
3321
|
-
if (!ds) {
|
|
3322
|
-
await sessionReply(rootId, t('cmd.fork.no_session', undefined, loc));
|
|
3323
|
-
break;
|
|
3324
|
-
}
|
|
3325
|
-
const forkSenderOpenId = message.senderId;
|
|
3326
|
-
if (!forkSenderOpenId) {
|
|
3327
|
-
await sessionReply(rootId, t('cmd.fork.no_sender', undefined, loc));
|
|
3328
|
-
break;
|
|
3329
|
-
}
|
|
3330
|
-
// Owner-only.
|
|
3331
|
-
if (ds.session.ownerOpenId && ds.session.ownerOpenId !== forkSenderOpenId) {
|
|
3332
|
-
await sessionReply(rootId, t('cmd.fork.not_owner', undefined, loc));
|
|
3333
|
-
break;
|
|
3334
|
-
}
|
|
3335
|
-
// Capability gate — refuse non-forkable backends up front with a clear,
|
|
3336
|
-
// typed message (mirrors the design doc §4 refusal). Cheap check before
|
|
3337
|
-
// we create any group.
|
|
3338
|
-
const { isForkCapableSession } = await import('./worker-pool.js');
|
|
3339
|
-
if (!isForkCapableSession(ds)) {
|
|
3340
|
-
const cliName = getCliDisplayName((ds.session.cliId ?? getBot(forkAppId).config.cliId ?? 'claude-code'));
|
|
3341
|
-
await sessionReply(rootId, t('cmd.fork.unsupported_backend', { cli: cliName }, loc));
|
|
3342
|
-
break;
|
|
3343
|
-
}
|
|
3344
|
-
// Front guards (fork needs a clean, real, idle source — same as relay).
|
|
3345
|
-
// These MUST run before creating either a topic root or a new group.
|
|
3346
|
-
if (ds.session.adoptedFrom) {
|
|
3347
|
-
await sessionReply(rootId, t('cmd.fork.adopt_not_forkable', undefined, loc));
|
|
3348
|
-
break;
|
|
3349
|
-
}
|
|
3350
|
-
if (ds.pendingRepo) {
|
|
3351
|
-
await sessionReply(rootId, t('cmd.fork.not_started_yet', undefined, loc));
|
|
3352
|
-
break;
|
|
3353
|
-
}
|
|
3354
|
-
// Real, resumable source session? A bare /fork scratch (worker:null, no
|
|
3355
|
-
// persisted CLI markers) is not forkable — most commonly this fires when
|
|
3356
|
-
// /fork was invoked at the group top-level while the session lives in a
|
|
3357
|
-
// 话题 (thread-scope). Refuse BEFORE creating any group.
|
|
3358
|
-
const { isRelayableRealSession: forkIsRealSession } = await import('./worker-pool.js');
|
|
3359
|
-
if (!forkIsRealSession(ds)) {
|
|
3360
|
-
await sessionReply(rootId, t('cmd.fork.no_source_here', undefined, loc));
|
|
3361
|
-
break;
|
|
3362
|
-
}
|
|
3363
|
-
// Idle check up front — mid-turn source can't be forked cleanly.
|
|
3364
|
-
const forkSt = ds.lastScreenStatus;
|
|
3365
|
-
if (ds.worker && !ds.worker.killed && forkSt !== 'idle' && forkSt !== 'limited') {
|
|
3366
|
-
await sessionReply(rootId, t('cmd.fork.mid_turn', undefined, loc));
|
|
3367
|
-
break;
|
|
3368
|
-
}
|
|
3369
|
-
if (!/^--create\b/i.test(argsLine)) {
|
|
3370
|
-
if (!argsLine) {
|
|
3371
|
-
await sessionReply(rootId, t('cmd.fork.subtopic_usage', undefined, loc));
|
|
3372
|
-
break;
|
|
3373
|
-
}
|
|
3374
|
-
if (ds.scope !== 'thread' || !ds.session.rootMessageId?.startsWith('om_')) {
|
|
3375
|
-
await sessionReply(rootId, t('cmd.fork.subtopic_thread_only', undefined, loc));
|
|
3376
|
-
break;
|
|
3377
|
-
}
|
|
3378
|
-
let chatMode;
|
|
3379
|
-
try {
|
|
3380
|
-
chatMode = await getChatModeStrict(forkAppId, ds.chatId);
|
|
3381
|
-
}
|
|
3382
|
-
catch {
|
|
3383
|
-
// Treat an unknown mode as unsupported: sending a top-level message
|
|
3384
|
-
// to a regular group would not create the isolated topic we promise.
|
|
3385
|
-
}
|
|
3386
|
-
if (chatMode !== 'topic') {
|
|
3387
|
-
await sessionReply(rootId, t('cmd.fork.subtopic_thread_only', undefined, loc));
|
|
3388
|
-
break;
|
|
3389
|
-
}
|
|
3390
|
-
const result = await startForkSubtopicSession(argsLine, ds, message, forkAppId);
|
|
3391
|
-
if (!result.ok) {
|
|
3392
|
-
const errKey = result.error === 'worker_busy' ? 'cmd.fork.mid_turn'
|
|
3393
|
-
: result.error === 'adopt_not_forkable' ? 'cmd.fork.adopt_not_forkable'
|
|
3394
|
-
: result.error === 'fork_unsupported_backend' ? 'cmd.fork.unsupported_backend'
|
|
3395
|
-
: result.error === 'not_started_yet' ? 'cmd.fork.not_started_yet'
|
|
3396
|
-
: undefined;
|
|
3397
|
-
if (errKey === 'cmd.fork.unsupported_backend') {
|
|
3398
|
-
const cliName = getCliDisplayName((ds.session.cliId ?? getBot(forkAppId).config.cliId ?? 'claude-code'));
|
|
3399
|
-
await sessionReply(rootId, t(errKey, { cli: cliName }, loc));
|
|
3400
|
-
}
|
|
3401
|
-
else if (errKey) {
|
|
3402
|
-
await sessionReply(rootId, t(errKey, undefined, loc));
|
|
3403
|
-
}
|
|
3404
|
-
else {
|
|
3405
|
-
await sessionReply(rootId, t('cmd.fork.failed', { error: result.error }, loc));
|
|
3406
|
-
}
|
|
3407
|
-
if (result.orphanTopic) {
|
|
3408
|
-
await sessionReply(rootId, t('cmd.fork.orphan_topic_left', undefined, loc));
|
|
3409
|
-
}
|
|
3410
|
-
break;
|
|
3411
|
-
}
|
|
3412
|
-
await sessionReply(rootId, t('cmd.fork.subtopic_created', { link: result.link }, loc));
|
|
3413
|
-
logger.info(`[${logTag}] /fork sub-topic completed: child=${result.childSessionId.substring(0, 8)} anchor=${result.anchorId.substring(0, 12)} (source ${ds.session.sessionId.substring(0, 8)} untouched)`);
|
|
3414
|
-
break;
|
|
3415
|
-
}
|
|
3416
|
-
// ── /fork --create <群名> @bot ──────────────────────────────────────
|
|
3417
|
-
const afterFlag = argsLine.replace(/^--create\s*/i, '').trim();
|
|
3418
|
-
// Resolve the bot to invite into the new group. Fork copies THIS
|
|
3419
|
-
// session's transcript, so the child MUST run the same bot as the
|
|
3420
|
-
// source — i.e. the invited bot is always this bot. Therefore:
|
|
3421
|
-
// • no @mention → default to the current bot (the common "fork myself
|
|
3422
|
-
// to a new group" case — no need to @ the bot you're already talking to);
|
|
3423
|
-
// • an explicit @mention → must resolve to THIS bot, else refuse.
|
|
3424
|
-
const forkSourceIsP2p = ds.chatType === 'p2p';
|
|
3425
|
-
const targetBotAppId = forkAppId;
|
|
3426
|
-
let targetBotName = botDisplayName(forkAppId);
|
|
3427
|
-
if (!forkSourceIsP2p) {
|
|
3428
|
-
const forkMentions = message.mentions ?? [];
|
|
3429
|
-
const knownBotNames = globalKnownBotNames();
|
|
3430
|
-
const forkBotMentions = forkMentions.filter(m => m.name && knownBotNames.has(m.name.toLowerCase()));
|
|
3431
|
-
// Only validate WHEN the user explicitly @'d a bot. An explicit
|
|
3432
|
-
// mention that resolves to a DIFFERENT bot is a real error (fork can't
|
|
3433
|
-
// hand this session's transcript to another CLI). No mention → just
|
|
3434
|
-
// use the current bot.
|
|
3435
|
-
if (forkBotMentions.length > 0) {
|
|
3436
|
-
const firstBot = forkBotMentions[0];
|
|
3437
|
-
const myOpenId = getBotOpenId(forkAppId);
|
|
3438
|
-
const myName = getBot(forkAppId).botName?.toLowerCase();
|
|
3439
|
-
const mentionIsThisBot = (!!myOpenId && firstBot.openId === myOpenId) ||
|
|
3440
|
-
(!myOpenId && !!myName && firstBot.name?.toLowerCase() === myName);
|
|
3441
|
-
if (!mentionIsThisBot) {
|
|
3442
|
-
await sessionReply(rootId, t('cmd.fork.wrong_bot', undefined, loc));
|
|
3443
|
-
break;
|
|
3444
|
-
}
|
|
3445
|
-
}
|
|
3446
|
-
}
|
|
3447
|
-
// Group name = first non-empty line after --create (mention text stripped).
|
|
3448
|
-
let forkRawArgs = afterFlag;
|
|
3449
|
-
for (const m of (message.mentions ?? [])) {
|
|
3450
|
-
if (m.name)
|
|
3451
|
-
forkRawArgs = forkRawArgs.split(`@${m.name}`).join(' ');
|
|
3452
|
-
}
|
|
3453
|
-
const forkFirstLine = forkRawArgs.split(/\r?\n/).map(s => s.trim()).find(Boolean) ?? '';
|
|
3454
|
-
const FORK_MAX_NAME = 50;
|
|
3455
|
-
let forkGroupName;
|
|
3456
|
-
if (forkFirstLine) {
|
|
3457
|
-
forkGroupName = forkFirstLine.length > FORK_MAX_NAME ? forkFirstLine.slice(0, FORK_MAX_NAME) + '…' : forkFirstLine;
|
|
3458
|
-
}
|
|
3459
|
-
else {
|
|
3460
|
-
const src = ds.session.title || ds.session.sessionId.substring(0, 8);
|
|
3461
|
-
forkGroupName = `🔱 ${src}`.slice(0, FORK_MAX_NAME);
|
|
3462
|
-
}
|
|
3463
|
-
// Create the new chat (single bot + the invoking user).
|
|
3464
|
-
let forkChatId;
|
|
3465
|
-
let forkInviteLink;
|
|
3466
|
-
try {
|
|
3467
|
-
const { createGroupWithBots } = await import('../services/group-creator.js');
|
|
3468
|
-
const result = await createGroupWithBots({
|
|
3469
|
-
creatorLarkAppId: forkAppId,
|
|
3470
|
-
larkAppIds: [targetBotAppId],
|
|
3471
|
-
name: forkGroupName,
|
|
3472
|
-
userOpenIds: [forkSenderOpenId],
|
|
3473
|
-
transferOwnerTo: forkSenderOpenId,
|
|
3474
|
-
});
|
|
3475
|
-
forkChatId = result.chatId;
|
|
3476
|
-
const applink = chatAppLink(result.chatId, normalizeBrand(getBot(forkAppId).config.brand));
|
|
3477
|
-
forkInviteLink = result.shareLink ?? applink;
|
|
3478
|
-
}
|
|
3479
|
-
catch (err) {
|
|
3480
|
-
logger.error(`[${logTag}] /fork --create: createGroup failed: ${err?.message ?? err}`);
|
|
3481
|
-
await sessionReply(rootId, t('cmd.fork.failed', { error: err?.message ?? String(err) }, loc));
|
|
3482
|
-
break;
|
|
3483
|
-
}
|
|
3484
|
-
// Fork the session into the new chat (chat-scope, group). The new chat
|
|
3485
|
-
// is empty by construction, so no target-anchor conflict. Source is
|
|
3486
|
-
// never touched.
|
|
3487
|
-
const { forkSession } = await import('./worker-pool.js');
|
|
3488
|
-
const forkResult = await forkSession(ds.session.sessionId, forkChatId, forkChatId, 'group', 'chat');
|
|
3489
|
-
if (!forkResult.ok) {
|
|
3490
|
-
// Residual-orphan cleanup: the front guards already ran before
|
|
3491
|
-
// createGroupWithBots, so this only fires on a narrow TOCTOU race
|
|
3492
|
-
// (source went busy / closed in the sub-second between guard and
|
|
3493
|
-
// fork). Best-effort disband the just-created empty group so a failed
|
|
3494
|
-
// fork never leaves an orphan chat. May fail if ownership already
|
|
3495
|
-
// transferred to the user (transferOwnerTo) — then we just tell them.
|
|
3496
|
-
let orphanCleaned = false;
|
|
3497
|
-
try {
|
|
3498
|
-
const { disbandChat } = await import('../services/groups-store.js');
|
|
3499
|
-
const dis = await disbandChat(forkAppId, forkChatId);
|
|
3500
|
-
orphanCleaned = dis.ok;
|
|
3501
|
-
if (!dis.ok)
|
|
3502
|
-
logger.warn(`[${logTag}] /fork --create: orphan group ${forkChatId} disband failed: ${dis.error}`);
|
|
3503
|
-
}
|
|
3504
|
-
catch (e) {
|
|
3505
|
-
logger.warn(`[${logTag}] /fork --create: orphan group ${forkChatId} disband threw: ${e?.message ?? e}`);
|
|
3506
|
-
}
|
|
3507
|
-
const errKey = forkResult.error === 'worker_busy' ? 'cmd.fork.mid_turn'
|
|
3508
|
-
: forkResult.error === 'adopt_not_forkable' ? 'cmd.fork.adopt_not_forkable'
|
|
3509
|
-
: forkResult.error === 'fork_unsupported_backend' ? 'cmd.fork.unsupported_backend'
|
|
3510
|
-
: forkResult.error === 'not_started_yet' ? 'cmd.fork.not_started_yet'
|
|
3511
|
-
: undefined;
|
|
3512
|
-
if (errKey === 'cmd.fork.unsupported_backend') {
|
|
3513
|
-
const cliName = getCliDisplayName((ds.session.cliId ?? getBot(forkAppId).config.cliId ?? 'claude-code'));
|
|
3514
|
-
await sessionReply(rootId, t(errKey, { cli: cliName }, loc));
|
|
3515
|
-
}
|
|
3516
|
-
else if (errKey) {
|
|
3517
|
-
await sessionReply(rootId, t(errKey, undefined, loc));
|
|
3518
|
-
}
|
|
3519
|
-
else {
|
|
3520
|
-
await sessionReply(rootId, t('cmd.fork.failed', { error: forkResult.error }, loc));
|
|
3521
|
-
}
|
|
3522
|
-
if (!orphanCleaned) {
|
|
3523
|
-
await sessionReply(rootId, t('cmd.fork.orphan_group_left', { name: forkGroupName }, loc));
|
|
3524
|
-
}
|
|
3525
|
-
logger.warn(`[${logTag}] /fork --create: forkSession failed (${forkResult.error}); new chat ${forkChatId} ${orphanCleaned ? 'disbanded' : 'LEFT (disband failed)'}`);
|
|
3526
|
-
break;
|
|
3527
|
-
}
|
|
3528
|
-
await sessionReply(rootId, t('cmd.fork.created', { name: forkGroupName, link: forkInviteLink }, loc));
|
|
3529
|
-
logger.info(`[${logTag}] /fork --create completed: chat=${forkChatId} child=${forkResult.childSessionId.substring(0, 8)} bot=${targetBotAppId} (source ${ds.session.sessionId.substring(0, 8)} untouched)`);
|
|
3530
|
-
break;
|
|
3531
|
-
}
|
|
3532
|
-
case '/forklist': {
|
|
3533
|
-
if (!ds) {
|
|
3534
|
-
await sessionReply(rootId, t('cmd.fork.no_session', undefined, loc));
|
|
3535
|
-
break;
|
|
3536
|
-
}
|
|
3537
|
-
await upsertForkPanelCard(ds, loc, { allowEmpty: true });
|
|
3538
|
-
break;
|
|
3539
|
-
}
|
|
3540
|
-
case '/card': {
|
|
3541
|
-
// Existing-session path. New topics route /card via handleCardCommand at
|
|
3542
|
-
// the router (so no phantom session is created). off/on work without a
|
|
3543
|
-
// live worker; show/bare summons a card.
|
|
3544
|
-
const appId = ds?.larkAppId ?? larkAppId;
|
|
3545
|
-
const cardChatId = ds?.chatId;
|
|
3546
|
-
if (!appId || !cardChatId) {
|
|
3547
|
-
await sessionReply(rootId, t('cmd.no_active_session', undefined, loc));
|
|
3548
|
-
break;
|
|
3549
|
-
}
|
|
3550
|
-
await handleCardCommand(rootId, appId, cardChatId, message.senderId, message.content, deps);
|
|
3551
|
-
break;
|
|
3552
|
-
}
|
|
3553
|
-
case '/term': {
|
|
3554
|
-
// Existing-session path. New topics route /term via handleTermLinkCommand
|
|
3555
|
-
// at the router (daemon.ts) so no phantom worker=null session is created.
|
|
3556
|
-
const appId = ds?.larkAppId ?? larkAppId;
|
|
3557
|
-
if (!appId) {
|
|
3558
|
-
await sessionReply(rootId, t('cmd.no_active_session', undefined, loc));
|
|
3559
|
-
break;
|
|
3560
|
-
}
|
|
3561
|
-
await handleTermLinkCommand(rootId, appId, ds?.chatId ?? '', message.senderId, message.content, deps);
|
|
3562
|
-
break;
|
|
3563
|
-
}
|
|
3564
|
-
case '/list-slash-command':
|
|
3565
|
-
case '/slash': {
|
|
3566
|
-
// 列出本 bot 当前可用的 slash 命令,分四段:
|
|
3567
|
-
// ① botmux 固定放行的透传白名单(PASSTHROUGH_COMMANDS)
|
|
3568
|
-
// ② 当前 CLI adapter 默认透传命令(defaultPassthroughCommands)
|
|
3569
|
-
// ③ 用户在 bots.json 自定义配置的额外透传命令(customPassthroughCommands)
|
|
3570
|
-
// ④ 文件系统自动发现的 CLI 自定义命令 / skill / 插件
|
|
3571
|
-
// MCP 的 /mcp__<server>__<prompt> 需运行时握手才能枚举,这里仅按 .mcp.json 提示 server 名。
|
|
3572
|
-
const botCfg = ds
|
|
3573
|
-
? getBot(ds.larkAppId).config
|
|
3574
|
-
: (larkAppId ? getBot(larkAppId).config : getAllBots()[0]?.config);
|
|
3575
|
-
const cliId = botCfg?.cliId ?? 'claude-code';
|
|
3576
|
-
const cliName = ds
|
|
3577
|
-
? sessionCliDisplayName(ds)
|
|
3578
|
-
: configuredRuntimeDisplayName(botCfg?.cliRuntime) ?? getCliDisplayName(cliId);
|
|
3579
|
-
const workingDir = getSessionWorkingDir(ds);
|
|
3580
|
-
const builtin = [...PASSTHROUGH_COMMANDS];
|
|
3581
|
-
const adapterDefaults = resolveAdapterDefaultPassthroughCommands(larkAppId);
|
|
3582
|
-
// 只展示「实际生效」的 custom 命令:用与 resolvePassthroughCommands 同一套
|
|
3583
|
-
// normalize 过滤掉手写 bots.json 里遮蔽 daemon 命令 / 非法的项(parser 出于
|
|
3584
|
-
// 兼容会保留它们,但路由会丢弃),避免 `/status` 之类被展示成可用却走 daemon。
|
|
3585
|
-
const custom = [...new Set((botCfg?.customPassthroughCommands ?? [])
|
|
3586
|
-
.map(normalizePassthroughCommand)
|
|
3587
|
-
.filter((c) => !!c))];
|
|
3588
|
-
let cliAdapter;
|
|
3589
|
-
try {
|
|
3590
|
-
cliAdapter = createCliAdapterSync(cliId, botCfg?.cliPathOverride);
|
|
3591
|
-
}
|
|
3592
|
-
catch (err) {
|
|
3593
|
-
logger.warn(`[${logTag}] /list-slash-command could not create adapter for ${cliId}: ${err instanceof Error ? err.message : String(err)}`);
|
|
3594
|
-
}
|
|
3595
|
-
const discoverySupported = supportsFilesystemCommandDiscovery(cliAdapter);
|
|
3596
|
-
const discovered = cliAdapter && discoverySupported
|
|
3597
|
-
? discoverSlashCommandsForAdapter(workingDir, cliAdapter)
|
|
3598
|
-
: [];
|
|
3599
|
-
const mcpServers = listMcpServerNames(workingDir);
|
|
3600
|
-
const card = buildSlashListCard({ cliName, builtin, adapterDefaults, custom, discovered, workingDir, mcpServers, discoverySupported }, loc);
|
|
3601
|
-
await sessionReply(rootId, card, 'interactive');
|
|
3602
|
-
logger.info(`[${logTag}] /list-slash-command builtin=${builtin.length} custom=${custom.length} discovered=${discovered.length}`);
|
|
3603
|
-
break;
|
|
3604
|
-
}
|
|
3605
|
-
case '/help': {
|
|
3606
|
-
const helpAppId = ds?.larkAppId ?? larkAppId;
|
|
3607
|
-
const botCfg = ds ? getBot(ds.larkAppId).config : (helpAppId ? getBot(helpAppId).config : getAllBots()[0]?.config);
|
|
3608
|
-
const cliName = ds
|
|
3609
|
-
? sessionCliDisplayName(ds)
|
|
3610
|
-
: configuredRuntimeDisplayName(botCfg?.cliRuntime)
|
|
3611
|
-
?? getCliDisplayName(botCfg?.cliId ?? 'claude-code');
|
|
3612
|
-
const passthroughCommands = [...resolvePassthroughCommands(helpAppId)];
|
|
3613
|
-
const help = [
|
|
3614
|
-
t('help.heading_session', undefined, loc),
|
|
3615
|
-
t('help.close', { cliName }, loc),
|
|
3616
|
-
t('help.restart', { cliName }, loc),
|
|
3617
|
-
t('help.topic', undefined, loc),
|
|
3618
|
-
t('help.cd', { cliName }, loc),
|
|
3619
|
-
t('help.repo_list', undefined, loc),
|
|
3620
|
-
t('help.repo_n', undefined, loc),
|
|
3621
|
-
t('help.repo_path', undefined, loc),
|
|
3622
|
-
t('help.repo_wt', undefined, loc),
|
|
3623
|
-
t('help.rename', undefined, loc),
|
|
3624
|
-
t('help.status', undefined, loc),
|
|
3625
|
-
t('help.card', undefined, loc),
|
|
3626
|
-
t('help.term', undefined, loc),
|
|
3627
|
-
t('help.dashboard', undefined, loc),
|
|
3628
|
-
t('help.issue', undefined, loc),
|
|
3629
|
-
t('help.insight', undefined, loc),
|
|
3630
|
-
t('help.subscribe_doc', undefined, loc),
|
|
3631
|
-
t('help.watch_comment', undefined, loc),
|
|
3632
|
-
t('help.vc', undefined, loc),
|
|
3633
|
-
t('help.summary', undefined, loc),
|
|
3634
|
-
'',
|
|
3635
|
-
t('help.heading_passthrough', { cliName }, loc),
|
|
3636
|
-
// 展示当前 bot 实际生效的透传集合:固定白名单 + adapter 默认 + 有效自定义项。
|
|
3637
|
-
passthroughCommands.join(' '),
|
|
3638
|
-
'',
|
|
3639
|
-
t('help.heading_schedule', undefined, loc),
|
|
3640
|
-
t('help.schedule_create', undefined, loc),
|
|
3641
|
-
t('help.schedule_list', undefined, loc),
|
|
3642
|
-
t('help.schedule_remove', undefined, loc),
|
|
3643
|
-
t('help.schedule_toggle', undefined, loc),
|
|
3644
|
-
t('help.schedule_run', undefined, loc),
|
|
3645
|
-
'',
|
|
3646
|
-
t('help.schedule_formats', undefined, loc),
|
|
3647
|
-
'',
|
|
3648
|
-
t('help.heading_adopt', undefined, loc),
|
|
3649
|
-
t('help.adopt', undefined, loc),
|
|
3650
|
-
t('help.adopt_pane', undefined, loc),
|
|
3651
|
-
t('help.detach', undefined, loc),
|
|
3652
|
-
'',
|
|
3653
|
-
t('help.heading_collab', undefined, loc),
|
|
3654
|
-
t('help.introduce', undefined, loc),
|
|
3655
|
-
t('help.relay', undefined, loc),
|
|
3656
|
-
t('help.relay_create', undefined, loc),
|
|
3657
|
-
t('help.fork', undefined, loc),
|
|
3658
|
-
t('help.forklist', undefined, loc),
|
|
3659
|
-
'',
|
|
3660
|
-
t('help.heading_login', undefined, loc),
|
|
3661
|
-
t('help.login', undefined, loc),
|
|
3662
|
-
t('help.login_status', undefined, loc),
|
|
3663
|
-
t('help.pair', undefined, loc),
|
|
3664
|
-
'',
|
|
3665
|
-
t('help.heading_workflow', undefined, loc),
|
|
3666
|
-
t('help.workflow_run', undefined, loc),
|
|
3667
|
-
t('help.workflow_cancel', undefined, loc),
|
|
3668
|
-
'',
|
|
3669
|
-
t('help.heading_role', undefined, loc),
|
|
3670
|
-
t('help.role_show', undefined, loc),
|
|
3671
|
-
t('help.role_set', undefined, loc),
|
|
3672
|
-
t('help.role_team', undefined, loc),
|
|
3673
|
-
t('help.role_cap', undefined, loc),
|
|
3674
|
-
t('help.role_profile', undefined, loc),
|
|
3675
|
-
'',
|
|
3676
|
-
t('help.heading_oncall', undefined, loc),
|
|
3677
|
-
t('help.oncall_bind', undefined, loc),
|
|
3678
|
-
t('help.oncall_unbind', undefined, loc),
|
|
3679
|
-
t('help.oncall_status', undefined, loc),
|
|
3680
|
-
'',
|
|
3681
|
-
t('help.heading_grant', undefined, loc),
|
|
3682
|
-
t('help.grant', undefined, loc),
|
|
3683
|
-
t('help.revoke', undefined, loc),
|
|
3684
|
-
t('help.vc_auth', undefined, loc),
|
|
3685
|
-
t('help.invite', undefined, loc),
|
|
3686
|
-
'',
|
|
3687
|
-
t('help.heading_config', undefined, loc),
|
|
3688
|
-
t('help.config_get', undefined, loc),
|
|
3689
|
-
t('help.config_set', undefined, loc),
|
|
3690
|
-
t('help.skills', undefined, loc),
|
|
3691
|
-
t('help.reply_mode', undefined, loc),
|
|
3692
|
-
'',
|
|
3693
|
-
t('help.heading_group', undefined, loc),
|
|
3694
|
-
t('help.group', undefined, loc),
|
|
3695
|
-
'',
|
|
3696
|
-
t('help.list_slash', undefined, loc),
|
|
3697
|
-
t('help.help', undefined, loc),
|
|
3698
|
-
];
|
|
3699
|
-
await sessionReply(rootId, help.join('\n'));
|
|
3700
|
-
break;
|
|
3701
|
-
}
|
|
3702
|
-
}
|
|
3703
|
-
}
|
|
3704
|
-
catch (err) {
|
|
3705
|
-
logger.error(`[${logTag}] Command ${cmd} error: ${err.message}`);
|
|
3706
|
-
}
|
|
3707
|
-
}
|
|
3708
|
-
async function handleCodexAppAdoptCommand(args, rootId, ds, deps, larkAppId) {
|
|
3709
|
-
const sessionReply = (rid, content, msgType) => deps.sessionReply(rid, content, msgType, larkAppId);
|
|
3710
|
-
const loc = localeForBot(ds.larkAppId ?? larkAppId);
|
|
3711
|
-
const botCfg = getBot(ds.larkAppId).config;
|
|
3712
|
-
const sourceSession = ds.session;
|
|
3713
|
-
const sourceAnchor = sessionAnchorId(ds);
|
|
3714
|
-
let threads;
|
|
3715
|
-
try {
|
|
3716
|
-
threads = await listCodexAppThreads({
|
|
3717
|
-
codexBin: botCfg.cliPathOverride,
|
|
3718
|
-
cwd: getSessionWorkingDir(ds),
|
|
3719
|
-
limit: 50,
|
|
3720
|
-
});
|
|
3721
|
-
}
|
|
3722
|
-
catch (err) {
|
|
3723
|
-
await sessionReply(rootId, t('cmd.codex_app_adopt.list_failed', { error: err?.message ?? String(err) }, loc));
|
|
3724
|
-
return;
|
|
3725
|
-
}
|
|
3726
|
-
if (ds.session !== sourceSession
|
|
3727
|
-
|| ds.session.status !== 'active'
|
|
3728
|
-
|| deps.activeSessions.get(sessionKey(sourceAnchor, ds.larkAppId)) !== ds
|
|
3729
|
-
|| isSessionTransferring(ds)) {
|
|
3730
|
-
await sessionReply(rootId, t('cmd.session.transfer_in_progress', undefined, loc));
|
|
3731
|
-
return;
|
|
3732
|
-
}
|
|
3733
|
-
if (threads.length === 0) {
|
|
3734
|
-
await sessionReply(rootId, t('cmd.codex_app_adopt.no_threads', undefined, loc));
|
|
3735
|
-
return;
|
|
3736
|
-
}
|
|
3737
|
-
if (args) {
|
|
3738
|
-
const target = threads.find(t => t.threadId === args || t.threadId.startsWith(args));
|
|
3739
|
-
if (!target) {
|
|
3740
|
-
await sessionReply(rootId, t('cmd.codex_app_adopt.thread_not_found', { threadId: args }, loc));
|
|
3741
|
-
return;
|
|
3742
|
-
}
|
|
3743
|
-
await startCodexAppThreadSession(target, ds, deps, larkAppId);
|
|
3744
|
-
return;
|
|
3745
|
-
}
|
|
3746
|
-
const cardJson = buildCodexAppThreadSelectCard(threads, rootId, loc);
|
|
3747
|
-
await sessionReply(rootId, cardJson, 'interactive');
|
|
3748
|
-
}
|
|
3749
|
-
// ─── Adopt session helper ────────────────────────────────────────────────────
|
|
3750
|
-
/** Discriminate a zellij adopt candidate from tmux/herdr candidates. */
|
|
3751
|
-
function isZellijTarget(t) {
|
|
3752
|
-
return 'zellijPaneId' in t;
|
|
3753
|
-
}
|
|
3754
|
-
/**
|
|
3755
|
-
* Refuse a takeover (`/adopt`, Codex App thread, disk resume import) while the
|
|
3756
|
-
* session is still on the first-spawn repo-select gate (`pendingRepo`).
|
|
3757
|
-
*
|
|
3758
|
-
* Adopt/import attaches to an already-running CLI, so it cannot double as a way
|
|
3759
|
-
* to finish that gate — the two states are mutually exclusive by design. Rather
|
|
3760
|
-
* than migrate the pending placeholder in place (which used to leave a
|
|
3761
|
-
* contradictory `adopt` + "待选仓库" session, and risked folding botmux
|
|
3762
|
-
* envelopes into the external CLI), we post a card that explains the refusal
|
|
3763
|
-
* and offers a one-tap "close session". After the user closes it, a fresh
|
|
3764
|
-
* `/adopt` runs as a clean first message (which never enters pendingRepo).
|
|
3765
|
-
*
|
|
3766
|
-
* Returns true when the takeover was blocked (caller must return immediately).
|
|
3767
|
-
* Note pendingRepo is in-memory only, so this can never wrongly fire on a
|
|
3768
|
-
* daemon-restored session.
|
|
3769
|
-
*/
|
|
3770
|
-
async function blockTakeoverWhilePendingRepo(ds, sessionReply) {
|
|
3771
|
-
if (!ds.pendingRepo)
|
|
3772
|
-
return false;
|
|
3773
|
-
const loc = localeForBot(ds.larkAppId);
|
|
3774
|
-
const card = buildAdoptBlockedCard(sessionAnchorId(ds), ds.session.sessionId, getBot(ds.larkAppId).config.cliId, loc);
|
|
3775
|
-
await sessionReply(sessionAnchorId(ds), card, 'interactive');
|
|
3776
|
-
logger.info(`[${tag(ds)}] Takeover refused: session still on pendingRepo gate — posted close-session card`);
|
|
3777
|
-
return true;
|
|
3778
|
-
}
|
|
3779
|
-
export async function startCodexAppThreadSession(thread, ds, deps, larkAppId) {
|
|
3780
|
-
const sessionReply = (rid, content, msgType) => deps.sessionReply(rid, content, msgType, larkAppId);
|
|
3781
|
-
const loc = localeForBot(ds.larkAppId ?? larkAppId);
|
|
3782
|
-
const title = codexAppThreadTitle(thread);
|
|
3783
|
-
if (isSessionTransferring(ds)) {
|
|
3784
|
-
await sessionReply(sessionAnchorId(ds), t('cmd.session.transfer_in_progress', undefined, loc));
|
|
3785
|
-
return;
|
|
3786
|
-
}
|
|
3787
|
-
if (await blockTakeoverWhilePendingRepo(ds, sessionReply))
|
|
3788
|
-
return;
|
|
3789
|
-
ds.adoptedFrom = undefined;
|
|
3790
|
-
ds.workingDir = thread.cwd;
|
|
3791
|
-
ds.hasHistory = true;
|
|
3792
|
-
ds.currentTurnTitle = undefined;
|
|
3793
|
-
ds.lastScreenContent = undefined;
|
|
3794
|
-
ds.lastScreenStatus = undefined;
|
|
3795
|
-
ds.session.workingDir = thread.cwd;
|
|
3796
|
-
ds.session.title = `Codex App: ${title}`;
|
|
3797
|
-
ds.session.cliId = 'codex-app';
|
|
3798
|
-
ds.session.cliSessionId = thread.threadId;
|
|
3799
|
-
ds.session.adoptedFrom = undefined;
|
|
3800
|
-
sessionStore.updateSession(ds.session);
|
|
3801
|
-
forkWorker(ds, '', true);
|
|
3802
|
-
await sessionReply(sessionAnchorId(ds), t('cmd.codex_app_adopt.success', { title }, loc));
|
|
3803
|
-
}
|
|
3804
|
-
export async function startAdoptSession(target, ds, deps, larkAppId) {
|
|
3805
|
-
const sessionReply = (rid, content, msgType) => deps.sessionReply(rid, content, msgType, larkAppId);
|
|
3806
|
-
const loc = localeForBot(ds.larkAppId ?? larkAppId);
|
|
3807
|
-
if (isSessionTransferring(ds)) {
|
|
3808
|
-
await sessionReply(sessionAnchorId(ds), t('cmd.session.transfer_in_progress', undefined, loc));
|
|
3809
|
-
return;
|
|
3810
|
-
}
|
|
3811
|
-
const zellij = isZellijTarget(target);
|
|
3812
|
-
if (!zellij && target.source === 'herdr' && target.herdrSessionName && target.herdrAgentName) {
|
|
3813
|
-
const occupied = [...deps.activeSessions.values()].some(active => {
|
|
3814
|
-
if (active.session.sessionId === ds.session.sessionId || active.session.status !== 'active' || active.adoptedFrom)
|
|
3815
|
-
return false;
|
|
3816
|
-
const owned = active.session.persistentBackendTarget;
|
|
3817
|
-
return owned?.backendType === 'herdr'
|
|
3818
|
-
&& owned.sessionName === target.herdrSessionName
|
|
3819
|
-
&& owned.agentName === target.herdrAgentName;
|
|
3820
|
-
});
|
|
3821
|
-
if (occupied) {
|
|
3822
|
-
await sessionReply(sessionAnchorId(ds), t('cmd.adopt.target_exited', undefined, loc));
|
|
3823
|
-
return;
|
|
3824
|
-
}
|
|
3825
|
-
}
|
|
3826
|
-
// Fail-closed at the ENTRY point, BEFORE any target validation or state
|
|
3827
|
-
// mutation: a sandbox-enabled bot can't wrap an already-running CLI
|
|
3828
|
-
// (confinement is spawn-time only). Reject here so `adoptedFrom` is never
|
|
3829
|
-
// persisted and "adopted" is never replied — otherwise the session would
|
|
3830
|
-
// become a worker=null pseudo-adopt whose next message still routes as a
|
|
3831
|
-
// bridge/adopt session. Covers both real host-process adopt entries
|
|
3832
|
-
// (`/adopt <pane>` and the adopt_select card, which both route here). Checks
|
|
3833
|
-
// the live bot flag AND the session's frozen sandbox decision (union).
|
|
3834
|
-
const adoptBotCfg = getBot(ds.larkAppId ?? larkAppId).config;
|
|
3835
|
-
const adoptRuntimeExecutable = ds.session.agentFrozen
|
|
3836
|
-
? ds.session.cliRuntime?.source === 'configured' ? ds.session.cliRuntime.executable : undefined
|
|
3837
|
-
: adoptBotCfg.cliRuntime?.executable;
|
|
3838
|
-
if (adoptSandboxBlocked(adoptBotCfg, ds.session)) {
|
|
3839
|
-
await sessionReply(sessionAnchorId(ds), t('cmd.adopt.sandbox_blocked', undefined, loc));
|
|
3840
|
-
return;
|
|
3841
|
-
}
|
|
3842
|
-
// A session still on the repo-select gate can't be adopted in place — refuse
|
|
3843
|
-
// and offer a one-tap close so the user retires it and re-adopts cleanly.
|
|
3844
|
-
if (await blockTakeoverWhilePendingRepo(ds, sessionReply))
|
|
3845
|
-
return;
|
|
3846
|
-
const valid = zellij
|
|
3847
|
-
? validateZellijAdoptTarget(target.zellijSession, target.zellijPaneId, target.cliPid, target.cliId, adoptRuntimeExecutable)
|
|
3848
|
-
: validateAdoptTarget(target, adoptRuntimeExecutable);
|
|
3849
|
-
if (!valid) {
|
|
3850
|
-
await sessionReply(sessionAnchorId(ds), t('cmd.adopt.target_exited', undefined, loc));
|
|
3851
|
-
return;
|
|
3852
|
-
}
|
|
3853
|
-
const project = target.cwd.split('/').pop() || target.cwd;
|
|
3854
|
-
const pane = zellij ? `${target.zellijSession}/${target.zellijPaneId}` : adoptTargetLabel(target);
|
|
3855
|
-
ds.workingDir = target.cwd;
|
|
3856
|
-
ds.session.workingDir = target.cwd;
|
|
3857
|
-
ds.session.title = `Adopt: ${project}`;
|
|
3858
|
-
ds.adoptedFrom = {
|
|
3859
|
-
source: zellij ? 'zellij' : target.source,
|
|
3860
|
-
tmuxTarget: zellij ? undefined : target.tmuxTarget,
|
|
3861
|
-
zellijSession: zellij ? target.zellijSession : undefined,
|
|
3862
|
-
zellijPaneId: zellij ? target.zellijPaneId : undefined,
|
|
3863
|
-
herdrSessionName: zellij ? undefined : target.herdrSessionName,
|
|
3864
|
-
herdrTarget: zellij ? undefined : target.herdrTarget,
|
|
3865
|
-
herdrPaneId: zellij ? undefined : target.herdrPaneId,
|
|
3866
|
-
herdrAgentName: zellij ? undefined : target.herdrAgentName,
|
|
3867
|
-
herdrTerminalId: zellij ? undefined : target.herdrTerminalId,
|
|
3868
|
-
originalCliPid: target.cliPid,
|
|
3869
|
-
sessionId: target.sessionId,
|
|
3870
|
-
cliId: target.cliId,
|
|
3871
|
-
cwd: target.cwd,
|
|
3872
|
-
paneCols: target.paneCols,
|
|
3873
|
-
paneRows: target.paneRows,
|
|
3874
|
-
};
|
|
3875
|
-
ds.session.adoptedFrom = { ...ds.adoptedFrom };
|
|
3876
|
-
sessionStore.updateSession(ds.session);
|
|
3877
|
-
forkAdoptWorker(ds);
|
|
3878
|
-
const cliName = sessionCliDisplayName(ds);
|
|
3879
|
-
await sessionReply(sessionAnchorId(ds), t('cmd.adopt.success', { cliName, project, pane }, loc));
|
|
3880
|
-
}
|
|
3881
|
-
/** Cap on resume candidates surfaced by the /adopt picker. Kept at the legacy
|
|
3882
|
-
* 20 (per product call: the V2 card is a display change, not a scope change).
|
|
3883
|
-
* When the cap is hit the card shows a hint pointing at search + the
|
|
3884
|
-
* `/adopt <id>` direct path, so history beyond the cap is still reachable. */
|
|
3885
|
-
export const ADOPT_RESUME_LIMIT = 20;
|
|
3886
|
-
/** Discover the sessions resumable from disk for `cliId`, excluding any whose
|
|
3887
|
-
* CLI-native id is already live in a botmux session (so a session botmux
|
|
3888
|
-
* already runs isn't offered for re-import). Returns [] when the adapter has
|
|
3889
|
-
* no on-disk store. */
|
|
3890
|
-
export async function discoverResumableSessionsForBot(cliId, cliPathOverride, activeSessions, limit = ADOPT_RESUME_LIMIT) {
|
|
3891
|
-
let adapter;
|
|
3892
|
-
try {
|
|
3893
|
-
adapter = createCliAdapterSync(cliId, cliPathOverride);
|
|
3894
|
-
}
|
|
3895
|
-
catch {
|
|
3896
|
-
return [];
|
|
3897
|
-
}
|
|
3898
|
-
if (!adapter.listResumableSessions)
|
|
3899
|
-
return [];
|
|
3900
|
-
// Exclude every session botmux already manages — live OR closed — so the
|
|
3901
|
-
// picker surfaces only genuinely external sessions (a CLI the user ran
|
|
3902
|
-
// standalone). botmux's own closed sessions stay resumable via their
|
|
3903
|
-
// session-closed cards, so hiding them here avoids a redundant, confusing
|
|
3904
|
-
// duplicate. The identity set spans all bot stores and includes both the
|
|
3905
|
-
// botmux sessionId (= the claude jsonl filename) and the cliSessionId
|
|
3906
|
-
// (codex/traex rollout id), covering every CLI's id shape. Passed INTO the
|
|
3907
|
-
// adapter so exclusion happens BEFORE the `limit` truncation.
|
|
3908
|
-
const exclude = sessionStore.collectBotmuxSessionIdentities() ?? new Set();
|
|
3909
|
-
// Belt-and-suspenders: also fold in the in-memory active map (freshest).
|
|
3910
|
-
for (const ds of activeSessions.values()) {
|
|
3911
|
-
if (ds.session.sessionId)
|
|
3912
|
-
exclude.add(ds.session.sessionId);
|
|
3913
|
-
if (ds.session.cliSessionId)
|
|
3914
|
-
exclude.add(ds.session.cliSessionId);
|
|
3915
|
-
}
|
|
3916
|
-
try {
|
|
3917
|
-
return await adapter.listResumableSessions({ limit, exclude });
|
|
3918
|
-
}
|
|
3919
|
-
catch {
|
|
3920
|
-
return [];
|
|
3921
|
-
}
|
|
3922
|
-
}
|
|
3923
|
-
/** Import (resume) a stored session into the current topic: re-spawn the bot's
|
|
3924
|
-
* CLI via `--resume <cliSessionId>` in `cwd`. Mirrors the manual resume path —
|
|
3925
|
-
* the worker owns the CLI (NOT an observe-adopt), so no `adoptedFrom` is set. */
|
|
3926
|
-
export async function startResumeImportSession(target, ds, deps, larkAppId) {
|
|
3927
|
-
const sessionReply = (rid, content, msgType) => deps.sessionReply(rid, content, msgType, larkAppId);
|
|
3928
|
-
const loc = localeForBot(ds.larkAppId ?? larkAppId);
|
|
3929
|
-
const project = target.cwd.split('/').pop() || target.cwd;
|
|
3930
|
-
if (isSessionTransferring(ds)) {
|
|
3931
|
-
await sessionReply(sessionAnchorId(ds), t('cmd.session.transfer_in_progress', undefined, loc));
|
|
3932
|
-
return;
|
|
3933
|
-
}
|
|
3934
|
-
if (await blockTakeoverWhilePendingRepo(ds, sessionReply))
|
|
3935
|
-
return;
|
|
3936
|
-
ds.workingDir = target.cwd;
|
|
3937
|
-
ds.session.workingDir = target.cwd;
|
|
3938
|
-
ds.session.cliSessionId = target.cliSessionId;
|
|
3939
|
-
ds.session.title = target.title || `Import: ${project}`;
|
|
3940
|
-
// Resume sandbox decision is left to forkWorker (resume=true → not sandboxed,
|
|
3941
|
-
// matching restore semantics). Mark history so the session is treated as a
|
|
3942
|
-
// resume, not a fresh spawn.
|
|
3943
|
-
ds.hasHistory = true;
|
|
3944
|
-
sessionStore.updateSession(ds.session);
|
|
3945
|
-
forkWorker(ds, '', true);
|
|
3946
|
-
const cliName = sessionCliDisplayName(ds);
|
|
3947
|
-
await sessionReply(sessionAnchorId(ds), t('cmd.adopt.resume_success', { cliName, project, title: target.title || target.cliSessionId.slice(0, 8) }, loc));
|
|
3948
|
-
}
|
|
3949
|
-
/** Fork the current session into a new sub-topic of the same topic group.
|
|
3950
|
-
* The session copy itself stays in worker-pool's generic `forkSession()`;
|
|
3951
|
-
* this layer only creates the Lark destination, supplies the first task turn,
|
|
3952
|
-
* and records display-only lineage for the parent panel. */
|
|
3953
|
-
export async function startForkSubtopicSession(taskText, parentDs, message, larkAppId) {
|
|
3954
|
-
const appId = parentDs.larkAppId ?? larkAppId;
|
|
3955
|
-
if (!appId)
|
|
3956
|
-
return { ok: false, error: 'missing_lark_app_id', orphanTopic: false };
|
|
3957
|
-
const loc = localeForBot(appId);
|
|
3958
|
-
const bot = getBot(appId);
|
|
3959
|
-
const botCfg = bot.config;
|
|
3960
|
-
const parentSession = parentDs.session;
|
|
3961
|
-
const chatId = parentDs.chatId;
|
|
3962
|
-
const brand = normalizeBrand(botCfg.brand);
|
|
3963
|
-
const taskTitle = taskText.split(/\r?\n/).map(line => line.trim()).find(Boolean)?.slice(0, 60)
|
|
3964
|
-
?? taskText.slice(0, 60);
|
|
3965
|
-
const senderIsBot = message.senderType === 'app' || message.senderType === 'bot';
|
|
3966
|
-
const triggerSender = {
|
|
3967
|
-
openId: message.senderId,
|
|
3968
|
-
type: senderIsBot ? 'bot' : 'user',
|
|
3969
|
-
...(message.senderName ? { name: message.senderName } : {}),
|
|
3970
|
-
};
|
|
3971
|
-
let anchorId;
|
|
3972
|
-
const recallAnchor = async () => {
|
|
3973
|
-
if (!anchorId)
|
|
3974
|
-
return true;
|
|
3975
|
-
try {
|
|
3976
|
-
return await deleteMessage(appId, anchorId);
|
|
3977
|
-
}
|
|
3978
|
-
catch (err) {
|
|
3979
|
-
logger.warn(`[${parentSession.sessionId.substring(0, 8)}] /fork sub-topic recall failed: `
|
|
3980
|
-
+ `${err instanceof Error ? err.message : String(err)}`);
|
|
3981
|
-
return false;
|
|
3982
|
-
}
|
|
3983
|
-
};
|
|
3984
|
-
try {
|
|
3985
|
-
let parentThreadId = parentSession.larkThreadId ?? message.threadId;
|
|
3986
|
-
if (!parentThreadId) {
|
|
3987
|
-
parentThreadId = (await getMessageThreadId(appId, parentSession.rootMessageId)) ?? undefined;
|
|
3988
|
-
}
|
|
3989
|
-
if (parentThreadId && parentSession.larkThreadId !== parentThreadId) {
|
|
3990
|
-
parentSession.larkThreadId = parentThreadId;
|
|
3991
|
-
sessionStore.updateSession(parentSession);
|
|
3992
|
-
}
|
|
3993
|
-
const parentLink = parentThreadId
|
|
3994
|
-
? threadAppLink(chatId, parentThreadId, brand)
|
|
3995
|
-
: chatAppLink(chatId, brand);
|
|
3996
|
-
const localeKey = loc === 'en' ? 'en_us' : 'zh_cn';
|
|
3997
|
-
const seedPost = JSON.stringify({
|
|
3998
|
-
[localeKey]: {
|
|
3999
|
-
title: `${t('cmd.fork.badge', undefined, loc)} ${taskText.replace(/\s*\n+\s*/g, ' ').slice(0, 300)}`,
|
|
4000
|
-
content: [[
|
|
4001
|
-
...(senderIsBot ? [] : [{ tag: 'at', user_id: message.senderId }]),
|
|
4002
|
-
{
|
|
4003
|
-
tag: 'text',
|
|
4004
|
-
text: `${senderIsBot ? '' : ' '}${t('cmd.fork.seed_parent_line', { title: parentSession.title || '' }, loc)} `,
|
|
4005
|
-
},
|
|
4006
|
-
{ tag: 'a', text: t('cmd.fork.seed_back_link', undefined, loc), href: parentLink },
|
|
4007
|
-
]],
|
|
4008
|
-
},
|
|
4009
|
-
});
|
|
4010
|
-
anchorId = await sendMessage(appId, chatId, seedPost, 'post');
|
|
4011
|
-
const childThreadId = (await getMessageThreadId(appId, anchorId)) ?? undefined;
|
|
4012
|
-
const childIntro = t('cmd.fork.child_intro', {
|
|
4013
|
-
parentTitle: parentSession.title || '',
|
|
4014
|
-
parentSessionId: parentSession.sessionId,
|
|
4015
|
-
parentRootId: parentSession.rootMessageId,
|
|
4016
|
-
}, loc);
|
|
4017
|
-
const availableBots = await getAvailableBots(appId, chatId);
|
|
4018
|
-
const childCliId = parentSession.cliId ?? botCfg.cliId;
|
|
4019
|
-
const { forkSession } = await import('./worker-pool.js');
|
|
4020
|
-
const forkResult = await forkSession(parentSession.sessionId, chatId, anchorId, 'group', 'thread', {
|
|
4021
|
-
childTitle: `${t('cmd.fork.badge', undefined, loc)} ${taskTitle}`,
|
|
4022
|
-
forkTaskText: taskText,
|
|
4023
|
-
larkThreadId: childThreadId,
|
|
4024
|
-
turnId: message.messageId,
|
|
4025
|
-
senderOpenId: triggerSender.openId,
|
|
4026
|
-
senderIsBot,
|
|
4027
|
-
buildInitialPrompt: childSessionId => buildNewTopicCliInput(`${childIntro}\n\n${taskText}`, childSessionId, childCliId, botCfg.cliPathOverride, undefined, undefined, availableBots, undefined, { name: bot.botName, openId: bot.botOpenId }, loc, triggerSender, { larkAppId: appId, chatId }),
|
|
4028
|
-
});
|
|
4029
|
-
if (!forkResult.ok) {
|
|
4030
|
-
const orphanTopic = !await recallAnchor();
|
|
4031
|
-
return { ok: false, error: forkResult.error, orphanTopic };
|
|
4032
|
-
}
|
|
4033
|
-
if (!parentSession.forkChildSessionIds?.includes(forkResult.childSessionId)) {
|
|
4034
|
-
parentSession.forkChildSessionIds = [
|
|
4035
|
-
...(parentSession.forkChildSessionIds ?? []),
|
|
4036
|
-
forkResult.childSessionId,
|
|
4037
|
-
];
|
|
4038
|
-
try {
|
|
4039
|
-
sessionStore.updateSession(parentSession);
|
|
4040
|
-
}
|
|
4041
|
-
catch (err) {
|
|
4042
|
-
logger.warn(`[${parentSession.sessionId.substring(0, 8)}] /fork parent lineage update failed: `
|
|
4043
|
-
+ `${err instanceof Error ? err.message : String(err)}`);
|
|
4044
|
-
}
|
|
4045
|
-
}
|
|
4046
|
-
try {
|
|
4047
|
-
await upsertForkPanelCard(parentDs, loc);
|
|
4048
|
-
}
|
|
4049
|
-
catch (err) {
|
|
4050
|
-
logger.warn(`[${parentSession.sessionId.substring(0, 8)}] /fork panel refresh failed: `
|
|
4051
|
-
+ `${err instanceof Error ? err.message : String(err)}`);
|
|
4052
|
-
}
|
|
4053
|
-
return {
|
|
4054
|
-
ok: true,
|
|
4055
|
-
childSessionId: forkResult.childSessionId,
|
|
4056
|
-
anchorId,
|
|
4057
|
-
link: childThreadId ? threadAppLink(chatId, childThreadId, brand) : chatAppLink(chatId, brand),
|
|
4058
|
-
};
|
|
4059
|
-
}
|
|
4060
|
-
catch (err) {
|
|
4061
|
-
logger.error(`[${parentSession.sessionId.substring(0, 8)}] /fork sub-topic failed: `
|
|
4062
|
-
+ `${err instanceof Error ? err.message : String(err)}`);
|
|
4063
|
-
return {
|
|
4064
|
-
ok: false,
|
|
4065
|
-
error: anchorId ? 'fork_subtopic_failed' : 'topic_creation_failed',
|
|
4066
|
-
orphanTopic: anchorId ? !await recallAnchor() : false,
|
|
4067
|
-
};
|
|
4068
|
-
}
|
|
4069
|
-
}
|
|
4070
|
-
/** Re-post the parent session's fork panel at the bottom of the topic. Reading
|
|
4071
|
-
* each child row from the store keeps `/forklist` status current without
|
|
4072
|
-
* coupling child lifecycle to its parent. */
|
|
4073
|
-
async function upsertForkPanelCard(parentDs, loc, opts) {
|
|
4074
|
-
const appId = parentDs.larkAppId;
|
|
4075
|
-
const chatId = parentDs.chatId;
|
|
4076
|
-
const brand = normalizeBrand(getBot(appId).config.brand);
|
|
4077
|
-
const children = (parentDs.session.forkChildSessionIds ?? [])
|
|
4078
|
-
.map(sessionId => sessionStore.getSession(sessionId))
|
|
4079
|
-
.filter((session) => !!session)
|
|
4080
|
-
.map(session => ({
|
|
4081
|
-
instruction: session.forkTaskText ?? session.title,
|
|
4082
|
-
status: (session.status === 'active' ? 'active' : 'closed'),
|
|
4083
|
-
link: session.larkThreadId
|
|
4084
|
-
? threadAppLink(chatId, session.larkThreadId, brand)
|
|
4085
|
-
: chatAppLink(chatId, brand),
|
|
4086
|
-
}));
|
|
4087
|
-
if (children.length === 0 && !opts?.allowEmpty)
|
|
4088
|
-
return;
|
|
4089
|
-
const staleCardId = parentDs.session.forkPanelCardId;
|
|
4090
|
-
if (staleCardId) {
|
|
4091
|
-
try {
|
|
4092
|
-
await deleteMessage(appId, staleCardId);
|
|
4093
|
-
}
|
|
4094
|
-
catch {
|
|
4095
|
-
// It may already be withdrawn or past Lark's recall window. Posting the
|
|
4096
|
-
// fresh panel is still more useful than keeping the command silent.
|
|
4097
|
-
}
|
|
4098
|
-
}
|
|
4099
|
-
try {
|
|
4100
|
-
const cardId = await replyMessage(appId, parentDs.session.rootMessageId, buildForkPanelCard(children, loc), 'interactive', true);
|
|
4101
|
-
parentDs.session.forkPanelCardId = cardId;
|
|
4102
|
-
sessionStore.updateSession(parentDs.session);
|
|
4103
|
-
}
|
|
4104
|
-
catch (err) {
|
|
4105
|
-
logger.warn(`[fork-panel] failed to post panel card: ${err instanceof Error ? err.message : err}`);
|
|
4106
|
-
}
|
|
4107
|
-
}
|
|
4108
|
-
//# sourceMappingURL=command-handler.js.map
|