@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
CHANGED
|
@@ -1,56 +1,71 @@
|
|
|
1
|
-
import { randomUUID, randomBytes, createHash } from 'crypto';
|
|
2
|
-
import * as syncFs from 'fs';
|
|
3
|
-
import * as os from 'os';
|
|
4
|
-
import { hostname } from 'os';
|
|
5
|
-
import * as path2 from 'path';
|
|
6
|
-
import { basename } from 'path';
|
|
7
|
-
import * as fsp from 'fs/promises';
|
|
8
|
-
|
|
9
1
|
// src/hq/protocol.ts
|
|
10
2
|
var HQ_PROTOCOL_VERSION = 1;
|
|
11
3
|
var DEFAULT_HQ_REDACTION_POLICY = {
|
|
12
|
-
rawContent:
|
|
13
|
-
toolArgs: "
|
|
14
|
-
paths: "
|
|
4
|
+
rawContent: true,
|
|
5
|
+
toolArgs: "full",
|
|
6
|
+
paths: "full"
|
|
15
7
|
};
|
|
8
|
+
var HQ_TRANSCRIPT_TEXT_CAP = 16e3;
|
|
16
9
|
var KNOWN_HQ_CLIENT_FRAME_TYPES = /* @__PURE__ */ new Set([
|
|
17
10
|
"client.hello",
|
|
18
11
|
"client.event",
|
|
19
12
|
"client.command_poll",
|
|
20
13
|
"client.command_ack"
|
|
21
14
|
]);
|
|
15
|
+
var HQ_CLIENT_KINDS = /* @__PURE__ */ new Set(["tui", "repl", "webui", "cli", "unknown"]);
|
|
16
|
+
var HQ_WORKSPACE_KINDS = /* @__PURE__ */ new Set(["git", "directory", "unknown"]);
|
|
17
|
+
var HQ_CLIENT_CAPABILITIES = /* @__PURE__ */ new Set([
|
|
18
|
+
"telemetry.publish",
|
|
19
|
+
"session.summary",
|
|
20
|
+
"fleet.summary",
|
|
21
|
+
"mailbox.summary",
|
|
22
|
+
"control.receive"
|
|
23
|
+
]);
|
|
24
|
+
var HQ_COMMAND_ACK_STATUSES = /* @__PURE__ */ new Set([
|
|
25
|
+
"accepted",
|
|
26
|
+
"completed",
|
|
27
|
+
"failed",
|
|
28
|
+
"rejected"
|
|
29
|
+
]);
|
|
22
30
|
function hasStringType(x) {
|
|
23
31
|
return typeof x === "object" && x !== null && typeof x.type === "string";
|
|
24
32
|
}
|
|
25
33
|
function isHqClientIdentity(x) {
|
|
26
34
|
if (typeof x !== "object" || x === null) return false;
|
|
27
35
|
const v = x;
|
|
28
|
-
return typeof v.clientId === "string" && typeof v.kind === "string" && typeof v.machineId === "string" && typeof v.startedAt === "string";
|
|
36
|
+
return typeof v.clientId === "string" && typeof v.kind === "string" && HQ_CLIENT_KINDS.has(v.kind) && typeof v.machineId === "string" && typeof v.startedAt === "string";
|
|
29
37
|
}
|
|
30
38
|
function isHqProjectIdentity(x) {
|
|
31
39
|
if (typeof x !== "object" || x === null) return false;
|
|
32
40
|
const v = x;
|
|
33
|
-
return typeof v.projectId === "string" && typeof v.projectRoot === "string" && typeof v.projectName === "string" && typeof v.machineId === "string" && typeof v.workspaceKind === "string";
|
|
41
|
+
return typeof v.projectId === "string" && typeof v.projectRoot === "string" && typeof v.projectName === "string" && typeof v.machineId === "string" && typeof v.workspaceKind === "string" && HQ_WORKSPACE_KINDS.has(v.workspaceKind);
|
|
42
|
+
}
|
|
43
|
+
function isHqRedactionPolicy(x) {
|
|
44
|
+
if (typeof x !== "object" || x === null) return false;
|
|
45
|
+
const v = x;
|
|
46
|
+
return typeof v.rawContent === "boolean" && (v.toolArgs === "none" || v.toolArgs === "summary" || v.toolArgs === "redacted" || v.toolArgs === "full") && (v.paths === "none" || v.paths === "project-relative" || v.paths === "redacted" || v.paths === "full");
|
|
34
47
|
}
|
|
35
48
|
function isHqClientHelloPayload(x) {
|
|
36
49
|
if (typeof x !== "object" || x === null) return false;
|
|
37
50
|
const v = x;
|
|
38
|
-
return typeof v.protocolVersion === "number" && isHqClientIdentity(v.client) && isHqProjectIdentity(v.project) && Array.isArray(v.capabilities)
|
|
51
|
+
return typeof v.protocolVersion === "number" && isHqClientIdentity(v.client) && isHqProjectIdentity(v.project) && Array.isArray(v.capabilities) && v.capabilities.every(
|
|
52
|
+
(capability) => typeof capability === "string" && HQ_CLIENT_CAPABILITIES.has(capability)
|
|
53
|
+
) && (v.redactionPolicy === void 0 || isHqRedactionPolicy(v.redactionPolicy));
|
|
39
54
|
}
|
|
40
55
|
function isHqEventEnvelope(x) {
|
|
41
56
|
if (typeof x !== "object" || x === null) return false;
|
|
42
57
|
const v = x;
|
|
43
|
-
return typeof v.id === "string" && typeof v.type === "string" &&
|
|
58
|
+
return typeof v.id === "string" && typeof v.type === "string" && v.schemaVersion === HQ_PROTOCOL_VERSION && typeof v.timestamp === "string" && typeof v.clientId === "string" && typeof v.projectId === "string" && Number.isSafeInteger(v.seq) && v.seq >= 0 && Object.hasOwn(v, "payload");
|
|
44
59
|
}
|
|
45
60
|
function isHqClientCommandPollMessage(x) {
|
|
46
61
|
if (typeof x !== "object" || x === null) return false;
|
|
47
62
|
const v = x;
|
|
48
|
-
return typeof v.clientId === "string" && typeof v.projectId === "string";
|
|
63
|
+
return typeof v.clientId === "string" && typeof v.projectId === "string" && (v.afterCommandId === void 0 || typeof v.afterCommandId === "string") && (v.limit === void 0 || Number.isSafeInteger(v.limit) && v.limit > 0 && v.limit <= 200);
|
|
49
64
|
}
|
|
50
65
|
function isHqClientCommandAckMessage(x) {
|
|
51
66
|
if (typeof x !== "object" || x === null) return false;
|
|
52
67
|
const v = x;
|
|
53
|
-
return typeof v.clientId === "string" && typeof v.projectId === "string" && typeof v.commandId === "string" && typeof v.status === "string";
|
|
68
|
+
return typeof v.clientId === "string" && typeof v.projectId === "string" && typeof v.commandId === "string" && typeof v.status === "string" && HQ_COMMAND_ACK_STATUSES.has(v.status) && (v.message === void 0 || typeof v.message === "string");
|
|
54
69
|
}
|
|
55
70
|
function parseHqFrame(raw) {
|
|
56
71
|
let parsed;
|
|
@@ -83,7 +98,13 @@ function parseHqFrame(raw) {
|
|
|
83
98
|
}
|
|
84
99
|
return {
|
|
85
100
|
ok: true,
|
|
86
|
-
frame: {
|
|
101
|
+
frame: {
|
|
102
|
+
type: "client.command_poll",
|
|
103
|
+
clientId: obj.clientId,
|
|
104
|
+
projectId: obj.projectId,
|
|
105
|
+
...typeof obj.afterCommandId === "string" ? { afterCommandId: obj.afterCommandId } : {},
|
|
106
|
+
...typeof obj.limit === "number" ? { limit: obj.limit } : {}
|
|
107
|
+
}
|
|
87
108
|
};
|
|
88
109
|
case "client.command_ack":
|
|
89
110
|
if (!isHqClientCommandAckMessage(obj)) {
|
|
@@ -118,8 +139,58 @@ var KNOWN_HQ_EVENT_PAYLOAD_TYPES = /* @__PURE__ */ new Set([
|
|
|
118
139
|
"worktree.event",
|
|
119
140
|
"tool.started",
|
|
120
141
|
"tool.completed",
|
|
121
|
-
"session.usage"
|
|
142
|
+
"session.usage",
|
|
143
|
+
"client.heartbeat",
|
|
144
|
+
"mcp.health.snapshot",
|
|
145
|
+
"mcp.operation"
|
|
146
|
+
]);
|
|
147
|
+
function isHqMcpLatencySummary(x) {
|
|
148
|
+
if (typeof x !== "object" || x === null) return false;
|
|
149
|
+
const v = x;
|
|
150
|
+
return typeof v.count === "number" && (v.lastMs === void 0 || typeof v.lastMs === "number") && (v.minMs === void 0 || typeof v.minMs === "number") && (v.maxMs === void 0 || typeof v.maxMs === "number") && (v.p50Ms === void 0 || typeof v.p50Ms === "number") && (v.p95Ms === void 0 || typeof v.p95Ms === "number");
|
|
151
|
+
}
|
|
152
|
+
function isHqMcpFailureCounts(x) {
|
|
153
|
+
if (typeof x !== "object" || x === null) return false;
|
|
154
|
+
const v = x;
|
|
155
|
+
return typeof v.transport === "number" && typeof v.protocol === "number" && typeof v.tool === "number";
|
|
156
|
+
}
|
|
157
|
+
function isHqMcpHealthCheck(x) {
|
|
158
|
+
if (typeof x !== "object" || x === null) return false;
|
|
159
|
+
const v = x;
|
|
160
|
+
return typeof v.name === "string" && typeof v.passed === "boolean" && (v.value === void 0 || typeof v.value === "number") && (v.threshold === void 0 || typeof v.threshold === "number");
|
|
161
|
+
}
|
|
162
|
+
var HQ_MCP_HEALTH_STATES = /* @__PURE__ */ new Set([
|
|
163
|
+
"disabled",
|
|
164
|
+
"dormant",
|
|
165
|
+
"connecting",
|
|
166
|
+
"healthy",
|
|
167
|
+
"degraded",
|
|
168
|
+
"failed"
|
|
122
169
|
]);
|
|
170
|
+
var HQ_MCP_CONNECTION_STATES = /* @__PURE__ */ new Set([
|
|
171
|
+
"idle",
|
|
172
|
+
"dormant",
|
|
173
|
+
"connecting",
|
|
174
|
+
"connected",
|
|
175
|
+
"reconnecting",
|
|
176
|
+
"disconnected",
|
|
177
|
+
"failed"
|
|
178
|
+
]);
|
|
179
|
+
function isHqMcpServerHealth(x) {
|
|
180
|
+
if (typeof x !== "object" || x === null) return false;
|
|
181
|
+
const v = x;
|
|
182
|
+
return typeof v.name === "string" && typeof v.projectId === "string" && typeof v.clientId === "string" && typeof v.connectionState === "string" && HQ_MCP_CONNECTION_STATES.has(v.connectionState) && typeof v.healthState === "string" && HQ_MCP_HEALTH_STATES.has(v.healthState) && (v.lastSuccessAt === void 0 || typeof v.lastSuccessAt === "string") && (v.lastFailureAt === void 0 || typeof v.lastFailureAt === "string") && (v.lastFailureKind === void 0 || v.lastFailureKind === "transport" || v.lastFailureKind === "protocol" || v.lastFailureKind === "tool") && typeof v.consecutiveFailures === "number" && isHqMcpFailureCounts(v.failures) && typeof v.reconnectCount === "number" && typeof v.wakeCount === "number" && typeof v.sleepCount === "number" && typeof v.restartCount === "number" && isHqMcpLatencySummary(v.connectionLatency) && isHqMcpLatencySummary(v.discoveryLatency) && isHqMcpLatencySummary(v.callLatency) && typeof v.inFlightCalls === "number" && typeof v.peakInFlightCalls === "number" && Array.isArray(v.healthChecks) && v.healthChecks.every(isHqMcpHealthCheck);
|
|
183
|
+
}
|
|
184
|
+
function isHqMcpHealthSnapshotPayload(x) {
|
|
185
|
+
if (typeof x !== "object" || x === null) return false;
|
|
186
|
+
const v = x;
|
|
187
|
+
return Array.isArray(v.servers) && v.servers.every(isHqMcpServerHealth);
|
|
188
|
+
}
|
|
189
|
+
function isHqMcpOperationPayload(x) {
|
|
190
|
+
if (typeof x !== "object" || x === null) return false;
|
|
191
|
+
const v = x;
|
|
192
|
+
return typeof v.operation === "object" && v.operation !== null && Array.isArray(v.servers) && v.servers.every(isHqMcpServerHealth);
|
|
193
|
+
}
|
|
123
194
|
function isHqMailboxMessageSummary(x) {
|
|
124
195
|
if (typeof x !== "object" || x === null) return false;
|
|
125
196
|
const v = x;
|
|
@@ -293,6 +364,11 @@ function isHqUsagePayload(x) {
|
|
|
293
364
|
if (typeof x !== "object" || x === null) return false;
|
|
294
365
|
return !Array.isArray(x);
|
|
295
366
|
}
|
|
367
|
+
function isHqClientHeartbeatPayload(x) {
|
|
368
|
+
if (typeof x !== "object" || x === null || Array.isArray(x)) return false;
|
|
369
|
+
const v = x;
|
|
370
|
+
return typeof v.uptimeMs === "number" && (v.activeSessionId === void 0 || typeof v.activeSessionId === "string") && (v.activeRunId === void 0 || typeof v.activeRunId === "string") && typeof v.status === "string" && (v.status === "active" || v.status === "idle" || v.status === "stale" || v.status === "error") && (v.activeSubagents === void 0 || typeof v.activeSubagents === "number") && (v.queuedTasks === void 0 || typeof v.queuedTasks === "number");
|
|
371
|
+
}
|
|
296
372
|
function parseHqEventPayload(eventType, payload) {
|
|
297
373
|
if (!KNOWN_HQ_EVENT_PAYLOAD_TYPES.has(eventType)) {
|
|
298
374
|
return { ok: true, payload };
|
|
@@ -322,6 +398,12 @@ function parseHqEventPayload(eventType, payload) {
|
|
|
322
398
|
return isHqToolCompletedPayload(payload) ? { ok: true, payload } : { ok: false, reason: "malformed-payload" };
|
|
323
399
|
case "session.usage":
|
|
324
400
|
return isHqUsagePayload(payload) ? { ok: true, payload } : { ok: false, reason: "malformed-payload" };
|
|
401
|
+
case "client.heartbeat":
|
|
402
|
+
return isHqClientHeartbeatPayload(payload) ? { ok: true, payload } : { ok: false, reason: "malformed-payload" };
|
|
403
|
+
case "mcp.health.snapshot":
|
|
404
|
+
return isHqMcpHealthSnapshotPayload(payload) ? { ok: true, payload } : { ok: false, reason: "malformed-payload" };
|
|
405
|
+
case "mcp.operation":
|
|
406
|
+
return isHqMcpOperationPayload(payload) ? { ok: true, payload } : { ok: false, reason: "malformed-payload" };
|
|
325
407
|
default: {
|
|
326
408
|
const _exhaustive = eventType;
|
|
327
409
|
return _exhaustive;
|
|
@@ -548,6 +630,8 @@ var RAW_CONTENT_KEYS = /* @__PURE__ */ new Set([
|
|
|
548
630
|
"prompts",
|
|
549
631
|
"completion",
|
|
550
632
|
"response",
|
|
633
|
+
"text",
|
|
634
|
+
"partialText",
|
|
551
635
|
"assistantMessage",
|
|
552
636
|
"userMessage",
|
|
553
637
|
"stdout",
|
|
@@ -555,6 +639,7 @@ var RAW_CONTENT_KEYS = /* @__PURE__ */ new Set([
|
|
|
555
639
|
"output",
|
|
556
640
|
"toolInput",
|
|
557
641
|
"toolOutput",
|
|
642
|
+
"outputSummary",
|
|
558
643
|
"body",
|
|
559
644
|
"mailboxBody",
|
|
560
645
|
"messageBody",
|
|
@@ -595,12 +680,34 @@ var PATH_KEYS = /* @__PURE__ */ new Set([
|
|
|
595
680
|
"workingDirectory"
|
|
596
681
|
]);
|
|
597
682
|
var defaultScrubber = new DefaultSecretScrubber();
|
|
598
|
-
function
|
|
683
|
+
function resolveHqRedactionPolicy(policy) {
|
|
599
684
|
return {
|
|
600
685
|
...DEFAULT_HQ_REDACTION_POLICY,
|
|
601
686
|
...policy
|
|
602
687
|
};
|
|
603
688
|
}
|
|
689
|
+
function tightenHqRedactionPolicy(publisherPolicy, operatorPolicy) {
|
|
690
|
+
if (operatorPolicy === void 0) return publisherPolicy;
|
|
691
|
+
const toolRank = {
|
|
692
|
+
none: 0,
|
|
693
|
+
summary: 1,
|
|
694
|
+
redacted: 2,
|
|
695
|
+
full: 3
|
|
696
|
+
};
|
|
697
|
+
const pathRank = {
|
|
698
|
+
none: 0,
|
|
699
|
+
redacted: 0,
|
|
700
|
+
"project-relative": 1,
|
|
701
|
+
full: 2
|
|
702
|
+
};
|
|
703
|
+
const requestedToolArgs = operatorPolicy.toolArgs;
|
|
704
|
+
const requestedPaths = operatorPolicy.paths;
|
|
705
|
+
return {
|
|
706
|
+
rawContent: publisherPolicy.rawContent && (operatorPolicy.rawContent === void 0 || operatorPolicy.rawContent),
|
|
707
|
+
toolArgs: requestedToolArgs !== void 0 && toolRank[requestedToolArgs] < toolRank[publisherPolicy.toolArgs] ? requestedToolArgs : publisherPolicy.toolArgs,
|
|
708
|
+
paths: requestedPaths !== void 0 && pathRank[requestedPaths] < pathRank[publisherPolicy.paths] ? requestedPaths : publisherPolicy.paths
|
|
709
|
+
};
|
|
710
|
+
}
|
|
604
711
|
function isPlainObject(value) {
|
|
605
712
|
return Object.prototype.toString.call(value) === "[object Object]";
|
|
606
713
|
}
|
|
@@ -618,7 +725,7 @@ function normalizePathForCompare(value) {
|
|
|
618
725
|
return value.replace(/\\/g, "/").replace(/\/+$/g, "");
|
|
619
726
|
}
|
|
620
727
|
function redactPath(value, projectRoot, policy) {
|
|
621
|
-
if (policy.paths === "full") return
|
|
728
|
+
if (policy.paths === "full") return value;
|
|
622
729
|
if (policy.paths === "none" || policy.paths === "redacted") return REDACTED_PATH_REPLACEMENT;
|
|
623
730
|
const normalizedValue = normalizePathForCompare(value);
|
|
624
731
|
if (!projectRoot) return normalizedValue.split("/").at(-1) ?? REDACTED_PATH_REPLACEMENT;
|
|
@@ -629,17 +736,17 @@ function redactPath(value, projectRoot, policy) {
|
|
|
629
736
|
}
|
|
630
737
|
return normalizedValue.split("/").at(-1) ?? REDACTED_PATH_REPLACEMENT;
|
|
631
738
|
}
|
|
632
|
-
function summarizeString(value, maxSummaryLength) {
|
|
633
|
-
const scrubbed = defaultScrubber.scrub(value);
|
|
739
|
+
function summarizeString(value, maxSummaryLength, scrub) {
|
|
740
|
+
const scrubbed = scrub ? defaultScrubber.scrub(value) : value;
|
|
634
741
|
if (scrubbed.length <= maxSummaryLength) return scrubbed;
|
|
635
742
|
return `${scrubbed.slice(0, maxSummaryLength)}\u2026[truncated:${scrubbed.length - maxSummaryLength}]`;
|
|
636
743
|
}
|
|
637
744
|
function scrubAndTruncateHqPreview(value, maxLength = 280) {
|
|
638
745
|
if (typeof value !== "string" || value.length === 0) return void 0;
|
|
639
|
-
return summarizeString(value, maxLength);
|
|
746
|
+
return summarizeString(value, maxLength, true);
|
|
640
747
|
}
|
|
641
748
|
function visitValue(value, options, key) {
|
|
642
|
-
if (key !== void 0 && isSensitiveKey(key)) {
|
|
749
|
+
if (!options.policy.rawContent && key !== void 0 && isSensitiveKey(key)) {
|
|
643
750
|
return { value: SENSITIVE_FIELD_REPLACEMENT, redacted: true };
|
|
644
751
|
}
|
|
645
752
|
if (typeof value === "string") {
|
|
@@ -650,7 +757,7 @@ function visitValue(value, options, key) {
|
|
|
650
757
|
if (!options.policy.rawContent && key !== void 0 && isRawContentKey(key)) {
|
|
651
758
|
return { value: RAW_CONTENT_REPLACEMENT, redacted: true };
|
|
652
759
|
}
|
|
653
|
-
const scrubbed = summarizeString(value, options.maxSummaryLength);
|
|
760
|
+
const scrubbed = summarizeString(value, options.maxSummaryLength, !options.policy.rawContent);
|
|
654
761
|
return { value: scrubbed, redacted: scrubbed !== value };
|
|
655
762
|
}
|
|
656
763
|
if (value === null || typeof value !== "object") return { value, redacted: false };
|
|
@@ -677,7 +784,7 @@ function visitValue(value, options, key) {
|
|
|
677
784
|
}
|
|
678
785
|
function redactHqValue(value, options = {}) {
|
|
679
786
|
const result = visitValue(value, {
|
|
680
|
-
policy:
|
|
787
|
+
policy: resolveHqRedactionPolicy(options.policy),
|
|
681
788
|
...options.projectRoot !== void 0 ? { projectRoot: options.projectRoot } : {},
|
|
682
789
|
maxSummaryLength: options.maxSummaryLength ?? 500,
|
|
683
790
|
seen: /* @__PURE__ */ new WeakSet()
|
|
@@ -693,7 +800,8 @@ function redactHqEvent(event, options = {}) {
|
|
|
693
800
|
return { value: nextEvent, redacted: payload.redacted };
|
|
694
801
|
}
|
|
695
802
|
function summarizeHqToolArgs(value, options = {}) {
|
|
696
|
-
const policy =
|
|
803
|
+
const policy = resolveHqRedactionPolicy(options.policy);
|
|
804
|
+
if (policy.toolArgs === "full") return value;
|
|
697
805
|
if (policy.toolArgs === "none") return "[REDACTED:hq_tool_args]";
|
|
698
806
|
if (policy.toolArgs === "redacted") return redactHqValue(value, options).value;
|
|
699
807
|
if (value === null || typeof value !== "object") return redactHqValue(value, options).value;
|
|
@@ -704,7 +812,7 @@ function summarizeHqToolArgs(value, options = {}) {
|
|
|
704
812
|
if (isSensitiveKey(key)) {
|
|
705
813
|
summary[key] = SENSITIVE_FIELD_REPLACEMENT;
|
|
706
814
|
} else if (typeof item === "string") {
|
|
707
|
-
summary[key] = isPathKey(key) ? redactPath(item, options.projectRoot, policy) : summarizeString(item, 120);
|
|
815
|
+
summary[key] = isPathKey(key) ? redactPath(item, options.projectRoot, policy) : summarizeString(item, 120, true);
|
|
708
816
|
} else if (Array.isArray(item)) {
|
|
709
817
|
summary[key] = `[array:${item.length}]`;
|
|
710
818
|
} else if (item !== null && typeof item === "object") {
|
|
@@ -720,9 +828,12 @@ function summarizeHqToolArgs(value, options = {}) {
|
|
|
720
828
|
// src/hq/mailbox-mapper.ts
|
|
721
829
|
function previewText(value, maxLength, policy) {
|
|
722
830
|
if (value === void 0 || value.length === 0) return void 0;
|
|
723
|
-
|
|
724
|
-
if (
|
|
725
|
-
|
|
831
|
+
if (policy?.rawContent === false) return "[REDACTED:hq_raw_content]";
|
|
832
|
+
if (policy?.rawContent === true) {
|
|
833
|
+
if (value.length <= maxLength) return value;
|
|
834
|
+
return `${value.slice(0, maxLength)}\u2026`;
|
|
835
|
+
}
|
|
836
|
+
return scrubAndTruncateHqPreview(value, maxLength);
|
|
726
837
|
}
|
|
727
838
|
function readCount(message) {
|
|
728
839
|
return Object.keys(message.readBy).length;
|
|
@@ -823,6 +934,10 @@ function createMailboxEventPayload(input) {
|
|
|
823
934
|
...input.summary !== void 0 ? { summary: previewText(input.summary, input.previewLength ?? 160, input.redactionPolicy) ?? "" } : {}
|
|
824
935
|
};
|
|
825
936
|
}
|
|
937
|
+
|
|
938
|
+
// src/hq/publisher.ts
|
|
939
|
+
import { randomUUID } from "node:crypto";
|
|
940
|
+
var TRANSCRIPT_EVENT_TYPES = /* @__PURE__ */ new Set(["session.transcript", "agent.message"]);
|
|
826
941
|
var OPEN_STATE = 1;
|
|
827
942
|
var CONNECT_WARN_AFTER_FAILURES = 5;
|
|
828
943
|
var DEFAULT_RECONNECT_BASE_MS = 1e3;
|
|
@@ -831,6 +946,7 @@ var DEFAULT_DISCOVERY_POLL_MS = 5e3;
|
|
|
831
946
|
var DEFAULT_MAX_QUEUED_MESSAGES = 2e3;
|
|
832
947
|
var DEFAULT_COMMAND_POLL_INTERVAL_MS = 2e3;
|
|
833
948
|
var DEFAULT_COMMAND_POLL_LIMIT = 25;
|
|
949
|
+
var DEFAULT_HEARTBEAT_INTERVAL_MS = 25e3;
|
|
834
950
|
function defaultSocketFactory(url) {
|
|
835
951
|
const WebSocketCtor = globalThis.WebSocket;
|
|
836
952
|
if (WebSocketCtor === void 0) {
|
|
@@ -877,6 +993,8 @@ var HqPublisher = class {
|
|
|
877
993
|
this.reconnectBaseMs = options.reconnectBaseMs ?? DEFAULT_RECONNECT_BASE_MS;
|
|
878
994
|
this.reconnectMaxMs = options.reconnectMaxMs ?? DEFAULT_RECONNECT_MAX_MS;
|
|
879
995
|
this.maxQueuedMessages = options.maxQueuedMessages ?? DEFAULT_MAX_QUEUED_MESSAGES;
|
|
996
|
+
this.resolvedRedactionPolicy = resolveHqRedactionPolicy(options.redactionPolicy);
|
|
997
|
+
this.logger = options.logger;
|
|
880
998
|
}
|
|
881
999
|
options;
|
|
882
1000
|
socketFactory;
|
|
@@ -887,6 +1005,8 @@ var HqPublisher = class {
|
|
|
887
1005
|
reconnectBaseMs;
|
|
888
1006
|
reconnectMaxMs;
|
|
889
1007
|
maxQueuedMessages;
|
|
1008
|
+
resolvedRedactionPolicy;
|
|
1009
|
+
logger;
|
|
890
1010
|
socket = null;
|
|
891
1011
|
seq = 0;
|
|
892
1012
|
queue = [];
|
|
@@ -896,6 +1016,7 @@ var HqPublisher = class {
|
|
|
896
1016
|
lastAttempt = null;
|
|
897
1017
|
reconnectTimer = null;
|
|
898
1018
|
commandPollTimer = null;
|
|
1019
|
+
heartbeatTimer = null;
|
|
899
1020
|
lastCommandId;
|
|
900
1021
|
connect() {
|
|
901
1022
|
if (this.socket !== null || this.stopped) return;
|
|
@@ -926,6 +1047,7 @@ var HqPublisher = class {
|
|
|
926
1047
|
this.reconnectAttempt = 0;
|
|
927
1048
|
this.sendHelloNow();
|
|
928
1049
|
this.flushQueue();
|
|
1050
|
+
this.startHeartbeat();
|
|
929
1051
|
if (this.options.onCommand !== void 0) {
|
|
930
1052
|
this.startCommandPolling();
|
|
931
1053
|
this.pollCommands();
|
|
@@ -940,6 +1062,7 @@ var HqPublisher = class {
|
|
|
940
1062
|
removeSocketListener(socket, "close", onCloseOrError);
|
|
941
1063
|
removeSocketListener(socket, "error", onCloseOrError);
|
|
942
1064
|
this.stopCommandPolling();
|
|
1065
|
+
this.stopHeartbeat();
|
|
943
1066
|
if (this.socket === socket) this.socket = null;
|
|
944
1067
|
this.scheduleReconnect();
|
|
945
1068
|
};
|
|
@@ -956,6 +1079,7 @@ var HqPublisher = class {
|
|
|
956
1079
|
this.reconnectTimer = null;
|
|
957
1080
|
}
|
|
958
1081
|
this.stopCommandPolling();
|
|
1082
|
+
this.stopHeartbeat();
|
|
959
1083
|
this.queue = [];
|
|
960
1084
|
const socket = this.socket;
|
|
961
1085
|
this.socket = null;
|
|
@@ -973,13 +1097,19 @@ var HqPublisher = class {
|
|
|
973
1097
|
...options.sessionId !== void 0 ? { sessionId: options.sessionId } : {},
|
|
974
1098
|
...options.runId !== void 0 ? { runId: options.runId } : {}
|
|
975
1099
|
});
|
|
976
|
-
|
|
977
|
-
|
|
1100
|
+
const maxSummaryLength = options.maxSummaryLength ?? (TRANSCRIPT_EVENT_TYPES.has(options.type) ? HQ_TRANSCRIPT_TEXT_CAP : void 0);
|
|
1101
|
+
const redacted = redactHqEvent(event, {
|
|
1102
|
+
policy: this.resolvedRedactionPolicy,
|
|
1103
|
+
projectRoot: this.options.project.projectRoot,
|
|
1104
|
+
...maxSummaryLength !== void 0 ? { maxSummaryLength } : {}
|
|
1105
|
+
}).value;
|
|
1106
|
+
this.sendFrame({ type: "client.event", event: redacted });
|
|
1107
|
+
return redacted;
|
|
978
1108
|
}
|
|
979
1109
|
async publishMailboxSnapshot(mailbox, options) {
|
|
980
1110
|
const payload = await createMailboxSnapshotPayloadFromMailbox(mailbox, {
|
|
981
1111
|
...options,
|
|
982
|
-
|
|
1112
|
+
redactionPolicy: this.resolvedRedactionPolicy
|
|
983
1113
|
});
|
|
984
1114
|
return this.publishEvent({
|
|
985
1115
|
type: "mailbox.snapshot",
|
|
@@ -996,7 +1126,7 @@ var HqPublisher = class {
|
|
|
996
1126
|
...input.agent !== void 0 ? { agent: input.agent } : {},
|
|
997
1127
|
...input.summary !== void 0 ? { summary: input.summary } : {},
|
|
998
1128
|
...input.previewLength !== void 0 ? { previewLength: input.previewLength } : {},
|
|
999
|
-
|
|
1129
|
+
redactionPolicy: this.resolvedRedactionPolicy
|
|
1000
1130
|
});
|
|
1001
1131
|
return this.publishEvent({
|
|
1002
1132
|
type: "mailbox.event",
|
|
@@ -1013,6 +1143,10 @@ var HqPublisher = class {
|
|
|
1013
1143
|
get project() {
|
|
1014
1144
|
return this.options.project;
|
|
1015
1145
|
}
|
|
1146
|
+
/** Effective publisher-side policy applied before any event leaves this process. */
|
|
1147
|
+
get redactionPolicy() {
|
|
1148
|
+
return this.resolvedRedactionPolicy;
|
|
1149
|
+
}
|
|
1016
1150
|
/** Publish a live session/terminal snapshot (state + agents). */
|
|
1017
1151
|
publishSessionSnapshot(payload, opts) {
|
|
1018
1152
|
return this.publishEvent({
|
|
@@ -1076,7 +1210,8 @@ var HqPublisher = class {
|
|
|
1076
1210
|
protocolVersion: HQ_PROTOCOL_VERSION,
|
|
1077
1211
|
client: this.options.client,
|
|
1078
1212
|
project: this.options.project,
|
|
1079
|
-
capabilities: this.capabilities
|
|
1213
|
+
capabilities: this.capabilities,
|
|
1214
|
+
redactionPolicy: this.resolvedRedactionPolicy
|
|
1080
1215
|
}
|
|
1081
1216
|
};
|
|
1082
1217
|
}
|
|
@@ -1124,6 +1259,30 @@ var HqPublisher = class {
|
|
|
1124
1259
|
clearInterval(this.commandPollTimer);
|
|
1125
1260
|
this.commandPollTimer = null;
|
|
1126
1261
|
}
|
|
1262
|
+
startHeartbeat() {
|
|
1263
|
+
if (this.heartbeatTimer !== null) return;
|
|
1264
|
+
this.heartbeatTimer = setInterval(
|
|
1265
|
+
() => this.publishHeartbeat(),
|
|
1266
|
+
this.options.heartbeatIntervalMs ?? DEFAULT_HEARTBEAT_INTERVAL_MS
|
|
1267
|
+
);
|
|
1268
|
+
this.heartbeatTimer.unref?.();
|
|
1269
|
+
}
|
|
1270
|
+
stopHeartbeat() {
|
|
1271
|
+
if (this.heartbeatTimer === null) return;
|
|
1272
|
+
clearInterval(this.heartbeatTimer);
|
|
1273
|
+
this.heartbeatTimer = null;
|
|
1274
|
+
}
|
|
1275
|
+
publishHeartbeat() {
|
|
1276
|
+
const startedAt = Date.parse(this.options.client.startedAt);
|
|
1277
|
+
const now = Date.parse(this.now());
|
|
1278
|
+
this.publishEvent({
|
|
1279
|
+
type: "client.heartbeat",
|
|
1280
|
+
payload: {
|
|
1281
|
+
uptimeMs: Number.isFinite(startedAt) && Number.isFinite(now) ? Math.max(0, now - startedAt) : 0,
|
|
1282
|
+
status: "idle"
|
|
1283
|
+
}
|
|
1284
|
+
});
|
|
1285
|
+
}
|
|
1127
1286
|
async handleServerMessage(event) {
|
|
1128
1287
|
const message = this.parseServerMessage(event);
|
|
1129
1288
|
if (message?.type !== "hq.command_batch") return;
|
|
@@ -1186,6 +1345,10 @@ var HqPublisher = class {
|
|
|
1186
1345
|
emitConnectWarning() {
|
|
1187
1346
|
const attempt = this.lastAttempt;
|
|
1188
1347
|
const message = `WrongStack HQ publisher: ${this.reconnectAttempt} consecutive connection failures${attempt !== null ? ` to ${attempt.url} (client token ${attempt.hadToken ? "present" : "absent"})` : ""}. Either the HQ server is unreachable or it rejected the token (401). If HQ runs in client-token mode, verify WRONGSTACK_HQ_TOKEN / auth.json. Retries continue with backoff.`;
|
|
1348
|
+
if (this.logger) {
|
|
1349
|
+
this.logger.warn(message, { event: "hq.publisher.connect_failed" });
|
|
1350
|
+
return;
|
|
1351
|
+
}
|
|
1189
1352
|
const warn = this.options.warn ?? ((msg) => console.warn(
|
|
1190
1353
|
JSON.stringify({
|
|
1191
1354
|
level: "warn",
|
|
@@ -1215,13 +1378,32 @@ var HqPublisher = class {
|
|
|
1215
1378
|
this.reconnectTimer.unref?.();
|
|
1216
1379
|
}
|
|
1217
1380
|
};
|
|
1381
|
+
|
|
1382
|
+
// src/hq/factory.ts
|
|
1383
|
+
import { createHash as createHash2, randomUUID as randomUUID4 } from "node:crypto";
|
|
1384
|
+
import * as fs3 from "node:fs";
|
|
1385
|
+
import { hostname } from "node:os";
|
|
1386
|
+
import { basename as basename5 } from "node:path";
|
|
1387
|
+
|
|
1388
|
+
// src/coordination/global-mailbox.ts
|
|
1389
|
+
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
1390
|
+
import * as fsp from "node:fs/promises";
|
|
1391
|
+
import * as path4 from "node:path";
|
|
1392
|
+
|
|
1393
|
+
// src/utils/atomic-write.ts
|
|
1394
|
+
import { randomBytes } from "node:crypto";
|
|
1395
|
+
import * as fs from "node:fs/promises";
|
|
1396
|
+
import * as path3 from "node:path";
|
|
1397
|
+
|
|
1398
|
+
// src/utils/session-scoped-path.ts
|
|
1399
|
+
import * as path from "node:path";
|
|
1218
1400
|
function sessionScopedPath(dir, sessionId, suffix) {
|
|
1219
1401
|
if (!sessionId || sessionId.includes("\\") || sessionId.includes("..")) {
|
|
1220
1402
|
throw invalid(sessionId);
|
|
1221
1403
|
}
|
|
1222
|
-
const resolved =
|
|
1223
|
-
const rel =
|
|
1224
|
-
if (rel.startsWith("..") ||
|
|
1404
|
+
const resolved = path.resolve(dir, `${sessionId}${suffix}`);
|
|
1405
|
+
const rel = path.relative(path.resolve(dir), resolved);
|
|
1406
|
+
if (rel.startsWith("..") || path.isAbsolute(rel)) {
|
|
1225
1407
|
throw invalid(sessionId);
|
|
1226
1408
|
}
|
|
1227
1409
|
return resolved;
|
|
@@ -1234,6 +1416,11 @@ function invalid(sessionId) {
|
|
|
1234
1416
|
context: { reason: "path_traversal" }
|
|
1235
1417
|
});
|
|
1236
1418
|
}
|
|
1419
|
+
|
|
1420
|
+
// src/utils/wstack-paths.ts
|
|
1421
|
+
import { createHash } from "node:crypto";
|
|
1422
|
+
import * as os from "node:os";
|
|
1423
|
+
import * as path2 from "node:path";
|
|
1237
1424
|
function projectHash(absRoot) {
|
|
1238
1425
|
return createHash("sha256").update(path2.resolve(absRoot)).digest("hex").slice(0, 12);
|
|
1239
1426
|
}
|
|
@@ -1307,9 +1494,61 @@ function resolveWstackPaths(opts) {
|
|
|
1307
1494
|
|
|
1308
1495
|
// src/types/errors.ts
|
|
1309
1496
|
var ERROR_CODES = {
|
|
1497
|
+
// Provider
|
|
1498
|
+
PROVIDER_RATE_LIMITED: "PROVIDER_RATE_LIMITED",
|
|
1499
|
+
PROVIDER_AUTH_FAILED: "PROVIDER_AUTH_FAILED",
|
|
1500
|
+
PROVIDER_OVERLOADED: "PROVIDER_OVERLOADED",
|
|
1501
|
+
PROVIDER_INVALID_REQUEST: "PROVIDER_INVALID_REQUEST",
|
|
1502
|
+
PROVIDER_SERVER_ERROR: "PROVIDER_SERVER_ERROR",
|
|
1503
|
+
PROVIDER_NETWORK_ERROR: "PROVIDER_NETWORK_ERROR",
|
|
1504
|
+
PROVIDER_CONTEXT_OVERFLOW: "PROVIDER_CONTEXT_OVERFLOW",
|
|
1505
|
+
// Tool
|
|
1506
|
+
TOOL_NOT_FOUND: "TOOL_NOT_FOUND",
|
|
1507
|
+
TOOL_PERMISSION_DENIED: "TOOL_PERMISSION_DENIED",
|
|
1508
|
+
TOOL_EXECUTION_FAILED: "TOOL_EXECUTION_FAILED",
|
|
1509
|
+
TOOL_TIMEOUT: "TOOL_TIMEOUT",
|
|
1510
|
+
TOOL_INPUT_INVALID: "TOOL_INPUT_INVALID",
|
|
1511
|
+
// Config
|
|
1512
|
+
CONFIG_INVALID: "CONFIG_INVALID",
|
|
1513
|
+
CONFIG_NOT_FOUND: "CONFIG_NOT_FOUND",
|
|
1514
|
+
CONFIG_PARSE_FAILED: "CONFIG_PARSE_FAILED",
|
|
1515
|
+
CONFIG_MIGRATION_NEEDED: "CONFIG_MIGRATION_NEEDED",
|
|
1516
|
+
// Plugin
|
|
1517
|
+
PLUGIN_LOAD_FAILED: "PLUGIN_LOAD_FAILED",
|
|
1518
|
+
PLUGIN_API_MISMATCH: "PLUGIN_API_MISMATCH",
|
|
1519
|
+
PLUGIN_MISSING_DEPENDENCY: "PLUGIN_MISSING_DEPENDENCY",
|
|
1520
|
+
// Agent
|
|
1521
|
+
AGENT_ITERATION_LIMIT: "AGENT_ITERATION_LIMIT",
|
|
1522
|
+
AGENT_CONTEXT_OVERFLOW: "AGENT_CONTEXT_OVERFLOW",
|
|
1523
|
+
AGENT_ABORTED: "AGENT_ABORTED",
|
|
1524
|
+
AGENT_RUN_FAILED: "AGENT_RUN_FAILED",
|
|
1525
|
+
// Session
|
|
1526
|
+
SESSION_NOT_FOUND: "SESSION_NOT_FOUND",
|
|
1527
|
+
SESSION_CORRUPTED: "SESSION_CORRUPTED",
|
|
1528
|
+
SESSION_WRITE_FAILED: "SESSION_WRITE_FAILED",
|
|
1529
|
+
// Container / Registry
|
|
1530
|
+
CONTAINER_TOKEN_ALREADY_BOUND: "CONTAINER_TOKEN_ALREADY_BOUND",
|
|
1531
|
+
CONTAINER_TOKEN_NOT_BOUND: "CONTAINER_TOKEN_NOT_BOUND",
|
|
1532
|
+
CONTAINER_CIRCULAR_DEPENDENCY: "CONTAINER_CIRCULAR_DEPENDENCY",
|
|
1533
|
+
REGISTRY_DUPLICATE: "REGISTRY_DUPLICATE",
|
|
1534
|
+
REGISTRY_NOT_FOUND: "REGISTRY_NOT_FOUND",
|
|
1535
|
+
REGISTRY_INVALID: "REGISTRY_INVALID",
|
|
1310
1536
|
// File system
|
|
1311
1537
|
FS_READ_FAILED: "FS_READ_FAILED",
|
|
1312
|
-
|
|
1538
|
+
FS_WRITE_FAILED: "FS_WRITE_FAILED",
|
|
1539
|
+
FS_MKDIR_FAILED: "FS_MKDIR_FAILED",
|
|
1540
|
+
FS_DELETE_FAILED: "FS_DELETE_FAILED",
|
|
1541
|
+
FS_ATOMIC_WRITE_FAILED: "FS_ATOMIC_WRITE_FAILED",
|
|
1542
|
+
// SDD (Spec-Driven Development)
|
|
1543
|
+
SDD_VALIDATION_FAILED: "SDD_VALIDATION_FAILED",
|
|
1544
|
+
SDD_PARSE_FAILED: "SDD_PARSE_FAILED",
|
|
1545
|
+
SDD_INVALID_STATE: "SDD_INVALID_STATE",
|
|
1546
|
+
SDD_NOT_READY: "SDD_NOT_READY",
|
|
1547
|
+
// General
|
|
1548
|
+
VALIDATION_ERROR: "VALIDATION_ERROR",
|
|
1549
|
+
PARSE_FAILED: "PARSE_FAILED",
|
|
1550
|
+
UNKNOWN: "UNKNOWN"
|
|
1551
|
+
};
|
|
1313
1552
|
var WrongStackError = class extends Error {
|
|
1314
1553
|
code;
|
|
1315
1554
|
subsystem;
|
|
@@ -1357,17 +1596,17 @@ var FsError = class extends WrongStackError {
|
|
|
1357
1596
|
|
|
1358
1597
|
// src/utils/atomic-write.ts
|
|
1359
1598
|
async function atomicWrite(targetPath, content, opts = {}) {
|
|
1360
|
-
const dir =
|
|
1361
|
-
await
|
|
1362
|
-
const tmp =
|
|
1599
|
+
const dir = path3.dirname(targetPath);
|
|
1600
|
+
await fs.mkdir(dir, { recursive: true });
|
|
1601
|
+
const tmp = path3.join(dir, `.${path3.basename(targetPath)}.${randomBytes(6).toString("hex")}.tmp`);
|
|
1363
1602
|
try {
|
|
1364
1603
|
if (typeof content === "string") {
|
|
1365
|
-
await
|
|
1604
|
+
await fs.writeFile(tmp, content, { flag: "wx", encoding: opts.encoding ?? "utf8" });
|
|
1366
1605
|
} else {
|
|
1367
|
-
await
|
|
1606
|
+
await fs.writeFile(tmp, content, { flag: "wx" });
|
|
1368
1607
|
}
|
|
1369
1608
|
try {
|
|
1370
|
-
const fh = await
|
|
1609
|
+
const fh = await fs.open(tmp, "r+");
|
|
1371
1610
|
try {
|
|
1372
1611
|
await fh.sync();
|
|
1373
1612
|
} finally {
|
|
@@ -1377,53 +1616,53 @@ async function atomicWrite(targetPath, content, opts = {}) {
|
|
|
1377
1616
|
}
|
|
1378
1617
|
let mode;
|
|
1379
1618
|
try {
|
|
1380
|
-
const stat4 = await
|
|
1619
|
+
const stat4 = await fs.stat(targetPath);
|
|
1381
1620
|
mode = stat4.mode & 511;
|
|
1382
1621
|
} catch {
|
|
1383
1622
|
mode = opts.mode;
|
|
1384
1623
|
}
|
|
1385
1624
|
if (mode !== void 0) {
|
|
1386
|
-
await
|
|
1625
|
+
await fs.chmod(tmp, mode);
|
|
1387
1626
|
}
|
|
1388
1627
|
await renameWithRetry(tmp, targetPath);
|
|
1389
1628
|
if (mode !== void 0 && process.platform === "win32") {
|
|
1390
1629
|
try {
|
|
1391
|
-
await
|
|
1630
|
+
await fs.chmod(targetPath, mode);
|
|
1392
1631
|
} catch {
|
|
1393
1632
|
}
|
|
1394
1633
|
}
|
|
1395
1634
|
} catch (err) {
|
|
1396
1635
|
try {
|
|
1397
|
-
await
|
|
1636
|
+
await fs.unlink(tmp);
|
|
1398
1637
|
} catch {
|
|
1399
1638
|
}
|
|
1400
1639
|
throw err;
|
|
1401
1640
|
}
|
|
1402
1641
|
}
|
|
1403
1642
|
async function withFileLock(targetPath, fn, opts = {}) {
|
|
1404
|
-
const dir =
|
|
1405
|
-
await
|
|
1406
|
-
const lockPath =
|
|
1643
|
+
const dir = path3.dirname(targetPath);
|
|
1644
|
+
await fs.mkdir(dir, { recursive: true });
|
|
1645
|
+
const lockPath = path3.join(dir, `.${path3.basename(targetPath)}.lock`);
|
|
1407
1646
|
const timeoutMs = opts.timeoutMs ?? 5e3;
|
|
1408
1647
|
const staleMs = opts.staleMs ?? 3e4;
|
|
1409
1648
|
const started = Date.now();
|
|
1410
1649
|
let handle;
|
|
1411
1650
|
for (; ; ) {
|
|
1412
1651
|
try {
|
|
1413
|
-
handle = await
|
|
1652
|
+
handle = await fs.open(lockPath, "wx");
|
|
1414
1653
|
await handle.writeFile(`${process.pid}:${Date.now()}`);
|
|
1415
1654
|
break;
|
|
1416
1655
|
} catch (err) {
|
|
1417
1656
|
const code = err.code;
|
|
1418
1657
|
if (code === "ENOENT") {
|
|
1419
|
-
await
|
|
1658
|
+
await fs.mkdir(dir, { recursive: true });
|
|
1420
1659
|
continue;
|
|
1421
1660
|
}
|
|
1422
1661
|
if (code !== "EEXIST") throw err;
|
|
1423
1662
|
try {
|
|
1424
|
-
const stat4 = await
|
|
1663
|
+
const stat4 = await fs.stat(lockPath);
|
|
1425
1664
|
if (Date.now() - stat4.mtimeMs > staleMs) {
|
|
1426
|
-
await
|
|
1665
|
+
await fs.unlink(lockPath);
|
|
1427
1666
|
continue;
|
|
1428
1667
|
}
|
|
1429
1668
|
} catch {
|
|
@@ -1448,7 +1687,7 @@ async function withFileLock(targetPath, fn, opts = {}) {
|
|
|
1448
1687
|
} catch {
|
|
1449
1688
|
}
|
|
1450
1689
|
try {
|
|
1451
|
-
await
|
|
1690
|
+
await fs.unlink(lockPath);
|
|
1452
1691
|
} catch {
|
|
1453
1692
|
}
|
|
1454
1693
|
}
|
|
@@ -1456,14 +1695,14 @@ async function withFileLock(targetPath, fn, opts = {}) {
|
|
|
1456
1695
|
var TRANSIENT_RENAME_CODES = /* @__PURE__ */ new Set(["EPERM", "EBUSY", "EACCES", "ENOTEMPTY"]);
|
|
1457
1696
|
async function renameWithRetry(from, to) {
|
|
1458
1697
|
if (process.platform !== "win32") {
|
|
1459
|
-
await
|
|
1698
|
+
await fs.rename(from, to);
|
|
1460
1699
|
return;
|
|
1461
1700
|
}
|
|
1462
1701
|
const delays = [10, 25, 60, 120, 250];
|
|
1463
1702
|
let lastErr;
|
|
1464
1703
|
for (let i = 0; i <= delays.length; i++) {
|
|
1465
1704
|
try {
|
|
1466
|
-
await
|
|
1705
|
+
await fs.rename(from, to);
|
|
1467
1706
|
return;
|
|
1468
1707
|
} catch (err) {
|
|
1469
1708
|
lastErr = err;
|
|
@@ -1477,6 +1716,148 @@ async function renameWithRetry(from, to) {
|
|
|
1477
1716
|
throw lastErr;
|
|
1478
1717
|
}
|
|
1479
1718
|
|
|
1719
|
+
// src/coordination/mailbox-constants.ts
|
|
1720
|
+
var AGENT_STALE_MS = 6e4;
|
|
1721
|
+
var CLIENT_STALE_MS = 6e4;
|
|
1722
|
+
var HEARTBEAT_THROTTLE_MS = 5e3;
|
|
1723
|
+
var REGISTRY_CACHE_TTL_MS = 2e3;
|
|
1724
|
+
var LINE_SEPARATOR = "\n";
|
|
1725
|
+
var MESSAGE_CACHE_MAX_ENTRIES = 1e4;
|
|
1726
|
+
var AUTO_COMPACT_INTERVAL_MS = 3e5;
|
|
1727
|
+
var AUTO_COMPACT_READ_MAX_AGE_MS = 6e5;
|
|
1728
|
+
var AUTO_COMPACT_DEFAULT_TTL_MS = 864e5;
|
|
1729
|
+
|
|
1730
|
+
// src/coordination/mailbox-message-codec.ts
|
|
1731
|
+
var MESSAGE_TYPES = /* @__PURE__ */ new Set([
|
|
1732
|
+
"note",
|
|
1733
|
+
"ask",
|
|
1734
|
+
"assign",
|
|
1735
|
+
"steer",
|
|
1736
|
+
"btw",
|
|
1737
|
+
"broadcast",
|
|
1738
|
+
"status",
|
|
1739
|
+
"result",
|
|
1740
|
+
"review",
|
|
1741
|
+
"control"
|
|
1742
|
+
]);
|
|
1743
|
+
var PRIORITIES = /* @__PURE__ */ new Set(["low", "normal", "high"]);
|
|
1744
|
+
var TASK_STATUSES = /* @__PURE__ */ new Set([
|
|
1745
|
+
"pending",
|
|
1746
|
+
"in_progress",
|
|
1747
|
+
"completed",
|
|
1748
|
+
"failed",
|
|
1749
|
+
"idle",
|
|
1750
|
+
"running",
|
|
1751
|
+
"streaming",
|
|
1752
|
+
"waiting_user",
|
|
1753
|
+
"error",
|
|
1754
|
+
"offline",
|
|
1755
|
+
"busy"
|
|
1756
|
+
]);
|
|
1757
|
+
function isRecord(value) {
|
|
1758
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1759
|
+
}
|
|
1760
|
+
function requiredString(record, key) {
|
|
1761
|
+
const value = record[key];
|
|
1762
|
+
if (typeof value !== "string") {
|
|
1763
|
+
throw new TypeError(`mailbox message field "${key}" must be a string`);
|
|
1764
|
+
}
|
|
1765
|
+
return value;
|
|
1766
|
+
}
|
|
1767
|
+
function optionalString(record, key) {
|
|
1768
|
+
const value = record[key];
|
|
1769
|
+
if (value === void 0) return {};
|
|
1770
|
+
if (typeof value !== "string") {
|
|
1771
|
+
throw new TypeError(`mailbox message field "${key}" must be a string when present`);
|
|
1772
|
+
}
|
|
1773
|
+
return { [key]: value };
|
|
1774
|
+
}
|
|
1775
|
+
function parseMessageType(value) {
|
|
1776
|
+
if (value === "info") return "note";
|
|
1777
|
+
if (value === "task") return "assign";
|
|
1778
|
+
if (typeof value === "string" && MESSAGE_TYPES.has(value)) {
|
|
1779
|
+
return value;
|
|
1780
|
+
}
|
|
1781
|
+
throw new TypeError('mailbox message field "type" is invalid');
|
|
1782
|
+
}
|
|
1783
|
+
function normalizeMailboxMessageType(value) {
|
|
1784
|
+
return parseMessageType(value);
|
|
1785
|
+
}
|
|
1786
|
+
function parsePriority(value) {
|
|
1787
|
+
if (typeof value === "string" && PRIORITIES.has(value)) {
|
|
1788
|
+
return value;
|
|
1789
|
+
}
|
|
1790
|
+
if (typeof value === "string") return "normal";
|
|
1791
|
+
throw new TypeError('mailbox message field "priority" must be a string');
|
|
1792
|
+
}
|
|
1793
|
+
function parseReadReceipts(record, to) {
|
|
1794
|
+
const value = record["readBy"];
|
|
1795
|
+
if (value === void 0) {
|
|
1796
|
+
const legacyReadAt = record["readAt"];
|
|
1797
|
+
return record["read"] === true && typeof legacyReadAt === "string" ? { [to || "unknown"]: legacyReadAt } : {};
|
|
1798
|
+
}
|
|
1799
|
+
if (!isRecord(value)) {
|
|
1800
|
+
throw new TypeError('mailbox message field "readBy" must be an object');
|
|
1801
|
+
}
|
|
1802
|
+
const receipts = {};
|
|
1803
|
+
for (const [agentId, timestamp] of Object.entries(value)) {
|
|
1804
|
+
if (typeof timestamp !== "string") {
|
|
1805
|
+
throw new TypeError("mailbox message read receipt timestamps must be strings");
|
|
1806
|
+
}
|
|
1807
|
+
receipts[agentId] = timestamp;
|
|
1808
|
+
}
|
|
1809
|
+
return receipts;
|
|
1810
|
+
}
|
|
1811
|
+
function parseTaskContext(value) {
|
|
1812
|
+
if (value === void 0) return void 0;
|
|
1813
|
+
if (!isRecord(value)) {
|
|
1814
|
+
throw new TypeError('mailbox message field "taskContext" must be an object');
|
|
1815
|
+
}
|
|
1816
|
+
const status = value["status"];
|
|
1817
|
+
if (status !== void 0 && (typeof status !== "string" || !TASK_STATUSES.has(status))) {
|
|
1818
|
+
throw new TypeError("mailbox message taskContext status is invalid");
|
|
1819
|
+
}
|
|
1820
|
+
return {
|
|
1821
|
+
...optionalString(value, "agentRole"),
|
|
1822
|
+
...optionalString(value, "agentName"),
|
|
1823
|
+
...optionalString(value, "taskId"),
|
|
1824
|
+
...status === void 0 ? {} : { status }
|
|
1825
|
+
};
|
|
1826
|
+
}
|
|
1827
|
+
function parseMailboxMessage(value) {
|
|
1828
|
+
if (!isRecord(value)) throw new TypeError("mailbox message must be an object");
|
|
1829
|
+
const to = value["to"] === void 0 ? "" : requiredString(value, "to");
|
|
1830
|
+
const completed = value["completed"];
|
|
1831
|
+
if (typeof completed !== "boolean") {
|
|
1832
|
+
throw new TypeError('mailbox message field "completed" must be a boolean');
|
|
1833
|
+
}
|
|
1834
|
+
const taskContext = parseTaskContext(value["taskContext"]);
|
|
1835
|
+
return {
|
|
1836
|
+
id: requiredString(value, "id"),
|
|
1837
|
+
from: requiredString(value, "from"),
|
|
1838
|
+
to,
|
|
1839
|
+
type: parseMessageType(value["type"]),
|
|
1840
|
+
subject: requiredString(value, "subject"),
|
|
1841
|
+
body: requiredString(value, "body"),
|
|
1842
|
+
priority: parsePriority(value["priority"]),
|
|
1843
|
+
readBy: parseReadReceipts(value, to),
|
|
1844
|
+
completed,
|
|
1845
|
+
timestamp: requiredString(value, "timestamp"),
|
|
1846
|
+
...optionalString(value, "completedBy"),
|
|
1847
|
+
...optionalString(value, "outcome"),
|
|
1848
|
+
...optionalString(value, "completedAt"),
|
|
1849
|
+
...optionalString(value, "deletedAt"),
|
|
1850
|
+
...optionalString(value, "deletedBy"),
|
|
1851
|
+
...optionalString(value, "replyTo"),
|
|
1852
|
+
...optionalString(value, "senderSessionId"),
|
|
1853
|
+
...optionalString(value, "expiresAt"),
|
|
1854
|
+
...taskContext === void 0 ? {} : { taskContext }
|
|
1855
|
+
};
|
|
1856
|
+
}
|
|
1857
|
+
function parseMailboxMessageLine(line) {
|
|
1858
|
+
return parseMailboxMessage(JSON.parse(line));
|
|
1859
|
+
}
|
|
1860
|
+
|
|
1480
1861
|
// src/coordination/mailbox-types.ts
|
|
1481
1862
|
function normalizeRecipient(to) {
|
|
1482
1863
|
return to.trim().toLowerCase() === "all" ? "*" : to.trim();
|
|
@@ -1485,13 +1866,6 @@ function normalizeRecipient(to) {
|
|
|
1485
1866
|
// src/coordination/global-mailbox.ts
|
|
1486
1867
|
var MAILBOX_FILE = "_mailbox.jsonl";
|
|
1487
1868
|
var CLIENT_REGISTRY_FILE = "_mailbox.clients.json";
|
|
1488
|
-
var AGENT_STALE_MS = 6e4;
|
|
1489
|
-
var AGENT_PURGE_MS = 864e5;
|
|
1490
|
-
var CLIENT_STALE_MS = 6e4;
|
|
1491
|
-
var HEARTBEAT_THROTTLE_MS = 5e3;
|
|
1492
|
-
var REGISTRY_CACHE_TTL_MS = 2e3;
|
|
1493
|
-
var LINE_SEPARATOR = "\n";
|
|
1494
|
-
var MESSAGE_CACHE_MAX_ENTRIES = 1e4;
|
|
1495
1869
|
var GlobalMailbox = class {
|
|
1496
1870
|
/** Path to the JSONL message file. */
|
|
1497
1871
|
messagePath;
|
|
@@ -1503,6 +1877,12 @@ var GlobalMailbox = class {
|
|
|
1503
1877
|
_events;
|
|
1504
1878
|
/** Optional HQ publisher for cross-project command-center telemetry. */
|
|
1505
1879
|
_hqPublisher;
|
|
1880
|
+
/**
|
|
1881
|
+
* Optional SSE event emitter for real-time push to HTTP bridge clients.
|
|
1882
|
+
* When present, `send`/`ack`/`softDelete`/`restore` emit events that
|
|
1883
|
+
* connected SSE subscribers receive instantly.
|
|
1884
|
+
*/
|
|
1885
|
+
eventEmitter;
|
|
1506
1886
|
/**
|
|
1507
1887
|
* Local cache of the agent registry to avoid re-reading on every call.
|
|
1508
1888
|
* Time-bounded: the registry file is shared ACROSS PROCESSES (that's the
|
|
@@ -1548,20 +1928,47 @@ var GlobalMailbox = class {
|
|
|
1548
1928
|
* that follows the read. Pattern mirrors `DefaultMemoryStore.runSerialized`.
|
|
1549
1929
|
*/
|
|
1550
1930
|
_readChain = Promise.resolve([]);
|
|
1931
|
+
/**
|
|
1932
|
+
* Recipient → Set of indices into `_messageCache`. Maintained alongside
|
|
1933
|
+
* the cache so `query({ to })` and `unreadCount(agentId)` can skip the
|
|
1934
|
+
* O(N) full scan and iterate only the messages addressed to the target
|
|
1935
|
+
* recipient (plus broadcasts `*`).
|
|
1936
|
+
*
|
|
1937
|
+
* The index is rebuilt whenever the cache array is replaced
|
|
1938
|
+
* (`_setMessageCache`), extended when new messages are pushed
|
|
1939
|
+
* (`_pushToCache`, `_readNewMessagesOnly`), and cleared on `close()`.
|
|
1940
|
+
* It is `null` when the cache itself is null (> MESSAGE_CACHE_MAX_ENTRIES
|
|
1941
|
+
* or never populated).
|
|
1942
|
+
*
|
|
1943
|
+
* Safety: array indices are valid only as long as the cache array
|
|
1944
|
+
* reference hasn't changed. Since we rebuild the index in the same
|
|
1945
|
+
* synchronous step that replaces the cache, a reader that calls
|
|
1946
|
+
* `_readMessagesCached()` either gets the old array + old index, or
|
|
1947
|
+
* the new array + new index — never a mismatch.
|
|
1948
|
+
*/
|
|
1949
|
+
_recipientIndex = null;
|
|
1950
|
+
/**
|
|
1951
|
+
* Sender → Set of indices into `_messageCache`. Same lifecycle and
|
|
1952
|
+
* safety properties as `_recipientIndex`, but keyed on `msg.from`
|
|
1953
|
+
* so `query({ from })` can skip the full scan.
|
|
1954
|
+
*/
|
|
1955
|
+
_senderIndex = null;
|
|
1551
1956
|
/**
|
|
1552
1957
|
* @param projectDir — `~/.wrongstack/projects/<slug>/`
|
|
1553
1958
|
* @param events — optional EventBus for real-time TUI/WebUI notifications
|
|
1554
1959
|
* @param hqPublisher — optional HQ publisher, or getter, for cross-project telemetry
|
|
1960
|
+
* @param eventEmitter — optional SSE event emitter for HTTP bridge push
|
|
1555
1961
|
*/
|
|
1556
|
-
constructor(projectDir, events, hqPublisher) {
|
|
1557
|
-
this.messagePath =
|
|
1558
|
-
this.registryPath =
|
|
1559
|
-
this.clientRegistryPath =
|
|
1962
|
+
constructor(projectDir, events, hqPublisher, eventEmitter) {
|
|
1963
|
+
this.messagePath = path4.join(projectDir, MAILBOX_FILE);
|
|
1964
|
+
this.registryPath = path4.join(projectDir, "_mailbox.registry.json");
|
|
1965
|
+
this.clientRegistryPath = path4.join(projectDir, CLIENT_REGISTRY_FILE);
|
|
1560
1966
|
this._events = events;
|
|
1561
1967
|
this._hqPublisher = hqPublisher;
|
|
1968
|
+
this.eventEmitter = eventEmitter;
|
|
1562
1969
|
}
|
|
1563
1970
|
get hqMailboxId() {
|
|
1564
|
-
return `${
|
|
1971
|
+
return `${path4.basename(path4.dirname(this.messagePath))}:mailbox`;
|
|
1565
1972
|
}
|
|
1566
1973
|
get hqPublisher() {
|
|
1567
1974
|
return typeof this._hqPublisher === "function" ? this._hqPublisher() : this._hqPublisher;
|
|
@@ -1582,12 +1989,12 @@ var GlobalMailbox = class {
|
|
|
1582
1989
|
async send(input) {
|
|
1583
1990
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1584
1991
|
const msg = {
|
|
1585
|
-
id:
|
|
1992
|
+
id: randomUUID2(),
|
|
1586
1993
|
from: input.from,
|
|
1587
1994
|
// "all" is an accepted spelling of the broadcast address — canonical
|
|
1588
1995
|
// form on disk is '*' so every query/checker matches it.
|
|
1589
1996
|
to: normalizeRecipient(input.to),
|
|
1590
|
-
type: input.type,
|
|
1997
|
+
type: normalizeMailboxMessageType(input.type),
|
|
1591
1998
|
subject: input.subject,
|
|
1592
1999
|
body: input.body,
|
|
1593
2000
|
priority: input.priority ?? "normal",
|
|
@@ -1595,10 +2002,11 @@ var GlobalMailbox = class {
|
|
|
1595
2002
|
completed: false,
|
|
1596
2003
|
timestamp: now,
|
|
1597
2004
|
replyTo: input.replyTo,
|
|
1598
|
-
taskContext: input.taskContext
|
|
2005
|
+
taskContext: input.taskContext,
|
|
2006
|
+
expiresAt: input.ttlMs !== void 0 ? new Date(Date.now() + input.ttlMs).toISOString() : void 0
|
|
1599
2007
|
};
|
|
1600
2008
|
const line = JSON.stringify(msg) + LINE_SEPARATOR;
|
|
1601
|
-
await fsp.mkdir(
|
|
2009
|
+
await fsp.mkdir(path4.dirname(this.messagePath), { recursive: true });
|
|
1602
2010
|
await withFileLock(this.messagePath, async () => {
|
|
1603
2011
|
await fsp.appendFile(this.messagePath, line, "utf8");
|
|
1604
2012
|
const { mtimeMs, size } = await this._statMessageFile();
|
|
@@ -1610,21 +2018,49 @@ var GlobalMailbox = class {
|
|
|
1610
2018
|
message: msg
|
|
1611
2019
|
});
|
|
1612
2020
|
this.publishHqMailboxSnapshot();
|
|
2021
|
+
this._events?.emitCustom("mailbox.message_sent", {
|
|
2022
|
+
messageId: msg.id,
|
|
2023
|
+
from: msg.from,
|
|
2024
|
+
to: msg.to,
|
|
2025
|
+
type: msg.type,
|
|
2026
|
+
subject: msg.subject
|
|
2027
|
+
});
|
|
2028
|
+
this.eventEmitter?.emit({
|
|
2029
|
+
type: "message.sent",
|
|
2030
|
+
messageId: msg.id,
|
|
2031
|
+
from: msg.from,
|
|
2032
|
+
to: msg.to,
|
|
2033
|
+
timestamp: now
|
|
2034
|
+
});
|
|
1613
2035
|
return msg;
|
|
1614
2036
|
}
|
|
1615
2037
|
async query(q) {
|
|
2038
|
+
const queryType = q.type === void 0 ? void 0 : normalizeMailboxMessageType(q.type);
|
|
1616
2039
|
const all = await this._readMessagesCached();
|
|
1617
2040
|
const limit = q.limit ?? 50;
|
|
1618
2041
|
const order = q.minPriority !== void 0 ? { low: 0, normal: 1, high: 2 } : null;
|
|
1619
2042
|
const minPriorityRank = order && q.minPriority !== void 0 ? order[q.minPriority] : 0;
|
|
1620
2043
|
const out = [];
|
|
1621
|
-
|
|
1622
|
-
|
|
2044
|
+
let candidates;
|
|
2045
|
+
if (q.to !== void 0 && this._recipientIndex !== null && q.from === void 0 && q.type === void 0 && q.minPriority === void 0) {
|
|
2046
|
+
const indices = /* @__PURE__ */ new Set();
|
|
2047
|
+
const direct = this._recipientIndex.get(q.to);
|
|
2048
|
+
if (direct !== void 0) for (const i of direct) indices.add(i);
|
|
2049
|
+
const broadcasts = this._recipientIndex.get("*");
|
|
2050
|
+
if (broadcasts !== void 0) for (const i of broadcasts) indices.add(i);
|
|
2051
|
+
candidates = [...indices].sort((a, b) => a - b).map((i) => all[i]);
|
|
2052
|
+
} else if (q.from !== void 0 && q.to === void 0 && this._senderIndex !== null && q.type === void 0 && q.minPriority === void 0) {
|
|
2053
|
+
const indices = this._senderIndex.get(q.from);
|
|
2054
|
+
candidates = indices !== void 0 ? [...indices].sort((a, b) => a - b).map((i) => all[i]) : [];
|
|
2055
|
+
} else {
|
|
2056
|
+
candidates = all;
|
|
2057
|
+
}
|
|
2058
|
+
for (const m of candidates) {
|
|
1623
2059
|
if (q.to !== void 0 && m.to !== q.to && m.to !== "*") continue;
|
|
1624
2060
|
if (q.from !== void 0 && m.from !== q.from) continue;
|
|
1625
2061
|
if (q.unreadBy !== void 0 && q.unreadBy in m.readBy) continue;
|
|
1626
2062
|
if (q.incompleteOnly && m.completed) continue;
|
|
1627
|
-
if (
|
|
2063
|
+
if (queryType !== void 0 && m.type !== queryType) continue;
|
|
1628
2064
|
if (order !== null && (order[m.priority] ?? 1) < minPriorityRank) {
|
|
1629
2065
|
continue;
|
|
1630
2066
|
}
|
|
@@ -1682,6 +2118,13 @@ var GlobalMailbox = class {
|
|
|
1682
2118
|
action: message.completed ? "message.completed" : "message.read",
|
|
1683
2119
|
message
|
|
1684
2120
|
});
|
|
2121
|
+
this.eventEmitter?.emit({
|
|
2122
|
+
type: "message.acked",
|
|
2123
|
+
messageId: message.id,
|
|
2124
|
+
from: message.from,
|
|
2125
|
+
to: message.to,
|
|
2126
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
2127
|
+
});
|
|
1685
2128
|
}
|
|
1686
2129
|
if (updated.length > 0) this.publishHqMailboxSnapshot();
|
|
1687
2130
|
return updated;
|
|
@@ -1689,10 +2132,22 @@ var GlobalMailbox = class {
|
|
|
1689
2132
|
async unreadCount(forAgentId) {
|
|
1690
2133
|
const all = await this._readMessagesCached();
|
|
1691
2134
|
let count = 0;
|
|
1692
|
-
|
|
1693
|
-
const
|
|
1694
|
-
|
|
1695
|
-
|
|
2135
|
+
if (this._recipientIndex !== null) {
|
|
2136
|
+
const indices = /* @__PURE__ */ new Set();
|
|
2137
|
+
const direct = this._recipientIndex.get(forAgentId);
|
|
2138
|
+
if (direct !== void 0) for (const i of direct) indices.add(i);
|
|
2139
|
+
const broadcasts = this._recipientIndex.get("*");
|
|
2140
|
+
if (broadcasts !== void 0) for (const i of broadcasts) indices.add(i);
|
|
2141
|
+
for (const i of indices) {
|
|
2142
|
+
const m = all[i];
|
|
2143
|
+
if (!(forAgentId in m.readBy) && !m.completed) count++;
|
|
2144
|
+
}
|
|
2145
|
+
} else {
|
|
2146
|
+
for (let i = 0; i < all.length; i++) {
|
|
2147
|
+
const m = all[i];
|
|
2148
|
+
if ((m.to === forAgentId || m.to === "*") && !(forAgentId in m.readBy) && !m.completed) {
|
|
2149
|
+
count++;
|
|
2150
|
+
}
|
|
1696
2151
|
}
|
|
1697
2152
|
}
|
|
1698
2153
|
return count;
|
|
@@ -1702,6 +2157,7 @@ var GlobalMailbox = class {
|
|
|
1702
2157
|
await withFileLock(this.messagePath, async () => {
|
|
1703
2158
|
const all = await this._readMessagesFresh();
|
|
1704
2159
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
2160
|
+
let changed = false;
|
|
1705
2161
|
for (const m of all) {
|
|
1706
2162
|
if (m.id !== mailId) continue;
|
|
1707
2163
|
if (m.deletedAt !== void 0) {
|
|
@@ -1711,19 +2167,30 @@ var GlobalMailbox = class {
|
|
|
1711
2167
|
m.deletedAt = now;
|
|
1712
2168
|
m.deletedBy = by;
|
|
1713
2169
|
updated = m;
|
|
2170
|
+
changed = true;
|
|
2171
|
+
}
|
|
2172
|
+
if (changed) {
|
|
2173
|
+
const serialized = all.map((m) => JSON.stringify(m)).join(LINE_SEPARATOR) + LINE_SEPARATOR;
|
|
2174
|
+
await fsp.writeFile(this.messagePath, serialized, "utf8");
|
|
1714
2175
|
}
|
|
1715
|
-
const serialized = all.map((m) => JSON.stringify(m)).join(LINE_SEPARATOR) + LINE_SEPARATOR;
|
|
1716
|
-
await fsp.writeFile(this.messagePath, serialized, "utf8");
|
|
1717
2176
|
const { mtimeMs, size } = await this._statMessageFile();
|
|
1718
2177
|
this._setMessageCache(all, mtimeMs, size);
|
|
1719
2178
|
});
|
|
1720
2179
|
if (updated !== null) {
|
|
2180
|
+
const msg = updated;
|
|
1721
2181
|
this.publishHqMailboxEvent({
|
|
1722
2182
|
mailboxId: this.hqMailboxId,
|
|
1723
2183
|
action: "message.updated",
|
|
1724
|
-
message:
|
|
2184
|
+
message: msg
|
|
1725
2185
|
});
|
|
1726
2186
|
this.publishHqMailboxSnapshot();
|
|
2187
|
+
this.eventEmitter?.emit({
|
|
2188
|
+
type: "message.deleted",
|
|
2189
|
+
messageId: msg.id,
|
|
2190
|
+
from: msg.from,
|
|
2191
|
+
to: msg.to,
|
|
2192
|
+
timestamp: msg.deletedAt ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
2193
|
+
});
|
|
1727
2194
|
}
|
|
1728
2195
|
return updated;
|
|
1729
2196
|
}
|
|
@@ -1731,24 +2198,40 @@ var GlobalMailbox = class {
|
|
|
1731
2198
|
let updated = null;
|
|
1732
2199
|
await withFileLock(this.messagePath, async () => {
|
|
1733
2200
|
const all = await this._readMessagesFresh();
|
|
2201
|
+
let changed = false;
|
|
1734
2202
|
for (const m of all) {
|
|
1735
2203
|
if (m.id !== mailId) continue;
|
|
2204
|
+
if (m.deletedAt === void 0 && m.deletedBy === void 0) {
|
|
2205
|
+
updated = m;
|
|
2206
|
+
continue;
|
|
2207
|
+
}
|
|
1736
2208
|
delete m.deletedAt;
|
|
1737
2209
|
delete m.deletedBy;
|
|
1738
2210
|
updated = m;
|
|
2211
|
+
changed = true;
|
|
2212
|
+
}
|
|
2213
|
+
if (changed) {
|
|
2214
|
+
const serialized = all.map((m) => JSON.stringify(m)).join(LINE_SEPARATOR) + LINE_SEPARATOR;
|
|
2215
|
+
await fsp.writeFile(this.messagePath, serialized, "utf8");
|
|
1739
2216
|
}
|
|
1740
|
-
const serialized = all.map((m) => JSON.stringify(m)).join(LINE_SEPARATOR) + LINE_SEPARATOR;
|
|
1741
|
-
await fsp.writeFile(this.messagePath, serialized, "utf8");
|
|
1742
2217
|
const { mtimeMs, size } = await this._statMessageFile();
|
|
1743
2218
|
this._setMessageCache(all, mtimeMs, size);
|
|
1744
2219
|
});
|
|
1745
2220
|
if (updated !== null) {
|
|
2221
|
+
const msg = updated;
|
|
1746
2222
|
this.publishHqMailboxEvent({
|
|
1747
2223
|
mailboxId: this.hqMailboxId,
|
|
1748
2224
|
action: "message.updated",
|
|
1749
|
-
message:
|
|
2225
|
+
message: msg
|
|
1750
2226
|
});
|
|
1751
2227
|
this.publishHqMailboxSnapshot();
|
|
2228
|
+
this.eventEmitter?.emit({
|
|
2229
|
+
type: "message.restored",
|
|
2230
|
+
messageId: msg.id,
|
|
2231
|
+
from: msg.from,
|
|
2232
|
+
to: msg.to,
|
|
2233
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
2234
|
+
});
|
|
1752
2235
|
}
|
|
1753
2236
|
return updated;
|
|
1754
2237
|
}
|
|
@@ -1881,8 +2364,19 @@ var GlobalMailbox = class {
|
|
|
1881
2364
|
}
|
|
1882
2365
|
async getAgentStatuses() {
|
|
1883
2366
|
await this._ensureRegistry();
|
|
1884
|
-
|
|
2367
|
+
let registry = await this._readRegistry();
|
|
2368
|
+
const before = registry.size;
|
|
1885
2369
|
this._pruneStaleInPlace(registry);
|
|
2370
|
+
if (registry.size < before) {
|
|
2371
|
+
await withFileLock(this.registryPath, async () => {
|
|
2372
|
+
const fresh = await this._readRegistry({ fresh: true });
|
|
2373
|
+
this._pruneStaleInPlace(fresh);
|
|
2374
|
+
this._registryCache = fresh;
|
|
2375
|
+
this._registryCacheAt = Date.now();
|
|
2376
|
+
await this._writeRegistry(fresh);
|
|
2377
|
+
registry = fresh;
|
|
2378
|
+
});
|
|
2379
|
+
}
|
|
1886
2380
|
const now = Date.now();
|
|
1887
2381
|
return Array.from(registry.values()).map((a) => ({
|
|
1888
2382
|
agentId: a.agentId,
|
|
@@ -1934,6 +2428,20 @@ var GlobalMailbox = class {
|
|
|
1934
2428
|
});
|
|
1935
2429
|
this.publishHqMailboxSnapshot();
|
|
1936
2430
|
}
|
|
2431
|
+
async deregisterClient(clientId) {
|
|
2432
|
+
await this._ensureClientRegistry();
|
|
2433
|
+
await withFileLock(this.clientRegistryPath, async () => {
|
|
2434
|
+
const registry = await this._readClientRegistry({ fresh: true });
|
|
2435
|
+
this._pruneStaleClientsInPlace(registry);
|
|
2436
|
+
registry.delete(clientId);
|
|
2437
|
+
this._clientRegistryCache = registry;
|
|
2438
|
+
this._clientRegistryCacheAt = Date.now();
|
|
2439
|
+
await this._writeClientRegistry(registry);
|
|
2440
|
+
});
|
|
2441
|
+
this._lastClientHeartbeat.delete(clientId);
|
|
2442
|
+
this._events?.emitCustom("mailbox.client_deregistered", { clientId });
|
|
2443
|
+
this.publishHqMailboxSnapshot();
|
|
2444
|
+
}
|
|
1937
2445
|
async clientHeartbeat(input) {
|
|
1938
2446
|
const last = this._lastClientHeartbeat.get(input.clientId) ?? 0;
|
|
1939
2447
|
const now = Date.now();
|
|
@@ -1963,7 +2471,11 @@ var GlobalMailbox = class {
|
|
|
1963
2471
|
async getClientStatuses() {
|
|
1964
2472
|
await this._ensureClientRegistry();
|
|
1965
2473
|
const registry = await this._readClientRegistry();
|
|
2474
|
+
const before = registry.size;
|
|
1966
2475
|
this._pruneStaleClientsInPlace(registry);
|
|
2476
|
+
if (registry.size < before) {
|
|
2477
|
+
await this._writeClientRegistry(registry);
|
|
2478
|
+
}
|
|
1967
2479
|
const now = Date.now();
|
|
1968
2480
|
return Array.from(registry.values()).map((c) => ({
|
|
1969
2481
|
clientId: c.clientId,
|
|
@@ -1975,6 +2487,32 @@ var GlobalMailbox = class {
|
|
|
1975
2487
|
pid: c.pid
|
|
1976
2488
|
})).sort((a, b) => b.lastSeenAt.localeCompare(a.lastSeenAt));
|
|
1977
2489
|
}
|
|
2490
|
+
/**
|
|
2491
|
+
* Explicitly purge stale clients from the registry and write back to disk.
|
|
2492
|
+
* Removes client entries whose lastSeenAt is older than CLIENT_STALE_MS.
|
|
2493
|
+
* Returns the number of entries purged.
|
|
2494
|
+
*
|
|
2495
|
+
* Idempotent — safe to call regularly. The same pruning runs implicitly
|
|
2496
|
+
* inside registerClient, clientHeartbeat, and getClientStatuses, but if
|
|
2497
|
+
* no client registers or heartbeats for a long time, this public method
|
|
2498
|
+
* ensures the file gets cleaned up on demand.
|
|
2499
|
+
*/
|
|
2500
|
+
async purgeClients() {
|
|
2501
|
+
await this._ensureClientRegistry();
|
|
2502
|
+
let purged = 0;
|
|
2503
|
+
await withFileLock(this.clientRegistryPath, async () => {
|
|
2504
|
+
const registry = await this._readClientRegistry({ fresh: true });
|
|
2505
|
+
const before = registry.size;
|
|
2506
|
+
this._pruneStaleClientsInPlace(registry);
|
|
2507
|
+
purged = before - registry.size;
|
|
2508
|
+
if (purged > 0) {
|
|
2509
|
+
this._clientRegistryCache = registry;
|
|
2510
|
+
this._clientRegistryCacheAt = Date.now();
|
|
2511
|
+
await this._writeClientRegistry(registry);
|
|
2512
|
+
}
|
|
2513
|
+
});
|
|
2514
|
+
return purged;
|
|
2515
|
+
}
|
|
1978
2516
|
// ── Lifecycle ───────────────────────────────────────────────────────────
|
|
1979
2517
|
async close() {
|
|
1980
2518
|
this._registryCache = null;
|
|
@@ -1982,6 +2520,8 @@ var GlobalMailbox = class {
|
|
|
1982
2520
|
this._messageCache = null;
|
|
1983
2521
|
this._messageCacheMtime = -1;
|
|
1984
2522
|
this._messageCacheSize = -1;
|
|
2523
|
+
this._recipientIndex = null;
|
|
2524
|
+
this._senderIndex = null;
|
|
1985
2525
|
}
|
|
1986
2526
|
async clearAll() {
|
|
1987
2527
|
await withFileLock(this.messagePath, async () => {
|
|
@@ -2030,6 +2570,100 @@ var GlobalMailbox = class {
|
|
|
2030
2570
|
remaining
|
|
2031
2571
|
};
|
|
2032
2572
|
}
|
|
2573
|
+
// ── Auto-compaction ─────────────────────────────────────────────────────
|
|
2574
|
+
_autoCompactTimer = null;
|
|
2575
|
+
async autoCompact(opts) {
|
|
2576
|
+
const readMaxAgeMs = opts?.readMaxAgeMs ?? AUTO_COMPACT_READ_MAX_AGE_MS;
|
|
2577
|
+
const defaultTtlMs = opts?.defaultTtlMs ?? AUTO_COMPACT_DEFAULT_TTL_MS;
|
|
2578
|
+
const completedMaxAgeMs = opts?.completedMaxAgeMs ?? 864e5;
|
|
2579
|
+
const incompleteMaxAgeMs = opts?.incompleteMaxAgeMs ?? 6048e5;
|
|
2580
|
+
let expiredPurged = 0;
|
|
2581
|
+
let readByAllPurged = 0;
|
|
2582
|
+
let completedPurged = 0;
|
|
2583
|
+
let incompletePurged = 0;
|
|
2584
|
+
let remaining = 0;
|
|
2585
|
+
let onlineAgentIds = null;
|
|
2586
|
+
try {
|
|
2587
|
+
const statuses = await this.getAgentStatuses();
|
|
2588
|
+
const online = statuses.filter((s) => s.online);
|
|
2589
|
+
onlineAgentIds = online.length > 0 ? new Set(online.map((s) => s.agentId)) : null;
|
|
2590
|
+
} catch {
|
|
2591
|
+
onlineAgentIds = null;
|
|
2592
|
+
}
|
|
2593
|
+
await withFileLock(this.messagePath, async () => {
|
|
2594
|
+
const all = await this._readMessagesFresh();
|
|
2595
|
+
const now = Date.now();
|
|
2596
|
+
const cutoffReadAge = now - readMaxAgeMs;
|
|
2597
|
+
const cutoffCompleted = now - completedMaxAgeMs;
|
|
2598
|
+
const cutoffIncomplete = now - incompleteMaxAgeMs;
|
|
2599
|
+
const cutoffDefaultTtl = now - defaultTtlMs;
|
|
2600
|
+
const kept = [];
|
|
2601
|
+
for (const msg of all) {
|
|
2602
|
+
const msgTime = new Date(msg.timestamp).getTime();
|
|
2603
|
+
if (msg.expiresAt !== void 0) {
|
|
2604
|
+
if (new Date(msg.expiresAt).getTime() < now) {
|
|
2605
|
+
expiredPurged++;
|
|
2606
|
+
continue;
|
|
2607
|
+
}
|
|
2608
|
+
} else if (msgTime < cutoffDefaultTtl) {
|
|
2609
|
+
expiredPurged++;
|
|
2610
|
+
continue;
|
|
2611
|
+
}
|
|
2612
|
+
if (onlineAgentIds !== null && !msg.completed) {
|
|
2613
|
+
const readByAll = onlineAgentIds.size > 0 && [...onlineAgentIds].every((id) => id in msg.readBy);
|
|
2614
|
+
if (readByAll) {
|
|
2615
|
+
const readTimes = Object.values(msg.readBy).map((t) => new Date(t).getTime());
|
|
2616
|
+
const latestRead = Math.max(...readTimes);
|
|
2617
|
+
if (latestRead < cutoffReadAge) {
|
|
2618
|
+
readByAllPurged++;
|
|
2619
|
+
continue;
|
|
2620
|
+
}
|
|
2621
|
+
}
|
|
2622
|
+
}
|
|
2623
|
+
const completedTime = msg.completedAt ? new Date(msg.completedAt).getTime() : 0;
|
|
2624
|
+
if (msg.completed && completedTime < cutoffCompleted) {
|
|
2625
|
+
completedPurged++;
|
|
2626
|
+
continue;
|
|
2627
|
+
}
|
|
2628
|
+
if (!msg.completed && msgTime < cutoffIncomplete) {
|
|
2629
|
+
incompletePurged++;
|
|
2630
|
+
continue;
|
|
2631
|
+
}
|
|
2632
|
+
kept.push(msg);
|
|
2633
|
+
}
|
|
2634
|
+
remaining = kept.length;
|
|
2635
|
+
if (kept.length < all.length) {
|
|
2636
|
+
const content = kept.map((m) => JSON.stringify(m)).join(LINE_SEPARATOR) + LINE_SEPARATOR;
|
|
2637
|
+
await fsp.writeFile(this.messagePath, content, "utf8");
|
|
2638
|
+
}
|
|
2639
|
+
const { mtimeMs, size } = await this._statMessageFile();
|
|
2640
|
+
this._setMessageCache(kept, mtimeMs, size);
|
|
2641
|
+
});
|
|
2642
|
+
const totalRemoved = expiredPurged + readByAllPurged + completedPurged + incompletePurged;
|
|
2643
|
+
return {
|
|
2644
|
+
expiredRemoved: expiredPurged,
|
|
2645
|
+
readByAllRemoved: readByAllPurged,
|
|
2646
|
+
stalePurged: completedPurged + incompletePurged,
|
|
2647
|
+
totalRemoved,
|
|
2648
|
+
remaining
|
|
2649
|
+
};
|
|
2650
|
+
}
|
|
2651
|
+
startAutoCompactTimer(opts) {
|
|
2652
|
+
if (this._autoCompactTimer !== null) {
|
|
2653
|
+
clearInterval(this._autoCompactTimer);
|
|
2654
|
+
}
|
|
2655
|
+
const intervalMs = opts?.intervalMs ?? AUTO_COMPACT_INTERVAL_MS;
|
|
2656
|
+
const timer = setInterval(() => {
|
|
2657
|
+
this.autoCompact(opts).catch(() => {
|
|
2658
|
+
});
|
|
2659
|
+
}, intervalMs);
|
|
2660
|
+
timer.unref?.();
|
|
2661
|
+
this._autoCompactTimer = timer;
|
|
2662
|
+
return () => {
|
|
2663
|
+
clearInterval(timer);
|
|
2664
|
+
this._autoCompactTimer = null;
|
|
2665
|
+
};
|
|
2666
|
+
}
|
|
2033
2667
|
// ── Internal ────────────────────────────────────────────────────────────
|
|
2034
2668
|
/**
|
|
2035
2669
|
* Read all messages from the JSONL file. Always reads + parses the file.
|
|
@@ -2062,44 +2696,59 @@ var GlobalMailbox = class {
|
|
|
2062
2696
|
const buf = Buffer.alloc(tailLen);
|
|
2063
2697
|
await fd.read(buf, 0, tailLen, oldSize);
|
|
2064
2698
|
const tail = buf.toString("utf8");
|
|
2065
|
-
|
|
2699
|
+
if (!tail.endsWith(LINE_SEPARATOR)) {
|
|
2700
|
+
const lastSeparatorIdx = tail.lastIndexOf(LINE_SEPARATOR);
|
|
2701
|
+
if (lastSeparatorIdx === -1) {
|
|
2702
|
+
return this._messageCache;
|
|
2703
|
+
}
|
|
2704
|
+
const completeTail = tail.slice(0, lastSeparatorIdx + 1);
|
|
2705
|
+
this._appendIncrementalLines(completeTail);
|
|
2706
|
+
this._messageCacheSize = oldSize + lastSeparatorIdx + 1;
|
|
2707
|
+
return this._messageCache;
|
|
2708
|
+
}
|
|
2709
|
+
this._appendIncrementalLines(tail);
|
|
2710
|
+
this._messageCacheSize = newSize;
|
|
2711
|
+
return this._messageCache;
|
|
2712
|
+
}
|
|
2713
|
+
_appendIncrementalLines(raw) {
|
|
2714
|
+
for (const line of raw.split(LINE_SEPARATOR)) {
|
|
2066
2715
|
if (!line.trim()) continue;
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
delete parsed["readAt"];
|
|
2716
|
+
const message = this._parseLine(line);
|
|
2717
|
+
if (message === null) continue;
|
|
2718
|
+
this._messageCache.push(message);
|
|
2719
|
+
const idx = this._messageCache.length - 1;
|
|
2720
|
+
if (this._recipientIndex !== null) {
|
|
2721
|
+
let set = this._recipientIndex.get(message.to);
|
|
2722
|
+
if (set === void 0) {
|
|
2723
|
+
set = /* @__PURE__ */ new Set();
|
|
2724
|
+
this._recipientIndex.set(message.to, set);
|
|
2077
2725
|
}
|
|
2078
|
-
|
|
2079
|
-
}
|
|
2726
|
+
set.add(idx);
|
|
2727
|
+
}
|
|
2728
|
+
if (this._senderIndex !== null) {
|
|
2729
|
+
let set = this._senderIndex.get(message.from);
|
|
2730
|
+
if (set === void 0) {
|
|
2731
|
+
set = /* @__PURE__ */ new Set();
|
|
2732
|
+
this._senderIndex.set(message.from, set);
|
|
2733
|
+
}
|
|
2734
|
+
set.add(idx);
|
|
2080
2735
|
}
|
|
2081
2736
|
}
|
|
2082
|
-
|
|
2737
|
+
}
|
|
2738
|
+
_parseLine(line) {
|
|
2739
|
+
try {
|
|
2740
|
+
return parseMailboxMessageLine(line);
|
|
2741
|
+
} catch {
|
|
2742
|
+
return null;
|
|
2743
|
+
}
|
|
2083
2744
|
}
|
|
2084
2745
|
/** Parse a JSONL string into MailboxMessage[], including migration. */
|
|
2085
2746
|
_parseLines(raw) {
|
|
2086
2747
|
const lines = raw.split(LINE_SEPARATOR).filter((l) => l.trim().length > 0);
|
|
2087
2748
|
const messages = [];
|
|
2088
2749
|
for (const line of lines) {
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
if (!parsed["readBy"]) {
|
|
2092
|
-
const readBy = {};
|
|
2093
|
-
if (parsed["read"] && parsed["readAt"]) {
|
|
2094
|
-
readBy[parsed["to"]] = parsed["readAt"];
|
|
2095
|
-
}
|
|
2096
|
-
parsed["readBy"] = readBy;
|
|
2097
|
-
delete parsed["read"];
|
|
2098
|
-
delete parsed["readAt"];
|
|
2099
|
-
}
|
|
2100
|
-
messages.push(parsed);
|
|
2101
|
-
} catch {
|
|
2102
|
-
}
|
|
2750
|
+
const message = this._parseLine(line);
|
|
2751
|
+
if (message !== null) messages.push(message);
|
|
2103
2752
|
}
|
|
2104
2753
|
return messages;
|
|
2105
2754
|
}
|
|
@@ -2187,7 +2836,6 @@ var GlobalMailbox = class {
|
|
|
2187
2836
|
try {
|
|
2188
2837
|
const updated = await this._readNewMessagesOnly(fd, this._messageCacheSize, st.size);
|
|
2189
2838
|
this._messageCacheMtime = st.mtimeMs;
|
|
2190
|
-
this._messageCacheSize = st.size;
|
|
2191
2839
|
return updated;
|
|
2192
2840
|
} finally {
|
|
2193
2841
|
await fd.close();
|
|
@@ -2224,11 +2872,46 @@ var GlobalMailbox = class {
|
|
|
2224
2872
|
this._messageCache = null;
|
|
2225
2873
|
this._messageCacheMtime = -1;
|
|
2226
2874
|
this._messageCacheSize = -1;
|
|
2875
|
+
this._recipientIndex = null;
|
|
2876
|
+
this._senderIndex = null;
|
|
2227
2877
|
return;
|
|
2228
2878
|
}
|
|
2229
2879
|
this._messageCache = messages;
|
|
2230
2880
|
this._messageCacheMtime = mtime;
|
|
2231
2881
|
this._messageCacheSize = size;
|
|
2882
|
+
this._rebuildRecipientIndex();
|
|
2883
|
+
}
|
|
2884
|
+
/**
|
|
2885
|
+
* Build the recipient AND sender indexes from the current `_messageCache`.
|
|
2886
|
+
* Called only from `_setMessageCache` so both indexes are always in sync
|
|
2887
|
+
* with a freshly-replaced cache array.
|
|
2888
|
+
*/
|
|
2889
|
+
_rebuildRecipientIndex() {
|
|
2890
|
+
const cache = this._messageCache;
|
|
2891
|
+
if (cache === null) {
|
|
2892
|
+
this._recipientIndex = null;
|
|
2893
|
+
this._senderIndex = null;
|
|
2894
|
+
return;
|
|
2895
|
+
}
|
|
2896
|
+
const recIdx = /* @__PURE__ */ new Map();
|
|
2897
|
+
const sndIdx = /* @__PURE__ */ new Map();
|
|
2898
|
+
for (let i = 0; i < cache.length; i++) {
|
|
2899
|
+
const msg = cache[i];
|
|
2900
|
+
let rSet = recIdx.get(msg.to);
|
|
2901
|
+
if (rSet === void 0) {
|
|
2902
|
+
rSet = /* @__PURE__ */ new Set();
|
|
2903
|
+
recIdx.set(msg.to, rSet);
|
|
2904
|
+
}
|
|
2905
|
+
rSet.add(i);
|
|
2906
|
+
let sSet = sndIdx.get(msg.from);
|
|
2907
|
+
if (sSet === void 0) {
|
|
2908
|
+
sSet = /* @__PURE__ */ new Set();
|
|
2909
|
+
sndIdx.set(msg.from, sSet);
|
|
2910
|
+
}
|
|
2911
|
+
sSet.add(i);
|
|
2912
|
+
}
|
|
2913
|
+
this._recipientIndex = recIdx;
|
|
2914
|
+
this._senderIndex = sndIdx;
|
|
2232
2915
|
}
|
|
2233
2916
|
/**
|
|
2234
2917
|
* Append a single just-sent message to the in-memory cache without
|
|
@@ -2255,11 +2938,28 @@ var GlobalMailbox = class {
|
|
|
2255
2938
|
return;
|
|
2256
2939
|
}
|
|
2257
2940
|
this._messageCache.push(msg);
|
|
2941
|
+
const newIdx = this._messageCache.length - 1;
|
|
2942
|
+
if (this._recipientIndex !== null) {
|
|
2943
|
+
let set = this._recipientIndex.get(msg.to);
|
|
2944
|
+
if (set === void 0) {
|
|
2945
|
+
set = /* @__PURE__ */ new Set();
|
|
2946
|
+
this._recipientIndex.set(msg.to, set);
|
|
2947
|
+
}
|
|
2948
|
+
set.add(newIdx);
|
|
2949
|
+
}
|
|
2950
|
+
if (this._senderIndex !== null) {
|
|
2951
|
+
let set = this._senderIndex.get(msg.from);
|
|
2952
|
+
if (set === void 0) {
|
|
2953
|
+
set = /* @__PURE__ */ new Set();
|
|
2954
|
+
this._senderIndex.set(msg.from, set);
|
|
2955
|
+
}
|
|
2956
|
+
set.add(newIdx);
|
|
2957
|
+
}
|
|
2258
2958
|
this._messageCacheMtime = mtime;
|
|
2259
2959
|
this._messageCacheSize = size;
|
|
2260
2960
|
}
|
|
2261
2961
|
async _ensureRegistry() {
|
|
2262
|
-
await fsp.mkdir(
|
|
2962
|
+
await fsp.mkdir(path4.dirname(this.registryPath), { recursive: true });
|
|
2263
2963
|
}
|
|
2264
2964
|
async _readRegistry(opts) {
|
|
2265
2965
|
if (!opts?.fresh && this._registryCache && Date.now() - this._registryCacheAt < REGISTRY_CACHE_TTL_MS) {
|
|
@@ -2286,35 +2986,26 @@ var GlobalMailbox = class {
|
|
|
2286
2986
|
}
|
|
2287
2987
|
}
|
|
2288
2988
|
_pruneStaleInPlace(registry) {
|
|
2289
|
-
const
|
|
2290
|
-
const purgeCutoff = Date.now() - AGENT_PURGE_MS;
|
|
2291
|
-
const toDelete = [];
|
|
2989
|
+
const cutoff = Date.now() - AGENT_STALE_MS;
|
|
2292
2990
|
for (const [id, agent] of registry) {
|
|
2293
|
-
const lastSeen =
|
|
2294
|
-
if (lastSeen <
|
|
2295
|
-
|
|
2296
|
-
continue;
|
|
2297
|
-
}
|
|
2298
|
-
if (lastSeen < staleCutoff) {
|
|
2299
|
-
agent.status = "idle";
|
|
2991
|
+
const lastSeen = Date.parse(agent.lastSeenAt);
|
|
2992
|
+
if (!Number.isFinite(lastSeen) || lastSeen < cutoff) {
|
|
2993
|
+
registry.delete(id);
|
|
2300
2994
|
}
|
|
2301
2995
|
}
|
|
2302
|
-
for (const id of toDelete) {
|
|
2303
|
-
registry.delete(id);
|
|
2304
|
-
}
|
|
2305
2996
|
}
|
|
2306
2997
|
async _writeRegistry(registry) {
|
|
2307
2998
|
const obj = {};
|
|
2308
2999
|
for (const [id, agent] of registry) {
|
|
2309
3000
|
obj[id] = agent;
|
|
2310
3001
|
}
|
|
2311
|
-
const tmp = `${this.registryPath}.${
|
|
3002
|
+
const tmp = `${this.registryPath}.${randomUUID2().slice(0, 8)}.tmp`;
|
|
2312
3003
|
await fsp.writeFile(tmp, JSON.stringify(obj), "utf8");
|
|
2313
3004
|
await fsp.rename(tmp, this.registryPath);
|
|
2314
3005
|
}
|
|
2315
3006
|
// ── Client registry internals ───────────────────────────────────────────
|
|
2316
3007
|
async _ensureClientRegistry() {
|
|
2317
|
-
await fsp.mkdir(
|
|
3008
|
+
await fsp.mkdir(path4.dirname(this.clientRegistryPath), { recursive: true });
|
|
2318
3009
|
}
|
|
2319
3010
|
async _readClientRegistry(opts) {
|
|
2320
3011
|
if (!opts?.fresh && this._clientRegistryCache && Date.now() - this._clientRegistryCacheAt < REGISTRY_CACHE_TTL_MS) {
|
|
@@ -2342,9 +3033,10 @@ var GlobalMailbox = class {
|
|
|
2342
3033
|
}
|
|
2343
3034
|
_pruneStaleClientsInPlace(registry) {
|
|
2344
3035
|
const cutoff = Date.now() - CLIENT_STALE_MS;
|
|
2345
|
-
for (const client of registry
|
|
2346
|
-
|
|
2347
|
-
|
|
3036
|
+
for (const [id, client] of registry) {
|
|
3037
|
+
const lastSeen = Date.parse(client.lastSeenAt);
|
|
3038
|
+
if (!Number.isFinite(lastSeen) || lastSeen < cutoff) {
|
|
3039
|
+
registry.delete(id);
|
|
2348
3040
|
}
|
|
2349
3041
|
}
|
|
2350
3042
|
}
|
|
@@ -2353,19 +3045,25 @@ var GlobalMailbox = class {
|
|
|
2353
3045
|
for (const [id, client] of registry) {
|
|
2354
3046
|
obj[id] = client;
|
|
2355
3047
|
}
|
|
2356
|
-
const tmp = `${this.clientRegistryPath}.${
|
|
3048
|
+
const tmp = `${this.clientRegistryPath}.${randomUUID2().slice(0, 8)}.tmp`;
|
|
2357
3049
|
await fsp.writeFile(tmp, JSON.stringify(obj), "utf8");
|
|
2358
3050
|
await fsp.rename(tmp, this.clientRegistryPath);
|
|
2359
3051
|
}
|
|
2360
3052
|
};
|
|
3053
|
+
|
|
3054
|
+
// src/hq/auth-store.ts
|
|
3055
|
+
import { randomBytes as randomBytes2, randomUUID as randomUUID3, scrypt, timingSafeEqual } from "node:crypto";
|
|
3056
|
+
import * as fs2 from "node:fs/promises";
|
|
3057
|
+
import * as syncFs from "node:fs";
|
|
3058
|
+
import * as path5 from "node:path";
|
|
2361
3059
|
var HQ_AUTH_FILE_VERSION = 1;
|
|
2362
3060
|
function defaultHqDataDir() {
|
|
2363
|
-
return
|
|
3061
|
+
return path5.join(wstackGlobalRoot(), "hq");
|
|
2364
3062
|
}
|
|
2365
3063
|
function resolveHqDataDir(override, env = process.env) {
|
|
2366
3064
|
const raw = override ?? env["WRONGSTACK_HQ_DATA_DIR"]?.trim();
|
|
2367
3065
|
if (!raw) return defaultHqDataDir();
|
|
2368
|
-
return
|
|
3066
|
+
return path5.isAbsolute(raw) ? path5.resolve(raw) : path5.resolve(process.cwd(), raw);
|
|
2369
3067
|
}
|
|
2370
3068
|
function tokenHasCapability(token, capability) {
|
|
2371
3069
|
if (token === void 0) return false;
|
|
@@ -2379,10 +3077,10 @@ function emptyHqAuthFile() {
|
|
|
2379
3077
|
};
|
|
2380
3078
|
}
|
|
2381
3079
|
function hqAuthFilePath(dataDir) {
|
|
2382
|
-
return
|
|
3080
|
+
return path5.join(dataDir, "auth.json");
|
|
2383
3081
|
}
|
|
2384
3082
|
function hqRuntimeFilePath(dataDir) {
|
|
2385
|
-
return
|
|
3083
|
+
return path5.join(dataDir, "runtime.json");
|
|
2386
3084
|
}
|
|
2387
3085
|
async function writeHqRuntimeFile(dataDir, file) {
|
|
2388
3086
|
const payload = {
|
|
@@ -2419,7 +3117,7 @@ async function readHqAuthFile(dataDir, opts = {}) {
|
|
|
2419
3117
|
const file = hqAuthFilePath(dataDir);
|
|
2420
3118
|
let raw;
|
|
2421
3119
|
try {
|
|
2422
|
-
raw = await
|
|
3120
|
+
raw = await fs2.readFile(file, "utf8");
|
|
2423
3121
|
} catch (err) {
|
|
2424
3122
|
if (err.code === "ENOENT") return emptyHqAuthFile();
|
|
2425
3123
|
opts.warn?.(`HQ auth file read failed at ${file}: ${err.message}`);
|
|
@@ -2452,7 +3150,7 @@ async function writeHqAuthFile(dataDir, file) {
|
|
|
2452
3150
|
async function ensureHqFirstRunAuthFile(dataDir, opts = {}) {
|
|
2453
3151
|
const file = hqAuthFilePath(dataDir);
|
|
2454
3152
|
try {
|
|
2455
|
-
await
|
|
3153
|
+
await fs2.access(file);
|
|
2456
3154
|
return { authFile: await readHqAuthFile(dataDir, opts), created: false };
|
|
2457
3155
|
} catch (err) {
|
|
2458
3156
|
if (err.code !== "ENOENT") {
|
|
@@ -2460,14 +3158,18 @@ async function ensureHqFirstRunAuthFile(dataDir, opts = {}) {
|
|
|
2460
3158
|
return { authFile: await readHqAuthFile(dataDir, opts), created: false };
|
|
2461
3159
|
}
|
|
2462
3160
|
}
|
|
2463
|
-
const browserToken = mintHqToken("first-run browser");
|
|
2464
|
-
const clientToken = mintHqToken("first-run client");
|
|
3161
|
+
const browserToken = { ...mintHqToken("first-run browser"), capabilities: ["control.enqueue"] };
|
|
3162
|
+
const clientToken = { ...mintHqToken("first-run client"), capabilities: ["telemetry.publish"] };
|
|
2465
3163
|
const authFile = {
|
|
2466
3164
|
version: HQ_AUTH_FILE_VERSION,
|
|
2467
3165
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2468
3166
|
browserTokens: [browserToken],
|
|
2469
3167
|
clientTokens: [clientToken]
|
|
2470
3168
|
};
|
|
3169
|
+
if (opts.password) {
|
|
3170
|
+
authFile.passwordHash = await hashHqPassword(opts.password);
|
|
3171
|
+
authFile.cookieSecret = mintHqCookieSecret();
|
|
3172
|
+
}
|
|
2471
3173
|
await writeHqAuthFile(dataDir, authFile);
|
|
2472
3174
|
return { authFile: await readHqAuthFile(dataDir, opts), created: true, browserToken, clientToken };
|
|
2473
3175
|
}
|
|
@@ -2477,11 +3179,47 @@ async function mutateHqAuthFile(dataDir, mutator, opts = {}) {
|
|
|
2477
3179
|
await writeHqAuthFile(dataDir, next);
|
|
2478
3180
|
return next;
|
|
2479
3181
|
}
|
|
3182
|
+
var HQ_PASSWORD_SALT_BYTES = 16;
|
|
3183
|
+
var HQ_PASSWORD_HASH_BYTES = 32;
|
|
3184
|
+
var HQ_PASSWORD_SCRYPT_PARAMS = { N: 16384, r: 8, p: 1 };
|
|
3185
|
+
function hashHqPassword(password) {
|
|
3186
|
+
return new Promise((resolve4, reject) => {
|
|
3187
|
+
const salt = randomBytes2(HQ_PASSWORD_SALT_BYTES);
|
|
3188
|
+
scrypt(password, salt, HQ_PASSWORD_HASH_BYTES, HQ_PASSWORD_SCRYPT_PARAMS, (err, derivedKey) => {
|
|
3189
|
+
if (err) return reject(err);
|
|
3190
|
+
const payload = `scrypt$${salt.toString("base64url")}$${derivedKey.toString("base64url")}`;
|
|
3191
|
+
resolve4(payload);
|
|
3192
|
+
});
|
|
3193
|
+
});
|
|
3194
|
+
}
|
|
3195
|
+
async function verifyHqPassword(password, hash) {
|
|
3196
|
+
const parts = hash.split("$");
|
|
3197
|
+
if (parts.length !== 3 || parts[0] !== "scrypt" || !parts[1] || !parts[2]) return false;
|
|
3198
|
+
let salt;
|
|
3199
|
+
let expected;
|
|
3200
|
+
try {
|
|
3201
|
+
salt = Buffer.from(parts[1], "base64url");
|
|
3202
|
+
expected = Buffer.from(parts[2], "base64url");
|
|
3203
|
+
} catch {
|
|
3204
|
+
return false;
|
|
3205
|
+
}
|
|
3206
|
+
if (salt.length === 0 || expected.length === 0) return false;
|
|
3207
|
+
const derived = await new Promise((resolve4, reject) => {
|
|
3208
|
+
scrypt(password, salt, expected.length, HQ_PASSWORD_SCRYPT_PARAMS, (err, key) => {
|
|
3209
|
+
if (err) reject(err);
|
|
3210
|
+
else resolve4(key);
|
|
3211
|
+
});
|
|
3212
|
+
});
|
|
3213
|
+
return timingSafeEqual(derived, expected);
|
|
3214
|
+
}
|
|
3215
|
+
function mintHqCookieSecret() {
|
|
3216
|
+
return randomBytes2(32).toString("base64url");
|
|
3217
|
+
}
|
|
2480
3218
|
function mintHqToken(label) {
|
|
2481
3219
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
2482
3220
|
return {
|
|
2483
|
-
id:
|
|
2484
|
-
token:
|
|
3221
|
+
id: randomUUID3(),
|
|
3222
|
+
token: randomUUID3().replace(/-/g, "") + randomUUID3().replace(/-/g, ""),
|
|
2485
3223
|
...label ? { label } : {},
|
|
2486
3224
|
createdAt: now
|
|
2487
3225
|
};
|
|
@@ -2494,7 +3232,7 @@ function watchHqAuthFile(dataDir, onChange, opts = {}) {
|
|
|
2494
3232
|
let closed = false;
|
|
2495
3233
|
let watcher;
|
|
2496
3234
|
try {
|
|
2497
|
-
watcher = syncFs.watch(
|
|
3235
|
+
watcher = syncFs.watch(path5.dirname(file), { recursive: false });
|
|
2498
3236
|
} catch (err) {
|
|
2499
3237
|
opts.warn?.(`HQ auth watcher could not start: ${err.message}`);
|
|
2500
3238
|
return { close: () => {
|
|
@@ -2518,7 +3256,7 @@ function watchHqAuthFile(dataDir, onChange, opts = {}) {
|
|
|
2518
3256
|
watcher.on("change", (eventType, filename) => {
|
|
2519
3257
|
const name = typeof filename === "string" ? filename : "";
|
|
2520
3258
|
if (eventType === "rename" || eventType === "change") {
|
|
2521
|
-
if (!name || name === "auth.json" || name ===
|
|
3259
|
+
if (!name || name === "auth.json" || name === path5.basename(file)) {
|
|
2522
3260
|
trigger();
|
|
2523
3261
|
}
|
|
2524
3262
|
}
|
|
@@ -2545,7 +3283,7 @@ function discoverLocalHqEndpoint(options = {}) {
|
|
|
2545
3283
|
}
|
|
2546
3284
|
function readFirstClientTokenFromAuthFile(dataDir) {
|
|
2547
3285
|
try {
|
|
2548
|
-
const raw =
|
|
3286
|
+
const raw = fs3.readFileSync(hqAuthFilePath(dataDir), "utf8");
|
|
2549
3287
|
const parsed = JSON.parse(raw);
|
|
2550
3288
|
return parsed.clientTokens?.find((t) => t.token.trim().length > 0)?.token;
|
|
2551
3289
|
} catch {
|
|
@@ -2578,6 +3316,10 @@ function resolveHqConfig(options = {}) {
|
|
|
2578
3316
|
const url = envUrl || configUrl;
|
|
2579
3317
|
const localFallbackToken = !url || isLoopbackHqUrl(url) ? readFirstClientTokenFromAuthFile(dataDir) : void 0;
|
|
2580
3318
|
const token = explicitToken || localFallbackToken;
|
|
3319
|
+
const rawContentEnv = env["WRONGSTACK_HQ_RAW_CONTENT"]?.trim();
|
|
3320
|
+
const explicitRawContent = rawContentEnv ? rawContentEnv === "1" : fileConfig?.rawContent;
|
|
3321
|
+
const projectAliasEnv = env["WRONGSTACK_HQ_PROJECT_ALIAS"]?.trim();
|
|
3322
|
+
const projectAlias = projectAliasEnv || fileConfig?.projectAlias;
|
|
2581
3323
|
if (!url) {
|
|
2582
3324
|
if (enabled === false) return void 0;
|
|
2583
3325
|
return {
|
|
@@ -2585,33 +3327,34 @@ function resolveHqConfig(options = {}) {
|
|
|
2585
3327
|
enabled: true,
|
|
2586
3328
|
discover: true,
|
|
2587
3329
|
dataDir,
|
|
2588
|
-
|
|
3330
|
+
rawContent: explicitRawContent ?? true,
|
|
3331
|
+
...token ? { token } : {},
|
|
3332
|
+
...projectAlias ? { projectAlias } : {}
|
|
2589
3333
|
};
|
|
2590
3334
|
}
|
|
2591
|
-
const
|
|
2592
|
-
const projectAliasEnv = env["WRONGSTACK_HQ_PROJECT_ALIAS"]?.trim();
|
|
3335
|
+
const rawContent = explicitRawContent ?? true;
|
|
2593
3336
|
return {
|
|
2594
3337
|
url,
|
|
2595
3338
|
...token ? { token } : {},
|
|
2596
3339
|
...enabled !== void 0 ? { enabled } : {},
|
|
2597
|
-
...
|
|
2598
|
-
...
|
|
3340
|
+
...rawContent !== void 0 ? { rawContent } : {},
|
|
3341
|
+
...projectAlias ? { projectAlias } : {}
|
|
2599
3342
|
};
|
|
2600
3343
|
}
|
|
2601
3344
|
function stableMachineId() {
|
|
2602
|
-
return
|
|
3345
|
+
return createHash2("sha256").update(hostname()).digest("hex").slice(0, 12);
|
|
2603
3346
|
}
|
|
2604
3347
|
function deriveProjectId(projectRoot) {
|
|
2605
|
-
return
|
|
3348
|
+
return createHash2("sha256").update(projectRoot).digest("hex").slice(0, 12);
|
|
2606
3349
|
}
|
|
2607
3350
|
function createHqPublisherFromEnv(options) {
|
|
2608
3351
|
const config = options.config ?? resolveHqConfig({ config: options.appConfig?.hq });
|
|
2609
3352
|
if (!config || config.enabled === false) return void 0;
|
|
2610
3353
|
const machineId = options.machineId ?? stableMachineId();
|
|
2611
3354
|
const host = options.hostnameOverride ?? hostname();
|
|
2612
|
-
const projectName = options.projectName ?? config.projectAlias ?? (
|
|
3355
|
+
const projectName = options.projectName ?? config.projectAlias ?? (basename5(options.projectRoot) || "unknown");
|
|
2613
3356
|
const client = {
|
|
2614
|
-
clientId: `${machineId}:${options.clientKind}:${process.pid}`,
|
|
3357
|
+
clientId: `${machineId}:${options.clientKind}:${process.pid}:${randomUUID4().slice(0, 8)}`,
|
|
2615
3358
|
kind: options.clientKind,
|
|
2616
3359
|
machineId,
|
|
2617
3360
|
...host ? { hostname: host } : {},
|
|
@@ -2642,7 +3385,8 @@ function createHqPublisherFromEnv(options) {
|
|
|
2642
3385
|
// Auto-discovery: re-read the local HQ runtime marker + client token on
|
|
2643
3386
|
// every connect attempt so late-started/restarted HQs are picked up.
|
|
2644
3387
|
...config.discover ? { resolveEndpoint: () => discoverLocalHqEndpoint({ dataDir: discoveryDataDir }) } : {},
|
|
2645
|
-
...options.discoveryPollMs !== void 0 ? { discoveryPollMs: options.discoveryPollMs } : {}
|
|
3388
|
+
...options.discoveryPollMs !== void 0 ? { discoveryPollMs: options.discoveryPollMs } : {},
|
|
3389
|
+
...options.logger !== void 0 ? { logger: options.logger } : {}
|
|
2646
3390
|
});
|
|
2647
3391
|
}
|
|
2648
3392
|
function createGlobalMailbox(options) {
|
|
@@ -2704,6 +3448,10 @@ function startAgentMonitorEventBridge(opts) {
|
|
|
2704
3448
|
};
|
|
2705
3449
|
}
|
|
2706
3450
|
|
|
3451
|
+
// src/hq/session-bridge.ts
|
|
3452
|
+
import * as fs4 from "node:fs";
|
|
3453
|
+
import * as fsp2 from "node:fs/promises";
|
|
3454
|
+
|
|
2707
3455
|
// src/hq/transcript-mapper.ts
|
|
2708
3456
|
function blocksToText(content) {
|
|
2709
3457
|
if (typeof content === "string") return content;
|
|
@@ -2852,6 +3600,8 @@ var VALID_AGENT_STATUS = /* @__PURE__ */ new Set([
|
|
|
2852
3600
|
"waiting_user",
|
|
2853
3601
|
"error"
|
|
2854
3602
|
]);
|
|
3603
|
+
var MAX_TRANSCRIPT_BATCH_ENTRIES = 32;
|
|
3604
|
+
var MAX_TRANSCRIPT_BATCH_BYTES = 512 * 1024;
|
|
2855
3605
|
function toAgentSummary(a) {
|
|
2856
3606
|
const status = VALID_AGENT_STATUS.has(a.status) ? a.status : "idle";
|
|
2857
3607
|
return {
|
|
@@ -2923,6 +3673,37 @@ function startSessionTelemetryBridge(opts) {
|
|
|
2923
3673
|
} catch {
|
|
2924
3674
|
}
|
|
2925
3675
|
}
|
|
3676
|
+
function publishTranscriptEntries(entries) {
|
|
3677
|
+
let batch = [];
|
|
3678
|
+
let batchFromSeq = seqEmitted;
|
|
3679
|
+
const publishBatch = () => {
|
|
3680
|
+
if (batch.length === 0) return;
|
|
3681
|
+
try {
|
|
3682
|
+
publisher.publishTranscriptAppend({
|
|
3683
|
+
sessionId: opts.sessionId,
|
|
3684
|
+
fromSeq: batchFromSeq,
|
|
3685
|
+
entries: batch
|
|
3686
|
+
});
|
|
3687
|
+
} catch {
|
|
3688
|
+
}
|
|
3689
|
+
seqEmitted += batch.length;
|
|
3690
|
+
batch = [];
|
|
3691
|
+
batchFromSeq = seqEmitted;
|
|
3692
|
+
};
|
|
3693
|
+
for (const entry of entries) {
|
|
3694
|
+
const candidate = [...batch, entry];
|
|
3695
|
+
const candidatePayload = {
|
|
3696
|
+
sessionId: opts.sessionId,
|
|
3697
|
+
fromSeq: batchFromSeq,
|
|
3698
|
+
entries: candidate
|
|
3699
|
+
};
|
|
3700
|
+
const tooManyEntries = candidate.length > MAX_TRANSCRIPT_BATCH_ENTRIES;
|
|
3701
|
+
const tooLarge = batch.length > 0 && Buffer.byteLength(JSON.stringify(candidatePayload), "utf8") > MAX_TRANSCRIPT_BATCH_BYTES;
|
|
3702
|
+
if (tooManyEntries || tooLarge) publishBatch();
|
|
3703
|
+
batch.push(entry);
|
|
3704
|
+
}
|
|
3705
|
+
publishBatch();
|
|
3706
|
+
}
|
|
2926
3707
|
const offAgents = opts.events?.on("session.agents_updated", (payload) => {
|
|
2927
3708
|
agents = payload.agents.map(toAgentSummary);
|
|
2928
3709
|
lastActivityAt = now();
|
|
@@ -2938,7 +3719,7 @@ function startSessionTelemetryBridge(opts) {
|
|
|
2938
3719
|
function setupWatcher() {
|
|
2939
3720
|
if (disposed || watcher) return;
|
|
2940
3721
|
try {
|
|
2941
|
-
const nextWatcher =
|
|
3722
|
+
const nextWatcher = fs4.watch(sessionFile, () => {
|
|
2942
3723
|
if (watchPending || disposed) return;
|
|
2943
3724
|
watchPending = true;
|
|
2944
3725
|
setTimeout(() => {
|
|
@@ -2962,12 +3743,12 @@ function startSessionTelemetryBridge(opts) {
|
|
|
2962
3743
|
if (disposed || tailing) return;
|
|
2963
3744
|
tailing = true;
|
|
2964
3745
|
try {
|
|
2965
|
-
const stat4 = await
|
|
3746
|
+
const stat4 = await fsp2.stat(sessionFile).catch(() => null);
|
|
2966
3747
|
if (disposed) return;
|
|
2967
3748
|
if (!stat4) return;
|
|
2968
3749
|
setupWatcher();
|
|
2969
3750
|
if (stat4.size <= offset) return;
|
|
2970
|
-
const fd = await
|
|
3751
|
+
const fd = await fsp2.open(sessionFile, "r");
|
|
2971
3752
|
try {
|
|
2972
3753
|
if (disposed) return;
|
|
2973
3754
|
const len = stat4.size - offset;
|
|
@@ -2990,15 +3771,7 @@ function startSessionTelemetryBridge(opts) {
|
|
|
2990
3771
|
for (const entry of mapSessionEventToEntries(obj)) entries.push(entry);
|
|
2991
3772
|
}
|
|
2992
3773
|
if (entries.length > 0) {
|
|
2993
|
-
|
|
2994
|
-
publisher.publishTranscriptAppend({
|
|
2995
|
-
sessionId: opts.sessionId,
|
|
2996
|
-
fromSeq: seqEmitted,
|
|
2997
|
-
entries
|
|
2998
|
-
});
|
|
2999
|
-
} catch {
|
|
3000
|
-
}
|
|
3001
|
-
seqEmitted += entries.length;
|
|
3774
|
+
publishTranscriptEntries(entries);
|
|
3002
3775
|
lastActivityAt = now();
|
|
3003
3776
|
}
|
|
3004
3777
|
} finally {
|
|
@@ -3306,6 +4079,7 @@ function startToolTelemetryBridge(opts) {
|
|
|
3306
4079
|
toolName: p.name,
|
|
3307
4080
|
...p.input !== void 0 ? {
|
|
3308
4081
|
inputSummary: summarizeHqToolArgs(p.input, {
|
|
4082
|
+
policy: publisher.redactionPolicy,
|
|
3309
4083
|
...opts.projectRoot !== void 0 ? { projectRoot: opts.projectRoot } : {}
|
|
3310
4084
|
})
|
|
3311
4085
|
} : {}
|
|
@@ -3327,7 +4101,7 @@ function startToolTelemetryBridge(opts) {
|
|
|
3327
4101
|
toolName: p.name,
|
|
3328
4102
|
status: p.ok ? "success" : "error",
|
|
3329
4103
|
durationMs: p.durationMs,
|
|
3330
|
-
...p.output !== void 0 && p.output.length > 0 ? { outputSummary: truncateForSummary(p.output) } : {}
|
|
4104
|
+
...p.output !== void 0 && p.output.length > 0 ? { outputSummary: truncateForSummary(p.output, publisher.redactionPolicy) } : {}
|
|
3331
4105
|
};
|
|
3332
4106
|
publisher.publishEvent({
|
|
3333
4107
|
type: "tool.completed",
|
|
@@ -3344,9 +4118,13 @@ function startToolTelemetryBridge(opts) {
|
|
|
3344
4118
|
inFlight.clear();
|
|
3345
4119
|
};
|
|
3346
4120
|
}
|
|
3347
|
-
function truncateForSummary(output, max = 280) {
|
|
3348
|
-
|
|
3349
|
-
|
|
4121
|
+
function truncateForSummary(output, policy, max = 280) {
|
|
4122
|
+
const resolved = resolveHqRedactionPolicy(policy);
|
|
4123
|
+
if (resolved.rawContent) {
|
|
4124
|
+
if (output.length <= max) return output;
|
|
4125
|
+
return `${output.slice(0, max)}\u2026[truncated:${output.length - max}]`;
|
|
4126
|
+
}
|
|
4127
|
+
return scrubAndTruncateHqPreview(output, max) ?? "";
|
|
3350
4128
|
}
|
|
3351
4129
|
|
|
3352
4130
|
// src/hq/cost-bridge.ts
|
|
@@ -3375,6 +4153,10 @@ function startCostTelemetryBridge(opts) {
|
|
|
3375
4153
|
off();
|
|
3376
4154
|
};
|
|
3377
4155
|
}
|
|
4156
|
+
|
|
4157
|
+
// src/hq/persistence.ts
|
|
4158
|
+
import * as fs5 from "node:fs/promises";
|
|
4159
|
+
import * as path6 from "node:path";
|
|
3378
4160
|
var DEFAULT_EVENT_LOG_MAX_LINES = 5e4;
|
|
3379
4161
|
var DEFAULT_EVENT_LOG_ROTATE_KEEP = 2e4;
|
|
3380
4162
|
var HqEventLog = class {
|
|
@@ -3385,7 +4167,7 @@ var HqEventLog = class {
|
|
|
3385
4167
|
lineCount = 0;
|
|
3386
4168
|
counted = false;
|
|
3387
4169
|
constructor(opts) {
|
|
3388
|
-
this.filePath =
|
|
4170
|
+
this.filePath = path6.join(opts.dataDir, "events.jsonl");
|
|
3389
4171
|
this.maxLines = opts.maxLines ?? DEFAULT_EVENT_LOG_MAX_LINES;
|
|
3390
4172
|
this.rotateKeep = opts.rotateKeep ?? DEFAULT_EVENT_LOG_ROTATE_KEEP;
|
|
3391
4173
|
}
|
|
@@ -3405,7 +4187,7 @@ var HqEventLog = class {
|
|
|
3405
4187
|
this.counted = true;
|
|
3406
4188
|
}
|
|
3407
4189
|
const line = JSON.stringify(event) + "\n";
|
|
3408
|
-
await
|
|
4190
|
+
await fs5.appendFile(this.filePath, line, { encoding: "utf8" });
|
|
3409
4191
|
this.lineCount += 1;
|
|
3410
4192
|
if (this.lineCount >= this.maxLines) {
|
|
3411
4193
|
await this.rotate();
|
|
@@ -3414,7 +4196,7 @@ var HqEventLog = class {
|
|
|
3414
4196
|
async rotate() {
|
|
3415
4197
|
await withFileLock(this.filePath, async () => {
|
|
3416
4198
|
try {
|
|
3417
|
-
const content = await
|
|
4199
|
+
const content = await fs5.readFile(this.filePath, "utf8");
|
|
3418
4200
|
const lines = content.split("\n").filter((l) => l.length > 0);
|
|
3419
4201
|
if (lines.length <= this.rotateKeep) {
|
|
3420
4202
|
this.lineCount = lines.length;
|
|
@@ -3429,7 +4211,7 @@ var HqEventLog = class {
|
|
|
3429
4211
|
}
|
|
3430
4212
|
async countLines() {
|
|
3431
4213
|
try {
|
|
3432
|
-
const content = await
|
|
4214
|
+
const content = await fs5.readFile(this.filePath, "utf8");
|
|
3433
4215
|
return content.split("\n").filter((l) => l.length > 0).length;
|
|
3434
4216
|
} catch {
|
|
3435
4217
|
return 0;
|
|
@@ -3442,7 +4224,7 @@ var HqEventLog = class {
|
|
|
3442
4224
|
async recent(limit, typeFilter) {
|
|
3443
4225
|
let content;
|
|
3444
4226
|
try {
|
|
3445
|
-
content = await
|
|
4227
|
+
content = await fs5.readFile(this.filePath, "utf8");
|
|
3446
4228
|
} catch {
|
|
3447
4229
|
return [];
|
|
3448
4230
|
}
|
|
@@ -3469,7 +4251,7 @@ var HqSnapshotStore = class {
|
|
|
3469
4251
|
filePath;
|
|
3470
4252
|
writeChain = Promise.resolve();
|
|
3471
4253
|
constructor(opts) {
|
|
3472
|
-
this.filePath =
|
|
4254
|
+
this.filePath = path6.join(opts.dataDir, "snapshot.json");
|
|
3473
4255
|
}
|
|
3474
4256
|
/** Persist a snapshot. Best-effort, never rejects. */
|
|
3475
4257
|
save(snapshot) {
|
|
@@ -3484,7 +4266,7 @@ var HqSnapshotStore = class {
|
|
|
3484
4266
|
/** Read the last persisted snapshot, or `null` if none. */
|
|
3485
4267
|
async load() {
|
|
3486
4268
|
try {
|
|
3487
|
-
const content = await
|
|
4269
|
+
const content = await fs5.readFile(this.filePath, "utf8");
|
|
3488
4270
|
return JSON.parse(content);
|
|
3489
4271
|
} catch {
|
|
3490
4272
|
return null;
|
|
@@ -3498,7 +4280,7 @@ var HqTimeseriesStore = class {
|
|
|
3498
4280
|
buckets = /* @__PURE__ */ new Map();
|
|
3499
4281
|
flushChain = Promise.resolve();
|
|
3500
4282
|
constructor(opts) {
|
|
3501
|
-
this.filePath =
|
|
4283
|
+
this.filePath = path6.join(opts.dataDir, "timeseries.jsonl");
|
|
3502
4284
|
this.bucketMs = opts.bucketMs ?? 5 * 60 * 1e3;
|
|
3503
4285
|
this.maxBuckets = opts.maxBuckets ?? 2016;
|
|
3504
4286
|
}
|
|
@@ -3542,7 +4324,7 @@ var HqTimeseriesStore = class {
|
|
|
3542
4324
|
async flushInternal(toWrite) {
|
|
3543
4325
|
const lines = toWrite.map((b) => JSON.stringify(b)).join("\n") + "\n";
|
|
3544
4326
|
await withFileLock(this.filePath, async () => {
|
|
3545
|
-
await
|
|
4327
|
+
await fs5.appendFile(this.filePath, lines, { encoding: "utf8" });
|
|
3546
4328
|
});
|
|
3547
4329
|
const sorted = Array.from(this.buckets.keys()).sort((a, b) => a - b);
|
|
3548
4330
|
while (this.buckets.size > this.maxBuckets) {
|
|
@@ -3561,7 +4343,7 @@ var HqTimeseriesStore = class {
|
|
|
3561
4343
|
async load() {
|
|
3562
4344
|
let content;
|
|
3563
4345
|
try {
|
|
3564
|
-
content = await
|
|
4346
|
+
content = await fs5.readFile(this.filePath, "utf8");
|
|
3565
4347
|
} catch {
|
|
3566
4348
|
return;
|
|
3567
4349
|
}
|
|
@@ -3680,6 +4462,15 @@ var HqCommandAuditLog = class {
|
|
|
3680
4462
|
const entry = this.entries.find((e) => e.commandId === commandId);
|
|
3681
4463
|
if (entry) Object.assign(entry, patch);
|
|
3682
4464
|
}
|
|
4465
|
+
/** Update only when the command belongs to the authenticated client. */
|
|
4466
|
+
updateForClient(commandId, clientId, patch) {
|
|
4467
|
+
const entry = this.entries.find(
|
|
4468
|
+
(candidate) => candidate.commandId === commandId && candidate.clientId === clientId
|
|
4469
|
+
);
|
|
4470
|
+
if (!entry) return false;
|
|
4471
|
+
Object.assign(entry, patch);
|
|
4472
|
+
return true;
|
|
4473
|
+
}
|
|
3683
4474
|
recent(limit = 200) {
|
|
3684
4475
|
return this.entries.slice(-limit);
|
|
3685
4476
|
}
|
|
@@ -3837,7 +4628,67 @@ function toAlertMessage(alert) {
|
|
|
3837
4628
|
timestamp: new Date(alert.lastFiredAt).toISOString()
|
|
3838
4629
|
};
|
|
3839
4630
|
}
|
|
3840
|
-
|
|
3841
|
-
|
|
4631
|
+
export {
|
|
4632
|
+
DEFAULT_HQ_REDACTION_POLICY,
|
|
4633
|
+
HQ_AUTH_FILE_VERSION,
|
|
4634
|
+
HQ_COMMAND_TYPES,
|
|
4635
|
+
HQ_PROTOCOL_VERSION,
|
|
4636
|
+
HQ_TRANSCRIPT_TEXT_CAP,
|
|
4637
|
+
HqAlertEngine,
|
|
4638
|
+
HqCommandAuditLog,
|
|
4639
|
+
HqEventLog,
|
|
4640
|
+
HqPublisher,
|
|
4641
|
+
HqSnapshotStore,
|
|
4642
|
+
HqTimeseriesStore,
|
|
4643
|
+
buildTranscriptFromEvents,
|
|
4644
|
+
createGlobalMailbox,
|
|
4645
|
+
createHqEventEnvelope,
|
|
4646
|
+
createHqPersistence,
|
|
4647
|
+
createHqPublisherFromEnv,
|
|
4648
|
+
createMailboxEventPayload,
|
|
4649
|
+
createMailboxSnapshotPayload,
|
|
4650
|
+
createMailboxSnapshotPayloadFromMailbox,
|
|
4651
|
+
defaultHqDataDir,
|
|
4652
|
+
discoverLocalHqEndpoint,
|
|
4653
|
+
emptyHqAuthFile,
|
|
4654
|
+
ensureHqFirstRunAuthFile,
|
|
4655
|
+
hashHqPassword,
|
|
4656
|
+
hqAuthFilePath,
|
|
4657
|
+
hqRuntimeFilePath,
|
|
4658
|
+
mapMailboxAgentToHqSummary,
|
|
4659
|
+
mapMailboxMessageToHqSummary,
|
|
4660
|
+
mapSessionEventToEntries,
|
|
4661
|
+
mergeToolResults,
|
|
4662
|
+
mintHqBrowserToken,
|
|
4663
|
+
mintHqCookieSecret,
|
|
4664
|
+
mintHqToken,
|
|
4665
|
+
mutateHqAuthFile,
|
|
4666
|
+
parseHqEventPayload,
|
|
4667
|
+
parseHqFrame,
|
|
4668
|
+
readHqAuthFile,
|
|
4669
|
+
readHqRuntimeFileSync,
|
|
4670
|
+
redactHqEvent,
|
|
4671
|
+
redactHqValue,
|
|
4672
|
+
resolveHqConfig,
|
|
4673
|
+
resolveHqConfigFromEnv,
|
|
4674
|
+
resolveHqDataDir,
|
|
4675
|
+
resolveHqRedactionPolicy,
|
|
4676
|
+
scrubAndTruncateHqPreview,
|
|
4677
|
+
startAgentMonitorEventBridge,
|
|
4678
|
+
startBrainTelemetryBridge,
|
|
4679
|
+
startCostTelemetryBridge,
|
|
4680
|
+
startFleetTelemetryBridge,
|
|
4681
|
+
startSessionTelemetryBridge,
|
|
4682
|
+
startToolTelemetryBridge,
|
|
4683
|
+
startWorktreeTelemetryBridge,
|
|
4684
|
+
summarizeHqToolArgs,
|
|
4685
|
+
tightenHqRedactionPolicy,
|
|
4686
|
+
toAlertMessage,
|
|
4687
|
+
tokenHasCapability,
|
|
4688
|
+
validateHqCommand,
|
|
4689
|
+
verifyHqPassword,
|
|
4690
|
+
watchHqAuthFile,
|
|
4691
|
+
writeHqAuthFile,
|
|
4692
|
+
writeHqRuntimeFile
|
|
4693
|
+
};
|
|
3842
4694
|
//# sourceMappingURL=index.js.map
|
|
3843
|
-
//# sourceMappingURL=index.js.map
|