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,3274 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Lark event dispatcher — handles WSClient setup, bot identity probing,
|
|
3
|
-
* and message routing (group access checks, @mention detection).
|
|
4
|
-
* Extracted from daemon.ts for modularity.
|
|
5
|
-
*/
|
|
6
|
-
import * as Lark from '@larksuiteoapi/node-sdk';
|
|
7
|
-
import { ProxyAgent } from 'proxy-agent';
|
|
8
|
-
import { readFileSync, mkdirSync, existsSync } from 'node:fs';
|
|
9
|
-
import { atomicWriteFileSync } from '../../utils/atomic-write.js';
|
|
10
|
-
import { join } from 'node:path';
|
|
11
|
-
import { getBot, getAllBots, findOncallChat, getOwnerOpenId, loadBotConfigs } from '../../bot-registry.js';
|
|
12
|
-
import { config, isVcMeetingAgentGloballyEnabled, vcMeetingAgentGlobalListenerBotAppId } from '../../config.js';
|
|
13
|
-
import { getChatInfo, getChatMode, getCachedChatMode, getUserProfile, listChatMessagesUntil, resolveSiblingBotBySenderOpenId, replyMessage, sendMessage, sendUserMessage, isHumanOpenId, updateMessage } from './client.js';
|
|
14
|
-
import { logger } from '../../utils/logger.js';
|
|
15
|
-
import { BoundedMap } from '../../utils/bounded-map.js';
|
|
16
|
-
import { serializeByAnchor } from '../../utils/anchor-serializer.js';
|
|
17
|
-
import { parseForceTopicInvocation } from '../../core/command-handler.js';
|
|
18
|
-
import { shouldAutoStartOnNewTopic } from '../../core/auto-start.js';
|
|
19
|
-
import { stripLeadingMentions, mentionOpenId, mentionAppId, extractMentionIdentities, messageMentionsBot } from './message-parser.js';
|
|
20
|
-
import { recordObservedBots, listObservedBots } from '../../services/observed-bots-store.js';
|
|
21
|
-
import { isTeamBot, recordTeamBot } from '../../services/team-bots-store.js';
|
|
22
|
-
import { isTeamGroupChat } from '../../services/team-groups-store.js';
|
|
23
|
-
import { isPlatformTeamBot, isPlatformHallChat, isPlatformTeamMemberChat } from '../../services/platform-team-store.js';
|
|
24
|
-
import { getBotUnionId, recordBotUnionId, recordBotUnionIdFromMentions } from '../../services/bot-union-ids-store.js';
|
|
25
|
-
import { getDocSubscription, putDocSubscription, removeDocSubscription, listAllDocSubscriptions } from '../../services/doc-subs-store.js';
|
|
26
|
-
import { getDocComment, isBotAuthoredReply, hasBotSentinel, commentTriggerAllowed, BOT_REPLY_SENTINEL } from './doc-comment.js';
|
|
27
|
-
import { BOTMUX_REQUIRED_SCOPES, DOC_FEATURE_SCOPES, DOC_WATCH_SCOPES, DOC_COMMENT_EVENT, VC_MEETING_BOT_EVENTS, VC_MEETING_FEATURE_SCOPES, VC_MEETING_REALTIME_VOICE_SCOPES, buildEventSubDeepLink, buildScopeDeepLink, } from '../../setup/verify-permissions.js';
|
|
28
|
-
import { automateOpenPlatformSetup } from '../../setup/open-platform-automation.js';
|
|
29
|
-
import { larkHosts, normalizeBrand, sdkDomain } from './lark-hosts.js';
|
|
30
|
-
import { tryHandleGrantCommand } from './grant-command.js';
|
|
31
|
-
import { tryHandleInviteCommand } from './invite-command.js';
|
|
32
|
-
import { autoInviteOwnerOnGroupJoin } from '../../services/groups-store.js';
|
|
33
|
-
import { tryHandleReplyModeCommand } from './reply-mode-command.js';
|
|
34
|
-
import { tryHandleSubstituteCommand } from './substitute-command.js';
|
|
35
|
-
import { buildGrantCard } from './card-builder.js';
|
|
36
|
-
import { openPending, isThrottled, clearPending } from './grant-pending.js';
|
|
37
|
-
import { localeForBot, t } from '../../i18n/index.js';
|
|
38
|
-
import { chatQuotaKey, getGrantExpiresAt, globalQuotaKey, removeExpiredGrant, } from '../../services/grant-store.js';
|
|
39
|
-
import { ForwardFollowupBuffer } from './forward-followup-buffer.js';
|
|
40
|
-
import { listForwardFollowups, putForwardFollowup, removeForwardFollowup } from './forward-followup-store.js';
|
|
41
|
-
import { claimMessageOnce, _resetCacheForTest as _resetSeenMessagesForTest } from '../../services/seen-message-store.js';
|
|
42
|
-
import { ensureDefaultOncallBound } from '../../services/oncall-store.js';
|
|
43
|
-
import { resolveRegularGroupMode, resolveGroupMentionMode } from '../../services/chat-reply-mode-store.js';
|
|
44
|
-
import { buildSummaryCommandPrompt } from './summary-command.js';
|
|
45
|
-
import { DEFAULT_SUMMARY_PROMPT, summaryRangeFromBotConfig } from '../../services/summary-range-store.js';
|
|
46
|
-
import { isSubstituteEnabledForChat } from '../../services/substitute-chat-toggle-store.js';
|
|
47
|
-
import { evaluateMessageListener, resolveListenerSenderIdentity, buildListenerBotAppIdToOpenId, collectListenerBotAppIds } from '../../services/message-listener.js';
|
|
48
|
-
import { parseVcMeetingPushEvent, VC_BOT_MEETING_ACTIVITY_EVENT, VC_BOT_MEETING_ENDED_EVENT, VC_BOT_MEETING_INVITED_EVENT, VC_PARTICIPANT_MEETING_JOINED_EVENT, } from '../../vc-agent/push-source.js';
|
|
49
|
-
import { DEFAULT_GRANT_DURATION_MS, DEFAULT_GRANT_QUOTA } from '../../services/grant-policy.js';
|
|
50
|
-
// 大厅回执互教的防环闸:每进程对同一打卡者只回一次(见 hall swallow 分支)。
|
|
51
|
-
const hallEchoReplied = new Set();
|
|
52
|
-
function vcMeetingEventPayloadForLog(data) {
|
|
53
|
-
try {
|
|
54
|
-
return JSON.stringify(data?.event ?? data);
|
|
55
|
-
}
|
|
56
|
-
catch (err) {
|
|
57
|
-
return `[unserializable:${err instanceof Error ? err.message : String(err)}]`;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
// ─── Bot identity ─────────────────────────────────────────────────────────
|
|
61
|
-
/** Set the bot's open_id. Callers should also call writeBotInfoFile() to persist. */
|
|
62
|
-
export function setBotOpenId(larkAppId, id) {
|
|
63
|
-
getBot(larkAppId).botOpenId = id;
|
|
64
|
-
}
|
|
65
|
-
/** Persist bot registry info to disk for agent-facing CLI subcommands to read.
|
|
66
|
-
* Merges current process's bot(s) into the existing file so that
|
|
67
|
-
* multiple daemon processes (one per bot) don't overwrite each other. */
|
|
68
|
-
export function writeBotInfoFile(dataDir) {
|
|
69
|
-
const filePath = join(dataDir, 'bots-info.json');
|
|
70
|
-
if (!existsSync(dataDir))
|
|
71
|
-
mkdirSync(dataDir, { recursive: true });
|
|
72
|
-
let existing = [];
|
|
73
|
-
try {
|
|
74
|
-
if (existsSync(filePath)) {
|
|
75
|
-
existing = JSON.parse(readFileSync(filePath, 'utf-8'));
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
catch { /* ignore corrupt file */ }
|
|
79
|
-
// Build a map keyed by larkAppId, start with existing entries
|
|
80
|
-
const map = new Map();
|
|
81
|
-
for (const entry of existing) {
|
|
82
|
-
if (entry.larkAppId)
|
|
83
|
-
map.set(entry.larkAppId, entry);
|
|
84
|
-
}
|
|
85
|
-
// Upsert current process's bot(s)
|
|
86
|
-
for (const b of getAllBots()) {
|
|
87
|
-
map.set(b.config.larkAppId, {
|
|
88
|
-
larkAppId: b.config.larkAppId,
|
|
89
|
-
botOpenId: b.botOpenId ?? null,
|
|
90
|
-
botName: b.botName ?? null,
|
|
91
|
-
botAvatarUrl: b.botAvatarUrl ?? null,
|
|
92
|
-
cliId: b.config.cliId,
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
// 原子写:一 bot 一 daemon,多个 daemon 进程并发 upsert 同一个 bots-info.json,
|
|
96
|
-
// 裸写会让并发读者看到半截 JSON。(read-merge-write 的 lost-update 仍存在,
|
|
97
|
-
// 但每个 daemon 周期性重写自己的条目,可自愈。)
|
|
98
|
-
atomicWriteFileSync(filePath, JSON.stringify([...map.values()], null, 2) + '\n');
|
|
99
|
-
}
|
|
100
|
-
/**
|
|
101
|
-
* Probe the bot's own open_id at startup via the Lark bot info API.
|
|
102
|
-
*/
|
|
103
|
-
/** Per-app in-flight open_id probe, so a startup burst of events shares one probe. */
|
|
104
|
-
const inflightOpenIdProbes = new Map();
|
|
105
|
-
/**
|
|
106
|
-
* Ensure the bot's own open_id is resolved before @-detection. `probeBotOpenId`
|
|
107
|
-
* is fired fire-and-forget at daemon startup, so events can arrive while
|
|
108
|
-
* `botOpenId` is still undefined — `isBotMentioned` then can't recognize an @ as
|
|
109
|
-
* ours and silently drops it. The WSClient still ACKs that dropped event, so
|
|
110
|
-
* Lark never redelivers it (the @ is lost until manually re-sent). Awaiting the
|
|
111
|
-
* deduped probe here closes that window: concurrent events share one probe, and
|
|
112
|
-
* each is held only until the open_id lands, then processed normally.
|
|
113
|
-
*/
|
|
114
|
-
export function ensureBotOpenId(larkAppId) {
|
|
115
|
-
if (getBot(larkAppId).botOpenId)
|
|
116
|
-
return Promise.resolve();
|
|
117
|
-
let inflight = inflightOpenIdProbes.get(larkAppId);
|
|
118
|
-
if (!inflight) {
|
|
119
|
-
inflight = probeBotOpenId(larkAppId).finally(() => inflightOpenIdProbes.delete(larkAppId));
|
|
120
|
-
inflightOpenIdProbes.set(larkAppId, inflight);
|
|
121
|
-
}
|
|
122
|
-
return inflight;
|
|
123
|
-
}
|
|
124
|
-
export async function probeBotOpenId(larkAppId) {
|
|
125
|
-
const bot = getBot(larkAppId);
|
|
126
|
-
if (bot.botOpenId)
|
|
127
|
-
return; // already known
|
|
128
|
-
const openApi = larkHosts(normalizeBrand(bot.config.brand)).openApi;
|
|
129
|
-
// Call /bot/v3/info to get the bot's open_id using tenant_access_token
|
|
130
|
-
const tokenRes = await fetch(`${openApi}/open-apis/auth/v3/tenant_access_token/internal`, {
|
|
131
|
-
method: 'POST',
|
|
132
|
-
headers: { 'Content-Type': 'application/json' },
|
|
133
|
-
body: JSON.stringify({ app_id: bot.config.larkAppId, app_secret: bot.config.larkAppSecret }),
|
|
134
|
-
});
|
|
135
|
-
const tokenData = await tokenRes.json();
|
|
136
|
-
if (tokenData.code !== 0) {
|
|
137
|
-
throw new Error(`Failed to get tenant_access_token: ${tokenData.msg}`);
|
|
138
|
-
}
|
|
139
|
-
const botRes = await fetch(`${openApi}/open-apis/bot/v3/info/`, {
|
|
140
|
-
headers: { Authorization: `Bearer ${tokenData.tenant_access_token}` },
|
|
141
|
-
});
|
|
142
|
-
const botData = await botRes.json();
|
|
143
|
-
if (botData.code !== 0) {
|
|
144
|
-
throw new Error(`Failed to get bot info: ${botData.msg}`);
|
|
145
|
-
}
|
|
146
|
-
const openId = botData.bot?.open_id;
|
|
147
|
-
const appName = botData.bot?.app_name;
|
|
148
|
-
const avatarUrl = botData.bot?.avatar_url;
|
|
149
|
-
if (openId) {
|
|
150
|
-
bot.botOpenId = openId;
|
|
151
|
-
if (appName)
|
|
152
|
-
bot.botName = appName;
|
|
153
|
-
if (avatarUrl)
|
|
154
|
-
bot.botAvatarUrl = avatarUrl;
|
|
155
|
-
logger.info(`Bot open_id: ${bot.botOpenId}`);
|
|
156
|
-
}
|
|
157
|
-
else {
|
|
158
|
-
throw new Error('No open_id in bot info response');
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
// ─── Required-scope check ───────────────────────────────────────────────────
|
|
162
|
-
//
|
|
163
|
-
// Bot-to-bot @mention 投递依赖 "获取群组中其他机器人和用户@当前机器人的消息"
|
|
164
|
-
// 权限(scope: im:message.group_at_msg.include_bot:readonly)。该权限关闭
|
|
165
|
-
// 后飞书不会把跨 bot 的事件推到 WSClient,botmux 的 handleThreadReply 收
|
|
166
|
-
// 不到,看上去就是"另一个 bot @ 我没反应"——而 botmux 已经把本地 signal-file
|
|
167
|
-
// 转发删了,不再有兜底。启动时主动校验一下,缺了就向 allowedUsers[0] 私信
|
|
168
|
-
// 提示。
|
|
169
|
-
//
|
|
170
|
-
// 校验通过飞书 "Get application info" API(应用身份):
|
|
171
|
-
// GET /open-apis/application/v6/applications/{app_id}?lang=zh_cn
|
|
172
|
-
// 返回的 data.app.scopes 是个 {scope, description, ...} 数组,遍历找
|
|
173
|
-
// scope 字段是否包含目标 key。
|
|
174
|
-
//
|
|
175
|
-
// 鸡生蛋约束:调这个 API 自身需要 admin:app.info:readonly 或
|
|
176
|
-
// application:application:self_manage 中任一权限。后者免审批,是
|
|
177
|
-
// 推荐路径——拿不到 app info 时(飞书返回 99991672)我们就主动私信
|
|
178
|
-
// admin 提示开通 self_manage,下次重启就能自检。
|
|
179
|
-
const REQUIRED_BOT_AT_SCOPE = 'im:message.group_at_msg.include_bot:readonly';
|
|
180
|
-
const SELF_MANAGE_SCOPE = 'application:application:self_manage';
|
|
181
|
-
function getAdminOpenId(bot) {
|
|
182
|
-
return bot.resolvedAllowedUsers.find(u => u.startsWith('ou_'));
|
|
183
|
-
}
|
|
184
|
-
async function dmAdmin(larkAppId, adminOpenId, content, contextTag) {
|
|
185
|
-
try {
|
|
186
|
-
await sendUserMessage(larkAppId, adminOpenId, content, 'text');
|
|
187
|
-
logger.info(`[${larkAppId}] notified admin ${adminOpenId.substring(0, 12)} about ${contextTag}`);
|
|
188
|
-
}
|
|
189
|
-
catch (err) {
|
|
190
|
-
logger.warn(`[${larkAppId}] failed to DM admin about ${contextTag}: ${err?.message ?? err}`);
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
/**
|
|
194
|
-
* Try to auto-fix missing scopes using the same Open Platform web-session
|
|
195
|
-
* automation that powers `botmux setup`. If ~/.botmux/feishu-session.json holds
|
|
196
|
-
* a valid cached session, this adds all botmux-required scopes and publishes
|
|
197
|
-
* a new app version — no user interaction needed.
|
|
198
|
-
*
|
|
199
|
-
* Returns `true` if scopes were successfully applied (caller should stop),
|
|
200
|
-
* `false` to fall through to the manual DM warning.
|
|
201
|
-
*
|
|
202
|
-
* `opts.disableQrLogin` — when the only thing missing is a non-critical scope,
|
|
203
|
-
* we still try to grab it (the automation imports the full manifest), but must
|
|
204
|
-
* NOT pop a second QR code if the cached session is gone. Passing this makes a
|
|
205
|
-
* missing/expired session fail cleanly (reason `invalid_session`) instead of
|
|
206
|
-
* prompting a login.
|
|
207
|
-
* `opts.silent` — suppress the admin success DM (used for the opt-in / optional
|
|
208
|
-
* path so a bot that never asked for the feature isn't pinged; the log line is
|
|
209
|
-
* enough). Failures are always silent here regardless.
|
|
210
|
-
*/
|
|
211
|
-
async function tryAutoFixScopes(larkAppId, bot, brand, missingCritical, missingOptional, opts) {
|
|
212
|
-
if (brand !== 'feishu')
|
|
213
|
-
return false;
|
|
214
|
-
try {
|
|
215
|
-
const totalMissing = missingCritical.length + missingOptional.length;
|
|
216
|
-
logger.info(`[${larkAppId}] attempting auto-fix for ${totalMissing} missing scopes via Open Platform...`);
|
|
217
|
-
const result = await automateOpenPlatformSetup({
|
|
218
|
-
appId: bot.config.larkAppId,
|
|
219
|
-
brand,
|
|
220
|
-
maxWaitMs: 60_000,
|
|
221
|
-
disableQrLogin: opts?.disableQrLogin,
|
|
222
|
-
onStatus: (msg) => logger.info(`[${larkAppId}] auto-fix: ${msg}`),
|
|
223
|
-
onQrCode: (info) => {
|
|
224
|
-
logger.warn(`[${larkAppId}] auto-fix: cached Feishu web session expired, QR login needed. ` +
|
|
225
|
-
`Run \`botmux setup\` to refresh session, or manually apply scopes from deep links below. ` +
|
|
226
|
-
`QR text (first 80 chars): ${info.qrText.substring(0, 80)}...`);
|
|
227
|
-
},
|
|
228
|
-
});
|
|
229
|
-
if (result.ok) {
|
|
230
|
-
const scopeDetail = result.scopeCount > 0
|
|
231
|
-
? `${result.scopeCount} 项权限已导入${result.skippedScopeCount > 0 ? `(${result.skippedScopeCount} 项跳过)` : ''}`
|
|
232
|
-
: '所有必需权限已在应用清单中';
|
|
233
|
-
logger.info(`[${larkAppId}] auto-fix succeeded: ${scopeDetail}, ` +
|
|
234
|
-
`version ${result.versionId ?? 'n/a'} published, ` +
|
|
235
|
-
`${result.subscribedEventCount} events subscribed`);
|
|
236
|
-
// opt-in / optional-only path: succeeded silently, no admin DM (a bot that
|
|
237
|
-
// never enabled the feature must not be pinged just because a non-critical
|
|
238
|
-
// scope was topped up in the background). The log line above is the record.
|
|
239
|
-
if (opts?.silent)
|
|
240
|
-
return true;
|
|
241
|
-
// Notify admin that auto-fix worked — even if im:message was missing before,
|
|
242
|
-
// the newly published version should now have it.
|
|
243
|
-
const adminOpenId = getAdminOpenId(bot);
|
|
244
|
-
if (adminOpenId) {
|
|
245
|
-
const fixedList = [...missingCritical, ...missingOptional];
|
|
246
|
-
const missingList = fixedList.map(s => `• ${s.desc} (\`${s.name}\`)`).join('\n');
|
|
247
|
-
await dmAdmin(larkAppId, adminOpenId, `✅ botmux 已自动为机器人 "${bot.botName ?? larkAppId}" 修复了缺失的权限:\n\n${missingList}\n\n` +
|
|
248
|
-
`${scopeDetail},新版本已发布。\n` +
|
|
249
|
-
`权限变更可能需要 1-2 分钟生效。如仍有问题执行 \`botmux restart\`。`, `auto-fixed ${fixedList.length} scopes`);
|
|
250
|
-
}
|
|
251
|
-
return true;
|
|
252
|
-
}
|
|
253
|
-
// Auto-fix failed — log reason. Critical path falls through to a manual
|
|
254
|
-
// deep-link DM; the silent optional-scope top-up path does NOT DM (it just
|
|
255
|
-
// leaves the opt-in scope ungranted), so don't claim a DM fallback there.
|
|
256
|
-
const reasons = {
|
|
257
|
-
missing_session: '无可用的 Feishu Web session',
|
|
258
|
-
invalid_session: 'Web session 已失效',
|
|
259
|
-
login_failed: 'Web session 登录失败',
|
|
260
|
-
qr_expired: '需要扫码但二维码已过期',
|
|
261
|
-
timeout: '等待扫码超时',
|
|
262
|
-
unsupported_brand: '仅支持 feishu.cn 租户',
|
|
263
|
-
network: '网络错误',
|
|
264
|
-
missing_csrf: '开放平台页面未返回 CSRF token',
|
|
265
|
-
scope_mapping_failed: '权限映射失败',
|
|
266
|
-
api_error: '开放平台 API 错误',
|
|
267
|
-
};
|
|
268
|
-
logger.warn(`[${larkAppId}] auto-fix not possible (${result.reason}: ${reasons[result.reason] ?? result.message}). ` +
|
|
269
|
-
(opts?.silent ? 'Leaving opt-in scope ungranted (no DM).' : 'Falling back to manual deep-link DM.'));
|
|
270
|
-
return false;
|
|
271
|
-
}
|
|
272
|
-
catch (err) {
|
|
273
|
-
logger.warn(`[${larkAppId}] auto-fix error: ${err?.message ?? err}` +
|
|
274
|
-
(opts?.silent ? ' — leaving opt-in scope ungranted (no DM)' : ' — falling back to manual DM'));
|
|
275
|
-
return false;
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
export async function checkRequiredScopes(larkAppId) {
|
|
279
|
-
const bot = getBot(larkAppId);
|
|
280
|
-
const brand = normalizeBrand(bot.config.brand);
|
|
281
|
-
const openApi = larkHosts(brand).openApi;
|
|
282
|
-
try {
|
|
283
|
-
const tokenRes = await fetch(`${openApi}/open-apis/auth/v3/tenant_access_token/internal`, {
|
|
284
|
-
method: 'POST',
|
|
285
|
-
headers: { 'Content-Type': 'application/json' },
|
|
286
|
-
body: JSON.stringify({ app_id: bot.config.larkAppId, app_secret: bot.config.larkAppSecret }),
|
|
287
|
-
});
|
|
288
|
-
const tokenData = await tokenRes.json();
|
|
289
|
-
if (tokenData.code !== 0) {
|
|
290
|
-
logger.debug(`[${larkAppId}] scope check skipped: tenant_access_token failed (${tokenData.msg})`);
|
|
291
|
-
return;
|
|
292
|
-
}
|
|
293
|
-
const infoRes = await fetch(`${openApi}/open-apis/application/v6/applications/${bot.config.larkAppId}?lang=zh_cn`, { headers: { Authorization: `Bearer ${tokenData.tenant_access_token}` } });
|
|
294
|
-
const infoData = await infoRes.json();
|
|
295
|
-
// 99991672 = 应用身份缺权限。最常见就是 admin:app.info:readonly /
|
|
296
|
-
// application:application:self_manage 都没拿到,导致根本查不到自己的
|
|
297
|
-
// scope 列表。这种"鸡生蛋"情况单独提示:让 admin 开通免审批的
|
|
298
|
-
// self_manage 后下次重启就能自检了。
|
|
299
|
-
if (infoData.code === 99991672) {
|
|
300
|
-
// Chicken-and-egg: app lacks self_manage so we can't even check what scopes
|
|
301
|
-
// are missing. Try the Open Platform web-session auto-fix to add ALL
|
|
302
|
-
// required scopes (including self_manage) in one shot.
|
|
303
|
-
if (brand === 'feishu') {
|
|
304
|
-
const fixed = await tryAutoFixScopes(larkAppId, bot, brand, [{ name: SELF_MANAGE_SCOPE, desc: '应用自查 (免审批)' }], []);
|
|
305
|
-
if (fixed)
|
|
306
|
-
return;
|
|
307
|
-
}
|
|
308
|
-
const selfManageAuthUrl = buildScopeDeepLink(bot.config.larkAppId, SELF_MANAGE_SCOPE, brand);
|
|
309
|
-
const targetAuthUrl = buildScopeDeepLink(bot.config.larkAppId, REQUIRED_BOT_AT_SCOPE, brand);
|
|
310
|
-
logger.warn(`[${larkAppId}] scope 自检 API 被拒(99991672):应用缺少 ${SELF_MANAGE_SCOPE}(免审批)。` +
|
|
311
|
-
`开通后下次 daemon 重启即可自动核验跨 bot @ 必需权限 ${REQUIRED_BOT_AT_SCOPE}。申请链接:${selfManageAuthUrl}`);
|
|
312
|
-
const adminOpenId = getAdminOpenId(bot);
|
|
313
|
-
if (!adminOpenId) {
|
|
314
|
-
logger.warn(`[${larkAppId}] 没有 resolved 的 admin open_id,self_manage 提示仅出现在 daemon 日志`);
|
|
315
|
-
return;
|
|
316
|
-
}
|
|
317
|
-
const dm = `⚠️ botmux 想自动核验机器人 "${bot.botName ?? larkAppId}" 是否开通了跨 bot @ 必需权限,但发现应用自身缺少一个**免审批**的辅助权限,因此查不到 scope 列表。\n\n` +
|
|
318
|
-
`**操作步骤(点链接 → 申请开通 → 重启 daemon)**:\n` +
|
|
319
|
-
`1. 开通 ${SELF_MANAGE_SCOPE}(免审批,自动通过):\n ${selfManageAuthUrl}\n\n` +
|
|
320
|
-
`2. 顺便确认/开通真正的目标权限 ${REQUIRED_BOT_AT_SCOPE}("获取群组中其他机器人和用户@当前机器人的消息",免审批,自动通过):\n ${targetAuthUrl}\n\n` +
|
|
321
|
-
`3. \`botmux restart\`,启动后 botmux 会自动复核,结果会再次发到这里。\n\n` +
|
|
322
|
-
`**为什么需要**:botmux 多机器人协作(A 机器人 @ B 机器人)依赖目标权限把跨 bot 事件推送过来;不开通则跨 bot @ 完全失效。`;
|
|
323
|
-
await dmAdmin(larkAppId, adminOpenId, dm, 'self_manage scope (auto-approved) missing');
|
|
324
|
-
return;
|
|
325
|
-
}
|
|
326
|
-
if (infoData.code !== 0) {
|
|
327
|
-
logger.debug(`[${larkAppId}] scope check skipped: app info failed (code=${infoData.code} msg=${infoData.msg ?? ''})`);
|
|
328
|
-
return;
|
|
329
|
-
}
|
|
330
|
-
// Lark 文档示例把 scopes 放在 data.app.scopes;为防响应结构变化,
|
|
331
|
-
// 同时兜底 data.scopes / data.application.scopes,取到的第一个非空数组为准。
|
|
332
|
-
const scopesRaw = infoData.data?.app?.scopes
|
|
333
|
-
?? infoData.data?.application?.scopes
|
|
334
|
-
?? infoData.data?.scopes
|
|
335
|
-
?? [];
|
|
336
|
-
if (!Array.isArray(scopesRaw) || scopesRaw.length === 0) {
|
|
337
|
-
logger.debug(`[${larkAppId}] scope check inconclusive: scopes array empty or shape unexpected — skipping`);
|
|
338
|
-
return;
|
|
339
|
-
}
|
|
340
|
-
const grantedScopes = new Set(scopesRaw.map(s => typeof s === 'string' ? s : s?.scope).filter(Boolean));
|
|
341
|
-
// 文档评论入口就绪自检:仅对「已订阅过文档」的 bot 生效(opt-in,不打扰其他 bot)。
|
|
342
|
-
// ① 校验文档 app 权限是否开通(可查 → 缺则 DM 深链)② 提醒去后台订阅评论事件
|
|
343
|
-
// drive.notice.comment_add_v1(飞书无 API 可查是否已订阅,只能提醒)——让「订阅
|
|
344
|
-
// 成功却收不到评论」这类配置漏项在重启自检时暴露。
|
|
345
|
-
try {
|
|
346
|
-
const docSubs = listAllDocSubscriptions(config.session.dataDir, larkAppId);
|
|
347
|
-
if (docSubs.length > 0) {
|
|
348
|
-
const hasWatch = docSubs.some(s => s.managedBy === 'watch-comment');
|
|
349
|
-
// Historical records have no managedBy and belong to the legacy
|
|
350
|
-
// /subscribe-lark-doc flow, which still needs every OAuth/subscribe scope.
|
|
351
|
-
const hasApiSubscribe = docSubs.some(s => s.managedBy !== 'watch-comment');
|
|
352
|
-
const requiredDocScopes = [
|
|
353
|
-
...(hasWatch ? DOC_WATCH_SCOPES : []),
|
|
354
|
-
...(hasApiSubscribe ? DOC_FEATURE_SCOPES : []),
|
|
355
|
-
].filter((scope, index, all) => all.findIndex(s => s.name === scope.name) === index);
|
|
356
|
-
const missingDoc = requiredDocScopes.filter(s => !grantedScopes.has(s.name));
|
|
357
|
-
const featureLabel = [
|
|
358
|
-
hasWatch ? '/watch-comment' : '',
|
|
359
|
-
hasApiSubscribe ? '/subscribe-lark-doc' : '',
|
|
360
|
-
].filter(Boolean).join(' + ');
|
|
361
|
-
if (missingDoc.length > 0) {
|
|
362
|
-
const summary = missingDoc.map(s => `${s.name}(${s.desc})`).join('、');
|
|
363
|
-
logger.error(`[${larkAppId}] ${featureLabel} 已在用(${docSubs.length} 个绑定)但缺 ${missingDoc.length} 项文档权限:${summary}。评论将收不到/回不了,请到权限管理开通后 botmux restart。`);
|
|
364
|
-
const adminDoc = getAdminOpenId(bot);
|
|
365
|
-
if (adminDoc) {
|
|
366
|
-
const lines = missingDoc.map((s, i) => `${i + 1}. **${s.desc}** (\`${s.name}\`)\n ${buildScopeDeepLink(bot.config.larkAppId, s.name, brand)}`).join('\n\n');
|
|
367
|
-
await dmAdmin(larkAppId, adminDoc, `⚠️ 机器人 "${bot.botName ?? larkAppId}" 已通过 ${featureLabel} 绑定 ${docSubs.length} 个飞书文档,但缺少对应权限:\n\n${lines}\n\n` +
|
|
368
|
-
`另外请确认开发者后台「事件订阅」里已添加 **\`${DOC_COMMENT_EVENT}\`**(云文档新增评论)事件——该事件无法被自动检测,缺它则评论永远收不到。\n\n开通 + 订阅事件后执行 \`botmux restart\`。`, `missing doc-feature scopes: ${missingDoc.map(s => s.name).join(',')}`);
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
else {
|
|
372
|
-
// 权限齐了——事件订阅查不了,仅 info 记一条提醒(不 DM 免重启刷屏)。
|
|
373
|
-
logger.info(`[${larkAppId}] ${featureLabel} 文档权限齐全(${docSubs.length} 绑定);请确保后台已订阅事件 ${DOC_COMMENT_EVENT}(无法自动检测)`);
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
catch (err) {
|
|
378
|
-
logger.debug(`[${larkAppId}] doc-feature readiness check errored: ${err?.message ?? err}`);
|
|
379
|
-
}
|
|
380
|
-
// VC meeting agent readiness: app scopes can be checked; Open Platform event
|
|
381
|
-
// subscription status cannot be listed via public API, so we surface the
|
|
382
|
-
// exact required event keys as an explicit operator checklist.
|
|
383
|
-
try {
|
|
384
|
-
const globalVcListenerAppId = vcMeetingAgentGlobalListenerBotAppId();
|
|
385
|
-
if (isVcMeetingAgentGloballyEnabled()
|
|
386
|
-
&& bot.config.vcMeetingAgent?.enabled === true
|
|
387
|
-
&& (!globalVcListenerAppId || globalVcListenerAppId === larkAppId)) {
|
|
388
|
-
const requiredVcScopes = bot.config.vcMeetingAgent.realtimeVoice?.enabled === true
|
|
389
|
-
? [...VC_MEETING_FEATURE_SCOPES, ...VC_MEETING_REALTIME_VOICE_SCOPES]
|
|
390
|
-
: VC_MEETING_FEATURE_SCOPES;
|
|
391
|
-
const missingVc = requiredVcScopes.filter(s => !grantedScopes.has(s.name));
|
|
392
|
-
const eventList = VC_MEETING_BOT_EVENTS.map(e => `\`${e}\``).join('、');
|
|
393
|
-
const eventSubUrl = buildEventSubDeepLink(bot.config.larkAppId, brand);
|
|
394
|
-
if (missingVc.length > 0) {
|
|
395
|
-
const summary = missingVc.map(s => `${s.name}(${s.desc})`).join('、');
|
|
396
|
-
logger.error(`[${larkAppId}] vcMeetingAgent 已启用但缺 ${missingVc.length} 项 VC 权限:${summary}。` +
|
|
397
|
-
`会议智能体入会/读事件可能失败。请到权限管理开通,并确认事件订阅页包含 ${VC_MEETING_BOT_EVENTS.join(', ')}。`);
|
|
398
|
-
const adminVc = getAdminOpenId(bot);
|
|
399
|
-
if (adminVc) {
|
|
400
|
-
const lines = missingVc.map((s, i) => `${i + 1}. **${s.desc}** (\`${s.name}\`)\n ${buildScopeDeepLink(bot.config.larkAppId, s.name, brand)}`).join('\n\n');
|
|
401
|
-
await dmAdmin(larkAppId, adminVc, `⚠️ 机器人 "${bot.botName ?? larkAppId}" 已启用 \`vcMeetingAgent\`,但缺少会议智能体所需权限:\n\n${lines}\n\n` +
|
|
402
|
-
`另外请确认开发者后台「事件订阅」里已添加这 3 个事件:${eventList}\n\n` +
|
|
403
|
-
`事件订阅页:${eventSubUrl}\n\n` +
|
|
404
|
-
`注意:飞书目前没有公开 API 可自动确认这 3 个事件是否已订阅/发布;缺事件时 daemon 只会收不到 push,不会有运行时错误。开通 + 发布后执行 \`botmux restart\`。`, `missing vc-meeting scopes: ${missingVc.map(s => s.name).join(',')}`);
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
else {
|
|
408
|
-
logger.info(`[${larkAppId}] vcMeetingAgent VC 权限齐全;请确保后台事件订阅页已添加 ${VC_MEETING_BOT_EVENTS.join(', ')} ` +
|
|
409
|
-
`并已发布(无法自动检测):${eventSubUrl}`);
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
}
|
|
413
|
-
catch (err) {
|
|
414
|
-
logger.debug(`[${larkAppId}] vc-meeting readiness check errored: ${err?.message ?? err}`);
|
|
415
|
-
}
|
|
416
|
-
// Diff against the canonical list. Critical-missing is the main signal;
|
|
417
|
-
// non-critical is mentioned only when something critical is also missing,
|
|
418
|
-
// so deployments don't get nagged about purely optional scopes like
|
|
419
|
-
// `application:application:self_manage`.
|
|
420
|
-
const missingCritical = BOTMUX_REQUIRED_SCOPES.filter(s => s.critical && !grantedScopes.has(s.name));
|
|
421
|
-
const missingOptional = BOTMUX_REQUIRED_SCOPES.filter(s => !s.critical && !grantedScopes.has(s.name));
|
|
422
|
-
if (missingCritical.length === 0) {
|
|
423
|
-
// All critical scopes present. If an opt-in feature added a non-critical
|
|
424
|
-
// scope that isn't granted yet, top it up SILENTLY — but only when a cached
|
|
425
|
-
// Feishu web session already exists (disableQrLogin makes a missing session
|
|
426
|
-
// fail cleanly with no second QR code and no DM). This makes `botmux restart`
|
|
427
|
-
// actually pick up newly-declared optional scopes (e.g. the foreign-bot
|
|
428
|
-
// group-message scope) without the admin having to visit the Open Platform,
|
|
429
|
-
// while a bot with nothing missing — or no web session — behaves exactly as
|
|
430
|
-
// before (no API call / no prompt / no nag).
|
|
431
|
-
if (missingOptional.length > 0 && brand === 'feishu') {
|
|
432
|
-
const toppedUp = await tryAutoFixScopes(larkAppId, bot, brand, [], missingOptional, { disableQrLogin: true, silent: true });
|
|
433
|
-
if (toppedUp) {
|
|
434
|
-
logger.info(`[${larkAppId}] auto-topped-up ${missingOptional.length} optional scope(s): ${missingOptional.map(s => s.name).join('、')}`);
|
|
435
|
-
return;
|
|
436
|
-
}
|
|
437
|
-
logger.debug(`[${larkAppId}] optional scope(s) missing (${missingOptional.map(s => s.name).join('、')}); no cached web session to auto-apply — leaving to opt-in feature owner`);
|
|
438
|
-
}
|
|
439
|
-
logger.info(`[${larkAppId}] all critical scopes granted (${BOTMUX_REQUIRED_SCOPES.filter(s => s.critical).length} checked)`);
|
|
440
|
-
return;
|
|
441
|
-
}
|
|
442
|
-
// Auto-fix: try the same Open Platform automation used by `botmux setup`.
|
|
443
|
-
// If a cached Feishu web session exists (~/.botmux/feishu-session.json), we can
|
|
444
|
-
// directly add missing scopes and publish a new version without user interaction.
|
|
445
|
-
// Falls through to manual DM warning if session is missing/expired.
|
|
446
|
-
const autoFixed = await tryAutoFixScopes(larkAppId, bot, brand, missingCritical, missingOptional);
|
|
447
|
-
if (autoFixed)
|
|
448
|
-
return;
|
|
449
|
-
// Log + DM consolidated message listing all missing critical scopes.
|
|
450
|
-
const summaryLine = missingCritical.map(s => `${s.name} (${s.desc})`).join('、');
|
|
451
|
-
logger.error(`[${larkAppId}] 缺少 ${missingCritical.length} 项必需权限:${summaryLine}。` +
|
|
452
|
-
`botmux 核心功能(消息收发、附件下载、用户名解析等)会受影响。请到飞书开放平台 → 应用 → 权限管理里申请,开通后 \`botmux restart\`。`);
|
|
453
|
-
const adminOpenId = getAdminOpenId(bot);
|
|
454
|
-
if (!adminOpenId) {
|
|
455
|
-
logger.warn(`[${larkAppId}] no resolved admin open_id in allowedUsers; missing-scope warning visible only in daemon log`);
|
|
456
|
-
return;
|
|
457
|
-
}
|
|
458
|
-
const criticalLines = missingCritical.map((s, i) => `${i + 1}. **${s.desc}** (\`${s.name}\`)\n ${buildScopeDeepLink(bot.config.larkAppId, s.name, brand)}`).join('\n\n');
|
|
459
|
-
const optionalBlock = missingOptional.length > 0
|
|
460
|
-
? `\n\n**可选权限(建议一并开通)**:\n${missingOptional.map(s => `- ${s.desc} (\`${s.name}\`): ${buildScopeDeepLink(bot.config.larkAppId, s.name, brand)}`).join('\n')}`
|
|
461
|
-
: '';
|
|
462
|
-
const dm = `⚠️ botmux 启动检查发现机器人 "${bot.botName ?? larkAppId}" 缺少 ${missingCritical.length} 项必需权限\n\n` +
|
|
463
|
-
`**操作步骤(点链接 → 申请开通 → 重启 daemon)**:\n\n` +
|
|
464
|
-
`${criticalLines}\n\n` +
|
|
465
|
-
`开通完成后执行 \`botmux restart\`,botmux 会再次自检并把结果发到这里。${optionalBlock}`;
|
|
466
|
-
await dmAdmin(larkAppId, adminOpenId, dm, `missing scopes: ${missingCritical.map(s => s.name).join(',')}`);
|
|
467
|
-
}
|
|
468
|
-
catch (err) {
|
|
469
|
-
logger.debug(`[${larkAppId}] scope check errored: ${err?.message ?? err}`);
|
|
470
|
-
}
|
|
471
|
-
}
|
|
472
|
-
// ─── Group chat stats cache ───────────────────────────────────────────────
|
|
473
|
-
//
|
|
474
|
-
// chat.get returns both user_count (real users only) and bot_count (bots).
|
|
475
|
-
// One API call, one cache — used to gate auto-replies in multi-bot/multi-user
|
|
476
|
-
// groups (oncall chats often have 3rd-party oncall/form/AI-search bots).
|
|
477
|
-
export const CHAT_CACHE_TTL = 5 * 60_000; // 5 minutes
|
|
478
|
-
// Bounded: keyed per chat; TTL gates freshness on read, the cap stops the
|
|
479
|
-
// entry count growing with every distinct chat the bot ever serves.
|
|
480
|
-
const chatStatsCache = new BoundedMap(1000);
|
|
481
|
-
// ─── Event callback ACK safety ──────────────────────────────────────────────
|
|
482
|
-
//
|
|
483
|
-
// The Lark WS SDK sends exactly one response frame per event and only AFTER the
|
|
484
|
-
// registered handler's promise resolves (WSClient.handleEventData: it awaits
|
|
485
|
-
// eventDispatcher.invoke, then sendMessage once). So that frame is the ACK: a
|
|
486
|
-
// slow handler delays it past Feishu's 3s budget and triggers a timeout re-push.
|
|
487
|
-
// The message path below can spend seconds on OpenAPI lookups + spawning a CLI,
|
|
488
|
-
// so we return synchronously and run the heavy work behind setImmediate — the
|
|
489
|
-
// handler resolves immediately, the ACK is prompt, and the work runs after.
|
|
490
|
-
//
|
|
491
|
-
// Dedupe: Feishu re-pushes an un-ACKed/non-200 event at 15s, 5min, 1h, 6h (max
|
|
492
|
-
// 4 retries), and its pipeline is at-least-once, so a duplicate can arrive even
|
|
493
|
-
// after a timely 200. Fast-ACK keeps us inside 3s so timeout-retries stop
|
|
494
|
-
// firing — the realistic duplicate is then a near-simultaneous at-least-once
|
|
495
|
-
// copy, which a short-lived claim per stable event key suppresses. The TTL
|
|
496
|
-
// covers the 15s/5min/1h retry tiers with margin; the 6h tier is only reachable
|
|
497
|
-
// after a sustained ACK failure that fast-ACK prevents, so we don't size for it.
|
|
498
|
-
// (We claim-then-ack-success on purpose: a redelivery is always treated as a
|
|
499
|
-
// duplicate, never as recovery — matching the prior swallow-and-ACK behavior.)
|
|
500
|
-
const EVENT_CLAIM_TTL_MS = 2 * 60 * 60_000; // 2h — covers the 15s/5min/1h retry tiers
|
|
501
|
-
const EVENT_CLAIM_PRUNE_INTERVAL_MS = 5 * 60_000;
|
|
502
|
-
const EVENT_CLAIM_PRUNE_SIZE = 5000;
|
|
503
|
-
const eventClaims = new Map();
|
|
504
|
-
let eventClaimsLastPrunedAt = 0;
|
|
505
|
-
function pruneEventClaims(now = Date.now()) {
|
|
506
|
-
eventClaimsLastPrunedAt = now;
|
|
507
|
-
for (const [key, expiresAt] of eventClaims) {
|
|
508
|
-
if (expiresAt <= now)
|
|
509
|
-
eventClaims.delete(key);
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
function claimEventOnce(key) {
|
|
513
|
-
const now = Date.now();
|
|
514
|
-
// Prune under size pressure OR on a time interval, so a busy bot's map stays
|
|
515
|
-
// bounded regardless of call cadence (the size gate alone never fires below
|
|
516
|
-
// the threshold, leaving expired entries pinned for the full TTL).
|
|
517
|
-
if (eventClaims.size > EVENT_CLAIM_PRUNE_SIZE || now - eventClaimsLastPrunedAt > EVENT_CLAIM_PRUNE_INTERVAL_MS) {
|
|
518
|
-
pruneEventClaims(now);
|
|
519
|
-
}
|
|
520
|
-
const expiresAt = eventClaims.get(key);
|
|
521
|
-
if (expiresAt && expiresAt > now)
|
|
522
|
-
return false;
|
|
523
|
-
eventClaims.set(key, now + EVENT_CLAIM_TTL_MS);
|
|
524
|
-
return true;
|
|
525
|
-
}
|
|
526
|
-
// `claim` defaults to the in-memory event-id claim; the message path passes a
|
|
527
|
-
// persistent message_id claim (claimMessageOnce) so a daemon restart or the 6h
|
|
528
|
-
// re-push tier can't replay an already-handled message. The claim MUST be fully
|
|
529
|
-
// synchronous (see INVARIANT below) — both claimEventOnce and claimMessageOnce are.
|
|
530
|
-
function scheduleAckSafeEvent(key, work, label, claim = () => claimEventOnce(key)) {
|
|
531
|
-
if (!claim()) {
|
|
532
|
-
logger.info(`[event-dedupe] duplicate ${label} ignored: ${key}`);
|
|
533
|
-
return false;
|
|
534
|
-
}
|
|
535
|
-
// INVARIANT: the claim above + this setImmediate scheduling must stay fully
|
|
536
|
-
// synchronous (no await before we get here). WS events arrive in order and
|
|
537
|
-
// setImmediate is FIFO, so same-anchor messages reach serializeByAnchor in
|
|
538
|
-
// arrival order ONLY while nothing awaits ahead of the schedule. An await here
|
|
539
|
-
// would reintroduce the kickoff-ordering bug serializeByAnchor guards against.
|
|
540
|
-
setImmediate(() => {
|
|
541
|
-
void work().catch(err => logger.error(`Error handling ${label}: ${err}`));
|
|
542
|
-
});
|
|
543
|
-
return true;
|
|
544
|
-
}
|
|
545
|
-
// Fallback for an event that carries no stable id at all. Dedupe must never
|
|
546
|
-
// silently DROP a real message, so we hand back a unique key (process it, accept
|
|
547
|
-
// a rare duplicate) rather than a content-prefix key that could collide with a
|
|
548
|
-
// distinct message and suppress it for the whole TTL.
|
|
549
|
-
let unkeyableEventSeq = 0;
|
|
550
|
-
function unkeyableEventKey() {
|
|
551
|
-
return `__unkeyable__:${++unkeyableEventSeq}`;
|
|
552
|
-
}
|
|
553
|
-
function eventIdForKey(data) {
|
|
554
|
-
return data?.event_id ?? data?.uuid ?? data?.header?.event_id ?? data?.event?.event_id;
|
|
555
|
-
}
|
|
556
|
-
// card.action.trigger is a synchronous callback with a 3s deadline and NO
|
|
557
|
-
// re-push (unlike events). If a handler (e.g. restart, which spawns a worker)
|
|
558
|
-
// might exceed the budget, we ACK before 3s with a toast and patch the card
|
|
559
|
-
// afterwards — missing the deadline otherwise surfaces error 200341 to the user.
|
|
560
|
-
// 2500ms leaves headroom for the WS frame round-trip inside the 3s window.
|
|
561
|
-
const CARD_ACTION_ACK_TIMEOUT_MS = 2500;
|
|
562
|
-
const CARD_ACTION_TIMEOUT = Symbol('card-action-timeout');
|
|
563
|
-
const cardActionInFlight = new Set();
|
|
564
|
-
function cardActionMessageId(data) {
|
|
565
|
-
return data?.context?.open_message_id ?? data?.open_message_id;
|
|
566
|
-
}
|
|
567
|
-
function cardActionKey(larkAppId, data) {
|
|
568
|
-
const eventId = eventIdForKey(data);
|
|
569
|
-
if (eventId)
|
|
570
|
-
return `card.action.trigger:${larkAppId}:${eventId}`;
|
|
571
|
-
const action = data?.action;
|
|
572
|
-
const value = action?.value ?? {};
|
|
573
|
-
return `card.action.trigger:${larkAppId}:${JSON.stringify({
|
|
574
|
-
messageId: cardActionMessageId(data),
|
|
575
|
-
operator: data?.operator?.open_id,
|
|
576
|
-
action: value?.action ?? action?.option ?? action?.tag,
|
|
577
|
-
rootId: value?.root_id,
|
|
578
|
-
sessionId: value?.session_id,
|
|
579
|
-
// Detail actions can share action labels across rows; include row ids so
|
|
580
|
-
// rapid clicks on different rows do not collide in the in-flight dedupe key.
|
|
581
|
-
scheduleId: value?.schedule_id,
|
|
582
|
-
runId: value?.run_id,
|
|
583
|
-
nonce: value?.card_nonce ?? value?.nonce,
|
|
584
|
-
option: action?.option,
|
|
585
|
-
key: value?.key,
|
|
586
|
-
// Settings toggles share one action; distinguish the target field/value.
|
|
587
|
-
field: value?.field,
|
|
588
|
-
next_value: value?.next_value,
|
|
589
|
-
// Pagination actions share one action; distinguish the target page.
|
|
590
|
-
page: value?.page,
|
|
591
|
-
// Navigation context and page size affect the card that will be rebuilt.
|
|
592
|
-
origin: value?.origin,
|
|
593
|
-
pageSize: value?.page_size,
|
|
594
|
-
// `dashboard_scope` distinguishes the global tool-panel card from a
|
|
595
|
-
// per-bot view that might happen to be open on the same module. Without
|
|
596
|
-
// it a rapid global→per-bot click sequence within the dedupe window
|
|
597
|
-
// would hash-collide and the second click would be silently dropped.
|
|
598
|
-
dashboardScope: value?.dashboard_scope,
|
|
599
|
-
// Groups detail/actions can share the same `dash_groups_*` action within
|
|
600
|
-
// one card but target different chat/bot cells. Include both ids so
|
|
601
|
-
// managing bot A in group X doesn't dedupe bot B in group Y.
|
|
602
|
-
chatId: value?.chat_id,
|
|
603
|
-
appId: value?.app_id,
|
|
604
|
-
})}`;
|
|
605
|
-
}
|
|
606
|
-
function shapeCardActionResult(result) {
|
|
607
|
-
// The handler may return:
|
|
608
|
-
// - an already-shaped Lark response ({toast} and/or {card}) -> pass through;
|
|
609
|
-
// - a raw card body (e.g. toggle_stream) -> wrap as an in-place card patch.
|
|
610
|
-
if (result && (result.toast || result.card))
|
|
611
|
-
return result;
|
|
612
|
-
if (result)
|
|
613
|
-
return { card: { type: 'raw', data: result } };
|
|
614
|
-
// The Lark WS SDK only serializes callback `data` for truthy results. An
|
|
615
|
-
// empty object therefore means "ACK with no UI update", while undefined
|
|
616
|
-
// produces a code-only response that the client rejects as an invalid ACK.
|
|
617
|
-
return {};
|
|
618
|
-
}
|
|
619
|
-
function serializeRawCardForPatch(cardData) {
|
|
620
|
-
if (cardData === undefined || cardData === null)
|
|
621
|
-
return undefined;
|
|
622
|
-
return typeof cardData === 'string' ? cardData : JSON.stringify(cardData);
|
|
623
|
-
}
|
|
624
|
-
async function patchTimedOutCardActionResult(larkAppId, data, shapedResult) {
|
|
625
|
-
const messageId = cardActionMessageId(data);
|
|
626
|
-
if (!messageId || !shapedResult?.card)
|
|
627
|
-
return;
|
|
628
|
-
const card = shapedResult.card;
|
|
629
|
-
const raw = card.type === 'raw' ? card.data : card;
|
|
630
|
-
const body = serializeRawCardForPatch(raw);
|
|
631
|
-
if (!body)
|
|
632
|
-
return;
|
|
633
|
-
await updateMessage(larkAppId, messageId, body);
|
|
634
|
-
}
|
|
635
|
-
async function handleCardActionAckSafe(data, larkAppId, handlers) {
|
|
636
|
-
const eventId = eventIdForKey(data);
|
|
637
|
-
const key = cardActionKey(larkAppId, data);
|
|
638
|
-
// Durable dedupe ONLY when the platform gave a stable per-interaction id:
|
|
639
|
-
// suppresses a same-interaction redelivery over the long-connection so a
|
|
640
|
-
// non-idempotent action (restart/close) can't double-fire after the first
|
|
641
|
-
// copy already finished — the in-flight Set alone clears in finally() and
|
|
642
|
-
// would miss that. We deliberately do NOT durably claim the payload-based
|
|
643
|
-
// fallback key: distinct clicks of the same button (e.g. toggling stream
|
|
644
|
-
// on/off) legitimately repeat and must not be pinned for the whole TTL.
|
|
645
|
-
if (eventId && !claimEventOnce(key)) {
|
|
646
|
-
logger.info(`[event-dedupe] duplicate card action ignored (claimed): ${key}`);
|
|
647
|
-
return { toast: { type: 'info', content: t('toast.action_received_no_repeat', undefined, localeForBot(larkAppId)) } };
|
|
648
|
-
}
|
|
649
|
-
if (cardActionInFlight.has(key)) {
|
|
650
|
-
logger.info(`[event-dedupe] duplicate card action ignored while in-flight: ${key}`);
|
|
651
|
-
return { toast: { type: 'info', content: t('toast.action_in_progress', undefined, localeForBot(larkAppId)) } };
|
|
652
|
-
}
|
|
653
|
-
cardActionInFlight.add(key);
|
|
654
|
-
let timedOut = false;
|
|
655
|
-
const work = handlers.handleCardAction(data, larkAppId)
|
|
656
|
-
.then(shapeCardActionResult)
|
|
657
|
-
.catch(err => {
|
|
658
|
-
logger.error(`Error handling card action: ${err}`);
|
|
659
|
-
return {};
|
|
660
|
-
});
|
|
661
|
-
void work.then(result => {
|
|
662
|
-
if (!timedOut || !result)
|
|
663
|
-
return;
|
|
664
|
-
if (!result.card && result.toast) {
|
|
665
|
-
// A toast-only result can't be re-surfaced after we already ACKed with the
|
|
666
|
-
// generic "后台处理中" toast: toasts ride the synchronous callback response,
|
|
667
|
-
// and the message-update API only patches the card. Log rather than drop.
|
|
668
|
-
logger.warn(`[card-action] slow handler resolved to a toast-only result after ACK; not shown to user: ${JSON.stringify(result.toast)}`);
|
|
669
|
-
return;
|
|
670
|
-
}
|
|
671
|
-
return patchTimedOutCardActionResult(larkAppId, data, result)
|
|
672
|
-
.catch(err => logger.warn(`Failed to patch timed-out card action result: ${err}`));
|
|
673
|
-
}).finally(() => {
|
|
674
|
-
cardActionInFlight.delete(key);
|
|
675
|
-
});
|
|
676
|
-
const timeout = new Promise(resolve => setTimeout(resolve, CARD_ACTION_ACK_TIMEOUT_MS, CARD_ACTION_TIMEOUT));
|
|
677
|
-
const result = await Promise.race([work, timeout]);
|
|
678
|
-
if (result === CARD_ACTION_TIMEOUT) {
|
|
679
|
-
timedOut = true;
|
|
680
|
-
logger.warn(`[card-action] handler exceeded ${CARD_ACTION_ACK_TIMEOUT_MS}ms; ACKing first and continuing in background: ${key}`);
|
|
681
|
-
return { toast: { type: 'info', content: t('toast.action_received_bg', undefined, localeForBot(larkAppId)) } };
|
|
682
|
-
}
|
|
683
|
-
return result;
|
|
684
|
-
}
|
|
685
|
-
/** Test-only: clear callback dedupe claims between cases. */
|
|
686
|
-
export function __resetEventClaimsForTest() {
|
|
687
|
-
eventClaims.clear();
|
|
688
|
-
cardActionInFlight.clear();
|
|
689
|
-
// The message path now dedupes via the persistent seen-message store; clear its
|
|
690
|
-
// in-memory cache too so cases reusing the same message_id don't suppress each other.
|
|
691
|
-
_resetSeenMessagesForTest();
|
|
692
|
-
}
|
|
693
|
-
export async function getGroupStats(larkAppId, chatId) {
|
|
694
|
-
const cacheKey = `${larkAppId}:${chatId}`;
|
|
695
|
-
const cached = chatStatsCache.get(cacheKey);
|
|
696
|
-
if (cached && Date.now() - cached.fetchedAt < CHAT_CACHE_TTL) {
|
|
697
|
-
return { userCount: cached.userCount, botCount: cached.botCount };
|
|
698
|
-
}
|
|
699
|
-
try {
|
|
700
|
-
const info = await getChatInfo(larkAppId, chatId);
|
|
701
|
-
chatStatsCache.set(cacheKey, { userCount: info.userCount, botCount: info.botCount, fetchedAt: Date.now() });
|
|
702
|
-
return info;
|
|
703
|
-
}
|
|
704
|
-
catch (err) {
|
|
705
|
-
// Soft failure — the fallback below assumes worst case (multi-user,
|
|
706
|
-
// multi-bot → require @mention). No user-visible regression, so debug.
|
|
707
|
-
logger.debug(`Failed to get chat stats for ${chatId}, using safe fallback: ${err}`);
|
|
708
|
-
if (cached)
|
|
709
|
-
return { userCount: cached.userCount, botCount: cached.botCount };
|
|
710
|
-
// Fallback: assume multi-person, multi-bot → require @mention to be safe.
|
|
711
|
-
return { userCount: 999, botCount: 999 };
|
|
712
|
-
}
|
|
713
|
-
}
|
|
714
|
-
/**
|
|
715
|
-
* Drop the cached group stats for one chat — called when a membership-change
|
|
716
|
-
* event that is VISIBLE to this app arrives (user add/delete broadcast, or our
|
|
717
|
-
* own bot being added/removed), so the 1v1 relax gate sees fresh counts on the
|
|
718
|
-
* very next message instead of coasting on stale numbers for up to
|
|
719
|
-
* CHAT_CACHE_TTL. TTL 继续保留,作为事件未订阅(老应用)时的兜底。
|
|
720
|
-
* 注意跨进程边界:「别的 bot 进群/离群」事件只推给当事 bot 自己的 app,
|
|
721
|
-
* 一 bot 一 daemon 部署下此函数够不到兄弟进程的缓存(见 handler 处注释)。
|
|
722
|
-
*/
|
|
723
|
-
export function invalidateChatStats(larkAppId, chatId) {
|
|
724
|
-
if (chatStatsCache.delete(`${larkAppId}:${chatId}`)) {
|
|
725
|
-
logger.debug(`[group-stats] invalidated cached stats for ${chatId} (${larkAppId}): membership changed`);
|
|
726
|
-
}
|
|
727
|
-
}
|
|
728
|
-
/** Test-only: clear the group-stats cache between cases. */
|
|
729
|
-
export function __resetChatStatsForTest() {
|
|
730
|
-
chatStatsCache.clear();
|
|
731
|
-
}
|
|
732
|
-
// ─── Cross-bot open_id mapping ──────────────────────────────────────────
|
|
733
|
-
//
|
|
734
|
-
// Lark open_id is per-app scoped: Bot A sees a different open_id for Bot B
|
|
735
|
-
// than Bot B sees for itself. The self-reported botOpenId (from /bot/v3/info)
|
|
736
|
-
// is useless for other bots to @mention.
|
|
737
|
-
//
|
|
738
|
-
// We build a per-bot cross-reference from event data: when Bot A's event
|
|
739
|
-
// handler receives a message that @mentions Bot B, the mention includes
|
|
740
|
-
// Bot B's open_id as seen by Bot A's app. We persist this mapping so that
|
|
741
|
-
// listChatBotMembers can return correct open_ids.
|
|
742
|
-
/** Read the per-bot cross-reference: botName(lowercase) → openId as seen by larkAppId's app */
|
|
743
|
-
export function readBotOpenIdCrossRef(dataDir, larkAppId) {
|
|
744
|
-
const map = new Map();
|
|
745
|
-
try {
|
|
746
|
-
const fp = join(dataDir, `bot-openids-${larkAppId}.json`);
|
|
747
|
-
if (existsSync(fp)) {
|
|
748
|
-
const data = JSON.parse(readFileSync(fp, 'utf-8'));
|
|
749
|
-
for (const [name, openId] of Object.entries(data)) {
|
|
750
|
-
map.set(name.toLowerCase(), openId);
|
|
751
|
-
}
|
|
752
|
-
}
|
|
753
|
-
}
|
|
754
|
-
catch { /* ignore */ }
|
|
755
|
-
return map;
|
|
756
|
-
}
|
|
757
|
-
/** Is `senderOpenId` a registered botmux peer (from larkAppId's cross-ref)?
|
|
758
|
-
* Used to gate chat-scope foreign-bot @mention spawning to vetted peers. */
|
|
759
|
-
export function isKnownPeerBot(dataDir, larkAppId, senderOpenId) {
|
|
760
|
-
if (!senderOpenId)
|
|
761
|
-
return false;
|
|
762
|
-
for (const openId of readBotOpenIdCrossRef(dataDir, larkAppId).values()) {
|
|
763
|
-
if (openId === senderOpenId)
|
|
764
|
-
return true;
|
|
765
|
-
}
|
|
766
|
-
return false;
|
|
767
|
-
}
|
|
768
|
-
/**
|
|
769
|
-
* Auth-grade local sibling check for the narrow `/repo` exception.
|
|
770
|
-
*
|
|
771
|
-
* Cross-ref proves only "this receiver has seen this sender open_id as some
|
|
772
|
-
* peer" and may be stale or name-poisoned. For authorization we additionally
|
|
773
|
-
* require the Lark-stamped sender union_id to match exactly one currently
|
|
774
|
-
* configured, transport-enabled sibling app's learned own union_id.
|
|
775
|
-
*/
|
|
776
|
-
export function isVerifiedLocalSiblingBot(dataDir, larkAppId, senderOpenId, senderUnionId) {
|
|
777
|
-
const openId = (senderOpenId ?? '').trim();
|
|
778
|
-
const unionId = (senderUnionId ?? '').trim();
|
|
779
|
-
if (!openId || !unionId)
|
|
780
|
-
return false;
|
|
781
|
-
if (!isKnownPeerBot(dataDir, larkAppId, openId))
|
|
782
|
-
return false;
|
|
783
|
-
let matchingConfiguredSiblings = 0;
|
|
784
|
-
try {
|
|
785
|
-
for (const cfg of loadBotConfigs()) {
|
|
786
|
-
const appId = (cfg.larkAppId ?? '').trim();
|
|
787
|
-
if (!appId || appId === larkAppId || cfg.apiOnly === true)
|
|
788
|
-
continue;
|
|
789
|
-
if (getBotUnionId(dataDir, appId) === unionId)
|
|
790
|
-
matchingConfiguredSiblings += 1;
|
|
791
|
-
if (matchingConfiguredSiblings > 1)
|
|
792
|
-
return false;
|
|
793
|
-
}
|
|
794
|
-
}
|
|
795
|
-
catch {
|
|
796
|
-
return false;
|
|
797
|
-
}
|
|
798
|
-
return matchingConfiguredSiblings === 1;
|
|
799
|
-
}
|
|
800
|
-
/**
|
|
801
|
-
* Should a FOREIGN bot sender be trusted to collaborate (route/spawn a session)
|
|
802
|
-
* WITHOUT `/grant`, because it's a teammate? Two trust sources, both rooted in
|
|
803
|
-
* tenant-stable identity or team-controlled group membership — never a name:
|
|
804
|
-
*
|
|
805
|
-
* 1. **Learned teammate** — its `union_id` (from the inbound event's
|
|
806
|
-
* `sender.sender_id.union_id`) is in the team-bot store, i.e. we've seen it
|
|
807
|
-
* vouched inside a team-assembled group before. Honoured in ANY chat.
|
|
808
|
-
* 2. **Team-assembled group** — the chat itself is a 拉群 group (team-controlled
|
|
809
|
-
* membership), so a botmux bot speaking there is a vouched teammate even on
|
|
810
|
-
* first contact (mirrors the existing oncall-chat exemption).
|
|
811
|
-
*
|
|
812
|
-
* `isKnownPeerBot` (same-deployment siblings) is checked separately by callers;
|
|
813
|
-
* this covers cross-deployment TEAM peers. Returns false when neither holds, so
|
|
814
|
-
* the caller falls back to the /grant request card.
|
|
815
|
-
*
|
|
816
|
-
* 平台团队与旧版联邦团队同权:isPlatformTeamBot(平台 team-sync 下发的团队 bot
|
|
817
|
-
* union_id roster)与 isTeamBot(团队群里学来的 union_id)都是 union_id 锚定的
|
|
818
|
-
* bot 专属信任;平台拉的团队群则经 platform: 前缀镜像进 team-groups,走同一个
|
|
819
|
-
* isTeamGroupChat。两条路都算团队模式,都不需要 /grant。
|
|
820
|
-
*
|
|
821
|
-
* 调用方只剩 {@link evaluateBotTalk} 一个(bot 闸门的唯一入口);(1) 的两条腿与
|
|
822
|
-
* evaluateTalk 的 teamBot 腿重合,真正额外放行的是 (2)。保留本谓词是因为它是
|
|
823
|
-
* 「bot 团队信任」的定义所在,且有专属单测(team-peer-trust / platform-team-trust)。
|
|
824
|
-
*/
|
|
825
|
-
export function isTrustedTeamBotSender(dataDir, chatId, senderUnionId) {
|
|
826
|
-
return isTeamBot(dataDir, senderUnionId)
|
|
827
|
-
|| isPlatformTeamBot(dataDir, senderUnionId)
|
|
828
|
-
|| isTeamGroupChat(dataDir, chatId);
|
|
829
|
-
}
|
|
830
|
-
/** Update the per-bot cross-reference from @mention data in an event.
|
|
831
|
-
* mentionsList comes from Lark event message.mentions array. */
|
|
832
|
-
export function updateBotOpenIdCrossRef(dataDir, larkAppId, mentionsList) {
|
|
833
|
-
if (!mentionsList || mentionsList.length === 0)
|
|
834
|
-
return;
|
|
835
|
-
// Read known bot names from bots-info.json
|
|
836
|
-
const knownBotNames = new Set();
|
|
837
|
-
try {
|
|
838
|
-
const infoPath = join(dataDir, 'bots-info.json');
|
|
839
|
-
if (existsSync(infoPath)) {
|
|
840
|
-
const entries = JSON.parse(readFileSync(infoPath, 'utf-8'));
|
|
841
|
-
for (const e of entries) {
|
|
842
|
-
if (e.botName)
|
|
843
|
-
knownBotNames.add(e.botName.toLowerCase());
|
|
844
|
-
}
|
|
845
|
-
}
|
|
846
|
-
}
|
|
847
|
-
catch { /* ignore */ }
|
|
848
|
-
if (knownBotNames.size === 0)
|
|
849
|
-
return;
|
|
850
|
-
// Read existing cross-reference
|
|
851
|
-
const fp = join(dataDir, `bot-openids-${larkAppId}.json`);
|
|
852
|
-
let existing = {};
|
|
853
|
-
try {
|
|
854
|
-
if (existsSync(fp))
|
|
855
|
-
existing = JSON.parse(readFileSync(fp, 'utf-8'));
|
|
856
|
-
}
|
|
857
|
-
catch { /* ignore */ }
|
|
858
|
-
// Update with new mentions that match known bot names
|
|
859
|
-
let changed = false;
|
|
860
|
-
for (const m of mentionsList) {
|
|
861
|
-
const name = m.name;
|
|
862
|
-
const openId = mentionOpenId(m);
|
|
863
|
-
if (!name || !openId)
|
|
864
|
-
continue;
|
|
865
|
-
if (!knownBotNames.has(name.toLowerCase()))
|
|
866
|
-
continue;
|
|
867
|
-
if (existing[name] === openId)
|
|
868
|
-
continue;
|
|
869
|
-
existing[name] = openId;
|
|
870
|
-
changed = true;
|
|
871
|
-
}
|
|
872
|
-
if (changed) {
|
|
873
|
-
try {
|
|
874
|
-
if (!existsSync(dataDir))
|
|
875
|
-
mkdirSync(dataDir, { recursive: true });
|
|
876
|
-
atomicWriteFileSync(fp, JSON.stringify(existing, null, 2) + '\n');
|
|
877
|
-
logger.debug(`Updated bot open_id cross-ref for ${larkAppId}: ${JSON.stringify(existing)}`);
|
|
878
|
-
}
|
|
879
|
-
catch (err) {
|
|
880
|
-
logger.debug(`Failed to write bot open_id cross-ref: ${err}`);
|
|
881
|
-
}
|
|
882
|
-
}
|
|
883
|
-
}
|
|
884
|
-
// ─── /introduce collaboration handshake ──────────────────────────────────
|
|
885
|
-
//
|
|
886
|
-
// 用户在群里发 `@A @B /introduce`(顺序任意,带不带额外文本都行),每个被
|
|
887
|
-
// @ 的 bot 的 daemon 都会收到一份相同的 mentions[],里面自带每个被 @ 实体
|
|
888
|
-
// 的 (open_id, name)。我们把这些登记进按 chatId 分文件的 observed-bots-store,
|
|
889
|
-
// 后续 `botmux bots list` / `<available_bots>` 就能感知到非本机 daemon 启动
|
|
890
|
-
// 的协作 bot,并能 @ 回去。
|
|
891
|
-
//
|
|
892
|
-
// 飞书没有任何公开接口能列出群里 bot 的 open_id(chat-members/get 明文跳过
|
|
893
|
-
// bot 成员),这是当前条件下能拿到陌生 bot open_id 的唯一可靠路径。
|
|
894
|
-
/** Command-position match: after stripping leading @mentions, the remaining
|
|
895
|
-
* text must begin with `/introduce` (optionally followed by whitespace).
|
|
896
|
-
* This is the same approach `parseForceTopicInvocation` takes for /t /topic.
|
|
897
|
-
* Stricter than a bare token match — "please run /introduce" or similar
|
|
898
|
-
* quoted/explanatory text won't trigger. */
|
|
899
|
-
const INTRODUCE_RE = /^\/introduce(?:\s|$)/i;
|
|
900
|
-
/**
|
|
901
|
-
* If `message` is a /introduce command, side-effect it (record observed bots
|
|
902
|
-
* + send ack) and return `true` so the caller skips normal CLI routing.
|
|
903
|
-
*
|
|
904
|
-
* /introduce 不需要任何授权:它只是把群里别的 bot 记进花名册(observed),不授予
|
|
905
|
-
* 任何对话/操作权,所以群里任何人都能用(与 /grant 的 owner 强闸门相反)。
|
|
906
|
-
*
|
|
907
|
-
* Consumed without side effects (still returns true) when:
|
|
908
|
-
* - mentions[] minus self is empty — nothing to learn, ignore quietly
|
|
909
|
-
*
|
|
910
|
-
* Writes ALL mentions including self to the store. Each receiving bot's
|
|
911
|
-
* daemon owns its own per-observer file (see observed-bots-store), so the
|
|
912
|
-
* self entry is the only authoritative record of this app's own open_id
|
|
913
|
-
* in the per-observer view — useful for `botmux bots list` self-identification.
|
|
914
|
-
*/
|
|
915
|
-
export async function tryHandleIntroduceCommand(larkAppId, message, senderOpenId) {
|
|
916
|
-
const text = extractMessageTextForRouting(message);
|
|
917
|
-
if (!text)
|
|
918
|
-
return false;
|
|
919
|
-
// Strip leading @<mention> tokens (using the message's mentions list to
|
|
920
|
-
// tolerate names with spaces) before checking the command position.
|
|
921
|
-
const stripped = stripLeadingMentions(text.trim(), message?.mentions ?? []);
|
|
922
|
-
if (!INTRODUCE_RE.test(stripped))
|
|
923
|
-
return false;
|
|
924
|
-
logger.debug(`[${larkAppId}] /introduce from ${senderOpenId ?? 'unknown'} (no auth required)`);
|
|
925
|
-
if (grantCommandRestriction(larkAppId, message.chat_id, senderOpenId).blocked) {
|
|
926
|
-
const loc = localeForBot(larkAppId);
|
|
927
|
-
await replyMessage(larkAppId, message.message_id, JSON.stringify({
|
|
928
|
-
text: t('cmd.grant_restricted', { cmd: '/introduce' }, loc),
|
|
929
|
-
})).catch(err => logger.debug(`introduce grant_restricted reply failed: ${err}`));
|
|
930
|
-
return true;
|
|
931
|
-
}
|
|
932
|
-
const selfOpenId = getBot(larkAppId).botOpenId;
|
|
933
|
-
const rawMentions = message.mentions ?? [];
|
|
934
|
-
const all = rawMentions
|
|
935
|
-
.map(m => ({ openId: mentionOpenId(m) ?? '', name: m.name ?? '' }))
|
|
936
|
-
.filter(m => m.openId && m.name);
|
|
937
|
-
const hasExternal = all.some(m => m.openId !== selfOpenId);
|
|
938
|
-
if (!hasExternal) {
|
|
939
|
-
logger.debug(`[${larkAppId}] /introduce ignored: no external bot in mentions`);
|
|
940
|
-
return true;
|
|
941
|
-
}
|
|
942
|
-
const chatId = message.chat_id;
|
|
943
|
-
// 查通讯录剔除真人:花名册只收 bot——真人混进去会污染 <available_bots> 误导模型,
|
|
944
|
-
// 且不必再「靠人自觉」只 @ bot。self 始终保留(它是本 app open_id 的权威自记录)。
|
|
945
|
-
// 缺 contact 读权限时 isHumanOpenId 一律返回 false → 退回「全部登记」旧行为(见其注释)。
|
|
946
|
-
const humanFlags = await Promise.all(all.map(m => (m.openId === selfOpenId ? Promise.resolve(false) : isHumanOpenId(larkAppId, m.openId).catch(() => false))));
|
|
947
|
-
const bots = all.filter((_, i) => !humanFlags[i]);
|
|
948
|
-
try {
|
|
949
|
-
// Persist to the observer-scoped store: these open_ids are scoped to the
|
|
950
|
-
// receiving app (larkAppId), so they're correct for THIS daemon to use
|
|
951
|
-
// when @-mentioning back.
|
|
952
|
-
recordObservedBots(config.session.dataDir, larkAppId, chatId, bots, 'introduce');
|
|
953
|
-
}
|
|
954
|
-
catch (err) {
|
|
955
|
-
logger.warn(`[${larkAppId}] /introduce: failed to persist observed bots: ${err}`);
|
|
956
|
-
}
|
|
957
|
-
const externalBots = bots.filter(m => m.openId !== selfOpenId);
|
|
958
|
-
const ackText = externalBots.length
|
|
959
|
-
? `✅ 已认识本群 ${externalBots.length} 个伙伴:${externalBots.map(m => `@${m.name}`).join(' ')}`
|
|
960
|
-
: `ℹ️ 没有可登记的机器人(/introduce 只登记机器人,@ 的若是真人会被忽略)`;
|
|
961
|
-
try {
|
|
962
|
-
await replyMessage(larkAppId, message.message_id, ackText);
|
|
963
|
-
}
|
|
964
|
-
catch (err) {
|
|
965
|
-
logger.warn(`[${larkAppId}] /introduce ack failed: ${err}`);
|
|
966
|
-
}
|
|
967
|
-
return true;
|
|
968
|
-
}
|
|
969
|
-
// ─── @mention detection ──────────────────────────────────────────────────
|
|
970
|
-
/** One-shot guard so the mention-shape early-warning logs at most once per
|
|
971
|
-
* process instead of flooding once Lark converges the shapes (see below). */
|
|
972
|
-
let warnedStringMentionShape = false;
|
|
973
|
-
/** Check if the bot was @mentioned in this message */
|
|
974
|
-
export function isBotMentioned(larkAppId, message, _senderOpenId) {
|
|
975
|
-
const botOpenId = getBot(larkAppId).botOpenId;
|
|
976
|
-
if (!botOpenId) {
|
|
977
|
-
// Startup race: events can arrive before probeBotOpenId() resolves the
|
|
978
|
-
// per-bot open_id. Subsequent events succeed once the probe completes,
|
|
979
|
-
// so this is not a real warning — drop to debug to keep error.log clean.
|
|
980
|
-
logger.debug(`[${larkAppId}] Bot open_id not yet known, skipping @mention check`);
|
|
981
|
-
return false;
|
|
982
|
-
}
|
|
983
|
-
// Early-warning: today's WS events carry mention.id as an object; the REST
|
|
984
|
-
// API carries a bare string. A string-form id on the event path means Lark
|
|
985
|
-
// has converged the event onto the REST shape — surface it (once) so a silent
|
|
986
|
-
// @-routing regression announces itself even though the shared gate absorbs it.
|
|
987
|
-
const mentions = message?.mentions ?? [];
|
|
988
|
-
if (!warnedStringMentionShape && mentions.some((m) => typeof m?.id === 'string')) {
|
|
989
|
-
warnedStringMentionShape = true;
|
|
990
|
-
logger.warn(`[${larkAppId}] mention.id arrived in string form on the event path — Lark may have converged the WS event onto the REST shape. mentionOpenId() absorbs it, but verify group @-routing. (logged once per process)`);
|
|
991
|
-
}
|
|
992
|
-
// Single source of truth shared with the poll + dashboard-preview legs.
|
|
993
|
-
return messageMentionsBot(message, larkAppId, botOpenId);
|
|
994
|
-
}
|
|
995
|
-
/** Does this message @mention a *specific other member* (a person or bot that
|
|
996
|
-
* is NOT this bot)? Used by the 'ambient' mention policy to decide whether to
|
|
997
|
-
* back off: under 'ambient' the bot answers un-@ messages, but if the user
|
|
998
|
-
* explicitly addresses SOMEONE ELSE it stays quiet (the redirect carve-out).
|
|
999
|
-
* `@all` addresses everyone including this bot, so it is NOT an "other member"
|
|
1000
|
-
* and does NOT trigger backoff. Mirrors isBotMentioned's two shapes:
|
|
1001
|
-
* message.mentions[] (user text) and inline `at` nodes in post content. */
|
|
1002
|
-
export function mentionsAnotherMember(larkAppId, message) {
|
|
1003
|
-
const botOpenId = getBot(larkAppId).botOpenId;
|
|
1004
|
-
// 1. message.mentions array (populated for user-sent text messages)
|
|
1005
|
-
const mentions = message.mentions ?? [];
|
|
1006
|
-
for (const m of mentions) {
|
|
1007
|
-
// mentionOpenId() tolerates both the WS event object shape ({ open_id }) and
|
|
1008
|
-
// the REST bare-string shape. Bot mentions may also arrive as app_id
|
|
1009
|
-
// (id_type='app_id' / { app_id }) with no open_id; isBotMentioned handles
|
|
1010
|
-
// that shape via mentionMatchesBot(), so the redirect/yield check must too.
|
|
1011
|
-
const oid = mentionOpenId(m);
|
|
1012
|
-
if (oid) {
|
|
1013
|
-
if (oid === botOpenId)
|
|
1014
|
-
continue; // that's me
|
|
1015
|
-
if (oid === 'all')
|
|
1016
|
-
continue; // @all → everyone incl. me
|
|
1017
|
-
return true; // a specific other member
|
|
1018
|
-
}
|
|
1019
|
-
const appId = mentionAppId(m);
|
|
1020
|
-
if (appId) {
|
|
1021
|
-
if (appId === larkAppId)
|
|
1022
|
-
continue; // that's me, addressed by app_id
|
|
1023
|
-
if (appId === 'all')
|
|
1024
|
-
continue;
|
|
1025
|
-
return true; // another bot addressed by app_id
|
|
1026
|
-
}
|
|
1027
|
-
}
|
|
1028
|
-
// 2. inline `at` nodes in post content (bot-sent / rich messages)
|
|
1029
|
-
try {
|
|
1030
|
-
const content = JSON.parse(message.content ?? '{}');
|
|
1031
|
-
const inner = content.zh_cn ?? content.en_us ?? content;
|
|
1032
|
-
if (Array.isArray(inner?.content)) {
|
|
1033
|
-
for (const paragraph of inner.content) {
|
|
1034
|
-
if (!Array.isArray(paragraph))
|
|
1035
|
-
continue;
|
|
1036
|
-
for (const node of paragraph) {
|
|
1037
|
-
if (node.tag !== 'at')
|
|
1038
|
-
continue;
|
|
1039
|
-
const uid = node.user_id;
|
|
1040
|
-
if (!uid || uid === botOpenId || uid === 'all')
|
|
1041
|
-
continue;
|
|
1042
|
-
return true;
|
|
1043
|
-
}
|
|
1044
|
-
}
|
|
1045
|
-
}
|
|
1046
|
-
}
|
|
1047
|
-
catch { /* ignore parse errors */ }
|
|
1048
|
-
return false;
|
|
1049
|
-
}
|
|
1050
|
-
function substituteTargetMatchesMention(target, mention) {
|
|
1051
|
-
return Boolean((target.openId && mention.openId === target.openId) ||
|
|
1052
|
-
(target.userId && mention.userId === target.userId) ||
|
|
1053
|
-
(target.unionId && mention.unionId === target.unionId));
|
|
1054
|
-
}
|
|
1055
|
-
export function resolveSubstituteTrigger(larkAppId, message) {
|
|
1056
|
-
const cfg = getBot(larkAppId).config.substituteMode;
|
|
1057
|
-
if (!cfg?.enabled || !cfg.targets?.length)
|
|
1058
|
-
return undefined;
|
|
1059
|
-
const mentions = extractMentionIdentities(message);
|
|
1060
|
-
for (const mention of mentions) {
|
|
1061
|
-
const target = cfg.targets.find(t => substituteTargetMatchesMention(t, mention));
|
|
1062
|
-
if (!target)
|
|
1063
|
-
continue;
|
|
1064
|
-
return {
|
|
1065
|
-
target: {
|
|
1066
|
-
name: target.name,
|
|
1067
|
-
openId: target.openId,
|
|
1068
|
-
userId: target.userId,
|
|
1069
|
-
unionId: target.unionId,
|
|
1070
|
-
},
|
|
1071
|
-
observedMention: {
|
|
1072
|
-
name: mention.name,
|
|
1073
|
-
openId: mention.openId,
|
|
1074
|
-
userId: mention.userId,
|
|
1075
|
-
unionId: mention.unionId,
|
|
1076
|
-
},
|
|
1077
|
-
disclosure: cfg.disclosure ?? 'prefix',
|
|
1078
|
-
};
|
|
1079
|
-
}
|
|
1080
|
-
return undefined;
|
|
1081
|
-
}
|
|
1082
|
-
function isSubstituteExcludedChat(cfg, chatId) {
|
|
1083
|
-
return cfg?.excludedChats?.includes(chatId) ?? false;
|
|
1084
|
-
}
|
|
1085
|
-
function isSubstituteAllowedChat(cfg, chatId) {
|
|
1086
|
-
// 黑名单先判且 deny-wins:命中即整段替身触发块短路(连带跳过其后的运行态
|
|
1087
|
-
// 开关 isSubstituteEnabledForChat),因此配置黑名单 = 硬关闭,/substitute on
|
|
1088
|
-
// 也翻不回来。对普通群与话题群一视同仁,与白名单同层。
|
|
1089
|
-
if (isSubstituteExcludedChat(cfg, chatId))
|
|
1090
|
-
return false;
|
|
1091
|
-
if (!cfg?.chats?.length)
|
|
1092
|
-
return true;
|
|
1093
|
-
return cfg.chats.includes(chatId);
|
|
1094
|
-
}
|
|
1095
|
-
function mentionMatchesBot(m, larkAppId, botOpenId) {
|
|
1096
|
-
const openId = mentionOpenId(m);
|
|
1097
|
-
if (botOpenId && openId === botOpenId)
|
|
1098
|
-
return true;
|
|
1099
|
-
// Some Lark event payloads identify bot mentions by app_id:
|
|
1100
|
-
// { id_type: "app_id", id: "cli_xxx" }
|
|
1101
|
-
// Treat that as an explicit mention of this daemon, but do not let app_id
|
|
1102
|
-
// flow through mentionOpenId(), which is persisted and used as an open_id.
|
|
1103
|
-
const appId = mentionAppId(m);
|
|
1104
|
-
return Boolean(larkAppId && appId === larkAppId);
|
|
1105
|
-
}
|
|
1106
|
-
/**
|
|
1107
|
-
* 全部 talk 放行源的**运行时**枚举(TalkReason 由它派生)。
|
|
1108
|
-
*
|
|
1109
|
-
* 之所以是数组而不是纯 type:`test/bot-talk-parity.test.ts` 按它逐条核对
|
|
1110
|
-
* 「这条腿对人和对 bot 分别是什么行为」,少一格就红。tsconfig 的 include 只有
|
|
1111
|
-
* `src/**`,测试不过 tsc——纯类型层的穷尽约束在这里执行不了,必须落到运行时。
|
|
1112
|
-
*
|
|
1113
|
-
* 新增一条 talk 源时:改 evaluateTalk(人/bot 同时生效)+ 在那张表补一格说明,
|
|
1114
|
-
* **不要**去 bot 路由闸里加 OR 腿(那正是 allowedChatGroups 漏掉的老路)。
|
|
1115
|
-
*/
|
|
1116
|
-
export const TALK_REASONS = [
|
|
1117
|
-
'allowedUser',
|
|
1118
|
-
'oncall',
|
|
1119
|
-
'peer',
|
|
1120
|
-
'teamBot',
|
|
1121
|
-
'teamMember',
|
|
1122
|
-
'allowedChatGroup',
|
|
1123
|
-
'open',
|
|
1124
|
-
'chatGrant',
|
|
1125
|
-
'globalGrant',
|
|
1126
|
-
'p2pOpen',
|
|
1127
|
-
'none',
|
|
1128
|
-
];
|
|
1129
|
-
export function grantCommandRestriction(larkAppId, chatId, senderOpenId) {
|
|
1130
|
-
const bot = getBot(larkAppId);
|
|
1131
|
-
if (bot.config.restrictGrantCommands !== true)
|
|
1132
|
-
return { blocked: false };
|
|
1133
|
-
const ev = evaluateTalk(larkAppId, chatId, senderOpenId);
|
|
1134
|
-
if (ev.reason === 'chatGrant' || ev.reason === 'globalGrant') {
|
|
1135
|
-
return { blocked: true, reason: ev.reason };
|
|
1136
|
-
}
|
|
1137
|
-
return { blocked: false };
|
|
1138
|
-
}
|
|
1139
|
-
/** per-chat per-user 授权命中判断(仅用于 canTalk —— 不给管理命令权)。 */
|
|
1140
|
-
function hasChatGrant(larkAppId, chatId, openId) {
|
|
1141
|
-
if (!chatId || !openId || !getBot(larkAppId).config.chatGrants?.[chatId]?.includes(openId))
|
|
1142
|
-
return false;
|
|
1143
|
-
return grantNotExpired(larkAppId, 'chat', chatId, openId, chatQuotaKey(chatId, openId));
|
|
1144
|
-
}
|
|
1145
|
-
/** 全局对话授权命中判断(人/bot 通用,仅用于 canTalk / bot 路由闸 —— 不给管理命令权)。 */
|
|
1146
|
-
function hasGlobalGrant(larkAppId, openId) {
|
|
1147
|
-
if (!openId || !getBot(larkAppId).config.globalGrants?.includes(openId))
|
|
1148
|
-
return false;
|
|
1149
|
-
return grantNotExpired(larkAppId, 'global', undefined, openId, globalQuotaKey(openId));
|
|
1150
|
-
}
|
|
1151
|
-
const expiryCleanupInFlight = new Set();
|
|
1152
|
-
/**
|
|
1153
|
-
* 到期判断是同步安全边界:过期后本条消息立即拒绝;持久化清理由带 observedExpiresAt
|
|
1154
|
-
* 条件的原子 RMW 异步完成,避免误删刚续期的授权。
|
|
1155
|
-
*/
|
|
1156
|
-
function grantNotExpired(larkAppId, scope, chatId, openId, grantKey) {
|
|
1157
|
-
const expiresAt = getGrantExpiresAt(larkAppId, grantKey);
|
|
1158
|
-
if (expiresAt === undefined || Date.now() < expiresAt)
|
|
1159
|
-
return true;
|
|
1160
|
-
const cleanupKey = `${larkAppId}:${grantKey}:${expiresAt}`;
|
|
1161
|
-
if (!expiryCleanupInFlight.has(cleanupKey)) {
|
|
1162
|
-
expiryCleanupInFlight.add(cleanupKey);
|
|
1163
|
-
void removeExpiredGrant(larkAppId, scope, chatId, openId, expiresAt)
|
|
1164
|
-
.then(result => {
|
|
1165
|
-
if (!result.ok)
|
|
1166
|
-
logger.warn(`[grant:${larkAppId}] expiry cleanup failed key=${grantKey} reason=${result.reason}`);
|
|
1167
|
-
})
|
|
1168
|
-
.catch(err => logger.warn(`[grant:${larkAppId}] expiry cleanup failed key=${grantKey}: ${err}`))
|
|
1169
|
-
.finally(() => expiryCleanupInFlight.delete(cleanupKey));
|
|
1170
|
-
}
|
|
1171
|
-
return false;
|
|
1172
|
-
}
|
|
1173
|
-
/** 整群 talk 授权命中判断(裸 `/grant` 写入的 allowedChatGroups)。chat 维度、sender 无关,
|
|
1174
|
-
* 与 oncall 同一个安全模型:只放行 canTalk / bot 路由闸,canOperate 绝不读它。 */
|
|
1175
|
-
function hasAllowedChatGroup(larkAppId, chatId) {
|
|
1176
|
-
return !!chatId && !!getBot(larkAppId).config.allowedChatGroups?.includes(chatId);
|
|
1177
|
-
}
|
|
1178
|
-
/**
|
|
1179
|
-
* 是否配置了任何白名单(限制态)。判定用 **原始** config.allowedUsers, 不用
|
|
1180
|
-
* resolvedAllowedUsers——否则「配了 owner 但启动时邮箱/union 解析失败 → resolved 为空」
|
|
1181
|
-
* 会 fall through 成「无白名单 = 全开放」,把误配/解析失败 fail-open 成谁都能 operate。
|
|
1182
|
-
* 配了就算限制态:解析为空时成员判定一律落空 → fail-closed(由 owner 修配置)。
|
|
1183
|
-
*/
|
|
1184
|
-
function hasConfiguredAllowlist(bot) {
|
|
1185
|
-
return (bot.config.allowedUsers?.length ?? 0) > 0
|
|
1186
|
-
|| (bot.config.allowedChatGroups?.length ?? 0) > 0
|
|
1187
|
-
|| (bot.config.globalGrants?.length ?? 0) > 0
|
|
1188
|
-
// p2pOpen 也是一次显式的权限边界声明:配了它 = 进入限制态。否则「只配 p2pOpen、
|
|
1189
|
-
// 没配 allowedUsers」会 fall through 到 open 模式,把**群聊**和 **canOperate** 一起
|
|
1190
|
-
// 放开(陌生人能 /restart /cd),与 p2pOpen「只开私聊 talk」的语义正好相反。
|
|
1191
|
-
// 此时若没配 allowedUsers → 谁都不能 operate(fail-closed),bot-registry 会告警。
|
|
1192
|
-
|| bot.config.p2pOpen === true;
|
|
1193
|
-
}
|
|
1194
|
-
export function canTalk(larkAppId, chatId, senderOpenId, senderUnionId, memberUnionId, chatType) {
|
|
1195
|
-
return evaluateTalk(larkAppId, chatId, senderOpenId, senderUnionId, memberUnionId, chatType).allowed;
|
|
1196
|
-
}
|
|
1197
|
-
/**
|
|
1198
|
-
* @param senderUnionId BOT-trust union(teamBot 腿)——调用方必须已按 sender_type
|
|
1199
|
-
* 锁定为「飞书盖章的 bot 发送方」(daemon 的 teamTrustUnionId),否则恶意成员把
|
|
1200
|
-
* 真人 union 报成 bot 就能让真人继承 bot 信任。
|
|
1201
|
-
* @param memberUnionId 发送方 union(teamMember 腿)——可为真人 union(未锁 bot)。
|
|
1202
|
-
* 仅授 chat 作用域内的 talk、不授 operate,且要求 union 在该团队的成员名单里
|
|
1203
|
-
* (memberUnionIds 来自平台鉴权的团队成员,非机器自报),故喂真人 union 是安全的。
|
|
1204
|
-
* @param chatType 当前会话类型。**仅 p2pOpen 腿读它**;省略时该腿不生效(fail-closed),
|
|
1205
|
-
* 所以拿不到 chatType 的调用点保持原语义、不会误放行。
|
|
1206
|
-
*/
|
|
1207
|
-
export function evaluateTalk(larkAppId, chatId, senderOpenId, senderUnionId, memberUnionId, chatType) {
|
|
1208
|
-
const bot = getBot(larkAppId);
|
|
1209
|
-
// allowedChatGroups 是"talk-open 的 chat_id 列表":当前消息来自其中之一即放行(仅 canTalk)。
|
|
1210
|
-
// 成员关系隐含在"能在该 chat 发言"里 —— 退群者发不了言自动失权,新人进群即生效,无需成员快照。
|
|
1211
|
-
const allowedUsers = bot.resolvedAllowedUsers;
|
|
1212
|
-
if (senderOpenId && allowedUsers.includes(senderOpenId))
|
|
1213
|
-
return { allowed: true, reason: 'allowedUser' };
|
|
1214
|
-
// Oncall 群命中:默认不限额;仅当 bot 配了 messageQuota.defaultLimit 时,
|
|
1215
|
-
// 才挂 chat:<chatId>:<openId> 这一 quotaKey(与 chatGrant 同键、同计数器,
|
|
1216
|
-
// 便于 owner 后续 /grant @x N 续杯/重置)。
|
|
1217
|
-
if (chatId && findOncallChat(larkAppId, chatId)) {
|
|
1218
|
-
const def = bot.config.messageQuota?.defaultLimit;
|
|
1219
|
-
if (typeof def === 'number' && Number.isInteger(def) && def > 0 && senderOpenId) {
|
|
1220
|
-
// 交集处理:同群若还持有显式 chatGrant,额度由授权决定而非 oncall default。
|
|
1221
|
-
// 三态:live 显式授权 → explicitGrantOverride(不兜 default);已过期 → expiredGrantCleanup
|
|
1222
|
-
//(透传给 consumeQuota,锁内以当前 expiry 为准原子清成员+quota+expiry 并回落 default);
|
|
1223
|
-
// 非成员 → 无覆盖,正常走 oncall default 懒初始化。
|
|
1224
|
-
const gk = chatQuotaKey(chatId, senderOpenId);
|
|
1225
|
-
const isMember = !!bot.config.chatGrants?.[chatId]?.includes(senderOpenId);
|
|
1226
|
-
const exp = isMember ? getGrantExpiresAt(larkAppId, gk) : undefined;
|
|
1227
|
-
if (isMember && exp !== undefined && Date.now() >= exp) {
|
|
1228
|
-
return {
|
|
1229
|
-
allowed: true, reason: 'oncall', quotaKey: gk,
|
|
1230
|
-
expiredGrantCleanup: { scope: 'chat', chatId, openId: senderOpenId },
|
|
1231
|
-
};
|
|
1232
|
-
}
|
|
1233
|
-
return { allowed: true, reason: 'oncall', quotaKey: gk, explicitGrantOverride: isMember };
|
|
1234
|
-
}
|
|
1235
|
-
return { allowed: true, reason: 'oncall' };
|
|
1236
|
-
}
|
|
1237
|
-
if (isKnownPeerBot(config.session.dataDir, larkAppId, senderOpenId))
|
|
1238
|
-
return { allowed: true, reason: 'peer' };
|
|
1239
|
-
// 跨部署团队 peer bot(旧版联邦学来的 union_id / 平台 roster 下发的 union_id)——
|
|
1240
|
-
// 与 isKnownPeerBot 兄弟 bot 对等的 talk 放行。没有这一腿,外部 bot 闸门
|
|
1241
|
-
//(isTrustedTeamBotSender)放进来的团队 bot 消息会在 enforceMessageQuotaForCliInput
|
|
1242
|
-
// 的 evaluateTalk 复查处被静默丢弃(受限 bot 上 #332 的端到端断点)。仅认租户
|
|
1243
|
-
// 稳定 union_id(bot 专属,人不会进这两张表),不看 chatId,不授 operate。
|
|
1244
|
-
if (senderUnionId && (isTeamBot(config.session.dataDir, senderUnionId) || isPlatformTeamBot(config.session.dataDir, senderUnionId))) {
|
|
1245
|
-
return { allowed: true, reason: 'teamBot' };
|
|
1246
|
-
}
|
|
1247
|
-
// 平台团队成员(人):发送者 union_id 是本群所属平台团队的成员 → talk 免 grant。
|
|
1248
|
-
// 严格 chat 作用域(isPlatformTeamMemberChat 要求成员与群在同一团队),只放 talk:
|
|
1249
|
-
// canOperate 不引这一腿,/restart 等仍限 allowedUsers。授权用户在团队群里 @ bot 即免卡。
|
|
1250
|
-
if (memberUnionId && isPlatformTeamMemberChat(config.session.dataDir, chatId, memberUnionId)) {
|
|
1251
|
-
return { allowed: true, reason: 'teamMember' };
|
|
1252
|
-
}
|
|
1253
|
-
if (hasAllowedChatGroup(larkAppId, chatId))
|
|
1254
|
-
return { allowed: true, reason: 'allowedChatGroup' };
|
|
1255
|
-
// p2pOpen:私聊维度的 talk-open,与 oncall(群维度)同一个安全模型——放行 canTalk,
|
|
1256
|
-
// canOperate 一行不读它(管理仍限 allowedUsers)。谁能私聊由飞书应用「可用范围」控制。
|
|
1257
|
-
// chatType 省略 → 该腿不生效(fail-closed),未接入 chatType 的调用点语义不变。
|
|
1258
|
-
if (chatType === 'p2p' && bot.config.p2pOpen === true)
|
|
1259
|
-
return { allowed: true, reason: 'p2pOpen' };
|
|
1260
|
-
// globalGrants 与 allowedChatGroups 同样确立"有白名单"语义:只配 globalGrants 也算限制态,
|
|
1261
|
-
// 不能 fall through 到"全开放"。用原始配置判定(见 hasConfiguredAllowlist):配了 owner
|
|
1262
|
-
// 但解析失败时也保持限制态, 不 fail-open。
|
|
1263
|
-
if (!hasConfiguredAllowlist(bot))
|
|
1264
|
-
return { allowed: true, reason: 'open' };
|
|
1265
|
-
if (hasChatGrant(larkAppId, chatId, senderOpenId)) {
|
|
1266
|
-
return { allowed: true, reason: 'chatGrant', quotaKey: chatQuotaKey(chatId, senderOpenId) };
|
|
1267
|
-
}
|
|
1268
|
-
// 全局对话授权(talk-only,人/bot 通用):命中即在任意群放行,与 chatGrants 同级、不授 operate。
|
|
1269
|
-
if (hasGlobalGrant(larkAppId, senderOpenId)) {
|
|
1270
|
-
return { allowed: true, reason: 'globalGrant', quotaKey: globalQuotaKey(senderOpenId) };
|
|
1271
|
-
}
|
|
1272
|
-
return { allowed: false, reason: 'none' };
|
|
1273
|
-
}
|
|
1274
|
-
/**
|
|
1275
|
-
* BOT 发送方的 talk 判定 —— bot 路由闸(外部 bot @ 本 bot)的**唯一**入口。
|
|
1276
|
-
*
|
|
1277
|
-
* = 人侧 evaluateTalk 的完整模型 + 一条 bot 专属腿。历史上 bot 侧手抄了一份
|
|
1278
|
-
* talk 源子集(oncall / peer / teamBot / chatGrant / globalGrant 的 OR 链),
|
|
1279
|
-
* 于是每加一条新 talk 源就漏一次、复发一次同类 bug:oncall 漏过一次、开放模式
|
|
1280
|
-
* 漏过一次、allowedChatGroups 又漏一次(owner 整群 `/grant` 后真人能说话、外部 bot
|
|
1281
|
-
* 一 @ 仍弹授权卡)。收敛成单一谓词后,**新增 talk 源只需改 evaluateTalk**;
|
|
1282
|
-
* test/bot-talk-parity.test.ts 按 TALK_REASONS 逐条盯着这条约束。
|
|
1283
|
-
*
|
|
1284
|
-
* 与人侧仅有的两条差异,都是刻意的,改动前先读:
|
|
1285
|
-
*
|
|
1286
|
-
* 1. `isTrustedTeamBotSender`(+,bot 才有):其中真正额外放行的是**团队拉群**那条腿
|
|
1287
|
-
* ——本群是团队拉群(团队掌控成员)→ 说话的 botmux bot 即视为背书队友,首次接触
|
|
1288
|
-
* 也放行,与 oncall 群豁免同构。chat 维度、不看 union,覆盖 sender 事件没带
|
|
1289
|
-
* `union_id` 的情况(此时 gate 前那次 `recordTeamBot` 被 `senderUnionId &&` 短路,
|
|
1290
|
-
* evaluateTalk 的 teamBot 腿必然落空)。**这条不能下沉进 evaluateTalk**:那是人/bot
|
|
1291
|
-
* 共用的,加进去等于团队群里任何真人都自动过 canTalk,绕开 teamMember 腿的成员校验
|
|
1292
|
-
* (isPlatformTeamMemberChat 要求 union 在该团队成员名单里)。它另外两条 union 锚定
|
|
1293
|
-
* 的腿与 evaluateTalk 的 teamBot 腿重合,留着是为了让「bot 团队信任」只有一处定义。
|
|
1294
|
-
*
|
|
1295
|
-
* 2. `p2pOpen`(−):不传 chatType → 该腿 fail-closed 不生效。飞书里 bot 之间不存在
|
|
1296
|
-
* 私聊,开着只是白扩边界。
|
|
1297
|
-
*
|
|
1298
|
-
* @param senderUnionId 必须是飞书盖章的 bot 发送方 union(`sender_type ∈ app|bot`),
|
|
1299
|
-
* 与 evaluateTalk 的 bot-trust 腿同一契约。真人 union 走 memberUnionId,本函数恒不传。
|
|
1300
|
-
*/
|
|
1301
|
-
export function evaluateBotTalk(larkAppId, chatId, senderOpenId, senderUnionId) {
|
|
1302
|
-
const ev = evaluateTalk(larkAppId, chatId, senderOpenId, senderUnionId);
|
|
1303
|
-
if (ev.allowed)
|
|
1304
|
-
return ev;
|
|
1305
|
-
return isTrustedTeamBotSender(config.session.dataDir, chatId, senderUnionId)
|
|
1306
|
-
? { allowed: true, reason: 'teamBot' }
|
|
1307
|
-
: ev;
|
|
1308
|
-
}
|
|
1309
|
-
/**
|
|
1310
|
-
* `botmux ask` 答复者是否可作答(= 该 chat 的 canTalk 门)——ask-broker 注入的
|
|
1311
|
-
* canTalkChecker 的**唯一生产实现**,daemon bootstrap 一行转调它。
|
|
1312
|
-
*
|
|
1313
|
-
* 抽成独立导出函数(而非把分派内联进 daemon setter 闭包)的意义:让**分派谓词本身**
|
|
1314
|
-
* 能被回归测试直接咬住——测试对本函数喂真实 team store 状态断言三组行为,改坏这里的
|
|
1315
|
-
* 分派逻辑(如退回旧 evaluateTalk / 不认 actor.botSender)会立刻红。注意测试只覆盖到
|
|
1316
|
-
* 本函数;daemon setter 的一行转调与 submitCustomReply 的 actor 构造仍靠人工核对
|
|
1317
|
-
* (setter 只有一行,不经测试机械覆盖)。
|
|
1318
|
-
*
|
|
1319
|
-
* - bot 发送方(actor.botSender)→ evaluateBotTalk(含团队拉群那条 chat 维度腿,
|
|
1320
|
-
* 覆盖 sender 事件没带 union_id 的场景),与 dispatcher 外层闸 / quota 复查同源。
|
|
1321
|
-
* - 人 / 无 actor(卡片点击路径)→ evaluateTalk 全模型:actor.senderUnionId 走
|
|
1322
|
-
* teamBot 腿(人路径恒 undefined)、actor.memberUnionId 走 teamMember 腿。
|
|
1323
|
-
* actor 省略时两者都是 undefined → 退化为纯 evaluateTalk(openId, chatType),
|
|
1324
|
-
* 与本次改动前的卡片点击语义完全一致。
|
|
1325
|
-
*/
|
|
1326
|
-
export function evaluateAskAnswerTalk(larkAppId, chatId, senderOpenId, chatType, actor) {
|
|
1327
|
-
return actor?.botSender
|
|
1328
|
-
? evaluateBotTalk(larkAppId, chatId, senderOpenId, actor.senderUnionId).allowed
|
|
1329
|
-
: evaluateTalk(larkAppId, chatId, senderOpenId, actor?.senderUnionId, actor?.memberUnionId, chatType).allowed;
|
|
1330
|
-
}
|
|
1331
|
-
export function canOperate(larkAppId, _chatId, senderOpenId, senderUnionId) {
|
|
1332
|
-
const bot = getBot(larkAppId);
|
|
1333
|
-
// 同部署 cross-ref / isKnownPeerBot 只证明「这是一个可路由的 bot 身份」,仅供
|
|
1334
|
-
// evaluateTalk 的 peer 腿使用,绝不能隐式升级为管理权限。需要让编排者执行
|
|
1335
|
-
// /repo /cd /restart 等命令时,必须命中下面显式支持 operate 的权限源。
|
|
1336
|
-
//
|
|
1337
|
-
// 跨部署「团队 peer bot」互信 operate(覆盖编排者给
|
|
1338
|
-
// 队友派 /repo /cd 等)。**只认租户稳定的 union_id**(isTeamBot / 平台 roster),
|
|
1339
|
-
// 不走 isTrustedTeamBotSender 的「团队群成员」分支——那条按 chat 放行是 sender
|
|
1340
|
-
// 无关的,会把「团队群里的真人」也误放进 operate,破坏 allowedUsers 边界。union_id
|
|
1341
|
-
// 是发送方专属、且必须先被团队背书(团队群学习 / 平台 roster)才进表,人不会命中。
|
|
1342
|
-
if (isTeamBot(config.session.dataDir, senderUnionId))
|
|
1343
|
-
return true;
|
|
1344
|
-
if (isPlatformTeamBot(config.session.dataDir, senderUnionId))
|
|
1345
|
-
return true;
|
|
1346
|
-
const allowedUsers = bot.resolvedAllowedUsers;
|
|
1347
|
-
// globalGrants(与 allowedChatGroups 同理)确立"有白名单"语义:只配 globalGrants 也算限制态,
|
|
1348
|
-
// 否则 canOperate 会 fall through 到"全开放",把 talk-only 授权变成 operate 全开——正是 PR #46
|
|
1349
|
-
// 要堵的洞。注意 globalGrants 只进 hasAllowlist 判定,operate 命中仍只认 allowedUsers。
|
|
1350
|
-
// 用原始配置判定(hasConfiguredAllowlist):配了 owner 但解析为空时 fail-closed, 不 fail-open。
|
|
1351
|
-
if (!hasConfiguredAllowlist(bot))
|
|
1352
|
-
return true;
|
|
1353
|
-
return !!senderOpenId && allowedUsers.includes(senderOpenId);
|
|
1354
|
-
}
|
|
1355
|
-
/**
|
|
1356
|
-
* Daemon 命令统一闸:canOperate 恒放行;此外,bot 配置的 `canTalkDaemonCommands`
|
|
1357
|
-
* 名单内的命令降到 canTalk 判定(oncall / allowedChatGroup / grant / p2pOpen 等
|
|
1358
|
-
* 对话放行腿命中即可)。名单外或未配置 → 与 canOperate 完全等价(现状不变)。
|
|
1359
|
-
*
|
|
1360
|
-
* 只作用于 daemon.ts 两条路由的 DAEMON_COMMANDS 统一闸;在统一闸之前特判的命令
|
|
1361
|
-
* (/vc-auth /term)与 handler 内部自带 owner 闸的命令(/card /insight)
|
|
1362
|
-
* 不受影响——内部闸仍是最终权威(fail-closed)。
|
|
1363
|
-
*
|
|
1364
|
-
* chatType 省略时 p2pOpen 腿不生效(fail-closed),与 canTalk 语义一致——
|
|
1365
|
-
* 私聊路径的调用点必须把 chatType 传进来。
|
|
1366
|
-
*
|
|
1367
|
-
* botSender:降权到 talk 判定这一段,必须与 dispatcher 外层闸 / quota 复查用**同一个**
|
|
1368
|
-
* 谓词。bot 发送方走 evaluateBotTalk(含团队拉群那条 chat 维度腿,覆盖 sender 事件没带
|
|
1369
|
-
* union_id 的情况);否则「团队拉群里外部 bot 能 talk 却执行不了降权到 canTalk 的命令
|
|
1370
|
-
* (如 /status)」——单一 talk 谓词在这道 daemon 命令闸继续分叉。不传(人的路径)→
|
|
1371
|
-
* 原样走 canTalk / evaluateTalk,语义不变。canOperate 那段人/bot 通用,不受影响。
|
|
1372
|
-
*
|
|
1373
|
-
* `/repo` 另有一个更窄的同部署 sibling bot 例外:仅当飞书事件把发送方盖章为 bot,
|
|
1374
|
-
* receiver cross-ref 命中 sender open_id,且 sender union_id 精确匹配当前仍配置的唯一
|
|
1375
|
-
* 本机 sibling app 已学习的自身 union_id 时放行;不把 sibling 提升为 canOperate,也不把其他 daemon 命令降权。
|
|
1376
|
-
*/
|
|
1377
|
-
export function canRunDaemonCommand(larkAppId, chatId, senderOpenId, senderUnionId, cmd, memberUnionId, chatType, botSender, larkStampedBotSender) {
|
|
1378
|
-
if (canOperate(larkAppId, chatId, senderOpenId, senderUnionId))
|
|
1379
|
-
return true;
|
|
1380
|
-
if (cmd === '/repo' && larkStampedBotSender === true
|
|
1381
|
-
&& isVerifiedLocalSiblingBot(config.session.dataDir, larkAppId, senderOpenId, senderUnionId)) {
|
|
1382
|
-
return true;
|
|
1383
|
-
}
|
|
1384
|
-
const list = getBot(larkAppId).config.canTalkDaemonCommands;
|
|
1385
|
-
if (!list?.includes(cmd))
|
|
1386
|
-
return false;
|
|
1387
|
-
return botSender
|
|
1388
|
-
? evaluateBotTalk(larkAppId, chatId, senderOpenId, senderUnionId).allowed
|
|
1389
|
-
: canTalk(larkAppId, chatId, senderOpenId, senderUnionId, memberUnionId, chatType);
|
|
1390
|
-
}
|
|
1391
|
-
/**
|
|
1392
|
-
* 入口 A:无权限者 @bot 时弹授权申请卡(正文 @owner,由 owner 处置)。
|
|
1393
|
-
* 受 grant-pending 节流:pending 中 / deny 冷却期内静默不发。开放模式(无 owner)兜底不发。
|
|
1394
|
-
*/
|
|
1395
|
-
async function maybeSendGrantRequestCard(larkAppId, message, chatId, requesterOpenId, messageData) {
|
|
1396
|
-
if (getBot(larkAppId).config.autoGrantRequestCards === false)
|
|
1397
|
-
return;
|
|
1398
|
-
const owner = getOwnerOpenId(larkAppId);
|
|
1399
|
-
if (!owner || !requesterOpenId)
|
|
1400
|
-
return;
|
|
1401
|
-
if (isThrottled(larkAppId, chatId, requesterOpenId))
|
|
1402
|
-
return;
|
|
1403
|
-
// 名字优先级:本消息 mentions(真人发送方、被 @ 目标都在此)→ observed-bots 花名册
|
|
1404
|
-
// (/introduce 登记过的 (open_id,name))→ 裸 open_id 兜底。外部 bot 发送方不在自己
|
|
1405
|
-
// 消息的 mentions 里(那是 @ 目标),只靠 mentions 会让 owner 只看到 open_id。
|
|
1406
|
-
const mentionName = (message?.mentions ?? []).find((m) => mentionOpenId(m) === requesterOpenId)?.name;
|
|
1407
|
-
const observedName = mentionName
|
|
1408
|
-
? undefined
|
|
1409
|
-
: listObservedBots(config.session.dataDir, larkAppId, chatId).find(b => b.openId === requesterOpenId)?.name;
|
|
1410
|
-
const profileName = mentionName || observedName
|
|
1411
|
-
? undefined
|
|
1412
|
-
: (await getUserProfile(larkAppId, requesterOpenId).catch(() => null))?.name;
|
|
1413
|
-
const shortRequester = `${requesterOpenId.slice(0, 10)}…${requesterOpenId.slice(-4)}`;
|
|
1414
|
-
const name = mentionName ?? observedName ?? profileName ?? shortRequester;
|
|
1415
|
-
// 把原始消息事件挂在 pending 上:授权成功后可重放,用户无需再 @ 一遍。
|
|
1416
|
-
const quota = getBot(larkAppId).config.messageQuota?.defaultLimit ?? DEFAULT_GRANT_QUOTA;
|
|
1417
|
-
const nonce = openPending(larkAppId, chatId, requesterOpenId, quota, messageData, DEFAULT_GRANT_DURATION_MS);
|
|
1418
|
-
const card = buildGrantCard({
|
|
1419
|
-
ownerOpenId: owner,
|
|
1420
|
-
targets: [{ openId: requesterOpenId, name: String(name) }],
|
|
1421
|
-
chatId,
|
|
1422
|
-
nonce,
|
|
1423
|
-
mode: 'request',
|
|
1424
|
-
quota,
|
|
1425
|
-
durationMs: DEFAULT_GRANT_DURATION_MS,
|
|
1426
|
-
}, localeForBot(larkAppId));
|
|
1427
|
-
await replyMessage(larkAppId, message.message_id, card, 'interactive')
|
|
1428
|
-
.catch(err => {
|
|
1429
|
-
// 发卡失败必须撤掉刚开的 pending,否则该发送方被节流压死、owner 永远看不到卡片,
|
|
1430
|
-
// 只能等 daemon 重启或别的 target 触发全表 prune 才恢复。清掉后下次 @ 会重试发卡。
|
|
1431
|
-
clearPending(larkAppId, chatId, requesterOpenId);
|
|
1432
|
-
logger.debug(`grant request card send failed: ${err}`);
|
|
1433
|
-
});
|
|
1434
|
-
}
|
|
1435
|
-
// ─── Group message access check ──────────────────────────────────────────
|
|
1436
|
-
/**
|
|
1437
|
-
* Check group message addressing:
|
|
1438
|
-
* - 'allowed' -> sender is allowed, bot was @mentioned or solo group
|
|
1439
|
-
* - 'not_allowed' -> bot was @mentioned but sender is not in allowlist
|
|
1440
|
-
* - 'ignore' -> not addressed to bot at all
|
|
1441
|
-
*/
|
|
1442
|
-
export async function checkGroupMessageAccess(larkAppId, message, chatId, senderOpenId, memberUnionId) {
|
|
1443
|
-
const mentioned = isBotMentioned(larkAppId, message, senderOpenId);
|
|
1444
|
-
// 群消息访问检查只在人路径调用,union 走 memberUnionId 腿(不进 bot-trust)。
|
|
1445
|
-
const isAllowed = canTalk(larkAppId, chatId, senderOpenId, undefined, memberUnionId);
|
|
1446
|
-
logger.debug(`Check group message access: mentioned=${mentioned}, isAllowed=${isAllowed}`);
|
|
1447
|
-
if (mentioned) {
|
|
1448
|
-
return isAllowed ? 'allowed' : 'not_allowed';
|
|
1449
|
-
}
|
|
1450
|
-
// No @mention — only allow if sender is the sole human in the group
|
|
1451
|
-
// AND this is the only bot in the chat. With multiple bots, require @mention
|
|
1452
|
-
// to disambiguate.
|
|
1453
|
-
//
|
|
1454
|
-
// 若消息 @ 了别的具体成员(mentionsAnotherMember),群必然不是 1人1bot——
|
|
1455
|
-
// 只有群成员能被 @,多出的那个 @ 本身就是人数变化的证据。上游可能还抱着
|
|
1456
|
-
// 陈旧缓存 {1,1}(刚拉了新 bot 的 TTL 窗口),这会直接跳过人数查询落到
|
|
1457
|
-
// 'ignore',挡住「用户 @ 新 bot、老 bot 跟着回复」。群聊 @ 策略 never/ambient
|
|
1458
|
-
// 在调用方(relax 条款)已先行结算,这里不受影响。
|
|
1459
|
-
if (isAllowed && !mentionsAnotherMember(larkAppId, message)) {
|
|
1460
|
-
const { userCount, botCount } = await getGroupStats(larkAppId, chatId);
|
|
1461
|
-
logger.debug(`Group user count: ${userCount}, bot count: ${botCount}`);
|
|
1462
|
-
if (userCount <= 1 && botCount <= 1) {
|
|
1463
|
-
return 'allowed';
|
|
1464
|
-
}
|
|
1465
|
-
}
|
|
1466
|
-
return 'ignore';
|
|
1467
|
-
}
|
|
1468
|
-
function listenerRoutingContext(input) {
|
|
1469
|
-
return {
|
|
1470
|
-
data: input.data,
|
|
1471
|
-
ctx: {
|
|
1472
|
-
chatId: input.chatId,
|
|
1473
|
-
messageId: input.messageId,
|
|
1474
|
-
chatType: input.chatType,
|
|
1475
|
-
larkAppId: input.larkAppId,
|
|
1476
|
-
scope: 'thread',
|
|
1477
|
-
anchor: input.messageId,
|
|
1478
|
-
messageListener: input.match,
|
|
1479
|
-
},
|
|
1480
|
-
ownsSession: false,
|
|
1481
|
-
};
|
|
1482
|
-
}
|
|
1483
|
-
const MESSAGE_LISTENER_POLL_INTERVAL_MS = Math.max(5_000, Number(process.env.BOTMUX_MESSAGE_LISTENER_POLL_INTERVAL_MS) || 30_000);
|
|
1484
|
-
const MESSAGE_LISTENER_BACKFILL_WINDOW_MS = Math.max(60_000, Number(process.env.BOTMUX_MESSAGE_LISTENER_BACKFILL_WINDOW_MS) || 30 * 60_000);
|
|
1485
|
-
const MESSAGE_LISTENER_BACKFILL_SCAN_LIMIT = Math.max(1, Number(process.env.BOTMUX_MESSAGE_LISTENER_BACKFILL_SCAN_LIMIT) || 100);
|
|
1486
|
-
const MESSAGE_LISTENER_BACKFILL_PAGE_SIZE = Math.min(50, Math.max(1, Number(process.env.BOTMUX_MESSAGE_LISTENER_BACKFILL_PAGE_SIZE) || 50));
|
|
1487
|
-
function enabledMessageListenerChatIds(bot) {
|
|
1488
|
-
return Object.entries(bot.config.messageListeners ?? {})
|
|
1489
|
-
.filter(([, listener]) => listener?.enabled === true && !!listener.prompt?.trim())
|
|
1490
|
-
.map(([chatId]) => chatId);
|
|
1491
|
-
}
|
|
1492
|
-
function messageCreateTimeMs(message) {
|
|
1493
|
-
const raw = message?.create_time ?? message?.createTime;
|
|
1494
|
-
const value = Number(raw);
|
|
1495
|
-
return Number.isFinite(value) ? value : undefined;
|
|
1496
|
-
}
|
|
1497
|
-
function historyMessageSender(message) {
|
|
1498
|
-
const sender = message?.sender ?? {};
|
|
1499
|
-
// A bot sender is reported by app_id (cli_) in `sender.id`, but with
|
|
1500
|
-
// `with_sender_name=true` (which listChatMessagesUntil always sets) Lark also
|
|
1501
|
-
// returns `sender.open_bot_id` — the bot's per-app open_id, IDENTICAL to what
|
|
1502
|
-
// /members/bots reports and to what the dashboard bot-picker stores. Prefer it
|
|
1503
|
-
// so a third-party bot resolves to the same ou_ the include/exclude lists use
|
|
1504
|
-
// (otherwise it stays an unresolvable cli_ and never matches an open_id list).
|
|
1505
|
-
const senderId = sender.open_bot_id ?? sender.id ?? sender.open_id ?? sender.user_id ?? sender.app_id
|
|
1506
|
-
?? message?.sender_id?.open_id ?? message?.sender_id?.user_id ?? message?.sender_id?.app_id;
|
|
1507
|
-
const rawIdType = sender.id_type ?? sender.sender_id_type;
|
|
1508
|
-
// open_bot_id is an open_id even though the row's id_type still says app_id.
|
|
1509
|
-
const senderIdType = sender.open_bot_id ? 'open_id' : rawIdType;
|
|
1510
|
-
const inferredType = sender.sender_type
|
|
1511
|
-
?? message?.sender_type
|
|
1512
|
-
?? (rawIdType === 'app_id' ? 'app' : undefined);
|
|
1513
|
-
return {
|
|
1514
|
-
senderOpenId: typeof senderId === 'string' ? senderId : undefined,
|
|
1515
|
-
senderTypeRaw: typeof inferredType === 'string' ? inferredType : undefined,
|
|
1516
|
-
senderIdType: typeof senderIdType === 'string' ? senderIdType : undefined,
|
|
1517
|
-
};
|
|
1518
|
-
}
|
|
1519
|
-
function larkReceiveEventFromHistoryMessage(message, chatId) {
|
|
1520
|
-
const { senderOpenId, senderTypeRaw, senderIdType } = historyMessageSender(message);
|
|
1521
|
-
// sender_type and the ID DOMAIN are independent axes. A bot sender keeps
|
|
1522
|
-
// sender_type='app', but when we resolved its identity to an open_id (via
|
|
1523
|
-
// sender.open_bot_id, senderIdType==='open_id'), the value MUST go in the
|
|
1524
|
-
// open_id slot — the whole downstream chain (message-parser senderId,
|
|
1525
|
-
// handleNewTopic owner/quote target, --mention-back) reads sender_id.open_id
|
|
1526
|
-
// ONLY. Putting an ou_ into { app_id } both mislabels the field and drops the
|
|
1527
|
-
// identity (senderId becomes ''). Choose the key by domain, not by type.
|
|
1528
|
-
const isBotSenderType = senderIdType === 'app_id' || senderTypeRaw === 'app' || senderTypeRaw === 'bot';
|
|
1529
|
-
const isOpenIdDomain = senderIdType === 'open_id'
|
|
1530
|
-
|| (typeof senderOpenId === 'string' && senderOpenId.startsWith('ou_'));
|
|
1531
|
-
return {
|
|
1532
|
-
message: {
|
|
1533
|
-
...message,
|
|
1534
|
-
message_type: message?.message_type ?? message?.msg_type,
|
|
1535
|
-
chat_id: message?.chat_id ?? chatId,
|
|
1536
|
-
chat_type: message?.chat_type ?? 'group',
|
|
1537
|
-
},
|
|
1538
|
-
sender: {
|
|
1539
|
-
// Preserve the bot sender_type (talk/quota gates and foreign-bot owner
|
|
1540
|
-
// suppression key off it) even when the id itself is an open_id.
|
|
1541
|
-
sender_type: senderTypeRaw ?? (isBotSenderType ? 'app' : 'user'),
|
|
1542
|
-
sender_id: isOpenIdDomain
|
|
1543
|
-
? { open_id: senderOpenId }
|
|
1544
|
-
: isBotSenderType
|
|
1545
|
-
? { app_id: senderOpenId }
|
|
1546
|
-
: { open_id: senderOpenId },
|
|
1547
|
-
},
|
|
1548
|
-
};
|
|
1549
|
-
}
|
|
1550
|
-
async function dispatchHumanMessageViaHandlers(larkAppId, handlers, payload) {
|
|
1551
|
-
await serializeByAnchor(payload.ctx.anchor, () => {
|
|
1552
|
-
const ownsSession = handlers.isSessionOwner?.(payload.ctx.anchor, larkAppId) ?? payload.ownsSession;
|
|
1553
|
-
return ownsSession
|
|
1554
|
-
? handlers.handleThreadReply(payload.data, payload.ctx)
|
|
1555
|
-
: handlers.handleNewTopic(payload.data, payload.ctx);
|
|
1556
|
-
});
|
|
1557
|
-
}
|
|
1558
|
-
async function dispatchPolledMessageListenerMatch(input) {
|
|
1559
|
-
if (!claimMessageOnce(input.larkAppId, input.messageId)) {
|
|
1560
|
-
logger.debug(`[message-listener:${input.larkAppId}] polled duplicate ignored msg=${input.messageId.substring(0, 12)}`);
|
|
1561
|
-
return;
|
|
1562
|
-
}
|
|
1563
|
-
logger.info(`[message-listener:${input.larkAppId}] matched polled chat=${input.chatId.substring(0, 12)} ` +
|
|
1564
|
-
`msg=${input.messageId.substring(0, 12)} sender=${input.match.senderOpenId?.substring(0, 12) ?? '-'}`);
|
|
1565
|
-
await dispatchHumanMessageViaHandlers(input.larkAppId, input.handlers, listenerRoutingContext({
|
|
1566
|
-
data: input.data,
|
|
1567
|
-
match: input.match,
|
|
1568
|
-
chatId: input.chatId,
|
|
1569
|
-
messageId: input.messageId,
|
|
1570
|
-
chatType: 'group',
|
|
1571
|
-
larkAppId: input.larkAppId,
|
|
1572
|
-
}));
|
|
1573
|
-
}
|
|
1574
|
-
async function pollMessageListenersOnce(larkAppId, handlers, now = Date.now()) {
|
|
1575
|
-
const bot = getBot(larkAppId);
|
|
1576
|
-
const chatIds = enabledMessageListenerChatIds(bot);
|
|
1577
|
-
if (chatIds.length === 0)
|
|
1578
|
-
return;
|
|
1579
|
-
const cutoff = now - MESSAGE_LISTENER_BACKFILL_WINDOW_MS;
|
|
1580
|
-
await ensureBotOpenId(larkAppId).catch(() => { });
|
|
1581
|
-
for (const chatId of chatIds) {
|
|
1582
|
-
let messages;
|
|
1583
|
-
try {
|
|
1584
|
-
messages = await listChatMessagesUntil(larkAppId, chatId, {
|
|
1585
|
-
pageSize: MESSAGE_LISTENER_BACKFILL_PAGE_SIZE,
|
|
1586
|
-
stopAfter: (message, seenCount) => {
|
|
1587
|
-
const createdAt = messageCreateTimeMs(message);
|
|
1588
|
-
return seenCount >= MESSAGE_LISTENER_BACKFILL_SCAN_LIMIT ||
|
|
1589
|
-
(Number.isFinite(createdAt) && createdAt < cutoff);
|
|
1590
|
-
},
|
|
1591
|
-
});
|
|
1592
|
-
}
|
|
1593
|
-
catch (err) {
|
|
1594
|
-
logger.warn(`[message-listener:${larkAppId}] failed to poll chat=${chatId.substring(0, 12)}: ${err instanceof Error ? err.message : String(err)}`);
|
|
1595
|
-
continue;
|
|
1596
|
-
}
|
|
1597
|
-
// Build the app_id→open_id map once per chat (shared with the dashboard
|
|
1598
|
-
// preview leg) so bot senders (reported by app_id in history) match sender
|
|
1599
|
-
// filters keyed on open_id, and unprovable bots fail closed on exclusion.
|
|
1600
|
-
const candidateBotAppIds = collectListenerBotAppIds(messages, historyMessageSender);
|
|
1601
|
-
const appIdToOpenId = await buildListenerBotAppIdToOpenId(larkAppId, chatId, candidateBotAppIds);
|
|
1602
|
-
for (const message of messages) {
|
|
1603
|
-
const messageId = String(message?.message_id ?? '');
|
|
1604
|
-
if (!messageId)
|
|
1605
|
-
continue;
|
|
1606
|
-
const createdAt = messageCreateTimeMs(message);
|
|
1607
|
-
if (Number.isFinite(createdAt) && createdAt < cutoff)
|
|
1608
|
-
continue;
|
|
1609
|
-
const data = larkReceiveEventFromHistoryMessage(message, chatId);
|
|
1610
|
-
const rawSender = historyMessageSender(message);
|
|
1611
|
-
const resolved = resolveListenerSenderIdentity(rawSender, appIdToOpenId);
|
|
1612
|
-
const match = evaluateMessageListener({
|
|
1613
|
-
bot,
|
|
1614
|
-
chatId,
|
|
1615
|
-
message: data.message,
|
|
1616
|
-
senderOpenId: resolved.senderOpenId,
|
|
1617
|
-
senderTypeRaw: rawSender.senderTypeRaw,
|
|
1618
|
-
senderIdentityUnverified: resolved.identityUnverified,
|
|
1619
|
-
explicitlyMentionedThisBot: isBotMentioned(larkAppId, data.message, resolved.senderOpenId),
|
|
1620
|
-
});
|
|
1621
|
-
if (!match)
|
|
1622
|
-
continue;
|
|
1623
|
-
await dispatchPolledMessageListenerMatch({
|
|
1624
|
-
larkAppId,
|
|
1625
|
-
handlers,
|
|
1626
|
-
data,
|
|
1627
|
-
match,
|
|
1628
|
-
chatId,
|
|
1629
|
-
messageId,
|
|
1630
|
-
}).catch(err => logger.error(`Error handling polled message listener event: ${err}`));
|
|
1631
|
-
}
|
|
1632
|
-
}
|
|
1633
|
-
}
|
|
1634
|
-
export async function __pollMessageListenersOnceForTest(larkAppId, handlers, now = Date.now()) {
|
|
1635
|
-
await pollMessageListenersOnce(larkAppId, handlers, now);
|
|
1636
|
-
}
|
|
1637
|
-
function usesForwardFollowupDelay(mentionMode) {
|
|
1638
|
-
return mentionMode === 'never' || mentionMode === 'ambient';
|
|
1639
|
-
}
|
|
1640
|
-
/**
|
|
1641
|
-
* Per-app barriers that resolve once `restoreActiveSessions()` completes.
|
|
1642
|
-
*
|
|
1643
|
-
* Persisted forward-followup seeds are loaded into the in-memory buffer at
|
|
1644
|
-
* dispatcher startup (so root-linked clarifications can still pair with them
|
|
1645
|
-
* while the WS is already receiving events), but any flush — timer expiry or
|
|
1646
|
-
* immediate dispatch — waits for this barrier. Without it, `isSessionOwner`
|
|
1647
|
-
* would always return false before sessions are rehydrated, routing thread
|
|
1648
|
-
* replies through `handleNewTopic` and potentially duplicating sessions.
|
|
1649
|
-
*/
|
|
1650
|
-
const sessionsReadyBarriers = new Map();
|
|
1651
|
-
const sessionsReadyApps = new Set();
|
|
1652
|
-
/** Mark a bot's active sessions as restored so pending forward-followup seeds can flush. */
|
|
1653
|
-
export function markForwardFollowupsSessionsReady(larkAppId) {
|
|
1654
|
-
sessionsReadyApps.add(larkAppId);
|
|
1655
|
-
const barrier = sessionsReadyBarriers.get(larkAppId);
|
|
1656
|
-
if (barrier)
|
|
1657
|
-
barrier.resolve();
|
|
1658
|
-
}
|
|
1659
|
-
/**
|
|
1660
|
-
* Best-effort plain-text extraction from a Lark message for routing-level
|
|
1661
|
-
* decisions (currently: `/t` / `/topic` detection). Handles the two common
|
|
1662
|
-
* shapes — `text` (`{"text": "..."}`) and `post` (zh_cn/en_us nested
|
|
1663
|
-
* paragraphs of `text` / `at` nodes). Other types (image, file, sticker,
|
|
1664
|
-
* interactive, …) return null so the caller falls through to the default
|
|
1665
|
-
* routing path.
|
|
1666
|
-
*
|
|
1667
|
-
* Kept deliberately tiny rather than reusing parseEventMessage: the dispatcher
|
|
1668
|
-
* runs on every inbound event and we only need a quick text peek before the
|
|
1669
|
-
* permission gates / scope override; full parseEventMessage still runs once
|
|
1670
|
-
* inside the chosen handler.
|
|
1671
|
-
*/
|
|
1672
|
-
export function extractMessageTextForRouting(message) {
|
|
1673
|
-
if (!message?.content)
|
|
1674
|
-
return null;
|
|
1675
|
-
try {
|
|
1676
|
-
const obj = JSON.parse(message.content);
|
|
1677
|
-
// text shape: {"text":"..."}. Lark stuffs placeholder keys like "@_user_1"
|
|
1678
|
-
// into obj.text; the human name only lives in message.mentions[].name. We
|
|
1679
|
-
// must resolve keys → @${name} so stripLeadingMentions can strip them
|
|
1680
|
-
// before parseForceTopicInvocation sees the content. Mirrors the
|
|
1681
|
-
// resolveMentions logic in parseEventMessage.
|
|
1682
|
-
if (typeof obj?.text === 'string') {
|
|
1683
|
-
let text = obj.text;
|
|
1684
|
-
const mentions = message?.mentions;
|
|
1685
|
-
if (Array.isArray(mentions)) {
|
|
1686
|
-
for (const m of mentions) {
|
|
1687
|
-
if (m?.key && m?.name) {
|
|
1688
|
-
text = text.split(m.key).join(`@${m.name}`);
|
|
1689
|
-
}
|
|
1690
|
-
}
|
|
1691
|
-
}
|
|
1692
|
-
return text;
|
|
1693
|
-
}
|
|
1694
|
-
// post shape: {"zh_cn":{"content":[[{tag:"text",text:"..."},{tag:"at",...}]]}}
|
|
1695
|
-
// Post messages keep @mentions as separate `at` nodes (not embedded in
|
|
1696
|
-
// text), so the joined text-node content is already clean of placeholders.
|
|
1697
|
-
const inner = obj?.zh_cn ?? obj?.en_us ?? obj;
|
|
1698
|
-
if (Array.isArray(inner?.content)) {
|
|
1699
|
-
const parts = [];
|
|
1700
|
-
for (const para of inner.content) {
|
|
1701
|
-
if (!Array.isArray(para))
|
|
1702
|
-
continue;
|
|
1703
|
-
for (const node of para) {
|
|
1704
|
-
if (node?.tag === 'text' && typeof node.text === 'string') {
|
|
1705
|
-
parts.push(node.text);
|
|
1706
|
-
}
|
|
1707
|
-
}
|
|
1708
|
-
}
|
|
1709
|
-
return parts.length > 0 ? parts.join('') : null;
|
|
1710
|
-
}
|
|
1711
|
-
}
|
|
1712
|
-
catch { /* malformed content — skip */ }
|
|
1713
|
-
return null;
|
|
1714
|
-
}
|
|
1715
|
-
/**
|
|
1716
|
-
* If the inbound message starts with `/t` / `/topic` AND the routing
|
|
1717
|
-
* currently lands on chat-scope, override to thread-scope anchored at
|
|
1718
|
-
* the inbound message_id. This makes "force topic mode" work even when
|
|
1719
|
-
* the bot already owns a chat-scope session in the chat — the dispatcher
|
|
1720
|
-
* routes to handleNewTopic at a fresh anchor instead of falling into
|
|
1721
|
-
* handleThreadReply on the chat-scope owner.
|
|
1722
|
-
*
|
|
1723
|
-
* Already-thread messages (real Lark 话题, p2p, 话题群) are left alone:
|
|
1724
|
-
* the prefix is still stripped downstream by handleNewTopic.
|
|
1725
|
-
*/
|
|
1726
|
-
export function maybeApplyForceTopicOverride(routing, message, messageId) {
|
|
1727
|
-
if (routing.scope !== 'chat')
|
|
1728
|
-
return false;
|
|
1729
|
-
const rawText = extractMessageTextForRouting(message);
|
|
1730
|
-
if (!rawText)
|
|
1731
|
-
return false;
|
|
1732
|
-
const stripped = stripLeadingMentions(rawText.trim(), message?.mentions ?? []);
|
|
1733
|
-
if (!parseForceTopicInvocation(stripped))
|
|
1734
|
-
return false;
|
|
1735
|
-
routing.scope = 'thread';
|
|
1736
|
-
routing.anchor = messageId;
|
|
1737
|
-
return true;
|
|
1738
|
-
}
|
|
1739
|
-
async function maybeApplySharedTopicSeed(input) {
|
|
1740
|
-
const { larkAppId, chatId, chatType, message, senderOpenId, messageId, routing, forceTopicApplied, } = input;
|
|
1741
|
-
if (forceTopicApplied)
|
|
1742
|
-
return undefined;
|
|
1743
|
-
// This helper only seeds a shared reply topic. A message with both fields is
|
|
1744
|
-
// already a reply inside a native thread; folding it would divert an owned
|
|
1745
|
-
// thread session back into the group lobby and split one topic's context.
|
|
1746
|
-
if (message?.root_id && message?.thread_id)
|
|
1747
|
-
return undefined;
|
|
1748
|
-
if (chatType !== 'group')
|
|
1749
|
-
return undefined;
|
|
1750
|
-
if (resolveRegularGroupMode(larkAppId, chatId) !== 'shared')
|
|
1751
|
-
return undefined;
|
|
1752
|
-
// Seeding a shared topic normally needs an @mention. But the 'never' and
|
|
1753
|
-
// 'ambient' mention policies answer non-@ messages too — and in shared mode it
|
|
1754
|
-
// must still OPEN a topic (reply in a thread reusing the chat session), not
|
|
1755
|
-
// fall back to a flat top-level reply. So allow non-@ seeding under 'never'
|
|
1756
|
-
// (unconditional) or 'ambient' — but for 'ambient' NOT when the message
|
|
1757
|
-
// @mentions another specific member (person/bot) without @ing us: that is a
|
|
1758
|
-
// redirect to someone else, so we back off (mentionsAnotherMember).
|
|
1759
|
-
const seedMentionMode = resolveGroupMentionMode(larkAppId);
|
|
1760
|
-
if (!isBotMentioned(larkAppId, message, senderOpenId)
|
|
1761
|
-
&& !(seedMentionMode === 'never'
|
|
1762
|
-
|| (seedMentionMode === 'ambient' && !mentionsAnotherMember(larkAppId, message))))
|
|
1763
|
-
return undefined;
|
|
1764
|
-
const freshMode = routing.scope === 'thread'
|
|
1765
|
-
? await getChatMode(larkAppId, chatId, { forceRefresh: true })
|
|
1766
|
-
: (getCachedChatMode(larkAppId, chatId) ?? 'group');
|
|
1767
|
-
if (freshMode !== 'group')
|
|
1768
|
-
return undefined;
|
|
1769
|
-
routing.scope = 'chat';
|
|
1770
|
-
routing.anchor = chatId;
|
|
1771
|
-
logger.info(`[reply-mode] shared turn msg=${messageId.substring(0, 12)} routes through chat=${chatId.substring(0, 12)}`);
|
|
1772
|
-
return messageId;
|
|
1773
|
-
}
|
|
1774
|
-
async function maybeFoldMentionedRegularGroupThreadToChat(input) {
|
|
1775
|
-
const { larkAppId, chatId, chatType, message, routing, forceTopicApplied, mentionedThisBot, ownsThreadSession } = input;
|
|
1776
|
-
if (forceTopicApplied || ownsThreadSession)
|
|
1777
|
-
return undefined;
|
|
1778
|
-
if (!mentionedThisBot)
|
|
1779
|
-
return undefined;
|
|
1780
|
-
if (chatType !== 'group')
|
|
1781
|
-
return undefined;
|
|
1782
|
-
const rootId = message?.root_id;
|
|
1783
|
-
const threadId = message?.thread_id;
|
|
1784
|
-
if (!rootId || !threadId)
|
|
1785
|
-
return undefined;
|
|
1786
|
-
// A genuine native Lark topic is an explicit user-created context boundary,
|
|
1787
|
-
// even when this bot first enters on a later reply rather than on the seed.
|
|
1788
|
-
// In `chat-topic` mode that boundary is honored — don't fold it into the group
|
|
1789
|
-
// lobby. chat / shared are documented to fold native topics into the group
|
|
1790
|
-
// session, so they must fall through to the regular-group fold below.
|
|
1791
|
-
// Synthetic/shared reply aliases do not use an omt_* thread id and always
|
|
1792
|
-
// continue through the fold below regardless of mode.
|
|
1793
|
-
if (threadId.startsWith('omt_') && resolveRegularGroupMode(larkAppId, chatId) === 'chat-topic')
|
|
1794
|
-
return undefined;
|
|
1795
|
-
const rawText = extractMessageTextForRouting(message);
|
|
1796
|
-
if (rawText) {
|
|
1797
|
-
const stripped = stripLeadingMentions(rawText.trim(), message?.mentions ?? []);
|
|
1798
|
-
if (parseForceTopicInvocation(stripped))
|
|
1799
|
-
return undefined;
|
|
1800
|
-
}
|
|
1801
|
-
// In a regular group, `chat` and `shared` both mean "use the group's one
|
|
1802
|
-
// chat-scope session/context". Lark still reports replies inside an existing
|
|
1803
|
-
// topic as root_id+thread_id, so decideRouting's generic real-thread rule
|
|
1804
|
-
// would otherwise fork a brand-new thread-scope session every time another
|
|
1805
|
-
// human/bot @mentions us inside that topic. Keep the visible reply in the
|
|
1806
|
-
// same topic (replyRootId=rootId), but route the turn through the group
|
|
1807
|
-
// chat-scope session. `new-topic` and `chat-topic` are the modes that
|
|
1808
|
-
// intentionally keep per-topic independent sessions — they must NOT fold:
|
|
1809
|
-
// new-topic forks every top-level @ too, while chat-topic keeps top level
|
|
1810
|
-
// flat but lets each native Lark topic run its own session.
|
|
1811
|
-
const mode = resolveRegularGroupMode(larkAppId, chatId);
|
|
1812
|
-
if (mode === 'new-topic' || mode === 'chat-topic')
|
|
1813
|
-
return undefined;
|
|
1814
|
-
const freshMode = await getChatMode(larkAppId, chatId, { forceRefresh: true });
|
|
1815
|
-
if (freshMode !== 'group')
|
|
1816
|
-
return undefined;
|
|
1817
|
-
routing.scope = 'chat';
|
|
1818
|
-
routing.anchor = chatId;
|
|
1819
|
-
logger.info(`[reply-mode] mentioned thread root=${rootId.substring(0, 12)} folds into chat=${chatId.substring(0, 12)}`);
|
|
1820
|
-
return rootId;
|
|
1821
|
-
}
|
|
1822
|
-
function regularGroupRouting(larkAppId, messageId, chatId) {
|
|
1823
|
-
// Only `new-topic` forks a fresh thread-scope session for a TOP-LEVEL @.
|
|
1824
|
-
// `shared` stays chat-scope here (the topic fold happens post-routing, see
|
|
1825
|
-
// maybeApplySharedTopicSeed); `chat` is flat top-level; `chat-topic` (the
|
|
1826
|
-
// default) is also flat at top level (it only diverges for native topics,
|
|
1827
|
-
// where the fold is skipped — see maybeFoldMentionedRegularGroupThreadToChat). resolveRegularGroupMode
|
|
1828
|
-
// is the single decision point so the modes never both fire.
|
|
1829
|
-
if (resolveRegularGroupMode(larkAppId, chatId) === 'new-topic') {
|
|
1830
|
-
return { scope: 'thread', anchor: messageId, source: 'regular-group-thread' };
|
|
1831
|
-
}
|
|
1832
|
-
return { scope: 'chat', anchor: chatId, source: 'regular-group-chat' };
|
|
1833
|
-
}
|
|
1834
|
-
async function decideRoutingWithSource(larkAppId, message) {
|
|
1835
|
-
const rootId = message.root_id;
|
|
1836
|
-
const threadId = message.thread_id;
|
|
1837
|
-
const chatType = message.chat_type ?? 'group';
|
|
1838
|
-
const messageId = message.message_id;
|
|
1839
|
-
const chatId = message.chat_id;
|
|
1840
|
-
// 私聊 chat 模式(默认):整段 DM 一律折进同一个扁平 chat-scope 会话。必须先于
|
|
1841
|
-
// 下面的 real-thread(root_id+thread_id)分支判断 —— 否则用户在 DM 里"回复某条
|
|
1842
|
-
// 消息"形成的 thread 形态消息会被提前分流到 thread-scope,破坏"连续单聊会话"
|
|
1843
|
-
// 语义(典型触发:thread→chat 模式切换后回复旧 thread,或 Lark 给 DM 回复塞了
|
|
1844
|
-
// thread_id)。p2pMode 默认 'chat';只有显式 'thread' 才回到每条 DM 独立话题的
|
|
1845
|
-
// 旧行为。群聊不受影响。
|
|
1846
|
-
if (chatType === 'p2p' && getBot(larkAppId)?.config?.p2pMode !== 'thread') {
|
|
1847
|
-
return { scope: 'chat', anchor: chatId, source: 'p2p' };
|
|
1848
|
-
}
|
|
1849
|
-
if (rootId && threadId)
|
|
1850
|
-
return { scope: 'thread', anchor: rootId, source: 'real-thread' };
|
|
1851
|
-
// 私聊 thread 模式(显式 opt-out):每条 top-level DM 都视为新话题 — 跟话题群
|
|
1852
|
-
// 同款,匹配 Lark DM 的话题化行为,把 1:1 对话按消息拆成独立 CLI 进程。
|
|
1853
|
-
if (chatType === 'p2p') {
|
|
1854
|
-
return { scope: 'thread', anchor: messageId, source: 'p2p' };
|
|
1855
|
-
}
|
|
1856
|
-
// Group chat — fetch chat_mode (cached) to disambiguate 话题群 from 普通群.
|
|
1857
|
-
const mode = await getChatMode(larkAppId, chatId);
|
|
1858
|
-
if (mode === 'topic') {
|
|
1859
|
-
return { scope: 'thread', anchor: messageId, source: 'topic-chat' };
|
|
1860
|
-
}
|
|
1861
|
-
// A native topic root in a regular group carries thread_id=omt_* but no
|
|
1862
|
-
// root_id. In `chat-topic` mode (顶层平铺连续会话;群内原生话题各自独立会话)
|
|
1863
|
-
// this seed must start its own thread-scope session instead of folding into
|
|
1864
|
-
// the group lobby — otherwise the topic's opening message lands in the shared
|
|
1865
|
-
// chat session and only later replies (which carry root_id and hit the
|
|
1866
|
-
// real-thread branch above) isolate, breaking chat-topic's own contract.
|
|
1867
|
-
//
|
|
1868
|
-
// Gated on `chat-topic` ONLY, by design (遵循 /reply-mode 配置):
|
|
1869
|
-
// • chat / shared — documented to fold native topics into the group session
|
|
1870
|
-
// (see /reply-mode help); must NOT isolate here.
|
|
1871
|
-
// • new-topic — regularGroupRouting already returns thread-scope anchored
|
|
1872
|
-
// at messageId for top-level messages, with the correct
|
|
1873
|
-
// source=regular-group-thread; letting it fall through keeps
|
|
1874
|
-
// that source (and its downstream summary/forward semantics).
|
|
1875
|
-
// Keep this after the topic-chat check so 话题群 seeds retain source=topic-chat
|
|
1876
|
-
// (and therefore autoStartOnNewTopic semantics).
|
|
1877
|
-
if (threadId?.startsWith('omt_') && resolveRegularGroupMode(larkAppId, chatId) === 'chat-topic') {
|
|
1878
|
-
return { scope: 'thread', anchor: messageId, source: 'real-thread' };
|
|
1879
|
-
}
|
|
1880
|
-
return regularGroupRouting(larkAppId, messageId, chatId);
|
|
1881
|
-
}
|
|
1882
|
-
export async function decideRouting(larkAppId, message) {
|
|
1883
|
-
const { scope, anchor } = await decideRoutingWithSource(larkAppId, message);
|
|
1884
|
-
return { scope, anchor };
|
|
1885
|
-
}
|
|
1886
|
-
async function classifySummaryChatKind(input) {
|
|
1887
|
-
if (input.routingSource === 'topic-chat')
|
|
1888
|
-
return 'topic';
|
|
1889
|
-
if (input.routingSource === 'regular-group-chat' || input.routingSource === 'regular-group-thread')
|
|
1890
|
-
return 'regularGroup';
|
|
1891
|
-
// Real thread replies can occur in topic groups and in regular groups that
|
|
1892
|
-
// use threaded replies. Ask Lark for the current chat mode only for explicit
|
|
1893
|
-
// /summary so normal routing does not pay this extra lookup.
|
|
1894
|
-
if (input.routingSource === 'real-thread') {
|
|
1895
|
-
const mode = await getChatMode(input.larkAppId, input.chatId, { forceRefresh: true });
|
|
1896
|
-
return mode === 'topic' ? 'topic' : 'regularGroup';
|
|
1897
|
-
}
|
|
1898
|
-
return undefined;
|
|
1899
|
-
}
|
|
1900
|
-
const SUMMARY_COMMAND_RE = /^\/summary(?:\s|$)/i;
|
|
1901
|
-
function summaryCommandText(message) {
|
|
1902
|
-
const text = extractMessageTextForRouting(message);
|
|
1903
|
-
if (!text)
|
|
1904
|
-
return undefined;
|
|
1905
|
-
const stripped = stripLeadingMentions(text.trim(), message?.mentions ?? []).trim();
|
|
1906
|
-
return SUMMARY_COMMAND_RE.test(stripped) ? stripped : undefined;
|
|
1907
|
-
}
|
|
1908
|
-
async function resolveSummaryCommandMatch(input) {
|
|
1909
|
-
if (input.chatType !== 'group')
|
|
1910
|
-
return undefined;
|
|
1911
|
-
if (!isBotMentioned(input.larkAppId, input.message, input.senderOpenId))
|
|
1912
|
-
return undefined;
|
|
1913
|
-
const triggerText = summaryCommandText(input.message);
|
|
1914
|
-
if (!triggerText)
|
|
1915
|
-
return undefined;
|
|
1916
|
-
const chatKind = await classifySummaryChatKind(input);
|
|
1917
|
-
if (!chatKind)
|
|
1918
|
-
return undefined;
|
|
1919
|
-
const botConfig = getBot(input.larkAppId).config;
|
|
1920
|
-
return {
|
|
1921
|
-
chatKind,
|
|
1922
|
-
triggerText,
|
|
1923
|
-
range: summaryRangeFromBotConfig(botConfig),
|
|
1924
|
-
prompt: DEFAULT_SUMMARY_PROMPT,
|
|
1925
|
-
summaryMemory: botConfig.summaryMemory === true,
|
|
1926
|
-
summaryMemoryPath: typeof botConfig.summaryMemoryPath === 'string' && botConfig.summaryMemoryPath.trim()
|
|
1927
|
-
? botConfig.summaryMemoryPath.trim()
|
|
1928
|
-
: 'summary.md',
|
|
1929
|
-
};
|
|
1930
|
-
}
|
|
1931
|
-
/** 从评论事件 payload 里挖出 { fileToken, fileType, commentId, replyId,
|
|
1932
|
-
* noticeType, isMentioned, operatorOpenId }。
|
|
1933
|
-
*
|
|
1934
|
-
* 真机实测 drive.notice.comment_add_v1 的 event 体形如
|
|
1935
|
-
* `{ comment_id, is_mentioned, notice_meta, reply_id }` —— **file_token 不在顶层,
|
|
1936
|
-
* 藏在 notice_meta 里**(notice_meta 可能是对象或 JSON 字符串)。故这里展开
|
|
1937
|
-
* notice_meta 并多路径兜底;file_type 拿不到无妨(后续用订阅表里的)。 */
|
|
1938
|
-
function parseCommentEvent(data) {
|
|
1939
|
-
const d = data?.event ?? data ?? {};
|
|
1940
|
-
let meta = d.notice_meta ?? d.noticeMeta;
|
|
1941
|
-
if (typeof meta === 'string') {
|
|
1942
|
-
try {
|
|
1943
|
-
meta = JSON.parse(meta);
|
|
1944
|
-
}
|
|
1945
|
-
catch { /* 保留原字符串 */ }
|
|
1946
|
-
}
|
|
1947
|
-
const m = (meta && typeof meta === 'object') ? meta : {};
|
|
1948
|
-
const pick = (k) => d[k] ?? m[k] ?? m[k.replace(/_([a-z])/g, (_, c) => c.toUpperCase())];
|
|
1949
|
-
return {
|
|
1950
|
-
fileToken: pick('file_token') ?? pick('token') ?? pick('obj_token'),
|
|
1951
|
-
fileType: pick('file_type') ?? pick('obj_type'),
|
|
1952
|
-
commentId: pick('comment_id'),
|
|
1953
|
-
replyId: pick('reply_id'),
|
|
1954
|
-
noticeType: pick('notice_type'),
|
|
1955
|
-
isMentioned: d.is_mentioned === true || m.is_mentioned === true,
|
|
1956
|
-
operatorOpenId: d.operator_id?.open_id ?? d.user_id?.open_id ?? m.operator_id?.open_id,
|
|
1957
|
-
meta,
|
|
1958
|
-
};
|
|
1959
|
-
}
|
|
1960
|
-
/** 评论事件入口:去重 ACK-safe 包装 + 订阅匹配 + 自触发/触发范围过滤后转 daemon。 */
|
|
1961
|
-
function handleCommentEventAckSafe(data, larkAppId, handlers) {
|
|
1962
|
-
const parsed = parseCommentEvent(data);
|
|
1963
|
-
const eventKey = `drive.comment_add:${larkAppId}:${eventIdForKey(data) ?? `${parsed.fileToken ?? '?'}:${parsed.replyId ?? parsed.commentId ?? '?'}`}`;
|
|
1964
|
-
scheduleAckSafeEvent(eventKey, async () => {
|
|
1965
|
-
try {
|
|
1966
|
-
await processCommentEvent(parsed, larkAppId, handlers);
|
|
1967
|
-
}
|
|
1968
|
-
catch (err) {
|
|
1969
|
-
logger.error(`Error handling doc-comment event: ${err}`);
|
|
1970
|
-
}
|
|
1971
|
-
}, 'doc-comment event');
|
|
1972
|
-
}
|
|
1973
|
-
function handleVcMeetingPushEventAckSafe(data, larkAppId, handlers, kind, eventType) {
|
|
1974
|
-
const parsed = parseVcMeetingPushEvent({ data, larkAppId, kind, eventType });
|
|
1975
|
-
const eventKey = `${eventType}:${larkAppId}:${parsed.eventId ?? unkeyableEventKey()}`;
|
|
1976
|
-
scheduleAckSafeEvent(eventKey, async () => {
|
|
1977
|
-
if (!handlers.handleVcMeetingPush) {
|
|
1978
|
-
logger.info(`[vc-agent] ${eventType} ignored: daemon has no VC meeting handler`);
|
|
1979
|
-
return;
|
|
1980
|
-
}
|
|
1981
|
-
await handlers.handleVcMeetingPush(parsed);
|
|
1982
|
-
}, `vc-meeting ${kind} event`);
|
|
1983
|
-
}
|
|
1984
|
-
async function processCommentEvent(parsed, larkAppId, handlers) {
|
|
1985
|
-
if (!handlers.handleDocComment)
|
|
1986
|
-
return;
|
|
1987
|
-
const { fileToken, commentId } = parsed;
|
|
1988
|
-
if (!fileToken || !commentId) {
|
|
1989
|
-
logger.info(`[doc-comment] event dropped: missing fileToken/commentId (fileToken=${fileToken ?? '?'} commentId=${commentId ?? '?'}) — payload 字段路径可能与解析不符`);
|
|
1990
|
-
return;
|
|
1991
|
-
}
|
|
1992
|
-
// 1) 查订阅表;未订阅的文档 @bot 时自动创建 mention-only 订阅(任何人都可以
|
|
1993
|
-
// 通过在文档里 @bot 触发 bot 回复,不需要 owner 预先订阅。/watch-comment 命令
|
|
1994
|
-
// 管理持久订阅才需要 owner 权限)。
|
|
1995
|
-
// 注意:auto-sub 先创建占位,但如果后续审计硬门失败会回滚(非 owner 触发
|
|
1996
|
-
// 且通知 owner 失败时不允许留下订阅记录)。
|
|
1997
|
-
let sub = getDocSubscription(config.session.dataDir, larkAppId, fileToken);
|
|
1998
|
-
let autoCreatedSub = false;
|
|
1999
|
-
if (!sub) {
|
|
2000
|
-
const operatorOpenId = parsed.operatorOpenId;
|
|
2001
|
-
const botCfg = getBot(larkAppId).config;
|
|
2002
|
-
const mappedDir = botCfg.docRepoMap?.[fileToken];
|
|
2003
|
-
const autoSub = {
|
|
2004
|
-
fileToken,
|
|
2005
|
-
fileType: parsed.fileType || 'docx',
|
|
2006
|
-
sessionAnchor: `doc:${fileToken}`,
|
|
2007
|
-
sessionId: undefined,
|
|
2008
|
-
scope: 'chat',
|
|
2009
|
-
chatId: `doc:${fileToken}`,
|
|
2010
|
-
commentTriggerMode: 'mention-only',
|
|
2011
|
-
managedBy: 'watch-comment',
|
|
2012
|
-
ownerOpenId: operatorOpenId || getOwnerOpenId(larkAppId),
|
|
2013
|
-
workingDir: mappedDir,
|
|
2014
|
-
createdAt: Date.now(),
|
|
2015
|
-
};
|
|
2016
|
-
putDocSubscription(config.session.dataDir, larkAppId, autoSub);
|
|
2017
|
-
sub = autoSub;
|
|
2018
|
-
autoCreatedSub = true;
|
|
2019
|
-
logger.info(`[doc-comment] auto-subscribed file=${fileToken.slice(0, 12)} by @mention (mention-only${mappedDir ? `, wd=${mappedDir}` : ''}, anchor=doc:${fileToken.slice(0, 12)}, requester=${operatorOpenId?.slice(0, 12) || '?'})`);
|
|
2020
|
-
}
|
|
2021
|
-
// 关掉 open_id 启动竞态:probeBotOpenId 在启动时 fire-and-forget,若评论事件
|
|
2022
|
-
// 在该窗口内到达,下面 mention-only 闸 / 自触发过滤会拿到 undefined 的 botOpenId
|
|
2023
|
-
// → 合法的 @bot 评论被误丢(事件已被 ACK,飞书不会重投,@ 永久丢失)。await
|
|
2024
|
-
// 去重后的探针把 open_id 补齐;探针失败则降级(心跳会重试)。
|
|
2025
|
-
await ensureBotOpenId(larkAppId).catch(() => { });
|
|
2026
|
-
// 2) 拉评论 thread 取权威正文 / 作者 / @ 列表(事件 payload 不保证带全),
|
|
2027
|
-
// 同时用最新一条回复作为"触发回复"。
|
|
2028
|
-
const comment = await getDocComment(larkAppId, { fileToken, fileType: sub.fileType }, commentId);
|
|
2029
|
-
if (!comment || comment.replies.length === 0) {
|
|
2030
|
-
logger.info(`[doc-comment] event dropped: 取不到评论内容 comment=${commentId.slice(0, 12)}(replies=${comment ? comment.replies.length : 'null'})`);
|
|
2031
|
-
return;
|
|
2032
|
-
}
|
|
2033
|
-
const trigger = parsed.replyId
|
|
2034
|
-
? comment.replies.find(r => r.replyId === parsed.replyId) ?? comment.replies[comment.replies.length - 1]
|
|
2035
|
-
: comment.replies[comment.replies.length - 1];
|
|
2036
|
-
const triggerIndex = Math.max(0, comment.replies.indexOf(trigger));
|
|
2037
|
-
// 3) 自触发过滤(防死循环):bot 的回复可能以应用身份(作者=bot open_id)或回退
|
|
2038
|
-
// 用户身份(作者=授权用户,无法靠作者区分)发出。三重保险:①作者==本 bot
|
|
2039
|
-
// ②reply_id 在 bot 创建集合 ③文本含隐形哨兵。任一命中即跳过。
|
|
2040
|
-
const selfBotOpenId = getBot(larkAppId).botOpenId;
|
|
2041
|
-
if ((selfBotOpenId && trigger.userId === selfBotOpenId) || isBotAuthoredReply(trigger.replyId) || hasBotSentinel(trigger.text))
|
|
2042
|
-
return;
|
|
2043
|
-
// 4) 触发范围闸(mention-only 仅当评论真的 @ 了本 bot 才触发)。
|
|
2044
|
-
// ⚠️ 必须以拉到的评论正文 @person(open_id) 列表为准,不能信事件自带的
|
|
2045
|
-
// `is_mentioned`——它表示「评论里存在任意 @」,@ 别人时也是 true,曾导致
|
|
2046
|
-
// 「@ 同事的评论也被误触发」。详见 commentTriggerAllowed 注释。
|
|
2047
|
-
if (!commentTriggerAllowed(sub.commentTriggerMode, trigger.mentions, selfBotOpenId)) {
|
|
2048
|
-
logger.info(`[doc-comment] event dropped: mention-only 但未 @ 本 bot (comment=${commentId.slice(0, 12)} isMentioned=${parsed.isMentioned} mentions=${trigger.mentions.length} self=${selfBotOpenId ? selfBotOpenId.slice(0, 10) : '?'})`);
|
|
2049
|
-
return;
|
|
2050
|
-
}
|
|
2051
|
-
const text = trigger.text.trim();
|
|
2052
|
-
if (!text)
|
|
2053
|
-
return;
|
|
2054
|
-
// 审计硬门:非 owner @bot 触发时,必须成功通知 owner 才允许回复。
|
|
2055
|
-
// 通知失败 = owner 无法感知 = 越权,直接拒绝响应并回滚 auto-sub。
|
|
2056
|
-
// (owner 自己触发的不通知,直接放行。)
|
|
2057
|
-
const ownerOpenId = getOwnerOpenId(larkAppId);
|
|
2058
|
-
const requesterOpenId = parsed.operatorOpenId;
|
|
2059
|
-
const isOwnerTrigger = ownerOpenId && requesterOpenId && requesterOpenId === ownerOpenId;
|
|
2060
|
-
if (!isOwnerTrigger) {
|
|
2061
|
-
const rollbackAutoSub = () => { if (autoCreatedSub)
|
|
2062
|
-
removeDocSubscription(config.session.dataDir, larkAppId, fileToken); };
|
|
2063
|
-
if (!ownerOpenId) {
|
|
2064
|
-
logger.warn(`[doc-comment] non-owner @mention but no ownerOpenId configured — rejecting (audit gate) file=${fileToken.slice(0, 12)} requester=${requesterOpenId?.slice(0, 12) || '?'}`);
|
|
2065
|
-
rollbackAutoSub();
|
|
2066
|
-
return;
|
|
2067
|
-
}
|
|
2068
|
-
try {
|
|
2069
|
-
const loc = localeForBot(larkAppId);
|
|
2070
|
-
const requesterName = requesterOpenId?.slice(0, 12) || '?';
|
|
2071
|
-
const notifyText = [
|
|
2072
|
-
t('daemon.doc_mention_notify_title', undefined, loc),
|
|
2073
|
-
'',
|
|
2074
|
-
t('daemon.doc_mention_notify_body', { requester: requesterName, token: fileToken.slice(0, 12) }, loc),
|
|
2075
|
-
'',
|
|
2076
|
-
`📄 \`${fileToken}\``,
|
|
2077
|
-
`💬 ${text.slice(0, 200)}${text.length > 200 ? '…' : ''}`,
|
|
2078
|
-
].join('\n');
|
|
2079
|
-
await sendUserMessage(larkAppId, ownerOpenId, notifyText);
|
|
2080
|
-
}
|
|
2081
|
-
catch (e) {
|
|
2082
|
-
logger.warn(`[doc-comment] non-owner @mention but owner notification failed — rejecting (audit gate) file=${fileToken.slice(0, 12)} requester=${requesterOpenId?.slice(0, 12) || '?'} err=${e instanceof Error ? e.message : String(e)}`);
|
|
2083
|
-
rollbackAutoSub();
|
|
2084
|
-
return;
|
|
2085
|
-
}
|
|
2086
|
-
}
|
|
2087
|
-
logger.info(`[doc-comment] dispatch file=${fileToken.slice(0, 12)} comment=${commentId.slice(0, 12)} mode=${sub.commentTriggerMode} → session anchor=${sub.sessionAnchor.slice(0, 12)}`);
|
|
2088
|
-
await handlers.handleDocComment({
|
|
2089
|
-
larkAppId,
|
|
2090
|
-
sub,
|
|
2091
|
-
commentId,
|
|
2092
|
-
replyId: trigger.replyId || commentId,
|
|
2093
|
-
text,
|
|
2094
|
-
selectedText: comment.quote,
|
|
2095
|
-
priorReplies: comment.replies.slice(0, triggerIndex).map(reply => ({
|
|
2096
|
-
authorOpenId: reply.userId,
|
|
2097
|
-
text: reply.text.replaceAll(BOT_REPLY_SENTINEL, '').trim(),
|
|
2098
|
-
})).filter(reply => reply.text.length > 0),
|
|
2099
|
-
isWhole: comment.isWhole,
|
|
2100
|
-
authorOpenId: trigger.userId,
|
|
2101
|
-
});
|
|
2102
|
-
}
|
|
2103
|
-
const LARK_WS_PROXY_ENV_KEYS = [
|
|
2104
|
-
'npm_config_https_proxy',
|
|
2105
|
-
'NPM_CONFIG_HTTPS_PROXY',
|
|
2106
|
-
'https_proxy',
|
|
2107
|
-
'HTTPS_PROXY',
|
|
2108
|
-
'npm_config_proxy',
|
|
2109
|
-
'NPM_CONFIG_PROXY',
|
|
2110
|
-
'all_proxy',
|
|
2111
|
-
'ALL_PROXY',
|
|
2112
|
-
];
|
|
2113
|
-
function createLarkWsAgent() {
|
|
2114
|
-
const hasSecureProxy = LARK_WS_PROXY_ENV_KEYS.some(key => process.env[key]?.trim());
|
|
2115
|
-
if (!hasSecureProxy)
|
|
2116
|
-
return undefined;
|
|
2117
|
-
const agent = new ProxyAgent();
|
|
2118
|
-
const resolveEnvProxy = agent.getProxyForUrl;
|
|
2119
|
-
agent.getProxyForUrl = (url, req) => {
|
|
2120
|
-
const target = new URL(url);
|
|
2121
|
-
if (target.protocol === 'wss:')
|
|
2122
|
-
target.protocol = 'https:';
|
|
2123
|
-
else if (target.protocol === 'ws:')
|
|
2124
|
-
target.protocol = 'http:';
|
|
2125
|
-
return resolveEnvProxy(target.href, req);
|
|
2126
|
-
};
|
|
2127
|
-
return agent;
|
|
2128
|
-
}
|
|
2129
|
-
/**
|
|
2130
|
-
* Create and start the Lark WSClient with event dispatching.
|
|
2131
|
-
* Returns the WSClient instance for lifecycle management.
|
|
2132
|
-
*/
|
|
2133
|
-
export function startLarkEventDispatcher(larkAppId, larkAppSecret, handlers, brand = 'feishu') {
|
|
2134
|
-
const forwardFollowups = new ForwardFollowupBuffer(config.daemon.forwardFollowupWaitMs, err => logger.error(`Error flushing delayed topic seed: ${err}`));
|
|
2135
|
-
// Barrier that resolves once restoreActiveSessions() completes. Flushes wait
|
|
2136
|
-
// on it so isSessionOwner reads the populated activeSessions map. If the app
|
|
2137
|
-
// was already marked ready (e.g. tests or a restart within the same process),
|
|
2138
|
-
// resolve immediately.
|
|
2139
|
-
let resolveSessionsReady;
|
|
2140
|
-
const sessionsReady = new Promise(resolve => { resolveSessionsReady = resolve; });
|
|
2141
|
-
if (sessionsReadyApps.has(larkAppId))
|
|
2142
|
-
resolveSessionsReady();
|
|
2143
|
-
sessionsReadyBarriers.set(larkAppId, { promise: sessionsReady, resolve: resolveSessionsReady });
|
|
2144
|
-
const dispatchHumanMessage = async (payload) => {
|
|
2145
|
-
await dispatchHumanMessageViaHandlers(larkAppId, handlers, payload);
|
|
2146
|
-
};
|
|
2147
|
-
const dispatchPersistedForwardFollowup = async (seedMessageId, payload) => {
|
|
2148
|
-
// Wait for activeSessions to be rehydrated before checking ownership, so a
|
|
2149
|
-
// thread reply isn't misrouted to handleNewTopic during daemon startup.
|
|
2150
|
-
await sessionsReady;
|
|
2151
|
-
await dispatchHumanMessage(payload);
|
|
2152
|
-
removeForwardFollowup(larkAppId, seedMessageId);
|
|
2153
|
-
};
|
|
2154
|
-
// Load persisted seeds into the buffer immediately so root-linked
|
|
2155
|
-
// clarifications can pair with them while the WS is already receiving
|
|
2156
|
-
// events. Flushes (timer expiry or immediate) wait on sessionsReady above.
|
|
2157
|
-
for (const record of listForwardFollowups(larkAppId)) {
|
|
2158
|
-
const senderOpenId = record.payload?.data?.sender?.sender_id?.open_id;
|
|
2159
|
-
const chatId = record.payload?.ctx?.chatId;
|
|
2160
|
-
if (!senderOpenId || !chatId || !record.payload?.ctx?.anchor) {
|
|
2161
|
-
removeForwardFollowup(larkAppId, record.messageId);
|
|
2162
|
-
continue;
|
|
2163
|
-
}
|
|
2164
|
-
const flush = (payload) => dispatchPersistedForwardFollowup(record.messageId, payload);
|
|
2165
|
-
const remainingMs = record.dueAt - Date.now();
|
|
2166
|
-
const isUnpairedSeed = !record.payload.ctx.forwardSeedData;
|
|
2167
|
-
const delayStillEnabled = usesForwardFollowupDelay(resolveGroupMentionMode(larkAppId));
|
|
2168
|
-
if (isUnpairedSeed && delayStillEnabled && remainingMs > 0 && forwardFollowups.hold({
|
|
2169
|
-
larkAppId,
|
|
2170
|
-
chatId,
|
|
2171
|
-
senderOpenId,
|
|
2172
|
-
messageId: record.messageId,
|
|
2173
|
-
payload: record.payload,
|
|
2174
|
-
flush,
|
|
2175
|
-
}, remainingMs)) {
|
|
2176
|
-
logger.info(`[forward-followup] restored pending seed=${record.messageId.substring(0, 12)} remaining=${remainingMs}ms`);
|
|
2177
|
-
}
|
|
2178
|
-
else {
|
|
2179
|
-
void flush(record.payload).catch(err => logger.error(`Error restoring delayed topic seed: ${err}`));
|
|
2180
|
-
}
|
|
2181
|
-
}
|
|
2182
|
-
const seedRoutingGates = new Map();
|
|
2183
|
-
const registerSeedRoutingGate = (messageId) => {
|
|
2184
|
-
let resolveReady;
|
|
2185
|
-
const ready = new Promise(resolve => { resolveReady = resolve; });
|
|
2186
|
-
let completed = false;
|
|
2187
|
-
const gate = {
|
|
2188
|
-
ready,
|
|
2189
|
-
complete: () => {
|
|
2190
|
-
if (completed)
|
|
2191
|
-
return;
|
|
2192
|
-
completed = true;
|
|
2193
|
-
resolveReady();
|
|
2194
|
-
setTimeout(() => {
|
|
2195
|
-
if (seedRoutingGates.get(messageId) === gate)
|
|
2196
|
-
seedRoutingGates.delete(messageId);
|
|
2197
|
-
}, config.daemon.forwardFollowupWaitMs);
|
|
2198
|
-
},
|
|
2199
|
-
};
|
|
2200
|
-
seedRoutingGates.set(messageId, gate);
|
|
2201
|
-
return gate;
|
|
2202
|
-
};
|
|
2203
|
-
async function processMessageEvent(data, seedRoutingGate) {
|
|
2204
|
-
try {
|
|
2205
|
-
const message = data.message;
|
|
2206
|
-
const sender = data.sender;
|
|
2207
|
-
if (!message)
|
|
2208
|
-
return;
|
|
2209
|
-
// Close the open_id startup race: probeBotOpenId is fire-and-forget at
|
|
2210
|
-
// startup, so an @ arriving in that window would hit isBotMentioned with
|
|
2211
|
-
// an undefined botOpenId and be silently dropped (the WSClient still ACKs
|
|
2212
|
-
// it, so Lark never redelivers → the @ is lost). Await the deduped probe
|
|
2213
|
-
// so the @ is recognized. Best-effort: on probe failure we degrade to the
|
|
2214
|
-
// prior behavior (the periodic heartbeat retries the probe).
|
|
2215
|
-
await ensureBotOpenId(larkAppId).catch(() => { });
|
|
2216
|
-
// Learn other bots' open_ids from @mentions in this event.
|
|
2217
|
-
// Lark open_id is per-app: these IDs are correct for our app context.
|
|
2218
|
-
if (message.mentions?.length > 0) {
|
|
2219
|
-
updateBotOpenIdCrossRef(config.session.dataDir, larkAppId, message.mentions);
|
|
2220
|
-
// Learn our OWN union_id from any @ of ourselves: Lark stamps every
|
|
2221
|
-
// mention with the target's union_id, and mention-driven delivery
|
|
2222
|
-
// works even where the self-message echo never arrives(无 receive-all
|
|
2223
|
-
// scope 的应用收不到自己发的消息;bot-only 大厅实测完全不推事件)。
|
|
2224
|
-
if (recordBotUnionIdFromMentions(config.session.dataDir, larkAppId, getBot(larkAppId).botOpenId, message.mentions)) {
|
|
2225
|
-
logger.info(`[${larkAppId}] learned own bot union_id from @mention`);
|
|
2226
|
-
}
|
|
2227
|
-
}
|
|
2228
|
-
const chatId = message.chat_id;
|
|
2229
|
-
const chatType = (message.chat_type === 'p2p' ? 'p2p' : 'group');
|
|
2230
|
-
const messageId = message.message_id;
|
|
2231
|
-
// Bot-originated messages — bots historically only post inside threads
|
|
2232
|
-
// (their own thread replies). With chat-scope sessions a bot can also
|
|
2233
|
-
// post top-level (its first reply in a chat-scope group), so we still
|
|
2234
|
-
// route them through `decideRouting` rather than gating on root_id.
|
|
2235
|
-
//
|
|
2236
|
-
// 飞书在跨 bot 卡片消息场景实测会把发送方标成 sender_type='bot'(不是
|
|
2237
|
-
// 文档里写的 'app'),所以这里两个值都接受,否则那条路径会落到下面的
|
|
2238
|
-
// user-message 通用分支,绕开 /close self-message 特判、foreign-bot
|
|
2239
|
-
// chat-scope gate(isKnownPeerBot)和"Bot-to-bot @mention detected"
|
|
2240
|
-
// 日志。
|
|
2241
|
-
const senderType = sender?.sender_type;
|
|
2242
|
-
const isBotSenderType = senderType === 'app' || senderType === 'bot';
|
|
2243
|
-
if (isBotSenderType) {
|
|
2244
|
-
const senderOpenId = sender.sender_id?.open_id ?? sender.sender_id?.app_id;
|
|
2245
|
-
// When Feishu gave us only an app_id (no open_id), this bot sender's
|
|
2246
|
-
// identity is not in the open_id domain the listener filters use, so
|
|
2247
|
-
// the matcher must fail closed on open_id-based exclusion. Realtime
|
|
2248
|
-
// events normally carry open_id; the app_id fallback is the rare case.
|
|
2249
|
-
const senderIdentityUnverified = !sender.sender_id?.open_id && !!sender.sender_id?.app_id;
|
|
2250
|
-
const isSelfMessage = senderOpenId === getBot(larkAppId).botOpenId;
|
|
2251
|
-
// Self messages: learn our OWN union_id from the echo first (the only
|
|
2252
|
-
// reliable source — see bot-union-ids-store; reported to the platform
|
|
2253
|
-
// on heartbeat for the team roster), then only echoed `/close` matters.
|
|
2254
|
-
if (isSelfMessage) {
|
|
2255
|
-
const selfUnionId = sender.sender_id?.union_id;
|
|
2256
|
-
if (selfUnionId && recordBotUnionId(config.session.dataDir, larkAppId, selfUnionId)) {
|
|
2257
|
-
logger.info(`[${larkAppId}] learned own bot union_id from self-message echo`);
|
|
2258
|
-
}
|
|
2259
|
-
try {
|
|
2260
|
-
const body = JSON.parse(message.content ?? '{}');
|
|
2261
|
-
if (body.text?.trim() !== '/close')
|
|
2262
|
-
return;
|
|
2263
|
-
}
|
|
2264
|
-
catch {
|
|
2265
|
-
return;
|
|
2266
|
-
}
|
|
2267
|
-
const ctx = await decideRouting(larkAppId, message);
|
|
2268
|
-
// Serialize per anchor so back-to-back messages to the same thread
|
|
2269
|
-
// (e.g. dispatch's /repo prime + brief kickoff) don't interleave with
|
|
2270
|
-
// the first's async session-spawn. See anchor-serializer.ts.
|
|
2271
|
-
await serializeByAnchor(ctx.anchor, () => handlers.handleThreadReply(data, { ...ctx, chatId, messageId, chatType, larkAppId }))
|
|
2272
|
-
.catch(err => logger.error(`Error handling message event: ${err}`));
|
|
2273
|
-
return;
|
|
2274
|
-
}
|
|
2275
|
-
// Learn teammate identity from team-assembled groups (the trust root):
|
|
2276
|
-
// any bot talking in a 拉群 group is a vouched teammate, so capture its
|
|
2277
|
-
// tenant-stable union_id — we then honour it as a teammate in ANY chat
|
|
2278
|
-
// (see team-bots-store). Done BEFORE the @mention gate so even a non-@
|
|
2279
|
-
// message in a team group teaches us the teammate. Cheap + idempotent.
|
|
2280
|
-
const senderUnionId = sender.sender_id?.union_id;
|
|
2281
|
-
if (senderUnionId && isTeamGroupChat(config.session.dataDir, chatId)) {
|
|
2282
|
-
recordTeamBot(config.session.dataDir, { unionId: senderUnionId });
|
|
2283
|
-
}
|
|
2284
|
-
// 机器人大厅:bot 消息只用于身份登记(上面已学 sender union / mentions
|
|
2285
|
-
// 自学 / cross-ref),绝不当任务路由——大厅打卡会点名 @ 同伴,不吞掉的话
|
|
2286
|
-
// 接收 bot 会把打卡当任务拉起会话在大厅里回话(实测)。只吞 bot 发送方:
|
|
2287
|
-
// 人类经隐藏入口进大厅后 @ bot 仍正常应答。
|
|
2288
|
-
if (isPlatformHallChat(config.session.dataDir, chatId)) {
|
|
2289
|
-
// 回执互教:打卡者点名了我们且带 #hall-echo(= 它还没学到自己的
|
|
2290
|
-
// union_id)→ @ 回它一次。open_id 直接取事件 sender_id(本 app 视角,
|
|
2291
|
-
// 无需 cross-ref),打卡者从回执的 mentions[] 学到自己。每进程每发送者
|
|
2292
|
-
// 只回一次;回执不带标记,链路必然终止。
|
|
2293
|
-
try {
|
|
2294
|
-
const text = JSON.parse(message.content ?? '{}')?.text;
|
|
2295
|
-
if (typeof text === 'string' && text.includes('#hall-echo') && senderOpenId &&
|
|
2296
|
-
isBotMentioned(larkAppId, message, undefined) &&
|
|
2297
|
-
!hallEchoReplied.has(`${larkAppId}::${senderOpenId}`)) {
|
|
2298
|
-
hallEchoReplied.add(`${larkAppId}::${senderOpenId}`);
|
|
2299
|
-
void sendMessage(larkAppId, chatId, `<at user_id="${senderOpenId}"></at> 已登记`, 'text')
|
|
2300
|
-
.then(() => logger.info(`[${larkAppId}] hall echo reply sent to ${senderOpenId.substring(0, 12)}`))
|
|
2301
|
-
.catch((e) => logger.warn(`[${larkAppId}] hall echo reply failed: ${e.message}`));
|
|
2302
|
-
}
|
|
2303
|
-
}
|
|
2304
|
-
catch { /* content 非 JSON → 忽略 */ }
|
|
2305
|
-
logger.debug(`[${larkAppId}] hall bot message swallowed after learning (chat=${chatId.substring(0, 12)})`);
|
|
2306
|
-
return;
|
|
2307
|
-
}
|
|
2308
|
-
const botMessageListener = chatType === 'group'
|
|
2309
|
-
? evaluateMessageListener({
|
|
2310
|
-
bot: getBot(larkAppId),
|
|
2311
|
-
chatId,
|
|
2312
|
-
message,
|
|
2313
|
-
senderOpenId,
|
|
2314
|
-
senderTypeRaw: sender?.sender_type,
|
|
2315
|
-
senderIdentityUnverified,
|
|
2316
|
-
explicitlyMentionedThisBot: isBotMentioned(larkAppId, message, senderOpenId),
|
|
2317
|
-
})
|
|
2318
|
-
: undefined;
|
|
2319
|
-
if (botMessageListener) {
|
|
2320
|
-
logger.info(`[message-listener:${larkAppId}] matched bot-sender chat=${chatId.substring(0, 12)} ` +
|
|
2321
|
-
`msg=${messageId.substring(0, 12)} sender=${senderOpenId?.substring(0, 12) ?? '-'}`);
|
|
2322
|
-
await dispatchHumanMessage(listenerRoutingContext({
|
|
2323
|
-
data,
|
|
2324
|
-
match: botMessageListener,
|
|
2325
|
-
chatId,
|
|
2326
|
-
messageId,
|
|
2327
|
-
chatType,
|
|
2328
|
-
larkAppId,
|
|
2329
|
-
})).catch(err => logger.error(`Error handling bot message listener event: ${err}`));
|
|
2330
|
-
return;
|
|
2331
|
-
}
|
|
2332
|
-
// Foreign bot: only route on @mention of us — with one exception.
|
|
2333
|
-
//
|
|
2334
|
-
// 主动开工 — 场景② (bot sender): 「话题群新话题自动开工」(autoStartOnNewTopic)
|
|
2335
|
-
// 覆盖到「其他机器人开的新话题」。人分支在 3271 对非 @ 的话题群新话题种子做
|
|
2336
|
-
// 同一判定;bot 消息走本分支,若不在这里补一个等价出口,就会在下面这行 return
|
|
2337
|
-
// 掉——所以 bot 开的新话题永远到不了人分支的场景②。判定复用同一个纯函数
|
|
2338
|
-
// shouldAutoStartOnNewTopic(形态门:thread-scope + anchor===本消息 + 无会话
|
|
2339
|
-
// 占用,天然只认「全新话题种子」,不认话题内回复,故不会自我循环——回复锚定在
|
|
2340
|
-
// 话题根 anchor≠messageId),并要求飞书真的把这条非 @ 的 bot 消息推过来
|
|
2341
|
-
//(依赖 im:message.group_msg.include_bot:read scope;缺则事件根本不到,静默降级)。
|
|
2342
|
-
// sender 受授权门约束(与人分支 + 下游 enforceMessageQuotaForCliInput 同源):
|
|
2343
|
-
// 授权/peer/团队/oncall/开放腿放行的 sender 才自动开工,restricted 下未授权陌生
|
|
2344
|
-
// bot 改发授权卡(详见下方 autoTopic 分支)。
|
|
2345
|
-
//
|
|
2346
|
-
// 收到 im:message.group_msg.include_bot:read 推来的「其他用户/机器人发的群消息」后,
|
|
2347
|
-
// 只有满足形态门才免 @ 自动开工;否则保持原有「未 @ 即忽略」语义。
|
|
2348
|
-
if (!isBotMentioned(larkAppId, message, undefined)) {
|
|
2349
|
-
if (getBot(larkAppId).config.autoStartOnNewTopic === true && chatType === 'group') {
|
|
2350
|
-
const seedDecision = await decideRoutingWithSource(larkAppId, message);
|
|
2351
|
-
// P3 — 镜像人分支「话题群 → 普通群 (reverse conversion)」那道 forceRefresh
|
|
2352
|
-
// 守卫:decideRoutingWithSource 判 topic-chat 种子靠的是**缓存** chat_mode
|
|
2353
|
-
//(5min TTL)。管理员把话题群翻回普通群后缓存可能仍是 'topic',于是一条本该
|
|
2354
|
-
// 是普通群顶层的 bot 消息被误判成话题种子,起 thread-scope 会话把回复裹进
|
|
2355
|
-
//「其实已是普通群」的新 Lark 话题。无真实 thread_id(= 种子形态,非既有话题内
|
|
2356
|
-
// 回复,权威信号不会 stale)时用 forceRefresh 再确认;飞书现在报 'group' 就当
|
|
2357
|
-
// 它不是话题种子(降级),不自动开工。这道 API 往返只落在「已呈现 topic 种子
|
|
2358
|
-
// 形态的 opt-in 候选」上——与人分支同样的成本取舍(宁可多一次调用,也不用
|
|
2359
|
-
// 一个 5min 错建 session 的窗口换省一次调用)。
|
|
2360
|
-
let seedIsTopicChat = seedDecision.source === 'topic-chat';
|
|
2361
|
-
if (seedIsTopicChat && !message.thread_id) {
|
|
2362
|
-
const freshMode = await getChatMode(larkAppId, chatId, { forceRefresh: true });
|
|
2363
|
-
if (freshMode === 'group') {
|
|
2364
|
-
logger.info(`[chat-mode-converted] ${chatId.substring(0, 12)} chat_mode flipped 'topic' → 'group'; ` +
|
|
2365
|
-
`跳过 bot 新话题自动开工 msg=${messageId.substring(0, 12)}`);
|
|
2366
|
-
seedIsTopicChat = false;
|
|
2367
|
-
}
|
|
2368
|
-
}
|
|
2369
|
-
// 与人分支同源:只有真正的话题群顶层种子(source==='topic-chat' 且经 forceRefresh
|
|
2370
|
-
// 复核仍是话题群)才是自动开工候选;普通群 /t / 新话题模式产生的同形
|
|
2371
|
-
// {thread, anchor=msg} 不算。
|
|
2372
|
-
const seedScope = seedIsTopicChat ? seedDecision.scope : 'chat';
|
|
2373
|
-
const seedAnchor = seedIsTopicChat ? seedDecision.anchor : chatId;
|
|
2374
|
-
const seedOwnsSession = seedScope === 'thread'
|
|
2375
|
-
? (handlers.isSessionOwner?.(seedAnchor, larkAppId) ?? false)
|
|
2376
|
-
: false;
|
|
2377
|
-
const autoTopic = shouldAutoStartOnNewTopic({
|
|
2378
|
-
enabled: true,
|
|
2379
|
-
scope: seedScope,
|
|
2380
|
-
anchor: seedAnchor,
|
|
2381
|
-
messageId,
|
|
2382
|
-
chatType,
|
|
2383
|
-
ownsSession: seedOwnsSession,
|
|
2384
|
-
});
|
|
2385
|
-
// Sender 授权门(与人分支 + 下游 enforceMessageQuotaForCliInput 一致):
|
|
2386
|
-
// 自动开工最终仍要经 handleNewTopic 里的 enforceMessageQuotaForCliInput →
|
|
2387
|
-
// evaluateBotTalk 复查,restricted 模式(配了 allowlist)下未授权的陌生 bot
|
|
2388
|
-
// 会在那里被静默 drop、session 根本不建。所以在这里**先判同一个谓词**:
|
|
2389
|
-
// • allowed → 正常免 @ 自动开工(open 模式 / oncall / 整群授权 / peer /
|
|
2390
|
-
// 团队 bot 等任一放行腿命中,与人/下游同源)。
|
|
2391
|
-
// • !allowed(restricted 下的陌生 bot)→ 不建 session,改发一次授权申请卡
|
|
2392
|
-
// 给 owner(节流复用 maybeSendGrantRequestCard 内的 isThrottled),让
|
|
2393
|
-
// owner 决定是否把它加进 allowlist——与人分支 @bot 被挡时的 not_allowed
|
|
2394
|
-
// 体验一致、可发现,而不是静默吞掉。
|
|
2395
|
-
// 只在「真未授权」发卡;已授权但额度耗尽是另一回事(走下游 quota exhausted
|
|
2396
|
-
// 语义),不在这里混。授权卡的申请对象是触发 bot 的 open_id,但审批/操作权限
|
|
2397
|
-
// 仍只归 owner;此刻不建 session,绝不把触发 bot 写成 owner,也不 --mention-back
|
|
2398
|
-
// 回唤它(dispatchHumanMessage 那条才建 session,本分支只发卡后 return)。
|
|
2399
|
-
if (autoTopic) {
|
|
2400
|
-
const seedBotTalk = evaluateBotTalk(larkAppId, chatId, senderOpenId, senderUnionId);
|
|
2401
|
-
if (!seedBotTalk.allowed) {
|
|
2402
|
-
logger.info(`[auto-start:新话题] ${chatId.substring(0, 12)} 其他机器人开新话题但未授权(restricted)→ 发授权卡不自动开工 ` +
|
|
2403
|
-
`msg=${messageId.substring(0, 12)} sender=${senderOpenId?.substring(0, 12) ?? '-'}`);
|
|
2404
|
-
await maybeSendGrantRequestCard(larkAppId, message, chatId, senderOpenId, data)
|
|
2405
|
-
.catch(err => logger.error(`Error sending grant card for foreign-bot new topic: ${err}`));
|
|
2406
|
-
return;
|
|
2407
|
-
}
|
|
2408
|
-
logger.info(`[auto-start:新话题] ${chatId.substring(0, 12)} 其他机器人开新话题免@自动开工 ` +
|
|
2409
|
-
`msg=${messageId.substring(0, 12)} sender=${senderOpenId?.substring(0, 12) ?? '-'} reason=${seedBotTalk.reason}`);
|
|
2410
|
-
const seedCtx = { chatId, messageId, chatType, larkAppId, scope: seedScope, anchor: seedAnchor };
|
|
2411
|
-
await dispatchHumanMessage({ data, ctx: seedCtx, ownsSession: false })
|
|
2412
|
-
.catch(err => logger.error(`Error auto-starting on foreign-bot new topic: ${err}`));
|
|
2413
|
-
return;
|
|
2414
|
-
}
|
|
2415
|
-
}
|
|
2416
|
-
return;
|
|
2417
|
-
}
|
|
2418
|
-
const decision = await decideRoutingWithSource(larkAppId, message);
|
|
2419
|
-
const ctx = { scope: decision.scope, anchor: decision.anchor };
|
|
2420
|
-
// Honor `/t` / `/topic` from bot senders too, aligning with the human
|
|
2421
|
-
// path so an explicit `@bot /t …` handoff seeds a fresh topic instead of
|
|
2422
|
-
// sticking to chat-scope. Applied BEFORE the gate (and the shared-topic
|
|
2423
|
-
// fold) so vetting keys on the FINAL routing: `/t` rewrites ctx to a
|
|
2424
|
-
// brand-new {thread, messageId} anchor. forceTopicApplied also suppresses
|
|
2425
|
-
// the shared-topic fold below — a `/t` seed wins over shared, same
|
|
2426
|
-
// precedence as the human path.
|
|
2427
|
-
const forcedTopic = maybeApplyForceTopicOverride(ctx, message, messageId);
|
|
2428
|
-
if (forcedTopic) {
|
|
2429
|
-
logger.info(`[/t] Force-topic override (bot sender): msg=${messageId.substring(0, 12)} → thread-scope, anchor=msg`);
|
|
2430
|
-
}
|
|
2431
|
-
const ownsThreadSession = ctx.scope === 'thread'
|
|
2432
|
-
? (handlers.isSessionOwner?.(ctx.anchor, larkAppId) ?? false)
|
|
2433
|
-
: false;
|
|
2434
|
-
// 这个 bot 能不能在本群跟我们说话 —— 判定一次,fold 与下面的 gate 共用同一个
|
|
2435
|
-
// 结论(二者之间只有 fold / shared-seed 的路由计算,不改任何授权状态)。
|
|
2436
|
-
// 曾经这里是两条手抄的 OR 链,靠人肉保持同步;漏一处就是「能路由但不能 fold」
|
|
2437
|
-
// 或「fold 了却弹卡」的二次分裂。
|
|
2438
|
-
const botTalk = evaluateBotTalk(larkAppId, chatId, senderOpenId, senderUnionId);
|
|
2439
|
-
let replyRootId = await maybeFoldMentionedRegularGroupThreadToChat({
|
|
2440
|
-
larkAppId, chatId, chatType, message, routing: ctx, forceTopicApplied: forcedTopic, mentionedThisBot: botTalk.allowed, ownsThreadSession,
|
|
2441
|
-
});
|
|
2442
|
-
if (!replyRootId) {
|
|
2443
|
-
replyRootId = await maybeApplySharedTopicSeed({
|
|
2444
|
-
larkAppId, chatId, chatType, message, senderOpenId, messageId, routing: ctx, forceTopicApplied: forcedTopic,
|
|
2445
|
-
});
|
|
2446
|
-
}
|
|
2447
|
-
// Foreign-bot @mention gate: apply the same vetted-peer/talk-only
|
|
2448
|
-
// boundary to chat scope, regular-group threads, and native topic
|
|
2449
|
-
// threads. Previously native topic replies skipped this outer gate and
|
|
2450
|
-
// were silently dropped by daemon's second evaluateTalk check, so the
|
|
2451
|
-
// owner never saw a grant card. Owning an existing session is not an
|
|
2452
|
-
// authorization source; a revoked/unknown bot must still pass
|
|
2453
|
-
// evaluateBotTalk (the single talk predicate — see its doc for the two
|
|
2454
|
-
// deliberate human/bot deltas) or prove itself a sibling below.
|
|
2455
|
-
//
|
|
2456
|
-
// 这里**只判 evaluateBotTalk**。以前是手抄的 OR 链,每加一条 talk 源就漏一次:
|
|
2457
|
-
// oncall 漏过、开放模式漏过、allowedChatGroups 又漏过(整群 /grant 后人通 bot 卡)。
|
|
2458
|
-
// 要加新的 talk 放行源,改 evaluateTalk(人/bot 同时生效),不要在这里加腿;
|
|
2459
|
-
// test/bot-talk-parity.test.ts 会盯着这条约束。
|
|
2460
|
-
//
|
|
2461
|
-
// 唯一留在闸门里的 bot 专属逻辑是下面的 cross-ref 冷启动自愈:它不是一条
|
|
2462
|
-
// 授权来源,而是「同部署兄弟 bot 的身份还没学到」这个**识别**问题的补救。
|
|
2463
|
-
if (!botTalk.allowed) {
|
|
2464
|
-
// Cold-start self-heal: the cross-ref (bot-openids-<appId>.json) is
|
|
2465
|
-
// learned lazily from observed mentions[], so the FIRST bot→bot
|
|
2466
|
-
// direct @ from a same-deployment sibling can arrive before the
|
|
2467
|
-
// receiver has learned that sibling's receiver-scoped open_id
|
|
2468
|
-
// (Lark open_id is per-app). That raced a real sibling into this
|
|
2469
|
-
// "unknown external bot" branch and mis-fired a /grant card
|
|
2470
|
-
// (regression from ec146a49). Before deciding unknown, confirm the
|
|
2471
|
-
// sender against the group's LIVE `/members/bots` roster: accept
|
|
2472
|
-
// only when it binds to exactly one locally-configured sibling of
|
|
2473
|
-
// the same unique name that independently confirms is_in_chat.
|
|
2474
|
-
// Fails closed to the grant card on any API error / ambiguity /
|
|
2475
|
-
// genuine external bot — never a name-only shortcut.
|
|
2476
|
-
const sibling = await resolveSiblingBotBySenderOpenId(larkAppId, chatId, senderOpenId)
|
|
2477
|
-
.catch((err) => ({ ok: false, reason: `resolve_threw: ${err?.message ?? String(err)}` }));
|
|
2478
|
-
if (sibling.ok) {
|
|
2479
|
-
// Persist the newly-proven mapping so subsequent @s from this
|
|
2480
|
-
// sibling hit isKnownPeerBot directly (no live API roundtrip).
|
|
2481
|
-
updateBotOpenIdCrossRef(config.session.dataDir, larkAppId, [
|
|
2482
|
-
{ name: sibling.botName, id: { open_id: sibling.senderOpenId } },
|
|
2483
|
-
]);
|
|
2484
|
-
logger.info(`Lazy sibling cross-ref backfill: ${sibling.botName} → ${senderOpenId?.substring(0, 12)} (was cold; skipping /grant)`);
|
|
2485
|
-
}
|
|
2486
|
-
else {
|
|
2487
|
-
logger.info(`Foreign bot @mention not a known sibling (${sibling.reason}); sending grant request card`);
|
|
2488
|
-
await maybeSendGrantRequestCard(larkAppId, message, chatId, senderOpenId, data);
|
|
2489
|
-
return;
|
|
2490
|
-
}
|
|
2491
|
-
}
|
|
2492
|
-
logger.info(`Bot-to-bot @mention detected (scope=${ctx.scope}): routing to handleThreadReply`);
|
|
2493
|
-
// Serialize per anchor — a sub-bot dispatched a /repo prime + kickoff
|
|
2494
|
-
// back-to-back into this thread must be handled in order, not raced.
|
|
2495
|
-
await serializeByAnchor(ctx.anchor, () => handlers.handleThreadReply(data, { ...ctx, chatId, messageId, chatType, larkAppId, replyRootId }))
|
|
2496
|
-
.catch(err => logger.error(`Error handling bot @mention: ${err}`));
|
|
2497
|
-
return;
|
|
2498
|
-
}
|
|
2499
|
-
const senderOpenId = sender?.sender_id?.open_id;
|
|
2500
|
-
// 人的 union_id:平台团队成员 talk-免grant 腿(isPlatformTeamMemberChat)要用。
|
|
2501
|
-
const humanSenderUnionId = sender?.sender_id?.union_id;
|
|
2502
|
-
// defaultOncall 自动绑定必须在 canTalk 权限判断前完成,否则已开 defaultOncall
|
|
2503
|
-
// 的群首次 @bot 时 oncallChats 中还没有该 chat → evaluateTalk 判无权限 → 误弹
|
|
2504
|
-
// 自助授权申请卡。ensureDefaultOncallBound 本身带 fast-path 短路且 idempotent。
|
|
2505
|
-
await ensureDefaultOncallBound(larkAppId, chatId, chatType).catch(err => logger.warn(`[oncall:${larkAppId}] pre-permission auto-bind failed for ${chatId.substring(0, 12)}: ${err}`));
|
|
2506
|
-
// 人的路径(bot 发送方已在上面的分支 return):union 走 memberUnionId 腿,
|
|
2507
|
-
// 不进 bot-trust 腿——teamBot 只认 bot-locked union。
|
|
2508
|
-
const isAllowed = canTalk(larkAppId, chatId, senderOpenId, undefined, humanSenderUnionId, chatType);
|
|
2509
|
-
// /introduce — collaboration handshake. Intercept before any routing
|
|
2510
|
-
// so the command never reaches a CLI session (each @ed bot's daemon
|
|
2511
|
-
// independently records the mentions[] open_ids + names). 无需授权:
|
|
2512
|
-
// 任何人都能登记花名册(只记 observed,不授予任何权限)。
|
|
2513
|
-
if (await tryHandleIntroduceCommand(larkAppId, message, senderOpenId)) {
|
|
2514
|
-
return;
|
|
2515
|
-
}
|
|
2516
|
-
if (await tryHandleReplyModeCommand(larkAppId, message, senderOpenId, isAllowed)) {
|
|
2517
|
-
return;
|
|
2518
|
-
}
|
|
2519
|
-
if (await tryHandleSubstituteCommand(larkAppId, message, senderOpenId)) {
|
|
2520
|
-
return;
|
|
2521
|
-
}
|
|
2522
|
-
// /grant、/revoke — 群内授权元命令。在路由/spawn 之前拦截(仅 owner,需明确 @ 本 bot),
|
|
2523
|
-
// 否则会被当成 prompt 喂给 CLI 会话。
|
|
2524
|
-
if (await tryHandleGrantCommand(larkAppId, message, senderOpenId)) {
|
|
2525
|
-
return;
|
|
2526
|
-
}
|
|
2527
|
-
// /invite — 把群外 bot 拉进本群的元命令。与 /grant 同款拦截模型(仅 owner,
|
|
2528
|
-
// 需明确 @ 本 bot),防止进路由/spawn,也防多 bot 重复执行拉人。
|
|
2529
|
-
if (await tryHandleInviteCommand(larkAppId, message, senderOpenId)) {
|
|
2530
|
-
return;
|
|
2531
|
-
}
|
|
2532
|
-
logger.debug('Received message:', message);
|
|
2533
|
-
// Diagnostic: record the Lark quote-bubble UI quirk where root_id
|
|
2534
|
-
// appears without thread_id. decideRouting now treats this as
|
|
2535
|
-
// "no thread" (chat-scope / topic / new-topic depending on context),
|
|
2536
|
-
// which is the authoritative behavior. Logging it here so we can spot
|
|
2537
|
-
// any future surprise in the wild.
|
|
2538
|
-
if (message.root_id && !message.thread_id) {
|
|
2539
|
-
logger.info(`[routing] root_id w/o thread_id (Lark UI quirk, treating as top-level): ` +
|
|
2540
|
-
`msg=${messageId.substring(0, 12)} chat=${chatId.substring(0, 12)} ` +
|
|
2541
|
-
`type=${chatType} root=${String(message.root_id).substring(0, 12)} ` +
|
|
2542
|
-
`parent=${String(message.parent_id ?? '').substring(0, 12)}`);
|
|
2543
|
-
}
|
|
2544
|
-
const decision = await decideRoutingWithSource(larkAppId, message);
|
|
2545
|
-
const routing = {
|
|
2546
|
-
scope: decision.scope,
|
|
2547
|
-
anchor: decision.anchor,
|
|
2548
|
-
};
|
|
2549
|
-
let routingSource = decision.source;
|
|
2550
|
-
let replyRootId;
|
|
2551
|
-
// 私聊 chat 模式:会话是扁平连续的(整段 DM 一个 chat-scope 会话),但如果这条
|
|
2552
|
-
// 消息本身是在某个已存在的话题里回复的(root_id+thread_id),可见回复必须落回
|
|
2553
|
-
// 那个话题里,而不是漏到 DM 顶层。decideRouting 已把 scope 折成 chat(会话扁平
|
|
2554
|
-
// 语义不变),这里只补 replyRootId 让 sendReply 用 reply_in_thread 锚回话题根。
|
|
2555
|
-
// 群聊侧的同类保留由 maybeFold / alias 分支处理(它们 gate chatType==='group',
|
|
2556
|
-
// 私聊走不到),故私聊必须在此单独补。仅 p2p:群顶层消息不该被强行塞进话题。
|
|
2557
|
-
if (routing.scope === 'chat' && chatType === 'p2p' && message.root_id && message.thread_id) {
|
|
2558
|
-
replyRootId = message.root_id;
|
|
2559
|
-
}
|
|
2560
|
-
const explicitlyMentionedThisBot = isBotMentioned(larkAppId, message, senderOpenId);
|
|
2561
|
-
const messageListener = chatType === 'group'
|
|
2562
|
-
? evaluateMessageListener({
|
|
2563
|
-
bot: getBot(larkAppId),
|
|
2564
|
-
chatId,
|
|
2565
|
-
message,
|
|
2566
|
-
senderOpenId,
|
|
2567
|
-
senderTypeRaw: sender?.sender_type,
|
|
2568
|
-
explicitlyMentionedThisBot,
|
|
2569
|
-
})
|
|
2570
|
-
: undefined;
|
|
2571
|
-
if (messageListener) {
|
|
2572
|
-
routing.scope = 'thread';
|
|
2573
|
-
routing.anchor = messageId;
|
|
2574
|
-
routingSource = 'topic-chat';
|
|
2575
|
-
replyRootId = undefined;
|
|
2576
|
-
logger.info(`[message-listener:${larkAppId}] matched chat=${chatId.substring(0, 12)} ` +
|
|
2577
|
-
`msg=${messageId.substring(0, 12)} sender=${senderOpenId?.substring(0, 12) ?? '-'}`);
|
|
2578
|
-
}
|
|
2579
|
-
// Cheap in-memory gate FIRST: skip the getChatMode roundtrip and the
|
|
2580
|
-
// per-chat toggle disk read entirely for bots that never configured a
|
|
2581
|
-
// substitute target (the overwhelming majority on the hot path).
|
|
2582
|
-
const substituteCfg = getBot(larkAppId).config.substituteMode;
|
|
2583
|
-
let substituteChatMode;
|
|
2584
|
-
// chats 白名单在 getChatMode 之前(纯内存判断走在 API roundtrip 前),
|
|
2585
|
-
// 对普通群与话题群统一生效:白名单是「替身可触发的群」清单,与群形态无关。
|
|
2586
|
-
if (substituteCfg?.enabled === true && chatType === 'group' && isSubstituteAllowedChat(substituteCfg, chatId)) {
|
|
2587
|
-
const chatMode = await getChatMode(larkAppId, chatId);
|
|
2588
|
-
const modeSupported = chatMode === 'group'
|
|
2589
|
-
// 话题群支持默认开(缺省=开,normalize 只在显式 false 时关)。
|
|
2590
|
-
|| (chatMode === 'topic' && substituteCfg.topicGroups !== false);
|
|
2591
|
-
if (modeSupported && isSubstituteEnabledForChat(larkAppId, chatId)) {
|
|
2592
|
-
substituteChatMode = chatMode;
|
|
2593
|
-
}
|
|
2594
|
-
}
|
|
2595
|
-
// 黑名单硬静默:命中黑名单的群里,一条「本该触发替身」的消息(@ 到了配置的
|
|
2596
|
-
// 替身对象、但没有直接 @ 本 bot)必须当作没读到——直接 return,不只是清 trigger。
|
|
2597
|
-
// 只清 trigger 不够:消息会继续 fall-through 到通用群消息门,若 bot 在该群有活跃
|
|
2598
|
-
// 会话 / 是 solo 群 / mentionMode 放开,仍会被喂进去并弹卡片(用户实测现象)。
|
|
2599
|
-
// 直接 @ 本 bot(explicitlyMentionedThisBot)不受影响:黑名单只静音替身代答,
|
|
2600
|
-
// 不静音「直接找 bot 问问题」。/substitute 命令已在上方 command 处理器拦截。
|
|
2601
|
-
if (substituteCfg?.enabled === true
|
|
2602
|
-
&& chatType === 'group'
|
|
2603
|
-
&& !explicitlyMentionedThisBot
|
|
2604
|
-
&& isSubstituteExcludedChat(substituteCfg, chatId)
|
|
2605
|
-
&& resolveSubstituteTrigger(larkAppId, message)) {
|
|
2606
|
-
logger.info(`[substitute:${larkAppId}] excluded chat — dropping @target message ` +
|
|
2607
|
-
`msg=${messageId.substring(0, 12)} chat=${chatId.substring(0, 12)}`);
|
|
2608
|
-
return;
|
|
2609
|
-
}
|
|
2610
|
-
let substituteTrigger = substituteChatMode
|
|
2611
|
-
? resolveSubstituteTrigger(larkAppId, message)
|
|
2612
|
-
: undefined;
|
|
2613
|
-
if (substituteTrigger && !explicitlyMentionedThisBot) {
|
|
2614
|
-
const rawText = extractMessageTextForRouting(message);
|
|
2615
|
-
const stripped = rawText ? stripLeadingMentions(rawText.trim(), message?.mentions ?? []).trim() : '';
|
|
2616
|
-
if (stripped.startsWith('/'))
|
|
2617
|
-
substituteTrigger = undefined;
|
|
2618
|
-
}
|
|
2619
|
-
if (substituteTrigger && substituteChatMode === 'topic'
|
|
2620
|
-
&& substituteCfg?.topicActiveSessionTrigger === false
|
|
2621
|
-
&& (handlers.isSessionOwner?.(routing.anchor, larkAppId) ?? false)) {
|
|
2622
|
-
// 话题里已有本 bot 活跃会话 + 用户关掉了「活跃话题也触发」:
|
|
2623
|
-
// 单独 @替身对象 是明确转交,必须在任何通用免 @ 规则前直接让路;
|
|
2624
|
-
// 只清掉 metadata 不够,1v1 群/mentionMode=never 仍会把消息喂给 bot。
|
|
2625
|
-
substituteTrigger = undefined;
|
|
2626
|
-
if (!explicitlyMentionedThisBot) {
|
|
2627
|
-
logger.debug(`[substitute:${larkAppId}] active-topic trigger disabled; backing off ` +
|
|
2628
|
-
`msg=${messageId.substring(0, 12)} thread=${String(routing.anchor).substring(0, 12)}`);
|
|
2629
|
-
return;
|
|
2630
|
-
}
|
|
2631
|
-
}
|
|
2632
|
-
if (substituteTrigger) {
|
|
2633
|
-
if (substituteChatMode === 'group') {
|
|
2634
|
-
routing.scope = 'chat';
|
|
2635
|
-
routing.anchor = chatId;
|
|
2636
|
-
routingSource = 'regular-group-chat';
|
|
2637
|
-
// Top-level substitute messages need their own reply anchor so that
|
|
2638
|
-
// concurrent triggers from different users in the same chat-scope
|
|
2639
|
-
// session don't collapse or thread under the wrong message. Existing
|
|
2640
|
-
// real threads keep their root_id.
|
|
2641
|
-
replyRootId = (message.root_id && message.thread_id) ? message.root_id : messageId;
|
|
2642
|
-
}
|
|
2643
|
-
// 话题群:保持 decideRouting 的 thread-scope/话题锚点不动——替身回合
|
|
2644
|
-
// 直接搭该话题自己的会话(无会话则由 handleNewTopic 新开),与普通群
|
|
2645
|
-
// 「搭群 chat-scope 会话」同构;回复天然落回本话题,无需 replyRootId。
|
|
2646
|
-
const configuredTargetId = substituteTrigger.target.openId
|
|
2647
|
-
?? substituteTrigger.target.userId
|
|
2648
|
-
?? substituteTrigger.target.unionId
|
|
2649
|
-
?? 'unknown';
|
|
2650
|
-
const configuredTargetForLog = JSON.stringify(configuredTargetId.slice(0, 128));
|
|
2651
|
-
logger.info(`[substitute:${larkAppId}] mention target=${configuredTargetForLog} ` +
|
|
2652
|
-
`msg=${messageId.substring(0, 12)} chat=${chatId.substring(0, 12)} → ${substituteChatMode === 'group' ? 'chat-scope' : `topic thread=${String(routing.anchor).substring(0, 12)}`}`);
|
|
2653
|
-
}
|
|
2654
|
-
// Shared-mode follow-up: a non-@ message inside a Lark thread can belong
|
|
2655
|
-
// to the regular group's chat-scope session when that root was registered
|
|
2656
|
-
// as a shared-topic alias. Whether a 普通群 answers it without an @mention
|
|
2657
|
-
// is governed by the bot-global mention policy: 'always' (default) keeps
|
|
2658
|
-
// "@ required" so this fold-back is skipped (non-@ thread chatter falls
|
|
2659
|
-
// through to the gate below and is ignored — only an explicit @ continues
|
|
2660
|
-
// a shared topic); 'topic', 'never' and 'ambient' enable the seamless
|
|
2661
|
-
// no-@ fold-back. Carve-out: under 'topic' / 'ambient', a non-@ reply
|
|
2662
|
-
// that @mentions another specific member (person/bot) is a redirect to
|
|
2663
|
-
// someone else → back off, don't fold it in (mentionsAnotherMember).
|
|
2664
|
-
// 'never' stays unconditional by design.
|
|
2665
|
-
const mentionModeForAlias = resolveGroupMentionMode(larkAppId);
|
|
2666
|
-
if (!explicitlyMentionedThisBot
|
|
2667
|
-
&& mentionModeForAlias !== 'always'
|
|
2668
|
-
&& !((mentionModeForAlias === 'topic' || mentionModeForAlias === 'ambient') && mentionsAnotherMember(larkAppId, message))
|
|
2669
|
-
&& routing.scope === 'thread' && message.root_id && message.thread_id && chatType === 'group') {
|
|
2670
|
-
const alias = handlers.resolveReplyThreadAlias?.(message.root_id, chatId, larkAppId) ?? null;
|
|
2671
|
-
if (alias) {
|
|
2672
|
-
const freshMode = await getChatMode(larkAppId, chatId, { forceRefresh: true });
|
|
2673
|
-
if (freshMode === 'group') {
|
|
2674
|
-
routing.scope = 'chat';
|
|
2675
|
-
routing.anchor = alias.anchor ?? alias.chatId;
|
|
2676
|
-
replyRootId = message.root_id;
|
|
2677
|
-
logger.info(`[reply-mode] alias root=${message.root_id.substring(0, 12)} → chat=${alias.chatId.substring(0, 12)} session=${alias.sessionId.substring(0, 8)}`);
|
|
2678
|
-
}
|
|
2679
|
-
}
|
|
2680
|
-
}
|
|
2681
|
-
// 话题群 → 普通群 (reverse conversion). Symmetric to the forward check
|
|
2682
|
-
// below: when decideRouting lands on thread-scope purely because the
|
|
2683
|
-
// *cached* chat_mode said 'topic' (no real thread_id on the message
|
|
2684
|
-
// either — i.e. this would seed a brand-new thread), our 5-min cache
|
|
2685
|
-
// may be stale from before a flip-back to 普通群. Re-verify with
|
|
2686
|
-
// forceRefresh; if Lark now reports 'group', flatten to chat-scope so
|
|
2687
|
-
// the bot doesn't keep wrapping every top-level reply in a fresh
|
|
2688
|
-
// Lark topic via reply_in_thread.
|
|
2689
|
-
//
|
|
2690
|
-
// Skip when there's a real thread_id (authoritative thread signal,
|
|
2691
|
-
// can't be cache-stale) or when chatType is p2p (DMs always thread).
|
|
2692
|
-
// Runs BEFORE /t override so a `@bot /t …` in a now-flat 普通群 still
|
|
2693
|
-
// gets the explicit topic seed it asked for.
|
|
2694
|
-
if (!messageListener &&
|
|
2695
|
-
routing.scope === 'thread' &&
|
|
2696
|
-
routing.anchor === messageId &&
|
|
2697
|
-
!message.thread_id &&
|
|
2698
|
-
chatType === 'group') {
|
|
2699
|
-
const freshMode = await getChatMode(larkAppId, chatId, { forceRefresh: true });
|
|
2700
|
-
if (freshMode === 'group') {
|
|
2701
|
-
const rerouted = regularGroupRouting(larkAppId, messageId, chatId);
|
|
2702
|
-
logger.info(`[chat-mode-converted] ${chatId.substring(0, 12)} chat_mode flipped 'topic' → 'group'; ` +
|
|
2703
|
-
`rerouting msg=${messageId.substring(0, 12)} as ${rerouted.scope}-scope`);
|
|
2704
|
-
routing.scope = rerouted.scope;
|
|
2705
|
-
routing.anchor = rerouted.anchor;
|
|
2706
|
-
routingSource = rerouted.source;
|
|
2707
|
-
}
|
|
2708
|
-
}
|
|
2709
|
-
// 主动开工 — 场景②: capture only genuine topic-group seeds NOW, before
|
|
2710
|
-
// `/t` or the regular-group new-topic mode can create the same
|
|
2711
|
-
// {thread, anchor=messageId} shape in a regular group. autoStartOnNewTopic
|
|
2712
|
-
// is deliberately limited to 话题群.
|
|
2713
|
-
const autoTopicSeedScope = routingSource === 'topic-chat' ? routing.scope : 'chat';
|
|
2714
|
-
const autoTopicSeedAnchor = routingSource === 'topic-chat' ? routing.anchor : chatId;
|
|
2715
|
-
// /t / /topic in 普通群: flip routing to thread-scope so the bot's
|
|
2716
|
-
// first reply seeds a fresh Lark thread, even if a chat-scope session
|
|
2717
|
-
// is currently active in this chat.
|
|
2718
|
-
const forceTopicApplied = substituteTrigger ? false : maybeApplyForceTopicOverride(routing, message, messageId);
|
|
2719
|
-
if (forceTopicApplied) {
|
|
2720
|
-
logger.info(`[/t] Force-topic override: msg=${messageId.substring(0, 12)} → thread-scope, anchor=msg`);
|
|
2721
|
-
}
|
|
2722
|
-
let ownsSession = handlers.isSessionOwner?.(routing.anchor, larkAppId) ?? false;
|
|
2723
|
-
const ownsThreadSessionBeforeFold = routing.scope === 'thread'
|
|
2724
|
-
? (handlers.isSessionOwner?.(routing.anchor, larkAppId) ?? false)
|
|
2725
|
-
: false;
|
|
2726
|
-
const foldedReplyRootId = await maybeFoldMentionedRegularGroupThreadToChat({
|
|
2727
|
-
larkAppId, chatId, chatType, message, routing, forceTopicApplied, mentionedThisBot: explicitlyMentionedThisBot, ownsThreadSession: ownsThreadSessionBeforeFold,
|
|
2728
|
-
});
|
|
2729
|
-
if (foldedReplyRootId) {
|
|
2730
|
-
replyRootId = foldedReplyRootId;
|
|
2731
|
-
ownsSession = handlers.isSessionOwner?.(routing.anchor, larkAppId) ?? false;
|
|
2732
|
-
}
|
|
2733
|
-
else {
|
|
2734
|
-
const seedReplyRootId = await maybeApplySharedTopicSeed({
|
|
2735
|
-
larkAppId, chatId, chatType, message, senderOpenId, messageId, routing, forceTopicApplied,
|
|
2736
|
-
});
|
|
2737
|
-
if (seedReplyRootId) {
|
|
2738
|
-
replyRootId = seedReplyRootId;
|
|
2739
|
-
ownsSession = handlers.isSessionOwner?.(routing.anchor, larkAppId) ?? false;
|
|
2740
|
-
}
|
|
2741
|
-
}
|
|
2742
|
-
// 普通群 → 话题群 conversion detection. Lark group admins can flip
|
|
2743
|
-
// chat_mode at any time; our 30/5-min cache lags. If routing landed on
|
|
2744
|
-
// chat-scope AND we own a session at this chat, the chat-scope session
|
|
2745
|
-
// may be stale from before a conversion. Re-fetch chat_mode with
|
|
2746
|
-
// forceRefresh to confirm. If it's now 'topic', the session is dead:
|
|
2747
|
-
// sendMessage(chatId) at dispatch time would wrap each reply in a new
|
|
2748
|
-
// Lark topic (the user-reported bug). Evict the stale session, then
|
|
2749
|
-
// route this message as if it were a brand-new thread seed so
|
|
2750
|
-
// handleNewTopic spawns a thread-scope session anchored at messageId.
|
|
2751
|
-
// Gate on ownsSession to avoid an API roundtrip on every fresh inbound.
|
|
2752
|
-
// Skip p2p: a DM is always 'p2p' and can never be a topic group, so the
|
|
2753
|
-
// check can only waste a forceRefresh roundtrip (relevant now that
|
|
2754
|
-
// p2pMode==='chat' makes DMs land on chat-scope).
|
|
2755
|
-
if (routing.scope === 'chat' && ownsSession && chatType !== 'p2p') {
|
|
2756
|
-
const freshMode = await getChatMode(larkAppId, chatId, { forceRefresh: true });
|
|
2757
|
-
if (freshMode === 'topic') {
|
|
2758
|
-
logger.info(`[chat-mode-converted] ${chatId.substring(0, 12)} chat_mode flipped 'group' → 'topic'; ` +
|
|
2759
|
-
`evicting stale chat-scope session and rerouting msg=${messageId.substring(0, 12)} as thread seed`);
|
|
2760
|
-
try {
|
|
2761
|
-
handlers.onChatModeConverted?.(chatId, larkAppId);
|
|
2762
|
-
}
|
|
2763
|
-
catch (err) {
|
|
2764
|
-
logger.warn(`onChatModeConverted handler threw: ${err}`);
|
|
2765
|
-
}
|
|
2766
|
-
routing.scope = 'thread';
|
|
2767
|
-
routing.anchor = messageId;
|
|
2768
|
-
routingSource = 'topic-chat';
|
|
2769
|
-
// ownsSession was true on the stale chatId anchor; the new anchor
|
|
2770
|
-
// (messageId) is brand-new, so no current session owns it.
|
|
2771
|
-
ownsSession = false;
|
|
2772
|
-
}
|
|
2773
|
-
}
|
|
2774
|
-
const summaryCommandMatch = await resolveSummaryCommandMatch({
|
|
2775
|
-
larkAppId,
|
|
2776
|
-
chatId,
|
|
2777
|
-
chatType,
|
|
2778
|
-
routingSource,
|
|
2779
|
-
message,
|
|
2780
|
-
senderOpenId,
|
|
2781
|
-
});
|
|
2782
|
-
const summaryCommandTriggered = !!summaryCommandMatch && isAllowed;
|
|
2783
|
-
const routingText = extractMessageTextForRouting(message);
|
|
2784
|
-
const strippedRoutingText = routingText
|
|
2785
|
-
? stripLeadingMentions(routingText.trim(), message?.mentions ?? []).trim()
|
|
2786
|
-
: '';
|
|
2787
|
-
const isControlCommand = strippedRoutingText.startsWith('/');
|
|
2788
|
-
let pairedForwardSeed;
|
|
2789
|
-
// Require isAllowed before pairing: a root-linked clarification from a
|
|
2790
|
-
// sender who was /revoked within the grace window must not consume the
|
|
2791
|
-
// seed from the buffer or overwrite the durable paired record. The seed
|
|
2792
|
-
// stays in the buffer and flushes on its original timer. Paired seeds
|
|
2793
|
-
// only arise under never/ambient modes, where a legitimate merge always
|
|
2794
|
-
// requires isAllowed anyway.
|
|
2795
|
-
if (senderOpenId && isAllowed && message.root_id && !isControlCommand) {
|
|
2796
|
-
await seedRoutingGates.get(message.root_id)?.ready;
|
|
2797
|
-
const pairingInput = {
|
|
2798
|
-
larkAppId,
|
|
2799
|
-
chatId,
|
|
2800
|
-
senderOpenId,
|
|
2801
|
-
rootId: message.root_id,
|
|
2802
|
-
};
|
|
2803
|
-
const pairingMentionMode = resolveGroupMentionMode(larkAppId);
|
|
2804
|
-
const ambientRedirect = pairingMentionMode === 'ambient'
|
|
2805
|
-
&& !explicitlyMentionedThisBot
|
|
2806
|
-
&& mentionsAnotherMember(larkAppId, message);
|
|
2807
|
-
const pairingDelayEnabled = usesForwardFollowupDelay(pairingMentionMode);
|
|
2808
|
-
if (pairingDelayEnabled && !ambientRedirect) {
|
|
2809
|
-
pairedForwardSeed = forwardFollowups.take(pairingInput);
|
|
2810
|
-
}
|
|
2811
|
-
else if (!pairingDelayEnabled) {
|
|
2812
|
-
const stalePendingSeed = forwardFollowups.take(pairingInput);
|
|
2813
|
-
if (stalePendingSeed) {
|
|
2814
|
-
try {
|
|
2815
|
-
await dispatchPersistedForwardFollowup(stalePendingSeed.messageId, stalePendingSeed.payload);
|
|
2816
|
-
}
|
|
2817
|
-
catch (err) {
|
|
2818
|
-
logger.warn(`[forward-followup] failed to flush stale seed=${stalePendingSeed.messageId.substring(0, 12)}; ` +
|
|
2819
|
-
`continuing current msg=${messageId.substring(0, 12)}: ${err}`);
|
|
2820
|
-
}
|
|
2821
|
-
}
|
|
2822
|
-
}
|
|
2823
|
-
}
|
|
2824
|
-
if (pairedForwardSeed) {
|
|
2825
|
-
// The clarification becomes the visible Lark topic root. The earlier
|
|
2826
|
-
// forwarded seed is retained only as prompt context, so the bot never
|
|
2827
|
-
// emits a reply under the forwarding bubble itself.
|
|
2828
|
-
routing.scope = 'thread';
|
|
2829
|
-
routing.anchor = messageId;
|
|
2830
|
-
routingSource = 'topic-chat';
|
|
2831
|
-
replyRootId = undefined;
|
|
2832
|
-
ownsSession = false;
|
|
2833
|
-
try {
|
|
2834
|
-
putForwardFollowup(larkAppId, {
|
|
2835
|
-
messageId: pairedForwardSeed.messageId,
|
|
2836
|
-
dueAt: Date.now(),
|
|
2837
|
-
payload: {
|
|
2838
|
-
data,
|
|
2839
|
-
ctx: {
|
|
2840
|
-
...pairedForwardSeed.payload.ctx,
|
|
2841
|
-
chatId,
|
|
2842
|
-
messageId,
|
|
2843
|
-
chatType,
|
|
2844
|
-
larkAppId,
|
|
2845
|
-
scope: 'thread',
|
|
2846
|
-
anchor: messageId,
|
|
2847
|
-
replyRootId: undefined,
|
|
2848
|
-
forwardSeedData: pairedForwardSeed.payload.data,
|
|
2849
|
-
},
|
|
2850
|
-
ownsSession: false,
|
|
2851
|
-
},
|
|
2852
|
-
});
|
|
2853
|
-
}
|
|
2854
|
-
catch (err) {
|
|
2855
|
-
logger.warn(`[forward-followup] failed to persist provisional paired payload: ${err}`);
|
|
2856
|
-
}
|
|
2857
|
-
logger.info(`[forward-followup] merged seed=${pairedForwardSeed.messageId.substring(0, 12)} ` +
|
|
2858
|
-
`into msg=${messageId.substring(0, 12)} chat=${chatId.substring(0, 12)}`);
|
|
2859
|
-
}
|
|
2860
|
-
// Permission gating — same shape as before, just keyed on
|
|
2861
|
-
// `ownsSession` (anchor-aware) instead of "rootId presence":
|
|
2862
|
-
//
|
|
2863
|
-
// ownsSession + 1v1 group → relax (no @mention required)
|
|
2864
|
-
// ownsSession + multi → require @mention
|
|
2865
|
-
// !ownsSession (group) → require @mention + allowlist
|
|
2866
|
-
// p2p → allowlist only
|
|
2867
|
-
if (chatType === 'group') {
|
|
2868
|
-
const mentionMode = resolveGroupMentionMode(larkAppId);
|
|
2869
|
-
// 消息里 @ 了别的具体成员,就已经证明群不是 1人1bot(只有群成员能被 @)——
|
|
2870
|
-
// 此刻末条 solo 放行必然不成立,而 stats 只被末条消费,直接跳过这次(可能
|
|
2871
|
-
// 昂贵的)人数查询。这在「刚拉了新 bot、用户 @ 新 bot」窗口里尤为重要:
|
|
2872
|
-
// 拦截老 bot 的同时不再为它反复刷新陈旧缓存。
|
|
2873
|
-
const mentionsOther = mentionsAnotherMember(larkAppId, message);
|
|
2874
|
-
let stats = null;
|
|
2875
|
-
if (ownsSession && !replyRootId && !mentionsOther && mentionMode !== 'never') {
|
|
2876
|
-
stats = await getGroupStats(larkAppId, chatId);
|
|
2877
|
-
}
|
|
2878
|
-
// replyRootId means this turn has already been explicitly addressed
|
|
2879
|
-
// to the bot by shared-topic logic (possibly from inside an existing
|
|
2880
|
-
// Lark thread). Do not re-run the generic group @ gate, which would
|
|
2881
|
-
// reject multi-bot thread replies simply because `routing.scope` was
|
|
2882
|
-
// folded back to chat-scope.
|
|
2883
|
-
//
|
|
2884
|
-
// The bot-global mention policy drops the @ requirement:
|
|
2885
|
-
// • 'never' — answer EVERY un-@ message from talk-allowed senders
|
|
2886
|
-
// (incl. brand-new non-@ top-level → spawns/continues a session),
|
|
2887
|
-
// unconditionally. Intended for dedicated / on-call groups.
|
|
2888
|
-
// • 'ambient' — like 'never' (answer un-@ messages), EXCEPT when the
|
|
2889
|
-
// message @mentions another specific member (person/bot) without
|
|
2890
|
-
// @ing us — that is a redirect to someone else, so we back off and
|
|
2891
|
-
// stay quiet (mentionsAnotherMember). @all does not count as a
|
|
2892
|
-
// redirect. Best for multi-bot / multi-person groups that want a
|
|
2893
|
-
// default responder which yields the moment you address someone else.
|
|
2894
|
-
// • 'topic' — only inside a topic the bot already owns: a non-@ reply
|
|
2895
|
-
// INSIDE such a thread (new-topic / 话题群 thread the bot owns, or a
|
|
2896
|
-
// shared-topic alias via replyRootId) continues without @, while a
|
|
2897
|
-
// brand-new top-level conversation still requires @. If the user
|
|
2898
|
-
// explicitly @mentions another member/bot without @ing this bot,
|
|
2899
|
-
// treat it as a hand-off and stay quiet.
|
|
2900
|
-
// Both gated on isAllowed so restricted groups still only react to
|
|
2901
|
-
// permitted senders. (The shared fold-back's replyRootId is already
|
|
2902
|
-
// handled by the first clause. `mentionMode` 已在块首解析,用于 stats
|
|
2903
|
-
// 惰性获取。)
|
|
2904
|
-
// 话题群 owned-topic 免@续话不再无条件放行(#336 引入的默认行为回归:
|
|
2905
|
-
// 多人群里旁人不 @ 也会触发 bot)。现在与普通群共用同一套「群聊 @ 策略」:
|
|
2906
|
-
// 默认 'always' 在多人群里必须 @,想要话题内免@续话就把 mentionMode 配成
|
|
2907
|
-
// 'topic'(下方条款已同时覆盖话题群 thread 与普通群 shared topic),
|
|
2908
|
-
// 'never'/'ambient' 亦按各自语义生效。1人1bot 的 solo 群仍走末条放行。
|
|
2909
|
-
// 注:pairedForwardSeed 仅在 never/ambient 模式下产生,且 ambient redirect
|
|
2910
|
-
// 已在配对前排除,故 isAllowed=true 时下方 never/ambient 条款必然放行;
|
|
2911
|
-
// 不在此单独加 clause,以免 isAllowed=false 时绕过权限检查。
|
|
2912
|
-
// 末条 solo 放行另有 `!mentionsOther` 守卫:消息 @ 了别的具体成员时,
|
|
2913
|
-
// 群必然不是 1人1bot(只有群成员能被 @),且是指给别人的——拦住「刚拉新 bot、
|
|
2914
|
-
// 缓存仍是陈旧 {1,1} 时老 bot 跟着回复」的误放行。never 条款在前已短路,
|
|
2915
|
-
// 故该守卫不影响「群聊 @ 策略」配置的 never 语义。
|
|
2916
|
-
const relax = (!!replyRootId && isAllowed)
|
|
2917
|
-
|| (!!substituteTrigger && isAllowed)
|
|
2918
|
-
|| !!messageListener
|
|
2919
|
-
|| (isAllowed && mentionMode === 'never')
|
|
2920
|
-
|| (isAllowed && mentionMode === 'ambient' && !mentionsOther)
|
|
2921
|
-
|| (isAllowed && mentionMode === 'topic' && ownsSession && !!message.thread_id && !mentionsOther)
|
|
2922
|
-
|| (ownsSession && isAllowed && !!stats && !mentionsOther && stats.userCount <= 1 && stats.botCount <= 1);
|
|
2923
|
-
if (!relax) {
|
|
2924
|
-
const access = await checkGroupMessageAccess(larkAppId, message, chatId, senderOpenId, humanSenderUnionId);
|
|
2925
|
-
if (access === 'not_allowed') {
|
|
2926
|
-
// 入口 A:无权限者 @bot → 弹授权申请卡(@owner),代替「无操作权限」。
|
|
2927
|
-
// 覆盖 ownsSession 真假两种情况,但绝不把该消息喂进已有 session。
|
|
2928
|
-
await maybeSendGrantRequestCard(larkAppId, message, chatId, senderOpenId, data);
|
|
2929
|
-
logger.debug(`Ignoring group message from non-allowed user: ${senderOpenId} (grant request card path)`);
|
|
2930
|
-
return;
|
|
2931
|
-
}
|
|
2932
|
-
if (access === 'ignore') {
|
|
2933
|
-
// 主动开工 — 场景②: a non-@ message that seeds a brand-new topic in
|
|
2934
|
-
// a 话题群 auto-starts a session when the bot opted in. Everything
|
|
2935
|
-
// else (regular-group chatter, thread replies, disabled bots) keeps
|
|
2936
|
-
// the original ignore. Sender is intentionally not gated (D4).
|
|
2937
|
-
const autoTopic = shouldAutoStartOnNewTopic({
|
|
2938
|
-
enabled: getBot(larkAppId).config.autoStartOnNewTopic === true,
|
|
2939
|
-
scope: autoTopicSeedScope,
|
|
2940
|
-
anchor: autoTopicSeedAnchor,
|
|
2941
|
-
messageId,
|
|
2942
|
-
chatType,
|
|
2943
|
-
ownsSession,
|
|
2944
|
-
});
|
|
2945
|
-
if (!autoTopic) {
|
|
2946
|
-
logger.debug(`Ignoring group message not addressed to bot: ${messageId}`);
|
|
2947
|
-
return;
|
|
2948
|
-
}
|
|
2949
|
-
logger.info(`[auto-start:新话题] ${chatId.substring(0, 12)} 新话题免@自动开工 msg=${messageId.substring(0, 12)}`);
|
|
2950
|
-
}
|
|
2951
|
-
}
|
|
2952
|
-
}
|
|
2953
|
-
else if (!isAllowed) {
|
|
2954
|
-
// 私聊被挡目前是静默丢弃:owner 不在这个 p2p 会话里,把授权申请卡 reply 回来只会
|
|
2955
|
-
// 发给陌生人自己(卡上的按钮又是 owner 专属),既不可用又泄露 owner —— 所以不发。
|
|
2956
|
-
// 真正的修法是把申请发到 owner 自己的 DM 并加 owner 维度节流,单独一个 PR 做。
|
|
2957
|
-
logger.debug(`Ignoring p2p message from non-allowed user: ${senderOpenId}`);
|
|
2958
|
-
return;
|
|
2959
|
-
}
|
|
2960
|
-
const promptOverride = summaryCommandTriggered && summaryCommandMatch
|
|
2961
|
-
? await buildSummaryCommandPrompt({ larkAppId, chatId, message, match: summaryCommandMatch })
|
|
2962
|
-
: undefined;
|
|
2963
|
-
if (promptOverride && summaryCommandMatch) {
|
|
2964
|
-
logger.info(`[summary-command] matched msg=${messageId.substring(0, 12)} ` +
|
|
2965
|
-
`chat=${chatId.substring(0, 12)} kind=${summaryCommandMatch.chatKind}`);
|
|
2966
|
-
}
|
|
2967
|
-
const ctx = {
|
|
2968
|
-
chatId,
|
|
2969
|
-
messageId,
|
|
2970
|
-
chatType,
|
|
2971
|
-
larkAppId,
|
|
2972
|
-
...routing,
|
|
2973
|
-
replyRootId,
|
|
2974
|
-
promptOverride,
|
|
2975
|
-
summaryCommand: summaryCommandTriggered && summaryCommandMatch
|
|
2976
|
-
? { name: 'summary-command', chatKind: summaryCommandMatch.chatKind }
|
|
2977
|
-
: undefined,
|
|
2978
|
-
substituteTrigger,
|
|
2979
|
-
messageListener,
|
|
2980
|
-
forwardSeedData: pairedForwardSeed?.payload.data,
|
|
2981
|
-
};
|
|
2982
|
-
if (explicitlyMentionedThisBot) {
|
|
2983
|
-
const before = await handlers.beforeSessionTurn?.(data, ctx, { senderOpenId, explicitlyMentionedThisBot });
|
|
2984
|
-
if (before?.block)
|
|
2985
|
-
return;
|
|
2986
|
-
if (before?.anchorOverride)
|
|
2987
|
-
ctx.anchor = before.anchorOverride;
|
|
2988
|
-
ownsSession = handlers.isSessionOwner?.(ctx.anchor, larkAppId) ?? ownsSession;
|
|
2989
|
-
}
|
|
2990
|
-
const payload = { data, ctx, ownsSession };
|
|
2991
|
-
const groupMentionMode = resolveGroupMentionMode(larkAppId);
|
|
2992
|
-
const shouldDelayTopicSeed = usesForwardFollowupDelay(groupMentionMode)
|
|
2993
|
-
&& !pairedForwardSeed
|
|
2994
|
-
&& !isControlCommand
|
|
2995
|
-
&& !!senderOpenId
|
|
2996
|
-
&& routingSource === 'topic-chat'
|
|
2997
|
-
&& ctx.scope === 'thread'
|
|
2998
|
-
&& ctx.anchor === messageId
|
|
2999
|
-
&& !ownsSession;
|
|
3000
|
-
if (shouldDelayTopicSeed) {
|
|
3001
|
-
try {
|
|
3002
|
-
putForwardFollowup(larkAppId, {
|
|
3003
|
-
messageId,
|
|
3004
|
-
dueAt: Date.now() + config.daemon.forwardFollowupWaitMs,
|
|
3005
|
-
payload,
|
|
3006
|
-
});
|
|
3007
|
-
if (forwardFollowups.hold({
|
|
3008
|
-
larkAppId,
|
|
3009
|
-
chatId,
|
|
3010
|
-
senderOpenId,
|
|
3011
|
-
messageId,
|
|
3012
|
-
payload,
|
|
3013
|
-
flush: delayedPayload => dispatchPersistedForwardFollowup(messageId, delayedPayload),
|
|
3014
|
-
})) {
|
|
3015
|
-
logger.debug(`[forward-followup] holding topic seed msg=${messageId.substring(0, 12)} ` +
|
|
3016
|
-
`for ${config.daemon.forwardFollowupWaitMs}ms`);
|
|
3017
|
-
return;
|
|
3018
|
-
}
|
|
3019
|
-
removeForwardFollowup(larkAppId, messageId);
|
|
3020
|
-
}
|
|
3021
|
-
catch (err) {
|
|
3022
|
-
logger.warn(`[forward-followup] persistence unavailable, dispatching immediately: ${err}`);
|
|
3023
|
-
}
|
|
3024
|
-
}
|
|
3025
|
-
if (pairedForwardSeed) {
|
|
3026
|
-
try {
|
|
3027
|
-
putForwardFollowup(larkAppId, {
|
|
3028
|
-
messageId: pairedForwardSeed.messageId,
|
|
3029
|
-
dueAt: Date.now(),
|
|
3030
|
-
payload,
|
|
3031
|
-
});
|
|
3032
|
-
}
|
|
3033
|
-
catch (err) {
|
|
3034
|
-
logger.warn(`[forward-followup] failed to persist paired payload before dispatch: ${err}`);
|
|
3035
|
-
}
|
|
3036
|
-
await dispatchPersistedForwardFollowup(pairedForwardSeed.messageId, payload)
|
|
3037
|
-
.catch(err => logger.error(`Error handling paired message event: ${err}`));
|
|
3038
|
-
return;
|
|
3039
|
-
}
|
|
3040
|
-
// Serialize per anchor so two messages to the same thread/chat are
|
|
3041
|
-
// processed in arrival order — never concurrently. Without this a fast
|
|
3042
|
-
// second message interleaves with the first's async session-spawn and is
|
|
3043
|
-
// dropped (worker-not-ready → re-fork branch). See anchor-serializer.ts.
|
|
3044
|
-
await dispatchHumanMessage(payload)
|
|
3045
|
-
.catch(err => logger.error(`Error handling message event: ${err}`));
|
|
3046
|
-
}
|
|
3047
|
-
catch (err) {
|
|
3048
|
-
logger.error(`Error handling message event: ${err}`);
|
|
3049
|
-
}
|
|
3050
|
-
finally {
|
|
3051
|
-
seedRoutingGate?.complete();
|
|
3052
|
-
}
|
|
3053
|
-
}
|
|
3054
|
-
/** 授权成功后重放之前被拦截的消息,让用户无需再 @ 一遍。
|
|
3055
|
-
* 绕过消息去重(原消息在拦截时已 claim 过),直接重新走消息处理流程。
|
|
3056
|
-
* 用 setImmediate 异步执行,不阻塞卡片回调。 */
|
|
3057
|
-
function replayMessageEvent(data) {
|
|
3058
|
-
setImmediate(() => {
|
|
3059
|
-
void processMessageEvent(data)
|
|
3060
|
-
.catch(err => logger.error(`Error replaying message event after grant: ${err}`));
|
|
3061
|
-
});
|
|
3062
|
-
}
|
|
3063
|
-
// 暴露给 daemon 的 cardDeps.replayGrantedMessage 调用。
|
|
3064
|
-
handlers.replayMessageEvent = replayMessageEvent;
|
|
3065
|
-
const eventDispatcher = new Lark.EventDispatcher({}).register({
|
|
3066
|
-
// 主动开工 — 场景①: the bot was added to a chat. Hand off to the daemon,
|
|
3067
|
-
// which gates on the autoStartOnGroupJoin toggle + allowedUser membership.
|
|
3068
|
-
// Requires this event to be subscribed for the app in the Feishu console.
|
|
3069
|
-
'im.chat.member.bot.added_v1': (data) => {
|
|
3070
|
-
const chatIdForKey = data?.chat_id;
|
|
3071
|
-
const operatorForKey = data?.operator_id?.open_id;
|
|
3072
|
-
const eventKey = `im.chat.member.bot.added_v1:${larkAppId}:${eventIdForKey(data) ?? `${chatIdForKey ?? 'unknown'}:${operatorForKey ?? 'unknown'}`}`;
|
|
3073
|
-
// 飞书只把 bot.added 推给「进群的那个 bot 自己的 app」(官方文档语義,
|
|
3074
|
-
// codex 复审证实),且生产是 PM2「一 bot 一 daemon 进程」(daemon.ts
|
|
3075
|
-
// "Load the assigned bot (one daemon per bot)")——同群其他 bot 的缓存在
|
|
3076
|
-
// 别的进程,这里够不到,只能清自己的 key。覆盖增量其实很小:新添进群
|
|
3077
|
-
// 时本 bot 此前若恰有该群条目(曾被移出又拉回),避免带着上轮陈旧数放行。
|
|
3078
|
-
// 「拉了别的 bot 进群→存量 bot 陈旧」方向无事件信号,靠 relax 末条款的
|
|
3079
|
-
// mentionsAnotherMember 守卫 + TTL 兜底。
|
|
3080
|
-
if (chatIdForKey)
|
|
3081
|
-
invalidateChatStats(larkAppId, chatIdForKey);
|
|
3082
|
-
scheduleAckSafeEvent(eventKey, async () => {
|
|
3083
|
-
try {
|
|
3084
|
-
const chatId = data?.chat_id;
|
|
3085
|
-
const operatorOpenId = data?.operator_id?.open_id;
|
|
3086
|
-
if (!chatId)
|
|
3087
|
-
return;
|
|
3088
|
-
logger.info(`[auto-start:入群] bot added to chat=${chatId.substring(0, 12)} by ${String(operatorOpenId ?? '?').substring(0, 12)}`);
|
|
3089
|
-
// 进群先自动拉 owner(不受任何开工开关影响,失败仅日志):bot 应始终
|
|
3090
|
-
// 处于 owner 可见的群里。放在 handleBotAdded 之前,让 autoStart 的
|
|
3091
|
-
// D7「群内需有 allowedUser」闸能吃到刚拉进来的 owner。
|
|
3092
|
-
await autoInviteOwnerOnGroupJoin(larkAppId, chatId, operatorOpenId)
|
|
3093
|
-
.catch(err => logger.warn(`[groups] autoInviteOwner error (bot=${larkAppId} chat=${chatId}): ${err?.message ?? err}`));
|
|
3094
|
-
await handlers.handleBotAdded?.(chatId, operatorOpenId, larkAppId);
|
|
3095
|
-
}
|
|
3096
|
-
catch (err) {
|
|
3097
|
-
logger.error(`Error handling bot-added event: ${err}`);
|
|
3098
|
-
}
|
|
3099
|
-
}, 'bot-added event');
|
|
3100
|
-
},
|
|
3101
|
-
// bot.deleted 同样只推给被移出的 bot 自己的 app——清自己的 key 即可(语义
|
|
3102
|
-
// 同 bot.added:进程边界上够不到兄弟 daemon;「别的 bot 离群→存量 bot
|
|
3103
|
-
// 陈旧」靠①守卫+TTL)。user.added/deleted_v1 推给群内已订阅的所有 bot
|
|
3104
|
-
// app,每个 bot 自己的 WS 都收到,各自清自己那条。纯本地 map 删除,同步
|
|
3105
|
-
// 处理、即时 ACK,不进 work 队列;去重也不必要——失效是幂等的。
|
|
3106
|
-
'im.chat.member.bot.deleted_v1': (data) => {
|
|
3107
|
-
const chatId = data?.chat_id;
|
|
3108
|
-
if (chatId)
|
|
3109
|
-
invalidateChatStats(larkAppId, chatId);
|
|
3110
|
-
},
|
|
3111
|
-
'im.chat.member.user.added_v1': (data) => {
|
|
3112
|
-
const chatId = data?.chat_id;
|
|
3113
|
-
if (chatId)
|
|
3114
|
-
invalidateChatStats(larkAppId, chatId);
|
|
3115
|
-
},
|
|
3116
|
-
'im.chat.member.user.deleted_v1': (data) => {
|
|
3117
|
-
const chatId = data?.chat_id;
|
|
3118
|
-
if (chatId)
|
|
3119
|
-
invalidateChatStats(larkAppId, chatId);
|
|
3120
|
-
},
|
|
3121
|
-
// 文档评论入口(/watch-comment / /subscribe-lark-doc)。notice 事件主要覆盖 @Bot
|
|
3122
|
-
// 通知;普通评论由 daemon 应用身份轮询补齐,不依赖逐文件 subscribe API。
|
|
3123
|
-
'drive.notice.comment_add_v1': (data) => handleCommentEventAckSafe(data, larkAppId, handlers),
|
|
3124
|
-
[VC_BOT_MEETING_INVITED_EVENT]: (data) => handleVcMeetingPushEventAckSafe(data, larkAppId, handlers, 'meeting_invited', VC_BOT_MEETING_INVITED_EVENT),
|
|
3125
|
-
[VC_BOT_MEETING_ACTIVITY_EVENT]: (data) => handleVcMeetingPushEventAckSafe(data, larkAppId, handlers, 'meeting_activity', VC_BOT_MEETING_ACTIVITY_EVENT),
|
|
3126
|
-
[VC_BOT_MEETING_ENDED_EVENT]: (data) => handleVcMeetingPushEventAckSafe(data, larkAppId, handlers, 'meeting_ended', VC_BOT_MEETING_ENDED_EVENT),
|
|
3127
|
-
[VC_PARTICIPANT_MEETING_JOINED_EVENT]: (data) => handleVcMeetingPushEventAckSafe(data, larkAppId, handlers, 'participant_meeting_joined', VC_PARTICIPANT_MEETING_JOINED_EVENT),
|
|
3128
|
-
'card.action.trigger': (data) => handleCardActionAckSafe(data, larkAppId, handlers),
|
|
3129
|
-
// 表情回复事件——一旦在开发者后台订阅了 reaction,SDK 每收到一次都会因
|
|
3130
|
-
// 没有 handler 打 "no im.message.reaction.created_v1 handle" 警告刷屏。
|
|
3131
|
-
// botmux 不消费表情事件,注册显式 no-op 把这条噪声静默掉。
|
|
3132
|
-
'im.message.reaction.created_v1': () => { },
|
|
3133
|
-
'im.message.reaction.deleted_v1': () => { },
|
|
3134
|
-
'im.message.receive_v1': (data) => {
|
|
3135
|
-
// Dedupe by message_id (stable across re-pushes / event_id re-mints /
|
|
3136
|
-
// daemon restarts), persisted so the 6h re-push tier or a restart can't
|
|
3137
|
-
// replay an already-handled message. Fall back to the in-memory event-id
|
|
3138
|
-
// claim only when message_id is absent (shouldn't happen for real messages).
|
|
3139
|
-
const messageIdForKey = data?.message?.message_id;
|
|
3140
|
-
const eventKey = `im.message.receive_v1:${larkAppId}:${messageIdForKey ?? eventIdForKey(data) ?? unkeyableEventKey()}`;
|
|
3141
|
-
const claim = messageIdForKey
|
|
3142
|
-
? () => claimMessageOnce(larkAppId, messageIdForKey)
|
|
3143
|
-
: () => claimEventOnce(eventKey);
|
|
3144
|
-
let seedRoutingGate;
|
|
3145
|
-
const scheduled = scheduleAckSafeEvent(eventKey, () => processMessageEvent(data, seedRoutingGate), 'message event', claim);
|
|
3146
|
-
const rawMessage = data?.message;
|
|
3147
|
-
const rawSenderType = data?.sender?.sender_type;
|
|
3148
|
-
if (scheduled
|
|
3149
|
-
&& config.daemon.forwardFollowupWaitMs > 0
|
|
3150
|
-
&& rawMessage?.message_id
|
|
3151
|
-
&& rawMessage.chat_type !== 'p2p'
|
|
3152
|
-
&& !rawMessage.root_id
|
|
3153
|
-
&& !rawMessage.thread_id
|
|
3154
|
-
&& rawSenderType !== 'app'
|
|
3155
|
-
&& rawSenderType !== 'bot') {
|
|
3156
|
-
seedRoutingGate = registerSeedRoutingGate(rawMessage.message_id);
|
|
3157
|
-
}
|
|
3158
|
-
},
|
|
3159
|
-
});
|
|
3160
|
-
// 诊断:包一层 invoke,记录长连接收到的**每一个**事件类型(含未注册的)。
|
|
3161
|
-
// 排查云文档评论事件是否真送达 / 实际事件名用——comment 类一律连 payload 关键字段
|
|
3162
|
-
// 一起打。日常其它事件只在 DEBUG 下打,避免刷屏。
|
|
3163
|
-
// 仅当 dispatcher 真有 invoke 方法时才包(单测里 Lark.EventDispatcher 是 mock,
|
|
3164
|
-
// register() 返回的对象没有 invoke → 不包,避免 undefined.bind 抛错)。
|
|
3165
|
-
const __origInvoke = typeof eventDispatcher.invoke === 'function'
|
|
3166
|
-
? eventDispatcher.invoke.bind(eventDispatcher)
|
|
3167
|
-
: undefined;
|
|
3168
|
-
if (__origInvoke) {
|
|
3169
|
-
eventDispatcher.invoke = (data) => {
|
|
3170
|
-
try {
|
|
3171
|
-
const et = data?.header?.event_type ?? data?.event_type ?? data?.type ?? 'unknown';
|
|
3172
|
-
const isCommentish = typeof et === 'string' && et.includes('comment');
|
|
3173
|
-
const isVcMeeting = typeof et === 'string' && (et.startsWith('vc.bot.meeting_') || et === VC_PARTICIPANT_MEETING_JOINED_EVENT);
|
|
3174
|
-
if (isCommentish) {
|
|
3175
|
-
const ev = data?.event ?? data;
|
|
3176
|
-
const p = parseCommentEvent(data);
|
|
3177
|
-
logger.info(`[ws-event] ${larkAppId} event_type=${et} → parsed fileToken=${p.fileToken ?? '?'} commentId=${p.commentId ?? '?'} replyId=${p.replyId ?? '?'} isMentioned=${p.isMentioned} | notice_meta=${JSON.stringify(ev?.notice_meta ?? ev?.noticeMeta ?? null)}`);
|
|
3178
|
-
}
|
|
3179
|
-
else if (isVcMeeting) {
|
|
3180
|
-
const kind = et === VC_BOT_MEETING_INVITED_EVENT
|
|
3181
|
-
? 'meeting_invited'
|
|
3182
|
-
: et === VC_BOT_MEETING_ENDED_EVENT
|
|
3183
|
-
? 'meeting_ended'
|
|
3184
|
-
: et === VC_PARTICIPANT_MEETING_JOINED_EVENT
|
|
3185
|
-
? 'participant_meeting_joined'
|
|
3186
|
-
: 'meeting_activity';
|
|
3187
|
-
const parsed = parseVcMeetingPushEvent({ data, larkAppId, kind, eventType: et });
|
|
3188
|
-
logger.info(`[ws-event] ${larkAppId} event_type=${et} eventId=${parsed.eventId ?? '?'} meetingId=${parsed.meeting.id || '?'} items=${Array.isArray((data?.event ?? data)?.meeting_actitivty_items) ? (data?.event ?? data).meeting_actitivty_items.length : '?'}`);
|
|
3189
|
-
if (et === VC_BOT_MEETING_ACTIVITY_EVENT && process.env.DEBUG) {
|
|
3190
|
-
logger.info(`[ws-event:raw] ${larkAppId} event_type=${et} eventId=${parsed.eventId ?? '?'} payload=${vcMeetingEventPayloadForLog(data)}`);
|
|
3191
|
-
}
|
|
3192
|
-
}
|
|
3193
|
-
else if (process.env.DEBUG) {
|
|
3194
|
-
logger.info(`[ws-event] ${larkAppId} event_type=${et}`);
|
|
3195
|
-
}
|
|
3196
|
-
}
|
|
3197
|
-
catch { /* 诊断不阻断分发 */ }
|
|
3198
|
-
return __origInvoke(data);
|
|
3199
|
-
};
|
|
3200
|
-
}
|
|
3201
|
-
// Start WSClient
|
|
3202
|
-
const wsClient = new Lark.WSClient({
|
|
3203
|
-
appId: larkAppId,
|
|
3204
|
-
appSecret: larkAppSecret,
|
|
3205
|
-
// brand → 长连接域名。国际版租户必须连 larksuite.com,否则收不到任何事件。
|
|
3206
|
-
domain: sdkDomain(brand),
|
|
3207
|
-
// `proxy-from-env` treats WSS_PROXY as distinct from HTTPS_PROXY, while
|
|
3208
|
-
// Lark's preceding Axios bootstrap request uses HTTPS proxy semantics.
|
|
3209
|
-
// The custom resolver keeps both phases aligned and still honors NO_PROXY.
|
|
3210
|
-
agent: createLarkWsAgent(),
|
|
3211
|
-
// Default to warn — the SDK is chatty at info ("client ready", reconnect
|
|
3212
|
-
// heartbeats, etc.) and floods pm2 error.log when stderr is the only sink.
|
|
3213
|
-
// DEBUG=1 widens the level back to info for troubleshooting.
|
|
3214
|
-
loggerLevel: process.env.DEBUG ? Lark.LoggerLevel.info : Lark.LoggerLevel.warn,
|
|
3215
|
-
// 主机长断网(夜间合盖睡眠、Wi-Fi 切换、VPN 重连)后,SDK 重连要先用 HTTPS 去
|
|
3216
|
-
// 飞书换 ws 接入点,这步会 ENOTFOUND / 15s 超时;重连次数由服务端下发且有限,
|
|
3217
|
-
// 耗尽后 SDK 置 terminalError 永久放弃,但进程仍 online、PM2 不会兜底 —— 表现为
|
|
3218
|
-
// 「必须手动 botmux restart 才能恢复收消息」。下面两道防线让长连接死后自愈。
|
|
3219
|
-
//
|
|
3220
|
-
// ① pingTimeout:发 ping 后 30s 内无任何 inbound 帧即掐断 socket,触发 close →
|
|
3221
|
-
// SDK 自身重连。专治 TCP 半开连接(没收到 FIN/RST、close 事件不触发)的静默卡死。
|
|
3222
|
-
wsConfig: { pingTimeout: 30 },
|
|
3223
|
-
// 重连握手卡死(DNS/代理/NAT)兜底,避免单次握手永久 pending。
|
|
3224
|
-
handshakeTimeoutMs: 15_000,
|
|
3225
|
-
// 重连过程打日志,便于事后从 `pnpm daemon:logs` 复盘(warn 默认看不到这些)。
|
|
3226
|
-
onReconnecting: () => logger.warn(`[ws] ${larkAppId} reconnecting…`),
|
|
3227
|
-
onReconnected: () => logger.info(`[ws] ${larkAppId} reconnected`),
|
|
3228
|
-
onError: (err) => logger.error(`[ws] ${larkAppId} terminal error: ${err.message}`),
|
|
3229
|
-
});
|
|
3230
|
-
wsClient.start({ eventDispatcher });
|
|
3231
|
-
logger.info('Daemon WSClient started');
|
|
3232
|
-
let listenerPollInFlight = false;
|
|
3233
|
-
const listenerPollTimer = setInterval(() => {
|
|
3234
|
-
if (listenerPollInFlight)
|
|
3235
|
-
return;
|
|
3236
|
-
listenerPollInFlight = true;
|
|
3237
|
-
void pollMessageListenersOnce(larkAppId, handlers)
|
|
3238
|
-
.catch(err => logger.error(`[message-listener:${larkAppId}] poll failed: ${err instanceof Error ? err.message : String(err)}`))
|
|
3239
|
-
.finally(() => { listenerPollInFlight = false; });
|
|
3240
|
-
}, MESSAGE_LISTENER_POLL_INTERVAL_MS);
|
|
3241
|
-
listenerPollTimer.unref();
|
|
3242
|
-
const hasListenerBackfill = enabledMessageListenerChatIds(getBot(larkAppId)).length > 0;
|
|
3243
|
-
if (hasListenerBackfill) {
|
|
3244
|
-
setTimeout(() => {
|
|
3245
|
-
if (listenerPollInFlight)
|
|
3246
|
-
return;
|
|
3247
|
-
listenerPollInFlight = true;
|
|
3248
|
-
void pollMessageListenersOnce(larkAppId, handlers)
|
|
3249
|
-
.catch(err => logger.error(`[message-listener:${larkAppId}] initial poll failed: ${err instanceof Error ? err.message : String(err)}`))
|
|
3250
|
-
.finally(() => { listenerPollInFlight = false; });
|
|
3251
|
-
}, 2_000).unref();
|
|
3252
|
-
logger.info(`[message-listener:${larkAppId}] polling backfill enabled interval=${MESSAGE_LISTENER_POLL_INTERVAL_MS}ms ` +
|
|
3253
|
-
`window=${MESSAGE_LISTENER_BACKFILL_WINDOW_MS}ms chats=${enabledMessageListenerChatIds(getBot(larkAppId)).length}`);
|
|
3254
|
-
}
|
|
3255
|
-
// ② SDK 重连耗尽后停在 terminalError(getConnectionStatus().state === 'failed')并
|
|
3256
|
-
// 永久放弃。每分钟探测一次,发现已放弃就 start() 重新发起一轮全新握手 —— start()
|
|
3257
|
-
// 会清掉 terminalError 并重新 pullConnectConfig + connect,无需手动重启 daemon。
|
|
3258
|
-
// 只在 'failed' 时介入,不打断 SDK 正在进行的 'reconnecting' / 'connecting'。
|
|
3259
|
-
let reviving = false;
|
|
3260
|
-
const reviveTimer = setInterval(() => {
|
|
3261
|
-
if (reviving)
|
|
3262
|
-
return;
|
|
3263
|
-
if (wsClient.getConnectionStatus().state !== 'failed')
|
|
3264
|
-
return;
|
|
3265
|
-
reviving = true;
|
|
3266
|
-
logger.warn(`[ws] ${larkAppId} connection failed (reconnect exhausted), restarting WSClient`);
|
|
3267
|
-
wsClient.start({ eventDispatcher })
|
|
3268
|
-
.catch(err => logger.error(`[ws] ${larkAppId} WSClient restart failed: ${err?.message ?? err}`))
|
|
3269
|
-
.finally(() => { reviving = false; });
|
|
3270
|
-
}, 60_000);
|
|
3271
|
-
reviveTimer.unref();
|
|
3272
|
-
return wsClient;
|
|
3273
|
-
}
|
|
3274
|
-
//# sourceMappingURL=event-dispatcher.js.map
|