@wrongstack/core 0.284.1 → 0.286.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-status-tracker.d.ts +74 -0
- package/dist/agent-status-tracker.d.ts.map +1 -0
- package/dist/autophase/auto-phase-planner.d.ts +79 -0
- package/dist/autophase/auto-phase-planner.d.ts.map +1 -0
- package/dist/autophase/auto-phase-runner.d.ts +79 -0
- package/dist/autophase/auto-phase-runner.d.ts.map +1 -0
- package/dist/autophase/checkpoint.d.ts +49 -0
- package/dist/autophase/checkpoint.d.ts.map +1 -0
- package/dist/autophase/index.d.ts +9 -0
- package/dist/autophase/index.d.ts.map +1 -0
- package/dist/autophase/phase-graph-builder.d.ts +46 -0
- package/dist/autophase/phase-graph-builder.d.ts.map +1 -0
- package/dist/autophase/phase-orchestrator.d.ts +150 -0
- package/dist/autophase/phase-orchestrator.d.ts.map +1 -0
- package/dist/autophase/phase-store.d.ts +29 -0
- package/dist/autophase/phase-store.d.ts.map +1 -0
- package/dist/autophase/types.d.ts +329 -0
- package/dist/autophase/types.d.ts.map +1 -0
- package/dist/boot.d.ts +73 -0
- package/dist/boot.d.ts.map +1 -0
- package/dist/coordination/adaptive-concurrency.d.ts +63 -0
- package/dist/coordination/adaptive-concurrency.d.ts.map +1 -0
- package/dist/coordination/agent-bridge.d.ts +24 -0
- package/dist/coordination/agent-bridge.d.ts.map +1 -0
- package/dist/coordination/agent-monitor.d.ts +129 -0
- package/dist/coordination/agent-monitor.d.ts.map +1 -0
- package/dist/coordination/agent-subagent-runner.d.ts +74 -0
- package/dist/coordination/agent-subagent-runner.d.ts.map +1 -0
- package/dist/coordination/agents/agent-prompts.d.ts +2 -0
- package/dist/coordination/agents/agent-prompts.d.ts.map +1 -0
- package/dist/coordination/agents/index.d.ts +35 -0
- package/dist/coordination/agents/index.d.ts.map +1 -0
- package/dist/coordination/agents/phase1-discovery.d.ts +4 -0
- package/dist/coordination/agents/phase1-discovery.d.ts.map +1 -0
- package/dist/coordination/agents/phase2-planning.d.ts +4 -0
- package/dist/coordination/agents/phase2-planning.d.ts.map +1 -0
- package/dist/coordination/agents/phase3-build.d.ts +4 -0
- package/dist/coordination/agents/phase3-build.d.ts.map +1 -0
- package/dist/coordination/agents/phase3-techstack.d.ts +13 -0
- package/dist/coordination/agents/phase3-techstack.d.ts.map +1 -0
- package/dist/coordination/agents/phase4-verify.d.ts +4 -0
- package/dist/coordination/agents/phase4-verify.d.ts.map +1 -0
- package/dist/coordination/agents/phase5-review.d.ts +4 -0
- package/dist/coordination/agents/phase5-review.d.ts.map +1 -0
- package/dist/coordination/agents/phase6-domain.d.ts +4 -0
- package/dist/coordination/agents/phase6-domain.d.ts.map +1 -0
- package/dist/coordination/agents/phase7-knowledge.d.ts +4 -0
- package/dist/coordination/agents/phase7-knowledge.d.ts.map +1 -0
- package/dist/coordination/agents/phase8-delivery.d.ts +4 -0
- package/dist/coordination/agents/phase8-delivery.d.ts.map +1 -0
- package/dist/coordination/agents/phase9-meta.d.ts +4 -0
- package/dist/coordination/agents/phase9-meta.d.ts.map +1 -0
- package/dist/coordination/agents/types.d.ts +79 -0
- package/dist/coordination/agents/types.d.ts.map +1 -0
- package/dist/coordination/agents.d.ts +8 -0
- package/dist/coordination/agents.d.ts.map +1 -0
- package/dist/coordination/auto-extend.d.ts +46 -0
- package/dist/coordination/auto-extend.d.ts.map +1 -0
- package/dist/coordination/autonomous-brain.d.ts +152 -0
- package/dist/coordination/autonomous-brain.d.ts.map +1 -0
- package/dist/coordination/autonomous-coordinator.d.ts +243 -0
- package/dist/coordination/autonomous-coordinator.d.ts.map +1 -0
- package/dist/coordination/brain-ledger.d.ts +142 -0
- package/dist/coordination/brain-ledger.d.ts.map +1 -0
- package/dist/coordination/brain-monitor.d.ts +103 -0
- package/dist/coordination/brain-monitor.d.ts.map +1 -0
- package/dist/coordination/brain.d.ts +147 -0
- package/dist/coordination/brain.d.ts.map +1 -0
- package/dist/coordination/change-manager.d.ts +151 -0
- package/dist/coordination/change-manager.d.ts.map +1 -0
- package/dist/coordination/checkpoint-wiring.d.ts +61 -0
- package/dist/coordination/checkpoint-wiring.d.ts.map +1 -0
- package/dist/coordination/collab-bus.d.ts +132 -0
- package/dist/coordination/collab-bus.d.ts.map +1 -0
- package/dist/coordination/collab-debug.d.ts +302 -0
- package/dist/coordination/collab-debug.d.ts.map +1 -0
- package/dist/coordination/commit-safety.d.ts +72 -0
- package/dist/coordination/commit-safety.d.ts.map +1 -0
- package/dist/coordination/consensus-protocol.d.ts +106 -0
- package/dist/coordination/consensus-protocol.d.ts.map +1 -0
- package/dist/coordination/coordinator/error-classifier.d.ts +15 -0
- package/dist/coordination/coordinator/error-classifier.d.ts.map +1 -0
- package/dist/coordination/delegate-tool.d.ts +101 -0
- package/dist/coordination/delegate-tool.d.ts.map +1 -0
- package/dist/coordination/dep-watcher-bridge.d.ts +47 -0
- package/dist/coordination/dep-watcher-bridge.d.ts.map +1 -0
- package/dist/coordination/dep-watcher.d.ts +74 -0
- package/dist/coordination/dep-watcher.d.ts.map +1 -0
- package/dist/coordination/director/director-errors.d.ts +29 -0
- package/dist/coordination/director/director-errors.d.ts.map +1 -0
- package/dist/coordination/director-construction.d.ts +90 -0
- package/dist/coordination/director-construction.d.ts.map +1 -0
- package/dist/coordination/director-prompts.d.ts +119 -0
- package/dist/coordination/director-prompts.d.ts.map +1 -0
- package/dist/coordination/director-session.d.ts +68 -0
- package/dist/coordination/director-session.d.ts.map +1 -0
- package/dist/coordination/director-tools.d.ts +65 -0
- package/dist/coordination/director-tools.d.ts.map +1 -0
- package/dist/coordination/director.d.ts +802 -0
- package/dist/coordination/director.d.ts.map +1 -0
- package/dist/coordination/dispatcher.d.ts +82 -0
- package/dist/coordination/dispatcher.d.ts.map +1 -0
- package/dist/coordination/file-author-tracker.d.ts +76 -0
- package/dist/coordination/file-author-tracker.d.ts.map +1 -0
- package/dist/coordination/fleet-bus.d.ts +122 -0
- package/dist/coordination/fleet-bus.d.ts.map +1 -0
- package/dist/coordination/fleet-event-validation.d.ts +10 -0
- package/dist/coordination/fleet-event-validation.d.ts.map +1 -0
- package/dist/coordination/fleet-manager.d.ts +234 -0
- package/dist/coordination/fleet-manager.d.ts.map +1 -0
- package/dist/coordination/fleet-spawn.d.ts +102 -0
- package/dist/coordination/fleet-spawn.d.ts.map +1 -0
- package/dist/coordination/fleet-status-tool.d.ts +36 -0
- package/dist/coordination/fleet-status-tool.d.ts.map +1 -0
- package/dist/coordination/fleet-supervisor.d.ts +157 -0
- package/dist/coordination/fleet-supervisor.d.ts.map +1 -0
- package/dist/coordination/fleet.d.ts +96 -0
- package/dist/coordination/fleet.d.ts.map +1 -0
- package/dist/coordination/global-mailbox.d.ts +295 -0
- package/dist/coordination/global-mailbox.d.ts.map +1 -0
- package/dist/coordination/icoordinator.d.ts +97 -0
- package/dist/coordination/icoordinator.d.ts.map +1 -0
- package/dist/coordination/ifleet-manager.d.ts +177 -0
- package/dist/coordination/ifleet-manager.d.ts.map +1 -0
- package/dist/coordination/in-memory-transport.d.ts +12 -0
- package/dist/coordination/in-memory-transport.d.ts.map +1 -0
- package/dist/coordination/index.d.ts +79 -2587
- package/dist/coordination/index.d.ts.map +1 -0
- package/dist/coordination/index.js +2262 -673
- package/dist/coordination/index.js.map +7 -1
- package/dist/coordination/knowledge-graph.d.ts +229 -0
- package/dist/coordination/knowledge-graph.d.ts.map +1 -0
- package/dist/coordination/large-answer-store.d.ts +61 -0
- package/dist/coordination/large-answer-store.d.ts.map +1 -0
- package/dist/coordination/mail-tools.d.ts +34 -0
- package/dist/coordination/mail-tools.d.ts.map +1 -0
- package/dist/coordination/mailbox-actions.d.ts +67 -0
- package/dist/coordination/mailbox-actions.d.ts.map +1 -0
- package/dist/coordination/mailbox-constants.d.ts +64 -0
- package/dist/coordination/mailbox-constants.d.ts.map +1 -0
- package/dist/coordination/mailbox-events.d.ts +32 -0
- package/dist/coordination/mailbox-events.d.ts.map +1 -0
- package/dist/coordination/mailbox-health.d.ts +131 -0
- package/dist/coordination/mailbox-health.d.ts.map +1 -0
- package/dist/coordination/mailbox-hooks.d.ts +55 -0
- package/dist/coordination/mailbox-hooks.d.ts.map +1 -0
- package/dist/coordination/mailbox-message-codec.d.ts +8 -0
- package/dist/coordination/mailbox-message-codec.d.ts.map +1 -0
- package/dist/coordination/mailbox-tool.d.ts +75 -0
- package/dist/coordination/mailbox-tool.d.ts.map +1 -0
- package/dist/{mailbox-types-BGZWrYTJ.d.ts → coordination/mailbox-types.d.ts} +125 -26
- package/dist/coordination/mailbox-types.d.ts.map +1 -0
- package/dist/coordination/mailbox.d.ts +88 -0
- package/dist/coordination/mailbox.d.ts.map +1 -0
- package/dist/coordination/model-matrix.d.ts +98 -0
- package/dist/coordination/model-matrix.d.ts.map +1 -0
- package/dist/coordination/multi-agent-coordinator.d.ts +202 -0
- package/dist/coordination/multi-agent-coordinator.d.ts.map +1 -0
- package/dist/coordination/null-fleet-bus.d.ts +10 -0
- package/dist/coordination/null-fleet-bus.d.ts.map +1 -0
- package/dist/coordination/package-author-tracker.d.ts +87 -0
- package/dist/coordination/package-author-tracker.d.ts.map +1 -0
- package/dist/coordination/package-outdated-watcher.d.ts +83 -0
- package/dist/coordination/package-outdated-watcher.d.ts.map +1 -0
- package/dist/coordination/single-instance-mailbox.d.ts +154 -0
- package/dist/coordination/single-instance-mailbox.d.ts.map +1 -0
- package/dist/coordination/spawn-budget.d.ts +6 -0
- package/dist/coordination/spawn-budget.d.ts.map +1 -0
- package/dist/coordination/subagent-budget.d.ts +323 -0
- package/dist/coordination/subagent-budget.d.ts.map +1 -0
- package/dist/coordination/subagent-nicknames.d.ts +42 -0
- package/dist/coordination/subagent-nicknames.d.ts.map +1 -0
- package/dist/coordination/subagent-result-tool.d.ts +20 -0
- package/dist/coordination/subagent-result-tool.d.ts.map +1 -0
- package/dist/coordination/task-auctioneer.d.ts +143 -0
- package/dist/coordination/task-auctioneer.d.ts.map +1 -0
- package/dist/coordination/task-dag.d.ts +147 -0
- package/dist/coordination/task-dag.d.ts.map +1 -0
- package/dist/coordination/techstack-mailbox-consumer.d.ts +50 -0
- package/dist/coordination/techstack-mailbox-consumer.d.ts.map +1 -0
- package/dist/coordination/transport.d.ts +2 -0
- package/dist/coordination/transport.d.ts.map +1 -0
- package/dist/coordination/worktree-task-runner.d.ts +45 -0
- package/dist/coordination/worktree-task-runner.d.ts.map +1 -0
- package/dist/core/agent-internals.d.ts +41 -0
- package/dist/core/agent-internals.d.ts.map +1 -0
- package/dist/core/agent-loop.d.ts +18 -0
- package/dist/core/agent-loop.d.ts.map +1 -0
- package/dist/core/agent-response.d.ts +21 -0
- package/dist/core/agent-response.d.ts.map +1 -0
- package/dist/core/agent-tools.d.ts +21 -0
- package/dist/core/agent-tools.d.ts.map +1 -0
- package/dist/core/agent-types.d.ts +95 -0
- package/dist/core/agent-types.d.ts.map +1 -0
- package/dist/core/agent.d.ts +54 -0
- package/dist/core/agent.d.ts.map +1 -0
- package/dist/core/btw.d.ts +40 -0
- package/dist/core/btw.d.ts.map +1 -0
- package/dist/core/context.d.ts +269 -0
- package/dist/core/context.d.ts.map +1 -0
- package/dist/core/continue-intent.d.ts +92 -0
- package/dist/core/continue-intent.d.ts.map +1 -0
- package/dist/core/continue-to-next-iteration.d.ts +96 -0
- package/dist/core/continue-to-next-iteration.d.ts.map +1 -0
- package/dist/core/conversation-state.d.ts +96 -0
- package/dist/core/conversation-state.d.ts.map +1 -0
- package/dist/core/fallback-model.d.ts +94 -0
- package/dist/core/fallback-model.d.ts.map +1 -0
- package/dist/core/fleet-pulse.d.ts +42 -0
- package/dist/core/fleet-pulse.d.ts.map +1 -0
- package/dist/core/input-builder.d.ts +95 -0
- package/dist/core/input-builder.d.ts.map +1 -0
- package/dist/core/instruction-bundle.d.ts +22 -0
- package/dist/core/instruction-bundle.d.ts.map +1 -0
- package/dist/core/iteration-limit.d.ts +35 -0
- package/dist/core/iteration-limit.d.ts.map +1 -0
- package/dist/core/mailbox-loop.d.ts +63 -0
- package/dist/core/mailbox-loop.d.ts.map +1 -0
- package/dist/core/modes/brief.d.ts +2 -0
- package/dist/core/modes/brief.d.ts.map +1 -0
- package/dist/core/modes/default.d.ts +8 -0
- package/dist/core/modes/default.d.ts.map +1 -0
- package/dist/core/modes/teach.d.ts +2 -0
- package/dist/core/modes/teach.d.ts.map +1 -0
- package/dist/core/provider-runner.d.ts +24 -0
- package/dist/core/provider-runner.d.ts.map +1 -0
- package/dist/core/queued-messages.d.ts +55 -0
- package/dist/core/queued-messages.d.ts.map +1 -0
- package/dist/core/run-env.d.ts +49 -0
- package/dist/core/run-env.d.ts.map +1 -0
- package/dist/core/streaming-response-builder.d.ts +78 -0
- package/dist/core/streaming-response-builder.d.ts.map +1 -0
- package/dist/core/system-prompt-builder.d.ts +213 -0
- package/dist/core/system-prompt-builder.d.ts.map +1 -0
- package/dist/defaults/index.d.ts +68 -158
- package/dist/defaults/index.d.ts.map +1 -0
- package/dist/defaults/index.js +2061 -1300
- package/dist/defaults/index.js.map +7 -1
- package/dist/execution/auto-compaction-middleware.d.ts +123 -0
- package/dist/execution/auto-compaction-middleware.d.ts.map +1 -0
- package/dist/execution/autonomous-runner.d.ts +61 -0
- package/dist/execution/autonomous-runner.d.ts.map +1 -0
- package/dist/execution/autonomy-brain.d.ts +151 -0
- package/dist/execution/autonomy-brain.d.ts.map +1 -0
- package/dist/execution/autonomy-prompt-contributor.d.ts +39 -0
- package/dist/execution/autonomy-prompt-contributor.d.ts.map +1 -0
- package/dist/execution/brain-chain.d.ts +53 -0
- package/dist/execution/brain-chain.d.ts.map +1 -0
- package/dist/execution/brain-evaluation.d.ts +66 -0
- package/dist/execution/brain-evaluation.d.ts.map +1 -0
- package/dist/execution/brain-runtime.d.ts +171 -0
- package/dist/execution/brain-runtime.d.ts.map +1 -0
- package/dist/execution/compaction-core.d.ts +103 -0
- package/dist/execution/compaction-core.d.ts.map +1 -0
- package/dist/execution/compactor.d.ts +56 -0
- package/dist/execution/compactor.d.ts.map +1 -0
- package/dist/execution/council-brain.d.ts +79 -0
- package/dist/execution/council-brain.d.ts.map +1 -0
- package/dist/execution/design-color.d.ts +31 -0
- package/dist/execution/design-color.d.ts.map +1 -0
- package/dist/execution/design-detect.d.ts +96 -0
- package/dist/execution/design-detect.d.ts.map +1 -0
- package/dist/execution/design-kit-loader.d.ts +53 -0
- package/dist/execution/design-kit-loader.d.ts.map +1 -0
- package/dist/execution/design-materialize.d.ts +32 -0
- package/dist/execution/design-materialize.d.ts.map +1 -0
- package/dist/execution/design-project-store.d.ts +57 -0
- package/dist/execution/design-project-store.d.ts.map +1 -0
- package/dist/execution/design-verify.d.ts +44 -0
- package/dist/execution/design-verify.d.ts.map +1 -0
- package/dist/execution/error-handler.d.ts +34 -0
- package/dist/execution/error-handler.d.ts.map +1 -0
- package/dist/{parallel-eternal-engine-HUrtePLd.d.ts → execution/eternal-autonomy.d.ts} +22 -225
- package/dist/execution/eternal-autonomy.d.ts.map +1 -0
- package/dist/execution/goal-preamble.d.ts +2 -0
- package/dist/execution/goal-preamble.d.ts.map +1 -0
- package/dist/execution/index.d.ts +25 -180
- package/dist/execution/index.d.ts.map +1 -0
- package/dist/execution/index.js +1748 -490
- package/dist/execution/index.js.map +7 -1
- package/dist/execution/intelligent-compactor.d.ts +85 -0
- package/dist/execution/intelligent-compactor.d.ts.map +1 -0
- package/dist/execution/model-runtime.d.ts +75 -0
- package/dist/execution/model-runtime.d.ts.map +1 -0
- package/dist/execution/parallel-eternal-engine.d.ts +142 -0
- package/dist/execution/parallel-eternal-engine.d.ts.map +1 -0
- package/dist/execution/prompt-enhancer.d.ts +12 -13
- package/dist/execution/prompt-enhancer.d.ts.map +1 -0
- package/dist/execution/prompt-enhancer.js +13 -7
- package/dist/execution/prompt-enhancer.js.map +7 -1
- package/dist/execution/prompt-loader.d.ts +52 -0
- package/dist/execution/prompt-loader.d.ts.map +1 -0
- package/dist/execution/provider-runner-impl.d.ts +14 -0
- package/dist/execution/provider-runner-impl.d.ts.map +1 -0
- package/dist/execution/regex-patterns.d.ts +7 -0
- package/dist/execution/regex-patterns.d.ts.map +1 -0
- package/dist/execution/retry-policy.d.ts +35 -0
- package/dist/execution/retry-policy.d.ts.map +1 -0
- package/dist/execution/selective-compactor.d.ts +94 -0
- package/dist/execution/selective-compactor.d.ts.map +1 -0
- package/dist/execution/skill-loader.d.ts +43 -0
- package/dist/execution/skill-loader.d.ts.map +1 -0
- package/dist/execution/strategy-compactor.d.ts +43 -0
- package/dist/execution/strategy-compactor.d.ts.map +1 -0
- package/dist/execution/tool-executor.d.ts +112 -0
- package/dist/execution/tool-executor.d.ts.map +1 -0
- package/dist/extension/extension-points.d.ts +121 -0
- package/dist/extension/extension-points.d.ts.map +1 -0
- package/dist/extension/index.d.ts +3 -10
- package/dist/extension/index.d.ts.map +1 -0
- package/dist/extension/index.js +59 -5
- package/dist/extension/index.js.map +7 -1
- package/dist/extension/registry.d.ts +86 -0
- package/dist/extension/registry.d.ts.map +1 -0
- package/dist/fleet-notifier.d.ts +28 -0
- package/dist/fleet-notifier.d.ts.map +1 -0
- package/dist/hooks/http-executor.d.ts +11 -0
- package/dist/hooks/http-executor.d.ts.map +1 -0
- package/dist/hooks/index.d.ts +10 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/registry.d.ts +71 -0
- package/dist/hooks/registry.d.ts.map +1 -0
- package/dist/hooks/runner.d.ts +65 -0
- package/dist/hooks/runner.d.ts.map +1 -0
- package/dist/hooks/shell-executor.d.ts +33 -0
- package/dist/hooks/shell-executor.d.ts.map +1 -0
- package/dist/hooks/shell-hooks-equal.d.ts +15 -0
- package/dist/hooks/shell-hooks-equal.d.ts.map +1 -0
- package/dist/hq/agent-bridge.d.ts +27 -0
- package/dist/hq/agent-bridge.d.ts.map +1 -0
- package/dist/hq/alerts.d.ts +67 -0
- package/dist/hq/alerts.d.ts.map +1 -0
- package/dist/hq/auth-store.d.ts +179 -0
- package/dist/hq/auth-store.d.ts.map +1 -0
- package/dist/hq/brain-bridge.d.ts +37 -0
- package/dist/hq/brain-bridge.d.ts.map +1 -0
- package/dist/hq/commands.d.ts +122 -0
- package/dist/hq/commands.d.ts.map +1 -0
- package/dist/hq/cost-bridge.d.ts +36 -0
- package/dist/hq/cost-bridge.d.ts.map +1 -0
- package/dist/hq/factory.d.ts +69 -0
- package/dist/hq/factory.d.ts.map +1 -0
- package/dist/hq/fleet-bridge.d.ts +39 -0
- package/dist/hq/fleet-bridge.d.ts.map +1 -0
- package/dist/hq/index.d.ts +18 -816
- package/dist/hq/index.d.ts.map +1 -0
- package/dist/hq/index.js +1043 -192
- package/dist/hq/index.js.map +7 -1
- package/dist/hq/mailbox-mapper.d.ts +27 -0
- package/dist/hq/mailbox-mapper.d.ts.map +1 -0
- package/dist/hq/persistence.d.ts +121 -0
- package/dist/hq/persistence.d.ts.map +1 -0
- package/dist/hq/protocol.d.ts +612 -0
- package/dist/hq/protocol.d.ts.map +1 -0
- package/dist/hq/publisher.d.ts +181 -0
- package/dist/hq/publisher.d.ts.map +1 -0
- package/dist/hq/redaction.d.ts +30 -0
- package/dist/hq/redaction.d.ts.map +1 -0
- package/dist/hq/session-bridge.d.ts +29 -0
- package/dist/hq/session-bridge.d.ts.map +1 -0
- package/dist/hq/tool-bridge.d.ts +41 -0
- package/dist/hq/tool-bridge.d.ts.map +1 -0
- package/dist/hq/transcript-mapper.d.ts +36 -0
- package/dist/hq/transcript-mapper.d.ts.map +1 -0
- package/dist/hq/worktree-bridge.d.ts +34 -0
- package/dist/hq/worktree-bridge.d.ts.map +1 -0
- package/dist/index.d.ts +114 -2872
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6104 -2737
- package/dist/index.js.map +7 -1
- package/dist/infrastructure/context-manager.d.ts +92 -0
- package/dist/infrastructure/context-manager.d.ts.map +1 -0
- package/dist/infrastructure/index.d.ts +6 -64
- package/dist/infrastructure/index.d.ts.map +1 -0
- package/dist/infrastructure/index.js +39 -12
- package/dist/infrastructure/index.js.map +7 -1
- package/dist/infrastructure/logger.d.ts +99 -0
- package/dist/infrastructure/logger.d.ts.map +1 -0
- package/dist/infrastructure/mcp-servers.d.ts +83 -0
- package/dist/infrastructure/mcp-servers.d.ts.map +1 -0
- package/dist/{path-resolver-CMS5307d.d.ts → infrastructure/path-resolver.d.ts} +3 -5
- package/dist/infrastructure/path-resolver.d.ts.map +1 -0
- package/dist/infrastructure/token-counter.d.ts +57 -0
- package/dist/infrastructure/token-counter.d.ts.map +1 -0
- package/dist/kernel/container.d.ts +84 -0
- package/dist/kernel/container.d.ts.map +1 -0
- package/dist/{events-Bgnh43r9.d.ts → kernel/events.d.ts} +134 -210
- package/dist/kernel/events.d.ts.map +1 -0
- package/dist/kernel/index.d.ts +6 -107
- package/dist/kernel/index.d.ts.map +1 -0
- package/dist/kernel/index.js +56 -4
- package/dist/kernel/index.js.map +7 -1
- package/dist/kernel/pipeline.d.ts +105 -0
- package/dist/kernel/pipeline.d.ts.map +1 -0
- package/dist/kernel/run-controller.d.ts +55 -0
- package/dist/kernel/run-controller.d.ts.map +1 -0
- package/dist/kernel/tokens.d.ts +53 -0
- package/dist/kernel/tokens.d.ts.map +1 -0
- package/dist/mailbox-attach.d.ts +27 -0
- package/dist/mailbox-attach.d.ts.map +1 -0
- package/dist/middleware/collab-pause.d.ts +73 -0
- package/dist/middleware/collab-pause.d.ts.map +1 -0
- package/dist/models/codex-catalog.d.ts +41 -0
- package/dist/models/codex-catalog.d.ts.map +1 -0
- package/dist/models/index.d.ts +8 -163
- package/dist/models/index.d.ts.map +1 -0
- package/dist/models/index.js +150 -51
- package/dist/models/index.js.map +7 -1
- package/dist/models/llm-selector.d.ts +47 -0
- package/dist/models/llm-selector.d.ts.map +1 -0
- package/dist/models/mode-store.d.ts +22 -0
- package/dist/models/mode-store.d.ts.map +1 -0
- package/dist/models/model-intelligence.d.ts +56 -0
- package/dist/models/model-intelligence.d.ts.map +1 -0
- package/dist/models/model-router.d.ts +100 -0
- package/dist/models/model-router.d.ts.map +1 -0
- package/dist/models/models-registry.d.ts +106 -0
- package/dist/models/models-registry.d.ts.map +1 -0
- package/dist/models/provider-model-resolve.d.ts +69 -0
- package/dist/models/provider-model-resolve.d.ts.map +1 -0
- package/dist/observability/event-bridge.d.ts +10 -0
- package/dist/observability/event-bridge.d.ts.map +1 -0
- package/dist/observability/health.d.ts +18 -0
- package/dist/observability/health.d.ts.map +1 -0
- package/dist/observability/index.d.ts +9 -354
- package/dist/observability/index.d.ts.map +1 -0
- package/dist/observability/index.js +37 -23
- package/dist/observability/index.js.map +7 -1
- package/dist/observability/metrics.d.ts +26 -0
- package/dist/observability/metrics.d.ts.map +1 -0
- package/dist/observability/otel-tracer.d.ts +41 -0
- package/dist/observability/otel-tracer.d.ts.map +1 -0
- package/dist/observability/otlp-metrics.d.ts +111 -0
- package/dist/observability/otlp-metrics.d.ts.map +1 -0
- package/dist/observability/otlp-traces.d.ts +95 -0
- package/dist/observability/otlp-traces.d.ts.map +1 -0
- package/dist/observability/prometheus.d.ts +49 -0
- package/dist/observability/prometheus.d.ts.map +1 -0
- package/dist/observability/tracer.d.ts +9 -0
- package/dist/observability/tracer.d.ts.map +1 -0
- package/dist/plugin/api.d.ts +226 -0
- package/dist/plugin/api.d.ts.map +1 -0
- package/dist/plugin/loader.d.ts +73 -0
- package/dist/plugin/loader.d.ts.map +1 -0
- package/dist/plugins/chimera-plugin.d.ts +37 -0
- package/dist/plugins/chimera-plugin.d.ts.map +1 -0
- package/dist/plugins/prompts-plugin.d.ts +26 -0
- package/dist/plugins/prompts-plugin.d.ts.map +1 -0
- package/dist/plugins/security-plugin.d.ts +19 -0
- package/dist/plugins/security-plugin.d.ts.map +1 -0
- package/dist/plugins/skills-plugin.d.ts +42 -0
- package/dist/plugins/skills-plugin.d.ts.map +1 -0
- package/dist/plugins/sync-plugin.d.ts +22 -0
- package/dist/plugins/sync-plugin.d.ts.map +1 -0
- package/dist/prompts/index.d.ts +3 -0
- package/dist/prompts/index.d.ts.map +1 -0
- package/dist/prompts/prompt-installer.d.ts +50 -0
- package/dist/prompts/prompt-installer.d.ts.map +1 -0
- package/dist/prompts/prompt-manifest-store.d.ts +18 -0
- package/dist/prompts/prompt-manifest-store.d.ts.map +1 -0
- package/dist/registry/provider-registry.d.ts +51 -0
- package/dist/registry/provider-registry.d.ts.map +1 -0
- package/dist/registry/slash-command-registry.d.ts +61 -0
- package/dist/registry/slash-command-registry.d.ts.map +1 -0
- package/dist/registry/tool-registry.d.ts +154 -0
- package/dist/registry/tool-registry.d.ts.map +1 -0
- package/dist/replay/hash.d.ts +31 -0
- package/dist/replay/hash.d.ts.map +1 -0
- package/dist/replay/replay-provider-runner.d.ts +53 -0
- package/dist/replay/replay-provider-runner.d.ts.map +1 -0
- package/dist/{index-CbyuOE5y.d.ts → security/capabilities.d.ts} +31 -34
- package/dist/security/capabilities.d.ts.map +1 -0
- package/dist/security/config-secrets.d.ts +25 -0
- package/dist/security/config-secrets.d.ts.map +1 -0
- package/dist/security/index.d.ts +7 -8
- package/dist/security/index.d.ts.map +1 -0
- package/dist/security/index.js +354 -401
- package/dist/security/index.js.map +7 -1
- package/dist/security/permission-policy-schema.d.ts +77 -0
- package/dist/security/permission-policy-schema.d.ts.map +1 -0
- package/dist/security/permission-policy.d.ts +158 -0
- package/dist/security/permission-policy.d.ts.map +1 -0
- package/dist/security/secret-scrubber.d.ts +14 -0
- package/dist/security/secret-scrubber.d.ts.map +1 -0
- package/dist/security/secret-vault.d.ts +96 -0
- package/dist/security/secret-vault.d.ts.map +1 -0
- package/dist/security/yolo-risk.d.ts +11 -0
- package/dist/security/yolo-risk.d.ts.map +1 -0
- package/dist/{session-registry-Dvg7i_IA.d.ts → session-registry.d.ts} +8 -9
- package/dist/session-registry.d.ts.map +1 -0
- package/dist/skills/foreign-sources.d.ts +59 -0
- package/dist/skills/foreign-sources.d.ts.map +1 -0
- package/dist/skills/frontmatter.d.ts +44 -0
- package/dist/skills/frontmatter.d.ts.map +1 -0
- package/dist/skills/github-fetcher.d.ts +38 -0
- package/dist/skills/github-fetcher.d.ts.map +1 -0
- package/dist/skills/index.d.ts +11 -582
- package/dist/skills/index.d.ts.map +1 -0
- package/dist/skills/index.js +81 -43
- package/dist/skills/index.js.map +7 -1
- package/dist/skills/limits.d.ts +92 -0
- package/dist/skills/limits.d.ts.map +1 -0
- package/dist/skills/manifest-store.d.ts +42 -0
- package/dist/skills/manifest-store.d.ts.map +1 -0
- package/dist/skills/registry/github-direct-adapter.d.ts +17 -0
- package/dist/skills/registry/github-direct-adapter.d.ts.map +1 -0
- package/dist/skills/registry/registry-adapter.d.ts +84 -0
- package/dist/skills/registry/registry-adapter.d.ts.map +1 -0
- package/dist/skills/registry/skills-sh-adapter.d.ts +13 -0
- package/dist/skills/registry/skills-sh-adapter.d.ts.map +1 -0
- package/dist/skills/skill-generator.d.ts +82 -0
- package/dist/skills/skill-generator.d.ts.map +1 -0
- package/dist/skills/skill-installer.d.ts +124 -0
- package/dist/skills/skill-installer.d.ts.map +1 -0
- package/dist/storage/annotations-store.d.ts +118 -0
- package/dist/storage/annotations-store.d.ts.map +1 -0
- package/dist/storage/attachment-store.d.ts +31 -0
- package/dist/storage/attachment-store.d.ts.map +1 -0
- package/dist/storage/cloud-sync.d.ts +44 -0
- package/dist/storage/cloud-sync.d.ts.map +1 -0
- package/dist/storage/completed-work-checkpoint.d.ts +11 -0
- package/dist/storage/completed-work-checkpoint.d.ts.map +1 -0
- package/dist/storage/config-loader.d.ts +114 -0
- package/dist/storage/config-loader.d.ts.map +1 -0
- package/dist/storage/config-migration.d.ts +87 -0
- package/dist/storage/config-migration.d.ts.map +1 -0
- package/dist/storage/config-store.d.ts +22 -0
- package/dist/storage/config-store.d.ts.map +1 -0
- package/dist/{director-state-CMS_bMs4.d.ts → storage/director-state.d.ts} +28 -8
- package/dist/storage/director-state.d.ts.map +1 -0
- package/dist/storage/file-session-writer.d.ts +169 -0
- package/dist/storage/file-session-writer.d.ts.map +1 -0
- package/dist/{goal-store-Datpp-ar.d.ts → storage/goal-store.d.ts} +26 -19
- package/dist/storage/goal-store.d.ts.map +1 -0
- package/dist/storage/index.d.ts +39 -1031
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +783 -443
- package/dist/storage/index.js.map +7 -1
- package/dist/storage/input-history-store.d.ts +56 -0
- package/dist/storage/input-history-store.d.ts.map +1 -0
- package/dist/storage/memory-backend.d.ts +66 -0
- package/dist/storage/memory-backend.d.ts.map +1 -0
- package/dist/storage/memory-consolidator.d.ts +50 -0
- package/dist/storage/memory-consolidator.d.ts.map +1 -0
- package/dist/storage/memory-graph-backend.d.ts +117 -0
- package/dist/storage/memory-graph-backend.d.ts.map +1 -0
- package/dist/storage/memory-store.d.ts +119 -0
- package/dist/storage/memory-store.d.ts.map +1 -0
- package/dist/storage/plan-store.d.ts +78 -0
- package/dist/storage/plan-store.d.ts.map +1 -0
- package/dist/storage/plan-templates.d.ts +21 -0
- package/dist/storage/plan-templates.d.ts.map +1 -0
- package/dist/storage/prompt-store.d.ts +37 -0
- package/dist/storage/prompt-store.d.ts.map +1 -0
- package/dist/storage/prompt-usage-store.d.ts +29 -0
- package/dist/storage/prompt-usage-store.d.ts.map +1 -0
- package/dist/storage/provider-config-watcher.d.ts +34 -0
- package/dist/storage/provider-config-watcher.d.ts.map +1 -0
- package/dist/storage/queue-store.d.ts +41 -0
- package/dist/storage/queue-store.d.ts.map +1 -0
- package/dist/storage/recovery-lock.d.ts +79 -0
- package/dist/storage/recovery-lock.d.ts.map +1 -0
- package/dist/storage/replay-log-store.d.ts +97 -0
- package/dist/storage/replay-log-store.d.ts.map +1 -0
- package/dist/storage/session-analyzer.d.ts +48 -0
- package/dist/storage/session-analyzer.d.ts.map +1 -0
- package/dist/storage/session-checkpoint-cas.d.ts +37 -0
- package/dist/storage/session-checkpoint-cas.d.ts.map +1 -0
- package/dist/{session-event-bridge-D_z_mBwk.d.ts → storage/session-event-bridge.d.ts} +14 -15
- package/dist/storage/session-event-bridge.d.ts.map +1 -0
- package/dist/storage/session-helpers.d.ts +9 -0
- package/dist/storage/session-helpers.d.ts.map +1 -0
- package/dist/storage/session-id.d.ts +18 -0
- package/dist/storage/session-id.d.ts.map +1 -0
- package/dist/storage/session-reader.d.ts +21 -0
- package/dist/storage/session-reader.d.ts.map +1 -0
- package/dist/storage/session-recovery.d.ts +93 -0
- package/dist/storage/session-recovery.d.ts.map +1 -0
- package/dist/storage/session-resume-validation.d.ts +6 -0
- package/dist/storage/session-resume-validation.d.ts.map +1 -0
- package/dist/storage/session-rewinder.d.ts +21 -0
- package/dist/storage/session-rewinder.d.ts.map +1 -0
- package/dist/storage/session-store.d.ts +219 -0
- package/dist/storage/session-store.d.ts.map +1 -0
- package/dist/storage/session-summary.d.ts +12 -0
- package/dist/storage/session-summary.d.ts.map +1 -0
- package/dist/storage/session-tool-call-ends.d.ts +5 -0
- package/dist/storage/session-tool-call-ends.d.ts.map +1 -0
- package/dist/storage/storage-concurrency.d.ts +2 -0
- package/dist/storage/storage-concurrency.d.ts.map +1 -0
- package/dist/storage/task-store.d.ts +33 -0
- package/dist/storage/task-store.d.ts.map +1 -0
- package/dist/storage/todos-checkpoint.d.ts +39 -0
- package/dist/storage/todos-checkpoint.d.ts.map +1 -0
- package/dist/storage/tool-audit-log.d.ts +141 -0
- package/dist/storage/tool-audit-log.d.ts.map +1 -0
- package/dist/tasking/index.d.ts +3 -124
- package/dist/tasking/index.d.ts.map +1 -0
- package/dist/tasking/index.js +57 -4
- package/dist/tasking/index.js.map +7 -1
- package/dist/tasking/task-store.d.ts +22 -0
- package/dist/tasking/task-store.d.ts.map +1 -0
- package/dist/tasking/task-tracker.d.ts +102 -0
- package/dist/tasking/task-tracker.d.ts.map +1 -0
- package/dist/tools/index.d.ts +2 -59
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +93 -14
- package/dist/tools/index.js.map +7 -1
- package/dist/tools/mcp-control.d.ts +53 -0
- package/dist/tools/mcp-control.d.ts.map +1 -0
- package/dist/tools/mcp-use.d.ts +24 -0
- package/dist/tools/mcp-use.d.ts.map +1 -0
- package/dist/types/agent-bridge.d.ts +42 -0
- package/dist/types/agent-bridge.d.ts.map +1 -0
- package/dist/types/attachment.d.ts +54 -0
- package/dist/types/attachment.d.ts.map +1 -0
- package/dist/types/autonomy.d.ts +5 -0
- package/dist/types/autonomy.d.ts.map +1 -0
- package/dist/types/blocks.d.ts +76 -0
- package/dist/types/blocks.d.ts.map +1 -0
- package/dist/{compactor-DQLL4HTo.d.ts → types/compactor.d.ts} +5 -7
- package/dist/types/compactor.d.ts.map +1 -0
- package/dist/{config-MRqn1V-u.d.ts → types/config.d.ts} +344 -355
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/context-evidence.d.ts +68 -0
- package/dist/types/context-evidence.d.ts.map +1 -0
- package/dist/types/context-window.d.ts +35 -0
- package/dist/types/context-window.d.ts.map +1 -0
- package/dist/{default-config-B79_gJYv.d.ts → types/default-config.d.ts} +10 -11
- package/dist/types/default-config.d.ts.map +1 -0
- package/dist/types/design-kit.d.ts +91 -0
- package/dist/types/design-kit.d.ts.map +1 -0
- package/dist/{retry-policy-CQ7KwXJa.d.ts → types/error-handler.d.ts} +5 -12
- package/dist/types/error-handler.d.ts.map +1 -0
- package/dist/types/errors.d.ts +277 -0
- package/dist/types/errors.d.ts.map +1 -0
- package/dist/types/hooks.d.ts +167 -0
- package/dist/types/hooks.d.ts.map +1 -0
- package/dist/types/index.d.ts +40 -244
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +101 -12
- package/dist/types/index.js.map +7 -1
- package/dist/{input-reader-E-ffP2ee.d.ts → types/input-reader.d.ts} +3 -4
- package/dist/types/input-reader.d.ts.map +1 -0
- package/dist/{logger-B63L5bTg.d.ts → types/logger.d.ts} +3 -4
- package/dist/types/logger.d.ts.map +1 -0
- package/dist/types/memory.d.ts +89 -0
- package/dist/types/memory.d.ts.map +1 -0
- package/dist/types/messages.d.ts +24 -0
- package/dist/types/messages.d.ts.map +1 -0
- package/dist/types/mode-prompts.d.ts +2 -0
- package/dist/types/mode-prompts.d.ts.map +1 -0
- package/dist/{mode-CZlO9iU1.d.ts → types/mode.d.ts} +6 -7
- package/dist/types/mode.d.ts.map +1 -0
- package/dist/types/models-registry.d.ts +105 -0
- package/dist/types/models-registry.d.ts.map +1 -0
- package/dist/types/multi-agent.d.ts +443 -0
- package/dist/types/multi-agent.d.ts.map +1 -0
- package/dist/{observability-D-HZN_mF.d.ts → types/observability.d.ts} +17 -13
- package/dist/types/observability.d.ts.map +1 -0
- package/dist/{path-resolver-CPRj4bFY.d.ts → types/path-resolver.d.ts} +2 -3
- package/dist/types/path-resolver.d.ts.map +1 -0
- package/dist/{permission-ByDKXEcG.d.ts → types/permission.d.ts} +8 -9
- package/dist/types/permission.d.ts.map +1 -0
- package/dist/types/plugin.d.ts +385 -0
- package/dist/types/plugin.d.ts.map +1 -0
- package/dist/types/prompt-registry.d.ts +81 -0
- package/dist/types/prompt-registry.d.ts.map +1 -0
- package/dist/{prompt-DLd35n4Q.d.ts → types/prompt.d.ts} +14 -15
- package/dist/types/prompt.d.ts.map +1 -0
- package/dist/{provider-runner-ChL-kVg6.d.ts → types/provider-runner.d.ts} +9 -10
- package/dist/types/provider-runner.d.ts.map +1 -0
- package/dist/types/provider.d.ts +387 -0
- package/dist/types/provider.d.ts.map +1 -0
- package/dist/types/renderer.d.ts +23 -0
- package/dist/types/renderer.d.ts.map +1 -0
- package/dist/types/retry-policy.d.ts +7 -0
- package/dist/types/retry-policy.d.ts.map +1 -0
- package/dist/types/secret-scrubber.d.ts +5 -0
- package/dist/types/secret-scrubber.d.ts.map +1 -0
- package/dist/{secret-vault-BAKpgFw_.d.ts → types/secret-vault.d.ts} +13 -7
- package/dist/types/secret-vault.d.ts.map +1 -0
- package/dist/{selector-D8O6B_Rm.d.ts → types/selector.d.ts} +4 -6
- package/dist/types/selector.d.ts.map +1 -0
- package/dist/types/session-reader.d.ts +81 -0
- package/dist/types/session-reader.d.ts.map +1 -0
- package/dist/{session-rewinder-C9HnMkhP.d.ts → types/session-rewinder.d.ts} +5 -6
- package/dist/types/session-rewinder.d.ts.map +1 -0
- package/dist/types/session.d.ts +650 -0
- package/dist/types/session.d.ts.map +1 -0
- package/dist/types/side-effect.d.ts +34 -0
- package/dist/types/side-effect.d.ts.map +1 -0
- package/dist/{skill-DHniprNl.d.ts → types/skill.d.ts} +4 -5
- package/dist/types/skill.d.ts.map +1 -0
- package/dist/types/slash-command.d.ts +59 -0
- package/dist/types/slash-command.d.ts.map +1 -0
- package/dist/types/spec.d.ts +77 -0
- package/dist/types/spec.d.ts.map +1 -0
- package/dist/types/system-prompt-contributor.d.ts +20 -0
- package/dist/types/system-prompt-contributor.d.ts.map +1 -0
- package/dist/types/system-prompt.d.ts +51 -0
- package/dist/types/system-prompt.d.ts.map +1 -0
- package/dist/{task-graph-CH3acNQ7.d.ts → types/task-graph.d.ts} +21 -22
- package/dist/types/task-graph.d.ts.map +1 -0
- package/dist/types/token-counter.d.ts +42 -0
- package/dist/types/token-counter.d.ts.map +1 -0
- package/dist/types/tool-executor.d.ts +133 -0
- package/dist/types/tool-executor.d.ts.map +1 -0
- package/dist/types/tool-markers.d.ts +23 -0
- package/dist/types/tool-markers.d.ts.map +1 -0
- package/dist/types/tool.d.ts +252 -0
- package/dist/types/tool.d.ts.map +1 -0
- package/dist/types/utility-types.d.ts +31 -0
- package/dist/types/utility-types.d.ts.map +1 -0
- package/dist/utils/assert-never.d.ts +14 -0
- package/dist/utils/assert-never.d.ts.map +1 -0
- package/dist/utils/atomic-write.d.ts +12 -0
- package/dist/utils/atomic-write.d.ts.map +1 -0
- package/dist/utils/child-env.d.ts +67 -0
- package/dist/utils/child-env.d.ts.map +1 -0
- package/dist/utils/color.d.ts +20 -0
- package/dist/utils/color.d.ts.map +1 -0
- package/dist/utils/config-json.d.ts +14 -0
- package/dist/utils/config-json.d.ts.map +1 -0
- package/dist/utils/context-evidence.d.ts +47 -0
- package/dist/utils/context-evidence.d.ts.map +1 -0
- package/dist/utils/deep-merge.d.ts +64 -0
- package/dist/utils/deep-merge.d.ts.map +1 -0
- package/dist/utils/diff.d.ts +11 -0
- package/dist/utils/diff.d.ts.map +1 -0
- package/dist/utils/error.d.ts +2 -3
- package/dist/utils/error.d.ts.map +1 -0
- package/dist/utils/error.js +3 -3
- package/dist/utils/error.js.map +7 -1
- package/dist/utils/expect-defined.d.ts +2 -3
- package/dist/utils/expect-defined.d.ts.map +1 -0
- package/dist/utils/expect-defined.js +3 -3
- package/dist/utils/expect-defined.js.map +7 -1
- package/dist/utils/glob-expand.d.ts +10 -0
- package/dist/utils/glob-expand.d.ts.map +1 -0
- package/dist/utils/glob-match.d.ts +4 -0
- package/dist/utils/glob-match.d.ts.map +1 -0
- package/dist/utils/incoming-images.d.ts +39 -0
- package/dist/utils/incoming-images.d.ts.map +1 -0
- package/dist/utils/index.d.ts +38 -920
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +323 -36
- package/dist/utils/index.js.map +7 -1
- package/dist/utils/instruction-file.d.ts +3 -0
- package/dist/utils/instruction-file.d.ts.map +1 -0
- package/dist/utils/ip-guard.d.ts +34 -0
- package/dist/utils/ip-guard.d.ts.map +1 -0
- package/dist/utils/json-repair.d.ts +23 -0
- package/dist/utils/json-repair.d.ts.map +1 -0
- package/dist/utils/json-schema-validate.d.ts +42 -0
- package/dist/utils/json-schema-validate.d.ts.map +1 -0
- package/dist/utils/lru-cache.d.ts +29 -0
- package/dist/utils/lru-cache.d.ts.map +1 -0
- package/dist/utils/merge-custom-models.d.ts +12 -0
- package/dist/utils/merge-custom-models.d.ts.map +1 -0
- package/dist/utils/merge-models-payload.d.ts +20 -0
- package/dist/utils/merge-models-payload.d.ts.map +1 -0
- package/dist/utils/message-invariants.d.ts +22 -0
- package/dist/utils/message-invariants.d.ts.map +1 -0
- package/dist/utils/newline-normalize.d.ts +5 -0
- package/dist/utils/newline-normalize.d.ts.map +1 -0
- package/dist/utils/regex-guard.d.ts +21 -0
- package/dist/utils/regex-guard.d.ts.map +1 -0
- package/dist/utils/safe-json.d.ts +31 -0
- package/dist/utils/safe-json.d.ts.map +1 -0
- package/dist/utils/session-scoped-path.d.ts +13 -0
- package/dist/utils/session-scoped-path.d.ts.map +1 -0
- package/dist/utils/sleep.d.ts +5 -0
- package/dist/utils/sleep.d.ts.map +1 -0
- package/dist/utils/slug.d.ts +13 -0
- package/dist/utils/slug.d.ts.map +1 -0
- package/dist/utils/string.d.ts +9 -0
- package/dist/utils/string.d.ts.map +1 -0
- package/dist/utils/task-format.d.ts +22 -0
- package/dist/utils/task-format.d.ts.map +1 -0
- package/dist/utils/term.d.ts +133 -0
- package/dist/utils/term.d.ts.map +1 -0
- package/dist/utils/todos-format.d.ts +30 -0
- package/dist/utils/todos-format.d.ts.map +1 -0
- package/dist/utils/token-estimate.d.ts +112 -0
- package/dist/utils/token-estimate.d.ts.map +1 -0
- package/dist/utils/tool-description-mode.d.ts +28 -0
- package/dist/utils/tool-description-mode.d.ts.map +1 -0
- package/dist/utils/tool-output-serializer.d.ts +40 -0
- package/dist/utils/tool-output-serializer.d.ts.map +1 -0
- package/dist/utils/tool-result-render-mode.d.ts +55 -0
- package/dist/utils/tool-result-render-mode.d.ts.map +1 -0
- package/dist/utils/tool-subject.d.ts +5 -0
- package/dist/utils/tool-subject.d.ts.map +1 -0
- package/dist/utils/tool-wire-compact.d.ts +28 -0
- package/dist/utils/tool-wire-compact.d.ts.map +1 -0
- package/dist/utils/ulid.d.ts +11 -0
- package/dist/utils/ulid.d.ts.map +1 -0
- package/dist/{wstack-paths-C3K40Qst.d.ts → utils/wstack-paths.d.ts} +7 -8
- package/dist/utils/wstack-paths.d.ts.map +1 -0
- package/dist/worktree/index.d.ts +2 -0
- package/dist/worktree/index.d.ts.map +1 -0
- package/dist/{worktree-manager-DzwxKE35.d.ts → worktree/worktree-manager.d.ts} +32 -17
- package/dist/worktree/worktree-manager.d.ts.map +1 -0
- package/instructions/agents/browser.md +25 -16
- package/instructions/autonomy/active-mission.md +2 -4
- package/instructions/coordination/subagent-baseline.md +16 -2
- package/instructions/leader-after-task.md +3 -1
- package/instructions/sections/tool/common-patterns.md +7 -1
- package/instructions/sections/tool/delegation-full.md +1 -1
- package/instructions/system.md +47 -0
- package/package.json +4 -5
- package/skills/docker-deploy/SKILL.md +1 -1
- package/skills/node-modern/SKILL.md +2 -2
- package/skills/plugin-author/SKILL.md +9 -16
- package/skills/wrongstack-mailbox/SKILL.md +51 -12
- package/dist/dispatcher-types.d-BBeXBQgS.d.ts +0 -66
- package/dist/global-mailbox-sZwyI6CS.d.ts +0 -959
- package/dist/index--Gm41aBJ.d.ts +0 -671
- package/dist/mcp-servers-DEV4s6Ks.d.ts +0 -259
- package/dist/multi-agent-coordinator-4RCRZKjN.d.ts +0 -1770
- package/dist/null-fleet-bus-CFoNVQEK.d.ts +0 -2127
- package/dist/pipeline-DGDyIohT.d.ts +0 -331
- package/dist/provider-model-resolve-o2hHLs79.d.ts +0 -263
- package/dist/secret-scrubber-3MHDDAtm.d.ts +0 -6
- package/dist/secret-vault-DxohkUBc.d.ts +0 -272
- package/dist/session-reader-7Esxrkpw.d.ts +0 -155
- package/dist/task-format-GX0B1mMC.d.ts +0 -23
- package/dist/todos-checkpoint-FY7PjmMx.d.ts +0 -850
- package/dist/tool-BNlnIJvo.d.ts +0 -2190
- package/dist/tool-executor-CckSCM5E.d.ts +0 -906
package/dist/hq/index.js.map
CHANGED
|
@@ -1 +1,7 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/hq/protocol.ts","../../src/security/secret-scrubber.ts","../../src/hq/redaction.ts","../../src/hq/mailbox-mapper.ts","../../src/hq/publisher.ts","../../src/utils/session-scoped-path.ts","../../src/utils/wstack-paths.ts","../../src/types/errors.ts","../../src/utils/atomic-write.ts","../../src/coordination/mailbox-types.ts","../../src/coordination/global-mailbox.ts","../../src/hq/auth-store.ts","../../src/hq/factory.ts","../../src/hq/agent-bridge.ts","../../src/hq/transcript-mapper.ts","../../src/hq/session-bridge.ts","../../src/hq/fleet-bridge.ts","../../src/hq/brain-bridge.ts","../../src/hq/worktree-bridge.ts","../../src/hq/tool-bridge.ts","../../src/hq/cost-bridge.ts","../../src/hq/persistence.ts","../../src/hq/commands.ts","../../src/hq/alerts.ts"],"names":["redacted","out","path","projectHash","path3","fs","stat","resolve","path4","randomUUID","path5","fs2","fs3","createHash","basename","fs4","fsp2","path6","fs5"],"mappings":"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","file":"index.js","sourcesContent":["export const HQ_PROTOCOL_VERSION = 1 as const;\n\nexport type HqProtocolVersion = typeof HQ_PROTOCOL_VERSION;\n\nexport type HqClientKind = 'tui' | 'repl' | 'webui' | 'cli' | 'unknown';\n\nexport type HqWorkspaceKind = 'git' | 'directory' | 'unknown';\n\nexport type HqProjectStatus = 'active' | 'idle' | 'stale' | 'error';\n\nexport type HqClientCapability =\n | 'telemetry.publish'\n | 'session.summary'\n | 'fleet.summary'\n | 'mailbox.summary'\n | 'control.receive';\n\nexport type HqToolArgsPolicy = 'none' | 'summary' | 'redacted';\n\nexport type HqPathPolicy = 'none' | 'project-relative' | 'redacted' | 'full';\n\nexport interface HqRedactionPolicy {\n rawContent: boolean;\n toolArgs: HqToolArgsPolicy;\n paths: HqPathPolicy;\n}\n\nexport const DEFAULT_HQ_REDACTION_POLICY: HqRedactionPolicy = {\n rawContent: false,\n toolArgs: 'summary',\n paths: 'project-relative',\n};\n\nexport interface HqClientIdentity {\n clientId: string;\n kind: HqClientKind;\n version?: string;\n machineId: string;\n hostname?: string;\n pid?: number;\n startedAt: string;\n}\n\nexport interface HqProjectIdentity {\n projectId: string;\n projectRoot: string;\n projectName: string;\n gitRemote?: string;\n gitBranch?: string;\n machineId: string;\n workspaceKind: HqWorkspaceKind;\n}\n\nexport interface HqClientHelloPayload {\n protocolVersion: HqProtocolVersion;\n client: HqClientIdentity;\n project: HqProjectIdentity;\n capabilities: readonly HqClientCapability[];\n}\n\nexport interface HqWelcomePayload {\n type: 'hq.welcome';\n protocolVersion: HqProtocolVersion;\n serverTime: string;\n acceptedCapabilities: readonly HqClientCapability[];\n redactionPolicy: HqRedactionPolicy;\n}\n\nexport interface HqEventEnvelope<TPayload = unknown> {\n id: string;\n type: HqEventType | (string & {});\n schemaVersion: HqProtocolVersion;\n timestamp: string;\n clientId: string;\n projectId: string;\n sessionId?: string;\n runId?: string;\n seq: number;\n payload: TPayload;\n}\n\nexport type HqEventType =\n | 'client.hello'\n | 'client.heartbeat'\n | 'session.started'\n | 'session.status'\n | 'session.usage'\n | 'tool.started'\n | 'tool.completed'\n | 'fleet.snapshot'\n | 'fleet.event'\n | 'mailbox.snapshot'\n | 'mailbox.event'\n | 'worklist.snapshot'\n | 'git.snapshot'\n | 'agent.message'\n | 'agent.status'\n | 'session.snapshot'\n | 'session.transcript'\n | 'session.ended'\n | 'brain.event'\n | 'worktree.event';\n\nexport interface HqClientHeartbeatPayload {\n uptimeMs: number;\n activeSessionId?: string;\n activeRunId?: string;\n status: HqProjectStatus;\n activeSubagents?: number;\n queuedTasks?: number;\n}\n\nexport type HqSessionStatus = 'idle' | 'running' | 'paused' | 'completed' | 'failed';\n\nexport interface HqSessionStartedPayload {\n sessionId: string;\n provider?: string;\n model?: string;\n startedAt: string;\n}\n\nexport interface HqSessionStatusPayload {\n status: HqSessionStatus;\n phase?: string;\n message?: string;\n}\n\nexport interface HqUsagePayload {\n inputTokens?: number;\n outputTokens?: number;\n totalTokens?: number;\n costUsd?: number;\n durationMs?: number;\n}\n\nexport interface HqToolStartedPayload {\n toolName: string;\n capabilities?: readonly string[];\n risk?: string;\n inputSummary?: unknown;\n}\n\nexport interface HqToolCompletedPayload {\n toolName: string;\n status: 'success' | 'error' | 'timeout' | 'cancelled';\n durationMs: number;\n outputSummary?: unknown;\n errorClass?: string;\n}\n\nexport interface HqSubagentSummary {\n subagentId: string;\n role?: string;\n status: 'pending' | 'running' | 'idle' | 'completed' | 'failed' | 'stopped';\n task?: string;\n currentTool?: string;\n runtimeMs?: number;\n costUsd?: number;\n lastActivityAt?: string;\n}\n\nexport interface HqFleetSnapshotPayload {\n runId: string;\n activeSubagents: number;\n queuedTasks: number;\n completedTasks: number;\n failedTasks: number;\n totalCostUsd?: number;\n subagents: readonly HqSubagentSummary[];\n}\n\n/** Payload for `agent.message` events — a subagent's conversational output. */\nexport interface HqAgentMessagePayload {\n subagentId: string;\n agentName: string;\n content: string;\n kind: 'text' | 'thinking' | 'tool_use' | 'tool_result' | 'error' | 'status' | 'system';\n iteration: number;\n ts: string;\n toolName?: string;\n costUsd?: number;\n}\n\n/** Payload for `agent.status` events — a subagent's lifecycle transition. */\nexport interface HqAgentStatusPayload {\n subagentId: string;\n agentName: string;\n status:\n | 'spawned'\n | 'running'\n | 'completed'\n | 'failed'\n | 'timeout'\n | 'stopped'\n | 'budget_exhausted';\n ts: string;\n summary?: string;\n task?: string;\n}\n\nexport interface HqFleetEventPayload {\n runId: string;\n subagentId?: string;\n event: string;\n summary?: string;\n data?: unknown;\n}\n\n// ── Brain decision telemetry ───────────────────────────────────────────────\n//\n// The Brain (decision layer) routes autonomous decisions through a three-tier\n// chain. These envelopes let the HQ command center observe decision requests,\n// answers, denials, ask-human escalations, and self-activated interventions\n// across every connected machine — without coupling HQ to the in-process\n// Brain. All payloads are plain serializable data (no closures); the rich\n// BrainDecisionRequest / BrainDecision shapes are forwarded as-is.\n\nexport type HqBrainEventKind =\n | 'decision_requested'\n | 'decision_answered'\n | 'decision_ask_human'\n | 'human_answered'\n | 'decision_denied'\n | 'intervention';\n\nexport interface HqBrainEventPayload {\n /** Which brain lifecycle event this is (mirrors the EventBus `brain.*` name suffix). */\n kind: HqBrainEventKind;\n /** The decision request id, when present (decision_request/answer/deny). */\n requestId?: string;\n /** Short human-readable question the brain was asked. */\n question?: string;\n /** The source that triggered the decision (e.g. 'autonomy', 'system'). */\n source?: string;\n /** Resolved risk tier, when known (e.g. 'low' | 'medium' | 'high'). */\n risk?: string;\n /** The chosen decision kind, when answered/denied (e.g. 'answer' | 'ask_human' | 'deny'). */\n decision?: string;\n /** Free-text rationale or answer payload, when present. */\n detail?: string;\n /** For `intervention`: the watched signal that engaged the brain. */\n interventionKind?: 'tool_failure_streak' | 'error_storm';\n /** For `intervention`: true when a steer was actually delivered to the agent. */\n intervened?: boolean;\n /** Epoch milliseconds at which the event occurred. */\n at: number;\n}\n\n// ── Worktree lifecycle telemetry ────────────────────────────────────────────\n//\n// AutoPhase allocates one git worktree per phase so parallelizable phases run\n// isolated, then merges them back sequentially. These envelopes let HQ render\n// live build phase swim-lanes / DAG across every connected machine. All fields\n// are plain serializable data (the EventBus `worktree.*` payloads forwarded\n// with the type tag added).\n\nexport type HqWorktreeEventKind =\n | 'allocated'\n | 'committed'\n | 'merged'\n | 'conflict'\n | 'released'\n | 'failed';\n\nexport interface HqWorktreeEventPayload {\n /** Which worktree lifecycle event this is (mirrors `worktree.<kind>`). */\n kind: HqWorktreeEventKind;\n handleId: string;\n ownerId: string;\n ownerLabel?: string;\n slug?: string;\n branch?: string;\n baseBranch?: string;\n /** For `committed`: diff stats. */\n insertions?: number;\n deletions?: number;\n files?: number;\n sha?: string;\n /** For `merged`: whether the merge was a squash. */\n squash?: boolean;\n /** For `conflict`: the list of conflicting files. */\n conflictFiles?: readonly string[];\n /** For `released`: whether the worktree was kept (true) or pruned (false). */\n kept?: boolean;\n /** For `failed`: the error message. */\n error?: string;\n}\n\n// ── Session telemetry (live terminals + full chat transcript) ──────────────\n//\n// Every surface (tui / repl / webui / cli) streams its own live session state\n// and conversation transcript to HQ so the command center can render a true\n// machine → project → terminal → agent → full-history tree across every\n// connected machine — not just the one HQ happens to run on.\n\nexport type HqSessionLiveStatus = 'active' | 'idle' | 'closing' | 'stale';\n\nexport type HqSessionAgentLiveStatus = 'idle' | 'running' | 'streaming' | 'waiting_user' | 'error';\n\n/** A single live agent inside a session snapshot (mirrors SessionRegistry's AgentEntry). */\nexport interface HqSessionAgentSummary {\n id: string;\n name: string;\n /** UTC ISO timestamp when this agent/run started, when known. */\n startedAt?: string;\n status: HqSessionAgentLiveStatus;\n currentTool?: string;\n iterations: number;\n toolCalls: number;\n costUsd?: number;\n tokensIn?: number;\n tokensOut?: number;\n ctxPct?: number;\n model?: string;\n /** Throttled tail of the response currently streaming, when known. */\n partialText?: string;\n lastActivityAt: string;\n}\n\n/** Payload for `session.snapshot` — one connected terminal's live state. */\nexport interface HqSessionSnapshotPayload {\n sessionId: string;\n clientKind: HqClientKind;\n machineId: string;\n hostname?: string;\n pid?: number;\n projectId: string;\n projectName: string;\n projectRoot: string;\n gitBranch?: string;\n status: HqSessionLiveStatus;\n startedAt: string;\n lastActivityAt: string;\n agentCount: number;\n agents: readonly HqSessionAgentSummary[];\n}\n\nexport type HqTranscriptRole = 'user' | 'assistant' | 'thinking' | 'tool' | 'system' | 'error';\n\n/** One rendered conversation turn. Canonical shape shared by client streaming\n * and server-side JSONL replay so both planes agree. */\nexport interface HqTranscriptEntry {\n ts: string;\n role: HqTranscriptRole;\n text: string;\n tool?: string;\n /** Stringified tool input/arguments, for tool calls (shown alongside the result). */\n toolInput?: string;\n durationMs?: number;\n isError?: boolean;\n toolUseId?: string;\n /** Which agent/subagent produced this turn, when attribution is known. */\n agentId?: string;\n}\n\n/** Payload for `session.transcript` — an incremental batch of new turns. */\nexport interface HqTranscriptAppendPayload {\n sessionId: string;\n /** Monotonic sequence index of the FIRST entry in this batch within the session. */\n fromSeq: number;\n entries: readonly HqTranscriptEntry[];\n}\n\n/** Payload for `session.ended` — a terminal closed. */\nexport interface HqSessionEndedPayload {\n sessionId: string;\n endedAt: string;\n}\n\n/** A physical machine, aggregated by HQ from connected clients' machineId. */\nexport interface HqMachineRecord {\n machineId: string;\n hostname?: string;\n clientCount: number;\n sessionCount: number;\n agentCount: number;\n projectIds: readonly string[];\n lastActivityAt: string;\n}\n\nexport type HqMailboxMessageType =\n | 'note'\n | 'ask'\n | 'assign'\n | 'steer'\n | 'btw'\n | 'broadcast'\n | 'status'\n | 'result'\n | 'review'\n | 'control';\n\nexport type HqMailboxPriority = 'low' | 'normal' | 'high';\n\nexport type HqMailboxAgentStatus =\n | 'idle'\n | 'running'\n | 'streaming'\n | 'waiting_user'\n | 'error'\n | 'offline';\n\nexport interface HqMailboxMessageSummary {\n mailId: string; // unique UUID per message record, used for deduplication\n messageId: string;\n from: string;\n to: string;\n type: HqMailboxMessageType;\n subject: string;\n priority: HqMailboxPriority;\n timestamp: string;\n replyTo?: string;\n senderSessionId?: string;\n completed: boolean;\n completedBy?: string;\n completedAt?: string;\n unreadCount?: number;\n readCount?: number;\n hasBody: boolean;\n bodyPreview?: string;\n outcomePreview?: string;\n task?: {\n taskId?: string;\n agentRole?: string;\n agentName?: string;\n status?: 'pending' | 'in_progress' | 'completed' | 'failed';\n };\n}\n\nexport interface HqMailboxAgentSummary {\n agentId: string;\n name: string;\n role?: string;\n sessionId: string;\n status: HqMailboxAgentStatus;\n currentTool?: string;\n currentTask?: string;\n iterations: number;\n toolCalls: number;\n lastActivityAt: string;\n lastSeenAt: string;\n online: boolean;\n source?: 'cli' | 'webui' | 'mcp' | 'acp' | 'http';\n}\n\nexport interface HqMailboxSnapshotPayload {\n mailboxId: string;\n scope: 'project' | 'global';\n messages: readonly HqMailboxMessageSummary[];\n agents: readonly HqMailboxAgentSummary[];\n totals: {\n messages: number;\n unread: number;\n incomplete: number;\n highPriority: number;\n onlineAgents: number;\n };\n}\n\nexport interface HqMailboxEventPayload {\n mailboxId: string;\n action:\n | 'message.sent'\n | 'message.read'\n | 'message.completed'\n | 'message.updated'\n | 'agent.registered'\n | 'agent.heartbeat'\n | 'agent.offline'\n | 'agent.deregistered';\n message?: HqMailboxMessageSummary;\n agent?: HqMailboxAgentSummary;\n summary?: string;\n}\n\nexport interface HqWorklistSnapshotPayload {\n todos?: HqWorklistCounts;\n tasks?: HqWorklistCounts;\n plans?: HqWorklistCounts;\n activeItem?: string;\n}\n\nexport interface HqWorklistCounts {\n total: number;\n pending: number;\n inProgress: number;\n completed: number;\n failed?: number;\n}\n\nexport interface HqGitSnapshotPayload {\n branch?: string;\n dirtyFiles?: number;\n stagedFiles?: number;\n ahead?: number;\n behind?: number;\n}\n\nexport interface HqClientRecord {\n clientId: string;\n kind: HqClientKind;\n machineId: string;\n hostname?: string;\n pid?: number;\n version?: string;\n connected: boolean;\n connectedAt?: string;\n lastSeenAt: string;\n projectId: string;\n sessionId?: string;\n capabilities: readonly HqClientCapability[];\n}\n\nexport interface HqProjectRecord {\n projectId: string;\n projectName: string;\n projectRootDisplay: string;\n machineIds: readonly string[];\n gitBranch?: string;\n activeClients: number;\n activeSessions: number;\n activeSubagents: number;\n totalCostUsd: number;\n lastActivityAt: string;\n status: HqProjectStatus;\n}\n\nexport interface HqSessionSummary {\n sessionId: string;\n projectId: string;\n clientId: string;\n status: HqSessionStatus;\n provider?: string;\n model?: string;\n startedAt?: string;\n lastActivityAt: string;\n costUsd?: number;\n}\n\nexport interface HqFleetSummary {\n runId: string;\n projectId: string;\n clientId: string;\n activeSubagents: number;\n queuedTasks: number;\n completedTasks: number;\n failedTasks: number;\n totalCostUsd?: number;\n lastActivityAt: string;\n}\n\nexport interface HqMailboxSummary {\n mailboxId: string;\n projectId: string;\n scope: 'project' | 'global';\n messageCount: number;\n unreadCount: number;\n incompleteCount: number;\n highPriorityCount: number;\n onlineAgentCount: number;\n lastActivityAt: string;\n}\n\nexport interface HqSnapshot {\n generatedAt: string;\n clients: readonly HqClientRecord[];\n projects: readonly HqProjectRecord[];\n sessions: readonly HqSessionSummary[];\n fleets: readonly HqFleetSummary[];\n mailboxes: readonly HqMailboxSummary[];\n /** Physical machines aggregated from connected clients (optional, additive). */\n machines?: readonly HqMachineRecord[];\n /** Live terminal sessions with their agents — the spine of the fleet tree. */\n liveSessions?: readonly HqSessionSnapshotPayload[];\n totals: {\n activeProjects: number;\n activeClients: number;\n activeSessions: number;\n activeSubagents: number;\n unreadMailboxMessages: number;\n incompleteMailboxMessages: number;\n totalCostUsd: number;\n /** Distinct physical machines currently connected. */\n activeMachines?: number;\n /** Total live agents across all sessions. */\n activeAgents?: number;\n };\n}\n\nexport interface HqBrowserSnapshotMessage {\n type: 'hq.snapshot';\n snapshot: HqSnapshot;\n}\n\nexport interface HqBrowserEventMessage<TPayload = unknown> {\n type: 'hq.event';\n event: HqEventEnvelope<TPayload>;\n}\n\nexport interface HqAlertMessage {\n type: 'hq.alert';\n severity: 'info' | 'warn' | 'error';\n message: string;\n timestamp: string;\n}\n\nexport type HqBrowserMessage = HqBrowserSnapshotMessage | HqBrowserEventMessage | HqAlertMessage;\n\nexport interface HqClientHelloMessage {\n type: 'client.hello';\n payload: HqClientHelloPayload;\n}\n\nexport interface HqClientEventMessage<TPayload = unknown> {\n type: 'client.event';\n event: HqEventEnvelope<TPayload>;\n}\n\nexport interface HqClientCommandPollMessage {\n type: 'client.command_poll';\n clientId: string;\n projectId: string;\n afterCommandId?: string;\n limit?: number;\n}\n\nexport interface HqClientCommandAckMessage {\n type: 'client.command_ack';\n clientId: string;\n projectId: string;\n commandId: string;\n status: 'accepted' | 'completed' | 'failed' | 'rejected';\n message?: string;\n}\n\nexport interface HqQueuedCommand {\n commandId: string;\n type: string;\n createdAt: string;\n payload: unknown;\n requiresAck?: boolean;\n}\n\nexport interface HqServerCommandBatchMessage {\n type: 'hq.command_batch';\n commands: readonly HqQueuedCommand[];\n}\n\nexport type HqClientMessage =\n | HqClientHelloMessage\n | HqClientEventMessage\n | HqClientCommandPollMessage\n | HqClientCommandAckMessage;\n\nexport type HqServerMessage = HqServerCommandBatchMessage | HqWelcomePayload;\n\n/**\n * Discriminated parse result for {@link parseHqFrame}. The `reason` field\n * is only present when `ok` is `false`; consumers should narrow on `ok`\n * before accessing `frame` or `reason`.\n */\nexport type HqParseResult =\n | { ok: true; frame: HqClientMessage }\n | { ok: false; reason: 'invalid-json' | 'unknown-type' | 'malformed' };\n\n/** Known client → server frame `type` discriminators. */\nconst KNOWN_HQ_CLIENT_FRAME_TYPES = new Set<HqClientMessage['type']>([\n 'client.hello',\n 'client.event',\n 'client.command_poll',\n 'client.command_ack',\n]);\n\n/** Top-level object + string `type` guard. */\nfunction hasStringType(x: unknown): x is { type: string } {\n return typeof x === 'object' && x !== null && typeof (x as { type?: unknown }).type === 'string';\n}\n\nfunction isHqClientIdentity(x: unknown): x is HqClientIdentity {\n if (typeof x !== 'object' || x === null) return false;\n const v = x as Record<string, unknown>;\n return (\n typeof v.clientId === 'string' &&\n typeof v.kind === 'string' &&\n typeof v.machineId === 'string' &&\n typeof v.startedAt === 'string'\n );\n}\n\nfunction isHqProjectIdentity(x: unknown): x is HqProjectIdentity {\n if (typeof x !== 'object' || x === null) return false;\n const v = x as Record<string, unknown>;\n return (\n typeof v.projectId === 'string' &&\n typeof v.projectRoot === 'string' &&\n typeof v.projectName === 'string' &&\n typeof v.machineId === 'string' &&\n typeof v.workspaceKind === 'string'\n );\n}\n\nfunction isHqClientHelloPayload(x: unknown): x is HqClientHelloPayload {\n if (typeof x !== 'object' || x === null) return false;\n const v = x as Record<string, unknown>;\n return (\n typeof v.protocolVersion === 'number' &&\n isHqClientIdentity(v.client) &&\n isHqProjectIdentity(v.project) &&\n Array.isArray(v.capabilities)\n );\n}\n\nfunction isHqEventEnvelope(x: unknown): x is HqEventEnvelope {\n if (typeof x !== 'object' || x === null) return false;\n const v = x as Record<string, unknown>;\n return (\n typeof v.id === 'string' &&\n typeof v.type === 'string' &&\n typeof v.schemaVersion === 'number' &&\n typeof v.timestamp === 'string' &&\n typeof v.clientId === 'string' &&\n typeof v.projectId === 'string' &&\n typeof v.seq === 'number'\n );\n}\n\nfunction isHqClientCommandPollMessage(x: unknown): x is HqClientCommandPollMessage {\n if (typeof x !== 'object' || x === null) return false;\n const v = x as Record<string, unknown>;\n return typeof v.clientId === 'string' && typeof v.projectId === 'string';\n}\n\nfunction isHqClientCommandAckMessage(x: unknown): x is HqClientCommandAckMessage {\n if (typeof x !== 'object' || x === null) return false;\n const v = x as Record<string, unknown>;\n return (\n typeof v.clientId === 'string' &&\n typeof v.projectId === 'string' &&\n typeof v.commandId === 'string' &&\n typeof v.status === 'string'\n );\n}\n\n/**\n * Strictly parse a raw client → server frame into a {@link HqParseResult}.\n *\n * Validates, in order:\n * 1. JSON syntax (`invalid-json` on failure)\n * 2. Top-level object with string `type` discriminator\n * 3. `type` is one of {@link HqClientMessage} union members (`unknown-type`)\n * 4. Per-type field-shape presence checks (`malformed` on failure)\n *\n * On success, `frame` is narrowed to {@link HqClientMessage} and consumers\n * can switch on `frame.type` for type-safe access to per-union-member\n * fields without `as` casts.\n */\nexport function parseHqFrame(raw: string | Buffer): HqParseResult {\n let parsed: unknown;\n try {\n parsed = JSON.parse(typeof raw === 'string' ? raw : raw.toString('utf8'));\n } catch {\n return { ok: false, reason: 'invalid-json' };\n }\n\n if (!hasStringType(parsed)) {\n return { ok: false, reason: 'malformed' };\n }\n const obj = parsed as { type: string } & Record<string, unknown>;\n\n if (!KNOWN_HQ_CLIENT_FRAME_TYPES.has(obj.type as HqClientMessage['type'])) {\n return { ok: false, reason: 'unknown-type' };\n }\n\n switch (obj.type as HqClientMessage['type']) {\n case 'client.hello':\n if (!isHqClientHelloPayload(obj.payload)) {\n return { ok: false, reason: 'malformed' };\n }\n return { ok: true, frame: { type: 'client.hello', payload: obj.payload } };\n case 'client.event':\n if (!isHqEventEnvelope(obj.event)) {\n return { ok: false, reason: 'malformed' };\n }\n return { ok: true, frame: { type: 'client.event', event: obj.event } };\n case 'client.command_poll':\n if (!isHqClientCommandPollMessage(obj)) {\n return { ok: false, reason: 'malformed' };\n }\n return {\n ok: true,\n frame: { type: 'client.command_poll', clientId: obj.clientId, projectId: obj.projectId },\n };\n case 'client.command_ack':\n if (!isHqClientCommandAckMessage(obj)) {\n return { ok: false, reason: 'malformed' };\n }\n return {\n ok: true,\n frame: {\n type: 'client.command_ack',\n clientId: obj.clientId,\n projectId: obj.projectId,\n commandId: obj.commandId,\n status: obj.status as HqClientCommandAckMessage['status'],\n ...(typeof obj.message === 'string' ? { message: obj.message } : {}),\n },\n };\n default: {\n // Unreachable: KNOWN_HQ_CLIENT_FRAME_TYPES membership guarantees\n // `obj.type` is one of the cases above. Return `unknown-type` defensively\n // to satisfy the return type if a future HqClientMessage union member\n // is added without updating this switch.\n const _exhaustive: never = obj.type as never;\n return _exhaustive;\n }\n }\n}\n\n/** Known `client.event` envelope event types whose payload shape we validate. */\nconst KNOWN_HQ_EVENT_PAYLOAD_TYPES = new Set<string>([\n 'mailbox.snapshot',\n 'mailbox.event',\n 'session.snapshot',\n 'session.transcript',\n 'session.ended',\n 'fleet.snapshot',\n 'fleet.event',\n 'brain.event',\n 'worktree.event',\n 'tool.started',\n 'tool.completed',\n 'session.usage',\n]);\n\nfunction isHqMailboxMessageSummary(x: unknown): x is HqMailboxMessageSummary {\n if (typeof x !== 'object' || x === null) return false;\n const v = x as Record<string, unknown>;\n return (\n typeof v.messageId === 'string' &&\n typeof v.from === 'string' &&\n typeof v.to === 'string' &&\n typeof v.subject === 'string' &&\n typeof v.priority === 'string' &&\n typeof v.timestamp === 'string' &&\n typeof v.completed === 'boolean' &&\n typeof v.hasBody === 'boolean'\n );\n}\n\nfunction isHqMailboxAgentSummary(x: unknown): x is HqMailboxAgentSummary {\n if (typeof x !== 'object' || x === null) return false;\n const v = x as Record<string, unknown>;\n return (\n typeof v.agentId === 'string' &&\n typeof v.name === 'string' &&\n typeof v.sessionId === 'string' &&\n typeof v.status === 'string' &&\n typeof v.iterations === 'number' &&\n typeof v.toolCalls === 'number' &&\n typeof v.lastActivityAt === 'string' &&\n typeof v.lastSeenAt === 'string' &&\n typeof v.online === 'boolean'\n );\n}\n\nfunction isHqMailboxSnapshotPayload(x: unknown): x is HqMailboxSnapshotPayload {\n if (typeof x !== 'object' || x === null) return false;\n const v = x as Record<string, unknown>;\n if (\n typeof v.mailboxId !== 'string' ||\n (v.scope !== 'project' && v.scope !== 'global') ||\n !Array.isArray(v.messages) ||\n !Array.isArray(v.agents) ||\n typeof v.totals !== 'object' ||\n v.totals === null\n ) {\n return false;\n }\n const totals = v.totals as Record<string, unknown>;\n if (\n typeof totals.messages !== 'number' ||\n typeof totals.unread !== 'number' ||\n typeof totals.incomplete !== 'number' ||\n typeof totals.highPriority !== 'number' ||\n typeof totals.onlineAgents !== 'number'\n ) {\n return false;\n }\n for (const message of v.messages) {\n if (!isHqMailboxMessageSummary(message)) return false;\n }\n for (const agent of v.agents) {\n if (!isHqMailboxAgentSummary(agent)) return false;\n }\n return true;\n}\n\nconst HQ_MAILBOX_EVENT_ACTIONS = new Set<string>([\n 'message.sent',\n 'message.read',\n 'message.completed',\n 'message.updated',\n 'agent.registered',\n 'agent.heartbeat',\n 'agent.offline',\n 'agent.deregistered',\n]);\n\nfunction isHqMailboxEventPayload(x: unknown): x is HqMailboxEventPayload {\n if (typeof x !== 'object' || x === null) return false;\n const v = x as Record<string, unknown>;\n if (typeof v.mailboxId !== 'string') return false;\n if (typeof v.action !== 'string' || !HQ_MAILBOX_EVENT_ACTIONS.has(v.action)) return false;\n // `message` and `agent` are optional but, when present, must satisfy\n // their respective shape guard so a downstream consumer can rely on\n // the typed fields.\n if (v.message !== undefined && !isHqMailboxMessageSummary(v.message)) return false;\n if (v.agent !== undefined && !isHqMailboxAgentSummary(v.agent)) return false;\n return true;\n}\n\nconst HQ_SESSION_AGENT_STATUSES = new Set<string>([\n 'idle',\n 'running',\n 'streaming',\n 'waiting_user',\n 'error',\n]);\n\nfunction isHqSessionAgentSummary(x: unknown): x is HqSessionAgentSummary {\n if (typeof x !== 'object' || x === null) return false;\n const v = x as Record<string, unknown>;\n return (\n typeof v.id === 'string' &&\n typeof v.name === 'string' &&\n typeof v.status === 'string' &&\n HQ_SESSION_AGENT_STATUSES.has(v.status) &&\n typeof v.iterations === 'number' &&\n typeof v.toolCalls === 'number' &&\n typeof v.lastActivityAt === 'string'\n );\n}\n\nconst HQ_SESSION_STATUSES = new Set<string>(['active', 'idle', 'closing', 'stale']);\n\nfunction isHqSessionSnapshotPayload(x: unknown): x is HqSessionSnapshotPayload {\n if (typeof x !== 'object' || x === null) return false;\n const v = x as Record<string, unknown>;\n if (\n typeof v.sessionId !== 'string' ||\n typeof v.clientKind !== 'string' ||\n typeof v.machineId !== 'string' ||\n typeof v.projectId !== 'string' ||\n typeof v.projectName !== 'string' ||\n typeof v.projectRoot !== 'string' ||\n typeof v.status !== 'string' ||\n !HQ_SESSION_STATUSES.has(v.status) ||\n typeof v.startedAt !== 'string' ||\n typeof v.lastActivityAt !== 'string' ||\n typeof v.agentCount !== 'number' ||\n !Array.isArray(v.agents)\n ) {\n return false;\n }\n for (const agent of v.agents) {\n if (!isHqSessionAgentSummary(agent)) return false;\n }\n return true;\n}\n\nconst HQ_TRANSCRIPT_ROLES = new Set<string>([\n 'user',\n 'assistant',\n 'thinking',\n 'tool',\n 'system',\n 'error',\n]);\n\nfunction isHqTranscriptEntry(x: unknown): x is HqTranscriptEntry {\n if (typeof x !== 'object' || x === null) return false;\n const v = x as Record<string, unknown>;\n return (\n typeof v.ts === 'string' &&\n typeof v.role === 'string' &&\n HQ_TRANSCRIPT_ROLES.has(v.role) &&\n typeof v.text === 'string'\n );\n}\n\nfunction isHqTranscriptAppendPayload(x: unknown): x is HqTranscriptAppendPayload {\n if (typeof x !== 'object' || x === null) return false;\n const v = x as Record<string, unknown>;\n if (\n typeof v.sessionId !== 'string' ||\n typeof v.fromSeq !== 'number' ||\n !Array.isArray(v.entries)\n ) {\n return false;\n }\n for (const entry of v.entries) {\n if (!isHqTranscriptEntry(entry)) return false;\n }\n return true;\n}\n\nfunction isHqSessionEndedPayload(x: unknown): x is HqSessionEndedPayload {\n if (typeof x !== 'object' || x === null) return false;\n const v = x as Record<string, unknown>;\n return typeof v.sessionId === 'string' && typeof v.endedAt === 'string';\n}\n\nconst HQ_FLEET_SUBAGENT_STATUS = new Set<string>([\n 'pending',\n 'running',\n 'idle',\n 'completed',\n 'failed',\n 'stopped',\n]);\n\nfunction isHqSubagentSummary(x: unknown): x is HqSubagentSummary {\n if (typeof x !== 'object' || x === null) return false;\n const v = x as Record<string, unknown>;\n return (\n typeof v.subagentId === 'string' &&\n typeof v.status === 'string' &&\n HQ_FLEET_SUBAGENT_STATUS.has(v.status)\n );\n}\n\nfunction isHqFleetSnapshotPayload(x: unknown): x is HqFleetSnapshotPayload {\n if (typeof x !== 'object' || x === null) return false;\n const v = x as Record<string, unknown>;\n if (\n typeof v.runId !== 'string' ||\n typeof v.activeSubagents !== 'number' ||\n typeof v.queuedTasks !== 'number' ||\n typeof v.completedTasks !== 'number' ||\n typeof v.failedTasks !== 'number' ||\n !Array.isArray(v.subagents)\n ) {\n return false;\n }\n for (const s of v.subagents) {\n if (!isHqSubagentSummary(s)) return false;\n }\n return true;\n}\n\nfunction isHqFleetEventPayload(x: unknown): x is HqFleetEventPayload {\n if (typeof x !== 'object' || x === null) return false;\n const v = x as Record<string, unknown>;\n return typeof v.runId === 'string' && typeof v.event === 'string';\n}\n\nconst HQ_BRAIN_EVENT_KINDS = new Set<string>([\n 'decision_requested',\n 'decision_answered',\n 'decision_ask_human',\n 'human_answered',\n 'decision_denied',\n 'intervention',\n]);\n\nfunction isHqBrainEventPayload(x: unknown): x is HqBrainEventPayload {\n if (typeof x !== 'object' || x === null) return false;\n const v = x as Record<string, unknown>;\n if (typeof v.kind !== 'string' || !HQ_BRAIN_EVENT_KINDS.has(v.kind)) return false;\n if (typeof v.at !== 'number') return false;\n return true;\n}\n\nconst HQ_WORKTREE_EVENT_KINDS = new Set<string>([\n 'allocated',\n 'committed',\n 'merged',\n 'conflict',\n 'released',\n 'failed',\n]);\n\nfunction isHqWorktreeEventPayload(x: unknown): x is HqWorktreeEventPayload {\n if (typeof x !== 'object' || x === null) return false;\n const v = x as Record<string, unknown>;\n if (typeof v.kind !== 'string' || !HQ_WORKTREE_EVENT_KINDS.has(v.kind)) return false;\n if (typeof v.handleId !== 'string' || typeof v.ownerId !== 'string') return false;\n return true;\n}\n\nfunction isHqToolStartedPayload(x: unknown): x is HqToolStartedPayload {\n if (typeof x !== 'object' || x === null) return false;\n const v = x as Record<string, unknown>;\n return typeof v.toolName === 'string';\n}\n\nfunction isHqToolCompletedPayload(x: unknown): x is HqToolCompletedPayload {\n if (typeof x !== 'object' || x === null) return false;\n const v = x as Record<string, unknown>;\n return (\n typeof v.toolName === 'string' &&\n typeof v.status === 'string' &&\n typeof v.durationMs === 'number'\n );\n}\n\nfunction isHqUsagePayload(x: unknown): x is HqUsagePayload {\n if (typeof x !== 'object' || x === null) return false;\n // HqUsagePayload has all-optional numeric fields; accept any object so the\n // cost signal is never dropped on a partial payload, but require it be a\n // plain object (not array/null) to keep the downstream typed.\n return !Array.isArray(x);\n}\n\n/**\n * Validate the `payload` field of a {@link HqEventEnvelope} for known\n * event types. Returns `{ ok: true, payload }` with a narrowed payload\n * type when the event type has a registered shape guard and the payload\n * matches it; `{ ok: true, payload: unknown }` for event types that the\n * server does not yet validate; or `{ ok: false, reason }` when the\n * payload fails the registered guard.\n *\n * Use this after {@link parseHqFrame} has produced a valid frame, when\n * the frame is `client.event` and the server is about to consume the\n * event payload.\n */\nexport type HqEventPayloadResult<T> =\n | { ok: true; payload: T }\n | { ok: false; reason: 'unknown-event-type' | 'malformed-payload' };\n\nexport function parseHqEventPayload(\n eventType: string,\n payload: unknown,\n): HqEventPayloadResult<unknown> {\n if (!KNOWN_HQ_EVENT_PAYLOAD_TYPES.has(eventType)) {\n // Server does not validate this event type yet — pass it through\n // untyped so the publish pipeline is not blocked. Future events\n // can opt-in by adding their type + guard here.\n return { ok: true, payload };\n }\n switch (eventType) {\n case 'mailbox.snapshot':\n return isHqMailboxSnapshotPayload(payload)\n ? { ok: true, payload }\n : { ok: false, reason: 'malformed-payload' };\n case 'mailbox.event':\n return isHqMailboxEventPayload(payload)\n ? { ok: true, payload }\n : { ok: false, reason: 'malformed-payload' };\n case 'session.snapshot':\n return isHqSessionSnapshotPayload(payload)\n ? { ok: true, payload }\n : { ok: false, reason: 'malformed-payload' };\n case 'session.transcript':\n return isHqTranscriptAppendPayload(payload)\n ? { ok: true, payload }\n : { ok: false, reason: 'malformed-payload' };\n case 'session.ended':\n return isHqSessionEndedPayload(payload)\n ? { ok: true, payload }\n : { ok: false, reason: 'malformed-payload' };\n case 'fleet.snapshot':\n return isHqFleetSnapshotPayload(payload)\n ? { ok: true, payload }\n : { ok: false, reason: 'malformed-payload' };\n case 'fleet.event':\n return isHqFleetEventPayload(payload)\n ? { ok: true, payload }\n : { ok: false, reason: 'malformed-payload' };\n case 'brain.event':\n return isHqBrainEventPayload(payload)\n ? { ok: true, payload }\n : { ok: false, reason: 'malformed-payload' };\n case 'worktree.event':\n return isHqWorktreeEventPayload(payload)\n ? { ok: true, payload }\n : { ok: false, reason: 'malformed-payload' };\n case 'tool.started':\n return isHqToolStartedPayload(payload)\n ? { ok: true, payload }\n : { ok: false, reason: 'malformed-payload' };\n case 'tool.completed':\n return isHqToolCompletedPayload(payload)\n ? { ok: true, payload }\n : { ok: false, reason: 'malformed-payload' };\n case 'session.usage':\n return isHqUsagePayload(payload)\n ? { ok: true, payload }\n : { ok: false, reason: 'malformed-payload' };\n default: {\n const _exhaustive: never = eventType as never;\n return _exhaustive;\n }\n }\n}\n\nexport function createHqEventEnvelope<TPayload>(input: {\n id: string;\n type: HqEventType | (string & {});\n timestamp: string;\n clientId: string;\n projectId: string;\n seq: number;\n payload: TPayload;\n sessionId?: string;\n runId?: string;\n}): HqEventEnvelope<TPayload> {\n return {\n id: input.id,\n type: input.type,\n schemaVersion: HQ_PROTOCOL_VERSION,\n timestamp: input.timestamp,\n clientId: input.clientId,\n projectId: input.projectId,\n seq: input.seq,\n payload: input.payload,\n ...(input.sessionId !== undefined ? { sessionId: input.sessionId } : {}),\n ...(input.runId !== undefined ? { runId: input.runId } : {}),\n };\n}\n","import type { SecretScrubber } from '../types/secret-scrubber.js';\n\ninterface Pattern {\n type: string;\n regex: RegExp;\n}\n\nconst PATTERNS: Pattern[] = [\n // Anchored at the start where possible so partial matches inside larger\n // strings don't trigger false positives.\n {\n type: 'anthropic_key',\n regex: /(?<![A-Za-z0-9])sk-ant-api\\d+-[A-Za-z0-9_-]{20,}(?![A-Za-z0-9])/g,\n },\n { type: 'openai_key', regex: /(?<![A-Za-z0-9])sk-(?:proj-)?[A-Za-z0-9_-]{20,}(?![A-Za-z0-9])/g },\n { type: 'github_pat', regex: /(?<![A-Za-z0-9])ghp_[A-Za-z0-9]{36,}(?![A-Za-z0-9])/g },\n { type: 'github_pat_v2', regex: /(?<![A-Za-z0-9])github_pat_[A-Za-z0-9_]{50,}(?![A-Za-z0-9])/g },\n { type: 'aws_access_key', regex: /(?<![A-Za-z0-9])AKIA[0-9A-Z]{16}(?![A-Za-z0-9])/g },\n { type: 'gcp_key', regex: /(?<![A-Za-z0-9])AIza[0-9A-Za-z_-]{35}(?![A-Za-z0-9])/g },\n { type: 'slack_token', regex: /(?<![A-Za-z0-9-])xox[abpos]-[A-Za-z0-9-]{10,}(?![A-Za-z0-9-])/g },\n {\n type: 'stripe_key',\n regex: /(?<![A-Za-z0-9])sk_(?:live|test)_[A-Za-z0-9]{24,}(?![A-Za-z0-9])/g,\n },\n {\n type: 'twilio_sid', regex: /(?<![A-Za-z0-9])AC[a-f0-9]{32}(?![A-Za-z0-9])/g,\n },\n {\n type: 'telegram_bot_token',\n // Telegram tokens are of the form bot<digits>:<alphanum> in URL paths\n regex: /\\/bot\\d+:[A-Za-z0-9_-]{20,}(?![A-Za-z0-9_-])/g,\n },\n {\n type: 'jwt',\n // Anchored: look for literal \"eyJ\" which is unambiguous for JWT header\n regex:\n /(?<![A-Za-z0-9/+=])eyJ[A-Za-z0-9_-]{10,}\\.[A-Za-z0-9_-]{10,}\\.[A-Za-z0-9_-]{10,}(?![A-Za-z0-9/+=])/g,\n },\n {\n type: 'private_key',\n // Anchored: start must be BEGIN, end must be END with no extra dashes after END\n regex:\n /(?:^|\\n)-----BEGIN (?:RSA|EC|OPENSSH|DSA|PGP)? ?PRIVATE KEY-----[\\s\\S]*?-----END[^-]*-----(?:\\n|$)/g,\n },\n { type: 'mongodb_uri', regex: /mongodb(?:\\+srv)?:\\/\\/[^\\s\"'`]+/g },\n { type: 'postgres_uri', regex: /postgres(?:ql)?:\\/\\/[^\\s\"'`]+/g },\n { type: 'mysql_uri', regex: /mysql:\\/\\/[^\\s\"'`]+/g },\n { type: 'redis_uri', regex: /redis:\\/\\/[^\\s\"'`]+/g },\n // AI/ML provider keys — modern LLM services with well-known prefixes\n {\n type: 'huggingface_token',\n // HuggingFace tokens: hf_ followed by 34 alphanumeric chars\n regex: /(?<![A-Za-z0-9])hf_[A-Za-z0-9]{34}(?![A-Za-z0-9])/g,\n },\n {\n type: 'replicate_token',\n // Replicate tokens: r8_ followed by 40+ alphanumeric chars\n regex: /(?<![A-Za-z0-9])r8_[A-Za-z0-9]{40,}(?![A-Za-z0-9])/g,\n },\n {\n type: 'perplexity_key',\n // Perplexity API keys: pplx- followed by 40+ alphanumeric chars\n regex: /(?<![A-Za-z0-9])pplx-[A-Za-z0-9]{40,}(?![A-Za-z0-9])/g,\n },\n {\n type: 'groq_key',\n // Groq API keys: gsk_ followed by 40+ alphanumeric chars\n regex: /(?<![A-Za-z0-9])gsk_[A-Za-z0-9]{40,}(?![A-Za-z0-9])/g,\n },\n {\n type: 'bearer_token',\n // Anchored with alternation instead of negative lookahead — avoids V8\n // backtracking risk on adversarial input. Bounded at 512 chars.\n // Min 12 chars: some OAuth providers issue shorter-lived tokens (< 20\n // chars). A 12-char base64 string has ~71 bits of entropy — above the\n // threshold where random strings are unlikely to produce false matches.\n // The trailing boundary is a NON-consuming lookahead: two adjacent bearer\n // tokens sharing a single delimiter (`Bearer a… Bearer b…`) must both be\n // redacted. A consuming trailing delimiter would eat the separator the\n // next match needs for its leading anchor, leaking the second token.\n regex: /(?:^|[^A-Za-z0-9_.~+/-])Bearer\\s+[A-Za-z0-9._~+/-]{12,512}=*(?=$|[^A-Za-z0-9_.~+/-])/g,\n },\n {\n type: 'high_entropy_env',\n // Anchored with alternation instead of lookbehind to avoid backtracking.\n // Value bounded at 512 chars.\n // The trailing boundary is a NON-consuming lookahead so two secrets\n // separated by a single delimiter (one space OR one newline, e.g.\n // `printenv` / `.env` dumps: `API_KEY=… \\n SESSION_TOKEN=…`) are BOTH\n // redacted. A consuming trailing `\\s` would swallow the separator the\n // next match needs for its leading anchor, so every other secret would\n // leak in plaintext.\n // The leading delimiter is CAPTURED (group 1) and re-emitted by the\n // replacement so the separator between adjacent secrets is preserved\n // rather than collapsed. Capture groups are therefore: 1=leading\n // delimiter, 2=key name, 3=value.\n regex: /(^|\\s)([A-Z_]{4,}(?:KEY|TOKEN|SECRET|PASSWORD|PWD))\\s*[:=]\\s*['\"]?([A-Za-z0-9_/+=-]{20,512})['\"]?(?=\\s|$)/g,\n },\n];\n\n/**\n * `high_entropy_env` is the one pattern that needs special replacement logic\n * (it preserves the key name), so it runs in its own pass. Every other pattern\n * is folded into a single combined regex. Derive the split by type rather than\n * by hard-coded indices so adding/removing a pattern can't silently drop one.\n */\nconst SIMPLE_PATTERNS = PATTERNS.filter((p) => p.type !== 'high_entropy_env');\n\n/**\n * Combined single-pass regex for all simple patterns. Each alternative is a\n * capturing group so the callback can determine which original pattern fired\n * (only one group is non-undefined at match time). Order matches SIMPLE_PATTERNS\n * (longer/more-specific prefixes first). Relies on each simple pattern source\n * containing no internal capturing groups — only `(?:...)` and lookarounds.\n */\nconst COMBINED_REGEX = new RegExp(SIMPLE_PATTERNS.map((p) => `(${p.regex.source})`).join('|'), 'g');\n\n/** Separate pattern for high_entropy_env (different replacement logic). */\nconst HIGH_ENTROPY_REGEX = PATTERNS.find((p) => p.type === 'high_entropy_env')!.regex;\n\n/**\n * Replacements for the combined patterns, parallel to SIMPLE_PATTERNS. The\n * combined-regex callback indexes into this with the matched group's position.\n */\nconst COMBINED_REPLACEMENTS = SIMPLE_PATTERNS.map((p) => `[REDACTED:${p.type}]`);\n\n/**\n * Per-chunk cap. Splits long inputs into 64 KB chunks to keep scrub() memory\n * bounded. Real scrub() inputs (LLM responses, tool outputs) are typically\n * much smaller; this cap handles edge cases without impacting normal usage.\n */\nconst SCRUB_CHUNK_BYTES = 64 * 1024;\n\n/**\n * Overlap window used to nudge a chunk boundary onto a safe separator so a\n * secret straddling the 64 KB cut isn't split in half (which would leave\n * neither half matching, leaking the secret verbatim).\n *\n * Sized above the longest BOUNDED credential pattern: `high_entropy_env`\n * caps its value at 512 chars (+ key name + quotes ≈ 560) and `bearer_token`\n * at 512; every prefix-keyed pattern is far shorter. Because all of these\n * patterns are whitespace-free, the first whitespace at/after the nominal cut\n * is guaranteed to sit *past the end* of any such secret — so snapping the\n * boundary forward to it keeps every bounded secret wholly inside one chunk.\n * 1 KB gives comfortable headroom over the 560-char worst case.\n */\nconst SCRUB_OVERLAP_BYTES = 1024;\n\n/**\n * Quick pre-scan: check if the text contains any substring that MUST be\n * present for a credential pattern to match. If none are found, the text\n * is guaranteed clean — skip all regex passes (2 total: 16-pattern combined + high_entropy_env).\n *\n * Each anchor is the shortest unique substring from the corresponding pattern.\n * V8's `String.includes()` is hand-tuned C++ — O(n) with near-zero overhead\n * for typical tool-output lengths (100–5000 chars). A single combined regex\n * via `text.search()` is consistently slower for this many alternatives.\n */\nfunction hasCredentialAnchors(text: string): boolean {\n return (\n text.includes('-----BEGIN') || // Private keys (most unique → cheap reject)\n text.includes('sk-') || // Anthropic + OpenAI keys\n text.includes('sk_') || // Stripe live/test keys\n text.includes('ghp_') || // GitHub PAT v1\n text.includes('github_pat_') || // GitHub PAT v2\n text.includes('eyJ') || // JWT\n text.includes('AKIA') || // AWS access key\n text.includes('AIza') || // GCP service key\n text.includes('xox') || // Slack token (xoxa/xoxb/xoxp/xoxo/xoxs)\n text.includes('Bearer ') || // Bearer token (space suffix reduces false positives)\n text.includes('/bot') || // Telegram bot token (URL path pattern)\n text.includes('hf_') || // HuggingFace token\n text.includes('r8_') || // Replicate token\n text.includes('pplx-') || // Perplexity API key\n text.includes('gsk_') || // Groq API key\n text.includes('_KEY=') || // High-entropy env vars: API_KEY=, SECRET_KEY=, ...\n text.includes('_TOKEN=') || // ACCESS_TOKEN=, AUTH_TOKEN=, ...\n text.includes('_SECRET=') || // API_SECRET=, CLIENT_SECRET=, ...\n text.includes('_PASSWORD=') || // DB_PASSWORD=, ROOT_PASSWORD=, ...\n text.includes('mongodb://') ||\n text.includes('mongodb+srv://') ||\n text.includes('postgres://') ||\n text.includes('postgresql://') ||\n text.includes('mysql://') ||\n text.includes('redis://')\n );\n}\n\nexport class DefaultSecretScrubber implements SecretScrubber {\n scrub(text: string): string {\n if (!text) return text;\n\n // Fast path: if no credential anchor substrings exist in the text,\n // none of the 17 regex patterns can match. Skip all regex work.\n // This covers the vast majority of tool outputs (~95% of calls on\n // typical sessions are file paths, status messages, diffs, etc.).\n if (!hasCredentialAnchors(text)) return text;\n\n // For oversize inputs, scrub in fixed chunks to keep memory bounded.\n // The boundary is snapped FORWARD to the next whitespace within an\n // overlap window so a secret straddling the nominal 64 KB cut is never\n // split in half. Every bounded credential pattern is whitespace-free, so\n // the next whitespace at/after the cut necessarily falls past the end of\n // any such secret — guaranteeing it stays wholly inside the current chunk.\n if (text.length <= SCRUB_CHUNK_BYTES) {\n return this.scrubOne(text);\n }\n const out: string[] = [];\n let i = 0;\n while (i < text.length) {\n let end = Math.min(i + SCRUB_CHUNK_BYTES, text.length);\n if (end < text.length) {\n // Look for the first whitespace at/after the nominal cut, bounded by\n // the overlap window. Extending forward (not backward) ensures any\n // secret that began before `end` finishes before the new boundary.\n const limit = Math.min(end + SCRUB_OVERLAP_BYTES, text.length);\n let safe = -1;\n for (let j = end; j < limit; j++) {\n const ch = text.charCodeAt(j);\n // space, \\t, \\n, \\r\n if (ch === 32 || ch === 9 || ch === 10 || ch === 13) {\n safe = j;\n break;\n }\n }\n // Snap onto the whitespace if found; otherwise fall back to the hard\n // cut (an unbroken >1 KB run with no whitespace can't be a bounded\n // secret anyway — those are all ≤ ~560 chars and whitespace-free).\n end = safe === -1 ? end : safe + 1;\n }\n out.push(this.scrubOne(text.slice(i, end)));\n i = end;\n }\n return out.join('');\n }\n\n private scrubOne(text: string): string {\n // Redundant guard: if we reached scrubOne via the chunked path, the\n // chunk may have been small enough to anchor-skip independently.\n if (!hasCredentialAnchors(text)) return text;\n\n // Pass 1: combined single-pass regex for all simple patterns. Each\n // alternative is a capturing group; only the group that matched is\n // non-undefined. The trailing offset/string args replace() appends are\n // always defined, so the matched group (which precedes them) is found first.\n let out = text.replace(\n COMBINED_REGEX,\n (match, ...groups) => {\n // groups[i] corresponds to SIMPLE_PATTERNS[i]; find which one fired.\n const idx = groups.findIndex((g) => g !== undefined);\n if (idx < 0) return match;\n const replacement = COMBINED_REPLACEMENTS[idx];\n return replacement !== undefined ? replacement : match;\n },\n );\n\n // Pass 2: high_entropy_env needs special handling — preserve the key name.\n // Groups: 1=leading delimiter (re-emitted so adjacent-secret separators\n // aren't collapsed), 2=key name, 3=value (redacted).\n out = out.replace(HIGH_ENTROPY_REGEX, (_match, lead, key, _value) => {\n return `${lead}${key}=[REDACTED:high_entropy_env]`;\n });\n\n return out;\n }\n\n /**\n * Recursively scrub every string value in an object/array graph. Secrets can\n * appear under any key — a URL query param, an `authorization` header, an\n * arbitrarily-named nested field — so we don't gate recursion on key names.\n * The per-string `scrub()` fast-path (anchor pre-scan) keeps this cheap: any\n * value without a credential anchor returns immediately without regex work.\n */\n scrubObject<T>(obj: T): T {\n const seen = new WeakSet();\n const visit = (v: unknown): unknown => {\n if (typeof v === 'string') return this.scrub(v);\n if (v === null || typeof v !== 'object') return v;\n if (seen.has(v as object)) return v;\n seen.add(v as object);\n if (Array.isArray(v)) return v.map(visit);\n const out: Record<string, unknown> = {};\n for (const [k, val] of Object.entries(v as Record<string, unknown>)) {\n out[k] = visit(val);\n }\n return out;\n };\n return visit(obj) as T;\n }\n}\n","import { DefaultSecretScrubber } from '../security/secret-scrubber.js';\nimport {\n DEFAULT_HQ_REDACTION_POLICY,\n type HqEventEnvelope,\n type HqRedactionPolicy,\n} from './protocol.js';\n\nconst RAW_CONTENT_REPLACEMENT = '[REDACTED:hq_raw_content]';\nconst SENSITIVE_FIELD_REPLACEMENT = '[REDACTED:hq_sensitive_field]';\nconst REDACTED_PATH_REPLACEMENT = '[REDACTED:hq_path]';\n\nconst RAW_CONTENT_KEYS = new Set([\n 'content',\n 'contents',\n 'raw',\n 'rawContent',\n 'body',\n 'message',\n 'messages',\n 'prompt',\n 'prompts',\n 'completion',\n 'response',\n 'assistantMessage',\n 'userMessage',\n 'stdout',\n 'stderr',\n 'output',\n 'toolInput',\n 'toolOutput',\n 'body',\n 'mailboxBody',\n 'messageBody',\n 'outcome',\n 'fileContent',\n 'diff',\n 'patch',\n 'transcript',\n 'logs',\n]);\n\nconst SENSITIVE_KEYS = new Set([\n 'authorization',\n 'cookie',\n 'password',\n 'passwd',\n 'pwd',\n 'secret',\n 'token',\n 'accessToken',\n 'refreshToken',\n 'apiKey',\n 'apikey',\n 'clientSecret',\n 'privateKey',\n]);\n\nconst PATH_KEYS = new Set([\n 'path',\n 'paths',\n 'file',\n 'files',\n 'filepath',\n 'filePath',\n 'filename',\n 'projectRoot',\n 'projectRootDisplay',\n 'cwd',\n 'workingDir',\n 'workingDirectory',\n]);\n\nexport interface HqRedactOptions {\n policy?: Partial<HqRedactionPolicy>;\n projectRoot?: string;\n maxSummaryLength?: number;\n}\n\nexport interface HqRedactionResult<T> {\n value: T;\n redacted: boolean;\n}\n\nconst defaultScrubber = new DefaultSecretScrubber();\n\nfunction resolvePolicy(policy?: Partial<HqRedactionPolicy>): HqRedactionPolicy {\n return {\n ...DEFAULT_HQ_REDACTION_POLICY,\n ...policy,\n };\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return Object.prototype.toString.call(value) === '[object Object]';\n}\n\nfunction isSensitiveKey(key: string): boolean {\n const lower = key.toLowerCase();\n return (\n SENSITIVE_KEYS.has(key) ||\n lower.includes('authorization') ||\n lower.includes('password') ||\n lower.includes('secret') ||\n lower.endsWith('token') ||\n lower.endsWith('apikey') ||\n lower.endsWith('api_key')\n );\n}\n\nfunction isRawContentKey(key: string): boolean {\n return RAW_CONTENT_KEYS.has(key) || RAW_CONTENT_KEYS.has(key.toLowerCase());\n}\n\nfunction isPathKey(key: string): boolean {\n return PATH_KEYS.has(key) || PATH_KEYS.has(key.toLowerCase());\n}\n\nfunction normalizePathForCompare(value: string): string {\n return value.replace(/\\\\/g, '/').replace(/\\/+$/g, '');\n}\n\nfunction redactPath(\n value: string,\n projectRoot: string | undefined,\n policy: HqRedactionPolicy,\n): string {\n if (policy.paths === 'full') return defaultScrubber.scrub(value);\n if (policy.paths === 'none' || policy.paths === 'redacted') return REDACTED_PATH_REPLACEMENT;\n\n const normalizedValue = normalizePathForCompare(value);\n if (!projectRoot) return normalizedValue.split('/').at(-1) ?? REDACTED_PATH_REPLACEMENT;\n\n const normalizedRoot = normalizePathForCompare(projectRoot);\n if (normalizedValue === normalizedRoot) return '.';\n if (normalizedValue.startsWith(`${normalizedRoot}/`)) {\n return normalizedValue.slice(normalizedRoot.length + 1) || '.';\n }\n return normalizedValue.split('/').at(-1) ?? REDACTED_PATH_REPLACEMENT;\n}\n\nfunction summarizeString(value: string, maxSummaryLength: number): string {\n const scrubbed = defaultScrubber.scrub(value);\n if (scrubbed.length <= maxSummaryLength) return scrubbed;\n return `${scrubbed.slice(0, maxSummaryLength)}…[truncated:${scrubbed.length - maxSummaryLength}]`;\n}\n\n/**\n * Scrub a free-text preview field and truncate it to a maximum length so\n * it is safe to embed in HQ event envelopes and broadcast to browsers\n * without leaking secrets or running away on unbounded input.\n *\n * Returns `undefined` when the input is empty or non-string. Truncation\n * suffix is `\"…[truncated:N]\"` where N is the number of dropped chars.\n */\nexport function scrubAndTruncateHqPreview(\n value: unknown,\n maxLength: number = 280,\n): string | undefined {\n if (typeof value !== 'string' || value.length === 0) return undefined;\n return summarizeString(value, maxLength);\n}\n\nfunction visitValue(\n value: unknown,\n options: {\n policy: HqRedactionPolicy;\n projectRoot?: string;\n maxSummaryLength: number;\n seen: WeakSet<object>;\n },\n key?: string,\n): { value: unknown; redacted: boolean } {\n if (key !== undefined && isSensitiveKey(key)) {\n return { value: SENSITIVE_FIELD_REPLACEMENT, redacted: true };\n }\n\n if (typeof value === 'string') {\n if (key !== undefined && isPathKey(key)) {\n const redactedPath = redactPath(value, options.projectRoot, options.policy);\n return { value: redactedPath, redacted: redactedPath !== value };\n }\n\n if (!options.policy.rawContent && key !== undefined && isRawContentKey(key)) {\n return { value: RAW_CONTENT_REPLACEMENT, redacted: true };\n }\n\n const scrubbed = summarizeString(value, options.maxSummaryLength);\n return { value: scrubbed, redacted: scrubbed !== value };\n }\n\n if (value === null || typeof value !== 'object') return { value, redacted: false };\n\n if (options.seen.has(value)) return { value: '[REDACTED:hq_circular]', redacted: true };\n options.seen.add(value);\n\n if (Array.isArray(value)) {\n let redacted = false;\n const out = value.map((item) => {\n const next = visitValue(item, options, key);\n redacted ||= next.redacted;\n return next.value;\n });\n return { value: out, redacted };\n }\n\n if (!isPlainObject(value)) return { value: String(value), redacted: true };\n\n let redacted = false;\n const out: Record<string, unknown> = {};\n for (const [childKey, childValue] of Object.entries(value)) {\n const next = visitValue(childValue, options, childKey);\n redacted ||= next.redacted;\n out[childKey] = next.value;\n }\n return { value: out, redacted };\n}\n\nexport function redactHqValue<T>(value: T, options: HqRedactOptions = {}): HqRedactionResult<T> {\n const result = visitValue(value, {\n policy: resolvePolicy(options.policy),\n ...(options.projectRoot !== undefined ? { projectRoot: options.projectRoot } : {}),\n maxSummaryLength: options.maxSummaryLength ?? 500,\n seen: new WeakSet<object>(),\n });\n return { value: result.value as T, redacted: result.redacted };\n}\n\nexport function redactHqEvent<TPayload>(\n event: HqEventEnvelope<TPayload>,\n options: HqRedactOptions = {},\n): HqRedactionResult<HqEventEnvelope<TPayload>> {\n const payload = redactHqValue(event.payload, options);\n const nextEvent = {\n ...event,\n payload: payload.value,\n };\n return { value: nextEvent, redacted: payload.redacted };\n}\n\nexport function summarizeHqToolArgs(value: unknown, options: HqRedactOptions = {}): unknown {\n const policy = resolvePolicy(options.policy);\n if (policy.toolArgs === 'none') return '[REDACTED:hq_tool_args]';\n if (policy.toolArgs === 'redacted') return redactHqValue(value, options).value;\n\n if (value === null || typeof value !== 'object') return redactHqValue(value, options).value;\n if (Array.isArray(value)) return `[array:${value.length}]`;\n\n const entries = Object.entries(value as Record<string, unknown>);\n const summary: Record<string, unknown> = {};\n for (const [key, item] of entries.slice(0, 20)) {\n if (isSensitiveKey(key)) {\n summary[key] = SENSITIVE_FIELD_REPLACEMENT;\n } else if (typeof item === 'string') {\n summary[key] = isPathKey(key)\n ? redactPath(item, options.projectRoot, policy)\n : summarizeString(item, 120);\n } else if (Array.isArray(item)) {\n summary[key] = `[array:${item.length}]`;\n } else if (item !== null && typeof item === 'object') {\n summary[key] = '[object]';\n } else {\n summary[key] = item;\n }\n }\n if (entries.length > 20) summary.__truncatedKeys = entries.length - 20;\n return summary;\n}\n","import type { Mailbox, MailboxAgentStatus, MailboxMessage } from '../coordination/mailbox-types.js';\nimport type {\n HqMailboxAgentSummary,\n HqMailboxEventPayload,\n HqMailboxMessageSummary,\n HqMailboxSnapshotPayload,\n HqRedactionPolicy,\n} from './protocol.js';\nimport { redactHqValue } from './redaction.js';\n\nexport interface HqMailboxMappingOptions {\n mailboxId: string;\n scope?: 'project' | 'global';\n limit?: number;\n previewLength?: number;\n redactionPolicy?: Partial<HqRedactionPolicy>;\n}\n\nexport interface HqMailboxSnapshotOptions extends HqMailboxMappingOptions {\n includeCompleted?: boolean;\n}\n\nexport type HqMailboxEventAction = HqMailboxEventPayload['action'];\n\nfunction previewText(value: string | undefined, maxLength: number, policy?: Partial<HqRedactionPolicy>): string | undefined {\n if (value === undefined || value.length === 0) return undefined;\n const redacted = redactHqValue(value, { maxSummaryLength: maxLength, policy: { rawContent: true, ...policy } }).value;\n if (redacted.length <= maxLength) return redacted;\n return `${redacted.slice(0, maxLength)}…`;\n}\n\nfunction readCount(message: MailboxMessage): number {\n return Object.keys(message.readBy).length;\n}\n\nfunction taskSummary(message: MailboxMessage): HqMailboxMessageSummary['task'] {\n if (message.taskContext === undefined) return undefined;\n const task = {\n ...(message.taskContext.taskId !== undefined ? { taskId: message.taskContext.taskId } : {}),\n ...(message.taskContext.agentRole !== undefined ? { agentRole: message.taskContext.agentRole } : {}),\n ...(message.taskContext.agentName !== undefined ? { agentName: message.taskContext.agentName } : {}),\n ...(message.taskContext.status !== undefined ? { status: message.taskContext.status } : {}),\n } satisfies HqMailboxMessageSummary['task'];\n return Object.keys(task).length > 0 ? task : undefined;\n}\n\nexport function mapMailboxMessageToHqSummary(\n message: MailboxMessage,\n options: Pick<HqMailboxMappingOptions, 'previewLength' | 'redactionPolicy'> = {},\n): HqMailboxMessageSummary {\n const previewLength = options.previewLength ?? 500;\n const bodyPreview = previewText(message.body, previewLength, options.redactionPolicy);\n const outcomePreview = previewText(message.outcome, previewLength, options.redactionPolicy);\n const task = taskSummary(message);\n\n return {\n mailId: message.id, // unique UUID per message record, used for deduplication\n messageId: message.id,\n from: message.from,\n to: message.to,\n type: message.type,\n subject: previewText(message.subject, previewLength, options.redactionPolicy) ?? '',\n priority: message.priority,\n timestamp: message.timestamp,\n ...(message.replyTo !== undefined ? { replyTo: message.replyTo } : {}),\n ...(message.senderSessionId !== undefined ? { senderSessionId: message.senderSessionId } : {}),\n completed: message.completed,\n ...(message.completedBy !== undefined ? { completedBy: message.completedBy } : {}),\n ...(message.completedAt !== undefined ? { completedAt: message.completedAt } : {}),\n readCount: readCount(message),\n hasBody: message.body.length > 0,\n ...(bodyPreview !== undefined ? { bodyPreview } : {}),\n ...(outcomePreview !== undefined ? { outcomePreview } : {}),\n ...(task !== undefined ? { task } : {}),\n };\n}\n\nexport function mapMailboxAgentToHqSummary(agent: MailboxAgentStatus): HqMailboxAgentSummary {\n return {\n agentId: agent.agentId,\n name: agent.name,\n ...(agent.role !== undefined ? { role: agent.role } : {}),\n sessionId: agent.sessionId,\n status: agent.status,\n ...(agent.currentTool !== undefined ? { currentTool: agent.currentTool } : {}),\n ...(agent.currentTask !== undefined ? { currentTask: agent.currentTask } : {}),\n iterations: agent.iterations,\n toolCalls: agent.toolCalls,\n lastActivityAt: agent.lastActivityAt,\n lastSeenAt: agent.lastSeenAt,\n online: agent.online,\n ...(agent.source !== undefined ? { source: agent.source } : {}),\n };\n}\n\nexport function createMailboxSnapshotPayload(\n messages: readonly MailboxMessage[],\n agents: readonly MailboxAgentStatus[],\n options: HqMailboxSnapshotOptions,\n): HqMailboxSnapshotPayload {\n const includeCompleted = options.includeCompleted ?? true;\n const filteredMessages = includeCompleted ? messages : messages.filter((message) => !message.completed);\n const limit = options.limit ?? 50;\n const sortedMessages = [...filteredMessages].sort((a, b) => b.timestamp.localeCompare(a.timestamp)).slice(0, limit);\n const summaries = sortedMessages.map((message) => mapMailboxMessageToHqSummary(message, options));\n const agentSummaries = agents.map(mapMailboxAgentToHqSummary);\n\n return {\n mailboxId: options.mailboxId,\n scope: options.scope ?? 'project',\n messages: summaries,\n agents: agentSummaries,\n totals: {\n messages: messages.length,\n unread: messages.filter((message) => !message.completed && readCount(message) === 0).length,\n incomplete: messages.filter((message) => !message.completed).length,\n highPriority: messages.filter((message) => message.priority === 'high').length,\n onlineAgents: agents.filter((agent) => agent.online).length,\n },\n };\n}\n\nexport async function createMailboxSnapshotPayloadFromMailbox(\n mailbox: Pick<Mailbox, 'query' | 'getAgentStatuses'>,\n options: HqMailboxSnapshotOptions,\n): Promise<HqMailboxSnapshotPayload> {\n const limit = options.limit ?? 50;\n const [messages, agents] = await Promise.all([\n mailbox.query({ limit }),\n mailbox.getAgentStatuses(),\n ]);\n return createMailboxSnapshotPayload(messages, agents, options);\n}\n\nexport function createMailboxEventPayload(input: {\n mailboxId: string;\n action: HqMailboxEventAction;\n message?: MailboxMessage;\n agent?: MailboxAgentStatus;\n summary?: string;\n previewLength?: number;\n redactionPolicy?: Partial<HqRedactionPolicy>;\n}): HqMailboxEventPayload {\n const summaryOptions: Pick<HqMailboxMappingOptions, 'previewLength' | 'redactionPolicy'> = {\n ...(input.previewLength !== undefined ? { previewLength: input.previewLength } : {}),\n ...(input.redactionPolicy !== undefined ? { redactionPolicy: input.redactionPolicy } : {}),\n };\n\n return {\n mailboxId: input.mailboxId,\n action: input.action,\n ...(input.message !== undefined ? { message: mapMailboxMessageToHqSummary(input.message, summaryOptions) } : {}),\n ...(input.agent !== undefined ? { agent: mapMailboxAgentToHqSummary(input.agent) } : {}),\n ...(input.summary !== undefined\n ? { summary: previewText(input.summary, input.previewLength ?? 160, input.redactionPolicy) ?? '' }\n : {}),\n };\n}\n","import { randomUUID } from 'node:crypto';\nimport type { Mailbox, MailboxAgentStatus, MailboxMessage } from '../coordination/mailbox-types.js';\nimport {\n createMailboxEventPayload,\n createMailboxSnapshotPayloadFromMailbox,\n type HqMailboxEventAction,\n type HqMailboxSnapshotOptions,\n} from './mailbox-mapper.js';\nimport {\n createHqEventEnvelope,\n HQ_PROTOCOL_VERSION,\n type HqClientCapability,\n type HqClientCommandAckMessage,\n type HqClientCommandPollMessage,\n type HqClientEventMessage,\n type HqClientHelloMessage,\n type HqClientIdentity,\n type HqEventEnvelope,\n type HqEventType,\n type HqFleetSnapshotPayload,\n type HqMailboxEventPayload,\n type HqMailboxSnapshotPayload,\n type HqProjectIdentity,\n type HqQueuedCommand,\n type HqRedactionPolicy,\n type HqServerCommandBatchMessage,\n type HqSessionEndedPayload,\n type HqSessionSnapshotPayload,\n type HqTranscriptAppendPayload,\n} from './protocol.js';\n\nexport interface HqSocketLike {\n readyState: number;\n send(data: string): void;\n close(code?: number, reason?: string): void;\n addEventListener?(\n type: 'open' | 'close' | 'error' | 'message',\n listener: (event: unknown) => void,\n ): void;\n removeEventListener?(\n type: 'open' | 'close' | 'error' | 'message',\n listener: (event: unknown) => void,\n ): void;\n on?(type: 'open' | 'close' | 'error' | 'message', listener: (event: unknown) => void): void;\n off?(type: 'open' | 'close' | 'error' | 'message', listener: (event: unknown) => void): void;\n}\n\nexport type HqSocketFactory = (url: string, init: { token?: string }) => HqSocketLike;\n\nexport interface HqPublisherCommandResult {\n commandId: string;\n status: 'accepted' | 'completed' | 'failed' | 'rejected';\n message?: string;\n}\n\nexport type HqPublisherCommandHandler = (\n command: HqQueuedCommand,\n) => void | HqPublisherCommandResult | Promise<void | HqPublisherCommandResult>;\n\nexport interface HqPublisherOptions {\n url: string;\n token?: string;\n client: HqClientIdentity;\n project: HqProjectIdentity;\n capabilities?: readonly HqClientCapability[];\n socketFactory?: HqSocketFactory;\n now?: () => string;\n idFactory?: () => string;\n reconnect?: boolean;\n reconnectBaseMs?: number;\n reconnectMaxMs?: number;\n maxQueuedMessages?: number;\n redactionPolicy?: Partial<HqRedactionPolicy>;\n commandPollIntervalMs?: number;\n commandPollLimit?: number;\n onCommand?: HqPublisherCommandHandler;\n /**\n * Local auto-discovery hook: re-resolve the HQ endpoint before EVERY\n * connect attempt (e.g. by reading `<hq dataDir>/runtime.json`). Returning\n * `undefined` means no HQ is currently discoverable — the publisher stays\n * dormant (events keep queueing, bounded) and re-checks every\n * {@link HqPublisherOptions.discoveryPollMs}. Because the endpoint is\n * re-resolved per attempt, an HQ started AFTER this client — or restarted\n * on a different port, or one that minted its first client token on boot —\n * is picked up automatically.\n */\n resolveEndpoint?: () => { url: string; token?: string | undefined } | undefined;\n /** Dormant re-check interval while `resolveEndpoint` yields nothing. Default 5s. */\n discoveryPollMs?: number;\n /**\n * Diagnostic sink for the one-time consecutive-connect-failure warning.\n * The publisher is otherwise deliberately silent (dormant queueing), which\n * made auth failures invisible: a token the server rejects — e.g. a wrong\n * `WRONGSTACK_HQ_TOKEN` against a remote HQ — looked exactly like \"HQ not\n * running\". Defaults to a single structured `console.warn` line.\n */\n warn?: (message: string) => void;\n}\n\nexport interface HqPublishEventOptions {\n type: HqEventType | (string & {});\n payload: unknown;\n sessionId?: string;\n runId?: string;\n timestamp?: string;\n}\n\nconst OPEN_STATE = 1;\n/**\n * After this many consecutive failed connects (never reaching `open`), emit\n * ONE diagnostic warning. The WS handshake gives the browser-style socket no\n * HTTP status, so a 401 (token mismatch) is indistinguishable from a dead\n * server at this layer — the warning names both possibilities.\n */\nconst CONNECT_WARN_AFTER_FAILURES = 5;\nconst DEFAULT_RECONNECT_BASE_MS = 1_000;\nconst DEFAULT_RECONNECT_MAX_MS = 30_000;\nconst DEFAULT_DISCOVERY_POLL_MS = 5_000;\nconst DEFAULT_MAX_QUEUED_MESSAGES = 2000;\nconst DEFAULT_COMMAND_POLL_INTERVAL_MS = 2_000;\nconst DEFAULT_COMMAND_POLL_LIMIT = 25;\n\nfunction defaultSocketFactory(url: string): HqSocketLike {\n const WebSocketCtor = globalThis.WebSocket;\n if (WebSocketCtor === undefined) {\n throw new Error(\n 'No global WebSocket implementation is available; provide HqPublisherOptions.socketFactory.',\n );\n }\n return new WebSocketCtor(url) as HqSocketLike;\n}\n\nfunction toClientUrl(baseUrl: string, token: string | undefined): string {\n const url = new URL(baseUrl);\n url.protocol = url.protocol === 'https:' ? 'wss:' : 'ws:';\n if (url.pathname === '/' || url.pathname === '') url.pathname = '/ws/client';\n if (token !== undefined && token.length > 0) url.searchParams.set('token', token);\n return url.toString();\n}\n\nfunction addSocketListener(\n socket: HqSocketLike,\n type: 'open' | 'close' | 'error' | 'message',\n listener: (event: unknown) => void,\n): void {\n if (socket.addEventListener !== undefined) {\n socket.addEventListener(type, listener);\n return;\n }\n socket.on?.(type, listener);\n}\n\nfunction removeSocketListener(\n socket: HqSocketLike,\n type: 'open' | 'close' | 'error' | 'message',\n listener: (event: unknown) => void,\n): void {\n if (socket.removeEventListener !== undefined) {\n socket.removeEventListener(type, listener);\n return;\n }\n socket.off?.(type, listener);\n}\n\nexport class HqPublisher {\n private readonly socketFactory: HqSocketFactory;\n private readonly now: () => string;\n private readonly idFactory: () => string;\n private readonly capabilities: readonly HqClientCapability[];\n private readonly reconnect: boolean;\n private readonly reconnectBaseMs: number;\n private readonly reconnectMaxMs: number;\n private readonly maxQueuedMessages: number;\n private socket: HqSocketLike | null = null;\n private seq = 0;\n private queue: string[] = [];\n private stopped = false;\n private reconnectAttempt = 0;\n private connectWarningEmitted = false;\n private lastAttempt: { url: string; hadToken: boolean } | null = null;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private commandPollTimer: ReturnType<typeof setInterval> | null = null;\n private lastCommandId: string | undefined;\n\n constructor(private readonly options: HqPublisherOptions) {\n this.socketFactory = options.socketFactory ?? defaultSocketFactory;\n this.now = options.now ?? (() => new Date().toISOString());\n this.idFactory = options.idFactory ?? randomUUID;\n this.capabilities = options.capabilities ?? [\n 'telemetry.publish',\n 'mailbox.summary',\n 'fleet.summary',\n 'session.summary',\n ];\n this.reconnect = options.reconnect ?? true;\n this.reconnectBaseMs = options.reconnectBaseMs ?? DEFAULT_RECONNECT_BASE_MS;\n this.reconnectMaxMs = options.reconnectMaxMs ?? DEFAULT_RECONNECT_MAX_MS;\n this.maxQueuedMessages = options.maxQueuedMessages ?? DEFAULT_MAX_QUEUED_MESSAGES;\n }\n\n connect(): void {\n if (this.socket !== null || this.stopped) return;\n // A retry / discovery poll is already scheduled — let it fire instead of\n // dialing (and re-resolving the endpoint) on every publish while offline.\n if (this.reconnectTimer !== null) return;\n\n let url = this.options.url;\n let token = this.options.token;\n if (this.options.resolveEndpoint !== undefined) {\n const endpoint = this.options.resolveEndpoint();\n if (endpoint === undefined) {\n this.scheduleDiscoveryPoll();\n return;\n }\n url = endpoint.url;\n token = endpoint.token ?? token;\n }\n this.lastAttempt = { url, hadToken: token !== undefined };\n\n let socket: HqSocketLike;\n try {\n socket = this.socketFactory(toClientUrl(url, token), {\n ...(token !== undefined ? { token } : {}),\n });\n } catch {\n this.scheduleReconnect();\n return;\n }\n this.socket = socket;\n\n const onOpen = () => {\n this.reconnectAttempt = 0;\n this.sendHelloNow();\n this.flushQueue();\n if (this.options.onCommand !== undefined) {\n this.startCommandPolling();\n this.pollCommands();\n }\n };\n const onMessage = (event: unknown) => {\n void this.handleServerMessage(event);\n };\n const onCloseOrError = () => {\n removeSocketListener(socket, 'open', onOpen);\n removeSocketListener(socket, 'message', onMessage);\n removeSocketListener(socket, 'close', onCloseOrError);\n removeSocketListener(socket, 'error', onCloseOrError);\n this.stopCommandPolling();\n if (this.socket === socket) this.socket = null;\n this.scheduleReconnect();\n };\n\n addSocketListener(socket, 'open', onOpen);\n addSocketListener(socket, 'message', onMessage);\n addSocketListener(socket, 'close', onCloseOrError);\n addSocketListener(socket, 'error', onCloseOrError);\n\n if (socket.readyState === OPEN_STATE) onOpen();\n }\n\n close(): void {\n this.stopped = true;\n if (this.reconnectTimer !== null) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n this.stopCommandPolling();\n this.queue = [];\n const socket = this.socket;\n this.socket = null;\n socket?.close(1000, 'hq publisher closed');\n }\n\n publishEvent<TPayload>(\n options: HqPublishEventOptions & { payload: TPayload },\n ): HqEventEnvelope<TPayload> {\n const event = createHqEventEnvelope({\n id: this.idFactory(),\n type: options.type,\n timestamp: options.timestamp ?? this.now(),\n clientId: this.options.client.clientId,\n projectId: this.options.project.projectId,\n seq: ++this.seq,\n payload: options.payload,\n ...(options.sessionId !== undefined ? { sessionId: options.sessionId } : {}),\n ...(options.runId !== undefined ? { runId: options.runId } : {}),\n });\n this.sendFrame({ type: 'client.event', event });\n return event;\n }\n\n async publishMailboxSnapshot(\n mailbox: Pick<Mailbox, 'query' | 'getAgentStatuses'>,\n options: Omit<HqMailboxSnapshotOptions, 'redactionPolicy'> & {\n sessionId?: string;\n timestamp?: string;\n },\n ): Promise<HqEventEnvelope<HqMailboxSnapshotPayload>> {\n const payload = await createMailboxSnapshotPayloadFromMailbox(mailbox, {\n ...options,\n ...(this.options.redactionPolicy !== undefined\n ? { redactionPolicy: this.options.redactionPolicy }\n : {}),\n });\n return this.publishEvent({\n type: 'mailbox.snapshot',\n payload,\n ...(options.sessionId !== undefined ? { sessionId: options.sessionId } : {}),\n ...(options.timestamp !== undefined ? { timestamp: options.timestamp } : {}),\n });\n }\n\n publishMailboxEvent(input: {\n mailboxId: string;\n action: HqMailboxEventAction;\n message?: MailboxMessage;\n agent?: MailboxAgentStatus;\n summary?: string;\n previewLength?: number;\n sessionId?: string;\n timestamp?: string;\n }): HqEventEnvelope<HqMailboxEventPayload> {\n const payload = createMailboxEventPayload({\n mailboxId: input.mailboxId,\n action: input.action,\n ...(input.message !== undefined ? { message: input.message } : {}),\n ...(input.agent !== undefined ? { agent: input.agent } : {}),\n ...(input.summary !== undefined ? { summary: input.summary } : {}),\n ...(input.previewLength !== undefined ? { previewLength: input.previewLength } : {}),\n ...(this.options.redactionPolicy !== undefined\n ? { redactionPolicy: this.options.redactionPolicy }\n : {}),\n });\n return this.publishEvent({\n type: 'mailbox.event',\n payload,\n ...(input.sessionId !== undefined ? { sessionId: input.sessionId } : {}),\n ...(input.timestamp !== undefined ? { timestamp: input.timestamp } : {}),\n });\n }\n\n /** The client identity this publisher announced (clientId, kind, machineId, …). */\n get identity(): HqClientIdentity {\n return this.options.client;\n }\n\n /** The project identity this publisher is bound to. */\n get project(): HqProjectIdentity {\n return this.options.project;\n }\n\n /** Publish a live session/terminal snapshot (state + agents). */\n publishSessionSnapshot(\n payload: HqSessionSnapshotPayload,\n opts?: { timestamp?: string },\n ): HqEventEnvelope<HqSessionSnapshotPayload> {\n return this.publishEvent({\n type: 'session.snapshot',\n payload,\n sessionId: payload.sessionId,\n ...(opts?.timestamp !== undefined ? { timestamp: opts.timestamp } : {}),\n });\n }\n\n /** Publish an incremental batch of transcript turns for a session. */\n publishTranscriptAppend(\n payload: HqTranscriptAppendPayload,\n opts?: { timestamp?: string },\n ): HqEventEnvelope<HqTranscriptAppendPayload> {\n return this.publishEvent({\n type: 'session.transcript',\n payload,\n sessionId: payload.sessionId,\n ...(opts?.timestamp !== undefined ? { timestamp: opts.timestamp } : {}),\n });\n }\n\n /** Mark a session/terminal as ended. */\n publishSessionEnded(\n payload: HqSessionEndedPayload,\n opts?: { timestamp?: string },\n ): HqEventEnvelope<HqSessionEndedPayload> {\n return this.publishEvent({\n type: 'session.ended',\n payload,\n sessionId: payload.sessionId,\n ...(opts?.timestamp !== undefined ? { timestamp: opts.timestamp } : {}),\n });\n }\n\n /** Publish a fleet (multi-agent coordinator) snapshot. */\n publishFleetSnapshot(\n payload: HqFleetSnapshotPayload,\n opts?: { sessionId?: string; timestamp?: string },\n ): HqEventEnvelope<HqFleetSnapshotPayload> {\n return this.publishEvent({\n type: 'fleet.snapshot',\n payload,\n runId: payload.runId,\n ...(opts?.sessionId !== undefined ? { sessionId: opts.sessionId } : {}),\n ...(opts?.timestamp !== undefined ? { timestamp: opts.timestamp } : {}),\n });\n }\n\n pollCommands(): void {\n this.sendFrame({\n type: 'client.command_poll',\n clientId: this.options.client.clientId,\n projectId: this.options.project.projectId,\n ...(this.lastCommandId !== undefined ? { afterCommandId: this.lastCommandId } : {}),\n limit: this.options.commandPollLimit ?? DEFAULT_COMMAND_POLL_LIMIT,\n });\n }\n\n ackCommand(result: HqPublisherCommandResult): void {\n this.sendFrame({\n type: 'client.command_ack',\n clientId: this.options.client.clientId,\n projectId: this.options.project.projectId,\n commandId: result.commandId,\n status: result.status,\n ...(result.message !== undefined ? { message: result.message } : {}),\n });\n }\n\n private createHelloFrame(): HqClientHelloMessage {\n return {\n type: 'client.hello',\n payload: {\n protocolVersion: HQ_PROTOCOL_VERSION,\n client: this.options.client,\n project: this.options.project,\n capabilities: this.capabilities,\n },\n };\n }\n\n private sendHelloNow(): void {\n const socket = this.socket;\n if (socket?.readyState !== OPEN_STATE) {\n this.sendFrame(this.createHelloFrame());\n return;\n }\n socket.send(JSON.stringify(this.createHelloFrame()));\n }\n\n private sendFrame(\n frame:\n | HqClientHelloMessage\n | HqClientEventMessage\n | HqClientCommandPollMessage\n | HqClientCommandAckMessage,\n ): void {\n const serialized = JSON.stringify(frame);\n const socket = this.socket;\n // Fast path: socket is open and nothing queued — send immediately.\n if (socket?.readyState === OPEN_STATE && this.queue.length === 0) {\n socket.send(serialized);\n return;\n }\n // Slow path: socket offline or queue already has pending frames — enqueue.\n this.enqueue(serialized);\n this.connect();\n }\n\n private enqueue(serialized: string): void {\n if (this.queue.length >= this.maxQueuedMessages) this.queue.shift();\n this.queue.push(serialized);\n }\n\n /** Batch-dequeue up to 50 frames at a time, yielding to the microtask\n * queue between batches so we don't starve the event loop on reconnect. */\n private flushQueue(): void {\n const socket = this.socket;\n if (socket?.readyState !== OPEN_STATE || this.queue.length === 0) return;\n const batch = this.queue.splice(0, 50);\n for (const frame of batch) socket.send(frame);\n if (this.queue.length > 0) setImmediate(() => this.flushQueue());\n }\n\n private startCommandPolling(): void {\n if (this.options.onCommand === undefined || this.commandPollTimer !== null) return;\n this.commandPollTimer = setInterval(\n () => this.pollCommands(),\n this.options.commandPollIntervalMs ?? DEFAULT_COMMAND_POLL_INTERVAL_MS,\n );\n this.commandPollTimer.unref?.();\n }\n\n private stopCommandPolling(): void {\n if (this.commandPollTimer === null) return;\n clearInterval(this.commandPollTimer);\n this.commandPollTimer = null;\n }\n\n private async handleServerMessage(event: unknown): Promise<void> {\n const message = this.parseServerMessage(event);\n if (message?.type !== 'hq.command_batch') return;\n await this.handleCommandBatch(message);\n }\n\n private parseServerMessage(event: unknown): HqServerCommandBatchMessage | null {\n const data = this.extractMessageData(event);\n if (data === null) return null;\n try {\n const parsed = JSON.parse(data) as Partial<HqServerCommandBatchMessage>;\n if (parsed.type !== 'hq.command_batch' || !Array.isArray(parsed.commands)) return null;\n return parsed as HqServerCommandBatchMessage;\n } catch {\n return null;\n }\n }\n\n private extractMessageData(event: unknown): string | null {\n const value =\n typeof event === 'object' && event !== null && 'data' in event\n ? (event as { data?: unknown }).data\n : event;\n if (typeof value === 'string') return value;\n if (value instanceof ArrayBuffer) return new TextDecoder().decode(value);\n if (ArrayBuffer.isView(value)) {\n const bytes = new Uint8Array(value.buffer, value.byteOffset, value.byteLength);\n return new TextDecoder().decode(bytes);\n }\n return null;\n }\n\n private async handleCommandBatch(message: HqServerCommandBatchMessage): Promise<void> {\n const handler = this.options.onCommand;\n if (handler === undefined) return;\n\n for (const command of message.commands) {\n this.lastCommandId = command.commandId;\n try {\n const result = await handler(command);\n if (result !== undefined) this.ackCommand(result);\n else if (command.requiresAck)\n this.ackCommand({ commandId: command.commandId, status: 'accepted' });\n } catch (err) {\n this.ackCommand({\n commandId: command.commandId,\n status: 'failed',\n message: err instanceof Error ? err.message : String(err),\n });\n }\n }\n }\n\n private scheduleReconnect(): void {\n if (this.stopped || !this.reconnect || this.reconnectTimer !== null) return;\n const delay = Math.min(this.reconnectMaxMs, this.reconnectBaseMs * 2 ** this.reconnectAttempt);\n this.reconnectAttempt += 1;\n // One-time visibility for persistent failures. `reconnectAttempt` resets\n // on every successful open, so reaching the threshold means the endpoint\n // has NEVER accepted us in this streak — dead server or rejected token.\n if (!this.connectWarningEmitted && this.reconnectAttempt >= CONNECT_WARN_AFTER_FAILURES) {\n this.connectWarningEmitted = true;\n this.emitConnectWarning();\n }\n this.reconnectTimer = setTimeout(() => {\n this.reconnectTimer = null;\n this.connect();\n }, delay);\n this.reconnectTimer.unref?.();\n }\n\n private emitConnectWarning(): void {\n const attempt = this.lastAttempt;\n const message =\n `WrongStack HQ publisher: ${this.reconnectAttempt} consecutive connection failures` +\n `${attempt !== null ? ` to ${attempt.url} (client token ${attempt.hadToken ? 'present' : 'absent'})` : ''}. ` +\n 'Either the HQ server is unreachable or it rejected the token (401). ' +\n 'If HQ runs in client-token mode, verify WRONGSTACK_HQ_TOKEN / auth.json. Retries continue with backoff.';\n const warn =\n this.options.warn ??\n ((msg: string) =>\n console.warn(\n JSON.stringify({\n level: 'warn',\n event: 'hq.publisher.connect_failed',\n message: msg,\n timestamp: this.now(),\n }),\n ));\n try {\n warn(message);\n } catch {\n /* diagnostics must never break publishing */\n }\n }\n\n /**\n * Dormant re-check while no HQ endpoint is discoverable. Uses a FIXED\n * interval (not the exponential reconnect backoff): the check is a cheap\n * local file read, and backing off would delay attaching to an HQ the\n * user just started — the whole point of auto-discovery.\n */\n private scheduleDiscoveryPoll(): void {\n if (this.stopped || !this.reconnect || this.reconnectTimer !== null) return;\n this.reconnectAttempt = 0;\n this.reconnectTimer = setTimeout(() => {\n this.reconnectTimer = null;\n this.connect();\n }, this.options.discoveryPollMs ?? DEFAULT_DISCOVERY_POLL_MS);\n this.reconnectTimer.unref?.();\n }\n}\n","import * as path from 'node:path';\nimport { ERROR_CODES, FsError } from '../types/errors.js';\n\n/**\n * Resolve `<dir>/<sessionId><suffix>` for per-session sidecar files\n * (annotations, audit chain, replay log, the session JSONL itself).\n *\n * Modern session ids are date-sharded (\"2026-06-11/sess_<ULID>\"),\n * so a forward slash is a legitimate shard separator — NOT traversal.\n * Escape attempts are blocked two ways: an explicit ban on `..` and\n * backslashes, plus a resolved-path containment check that rejects any\n * id whose resolved target leaves `dir`. Character bans alone are how\n * several stores ended up throwing on every modern session id.\n */\nexport function sessionScopedPath(dir: string, sessionId: string, suffix: string): string {\n if (!sessionId || sessionId.includes('\\\\') || sessionId.includes('..')) {\n throw invalid(sessionId);\n }\n const resolved = path.resolve(dir, `${sessionId}${suffix}`);\n const rel = path.relative(path.resolve(dir), resolved);\n if (rel.startsWith('..') || path.isAbsolute(rel)) {\n throw invalid(sessionId);\n }\n return resolved;\n}\n\nfunction invalid(sessionId: string): FsError {\n return new FsError({\n message: `Invalid sessionId: ${sessionId}`,\n code: ERROR_CODES.FS_DELETE_FAILED,\n path: sessionId,\n context: { reason: 'path_traversal' },\n });\n}\n","import { createHash } from 'node:crypto';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\n\n/**\n * Path layout. All developer-level state lives in ~/.wrongstack/.\n * Per-project state is keyed by sha256(absoluteProjectRoot).slice(0,12)\n * under ~/.wrongstack/projects/<hash>/.\n *\n * The ONLY thing inside the project tree is the optional\n * .wrongstack/AGENTS.md (committed) and .wrongstack/skills/ (committed).\n */\n\nexport interface WstackPaths {\n /** ~/.wrongstack — global root. */\n globalRoot: string;\n /** Absolute project root. */\n projectRoot: string;\n /** Home directory (~) — base for foreign tool state (~/.codex, ~/.agents, …). */\n homeDir: string;\n /**\n * ~/.wrongstack — directory for user-global stateful config files\n * (mode.json, theme.json, …). Currently an alias for `globalRoot`;\n * separate name lets us split out per-OS XDG_CONFIG_HOME later\n * without rewriting callers.\n */\n configDir: string;\n /** ~/.wrongstack/config.json */\n globalConfig: string;\n /** ~/.wrongstack/.key — 32 random bytes, mode 0600, AES-GCM key for the secret vault. */\n secretsKey: string;\n /** ~/.wrongstack/memory.md — user-global memory. */\n globalMemory: string;\n /** ~/.wrongstack/skills — user-global skills. */\n globalSkills: string;\n /** ~/.claude/skills — user-global skills from foreign coding agents (Claude Code, Codex, …). Read-only. */\n globalClaudeSkills: string;\n /** ~/.wrongstack/design-kits — user-global Design Studio kits. */\n globalDesignKits: string;\n /** ~/.wrongstack/prompts — user-global prompt library. */\n globalPrompts: string;\n /** ~/.wrongstack/instructions — user-global system instruction overrides. */\n globalInstructions: string;\n /** ~/.wrongstack/prompt-usage.json — per-slug insert counts (recent/popular). */\n promptUsage: string;\n /** ~/.wrongstack/cache — fetched data (models.dev, etc.). */\n cacheDir: string;\n /** ~/.wrongstack/cache/models.dev.json */\n modelsCache: string;\n /** ~/.wrongstack/cache/models-overlay.json — cached curated overlay. */\n modelsOverlayCache: string;\n /**\n * Per-project codebase symbol index (SQLite). Lives under the global project\n * dir — NOT inside the repo — so it never clutters the working tree or needs\n * gitignoring. `~/.wrongstack/projects/<hash>/codebase-index`.\n */\n projectCodebaseIndex: string;\n /** ~/.wrongstack/history — REPL line history. */\n historyFile: string;\n /** ~/.wrongstack/logs/wrongstack.log */\n logFile: string;\n /** ~/.wrongstack/projects/<hash> */\n projectDir: string;\n /** ~/.wrongstack/projects/<hash>/memory.md */\n projectMemory: string;\n /** ~/.wrongstack/projects/<hash>/sessions */\n projectSessions: string;\n /** ~/.wrongstack/projects/<hash>/trust.json */\n projectTrust: string;\n /** ~/.wrongstack/projects/<hash>/meta.json */\n projectMeta: string;\n /** ~/.wrongstack/projects/<hash>/config.local.json — optional override */\n projectLocalConfig: string;\n /** <project>/.wrongstack/config.json — per-project settings (safe fields only).\n * This lives inside the project root so it can be gitignored or shared. */\n inProjectConfig: string;\n /** <project>/.wrongstack/AGENTS.md — committed project memory. */\n inProjectAgentsFile: string;\n /** <project>/.wrongstack/skills — committed project skills. */\n inProjectSkills: string;\n /** <project>/.claude/skills — project skills authored for foreign coding agents (Claude Code, …). Read-only. */\n inProjectClaudeSkills: string;\n /** <project>/.wrongstack/prompts — committed project prompt library. */\n inProjectPrompts: string;\n /** <project>/.wrongstack/instructions — committed project instruction overrides. */\n inProjectInstructions: string;\n /** <project>/.wrongstack/design-kits — committed project Design Studio kits. */\n inProjectDesignKits: string;\n /** <project>/.wrongstack/worktrees — git worktrees for per-phase isolation (gitignored). */\n inProjectWorktrees: string;\n /** Stable hash for the project root. */\n projectHash: string;\n /** Human-readable project slug: `wrongstack-a1b2c3` instead of `3024e5e6fa58`. */\n projectSlug: string;\n /** ~/.wrongstack/projects/<hash>/goal.json — goal persistence */\n projectGoal: string;\n /** ~/.wrongstack/projects/<hash>/input-history.json — TUI prompt input history */\n projectInputHistory: string;\n /** ~/.wrongstack/projects/<hash>/specs — SDD spec files */\n projectSpecs: string;\n /** ~/.wrongstack/projects/<hash>/task-graphs — SDD task graphs */\n projectTaskGraphs: string;\n /** ~/.wrongstack/projects/<hash>/sdd-session.json — SDD session state */\n projectSddSession: string;\n /** ~/.wrongstack/projects/<hash>/plan.json — plan persistence */\n projectPlan: string;\n /** ~/.wrongstack/projects/<hash>/autophase — AutoPhase phase-graph JSON files */\n projectAutophase: string;\n /** ~/.wrongstack/projects/<hash>/sdd-boards — live SDD board snapshots + JSONL event logs */\n projectSddBoards: string;\n /** ~/.wrongstack/sync.json — CloudSync configuration */\n syncConfig: string;\n /** Function to get the status.json path for a project given its hash. */\n projectStatus: (projectHash: string) => string;\n}\n\nexport function projectHash(absRoot: string): string {\n return createHash('sha256').update(path.resolve(absRoot)).digest('hex').slice(0, 12);\n}\n\n/**\n * Human-readable project directory name: slugified folder name + short hash\n * suffix for uniqueness. e.g. `wrongstack-a1b2c3` instead of `3024e5e6fa58`.\n */\nexport function projectSlug(absRoot: string): string {\n const base = slugify(path.basename(absRoot));\n const hash = createHash('sha256').update(path.resolve(absRoot)).digest('hex').slice(0, 6);\n return `${base}-${hash}`;\n}\n\n/** Turn a folder name into a filesystem-safe lowercase slug. */\nfunction slugify(name: string): string {\n return (\n name\n .toLowerCase()\n // Collapse any run of non-alphanumeric chars into a single hyphen.\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, 40) || 'project'\n );\n}\n\nexport interface WstackPathOptions {\n userHome?: string | undefined;\n projectRoot: string;\n /** Override the global root (e.g. for tests). Default: `${userHome}/.wrongstack`. */\n globalRoot?: string | undefined;\n}\n\n/**\n * The global `~/.wrongstack` root, honoring the `WRONGSTACK_HOME` env\n * override. The override exists so tests (and sandboxed runs) can redirect\n * ALL global state — config, secrets, logs, projects/, mailboxes — away from\n * the real user home. Before it existed, `pnpm test` booted runtimes against\n * the real `~/.wrongstack`: it read the user's real config.json (starting a\n * second live Telegram poller), appended to the real wrongstack.log, and left\n * ~20k orphaned fixture dirs under projects/.\n *\n * Every code path that wants the global dir must come through here (or\n * through `resolveWstackPaths`) instead of `path.join(os.homedir(), '.wrongstack')`.\n */\nexport function wstackGlobalRoot(): string {\n const fromEnv = process.env['WRONGSTACK_HOME'];\n if (fromEnv && fromEnv.trim().length > 0) return path.resolve(fromEnv);\n return path.join(os.homedir(), '.wrongstack');\n}\n\nexport function resolveWstackPaths(opts: WstackPathOptions): WstackPaths {\n // Precedence: explicit globalRoot > explicit userHome (callers/tests that\n // pass one expect paths under it) > WRONGSTACK_HOME env > real home dir.\n const globalRoot =\n opts.globalRoot ?? (opts.userHome ? path.join(opts.userHome, '.wrongstack') : wstackGlobalRoot());\n // Home dir for FOREIGN tool state (Claude Code's ~/.claude). Independent of\n // WRONGSTACK_HOME, which redirects only WrongStack state: a real user's\n // Claude skills live in their real home, but tests pass `userHome` to keep\n // both `.wrongstack` and `.claude` under a temp dir.\n const homeDir = opts.userHome ?? os.homedir();\n const hash = projectHash(opts.projectRoot);\n const slug = projectSlug(opts.projectRoot);\n const projectDir = path.join(globalRoot, 'projects', slug);\n return {\n globalRoot,\n projectRoot: opts.projectRoot,\n homeDir,\n configDir: globalRoot,\n globalConfig: path.join(globalRoot, 'config.json'),\n secretsKey: path.join(globalRoot, '.key'),\n globalMemory: path.join(globalRoot, 'memory.md'),\n globalSkills: path.join(globalRoot, 'skills'),\n globalClaudeSkills: path.join(homeDir, '.claude', 'skills'),\n globalDesignKits: path.join(globalRoot, 'design-kits'),\n globalPrompts: path.join(globalRoot, 'prompts'),\n globalInstructions: path.join(globalRoot, 'instructions'),\n promptUsage: path.join(globalRoot, 'prompt-usage.json'),\n cacheDir: path.join(globalRoot, 'cache'),\n modelsCache: path.join(globalRoot, 'cache', 'models.dev.json'),\n modelsOverlayCache: path.join(globalRoot, 'cache', 'models-overlay.json'),\n historyFile: path.join(globalRoot, 'history'),\n logFile: path.join(globalRoot, 'logs', 'wrongstack.log'),\n projectDir,\n projectCodebaseIndex: path.join(projectDir, 'codebase-index'),\n projectMemory: path.join(projectDir, 'memory.md'),\n projectSessions: path.join(projectDir, 'sessions'),\n projectTrust: path.join(projectDir, 'trust.json'),\n projectMeta: path.join(projectDir, 'meta.json'),\n projectLocalConfig: path.join(projectDir, 'config.local.json'),\n inProjectConfig: path.join(opts.projectRoot, '.wrongstack', 'config.json'),\n inProjectAgentsFile: path.join(opts.projectRoot, '.wrongstack', 'AGENTS.md'),\n inProjectSkills: path.join(opts.projectRoot, '.wrongstack', 'skills'),\n inProjectClaudeSkills: path.join(opts.projectRoot, '.claude', 'skills'),\n inProjectPrompts: path.join(opts.projectRoot, '.wrongstack', 'prompts'),\n inProjectInstructions: path.join(opts.projectRoot, '.wrongstack', 'instructions'),\n inProjectDesignKits: path.join(opts.projectRoot, '.wrongstack', 'design-kits'),\n inProjectWorktrees: path.join(opts.projectRoot, '.wrongstack', 'worktrees'),\n projectHash: hash,\n projectSlug: slug,\n projectGoal: path.join(projectDir, 'goal.json'),\n projectInputHistory: path.join(projectDir, 'input-history.json'),\n projectSpecs: path.join(projectDir, 'specs'),\n projectTaskGraphs: path.join(projectDir, 'task-graphs'),\n projectSddSession: path.join(projectDir, 'sdd-session.json'),\n projectPlan: path.join(projectDir, 'plan.json'),\n projectAutophase: path.join(projectDir, 'autophase'),\n projectSddBoards: path.join(projectDir, 'sdd-boards'),\n syncConfig: path.join(globalRoot, 'sync.json'),\n projectStatus: (projectHash: string) => path.join(globalRoot, 'projects', projectHash, 'status.json'),\n };\n}\n","import { toErrorMessage } from '../utils/index.js';\n\n/**\n * WrongStack error hierarchy.\n *\n * Every error thrown by the framework is a `WrongStackError` with a\n * machine-readable `code`, a `subsystem` tag, and a `severity` level.\n * This lets consumers (CLI, TUI, plugins, tests) branch on structured\n * data instead of parsing error messages.\n */\n\n// ── Error codes ──────────────────────────────────────────────────────\n\n/**\n * Machine-readable error codes as frozen constants.\n *\n * Use `ERROR_CODES.X` instead of raw string literals for:\n * - IDE autocomplete and compile-time validation\n * - Safe refactoring (rename updates all usages)\n * - Plugin extensibility (extend the object to add custom codes)\n *\n * The `ErrorCode` type is derived from this object, so adding a new\n * code here automatically updates the type without extra changes.\n */\nexport const ERROR_CODES = {\n // Provider\n PROVIDER_RATE_LIMITED: 'PROVIDER_RATE_LIMITED',\n PROVIDER_AUTH_FAILED: 'PROVIDER_AUTH_FAILED',\n PROVIDER_OVERLOADED: 'PROVIDER_OVERLOADED',\n PROVIDER_INVALID_REQUEST: 'PROVIDER_INVALID_REQUEST',\n PROVIDER_SERVER_ERROR: 'PROVIDER_SERVER_ERROR',\n PROVIDER_NETWORK_ERROR: 'PROVIDER_NETWORK_ERROR',\n PROVIDER_CONTEXT_OVERFLOW: 'PROVIDER_CONTEXT_OVERFLOW',\n // Tool\n TOOL_NOT_FOUND: 'TOOL_NOT_FOUND',\n TOOL_PERMISSION_DENIED: 'TOOL_PERMISSION_DENIED',\n TOOL_EXECUTION_FAILED: 'TOOL_EXECUTION_FAILED',\n TOOL_TIMEOUT: 'TOOL_TIMEOUT',\n TOOL_INPUT_INVALID: 'TOOL_INPUT_INVALID',\n // Config\n CONFIG_INVALID: 'CONFIG_INVALID',\n CONFIG_NOT_FOUND: 'CONFIG_NOT_FOUND',\n CONFIG_PARSE_FAILED: 'CONFIG_PARSE_FAILED',\n CONFIG_MIGRATION_NEEDED: 'CONFIG_MIGRATION_NEEDED',\n // Plugin\n PLUGIN_LOAD_FAILED: 'PLUGIN_LOAD_FAILED',\n PLUGIN_API_MISMATCH: 'PLUGIN_API_MISMATCH',\n PLUGIN_MISSING_DEPENDENCY: 'PLUGIN_MISSING_DEPENDENCY',\n // Agent\n AGENT_ITERATION_LIMIT: 'AGENT_ITERATION_LIMIT',\n AGENT_CONTEXT_OVERFLOW: 'AGENT_CONTEXT_OVERFLOW',\n AGENT_ABORTED: 'AGENT_ABORTED',\n AGENT_RUN_FAILED: 'AGENT_RUN_FAILED',\n // Session\n SESSION_NOT_FOUND: 'SESSION_NOT_FOUND',\n SESSION_CORRUPTED: 'SESSION_CORRUPTED',\n SESSION_WRITE_FAILED: 'SESSION_WRITE_FAILED',\n // Container / Registry\n CONTAINER_TOKEN_ALREADY_BOUND: 'CONTAINER_TOKEN_ALREADY_BOUND',\n CONTAINER_TOKEN_NOT_BOUND: 'CONTAINER_TOKEN_NOT_BOUND',\n CONTAINER_CIRCULAR_DEPENDENCY: 'CONTAINER_CIRCULAR_DEPENDENCY',\n REGISTRY_DUPLICATE: 'REGISTRY_DUPLICATE',\n REGISTRY_NOT_FOUND: 'REGISTRY_NOT_FOUND',\n REGISTRY_INVALID: 'REGISTRY_INVALID',\n // File system\n FS_READ_FAILED: 'FS_READ_FAILED',\n FS_WRITE_FAILED: 'FS_WRITE_FAILED',\n FS_MKDIR_FAILED: 'FS_MKDIR_FAILED',\n FS_DELETE_FAILED: 'FS_DELETE_FAILED',\n FS_ATOMIC_WRITE_FAILED: 'FS_ATOMIC_WRITE_FAILED',\n // SDD (Spec-Driven Development)\n SDD_VALIDATION_FAILED: 'SDD_VALIDATION_FAILED',\n SDD_PARSE_FAILED: 'SDD_PARSE_FAILED',\n SDD_INVALID_STATE: 'SDD_INVALID_STATE',\n SDD_NOT_READY: 'SDD_NOT_READY',\n // General\n VALIDATION_ERROR: 'VALIDATION_ERROR',\n PARSE_FAILED: 'PARSE_FAILED',\n UNKNOWN: 'UNKNOWN',\n} as const;\n\n/**\n * Union type derived from `ERROR_CODES`. Using `typeof ERROR_CODES[keyof typeof ERROR_CODES]`\n * instead of a string literal union means TypeScript auto-updates the type whenever\n * a new code is added to `ERROR_CODES` — no need to keep two lists in sync.\n */\nexport type ErrorCode = (typeof ERROR_CODES)[keyof typeof ERROR_CODES];\n\nexport type ErrorSubsystem =\n | 'provider'\n | 'tool'\n | 'config'\n | 'plugin'\n | 'agent'\n | 'session'\n | 'sdd'\n | 'container'\n | 'fs'\n | 'general';\nexport type ErrorSeverity = 'fatal' | 'error' | 'warning';\n\n// ── Base error class ─────────────────────────────────────────────────\n\nexport class WrongStackError extends Error {\n readonly code: ErrorCode;\n readonly subsystem: ErrorSubsystem;\n readonly severity: ErrorSeverity;\n readonly recoverable: boolean;\n readonly context?: Record<string, unknown> | undefined;\n\n constructor(opts: {\n message: string;\n code: ErrorCode;\n subsystem: ErrorSubsystem;\n severity?: ErrorSeverity | undefined;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super(opts.message, { cause: opts.cause });\n this.name = 'WrongStackError';\n this.code = opts.code;\n this.subsystem = opts.subsystem;\n this.severity = opts.severity ?? 'error';\n this.recoverable = opts.recoverable ?? false;\n this.context = opts.context;\n }\n\n /**\n * Render a one-line user-facing description.\n * Subclasses should override for domain-specific formatting.\n */\n describe(): string {\n const ctx = this.context ? ` ${formatContext(this.context)}` : '';\n return `${this.code}: ${this.message}${ctx}`;\n }\n}\n\nfunction formatContext(ctx: Record<string, unknown>): string {\n const parts = Object.entries(ctx)\n .filter(([, v]) => v !== undefined)\n .slice(0, 3)\n .map(([k, v]) => `${k}=${String(v)}`);\n return parts.length > 0 ? `[${parts.join(' ')}]` : '';\n}\n\n// ── Specific error classes ───────────────────────────────────────────\n\n/**\n * Tool execution errors — thrown by ToolExecutor and individual tools.\n */\nexport class ToolError extends WrongStackError {\n readonly toolName: string;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n | 'TOOL_NOT_FOUND'\n | 'TOOL_PERMISSION_DENIED'\n | 'TOOL_EXECUTION_FAILED'\n | 'TOOL_TIMEOUT'\n | 'TOOL_INPUT_INVALID'\n >;\n toolName: string;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'tool',\n recoverable: opts.recoverable,\n context: { tool: opts.toolName, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'ToolError';\n this.toolName = opts.toolName;\n }\n}\n\n/**\n * Config loading / validation errors.\n */\nexport class ConfigError extends WrongStackError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'CONFIG_INVALID' | 'CONFIG_NOT_FOUND' | 'CONFIG_PARSE_FAILED' | 'CONFIG_MIGRATION_NEEDED'\n >;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'config',\n severity: 'fatal',\n recoverable: false,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'ConfigError';\n }\n}\n\n/**\n * Plugin loading / lifecycle errors.\n */\nexport class PluginError extends WrongStackError {\n readonly pluginName: string;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'PLUGIN_LOAD_FAILED' | 'PLUGIN_API_MISMATCH' | 'PLUGIN_MISSING_DEPENDENCY'\n >;\n pluginName: string;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'plugin',\n severity: 'error',\n recoverable: opts.code === ERROR_CODES.PLUGIN_MISSING_DEPENDENCY,\n context: { plugin: opts.pluginName, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'PluginError';\n this.pluginName = opts.pluginName;\n }\n}\n\n/**\n * Agent runtime errors — thrown by Agent.run when a non-WrongStackError\n * escapes the inner loop, so callers always see a structured error.\n */\nexport class AgentError extends WrongStackError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'AGENT_ITERATION_LIMIT' | 'AGENT_CONTEXT_OVERFLOW' | 'AGENT_ABORTED' | 'AGENT_RUN_FAILED'\n >;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'agent',\n severity: opts.code === ERROR_CODES.AGENT_ABORTED ? 'warning' : 'error',\n recoverable: opts.recoverable ?? opts.code === ERROR_CODES.AGENT_ITERATION_LIMIT,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'AgentError';\n }\n}\n\n/**\n * Wrap an arbitrary thrown value into a `WrongStackError` so the caller\n * always gets a structured error. Pass-throughs WrongStackError instances\n * unchanged; raw `Error`s and primitives get an `AGENT_RUN_FAILED` wrapper\n * with the original preserved as `cause`.\n */\nexport function toWrongStackError(\n err: unknown,\n code: Extract<ErrorCode, 'AGENT_RUN_FAILED' | 'AGENT_ABORTED' | 'UNKNOWN'> = ERROR_CODES.AGENT_RUN_FAILED,\n): WrongStackError {\n if (err instanceof WrongStackError) return err;\n const message = toErrorMessage(err);\n return new AgentError({\n message,\n code: code === 'UNKNOWN' ? ERROR_CODES.AGENT_RUN_FAILED : code,\n cause: err,\n });\n}\n\n/**\n * Session storage errors.\n */\nexport class SessionError extends WrongStackError {\n readonly sessionId?: string | undefined;\n\n constructor(opts: {\n message: string;\n code: Extract<ErrorCode, 'SESSION_NOT_FOUND' | 'SESSION_CORRUPTED' | 'SESSION_WRITE_FAILED'>;\n sessionId?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'session',\n severity: opts.code === ERROR_CODES.SESSION_WRITE_FAILED ? 'error' : 'warning',\n recoverable: opts.code !== ERROR_CODES.SESSION_CORRUPTED,\n context: { sessionId: opts.sessionId, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'SessionError';\n this.sessionId = opts.sessionId;\n }\n}\n\n/**\n * SDD (Spec-Driven Development) errors — spec validation, parsing, and\n * state machine violations in the AISpecBuilder, TaskFlow, and TaskTracker.\n */\nexport class SddError extends WrongStackError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'SDD_VALIDATION_FAILED' | 'SDD_PARSE_FAILED' | 'SDD_INVALID_STATE' | 'SDD_NOT_READY'\n >;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'sdd',\n severity: opts.code === ERROR_CODES.SDD_PARSE_FAILED ? 'warning' : 'error',\n recoverable: opts.code === ERROR_CODES.SDD_NOT_READY,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'SddError';\n }\n}\n\n/**\n * File system operation errors.\n */\nexport class FsError extends WrongStackError {\n readonly path?: string | undefined;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'FS_READ_FAILED' | 'FS_WRITE_FAILED' | 'FS_MKDIR_FAILED' | 'FS_DELETE_FAILED' | 'FS_ATOMIC_WRITE_FAILED'\n >;\n path?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'fs',\n severity: 'error',\n recoverable: opts.code !== ERROR_CODES.FS_READ_FAILED,\n context: { path: opts.path, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'FsError';\n this.path = opts.path;\n }\n}\n\n/**\n * HTTP fetch error — thrown when a network request returns a non-OK status.\n * Carries the response status so {@link classifyToolError} can branch on it\n * (429 → transient, 404 → not_found, 401 → permission) without duck-typing\n * the error via `'response' in err`.\n *\n * P3 #18 (before-release.md): the previous `'response' in err` check caught\n * any Error with a `response` property, including custom errors, proxy\n * objects, or mocked errors in tests. `instanceof FetchError` is reliable.\n *\n * Tools and providers that make HTTP requests and need the executor to\n * classify their failures should throw `new FetchError({ status, message })`\n * instead of a bare `Error` with an ad-hoc `response` field.\n */\nexport class FetchError extends WrongStackError {\n readonly status: number;\n\n constructor(opts: {\n message: string;\n status: number;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: ERROR_CODES.VALIDATION_ERROR,\n subsystem: 'general',\n severity: 'error',\n recoverable: opts.status === 429 || opts.status >= 500,\n context: { status: opts.status, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'FetchError';\n this.status = opts.status;\n }\n}\n\n/**\n * Tool input validation error — thrown when a tool's input fails a validation\n * check that the JSON Schema cannot express (e.g. `old_string === new_string`\n * in edit, or a cross-field invariant). Use this instead of a bare\n * `throw new Error('...validation...')` so {@link classifyToolError} can\n * match on `instanceof` rather than a locale-dependent message substring.\n *\n * P2 #6 (before-release.md): the previous `err.message.includes('validation')`\n * check misclassified any error whose message happened to contain \"validation\"\n * (e.g. a third-party \"input validation timeout\") as a VALIDATION error.\n *\n * Named `ToolValidationError` (not `ValidationError`) to avoid colliding with\n * the existing `ValidationError` interface exported by json-schema-validate.ts\n * (a validation-result shape, not an Error subclass).\n */\nexport class ToolValidationError extends WrongStackError {\n constructor(opts: {\n message: string;\n /** Field path or tool name that failed validation, for diagnostics. */\n field?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: ERROR_CODES.VALIDATION_ERROR,\n subsystem: 'general',\n severity: 'error',\n recoverable: false,\n context: { field: opts.field, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'ToolValidationError';\n }\n}\n\n/**\n * Response / payload parse error — thrown when an upstream HTTP response,\n * file, or data structure is well-formed at the transport layer (HTTP 200,\n * valid JSON) but is missing required fields or has an unexpected shape.\n *\n * Distinct from `ConfigError(CONFIG_PARSE_FAILED)` (which is specifically\n * for config-file parsing) and `FetchError` (which covers HTTP non-OK\n * responses). `ParseError` fills the gap: the request succeeded but the\n * response body couldn't be interpreted.\n *\n * Common sites: OAuth token responses missing `access_token`, device-code\n * responses missing `device_code`, registry responses with unexpected\n * schemas.\n */\nexport class ParseError extends WrongStackError {\n readonly source?: string | undefined;\n\n constructor(opts: {\n message: string;\n /**\n * What was being parsed — e.g. `'oauth-token-response'`,\n * `'device-code-response'`. Lets consumers distinguish parse failures\n * from different upstream APIs without parsing the message.\n */\n source?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: ERROR_CODES.PARSE_FAILED,\n subsystem: 'general',\n severity: 'error',\n recoverable: false,\n context: { source: opts.source, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'ParseError';\n this.source = opts.source;\n }\n}\n\n// ── Type guards ──────────────────────────────────────────────────────\n\nexport function isWrongStackError(err: unknown): err is WrongStackError {\n return err instanceof WrongStackError;\n}\n\nexport function isToolError(err: unknown): err is ToolError {\n return err instanceof ToolError;\n}\n\nexport function isConfigError(err: unknown): err is ConfigError {\n return err instanceof ConfigError;\n}\n\nexport function isPluginError(err: unknown): err is PluginError {\n return err instanceof PluginError;\n}\n\nexport function isSessionError(err: unknown): err is SessionError {\n return err instanceof SessionError;\n}\n\nexport function isAgentError(err: unknown): err is AgentError {\n return err instanceof AgentError;\n}\n\nexport function isFsError(err: unknown): err is FsError {\n return err instanceof FsError;\n}\n\nexport function isToolValidationError(err: unknown): err is ToolValidationError {\n return err instanceof ToolValidationError;\n}\n\nexport function isFetchError(err: unknown): err is FetchError {\n return err instanceof FetchError;\n}\n\nexport function isParseError(err: unknown): err is ParseError {\n return err instanceof ParseError;\n}\n\nexport function isSddError(err: unknown): err is SddError {\n return err instanceof SddError;\n}\n","import { randomBytes } from 'node:crypto';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { FsError } from '../types/errors.js';\n\nexport interface AtomicWriteOptions {\n mode?: number | undefined;\n encoding?: BufferEncoding | undefined;\n}\n\nexport interface FileLockOptions {\n timeoutMs?: number | undefined;\n staleMs?: number | undefined;\n}\n\nexport async function atomicWrite(\n targetPath: string,\n content: string | Uint8Array,\n opts: AtomicWriteOptions = {},\n): Promise<void> {\n const dir = path.dirname(targetPath);\n await fs.mkdir(dir, { recursive: true });\n const tmp = path.join(dir, `.${path.basename(targetPath)}.${randomBytes(6).toString('hex')}.tmp`);\n\n // Write content to tmp first; 'wx' ensures exclusive creation (fails if\n // tmp already exists — extremely unlikely with 6-byte random suffix).\n try {\n if (typeof content === 'string') {\n await fs.writeFile(tmp, content, { flag: 'wx', encoding: opts.encoding ?? 'utf8' });\n } else {\n await fs.writeFile(tmp, content, { flag: 'wx' });\n }\n try {\n const fh = await fs.open(tmp, 'r+');\n try {\n await fh.sync();\n } finally {\n await fh.close();\n }\n } catch {\n // fsync best-effort\n }\n // Now safely read mode from target (if it exists) and apply to tmp before rename.\n // Prefer opts.mode for new files; for existing files preserve their mode.\n let mode: number | undefined;\n try {\n const stat = await fs.stat(targetPath);\n mode = stat.mode & 0o777;\n } catch {\n mode = opts.mode;\n }\n if (mode !== undefined) {\n await fs.chmod(tmp, mode);\n }\n await renameWithRetry(tmp, targetPath);\n // P3 #20 (before-release.md): on Windows, fs.rename (MoveFileExW) does\n // not preserve Unix permission bits — the chmod above applies to the tmp\n // file, but the rename may reset the destination's mode to the Windows\n // default. Re-apply the mode after rename on win32 so an edited file\n // keeps its executable bit (or any non-default permission). On POSIX,\n // rename preserves metadata so this is a no-op (chmod is idempotent and\n // cheap), but we gate it on win32 to avoid the extra stat+chmod on the\n // common path.\n if (mode !== undefined && process.platform === 'win32') {\n try {\n await fs.chmod(targetPath, mode);\n } catch {\n // Best-effort: a transient EPERM (antivirus lock) should not fail\n // the write — the content is already on disk.\n }\n }\n } catch (err) {\n try {\n await fs.unlink(tmp);\n } catch {\n // ignore cleanup error\n }\n throw err;\n }\n}\n\nexport async function ensureDir(dir: string): Promise<void> {\n await fs.mkdir(dir, { recursive: true });\n}\n\nexport async function withFileLock<T>(\n targetPath: string,\n fn: () => Promise<T>,\n opts: FileLockOptions = {},\n): Promise<T> {\n const dir = path.dirname(targetPath);\n await fs.mkdir(dir, { recursive: true });\n const lockPath = path.join(dir, `.${path.basename(targetPath)}.lock`);\n const timeoutMs = opts.timeoutMs ?? 5_000;\n const staleMs = opts.staleMs ?? 30_000;\n const started = Date.now();\n let handle: fs.FileHandle | undefined;\n\n for (;;) {\n try {\n handle = await fs.open(lockPath, 'wx');\n await handle.writeFile(`${process.pid}:${Date.now()}`);\n break;\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n // ENOENT means the directory was deleted (e.g. by concurrent cleanup).\n // Recreate it and retry acquiring the lock.\n if (code === 'ENOENT') {\n await fs.mkdir(dir, { recursive: true });\n continue;\n }\n if (code !== 'EEXIST') throw err;\n try {\n const stat = await fs.stat(lockPath);\n if (Date.now() - stat.mtimeMs > staleMs) {\n await fs.unlink(lockPath);\n continue;\n }\n } catch {\n continue;\n }\n if (Date.now() - started >= timeoutMs) {\n throw new FsError({\n message: `Timed out waiting for file lock: ${targetPath}`,\n code: 'FS_ATOMIC_WRITE_FAILED',\n path: targetPath,\n context: { timeoutMs },\n });\n }\n await new Promise((resolve) => setTimeout(resolve, 25));\n }\n }\n\n try {\n return await fn();\n } finally {\n try {\n await handle?.close();\n } catch {\n // ignore\n }\n try {\n await fs.unlink(lockPath);\n } catch {\n // ignore\n }\n }\n}\n\n// On Windows, fs.rename over an existing file can fail with EPERM/EBUSY/EACCES\n// when antivirus, file indexers, editor file watchers, or a concurrent writer\n// briefly hold a handle on the destination. These are transient — retry with a\n// short backoff before giving up. POSIX renames are atomic and won't hit this.\nconst TRANSIENT_RENAME_CODES = new Set(['EPERM', 'EBUSY', 'EACCES', 'ENOTEMPTY']);\n\nasync function renameWithRetry(from: string, to: string): Promise<void> {\n if (process.platform !== 'win32') {\n await fs.rename(from, to);\n return;\n }\n const delays = [10, 25, 60, 120, 250];\n let lastErr: unknown;\n for (let i = 0; i <= delays.length; i++) {\n try {\n await fs.rename(from, to);\n return;\n } catch (err) {\n lastErr = err;\n const code = (err as NodeJS.ErrnoException)?.code;\n if (!code || !TRANSIENT_RENAME_CODES.has(code) || i === delays.length) {\n throw err;\n }\n await new Promise((resolve) => setTimeout(resolve, delays[i]));\n }\n }\n throw lastErr;\n}\n","/**\n * Mailbox — persistent inter-agent messaging system with cross-session support.\n *\n * Agents can leave notes for specific agents or broadcast to all. Each agent\n * periodically checks the mailbox or retrieves messages via tool calls.\n *\n * ## Cross-session communication\n *\n * The mailbox is stored at **project level** (`~/.wrongstack/projects/<slug>/_mailbox.jsonl`),\n * so agents in different terminal sessions / WebUI tabs working on the same\n * project can communicate live.\n *\n * ## Agent registration\n *\n * Every agent that uses the mailbox registers itself with a heartbeat.\n * Other agents can discover online agents via `getOnlineAgents()`.\n * Stale agents (no heartbeat > 60s) are pruned automatically.\n *\n * ## Read receipts\n *\n * Each message tracks per-recipient read status via a `readBy` map:\n * `{ \"agentId\": \"ISO8601\" }`. When agent X reads a message, its entry\n * is added. The WebUI shows who read what and when.\n *\n * @module mailbox-types\n */\n\n// ── Message type discriminator ───────────────────────────────────────────\n\nexport type MailboxMessageType =\n | 'note' // informational message\n | 'ask' // question / request for advice\n | 'assign' // task assignment\n | 'steer' // steering instruction (change behavior mid-task)\n | 'btw' // \"by the way\" — non-urgent info\n | 'broadcast' // sent to all agents\n | 'status' // agent status update\n | 'result' // task result / completion notice\n | 'review' // review request (code/doc/PR) — passive ask, no reply required\n | 'control'; // out-of-band control signal (e.g. interrupt) — handled by\n// the agent loop, NOT folded into the conversation as content\n\n// ── Read receipt ─────────────────────────────────────────────────────────\n\n/**\n * Per-recipient read status. `readBy` maps agentId → ISO8601 timestamp of\n * when that agent first read the message. An empty map means unread by all.\n */\nexport interface ReadReceipts {\n [agentId: string]: string; // ISO8601 timestamp\n}\n\n// ── Core message ─────────────────────────────────────────────────────────\n\nexport interface MailboxMessage {\n /** Unique message id (UUID). */\n id: string;\n /** Sender agent id. */\n from: string;\n /** Recipient agent id, or '*' for broadcast. */\n to: string;\n /** Message category. */\n type: MailboxMessageType;\n /** Short subject line — one sentence. */\n subject: string;\n /** Full message content. */\n body: string;\n /** Priority — high priority messages surface first. */\n priority: 'low' | 'normal' | 'high';\n /**\n * Per-recipient read receipts. agentId → ISO8601 when they first read it.\n * Replaces the old single `read: boolean` + `readAt` fields.\n */\n readBy: ReadReceipts;\n /** Has any recipient acted on / completed this? */\n completed: boolean;\n /** Who completed it (agentId). */\n completedBy?: string | undefined;\n /** Optional summary of what happened after handling. */\n outcome?: string | undefined;\n /** ISO8601 — when the message was sent. */\n timestamp: string;\n /** ISO8601 — when the message was marked complete. */\n completedAt?: string | undefined;\n /**\n * ISO8601 — when the message was soft-deleted. When present, the\n * default `Mailbox.query()` filter excludes the message from the\n * normal inbox view; {@link GlobalMailbox.restore} clears the\n * field to undo the delete. Hard deletes (removing the line from\n * the JSONL) are reserved for the CLI and never happen via the\n * server route handlers.\n */\n deletedAt?: string | undefined;\n /** When the soft-delete happened, the agentId that issued it. */\n deletedBy?: string | undefined;\n /** If this is a reply, the id of the parent message. */\n replyTo?: string | undefined;\n /** For assign-type messages — task context for agent discovery. */\n taskContext?: MailboxTaskContext | undefined;\n /** Session id of the sender. Enables cross-session communication. */\n senderSessionId?: string | undefined;\n}\n\n// ── Task context for agent discovery ─────────────────────────────────────\n\nexport interface MailboxTaskContext {\n /** The role that should handle this task (e.g. \"tech-stack\", \"audit-log\"). */\n agentRole?: string | undefined;\n /** Human-readable agent name (e.g. \"Tesla (Executor)\"). */\n agentName?: string | undefined;\n /** Task id if already assigned via coordinator. */\n taskId?: string | undefined;\n /** Current task status. */\n status?: 'pending' | 'in_progress' | 'completed' | 'failed' | undefined;\n}\n\n// ── Agent registration ──────────────────────────────────────────────────\n\nexport interface RegisteredAgent {\n /** Unique agent id. */\n agentId: string;\n /** Session id this agent belongs to. */\n sessionId: string;\n /** Human-readable name. */\n name: string;\n /** Role (e.g. \"leader\", \"tech-stack\", \"bug-hunter\"). */\n role?: string | undefined;\n /** Current status. */\n status: 'idle' | 'running' | 'streaming' | 'waiting_user' | 'error';\n /** Current tool being executed, if any. */\n currentTool?: string | undefined;\n /** Current task description. */\n currentTask?: string | undefined;\n /** Iteration count so far. */\n iterations: number;\n /** Tool calls so far. */\n toolCalls: number;\n /** ISO8601 — registered at. */\n registeredAt: string;\n /** ISO8601 — last heartbeat (updated on every mailbox op). */\n lastSeenAt: string;\n /** Which process registered this agent (PID). */\n pid: number;\n /** Where the agent is running (e.g. \"cli\", \"webui\"). */\n source?: 'cli' | 'webui' | 'mcp' | 'acp' | 'http' | undefined;\n}\n\n// ── Agent status entry (for discovery) ───────────────────────────────────\n\nexport interface MailboxAgentStatus {\n /** Agent id. */\n agentId: string;\n /** Human-readable name. */\n name: string;\n /** Role. */\n role?: string | undefined;\n /** Session id. */\n sessionId: string;\n /** Current status. */\n status: 'idle' | 'running' | 'streaming' | 'waiting_user' | 'error' | 'offline';\n /** Current tool being executed, if any. */\n currentTool?: string | undefined;\n /** Current task description. */\n currentTask?: string | undefined;\n /** Iteration count so far. */\n iterations: number;\n /** Tool calls so far. */\n toolCalls: number;\n /** ISO8601 — last activity timestamp. */\n lastActivityAt: string;\n /** ISO8601 — last heartbeat. */\n lastSeenAt: string;\n /** Whether this agent is currently online (heartbeat within threshold). */\n online: boolean;\n /** Which process. */\n pid: number;\n /** Source. */\n source?: 'cli' | 'webui' | 'mcp' | 'acp' | 'http' | undefined;\n}\n\n// ── Mailbox query ────────────────────────────────────────────────────────\n\nexport interface MailboxQuery {\n /** Filter by recipient agent id. */\n to?: string | undefined;\n /** Filter by sender agent id. */\n from?: string | undefined;\n /** Only messages unread by this agent. */\n unreadBy?: string | undefined;\n /** Only incomplete messages. */\n incompleteOnly?: boolean | undefined;\n /** Filter by message type. */\n type?: MailboxMessageType | undefined;\n /** Filter by priority (>= this level). */\n minPriority?: 'low' | 'normal' | 'high' | undefined;\n /** Maximum number of messages to return. */\n limit?: number | undefined;\n /** ISO8601 — only messages after this timestamp. */\n since?: string | undefined;\n /**\n * Include soft-deleted messages (where `deletedAt` is set). When\n * `false` (the default), soft-deleted messages are filtered out so\n * the normal inbox view stays clean. The \"trash\" view passes\n * `true` to surface them.\n */\n includeDeleted?: boolean | undefined;\n}\n\n// ── Mailbox operations ───────────────────────────────────────────────────\n\n/**\n * Normalize a recipient address. `\"all\"` (any casing) is an accepted\n * spelling of the broadcast address and is canonicalized to `'*'` at send\n * time — both agents and humans reach for \"all\" naturally, and a literal\n * \"all\" recipient would otherwise be deliverable to nobody. The word is\n * therefore RESERVED: no agent may register under the base id \"all\".\n */\nexport function normalizeRecipient(to: string): string {\n return to.trim().toLowerCase() === 'all' ? '*' : to.trim();\n}\n\nexport interface MailboxSendInput {\n /** Sender agent id. */\n from: string;\n /** Recipient agent id, '*' for broadcast (alias: \"all\"). */\n to: string;\n /** Message category. */\n type: MailboxMessageType;\n /** Short subject line. */\n subject: string;\n /** Full message content. */\n body: string;\n /** Priority. Default: 'normal'. */\n priority?: 'low' | 'normal' | 'high' | undefined;\n /** If replying, the id of the parent message. */\n replyTo?: string | undefined;\n /** Task context for assign-type messages. */\n taskContext?: MailboxTaskContext | undefined;\n}\n\nexport interface MailboxAckInput {\n /** Message id to acknowledge. */\n messageId: string;\n /** Agent id of who is reading/acking. */\n readerId: string;\n /** Mark as read by this agent? Defaults to true if not specified. */\n read?: boolean | undefined;\n /** Mark as completed? */\n completed?: boolean | undefined;\n /** Optional outcome summary. */\n outcome?: string | undefined;\n}\n\n/**\n * Batch acknowledgment input — applies a batch of acks under a single file\n * lock + single file rewrite. Each entry has the same shape as\n * {@link MailboxAckInput} minus the per-batch defaults documented on\n * `ackMany`. Use this when an agent is acking several fresh messages at\n * once (the common case in the mailbox loop) — it collapses N full-file\n * rewrites into one.\n */\nexport interface MailboxAckBatchInput {\n /** Ack entries to apply. */\n acks: MailboxAckInput[];\n}\n\n// ── Agent registration input ────────────────────────────────────────────\n\nexport interface AgentRegistrationInput {\n agentId: string;\n sessionId: string;\n name: string;\n role?: string | undefined;\n pid: number;\n source?: 'cli' | 'webui' | 'mcp' | 'acp' | 'http' | undefined;\n}\n\n// ── Client (REPL/TUI/WebUI) registration ─────────────────────────────────\n\nexport type ClientSource = 'repl' | 'tui' | 'webui' | 'http';\n\nexport interface RegisteredClient {\n /** Unique client id. */\n clientId: string;\n /** Session/project context id. */\n sessionId: string;\n /** Human-readable name (e.g. \"TUI [main]\", \"WebUI [chrome]\"). */\n name: string;\n /** Client type. */\n source: ClientSource;\n /** ISO8601 — registered at. */\n registeredAt: string;\n /** ISO8601 — last heartbeat. */\n lastSeenAt: string;\n /** Which process. */\n pid: number;\n}\n\nexport interface ClientStatus {\n /** Client id. */\n clientId: string;\n /** Human-readable name. */\n name: string;\n /** Client type. */\n source: ClientSource;\n /** Session id. */\n sessionId: string;\n /** ISO8601 — last activity timestamp. */\n lastSeenAt: string;\n /** Whether this client is currently online (heartbeat within threshold). */\n online: boolean;\n /** Which process. */\n pid: number;\n}\n\nexport interface ClientRegistrationInput {\n clientId: string;\n sessionId: string;\n name: string;\n source: ClientSource;\n pid: number;\n}\n\nexport interface ClientHeartbeatInput {\n clientId: string;\n /** Active session id for this client. When present, updates the registry entry. */\n sessionId?: string | undefined;\n}\n\n// ── Agent heartbeat input ────────────────────────────────────────────────\n\nexport interface AgentHeartbeatInput {\n agentId: string;\n status?: RegisteredAgent['status'] | undefined;\n currentTool?: string | undefined;\n currentTask?: string | undefined;\n iterations?: number | undefined;\n toolCalls?: number | undefined;\n}\n\n// ── Purge options & result ───────────────────────────────────────────────\n\nexport interface PurgeOptions {\n /**\n * Purge completed messages older than this many milliseconds.\n * Default: 1 day (86_400_000 ms)\n */\n completedMaxAgeMs?: number | undefined;\n /**\n * Purge incomplete messages older than this many milliseconds.\n * Default: 7 days (604_800_000 ms)\n */\n incompleteMaxAgeMs?: number | undefined;\n}\n\nexport interface PurgeResult {\n /** Messages removed because they were completed and too old. */\n completedPurged: number;\n /** Messages removed because they were incomplete and too old. */\n incompletePurged: number;\n /** Total messages removed. */\n totalPurged: number;\n /** Messages remaining in the mailbox after purge. */\n remaining: number;\n}\n\n// ── Mailbox interface ────────────────────────────────────────────────────\n\nexport interface Mailbox {\n /** Send a message. Returns the created message. */\n send(input: MailboxSendInput): Promise<MailboxMessage>;\n\n /** Query messages matching criteria. */\n query(query: MailboxQuery): Promise<MailboxMessage[]>;\n\n /** Acknowledge a message (read/complete). Returns updated message. */\n ack(input: MailboxAckInput): Promise<MailboxMessage | null>;\n\n /**\n * Acknowledge many messages in one shot. Acquires the file lock once and\n * rewrites the message file once, regardless of how many acks are in the\n * batch. Returns the messages that were actually updated (messages whose\n * ids are not in the file are skipped silently).\n *\n * This is the preferred path when an agent has multiple fresh messages\n * to receipt at once — the per-message {@link ack} path does a full\n * read-modify-rewrite of the mailbox file for every call.\n */\n ackMany(input: MailboxAckBatchInput): Promise<MailboxMessage[]>;\n\n /**\n * Soft-delete a message. Sets `deletedAt` to the current timestamp\n * and records the acting agent in `deletedBy`. Reversible via\n * {@link restore}. The default `query()` filter hides the message\n * once `deletedAt` is set; pass `includeDeleted: true` to see the\n * trash.\n *\n * Phase 2 skeleton — the method signature is declared here so the\n * WebUI client and the server route handler can compile against\n * it; the implementation lands in the same PR.\n */\n softDelete(mailId: string, by: string): Promise<MailboxMessage | null>;\n\n /**\n * Undo a {@link softDelete}. Clears `deletedAt` and `deletedBy` on\n * the message. No-op (returns the message as-is) if the message is\n * not soft-deleted.\n */\n restore(mailId: string): Promise<MailboxMessage | null>;\n\n /** Get a snapshot of online/offline agents and their current tasks. */\n getAgentStatuses(): Promise<MailboxAgentStatus[]>;\n\n /**\n * Get only online agents (heartbeat within 60s).\n * Useful for \"who can I talk to right now?\" queries.\n */\n getOnlineAgents(): Promise<MailboxAgentStatus[]>;\n\n /**\n * Register an agent. Called once per agent on first mailbox use.\n * Subsequent calls are idempotent — they update lastSeenAt.\n */\n registerAgent(input: AgentRegistrationInput): Promise<void>;\n /** Remove an agent from the registry entirely. Called on session shutdown. */\n deregisterAgent(agentId: string): Promise<void>;\n\n /**\n * Update agent heartbeat and optional status fields.\n * Called periodically (every tool call / iteration).\n */\n heartbeat(input: AgentHeartbeatInput): Promise<void>;\n\n /**\n * Count unread messages for a specific agent.\n * Used for \"new mail\" notifications without pulling full message bodies.\n */\n unreadCount(forAgentId: string): Promise<number>;\n\n /** Close and flush any pending writes. */\n close(): Promise<void>;\n\n /**\n * Delete all messages from the mailbox file.\n * Agents and read receipts are preserved; only messages are cleared.\n */\n clearAll(): Promise<void>;\n\n /**\n * Purge orphaned and stale messages from the mailbox.\n *\n * Stale messages are:\n * - Completed messages older than `completedMaxAgeMs` (default: 1 day)\n * - Incomplete messages older than `incompleteMaxAgeMs` (default: 7 days)\n *\n * This does NOT touch agent registrations or client registry.\n */\n purgeStale(opts?: PurgeOptions): Promise<PurgeResult>;\n\n // ── Client (REPL/TUI/WebUI) registry ──────────────────────────────────\n\n /**\n * Register a client (REPL/TUI/WebUI). Called once per client on startup.\n * Subsequent calls are idempotent — they update lastSeenAt.\n */\n registerClient(input: ClientRegistrationInput): Promise<void>;\n\n /**\n * Update client heartbeat. Called periodically (every 15s for clients).\n */\n clientHeartbeat(input: ClientHeartbeatInput): Promise<void>;\n\n /**\n * Get snapshot of online/offline clients and their last activity.\n */\n getClientStatuses(): Promise<ClientStatus[]>;\n}\n","/**\n * GlobalMailbox — project-level inter-agent mailbox with cross-session support.\n *\n * Stores messages at `~/.wrongstack/projects/<slug>/_mailbox.jsonl` so all\n * sessions (terminals, WebUIs) working on the same project share one inbox.\n *\n * Features:\n * - Agent registration + heartbeat (agents go stale after 60s without heartbeat)\n * - Per-recipient read receipts (readBy[agentId] = ISO8601)\n * - Atomic file-locking for concurrent multi-process writes\n * - Unread count for new-mail notifications\n * - Online agent list\n *\n * @module GlobalMailbox\n */\n\nimport { randomUUID } from 'node:crypto';\nimport * as fsp from 'node:fs/promises';\n\nimport * as path from 'node:path';\nimport type { HqPublisher } from '../hq/publisher.js';\nimport type { EventBus } from '../kernel/events.js';\nimport { withFileLock } from '../utils/atomic-write.js';\nimport { projectSlug } from '../utils/wstack-paths.js';\nimport type {\n AgentHeartbeatInput,\n AgentRegistrationInput,\n ClientHeartbeatInput,\n ClientRegistrationInput,\n ClientStatus,\n Mailbox,\n MailboxAckBatchInput,\n MailboxAckInput,\n MailboxAgentStatus,\n MailboxMessage,\n MailboxQuery,\n MailboxSendInput,\n PurgeOptions,\n PurgeResult,\n RegisteredAgent,\n RegisteredClient,\n} from './mailbox-types.js';\nimport { normalizeRecipient } from './mailbox-types.js';\n\n// ── Constants ────────────────────────────────────────────────────────────\n\nconst MAILBOX_FILE = '_mailbox.jsonl';\nconst CLIENT_REGISTRY_FILE = '_mailbox.clients.json';\n/** Agents without a heartbeat for this long are considered offline. */\nconst AGENT_STALE_MS = 60_000;\n/** Agents without a heartbeat for this long are removed from the registry entirely. */\nconst AGENT_PURGE_MS = 86_400_000; // 24 hours\n/** Clients without a heartbeat for this long are considered offline. */\nconst CLIENT_STALE_MS = 60_000;\n/** Heartbeat updates are throttled to at most this interval. */\nconst HEARTBEAT_THROTTLE_MS = 5_000;\n/**\n * How long a read may be served from the in-process registry cache before\n * re-reading the shared file. Kept well below HEARTBEAT_THROTTLE_MS so\n * cross-process registrations become visible promptly.\n */\nconst REGISTRY_CACHE_TTL_MS = 2_000;\nconst LINE_SEPARATOR = '\\n';\n/**\n * Soft cap on the in-memory message cache. The cache mirrors the JSONL\n * message file; under normal load it stays well under this. If a pathological\n * mailbox exceeds the cap we fall back to reading from disk rather than\n * holding an unbounded buffer in memory.\n */\nconst MESSAGE_CACHE_MAX_ENTRIES = 10_000;\n\ntype HqPublisherRef = HqPublisher | (() => HqPublisher | undefined);\n\n/**\n * Derive the project-level mailbox directory path.\n *\n * Delegates to the CANONICAL `projectSlug()` from wstack-paths so every\n * surface (CLI, TUI, WebUI, mailbox tool, loop checker) lands in the exact\n * same `~/.wrongstack/projects/<slug>/` directory. A previous inline copy\n * skipped the leading/trailing-hyphen strip, which silently split agents\n * working on projects with non-alphanumeric name edges into TWO mailboxes.\n *\n * @param projectRoot — absolute path to the project root\n * @param globalRoot — `~/.wrongstack` (or custom global root)\n */\nexport function resolveProjectDir(projectRoot: string, globalRoot: string): string {\n return path.join(globalRoot, 'projects', projectSlug(projectRoot));\n}\n\n// ── GlobalMailbox ────────────────────────────────────────────────────────\n\nexport class GlobalMailbox implements Mailbox {\n /** Path to the JSONL message file. */\n readonly messagePath: string;\n /** Path to the JSON agent registry file. */\n readonly registryPath: string;\n /** Path to the JSON client registry file. */\n readonly clientRegistryPath: string;\n /** Optional event bus for emitting agent registration/heartbeat events. */\n private readonly _events?: EventBus | undefined;\n /** Optional HQ publisher for cross-project command-center telemetry. */\n private readonly _hqPublisher?: HqPublisherRef | undefined;\n /**\n * Local cache of the agent registry to avoid re-reading on every call.\n * Time-bounded: the registry file is shared ACROSS PROCESSES (that's the\n * whole point of GlobalMailbox), so a cache served forever would never see\n * agents registered by other sessions. Writers always bypass it.\n */\n private _registryCache: Map<string, RegisteredAgent> | null = null;\n /** When the registry cache was last refreshed from disk (epoch ms). */\n private _registryCacheAt = 0;\n /**\n * Local cache of the client registry to avoid re-reading on every call.\n * Same reasoning as agent registry cache.\n */\n private _clientRegistryCache: Map<string, RegisteredClient> | null = null;\n /** When the client registry cache was last refreshed from disk (epoch ms). */\n private _clientRegistryCacheAt = 0;\n /** Last time each local agent sent a heartbeat (throttle). */\n private _lastHeartbeat = new Map<string, number>();\n /** Last time each local client sent a heartbeat (throttle). */\n private _lastClientHeartbeat = new Map<string, number>();\n /**\n * In-memory mirror of the JSONL message file. The mailbox is shared\n * ACROSS PROCESSES, so reads cannot trust the cache blindly — we pair it\n * with an mtime check. The file lock serializes every write, so a\n * changed mtimeMs is a definitive signal that another process (or this\n * one) wrote; an unchanged mtimeMs guarantees no write happened and the\n * cache is current. This collapses the per-iteration `query()` cost from\n * O(file_size) disk + parse to O(messages) in memory.\n */\n private _messageCache: MailboxMessage[] | null = null;\n /** mtimeMs of the file when `_messageCache` was populated. */\n private _messageCacheMtime = -1;\n /** Size of the file when `_messageCache` was populated (extra guard). */\n private _messageCacheSize = -1;\n /**\n * Serializes reads of the message file so overlapping concurrent\n * `_readMessagesCached()` calls don't both enter the incremental \"file\n * only grew\" branch against the same stale `_messageCacheSize` and\n * each push the same tail bytes onto the cache (duplicating every\n * appended message). The chain runs each read to completion before\n * the next starts, in issue order — readers are read-only and never\n * conflict with each other on content, only on the cache mutation\n * that follows the read. Pattern mirrors `DefaultMemoryStore.runSerialized`.\n */\n private _readChain: Promise<MailboxMessage[]> = Promise.resolve([] as MailboxMessage[]);\n\n /**\n * @param projectDir — `~/.wrongstack/projects/<slug>/`\n * @param events — optional EventBus for real-time TUI/WebUI notifications\n * @param hqPublisher — optional HQ publisher, or getter, for cross-project telemetry\n */\n constructor(projectDir: string, events?: EventBus, hqPublisher?: HqPublisherRef) {\n this.messagePath = path.join(projectDir, MAILBOX_FILE);\n this.registryPath = path.join(projectDir, '_mailbox.registry.json');\n this.clientRegistryPath = path.join(projectDir, CLIENT_REGISTRY_FILE);\n this._events = events;\n this._hqPublisher = hqPublisher;\n }\n\n private get hqMailboxId(): string {\n return `${path.basename(path.dirname(this.messagePath))}:mailbox`;\n }\n\n private get hqPublisher(): HqPublisher | undefined {\n return typeof this._hqPublisher === 'function' ? this._hqPublisher() : this._hqPublisher;\n }\n\n private publishHqMailboxEvent(input: Parameters<HqPublisher['publishMailboxEvent']>[0]): void {\n try {\n this.hqPublisher?.publishMailboxEvent(input);\n } catch {\n // HQ telemetry is best-effort and must never affect mailbox behavior.\n }\n }\n\n private publishHqMailboxSnapshot(): void {\n const publisher = this.hqPublisher;\n if (publisher === undefined) return;\n void publisher.publishMailboxSnapshot(this, { mailboxId: this.hqMailboxId }).catch(() => {\n // HQ telemetry is best-effort and must never affect mailbox behavior.\n });\n }\n\n // ── Messages ────────────────────────────────────────────────────────────\n\n async send(input: MailboxSendInput): Promise<MailboxMessage> {\n const now = new Date().toISOString();\n const msg: MailboxMessage = {\n id: randomUUID(),\n from: input.from,\n // \"all\" is an accepted spelling of the broadcast address — canonical\n // form on disk is '*' so every query/checker matches it.\n to: normalizeRecipient(input.to),\n type: input.type,\n subject: input.subject,\n body: input.body,\n priority: input.priority ?? 'normal',\n readBy: {},\n completed: false,\n timestamp: now,\n replyTo: input.replyTo,\n taskContext: input.taskContext,\n };\n\n const line = JSON.stringify(msg) + LINE_SEPARATOR;\n await fsp.mkdir(path.dirname(this.messagePath), { recursive: true });\n // The append must hold the same lock ack() rewrites under: an unlocked\n // append racing ack's read→rewrite gets silently erased when the rewrite\n // lands. This file is shared ACROSS PROCESSES, so the window is real.\n await withFileLock(this.messagePath, async () => {\n await fsp.appendFile(this.messagePath, line, 'utf8');\n // Capture the post-append stat INSIDE the lock so the cache trackers\n // advance with the pushed content. A concurrent reader that lands\n // after we release but before a future stat would otherwise see the\n // file grew and re-append the just-sent tail, duplicating it.\n const { mtimeMs, size } = await this._statMessageFile();\n // Refresh the in-memory cache from the message we just appended —\n // cheaper than re-reading the whole file, and correct because we\n // held the lock so nothing else changed underneath us.\n this._pushToCache(msg, mtimeMs, size);\n });\n\n this.publishHqMailboxEvent({\n mailboxId: this.hqMailboxId,\n action: 'message.sent',\n message: msg,\n });\n this.publishHqMailboxSnapshot();\n return msg;\n }\n\n async query(q: MailboxQuery): Promise<MailboxMessage[]> {\n const all = await this._readMessagesCached();\n const limit = q.limit ?? 50;\n\n // Single-pass filter — previously 7 chained .filter() allocations each\n // producing a fresh array. Predicates are independent, so we can AND\n // them in one walk and short-circuit per element.\n const order = q.minPriority !== undefined ? ({ low: 0, normal: 1, high: 2 } as const) : null;\n const minPriorityRank = order && q.minPriority !== undefined ? order[q.minPriority] : 0;\n const out: MailboxMessage[] = [];\n for (let i = 0; i < all.length; i++) {\n const m = all[i]!;\n if (q.to !== undefined && m.to !== q.to && m.to !== '*') continue;\n if (q.from !== undefined && m.from !== q.from) continue;\n if (q.unreadBy !== undefined && q.unreadBy in m.readBy) continue;\n if (q.incompleteOnly && m.completed) continue;\n if (q.type !== undefined && m.type !== q.type) continue;\n if (order !== null && (order[m.priority as keyof typeof order] ?? 1) < minPriorityRank!) {\n continue;\n }\n if (q.since !== undefined && m.timestamp <= q.since) continue;\n // Default behavior: soft-deleted messages are hidden unless the\n // caller explicitly opts in via `includeDeleted: true` (used by\n // the WebUI's \"trash\" view).\n if (!q.includeDeleted && m.deletedAt !== undefined) continue;\n out.push(m);\n }\n\n out.sort((a, b) => b.timestamp.localeCompare(a.timestamp));\n // Return defensive shallow copies so callers cannot mutate the shared\n // cache entries. Only the returned slice is copied — O(limit), not O(N).\n return out.slice(0, limit).map((m) => ({ ...m, readBy: { ...m.readBy } }));\n }\n\n async ack(input: MailboxAckInput): Promise<MailboxMessage | null> {\n const updated = await this.ackMany({ acks: [input] });\n return updated.length > 0 ? updated[0]! : null;\n }\n\n async ackMany(input: MailboxAckBatchInput): Promise<MailboxMessage[]> {\n // One lock acquisition + one file rewrite for the whole batch. The\n // previous per-message ack() did a full read-modify-rewrite for every\n // single ack — N fresh messages meant N full-file rewrites in a row.\n if (input.acks.length === 0) return [];\n\n const updated: MailboxMessage[] = [];\n const byId = new Map<string, MailboxAckInput>();\n for (const a of input.acks) {\n // Last-write-wins within the batch for the same messageId — matches\n // the prior sequential semantics where later acks overrode earlier.\n byId.set(a.messageId, a);\n }\n\n await withFileLock(this.messagePath, async () => {\n // Read fresh under the lock — the cache may be stale relative to\n // other processes that wrote since our last read.\n const all = await this._readMessagesFresh();\n const now = new Date().toISOString();\n let changed = false;\n\n for (const msg of all) {\n const a = byId.get(msg.id);\n if (!a) continue;\n // Preserve prior semantics: return the message as long as it was\n // found, even if the ack was a no-op (e.g. already read).\n updated.push(msg);\n if (a.read !== false && !(a.readerId in msg.readBy)) {\n msg.readBy[a.readerId] = now;\n changed = true;\n }\n if (a.completed && !msg.completed) {\n msg.completed = true;\n msg.completedBy = a.readerId;\n msg.completedAt = now;\n changed = true;\n }\n if (a.outcome !== undefined && msg.outcome !== a.outcome) {\n msg.outcome = a.outcome;\n changed = true;\n }\n }\n\n // Only rewrite the file if at least one ack actually mutated state —\n // a re-ack of an already-read message is now a no-op on disk, where\n // previously it was a full rewrite.\n if (changed) {\n const serialized = all.map((m) => JSON.stringify(m)).join(LINE_SEPARATOR) + LINE_SEPARATOR;\n await fsp.writeFile(this.messagePath, serialized, 'utf8');\n }\n // Promote the cache INSIDE the lock with the post-write (or\n // post-read when unchanged) stat so the mtime/size trackers are set\n // synchronously with the content — no race window where a concurrent\n // reader sees fresh content but stale trackers and misclassifies a\n // rewrite as a \"file only grew\" append.\n const { mtimeMs, size } = await this._statMessageFile();\n this._setMessageCache(all, mtimeMs, size);\n });\n\n for (const message of updated) {\n this.publishHqMailboxEvent({\n mailboxId: this.hqMailboxId,\n action: message.completed ? 'message.completed' : 'message.read',\n message,\n });\n }\n if (updated.length > 0) this.publishHqMailboxSnapshot();\n return updated;\n }\n\n async unreadCount(forAgentId: string): Promise<number> {\n const all = await this._readMessagesCached();\n let count = 0;\n for (let i = 0; i < all.length; i++) {\n const m = all[i]!;\n if ((m.to === forAgentId || m.to === '*') && !(forAgentId in m.readBy) && !m.completed) {\n count++;\n }\n }\n return count;\n }\n\n async softDelete(mailId: string, by: string): Promise<MailboxMessage | null> {\n // Single-message soft delete. Acquires the file lock and writes\n // the file with the matched message's `deletedAt` set. No-op if\n // the message does not exist or is already soft-deleted (the\n // second case is a successful no-op: returns the message with\n // `deletedAt` unchanged).\n let updated: MailboxMessage | null = null;\n await withFileLock(this.messagePath, async () => {\n const all = await this._readMessagesFresh();\n const now = new Date().toISOString();\n for (const m of all) {\n if (m.id !== mailId) continue;\n if (m.deletedAt !== undefined) {\n // Already soft-deleted — return the existing record so the\n // caller can no-op cleanly. No event is published.\n updated = m;\n continue;\n }\n m.deletedAt = now;\n m.deletedBy = by;\n updated = m;\n }\n const serialized = all.map((m) => JSON.stringify(m)).join(LINE_SEPARATOR) + LINE_SEPARATOR;\n await fsp.writeFile(this.messagePath, serialized, 'utf8');\n // Promote the cache inside the lock with the post-write stat so the\n // mtime/size trackers are set synchronously with the content.\n const { mtimeMs, size } = await this._statMessageFile();\n this._setMessageCache(all, mtimeMs, size);\n });\n if (updated !== null) {\n this.publishHqMailboxEvent({\n mailboxId: this.hqMailboxId,\n action: 'message.updated',\n message: updated,\n });\n this.publishHqMailboxSnapshot();\n }\n return updated;\n }\n\n async restore(mailId: string): Promise<MailboxMessage | null> {\n // Inverse of `softDelete`. Clears `deletedAt` + `deletedBy` so the\n // message reappears in the default `query()` result. No-op when\n // the message exists but is not currently soft-deleted. Emits an\n // event unconditionally so the WebUI can re-fetch the message\n // (the duplicate-event cost is acceptable: the WebUI dedupes by\n // `mailId`).\n let updated: MailboxMessage | null = null;\n await withFileLock(this.messagePath, async () => {\n const all = await this._readMessagesFresh();\n for (const m of all) {\n if (m.id !== mailId) continue;\n delete m.deletedAt;\n delete m.deletedBy;\n updated = m;\n }\n const serialized = all.map((m) => JSON.stringify(m)).join(LINE_SEPARATOR) + LINE_SEPARATOR;\n await fsp.writeFile(this.messagePath, serialized, 'utf8');\n // Promote the cache inside the lock with the post-write stat so the\n // mtime/size trackers are set synchronously with the content.\n const { mtimeMs, size } = await this._statMessageFile();\n this._setMessageCache(all, mtimeMs, size);\n });\n if (updated !== null) {\n this.publishHqMailboxEvent({\n mailboxId: this.hqMailboxId,\n action: 'message.updated',\n message: updated,\n });\n this.publishHqMailboxSnapshot();\n }\n return updated;\n }\n\n // ── Agent registry ──────────────────────────────────────────────────────\n\n async registerAgent(input: AgentRegistrationInput): Promise<void> {\n await this._ensureRegistry();\n const now = new Date().toISOString();\n const agent: RegisteredAgent = {\n agentId: input.agentId,\n sessionId: input.sessionId,\n name: input.name,\n role: input.role,\n status: 'idle',\n currentTool: undefined,\n currentTask: undefined,\n iterations: 0,\n toolCalls: 0,\n registeredAt: now,\n lastSeenAt: now,\n pid: input.pid,\n source: input.source,\n };\n\n await withFileLock(this.registryPath, async () => {\n // fresh: read-modify-write must start from the on-disk state, not the\n // cache — other processes may have registered agents since.\n const registry = await this._readRegistry({ fresh: true });\n // Prune stale agents\n this._pruneStaleInPlace(registry);\n // Upsert\n registry.set(input.agentId, agent);\n // Update cache\n this._registryCache = registry;\n this._registryCacheAt = Date.now();\n await this._writeRegistry(registry);\n });\n\n // Emit event for TUI/WebUI to update online agent count\n this._events?.emitCustom('mailbox.agent_registered', {\n agentId: input.agentId,\n sessionId: input.sessionId,\n name: input.name,\n role: input.role,\n source: input.source,\n });\n this.publishHqMailboxEvent({\n mailboxId: this.hqMailboxId,\n action: 'agent.registered',\n agent: {\n agentId: input.agentId,\n name: input.name,\n ...(input.role !== undefined ? { role: input.role } : {}),\n sessionId: input.sessionId,\n status: 'idle',\n iterations: 0,\n toolCalls: 0,\n lastActivityAt: now,\n lastSeenAt: now,\n online: true,\n pid: input.pid,\n ...(input.source !== undefined ? { source: input.source } : {}),\n },\n });\n this.publishHqMailboxSnapshot();\n }\n\n async deregisterAgent(agentId: string): Promise<void> {\n await this._ensureRegistry();\n let removed: RegisteredAgent | undefined;\n await withFileLock(this.registryPath, async () => {\n const registry = await this._readRegistry({ fresh: true });\n this._pruneStaleInPlace(registry);\n // Capture the record before deletion so HQ telemetry can emit a full,\n // well-typed agent summary rather than a bare id.\n removed = registry.get(agentId);\n registry.delete(agentId);\n this._registryCache = registry;\n this._registryCacheAt = Date.now();\n await this._writeRegistry(registry);\n });\n this._events?.emitCustom('mailbox.agent_deregistered', {\n agentId,\n });\n this.publishHqMailboxEvent({\n mailboxId: this.hqMailboxId,\n action: 'agent.deregistered',\n agent: {\n agentId,\n name: removed?.name ?? agentId,\n ...(removed?.role !== undefined ? { role: removed.role } : {}),\n sessionId: removed?.sessionId ?? '',\n status: 'offline',\n ...(removed?.currentTool !== undefined ? { currentTool: removed.currentTool } : {}),\n ...(removed?.currentTask !== undefined ? { currentTask: removed.currentTask } : {}),\n iterations: removed?.iterations ?? 0,\n toolCalls: removed?.toolCalls ?? 0,\n lastActivityAt: removed?.lastSeenAt ?? new Date().toISOString(),\n lastSeenAt: removed?.lastSeenAt ?? new Date().toISOString(),\n online: false,\n pid: removed?.pid ?? 0,\n ...(removed?.source !== undefined ? { source: removed.source } : {}),\n },\n });\n this.publishHqMailboxSnapshot();\n }\n\n async heartbeat(input: AgentHeartbeatInput): Promise<void> {\n // Throttle: at most one heartbeat per agent per HEARTBEAT_THROTTLE_MS\n const last = this._lastHeartbeat.get(input.agentId) ?? 0;\n const now = Date.now();\n if (now - last < HEARTBEAT_THROTTLE_MS) return;\n\n this._lastHeartbeat.set(input.agentId, now);\n\n await this._ensureRegistry();\n\n await withFileLock(this.registryPath, async () => {\n // fresh: see registerAgent — never read-modify-write from the cache.\n const registry = await this._readRegistry({ fresh: true });\n this._pruneStaleInPlace(registry);\n\n const agent = registry.get(input.agentId);\n if (agent) {\n const iso = new Date().toISOString();\n agent.lastSeenAt = iso;\n if (input.status !== undefined) agent.status = input.status;\n if (input.currentTool !== undefined) agent.currentTool = input.currentTool;\n if (input.currentTask !== undefined) agent.currentTask = input.currentTask;\n if (input.iterations !== undefined) agent.iterations = input.iterations;\n if (input.toolCalls !== undefined) agent.toolCalls = input.toolCalls;\n }\n // If agent not registered yet, silently skip — registerAgent first\n\n this._registryCache = registry;\n this._registryCacheAt = Date.now();\n await this._writeRegistry(registry);\n });\n\n // Emit event so TUI/WebUI can track online agents in real time\n this._events?.emitCustom('mailbox.agent_heartbeat', {\n agentId: input.agentId,\n status: input.status,\n currentTool: input.currentTool,\n currentTask: input.currentTask,\n });\n this.publishHqMailboxEvent({\n mailboxId: this.hqMailboxId,\n action: 'agent.heartbeat',\n summary: input.agentId,\n });\n this.publishHqMailboxSnapshot();\n }\n\n async getAgentStatuses(): Promise<MailboxAgentStatus[]> {\n await this._ensureRegistry();\n const registry = await this._readRegistry();\n this._pruneStaleInPlace(registry);\n\n const now = Date.now();\n return Array.from(registry.values())\n .map((a) => ({\n agentId: a.agentId,\n name: a.name,\n role: a.role,\n sessionId: a.sessionId,\n status: a.status,\n currentTool: a.currentTool,\n currentTask: a.currentTask,\n iterations: a.iterations,\n toolCalls: a.toolCalls,\n lastActivityAt: a.lastSeenAt,\n lastSeenAt: a.lastSeenAt,\n online: now - new Date(a.lastSeenAt).getTime() < AGENT_STALE_MS,\n pid: a.pid,\n source: a.source,\n }))\n .sort((a, b) => b.lastSeenAt.localeCompare(a.lastSeenAt));\n }\n\n async getOnlineAgents(): Promise<MailboxAgentStatus[]> {\n const all = await this.getAgentStatuses();\n return all.filter((a) => a.online);\n }\n\n // ── Client registry ─────────────────────────────────────────────────────\n\n async registerClient(input: ClientRegistrationInput): Promise<void> {\n await this._ensureClientRegistry();\n const now = new Date().toISOString();\n const client: RegisteredClient = {\n clientId: input.clientId,\n sessionId: input.sessionId,\n name: input.name,\n source: input.source,\n registeredAt: now,\n lastSeenAt: now,\n pid: input.pid,\n };\n\n await withFileLock(this.clientRegistryPath, async () => {\n const registry = await this._readClientRegistry({ fresh: true });\n this._pruneStaleClientsInPlace(registry);\n registry.set(input.clientId, client);\n this._clientRegistryCache = registry;\n this._clientRegistryCacheAt = Date.now();\n await this._writeClientRegistry(registry);\n });\n\n // Emit event for TUI/WebUI to update online client count\n this._events?.emitCustom('mailbox.client_registered', {\n clientId: input.clientId,\n sessionId: input.sessionId,\n name: input.name,\n source: input.source,\n });\n this.publishHqMailboxSnapshot();\n }\n\n async clientHeartbeat(input: ClientHeartbeatInput): Promise<void> {\n // Throttle: at most one heartbeat per client per HEARTBEAT_THROTTLE_MS\n const last = this._lastClientHeartbeat.get(input.clientId) ?? 0;\n const now = Date.now();\n if (now - last < HEARTBEAT_THROTTLE_MS) return;\n\n this._lastClientHeartbeat.set(input.clientId, now);\n\n await this._ensureClientRegistry();\n\n await withFileLock(this.clientRegistryPath, async () => {\n const registry = await this._readClientRegistry({ fresh: true });\n this._pruneStaleClientsInPlace(registry);\n\n const client = registry.get(input.clientId);\n if (client) {\n client.lastSeenAt = new Date().toISOString();\n if (typeof input.sessionId === 'string' && input.sessionId.length > 0) {\n client.sessionId = input.sessionId;\n }\n }\n\n this._clientRegistryCache = registry;\n this._clientRegistryCacheAt = Date.now();\n await this._writeClientRegistry(registry);\n });\n\n // Emit event so TUI/WebUI can track online clients in real time\n this._events?.emitCustom('mailbox.client_heartbeat', {\n clientId: input.clientId,\n ...(input.sessionId ? { sessionId: input.sessionId } : {}),\n });\n this.publishHqMailboxSnapshot();\n }\n\n async getClientStatuses(): Promise<ClientStatus[]> {\n await this._ensureClientRegistry();\n const registry = await this._readClientRegistry();\n this._pruneStaleClientsInPlace(registry);\n\n const now = Date.now();\n return Array.from(registry.values())\n .map((c) => ({\n clientId: c.clientId,\n name: c.name,\n source: c.source,\n sessionId: c.sessionId,\n lastSeenAt: c.lastSeenAt,\n online: now - new Date(c.lastSeenAt).getTime() < CLIENT_STALE_MS,\n pid: c.pid,\n }))\n .sort((a, b) => b.lastSeenAt.localeCompare(a.lastSeenAt));\n }\n\n // ── Lifecycle ───────────────────────────────────────────────────────────\n\n async close(): Promise<void> {\n // JSONL append-only — no flush needed\n this._registryCache = null;\n this._clientRegistryCache = null;\n this._messageCache = null;\n this._messageCacheMtime = -1;\n this._messageCacheSize = -1;\n }\n\n async clearAll(): Promise<void> {\n // Truncate the mailbox file and promote the empty cache under the same\n // lock, with the post-truncate stat captured synchronously so a\n // concurrent reader doesn't misclassify the shrink as a \"file only\n // grew\" append.\n await withFileLock(this.messagePath, async () => {\n await fsp.writeFile(this.messagePath, '', 'utf8');\n const { mtimeMs, size } = await this._statMessageFile();\n this._setMessageCache([], mtimeMs, size);\n });\n }\n\n async purgeStale(opts?: PurgeOptions): Promise<PurgeResult> {\n const COMPLETED_MAX_AGE_MS = opts?.completedMaxAgeMs ?? 86_400_000; // 1 day\n const INCOMPLETE_MAX_AGE_MS = opts?.incompleteMaxAgeMs ?? 604_800_000; // 7 days\n\n let completedPurged = 0;\n let incompletePurged = 0;\n let remaining = 0;\n\n // Read-modify-write under the lock — same pattern as ack().\n await withFileLock(this.messagePath, async () => {\n const all = await this._readMessagesFresh();\n const now = Date.now();\n const cutoffCompleted = now - COMPLETED_MAX_AGE_MS;\n const cutoffIncomplete = now - INCOMPLETE_MAX_AGE_MS;\n\n const kept: MailboxMessage[] = [];\n\n for (const msg of all) {\n const msgTime = new Date(msg.timestamp).getTime();\n const completedTime = msg.completedAt ? new Date(msg.completedAt).getTime() : 0;\n\n if (msg.completed && completedTime < cutoffCompleted) {\n completedPurged++;\n continue; // drop\n }\n if (!msg.completed && msgTime < cutoffIncomplete) {\n incompletePurged++;\n continue; // drop\n }\n\n kept.push(msg);\n }\n remaining = kept.length;\n\n // Rewrite only if something changed\n if (kept.length < all.length) {\n const content = kept.map((m) => JSON.stringify(m)).join(LINE_SEPARATOR) + LINE_SEPARATOR;\n await fsp.writeFile(this.messagePath, content, 'utf8');\n }\n // Capture the post-write (or post-read when nothing purged) stat\n // inside the lock so the cache trackers match the on-disk state.\n const { mtimeMs, size } = await this._statMessageFile();\n // Either way we just read fresh under the lock, so adopt the kept\n // snapshot (== all when nothing was purged) as the cache.\n this._setMessageCache(kept, mtimeMs, size);\n });\n\n return {\n completedPurged,\n incompletePurged,\n totalPurged: completedPurged + incompletePurged,\n remaining,\n };\n }\n\n // ── Internal ────────────────────────────────────────────────────────────\n\n /**\n * Read all messages from the JSONL file. Always reads + parses the file.\n * Callers that can tolerate a stale-by-mtime view should use\n * {@link _readMessagesCached}; writers that need the post-lock truth\n * should call this directly (it's what {@link _readMessagesFresh} aliases).\n */\n private async _readMessages(): Promise<MailboxMessage[]> {\n try {\n const raw = await fsp.readFile(this.messagePath, 'utf8');\n return this._parseLines(raw);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return [];\n throw err;\n }\n }\n\n /**\n * Read only newly-appended bytes from the file and append them to the\n * in-memory cache. This avoids re-reading and re-parsing the entire file\n * when another process appended messages since our last read.\n *\n * Only safe when the file grew in size (messages are append-only). When\n * the file was rewritten (ack/purge changed existing content), callers\n * must fall back to {@link _readMessages}.\n *\n * @returns The (now up-to-date) message cache.\n */\n private async _readNewMessagesOnly(\n fd: fsp.FileHandle,\n oldSize: number,\n newSize: number,\n ): Promise<MailboxMessage[]> {\n const tailLen = newSize - oldSize;\n const buf = Buffer.alloc(tailLen);\n await fd.read(buf, 0, tailLen, oldSize);\n const tail = buf.toString('utf8');\n // Parse and append each new line to the cache.\n for (const line of tail.split(LINE_SEPARATOR)) {\n if (!line.trim()) continue;\n try {\n const parsed = JSON.parse(line) as Record<string, unknown>;\n // Migrate old `read: boolean` + `readAt` to new `readBy`\n if (!parsed['readBy']) {\n const readBy: Record<string, string> = {};\n if (parsed['read'] && parsed['readAt']) {\n readBy[parsed['to'] as string] = parsed['readAt'] as string;\n }\n parsed['readBy'] = readBy;\n delete parsed['read'];\n delete parsed['readAt'];\n }\n this._messageCache!.push(parsed as never as MailboxMessage);\n } catch {\n // Skip malformed lines\n }\n }\n return this._messageCache!;\n }\n\n /** Parse a JSONL string into MailboxMessage[], including migration. */\n private _parseLines(raw: string): MailboxMessage[] {\n const lines = raw.split(LINE_SEPARATOR).filter((l) => l.trim().length > 0);\n const messages: MailboxMessage[] = [];\n for (const line of lines) {\n try {\n const parsed = JSON.parse(line) as Record<string, unknown>;\n // Migrate old `read: boolean` + `readAt` to new `readBy`\n if (!parsed['readBy']) {\n const readBy: Record<string, unknown> = {};\n if (parsed['read'] && parsed['readAt']) {\n readBy[parsed['to'] as string] = parsed['readAt'];\n }\n parsed['readBy'] = readBy;\n delete parsed['read'];\n delete parsed['readAt'];\n }\n messages.push(parsed as never as MailboxMessage);\n } catch {\n // Skip malformed lines\n }\n }\n return messages;\n }\n\n /**\n * Read messages, then adopt the result as the in-memory cache. Use this\n * from writers that just took the file lock — the read reflects the\n * authoritative post-lock state and should be served to subsequent\n * queries without re-reading.\n *\n * The mtime/size are captured from the stat at read time so the cache\n * trackers match exactly what was parsed. Writers that subsequently\n * rewrite the file MUST re-stat after the write and re-promote with the\n * post-write values (see ackMany / softDelete / restore / purgeStale /\n * clearAll) — otherwise a concurrent reader misclassifies the rewrite\n * as a \"file only grew\" append and corrupts the cache.\n */\n private async _readMessagesFresh(): Promise<MailboxMessage[]> {\n const all = await this._readMessages();\n const { mtimeMs, size } = await this._statMessageFile();\n this._setMessageCache(all, mtimeMs, size);\n return all;\n }\n\n /**\n * Stat the message file, returning its mtimeMs and size. Returns\n * `-1/-1` when the file does not yet exist (ENOENT) so callers can\n * still promote a cache snapshot — the next read will re-stat and\n * fall through to a full re-read. Call from inside the file lock so\n * the result reflects the post-write on-disk state, not a later\n * intermediate state from another process.\n */\n private async _statMessageFile(): Promise<{ mtimeMs: number; size: number }> {\n try {\n const st = await fsp.stat(this.messagePath);\n return { mtimeMs: st.mtimeMs, size: st.size };\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') {\n return { mtimeMs: -1, size: -1 };\n }\n throw err;\n }\n }\n\n /**\n * Read messages, consulting the mtime-bounded in-memory cache first,\n * serialized so concurrent callers don't both mutate the cache.\n *\n * The mailbox file is shared across processes; every `send`/`ack`/\n * `clearAll`/`purgeStale` takes the file lock, so writes are serialized\n * and a changed mtimeMs is a definitive freshness signal. When the\n * stat matches the cached mtime+size we return the cached array — no\n * file read and no JSON.parse — collapsing the per-iteration query\n * cost on the mailbox-loop hot path.\n *\n * When the file only grew (new messages appended by another process),\n * we read and parse just the tail bytes instead of the entire file.\n * This avoids re-parsing the full 10K-message history on every check.\n *\n * SERIALIZATION: the actual work is chained onto `_readChain` so two\n * overlapping calls can't both pass the `st.size > _messageCacheSize`\n * incremental check against the same stale tracker and each push the\n * same tail bytes onto the cache (duplicating every appended message).\n * Readers don't conflict on file content — only on the cache mutation\n * that follows the read — so we run them one at a time in issue order.\n * Errors in the chain are swallowed so a failed read never poisons\n * subsequent reads; each caller observes and re-throws its own error.\n */\n private _readMessagesCached(): Promise<MailboxMessage[]> {\n // Chain this read after the prior one settles. Catch-and-swallow the\n // prior's error so the chain stays alive for this call regardless.\n const run = this._readChain\n .catch(() => undefined as unknown as MailboxMessage[])\n .then(() => this._readMessagesCachedWork());\n this._readChain = run.catch(() => [] as MailboxMessage[]);\n return run;\n }\n\n /**\n * The un-serialized body of {@link _readMessagesCached}. Reads the\n * message file with the mtime-bounded cache + incremental-tail\n * optimization. Must only be called from `_readMessagesCached` so the\n * cache mutations here don't race a sibling read.\n */\n private async _readMessagesCachedWork(): Promise<MailboxMessage[]> {\n try {\n const st = await fsp.stat(this.messagePath);\n\n // Fast path: cache is current — no disk I/O beyond stat.\n if (\n this._messageCache !== null &&\n this._messageCacheMtime === st.mtimeMs &&\n this._messageCacheSize === st.size\n ) {\n return this._messageCache;\n }\n\n // Incremental path: cache exists and the file only grew (appends).\n // No ack/purge/clear rewrote the file, so we only need to parse\n // the newly-appended bytes.\n if (\n this._messageCache !== null &&\n this._messageCacheSize >= 0 &&\n st.size > this._messageCacheSize\n ) {\n const fd = await fsp.open(this.messagePath, 'r');\n try {\n const updated = await this._readNewMessagesOnly(fd, this._messageCacheSize, st.size);\n this._messageCacheMtime = st.mtimeMs;\n this._messageCacheSize = st.size;\n return updated;\n } finally {\n await fd.close();\n }\n }\n\n // Full re-read: cache empty, file was rewritten (ack/purge), or\n // this is the first read.\n const all = await this._readMessages();\n this._setMessageCache(all, st.mtimeMs, st.size);\n return all;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') {\n this._setMessageCache([], -1, -1);\n return [];\n }\n throw err;\n }\n }\n\n /**\n * Replace the in-memory cache, setting the mtime/size trackers\n * synchronously in the same step. Callers MUST pass the stat of the\n * on-disk file state that produced `messages`.\n *\n * Why both are required (not fire-and-forget): `_readMessagesCached()`\n * validates the cache against a fresh stat using these two trackers.\n * If the cache array is updated but the trackers lag behind (e.g. via\n * a deferred `stat().then(...)`), a concurrent reader landing in that\n * window sees a mismatched mtime and falls into the incremental\n * \"file only grew\" branch — parsing rewritten bytes as an appended\n * tail and corrupting the cache with duplicates/garbage. So both\n * values are captured under the file lock and applied synchronously\n * here, matching the fix already shipped in DefaultMailbox.\n */\n private _setMessageCache(messages: MailboxMessage[], mtime: number, size: number): void {\n // Bound the cache so a runaway mailbox can't balloon memory. The cap\n // is high enough that any realistic project mailbox fits; if it ever\n // exceeds the cap we just refuse to cache and the next read goes to\n // disk (the unoptimized but correct behavior).\n if (messages.length > MESSAGE_CACHE_MAX_ENTRIES) {\n this._messageCache = null;\n this._messageCacheMtime = -1;\n this._messageCacheSize = -1;\n return;\n }\n this._messageCache = messages;\n this._messageCacheMtime = mtime;\n this._messageCacheSize = size;\n }\n\n /**\n * Append a single just-sent message to the in-memory cache without\n * re-reading the file. The caller must hold the file lock (or have\n * just released it after a successful append) and MUST pass the\n * post-append stat so the mtime/size trackers advance in lock-step\n * with the pushed content.\n *\n * Why the stat is required here: without it, `_messageCacheSize`\n * stays at the pre-append value. A concurrent `_readMessagesCached()`\n * then sees `st.size > _messageCacheSize` (the file did grow), takes\n * the incremental branch, and re-reads the just-appended tail —\n * pushing the same message onto the cache a second time. Setting the\n * trackers here closes that window for the local-process append path.\n */\n private _pushToCache(msg: MailboxMessage, mtime: number, size: number): void {\n if (this._messageCache === null) {\n // No cache to extend — leave trackers at -1 so the next read does\n // a full re-read and rebuilds the cache from disk.\n return;\n }\n if (this._messageCache.length >= MESSAGE_CACHE_MAX_ENTRIES) {\n this._messageCache = null;\n this._messageCacheMtime = -1;\n this._messageCacheSize = -1;\n return;\n }\n // The cache holds shared message objects; we mirror the on-disk line\n // by storing the same reference. Callers of `query()` get defensive\n // copies, so this shared reference is safe.\n this._messageCache.push(msg);\n // Advance the trackers synchronously with the content push so a\n // concurrent reader does not re-append this same message.\n this._messageCacheMtime = mtime;\n this._messageCacheSize = size;\n }\n\n private async _ensureRegistry(): Promise<void> {\n await fsp.mkdir(path.dirname(this.registryPath), { recursive: true });\n }\n\n private async _readRegistry(opts?: { fresh?: boolean }): Promise<Map<string, RegisteredAgent>> {\n // The registry file is shared across processes. Reads may use a short\n // TTL cache; writers (under the file lock) MUST pass { fresh: true } —\n // a read-modify-write from a stale cache would silently erase agents\n // registered by other sessions.\n if (\n !opts?.fresh &&\n this._registryCache &&\n Date.now() - this._registryCacheAt < REGISTRY_CACHE_TTL_MS\n ) {\n return new Map(this._registryCache);\n }\n\n try {\n const raw = await fsp.readFile(this.registryPath, 'utf8');\n const data = JSON.parse(raw) as Record<string, RegisteredAgent>;\n // Parse lastSeenAt strings back into objects\n const map = new Map<string, RegisteredAgent>();\n for (const [id, agent] of Object.entries(data)) {\n map.set(id, agent as RegisteredAgent);\n }\n this._registryCache = map;\n this._registryCacheAt = Date.now();\n return new Map(map);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') {\n const empty = new Map<string, RegisteredAgent>();\n this._registryCache = empty;\n this._registryCacheAt = Date.now();\n return empty;\n }\n throw err;\n }\n }\n\n private _pruneStaleInPlace(registry: Map<string, RegisteredAgent>): void {\n const staleCutoff = Date.now() - AGENT_STALE_MS;\n const purgeCutoff = Date.now() - AGENT_PURGE_MS;\n const toDelete: string[] = [];\n for (const [id, agent] of registry) {\n const lastSeen = new Date(agent.lastSeenAt).getTime();\n // Delete entries past the purge threshold entirely\n if (lastSeen < purgeCutoff) {\n toDelete.push(id);\n continue;\n }\n // Mark stale agents as idle. Online/offline is a derived view built in\n // getAgentStatuses() from lastSeenAt freshness — RegisteredAgent has no\n // `online` field, so we only normalize the persisted status here.\n if (lastSeen < staleCutoff) {\n agent.status = 'idle';\n }\n }\n for (const id of toDelete) {\n registry.delete(id);\n }\n }\n\n private async _writeRegistry(registry: Map<string, RegisteredAgent>): Promise<void> {\n const obj: Record<string, RegisteredAgent> = {};\n for (const [id, agent] of registry) {\n obj[id] = agent;\n }\n const tmp = `${this.registryPath}.${randomUUID().slice(0, 8)}.tmp`;\n await fsp.writeFile(tmp, JSON.stringify(obj), 'utf8');\n await fsp.rename(tmp, this.registryPath);\n }\n\n // ── Client registry internals ───────────────────────────────────────────\n\n private async _ensureClientRegistry(): Promise<void> {\n await fsp.mkdir(path.dirname(this.clientRegistryPath), { recursive: true });\n }\n\n private async _readClientRegistry(opts?: {\n fresh?: boolean;\n }): Promise<Map<string, RegisteredClient>> {\n if (\n !opts?.fresh &&\n this._clientRegistryCache &&\n Date.now() - this._clientRegistryCacheAt < REGISTRY_CACHE_TTL_MS\n ) {\n return new Map(this._clientRegistryCache);\n }\n\n try {\n const raw = await fsp.readFile(this.clientRegistryPath, 'utf8');\n const data = JSON.parse(raw) as Record<string, RegisteredClient>;\n const map = new Map<string, RegisteredClient>();\n for (const [id, client] of Object.entries(data)) {\n map.set(id, client as RegisteredClient);\n }\n this._clientRegistryCache = map;\n this._clientRegistryCacheAt = Date.now();\n return new Map(map);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') {\n const empty = new Map<string, RegisteredClient>();\n this._clientRegistryCache = empty;\n this._clientRegistryCacheAt = Date.now();\n return empty;\n }\n throw err;\n }\n }\n\n private _pruneStaleClientsInPlace(registry: Map<string, RegisteredClient>): void {\n const cutoff = Date.now() - CLIENT_STALE_MS;\n for (const client of registry.values()) {\n if (new Date(client.lastSeenAt).getTime() < cutoff) {\n // Mark as offline but preserve entry\n client.lastSeenAt = new Date(cutoff).toISOString();\n }\n }\n }\n\n private async _writeClientRegistry(registry: Map<string, RegisteredClient>): Promise<void> {\n const obj: Record<string, RegisteredClient> = {};\n for (const [id, client] of registry) {\n obj[id] = client;\n }\n const tmp = `${this.clientRegistryPath}.${randomUUID().slice(0, 8)}.tmp`;\n await fsp.writeFile(tmp, JSON.stringify(obj), 'utf8');\n await fsp.rename(tmp, this.clientRegistryPath);\n }\n}\n","/**\n * HQ auth-store — persistent `auth.json` for the HQ command center.\n *\n * Phase 4 scope:\n * - Operator-configured redaction policy override (applied server-side\n * even when a publisher claims rawContent:true).\n * - Browser tokens (Phase 3) + client tokens (Phase 4). Separate lists so\n * a browser-only token cannot be replayed on /ws/client and vice versa.\n * - Live reload hook: callers can `watchHqAuthFile()` to re-read on change.\n *\n * Storage layout (under the HQ data directory, default `~/.wrongstack/hq/`):\n * <dataDir>/auth.json — this file (atomic write, mode 0o600)\n * <dataDir>/events.jsonl — reserved for future persistent event log\n * <dataDir>/snapshot.json — reserved for future persisted snapshot\n *\n * The file is written atomically (tmp + rename) with mode 0o600 so a\n * shared host cannot read issued tokens or the redaction policy. Reads\n * are lenient: a missing file yields an empty document; a corrupt file\n * yields an empty document plus a warning so the operator can recover.\n *\n * @module hq/auth-store\n */\nimport { randomUUID } from 'node:crypto';\nimport * as fs from 'node:fs/promises';\nimport * as syncFs from 'node:fs';\nimport * as path from 'node:path';\n\nimport { atomicWrite } from '../utils/atomic-write.js';\nimport { wstackGlobalRoot } from '../utils/wstack-paths.js';\nimport type { HqRedactionPolicy } from './protocol.js';\n\n/** Current auth-file schema version. Bump on breaking shape changes. */\nexport const HQ_AUTH_FILE_VERSION = 1 as const;\n\n/** Default HQ data directory: `~/.wrongstack/hq` (honors WRONGSTACK_HOME). */\nexport function defaultHqDataDir(): string {\n return path.join(wstackGlobalRoot(), 'hq');\n}\n\n/**\n * Resolve an HQ data directory from an optional override.\n *\n * Resolution order:\n * 1. Explicit `override` (from `--data-dir`) — resolved against\n * `process.cwd()` if relative.\n * 2. `WRONGSTACK_HQ_DATA_DIR` env var (same resolution rules).\n * 3. `defaultHqDataDir()` — `~/.wrongstack/hq`.\n *\n * The env var exists so tests (and sandboxed runs) can redirect HQ state\n * away from the real user home without threading a CLI flag everywhere.\n */\nexport function resolveHqDataDir(override?: string, env: NodeJS.ProcessEnv = process.env): string {\n const raw = override ?? env['WRONGSTACK_HQ_DATA_DIR']?.trim();\n if (!raw) return defaultHqDataDir();\n return path.isAbsolute(raw) ? path.resolve(raw) : path.resolve(process.cwd(), raw);\n}\n\n/**\n * A generic HQ-issued token. Used for both browser tokens (validated on\n * `/ws/browser`) and client tokens (validated on `/ws/client`). The two\n * are stored in separate lists so a browser-only token cannot be replayed\n * against the client channel and vice versa.\n *\n * `capabilities` scopes what a token may do. When absent the token is\n * unrestricted (backward-compat with tokens minted before Phase 3). Known\n * capability strings:\n * - `control.enqueue` — browser token may enqueue commands to clients\n * - `control.execute` — client token may execute `run-command` commands\n * - `telemetry.publish` — client token may publish telemetry\n */\nexport interface HqToken {\n id: string;\n token: string;\n label?: string;\n createdAt: string;\n lastUsedAt?: string;\n /**\n * Optional capability scope. When absent, the token is unrestricted\n * (backward-compat). When present, only the listed capabilities are\n * granted.\n */\n capabilities?: string[];\n}\n\n/**\n * Check whether a token grants a capability. A token with no `capabilities`\n * field is unrestricted (backward-compat). Otherwise the capability must be\n * explicitly listed.\n */\nexport function tokenHasCapability(token: HqToken | undefined, capability: string): boolean {\n if (token === undefined) return false;\n if (token.capabilities === undefined) return true;\n return token.capabilities.includes(capability);\n}\n\n/**\n * Alias kept for backward-compat with Phase 3 callers/tests. New code\n * should prefer `HqToken`.\n */\nexport type HqBrowserToken = HqToken;\n\n/** On-disk shape of `<dataDir>/auth.json`. */\nexport interface HqRuntimeFile {\n url: string;\n updatedAt: string;\n pid?: number;\n}\n\nexport interface HqAuthFile {\n version: typeof HQ_AUTH_FILE_VERSION;\n updatedAt: string;\n /**\n * Operator-configured redaction policy override. When present, the HQ\n * server applies these settings AFTER any publisher-declared policy —\n * i.e. the operator can always tighten, never loosen.\n */\n redactionPolicy?: Partial<HqRedactionPolicy>;\n /** Browser tokens — validated on `/ws/browser` upgrades (Phase 3). */\n browserTokens?: HqToken[];\n /** Client tokens — validated on `/ws/client` upgrades (Phase 4). */\n clientTokens?: HqToken[];\n}\n\n/** An empty auth file — what a brand-new HQ install starts with. */\nexport function emptyHqAuthFile(): HqAuthFile {\n return {\n version: HQ_AUTH_FILE_VERSION,\n updatedAt: new Date().toISOString(),\n };\n}\n\n/** Path to `auth.json` under the given data directory. */\nexport function hqAuthFilePath(dataDir: string): string {\n return path.join(dataDir, 'auth.json');\n}\n\n/** Path to the best-effort runtime endpoint marker under the given data directory. */\nexport function hqRuntimeFilePath(dataDir: string): string {\n return path.join(dataDir, 'runtime.json');\n}\n\nexport async function writeHqRuntimeFile(dataDir: string, file: Omit<HqRuntimeFile, 'updatedAt'>): Promise<void> {\n const payload: HqRuntimeFile = {\n ...file,\n updatedAt: new Date().toISOString(),\n };\n await atomicWrite(hqRuntimeFilePath(dataDir), `${JSON.stringify(payload, null, 2)}\\n`, { mode: 0o600 });\n}\n\nfunction isProcessAlive(pid: number): boolean {\n if (!Number.isInteger(pid) || pid <= 0) return false;\n try {\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n}\n\nexport function readHqRuntimeFileSync(dataDir: string): HqRuntimeFile | undefined {\n try {\n const parsed = JSON.parse(syncFs.readFileSync(hqRuntimeFilePath(dataDir), 'utf8')) as Partial<HqRuntimeFile>;\n if (typeof parsed.url !== 'string' || parsed.url.trim().length === 0) return undefined;\n if (typeof parsed.pid === 'number' && !isProcessAlive(parsed.pid)) return undefined;\n return {\n url: parsed.url,\n updatedAt: typeof parsed.updatedAt === 'string' ? parsed.updatedAt : '',\n ...(typeof parsed.pid === 'number' ? { pid: parsed.pid } : {}),\n };\n } catch {\n return undefined;\n }\n}\n\n/**\n * Read `auth.json` from disk. Returns `emptyHqAuthFile()` when:\n * - the file does not exist (ENOENT), or\n * - the file cannot be parsed (the `warn` callback surfaces the error).\n *\n * Never throws for routine I/O — a missing or corrupt auth file should not\n * prevent the HQ server from starting. The operator can recover by editing\n * or deleting the file.\n */\nexport async function readHqAuthFile(\n dataDir: string,\n opts: { warn?: (msg: string) => void } = {},\n): Promise<HqAuthFile> {\n const file = hqAuthFilePath(dataDir);\n let raw: string;\n try {\n raw = await fs.readFile(file, 'utf8');\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return emptyHqAuthFile();\n // Non-ENOENT (EACCES, EIO, …) — surface but don't crash startup.\n opts.warn?.(`HQ auth file read failed at ${file}: ${(err as Error).message}`);\n return emptyHqAuthFile();\n }\n try {\n const parsed = JSON.parse(raw) as HqAuthFile;\n if (parsed.version !== HQ_AUTH_FILE_VERSION) {\n opts.warn?.(\n `HQ auth file at ${file} has unsupported version ${String(parsed.version)} (expected ${String(HQ_AUTH_FILE_VERSION)}); ignoring stored policy/tokens.`,\n );\n return emptyHqAuthFile();\n }\n return parsed;\n } catch (err) {\n opts.warn?.(`HQ auth file at ${file} is not valid JSON; ignoring stored policy/tokens: ${(err as Error).message}`);\n return emptyHqAuthFile();\n }\n}\n\n/**\n * Write `auth.json` atomically with mode 0o600. Creates the data directory\n * if needed. Throws on I/O failure — callers (CLI commands) should surface\n * the error to the operator.\n */\nexport async function writeHqAuthFile(dataDir: string, file: HqAuthFile): Promise<void> {\n const target = hqAuthFilePath(dataDir);\n const payload: HqAuthFile = {\n ...file,\n version: HQ_AUTH_FILE_VERSION,\n updatedAt: new Date().toISOString(),\n };\n await atomicWrite(target, `${JSON.stringify(payload, null, 2)}\\n`, { mode: 0o600 });\n}\n\nexport interface EnsureHqFirstRunAuthResult {\n authFile: HqAuthFile;\n created: boolean;\n browserToken?: HqToken;\n clientToken?: HqToken;\n}\n\n/**\n * Ensure a brand-new HQ data directory has the auth required for safe\n * first-run operation. Only a missing auth.json is bootstrapped; an existing\n * file, including one with empty token arrays, is treated as operator intent.\n */\nexport async function ensureHqFirstRunAuthFile(\n dataDir: string,\n opts: { warn?: (msg: string) => void } = {},\n): Promise<EnsureHqFirstRunAuthResult> {\n const file = hqAuthFilePath(dataDir);\n try {\n await fs.access(file);\n return { authFile: await readHqAuthFile(dataDir, opts), created: false };\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT') {\n opts.warn?.(`HQ auth file access failed at ${file}: ${(err as Error).message}`);\n return { authFile: await readHqAuthFile(dataDir, opts), created: false };\n }\n }\n\n const browserToken = mintHqToken('first-run browser');\n const clientToken = mintHqToken('first-run client');\n const authFile: HqAuthFile = {\n version: HQ_AUTH_FILE_VERSION,\n updatedAt: new Date().toISOString(),\n browserTokens: [browserToken],\n clientTokens: [clientToken],\n };\n await writeHqAuthFile(dataDir, authFile);\n return { authFile: await readHqAuthFile(dataDir, opts), created: true, browserToken, clientToken };\n}\n\n/**\n * Load → mutate → write. The mutator receives the current file (or an empty\n * one) and returns the next file. Use this for any read-modify-write cycle\n * to avoid clobbering concurrent edits from another CLI invocation.\n *\n * Note: this does NOT take a file lock. HQ auth edits are rare (operator\n * running `wstack --hq-token add` etc.) and the atomic rename protects\n * against torn writes; a race between two concurrent edits would be\n * last-write-wins, which is acceptable for this low-frequency file.\n */\nexport async function mutateHqAuthFile(\n dataDir: string,\n mutator: (current: HqAuthFile) => HqAuthFile | Promise<HqAuthFile>,\n opts: { warn?: (msg: string) => void } = {},\n): Promise<HqAuthFile> {\n const current = await readHqAuthFile(dataDir, opts);\n const next = await mutator(current);\n await writeHqAuthFile(dataDir, next);\n return next;\n}\n\n/**\n * Mint a fresh token. Used for both browser and client tokens; the caller\n * decides which list to append to.\n */\nexport function mintHqToken(label?: string): HqToken {\n const now = new Date().toISOString();\n return {\n id: randomUUID(),\n token: randomUUID().replace(/-/g, '') + randomUUID().replace(/-/g, ''),\n ...(label ? { label } : {}),\n createdAt: now,\n };\n}\n\n/**\n * Backward-compat alias for `mintHqToken`. Phase 3 callers/tests use this.\n */\nexport const mintHqBrowserToken = mintHqToken;\n\n/**\n * Watch `auth.json` for changes and invoke `onChange` with the freshly-read\n * file. Returns a `close()` function that stops watching.\n *\n * The watcher debounces events (default 200ms) because most editors do a\n * tmp+rename dance that emits multiple events. On any read failure (file\n * deleted, corrupt, etc.) the `warn` callback is invoked with the same\n * semantics as `readHqAuthFile`; the watcher stays active so a future\n * valid write re-triggers the callback.\n *\n * Notes:\n * - `fs.watch` is best-effort across platforms. On some network\n * filesystems events may not fire; the operator must restart the server\n * to pick up changes in that case.\n * - The watcher polls the parent directory (not the file itself) so that\n * atomic rename events surface reliably.\n */\nexport function watchHqAuthFile(\n dataDir: string,\n onChange: (file: HqAuthFile) => void,\n opts: { warn?: (msg: string) => void; debounceMs?: number } = {},\n): { close: () => void } {\n const file = hqAuthFilePath(dataDir);\n const debounceMs = opts.debounceMs ?? 200;\n let timer: ReturnType<typeof setTimeout> | undefined;\n let closed = false;\n\n let watcher: syncFs.FSWatcher;\n try {\n // Watch the directory (not the file) so atomic-rename events surface\n // reliably. `fs.watch` is best-effort across platforms — on some\n // network filesystems events may not fire; the operator must restart\n // the server in that case.\n watcher = syncFs.watch(path.dirname(file), { recursive: false });\n } catch (err) {\n opts.warn?.(`HQ auth watcher could not start: ${(err as Error).message}`);\n return { close: () => {} };\n }\n\n const trigger = (): void => {\n if (closed) return;\n if (timer) clearTimeout(timer);\n timer = setTimeout(() => {\n timer = undefined;\n const readOpts = opts.warn ? { warn: opts.warn } : {};\n void readHqAuthFile(dataDir, readOpts).then(\n (next) => {\n if (!closed) onChange(next);\n },\n () => {\n // readHqAuthFile never throws for routine I/O — this is a\n // belt-and-braces guard.\n },\n );\n }, debounceMs);\n };\n\n watcher.on('change', (eventType: string, filename: string | Buffer | null) => {\n const name = typeof filename === 'string' ? filename : '';\n // Only react to events that touch auth.json (rename, change).\n if (eventType === 'rename' || eventType === 'change') {\n if (!name || name === 'auth.json' || name === path.basename(file)) {\n trigger();\n }\n }\n });\n\n watcher.on('error', (err: Error) => {\n opts.warn?.(`HQ auth watcher error: ${err.message}`);\n });\n\n return {\n close: () => {\n closed = true;\n if (timer) clearTimeout(timer);\n watcher.close();\n },\n };\n}\n","import { createHash } from 'node:crypto';\nimport * as fs from 'node:fs';\nimport { hostname } from 'node:os';\nimport { basename } from 'node:path';\nimport { GlobalMailbox } from '../coordination/global-mailbox.js';\nimport type { EventBus } from '../kernel/events.js';\nimport type { HqClientConfig } from '../types/config.js';\nimport { hqAuthFilePath, readHqRuntimeFileSync, resolveHqDataDir, type HqAuthFile } from './auth-store.js';\nimport type { HqClientCapability, HqClientIdentity, HqProjectIdentity, HqRedactionPolicy } from './protocol.js';\nimport { HqPublisher, type HqPublisherCommandHandler, type HqSocketFactory } from './publisher.js';\n\nexport interface HqPublisherEnvConfig {\n url: string;\n token?: string;\n enabled?: boolean;\n rawContent?: boolean;\n projectAlias?: string;\n /**\n * Same-machine auto-discovery mode: no explicit URL was configured, so the\n * publisher should re-resolve the endpoint from `<dataDir>/runtime.json`\n * (+ the first client token in `auth.json`) before every connect attempt.\n * This lets every client on the machine attach to a `wstack --hq` that is\n * already running, starts later, or restarts on a different port.\n */\n discover?: boolean;\n /** Resolved HQ data dir the discovery reads from. */\n dataDir?: string;\n}\n\n/**\n * Discover a locally running `wstack --hq` endpoint: reads the runtime\n * marker (pid-liveness-checked) and the first client token. Returns\n * `undefined` when no live HQ is advertised on this machine.\n */\nexport function discoverLocalHqEndpoint(options: {\n dataDir?: string | undefined;\n env?: NodeJS.ProcessEnv | undefined;\n} = {}): { url: string; token?: string | undefined } | undefined {\n const dataDir = resolveHqDataDir(options.dataDir, options.env ?? process.env);\n const runtime = readHqRuntimeFileSync(dataDir);\n if (runtime === undefined) return undefined;\n const token = readFirstClientTokenFromAuthFile(dataDir);\n return { url: runtime.url, ...(token ? { token } : {}) };\n}\n\nfunction readFirstClientTokenFromAuthFile(dataDir: string): string | undefined {\n try {\n const raw = fs.readFileSync(hqAuthFilePath(dataDir), 'utf8');\n const parsed = JSON.parse(raw) as HqAuthFile;\n return parsed.clientTokens?.find((t) => t.token.trim().length > 0)?.token;\n } catch {\n return undefined;\n }\n}\n\n/**\n * True when an explicit HQ URL targets this machine. Falling back to the\n * LOCAL auth.json client token is only valid for same-machine servers — a\n * remote HQ has its own auth.json, and sending the local token would put the\n * publisher into a silent 401 reconnect loop.\n */\nfunction isLoopbackHqUrl(url: string): boolean {\n try {\n const host = new URL(url).hostname.toLowerCase();\n return host === '127.0.0.1' || host === 'localhost' || host === '::1' || host === '[::1]' || host === '0.0.0.0';\n } catch {\n return false;\n }\n}\n\nexport function resolveHqConfigFromEnv(env: NodeJS.ProcessEnv = process.env): HqPublisherEnvConfig | undefined {\n return resolveHqConfig({ env });\n}\n\nexport function resolveHqConfig(options: {\n env?: NodeJS.ProcessEnv | undefined;\n config?: HqClientConfig | undefined;\n} = {}): HqPublisherEnvConfig | undefined {\n const env = options.env ?? process.env;\n const fileConfig = options.config;\n const envUrl = env['WRONGSTACK_HQ_URL']?.trim();\n const envToken = env['WRONGSTACK_HQ_TOKEN']?.trim();\n const configUrl = fileConfig?.url?.trim();\n const configToken = fileConfig?.token?.trim();\n const envEnabledRaw = env['WRONGSTACK_HQ_ENABLED']?.trim();\n const enabled = envEnabledRaw !== undefined && envEnabledRaw.length > 0\n ? envEnabledRaw !== '0'\n : fileConfig?.enabled;\n const dataDir = resolveHqDataDir(fileConfig?.dataDir, env);\n const explicitToken = envToken || configToken;\n const runtimeUrl = readHqRuntimeFileSync(dataDir)?.url.trim();\n const url = envUrl || configUrl;\n // The local auth.json client token is only a valid fallback for\n // same-machine endpoints (discovery, or an explicit loopback URL). For a\n // remote URL without an explicit token, send NO token — the server's 401\n // is then an honest signal instead of a guaranteed-wrong local token.\n const localFallbackToken =\n !url || isLoopbackHqUrl(url) ? readFirstClientTokenFromAuthFile(dataDir) : undefined;\n const token = explicitToken || localFallbackToken;\n\n if (!url) {\n if (enabled === false) return undefined;\n // No explicit endpoint → same-machine auto-discovery (default ON).\n // The publisher re-resolves runtime.json + auth.json before every\n // connect attempt, so an HQ started AFTER this client — or restarted on\n // another port — is attached to automatically. While no HQ is running\n // the publisher stays dormant (bounded queue, cheap file poll).\n // Opt out with WRONGSTACK_HQ_ENABLED=0 or config `hq.enabled: false`.\n return {\n url: runtimeUrl || 'http://127.0.0.1:3499',\n enabled: true,\n discover: true,\n dataDir,\n ...(token ? { token } : {}),\n };\n }\n\n const rawContentEnv = env['WRONGSTACK_HQ_RAW_CONTENT']?.trim();\n const projectAliasEnv = env['WRONGSTACK_HQ_PROJECT_ALIAS']?.trim();\n return {\n url,\n ...(token ? { token } : {}),\n ...(enabled !== undefined ? { enabled } : {}),\n ...(rawContentEnv ? { rawContent: rawContentEnv === '1' } : fileConfig?.rawContent !== undefined ? { rawContent: fileConfig.rawContent } : {}),\n ...(projectAliasEnv ? { projectAlias: projectAliasEnv } : fileConfig?.projectAlias ? { projectAlias: fileConfig.projectAlias } : {}),\n };\n}\n\nfunction stableMachineId(): string {\n // Stable per *physical machine*, NOT per process — every terminal on the\n // same computer must share one machineId so HQ groups them under a single\n // machine node. (Process identity already lives in clientId via the pid.)\n return createHash('sha256').update(hostname()).digest('hex').slice(0, 12);\n}\n\nfunction deriveProjectId(projectRoot: string): string {\n return createHash('sha256').update(projectRoot).digest('hex').slice(0, 12);\n}\n\nexport interface CreateHqPublisherOptions {\n clientKind: HqClientIdentity['kind'];\n projectRoot: string;\n projectName?: string;\n machineId?: string;\n hostnameOverride?: string;\n socketFactory?: HqSocketFactory;\n config?: HqPublisherEnvConfig;\n appConfig?: { hq?: HqClientConfig | undefined } | undefined;\n redactionPolicy?: Partial<HqRedactionPolicy>;\n /** Forwarded to the HqPublisher constructor (Phase 4 control plane). */\n capabilities?: readonly HqClientCapability[];\n /** Forwarded to the HqPublisher constructor (Phase 4 control plane). */\n onCommand?: HqPublisherCommandHandler;\n /** Dormant discovery re-check interval override (tests / tight loops). */\n discoveryPollMs?: number;\n}\n\nexport function createHqPublisherFromEnv(options: CreateHqPublisherOptions): HqPublisher | undefined {\n const config = options.config ?? resolveHqConfig({ config: options.appConfig?.hq });\n if (!config || config.enabled === false) return undefined;\n\n const machineId = options.machineId ?? stableMachineId();\n const host = options.hostnameOverride ?? hostname();\n const projectName = options.projectName ?? config.projectAlias ?? (basename(options.projectRoot) || 'unknown');\n\n const client: HqClientIdentity = {\n clientId: `${machineId}:${options.clientKind}:${process.pid}`,\n kind: options.clientKind,\n machineId,\n ...(host ? { hostname: host } : {}),\n pid: process.pid,\n startedAt: new Date().toISOString(),\n };\n\n const project: HqProjectIdentity = {\n projectId: deriveProjectId(options.projectRoot),\n projectRoot: options.projectRoot,\n projectName,\n machineId,\n workspaceKind: 'git',\n };\n\n const redactionPolicy: Partial<HqRedactionPolicy> | undefined =\n options.redactionPolicy || config.rawContent !== undefined\n ? {\n ...(config.rawContent !== undefined ? { rawContent: config.rawContent } : {}),\n ...(options.redactionPolicy ?? {}),\n }\n : undefined;\n\n const discoveryDataDir = config.dataDir;\n return new HqPublisher({\n url: config.url,\n ...(config.token ? { token: config.token } : {}),\n client,\n project,\n ...(options.socketFactory ? { socketFactory: options.socketFactory } : {}),\n ...(redactionPolicy !== undefined ? { redactionPolicy } : {}),\n ...(options.capabilities !== undefined ? { capabilities: options.capabilities } : {}),\n ...(options.onCommand !== undefined ? { onCommand: options.onCommand } : {}),\n // Auto-discovery: re-read the local HQ runtime marker + client token on\n // every connect attempt so late-started/restarted HQs are picked up.\n ...(config.discover\n ? { resolveEndpoint: () => discoverLocalHqEndpoint({ dataDir: discoveryDataDir }) }\n : {}),\n ...(options.discoveryPollMs !== undefined ? { discoveryPollMs: options.discoveryPollMs } : {}),\n });\n}\n\nexport interface CreateGlobalMailboxOptions {\n projectDir: string;\n events?: EventBus;\n hqPublisher?: HqPublisher;\n}\n\nexport function createGlobalMailbox(options: CreateGlobalMailboxOptions): GlobalMailbox {\n return new GlobalMailbox(options.projectDir, options.events, options.hqPublisher);\n}\n","/**\n * AgentMonitorEventBridge — forwards local agent timeline and status events\n * to the HQ publisher as structured HQ event envelopes, so the HQ browser\n * dashboard sees real-time agent conversation streams.\n */\nimport type { EventBus } from '../kernel/events.js';\nimport { createHqEventEnvelope, type HqAgentMessagePayload, type HqAgentStatusPayload, type HqEventEnvelope } from './protocol.js';\n\nexport type HqAgentEventPublisher = (envelope: HqEventEnvelope) => void;\n\nexport interface AgentMonitorEventBridgeOptions {\n /** Local EventBus emitting agent.timeline.* and agent.status_changed events. */\n events: EventBus;\n /** Client/project identifiers for HQ envelope authorship. */\n clientId: string;\n projectId: string;\n /**\n * Publish callback — called with each HQ event envelope. Wire this to\n * your HQ publisher's `send()` or queue method when connected.\n * When null (no HQ connection), events are silently dropped.\n */\n publish?: HqAgentEventPublisher | undefined;\n}\n\n/**\n * Start forwarding agent monitoring events to HQ. Returns a disposer that\n * unsubscribes all listeners — call on shutdown.\n */\nexport function startAgentMonitorEventBridge(opts: AgentMonitorEventBridgeOptions): () => void {\n const { events, clientId, projectId, publish } = opts;\n const seq = { current: 0 };\n\n function nextSeq(): number {\n seq.current += 1;\n return seq.current;\n }\n\n function buildEnvelope<T>(type: string, payload: T, sessionId?: string): HqEventEnvelope<T> {\n return createHqEventEnvelope({\n id: `${Date.now().toString(36)}-${nextSeq()}`,\n type: type as never,\n timestamp: new Date().toISOString(),\n clientId,\n projectId,\n seq: nextSeq(),\n payload,\n // Carry the parent session id so HQ can scope per-agent transcripts by\n // (sessionId, subagentId) — without it, two sessions whose leaders both\n // use the default id 'leader' would collide into one shared ring.\n ...(sessionId !== undefined ? { sessionId } : {}),\n }) as HqEventEnvelope<T>;\n }\n\n const offMessage = events.on('agent.timeline.message', (payload) => {\n if (!publish) return;\n const msgPayload: HqAgentMessagePayload = {\n subagentId: payload.subagentId,\n agentName: payload.agentName,\n content: payload.content,\n kind: payload.kind,\n iteration: payload.iteration,\n ts: payload.ts,\n };\n if (payload.toolName !== undefined) msgPayload.toolName = payload.toolName;\n if (payload.costUsd !== undefined) msgPayload.costUsd = payload.costUsd;\n publish(buildEnvelope('agent.message', msgPayload, payload.sessionId));\n });\n\n const offStatus = events.on('agent.status_changed', (payload) => {\n if (!publish) return;\n const statusPayload: HqAgentStatusPayload = {\n subagentId: payload.subagentId,\n agentName: payload.agentName,\n status: payload.status,\n ts: payload.ts,\n };\n if (payload.summary !== undefined) statusPayload.summary = payload.summary;\n if (payload.task !== undefined) statusPayload.task = payload.task;\n publish(buildEnvelope('agent.status', statusPayload));\n });\n\n return () => {\n offMessage();\n offStatus();\n };\n}\n","/**\n * Transcript mapper — converts raw session JSONL events into the canonical\n * {@link HqTranscriptEntry} shape used by HQ for full chat-history rendering.\n *\n * On-disk reality (see `types/session.ts` + `core/agent-tools.ts`):\n * - A tool CALL (with its arguments) is NOT a standalone event — it is a\n * `tool_use` content block inside the assistant's `llm_response`.\n * - The tool RESULT is a separate `tool_result` event carrying the matching\n * `id`.\n * So we extract each `tool_use` block as a tool entry (args) at the assistant's\n * position, then merge the later `tool_result` (matched by `id`) INTO that same\n * entry — giving one box per tool (args + result) in strict chronological order.\n *\n * @module hq/transcript-mapper\n */\nimport type { HqTranscriptEntry, HqTranscriptRole } from './protocol.js';\n\nfunction blocksToText(content: unknown): string {\n if (typeof content === 'string') return content;\n if (Array.isArray(content)) {\n return content\n .filter(\n (b): b is { type: string; text: string } =>\n !!b &&\n typeof b === 'object' &&\n (b as { type?: unknown }).type === 'text' &&\n typeof (b as { text?: unknown }).text === 'string',\n )\n .map((b) => b.text)\n .join('\\n');\n }\n return '';\n}\n\nfunction asString(v: unknown): string {\n if (typeof v === 'string') return v;\n try {\n return JSON.stringify(v, null, 2);\n } catch {\n return String(v);\n }\n}\n\nfunction argsEntry(ts: string, name: unknown, input: unknown, id: unknown): HqTranscriptEntry {\n return {\n ts,\n role: 'tool',\n tool: String(name ?? 'tool'),\n toolInput: input !== undefined && input !== null ? asString(input) : '{}',\n text: '',\n ...(typeof id === 'string' ? { toolUseId: id } : {}),\n };\n}\n\n/**\n * Map a single raw JSONL session event to zero or more transcript entries.\n * An `llm_response` can yield an assistant text entry PLUS one tool entry per\n * embedded `tool_use` block.\n */\nexport function mapSessionEventToEntries(ev: Record<string, unknown>): HqTranscriptEntry[] {\n const ts = typeof ev['ts'] === 'string' ? (ev['ts'] as string) : '';\n const make = (\n role: HqTranscriptRole,\n text: string,\n extra?: Partial<HqTranscriptEntry>,\n ): HqTranscriptEntry => ({\n ts,\n role,\n text,\n ...extra,\n });\n\n switch (ev['type']) {\n case 'user_input': {\n const t = blocksToText(ev['content']);\n return t.trim() ? [make('user', t)] : [];\n }\n case 'llm_response': {\n const out: HqTranscriptEntry[] = [];\n const content = ev['content'];\n // Thinking blocks precede text/tool_use in an assistant message (provider\n // contract) — surface them first so the transcript preserves that order.\n if (Array.isArray(content)) {\n const thinking = content\n .filter(\n (b): b is { type: string; thinking: string } =>\n !!b &&\n typeof b === 'object' &&\n (b as { type?: unknown }).type === 'thinking' &&\n typeof (b as { thinking?: unknown }).thinking === 'string',\n )\n .map((b) => b.thinking)\n .join('\\n');\n if (thinking.trim()) out.push(make('thinking', thinking));\n }\n const t = blocksToText(content);\n if (t.trim()) out.push(make('assistant', t));\n if (Array.isArray(content)) {\n for (const b of content) {\n if (b && typeof b === 'object' && (b as { type?: unknown }).type === 'tool_use') {\n const block = b as { id?: unknown; name?: unknown; input?: unknown };\n out.push(argsEntry(ts, block.name, block.input, block.id));\n }\n }\n }\n return out;\n }\n case 'tool_use':\n return [argsEntry(ts, ev['name'], ev['input'], ev['id'])];\n case 'tool_call_start':\n return [argsEntry(ts, ev['name'], ev['input'] ?? ev['args'], ev['id'])];\n case 'tool_result': {\n const isError = ev['isError'] === true;\n const content = ev['content'] ?? ev['output'];\n const outStr = content !== undefined && content !== null ? asString(content) : '';\n return [\n make(isError ? 'error' : 'tool', outStr, {\n tool: '↳ result',\n ...(isError ? { isError: true } : {}),\n ...(typeof ev['id'] === 'string' ? { toolUseId: ev['id'] } : {}),\n }),\n ];\n }\n case 'tool_call_end': {\n const isError = ev['isError'] === true;\n const content = ev['output'] ?? ev['content'];\n const outStr = content !== undefined && content !== null ? asString(content) : '';\n if (!outStr.trim() && !isError && typeof ev['durationMs'] !== 'number') return [];\n return [\n make(isError ? 'error' : 'tool', outStr, {\n tool: typeof ev['name'] === 'string' ? String(ev['name']) : '↳ result',\n ...(typeof ev['durationMs'] === 'number' ? { durationMs: ev['durationMs'] } : {}),\n ...(isError ? { isError: true } : {}),\n ...(typeof ev['id'] === 'string' ? { toolUseId: ev['id'] } : {}),\n }),\n ];\n }\n case 'error':\n case 'provider_error':\n return [make('error', String(ev['message'] ?? 'error'))];\n case 'agent_spawned':\n return [make('system', `spawned ${String(ev['role'] ?? 'agent')}`)];\n case 'task_completed':\n return [make('system', `task done: ${String(ev['title'] ?? '')}`)];\n case 'task_failed':\n return [make('system', `task failed: ${String(ev['title'] ?? '')}`)];\n default:\n return [];\n }\n}\n\n/**\n * Identify a \"result\" entry — a tool/error entry that carries a tool-use id but\n * no args (it's the output half of a tool call, to be merged into the args\n * half).\n */\nfunction isResultEntry(e: HqTranscriptEntry): boolean {\n return (\n (e.role === 'tool' || e.role === 'error') &&\n e.toolUseId !== undefined &&\n e.toolInput === undefined\n );\n}\n\n/**\n * Merge each tool result into its matching args entry (by `toolUseId`),\n * keeping the args entry's chronological position. Results with no matching\n * args entry are kept as their own entries. Mutates/keeps order; pure w.r.t.\n * input ordering.\n */\nexport function mergeToolResults(flat: readonly HqTranscriptEntry[]): HqTranscriptEntry[] {\n const out: HqTranscriptEntry[] = [];\n const argsById = new Map<string, HqTranscriptEntry>();\n for (const src of flat) {\n const e: HqTranscriptEntry = { ...src };\n if (isResultEntry(e) && e.toolUseId !== undefined) {\n const tgt = argsById.get(e.toolUseId);\n if (tgt) {\n tgt.text = e.text || '';\n if (e.durationMs !== undefined) tgt.durationMs = e.durationMs;\n if (e.isError) {\n tgt.role = 'error';\n tgt.isError = true;\n }\n continue; // merged into the existing args box — no new entry\n }\n }\n out.push(e);\n if (e.role === 'tool' && e.toolUseId !== undefined && e.toolInput !== undefined) {\n argsById.set(e.toolUseId, e);\n }\n }\n return out;\n}\n\n/**\n * Map + merge an array of raw JSONL events into the final transcript-entry\n * list: strict chronological order, with each tool's args and result combined\n * into a single entry.\n */\nexport function buildTranscriptFromEvents(\n events: Iterable<Record<string, unknown>>,\n): HqTranscriptEntry[] {\n const flat: HqTranscriptEntry[] = [];\n for (const ev of events) {\n for (const e of mapSessionEventToEntries(ev)) flat.push(e);\n }\n return mergeToolResults(flat);\n}\n","/**\n * SessionTelemetryBridge — streams a surface's own live session state and full\n * chat transcript to HQ over the `/ws/client` plane, so the command center can\n * render every machine → terminal → agent → full-history across all connected\n * machines (not only the one HQ runs on).\n *\n * Two streams, both best-effort and self-contained:\n * 1. `session.snapshot` — the terminal's live state + agents, sourced from the\n * in-process `session.agents_updated` bus event (no registry file reads).\n * 2. `session.transcript` — incremental conversation turns, tailed cheaply\n * from this process's own session JSONL by byte offset.\n *\n * @module hq/session-bridge\n */\nimport * as fs from 'node:fs';\nimport * as fsp from 'node:fs/promises';\nimport type { EventBus, TrackedAgentSnapshot } from '../kernel/events.js';\nimport { sessionScopedPath } from '../utils/session-scoped-path.js';\nimport { resolveWstackPaths } from '../utils/wstack-paths.js';\nimport type {\n HqSessionAgentLiveStatus,\n HqSessionAgentSummary,\n HqSessionLiveStatus,\n HqSessionSnapshotPayload,\n HqTranscriptEntry,\n} from './protocol.js';\nimport type { HqPublisher } from './publisher.js';\nimport { mapSessionEventToEntries } from './transcript-mapper.js';\n\nexport interface SessionTelemetryBridgeOptions {\n publisher: HqPublisher;\n /** Local bus carrying `session.agents_updated`. When omitted, snapshots\n * still publish (with empty/last-known agents) and the transcript still\n * streams from disk. */\n events?: EventBus | undefined;\n sessionId: string;\n projectRoot: string;\n projectName?: string | undefined;\n /** Override the global root used to resolve the session JSONL path. */\n globalRoot?: string | undefined;\n /** Last-known agents to publish immediately before the next bus update. */\n initialAgents?: readonly TrackedAgentSnapshot[] | undefined;\n gitBranch?: string | undefined;\n startedAt?: string | undefined;\n /** Snapshot republish interval (also refreshes lastActivity). Default 2500ms. */\n snapshotIntervalMs?: number | undefined;\n /** Transcript tail poll interval. Default 1200ms. */\n transcriptIntervalMs?: number | undefined;\n now?: (() => string) | undefined;\n}\n\nconst VALID_AGENT_STATUS = new Set<HqSessionAgentLiveStatus>([\n 'idle',\n 'running',\n 'streaming',\n 'waiting_user',\n 'error',\n]);\n\nfunction toAgentSummary(a: TrackedAgentSnapshot): HqSessionAgentSummary {\n const status = (\n VALID_AGENT_STATUS.has(a.status as HqSessionAgentLiveStatus) ? a.status : 'idle'\n ) as HqSessionAgentLiveStatus;\n return {\n id: a.id,\n name: a.name,\n status,\n iterations: a.iterations,\n toolCalls: a.toolCalls,\n lastActivityAt: a.lastActivityAt,\n ...(a.startedAt !== undefined ? { startedAt: a.startedAt } : {}),\n ...(a.currentTool !== undefined ? { currentTool: a.currentTool } : {}),\n ...(a.costUsd !== undefined ? { costUsd: a.costUsd } : {}),\n ...(a.tokensIn !== undefined ? { tokensIn: a.tokensIn } : {}),\n ...(a.tokensOut !== undefined ? { tokensOut: a.tokensOut } : {}),\n ...(a.ctxPct !== undefined ? { ctxPct: a.ctxPct } : {}),\n ...(a.model !== undefined ? { model: a.model } : {}),\n ...(a.partialText !== undefined ? { partialText: a.partialText } : {}),\n };\n}\n\nfunction deriveSessionStatus(agents: readonly HqSessionAgentSummary[]): HqSessionLiveStatus {\n return agents.some(\n (a) => a.status === 'running' || a.status === 'streaming' || a.status === 'waiting_user',\n )\n ? 'active'\n : 'idle';\n}\n\n/**\n * Start streaming this surface's session telemetry to HQ. Returns a disposer\n * that stops both streams and publishes a final `session.ended`.\n */\nexport function startSessionTelemetryBridge(opts: SessionTelemetryBridgeOptions): () => void {\n const now = opts.now ?? (() => new Date().toISOString());\n const publisher = opts.publisher;\n const identity = publisher.identity;\n const project = publisher.project;\n const startedAt = opts.startedAt ?? now();\n\n const wpaths = resolveWstackPaths({\n projectRoot: opts.projectRoot,\n ...(opts.globalRoot !== undefined ? { globalRoot: opts.globalRoot } : {}),\n });\n const sessionFile = sessionScopedPath(wpaths.projectSessions, opts.sessionId, '.jsonl');\n\n let agents: HqSessionAgentSummary[] = (opts.initialAgents ?? []).map(toAgentSummary);\n let lastActivityAt = agents.reduce(\n (latest, agent) => agent.lastActivityAt > latest ? agent.lastActivityAt : latest,\n startedAt,\n );\n let lastSnapshotHash = '';\n let disposed = false;\n\n function buildSnapshot(): HqSessionSnapshotPayload {\n return {\n sessionId: opts.sessionId,\n clientKind: identity.kind,\n machineId: identity.machineId,\n projectId: project.projectId,\n projectName: opts.projectName ?? project.projectName,\n projectRoot: opts.projectRoot,\n status: deriveSessionStatus(agents),\n startedAt,\n lastActivityAt,\n agentCount: agents.length,\n agents,\n ...(identity.hostname !== undefined ? { hostname: identity.hostname } : {}),\n ...(identity.pid !== undefined ? { pid: identity.pid } : {}),\n ...(opts.gitBranch !== undefined ? { gitBranch: opts.gitBranch } : {}),\n };\n }\n\n function publishSnapshot(force = false): void {\n if (disposed) return;\n const snap = buildSnapshot();\n // Hash on everything except lastActivityAt so identical state isn't\n // republished by the heartbeat tick, but real changes always go out.\n const hash = JSON.stringify({ ...snap, lastActivityAt: '' });\n if (!force && hash === lastSnapshotHash) return;\n lastSnapshotHash = hash;\n try {\n publisher.publishSessionSnapshot(snap);\n } catch {\n /* best-effort */\n }\n }\n\n const offAgents = opts.events?.on('session.agents_updated', (payload) => {\n agents = payload.agents.map(toAgentSummary);\n lastActivityAt = now();\n publishSnapshot();\n });\n\n // Announce the terminal immediately so its node appears even before any\n // agent activity.\n publishSnapshot(true);\n\n // ── Transcript tail ───────────────────────────────────────────────────────\n let offset = 0;\n let partial = '';\n let seqEmitted = 0;\n let tailing = false;\n let watcher: fs.FSWatcher | null = null;\n let watchPending = false;\n\n // Once the session file exists, watch it so new turns are streamed within\n // milliseconds of being written — the interval poll is only a safety net.\n function setupWatcher(): void {\n if (disposed || watcher) return;\n try {\n const nextWatcher = fs.watch(sessionFile, () => {\n if (watchPending || disposed) return;\n watchPending = true;\n setTimeout(() => {\n watchPending = false;\n void tail();\n }, 25);\n });\n // fs.watch surfaces transient failures (EPERM/ENOENT on rename/delete,\n // common on Windows) as async 'error' events — swallow them so they\n // never become uncaught exceptions. The interval poll keeps us live.\n nextWatcher.on('error', () => {\n try {\n nextWatcher.close();\n } catch {\n /* ignore */\n }\n if (watcher === nextWatcher) watcher = null;\n });\n watcher = nextWatcher;\n } catch {\n watcher = null;\n }\n }\n\n async function tail(): Promise<void> {\n if (disposed || tailing) return;\n tailing = true;\n try {\n const stat = await fsp.stat(sessionFile).catch(() => null);\n if (disposed) return;\n if (!stat) return;\n setupWatcher();\n if (stat.size <= offset) return;\n const fd = await fsp.open(sessionFile, 'r');\n try {\n if (disposed) return;\n const len = stat.size - offset;\n const buf = Buffer.allocUnsafe(len);\n await fd.read(buf, 0, len, offset);\n offset = stat.size;\n partial += buf.toString('utf8');\n const lines = partial.split('\\n');\n partial = lines.pop() ?? '';\n const entries: HqTranscriptEntry[] = [];\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n let obj: Record<string, unknown>;\n try {\n obj = JSON.parse(trimmed) as Record<string, unknown>;\n } catch {\n continue;\n }\n for (const entry of mapSessionEventToEntries(obj)) entries.push(entry);\n }\n if (entries.length > 0) {\n try {\n publisher.publishTranscriptAppend({\n sessionId: opts.sessionId,\n fromSeq: seqEmitted,\n entries,\n });\n } catch {\n /* best-effort */\n }\n seqEmitted += entries.length;\n lastActivityAt = now();\n }\n } finally {\n await fd.close();\n }\n } catch {\n /* best-effort */\n } finally {\n tailing = false;\n }\n }\n\n const snapshotTimer = setInterval(() => publishSnapshot(true), opts.snapshotIntervalMs ?? 2500);\n const tailTimer = setInterval(() => void tail(), opts.transcriptIntervalMs ?? 500);\n snapshotTimer.unref?.();\n tailTimer.unref?.();\n void tail();\n\n return () => {\n if (disposed) return;\n disposed = true;\n offAgents?.();\n if (watcher) {\n try {\n watcher.close();\n } catch {\n /* ignore */\n }\n watcher = null;\n }\n clearInterval(snapshotTimer);\n clearInterval(tailTimer);\n try {\n publisher.publishSessionEnded({ sessionId: opts.sessionId, endedAt: now() });\n } catch {\n /* best-effort */\n }\n };\n}\n","/**\n * FleetTelemetryBridge — forwards local multi-agent coordinator stats to the\n * HQ publisher as `fleet.snapshot` envelopes, so the command center can render\n * a global fleet roll-up (queued/completed/failed tasks, per-subagent status,\n * fleet cost) across every connected machine.\n *\n * Source: the `coordinator.stats` EventBus event (originating on the FleetBus\n * and re-emitted onto the host EventBus by `fleet/host.ts`). All payload\n * fields are plain serializable data — no closures, no decoupled relay needed.\n *\n * The snapshot is republished on every `coordinator.stats` change (hash-dedup,\n * mirroring {@link startSessionTelemetryBridge}) so the HQ browser sees live\n * fleet counters without polling.\n *\n * @module hq/fleet-bridge\n */\nimport type { EventBus } from '../kernel/events.js';\nimport type { HqEventEnvelope, HqFleetSnapshotPayload, HqSubagentSummary } from './protocol.js';\nimport type { HqPublisher } from './publisher.js';\n\nexport interface FleetTelemetryBridgeOptions {\n /** Local EventBus emitting `coordinator.stats` (host EventBus after the FleetBus hop). */\n events: EventBus;\n /** HQ publisher to forward envelopes to. */\n publisher: HqPublisher;\n /** Coordinator run id — identifies this fleet instance. Falls back to a stable per-session id. */\n runId: string;\n /** Optional sessionId to tag envelopes with. */\n sessionId?: string;\n /** Override `now()` for deterministic tests. */\n now?: () => string;\n}\n\n/**\n * Start forwarding coordinator stats to HQ. Returns a disposer that\n * unsubscribes the listener — call on shutdown.\n */\nexport function startFleetTelemetryBridge(opts: FleetTelemetryBridgeOptions): () => void {\n const { events, publisher, runId } = opts;\n const now = opts.now ?? (() => new Date().toISOString());\n let lastHash = '';\n\n function buildPayload(stats: {\n total: number;\n running: number;\n idle: number;\n stopped: number;\n inFlight: number;\n pending: number;\n completed: number;\n subagentStatuses: { subagentId: string; taskId: string; status: string; assigned: boolean }[];\n }): HqFleetSnapshotPayload {\n const subagents: HqSubagentSummary[] = stats.subagentStatuses.map((s) => ({\n subagentId: s.subagentId,\n ...(s.taskId ? { task: s.taskId } : {}),\n status: normalizeSubagentStatus(s.status),\n }));\n return {\n runId,\n activeSubagents: stats.running + stats.idle,\n queuedTasks: stats.pending,\n completedTasks: stats.completed,\n failedTasks: stats.stopped,\n subagents,\n };\n }\n\n const off = events.on('coordinator.stats', (stats) => {\n try {\n const payload = buildPayload(stats);\n // Hash-dedup so identical fleet state isn't republished.\n const hash = JSON.stringify(payload);\n if (hash === lastHash) return;\n lastHash = hash;\n publisher.publishFleetSnapshot(payload, {\n ...(opts.sessionId !== undefined ? { sessionId: opts.sessionId } : {}),\n timestamp: now(),\n });\n } catch {\n /* best-effort — HQ telemetry must never break the host */\n }\n });\n\n return () => {\n off();\n };\n}\n\nconst FLEET_STATUS_MAP: Record<string, HqSubagentSummary['status']> = {\n running: 'running',\n idle: 'idle',\n pending: 'pending',\n completed: 'completed',\n failed: 'failed',\n stopped: 'stopped',\n timeout: 'stopped',\n budget_exhausted: 'stopped',\n};\n\nfunction normalizeSubagentStatus(raw: string): HqSubagentSummary['status'] {\n return FLEET_STATUS_MAP[raw] ?? 'idle';\n}\n\n/** Re-export for type-only consumers. */\nexport type { HqEventEnvelope };\n","/**\n * BrainTelemetryBridge — forwards local Brain (decision layer) events to the\n * HQ publisher as `brain.event` envelopes, so the command center can observe\n * decision requests, answers, denials, ask-human escalations, and\n * self-activated interventions across every connected machine.\n *\n * Source: the `brain.*` EventBus events emitted by `ObservableBrainArbiter`\n * (`coordination/brain.ts`) and `BrainMonitor` (`coordination/brain-monitor.ts`).\n * All payloads are plain serializable data (request id, question, source, risk,\n * decision kind, rationale) — no closures, no decoupled relay needed.\n *\n * The webui `setup-events.ts` already forwards these verbatim to its browser;\n * this bridge does the same for the cross-machine HQ plane.\n *\n * @module hq/brain-bridge\n */\nimport type { EventBus } from '../kernel/events.js';\nimport type { BrainDecision, BrainDecisionRequest } from '../coordination/brain.js';\nimport type { HqBrainEventKind, HqBrainEventPayload, HqEventEnvelope } from './protocol.js';\nimport type { HqPublisher } from './publisher.js';\n\nexport interface BrainTelemetryBridgeOptions {\n /** Local EventBus emitting `brain.*` events. */\n events: EventBus;\n /** HQ publisher to forward envelopes to. */\n publisher: HqPublisher;\n /** Optional sessionId to tag envelopes with. */\n sessionId?: string;\n /** Override `now()` for deterministic tests. */\n now?: () => string;\n}\n\nfunction extractRequestFields(req: BrainDecisionRequest | undefined): {\n requestId?: string;\n question?: string;\n source?: string;\n risk?: string;\n} {\n if (req === undefined) return {};\n const out: { requestId?: string; question?: string; source?: string; risk?: string } = {};\n if (typeof req.id === 'string') out.requestId = req.id;\n if (typeof req.question === 'string') out.question = req.question;\n if (typeof req.source === 'string') out.source = req.source;\n if (typeof req.risk === 'string') out.risk = req.risk;\n return out;\n}\n\nfunction extractDecisionFields(dec: BrainDecision | undefined): { decision?: string; detail?: string } {\n if (dec === undefined) return {};\n const out: { decision?: string; detail?: string } = {};\n // BrainDecision is a discriminated union on `type` (answer | ask_human | deny).\n out.decision = dec.type;\n if (dec.type === 'answer') {\n out.detail = dec.text;\n } else if (dec.type === 'ask_human') {\n out.detail = dec.prompt;\n } else if (dec.type === 'deny') {\n out.detail = dec.reason;\n }\n return out;\n}\n\n/**\n * Start forwarding brain events to HQ. Returns a disposer that unsubscribes\n * all listeners — call on shutdown.\n */\nexport function startBrainTelemetryBridge(opts: BrainTelemetryBridgeOptions): () => void {\n const { events, publisher } = opts;\n const now = opts.now ?? (() => new Date().toISOString());\n\n function publish(kind: HqBrainEventKind, payload: Partial<HqBrainEventPayload>, at: number): void {\n try {\n const full: HqBrainEventPayload = { kind, at, ...payload } as HqBrainEventPayload;\n publisher.publishEvent({\n type: 'brain.event',\n payload: full,\n ...(opts.sessionId !== undefined ? { sessionId: opts.sessionId } : {}),\n timestamp: now(),\n });\n } catch {\n /* best-effort */\n }\n }\n\n const offs: Array<() => void> = [];\n\n offs.push(\n events.on('brain.decision_requested', (p) => {\n publish('decision_requested', extractRequestFields(p.request), p.at);\n }),\n );\n offs.push(\n events.on('brain.decision_answered', (p) => {\n publish('decision_answered', {\n ...extractRequestFields(p.request),\n ...extractDecisionFields(p.decision),\n }, p.at);\n }),\n );\n offs.push(\n events.on('brain.decision_ask_human', (p) => {\n publish('decision_ask_human', {\n ...extractRequestFields(p.request),\n ...extractDecisionFields(p.decision),\n }, p.at);\n }),\n );\n offs.push(\n events.on('brain.decision_denied', (p) => {\n publish('decision_denied', {\n ...extractRequestFields(p.request),\n ...extractDecisionFields(p.decision),\n }, p.at);\n }),\n );\n offs.push(\n events.on('brain.human_answered', (p) => {\n const detail = typeof p.text === 'string' ? p.text : p.optionId;\n publish('human_answered', {\n requestId: p.id,\n ...(detail !== undefined ? { detail } : {}),\n ...(p.deny === true ? { decision: 'deny' } : {}),\n }, p.at);\n }),\n );\n offs.push(\n events.on('brain.intervention', (p) => {\n publish('intervention', {\n ...extractRequestFields(p.request),\n ...extractDecisionFields(p.decision),\n interventionKind: p.kind,\n intervened: p.intervened,\n }, p.at);\n }),\n );\n\n return () => {\n for (const off of offs) off();\n };\n}\n\n/** Re-export for type-only consumers. */\nexport type { HqEventEnvelope };\n","/**\n * WorktreeTelemetryBridge — forwards local git-worktree lifecycle events to\n * the HQ publisher as `worktree.event` envelopes, so the command center can\n * render live build phase swim-lanes / DAG across every connected machine.\n *\n * Source: the `worktree.*` EventBus events emitted by `WorktreeManager`\n * (`worktree/worktree-manager.ts`): allocated, committed, merged, conflict,\n * released, failed. All payload fields are plain serializable data\n * (handleId, ownerId, branch, diff stats, conflict files) — no closures, no\n * decoupled relay needed.\n *\n * @module hq/worktree-bridge\n */\nimport type { EventBus } from '../kernel/events.js';\nimport type { HqEventEnvelope, HqWorktreeEventPayload } from './protocol.js';\nimport type { HqPublisher } from './publisher.js';\n\nexport interface WorktreeTelemetryBridgeOptions {\n /** Local EventBus emitting `worktree.*` events. */\n events: EventBus;\n /** HQ publisher to forward envelopes to. */\n publisher: HqPublisher;\n /** Optional sessionId to tag envelopes with. */\n sessionId?: string;\n /** Override `now()` for deterministic tests. */\n now?: () => string;\n}\n\ntype WorktreeAllocated = {\n sessionId?: string | undefined;\n handleId: string;\n ownerId: string;\n ownerLabel: string;\n slug: string;\n dir: string;\n branch: string;\n baseBranch: string;\n};\ntype WorktreeCommitted = {\n sessionId?: string | undefined;\n handleId: string;\n ownerId: string;\n branch: string;\n committed: boolean;\n insertions: number;\n deletions: number;\n files: number;\n sha?: string | undefined;\n};\ntype WorktreeMerged = {\n sessionId?: string | undefined;\n handleId: string;\n ownerId: string;\n branch: string;\n baseBranch: string;\n squash: boolean;\n};\ntype WorktreeConflict = {\n sessionId?: string | undefined;\n handleId: string;\n ownerId: string;\n branch: string;\n conflictFiles: string[];\n};\ntype WorktreeReleased = {\n sessionId?: string | undefined;\n handleId: string;\n ownerId: string;\n branch: string;\n kept: boolean;\n};\ntype WorktreeFailed = {\n sessionId?: string | undefined;\n handleId: string;\n ownerId: string;\n branch?: string | undefined;\n error: string;\n};\n\n/**\n * Start forwarding worktree lifecycle events to HQ. Returns a disposer that\n * unsubscribes all listeners — call on shutdown.\n */\nexport function startWorktreeTelemetryBridge(opts: WorktreeTelemetryBridgeOptions): () => void {\n const { events, publisher } = opts;\n const now = opts.now ?? (() => new Date().toISOString());\n\n function publish(payload: HqWorktreeEventPayload, sessionId?: string): void {\n try {\n publisher.publishEvent({\n type: 'worktree.event',\n payload,\n ...(sessionId !== undefined && sessionId !== '' ? { sessionId } : {}),\n ...(opts.sessionId !== undefined ? { sessionId: opts.sessionId } : {}),\n timestamp: now(),\n });\n } catch {\n /* best-effort */\n }\n }\n\n const offs: Array<() => void> = [];\n\n offs.push(\n events.on('worktree.allocated', (p: WorktreeAllocated) => {\n publish(\n {\n kind: 'allocated',\n handleId: p.handleId,\n ownerId: p.ownerId,\n ownerLabel: p.ownerLabel,\n slug: p.slug,\n branch: p.branch,\n baseBranch: p.baseBranch,\n },\n p.sessionId,\n );\n }),\n );\n\n offs.push(\n events.on('worktree.committed', (p: WorktreeCommitted) => {\n publish(\n {\n kind: 'committed',\n handleId: p.handleId,\n ownerId: p.ownerId,\n branch: p.branch,\n insertions: p.insertions,\n deletions: p.deletions,\n files: p.files,\n ...(p.sha !== undefined ? { sha: p.sha } : {}),\n },\n p.sessionId,\n );\n }),\n );\n\n offs.push(\n events.on('worktree.merged', (p: WorktreeMerged) => {\n publish(\n {\n kind: 'merged',\n handleId: p.handleId,\n ownerId: p.ownerId,\n branch: p.branch,\n baseBranch: p.baseBranch,\n squash: p.squash,\n },\n p.sessionId,\n );\n }),\n );\n\n offs.push(\n events.on('worktree.conflict', (p: WorktreeConflict) => {\n publish(\n {\n kind: 'conflict',\n handleId: p.handleId,\n ownerId: p.ownerId,\n branch: p.branch,\n conflictFiles: p.conflictFiles,\n },\n p.sessionId,\n );\n }),\n );\n\n offs.push(\n events.on('worktree.released', (p: WorktreeReleased) => {\n publish(\n {\n kind: 'released',\n handleId: p.handleId,\n ownerId: p.ownerId,\n branch: p.branch,\n kept: p.kept,\n },\n p.sessionId,\n );\n }),\n );\n\n offs.push(\n events.on('worktree.failed', (p: WorktreeFailed) => {\n publish(\n {\n kind: 'failed',\n handleId: p.handleId,\n ownerId: p.ownerId,\n ...(p.branch !== undefined ? { branch: p.branch } : {}),\n error: p.error,\n },\n p.sessionId,\n );\n }),\n );\n\n return () => {\n for (const off of offs) off();\n };\n}\n\n/** Re-export for type-only consumers. */\nexport type { HqEventEnvelope };\n","/**\n * ToolTelemetryBridge — forwards local tool execution events to the HQ\n * publisher as `tool.started` and `tool.completed` envelopes, so the command\n * center can surface live tool activity (what's running, durations, success\n * rates) across every connected machine.\n *\n * Sources:\n * - `tool.started` (EventBus) → `tool.started` envelope. Raw tool input is\n * summarized via {@link summarizeHqToolArgs} so no secrets or oversized\n * payloads leak to the HQ browser.\n * - `tool.executed` (EventBus) → `tool.completed` envelope (carries the\n * richer post-execution signal: duration, ok/error, output bytes).\n *\n * All payload fields are plain serializable data — no closures. The\n * `tool.started.input` raw args are the only sensitive surface and are\n * reduced to a summary before publishing.\n *\n * @module hq/tool-bridge\n */\nimport type { EventBus } from '../kernel/events.js';\nimport { summarizeHqToolArgs } from './redaction.js';\nimport type { HqEventEnvelope, HqToolCompletedPayload, HqToolStartedPayload } from './protocol.js';\nimport type { HqPublisher } from './publisher.js';\n\nexport interface ToolTelemetryBridgeOptions {\n /** Local EventBus emitting `tool.started` and `tool.executed` events. */\n events: EventBus;\n /** HQ publisher to forward envelopes to. */\n publisher: HqPublisher;\n /** Project root for path redaction in tool input summaries. */\n projectRoot?: string;\n /** Optional sessionId to tag envelopes with. */\n sessionId?: string;\n /** Override `now()` for deterministic tests. */\n now?: () => string;\n}\n\ninterface ToolStartedEvent {\n sessionId?: string | undefined;\n name: string;\n id: string;\n input?: unknown | undefined;\n}\n\ninterface ToolExecutedEvent {\n sessionId?: string | undefined;\n id?: string | undefined;\n name: string;\n durationMs: number;\n ok: boolean;\n input?: unknown | undefined;\n output?: string | undefined;\n outputBytes?: number | undefined;\n}\n\n/** Track in-flight tool calls so we can attach start info to completion. */\ninterface InFlightTool {\n name: string;\n startedAt: number;\n}\n\n/**\n * Start forwarding tool execution events to HQ. Returns a disposer that\n * unsubscribes all listeners — call on shutdown.\n */\nexport function startToolTelemetryBridge(opts: ToolTelemetryBridgeOptions): () => void {\n const { events, publisher } = opts;\n const now = opts.now ?? (() => new Date().toISOString());\n const inFlight = new Map<string, InFlightTool>();\n\n function sessionIdTag(sessionId?: string): { sessionId?: string } {\n const tag = sessionId ?? opts.sessionId;\n return tag !== undefined ? { sessionId: tag } : {};\n }\n\n const offStarted = events.on('tool.started', (p: ToolStartedEvent) => {\n inFlight.set(p.id, { name: p.name, startedAt: Date.now() });\n try {\n const payload: HqToolStartedPayload = {\n toolName: p.name,\n ...(p.input !== undefined\n ? {\n inputSummary: summarizeHqToolArgs(p.input, {\n ...(opts.projectRoot !== undefined ? { projectRoot: opts.projectRoot } : {}),\n }),\n }\n : {}),\n };\n publisher.publishEvent({\n type: 'tool.started',\n payload,\n ...sessionIdTag(p.sessionId),\n timestamp: now(),\n });\n } catch {\n /* best-effort */\n }\n });\n\n const offExecuted = events.on('tool.executed', (p: ToolExecutedEvent) => {\n const id = p.id;\n if (id !== undefined) inFlight.delete(id);\n try {\n const payload: HqToolCompletedPayload = {\n toolName: p.name,\n status: p.ok ? 'success' : 'error',\n durationMs: p.durationMs,\n ...(p.output !== undefined && p.output.length > 0\n ? { outputSummary: truncateForSummary(p.output) }\n : {}),\n };\n publisher.publishEvent({\n type: 'tool.completed',\n payload,\n ...sessionIdTag(p.sessionId),\n timestamp: now(),\n });\n } catch {\n /* best-effort */\n }\n });\n\n return () => {\n offStarted();\n offExecuted();\n inFlight.clear();\n };\n}\n\nfunction truncateForSummary(output: string, max = 280): unknown {\n if (output.length <= max) return output;\n return `${output.slice(0, max)}…[truncated:${output.length - max}]`;\n}\n\n/** Re-export for type-only consumers. */\nexport type { HqEventEnvelope };\n","/**\n * CostTelemetryBridge — forwards local token/cost accounting events to the HQ\n * publisher as `session.usage` envelopes, giving the command center the\n * granular per-call cost signal it needs to render live cost trends and\n * roll-ups across every connected machine.\n *\n * Source: the `token.accounted` EventBus event, emitted by the TokenCounter\n * (`infrastructure/token-counter.ts`) after every provider call. The payload\n * is plain serializable data (usage counts + a cost breakdown) — no closures.\n *\n * This is the high-frequency cost feed; HQ's persistence layer (Phase 2)\n * time-buckets these into trend series.\n *\n * @module hq/cost-bridge\n */\nimport type { EventBus } from '../kernel/events.js';\nimport type { Usage } from '../types/provider.js';\nimport type { HqEventEnvelope, HqUsagePayload } from './protocol.js';\nimport type { HqPublisher } from './publisher.js';\n\nexport interface CostTelemetryBridgeOptions {\n /** Local EventBus emitting `token.accounted`. */\n events: EventBus;\n /** HQ publisher to forward envelopes to. */\n publisher: HqPublisher;\n /** Optional sessionId to tag envelopes with (overrides the event's, when set). */\n sessionId?: string;\n /** Override `now()` for deterministic tests. */\n now?: () => string;\n}\n\ninterface TokenAccountedEvent {\n sessionId?: string | undefined;\n usage: Usage;\n cost: { input: number; output: number; total: number };\n}\n\n/**\n * Start forwarding token/cost events to HQ. Returns a disposer that\n * unsubscribes the listener — call on shutdown.\n */\nexport function startCostTelemetryBridge(opts: CostTelemetryBridgeOptions): () => void {\n const { events, publisher } = opts;\n const now = opts.now ?? (() => new Date().toISOString());\n\n const off = events.on('token.accounted', (p: TokenAccountedEvent) => {\n try {\n const payload: HqUsagePayload = {\n inputTokens: p.usage.input,\n outputTokens: p.usage.output,\n totalTokens: p.usage.input + p.usage.output,\n costUsd: p.cost.total,\n };\n const sessionId = opts.sessionId ?? p.sessionId;\n publisher.publishEvent({\n type: 'session.usage',\n payload,\n ...(sessionId !== undefined ? { sessionId } : {}),\n timestamp: now(),\n });\n } catch {\n /* best-effort */\n }\n });\n\n return () => {\n off();\n };\n}\n\n/** Re-export for type-only consumers. */\nexport type { HqEventEnvelope };\n","/**\n * HQ persistence layer — survives HQ server restarts so the command center\n * keeps its event history, snapshot state, cost/activity trends, and (later)\n * alert + command-audit logs across reboots.\n *\n * Three stores, all file-backed under the HQ dataDir\n * (`~/.wrongstack/hq/` by default — see {@link resolveHqDataDir}):\n *\n * - {@link HqEventLog} — append-only JSONL of every received event\n * envelope, rotated when it exceeds a cap.\n * - {@link HqSnapshotStore} — atomic checkpoint of the latest snapshot,\n * written on every debounced broadcast.\n * - {@link HqTimeseriesStore}— time-bucketed cost + activity samples for\n * trend charts.\n *\n * Design constraints (mirrors the codebase conventions):\n * - All disk writes go through {@link withFileLock} + {@link atomicWrite}\n * (shared primitives from `utils/atomic-write.ts`) for cross-process safety.\n * - Every write is best-effort and never throws into the HQ server hot path —\n * callers wrap in try/catch and degrade to in-memory-only on failure.\n * - Appends use a FIFO write chain (single in-flight writer) so concurrent\n * event arrivals don't interleave lines.\n *\n * @module hq/persistence\n */\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { atomicWrite, withFileLock } from '../utils/atomic-write.js';\nimport type { HqEventEnvelope, HqSnapshot } from './protocol.js';\n\n/** Maximum event-log lines before a rotation compacts it down to the tail. */\nconst DEFAULT_EVENT_LOG_MAX_LINES = 50_000;\n/** How many lines to retain after a rotation. */\nconst DEFAULT_EVENT_LOG_ROTATE_KEEP = 20_000;\n\n// ── HqEventLog ──────────────────────────────────────────────────────────────\n\nexport interface HqEventLogOptions {\n dataDir: string;\n maxLines?: number;\n rotateKeep?: number;\n}\n\n/**\n * Append-only JSONL event log. Every received event envelope is appended to\n * `events.jsonl`; when the file exceeds `maxLines` it is rotated under a file\n * lock to keep only the most recent `rotateKeep` lines.\n *\n * Writes are serialized through a FIFO chain so concurrent appends never\n * interleave. All operations are best-effort: a rejected append resolves\n * (never rejects) and the caller's `await` never breaks the server loop.\n */\nexport class HqEventLog {\n private readonly filePath: string;\n private readonly maxLines: number;\n private readonly rotateKeep: number;\n private writeChain: Promise<void> = Promise.resolve();\n private lineCount = 0;\n private counted = false;\n\n constructor(opts: HqEventLogOptions) {\n this.filePath = path.join(opts.dataDir, 'events.jsonl');\n this.maxLines = opts.maxLines ?? DEFAULT_EVENT_LOG_MAX_LINES;\n this.rotateKeep = opts.rotateKeep ?? DEFAULT_EVENT_LOG_ROTATE_KEEP;\n }\n\n /** Append an event envelope as one JSON line. Best-effort, never rejects. */\n append(event: HqEventEnvelope): void {\n this.writeChain = this.writeChain\n .then(() => this.appendInternal(event))\n .catch(() => {\n /* best-effort: a failed append must not break the write chain */\n });\n }\n\n /** Resolves once all queued appends have settled. For tests. */\n async drain(): Promise<void> {\n await this.writeChain.catch(() => {\n /* best-effort */\n });\n }\n\n private async appendInternal(event: HqEventEnvelope): Promise<void> {\n if (!this.counted) {\n this.lineCount = await this.countLines();\n this.counted = true;\n }\n const line = JSON.stringify(event) + '\\n';\n await fs.appendFile(this.filePath, line, { encoding: 'utf8' });\n this.lineCount += 1;\n if (this.lineCount >= this.maxLines) {\n await this.rotate();\n }\n }\n\n private async rotate(): Promise<void> {\n await withFileLock(this.filePath, async () => {\n try {\n const content = await fs.readFile(this.filePath, 'utf8');\n const lines = content.split('\\n').filter((l) => l.length > 0);\n if (lines.length <= this.rotateKeep) {\n this.lineCount = lines.length;\n return;\n }\n const kept = lines.slice(lines.length - this.rotateKeep);\n await atomicWrite(this.filePath, kept.join('\\n') + '\\n');\n this.lineCount = kept.length;\n } catch {\n /* best-effort */\n }\n });\n }\n\n private async countLines(): Promise<number> {\n try {\n const content = await fs.readFile(this.filePath, 'utf8');\n return content.split('\\n').filter((l) => l.length > 0).length;\n } catch {\n return 0;\n }\n }\n\n /**\n * Read the most recent `limit` events, optionally filtered by envelope\n * `type`. Newest first. Returns `[]` if the file doesn't exist yet.\n */\n async recent(limit: number, typeFilter?: string): Promise<HqEventEnvelope[]> {\n let content: string;\n try {\n content = await fs.readFile(this.filePath, 'utf8');\n } catch {\n return [];\n }\n const lines = content.split('\\n').filter((l) => l.length > 0);\n const out: HqEventEnvelope[] = [];\n // Walk newest-first so we can stop early once we have `limit` matches.\n for (let i = lines.length - 1; i >= 0 && out.length < limit; i--) {\n try {\n const env = JSON.parse(lines[i]!) as HqEventEnvelope;\n if (typeFilter === undefined || env.type === typeFilter) {\n out.push(env);\n }\n } catch {\n /* skip malformed lines */\n }\n }\n return out;\n }\n\n /** Initialize the line count cache from disk (call once at boot). */\n async hydrate(): Promise<void> {\n this.lineCount = await this.countLines();\n this.counted = true;\n }\n}\n\n// ── HqSnapshotStore ──────────────────────────────────────────────────────────\n\nexport interface HqSnapshotStoreOptions {\n dataDir: string;\n}\n\n/**\n * Atomic checkpoint of the latest snapshot, written to `snapshot.json`.\n * The HQ server writes on every debounced broadcast and reads on boot to\n * re-seed its in-memory state. Best-effort, never rejects.\n */\nexport class HqSnapshotStore {\n private readonly filePath: string;\n private writeChain: Promise<void> = Promise.resolve();\n\n constructor(opts: HqSnapshotStoreOptions) {\n this.filePath = path.join(opts.dataDir, 'snapshot.json');\n }\n\n /** Persist a snapshot. Best-effort, never rejects. */\n save(snapshot: HqSnapshot): void {\n this.writeChain = this.writeChain\n .then(() => atomicWrite(this.filePath, JSON.stringify(snapshot), { mode: 0o600 }))\n .catch(() => {\n /* best-effort */\n });\n }\n\n /** Resolves once all queued saves have settled. For tests. */\n async drain(): Promise<void> {\n await this.writeChain.catch(() => {\n /* best-effort */\n });\n }\n\n /** Read the last persisted snapshot, or `null` if none. */\n async load(): Promise<HqSnapshot | null> {\n try {\n const content = await fs.readFile(this.filePath, 'utf8');\n return JSON.parse(content) as HqSnapshot;\n } catch {\n return null;\n }\n }\n}\n\n// ── HqTimeseriesStore ────────────────────────────────────────────────────────\n\nexport interface HqTimeseriesSample {\n /** Bucket start (epoch ms, floored to the bucket width). */\n ts: number;\n /** Total cost (USD) accumulated in this bucket. */\n costUsd: number;\n /** Total input tokens in this bucket. */\n inputTokens: number;\n /** Total output tokens in this bucket. */\n outputTokens: number;\n /** Number of tool executions in this bucket. */\n toolCalls: number;\n /** Snapshot of active agents at bucket close (last-write per bucket). */\n activeAgents?: number;\n}\n\nexport interface HqTimeseriesStoreOptions {\n dataDir: string;\n /** Bucket width in ms. Default 5 minutes. */\n bucketMs?: number;\n /** How many buckets to retain. Default 2016 (1 week of 5-min buckets). */\n maxBuckets?: number;\n}\n\n/**\n * Time-bucketed cost + activity samples for trend charts. Each {@link record}\n * call folds a cost/tool signal into the current bucket; {@link flush} writes\n * the accumulated buckets to `timeseries.jsonl` (append under lock) and prunes\n * to `maxBuckets`.\n *\n * The store keeps an in-memory ring of buckets for cheap reads; {@link load}\n * rehydrates them on boot.\n */\nexport class HqTimeseriesStore {\n private readonly filePath: string;\n private readonly bucketMs: number;\n private readonly maxBuckets: number;\n private readonly buckets = new Map<number, HqTimeseriesSample>();\n private flushChain: Promise<void> = Promise.resolve();\n\n constructor(opts: HqTimeseriesStoreOptions) {\n this.filePath = path.join(opts.dataDir, 'timeseries.jsonl');\n this.bucketMs = opts.bucketMs ?? 5 * 60 * 1000;\n this.maxBuckets = opts.maxBuckets ?? 2016;\n }\n\n private bucketStart(ts: number): number {\n return Math.floor(ts / this.bucketMs) * this.bucketMs;\n }\n\n /** Fold a cost/tool signal into the current bucket. Best-effort. */\n record(signal: {\n ts?: number;\n costUsd?: number;\n inputTokens?: number;\n outputTokens?: number;\n toolCalls?: number;\n activeAgents?: number;\n }): void {\n const start = this.bucketStart(signal.ts ?? Date.now());\n let bucket = this.buckets.get(start);\n if (!bucket) {\n bucket = { ts: start, costUsd: 0, inputTokens: 0, outputTokens: 0, toolCalls: 0 };\n this.buckets.set(start, bucket);\n }\n if (signal.costUsd !== undefined) bucket.costUsd += signal.costUsd;\n if (signal.inputTokens !== undefined) bucket.inputTokens += signal.inputTokens;\n if (signal.outputTokens !== undefined) bucket.outputTokens += signal.outputTokens;\n if (signal.toolCalls !== undefined) bucket.toolCalls += signal.toolCalls;\n if (signal.activeAgents !== undefined) bucket.activeAgents = signal.activeAgents;\n // Prune in-memory buckets beyond retention so a long-lived HQ doesn't\n // accumulate unbounded history. Keep the most-recent maxBuckets.\n if (this.buckets.size > this.maxBuckets) {\n const sorted = Array.from(this.buckets.keys()).sort((a, b) => a - b);\n while (this.buckets.size > this.maxBuckets && sorted.length > 0) {\n const oldest = sorted.shift();\n if (oldest === undefined) break;\n this.buckets.delete(oldest);\n }\n }\n }\n\n /** Persist accumulated buckets to disk (append under lock), prune to maxBuckets. */\n flush(): void {\n const snapshot = Array.from(this.buckets.values()).sort((a, b) => a.ts - b.ts);\n if (snapshot.length === 0) return;\n this.flushChain = this.flushChain\n .then(() => this.flushInternal(snapshot))\n .catch(() => {\n /* best-effort */\n });\n }\n\n /** Resolves once all queued flushes have settled. For tests. */\n async drain(): Promise<void> {\n await this.flushChain.catch(() => {\n /* best-effort */\n });\n }\n\n private async flushInternal(toWrite: HqTimeseriesSample[]): Promise<void> {\n const lines = toWrite.map((b) => JSON.stringify(b)).join('\\n') + '\\n';\n await withFileLock(this.filePath, async () => {\n await fs.appendFile(this.filePath, lines, { encoding: 'utf8' });\n });\n // Prune in-memory buckets beyond retention.\n const sorted = Array.from(this.buckets.keys()).sort((a, b) => a - b);\n while (this.buckets.size > this.maxBuckets) {\n const oldest = sorted.shift();\n if (oldest === undefined) break;\n this.buckets.delete(oldest);\n }\n }\n\n /** Read buckets within `[since, now]`, oldest-first. */\n async read(sinceMs?: number): Promise<HqTimeseriesSample[]> {\n // Prefer in-memory (always most current); supplement from disk on first call.\n if (this.buckets.size === 0) await this.load();\n const since = sinceMs ?? 0;\n return Array.from(this.buckets.values())\n .filter((b) => b.ts >= since)\n .sort((a, b) => a.ts - b.ts);\n }\n\n /** Rehydrate buckets from disk (deduped, latest-per-bucket wins). */\n async load(): Promise<void> {\n let content: string;\n try {\n content = await fs.readFile(this.filePath, 'utf8');\n } catch {\n return;\n }\n for (const line of content.split('\\n')) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n try {\n const sample = JSON.parse(trimmed) as HqTimeseriesSample;\n // Last-write-wins per bucket (file is append-only, so later lines win).\n this.buckets.set(sample.ts, sample);\n } catch {\n /* skip malformed */\n }\n }\n // Prune to retention.\n const sorted = Array.from(this.buckets.keys()).sort((a, b) => a - b);\n while (this.buckets.size > this.maxBuckets) {\n const oldest = sorted.shift();\n if (oldest === undefined) break;\n this.buckets.delete(oldest);\n }\n }\n}\n\n// ── Aggregate persistence facade ─────────────────────────────────────────────\n\nexport interface HqPersistence {\n eventLog: HqEventLog;\n snapshotStore: HqSnapshotStore;\n timeseries: HqTimeseriesStore;\n}\n\nexport function createHqPersistence(dataDir: string): HqPersistence {\n return {\n eventLog: new HqEventLog({ dataDir }),\n snapshotStore: new HqSnapshotStore({ dataDir }),\n timeseries: new HqTimeseriesStore({ dataDir }),\n };\n}\n","/**\n * HQ control-plane command definitions — typed payloads for the commands the\n * HQ dashboard can enqueue to connected machines (Phase 3+ of the HQ command\n * center). These are carried over the existing `HqQueuedCommand` wire shape\n * (`{commandId, type, payload, …}`) whose `type`/`payload` were previously\n * type-erased. This module gives them a discriminated union for type-safe\n * dispatch on the client side (Phase 4).\n *\n * Security model: `run-command` (raw shell) is gated by a per-token\n * `control.execute` capability AND an operator opt-in; the other four commands\n * route through the agent's own decision loop / mailbox and inherit their\n * existing guardrails. See `docs/plans/hq-command-center-2026-07.md`.\n *\n * @module hq/commands\n */\nimport type { HqQueuedCommand } from './protocol.js';\n\n// ── Command types ───────────────────────────────────────────────────────────\n\n/** HQ_COMMAND_TYPES — the full set of recognized command `type` strings. */\nexport const HQ_COMMAND_TYPES = [\n 'steer',\n 'btw',\n 'queue',\n 'abort',\n 'spawn',\n 'broadcast',\n 'run-command',\n] as const;\n\nexport type HqCommandType = (typeof HQ_COMMAND_TYPES)[number];\n\n/** Inject a steer text into a target agent's conversation. */\nexport interface HqSteerCommand {\n type: 'steer';\n /** Target agent address: a unique id (`leader@<tag>`), an alias (`leader`), or `*` for all. */\n to: string;\n subject: string;\n body: string;\n priority?: 'low' | 'normal' | 'high';\n}\n\n/**\n * Post a non-urgent FYI (`btw`) into a target agent's mailbox. Unlike a steer,\n * a btw is absorbed as context — it does not demand the agent change course.\n * Same wire shape as steer; only the emitted mailbox `type` differs.\n */\nexport interface HqBtwCommand {\n type: 'btw';\n /** Target agent address: a unique id (`leader@<tag>`), an alias (`leader`), or `*` for all. */\n to: string;\n subject: string;\n body: string;\n priority?: 'low' | 'normal' | 'high';\n}\n\n/**\n * Queue a prompt/note (`queue`) for a target agent. Delivered as a plain\n * `note` mailbox message the agent picks up before its next step — used when\n * the prompt should wait its turn rather than steer the current operation.\n */\nexport interface HqQueueCommand {\n type: 'queue';\n /** Target agent address: a unique id (`leader@<tag>`), an alias (`leader`), or `*` for all. */\n to: string;\n subject: string;\n body: string;\n priority?: 'low' | 'normal' | 'high';\n}\n\n/** Abort a running agent run or fleet. */\nexport interface HqAbortCommand {\n type: 'abort';\n /** `'leader'` aborts the session leader; a subagentId aborts one agent; `'fleet'` stops all. */\n target: 'leader' | 'fleet' | string;\n}\n\n/** Spawn a subagent of the given role. */\nexport interface HqSpawnCommand {\n type: 'spawn';\n role: string;\n /** Optional task description for dispatch routing. */\n task?: string;\n maxIterations?: number;\n}\n\n/** Broadcast a mailbox message to all agents on the target's project. */\nexport interface HqBroadcastCommand {\n type: 'broadcast';\n subject: string;\n body: string;\n priority?: 'low' | 'normal' | 'high';\n}\n\n/** Run a shell command on the target machine. GATED by `control.execute`. */\nexport interface HqRunCommandCommand {\n type: 'run-command';\n command: string;\n /** Optional working directory (defaults to the agent's project root). */\n cwd?: string;\n}\n\nexport type HqCommand =\n | HqSteerCommand\n | HqBtwCommand\n | HqQueueCommand\n | HqAbortCommand\n | HqSpawnCommand\n | HqBroadcastCommand\n | HqRunCommandCommand;\n\n// ── Validation ──────────────────────────────────────────────────────────────\n\nconst HQ_COMMAND_TYPE_SET = new Set<string>(HQ_COMMAND_TYPES);\n\n/**\n * Validate that an inbound `HqQueuedCommand` has a recognized `type` and a\n * minimally well-formed payload. Returns the narrowed command on success, or\n * `null` when the command should be rejected.\n *\n * This is a shape check, not a security gate — capability enforcement happens\n * at enqueue time (browser token must have `control.enqueue`) and at execute\n * time (`run-command` requires `control.execute`).\n */\nexport function validateHqCommand(queued: HqQueuedCommand): HqCommand | null {\n if (!HQ_COMMAND_TYPE_SET.has(queued.type)) return null;\n const p = queued.payload as Record<string, unknown>;\n if (p === null || typeof p !== 'object') return null;\n switch (queued.type as HqCommandType) {\n case 'steer': {\n if (typeof p['to'] !== 'string' || typeof p['subject'] !== 'string' || typeof p['body'] !== 'string') {\n return null;\n }\n const result: HqSteerCommand = { type: 'steer', to: p['to'], subject: p['subject'], body: p['body'] };\n if (p['priority'] === 'low' || p['priority'] === 'normal' || p['priority'] === 'high') {\n result.priority = p['priority'];\n }\n return result;\n }\n case 'btw': {\n if (typeof p['to'] !== 'string' || typeof p['subject'] !== 'string' || typeof p['body'] !== 'string') {\n return null;\n }\n const result: HqBtwCommand = { type: 'btw', to: p['to'], subject: p['subject'], body: p['body'] };\n if (p['priority'] === 'low' || p['priority'] === 'normal' || p['priority'] === 'high') {\n result.priority = p['priority'];\n }\n return result;\n }\n case 'queue': {\n if (typeof p['to'] !== 'string' || typeof p['subject'] !== 'string' || typeof p['body'] !== 'string') {\n return null;\n }\n const result: HqQueueCommand = { type: 'queue', to: p['to'], subject: p['subject'], body: p['body'] };\n if (p['priority'] === 'low' || p['priority'] === 'normal' || p['priority'] === 'high') {\n result.priority = p['priority'];\n }\n return result;\n }\n case 'abort':\n if (typeof p['target'] !== 'string') return null;\n return { type: 'abort', target: p['target'] };\n case 'spawn': {\n if (typeof p['role'] !== 'string') return null;\n const result: HqSpawnCommand = { type: 'spawn', role: p['role'] };\n if (typeof p['task'] === 'string') result.task = p['task'];\n if (typeof p['maxIterations'] === 'number') result.maxIterations = p['maxIterations'];\n return result;\n }\n case 'broadcast': {\n if (typeof p['subject'] !== 'string' || typeof p['body'] !== 'string') return null;\n const result: HqBroadcastCommand = { type: 'broadcast', subject: p['subject'], body: p['body'] };\n if (p['priority'] === 'low' || p['priority'] === 'normal' || p['priority'] === 'high') {\n result.priority = p['priority'];\n }\n return result;\n }\n case 'run-command': {\n if (typeof p['command'] !== 'string') return null;\n const result: HqRunCommandCommand = { type: 'run-command', command: p['command'] };\n if (typeof p['cwd'] === 'string') result.cwd = p['cwd'];\n return result;\n }\n default:\n return null;\n }\n}\n\n// ── Audit log ───────────────────────────────────────────────────────────────\n\nexport interface HqCommandAuditEntry {\n commandId: string;\n type: HqCommandType;\n clientId: string;\n /** Who enqueued the command (browser token id, or 'anonymous' in open mode). */\n enqueuedBy: string;\n enqueuedAt: string;\n status: 'queued' | 'delivered' | 'acked';\n /** Ack status when the client has responded. */\n ackStatus?: 'accepted' | 'completed' | 'failed' | 'rejected';\n ackMessage?: string;\n ackedAt?: string;\n}\n\n/**\n * In-memory command audit ring. Capped; the Phase 2 persistence layer can\n * sink entries to disk when wired (future). For now this gives the server a\n * queryable history for `/api/commands` and snapshot enrichment.\n */\nexport class HqCommandAuditLog {\n private readonly entries: HqCommandAuditEntry[] = [];\n private readonly max: number;\n\n constructor(max = 1000) {\n this.max = max;\n }\n\n record(entry: HqCommandAuditEntry): void {\n this.entries.push(entry);\n if (this.entries.length > this.max) {\n this.entries.splice(0, this.entries.length - this.max);\n }\n }\n\n update(commandId: string, patch: Partial<HqCommandAuditEntry>): void {\n const entry = this.entries.find((e) => e.commandId === commandId);\n if (entry) Object.assign(entry, patch);\n }\n\n recent(limit = 200): HqCommandAuditEntry[] {\n return this.entries.slice(-limit);\n }\n}\n","/**\n * HQ alerting engine — evaluates the current snapshot against a set of\n * operator-configurable rules and emits `hq.alert` messages when a threshold\n * is crossed. Mirrors the BrainMonitor's self-activation logic (tool-failure\n * streaks, error storms) but at the fleet-wide command-center scope.\n *\n * Rules are evaluated on a periodic tick (default 15s, unref'd) against the\n * latest in-memory snapshot. Deduplication prevents alert storms: a rule that\n * is still firing is not re-emitted until it clears (state machine per rule).\n *\n * @module hq/alerts\n */\nimport type { HqAlertMessage, HqSnapshot } from './protocol.js';\n\n/** Severity levels for alerts, mirroring {@link HqAlertMessage}. */\nexport type HqAlertSeverity = HqAlertMessage['severity'];\n\nexport interface HqAlert {\n id: string;\n ruleId: string;\n severity: HqAlertSeverity;\n message: string;\n /** Epoch ms when the alert first fired in its current episode. */\n firstFiredAt: number;\n /** Epoch ms of the most recent evaluation that confirmed the alert. */\n lastFiredAt: number;\n}\n\nexport interface HqAlertRuleConfig {\n /** Maximum cost (USD) across the whole fleet before alerting. Default 50. */\n costThresholdUsd?: number;\n /** Seconds of silence from ALL machines before a stale alert fires. Default 120. */\n staleMachineSeconds?: number;\n /** Minimum number of active agents before concurrency alert fires. Default: disabled (0). */\n maxAgents?: number;\n}\n\n/** The fully-resolved config passed to rule.evaluate (no optional fields). */\ntype ResolvedAlertConfig = Required<Pick<HqAlertRuleConfig, 'costThresholdUsd' | 'staleMachineSeconds' | 'maxAgents'>>;\n\n/** A rule is a pure function: snapshot + config → optional firing. */\ninterface HqAlertRule {\n id: string;\n severity: HqAlertSeverity;\n evaluate: (snapshot: HqSnapshot | null, config: ResolvedAlertConfig, now: number) => string | null;\n}\n\nconst DEFAULT_CONFIG: ResolvedAlertConfig = {\n costThresholdUsd: 50,\n staleMachineSeconds: 120,\n maxAgents: 0,\n};\n\nfunction resolveConfig(config?: HqAlertRuleConfig): ResolvedAlertConfig {\n return { ...DEFAULT_CONFIG, ...(config ?? {}) };\n}\n\nconst RULES: readonly HqAlertRule[] = [\n {\n id: 'fleet-cost-threshold',\n severity: 'warn',\n evaluate: (snapshot, config) => {\n if (snapshot === null) return null;\n const cost = snapshot.totals.totalCostUsd ?? 0;\n if (cost >= config.costThresholdUsd) {\n return `Fleet cost $${cost.toFixed(2)} exceeded threshold $${config.costThresholdUsd.toFixed(2)}`;\n }\n return null;\n },\n },\n {\n id: 'all-machines-stale',\n severity: 'warn',\n evaluate: (snapshot, config, now) => {\n if (snapshot === null) return null;\n const machines = snapshot.machines ?? [];\n if (machines.length === 0) return null;\n const cutoff = now - config.staleMachineSeconds * 1000;\n const stale = machines.filter((m) => Date.parse(m.lastActivityAt) < cutoff);\n if (stale.length === machines.length) {\n return `All ${machines.length} machine(s) silent for ${config.staleMachineSeconds}s`;\n }\n return null;\n },\n },\n {\n id: 'high-concurrency',\n severity: 'info',\n evaluate: (snapshot, config) => {\n if (snapshot === null || config.maxAgents <= 0) return null;\n const agents = snapshot.totals.activeAgents ?? 0;\n if (agents >= config.maxAgents) {\n return `High fleet concurrency: ${agents} active agents (limit ${config.maxAgents})`;\n }\n return null;\n },\n },\n {\n id: 'fleet-failure-spike',\n severity: 'warn',\n evaluate: (snapshot) => {\n if (snapshot === null) return null;\n // Aggregate failed tasks across all reported fleets.\n const fleets = snapshot.fleets ?? [];\n const failed = fleets.reduce((sum, f) => sum + f.failedTasks, 0);\n if (failed >= 5) {\n return `${failed} failed task(s) across the fleet`;\n }\n return null;\n },\n },\n];\n\n/**\n * In-memory alert state. Tracks which rules are currently firing so the same\n * alert is not re-emitted every tick — only state transitions (cleared →\n * firing) emit. Optionally persists to disk via a callback.\n */\nexport class HqAlertEngine {\n private readonly active = new Map<string, HqAlert>();\n private readonly history: HqAlert[] = [];\n private readonly maxHistory: number;\n private timer: ReturnType<typeof setInterval> | null = null;\n private readonly onAlert: (alert: HqAlert) => void;\n\n constructor(opts: { onAlert: (alert: HqAlert) => void; maxHistory?: number }) {\n this.onAlert = opts.onAlert;\n this.maxHistory = opts.maxHistory ?? 500;\n }\n\n /**\n * Evaluate all rules against the snapshot. Emits (via the `onAlert`\n * callback) only for rules that newly transition to firing. Clears rules\n * that are no longer firing. Returns the list of newly-fired alerts.\n */\n evaluate(snapshot: HqSnapshot | null, config?: HqAlertRuleConfig, now: number = Date.now()): HqAlert[] {\n const resolved = resolveConfig(config);\n const fired: HqAlert[] = [];\n const firingIds = new Set<string>();\n\n for (const rule of RULES) {\n const message = rule.evaluate(snapshot, resolved, now);\n if (message !== null) {\n firingIds.add(rule.id);\n const existing = this.active.get(rule.id);\n if (existing === undefined) {\n // New transition → emit.\n const alert: HqAlert = {\n id: `${rule.id}-${now}`,\n ruleId: rule.id,\n severity: rule.severity,\n message,\n firstFiredAt: now,\n lastFiredAt: now,\n };\n this.active.set(rule.id, alert);\n this.history.push(alert);\n if (this.history.length > this.maxHistory) this.history.splice(0, this.history.length - this.maxHistory);\n fired.push(alert);\n this.onAlert(alert);\n } else {\n // Already firing — refresh timestamp, don't re-emit.\n existing.lastFiredAt = now;\n }\n }\n }\n\n // Clear rules no longer firing.\n for (const id of Array.from(this.active.keys())) {\n if (!firingIds.has(id)) {\n this.active.delete(id);\n }\n }\n\n return fired;\n }\n\n /** Currently-active (firing) alerts. */\n activeAlerts(): HqAlert[] {\n return Array.from(this.active.values());\n }\n\n /** Historical alerts (newest-last), capped at maxHistory. */\n recentAlerts(limit = 100): HqAlert[] {\n return this.history.slice(-limit);\n }\n\n /**\n * Start periodic evaluation against a snapshot getter. The timer is\n * unref'd so it never keeps the process alive. Returns a disposer.\n */\n startPeriodic(\n getSnapshot: () => HqSnapshot | null,\n config?: HqAlertRuleConfig | (() => HqAlertRuleConfig | undefined),\n intervalMs = 15_000,\n ): () => void {\n if (this.timer !== null) return () => undefined;\n const tick = (): void => {\n try {\n const cfg = typeof config === 'function' ? config() : config;\n this.evaluate(getSnapshot(), cfg);\n } catch {\n /* best-effort — alert evaluation must never crash the server */\n }\n };\n this.timer = setInterval(tick, intervalMs);\n this.timer.unref?.();\n return () => {\n if (this.timer !== null) {\n clearInterval(this.timer);\n this.timer = null;\n }\n };\n }\n}\n\n/** Map an internal {@link HqAlert} to the wire {@link HqAlertMessage}. */\nexport function toAlertMessage(alert: HqAlert): HqAlertMessage {\n return {\n type: 'hq.alert',\n severity: alert.severity,\n message: `[${alert.ruleId}] ${alert.message}`,\n timestamp: new Date(alert.lastFiredAt).toISOString(),\n };\n}\n"]}
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/hq/protocol.ts", "../../src/security/secret-scrubber.ts", "../../src/hq/redaction.ts", "../../src/hq/mailbox-mapper.ts", "../../src/hq/publisher.ts", "../../src/hq/factory.ts", "../../src/coordination/global-mailbox.ts", "../../src/utils/atomic-write.ts", "../../src/utils/session-scoped-path.ts", "../../src/utils/wstack-paths.ts", "../../src/types/errors.ts", "../../src/coordination/mailbox-constants.ts", "../../src/coordination/mailbox-message-codec.ts", "../../src/coordination/mailbox-types.ts", "../../src/hq/auth-store.ts", "../../src/hq/agent-bridge.ts", "../../src/hq/session-bridge.ts", "../../src/hq/transcript-mapper.ts", "../../src/hq/fleet-bridge.ts", "../../src/hq/brain-bridge.ts", "../../src/hq/worktree-bridge.ts", "../../src/hq/tool-bridge.ts", "../../src/hq/cost-bridge.ts", "../../src/hq/persistence.ts", "../../src/hq/commands.ts", "../../src/hq/alerts.ts"],
|
|
4
|
+
"sourcesContent": ["export const HQ_PROTOCOL_VERSION = 1 as const;\n\nexport type HqProtocolVersion = typeof HQ_PROTOCOL_VERSION;\n\nexport type HqClientKind = 'tui' | 'repl' | 'webui' | 'cli' | 'unknown';\n\nexport type HqWorkspaceKind = 'git' | 'directory' | 'unknown';\n\nexport type HqProjectStatus = 'active' | 'idle' | 'stale' | 'error';\n\nexport type HqClientCapability =\n | 'telemetry.publish'\n | 'session.summary'\n | 'fleet.summary'\n | 'mailbox.summary'\n | 'control.receive';\n\nexport type HqToolArgsPolicy = 'none' | 'summary' | 'redacted' | 'full';\n\nexport type HqPathPolicy = 'none' | 'project-relative' | 'redacted' | 'full';\n\nexport interface HqRedactionPolicy {\n rawContent: boolean;\n toolArgs: HqToolArgsPolicy;\n paths: HqPathPolicy;\n}\n\nexport const DEFAULT_HQ_REDACTION_POLICY: HqRedactionPolicy = {\n rawContent: true,\n toolArgs: 'full',\n paths: 'full',\n};\n\n/**\n * Per-string cap applied when redacting chat-transcript events\n * (`session.transcript` / `agent.message`). The generic 500-char summary cap\n * is right for telemetry rollups but would mangle full chat-history rendering\n * in the HQ Console once `rawContent` is enabled \u2014 messages and tool outputs\n * routinely exceed it. Applied publisher-side AND at the server's re-redaction\n * so both hops agree.\n */\nexport const HQ_TRANSCRIPT_TEXT_CAP = 16_000;\n\nexport interface HqClientIdentity {\n clientId: string;\n kind: HqClientKind;\n version?: string;\n machineId: string;\n hostname?: string;\n pid?: number;\n startedAt: string;\n}\n\nexport interface HqProjectIdentity {\n projectId: string;\n projectRoot: string;\n projectName: string;\n gitRemote?: string;\n gitBranch?: string;\n machineId: string;\n workspaceKind: HqWorkspaceKind;\n}\n\nexport interface HqClientHelloPayload {\n protocolVersion: HqProtocolVersion;\n client: HqClientIdentity;\n project: HqProjectIdentity;\n capabilities: readonly HqClientCapability[];\n /** Publisher-side policy already applied before telemetry leaves the client. */\n redactionPolicy?: HqRedactionPolicy;\n}\n\nexport interface HqWelcomePayload {\n type: 'hq.welcome';\n protocolVersion: HqProtocolVersion;\n serverTime: string;\n acceptedCapabilities: readonly HqClientCapability[];\n redactionPolicy: HqRedactionPolicy;\n}\n\nexport interface HqEventEnvelope<TPayload = unknown> {\n id: string;\n type: HqEventType | (string & {});\n schemaVersion: HqProtocolVersion;\n timestamp: string;\n clientId: string;\n projectId: string;\n sessionId?: string;\n runId?: string;\n seq: number;\n payload: TPayload;\n}\n\nexport type HqEventType =\n | 'client.hello'\n | 'client.heartbeat'\n | 'session.started'\n | 'session.status'\n | 'session.usage'\n | 'tool.started'\n | 'tool.completed'\n | 'fleet.snapshot'\n | 'fleet.event'\n | 'mailbox.snapshot'\n | 'mailbox.event'\n | 'worklist.snapshot'\n | 'git.snapshot'\n | 'agent.message'\n | 'agent.status'\n | 'session.snapshot'\n | 'session.transcript'\n | 'session.ended'\n | 'brain.event'\n | 'worktree.event'\n | 'mcp.health.snapshot'\n | 'mcp.operation';\n\nexport interface HqClientHeartbeatPayload {\n uptimeMs: number;\n activeSessionId?: string;\n activeRunId?: string;\n status: HqProjectStatus;\n activeSubagents?: number;\n queuedTasks?: number;\n}\n\nexport type HqSessionStatus = 'idle' | 'running' | 'paused' | 'completed' | 'failed';\n\nexport interface HqSessionStartedPayload {\n sessionId: string;\n provider?: string;\n model?: string;\n startedAt: string;\n}\n\nexport interface HqSessionStatusPayload {\n status: HqSessionStatus;\n phase?: string;\n message?: string;\n}\n\nexport interface HqUsagePayload {\n inputTokens?: number;\n outputTokens?: number;\n totalTokens?: number;\n costUsd?: number;\n durationMs?: number;\n}\n\nexport interface HqToolStartedPayload {\n toolName: string;\n capabilities?: readonly string[];\n risk?: string;\n inputSummary?: unknown;\n}\n\nexport interface HqToolCompletedPayload {\n toolName: string;\n status: 'success' | 'error' | 'timeout' | 'cancelled';\n durationMs: number;\n outputSummary?: unknown;\n errorClass?: string;\n}\n\nexport interface HqSubagentSummary {\n subagentId: string;\n role?: string;\n status: 'pending' | 'running' | 'idle' | 'completed' | 'failed' | 'stopped';\n task?: string;\n currentTool?: string;\n runtimeMs?: number;\n costUsd?: number;\n lastActivityAt?: string;\n}\n\nexport interface HqFleetSnapshotPayload {\n runId: string;\n activeSubagents: number;\n queuedTasks: number;\n completedTasks: number;\n failedTasks: number;\n totalCostUsd?: number;\n subagents: readonly HqSubagentSummary[];\n}\n\n/** Payload for `agent.message` events \u2014 a subagent's conversational output. */\nexport interface HqAgentMessagePayload {\n subagentId: string;\n agentName: string;\n content: string;\n kind: 'text' | 'thinking' | 'tool_use' | 'tool_result' | 'error' | 'status' | 'system';\n iteration: number;\n ts: string;\n toolName?: string;\n costUsd?: number;\n}\n\n/** Payload for `agent.status` events \u2014 a subagent's lifecycle transition. */\nexport interface HqAgentStatusPayload {\n subagentId: string;\n agentName: string;\n status:\n | 'spawned'\n | 'running'\n | 'completed'\n | 'failed'\n | 'timeout'\n | 'stopped'\n | 'budget_exhausted';\n ts: string;\n summary?: string;\n task?: string;\n}\n\nexport interface HqFleetEventPayload {\n runId: string;\n subagentId?: string;\n event: string;\n summary?: string;\n data?: unknown;\n}\n\n// \u2500\u2500 Brain decision telemetry \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n//\n// The Brain (decision layer) routes autonomous decisions through a three-tier\n// chain. These envelopes let the HQ command center observe decision requests,\n// answers, denials, ask-human escalations, and self-activated interventions\n// across every connected machine \u2014 without coupling HQ to the in-process\n// Brain. All payloads are plain serializable data (no closures); the rich\n// BrainDecisionRequest / BrainDecision shapes are forwarded as-is.\n\nexport type HqBrainEventKind =\n | 'decision_requested'\n | 'decision_answered'\n | 'decision_ask_human'\n | 'human_answered'\n | 'decision_denied'\n | 'intervention';\n\nexport interface HqBrainEventPayload {\n /** Which brain lifecycle event this is (mirrors the EventBus `brain.*` name suffix). */\n kind: HqBrainEventKind;\n /** The decision request id, when present (decision_request/answer/deny). */\n requestId?: string;\n /** Short human-readable question the brain was asked. */\n question?: string;\n /** The source that triggered the decision (e.g. 'autonomy', 'system'). */\n source?: string;\n /** Resolved risk tier, when known (e.g. 'low' | 'medium' | 'high'). */\n risk?: string;\n /** The chosen decision kind, when answered/denied (e.g. 'answer' | 'ask_human' | 'deny'). */\n decision?: string;\n /** Free-text rationale or answer payload, when present. */\n detail?: string;\n /** For `intervention`: the watched signal that engaged the brain. */\n interventionKind?: 'tool_failure_streak' | 'error_storm' | 'agent_stall' | 'file_churn';\n /** For `intervention`: true when a steer was actually delivered to the agent. */\n intervened?: boolean;\n /** Epoch milliseconds at which the event occurred. */\n at: number;\n}\n\n// \u2500\u2500 Worktree lifecycle telemetry \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n//\n// AutoPhase allocates one git worktree per phase so parallelizable phases run\n// isolated, then merges them back sequentially. These envelopes let HQ render\n// live build phase swim-lanes / DAG across every connected machine. All fields\n// are plain serializable data (the EventBus `worktree.*` payloads forwarded\n// with the type tag added).\n\nexport type HqWorktreeEventKind =\n | 'allocated'\n | 'committed'\n | 'merged'\n | 'conflict'\n | 'released'\n | 'failed';\n\nexport interface HqWorktreeEventPayload {\n /** Which worktree lifecycle event this is (mirrors `worktree.<kind>`). */\n kind: HqWorktreeEventKind;\n handleId: string;\n ownerId: string;\n ownerLabel?: string;\n slug?: string;\n branch?: string;\n baseBranch?: string;\n /** For `committed`: diff stats. */\n insertions?: number;\n deletions?: number;\n files?: number;\n sha?: string;\n /** For `merged`: whether the merge was a squash. */\n squash?: boolean;\n /** For `conflict`: the list of conflicting files. */\n conflictFiles?: readonly string[];\n /** For `released`: whether the worktree was kept (true) or pruned (false). */\n kept?: boolean;\n /** For `failed`: the error message. */\n error?: string;\n}\n\n// \u2500\u2500 Session telemetry (live terminals + full chat transcript) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n//\n// Every surface (tui / repl / webui / cli) streams its own live session state\n// and conversation transcript to HQ so the command center can render a true\n// machine \u2192 project \u2192 terminal \u2192 agent \u2192 full-history tree across every\n// connected machine \u2014 not just the one HQ happens to run on.\n\nexport type HqSessionLiveStatus = 'active' | 'idle' | 'closing' | 'stale';\n\nexport type HqSessionAgentLiveStatus = 'idle' | 'running' | 'streaming' | 'waiting_user' | 'error';\n\n/** A single live agent inside a session snapshot (mirrors SessionRegistry's AgentEntry). */\nexport interface HqSessionAgentSummary {\n id: string;\n name: string;\n /** UTC ISO timestamp when this agent/run started, when known. */\n startedAt?: string;\n status: HqSessionAgentLiveStatus;\n currentTool?: string;\n iterations: number;\n toolCalls: number;\n costUsd?: number;\n tokensIn?: number;\n tokensOut?: number;\n ctxPct?: number;\n model?: string;\n /** Throttled tail of the response currently streaming, when known. */\n partialText?: string;\n lastActivityAt: string;\n}\n\n/** Payload for `session.snapshot` \u2014 one connected terminal's live state. */\nexport interface HqSessionSnapshotPayload {\n sessionId: string;\n clientKind: HqClientKind;\n machineId: string;\n hostname?: string;\n pid?: number;\n projectId: string;\n projectName: string;\n projectRoot: string;\n gitBranch?: string;\n status: HqSessionLiveStatus;\n startedAt: string;\n lastActivityAt: string;\n agentCount: number;\n agents: readonly HqSessionAgentSummary[];\n}\n\nexport type HqTranscriptRole = 'user' | 'assistant' | 'thinking' | 'tool' | 'system' | 'error';\n\n/** One rendered conversation turn. Canonical shape shared by client streaming\n * and server-side JSONL replay so both planes agree. */\nexport interface HqTranscriptEntry {\n ts: string;\n role: HqTranscriptRole;\n text: string;\n tool?: string;\n /** Stringified tool input/arguments, for tool calls (shown alongside the result). */\n toolInput?: string;\n durationMs?: number;\n isError?: boolean;\n toolUseId?: string;\n /** Which agent/subagent produced this turn, when attribution is known. */\n agentId?: string;\n}\n\n/** Payload for `session.transcript` \u2014 an incremental batch of new turns. */\nexport interface HqTranscriptAppendPayload {\n sessionId: string;\n /** Monotonic sequence index of the FIRST entry in this batch within the session. */\n fromSeq: number;\n entries: readonly HqTranscriptEntry[];\n}\n\n/** Payload for `session.ended` \u2014 a terminal closed. */\nexport interface HqSessionEndedPayload {\n sessionId: string;\n endedAt: string;\n}\n\n/** A physical machine, aggregated by HQ from connected clients' machineId. */\nexport interface HqMachineRecord {\n machineId: string;\n hostname?: string;\n clientCount: number;\n sessionCount: number;\n agentCount: number;\n projectIds: readonly string[];\n lastActivityAt: string;\n}\n\nexport type HqMailboxMessageType =\n | 'note'\n | 'ask'\n | 'assign'\n | 'steer'\n | 'btw'\n | 'broadcast'\n | 'status'\n | 'result'\n | 'review'\n | 'control';\n\nexport type HqMailboxPriority = 'low' | 'normal' | 'high';\n\nexport type HqMailboxAgentStatus =\n | 'idle'\n | 'running'\n | 'streaming'\n | 'waiting_user'\n | 'error'\n | 'offline';\n\nexport interface HqMailboxMessageSummary {\n mailId: string; // unique UUID per message record, used for deduplication\n messageId: string;\n from: string;\n to: string;\n type: HqMailboxMessageType;\n subject: string;\n priority: HqMailboxPriority;\n timestamp: string;\n replyTo?: string;\n senderSessionId?: string;\n completed: boolean;\n completedBy?: string;\n completedAt?: string;\n unreadCount?: number;\n readCount?: number;\n hasBody: boolean;\n bodyPreview?: string;\n outcomePreview?: string;\n task?: {\n taskId?: string;\n agentRole?: string;\n agentName?: string;\n status?: 'pending' | 'in_progress' | 'completed' | 'failed';\n };\n}\n\nexport interface HqMailboxAgentSummary {\n agentId: string;\n name: string;\n role?: string;\n sessionId: string;\n status: HqMailboxAgentStatus;\n currentTool?: string;\n currentTask?: string;\n iterations: number;\n toolCalls: number;\n lastActivityAt: string;\n lastSeenAt: string;\n online: boolean;\n source?: 'cli' | 'webui' | 'mcp' | 'acp' | 'http';\n}\n\nexport interface HqMailboxSnapshotPayload {\n mailboxId: string;\n scope: 'project' | 'global';\n messages: readonly HqMailboxMessageSummary[];\n agents: readonly HqMailboxAgentSummary[];\n totals: {\n messages: number;\n unread: number;\n incomplete: number;\n highPriority: number;\n onlineAgents: number;\n };\n}\n\nexport interface HqMailboxEventPayload {\n mailboxId: string;\n action:\n | 'message.sent'\n | 'message.read'\n | 'message.completed'\n | 'message.updated'\n | 'agent.registered'\n | 'agent.heartbeat'\n | 'agent.offline'\n | 'agent.deregistered';\n message?: HqMailboxMessageSummary;\n agent?: HqMailboxAgentSummary;\n summary?: string;\n}\n\nexport interface HqWorklistSnapshotPayload {\n todos?: HqWorklistCounts;\n tasks?: HqWorklistCounts;\n plans?: HqWorklistCounts;\n activeItem?: string;\n}\n\nexport interface HqWorklistCounts {\n total: number;\n pending: number;\n inProgress: number;\n completed: number;\n failed?: number;\n}\n\nexport interface HqGitSnapshotPayload {\n branch?: string;\n dirtyFiles?: number;\n stagedFiles?: number;\n ahead?: number;\n behind?: number;\n}\n\nexport interface HqClientRecord {\n clientId: string;\n kind: HqClientKind;\n machineId: string;\n hostname?: string;\n pid?: number;\n version?: string;\n connected: boolean;\n connectedAt?: string;\n lastSeenAt: string;\n projectId: string;\n sessionId?: string;\n capabilities: readonly HqClientCapability[];\n}\n\nexport interface HqProjectRecord {\n projectId: string;\n projectName: string;\n projectRootDisplay: string;\n machineIds: readonly string[];\n gitBranch?: string;\n activeClients: number;\n activeSessions: number;\n activeSubagents: number;\n totalCostUsd: number;\n lastActivityAt: string;\n status: HqProjectStatus;\n}\n\nexport interface HqSessionSummary {\n sessionId: string;\n projectId: string;\n clientId: string;\n status: HqSessionStatus;\n provider?: string;\n model?: string;\n startedAt?: string;\n lastActivityAt: string;\n costUsd?: number;\n}\n\nexport interface HqFleetSummary {\n runId: string;\n projectId: string;\n clientId: string;\n activeSubagents: number;\n queuedTasks: number;\n completedTasks: number;\n failedTasks: number;\n totalCostUsd?: number;\n lastActivityAt: string;\n}\n\nexport interface HqMailboxSummary {\n mailboxId: string;\n projectId: string;\n scope: 'project' | 'global';\n messageCount: number;\n unreadCount: number;\n incompleteCount: number;\n highPriorityCount: number;\n onlineAgentCount: number;\n lastActivityAt: string;\n}\n\nexport interface HqMcpLatencySummary {\n count: number;\n lastMs?: number | undefined;\n minMs?: number | undefined;\n maxMs?: number | undefined;\n p50Ms?: number | undefined;\n p95Ms?: number | undefined;\n}\n\nexport interface HqMcpFailureCounts {\n transport: number;\n protocol: number;\n tool: number;\n}\n\nexport interface HqMcpHealthCheck {\n name: string;\n passed: boolean;\n value?: number | undefined;\n threshold?: number | undefined;\n}\n\nexport type HqMcpHealthState =\n | 'disabled'\n | 'dormant'\n | 'connecting'\n | 'healthy'\n | 'degraded'\n | 'failed';\n\nexport type HqMcpConnectionState =\n | 'idle'\n | 'dormant'\n | 'connecting'\n | 'connected'\n | 'reconnecting'\n | 'disconnected'\n | 'failed';\n\nexport interface HqMcpServerHealth {\n name: string;\n projectId: string;\n clientId: string;\n connectionState: HqMcpConnectionState;\n healthState: HqMcpHealthState;\n lastSuccessAt?: string | undefined;\n lastFailureAt?: string | undefined;\n lastFailureKind?: 'transport' | 'protocol' | 'tool' | undefined;\n consecutiveFailures: number;\n failures: HqMcpFailureCounts;\n reconnectCount: number;\n wakeCount: number;\n sleepCount: number;\n restartCount: number;\n connectionLatency: HqMcpLatencySummary;\n discoveryLatency: HqMcpLatencySummary;\n callLatency: HqMcpLatencySummary;\n inFlightCalls: number;\n peakInFlightCalls: number;\n healthChecks: HqMcpHealthCheck[];\n}\n\nexport interface HqMcpHealthSnapshotPayload {\n servers: HqMcpServerHealth[];\n}\n\nexport interface HqMcpOperationPayload {\n operation: Record<string, unknown>;\n servers: HqMcpServerHealth[];\n}\n\nexport interface HqSnapshot {\n generatedAt: string;\n clients: readonly HqClientRecord[];\n projects: readonly HqProjectRecord[];\n sessions: readonly HqSessionSummary[];\n fleets: readonly HqFleetSummary[];\n mailboxes: readonly HqMailboxSummary[];\n /** Physical machines aggregated from connected clients (optional, additive). */\n machines?: readonly HqMachineRecord[];\n /** Live terminal sessions with their agents \u2014 the spine of the fleet tree. */\n liveSessions?: readonly HqSessionSnapshotPayload[];\n /** Latest operational health for each MCP server reported by any connected client. */\n mcpServers?: readonly HqMcpServerHealth[];\n totals: {\n activeProjects: number;\n activeClients: number;\n activeSessions: number;\n activeSubagents: number;\n unreadMailboxMessages: number;\n incompleteMailboxMessages: number;\n totalCostUsd: number;\n /** Distinct physical machines currently connected. */\n activeMachines?: number;\n /** Total live agents across all sessions. */\n activeAgents?: number;\n };\n}\n\nexport interface HqBrowserSnapshotMessage {\n type: 'hq.snapshot';\n snapshot: HqSnapshot;\n}\n\nexport interface HqBrowserEventMessage<TPayload = unknown> {\n type: 'hq.event';\n event: HqEventEnvelope<TPayload>;\n}\n\nexport interface HqAlertMessage {\n type: 'hq.alert';\n severity: 'info' | 'warn' | 'error';\n message: string;\n timestamp: string;\n}\n\nexport interface HqHeartbeatMessage {\n type: 'hq.heartbeat';\n serverTime: string;\n}\n\nexport type HqBrowserMessage =\n | HqBrowserSnapshotMessage\n | HqBrowserEventMessage\n | HqAlertMessage\n | HqHeartbeatMessage;\n\nexport interface HqClientHelloMessage {\n type: 'client.hello';\n payload: HqClientHelloPayload;\n}\n\nexport interface HqClientEventMessage<TPayload = unknown> {\n type: 'client.event';\n event: HqEventEnvelope<TPayload>;\n}\n\nexport interface HqClientCommandPollMessage {\n type: 'client.command_poll';\n clientId: string;\n projectId: string;\n afterCommandId?: string;\n limit?: number;\n}\n\nexport interface HqClientCommandAckMessage {\n type: 'client.command_ack';\n clientId: string;\n projectId: string;\n commandId: string;\n status: 'accepted' | 'completed' | 'failed' | 'rejected';\n message?: string;\n}\n\nexport interface HqQueuedCommand {\n commandId: string;\n type: string;\n createdAt: string;\n payload: unknown;\n requiresAck?: boolean;\n}\n\nexport interface HqServerCommandBatchMessage {\n type: 'hq.command_batch';\n commands: readonly HqQueuedCommand[];\n}\n\nexport type HqClientMessage =\n | HqClientHelloMessage\n | HqClientEventMessage\n | HqClientCommandPollMessage\n | HqClientCommandAckMessage;\n\nexport type HqServerMessage = HqServerCommandBatchMessage | HqWelcomePayload;\n\n/**\n * Discriminated parse result for {@link parseHqFrame}. The `reason` field\n * is only present when `ok` is `false`; consumers should narrow on `ok`\n * before accessing `frame` or `reason`.\n */\nexport type HqParseResult =\n | { ok: true; frame: HqClientMessage }\n | { ok: false; reason: 'invalid-json' | 'unknown-type' | 'malformed' };\n\n/** Known client \u2192 server frame `type` discriminators. */\nconst KNOWN_HQ_CLIENT_FRAME_TYPES = new Set<HqClientMessage['type']>([\n 'client.hello',\n 'client.event',\n 'client.command_poll',\n 'client.command_ack',\n]);\n\nconst HQ_CLIENT_KINDS = new Set<HqClientKind>(['tui', 'repl', 'webui', 'cli', 'unknown']);\nconst HQ_WORKSPACE_KINDS = new Set<HqWorkspaceKind>(['git', 'directory', 'unknown']);\nconst HQ_CLIENT_CAPABILITIES = new Set<HqClientCapability>([\n 'telemetry.publish',\n 'session.summary',\n 'fleet.summary',\n 'mailbox.summary',\n 'control.receive',\n]);\nconst HQ_COMMAND_ACK_STATUSES = new Set<HqClientCommandAckMessage['status']>([\n 'accepted',\n 'completed',\n 'failed',\n 'rejected',\n]);\n\n/** Top-level object + string `type` guard. */\nfunction hasStringType(x: unknown): x is { type: string } {\n return typeof x === 'object' && x !== null && typeof (x as { type?: unknown }).type === 'string';\n}\n\nfunction isHqClientIdentity(x: unknown): x is HqClientIdentity {\n if (typeof x !== 'object' || x === null) return false;\n const v = x as Record<string, unknown>;\n return (\n typeof v.clientId === 'string' &&\n typeof v.kind === 'string' &&\n HQ_CLIENT_KINDS.has(v.kind as HqClientKind) &&\n typeof v.machineId === 'string' &&\n typeof v.startedAt === 'string'\n );\n}\n\nfunction isHqProjectIdentity(x: unknown): x is HqProjectIdentity {\n if (typeof x !== 'object' || x === null) return false;\n const v = x as Record<string, unknown>;\n return (\n typeof v.projectId === 'string' &&\n typeof v.projectRoot === 'string' &&\n typeof v.projectName === 'string' &&\n typeof v.machineId === 'string' &&\n typeof v.workspaceKind === 'string' &&\n HQ_WORKSPACE_KINDS.has(v.workspaceKind as HqWorkspaceKind)\n );\n}\n\nfunction isHqRedactionPolicy(x: unknown): x is HqRedactionPolicy {\n if (typeof x !== 'object' || x === null) return false;\n const v = x as Record<string, unknown>;\n return (\n typeof v.rawContent === 'boolean' &&\n (v.toolArgs === 'none' || v.toolArgs === 'summary' || v.toolArgs === 'redacted' || v.toolArgs === 'full') &&\n (v.paths === 'none' ||\n v.paths === 'project-relative' ||\n v.paths === 'redacted' ||\n v.paths === 'full')\n );\n}\n\nfunction isHqClientHelloPayload(x: unknown): x is HqClientHelloPayload {\n if (typeof x !== 'object' || x === null) return false;\n const v = x as Record<string, unknown>;\n return (\n typeof v.protocolVersion === 'number' &&\n isHqClientIdentity(v.client) &&\n isHqProjectIdentity(v.project) &&\n Array.isArray(v.capabilities) &&\n v.capabilities.every(\n (capability) =>\n typeof capability === 'string' &&\n HQ_CLIENT_CAPABILITIES.has(capability as HqClientCapability),\n ) &&\n (v.redactionPolicy === undefined || isHqRedactionPolicy(v.redactionPolicy))\n );\n}\n\nfunction isHqEventEnvelope(x: unknown): x is HqEventEnvelope {\n if (typeof x !== 'object' || x === null) return false;\n const v = x as Record<string, unknown>;\n return (\n typeof v.id === 'string' &&\n typeof v.type === 'string' &&\n v.schemaVersion === HQ_PROTOCOL_VERSION &&\n typeof v.timestamp === 'string' &&\n typeof v.clientId === 'string' &&\n typeof v.projectId === 'string' &&\n Number.isSafeInteger(v.seq) &&\n (v.seq as number) >= 0 &&\n Object.hasOwn(v, 'payload')\n );\n}\n\nfunction isHqClientCommandPollMessage(x: unknown): x is HqClientCommandPollMessage {\n if (typeof x !== 'object' || x === null) return false;\n const v = x as Record<string, unknown>;\n return (\n typeof v.clientId === 'string' &&\n typeof v.projectId === 'string' &&\n (v.afterCommandId === undefined || typeof v.afterCommandId === 'string') &&\n (v.limit === undefined ||\n (Number.isSafeInteger(v.limit) && (v.limit as number) > 0 && (v.limit as number) <= 200))\n );\n}\n\nfunction isHqClientCommandAckMessage(x: unknown): x is HqClientCommandAckMessage {\n if (typeof x !== 'object' || x === null) return false;\n const v = x as Record<string, unknown>;\n return (\n typeof v.clientId === 'string' &&\n typeof v.projectId === 'string' &&\n typeof v.commandId === 'string' &&\n typeof v.status === 'string' &&\n HQ_COMMAND_ACK_STATUSES.has(v.status as HqClientCommandAckMessage['status']) &&\n (v.message === undefined || typeof v.message === 'string')\n );\n}\n\n/**\n * Strictly parse a raw client \u2192 server frame into a {@link HqParseResult}.\n *\n * Validates, in order:\n * 1. JSON syntax (`invalid-json` on failure)\n * 2. Top-level object with string `type` discriminator\n * 3. `type` is one of {@link HqClientMessage} union members (`unknown-type`)\n * 4. Per-type field-shape presence checks (`malformed` on failure)\n *\n * On success, `frame` is narrowed to {@link HqClientMessage} and consumers\n * can switch on `frame.type` for type-safe access to per-union-member\n * fields without `as` casts.\n */\nexport function parseHqFrame(raw: string | Buffer): HqParseResult {\n let parsed: unknown;\n try {\n parsed = JSON.parse(typeof raw === 'string' ? raw : raw.toString('utf8'));\n } catch {\n return { ok: false, reason: 'invalid-json' };\n }\n\n if (!hasStringType(parsed)) {\n return { ok: false, reason: 'malformed' };\n }\n const obj = parsed as { type: string } & Record<string, unknown>;\n\n if (!KNOWN_HQ_CLIENT_FRAME_TYPES.has(obj.type as HqClientMessage['type'])) {\n return { ok: false, reason: 'unknown-type' };\n }\n\n switch (obj.type as HqClientMessage['type']) {\n case 'client.hello':\n if (!isHqClientHelloPayload(obj.payload)) {\n return { ok: false, reason: 'malformed' };\n }\n return { ok: true, frame: { type: 'client.hello', payload: obj.payload } };\n case 'client.event':\n if (!isHqEventEnvelope(obj.event)) {\n return { ok: false, reason: 'malformed' };\n }\n return { ok: true, frame: { type: 'client.event', event: obj.event } };\n case 'client.command_poll':\n if (!isHqClientCommandPollMessage(obj)) {\n return { ok: false, reason: 'malformed' };\n }\n return {\n ok: true,\n frame: {\n type: 'client.command_poll',\n clientId: obj.clientId,\n projectId: obj.projectId,\n ...(typeof obj.afterCommandId === 'string'\n ? { afterCommandId: obj.afterCommandId }\n : {}),\n ...(typeof obj.limit === 'number' ? { limit: obj.limit } : {}),\n },\n };\n case 'client.command_ack':\n if (!isHqClientCommandAckMessage(obj)) {\n return { ok: false, reason: 'malformed' };\n }\n return {\n ok: true,\n frame: {\n type: 'client.command_ack',\n clientId: obj.clientId,\n projectId: obj.projectId,\n commandId: obj.commandId,\n status: obj.status as HqClientCommandAckMessage['status'],\n ...(typeof obj.message === 'string' ? { message: obj.message } : {}),\n },\n };\n default: {\n // Unreachable: KNOWN_HQ_CLIENT_FRAME_TYPES membership guarantees\n // `obj.type` is one of the cases above. Return `unknown-type` defensively\n // to satisfy the return type if a future HqClientMessage union member\n // is added without updating this switch.\n const _exhaustive: never = obj.type as never;\n return _exhaustive;\n }\n }\n}\n\n/** Known `client.event` envelope event types whose payload shape we validate. */\nconst KNOWN_HQ_EVENT_PAYLOAD_TYPES = new Set<string>([\n 'mailbox.snapshot',\n 'mailbox.event',\n 'session.snapshot',\n 'session.transcript',\n 'session.ended',\n 'fleet.snapshot',\n 'fleet.event',\n 'brain.event',\n 'worktree.event',\n 'tool.started',\n 'tool.completed',\n 'session.usage',\n 'client.heartbeat',\n 'mcp.health.snapshot',\n 'mcp.operation',\n]);\n\nfunction isHqMcpLatencySummary(x: unknown): x is HqMcpLatencySummary {\n if (typeof x !== 'object' || x === null) return false;\n const v = x as Record<string, unknown>;\n return (\n typeof v.count === 'number' &&\n (v.lastMs === undefined || typeof v.lastMs === 'number') &&\n (v.minMs === undefined || typeof v.minMs === 'number') &&\n (v.maxMs === undefined || typeof v.maxMs === 'number') &&\n (v.p50Ms === undefined || typeof v.p50Ms === 'number') &&\n (v.p95Ms === undefined || typeof v.p95Ms === 'number')\n );\n}\n\nfunction isHqMcpFailureCounts(x: unknown): x is HqMcpFailureCounts {\n if (typeof x !== 'object' || x === null) return false;\n const v = x as Record<string, unknown>;\n return (\n typeof v.transport === 'number' &&\n typeof v.protocol === 'number' &&\n typeof v.tool === 'number'\n );\n}\n\nfunction isHqMcpHealthCheck(x: unknown): x is HqMcpHealthCheck {\n if (typeof x !== 'object' || x === null) return false;\n const v = x as Record<string, unknown>;\n return (\n typeof v.name === 'string' &&\n typeof v.passed === 'boolean' &&\n (v.value === undefined || typeof v.value === 'number') &&\n (v.threshold === undefined || typeof v.threshold === 'number')\n );\n}\n\nconst HQ_MCP_HEALTH_STATES = new Set<string>([\n 'disabled',\n 'dormant',\n 'connecting',\n 'healthy',\n 'degraded',\n 'failed',\n]);\n\nconst HQ_MCP_CONNECTION_STATES = new Set<string>([\n 'idle',\n 'dormant',\n 'connecting',\n 'connected',\n 'reconnecting',\n 'disconnected',\n 'failed',\n]);\n\nfunction isHqMcpServerHealth(x: unknown): x is HqMcpServerHealth {\n if (typeof x !== 'object' || x === null) return false;\n const v = x as Record<string, unknown>;\n return (\n typeof v.name === 'string' &&\n typeof v.projectId === 'string' &&\n typeof v.clientId === 'string' &&\n typeof v.connectionState === 'string' &&\n HQ_MCP_CONNECTION_STATES.has(v.connectionState) &&\n typeof v.healthState === 'string' &&\n HQ_MCP_HEALTH_STATES.has(v.healthState) &&\n (v.lastSuccessAt === undefined || typeof v.lastSuccessAt === 'string') &&\n (v.lastFailureAt === undefined || typeof v.lastFailureAt === 'string') &&\n (v.lastFailureKind === undefined ||\n v.lastFailureKind === 'transport' ||\n v.lastFailureKind === 'protocol' ||\n v.lastFailureKind === 'tool') &&\n typeof v.consecutiveFailures === 'number' &&\n isHqMcpFailureCounts(v.failures) &&\n typeof v.reconnectCount === 'number' &&\n typeof v.wakeCount === 'number' &&\n typeof v.sleepCount === 'number' &&\n typeof v.restartCount === 'number' &&\n isHqMcpLatencySummary(v.connectionLatency) &&\n isHqMcpLatencySummary(v.discoveryLatency) &&\n isHqMcpLatencySummary(v.callLatency) &&\n typeof v.inFlightCalls === 'number' &&\n typeof v.peakInFlightCalls === 'number' &&\n Array.isArray(v.healthChecks) &&\n v.healthChecks.every(isHqMcpHealthCheck)\n );\n}\n\nfunction isHqMcpHealthSnapshotPayload(x: unknown): x is HqMcpHealthSnapshotPayload {\n if (typeof x !== 'object' || x === null) return false;\n const v = x as Record<string, unknown>;\n return Array.isArray(v.servers) && v.servers.every(isHqMcpServerHealth);\n}\n\nfunction isHqMcpOperationPayload(x: unknown): x is HqMcpOperationPayload {\n if (typeof x !== 'object' || x === null) return false;\n const v = x as Record<string, unknown>;\n return (\n typeof v.operation === 'object' &&\n v.operation !== null &&\n Array.isArray(v.servers) &&\n v.servers.every(isHqMcpServerHealth)\n );\n}\n\nfunction isHqMailboxMessageSummary(x: unknown): x is HqMailboxMessageSummary {\n if (typeof x !== 'object' || x === null) return false;\n const v = x as Record<string, unknown>;\n return (\n typeof v.messageId === 'string' &&\n typeof v.from === 'string' &&\n typeof v.to === 'string' &&\n typeof v.subject === 'string' &&\n typeof v.priority === 'string' &&\n typeof v.timestamp === 'string' &&\n typeof v.completed === 'boolean' &&\n typeof v.hasBody === 'boolean'\n );\n}\n\nfunction isHqMailboxAgentSummary(x: unknown): x is HqMailboxAgentSummary {\n if (typeof x !== 'object' || x === null) return false;\n const v = x as Record<string, unknown>;\n return (\n typeof v.agentId === 'string' &&\n typeof v.name === 'string' &&\n typeof v.sessionId === 'string' &&\n typeof v.status === 'string' &&\n typeof v.iterations === 'number' &&\n typeof v.toolCalls === 'number' &&\n typeof v.lastActivityAt === 'string' &&\n typeof v.lastSeenAt === 'string' &&\n typeof v.online === 'boolean'\n );\n}\n\nfunction isHqMailboxSnapshotPayload(x: unknown): x is HqMailboxSnapshotPayload {\n if (typeof x !== 'object' || x === null) return false;\n const v = x as Record<string, unknown>;\n if (\n typeof v.mailboxId !== 'string' ||\n (v.scope !== 'project' && v.scope !== 'global') ||\n !Array.isArray(v.messages) ||\n !Array.isArray(v.agents) ||\n typeof v.totals !== 'object' ||\n v.totals === null\n ) {\n return false;\n }\n const totals = v.totals as Record<string, unknown>;\n if (\n typeof totals.messages !== 'number' ||\n typeof totals.unread !== 'number' ||\n typeof totals.incomplete !== 'number' ||\n typeof totals.highPriority !== 'number' ||\n typeof totals.onlineAgents !== 'number'\n ) {\n return false;\n }\n for (const message of v.messages) {\n if (!isHqMailboxMessageSummary(message)) return false;\n }\n for (const agent of v.agents) {\n if (!isHqMailboxAgentSummary(agent)) return false;\n }\n return true;\n}\n\nconst HQ_MAILBOX_EVENT_ACTIONS = new Set<string>([\n 'message.sent',\n 'message.read',\n 'message.completed',\n 'message.updated',\n 'agent.registered',\n 'agent.heartbeat',\n 'agent.offline',\n 'agent.deregistered',\n]);\n\nfunction isHqMailboxEventPayload(x: unknown): x is HqMailboxEventPayload {\n if (typeof x !== 'object' || x === null) return false;\n const v = x as Record<string, unknown>;\n if (typeof v.mailboxId !== 'string') return false;\n if (typeof v.action !== 'string' || !HQ_MAILBOX_EVENT_ACTIONS.has(v.action)) return false;\n // `message` and `agent` are optional but, when present, must satisfy\n // their respective shape guard so a downstream consumer can rely on\n // the typed fields.\n if (v.message !== undefined && !isHqMailboxMessageSummary(v.message)) return false;\n if (v.agent !== undefined && !isHqMailboxAgentSummary(v.agent)) return false;\n return true;\n}\n\nconst HQ_SESSION_AGENT_STATUSES = new Set<string>([\n 'idle',\n 'running',\n 'streaming',\n 'waiting_user',\n 'error',\n]);\n\nfunction isHqSessionAgentSummary(x: unknown): x is HqSessionAgentSummary {\n if (typeof x !== 'object' || x === null) return false;\n const v = x as Record<string, unknown>;\n return (\n typeof v.id === 'string' &&\n typeof v.name === 'string' &&\n typeof v.status === 'string' &&\n HQ_SESSION_AGENT_STATUSES.has(v.status) &&\n typeof v.iterations === 'number' &&\n typeof v.toolCalls === 'number' &&\n typeof v.lastActivityAt === 'string'\n );\n}\n\nconst HQ_SESSION_STATUSES = new Set<string>(['active', 'idle', 'closing', 'stale']);\n\nfunction isHqSessionSnapshotPayload(x: unknown): x is HqSessionSnapshotPayload {\n if (typeof x !== 'object' || x === null) return false;\n const v = x as Record<string, unknown>;\n if (\n typeof v.sessionId !== 'string' ||\n typeof v.clientKind !== 'string' ||\n typeof v.machineId !== 'string' ||\n typeof v.projectId !== 'string' ||\n typeof v.projectName !== 'string' ||\n typeof v.projectRoot !== 'string' ||\n typeof v.status !== 'string' ||\n !HQ_SESSION_STATUSES.has(v.status) ||\n typeof v.startedAt !== 'string' ||\n typeof v.lastActivityAt !== 'string' ||\n typeof v.agentCount !== 'number' ||\n !Array.isArray(v.agents)\n ) {\n return false;\n }\n for (const agent of v.agents) {\n if (!isHqSessionAgentSummary(agent)) return false;\n }\n return true;\n}\n\nconst HQ_TRANSCRIPT_ROLES = new Set<string>([\n 'user',\n 'assistant',\n 'thinking',\n 'tool',\n 'system',\n 'error',\n]);\n\nfunction isHqTranscriptEntry(x: unknown): x is HqTranscriptEntry {\n if (typeof x !== 'object' || x === null) return false;\n const v = x as Record<string, unknown>;\n return (\n typeof v.ts === 'string' &&\n typeof v.role === 'string' &&\n HQ_TRANSCRIPT_ROLES.has(v.role) &&\n typeof v.text === 'string'\n );\n}\n\nfunction isHqTranscriptAppendPayload(x: unknown): x is HqTranscriptAppendPayload {\n if (typeof x !== 'object' || x === null) return false;\n const v = x as Record<string, unknown>;\n if (\n typeof v.sessionId !== 'string' ||\n typeof v.fromSeq !== 'number' ||\n !Array.isArray(v.entries)\n ) {\n return false;\n }\n for (const entry of v.entries) {\n if (!isHqTranscriptEntry(entry)) return false;\n }\n return true;\n}\n\nfunction isHqSessionEndedPayload(x: unknown): x is HqSessionEndedPayload {\n if (typeof x !== 'object' || x === null) return false;\n const v = x as Record<string, unknown>;\n return typeof v.sessionId === 'string' && typeof v.endedAt === 'string';\n}\n\nconst HQ_FLEET_SUBAGENT_STATUS = new Set<string>([\n 'pending',\n 'running',\n 'idle',\n 'completed',\n 'failed',\n 'stopped',\n]);\n\nfunction isHqSubagentSummary(x: unknown): x is HqSubagentSummary {\n if (typeof x !== 'object' || x === null) return false;\n const v = x as Record<string, unknown>;\n return (\n typeof v.subagentId === 'string' &&\n typeof v.status === 'string' &&\n HQ_FLEET_SUBAGENT_STATUS.has(v.status)\n );\n}\n\nfunction isHqFleetSnapshotPayload(x: unknown): x is HqFleetSnapshotPayload {\n if (typeof x !== 'object' || x === null) return false;\n const v = x as Record<string, unknown>;\n if (\n typeof v.runId !== 'string' ||\n typeof v.activeSubagents !== 'number' ||\n typeof v.queuedTasks !== 'number' ||\n typeof v.completedTasks !== 'number' ||\n typeof v.failedTasks !== 'number' ||\n !Array.isArray(v.subagents)\n ) {\n return false;\n }\n for (const s of v.subagents) {\n if (!isHqSubagentSummary(s)) return false;\n }\n return true;\n}\n\nfunction isHqFleetEventPayload(x: unknown): x is HqFleetEventPayload {\n if (typeof x !== 'object' || x === null) return false;\n const v = x as Record<string, unknown>;\n return typeof v.runId === 'string' && typeof v.event === 'string';\n}\n\nconst HQ_BRAIN_EVENT_KINDS = new Set<string>([\n 'decision_requested',\n 'decision_answered',\n 'decision_ask_human',\n 'human_answered',\n 'decision_denied',\n 'intervention',\n]);\n\nfunction isHqBrainEventPayload(x: unknown): x is HqBrainEventPayload {\n if (typeof x !== 'object' || x === null) return false;\n const v = x as Record<string, unknown>;\n if (typeof v.kind !== 'string' || !HQ_BRAIN_EVENT_KINDS.has(v.kind)) return false;\n if (typeof v.at !== 'number') return false;\n return true;\n}\n\nconst HQ_WORKTREE_EVENT_KINDS = new Set<string>([\n 'allocated',\n 'committed',\n 'merged',\n 'conflict',\n 'released',\n 'failed',\n]);\n\nfunction isHqWorktreeEventPayload(x: unknown): x is HqWorktreeEventPayload {\n if (typeof x !== 'object' || x === null) return false;\n const v = x as Record<string, unknown>;\n if (typeof v.kind !== 'string' || !HQ_WORKTREE_EVENT_KINDS.has(v.kind)) return false;\n if (typeof v.handleId !== 'string' || typeof v.ownerId !== 'string') return false;\n return true;\n}\n\nfunction isHqToolStartedPayload(x: unknown): x is HqToolStartedPayload {\n if (typeof x !== 'object' || x === null) return false;\n const v = x as Record<string, unknown>;\n return typeof v.toolName === 'string';\n}\n\nfunction isHqToolCompletedPayload(x: unknown): x is HqToolCompletedPayload {\n if (typeof x !== 'object' || x === null) return false;\n const v = x as Record<string, unknown>;\n return (\n typeof v.toolName === 'string' &&\n typeof v.status === 'string' &&\n typeof v.durationMs === 'number'\n );\n}\n\nfunction isHqUsagePayload(x: unknown): x is HqUsagePayload {\n if (typeof x !== 'object' || x === null) return false;\n // HqUsagePayload has all-optional numeric fields; accept any object so the\n // cost signal is never dropped on a partial payload, but require it be a\n // plain object (not array/null) to keep the downstream typed.\n return !Array.isArray(x);\n}\n\nfunction isHqClientHeartbeatPayload(x: unknown): x is HqClientHeartbeatPayload {\n if (typeof x !== 'object' || x === null || Array.isArray(x)) return false;\n const v = x as Record<string, unknown>;\n return (\n typeof v.uptimeMs === 'number' &&\n (v.activeSessionId === undefined || typeof v.activeSessionId === 'string') &&\n (v.activeRunId === undefined || typeof v.activeRunId === 'string') &&\n typeof v.status === 'string' &&\n (v.status === 'active' ||\n v.status === 'idle' ||\n v.status === 'stale' ||\n v.status === 'error') &&\n (v.activeSubagents === undefined || typeof v.activeSubagents === 'number') &&\n (v.queuedTasks === undefined || typeof v.queuedTasks === 'number')\n );\n}\n\n/**\n * Validate the `payload` field of a {@link HqEventEnvelope} for known\n * event types. Returns `{ ok: true, payload }` with a narrowed payload\n * type when the event type has a registered shape guard and the payload\n * matches it; `{ ok: true, payload: unknown }` for event types that the\n * server does not yet validate; or `{ ok: false, reason }` when the\n * payload fails the registered guard.\n *\n * Use this after {@link parseHqFrame} has produced a valid frame, when\n * the frame is `client.event` and the server is about to consume the\n * event payload.\n */\nexport type HqEventPayloadResult<T> =\n | { ok: true; payload: T }\n | { ok: false; reason: 'unknown-event-type' | 'malformed-payload' };\n\nexport function parseHqEventPayload(\n eventType: string,\n payload: unknown,\n): HqEventPayloadResult<unknown> {\n if (!KNOWN_HQ_EVENT_PAYLOAD_TYPES.has(eventType)) {\n // Server does not validate this event type yet \u2014 pass it through\n // untyped so the publish pipeline is not blocked. Future events\n // can opt-in by adding their type + guard here.\n return { ok: true, payload };\n }\n switch (eventType) {\n case 'mailbox.snapshot':\n return isHqMailboxSnapshotPayload(payload)\n ? { ok: true, payload }\n : { ok: false, reason: 'malformed-payload' };\n case 'mailbox.event':\n return isHqMailboxEventPayload(payload)\n ? { ok: true, payload }\n : { ok: false, reason: 'malformed-payload' };\n case 'session.snapshot':\n return isHqSessionSnapshotPayload(payload)\n ? { ok: true, payload }\n : { ok: false, reason: 'malformed-payload' };\n case 'session.transcript':\n return isHqTranscriptAppendPayload(payload)\n ? { ok: true, payload }\n : { ok: false, reason: 'malformed-payload' };\n case 'session.ended':\n return isHqSessionEndedPayload(payload)\n ? { ok: true, payload }\n : { ok: false, reason: 'malformed-payload' };\n case 'fleet.snapshot':\n return isHqFleetSnapshotPayload(payload)\n ? { ok: true, payload }\n : { ok: false, reason: 'malformed-payload' };\n case 'fleet.event':\n return isHqFleetEventPayload(payload)\n ? { ok: true, payload }\n : { ok: false, reason: 'malformed-payload' };\n case 'brain.event':\n return isHqBrainEventPayload(payload)\n ? { ok: true, payload }\n : { ok: false, reason: 'malformed-payload' };\n case 'worktree.event':\n return isHqWorktreeEventPayload(payload)\n ? { ok: true, payload }\n : { ok: false, reason: 'malformed-payload' };\n case 'tool.started':\n return isHqToolStartedPayload(payload)\n ? { ok: true, payload }\n : { ok: false, reason: 'malformed-payload' };\n case 'tool.completed':\n return isHqToolCompletedPayload(payload)\n ? { ok: true, payload }\n : { ok: false, reason: 'malformed-payload' };\n case 'session.usage':\n return isHqUsagePayload(payload)\n ? { ok: true, payload }\n : { ok: false, reason: 'malformed-payload' };\n case 'client.heartbeat':\n return isHqClientHeartbeatPayload(payload)\n ? { ok: true, payload }\n : { ok: false, reason: 'malformed-payload' };\n case 'mcp.health.snapshot':\n return isHqMcpHealthSnapshotPayload(payload)\n ? { ok: true, payload }\n : { ok: false, reason: 'malformed-payload' };\n case 'mcp.operation':\n return isHqMcpOperationPayload(payload)\n ? { ok: true, payload }\n : { ok: false, reason: 'malformed-payload' };\n default: {\n const _exhaustive: never = eventType as never;\n return _exhaustive;\n }\n }\n}\n\nexport function createHqEventEnvelope<TPayload>(input: {\n id: string;\n type: HqEventType | (string & {});\n timestamp: string;\n clientId: string;\n projectId: string;\n seq: number;\n payload: TPayload;\n sessionId?: string;\n runId?: string;\n}): HqEventEnvelope<TPayload> {\n return {\n id: input.id,\n type: input.type,\n schemaVersion: HQ_PROTOCOL_VERSION,\n timestamp: input.timestamp,\n clientId: input.clientId,\n projectId: input.projectId,\n seq: input.seq,\n payload: input.payload,\n ...(input.sessionId !== undefined ? { sessionId: input.sessionId } : {}),\n ...(input.runId !== undefined ? { runId: input.runId } : {}),\n };\n}\n", "import type { SecretScrubber } from '../types/secret-scrubber.js';\n\ninterface Pattern {\n type: string;\n regex: RegExp;\n}\n\nconst PATTERNS: Pattern[] = [\n // Anchored at the start where possible so partial matches inside larger\n // strings don't trigger false positives.\n {\n type: 'anthropic_key',\n regex: /(?<![A-Za-z0-9])sk-ant-api\\d+-[A-Za-z0-9_-]{20,}(?![A-Za-z0-9])/g,\n },\n { type: 'openai_key', regex: /(?<![A-Za-z0-9])sk-(?:proj-)?[A-Za-z0-9_-]{20,}(?![A-Za-z0-9])/g },\n { type: 'github_pat', regex: /(?<![A-Za-z0-9])ghp_[A-Za-z0-9]{36,}(?![A-Za-z0-9])/g },\n { type: 'github_pat_v2', regex: /(?<![A-Za-z0-9])github_pat_[A-Za-z0-9_]{50,}(?![A-Za-z0-9])/g },\n { type: 'aws_access_key', regex: /(?<![A-Za-z0-9])AKIA[0-9A-Z]{16}(?![A-Za-z0-9])/g },\n { type: 'gcp_key', regex: /(?<![A-Za-z0-9])AIza[0-9A-Za-z_-]{35}(?![A-Za-z0-9])/g },\n { type: 'slack_token', regex: /(?<![A-Za-z0-9-])xox[abpos]-[A-Za-z0-9-]{10,}(?![A-Za-z0-9-])/g },\n {\n type: 'stripe_key',\n regex: /(?<![A-Za-z0-9])sk_(?:live|test)_[A-Za-z0-9]{24,}(?![A-Za-z0-9])/g,\n },\n {\n type: 'twilio_sid', regex: /(?<![A-Za-z0-9])AC[a-f0-9]{32}(?![A-Za-z0-9])/g,\n },\n {\n type: 'telegram_bot_token',\n // Telegram tokens are of the form bot<digits>:<alphanum> in URL paths\n regex: /\\/bot\\d+:[A-Za-z0-9_-]{20,}(?![A-Za-z0-9_-])/g,\n },\n {\n type: 'jwt',\n // Anchored: look for literal \"eyJ\" which is unambiguous for JWT header\n regex:\n /(?<![A-Za-z0-9/+=])eyJ[A-Za-z0-9_-]{10,}\\.[A-Za-z0-9_-]{10,}\\.[A-Za-z0-9_-]{10,}(?![A-Za-z0-9/+=])/g,\n },\n {\n type: 'private_key',\n // Anchored: start must be BEGIN, end must be END with no extra dashes after END\n regex:\n /(?:^|\\n)-----BEGIN (?:RSA|EC|OPENSSH|DSA|PGP)? ?PRIVATE KEY-----[\\s\\S]*?-----END[^-]*-----(?:\\n|$)/g,\n },\n { type: 'mongodb_uri', regex: /mongodb(?:\\+srv)?:\\/\\/[^\\s\"'`]+/g },\n { type: 'postgres_uri', regex: /postgres(?:ql)?:\\/\\/[^\\s\"'`]+/g },\n { type: 'mysql_uri', regex: /mysql:\\/\\/[^\\s\"'`]+/g },\n { type: 'redis_uri', regex: /redis:\\/\\/[^\\s\"'`]+/g },\n // AI/ML provider keys \u2014 modern LLM services with well-known prefixes\n {\n type: 'huggingface_token',\n // HuggingFace tokens: hf_ followed by 34 alphanumeric chars\n regex: /(?<![A-Za-z0-9])hf_[A-Za-z0-9]{34}(?![A-Za-z0-9])/g,\n },\n {\n type: 'replicate_token',\n // Replicate tokens: r8_ followed by 40+ alphanumeric chars\n regex: /(?<![A-Za-z0-9])r8_[A-Za-z0-9]{40,}(?![A-Za-z0-9])/g,\n },\n {\n type: 'perplexity_key',\n // Perplexity API keys: pplx- followed by 40+ alphanumeric chars\n regex: /(?<![A-Za-z0-9])pplx-[A-Za-z0-9]{40,}(?![A-Za-z0-9])/g,\n },\n {\n type: 'groq_key',\n // Groq API keys: gsk_ followed by 40+ alphanumeric chars\n regex: /(?<![A-Za-z0-9])gsk_[A-Za-z0-9]{40,}(?![A-Za-z0-9])/g,\n },\n {\n type: 'bearer_token',\n // Anchored with alternation instead of negative lookahead \u2014 avoids V8\n // backtracking risk on adversarial input. Bounded at 512 chars.\n // Min 12 chars: some OAuth providers issue shorter-lived tokens (< 20\n // chars). A 12-char base64 string has ~71 bits of entropy \u2014 above the\n // threshold where random strings are unlikely to produce false matches.\n // The trailing boundary is a NON-consuming lookahead: two adjacent bearer\n // tokens sharing a single delimiter (`Bearer a\u2026 Bearer b\u2026`) must both be\n // redacted. A consuming trailing delimiter would eat the separator the\n // next match needs for its leading anchor, leaking the second token.\n regex: /(?:^|[^A-Za-z0-9_.~+/-])Bearer\\s+[A-Za-z0-9._~+/-]{12,512}=*(?=$|[^A-Za-z0-9_.~+/-])/g,\n },\n {\n type: 'high_entropy_env',\n // Anchored with alternation instead of lookbehind to avoid backtracking.\n // Value bounded at 512 chars.\n // The trailing boundary is a NON-consuming lookahead so two secrets\n // separated by a single delimiter (one space OR one newline, e.g.\n // `printenv` / `.env` dumps: `API_KEY=\u2026 \\n SESSION_TOKEN=\u2026`) are BOTH\n // redacted. A consuming trailing `\\s` would swallow the separator the\n // next match needs for its leading anchor, so every other secret would\n // leak in plaintext.\n // The leading delimiter is CAPTURED (group 1) and re-emitted by the\n // replacement so the separator between adjacent secrets is preserved\n // rather than collapsed. Capture groups are therefore: 1=leading\n // delimiter, 2=key name, 3=value.\n regex: /(^|\\s)([A-Z_]{4,}(?:KEY|TOKEN|SECRET|PASSWORD|PWD))\\s*[:=]\\s*['\"]?([A-Za-z0-9_/+=-]{20,512})['\"]?(?=\\s|$)/g,\n },\n];\n\n/**\n * `high_entropy_env` is the one pattern that needs special replacement logic\n * (it preserves the key name), so it runs in its own pass. Every other pattern\n * is folded into a single combined regex. Derive the split by type rather than\n * by hard-coded indices so adding/removing a pattern can't silently drop one.\n */\nconst SIMPLE_PATTERNS = PATTERNS.filter((p) => p.type !== 'high_entropy_env');\n\n/**\n * Combined single-pass regex for all simple patterns. Each alternative is a\n * capturing group so the callback can determine which original pattern fired\n * (only one group is non-undefined at match time). Order matches SIMPLE_PATTERNS\n * (longer/more-specific prefixes first). Relies on each simple pattern source\n * containing no internal capturing groups \u2014 only `(?:...)` and lookarounds.\n */\nconst COMBINED_REGEX = new RegExp(SIMPLE_PATTERNS.map((p) => `(${p.regex.source})`).join('|'), 'g');\n\n/** Separate pattern for high_entropy_env (different replacement logic). */\nconst HIGH_ENTROPY_REGEX = PATTERNS.find((p) => p.type === 'high_entropy_env')!.regex;\n\n/**\n * Replacements for the combined patterns, parallel to SIMPLE_PATTERNS. The\n * combined-regex callback indexes into this with the matched group's position.\n */\nconst COMBINED_REPLACEMENTS = SIMPLE_PATTERNS.map((p) => `[REDACTED:${p.type}]`);\n\n/**\n * Per-chunk cap. Splits long inputs into 64 KB chunks to keep scrub() memory\n * bounded. Real scrub() inputs (LLM responses, tool outputs) are typically\n * much smaller; this cap handles edge cases without impacting normal usage.\n */\nconst SCRUB_CHUNK_BYTES = 64 * 1024;\n\n/**\n * Overlap window used to nudge a chunk boundary onto a safe separator so a\n * secret straddling the 64 KB cut isn't split in half (which would leave\n * neither half matching, leaking the secret verbatim).\n *\n * Sized above the longest BOUNDED credential pattern: `high_entropy_env`\n * caps its value at 512 chars (+ key name + quotes \u2248 560) and `bearer_token`\n * at 512; every prefix-keyed pattern is far shorter. Because all of these\n * patterns are whitespace-free, the first whitespace at/after the nominal cut\n * is guaranteed to sit *past the end* of any such secret \u2014 so snapping the\n * boundary forward to it keeps every bounded secret wholly inside one chunk.\n * 1 KB gives comfortable headroom over the 560-char worst case.\n */\nconst SCRUB_OVERLAP_BYTES = 1024;\n\n/**\n * Quick pre-scan: check if the text contains any substring that MUST be\n * present for a credential pattern to match. If none are found, the text\n * is guaranteed clean \u2014 skip all regex passes (2 total: 16-pattern combined + high_entropy_env).\n *\n * Each anchor is the shortest unique substring from the corresponding pattern.\n * V8's `String.includes()` is hand-tuned C++ \u2014 O(n) with near-zero overhead\n * for typical tool-output lengths (100\u20135000 chars). A single combined regex\n * via `text.search()` is consistently slower for this many alternatives.\n */\nfunction hasCredentialAnchors(text: string): boolean {\n return (\n text.includes('-----BEGIN') || // Private keys (most unique \u2192 cheap reject)\n text.includes('sk-') || // Anthropic + OpenAI keys\n text.includes('sk_') || // Stripe live/test keys\n text.includes('ghp_') || // GitHub PAT v1\n text.includes('github_pat_') || // GitHub PAT v2\n text.includes('eyJ') || // JWT\n text.includes('AKIA') || // AWS access key\n text.includes('AIza') || // GCP service key\n text.includes('xox') || // Slack token (xoxa/xoxb/xoxp/xoxo/xoxs)\n text.includes('Bearer ') || // Bearer token (space suffix reduces false positives)\n text.includes('/bot') || // Telegram bot token (URL path pattern)\n text.includes('hf_') || // HuggingFace token\n text.includes('r8_') || // Replicate token\n text.includes('pplx-') || // Perplexity API key\n text.includes('gsk_') || // Groq API key\n text.includes('_KEY=') || // High-entropy env vars: API_KEY=, SECRET_KEY=, ...\n text.includes('_TOKEN=') || // ACCESS_TOKEN=, AUTH_TOKEN=, ...\n text.includes('_SECRET=') || // API_SECRET=, CLIENT_SECRET=, ...\n text.includes('_PASSWORD=') || // DB_PASSWORD=, ROOT_PASSWORD=, ...\n text.includes('mongodb://') ||\n text.includes('mongodb+srv://') ||\n text.includes('postgres://') ||\n text.includes('postgresql://') ||\n text.includes('mysql://') ||\n text.includes('redis://')\n );\n}\n\nexport class DefaultSecretScrubber implements SecretScrubber {\n scrub(text: string): string {\n if (!text) return text;\n\n // Fast path: if no credential anchor substrings exist in the text,\n // none of the 17 regex patterns can match. Skip all regex work.\n // This covers the vast majority of tool outputs (~95% of calls on\n // typical sessions are file paths, status messages, diffs, etc.).\n if (!hasCredentialAnchors(text)) return text;\n\n // For oversize inputs, scrub in fixed chunks to keep memory bounded.\n // The boundary is snapped FORWARD to the next whitespace within an\n // overlap window so a secret straddling the nominal 64 KB cut is never\n // split in half. Every bounded credential pattern is whitespace-free, so\n // the next whitespace at/after the cut necessarily falls past the end of\n // any such secret \u2014 guaranteeing it stays wholly inside the current chunk.\n if (text.length <= SCRUB_CHUNK_BYTES) {\n return this.scrubOne(text);\n }\n const out: string[] = [];\n let i = 0;\n while (i < text.length) {\n let end = Math.min(i + SCRUB_CHUNK_BYTES, text.length);\n if (end < text.length) {\n // Look for the first whitespace at/after the nominal cut, bounded by\n // the overlap window. Extending forward (not backward) ensures any\n // secret that began before `end` finishes before the new boundary.\n const limit = Math.min(end + SCRUB_OVERLAP_BYTES, text.length);\n let safe = -1;\n for (let j = end; j < limit; j++) {\n const ch = text.charCodeAt(j);\n // space, \\t, \\n, \\r\n if (ch === 32 || ch === 9 || ch === 10 || ch === 13) {\n safe = j;\n break;\n }\n }\n // Snap onto the whitespace if found; otherwise fall back to the hard\n // cut (an unbroken >1 KB run with no whitespace can't be a bounded\n // secret anyway \u2014 those are all \u2264 ~560 chars and whitespace-free).\n end = safe === -1 ? end : safe + 1;\n }\n out.push(this.scrubOne(text.slice(i, end)));\n i = end;\n }\n return out.join('');\n }\n\n private scrubOne(text: string): string {\n // Redundant guard: if we reached scrubOne via the chunked path, the\n // chunk may have been small enough to anchor-skip independently.\n if (!hasCredentialAnchors(text)) return text;\n\n // Pass 1: combined single-pass regex for all simple patterns. Each\n // alternative is a capturing group; only the group that matched is\n // non-undefined. The trailing offset/string args replace() appends are\n // always defined, so the matched group (which precedes them) is found first.\n let out = text.replace(\n COMBINED_REGEX,\n (match, ...groups) => {\n // groups[i] corresponds to SIMPLE_PATTERNS[i]; find which one fired.\n const idx = groups.findIndex((g) => g !== undefined);\n if (idx < 0) return match;\n const replacement = COMBINED_REPLACEMENTS[idx];\n return replacement !== undefined ? replacement : match;\n },\n );\n\n // Pass 2: high_entropy_env needs special handling \u2014 preserve the key name.\n // Groups: 1=leading delimiter (re-emitted so adjacent-secret separators\n // aren't collapsed), 2=key name, 3=value (redacted).\n out = out.replace(HIGH_ENTROPY_REGEX, (_match, lead, key, _value) => {\n return `${lead}${key}=[REDACTED:high_entropy_env]`;\n });\n\n return out;\n }\n\n /**\n * Recursively scrub every string value in an object/array graph. Secrets can\n * appear under any key \u2014 a URL query param, an `authorization` header, an\n * arbitrarily-named nested field \u2014 so we don't gate recursion on key names.\n * The per-string `scrub()` fast-path (anchor pre-scan) keeps this cheap: any\n * value without a credential anchor returns immediately without regex work.\n */\n scrubObject<T>(obj: T): T {\n const seen = new WeakSet();\n const visit = (v: unknown): unknown => {\n if (typeof v === 'string') return this.scrub(v);\n if (v === null || typeof v !== 'object') return v;\n if (seen.has(v as object)) return v;\n seen.add(v as object);\n if (Array.isArray(v)) return v.map(visit);\n const out: Record<string, unknown> = {};\n for (const [k, val] of Object.entries(v as Record<string, unknown>)) {\n out[k] = visit(val);\n }\n return out;\n };\n return visit(obj) as T;\n }\n}\n", "import { DefaultSecretScrubber } from '../security/secret-scrubber.js';\nimport {\n DEFAULT_HQ_REDACTION_POLICY,\n type HqEventEnvelope,\n type HqRedactionPolicy,\n} from './protocol.js';\n\nconst RAW_CONTENT_REPLACEMENT = '[REDACTED:hq_raw_content]';\nconst SENSITIVE_FIELD_REPLACEMENT = '[REDACTED:hq_sensitive_field]';\nconst REDACTED_PATH_REPLACEMENT = '[REDACTED:hq_path]';\n\nconst RAW_CONTENT_KEYS = new Set([\n 'content',\n 'contents',\n 'raw',\n 'rawContent',\n 'body',\n 'message',\n 'messages',\n 'prompt',\n 'prompts',\n 'completion',\n 'response',\n 'text',\n 'partialText',\n 'assistantMessage',\n 'userMessage',\n 'stdout',\n 'stderr',\n 'output',\n 'toolInput',\n 'toolOutput',\n 'outputSummary',\n 'body',\n 'mailboxBody',\n 'messageBody',\n 'outcome',\n 'fileContent',\n 'diff',\n 'patch',\n 'transcript',\n 'logs',\n]);\n\nconst SENSITIVE_KEYS = new Set([\n 'authorization',\n 'cookie',\n 'password',\n 'passwd',\n 'pwd',\n 'secret',\n 'token',\n 'accessToken',\n 'refreshToken',\n 'apiKey',\n 'apikey',\n 'clientSecret',\n 'privateKey',\n]);\n\nconst PATH_KEYS = new Set([\n 'path',\n 'paths',\n 'file',\n 'files',\n 'filepath',\n 'filePath',\n 'filename',\n 'projectRoot',\n 'projectRootDisplay',\n 'cwd',\n 'workingDir',\n 'workingDirectory',\n]);\n\nexport interface HqRedactOptions {\n policy?: Partial<HqRedactionPolicy>;\n projectRoot?: string;\n maxSummaryLength?: number;\n}\n\nexport interface HqRedactionResult<T> {\n value: T;\n redacted: boolean;\n}\n\nconst defaultScrubber = new DefaultSecretScrubber();\n\nexport function resolveHqRedactionPolicy(\n policy?: Partial<HqRedactionPolicy>,\n): HqRedactionPolicy {\n return {\n ...DEFAULT_HQ_REDACTION_POLICY,\n ...policy,\n };\n}\n\n/**\n * Apply an operator policy as a one-way privacy clamp. An override can make a\n * publisher policy stricter, but can never enable raw content or broader path\n * / tool-argument disclosure than the publisher selected.\n */\nexport function tightenHqRedactionPolicy(\n publisherPolicy: HqRedactionPolicy,\n operatorPolicy?: Partial<HqRedactionPolicy>,\n): HqRedactionPolicy {\n if (operatorPolicy === undefined) return publisherPolicy;\n const toolRank: Record<HqRedactionPolicy['toolArgs'], number> = {\n none: 0,\n summary: 1,\n redacted: 2,\n full: 3,\n };\n const pathRank: Record<HqRedactionPolicy['paths'], number> = {\n none: 0,\n redacted: 0,\n 'project-relative': 1,\n full: 2,\n };\n const requestedToolArgs = operatorPolicy.toolArgs;\n const requestedPaths = operatorPolicy.paths;\n return {\n rawContent:\n publisherPolicy.rawContent &&\n (operatorPolicy.rawContent === undefined || operatorPolicy.rawContent),\n toolArgs:\n requestedToolArgs !== undefined &&\n toolRank[requestedToolArgs] < toolRank[publisherPolicy.toolArgs]\n ? requestedToolArgs\n : publisherPolicy.toolArgs,\n paths:\n requestedPaths !== undefined && pathRank[requestedPaths] < pathRank[publisherPolicy.paths]\n ? requestedPaths\n : publisherPolicy.paths,\n };\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return Object.prototype.toString.call(value) === '[object Object]';\n}\n\nfunction isSensitiveKey(key: string): boolean {\n const lower = key.toLowerCase();\n return (\n SENSITIVE_KEYS.has(key) ||\n lower.includes('authorization') ||\n lower.includes('password') ||\n lower.includes('secret') ||\n lower.endsWith('token') ||\n lower.endsWith('apikey') ||\n lower.endsWith('api_key')\n );\n}\n\nfunction isRawContentKey(key: string): boolean {\n return RAW_CONTENT_KEYS.has(key) || RAW_CONTENT_KEYS.has(key.toLowerCase());\n}\n\nfunction isPathKey(key: string): boolean {\n return PATH_KEYS.has(key) || PATH_KEYS.has(key.toLowerCase());\n}\n\nfunction normalizePathForCompare(value: string): string {\n return value.replace(/\\\\/g, '/').replace(/\\/+$/g, '');\n}\n\nfunction redactPath(\n value: string,\n projectRoot: string | undefined,\n policy: HqRedactionPolicy,\n): string {\n if (policy.paths === 'full') return value;\n if (policy.paths === 'none' || policy.paths === 'redacted') return REDACTED_PATH_REPLACEMENT;\n\n const normalizedValue = normalizePathForCompare(value);\n if (!projectRoot) return normalizedValue.split('/').at(-1) ?? REDACTED_PATH_REPLACEMENT;\n\n const normalizedRoot = normalizePathForCompare(projectRoot);\n if (normalizedValue === normalizedRoot) return '.';\n if (normalizedValue.startsWith(`${normalizedRoot}/`)) {\n return normalizedValue.slice(normalizedRoot.length + 1) || '.';\n }\n return normalizedValue.split('/').at(-1) ?? REDACTED_PATH_REPLACEMENT;\n}\n\nfunction summarizeString(value: string, maxSummaryLength: number, scrub: boolean): string {\n const scrubbed = scrub ? defaultScrubber.scrub(value) : value;\n if (scrubbed.length <= maxSummaryLength) return scrubbed;\n return `${scrubbed.slice(0, maxSummaryLength)}\u2026[truncated:${scrubbed.length - maxSummaryLength}]`;\n}\n\n/**\n * Scrub a free-text preview field and truncate it to a maximum length so\n * it is safe to embed in HQ event envelopes and broadcast to browsers\n * without leaking secrets or running away on unbounded input.\n *\n * Returns `undefined` when the input is empty or non-string. Truncation\n * suffix is `\"\u2026[truncated:N]\"` where N is the number of dropped chars.\n */\nexport function scrubAndTruncateHqPreview(\n value: unknown,\n maxLength: number = 280,\n): string | undefined {\n if (typeof value !== 'string' || value.length === 0) return undefined;\n return summarizeString(value, maxLength, true);\n}\n\nfunction visitValue(\n value: unknown,\n options: {\n policy: HqRedactionPolicy;\n projectRoot?: string;\n maxSummaryLength: number;\n seen: WeakSet<object>;\n },\n key?: string,\n): { value: unknown; redacted: boolean } {\n if (!options.policy.rawContent && key !== undefined && isSensitiveKey(key)) {\n return { value: SENSITIVE_FIELD_REPLACEMENT, redacted: true };\n }\n\n if (typeof value === 'string') {\n if (key !== undefined && isPathKey(key)) {\n const redactedPath = redactPath(value, options.projectRoot, options.policy);\n return { value: redactedPath, redacted: redactedPath !== value };\n }\n\n if (!options.policy.rawContent && key !== undefined && isRawContentKey(key)) {\n return { value: RAW_CONTENT_REPLACEMENT, redacted: true };\n }\n\n const scrubbed = summarizeString(value, options.maxSummaryLength, !options.policy.rawContent);\n return { value: scrubbed, redacted: scrubbed !== value };\n }\n\n if (value === null || typeof value !== 'object') return { value, redacted: false };\n\n if (options.seen.has(value)) return { value: '[REDACTED:hq_circular]', redacted: true };\n options.seen.add(value);\n\n if (Array.isArray(value)) {\n let redacted = false;\n const out = value.map((item) => {\n const next = visitValue(item, options, key);\n redacted ||= next.redacted;\n return next.value;\n });\n return { value: out, redacted };\n }\n\n if (!isPlainObject(value)) return { value: String(value), redacted: true };\n\n let redacted = false;\n const out: Record<string, unknown> = {};\n for (const [childKey, childValue] of Object.entries(value)) {\n const next = visitValue(childValue, options, childKey);\n redacted ||= next.redacted;\n out[childKey] = next.value;\n }\n return { value: out, redacted };\n}\n\nexport function redactHqValue<T>(value: T, options: HqRedactOptions = {}): HqRedactionResult<T> {\n const result = visitValue(value, {\n policy: resolveHqRedactionPolicy(options.policy),\n ...(options.projectRoot !== undefined ? { projectRoot: options.projectRoot } : {}),\n maxSummaryLength: options.maxSummaryLength ?? 500,\n seen: new WeakSet<object>(),\n });\n return { value: result.value as T, redacted: result.redacted };\n}\n\nexport function redactHqEvent<TPayload>(\n event: HqEventEnvelope<TPayload>,\n options: HqRedactOptions = {},\n): HqRedactionResult<HqEventEnvelope<TPayload>> {\n const payload = redactHqValue(event.payload, options);\n const nextEvent = {\n ...event,\n payload: payload.value,\n };\n return { value: nextEvent, redacted: payload.redacted };\n}\n\nexport function summarizeHqToolArgs(value: unknown, options: HqRedactOptions = {}): unknown {\n const policy = resolveHqRedactionPolicy(options.policy);\n if (policy.toolArgs === 'full') return value;\n if (policy.toolArgs === 'none') return '[REDACTED:hq_tool_args]';\n if (policy.toolArgs === 'redacted') return redactHqValue(value, options).value;\n\n if (value === null || typeof value !== 'object') return redactHqValue(value, options).value;\n if (Array.isArray(value)) return `[array:${value.length}]`;\n\n const entries = Object.entries(value as Record<string, unknown>);\n const summary: Record<string, unknown> = {};\n for (const [key, item] of entries.slice(0, 20)) {\n if (isSensitiveKey(key)) {\n summary[key] = SENSITIVE_FIELD_REPLACEMENT;\n } else if (typeof item === 'string') {\n summary[key] = isPathKey(key)\n ? redactPath(item, options.projectRoot, policy)\n : summarizeString(item, 120, true);\n } else if (Array.isArray(item)) {\n summary[key] = `[array:${item.length}]`;\n } else if (item !== null && typeof item === 'object') {\n summary[key] = '[object]';\n } else {\n summary[key] = item;\n }\n }\n if (entries.length > 20) summary.__truncatedKeys = entries.length - 20;\n return summary;\n}\n", "import type { Mailbox, MailboxAgentStatus, MailboxMessage } from '../coordination/mailbox-types.js';\nimport type {\n HqMailboxAgentSummary,\n HqMailboxEventPayload,\n HqMailboxMessageSummary,\n HqMailboxSnapshotPayload,\n HqRedactionPolicy,\n} from './protocol.js';\nimport { scrubAndTruncateHqPreview } from './redaction.js';\n\nexport interface HqMailboxMappingOptions {\n mailboxId: string;\n scope?: 'project' | 'global';\n limit?: number;\n previewLength?: number;\n redactionPolicy?: Partial<HqRedactionPolicy>;\n}\n\nexport interface HqMailboxSnapshotOptions extends HqMailboxMappingOptions {\n includeCompleted?: boolean;\n}\n\nexport type HqMailboxEventAction = HqMailboxEventPayload['action'];\n\nfunction previewText(value: string | undefined, maxLength: number, policy?: Partial<HqRedactionPolicy>): string | undefined {\n if (value === undefined || value.length === 0) return undefined;\n if (policy?.rawContent === false) return '[REDACTED:hq_raw_content]';\n if (policy?.rawContent === true) {\n if (value.length <= maxLength) return value;\n return `${value.slice(0, maxLength)}\u2026`;\n }\n return scrubAndTruncateHqPreview(value, maxLength);\n}\n\nfunction readCount(message: MailboxMessage): number {\n return Object.keys(message.readBy).length;\n}\n\nfunction taskSummary(message: MailboxMessage): HqMailboxMessageSummary['task'] {\n if (message.taskContext === undefined) return undefined;\n const task = {\n ...(message.taskContext.taskId !== undefined ? { taskId: message.taskContext.taskId } : {}),\n ...(message.taskContext.agentRole !== undefined ? { agentRole: message.taskContext.agentRole } : {}),\n ...(message.taskContext.agentName !== undefined ? { agentName: message.taskContext.agentName } : {}),\n ...(message.taskContext.status !== undefined ? { status: message.taskContext.status } : {}),\n } satisfies HqMailboxMessageSummary['task'];\n return Object.keys(task).length > 0 ? task : undefined;\n}\n\nexport function mapMailboxMessageToHqSummary(\n message: MailboxMessage,\n options: Pick<HqMailboxMappingOptions, 'previewLength' | 'redactionPolicy'> = {},\n): HqMailboxMessageSummary {\n const previewLength = options.previewLength ?? 500;\n const bodyPreview = previewText(message.body, previewLength, options.redactionPolicy);\n const outcomePreview = previewText(message.outcome, previewLength, options.redactionPolicy);\n const task = taskSummary(message);\n\n return {\n mailId: message.id, // unique UUID per message record, used for deduplication\n messageId: message.id,\n from: message.from,\n to: message.to,\n type: message.type,\n subject: previewText(message.subject, previewLength, options.redactionPolicy) ?? '',\n priority: message.priority,\n timestamp: message.timestamp,\n ...(message.replyTo !== undefined ? { replyTo: message.replyTo } : {}),\n ...(message.senderSessionId !== undefined ? { senderSessionId: message.senderSessionId } : {}),\n completed: message.completed,\n ...(message.completedBy !== undefined ? { completedBy: message.completedBy } : {}),\n ...(message.completedAt !== undefined ? { completedAt: message.completedAt } : {}),\n readCount: readCount(message),\n hasBody: message.body.length > 0,\n ...(bodyPreview !== undefined ? { bodyPreview } : {}),\n ...(outcomePreview !== undefined ? { outcomePreview } : {}),\n ...(task !== undefined ? { task } : {}),\n };\n}\n\nexport function mapMailboxAgentToHqSummary(agent: MailboxAgentStatus): HqMailboxAgentSummary {\n return {\n agentId: agent.agentId,\n name: agent.name,\n ...(agent.role !== undefined ? { role: agent.role } : {}),\n sessionId: agent.sessionId,\n status: agent.status,\n ...(agent.currentTool !== undefined ? { currentTool: agent.currentTool } : {}),\n ...(agent.currentTask !== undefined ? { currentTask: agent.currentTask } : {}),\n iterations: agent.iterations,\n toolCalls: agent.toolCalls,\n lastActivityAt: agent.lastActivityAt,\n lastSeenAt: agent.lastSeenAt,\n online: agent.online,\n ...(agent.source !== undefined ? { source: agent.source } : {}),\n };\n}\n\nexport function createMailboxSnapshotPayload(\n messages: readonly MailboxMessage[],\n agents: readonly MailboxAgentStatus[],\n options: HqMailboxSnapshotOptions,\n): HqMailboxSnapshotPayload {\n const includeCompleted = options.includeCompleted ?? true;\n const filteredMessages = includeCompleted ? messages : messages.filter((message) => !message.completed);\n const limit = options.limit ?? 50;\n const sortedMessages = [...filteredMessages].sort((a, b) => b.timestamp.localeCompare(a.timestamp)).slice(0, limit);\n const summaries = sortedMessages.map((message) => mapMailboxMessageToHqSummary(message, options));\n const agentSummaries = agents.map(mapMailboxAgentToHqSummary);\n\n return {\n mailboxId: options.mailboxId,\n scope: options.scope ?? 'project',\n messages: summaries,\n agents: agentSummaries,\n totals: {\n messages: messages.length,\n unread: messages.filter((message) => !message.completed && readCount(message) === 0).length,\n incomplete: messages.filter((message) => !message.completed).length,\n highPriority: messages.filter((message) => message.priority === 'high').length,\n onlineAgents: agents.filter((agent) => agent.online).length,\n },\n };\n}\n\nexport async function createMailboxSnapshotPayloadFromMailbox(\n mailbox: Pick<Mailbox, 'query' | 'getAgentStatuses'>,\n options: HqMailboxSnapshotOptions,\n): Promise<HqMailboxSnapshotPayload> {\n const limit = options.limit ?? 50;\n const [messages, agents] = await Promise.all([\n mailbox.query({ limit }),\n mailbox.getAgentStatuses(),\n ]);\n return createMailboxSnapshotPayload(messages, agents, options);\n}\n\nexport function createMailboxEventPayload(input: {\n mailboxId: string;\n action: HqMailboxEventAction;\n message?: MailboxMessage;\n agent?: MailboxAgentStatus;\n summary?: string;\n previewLength?: number;\n redactionPolicy?: Partial<HqRedactionPolicy>;\n}): HqMailboxEventPayload {\n const summaryOptions: Pick<HqMailboxMappingOptions, 'previewLength' | 'redactionPolicy'> = {\n ...(input.previewLength !== undefined ? { previewLength: input.previewLength } : {}),\n ...(input.redactionPolicy !== undefined ? { redactionPolicy: input.redactionPolicy } : {}),\n };\n\n return {\n mailboxId: input.mailboxId,\n action: input.action,\n ...(input.message !== undefined ? { message: mapMailboxMessageToHqSummary(input.message, summaryOptions) } : {}),\n ...(input.agent !== undefined ? { agent: mapMailboxAgentToHqSummary(input.agent) } : {}),\n ...(input.summary !== undefined\n ? { summary: previewText(input.summary, input.previewLength ?? 160, input.redactionPolicy) ?? '' }\n : {}),\n };\n}\n", "import { randomUUID } from 'node:crypto';\nimport type { Logger } from '../types/logger.js';\nimport type { Mailbox, MailboxAgentStatus, MailboxMessage } from '../coordination/mailbox-types.js';\nimport {\n createMailboxEventPayload,\n createMailboxSnapshotPayloadFromMailbox,\n type HqMailboxEventAction,\n type HqMailboxSnapshotOptions,\n} from './mailbox-mapper.js';\nimport { redactHqEvent, resolveHqRedactionPolicy } from './redaction.js';\nimport {\n createHqEventEnvelope,\n HQ_PROTOCOL_VERSION,\n HQ_TRANSCRIPT_TEXT_CAP,\n type HqClientCapability,\n type HqClientCommandAckMessage,\n type HqClientCommandPollMessage,\n type HqClientEventMessage,\n type HqClientHelloMessage,\n type HqClientIdentity,\n type HqEventEnvelope,\n type HqEventType,\n type HqFleetSnapshotPayload,\n type HqMailboxEventPayload,\n type HqMailboxSnapshotPayload,\n type HqProjectIdentity,\n type HqQueuedCommand,\n type HqRedactionPolicy,\n type HqServerCommandBatchMessage,\n type HqSessionEndedPayload,\n type HqSessionSnapshotPayload,\n type HqTranscriptAppendPayload,\n} from './protocol.js';\n\nexport interface HqSocketLike {\n readyState: number;\n send(data: string): void;\n close(code?: number, reason?: string): void;\n addEventListener?(\n type: 'open' | 'close' | 'error' | 'message',\n listener: (event: unknown) => void,\n ): void;\n removeEventListener?(\n type: 'open' | 'close' | 'error' | 'message',\n listener: (event: unknown) => void,\n ): void;\n on?(type: 'open' | 'close' | 'error' | 'message', listener: (event: unknown) => void): void;\n off?(type: 'open' | 'close' | 'error' | 'message', listener: (event: unknown) => void): void;\n}\n\nexport type HqSocketFactory = (url: string, init: { token?: string }) => HqSocketLike;\n\nexport interface HqPublisherCommandResult {\n commandId: string;\n status: 'accepted' | 'completed' | 'failed' | 'rejected';\n message?: string;\n}\n\nexport type HqPublisherCommandHandler = (\n command: HqQueuedCommand,\n) => void | HqPublisherCommandResult | Promise<void | HqPublisherCommandResult>;\n\nexport interface HqPublisherOptions {\n url: string;\n token?: string;\n client: HqClientIdentity;\n project: HqProjectIdentity;\n capabilities?: readonly HqClientCapability[];\n socketFactory?: HqSocketFactory;\n now?: () => string;\n idFactory?: () => string;\n reconnect?: boolean;\n reconnectBaseMs?: number;\n reconnectMaxMs?: number;\n maxQueuedMessages?: number;\n redactionPolicy?: Partial<HqRedactionPolicy>;\n commandPollIntervalMs?: number;\n commandPollLimit?: number;\n onCommand?: HqPublisherCommandHandler;\n /**\n * Local auto-discovery hook: re-resolve the HQ endpoint before EVERY\n * connect attempt (e.g. by reading `<hq dataDir>/runtime.json`). Returning\n * `undefined` means no HQ is currently discoverable \u2014 the publisher stays\n * dormant (events keep queueing, bounded) and re-checks every\n * {@link HqPublisherOptions.discoveryPollMs}. Because the endpoint is\n * re-resolved per attempt, an HQ started AFTER this client \u2014 or restarted\n * on a different port, or one that minted its first client token on boot \u2014\n * is picked up automatically.\n */\n resolveEndpoint?: () => { url: string; token?: string | undefined } | undefined;\n /** Dormant re-check interval while `resolveEndpoint` yields nothing. Default 5s. */\n discoveryPollMs?: number;\n /**\n * Application-level heartbeat interval for the `/ws/client` connection.\n * The HQ server evicts silent sockets, so this must be comfortably below\n * the server-side client TTL even when no command handler is installed.\n */\n heartbeatIntervalMs?: number;\n /**\n * Diagnostic sink for the one-time consecutive-connect-failure warning.\n * The publisher is otherwise deliberately silent (dormant queueing), which\n * made auth failures invisible: a token the server rejects \u2014 e.g. a wrong\n * `WRONGSTACK_HQ_TOKEN` against a remote HQ \u2014 looked exactly like \"HQ not\n * running\". Defaults to a single structured `console.warn` line.\n */\n warn?: (message: string) => void;\n /** Logger for structured events. When provided, the `warn` callback is derived from it. */\n logger?: Logger | undefined;\n}\n\nexport interface HqPublishEventOptions {\n type: HqEventType | (string & {});\n payload: unknown;\n sessionId?: string;\n runId?: string;\n timestamp?: string;\n /**\n * Per-string redaction cap override. Defaults to the generic 500-char\n * summary cap; chat-transcript event types (`session.transcript`,\n * `agent.message`) automatically get {@link HQ_TRANSCRIPT_TEXT_CAP} so\n * full chat history survives when `rawContent` is enabled.\n */\n maxSummaryLength?: number;\n}\n\n/** Event types that carry full chat turns rather than telemetry summaries. */\nconst TRANSCRIPT_EVENT_TYPES = new Set<string>(['session.transcript', 'agent.message']);\n\nconst OPEN_STATE = 1;\n/**\n * After this many consecutive failed connects (never reaching `open`), emit\n * ONE diagnostic warning. The WS handshake gives the browser-style socket no\n * HTTP status, so a 401 (token mismatch) is indistinguishable from a dead\n * server at this layer \u2014 the warning names both possibilities.\n */\nconst CONNECT_WARN_AFTER_FAILURES = 5;\nconst DEFAULT_RECONNECT_BASE_MS = 1_000;\nconst DEFAULT_RECONNECT_MAX_MS = 30_000;\nconst DEFAULT_DISCOVERY_POLL_MS = 5_000;\nconst DEFAULT_MAX_QUEUED_MESSAGES = 2000;\nconst DEFAULT_COMMAND_POLL_INTERVAL_MS = 2_000;\nconst DEFAULT_COMMAND_POLL_LIMIT = 25;\nconst DEFAULT_HEARTBEAT_INTERVAL_MS = 25_000;\n\nfunction defaultSocketFactory(url: string): HqSocketLike {\n const WebSocketCtor = globalThis.WebSocket;\n if (WebSocketCtor === undefined) {\n throw new Error(\n 'No global WebSocket implementation is available; provide HqPublisherOptions.socketFactory.',\n );\n }\n return new WebSocketCtor(url) as HqSocketLike;\n}\n\nfunction toClientUrl(baseUrl: string, token: string | undefined): string {\n const url = new URL(baseUrl);\n url.protocol = url.protocol === 'https:' ? 'wss:' : 'ws:';\n if (url.pathname === '/' || url.pathname === '') url.pathname = '/ws/client';\n if (token !== undefined && token.length > 0) url.searchParams.set('token', token);\n return url.toString();\n}\n\nfunction addSocketListener(\n socket: HqSocketLike,\n type: 'open' | 'close' | 'error' | 'message',\n listener: (event: unknown) => void,\n): void {\n if (socket.addEventListener !== undefined) {\n socket.addEventListener(type, listener);\n return;\n }\n socket.on?.(type, listener);\n}\n\nfunction removeSocketListener(\n socket: HqSocketLike,\n type: 'open' | 'close' | 'error' | 'message',\n listener: (event: unknown) => void,\n): void {\n if (socket.removeEventListener !== undefined) {\n socket.removeEventListener(type, listener);\n return;\n }\n socket.off?.(type, listener);\n}\n\nexport class HqPublisher {\n private readonly socketFactory: HqSocketFactory;\n private readonly now: () => string;\n private readonly idFactory: () => string;\n private readonly capabilities: readonly HqClientCapability[];\n private readonly reconnect: boolean;\n private readonly reconnectBaseMs: number;\n private readonly reconnectMaxMs: number;\n private readonly maxQueuedMessages: number;\n private readonly resolvedRedactionPolicy: HqRedactionPolicy;\n private readonly logger: Logger | undefined;\n private socket: HqSocketLike | null = null;\n private seq = 0;\n private queue: string[] = [];\n private stopped = false;\n private reconnectAttempt = 0;\n private connectWarningEmitted = false;\n private lastAttempt: { url: string; hadToken: boolean } | null = null;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private commandPollTimer: ReturnType<typeof setInterval> | null = null;\n private heartbeatTimer: ReturnType<typeof setInterval> | null = null;\n private lastCommandId: string | undefined;\n\n constructor(private readonly options: HqPublisherOptions) {\n this.socketFactory = options.socketFactory ?? defaultSocketFactory;\n this.now = options.now ?? (() => new Date().toISOString());\n this.idFactory = options.idFactory ?? randomUUID;\n this.capabilities = options.capabilities ?? [\n 'telemetry.publish',\n 'mailbox.summary',\n 'fleet.summary',\n 'session.summary',\n ];\n this.reconnect = options.reconnect ?? true;\n this.reconnectBaseMs = options.reconnectBaseMs ?? DEFAULT_RECONNECT_BASE_MS;\n this.reconnectMaxMs = options.reconnectMaxMs ?? DEFAULT_RECONNECT_MAX_MS;\n this.maxQueuedMessages = options.maxQueuedMessages ?? DEFAULT_MAX_QUEUED_MESSAGES;\n this.resolvedRedactionPolicy = resolveHqRedactionPolicy(options.redactionPolicy);\n this.logger = options.logger;\n }\n\n connect(): void {\n if (this.socket !== null || this.stopped) return;\n // A retry / discovery poll is already scheduled \u2014 let it fire instead of\n // dialing (and re-resolving the endpoint) on every publish while offline.\n if (this.reconnectTimer !== null) return;\n\n let url = this.options.url;\n let token = this.options.token;\n if (this.options.resolveEndpoint !== undefined) {\n const endpoint = this.options.resolveEndpoint();\n if (endpoint === undefined) {\n this.scheduleDiscoveryPoll();\n return;\n }\n url = endpoint.url;\n token = endpoint.token ?? token;\n }\n this.lastAttempt = { url, hadToken: token !== undefined };\n\n let socket: HqSocketLike;\n try {\n socket = this.socketFactory(toClientUrl(url, token), {\n ...(token !== undefined ? { token } : {}),\n });\n } catch {\n this.scheduleReconnect();\n return;\n }\n this.socket = socket;\n\n const onOpen = () => {\n this.reconnectAttempt = 0;\n this.sendHelloNow();\n this.flushQueue();\n this.startHeartbeat();\n if (this.options.onCommand !== undefined) {\n this.startCommandPolling();\n this.pollCommands();\n }\n };\n const onMessage = (event: unknown) => {\n void this.handleServerMessage(event);\n };\n const onCloseOrError = () => {\n removeSocketListener(socket, 'open', onOpen);\n removeSocketListener(socket, 'message', onMessage);\n removeSocketListener(socket, 'close', onCloseOrError);\n removeSocketListener(socket, 'error', onCloseOrError);\n this.stopCommandPolling();\n this.stopHeartbeat();\n if (this.socket === socket) this.socket = null;\n this.scheduleReconnect();\n };\n\n addSocketListener(socket, 'open', onOpen);\n addSocketListener(socket, 'message', onMessage);\n addSocketListener(socket, 'close', onCloseOrError);\n addSocketListener(socket, 'error', onCloseOrError);\n\n if (socket.readyState === OPEN_STATE) onOpen();\n }\n\n close(): void {\n this.stopped = true;\n if (this.reconnectTimer !== null) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n this.stopCommandPolling();\n this.stopHeartbeat();\n this.queue = [];\n const socket = this.socket;\n this.socket = null;\n socket?.close(1000, 'hq publisher closed');\n }\n\n publishEvent<TPayload>(\n options: HqPublishEventOptions & { payload: TPayload },\n ): HqEventEnvelope<TPayload> {\n const event = createHqEventEnvelope({\n id: this.idFactory(),\n type: options.type,\n timestamp: options.timestamp ?? this.now(),\n clientId: this.options.client.clientId,\n projectId: this.options.project.projectId,\n seq: ++this.seq,\n payload: options.payload,\n ...(options.sessionId !== undefined ? { sessionId: options.sessionId } : {}),\n ...(options.runId !== undefined ? { runId: options.runId } : {}),\n });\n const maxSummaryLength =\n options.maxSummaryLength ??\n (TRANSCRIPT_EVENT_TYPES.has(options.type) ? HQ_TRANSCRIPT_TEXT_CAP : undefined);\n const redacted = redactHqEvent(event, {\n policy: this.resolvedRedactionPolicy,\n projectRoot: this.options.project.projectRoot,\n ...(maxSummaryLength !== undefined ? { maxSummaryLength } : {}),\n }).value;\n this.sendFrame({ type: 'client.event', event: redacted });\n return redacted;\n }\n\n async publishMailboxSnapshot(\n mailbox: Pick<Mailbox, 'query' | 'getAgentStatuses'>,\n options: Omit<HqMailboxSnapshotOptions, 'redactionPolicy'> & {\n sessionId?: string;\n timestamp?: string;\n },\n ): Promise<HqEventEnvelope<HqMailboxSnapshotPayload>> {\n const payload = await createMailboxSnapshotPayloadFromMailbox(mailbox, {\n ...options,\n redactionPolicy: this.resolvedRedactionPolicy,\n });\n return this.publishEvent({\n type: 'mailbox.snapshot',\n payload,\n ...(options.sessionId !== undefined ? { sessionId: options.sessionId } : {}),\n ...(options.timestamp !== undefined ? { timestamp: options.timestamp } : {}),\n });\n }\n\n publishMailboxEvent(input: {\n mailboxId: string;\n action: HqMailboxEventAction;\n message?: MailboxMessage;\n agent?: MailboxAgentStatus;\n summary?: string;\n previewLength?: number;\n sessionId?: string;\n timestamp?: string;\n }): HqEventEnvelope<HqMailboxEventPayload> {\n const payload = createMailboxEventPayload({\n mailboxId: input.mailboxId,\n action: input.action,\n ...(input.message !== undefined ? { message: input.message } : {}),\n ...(input.agent !== undefined ? { agent: input.agent } : {}),\n ...(input.summary !== undefined ? { summary: input.summary } : {}),\n ...(input.previewLength !== undefined ? { previewLength: input.previewLength } : {}),\n redactionPolicy: this.resolvedRedactionPolicy,\n });\n return this.publishEvent({\n type: 'mailbox.event',\n payload,\n ...(input.sessionId !== undefined ? { sessionId: input.sessionId } : {}),\n ...(input.timestamp !== undefined ? { timestamp: input.timestamp } : {}),\n });\n }\n\n /** The client identity this publisher announced (clientId, kind, machineId, \u2026). */\n get identity(): HqClientIdentity {\n return this.options.client;\n }\n\n /** The project identity this publisher is bound to. */\n get project(): HqProjectIdentity {\n return this.options.project;\n }\n\n /** Effective publisher-side policy applied before any event leaves this process. */\n get redactionPolicy(): HqRedactionPolicy {\n return this.resolvedRedactionPolicy;\n }\n\n /** Publish a live session/terminal snapshot (state + agents). */\n publishSessionSnapshot(\n payload: HqSessionSnapshotPayload,\n opts?: { timestamp?: string },\n ): HqEventEnvelope<HqSessionSnapshotPayload> {\n return this.publishEvent({\n type: 'session.snapshot',\n payload,\n sessionId: payload.sessionId,\n ...(opts?.timestamp !== undefined ? { timestamp: opts.timestamp } : {}),\n });\n }\n\n /** Publish an incremental batch of transcript turns for a session. */\n publishTranscriptAppend(\n payload: HqTranscriptAppendPayload,\n opts?: { timestamp?: string },\n ): HqEventEnvelope<HqTranscriptAppendPayload> {\n return this.publishEvent({\n type: 'session.transcript',\n payload,\n sessionId: payload.sessionId,\n ...(opts?.timestamp !== undefined ? { timestamp: opts.timestamp } : {}),\n });\n }\n\n /** Mark a session/terminal as ended. */\n publishSessionEnded(\n payload: HqSessionEndedPayload,\n opts?: { timestamp?: string },\n ): HqEventEnvelope<HqSessionEndedPayload> {\n return this.publishEvent({\n type: 'session.ended',\n payload,\n sessionId: payload.sessionId,\n ...(opts?.timestamp !== undefined ? { timestamp: opts.timestamp } : {}),\n });\n }\n\n /** Publish a fleet (multi-agent coordinator) snapshot. */\n publishFleetSnapshot(\n payload: HqFleetSnapshotPayload,\n opts?: { sessionId?: string; timestamp?: string },\n ): HqEventEnvelope<HqFleetSnapshotPayload> {\n return this.publishEvent({\n type: 'fleet.snapshot',\n payload,\n runId: payload.runId,\n ...(opts?.sessionId !== undefined ? { sessionId: opts.sessionId } : {}),\n ...(opts?.timestamp !== undefined ? { timestamp: opts.timestamp } : {}),\n });\n }\n\n pollCommands(): void {\n this.sendFrame({\n type: 'client.command_poll',\n clientId: this.options.client.clientId,\n projectId: this.options.project.projectId,\n ...(this.lastCommandId !== undefined ? { afterCommandId: this.lastCommandId } : {}),\n limit: this.options.commandPollLimit ?? DEFAULT_COMMAND_POLL_LIMIT,\n });\n }\n\n ackCommand(result: HqPublisherCommandResult): void {\n this.sendFrame({\n type: 'client.command_ack',\n clientId: this.options.client.clientId,\n projectId: this.options.project.projectId,\n commandId: result.commandId,\n status: result.status,\n ...(result.message !== undefined ? { message: result.message } : {}),\n });\n }\n\n private createHelloFrame(): HqClientHelloMessage {\n return {\n type: 'client.hello',\n payload: {\n protocolVersion: HQ_PROTOCOL_VERSION,\n client: this.options.client,\n project: this.options.project,\n capabilities: this.capabilities,\n redactionPolicy: this.resolvedRedactionPolicy,\n },\n };\n }\n\n private sendHelloNow(): void {\n const socket = this.socket;\n if (socket?.readyState !== OPEN_STATE) {\n this.sendFrame(this.createHelloFrame());\n return;\n }\n socket.send(JSON.stringify(this.createHelloFrame()));\n }\n\n private sendFrame(\n frame:\n | HqClientHelloMessage\n | HqClientEventMessage\n | HqClientCommandPollMessage\n | HqClientCommandAckMessage,\n ): void {\n const serialized = JSON.stringify(frame);\n const socket = this.socket;\n // Fast path: socket is open and nothing queued \u2014 send immediately.\n if (socket?.readyState === OPEN_STATE && this.queue.length === 0) {\n socket.send(serialized);\n return;\n }\n // Slow path: socket offline or queue already has pending frames \u2014 enqueue.\n this.enqueue(serialized);\n this.connect();\n }\n\n private enqueue(serialized: string): void {\n if (this.queue.length >= this.maxQueuedMessages) this.queue.shift();\n this.queue.push(serialized);\n }\n\n /** Batch-dequeue up to 50 frames at a time, yielding to the microtask\n * queue between batches so we don't starve the event loop on reconnect. */\n private flushQueue(): void {\n const socket = this.socket;\n if (socket?.readyState !== OPEN_STATE || this.queue.length === 0) return;\n const batch = this.queue.splice(0, 50);\n for (const frame of batch) socket.send(frame);\n if (this.queue.length > 0) setImmediate(() => this.flushQueue());\n }\n\n private startCommandPolling(): void {\n if (this.options.onCommand === undefined || this.commandPollTimer !== null) return;\n this.commandPollTimer = setInterval(\n () => this.pollCommands(),\n this.options.commandPollIntervalMs ?? DEFAULT_COMMAND_POLL_INTERVAL_MS,\n );\n this.commandPollTimer.unref?.();\n }\n\n private stopCommandPolling(): void {\n if (this.commandPollTimer === null) return;\n clearInterval(this.commandPollTimer);\n this.commandPollTimer = null;\n }\n\n private startHeartbeat(): void {\n if (this.heartbeatTimer !== null) return;\n this.heartbeatTimer = setInterval(\n () => this.publishHeartbeat(),\n this.options.heartbeatIntervalMs ?? DEFAULT_HEARTBEAT_INTERVAL_MS,\n );\n this.heartbeatTimer.unref?.();\n }\n\n private stopHeartbeat(): void {\n if (this.heartbeatTimer === null) return;\n clearInterval(this.heartbeatTimer);\n this.heartbeatTimer = null;\n }\n\n private publishHeartbeat(): void {\n const startedAt = Date.parse(this.options.client.startedAt);\n const now = Date.parse(this.now());\n this.publishEvent({\n type: 'client.heartbeat',\n payload: {\n uptimeMs:\n Number.isFinite(startedAt) && Number.isFinite(now) ? Math.max(0, now - startedAt) : 0,\n status: 'idle',\n },\n });\n }\n\n private async handleServerMessage(event: unknown): Promise<void> {\n const message = this.parseServerMessage(event);\n if (message?.type !== 'hq.command_batch') return;\n await this.handleCommandBatch(message);\n }\n\n private parseServerMessage(event: unknown): HqServerCommandBatchMessage | null {\n const data = this.extractMessageData(event);\n if (data === null) return null;\n try {\n const parsed = JSON.parse(data) as Partial<HqServerCommandBatchMessage>;\n if (parsed.type !== 'hq.command_batch' || !Array.isArray(parsed.commands)) return null;\n return parsed as HqServerCommandBatchMessage;\n } catch {\n return null;\n }\n }\n\n private extractMessageData(event: unknown): string | null {\n const value =\n typeof event === 'object' && event !== null && 'data' in event\n ? (event as { data?: unknown }).data\n : event;\n if (typeof value === 'string') return value;\n if (value instanceof ArrayBuffer) return new TextDecoder().decode(value);\n if (ArrayBuffer.isView(value)) {\n const bytes = new Uint8Array(value.buffer, value.byteOffset, value.byteLength);\n return new TextDecoder().decode(bytes);\n }\n return null;\n }\n\n private async handleCommandBatch(message: HqServerCommandBatchMessage): Promise<void> {\n const handler = this.options.onCommand;\n if (handler === undefined) return;\n\n for (const command of message.commands) {\n this.lastCommandId = command.commandId;\n try {\n const result = await handler(command);\n if (result !== undefined) this.ackCommand(result);\n else if (command.requiresAck)\n this.ackCommand({ commandId: command.commandId, status: 'accepted' });\n } catch (err) {\n this.ackCommand({\n commandId: command.commandId,\n status: 'failed',\n message: err instanceof Error ? err.message : String(err),\n });\n }\n }\n }\n\n private scheduleReconnect(): void {\n if (this.stopped || !this.reconnect || this.reconnectTimer !== null) return;\n const delay = Math.min(this.reconnectMaxMs, this.reconnectBaseMs * 2 ** this.reconnectAttempt);\n this.reconnectAttempt += 1;\n // One-time visibility for persistent failures. `reconnectAttempt` resets\n // on every successful open, so reaching the threshold means the endpoint\n // has NEVER accepted us in this streak \u2014 dead server or rejected token.\n if (!this.connectWarningEmitted && this.reconnectAttempt >= CONNECT_WARN_AFTER_FAILURES) {\n this.connectWarningEmitted = true;\n this.emitConnectWarning();\n }\n this.reconnectTimer = setTimeout(() => {\n this.reconnectTimer = null;\n this.connect();\n }, delay);\n this.reconnectTimer.unref?.();\n }\n\n private emitConnectWarning(): void {\n const attempt = this.lastAttempt;\n const message =\n `WrongStack HQ publisher: ${this.reconnectAttempt} consecutive connection failures` +\n `${attempt !== null ? ` to ${attempt.url} (client token ${attempt.hadToken ? 'present' : 'absent'})` : ''}. ` +\n 'Either the HQ server is unreachable or it rejected the token (401). ' +\n 'If HQ runs in client-token mode, verify WRONGSTACK_HQ_TOKEN / auth.json. Retries continue with backoff.';\n if (this.logger) {\n this.logger.warn(message, { event: 'hq.publisher.connect_failed' });\n return;\n }\n const warn =\n this.options.warn ??\n ((msg: string) =>\n console.warn(\n JSON.stringify({\n level: 'warn',\n event: 'hq.publisher.connect_failed',\n message: msg,\n timestamp: this.now(),\n }),\n ));\n try {\n warn(message);\n } catch {\n /* diagnostics must never break publishing */\n }\n }\n\n /**\n * Dormant re-check while no HQ endpoint is discoverable. Uses a FIXED\n * interval (not the exponential reconnect backoff): the check is a cheap\n * local file read, and backing off would delay attaching to an HQ the\n * user just started \u2014 the whole point of auto-discovery.\n */\n private scheduleDiscoveryPoll(): void {\n if (this.stopped || !this.reconnect || this.reconnectTimer !== null) return;\n this.reconnectAttempt = 0;\n this.reconnectTimer = setTimeout(() => {\n this.reconnectTimer = null;\n this.connect();\n }, this.options.discoveryPollMs ?? DEFAULT_DISCOVERY_POLL_MS);\n this.reconnectTimer.unref?.();\n }\n}\n", "import { createHash, randomUUID } from 'node:crypto';\nimport * as fs from 'node:fs';\nimport { hostname } from 'node:os';\nimport { basename } from 'node:path';\nimport { GlobalMailbox } from '../coordination/global-mailbox.js';\nimport type { EventBus } from '../kernel/events.js';\nimport type { HqClientConfig } from '../types/config.js';\nimport type { Logger } from '../types/logger.js';\nimport {\n type HqAuthFile,\n hqAuthFilePath,\n readHqRuntimeFileSync,\n resolveHqDataDir,\n} from './auth-store.js';\nimport type {\n HqClientCapability,\n HqClientIdentity,\n HqProjectIdentity,\n HqRedactionPolicy,\n} from './protocol.js';\nimport { HqPublisher, type HqPublisherCommandHandler, type HqSocketFactory } from './publisher.js';\n\nexport interface HqPublisherEnvConfig {\n url: string;\n token?: string;\n enabled?: boolean;\n rawContent?: boolean;\n projectAlias?: string;\n /**\n * Same-machine auto-discovery mode: no explicit URL was configured, so the\n * publisher should re-resolve the endpoint from `<dataDir>/runtime.json`\n * (+ the first client token in `auth.json`) before every connect attempt.\n * This lets every client on the machine attach to a `wstack --hq` that is\n * already running, starts later, or restarts on a different port.\n */\n discover?: boolean;\n /** Resolved HQ data dir the discovery reads from. */\n dataDir?: string;\n}\n\n/**\n * Discover a locally running `wstack --hq` endpoint: reads the runtime\n * marker (pid-liveness-checked) and the first client token. Returns\n * `undefined` when no live HQ is advertised on this machine.\n */\nexport function discoverLocalHqEndpoint(options: {\n dataDir?: string | undefined;\n env?: NodeJS.ProcessEnv | undefined;\n} = {}): { url: string; token?: string | undefined } | undefined {\n const dataDir = resolveHqDataDir(options.dataDir, options.env ?? process.env);\n const runtime = readHqRuntimeFileSync(dataDir);\n if (runtime === undefined) return undefined;\n const token = readFirstClientTokenFromAuthFile(dataDir);\n return { url: runtime.url, ...(token ? { token } : {}) };\n}\n\nfunction readFirstClientTokenFromAuthFile(dataDir: string): string | undefined {\n try {\n const raw = fs.readFileSync(hqAuthFilePath(dataDir), 'utf8');\n const parsed = JSON.parse(raw) as HqAuthFile;\n return parsed.clientTokens?.find((t) => t.token.trim().length > 0)?.token;\n } catch {\n return undefined;\n }\n}\n\n/**\n * True when an explicit HQ URL targets this machine. Falling back to the\n * LOCAL auth.json client token is only valid for same-machine servers \u2014 a\n * remote HQ has its own auth.json, and sending the local token would put the\n * publisher into a silent 401 reconnect loop.\n */\nfunction isLoopbackHqUrl(url: string): boolean {\n try {\n const host = new URL(url).hostname.toLowerCase();\n return host === '127.0.0.1' || host === 'localhost' || host === '::1' || host === '[::1]' || host === '0.0.0.0';\n } catch {\n return false;\n }\n}\n\nexport function resolveHqConfigFromEnv(env: NodeJS.ProcessEnv = process.env): HqPublisherEnvConfig | undefined {\n return resolveHqConfig({ env });\n}\n\nexport function resolveHqConfig(options: {\n env?: NodeJS.ProcessEnv | undefined;\n config?: HqClientConfig | undefined;\n} = {}): HqPublisherEnvConfig | undefined {\n const env = options.env ?? process.env;\n const fileConfig = options.config;\n const envUrl = env['WRONGSTACK_HQ_URL']?.trim();\n const envToken = env['WRONGSTACK_HQ_TOKEN']?.trim();\n const configUrl = fileConfig?.url?.trim();\n const configToken = fileConfig?.token?.trim();\n const envEnabledRaw = env['WRONGSTACK_HQ_ENABLED']?.trim();\n const enabled = envEnabledRaw !== undefined && envEnabledRaw.length > 0\n ? envEnabledRaw !== '0'\n : fileConfig?.enabled;\n const dataDir = resolveHqDataDir(fileConfig?.dataDir, env);\n const explicitToken = envToken || configToken;\n const runtimeUrl = readHqRuntimeFileSync(dataDir)?.url.trim();\n const url = envUrl || configUrl;\n // The local auth.json client token is only a valid fallback for\n // same-machine endpoints (discovery, or an explicit loopback URL). For a\n // remote URL without an explicit token, send NO token \u2014 the server's 401\n // is then an honest signal instead of a guaranteed-wrong local token.\n const localFallbackToken =\n !url || isLoopbackHqUrl(url) ? readFirstClientTokenFromAuthFile(dataDir) : undefined;\n const token = explicitToken || localFallbackToken;\n\n const rawContentEnv = env['WRONGSTACK_HQ_RAW_CONTENT']?.trim();\n const explicitRawContent = rawContentEnv ? rawContentEnv === '1' : fileConfig?.rawContent;\n const projectAliasEnv = env['WRONGSTACK_HQ_PROJECT_ALIAS']?.trim();\n const projectAlias = projectAliasEnv || fileConfig?.projectAlias;\n\n if (!url) {\n if (enabled === false) return undefined;\n // No explicit endpoint \u2192 same-machine auto-discovery (default ON).\n // The publisher re-resolves runtime.json + auth.json before every\n // connect attempt, so an HQ started AFTER this client \u2014 or restarted on\n // another port \u2014 is attached to automatically. While no HQ is running\n // the publisher stays dormant (bounded queue, cheap file poll).\n // Opt out with WRONGSTACK_HQ_ENABLED=0 or config `hq.enabled: false`.\n //\n // Same-machine HQ defaults to RAW content: the data never leaves this\n // machine and the operator watching HQ is the same user running the\n // sessions \u2014 a redacted chat history there is useless. Opt out with\n // WRONGSTACK_HQ_RAW_CONTENT=0 or `hq.rawContent: false` (/hq raw off).\n // Secret scrubbing + sensitive-field masking still always apply.\n return {\n url: runtimeUrl || 'http://127.0.0.1:3499',\n enabled: true,\n discover: true,\n dataDir,\n rawContent: explicitRawContent ?? true,\n ...(token ? { token } : {}),\n ...(projectAlias ? { projectAlias } : {}),\n };\n }\n\n // Explicit URL: raw content is the default for every HQ target. Operators\n // can still opt out with WRONGSTACK_HQ_RAW_CONTENT=0 or hq.rawContent=false,\n // and the HQ server can clamp disclosure with auth.json redactionPolicy.\n const rawContent = explicitRawContent ?? true;\n return {\n url,\n ...(token ? { token } : {}),\n ...(enabled !== undefined ? { enabled } : {}),\n ...(rawContent !== undefined ? { rawContent } : {}),\n ...(projectAlias ? { projectAlias } : {}),\n };\n}\n\nfunction stableMachineId(): string {\n // Stable per *physical machine*, NOT per process \u2014 every terminal on the\n // same computer must share one machineId so HQ groups them under a single\n // machine node. (Process identity already lives in clientId via the pid.)\n return createHash('sha256').update(hostname()).digest('hex').slice(0, 12);\n}\n\nfunction deriveProjectId(projectRoot: string): string {\n return createHash('sha256').update(projectRoot).digest('hex').slice(0, 12);\n}\n\nexport interface CreateHqPublisherOptions {\n clientKind: HqClientIdentity['kind'];\n projectRoot: string;\n projectName?: string;\n machineId?: string;\n hostnameOverride?: string;\n socketFactory?: HqSocketFactory;\n config?: HqPublisherEnvConfig;\n appConfig?: { hq?: HqClientConfig | undefined } | undefined;\n redactionPolicy?: Partial<HqRedactionPolicy>;\n /** Forwarded to the HqPublisher constructor (Phase 4 control plane). */\n capabilities?: readonly HqClientCapability[];\n /** Forwarded to the HqPublisher constructor (Phase 4 control plane). */\n onCommand?: HqPublisherCommandHandler;\n /** Dormant discovery re-check interval override (tests / tight loops). */\n discoveryPollMs?: number;\n /** Logger for structured connect-failure diagnostics. */\n logger?: Logger | undefined;\n}\n\nexport function createHqPublisherFromEnv(options: CreateHqPublisherOptions): HqPublisher | undefined {\n const config = options.config ?? resolveHqConfig({ config: options.appConfig?.hq });\n if (!config || config.enabled === false) return undefined;\n\n const machineId = options.machineId ?? stableMachineId();\n const host = options.hostnameOverride ?? hostname();\n const projectName = options.projectName ?? config.projectAlias ?? (basename(options.projectRoot) || 'unknown');\n\n const client: HqClientIdentity = {\n clientId: `${machineId}:${options.clientKind}:${process.pid}:${randomUUID().slice(0, 8)}`,\n kind: options.clientKind,\n machineId,\n ...(host ? { hostname: host } : {}),\n pid: process.pid,\n startedAt: new Date().toISOString(),\n };\n\n const project: HqProjectIdentity = {\n projectId: deriveProjectId(options.projectRoot),\n projectRoot: options.projectRoot,\n projectName,\n machineId,\n workspaceKind: 'git',\n };\n\n const redactionPolicy: Partial<HqRedactionPolicy> | undefined =\n options.redactionPolicy || config.rawContent !== undefined\n ? {\n ...(config.rawContent !== undefined ? { rawContent: config.rawContent } : {}),\n ...(options.redactionPolicy ?? {}),\n }\n : undefined;\n\n const discoveryDataDir = config.dataDir;\n return new HqPublisher({\n url: config.url,\n ...(config.token ? { token: config.token } : {}),\n client,\n project,\n ...(options.socketFactory ? { socketFactory: options.socketFactory } : {}),\n ...(redactionPolicy !== undefined ? { redactionPolicy } : {}),\n ...(options.capabilities !== undefined ? { capabilities: options.capabilities } : {}),\n ...(options.onCommand !== undefined ? { onCommand: options.onCommand } : {}),\n // Auto-discovery: re-read the local HQ runtime marker + client token on\n // every connect attempt so late-started/restarted HQs are picked up.\n ...(config.discover\n ? { resolveEndpoint: () => discoverLocalHqEndpoint({ dataDir: discoveryDataDir }) }\n : {}),\n ...(options.discoveryPollMs !== undefined ? { discoveryPollMs: options.discoveryPollMs } : {}),\n ...(options.logger !== undefined ? { logger: options.logger } : {}),\n });\n}\n\nexport interface CreateGlobalMailboxOptions {\n projectDir: string;\n events?: EventBus;\n hqPublisher?: HqPublisher;\n}\n\nexport function createGlobalMailbox(options: CreateGlobalMailboxOptions): GlobalMailbox {\n return new GlobalMailbox(options.projectDir, options.events, options.hqPublisher);\n}\n", "/**\n * GlobalMailbox \u2014 project-level inter-agent mailbox with cross-session support.\n *\n * Stores messages at `~/.wrongstack/projects/<slug>/_mailbox.jsonl` so all\n * sessions (terminals, WebUIs) working on the same project share one inbox.\n *\n * Features:\n * - Agent registration + heartbeat (agents go stale after 60s without heartbeat)\n * - Per-recipient read receipts (readBy[agentId] = ISO8601)\n * - Atomic file-locking for concurrent multi-process writes\n * - Unread count for new-mail notifications\n * - Online agent list\n *\n * @module GlobalMailbox\n */\n\nimport { randomUUID } from 'node:crypto';\nimport * as fsp from 'node:fs/promises';\n\nimport * as path from 'node:path';\nimport type { HqPublisher } from '../hq/publisher.js';\nimport type { EventBus } from '../kernel/events.js';\nimport { withFileLock } from '../utils/atomic-write.js';\nimport { projectSlug } from '../utils/wstack-paths.js';\nimport {\n AGENT_STALE_MS,\n AUTO_COMPACT_DEFAULT_TTL_MS,\n AUTO_COMPACT_INTERVAL_MS,\n AUTO_COMPACT_READ_MAX_AGE_MS,\n CLIENT_STALE_MS,\n HEARTBEAT_THROTTLE_MS,\n LINE_SEPARATOR,\n MESSAGE_CACHE_MAX_ENTRIES,\n REGISTRY_CACHE_TTL_MS,\n} from './mailbox-constants.js';\nimport type { MailboxEventEmitter } from './mailbox-events.js';\nimport { normalizeMailboxMessageType, parseMailboxMessageLine } from './mailbox-message-codec.js';\nimport type {\n AgentHeartbeatInput,\n AgentRegistrationInput,\n AutoCompactOptions,\n AutoCompactResult,\n ClientHeartbeatInput,\n ClientRegistrationInput,\n ClientStatus,\n Mailbox,\n MailboxAckBatchInput,\n MailboxAckInput,\n MailboxAgentStatus,\n MailboxMessage,\n MailboxQuery,\n MailboxSendInput,\n PurgeOptions,\n PurgeResult,\n RegisteredAgent,\n RegisteredClient,\n} from './mailbox-types.js';\nimport { normalizeRecipient } from './mailbox-types.js';\n\n// \u2500\u2500 Constants \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst MAILBOX_FILE = '_mailbox.jsonl';\nconst CLIENT_REGISTRY_FILE = '_mailbox.clients.json';\n\ntype HqPublisherRef = HqPublisher | (() => HqPublisher | undefined);\n\n/**\n * Derive the project-level mailbox directory path.\n *\n * Delegates to the CANONICAL `projectSlug()` from wstack-paths so every\n * surface (CLI, TUI, WebUI, mailbox tool, loop checker) lands in the exact\n * same `~/.wrongstack/projects/<slug>/` directory. A previous inline copy\n * skipped the leading/trailing-hyphen strip, which silently split agents\n * working on projects with non-alphanumeric name edges into TWO mailboxes.\n *\n * @param projectRoot \u2014 absolute path to the project root\n * @param globalRoot \u2014 `~/.wrongstack` (or custom global root)\n */\nexport function resolveProjectDir(projectRoot: string, globalRoot: string): string {\n return path.join(globalRoot, 'projects', projectSlug(projectRoot));\n}\n\n// \u2500\u2500 Singleton factory \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Process-wide registry of GlobalMailbox instances, keyed by projectDir.\n *\n * Without this, `attachMailboxChecker` and `attachFleetPulse` each created\n * a SEPARATE GlobalMailbox for the same project directory \u2014 two independent\n * mtime caches, two read chains, two sets of heartbeat timers. The factory\n * ensures that within a single process there is at most one instance per\n * project directory, so cache hit ratio is maximized and I/O is minimized.\n *\n * Cross-process sharing still works as before (the JSONL file + file lock\n * is the source of truth); this is purely an in-process optimization.\n *\n * Pass `forceNew: true` to bypass the cache (used by tests that need an\n * isolated tmpdir instance without polluting the singleton).\n */\nconst _mailboxInstances = new Map<string, GlobalMailbox>();\n\nexport function getSharedMailbox(\n projectDir: string,\n events?: EventBus,\n hqPublisher?: HqPublisherRef,\n opts?: { forceNew?: boolean },\n): GlobalMailbox {\n if (opts?.forceNew) {\n return new GlobalMailbox(projectDir, events, hqPublisher);\n }\n const existing = _mailboxInstances.get(projectDir);\n if (existing !== undefined) return existing;\n const mb = new GlobalMailbox(projectDir, events, hqPublisher);\n _mailboxInstances.set(projectDir, mb);\n return mb;\n}\n\n/** Clear the singleton registry \u2014 used by tests to avoid cross-test leakage. */\nexport function _clearMailboxSingletons(): void {\n _mailboxInstances.clear();\n}\n\n// \u2500\u2500 GlobalMailbox \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport class GlobalMailbox implements Mailbox {\n /** Path to the JSONL message file. */\n readonly messagePath: string;\n /** Path to the JSON agent registry file. */\n readonly registryPath: string;\n /** Path to the JSON client registry file. */\n readonly clientRegistryPath: string;\n /** Optional event bus for emitting agent registration/heartbeat events. */\n private readonly _events?: EventBus | undefined;\n /** Optional HQ publisher for cross-project command-center telemetry. */\n private readonly _hqPublisher?: HqPublisherRef | undefined;\n /**\n * Optional SSE event emitter for real-time push to HTTP bridge clients.\n * When present, `send`/`ack`/`softDelete`/`restore` emit events that\n * connected SSE subscribers receive instantly.\n */\n readonly eventEmitter?: MailboxEventEmitter | undefined;\n /**\n * Local cache of the agent registry to avoid re-reading on every call.\n * Time-bounded: the registry file is shared ACROSS PROCESSES (that's the\n * whole point of GlobalMailbox), so a cache served forever would never see\n * agents registered by other sessions. Writers always bypass it.\n */\n private _registryCache: Map<string, RegisteredAgent> | null = null;\n /** When the registry cache was last refreshed from disk (epoch ms). */\n private _registryCacheAt = 0;\n /**\n * Local cache of the client registry to avoid re-reading on every call.\n * Same reasoning as agent registry cache.\n */\n private _clientRegistryCache: Map<string, RegisteredClient> | null = null;\n /** When the client registry cache was last refreshed from disk (epoch ms). */\n private _clientRegistryCacheAt = 0;\n /** Last time each local agent sent a heartbeat (throttle). */\n private _lastHeartbeat = new Map<string, number>();\n /** Last time each local client sent a heartbeat (throttle). */\n private _lastClientHeartbeat = new Map<string, number>();\n /**\n * In-memory mirror of the JSONL message file. The mailbox is shared\n * ACROSS PROCESSES, so reads cannot trust the cache blindly \u2014 we pair it\n * with an mtime check. The file lock serializes every write, so a\n * changed mtimeMs is a definitive signal that another process (or this\n * one) wrote; an unchanged mtimeMs guarantees no write happened and the\n * cache is current. This collapses the per-iteration `query()` cost from\n * O(file_size) disk + parse to O(messages) in memory.\n */\n private _messageCache: MailboxMessage[] | null = null;\n /** mtimeMs of the file when `_messageCache` was populated. */\n private _messageCacheMtime = -1;\n /** Size of the file when `_messageCache` was populated (extra guard). */\n private _messageCacheSize = -1;\n /**\n * Serializes reads of the message file so overlapping concurrent\n * `_readMessagesCached()` calls don't both enter the incremental \"file\n * only grew\" branch against the same stale `_messageCacheSize` and\n * each push the same tail bytes onto the cache (duplicating every\n * appended message). The chain runs each read to completion before\n * the next starts, in issue order \u2014 readers are read-only and never\n * conflict with each other on content, only on the cache mutation\n * that follows the read. Pattern mirrors `DefaultMemoryStore.runSerialized`.\n */\n private _readChain: Promise<MailboxMessage[]> = Promise.resolve([] as MailboxMessage[]);\n\n /**\n * Recipient \u2192 Set of indices into `_messageCache`. Maintained alongside\n * the cache so `query({ to })` and `unreadCount(agentId)` can skip the\n * O(N) full scan and iterate only the messages addressed to the target\n * recipient (plus broadcasts `*`).\n *\n * The index is rebuilt whenever the cache array is replaced\n * (`_setMessageCache`), extended when new messages are pushed\n * (`_pushToCache`, `_readNewMessagesOnly`), and cleared on `close()`.\n * It is `null` when the cache itself is null (> MESSAGE_CACHE_MAX_ENTRIES\n * or never populated).\n *\n * Safety: array indices are valid only as long as the cache array\n * reference hasn't changed. Since we rebuild the index in the same\n * synchronous step that replaces the cache, a reader that calls\n * `_readMessagesCached()` either gets the old array + old index, or\n * the new array + new index \u2014 never a mismatch.\n */\n private _recipientIndex: Map<string, Set<number>> | null = null;\n\n /**\n * Sender \u2192 Set of indices into `_messageCache`. Same lifecycle and\n * safety properties as `_recipientIndex`, but keyed on `msg.from`\n * so `query({ from })` can skip the full scan.\n */\n private _senderIndex: Map<string, Set<number>> | null = null;\n\n /**\n * @param projectDir \u2014 `~/.wrongstack/projects/<slug>/`\n * @param events \u2014 optional EventBus for real-time TUI/WebUI notifications\n * @param hqPublisher \u2014 optional HQ publisher, or getter, for cross-project telemetry\n * @param eventEmitter \u2014 optional SSE event emitter for HTTP bridge push\n */\n constructor(\n projectDir: string,\n events?: EventBus,\n hqPublisher?: HqPublisherRef,\n eventEmitter?: MailboxEventEmitter,\n ) {\n this.messagePath = path.join(projectDir, MAILBOX_FILE);\n this.registryPath = path.join(projectDir, '_mailbox.registry.json');\n this.clientRegistryPath = path.join(projectDir, CLIENT_REGISTRY_FILE);\n this._events = events;\n this._hqPublisher = hqPublisher;\n this.eventEmitter = eventEmitter;\n }\n\n private get hqMailboxId(): string {\n return `${path.basename(path.dirname(this.messagePath))}:mailbox`;\n }\n\n private get hqPublisher(): HqPublisher | undefined {\n return typeof this._hqPublisher === 'function' ? this._hqPublisher() : this._hqPublisher;\n }\n\n private publishHqMailboxEvent(input: Parameters<HqPublisher['publishMailboxEvent']>[0]): void {\n try {\n this.hqPublisher?.publishMailboxEvent(input);\n } catch {\n // HQ telemetry is best-effort and must never affect mailbox behavior.\n }\n }\n\n private publishHqMailboxSnapshot(): void {\n const publisher = this.hqPublisher;\n if (publisher === undefined) return;\n void publisher.publishMailboxSnapshot(this, { mailboxId: this.hqMailboxId }).catch(() => {\n // HQ telemetry is best-effort and must never affect mailbox behavior.\n });\n }\n\n // \u2500\u2500 Messages \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n async send(input: MailboxSendInput): Promise<MailboxMessage> {\n const now = new Date().toISOString();\n const msg: MailboxMessage = {\n id: randomUUID(),\n from: input.from,\n // \"all\" is an accepted spelling of the broadcast address \u2014 canonical\n // form on disk is '*' so every query/checker matches it.\n to: normalizeRecipient(input.to),\n type: normalizeMailboxMessageType(input.type),\n subject: input.subject,\n body: input.body,\n priority: input.priority ?? 'normal',\n readBy: {},\n completed: false,\n timestamp: now,\n replyTo: input.replyTo,\n taskContext: input.taskContext,\n expiresAt:\n input.ttlMs !== undefined ? new Date(Date.now() + input.ttlMs).toISOString() : undefined,\n };\n\n const line = JSON.stringify(msg) + LINE_SEPARATOR;\n await fsp.mkdir(path.dirname(this.messagePath), { recursive: true });\n // The append must hold the same lock ack() rewrites under: an unlocked\n // append racing ack's read\u2192rewrite gets silently erased when the rewrite\n // lands. This file is shared ACROSS PROCESSES, so the window is real.\n await withFileLock(this.messagePath, async () => {\n await fsp.appendFile(this.messagePath, line, 'utf8');\n // Capture the post-append stat INSIDE the lock so the cache trackers\n // advance with the pushed content. A concurrent reader that lands\n // after we release but before a future stat would otherwise see the\n // file grew and re-append the just-sent tail, duplicating it.\n const { mtimeMs, size } = await this._statMessageFile();\n // Refresh the in-memory cache from the message we just appended \u2014\n // cheaper than re-reading the whole file, and correct because we\n // held the lock so nothing else changed underneath us.\n this._pushToCache(msg, mtimeMs, size);\n });\n\n this.publishHqMailboxEvent({\n mailboxId: this.hqMailboxId,\n action: 'message.sent',\n message: msg,\n });\n this.publishHqMailboxSnapshot();\n\n // In-process push notification: same-process mailbox consumers (the\n // awareness poller, fleet pulse, TUI/WebUI) can listen on this event\n // to get real-time updates instead of polling on every iteration.\n this._events?.emitCustom('mailbox.message_sent', {\n messageId: msg.id,\n from: msg.from,\n to: msg.to,\n type: msg.type,\n subject: msg.subject,\n });\n // SSE push for external HTTP bridge clients.\n this.eventEmitter?.emit({\n type: 'message.sent' as const,\n messageId: msg.id,\n from: msg.from,\n to: msg.to,\n timestamp: now,\n });\n\n return msg;\n }\n\n async query(q: MailboxQuery): Promise<MailboxMessage[]> {\n const queryType = q.type === undefined ? undefined : normalizeMailboxMessageType(q.type);\n const all = await this._readMessagesCached();\n const limit = q.limit ?? 50;\n\n // Single-pass filter \u2014 previously 7 chained .filter() allocations each\n // producing a fresh array. Predicates are independent, so we can AND\n // them in one walk and short-circuit per element.\n const order = q.minPriority !== undefined ? ({ low: 0, normal: 1, high: 2 } as const) : null;\n const minPriorityRank = order && q.minPriority !== undefined ? order[q.minPriority] : 0;\n const out: MailboxMessage[] = [];\n\n // Recipient index fast-path: when the query filters by `to` AND no\n // other broad filter (from, type, etc.) would benefit from the index,\n // iterate only the messages addressed to the target recipient (plus\n // broadcasts `*`) instead of scanning the full cache. Falls back to\n // the full scan when the index is unavailable or when multiple\n // non-recipient filters are present (the index doesn't help there).\n //\n // Sender index fast-path: symmetric \u2014 when filtering ONLY by `from`\n // (no `to`, `type`, `minPriority`), iterate only messages from that\n // sender.\n let candidates: Iterable<MailboxMessage>;\n if (\n q.to !== undefined &&\n this._recipientIndex !== null &&\n q.from === undefined &&\n q.type === undefined &&\n q.minPriority === undefined\n ) {\n // Collect candidate indices: messages addressed to `q.to` + broadcasts.\n const indices = new Set<number>();\n const direct = this._recipientIndex.get(q.to);\n if (direct !== undefined) for (const i of direct) indices.add(i);\n const broadcasts = this._recipientIndex.get('*');\n if (broadcasts !== undefined) for (const i of broadcasts) indices.add(i);\n candidates = [...indices].sort((a, b) => a - b).map((i) => all[i]!);\n } else if (\n q.from !== undefined &&\n q.to === undefined &&\n this._senderIndex !== null &&\n q.type === undefined &&\n q.minPriority === undefined\n ) {\n // Sender index fast-path: iterate only messages from `q.from`.\n const indices = this._senderIndex.get(q.from);\n candidates =\n indices !== undefined ? [...indices].sort((a, b) => a - b).map((i) => all[i]!) : [];\n } else {\n candidates = all;\n }\n\n for (const m of candidates) {\n if (q.to !== undefined && m.to !== q.to && m.to !== '*') continue;\n if (q.from !== undefined && m.from !== q.from) continue;\n if (q.unreadBy !== undefined && q.unreadBy in m.readBy) continue;\n if (q.incompleteOnly && m.completed) continue;\n if (queryType !== undefined && m.type !== queryType) continue;\n if (order !== null && (order[m.priority as keyof typeof order] ?? 1) < minPriorityRank!) {\n continue;\n }\n if (q.since !== undefined && m.timestamp <= q.since) continue;\n // Default behavior: soft-deleted messages are hidden unless the\n // caller explicitly opts in via `includeDeleted: true` (used by\n // the WebUI's \"trash\" view).\n if (!q.includeDeleted && m.deletedAt !== undefined) continue;\n out.push(m);\n }\n\n out.sort((a, b) => b.timestamp.localeCompare(a.timestamp));\n // Return defensive shallow copies so callers cannot mutate the shared\n // cache entries. Only the returned slice is copied \u2014 O(limit), not O(N).\n return out.slice(0, limit).map((m) => ({ ...m, readBy: { ...m.readBy } }));\n }\n\n async ack(input: MailboxAckInput): Promise<MailboxMessage | null> {\n const updated = await this.ackMany({ acks: [input] });\n return updated.length > 0 ? updated[0]! : null;\n }\n\n async ackMany(input: MailboxAckBatchInput): Promise<MailboxMessage[]> {\n // One lock acquisition + one file rewrite for the whole batch. The\n // previous per-message ack() did a full read-modify-rewrite for every\n // single ack \u2014 N fresh messages meant N full-file rewrites in a row.\n if (input.acks.length === 0) return [];\n\n const updated: MailboxMessage[] = [];\n const byId = new Map<string, MailboxAckInput>();\n for (const a of input.acks) {\n // Last-write-wins within the batch for the same messageId \u2014 matches\n // the prior sequential semantics where later acks overrode earlier.\n byId.set(a.messageId, a);\n }\n\n await withFileLock(this.messagePath, async () => {\n // Read fresh under the lock \u2014 the cache may be stale relative to\n // other processes that wrote since our last read.\n const all = await this._readMessagesFresh();\n const now = new Date().toISOString();\n let changed = false;\n\n for (const msg of all) {\n const a = byId.get(msg.id);\n if (!a) continue;\n // Preserve prior semantics: return the message as long as it was\n // found, even if the ack was a no-op (e.g. already read).\n updated.push(msg);\n if (a.read !== false && !(a.readerId in msg.readBy)) {\n msg.readBy[a.readerId] = now;\n changed = true;\n }\n if (a.completed && !msg.completed) {\n msg.completed = true;\n msg.completedBy = a.readerId;\n msg.completedAt = now;\n changed = true;\n }\n if (a.outcome !== undefined && msg.outcome !== a.outcome) {\n msg.outcome = a.outcome;\n changed = true;\n }\n }\n\n // Only rewrite the file if at least one ack actually mutated state \u2014\n // a re-ack of an already-read message is now a no-op on disk, where\n // previously it was a full rewrite.\n if (changed) {\n const serialized = all.map((m) => JSON.stringify(m)).join(LINE_SEPARATOR) + LINE_SEPARATOR;\n await fsp.writeFile(this.messagePath, serialized, 'utf8');\n }\n // Promote the cache INSIDE the lock with the post-write (or\n // post-read when unchanged) stat so the mtime/size trackers are set\n // synchronously with the content \u2014 no race window where a concurrent\n // reader sees fresh content but stale trackers and misclassifies a\n // rewrite as a \"file only grew\" append.\n const { mtimeMs, size } = await this._statMessageFile();\n this._setMessageCache(all, mtimeMs, size);\n });\n\n for (const message of updated) {\n this.publishHqMailboxEvent({\n mailboxId: this.hqMailboxId,\n action: message.completed ? 'message.completed' : 'message.read',\n message,\n });\n // SSE push for external HTTP bridge clients.\n this.eventEmitter?.emit({\n type: 'message.acked' as const,\n messageId: message.id,\n from: message.from,\n to: message.to,\n timestamp: new Date().toISOString(),\n });\n }\n if (updated.length > 0) this.publishHqMailboxSnapshot();\n return updated;\n }\n\n async unreadCount(forAgentId: string): Promise<number> {\n const all = await this._readMessagesCached();\n let count = 0;\n\n // Recipient index fast-path: iterate only messages addressed to this\n // agent + broadcasts, instead of the full cache.\n if (this._recipientIndex !== null) {\n const indices = new Set<number>();\n const direct = this._recipientIndex.get(forAgentId);\n if (direct !== undefined) for (const i of direct) indices.add(i);\n const broadcasts = this._recipientIndex.get('*');\n if (broadcasts !== undefined) for (const i of broadcasts) indices.add(i);\n for (const i of indices) {\n const m = all[i]!;\n if (!(forAgentId in m.readBy) && !m.completed) count++;\n }\n } else {\n for (let i = 0; i < all.length; i++) {\n const m = all[i]!;\n if ((m.to === forAgentId || m.to === '*') && !(forAgentId in m.readBy) && !m.completed) {\n count++;\n }\n }\n }\n return count;\n }\n\n async softDelete(mailId: string, by: string): Promise<MailboxMessage | null> {\n // Single-message soft delete. Acquires the file lock and writes\n // the file with the matched message's `deletedAt` set. No-op if\n // the message does not exist or is already soft-deleted (the\n // second case is a successful no-op: returns the message with\n // `deletedAt` unchanged).\n let updated: MailboxMessage | null = null;\n await withFileLock(this.messagePath, async () => {\n const all = await this._readMessagesFresh();\n const now = new Date().toISOString();\n let changed = false;\n for (const m of all) {\n if (m.id !== mailId) continue;\n if (m.deletedAt !== undefined) {\n // Already soft-deleted \u2014 return the existing record so the\n // caller can no-op cleanly. No event is published.\n updated = m;\n continue;\n }\n m.deletedAt = now;\n m.deletedBy = by;\n updated = m;\n changed = true;\n }\n // Only rewrite the file if the soft-delete actually mutated state \u2014\n // a re-delete of an already-deleted message is a no-op on disk.\n if (changed) {\n const serialized = all.map((m) => JSON.stringify(m)).join(LINE_SEPARATOR) + LINE_SEPARATOR;\n await fsp.writeFile(this.messagePath, serialized, 'utf8');\n }\n // Promote the cache inside the lock with the post-write stat so the\n // mtime/size trackers are set synchronously with the content.\n const { mtimeMs, size } = await this._statMessageFile();\n this._setMessageCache(all, mtimeMs, size);\n });\n if (updated !== null) {\n const msg = updated as MailboxMessage;\n this.publishHqMailboxEvent({\n mailboxId: this.hqMailboxId,\n action: 'message.updated',\n message: msg,\n });\n this.publishHqMailboxSnapshot();\n // SSE push for external HTTP bridge clients.\n this.eventEmitter?.emit({\n type: 'message.deleted' as const,\n messageId: msg.id,\n from: msg.from,\n to: msg.to,\n timestamp: msg.deletedAt ?? new Date().toISOString(),\n });\n }\n return updated;\n }\n\n async restore(mailId: string): Promise<MailboxMessage | null> {\n // Inverse of `softDelete`. Clears `deletedAt` + `deletedBy` so the\n // message reappears in the default `query()` result. No-op when\n // the message exists but is not currently soft-deleted. Emits an\n // event unconditionally so the WebUI can re-fetch the message\n // (the duplicate-event cost is acceptable: the WebUI dedupes by\n // `mailId`).\n let updated: MailboxMessage | null = null;\n await withFileLock(this.messagePath, async () => {\n const all = await this._readMessagesFresh();\n let changed = false;\n for (const m of all) {\n if (m.id !== mailId) continue;\n if (m.deletedAt === undefined && m.deletedBy === undefined) {\n // Not soft-deleted \u2014 no-op, return the message as-is.\n updated = m;\n continue;\n }\n delete m.deletedAt;\n delete m.deletedBy;\n updated = m;\n changed = true;\n }\n if (changed) {\n const serialized = all.map((m) => JSON.stringify(m)).join(LINE_SEPARATOR) + LINE_SEPARATOR;\n await fsp.writeFile(this.messagePath, serialized, 'utf8');\n }\n // Promote the cache inside the lock with the post-write stat so the\n // mtime/size trackers are set synchronously with the content.\n const { mtimeMs, size } = await this._statMessageFile();\n this._setMessageCache(all, mtimeMs, size);\n });\n if (updated !== null) {\n const msg = updated as MailboxMessage;\n this.publishHqMailboxEvent({\n mailboxId: this.hqMailboxId,\n action: 'message.updated',\n message: msg,\n });\n this.publishHqMailboxSnapshot();\n // SSE push for external HTTP bridge clients.\n this.eventEmitter?.emit({\n type: 'message.restored' as const,\n messageId: msg.id,\n from: msg.from,\n to: msg.to,\n timestamp: new Date().toISOString(),\n });\n }\n return updated;\n }\n\n // \u2500\u2500 Agent registry \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n async registerAgent(input: AgentRegistrationInput): Promise<void> {\n await this._ensureRegistry();\n const now = new Date().toISOString();\n const agent: RegisteredAgent = {\n agentId: input.agentId,\n sessionId: input.sessionId,\n name: input.name,\n role: input.role,\n status: 'idle',\n currentTool: undefined,\n currentTask: undefined,\n iterations: 0,\n toolCalls: 0,\n registeredAt: now,\n lastSeenAt: now,\n pid: input.pid,\n source: input.source,\n };\n\n await withFileLock(this.registryPath, async () => {\n // fresh: read-modify-write must start from the on-disk state, not the\n // cache \u2014 other processes may have registered agents since.\n const registry = await this._readRegistry({ fresh: true });\n // Prune stale agents\n this._pruneStaleInPlace(registry);\n // Upsert\n registry.set(input.agentId, agent);\n // Update cache\n this._registryCache = registry;\n this._registryCacheAt = Date.now();\n await this._writeRegistry(registry);\n });\n\n // Emit event for TUI/WebUI to update online agent count\n this._events?.emitCustom('mailbox.agent_registered', {\n agentId: input.agentId,\n sessionId: input.sessionId,\n name: input.name,\n role: input.role,\n source: input.source,\n });\n this.publishHqMailboxEvent({\n mailboxId: this.hqMailboxId,\n action: 'agent.registered',\n agent: {\n agentId: input.agentId,\n name: input.name,\n ...(input.role !== undefined ? { role: input.role } : {}),\n sessionId: input.sessionId,\n status: 'idle',\n iterations: 0,\n toolCalls: 0,\n lastActivityAt: now,\n lastSeenAt: now,\n online: true,\n pid: input.pid,\n ...(input.source !== undefined ? { source: input.source } : {}),\n },\n });\n this.publishHqMailboxSnapshot();\n }\n\n async deregisterAgent(agentId: string): Promise<void> {\n await this._ensureRegistry();\n let removed: RegisteredAgent | undefined;\n await withFileLock(this.registryPath, async () => {\n const registry = await this._readRegistry({ fresh: true });\n this._pruneStaleInPlace(registry);\n // Capture the record before deletion so HQ telemetry can emit a full,\n // well-typed agent summary rather than a bare id.\n removed = registry.get(agentId);\n registry.delete(agentId);\n this._registryCache = registry;\n this._registryCacheAt = Date.now();\n await this._writeRegistry(registry);\n });\n this._events?.emitCustom('mailbox.agent_deregistered', {\n agentId,\n });\n this.publishHqMailboxEvent({\n mailboxId: this.hqMailboxId,\n action: 'agent.deregistered',\n agent: {\n agentId,\n name: removed?.name ?? agentId,\n ...(removed?.role !== undefined ? { role: removed.role } : {}),\n sessionId: removed?.sessionId ?? '',\n status: 'offline',\n ...(removed?.currentTool !== undefined ? { currentTool: removed.currentTool } : {}),\n ...(removed?.currentTask !== undefined ? { currentTask: removed.currentTask } : {}),\n iterations: removed?.iterations ?? 0,\n toolCalls: removed?.toolCalls ?? 0,\n lastActivityAt: removed?.lastSeenAt ?? new Date().toISOString(),\n lastSeenAt: removed?.lastSeenAt ?? new Date().toISOString(),\n online: false,\n pid: removed?.pid ?? 0,\n ...(removed?.source !== undefined ? { source: removed.source } : {}),\n },\n });\n this.publishHqMailboxSnapshot();\n }\n\n async heartbeat(input: AgentHeartbeatInput): Promise<void> {\n // Throttle: at most one heartbeat per agent per HEARTBEAT_THROTTLE_MS\n const last = this._lastHeartbeat.get(input.agentId) ?? 0;\n const now = Date.now();\n if (now - last < HEARTBEAT_THROTTLE_MS) return;\n\n this._lastHeartbeat.set(input.agentId, now);\n\n await this._ensureRegistry();\n\n await withFileLock(this.registryPath, async () => {\n // fresh: see registerAgent \u2014 never read-modify-write from the cache.\n const registry = await this._readRegistry({ fresh: true });\n this._pruneStaleInPlace(registry);\n\n const agent = registry.get(input.agentId);\n if (agent) {\n const iso = new Date().toISOString();\n agent.lastSeenAt = iso;\n if (input.status !== undefined) agent.status = input.status;\n if (input.currentTool !== undefined) agent.currentTool = input.currentTool;\n if (input.currentTask !== undefined) agent.currentTask = input.currentTask;\n if (input.iterations !== undefined) agent.iterations = input.iterations;\n if (input.toolCalls !== undefined) agent.toolCalls = input.toolCalls;\n }\n // If agent not registered yet, silently skip \u2014 registerAgent first\n\n this._registryCache = registry;\n this._registryCacheAt = Date.now();\n await this._writeRegistry(registry);\n });\n\n // Emit event so TUI/WebUI can track online agents in real time\n this._events?.emitCustom('mailbox.agent_heartbeat', {\n agentId: input.agentId,\n status: input.status,\n currentTool: input.currentTool,\n currentTask: input.currentTask,\n });\n this.publishHqMailboxEvent({\n mailboxId: this.hqMailboxId,\n action: 'agent.heartbeat',\n summary: input.agentId,\n });\n this.publishHqMailboxSnapshot();\n }\n\n async getAgentStatuses(): Promise<MailboxAgentStatus[]> {\n await this._ensureRegistry();\n let registry = await this._readRegistry();\n const before = registry.size;\n this._pruneStaleInPlace(registry);\n\n // A read can be the only activity after every process in a project exits.\n // Persist expiry under the file lock so old agents do not survive forever\n // in `_mailbox.registry.json` (or race a concurrent registration).\n if (registry.size < before) {\n await withFileLock(this.registryPath, async () => {\n const fresh = await this._readRegistry({ fresh: true });\n this._pruneStaleInPlace(fresh);\n this._registryCache = fresh;\n this._registryCacheAt = Date.now();\n await this._writeRegistry(fresh);\n registry = fresh;\n });\n }\n\n const now = Date.now();\n return Array.from(registry.values())\n .map((a) => ({\n agentId: a.agentId,\n name: a.name,\n role: a.role,\n sessionId: a.sessionId,\n status: a.status,\n currentTool: a.currentTool,\n currentTask: a.currentTask,\n iterations: a.iterations,\n toolCalls: a.toolCalls,\n lastActivityAt: a.lastSeenAt,\n lastSeenAt: a.lastSeenAt,\n online: now - new Date(a.lastSeenAt).getTime() < AGENT_STALE_MS,\n pid: a.pid,\n source: a.source,\n }))\n .sort((a, b) => b.lastSeenAt.localeCompare(a.lastSeenAt));\n }\n\n async getOnlineAgents(): Promise<MailboxAgentStatus[]> {\n const all = await this.getAgentStatuses();\n return all.filter((a) => a.online);\n }\n\n // \u2500\u2500 Client registry \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n async registerClient(input: ClientRegistrationInput): Promise<void> {\n await this._ensureClientRegistry();\n const now = new Date().toISOString();\n const client: RegisteredClient = {\n clientId: input.clientId,\n sessionId: input.sessionId,\n name: input.name,\n source: input.source,\n registeredAt: now,\n lastSeenAt: now,\n pid: input.pid,\n };\n\n await withFileLock(this.clientRegistryPath, async () => {\n const registry = await this._readClientRegistry({ fresh: true });\n this._pruneStaleClientsInPlace(registry);\n registry.set(input.clientId, client);\n this._clientRegistryCache = registry;\n this._clientRegistryCacheAt = Date.now();\n await this._writeClientRegistry(registry);\n });\n\n // Emit event for TUI/WebUI to update online client count\n this._events?.emitCustom('mailbox.client_registered', {\n clientId: input.clientId,\n sessionId: input.sessionId,\n name: input.name,\n source: input.source,\n });\n this.publishHqMailboxSnapshot();\n }\n\n async deregisterClient(clientId: string): Promise<void> {\n await this._ensureClientRegistry();\n await withFileLock(this.clientRegistryPath, async () => {\n const registry = await this._readClientRegistry({ fresh: true });\n this._pruneStaleClientsInPlace(registry);\n registry.delete(clientId);\n this._clientRegistryCache = registry;\n this._clientRegistryCacheAt = Date.now();\n await this._writeClientRegistry(registry);\n });\n this._lastClientHeartbeat.delete(clientId);\n this._events?.emitCustom('mailbox.client_deregistered', { clientId });\n this.publishHqMailboxSnapshot();\n }\n\n async clientHeartbeat(input: ClientHeartbeatInput): Promise<void> {\n // Throttle: at most one heartbeat per client per HEARTBEAT_THROTTLE_MS\n const last = this._lastClientHeartbeat.get(input.clientId) ?? 0;\n const now = Date.now();\n if (now - last < HEARTBEAT_THROTTLE_MS) return;\n\n this._lastClientHeartbeat.set(input.clientId, now);\n\n await this._ensureClientRegistry();\n\n await withFileLock(this.clientRegistryPath, async () => {\n const registry = await this._readClientRegistry({ fresh: true });\n this._pruneStaleClientsInPlace(registry);\n\n const client = registry.get(input.clientId);\n if (client) {\n client.lastSeenAt = new Date().toISOString();\n if (typeof input.sessionId === 'string' && input.sessionId.length > 0) {\n client.sessionId = input.sessionId;\n }\n }\n\n this._clientRegistryCache = registry;\n this._clientRegistryCacheAt = Date.now();\n await this._writeClientRegistry(registry);\n });\n\n // Emit event so TUI/WebUI can track online clients in real time\n this._events?.emitCustom('mailbox.client_heartbeat', {\n clientId: input.clientId,\n ...(input.sessionId ? { sessionId: input.sessionId } : {}),\n });\n this.publishHqMailboxSnapshot();\n }\n\n async getClientStatuses(): Promise<ClientStatus[]> {\n await this._ensureClientRegistry();\n const registry = await this._readClientRegistry();\n const before = registry.size;\n this._pruneStaleClientsInPlace(registry);\n\n // Persist the pruning so stale entries in _mailbox.clients.json don't\n // accumulate indefinitely. Without this, `getClientStatuses` prunes in\n // memory only \u2014 the stale JSON records survive on disk until another\n // write happens (registerClient / clientHeartbeat), which may never\n // occur if all bridge clients are dead.\n if (registry.size < before) {\n await this._writeClientRegistry(registry);\n }\n\n const now = Date.now();\n return Array.from(registry.values())\n .map((c) => ({\n clientId: c.clientId,\n name: c.name,\n source: c.source,\n sessionId: c.sessionId,\n lastSeenAt: c.lastSeenAt,\n online: now - new Date(c.lastSeenAt).getTime() < CLIENT_STALE_MS,\n pid: c.pid,\n }))\n .sort((a, b) => b.lastSeenAt.localeCompare(a.lastSeenAt));\n }\n\n /**\n * Explicitly purge stale clients from the registry and write back to disk.\n * Removes client entries whose lastSeenAt is older than CLIENT_STALE_MS.\n * Returns the number of entries purged.\n *\n * Idempotent \u2014 safe to call regularly. The same pruning runs implicitly\n * inside registerClient, clientHeartbeat, and getClientStatuses, but if\n * no client registers or heartbeats for a long time, this public method\n * ensures the file gets cleaned up on demand.\n */\n async purgeClients(): Promise<number> {\n await this._ensureClientRegistry();\n let purged = 0;\n await withFileLock(this.clientRegistryPath, async () => {\n const registry = await this._readClientRegistry({ fresh: true });\n const before = registry.size;\n this._pruneStaleClientsInPlace(registry);\n purged = before - registry.size;\n if (purged > 0) {\n this._clientRegistryCache = registry;\n this._clientRegistryCacheAt = Date.now();\n await this._writeClientRegistry(registry);\n }\n });\n return purged;\n }\n\n // \u2500\u2500 Lifecycle \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n async close(): Promise<void> {\n // JSONL append-only \u2014 no flush needed\n this._registryCache = null;\n this._clientRegistryCache = null;\n this._messageCache = null;\n this._messageCacheMtime = -1;\n this._messageCacheSize = -1;\n this._recipientIndex = null;\n this._senderIndex = null;\n }\n\n async clearAll(): Promise<void> {\n // Truncate the mailbox file and promote the empty cache under the same\n // lock, with the post-truncate stat captured synchronously so a\n // concurrent reader doesn't misclassify the shrink as a \"file only\n // grew\" append.\n await withFileLock(this.messagePath, async () => {\n await fsp.writeFile(this.messagePath, '', 'utf8');\n const { mtimeMs, size } = await this._statMessageFile();\n this._setMessageCache([], mtimeMs, size);\n });\n }\n\n async purgeStale(opts?: PurgeOptions): Promise<PurgeResult> {\n const COMPLETED_MAX_AGE_MS = opts?.completedMaxAgeMs ?? 86_400_000; // 1 day\n const INCOMPLETE_MAX_AGE_MS = opts?.incompleteMaxAgeMs ?? 604_800_000; // 7 days\n\n let completedPurged = 0;\n let incompletePurged = 0;\n let remaining = 0;\n\n // Read-modify-write under the lock \u2014 same pattern as ack().\n await withFileLock(this.messagePath, async () => {\n const all = await this._readMessagesFresh();\n const now = Date.now();\n const cutoffCompleted = now - COMPLETED_MAX_AGE_MS;\n const cutoffIncomplete = now - INCOMPLETE_MAX_AGE_MS;\n\n const kept: MailboxMessage[] = [];\n\n for (const msg of all) {\n const msgTime = new Date(msg.timestamp).getTime();\n const completedTime = msg.completedAt ? new Date(msg.completedAt).getTime() : 0;\n\n if (msg.completed && completedTime < cutoffCompleted) {\n completedPurged++;\n continue; // drop\n }\n if (!msg.completed && msgTime < cutoffIncomplete) {\n incompletePurged++;\n continue; // drop\n }\n\n kept.push(msg);\n }\n remaining = kept.length;\n\n // Rewrite only if something changed\n if (kept.length < all.length) {\n const content = kept.map((m) => JSON.stringify(m)).join(LINE_SEPARATOR) + LINE_SEPARATOR;\n await fsp.writeFile(this.messagePath, content, 'utf8');\n }\n // Capture the post-write (or post-read when nothing purged) stat\n // inside the lock so the cache trackers match the on-disk state.\n const { mtimeMs, size } = await this._statMessageFile();\n // Either way we just read fresh under the lock, so adopt the kept\n // snapshot (== all when nothing was purged) as the cache.\n this._setMessageCache(kept, mtimeMs, size);\n });\n\n return {\n completedPurged,\n incompletePurged,\n totalPurged: completedPurged + incompletePurged,\n remaining,\n };\n }\n\n // \u2500\u2500 Auto-compaction \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n private _autoCompactTimer: NodeJS.Timeout | null = null;\n\n async autoCompact(opts?: AutoCompactOptions): Promise<AutoCompactResult> {\n const readMaxAgeMs = opts?.readMaxAgeMs ?? AUTO_COMPACT_READ_MAX_AGE_MS;\n const defaultTtlMs = opts?.defaultTtlMs ?? AUTO_COMPACT_DEFAULT_TTL_MS;\n const completedMaxAgeMs = opts?.completedMaxAgeMs ?? 86_400_000; // 1 day\n const incompleteMaxAgeMs = opts?.incompleteMaxAgeMs ?? 604_800_000; // 7 days\n\n let expiredPurged = 0;\n let readByAllPurged = 0;\n let completedPurged = 0;\n let incompletePurged = 0;\n let remaining = 0;\n\n // Resolve the set of currently-online agent ids so we can check\n // \"has every online agent read this?\" without a second file read.\n // Online set is advisory \u2014 if the registry is temporarily empty we\n // skip the read-by-all pass rather than purging everything.\n let onlineAgentIds: Set<string> | null = null;\n try {\n const statuses = await this.getAgentStatuses();\n const online = statuses.filter((s) => s.online);\n onlineAgentIds = online.length > 0 ? new Set(online.map((s) => s.agentId)) : null;\n } catch {\n onlineAgentIds = null;\n }\n\n await withFileLock(this.messagePath, async () => {\n const all = await this._readMessagesFresh();\n const now = Date.now();\n const cutoffReadAge = now - readMaxAgeMs;\n const cutoffCompleted = now - completedMaxAgeMs;\n const cutoffIncomplete = now - incompleteMaxAgeMs;\n const cutoffDefaultTtl = now - defaultTtlMs;\n\n const kept: MailboxMessage[] = [];\n\n for (const msg of all) {\n const msgTime = new Date(msg.timestamp).getTime();\n\n // Pass 1: Explicit expiry.\n if (msg.expiresAt !== undefined) {\n if (new Date(msg.expiresAt).getTime() < now) {\n expiredPurged++;\n continue;\n }\n } else if (msgTime < cutoffDefaultTtl) {\n // No explicit expiry; use default TTL from send time.\n expiredPurged++;\n continue;\n }\n\n // Pass 2: Read by ALL currently-online agents.\n if (onlineAgentIds !== null && !msg.completed) {\n const readByAll =\n onlineAgentIds.size > 0 && [...onlineAgentIds].every((id) => id in msg.readBy);\n if (readByAll) {\n // Check age of the most recent read receipt.\n const readTimes = Object.values(msg.readBy).map((t) => new Date(t).getTime());\n const latestRead = Math.max(...readTimes);\n if (latestRead < cutoffReadAge) {\n readByAllPurged++;\n continue;\n }\n }\n }\n\n // Pass 3: Standard purge-stale logic.\n const completedTime = msg.completedAt ? new Date(msg.completedAt).getTime() : 0;\n if (msg.completed && completedTime < cutoffCompleted) {\n completedPurged++;\n continue;\n }\n if (!msg.completed && msgTime < cutoffIncomplete) {\n incompletePurged++;\n continue;\n }\n\n kept.push(msg);\n }\n remaining = kept.length;\n\n if (kept.length < all.length) {\n const content = kept.map((m) => JSON.stringify(m)).join(LINE_SEPARATOR) + LINE_SEPARATOR;\n await fsp.writeFile(this.messagePath, content, 'utf8');\n }\n const { mtimeMs, size } = await this._statMessageFile();\n this._setMessageCache(kept, mtimeMs, size);\n });\n\n const totalRemoved = expiredPurged + readByAllPurged + completedPurged + incompletePurged;\n return {\n expiredRemoved: expiredPurged,\n readByAllRemoved: readByAllPurged,\n stalePurged: completedPurged + incompletePurged,\n totalRemoved,\n remaining,\n };\n }\n\n startAutoCompactTimer(opts?: AutoCompactOptions): () => void {\n // Replace any prior timer.\n if (this._autoCompactTimer !== null) {\n clearInterval(this._autoCompactTimer);\n }\n const intervalMs = opts?.intervalMs ?? AUTO_COMPACT_INTERVAL_MS;\n const timer = setInterval(() => {\n this.autoCompact(opts).catch(() => {\n // Best-effort \u2014 background compaction must never crash the process.\n });\n }, intervalMs);\n timer.unref?.();\n this._autoCompactTimer = timer;\n return () => {\n clearInterval(timer);\n this._autoCompactTimer = null;\n };\n }\n\n // \u2500\u2500 Internal \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /**\n * Read all messages from the JSONL file. Always reads + parses the file.\n * Callers that can tolerate a stale-by-mtime view should use\n * {@link _readMessagesCached}; writers that need the post-lock truth\n * should call this directly (it's what {@link _readMessagesFresh} aliases).\n */\n private async _readMessages(): Promise<MailboxMessage[]> {\n try {\n const raw = await fsp.readFile(this.messagePath, 'utf8');\n return this._parseLines(raw);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return [];\n throw err;\n }\n }\n\n /**\n * Read only newly-appended bytes from the file and append them to the\n * in-memory cache. This avoids re-reading and re-parsing the entire file\n * when another process appended messages since our last read.\n *\n * Only safe when the file grew in size (messages are append-only). When\n * the file was rewritten (ack/purge changed existing content), callers\n * must fall back to {@link _readMessages}.\n *\n * @returns The (now up-to-date) message cache.\n */\n private async _readNewMessagesOnly(\n fd: fsp.FileHandle,\n oldSize: number,\n newSize: number,\n ): Promise<MailboxMessage[]> {\n const tailLen = newSize - oldSize;\n const buf = Buffer.alloc(tailLen);\n await fd.read(buf, 0, tailLen, oldSize);\n const tail = buf.toString('utf8');\n\n // Guard against a half-written tail: if another process is mid-append,\n // the tail may not end with the LINE_SEPARATOR. Parsing a partial JSON\n // line would throw (caught below), but worse: the NEXT incremental read\n // would skip that same line because the size tracker already advanced.\n // If the tail doesn't end with LINE_SEPARATOR, the last segment is a\n // partial write \u2014 return the cache as-is WITHOUT advancing trackers so\n // the next read retries from the same offset.\n if (!tail.endsWith(LINE_SEPARATOR)) {\n // Check if there are complete lines before the partial one.\n // We can safely parse complete lines and leave the partial for next read.\n const lastSeparatorIdx = tail.lastIndexOf(LINE_SEPARATOR);\n if (lastSeparatorIdx === -1) {\n // Entire tail is a partial line \u2014 don't advance, let caller fall\n // through to a full re-read on the next call.\n return this._messageCache!;\n }\n // Parse complete lines only; advance size tracker to the last complete\n // byte so the next incremental read picks up from the right offset.\n const completeTail = tail.slice(0, lastSeparatorIdx + 1);\n this._appendIncrementalLines(completeTail);\n // Advance size tracker to reflect only the consumed bytes.\n // The caller still updates _messageCacheMtime from the stat.\n this._messageCacheSize = oldSize + lastSeparatorIdx + 1;\n return this._messageCache!;\n }\n\n // Normal path: tail ends with LINE_SEPARATOR, all lines are complete.\n this._appendIncrementalLines(tail);\n // Advance size tracker to match the fully-consumed tail.\n this._messageCacheSize = newSize;\n return this._messageCache!;\n }\n\n private _appendIncrementalLines(raw: string): void {\n for (const line of raw.split(LINE_SEPARATOR)) {\n if (!line.trim()) continue;\n const message = this._parseLine(line);\n if (message === null) continue;\n this._messageCache!.push(message);\n const idx = this._messageCache!.length - 1;\n if (this._recipientIndex !== null) {\n let set = this._recipientIndex.get(message.to);\n if (set === undefined) {\n set = new Set();\n this._recipientIndex.set(message.to, set);\n }\n set.add(idx);\n }\n if (this._senderIndex !== null) {\n let set = this._senderIndex.get(message.from);\n if (set === undefined) {\n set = new Set();\n this._senderIndex.set(message.from, set);\n }\n set.add(idx);\n }\n }\n }\n\n private _parseLine(line: string): MailboxMessage | null {\n try {\n return parseMailboxMessageLine(line);\n } catch {\n return null;\n }\n }\n\n /** Parse a JSONL string into MailboxMessage[], including migration. */\n private _parseLines(raw: string): MailboxMessage[] {\n const lines = raw.split(LINE_SEPARATOR).filter((l) => l.trim().length > 0);\n const messages: MailboxMessage[] = [];\n for (const line of lines) {\n const message = this._parseLine(line);\n if (message !== null) messages.push(message);\n }\n return messages;\n }\n\n /**\n * Read messages, then adopt the result as the in-memory cache. Use this\n * from writers that just took the file lock \u2014 the read reflects the\n * authoritative post-lock state and should be served to subsequent\n * queries without re-reading.\n *\n * The mtime/size are captured from the stat at read time so the cache\n * trackers match exactly what was parsed. Writers that subsequently\n * rewrite the file MUST re-stat after the write and re-promote with the\n * post-write values (see ackMany / softDelete / restore / purgeStale /\n * clearAll) \u2014 otherwise a concurrent reader misclassifies the rewrite\n * as a \"file only grew\" append and corrupts the cache.\n */\n private async _readMessagesFresh(): Promise<MailboxMessage[]> {\n const all = await this._readMessages();\n const { mtimeMs, size } = await this._statMessageFile();\n this._setMessageCache(all, mtimeMs, size);\n return all;\n }\n\n /**\n * Stat the message file, returning its mtimeMs and size. Returns\n * `-1/-1` when the file does not yet exist (ENOENT) so callers can\n * still promote a cache snapshot \u2014 the next read will re-stat and\n * fall through to a full re-read. Call from inside the file lock so\n * the result reflects the post-write on-disk state, not a later\n * intermediate state from another process.\n */\n private async _statMessageFile(): Promise<{ mtimeMs: number; size: number }> {\n try {\n const st = await fsp.stat(this.messagePath);\n return { mtimeMs: st.mtimeMs, size: st.size };\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') {\n return { mtimeMs: -1, size: -1 };\n }\n throw err;\n }\n }\n\n /**\n * Read messages, consulting the mtime-bounded in-memory cache first,\n * serialized so concurrent callers don't both mutate the cache.\n *\n * The mailbox file is shared across processes; every `send`/`ack`/\n * `clearAll`/`purgeStale` takes the file lock, so writes are serialized\n * and a changed mtimeMs is a definitive freshness signal. When the\n * stat matches the cached mtime+size we return the cached array \u2014 no\n * file read and no JSON.parse \u2014 collapsing the per-iteration query\n * cost on the mailbox-loop hot path.\n *\n * When the file only grew (new messages appended by another process),\n * we read and parse just the tail bytes instead of the entire file.\n * This avoids re-parsing the full 10K-message history on every check.\n *\n * SERIALIZATION: the actual work is chained onto `_readChain` so two\n * overlapping calls can't both pass the `st.size > _messageCacheSize`\n * incremental check against the same stale tracker and each push the\n * same tail bytes onto the cache (duplicating every appended message).\n * Readers don't conflict on file content \u2014 only on the cache mutation\n * that follows the read \u2014 so we run them one at a time in issue order.\n * Errors in the chain are swallowed so a failed read never poisons\n * subsequent reads; each caller observes and re-throws its own error.\n */\n private _readMessagesCached(): Promise<MailboxMessage[]> {\n // Chain this read after the prior one settles. Catch-and-swallow the\n // prior's error so the chain stays alive for this call regardless.\n const run = this._readChain\n .catch(() => undefined as unknown as MailboxMessage[])\n .then(() => this._readMessagesCachedWork());\n this._readChain = run.catch(() => [] as MailboxMessage[]);\n return run;\n }\n\n /**\n * The un-serialized body of {@link _readMessagesCached}. Reads the\n * message file with the mtime-bounded cache + incremental-tail\n * optimization. Must only be called from `_readMessagesCached` so the\n * cache mutations here don't race a sibling read.\n */\n private async _readMessagesCachedWork(): Promise<MailboxMessage[]> {\n try {\n const st = await fsp.stat(this.messagePath);\n\n // Fast path: cache is current \u2014 no disk I/O beyond stat.\n if (\n this._messageCache !== null &&\n this._messageCacheMtime === st.mtimeMs &&\n this._messageCacheSize === st.size\n ) {\n return this._messageCache;\n }\n\n // Incremental path: cache exists and the file only grew (appends).\n // No ack/purge/clear rewrote the file, so we only need to parse\n // the newly-appended bytes.\n if (\n this._messageCache !== null &&\n this._messageCacheSize >= 0 &&\n st.size > this._messageCacheSize\n ) {\n const fd = await fsp.open(this.messagePath, 'r');\n try {\n const updated = await this._readNewMessagesOnly(fd, this._messageCacheSize, st.size);\n this._messageCacheMtime = st.mtimeMs;\n return updated;\n } finally {\n await fd.close();\n }\n }\n\n // Full re-read: cache empty, file was rewritten (ack/purge), or\n // this is the first read.\n const all = await this._readMessages();\n this._setMessageCache(all, st.mtimeMs, st.size);\n return all;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') {\n this._setMessageCache([], -1, -1);\n return [];\n }\n throw err;\n }\n }\n\n /**\n * Replace the in-memory cache, setting the mtime/size trackers\n * synchronously in the same step. Callers MUST pass the stat of the\n * on-disk file state that produced `messages`.\n *\n * Why both are required (not fire-and-forget): `_readMessagesCached()`\n * validates the cache against a fresh stat using these two trackers.\n * If the cache array is updated but the trackers lag behind (e.g. via\n * a deferred `stat().then(...)`), a concurrent reader landing in that\n * window sees a mismatched mtime and falls into the incremental\n * \"file only grew\" branch \u2014 parsing rewritten bytes as an appended\n * tail and corrupting the cache with duplicates/garbage. So both\n * values are captured under the file lock and applied synchronously\n * here, matching the fix already shipped in DefaultMailbox.\n */\n private _setMessageCache(messages: MailboxMessage[], mtime: number, size: number): void {\n // Bound the cache so a runaway mailbox can't balloon memory. The cap\n // is high enough that any realistic project mailbox fits; if it ever\n // exceeds the cap we just refuse to cache and the next read goes to\n // disk (the unoptimized but correct behavior).\n if (messages.length > MESSAGE_CACHE_MAX_ENTRIES) {\n this._messageCache = null;\n this._messageCacheMtime = -1;\n this._messageCacheSize = -1;\n this._recipientIndex = null;\n this._senderIndex = null;\n return;\n }\n this._messageCache = messages;\n this._messageCacheMtime = mtime;\n this._messageCacheSize = size;\n this._rebuildRecipientIndex();\n }\n\n /**\n * Build the recipient AND sender indexes from the current `_messageCache`.\n * Called only from `_setMessageCache` so both indexes are always in sync\n * with a freshly-replaced cache array.\n */\n private _rebuildRecipientIndex(): void {\n const cache = this._messageCache;\n if (cache === null) {\n this._recipientIndex = null;\n this._senderIndex = null;\n return;\n }\n const recIdx = new Map<string, Set<number>>();\n const sndIdx = new Map<string, Set<number>>();\n for (let i = 0; i < cache.length; i++) {\n const msg = cache[i]!;\n let rSet = recIdx.get(msg.to);\n if (rSet === undefined) {\n rSet = new Set();\n recIdx.set(msg.to, rSet);\n }\n rSet.add(i);\n let sSet = sndIdx.get(msg.from);\n if (sSet === undefined) {\n sSet = new Set();\n sndIdx.set(msg.from, sSet);\n }\n sSet.add(i);\n }\n this._recipientIndex = recIdx;\n this._senderIndex = sndIdx;\n }\n\n /**\n * Append a single just-sent message to the in-memory cache without\n * re-reading the file. The caller must hold the file lock (or have\n * just released it after a successful append) and MUST pass the\n * post-append stat so the mtime/size trackers advance in lock-step\n * with the pushed content.\n *\n * Why the stat is required here: without it, `_messageCacheSize`\n * stays at the pre-append value. A concurrent `_readMessagesCached()`\n * then sees `st.size > _messageCacheSize` (the file did grow), takes\n * the incremental branch, and re-reads the just-appended tail \u2014\n * pushing the same message onto the cache a second time. Setting the\n * trackers here closes that window for the local-process append path.\n */\n private _pushToCache(msg: MailboxMessage, mtime: number, size: number): void {\n if (this._messageCache === null) {\n // No cache to extend \u2014 leave trackers at -1 so the next read does\n // a full re-read and rebuilds the cache from disk.\n return;\n }\n if (this._messageCache.length >= MESSAGE_CACHE_MAX_ENTRIES) {\n this._messageCache = null;\n this._messageCacheMtime = -1;\n this._messageCacheSize = -1;\n return;\n }\n // The cache holds shared message objects; we mirror the on-disk line\n // by storing the same reference. Callers of `query()` get defensive\n // copies, so this shared reference is safe.\n this._messageCache.push(msg);\n // Update the recipient index with the new message's position.\n const newIdx = this._messageCache.length - 1;\n if (this._recipientIndex !== null) {\n let set = this._recipientIndex.get(msg.to);\n if (set === undefined) {\n set = new Set();\n this._recipientIndex.set(msg.to, set);\n }\n set.add(newIdx);\n }\n // Update the sender index with the new message's position.\n if (this._senderIndex !== null) {\n let set = this._senderIndex.get(msg.from);\n if (set === undefined) {\n set = new Set();\n this._senderIndex.set(msg.from, set);\n }\n set.add(newIdx);\n }\n // Advance the trackers synchronously with the content push so a\n // concurrent reader does not re-append this same message.\n this._messageCacheMtime = mtime;\n this._messageCacheSize = size;\n }\n\n private async _ensureRegistry(): Promise<void> {\n await fsp.mkdir(path.dirname(this.registryPath), { recursive: true });\n }\n\n private async _readRegistry(opts?: { fresh?: boolean }): Promise<Map<string, RegisteredAgent>> {\n // The registry file is shared across processes. Reads may use a short\n // TTL cache; writers (under the file lock) MUST pass { fresh: true } \u2014\n // a read-modify-write from a stale cache would silently erase agents\n // registered by other sessions.\n if (\n !opts?.fresh &&\n this._registryCache &&\n Date.now() - this._registryCacheAt < REGISTRY_CACHE_TTL_MS\n ) {\n return new Map(this._registryCache);\n }\n\n try {\n const raw = await fsp.readFile(this.registryPath, 'utf8');\n const data = JSON.parse(raw) as Record<string, RegisteredAgent>;\n // Parse lastSeenAt strings back into objects\n const map = new Map<string, RegisteredAgent>();\n for (const [id, agent] of Object.entries(data)) {\n map.set(id, agent as RegisteredAgent);\n }\n this._registryCache = map;\n this._registryCacheAt = Date.now();\n return new Map(map);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') {\n const empty = new Map<string, RegisteredAgent>();\n this._registryCache = empty;\n this._registryCacheAt = Date.now();\n return empty;\n }\n throw err;\n }\n }\n\n private _pruneStaleInPlace(registry: Map<string, RegisteredAgent>): void {\n const cutoff = Date.now() - AGENT_STALE_MS;\n for (const [id, agent] of registry) {\n const lastSeen = Date.parse(agent.lastSeenAt);\n // Missing/invalid heartbeat timestamps cannot establish liveness. Remove\n // them alongside expired entries instead of making malformed ghosts\n // immortal through NaN comparisons.\n if (!Number.isFinite(lastSeen) || lastSeen < cutoff) {\n registry.delete(id);\n }\n }\n }\n\n private async _writeRegistry(registry: Map<string, RegisteredAgent>): Promise<void> {\n const obj: Record<string, RegisteredAgent> = {};\n for (const [id, agent] of registry) {\n obj[id] = agent;\n }\n const tmp = `${this.registryPath}.${randomUUID().slice(0, 8)}.tmp`;\n await fsp.writeFile(tmp, JSON.stringify(obj), 'utf8');\n await fsp.rename(tmp, this.registryPath);\n }\n\n // \u2500\u2500 Client registry internals \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n private async _ensureClientRegistry(): Promise<void> {\n await fsp.mkdir(path.dirname(this.clientRegistryPath), { recursive: true });\n }\n\n private async _readClientRegistry(opts?: {\n fresh?: boolean;\n }): Promise<Map<string, RegisteredClient>> {\n if (\n !opts?.fresh &&\n this._clientRegistryCache &&\n Date.now() - this._clientRegistryCacheAt < REGISTRY_CACHE_TTL_MS\n ) {\n return new Map(this._clientRegistryCache);\n }\n\n try {\n const raw = await fsp.readFile(this.clientRegistryPath, 'utf8');\n const data = JSON.parse(raw) as Record<string, RegisteredClient>;\n const map = new Map<string, RegisteredClient>();\n for (const [id, client] of Object.entries(data)) {\n map.set(id, client as RegisteredClient);\n }\n this._clientRegistryCache = map;\n this._clientRegistryCacheAt = Date.now();\n return new Map(map);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') {\n const empty = new Map<string, RegisteredClient>();\n this._clientRegistryCache = empty;\n this._clientRegistryCacheAt = Date.now();\n return empty;\n }\n throw err;\n }\n }\n\n private _pruneStaleClientsInPlace(registry: Map<string, RegisteredClient>): void {\n const cutoff = Date.now() - CLIENT_STALE_MS;\n for (const [id, client] of registry) {\n const lastSeen = Date.parse(client.lastSeenAt);\n if (!Number.isFinite(lastSeen) || lastSeen < cutoff) {\n registry.delete(id);\n }\n }\n }\n\n private async _writeClientRegistry(registry: Map<string, RegisteredClient>): Promise<void> {\n const obj: Record<string, RegisteredClient> = {};\n for (const [id, client] of registry) {\n obj[id] = client;\n }\n const tmp = `${this.clientRegistryPath}.${randomUUID().slice(0, 8)}.tmp`;\n await fsp.writeFile(tmp, JSON.stringify(obj), 'utf8');\n await fsp.rename(tmp, this.clientRegistryPath);\n }\n}\n", "import { randomBytes } from 'node:crypto';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { FsError } from '../types/errors.js';\n\nexport interface AtomicWriteOptions {\n mode?: number | undefined;\n encoding?: BufferEncoding | undefined;\n}\n\nexport interface FileLockOptions {\n timeoutMs?: number | undefined;\n staleMs?: number | undefined;\n}\n\nexport async function atomicWrite(\n targetPath: string,\n content: string | Uint8Array,\n opts: AtomicWriteOptions = {},\n): Promise<void> {\n const dir = path.dirname(targetPath);\n await fs.mkdir(dir, { recursive: true });\n const tmp = path.join(dir, `.${path.basename(targetPath)}.${randomBytes(6).toString('hex')}.tmp`);\n\n // Write content to tmp first; 'wx' ensures exclusive creation (fails if\n // tmp already exists \u2014 extremely unlikely with 6-byte random suffix).\n try {\n if (typeof content === 'string') {\n await fs.writeFile(tmp, content, { flag: 'wx', encoding: opts.encoding ?? 'utf8' });\n } else {\n await fs.writeFile(tmp, content, { flag: 'wx' });\n }\n try {\n const fh = await fs.open(tmp, 'r+');\n try {\n await fh.sync();\n } finally {\n await fh.close();\n }\n } catch {\n // fsync best-effort\n }\n // Now safely read mode from target (if it exists) and apply to tmp before rename.\n // Prefer opts.mode for new files; for existing files preserve their mode.\n let mode: number | undefined;\n try {\n const stat = await fs.stat(targetPath);\n mode = stat.mode & 0o777;\n } catch {\n mode = opts.mode;\n }\n if (mode !== undefined) {\n await fs.chmod(tmp, mode);\n }\n await renameWithRetry(tmp, targetPath);\n // P3 #20 (before-release.md): on Windows, fs.rename (MoveFileExW) does\n // not preserve Unix permission bits \u2014 the chmod above applies to the tmp\n // file, but the rename may reset the destination's mode to the Windows\n // default. Re-apply the mode after rename on win32 so an edited file\n // keeps its executable bit (or any non-default permission). On POSIX,\n // rename preserves metadata so this is a no-op (chmod is idempotent and\n // cheap), but we gate it on win32 to avoid the extra stat+chmod on the\n // common path.\n if (mode !== undefined && process.platform === 'win32') {\n try {\n await fs.chmod(targetPath, mode);\n } catch {\n // Best-effort: a transient EPERM (antivirus lock) should not fail\n // the write \u2014 the content is already on disk.\n }\n }\n } catch (err) {\n try {\n await fs.unlink(tmp);\n } catch {\n // ignore cleanup error\n }\n throw err;\n }\n}\n\nexport async function ensureDir(dir: string): Promise<void> {\n await fs.mkdir(dir, { recursive: true });\n}\n\nexport async function withFileLock<T>(\n targetPath: string,\n fn: () => Promise<T>,\n opts: FileLockOptions = {},\n): Promise<T> {\n const dir = path.dirname(targetPath);\n await fs.mkdir(dir, { recursive: true });\n const lockPath = path.join(dir, `.${path.basename(targetPath)}.lock`);\n const timeoutMs = opts.timeoutMs ?? 5_000;\n const staleMs = opts.staleMs ?? 30_000;\n const started = Date.now();\n let handle: fs.FileHandle | undefined;\n\n for (;;) {\n try {\n handle = await fs.open(lockPath, 'wx');\n await handle.writeFile(`${process.pid}:${Date.now()}`);\n break;\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n // ENOENT means the directory was deleted (e.g. by concurrent cleanup).\n // Recreate it and retry acquiring the lock.\n if (code === 'ENOENT') {\n await fs.mkdir(dir, { recursive: true });\n continue;\n }\n if (code !== 'EEXIST') throw err;\n try {\n const stat = await fs.stat(lockPath);\n if (Date.now() - stat.mtimeMs > staleMs) {\n await fs.unlink(lockPath);\n continue;\n }\n } catch {\n continue;\n }\n if (Date.now() - started >= timeoutMs) {\n throw new FsError({\n message: `Timed out waiting for file lock: ${targetPath}`,\n code: 'FS_ATOMIC_WRITE_FAILED',\n path: targetPath,\n context: { timeoutMs },\n });\n }\n await new Promise((resolve) => setTimeout(resolve, 25));\n }\n }\n\n try {\n return await fn();\n } finally {\n try {\n await handle?.close();\n } catch {\n // ignore\n }\n try {\n await fs.unlink(lockPath);\n } catch {\n // ignore\n }\n }\n}\n\n// On Windows, fs.rename over an existing file can fail with EPERM/EBUSY/EACCES\n// when antivirus, file indexers, editor file watchers, or a concurrent writer\n// briefly hold a handle on the destination. These are transient \u2014 retry with a\n// short backoff before giving up. POSIX renames are atomic and won't hit this.\nconst TRANSIENT_RENAME_CODES = new Set(['EPERM', 'EBUSY', 'EACCES', 'ENOTEMPTY']);\n\nasync function renameWithRetry(from: string, to: string): Promise<void> {\n if (process.platform !== 'win32') {\n await fs.rename(from, to);\n return;\n }\n const delays = [10, 25, 60, 120, 250];\n let lastErr: unknown;\n for (let i = 0; i <= delays.length; i++) {\n try {\n await fs.rename(from, to);\n return;\n } catch (err) {\n lastErr = err;\n const code = (err as NodeJS.ErrnoException)?.code;\n if (!code || !TRANSIENT_RENAME_CODES.has(code) || i === delays.length) {\n throw err;\n }\n await new Promise((resolve) => setTimeout(resolve, delays[i]));\n }\n }\n throw lastErr;\n}\n", "import * as path from 'node:path';\nimport { ERROR_CODES, FsError } from '../types/errors.js';\n\n/**\n * Resolve `<dir>/<sessionId><suffix>` for per-session sidecar files\n * (annotations, audit chain, replay log, the session JSONL itself).\n *\n * Modern session ids are date-sharded (\"2026-06-11/sess_<ULID>\"),\n * so a forward slash is a legitimate shard separator \u2014 NOT traversal.\n * Escape attempts are blocked two ways: an explicit ban on `..` and\n * backslashes, plus a resolved-path containment check that rejects any\n * id whose resolved target leaves `dir`. Character bans alone are how\n * several stores ended up throwing on every modern session id.\n */\nexport function sessionScopedPath(dir: string, sessionId: string, suffix: string): string {\n if (!sessionId || sessionId.includes('\\\\') || sessionId.includes('..')) {\n throw invalid(sessionId);\n }\n const resolved = path.resolve(dir, `${sessionId}${suffix}`);\n const rel = path.relative(path.resolve(dir), resolved);\n if (rel.startsWith('..') || path.isAbsolute(rel)) {\n throw invalid(sessionId);\n }\n return resolved;\n}\n\nfunction invalid(sessionId: string): FsError {\n return new FsError({\n message: `Invalid sessionId: ${sessionId}`,\n code: ERROR_CODES.FS_DELETE_FAILED,\n path: sessionId,\n context: { reason: 'path_traversal' },\n });\n}\n", "import { createHash } from 'node:crypto';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\n\n/**\n * Path layout. All developer-level state lives in ~/.wrongstack/.\n * Per-project state is keyed by sha256(absoluteProjectRoot).slice(0,12)\n * under ~/.wrongstack/projects/<hash>/.\n *\n * The ONLY thing inside the project tree is the optional\n * .wrongstack/AGENTS.md (committed) and .wrongstack/skills/ (committed).\n */\n\nexport interface WstackPaths {\n /** ~/.wrongstack \u2014 global root. */\n globalRoot: string;\n /** Absolute project root. */\n projectRoot: string;\n /** Home directory (~) \u2014 base for foreign tool state (~/.codex, ~/.agents, \u2026). */\n homeDir: string;\n /**\n * ~/.wrongstack \u2014 directory for user-global stateful config files\n * (mode.json, theme.json, \u2026). Currently an alias for `globalRoot`;\n * separate name lets us split out per-OS XDG_CONFIG_HOME later\n * without rewriting callers.\n */\n configDir: string;\n /** ~/.wrongstack/config.json */\n globalConfig: string;\n /** ~/.wrongstack/.key \u2014 32 random bytes, mode 0600, AES-GCM key for the secret vault. */\n secretsKey: string;\n /** ~/.wrongstack/memory.md \u2014 user-global memory. */\n globalMemory: string;\n /** ~/.wrongstack/skills \u2014 user-global skills. */\n globalSkills: string;\n /** ~/.claude/skills \u2014 user-global skills from foreign coding agents (Claude Code, Codex, \u2026). Read-only. */\n globalClaudeSkills: string;\n /** ~/.wrongstack/design-kits \u2014 user-global Design Studio kits. */\n globalDesignKits: string;\n /** ~/.wrongstack/prompts \u2014 user-global prompt library. */\n globalPrompts: string;\n /** ~/.wrongstack/instructions \u2014 user-global system instruction overrides. */\n globalInstructions: string;\n /** ~/.wrongstack/prompt-usage.json \u2014 per-slug insert counts (recent/popular). */\n promptUsage: string;\n /** ~/.wrongstack/cache \u2014 fetched data (models.dev, etc.). */\n cacheDir: string;\n /** ~/.wrongstack/cache/models.dev.json */\n modelsCache: string;\n /** ~/.wrongstack/cache/models-overlay.json \u2014 cached curated overlay. */\n modelsOverlayCache: string;\n /**\n * Per-project codebase symbol index (SQLite). Lives under the global project\n * dir \u2014 NOT inside the repo \u2014 so it never clutters the working tree or needs\n * gitignoring. `~/.wrongstack/projects/<hash>/codebase-index`.\n */\n projectCodebaseIndex: string;\n /** ~/.wrongstack/history \u2014 REPL line history. */\n historyFile: string;\n /** ~/.wrongstack/logs/wrongstack.log */\n logFile: string;\n /** ~/.wrongstack/projects/<hash> */\n projectDir: string;\n /** ~/.wrongstack/projects/<hash>/memory.md */\n projectMemory: string;\n /** ~/.wrongstack/projects/<hash>/sessions */\n projectSessions: string;\n /** ~/.wrongstack/projects/<hash>/trust.json */\n projectTrust: string;\n /** ~/.wrongstack/projects/<hash>/meta.json */\n projectMeta: string;\n /** ~/.wrongstack/projects/<hash>/config.local.json \u2014 optional override */\n projectLocalConfig: string;\n /** <project>/.wrongstack/config.json \u2014 per-project settings (safe fields only).\n * This lives inside the project root so it can be gitignored or shared. */\n inProjectConfig: string;\n /** <project>/.wrongstack/AGENTS.md \u2014 committed project memory. */\n inProjectAgentsFile: string;\n /** <project>/.wrongstack/skills \u2014 committed project skills. */\n inProjectSkills: string;\n /** <project>/.claude/skills \u2014 project skills authored for foreign coding agents (Claude Code, \u2026). Read-only. */\n inProjectClaudeSkills: string;\n /** <project>/.wrongstack/prompts \u2014 committed project prompt library. */\n inProjectPrompts: string;\n /** <project>/.wrongstack/instructions \u2014 committed project instruction overrides. */\n inProjectInstructions: string;\n /** <project>/.wrongstack/design-kits \u2014 committed project Design Studio kits. */\n inProjectDesignKits: string;\n /** <project>/.wrongstack/worktrees \u2014 git worktrees for per-phase isolation (gitignored). */\n inProjectWorktrees: string;\n /** Stable hash for the project root. */\n projectHash: string;\n /** Human-readable project slug: `wrongstack-a1b2c3` instead of `3024e5e6fa58`. */\n projectSlug: string;\n /** ~/.wrongstack/projects/<hash>/goal.json \u2014 goal persistence */\n projectGoal: string;\n /** ~/.wrongstack/projects/<hash>/input-history.json \u2014 TUI prompt input history */\n projectInputHistory: string;\n /** ~/.wrongstack/projects/<hash>/specs \u2014 SDD spec files */\n projectSpecs: string;\n /** ~/.wrongstack/projects/<hash>/task-graphs \u2014 SDD task graphs */\n projectTaskGraphs: string;\n /** ~/.wrongstack/projects/<hash>/sdd-session.json \u2014 SDD session state */\n projectSddSession: string;\n /** ~/.wrongstack/projects/<hash>/plan.json \u2014 plan persistence */\n projectPlan: string;\n /** ~/.wrongstack/projects/<hash>/autophase \u2014 AutoPhase phase-graph JSON files */\n projectAutophase: string;\n /** ~/.wrongstack/projects/<hash>/sdd-boards \u2014 live SDD board snapshots + JSONL event logs */\n projectSddBoards: string;\n /** ~/.wrongstack/sync.json \u2014 CloudSync configuration */\n syncConfig: string;\n /** Function to get the status.json path for a project given its hash. */\n projectStatus: (projectHash: string) => string;\n}\n\nexport function projectHash(absRoot: string): string {\n return createHash('sha256').update(path.resolve(absRoot)).digest('hex').slice(0, 12);\n}\n\n/**\n * Human-readable project directory name: slugified folder name + short hash\n * suffix for uniqueness. e.g. `wrongstack-a1b2c3` instead of `3024e5e6fa58`.\n */\nexport function projectSlug(absRoot: string): string {\n const base = slugify(path.basename(absRoot));\n const hash = createHash('sha256').update(path.resolve(absRoot)).digest('hex').slice(0, 6);\n return `${base}-${hash}`;\n}\n\n/** Turn a folder name into a filesystem-safe lowercase slug. */\nfunction slugify(name: string): string {\n return (\n name\n .toLowerCase()\n // Collapse any run of non-alphanumeric chars into a single hyphen.\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, 40) || 'project'\n );\n}\n\nexport interface WstackPathOptions {\n userHome?: string | undefined;\n projectRoot: string;\n /** Override the global root (e.g. for tests). Default: `${userHome}/.wrongstack`. */\n globalRoot?: string | undefined;\n}\n\n/**\n * The global `~/.wrongstack` root, honoring the `WRONGSTACK_HOME` env\n * override. The override exists so tests (and sandboxed runs) can redirect\n * ALL global state \u2014 config, secrets, logs, projects/, mailboxes \u2014 away from\n * the real user home. Before it existed, `pnpm test` booted runtimes against\n * the real `~/.wrongstack`: it read the user's real config.json (starting a\n * second live Telegram poller), appended to the real wrongstack.log, and left\n * ~20k orphaned fixture dirs under projects/.\n *\n * Every code path that wants the global dir must come through here (or\n * through `resolveWstackPaths`) instead of `path.join(os.homedir(), '.wrongstack')`.\n */\nexport function wstackGlobalRoot(): string {\n const fromEnv = process.env['WRONGSTACK_HOME'];\n if (fromEnv && fromEnv.trim().length > 0) return path.resolve(fromEnv);\n return path.join(os.homedir(), '.wrongstack');\n}\n\nexport function resolveWstackPaths(opts: WstackPathOptions): WstackPaths {\n // Precedence: explicit globalRoot > explicit userHome (callers/tests that\n // pass one expect paths under it) > WRONGSTACK_HOME env > real home dir.\n const globalRoot =\n opts.globalRoot ?? (opts.userHome ? path.join(opts.userHome, '.wrongstack') : wstackGlobalRoot());\n // Home dir for FOREIGN tool state (Claude Code's ~/.claude). Independent of\n // WRONGSTACK_HOME, which redirects only WrongStack state: a real user's\n // Claude skills live in their real home, but tests pass `userHome` to keep\n // both `.wrongstack` and `.claude` under a temp dir.\n const homeDir = opts.userHome ?? os.homedir();\n const hash = projectHash(opts.projectRoot);\n const slug = projectSlug(opts.projectRoot);\n const projectDir = path.join(globalRoot, 'projects', slug);\n return {\n globalRoot,\n projectRoot: opts.projectRoot,\n homeDir,\n configDir: globalRoot,\n globalConfig: path.join(globalRoot, 'config.json'),\n secretsKey: path.join(globalRoot, '.key'),\n globalMemory: path.join(globalRoot, 'memory.md'),\n globalSkills: path.join(globalRoot, 'skills'),\n globalClaudeSkills: path.join(homeDir, '.claude', 'skills'),\n globalDesignKits: path.join(globalRoot, 'design-kits'),\n globalPrompts: path.join(globalRoot, 'prompts'),\n globalInstructions: path.join(globalRoot, 'instructions'),\n promptUsage: path.join(globalRoot, 'prompt-usage.json'),\n cacheDir: path.join(globalRoot, 'cache'),\n modelsCache: path.join(globalRoot, 'cache', 'models.dev.json'),\n modelsOverlayCache: path.join(globalRoot, 'cache', 'models-overlay.json'),\n historyFile: path.join(globalRoot, 'history'),\n logFile: path.join(globalRoot, 'logs', 'wrongstack.log'),\n projectDir,\n projectCodebaseIndex: path.join(projectDir, 'codebase-index'),\n projectMemory: path.join(projectDir, 'memory.md'),\n projectSessions: path.join(projectDir, 'sessions'),\n projectTrust: path.join(projectDir, 'trust.json'),\n projectMeta: path.join(projectDir, 'meta.json'),\n projectLocalConfig: path.join(projectDir, 'config.local.json'),\n inProjectConfig: path.join(opts.projectRoot, '.wrongstack', 'config.json'),\n inProjectAgentsFile: path.join(opts.projectRoot, '.wrongstack', 'AGENTS.md'),\n inProjectSkills: path.join(opts.projectRoot, '.wrongstack', 'skills'),\n inProjectClaudeSkills: path.join(opts.projectRoot, '.claude', 'skills'),\n inProjectPrompts: path.join(opts.projectRoot, '.wrongstack', 'prompts'),\n inProjectInstructions: path.join(opts.projectRoot, '.wrongstack', 'instructions'),\n inProjectDesignKits: path.join(opts.projectRoot, '.wrongstack', 'design-kits'),\n inProjectWorktrees: path.join(opts.projectRoot, '.wrongstack', 'worktrees'),\n projectHash: hash,\n projectSlug: slug,\n projectGoal: path.join(projectDir, 'goal.json'),\n projectInputHistory: path.join(projectDir, 'input-history.json'),\n projectSpecs: path.join(projectDir, 'specs'),\n projectTaskGraphs: path.join(projectDir, 'task-graphs'),\n projectSddSession: path.join(projectDir, 'sdd-session.json'),\n projectPlan: path.join(projectDir, 'plan.json'),\n projectAutophase: path.join(projectDir, 'autophase'),\n projectSddBoards: path.join(projectDir, 'sdd-boards'),\n syncConfig: path.join(globalRoot, 'sync.json'),\n projectStatus: (projectHash: string) => path.join(globalRoot, 'projects', projectHash, 'status.json'),\n };\n}\n", "import { toErrorMessage } from '../utils/index.js';\n\n/**\n * WrongStack error hierarchy.\n *\n * Every error thrown by the framework is a `WrongStackError` with a\n * machine-readable `code`, a `subsystem` tag, and a `severity` level.\n * This lets consumers (CLI, TUI, plugins, tests) branch on structured\n * data instead of parsing error messages.\n */\n\n// \u2500\u2500 Error codes \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Machine-readable error codes as frozen constants.\n *\n * Use `ERROR_CODES.X` instead of raw string literals for:\n * - IDE autocomplete and compile-time validation\n * - Safe refactoring (rename updates all usages)\n * - Plugin extensibility (extend the object to add custom codes)\n *\n * The `ErrorCode` type is derived from this object, so adding a new\n * code here automatically updates the type without extra changes.\n */\nexport const ERROR_CODES = {\n // Provider\n PROVIDER_RATE_LIMITED: 'PROVIDER_RATE_LIMITED',\n PROVIDER_AUTH_FAILED: 'PROVIDER_AUTH_FAILED',\n PROVIDER_OVERLOADED: 'PROVIDER_OVERLOADED',\n PROVIDER_INVALID_REQUEST: 'PROVIDER_INVALID_REQUEST',\n PROVIDER_SERVER_ERROR: 'PROVIDER_SERVER_ERROR',\n PROVIDER_NETWORK_ERROR: 'PROVIDER_NETWORK_ERROR',\n PROVIDER_CONTEXT_OVERFLOW: 'PROVIDER_CONTEXT_OVERFLOW',\n // Tool\n TOOL_NOT_FOUND: 'TOOL_NOT_FOUND',\n TOOL_PERMISSION_DENIED: 'TOOL_PERMISSION_DENIED',\n TOOL_EXECUTION_FAILED: 'TOOL_EXECUTION_FAILED',\n TOOL_TIMEOUT: 'TOOL_TIMEOUT',\n TOOL_INPUT_INVALID: 'TOOL_INPUT_INVALID',\n // Config\n CONFIG_INVALID: 'CONFIG_INVALID',\n CONFIG_NOT_FOUND: 'CONFIG_NOT_FOUND',\n CONFIG_PARSE_FAILED: 'CONFIG_PARSE_FAILED',\n CONFIG_MIGRATION_NEEDED: 'CONFIG_MIGRATION_NEEDED',\n // Plugin\n PLUGIN_LOAD_FAILED: 'PLUGIN_LOAD_FAILED',\n PLUGIN_API_MISMATCH: 'PLUGIN_API_MISMATCH',\n PLUGIN_MISSING_DEPENDENCY: 'PLUGIN_MISSING_DEPENDENCY',\n // Agent\n AGENT_ITERATION_LIMIT: 'AGENT_ITERATION_LIMIT',\n AGENT_CONTEXT_OVERFLOW: 'AGENT_CONTEXT_OVERFLOW',\n AGENT_ABORTED: 'AGENT_ABORTED',\n AGENT_RUN_FAILED: 'AGENT_RUN_FAILED',\n // Session\n SESSION_NOT_FOUND: 'SESSION_NOT_FOUND',\n SESSION_CORRUPTED: 'SESSION_CORRUPTED',\n SESSION_WRITE_FAILED: 'SESSION_WRITE_FAILED',\n // Container / Registry\n CONTAINER_TOKEN_ALREADY_BOUND: 'CONTAINER_TOKEN_ALREADY_BOUND',\n CONTAINER_TOKEN_NOT_BOUND: 'CONTAINER_TOKEN_NOT_BOUND',\n CONTAINER_CIRCULAR_DEPENDENCY: 'CONTAINER_CIRCULAR_DEPENDENCY',\n REGISTRY_DUPLICATE: 'REGISTRY_DUPLICATE',\n REGISTRY_NOT_FOUND: 'REGISTRY_NOT_FOUND',\n REGISTRY_INVALID: 'REGISTRY_INVALID',\n // File system\n FS_READ_FAILED: 'FS_READ_FAILED',\n FS_WRITE_FAILED: 'FS_WRITE_FAILED',\n FS_MKDIR_FAILED: 'FS_MKDIR_FAILED',\n FS_DELETE_FAILED: 'FS_DELETE_FAILED',\n FS_ATOMIC_WRITE_FAILED: 'FS_ATOMIC_WRITE_FAILED',\n // SDD (Spec-Driven Development)\n SDD_VALIDATION_FAILED: 'SDD_VALIDATION_FAILED',\n SDD_PARSE_FAILED: 'SDD_PARSE_FAILED',\n SDD_INVALID_STATE: 'SDD_INVALID_STATE',\n SDD_NOT_READY: 'SDD_NOT_READY',\n // General\n VALIDATION_ERROR: 'VALIDATION_ERROR',\n PARSE_FAILED: 'PARSE_FAILED',\n UNKNOWN: 'UNKNOWN',\n} as const;\n\n/**\n * Union type derived from `ERROR_CODES`. Using `typeof ERROR_CODES[keyof typeof ERROR_CODES]`\n * instead of a string literal union means TypeScript auto-updates the type whenever\n * a new code is added to `ERROR_CODES` \u2014 no need to keep two lists in sync.\n */\nexport type ErrorCode = (typeof ERROR_CODES)[keyof typeof ERROR_CODES];\n\nexport type ErrorSubsystem =\n | 'provider'\n | 'tool'\n | 'config'\n | 'plugin'\n | 'agent'\n | 'session'\n | 'sdd'\n | 'container'\n | 'fs'\n | 'general';\nexport type ErrorSeverity = 'fatal' | 'error' | 'warning';\n\n// \u2500\u2500 Base error class \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport class WrongStackError extends Error {\n readonly code: ErrorCode;\n readonly subsystem: ErrorSubsystem;\n readonly severity: ErrorSeverity;\n readonly recoverable: boolean;\n readonly context?: Record<string, unknown> | undefined;\n\n constructor(opts: {\n message: string;\n code: ErrorCode;\n subsystem: ErrorSubsystem;\n severity?: ErrorSeverity | undefined;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super(opts.message, { cause: opts.cause });\n this.name = 'WrongStackError';\n this.code = opts.code;\n this.subsystem = opts.subsystem;\n this.severity = opts.severity ?? 'error';\n this.recoverable = opts.recoverable ?? false;\n this.context = opts.context;\n }\n\n /**\n * Render a one-line user-facing description.\n * Subclasses should override for domain-specific formatting.\n */\n describe(): string {\n const ctx = this.context ? ` ${formatContext(this.context)}` : '';\n return `${this.code}: ${this.message}${ctx}`;\n }\n}\n\nfunction formatContext(ctx: Record<string, unknown>): string {\n const parts = Object.entries(ctx)\n .filter(([, v]) => v !== undefined)\n .slice(0, 3)\n .map(([k, v]) => `${k}=${String(v)}`);\n return parts.length > 0 ? `[${parts.join(' ')}]` : '';\n}\n\n// \u2500\u2500 Specific error classes \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Tool execution errors \u2014 thrown by ToolExecutor and individual tools.\n */\nexport class ToolError extends WrongStackError {\n readonly toolName: string;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n | 'TOOL_NOT_FOUND'\n | 'TOOL_PERMISSION_DENIED'\n | 'TOOL_EXECUTION_FAILED'\n | 'TOOL_TIMEOUT'\n | 'TOOL_INPUT_INVALID'\n >;\n toolName: string;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'tool',\n recoverable: opts.recoverable,\n context: { tool: opts.toolName, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'ToolError';\n this.toolName = opts.toolName;\n }\n}\n\n/**\n * Config loading / validation errors.\n */\nexport class ConfigError extends WrongStackError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'CONFIG_INVALID' | 'CONFIG_NOT_FOUND' | 'CONFIG_PARSE_FAILED' | 'CONFIG_MIGRATION_NEEDED'\n >;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'config',\n severity: 'fatal',\n recoverable: false,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'ConfigError';\n }\n}\n\n/**\n * Plugin loading / lifecycle errors.\n */\nexport class PluginError extends WrongStackError {\n readonly pluginName: string;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'PLUGIN_LOAD_FAILED' | 'PLUGIN_API_MISMATCH' | 'PLUGIN_MISSING_DEPENDENCY'\n >;\n pluginName: string;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'plugin',\n severity: 'error',\n recoverable: opts.code === ERROR_CODES.PLUGIN_MISSING_DEPENDENCY,\n context: { plugin: opts.pluginName, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'PluginError';\n this.pluginName = opts.pluginName;\n }\n}\n\n/**\n * Agent runtime errors \u2014 thrown by Agent.run when a non-WrongStackError\n * escapes the inner loop, so callers always see a structured error.\n */\nexport class AgentError extends WrongStackError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'AGENT_ITERATION_LIMIT' | 'AGENT_CONTEXT_OVERFLOW' | 'AGENT_ABORTED' | 'AGENT_RUN_FAILED'\n >;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'agent',\n severity: opts.code === ERROR_CODES.AGENT_ABORTED ? 'warning' : 'error',\n recoverable: opts.recoverable ?? opts.code === ERROR_CODES.AGENT_ITERATION_LIMIT,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'AgentError';\n }\n}\n\n/**\n * Wrap an arbitrary thrown value into a `WrongStackError` so the caller\n * always gets a structured error. Pass-throughs WrongStackError instances\n * unchanged; raw `Error`s and primitives get an `AGENT_RUN_FAILED` wrapper\n * with the original preserved as `cause`.\n */\nexport function toWrongStackError(\n err: unknown,\n code: Extract<ErrorCode, 'AGENT_RUN_FAILED' | 'AGENT_ABORTED' | 'UNKNOWN'> = ERROR_CODES.AGENT_RUN_FAILED,\n): WrongStackError {\n if (err instanceof WrongStackError) return err;\n const message = toErrorMessage(err);\n return new AgentError({\n message,\n code: code === 'UNKNOWN' ? ERROR_CODES.AGENT_RUN_FAILED : code,\n cause: err,\n });\n}\n\n/**\n * Session storage errors.\n */\nexport class SessionError extends WrongStackError {\n readonly sessionId?: string | undefined;\n\n constructor(opts: {\n message: string;\n code: Extract<ErrorCode, 'SESSION_NOT_FOUND' | 'SESSION_CORRUPTED' | 'SESSION_WRITE_FAILED'>;\n sessionId?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'session',\n severity: opts.code === ERROR_CODES.SESSION_WRITE_FAILED ? 'error' : 'warning',\n recoverable: opts.code !== ERROR_CODES.SESSION_CORRUPTED,\n context: { sessionId: opts.sessionId, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'SessionError';\n this.sessionId = opts.sessionId;\n }\n}\n\n/**\n * SDD (Spec-Driven Development) errors \u2014 spec validation, parsing, and\n * state machine violations in the AISpecBuilder, TaskFlow, and TaskTracker.\n */\nexport class SddError extends WrongStackError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'SDD_VALIDATION_FAILED' | 'SDD_PARSE_FAILED' | 'SDD_INVALID_STATE' | 'SDD_NOT_READY'\n >;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'sdd',\n severity: opts.code === ERROR_CODES.SDD_PARSE_FAILED ? 'warning' : 'error',\n recoverable: opts.code === ERROR_CODES.SDD_NOT_READY,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'SddError';\n }\n}\n\n/**\n * File system operation errors.\n */\nexport class FsError extends WrongStackError {\n readonly path?: string | undefined;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'FS_READ_FAILED' | 'FS_WRITE_FAILED' | 'FS_MKDIR_FAILED' | 'FS_DELETE_FAILED' | 'FS_ATOMIC_WRITE_FAILED'\n >;\n path?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'fs',\n severity: 'error',\n recoverable: opts.code !== ERROR_CODES.FS_READ_FAILED,\n context: { path: opts.path, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'FsError';\n this.path = opts.path;\n }\n}\n\n/**\n * HTTP fetch error \u2014 thrown when a network request returns a non-OK status.\n * Carries the response status so {@link classifyToolError} can branch on it\n * (429 \u2192 transient, 404 \u2192 not_found, 401 \u2192 permission) without duck-typing\n * the error via `'response' in err`.\n *\n * P3 #18 (before-release.md): the previous `'response' in err` check caught\n * any Error with a `response` property, including custom errors, proxy\n * objects, or mocked errors in tests. `instanceof FetchError` is reliable.\n *\n * Tools and providers that make HTTP requests and need the executor to\n * classify their failures should throw `new FetchError({ status, message })`\n * instead of a bare `Error` with an ad-hoc `response` field.\n */\nexport class FetchError extends WrongStackError {\n readonly status: number;\n\n constructor(opts: {\n message: string;\n status: number;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: ERROR_CODES.VALIDATION_ERROR,\n subsystem: 'general',\n severity: 'error',\n recoverable: opts.status === 429 || opts.status >= 500,\n context: { status: opts.status, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'FetchError';\n this.status = opts.status;\n }\n}\n\n/**\n * Tool input validation error \u2014 thrown when a tool's input fails a validation\n * check that the JSON Schema cannot express (e.g. `old_string === new_string`\n * in edit, or a cross-field invariant). Use this instead of a bare\n * `throw new Error('...validation...')` so {@link classifyToolError} can\n * match on `instanceof` rather than a locale-dependent message substring.\n *\n * P2 #6 (before-release.md): the previous `err.message.includes('validation')`\n * check misclassified any error whose message happened to contain \"validation\"\n * (e.g. a third-party \"input validation timeout\") as a VALIDATION error.\n *\n * Named `ToolValidationError` (not `ValidationError`) to avoid colliding with\n * the existing `ValidationError` interface exported by json-schema-validate.ts\n * (a validation-result shape, not an Error subclass).\n */\nexport class ToolValidationError extends WrongStackError {\n constructor(opts: {\n message: string;\n /** Field path or tool name that failed validation, for diagnostics. */\n field?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: ERROR_CODES.VALIDATION_ERROR,\n subsystem: 'general',\n severity: 'error',\n recoverable: false,\n context: { field: opts.field, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'ToolValidationError';\n }\n}\n\n/**\n * Response / payload parse error \u2014 thrown when an upstream HTTP response,\n * file, or data structure is well-formed at the transport layer (HTTP 200,\n * valid JSON) but is missing required fields or has an unexpected shape.\n *\n * Distinct from `ConfigError(CONFIG_PARSE_FAILED)` (which is specifically\n * for config-file parsing) and `FetchError` (which covers HTTP non-OK\n * responses). `ParseError` fills the gap: the request succeeded but the\n * response body couldn't be interpreted.\n *\n * Common sites: OAuth token responses missing `access_token`, device-code\n * responses missing `device_code`, registry responses with unexpected\n * schemas.\n */\nexport class ParseError extends WrongStackError {\n readonly source?: string | undefined;\n\n constructor(opts: {\n message: string;\n /**\n * What was being parsed \u2014 e.g. `'oauth-token-response'`,\n * `'device-code-response'`. Lets consumers distinguish parse failures\n * from different upstream APIs without parsing the message.\n */\n source?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: ERROR_CODES.PARSE_FAILED,\n subsystem: 'general',\n severity: 'error',\n recoverable: false,\n context: { source: opts.source, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'ParseError';\n this.source = opts.source;\n }\n}\n\n// \u2500\u2500 Type guards \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport function isWrongStackError(err: unknown): err is WrongStackError {\n return err instanceof WrongStackError;\n}\n\nexport function isToolError(err: unknown): err is ToolError {\n return err instanceof ToolError;\n}\n\nexport function isConfigError(err: unknown): err is ConfigError {\n return err instanceof ConfigError;\n}\n\nexport function isPluginError(err: unknown): err is PluginError {\n return err instanceof PluginError;\n}\n\nexport function isSessionError(err: unknown): err is SessionError {\n return err instanceof SessionError;\n}\n\nexport function isAgentError(err: unknown): err is AgentError {\n return err instanceof AgentError;\n}\n\nexport function isFsError(err: unknown): err is FsError {\n return err instanceof FsError;\n}\n\nexport function isToolValidationError(err: unknown): err is ToolValidationError {\n return err instanceof ToolValidationError;\n}\n\nexport function isFetchError(err: unknown): err is FetchError {\n return err instanceof FetchError;\n}\n\nexport function isParseError(err: unknown): err is ParseError {\n return err instanceof ParseError;\n}\n\nexport function isSddError(err: unknown): err is SddError {\n return err instanceof SddError;\n}\n", "/**\n * Centralized constants for the mailbox system.\n *\n * Previously these magic numbers were scattered across global-mailbox.ts,\n * mailbox-attach.ts, mailbox-hooks.ts, and mailbox-health.ts. Keeping them\n * in one place ensures every surface agrees on timeouts, intervals, and\n * thresholds \u2014 and makes tuning a single-file change.\n *\n * @module mailbox-constants\n */\n\n/**\n * Agents without a heartbeat for this long are no longer live and are removed\n * from the registry. Presence registries are not history stores: retaining an\n * offline row makes dead agents and shadow workers look actionable in HQ.\n */\nexport const AGENT_STALE_MS = 60_000;\n\n/** Clients without a heartbeat for this long are considered offline. */\nexport const CLIENT_STALE_MS = 60_000;\n\n/** Heartbeat updates are throttled to at most this interval (per agent/client). */\nexport const HEARTBEAT_THROTTLE_MS = 5_000;\n\n/**\n * How long a read may be served from the in-process registry cache before\n * re-reading the shared file. Kept well below HEARTBEAT_THROTTLE_MS so\n * cross-process registrations become visible promptly.\n */\nexport const REGISTRY_CACHE_TTL_MS = 2_000;\n\n/** JSONL line separator. */\nexport const LINE_SEPARATOR = '\\n';\n\n/**\n * Soft cap on the in-memory message cache. The cache mirrors the JSONL\n * message file; under normal load it stays well under this. If a pathological\n * mailbox exceeds the cap we fall back to reading from disk rather than\n * holding an unbounded buffer in memory.\n */\nexport const MESSAGE_CACHE_MAX_ENTRIES = 10_000;\n\n// \u2500\u2500 Polling / heartbeat intervals (used by mailbox-attach.ts) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Background mailbox awareness polling interval (cross-process fallback). */\nexport const MAILBOX_AWARENESS_INTERVAL_MS = 30_000;\n\n/** Agent heartbeat interval in the attach layer. */\nexport const MAILBOX_HEARTBEAT_INTERVAL_MS = 30_000;\n\n/** Min interval between registry reads for the fleet pulse digest. */\nexport const PULSE_MIN_READ_INTERVAL_MS = 30_000;\n\n// \u2500\u2500 Auto-cleanup / compaction \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Interval at which the background auto-compaction sweep runs.\n * Default: every 5 minutes.\n */\nexport const AUTO_COMPACT_INTERVAL_MS = 300_000;\n\n/**\n * Messages that have been read by ALL currently-online agents are eligible\n * for auto-removal after this many milliseconds since the last read.\n * Default: 10 minutes.\n */\nexport const AUTO_COMPACT_READ_MAX_AGE_MS = 600_000;\n\n/**\n * Messages whose TTL (time-to-live) has expired are eligible for auto-removal.\n * When a message has `expiresAt` set and that timestamp is in the past, the\n * next compaction sweep drops it. Default TTL for messages without an explicit\n * `expiresAt`: 24 hours.\n */\nexport const AUTO_COMPACT_DEFAULT_TTL_MS = 86_400_000; // 24h\n\n// \u2500\u2500 HTTP bridge rate limiting \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Maximum requests per minute from a single external agent (bearer token). */\nexport const HTTP_RATE_LIMIT_PER_MINUTE = 120;\n\n/** Window size for the sliding-window rate limiter. */\nexport const HTTP_RATE_LIMIT_WINDOW_MS = 60_000;\n", "import type {\n MailboxMessage,\n MailboxMessageType,\n MailboxTaskContext,\n ReadReceipts,\n} from './mailbox-types.js';\n\nconst MESSAGE_TYPES = new Set<MailboxMessageType>([\n 'note',\n 'ask',\n 'assign',\n 'steer',\n 'btw',\n 'broadcast',\n 'status',\n 'result',\n 'review',\n 'control',\n]);\n\nconst PRIORITIES = new Set<MailboxMessage['priority']>(['low', 'normal', 'high']);\nconst TASK_STATUSES = new Set([\n 'pending',\n 'in_progress',\n 'completed',\n 'failed',\n 'idle',\n 'running',\n 'streaming',\n 'waiting_user',\n 'error',\n 'offline',\n 'busy',\n]);\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction requiredString(record: Record<string, unknown>, key: string): string {\n const value = record[key];\n if (typeof value !== 'string') {\n throw new TypeError(`mailbox message field \"${key}\" must be a string`);\n }\n return value;\n}\n\nfunction optionalString(record: Record<string, unknown>, key: string): Record<string, string> {\n const value = record[key];\n if (value === undefined) return {};\n if (typeof value !== 'string') {\n throw new TypeError(`mailbox message field \"${key}\" must be a string when present`);\n }\n return { [key]: value };\n}\n\nfunction parseMessageType(value: unknown): MailboxMessageType {\n if (value === 'info') return 'note';\n if (value === 'task') return 'assign';\n if (typeof value === 'string' && MESSAGE_TYPES.has(value as MailboxMessageType)) {\n return value as MailboxMessageType;\n }\n throw new TypeError('mailbox message field \"type\" is invalid');\n}\n\n/** Normalize message types emitted by pre-union mailbox builds. */\nexport function normalizeMailboxMessageType(value: unknown): MailboxMessageType {\n return parseMessageType(value);\n}\n\nfunction parsePriority(value: unknown): MailboxMessage['priority'] {\n if (typeof value === 'string' && PRIORITIES.has(value as MailboxMessage['priority'])) {\n return value as MailboxMessage['priority'];\n }\n // Older callers were intentionally tolerant here and ranked unknown values\n // as normal. Normalize rather than dropping an otherwise valid message.\n if (typeof value === 'string') return 'normal';\n throw new TypeError('mailbox message field \"priority\" must be a string');\n}\n\nfunction parseReadReceipts(record: Record<string, unknown>, to: string): ReadReceipts {\n const value = record['readBy'];\n if (value === undefined) {\n const legacyReadAt = record['readAt'];\n return record['read'] === true && typeof legacyReadAt === 'string'\n ? { [to || 'unknown']: legacyReadAt }\n : {};\n }\n if (!isRecord(value)) {\n throw new TypeError('mailbox message field \"readBy\" must be an object');\n }\n\n const receipts: ReadReceipts = {};\n for (const [agentId, timestamp] of Object.entries(value)) {\n if (typeof timestamp !== 'string') {\n throw new TypeError('mailbox message read receipt timestamps must be strings');\n }\n receipts[agentId] = timestamp;\n }\n return receipts;\n}\n\nfunction parseTaskContext(value: unknown): MailboxTaskContext | undefined {\n if (value === undefined) return undefined;\n if (!isRecord(value)) {\n throw new TypeError('mailbox message field \"taskContext\" must be an object');\n }\n\n const status = value['status'];\n if (\n status !== undefined &&\n (typeof status !== 'string' ||\n !TASK_STATUSES.has(status as NonNullable<MailboxTaskContext['status']>))\n ) {\n throw new TypeError('mailbox message taskContext status is invalid');\n }\n\n return {\n ...optionalString(value, 'agentRole'),\n ...optionalString(value, 'agentName'),\n ...optionalString(value, 'taskId'),\n ...(status === undefined\n ? {}\n : { status: status as NonNullable<MailboxTaskContext['status']> }),\n };\n}\n\n/** Parse, migrate, and structurally validate one persisted mailbox message. */\nexport function parseMailboxMessage(value: unknown): MailboxMessage {\n if (!isRecord(value)) throw new TypeError('mailbox message must be an object');\n\n const to = value['to'] === undefined ? '' : requiredString(value, 'to');\n const completed = value['completed'];\n if (typeof completed !== 'boolean') {\n throw new TypeError('mailbox message field \"completed\" must be a boolean');\n }\n\n const taskContext = parseTaskContext(value['taskContext']);\n return {\n id: requiredString(value, 'id'),\n from: requiredString(value, 'from'),\n to,\n type: parseMessageType(value['type']),\n subject: requiredString(value, 'subject'),\n body: requiredString(value, 'body'),\n priority: parsePriority(value['priority']),\n readBy: parseReadReceipts(value, to),\n completed,\n timestamp: requiredString(value, 'timestamp'),\n ...optionalString(value, 'completedBy'),\n ...optionalString(value, 'outcome'),\n ...optionalString(value, 'completedAt'),\n ...optionalString(value, 'deletedAt'),\n ...optionalString(value, 'deletedBy'),\n ...optionalString(value, 'replyTo'),\n ...optionalString(value, 'senderSessionId'),\n ...optionalString(value, 'expiresAt'),\n ...(taskContext === undefined ? {} : { taskContext }),\n };\n}\n\n/** Parse one JSONL line and validate the decoded mailbox message. */\nexport function parseMailboxMessageLine(line: string): MailboxMessage {\n return parseMailboxMessage(JSON.parse(line) as unknown);\n}\n", "/**\n * Mailbox \u2014 persistent inter-agent messaging system with cross-session support.\n *\n * Agents can leave notes for specific agents or broadcast to all. Each agent\n * periodically checks the mailbox or retrieves messages via tool calls.\n *\n * ## Cross-session communication\n *\n * The mailbox is stored at **project level** (`~/.wrongstack/projects/<slug>/_mailbox.jsonl`),\n * so agents in different terminal sessions / WebUI tabs working on the same\n * project can communicate live.\n *\n * ## Agent registration\n *\n * Every agent that uses the mailbox registers itself with a heartbeat.\n * Other agents can discover online agents via `getOnlineAgents()`.\n * Stale agents (no heartbeat > 60s) are pruned automatically.\n *\n * ## Read receipts\n *\n * Each message tracks per-recipient read status via a `readBy` map:\n * `{ \"agentId\": \"ISO8601\" }`. When agent X reads a message, its entry\n * is added. The WebUI shows who read what and when.\n *\n * @module mailbox-types\n */\n\n// \u2500\u2500 Message type discriminator \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport type MailboxMessageType =\n | 'note' // informational message\n | 'ask' // question / request for advice\n | 'assign' // task assignment\n | 'steer' // steering instruction (change behavior mid-task)\n | 'btw' // \"by the way\" \u2014 non-urgent info\n | 'broadcast' // sent to all agents\n | 'status' // agent status update\n | 'result' // task result / completion notice\n | 'review' // review request (code/doc/PR) \u2014 passive ask, no reply required\n | 'control'; // out-of-band control signal (e.g. interrupt) \u2014 handled by\n// the agent loop, NOT folded into the conversation as content\n\n// \u2500\u2500 Read receipt \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Per-recipient read status. `readBy` maps agentId \u2192 ISO8601 timestamp of\n * when that agent first read the message. An empty map means unread by all.\n */\nexport interface ReadReceipts {\n [agentId: string]: string; // ISO8601 timestamp\n}\n\n// \u2500\u2500 Core message \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface MailboxMessage {\n /** Unique message id (UUID). */\n id: string;\n /** Sender agent id. */\n from: string;\n /** Recipient agent id, or '*' for broadcast. */\n to: string;\n /** Message category. */\n type: MailboxMessageType;\n /** Short subject line \u2014 one sentence. */\n subject: string;\n /** Full message content. */\n body: string;\n /** Priority \u2014 high priority messages surface first. */\n priority: 'low' | 'normal' | 'high';\n /**\n * Per-recipient read receipts. agentId \u2192 ISO8601 when they first read it.\n * Replaces the old single `read: boolean` + `readAt` fields.\n */\n readBy: ReadReceipts;\n /** Has any recipient acted on / completed this? */\n completed: boolean;\n /** Who completed it (agentId). */\n completedBy?: string | undefined;\n /** Optional summary of what happened after handling. */\n outcome?: string | undefined;\n /** ISO8601 \u2014 when the message was sent. */\n timestamp: string;\n /** ISO8601 \u2014 when the message was marked complete. */\n completedAt?: string | undefined;\n /**\n * ISO8601 \u2014 when the message was soft-deleted. When present, the\n * default `Mailbox.query()` filter excludes the message from the\n * normal inbox view; {@link GlobalMailbox.restore} clears the\n * field to undo the delete. Hard deletes (removing the line from\n * the JSONL) are reserved for the CLI and never happen via the\n * server route handlers.\n */\n deletedAt?: string | undefined;\n /** When the soft-delete happened, the agentId that issued it. */\n deletedBy?: string | undefined;\n /** If this is a reply, the id of the parent message. */\n replyTo?: string | undefined;\n /** For assign-type messages \u2014 task context for agent discovery. */\n taskContext?: MailboxTaskContext | undefined;\n /** Session id of the sender. Enables cross-session communication. */\n senderSessionId?: string | undefined;\n /**\n * ISO8601 \u2014 when the message expires. Set at send time from `ttlMs`\n * (default: 24h via AUTO_COMPACT_DEFAULT_TTL_MS). The auto-compaction\n * sweep removes messages whose `expiresAt` is in the past. When\n * undefined, the compaction sweep uses the default TTL from the\n * caller's options.\n */\n expiresAt?: string | undefined;\n}\n\n// \u2500\u2500 Task context for agent discovery \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface MailboxTaskContext {\n /** The role that should handle this task (e.g. \"tech-stack\", \"audit-log\"). */\n agentRole?: string | undefined;\n /** Human-readable agent name (e.g. \"Tesla (Executor)\"). */\n agentName?: string | undefined;\n /** Task id if already assigned via coordinator. */\n taskId?: string | undefined;\n /** Current task status. */\n status?: 'pending' | 'in_progress' | 'completed' | 'failed' | undefined;\n}\n\n// \u2500\u2500 Agent registration \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface RegisteredAgent {\n /** Unique agent id. */\n agentId: string;\n /** Session id this agent belongs to. */\n sessionId: string;\n /** Human-readable name. */\n name: string;\n /** Role (e.g. \"leader\", \"tech-stack\", \"bug-hunter\"). */\n role?: string | undefined;\n /** Current status. */\n status: 'idle' | 'running' | 'streaming' | 'waiting_user' | 'error';\n /** Current tool being executed, if any. */\n currentTool?: string | undefined;\n /** Current task description. */\n currentTask?: string | undefined;\n /** Iteration count so far. */\n iterations: number;\n /** Tool calls so far. */\n toolCalls: number;\n /** ISO8601 \u2014 registered at. */\n registeredAt: string;\n /** ISO8601 \u2014 last heartbeat (updated on every mailbox op). */\n lastSeenAt: string;\n /** Which process registered this agent (PID). */\n pid: number;\n /** Where the agent is running (e.g. \"cli\", \"webui\"). */\n source?: 'cli' | 'webui' | 'mcp' | 'acp' | 'http' | undefined;\n}\n\n// \u2500\u2500 Agent status entry (for discovery) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface MailboxAgentStatus {\n /** Agent id. */\n agentId: string;\n /** Human-readable name. */\n name: string;\n /** Role. */\n role?: string | undefined;\n /** Session id. */\n sessionId: string;\n /** Current status. */\n status: 'idle' | 'running' | 'streaming' | 'waiting_user' | 'error' | 'offline';\n /** Current tool being executed, if any. */\n currentTool?: string | undefined;\n /** Current task description. */\n currentTask?: string | undefined;\n /** Iteration count so far. */\n iterations: number;\n /** Tool calls so far. */\n toolCalls: number;\n /** ISO8601 \u2014 last activity timestamp. */\n lastActivityAt: string;\n /** ISO8601 \u2014 last heartbeat. */\n lastSeenAt: string;\n /** Whether this agent is currently online (heartbeat within threshold). */\n online: boolean;\n /** Which process. */\n pid: number;\n /** Source. */\n source?: 'cli' | 'webui' | 'mcp' | 'acp' | 'http' | undefined;\n}\n\n// \u2500\u2500 Mailbox query \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface MailboxQuery {\n /** Filter by recipient agent id. */\n to?: string | undefined;\n /** Filter by sender agent id. */\n from?: string | undefined;\n /** Only messages unread by this agent. */\n unreadBy?: string | undefined;\n /** Only incomplete messages. */\n incompleteOnly?: boolean | undefined;\n /** Filter by message type. */\n type?: MailboxMessageType | undefined;\n /** Filter by priority (>= this level). */\n minPriority?: 'low' | 'normal' | 'high' | undefined;\n /** Maximum number of messages to return. */\n limit?: number | undefined;\n /** ISO8601 \u2014 only messages after this timestamp. */\n since?: string | undefined;\n /**\n * Include soft-deleted messages (where `deletedAt` is set). When\n * `false` (the default), soft-deleted messages are filtered out so\n * the normal inbox view stays clean. The \"trash\" view passes\n * `true` to surface them.\n */\n includeDeleted?: boolean | undefined;\n}\n\n// \u2500\u2500 Mailbox operations \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Normalize a recipient address. `\"all\"` (any casing) is an accepted\n * spelling of the broadcast address and is canonicalized to `'*'` at send\n * time \u2014 both agents and humans reach for \"all\" naturally, and a literal\n * \"all\" recipient would otherwise be deliverable to nobody. The word is\n * therefore RESERVED: no agent may register under the base id \"all\".\n */\nexport function normalizeRecipient(to: string): string {\n return to.trim().toLowerCase() === 'all' ? '*' : to.trim();\n}\n\nexport interface MailboxSendInput {\n /** Sender agent id. */\n from: string;\n /** Recipient agent id, '*' for broadcast (alias: \"all\"). */\n to: string;\n /** Message category. */\n type: MailboxMessageType;\n /** Short subject line. */\n subject: string;\n /** Full message content. */\n body: string;\n /** Priority. Default: 'normal'. */\n priority?: 'low' | 'normal' | 'high' | undefined;\n /** If replying, the id of the parent message. */\n replyTo?: string | undefined;\n /** Task context for assign-type messages. */\n taskContext?: MailboxTaskContext | undefined;\n /**\n * Time-to-live in milliseconds. When set, the message's `expiresAt` is\n * computed as `now + ttlMs` at send time. The auto-compaction sweep\n * removes expired messages. Default: none (use compaction sweep default).\n */\n ttlMs?: number | undefined;\n}\n\nexport interface MailboxAckInput {\n /** Message id to acknowledge. */\n messageId: string;\n /** Agent id of who is reading/acking. */\n readerId: string;\n /** Mark as read by this agent? Defaults to true if not specified. */\n read?: boolean | undefined;\n /** Mark as completed? */\n completed?: boolean | undefined;\n /** Optional outcome summary. */\n outcome?: string | undefined;\n}\n\n/**\n * Batch acknowledgment input \u2014 applies a batch of acks under a single file\n * lock + single file rewrite. Each entry has the same shape as\n * {@link MailboxAckInput} minus the per-batch defaults documented on\n * `ackMany`. Use this when an agent is acking several fresh messages at\n * once (the common case in the mailbox loop) \u2014 it collapses N full-file\n * rewrites into one.\n */\nexport interface MailboxAckBatchInput {\n /** Ack entries to apply. */\n acks: MailboxAckInput[];\n}\n\n// \u2500\u2500 Agent registration input \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface AgentRegistrationInput {\n agentId: string;\n sessionId: string;\n name: string;\n role?: string | undefined;\n pid: number;\n source?: 'cli' | 'webui' | 'mcp' | 'acp' | 'http' | undefined;\n}\n\n// \u2500\u2500 Client (REPL/TUI/WebUI) registration \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport type ClientSource = 'repl' | 'tui' | 'webui' | 'http';\n\nexport interface RegisteredClient {\n /** Unique client id. */\n clientId: string;\n /** Session/project context id. */\n sessionId: string;\n /** Human-readable name (e.g. \"TUI [main]\", \"WebUI [chrome]\"). */\n name: string;\n /** Client type. */\n source: ClientSource;\n /** ISO8601 \u2014 registered at. */\n registeredAt: string;\n /** ISO8601 \u2014 last heartbeat. */\n lastSeenAt: string;\n /** Which process. */\n pid: number;\n}\n\nexport interface ClientStatus {\n /** Client id. */\n clientId: string;\n /** Human-readable name. */\n name: string;\n /** Client type. */\n source: ClientSource;\n /** Session id. */\n sessionId: string;\n /** ISO8601 \u2014 last activity timestamp. */\n lastSeenAt: string;\n /** Whether this client is currently online (heartbeat within threshold). */\n online: boolean;\n /** Which process. */\n pid: number;\n}\n\nexport interface ClientRegistrationInput {\n clientId: string;\n sessionId: string;\n name: string;\n source: ClientSource;\n pid: number;\n}\n\nexport interface ClientHeartbeatInput {\n clientId: string;\n /** Active session id for this client. When present, updates the registry entry. */\n sessionId?: string | undefined;\n}\n\n// \u2500\u2500 Agent heartbeat input \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface AgentHeartbeatInput {\n agentId: string;\n status?: RegisteredAgent['status'] | undefined;\n currentTool?: string | undefined;\n currentTask?: string | undefined;\n iterations?: number | undefined;\n toolCalls?: number | undefined;\n}\n\n// \u2500\u2500 Purge options & result \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface PurgeOptions {\n /**\n * Purge completed messages older than this many milliseconds.\n * Default: 1 day (86_400_000 ms)\n */\n completedMaxAgeMs?: number | undefined;\n /**\n * Purge incomplete messages older than this many milliseconds.\n * Default: 7 days (604_800_000 ms)\n */\n incompleteMaxAgeMs?: number | undefined;\n}\n\nexport interface PurgeResult {\n /** Messages removed because they were completed and too old. */\n completedPurged: number;\n /** Messages removed because they were incomplete and too old. */\n incompletePurged: number;\n /** Total messages removed. */\n totalPurged: number;\n /** Messages remaining in the mailbox after purge. */\n remaining: number;\n}\n\n// \u2500\u2500 Auto-compact options & result \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface AutoCompactOptions {\n /**\n * Remove messages read by ALL currently-online agents that are older\n * than this many milliseconds since the last read receipt was stamped.\n * Default: 10 minutes (AUTO_COMPACT_READ_MAX_AGE_MS).\n */\n readMaxAgeMs?: number | undefined;\n /**\n * Default TTL for messages without an explicit `expiresAt`. Messages\n * whose `timestamp` is older than `now - defaultTtlMs` are removed.\n * Default: 24 hours (AUTO_COMPACT_DEFAULT_TTL_MS).\n */\n defaultTtlMs?: number | undefined;\n /**\n * Also run `purgeStale` logic in the same pass \u2014 purge completed\n * messages older than this many ms. Default: 1 day.\n */\n completedMaxAgeMs?: number | undefined;\n /**\n * Also run `purgeStale` logic in the same pass \u2014 purge incomplete\n * messages older than this many ms. Default: 7 days.\n */\n incompleteMaxAgeMs?: number | undefined;\n /**\n * Interval for the background auto-compact timer.\n * Default: 5 minutes (AUTO_COMPACT_INTERVAL_MS).\n */\n intervalMs?: number | undefined;\n /**\n * Also run `purgeStale` logic in the same pass (completed > 1 day,\n * incomplete > 7 days). Default: true.\n */\n includePurgeStale?: boolean | undefined;\n}\n\nexport interface AutoCompactResult {\n /** Messages removed because they were read by all online agents. */\n readByAllRemoved: number;\n /** Messages removed because their TTL expired (explicit or default). */\n expiredRemoved: number;\n /** Messages removed by the purgeStale pass (if enabled). */\n stalePurged: number;\n /** Total messages removed. */\n totalRemoved: number;\n /** Messages remaining in the mailbox after compaction. */\n remaining: number;\n}\n\n// \u2500\u2500 Mailbox interface \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface Mailbox {\n /** Send a message. Returns the created message. */\n send(input: MailboxSendInput): Promise<MailboxMessage>;\n\n /** Query messages matching criteria. */\n query(query: MailboxQuery): Promise<MailboxMessage[]>;\n\n /** Acknowledge a message (read/complete). Returns updated message. */\n ack(input: MailboxAckInput): Promise<MailboxMessage | null>;\n\n /**\n * Acknowledge many messages in one shot. Acquires the file lock once and\n * rewrites the message file once, regardless of how many acks are in the\n * batch. Returns the messages that were actually updated (messages whose\n * ids are not in the file are skipped silently).\n *\n * This is the preferred path when an agent has multiple fresh messages\n * to receipt at once \u2014 the per-message {@link ack} path does a full\n * read-modify-rewrite of the mailbox file for every call.\n */\n ackMany(input: MailboxAckBatchInput): Promise<MailboxMessage[]>;\n\n /**\n * Soft-delete a message. Sets `deletedAt` to the current timestamp\n * and records the acting agent in `deletedBy`. Reversible via\n * {@link restore}. The default `query()` filter hides the message\n * once `deletedAt` is set; pass `includeDeleted: true` to see the\n * trash.\n */\n softDelete(mailId: string, by: string): Promise<MailboxMessage | null>;\n\n /**\n * Undo a {@link softDelete}. Clears `deletedAt` and `deletedBy` on\n * the message. No-op (returns the message as-is) if the message is\n * not soft-deleted.\n */\n restore(mailId: string): Promise<MailboxMessage | null>;\n\n /** Get a snapshot of online/offline agents and their current tasks. */\n getAgentStatuses(): Promise<MailboxAgentStatus[]>;\n\n /**\n * Get only online agents (heartbeat within 60s).\n * Useful for \"who can I talk to right now?\" queries.\n */\n getOnlineAgents(): Promise<MailboxAgentStatus[]>;\n\n /**\n * Register an agent. Called once per agent on first mailbox use.\n * Subsequent calls are idempotent \u2014 they update lastSeenAt.\n */\n registerAgent(input: AgentRegistrationInput): Promise<void>;\n /** Remove an agent from the registry entirely. Called on session shutdown. */\n deregisterAgent(agentId: string): Promise<void>;\n\n /**\n * Update agent heartbeat and optional status fields.\n * Called periodically (every tool call / iteration).\n */\n heartbeat(input: AgentHeartbeatInput): Promise<void>;\n\n /**\n * Count unread messages for a specific agent.\n * Used for \"new mail\" notifications without pulling full message bodies.\n */\n unreadCount(forAgentId: string): Promise<number>;\n\n /** Close and flush any pending writes. */\n close(): Promise<void>;\n\n /**\n * Delete all messages from the mailbox file.\n * Agents and read receipts are preserved; only messages are cleared.\n */\n clearAll(): Promise<void>;\n\n /**\n * Purge orphaned and stale messages from the mailbox.\n *\n * Stale messages are:\n * - Completed messages older than `completedMaxAgeMs` (default: 1 day)\n * - Incomplete messages older than `incompleteMaxAgeMs` (default: 7 days)\n *\n * This does NOT touch agent registrations or client registry.\n */\n purgeStale(opts?: PurgeOptions): Promise<PurgeResult>;\n\n /**\n * Auto-compact: remove messages that are no longer needed.\n *\n * Two cleanup passes run in a single file rewrite:\n * 1. **Read-by-all**: Messages read by every currently-online agent,\n * older than `readMaxAgeMs` (default 10 min).\n * 2. **Expired**: Messages whose `expiresAt` is in the past, or whose\n * `timestamp` is older than `defaultTtlMs` (default 24h) when no\n * explicit `expiresAt` is set.\n *\n * Also runs `purgeStale` logic (completed > 1 day, incomplete > 7 days)\n * in the same pass to avoid a second rewrite.\n */\n autoCompact(opts?: AutoCompactOptions): Promise<AutoCompactResult>;\n\n /**\n * Start a background timer that periodically calls `autoCompact`.\n * Returns a dispose function that stops the timer. Idempotent \u2014\n * calling start twice replaces the prior timer.\n */\n startAutoCompactTimer(opts?: AutoCompactOptions): () => void;\n\n // \u2500\u2500 Client (REPL/TUI/WebUI) registry \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /**\n * Register a client (REPL/TUI/WebUI). Called once per client on startup.\n * Subsequent calls are idempotent \u2014 they update lastSeenAt.\n */\n registerClient(input: ClientRegistrationInput): Promise<void>;\n\n /**\n * Update client heartbeat. Called periodically (every 15s for clients).\n */\n clientHeartbeat(input: ClientHeartbeatInput): Promise<void>;\n\n /** Remove a client immediately on clean shutdown. */\n deregisterClient(clientId: string): Promise<void>;\n\n /**\n * Get snapshot of online/offline clients and their last activity.\n */\n getClientStatuses(): Promise<ClientStatus[]>;\n\n /**\n * Explicitly purge stale clients from the registry.\n * Removes client entries whose lastSeenAt is older than CLIENT_STALE_MS.\n * Returns the number of entries purged.\n */\n purgeClients(): Promise<number>;\n}\n", "/**\n * HQ auth-store \u2014 persistent `auth.json` for the HQ command center.\n *\n * Phase 4 scope:\n * - Operator-configured redaction policy override (applied server-side\n * even when a publisher claims rawContent:true).\n * - Browser tokens (Phase 3) + client tokens (Phase 4). Separate lists so\n * a browser-only token cannot be replayed on /ws/client and vice versa.\n * - Live reload hook: callers can `watchHqAuthFile()` to re-read on change.\n *\n * Storage layout (under the HQ data directory, default `~/.wrongstack/hq/`):\n * <dataDir>/auth.json \u2014 this file (atomic write, mode 0o600)\n * <dataDir>/events.jsonl \u2014 reserved for future persistent event log\n * <dataDir>/snapshot.json \u2014 reserved for future persisted snapshot\n *\n * The file is written atomically (tmp + rename) with mode 0o600 so a\n * shared host cannot read issued tokens or the redaction policy. Reads\n * are lenient: a missing file yields an empty document; a corrupt file\n * yields an empty document plus a warning so the operator can recover.\n *\n * @module hq/auth-store\n */\nimport { randomBytes, randomUUID, scrypt, timingSafeEqual } from 'node:crypto';\nimport * as fs from 'node:fs/promises';\nimport * as syncFs from 'node:fs';\nimport * as path from 'node:path';\n\nimport { atomicWrite } from '../utils/atomic-write.js';\nimport { wstackGlobalRoot } from '../utils/wstack-paths.js';\nimport type { HqRedactionPolicy } from './protocol.js';\n\n/** Current auth-file schema version. Bump on breaking shape changes. */\nexport const HQ_AUTH_FILE_VERSION = 1 as const;\n\n/** Default HQ data directory: `~/.wrongstack/hq` (honors WRONGSTACK_HOME). */\nexport function defaultHqDataDir(): string {\n return path.join(wstackGlobalRoot(), 'hq');\n}\n\n/**\n * Resolve an HQ data directory from an optional override.\n *\n * Resolution order:\n * 1. Explicit `override` (from `--data-dir`) \u2014 resolved against\n * `process.cwd()` if relative.\n * 2. `WRONGSTACK_HQ_DATA_DIR` env var (same resolution rules).\n * 3. `defaultHqDataDir()` \u2014 `~/.wrongstack/hq`.\n *\n * The env var exists so tests (and sandboxed runs) can redirect HQ state\n * away from the real user home without threading a CLI flag everywhere.\n */\nexport function resolveHqDataDir(override?: string, env: NodeJS.ProcessEnv = process.env): string {\n const raw = override ?? env['WRONGSTACK_HQ_DATA_DIR']?.trim();\n if (!raw) return defaultHqDataDir();\n return path.isAbsolute(raw) ? path.resolve(raw) : path.resolve(process.cwd(), raw);\n}\n\n/**\n * A generic HQ-issued token. Used for both browser tokens (validated on\n * `/ws/browser`) and client tokens (validated on `/ws/client`). The two\n * are stored in separate lists so a browser-only token cannot be replayed\n * against the client channel and vice versa.\n *\n * `capabilities` scopes what a token may do. When absent the token is\n * unrestricted (backward-compat with tokens minted before Phase 3). Known\n * capability strings:\n * - `control.enqueue` \u2014 browser token may enqueue commands to clients\n * - `control.execute` \u2014 client token may execute `run-command` commands\n * - `telemetry.publish` \u2014 client token may publish telemetry\n */\nexport interface HqToken {\n id: string;\n token: string;\n label?: string;\n createdAt: string;\n lastUsedAt?: string;\n /**\n * Optional capability scope. When absent, the token is unrestricted\n * (backward-compat). When present, only the listed capabilities are\n * granted.\n */\n capabilities?: string[];\n}\n\n/**\n * Check whether a token grants a capability. A token with no `capabilities`\n * field is unrestricted (backward-compat). Otherwise the capability must be\n * explicitly listed.\n */\nexport function tokenHasCapability(token: HqToken | undefined, capability: string): boolean {\n if (token === undefined) return false;\n if (token.capabilities === undefined) return true;\n return token.capabilities.includes(capability);\n}\n\n/**\n * Alias kept for backward-compat with Phase 3 callers/tests. New code\n * should prefer `HqToken`.\n */\nexport type HqBrowserToken = HqToken;\n\n/** On-disk shape of `<dataDir>/auth.json`. */\nexport interface HqRuntimeFile {\n url: string;\n updatedAt: string;\n pid?: number;\n}\n\nexport interface HqAuthFile {\n version: typeof HQ_AUTH_FILE_VERSION;\n updatedAt: string;\n /**\n * Operator-configured redaction policy override. When present, the HQ\n * server applies these settings AFTER any publisher-declared policy \u2014\n * i.e. the operator can always tighten, never loosen.\n */\n redactionPolicy?: Partial<HqRedactionPolicy>;\n /** Browser tokens \u2014 validated on `/ws/browser` upgrades (Phase 3). */\n browserTokens?: HqToken[];\n /** Client tokens \u2014 validated on `/ws/client` upgrades (Phase 4). */\n clientTokens?: HqToken[];\n /** scrypt hash of the optional browser password login. */\n passwordHash?: string;\n /** Secret used to sign browser session cookies. */\n cookieSecret?: string;\n}\n\n/** An empty auth file \u2014 what a brand-new HQ install starts with. */\nexport function emptyHqAuthFile(): HqAuthFile {\n return {\n version: HQ_AUTH_FILE_VERSION,\n updatedAt: new Date().toISOString(),\n };\n}\n\n/** Path to `auth.json` under the given data directory. */\nexport function hqAuthFilePath(dataDir: string): string {\n return path.join(dataDir, 'auth.json');\n}\n\n/** Path to the best-effort runtime endpoint marker under the given data directory. */\nexport function hqRuntimeFilePath(dataDir: string): string {\n return path.join(dataDir, 'runtime.json');\n}\n\nexport async function writeHqRuntimeFile(dataDir: string, file: Omit<HqRuntimeFile, 'updatedAt'>): Promise<void> {\n const payload: HqRuntimeFile = {\n ...file,\n updatedAt: new Date().toISOString(),\n };\n await atomicWrite(hqRuntimeFilePath(dataDir), `${JSON.stringify(payload, null, 2)}\\n`, { mode: 0o600 });\n}\n\nfunction isProcessAlive(pid: number): boolean {\n if (!Number.isInteger(pid) || pid <= 0) return false;\n try {\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n}\n\nexport function readHqRuntimeFileSync(dataDir: string): HqRuntimeFile | undefined {\n try {\n const parsed = JSON.parse(syncFs.readFileSync(hqRuntimeFilePath(dataDir), 'utf8')) as Partial<HqRuntimeFile>;\n if (typeof parsed.url !== 'string' || parsed.url.trim().length === 0) return undefined;\n if (typeof parsed.pid === 'number' && !isProcessAlive(parsed.pid)) return undefined;\n return {\n url: parsed.url,\n updatedAt: typeof parsed.updatedAt === 'string' ? parsed.updatedAt : '',\n ...(typeof parsed.pid === 'number' ? { pid: parsed.pid } : {}),\n };\n } catch {\n return undefined;\n }\n}\n\n/**\n * Read `auth.json` from disk. Returns `emptyHqAuthFile()` when:\n * - the file does not exist (ENOENT), or\n * - the file cannot be parsed (the `warn` callback surfaces the error).\n *\n * Never throws for routine I/O \u2014 a missing or corrupt auth file should not\n * prevent the HQ server from starting. The operator can recover by editing\n * or deleting the file.\n */\nexport async function readHqAuthFile(\n dataDir: string,\n opts: { warn?: (msg: string) => void } = {},\n): Promise<HqAuthFile> {\n const file = hqAuthFilePath(dataDir);\n let raw: string;\n try {\n raw = await fs.readFile(file, 'utf8');\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return emptyHqAuthFile();\n // Non-ENOENT (EACCES, EIO, \u2026) \u2014 surface but don't crash startup.\n opts.warn?.(`HQ auth file read failed at ${file}: ${(err as Error).message}`);\n return emptyHqAuthFile();\n }\n try {\n const parsed = JSON.parse(raw) as HqAuthFile;\n if (parsed.version !== HQ_AUTH_FILE_VERSION) {\n opts.warn?.(\n `HQ auth file at ${file} has unsupported version ${String(parsed.version)} (expected ${String(HQ_AUTH_FILE_VERSION)}); ignoring stored policy/tokens.`,\n );\n return emptyHqAuthFile();\n }\n return parsed;\n } catch (err) {\n opts.warn?.(`HQ auth file at ${file} is not valid JSON; ignoring stored policy/tokens: ${(err as Error).message}`);\n return emptyHqAuthFile();\n }\n}\n\n/**\n * Write `auth.json` atomically with mode 0o600. Creates the data directory\n * if needed. Throws on I/O failure \u2014 callers (CLI commands) should surface\n * the error to the operator.\n */\nexport async function writeHqAuthFile(dataDir: string, file: HqAuthFile): Promise<void> {\n const target = hqAuthFilePath(dataDir);\n const payload: HqAuthFile = {\n ...file,\n version: HQ_AUTH_FILE_VERSION,\n updatedAt: new Date().toISOString(),\n };\n await atomicWrite(target, `${JSON.stringify(payload, null, 2)}\\n`, { mode: 0o600 });\n}\n\nexport interface EnsureHqFirstRunAuthOptions {\n warn?: (msg: string) => void;\n /** Optional browser password login. Hashed with scrypt before storage. */\n password?: string;\n}\n\nexport interface EnsureHqFirstRunAuthResult {\n authFile: HqAuthFile;\n created: boolean;\n browserToken?: HqToken;\n clientToken?: HqToken;\n}\n\n/**\n * Ensure a brand-new HQ data directory has the auth required for safe\n * first-run operation. Only a missing auth.json is bootstrapped; an existing\n * file, including one with empty token arrays, is treated as operator intent.\n */\nexport async function ensureHqFirstRunAuthFile(\n dataDir: string,\n opts: EnsureHqFirstRunAuthOptions = {},\n): Promise<EnsureHqFirstRunAuthResult> {\n const file = hqAuthFilePath(dataDir);\n try {\n await fs.access(file);\n return { authFile: await readHqAuthFile(dataDir, opts), created: false };\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT') {\n opts.warn?.(`HQ auth file access failed at ${file}: ${(err as Error).message}`);\n return { authFile: await readHqAuthFile(dataDir, opts), created: false };\n }\n }\n\n // First-run credentials are deliberately least-privilege. Operators can\n // mint an execution-capable client token explicitly when remote command\n // execution is required; a freshly started HQ must never grant it by\n // accident.\n const browserToken = { ...mintHqToken('first-run browser'), capabilities: ['control.enqueue'] };\n const clientToken = { ...mintHqToken('first-run client'), capabilities: ['telemetry.publish'] };\n const authFile: HqAuthFile = {\n version: HQ_AUTH_FILE_VERSION,\n updatedAt: new Date().toISOString(),\n browserTokens: [browserToken],\n clientTokens: [clientToken],\n };\n if (opts.password) {\n authFile.passwordHash = await hashHqPassword(opts.password);\n authFile.cookieSecret = mintHqCookieSecret();\n }\n await writeHqAuthFile(dataDir, authFile);\n return { authFile: await readHqAuthFile(dataDir, opts), created: true, browserToken, clientToken };\n}\n\n/**\n * Load \u2192 mutate \u2192 write. The mutator receives the current file (or an empty\n * one) and returns the next file. Use this for any read-modify-write cycle\n * to avoid clobbering concurrent edits from another CLI invocation.\n *\n * Note: this does NOT take a file lock. HQ auth edits are rare (operator\n * running `wstack --hq-token add` etc.) and the atomic rename protects\n * against torn writes; a race between two concurrent edits would be\n * last-write-wins, which is acceptable for this low-frequency file.\n */\nexport async function mutateHqAuthFile(\n dataDir: string,\n mutator: (current: HqAuthFile) => HqAuthFile | Promise<HqAuthFile>,\n opts: { warn?: (msg: string) => void } = {},\n): Promise<HqAuthFile> {\n const current = await readHqAuthFile(dataDir, opts);\n const next = await mutator(current);\n await writeHqAuthFile(dataDir, next);\n return next;\n}\n\nconst HQ_PASSWORD_SALT_BYTES = 16;\nconst HQ_PASSWORD_HASH_BYTES = 32;\nconst HQ_PASSWORD_SCRYPT_PARAMS = { N: 16384, r: 8, p: 1 };\n\n/**\n * Hash a browser password for storage in `auth.json`. Uses scrypt with a\n * random salt; the returned string is `scrypt$<salt>$<hash>` in base64url.\n */\nexport function hashHqPassword(password: string): Promise<string> {\n return new Promise((resolve, reject) => {\n const salt = randomBytes(HQ_PASSWORD_SALT_BYTES);\n scrypt(password, salt, HQ_PASSWORD_HASH_BYTES, HQ_PASSWORD_SCRYPT_PARAMS, (err, derivedKey) => {\n if (err) return reject(err);\n const payload = `scrypt$${salt.toString('base64url')}$${derivedKey.toString('base64url')}`;\n resolve(payload);\n });\n });\n}\n\n/**\n * Verify a browser password against a stored scrypt hash.\n */\nexport async function verifyHqPassword(password: string, hash: string): Promise<boolean> {\n const parts = hash.split('$');\n if (parts.length !== 3 || parts[0] !== 'scrypt' || !parts[1] || !parts[2]) return false;\n let salt: Buffer;\n let expected: Buffer;\n try {\n salt = Buffer.from(parts[1], 'base64url');\n expected = Buffer.from(parts[2], 'base64url');\n } catch {\n return false;\n }\n if (salt.length === 0 || expected.length === 0) return false;\n const derived = await new Promise<Buffer>((resolve, reject) => {\n scrypt(password, salt, expected.length, HQ_PASSWORD_SCRYPT_PARAMS, (err, key) => {\n if (err) reject(err);\n else resolve(key);\n });\n });\n return timingSafeEqual(derived, expected);\n}\n\n/** Mint a secret used to sign browser session cookies. */\nexport function mintHqCookieSecret(): string {\n return randomBytes(32).toString('base64url');\n}\n\n/**\n * Mint a fresh token. Used for both browser and client tokens; the caller\n * decides which list to append to.\n */\nexport function mintHqToken(label?: string): HqToken {\n const now = new Date().toISOString();\n return {\n id: randomUUID(),\n token: randomUUID().replace(/-/g, '') + randomUUID().replace(/-/g, ''),\n ...(label ? { label } : {}),\n createdAt: now,\n };\n}\n\n/**\n * Backward-compat alias for `mintHqToken`. Phase 3 callers/tests use this.\n */\nexport const mintHqBrowserToken = mintHqToken;\n\n/**\n * Watch `auth.json` for changes and invoke `onChange` with the freshly-read\n * file. Returns a `close()` function that stops watching.\n *\n * The watcher debounces events (default 200ms) because most editors do a\n * tmp+rename dance that emits multiple events. On any read failure (file\n * deleted, corrupt, etc.) the `warn` callback is invoked with the same\n * semantics as `readHqAuthFile`; the watcher stays active so a future\n * valid write re-triggers the callback.\n *\n * Notes:\n * - `fs.watch` is best-effort across platforms. On some network\n * filesystems events may not fire; the operator must restart the server\n * to pick up changes in that case.\n * - The watcher polls the parent directory (not the file itself) so that\n * atomic rename events surface reliably.\n */\nexport function watchHqAuthFile(\n dataDir: string,\n onChange: (file: HqAuthFile) => void,\n opts: { warn?: (msg: string) => void; debounceMs?: number } = {},\n): { close: () => void } {\n const file = hqAuthFilePath(dataDir);\n const debounceMs = opts.debounceMs ?? 200;\n let timer: ReturnType<typeof setTimeout> | undefined;\n let closed = false;\n\n let watcher: syncFs.FSWatcher;\n try {\n // Watch the directory (not the file) so atomic-rename events surface\n // reliably. `fs.watch` is best-effort across platforms \u2014 on some\n // network filesystems events may not fire; the operator must restart\n // the server in that case.\n watcher = syncFs.watch(path.dirname(file), { recursive: false });\n } catch (err) {\n opts.warn?.(`HQ auth watcher could not start: ${(err as Error).message}`);\n return { close: () => {} };\n }\n\n const trigger = (): void => {\n if (closed) return;\n if (timer) clearTimeout(timer);\n timer = setTimeout(() => {\n timer = undefined;\n const readOpts = opts.warn ? { warn: opts.warn } : {};\n void readHqAuthFile(dataDir, readOpts).then(\n (next) => {\n if (!closed) onChange(next);\n },\n () => {\n // readHqAuthFile never throws for routine I/O \u2014 this is a\n // belt-and-braces guard.\n },\n );\n }, debounceMs);\n };\n\n watcher.on('change', (eventType: string, filename: string | Buffer | null) => {\n const name = typeof filename === 'string' ? filename : '';\n // Only react to events that touch auth.json (rename, change).\n if (eventType === 'rename' || eventType === 'change') {\n if (!name || name === 'auth.json' || name === path.basename(file)) {\n trigger();\n }\n }\n });\n\n watcher.on('error', (err: Error) => {\n opts.warn?.(`HQ auth watcher error: ${err.message}`);\n });\n\n return {\n close: () => {\n closed = true;\n if (timer) clearTimeout(timer);\n watcher.close();\n },\n };\n}\n", "/**\n * AgentMonitorEventBridge \u2014 forwards local agent timeline and status events\n * to the HQ publisher as structured HQ event envelopes, so the HQ browser\n * dashboard sees real-time agent conversation streams.\n */\nimport type { EventBus } from '../kernel/events.js';\nimport { createHqEventEnvelope, type HqAgentMessagePayload, type HqAgentStatusPayload, type HqEventEnvelope } from './protocol.js';\n\nexport type HqAgentEventPublisher = (envelope: HqEventEnvelope) => void;\n\nexport interface AgentMonitorEventBridgeOptions {\n /** Local EventBus emitting agent.timeline.* and agent.status_changed events. */\n events: EventBus;\n /** Client/project identifiers for HQ envelope authorship. */\n clientId: string;\n projectId: string;\n /**\n * Publish callback \u2014 called with each HQ event envelope. Wire this to\n * your HQ publisher's `send()` or queue method when connected.\n * When null (no HQ connection), events are silently dropped.\n */\n publish?: HqAgentEventPublisher | undefined;\n}\n\n/**\n * Start forwarding agent monitoring events to HQ. Returns a disposer that\n * unsubscribes all listeners \u2014 call on shutdown.\n */\nexport function startAgentMonitorEventBridge(opts: AgentMonitorEventBridgeOptions): () => void {\n const { events, clientId, projectId, publish } = opts;\n const seq = { current: 0 };\n\n function nextSeq(): number {\n seq.current += 1;\n return seq.current;\n }\n\n function buildEnvelope<T>(type: string, payload: T, sessionId?: string): HqEventEnvelope<T> {\n return createHqEventEnvelope({\n id: `${Date.now().toString(36)}-${nextSeq()}`,\n type: type as never,\n timestamp: new Date().toISOString(),\n clientId,\n projectId,\n seq: nextSeq(),\n payload,\n // Carry the parent session id so HQ can scope per-agent transcripts by\n // (sessionId, subagentId) \u2014 without it, two sessions whose leaders both\n // use the default id 'leader' would collide into one shared ring.\n ...(sessionId !== undefined ? { sessionId } : {}),\n }) as HqEventEnvelope<T>;\n }\n\n const offMessage = events.on('agent.timeline.message', (payload) => {\n if (!publish) return;\n const msgPayload: HqAgentMessagePayload = {\n subagentId: payload.subagentId,\n agentName: payload.agentName,\n content: payload.content,\n kind: payload.kind,\n iteration: payload.iteration,\n ts: payload.ts,\n };\n if (payload.toolName !== undefined) msgPayload.toolName = payload.toolName;\n if (payload.costUsd !== undefined) msgPayload.costUsd = payload.costUsd;\n publish(buildEnvelope('agent.message', msgPayload, payload.sessionId));\n });\n\n const offStatus = events.on('agent.status_changed', (payload) => {\n if (!publish) return;\n const statusPayload: HqAgentStatusPayload = {\n subagentId: payload.subagentId,\n agentName: payload.agentName,\n status: payload.status,\n ts: payload.ts,\n };\n if (payload.summary !== undefined) statusPayload.summary = payload.summary;\n if (payload.task !== undefined) statusPayload.task = payload.task;\n publish(buildEnvelope('agent.status', statusPayload));\n });\n\n return () => {\n offMessage();\n offStatus();\n };\n}\n", "/**\n * SessionTelemetryBridge \u2014 streams a surface's own live session state and full\n * chat transcript to HQ over the `/ws/client` plane, so the command center can\n * render every machine \u2192 terminal \u2192 agent \u2192 full-history across all connected\n * machines (not only the one HQ runs on).\n *\n * Two streams, both best-effort and self-contained:\n * 1. `session.snapshot` \u2014 the terminal's live state + agents, sourced from the\n * in-process `session.agents_updated` bus event (no registry file reads).\n * 2. `session.transcript` \u2014 incremental conversation turns, tailed cheaply\n * from this process's own session JSONL by byte offset.\n *\n * @module hq/session-bridge\n */\nimport * as fs from 'node:fs';\nimport * as fsp from 'node:fs/promises';\nimport type { EventBus, TrackedAgentSnapshot } from '../kernel/events.js';\nimport { sessionScopedPath } from '../utils/session-scoped-path.js';\nimport { resolveWstackPaths } from '../utils/wstack-paths.js';\nimport type {\n HqSessionAgentLiveStatus,\n HqSessionAgentSummary,\n HqSessionLiveStatus,\n HqSessionSnapshotPayload,\n HqTranscriptEntry,\n} from './protocol.js';\nimport type { HqPublisher } from './publisher.js';\nimport { mapSessionEventToEntries } from './transcript-mapper.js';\n\nexport interface SessionTelemetryBridgeOptions {\n publisher: HqPublisher;\n /** Local bus carrying `session.agents_updated`. When omitted, snapshots\n * still publish (with empty/last-known agents) and the transcript still\n * streams from disk. */\n events?: EventBus | undefined;\n sessionId: string;\n projectRoot: string;\n projectName?: string | undefined;\n /** Override the global root used to resolve the session JSONL path. */\n globalRoot?: string | undefined;\n /** Last-known agents to publish immediately before the next bus update. */\n initialAgents?: readonly TrackedAgentSnapshot[] | undefined;\n gitBranch?: string | undefined;\n startedAt?: string | undefined;\n /** Snapshot republish interval (also refreshes lastActivity). Default 2500ms. */\n snapshotIntervalMs?: number | undefined;\n /** Transcript tail poll interval. Default 1200ms. */\n transcriptIntervalMs?: number | undefined;\n now?: (() => string) | undefined;\n}\n\nconst VALID_AGENT_STATUS = new Set<HqSessionAgentLiveStatus>([\n 'idle',\n 'running',\n 'streaming',\n 'waiting_user',\n 'error',\n]);\nconst MAX_TRANSCRIPT_BATCH_ENTRIES = 32;\nconst MAX_TRANSCRIPT_BATCH_BYTES = 512 * 1024;\n\nfunction toAgentSummary(a: TrackedAgentSnapshot): HqSessionAgentSummary {\n const status = (\n VALID_AGENT_STATUS.has(a.status as HqSessionAgentLiveStatus) ? a.status : 'idle'\n ) as HqSessionAgentLiveStatus;\n return {\n id: a.id,\n name: a.name,\n status,\n iterations: a.iterations,\n toolCalls: a.toolCalls,\n lastActivityAt: a.lastActivityAt,\n ...(a.startedAt !== undefined ? { startedAt: a.startedAt } : {}),\n ...(a.currentTool !== undefined ? { currentTool: a.currentTool } : {}),\n ...(a.costUsd !== undefined ? { costUsd: a.costUsd } : {}),\n ...(a.tokensIn !== undefined ? { tokensIn: a.tokensIn } : {}),\n ...(a.tokensOut !== undefined ? { tokensOut: a.tokensOut } : {}),\n ...(a.ctxPct !== undefined ? { ctxPct: a.ctxPct } : {}),\n ...(a.model !== undefined ? { model: a.model } : {}),\n ...(a.partialText !== undefined ? { partialText: a.partialText } : {}),\n };\n}\n\nfunction deriveSessionStatus(agents: readonly HqSessionAgentSummary[]): HqSessionLiveStatus {\n return agents.some(\n (a) => a.status === 'running' || a.status === 'streaming' || a.status === 'waiting_user',\n )\n ? 'active'\n : 'idle';\n}\n\n/**\n * Start streaming this surface's session telemetry to HQ. Returns a disposer\n * that stops both streams and publishes a final `session.ended`.\n */\nexport function startSessionTelemetryBridge(opts: SessionTelemetryBridgeOptions): () => void {\n const now = opts.now ?? (() => new Date().toISOString());\n const publisher = opts.publisher;\n const identity = publisher.identity;\n const project = publisher.project;\n const startedAt = opts.startedAt ?? now();\n\n const wpaths = resolveWstackPaths({\n projectRoot: opts.projectRoot,\n ...(opts.globalRoot !== undefined ? { globalRoot: opts.globalRoot } : {}),\n });\n const sessionFile = sessionScopedPath(wpaths.projectSessions, opts.sessionId, '.jsonl');\n\n let agents: HqSessionAgentSummary[] = (opts.initialAgents ?? []).map(toAgentSummary);\n let lastActivityAt = agents.reduce(\n (latest, agent) => agent.lastActivityAt > latest ? agent.lastActivityAt : latest,\n startedAt,\n );\n let lastSnapshotHash = '';\n let disposed = false;\n\n function buildSnapshot(): HqSessionSnapshotPayload {\n return {\n sessionId: opts.sessionId,\n clientKind: identity.kind,\n machineId: identity.machineId,\n projectId: project.projectId,\n projectName: opts.projectName ?? project.projectName,\n projectRoot: opts.projectRoot,\n status: deriveSessionStatus(agents),\n startedAt,\n lastActivityAt,\n agentCount: agents.length,\n agents,\n ...(identity.hostname !== undefined ? { hostname: identity.hostname } : {}),\n ...(identity.pid !== undefined ? { pid: identity.pid } : {}),\n ...(opts.gitBranch !== undefined ? { gitBranch: opts.gitBranch } : {}),\n };\n }\n\n function publishSnapshot(force = false): void {\n if (disposed) return;\n const snap = buildSnapshot();\n // Hash on everything except lastActivityAt so identical state isn't\n // republished by the heartbeat tick, but real changes always go out.\n const hash = JSON.stringify({ ...snap, lastActivityAt: '' });\n if (!force && hash === lastSnapshotHash) return;\n lastSnapshotHash = hash;\n try {\n publisher.publishSessionSnapshot(snap);\n } catch {\n /* best-effort */\n }\n }\n\n function publishTranscriptEntries(entries: HqTranscriptEntry[]): void {\n let batch: HqTranscriptEntry[] = [];\n let batchFromSeq = seqEmitted;\n\n const publishBatch = (): void => {\n if (batch.length === 0) return;\n try {\n publisher.publishTranscriptAppend({\n sessionId: opts.sessionId,\n fromSeq: batchFromSeq,\n entries: batch,\n });\n } catch {\n /* best-effort */\n }\n seqEmitted += batch.length;\n batch = [];\n batchFromSeq = seqEmitted;\n };\n\n for (const entry of entries) {\n const candidate = [...batch, entry];\n const candidatePayload = {\n sessionId: opts.sessionId,\n fromSeq: batchFromSeq,\n entries: candidate,\n };\n const tooManyEntries = candidate.length > MAX_TRANSCRIPT_BATCH_ENTRIES;\n const tooLarge =\n batch.length > 0 &&\n Buffer.byteLength(JSON.stringify(candidatePayload), 'utf8') >\n MAX_TRANSCRIPT_BATCH_BYTES;\n if (tooManyEntries || tooLarge) publishBatch();\n batch.push(entry);\n }\n\n publishBatch();\n }\n\n const offAgents = opts.events?.on('session.agents_updated', (payload) => {\n agents = payload.agents.map(toAgentSummary);\n lastActivityAt = now();\n publishSnapshot();\n });\n\n // Announce the terminal immediately so its node appears even before any\n // agent activity.\n publishSnapshot(true);\n\n // \u2500\u2500 Transcript tail \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n let offset = 0;\n let partial = '';\n let seqEmitted = 0;\n let tailing = false;\n let watcher: fs.FSWatcher | null = null;\n let watchPending = false;\n\n // Once the session file exists, watch it so new turns are streamed within\n // milliseconds of being written \u2014 the interval poll is only a safety net.\n function setupWatcher(): void {\n if (disposed || watcher) return;\n try {\n const nextWatcher = fs.watch(sessionFile, () => {\n if (watchPending || disposed) return;\n watchPending = true;\n setTimeout(() => {\n watchPending = false;\n void tail();\n }, 25);\n });\n // fs.watch surfaces transient failures (EPERM/ENOENT on rename/delete,\n // common on Windows) as async 'error' events \u2014 swallow them so they\n // never become uncaught exceptions. The interval poll keeps us live.\n nextWatcher.on('error', () => {\n try {\n nextWatcher.close();\n } catch {\n /* ignore */\n }\n if (watcher === nextWatcher) watcher = null;\n });\n watcher = nextWatcher;\n } catch {\n watcher = null;\n }\n }\n\n async function tail(): Promise<void> {\n if (disposed || tailing) return;\n tailing = true;\n try {\n const stat = await fsp.stat(sessionFile).catch(() => null);\n if (disposed) return;\n if (!stat) return;\n setupWatcher();\n if (stat.size <= offset) return;\n const fd = await fsp.open(sessionFile, 'r');\n try {\n if (disposed) return;\n const len = stat.size - offset;\n const buf = Buffer.allocUnsafe(len);\n await fd.read(buf, 0, len, offset);\n offset = stat.size;\n partial += buf.toString('utf8');\n const lines = partial.split('\\n');\n partial = lines.pop() ?? '';\n const entries: HqTranscriptEntry[] = [];\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n let obj: Record<string, unknown>;\n try {\n obj = JSON.parse(trimmed) as Record<string, unknown>;\n } catch {\n continue;\n }\n for (const entry of mapSessionEventToEntries(obj)) entries.push(entry);\n }\n if (entries.length > 0) {\n publishTranscriptEntries(entries);\n lastActivityAt = now();\n }\n } finally {\n await fd.close();\n }\n } catch {\n /* best-effort */\n } finally {\n tailing = false;\n }\n }\n\n const snapshotTimer = setInterval(() => publishSnapshot(true), opts.snapshotIntervalMs ?? 2500);\n const tailTimer = setInterval(() => void tail(), opts.transcriptIntervalMs ?? 500);\n snapshotTimer.unref?.();\n tailTimer.unref?.();\n void tail();\n\n return () => {\n if (disposed) return;\n disposed = true;\n offAgents?.();\n if (watcher) {\n try {\n watcher.close();\n } catch {\n /* ignore */\n }\n watcher = null;\n }\n clearInterval(snapshotTimer);\n clearInterval(tailTimer);\n try {\n publisher.publishSessionEnded({ sessionId: opts.sessionId, endedAt: now() });\n } catch {\n /* best-effort */\n }\n };\n}\n", "/**\n * Transcript mapper \u2014 converts raw session JSONL events into the canonical\n * {@link HqTranscriptEntry} shape used by HQ for full chat-history rendering.\n *\n * On-disk reality (see `types/session.ts` + `core/agent-tools.ts`):\n * - A tool CALL (with its arguments) is NOT a standalone event \u2014 it is a\n * `tool_use` content block inside the assistant's `llm_response`.\n * - The tool RESULT is a separate `tool_result` event carrying the matching\n * `id`.\n * So we extract each `tool_use` block as a tool entry (args) at the assistant's\n * position, then merge the later `tool_result` (matched by `id`) INTO that same\n * entry \u2014 giving one box per tool (args + result) in strict chronological order.\n *\n * @module hq/transcript-mapper\n */\nimport type { HqTranscriptEntry, HqTranscriptRole } from './protocol.js';\n\nfunction blocksToText(content: unknown): string {\n if (typeof content === 'string') return content;\n if (Array.isArray(content)) {\n return content\n .filter(\n (b): b is { type: string; text: string } =>\n !!b &&\n typeof b === 'object' &&\n (b as { type?: unknown }).type === 'text' &&\n typeof (b as { text?: unknown }).text === 'string',\n )\n .map((b) => b.text)\n .join('\\n');\n }\n return '';\n}\n\nfunction asString(v: unknown): string {\n if (typeof v === 'string') return v;\n try {\n return JSON.stringify(v, null, 2);\n } catch {\n return String(v);\n }\n}\n\nfunction argsEntry(ts: string, name: unknown, input: unknown, id: unknown): HqTranscriptEntry {\n return {\n ts,\n role: 'tool',\n tool: String(name ?? 'tool'),\n toolInput: input !== undefined && input !== null ? asString(input) : '{}',\n text: '',\n ...(typeof id === 'string' ? { toolUseId: id } : {}),\n };\n}\n\n/**\n * Map a single raw JSONL session event to zero or more transcript entries.\n * An `llm_response` can yield an assistant text entry PLUS one tool entry per\n * embedded `tool_use` block.\n */\nexport function mapSessionEventToEntries(ev: Record<string, unknown>): HqTranscriptEntry[] {\n const ts = typeof ev['ts'] === 'string' ? (ev['ts'] as string) : '';\n const make = (\n role: HqTranscriptRole,\n text: string,\n extra?: Partial<HqTranscriptEntry>,\n ): HqTranscriptEntry => ({\n ts,\n role,\n text,\n ...extra,\n });\n\n switch (ev['type']) {\n case 'user_input': {\n const t = blocksToText(ev['content']);\n return t.trim() ? [make('user', t)] : [];\n }\n case 'llm_response': {\n const out: HqTranscriptEntry[] = [];\n const content = ev['content'];\n // Thinking blocks precede text/tool_use in an assistant message (provider\n // contract) \u2014 surface them first so the transcript preserves that order.\n if (Array.isArray(content)) {\n const thinking = content\n .filter(\n (b): b is { type: string; thinking: string } =>\n !!b &&\n typeof b === 'object' &&\n (b as { type?: unknown }).type === 'thinking' &&\n typeof (b as { thinking?: unknown }).thinking === 'string',\n )\n .map((b) => b.thinking)\n .join('\\n');\n if (thinking.trim()) out.push(make('thinking', thinking));\n }\n const t = blocksToText(content);\n if (t.trim()) out.push(make('assistant', t));\n if (Array.isArray(content)) {\n for (const b of content) {\n if (b && typeof b === 'object' && (b as { type?: unknown }).type === 'tool_use') {\n const block = b as { id?: unknown; name?: unknown; input?: unknown };\n out.push(argsEntry(ts, block.name, block.input, block.id));\n }\n }\n }\n return out;\n }\n case 'tool_use':\n return [argsEntry(ts, ev['name'], ev['input'], ev['id'])];\n case 'tool_call_start':\n return [argsEntry(ts, ev['name'], ev['input'] ?? ev['args'], ev['id'])];\n case 'tool_result': {\n const isError = ev['isError'] === true;\n const content = ev['content'] ?? ev['output'];\n const outStr = content !== undefined && content !== null ? asString(content) : '';\n return [\n make(isError ? 'error' : 'tool', outStr, {\n tool: '\u21B3 result',\n ...(isError ? { isError: true } : {}),\n ...(typeof ev['id'] === 'string' ? { toolUseId: ev['id'] } : {}),\n }),\n ];\n }\n case 'tool_call_end': {\n const isError = ev['isError'] === true;\n const content = ev['output'] ?? ev['content'];\n const outStr = content !== undefined && content !== null ? asString(content) : '';\n if (!outStr.trim() && !isError && typeof ev['durationMs'] !== 'number') return [];\n return [\n make(isError ? 'error' : 'tool', outStr, {\n tool: typeof ev['name'] === 'string' ? String(ev['name']) : '\u21B3 result',\n ...(typeof ev['durationMs'] === 'number' ? { durationMs: ev['durationMs'] } : {}),\n ...(isError ? { isError: true } : {}),\n ...(typeof ev['id'] === 'string' ? { toolUseId: ev['id'] } : {}),\n }),\n ];\n }\n case 'error':\n case 'provider_error':\n return [make('error', String(ev['message'] ?? 'error'))];\n case 'agent_spawned':\n return [make('system', `spawned ${String(ev['role'] ?? 'agent')}`)];\n case 'task_completed':\n return [make('system', `task done: ${String(ev['title'] ?? '')}`)];\n case 'task_failed':\n return [make('system', `task failed: ${String(ev['title'] ?? '')}`)];\n default:\n return [];\n }\n}\n\n/**\n * Identify a \"result\" entry \u2014 a tool/error entry that carries a tool-use id but\n * no args (it's the output half of a tool call, to be merged into the args\n * half).\n */\nfunction isResultEntry(e: HqTranscriptEntry): boolean {\n return (\n (e.role === 'tool' || e.role === 'error') &&\n e.toolUseId !== undefined &&\n e.toolInput === undefined\n );\n}\n\n/**\n * Merge each tool result into its matching args entry (by `toolUseId`),\n * keeping the args entry's chronological position. Results with no matching\n * args entry are kept as their own entries. Mutates/keeps order; pure w.r.t.\n * input ordering.\n */\nexport function mergeToolResults(flat: readonly HqTranscriptEntry[]): HqTranscriptEntry[] {\n const out: HqTranscriptEntry[] = [];\n const argsById = new Map<string, HqTranscriptEntry>();\n for (const src of flat) {\n const e: HqTranscriptEntry = { ...src };\n if (isResultEntry(e) && e.toolUseId !== undefined) {\n const tgt = argsById.get(e.toolUseId);\n if (tgt) {\n tgt.text = e.text || '';\n if (e.durationMs !== undefined) tgt.durationMs = e.durationMs;\n if (e.isError) {\n tgt.role = 'error';\n tgt.isError = true;\n }\n continue; // merged into the existing args box \u2014 no new entry\n }\n }\n out.push(e);\n if (e.role === 'tool' && e.toolUseId !== undefined && e.toolInput !== undefined) {\n argsById.set(e.toolUseId, e);\n }\n }\n return out;\n}\n\n/**\n * Map + merge an array of raw JSONL events into the final transcript-entry\n * list: strict chronological order, with each tool's args and result combined\n * into a single entry.\n */\nexport function buildTranscriptFromEvents(\n events: Iterable<Record<string, unknown>>,\n): HqTranscriptEntry[] {\n const flat: HqTranscriptEntry[] = [];\n for (const ev of events) {\n for (const e of mapSessionEventToEntries(ev)) flat.push(e);\n }\n return mergeToolResults(flat);\n}\n", "/**\n * FleetTelemetryBridge \u2014 forwards local multi-agent coordinator stats to the\n * HQ publisher as `fleet.snapshot` envelopes, so the command center can render\n * a global fleet roll-up (queued/completed/failed tasks, per-subagent status,\n * fleet cost) across every connected machine.\n *\n * Source: the `coordinator.stats` EventBus event (originating on the FleetBus\n * and re-emitted onto the host EventBus by `fleet/host.ts`). All payload\n * fields are plain serializable data \u2014 no closures, no decoupled relay needed.\n *\n * The snapshot is republished on every `coordinator.stats` change (hash-dedup,\n * mirroring {@link startSessionTelemetryBridge}) so the HQ browser sees live\n * fleet counters without polling.\n *\n * @module hq/fleet-bridge\n */\nimport type { EventBus } from '../kernel/events.js';\nimport type { HqEventEnvelope, HqFleetSnapshotPayload, HqSubagentSummary } from './protocol.js';\nimport type { HqPublisher } from './publisher.js';\n\nexport interface FleetTelemetryBridgeOptions {\n /** Local EventBus emitting `coordinator.stats` (host EventBus after the FleetBus hop). */\n events: EventBus;\n /** HQ publisher to forward envelopes to. */\n publisher: HqPublisher;\n /** Coordinator run id \u2014 identifies this fleet instance. Falls back to a stable per-session id. */\n runId: string;\n /** Optional sessionId to tag envelopes with. */\n sessionId?: string;\n /** Override `now()` for deterministic tests. */\n now?: () => string;\n}\n\n/**\n * Start forwarding coordinator stats to HQ. Returns a disposer that\n * unsubscribes the listener \u2014 call on shutdown.\n */\nexport function startFleetTelemetryBridge(opts: FleetTelemetryBridgeOptions): () => void {\n const { events, publisher, runId } = opts;\n const now = opts.now ?? (() => new Date().toISOString());\n let lastHash = '';\n\n function buildPayload(stats: {\n total: number;\n running: number;\n idle: number;\n stopped: number;\n inFlight: number;\n pending: number;\n completed: number;\n subagentStatuses: { subagentId: string; taskId: string; status: string; assigned: boolean }[];\n }): HqFleetSnapshotPayload {\n const subagents: HqSubagentSummary[] = stats.subagentStatuses.map((s) => ({\n subagentId: s.subagentId,\n ...(s.taskId ? { task: s.taskId } : {}),\n status: normalizeSubagentStatus(s.status),\n }));\n return {\n runId,\n activeSubagents: stats.running + stats.idle,\n queuedTasks: stats.pending,\n completedTasks: stats.completed,\n failedTasks: stats.stopped,\n subagents,\n };\n }\n\n const off = events.on('coordinator.stats', (stats) => {\n try {\n const payload = buildPayload(stats);\n // Hash-dedup so identical fleet state isn't republished.\n const hash = JSON.stringify(payload);\n if (hash === lastHash) return;\n lastHash = hash;\n publisher.publishFleetSnapshot(payload, {\n ...(opts.sessionId !== undefined ? { sessionId: opts.sessionId } : {}),\n timestamp: now(),\n });\n } catch {\n /* best-effort \u2014 HQ telemetry must never break the host */\n }\n });\n\n return () => {\n off();\n };\n}\n\nconst FLEET_STATUS_MAP: Record<string, HqSubagentSummary['status']> = {\n running: 'running',\n idle: 'idle',\n pending: 'pending',\n completed: 'completed',\n failed: 'failed',\n stopped: 'stopped',\n timeout: 'stopped',\n budget_exhausted: 'stopped',\n};\n\nfunction normalizeSubagentStatus(raw: string): HqSubagentSummary['status'] {\n return FLEET_STATUS_MAP[raw] ?? 'idle';\n}\n\n/** Re-export for type-only consumers. */\nexport type { HqEventEnvelope };\n", "/**\n * BrainTelemetryBridge \u2014 forwards local Brain (decision layer) events to the\n * HQ publisher as `brain.event` envelopes, so the command center can observe\n * decision requests, answers, denials, ask-human escalations, and\n * self-activated interventions across every connected machine.\n *\n * Source: the `brain.*` EventBus events emitted by `ObservableBrainArbiter`\n * (`coordination/brain.ts`) and `BrainMonitor` (`coordination/brain-monitor.ts`).\n * All payloads are plain serializable data (request id, question, source, risk,\n * decision kind, rationale) \u2014 no closures, no decoupled relay needed.\n *\n * The webui `setup-events.ts` already forwards these verbatim to its browser;\n * this bridge does the same for the cross-machine HQ plane.\n *\n * @module hq/brain-bridge\n */\nimport type { EventBus } from '../kernel/events.js';\nimport type { BrainDecision, BrainDecisionRequest } from '../coordination/brain.js';\nimport type { HqBrainEventKind, HqBrainEventPayload, HqEventEnvelope } from './protocol.js';\nimport type { HqPublisher } from './publisher.js';\n\nexport interface BrainTelemetryBridgeOptions {\n /** Local EventBus emitting `brain.*` events. */\n events: EventBus;\n /** HQ publisher to forward envelopes to. */\n publisher: HqPublisher;\n /** Optional sessionId to tag envelopes with. */\n sessionId?: string;\n /** Override `now()` for deterministic tests. */\n now?: () => string;\n}\n\nfunction extractRequestFields(req: BrainDecisionRequest | undefined): {\n requestId?: string;\n question?: string;\n source?: string;\n risk?: string;\n} {\n if (req === undefined) return {};\n const out: { requestId?: string; question?: string; source?: string; risk?: string } = {};\n if (typeof req.id === 'string') out.requestId = req.id;\n if (typeof req.question === 'string') out.question = req.question;\n if (typeof req.source === 'string') out.source = req.source;\n if (typeof req.risk === 'string') out.risk = req.risk;\n return out;\n}\n\nfunction extractDecisionFields(dec: BrainDecision | undefined): { decision?: string; detail?: string } {\n if (dec === undefined) return {};\n const out: { decision?: string; detail?: string } = {};\n // BrainDecision is a discriminated union on `type` (answer | ask_human | deny).\n out.decision = dec.type;\n if (dec.type === 'answer') {\n out.detail = dec.text;\n } else if (dec.type === 'ask_human') {\n out.detail = dec.prompt;\n } else if (dec.type === 'deny') {\n out.detail = dec.reason;\n }\n return out;\n}\n\n/**\n * Start forwarding brain events to HQ. Returns a disposer that unsubscribes\n * all listeners \u2014 call on shutdown.\n */\nexport function startBrainTelemetryBridge(opts: BrainTelemetryBridgeOptions): () => void {\n const { events, publisher } = opts;\n const now = opts.now ?? (() => new Date().toISOString());\n\n function publish(kind: HqBrainEventKind, payload: Partial<HqBrainEventPayload>, at: number): void {\n try {\n const full: HqBrainEventPayload = { kind, at, ...payload } as HqBrainEventPayload;\n publisher.publishEvent({\n type: 'brain.event',\n payload: full,\n ...(opts.sessionId !== undefined ? { sessionId: opts.sessionId } : {}),\n timestamp: now(),\n });\n } catch {\n /* best-effort */\n }\n }\n\n const offs: Array<() => void> = [];\n\n offs.push(\n events.on('brain.decision_requested', (p) => {\n publish('decision_requested', extractRequestFields(p.request), p.at);\n }),\n );\n offs.push(\n events.on('brain.decision_answered', (p) => {\n publish('decision_answered', {\n ...extractRequestFields(p.request),\n ...extractDecisionFields(p.decision),\n }, p.at);\n }),\n );\n offs.push(\n events.on('brain.decision_ask_human', (p) => {\n publish('decision_ask_human', {\n ...extractRequestFields(p.request),\n ...extractDecisionFields(p.decision),\n }, p.at);\n }),\n );\n offs.push(\n events.on('brain.decision_denied', (p) => {\n publish('decision_denied', {\n ...extractRequestFields(p.request),\n ...extractDecisionFields(p.decision),\n }, p.at);\n }),\n );\n offs.push(\n events.on('brain.human_answered', (p) => {\n const detail = typeof p.text === 'string' ? p.text : p.optionId;\n publish('human_answered', {\n requestId: p.id,\n ...(detail !== undefined ? { detail } : {}),\n ...(p.deny === true ? { decision: 'deny' } : {}),\n }, p.at);\n }),\n );\n offs.push(\n events.on('brain.intervention', (p) => {\n publish('intervention', {\n ...extractRequestFields(p.request),\n ...extractDecisionFields(p.decision),\n interventionKind: p.kind,\n intervened: p.intervened,\n }, p.at);\n }),\n );\n\n return () => {\n for (const off of offs) off();\n };\n}\n\n/** Re-export for type-only consumers. */\nexport type { HqEventEnvelope };\n", "/**\n * WorktreeTelemetryBridge \u2014 forwards local git-worktree lifecycle events to\n * the HQ publisher as `worktree.event` envelopes, so the command center can\n * render live build phase swim-lanes / DAG across every connected machine.\n *\n * Source: the `worktree.*` EventBus events emitted by `WorktreeManager`\n * (`worktree/worktree-manager.ts`): allocated, committed, merged, conflict,\n * released, failed. All payload fields are plain serializable data\n * (handleId, ownerId, branch, diff stats, conflict files) \u2014 no closures, no\n * decoupled relay needed.\n *\n * @module hq/worktree-bridge\n */\nimport type { EventBus } from '../kernel/events.js';\nimport type { HqEventEnvelope, HqWorktreeEventPayload } from './protocol.js';\nimport type { HqPublisher } from './publisher.js';\n\nexport interface WorktreeTelemetryBridgeOptions {\n /** Local EventBus emitting `worktree.*` events. */\n events: EventBus;\n /** HQ publisher to forward envelopes to. */\n publisher: HqPublisher;\n /** Optional sessionId to tag envelopes with. */\n sessionId?: string;\n /** Override `now()` for deterministic tests. */\n now?: () => string;\n}\n\ntype WorktreeAllocated = {\n sessionId?: string | undefined;\n handleId: string;\n ownerId: string;\n ownerLabel: string;\n slug: string;\n dir: string;\n branch: string;\n baseBranch: string;\n};\ntype WorktreeCommitted = {\n sessionId?: string | undefined;\n handleId: string;\n ownerId: string;\n branch: string;\n committed: boolean;\n insertions: number;\n deletions: number;\n files: number;\n sha?: string | undefined;\n};\ntype WorktreeMerged = {\n sessionId?: string | undefined;\n handleId: string;\n ownerId: string;\n branch: string;\n baseBranch: string;\n squash: boolean;\n};\ntype WorktreeConflict = {\n sessionId?: string | undefined;\n handleId: string;\n ownerId: string;\n branch: string;\n conflictFiles: string[];\n};\ntype WorktreeReleased = {\n sessionId?: string | undefined;\n handleId: string;\n ownerId: string;\n branch: string;\n kept: boolean;\n};\ntype WorktreeFailed = {\n sessionId?: string | undefined;\n handleId: string;\n ownerId: string;\n branch?: string | undefined;\n error: string;\n};\n\n/**\n * Start forwarding worktree lifecycle events to HQ. Returns a disposer that\n * unsubscribes all listeners \u2014 call on shutdown.\n */\nexport function startWorktreeTelemetryBridge(opts: WorktreeTelemetryBridgeOptions): () => void {\n const { events, publisher } = opts;\n const now = opts.now ?? (() => new Date().toISOString());\n\n function publish(payload: HqWorktreeEventPayload, sessionId?: string): void {\n try {\n publisher.publishEvent({\n type: 'worktree.event',\n payload,\n ...(sessionId !== undefined && sessionId !== '' ? { sessionId } : {}),\n ...(opts.sessionId !== undefined ? { sessionId: opts.sessionId } : {}),\n timestamp: now(),\n });\n } catch {\n /* best-effort */\n }\n }\n\n const offs: Array<() => void> = [];\n\n offs.push(\n events.on('worktree.allocated', (p: WorktreeAllocated) => {\n publish(\n {\n kind: 'allocated',\n handleId: p.handleId,\n ownerId: p.ownerId,\n ownerLabel: p.ownerLabel,\n slug: p.slug,\n branch: p.branch,\n baseBranch: p.baseBranch,\n },\n p.sessionId,\n );\n }),\n );\n\n offs.push(\n events.on('worktree.committed', (p: WorktreeCommitted) => {\n publish(\n {\n kind: 'committed',\n handleId: p.handleId,\n ownerId: p.ownerId,\n branch: p.branch,\n insertions: p.insertions,\n deletions: p.deletions,\n files: p.files,\n ...(p.sha !== undefined ? { sha: p.sha } : {}),\n },\n p.sessionId,\n );\n }),\n );\n\n offs.push(\n events.on('worktree.merged', (p: WorktreeMerged) => {\n publish(\n {\n kind: 'merged',\n handleId: p.handleId,\n ownerId: p.ownerId,\n branch: p.branch,\n baseBranch: p.baseBranch,\n squash: p.squash,\n },\n p.sessionId,\n );\n }),\n );\n\n offs.push(\n events.on('worktree.conflict', (p: WorktreeConflict) => {\n publish(\n {\n kind: 'conflict',\n handleId: p.handleId,\n ownerId: p.ownerId,\n branch: p.branch,\n conflictFiles: p.conflictFiles,\n },\n p.sessionId,\n );\n }),\n );\n\n offs.push(\n events.on('worktree.released', (p: WorktreeReleased) => {\n publish(\n {\n kind: 'released',\n handleId: p.handleId,\n ownerId: p.ownerId,\n branch: p.branch,\n kept: p.kept,\n },\n p.sessionId,\n );\n }),\n );\n\n offs.push(\n events.on('worktree.failed', (p: WorktreeFailed) => {\n publish(\n {\n kind: 'failed',\n handleId: p.handleId,\n ownerId: p.ownerId,\n ...(p.branch !== undefined ? { branch: p.branch } : {}),\n error: p.error,\n },\n p.sessionId,\n );\n }),\n );\n\n return () => {\n for (const off of offs) off();\n };\n}\n\n/** Re-export for type-only consumers. */\nexport type { HqEventEnvelope };\n", "/**\n * ToolTelemetryBridge \u2014 forwards local tool execution events to the HQ\n * publisher as `tool.started` and `tool.completed` envelopes, so the command\n * center can surface live tool activity (what's running, durations, success\n * rates) across every connected machine.\n *\n * Sources:\n * - `tool.started` (EventBus) \u2192 `tool.started` envelope. Raw tool input is\n * shaped via {@link summarizeHqToolArgs} according to the active HQ policy.\n * - `tool.executed` (EventBus) \u2192 `tool.completed` envelope (carries the\n * richer post-execution signal: duration, ok/error, output bytes).\n *\n * All payload fields are plain serializable data \u2014 no closures. The\n * `tool.started.input` raw args follow the publisher redaction policy before\n * publishing.\n *\n * @module hq/tool-bridge\n */\nimport type { EventBus } from '../kernel/events.js';\nimport { resolveHqRedactionPolicy, scrubAndTruncateHqPreview, summarizeHqToolArgs } from './redaction.js';\nimport type { HqEventEnvelope, HqRedactionPolicy, HqToolCompletedPayload, HqToolStartedPayload } from './protocol.js';\nimport type { HqPublisher } from './publisher.js';\n\nexport interface ToolTelemetryBridgeOptions {\n /** Local EventBus emitting `tool.started` and `tool.executed` events. */\n events: EventBus;\n /** HQ publisher to forward envelopes to. */\n publisher: HqPublisher;\n /** Project root for path redaction in tool input summaries. */\n projectRoot?: string;\n /** Optional sessionId to tag envelopes with. */\n sessionId?: string;\n /** Override `now()` for deterministic tests. */\n now?: () => string;\n}\n\ninterface ToolStartedEvent {\n sessionId?: string | undefined;\n name: string;\n id: string;\n input?: unknown | undefined;\n}\n\ninterface ToolExecutedEvent {\n sessionId?: string | undefined;\n id?: string | undefined;\n name: string;\n durationMs: number;\n ok: boolean;\n input?: unknown | undefined;\n output?: string | undefined;\n outputBytes?: number | undefined;\n}\n\n/** Track in-flight tool calls so we can attach start info to completion. */\ninterface InFlightTool {\n name: string;\n startedAt: number;\n}\n\n/**\n * Start forwarding tool execution events to HQ. Returns a disposer that\n * unsubscribes all listeners \u2014 call on shutdown.\n */\nexport function startToolTelemetryBridge(opts: ToolTelemetryBridgeOptions): () => void {\n const { events, publisher } = opts;\n const now = opts.now ?? (() => new Date().toISOString());\n const inFlight = new Map<string, InFlightTool>();\n\n function sessionIdTag(sessionId?: string): { sessionId?: string } {\n const tag = sessionId ?? opts.sessionId;\n return tag !== undefined ? { sessionId: tag } : {};\n }\n\n const offStarted = events.on('tool.started', (p: ToolStartedEvent) => {\n inFlight.set(p.id, { name: p.name, startedAt: Date.now() });\n try {\n const payload: HqToolStartedPayload = {\n toolName: p.name,\n ...(p.input !== undefined\n ? {\n inputSummary: summarizeHqToolArgs(p.input, {\n policy: publisher.redactionPolicy,\n ...(opts.projectRoot !== undefined ? { projectRoot: opts.projectRoot } : {}),\n }),\n }\n : {}),\n };\n publisher.publishEvent({\n type: 'tool.started',\n payload,\n ...sessionIdTag(p.sessionId),\n timestamp: now(),\n });\n } catch {\n /* best-effort */\n }\n });\n\n const offExecuted = events.on('tool.executed', (p: ToolExecutedEvent) => {\n const id = p.id;\n if (id !== undefined) inFlight.delete(id);\n try {\n const payload: HqToolCompletedPayload = {\n toolName: p.name,\n status: p.ok ? 'success' : 'error',\n durationMs: p.durationMs,\n ...(p.output !== undefined && p.output.length > 0\n ? { outputSummary: truncateForSummary(p.output, publisher.redactionPolicy) }\n : {}),\n };\n publisher.publishEvent({\n type: 'tool.completed',\n payload,\n ...sessionIdTag(p.sessionId),\n timestamp: now(),\n });\n } catch {\n /* best-effort */\n }\n });\n\n return () => {\n offStarted();\n offExecuted();\n inFlight.clear();\n };\n}\n\nfunction truncateForSummary(output: string, policy?: Partial<HqRedactionPolicy>, max = 280): unknown {\n const resolved = resolveHqRedactionPolicy(policy);\n if (resolved.rawContent) {\n if (output.length <= max) return output;\n return `${output.slice(0, max)}\u2026[truncated:${output.length - max}]`;\n }\n return scrubAndTruncateHqPreview(output, max) ?? '';\n}\n\n/** Re-export for type-only consumers. */\nexport type { HqEventEnvelope };\n", "/**\n * CostTelemetryBridge \u2014 forwards local token/cost accounting events to the HQ\n * publisher as `session.usage` envelopes, giving the command center the\n * granular per-call cost signal it needs to render live cost trends and\n * roll-ups across every connected machine.\n *\n * Source: the `token.accounted` EventBus event, emitted by the TokenCounter\n * (`infrastructure/token-counter.ts`) after every provider call. The payload\n * is plain serializable data (usage counts + a cost breakdown) \u2014 no closures.\n *\n * This is the high-frequency cost feed; HQ's persistence layer (Phase 2)\n * time-buckets these into trend series.\n *\n * @module hq/cost-bridge\n */\nimport type { EventBus } from '../kernel/events.js';\nimport type { Usage } from '../types/provider.js';\nimport type { HqEventEnvelope, HqUsagePayload } from './protocol.js';\nimport type { HqPublisher } from './publisher.js';\n\nexport interface CostTelemetryBridgeOptions {\n /** Local EventBus emitting `token.accounted`. */\n events: EventBus;\n /** HQ publisher to forward envelopes to. */\n publisher: HqPublisher;\n /** Optional sessionId to tag envelopes with (overrides the event's, when set). */\n sessionId?: string;\n /** Override `now()` for deterministic tests. */\n now?: () => string;\n}\n\ninterface TokenAccountedEvent {\n sessionId?: string | undefined;\n usage: Usage;\n cost: { input: number; output: number; total: number };\n}\n\n/**\n * Start forwarding token/cost events to HQ. Returns a disposer that\n * unsubscribes the listener \u2014 call on shutdown.\n */\nexport function startCostTelemetryBridge(opts: CostTelemetryBridgeOptions): () => void {\n const { events, publisher } = opts;\n const now = opts.now ?? (() => new Date().toISOString());\n\n const off = events.on('token.accounted', (p: TokenAccountedEvent) => {\n try {\n const payload: HqUsagePayload = {\n inputTokens: p.usage.input,\n outputTokens: p.usage.output,\n totalTokens: p.usage.input + p.usage.output,\n costUsd: p.cost.total,\n };\n const sessionId = opts.sessionId ?? p.sessionId;\n publisher.publishEvent({\n type: 'session.usage',\n payload,\n ...(sessionId !== undefined ? { sessionId } : {}),\n timestamp: now(),\n });\n } catch {\n /* best-effort */\n }\n });\n\n return () => {\n off();\n };\n}\n\n/** Re-export for type-only consumers. */\nexport type { HqEventEnvelope };\n", "/**\n * HQ persistence layer \u2014 survives HQ server restarts so the command center\n * keeps its event history, snapshot state, cost/activity trends, and (later)\n * alert + command-audit logs across reboots.\n *\n * Three stores, all file-backed under the HQ dataDir\n * (`~/.wrongstack/hq/` by default \u2014 see {@link resolveHqDataDir}):\n *\n * - {@link HqEventLog} \u2014 append-only JSONL of every received event\n * envelope, rotated when it exceeds a cap.\n * - {@link HqSnapshotStore} \u2014 atomic checkpoint of the latest snapshot,\n * written on every debounced broadcast.\n * - {@link HqTimeseriesStore}\u2014 time-bucketed cost + activity samples for\n * trend charts.\n *\n * Design constraints (mirrors the codebase conventions):\n * - All disk writes go through {@link withFileLock} + {@link atomicWrite}\n * (shared primitives from `utils/atomic-write.ts`) for cross-process safety.\n * - Every write is best-effort and never throws into the HQ server hot path \u2014\n * callers wrap in try/catch and degrade to in-memory-only on failure.\n * - Appends use a FIFO write chain (single in-flight writer) so concurrent\n * event arrivals don't interleave lines.\n *\n * @module hq/persistence\n */\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { atomicWrite, withFileLock } from '../utils/atomic-write.js';\nimport type { HqEventEnvelope, HqSnapshot } from './protocol.js';\n\n/** Maximum event-log lines before a rotation compacts it down to the tail. */\nconst DEFAULT_EVENT_LOG_MAX_LINES = 50_000;\n/** How many lines to retain after a rotation. */\nconst DEFAULT_EVENT_LOG_ROTATE_KEEP = 20_000;\n\n// \u2500\u2500 HqEventLog \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface HqEventLogOptions {\n dataDir: string;\n maxLines?: number;\n rotateKeep?: number;\n}\n\n/**\n * Append-only JSONL event log. Every received event envelope is appended to\n * `events.jsonl`; when the file exceeds `maxLines` it is rotated under a file\n * lock to keep only the most recent `rotateKeep` lines.\n *\n * Writes are serialized through a FIFO chain so concurrent appends never\n * interleave. All operations are best-effort: a rejected append resolves\n * (never rejects) and the caller's `await` never breaks the server loop.\n */\nexport class HqEventLog {\n private readonly filePath: string;\n private readonly maxLines: number;\n private readonly rotateKeep: number;\n private writeChain: Promise<void> = Promise.resolve();\n private lineCount = 0;\n private counted = false;\n\n constructor(opts: HqEventLogOptions) {\n this.filePath = path.join(opts.dataDir, 'events.jsonl');\n this.maxLines = opts.maxLines ?? DEFAULT_EVENT_LOG_MAX_LINES;\n this.rotateKeep = opts.rotateKeep ?? DEFAULT_EVENT_LOG_ROTATE_KEEP;\n }\n\n /** Append an event envelope as one JSON line. Best-effort, never rejects. */\n append(event: HqEventEnvelope): void {\n this.writeChain = this.writeChain\n .then(() => this.appendInternal(event))\n .catch(() => {\n /* best-effort: a failed append must not break the write chain */\n });\n }\n\n /** Resolves once all queued appends have settled. For tests. */\n async drain(): Promise<void> {\n await this.writeChain.catch(() => {\n /* best-effort */\n });\n }\n\n private async appendInternal(event: HqEventEnvelope): Promise<void> {\n if (!this.counted) {\n this.lineCount = await this.countLines();\n this.counted = true;\n }\n const line = JSON.stringify(event) + '\\n';\n await fs.appendFile(this.filePath, line, { encoding: 'utf8' });\n this.lineCount += 1;\n if (this.lineCount >= this.maxLines) {\n await this.rotate();\n }\n }\n\n private async rotate(): Promise<void> {\n await withFileLock(this.filePath, async () => {\n try {\n const content = await fs.readFile(this.filePath, 'utf8');\n const lines = content.split('\\n').filter((l) => l.length > 0);\n if (lines.length <= this.rotateKeep) {\n this.lineCount = lines.length;\n return;\n }\n const kept = lines.slice(lines.length - this.rotateKeep);\n await atomicWrite(this.filePath, kept.join('\\n') + '\\n');\n this.lineCount = kept.length;\n } catch {\n /* best-effort */\n }\n });\n }\n\n private async countLines(): Promise<number> {\n try {\n const content = await fs.readFile(this.filePath, 'utf8');\n return content.split('\\n').filter((l) => l.length > 0).length;\n } catch {\n return 0;\n }\n }\n\n /**\n * Read the most recent `limit` events, optionally filtered by envelope\n * `type`. Newest first. Returns `[]` if the file doesn't exist yet.\n */\n async recent(limit: number, typeFilter?: string): Promise<HqEventEnvelope[]> {\n let content: string;\n try {\n content = await fs.readFile(this.filePath, 'utf8');\n } catch {\n return [];\n }\n const lines = content.split('\\n').filter((l) => l.length > 0);\n const out: HqEventEnvelope[] = [];\n // Walk newest-first so we can stop early once we have `limit` matches.\n for (let i = lines.length - 1; i >= 0 && out.length < limit; i--) {\n try {\n const env = JSON.parse(lines[i]!) as HqEventEnvelope;\n if (typeFilter === undefined || env.type === typeFilter) {\n out.push(env);\n }\n } catch {\n /* skip malformed lines */\n }\n }\n return out;\n }\n\n /** Initialize the line count cache from disk (call once at boot). */\n async hydrate(): Promise<void> {\n this.lineCount = await this.countLines();\n this.counted = true;\n }\n}\n\n// \u2500\u2500 HqSnapshotStore \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface HqSnapshotStoreOptions {\n dataDir: string;\n}\n\n/**\n * Atomic checkpoint of the latest snapshot, written to `snapshot.json`.\n * The HQ server writes on every debounced broadcast and reads on boot to\n * re-seed its in-memory state. Best-effort, never rejects.\n */\nexport class HqSnapshotStore {\n private readonly filePath: string;\n private writeChain: Promise<void> = Promise.resolve();\n\n constructor(opts: HqSnapshotStoreOptions) {\n this.filePath = path.join(opts.dataDir, 'snapshot.json');\n }\n\n /** Persist a snapshot. Best-effort, never rejects. */\n save(snapshot: HqSnapshot): void {\n this.writeChain = this.writeChain\n .then(() => atomicWrite(this.filePath, JSON.stringify(snapshot), { mode: 0o600 }))\n .catch(() => {\n /* best-effort */\n });\n }\n\n /** Resolves once all queued saves have settled. For tests. */\n async drain(): Promise<void> {\n await this.writeChain.catch(() => {\n /* best-effort */\n });\n }\n\n /** Read the last persisted snapshot, or `null` if none. */\n async load(): Promise<HqSnapshot | null> {\n try {\n const content = await fs.readFile(this.filePath, 'utf8');\n return JSON.parse(content) as HqSnapshot;\n } catch {\n return null;\n }\n }\n}\n\n// \u2500\u2500 HqTimeseriesStore \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface HqTimeseriesSample {\n /** Bucket start (epoch ms, floored to the bucket width). */\n ts: number;\n /** Total cost (USD) accumulated in this bucket. */\n costUsd: number;\n /** Total input tokens in this bucket. */\n inputTokens: number;\n /** Total output tokens in this bucket. */\n outputTokens: number;\n /** Number of tool executions in this bucket. */\n toolCalls: number;\n /** Snapshot of active agents at bucket close (last-write per bucket). */\n activeAgents?: number;\n}\n\nexport interface HqTimeseriesStoreOptions {\n dataDir: string;\n /** Bucket width in ms. Default 5 minutes. */\n bucketMs?: number;\n /** How many buckets to retain. Default 2016 (1 week of 5-min buckets). */\n maxBuckets?: number;\n}\n\n/**\n * Time-bucketed cost + activity samples for trend charts. Each {@link record}\n * call folds a cost/tool signal into the current bucket; {@link flush} writes\n * the accumulated buckets to `timeseries.jsonl` (append under lock) and prunes\n * to `maxBuckets`.\n *\n * The store keeps an in-memory ring of buckets for cheap reads; {@link load}\n * rehydrates them on boot.\n */\nexport class HqTimeseriesStore {\n private readonly filePath: string;\n private readonly bucketMs: number;\n private readonly maxBuckets: number;\n private readonly buckets = new Map<number, HqTimeseriesSample>();\n private flushChain: Promise<void> = Promise.resolve();\n\n constructor(opts: HqTimeseriesStoreOptions) {\n this.filePath = path.join(opts.dataDir, 'timeseries.jsonl');\n this.bucketMs = opts.bucketMs ?? 5 * 60 * 1000;\n this.maxBuckets = opts.maxBuckets ?? 2016;\n }\n\n private bucketStart(ts: number): number {\n return Math.floor(ts / this.bucketMs) * this.bucketMs;\n }\n\n /** Fold a cost/tool signal into the current bucket. Best-effort. */\n record(signal: {\n ts?: number;\n costUsd?: number;\n inputTokens?: number;\n outputTokens?: number;\n toolCalls?: number;\n activeAgents?: number;\n }): void {\n const start = this.bucketStart(signal.ts ?? Date.now());\n let bucket = this.buckets.get(start);\n if (!bucket) {\n bucket = { ts: start, costUsd: 0, inputTokens: 0, outputTokens: 0, toolCalls: 0 };\n this.buckets.set(start, bucket);\n }\n if (signal.costUsd !== undefined) bucket.costUsd += signal.costUsd;\n if (signal.inputTokens !== undefined) bucket.inputTokens += signal.inputTokens;\n if (signal.outputTokens !== undefined) bucket.outputTokens += signal.outputTokens;\n if (signal.toolCalls !== undefined) bucket.toolCalls += signal.toolCalls;\n if (signal.activeAgents !== undefined) bucket.activeAgents = signal.activeAgents;\n // Prune in-memory buckets beyond retention so a long-lived HQ doesn't\n // accumulate unbounded history. Keep the most-recent maxBuckets.\n if (this.buckets.size > this.maxBuckets) {\n const sorted = Array.from(this.buckets.keys()).sort((a, b) => a - b);\n while (this.buckets.size > this.maxBuckets && sorted.length > 0) {\n const oldest = sorted.shift();\n if (oldest === undefined) break;\n this.buckets.delete(oldest);\n }\n }\n }\n\n /** Persist accumulated buckets to disk (append under lock), prune to maxBuckets. */\n flush(): void {\n const snapshot = Array.from(this.buckets.values()).sort((a, b) => a.ts - b.ts);\n if (snapshot.length === 0) return;\n this.flushChain = this.flushChain\n .then(() => this.flushInternal(snapshot))\n .catch(() => {\n /* best-effort */\n });\n }\n\n /** Resolves once all queued flushes have settled. For tests. */\n async drain(): Promise<void> {\n await this.flushChain.catch(() => {\n /* best-effort */\n });\n }\n\n private async flushInternal(toWrite: HqTimeseriesSample[]): Promise<void> {\n const lines = toWrite.map((b) => JSON.stringify(b)).join('\\n') + '\\n';\n await withFileLock(this.filePath, async () => {\n await fs.appendFile(this.filePath, lines, { encoding: 'utf8' });\n });\n // Prune in-memory buckets beyond retention.\n const sorted = Array.from(this.buckets.keys()).sort((a, b) => a - b);\n while (this.buckets.size > this.maxBuckets) {\n const oldest = sorted.shift();\n if (oldest === undefined) break;\n this.buckets.delete(oldest);\n }\n }\n\n /** Read buckets within `[since, now]`, oldest-first. */\n async read(sinceMs?: number): Promise<HqTimeseriesSample[]> {\n // Prefer in-memory (always most current); supplement from disk on first call.\n if (this.buckets.size === 0) await this.load();\n const since = sinceMs ?? 0;\n return Array.from(this.buckets.values())\n .filter((b) => b.ts >= since)\n .sort((a, b) => a.ts - b.ts);\n }\n\n /** Rehydrate buckets from disk (deduped, latest-per-bucket wins). */\n async load(): Promise<void> {\n let content: string;\n try {\n content = await fs.readFile(this.filePath, 'utf8');\n } catch {\n return;\n }\n for (const line of content.split('\\n')) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n try {\n const sample = JSON.parse(trimmed) as HqTimeseriesSample;\n // Last-write-wins per bucket (file is append-only, so later lines win).\n this.buckets.set(sample.ts, sample);\n } catch {\n /* skip malformed */\n }\n }\n // Prune to retention.\n const sorted = Array.from(this.buckets.keys()).sort((a, b) => a - b);\n while (this.buckets.size > this.maxBuckets) {\n const oldest = sorted.shift();\n if (oldest === undefined) break;\n this.buckets.delete(oldest);\n }\n }\n}\n\n// \u2500\u2500 Aggregate persistence facade \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface HqPersistence {\n eventLog: HqEventLog;\n snapshotStore: HqSnapshotStore;\n timeseries: HqTimeseriesStore;\n}\n\nexport function createHqPersistence(dataDir: string): HqPersistence {\n return {\n eventLog: new HqEventLog({ dataDir }),\n snapshotStore: new HqSnapshotStore({ dataDir }),\n timeseries: new HqTimeseriesStore({ dataDir }),\n };\n}\n", "/**\n * HQ control-plane command definitions \u2014 typed payloads for the commands the\n * HQ dashboard can enqueue to connected machines (Phase 3+ of the HQ command\n * center). These are carried over the existing `HqQueuedCommand` wire shape\n * (`{commandId, type, payload, \u2026}`) whose `type`/`payload` were previously\n * type-erased. This module gives them a discriminated union for type-safe\n * dispatch on the client side (Phase 4).\n *\n * Security model: `run-command` (raw shell) is gated by a per-token\n * `control.execute` capability AND an operator opt-in; the other four commands\n * route through the agent's own decision loop / mailbox and inherit their\n * existing guardrails. See `docs/plans/hq-command-center-2026-07.md`.\n *\n * @module hq/commands\n */\nimport type { HqQueuedCommand } from './protocol.js';\n\n// \u2500\u2500 Command types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** HQ_COMMAND_TYPES \u2014 the full set of recognized command `type` strings. */\nexport const HQ_COMMAND_TYPES = [\n 'steer',\n 'btw',\n 'queue',\n 'abort',\n 'spawn',\n 'broadcast',\n 'run-command',\n] as const;\n\nexport type HqCommandType = (typeof HQ_COMMAND_TYPES)[number];\n\n/** Inject a steer text into a target agent's conversation. */\nexport interface HqSteerCommand {\n type: 'steer';\n /** Target agent address: a unique id (`leader@<tag>`), an alias (`leader`), or `*` for all. */\n to: string;\n subject: string;\n body: string;\n priority?: 'low' | 'normal' | 'high';\n}\n\n/**\n * Post a non-urgent FYI (`btw`) into a target agent's mailbox. Unlike a steer,\n * a btw is absorbed as context \u2014 it does not demand the agent change course.\n * Same wire shape as steer; only the emitted mailbox `type` differs.\n */\nexport interface HqBtwCommand {\n type: 'btw';\n /** Target agent address: a unique id (`leader@<tag>`), an alias (`leader`), or `*` for all. */\n to: string;\n subject: string;\n body: string;\n priority?: 'low' | 'normal' | 'high';\n}\n\n/**\n * Queue a prompt/note (`queue`) for a target agent. Delivered as a plain\n * `note` mailbox message the agent picks up before its next step \u2014 used when\n * the prompt should wait its turn rather than steer the current operation.\n */\nexport interface HqQueueCommand {\n type: 'queue';\n /** Target agent address: a unique id (`leader@<tag>`), an alias (`leader`), or `*` for all. */\n to: string;\n subject: string;\n body: string;\n priority?: 'low' | 'normal' | 'high';\n}\n\n/** Abort a running agent run or fleet. */\nexport interface HqAbortCommand {\n type: 'abort';\n /** `'leader'` aborts the session leader; a subagentId aborts one agent; `'fleet'` stops all. */\n target: 'leader' | 'fleet' | string;\n}\n\n/** Spawn a subagent of the given role. */\nexport interface HqSpawnCommand {\n type: 'spawn';\n role: string;\n /** Optional task description for dispatch routing. */\n task?: string;\n maxIterations?: number;\n}\n\n/** Broadcast a mailbox message to all agents on the target's project. */\nexport interface HqBroadcastCommand {\n type: 'broadcast';\n subject: string;\n body: string;\n priority?: 'low' | 'normal' | 'high';\n}\n\n/** Run a shell command on the target machine. GATED by `control.execute`. */\nexport interface HqRunCommandCommand {\n type: 'run-command';\n command: string;\n /** Optional working directory (defaults to the agent's project root). */\n cwd?: string;\n}\n\nexport type HqCommand =\n | HqSteerCommand\n | HqBtwCommand\n | HqQueueCommand\n | HqAbortCommand\n | HqSpawnCommand\n | HqBroadcastCommand\n | HqRunCommandCommand;\n\n// \u2500\u2500 Validation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst HQ_COMMAND_TYPE_SET = new Set<string>(HQ_COMMAND_TYPES);\n\n/**\n * Validate that an inbound `HqQueuedCommand` has a recognized `type` and a\n * minimally well-formed payload. Returns the narrowed command on success, or\n * `null` when the command should be rejected.\n *\n * This is a shape check, not a security gate \u2014 capability enforcement happens\n * at enqueue time (browser token must have `control.enqueue`) and at execute\n * time (`run-command` requires `control.execute`).\n */\nexport function validateHqCommand(queued: HqQueuedCommand): HqCommand | null {\n if (!HQ_COMMAND_TYPE_SET.has(queued.type)) return null;\n const p = queued.payload as Record<string, unknown>;\n if (p === null || typeof p !== 'object') return null;\n switch (queued.type as HqCommandType) {\n case 'steer': {\n if (typeof p['to'] !== 'string' || typeof p['subject'] !== 'string' || typeof p['body'] !== 'string') {\n return null;\n }\n const result: HqSteerCommand = { type: 'steer', to: p['to'], subject: p['subject'], body: p['body'] };\n if (p['priority'] === 'low' || p['priority'] === 'normal' || p['priority'] === 'high') {\n result.priority = p['priority'];\n }\n return result;\n }\n case 'btw': {\n if (typeof p['to'] !== 'string' || typeof p['subject'] !== 'string' || typeof p['body'] !== 'string') {\n return null;\n }\n const result: HqBtwCommand = { type: 'btw', to: p['to'], subject: p['subject'], body: p['body'] };\n if (p['priority'] === 'low' || p['priority'] === 'normal' || p['priority'] === 'high') {\n result.priority = p['priority'];\n }\n return result;\n }\n case 'queue': {\n if (typeof p['to'] !== 'string' || typeof p['subject'] !== 'string' || typeof p['body'] !== 'string') {\n return null;\n }\n const result: HqQueueCommand = { type: 'queue', to: p['to'], subject: p['subject'], body: p['body'] };\n if (p['priority'] === 'low' || p['priority'] === 'normal' || p['priority'] === 'high') {\n result.priority = p['priority'];\n }\n return result;\n }\n case 'abort':\n if (typeof p['target'] !== 'string') return null;\n return { type: 'abort', target: p['target'] };\n case 'spawn': {\n if (typeof p['role'] !== 'string') return null;\n const result: HqSpawnCommand = { type: 'spawn', role: p['role'] };\n if (typeof p['task'] === 'string') result.task = p['task'];\n if (typeof p['maxIterations'] === 'number') result.maxIterations = p['maxIterations'];\n return result;\n }\n case 'broadcast': {\n if (typeof p['subject'] !== 'string' || typeof p['body'] !== 'string') return null;\n const result: HqBroadcastCommand = { type: 'broadcast', subject: p['subject'], body: p['body'] };\n if (p['priority'] === 'low' || p['priority'] === 'normal' || p['priority'] === 'high') {\n result.priority = p['priority'];\n }\n return result;\n }\n case 'run-command': {\n if (typeof p['command'] !== 'string') return null;\n const result: HqRunCommandCommand = { type: 'run-command', command: p['command'] };\n if (typeof p['cwd'] === 'string') result.cwd = p['cwd'];\n return result;\n }\n default:\n return null;\n }\n}\n\n// \u2500\u2500 Audit log \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface HqCommandAuditEntry {\n commandId: string;\n type: HqCommandType;\n clientId: string;\n /** Who enqueued the command (browser token id, or 'anonymous' in open mode). */\n enqueuedBy: string;\n enqueuedAt: string;\n status: 'queued' | 'delivered' | 'acked';\n /** Ack status when the client has responded. */\n ackStatus?: 'accepted' | 'completed' | 'failed' | 'rejected';\n ackMessage?: string;\n ackedAt?: string;\n}\n\n/**\n * In-memory command audit ring. Capped; the Phase 2 persistence layer can\n * sink entries to disk when wired (future). For now this gives the server a\n * queryable history for `/api/commands` and snapshot enrichment.\n */\nexport class HqCommandAuditLog {\n private readonly entries: HqCommandAuditEntry[] = [];\n private readonly max: number;\n\n constructor(max = 1000) {\n this.max = max;\n }\n\n record(entry: HqCommandAuditEntry): void {\n this.entries.push(entry);\n if (this.entries.length > this.max) {\n this.entries.splice(0, this.entries.length - this.max);\n }\n }\n\n update(commandId: string, patch: Partial<HqCommandAuditEntry>): void {\n const entry = this.entries.find((e) => e.commandId === commandId);\n if (entry) Object.assign(entry, patch);\n }\n\n /** Update only when the command belongs to the authenticated client. */\n updateForClient(\n commandId: string,\n clientId: string,\n patch: Partial<HqCommandAuditEntry>,\n ): boolean {\n const entry = this.entries.find(\n (candidate) => candidate.commandId === commandId && candidate.clientId === clientId,\n );\n if (!entry) return false;\n Object.assign(entry, patch);\n return true;\n }\n\n recent(limit = 200): HqCommandAuditEntry[] {\n return this.entries.slice(-limit);\n }\n}\n", "/**\n * HQ alerting engine \u2014 evaluates the current snapshot against a set of\n * operator-configurable rules and emits `hq.alert` messages when a threshold\n * is crossed. Mirrors the BrainMonitor's self-activation logic (tool-failure\n * streaks, error storms) but at the fleet-wide command-center scope.\n *\n * Rules are evaluated on a periodic tick (default 15s, unref'd) against the\n * latest in-memory snapshot. Deduplication prevents alert storms: a rule that\n * is still firing is not re-emitted until it clears (state machine per rule).\n *\n * @module hq/alerts\n */\nimport type { HqAlertMessage, HqSnapshot } from './protocol.js';\n\n/** Severity levels for alerts, mirroring {@link HqAlertMessage}. */\nexport type HqAlertSeverity = HqAlertMessage['severity'];\n\nexport interface HqAlert {\n id: string;\n ruleId: string;\n severity: HqAlertSeverity;\n message: string;\n /** Epoch ms when the alert first fired in its current episode. */\n firstFiredAt: number;\n /** Epoch ms of the most recent evaluation that confirmed the alert. */\n lastFiredAt: number;\n}\n\nexport interface HqAlertRuleConfig {\n /** Maximum cost (USD) across the whole fleet before alerting. Default 50. */\n costThresholdUsd?: number;\n /** Seconds of silence from ALL machines before a stale alert fires. Default 120. */\n staleMachineSeconds?: number;\n /** Minimum number of active agents before concurrency alert fires. Default: disabled (0). */\n maxAgents?: number;\n}\n\n/** The fully-resolved config passed to rule.evaluate (no optional fields). */\ntype ResolvedAlertConfig = Required<Pick<HqAlertRuleConfig, 'costThresholdUsd' | 'staleMachineSeconds' | 'maxAgents'>>;\n\n/** A rule is a pure function: snapshot + config \u2192 optional firing. */\ninterface HqAlertRule {\n id: string;\n severity: HqAlertSeverity;\n evaluate: (snapshot: HqSnapshot | null, config: ResolvedAlertConfig, now: number) => string | null;\n}\n\nconst DEFAULT_CONFIG: ResolvedAlertConfig = {\n costThresholdUsd: 50,\n staleMachineSeconds: 120,\n maxAgents: 0,\n};\n\nfunction resolveConfig(config?: HqAlertRuleConfig): ResolvedAlertConfig {\n return { ...DEFAULT_CONFIG, ...(config ?? {}) };\n}\n\nconst RULES: readonly HqAlertRule[] = [\n {\n id: 'fleet-cost-threshold',\n severity: 'warn',\n evaluate: (snapshot, config) => {\n if (snapshot === null) return null;\n const cost = snapshot.totals.totalCostUsd ?? 0;\n if (cost >= config.costThresholdUsd) {\n return `Fleet cost $${cost.toFixed(2)} exceeded threshold $${config.costThresholdUsd.toFixed(2)}`;\n }\n return null;\n },\n },\n {\n id: 'all-machines-stale',\n severity: 'warn',\n evaluate: (snapshot, config, now) => {\n if (snapshot === null) return null;\n const machines = snapshot.machines ?? [];\n if (machines.length === 0) return null;\n const cutoff = now - config.staleMachineSeconds * 1000;\n const stale = machines.filter((m) => Date.parse(m.lastActivityAt) < cutoff);\n if (stale.length === machines.length) {\n return `All ${machines.length} machine(s) silent for ${config.staleMachineSeconds}s`;\n }\n return null;\n },\n },\n {\n id: 'high-concurrency',\n severity: 'info',\n evaluate: (snapshot, config) => {\n if (snapshot === null || config.maxAgents <= 0) return null;\n const agents = snapshot.totals.activeAgents ?? 0;\n if (agents >= config.maxAgents) {\n return `High fleet concurrency: ${agents} active agents (limit ${config.maxAgents})`;\n }\n return null;\n },\n },\n {\n id: 'fleet-failure-spike',\n severity: 'warn',\n evaluate: (snapshot) => {\n if (snapshot === null) return null;\n // Aggregate failed tasks across all reported fleets.\n const fleets = snapshot.fleets ?? [];\n const failed = fleets.reduce((sum, f) => sum + f.failedTasks, 0);\n if (failed >= 5) {\n return `${failed} failed task(s) across the fleet`;\n }\n return null;\n },\n },\n];\n\n/**\n * In-memory alert state. Tracks which rules are currently firing so the same\n * alert is not re-emitted every tick \u2014 only state transitions (cleared \u2192\n * firing) emit. Optionally persists to disk via a callback.\n */\nexport class HqAlertEngine {\n private readonly active = new Map<string, HqAlert>();\n private readonly history: HqAlert[] = [];\n private readonly maxHistory: number;\n private timer: ReturnType<typeof setInterval> | null = null;\n private readonly onAlert: (alert: HqAlert) => void;\n\n constructor(opts: { onAlert: (alert: HqAlert) => void; maxHistory?: number }) {\n this.onAlert = opts.onAlert;\n this.maxHistory = opts.maxHistory ?? 500;\n }\n\n /**\n * Evaluate all rules against the snapshot. Emits (via the `onAlert`\n * callback) only for rules that newly transition to firing. Clears rules\n * that are no longer firing. Returns the list of newly-fired alerts.\n */\n evaluate(snapshot: HqSnapshot | null, config?: HqAlertRuleConfig, now: number = Date.now()): HqAlert[] {\n const resolved = resolveConfig(config);\n const fired: HqAlert[] = [];\n const firingIds = new Set<string>();\n\n for (const rule of RULES) {\n const message = rule.evaluate(snapshot, resolved, now);\n if (message !== null) {\n firingIds.add(rule.id);\n const existing = this.active.get(rule.id);\n if (existing === undefined) {\n // New transition \u2192 emit.\n const alert: HqAlert = {\n id: `${rule.id}-${now}`,\n ruleId: rule.id,\n severity: rule.severity,\n message,\n firstFiredAt: now,\n lastFiredAt: now,\n };\n this.active.set(rule.id, alert);\n this.history.push(alert);\n if (this.history.length > this.maxHistory) this.history.splice(0, this.history.length - this.maxHistory);\n fired.push(alert);\n this.onAlert(alert);\n } else {\n // Already firing \u2014 refresh timestamp, don't re-emit.\n existing.lastFiredAt = now;\n }\n }\n }\n\n // Clear rules no longer firing.\n for (const id of Array.from(this.active.keys())) {\n if (!firingIds.has(id)) {\n this.active.delete(id);\n }\n }\n\n return fired;\n }\n\n /** Currently-active (firing) alerts. */\n activeAlerts(): HqAlert[] {\n return Array.from(this.active.values());\n }\n\n /** Historical alerts (newest-last), capped at maxHistory. */\n recentAlerts(limit = 100): HqAlert[] {\n return this.history.slice(-limit);\n }\n\n /**\n * Start periodic evaluation against a snapshot getter. The timer is\n * unref'd so it never keeps the process alive. Returns a disposer.\n */\n startPeriodic(\n getSnapshot: () => HqSnapshot | null,\n config?: HqAlertRuleConfig | (() => HqAlertRuleConfig | undefined),\n intervalMs = 15_000,\n ): () => void {\n if (this.timer !== null) return () => undefined;\n const tick = (): void => {\n try {\n const cfg = typeof config === 'function' ? config() : config;\n this.evaluate(getSnapshot(), cfg);\n } catch {\n /* best-effort \u2014 alert evaluation must never crash the server */\n }\n };\n this.timer = setInterval(tick, intervalMs);\n this.timer.unref?.();\n return () => {\n if (this.timer !== null) {\n clearInterval(this.timer);\n this.timer = null;\n }\n };\n }\n}\n\n/** Map an internal {@link HqAlert} to the wire {@link HqAlertMessage}. */\nexport function toAlertMessage(alert: HqAlert): HqAlertMessage {\n return {\n type: 'hq.alert',\n severity: alert.severity,\n message: `[${alert.ruleId}] ${alert.message}`,\n timestamp: new Date(alert.lastFiredAt).toISOString(),\n };\n}\n"],
|
|
5
|
+
"mappings": ";AAAO,IAAM,sBAAsB;AA2B5B,IAAM,8BAAiD;AAAA,EAC5D,YAAY;AAAA,EACZ,UAAU;AAAA,EACV,OAAO;AACT;AAUO,IAAM,yBAAyB;AAitBtC,IAAM,8BAA8B,oBAAI,IAA6B;AAAA,EACnE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,IAAM,kBAAkB,oBAAI,IAAkB,CAAC,OAAO,QAAQ,SAAS,OAAO,SAAS,CAAC;AACxF,IAAM,qBAAqB,oBAAI,IAAqB,CAAC,OAAO,aAAa,SAAS,CAAC;AACnF,IAAM,yBAAyB,oBAAI,IAAwB;AAAA,EACzD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AACD,IAAM,0BAA0B,oBAAI,IAAyC;AAAA,EAC3E;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAGD,SAAS,cAAc,GAAmC;AACxD,SAAO,OAAO,MAAM,YAAY,MAAM,QAAQ,OAAQ,EAAyB,SAAS;AAC1F;AAEA,SAAS,mBAAmB,GAAmC;AAC7D,MAAI,OAAO,MAAM,YAAY,MAAM,KAAM,QAAO;AAChD,QAAM,IAAI;AACV,SACE,OAAO,EAAE,aAAa,YACtB,OAAO,EAAE,SAAS,YAClB,gBAAgB,IAAI,EAAE,IAAoB,KAC1C,OAAO,EAAE,cAAc,YACvB,OAAO,EAAE,cAAc;AAE3B;AAEA,SAAS,oBAAoB,GAAoC;AAC/D,MAAI,OAAO,MAAM,YAAY,MAAM,KAAM,QAAO;AAChD,QAAM,IAAI;AACV,SACE,OAAO,EAAE,cAAc,YACvB,OAAO,EAAE,gBAAgB,YACzB,OAAO,EAAE,gBAAgB,YACzB,OAAO,EAAE,cAAc,YACvB,OAAO,EAAE,kBAAkB,YAC3B,mBAAmB,IAAI,EAAE,aAAgC;AAE7D;AAEA,SAAS,oBAAoB,GAAoC;AAC/D,MAAI,OAAO,MAAM,YAAY,MAAM,KAAM,QAAO;AAChD,QAAM,IAAI;AACV,SACE,OAAO,EAAE,eAAe,cACvB,EAAE,aAAa,UAAU,EAAE,aAAa,aAAa,EAAE,aAAa,cAAc,EAAE,aAAa,YACjG,EAAE,UAAU,UACX,EAAE,UAAU,sBACZ,EAAE,UAAU,cACZ,EAAE,UAAU;AAElB;AAEA,SAAS,uBAAuB,GAAuC;AACrE,MAAI,OAAO,MAAM,YAAY,MAAM,KAAM,QAAO;AAChD,QAAM,IAAI;AACV,SACE,OAAO,EAAE,oBAAoB,YAC7B,mBAAmB,EAAE,MAAM,KAC3B,oBAAoB,EAAE,OAAO,KAC7B,MAAM,QAAQ,EAAE,YAAY,KAC5B,EAAE,aAAa;AAAA,IACb,CAAC,eACC,OAAO,eAAe,YACtB,uBAAuB,IAAI,UAAgC;AAAA,EAC/D,MACC,EAAE,oBAAoB,UAAa,oBAAoB,EAAE,eAAe;AAE7E;AAEA,SAAS,kBAAkB,GAAkC;AAC3D,MAAI,OAAO,MAAM,YAAY,MAAM,KAAM,QAAO;AAChD,QAAM,IAAI;AACV,SACE,OAAO,EAAE,OAAO,YAChB,OAAO,EAAE,SAAS,YAClB,EAAE,kBAAkB,uBACpB,OAAO,EAAE,cAAc,YACvB,OAAO,EAAE,aAAa,YACtB,OAAO,EAAE,cAAc,YACvB,OAAO,cAAc,EAAE,GAAG,KACzB,EAAE,OAAkB,KACrB,OAAO,OAAO,GAAG,SAAS;AAE9B;AAEA,SAAS,6BAA6B,GAA6C;AACjF,MAAI,OAAO,MAAM,YAAY,MAAM,KAAM,QAAO;AAChD,QAAM,IAAI;AACV,SACE,OAAO,EAAE,aAAa,YACtB,OAAO,EAAE,cAAc,aACtB,EAAE,mBAAmB,UAAa,OAAO,EAAE,mBAAmB,cAC9D,EAAE,UAAU,UACV,OAAO,cAAc,EAAE,KAAK,KAAM,EAAE,QAAmB,KAAM,EAAE,SAAoB;AAE1F;AAEA,SAAS,4BAA4B,GAA4C;AAC/E,MAAI,OAAO,MAAM,YAAY,MAAM,KAAM,QAAO;AAChD,QAAM,IAAI;AACV,SACE,OAAO,EAAE,aAAa,YACtB,OAAO,EAAE,cAAc,YACvB,OAAO,EAAE,cAAc,YACvB,OAAO,EAAE,WAAW,YACpB,wBAAwB,IAAI,EAAE,MAA6C,MAC1E,EAAE,YAAY,UAAa,OAAO,EAAE,YAAY;AAErD;AAeO,SAAS,aAAa,KAAqC;AAChE,MAAI;AACJ,MAAI;AACF,aAAS,KAAK,MAAM,OAAO,QAAQ,WAAW,MAAM,IAAI,SAAS,MAAM,CAAC;AAAA,EAC1E,QAAQ;AACN,WAAO,EAAE,IAAI,OAAO,QAAQ,eAAe;AAAA,EAC7C;AAEA,MAAI,CAAC,cAAc,MAAM,GAAG;AAC1B,WAAO,EAAE,IAAI,OAAO,QAAQ,YAAY;AAAA,EAC1C;AACA,QAAM,MAAM;AAEZ,MAAI,CAAC,4BAA4B,IAAI,IAAI,IAA+B,GAAG;AACzE,WAAO,EAAE,IAAI,OAAO,QAAQ,eAAe;AAAA,EAC7C;AAEA,UAAQ,IAAI,MAAiC;AAAA,IAC3C,KAAK;AACH,UAAI,CAAC,uBAAuB,IAAI,OAAO,GAAG;AACxC,eAAO,EAAE,IAAI,OAAO,QAAQ,YAAY;AAAA,MAC1C;AACA,aAAO,EAAE,IAAI,MAAM,OAAO,EAAE,MAAM,gBAAgB,SAAS,IAAI,QAAQ,EAAE;AAAA,IAC3E,KAAK;AACH,UAAI,CAAC,kBAAkB,IAAI,KAAK,GAAG;AACjC,eAAO,EAAE,IAAI,OAAO,QAAQ,YAAY;AAAA,MAC1C;AACA,aAAO,EAAE,IAAI,MAAM,OAAO,EAAE,MAAM,gBAAgB,OAAO,IAAI,MAAM,EAAE;AAAA,IACvE,KAAK;AACH,UAAI,CAAC,6BAA6B,GAAG,GAAG;AACtC,eAAO,EAAE,IAAI,OAAO,QAAQ,YAAY;AAAA,MAC1C;AACA,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,OAAO;AAAA,UACL,MAAM;AAAA,UACN,UAAU,IAAI;AAAA,UACd,WAAW,IAAI;AAAA,UACf,GAAI,OAAO,IAAI,mBAAmB,WAC9B,EAAE,gBAAgB,IAAI,eAAe,IACrC,CAAC;AAAA,UACL,GAAI,OAAO,IAAI,UAAU,WAAW,EAAE,OAAO,IAAI,MAAM,IAAI,CAAC;AAAA,QAC9D;AAAA,MACF;AAAA,IACF,KAAK;AACH,UAAI,CAAC,4BAA4B,GAAG,GAAG;AACrC,eAAO,EAAE,IAAI,OAAO,QAAQ,YAAY;AAAA,MAC1C;AACA,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,OAAO;AAAA,UACL,MAAM;AAAA,UACN,UAAU,IAAI;AAAA,UACd,WAAW,IAAI;AAAA,UACf,WAAW,IAAI;AAAA,UACf,QAAQ,IAAI;AAAA,UACZ,GAAI,OAAO,IAAI,YAAY,WAAW,EAAE,SAAS,IAAI,QAAQ,IAAI,CAAC;AAAA,QACpE;AAAA,MACF;AAAA,IACF,SAAS;AAKP,YAAM,cAAqB,IAAI;AAC/B,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAGA,IAAM,+BAA+B,oBAAI,IAAY;AAAA,EACnD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,SAAS,sBAAsB,GAAsC;AACnE,MAAI,OAAO,MAAM,YAAY,MAAM,KAAM,QAAO;AAChD,QAAM,IAAI;AACV,SACE,OAAO,EAAE,UAAU,aAClB,EAAE,WAAW,UAAa,OAAO,EAAE,WAAW,cAC9C,EAAE,UAAU,UAAa,OAAO,EAAE,UAAU,cAC5C,EAAE,UAAU,UAAa,OAAO,EAAE,UAAU,cAC5C,EAAE,UAAU,UAAa,OAAO,EAAE,UAAU,cAC5C,EAAE,UAAU,UAAa,OAAO,EAAE,UAAU;AAEjD;AAEA,SAAS,qBAAqB,GAAqC;AACjE,MAAI,OAAO,MAAM,YAAY,MAAM,KAAM,QAAO;AAChD,QAAM,IAAI;AACV,SACE,OAAO,EAAE,cAAc,YACvB,OAAO,EAAE,aAAa,YACtB,OAAO,EAAE,SAAS;AAEtB;AAEA,SAAS,mBAAmB,GAAmC;AAC7D,MAAI,OAAO,MAAM,YAAY,MAAM,KAAM,QAAO;AAChD,QAAM,IAAI;AACV,SACE,OAAO,EAAE,SAAS,YAClB,OAAO,EAAE,WAAW,cACnB,EAAE,UAAU,UAAa,OAAO,EAAE,UAAU,cAC5C,EAAE,cAAc,UAAa,OAAO,EAAE,cAAc;AAEzD;AAEA,IAAM,uBAAuB,oBAAI,IAAY;AAAA,EAC3C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,IAAM,2BAA2B,oBAAI,IAAY;AAAA,EAC/C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,SAAS,oBAAoB,GAAoC;AAC/D,MAAI,OAAO,MAAM,YAAY,MAAM,KAAM,QAAO;AAChD,QAAM,IAAI;AACV,SACE,OAAO,EAAE,SAAS,YAClB,OAAO,EAAE,cAAc,YACvB,OAAO,EAAE,aAAa,YACtB,OAAO,EAAE,oBAAoB,YAC7B,yBAAyB,IAAI,EAAE,eAAe,KAC9C,OAAO,EAAE,gBAAgB,YACzB,qBAAqB,IAAI,EAAE,WAAW,MACrC,EAAE,kBAAkB,UAAa,OAAO,EAAE,kBAAkB,cAC5D,EAAE,kBAAkB,UAAa,OAAO,EAAE,kBAAkB,cAC5D,EAAE,oBAAoB,UACrB,EAAE,oBAAoB,eACtB,EAAE,oBAAoB,cACtB,EAAE,oBAAoB,WACxB,OAAO,EAAE,wBAAwB,YACjC,qBAAqB,EAAE,QAAQ,KAC/B,OAAO,EAAE,mBAAmB,YAC5B,OAAO,EAAE,cAAc,YACvB,OAAO,EAAE,eAAe,YACxB,OAAO,EAAE,iBAAiB,YAC1B,sBAAsB,EAAE,iBAAiB,KACzC,sBAAsB,EAAE,gBAAgB,KACxC,sBAAsB,EAAE,WAAW,KACnC,OAAO,EAAE,kBAAkB,YAC3B,OAAO,EAAE,sBAAsB,YAC/B,MAAM,QAAQ,EAAE,YAAY,KAC5B,EAAE,aAAa,MAAM,kBAAkB;AAE3C;AAEA,SAAS,6BAA6B,GAA6C;AACjF,MAAI,OAAO,MAAM,YAAY,MAAM,KAAM,QAAO;AAChD,QAAM,IAAI;AACV,SAAO,MAAM,QAAQ,EAAE,OAAO,KAAK,EAAE,QAAQ,MAAM,mBAAmB;AACxE;AAEA,SAAS,wBAAwB,GAAwC;AACvE,MAAI,OAAO,MAAM,YAAY,MAAM,KAAM,QAAO;AAChD,QAAM,IAAI;AACV,SACE,OAAO,EAAE,cAAc,YACvB,EAAE,cAAc,QAChB,MAAM,QAAQ,EAAE,OAAO,KACvB,EAAE,QAAQ,MAAM,mBAAmB;AAEvC;AAEA,SAAS,0BAA0B,GAA0C;AAC3E,MAAI,OAAO,MAAM,YAAY,MAAM,KAAM,QAAO;AAChD,QAAM,IAAI;AACV,SACE,OAAO,EAAE,cAAc,YACvB,OAAO,EAAE,SAAS,YAClB,OAAO,EAAE,OAAO,YAChB,OAAO,EAAE,YAAY,YACrB,OAAO,EAAE,aAAa,YACtB,OAAO,EAAE,cAAc,YACvB,OAAO,EAAE,cAAc,aACvB,OAAO,EAAE,YAAY;AAEzB;AAEA,SAAS,wBAAwB,GAAwC;AACvE,MAAI,OAAO,MAAM,YAAY,MAAM,KAAM,QAAO;AAChD,QAAM,IAAI;AACV,SACE,OAAO,EAAE,YAAY,YACrB,OAAO,EAAE,SAAS,YAClB,OAAO,EAAE,cAAc,YACvB,OAAO,EAAE,WAAW,YACpB,OAAO,EAAE,eAAe,YACxB,OAAO,EAAE,cAAc,YACvB,OAAO,EAAE,mBAAmB,YAC5B,OAAO,EAAE,eAAe,YACxB,OAAO,EAAE,WAAW;AAExB;AAEA,SAAS,2BAA2B,GAA2C;AAC7E,MAAI,OAAO,MAAM,YAAY,MAAM,KAAM,QAAO;AAChD,QAAM,IAAI;AACV,MACE,OAAO,EAAE,cAAc,YACtB,EAAE,UAAU,aAAa,EAAE,UAAU,YACtC,CAAC,MAAM,QAAQ,EAAE,QAAQ,KACzB,CAAC,MAAM,QAAQ,EAAE,MAAM,KACvB,OAAO,EAAE,WAAW,YACpB,EAAE,WAAW,MACb;AACA,WAAO;AAAA,EACT;AACA,QAAM,SAAS,EAAE;AACjB,MACE,OAAO,OAAO,aAAa,YAC3B,OAAO,OAAO,WAAW,YACzB,OAAO,OAAO,eAAe,YAC7B,OAAO,OAAO,iBAAiB,YAC/B,OAAO,OAAO,iBAAiB,UAC/B;AACA,WAAO;AAAA,EACT;AACA,aAAW,WAAW,EAAE,UAAU;AAChC,QAAI,CAAC,0BAA0B,OAAO,EAAG,QAAO;AAAA,EAClD;AACA,aAAW,SAAS,EAAE,QAAQ;AAC5B,QAAI,CAAC,wBAAwB,KAAK,EAAG,QAAO;AAAA,EAC9C;AACA,SAAO;AACT;AAEA,IAAM,2BAA2B,oBAAI,IAAY;AAAA,EAC/C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,SAAS,wBAAwB,GAAwC;AACvE,MAAI,OAAO,MAAM,YAAY,MAAM,KAAM,QAAO;AAChD,QAAM,IAAI;AACV,MAAI,OAAO,EAAE,cAAc,SAAU,QAAO;AAC5C,MAAI,OAAO,EAAE,WAAW,YAAY,CAAC,yBAAyB,IAAI,EAAE,MAAM,EAAG,QAAO;AAIpF,MAAI,EAAE,YAAY,UAAa,CAAC,0BAA0B,EAAE,OAAO,EAAG,QAAO;AAC7E,MAAI,EAAE,UAAU,UAAa,CAAC,wBAAwB,EAAE,KAAK,EAAG,QAAO;AACvE,SAAO;AACT;AAEA,IAAM,4BAA4B,oBAAI,IAAY;AAAA,EAChD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,SAAS,wBAAwB,GAAwC;AACvE,MAAI,OAAO,MAAM,YAAY,MAAM,KAAM,QAAO;AAChD,QAAM,IAAI;AACV,SACE,OAAO,EAAE,OAAO,YAChB,OAAO,EAAE,SAAS,YAClB,OAAO,EAAE,WAAW,YACpB,0BAA0B,IAAI,EAAE,MAAM,KACtC,OAAO,EAAE,eAAe,YACxB,OAAO,EAAE,cAAc,YACvB,OAAO,EAAE,mBAAmB;AAEhC;AAEA,IAAM,sBAAsB,oBAAI,IAAY,CAAC,UAAU,QAAQ,WAAW,OAAO,CAAC;AAElF,SAAS,2BAA2B,GAA2C;AAC7E,MAAI,OAAO,MAAM,YAAY,MAAM,KAAM,QAAO;AAChD,QAAM,IAAI;AACV,MACE,OAAO,EAAE,cAAc,YACvB,OAAO,EAAE,eAAe,YACxB,OAAO,EAAE,cAAc,YACvB,OAAO,EAAE,cAAc,YACvB,OAAO,EAAE,gBAAgB,YACzB,OAAO,EAAE,gBAAgB,YACzB,OAAO,EAAE,WAAW,YACpB,CAAC,oBAAoB,IAAI,EAAE,MAAM,KACjC,OAAO,EAAE,cAAc,YACvB,OAAO,EAAE,mBAAmB,YAC5B,OAAO,EAAE,eAAe,YACxB,CAAC,MAAM,QAAQ,EAAE,MAAM,GACvB;AACA,WAAO;AAAA,EACT;AACA,aAAW,SAAS,EAAE,QAAQ;AAC5B,QAAI,CAAC,wBAAwB,KAAK,EAAG,QAAO;AAAA,EAC9C;AACA,SAAO;AACT;AAEA,IAAM,sBAAsB,oBAAI,IAAY;AAAA,EAC1C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,SAAS,oBAAoB,GAAoC;AAC/D,MAAI,OAAO,MAAM,YAAY,MAAM,KAAM,QAAO;AAChD,QAAM,IAAI;AACV,SACE,OAAO,EAAE,OAAO,YAChB,OAAO,EAAE,SAAS,YAClB,oBAAoB,IAAI,EAAE,IAAI,KAC9B,OAAO,EAAE,SAAS;AAEtB;AAEA,SAAS,4BAA4B,GAA4C;AAC/E,MAAI,OAAO,MAAM,YAAY,MAAM,KAAM,QAAO;AAChD,QAAM,IAAI;AACV,MACE,OAAO,EAAE,cAAc,YACvB,OAAO,EAAE,YAAY,YACrB,CAAC,MAAM,QAAQ,EAAE,OAAO,GACxB;AACA,WAAO;AAAA,EACT;AACA,aAAW,SAAS,EAAE,SAAS;AAC7B,QAAI,CAAC,oBAAoB,KAAK,EAAG,QAAO;AAAA,EAC1C;AACA,SAAO;AACT;AAEA,SAAS,wBAAwB,GAAwC;AACvE,MAAI,OAAO,MAAM,YAAY,MAAM,KAAM,QAAO;AAChD,QAAM,IAAI;AACV,SAAO,OAAO,EAAE,cAAc,YAAY,OAAO,EAAE,YAAY;AACjE;AAEA,IAAM,2BAA2B,oBAAI,IAAY;AAAA,EAC/C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,SAAS,oBAAoB,GAAoC;AAC/D,MAAI,OAAO,MAAM,YAAY,MAAM,KAAM,QAAO;AAChD,QAAM,IAAI;AACV,SACE,OAAO,EAAE,eAAe,YACxB,OAAO,EAAE,WAAW,YACpB,yBAAyB,IAAI,EAAE,MAAM;AAEzC;AAEA,SAAS,yBAAyB,GAAyC;AACzE,MAAI,OAAO,MAAM,YAAY,MAAM,KAAM,QAAO;AAChD,QAAM,IAAI;AACV,MACE,OAAO,EAAE,UAAU,YACnB,OAAO,EAAE,oBAAoB,YAC7B,OAAO,EAAE,gBAAgB,YACzB,OAAO,EAAE,mBAAmB,YAC5B,OAAO,EAAE,gBAAgB,YACzB,CAAC,MAAM,QAAQ,EAAE,SAAS,GAC1B;AACA,WAAO;AAAA,EACT;AACA,aAAW,KAAK,EAAE,WAAW;AAC3B,QAAI,CAAC,oBAAoB,CAAC,EAAG,QAAO;AAAA,EACtC;AACA,SAAO;AACT;AAEA,SAAS,sBAAsB,GAAsC;AACnE,MAAI,OAAO,MAAM,YAAY,MAAM,KAAM,QAAO;AAChD,QAAM,IAAI;AACV,SAAO,OAAO,EAAE,UAAU,YAAY,OAAO,EAAE,UAAU;AAC3D;AAEA,IAAM,uBAAuB,oBAAI,IAAY;AAAA,EAC3C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,SAAS,sBAAsB,GAAsC;AACnE,MAAI,OAAO,MAAM,YAAY,MAAM,KAAM,QAAO;AAChD,QAAM,IAAI;AACV,MAAI,OAAO,EAAE,SAAS,YAAY,CAAC,qBAAqB,IAAI,EAAE,IAAI,EAAG,QAAO;AAC5E,MAAI,OAAO,EAAE,OAAO,SAAU,QAAO;AACrC,SAAO;AACT;AAEA,IAAM,0BAA0B,oBAAI,IAAY;AAAA,EAC9C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,SAAS,yBAAyB,GAAyC;AACzE,MAAI,OAAO,MAAM,YAAY,MAAM,KAAM,QAAO;AAChD,QAAM,IAAI;AACV,MAAI,OAAO,EAAE,SAAS,YAAY,CAAC,wBAAwB,IAAI,EAAE,IAAI,EAAG,QAAO;AAC/E,MAAI,OAAO,EAAE,aAAa,YAAY,OAAO,EAAE,YAAY,SAAU,QAAO;AAC5E,SAAO;AACT;AAEA,SAAS,uBAAuB,GAAuC;AACrE,MAAI,OAAO,MAAM,YAAY,MAAM,KAAM,QAAO;AAChD,QAAM,IAAI;AACV,SAAO,OAAO,EAAE,aAAa;AAC/B;AAEA,SAAS,yBAAyB,GAAyC;AACzE,MAAI,OAAO,MAAM,YAAY,MAAM,KAAM,QAAO;AAChD,QAAM,IAAI;AACV,SACE,OAAO,EAAE,aAAa,YACtB,OAAO,EAAE,WAAW,YACpB,OAAO,EAAE,eAAe;AAE5B;AAEA,SAAS,iBAAiB,GAAiC;AACzD,MAAI,OAAO,MAAM,YAAY,MAAM,KAAM,QAAO;AAIhD,SAAO,CAAC,MAAM,QAAQ,CAAC;AACzB;AAEA,SAAS,2BAA2B,GAA2C;AAC7E,MAAI,OAAO,MAAM,YAAY,MAAM,QAAQ,MAAM,QAAQ,CAAC,EAAG,QAAO;AACpE,QAAM,IAAI;AACV,SACE,OAAO,EAAE,aAAa,aACrB,EAAE,oBAAoB,UAAa,OAAO,EAAE,oBAAoB,cAChE,EAAE,gBAAgB,UAAa,OAAO,EAAE,gBAAgB,aACzD,OAAO,EAAE,WAAW,aACnB,EAAE,WAAW,YACZ,EAAE,WAAW,UACb,EAAE,WAAW,WACb,EAAE,WAAW,aACd,EAAE,oBAAoB,UAAa,OAAO,EAAE,oBAAoB,cAChE,EAAE,gBAAgB,UAAa,OAAO,EAAE,gBAAgB;AAE7D;AAkBO,SAAS,oBACd,WACA,SAC+B;AAC/B,MAAI,CAAC,6BAA6B,IAAI,SAAS,GAAG;AAIhD,WAAO,EAAE,IAAI,MAAM,QAAQ;AAAA,EAC7B;AACA,UAAQ,WAAW;AAAA,IACjB,KAAK;AACH,aAAO,2BAA2B,OAAO,IACrC,EAAE,IAAI,MAAM,QAAQ,IACpB,EAAE,IAAI,OAAO,QAAQ,oBAAoB;AAAA,IAC/C,KAAK;AACH,aAAO,wBAAwB,OAAO,IAClC,EAAE,IAAI,MAAM,QAAQ,IACpB,EAAE,IAAI,OAAO,QAAQ,oBAAoB;AAAA,IAC/C,KAAK;AACH,aAAO,2BAA2B,OAAO,IACrC,EAAE,IAAI,MAAM,QAAQ,IACpB,EAAE,IAAI,OAAO,QAAQ,oBAAoB;AAAA,IAC/C,KAAK;AACH,aAAO,4BAA4B,OAAO,IACtC,EAAE,IAAI,MAAM,QAAQ,IACpB,EAAE,IAAI,OAAO,QAAQ,oBAAoB;AAAA,IAC/C,KAAK;AACH,aAAO,wBAAwB,OAAO,IAClC,EAAE,IAAI,MAAM,QAAQ,IACpB,EAAE,IAAI,OAAO,QAAQ,oBAAoB;AAAA,IAC/C,KAAK;AACH,aAAO,yBAAyB,OAAO,IACnC,EAAE,IAAI,MAAM,QAAQ,IACpB,EAAE,IAAI,OAAO,QAAQ,oBAAoB;AAAA,IAC/C,KAAK;AACH,aAAO,sBAAsB,OAAO,IAChC,EAAE,IAAI,MAAM,QAAQ,IACpB,EAAE,IAAI,OAAO,QAAQ,oBAAoB;AAAA,IAC/C,KAAK;AACH,aAAO,sBAAsB,OAAO,IAChC,EAAE,IAAI,MAAM,QAAQ,IACpB,EAAE,IAAI,OAAO,QAAQ,oBAAoB;AAAA,IAC/C,KAAK;AACH,aAAO,yBAAyB,OAAO,IACnC,EAAE,IAAI,MAAM,QAAQ,IACpB,EAAE,IAAI,OAAO,QAAQ,oBAAoB;AAAA,IAC/C,KAAK;AACH,aAAO,uBAAuB,OAAO,IACjC,EAAE,IAAI,MAAM,QAAQ,IACpB,EAAE,IAAI,OAAO,QAAQ,oBAAoB;AAAA,IAC/C,KAAK;AACH,aAAO,yBAAyB,OAAO,IACnC,EAAE,IAAI,MAAM,QAAQ,IACpB,EAAE,IAAI,OAAO,QAAQ,oBAAoB;AAAA,IAC/C,KAAK;AACH,aAAO,iBAAiB,OAAO,IAC3B,EAAE,IAAI,MAAM,QAAQ,IACpB,EAAE,IAAI,OAAO,QAAQ,oBAAoB;AAAA,IAC/C,KAAK;AACH,aAAO,2BAA2B,OAAO,IACrC,EAAE,IAAI,MAAM,QAAQ,IACpB,EAAE,IAAI,OAAO,QAAQ,oBAAoB;AAAA,IAC/C,KAAK;AACH,aAAO,6BAA6B,OAAO,IACvC,EAAE,IAAI,MAAM,QAAQ,IACpB,EAAE,IAAI,OAAO,QAAQ,oBAAoB;AAAA,IAC/C,KAAK;AACH,aAAO,wBAAwB,OAAO,IAClC,EAAE,IAAI,MAAM,QAAQ,IACpB,EAAE,IAAI,OAAO,QAAQ,oBAAoB;AAAA,IAC/C,SAAS;AACP,YAAM,cAAqB;AAC3B,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAEO,SAAS,sBAAgC,OAUlB;AAC5B,SAAO;AAAA,IACL,IAAI,MAAM;AAAA,IACV,MAAM,MAAM;AAAA,IACZ,eAAe;AAAA,IACf,WAAW,MAAM;AAAA,IACjB,UAAU,MAAM;AAAA,IAChB,WAAW,MAAM;AAAA,IACjB,KAAK,MAAM;AAAA,IACX,SAAS,MAAM;AAAA,IACf,GAAI,MAAM,cAAc,SAAY,EAAE,WAAW,MAAM,UAAU,IAAI,CAAC;AAAA,IACtE,GAAI,MAAM,UAAU,SAAY,EAAE,OAAO,MAAM,MAAM,IAAI,CAAC;AAAA,EAC5D;AACF;;;AC19CA,IAAM,WAAsB;AAAA;AAAA;AAAA,EAG1B;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,EACT;AAAA,EACA,EAAE,MAAM,cAAc,OAAO,kEAAkE;AAAA,EAC/F,EAAE,MAAM,cAAc,OAAO,uDAAuD;AAAA,EACpF,EAAE,MAAM,iBAAiB,OAAO,+DAA+D;AAAA,EAC/F,EAAE,MAAM,kBAAkB,OAAO,mDAAmD;AAAA,EACpF,EAAE,MAAM,WAAW,OAAO,wDAAwD;AAAA,EAClF,EAAE,MAAM,eAAe,OAAO,iEAAiE;AAAA,EAC/F;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IAAc,OAAO;AAAA,EAC7B;AAAA,EACA;AAAA,IACE,MAAM;AAAA;AAAA,IAEN,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,MAAM;AAAA;AAAA,IAEN,OACE;AAAA,EACJ;AAAA,EACA;AAAA,IACE,MAAM;AAAA;AAAA,IAEN,OACE;AAAA,EACJ;AAAA,EACA,EAAE,MAAM,eAAe,OAAO,mCAAmC;AAAA,EACjE,EAAE,MAAM,gBAAgB,OAAO,iCAAiC;AAAA,EAChE,EAAE,MAAM,aAAa,OAAO,uBAAuB;AAAA,EACnD,EAAE,MAAM,aAAa,OAAO,uBAAuB;AAAA;AAAA,EAEnD;AAAA,IACE,MAAM;AAAA;AAAA,IAEN,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,MAAM;AAAA;AAAA,IAEN,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,MAAM;AAAA;AAAA,IAEN,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,MAAM;AAAA;AAAA,IAEN,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAUN,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAaN,OAAO;AAAA,EACT;AACF;AAQA,IAAM,kBAAkB,SAAS,OAAO,CAAC,MAAM,EAAE,SAAS,kBAAkB;AAS5E,IAAM,iBAAiB,IAAI,OAAO,gBAAgB,IAAI,CAAC,MAAM,IAAI,EAAE,MAAM,MAAM,GAAG,EAAE,KAAK,GAAG,GAAG,GAAG;AAGlG,IAAM,qBAAqB,SAAS,KAAK,CAAC,MAAM,EAAE,SAAS,kBAAkB,EAAG;AAMhF,IAAM,wBAAwB,gBAAgB,IAAI,CAAC,MAAM,aAAa,EAAE,IAAI,GAAG;AAO/E,IAAM,oBAAoB,KAAK;AAe/B,IAAM,sBAAsB;AAY5B,SAAS,qBAAqB,MAAuB;AACnD,SACE,KAAK,SAAS,YAAY;AAAA,EAC1B,KAAK,SAAS,KAAK;AAAA,EACnB,KAAK,SAAS,KAAK;AAAA,EACnB,KAAK,SAAS,MAAM;AAAA,EACpB,KAAK,SAAS,aAAa;AAAA,EAC3B,KAAK,SAAS,KAAK;AAAA,EACnB,KAAK,SAAS,MAAM;AAAA,EACpB,KAAK,SAAS,MAAM;AAAA,EACpB,KAAK,SAAS,KAAK;AAAA,EACnB,KAAK,SAAS,SAAS;AAAA,EACvB,KAAK,SAAS,MAAM;AAAA,EACpB,KAAK,SAAS,KAAK;AAAA,EACnB,KAAK,SAAS,KAAK;AAAA,EACnB,KAAK,SAAS,OAAO;AAAA,EACrB,KAAK,SAAS,MAAM;AAAA,EACpB,KAAK,SAAS,OAAO;AAAA,EACrB,KAAK,SAAS,SAAS;AAAA,EACvB,KAAK,SAAS,UAAU;AAAA,EACxB,KAAK,SAAS,YAAY;AAAA,EAC1B,KAAK,SAAS,YAAY,KAC1B,KAAK,SAAS,gBAAgB,KAC9B,KAAK,SAAS,aAAa,KAC3B,KAAK,SAAS,eAAe,KAC7B,KAAK,SAAS,UAAU,KACxB,KAAK,SAAS,UAAU;AAE5B;AAEO,IAAM,wBAAN,MAAsD;AAAA,EAC3D,MAAM,MAAsB;AAC1B,QAAI,CAAC,KAAM,QAAO;AAMlB,QAAI,CAAC,qBAAqB,IAAI,EAAG,QAAO;AAQxC,QAAI,KAAK,UAAU,mBAAmB;AACpC,aAAO,KAAK,SAAS,IAAI;AAAA,IAC3B;AACA,UAAM,MAAgB,CAAC;AACvB,QAAI,IAAI;AACR,WAAO,IAAI,KAAK,QAAQ;AACtB,UAAI,MAAM,KAAK,IAAI,IAAI,mBAAmB,KAAK,MAAM;AACrD,UAAI,MAAM,KAAK,QAAQ;AAIrB,cAAM,QAAQ,KAAK,IAAI,MAAM,qBAAqB,KAAK,MAAM;AAC7D,YAAI,OAAO;AACX,iBAAS,IAAI,KAAK,IAAI,OAAO,KAAK;AAChC,gBAAM,KAAK,KAAK,WAAW,CAAC;AAE5B,cAAI,OAAO,MAAM,OAAO,KAAK,OAAO,MAAM,OAAO,IAAI;AACnD,mBAAO;AACP;AAAA,UACF;AAAA,QACF;AAIA,cAAM,SAAS,KAAK,MAAM,OAAO;AAAA,MACnC;AACA,UAAI,KAAK,KAAK,SAAS,KAAK,MAAM,GAAG,GAAG,CAAC,CAAC;AAC1C,UAAI;AAAA,IACN;AACA,WAAO,IAAI,KAAK,EAAE;AAAA,EACpB;AAAA,EAEQ,SAAS,MAAsB;AAGrC,QAAI,CAAC,qBAAqB,IAAI,EAAG,QAAO;AAMxC,QAAI,MAAM,KAAK;AAAA,MACb;AAAA,MACA,CAAC,UAAU,WAAW;AAEpB,cAAM,MAAM,OAAO,UAAU,CAAC,MAAM,MAAM,MAAS;AACnD,YAAI,MAAM,EAAG,QAAO;AACpB,cAAM,cAAc,sBAAsB,GAAG;AAC7C,eAAO,gBAAgB,SAAY,cAAc;AAAA,MACnD;AAAA,IACF;AAKA,UAAM,IAAI,QAAQ,oBAAoB,CAAC,QAAQ,MAAM,KAAK,WAAW;AACnE,aAAO,GAAG,IAAI,GAAG,GAAG;AAAA,IACtB,CAAC;AAED,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,YAAe,KAAW;AACxB,UAAM,OAAO,oBAAI,QAAQ;AACzB,UAAM,QAAQ,CAAC,MAAwB;AACrC,UAAI,OAAO,MAAM,SAAU,QAAO,KAAK,MAAM,CAAC;AAC9C,UAAI,MAAM,QAAQ,OAAO,MAAM,SAAU,QAAO;AAChD,UAAI,KAAK,IAAI,CAAW,EAAG,QAAO;AAClC,WAAK,IAAI,CAAW;AACpB,UAAI,MAAM,QAAQ,CAAC,EAAG,QAAO,EAAE,IAAI,KAAK;AACxC,YAAM,MAA+B,CAAC;AACtC,iBAAW,CAAC,GAAG,GAAG,KAAK,OAAO,QAAQ,CAA4B,GAAG;AACnE,YAAI,CAAC,IAAI,MAAM,GAAG;AAAA,MACpB;AACA,aAAO;AAAA,IACT;AACA,WAAO,MAAM,GAAG;AAAA,EAClB;AACF;;;AC1RA,IAAM,0BAA0B;AAChC,IAAM,8BAA8B;AACpC,IAAM,4BAA4B;AAElC,IAAM,mBAAmB,oBAAI,IAAI;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,IAAM,iBAAiB,oBAAI,IAAI;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,IAAM,YAAY,oBAAI,IAAI;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAaD,IAAM,kBAAkB,IAAI,sBAAsB;AAE3C,SAAS,yBACd,QACmB;AACnB,SAAO;AAAA,IACL,GAAG;AAAA,IACH,GAAG;AAAA,EACL;AACF;AAOO,SAAS,yBACd,iBACA,gBACmB;AACnB,MAAI,mBAAmB,OAAW,QAAO;AACzC,QAAM,WAA0D;AAAA,IAC9D,MAAM;AAAA,IACN,SAAS;AAAA,IACT,UAAU;AAAA,IACV,MAAM;AAAA,EACR;AACA,QAAM,WAAuD;AAAA,IAC3D,MAAM;AAAA,IACN,UAAU;AAAA,IACV,oBAAoB;AAAA,IACpB,MAAM;AAAA,EACR;AACA,QAAM,oBAAoB,eAAe;AACzC,QAAM,iBAAiB,eAAe;AACtC,SAAO;AAAA,IACL,YACE,gBAAgB,eACf,eAAe,eAAe,UAAa,eAAe;AAAA,IAC7D,UACE,sBAAsB,UACtB,SAAS,iBAAiB,IAAI,SAAS,gBAAgB,QAAQ,IAC3D,oBACA,gBAAgB;AAAA,IACtB,OACE,mBAAmB,UAAa,SAAS,cAAc,IAAI,SAAS,gBAAgB,KAAK,IACrF,iBACA,gBAAgB;AAAA,EACxB;AACF;AAEA,SAAS,cAAc,OAAkD;AACvE,SAAO,OAAO,UAAU,SAAS,KAAK,KAAK,MAAM;AACnD;AAEA,SAAS,eAAe,KAAsB;AAC5C,QAAM,QAAQ,IAAI,YAAY;AAC9B,SACE,eAAe,IAAI,GAAG,KACtB,MAAM,SAAS,eAAe,KAC9B,MAAM,SAAS,UAAU,KACzB,MAAM,SAAS,QAAQ,KACvB,MAAM,SAAS,OAAO,KACtB,MAAM,SAAS,QAAQ,KACvB,MAAM,SAAS,SAAS;AAE5B;AAEA,SAAS,gBAAgB,KAAsB;AAC7C,SAAO,iBAAiB,IAAI,GAAG,KAAK,iBAAiB,IAAI,IAAI,YAAY,CAAC;AAC5E;AAEA,SAAS,UAAU,KAAsB;AACvC,SAAO,UAAU,IAAI,GAAG,KAAK,UAAU,IAAI,IAAI,YAAY,CAAC;AAC9D;AAEA,SAAS,wBAAwB,OAAuB;AACtD,SAAO,MAAM,QAAQ,OAAO,GAAG,EAAE,QAAQ,SAAS,EAAE;AACtD;AAEA,SAAS,WACP,OACA,aACA,QACQ;AACR,MAAI,OAAO,UAAU,OAAQ,QAAO;AACpC,MAAI,OAAO,UAAU,UAAU,OAAO,UAAU,WAAY,QAAO;AAEnE,QAAM,kBAAkB,wBAAwB,KAAK;AACrD,MAAI,CAAC,YAAa,QAAO,gBAAgB,MAAM,GAAG,EAAE,GAAG,EAAE,KAAK;AAE9D,QAAM,iBAAiB,wBAAwB,WAAW;AAC1D,MAAI,oBAAoB,eAAgB,QAAO;AAC/C,MAAI,gBAAgB,WAAW,GAAG,cAAc,GAAG,GAAG;AACpD,WAAO,gBAAgB,MAAM,eAAe,SAAS,CAAC,KAAK;AAAA,EAC7D;AACA,SAAO,gBAAgB,MAAM,GAAG,EAAE,GAAG,EAAE,KAAK;AAC9C;AAEA,SAAS,gBAAgB,OAAe,kBAA0B,OAAwB;AACxF,QAAM,WAAW,QAAQ,gBAAgB,MAAM,KAAK,IAAI;AACxD,MAAI,SAAS,UAAU,iBAAkB,QAAO;AAChD,SAAO,GAAG,SAAS,MAAM,GAAG,gBAAgB,CAAC,oBAAe,SAAS,SAAS,gBAAgB;AAChG;AAUO,SAAS,0BACd,OACA,YAAoB,KACA;AACpB,MAAI,OAAO,UAAU,YAAY,MAAM,WAAW,EAAG,QAAO;AAC5D,SAAO,gBAAgB,OAAO,WAAW,IAAI;AAC/C;AAEA,SAAS,WACP,OACA,SAMA,KACuC;AACvC,MAAI,CAAC,QAAQ,OAAO,cAAc,QAAQ,UAAa,eAAe,GAAG,GAAG;AAC1E,WAAO,EAAE,OAAO,6BAA6B,UAAU,KAAK;AAAA,EAC9D;AAEA,MAAI,OAAO,UAAU,UAAU;AAC7B,QAAI,QAAQ,UAAa,UAAU,GAAG,GAAG;AACvC,YAAM,eAAe,WAAW,OAAO,QAAQ,aAAa,QAAQ,MAAM;AAC1E,aAAO,EAAE,OAAO,cAAc,UAAU,iBAAiB,MAAM;AAAA,IACjE;AAEA,QAAI,CAAC,QAAQ,OAAO,cAAc,QAAQ,UAAa,gBAAgB,GAAG,GAAG;AAC3E,aAAO,EAAE,OAAO,yBAAyB,UAAU,KAAK;AAAA,IAC1D;AAEA,UAAM,WAAW,gBAAgB,OAAO,QAAQ,kBAAkB,CAAC,QAAQ,OAAO,UAAU;AAC5F,WAAO,EAAE,OAAO,UAAU,UAAU,aAAa,MAAM;AAAA,EACzD;AAEA,MAAI,UAAU,QAAQ,OAAO,UAAU,SAAU,QAAO,EAAE,OAAO,UAAU,MAAM;AAEjF,MAAI,QAAQ,KAAK,IAAI,KAAK,EAAG,QAAO,EAAE,OAAO,0BAA0B,UAAU,KAAK;AACtF,UAAQ,KAAK,IAAI,KAAK;AAEtB,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,QAAIA,YAAW;AACf,UAAMC,OAAM,MAAM,IAAI,CAAC,SAAS;AAC9B,YAAM,OAAO,WAAW,MAAM,SAAS,GAAG;AAC1C,MAAAD,cAAa,KAAK;AAClB,aAAO,KAAK;AAAA,IACd,CAAC;AACD,WAAO,EAAE,OAAOC,MAAK,UAAAD,UAAS;AAAA,EAChC;AAEA,MAAI,CAAC,cAAc,KAAK,EAAG,QAAO,EAAE,OAAO,OAAO,KAAK,GAAG,UAAU,KAAK;AAEzE,MAAI,WAAW;AACf,QAAM,MAA+B,CAAC;AACtC,aAAW,CAAC,UAAU,UAAU,KAAK,OAAO,QAAQ,KAAK,GAAG;AAC1D,UAAM,OAAO,WAAW,YAAY,SAAS,QAAQ;AACrD,iBAAa,KAAK;AAClB,QAAI,QAAQ,IAAI,KAAK;AAAA,EACvB;AACA,SAAO,EAAE,OAAO,KAAK,SAAS;AAChC;AAEO,SAAS,cAAiB,OAAU,UAA2B,CAAC,GAAyB;AAC9F,QAAM,SAAS,WAAW,OAAO;AAAA,IAC/B,QAAQ,yBAAyB,QAAQ,MAAM;AAAA,IAC/C,GAAI,QAAQ,gBAAgB,SAAY,EAAE,aAAa,QAAQ,YAAY,IAAI,CAAC;AAAA,IAChF,kBAAkB,QAAQ,oBAAoB;AAAA,IAC9C,MAAM,oBAAI,QAAgB;AAAA,EAC5B,CAAC;AACD,SAAO,EAAE,OAAO,OAAO,OAAY,UAAU,OAAO,SAAS;AAC/D;AAEO,SAAS,cACd,OACA,UAA2B,CAAC,GACkB;AAC9C,QAAM,UAAU,cAAc,MAAM,SAAS,OAAO;AACpD,QAAM,YAAY;AAAA,IAChB,GAAG;AAAA,IACH,SAAS,QAAQ;AAAA,EACnB;AACA,SAAO,EAAE,OAAO,WAAW,UAAU,QAAQ,SAAS;AACxD;AAEO,SAAS,oBAAoB,OAAgB,UAA2B,CAAC,GAAY;AAC1F,QAAM,SAAS,yBAAyB,QAAQ,MAAM;AACtD,MAAI,OAAO,aAAa,OAAQ,QAAO;AACvC,MAAI,OAAO,aAAa,OAAQ,QAAO;AACvC,MAAI,OAAO,aAAa,WAAY,QAAO,cAAc,OAAO,OAAO,EAAE;AAEzE,MAAI,UAAU,QAAQ,OAAO,UAAU,SAAU,QAAO,cAAc,OAAO,OAAO,EAAE;AACtF,MAAI,MAAM,QAAQ,KAAK,EAAG,QAAO,UAAU,MAAM,MAAM;AAEvD,QAAM,UAAU,OAAO,QAAQ,KAAgC;AAC/D,QAAM,UAAmC,CAAC;AAC1C,aAAW,CAAC,KAAK,IAAI,KAAK,QAAQ,MAAM,GAAG,EAAE,GAAG;AAC9C,QAAI,eAAe,GAAG,GAAG;AACvB,cAAQ,GAAG,IAAI;AAAA,IACjB,WAAW,OAAO,SAAS,UAAU;AACnC,cAAQ,GAAG,IAAI,UAAU,GAAG,IACxB,WAAW,MAAM,QAAQ,aAAa,MAAM,IAC5C,gBAAgB,MAAM,KAAK,IAAI;AAAA,IACrC,WAAW,MAAM,QAAQ,IAAI,GAAG;AAC9B,cAAQ,GAAG,IAAI,UAAU,KAAK,MAAM;AAAA,IACtC,WAAW,SAAS,QAAQ,OAAO,SAAS,UAAU;AACpD,cAAQ,GAAG,IAAI;AAAA,IACjB,OAAO;AACL,cAAQ,GAAG,IAAI;AAAA,IACjB;AAAA,EACF;AACA,MAAI,QAAQ,SAAS,GAAI,SAAQ,kBAAkB,QAAQ,SAAS;AACpE,SAAO;AACT;;;AChSA,SAAS,YAAY,OAA2B,WAAmB,QAAyD;AAC1H,MAAI,UAAU,UAAa,MAAM,WAAW,EAAG,QAAO;AACtD,MAAI,QAAQ,eAAe,MAAO,QAAO;AACzC,MAAI,QAAQ,eAAe,MAAM;AAC/B,QAAI,MAAM,UAAU,UAAW,QAAO;AACtC,WAAO,GAAG,MAAM,MAAM,GAAG,SAAS,CAAC;AAAA,EACrC;AACA,SAAO,0BAA0B,OAAO,SAAS;AACnD;AAEA,SAAS,UAAU,SAAiC;AAClD,SAAO,OAAO,KAAK,QAAQ,MAAM,EAAE;AACrC;AAEA,SAAS,YAAY,SAA0D;AAC7E,MAAI,QAAQ,gBAAgB,OAAW,QAAO;AAC9C,QAAM,OAAO;AAAA,IACX,GAAI,QAAQ,YAAY,WAAW,SAAY,EAAE,QAAQ,QAAQ,YAAY,OAAO,IAAI,CAAC;AAAA,IACzF,GAAI,QAAQ,YAAY,cAAc,SAAY,EAAE,WAAW,QAAQ,YAAY,UAAU,IAAI,CAAC;AAAA,IAClG,GAAI,QAAQ,YAAY,cAAc,SAAY,EAAE,WAAW,QAAQ,YAAY,UAAU,IAAI,CAAC;AAAA,IAClG,GAAI,QAAQ,YAAY,WAAW,SAAY,EAAE,QAAQ,QAAQ,YAAY,OAAO,IAAI,CAAC;AAAA,EAC3F;AACA,SAAO,OAAO,KAAK,IAAI,EAAE,SAAS,IAAI,OAAO;AAC/C;AAEO,SAAS,6BACd,SACA,UAA8E,CAAC,GACtD;AACzB,QAAM,gBAAgB,QAAQ,iBAAiB;AAC/C,QAAM,cAAc,YAAY,QAAQ,MAAM,eAAe,QAAQ,eAAe;AACpF,QAAM,iBAAiB,YAAY,QAAQ,SAAS,eAAe,QAAQ,eAAe;AAC1F,QAAM,OAAO,YAAY,OAAO;AAEhC,SAAO;AAAA,IACL,QAAQ,QAAQ;AAAA;AAAA,IAChB,WAAW,QAAQ;AAAA,IACnB,MAAM,QAAQ;AAAA,IACd,IAAI,QAAQ;AAAA,IACZ,MAAM,QAAQ;AAAA,IACd,SAAS,YAAY,QAAQ,SAAS,eAAe,QAAQ,eAAe,KAAK;AAAA,IACjF,UAAU,QAAQ;AAAA,IAClB,WAAW,QAAQ;AAAA,IACnB,GAAI,QAAQ,YAAY,SAAY,EAAE,SAAS,QAAQ,QAAQ,IAAI,CAAC;AAAA,IACpE,GAAI,QAAQ,oBAAoB,SAAY,EAAE,iBAAiB,QAAQ,gBAAgB,IAAI,CAAC;AAAA,IAC5F,WAAW,QAAQ;AAAA,IACnB,GAAI,QAAQ,gBAAgB,SAAY,EAAE,aAAa,QAAQ,YAAY,IAAI,CAAC;AAAA,IAChF,GAAI,QAAQ,gBAAgB,SAAY,EAAE,aAAa,QAAQ,YAAY,IAAI,CAAC;AAAA,IAChF,WAAW,UAAU,OAAO;AAAA,IAC5B,SAAS,QAAQ,KAAK,SAAS;AAAA,IAC/B,GAAI,gBAAgB,SAAY,EAAE,YAAY,IAAI,CAAC;AAAA,IACnD,GAAI,mBAAmB,SAAY,EAAE,eAAe,IAAI,CAAC;AAAA,IACzD,GAAI,SAAS,SAAY,EAAE,KAAK,IAAI,CAAC;AAAA,EACvC;AACF;AAEO,SAAS,2BAA2B,OAAkD;AAC3F,SAAO;AAAA,IACL,SAAS,MAAM;AAAA,IACf,MAAM,MAAM;AAAA,IACZ,GAAI,MAAM,SAAS,SAAY,EAAE,MAAM,MAAM,KAAK,IAAI,CAAC;AAAA,IACvD,WAAW,MAAM;AAAA,IACjB,QAAQ,MAAM;AAAA,IACd,GAAI,MAAM,gBAAgB,SAAY,EAAE,aAAa,MAAM,YAAY,IAAI,CAAC;AAAA,IAC5E,GAAI,MAAM,gBAAgB,SAAY,EAAE,aAAa,MAAM,YAAY,IAAI,CAAC;AAAA,IAC5E,YAAY,MAAM;AAAA,IAClB,WAAW,MAAM;AAAA,IACjB,gBAAgB,MAAM;AAAA,IACtB,YAAY,MAAM;AAAA,IAClB,QAAQ,MAAM;AAAA,IACd,GAAI,MAAM,WAAW,SAAY,EAAE,QAAQ,MAAM,OAAO,IAAI,CAAC;AAAA,EAC/D;AACF;AAEO,SAAS,6BACd,UACA,QACA,SAC0B;AAC1B,QAAM,mBAAmB,QAAQ,oBAAoB;AACrD,QAAM,mBAAmB,mBAAmB,WAAW,SAAS,OAAO,CAAC,YAAY,CAAC,QAAQ,SAAS;AACtG,QAAM,QAAQ,QAAQ,SAAS;AAC/B,QAAM,iBAAiB,CAAC,GAAG,gBAAgB,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,UAAU,cAAc,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,KAAK;AAClH,QAAM,YAAY,eAAe,IAAI,CAAC,YAAY,6BAA6B,SAAS,OAAO,CAAC;AAChG,QAAM,iBAAiB,OAAO,IAAI,0BAA0B;AAE5D,SAAO;AAAA,IACL,WAAW,QAAQ;AAAA,IACnB,OAAO,QAAQ,SAAS;AAAA,IACxB,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,QAAQ;AAAA,MACN,UAAU,SAAS;AAAA,MACnB,QAAQ,SAAS,OAAO,CAAC,YAAY,CAAC,QAAQ,aAAa,UAAU,OAAO,MAAM,CAAC,EAAE;AAAA,MACrF,YAAY,SAAS,OAAO,CAAC,YAAY,CAAC,QAAQ,SAAS,EAAE;AAAA,MAC7D,cAAc,SAAS,OAAO,CAAC,YAAY,QAAQ,aAAa,MAAM,EAAE;AAAA,MACxE,cAAc,OAAO,OAAO,CAAC,UAAU,MAAM,MAAM,EAAE;AAAA,IACvD;AAAA,EACF;AACF;AAEA,eAAsB,wCACpB,SACA,SACmC;AACnC,QAAM,QAAQ,QAAQ,SAAS;AAC/B,QAAM,CAAC,UAAU,MAAM,IAAI,MAAM,QAAQ,IAAI;AAAA,IAC3C,QAAQ,MAAM,EAAE,MAAM,CAAC;AAAA,IACvB,QAAQ,iBAAiB;AAAA,EAC3B,CAAC;AACD,SAAO,6BAA6B,UAAU,QAAQ,OAAO;AAC/D;AAEO,SAAS,0BAA0B,OAQhB;AACxB,QAAM,iBAAqF;AAAA,IACzF,GAAI,MAAM,kBAAkB,SAAY,EAAE,eAAe,MAAM,cAAc,IAAI,CAAC;AAAA,IAClF,GAAI,MAAM,oBAAoB,SAAY,EAAE,iBAAiB,MAAM,gBAAgB,IAAI,CAAC;AAAA,EAC1F;AAEA,SAAO;AAAA,IACL,WAAW,MAAM;AAAA,IACjB,QAAQ,MAAM;AAAA,IACd,GAAI,MAAM,YAAY,SAAY,EAAE,SAAS,6BAA6B,MAAM,SAAS,cAAc,EAAE,IAAI,CAAC;AAAA,IAC9G,GAAI,MAAM,UAAU,SAAY,EAAE,OAAO,2BAA2B,MAAM,KAAK,EAAE,IAAI,CAAC;AAAA,IACtF,GAAI,MAAM,YAAY,SAClB,EAAE,SAAS,YAAY,MAAM,SAAS,MAAM,iBAAiB,KAAK,MAAM,eAAe,KAAK,GAAG,IAC/F,CAAC;AAAA,EACP;AACF;;;AChKA,SAAS,kBAAkB;AA8H3B,IAAM,yBAAyB,oBAAI,IAAY,CAAC,sBAAsB,eAAe,CAAC;AAEtF,IAAM,aAAa;AAOnB,IAAM,8BAA8B;AACpC,IAAM,4BAA4B;AAClC,IAAM,2BAA2B;AACjC,IAAM,4BAA4B;AAClC,IAAM,8BAA8B;AACpC,IAAM,mCAAmC;AACzC,IAAM,6BAA6B;AACnC,IAAM,gCAAgC;AAEtC,SAAS,qBAAqB,KAA2B;AACvD,QAAM,gBAAgB,WAAW;AACjC,MAAI,kBAAkB,QAAW;AAC/B,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,SAAO,IAAI,cAAc,GAAG;AAC9B;AAEA,SAAS,YAAY,SAAiB,OAAmC;AACvE,QAAM,MAAM,IAAI,IAAI,OAAO;AAC3B,MAAI,WAAW,IAAI,aAAa,WAAW,SAAS;AACpD,MAAI,IAAI,aAAa,OAAO,IAAI,aAAa,GAAI,KAAI,WAAW;AAChE,MAAI,UAAU,UAAa,MAAM,SAAS,EAAG,KAAI,aAAa,IAAI,SAAS,KAAK;AAChF,SAAO,IAAI,SAAS;AACtB;AAEA,SAAS,kBACP,QACA,MACA,UACM;AACN,MAAI,OAAO,qBAAqB,QAAW;AACzC,WAAO,iBAAiB,MAAM,QAAQ;AACtC;AAAA,EACF;AACA,SAAO,KAAK,MAAM,QAAQ;AAC5B;AAEA,SAAS,qBACP,QACA,MACA,UACM;AACN,MAAI,OAAO,wBAAwB,QAAW;AAC5C,WAAO,oBAAoB,MAAM,QAAQ;AACzC;AAAA,EACF;AACA,SAAO,MAAM,MAAM,QAAQ;AAC7B;AAEO,IAAM,cAAN,MAAkB;AAAA,EAuBvB,YAA6B,SAA6B;AAA7B;AAC3B,SAAK,gBAAgB,QAAQ,iBAAiB;AAC9C,SAAK,MAAM,QAAQ,QAAQ,OAAM,oBAAI,KAAK,GAAE,YAAY;AACxD,SAAK,YAAY,QAAQ,aAAa;AACtC,SAAK,eAAe,QAAQ,gBAAgB;AAAA,MAC1C;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,SAAK,YAAY,QAAQ,aAAa;AACtC,SAAK,kBAAkB,QAAQ,mBAAmB;AAClD,SAAK,iBAAiB,QAAQ,kBAAkB;AAChD,SAAK,oBAAoB,QAAQ,qBAAqB;AACtD,SAAK,0BAA0B,yBAAyB,QAAQ,eAAe;AAC/E,SAAK,SAAS,QAAQ;AAAA,EACxB;AAAA,EAhB6B;AAAA,EAtBZ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACT,SAA8B;AAAA,EAC9B,MAAM;AAAA,EACN,QAAkB,CAAC;AAAA,EACnB,UAAU;AAAA,EACV,mBAAmB;AAAA,EACnB,wBAAwB;AAAA,EACxB,cAAyD;AAAA,EACzD,iBAAuD;AAAA,EACvD,mBAA0D;AAAA,EAC1D,iBAAwD;AAAA,EACxD;AAAA,EAoBR,UAAgB;AACd,QAAI,KAAK,WAAW,QAAQ,KAAK,QAAS;AAG1C,QAAI,KAAK,mBAAmB,KAAM;AAElC,QAAI,MAAM,KAAK,QAAQ;AACvB,QAAI,QAAQ,KAAK,QAAQ;AACzB,QAAI,KAAK,QAAQ,oBAAoB,QAAW;AAC9C,YAAM,WAAW,KAAK,QAAQ,gBAAgB;AAC9C,UAAI,aAAa,QAAW;AAC1B,aAAK,sBAAsB;AAC3B;AAAA,MACF;AACA,YAAM,SAAS;AACf,cAAQ,SAAS,SAAS;AAAA,IAC5B;AACA,SAAK,cAAc,EAAE,KAAK,UAAU,UAAU,OAAU;AAExD,QAAI;AACJ,QAAI;AACF,eAAS,KAAK,cAAc,YAAY,KAAK,KAAK,GAAG;AAAA,QACnD,GAAI,UAAU,SAAY,EAAE,MAAM,IAAI,CAAC;AAAA,MACzC,CAAC;AAAA,IACH,QAAQ;AACN,WAAK,kBAAkB;AACvB;AAAA,IACF;AACA,SAAK,SAAS;AAEd,UAAM,SAAS,MAAM;AACnB,WAAK,mBAAmB;AACxB,WAAK,aAAa;AAClB,WAAK,WAAW;AAChB,WAAK,eAAe;AACpB,UAAI,KAAK,QAAQ,cAAc,QAAW;AACxC,aAAK,oBAAoB;AACzB,aAAK,aAAa;AAAA,MACpB;AAAA,IACF;AACA,UAAM,YAAY,CAAC,UAAmB;AACpC,WAAK,KAAK,oBAAoB,KAAK;AAAA,IACrC;AACA,UAAM,iBAAiB,MAAM;AAC3B,2BAAqB,QAAQ,QAAQ,MAAM;AAC3C,2BAAqB,QAAQ,WAAW,SAAS;AACjD,2BAAqB,QAAQ,SAAS,cAAc;AACpD,2BAAqB,QAAQ,SAAS,cAAc;AACpD,WAAK,mBAAmB;AACxB,WAAK,cAAc;AACnB,UAAI,KAAK,WAAW,OAAQ,MAAK,SAAS;AAC1C,WAAK,kBAAkB;AAAA,IACzB;AAEA,sBAAkB,QAAQ,QAAQ,MAAM;AACxC,sBAAkB,QAAQ,WAAW,SAAS;AAC9C,sBAAkB,QAAQ,SAAS,cAAc;AACjD,sBAAkB,QAAQ,SAAS,cAAc;AAEjD,QAAI,OAAO,eAAe,WAAY,QAAO;AAAA,EAC/C;AAAA,EAEA,QAAc;AACZ,SAAK,UAAU;AACf,QAAI,KAAK,mBAAmB,MAAM;AAChC,mBAAa,KAAK,cAAc;AAChC,WAAK,iBAAiB;AAAA,IACxB;AACA,SAAK,mBAAmB;AACxB,SAAK,cAAc;AACnB,SAAK,QAAQ,CAAC;AACd,UAAM,SAAS,KAAK;AACpB,SAAK,SAAS;AACd,YAAQ,MAAM,KAAM,qBAAqB;AAAA,EAC3C;AAAA,EAEA,aACE,SAC2B;AAC3B,UAAM,QAAQ,sBAAsB;AAAA,MAClC,IAAI,KAAK,UAAU;AAAA,MACnB,MAAM,QAAQ;AAAA,MACd,WAAW,QAAQ,aAAa,KAAK,IAAI;AAAA,MACzC,UAAU,KAAK,QAAQ,OAAO;AAAA,MAC9B,WAAW,KAAK,QAAQ,QAAQ;AAAA,MAChC,KAAK,EAAE,KAAK;AAAA,MACZ,SAAS,QAAQ;AAAA,MACjB,GAAI,QAAQ,cAAc,SAAY,EAAE,WAAW,QAAQ,UAAU,IAAI,CAAC;AAAA,MAC1E,GAAI,QAAQ,UAAU,SAAY,EAAE,OAAO,QAAQ,MAAM,IAAI,CAAC;AAAA,IAChE,CAAC;AACD,UAAM,mBACJ,QAAQ,qBACP,uBAAuB,IAAI,QAAQ,IAAI,IAAI,yBAAyB;AACvE,UAAM,WAAW,cAAc,OAAO;AAAA,MACpC,QAAQ,KAAK;AAAA,MACb,aAAa,KAAK,QAAQ,QAAQ;AAAA,MAClC,GAAI,qBAAqB,SAAY,EAAE,iBAAiB,IAAI,CAAC;AAAA,IAC/D,CAAC,EAAE;AACH,SAAK,UAAU,EAAE,MAAM,gBAAgB,OAAO,SAAS,CAAC;AACxD,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,uBACJ,SACA,SAIoD;AACpD,UAAM,UAAU,MAAM,wCAAwC,SAAS;AAAA,MACrE,GAAG;AAAA,MACH,iBAAiB,KAAK;AAAA,IACxB,CAAC;AACD,WAAO,KAAK,aAAa;AAAA,MACvB,MAAM;AAAA,MACN;AAAA,MACA,GAAI,QAAQ,cAAc,SAAY,EAAE,WAAW,QAAQ,UAAU,IAAI,CAAC;AAAA,MAC1E,GAAI,QAAQ,cAAc,SAAY,EAAE,WAAW,QAAQ,UAAU,IAAI,CAAC;AAAA,IAC5E,CAAC;AAAA,EACH;AAAA,EAEA,oBAAoB,OASuB;AACzC,UAAM,UAAU,0BAA0B;AAAA,MACxC,WAAW,MAAM;AAAA,MACjB,QAAQ,MAAM;AAAA,MACd,GAAI,MAAM,YAAY,SAAY,EAAE,SAAS,MAAM,QAAQ,IAAI,CAAC;AAAA,MAChE,GAAI,MAAM,UAAU,SAAY,EAAE,OAAO,MAAM,MAAM,IAAI,CAAC;AAAA,MAC1D,GAAI,MAAM,YAAY,SAAY,EAAE,SAAS,MAAM,QAAQ,IAAI,CAAC;AAAA,MAChE,GAAI,MAAM,kBAAkB,SAAY,EAAE,eAAe,MAAM,cAAc,IAAI,CAAC;AAAA,MAClF,iBAAiB,KAAK;AAAA,IACxB,CAAC;AACD,WAAO,KAAK,aAAa;AAAA,MACvB,MAAM;AAAA,MACN;AAAA,MACA,GAAI,MAAM,cAAc,SAAY,EAAE,WAAW,MAAM,UAAU,IAAI,CAAC;AAAA,MACtE,GAAI,MAAM,cAAc,SAAY,EAAE,WAAW,MAAM,UAAU,IAAI,CAAC;AAAA,IACxE,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,IAAI,WAA6B;AAC/B,WAAO,KAAK,QAAQ;AAAA,EACtB;AAAA;AAAA,EAGA,IAAI,UAA6B;AAC/B,WAAO,KAAK,QAAQ;AAAA,EACtB;AAAA;AAAA,EAGA,IAAI,kBAAqC;AACvC,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,uBACE,SACA,MAC2C;AAC3C,WAAO,KAAK,aAAa;AAAA,MACvB,MAAM;AAAA,MACN;AAAA,MACA,WAAW,QAAQ;AAAA,MACnB,GAAI,MAAM,cAAc,SAAY,EAAE,WAAW,KAAK,UAAU,IAAI,CAAC;AAAA,IACvE,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,wBACE,SACA,MAC4C;AAC5C,WAAO,KAAK,aAAa;AAAA,MACvB,MAAM;AAAA,MACN;AAAA,MACA,WAAW,QAAQ;AAAA,MACnB,GAAI,MAAM,cAAc,SAAY,EAAE,WAAW,KAAK,UAAU,IAAI,CAAC;AAAA,IACvE,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,oBACE,SACA,MACwC;AACxC,WAAO,KAAK,aAAa;AAAA,MACvB,MAAM;AAAA,MACN;AAAA,MACA,WAAW,QAAQ;AAAA,MACnB,GAAI,MAAM,cAAc,SAAY,EAAE,WAAW,KAAK,UAAU,IAAI,CAAC;AAAA,IACvE,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,qBACE,SACA,MACyC;AACzC,WAAO,KAAK,aAAa;AAAA,MACvB,MAAM;AAAA,MACN;AAAA,MACA,OAAO,QAAQ;AAAA,MACf,GAAI,MAAM,cAAc,SAAY,EAAE,WAAW,KAAK,UAAU,IAAI,CAAC;AAAA,MACrE,GAAI,MAAM,cAAc,SAAY,EAAE,WAAW,KAAK,UAAU,IAAI,CAAC;AAAA,IACvE,CAAC;AAAA,EACH;AAAA,EAEA,eAAqB;AACnB,SAAK,UAAU;AAAA,MACb,MAAM;AAAA,MACN,UAAU,KAAK,QAAQ,OAAO;AAAA,MAC9B,WAAW,KAAK,QAAQ,QAAQ;AAAA,MAChC,GAAI,KAAK,kBAAkB,SAAY,EAAE,gBAAgB,KAAK,cAAc,IAAI,CAAC;AAAA,MACjF,OAAO,KAAK,QAAQ,oBAAoB;AAAA,IAC1C,CAAC;AAAA,EACH;AAAA,EAEA,WAAW,QAAwC;AACjD,SAAK,UAAU;AAAA,MACb,MAAM;AAAA,MACN,UAAU,KAAK,QAAQ,OAAO;AAAA,MAC9B,WAAW,KAAK,QAAQ,QAAQ;AAAA,MAChC,WAAW,OAAO;AAAA,MAClB,QAAQ,OAAO;AAAA,MACf,GAAI,OAAO,YAAY,SAAY,EAAE,SAAS,OAAO,QAAQ,IAAI,CAAC;AAAA,IACpE,CAAC;AAAA,EACH;AAAA,EAEQ,mBAAyC;AAC/C,WAAO;AAAA,MACL,MAAM;AAAA,MACN,SAAS;AAAA,QACP,iBAAiB;AAAA,QACjB,QAAQ,KAAK,QAAQ;AAAA,QACrB,SAAS,KAAK,QAAQ;AAAA,QACtB,cAAc,KAAK;AAAA,QACnB,iBAAiB,KAAK;AAAA,MACxB;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,eAAqB;AAC3B,UAAM,SAAS,KAAK;AACpB,QAAI,QAAQ,eAAe,YAAY;AACrC,WAAK,UAAU,KAAK,iBAAiB,CAAC;AACtC;AAAA,IACF;AACA,WAAO,KAAK,KAAK,UAAU,KAAK,iBAAiB,CAAC,CAAC;AAAA,EACrD;AAAA,EAEQ,UACN,OAKM;AACN,UAAM,aAAa,KAAK,UAAU,KAAK;AACvC,UAAM,SAAS,KAAK;AAEpB,QAAI,QAAQ,eAAe,cAAc,KAAK,MAAM,WAAW,GAAG;AAChE,aAAO,KAAK,UAAU;AACtB;AAAA,IACF;AAEA,SAAK,QAAQ,UAAU;AACvB,SAAK,QAAQ;AAAA,EACf;AAAA,EAEQ,QAAQ,YAA0B;AACxC,QAAI,KAAK,MAAM,UAAU,KAAK,kBAAmB,MAAK,MAAM,MAAM;AAClE,SAAK,MAAM,KAAK,UAAU;AAAA,EAC5B;AAAA;AAAA;AAAA,EAIQ,aAAmB;AACzB,UAAM,SAAS,KAAK;AACpB,QAAI,QAAQ,eAAe,cAAc,KAAK,MAAM,WAAW,EAAG;AAClE,UAAM,QAAQ,KAAK,MAAM,OAAO,GAAG,EAAE;AACrC,eAAW,SAAS,MAAO,QAAO,KAAK,KAAK;AAC5C,QAAI,KAAK,MAAM,SAAS,EAAG,cAAa,MAAM,KAAK,WAAW,CAAC;AAAA,EACjE;AAAA,EAEQ,sBAA4B;AAClC,QAAI,KAAK,QAAQ,cAAc,UAAa,KAAK,qBAAqB,KAAM;AAC5E,SAAK,mBAAmB;AAAA,MACtB,MAAM,KAAK,aAAa;AAAA,MACxB,KAAK,QAAQ,yBAAyB;AAAA,IACxC;AACA,SAAK,iBAAiB,QAAQ;AAAA,EAChC;AAAA,EAEQ,qBAA2B;AACjC,QAAI,KAAK,qBAAqB,KAAM;AACpC,kBAAc,KAAK,gBAAgB;AACnC,SAAK,mBAAmB;AAAA,EAC1B;AAAA,EAEQ,iBAAuB;AAC7B,QAAI,KAAK,mBAAmB,KAAM;AAClC,SAAK,iBAAiB;AAAA,MACpB,MAAM,KAAK,iBAAiB;AAAA,MAC5B,KAAK,QAAQ,uBAAuB;AAAA,IACtC;AACA,SAAK,eAAe,QAAQ;AAAA,EAC9B;AAAA,EAEQ,gBAAsB;AAC5B,QAAI,KAAK,mBAAmB,KAAM;AAClC,kBAAc,KAAK,cAAc;AACjC,SAAK,iBAAiB;AAAA,EACxB;AAAA,EAEQ,mBAAyB;AAC/B,UAAM,YAAY,KAAK,MAAM,KAAK,QAAQ,OAAO,SAAS;AAC1D,UAAM,MAAM,KAAK,MAAM,KAAK,IAAI,CAAC;AACjC,SAAK,aAAa;AAAA,MAChB,MAAM;AAAA,MACN,SAAS;AAAA,QACP,UACE,OAAO,SAAS,SAAS,KAAK,OAAO,SAAS,GAAG,IAAI,KAAK,IAAI,GAAG,MAAM,SAAS,IAAI;AAAA,QACtF,QAAQ;AAAA,MACV;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,oBAAoB,OAA+B;AAC/D,UAAM,UAAU,KAAK,mBAAmB,KAAK;AAC7C,QAAI,SAAS,SAAS,mBAAoB;AAC1C,UAAM,KAAK,mBAAmB,OAAO;AAAA,EACvC;AAAA,EAEQ,mBAAmB,OAAoD;AAC7E,UAAM,OAAO,KAAK,mBAAmB,KAAK;AAC1C,QAAI,SAAS,KAAM,QAAO;AAC1B,QAAI;AACF,YAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,UAAI,OAAO,SAAS,sBAAsB,CAAC,MAAM,QAAQ,OAAO,QAAQ,EAAG,QAAO;AAClF,aAAO;AAAA,IACT,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEQ,mBAAmB,OAA+B;AACxD,UAAM,QACJ,OAAO,UAAU,YAAY,UAAU,QAAQ,UAAU,QACpD,MAA6B,OAC9B;AACN,QAAI,OAAO,UAAU,SAAU,QAAO;AACtC,QAAI,iBAAiB,YAAa,QAAO,IAAI,YAAY,EAAE,OAAO,KAAK;AACvE,QAAI,YAAY,OAAO,KAAK,GAAG;AAC7B,YAAM,QAAQ,IAAI,WAAW,MAAM,QAAQ,MAAM,YAAY,MAAM,UAAU;AAC7E,aAAO,IAAI,YAAY,EAAE,OAAO,KAAK;AAAA,IACvC;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,mBAAmB,SAAqD;AACpF,UAAM,UAAU,KAAK,QAAQ;AAC7B,QAAI,YAAY,OAAW;AAE3B,eAAW,WAAW,QAAQ,UAAU;AACtC,WAAK,gBAAgB,QAAQ;AAC7B,UAAI;AACF,cAAM,SAAS,MAAM,QAAQ,OAAO;AACpC,YAAI,WAAW,OAAW,MAAK,WAAW,MAAM;AAAA,iBACvC,QAAQ;AACf,eAAK,WAAW,EAAE,WAAW,QAAQ,WAAW,QAAQ,WAAW,CAAC;AAAA,MACxE,SAAS,KAAK;AACZ,aAAK,WAAW;AAAA,UACd,WAAW,QAAQ;AAAA,UACnB,QAAQ;AAAA,UACR,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,QAC1D,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,oBAA0B;AAChC,QAAI,KAAK,WAAW,CAAC,KAAK,aAAa,KAAK,mBAAmB,KAAM;AACrE,UAAM,QAAQ,KAAK,IAAI,KAAK,gBAAgB,KAAK,kBAAkB,KAAK,KAAK,gBAAgB;AAC7F,SAAK,oBAAoB;AAIzB,QAAI,CAAC,KAAK,yBAAyB,KAAK,oBAAoB,6BAA6B;AACvF,WAAK,wBAAwB;AAC7B,WAAK,mBAAmB;AAAA,IAC1B;AACA,SAAK,iBAAiB,WAAW,MAAM;AACrC,WAAK,iBAAiB;AACtB,WAAK,QAAQ;AAAA,IACf,GAAG,KAAK;AACR,SAAK,eAAe,QAAQ;AAAA,EAC9B;AAAA,EAEQ,qBAA2B;AACjC,UAAM,UAAU,KAAK;AACrB,UAAM,UACJ,4BAA4B,KAAK,gBAAgB,mCAC9C,YAAY,OAAO,OAAO,QAAQ,GAAG,kBAAkB,QAAQ,WAAW,YAAY,QAAQ,MAAM,EAAE;AAG3G,QAAI,KAAK,QAAQ;AACf,WAAK,OAAO,KAAK,SAAS,EAAE,OAAO,8BAA8B,CAAC;AAClE;AAAA,IACF;AACA,UAAM,OACJ,KAAK,QAAQ,SACZ,CAAC,QACA,QAAQ;AAAA,MACN,KAAK,UAAU;AAAA,QACb,OAAO;AAAA,QACP,OAAO;AAAA,QACP,SAAS;AAAA,QACT,WAAW,KAAK,IAAI;AAAA,MACtB,CAAC;AAAA,IACH;AACJ,QAAI;AACF,WAAK,OAAO;AAAA,IACd,QAAQ;AAAA,IAER;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,wBAA8B;AACpC,QAAI,KAAK,WAAW,CAAC,KAAK,aAAa,KAAK,mBAAmB,KAAM;AACrE,SAAK,mBAAmB;AACxB,SAAK,iBAAiB,WAAW,MAAM;AACrC,WAAK,iBAAiB;AACtB,WAAK,QAAQ;AAAA,IACf,GAAG,KAAK,QAAQ,mBAAmB,yBAAyB;AAC5D,SAAK,eAAe,QAAQ;AAAA,EAC9B;AACF;;;ACtqBA,SAAS,cAAAE,aAAY,cAAAC,mBAAkB;AACvC,YAAYC,SAAQ;AACpB,SAAS,gBAAgB;AACzB,SAAS,YAAAC,iBAAgB;;;ACazB,SAAS,cAAAC,mBAAkB;AAC3B,YAAY,SAAS;AAErB,YAAYC,WAAU;;;ACnBtB,SAAS,mBAAmB;AAC5B,YAAY,QAAQ;AACpB,YAAYC,WAAU;;;ACFtB,YAAY,UAAU;AAcf,SAAS,kBAAkB,KAAa,WAAmB,QAAwB;AACxF,MAAI,CAAC,aAAa,UAAU,SAAS,IAAI,KAAK,UAAU,SAAS,IAAI,GAAG;AACtE,UAAM,QAAQ,SAAS;AAAA,EACzB;AACA,QAAM,WAAgB,aAAQ,KAAK,GAAG,SAAS,GAAG,MAAM,EAAE;AAC1D,QAAM,MAAW,cAAc,aAAQ,GAAG,GAAG,QAAQ;AACrD,MAAI,IAAI,WAAW,IAAI,KAAU,gBAAW,GAAG,GAAG;AAChD,UAAM,QAAQ,SAAS;AAAA,EACzB;AACA,SAAO;AACT;AAEA,SAAS,QAAQ,WAA4B;AAC3C,SAAO,IAAI,QAAQ;AAAA,IACjB,SAAS,sBAAsB,SAAS;AAAA,IACxC,MAAM,YAAY;AAAA,IAClB,MAAM;AAAA,IACN,SAAS,EAAE,QAAQ,iBAAiB;AAAA,EACtC,CAAC;AACH;;;ACjCA,SAAS,kBAAkB;AAC3B,YAAY,QAAQ;AACpB,YAAYC,WAAU;AAkHf,SAAS,YAAY,SAAyB;AACnD,SAAO,WAAW,QAAQ,EAAE,OAAY,cAAQ,OAAO,CAAC,EAAE,OAAO,KAAK,EAAE,MAAM,GAAG,EAAE;AACrF;AAMO,SAAS,YAAY,SAAyB;AACnD,QAAM,OAAO,QAAa,eAAS,OAAO,CAAC;AAC3C,QAAM,OAAO,WAAW,QAAQ,EAAE,OAAY,cAAQ,OAAO,CAAC,EAAE,OAAO,KAAK,EAAE,MAAM,GAAG,CAAC;AACxF,SAAO,GAAG,IAAI,IAAI,IAAI;AACxB;AAGA,SAAS,QAAQ,MAAsB;AACrC,SACE,KACG,YAAY,EAEZ,QAAQ,eAAe,GAAG,EAC1B,QAAQ,YAAY,EAAE,EACtB,MAAM,GAAG,EAAE,KAAK;AAEvB;AAqBO,SAAS,mBAA2B;AACzC,QAAM,UAAU,QAAQ,IAAI,iBAAiB;AAC7C,MAAI,WAAW,QAAQ,KAAK,EAAE,SAAS,EAAG,QAAY,cAAQ,OAAO;AACrE,SAAY,WAAQ,WAAQ,GAAG,aAAa;AAC9C;AAEO,SAAS,mBAAmB,MAAsC;AAGvE,QAAM,aACJ,KAAK,eAAe,KAAK,WAAgB,WAAK,KAAK,UAAU,aAAa,IAAI,iBAAiB;AAKjG,QAAM,UAAU,KAAK,YAAe,WAAQ;AAC5C,QAAM,OAAO,YAAY,KAAK,WAAW;AACzC,QAAM,OAAO,YAAY,KAAK,WAAW;AACzC,QAAM,aAAkB,WAAK,YAAY,YAAY,IAAI;AACzD,SAAO;AAAA,IACL;AAAA,IACA,aAAa,KAAK;AAAA,IAClB;AAAA,IACA,WAAW;AAAA,IACX,cAAmB,WAAK,YAAY,aAAa;AAAA,IACjD,YAAiB,WAAK,YAAY,MAAM;AAAA,IACxC,cAAmB,WAAK,YAAY,WAAW;AAAA,IAC/C,cAAmB,WAAK,YAAY,QAAQ;AAAA,IAC5C,oBAAyB,WAAK,SAAS,WAAW,QAAQ;AAAA,IAC1D,kBAAuB,WAAK,YAAY,aAAa;AAAA,IACrD,eAAoB,WAAK,YAAY,SAAS;AAAA,IAC9C,oBAAyB,WAAK,YAAY,cAAc;AAAA,IACxD,aAAkB,WAAK,YAAY,mBAAmB;AAAA,IACtD,UAAe,WAAK,YAAY,OAAO;AAAA,IACvC,aAAkB,WAAK,YAAY,SAAS,iBAAiB;AAAA,IAC7D,oBAAyB,WAAK,YAAY,SAAS,qBAAqB;AAAA,IACxE,aAAkB,WAAK,YAAY,SAAS;AAAA,IAC5C,SAAc,WAAK,YAAY,QAAQ,gBAAgB;AAAA,IACvD;AAAA,IACA,sBAA2B,WAAK,YAAY,gBAAgB;AAAA,IAC5D,eAAoB,WAAK,YAAY,WAAW;AAAA,IAChD,iBAAsB,WAAK,YAAY,UAAU;AAAA,IACjD,cAAmB,WAAK,YAAY,YAAY;AAAA,IAChD,aAAkB,WAAK,YAAY,WAAW;AAAA,IAC9C,oBAAyB,WAAK,YAAY,mBAAmB;AAAA,IAC7D,iBAAsB,WAAK,KAAK,aAAa,eAAe,aAAa;AAAA,IACzE,qBAA0B,WAAK,KAAK,aAAa,eAAe,WAAW;AAAA,IAC3E,iBAAsB,WAAK,KAAK,aAAa,eAAe,QAAQ;AAAA,IACpE,uBAA4B,WAAK,KAAK,aAAa,WAAW,QAAQ;AAAA,IACtE,kBAAuB,WAAK,KAAK,aAAa,eAAe,SAAS;AAAA,IACtE,uBAA4B,WAAK,KAAK,aAAa,eAAe,cAAc;AAAA,IAChF,qBAA0B,WAAK,KAAK,aAAa,eAAe,aAAa;AAAA,IAC7E,oBAAyB,WAAK,KAAK,aAAa,eAAe,WAAW;AAAA,IAC1E,aAAa;AAAA,IACb,aAAa;AAAA,IACb,aAAkB,WAAK,YAAY,WAAW;AAAA,IAC9C,qBAA0B,WAAK,YAAY,oBAAoB;AAAA,IAC/D,cAAmB,WAAK,YAAY,OAAO;AAAA,IAC3C,mBAAwB,WAAK,YAAY,aAAa;AAAA,IACtD,mBAAwB,WAAK,YAAY,kBAAkB;AAAA,IAC3D,aAAkB,WAAK,YAAY,WAAW;AAAA,IAC9C,kBAAuB,WAAK,YAAY,WAAW;AAAA,IACnD,kBAAuB,WAAK,YAAY,YAAY;AAAA,IACpD,YAAiB,WAAK,YAAY,WAAW;AAAA,IAC7C,eAAe,CAACC,iBAA6B,WAAK,YAAY,YAAYA,cAAa,aAAa;AAAA,EACtG;AACF;;;AC3MO,IAAM,cAAc;AAAA;AAAA,EAEzB,uBAAuB;AAAA,EACvB,sBAAsB;AAAA,EACtB,qBAAqB;AAAA,EACrB,0BAA0B;AAAA,EAC1B,uBAAuB;AAAA,EACvB,wBAAwB;AAAA,EACxB,2BAA2B;AAAA;AAAA,EAE3B,gBAAgB;AAAA,EAChB,wBAAwB;AAAA,EACxB,uBAAuB;AAAA,EACvB,cAAc;AAAA,EACd,oBAAoB;AAAA;AAAA,EAEpB,gBAAgB;AAAA,EAChB,kBAAkB;AAAA,EAClB,qBAAqB;AAAA,EACrB,yBAAyB;AAAA;AAAA,EAEzB,oBAAoB;AAAA,EACpB,qBAAqB;AAAA,EACrB,2BAA2B;AAAA;AAAA,EAE3B,uBAAuB;AAAA,EACvB,wBAAwB;AAAA,EACxB,eAAe;AAAA,EACf,kBAAkB;AAAA;AAAA,EAElB,mBAAmB;AAAA,EACnB,mBAAmB;AAAA,EACnB,sBAAsB;AAAA;AAAA,EAEtB,+BAA+B;AAAA,EAC/B,2BAA2B;AAAA,EAC3B,+BAA+B;AAAA,EAC/B,oBAAoB;AAAA,EACpB,oBAAoB;AAAA,EACpB,kBAAkB;AAAA;AAAA,EAElB,gBAAgB;AAAA,EAChB,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,kBAAkB;AAAA,EAClB,wBAAwB;AAAA;AAAA,EAExB,uBAAuB;AAAA,EACvB,kBAAkB;AAAA,EAClB,mBAAmB;AAAA,EACnB,eAAe;AAAA;AAAA,EAEf,kBAAkB;AAAA,EAClB,cAAc;AAAA,EACd,SAAS;AACX;AAwBO,IAAM,kBAAN,cAA8B,MAAM;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAET,YAAY,MAQT;AACD,UAAM,KAAK,SAAS,EAAE,OAAO,KAAK,MAAM,CAAC;AACzC,SAAK,OAAO;AACZ,SAAK,OAAO,KAAK;AACjB,SAAK,YAAY,KAAK;AACtB,SAAK,WAAW,KAAK,YAAY;AACjC,SAAK,cAAc,KAAK,eAAe;AACvC,SAAK,UAAU,KAAK;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,WAAmB;AACjB,UAAM,MAAM,KAAK,UAAU,IAAI,cAAc,KAAK,OAAO,CAAC,KAAK;AAC/D,WAAO,GAAG,KAAK,IAAI,KAAK,KAAK,OAAO,GAAG,GAAG;AAAA,EAC5C;AACF;AAEA,SAAS,cAAc,KAAsC;AAC3D,QAAM,QAAQ,OAAO,QAAQ,GAAG,EAC7B,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,MAAM,MAAS,EACjC,MAAM,GAAG,CAAC,EACV,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,CAAC,CAAC,EAAE;AACtC,SAAO,MAAM,SAAS,IAAI,IAAI,MAAM,KAAK,GAAG,CAAC,MAAM;AACrD;AAsMO,IAAM,UAAN,cAAsB,gBAAgB;AAAA,EAClC;AAAA,EAET,YAAY,MAST;AACD,UAAM;AAAA,MACJ,SAAS,KAAK;AAAA,MACd,MAAM,KAAK;AAAA,MACX,WAAW;AAAA,MACX,UAAU;AAAA,MACV,aAAa,KAAK,SAAS,YAAY;AAAA,MACvC,SAAS,EAAE,MAAM,KAAK,MAAM,GAAG,KAAK,QAAQ;AAAA,MAC5C,OAAO,KAAK;AAAA,IACd,CAAC;AACD,SAAK,OAAO;AACZ,SAAK,OAAO,KAAK;AAAA,EACnB;AACF;;;AHhWA,eAAsB,YACpB,YACA,SACA,OAA2B,CAAC,GACb;AACf,QAAM,MAAW,cAAQ,UAAU;AACnC,QAAS,SAAM,KAAK,EAAE,WAAW,KAAK,CAAC;AACvC,QAAM,MAAW,WAAK,KAAK,IAAS,eAAS,UAAU,CAAC,IAAI,YAAY,CAAC,EAAE,SAAS,KAAK,CAAC,MAAM;AAIhG,MAAI;AACF,QAAI,OAAO,YAAY,UAAU;AAC/B,YAAS,aAAU,KAAK,SAAS,EAAE,MAAM,MAAM,UAAU,KAAK,YAAY,OAAO,CAAC;AAAA,IACpF,OAAO;AACL,YAAS,aAAU,KAAK,SAAS,EAAE,MAAM,KAAK,CAAC;AAAA,IACjD;AACA,QAAI;AACF,YAAM,KAAK,MAAS,QAAK,KAAK,IAAI;AAClC,UAAI;AACF,cAAM,GAAG,KAAK;AAAA,MAChB,UAAE;AACA,cAAM,GAAG,MAAM;AAAA,MACjB;AAAA,IACF,QAAQ;AAAA,IAER;AAGA,QAAI;AACJ,QAAI;AACF,YAAMC,QAAO,MAAS,QAAK,UAAU;AACrC,aAAOA,MAAK,OAAO;AAAA,IACrB,QAAQ;AACN,aAAO,KAAK;AAAA,IACd;AACA,QAAI,SAAS,QAAW;AACtB,YAAS,SAAM,KAAK,IAAI;AAAA,IAC1B;AACA,UAAM,gBAAgB,KAAK,UAAU;AASrC,QAAI,SAAS,UAAa,QAAQ,aAAa,SAAS;AACtD,UAAI;AACF,cAAS,SAAM,YAAY,IAAI;AAAA,MACjC,QAAQ;AAAA,MAGR;AAAA,IACF;AAAA,EACF,SAAS,KAAK;AACZ,QAAI;AACF,YAAS,UAAO,GAAG;AAAA,IACrB,QAAQ;AAAA,IAER;AACA,UAAM;AAAA,EACR;AACF;AAMA,eAAsB,aACpB,YACA,IACA,OAAwB,CAAC,GACb;AACZ,QAAM,MAAW,cAAQ,UAAU;AACnC,QAAS,SAAM,KAAK,EAAE,WAAW,KAAK,CAAC;AACvC,QAAM,WAAgB,WAAK,KAAK,IAAS,eAAS,UAAU,CAAC,OAAO;AACpE,QAAM,YAAY,KAAK,aAAa;AACpC,QAAM,UAAU,KAAK,WAAW;AAChC,QAAM,UAAU,KAAK,IAAI;AACzB,MAAI;AAEJ,aAAS;AACP,QAAI;AACF,eAAS,MAAS,QAAK,UAAU,IAAI;AACrC,YAAM,OAAO,UAAU,GAAG,QAAQ,GAAG,IAAI,KAAK,IAAI,CAAC,EAAE;AACrD;AAAA,IACF,SAAS,KAAK;AACZ,YAAM,OAAQ,IAA8B;AAG5C,UAAI,SAAS,UAAU;AACrB,cAAS,SAAM,KAAK,EAAE,WAAW,KAAK,CAAC;AACvC;AAAA,MACF;AACA,UAAI,SAAS,SAAU,OAAM;AAC7B,UAAI;AACF,cAAMC,QAAO,MAAS,QAAK,QAAQ;AACnC,YAAI,KAAK,IAAI,IAAIA,MAAK,UAAU,SAAS;AACvC,gBAAS,UAAO,QAAQ;AACxB;AAAA,QACF;AAAA,MACF,QAAQ;AACN;AAAA,MACF;AACA,UAAI,KAAK,IAAI,IAAI,WAAW,WAAW;AACrC,cAAM,IAAI,QAAQ;AAAA,UAChB,SAAS,oCAAoC,UAAU;AAAA,UACvD,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS,EAAE,UAAU;AAAA,QACvB,CAAC;AAAA,MACH;AACA,YAAM,IAAI,QAAQ,CAACC,aAAY,WAAWA,UAAS,EAAE,CAAC;AAAA,IACxD;AAAA,EACF;AAEA,MAAI;AACF,WAAO,MAAM,GAAG;AAAA,EAClB,UAAE;AACA,QAAI;AACF,YAAM,QAAQ,MAAM;AAAA,IACtB,QAAQ;AAAA,IAER;AACA,QAAI;AACF,YAAS,UAAO,QAAQ;AAAA,IAC1B,QAAQ;AAAA,IAER;AAAA,EACF;AACF;AAMA,IAAM,yBAAyB,oBAAI,IAAI,CAAC,SAAS,SAAS,UAAU,WAAW,CAAC;AAEhF,eAAe,gBAAgB,MAAc,IAA2B;AACtE,MAAI,QAAQ,aAAa,SAAS;AAChC,UAAS,UAAO,MAAM,EAAE;AACxB;AAAA,EACF;AACA,QAAM,SAAS,CAAC,IAAI,IAAI,IAAI,KAAK,GAAG;AACpC,MAAI;AACJ,WAAS,IAAI,GAAG,KAAK,OAAO,QAAQ,KAAK;AACvC,QAAI;AACF,YAAS,UAAO,MAAM,EAAE;AACxB;AAAA,IACF,SAAS,KAAK;AACZ,gBAAU;AACV,YAAM,OAAQ,KAA+B;AAC7C,UAAI,CAAC,QAAQ,CAAC,uBAAuB,IAAI,IAAI,KAAK,MAAM,OAAO,QAAQ;AACrE,cAAM;AAAA,MACR;AACA,YAAM,IAAI,QAAQ,CAACA,aAAY,WAAWA,UAAS,OAAO,CAAC,CAAC,CAAC;AAAA,IAC/D;AAAA,EACF;AACA,QAAM;AACR;;;AIhKO,IAAM,iBAAiB;AAGvB,IAAM,kBAAkB;AAGxB,IAAM,wBAAwB;AAO9B,IAAM,wBAAwB;AAG9B,IAAM,iBAAiB;AAQvB,IAAM,4BAA4B;AAmBlC,IAAM,2BAA2B;AAOjC,IAAM,+BAA+B;AAQrC,IAAM,8BAA8B;;;ACnE3C,IAAM,gBAAgB,oBAAI,IAAwB;AAAA,EAChD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,IAAM,aAAa,oBAAI,IAAgC,CAAC,OAAO,UAAU,MAAM,CAAC;AAChF,IAAM,gBAAgB,oBAAI,IAAI;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,SAAS,SAAS,OAAkD;AAClE,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAAS,eAAe,QAAiC,KAAqB;AAC5E,QAAM,QAAQ,OAAO,GAAG;AACxB,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM,IAAI,UAAU,0BAA0B,GAAG,oBAAoB;AAAA,EACvE;AACA,SAAO;AACT;AAEA,SAAS,eAAe,QAAiC,KAAqC;AAC5F,QAAM,QAAQ,OAAO,GAAG;AACxB,MAAI,UAAU,OAAW,QAAO,CAAC;AACjC,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM,IAAI,UAAU,0BAA0B,GAAG,iCAAiC;AAAA,EACpF;AACA,SAAO,EAAE,CAAC,GAAG,GAAG,MAAM;AACxB;AAEA,SAAS,iBAAiB,OAAoC;AAC5D,MAAI,UAAU,OAAQ,QAAO;AAC7B,MAAI,UAAU,OAAQ,QAAO;AAC7B,MAAI,OAAO,UAAU,YAAY,cAAc,IAAI,KAA2B,GAAG;AAC/E,WAAO;AAAA,EACT;AACA,QAAM,IAAI,UAAU,yCAAyC;AAC/D;AAGO,SAAS,4BAA4B,OAAoC;AAC9E,SAAO,iBAAiB,KAAK;AAC/B;AAEA,SAAS,cAAc,OAA4C;AACjE,MAAI,OAAO,UAAU,YAAY,WAAW,IAAI,KAAmC,GAAG;AACpF,WAAO;AAAA,EACT;AAGA,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,QAAM,IAAI,UAAU,mDAAmD;AACzE;AAEA,SAAS,kBAAkB,QAAiC,IAA0B;AACpF,QAAM,QAAQ,OAAO,QAAQ;AAC7B,MAAI,UAAU,QAAW;AACvB,UAAM,eAAe,OAAO,QAAQ;AACpC,WAAO,OAAO,MAAM,MAAM,QAAQ,OAAO,iBAAiB,WACtD,EAAE,CAAC,MAAM,SAAS,GAAG,aAAa,IAClC,CAAC;AAAA,EACP;AACA,MAAI,CAAC,SAAS,KAAK,GAAG;AACpB,UAAM,IAAI,UAAU,kDAAkD;AAAA,EACxE;AAEA,QAAM,WAAyB,CAAC;AAChC,aAAW,CAAC,SAAS,SAAS,KAAK,OAAO,QAAQ,KAAK,GAAG;AACxD,QAAI,OAAO,cAAc,UAAU;AACjC,YAAM,IAAI,UAAU,yDAAyD;AAAA,IAC/E;AACA,aAAS,OAAO,IAAI;AAAA,EACtB;AACA,SAAO;AACT;AAEA,SAAS,iBAAiB,OAAgD;AACxE,MAAI,UAAU,OAAW,QAAO;AAChC,MAAI,CAAC,SAAS,KAAK,GAAG;AACpB,UAAM,IAAI,UAAU,uDAAuD;AAAA,EAC7E;AAEA,QAAM,SAAS,MAAM,QAAQ;AAC7B,MACE,WAAW,WACV,OAAO,WAAW,YACjB,CAAC,cAAc,IAAI,MAAmD,IACxE;AACA,UAAM,IAAI,UAAU,+CAA+C;AAAA,EACrE;AAEA,SAAO;AAAA,IACL,GAAG,eAAe,OAAO,WAAW;AAAA,IACpC,GAAG,eAAe,OAAO,WAAW;AAAA,IACpC,GAAG,eAAe,OAAO,QAAQ;AAAA,IACjC,GAAI,WAAW,SACX,CAAC,IACD,EAAE,OAA4D;AAAA,EACpE;AACF;AAGO,SAAS,oBAAoB,OAAgC;AAClE,MAAI,CAAC,SAAS,KAAK,EAAG,OAAM,IAAI,UAAU,mCAAmC;AAE7E,QAAM,KAAK,MAAM,IAAI,MAAM,SAAY,KAAK,eAAe,OAAO,IAAI;AACtE,QAAM,YAAY,MAAM,WAAW;AACnC,MAAI,OAAO,cAAc,WAAW;AAClC,UAAM,IAAI,UAAU,qDAAqD;AAAA,EAC3E;AAEA,QAAM,cAAc,iBAAiB,MAAM,aAAa,CAAC;AACzD,SAAO;AAAA,IACL,IAAI,eAAe,OAAO,IAAI;AAAA,IAC9B,MAAM,eAAe,OAAO,MAAM;AAAA,IAClC;AAAA,IACA,MAAM,iBAAiB,MAAM,MAAM,CAAC;AAAA,IACpC,SAAS,eAAe,OAAO,SAAS;AAAA,IACxC,MAAM,eAAe,OAAO,MAAM;AAAA,IAClC,UAAU,cAAc,MAAM,UAAU,CAAC;AAAA,IACzC,QAAQ,kBAAkB,OAAO,EAAE;AAAA,IACnC;AAAA,IACA,WAAW,eAAe,OAAO,WAAW;AAAA,IAC5C,GAAG,eAAe,OAAO,aAAa;AAAA,IACtC,GAAG,eAAe,OAAO,SAAS;AAAA,IAClC,GAAG,eAAe,OAAO,aAAa;AAAA,IACtC,GAAG,eAAe,OAAO,WAAW;AAAA,IACpC,GAAG,eAAe,OAAO,WAAW;AAAA,IACpC,GAAG,eAAe,OAAO,SAAS;AAAA,IAClC,GAAG,eAAe,OAAO,iBAAiB;AAAA,IAC1C,GAAG,eAAe,OAAO,WAAW;AAAA,IACpC,GAAI,gBAAgB,SAAY,CAAC,IAAI,EAAE,YAAY;AAAA,EACrD;AACF;AAGO,SAAS,wBAAwB,MAA8B;AACpE,SAAO,oBAAoB,KAAK,MAAM,IAAI,CAAY;AACxD;;;AC6DO,SAAS,mBAAmB,IAAoB;AACrD,SAAO,GAAG,KAAK,EAAE,YAAY,MAAM,QAAQ,MAAM,GAAG,KAAK;AAC3D;;;APtKA,IAAM,eAAe;AACrB,IAAM,uBAAuB;AA8DtB,IAAM,gBAAN,MAAuC;AAAA;AAAA,EAEnC;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEQ;AAAA;AAAA,EAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOD,iBAAsD;AAAA;AAAA,EAEtD,mBAAmB;AAAA;AAAA;AAAA;AAAA;AAAA,EAKnB,uBAA6D;AAAA;AAAA,EAE7D,yBAAyB;AAAA;AAAA,EAEzB,iBAAiB,oBAAI,IAAoB;AAAA;AAAA,EAEzC,uBAAuB,oBAAI,IAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAU/C,gBAAyC;AAAA;AAAA,EAEzC,qBAAqB;AAAA;AAAA,EAErB,oBAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWpB,aAAwC,QAAQ,QAAQ,CAAC,CAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoB9E,kBAAmD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOnD,eAAgD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQxD,YACE,YACA,QACA,aACA,cACA;AACA,SAAK,cAAmB,WAAK,YAAY,YAAY;AACrD,SAAK,eAAoB,WAAK,YAAY,wBAAwB;AAClE,SAAK,qBAA0B,WAAK,YAAY,oBAAoB;AACpE,SAAK,UAAU;AACf,SAAK,eAAe;AACpB,SAAK,eAAe;AAAA,EACtB;AAAA,EAEA,IAAY,cAAsB;AAChC,WAAO,GAAQ,eAAc,cAAQ,KAAK,WAAW,CAAC,CAAC;AAAA,EACzD;AAAA,EAEA,IAAY,cAAuC;AACjD,WAAO,OAAO,KAAK,iBAAiB,aAAa,KAAK,aAAa,IAAI,KAAK;AAAA,EAC9E;AAAA,EAEQ,sBAAsB,OAAgE;AAC5F,QAAI;AACF,WAAK,aAAa,oBAAoB,KAAK;AAAA,IAC7C,QAAQ;AAAA,IAER;AAAA,EACF;AAAA,EAEQ,2BAAiC;AACvC,UAAM,YAAY,KAAK;AACvB,QAAI,cAAc,OAAW;AAC7B,SAAK,UAAU,uBAAuB,MAAM,EAAE,WAAW,KAAK,YAAY,CAAC,EAAE,MAAM,MAAM;AAAA,IAEzF,CAAC;AAAA,EACH;AAAA;AAAA,EAIA,MAAM,KAAK,OAAkD;AAC3D,UAAM,OAAM,oBAAI,KAAK,GAAE,YAAY;AACnC,UAAM,MAAsB;AAAA,MAC1B,IAAIC,YAAW;AAAA,MACf,MAAM,MAAM;AAAA;AAAA;AAAA,MAGZ,IAAI,mBAAmB,MAAM,EAAE;AAAA,MAC/B,MAAM,4BAA4B,MAAM,IAAI;AAAA,MAC5C,SAAS,MAAM;AAAA,MACf,MAAM,MAAM;AAAA,MACZ,UAAU,MAAM,YAAY;AAAA,MAC5B,QAAQ,CAAC;AAAA,MACT,WAAW;AAAA,MACX,WAAW;AAAA,MACX,SAAS,MAAM;AAAA,MACf,aAAa,MAAM;AAAA,MACnB,WACE,MAAM,UAAU,SAAY,IAAI,KAAK,KAAK,IAAI,IAAI,MAAM,KAAK,EAAE,YAAY,IAAI;AAAA,IACnF;AAEA,UAAM,OAAO,KAAK,UAAU,GAAG,IAAI;AACnC,UAAU,UAAW,cAAQ,KAAK,WAAW,GAAG,EAAE,WAAW,KAAK,CAAC;AAInE,UAAM,aAAa,KAAK,aAAa,YAAY;AAC/C,YAAU,eAAW,KAAK,aAAa,MAAM,MAAM;AAKnD,YAAM,EAAE,SAAS,KAAK,IAAI,MAAM,KAAK,iBAAiB;AAItD,WAAK,aAAa,KAAK,SAAS,IAAI;AAAA,IACtC,CAAC;AAED,SAAK,sBAAsB;AAAA,MACzB,WAAW,KAAK;AAAA,MAChB,QAAQ;AAAA,MACR,SAAS;AAAA,IACX,CAAC;AACD,SAAK,yBAAyB;AAK9B,SAAK,SAAS,WAAW,wBAAwB;AAAA,MAC/C,WAAW,IAAI;AAAA,MACf,MAAM,IAAI;AAAA,MACV,IAAI,IAAI;AAAA,MACR,MAAM,IAAI;AAAA,MACV,SAAS,IAAI;AAAA,IACf,CAAC;AAED,SAAK,cAAc,KAAK;AAAA,MACtB,MAAM;AAAA,MACN,WAAW,IAAI;AAAA,MACf,MAAM,IAAI;AAAA,MACV,IAAI,IAAI;AAAA,MACR,WAAW;AAAA,IACb,CAAC;AAED,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,MAAM,GAA4C;AACtD,UAAM,YAAY,EAAE,SAAS,SAAY,SAAY,4BAA4B,EAAE,IAAI;AACvF,UAAM,MAAM,MAAM,KAAK,oBAAoB;AAC3C,UAAM,QAAQ,EAAE,SAAS;AAKzB,UAAM,QAAQ,EAAE,gBAAgB,SAAa,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,EAAE,IAAc;AACxF,UAAM,kBAAkB,SAAS,EAAE,gBAAgB,SAAY,MAAM,EAAE,WAAW,IAAI;AACtF,UAAM,MAAwB,CAAC;AAY/B,QAAI;AACJ,QACE,EAAE,OAAO,UACT,KAAK,oBAAoB,QACzB,EAAE,SAAS,UACX,EAAE,SAAS,UACX,EAAE,gBAAgB,QAClB;AAEA,YAAM,UAAU,oBAAI,IAAY;AAChC,YAAM,SAAS,KAAK,gBAAgB,IAAI,EAAE,EAAE;AAC5C,UAAI,WAAW,OAAW,YAAW,KAAK,OAAQ,SAAQ,IAAI,CAAC;AAC/D,YAAM,aAAa,KAAK,gBAAgB,IAAI,GAAG;AAC/C,UAAI,eAAe,OAAW,YAAW,KAAK,WAAY,SAAQ,IAAI,CAAC;AACvE,mBAAa,CAAC,GAAG,OAAO,EAAE,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC,EAAE,IAAI,CAAC,MAAM,IAAI,CAAC,CAAE;AAAA,IACpE,WACE,EAAE,SAAS,UACX,EAAE,OAAO,UACT,KAAK,iBAAiB,QACtB,EAAE,SAAS,UACX,EAAE,gBAAgB,QAClB;AAEA,YAAM,UAAU,KAAK,aAAa,IAAI,EAAE,IAAI;AAC5C,mBACE,YAAY,SAAY,CAAC,GAAG,OAAO,EAAE,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC,EAAE,IAAI,CAAC,MAAM,IAAI,CAAC,CAAE,IAAI,CAAC;AAAA,IACtF,OAAO;AACL,mBAAa;AAAA,IACf;AAEA,eAAW,KAAK,YAAY;AAC1B,UAAI,EAAE,OAAO,UAAa,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,IAAK;AACzD,UAAI,EAAE,SAAS,UAAa,EAAE,SAAS,EAAE,KAAM;AAC/C,UAAI,EAAE,aAAa,UAAa,EAAE,YAAY,EAAE,OAAQ;AACxD,UAAI,EAAE,kBAAkB,EAAE,UAAW;AACrC,UAAI,cAAc,UAAa,EAAE,SAAS,UAAW;AACrD,UAAI,UAAU,SAAS,MAAM,EAAE,QAA8B,KAAK,KAAK,iBAAkB;AACvF;AAAA,MACF;AACA,UAAI,EAAE,UAAU,UAAa,EAAE,aAAa,EAAE,MAAO;AAIrD,UAAI,CAAC,EAAE,kBAAkB,EAAE,cAAc,OAAW;AACpD,UAAI,KAAK,CAAC;AAAA,IACZ;AAEA,QAAI,KAAK,CAAC,GAAG,MAAM,EAAE,UAAU,cAAc,EAAE,SAAS,CAAC;AAGzD,WAAO,IAAI,MAAM,GAAG,KAAK,EAAE,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE;AAAA,EAC3E;AAAA,EAEA,MAAM,IAAI,OAAwD;AAChE,UAAM,UAAU,MAAM,KAAK,QAAQ,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC;AACpD,WAAO,QAAQ,SAAS,IAAI,QAAQ,CAAC,IAAK;AAAA,EAC5C;AAAA,EAEA,MAAM,QAAQ,OAAwD;AAIpE,QAAI,MAAM,KAAK,WAAW,EAAG,QAAO,CAAC;AAErC,UAAM,UAA4B,CAAC;AACnC,UAAM,OAAO,oBAAI,IAA6B;AAC9C,eAAW,KAAK,MAAM,MAAM;AAG1B,WAAK,IAAI,EAAE,WAAW,CAAC;AAAA,IACzB;AAEA,UAAM,aAAa,KAAK,aAAa,YAAY;AAG/C,YAAM,MAAM,MAAM,KAAK,mBAAmB;AAC1C,YAAM,OAAM,oBAAI,KAAK,GAAE,YAAY;AACnC,UAAI,UAAU;AAEd,iBAAW,OAAO,KAAK;AACrB,cAAM,IAAI,KAAK,IAAI,IAAI,EAAE;AACzB,YAAI,CAAC,EAAG;AAGR,gBAAQ,KAAK,GAAG;AAChB,YAAI,EAAE,SAAS,SAAS,EAAE,EAAE,YAAY,IAAI,SAAS;AACnD,cAAI,OAAO,EAAE,QAAQ,IAAI;AACzB,oBAAU;AAAA,QACZ;AACA,YAAI,EAAE,aAAa,CAAC,IAAI,WAAW;AACjC,cAAI,YAAY;AAChB,cAAI,cAAc,EAAE;AACpB,cAAI,cAAc;AAClB,oBAAU;AAAA,QACZ;AACA,YAAI,EAAE,YAAY,UAAa,IAAI,YAAY,EAAE,SAAS;AACxD,cAAI,UAAU,EAAE;AAChB,oBAAU;AAAA,QACZ;AAAA,MACF;AAKA,UAAI,SAAS;AACX,cAAM,aAAa,IAAI,IAAI,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,EAAE,KAAK,cAAc,IAAI;AAC5E,cAAU,cAAU,KAAK,aAAa,YAAY,MAAM;AAAA,MAC1D;AAMA,YAAM,EAAE,SAAS,KAAK,IAAI,MAAM,KAAK,iBAAiB;AACtD,WAAK,iBAAiB,KAAK,SAAS,IAAI;AAAA,IAC1C,CAAC;AAED,eAAW,WAAW,SAAS;AAC7B,WAAK,sBAAsB;AAAA,QACzB,WAAW,KAAK;AAAA,QAChB,QAAQ,QAAQ,YAAY,sBAAsB;AAAA,QAClD;AAAA,MACF,CAAC;AAED,WAAK,cAAc,KAAK;AAAA,QACtB,MAAM;AAAA,QACN,WAAW,QAAQ;AAAA,QACnB,MAAM,QAAQ;AAAA,QACd,IAAI,QAAQ;AAAA,QACZ,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MACpC,CAAC;AAAA,IACH;AACA,QAAI,QAAQ,SAAS,EAAG,MAAK,yBAAyB;AACtD,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,YAAY,YAAqC;AACrD,UAAM,MAAM,MAAM,KAAK,oBAAoB;AAC3C,QAAI,QAAQ;AAIZ,QAAI,KAAK,oBAAoB,MAAM;AACjC,YAAM,UAAU,oBAAI,IAAY;AAChC,YAAM,SAAS,KAAK,gBAAgB,IAAI,UAAU;AAClD,UAAI,WAAW,OAAW,YAAW,KAAK,OAAQ,SAAQ,IAAI,CAAC;AAC/D,YAAM,aAAa,KAAK,gBAAgB,IAAI,GAAG;AAC/C,UAAI,eAAe,OAAW,YAAW,KAAK,WAAY,SAAQ,IAAI,CAAC;AACvE,iBAAW,KAAK,SAAS;AACvB,cAAM,IAAI,IAAI,CAAC;AACf,YAAI,EAAE,cAAc,EAAE,WAAW,CAAC,EAAE,UAAW;AAAA,MACjD;AAAA,IACF,OAAO;AACL,eAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACnC,cAAM,IAAI,IAAI,CAAC;AACf,aAAK,EAAE,OAAO,cAAc,EAAE,OAAO,QAAQ,EAAE,cAAc,EAAE,WAAW,CAAC,EAAE,WAAW;AACtF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,WAAW,QAAgB,IAA4C;AAM3E,QAAI,UAAiC;AACrC,UAAM,aAAa,KAAK,aAAa,YAAY;AAC/C,YAAM,MAAM,MAAM,KAAK,mBAAmB;AAC1C,YAAM,OAAM,oBAAI,KAAK,GAAE,YAAY;AACnC,UAAI,UAAU;AACd,iBAAW,KAAK,KAAK;AACnB,YAAI,EAAE,OAAO,OAAQ;AACrB,YAAI,EAAE,cAAc,QAAW;AAG7B,oBAAU;AACV;AAAA,QACF;AACA,UAAE,YAAY;AACd,UAAE,YAAY;AACd,kBAAU;AACV,kBAAU;AAAA,MACZ;AAGA,UAAI,SAAS;AACX,cAAM,aAAa,IAAI,IAAI,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,EAAE,KAAK,cAAc,IAAI;AAC5E,cAAU,cAAU,KAAK,aAAa,YAAY,MAAM;AAAA,MAC1D;AAGA,YAAM,EAAE,SAAS,KAAK,IAAI,MAAM,KAAK,iBAAiB;AACtD,WAAK,iBAAiB,KAAK,SAAS,IAAI;AAAA,IAC1C,CAAC;AACD,QAAI,YAAY,MAAM;AACpB,YAAM,MAAM;AACZ,WAAK,sBAAsB;AAAA,QACzB,WAAW,KAAK;AAAA,QAChB,QAAQ;AAAA,QACR,SAAS;AAAA,MACX,CAAC;AACD,WAAK,yBAAyB;AAE9B,WAAK,cAAc,KAAK;AAAA,QACtB,MAAM;AAAA,QACN,WAAW,IAAI;AAAA,QACf,MAAM,IAAI;AAAA,QACV,IAAI,IAAI;AAAA,QACR,WAAW,IAAI,cAAa,oBAAI,KAAK,GAAE,YAAY;AAAA,MACrD,CAAC;AAAA,IACH;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,QAAQ,QAAgD;AAO5D,QAAI,UAAiC;AACrC,UAAM,aAAa,KAAK,aAAa,YAAY;AAC/C,YAAM,MAAM,MAAM,KAAK,mBAAmB;AAC1C,UAAI,UAAU;AACd,iBAAW,KAAK,KAAK;AACnB,YAAI,EAAE,OAAO,OAAQ;AACrB,YAAI,EAAE,cAAc,UAAa,EAAE,cAAc,QAAW;AAE1D,oBAAU;AACV;AAAA,QACF;AACA,eAAO,EAAE;AACT,eAAO,EAAE;AACT,kBAAU;AACV,kBAAU;AAAA,MACZ;AACA,UAAI,SAAS;AACX,cAAM,aAAa,IAAI,IAAI,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,EAAE,KAAK,cAAc,IAAI;AAC5E,cAAU,cAAU,KAAK,aAAa,YAAY,MAAM;AAAA,MAC1D;AAGA,YAAM,EAAE,SAAS,KAAK,IAAI,MAAM,KAAK,iBAAiB;AACtD,WAAK,iBAAiB,KAAK,SAAS,IAAI;AAAA,IAC1C,CAAC;AACD,QAAI,YAAY,MAAM;AACpB,YAAM,MAAM;AACZ,WAAK,sBAAsB;AAAA,QACzB,WAAW,KAAK;AAAA,QAChB,QAAQ;AAAA,QACR,SAAS;AAAA,MACX,CAAC;AACD,WAAK,yBAAyB;AAE9B,WAAK,cAAc,KAAK;AAAA,QACtB,MAAM;AAAA,QACN,WAAW,IAAI;AAAA,QACf,MAAM,IAAI;AAAA,QACV,IAAI,IAAI;AAAA,QACR,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MACpC,CAAC;AAAA,IACH;AACA,WAAO;AAAA,EACT;AAAA;AAAA,EAIA,MAAM,cAAc,OAA8C;AAChE,UAAM,KAAK,gBAAgB;AAC3B,UAAM,OAAM,oBAAI,KAAK,GAAE,YAAY;AACnC,UAAM,QAAyB;AAAA,MAC7B,SAAS,MAAM;AAAA,MACf,WAAW,MAAM;AAAA,MACjB,MAAM,MAAM;AAAA,MACZ,MAAM,MAAM;AAAA,MACZ,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,aAAa;AAAA,MACb,YAAY;AAAA,MACZ,WAAW;AAAA,MACX,cAAc;AAAA,MACd,YAAY;AAAA,MACZ,KAAK,MAAM;AAAA,MACX,QAAQ,MAAM;AAAA,IAChB;AAEA,UAAM,aAAa,KAAK,cAAc,YAAY;AAGhD,YAAM,WAAW,MAAM,KAAK,cAAc,EAAE,OAAO,KAAK,CAAC;AAEzD,WAAK,mBAAmB,QAAQ;AAEhC,eAAS,IAAI,MAAM,SAAS,KAAK;AAEjC,WAAK,iBAAiB;AACtB,WAAK,mBAAmB,KAAK,IAAI;AACjC,YAAM,KAAK,eAAe,QAAQ;AAAA,IACpC,CAAC;AAGD,SAAK,SAAS,WAAW,4BAA4B;AAAA,MACnD,SAAS,MAAM;AAAA,MACf,WAAW,MAAM;AAAA,MACjB,MAAM,MAAM;AAAA,MACZ,MAAM,MAAM;AAAA,MACZ,QAAQ,MAAM;AAAA,IAChB,CAAC;AACD,SAAK,sBAAsB;AAAA,MACzB,WAAW,KAAK;AAAA,MAChB,QAAQ;AAAA,MACR,OAAO;AAAA,QACL,SAAS,MAAM;AAAA,QACf,MAAM,MAAM;AAAA,QACZ,GAAI,MAAM,SAAS,SAAY,EAAE,MAAM,MAAM,KAAK,IAAI,CAAC;AAAA,QACvD,WAAW,MAAM;AAAA,QACjB,QAAQ;AAAA,QACR,YAAY;AAAA,QACZ,WAAW;AAAA,QACX,gBAAgB;AAAA,QAChB,YAAY;AAAA,QACZ,QAAQ;AAAA,QACR,KAAK,MAAM;AAAA,QACX,GAAI,MAAM,WAAW,SAAY,EAAE,QAAQ,MAAM,OAAO,IAAI,CAAC;AAAA,MAC/D;AAAA,IACF,CAAC;AACD,SAAK,yBAAyB;AAAA,EAChC;AAAA,EAEA,MAAM,gBAAgB,SAAgC;AACpD,UAAM,KAAK,gBAAgB;AAC3B,QAAI;AACJ,UAAM,aAAa,KAAK,cAAc,YAAY;AAChD,YAAM,WAAW,MAAM,KAAK,cAAc,EAAE,OAAO,KAAK,CAAC;AACzD,WAAK,mBAAmB,QAAQ;AAGhC,gBAAU,SAAS,IAAI,OAAO;AAC9B,eAAS,OAAO,OAAO;AACvB,WAAK,iBAAiB;AACtB,WAAK,mBAAmB,KAAK,IAAI;AACjC,YAAM,KAAK,eAAe,QAAQ;AAAA,IACpC,CAAC;AACD,SAAK,SAAS,WAAW,8BAA8B;AAAA,MACrD;AAAA,IACF,CAAC;AACD,SAAK,sBAAsB;AAAA,MACzB,WAAW,KAAK;AAAA,MAChB,QAAQ;AAAA,MACR,OAAO;AAAA,QACL;AAAA,QACA,MAAM,SAAS,QAAQ;AAAA,QACvB,GAAI,SAAS,SAAS,SAAY,EAAE,MAAM,QAAQ,KAAK,IAAI,CAAC;AAAA,QAC5D,WAAW,SAAS,aAAa;AAAA,QACjC,QAAQ;AAAA,QACR,GAAI,SAAS,gBAAgB,SAAY,EAAE,aAAa,QAAQ,YAAY,IAAI,CAAC;AAAA,QACjF,GAAI,SAAS,gBAAgB,SAAY,EAAE,aAAa,QAAQ,YAAY,IAAI,CAAC;AAAA,QACjF,YAAY,SAAS,cAAc;AAAA,QACnC,WAAW,SAAS,aAAa;AAAA,QACjC,gBAAgB,SAAS,eAAc,oBAAI,KAAK,GAAE,YAAY;AAAA,QAC9D,YAAY,SAAS,eAAc,oBAAI,KAAK,GAAE,YAAY;AAAA,QAC1D,QAAQ;AAAA,QACR,KAAK,SAAS,OAAO;AAAA,QACrB,GAAI,SAAS,WAAW,SAAY,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;AAAA,MACpE;AAAA,IACF,CAAC;AACD,SAAK,yBAAyB;AAAA,EAChC;AAAA,EAEA,MAAM,UAAU,OAA2C;AAEzD,UAAM,OAAO,KAAK,eAAe,IAAI,MAAM,OAAO,KAAK;AACvD,UAAM,MAAM,KAAK,IAAI;AACrB,QAAI,MAAM,OAAO,sBAAuB;AAExC,SAAK,eAAe,IAAI,MAAM,SAAS,GAAG;AAE1C,UAAM,KAAK,gBAAgB;AAE3B,UAAM,aAAa,KAAK,cAAc,YAAY;AAEhD,YAAM,WAAW,MAAM,KAAK,cAAc,EAAE,OAAO,KAAK,CAAC;AACzD,WAAK,mBAAmB,QAAQ;AAEhC,YAAM,QAAQ,SAAS,IAAI,MAAM,OAAO;AACxC,UAAI,OAAO;AACT,cAAM,OAAM,oBAAI,KAAK,GAAE,YAAY;AACnC,cAAM,aAAa;AACnB,YAAI,MAAM,WAAW,OAAW,OAAM,SAAS,MAAM;AACrD,YAAI,MAAM,gBAAgB,OAAW,OAAM,cAAc,MAAM;AAC/D,YAAI,MAAM,gBAAgB,OAAW,OAAM,cAAc,MAAM;AAC/D,YAAI,MAAM,eAAe,OAAW,OAAM,aAAa,MAAM;AAC7D,YAAI,MAAM,cAAc,OAAW,OAAM,YAAY,MAAM;AAAA,MAC7D;AAGA,WAAK,iBAAiB;AACtB,WAAK,mBAAmB,KAAK,IAAI;AACjC,YAAM,KAAK,eAAe,QAAQ;AAAA,IACpC,CAAC;AAGD,SAAK,SAAS,WAAW,2BAA2B;AAAA,MAClD,SAAS,MAAM;AAAA,MACf,QAAQ,MAAM;AAAA,MACd,aAAa,MAAM;AAAA,MACnB,aAAa,MAAM;AAAA,IACrB,CAAC;AACD,SAAK,sBAAsB;AAAA,MACzB,WAAW,KAAK;AAAA,MAChB,QAAQ;AAAA,MACR,SAAS,MAAM;AAAA,IACjB,CAAC;AACD,SAAK,yBAAyB;AAAA,EAChC;AAAA,EAEA,MAAM,mBAAkD;AACtD,UAAM,KAAK,gBAAgB;AAC3B,QAAI,WAAW,MAAM,KAAK,cAAc;AACxC,UAAM,SAAS,SAAS;AACxB,SAAK,mBAAmB,QAAQ;AAKhC,QAAI,SAAS,OAAO,QAAQ;AAC1B,YAAM,aAAa,KAAK,cAAc,YAAY;AAChD,cAAM,QAAQ,MAAM,KAAK,cAAc,EAAE,OAAO,KAAK,CAAC;AACtD,aAAK,mBAAmB,KAAK;AAC7B,aAAK,iBAAiB;AACtB,aAAK,mBAAmB,KAAK,IAAI;AACjC,cAAM,KAAK,eAAe,KAAK;AAC/B,mBAAW;AAAA,MACb,CAAC;AAAA,IACH;AAEA,UAAM,MAAM,KAAK,IAAI;AACrB,WAAO,MAAM,KAAK,SAAS,OAAO,CAAC,EAChC,IAAI,CAAC,OAAO;AAAA,MACX,SAAS,EAAE;AAAA,MACX,MAAM,EAAE;AAAA,MACR,MAAM,EAAE;AAAA,MACR,WAAW,EAAE;AAAA,MACb,QAAQ,EAAE;AAAA,MACV,aAAa,EAAE;AAAA,MACf,aAAa,EAAE;AAAA,MACf,YAAY,EAAE;AAAA,MACd,WAAW,EAAE;AAAA,MACb,gBAAgB,EAAE;AAAA,MAClB,YAAY,EAAE;AAAA,MACd,QAAQ,MAAM,IAAI,KAAK,EAAE,UAAU,EAAE,QAAQ,IAAI;AAAA,MACjD,KAAK,EAAE;AAAA,MACP,QAAQ,EAAE;AAAA,IACZ,EAAE,EACD,KAAK,CAAC,GAAG,MAAM,EAAE,WAAW,cAAc,EAAE,UAAU,CAAC;AAAA,EAC5D;AAAA,EAEA,MAAM,kBAAiD;AACrD,UAAM,MAAM,MAAM,KAAK,iBAAiB;AACxC,WAAO,IAAI,OAAO,CAAC,MAAM,EAAE,MAAM;AAAA,EACnC;AAAA;AAAA,EAIA,MAAM,eAAe,OAA+C;AAClE,UAAM,KAAK,sBAAsB;AACjC,UAAM,OAAM,oBAAI,KAAK,GAAE,YAAY;AACnC,UAAM,SAA2B;AAAA,MAC/B,UAAU,MAAM;AAAA,MAChB,WAAW,MAAM;AAAA,MACjB,MAAM,MAAM;AAAA,MACZ,QAAQ,MAAM;AAAA,MACd,cAAc;AAAA,MACd,YAAY;AAAA,MACZ,KAAK,MAAM;AAAA,IACb;AAEA,UAAM,aAAa,KAAK,oBAAoB,YAAY;AACtD,YAAM,WAAW,MAAM,KAAK,oBAAoB,EAAE,OAAO,KAAK,CAAC;AAC/D,WAAK,0BAA0B,QAAQ;AACvC,eAAS,IAAI,MAAM,UAAU,MAAM;AACnC,WAAK,uBAAuB;AAC5B,WAAK,yBAAyB,KAAK,IAAI;AACvC,YAAM,KAAK,qBAAqB,QAAQ;AAAA,IAC1C,CAAC;AAGD,SAAK,SAAS,WAAW,6BAA6B;AAAA,MACpD,UAAU,MAAM;AAAA,MAChB,WAAW,MAAM;AAAA,MACjB,MAAM,MAAM;AAAA,MACZ,QAAQ,MAAM;AAAA,IAChB,CAAC;AACD,SAAK,yBAAyB;AAAA,EAChC;AAAA,EAEA,MAAM,iBAAiB,UAAiC;AACtD,UAAM,KAAK,sBAAsB;AACjC,UAAM,aAAa,KAAK,oBAAoB,YAAY;AACtD,YAAM,WAAW,MAAM,KAAK,oBAAoB,EAAE,OAAO,KAAK,CAAC;AAC/D,WAAK,0BAA0B,QAAQ;AACvC,eAAS,OAAO,QAAQ;AACxB,WAAK,uBAAuB;AAC5B,WAAK,yBAAyB,KAAK,IAAI;AACvC,YAAM,KAAK,qBAAqB,QAAQ;AAAA,IAC1C,CAAC;AACD,SAAK,qBAAqB,OAAO,QAAQ;AACzC,SAAK,SAAS,WAAW,+BAA+B,EAAE,SAAS,CAAC;AACpE,SAAK,yBAAyB;AAAA,EAChC;AAAA,EAEA,MAAM,gBAAgB,OAA4C;AAEhE,UAAM,OAAO,KAAK,qBAAqB,IAAI,MAAM,QAAQ,KAAK;AAC9D,UAAM,MAAM,KAAK,IAAI;AACrB,QAAI,MAAM,OAAO,sBAAuB;AAExC,SAAK,qBAAqB,IAAI,MAAM,UAAU,GAAG;AAEjD,UAAM,KAAK,sBAAsB;AAEjC,UAAM,aAAa,KAAK,oBAAoB,YAAY;AACtD,YAAM,WAAW,MAAM,KAAK,oBAAoB,EAAE,OAAO,KAAK,CAAC;AAC/D,WAAK,0BAA0B,QAAQ;AAEvC,YAAM,SAAS,SAAS,IAAI,MAAM,QAAQ;AAC1C,UAAI,QAAQ;AACV,eAAO,cAAa,oBAAI,KAAK,GAAE,YAAY;AAC3C,YAAI,OAAO,MAAM,cAAc,YAAY,MAAM,UAAU,SAAS,GAAG;AACrE,iBAAO,YAAY,MAAM;AAAA,QAC3B;AAAA,MACF;AAEA,WAAK,uBAAuB;AAC5B,WAAK,yBAAyB,KAAK,IAAI;AACvC,YAAM,KAAK,qBAAqB,QAAQ;AAAA,IAC1C,CAAC;AAGD,SAAK,SAAS,WAAW,4BAA4B;AAAA,MACnD,UAAU,MAAM;AAAA,MAChB,GAAI,MAAM,YAAY,EAAE,WAAW,MAAM,UAAU,IAAI,CAAC;AAAA,IAC1D,CAAC;AACD,SAAK,yBAAyB;AAAA,EAChC;AAAA,EAEA,MAAM,oBAA6C;AACjD,UAAM,KAAK,sBAAsB;AACjC,UAAM,WAAW,MAAM,KAAK,oBAAoB;AAChD,UAAM,SAAS,SAAS;AACxB,SAAK,0BAA0B,QAAQ;AAOvC,QAAI,SAAS,OAAO,QAAQ;AAC1B,YAAM,KAAK,qBAAqB,QAAQ;AAAA,IAC1C;AAEA,UAAM,MAAM,KAAK,IAAI;AACrB,WAAO,MAAM,KAAK,SAAS,OAAO,CAAC,EAChC,IAAI,CAAC,OAAO;AAAA,MACX,UAAU,EAAE;AAAA,MACZ,MAAM,EAAE;AAAA,MACR,QAAQ,EAAE;AAAA,MACV,WAAW,EAAE;AAAA,MACb,YAAY,EAAE;AAAA,MACd,QAAQ,MAAM,IAAI,KAAK,EAAE,UAAU,EAAE,QAAQ,IAAI;AAAA,MACjD,KAAK,EAAE;AAAA,IACT,EAAE,EACD,KAAK,CAAC,GAAG,MAAM,EAAE,WAAW,cAAc,EAAE,UAAU,CAAC;AAAA,EAC5D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,eAAgC;AACpC,UAAM,KAAK,sBAAsB;AACjC,QAAI,SAAS;AACb,UAAM,aAAa,KAAK,oBAAoB,YAAY;AACtD,YAAM,WAAW,MAAM,KAAK,oBAAoB,EAAE,OAAO,KAAK,CAAC;AAC/D,YAAM,SAAS,SAAS;AACxB,WAAK,0BAA0B,QAAQ;AACvC,eAAS,SAAS,SAAS;AAC3B,UAAI,SAAS,GAAG;AACd,aAAK,uBAAuB;AAC5B,aAAK,yBAAyB,KAAK,IAAI;AACvC,cAAM,KAAK,qBAAqB,QAAQ;AAAA,MAC1C;AAAA,IACF,CAAC;AACD,WAAO;AAAA,EACT;AAAA;AAAA,EAIA,MAAM,QAAuB;AAE3B,SAAK,iBAAiB;AACtB,SAAK,uBAAuB;AAC5B,SAAK,gBAAgB;AACrB,SAAK,qBAAqB;AAC1B,SAAK,oBAAoB;AACzB,SAAK,kBAAkB;AACvB,SAAK,eAAe;AAAA,EACtB;AAAA,EAEA,MAAM,WAA0B;AAK9B,UAAM,aAAa,KAAK,aAAa,YAAY;AAC/C,YAAU,cAAU,KAAK,aAAa,IAAI,MAAM;AAChD,YAAM,EAAE,SAAS,KAAK,IAAI,MAAM,KAAK,iBAAiB;AACtD,WAAK,iBAAiB,CAAC,GAAG,SAAS,IAAI;AAAA,IACzC,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,WAAW,MAA2C;AAC1D,UAAM,uBAAuB,MAAM,qBAAqB;AACxD,UAAM,wBAAwB,MAAM,sBAAsB;AAE1D,QAAI,kBAAkB;AACtB,QAAI,mBAAmB;AACvB,QAAI,YAAY;AAGhB,UAAM,aAAa,KAAK,aAAa,YAAY;AAC/C,YAAM,MAAM,MAAM,KAAK,mBAAmB;AAC1C,YAAM,MAAM,KAAK,IAAI;AACrB,YAAM,kBAAkB,MAAM;AAC9B,YAAM,mBAAmB,MAAM;AAE/B,YAAM,OAAyB,CAAC;AAEhC,iBAAW,OAAO,KAAK;AACrB,cAAM,UAAU,IAAI,KAAK,IAAI,SAAS,EAAE,QAAQ;AAChD,cAAM,gBAAgB,IAAI,cAAc,IAAI,KAAK,IAAI,WAAW,EAAE,QAAQ,IAAI;AAE9E,YAAI,IAAI,aAAa,gBAAgB,iBAAiB;AACpD;AACA;AAAA,QACF;AACA,YAAI,CAAC,IAAI,aAAa,UAAU,kBAAkB;AAChD;AACA;AAAA,QACF;AAEA,aAAK,KAAK,GAAG;AAAA,MACf;AACA,kBAAY,KAAK;AAGjB,UAAI,KAAK,SAAS,IAAI,QAAQ;AAC5B,cAAM,UAAU,KAAK,IAAI,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,EAAE,KAAK,cAAc,IAAI;AAC1E,cAAU,cAAU,KAAK,aAAa,SAAS,MAAM;AAAA,MACvD;AAGA,YAAM,EAAE,SAAS,KAAK,IAAI,MAAM,KAAK,iBAAiB;AAGtD,WAAK,iBAAiB,MAAM,SAAS,IAAI;AAAA,IAC3C,CAAC;AAED,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,aAAa,kBAAkB;AAAA,MAC/B;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAIQ,oBAA2C;AAAA,EAEnD,MAAM,YAAY,MAAuD;AACvE,UAAM,eAAe,MAAM,gBAAgB;AAC3C,UAAM,eAAe,MAAM,gBAAgB;AAC3C,UAAM,oBAAoB,MAAM,qBAAqB;AACrD,UAAM,qBAAqB,MAAM,sBAAsB;AAEvD,QAAI,gBAAgB;AACpB,QAAI,kBAAkB;AACtB,QAAI,kBAAkB;AACtB,QAAI,mBAAmB;AACvB,QAAI,YAAY;AAMhB,QAAI,iBAAqC;AACzC,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,iBAAiB;AAC7C,YAAM,SAAS,SAAS,OAAO,CAAC,MAAM,EAAE,MAAM;AAC9C,uBAAiB,OAAO,SAAS,IAAI,IAAI,IAAI,OAAO,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI;AAAA,IAC/E,QAAQ;AACN,uBAAiB;AAAA,IACnB;AAEA,UAAM,aAAa,KAAK,aAAa,YAAY;AAC/C,YAAM,MAAM,MAAM,KAAK,mBAAmB;AAC1C,YAAM,MAAM,KAAK,IAAI;AACrB,YAAM,gBAAgB,MAAM;AAC5B,YAAM,kBAAkB,MAAM;AAC9B,YAAM,mBAAmB,MAAM;AAC/B,YAAM,mBAAmB,MAAM;AAE/B,YAAM,OAAyB,CAAC;AAEhC,iBAAW,OAAO,KAAK;AACrB,cAAM,UAAU,IAAI,KAAK,IAAI,SAAS,EAAE,QAAQ;AAGhD,YAAI,IAAI,cAAc,QAAW;AAC/B,cAAI,IAAI,KAAK,IAAI,SAAS,EAAE,QAAQ,IAAI,KAAK;AAC3C;AACA;AAAA,UACF;AAAA,QACF,WAAW,UAAU,kBAAkB;AAErC;AACA;AAAA,QACF;AAGA,YAAI,mBAAmB,QAAQ,CAAC,IAAI,WAAW;AAC7C,gBAAM,YACJ,eAAe,OAAO,KAAK,CAAC,GAAG,cAAc,EAAE,MAAM,CAAC,OAAO,MAAM,IAAI,MAAM;AAC/E,cAAI,WAAW;AAEb,kBAAM,YAAY,OAAO,OAAO,IAAI,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,KAAK,CAAC,EAAE,QAAQ,CAAC;AAC5E,kBAAM,aAAa,KAAK,IAAI,GAAG,SAAS;AACxC,gBAAI,aAAa,eAAe;AAC9B;AACA;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAGA,cAAM,gBAAgB,IAAI,cAAc,IAAI,KAAK,IAAI,WAAW,EAAE,QAAQ,IAAI;AAC9E,YAAI,IAAI,aAAa,gBAAgB,iBAAiB;AACpD;AACA;AAAA,QACF;AACA,YAAI,CAAC,IAAI,aAAa,UAAU,kBAAkB;AAChD;AACA;AAAA,QACF;AAEA,aAAK,KAAK,GAAG;AAAA,MACf;AACA,kBAAY,KAAK;AAEjB,UAAI,KAAK,SAAS,IAAI,QAAQ;AAC5B,cAAM,UAAU,KAAK,IAAI,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,EAAE,KAAK,cAAc,IAAI;AAC1E,cAAU,cAAU,KAAK,aAAa,SAAS,MAAM;AAAA,MACvD;AACA,YAAM,EAAE,SAAS,KAAK,IAAI,MAAM,KAAK,iBAAiB;AACtD,WAAK,iBAAiB,MAAM,SAAS,IAAI;AAAA,IAC3C,CAAC;AAED,UAAM,eAAe,gBAAgB,kBAAkB,kBAAkB;AACzE,WAAO;AAAA,MACL,gBAAgB;AAAA,MAChB,kBAAkB;AAAA,MAClB,aAAa,kBAAkB;AAAA,MAC/B;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,sBAAsB,MAAuC;AAE3D,QAAI,KAAK,sBAAsB,MAAM;AACnC,oBAAc,KAAK,iBAAiB;AAAA,IACtC;AACA,UAAM,aAAa,MAAM,cAAc;AACvC,UAAM,QAAQ,YAAY,MAAM;AAC9B,WAAK,YAAY,IAAI,EAAE,MAAM,MAAM;AAAA,MAEnC,CAAC;AAAA,IACH,GAAG,UAAU;AACb,UAAM,QAAQ;AACd,SAAK,oBAAoB;AACzB,WAAO,MAAM;AACX,oBAAc,KAAK;AACnB,WAAK,oBAAoB;AAAA,IAC3B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAc,gBAA2C;AACvD,QAAI;AACF,YAAM,MAAM,MAAU,aAAS,KAAK,aAAa,MAAM;AACvD,aAAO,KAAK,YAAY,GAAG;AAAA,IAC7B,SAAS,KAAK;AACZ,UAAK,IAA8B,SAAS,SAAU,QAAO,CAAC;AAC9D,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAc,qBACZ,IACA,SACA,SAC2B;AAC3B,UAAM,UAAU,UAAU;AAC1B,UAAM,MAAM,OAAO,MAAM,OAAO;AAChC,UAAM,GAAG,KAAK,KAAK,GAAG,SAAS,OAAO;AACtC,UAAM,OAAO,IAAI,SAAS,MAAM;AAShC,QAAI,CAAC,KAAK,SAAS,cAAc,GAAG;AAGlC,YAAM,mBAAmB,KAAK,YAAY,cAAc;AACxD,UAAI,qBAAqB,IAAI;AAG3B,eAAO,KAAK;AAAA,MACd;AAGA,YAAM,eAAe,KAAK,MAAM,GAAG,mBAAmB,CAAC;AACvD,WAAK,wBAAwB,YAAY;AAGzC,WAAK,oBAAoB,UAAU,mBAAmB;AACtD,aAAO,KAAK;AAAA,IACd;AAGA,SAAK,wBAAwB,IAAI;AAEjC,SAAK,oBAAoB;AACzB,WAAO,KAAK;AAAA,EACd;AAAA,EAEQ,wBAAwB,KAAmB;AACjD,eAAW,QAAQ,IAAI,MAAM,cAAc,GAAG;AAC5C,UAAI,CAAC,KAAK,KAAK,EAAG;AAClB,YAAM,UAAU,KAAK,WAAW,IAAI;AACpC,UAAI,YAAY,KAAM;AACtB,WAAK,cAAe,KAAK,OAAO;AAChC,YAAM,MAAM,KAAK,cAAe,SAAS;AACzC,UAAI,KAAK,oBAAoB,MAAM;AACjC,YAAI,MAAM,KAAK,gBAAgB,IAAI,QAAQ,EAAE;AAC7C,YAAI,QAAQ,QAAW;AACrB,gBAAM,oBAAI,IAAI;AACd,eAAK,gBAAgB,IAAI,QAAQ,IAAI,GAAG;AAAA,QAC1C;AACA,YAAI,IAAI,GAAG;AAAA,MACb;AACA,UAAI,KAAK,iBAAiB,MAAM;AAC9B,YAAI,MAAM,KAAK,aAAa,IAAI,QAAQ,IAAI;AAC5C,YAAI,QAAQ,QAAW;AACrB,gBAAM,oBAAI,IAAI;AACd,eAAK,aAAa,IAAI,QAAQ,MAAM,GAAG;AAAA,QACzC;AACA,YAAI,IAAI,GAAG;AAAA,MACb;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,WAAW,MAAqC;AACtD,QAAI;AACF,aAAO,wBAAwB,IAAI;AAAA,IACrC,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA,EAGQ,YAAY,KAA+B;AACjD,UAAM,QAAQ,IAAI,MAAM,cAAc,EAAE,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE,SAAS,CAAC;AACzE,UAAM,WAA6B,CAAC;AACpC,eAAW,QAAQ,OAAO;AACxB,YAAM,UAAU,KAAK,WAAW,IAAI;AACpC,UAAI,YAAY,KAAM,UAAS,KAAK,OAAO;AAAA,IAC7C;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,MAAc,qBAAgD;AAC5D,UAAM,MAAM,MAAM,KAAK,cAAc;AACrC,UAAM,EAAE,SAAS,KAAK,IAAI,MAAM,KAAK,iBAAiB;AACtD,SAAK,iBAAiB,KAAK,SAAS,IAAI;AACxC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAc,mBAA+D;AAC3E,QAAI;AACF,YAAM,KAAK,MAAU,SAAK,KAAK,WAAW;AAC1C,aAAO,EAAE,SAAS,GAAG,SAAS,MAAM,GAAG,KAAK;AAAA,IAC9C,SAAS,KAAK;AACZ,UAAK,IAA8B,SAAS,UAAU;AACpD,eAAO,EAAE,SAAS,IAAI,MAAM,GAAG;AAAA,MACjC;AACA,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA0BQ,sBAAiD;AAGvD,UAAM,MAAM,KAAK,WACd,MAAM,MAAM,MAAwC,EACpD,KAAK,MAAM,KAAK,wBAAwB,CAAC;AAC5C,SAAK,aAAa,IAAI,MAAM,MAAM,CAAC,CAAqB;AACxD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAc,0BAAqD;AACjE,QAAI;AACF,YAAM,KAAK,MAAU,SAAK,KAAK,WAAW;AAG1C,UACE,KAAK,kBAAkB,QACvB,KAAK,uBAAuB,GAAG,WAC/B,KAAK,sBAAsB,GAAG,MAC9B;AACA,eAAO,KAAK;AAAA,MACd;AAKA,UACE,KAAK,kBAAkB,QACvB,KAAK,qBAAqB,KAC1B,GAAG,OAAO,KAAK,mBACf;AACA,cAAM,KAAK,MAAU,SAAK,KAAK,aAAa,GAAG;AAC/C,YAAI;AACF,gBAAM,UAAU,MAAM,KAAK,qBAAqB,IAAI,KAAK,mBAAmB,GAAG,IAAI;AACnF,eAAK,qBAAqB,GAAG;AAC7B,iBAAO;AAAA,QACT,UAAE;AACA,gBAAM,GAAG,MAAM;AAAA,QACjB;AAAA,MACF;AAIA,YAAM,MAAM,MAAM,KAAK,cAAc;AACrC,WAAK,iBAAiB,KAAK,GAAG,SAAS,GAAG,IAAI;AAC9C,aAAO;AAAA,IACT,SAAS,KAAK;AACZ,UAAK,IAA8B,SAAS,UAAU;AACpD,aAAK,iBAAiB,CAAC,GAAG,IAAI,EAAE;AAChC,eAAO,CAAC;AAAA,MACV;AACA,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBQ,iBAAiB,UAA4B,OAAe,MAAoB;AAKtF,QAAI,SAAS,SAAS,2BAA2B;AAC/C,WAAK,gBAAgB;AACrB,WAAK,qBAAqB;AAC1B,WAAK,oBAAoB;AACzB,WAAK,kBAAkB;AACvB,WAAK,eAAe;AACpB;AAAA,IACF;AACA,SAAK,gBAAgB;AACrB,SAAK,qBAAqB;AAC1B,SAAK,oBAAoB;AACzB,SAAK,uBAAuB;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,yBAA+B;AACrC,UAAM,QAAQ,KAAK;AACnB,QAAI,UAAU,MAAM;AAClB,WAAK,kBAAkB;AACvB,WAAK,eAAe;AACpB;AAAA,IACF;AACA,UAAM,SAAS,oBAAI,IAAyB;AAC5C,UAAM,SAAS,oBAAI,IAAyB;AAC5C,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,YAAM,MAAM,MAAM,CAAC;AACnB,UAAI,OAAO,OAAO,IAAI,IAAI,EAAE;AAC5B,UAAI,SAAS,QAAW;AACtB,eAAO,oBAAI,IAAI;AACf,eAAO,IAAI,IAAI,IAAI,IAAI;AAAA,MACzB;AACA,WAAK,IAAI,CAAC;AACV,UAAI,OAAO,OAAO,IAAI,IAAI,IAAI;AAC9B,UAAI,SAAS,QAAW;AACtB,eAAO,oBAAI,IAAI;AACf,eAAO,IAAI,IAAI,MAAM,IAAI;AAAA,MAC3B;AACA,WAAK,IAAI,CAAC;AAAA,IACZ;AACA,SAAK,kBAAkB;AACvB,SAAK,eAAe;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBQ,aAAa,KAAqB,OAAe,MAAoB;AAC3E,QAAI,KAAK,kBAAkB,MAAM;AAG/B;AAAA,IACF;AACA,QAAI,KAAK,cAAc,UAAU,2BAA2B;AAC1D,WAAK,gBAAgB;AACrB,WAAK,qBAAqB;AAC1B,WAAK,oBAAoB;AACzB;AAAA,IACF;AAIA,SAAK,cAAc,KAAK,GAAG;AAE3B,UAAM,SAAS,KAAK,cAAc,SAAS;AAC3C,QAAI,KAAK,oBAAoB,MAAM;AACjC,UAAI,MAAM,KAAK,gBAAgB,IAAI,IAAI,EAAE;AACzC,UAAI,QAAQ,QAAW;AACrB,cAAM,oBAAI,IAAI;AACd,aAAK,gBAAgB,IAAI,IAAI,IAAI,GAAG;AAAA,MACtC;AACA,UAAI,IAAI,MAAM;AAAA,IAChB;AAEA,QAAI,KAAK,iBAAiB,MAAM;AAC9B,UAAI,MAAM,KAAK,aAAa,IAAI,IAAI,IAAI;AACxC,UAAI,QAAQ,QAAW;AACrB,cAAM,oBAAI,IAAI;AACd,aAAK,aAAa,IAAI,IAAI,MAAM,GAAG;AAAA,MACrC;AACA,UAAI,IAAI,MAAM;AAAA,IAChB;AAGA,SAAK,qBAAqB;AAC1B,SAAK,oBAAoB;AAAA,EAC3B;AAAA,EAEA,MAAc,kBAAiC;AAC7C,UAAU,UAAW,cAAQ,KAAK,YAAY,GAAG,EAAE,WAAW,KAAK,CAAC;AAAA,EACtE;AAAA,EAEA,MAAc,cAAc,MAAmE;AAK7F,QACE,CAAC,MAAM,SACP,KAAK,kBACL,KAAK,IAAI,IAAI,KAAK,mBAAmB,uBACrC;AACA,aAAO,IAAI,IAAI,KAAK,cAAc;AAAA,IACpC;AAEA,QAAI;AACF,YAAM,MAAM,MAAU,aAAS,KAAK,cAAc,MAAM;AACxD,YAAM,OAAO,KAAK,MAAM,GAAG;AAE3B,YAAM,MAAM,oBAAI,IAA6B;AAC7C,iBAAW,CAAC,IAAI,KAAK,KAAK,OAAO,QAAQ,IAAI,GAAG;AAC9C,YAAI,IAAI,IAAI,KAAwB;AAAA,MACtC;AACA,WAAK,iBAAiB;AACtB,WAAK,mBAAmB,KAAK,IAAI;AACjC,aAAO,IAAI,IAAI,GAAG;AAAA,IACpB,SAAS,KAAK;AACZ,UAAK,IAA8B,SAAS,UAAU;AACpD,cAAM,QAAQ,oBAAI,IAA6B;AAC/C,aAAK,iBAAiB;AACtB,aAAK,mBAAmB,KAAK,IAAI;AACjC,eAAO;AAAA,MACT;AACA,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEQ,mBAAmB,UAA8C;AACvE,UAAM,SAAS,KAAK,IAAI,IAAI;AAC5B,eAAW,CAAC,IAAI,KAAK,KAAK,UAAU;AAClC,YAAM,WAAW,KAAK,MAAM,MAAM,UAAU;AAI5C,UAAI,CAAC,OAAO,SAAS,QAAQ,KAAK,WAAW,QAAQ;AACnD,iBAAS,OAAO,EAAE;AAAA,MACpB;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,eAAe,UAAuD;AAClF,UAAM,MAAuC,CAAC;AAC9C,eAAW,CAAC,IAAI,KAAK,KAAK,UAAU;AAClC,UAAI,EAAE,IAAI;AAAA,IACZ;AACA,UAAM,MAAM,GAAG,KAAK,YAAY,IAAIA,YAAW,EAAE,MAAM,GAAG,CAAC,CAAC;AAC5D,UAAU,cAAU,KAAK,KAAK,UAAU,GAAG,GAAG,MAAM;AACpD,UAAU,WAAO,KAAK,KAAK,YAAY;AAAA,EACzC;AAAA;AAAA,EAIA,MAAc,wBAAuC;AACnD,UAAU,UAAW,cAAQ,KAAK,kBAAkB,GAAG,EAAE,WAAW,KAAK,CAAC;AAAA,EAC5E;AAAA,EAEA,MAAc,oBAAoB,MAES;AACzC,QACE,CAAC,MAAM,SACP,KAAK,wBACL,KAAK,IAAI,IAAI,KAAK,yBAAyB,uBAC3C;AACA,aAAO,IAAI,IAAI,KAAK,oBAAoB;AAAA,IAC1C;AAEA,QAAI;AACF,YAAM,MAAM,MAAU,aAAS,KAAK,oBAAoB,MAAM;AAC9D,YAAM,OAAO,KAAK,MAAM,GAAG;AAC3B,YAAM,MAAM,oBAAI,IAA8B;AAC9C,iBAAW,CAAC,IAAI,MAAM,KAAK,OAAO,QAAQ,IAAI,GAAG;AAC/C,YAAI,IAAI,IAAI,MAA0B;AAAA,MACxC;AACA,WAAK,uBAAuB;AAC5B,WAAK,yBAAyB,KAAK,IAAI;AACvC,aAAO,IAAI,IAAI,GAAG;AAAA,IACpB,SAAS,KAAK;AACZ,UAAK,IAA8B,SAAS,UAAU;AACpD,cAAM,QAAQ,oBAAI,IAA8B;AAChD,aAAK,uBAAuB;AAC5B,aAAK,yBAAyB,KAAK,IAAI;AACvC,eAAO;AAAA,MACT;AACA,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEQ,0BAA0B,UAA+C;AAC/E,UAAM,SAAS,KAAK,IAAI,IAAI;AAC5B,eAAW,CAAC,IAAI,MAAM,KAAK,UAAU;AACnC,YAAM,WAAW,KAAK,MAAM,OAAO,UAAU;AAC7C,UAAI,CAAC,OAAO,SAAS,QAAQ,KAAK,WAAW,QAAQ;AACnD,iBAAS,OAAO,EAAE;AAAA,MACpB;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,qBAAqB,UAAwD;AACzF,UAAM,MAAwC,CAAC;AAC/C,eAAW,CAAC,IAAI,MAAM,KAAK,UAAU;AACnC,UAAI,EAAE,IAAI;AAAA,IACZ;AACA,UAAM,MAAM,GAAG,KAAK,kBAAkB,IAAIA,YAAW,EAAE,MAAM,GAAG,CAAC,CAAC;AAClE,UAAU,cAAU,KAAK,KAAK,UAAU,GAAG,GAAG,MAAM;AACpD,UAAU,WAAO,KAAK,KAAK,kBAAkB;AAAA,EAC/C;AACF;;;AQnlDA,SAAS,eAAAC,cAAa,cAAAC,aAAY,QAAQ,uBAAuB;AACjE,YAAYC,SAAQ;AACpB,YAAY,YAAY;AACxB,YAAYC,WAAU;AAOf,IAAM,uBAAuB;AAG7B,SAAS,mBAA2B;AACzC,SAAY,WAAK,iBAAiB,GAAG,IAAI;AAC3C;AAcO,SAAS,iBAAiB,UAAmB,MAAyB,QAAQ,KAAa;AAChG,QAAM,MAAM,YAAY,IAAI,wBAAwB,GAAG,KAAK;AAC5D,MAAI,CAAC,IAAK,QAAO,iBAAiB;AAClC,SAAY,iBAAW,GAAG,IAAS,cAAQ,GAAG,IAAS,cAAQ,QAAQ,IAAI,GAAG,GAAG;AACnF;AAkCO,SAAS,mBAAmB,OAA4B,YAA6B;AAC1F,MAAI,UAAU,OAAW,QAAO;AAChC,MAAI,MAAM,iBAAiB,OAAW,QAAO;AAC7C,SAAO,MAAM,aAAa,SAAS,UAAU;AAC/C;AAmCO,SAAS,kBAA8B;AAC5C,SAAO;AAAA,IACL,SAAS;AAAA,IACT,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,EACpC;AACF;AAGO,SAAS,eAAe,SAAyB;AACtD,SAAY,WAAK,SAAS,WAAW;AACvC;AAGO,SAAS,kBAAkB,SAAyB;AACzD,SAAY,WAAK,SAAS,cAAc;AAC1C;AAEA,eAAsB,mBAAmB,SAAiB,MAAuD;AAC/G,QAAM,UAAyB;AAAA,IAC7B,GAAG;AAAA,IACH,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,EACpC;AACA,QAAM,YAAY,kBAAkB,OAAO,GAAG,GAAG,KAAK,UAAU,SAAS,MAAM,CAAC,CAAC;AAAA,GAAM,EAAE,MAAM,IAAM,CAAC;AACxG;AAEA,SAAS,eAAe,KAAsB;AAC5C,MAAI,CAAC,OAAO,UAAU,GAAG,KAAK,OAAO,EAAG,QAAO;AAC/C,MAAI;AACF,YAAQ,KAAK,KAAK,CAAC;AACnB,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,sBAAsB,SAA4C;AAChF,MAAI;AACF,UAAM,SAAS,KAAK,MAAa,oBAAa,kBAAkB,OAAO,GAAG,MAAM,CAAC;AACjF,QAAI,OAAO,OAAO,QAAQ,YAAY,OAAO,IAAI,KAAK,EAAE,WAAW,EAAG,QAAO;AAC7E,QAAI,OAAO,OAAO,QAAQ,YAAY,CAAC,eAAe,OAAO,GAAG,EAAG,QAAO;AAC1E,WAAO;AAAA,MACL,KAAK,OAAO;AAAA,MACZ,WAAW,OAAO,OAAO,cAAc,WAAW,OAAO,YAAY;AAAA,MACrE,GAAI,OAAO,OAAO,QAAQ,WAAW,EAAE,KAAK,OAAO,IAAI,IAAI,CAAC;AAAA,IAC9D;AAAA,EACF,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAWA,eAAsB,eACpB,SACA,OAAyC,CAAC,GACrB;AACrB,QAAM,OAAO,eAAe,OAAO;AACnC,MAAI;AACJ,MAAI;AACF,UAAM,MAAS,aAAS,MAAM,MAAM;AAAA,EACtC,SAAS,KAAK;AACZ,QAAK,IAA8B,SAAS,SAAU,QAAO,gBAAgB;AAE7E,SAAK,OAAO,+BAA+B,IAAI,KAAM,IAAc,OAAO,EAAE;AAC5E,WAAO,gBAAgB;AAAA,EACzB;AACA,MAAI;AACF,UAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,QAAI,OAAO,YAAY,sBAAsB;AAC3C,WAAK;AAAA,QACH,mBAAmB,IAAI,4BAA4B,OAAO,OAAO,OAAO,CAAC,cAAc,OAAO,oBAAoB,CAAC;AAAA,MACrH;AACA,aAAO,gBAAgB;AAAA,IACzB;AACA,WAAO;AAAA,EACT,SAAS,KAAK;AACZ,SAAK,OAAO,mBAAmB,IAAI,sDAAuD,IAAc,OAAO,EAAE;AACjH,WAAO,gBAAgB;AAAA,EACzB;AACF;AAOA,eAAsB,gBAAgB,SAAiB,MAAiC;AACtF,QAAM,SAAS,eAAe,OAAO;AACrC,QAAM,UAAsB;AAAA,IAC1B,GAAG;AAAA,IACH,SAAS;AAAA,IACT,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,EACpC;AACA,QAAM,YAAY,QAAQ,GAAG,KAAK,UAAU,SAAS,MAAM,CAAC,CAAC;AAAA,GAAM,EAAE,MAAM,IAAM,CAAC;AACpF;AAoBA,eAAsB,yBACpB,SACA,OAAoC,CAAC,GACA;AACrC,QAAM,OAAO,eAAe,OAAO;AACnC,MAAI;AACF,UAAS,WAAO,IAAI;AACpB,WAAO,EAAE,UAAU,MAAM,eAAe,SAAS,IAAI,GAAG,SAAS,MAAM;AAAA,EACzE,SAAS,KAAK;AACZ,QAAK,IAA8B,SAAS,UAAU;AACpD,WAAK,OAAO,iCAAiC,IAAI,KAAM,IAAc,OAAO,EAAE;AAC9E,aAAO,EAAE,UAAU,MAAM,eAAe,SAAS,IAAI,GAAG,SAAS,MAAM;AAAA,IACzE;AAAA,EACF;AAMA,QAAM,eAAe,EAAE,GAAG,YAAY,mBAAmB,GAAG,cAAc,CAAC,iBAAiB,EAAE;AAC9F,QAAM,cAAc,EAAE,GAAG,YAAY,kBAAkB,GAAG,cAAc,CAAC,mBAAmB,EAAE;AAC9F,QAAM,WAAuB;AAAA,IAC3B,SAAS;AAAA,IACT,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,IAClC,eAAe,CAAC,YAAY;AAAA,IAC5B,cAAc,CAAC,WAAW;AAAA,EAC5B;AACA,MAAI,KAAK,UAAU;AACjB,aAAS,eAAe,MAAM,eAAe,KAAK,QAAQ;AAC1D,aAAS,eAAe,mBAAmB;AAAA,EAC7C;AACA,QAAM,gBAAgB,SAAS,QAAQ;AACvC,SAAO,EAAE,UAAU,MAAM,eAAe,SAAS,IAAI,GAAG,SAAS,MAAM,cAAc,YAAY;AACnG;AAYA,eAAsB,iBACpB,SACA,SACA,OAAyC,CAAC,GACrB;AACrB,QAAM,UAAU,MAAM,eAAe,SAAS,IAAI;AAClD,QAAM,OAAO,MAAM,QAAQ,OAAO;AAClC,QAAM,gBAAgB,SAAS,IAAI;AACnC,SAAO;AACT;AAEA,IAAM,yBAAyB;AAC/B,IAAM,yBAAyB;AAC/B,IAAM,4BAA4B,EAAE,GAAG,OAAO,GAAG,GAAG,GAAG,EAAE;AAMlD,SAAS,eAAe,UAAmC;AAChE,SAAO,IAAI,QAAQ,CAACC,UAAS,WAAW;AACtC,UAAM,OAAOC,aAAY,sBAAsB;AAC/C,WAAO,UAAU,MAAM,wBAAwB,2BAA2B,CAAC,KAAK,eAAe;AAC7F,UAAI,IAAK,QAAO,OAAO,GAAG;AAC1B,YAAM,UAAU,UAAU,KAAK,SAAS,WAAW,CAAC,IAAI,WAAW,SAAS,WAAW,CAAC;AACxF,MAAAD,SAAQ,OAAO;AAAA,IACjB,CAAC;AAAA,EACH,CAAC;AACH;AAKA,eAAsB,iBAAiB,UAAkB,MAAgC;AACvF,QAAM,QAAQ,KAAK,MAAM,GAAG;AAC5B,MAAI,MAAM,WAAW,KAAK,MAAM,CAAC,MAAM,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,EAAG,QAAO;AAClF,MAAI;AACJ,MAAI;AACJ,MAAI;AACF,WAAO,OAAO,KAAK,MAAM,CAAC,GAAG,WAAW;AACxC,eAAW,OAAO,KAAK,MAAM,CAAC,GAAG,WAAW;AAAA,EAC9C,QAAQ;AACN,WAAO;AAAA,EACT;AACA,MAAI,KAAK,WAAW,KAAK,SAAS,WAAW,EAAG,QAAO;AACvD,QAAM,UAAU,MAAM,IAAI,QAAgB,CAACA,UAAS,WAAW;AAC7D,WAAO,UAAU,MAAM,SAAS,QAAQ,2BAA2B,CAAC,KAAK,QAAQ;AAC/E,UAAI,IAAK,QAAO,GAAG;AAAA,UACd,CAAAA,SAAQ,GAAG;AAAA,IAClB,CAAC;AAAA,EACH,CAAC;AACD,SAAO,gBAAgB,SAAS,QAAQ;AAC1C;AAGO,SAAS,qBAA6B;AAC3C,SAAOC,aAAY,EAAE,EAAE,SAAS,WAAW;AAC7C;AAMO,SAAS,YAAY,OAAyB;AACnD,QAAM,OAAM,oBAAI,KAAK,GAAE,YAAY;AACnC,SAAO;AAAA,IACL,IAAIC,YAAW;AAAA,IACf,OAAOA,YAAW,EAAE,QAAQ,MAAM,EAAE,IAAIA,YAAW,EAAE,QAAQ,MAAM,EAAE;AAAA,IACrE,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;AAAA,IACzB,WAAW;AAAA,EACb;AACF;AAKO,IAAM,qBAAqB;AAmB3B,SAAS,gBACd,SACA,UACA,OAA8D,CAAC,GACxC;AACvB,QAAM,OAAO,eAAe,OAAO;AACnC,QAAM,aAAa,KAAK,cAAc;AACtC,MAAI;AACJ,MAAI,SAAS;AAEb,MAAI;AACJ,MAAI;AAKF,cAAiB,aAAW,cAAQ,IAAI,GAAG,EAAE,WAAW,MAAM,CAAC;AAAA,EACjE,SAAS,KAAK;AACZ,SAAK,OAAO,oCAAqC,IAAc,OAAO,EAAE;AACxE,WAAO,EAAE,OAAO,MAAM;AAAA,IAAC,EAAE;AAAA,EAC3B;AAEA,QAAM,UAAU,MAAY;AAC1B,QAAI,OAAQ;AACZ,QAAI,MAAO,cAAa,KAAK;AAC7B,YAAQ,WAAW,MAAM;AACvB,cAAQ;AACR,YAAM,WAAW,KAAK,OAAO,EAAE,MAAM,KAAK,KAAK,IAAI,CAAC;AACpD,WAAK,eAAe,SAAS,QAAQ,EAAE;AAAA,QACrC,CAAC,SAAS;AACR,cAAI,CAAC,OAAQ,UAAS,IAAI;AAAA,QAC5B;AAAA,QACA,MAAM;AAAA,QAGN;AAAA,MACF;AAAA,IACF,GAAG,UAAU;AAAA,EACf;AAEA,UAAQ,GAAG,UAAU,CAAC,WAAmB,aAAqC;AAC5E,UAAM,OAAO,OAAO,aAAa,WAAW,WAAW;AAEvD,QAAI,cAAc,YAAY,cAAc,UAAU;AACpD,UAAI,CAAC,QAAQ,SAAS,eAAe,SAAc,eAAS,IAAI,GAAG;AACjE,gBAAQ;AAAA,MACV;AAAA,IACF;AAAA,EACF,CAAC;AAED,UAAQ,GAAG,SAAS,CAAC,QAAe;AAClC,SAAK,OAAO,0BAA0B,IAAI,OAAO,EAAE;AAAA,EACrD,CAAC;AAED,SAAO;AAAA,IACL,OAAO,MAAM;AACX,eAAS;AACT,UAAI,MAAO,cAAa,KAAK;AAC7B,cAAQ,MAAM;AAAA,IAChB;AAAA,EACF;AACF;;;ATrZO,SAAS,wBAAwB,UAGpC,CAAC,GAA4D;AAC/D,QAAM,UAAU,iBAAiB,QAAQ,SAAS,QAAQ,OAAO,QAAQ,GAAG;AAC5E,QAAM,UAAU,sBAAsB,OAAO;AAC7C,MAAI,YAAY,OAAW,QAAO;AAClC,QAAM,QAAQ,iCAAiC,OAAO;AACtD,SAAO,EAAE,KAAK,QAAQ,KAAK,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC,EAAG;AACzD;AAEA,SAAS,iCAAiC,SAAqC;AAC7E,MAAI;AACF,UAAM,MAAS,iBAAa,eAAe,OAAO,GAAG,MAAM;AAC3D,UAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,WAAO,OAAO,cAAc,KAAK,CAAC,MAAM,EAAE,MAAM,KAAK,EAAE,SAAS,CAAC,GAAG;AAAA,EACtE,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAQA,SAAS,gBAAgB,KAAsB;AAC7C,MAAI;AACF,UAAM,OAAO,IAAI,IAAI,GAAG,EAAE,SAAS,YAAY;AAC/C,WAAO,SAAS,eAAe,SAAS,eAAe,SAAS,SAAS,SAAS,WAAW,SAAS;AAAA,EACxG,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,uBAAuB,MAAyB,QAAQ,KAAuC;AAC7G,SAAO,gBAAgB,EAAE,IAAI,CAAC;AAChC;AAEO,SAAS,gBAAgB,UAG5B,CAAC,GAAqC;AACxC,QAAM,MAAM,QAAQ,OAAO,QAAQ;AACnC,QAAM,aAAa,QAAQ;AAC3B,QAAM,SAAS,IAAI,mBAAmB,GAAG,KAAK;AAC9C,QAAM,WAAW,IAAI,qBAAqB,GAAG,KAAK;AAClD,QAAM,YAAY,YAAY,KAAK,KAAK;AACxC,QAAM,cAAc,YAAY,OAAO,KAAK;AAC5C,QAAM,gBAAgB,IAAI,uBAAuB,GAAG,KAAK;AACzD,QAAM,UAAU,kBAAkB,UAAa,cAAc,SAAS,IAClE,kBAAkB,MAClB,YAAY;AAChB,QAAM,UAAU,iBAAiB,YAAY,SAAS,GAAG;AACzD,QAAM,gBAAgB,YAAY;AAClC,QAAM,aAAa,sBAAsB,OAAO,GAAG,IAAI,KAAK;AAC5D,QAAM,MAAM,UAAU;AAKtB,QAAM,qBACJ,CAAC,OAAO,gBAAgB,GAAG,IAAI,iCAAiC,OAAO,IAAI;AAC7E,QAAM,QAAQ,iBAAiB;AAE/B,QAAM,gBAAgB,IAAI,2BAA2B,GAAG,KAAK;AAC7D,QAAM,qBAAqB,gBAAgB,kBAAkB,MAAM,YAAY;AAC/E,QAAM,kBAAkB,IAAI,6BAA6B,GAAG,KAAK;AACjE,QAAM,eAAe,mBAAmB,YAAY;AAEpD,MAAI,CAAC,KAAK;AACR,QAAI,YAAY,MAAO,QAAO;AAa9B,WAAO;AAAA,MACL,KAAK,cAAc;AAAA,MACnB,SAAS;AAAA,MACT,UAAU;AAAA,MACV;AAAA,MACA,YAAY,sBAAsB;AAAA,MAClC,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;AAAA,MACzB,GAAI,eAAe,EAAE,aAAa,IAAI,CAAC;AAAA,IACzC;AAAA,EACF;AAKA,QAAM,aAAa,sBAAsB;AACzC,SAAO;AAAA,IACL;AAAA,IACA,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;AAAA,IACzB,GAAI,YAAY,SAAY,EAAE,QAAQ,IAAI,CAAC;AAAA,IAC3C,GAAI,eAAe,SAAY,EAAE,WAAW,IAAI,CAAC;AAAA,IACjD,GAAI,eAAe,EAAE,aAAa,IAAI,CAAC;AAAA,EACzC;AACF;AAEA,SAAS,kBAA0B;AAIjC,SAAOC,YAAW,QAAQ,EAAE,OAAO,SAAS,CAAC,EAAE,OAAO,KAAK,EAAE,MAAM,GAAG,EAAE;AAC1E;AAEA,SAAS,gBAAgB,aAA6B;AACpD,SAAOA,YAAW,QAAQ,EAAE,OAAO,WAAW,EAAE,OAAO,KAAK,EAAE,MAAM,GAAG,EAAE;AAC3E;AAsBO,SAAS,yBAAyB,SAA4D;AACnG,QAAM,SAAS,QAAQ,UAAU,gBAAgB,EAAE,QAAQ,QAAQ,WAAW,GAAG,CAAC;AAClF,MAAI,CAAC,UAAU,OAAO,YAAY,MAAO,QAAO;AAEhD,QAAM,YAAY,QAAQ,aAAa,gBAAgB;AACvD,QAAM,OAAO,QAAQ,oBAAoB,SAAS;AAClD,QAAM,cAAc,QAAQ,eAAe,OAAO,iBAAiBC,UAAS,QAAQ,WAAW,KAAK;AAEpG,QAAM,SAA2B;AAAA,IAC/B,UAAU,GAAG,SAAS,IAAI,QAAQ,UAAU,IAAI,QAAQ,GAAG,IAAIC,YAAW,EAAE,MAAM,GAAG,CAAC,CAAC;AAAA,IACvF,MAAM,QAAQ;AAAA,IACd;AAAA,IACA,GAAI,OAAO,EAAE,UAAU,KAAK,IAAI,CAAC;AAAA,IACjC,KAAK,QAAQ;AAAA,IACb,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,EACpC;AAEA,QAAM,UAA6B;AAAA,IACjC,WAAW,gBAAgB,QAAQ,WAAW;AAAA,IAC9C,aAAa,QAAQ;AAAA,IACrB;AAAA,IACA;AAAA,IACA,eAAe;AAAA,EACjB;AAEA,QAAM,kBACJ,QAAQ,mBAAmB,OAAO,eAAe,SAC7C;AAAA,IACE,GAAI,OAAO,eAAe,SAAY,EAAE,YAAY,OAAO,WAAW,IAAI,CAAC;AAAA,IAC3E,GAAI,QAAQ,mBAAmB,CAAC;AAAA,EAClC,IACA;AAEN,QAAM,mBAAmB,OAAO;AAChC,SAAO,IAAI,YAAY;AAAA,IACrB,KAAK,OAAO;AAAA,IACZ,GAAI,OAAO,QAAQ,EAAE,OAAO,OAAO,MAAM,IAAI,CAAC;AAAA,IAC9C;AAAA,IACA;AAAA,IACA,GAAI,QAAQ,gBAAgB,EAAE,eAAe,QAAQ,cAAc,IAAI,CAAC;AAAA,IACxE,GAAI,oBAAoB,SAAY,EAAE,gBAAgB,IAAI,CAAC;AAAA,IAC3D,GAAI,QAAQ,iBAAiB,SAAY,EAAE,cAAc,QAAQ,aAAa,IAAI,CAAC;AAAA,IACnF,GAAI,QAAQ,cAAc,SAAY,EAAE,WAAW,QAAQ,UAAU,IAAI,CAAC;AAAA;AAAA;AAAA,IAG1E,GAAI,OAAO,WACP,EAAE,iBAAiB,MAAM,wBAAwB,EAAE,SAAS,iBAAiB,CAAC,EAAE,IAChF,CAAC;AAAA,IACL,GAAI,QAAQ,oBAAoB,SAAY,EAAE,iBAAiB,QAAQ,gBAAgB,IAAI,CAAC;AAAA,IAC5F,GAAI,QAAQ,WAAW,SAAY,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;AAAA,EACnE,CAAC;AACH;AAQO,SAAS,oBAAoB,SAAoD;AACtF,SAAO,IAAI,cAAc,QAAQ,YAAY,QAAQ,QAAQ,QAAQ,WAAW;AAClF;;;AU1NO,SAAS,6BAA6B,MAAkD;AAC7F,QAAM,EAAE,QAAQ,UAAU,WAAW,QAAQ,IAAI;AACjD,QAAM,MAAM,EAAE,SAAS,EAAE;AAEzB,WAAS,UAAkB;AACzB,QAAI,WAAW;AACf,WAAO,IAAI;AAAA,EACb;AAEA,WAAS,cAAiB,MAAc,SAAY,WAAwC;AAC1F,WAAO,sBAAsB;AAAA,MAC3B,IAAI,GAAG,KAAK,IAAI,EAAE,SAAS,EAAE,CAAC,IAAI,QAAQ,CAAC;AAAA,MAC3C;AAAA,MACA,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MAClC;AAAA,MACA;AAAA,MACA,KAAK,QAAQ;AAAA,MACb;AAAA;AAAA;AAAA;AAAA,MAIA,GAAI,cAAc,SAAY,EAAE,UAAU,IAAI,CAAC;AAAA,IACjD,CAAC;AAAA,EACH;AAEA,QAAM,aAAa,OAAO,GAAG,0BAA0B,CAAC,YAAY;AAClE,QAAI,CAAC,QAAS;AACd,UAAM,aAAoC;AAAA,MACxC,YAAY,QAAQ;AAAA,MACpB,WAAW,QAAQ;AAAA,MACnB,SAAS,QAAQ;AAAA,MACjB,MAAM,QAAQ;AAAA,MACd,WAAW,QAAQ;AAAA,MACnB,IAAI,QAAQ;AAAA,IACd;AACA,QAAI,QAAQ,aAAa,OAAW,YAAW,WAAW,QAAQ;AAClE,QAAI,QAAQ,YAAY,OAAW,YAAW,UAAU,QAAQ;AAChE,YAAQ,cAAc,iBAAiB,YAAY,QAAQ,SAAS,CAAC;AAAA,EACvE,CAAC;AAED,QAAM,YAAY,OAAO,GAAG,wBAAwB,CAAC,YAAY;AAC/D,QAAI,CAAC,QAAS;AACd,UAAM,gBAAsC;AAAA,MAC1C,YAAY,QAAQ;AAAA,MACpB,WAAW,QAAQ;AAAA,MACnB,QAAQ,QAAQ;AAAA,MAChB,IAAI,QAAQ;AAAA,IACd;AACA,QAAI,QAAQ,YAAY,OAAW,eAAc,UAAU,QAAQ;AACnE,QAAI,QAAQ,SAAS,OAAW,eAAc,OAAO,QAAQ;AAC7D,YAAQ,cAAc,gBAAgB,aAAa,CAAC;AAAA,EACtD,CAAC;AAED,SAAO,MAAM;AACX,eAAW;AACX,cAAU;AAAA,EACZ;AACF;;;ACvEA,YAAYC,SAAQ;AACpB,YAAYC,UAAS;;;ACErB,SAAS,aAAa,SAA0B;AAC9C,MAAI,OAAO,YAAY,SAAU,QAAO;AACxC,MAAI,MAAM,QAAQ,OAAO,GAAG;AAC1B,WAAO,QACJ;AAAA,MACC,CAAC,MACC,CAAC,CAAC,KACF,OAAO,MAAM,YACZ,EAAyB,SAAS,UACnC,OAAQ,EAAyB,SAAS;AAAA,IAC9C,EACC,IAAI,CAAC,MAAM,EAAE,IAAI,EACjB,KAAK,IAAI;AAAA,EACd;AACA,SAAO;AACT;AAEA,SAAS,SAAS,GAAoB;AACpC,MAAI,OAAO,MAAM,SAAU,QAAO;AAClC,MAAI;AACF,WAAO,KAAK,UAAU,GAAG,MAAM,CAAC;AAAA,EAClC,QAAQ;AACN,WAAO,OAAO,CAAC;AAAA,EACjB;AACF;AAEA,SAAS,UAAU,IAAY,MAAe,OAAgB,IAAgC;AAC5F,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN,MAAM,OAAO,QAAQ,MAAM;AAAA,IAC3B,WAAW,UAAU,UAAa,UAAU,OAAO,SAAS,KAAK,IAAI;AAAA,IACrE,MAAM;AAAA,IACN,GAAI,OAAO,OAAO,WAAW,EAAE,WAAW,GAAG,IAAI,CAAC;AAAA,EACpD;AACF;AAOO,SAAS,yBAAyB,IAAkD;AACzF,QAAM,KAAK,OAAO,GAAG,IAAI,MAAM,WAAY,GAAG,IAAI,IAAe;AACjE,QAAM,OAAO,CACX,MACA,MACA,WACuB;AAAA,IACvB;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL;AAEA,UAAQ,GAAG,MAAM,GAAG;AAAA,IAClB,KAAK,cAAc;AACjB,YAAM,IAAI,aAAa,GAAG,SAAS,CAAC;AACpC,aAAO,EAAE,KAAK,IAAI,CAAC,KAAK,QAAQ,CAAC,CAAC,IAAI,CAAC;AAAA,IACzC;AAAA,IACA,KAAK,gBAAgB;AACnB,YAAM,MAA2B,CAAC;AAClC,YAAM,UAAU,GAAG,SAAS;AAG5B,UAAI,MAAM,QAAQ,OAAO,GAAG;AAC1B,cAAM,WAAW,QACd;AAAA,UACC,CAAC,MACC,CAAC,CAAC,KACF,OAAO,MAAM,YACZ,EAAyB,SAAS,cACnC,OAAQ,EAA6B,aAAa;AAAA,QACtD,EACC,IAAI,CAAC,MAAM,EAAE,QAAQ,EACrB,KAAK,IAAI;AACZ,YAAI,SAAS,KAAK,EAAG,KAAI,KAAK,KAAK,YAAY,QAAQ,CAAC;AAAA,MAC1D;AACA,YAAM,IAAI,aAAa,OAAO;AAC9B,UAAI,EAAE,KAAK,EAAG,KAAI,KAAK,KAAK,aAAa,CAAC,CAAC;AAC3C,UAAI,MAAM,QAAQ,OAAO,GAAG;AAC1B,mBAAW,KAAK,SAAS;AACvB,cAAI,KAAK,OAAO,MAAM,YAAa,EAAyB,SAAS,YAAY;AAC/E,kBAAM,QAAQ;AACd,gBAAI,KAAK,UAAU,IAAI,MAAM,MAAM,MAAM,OAAO,MAAM,EAAE,CAAC;AAAA,UAC3D;AAAA,QACF;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAAA,IACA,KAAK;AACH,aAAO,CAAC,UAAU,IAAI,GAAG,MAAM,GAAG,GAAG,OAAO,GAAG,GAAG,IAAI,CAAC,CAAC;AAAA,IAC1D,KAAK;AACH,aAAO,CAAC,UAAU,IAAI,GAAG,MAAM,GAAG,GAAG,OAAO,KAAK,GAAG,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC;AAAA,IACxE,KAAK,eAAe;AAClB,YAAM,UAAU,GAAG,SAAS,MAAM;AAClC,YAAM,UAAU,GAAG,SAAS,KAAK,GAAG,QAAQ;AAC5C,YAAM,SAAS,YAAY,UAAa,YAAY,OAAO,SAAS,OAAO,IAAI;AAC/E,aAAO;AAAA,QACL,KAAK,UAAU,UAAU,QAAQ,QAAQ;AAAA,UACvC,MAAM;AAAA,UACN,GAAI,UAAU,EAAE,SAAS,KAAK,IAAI,CAAC;AAAA,UACnC,GAAI,OAAO,GAAG,IAAI,MAAM,WAAW,EAAE,WAAW,GAAG,IAAI,EAAE,IAAI,CAAC;AAAA,QAChE,CAAC;AAAA,MACH;AAAA,IACF;AAAA,IACA,KAAK,iBAAiB;AACpB,YAAM,UAAU,GAAG,SAAS,MAAM;AAClC,YAAM,UAAU,GAAG,QAAQ,KAAK,GAAG,SAAS;AAC5C,YAAM,SAAS,YAAY,UAAa,YAAY,OAAO,SAAS,OAAO,IAAI;AAC/E,UAAI,CAAC,OAAO,KAAK,KAAK,CAAC,WAAW,OAAO,GAAG,YAAY,MAAM,SAAU,QAAO,CAAC;AAChF,aAAO;AAAA,QACL,KAAK,UAAU,UAAU,QAAQ,QAAQ;AAAA,UACvC,MAAM,OAAO,GAAG,MAAM,MAAM,WAAW,OAAO,GAAG,MAAM,CAAC,IAAI;AAAA,UAC5D,GAAI,OAAO,GAAG,YAAY,MAAM,WAAW,EAAE,YAAY,GAAG,YAAY,EAAE,IAAI,CAAC;AAAA,UAC/E,GAAI,UAAU,EAAE,SAAS,KAAK,IAAI,CAAC;AAAA,UACnC,GAAI,OAAO,GAAG,IAAI,MAAM,WAAW,EAAE,WAAW,GAAG,IAAI,EAAE,IAAI,CAAC;AAAA,QAChE,CAAC;AAAA,MACH;AAAA,IACF;AAAA,IACA,KAAK;AAAA,IACL,KAAK;AACH,aAAO,CAAC,KAAK,SAAS,OAAO,GAAG,SAAS,KAAK,OAAO,CAAC,CAAC;AAAA,IACzD,KAAK;AACH,aAAO,CAAC,KAAK,UAAU,WAAW,OAAO,GAAG,MAAM,KAAK,OAAO,CAAC,EAAE,CAAC;AAAA,IACpE,KAAK;AACH,aAAO,CAAC,KAAK,UAAU,cAAc,OAAO,GAAG,OAAO,KAAK,EAAE,CAAC,EAAE,CAAC;AAAA,IACnE,KAAK;AACH,aAAO,CAAC,KAAK,UAAU,gBAAgB,OAAO,GAAG,OAAO,KAAK,EAAE,CAAC,EAAE,CAAC;AAAA,IACrE;AACE,aAAO,CAAC;AAAA,EACZ;AACF;AAOA,SAAS,cAAc,GAA+B;AACpD,UACG,EAAE,SAAS,UAAU,EAAE,SAAS,YACjC,EAAE,cAAc,UAChB,EAAE,cAAc;AAEpB;AAQO,SAAS,iBAAiB,MAAyD;AACxF,QAAM,MAA2B,CAAC;AAClC,QAAM,WAAW,oBAAI,IAA+B;AACpD,aAAW,OAAO,MAAM;AACtB,UAAM,IAAuB,EAAE,GAAG,IAAI;AACtC,QAAI,cAAc,CAAC,KAAK,EAAE,cAAc,QAAW;AACjD,YAAM,MAAM,SAAS,IAAI,EAAE,SAAS;AACpC,UAAI,KAAK;AACP,YAAI,OAAO,EAAE,QAAQ;AACrB,YAAI,EAAE,eAAe,OAAW,KAAI,aAAa,EAAE;AACnD,YAAI,EAAE,SAAS;AACb,cAAI,OAAO;AACX,cAAI,UAAU;AAAA,QAChB;AACA;AAAA,MACF;AAAA,IACF;AACA,QAAI,KAAK,CAAC;AACV,QAAI,EAAE,SAAS,UAAU,EAAE,cAAc,UAAa,EAAE,cAAc,QAAW;AAC/E,eAAS,IAAI,EAAE,WAAW,CAAC;AAAA,IAC7B;AAAA,EACF;AACA,SAAO;AACT;AAOO,SAAS,0BACd,QACqB;AACrB,QAAM,OAA4B,CAAC;AACnC,aAAW,MAAM,QAAQ;AACvB,eAAW,KAAK,yBAAyB,EAAE,EAAG,MAAK,KAAK,CAAC;AAAA,EAC3D;AACA,SAAO,iBAAiB,IAAI;AAC9B;;;AD7JA,IAAM,qBAAqB,oBAAI,IAA8B;AAAA,EAC3D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AACD,IAAM,+BAA+B;AACrC,IAAM,6BAA6B,MAAM;AAEzC,SAAS,eAAe,GAAgD;AACtE,QAAM,SACJ,mBAAmB,IAAI,EAAE,MAAkC,IAAI,EAAE,SAAS;AAE5E,SAAO;AAAA,IACL,IAAI,EAAE;AAAA,IACN,MAAM,EAAE;AAAA,IACR;AAAA,IACA,YAAY,EAAE;AAAA,IACd,WAAW,EAAE;AAAA,IACb,gBAAgB,EAAE;AAAA,IAClB,GAAI,EAAE,cAAc,SAAY,EAAE,WAAW,EAAE,UAAU,IAAI,CAAC;AAAA,IAC9D,GAAI,EAAE,gBAAgB,SAAY,EAAE,aAAa,EAAE,YAAY,IAAI,CAAC;AAAA,IACpE,GAAI,EAAE,YAAY,SAAY,EAAE,SAAS,EAAE,QAAQ,IAAI,CAAC;AAAA,IACxD,GAAI,EAAE,aAAa,SAAY,EAAE,UAAU,EAAE,SAAS,IAAI,CAAC;AAAA,IAC3D,GAAI,EAAE,cAAc,SAAY,EAAE,WAAW,EAAE,UAAU,IAAI,CAAC;AAAA,IAC9D,GAAI,EAAE,WAAW,SAAY,EAAE,QAAQ,EAAE,OAAO,IAAI,CAAC;AAAA,IACrD,GAAI,EAAE,UAAU,SAAY,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAAA,IAClD,GAAI,EAAE,gBAAgB,SAAY,EAAE,aAAa,EAAE,YAAY,IAAI,CAAC;AAAA,EACtE;AACF;AAEA,SAAS,oBAAoB,QAA+D;AAC1F,SAAO,OAAO;AAAA,IACZ,CAAC,MAAM,EAAE,WAAW,aAAa,EAAE,WAAW,eAAe,EAAE,WAAW;AAAA,EAC5E,IACI,WACA;AACN;AAMO,SAAS,4BAA4B,MAAiD;AAC3F,QAAM,MAAM,KAAK,QAAQ,OAAM,oBAAI,KAAK,GAAE,YAAY;AACtD,QAAM,YAAY,KAAK;AACvB,QAAM,WAAW,UAAU;AAC3B,QAAM,UAAU,UAAU;AAC1B,QAAM,YAAY,KAAK,aAAa,IAAI;AAExC,QAAM,SAAS,mBAAmB;AAAA,IAChC,aAAa,KAAK;AAAA,IAClB,GAAI,KAAK,eAAe,SAAY,EAAE,YAAY,KAAK,WAAW,IAAI,CAAC;AAAA,EACzE,CAAC;AACD,QAAM,cAAc,kBAAkB,OAAO,iBAAiB,KAAK,WAAW,QAAQ;AAEtF,MAAI,UAAmC,KAAK,iBAAiB,CAAC,GAAG,IAAI,cAAc;AACnF,MAAI,iBAAiB,OAAO;AAAA,IAC1B,CAAC,QAAQ,UAAU,MAAM,iBAAiB,SAAS,MAAM,iBAAiB;AAAA,IAC1E;AAAA,EACF;AACA,MAAI,mBAAmB;AACvB,MAAI,WAAW;AAEf,WAAS,gBAA0C;AACjD,WAAO;AAAA,MACL,WAAW,KAAK;AAAA,MAChB,YAAY,SAAS;AAAA,MACrB,WAAW,SAAS;AAAA,MACpB,WAAW,QAAQ;AAAA,MACnB,aAAa,KAAK,eAAe,QAAQ;AAAA,MACzC,aAAa,KAAK;AAAA,MAClB,QAAQ,oBAAoB,MAAM;AAAA,MAClC;AAAA,MACA;AAAA,MACA,YAAY,OAAO;AAAA,MACnB;AAAA,MACA,GAAI,SAAS,aAAa,SAAY,EAAE,UAAU,SAAS,SAAS,IAAI,CAAC;AAAA,MACzE,GAAI,SAAS,QAAQ,SAAY,EAAE,KAAK,SAAS,IAAI,IAAI,CAAC;AAAA,MAC1D,GAAI,KAAK,cAAc,SAAY,EAAE,WAAW,KAAK,UAAU,IAAI,CAAC;AAAA,IACtE;AAAA,EACF;AAEA,WAAS,gBAAgB,QAAQ,OAAa;AAC5C,QAAI,SAAU;AACd,UAAM,OAAO,cAAc;AAG3B,UAAM,OAAO,KAAK,UAAU,EAAE,GAAG,MAAM,gBAAgB,GAAG,CAAC;AAC3D,QAAI,CAAC,SAAS,SAAS,iBAAkB;AACzC,uBAAmB;AACnB,QAAI;AACF,gBAAU,uBAAuB,IAAI;AAAA,IACvC,QAAQ;AAAA,IAER;AAAA,EACF;AAEA,WAAS,yBAAyB,SAAoC;AACpE,QAAI,QAA6B,CAAC;AAClC,QAAI,eAAe;AAEnB,UAAM,eAAe,MAAY;AAC/B,UAAI,MAAM,WAAW,EAAG;AACxB,UAAI;AACF,kBAAU,wBAAwB;AAAA,UAChC,WAAW,KAAK;AAAA,UAChB,SAAS;AAAA,UACT,SAAS;AAAA,QACX,CAAC;AAAA,MACH,QAAQ;AAAA,MAER;AACA,oBAAc,MAAM;AACpB,cAAQ,CAAC;AACT,qBAAe;AAAA,IACjB;AAEA,eAAW,SAAS,SAAS;AAC3B,YAAM,YAAY,CAAC,GAAG,OAAO,KAAK;AAClC,YAAM,mBAAmB;AAAA,QACvB,WAAW,KAAK;AAAA,QAChB,SAAS;AAAA,QACT,SAAS;AAAA,MACX;AACA,YAAM,iBAAiB,UAAU,SAAS;AAC1C,YAAM,WACJ,MAAM,SAAS,KACf,OAAO,WAAW,KAAK,UAAU,gBAAgB,GAAG,MAAM,IACxD;AACJ,UAAI,kBAAkB,SAAU,cAAa;AAC7C,YAAM,KAAK,KAAK;AAAA,IAClB;AAEA,iBAAa;AAAA,EACf;AAEA,QAAM,YAAY,KAAK,QAAQ,GAAG,0BAA0B,CAAC,YAAY;AACvE,aAAS,QAAQ,OAAO,IAAI,cAAc;AAC1C,qBAAiB,IAAI;AACrB,oBAAgB;AAAA,EAClB,CAAC;AAID,kBAAgB,IAAI;AAGpB,MAAI,SAAS;AACb,MAAI,UAAU;AACd,MAAI,aAAa;AACjB,MAAI,UAAU;AACd,MAAI,UAA+B;AACnC,MAAI,eAAe;AAInB,WAAS,eAAqB;AAC5B,QAAI,YAAY,QAAS;AACzB,QAAI;AACF,YAAM,cAAiB,UAAM,aAAa,MAAM;AAC9C,YAAI,gBAAgB,SAAU;AAC9B,uBAAe;AACf,mBAAW,MAAM;AACf,yBAAe;AACf,eAAK,KAAK;AAAA,QACZ,GAAG,EAAE;AAAA,MACP,CAAC;AAID,kBAAY,GAAG,SAAS,MAAM;AAC5B,YAAI;AACF,sBAAY,MAAM;AAAA,QACpB,QAAQ;AAAA,QAER;AACA,YAAI,YAAY,YAAa,WAAU;AAAA,MACzC,CAAC;AACD,gBAAU;AAAA,IACZ,QAAQ;AACN,gBAAU;AAAA,IACZ;AAAA,EACF;AAEA,iBAAe,OAAsB;AACnC,QAAI,YAAY,QAAS;AACzB,cAAU;AACV,QAAI;AACF,YAAMC,QAAO,MAAU,UAAK,WAAW,EAAE,MAAM,MAAM,IAAI;AACzD,UAAI,SAAU;AACd,UAAI,CAACA,MAAM;AACX,mBAAa;AACb,UAAIA,MAAK,QAAQ,OAAQ;AACzB,YAAM,KAAK,MAAU,UAAK,aAAa,GAAG;AAC1C,UAAI;AACF,YAAI,SAAU;AACd,cAAM,MAAMA,MAAK,OAAO;AACxB,cAAM,MAAM,OAAO,YAAY,GAAG;AAClC,cAAM,GAAG,KAAK,KAAK,GAAG,KAAK,MAAM;AACjC,iBAASA,MAAK;AACd,mBAAW,IAAI,SAAS,MAAM;AAC9B,cAAM,QAAQ,QAAQ,MAAM,IAAI;AAChC,kBAAU,MAAM,IAAI,KAAK;AACzB,cAAM,UAA+B,CAAC;AACtC,mBAAW,QAAQ,OAAO;AACxB,gBAAM,UAAU,KAAK,KAAK;AAC1B,cAAI,CAAC,QAAS;AACd,cAAI;AACJ,cAAI;AACF,kBAAM,KAAK,MAAM,OAAO;AAAA,UAC1B,QAAQ;AACN;AAAA,UACF;AACA,qBAAW,SAAS,yBAAyB,GAAG,EAAG,SAAQ,KAAK,KAAK;AAAA,QACvE;AACA,YAAI,QAAQ,SAAS,GAAG;AACtB,mCAAyB,OAAO;AAChC,2BAAiB,IAAI;AAAA,QACvB;AAAA,MACF,UAAE;AACA,cAAM,GAAG,MAAM;AAAA,MACjB;AAAA,IACF,QAAQ;AAAA,IAER,UAAE;AACA,gBAAU;AAAA,IACZ;AAAA,EACF;AAEA,QAAM,gBAAgB,YAAY,MAAM,gBAAgB,IAAI,GAAG,KAAK,sBAAsB,IAAI;AAC9F,QAAM,YAAY,YAAY,MAAM,KAAK,KAAK,GAAG,KAAK,wBAAwB,GAAG;AACjF,gBAAc,QAAQ;AACtB,YAAU,QAAQ;AAClB,OAAK,KAAK;AAEV,SAAO,MAAM;AACX,QAAI,SAAU;AACd,eAAW;AACX,gBAAY;AACZ,QAAI,SAAS;AACX,UAAI;AACF,gBAAQ,MAAM;AAAA,MAChB,QAAQ;AAAA,MAER;AACA,gBAAU;AAAA,IACZ;AACA,kBAAc,aAAa;AAC3B,kBAAc,SAAS;AACvB,QAAI;AACF,gBAAU,oBAAoB,EAAE,WAAW,KAAK,WAAW,SAAS,IAAI,EAAE,CAAC;AAAA,IAC7E,QAAQ;AAAA,IAER;AAAA,EACF;AACF;;;AE/QO,SAAS,0BAA0B,MAA+C;AACvF,QAAM,EAAE,QAAQ,WAAW,MAAM,IAAI;AACrC,QAAM,MAAM,KAAK,QAAQ,OAAM,oBAAI,KAAK,GAAE,YAAY;AACtD,MAAI,WAAW;AAEf,WAAS,aAAa,OASK;AACzB,UAAM,YAAiC,MAAM,iBAAiB,IAAI,CAAC,OAAO;AAAA,MACxE,YAAY,EAAE;AAAA,MACd,GAAI,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,IAAI,CAAC;AAAA,MACrC,QAAQ,wBAAwB,EAAE,MAAM;AAAA,IAC1C,EAAE;AACF,WAAO;AAAA,MACL;AAAA,MACA,iBAAiB,MAAM,UAAU,MAAM;AAAA,MACvC,aAAa,MAAM;AAAA,MACnB,gBAAgB,MAAM;AAAA,MACtB,aAAa,MAAM;AAAA,MACnB;AAAA,IACF;AAAA,EACF;AAEA,QAAM,MAAM,OAAO,GAAG,qBAAqB,CAAC,UAAU;AACpD,QAAI;AACF,YAAM,UAAU,aAAa,KAAK;AAElC,YAAM,OAAO,KAAK,UAAU,OAAO;AACnC,UAAI,SAAS,SAAU;AACvB,iBAAW;AACX,gBAAU,qBAAqB,SAAS;AAAA,QACtC,GAAI,KAAK,cAAc,SAAY,EAAE,WAAW,KAAK,UAAU,IAAI,CAAC;AAAA,QACpE,WAAW,IAAI;AAAA,MACjB,CAAC;AAAA,IACH,QAAQ;AAAA,IAER;AAAA,EACF,CAAC;AAED,SAAO,MAAM;AACX,QAAI;AAAA,EACN;AACF;AAEA,IAAM,mBAAgE;AAAA,EACpE,SAAS;AAAA,EACT,MAAM;AAAA,EACN,SAAS;AAAA,EACT,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,SAAS;AAAA,EACT,kBAAkB;AACpB;AAEA,SAAS,wBAAwB,KAA0C;AACzE,SAAO,iBAAiB,GAAG,KAAK;AAClC;;;ACrEA,SAAS,qBAAqB,KAK5B;AACA,MAAI,QAAQ,OAAW,QAAO,CAAC;AAC/B,QAAM,MAAiF,CAAC;AACxF,MAAI,OAAO,IAAI,OAAO,SAAU,KAAI,YAAY,IAAI;AACpD,MAAI,OAAO,IAAI,aAAa,SAAU,KAAI,WAAW,IAAI;AACzD,MAAI,OAAO,IAAI,WAAW,SAAU,KAAI,SAAS,IAAI;AACrD,MAAI,OAAO,IAAI,SAAS,SAAU,KAAI,OAAO,IAAI;AACjD,SAAO;AACT;AAEA,SAAS,sBAAsB,KAAwE;AACrG,MAAI,QAAQ,OAAW,QAAO,CAAC;AAC/B,QAAM,MAA8C,CAAC;AAErD,MAAI,WAAW,IAAI;AACnB,MAAI,IAAI,SAAS,UAAU;AACzB,QAAI,SAAS,IAAI;AAAA,EACnB,WAAW,IAAI,SAAS,aAAa;AACnC,QAAI,SAAS,IAAI;AAAA,EACnB,WAAW,IAAI,SAAS,QAAQ;AAC9B,QAAI,SAAS,IAAI;AAAA,EACnB;AACA,SAAO;AACT;AAMO,SAAS,0BAA0B,MAA+C;AACvF,QAAM,EAAE,QAAQ,UAAU,IAAI;AAC9B,QAAM,MAAM,KAAK,QAAQ,OAAM,oBAAI,KAAK,GAAE,YAAY;AAEtD,WAAS,QAAQ,MAAwB,SAAuC,IAAkB;AAChG,QAAI;AACF,YAAM,OAA4B,EAAE,MAAM,IAAI,GAAG,QAAQ;AACzD,gBAAU,aAAa;AAAA,QACrB,MAAM;AAAA,QACN,SAAS;AAAA,QACT,GAAI,KAAK,cAAc,SAAY,EAAE,WAAW,KAAK,UAAU,IAAI,CAAC;AAAA,QACpE,WAAW,IAAI;AAAA,MACjB,CAAC;AAAA,IACH,QAAQ;AAAA,IAER;AAAA,EACF;AAEA,QAAM,OAA0B,CAAC;AAEjC,OAAK;AAAA,IACH,OAAO,GAAG,4BAA4B,CAAC,MAAM;AAC3C,cAAQ,sBAAsB,qBAAqB,EAAE,OAAO,GAAG,EAAE,EAAE;AAAA,IACrE,CAAC;AAAA,EACH;AACA,OAAK;AAAA,IACH,OAAO,GAAG,2BAA2B,CAAC,MAAM;AAC1C,cAAQ,qBAAqB;AAAA,QAC3B,GAAG,qBAAqB,EAAE,OAAO;AAAA,QACjC,GAAG,sBAAsB,EAAE,QAAQ;AAAA,MACrC,GAAG,EAAE,EAAE;AAAA,IACT,CAAC;AAAA,EACH;AACA,OAAK;AAAA,IACH,OAAO,GAAG,4BAA4B,CAAC,MAAM;AAC3C,cAAQ,sBAAsB;AAAA,QAC5B,GAAG,qBAAqB,EAAE,OAAO;AAAA,QACjC,GAAG,sBAAsB,EAAE,QAAQ;AAAA,MACrC,GAAG,EAAE,EAAE;AAAA,IACT,CAAC;AAAA,EACH;AACA,OAAK;AAAA,IACH,OAAO,GAAG,yBAAyB,CAAC,MAAM;AACxC,cAAQ,mBAAmB;AAAA,QACzB,GAAG,qBAAqB,EAAE,OAAO;AAAA,QACjC,GAAG,sBAAsB,EAAE,QAAQ;AAAA,MACrC,GAAG,EAAE,EAAE;AAAA,IACT,CAAC;AAAA,EACH;AACA,OAAK;AAAA,IACH,OAAO,GAAG,wBAAwB,CAAC,MAAM;AACvC,YAAM,SAAS,OAAO,EAAE,SAAS,WAAW,EAAE,OAAO,EAAE;AACvD,cAAQ,kBAAkB;AAAA,QACxB,WAAW,EAAE;AAAA,QACb,GAAI,WAAW,SAAY,EAAE,OAAO,IAAI,CAAC;AAAA,QACzC,GAAI,EAAE,SAAS,OAAO,EAAE,UAAU,OAAO,IAAI,CAAC;AAAA,MAChD,GAAG,EAAE,EAAE;AAAA,IACT,CAAC;AAAA,EACH;AACA,OAAK;AAAA,IACH,OAAO,GAAG,sBAAsB,CAAC,MAAM;AACrC,cAAQ,gBAAgB;AAAA,QACtB,GAAG,qBAAqB,EAAE,OAAO;AAAA,QACjC,GAAG,sBAAsB,EAAE,QAAQ;AAAA,QACnC,kBAAkB,EAAE;AAAA,QACpB,YAAY,EAAE;AAAA,MAChB,GAAG,EAAE,EAAE;AAAA,IACT,CAAC;AAAA,EACH;AAEA,SAAO,MAAM;AACX,eAAW,OAAO,KAAM,KAAI;AAAA,EAC9B;AACF;;;ACxDO,SAAS,6BAA6B,MAAkD;AAC7F,QAAM,EAAE,QAAQ,UAAU,IAAI;AAC9B,QAAM,MAAM,KAAK,QAAQ,OAAM,oBAAI,KAAK,GAAE,YAAY;AAEtD,WAAS,QAAQ,SAAiC,WAA0B;AAC1E,QAAI;AACF,gBAAU,aAAa;AAAA,QACrB,MAAM;AAAA,QACN;AAAA,QACA,GAAI,cAAc,UAAa,cAAc,KAAK,EAAE,UAAU,IAAI,CAAC;AAAA,QACnE,GAAI,KAAK,cAAc,SAAY,EAAE,WAAW,KAAK,UAAU,IAAI,CAAC;AAAA,QACpE,WAAW,IAAI;AAAA,MACjB,CAAC;AAAA,IACH,QAAQ;AAAA,IAER;AAAA,EACF;AAEA,QAAM,OAA0B,CAAC;AAEjC,OAAK;AAAA,IACH,OAAO,GAAG,sBAAsB,CAAC,MAAyB;AACxD;AAAA,QACE;AAAA,UACE,MAAM;AAAA,UACN,UAAU,EAAE;AAAA,UACZ,SAAS,EAAE;AAAA,UACX,YAAY,EAAE;AAAA,UACd,MAAM,EAAE;AAAA,UACR,QAAQ,EAAE;AAAA,UACV,YAAY,EAAE;AAAA,QAChB;AAAA,QACA,EAAE;AAAA,MACJ;AAAA,IACF,CAAC;AAAA,EACH;AAEA,OAAK;AAAA,IACH,OAAO,GAAG,sBAAsB,CAAC,MAAyB;AACxD;AAAA,QACE;AAAA,UACE,MAAM;AAAA,UACN,UAAU,EAAE;AAAA,UACZ,SAAS,EAAE;AAAA,UACX,QAAQ,EAAE;AAAA,UACV,YAAY,EAAE;AAAA,UACd,WAAW,EAAE;AAAA,UACb,OAAO,EAAE;AAAA,UACT,GAAI,EAAE,QAAQ,SAAY,EAAE,KAAK,EAAE,IAAI,IAAI,CAAC;AAAA,QAC9C;AAAA,QACA,EAAE;AAAA,MACJ;AAAA,IACF,CAAC;AAAA,EACH;AAEA,OAAK;AAAA,IACH,OAAO,GAAG,mBAAmB,CAAC,MAAsB;AAClD;AAAA,QACE;AAAA,UACE,MAAM;AAAA,UACN,UAAU,EAAE;AAAA,UACZ,SAAS,EAAE;AAAA,UACX,QAAQ,EAAE;AAAA,UACV,YAAY,EAAE;AAAA,UACd,QAAQ,EAAE;AAAA,QACZ;AAAA,QACA,EAAE;AAAA,MACJ;AAAA,IACF,CAAC;AAAA,EACH;AAEA,OAAK;AAAA,IACH,OAAO,GAAG,qBAAqB,CAAC,MAAwB;AACtD;AAAA,QACE;AAAA,UACE,MAAM;AAAA,UACN,UAAU,EAAE;AAAA,UACZ,SAAS,EAAE;AAAA,UACX,QAAQ,EAAE;AAAA,UACV,eAAe,EAAE;AAAA,QACnB;AAAA,QACA,EAAE;AAAA,MACJ;AAAA,IACF,CAAC;AAAA,EACH;AAEA,OAAK;AAAA,IACH,OAAO,GAAG,qBAAqB,CAAC,MAAwB;AACtD;AAAA,QACE;AAAA,UACE,MAAM;AAAA,UACN,UAAU,EAAE;AAAA,UACZ,SAAS,EAAE;AAAA,UACX,QAAQ,EAAE;AAAA,UACV,MAAM,EAAE;AAAA,QACV;AAAA,QACA,EAAE;AAAA,MACJ;AAAA,IACF,CAAC;AAAA,EACH;AAEA,OAAK;AAAA,IACH,OAAO,GAAG,mBAAmB,CAAC,MAAsB;AAClD;AAAA,QACE;AAAA,UACE,MAAM;AAAA,UACN,UAAU,EAAE;AAAA,UACZ,SAAS,EAAE;AAAA,UACX,GAAI,EAAE,WAAW,SAAY,EAAE,QAAQ,EAAE,OAAO,IAAI,CAAC;AAAA,UACrD,OAAO,EAAE;AAAA,QACX;AAAA,QACA,EAAE;AAAA,MACJ;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO,MAAM;AACX,eAAW,OAAO,KAAM,KAAI;AAAA,EAC9B;AACF;;;AC1IO,SAAS,yBAAyB,MAA8C;AACrF,QAAM,EAAE,QAAQ,UAAU,IAAI;AAC9B,QAAM,MAAM,KAAK,QAAQ,OAAM,oBAAI,KAAK,GAAE,YAAY;AACtD,QAAM,WAAW,oBAAI,IAA0B;AAE/C,WAAS,aAAa,WAA4C;AAChE,UAAM,MAAM,aAAa,KAAK;AAC9B,WAAO,QAAQ,SAAY,EAAE,WAAW,IAAI,IAAI,CAAC;AAAA,EACnD;AAEA,QAAM,aAAa,OAAO,GAAG,gBAAgB,CAAC,MAAwB;AACpE,aAAS,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,WAAW,KAAK,IAAI,EAAE,CAAC;AAC1D,QAAI;AACF,YAAM,UAAgC;AAAA,QACpC,UAAU,EAAE;AAAA,QACZ,GAAI,EAAE,UAAU,SACZ;AAAA,UACE,cAAc,oBAAoB,EAAE,OAAO;AAAA,YACzC,QAAQ,UAAU;AAAA,YAClB,GAAI,KAAK,gBAAgB,SAAY,EAAE,aAAa,KAAK,YAAY,IAAI,CAAC;AAAA,UAC5E,CAAC;AAAA,QACH,IACA,CAAC;AAAA,MACP;AACA,gBAAU,aAAa;AAAA,QACrB,MAAM;AAAA,QACN;AAAA,QACA,GAAG,aAAa,EAAE,SAAS;AAAA,QAC3B,WAAW,IAAI;AAAA,MACjB,CAAC;AAAA,IACH,QAAQ;AAAA,IAER;AAAA,EACF,CAAC;AAED,QAAM,cAAc,OAAO,GAAG,iBAAiB,CAAC,MAAyB;AACvE,UAAM,KAAK,EAAE;AACb,QAAI,OAAO,OAAW,UAAS,OAAO,EAAE;AACxC,QAAI;AACF,YAAM,UAAkC;AAAA,QACtC,UAAU,EAAE;AAAA,QACZ,QAAQ,EAAE,KAAK,YAAY;AAAA,QAC3B,YAAY,EAAE;AAAA,QACd,GAAI,EAAE,WAAW,UAAa,EAAE,OAAO,SAAS,IAC5C,EAAE,eAAe,mBAAmB,EAAE,QAAQ,UAAU,eAAe,EAAE,IACzE,CAAC;AAAA,MACP;AACA,gBAAU,aAAa;AAAA,QACrB,MAAM;AAAA,QACN;AAAA,QACA,GAAG,aAAa,EAAE,SAAS;AAAA,QAC3B,WAAW,IAAI;AAAA,MACjB,CAAC;AAAA,IACH,QAAQ;AAAA,IAER;AAAA,EACF,CAAC;AAED,SAAO,MAAM;AACX,eAAW;AACX,gBAAY;AACZ,aAAS,MAAM;AAAA,EACjB;AACF;AAEA,SAAS,mBAAmB,QAAgB,QAAqC,MAAM,KAAc;AACnG,QAAM,WAAW,yBAAyB,MAAM;AAChD,MAAI,SAAS,YAAY;AACvB,QAAI,OAAO,UAAU,IAAK,QAAO;AACjC,WAAO,GAAG,OAAO,MAAM,GAAG,GAAG,CAAC,oBAAe,OAAO,SAAS,GAAG;AAAA,EAClE;AACA,SAAO,0BAA0B,QAAQ,GAAG,KAAK;AACnD;;;AC/FO,SAAS,yBAAyB,MAA8C;AACrF,QAAM,EAAE,QAAQ,UAAU,IAAI;AAC9B,QAAM,MAAM,KAAK,QAAQ,OAAM,oBAAI,KAAK,GAAE,YAAY;AAEtD,QAAM,MAAM,OAAO,GAAG,mBAAmB,CAAC,MAA2B;AACnE,QAAI;AACF,YAAM,UAA0B;AAAA,QAC9B,aAAa,EAAE,MAAM;AAAA,QACrB,cAAc,EAAE,MAAM;AAAA,QACtB,aAAa,EAAE,MAAM,QAAQ,EAAE,MAAM;AAAA,QACrC,SAAS,EAAE,KAAK;AAAA,MAClB;AACA,YAAM,YAAY,KAAK,aAAa,EAAE;AACtC,gBAAU,aAAa;AAAA,QACrB,MAAM;AAAA,QACN;AAAA,QACA,GAAI,cAAc,SAAY,EAAE,UAAU,IAAI,CAAC;AAAA,QAC/C,WAAW,IAAI;AAAA,MACjB,CAAC;AAAA,IACH,QAAQ;AAAA,IAER;AAAA,EACF,CAAC;AAED,SAAO,MAAM;AACX,QAAI;AAAA,EACN;AACF;;;AC3CA,YAAYC,SAAQ;AACpB,YAAYC,WAAU;AAKtB,IAAM,8BAA8B;AAEpC,IAAM,gCAAgC;AAmB/B,IAAM,aAAN,MAAiB;AAAA,EACL;AAAA,EACA;AAAA,EACA;AAAA,EACT,aAA4B,QAAQ,QAAQ;AAAA,EAC5C,YAAY;AAAA,EACZ,UAAU;AAAA,EAElB,YAAY,MAAyB;AACnC,SAAK,WAAgB,WAAK,KAAK,SAAS,cAAc;AACtD,SAAK,WAAW,KAAK,YAAY;AACjC,SAAK,aAAa,KAAK,cAAc;AAAA,EACvC;AAAA;AAAA,EAGA,OAAO,OAA8B;AACnC,SAAK,aAAa,KAAK,WACpB,KAAK,MAAM,KAAK,eAAe,KAAK,CAAC,EACrC,MAAM,MAAM;AAAA,IAEb,CAAC;AAAA,EACL;AAAA;AAAA,EAGA,MAAM,QAAuB;AAC3B,UAAM,KAAK,WAAW,MAAM,MAAM;AAAA,IAElC,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,eAAe,OAAuC;AAClE,QAAI,CAAC,KAAK,SAAS;AACjB,WAAK,YAAY,MAAM,KAAK,WAAW;AACvC,WAAK,UAAU;AAAA,IACjB;AACA,UAAM,OAAO,KAAK,UAAU,KAAK,IAAI;AACrC,UAAS,eAAW,KAAK,UAAU,MAAM,EAAE,UAAU,OAAO,CAAC;AAC7D,SAAK,aAAa;AAClB,QAAI,KAAK,aAAa,KAAK,UAAU;AACnC,YAAM,KAAK,OAAO;AAAA,IACpB;AAAA,EACF;AAAA,EAEA,MAAc,SAAwB;AACpC,UAAM,aAAa,KAAK,UAAU,YAAY;AAC5C,UAAI;AACF,cAAM,UAAU,MAAS,aAAS,KAAK,UAAU,MAAM;AACvD,cAAM,QAAQ,QAAQ,MAAM,IAAI,EAAE,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC;AAC5D,YAAI,MAAM,UAAU,KAAK,YAAY;AACnC,eAAK,YAAY,MAAM;AACvB;AAAA,QACF;AACA,cAAM,OAAO,MAAM,MAAM,MAAM,SAAS,KAAK,UAAU;AACvD,cAAM,YAAY,KAAK,UAAU,KAAK,KAAK,IAAI,IAAI,IAAI;AACvD,aAAK,YAAY,KAAK;AAAA,MACxB,QAAQ;AAAA,MAER;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,aAA8B;AAC1C,QAAI;AACF,YAAM,UAAU,MAAS,aAAS,KAAK,UAAU,MAAM;AACvD,aAAO,QAAQ,MAAM,IAAI,EAAE,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE;AAAA,IACzD,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,OAAO,OAAe,YAAiD;AAC3E,QAAI;AACJ,QAAI;AACF,gBAAU,MAAS,aAAS,KAAK,UAAU,MAAM;AAAA,IACnD,QAAQ;AACN,aAAO,CAAC;AAAA,IACV;AACA,UAAM,QAAQ,QAAQ,MAAM,IAAI,EAAE,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC;AAC5D,UAAM,MAAyB,CAAC;AAEhC,aAAS,IAAI,MAAM,SAAS,GAAG,KAAK,KAAK,IAAI,SAAS,OAAO,KAAK;AAChE,UAAI;AACF,cAAM,MAAM,KAAK,MAAM,MAAM,CAAC,CAAE;AAChC,YAAI,eAAe,UAAa,IAAI,SAAS,YAAY;AACvD,cAAI,KAAK,GAAG;AAAA,QACd;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,MAAM,UAAyB;AAC7B,SAAK,YAAY,MAAM,KAAK,WAAW;AACvC,SAAK,UAAU;AAAA,EACjB;AACF;AAaO,IAAM,kBAAN,MAAsB;AAAA,EACV;AAAA,EACT,aAA4B,QAAQ,QAAQ;AAAA,EAEpD,YAAY,MAA8B;AACxC,SAAK,WAAgB,WAAK,KAAK,SAAS,eAAe;AAAA,EACzD;AAAA;AAAA,EAGA,KAAK,UAA4B;AAC/B,SAAK,aAAa,KAAK,WACpB,KAAK,MAAM,YAAY,KAAK,UAAU,KAAK,UAAU,QAAQ,GAAG,EAAE,MAAM,IAAM,CAAC,CAAC,EAChF,MAAM,MAAM;AAAA,IAEb,CAAC;AAAA,EACL;AAAA;AAAA,EAGA,MAAM,QAAuB;AAC3B,UAAM,KAAK,WAAW,MAAM,MAAM;AAAA,IAElC,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,OAAmC;AACvC,QAAI;AACF,YAAM,UAAU,MAAS,aAAS,KAAK,UAAU,MAAM;AACvD,aAAO,KAAK,MAAM,OAAO;AAAA,IAC3B,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAoCO,IAAM,oBAAN,MAAwB;AAAA,EACZ;AAAA,EACA;AAAA,EACA;AAAA,EACA,UAAU,oBAAI,IAAgC;AAAA,EACvD,aAA4B,QAAQ,QAAQ;AAAA,EAEpD,YAAY,MAAgC;AAC1C,SAAK,WAAgB,WAAK,KAAK,SAAS,kBAAkB;AAC1D,SAAK,WAAW,KAAK,YAAY,IAAI,KAAK;AAC1C,SAAK,aAAa,KAAK,cAAc;AAAA,EACvC;AAAA,EAEQ,YAAY,IAAoB;AACtC,WAAO,KAAK,MAAM,KAAK,KAAK,QAAQ,IAAI,KAAK;AAAA,EAC/C;AAAA;AAAA,EAGA,OAAO,QAOE;AACP,UAAM,QAAQ,KAAK,YAAY,OAAO,MAAM,KAAK,IAAI,CAAC;AACtD,QAAI,SAAS,KAAK,QAAQ,IAAI,KAAK;AACnC,QAAI,CAAC,QAAQ;AACX,eAAS,EAAE,IAAI,OAAO,SAAS,GAAG,aAAa,GAAG,cAAc,GAAG,WAAW,EAAE;AAChF,WAAK,QAAQ,IAAI,OAAO,MAAM;AAAA,IAChC;AACA,QAAI,OAAO,YAAY,OAAW,QAAO,WAAW,OAAO;AAC3D,QAAI,OAAO,gBAAgB,OAAW,QAAO,eAAe,OAAO;AACnE,QAAI,OAAO,iBAAiB,OAAW,QAAO,gBAAgB,OAAO;AACrE,QAAI,OAAO,cAAc,OAAW,QAAO,aAAa,OAAO;AAC/D,QAAI,OAAO,iBAAiB,OAAW,QAAO,eAAe,OAAO;AAGpE,QAAI,KAAK,QAAQ,OAAO,KAAK,YAAY;AACvC,YAAM,SAAS,MAAM,KAAK,KAAK,QAAQ,KAAK,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC;AACnE,aAAO,KAAK,QAAQ,OAAO,KAAK,cAAc,OAAO,SAAS,GAAG;AAC/D,cAAM,SAAS,OAAO,MAAM;AAC5B,YAAI,WAAW,OAAW;AAC1B,aAAK,QAAQ,OAAO,MAAM;AAAA,MAC5B;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA,QAAc;AACZ,UAAM,WAAW,MAAM,KAAK,KAAK,QAAQ,OAAO,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,KAAK,EAAE,EAAE;AAC7E,QAAI,SAAS,WAAW,EAAG;AAC3B,SAAK,aAAa,KAAK,WACpB,KAAK,MAAM,KAAK,cAAc,QAAQ,CAAC,EACvC,MAAM,MAAM;AAAA,IAEb,CAAC;AAAA,EACL;AAAA;AAAA,EAGA,MAAM,QAAuB;AAC3B,UAAM,KAAK,WAAW,MAAM,MAAM;AAAA,IAElC,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,cAAc,SAA8C;AACxE,UAAM,QAAQ,QAAQ,IAAI,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,EAAE,KAAK,IAAI,IAAI;AACjE,UAAM,aAAa,KAAK,UAAU,YAAY;AAC5C,YAAS,eAAW,KAAK,UAAU,OAAO,EAAE,UAAU,OAAO,CAAC;AAAA,IAChE,CAAC;AAED,UAAM,SAAS,MAAM,KAAK,KAAK,QAAQ,KAAK,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC;AACnE,WAAO,KAAK,QAAQ,OAAO,KAAK,YAAY;AAC1C,YAAM,SAAS,OAAO,MAAM;AAC5B,UAAI,WAAW,OAAW;AAC1B,WAAK,QAAQ,OAAO,MAAM;AAAA,IAC5B;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,KAAK,SAAiD;AAE1D,QAAI,KAAK,QAAQ,SAAS,EAAG,OAAM,KAAK,KAAK;AAC7C,UAAM,QAAQ,WAAW;AACzB,WAAO,MAAM,KAAK,KAAK,QAAQ,OAAO,CAAC,EACpC,OAAO,CAAC,MAAM,EAAE,MAAM,KAAK,EAC3B,KAAK,CAAC,GAAG,MAAM,EAAE,KAAK,EAAE,EAAE;AAAA,EAC/B;AAAA;AAAA,EAGA,MAAM,OAAsB;AAC1B,QAAI;AACJ,QAAI;AACF,gBAAU,MAAS,aAAS,KAAK,UAAU,MAAM;AAAA,IACnD,QAAQ;AACN;AAAA,IACF;AACA,eAAW,QAAQ,QAAQ,MAAM,IAAI,GAAG;AACtC,YAAM,UAAU,KAAK,KAAK;AAC1B,UAAI,CAAC,QAAS;AACd,UAAI;AACF,cAAM,SAAS,KAAK,MAAM,OAAO;AAEjC,aAAK,QAAQ,IAAI,OAAO,IAAI,MAAM;AAAA,MACpC,QAAQ;AAAA,MAER;AAAA,IACF;AAEA,UAAM,SAAS,MAAM,KAAK,KAAK,QAAQ,KAAK,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC;AACnE,WAAO,KAAK,QAAQ,OAAO,KAAK,YAAY;AAC1C,YAAM,SAAS,OAAO,MAAM;AAC5B,UAAI,WAAW,OAAW;AAC1B,WAAK,QAAQ,OAAO,MAAM;AAAA,IAC5B;AAAA,EACF;AACF;AAUO,SAAS,oBAAoB,SAAgC;AAClE,SAAO;AAAA,IACL,UAAU,IAAI,WAAW,EAAE,QAAQ,CAAC;AAAA,IACpC,eAAe,IAAI,gBAAgB,EAAE,QAAQ,CAAC;AAAA,IAC9C,YAAY,IAAI,kBAAkB,EAAE,QAAQ,CAAC;AAAA,EAC/C;AACF;;;AC9VO,IAAM,mBAAmB;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAqFA,IAAM,sBAAsB,IAAI,IAAY,gBAAgB;AAWrD,SAAS,kBAAkB,QAA2C;AAC3E,MAAI,CAAC,oBAAoB,IAAI,OAAO,IAAI,EAAG,QAAO;AAClD,QAAM,IAAI,OAAO;AACjB,MAAI,MAAM,QAAQ,OAAO,MAAM,SAAU,QAAO;AAChD,UAAQ,OAAO,MAAuB;AAAA,IACpC,KAAK,SAAS;AACZ,UAAI,OAAO,EAAE,IAAI,MAAM,YAAY,OAAO,EAAE,SAAS,MAAM,YAAY,OAAO,EAAE,MAAM,MAAM,UAAU;AACpG,eAAO;AAAA,MACT;AACA,YAAM,SAAyB,EAAE,MAAM,SAAS,IAAI,EAAE,IAAI,GAAG,SAAS,EAAE,SAAS,GAAG,MAAM,EAAE,MAAM,EAAE;AACpG,UAAI,EAAE,UAAU,MAAM,SAAS,EAAE,UAAU,MAAM,YAAY,EAAE,UAAU,MAAM,QAAQ;AACrF,eAAO,WAAW,EAAE,UAAU;AAAA,MAChC;AACA,aAAO;AAAA,IACT;AAAA,IACA,KAAK,OAAO;AACV,UAAI,OAAO,EAAE,IAAI,MAAM,YAAY,OAAO,EAAE,SAAS,MAAM,YAAY,OAAO,EAAE,MAAM,MAAM,UAAU;AACpG,eAAO;AAAA,MACT;AACA,YAAM,SAAuB,EAAE,MAAM,OAAO,IAAI,EAAE,IAAI,GAAG,SAAS,EAAE,SAAS,GAAG,MAAM,EAAE,MAAM,EAAE;AAChG,UAAI,EAAE,UAAU,MAAM,SAAS,EAAE,UAAU,MAAM,YAAY,EAAE,UAAU,MAAM,QAAQ;AACrF,eAAO,WAAW,EAAE,UAAU;AAAA,MAChC;AACA,aAAO;AAAA,IACT;AAAA,IACA,KAAK,SAAS;AACZ,UAAI,OAAO,EAAE,IAAI,MAAM,YAAY,OAAO,EAAE,SAAS,MAAM,YAAY,OAAO,EAAE,MAAM,MAAM,UAAU;AACpG,eAAO;AAAA,MACT;AACA,YAAM,SAAyB,EAAE,MAAM,SAAS,IAAI,EAAE,IAAI,GAAG,SAAS,EAAE,SAAS,GAAG,MAAM,EAAE,MAAM,EAAE;AACpG,UAAI,EAAE,UAAU,MAAM,SAAS,EAAE,UAAU,MAAM,YAAY,EAAE,UAAU,MAAM,QAAQ;AACrF,eAAO,WAAW,EAAE,UAAU;AAAA,MAChC;AACA,aAAO;AAAA,IACT;AAAA,IACA,KAAK;AACH,UAAI,OAAO,EAAE,QAAQ,MAAM,SAAU,QAAO;AAC5C,aAAO,EAAE,MAAM,SAAS,QAAQ,EAAE,QAAQ,EAAE;AAAA,IAC9C,KAAK,SAAS;AACZ,UAAI,OAAO,EAAE,MAAM,MAAM,SAAU,QAAO;AAC1C,YAAM,SAAyB,EAAE,MAAM,SAAS,MAAM,EAAE,MAAM,EAAE;AAChE,UAAI,OAAO,EAAE,MAAM,MAAM,SAAU,QAAO,OAAO,EAAE,MAAM;AACzD,UAAI,OAAO,EAAE,eAAe,MAAM,SAAU,QAAO,gBAAgB,EAAE,eAAe;AACpF,aAAO;AAAA,IACT;AAAA,IACA,KAAK,aAAa;AAChB,UAAI,OAAO,EAAE,SAAS,MAAM,YAAY,OAAO,EAAE,MAAM,MAAM,SAAU,QAAO;AAC9E,YAAM,SAA6B,EAAE,MAAM,aAAa,SAAS,EAAE,SAAS,GAAG,MAAM,EAAE,MAAM,EAAE;AAC/F,UAAI,EAAE,UAAU,MAAM,SAAS,EAAE,UAAU,MAAM,YAAY,EAAE,UAAU,MAAM,QAAQ;AACrF,eAAO,WAAW,EAAE,UAAU;AAAA,MAChC;AACA,aAAO;AAAA,IACT;AAAA,IACA,KAAK,eAAe;AAClB,UAAI,OAAO,EAAE,SAAS,MAAM,SAAU,QAAO;AAC7C,YAAM,SAA8B,EAAE,MAAM,eAAe,SAAS,EAAE,SAAS,EAAE;AACjF,UAAI,OAAO,EAAE,KAAK,MAAM,SAAU,QAAO,MAAM,EAAE,KAAK;AACtD,aAAO;AAAA,IACT;AAAA,IACA;AACE,aAAO;AAAA,EACX;AACF;AAuBO,IAAM,oBAAN,MAAwB;AAAA,EACZ,UAAiC,CAAC;AAAA,EAClC;AAAA,EAEjB,YAAY,MAAM,KAAM;AACtB,SAAK,MAAM;AAAA,EACb;AAAA,EAEA,OAAO,OAAkC;AACvC,SAAK,QAAQ,KAAK,KAAK;AACvB,QAAI,KAAK,QAAQ,SAAS,KAAK,KAAK;AAClC,WAAK,QAAQ,OAAO,GAAG,KAAK,QAAQ,SAAS,KAAK,GAAG;AAAA,IACvD;AAAA,EACF;AAAA,EAEA,OAAO,WAAmB,OAA2C;AACnE,UAAM,QAAQ,KAAK,QAAQ,KAAK,CAAC,MAAM,EAAE,cAAc,SAAS;AAChE,QAAI,MAAO,QAAO,OAAO,OAAO,KAAK;AAAA,EACvC;AAAA;AAAA,EAGA,gBACE,WACA,UACA,OACS;AACT,UAAM,QAAQ,KAAK,QAAQ;AAAA,MACzB,CAAC,cAAc,UAAU,cAAc,aAAa,UAAU,aAAa;AAAA,IAC7E;AACA,QAAI,CAAC,MAAO,QAAO;AACnB,WAAO,OAAO,OAAO,KAAK;AAC1B,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,QAAQ,KAA4B;AACzC,WAAO,KAAK,QAAQ,MAAM,CAAC,KAAK;AAAA,EAClC;AACF;;;ACvMA,IAAM,iBAAsC;AAAA,EAC1C,kBAAkB;AAAA,EAClB,qBAAqB;AAAA,EACrB,WAAW;AACb;AAEA,SAAS,cAAc,QAAiD;AACtE,SAAO,EAAE,GAAG,gBAAgB,GAAI,UAAU,CAAC,EAAG;AAChD;AAEA,IAAM,QAAgC;AAAA,EACpC;AAAA,IACE,IAAI;AAAA,IACJ,UAAU;AAAA,IACV,UAAU,CAAC,UAAU,WAAW;AAC9B,UAAI,aAAa,KAAM,QAAO;AAC9B,YAAM,OAAO,SAAS,OAAO,gBAAgB;AAC7C,UAAI,QAAQ,OAAO,kBAAkB;AACnC,eAAO,eAAe,KAAK,QAAQ,CAAC,CAAC,wBAAwB,OAAO,iBAAiB,QAAQ,CAAC,CAAC;AAAA,MACjG;AACA,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,UAAU;AAAA,IACV,UAAU,CAAC,UAAU,QAAQ,QAAQ;AACnC,UAAI,aAAa,KAAM,QAAO;AAC9B,YAAM,WAAW,SAAS,YAAY,CAAC;AACvC,UAAI,SAAS,WAAW,EAAG,QAAO;AAClC,YAAM,SAAS,MAAM,OAAO,sBAAsB;AAClD,YAAM,QAAQ,SAAS,OAAO,CAAC,MAAM,KAAK,MAAM,EAAE,cAAc,IAAI,MAAM;AAC1E,UAAI,MAAM,WAAW,SAAS,QAAQ;AACpC,eAAO,OAAO,SAAS,MAAM,0BAA0B,OAAO,mBAAmB;AAAA,MACnF;AACA,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,UAAU;AAAA,IACV,UAAU,CAAC,UAAU,WAAW;AAC9B,UAAI,aAAa,QAAQ,OAAO,aAAa,EAAG,QAAO;AACvD,YAAM,SAAS,SAAS,OAAO,gBAAgB;AAC/C,UAAI,UAAU,OAAO,WAAW;AAC9B,eAAO,2BAA2B,MAAM,yBAAyB,OAAO,SAAS;AAAA,MACnF;AACA,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,UAAU;AAAA,IACV,UAAU,CAAC,aAAa;AACtB,UAAI,aAAa,KAAM,QAAO;AAE9B,YAAM,SAAS,SAAS,UAAU,CAAC;AACnC,YAAM,SAAS,OAAO,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,aAAa,CAAC;AAC/D,UAAI,UAAU,GAAG;AACf,eAAO,GAAG,MAAM;AAAA,MAClB;AACA,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAOO,IAAM,gBAAN,MAAoB;AAAA,EACR,SAAS,oBAAI,IAAqB;AAAA,EAClC,UAAqB,CAAC;AAAA,EACtB;AAAA,EACT,QAA+C;AAAA,EACtC;AAAA,EAEjB,YAAY,MAAkE;AAC5E,SAAK,UAAU,KAAK;AACpB,SAAK,aAAa,KAAK,cAAc;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,SAAS,UAA6B,QAA4B,MAAc,KAAK,IAAI,GAAc;AACrG,UAAM,WAAW,cAAc,MAAM;AACrC,UAAM,QAAmB,CAAC;AAC1B,UAAM,YAAY,oBAAI,IAAY;AAElC,eAAW,QAAQ,OAAO;AACxB,YAAM,UAAU,KAAK,SAAS,UAAU,UAAU,GAAG;AACrD,UAAI,YAAY,MAAM;AACpB,kBAAU,IAAI,KAAK,EAAE;AACrB,cAAM,WAAW,KAAK,OAAO,IAAI,KAAK,EAAE;AACxC,YAAI,aAAa,QAAW;AAE1B,gBAAM,QAAiB;AAAA,YACrB,IAAI,GAAG,KAAK,EAAE,IAAI,GAAG;AAAA,YACrB,QAAQ,KAAK;AAAA,YACb,UAAU,KAAK;AAAA,YACf;AAAA,YACA,cAAc;AAAA,YACd,aAAa;AAAA,UACf;AACA,eAAK,OAAO,IAAI,KAAK,IAAI,KAAK;AAC9B,eAAK,QAAQ,KAAK,KAAK;AACvB,cAAI,KAAK,QAAQ,SAAS,KAAK,WAAY,MAAK,QAAQ,OAAO,GAAG,KAAK,QAAQ,SAAS,KAAK,UAAU;AACvG,gBAAM,KAAK,KAAK;AAChB,eAAK,QAAQ,KAAK;AAAA,QACpB,OAAO;AAEL,mBAAS,cAAc;AAAA,QACzB;AAAA,MACF;AAAA,IACF;AAGA,eAAW,MAAM,MAAM,KAAK,KAAK,OAAO,KAAK,CAAC,GAAG;AAC/C,UAAI,CAAC,UAAU,IAAI,EAAE,GAAG;AACtB,aAAK,OAAO,OAAO,EAAE;AAAA,MACvB;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,eAA0B;AACxB,WAAO,MAAM,KAAK,KAAK,OAAO,OAAO,CAAC;AAAA,EACxC;AAAA;AAAA,EAGA,aAAa,QAAQ,KAAgB;AACnC,WAAO,KAAK,QAAQ,MAAM,CAAC,KAAK;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,cACE,aACA,QACA,aAAa,MACD;AACZ,QAAI,KAAK,UAAU,KAAM,QAAO,MAAM;AACtC,UAAM,OAAO,MAAY;AACvB,UAAI;AACF,cAAM,MAAM,OAAO,WAAW,aAAa,OAAO,IAAI;AACtD,aAAK,SAAS,YAAY,GAAG,GAAG;AAAA,MAClC,QAAQ;AAAA,MAER;AAAA,IACF;AACA,SAAK,QAAQ,YAAY,MAAM,UAAU;AACzC,SAAK,MAAM,QAAQ;AACnB,WAAO,MAAM;AACX,UAAI,KAAK,UAAU,MAAM;AACvB,sBAAc,KAAK,KAAK;AACxB,aAAK,QAAQ;AAAA,MACf;AAAA,IACF;AAAA,EACF;AACF;AAGO,SAAS,eAAe,OAAgC;AAC7D,SAAO;AAAA,IACL,MAAM;AAAA,IACN,UAAU,MAAM;AAAA,IAChB,SAAS,IAAI,MAAM,MAAM,KAAK,MAAM,OAAO;AAAA,IAC3C,WAAW,IAAI,KAAK,MAAM,WAAW,EAAE,YAAY;AAAA,EACrD;AACF;",
|
|
6
|
+
"names": ["redacted", "out", "createHash", "randomUUID", "fs", "basename", "randomUUID", "path", "path", "path", "projectHash", "stat", "stat", "resolve", "randomUUID", "randomBytes", "randomUUID", "fs", "path", "resolve", "randomBytes", "randomUUID", "createHash", "basename", "randomUUID", "fs", "fsp", "stat", "fs", "path"]
|
|
7
|
+
}
|