@wrongstack/core 0.284.0 → 0.285.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 +100 -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 +154 -0
- package/dist/coordination/autonomous-brain.d.ts.map +1 -0
- package/dist/coordination/autonomous-coordinator.d.ts +239 -0
- package/dist/coordination/autonomous-coordinator.d.ts.map +1 -0
- package/dist/coordination/brain-monitor.d.ts +74 -0
- package/dist/coordination/brain-monitor.d.ts.map +1 -0
- package/dist/coordination/brain.d.ts +104 -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 +234 -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 +78 -2587
- package/dist/coordination/index.d.ts.map +1 -0
- package/dist/coordination/index.js +739 -254
- package/dist/coordination/index.js.map +7 -1
- package/dist/coordination/knowledge-graph.d.ts +217 -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 +68 -0
- package/dist/coordination/mailbox-actions.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-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} +37 -22
- package/dist/coordination/mailbox-types.d.ts.map +1 -0
- package/dist/coordination/mailbox.d.ts +69 -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 +1257 -819
- 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 +55 -0
- package/dist/execution/autonomous-runner.d.ts.map +1 -0
- package/dist/execution/autonomy-brain.d.ts +90 -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/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/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} +10 -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 +21 -180
- package/dist/execution/index.d.ts.map +1 -0
- package/dist/execution/index.js +465 -180
- 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 +130 -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 +161 -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 +66 -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 +417 -122
- 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 +560 -0
- package/dist/hq/protocol.d.ts.map +1 -0
- package/dist/hq/publisher.d.ts +177 -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 +108 -2872
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2724 -1344
- 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} +112 -206
- 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 +21 -8
- 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/git-plugin.d.ts +15 -0
- package/dist/plugins/git-plugin.d.ts.map +1 -0
- package/dist/plugins/observability-plugin.d.ts +19 -0
- package/dist/plugins/observability-plugin.d.ts.map +1 -0
- package/dist/plugins/plan-plugin.d.ts +16 -0
- package/dist/plugins/plan-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 +6 -8
- package/dist/security/index.d.ts.map +1 -0
- package/dist/security/index.js +102 -381
- package/dist/security/index.js.map +7 -1
- package/dist/security/permission-policy.d.ts +153 -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 +87 -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 +104 -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 +655 -300
- 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 +37 -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 +210 -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} +135 -354
- 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 +90 -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 +435 -0
- package/dist/types/multi-agent.d.ts.map +1 -0
- package/dist/{observability-D-HZN_mF.d.ts → types/observability.d.ts} +12 -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 +245 -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/index.d.ts +37 -920
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +242 -33
- 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} +19 -13
- package/dist/worktree/worktree-manager.d.ts.map +1 -0
- package/instructions/autonomy/active-mission.md +2 -4
- package/instructions/sections/tool/delegation-full.md +1 -1
- package/package.json +4 -5
- package/skills/node-modern/SKILL.md +2 -2
- package/skills/plugin-author/SKILL.md +9 -16
- 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/storage/index.js
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
|
-
import { randomUUID, createHash, randomBytes } from 'crypto';
|
|
2
|
-
import * as syncFs from 'fs';
|
|
3
|
-
import { createReadStream, openSync, writeSync, fsyncSync, closeSync, readFileSync, statSync } from 'fs';
|
|
4
|
-
import * as fsp4 from 'fs/promises';
|
|
5
|
-
import * as path2 from 'path';
|
|
6
|
-
import { createInterface } from 'readline';
|
|
7
|
-
import * as os from 'os';
|
|
8
|
-
import { hostname } from 'os';
|
|
9
|
-
import { spawn } from 'child_process';
|
|
10
|
-
import { fileURLToPath } from 'url';
|
|
11
|
-
|
|
12
1
|
// src/storage/session-store.ts
|
|
2
|
+
import { createHash as createHash4 } from "node:crypto";
|
|
3
|
+
import { createReadStream } from "node:fs";
|
|
4
|
+
import * as fsp4 from "node:fs/promises";
|
|
5
|
+
import * as path7 from "node:path";
|
|
6
|
+
import { createInterface } from "node:readline";
|
|
7
|
+
|
|
8
|
+
// src/utils/atomic-write.ts
|
|
9
|
+
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
10
|
+
import * as fs from "node:fs/promises";
|
|
11
|
+
import * as path3 from "node:path";
|
|
13
12
|
|
|
14
13
|
// src/utils/child-env.ts
|
|
15
14
|
var ALLOWED_KEYS = /* @__PURE__ */ new Set([
|
|
@@ -85,8 +84,9 @@ function sanitizeNodeOptions(value) {
|
|
|
85
84
|
}
|
|
86
85
|
return kept.join(" ");
|
|
87
86
|
}
|
|
87
|
+
var gitIdentity = null;
|
|
88
88
|
function buildChildEnv(optsOrSessionId) {
|
|
89
|
-
const opts = {};
|
|
89
|
+
const opts = typeof optsOrSessionId === "string" ? { sessionId: optsOrSessionId } : optsOrSessionId ?? {};
|
|
90
90
|
const hasOwn = Object.hasOwn(process.env, "WRONGSTACK_CHILD_ENV_PASSTHROUGH");
|
|
91
91
|
const legacyHasOwn = Object.hasOwn(process.env, "WRONGSTACK_BASH_ENV_PASSTHROUGH");
|
|
92
92
|
const passthrough = hasOwn && process.env["WRONGSTACK_CHILD_ENV_PASSTHROUGH"] === "1" || legacyHasOwn && process.env["WRONGSTACK_BASH_ENV_PASSTHROUGH"] === "1";
|
|
@@ -124,6 +124,16 @@ function buildChildEnv(optsOrSessionId) {
|
|
|
124
124
|
out[k] = v;
|
|
125
125
|
}
|
|
126
126
|
}
|
|
127
|
+
if (gitIdentity) {
|
|
128
|
+
if (gitIdentity.name) {
|
|
129
|
+
out["GIT_AUTHOR_NAME"] = gitIdentity.name;
|
|
130
|
+
out["GIT_COMMITTER_NAME"] = gitIdentity.name;
|
|
131
|
+
}
|
|
132
|
+
if (gitIdentity.email) {
|
|
133
|
+
out["GIT_AUTHOR_EMAIL"] = gitIdentity.email;
|
|
134
|
+
out["GIT_COMMITTER_EMAIL"] = gitIdentity.email;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
127
137
|
if (opts.extra) {
|
|
128
138
|
Object.assign(out, opts.extra);
|
|
129
139
|
}
|
|
@@ -236,7 +246,7 @@ function toErrorMessage(err) {
|
|
|
236
246
|
// src/utils/expect-defined.ts
|
|
237
247
|
function expectDefined(value, label) {
|
|
238
248
|
if (value === null || value === void 0) {
|
|
239
|
-
const err = new Error("Expected value to be defined");
|
|
249
|
+
const err = new Error(label ? `Expected ${label} to be defined` : "Expected value to be defined");
|
|
240
250
|
err.name = "ExpectDefinedError";
|
|
241
251
|
throw err;
|
|
242
252
|
}
|
|
@@ -385,13 +395,16 @@ function safeParse(input, maxBytes = 5e6) {
|
|
|
385
395
|
};
|
|
386
396
|
}
|
|
387
397
|
}
|
|
398
|
+
|
|
399
|
+
// src/utils/session-scoped-path.ts
|
|
400
|
+
import * as path from "node:path";
|
|
388
401
|
function sessionScopedPath(dir, sessionId, suffix) {
|
|
389
402
|
if (!sessionId || sessionId.includes("\\") || sessionId.includes("..")) {
|
|
390
403
|
throw invalid(sessionId);
|
|
391
404
|
}
|
|
392
|
-
const resolved =
|
|
393
|
-
const rel =
|
|
394
|
-
if (rel.startsWith("..") ||
|
|
405
|
+
const resolved = path.resolve(dir, `${sessionId}${suffix}`);
|
|
406
|
+
const rel = path.relative(path.resolve(dir), resolved);
|
|
407
|
+
if (rel.startsWith("..") || path.isAbsolute(rel)) {
|
|
395
408
|
throw invalid(sessionId);
|
|
396
409
|
}
|
|
397
410
|
return resolved;
|
|
@@ -409,6 +422,9 @@ function invalid(sessionId) {
|
|
|
409
422
|
function slugify(name, fallback = "prompt", maxLen = 64) {
|
|
410
423
|
return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, maxLen).replace(/-+$/g, "") || fallback;
|
|
411
424
|
}
|
|
425
|
+
|
|
426
|
+
// src/utils/ulid.ts
|
|
427
|
+
import { randomBytes } from "node:crypto";
|
|
412
428
|
var ENCODING = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
|
|
413
429
|
var ENCODING_LEN = ENCODING.length;
|
|
414
430
|
var TIME_LEN = 10;
|
|
@@ -434,6 +450,11 @@ function encodeRandom(len) {
|
|
|
434
450
|
function ulid(seedTime = Date.now()) {
|
|
435
451
|
return encodeTime(seedTime, TIME_LEN) + encodeRandom(RANDOM_LEN);
|
|
436
452
|
}
|
|
453
|
+
|
|
454
|
+
// src/utils/wstack-paths.ts
|
|
455
|
+
import { createHash } from "node:crypto";
|
|
456
|
+
import * as os from "node:os";
|
|
457
|
+
import * as path2 from "node:path";
|
|
437
458
|
function projectHash(absRoot) {
|
|
438
459
|
return createHash("sha256").update(path2.resolve(absRoot)).digest("hex").slice(0, 12);
|
|
439
460
|
}
|
|
@@ -507,18 +528,59 @@ function resolveWstackPaths(opts) {
|
|
|
507
528
|
|
|
508
529
|
// src/types/errors.ts
|
|
509
530
|
var ERROR_CODES = {
|
|
531
|
+
// Provider
|
|
532
|
+
PROVIDER_RATE_LIMITED: "PROVIDER_RATE_LIMITED",
|
|
533
|
+
PROVIDER_AUTH_FAILED: "PROVIDER_AUTH_FAILED",
|
|
534
|
+
PROVIDER_OVERLOADED: "PROVIDER_OVERLOADED",
|
|
535
|
+
PROVIDER_INVALID_REQUEST: "PROVIDER_INVALID_REQUEST",
|
|
536
|
+
PROVIDER_SERVER_ERROR: "PROVIDER_SERVER_ERROR",
|
|
537
|
+
PROVIDER_NETWORK_ERROR: "PROVIDER_NETWORK_ERROR",
|
|
538
|
+
PROVIDER_CONTEXT_OVERFLOW: "PROVIDER_CONTEXT_OVERFLOW",
|
|
539
|
+
// Tool
|
|
540
|
+
TOOL_NOT_FOUND: "TOOL_NOT_FOUND",
|
|
541
|
+
TOOL_PERMISSION_DENIED: "TOOL_PERMISSION_DENIED",
|
|
542
|
+
TOOL_EXECUTION_FAILED: "TOOL_EXECUTION_FAILED",
|
|
543
|
+
TOOL_TIMEOUT: "TOOL_TIMEOUT",
|
|
544
|
+
TOOL_INPUT_INVALID: "TOOL_INPUT_INVALID",
|
|
510
545
|
// Config
|
|
511
546
|
CONFIG_INVALID: "CONFIG_INVALID",
|
|
547
|
+
CONFIG_NOT_FOUND: "CONFIG_NOT_FOUND",
|
|
548
|
+
CONFIG_PARSE_FAILED: "CONFIG_PARSE_FAILED",
|
|
549
|
+
CONFIG_MIGRATION_NEEDED: "CONFIG_MIGRATION_NEEDED",
|
|
550
|
+
// Plugin
|
|
551
|
+
PLUGIN_LOAD_FAILED: "PLUGIN_LOAD_FAILED",
|
|
552
|
+
PLUGIN_API_MISMATCH: "PLUGIN_API_MISMATCH",
|
|
553
|
+
PLUGIN_MISSING_DEPENDENCY: "PLUGIN_MISSING_DEPENDENCY",
|
|
554
|
+
// Agent
|
|
555
|
+
AGENT_ITERATION_LIMIT: "AGENT_ITERATION_LIMIT",
|
|
556
|
+
AGENT_CONTEXT_OVERFLOW: "AGENT_CONTEXT_OVERFLOW",
|
|
557
|
+
AGENT_ABORTED: "AGENT_ABORTED",
|
|
558
|
+
AGENT_RUN_FAILED: "AGENT_RUN_FAILED",
|
|
512
559
|
// Session
|
|
513
560
|
SESSION_NOT_FOUND: "SESSION_NOT_FOUND",
|
|
514
561
|
SESSION_CORRUPTED: "SESSION_CORRUPTED",
|
|
515
562
|
SESSION_WRITE_FAILED: "SESSION_WRITE_FAILED",
|
|
563
|
+
// Container / Registry
|
|
564
|
+
CONTAINER_TOKEN_ALREADY_BOUND: "CONTAINER_TOKEN_ALREADY_BOUND",
|
|
565
|
+
CONTAINER_TOKEN_NOT_BOUND: "CONTAINER_TOKEN_NOT_BOUND",
|
|
566
|
+
CONTAINER_CIRCULAR_DEPENDENCY: "CONTAINER_CIRCULAR_DEPENDENCY",
|
|
567
|
+
REGISTRY_DUPLICATE: "REGISTRY_DUPLICATE",
|
|
568
|
+
REGISTRY_NOT_FOUND: "REGISTRY_NOT_FOUND",
|
|
569
|
+
REGISTRY_INVALID: "REGISTRY_INVALID",
|
|
516
570
|
// File system
|
|
517
571
|
FS_READ_FAILED: "FS_READ_FAILED",
|
|
572
|
+
FS_WRITE_FAILED: "FS_WRITE_FAILED",
|
|
573
|
+
FS_MKDIR_FAILED: "FS_MKDIR_FAILED",
|
|
518
574
|
FS_DELETE_FAILED: "FS_DELETE_FAILED",
|
|
519
575
|
FS_ATOMIC_WRITE_FAILED: "FS_ATOMIC_WRITE_FAILED",
|
|
576
|
+
// SDD (Spec-Driven Development)
|
|
577
|
+
SDD_VALIDATION_FAILED: "SDD_VALIDATION_FAILED",
|
|
578
|
+
SDD_PARSE_FAILED: "SDD_PARSE_FAILED",
|
|
579
|
+
SDD_INVALID_STATE: "SDD_INVALID_STATE",
|
|
580
|
+
SDD_NOT_READY: "SDD_NOT_READY",
|
|
520
581
|
// General
|
|
521
582
|
VALIDATION_ERROR: "VALIDATION_ERROR",
|
|
583
|
+
PARSE_FAILED: "PARSE_FAILED",
|
|
522
584
|
UNKNOWN: "UNKNOWN"
|
|
523
585
|
};
|
|
524
586
|
var WrongStackError = class extends Error {
|
|
@@ -598,17 +660,17 @@ var FsError = class extends WrongStackError {
|
|
|
598
660
|
|
|
599
661
|
// src/utils/atomic-write.ts
|
|
600
662
|
async function atomicWrite(targetPath, content, opts = {}) {
|
|
601
|
-
const dir =
|
|
602
|
-
await
|
|
603
|
-
const tmp =
|
|
663
|
+
const dir = path3.dirname(targetPath);
|
|
664
|
+
await fs.mkdir(dir, { recursive: true });
|
|
665
|
+
const tmp = path3.join(dir, `.${path3.basename(targetPath)}.${randomBytes2(6).toString("hex")}.tmp`);
|
|
604
666
|
try {
|
|
605
667
|
if (typeof content === "string") {
|
|
606
|
-
await
|
|
668
|
+
await fs.writeFile(tmp, content, { flag: "wx", encoding: opts.encoding ?? "utf8" });
|
|
607
669
|
} else {
|
|
608
|
-
await
|
|
670
|
+
await fs.writeFile(tmp, content, { flag: "wx" });
|
|
609
671
|
}
|
|
610
672
|
try {
|
|
611
|
-
const fh = await
|
|
673
|
+
const fh = await fs.open(tmp, "r+");
|
|
612
674
|
try {
|
|
613
675
|
await fh.sync();
|
|
614
676
|
} finally {
|
|
@@ -618,56 +680,56 @@ async function atomicWrite(targetPath, content, opts = {}) {
|
|
|
618
680
|
}
|
|
619
681
|
let mode;
|
|
620
682
|
try {
|
|
621
|
-
const stat13 = await
|
|
683
|
+
const stat13 = await fs.stat(targetPath);
|
|
622
684
|
mode = stat13.mode & 511;
|
|
623
685
|
} catch {
|
|
624
686
|
mode = opts.mode;
|
|
625
687
|
}
|
|
626
688
|
if (mode !== void 0) {
|
|
627
|
-
await
|
|
689
|
+
await fs.chmod(tmp, mode);
|
|
628
690
|
}
|
|
629
691
|
await renameWithRetry(tmp, targetPath);
|
|
630
692
|
if (mode !== void 0 && process.platform === "win32") {
|
|
631
693
|
try {
|
|
632
|
-
await
|
|
694
|
+
await fs.chmod(targetPath, mode);
|
|
633
695
|
} catch {
|
|
634
696
|
}
|
|
635
697
|
}
|
|
636
698
|
} catch (err) {
|
|
637
699
|
try {
|
|
638
|
-
await
|
|
700
|
+
await fs.unlink(tmp);
|
|
639
701
|
} catch {
|
|
640
702
|
}
|
|
641
703
|
throw err;
|
|
642
704
|
}
|
|
643
705
|
}
|
|
644
706
|
async function ensureDir(dir) {
|
|
645
|
-
await
|
|
707
|
+
await fs.mkdir(dir, { recursive: true });
|
|
646
708
|
}
|
|
647
709
|
async function withFileLock(targetPath, fn, opts = {}) {
|
|
648
|
-
const dir =
|
|
649
|
-
await
|
|
650
|
-
const lockPath =
|
|
710
|
+
const dir = path3.dirname(targetPath);
|
|
711
|
+
await fs.mkdir(dir, { recursive: true });
|
|
712
|
+
const lockPath = path3.join(dir, `.${path3.basename(targetPath)}.lock`);
|
|
651
713
|
const timeoutMs = opts.timeoutMs ?? 5e3;
|
|
652
714
|
const staleMs = opts.staleMs ?? 3e4;
|
|
653
715
|
const started = Date.now();
|
|
654
716
|
let handle;
|
|
655
717
|
for (; ; ) {
|
|
656
718
|
try {
|
|
657
|
-
handle = await
|
|
719
|
+
handle = await fs.open(lockPath, "wx");
|
|
658
720
|
await handle.writeFile(`${process.pid}:${Date.now()}`);
|
|
659
721
|
break;
|
|
660
722
|
} catch (err) {
|
|
661
723
|
const code = err.code;
|
|
662
724
|
if (code === "ENOENT") {
|
|
663
|
-
await
|
|
725
|
+
await fs.mkdir(dir, { recursive: true });
|
|
664
726
|
continue;
|
|
665
727
|
}
|
|
666
728
|
if (code !== "EEXIST") throw err;
|
|
667
729
|
try {
|
|
668
|
-
const stat13 = await
|
|
730
|
+
const stat13 = await fs.stat(lockPath);
|
|
669
731
|
if (Date.now() - stat13.mtimeMs > staleMs) {
|
|
670
|
-
await
|
|
732
|
+
await fs.unlink(lockPath);
|
|
671
733
|
continue;
|
|
672
734
|
}
|
|
673
735
|
} catch {
|
|
@@ -692,7 +754,7 @@ async function withFileLock(targetPath, fn, opts = {}) {
|
|
|
692
754
|
} catch {
|
|
693
755
|
}
|
|
694
756
|
try {
|
|
695
|
-
await
|
|
757
|
+
await fs.unlink(lockPath);
|
|
696
758
|
} catch {
|
|
697
759
|
}
|
|
698
760
|
}
|
|
@@ -700,14 +762,14 @@ async function withFileLock(targetPath, fn, opts = {}) {
|
|
|
700
762
|
var TRANSIENT_RENAME_CODES = /* @__PURE__ */ new Set(["EPERM", "EBUSY", "EACCES", "ENOTEMPTY"]);
|
|
701
763
|
async function renameWithRetry(from, to) {
|
|
702
764
|
if (process.platform !== "win32") {
|
|
703
|
-
await
|
|
765
|
+
await fs.rename(from, to);
|
|
704
766
|
return;
|
|
705
767
|
}
|
|
706
768
|
const delays = [10, 25, 60, 120, 250];
|
|
707
769
|
let lastErr;
|
|
708
770
|
for (let i = 0; i <= delays.length; i++) {
|
|
709
771
|
try {
|
|
710
|
-
await
|
|
772
|
+
await fs.rename(from, to);
|
|
711
773
|
return;
|
|
712
774
|
} catch (err) {
|
|
713
775
|
lastErr = err;
|
|
@@ -721,6 +783,11 @@ async function renameWithRetry(from, to) {
|
|
|
721
783
|
throw lastErr;
|
|
722
784
|
}
|
|
723
785
|
|
|
786
|
+
// src/storage/file-session-writer.ts
|
|
787
|
+
import { closeSync, fsyncSync, openSync, writeSync } from "node:fs";
|
|
788
|
+
import * as fsp from "node:fs/promises";
|
|
789
|
+
import * as path4 from "node:path";
|
|
790
|
+
|
|
724
791
|
// src/storage/session-helpers.ts
|
|
725
792
|
function userInputTitle(content) {
|
|
726
793
|
const text = typeof content === "string" ? content : content.filter((b) => b.type === "text").map((b) => b.text).join(" ");
|
|
@@ -736,7 +803,7 @@ var FileSessionWriter = class _FileSessionWriter {
|
|
|
736
803
|
this.meta = meta;
|
|
737
804
|
this.events = events;
|
|
738
805
|
this.resumed = opts.resumed ?? false;
|
|
739
|
-
this.manifestFile = opts.dir ?
|
|
806
|
+
this.manifestFile = opts.dir ? path4.join(opts.dir, `${path4.basename(id)}.summary.json`) : "";
|
|
740
807
|
this.filePath = opts.filePath ?? "";
|
|
741
808
|
this.secretScrubber = opts.secretScrubber;
|
|
742
809
|
this.checkpointCas = opts.checkpointCas;
|
|
@@ -1276,7 +1343,7 @@ var FileSessionWriter = class _FileSessionWriter {
|
|
|
1276
1343
|
let removedCount = 0;
|
|
1277
1344
|
let targetCheckpointSeen = false;
|
|
1278
1345
|
try {
|
|
1279
|
-
fd = await
|
|
1346
|
+
fd = await fsp.open(this.filePath, "r", 384);
|
|
1280
1347
|
while (true) {
|
|
1281
1348
|
const buf = Buffer.alloc(CHUNK_SIZE);
|
|
1282
1349
|
const { bytesRead } = await fd.read(buf, 0, CHUNK_SIZE, fileOffset);
|
|
@@ -1331,7 +1398,7 @@ var FileSessionWriter = class _FileSessionWriter {
|
|
|
1331
1398
|
await this.writeChain;
|
|
1332
1399
|
await this.handle.close();
|
|
1333
1400
|
const tmpPath = `${this.filePath}.rewind.tmp`;
|
|
1334
|
-
const src = await
|
|
1401
|
+
const src = await fsp.open(this.filePath, "r", 384);
|
|
1335
1402
|
try {
|
|
1336
1403
|
const statResult = await src.stat();
|
|
1337
1404
|
const totalSize = statResult.size;
|
|
@@ -1347,7 +1414,7 @@ var FileSessionWriter = class _FileSessionWriter {
|
|
|
1347
1414
|
} else {
|
|
1348
1415
|
newlineAfterCheckpoint = totalSize;
|
|
1349
1416
|
}
|
|
1350
|
-
const writeFd = await
|
|
1417
|
+
const writeFd = await fsp.open(tmpPath, "w", 384);
|
|
1351
1418
|
try {
|
|
1352
1419
|
let readOffset = 0;
|
|
1353
1420
|
while (readOffset < newlineAfterCheckpoint) {
|
|
@@ -1395,11 +1462,11 @@ var FileSessionWriter = class _FileSessionWriter {
|
|
|
1395
1462
|
await writeFd.close();
|
|
1396
1463
|
}
|
|
1397
1464
|
await src.close();
|
|
1398
|
-
await
|
|
1399
|
-
this.handle = await
|
|
1465
|
+
await fsp.rename(tmpPath, this.filePath);
|
|
1466
|
+
this.handle = await fsp.open(this.filePath, "a", 384);
|
|
1400
1467
|
} catch (err) {
|
|
1401
|
-
await
|
|
1402
|
-
this.handle = await
|
|
1468
|
+
await fsp.unlink(tmpPath).catch(() => void 0);
|
|
1469
|
+
this.handle = await fsp.open(this.filePath, "a", 384).catch(() => this.handle);
|
|
1403
1470
|
throw err;
|
|
1404
1471
|
}
|
|
1405
1472
|
await this.append({
|
|
@@ -1434,7 +1501,7 @@ var FileSessionWriter = class _FileSessionWriter {
|
|
|
1434
1501
|
provider: this.meta.provider ?? "unknown"
|
|
1435
1502
|
})}
|
|
1436
1503
|
`;
|
|
1437
|
-
await
|
|
1504
|
+
await fsp.writeFile(this.filePath, record, "utf8");
|
|
1438
1505
|
this.activePromptIndex = null;
|
|
1439
1506
|
this.pendingFileSnapshots = [];
|
|
1440
1507
|
}
|
|
@@ -1479,6 +1546,12 @@ var FileSessionWriter = class _FileSessionWriter {
|
|
|
1479
1546
|
}
|
|
1480
1547
|
};
|
|
1481
1548
|
|
|
1549
|
+
// src/storage/session-checkpoint-cas.ts
|
|
1550
|
+
import { spawn } from "node:child_process";
|
|
1551
|
+
import { createHash as createHash2, randomUUID } from "node:crypto";
|
|
1552
|
+
import * as fsp2 from "node:fs/promises";
|
|
1553
|
+
import * as path5 from "node:path";
|
|
1554
|
+
|
|
1482
1555
|
// src/storage/storage-concurrency.ts
|
|
1483
1556
|
async function mapWithConcurrency(items, concurrency, mapper) {
|
|
1484
1557
|
if (items.length === 0) return [];
|
|
@@ -1505,16 +1578,16 @@ var MAX_GIT_OUTPUT = 16 * 1024 * 1024;
|
|
|
1505
1578
|
var MAX_BLOB_BYTES = 64 * 1024 * 1024;
|
|
1506
1579
|
var MAX_CHECKPOINT_BYTES = 512 * 1024 * 1024;
|
|
1507
1580
|
function sha256(content) {
|
|
1508
|
-
return
|
|
1581
|
+
return createHash2("sha256").update(content).digest("hex");
|
|
1509
1582
|
}
|
|
1510
1583
|
function isInside(root, target) {
|
|
1511
|
-
const relative6 =
|
|
1512
|
-
return relative6 === "" || !relative6.startsWith("..") && !
|
|
1584
|
+
const relative6 = path5.relative(root, target);
|
|
1585
|
+
return relative6 === "" || !relative6.startsWith("..") && !path5.isAbsolute(relative6);
|
|
1513
1586
|
}
|
|
1514
1587
|
function normalizeRelative(input) {
|
|
1515
|
-
if (!input ||
|
|
1588
|
+
if (!input || path5.isAbsolute(input)) return null;
|
|
1516
1589
|
const normalized = input.replace(/\\/g, "/").replace(/^\.\//, "");
|
|
1517
|
-
const resolved =
|
|
1590
|
+
const resolved = path5.posix.normalize(normalized);
|
|
1518
1591
|
if (!resolved || resolved === "." || resolved === ".." || resolved.startsWith("../")) return null;
|
|
1519
1592
|
return resolved;
|
|
1520
1593
|
}
|
|
@@ -1529,8 +1602,8 @@ var SessionCheckpointCas = class {
|
|
|
1529
1602
|
projectRoot;
|
|
1530
1603
|
runGit;
|
|
1531
1604
|
constructor(opts) {
|
|
1532
|
-
this.rootDir =
|
|
1533
|
-
this.projectRoot =
|
|
1605
|
+
this.rootDir = path5.resolve(opts.rootDir);
|
|
1606
|
+
this.projectRoot = path5.resolve(opts.projectRoot);
|
|
1534
1607
|
this.runGit = opts.runGit ?? defaultRunGit;
|
|
1535
1608
|
}
|
|
1536
1609
|
async capture(_sessionId, _promptIndex) {
|
|
@@ -1555,17 +1628,17 @@ var SessionCheckpointCas = class {
|
|
|
1555
1628
|
relativePaths,
|
|
1556
1629
|
CAPTURE_CONCURRENCY,
|
|
1557
1630
|
async (relative6) => {
|
|
1558
|
-
const absolute =
|
|
1631
|
+
const absolute = path5.resolve(this.projectRoot, ...relative6.split("/"));
|
|
1559
1632
|
if (!isInside(this.projectRoot, absolute)) {
|
|
1560
1633
|
unresolved.push({ path: relative6, reason: "path escapes project root" });
|
|
1561
1634
|
return null;
|
|
1562
1635
|
}
|
|
1563
1636
|
try {
|
|
1564
|
-
const stat13 = await
|
|
1637
|
+
const stat13 = await fsp2.lstat(absolute);
|
|
1565
1638
|
if (stat13.isSymbolicLink()) {
|
|
1566
|
-
const linkTarget = await
|
|
1567
|
-
const resolvedLink =
|
|
1568
|
-
if (
|
|
1639
|
+
const linkTarget = await fsp2.readlink(absolute);
|
|
1640
|
+
const resolvedLink = path5.resolve(path5.dirname(absolute), linkTarget);
|
|
1641
|
+
if (path5.isAbsolute(linkTarget) || !isInside(this.projectRoot, resolvedLink)) {
|
|
1569
1642
|
unresolved.push({
|
|
1570
1643
|
path: relative6,
|
|
1571
1644
|
reason: "symlink target escapes project root"
|
|
@@ -1593,7 +1666,7 @@ var SessionCheckpointCas = class {
|
|
|
1593
1666
|
return null;
|
|
1594
1667
|
}
|
|
1595
1668
|
scheduledBytes += stat13.size;
|
|
1596
|
-
const content = await
|
|
1669
|
+
const content = await fsp2.readFile(absolute);
|
|
1597
1670
|
const blobHash = sha256(content);
|
|
1598
1671
|
await this.putBlob(blobHash, content);
|
|
1599
1672
|
return { path: relative6, state: "file", blobHash, mode: stat13.mode & 511 };
|
|
@@ -1627,11 +1700,11 @@ var SessionCheckpointCas = class {
|
|
|
1627
1700
|
};
|
|
1628
1701
|
}
|
|
1629
1702
|
async materialize(checkpoint, targetRoot) {
|
|
1630
|
-
const target =
|
|
1703
|
+
const target = path5.resolve(targetRoot);
|
|
1631
1704
|
if (target === this.projectRoot) {
|
|
1632
1705
|
throw new Error("Refusing to materialize a workspace checkpoint over the parent project root");
|
|
1633
1706
|
}
|
|
1634
|
-
const targetStat = await
|
|
1707
|
+
const targetStat = await fsp2.stat(target);
|
|
1635
1708
|
if (!targetStat.isDirectory()) throw new Error(`Checkpoint target is not a directory: ${target}`);
|
|
1636
1709
|
const manifest = await this.loadManifest(checkpoint.manifestHash);
|
|
1637
1710
|
if (manifest.baseHead !== checkpoint.baseHead.toLowerCase() || manifest.coverage !== checkpoint.coverage || manifest.entries.length !== checkpoint.entryCount || manifest.unresolved.length !== checkpoint.unresolvedCount) {
|
|
@@ -1658,7 +1731,7 @@ var SessionCheckpointCas = class {
|
|
|
1658
1731
|
if (targetStatus.stdout.length > 0) {
|
|
1659
1732
|
throw new Error("Checkpoint target must be a clean checkout before materialization");
|
|
1660
1733
|
}
|
|
1661
|
-
const realTarget = await
|
|
1734
|
+
const realTarget = await fsp2.realpath(target);
|
|
1662
1735
|
const writtenFiles = [];
|
|
1663
1736
|
const deletedFiles = [];
|
|
1664
1737
|
const errors = [];
|
|
@@ -1667,10 +1740,10 @@ var SessionCheckpointCas = class {
|
|
|
1667
1740
|
try {
|
|
1668
1741
|
const output = await this.safeOutputPath(target, realTarget, entry.path);
|
|
1669
1742
|
if (entry.state === "symlink") {
|
|
1670
|
-
if (
|
|
1743
|
+
if (path5.isAbsolute(entry.linkTarget)) {
|
|
1671
1744
|
throw new Error("absolute symlink target refused");
|
|
1672
1745
|
}
|
|
1673
|
-
const resolvedLink =
|
|
1746
|
+
const resolvedLink = path5.resolve(path5.dirname(output), entry.linkTarget);
|
|
1674
1747
|
if (!isInside(target, resolvedLink)) throw new Error("symlink target escapes checkpoint root");
|
|
1675
1748
|
}
|
|
1676
1749
|
prepared.push({
|
|
@@ -1688,24 +1761,24 @@ var SessionCheckpointCas = class {
|
|
|
1688
1761
|
for (const { entry, output, content } of prepared) {
|
|
1689
1762
|
try {
|
|
1690
1763
|
if (entry.state === "absent") {
|
|
1691
|
-
await
|
|
1764
|
+
await fsp2.unlink(output).catch((err) => {
|
|
1692
1765
|
if (err.code !== "ENOENT") throw err;
|
|
1693
1766
|
});
|
|
1694
1767
|
deletedFiles.push(entry.path);
|
|
1695
1768
|
continue;
|
|
1696
1769
|
}
|
|
1697
1770
|
if (entry.state === "symlink") {
|
|
1698
|
-
await
|
|
1771
|
+
await fsp2.unlink(output).catch((err) => {
|
|
1699
1772
|
if (err.code !== "ENOENT") throw err;
|
|
1700
1773
|
});
|
|
1701
|
-
await
|
|
1702
|
-
await
|
|
1774
|
+
await fsp2.mkdir(path5.dirname(output), { recursive: true });
|
|
1775
|
+
await fsp2.symlink(entry.linkTarget, output);
|
|
1703
1776
|
writtenFiles.push(entry.path);
|
|
1704
1777
|
continue;
|
|
1705
1778
|
}
|
|
1706
1779
|
if (!content) throw new Error("CAS blob was not prepared");
|
|
1707
1780
|
await atomicWrite(output, content, { mode: entry.mode });
|
|
1708
|
-
await
|
|
1781
|
+
await fsp2.chmod(output, entry.mode).catch(() => void 0);
|
|
1709
1782
|
writtenFiles.push(entry.path);
|
|
1710
1783
|
} catch (err) {
|
|
1711
1784
|
errors.push(`${entry.path}: ${toErrorMessage(err)}`);
|
|
@@ -1715,48 +1788,48 @@ var SessionCheckpointCas = class {
|
|
|
1715
1788
|
}
|
|
1716
1789
|
objectPath(hash) {
|
|
1717
1790
|
if (!HASH_RE.test(hash)) throw new Error(`Invalid CAS object hash: ${hash}`);
|
|
1718
|
-
return
|
|
1791
|
+
return path5.join(this.rootDir, "objects", hash.slice(0, 2), hash.slice(2));
|
|
1719
1792
|
}
|
|
1720
1793
|
manifestPath(hash) {
|
|
1721
1794
|
if (!HASH_RE.test(hash)) throw new Error(`Invalid checkpoint manifest hash: ${hash}`);
|
|
1722
|
-
return
|
|
1795
|
+
return path5.join(this.rootDir, "manifests", `${hash}.json`);
|
|
1723
1796
|
}
|
|
1724
1797
|
async putBlob(hash, content) {
|
|
1725
1798
|
const target = this.objectPath(hash);
|
|
1726
|
-
await
|
|
1799
|
+
await fsp2.mkdir(path5.dirname(target), { recursive: true });
|
|
1727
1800
|
try {
|
|
1728
|
-
const existing = await
|
|
1801
|
+
const existing = await fsp2.readFile(target);
|
|
1729
1802
|
if (sha256(existing) !== hash) throw new Error(`Corrupt CAS object collision: ${hash}`);
|
|
1730
1803
|
return;
|
|
1731
1804
|
} catch (err) {
|
|
1732
1805
|
if (err.code !== "ENOENT") throw err;
|
|
1733
1806
|
}
|
|
1734
|
-
const temp =
|
|
1735
|
-
|
|
1736
|
-
`.${
|
|
1807
|
+
const temp = path5.join(
|
|
1808
|
+
path5.dirname(target),
|
|
1809
|
+
`.${path5.basename(target)}.${process.pid}.${randomUUID()}.tmp`
|
|
1737
1810
|
);
|
|
1738
1811
|
let handle;
|
|
1739
1812
|
try {
|
|
1740
|
-
handle = await
|
|
1813
|
+
handle = await fsp2.open(temp, "wx", 384);
|
|
1741
1814
|
await handle.writeFile(content);
|
|
1742
1815
|
await handle.sync();
|
|
1743
1816
|
await handle.close();
|
|
1744
1817
|
handle = void 0;
|
|
1745
1818
|
try {
|
|
1746
|
-
await
|
|
1819
|
+
await fsp2.link(temp, target);
|
|
1747
1820
|
} catch (err) {
|
|
1748
1821
|
if (err.code !== "EEXIST") throw err;
|
|
1749
|
-
const existing = await
|
|
1822
|
+
const existing = await fsp2.readFile(target);
|
|
1750
1823
|
if (sha256(existing) !== hash) throw new Error(`Corrupt CAS object collision: ${hash}`);
|
|
1751
1824
|
}
|
|
1752
1825
|
} finally {
|
|
1753
1826
|
await handle?.close().catch(() => void 0);
|
|
1754
|
-
await
|
|
1827
|
+
await fsp2.unlink(temp).catch(() => void 0);
|
|
1755
1828
|
}
|
|
1756
1829
|
}
|
|
1757
1830
|
async putManifest(hash, encoded) {
|
|
1758
1831
|
const target = this.manifestPath(hash);
|
|
1759
|
-
const existing = await
|
|
1832
|
+
const existing = await fsp2.readFile(target).catch(() => null);
|
|
1760
1833
|
if (existing) {
|
|
1761
1834
|
if (sha256(existing) !== hash) throw new Error(`Corrupt checkpoint manifest collision: ${hash}`);
|
|
1762
1835
|
return;
|
|
@@ -1764,12 +1837,12 @@ var SessionCheckpointCas = class {
|
|
|
1764
1837
|
await atomicWrite(target, encoded, { mode: 384 });
|
|
1765
1838
|
}
|
|
1766
1839
|
async readBlob(hash) {
|
|
1767
|
-
const content = await
|
|
1840
|
+
const content = await fsp2.readFile(this.objectPath(hash));
|
|
1768
1841
|
if (sha256(content) !== hash) throw new Error(`CAS blob integrity check failed: ${hash}`);
|
|
1769
1842
|
return content;
|
|
1770
1843
|
}
|
|
1771
1844
|
async loadManifest(hash) {
|
|
1772
|
-
const raw = await
|
|
1845
|
+
const raw = await fsp2.readFile(this.manifestPath(hash));
|
|
1773
1846
|
if (sha256(raw) !== hash) throw new Error(`Checkpoint manifest integrity check failed: ${hash}`);
|
|
1774
1847
|
const parsed = JSON.parse(raw.toString("utf8"));
|
|
1775
1848
|
if (parsed.version !== 1 || typeof parsed.baseHead !== "string" || parsed.coverage !== "git-head-plus-dirty" || !Array.isArray(parsed.entries) || !Array.isArray(parsed.unresolved)) {
|
|
@@ -1794,17 +1867,17 @@ var SessionCheckpointCas = class {
|
|
|
1794
1867
|
async safeOutputPath(target, realTarget, relative6) {
|
|
1795
1868
|
const normalized = normalizeRelative(relative6);
|
|
1796
1869
|
if (!normalized) throw new Error("invalid relative path");
|
|
1797
|
-
const output =
|
|
1870
|
+
const output = path5.resolve(target, ...normalized.split("/"));
|
|
1798
1871
|
if (!isInside(target, output)) throw new Error("path escapes checkpoint target");
|
|
1799
1872
|
let probe = output;
|
|
1800
1873
|
for (; ; ) {
|
|
1801
1874
|
try {
|
|
1802
|
-
const real = await
|
|
1875
|
+
const real = await fsp2.realpath(probe);
|
|
1803
1876
|
if (!isInside(realTarget, real)) throw new Error("path resolves through a symlink outside checkpoint target");
|
|
1804
1877
|
return output;
|
|
1805
1878
|
} catch (err) {
|
|
1806
1879
|
if (err.code !== "ENOENT") throw err;
|
|
1807
|
-
const parent =
|
|
1880
|
+
const parent = path5.dirname(probe);
|
|
1808
1881
|
if (parent === probe) throw err;
|
|
1809
1882
|
probe = parent;
|
|
1810
1883
|
}
|
|
@@ -1859,12 +1932,17 @@ function defaultRunGit(args, cwd) {
|
|
|
1859
1932
|
child.on("close", (code) => resolve11(result(code ?? 1)));
|
|
1860
1933
|
});
|
|
1861
1934
|
}
|
|
1935
|
+
|
|
1936
|
+
// src/storage/session-resume-validation.ts
|
|
1937
|
+
import { createHash as createHash3 } from "node:crypto";
|
|
1938
|
+
import * as fsp3 from "node:fs/promises";
|
|
1939
|
+
import * as path6 from "node:path";
|
|
1862
1940
|
var MAX_REVALIDATE_BYTES = 5 * 1024 * 1024;
|
|
1863
1941
|
var VALIDATION_CONCURRENCY = 8;
|
|
1864
1942
|
var NOTICE_PATH_LIMIT = 20;
|
|
1865
1943
|
function isInside2(root, target) {
|
|
1866
|
-
const relative6 =
|
|
1867
|
-
return relative6 === "" || !relative6.startsWith("..") && !
|
|
1944
|
+
const relative6 = path6.relative(root, target);
|
|
1945
|
+
return relative6 === "" || !relative6.startsWith("..") && !path6.isAbsolute(relative6);
|
|
1868
1946
|
}
|
|
1869
1947
|
function errno(err) {
|
|
1870
1948
|
return err && typeof err === "object" && "code" in err ? String(err.code) : void 0;
|
|
@@ -1875,7 +1953,7 @@ function latestObservations(events, projectRoot) {
|
|
|
1875
1953
|
if (event.type !== "file_observation" || typeof event.path !== "string" || event.path.length === 0 || typeof event.hash !== "string" || !/^[a-f\d]{64}$/i.test(event.hash)) {
|
|
1876
1954
|
continue;
|
|
1877
1955
|
}
|
|
1878
|
-
const normalized =
|
|
1956
|
+
const normalized = path6.resolve(projectRoot, event.path);
|
|
1879
1957
|
latest.set(normalized, {
|
|
1880
1958
|
path: normalized,
|
|
1881
1959
|
hash: event.hash.toLowerCase(),
|
|
@@ -1899,7 +1977,7 @@ async function validateOne(observation, lexicalRoot, realRoot) {
|
|
|
1899
1977
|
}
|
|
1900
1978
|
let realFile;
|
|
1901
1979
|
try {
|
|
1902
|
-
realFile = await
|
|
1980
|
+
realFile = await fsp3.realpath(observation.path);
|
|
1903
1981
|
} catch (err) {
|
|
1904
1982
|
if (errno(err) === "ENOENT") return { ...base, status: "deleted" };
|
|
1905
1983
|
return { ...base, status: "unreadable", detail: toErrorMessage(err) };
|
|
@@ -1912,7 +1990,7 @@ async function validateOne(observation, lexicalRoot, realRoot) {
|
|
|
1912
1990
|
};
|
|
1913
1991
|
}
|
|
1914
1992
|
try {
|
|
1915
|
-
const stat13 = await
|
|
1993
|
+
const stat13 = await fsp3.stat(realFile);
|
|
1916
1994
|
if (!stat13.isFile()) {
|
|
1917
1995
|
return { ...base, status: "unreadable", detail: "Path is no longer a regular file." };
|
|
1918
1996
|
}
|
|
@@ -1923,8 +2001,8 @@ async function validateOne(observation, lexicalRoot, realRoot) {
|
|
|
1923
2001
|
detail: `File now exceeds the ${MAX_REVALIDATE_BYTES}-byte validation limit.`
|
|
1924
2002
|
};
|
|
1925
2003
|
}
|
|
1926
|
-
const content = await
|
|
1927
|
-
const actualHash =
|
|
2004
|
+
const content = await fsp3.readFile(realFile, "utf8");
|
|
2005
|
+
const actualHash = createHash3("sha256").update(content, "utf8").digest("hex");
|
|
1928
2006
|
if (actualHash === observation.hash) return null;
|
|
1929
2007
|
return { ...base, status: "modified", actualHash };
|
|
1930
2008
|
} catch (err) {
|
|
@@ -1933,8 +2011,8 @@ async function validateOne(observation, lexicalRoot, realRoot) {
|
|
|
1933
2011
|
}
|
|
1934
2012
|
}
|
|
1935
2013
|
async function validateResumeFileObservations(events, projectRoot) {
|
|
1936
|
-
const lexicalRoot =
|
|
1937
|
-
const realRoot = await
|
|
2014
|
+
const lexicalRoot = path6.resolve(projectRoot);
|
|
2015
|
+
const realRoot = await fsp3.realpath(lexicalRoot).catch(() => lexicalRoot);
|
|
1938
2016
|
const observations = latestObservations(events, lexicalRoot);
|
|
1939
2017
|
const results = await mapWithConcurrency(
|
|
1940
2018
|
observations,
|
|
@@ -1949,9 +2027,9 @@ async function validateResumeFileObservations(events, projectRoot) {
|
|
|
1949
2027
|
}
|
|
1950
2028
|
function formatResumeValidationNotice(validation, projectRoot) {
|
|
1951
2029
|
if (validation.staleFiles.length === 0) return null;
|
|
1952
|
-
const root =
|
|
2030
|
+
const root = path6.resolve(projectRoot);
|
|
1953
2031
|
const shown = validation.staleFiles.slice(0, NOTICE_PATH_LIMIT).map((entry) => {
|
|
1954
|
-
const relative6 =
|
|
2032
|
+
const relative6 = path6.relative(root, entry.path);
|
|
1955
2033
|
const display = isInside2(root, entry.path) ? relative6 || "." : entry.path;
|
|
1956
2034
|
return `- ${JSON.stringify(display)} [${entry.status}]`;
|
|
1957
2035
|
});
|
|
@@ -2076,9 +2154,9 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
2076
2154
|
static LIST_SCAN_CONCURRENCY = 32;
|
|
2077
2155
|
constructor(opts) {
|
|
2078
2156
|
this.dir = opts.dir;
|
|
2079
|
-
this.projectRoot = opts.projectRoot ?
|
|
2157
|
+
this.projectRoot = opts.projectRoot ? path7.resolve(opts.projectRoot) : void 0;
|
|
2080
2158
|
this.checkpointCas = this.projectRoot ? new SessionCheckpointCas({
|
|
2081
|
-
rootDir:
|
|
2159
|
+
rootDir: path7.join(this.dir, "_cas"),
|
|
2082
2160
|
projectRoot: this.projectRoot
|
|
2083
2161
|
}) : void 0;
|
|
2084
2162
|
this.events = opts.events;
|
|
@@ -2132,17 +2210,17 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
2132
2210
|
}
|
|
2133
2211
|
/** Absolute path to the session index file. */
|
|
2134
2212
|
get indexFile() {
|
|
2135
|
-
return
|
|
2213
|
+
return path7.join(this.dir, "_index.jsonl");
|
|
2136
2214
|
}
|
|
2137
2215
|
/** Join session ID to its absolute path within the store directory. */
|
|
2138
2216
|
sessionPath(id, ext) {
|
|
2139
2217
|
return sessionScopedPath(this.dir, id, ext);
|
|
2140
2218
|
}
|
|
2141
2219
|
shardManifestPath(shardKey) {
|
|
2142
|
-
return shardKey ?
|
|
2220
|
+
return shardKey ? path7.join(this.dir, shardKey, "_manifest.json") : path7.join(this.dir, "_manifest.json");
|
|
2143
2221
|
}
|
|
2144
2222
|
shardKeyForSessionId(id) {
|
|
2145
|
-
const dirName =
|
|
2223
|
+
const dirName = path7.dirname(id);
|
|
2146
2224
|
return dirName === "." ? "" : dirName;
|
|
2147
2225
|
}
|
|
2148
2226
|
invalidateShardManifestBySessionId(id) {
|
|
@@ -2154,7 +2232,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
2154
2232
|
* subdirectory so sessions group naturally by day.
|
|
2155
2233
|
*/
|
|
2156
2234
|
async ensureShardDir(id) {
|
|
2157
|
-
const dirPath =
|
|
2235
|
+
const dirPath = path7.dirname(sessionScopedPath(this.dir, id, ""));
|
|
2158
2236
|
await ensureDir(dirPath);
|
|
2159
2237
|
return dirPath;
|
|
2160
2238
|
}
|
|
@@ -2216,7 +2294,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
2216
2294
|
}
|
|
2217
2295
|
const parentPrefix = parent.events.slice(0, boundary + 1);
|
|
2218
2296
|
const workspaceCheckpoint = targetCheckpoint?.workspaceCheckpoint;
|
|
2219
|
-
const checkpointHash =
|
|
2297
|
+
const checkpointHash = createHash4("sha256").update(parentPrefix.map((event) => JSON.stringify(event)).join("\n") + "\n", "utf8").digest("hex");
|
|
2220
2298
|
const inherited = parentPrefix.filter(inheritsIntoFork);
|
|
2221
2299
|
const writer = await this.create({
|
|
2222
2300
|
id: "",
|
|
@@ -2311,7 +2389,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
2311
2389
|
// Shard directory (sessions/<date>/) — must match create() so the
|
|
2312
2390
|
// .summary.json sidecar lands next to the JSONL instead of the
|
|
2313
2391
|
// sessions root (where summaryFor() would never find it).
|
|
2314
|
-
dir:
|
|
2392
|
+
dir: path7.dirname(file),
|
|
2315
2393
|
filePath: file,
|
|
2316
2394
|
secretScrubber: this.secretScrubber,
|
|
2317
2395
|
checkpointCas: this.checkpointCas,
|
|
@@ -2866,7 +2944,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
2866
2944
|
return entry;
|
|
2867
2945
|
}
|
|
2868
2946
|
async collectSessionFilesInShard(shardKey) {
|
|
2869
|
-
const dir = shardKey ?
|
|
2947
|
+
const dir = shardKey ? path7.join(this.dir, shardKey) : this.dir;
|
|
2870
2948
|
const entries = await this.collectSessionFiles(dir, shardKey);
|
|
2871
2949
|
return shardKey ? entries.filter((entry) => entry.id.startsWith(`${shardKey}/`)) : entries.filter((entry) => !entry.id.includes("/"));
|
|
2872
2950
|
}
|
|
@@ -2889,13 +2967,13 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
2889
2967
|
if (entry.name === "_index.jsonl") continue;
|
|
2890
2968
|
const base = entry.name.replace(/\.jsonl$/, "");
|
|
2891
2969
|
const id = prefix ? `${prefix}/${base}` : base;
|
|
2892
|
-
files.push({ id, filePath:
|
|
2970
|
+
files.push({ id, filePath: path7.join(dir, entry.name) });
|
|
2893
2971
|
}
|
|
2894
2972
|
}
|
|
2895
2973
|
const childFileArrays = await Promise.all(
|
|
2896
2974
|
dirEntries.map((entry) => {
|
|
2897
2975
|
const childPrefix = depth === 0 ? entry.name : `${prefix}/${entry.name}`;
|
|
2898
|
-
return this.collectSessionFiles(
|
|
2976
|
+
return this.collectSessionFiles(path7.join(dir, entry.name), childPrefix, depth + 1);
|
|
2899
2977
|
})
|
|
2900
2978
|
);
|
|
2901
2979
|
return [...childFileArrays.flat(), ...files];
|
|
@@ -2928,7 +3006,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
2928
3006
|
const childIdArrays = await Promise.all(
|
|
2929
3007
|
dirEntries.map((entry) => {
|
|
2930
3008
|
const childPrefix = depth === 0 ? entry.name : `${prefix}/${entry.name}`;
|
|
2931
|
-
return this.collectSessionIds(
|
|
3009
|
+
return this.collectSessionIds(path7.join(dir, entry.name), childPrefix, depth + 1);
|
|
2932
3010
|
})
|
|
2933
3011
|
);
|
|
2934
3012
|
return [...childIdArrays.flat(), ...fileIds];
|
|
@@ -3045,9 +3123,9 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
3045
3123
|
async deleteSession(id) {
|
|
3046
3124
|
const jsonlPath = this.sessionPath(id, ".jsonl");
|
|
3047
3125
|
const summaryPath = this.sessionPath(id, ".summary.json");
|
|
3048
|
-
const shardDir =
|
|
3049
|
-
const base =
|
|
3050
|
-
const sessDir =
|
|
3126
|
+
const shardDir = path7.dirname(jsonlPath);
|
|
3127
|
+
const base = path7.basename(id);
|
|
3128
|
+
const sessDir = path7.join(shardDir, base);
|
|
3051
3129
|
const deletions = [
|
|
3052
3130
|
fsp4.unlink(jsonlPath),
|
|
3053
3131
|
fsp4.unlink(summaryPath),
|
|
@@ -3088,7 +3166,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
3088
3166
|
*/
|
|
3089
3167
|
async readActiveSessionId() {
|
|
3090
3168
|
try {
|
|
3091
|
-
const raw = await fsp4.readFile(
|
|
3169
|
+
const raw = await fsp4.readFile(path7.join(this.dir, "active.json"), "utf8");
|
|
3092
3170
|
const active = JSON.parse(raw);
|
|
3093
3171
|
return active.sessionId ?? null;
|
|
3094
3172
|
} catch {
|
|
@@ -3151,7 +3229,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
3151
3229
|
const activeSessionId = await this.readActiveSessionId();
|
|
3152
3230
|
const isPrunableJsonl = (name) => name.endsWith(".jsonl") && name !== "_index.jsonl" && name !== "_mailbox.jsonl" && !name.endsWith(".replay.jsonl") && !name.endsWith(".audit.jsonl");
|
|
3153
3231
|
const pruneFile = async (dir, name, prefix) => {
|
|
3154
|
-
const jsonlPath =
|
|
3232
|
+
const jsonlPath = path7.join(dir, name);
|
|
3155
3233
|
try {
|
|
3156
3234
|
const stat13 = await fsp4.stat(jsonlPath);
|
|
3157
3235
|
if (stat13.mtimeMs >= cutoff) return;
|
|
@@ -3171,7 +3249,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
3171
3249
|
continue;
|
|
3172
3250
|
}
|
|
3173
3251
|
if (!entry.isDirectory()) continue;
|
|
3174
|
-
const dateDir =
|
|
3252
|
+
const dateDir = path7.join(this.dir, entry.name);
|
|
3175
3253
|
const files = await fsp4.readdir(dateDir, { withFileTypes: true }).catch(() => []);
|
|
3176
3254
|
for (const file of files) {
|
|
3177
3255
|
if (!file.isFile() || !isPrunableJsonl(file.name)) continue;
|
|
@@ -3183,7 +3261,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
3183
3261
|
}
|
|
3184
3262
|
for (const entry of entries) {
|
|
3185
3263
|
if (!entry.isDirectory()) continue;
|
|
3186
|
-
const dateDir =
|
|
3264
|
+
const dateDir = path7.join(this.dir, entry.name);
|
|
3187
3265
|
try {
|
|
3188
3266
|
const remaining = await fsp4.readdir(dateDir);
|
|
3189
3267
|
if (remaining.length === 0) {
|
|
@@ -3305,6 +3383,10 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
3305
3383
|
}
|
|
3306
3384
|
}
|
|
3307
3385
|
};
|
|
3386
|
+
|
|
3387
|
+
// src/storage/queue-store.ts
|
|
3388
|
+
import * as fsp5 from "node:fs/promises";
|
|
3389
|
+
import * as path8 from "node:path";
|
|
3308
3390
|
var QueueStore = class {
|
|
3309
3391
|
file;
|
|
3310
3392
|
// Use `| undefined` (not `?`) so exactOptionalPropertyTypes doesn't
|
|
@@ -3312,7 +3394,7 @@ var QueueStore = class {
|
|
|
3312
3394
|
events;
|
|
3313
3395
|
traceId;
|
|
3314
3396
|
constructor(opts) {
|
|
3315
|
-
this.file =
|
|
3397
|
+
this.file = path8.join(opts.dir, "queue.json");
|
|
3316
3398
|
this.events = opts.events;
|
|
3317
3399
|
this.traceId = opts.traceId;
|
|
3318
3400
|
}
|
|
@@ -3357,7 +3439,7 @@ var QueueStore = class {
|
|
|
3357
3439
|
const t0 = Date.now();
|
|
3358
3440
|
let raw;
|
|
3359
3441
|
try {
|
|
3360
|
-
raw = await
|
|
3442
|
+
raw = await fsp5.readFile(this.file, "utf8");
|
|
3361
3443
|
} catch (err) {
|
|
3362
3444
|
const code = err.code;
|
|
3363
3445
|
if (code === "ENOENT") {
|
|
@@ -3438,7 +3520,7 @@ var QueueStore = class {
|
|
|
3438
3520
|
async clear() {
|
|
3439
3521
|
const t0 = Date.now();
|
|
3440
3522
|
try {
|
|
3441
|
-
await
|
|
3523
|
+
await fsp5.unlink(this.file);
|
|
3442
3524
|
this.events?.emit("storage.write", {
|
|
3443
3525
|
sessionId: this.traceId ?? "~boot~",
|
|
3444
3526
|
store: "queue",
|
|
@@ -3476,6 +3558,11 @@ function isPersistedQueueItem(v) {
|
|
|
3476
3558
|
const o = v;
|
|
3477
3559
|
return typeof o["displayText"] === "string" && Array.isArray(o["blocks"]);
|
|
3478
3560
|
}
|
|
3561
|
+
|
|
3562
|
+
// src/storage/attachment-store.ts
|
|
3563
|
+
import { randomBytes as randomBytes3 } from "node:crypto";
|
|
3564
|
+
import * as fsp6 from "node:fs/promises";
|
|
3565
|
+
import * as path9 from "node:path";
|
|
3479
3566
|
var DEFAULT_SPOOL_THRESHOLD = 256 * 1024;
|
|
3480
3567
|
var PLACEHOLDER_RE = /\[(pasted|image|file) #(\d+)[^\]]*\]|\[file:([^\]]+)\]/g;
|
|
3481
3568
|
var DefaultAttachmentStore = class {
|
|
@@ -3490,13 +3577,13 @@ var DefaultAttachmentStore = class {
|
|
|
3490
3577
|
}
|
|
3491
3578
|
async add(input) {
|
|
3492
3579
|
const seq = ++this.nextSeq[input.kind];
|
|
3493
|
-
const id = `${kindPrefix(input.kind)}-${seq}-${
|
|
3580
|
+
const id = `${kindPrefix(input.kind)}-${seq}-${randomBytes3(3).toString("hex")}`;
|
|
3494
3581
|
const bytes = Buffer.byteLength(input.data, input.kind === "image" ? "base64" : "utf8");
|
|
3495
3582
|
let spooledPath;
|
|
3496
3583
|
let data = input.data;
|
|
3497
3584
|
if (this.spoolDir && bytes >= this.spoolThreshold) {
|
|
3498
|
-
await
|
|
3499
|
-
spooledPath =
|
|
3585
|
+
await fsp6.mkdir(this.spoolDir, { recursive: true });
|
|
3586
|
+
spooledPath = path9.join(this.spoolDir, `${id}.bin`);
|
|
3500
3587
|
await atomicWrite(spooledPath, input.data, {
|
|
3501
3588
|
encoding: input.kind === "image" ? "base64" : "utf8"
|
|
3502
3589
|
});
|
|
@@ -3558,7 +3645,7 @@ var DefaultAttachmentStore = class {
|
|
|
3558
3645
|
for (const att of this.items.values()) {
|
|
3559
3646
|
if (att.path) toDelete.push(att.path);
|
|
3560
3647
|
}
|
|
3561
|
-
await Promise.all(toDelete.map((p) =>
|
|
3648
|
+
await Promise.all(toDelete.map((p) => fsp6.unlink(p).catch(() => void 0)));
|
|
3562
3649
|
}
|
|
3563
3650
|
this.items.clear();
|
|
3564
3651
|
this.refs.length = 0;
|
|
@@ -3566,7 +3653,7 @@ var DefaultAttachmentStore = class {
|
|
|
3566
3653
|
}
|
|
3567
3654
|
async toBlock(att) {
|
|
3568
3655
|
if (att.kind === "image") {
|
|
3569
|
-
const data = att.data ?? (att.path ? await
|
|
3656
|
+
const data = att.data ?? (att.path ? await fsp6.readFile(att.path, { encoding: "base64" }) : "");
|
|
3570
3657
|
return {
|
|
3571
3658
|
type: "image",
|
|
3572
3659
|
source: {
|
|
@@ -3576,7 +3663,7 @@ var DefaultAttachmentStore = class {
|
|
|
3576
3663
|
}
|
|
3577
3664
|
};
|
|
3578
3665
|
}
|
|
3579
|
-
const raw = att.data ?? (att.path ? await
|
|
3666
|
+
const raw = att.data ?? (att.path ? await fsp6.readFile(att.path, "utf8") : "");
|
|
3580
3667
|
const label = att.meta.filename ? `<file path="${att.meta.filename}">` : "<pasted>";
|
|
3581
3668
|
const close = att.meta.filename ? "</file>" : "</pasted>";
|
|
3582
3669
|
return { type: "text", text: `${label}
|
|
@@ -3614,6 +3701,11 @@ function mergeAdjacentText(blocks) {
|
|
|
3614
3701
|
return out;
|
|
3615
3702
|
}
|
|
3616
3703
|
|
|
3704
|
+
// src/storage/memory-backend.ts
|
|
3705
|
+
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
3706
|
+
import * as fs2 from "node:fs/promises";
|
|
3707
|
+
import * as path10 from "node:path";
|
|
3708
|
+
|
|
3617
3709
|
// src/types/memory.ts
|
|
3618
3710
|
var MEMORY_TYPE_LABELS = {
|
|
3619
3711
|
fact: "Fact",
|
|
@@ -3779,7 +3871,7 @@ var FileMemoryBackend = class {
|
|
|
3779
3871
|
}
|
|
3780
3872
|
async getMtime(file) {
|
|
3781
3873
|
try {
|
|
3782
|
-
const stat13 = await
|
|
3874
|
+
const stat13 = await fs2.stat(file);
|
|
3783
3875
|
return stat13.mtimeMs;
|
|
3784
3876
|
} catch {
|
|
3785
3877
|
return 0;
|
|
@@ -3826,13 +3918,13 @@ var FileMemoryBackend = class {
|
|
|
3826
3918
|
}
|
|
3827
3919
|
async remember(scope, entry, filePath) {
|
|
3828
3920
|
const file = this.resolveFile(filePath, scope);
|
|
3829
|
-
await ensureDir(
|
|
3921
|
+
await ensureDir(path10.dirname(file));
|
|
3830
3922
|
let existing = "";
|
|
3831
3923
|
try {
|
|
3832
|
-
existing = await
|
|
3924
|
+
existing = await fs2.readFile(file, "utf8");
|
|
3833
3925
|
} catch {
|
|
3834
3926
|
}
|
|
3835
|
-
const id = `mem_${Date.now()}_${
|
|
3927
|
+
const id = `mem_${Date.now()}_${randomUUID2().slice(0, 8)}`;
|
|
3836
3928
|
const meta = formatMetadata(entry);
|
|
3837
3929
|
const line = `
|
|
3838
3930
|
- [${entry.ts}] ${id}${meta} ${entry.text.replace(/\n/g, " ")}
|
|
@@ -3847,7 +3939,7 @@ ${line}`;
|
|
|
3847
3939
|
return withFileLock(file, async () => {
|
|
3848
3940
|
let existing;
|
|
3849
3941
|
try {
|
|
3850
|
-
existing = await
|
|
3942
|
+
existing = await fs2.readFile(file, "utf8");
|
|
3851
3943
|
} catch {
|
|
3852
3944
|
return 0;
|
|
3853
3945
|
}
|
|
@@ -3884,7 +3976,7 @@ ${line}`;
|
|
|
3884
3976
|
async readAll(scope, filePath) {
|
|
3885
3977
|
const file = this.resolveFile(filePath, scope);
|
|
3886
3978
|
try {
|
|
3887
|
-
return await
|
|
3979
|
+
return await fs2.readFile(file, "utf8");
|
|
3888
3980
|
} catch {
|
|
3889
3981
|
return "";
|
|
3890
3982
|
}
|
|
@@ -3908,7 +4000,7 @@ ${line}`;
|
|
|
3908
4000
|
const file = this.resolveFile(filePath, scope);
|
|
3909
4001
|
let existing;
|
|
3910
4002
|
try {
|
|
3911
|
-
existing = await
|
|
4003
|
+
existing = await fs2.readFile(file, "utf8");
|
|
3912
4004
|
} catch {
|
|
3913
4005
|
return 0;
|
|
3914
4006
|
}
|
|
@@ -3928,7 +4020,7 @@ ${line}`;
|
|
|
3928
4020
|
const next = lines.join("\n");
|
|
3929
4021
|
const backup = `${file}.bak.${Date.now()}`;
|
|
3930
4022
|
try {
|
|
3931
|
-
await
|
|
4023
|
+
await fs2.copyFile(file, backup);
|
|
3932
4024
|
await pruneConsolidateBackups(file);
|
|
3933
4025
|
} catch {
|
|
3934
4026
|
}
|
|
@@ -3942,14 +4034,14 @@ ${line}`;
|
|
|
3942
4034
|
}
|
|
3943
4035
|
};
|
|
3944
4036
|
async function pruneConsolidateBackups(file) {
|
|
3945
|
-
const dir =
|
|
3946
|
-
const base =
|
|
4037
|
+
const dir = path10.dirname(file);
|
|
4038
|
+
const base = path10.basename(file);
|
|
3947
4039
|
const prefix = `${base}.bak.`;
|
|
3948
|
-
const backups = (await
|
|
4040
|
+
const backups = (await fs2.readdir(dir)).filter((name) => name.startsWith(prefix)).sort().reverse();
|
|
3949
4041
|
await Promise.all(
|
|
3950
4042
|
backups.slice(MAX_MEMORY_CONSOLIDATE_BACKUPS).map(async (name) => {
|
|
3951
4043
|
try {
|
|
3952
|
-
await
|
|
4044
|
+
await fs2.unlink(path10.join(dir, name));
|
|
3953
4045
|
} catch {
|
|
3954
4046
|
}
|
|
3955
4047
|
})
|
|
@@ -4309,6 +4401,10 @@ ${body.trim()}`);
|
|
|
4309
4401
|
score += 1;
|
|
4310
4402
|
reasons.push("preference");
|
|
4311
4403
|
break;
|
|
4404
|
+
case "reference":
|
|
4405
|
+
break;
|
|
4406
|
+
case "fact":
|
|
4407
|
+
break;
|
|
4312
4408
|
}
|
|
4313
4409
|
const ageDays = (now - new Date(entry.ts).getTime()) / (1e3 * 60 * 60 * 24);
|
|
4314
4410
|
if (ageDays < 1) score += 1;
|
|
@@ -4516,9 +4612,9 @@ ${body.trim()}`);
|
|
|
4516
4612
|
if (!this.persistBackup || scope === "project-agents") return;
|
|
4517
4613
|
try {
|
|
4518
4614
|
const content = await this.backend.readAll(scope, this.files[scope]);
|
|
4519
|
-
const { writeFile:
|
|
4520
|
-
await
|
|
4521
|
-
await
|
|
4615
|
+
const { writeFile: writeFile7, mkdir: mkdir7 } = await import("node:fs/promises");
|
|
4616
|
+
await mkdir7(this.backupDir, { recursive: true });
|
|
4617
|
+
await writeFile7(`${this.backupDir}/${scope}.md`, content, "utf8");
|
|
4522
4618
|
} catch {
|
|
4523
4619
|
}
|
|
4524
4620
|
}
|
|
@@ -4533,6 +4629,9 @@ function labelOf(scope) {
|
|
|
4533
4629
|
return "User memory";
|
|
4534
4630
|
}
|
|
4535
4631
|
}
|
|
4632
|
+
|
|
4633
|
+
// src/storage/memory-graph-backend.ts
|
|
4634
|
+
import * as fs3 from "node:fs/promises";
|
|
4536
4635
|
var GraphMemoryBackend = class _GraphMemoryBackend {
|
|
4537
4636
|
kind = "graph";
|
|
4538
4637
|
file;
|
|
@@ -4584,7 +4683,8 @@ var GraphMemoryBackend = class _GraphMemoryBackend {
|
|
|
4584
4683
|
priority: entry.priority
|
|
4585
4684
|
});
|
|
4586
4685
|
this.indexNode(nodeId, entry);
|
|
4587
|
-
const
|
|
4686
|
+
const SIMILARITY_WINDOW = 100;
|
|
4687
|
+
const recentNodes = [...this.nodes.values()].slice(-SIMILARITY_WINDOW);
|
|
4588
4688
|
for (const other of recentNodes) {
|
|
4589
4689
|
if (other.id === nodeId) continue;
|
|
4590
4690
|
const sim = wordOverlap(entry.text, other.entry.text);
|
|
@@ -4699,7 +4799,7 @@ var GraphMemoryBackend = class _GraphMemoryBackend {
|
|
|
4699
4799
|
this.loadedScope = scope;
|
|
4700
4800
|
this.loaded = true;
|
|
4701
4801
|
try {
|
|
4702
|
-
await
|
|
4802
|
+
await fs3.unlink(this.graphFile);
|
|
4703
4803
|
} catch {
|
|
4704
4804
|
}
|
|
4705
4805
|
}
|
|
@@ -4739,7 +4839,7 @@ var GraphMemoryBackend = class _GraphMemoryBackend {
|
|
|
4739
4839
|
async loadGraph(scope) {
|
|
4740
4840
|
if (this.loaded && this.loadedScope === scope) return;
|
|
4741
4841
|
try {
|
|
4742
|
-
const raw = await
|
|
4842
|
+
const raw = await fs3.readFile(this.graphFile, "utf8");
|
|
4743
4843
|
const data = JSON.parse(raw);
|
|
4744
4844
|
this.nodes = new Map(data.nodes);
|
|
4745
4845
|
this.edges = data.edges;
|
|
@@ -4761,10 +4861,10 @@ var GraphMemoryBackend = class _GraphMemoryBackend {
|
|
|
4761
4861
|
edges: this.edges
|
|
4762
4862
|
};
|
|
4763
4863
|
const dir = this.graphFile.substring(0, this.graphFile.lastIndexOf("/"));
|
|
4764
|
-
await
|
|
4864
|
+
await fs3.mkdir(dir, { recursive: true });
|
|
4765
4865
|
const tmp = `${this.graphFile}.tmp`;
|
|
4766
|
-
await
|
|
4767
|
-
await
|
|
4866
|
+
await fs3.writeFile(tmp, JSON.stringify(data));
|
|
4867
|
+
await fs3.rename(tmp, this.graphFile);
|
|
4768
4868
|
} catch {
|
|
4769
4869
|
}
|
|
4770
4870
|
}
|
|
@@ -4880,6 +4980,11 @@ function simpleHash(s) {
|
|
|
4880
4980
|
}
|
|
4881
4981
|
return Math.abs(h).toString(36);
|
|
4882
4982
|
}
|
|
4983
|
+
|
|
4984
|
+
// src/utils/instruction-file.ts
|
|
4985
|
+
import { readFileSync, statSync } from "node:fs";
|
|
4986
|
+
import * as path11 from "node:path";
|
|
4987
|
+
import { fileURLToPath } from "node:url";
|
|
4883
4988
|
var textCache = /* @__PURE__ */ new Map();
|
|
4884
4989
|
var rootCandidates;
|
|
4885
4990
|
function readBundledInstructionText(relativePath) {
|
|
@@ -4888,7 +4993,7 @@ function readBundledInstructionText(relativePath) {
|
|
|
4888
4993
|
let resolved = "";
|
|
4889
4994
|
for (const root of instructionRootCandidates()) {
|
|
4890
4995
|
try {
|
|
4891
|
-
resolved = readFileSync(
|
|
4996
|
+
resolved = readFileSync(path11.join(root, relativePath), "utf8").trimEnd();
|
|
4892
4997
|
break;
|
|
4893
4998
|
} catch {
|
|
4894
4999
|
}
|
|
@@ -4904,11 +5009,11 @@ function renderInstructionTemplate(template, values) {
|
|
|
4904
5009
|
}
|
|
4905
5010
|
function instructionRootCandidates() {
|
|
4906
5011
|
if (rootCandidates !== void 0) return rootCandidates;
|
|
4907
|
-
const here =
|
|
5012
|
+
const here = path11.dirname(fileURLToPath(import.meta.url));
|
|
4908
5013
|
const candidates = [
|
|
4909
|
-
|
|
4910
|
-
|
|
4911
|
-
|
|
5014
|
+
path11.resolve(here, "../../instructions"),
|
|
5015
|
+
path11.resolve(here, "../instructions"),
|
|
5016
|
+
path11.resolve(here, "instructions")
|
|
4912
5017
|
];
|
|
4913
5018
|
rootCandidates = candidates.sort((a, b) => Number(!isDirectory(a)) - Number(!isDirectory(b)));
|
|
4914
5019
|
return rootCandidates;
|
|
@@ -5104,14 +5209,13 @@ function deepFreeze(obj) {
|
|
|
5104
5209
|
}
|
|
5105
5210
|
return Object.freeze(obj);
|
|
5106
5211
|
}
|
|
5107
|
-
|
|
5108
|
-
|
|
5109
|
-
|
|
5110
|
-
|
|
5111
|
-
|
|
5112
|
-
|
|
5113
|
-
|
|
5114
|
-
KEK_MAGIC.length + 1 + KEK_SALT_BYTES + IV_BYTES + TAG_BYTES + KEY_BYTES;
|
|
5212
|
+
|
|
5213
|
+
// src/storage/provider-config-watcher.ts
|
|
5214
|
+
import * as syncFs from "node:fs";
|
|
5215
|
+
import * as fs4 from "node:fs/promises";
|
|
5216
|
+
import * as path12 from "node:path";
|
|
5217
|
+
|
|
5218
|
+
// src/security/config-secrets.ts
|
|
5115
5219
|
function decryptConfigSecrets(cfg, vault, opts) {
|
|
5116
5220
|
const warn = opts?.warn ?? ((msg) => console.warn(msg));
|
|
5117
5221
|
return walk(cfg, vault, (v, key) => {
|
|
@@ -5155,7 +5259,7 @@ function isSecretField(name) {
|
|
|
5155
5259
|
async function readProviderSnapshot(configPath, vault, warn) {
|
|
5156
5260
|
let raw;
|
|
5157
5261
|
try {
|
|
5158
|
-
raw = await
|
|
5262
|
+
raw = await fs4.readFile(configPath, "utf8");
|
|
5159
5263
|
} catch (err) {
|
|
5160
5264
|
if (err.code !== "ENOENT") {
|
|
5161
5265
|
warn?.(`Could not read ${configPath}: ${err.message}`);
|
|
@@ -5190,7 +5294,7 @@ function serializeSnapshot(s) {
|
|
|
5190
5294
|
function watchProviderConfig(configPath, vault, onChange, opts = {}) {
|
|
5191
5295
|
const debounceMs = opts.debounceMs ?? 200;
|
|
5192
5296
|
const warn = opts.warn;
|
|
5193
|
-
const base =
|
|
5297
|
+
const base = path12.basename(configPath);
|
|
5194
5298
|
let timer;
|
|
5195
5299
|
let closed = false;
|
|
5196
5300
|
let lastSerialized;
|
|
@@ -5201,7 +5305,7 @@ function watchProviderConfig(configPath, vault, onChange, opts = {}) {
|
|
|
5201
5305
|
});
|
|
5202
5306
|
let watcher;
|
|
5203
5307
|
try {
|
|
5204
|
-
watcher = syncFs.watch(
|
|
5308
|
+
watcher = syncFs.watch(path12.dirname(configPath), { recursive: false });
|
|
5205
5309
|
} catch (err) {
|
|
5206
5310
|
warn?.(`Provider config watcher could not start: ${err.message}`);
|
|
5207
5311
|
return { close: () => {
|
|
@@ -5243,6 +5347,10 @@ function watchProviderConfig(configPath, vault, onChange, opts = {}) {
|
|
|
5243
5347
|
};
|
|
5244
5348
|
}
|
|
5245
5349
|
|
|
5350
|
+
// src/storage/config-loader.ts
|
|
5351
|
+
import * as fs5 from "node:fs/promises";
|
|
5352
|
+
import * as path13 from "node:path";
|
|
5353
|
+
|
|
5246
5354
|
// src/types/config.ts
|
|
5247
5355
|
var DEFAULT_TUI_THINKING_WORD = "thinking";
|
|
5248
5356
|
|
|
@@ -5381,12 +5489,38 @@ var BEHAVIOR_DEFAULTS = {
|
|
|
5381
5489
|
tokenSavingMode: "off",
|
|
5382
5490
|
allowOutsideProjectRoot: true
|
|
5383
5491
|
},
|
|
5492
|
+
superMemory: {
|
|
5493
|
+
enabled: true,
|
|
5494
|
+
storage: {
|
|
5495
|
+
projectLocal: true,
|
|
5496
|
+
directory: ".wrongstack/memories"
|
|
5497
|
+
},
|
|
5498
|
+
inject: {
|
|
5499
|
+
turnContext: true,
|
|
5500
|
+
toolResults: true,
|
|
5501
|
+
maxHintsPerTool: 4,
|
|
5502
|
+
maxCharsPerTool: 1200,
|
|
5503
|
+
maxTurnMemories: 8,
|
|
5504
|
+
maxCharsPerTurn: 2400,
|
|
5505
|
+
minScore: 0.65,
|
|
5506
|
+
repeatCooldownMs: 30 * 6e4
|
|
5507
|
+
},
|
|
5508
|
+
hygiene: {
|
|
5509
|
+
autoAfterSession: true,
|
|
5510
|
+
autoOnFileChange: true,
|
|
5511
|
+
retentionDays: 90,
|
|
5512
|
+
archiveLowConfidenceAfterDays: 30
|
|
5513
|
+
},
|
|
5514
|
+
embeddings: {
|
|
5515
|
+
enabled: false
|
|
5516
|
+
}
|
|
5517
|
+
},
|
|
5384
5518
|
skills: { readClaudeSkills: true },
|
|
5385
5519
|
mcpServers: {},
|
|
5386
5520
|
fallbackAuto: true,
|
|
5387
5521
|
maxConcurrent: 4,
|
|
5388
|
-
// YOLO on by default: auto-approve
|
|
5389
|
-
// prompt.
|
|
5522
|
+
// YOLO on by default: auto-approve non-denied tool calls without a per-call
|
|
5523
|
+
// prompt. Users
|
|
5390
5524
|
// who want the per-call prompts set `yolo: false`. Existing installs whose
|
|
5391
5525
|
// config lacks this key pick it up via fillMissingDefaults; an explicit
|
|
5392
5526
|
// `false` is preserved by the deep-merge (opt-out respected).
|
|
@@ -5405,8 +5539,8 @@ var BEHAVIOR_DEFAULTS = {
|
|
|
5405
5539
|
autonomy: {
|
|
5406
5540
|
// 'auto' by default: the agent self-drives (picks the top next-step after
|
|
5407
5541
|
// each turn). This is a startup default, not a runtime flip — the
|
|
5408
|
-
// autoProceedMaxIterations cap + autoProceedDelayMs cooldown +
|
|
5409
|
-
//
|
|
5542
|
+
// autoProceedMaxIterations cap + autoProceedDelayMs cooldown + Ctrl+C /
|
|
5543
|
+
// [GOAL_COMPLETE] stops remain in force. Explicit 'off'
|
|
5410
5544
|
// in a config file is preserved (opt-out respected).
|
|
5411
5545
|
defaultMode: "auto",
|
|
5412
5546
|
autoProceedDelayMs: DEFAULT_AUTONOMY_CONFIG.autoProceedDelayMs,
|
|
@@ -5521,6 +5655,7 @@ var IN_PROJECT_ALLOWED_KEYS = /* @__PURE__ */ new Set([
|
|
|
5521
5655
|
"context",
|
|
5522
5656
|
"tools",
|
|
5523
5657
|
"features",
|
|
5658
|
+
"superMemory",
|
|
5524
5659
|
"skills",
|
|
5525
5660
|
"autonomy",
|
|
5526
5661
|
"indexing",
|
|
@@ -5560,6 +5695,10 @@ var KNOWN_DENIED_IN_PROJECT = [
|
|
|
5560
5695
|
{
|
|
5561
5696
|
key: "fleet",
|
|
5562
5697
|
reason: "Fleet supervision knobs: a repo-committed config could enable autonomous subagent spawning/steering/termination and mailbox traffic on the victim machine."
|
|
5698
|
+
},
|
|
5699
|
+
{
|
|
5700
|
+
key: "git",
|
|
5701
|
+
reason: "Carries git.identity (GIT_AUTHOR_*/GIT_COMMITTER_* injection): a repo-committed config could spoof the author identity written into the victim's commit history (impersonation)."
|
|
5563
5702
|
}
|
|
5564
5703
|
];
|
|
5565
5704
|
var KNOWN_CONFIG_TOP_LEVEL_KEYS = /* @__PURE__ */ new Set([
|
|
@@ -5585,6 +5724,7 @@ var KNOWN_CONFIG_TOP_LEVEL_KEYS = /* @__PURE__ */ new Set([
|
|
|
5585
5724
|
"plugins",
|
|
5586
5725
|
"log",
|
|
5587
5726
|
"features",
|
|
5727
|
+
"superMemory",
|
|
5588
5728
|
"skills",
|
|
5589
5729
|
"yolo",
|
|
5590
5730
|
"nextPrediction",
|
|
@@ -5603,7 +5743,8 @@ var KNOWN_CONFIG_TOP_LEVEL_KEYS = /* @__PURE__ */ new Set([
|
|
|
5603
5743
|
"sync",
|
|
5604
5744
|
"extensions",
|
|
5605
5745
|
"acp",
|
|
5606
|
-
"fleet"
|
|
5746
|
+
"fleet",
|
|
5747
|
+
"git"
|
|
5607
5748
|
]);
|
|
5608
5749
|
function assertInProjectAllowListComplete() {
|
|
5609
5750
|
const missingFromBoth = [];
|
|
@@ -5696,6 +5837,19 @@ function stripUnsafeInProjectFields(inProject, sourcePath, warn = (msg) => conso
|
|
|
5696
5837
|
out["skills"] = clonedSkills;
|
|
5697
5838
|
}
|
|
5698
5839
|
}
|
|
5840
|
+
const outSuperMemory = out["superMemory"];
|
|
5841
|
+
if (outSuperMemory && typeof outSuperMemory === "object") {
|
|
5842
|
+
const storage = outSuperMemory["storage"];
|
|
5843
|
+
if (storage && typeof storage === "object" && "directory" in storage) {
|
|
5844
|
+
const clonedStorage = { ...storage };
|
|
5845
|
+
delete clonedStorage["directory"];
|
|
5846
|
+
out["superMemory"] = {
|
|
5847
|
+
...outSuperMemory,
|
|
5848
|
+
storage: clonedStorage
|
|
5849
|
+
};
|
|
5850
|
+
stripped.push("superMemory.storage.directory");
|
|
5851
|
+
}
|
|
5852
|
+
}
|
|
5699
5853
|
if (stripped.length > 0) {
|
|
5700
5854
|
warn(
|
|
5701
5855
|
JSON.stringify({
|
|
@@ -5711,8 +5865,8 @@ function stripUnsafeInProjectFields(inProject, sourcePath, warn = (msg) => conso
|
|
|
5711
5865
|
return out;
|
|
5712
5866
|
}
|
|
5713
5867
|
function samePath(a, b) {
|
|
5714
|
-
let ra =
|
|
5715
|
-
let rb =
|
|
5868
|
+
let ra = path13.resolve(a);
|
|
5869
|
+
let rb = path13.resolve(b);
|
|
5716
5870
|
if (process.platform === "win32" || process.platform === "darwin") {
|
|
5717
5871
|
ra = ra.toLowerCase();
|
|
5718
5872
|
rb = rb.toLowerCase();
|
|
@@ -5814,7 +5968,7 @@ var DefaultConfigLoader = class {
|
|
|
5814
5968
|
}
|
|
5815
5969
|
}
|
|
5816
5970
|
this.validateBehavior(cfg);
|
|
5817
|
-
if (this.strict) {
|
|
5971
|
+
if (this.strict && !opts.skipIdentityValidation) {
|
|
5818
5972
|
this.validateIdentity(cfg);
|
|
5819
5973
|
}
|
|
5820
5974
|
return Object.freeze(cfg);
|
|
@@ -5826,7 +5980,7 @@ var DefaultConfigLoader = class {
|
|
|
5826
5980
|
await withFileLock(fp, async () => {
|
|
5827
5981
|
let parsed;
|
|
5828
5982
|
try {
|
|
5829
|
-
const raw = await
|
|
5983
|
+
const raw = await fs5.readFile(fp, "utf8");
|
|
5830
5984
|
const result = safeParse(raw);
|
|
5831
5985
|
if (!result.ok || !isPlainRecord(result.value)) {
|
|
5832
5986
|
return;
|
|
@@ -5945,7 +6099,7 @@ var DefaultConfigLoader = class {
|
|
|
5945
6099
|
const fp = this.paths.syncConfig;
|
|
5946
6100
|
const t0 = Date.now();
|
|
5947
6101
|
try {
|
|
5948
|
-
const raw = await
|
|
6102
|
+
const raw = await fs5.readFile(fp, "utf8");
|
|
5949
6103
|
const parsed = safeParse(raw);
|
|
5950
6104
|
if (!parsed.ok || !parsed.value) {
|
|
5951
6105
|
this.events?.emit("storage.read", {
|
|
@@ -6011,7 +6165,7 @@ var DefaultConfigLoader = class {
|
|
|
6011
6165
|
const t0 = Date.now();
|
|
6012
6166
|
let mtimeMs = null;
|
|
6013
6167
|
try {
|
|
6014
|
-
const stat13 = await
|
|
6168
|
+
const stat13 = await fs5.stat(file);
|
|
6015
6169
|
mtimeMs = stat13.mtimeMs;
|
|
6016
6170
|
const cached = this.jsonCache.get(file);
|
|
6017
6171
|
if (cached && cached.mtimeMs === mtimeMs) {
|
|
@@ -6045,7 +6199,7 @@ var DefaultConfigLoader = class {
|
|
|
6045
6199
|
}
|
|
6046
6200
|
let raw;
|
|
6047
6201
|
try {
|
|
6048
|
-
raw = await
|
|
6202
|
+
raw = await fs5.readFile(file, "utf8");
|
|
6049
6203
|
} catch (err) {
|
|
6050
6204
|
if (err.code !== "ENOENT") {
|
|
6051
6205
|
this.events?.emit("storage.read", {
|
|
@@ -6212,6 +6366,11 @@ function runConfigMigrations(input, targetVersion, migrations) {
|
|
|
6212
6366
|
return { config: current, applied, shouldPersist };
|
|
6213
6367
|
}
|
|
6214
6368
|
var DEFAULT_CONFIG_MIGRATIONS = [];
|
|
6369
|
+
|
|
6370
|
+
// src/storage/recovery-lock.ts
|
|
6371
|
+
import * as fsp7 from "node:fs/promises";
|
|
6372
|
+
import * as os2 from "node:os";
|
|
6373
|
+
import * as path14 from "node:path";
|
|
6215
6374
|
var LOCK_FILE = "active.json";
|
|
6216
6375
|
var DEFAULT_MAX_AGE_MS = 24 * 60 * 60 * 1e3;
|
|
6217
6376
|
var RecoveryLock = class {
|
|
@@ -6222,9 +6381,9 @@ var RecoveryLock = class {
|
|
|
6222
6381
|
sessionStore;
|
|
6223
6382
|
probe;
|
|
6224
6383
|
constructor(opts) {
|
|
6225
|
-
this.file =
|
|
6384
|
+
this.file = path14.join(opts.dir, LOCK_FILE);
|
|
6226
6385
|
this.pid = opts.pid ?? process.pid;
|
|
6227
|
-
this.hostname = opts.hostname ??
|
|
6386
|
+
this.hostname = opts.hostname ?? os2.hostname();
|
|
6228
6387
|
this.maxAgeMs = opts.maxAgeMs ?? DEFAULT_MAX_AGE_MS;
|
|
6229
6388
|
this.sessionStore = opts.sessionStore;
|
|
6230
6389
|
this.probe = opts.isPidAlive ?? defaultIsPidAlive;
|
|
@@ -6283,7 +6442,7 @@ var RecoveryLock = class {
|
|
|
6283
6442
|
* null return before calling this.
|
|
6284
6443
|
*/
|
|
6285
6444
|
async write(sessionId) {
|
|
6286
|
-
await ensureDir(
|
|
6445
|
+
await ensureDir(path14.dirname(this.file));
|
|
6287
6446
|
const lock = {
|
|
6288
6447
|
v: 1,
|
|
6289
6448
|
sessionId,
|
|
@@ -6292,7 +6451,7 @@ var RecoveryLock = class {
|
|
|
6292
6451
|
startedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
6293
6452
|
};
|
|
6294
6453
|
try {
|
|
6295
|
-
await
|
|
6454
|
+
await fsp7.writeFile(this.file, JSON.stringify(lock), { flag: "wx", mode: 384 });
|
|
6296
6455
|
} catch (err) {
|
|
6297
6456
|
const code = err.code;
|
|
6298
6457
|
if (code === "EEXIST") {
|
|
@@ -6308,7 +6467,7 @@ var RecoveryLock = class {
|
|
|
6308
6467
|
*/
|
|
6309
6468
|
async clear() {
|
|
6310
6469
|
try {
|
|
6311
|
-
await
|
|
6470
|
+
await fsp7.unlink(this.file);
|
|
6312
6471
|
} catch (err) {
|
|
6313
6472
|
const code = err.code;
|
|
6314
6473
|
if (code === "ENOENT") return;
|
|
@@ -6318,7 +6477,7 @@ var RecoveryLock = class {
|
|
|
6318
6477
|
async readLock() {
|
|
6319
6478
|
let raw;
|
|
6320
6479
|
try {
|
|
6321
|
-
raw = await
|
|
6480
|
+
raw = await fsp7.readFile(this.file, "utf8");
|
|
6322
6481
|
} catch (err) {
|
|
6323
6482
|
const code = err.code;
|
|
6324
6483
|
if (code === "ENOENT") return null;
|
|
@@ -6349,6 +6508,9 @@ function defaultIsPidAlive(pid) {
|
|
|
6349
6508
|
return false;
|
|
6350
6509
|
}
|
|
6351
6510
|
}
|
|
6511
|
+
|
|
6512
|
+
// src/storage/session-reader.ts
|
|
6513
|
+
import * as fs6 from "node:fs/promises";
|
|
6352
6514
|
var DefaultSessionReader = class _DefaultSessionReader {
|
|
6353
6515
|
store;
|
|
6354
6516
|
eventCache = /* @__PURE__ */ new Map();
|
|
@@ -6366,7 +6528,7 @@ var DefaultSessionReader = class _DefaultSessionReader {
|
|
|
6366
6528
|
const sessionPath = sessionScopedPath(rootDir, sessionId, ".jsonl");
|
|
6367
6529
|
let mtimeMs = null;
|
|
6368
6530
|
try {
|
|
6369
|
-
const stat13 = await
|
|
6531
|
+
const stat13 = await fs6.stat(sessionPath);
|
|
6370
6532
|
mtimeMs = stat13.mtimeMs;
|
|
6371
6533
|
} catch {
|
|
6372
6534
|
this.eventCache.delete(sessionId);
|
|
@@ -6686,6 +6848,8 @@ function renderMarkdown(meta, events) {
|
|
|
6686
6848
|
lines.push("");
|
|
6687
6849
|
break;
|
|
6688
6850
|
}
|
|
6851
|
+
default:
|
|
6852
|
+
break;
|
|
6689
6853
|
}
|
|
6690
6854
|
}
|
|
6691
6855
|
return lines.join("\n");
|
|
@@ -6719,10 +6883,16 @@ function renderPlainText(meta, events) {
|
|
|
6719
6883
|
case "error":
|
|
6720
6884
|
lines.push(`[${e.ts}] ERROR (${e.phase}): ${e.message}`);
|
|
6721
6885
|
break;
|
|
6886
|
+
default:
|
|
6887
|
+
break;
|
|
6722
6888
|
}
|
|
6723
6889
|
}
|
|
6724
6890
|
return lines.join("\n");
|
|
6725
6891
|
}
|
|
6892
|
+
|
|
6893
|
+
// src/storage/annotations-store.ts
|
|
6894
|
+
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
6895
|
+
import * as fs7 from "node:fs/promises";
|
|
6726
6896
|
var FILE_VERSION = 1;
|
|
6727
6897
|
var MAX_TEXT_LENGTH = 2e3;
|
|
6728
6898
|
var MAX_ANNOTATIONS = 1e3;
|
|
@@ -6730,12 +6900,14 @@ var AnnotationsStore = class {
|
|
|
6730
6900
|
dir;
|
|
6731
6901
|
events;
|
|
6732
6902
|
traceId;
|
|
6903
|
+
maxAnnotations;
|
|
6733
6904
|
/** Per-session write queue. Created lazily on first add. */
|
|
6734
6905
|
writeChains = /* @__PURE__ */ new Map();
|
|
6735
6906
|
constructor(opts) {
|
|
6736
6907
|
this.dir = opts.dir;
|
|
6737
6908
|
this.events = opts.events;
|
|
6738
6909
|
this.traceId = opts.traceId;
|
|
6910
|
+
this.maxAnnotations = opts.maxAnnotations ?? MAX_ANNOTATIONS;
|
|
6739
6911
|
}
|
|
6740
6912
|
// ── Reads ──────────────────────────────────────────────────────────────
|
|
6741
6913
|
/**
|
|
@@ -6817,7 +6989,7 @@ var AnnotationsStore = class {
|
|
|
6817
6989
|
});
|
|
6818
6990
|
}
|
|
6819
6991
|
const annotation = {
|
|
6820
|
-
id:
|
|
6992
|
+
id: randomUUID3(),
|
|
6821
6993
|
sessionId: input.sessionId,
|
|
6822
6994
|
atEventIndex: input.atEventIndex,
|
|
6823
6995
|
authorId: input.authorId,
|
|
@@ -6833,12 +7005,12 @@ var AnnotationsStore = class {
|
|
|
6833
7005
|
await withFileLock(fp, async () => {
|
|
6834
7006
|
const all = await this.list(input.sessionId);
|
|
6835
7007
|
all.push(annotation);
|
|
6836
|
-
if (all.length >
|
|
7008
|
+
if (all.length > this.maxAnnotations) {
|
|
6837
7009
|
const sorted = all.map((a, i) => ({ a, i })).sort((x, y) => {
|
|
6838
7010
|
if (x.a.resolved !== y.a.resolved) return x.a.resolved ? 1 : -1;
|
|
6839
7011
|
return x.a.createdAt.localeCompare(y.a.createdAt);
|
|
6840
7012
|
});
|
|
6841
|
-
const evictCount = all.length -
|
|
7013
|
+
const evictCount = all.length - this.maxAnnotations;
|
|
6842
7014
|
const toEvict = new Set(sorted.slice(0, evictCount).map((s) => s.a.id));
|
|
6843
7015
|
const kept = all.filter((a) => !toEvict.has(a.id));
|
|
6844
7016
|
await this.writeFile(input.sessionId, { version: FILE_VERSION, annotations: kept });
|
|
@@ -6947,7 +7119,7 @@ var AnnotationsStore = class {
|
|
|
6947
7119
|
const fp = this.filePath(sessionId);
|
|
6948
7120
|
let raw;
|
|
6949
7121
|
try {
|
|
6950
|
-
raw = await
|
|
7122
|
+
raw = await fs7.readFile(fp, "utf8");
|
|
6951
7123
|
} catch (err) {
|
|
6952
7124
|
if (err.code === "ENOENT") return null;
|
|
6953
7125
|
throw err;
|
|
@@ -6982,6 +7154,13 @@ var AnnotationsStore = class {
|
|
|
6982
7154
|
return next;
|
|
6983
7155
|
}
|
|
6984
7156
|
};
|
|
7157
|
+
|
|
7158
|
+
// src/storage/replay-log-store.ts
|
|
7159
|
+
import * as fs8 from "node:fs/promises";
|
|
7160
|
+
import * as path15 from "node:path";
|
|
7161
|
+
|
|
7162
|
+
// src/replay/hash.ts
|
|
7163
|
+
import { createHash as createHash5 } from "node:crypto";
|
|
6985
7164
|
function stableStringify(value) {
|
|
6986
7165
|
return JSON.stringify(sortKeys(value));
|
|
6987
7166
|
}
|
|
@@ -7010,7 +7189,7 @@ function hashRequest(request) {
|
|
|
7010
7189
|
toolChoice: request.toolChoice
|
|
7011
7190
|
};
|
|
7012
7191
|
const json = stableStringify(payload);
|
|
7013
|
-
const digest =
|
|
7192
|
+
const digest = createHash5("sha256").update(json, "utf8").digest("hex");
|
|
7014
7193
|
return `sha256:${digest}`;
|
|
7015
7194
|
}
|
|
7016
7195
|
|
|
@@ -7022,6 +7201,7 @@ function storageErrorString2(err) {
|
|
|
7022
7201
|
}
|
|
7023
7202
|
return String(err);
|
|
7024
7203
|
}
|
|
7204
|
+
var FILE_VERSION2 = 1;
|
|
7025
7205
|
var DEFAULT_MAX_ENTRIES = 1e3;
|
|
7026
7206
|
var ReplayLogStore = class {
|
|
7027
7207
|
dir;
|
|
@@ -7066,12 +7246,12 @@ var ReplayLogStore = class {
|
|
|
7066
7246
|
const line = JSON.stringify(entry) + "\n";
|
|
7067
7247
|
let offset2 = 0;
|
|
7068
7248
|
try {
|
|
7069
|
-
const stat13 = await
|
|
7249
|
+
const stat13 = await fs8.stat(fp);
|
|
7070
7250
|
offset2 = stat13.size;
|
|
7071
7251
|
} catch (err) {
|
|
7072
7252
|
if (err.code !== "ENOENT") throw err;
|
|
7073
7253
|
}
|
|
7074
|
-
await
|
|
7254
|
+
await fs8.appendFile(fp, line, "utf8");
|
|
7075
7255
|
cache.set(hash, { entry, offset: offset2, length: Buffer.byteLength(line, "utf8") });
|
|
7076
7256
|
this.diskCount.set(input.sessionId, currentCount + 1);
|
|
7077
7257
|
this.events?.emit("storage.write", {
|
|
@@ -7199,7 +7379,7 @@ var ReplayLogStore = class {
|
|
|
7199
7379
|
const scan = async (dir, prefix, depth) => {
|
|
7200
7380
|
let entries;
|
|
7201
7381
|
try {
|
|
7202
|
-
entries = await
|
|
7382
|
+
entries = await fs8.readdir(dir, { withFileTypes: true });
|
|
7203
7383
|
} catch (err) {
|
|
7204
7384
|
if (depth === 0 && err.code !== "ENOENT") {
|
|
7205
7385
|
console.warn(JSON.stringify({
|
|
@@ -7215,13 +7395,13 @@ var ReplayLogStore = class {
|
|
|
7215
7395
|
for (const entry of entries) {
|
|
7216
7396
|
if (entry.name.startsWith(".")) continue;
|
|
7217
7397
|
if (entry.isDirectory()) {
|
|
7218
|
-
if (depth === 0) await scan(
|
|
7398
|
+
if (depth === 0) await scan(path15.join(dir, entry.name), entry.name, depth + 1);
|
|
7219
7399
|
continue;
|
|
7220
7400
|
}
|
|
7221
7401
|
if (!entry.isFile() || !entry.name.endsWith(".replay.jsonl")) continue;
|
|
7222
7402
|
const base = entry.name.slice(0, -".replay.jsonl".length);
|
|
7223
7403
|
const sessionId = prefix ? `${prefix}/${base}` : base;
|
|
7224
|
-
const fp =
|
|
7404
|
+
const fp = path15.join(dir, entry.name);
|
|
7225
7405
|
out.push({
|
|
7226
7406
|
sessionId,
|
|
7227
7407
|
entryCount: await this.countEntries(fp),
|
|
@@ -7237,7 +7417,7 @@ var ReplayLogStore = class {
|
|
|
7237
7417
|
return sessionScopedPath(this.dir, sessionId, ".replay.jsonl");
|
|
7238
7418
|
}
|
|
7239
7419
|
async countEntries(filePath) {
|
|
7240
|
-
const handle = await
|
|
7420
|
+
const handle = await fs8.open(filePath, "r");
|
|
7241
7421
|
const buffer = Buffer.allocUnsafe(64 * 1024);
|
|
7242
7422
|
let count = 0;
|
|
7243
7423
|
let hasNonWhitespace2 = false;
|
|
@@ -7278,7 +7458,7 @@ var ReplayLogStore = class {
|
|
|
7278
7458
|
async readAll(sessionId) {
|
|
7279
7459
|
const fp = this.filePath(sessionId);
|
|
7280
7460
|
try {
|
|
7281
|
-
const raw = await
|
|
7461
|
+
const raw = await fs8.readFile(fp, "utf8");
|
|
7282
7462
|
const out = [];
|
|
7283
7463
|
for (const line of raw.split("\n")) {
|
|
7284
7464
|
if (!line.trim()) continue;
|
|
@@ -7306,6 +7486,7 @@ var ReplayLogStore = class {
|
|
|
7306
7486
|
durationMs,
|
|
7307
7487
|
...this.traceId !== void 0 ? { traceId: this.traceId } : {}
|
|
7308
7488
|
});
|
|
7489
|
+
void FILE_VERSION2;
|
|
7309
7490
|
}
|
|
7310
7491
|
async ensureCache(sessionId) {
|
|
7311
7492
|
let cache = this.cache.get(sessionId);
|
|
@@ -7313,7 +7494,7 @@ var ReplayLogStore = class {
|
|
|
7313
7494
|
const fp = this.filePath(sessionId);
|
|
7314
7495
|
cache = /* @__PURE__ */ new Map();
|
|
7315
7496
|
try {
|
|
7316
|
-
const handle = await
|
|
7497
|
+
const handle = await fs8.open(fp, "r");
|
|
7317
7498
|
const CHUNK = 64 * 1024;
|
|
7318
7499
|
const buffer = Buffer.alloc(CHUNK);
|
|
7319
7500
|
let leftover = "";
|
|
@@ -7364,7 +7545,7 @@ var ReplayLogStore = class {
|
|
|
7364
7545
|
async hydrateEntry(sessionId, hash, location) {
|
|
7365
7546
|
if (location.entry) return location.entry;
|
|
7366
7547
|
const fp = this.filePath(sessionId);
|
|
7367
|
-
const handle = await
|
|
7548
|
+
const handle = await fs8.open(fp, "r");
|
|
7368
7549
|
try {
|
|
7369
7550
|
const buffer = Buffer.alloc(location.length);
|
|
7370
7551
|
const { bytesRead } = await handle.read(buffer, 0, location.length, location.offset);
|
|
@@ -7389,6 +7570,10 @@ var ReplayLogStore = class {
|
|
|
7389
7570
|
return next;
|
|
7390
7571
|
}
|
|
7391
7572
|
};
|
|
7573
|
+
|
|
7574
|
+
// src/storage/session-recovery.ts
|
|
7575
|
+
import * as fs9 from "node:fs/promises";
|
|
7576
|
+
import * as path16 from "node:path";
|
|
7392
7577
|
var SessionRecovery = class {
|
|
7393
7578
|
constructor(dir) {
|
|
7394
7579
|
this.dir = dir;
|
|
@@ -7414,7 +7599,7 @@ var SessionRecovery = class {
|
|
|
7414
7599
|
const fp = this.filePath(sessionId);
|
|
7415
7600
|
let stat13;
|
|
7416
7601
|
try {
|
|
7417
|
-
stat13 = await
|
|
7602
|
+
stat13 = await fs9.stat(fp);
|
|
7418
7603
|
} catch (err) {
|
|
7419
7604
|
if (err.code === "ENOENT") return null;
|
|
7420
7605
|
return null;
|
|
@@ -7448,7 +7633,7 @@ var SessionRecovery = class {
|
|
|
7448
7633
|
const fp = this.filePath(sessionId);
|
|
7449
7634
|
let raw;
|
|
7450
7635
|
try {
|
|
7451
|
-
raw = await
|
|
7636
|
+
raw = await fs9.readFile(fp, "utf8");
|
|
7452
7637
|
} catch (err) {
|
|
7453
7638
|
if (err.code === "ENOENT") return null;
|
|
7454
7639
|
return null;
|
|
@@ -7493,7 +7678,7 @@ var SessionRecovery = class {
|
|
|
7493
7678
|
const collect = async (dir, prefix, depth) => {
|
|
7494
7679
|
let entries;
|
|
7495
7680
|
try {
|
|
7496
|
-
entries = await
|
|
7681
|
+
entries = await fs9.readdir(dir, { withFileTypes: true });
|
|
7497
7682
|
} catch {
|
|
7498
7683
|
return;
|
|
7499
7684
|
}
|
|
@@ -7503,7 +7688,7 @@ var SessionRecovery = class {
|
|
|
7503
7688
|
continue;
|
|
7504
7689
|
if (entry.isDirectory()) {
|
|
7505
7690
|
if (depth === 0) {
|
|
7506
|
-
await collect(
|
|
7691
|
+
await collect(path16.join(dir, entry.name), entry.name, depth + 1);
|
|
7507
7692
|
}
|
|
7508
7693
|
continue;
|
|
7509
7694
|
}
|
|
@@ -7544,7 +7729,7 @@ function hasNonWhitespace(line) {
|
|
|
7544
7729
|
}
|
|
7545
7730
|
async function scanLatestLifecycleBoundary(filePath, size) {
|
|
7546
7731
|
const CHUNK_SIZE = 64 * 1024;
|
|
7547
|
-
const handle = await
|
|
7732
|
+
const handle = await fs9.open(filePath, "r");
|
|
7548
7733
|
let position = size;
|
|
7549
7734
|
let laterLineFragment = Buffer.alloc(0);
|
|
7550
7735
|
let latestBoundary = null;
|
|
@@ -7580,6 +7765,10 @@ async function scanLatestLifecycleBoundary(filePath, size) {
|
|
|
7580
7765
|
await handle.close();
|
|
7581
7766
|
}
|
|
7582
7767
|
}
|
|
7768
|
+
|
|
7769
|
+
// src/storage/tool-audit-log.ts
|
|
7770
|
+
import { createHash as createHash6, randomUUID as randomUUID4 } from "node:crypto";
|
|
7771
|
+
import * as fs10 from "node:fs/promises";
|
|
7583
7772
|
var GENESIS_PREV = "0".repeat(64);
|
|
7584
7773
|
var DEFAULT_FSYNC_EVERY = 100;
|
|
7585
7774
|
var ToolAuditLog = class {
|
|
@@ -7623,7 +7812,7 @@ var ToolAuditLog = class {
|
|
|
7623
7812
|
const tip = await this._resolveChainTip(input.sessionId, fp);
|
|
7624
7813
|
const prevHash = tip.prevHash;
|
|
7625
7814
|
const index = tip.nextIndex;
|
|
7626
|
-
const id =
|
|
7815
|
+
const id = randomUUID4();
|
|
7627
7816
|
const ts = (/* @__PURE__ */ new Date()).toISOString();
|
|
7628
7817
|
const content = {
|
|
7629
7818
|
id,
|
|
@@ -7636,7 +7825,7 @@ var ToolAuditLog = class {
|
|
|
7636
7825
|
isError: input.isError,
|
|
7637
7826
|
index
|
|
7638
7827
|
};
|
|
7639
|
-
const hash =
|
|
7828
|
+
const hash = createHash6("sha256").update(stableStringify2(content), "utf8").digest("hex");
|
|
7640
7829
|
entry = {
|
|
7641
7830
|
id,
|
|
7642
7831
|
ts,
|
|
@@ -7649,9 +7838,9 @@ var ToolAuditLog = class {
|
|
|
7649
7838
|
isError: input.isError,
|
|
7650
7839
|
index
|
|
7651
7840
|
};
|
|
7652
|
-
await
|
|
7841
|
+
await fs10.appendFile(fp, JSON.stringify(entry) + "\n", "utf8");
|
|
7653
7842
|
try {
|
|
7654
|
-
const st = await
|
|
7843
|
+
const st = await fs10.stat(fp);
|
|
7655
7844
|
this.tailStat.set(input.sessionId, { mtimeMs: st.mtimeMs, size: st.size });
|
|
7656
7845
|
} catch {
|
|
7657
7846
|
}
|
|
@@ -7698,7 +7887,7 @@ var ToolAuditLog = class {
|
|
|
7698
7887
|
const cachedStat = this.tailStat.get(sessionId);
|
|
7699
7888
|
if (cachedHash !== void 0 && cachedIndex !== void 0 && cachedStat) {
|
|
7700
7889
|
try {
|
|
7701
|
-
const st = await
|
|
7890
|
+
const st = await fs10.stat(fp);
|
|
7702
7891
|
if (st.mtimeMs === cachedStat.mtimeMs && st.size === cachedStat.size) {
|
|
7703
7892
|
return { prevHash: cachedHash, nextIndex: cachedIndex };
|
|
7704
7893
|
}
|
|
@@ -7719,7 +7908,7 @@ var ToolAuditLog = class {
|
|
|
7719
7908
|
this.tailHash.set(sessionId, prevHash);
|
|
7720
7909
|
this.tailIndex.set(sessionId, nextIndex);
|
|
7721
7910
|
try {
|
|
7722
|
-
const st = await
|
|
7911
|
+
const st = await fs10.stat(fp);
|
|
7723
7912
|
this.tailStat.set(sessionId, { mtimeMs: st.mtimeMs, size: st.size });
|
|
7724
7913
|
} catch {
|
|
7725
7914
|
}
|
|
@@ -7778,7 +7967,7 @@ var ToolAuditLog = class {
|
|
|
7778
7967
|
isError: e.isError,
|
|
7779
7968
|
index: e.index
|
|
7780
7969
|
};
|
|
7781
|
-
const expectedHash =
|
|
7970
|
+
const expectedHash = createHash6("sha256").update(stableStringify2(content), "utf8").digest("hex");
|
|
7782
7971
|
if (expectedHash !== e.hash) {
|
|
7783
7972
|
return {
|
|
7784
7973
|
ok: false,
|
|
@@ -7840,7 +8029,7 @@ var ToolAuditLog = class {
|
|
|
7840
8029
|
async readAll(sessionId) {
|
|
7841
8030
|
const fp = this.filePath(sessionId);
|
|
7842
8031
|
try {
|
|
7843
|
-
const raw = await
|
|
8032
|
+
const raw = await fs10.readFile(fp, "utf8");
|
|
7844
8033
|
const out = [];
|
|
7845
8034
|
for (const line of raw.split("\n")) {
|
|
7846
8035
|
if (!line.trim()) continue;
|
|
@@ -7878,7 +8067,7 @@ var ToolAuditLog = class {
|
|
|
7878
8067
|
}
|
|
7879
8068
|
async sync(sessionId, fp) {
|
|
7880
8069
|
try {
|
|
7881
|
-
const fh = await
|
|
8070
|
+
const fh = await fs10.open(fp, "r+");
|
|
7882
8071
|
try {
|
|
7883
8072
|
await fh.sync();
|
|
7884
8073
|
} finally {
|
|
@@ -8014,10 +8203,16 @@ var SessionAnalyzer = class {
|
|
|
8014
8203
|
return last - first;
|
|
8015
8204
|
}
|
|
8016
8205
|
};
|
|
8206
|
+
|
|
8207
|
+
// src/session-registry.ts
|
|
8208
|
+
import * as fs11 from "node:fs/promises";
|
|
8209
|
+
import * as path17 from "node:path";
|
|
8210
|
+
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
8017
8211
|
var REGISTRY_FILE = "session-registry.json";
|
|
8018
8212
|
var HEARTBEAT_INTERVAL_MS = 5e3;
|
|
8019
8213
|
var STALE_TIMEOUT_MS = 3e4;
|
|
8020
8214
|
var CLOSING_GRACE_MS = 15e3;
|
|
8215
|
+
var LOST_GRACE_MS = 3e5;
|
|
8021
8216
|
var STALE_LOCK_MS = 1e4;
|
|
8022
8217
|
var STALE_TMP_MS = 6e4;
|
|
8023
8218
|
var MAX_STALE_TMP_FILES = 20;
|
|
@@ -8029,6 +8224,16 @@ function pidAlive(pid) {
|
|
|
8029
8224
|
return false;
|
|
8030
8225
|
}
|
|
8031
8226
|
}
|
|
8227
|
+
function parseRegistry(raw) {
|
|
8228
|
+
try {
|
|
8229
|
+
const parsed = JSON.parse(raw);
|
|
8230
|
+
if (parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
8231
|
+
return parsed;
|
|
8232
|
+
}
|
|
8233
|
+
} catch {
|
|
8234
|
+
}
|
|
8235
|
+
return {};
|
|
8236
|
+
}
|
|
8032
8237
|
var SessionRegistry = class {
|
|
8033
8238
|
filePath;
|
|
8034
8239
|
heartbeatTimer = null;
|
|
@@ -8040,7 +8245,7 @@ var SessionRegistry = class {
|
|
|
8040
8245
|
*/
|
|
8041
8246
|
lastEntry = null;
|
|
8042
8247
|
constructor(globalRoot) {
|
|
8043
|
-
this.filePath =
|
|
8248
|
+
this.filePath = path17.join(globalRoot, REGISTRY_FILE);
|
|
8044
8249
|
}
|
|
8045
8250
|
// ── Public API ──────────────────────────────────────────────────────────
|
|
8046
8251
|
/**
|
|
@@ -8196,8 +8401,8 @@ var SessionRegistry = class {
|
|
|
8196
8401
|
}
|
|
8197
8402
|
async readAndPrune() {
|
|
8198
8403
|
try {
|
|
8199
|
-
const raw = await
|
|
8200
|
-
const registry =
|
|
8404
|
+
const raw = await fs11.readFile(this.filePath, "utf8");
|
|
8405
|
+
const registry = parseRegistry(raw);
|
|
8201
8406
|
const now = Date.now();
|
|
8202
8407
|
let pruned = false;
|
|
8203
8408
|
for (const [id, entry] of Object.entries(registry)) {
|
|
@@ -8207,12 +8412,24 @@ var SessionRegistry = class {
|
|
|
8207
8412
|
pruned = true;
|
|
8208
8413
|
continue;
|
|
8209
8414
|
}
|
|
8210
|
-
if (heartbeatAge > STALE_TIMEOUT_MS
|
|
8211
|
-
|
|
8212
|
-
|
|
8213
|
-
|
|
8214
|
-
|
|
8215
|
-
|
|
8415
|
+
if (heartbeatAge > STALE_TIMEOUT_MS) {
|
|
8416
|
+
const alive = pidAlive(entry.pid);
|
|
8417
|
+
if (alive) {
|
|
8418
|
+
if (entry.status !== "lost" && entry.status !== "closing" && entry.status !== "stale") {
|
|
8419
|
+
entry.status = "lost";
|
|
8420
|
+
pruned = true;
|
|
8421
|
+
}
|
|
8422
|
+
if (entry.status === "lost" && heartbeatAge > STALE_TIMEOUT_MS + LOST_GRACE_MS) {
|
|
8423
|
+
delete registry[id];
|
|
8424
|
+
pruned = true;
|
|
8425
|
+
}
|
|
8426
|
+
} else {
|
|
8427
|
+
entry.status = "stale";
|
|
8428
|
+
const startedAge = now - new Date(entry.startedAt).getTime();
|
|
8429
|
+
if (startedAge > 5 * 6e4) {
|
|
8430
|
+
delete registry[id];
|
|
8431
|
+
pruned = true;
|
|
8432
|
+
}
|
|
8216
8433
|
}
|
|
8217
8434
|
}
|
|
8218
8435
|
}
|
|
@@ -8230,11 +8447,11 @@ var SessionRegistry = class {
|
|
|
8230
8447
|
const retryDelayMs = 20;
|
|
8231
8448
|
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
|
8232
8449
|
try {
|
|
8233
|
-
await
|
|
8234
|
-
let lockHandle = await
|
|
8450
|
+
await fs11.mkdir(path17.dirname(this.filePath), { recursive: true });
|
|
8451
|
+
let lockHandle = await fs11.open(lockPath, "wx").catch(() => null);
|
|
8235
8452
|
if (!lockHandle) {
|
|
8236
8453
|
if (await this.breakStaleLock(lockPath)) {
|
|
8237
|
-
lockHandle = await
|
|
8454
|
+
lockHandle = await fs11.open(lockPath, "wx").catch(() => null);
|
|
8238
8455
|
}
|
|
8239
8456
|
if (!lockHandle) {
|
|
8240
8457
|
await new Promise((r) => setTimeout(r, retryDelayMs * (attempt + 1)));
|
|
@@ -8243,14 +8460,14 @@ var SessionRegistry = class {
|
|
|
8243
8460
|
}
|
|
8244
8461
|
try {
|
|
8245
8462
|
await lockHandle.writeFile(String(process.pid)).catch(() => void 0);
|
|
8246
|
-
const raw = await
|
|
8247
|
-
const registry =
|
|
8463
|
+
const raw = await fs11.readFile(this.filePath, "utf8").catch(() => "{}");
|
|
8464
|
+
const registry = parseRegistry(raw);
|
|
8248
8465
|
fn(registry);
|
|
8249
8466
|
await this.writeAtomicLocked(registry);
|
|
8250
8467
|
return;
|
|
8251
8468
|
} finally {
|
|
8252
8469
|
await lockHandle.close();
|
|
8253
|
-
await
|
|
8470
|
+
await fs11.unlink(lockPath).catch(() => void 0);
|
|
8254
8471
|
}
|
|
8255
8472
|
} catch {
|
|
8256
8473
|
return;
|
|
@@ -8267,16 +8484,16 @@ var SessionRegistry = class {
|
|
|
8267
8484
|
async breakStaleLock(lockPath) {
|
|
8268
8485
|
try {
|
|
8269
8486
|
const [stat13, content] = await Promise.all([
|
|
8270
|
-
|
|
8487
|
+
fs11.stat(lockPath),
|
|
8271
8488
|
/* v8 ignore start -- best-effort lock-content read; .catch only fires if the lock vanished */
|
|
8272
|
-
|
|
8489
|
+
fs11.readFile(lockPath, "utf8").catch(() => "")
|
|
8273
8490
|
/* v8 ignore stop */
|
|
8274
8491
|
]);
|
|
8275
8492
|
const ageMs = Date.now() - stat13.mtimeMs;
|
|
8276
8493
|
const ownerPid = Number.parseInt(content.trim(), 10);
|
|
8277
8494
|
const ownerDead = Number.isInteger(ownerPid) && ownerPid > 0 && ownerPid !== process.pid && !pidAlive(ownerPid);
|
|
8278
8495
|
if (ownerDead || ageMs > STALE_LOCK_MS) {
|
|
8279
|
-
await
|
|
8496
|
+
await fs11.unlink(lockPath).catch(() => void 0);
|
|
8280
8497
|
return true;
|
|
8281
8498
|
}
|
|
8282
8499
|
return false;
|
|
@@ -8294,35 +8511,41 @@ var SessionRegistry = class {
|
|
|
8294
8511
|
await this.writeAtomicFile(registry);
|
|
8295
8512
|
}
|
|
8296
8513
|
async writeAtomicFile(registry) {
|
|
8297
|
-
const tmp =
|
|
8298
|
-
|
|
8299
|
-
`.${
|
|
8514
|
+
const tmp = path17.join(
|
|
8515
|
+
path17.dirname(this.filePath),
|
|
8516
|
+
`.${path17.basename(this.filePath)}.${randomUUID5().slice(0, 8)}.tmp`
|
|
8300
8517
|
);
|
|
8301
8518
|
try {
|
|
8302
|
-
await
|
|
8303
|
-
|
|
8519
|
+
const handle = await fs11.open(tmp, "w");
|
|
8520
|
+
try {
|
|
8521
|
+
await handle.writeFile(JSON.stringify(registry, null, 2), "utf8");
|
|
8522
|
+
await handle.sync().catch(() => void 0);
|
|
8523
|
+
} finally {
|
|
8524
|
+
await handle.close();
|
|
8525
|
+
}
|
|
8526
|
+
await fs11.rename(tmp, this.filePath);
|
|
8304
8527
|
} catch (err) {
|
|
8305
|
-
await
|
|
8528
|
+
await fs11.unlink(tmp).catch(() => void 0);
|
|
8306
8529
|
throw err;
|
|
8307
8530
|
}
|
|
8308
8531
|
}
|
|
8309
8532
|
async pruneStaleTempFiles() {
|
|
8310
8533
|
try {
|
|
8311
|
-
const dir =
|
|
8312
|
-
const base =
|
|
8534
|
+
const dir = path17.dirname(this.filePath);
|
|
8535
|
+
const base = path17.basename(this.filePath);
|
|
8313
8536
|
const now = Date.now();
|
|
8314
8537
|
const stale = [];
|
|
8315
|
-
for (const name of await
|
|
8538
|
+
for (const name of await fs11.readdir(dir)) {
|
|
8316
8539
|
const isTemp = (name.startsWith(`${base}.`) || name.startsWith(`.${base}.`)) && name.endsWith(".tmp");
|
|
8317
8540
|
if (!isTemp) continue;
|
|
8318
|
-
const stat13 = await
|
|
8541
|
+
const stat13 = await fs11.stat(path17.join(dir, name)).catch(() => null);
|
|
8319
8542
|
if (!stat13) continue;
|
|
8320
8543
|
if (now - stat13.mtimeMs > STALE_TMP_MS) stale.push({ name, mtimeMs: stat13.mtimeMs });
|
|
8321
8544
|
}
|
|
8322
8545
|
stale.sort((a, b) => b.mtimeMs - a.mtimeMs);
|
|
8323
8546
|
await Promise.all(
|
|
8324
8547
|
stale.slice(MAX_STALE_TMP_FILES).map(async ({ name }) => {
|
|
8325
|
-
await
|
|
8548
|
+
await fs11.unlink(path17.join(dir, name)).catch(() => void 0);
|
|
8326
8549
|
})
|
|
8327
8550
|
);
|
|
8328
8551
|
} catch {
|
|
@@ -8617,6 +8840,13 @@ var AgentStatusTracker = class {
|
|
|
8617
8840
|
if (this.agents.delete(p.subagentId)) this.flush();
|
|
8618
8841
|
})
|
|
8619
8842
|
);
|
|
8843
|
+
this.unsubscribers.push(
|
|
8844
|
+
on("subagent.removed", (_e, payload) => {
|
|
8845
|
+
const p = payload;
|
|
8846
|
+
if (!p?.subagentId) return;
|
|
8847
|
+
if (this.agents.delete(p.subagentId)) this.flush();
|
|
8848
|
+
})
|
|
8849
|
+
);
|
|
8620
8850
|
this.sweepTimer = setInterval(() => this.sweep(), AGENT_SWEEP_INTERVAL_MS);
|
|
8621
8851
|
if (typeof this.sweepTimer.unref === "function") this.sweepTimer.unref();
|
|
8622
8852
|
}
|
|
@@ -8729,6 +8959,10 @@ var AgentStatusTracker = class {
|
|
|
8729
8959
|
}
|
|
8730
8960
|
}
|
|
8731
8961
|
};
|
|
8962
|
+
|
|
8963
|
+
// src/fleet-notifier.ts
|
|
8964
|
+
import * as fs12 from "node:fs/promises";
|
|
8965
|
+
import * as path18 from "node:path";
|
|
8732
8966
|
var INSTANCES_FILE = "webui-instances.json";
|
|
8733
8967
|
var DISCOVERY_TTL_MS = 2500;
|
|
8734
8968
|
var COALESCE_MS = 50;
|
|
@@ -8743,7 +8977,7 @@ function pidAlive2(pid) {
|
|
|
8743
8977
|
}
|
|
8744
8978
|
}
|
|
8745
8979
|
function normRoot(root) {
|
|
8746
|
-
const resolved =
|
|
8980
|
+
const resolved = path18.resolve(root);
|
|
8747
8981
|
return process.platform === "win32" ? resolved.toLowerCase() : resolved;
|
|
8748
8982
|
}
|
|
8749
8983
|
var FleetNotifier = class {
|
|
@@ -8790,7 +9024,7 @@ var FleetNotifier = class {
|
|
|
8790
9024
|
}
|
|
8791
9025
|
async discover() {
|
|
8792
9026
|
try {
|
|
8793
|
-
const raw = await
|
|
9027
|
+
const raw = await fs12.readFile(path18.join(this.baseDir, INSTANCES_FILE), "utf8");
|
|
8794
9028
|
const data = JSON.parse(raw);
|
|
8795
9029
|
const list = Array.isArray(data?.instances) ? data.instances : [];
|
|
8796
9030
|
return list.filter((i) => i && typeof i.httpPort === "number").filter((i) => i.pid !== this.selfPid).filter((i) => normRoot(i.projectRoot) === this.projectRoot).filter((i) => pidAlive2(i.pid)).map((i) => {
|
|
@@ -8808,6 +9042,10 @@ async function defaultPost(url) {
|
|
|
8808
9042
|
signal: AbortSignal.timeout(POST_TIMEOUT_MS)
|
|
8809
9043
|
});
|
|
8810
9044
|
}
|
|
9045
|
+
|
|
9046
|
+
// src/storage/session-rewinder.ts
|
|
9047
|
+
import * as fsp8 from "node:fs/promises";
|
|
9048
|
+
import * as path19 from "node:path";
|
|
8811
9049
|
var DefaultSessionRewinder = class {
|
|
8812
9050
|
constructor(sessionsDir, projectRoot) {
|
|
8813
9051
|
this.sessionsDir = sessionsDir;
|
|
@@ -8820,7 +9058,7 @@ var DefaultSessionRewinder = class {
|
|
|
8820
9058
|
}
|
|
8821
9059
|
async listCheckpoints(sessionId) {
|
|
8822
9060
|
const file = this.sessionFile(sessionId);
|
|
8823
|
-
const raw = await
|
|
9061
|
+
const raw = await fsp8.readFile(file, "utf8");
|
|
8824
9062
|
const events = parseEvents(raw);
|
|
8825
9063
|
const fileCountMap = /* @__PURE__ */ new Map();
|
|
8826
9064
|
for (const event of events) {
|
|
@@ -8845,7 +9083,7 @@ var DefaultSessionRewinder = class {
|
|
|
8845
9083
|
}
|
|
8846
9084
|
async rewindToCheckpoint(sessionId, checkpointIndex) {
|
|
8847
9085
|
const file = this.sessionFile(sessionId);
|
|
8848
|
-
const raw = await
|
|
9086
|
+
const raw = await fsp8.readFile(file, "utf8");
|
|
8849
9087
|
const events = parseEvents(raw);
|
|
8850
9088
|
let targetIdx = -1;
|
|
8851
9089
|
for (let i = 0; i < events.length; i++) {
|
|
@@ -8884,7 +9122,7 @@ var DefaultSessionRewinder = class {
|
|
|
8884
9122
|
}
|
|
8885
9123
|
async rewindLastN(sessionId, n) {
|
|
8886
9124
|
const file = this.sessionFile(sessionId);
|
|
8887
|
-
const raw = await
|
|
9125
|
+
const raw = await fsp8.readFile(file, "utf8");
|
|
8888
9126
|
const events = parseEvents(raw);
|
|
8889
9127
|
const checkpoints = [];
|
|
8890
9128
|
for (const event of events) {
|
|
@@ -8913,7 +9151,7 @@ var DefaultSessionRewinder = class {
|
|
|
8913
9151
|
}
|
|
8914
9152
|
async rewindToStart(sessionId) {
|
|
8915
9153
|
const file = this.sessionFile(sessionId);
|
|
8916
|
-
const raw = await
|
|
9154
|
+
const raw = await fsp8.readFile(file, "utf8");
|
|
8917
9155
|
const events = parseEvents(raw);
|
|
8918
9156
|
const allSnapshots = [];
|
|
8919
9157
|
for (const event of events) {
|
|
@@ -8948,10 +9186,10 @@ async function revertSnapshots(snapshots, projectRoot) {
|
|
|
8948
9186
|
for (const snapshot of [...snapshots].reverse()) {
|
|
8949
9187
|
for (const file of [...snapshot.files].reverse()) {
|
|
8950
9188
|
try {
|
|
8951
|
-
const absPath =
|
|
8952
|
-
const root =
|
|
8953
|
-
const rel =
|
|
8954
|
-
if (rel.startsWith("..") ||
|
|
9189
|
+
const absPath = path19.resolve(file.path);
|
|
9190
|
+
const root = path19.resolve(projectRoot);
|
|
9191
|
+
const rel = path19.relative(root, absPath);
|
|
9192
|
+
if (rel.startsWith("..") || path19.isAbsolute(rel)) {
|
|
8955
9193
|
errors.push(`${file.path}: path resolves outside project root \u2014 skipping`);
|
|
8956
9194
|
continue;
|
|
8957
9195
|
}
|
|
@@ -8961,7 +9199,7 @@ async function revertSnapshots(snapshots, projectRoot) {
|
|
|
8961
9199
|
revertedFiles.push(file.path);
|
|
8962
9200
|
}
|
|
8963
9201
|
} else if (file.action === "created") {
|
|
8964
|
-
await
|
|
9202
|
+
await fsp8.unlink(file.path);
|
|
8965
9203
|
revertedFiles.push(file.path);
|
|
8966
9204
|
} else if (file.action === "modified") {
|
|
8967
9205
|
if (file.before !== null) {
|
|
@@ -8976,11 +9214,14 @@ async function revertSnapshots(snapshots, projectRoot) {
|
|
|
8976
9214
|
}
|
|
8977
9215
|
return { revertedFiles, errors };
|
|
8978
9216
|
}
|
|
9217
|
+
|
|
9218
|
+
// src/storage/todos-checkpoint.ts
|
|
9219
|
+
import * as fsp9 from "node:fs/promises";
|
|
8979
9220
|
async function loadTodosCheckpoint(filePath, events, traceId) {
|
|
8980
9221
|
const t0 = Date.now();
|
|
8981
9222
|
let raw;
|
|
8982
9223
|
try {
|
|
8983
|
-
raw = await
|
|
9224
|
+
raw = await fsp9.readFile(filePath, "utf8");
|
|
8984
9225
|
} catch (err) {
|
|
8985
9226
|
events?.emit("storage.error", {
|
|
8986
9227
|
sessionId: traceId ?? "~boot~",
|
|
@@ -9115,11 +9356,14 @@ function attachTodosCheckpoint(state, filePath, sessionId, events, traceId) {
|
|
|
9115
9356
|
}
|
|
9116
9357
|
};
|
|
9117
9358
|
}
|
|
9359
|
+
|
|
9360
|
+
// src/storage/completed-work-checkpoint.ts
|
|
9361
|
+
import * as fsp10 from "node:fs/promises";
|
|
9118
9362
|
async function loadCompletedWorkCheckpoint(filePath, events, traceId) {
|
|
9119
9363
|
const t0 = Date.now();
|
|
9120
9364
|
let raw;
|
|
9121
9365
|
try {
|
|
9122
|
-
raw = await
|
|
9366
|
+
raw = await fsp10.readFile(filePath, "utf8");
|
|
9123
9367
|
} catch (err) {
|
|
9124
9368
|
events?.emit("storage.error", {
|
|
9125
9369
|
sessionId: traceId ?? "~boot~",
|
|
@@ -9213,11 +9457,15 @@ function isCompletedWorkEvidence(value) {
|
|
|
9213
9457
|
const item = value;
|
|
9214
9458
|
return typeof item.key === "string" && typeof item.source === "string" && ["todo", "plan", "task", "verification", "manual"].includes(item.source) && typeof item.summary === "string" && typeof item.completedAt === "number" && (item.evidence === void 0 || typeof item.evidence === "string");
|
|
9215
9459
|
}
|
|
9460
|
+
|
|
9461
|
+
// src/storage/plan-store.ts
|
|
9462
|
+
import * as fsp11 from "node:fs/promises";
|
|
9463
|
+
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
9216
9464
|
async function loadPlan(filePath, events) {
|
|
9217
9465
|
const t0 = Date.now();
|
|
9218
9466
|
let raw;
|
|
9219
9467
|
try {
|
|
9220
|
-
raw = await
|
|
9468
|
+
raw = await fsp11.readFile(filePath, "utf8");
|
|
9221
9469
|
} catch (err) {
|
|
9222
9470
|
events?.emit("storage.error", {
|
|
9223
9471
|
sessionId: "~boot~",
|
|
@@ -9306,7 +9554,7 @@ function emptyPlan(sessionId, title) {
|
|
|
9306
9554
|
function addPlanItem(plan, title, details) {
|
|
9307
9555
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
9308
9556
|
const item = {
|
|
9309
|
-
id: `plan_${Date.now()}_${
|
|
9557
|
+
id: `plan_${Date.now()}_${randomUUID6().slice(0, 6)}`,
|
|
9310
9558
|
title,
|
|
9311
9559
|
details,
|
|
9312
9560
|
status: "open",
|
|
@@ -9380,7 +9628,7 @@ function deriveTodosFromPlanItem(plan, idOrIndex, subtasks) {
|
|
|
9380
9628
|
if (subtasks && subtasks.length > 0) {
|
|
9381
9629
|
for (const st of subtasks) {
|
|
9382
9630
|
todos.push({
|
|
9383
|
-
id: `todo_${Date.now()}_${
|
|
9631
|
+
id: `todo_${Date.now()}_${randomUUID6().slice(0, 6)}`,
|
|
9384
9632
|
content: st,
|
|
9385
9633
|
status: "pending",
|
|
9386
9634
|
promotedFromPlan: item.id
|
|
@@ -9521,6 +9769,9 @@ ${cat}:`);
|
|
|
9521
9769
|
}
|
|
9522
9770
|
return lines.join("\n");
|
|
9523
9771
|
}
|
|
9772
|
+
|
|
9773
|
+
// src/storage/task-store.ts
|
|
9774
|
+
import * as fsp12 from "node:fs/promises";
|
|
9524
9775
|
function emptyTaskFile(sessionId) {
|
|
9525
9776
|
return {
|
|
9526
9777
|
version: 1,
|
|
@@ -9533,7 +9784,7 @@ async function loadTasks(filePath, events, traceId) {
|
|
|
9533
9784
|
const t0 = Date.now();
|
|
9534
9785
|
let raw;
|
|
9535
9786
|
try {
|
|
9536
|
-
raw = await
|
|
9787
|
+
raw = await fsp12.readFile(filePath, "utf8");
|
|
9537
9788
|
} catch (err) {
|
|
9538
9789
|
events?.emit("storage.error", {
|
|
9539
9790
|
sessionId: traceId ?? "~boot~",
|
|
@@ -9634,10 +9885,14 @@ async function mutateTasks(filePath, sessionId, fn, events, traceId) {
|
|
|
9634
9885
|
return updated;
|
|
9635
9886
|
});
|
|
9636
9887
|
}
|
|
9888
|
+
|
|
9889
|
+
// src/storage/director-state.ts
|
|
9890
|
+
import * as fsp13 from "node:fs/promises";
|
|
9891
|
+
import { hostname as hostname2 } from "node:os";
|
|
9637
9892
|
async function loadDirectorState(filePath) {
|
|
9638
9893
|
let raw;
|
|
9639
9894
|
try {
|
|
9640
|
-
raw = await
|
|
9895
|
+
raw = await fsp13.readFile(filePath, "utf8");
|
|
9641
9896
|
} catch {
|
|
9642
9897
|
return null;
|
|
9643
9898
|
}
|
|
@@ -9652,7 +9907,7 @@ async function loadDirectorState(filePath) {
|
|
|
9652
9907
|
async function acquireDirectorStateLock(lockPath, processId = process.pid) {
|
|
9653
9908
|
let existing;
|
|
9654
9909
|
try {
|
|
9655
|
-
existing = await
|
|
9910
|
+
existing = await fsp13.readFile(lockPath, "utf8");
|
|
9656
9911
|
} catch {
|
|
9657
9912
|
}
|
|
9658
9913
|
if (existing) {
|
|
@@ -9668,7 +9923,7 @@ async function acquireDirectorStateLock(lockPath, processId = process.pid) {
|
|
|
9668
9923
|
}
|
|
9669
9924
|
const lock = {
|
|
9670
9925
|
pid: processId,
|
|
9671
|
-
hostname:
|
|
9926
|
+
hostname: hostname2(),
|
|
9672
9927
|
startedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
9673
9928
|
};
|
|
9674
9929
|
await atomicWrite(lockPath, JSON.stringify(lock), { mode: 384 });
|
|
@@ -9676,7 +9931,7 @@ async function acquireDirectorStateLock(lockPath, processId = process.pid) {
|
|
|
9676
9931
|
}
|
|
9677
9932
|
async function releaseDirectorStateLock(lockPath) {
|
|
9678
9933
|
try {
|
|
9679
|
-
await
|
|
9934
|
+
await fsp13.unlink(lockPath);
|
|
9680
9935
|
} catch {
|
|
9681
9936
|
}
|
|
9682
9937
|
}
|
|
@@ -9831,6 +10086,9 @@ var DirectorStateCheckpoint = class {
|
|
|
9831
10086
|
}
|
|
9832
10087
|
}
|
|
9833
10088
|
};
|
|
10089
|
+
|
|
10090
|
+
// src/storage/goal-store.ts
|
|
10091
|
+
import * as fsp14 from "node:fs/promises";
|
|
9834
10092
|
var MAX_JOURNAL_ENTRIES = 500;
|
|
9835
10093
|
function goalFilePath(projectRoot) {
|
|
9836
10094
|
return resolveWstackPaths({ projectRoot }).projectGoal;
|
|
@@ -9839,7 +10097,7 @@ async function loadGoal(filePath, events) {
|
|
|
9839
10097
|
const t0 = Date.now();
|
|
9840
10098
|
let raw;
|
|
9841
10099
|
try {
|
|
9842
|
-
raw = await
|
|
10100
|
+
raw = await fsp14.readFile(filePath, "utf8");
|
|
9843
10101
|
} catch (err) {
|
|
9844
10102
|
const code = err.code;
|
|
9845
10103
|
if (code === "ENOENT") {
|
|
@@ -10083,9 +10341,14 @@ function computeTrend(history) {
|
|
|
10083
10341
|
if (avgDelta < -1) return "stalling";
|
|
10084
10342
|
return "steady";
|
|
10085
10343
|
}
|
|
10344
|
+
|
|
10345
|
+
// src/storage/prompt-store.ts
|
|
10346
|
+
import { createHash as createHash7 } from "node:crypto";
|
|
10347
|
+
import * as fs13 from "node:fs/promises";
|
|
10348
|
+
import * as path20 from "node:path";
|
|
10086
10349
|
var SCHEMA_VERSION = 2;
|
|
10087
10350
|
function promptChecksum(content) {
|
|
10088
|
-
return
|
|
10351
|
+
return createHash7("sha256").update(content, "utf8").digest("hex");
|
|
10089
10352
|
}
|
|
10090
10353
|
function migratePromptEntry(raw) {
|
|
10091
10354
|
if (!raw || typeof raw !== "object") return null;
|
|
@@ -10146,12 +10409,12 @@ var DefaultPromptStore = class {
|
|
|
10146
10409
|
await ensureDir(this.dir);
|
|
10147
10410
|
const entries = [];
|
|
10148
10411
|
try {
|
|
10149
|
-
const files = await
|
|
10412
|
+
const files = await fs13.readdir(this.dir);
|
|
10150
10413
|
for (const file of files) {
|
|
10151
10414
|
if (!file.endsWith(".json")) continue;
|
|
10152
10415
|
try {
|
|
10153
10416
|
const raw = JSON.parse(
|
|
10154
|
-
await
|
|
10417
|
+
await fs13.readFile(path20.join(this.dir, file), "utf8")
|
|
10155
10418
|
);
|
|
10156
10419
|
const migrated = migratePromptEntry(raw.entry);
|
|
10157
10420
|
if (migrated) entries.push(migrated);
|
|
@@ -10165,9 +10428,9 @@ var DefaultPromptStore = class {
|
|
|
10165
10428
|
);
|
|
10166
10429
|
}
|
|
10167
10430
|
async get(id) {
|
|
10168
|
-
const file =
|
|
10431
|
+
const file = path20.join(this.dir, `${id}.json`);
|
|
10169
10432
|
try {
|
|
10170
|
-
const raw = JSON.parse(await
|
|
10433
|
+
const raw = JSON.parse(await fs13.readFile(file, "utf8"));
|
|
10171
10434
|
return migratePromptEntry(raw.entry);
|
|
10172
10435
|
} catch {
|
|
10173
10436
|
return null;
|
|
@@ -10175,14 +10438,14 @@ var DefaultPromptStore = class {
|
|
|
10175
10438
|
}
|
|
10176
10439
|
async save(entry) {
|
|
10177
10440
|
await ensureDir(this.dir);
|
|
10178
|
-
const file =
|
|
10441
|
+
const file = path20.join(this.dir, `${entry.id}.json`);
|
|
10179
10442
|
const raw = { version: SCHEMA_VERSION, entry };
|
|
10180
10443
|
await atomicWrite(file, JSON.stringify(raw, null, 2));
|
|
10181
10444
|
}
|
|
10182
10445
|
async delete(id) {
|
|
10183
|
-
const file =
|
|
10446
|
+
const file = path20.join(this.dir, `${id}.json`);
|
|
10184
10447
|
try {
|
|
10185
|
-
await
|
|
10448
|
+
await fs13.unlink(file);
|
|
10186
10449
|
return true;
|
|
10187
10450
|
} catch {
|
|
10188
10451
|
return false;
|
|
@@ -10219,6 +10482,10 @@ var DefaultPromptStore = class {
|
|
|
10219
10482
|
};
|
|
10220
10483
|
}
|
|
10221
10484
|
};
|
|
10485
|
+
|
|
10486
|
+
// src/storage/prompt-usage-store.ts
|
|
10487
|
+
import * as fs14 from "node:fs/promises";
|
|
10488
|
+
import * as path21 from "node:path";
|
|
10222
10489
|
var PromptUsageStore = class {
|
|
10223
10490
|
constructor(file) {
|
|
10224
10491
|
this.file = file;
|
|
@@ -10226,7 +10493,7 @@ var PromptUsageStore = class {
|
|
|
10226
10493
|
file;
|
|
10227
10494
|
async load() {
|
|
10228
10495
|
try {
|
|
10229
|
-
const raw = JSON.parse(await
|
|
10496
|
+
const raw = JSON.parse(await fs14.readFile(this.file, "utf8"));
|
|
10230
10497
|
if (raw && typeof raw === "object" && raw.usage && typeof raw.usage === "object") {
|
|
10231
10498
|
return raw.usage;
|
|
10232
10499
|
}
|
|
@@ -10239,7 +10506,7 @@ var PromptUsageStore = class {
|
|
|
10239
10506
|
const prev = usage[slug];
|
|
10240
10507
|
const next = { count: (prev?.count ?? 0) + 1, lastUsedAt: at };
|
|
10241
10508
|
usage[slug] = next;
|
|
10242
|
-
await ensureDir(
|
|
10509
|
+
await ensureDir(path21.dirname(this.file));
|
|
10243
10510
|
await atomicWrite(this.file, JSON.stringify({ version: 1, usage }, null, 2));
|
|
10244
10511
|
return next;
|
|
10245
10512
|
}
|
|
@@ -10261,6 +10528,10 @@ var PromptUsageStore = class {
|
|
|
10261
10528
|
).slice(0, limit);
|
|
10262
10529
|
}
|
|
10263
10530
|
};
|
|
10531
|
+
|
|
10532
|
+
// src/storage/input-history-store.ts
|
|
10533
|
+
import * as fs15 from "node:fs/promises";
|
|
10534
|
+
import * as path22 from "node:path";
|
|
10264
10535
|
var INPUT_HISTORY_DEFAULT_MAX = 100;
|
|
10265
10536
|
var InputHistoryStore = class {
|
|
10266
10537
|
/**
|
|
@@ -10282,7 +10553,7 @@ var InputHistoryStore = class {
|
|
|
10282
10553
|
*/
|
|
10283
10554
|
async load() {
|
|
10284
10555
|
try {
|
|
10285
|
-
const raw = JSON.parse(await
|
|
10556
|
+
const raw = JSON.parse(await fs15.readFile(this.file, "utf8"));
|
|
10286
10557
|
if (raw && typeof raw === "object" && Array.isArray(raw.entries) && raw.entries.every((e) => typeof e === "string")) {
|
|
10287
10558
|
return raw.entries.slice(0, this.maxEntries);
|
|
10288
10559
|
}
|
|
@@ -10299,7 +10570,7 @@ var InputHistoryStore = class {
|
|
|
10299
10570
|
*/
|
|
10300
10571
|
async save(entries) {
|
|
10301
10572
|
const cleaned = this.scrubAndFilter(entries);
|
|
10302
|
-
await ensureDir(
|
|
10573
|
+
await ensureDir(path22.dirname(this.file));
|
|
10303
10574
|
const payload = {
|
|
10304
10575
|
version: 1,
|
|
10305
10576
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -10309,7 +10580,7 @@ var InputHistoryStore = class {
|
|
|
10309
10580
|
}
|
|
10310
10581
|
/** Truncate the file to an empty entry list (used by /clear). */
|
|
10311
10582
|
async clear() {
|
|
10312
|
-
await ensureDir(
|
|
10583
|
+
await ensureDir(path22.dirname(this.file));
|
|
10313
10584
|
const payload = { version: 1, updatedAt: (/* @__PURE__ */ new Date()).toISOString(), entries: [] };
|
|
10314
10585
|
await atomicWrite(this.file, JSON.stringify(payload, null, 2));
|
|
10315
10586
|
}
|
|
@@ -10337,13 +10608,18 @@ var InputHistoryStore = class {
|
|
|
10337
10608
|
return text.includes("***REDACTED***");
|
|
10338
10609
|
}
|
|
10339
10610
|
};
|
|
10611
|
+
|
|
10612
|
+
// src/storage/cloud-sync.ts
|
|
10613
|
+
import * as fs16 from "node:fs/promises";
|
|
10614
|
+
import * as path23 from "node:path";
|
|
10615
|
+
import { createHash as createHash8 } from "node:crypto";
|
|
10340
10616
|
var ALL_SYNC_CATEGORIES = ["settings", "skills", "prompts", "memory", "history"];
|
|
10341
10617
|
var CloudSync = class {
|
|
10342
10618
|
constructor(paths, getConfig, setConfig) {
|
|
10343
10619
|
this.paths = paths;
|
|
10344
10620
|
this.getConfig = getConfig;
|
|
10345
10621
|
this.setConfig = setConfig;
|
|
10346
|
-
this.statePath =
|
|
10622
|
+
this.statePath = path23.join(paths.globalRoot, "sync-state.json");
|
|
10347
10623
|
}
|
|
10348
10624
|
paths;
|
|
10349
10625
|
getConfig;
|
|
@@ -10418,7 +10694,7 @@ var CloudSync = class {
|
|
|
10418
10694
|
lastSyncedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
10419
10695
|
localRev: rev
|
|
10420
10696
|
};
|
|
10421
|
-
await
|
|
10697
|
+
await fs16.writeFile(this.statePath, JSON.stringify(syncState, null, 2), "utf8");
|
|
10422
10698
|
this.state = syncState;
|
|
10423
10699
|
return {
|
|
10424
10700
|
ok: true,
|
|
@@ -10450,8 +10726,8 @@ var CloudSync = class {
|
|
|
10450
10726
|
const rel = segments.slice(2).join("/");
|
|
10451
10727
|
const destPath = resolvePulledCategoryPath(cat, localPath, rel, entry.path);
|
|
10452
10728
|
const blobData = await this.getBlob(token, owner, repoName, entry.sha);
|
|
10453
|
-
await
|
|
10454
|
-
await
|
|
10729
|
+
await fs16.mkdir(path23.dirname(destPath), { recursive: true });
|
|
10730
|
+
await fs16.writeFile(destPath, Buffer.from(blobData, "base64"));
|
|
10455
10731
|
}
|
|
10456
10732
|
const localRev = await this.hashLocalCategories(cfg.categories);
|
|
10457
10733
|
const syncState = {
|
|
@@ -10460,7 +10736,7 @@ var CloudSync = class {
|
|
|
10460
10736
|
lastSyncedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
10461
10737
|
localRev
|
|
10462
10738
|
};
|
|
10463
|
-
await
|
|
10739
|
+
await fs16.writeFile(this.statePath, JSON.stringify(syncState, null, 2), "utf8");
|
|
10464
10740
|
this.state = syncState;
|
|
10465
10741
|
return {
|
|
10466
10742
|
ok: true,
|
|
@@ -10479,7 +10755,7 @@ var CloudSync = class {
|
|
|
10479
10755
|
}
|
|
10480
10756
|
async loadState() {
|
|
10481
10757
|
try {
|
|
10482
|
-
const raw = await
|
|
10758
|
+
const raw = await fs16.readFile(this.statePath, "utf8");
|
|
10483
10759
|
this.state = JSON.parse(raw);
|
|
10484
10760
|
} catch {
|
|
10485
10761
|
this.state = null;
|
|
@@ -10557,24 +10833,24 @@ var CloudSync = class {
|
|
|
10557
10833
|
const localPath = this.categoryToPath(cat);
|
|
10558
10834
|
if (!localPath) continue;
|
|
10559
10835
|
try {
|
|
10560
|
-
const stat13 = await
|
|
10836
|
+
const stat13 = await fs16.stat(localPath);
|
|
10561
10837
|
if (stat13.isDirectory()) {
|
|
10562
10838
|
const files = await this.walkDir(localPath, localPath);
|
|
10563
10839
|
for (const file of files) {
|
|
10564
|
-
const content = await
|
|
10565
|
-
const rel =
|
|
10840
|
+
const content = await fs16.readFile(file, "utf8");
|
|
10841
|
+
const rel = path23.relative(localPath, file).replace(/\\/g, "/");
|
|
10566
10842
|
entries.push({ path: `data/${cat}/${rel}`, content, mode: "100644" });
|
|
10567
10843
|
hashes.push(content);
|
|
10568
10844
|
}
|
|
10569
10845
|
} else {
|
|
10570
|
-
const content = await
|
|
10846
|
+
const content = await fs16.readFile(localPath, "utf8");
|
|
10571
10847
|
entries.push({ path: `data/${cat}`, content, mode: "100644" });
|
|
10572
10848
|
hashes.push(content);
|
|
10573
10849
|
}
|
|
10574
10850
|
} catch {
|
|
10575
10851
|
}
|
|
10576
10852
|
}
|
|
10577
|
-
const rev =
|
|
10853
|
+
const rev = createHash8("sha256").update(hashes.join("")).digest("hex").slice(0, 12);
|
|
10578
10854
|
return { treeEntries: entries, rev };
|
|
10579
10855
|
}
|
|
10580
10856
|
async hashLocalCategories(categories) {
|
|
@@ -10583,21 +10859,21 @@ var CloudSync = class {
|
|
|
10583
10859
|
const localPath = this.categoryToPath(cat);
|
|
10584
10860
|
if (!localPath) continue;
|
|
10585
10861
|
try {
|
|
10586
|
-
const stat13 = await
|
|
10862
|
+
const stat13 = await fs16.stat(localPath);
|
|
10587
10863
|
if (stat13.isDirectory()) {
|
|
10588
10864
|
const files = await this.walkDir(localPath, localPath);
|
|
10589
10865
|
for (const file of files) {
|
|
10590
|
-
const content = await
|
|
10866
|
+
const content = await fs16.readFile(file);
|
|
10591
10867
|
hashes.push(content.toString("base64") + file);
|
|
10592
10868
|
}
|
|
10593
10869
|
} else {
|
|
10594
|
-
const content = await
|
|
10870
|
+
const content = await fs16.readFile(localPath);
|
|
10595
10871
|
hashes.push(content.toString("base64") + localPath);
|
|
10596
10872
|
}
|
|
10597
10873
|
} catch {
|
|
10598
10874
|
}
|
|
10599
10875
|
}
|
|
10600
|
-
return
|
|
10876
|
+
return createHash8("sha256").update(hashes.join("")).digest("hex").slice(0, 12);
|
|
10601
10877
|
}
|
|
10602
10878
|
categoryToPath(cat) {
|
|
10603
10879
|
switch (cat) {
|
|
@@ -10618,9 +10894,9 @@ var CloudSync = class {
|
|
|
10618
10894
|
}
|
|
10619
10895
|
async walkDir(dir, base) {
|
|
10620
10896
|
const results = [];
|
|
10621
|
-
const entries = await
|
|
10897
|
+
const entries = await fs16.readdir(dir, { withFileTypes: true });
|
|
10622
10898
|
for (const entry of entries) {
|
|
10623
|
-
const full =
|
|
10899
|
+
const full = path23.join(dir, entry.name);
|
|
10624
10900
|
if (entry.isDirectory()) {
|
|
10625
10901
|
results.push(...await this.walkDir(full, base));
|
|
10626
10902
|
} else {
|
|
@@ -10642,9 +10918,9 @@ function resolvePulledCategoryPath(cat, localPath, rel, remotePath) {
|
|
|
10642
10918
|
return localPath;
|
|
10643
10919
|
}
|
|
10644
10920
|
if (!rel) return localPath;
|
|
10645
|
-
const normalizedRel =
|
|
10646
|
-
const traversesUp = normalizedRel === ".." || normalizedRel.startsWith(`..${
|
|
10647
|
-
if (
|
|
10921
|
+
const normalizedRel = path23.normalize(rel);
|
|
10922
|
+
const traversesUp = normalizedRel === ".." || normalizedRel.startsWith(`..${path23.sep}`);
|
|
10923
|
+
if (path23.isAbsolute(normalizedRel) || traversesUp) {
|
|
10648
10924
|
throw new FsError({
|
|
10649
10925
|
message: `Refusing CloudSync path traversal: ${remotePath}`,
|
|
10650
10926
|
code: ERROR_CODES.FS_DELETE_FAILED,
|
|
@@ -10652,10 +10928,10 @@ function resolvePulledCategoryPath(cat, localPath, rel, remotePath) {
|
|
|
10652
10928
|
context: { reason: "path_traversal", normalizedRel }
|
|
10653
10929
|
});
|
|
10654
10930
|
}
|
|
10655
|
-
const dest =
|
|
10656
|
-
const root =
|
|
10657
|
-
const relative6 =
|
|
10658
|
-
if (relative6.startsWith("..") ||
|
|
10931
|
+
const dest = path23.resolve(localPath, normalizedRel);
|
|
10932
|
+
const root = path23.resolve(localPath);
|
|
10933
|
+
const relative6 = path23.relative(root, dest);
|
|
10934
|
+
if (relative6.startsWith("..") || path23.isAbsolute(relative6)) {
|
|
10659
10935
|
throw new FsError({
|
|
10660
10936
|
message: `Refusing CloudSync path outside category root: ${remotePath}`,
|
|
10661
10937
|
code: ERROR_CODES.FS_DELETE_FAILED,
|
|
@@ -10794,7 +11070,86 @@ function resolveSessionLoggingConfig(cfg) {
|
|
|
10794
11070
|
}
|
|
10795
11071
|
};
|
|
10796
11072
|
}
|
|
10797
|
-
|
|
10798
|
-
|
|
11073
|
+
export {
|
|
11074
|
+
ALL_SYNC_CATEGORIES,
|
|
11075
|
+
AgentStatusTracker,
|
|
11076
|
+
AnnotationsStore,
|
|
11077
|
+
CORE_RECONSTRUCT_EVENTS,
|
|
11078
|
+
CloudSync,
|
|
11079
|
+
ConfigMigrationError,
|
|
11080
|
+
DEFAULT_CONFIG_MIGRATIONS,
|
|
11081
|
+
DefaultAttachmentStore,
|
|
11082
|
+
DefaultConfigLoader,
|
|
11083
|
+
DefaultConfigStore,
|
|
11084
|
+
DefaultMemoryStore,
|
|
11085
|
+
DefaultPromptStore,
|
|
11086
|
+
DefaultSessionReader,
|
|
11087
|
+
DefaultSessionRewinder,
|
|
11088
|
+
DefaultSessionStore,
|
|
11089
|
+
DirectorStateCheckpoint,
|
|
11090
|
+
FileMemoryBackend,
|
|
11091
|
+
FleetNotifier,
|
|
11092
|
+
GraphMemoryBackend,
|
|
11093
|
+
INPUT_HISTORY_DEFAULT_MAX,
|
|
11094
|
+
InputHistoryStore,
|
|
11095
|
+
MAX_JOURNAL_ENTRIES,
|
|
11096
|
+
MAX_PROGRESS_HISTORY,
|
|
11097
|
+
PromptUsageStore,
|
|
11098
|
+
QueueStore,
|
|
11099
|
+
RecoveryLock,
|
|
11100
|
+
ReplayLogStore,
|
|
11101
|
+
STANDARD_AUDIT_EVENTS,
|
|
11102
|
+
SessionAnalyzer,
|
|
11103
|
+
SessionCheckpointCas,
|
|
11104
|
+
SessionMemoryConsolidator,
|
|
11105
|
+
SessionRecovery,
|
|
11106
|
+
SessionRegistry,
|
|
11107
|
+
ToolAuditLog,
|
|
11108
|
+
addPlanItem,
|
|
11109
|
+
appendJournal,
|
|
11110
|
+
attachPlanCheckpoint,
|
|
11111
|
+
attachTodosCheckpoint,
|
|
11112
|
+
clearPlan,
|
|
11113
|
+
createSessionEventBridge,
|
|
11114
|
+
deriveTodosFromPlanItem,
|
|
11115
|
+
emptyGoal,
|
|
11116
|
+
emptyPlan,
|
|
11117
|
+
emptyTaskFile,
|
|
11118
|
+
formatGoal,
|
|
11119
|
+
formatPlan,
|
|
11120
|
+
formatPlanTemplates,
|
|
11121
|
+
generateSessionId,
|
|
11122
|
+
getPlanTemplate,
|
|
11123
|
+
getSessionRegistry,
|
|
11124
|
+
goalFilePath,
|
|
11125
|
+
hasSessionRegistry,
|
|
11126
|
+
listPlanTemplates,
|
|
11127
|
+
loadCompletedWorkCheckpoint,
|
|
11128
|
+
loadDirectorState,
|
|
11129
|
+
loadGoal,
|
|
11130
|
+
loadPlan,
|
|
11131
|
+
loadTasks,
|
|
11132
|
+
loadTodosCheckpoint,
|
|
11133
|
+
migratePromptEntry,
|
|
11134
|
+
mutatePlan,
|
|
11135
|
+
mutateTasks,
|
|
11136
|
+
parseEntries,
|
|
11137
|
+
parseProgressFromText,
|
|
11138
|
+
promptChecksum,
|
|
11139
|
+
recordProgress,
|
|
11140
|
+
removePlanItem,
|
|
11141
|
+
resolveAuditLevel,
|
|
11142
|
+
resolveSessionLoggingConfig,
|
|
11143
|
+
runConfigMigrations,
|
|
11144
|
+
sanitizeModel,
|
|
11145
|
+
saveCompletedWorkCheckpoint,
|
|
11146
|
+
saveGoal,
|
|
11147
|
+
savePlan,
|
|
11148
|
+
saveTasks,
|
|
11149
|
+
saveTodosCheckpoint,
|
|
11150
|
+
setPlanItemStatus,
|
|
11151
|
+
setProgress,
|
|
11152
|
+
summarizeUsage,
|
|
11153
|
+
watchProviderConfig
|
|
11154
|
+
};
|
|
10799
11155
|
//# sourceMappingURL=index.js.map
|
|
10800
|
-
//# sourceMappingURL=index.js.map
|