@wrongstack/core 0.284.1 → 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/defaults/index.js
CHANGED
|
@@ -1,41 +1,31 @@
|
|
|
1
|
-
import * as crypto from 'crypto';
|
|
2
|
-
import { randomUUID, createHash, randomInt, randomBytes, createCipheriv, createDecipheriv, scryptSync } from 'crypto';
|
|
3
|
-
import * as fsp9 from 'fs/promises';
|
|
4
|
-
import * as path4 from 'path';
|
|
5
|
-
import { isAbsolute, resolve } from 'path';
|
|
6
|
-
import * as os from 'os';
|
|
7
|
-
import { hostname } from 'os';
|
|
8
|
-
import * as fs11 from 'fs';
|
|
9
|
-
import { readFileSync, statSync, createReadStream, existsSync, openSync, writeSync, fsyncSync, closeSync } from 'fs';
|
|
10
|
-
import { fileURLToPath } from 'url';
|
|
11
|
-
import { EventEmitter } from 'events';
|
|
12
|
-
import { listReadyTasks, claimReadyTask, updateTaskAssignment } from '@wrongstack/kanban';
|
|
13
|
-
import { createInterface } from 'readline';
|
|
14
|
-
import { execFile, spawn } from 'child_process';
|
|
15
|
-
import { promisify, isDeepStrictEqual } from 'util';
|
|
16
|
-
|
|
17
1
|
// src/coordination/agent-bridge.ts
|
|
2
|
+
import { randomUUID } from "node:crypto";
|
|
18
3
|
|
|
19
4
|
// src/utils/assert-never.ts
|
|
20
5
|
function assertNever(x, message) {
|
|
21
6
|
const err = new Error(
|
|
22
|
-
`Unhandled case: ${JSON.stringify(x)}`
|
|
7
|
+
message ?? `Unhandled case: ${JSON.stringify(x)}`
|
|
23
8
|
);
|
|
24
9
|
err.name = "AssertNeverError";
|
|
25
10
|
throw err;
|
|
26
11
|
}
|
|
12
|
+
|
|
13
|
+
// src/utils/atomic-write.ts
|
|
14
|
+
import { randomBytes } from "node:crypto";
|
|
15
|
+
import * as fs from "node:fs/promises";
|
|
16
|
+
import * as path from "node:path";
|
|
27
17
|
async function atomicWrite(targetPath, content, opts = {}) {
|
|
28
|
-
const dir =
|
|
29
|
-
await
|
|
30
|
-
const tmp =
|
|
18
|
+
const dir = path.dirname(targetPath);
|
|
19
|
+
await fs.mkdir(dir, { recursive: true });
|
|
20
|
+
const tmp = path.join(dir, `.${path.basename(targetPath)}.${randomBytes(6).toString("hex")}.tmp`);
|
|
31
21
|
try {
|
|
32
22
|
if (typeof content === "string") {
|
|
33
|
-
await
|
|
23
|
+
await fs.writeFile(tmp, content, { flag: "wx", encoding: opts.encoding ?? "utf8" });
|
|
34
24
|
} else {
|
|
35
|
-
await
|
|
25
|
+
await fs.writeFile(tmp, content, { flag: "wx" });
|
|
36
26
|
}
|
|
37
27
|
try {
|
|
38
|
-
const fh = await
|
|
28
|
+
const fh = await fs.open(tmp, "r+");
|
|
39
29
|
try {
|
|
40
30
|
await fh.sync();
|
|
41
31
|
} finally {
|
|
@@ -45,56 +35,56 @@ async function atomicWrite(targetPath, content, opts = {}) {
|
|
|
45
35
|
}
|
|
46
36
|
let mode;
|
|
47
37
|
try {
|
|
48
|
-
const stat13 = await
|
|
38
|
+
const stat13 = await fs.stat(targetPath);
|
|
49
39
|
mode = stat13.mode & 511;
|
|
50
40
|
} catch {
|
|
51
41
|
mode = opts.mode;
|
|
52
42
|
}
|
|
53
43
|
if (mode !== void 0) {
|
|
54
|
-
await
|
|
44
|
+
await fs.chmod(tmp, mode);
|
|
55
45
|
}
|
|
56
46
|
await renameWithRetry(tmp, targetPath);
|
|
57
47
|
if (mode !== void 0 && process.platform === "win32") {
|
|
58
48
|
try {
|
|
59
|
-
await
|
|
49
|
+
await fs.chmod(targetPath, mode);
|
|
60
50
|
} catch {
|
|
61
51
|
}
|
|
62
52
|
}
|
|
63
53
|
} catch (err) {
|
|
64
54
|
try {
|
|
65
|
-
await
|
|
55
|
+
await fs.unlink(tmp);
|
|
66
56
|
} catch {
|
|
67
57
|
}
|
|
68
58
|
throw err;
|
|
69
59
|
}
|
|
70
60
|
}
|
|
71
61
|
async function ensureDir(dir) {
|
|
72
|
-
await
|
|
62
|
+
await fs.mkdir(dir, { recursive: true });
|
|
73
63
|
}
|
|
74
64
|
async function withFileLock(targetPath, fn, opts = {}) {
|
|
75
|
-
const dir =
|
|
76
|
-
await
|
|
77
|
-
const lockPath =
|
|
65
|
+
const dir = path.dirname(targetPath);
|
|
66
|
+
await fs.mkdir(dir, { recursive: true });
|
|
67
|
+
const lockPath = path.join(dir, `.${path.basename(targetPath)}.lock`);
|
|
78
68
|
const timeoutMs = opts.timeoutMs ?? 5e3;
|
|
79
69
|
const staleMs = opts.staleMs ?? 3e4;
|
|
80
70
|
const started = Date.now();
|
|
81
71
|
let handle;
|
|
82
72
|
for (; ; ) {
|
|
83
73
|
try {
|
|
84
|
-
handle = await
|
|
74
|
+
handle = await fs.open(lockPath, "wx");
|
|
85
75
|
await handle.writeFile(`${process.pid}:${Date.now()}`);
|
|
86
76
|
break;
|
|
87
77
|
} catch (err) {
|
|
88
78
|
const code = err.code;
|
|
89
79
|
if (code === "ENOENT") {
|
|
90
|
-
await
|
|
80
|
+
await fs.mkdir(dir, { recursive: true });
|
|
91
81
|
continue;
|
|
92
82
|
}
|
|
93
83
|
if (code !== "EEXIST") throw err;
|
|
94
84
|
try {
|
|
95
|
-
const stat13 = await
|
|
85
|
+
const stat13 = await fs.stat(lockPath);
|
|
96
86
|
if (Date.now() - stat13.mtimeMs > staleMs) {
|
|
97
|
-
await
|
|
87
|
+
await fs.unlink(lockPath);
|
|
98
88
|
continue;
|
|
99
89
|
}
|
|
100
90
|
} catch {
|
|
@@ -108,7 +98,7 @@ async function withFileLock(targetPath, fn, opts = {}) {
|
|
|
108
98
|
context: { timeoutMs }
|
|
109
99
|
});
|
|
110
100
|
}
|
|
111
|
-
await new Promise((
|
|
101
|
+
await new Promise((resolve12) => setTimeout(resolve12, 25));
|
|
112
102
|
}
|
|
113
103
|
}
|
|
114
104
|
try {
|
|
@@ -119,7 +109,7 @@ async function withFileLock(targetPath, fn, opts = {}) {
|
|
|
119
109
|
} catch {
|
|
120
110
|
}
|
|
121
111
|
try {
|
|
122
|
-
await
|
|
112
|
+
await fs.unlink(lockPath);
|
|
123
113
|
} catch {
|
|
124
114
|
}
|
|
125
115
|
}
|
|
@@ -127,14 +117,14 @@ async function withFileLock(targetPath, fn, opts = {}) {
|
|
|
127
117
|
var TRANSIENT_RENAME_CODES = /* @__PURE__ */ new Set(["EPERM", "EBUSY", "EACCES", "ENOTEMPTY"]);
|
|
128
118
|
async function renameWithRetry(from, to) {
|
|
129
119
|
if (process.platform !== "win32") {
|
|
130
|
-
await
|
|
120
|
+
await fs.rename(from, to);
|
|
131
121
|
return;
|
|
132
122
|
}
|
|
133
123
|
const delays = [10, 25, 60, 120, 250];
|
|
134
124
|
let lastErr;
|
|
135
125
|
for (let i = 0; i <= delays.length; i++) {
|
|
136
126
|
try {
|
|
137
|
-
await
|
|
127
|
+
await fs.rename(from, to);
|
|
138
128
|
return;
|
|
139
129
|
} catch (err) {
|
|
140
130
|
lastErr = err;
|
|
@@ -142,7 +132,7 @@ async function renameWithRetry(from, to) {
|
|
|
142
132
|
if (!code || !TRANSIENT_RENAME_CODES.has(code) || i === delays.length) {
|
|
143
133
|
throw err;
|
|
144
134
|
}
|
|
145
|
-
await new Promise((
|
|
135
|
+
await new Promise((resolve12) => setTimeout(resolve12, delays[i]));
|
|
146
136
|
}
|
|
147
137
|
}
|
|
148
138
|
throw lastErr;
|
|
@@ -222,8 +212,9 @@ function sanitizeNodeOptions(value) {
|
|
|
222
212
|
}
|
|
223
213
|
return kept.join(" ");
|
|
224
214
|
}
|
|
215
|
+
var gitIdentity = null;
|
|
225
216
|
function buildChildEnv(optsOrSessionId) {
|
|
226
|
-
const opts = {};
|
|
217
|
+
const opts = typeof optsOrSessionId === "string" ? { sessionId: optsOrSessionId } : optsOrSessionId ?? {};
|
|
227
218
|
const hasOwn = Object.hasOwn(process.env, "WRONGSTACK_CHILD_ENV_PASSTHROUGH");
|
|
228
219
|
const legacyHasOwn = Object.hasOwn(process.env, "WRONGSTACK_BASH_ENV_PASSTHROUGH");
|
|
229
220
|
const passthrough = hasOwn && process.env["WRONGSTACK_CHILD_ENV_PASSTHROUGH"] === "1" || legacyHasOwn && process.env["WRONGSTACK_BASH_ENV_PASSTHROUGH"] === "1";
|
|
@@ -261,6 +252,16 @@ function buildChildEnv(optsOrSessionId) {
|
|
|
261
252
|
out[k] = v;
|
|
262
253
|
}
|
|
263
254
|
}
|
|
255
|
+
if (gitIdentity) {
|
|
256
|
+
if (gitIdentity.name) {
|
|
257
|
+
out["GIT_AUTHOR_NAME"] = gitIdentity.name;
|
|
258
|
+
out["GIT_COMMITTER_NAME"] = gitIdentity.name;
|
|
259
|
+
}
|
|
260
|
+
if (gitIdentity.email) {
|
|
261
|
+
out["GIT_AUTHOR_EMAIL"] = gitIdentity.email;
|
|
262
|
+
out["GIT_COMMITTER_EMAIL"] = gitIdentity.email;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
264
265
|
if (opts.extra) {
|
|
265
266
|
Object.assign(out, opts.extra);
|
|
266
267
|
}
|
|
@@ -273,12 +274,18 @@ var hasStdout = () => typeof process !== "undefined" && !!process.stdout;
|
|
|
273
274
|
function isStdoutTTY() {
|
|
274
275
|
return hasStdout() && Boolean(process.stdout.isTTY);
|
|
275
276
|
}
|
|
277
|
+
var activeOutputGuard = null;
|
|
276
278
|
function writeTo(s, stream) {
|
|
277
279
|
if (!stream || typeof stream.write !== "function") return false;
|
|
278
|
-
|
|
280
|
+
const guard = activeOutputGuard;
|
|
281
|
+
if (!guard) {
|
|
279
282
|
stream.write(s);
|
|
280
283
|
return true;
|
|
281
284
|
}
|
|
285
|
+
guard.suspend();
|
|
286
|
+
stream.write(s);
|
|
287
|
+
guard.resume();
|
|
288
|
+
return true;
|
|
282
289
|
}
|
|
283
290
|
function writeErr(s, stream = process.stderr) {
|
|
284
291
|
return writeTo(s, stream);
|
|
@@ -315,6 +322,8 @@ var color = {
|
|
|
315
322
|
bgRed: wrap("41", "49"),
|
|
316
323
|
bgGreen: wrap("42", "49")
|
|
317
324
|
};
|
|
325
|
+
|
|
326
|
+
// src/utils/context-evidence.ts
|
|
318
327
|
var MAX_DIGEST_CHARS = 4e3;
|
|
319
328
|
function createContextEvidenceState() {
|
|
320
329
|
return {
|
|
@@ -458,12 +467,16 @@ function toErrorMessage(err) {
|
|
|
458
467
|
// src/utils/expect-defined.ts
|
|
459
468
|
function expectDefined(value, label) {
|
|
460
469
|
if (value === null || value === void 0) {
|
|
461
|
-
const err = new Error("Expected value to be defined");
|
|
470
|
+
const err = new Error(label ? `Expected ${label} to be defined` : "Expected value to be defined");
|
|
462
471
|
err.name = "ExpectDefinedError";
|
|
463
472
|
throw err;
|
|
464
473
|
}
|
|
465
474
|
return value;
|
|
466
475
|
}
|
|
476
|
+
|
|
477
|
+
// src/utils/glob-expand.ts
|
|
478
|
+
import * as fsp from "node:fs/promises";
|
|
479
|
+
import { isAbsolute, resolve } from "node:path";
|
|
467
480
|
var GLOB_CHARS = /* @__PURE__ */ new Set(["*", "?", "["]);
|
|
468
481
|
var IS_WINDOWS = process.platform === "win32";
|
|
469
482
|
var SEP = IS_WINDOWS ? "\\" : "/";
|
|
@@ -529,7 +542,7 @@ async function expandGlob(pattern) {
|
|
|
529
542
|
async function walk3(dir, pat) {
|
|
530
543
|
let entries;
|
|
531
544
|
try {
|
|
532
|
-
entries = await
|
|
545
|
+
entries = await fsp.readdir(dir);
|
|
533
546
|
} catch {
|
|
534
547
|
return;
|
|
535
548
|
}
|
|
@@ -551,7 +564,7 @@ async function expandGlob(pattern) {
|
|
|
551
564
|
for (const e of entries) {
|
|
552
565
|
const full = `${dir}${SEP}${e}`;
|
|
553
566
|
try {
|
|
554
|
-
const stat13 = await
|
|
567
|
+
const stat13 = await fsp.stat(full);
|
|
555
568
|
if (stat13.isDirectory()) await walk3(full, rest);
|
|
556
569
|
} catch {
|
|
557
570
|
}
|
|
@@ -569,7 +582,7 @@ async function expandGlob(pattern) {
|
|
|
569
582
|
if (entries.includes(seg)) {
|
|
570
583
|
const full = `${dir}${SEP}${seg}`;
|
|
571
584
|
try {
|
|
572
|
-
const stat13 = await
|
|
585
|
+
const stat13 = await fsp.stat(full);
|
|
573
586
|
if (stat13.isDirectory()) await walk3(full, rest);
|
|
574
587
|
} catch {
|
|
575
588
|
}
|
|
@@ -761,10 +774,10 @@ function validateAgainstSchema(value, schema) {
|
|
|
761
774
|
return { ok: errors.length === 0, errors };
|
|
762
775
|
}
|
|
763
776
|
var MAX_SCHEMA_DEPTH = 64;
|
|
764
|
-
function walk(value, schema,
|
|
777
|
+
function walk(value, schema, path29, errors, depth) {
|
|
765
778
|
if (depth > MAX_SCHEMA_DEPTH) {
|
|
766
779
|
errors.push({
|
|
767
|
-
path:
|
|
780
|
+
path: path29 || "<root>",
|
|
768
781
|
message: `schema nesting exceeds maximum depth (${MAX_SCHEMA_DEPTH})`
|
|
769
782
|
});
|
|
770
783
|
return;
|
|
@@ -772,7 +785,7 @@ function walk(value, schema, path31, errors, depth) {
|
|
|
772
785
|
if (schema.enum !== void 0) {
|
|
773
786
|
if (!enumIncludes(schema.enum, value)) {
|
|
774
787
|
errors.push({
|
|
775
|
-
path:
|
|
788
|
+
path: path29 || "<root>",
|
|
776
789
|
message: `expected one of ${JSON.stringify(schema.enum)}, got ${JSON.stringify(value)}`
|
|
777
790
|
});
|
|
778
791
|
return;
|
|
@@ -781,7 +794,7 @@ function walk(value, schema, path31, errors, depth) {
|
|
|
781
794
|
if (typeof schema.type === "string") {
|
|
782
795
|
if (!checkType(value, schema.type)) {
|
|
783
796
|
errors.push({
|
|
784
|
-
path:
|
|
797
|
+
path: path29 || "<root>",
|
|
785
798
|
message: `expected ${schema.type}, got ${describeType(value)} (${previewValue(value)})`
|
|
786
799
|
});
|
|
787
800
|
return;
|
|
@@ -793,7 +806,7 @@ function walk(value, schema, path31, errors, depth) {
|
|
|
793
806
|
if (!(req in obj)) {
|
|
794
807
|
const expected = schema.properties?.[req]?.type;
|
|
795
808
|
errors.push({
|
|
796
|
-
path: joinPath(
|
|
809
|
+
path: joinPath(path29, req),
|
|
797
810
|
message: `required property missing${typeof expected === "string" ? ` (expected ${expected})` : ""}`
|
|
798
811
|
});
|
|
799
812
|
}
|
|
@@ -801,14 +814,14 @@ function walk(value, schema, path31, errors, depth) {
|
|
|
801
814
|
if (schema.properties) {
|
|
802
815
|
for (const [key, subSchema] of Object.entries(schema.properties)) {
|
|
803
816
|
if (key in obj) {
|
|
804
|
-
walk(obj[key], subSchema, joinPath(
|
|
817
|
+
walk(obj[key], subSchema, joinPath(path29, key), errors, depth + 1);
|
|
805
818
|
}
|
|
806
819
|
}
|
|
807
820
|
}
|
|
808
821
|
}
|
|
809
822
|
if (schema.type === "array" && Array.isArray(value) && schema.items) {
|
|
810
823
|
for (let i = 0; i < value.length; i++) {
|
|
811
|
-
walk(value[i], schema.items, `${
|
|
824
|
+
walk(value[i], schema.items, `${path29}[${i}]`, errors, depth + 1);
|
|
812
825
|
}
|
|
813
826
|
}
|
|
814
827
|
}
|
|
@@ -1164,13 +1177,16 @@ function safeStringify(value, pretty = false) {
|
|
|
1164
1177
|
});
|
|
1165
1178
|
}
|
|
1166
1179
|
}
|
|
1180
|
+
|
|
1181
|
+
// src/utils/session-scoped-path.ts
|
|
1182
|
+
import * as path2 from "node:path";
|
|
1167
1183
|
function sessionScopedPath(dir, sessionId, suffix) {
|
|
1168
1184
|
if (!sessionId || sessionId.includes("\\") || sessionId.includes("..")) {
|
|
1169
1185
|
throw invalid(sessionId);
|
|
1170
1186
|
}
|
|
1171
|
-
const resolved =
|
|
1172
|
-
const rel =
|
|
1173
|
-
if (rel.startsWith("..") ||
|
|
1187
|
+
const resolved = path2.resolve(dir, `${sessionId}${suffix}`);
|
|
1188
|
+
const rel = path2.relative(path2.resolve(dir), resolved);
|
|
1189
|
+
if (rel.startsWith("..") || path2.isAbsolute(rel)) {
|
|
1174
1190
|
throw invalid(sessionId);
|
|
1175
1191
|
}
|
|
1176
1192
|
return resolved;
|
|
@@ -1188,6 +1204,9 @@ function invalid(sessionId) {
|
|
|
1188
1204
|
function slugify(name, fallback = "prompt", maxLen = 64) {
|
|
1189
1205
|
return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, maxLen).replace(/-+$/g, "") || fallback;
|
|
1190
1206
|
}
|
|
1207
|
+
|
|
1208
|
+
// src/utils/ulid.ts
|
|
1209
|
+
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
1191
1210
|
var ENCODING = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
|
|
1192
1211
|
var ENCODING_LEN = ENCODING.length;
|
|
1193
1212
|
var TIME_LEN = 10;
|
|
@@ -1203,7 +1222,7 @@ function encodeTime(now, len) {
|
|
|
1203
1222
|
return str;
|
|
1204
1223
|
}
|
|
1205
1224
|
function encodeRandom(len) {
|
|
1206
|
-
const bytes =
|
|
1225
|
+
const bytes = randomBytes2(len);
|
|
1207
1226
|
let str = "";
|
|
1208
1227
|
for (let i = 0; i < len; i++) {
|
|
1209
1228
|
str += ENCODING[bytes[i] % ENCODING_LEN];
|
|
@@ -1216,7 +1235,7 @@ function ulid(seedTime = Date.now()) {
|
|
|
1216
1235
|
|
|
1217
1236
|
// src/utils/sleep.ts
|
|
1218
1237
|
function sleep(ms) {
|
|
1219
|
-
return new Promise((
|
|
1238
|
+
return new Promise((resolve12) => setTimeout(resolve12, ms));
|
|
1220
1239
|
}
|
|
1221
1240
|
|
|
1222
1241
|
// src/utils/string.ts
|
|
@@ -2178,12 +2197,17 @@ function normalizeToolResultRenderMode(value) {
|
|
|
2178
2197
|
function resolveToolResultRenderMode(modes, toolName) {
|
|
2179
2198
|
return normalizeToolResultRenderMode(modes?.[toolName]) ?? DEFAULT_TOOL_RESULT_RENDER_MODE;
|
|
2180
2199
|
}
|
|
2200
|
+
|
|
2201
|
+
// src/utils/wstack-paths.ts
|
|
2202
|
+
import { createHash } from "node:crypto";
|
|
2203
|
+
import * as os from "node:os";
|
|
2204
|
+
import * as path3 from "node:path";
|
|
2181
2205
|
function projectHash(absRoot) {
|
|
2182
|
-
return createHash("sha256").update(
|
|
2206
|
+
return createHash("sha256").update(path3.resolve(absRoot)).digest("hex").slice(0, 12);
|
|
2183
2207
|
}
|
|
2184
2208
|
function projectSlug(absRoot) {
|
|
2185
|
-
const base = slugify2(
|
|
2186
|
-
const hash = createHash("sha256").update(
|
|
2209
|
+
const base = slugify2(path3.basename(absRoot));
|
|
2210
|
+
const hash = createHash("sha256").update(path3.resolve(absRoot)).digest("hex").slice(0, 6);
|
|
2187
2211
|
return `${base}-${hash}`;
|
|
2188
2212
|
}
|
|
2189
2213
|
function slugify2(name) {
|
|
@@ -2191,61 +2215,61 @@ function slugify2(name) {
|
|
|
2191
2215
|
}
|
|
2192
2216
|
function wstackGlobalRoot() {
|
|
2193
2217
|
const fromEnv = process.env["WRONGSTACK_HOME"];
|
|
2194
|
-
if (fromEnv && fromEnv.trim().length > 0) return
|
|
2195
|
-
return
|
|
2218
|
+
if (fromEnv && fromEnv.trim().length > 0) return path3.resolve(fromEnv);
|
|
2219
|
+
return path3.join(os.homedir(), ".wrongstack");
|
|
2196
2220
|
}
|
|
2197
2221
|
function resolveWstackPaths(opts) {
|
|
2198
|
-
const globalRoot = opts.globalRoot ?? (opts.userHome ?
|
|
2222
|
+
const globalRoot = opts.globalRoot ?? (opts.userHome ? path3.join(opts.userHome, ".wrongstack") : wstackGlobalRoot());
|
|
2199
2223
|
const homeDir = opts.userHome ?? os.homedir();
|
|
2200
2224
|
const hash = projectHash(opts.projectRoot);
|
|
2201
2225
|
const slug = projectSlug(opts.projectRoot);
|
|
2202
|
-
const projectDir =
|
|
2226
|
+
const projectDir = path3.join(globalRoot, "projects", slug);
|
|
2203
2227
|
return {
|
|
2204
2228
|
globalRoot,
|
|
2205
2229
|
projectRoot: opts.projectRoot,
|
|
2206
2230
|
homeDir,
|
|
2207
2231
|
configDir: globalRoot,
|
|
2208
|
-
globalConfig:
|
|
2209
|
-
secretsKey:
|
|
2210
|
-
globalMemory:
|
|
2211
|
-
globalSkills:
|
|
2212
|
-
globalClaudeSkills:
|
|
2213
|
-
globalDesignKits:
|
|
2214
|
-
globalPrompts:
|
|
2215
|
-
globalInstructions:
|
|
2216
|
-
promptUsage:
|
|
2217
|
-
cacheDir:
|
|
2218
|
-
modelsCache:
|
|
2219
|
-
modelsOverlayCache:
|
|
2220
|
-
historyFile:
|
|
2221
|
-
logFile:
|
|
2232
|
+
globalConfig: path3.join(globalRoot, "config.json"),
|
|
2233
|
+
secretsKey: path3.join(globalRoot, ".key"),
|
|
2234
|
+
globalMemory: path3.join(globalRoot, "memory.md"),
|
|
2235
|
+
globalSkills: path3.join(globalRoot, "skills"),
|
|
2236
|
+
globalClaudeSkills: path3.join(homeDir, ".claude", "skills"),
|
|
2237
|
+
globalDesignKits: path3.join(globalRoot, "design-kits"),
|
|
2238
|
+
globalPrompts: path3.join(globalRoot, "prompts"),
|
|
2239
|
+
globalInstructions: path3.join(globalRoot, "instructions"),
|
|
2240
|
+
promptUsage: path3.join(globalRoot, "prompt-usage.json"),
|
|
2241
|
+
cacheDir: path3.join(globalRoot, "cache"),
|
|
2242
|
+
modelsCache: path3.join(globalRoot, "cache", "models.dev.json"),
|
|
2243
|
+
modelsOverlayCache: path3.join(globalRoot, "cache", "models-overlay.json"),
|
|
2244
|
+
historyFile: path3.join(globalRoot, "history"),
|
|
2245
|
+
logFile: path3.join(globalRoot, "logs", "wrongstack.log"),
|
|
2222
2246
|
projectDir,
|
|
2223
|
-
projectCodebaseIndex:
|
|
2224
|
-
projectMemory:
|
|
2225
|
-
projectSessions:
|
|
2226
|
-
projectTrust:
|
|
2227
|
-
projectMeta:
|
|
2228
|
-
projectLocalConfig:
|
|
2229
|
-
inProjectConfig:
|
|
2230
|
-
inProjectAgentsFile:
|
|
2231
|
-
inProjectSkills:
|
|
2232
|
-
inProjectClaudeSkills:
|
|
2233
|
-
inProjectPrompts:
|
|
2234
|
-
inProjectInstructions:
|
|
2235
|
-
inProjectDesignKits:
|
|
2236
|
-
inProjectWorktrees:
|
|
2247
|
+
projectCodebaseIndex: path3.join(projectDir, "codebase-index"),
|
|
2248
|
+
projectMemory: path3.join(projectDir, "memory.md"),
|
|
2249
|
+
projectSessions: path3.join(projectDir, "sessions"),
|
|
2250
|
+
projectTrust: path3.join(projectDir, "trust.json"),
|
|
2251
|
+
projectMeta: path3.join(projectDir, "meta.json"),
|
|
2252
|
+
projectLocalConfig: path3.join(projectDir, "config.local.json"),
|
|
2253
|
+
inProjectConfig: path3.join(opts.projectRoot, ".wrongstack", "config.json"),
|
|
2254
|
+
inProjectAgentsFile: path3.join(opts.projectRoot, ".wrongstack", "AGENTS.md"),
|
|
2255
|
+
inProjectSkills: path3.join(opts.projectRoot, ".wrongstack", "skills"),
|
|
2256
|
+
inProjectClaudeSkills: path3.join(opts.projectRoot, ".claude", "skills"),
|
|
2257
|
+
inProjectPrompts: path3.join(opts.projectRoot, ".wrongstack", "prompts"),
|
|
2258
|
+
inProjectInstructions: path3.join(opts.projectRoot, ".wrongstack", "instructions"),
|
|
2259
|
+
inProjectDesignKits: path3.join(opts.projectRoot, ".wrongstack", "design-kits"),
|
|
2260
|
+
inProjectWorktrees: path3.join(opts.projectRoot, ".wrongstack", "worktrees"),
|
|
2237
2261
|
projectHash: hash,
|
|
2238
2262
|
projectSlug: slug,
|
|
2239
|
-
projectGoal:
|
|
2240
|
-
projectInputHistory:
|
|
2241
|
-
projectSpecs:
|
|
2242
|
-
projectTaskGraphs:
|
|
2243
|
-
projectSddSession:
|
|
2244
|
-
projectPlan:
|
|
2245
|
-
projectAutophase:
|
|
2246
|
-
projectSddBoards:
|
|
2247
|
-
syncConfig:
|
|
2248
|
-
projectStatus: (projectHash2) =>
|
|
2263
|
+
projectGoal: path3.join(projectDir, "goal.json"),
|
|
2264
|
+
projectInputHistory: path3.join(projectDir, "input-history.json"),
|
|
2265
|
+
projectSpecs: path3.join(projectDir, "specs"),
|
|
2266
|
+
projectTaskGraphs: path3.join(projectDir, "task-graphs"),
|
|
2267
|
+
projectSddSession: path3.join(projectDir, "sdd-session.json"),
|
|
2268
|
+
projectPlan: path3.join(projectDir, "plan.json"),
|
|
2269
|
+
projectAutophase: path3.join(projectDir, "autophase"),
|
|
2270
|
+
projectSddBoards: path3.join(projectDir, "sdd-boards"),
|
|
2271
|
+
syncConfig: path3.join(globalRoot, "sync.json"),
|
|
2272
|
+
projectStatus: (projectHash2) => path3.join(globalRoot, "projects", projectHash2, "status.json")
|
|
2249
2273
|
};
|
|
2250
2274
|
}
|
|
2251
2275
|
|
|
@@ -2538,7 +2562,7 @@ var InMemoryAgentBridge = class {
|
|
|
2538
2562
|
});
|
|
2539
2563
|
}
|
|
2540
2564
|
this.inflightGuards.add(correlationId);
|
|
2541
|
-
return new Promise((
|
|
2565
|
+
return new Promise((resolve12, reject) => {
|
|
2542
2566
|
const timer = setTimeout(() => {
|
|
2543
2567
|
this.inflightGuards.delete(correlationId);
|
|
2544
2568
|
this.pendingRequests.delete(correlationId);
|
|
@@ -2557,7 +2581,7 @@ var InMemoryAgentBridge = class {
|
|
|
2557
2581
|
return;
|
|
2558
2582
|
}
|
|
2559
2583
|
this.pendingRequests.set(correlationId, {
|
|
2560
|
-
resolve:
|
|
2584
|
+
resolve: resolve12,
|
|
2561
2585
|
reject,
|
|
2562
2586
|
timer
|
|
2563
2587
|
});
|
|
@@ -2906,13 +2930,13 @@ var SubagentBudget = class _SubagentBudget {
|
|
|
2906
2930
|
if (!bus?.hasListenerFor("budget.threshold_reached")) {
|
|
2907
2931
|
return Promise.resolve("stop");
|
|
2908
2932
|
}
|
|
2909
|
-
return new Promise((
|
|
2933
|
+
return new Promise((resolve12) => {
|
|
2910
2934
|
let resolved = false;
|
|
2911
2935
|
const respond = (d) => {
|
|
2912
2936
|
if (resolved) return;
|
|
2913
2937
|
resolved = true;
|
|
2914
2938
|
clearTimeout(fallback);
|
|
2915
|
-
|
|
2939
|
+
resolve12(d);
|
|
2916
2940
|
};
|
|
2917
2941
|
const fallback = setTimeout(() => respond("stop"), _SubagentBudget.DECISION_TIMEOUT_MS);
|
|
2918
2942
|
const sessionId = this.currentSessionId();
|
|
@@ -3063,8 +3087,16 @@ var ToolCapabilities = {
|
|
|
3063
3087
|
FS_WRITE_OUTSIDE_PROJECT: "fs.write.outside-project",
|
|
3064
3088
|
/** Can perform outbound network requests. */
|
|
3065
3089
|
NET_OUTBOUND: "net.outbound",
|
|
3090
|
+
/** Can mutate in-memory session todos only. */
|
|
3091
|
+
SESSION_TODO: "session.todo",
|
|
3092
|
+
/** Can mutate in-memory session mode only. */
|
|
3093
|
+
SESSION_MODE: "session.mode",
|
|
3094
|
+
/** Can inspect registered tool metadata. */
|
|
3095
|
+
TOOL_META: "tool.meta",
|
|
3066
3096
|
/** Can invoke arbitrary registered tools through a meta-tool. */
|
|
3067
3097
|
TOOL_MUTATE_ANY: "tool.mutate.any",
|
|
3098
|
+
/** Can read persistent memory. */
|
|
3099
|
+
MEMORY_READ: "memory.read",
|
|
3068
3100
|
/** Can write persistent memory. */
|
|
3069
3101
|
MEMORY_WRITE: "memory.write",
|
|
3070
3102
|
/** Can delete persistent memory. */
|
|
@@ -3077,6 +3109,12 @@ var ToolCapabilities = {
|
|
|
3077
3109
|
COORDINATION_FLEET_READ: "coordination.fleet.read",
|
|
3078
3110
|
/** Can publish attributed, schema-checked events onto the fleet bus. */
|
|
3079
3111
|
COORDINATION_FLEET_EMIT: "coordination.fleet.emit",
|
|
3112
|
+
/** Can submit a task-local structured result to the parent Director. */
|
|
3113
|
+
COORDINATION_RESULT_SUBMIT: "coordination.result.submit",
|
|
3114
|
+
/** Can read or write inter-agent mailbox messages. */
|
|
3115
|
+
COORDINATION_MAIL: "coordination.mail",
|
|
3116
|
+
/** Can schedule, inspect, or cancel in-session cron jobs. */
|
|
3117
|
+
COORDINATION_CRON: "coordination.cron",
|
|
3080
3118
|
/** Can mutate global or session configuration / trust state. */
|
|
3081
3119
|
CONFIG_MUTATE: "config.mutate",
|
|
3082
3120
|
/** Can install packages or run package managers with side effects. */
|
|
@@ -3096,6 +3134,22 @@ var DANGEROUS_FOR_SUBAGENTS = [
|
|
|
3096
3134
|
ToolCapabilities.CONFIG_MUTATE,
|
|
3097
3135
|
ToolCapabilities.PACKAGE_INSTALL
|
|
3098
3136
|
];
|
|
3137
|
+
var WIDE_SUBAGENT_CAPABILITIES = [
|
|
3138
|
+
ToolCapabilities.FS_READ,
|
|
3139
|
+
ToolCapabilities.FS_WRITE,
|
|
3140
|
+
ToolCapabilities.NET_OUTBOUND,
|
|
3141
|
+
ToolCapabilities.SESSION_TODO,
|
|
3142
|
+
ToolCapabilities.TOOL_META,
|
|
3143
|
+
ToolCapabilities.MEMORY_READ,
|
|
3144
|
+
ToolCapabilities.SHELL_ARBITRARY,
|
|
3145
|
+
ToolCapabilities.SHELL_RESTRICTED,
|
|
3146
|
+
ToolCapabilities.SHELL_EXEC,
|
|
3147
|
+
ToolCapabilities.PACKAGE_INSTALL,
|
|
3148
|
+
// Read-only fleet visibility (fleet_status) — peer awareness has no blast
|
|
3149
|
+
// radius and every fleet worker should coordinate around its peers.
|
|
3150
|
+
ToolCapabilities.COORDINATION_FLEET_READ,
|
|
3151
|
+
ToolCapabilities.COORDINATION_RESULT_SUBMIT
|
|
3152
|
+
];
|
|
3099
3153
|
function hasDangerousCapabilityForSubagents(toolOrCaps) {
|
|
3100
3154
|
if (!toolOrCaps) return false;
|
|
3101
3155
|
const input = toolOrCaps;
|
|
@@ -3453,6 +3507,12 @@ var TOOLS = {
|
|
|
3453
3507
|
/** Web research. */
|
|
3454
3508
|
research: ["read", "grep", "glob", "search", "fetch", "mailbox"]
|
|
3455
3509
|
};
|
|
3510
|
+
|
|
3511
|
+
// src/coordination/agents/agent-prompts.ts
|
|
3512
|
+
import { readFileSync, statSync } from "node:fs";
|
|
3513
|
+
import * as os2 from "node:os";
|
|
3514
|
+
import * as path4 from "node:path";
|
|
3515
|
+
import { fileURLToPath } from "node:url";
|
|
3456
3516
|
var promptCache = /* @__PURE__ */ new Map();
|
|
3457
3517
|
var candidateCache = /* @__PURE__ */ new Map();
|
|
3458
3518
|
function agentPrompt(id) {
|
|
@@ -3473,7 +3533,7 @@ function agentPrompt(id) {
|
|
|
3473
3533
|
return resolved;
|
|
3474
3534
|
}
|
|
3475
3535
|
function agentPromptDirCandidates(envDir) {
|
|
3476
|
-
const globalRoot = process.env["WRONGSTACK_HOME"] || path4.join(
|
|
3536
|
+
const globalRoot = process.env["WRONGSTACK_HOME"] || path4.join(os2.homedir(), ".wrongstack");
|
|
3477
3537
|
const candKey = `${envDir}\0${globalRoot}`;
|
|
3478
3538
|
const cached = candidateCache.get(candKey);
|
|
3479
3539
|
if (cached !== void 0) return cached;
|
|
@@ -5053,6 +5113,11 @@ function attachAutoExtend(events, policy = {}) {
|
|
|
5053
5113
|
};
|
|
5054
5114
|
}
|
|
5055
5115
|
|
|
5116
|
+
// src/coordination/delegate-tool.ts
|
|
5117
|
+
import * as fsp2 from "node:fs/promises";
|
|
5118
|
+
import * as path5 from "node:path";
|
|
5119
|
+
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
5120
|
+
|
|
5056
5121
|
// src/coordination/fleet.ts
|
|
5057
5122
|
var AUDIT_LOG_AGENT = {
|
|
5058
5123
|
id: "audit-log",
|
|
@@ -5201,10 +5266,10 @@ FLEET_ROSTER_BUDGETS["gemini-cli"] = { timeoutMs: 10 * 60 * 60 * 1e3, maxIterati
|
|
|
5201
5266
|
FLEET_ROSTER_BUDGETS["copilot"] = { timeoutMs: 10 * 60 * 60 * 1e3, maxIterations: 8e3, maxToolCalls: 2e4 };
|
|
5202
5267
|
FLEET_ROSTER_BUDGETS["openhands"] = { timeoutMs: 10 * 60 * 60 * 1e3, maxIterations: 8e3, maxToolCalls: 2e4 };
|
|
5203
5268
|
FLEET_ROSTER_BUDGETS["goose"] = { timeoutMs: 10 * 60 * 60 * 1e3, maxIterations: 8e3, maxToolCalls: 2e4 };
|
|
5204
|
-
|
|
5269
|
+
var FLEET_ROSTER_WITHACP = {
|
|
5205
5270
|
...FLEET_ROSTER,
|
|
5206
5271
|
...Object.fromEntries(ACP_AGENTS.map((a) => [a.role, a]))
|
|
5207
|
-
}
|
|
5272
|
+
};
|
|
5208
5273
|
|
|
5209
5274
|
// src/coordination/delegate-tool.ts
|
|
5210
5275
|
function createDelegateTool(opts) {
|
|
@@ -5274,17 +5339,25 @@ function createDelegateTool(opts) {
|
|
|
5274
5339
|
return {
|
|
5275
5340
|
name: "delegate",
|
|
5276
5341
|
description: "Hand a discrete piece of work to a dedicated subagent and wait for its result. The subagent has its own context, its own LLM call, and its own budget \u2014 use this when a task is self-contained, would otherwise blow up your context, or benefits from a specialized role (bug-hunter, security-scanner, refactor-planner, audit-log). For free-form coding tasks (not tied to a pre-defined role), pass `name` + `task` \u2014 the subagent runs as a general-purpose coding agent with a large default budget. YOU decide how big the budget is: pass `timeoutMs`, `maxIterations`, and `maxToolCalls` sized to the actual work. There is no hidden cap forcing a 3-minute / 80-iteration limit \u2014 if a monorepo audit needs 2 hours and 500 tool calls, ask for that. Call multiple delegates in parallel through the provider's parallel-tool-call surface to fan work out across roles.",
|
|
5277
|
-
usageHint: "Set `task` to a complete instruction. Either pick `role` from the roster (audit-log, bug-hunter, refactor-planner, security-scanner) or pass `name` to run a free-form coding agent. For non-trivial work, also pass `timeoutMs`, `maxIterations`, and `maxToolCalls`. Returns the subagent's `TaskResult` \u2014 including the textual `result`, iteration count, tool count, and duration.
|
|
5342
|
+
usageHint: "Set `task` to a complete instruction. Either pick `role` from the roster (audit-log, bug-hunter, refactor-planner, security-scanner) or pass `name` to run a free-form coding agent. For non-trivial work, also pass `timeoutMs`, `maxIterations`, and `maxToolCalls`. Returns the subagent's `TaskResult` \u2014 including the textual `result`, iteration count, tool count, and duration. Requires Director mode to be active in normal CLI sessions.",
|
|
5278
5343
|
permission: "auto",
|
|
5279
5344
|
mutating: false,
|
|
5280
5345
|
capabilities: [ToolCapabilities.SUBAGENT_SPAWN],
|
|
5281
5346
|
inputSchema,
|
|
5282
|
-
async execute(input) {
|
|
5347
|
+
async execute(input, _ctx, execOpts) {
|
|
5283
5348
|
const sessionId = opts.directorRunId;
|
|
5349
|
+
const abortSignal = execOpts?.signal;
|
|
5284
5350
|
const i = input ?? {};
|
|
5285
5351
|
if (typeof i.task !== "string" || !i.task.trim()) {
|
|
5286
5352
|
return { ok: false, error: "`task` is required." };
|
|
5287
5353
|
}
|
|
5354
|
+
if (abortSignal?.aborted) {
|
|
5355
|
+
return {
|
|
5356
|
+
ok: false,
|
|
5357
|
+
stopReason: "aborted",
|
|
5358
|
+
error: "Delegation cancelled before spawn \u2014 the run was interrupted."
|
|
5359
|
+
};
|
|
5360
|
+
}
|
|
5288
5361
|
const target = i.role ?? i.name ?? "subagent";
|
|
5289
5362
|
try {
|
|
5290
5363
|
let director = await opts.host.ensureDirector();
|
|
@@ -5349,14 +5422,16 @@ function createDelegateTool(opts) {
|
|
|
5349
5422
|
opts.events?.emit("delegate.started", { sessionId, target, task: i.task });
|
|
5350
5423
|
const subagentId = await director.spawn(cfg);
|
|
5351
5424
|
const taskId = await director.assign({
|
|
5352
|
-
id: `${
|
|
5425
|
+
id: `${randomUUID2()}`,
|
|
5353
5426
|
description: i.task,
|
|
5354
5427
|
subagentId
|
|
5355
5428
|
});
|
|
5356
5429
|
const dir = director;
|
|
5357
|
-
const result = await new Promise((
|
|
5430
|
+
const result = await new Promise((resolve12) => {
|
|
5358
5431
|
let settled = false;
|
|
5359
5432
|
let timer;
|
|
5433
|
+
let offAbort = () => {
|
|
5434
|
+
};
|
|
5360
5435
|
const finish = (value) => {
|
|
5361
5436
|
if (settled) return;
|
|
5362
5437
|
settled = true;
|
|
@@ -5364,7 +5439,8 @@ function createDelegateTool(opts) {
|
|
|
5364
5439
|
offTool();
|
|
5365
5440
|
offIter();
|
|
5366
5441
|
offProgress();
|
|
5367
|
-
|
|
5442
|
+
offAbort();
|
|
5443
|
+
resolve12(value);
|
|
5368
5444
|
};
|
|
5369
5445
|
const arm = () => {
|
|
5370
5446
|
if (timer) clearTimeout(timer);
|
|
@@ -5376,9 +5452,42 @@ function createDelegateTool(opts) {
|
|
|
5376
5452
|
const offTool = dir.fleet.filter("tool.executed", bump);
|
|
5377
5453
|
const offIter = dir.fleet.filter("iteration.started", bump);
|
|
5378
5454
|
const offProgress = dir.fleet.filter("tool.progress", bump);
|
|
5455
|
+
if (abortSignal) {
|
|
5456
|
+
const onAbortSignal = () => finish({ __aborted: true });
|
|
5457
|
+
abortSignal.addEventListener("abort", onAbortSignal, { once: true });
|
|
5458
|
+
offAbort = () => abortSignal.removeEventListener("abort", onAbortSignal);
|
|
5459
|
+
if (abortSignal.aborted) onAbortSignal();
|
|
5460
|
+
}
|
|
5379
5461
|
arm();
|
|
5380
5462
|
dir.awaitTasks([taskId]).then((r) => finish(r[0] ?? { __emptyResult: true })).catch(() => finish({ __timeout: true }));
|
|
5381
5463
|
});
|
|
5464
|
+
if ("__aborted" in result) {
|
|
5465
|
+
try {
|
|
5466
|
+
await dir.terminate(subagentId);
|
|
5467
|
+
} catch {
|
|
5468
|
+
}
|
|
5469
|
+
const partial2 = await readSubagentPartial(opts, subagentId);
|
|
5470
|
+
opts.events?.emit("delegate.completed", {
|
|
5471
|
+
sessionId,
|
|
5472
|
+
target,
|
|
5473
|
+
task: i.task,
|
|
5474
|
+
ok: false,
|
|
5475
|
+
status: "aborted",
|
|
5476
|
+
summary: `[${target}] aborted \u2014 the run was interrupted`,
|
|
5477
|
+
durationMs: 0,
|
|
5478
|
+
iterations: partial2?.events ?? 0,
|
|
5479
|
+
toolCalls: partial2?.toolUsesObserved ?? 0,
|
|
5480
|
+
subagentId
|
|
5481
|
+
});
|
|
5482
|
+
return {
|
|
5483
|
+
ok: false,
|
|
5484
|
+
stopReason: "aborted",
|
|
5485
|
+
error: "Delegated task aborted \u2014 the run was interrupted.",
|
|
5486
|
+
subagentId,
|
|
5487
|
+
taskId,
|
|
5488
|
+
partial: partial2
|
|
5489
|
+
};
|
|
5490
|
+
}
|
|
5382
5491
|
if ("__timeout" in result) {
|
|
5383
5492
|
const partial2 = await readSubagentPartial(opts, subagentId);
|
|
5384
5493
|
opts.events?.emit("delegate.completed", {
|
|
@@ -5505,7 +5614,7 @@ function instantiateRosterConfig(role, base) {
|
|
|
5505
5614
|
...withBudget,
|
|
5506
5615
|
// Give each spawn a fresh id so parallel or repeated delegates
|
|
5507
5616
|
// can use the same role safely.
|
|
5508
|
-
id: `${role}-${
|
|
5617
|
+
id: `${role}-${randomUUID2().slice(0, 8)}`
|
|
5509
5618
|
};
|
|
5510
5619
|
}
|
|
5511
5620
|
function hintForKind(kind, retryable, backoffMs, partial) {
|
|
@@ -5580,13 +5689,13 @@ async function readSubagentPartial(opts, subagentId) {
|
|
|
5580
5689
|
if (!opts.sessionsRoot) return void 0;
|
|
5581
5690
|
const candidates = [];
|
|
5582
5691
|
if (opts.directorRunId) {
|
|
5583
|
-
candidates.push(
|
|
5692
|
+
candidates.push(path5.join(opts.sessionsRoot, opts.directorRunId, `${subagentId}.jsonl`));
|
|
5584
5693
|
} else {
|
|
5585
5694
|
try {
|
|
5586
|
-
const entries = await
|
|
5695
|
+
const entries = await fsp2.readdir(opts.sessionsRoot, { withFileTypes: true });
|
|
5587
5696
|
for (const entry of entries) {
|
|
5588
5697
|
if (entry.isDirectory()) {
|
|
5589
|
-
candidates.push(
|
|
5698
|
+
candidates.push(path5.join(opts.sessionsRoot, entry.name, `${subagentId}.jsonl`));
|
|
5590
5699
|
}
|
|
5591
5700
|
}
|
|
5592
5701
|
} catch {
|
|
@@ -5596,7 +5705,7 @@ async function readSubagentPartial(opts, subagentId) {
|
|
|
5596
5705
|
for (const file of candidates) {
|
|
5597
5706
|
let raw;
|
|
5598
5707
|
try {
|
|
5599
|
-
raw = await
|
|
5708
|
+
raw = await fsp2.readFile(file, "utf8");
|
|
5600
5709
|
} catch {
|
|
5601
5710
|
continue;
|
|
5602
5711
|
}
|
|
@@ -5629,10 +5738,19 @@ async function readSubagentPartial(opts, subagentId) {
|
|
|
5629
5738
|
}
|
|
5630
5739
|
return void 0;
|
|
5631
5740
|
}
|
|
5741
|
+
|
|
5742
|
+
// src/coordination/director.ts
|
|
5743
|
+
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
5744
|
+
import * as fsp5 from "node:fs/promises";
|
|
5745
|
+
import * as path7 from "node:path";
|
|
5746
|
+
|
|
5747
|
+
// src/storage/director-state.ts
|
|
5748
|
+
import * as fsp3 from "node:fs/promises";
|
|
5749
|
+
import { hostname } from "node:os";
|
|
5632
5750
|
async function loadDirectorState(filePath) {
|
|
5633
5751
|
let raw;
|
|
5634
5752
|
try {
|
|
5635
|
-
raw = await
|
|
5753
|
+
raw = await fsp3.readFile(filePath, "utf8");
|
|
5636
5754
|
} catch {
|
|
5637
5755
|
return null;
|
|
5638
5756
|
}
|
|
@@ -5647,7 +5765,7 @@ async function loadDirectorState(filePath) {
|
|
|
5647
5765
|
async function acquireDirectorStateLock(lockPath, processId = process.pid) {
|
|
5648
5766
|
let existing;
|
|
5649
5767
|
try {
|
|
5650
|
-
existing = await
|
|
5768
|
+
existing = await fsp3.readFile(lockPath, "utf8");
|
|
5651
5769
|
} catch {
|
|
5652
5770
|
}
|
|
5653
5771
|
if (existing) {
|
|
@@ -5671,7 +5789,7 @@ async function acquireDirectorStateLock(lockPath, processId = process.pid) {
|
|
|
5671
5789
|
}
|
|
5672
5790
|
async function releaseDirectorStateLock(lockPath) {
|
|
5673
5791
|
try {
|
|
5674
|
-
await
|
|
5792
|
+
await fsp3.unlink(lockPath);
|
|
5675
5793
|
} catch {
|
|
5676
5794
|
}
|
|
5677
5795
|
}
|
|
@@ -5834,6 +5952,11 @@ function resolveMaxSpawnDepth(requested) {
|
|
|
5834
5952
|
return Math.max(0, Math.min(HARD_MAX_SPAWN_DEPTH, Math.floor(requested)));
|
|
5835
5953
|
}
|
|
5836
5954
|
|
|
5955
|
+
// src/coordination/collab-debug.ts
|
|
5956
|
+
import { EventEmitter } from "node:events";
|
|
5957
|
+
import * as fsp4 from "node:fs/promises";
|
|
5958
|
+
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
5959
|
+
|
|
5837
5960
|
// src/coordination/fleet-event-validation.ts
|
|
5838
5961
|
var ROLE_BY_EVENT = {
|
|
5839
5962
|
"bug.found": "bug-hunter",
|
|
@@ -5984,7 +6107,7 @@ var CollabSession = class extends EventEmitter {
|
|
|
5984
6107
|
_timeoutTimer;
|
|
5985
6108
|
constructor(director, fleetBus, options) {
|
|
5986
6109
|
super();
|
|
5987
|
-
this.sessionId =
|
|
6110
|
+
this.sessionId = randomUUID3();
|
|
5988
6111
|
this.options = options;
|
|
5989
6112
|
this.director = director;
|
|
5990
6113
|
this.fleetBus = fleetBus;
|
|
@@ -6046,8 +6169,8 @@ var CollabSession = class extends EventEmitter {
|
|
|
6046
6169
|
for (const filePath of allFiles) {
|
|
6047
6170
|
try {
|
|
6048
6171
|
const [content, stat13] = await Promise.all([
|
|
6049
|
-
|
|
6050
|
-
|
|
6172
|
+
fsp4.readFile(filePath, "utf8"),
|
|
6173
|
+
fsp4.stat(filePath)
|
|
6051
6174
|
]);
|
|
6052
6175
|
const ext = filePath.split(".").pop() ?? "";
|
|
6053
6176
|
const language = ext === "ts" || ext === "tsx" ? "typescript" : ext === "js" || ext === "jsx" ? "javascript" : ext === "md" ? "markdown" : ext === "json" ? "json" : void 0;
|
|
@@ -6224,7 +6347,7 @@ var CollabSession = class extends EventEmitter {
|
|
|
6224
6347
|
timeoutMs: budget.timeoutMs
|
|
6225
6348
|
};
|
|
6226
6349
|
const subagentId = await this.director.spawn(cfg);
|
|
6227
|
-
await this.director.assign({ id:
|
|
6350
|
+
await this.director.assign({ id: randomUUID3(), subagentId, description: taskBrief });
|
|
6228
6351
|
return subagentId;
|
|
6229
6352
|
}
|
|
6230
6353
|
buildBugHunterTask() {
|
|
@@ -6475,7 +6598,7 @@ Emit each evaluation immediately. Do not wait until you have read all reports.`;
|
|
|
6475
6598
|
for (const file of this.snapshot.files) {
|
|
6476
6599
|
if (file.snapshotMtimeMs === void 0 && file.snapshotSizeBytes === void 0) continue;
|
|
6477
6600
|
try {
|
|
6478
|
-
const stat13 = await
|
|
6601
|
+
const stat13 = await fsp4.stat(file.path);
|
|
6479
6602
|
const mtimeChanged = file.snapshotMtimeMs !== void 0 && stat13.mtimeMs > file.snapshotMtimeMs + 1;
|
|
6480
6603
|
const sizeChanged = file.snapshotSizeBytes !== void 0 && stat13.size !== file.snapshotSizeBytes;
|
|
6481
6604
|
if (mtimeChanged || sizeChanged) {
|
|
@@ -6608,6 +6731,11 @@ var FleetContextOverflowError = class extends Error {
|
|
|
6608
6731
|
this.observed = observed;
|
|
6609
6732
|
}
|
|
6610
6733
|
};
|
|
6734
|
+
|
|
6735
|
+
// src/utils/instruction-file.ts
|
|
6736
|
+
import { readFileSync as readFileSync2, statSync as statSync2 } from "node:fs";
|
|
6737
|
+
import * as path6 from "node:path";
|
|
6738
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
6611
6739
|
var textCache = /* @__PURE__ */ new Map();
|
|
6612
6740
|
var rootCandidates;
|
|
6613
6741
|
function readBundledInstructionText(relativePath) {
|
|
@@ -6616,7 +6744,7 @@ function readBundledInstructionText(relativePath) {
|
|
|
6616
6744
|
let resolved = "";
|
|
6617
6745
|
for (const root of instructionRootCandidates()) {
|
|
6618
6746
|
try {
|
|
6619
|
-
resolved =
|
|
6747
|
+
resolved = readFileSync2(path6.join(root, relativePath), "utf8").trimEnd();
|
|
6620
6748
|
break;
|
|
6621
6749
|
} catch {
|
|
6622
6750
|
}
|
|
@@ -6632,18 +6760,18 @@ function renderInstructionTemplate(template, values) {
|
|
|
6632
6760
|
}
|
|
6633
6761
|
function instructionRootCandidates() {
|
|
6634
6762
|
if (rootCandidates !== void 0) return rootCandidates;
|
|
6635
|
-
const here =
|
|
6763
|
+
const here = path6.dirname(fileURLToPath2(import.meta.url));
|
|
6636
6764
|
const candidates = [
|
|
6637
|
-
|
|
6638
|
-
|
|
6639
|
-
|
|
6765
|
+
path6.resolve(here, "../../instructions"),
|
|
6766
|
+
path6.resolve(here, "../instructions"),
|
|
6767
|
+
path6.resolve(here, "instructions")
|
|
6640
6768
|
];
|
|
6641
6769
|
rootCandidates = candidates.sort((a, b) => Number(!isDirectory2(a)) - Number(!isDirectory2(b)));
|
|
6642
6770
|
return rootCandidates;
|
|
6643
6771
|
}
|
|
6644
6772
|
function isDirectory2(candidate) {
|
|
6645
6773
|
try {
|
|
6646
|
-
return
|
|
6774
|
+
return statSync2(candidate).isDirectory();
|
|
6647
6775
|
} catch {
|
|
6648
6776
|
return false;
|
|
6649
6777
|
}
|
|
@@ -6710,6 +6838,14 @@ function rosterSummaryFromConfigs(roster) {
|
|
|
6710
6838
|
return lines.join("\n");
|
|
6711
6839
|
}
|
|
6712
6840
|
|
|
6841
|
+
// src/coordination/director-tools.ts
|
|
6842
|
+
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
6843
|
+
import {
|
|
6844
|
+
claimReadyTask,
|
|
6845
|
+
listReadyTasks,
|
|
6846
|
+
updateTaskAssignment
|
|
6847
|
+
} from "@wrongstack/kanban";
|
|
6848
|
+
|
|
6713
6849
|
// src/coordination/dispatcher.ts
|
|
6714
6850
|
var DEFAULT_DISPATCH_ROLE = "executor";
|
|
6715
6851
|
var FALLBACK_DEFINITION = {
|
|
@@ -6969,7 +7105,7 @@ function instantiateRosterConfig2(role, base) {
|
|
|
6969
7105
|
...base,
|
|
6970
7106
|
// Roster entries are templates. A director may spawn several
|
|
6971
7107
|
// workers with the same role, so never reuse the template id.
|
|
6972
|
-
id: `${role}-${
|
|
7108
|
+
id: `${role}-${randomUUID4().slice(0, 8)}`
|
|
6973
7109
|
};
|
|
6974
7110
|
}
|
|
6975
7111
|
function makeQualityGateTool(director, roster) {
|
|
@@ -7068,7 +7204,7 @@ function makeQualityGateTool(director, roster) {
|
|
|
7068
7204
|
makeQualityGateSubagentConfig("verifier", roster, i.verifierWorktree ?? "auto")
|
|
7069
7205
|
);
|
|
7070
7206
|
const taskId = await director.assign({
|
|
7071
|
-
id:
|
|
7207
|
+
id: randomUUID4(),
|
|
7072
7208
|
subagentId,
|
|
7073
7209
|
description: buildVerifierTask(i, {
|
|
7074
7210
|
attempt,
|
|
@@ -7086,7 +7222,7 @@ function makeQualityGateTool(director, roster) {
|
|
|
7086
7222
|
makeQualityGateSubagentConfig("reviewer", roster, i.reviewerWorktree ?? "off")
|
|
7087
7223
|
);
|
|
7088
7224
|
const taskId = await director.assign({
|
|
7089
|
-
id:
|
|
7225
|
+
id: randomUUID4(),
|
|
7090
7226
|
subagentId,
|
|
7091
7227
|
description: buildReviewerTask(i, {
|
|
7092
7228
|
attempt,
|
|
@@ -7114,7 +7250,7 @@ function makeQualityGateTool(director, roster) {
|
|
|
7114
7250
|
};
|
|
7115
7251
|
}
|
|
7116
7252
|
const repairTaskId = await director.assign({
|
|
7117
|
-
id:
|
|
7253
|
+
id: randomUUID4(),
|
|
7118
7254
|
subagentId: i.repairSubagentId,
|
|
7119
7255
|
description: buildRepairTask(i, attempts[attempts.length - 1], attempt),
|
|
7120
7256
|
timeoutMs: i.timeoutMs
|
|
@@ -7382,7 +7518,7 @@ function makeAssignTool(director) {
|
|
|
7382
7518
|
async execute(input) {
|
|
7383
7519
|
const i = input;
|
|
7384
7520
|
const task = {
|
|
7385
|
-
id:
|
|
7521
|
+
id: randomUUID4(),
|
|
7386
7522
|
description: i.description,
|
|
7387
7523
|
subagentId: i.subagentId,
|
|
7388
7524
|
maxToolCalls: i.maxToolCalls,
|
|
@@ -7463,7 +7599,7 @@ function makeKanbanQueueTool(director, roster) {
|
|
|
7463
7599
|
const leaseTtlMs = Math.max(1e3, Math.floor(i.leaseTtlMs ?? 5 * 60 * 1e3));
|
|
7464
7600
|
const claimedAt = nowIso();
|
|
7465
7601
|
const leaseSeeding = {
|
|
7466
|
-
leaseId:
|
|
7602
|
+
leaseId: randomUUID4(),
|
|
7467
7603
|
claimedAt,
|
|
7468
7604
|
heartbeatAt: claimedAt,
|
|
7469
7605
|
leaseExpiresAt: new Date(Date.now() + leaseTtlMs).toISOString()
|
|
@@ -7517,7 +7653,7 @@ function makeKanbanQueueTool(director, roster) {
|
|
|
7517
7653
|
const config = buildKanbanSubagentConfig(claim.task, i, roster);
|
|
7518
7654
|
subagentId = await director.spawn(config);
|
|
7519
7655
|
runTaskId = await director.assign({
|
|
7520
|
-
id:
|
|
7656
|
+
id: randomUUID4(),
|
|
7521
7657
|
subagentId,
|
|
7522
7658
|
description: buildKanbanFleetTaskPrompt(claim.board, claim.task, {
|
|
7523
7659
|
heartbeatIntervalMs: i.heartbeatIntervalMs ?? 6e4,
|
|
@@ -8526,6 +8662,9 @@ var KIND_TO_CODE = {
|
|
|
8526
8662
|
function kindToCode(kind) {
|
|
8527
8663
|
return KIND_TO_CODE[kind];
|
|
8528
8664
|
}
|
|
8665
|
+
|
|
8666
|
+
// src/coordination/model-matrix.ts
|
|
8667
|
+
var MATRIX_PHASE_KEYS = Object.keys(AGENTS_BY_PHASE);
|
|
8529
8668
|
var ROLE_TO_PHASE = (() => {
|
|
8530
8669
|
const map = {};
|
|
8531
8670
|
for (const [phase, defs] of Object.entries(AGENTS_BY_PHASE)) {
|
|
@@ -8552,6 +8691,10 @@ function roleNeedsIndependentReviewModel(role) {
|
|
|
8552
8691
|
return role === "reviewer" || phaseForRole(role) === "review";
|
|
8553
8692
|
}
|
|
8554
8693
|
|
|
8694
|
+
// src/coordination/multi-agent-coordinator.ts
|
|
8695
|
+
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
8696
|
+
import { EventEmitter as EventEmitter2 } from "node:events";
|
|
8697
|
+
|
|
8555
8698
|
// src/coordination/coordinator/error-classifier.ts
|
|
8556
8699
|
function classifySubagentError(err, hints = {}) {
|
|
8557
8700
|
if (err instanceof AgentError && err.cause) {
|
|
@@ -8746,7 +8889,7 @@ function formatRole(role) {
|
|
|
8746
8889
|
}
|
|
8747
8890
|
|
|
8748
8891
|
// src/coordination/multi-agent-coordinator.ts
|
|
8749
|
-
var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends
|
|
8892
|
+
var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends EventEmitter2 {
|
|
8750
8893
|
coordinatorId;
|
|
8751
8894
|
config;
|
|
8752
8895
|
runner;
|
|
@@ -8839,7 +8982,7 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
|
|
|
8839
8982
|
return { ...subagent, name: display };
|
|
8840
8983
|
}
|
|
8841
8984
|
async spawn(subagent) {
|
|
8842
|
-
const id = subagent.id ||
|
|
8985
|
+
const id = subagent.id || randomUUID5();
|
|
8843
8986
|
const cfg = this.withNickname(subagent, id);
|
|
8844
8987
|
if (this.subagents.has(id)) {
|
|
8845
8988
|
throw new Error(`Subagent id "${id}" already exists \u2014 refusing to overwrite`);
|
|
@@ -9013,7 +9156,7 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
|
|
|
9013
9156
|
taskIds.map((id) => {
|
|
9014
9157
|
const cached = this.completedResults.find((r) => r.taskId === id);
|
|
9015
9158
|
if (cached) return cached;
|
|
9016
|
-
return new Promise((
|
|
9159
|
+
return new Promise((resolve12, reject) => {
|
|
9017
9160
|
const timeout = setTimeout(() => {
|
|
9018
9161
|
this.off("task.completed", handler);
|
|
9019
9162
|
reject(new Error(`awaitTasks timed out waiting for task "${id}"`));
|
|
@@ -9022,7 +9165,7 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
|
|
|
9022
9165
|
if (result.taskId === id) {
|
|
9023
9166
|
clearTimeout(timeout);
|
|
9024
9167
|
this.off("task.completed", handler);
|
|
9025
|
-
|
|
9168
|
+
resolve12(result);
|
|
9026
9169
|
}
|
|
9027
9170
|
};
|
|
9028
9171
|
this.on("task.completed", handler);
|
|
@@ -9047,13 +9190,13 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
|
|
|
9047
9190
|
const done = new Set(completed.map((r) => r.taskId));
|
|
9048
9191
|
return { completed, pending: taskIds.filter((id) => !done.has(id)) };
|
|
9049
9192
|
}
|
|
9050
|
-
return new Promise((
|
|
9193
|
+
return new Promise((resolve12) => {
|
|
9051
9194
|
let timer;
|
|
9052
9195
|
const handler = ({ result }) => {
|
|
9053
9196
|
if (!ids.has(result.taskId)) return;
|
|
9054
9197
|
if (timer) clearTimeout(timer);
|
|
9055
9198
|
this.off("task.completed", handler);
|
|
9056
|
-
|
|
9199
|
+
resolve12({
|
|
9057
9200
|
completed: [result],
|
|
9058
9201
|
pending: taskIds.filter((id) => id !== result.taskId)
|
|
9059
9202
|
});
|
|
@@ -9061,7 +9204,7 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
|
|
|
9061
9204
|
if (opts?.timeoutMs !== void 0) {
|
|
9062
9205
|
timer = setTimeout(() => {
|
|
9063
9206
|
this.off("task.completed", handler);
|
|
9064
|
-
|
|
9207
|
+
resolve12({ completed: [], pending: [...taskIds], timedOut: true });
|
|
9065
9208
|
}, opts.timeoutMs);
|
|
9066
9209
|
}
|
|
9067
9210
|
this.on("task.completed", handler);
|
|
@@ -9343,12 +9486,12 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
|
|
|
9343
9486
|
}
|
|
9344
9487
|
return new Promise((resolveDecision) => {
|
|
9345
9488
|
let settled = false;
|
|
9346
|
-
const
|
|
9489
|
+
const resolve12 = (d) => {
|
|
9347
9490
|
if (settled) return;
|
|
9348
9491
|
settled = true;
|
|
9349
9492
|
resolveDecision(d);
|
|
9350
9493
|
};
|
|
9351
|
-
const fallback = setTimeout(() =>
|
|
9494
|
+
const fallback = setTimeout(() => resolve12("stop"), DECISION_TIMEOUT_MS);
|
|
9352
9495
|
const sessionId = this.currentSessionId();
|
|
9353
9496
|
budget._events?.emit("budget.threshold_reached", {
|
|
9354
9497
|
...sessionId ? { sessionId } : {},
|
|
@@ -9366,11 +9509,11 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
|
|
|
9366
9509
|
// disagreeing, resolves as a stop). Async grants still resolve.
|
|
9367
9510
|
extend: (extra) => {
|
|
9368
9511
|
clearTimeout(fallback);
|
|
9369
|
-
queueMicrotask(() =>
|
|
9512
|
+
queueMicrotask(() => resolve12({ extend: extra }));
|
|
9370
9513
|
},
|
|
9371
9514
|
deny: () => {
|
|
9372
9515
|
clearTimeout(fallback);
|
|
9373
|
-
|
|
9516
|
+
resolve12("stop");
|
|
9374
9517
|
}
|
|
9375
9518
|
});
|
|
9376
9519
|
});
|
|
@@ -9506,8 +9649,9 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
|
|
|
9506
9649
|
}
|
|
9507
9650
|
const subagent = this.subagents.get(result.subagentId);
|
|
9508
9651
|
if (subagent && subagent.status !== "stopped") {
|
|
9509
|
-
result.status === "failed" || result.status === "timeout";
|
|
9652
|
+
const failed = result.status === "failed" || result.status === "timeout";
|
|
9510
9653
|
subagent.status = "idle";
|
|
9654
|
+
void failed;
|
|
9511
9655
|
subagent.currentTask = void 0;
|
|
9512
9656
|
if (subagent.abortController.signal.aborted) {
|
|
9513
9657
|
subagent.abortController = new AbortController();
|
|
@@ -9896,6 +10040,9 @@ var Director = class _Director {
|
|
|
9896
10040
|
subagentBaseline;
|
|
9897
10041
|
/** See {@link DirectorOptions.taskResultNotifier}. */
|
|
9898
10042
|
taskResultNotifier;
|
|
10043
|
+
subagentIdleTimeoutMs;
|
|
10044
|
+
retireSubagentOnTaskComplete;
|
|
10045
|
+
subagentIdleTimers = /* @__PURE__ */ new Map();
|
|
9899
10046
|
/** Absolute path to the fleet's shared scratchpad directory, or null
|
|
9900
10047
|
* when none was configured. Exposed as a readonly getter for callers
|
|
9901
10048
|
* that need to surface the path to the user (e.g. the CLI logging
|
|
@@ -9991,13 +10138,15 @@ var Director = class _Director {
|
|
|
9991
10138
|
/** Prevents large `ask_subagent` answers from bloating the leader's context window. */
|
|
9992
10139
|
largeAnswerStore;
|
|
9993
10140
|
constructor(opts) {
|
|
9994
|
-
this.id = opts.config.coordinatorId ||
|
|
10141
|
+
this.id = opts.config.coordinatorId || randomUUID6();
|
|
9995
10142
|
this.brain = opts.brain;
|
|
9996
10143
|
this.manifestPath = opts.manifestPath;
|
|
9997
10144
|
this.roster = opts.roster;
|
|
9998
10145
|
this.directorPreamble = opts.directorPreamble ?? DEFAULT_DIRECTOR_PREAMBLE;
|
|
9999
10146
|
this.subagentBaseline = opts.subagentBaseline ?? DEFAULT_SUBAGENT_BASELINE;
|
|
10000
10147
|
this.taskResultNotifier = opts.taskResultNotifier;
|
|
10148
|
+
this.subagentIdleTimeoutMs = typeof opts.subagentIdleTimeoutMs === "number" && Number.isFinite(opts.subagentIdleTimeoutMs) && opts.subagentIdleTimeoutMs >= 0 ? opts.subagentIdleTimeoutMs : void 0;
|
|
10149
|
+
this.retireSubagentOnTaskComplete = opts.retireSubagentOnTaskComplete ?? false;
|
|
10001
10150
|
this.sharedScratchpadPath = opts.sharedScratchpadPath ?? null;
|
|
10002
10151
|
this.maxSpawns = opts.maxSpawns ?? Number.POSITIVE_INFINITY;
|
|
10003
10152
|
this.maxSpawnDepth = opts.fleetManager?.maxSpawnDepth ?? resolveMaxSpawnDepth(opts.maxSpawnDepth);
|
|
@@ -10028,7 +10177,7 @@ var Director = class _Director {
|
|
|
10028
10177
|
this.fleetManager = opts.fleetManager;
|
|
10029
10178
|
this.logger = opts.logger;
|
|
10030
10179
|
if (this.sharedScratchpadPath) {
|
|
10031
|
-
void
|
|
10180
|
+
void fsp5.mkdir(this.sharedScratchpadPath, { recursive: true }).catch((err) => this.logShutdownError("shared_scratchpad_mkdir", err));
|
|
10032
10181
|
}
|
|
10033
10182
|
this.transport = new InMemoryBridgeTransport();
|
|
10034
10183
|
this.bridge = new InMemoryAgentBridge(
|
|
@@ -10142,6 +10291,10 @@ var Director = class _Director {
|
|
|
10142
10291
|
} else {
|
|
10143
10292
|
this.scheduleManifest();
|
|
10144
10293
|
}
|
|
10294
|
+
this.armSubagentIdleRetirement(
|
|
10295
|
+
r.subagentId,
|
|
10296
|
+
this.retireSubagentOnTaskComplete ? 0 : this.subagentIdleTimeoutMs
|
|
10297
|
+
);
|
|
10145
10298
|
};
|
|
10146
10299
|
this.coordinator.on("task.completed", this.taskCompletedListener);
|
|
10147
10300
|
const extendCounts = /* @__PURE__ */ new Map();
|
|
@@ -10614,6 +10767,7 @@ var Director = class _Director {
|
|
|
10614
10767
|
});
|
|
10615
10768
|
this.scheduleManifest();
|
|
10616
10769
|
}
|
|
10770
|
+
this.armSubagentIdleRetirement(result.subagentId, this.subagentIdleTimeoutMs);
|
|
10617
10771
|
return result.subagentId;
|
|
10618
10772
|
}
|
|
10619
10773
|
/**
|
|
@@ -10636,7 +10790,7 @@ var Director = class _Director {
|
|
|
10636
10790
|
);
|
|
10637
10791
|
}
|
|
10638
10792
|
const msg = {
|
|
10639
|
-
id:
|
|
10793
|
+
id: randomUUID6(),
|
|
10640
10794
|
type: "task",
|
|
10641
10795
|
from: this.id,
|
|
10642
10796
|
to: subagentId,
|
|
@@ -10735,7 +10889,7 @@ var Director = class _Director {
|
|
|
10735
10889
|
})),
|
|
10736
10890
|
usage: this.usage.snapshot()
|
|
10737
10891
|
};
|
|
10738
|
-
await
|
|
10892
|
+
await fsp5.mkdir(path7.dirname(this.manifestPath), { recursive: true });
|
|
10739
10893
|
await atomicWrite(this.manifestPath, JSON.stringify(manifest, null, 2), { mode: 384 });
|
|
10740
10894
|
return this.manifestPath;
|
|
10741
10895
|
}
|
|
@@ -10762,6 +10916,8 @@ var Director = class _Director {
|
|
|
10762
10916
|
this.budgetFilter();
|
|
10763
10917
|
this.budgetFilter = null;
|
|
10764
10918
|
}
|
|
10919
|
+
for (const timer of this.subagentIdleTimers.values()) clearTimeout(timer);
|
|
10920
|
+
this.subagentIdleTimers.clear();
|
|
10765
10921
|
await this.coordinator.stopAll();
|
|
10766
10922
|
for (const b of this.subagentBridges.values()) {
|
|
10767
10923
|
await b.stop().catch((err) => this.logShutdownError("subagent_bridge_stop", err));
|
|
@@ -10801,7 +10957,7 @@ var Director = class _Director {
|
|
|
10801
10957
|
* concurrency limit applies — the task may queue before running.
|
|
10802
10958
|
*/
|
|
10803
10959
|
async assign(task) {
|
|
10804
|
-
const taskWithId = task.id ? task : { ...task, id:
|
|
10960
|
+
const taskWithId = task.id ? task : { ...task, id: randomUUID6() };
|
|
10805
10961
|
if (this.workCompleteFlag) {
|
|
10806
10962
|
const synthetic = {
|
|
10807
10963
|
subagentId: taskWithId.subagentId ?? "unassigned",
|
|
@@ -10865,7 +11021,7 @@ var Director = class _Director {
|
|
|
10865
11021
|
* rollups and persisted fleet task history.
|
|
10866
11022
|
*/
|
|
10867
11023
|
async assignInternal(task) {
|
|
10868
|
-
const taskWithId = task.id ? task : { ...task, id:
|
|
11024
|
+
const taskWithId = task.id ? task : { ...task, id: randomUUID6() };
|
|
10869
11025
|
this.internalTaskIds.add(taskWithId.id);
|
|
10870
11026
|
try {
|
|
10871
11027
|
await this.coordinator.assign(taskWithId);
|
|
@@ -10889,11 +11045,11 @@ var Director = class _Director {
|
|
|
10889
11045
|
if (cached) return cached;
|
|
10890
11046
|
const existing = this.taskWaiters.get(id);
|
|
10891
11047
|
if (existing) return existing.promise;
|
|
10892
|
-
let
|
|
11048
|
+
let resolve12;
|
|
10893
11049
|
const promise = new Promise((res) => {
|
|
10894
|
-
|
|
11050
|
+
resolve12 = res;
|
|
10895
11051
|
});
|
|
10896
|
-
this.taskWaiters.set(id, { promise, resolve:
|
|
11052
|
+
this.taskWaiters.set(id, { promise, resolve: resolve12 });
|
|
10897
11053
|
return promise;
|
|
10898
11054
|
})
|
|
10899
11055
|
);
|
|
@@ -10922,10 +11078,10 @@ var Director = class _Director {
|
|
|
10922
11078
|
pending: taskIds.filter((id) => !done.has(id))
|
|
10923
11079
|
});
|
|
10924
11080
|
}
|
|
10925
|
-
return new Promise((
|
|
11081
|
+
return new Promise((resolve12) => {
|
|
10926
11082
|
const entry = {
|
|
10927
11083
|
ids: new Set(taskIds),
|
|
10928
|
-
resolve: (r) =>
|
|
11084
|
+
resolve: (r) => resolve12({
|
|
10929
11085
|
completed: [r],
|
|
10930
11086
|
pending: taskIds.filter((id) => id !== r.taskId)
|
|
10931
11087
|
})
|
|
@@ -10933,7 +11089,7 @@ var Director = class _Director {
|
|
|
10933
11089
|
if (opts?.timeoutMs !== void 0) {
|
|
10934
11090
|
entry.timer = setTimeout(() => {
|
|
10935
11091
|
this.anyWaiters.delete(entry);
|
|
10936
|
-
|
|
11092
|
+
resolve12({ completed: [], pending: [...taskIds], timedOut: true });
|
|
10937
11093
|
}, opts.timeoutMs);
|
|
10938
11094
|
}
|
|
10939
11095
|
this.anyWaiters.add(entry);
|
|
@@ -10984,6 +11140,7 @@ var Director = class _Director {
|
|
|
10984
11140
|
await this.coordinator.stopAll();
|
|
10985
11141
|
}
|
|
10986
11142
|
async remove(subagentId) {
|
|
11143
|
+
this.clearSubagentIdleRetirement(subagentId);
|
|
10987
11144
|
await this.coordinator.remove(subagentId);
|
|
10988
11145
|
const bridge = this.subagentBridges.get(subagentId);
|
|
10989
11146
|
if (bridge) {
|
|
@@ -11004,6 +11161,34 @@ var Director = class _Director {
|
|
|
11004
11161
|
this.taskOwners.delete(subagentId);
|
|
11005
11162
|
this.taskDescriptions.delete(subagentId);
|
|
11006
11163
|
}
|
|
11164
|
+
clearSubagentIdleRetirement(subagentId) {
|
|
11165
|
+
const timer = this.subagentIdleTimers.get(subagentId);
|
|
11166
|
+
if (!timer) return;
|
|
11167
|
+
clearTimeout(timer);
|
|
11168
|
+
this.subagentIdleTimers.delete(subagentId);
|
|
11169
|
+
}
|
|
11170
|
+
/**
|
|
11171
|
+
* Arm one lifecycle timer per worker. The callback re-checks coordinator
|
|
11172
|
+
* state so a task assigned in the same turn always wins over retirement.
|
|
11173
|
+
*/
|
|
11174
|
+
armSubagentIdleRetirement(subagentId, delayMs) {
|
|
11175
|
+
this.clearSubagentIdleRetirement(subagentId);
|
|
11176
|
+
if (delayMs === void 0) return;
|
|
11177
|
+
const timer = setTimeout(() => {
|
|
11178
|
+
this.subagentIdleTimers.delete(subagentId);
|
|
11179
|
+
const entry = this.coordinator.getStatus().subagents.find((a) => a.id === subagentId);
|
|
11180
|
+
if (!entry || entry.status !== "idle") return;
|
|
11181
|
+
if (this.coordinator.listPendingTasks().some((task) => task.subagentId === subagentId)) {
|
|
11182
|
+
this.armSubagentIdleRetirement(subagentId, this.subagentIdleTimeoutMs);
|
|
11183
|
+
return;
|
|
11184
|
+
}
|
|
11185
|
+
void this.remove(subagentId).catch(
|
|
11186
|
+
(err) => this.logShutdownError("subagent_idle_retirement", err)
|
|
11187
|
+
);
|
|
11188
|
+
}, delayMs);
|
|
11189
|
+
if (typeof timer.unref === "function") timer.unref();
|
|
11190
|
+
this.subagentIdleTimers.set(subagentId, timer);
|
|
11191
|
+
}
|
|
11007
11192
|
status() {
|
|
11008
11193
|
const base = this.coordinator.getStatus();
|
|
11009
11194
|
return {
|
|
@@ -11055,10 +11240,10 @@ var Director = class _Director {
|
|
|
11055
11240
|
*/
|
|
11056
11241
|
async readSession(subagentId, tail) {
|
|
11057
11242
|
if (!this.sessionsRoot) return null;
|
|
11058
|
-
const filePath =
|
|
11243
|
+
const filePath = path7.join(this.sessionsRoot, this.directorRunId, `${subagentId}.jsonl`);
|
|
11059
11244
|
let raw;
|
|
11060
11245
|
try {
|
|
11061
|
-
raw = await
|
|
11246
|
+
raw = await fsp5.readFile(filePath, "utf8");
|
|
11062
11247
|
} catch {
|
|
11063
11248
|
return null;
|
|
11064
11249
|
}
|
|
@@ -11223,6 +11408,21 @@ var Director = class _Director {
|
|
|
11223
11408
|
}
|
|
11224
11409
|
};
|
|
11225
11410
|
|
|
11411
|
+
// src/coordination/director-session.ts
|
|
11412
|
+
import * as path12 from "node:path";
|
|
11413
|
+
|
|
11414
|
+
// src/storage/session-store.ts
|
|
11415
|
+
import { createHash as createHash4 } from "node:crypto";
|
|
11416
|
+
import { createReadStream } from "node:fs";
|
|
11417
|
+
import * as fsp9 from "node:fs/promises";
|
|
11418
|
+
import * as path11 from "node:path";
|
|
11419
|
+
import { createInterface } from "node:readline";
|
|
11420
|
+
|
|
11421
|
+
// src/storage/file-session-writer.ts
|
|
11422
|
+
import { closeSync, fsyncSync, openSync, writeSync } from "node:fs";
|
|
11423
|
+
import * as fsp6 from "node:fs/promises";
|
|
11424
|
+
import * as path8 from "node:path";
|
|
11425
|
+
|
|
11226
11426
|
// src/storage/session-helpers.ts
|
|
11227
11427
|
function userInputTitle(content) {
|
|
11228
11428
|
const text = typeof content === "string" ? content : content.filter((b) => b.type === "text").map((b) => b.text).join(" ");
|
|
@@ -11238,7 +11438,7 @@ var FileSessionWriter = class _FileSessionWriter {
|
|
|
11238
11438
|
this.meta = meta;
|
|
11239
11439
|
this.events = events;
|
|
11240
11440
|
this.resumed = opts.resumed ?? false;
|
|
11241
|
-
this.manifestFile = opts.dir ?
|
|
11441
|
+
this.manifestFile = opts.dir ? path8.join(opts.dir, `${path8.basename(id)}.summary.json`) : "";
|
|
11242
11442
|
this.filePath = opts.filePath ?? "";
|
|
11243
11443
|
this.secretScrubber = opts.secretScrubber;
|
|
11244
11444
|
this.checkpointCas = opts.checkpointCas;
|
|
@@ -11778,7 +11978,7 @@ var FileSessionWriter = class _FileSessionWriter {
|
|
|
11778
11978
|
let removedCount = 0;
|
|
11779
11979
|
let targetCheckpointSeen = false;
|
|
11780
11980
|
try {
|
|
11781
|
-
fd = await
|
|
11981
|
+
fd = await fsp6.open(this.filePath, "r", 384);
|
|
11782
11982
|
while (true) {
|
|
11783
11983
|
const buf = Buffer.alloc(CHUNK_SIZE);
|
|
11784
11984
|
const { bytesRead } = await fd.read(buf, 0, CHUNK_SIZE, fileOffset);
|
|
@@ -11833,7 +12033,7 @@ var FileSessionWriter = class _FileSessionWriter {
|
|
|
11833
12033
|
await this.writeChain;
|
|
11834
12034
|
await this.handle.close();
|
|
11835
12035
|
const tmpPath = `${this.filePath}.rewind.tmp`;
|
|
11836
|
-
const src = await
|
|
12036
|
+
const src = await fsp6.open(this.filePath, "r", 384);
|
|
11837
12037
|
try {
|
|
11838
12038
|
const statResult = await src.stat();
|
|
11839
12039
|
const totalSize = statResult.size;
|
|
@@ -11849,7 +12049,7 @@ var FileSessionWriter = class _FileSessionWriter {
|
|
|
11849
12049
|
} else {
|
|
11850
12050
|
newlineAfterCheckpoint = totalSize;
|
|
11851
12051
|
}
|
|
11852
|
-
const writeFd = await
|
|
12052
|
+
const writeFd = await fsp6.open(tmpPath, "w", 384);
|
|
11853
12053
|
try {
|
|
11854
12054
|
let readOffset = 0;
|
|
11855
12055
|
while (readOffset < newlineAfterCheckpoint) {
|
|
@@ -11897,11 +12097,11 @@ var FileSessionWriter = class _FileSessionWriter {
|
|
|
11897
12097
|
await writeFd.close();
|
|
11898
12098
|
}
|
|
11899
12099
|
await src.close();
|
|
11900
|
-
await
|
|
11901
|
-
this.handle = await
|
|
12100
|
+
await fsp6.rename(tmpPath, this.filePath);
|
|
12101
|
+
this.handle = await fsp6.open(this.filePath, "a", 384);
|
|
11902
12102
|
} catch (err) {
|
|
11903
|
-
await
|
|
11904
|
-
this.handle = await
|
|
12103
|
+
await fsp6.unlink(tmpPath).catch(() => void 0);
|
|
12104
|
+
this.handle = await fsp6.open(this.filePath, "a", 384).catch(() => this.handle);
|
|
11905
12105
|
throw err;
|
|
11906
12106
|
}
|
|
11907
12107
|
await this.append({
|
|
@@ -11936,7 +12136,7 @@ var FileSessionWriter = class _FileSessionWriter {
|
|
|
11936
12136
|
provider: this.meta.provider ?? "unknown"
|
|
11937
12137
|
})}
|
|
11938
12138
|
`;
|
|
11939
|
-
await
|
|
12139
|
+
await fsp6.writeFile(this.filePath, record, "utf8");
|
|
11940
12140
|
this.activePromptIndex = null;
|
|
11941
12141
|
this.pendingFileSnapshots = [];
|
|
11942
12142
|
}
|
|
@@ -11981,6 +12181,12 @@ var FileSessionWriter = class _FileSessionWriter {
|
|
|
11981
12181
|
}
|
|
11982
12182
|
};
|
|
11983
12183
|
|
|
12184
|
+
// src/storage/session-checkpoint-cas.ts
|
|
12185
|
+
import { spawn } from "node:child_process";
|
|
12186
|
+
import { createHash as createHash2, randomUUID as randomUUID7 } from "node:crypto";
|
|
12187
|
+
import * as fsp7 from "node:fs/promises";
|
|
12188
|
+
import * as path9 from "node:path";
|
|
12189
|
+
|
|
11984
12190
|
// src/storage/storage-concurrency.ts
|
|
11985
12191
|
async function mapWithConcurrency(items, concurrency, mapper) {
|
|
11986
12192
|
if (items.length === 0) return [];
|
|
@@ -12007,32 +12213,32 @@ var MAX_GIT_OUTPUT = 16 * 1024 * 1024;
|
|
|
12007
12213
|
var MAX_BLOB_BYTES = 64 * 1024 * 1024;
|
|
12008
12214
|
var MAX_CHECKPOINT_BYTES = 512 * 1024 * 1024;
|
|
12009
12215
|
function sha256(content) {
|
|
12010
|
-
return
|
|
12216
|
+
return createHash2("sha256").update(content).digest("hex");
|
|
12011
12217
|
}
|
|
12012
12218
|
function isInside(root, target) {
|
|
12013
|
-
const
|
|
12014
|
-
return
|
|
12219
|
+
const relative4 = path9.relative(root, target);
|
|
12220
|
+
return relative4 === "" || !relative4.startsWith("..") && !path9.isAbsolute(relative4);
|
|
12015
12221
|
}
|
|
12016
12222
|
function normalizeRelative(input) {
|
|
12017
|
-
if (!input ||
|
|
12223
|
+
if (!input || path9.isAbsolute(input)) return null;
|
|
12018
12224
|
const normalized = input.replace(/\\/g, "/").replace(/^\.\//, "");
|
|
12019
|
-
const resolved =
|
|
12225
|
+
const resolved = path9.posix.normalize(normalized);
|
|
12020
12226
|
if (!resolved || resolved === "." || resolved === ".." || resolved.startsWith("../")) return null;
|
|
12021
12227
|
return resolved;
|
|
12022
12228
|
}
|
|
12023
12229
|
function parseNulPaths(output) {
|
|
12024
12230
|
return output.split("\0").map(normalizeRelative).filter((value) => value !== null);
|
|
12025
12231
|
}
|
|
12026
|
-
function isWrongStackWorktreePath(
|
|
12027
|
-
return
|
|
12232
|
+
function isWrongStackWorktreePath(relative4) {
|
|
12233
|
+
return relative4 === ".wrongstack/worktrees" || relative4.startsWith(".wrongstack/worktrees/");
|
|
12028
12234
|
}
|
|
12029
12235
|
var SessionCheckpointCas = class {
|
|
12030
12236
|
rootDir;
|
|
12031
12237
|
projectRoot;
|
|
12032
12238
|
runGit;
|
|
12033
12239
|
constructor(opts) {
|
|
12034
|
-
this.rootDir =
|
|
12035
|
-
this.projectRoot =
|
|
12240
|
+
this.rootDir = path9.resolve(opts.rootDir);
|
|
12241
|
+
this.projectRoot = path9.resolve(opts.projectRoot);
|
|
12036
12242
|
this.runGit = opts.runGit ?? defaultRunGit;
|
|
12037
12243
|
}
|
|
12038
12244
|
async capture(_sessionId, _promptIndex) {
|
|
@@ -12050,60 +12256,60 @@ var SessionCheckpointCas = class {
|
|
|
12050
12256
|
}
|
|
12051
12257
|
const relativePaths = [
|
|
12052
12258
|
.../* @__PURE__ */ new Set([...parseNulPaths(tracked.stdout), ...parseNulPaths(untracked.stdout)])
|
|
12053
|
-
].filter((
|
|
12259
|
+
].filter((relative4) => !isWrongStackWorktreePath(relative4)).sort();
|
|
12054
12260
|
const unresolved = [];
|
|
12055
12261
|
let scheduledBytes = 0;
|
|
12056
12262
|
const captured = await mapWithConcurrency(
|
|
12057
12263
|
relativePaths,
|
|
12058
12264
|
CAPTURE_CONCURRENCY,
|
|
12059
|
-
async (
|
|
12060
|
-
const absolute =
|
|
12265
|
+
async (relative4) => {
|
|
12266
|
+
const absolute = path9.resolve(this.projectRoot, ...relative4.split("/"));
|
|
12061
12267
|
if (!isInside(this.projectRoot, absolute)) {
|
|
12062
|
-
unresolved.push({ path:
|
|
12268
|
+
unresolved.push({ path: relative4, reason: "path escapes project root" });
|
|
12063
12269
|
return null;
|
|
12064
12270
|
}
|
|
12065
12271
|
try {
|
|
12066
|
-
const stat13 = await
|
|
12272
|
+
const stat13 = await fsp7.lstat(absolute);
|
|
12067
12273
|
if (stat13.isSymbolicLink()) {
|
|
12068
|
-
const linkTarget = await
|
|
12069
|
-
const resolvedLink =
|
|
12070
|
-
if (
|
|
12274
|
+
const linkTarget = await fsp7.readlink(absolute);
|
|
12275
|
+
const resolvedLink = path9.resolve(path9.dirname(absolute), linkTarget);
|
|
12276
|
+
if (path9.isAbsolute(linkTarget) || !isInside(this.projectRoot, resolvedLink)) {
|
|
12071
12277
|
unresolved.push({
|
|
12072
|
-
path:
|
|
12278
|
+
path: relative4,
|
|
12073
12279
|
reason: "symlink target escapes project root"
|
|
12074
12280
|
});
|
|
12075
12281
|
return null;
|
|
12076
12282
|
}
|
|
12077
|
-
return { path:
|
|
12283
|
+
return { path: relative4, state: "symlink", linkTarget };
|
|
12078
12284
|
}
|
|
12079
12285
|
if (!stat13.isFile()) {
|
|
12080
|
-
unresolved.push({ path:
|
|
12286
|
+
unresolved.push({ path: relative4, reason: "changed path is not a regular file" });
|
|
12081
12287
|
return null;
|
|
12082
12288
|
}
|
|
12083
12289
|
if (stat13.size > MAX_BLOB_BYTES) {
|
|
12084
12290
|
unresolved.push({
|
|
12085
|
-
path:
|
|
12291
|
+
path: relative4,
|
|
12086
12292
|
reason: `file exceeds ${MAX_BLOB_BYTES}-byte checkpoint blob limit`
|
|
12087
12293
|
});
|
|
12088
12294
|
return null;
|
|
12089
12295
|
}
|
|
12090
12296
|
if (scheduledBytes + stat13.size > MAX_CHECKPOINT_BYTES) {
|
|
12091
12297
|
unresolved.push({
|
|
12092
|
-
path:
|
|
12298
|
+
path: relative4,
|
|
12093
12299
|
reason: `checkpoint exceeds ${MAX_CHECKPOINT_BYTES}-byte aggregate blob limit`
|
|
12094
12300
|
});
|
|
12095
12301
|
return null;
|
|
12096
12302
|
}
|
|
12097
12303
|
scheduledBytes += stat13.size;
|
|
12098
|
-
const content = await
|
|
12304
|
+
const content = await fsp7.readFile(absolute);
|
|
12099
12305
|
const blobHash = sha256(content);
|
|
12100
12306
|
await this.putBlob(blobHash, content);
|
|
12101
|
-
return { path:
|
|
12307
|
+
return { path: relative4, state: "file", blobHash, mode: stat13.mode & 511 };
|
|
12102
12308
|
} catch (err) {
|
|
12103
12309
|
if (err.code === "ENOENT") {
|
|
12104
|
-
return { path:
|
|
12310
|
+
return { path: relative4, state: "absent" };
|
|
12105
12311
|
}
|
|
12106
|
-
unresolved.push({ path:
|
|
12312
|
+
unresolved.push({ path: relative4, reason: toErrorMessage(err) });
|
|
12107
12313
|
return null;
|
|
12108
12314
|
}
|
|
12109
12315
|
}
|
|
@@ -12129,11 +12335,11 @@ var SessionCheckpointCas = class {
|
|
|
12129
12335
|
};
|
|
12130
12336
|
}
|
|
12131
12337
|
async materialize(checkpoint, targetRoot) {
|
|
12132
|
-
const target =
|
|
12338
|
+
const target = path9.resolve(targetRoot);
|
|
12133
12339
|
if (target === this.projectRoot) {
|
|
12134
12340
|
throw new Error("Refusing to materialize a workspace checkpoint over the parent project root");
|
|
12135
12341
|
}
|
|
12136
|
-
const targetStat = await
|
|
12342
|
+
const targetStat = await fsp7.stat(target);
|
|
12137
12343
|
if (!targetStat.isDirectory()) throw new Error(`Checkpoint target is not a directory: ${target}`);
|
|
12138
12344
|
const manifest = await this.loadManifest(checkpoint.manifestHash);
|
|
12139
12345
|
if (manifest.baseHead !== checkpoint.baseHead.toLowerCase() || manifest.coverage !== checkpoint.coverage || manifest.entries.length !== checkpoint.entryCount || manifest.unresolved.length !== checkpoint.unresolvedCount) {
|
|
@@ -12160,7 +12366,7 @@ var SessionCheckpointCas = class {
|
|
|
12160
12366
|
if (targetStatus.stdout.length > 0) {
|
|
12161
12367
|
throw new Error("Checkpoint target must be a clean checkout before materialization");
|
|
12162
12368
|
}
|
|
12163
|
-
const realTarget = await
|
|
12369
|
+
const realTarget = await fsp7.realpath(target);
|
|
12164
12370
|
const writtenFiles = [];
|
|
12165
12371
|
const deletedFiles = [];
|
|
12166
12372
|
const errors = [];
|
|
@@ -12169,10 +12375,10 @@ var SessionCheckpointCas = class {
|
|
|
12169
12375
|
try {
|
|
12170
12376
|
const output = await this.safeOutputPath(target, realTarget, entry.path);
|
|
12171
12377
|
if (entry.state === "symlink") {
|
|
12172
|
-
if (
|
|
12378
|
+
if (path9.isAbsolute(entry.linkTarget)) {
|
|
12173
12379
|
throw new Error("absolute symlink target refused");
|
|
12174
12380
|
}
|
|
12175
|
-
const resolvedLink =
|
|
12381
|
+
const resolvedLink = path9.resolve(path9.dirname(output), entry.linkTarget);
|
|
12176
12382
|
if (!isInside(target, resolvedLink)) throw new Error("symlink target escapes checkpoint root");
|
|
12177
12383
|
}
|
|
12178
12384
|
prepared.push({
|
|
@@ -12190,24 +12396,24 @@ var SessionCheckpointCas = class {
|
|
|
12190
12396
|
for (const { entry, output, content } of prepared) {
|
|
12191
12397
|
try {
|
|
12192
12398
|
if (entry.state === "absent") {
|
|
12193
|
-
await
|
|
12399
|
+
await fsp7.unlink(output).catch((err) => {
|
|
12194
12400
|
if (err.code !== "ENOENT") throw err;
|
|
12195
12401
|
});
|
|
12196
12402
|
deletedFiles.push(entry.path);
|
|
12197
12403
|
continue;
|
|
12198
12404
|
}
|
|
12199
12405
|
if (entry.state === "symlink") {
|
|
12200
|
-
await
|
|
12406
|
+
await fsp7.unlink(output).catch((err) => {
|
|
12201
12407
|
if (err.code !== "ENOENT") throw err;
|
|
12202
12408
|
});
|
|
12203
|
-
await
|
|
12204
|
-
await
|
|
12409
|
+
await fsp7.mkdir(path9.dirname(output), { recursive: true });
|
|
12410
|
+
await fsp7.symlink(entry.linkTarget, output);
|
|
12205
12411
|
writtenFiles.push(entry.path);
|
|
12206
12412
|
continue;
|
|
12207
12413
|
}
|
|
12208
12414
|
if (!content) throw new Error("CAS blob was not prepared");
|
|
12209
12415
|
await atomicWrite(output, content, { mode: entry.mode });
|
|
12210
|
-
await
|
|
12416
|
+
await fsp7.chmod(output, entry.mode).catch(() => void 0);
|
|
12211
12417
|
writtenFiles.push(entry.path);
|
|
12212
12418
|
} catch (err) {
|
|
12213
12419
|
errors.push(`${entry.path}: ${toErrorMessage(err)}`);
|
|
@@ -12217,48 +12423,48 @@ var SessionCheckpointCas = class {
|
|
|
12217
12423
|
}
|
|
12218
12424
|
objectPath(hash) {
|
|
12219
12425
|
if (!HASH_RE.test(hash)) throw new Error(`Invalid CAS object hash: ${hash}`);
|
|
12220
|
-
return
|
|
12426
|
+
return path9.join(this.rootDir, "objects", hash.slice(0, 2), hash.slice(2));
|
|
12221
12427
|
}
|
|
12222
12428
|
manifestPath(hash) {
|
|
12223
12429
|
if (!HASH_RE.test(hash)) throw new Error(`Invalid checkpoint manifest hash: ${hash}`);
|
|
12224
|
-
return
|
|
12430
|
+
return path9.join(this.rootDir, "manifests", `${hash}.json`);
|
|
12225
12431
|
}
|
|
12226
12432
|
async putBlob(hash, content) {
|
|
12227
12433
|
const target = this.objectPath(hash);
|
|
12228
|
-
await
|
|
12434
|
+
await fsp7.mkdir(path9.dirname(target), { recursive: true });
|
|
12229
12435
|
try {
|
|
12230
|
-
const existing = await
|
|
12436
|
+
const existing = await fsp7.readFile(target);
|
|
12231
12437
|
if (sha256(existing) !== hash) throw new Error(`Corrupt CAS object collision: ${hash}`);
|
|
12232
12438
|
return;
|
|
12233
12439
|
} catch (err) {
|
|
12234
12440
|
if (err.code !== "ENOENT") throw err;
|
|
12235
12441
|
}
|
|
12236
|
-
const temp =
|
|
12237
|
-
|
|
12238
|
-
`.${
|
|
12442
|
+
const temp = path9.join(
|
|
12443
|
+
path9.dirname(target),
|
|
12444
|
+
`.${path9.basename(target)}.${process.pid}.${randomUUID7()}.tmp`
|
|
12239
12445
|
);
|
|
12240
12446
|
let handle;
|
|
12241
12447
|
try {
|
|
12242
|
-
handle = await
|
|
12448
|
+
handle = await fsp7.open(temp, "wx", 384);
|
|
12243
12449
|
await handle.writeFile(content);
|
|
12244
12450
|
await handle.sync();
|
|
12245
12451
|
await handle.close();
|
|
12246
12452
|
handle = void 0;
|
|
12247
12453
|
try {
|
|
12248
|
-
await
|
|
12454
|
+
await fsp7.link(temp, target);
|
|
12249
12455
|
} catch (err) {
|
|
12250
12456
|
if (err.code !== "EEXIST") throw err;
|
|
12251
|
-
const existing = await
|
|
12457
|
+
const existing = await fsp7.readFile(target);
|
|
12252
12458
|
if (sha256(existing) !== hash) throw new Error(`Corrupt CAS object collision: ${hash}`);
|
|
12253
12459
|
}
|
|
12254
12460
|
} finally {
|
|
12255
12461
|
await handle?.close().catch(() => void 0);
|
|
12256
|
-
await
|
|
12462
|
+
await fsp7.unlink(temp).catch(() => void 0);
|
|
12257
12463
|
}
|
|
12258
12464
|
}
|
|
12259
12465
|
async putManifest(hash, encoded) {
|
|
12260
12466
|
const target = this.manifestPath(hash);
|
|
12261
|
-
const existing = await
|
|
12467
|
+
const existing = await fsp7.readFile(target).catch(() => null);
|
|
12262
12468
|
if (existing) {
|
|
12263
12469
|
if (sha256(existing) !== hash) throw new Error(`Corrupt checkpoint manifest collision: ${hash}`);
|
|
12264
12470
|
return;
|
|
@@ -12266,12 +12472,12 @@ var SessionCheckpointCas = class {
|
|
|
12266
12472
|
await atomicWrite(target, encoded, { mode: 384 });
|
|
12267
12473
|
}
|
|
12268
12474
|
async readBlob(hash) {
|
|
12269
|
-
const content = await
|
|
12475
|
+
const content = await fsp7.readFile(this.objectPath(hash));
|
|
12270
12476
|
if (sha256(content) !== hash) throw new Error(`CAS blob integrity check failed: ${hash}`);
|
|
12271
12477
|
return content;
|
|
12272
12478
|
}
|
|
12273
12479
|
async loadManifest(hash) {
|
|
12274
|
-
const raw = await
|
|
12480
|
+
const raw = await fsp7.readFile(this.manifestPath(hash));
|
|
12275
12481
|
if (sha256(raw) !== hash) throw new Error(`Checkpoint manifest integrity check failed: ${hash}`);
|
|
12276
12482
|
const parsed = JSON.parse(raw.toString("utf8"));
|
|
12277
12483
|
if (parsed.version !== 1 || typeof parsed.baseHead !== "string" || parsed.coverage !== "git-head-plus-dirty" || !Array.isArray(parsed.entries) || !Array.isArray(parsed.unresolved)) {
|
|
@@ -12293,20 +12499,20 @@ var SessionCheckpointCas = class {
|
|
|
12293
12499
|
}
|
|
12294
12500
|
return parsed;
|
|
12295
12501
|
}
|
|
12296
|
-
async safeOutputPath(target, realTarget,
|
|
12297
|
-
const normalized = normalizeRelative(
|
|
12502
|
+
async safeOutputPath(target, realTarget, relative4) {
|
|
12503
|
+
const normalized = normalizeRelative(relative4);
|
|
12298
12504
|
if (!normalized) throw new Error("invalid relative path");
|
|
12299
|
-
const output =
|
|
12505
|
+
const output = path9.resolve(target, ...normalized.split("/"));
|
|
12300
12506
|
if (!isInside(target, output)) throw new Error("path escapes checkpoint target");
|
|
12301
12507
|
let probe = output;
|
|
12302
12508
|
for (; ; ) {
|
|
12303
12509
|
try {
|
|
12304
|
-
const real = await
|
|
12510
|
+
const real = await fsp7.realpath(probe);
|
|
12305
12511
|
if (!isInside(realTarget, real)) throw new Error("path resolves through a symlink outside checkpoint target");
|
|
12306
12512
|
return output;
|
|
12307
12513
|
} catch (err) {
|
|
12308
12514
|
if (err.code !== "ENOENT") throw err;
|
|
12309
|
-
const parent =
|
|
12515
|
+
const parent = path9.dirname(probe);
|
|
12310
12516
|
if (parent === probe) throw err;
|
|
12311
12517
|
probe = parent;
|
|
12312
12518
|
}
|
|
@@ -12314,7 +12520,7 @@ var SessionCheckpointCas = class {
|
|
|
12314
12520
|
}
|
|
12315
12521
|
};
|
|
12316
12522
|
function defaultRunGit(args, cwd) {
|
|
12317
|
-
return new Promise((
|
|
12523
|
+
return new Promise((resolve12) => {
|
|
12318
12524
|
const stdoutChunks = [];
|
|
12319
12525
|
const stderrChunks = [];
|
|
12320
12526
|
let stdoutBytes = 0;
|
|
@@ -12357,16 +12563,21 @@ function defaultRunGit(args, cwd) {
|
|
|
12357
12563
|
stdoutTruncated,
|
|
12358
12564
|
stderrTruncated
|
|
12359
12565
|
});
|
|
12360
|
-
child.on("error", (err) =>
|
|
12361
|
-
child.on("close", (code) =>
|
|
12566
|
+
child.on("error", (err) => resolve12(result(1, err.message)));
|
|
12567
|
+
child.on("close", (code) => resolve12(result(code ?? 1)));
|
|
12362
12568
|
});
|
|
12363
12569
|
}
|
|
12570
|
+
|
|
12571
|
+
// src/storage/session-resume-validation.ts
|
|
12572
|
+
import { createHash as createHash3 } from "node:crypto";
|
|
12573
|
+
import * as fsp8 from "node:fs/promises";
|
|
12574
|
+
import * as path10 from "node:path";
|
|
12364
12575
|
var MAX_REVALIDATE_BYTES = 5 * 1024 * 1024;
|
|
12365
12576
|
var VALIDATION_CONCURRENCY = 8;
|
|
12366
12577
|
var NOTICE_PATH_LIMIT = 20;
|
|
12367
12578
|
function isInside2(root, target) {
|
|
12368
|
-
const
|
|
12369
|
-
return
|
|
12579
|
+
const relative4 = path10.relative(root, target);
|
|
12580
|
+
return relative4 === "" || !relative4.startsWith("..") && !path10.isAbsolute(relative4);
|
|
12370
12581
|
}
|
|
12371
12582
|
function errno(err) {
|
|
12372
12583
|
return err && typeof err === "object" && "code" in err ? String(err.code) : void 0;
|
|
@@ -12377,7 +12588,7 @@ function latestObservations(events, projectRoot) {
|
|
|
12377
12588
|
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)) {
|
|
12378
12589
|
continue;
|
|
12379
12590
|
}
|
|
12380
|
-
const normalized =
|
|
12591
|
+
const normalized = path10.resolve(projectRoot, event.path);
|
|
12381
12592
|
latest.set(normalized, {
|
|
12382
12593
|
path: normalized,
|
|
12383
12594
|
hash: event.hash.toLowerCase(),
|
|
@@ -12401,7 +12612,7 @@ async function validateOne(observation, lexicalRoot, realRoot) {
|
|
|
12401
12612
|
}
|
|
12402
12613
|
let realFile;
|
|
12403
12614
|
try {
|
|
12404
|
-
realFile = await
|
|
12615
|
+
realFile = await fsp8.realpath(observation.path);
|
|
12405
12616
|
} catch (err) {
|
|
12406
12617
|
if (errno(err) === "ENOENT") return { ...base, status: "deleted" };
|
|
12407
12618
|
return { ...base, status: "unreadable", detail: toErrorMessage(err) };
|
|
@@ -12414,7 +12625,7 @@ async function validateOne(observation, lexicalRoot, realRoot) {
|
|
|
12414
12625
|
};
|
|
12415
12626
|
}
|
|
12416
12627
|
try {
|
|
12417
|
-
const stat13 = await
|
|
12628
|
+
const stat13 = await fsp8.stat(realFile);
|
|
12418
12629
|
if (!stat13.isFile()) {
|
|
12419
12630
|
return { ...base, status: "unreadable", detail: "Path is no longer a regular file." };
|
|
12420
12631
|
}
|
|
@@ -12425,8 +12636,8 @@ async function validateOne(observation, lexicalRoot, realRoot) {
|
|
|
12425
12636
|
detail: `File now exceeds the ${MAX_REVALIDATE_BYTES}-byte validation limit.`
|
|
12426
12637
|
};
|
|
12427
12638
|
}
|
|
12428
|
-
const content = await
|
|
12429
|
-
const actualHash =
|
|
12639
|
+
const content = await fsp8.readFile(realFile, "utf8");
|
|
12640
|
+
const actualHash = createHash3("sha256").update(content, "utf8").digest("hex");
|
|
12430
12641
|
if (actualHash === observation.hash) return null;
|
|
12431
12642
|
return { ...base, status: "modified", actualHash };
|
|
12432
12643
|
} catch (err) {
|
|
@@ -12435,8 +12646,8 @@ async function validateOne(observation, lexicalRoot, realRoot) {
|
|
|
12435
12646
|
}
|
|
12436
12647
|
}
|
|
12437
12648
|
async function validateResumeFileObservations(events, projectRoot) {
|
|
12438
|
-
const lexicalRoot =
|
|
12439
|
-
const realRoot = await
|
|
12649
|
+
const lexicalRoot = path10.resolve(projectRoot);
|
|
12650
|
+
const realRoot = await fsp8.realpath(lexicalRoot).catch(() => lexicalRoot);
|
|
12440
12651
|
const observations = latestObservations(events, lexicalRoot);
|
|
12441
12652
|
const results = await mapWithConcurrency(
|
|
12442
12653
|
observations,
|
|
@@ -12451,10 +12662,10 @@ async function validateResumeFileObservations(events, projectRoot) {
|
|
|
12451
12662
|
}
|
|
12452
12663
|
function formatResumeValidationNotice(validation, projectRoot) {
|
|
12453
12664
|
if (validation.staleFiles.length === 0) return null;
|
|
12454
|
-
const root =
|
|
12665
|
+
const root = path10.resolve(projectRoot);
|
|
12455
12666
|
const shown = validation.staleFiles.slice(0, NOTICE_PATH_LIMIT).map((entry) => {
|
|
12456
|
-
const
|
|
12457
|
-
const display = isInside2(root, entry.path) ?
|
|
12667
|
+
const relative4 = path10.relative(root, entry.path);
|
|
12668
|
+
const display = isInside2(root, entry.path) ? relative4 || "." : entry.path;
|
|
12458
12669
|
return `- ${JSON.stringify(display)} [${entry.status}]`;
|
|
12459
12670
|
});
|
|
12460
12671
|
const omitted = validation.staleFiles.length - shown.length;
|
|
@@ -12575,9 +12786,9 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
12575
12786
|
static LIST_SCAN_CONCURRENCY = 32;
|
|
12576
12787
|
constructor(opts) {
|
|
12577
12788
|
this.dir = opts.dir;
|
|
12578
|
-
this.projectRoot = opts.projectRoot ?
|
|
12789
|
+
this.projectRoot = opts.projectRoot ? path11.resolve(opts.projectRoot) : void 0;
|
|
12579
12790
|
this.checkpointCas = this.projectRoot ? new SessionCheckpointCas({
|
|
12580
|
-
rootDir:
|
|
12791
|
+
rootDir: path11.join(this.dir, "_cas"),
|
|
12581
12792
|
projectRoot: this.projectRoot
|
|
12582
12793
|
}) : void 0;
|
|
12583
12794
|
this.events = opts.events;
|
|
@@ -12631,17 +12842,17 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
12631
12842
|
}
|
|
12632
12843
|
/** Absolute path to the session index file. */
|
|
12633
12844
|
get indexFile() {
|
|
12634
|
-
return
|
|
12845
|
+
return path11.join(this.dir, "_index.jsonl");
|
|
12635
12846
|
}
|
|
12636
12847
|
/** Join session ID to its absolute path within the store directory. */
|
|
12637
12848
|
sessionPath(id, ext) {
|
|
12638
12849
|
return sessionScopedPath(this.dir, id, ext);
|
|
12639
12850
|
}
|
|
12640
12851
|
shardManifestPath(shardKey) {
|
|
12641
|
-
return shardKey ?
|
|
12852
|
+
return shardKey ? path11.join(this.dir, shardKey, "_manifest.json") : path11.join(this.dir, "_manifest.json");
|
|
12642
12853
|
}
|
|
12643
12854
|
shardKeyForSessionId(id) {
|
|
12644
|
-
const dirName =
|
|
12855
|
+
const dirName = path11.dirname(id);
|
|
12645
12856
|
return dirName === "." ? "" : dirName;
|
|
12646
12857
|
}
|
|
12647
12858
|
invalidateShardManifestBySessionId(id) {
|
|
@@ -12653,7 +12864,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
12653
12864
|
* subdirectory so sessions group naturally by day.
|
|
12654
12865
|
*/
|
|
12655
12866
|
async ensureShardDir(id) {
|
|
12656
|
-
const dirPath =
|
|
12867
|
+
const dirPath = path11.dirname(sessionScopedPath(this.dir, id, ""));
|
|
12657
12868
|
await ensureDir(dirPath);
|
|
12658
12869
|
return dirPath;
|
|
12659
12870
|
}
|
|
@@ -12715,7 +12926,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
12715
12926
|
}
|
|
12716
12927
|
const parentPrefix = parent.events.slice(0, boundary + 1);
|
|
12717
12928
|
const workspaceCheckpoint = targetCheckpoint?.workspaceCheckpoint;
|
|
12718
|
-
const checkpointHash =
|
|
12929
|
+
const checkpointHash = createHash4("sha256").update(parentPrefix.map((event) => JSON.stringify(event)).join("\n") + "\n", "utf8").digest("hex");
|
|
12719
12930
|
const inherited = parentPrefix.filter(inheritsIntoFork);
|
|
12720
12931
|
const writer = await this.create({
|
|
12721
12932
|
id: "",
|
|
@@ -12810,7 +13021,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
12810
13021
|
// Shard directory (sessions/<date>/) — must match create() so the
|
|
12811
13022
|
// .summary.json sidecar lands next to the JSONL instead of the
|
|
12812
13023
|
// sessions root (where summaryFor() would never find it).
|
|
12813
|
-
dir:
|
|
13024
|
+
dir: path11.dirname(file),
|
|
12814
13025
|
filePath: file,
|
|
12815
13026
|
secretScrubber: this.secretScrubber,
|
|
12816
13027
|
checkpointCas: this.checkpointCas,
|
|
@@ -13365,7 +13576,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
13365
13576
|
return entry;
|
|
13366
13577
|
}
|
|
13367
13578
|
async collectSessionFilesInShard(shardKey) {
|
|
13368
|
-
const dir = shardKey ?
|
|
13579
|
+
const dir = shardKey ? path11.join(this.dir, shardKey) : this.dir;
|
|
13369
13580
|
const entries = await this.collectSessionFiles(dir, shardKey);
|
|
13370
13581
|
return shardKey ? entries.filter((entry) => entry.id.startsWith(`${shardKey}/`)) : entries.filter((entry) => !entry.id.includes("/"));
|
|
13371
13582
|
}
|
|
@@ -13388,13 +13599,13 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
13388
13599
|
if (entry.name === "_index.jsonl") continue;
|
|
13389
13600
|
const base = entry.name.replace(/\.jsonl$/, "");
|
|
13390
13601
|
const id = prefix ? `${prefix}/${base}` : base;
|
|
13391
|
-
files.push({ id, filePath:
|
|
13602
|
+
files.push({ id, filePath: path11.join(dir, entry.name) });
|
|
13392
13603
|
}
|
|
13393
13604
|
}
|
|
13394
13605
|
const childFileArrays = await Promise.all(
|
|
13395
13606
|
dirEntries.map((entry) => {
|
|
13396
13607
|
const childPrefix = depth === 0 ? entry.name : `${prefix}/${entry.name}`;
|
|
13397
|
-
return this.collectSessionFiles(
|
|
13608
|
+
return this.collectSessionFiles(path11.join(dir, entry.name), childPrefix, depth + 1);
|
|
13398
13609
|
})
|
|
13399
13610
|
);
|
|
13400
13611
|
return [...childFileArrays.flat(), ...files];
|
|
@@ -13427,7 +13638,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
13427
13638
|
const childIdArrays = await Promise.all(
|
|
13428
13639
|
dirEntries.map((entry) => {
|
|
13429
13640
|
const childPrefix = depth === 0 ? entry.name : `${prefix}/${entry.name}`;
|
|
13430
|
-
return this.collectSessionIds(
|
|
13641
|
+
return this.collectSessionIds(path11.join(dir, entry.name), childPrefix, depth + 1);
|
|
13431
13642
|
})
|
|
13432
13643
|
);
|
|
13433
13644
|
return [...childIdArrays.flat(), ...fileIds];
|
|
@@ -13544,9 +13755,9 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
13544
13755
|
async deleteSession(id) {
|
|
13545
13756
|
const jsonlPath = this.sessionPath(id, ".jsonl");
|
|
13546
13757
|
const summaryPath = this.sessionPath(id, ".summary.json");
|
|
13547
|
-
const shardDir =
|
|
13548
|
-
const base =
|
|
13549
|
-
const sessDir =
|
|
13758
|
+
const shardDir = path11.dirname(jsonlPath);
|
|
13759
|
+
const base = path11.basename(id);
|
|
13760
|
+
const sessDir = path11.join(shardDir, base);
|
|
13550
13761
|
const deletions = [
|
|
13551
13762
|
fsp9.unlink(jsonlPath),
|
|
13552
13763
|
fsp9.unlink(summaryPath),
|
|
@@ -13587,7 +13798,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
13587
13798
|
*/
|
|
13588
13799
|
async readActiveSessionId() {
|
|
13589
13800
|
try {
|
|
13590
|
-
const raw = await fsp9.readFile(
|
|
13801
|
+
const raw = await fsp9.readFile(path11.join(this.dir, "active.json"), "utf8");
|
|
13591
13802
|
const active = JSON.parse(raw);
|
|
13592
13803
|
return active.sessionId ?? null;
|
|
13593
13804
|
} catch {
|
|
@@ -13650,7 +13861,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
13650
13861
|
const activeSessionId = await this.readActiveSessionId();
|
|
13651
13862
|
const isPrunableJsonl = (name) => name.endsWith(".jsonl") && name !== "_index.jsonl" && name !== "_mailbox.jsonl" && !name.endsWith(".replay.jsonl") && !name.endsWith(".audit.jsonl");
|
|
13652
13863
|
const pruneFile = async (dir, name, prefix) => {
|
|
13653
|
-
const jsonlPath =
|
|
13864
|
+
const jsonlPath = path11.join(dir, name);
|
|
13654
13865
|
try {
|
|
13655
13866
|
const stat13 = await fsp9.stat(jsonlPath);
|
|
13656
13867
|
if (stat13.mtimeMs >= cutoff) return;
|
|
@@ -13670,7 +13881,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
13670
13881
|
continue;
|
|
13671
13882
|
}
|
|
13672
13883
|
if (!entry.isDirectory()) continue;
|
|
13673
|
-
const dateDir =
|
|
13884
|
+
const dateDir = path11.join(this.dir, entry.name);
|
|
13674
13885
|
const files = await fsp9.readdir(dateDir, { withFileTypes: true }).catch(() => []);
|
|
13675
13886
|
for (const file of files) {
|
|
13676
13887
|
if (!file.isFile() || !isPrunableJsonl(file.name)) continue;
|
|
@@ -13682,7 +13893,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
13682
13893
|
}
|
|
13683
13894
|
for (const entry of entries) {
|
|
13684
13895
|
if (!entry.isDirectory()) continue;
|
|
13685
|
-
const dateDir =
|
|
13896
|
+
const dateDir = path11.join(this.dir, entry.name);
|
|
13686
13897
|
try {
|
|
13687
13898
|
const remaining = await fsp9.readdir(dateDir);
|
|
13688
13899
|
if (remaining.length === 0) {
|
|
@@ -13813,9 +14024,9 @@ function makeDirectorSessionFactory(opts) {
|
|
|
13813
14024
|
let dir;
|
|
13814
14025
|
if (opts.store) {
|
|
13815
14026
|
store = opts.store;
|
|
13816
|
-
dir = opts.sessionsRoot ?
|
|
14027
|
+
dir = opts.sessionsRoot ? path12.join(opts.sessionsRoot, runId) : "(caller-managed)";
|
|
13817
14028
|
} else if (opts.sessionsRoot) {
|
|
13818
|
-
dir =
|
|
14029
|
+
dir = path12.join(opts.sessionsRoot, runId);
|
|
13819
14030
|
store = new DefaultSessionStore({ dir });
|
|
13820
14031
|
} else {
|
|
13821
14032
|
throw new Error("makeDirectorSessionFactory requires either `store` or `sessionsRoot`");
|
|
@@ -14337,6 +14548,9 @@ var AutonomousRunner = class {
|
|
|
14337
14548
|
this.stopped = true;
|
|
14338
14549
|
}
|
|
14339
14550
|
};
|
|
14551
|
+
|
|
14552
|
+
// src/storage/goal-store.ts
|
|
14553
|
+
import * as fsp10 from "node:fs/promises";
|
|
14340
14554
|
var MAX_JOURNAL_ENTRIES = 500;
|
|
14341
14555
|
function goalFilePath(projectRoot) {
|
|
14342
14556
|
return resolveWstackPaths({ projectRoot }).projectGoal;
|
|
@@ -14345,7 +14559,7 @@ async function loadGoal(filePath, events) {
|
|
|
14345
14559
|
const t0 = Date.now();
|
|
14346
14560
|
let raw;
|
|
14347
14561
|
try {
|
|
14348
|
-
raw = await
|
|
14562
|
+
raw = await fsp10.readFile(filePath, "utf8");
|
|
14349
14563
|
} catch (err) {
|
|
14350
14564
|
const code = err.code;
|
|
14351
14565
|
if (code === "ENOENT") {
|
|
@@ -15147,6 +15361,12 @@ var DESIGN_STACKS = ["web", "react-native", "flutter", "swiftui", "compose"];
|
|
|
15147
15361
|
function isDesignStack(v) {
|
|
15148
15362
|
return DESIGN_STACKS.includes(v);
|
|
15149
15363
|
}
|
|
15364
|
+
|
|
15365
|
+
// src/execution/design-kit-loader.ts
|
|
15366
|
+
import { existsSync } from "node:fs";
|
|
15367
|
+
import * as fs2 from "node:fs/promises";
|
|
15368
|
+
import * as path13 from "node:path";
|
|
15369
|
+
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
15150
15370
|
var KIT_FILE = "KIT.md";
|
|
15151
15371
|
var TOKENS_FILE = "tokens.json";
|
|
15152
15372
|
var FOUNDATIONS_ID = "_foundations";
|
|
@@ -15253,15 +15473,15 @@ var DefaultDesignKitLoader = class {
|
|
|
15253
15473
|
for (const { dir, source } of this.dirs) {
|
|
15254
15474
|
let entries;
|
|
15255
15475
|
try {
|
|
15256
|
-
entries = await
|
|
15476
|
+
entries = await fs2.readdir(dir, { withFileTypes: true });
|
|
15257
15477
|
} catch {
|
|
15258
15478
|
continue;
|
|
15259
15479
|
}
|
|
15260
15480
|
for (const e of entries) {
|
|
15261
15481
|
if (!e.isDirectory()) continue;
|
|
15262
|
-
const kitFile =
|
|
15482
|
+
const kitFile = path13.join(dir, e.name, KIT_FILE);
|
|
15263
15483
|
try {
|
|
15264
|
-
const raw = await
|
|
15484
|
+
const raw = await fs2.readFile(kitFile, "utf8");
|
|
15265
15485
|
const fm = parseKitFrontmatter(raw);
|
|
15266
15486
|
const id = fm.id ?? e.name;
|
|
15267
15487
|
if (!fm.name) continue;
|
|
@@ -15322,7 +15542,7 @@ var DefaultDesignKitLoader = class {
|
|
|
15322
15542
|
if (cached !== void 0) return cached;
|
|
15323
15543
|
const m = await this.find(id);
|
|
15324
15544
|
if (!m) throw new Error(`Design kit "${id}" not found`);
|
|
15325
|
-
const raw = await
|
|
15545
|
+
const raw = await fs2.readFile(m.path, "utf8");
|
|
15326
15546
|
const body = narrowStackSections(stripFrontmatter(raw), stack);
|
|
15327
15547
|
this.bodyCache.set(key, body);
|
|
15328
15548
|
return body;
|
|
@@ -15333,9 +15553,9 @@ var DefaultDesignKitLoader = class {
|
|
|
15333
15553
|
const m = await this.find(id);
|
|
15334
15554
|
let tokens;
|
|
15335
15555
|
if (m) {
|
|
15336
|
-
const tokensPath =
|
|
15556
|
+
const tokensPath = path13.join(path13.dirname(m.path), TOKENS_FILE);
|
|
15337
15557
|
try {
|
|
15338
|
-
const raw = await
|
|
15558
|
+
const raw = await fs2.readFile(tokensPath, "utf8");
|
|
15339
15559
|
const parsed = JSON.parse(raw);
|
|
15340
15560
|
tokens = parsed;
|
|
15341
15561
|
} catch {
|
|
@@ -15360,12 +15580,12 @@ var DefaultDesignKitLoader = class {
|
|
|
15360
15580
|
};
|
|
15361
15581
|
function resolveBundledDesignKitsDir() {
|
|
15362
15582
|
try {
|
|
15363
|
-
const here =
|
|
15583
|
+
const here = path13.dirname(fileURLToPath3(import.meta.url));
|
|
15364
15584
|
const candidates = [
|
|
15365
|
-
|
|
15366
|
-
|
|
15367
|
-
|
|
15368
|
-
|
|
15585
|
+
path13.join(here, "design-kits"),
|
|
15586
|
+
path13.join(here, "..", "design-kits"),
|
|
15587
|
+
path13.join(here, "..", "..", "design-kits"),
|
|
15588
|
+
path13.join(here, "..", "..", "..", "design-kits")
|
|
15369
15589
|
];
|
|
15370
15590
|
for (const c of candidates) {
|
|
15371
15591
|
if (existsSync(c)) return c;
|
|
@@ -15390,9 +15610,14 @@ function getDesignKitLoader(projectRoot) {
|
|
|
15390
15610
|
function _resetDesignKitLoaderMemo() {
|
|
15391
15611
|
loaderMemo.clear();
|
|
15392
15612
|
}
|
|
15613
|
+
|
|
15614
|
+
// src/execution/design-project-store.ts
|
|
15615
|
+
import { existsSync as existsSync2 } from "node:fs";
|
|
15616
|
+
import * as fs3 from "node:fs/promises";
|
|
15617
|
+
import * as path14 from "node:path";
|
|
15393
15618
|
var DESIGN_DIR = ".design";
|
|
15394
15619
|
function designProjectDir(projectRoot) {
|
|
15395
|
-
return
|
|
15620
|
+
return path14.join(projectRoot, DESIGN_DIR);
|
|
15396
15621
|
}
|
|
15397
15622
|
var RULE_FILES = ["rules.md", "RULES.md", "design.md"];
|
|
15398
15623
|
var rulesCache = /* @__PURE__ */ new Map();
|
|
@@ -15401,7 +15626,7 @@ async function loadProjectDesignRules(projectRoot) {
|
|
|
15401
15626
|
let rules;
|
|
15402
15627
|
for (const name of RULE_FILES) {
|
|
15403
15628
|
try {
|
|
15404
|
-
const txt = await
|
|
15629
|
+
const txt = await fs3.readFile(path14.join(designProjectDir(projectRoot), name), "utf8");
|
|
15405
15630
|
if (txt.trim()) {
|
|
15406
15631
|
rules = txt.trim();
|
|
15407
15632
|
break;
|
|
@@ -15422,7 +15647,7 @@ function parseOverrides(value) {
|
|
|
15422
15647
|
}
|
|
15423
15648
|
async function loadActiveKit(projectRoot) {
|
|
15424
15649
|
try {
|
|
15425
|
-
const raw = await
|
|
15650
|
+
const raw = await fs3.readFile(path14.join(designProjectDir(projectRoot), "active.json"), "utf8");
|
|
15426
15651
|
const parsed = JSON.parse(raw);
|
|
15427
15652
|
if (parsed && typeof parsed.kit === "string") {
|
|
15428
15653
|
return {
|
|
@@ -15455,11 +15680,11 @@ function applyTokenOverrides(tokens, overrides) {
|
|
|
15455
15680
|
}
|
|
15456
15681
|
async function ensureDesignDir(projectRoot) {
|
|
15457
15682
|
const dir = designProjectDir(projectRoot);
|
|
15458
|
-
await
|
|
15459
|
-
const gi =
|
|
15460
|
-
if (!
|
|
15683
|
+
await fs3.mkdir(dir, { recursive: true });
|
|
15684
|
+
const gi = path14.join(dir, ".gitignore");
|
|
15685
|
+
if (!existsSync2(gi)) {
|
|
15461
15686
|
try {
|
|
15462
|
-
await
|
|
15687
|
+
await fs3.writeFile(gi, "*\n");
|
|
15463
15688
|
} catch {
|
|
15464
15689
|
}
|
|
15465
15690
|
}
|
|
@@ -15470,11 +15695,11 @@ async function recordKitChoice(projectRoot, kit, stack, source, isoTime, overrid
|
|
|
15470
15695
|
const dir = await ensureDesignDir(projectRoot);
|
|
15471
15696
|
const record = { kit, stack: stack ?? null };
|
|
15472
15697
|
if (overrides && Object.keys(overrides).length > 0) record.overrides = overrides;
|
|
15473
|
-
await
|
|
15698
|
+
await fs3.writeFile(path14.join(dir, "active.json"), `${JSON.stringify(record, null, 2)}
|
|
15474
15699
|
`);
|
|
15475
15700
|
const line = `- ${isoTime} \xB7 kit=${kit}${stack ? ` stack=${stack}` : ""} \xB7 via=${source}
|
|
15476
15701
|
`;
|
|
15477
|
-
await
|
|
15702
|
+
await fs3.appendFile(path14.join(dir, "decisions.md"), line);
|
|
15478
15703
|
} catch {
|
|
15479
15704
|
}
|
|
15480
15705
|
}
|
|
@@ -15490,11 +15715,11 @@ async function recordOverrides(projectRoot, patch, isoTime) {
|
|
|
15490
15715
|
const dir = await ensureDesignDir(projectRoot);
|
|
15491
15716
|
const record = { kit: active.kit, stack: active.stack ?? null };
|
|
15492
15717
|
if (Object.keys(merged).length > 0) record.overrides = merged;
|
|
15493
|
-
await
|
|
15718
|
+
await fs3.writeFile(path14.join(dir, "active.json"), `${JSON.stringify(record, null, 2)}
|
|
15494
15719
|
`);
|
|
15495
15720
|
const keys = Object.keys(patch).join(",");
|
|
15496
|
-
await
|
|
15497
|
-
|
|
15721
|
+
await fs3.appendFile(
|
|
15722
|
+
path14.join(dir, "decisions.md"),
|
|
15498
15723
|
`- ${isoTime} \xB7 kit=${active.kit} \xB7 override=${keys} \xB7 via=set
|
|
15499
15724
|
`
|
|
15500
15725
|
);
|
|
@@ -15504,7 +15729,7 @@ async function recordOverrides(projectRoot, patch, isoTime) {
|
|
|
15504
15729
|
}
|
|
15505
15730
|
async function clearPersistedActiveKit(projectRoot) {
|
|
15506
15731
|
try {
|
|
15507
|
-
await
|
|
15732
|
+
await fs3.rm(path14.join(designProjectDir(projectRoot), "active.json"), { force: true });
|
|
15508
15733
|
} catch {
|
|
15509
15734
|
}
|
|
15510
15735
|
}
|
|
@@ -15620,12 +15845,12 @@ function verifyFiles(tokens, files) {
|
|
|
15620
15845
|
const violations = [];
|
|
15621
15846
|
let onPalette = 0;
|
|
15622
15847
|
let offPalette = 0;
|
|
15623
|
-
for (const { path:
|
|
15848
|
+
for (const { path: path29, text } of files) {
|
|
15624
15849
|
const lines = text.split("\n");
|
|
15625
15850
|
lines.forEach((lineText, i) => {
|
|
15626
15851
|
const lineNo = i + 1;
|
|
15627
15852
|
const flag = (snippet, reason) => {
|
|
15628
|
-
violations.push({ file:
|
|
15853
|
+
violations.push({ file: path29, line: lineNo, snippet: snippet.slice(0, 80), reason });
|
|
15629
15854
|
};
|
|
15630
15855
|
for (const re of [HEX_RE, FUNC_COLOR_RE]) {
|
|
15631
15856
|
re.lastIndex = 0;
|
|
@@ -15677,8 +15902,8 @@ var SKIP_DIR = /* @__PURE__ */ new Set([
|
|
|
15677
15902
|
".design"
|
|
15678
15903
|
]);
|
|
15679
15904
|
async function walkUiFiles(root, max = 200) {
|
|
15680
|
-
const { default: fs15 } = await import(
|
|
15681
|
-
const { default: nodePath } = await import(
|
|
15905
|
+
const { default: fs15 } = await import("node:fs/promises");
|
|
15906
|
+
const { default: nodePath } = await import("node:path");
|
|
15682
15907
|
const found = [];
|
|
15683
15908
|
async function rec(dir, depth) {
|
|
15684
15909
|
if (found.length >= max || depth > 8) return;
|
|
@@ -15702,8 +15927,8 @@ async function walkUiFiles(root, max = 200) {
|
|
|
15702
15927
|
return found;
|
|
15703
15928
|
}
|
|
15704
15929
|
async function runDesignVerify(projectRoot, tokens, explicitFiles) {
|
|
15705
|
-
const { default: fs15 } = await import(
|
|
15706
|
-
const { default: nodePath } = await import(
|
|
15930
|
+
const { default: fs15 } = await import("node:fs/promises");
|
|
15931
|
+
const { default: nodePath } = await import("node:path");
|
|
15707
15932
|
const abs = explicitFiles && explicitFiles.length > 0 ? explicitFiles.map((f) => nodePath.isAbsolute(f) ? f : nodePath.join(projectRoot, f)) : await walkUiFiles(projectRoot);
|
|
15708
15933
|
const files = [];
|
|
15709
15934
|
for (const a of abs) {
|
|
@@ -15839,8 +16064,8 @@ function makeDesignVerifyToolCallMiddleware() {
|
|
|
15839
16064
|
const p = typeof input?.path === "string" ? input.path : "";
|
|
15840
16065
|
if (!p || !detectFrontendFile(p)) return out;
|
|
15841
16066
|
const ctx = out.ctx;
|
|
15842
|
-
const { default: fs15 } = await import(
|
|
15843
|
-
const { default: nodePath } = await import(
|
|
16067
|
+
const { default: fs15 } = await import("node:fs/promises");
|
|
16068
|
+
const { default: nodePath } = await import("node:path");
|
|
15844
16069
|
const abs = nodePath.isAbsolute(p) ? p : nodePath.join(ctx.projectRoot, p);
|
|
15845
16070
|
const text = await fs15.readFile(abs, "utf8").catch(() => "");
|
|
15846
16071
|
if (!text) return out;
|
|
@@ -16144,14 +16369,75 @@ function buildRecoveryStrategies(opts) {
|
|
|
16144
16369
|
if (err.kind !== "overloaded" && err.kind !== "server" && err.kind !== "stream_hang") {
|
|
16145
16370
|
return null;
|
|
16146
16371
|
}
|
|
16147
|
-
|
|
16372
|
+
const registry = opts?.modelsRegistry;
|
|
16373
|
+
if (!registry) return null;
|
|
16374
|
+
try {
|
|
16375
|
+
const providerId = ctx.provider?.id;
|
|
16376
|
+
if (!providerId) return null;
|
|
16377
|
+
const provider = await registry.getProvider(providerId);
|
|
16378
|
+
if (!provider) return null;
|
|
16379
|
+
const currentModel = await registry.getModel(providerId, ctx.model);
|
|
16380
|
+
if (!currentModel) return null;
|
|
16381
|
+
const visibleModels = opts?.getConfig?.().providers?.[providerId]?.models;
|
|
16382
|
+
const candidates = provider.models.filter((m) => {
|
|
16383
|
+
if (visibleModels !== void 0 && !visibleModels.includes(m.id)) return false;
|
|
16384
|
+
const modelCost = m.cost?.input ?? Number.POSITIVE_INFINITY;
|
|
16385
|
+
const currentCost = currentModel.cost?.input ?? Number.POSITIVE_INFINITY;
|
|
16386
|
+
if (modelCost >= currentCost) return false;
|
|
16387
|
+
if (currentModel.capabilities.tools && !m.tool_call) return false;
|
|
16388
|
+
if (currentModel.capabilities.vision && !m.modalities?.input?.includes("image"))
|
|
16389
|
+
return false;
|
|
16390
|
+
return true;
|
|
16391
|
+
});
|
|
16392
|
+
if (candidates.length === 0) return null;
|
|
16393
|
+
const fallback = candidates.reduce(
|
|
16394
|
+
(prev, curr) => (curr.cost?.input ?? Number.POSITIVE_INFINITY) < (prev.cost?.input ?? Number.POSITIVE_INFINITY) ? curr : prev
|
|
16395
|
+
);
|
|
16396
|
+
return {
|
|
16397
|
+
action: "retry",
|
|
16398
|
+
reason: "model_downgrade",
|
|
16399
|
+
model: fallback.id
|
|
16400
|
+
};
|
|
16401
|
+
} catch {
|
|
16402
|
+
return null;
|
|
16403
|
+
}
|
|
16148
16404
|
}
|
|
16149
16405
|
},
|
|
16150
16406
|
{
|
|
16151
16407
|
label: "content_filter_reroute",
|
|
16152
16408
|
async attempt(err, ctx) {
|
|
16153
16409
|
if (!(err instanceof ProviderError) || err.kind !== "content_filter") return null;
|
|
16154
|
-
|
|
16410
|
+
const registry = opts?.modelsRegistry;
|
|
16411
|
+
if (!registry) return null;
|
|
16412
|
+
try {
|
|
16413
|
+
const providerId = ctx.provider?.id;
|
|
16414
|
+
if (!providerId) return null;
|
|
16415
|
+
const provider = await registry.getProvider(providerId);
|
|
16416
|
+
if (!provider) return null;
|
|
16417
|
+
const currentModel = await registry.getModel(providerId, ctx.model);
|
|
16418
|
+
if (!currentModel) return null;
|
|
16419
|
+
const visibleModels = opts?.getConfig?.().providers?.[providerId]?.models;
|
|
16420
|
+
const candidates = provider.models.filter((m) => {
|
|
16421
|
+
if (m.id === ctx.model) return false;
|
|
16422
|
+
if (visibleModels !== void 0 && !visibleModels.includes(m.id)) return false;
|
|
16423
|
+
if (currentModel.capabilities.tools && !m.tool_call) return false;
|
|
16424
|
+
if (currentModel.capabilities.vision && !m.modalities?.input?.includes("image"))
|
|
16425
|
+
return false;
|
|
16426
|
+
return true;
|
|
16427
|
+
});
|
|
16428
|
+
if (candidates.length === 0) return null;
|
|
16429
|
+
const currentCost = currentModel.cost?.input;
|
|
16430
|
+
const distance = (m) => currentCost === void 0 || m.cost?.input === void 0 ? Number.POSITIVE_INFINITY : Math.abs(m.cost.input - currentCost);
|
|
16431
|
+
const reroute = candidates.reduce((prev, curr) => {
|
|
16432
|
+
const delta = distance(curr) - distance(prev);
|
|
16433
|
+
if (delta < 0) return curr;
|
|
16434
|
+
if (delta === 0 && curr.id < prev.id) return curr;
|
|
16435
|
+
return prev;
|
|
16436
|
+
});
|
|
16437
|
+
return { action: "retry", reason: "content_filter_reroute", model: reroute.id };
|
|
16438
|
+
} catch {
|
|
16439
|
+
return null;
|
|
16440
|
+
}
|
|
16155
16441
|
}
|
|
16156
16442
|
}
|
|
16157
16443
|
];
|
|
@@ -16202,6 +16488,10 @@ var DefaultErrorHandler = class {
|
|
|
16202
16488
|
}
|
|
16203
16489
|
};
|
|
16204
16490
|
|
|
16491
|
+
// src/execution/eternal-autonomy.ts
|
|
16492
|
+
import { execFile } from "node:child_process";
|
|
16493
|
+
import { promisify } from "node:util";
|
|
16494
|
+
|
|
16205
16495
|
// src/execution/autonomy-brain.ts
|
|
16206
16496
|
function formatDecisionSummary(decision, request) {
|
|
16207
16497
|
const question = request.question.length > 80 ? request.question.slice(0, 77) + "\u2026" : request.question;
|
|
@@ -16694,8 +16984,8 @@ ${recentJournal}` : "No prior iterations.",
|
|
|
16694
16984
|
" \u2022 When this iteration's Task is finished (real artifact / passing",
|
|
16695
16985
|
" test / applied diff / clean output), emit `[done]` on its own line.",
|
|
16696
16986
|
" \u2022 Do not stop on the first obstacle \u2014 try at least 3 distinct",
|
|
16697
|
-
" approaches before giving up. YOLO is active
|
|
16698
|
-
"
|
|
16987
|
+
" approaches before giving up. YOLO is active unless an explicit",
|
|
16988
|
+
" deny rule blocks the call.",
|
|
16699
16989
|
"",
|
|
16700
16990
|
"2. UPDATE TODO STATE (when Source is `todo`)",
|
|
16701
16991
|
" \u2022 Mark this todo `in_progress` via the todos tool before tool work.",
|
|
@@ -16802,7 +17092,7 @@ ${recentJournal}` : "No prior iterations.",
|
|
|
16802
17092
|
await saveGoal(this.goalPath, abandoned, this.opts.events);
|
|
16803
17093
|
}
|
|
16804
17094
|
try {
|
|
16805
|
-
const { unlink: unlink12 } = await import(
|
|
17095
|
+
const { unlink: unlink12 } = await import("node:fs/promises");
|
|
16806
17096
|
await unlink12(this.goalPath);
|
|
16807
17097
|
} catch {
|
|
16808
17098
|
}
|
|
@@ -17041,6 +17331,9 @@ var IntelligentCompactor = class {
|
|
|
17041
17331
|
return [{ type: "text", text: lines.join("\n") }];
|
|
17042
17332
|
}
|
|
17043
17333
|
};
|
|
17334
|
+
|
|
17335
|
+
// src/execution/parallel-eternal-engine.ts
|
|
17336
|
+
import { randomUUID as randomUUID8 } from "node:crypto";
|
|
17044
17337
|
var GOAL_COMPLETE_MARKER2 = /^\s*\[goal[_\s-]?complete\]\s*$/im;
|
|
17045
17338
|
var ParallelEternalEngine = class {
|
|
17046
17339
|
constructor(opts) {
|
|
@@ -17099,7 +17392,7 @@ var ParallelEternalEngine = class {
|
|
|
17099
17392
|
this.state = "running";
|
|
17100
17393
|
await this.persistState("running");
|
|
17101
17394
|
const config = {
|
|
17102
|
-
coordinatorId: `parallel-${
|
|
17395
|
+
coordinatorId: `parallel-${randomUUID8().slice(0, 8)}`,
|
|
17103
17396
|
maxConcurrent: this.slots,
|
|
17104
17397
|
doneCondition: { type: "all_tasks_done" }
|
|
17105
17398
|
};
|
|
@@ -17153,7 +17446,7 @@ var ParallelEternalEngine = class {
|
|
|
17153
17446
|
}
|
|
17154
17447
|
if (!this.coordinator) {
|
|
17155
17448
|
const config = {
|
|
17156
|
-
coordinatorId: `parallel-${
|
|
17449
|
+
coordinatorId: `parallel-${randomUUID8().slice(0, 8)}`,
|
|
17157
17450
|
maxConcurrent: this.slots,
|
|
17158
17451
|
doneCondition: { type: "all_tasks_done" }
|
|
17159
17452
|
};
|
|
@@ -17227,8 +17520,7 @@ ${recentJournal}` : "No prior iterations.",
|
|
|
17227
17520
|
"\u2500\u2500 EXECUTION PROTOCOL \u2500\u2500",
|
|
17228
17521
|
"\u2022 Execute the assigned task end-to-end using multiple tool calls.",
|
|
17229
17522
|
"\u2022 Emit `[done]` on its own line when the task is complete.",
|
|
17230
|
-
"\u2022 Do not ask before
|
|
17231
|
-
"\u2022 If a destructive-gated confirmation appears, wait for the permission flow.",
|
|
17523
|
+
"\u2022 Do not ask before tool use \u2014 YOLO is active unless an explicit deny rule blocks the call.",
|
|
17232
17524
|
"\u2022 If the overall Mission is accomplished, emit `[GOAL_COMPLETE]` followed by a verification recipe.",
|
|
17233
17525
|
"\u2022 Keep output concise \u2014 summarize findings, do not transcribe files."
|
|
17234
17526
|
].join("\n");
|
|
@@ -17240,7 +17532,7 @@ ${recentJournal}` : "No prior iterations.",
|
|
|
17240
17532
|
const task = expectDefined(tasks[i]);
|
|
17241
17533
|
const route = routes[i] ?? null;
|
|
17242
17534
|
const subagentId = `parallel-${this.iterations}-${i}`;
|
|
17243
|
-
const taskId =
|
|
17535
|
+
const taskId = randomUUID8();
|
|
17244
17536
|
const personaLine = route ? `Acting agent: ${route.definition.config.name} \u2014 ${route.definition.capability.summary}
|
|
17245
17537
|
` : "";
|
|
17246
17538
|
const spec = {
|
|
@@ -17375,8 +17667,8 @@ ${personaLine}Task: ${task}
|
|
|
17375
17667
|
return tasks.length > 0 ? tasks.slice(0, this.slots) : null;
|
|
17376
17668
|
}
|
|
17377
17669
|
async readGitStatus() {
|
|
17378
|
-
const { execFile: execFile2 } = await import(
|
|
17379
|
-
const { promisify: promisify2 } = await import(
|
|
17670
|
+
const { execFile: execFile2 } = await import("node:child_process");
|
|
17671
|
+
const { promisify: promisify2 } = await import("node:util");
|
|
17380
17672
|
const execFileP2 = promisify2(execFile2);
|
|
17381
17673
|
const { stdout } = await execFileP2("git", ["status", "--porcelain"], {
|
|
17382
17674
|
cwd: this.opts.projectRoot,
|
|
@@ -17466,6 +17758,9 @@ ${lastFew}` : "No prior iterations.",
|
|
|
17466
17758
|
await saveGoal(this.goalPath, { ...current, engineState: state }, this.opts.events);
|
|
17467
17759
|
}
|
|
17468
17760
|
};
|
|
17761
|
+
|
|
17762
|
+
// src/core/streaming-response-builder.ts
|
|
17763
|
+
import { randomUUID as randomUUID9 } from "node:crypto";
|
|
17469
17764
|
var STREAM_DRAIN_TIMEOUT_MS = 500;
|
|
17470
17765
|
function buildResponse(state) {
|
|
17471
17766
|
const content = [];
|
|
@@ -17525,7 +17820,7 @@ function handleContentBlockStart(state, ev) {
|
|
|
17525
17820
|
state.textBuffers.push("");
|
|
17526
17821
|
state.blockOrder.push({ kind: "text", idx: state.currentTextIndex });
|
|
17527
17822
|
} else if (kind === "tool_use") {
|
|
17528
|
-
const id = ev.id ??
|
|
17823
|
+
const id = ev.id ?? randomUUID9();
|
|
17529
17824
|
state.tools.set(id, { name: ev.name ?? "unknown", partial: "" });
|
|
17530
17825
|
state.blockOrder.push({ kind: "tool", id });
|
|
17531
17826
|
state.currentTextIndex = -1;
|
|
@@ -17540,6 +17835,8 @@ function handleContentBlockStart(state, ev) {
|
|
|
17540
17835
|
}
|
|
17541
17836
|
}
|
|
17542
17837
|
function handleContentBlockStop(state, ev) {
|
|
17838
|
+
void state;
|
|
17839
|
+
void ev;
|
|
17543
17840
|
}
|
|
17544
17841
|
function handleTextDelta(state, text) {
|
|
17545
17842
|
if (state.currentTextIndex === -1) {
|
|
@@ -17732,8 +18029,8 @@ async function streamProviderToResponse(provider, req, signal, ctx, events, logg
|
|
|
17732
18029
|
});
|
|
17733
18030
|
await Promise.race([
|
|
17734
18031
|
drainPromise,
|
|
17735
|
-
new Promise((
|
|
17736
|
-
drainTimer = setTimeout(
|
|
18032
|
+
new Promise((resolve12) => {
|
|
18033
|
+
drainTimer = setTimeout(resolve12, STREAM_DRAIN_TIMEOUT_MS);
|
|
17737
18034
|
})
|
|
17738
18035
|
]);
|
|
17739
18036
|
} finally {
|
|
@@ -17844,7 +18141,7 @@ async function runProviderWithRetry(opts) {
|
|
|
17844
18141
|
description
|
|
17845
18142
|
});
|
|
17846
18143
|
}
|
|
17847
|
-
await new Promise((
|
|
18144
|
+
await new Promise((resolve12, reject) => {
|
|
17848
18145
|
let settled = false;
|
|
17849
18146
|
const cleanup = () => {
|
|
17850
18147
|
clearTimeout(t);
|
|
@@ -17860,7 +18157,7 @@ async function runProviderWithRetry(opts) {
|
|
|
17860
18157
|
if (settled) return;
|
|
17861
18158
|
settled = true;
|
|
17862
18159
|
cleanup();
|
|
17863
|
-
|
|
18160
|
+
resolve12();
|
|
17864
18161
|
}, delay);
|
|
17865
18162
|
if (signal.aborted) {
|
|
17866
18163
|
onAbort();
|
|
@@ -17879,6 +18176,9 @@ var DefaultProviderRunner = class {
|
|
|
17879
18176
|
return runProviderWithRetry(opts);
|
|
17880
18177
|
}
|
|
17881
18178
|
};
|
|
18179
|
+
|
|
18180
|
+
// src/execution/retry-policy.ts
|
|
18181
|
+
import { randomInt } from "node:crypto";
|
|
17882
18182
|
var MAX_RETRY_AFTER_MS = 6e4;
|
|
17883
18183
|
var MAX_ATTEMPTS_BY_KIND = {
|
|
17884
18184
|
rate_limit: 5,
|
|
@@ -18332,6 +18632,10 @@ Summarize the following message range:`;
|
|
|
18332
18632
|
}
|
|
18333
18633
|
};
|
|
18334
18634
|
|
|
18635
|
+
// src/execution/skill-loader.ts
|
|
18636
|
+
import * as fs4 from "node:fs/promises";
|
|
18637
|
+
import * as path15 from "node:path";
|
|
18638
|
+
|
|
18335
18639
|
// src/skills/foreign-sources.ts
|
|
18336
18640
|
var FOREIGN_SKILL_TOOLS = [
|
|
18337
18641
|
{ id: "agents", subdir: "skills" },
|
|
@@ -18447,6 +18751,56 @@ function isValidSkillNameFormat(name) {
|
|
|
18447
18751
|
|
|
18448
18752
|
// src/skills/limits.ts
|
|
18449
18753
|
var SKILL_LIMITS = {
|
|
18754
|
+
/**
|
|
18755
|
+
* Per-skill body cap when injecting a full skill body into the system prompt
|
|
18756
|
+
* (eager mode), and when returning a skill body from the `skill` tool.
|
|
18757
|
+
* ~4k tokens. Oversized bodies are truncated at a paragraph boundary.
|
|
18758
|
+
*
|
|
18759
|
+
* Consumers: `system-prompt-builder.capSkillBody`, `skill` tool body return.
|
|
18760
|
+
*/
|
|
18761
|
+
MAX_SKILL_BODY_CHARS: 16e3,
|
|
18762
|
+
/**
|
|
18763
|
+
* Per-resource cap when the `skill` tool loads a bundled file
|
|
18764
|
+
* (`scripts/`, `references/`, `assets/`). ~8k tokens.
|
|
18765
|
+
*
|
|
18766
|
+
* Consumer: `skill` tool `loadResource`.
|
|
18767
|
+
*/
|
|
18768
|
+
MAX_RESOURCE_CHARS: 32e3,
|
|
18769
|
+
/**
|
|
18770
|
+
* Maximum number of bundled resource paths the `skill` tool lists in one
|
|
18771
|
+
* response. Caps a pathological skill (huge `assets/` tree) from blowing up
|
|
18772
|
+
* the tool result.
|
|
18773
|
+
*
|
|
18774
|
+
* Consumer: `skill` tool resource listing.
|
|
18775
|
+
*/
|
|
18776
|
+
MAX_LISTED_RESOURCES: 100,
|
|
18777
|
+
/**
|
|
18778
|
+
* Max size of a single installed skill file (SKILL.md or a bundled resource).
|
|
18779
|
+
* Guards against a malicious registry skill shipping a multi-MB blob that
|
|
18780
|
+
* then flows into the prompt. 100KB.
|
|
18781
|
+
*
|
|
18782
|
+
* Consumer: `SkillInstaller.install` / `importFromDir`.
|
|
18783
|
+
*/
|
|
18784
|
+
MAX_SKILL_FILE_SIZE: 100 * 1024,
|
|
18785
|
+
/**
|
|
18786
|
+
* Max size of a GitHub tarball downloaded by the skill installer. Guards
|
|
18787
|
+
* against a repo accidentally (or maliciously) shipping a giant tarball that
|
|
18788
|
+
* would be extracted into a temp dir. 50MB.
|
|
18789
|
+
*
|
|
18790
|
+
* Consumer: `downloadGitHubTarball`.
|
|
18791
|
+
*/
|
|
18792
|
+
MAX_TARBALL_SIZE: 50 * 1024 * 1024,
|
|
18793
|
+
/**
|
|
18794
|
+
* Default total char budget for skill bodies injected in eager mode when
|
|
18795
|
+
* `config.skills.eagerMaxChars` is unset. ~6k tokens. Skills are injected
|
|
18796
|
+
* highest-priority first; once the budget is exhausted the remaining skills
|
|
18797
|
+
* are listed as a manifest the agent loads via the `skill` tool. Set very
|
|
18798
|
+
* high to effectively disable budgeting.
|
|
18799
|
+
*
|
|
18800
|
+
* Consumer: `DefaultSystemPromptBuilder.buildMemoryAndSkills` (default for
|
|
18801
|
+
* `skillEagerMaxChars`).
|
|
18802
|
+
*/
|
|
18803
|
+
EAGER_DEFAULT_MAX_CHARS: 24e3,
|
|
18450
18804
|
/**
|
|
18451
18805
|
* Auto-compact body limits (the token-saving fallback used when a skill has
|
|
18452
18806
|
* no hand-crafted `SKILL.save.md`). The Overview and Rules sections are
|
|
@@ -18456,7 +18810,24 @@ var SKILL_LIMITS = {
|
|
|
18456
18810
|
*/
|
|
18457
18811
|
COMPACT_OVERVIEW_MAX: 200,
|
|
18458
18812
|
COMPACT_RULES_MAX: 350,
|
|
18459
|
-
COMPACT_TOTAL_MAX: 450
|
|
18813
|
+
COMPACT_TOTAL_MAX: 450,
|
|
18814
|
+
/**
|
|
18815
|
+
* Max length of a skill name (agentskills.io spec). Enforced by the
|
|
18816
|
+
* frontmatter validator's format regex plus this length bound.
|
|
18817
|
+
*
|
|
18818
|
+
* Consumer: `isValidSkillNameFormat`.
|
|
18819
|
+
*/
|
|
18820
|
+
SKILL_NAME_MAX_LEN: 64,
|
|
18821
|
+
/**
|
|
18822
|
+
* Soft line limit for a SKILL.md body, per the bundled `skill-creator` rule.
|
|
18823
|
+
* Not enforced in code (a skill can exceed it) — surfaced by `/skill-gen
|
|
18824
|
+
* validate` and the `skill-creator` skill as guidance to move deep material
|
|
18825
|
+
* into `references/`.
|
|
18826
|
+
*
|
|
18827
|
+
* Consumer: `skill-creator` skill, `/skill-gen validate` advisory.
|
|
18828
|
+
*/
|
|
18829
|
+
SKILL_BODY_LINE_LIMIT: 500
|
|
18830
|
+
};
|
|
18460
18831
|
|
|
18461
18832
|
// src/execution/skill-loader.ts
|
|
18462
18833
|
function stripFrontmatter2(raw) {
|
|
@@ -18493,7 +18864,7 @@ async function entryIsDirectory(dir, entry) {
|
|
|
18493
18864
|
if (entry.isDirectory()) return true;
|
|
18494
18865
|
if (entry.isSymbolicLink()) {
|
|
18495
18866
|
try {
|
|
18496
|
-
return (await
|
|
18867
|
+
return (await fs4.stat(path15.join(dir, entry.name))).isDirectory();
|
|
18497
18868
|
} catch {
|
|
18498
18869
|
return false;
|
|
18499
18870
|
}
|
|
@@ -18514,7 +18885,7 @@ var DefaultSkillLoader = class {
|
|
|
18514
18885
|
for (const tool of FOREIGN_SKILL_TOOLS) {
|
|
18515
18886
|
if (!foreignIds.includes(tool.id)) continue;
|
|
18516
18887
|
dirs.push({
|
|
18517
|
-
dir:
|
|
18888
|
+
dir: path15.join(root, "." + tool.id, tool.subdir),
|
|
18518
18889
|
source: "foreign",
|
|
18519
18890
|
originTool: tool.id
|
|
18520
18891
|
});
|
|
@@ -18536,12 +18907,12 @@ var DefaultSkillLoader = class {
|
|
|
18536
18907
|
const seen = /* @__PURE__ */ new Set();
|
|
18537
18908
|
for (const { dir, source, originTool } of this.dirs) {
|
|
18538
18909
|
try {
|
|
18539
|
-
const entries = await
|
|
18910
|
+
const entries = await fs4.readdir(dir, { withFileTypes: true });
|
|
18540
18911
|
for (const e of entries) {
|
|
18541
18912
|
if (!await entryIsDirectory(dir, e)) continue;
|
|
18542
|
-
const skillFile =
|
|
18913
|
+
const skillFile = path15.join(dir, e.name, "SKILL.md");
|
|
18543
18914
|
try {
|
|
18544
|
-
const raw = await
|
|
18915
|
+
const raw = await fs4.readFile(skillFile, "utf8");
|
|
18545
18916
|
const fm = parseSkillFrontmatter(raw);
|
|
18546
18917
|
if (!fm.name || !fm.description) continue;
|
|
18547
18918
|
if (!isValidSkillNameFormat(fm.name)) continue;
|
|
@@ -18613,7 +18984,7 @@ var DefaultSkillLoader = class {
|
|
|
18613
18984
|
if (cached !== void 0) return cached;
|
|
18614
18985
|
const m = await this.find(name);
|
|
18615
18986
|
if (!m) throw new Error(`Skill "${name}" not found`);
|
|
18616
|
-
const body = await
|
|
18987
|
+
const body = await fs4.readFile(m.path, "utf8");
|
|
18617
18988
|
this.bodyCache.set(key, body);
|
|
18618
18989
|
return body;
|
|
18619
18990
|
}
|
|
@@ -18623,12 +18994,12 @@ var DefaultSkillLoader = class {
|
|
|
18623
18994
|
if (cached !== void 0) return cached;
|
|
18624
18995
|
const m = await this.find(name);
|
|
18625
18996
|
if (!m) throw new Error(`Skill "${name}" not found`);
|
|
18626
|
-
const savePath =
|
|
18997
|
+
const savePath = path15.join(path15.dirname(m.path), "SKILL.save.md");
|
|
18627
18998
|
let result;
|
|
18628
18999
|
try {
|
|
18629
|
-
result = await
|
|
19000
|
+
result = await fs4.readFile(savePath, "utf8");
|
|
18630
19001
|
} catch {
|
|
18631
|
-
const full = await
|
|
19002
|
+
const full = await fs4.readFile(m.path, "utf8");
|
|
18632
19003
|
const body = stripFrontmatter2(full);
|
|
18633
19004
|
const compact = compactSkillBody(body);
|
|
18634
19005
|
if (compact) {
|
|
@@ -18654,6 +19025,14 @@ function parseDescriptionFromText(desc) {
|
|
|
18654
19025
|
}
|
|
18655
19026
|
return { trigger, scope };
|
|
18656
19027
|
}
|
|
19028
|
+
|
|
19029
|
+
// src/execution/prompt-loader.ts
|
|
19030
|
+
import * as fs6 from "node:fs/promises";
|
|
19031
|
+
import * as path17 from "node:path";
|
|
19032
|
+
|
|
19033
|
+
// src/storage/prompt-store.ts
|
|
19034
|
+
import * as fs5 from "node:fs/promises";
|
|
19035
|
+
import * as path16 from "node:path";
|
|
18657
19036
|
var SCHEMA_VERSION = 2;
|
|
18658
19037
|
function migratePromptEntry(raw) {
|
|
18659
19038
|
if (!raw || typeof raw !== "object") return null;
|
|
@@ -18714,12 +19093,12 @@ var DefaultPromptStore = class {
|
|
|
18714
19093
|
await ensureDir(this.dir);
|
|
18715
19094
|
const entries = [];
|
|
18716
19095
|
try {
|
|
18717
|
-
const files = await
|
|
19096
|
+
const files = await fs5.readdir(this.dir);
|
|
18718
19097
|
for (const file of files) {
|
|
18719
19098
|
if (!file.endsWith(".json")) continue;
|
|
18720
19099
|
try {
|
|
18721
19100
|
const raw = JSON.parse(
|
|
18722
|
-
await
|
|
19101
|
+
await fs5.readFile(path16.join(this.dir, file), "utf8")
|
|
18723
19102
|
);
|
|
18724
19103
|
const migrated = migratePromptEntry(raw.entry);
|
|
18725
19104
|
if (migrated) entries.push(migrated);
|
|
@@ -18733,9 +19112,9 @@ var DefaultPromptStore = class {
|
|
|
18733
19112
|
);
|
|
18734
19113
|
}
|
|
18735
19114
|
async get(id) {
|
|
18736
|
-
const file =
|
|
19115
|
+
const file = path16.join(this.dir, `${id}.json`);
|
|
18737
19116
|
try {
|
|
18738
|
-
const raw = JSON.parse(await
|
|
19117
|
+
const raw = JSON.parse(await fs5.readFile(file, "utf8"));
|
|
18739
19118
|
return migratePromptEntry(raw.entry);
|
|
18740
19119
|
} catch {
|
|
18741
19120
|
return null;
|
|
@@ -18743,14 +19122,14 @@ var DefaultPromptStore = class {
|
|
|
18743
19122
|
}
|
|
18744
19123
|
async save(entry) {
|
|
18745
19124
|
await ensureDir(this.dir);
|
|
18746
|
-
const file =
|
|
19125
|
+
const file = path16.join(this.dir, `${entry.id}.json`);
|
|
18747
19126
|
const raw = { version: SCHEMA_VERSION, entry };
|
|
18748
19127
|
await atomicWrite(file, JSON.stringify(raw, null, 2));
|
|
18749
19128
|
}
|
|
18750
19129
|
async delete(id) {
|
|
18751
|
-
const file =
|
|
19130
|
+
const file = path16.join(this.dir, `${id}.json`);
|
|
18752
19131
|
try {
|
|
18753
|
-
await
|
|
19132
|
+
await fs5.unlink(file);
|
|
18754
19133
|
return true;
|
|
18755
19134
|
} catch {
|
|
18756
19135
|
return false;
|
|
@@ -18837,7 +19216,7 @@ var DefaultPromptLoader = class {
|
|
|
18837
19216
|
constructor(opts) {
|
|
18838
19217
|
this.projectStore = typeof opts.paths.inProjectPrompts === "string" ? new DefaultPromptStore(opts.paths.inProjectPrompts) : void 0;
|
|
18839
19218
|
this.userStore = typeof opts.paths.globalPrompts === "string" ? new DefaultPromptStore(opts.paths.globalPrompts) : void 0;
|
|
18840
|
-
this.builtinDir = opts.bundledDir ?
|
|
19219
|
+
this.builtinDir = opts.bundledDir ? path17.join(opts.bundledDir, "prompts") : void 0;
|
|
18841
19220
|
}
|
|
18842
19221
|
async list() {
|
|
18843
19222
|
if (this.cache) return this.cache;
|
|
@@ -18950,7 +19329,7 @@ var DefaultPromptLoader = class {
|
|
|
18950
19329
|
const files = await walkJson(dir);
|
|
18951
19330
|
for (const file of files) {
|
|
18952
19331
|
try {
|
|
18953
|
-
const parsed = JSON.parse(await
|
|
19332
|
+
const parsed = JSON.parse(await fs6.readFile(file, "utf8"));
|
|
18954
19333
|
const migrated = migratePromptEntry(parsed);
|
|
18955
19334
|
if (migrated) out.push({ ...migrated, source: "builtin" });
|
|
18956
19335
|
} catch {
|
|
@@ -18964,12 +19343,12 @@ async function walkJson(dir) {
|
|
|
18964
19343
|
const out = [];
|
|
18965
19344
|
let entries;
|
|
18966
19345
|
try {
|
|
18967
|
-
entries = await
|
|
19346
|
+
entries = await fs6.readdir(dir, { withFileTypes: true });
|
|
18968
19347
|
} catch {
|
|
18969
19348
|
return out;
|
|
18970
19349
|
}
|
|
18971
19350
|
for (const e of entries) {
|
|
18972
|
-
const full =
|
|
19351
|
+
const full = path17.join(dir, e.name);
|
|
18973
19352
|
if (e.isDirectory()) {
|
|
18974
19353
|
out.push(...await walkJson(full));
|
|
18975
19354
|
} else if (e.name.endsWith(".json") && e.name !== "index.json" && e.name !== "schema.json") {
|
|
@@ -19153,6 +19532,12 @@ function readPolicy(ctx) {
|
|
|
19153
19532
|
return candidate;
|
|
19154
19533
|
}
|
|
19155
19534
|
|
|
19535
|
+
// src/execution/tool-executor.ts
|
|
19536
|
+
import { randomUUID as randomUUID10 } from "node:crypto";
|
|
19537
|
+
import { isDeepStrictEqual } from "node:util";
|
|
19538
|
+
import * as fs7 from "node:fs/promises";
|
|
19539
|
+
import * as path18 from "node:path";
|
|
19540
|
+
|
|
19156
19541
|
// src/types/tool-markers.ts
|
|
19157
19542
|
var MALFORMED_ARG_MARKERS = ["__raw", "__raw_arguments", "_raw"];
|
|
19158
19543
|
|
|
@@ -19372,12 +19757,33 @@ ${errorDetails}`,
|
|
|
19372
19757
|
}
|
|
19373
19758
|
if (effectivePermission === "confirm") {
|
|
19374
19759
|
if (this.opts.confirmAwaiter) {
|
|
19375
|
-
const
|
|
19760
|
+
const awaiter = this.opts.confirmAwaiter;
|
|
19761
|
+
const choice = await new Promise(
|
|
19762
|
+
(resolve12, reject) => {
|
|
19763
|
+
const signal = ctx.signal;
|
|
19764
|
+
const onAbort = () => resolve12("abort");
|
|
19765
|
+
if (signal.aborted) {
|
|
19766
|
+
resolve12("abort");
|
|
19767
|
+
return;
|
|
19768
|
+
}
|
|
19769
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
19770
|
+
awaiter(tool, use.input, use.id, tool.name).then(
|
|
19771
|
+
(c) => {
|
|
19772
|
+
signal.removeEventListener("abort", onAbort);
|
|
19773
|
+
resolve12(c);
|
|
19774
|
+
},
|
|
19775
|
+
(e) => {
|
|
19776
|
+
signal.removeEventListener("abort", onAbort);
|
|
19777
|
+
reject(e);
|
|
19778
|
+
}
|
|
19779
|
+
);
|
|
19780
|
+
}
|
|
19781
|
+
);
|
|
19376
19782
|
if (choice !== "yes" && choice !== "always") {
|
|
19377
19783
|
const result = {
|
|
19378
19784
|
type: "tool_result",
|
|
19379
19785
|
tool_use_id: use.id,
|
|
19380
|
-
content: `Tool "${tool.name}" denied by user.`,
|
|
19786
|
+
content: choice === "abort" ? `Tool "${tool.name}" was not executed \u2014 the run was aborted while awaiting confirmation.` : `Tool "${tool.name}" denied by user.`,
|
|
19381
19787
|
is_error: true
|
|
19382
19788
|
};
|
|
19383
19789
|
budget = this.budgetForString(result.content, budget);
|
|
@@ -19483,6 +19889,9 @@ ${post.additionalContext}`;
|
|
|
19483
19889
|
is_error: true
|
|
19484
19890
|
};
|
|
19485
19891
|
budget = this.budgetForString(result.content, budget);
|
|
19892
|
+
void category;
|
|
19893
|
+
void retryable;
|
|
19894
|
+
void detail;
|
|
19486
19895
|
return { result, tool, durationMs: 0 };
|
|
19487
19896
|
}
|
|
19488
19897
|
};
|
|
@@ -19589,15 +19998,33 @@ ${post.additionalContext}`;
|
|
|
19589
19998
|
const timeoutSignal = AbortSignal.timeout(timeoutMs);
|
|
19590
19999
|
const combined = AbortSignal.any([parentSignal, timeoutSignal]);
|
|
19591
20000
|
let output;
|
|
20001
|
+
const toolPromise = typeof tool.executeStream === "function" ? this.runStreamedTool(tool, input, ctx, combined, toolUseId) : (async () => tool.execute(input, ctx, { signal: combined }))();
|
|
20002
|
+
toolPromise.catch(() => {
|
|
20003
|
+
});
|
|
19592
20004
|
try {
|
|
19593
|
-
output =
|
|
20005
|
+
output = await new Promise((resolve12, reject) => {
|
|
20006
|
+
const onAbort = () => {
|
|
20007
|
+
setTimeout(() => reject(abortReasonToError(combined.reason)), 0);
|
|
20008
|
+
};
|
|
20009
|
+
combined.addEventListener("abort", onAbort, { once: true });
|
|
20010
|
+
toolPromise.then(
|
|
20011
|
+
(v) => {
|
|
20012
|
+
combined.removeEventListener("abort", onAbort);
|
|
20013
|
+
resolve12(v);
|
|
20014
|
+
},
|
|
20015
|
+
(e) => {
|
|
20016
|
+
combined.removeEventListener("abort", onAbort);
|
|
20017
|
+
reject(e);
|
|
20018
|
+
}
|
|
20019
|
+
);
|
|
20020
|
+
});
|
|
19594
20021
|
} catch (err) {
|
|
19595
20022
|
if (combined.aborted) await this.runToolCleanup(tool, input, ctx);
|
|
19596
20023
|
throw err;
|
|
19597
20024
|
}
|
|
19598
20025
|
if (combined.aborted) {
|
|
19599
20026
|
await this.runToolCleanup(tool, input, ctx);
|
|
19600
|
-
throw
|
|
20027
|
+
throw abortReasonToError(combined.reason);
|
|
19601
20028
|
}
|
|
19602
20029
|
return output;
|
|
19603
20030
|
}
|
|
@@ -19758,6 +20185,9 @@ function clampTimeoutMs(timeoutMs, maxTimeoutMs) {
|
|
|
19758
20185
|
const finiteMax = Number.isFinite(maxTimeoutMs) && maxTimeoutMs > 0 ? maxTimeoutMs : fallback;
|
|
19759
20186
|
return Math.max(1, Math.min(finiteTimeout, finiteMax));
|
|
19760
20187
|
}
|
|
20188
|
+
function abortReasonToError(reason) {
|
|
20189
|
+
return reason instanceof Error ? reason : new Error(typeof reason === "string" ? reason : "tool timeout");
|
|
20190
|
+
}
|
|
19761
20191
|
function hasMalformedArguments(input) {
|
|
19762
20192
|
if (!input || typeof input !== "object" || Array.isArray(input)) return false;
|
|
19763
20193
|
const obj = input;
|
|
@@ -19856,12 +20286,12 @@ async function maybePersistLargeToolOutput(toolName, content, budget) {
|
|
|
19856
20286
|
return content;
|
|
19857
20287
|
}
|
|
19858
20288
|
try {
|
|
19859
|
-
const dir =
|
|
19860
|
-
await
|
|
20289
|
+
const dir = path18.join(wstackGlobalRoot(), "tool-output");
|
|
20290
|
+
await fs7.mkdir(dir, { recursive: true });
|
|
19861
20291
|
const safeTool = toolName.replace(/[^a-zA-Z0-9._-]+/g, "_").slice(0, 40) || "tool";
|
|
19862
20292
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
19863
|
-
const filePath =
|
|
19864
|
-
await
|
|
20293
|
+
const filePath = path18.join(dir, `${stamp}-${safeTool}-${randomUUID10()}.log`);
|
|
20294
|
+
await fs7.writeFile(filePath, content, "utf8");
|
|
19865
20295
|
const marker = `[full tool output: ${bytes} bytes at ${filePath}; read/grep that file selectively instead of re-running or requesting more output]`;
|
|
19866
20296
|
const fixedBytes = Buffer.byteLength(marker + TOOL_OUTPUT_ARTIFACT_OMISSION, "utf8");
|
|
19867
20297
|
const previewBytes = Math.min(
|
|
@@ -20015,7 +20445,7 @@ function createContextManagerTool(opts = {}) {
|
|
|
20015
20445
|
notes: "No compactor registered. Use /compact aggressive via slash command instead."
|
|
20016
20446
|
};
|
|
20017
20447
|
}
|
|
20018
|
-
const fullEstimate = input.systemPrompt != null && Array.isArray(input.tools) ? estimateRequestTokens(messages, input.systemPrompt, input.tools) : { total: beforeTokens};
|
|
20448
|
+
const fullEstimate = input.systemPrompt != null && Array.isArray(input.tools) ? estimateRequestTokens(messages, input.systemPrompt, input.tools) : { total: beforeTokens, messages: beforeTokens, systemPrompt: 0, tools: 0 };
|
|
20019
20449
|
const currentTokens = fullEstimate.total;
|
|
20020
20450
|
const runtimeMaxContext = configuredMaxContext ?? ctx.provider?.capabilities?.maxContext ?? 128e3;
|
|
20021
20451
|
const runtimeThreshold = minCompactThreshold > 0 ? minCompactThreshold : Math.floor(runtimeMaxContext * compactThresholdFraction);
|
|
@@ -20169,6 +20599,10 @@ function createContextManagerTool(opts = {}) {
|
|
|
20169
20599
|
};
|
|
20170
20600
|
}
|
|
20171
20601
|
var contextManagerTool = createContextManagerTool();
|
|
20602
|
+
|
|
20603
|
+
// src/infrastructure/logger.ts
|
|
20604
|
+
import * as fsp11 from "node:fs/promises";
|
|
20605
|
+
import * as path19 from "node:path";
|
|
20172
20606
|
var LEVEL_RANK2 = {
|
|
20173
20607
|
error: 0,
|
|
20174
20608
|
warn: 1,
|
|
@@ -20232,9 +20666,9 @@ var DefaultLogger = class _DefaultLogger {
|
|
|
20232
20666
|
this.stderr = opts.stderr !== false;
|
|
20233
20667
|
this.maxFileBytes = opts.maxFileBytes ?? 10 * 1024 * 1024;
|
|
20234
20668
|
if (this.file) {
|
|
20235
|
-
const dir =
|
|
20669
|
+
const dir = path19.dirname(this.file);
|
|
20236
20670
|
this._tail = this._tail.then(async () => {
|
|
20237
|
-
await
|
|
20671
|
+
await fsp11.mkdir(dir, { recursive: true });
|
|
20238
20672
|
}).catch(() => void 0);
|
|
20239
20673
|
}
|
|
20240
20674
|
}
|
|
@@ -20292,14 +20726,14 @@ var DefaultLogger = class _DefaultLogger {
|
|
|
20292
20726
|
this._tail = this._tail.then(async () => {
|
|
20293
20727
|
let st;
|
|
20294
20728
|
try {
|
|
20295
|
-
st = await
|
|
20729
|
+
st = await fsp11.stat(file);
|
|
20296
20730
|
} catch {
|
|
20297
20731
|
return;
|
|
20298
20732
|
}
|
|
20299
20733
|
if (st.size < this.maxFileBytes) return;
|
|
20300
20734
|
try {
|
|
20301
|
-
await
|
|
20302
|
-
await
|
|
20735
|
+
await fsp11.rm(`${file}.1`, { force: true });
|
|
20736
|
+
await fsp11.rename(file, `${file}.1`);
|
|
20303
20737
|
} catch {
|
|
20304
20738
|
}
|
|
20305
20739
|
}).catch(() => void 0);
|
|
@@ -20317,7 +20751,7 @@ var DefaultLogger = class _DefaultLogger {
|
|
|
20317
20751
|
this.enqueueRotate(this.file);
|
|
20318
20752
|
const line = `${JSON.stringify(entry)}
|
|
20319
20753
|
`;
|
|
20320
|
-
this._tail = this._tail.then(() =>
|
|
20754
|
+
this._tail = this._tail.then(() => fsp11.appendFile(this.file, line)).catch(() => void 0);
|
|
20321
20755
|
}
|
|
20322
20756
|
if (!this.stderr) return;
|
|
20323
20757
|
if (this.format === "json") {
|
|
@@ -20551,27 +20985,36 @@ var BY_ID = new Map(CODEX_MODELS.map((m) => [m.id, m]));
|
|
|
20551
20985
|
function codexModelMeta(id) {
|
|
20552
20986
|
return BY_ID.get(id);
|
|
20553
20987
|
}
|
|
20988
|
+
|
|
20989
|
+
// src/models/mode-store.ts
|
|
20990
|
+
import * as fs8 from "node:fs/promises";
|
|
20991
|
+
import * as path21 from "node:path";
|
|
20992
|
+
|
|
20993
|
+
// src/types/mode-prompts.ts
|
|
20994
|
+
import { readFileSync as readFileSync3, statSync as statSync3 } from "node:fs";
|
|
20995
|
+
import * as path20 from "node:path";
|
|
20996
|
+
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
20554
20997
|
function modePrompt(id) {
|
|
20555
20998
|
for (const dir of modePromptDirCandidates()) {
|
|
20556
20999
|
try {
|
|
20557
|
-
return
|
|
21000
|
+
return readFileSync3(path20.join(dir, `${id}.md`), "utf8").trimEnd();
|
|
20558
21001
|
} catch {
|
|
20559
21002
|
}
|
|
20560
21003
|
}
|
|
20561
21004
|
return "";
|
|
20562
21005
|
}
|
|
20563
21006
|
function modePromptDirCandidates() {
|
|
20564
|
-
const here =
|
|
21007
|
+
const here = path20.dirname(fileURLToPath4(import.meta.url));
|
|
20565
21008
|
const candidates = [
|
|
20566
|
-
|
|
20567
|
-
|
|
20568
|
-
|
|
21009
|
+
path20.resolve(here, "../../instructions/modes"),
|
|
21010
|
+
path20.resolve(here, "../instructions/modes"),
|
|
21011
|
+
path20.resolve(here, "instructions/modes")
|
|
20569
21012
|
];
|
|
20570
21013
|
return candidates.sort((a, b) => Number(!isDirectory3(a)) - Number(!isDirectory3(b)));
|
|
20571
21014
|
}
|
|
20572
21015
|
function isDirectory3(candidate) {
|
|
20573
21016
|
try {
|
|
20574
|
-
return
|
|
21017
|
+
return statSync3(candidate).isDirectory();
|
|
20575
21018
|
} catch {
|
|
20576
21019
|
return false;
|
|
20577
21020
|
}
|
|
@@ -20797,8 +21240,8 @@ var DefaultModeStore = class {
|
|
|
20797
21240
|
}
|
|
20798
21241
|
async loadActiveMode() {
|
|
20799
21242
|
try {
|
|
20800
|
-
const configPath =
|
|
20801
|
-
const content = await
|
|
21243
|
+
const configPath = path21.join(this.configDir, "mode.json");
|
|
21244
|
+
const content = await fs8.readFile(configPath, "utf8");
|
|
20802
21245
|
const data = JSON.parse(content);
|
|
20803
21246
|
this.activeModeId = data.activeMode ?? null;
|
|
20804
21247
|
} catch {
|
|
@@ -20807,8 +21250,8 @@ var DefaultModeStore = class {
|
|
|
20807
21250
|
}
|
|
20808
21251
|
async saveActiveMode() {
|
|
20809
21252
|
try {
|
|
20810
|
-
await
|
|
20811
|
-
const configPath =
|
|
21253
|
+
await fs8.mkdir(this.configDir, { recursive: true });
|
|
21254
|
+
const configPath = path21.join(this.configDir, "mode.json");
|
|
20812
21255
|
await atomicWrite(
|
|
20813
21256
|
configPath,
|
|
20814
21257
|
JSON.stringify({ activeMode: this.activeModeId }, null, 2)
|
|
@@ -20820,14 +21263,14 @@ var DefaultModeStore = class {
|
|
|
20820
21263
|
async function loadProjectModes(modesDir) {
|
|
20821
21264
|
const modes = [];
|
|
20822
21265
|
try {
|
|
20823
|
-
const entries = await
|
|
21266
|
+
const entries = await fs8.readdir(modesDir);
|
|
20824
21267
|
for (const entry of entries) {
|
|
20825
21268
|
if (!entry.endsWith(".md") && !entry.endsWith(".txt")) continue;
|
|
20826
|
-
const filePath =
|
|
20827
|
-
const stat13 = await
|
|
21269
|
+
const filePath = path21.join(modesDir, entry);
|
|
21270
|
+
const stat13 = await fs8.stat(filePath);
|
|
20828
21271
|
if (!stat13.isFile()) continue;
|
|
20829
|
-
const content = await
|
|
20830
|
-
const id =
|
|
21272
|
+
const content = await fs8.readFile(filePath, "utf8");
|
|
21273
|
+
const id = path21.basename(entry, path21.extname(entry));
|
|
20831
21274
|
modes.push({
|
|
20832
21275
|
id,
|
|
20833
21276
|
name: id.replace(/[-_]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase()),
|
|
@@ -20843,8 +21286,8 @@ async function loadProjectModes(modesDir) {
|
|
|
20843
21286
|
async function loadUserModes(modesDir) {
|
|
20844
21287
|
const modes = [];
|
|
20845
21288
|
try {
|
|
20846
|
-
const manifestPath =
|
|
20847
|
-
const content = await
|
|
21289
|
+
const manifestPath = path21.join(modesDir, "modes.json");
|
|
21290
|
+
const content = await fs8.readFile(manifestPath, "utf8");
|
|
20848
21291
|
const manifest = JSON.parse(content);
|
|
20849
21292
|
for (const mode of manifest.modes) {
|
|
20850
21293
|
modes.push(mode);
|
|
@@ -20853,6 +21296,10 @@ async function loadUserModes(modesDir) {
|
|
|
20853
21296
|
}
|
|
20854
21297
|
return modes;
|
|
20855
21298
|
}
|
|
21299
|
+
|
|
21300
|
+
// src/models/models-registry.ts
|
|
21301
|
+
import * as fs9 from "node:fs/promises";
|
|
21302
|
+
import * as path22 from "node:path";
|
|
20856
21303
|
var DEFAULT_URL = "https://models.dev/api.json";
|
|
20857
21304
|
var ENV_URL_KEY = "WRONGSTACK_MODELS_DEV_URL";
|
|
20858
21305
|
var DEFAULT_TTL_SECONDS = 24 * 3600;
|
|
@@ -20928,7 +21375,7 @@ var DefaultModelsRegistry = class {
|
|
|
20928
21375
|
this.overlay = opts.overlay;
|
|
20929
21376
|
this.overlayUrl = opts.overlayUrl;
|
|
20930
21377
|
this.overlayFile = opts.overlayFile;
|
|
20931
|
-
this.overlayCacheFile = opts.overlayCacheFile ?? (opts.overlayUrl ?
|
|
21378
|
+
this.overlayCacheFile = opts.overlayCacheFile ?? (opts.overlayUrl ? path22.join(path22.dirname(opts.cacheFile), "models-overlay-cache.json") : void 0);
|
|
20932
21379
|
}
|
|
20933
21380
|
async load(opts = {}) {
|
|
20934
21381
|
if (this.payload && !opts.force) return this.payload;
|
|
@@ -21093,7 +21540,7 @@ var DefaultModelsRegistry = class {
|
|
|
21093
21540
|
async readOverlayFile() {
|
|
21094
21541
|
if (!this.overlayFile) return void 0;
|
|
21095
21542
|
try {
|
|
21096
|
-
const raw = await
|
|
21543
|
+
const raw = await fs9.readFile(this.overlayFile, "utf8");
|
|
21097
21544
|
return JSON.parse(raw);
|
|
21098
21545
|
} catch {
|
|
21099
21546
|
return void 0;
|
|
@@ -21172,7 +21619,7 @@ var DefaultModelsRegistry = class {
|
|
|
21172
21619
|
}
|
|
21173
21620
|
async readCacheAt(file) {
|
|
21174
21621
|
try {
|
|
21175
|
-
const raw = await
|
|
21622
|
+
const raw = await fs9.readFile(file, "utf8");
|
|
21176
21623
|
return JSON.parse(raw);
|
|
21177
21624
|
} catch {
|
|
21178
21625
|
return void 0;
|
|
@@ -21180,7 +21627,7 @@ var DefaultModelsRegistry = class {
|
|
|
21180
21627
|
}
|
|
21181
21628
|
/** Used by `wstack models refresh` to expose where the cache lives. */
|
|
21182
21629
|
cacheLocation() {
|
|
21183
|
-
return
|
|
21630
|
+
return path22.resolve(this.cacheFile);
|
|
21184
21631
|
}
|
|
21185
21632
|
};
|
|
21186
21633
|
function formatAge(seconds) {
|
|
@@ -21215,32 +21662,48 @@ function describeCatalogModel(m) {
|
|
|
21215
21662
|
]
|
|
21216
21663
|
};
|
|
21217
21664
|
}
|
|
21218
|
-
function resolveProviderModelList(savedModels, catalog, providerHint) {
|
|
21665
|
+
function resolveProviderModelList(savedModels, catalog, providerHint, siblingCatalog) {
|
|
21666
|
+
const byId = new Map((catalog?.models ?? []).map((m) => [m.id, m]));
|
|
21667
|
+
const seen = /* @__PURE__ */ new Set();
|
|
21668
|
+
const out = [];
|
|
21219
21669
|
if (savedModels && savedModels.length > 0) {
|
|
21220
|
-
const
|
|
21221
|
-
|
|
21670
|
+
for (const id of savedModels) {
|
|
21671
|
+
seen.add(id);
|
|
21222
21672
|
const codex = codexModelMeta(id);
|
|
21223
21673
|
const hit = byId.get(id);
|
|
21224
21674
|
if (hit) {
|
|
21225
21675
|
const described = describeCatalogModel(hit);
|
|
21226
|
-
|
|
21676
|
+
out.push(codex ? { ...described, description: codex.description } : described);
|
|
21677
|
+
} else if (codex) {
|
|
21678
|
+
out.push({ id, name: codex.name, description: codex.description, capabilities: [] });
|
|
21679
|
+
} else {
|
|
21680
|
+
out.push({ id, name: id, capabilities: [] });
|
|
21227
21681
|
}
|
|
21228
|
-
|
|
21229
|
-
|
|
21682
|
+
}
|
|
21683
|
+
}
|
|
21684
|
+
for (const [id, m] of byId) {
|
|
21685
|
+
if (!seen.has(id)) {
|
|
21686
|
+
out.push(describeCatalogModel(m));
|
|
21687
|
+
seen.add(id);
|
|
21688
|
+
}
|
|
21689
|
+
}
|
|
21690
|
+
if (siblingCatalog && siblingCatalog !== catalog) {
|
|
21691
|
+
for (const m of siblingCatalog.models) {
|
|
21692
|
+
if (!seen.has(m.id)) {
|
|
21693
|
+
out.push(describeCatalogModel(m));
|
|
21694
|
+
seen.add(m.id);
|
|
21230
21695
|
}
|
|
21231
|
-
|
|
21232
|
-
});
|
|
21696
|
+
}
|
|
21233
21697
|
}
|
|
21234
|
-
if (catalog && catalog.models.length > 0) return catalog.models.map(describeCatalogModel);
|
|
21235
21698
|
if (providerHint === "openai-codex") {
|
|
21236
|
-
|
|
21237
|
-
|
|
21238
|
-
|
|
21239
|
-
|
|
21240
|
-
|
|
21241
|
-
}
|
|
21699
|
+
for (const m of CODEX_MODELS) {
|
|
21700
|
+
if (!seen.has(m.id)) {
|
|
21701
|
+
out.push({ id: m.id, name: m.name, description: m.description, capabilities: [] });
|
|
21702
|
+
seen.add(m.id);
|
|
21703
|
+
}
|
|
21704
|
+
}
|
|
21242
21705
|
}
|
|
21243
|
-
return
|
|
21706
|
+
return out;
|
|
21244
21707
|
}
|
|
21245
21708
|
|
|
21246
21709
|
// src/observability/metrics.ts
|
|
@@ -21402,9 +21865,9 @@ var DefaultHealthRegistry = class {
|
|
|
21402
21865
|
}
|
|
21403
21866
|
async runOne(check) {
|
|
21404
21867
|
let timer = null;
|
|
21405
|
-
const timeout = new Promise((
|
|
21868
|
+
const timeout = new Promise((resolve12) => {
|
|
21406
21869
|
timer = setTimeout(
|
|
21407
|
-
() =>
|
|
21870
|
+
() => resolve12({ status: "unhealthy", detail: `timeout after ${this.timeoutMs}ms` }),
|
|
21408
21871
|
this.timeoutMs
|
|
21409
21872
|
);
|
|
21410
21873
|
});
|
|
@@ -21587,7 +22050,7 @@ async function startMetricsServer(opts) {
|
|
|
21587
22050
|
const tls = opts.tls;
|
|
21588
22051
|
const useHttps = !!(tls?.cert && tls?.key);
|
|
21589
22052
|
const host = opts.host ?? "127.0.0.1";
|
|
21590
|
-
const
|
|
22053
|
+
const path29 = opts.path ?? "/metrics";
|
|
21591
22054
|
const healthPath = opts.healthPath ?? "/healthz";
|
|
21592
22055
|
const healthRegistry = opts.healthRegistry;
|
|
21593
22056
|
const listener = (req, res) => {
|
|
@@ -21597,7 +22060,7 @@ async function startMetricsServer(opts) {
|
|
|
21597
22060
|
return;
|
|
21598
22061
|
}
|
|
21599
22062
|
const url = req.url.split("?")[0];
|
|
21600
|
-
if (url ===
|
|
22063
|
+
if (url === path29) {
|
|
21601
22064
|
let body;
|
|
21602
22065
|
try {
|
|
21603
22066
|
body = renderPrometheus(opts.sink.snapshot());
|
|
@@ -21633,24 +22096,24 @@ async function startMetricsServer(opts) {
|
|
|
21633
22096
|
};
|
|
21634
22097
|
let server;
|
|
21635
22098
|
if (useHttps && tls) {
|
|
21636
|
-
const { createServer } = await import(
|
|
21637
|
-
const { readFileSync: readFileSync5 } = await import(
|
|
22099
|
+
const { createServer } = await import("node:https");
|
|
22100
|
+
const { readFileSync: readFileSync5 } = await import("node:fs");
|
|
21638
22101
|
server = createServer(
|
|
21639
22102
|
{ cert: readFileSync5(tls.cert), key: readFileSync5(tls.key) },
|
|
21640
22103
|
listener
|
|
21641
22104
|
);
|
|
21642
22105
|
} else {
|
|
21643
|
-
const { createServer } = await import(
|
|
22106
|
+
const { createServer } = await import("node:http");
|
|
21644
22107
|
server = createServer(listener);
|
|
21645
22108
|
}
|
|
21646
|
-
await new Promise((
|
|
22109
|
+
await new Promise((resolve12, reject) => {
|
|
21647
22110
|
const onError = (err) => {
|
|
21648
22111
|
server.off("listening", onListening);
|
|
21649
22112
|
reject(err);
|
|
21650
22113
|
};
|
|
21651
22114
|
const onListening = () => {
|
|
21652
22115
|
server.off("error", onError);
|
|
21653
|
-
|
|
22116
|
+
resolve12();
|
|
21654
22117
|
};
|
|
21655
22118
|
server.once("error", onError);
|
|
21656
22119
|
server.once("listening", onListening);
|
|
@@ -21661,9 +22124,9 @@ async function startMetricsServer(opts) {
|
|
|
21661
22124
|
const protocol = useHttps ? "https" : "http";
|
|
21662
22125
|
return {
|
|
21663
22126
|
port: boundPort,
|
|
21664
|
-
url: `${protocol}://${host}:${boundPort}${
|
|
21665
|
-
close: () => new Promise((
|
|
21666
|
-
server.close((err) => err ? reject(err) :
|
|
22127
|
+
url: `${protocol}://${host}:${boundPort}${path29}`,
|
|
22128
|
+
close: () => new Promise((resolve12, reject) => {
|
|
22129
|
+
server.close((err) => err ? reject(err) : resolve12());
|
|
21667
22130
|
})
|
|
21668
22131
|
};
|
|
21669
22132
|
}
|
|
@@ -21785,6 +22248,9 @@ function startOtlpMetricsExporter(opts) {
|
|
|
21785
22248
|
}
|
|
21786
22249
|
};
|
|
21787
22250
|
}
|
|
22251
|
+
|
|
22252
|
+
// src/observability/otlp-traces.ts
|
|
22253
|
+
import * as crypto from "node:crypto";
|
|
21788
22254
|
var SPAN_STATUS_CODE_UNSET = 0;
|
|
21789
22255
|
var SPAN_STATUS_CODE_OK = 1;
|
|
21790
22256
|
var SPAN_STATUS_CODE_ERROR = 2;
|
|
@@ -21929,6 +22395,9 @@ function startOtlpTraceExporter(opts) {
|
|
|
21929
22395
|
};
|
|
21930
22396
|
}
|
|
21931
22397
|
|
|
22398
|
+
// src/security/permission-policy.ts
|
|
22399
|
+
import * as fs10 from "node:fs/promises";
|
|
22400
|
+
|
|
21932
22401
|
// src/utils/lru-cache.ts
|
|
21933
22402
|
var LruCache = class {
|
|
21934
22403
|
store = /* @__PURE__ */ new Map();
|
|
@@ -21963,253 +22432,13 @@ var LruCache = class {
|
|
|
21963
22432
|
return this.store.size;
|
|
21964
22433
|
}
|
|
21965
22434
|
};
|
|
21966
|
-
|
|
21967
|
-
|
|
21968
|
-
// make a filesystem — wipes a partition
|
|
21969
|
-
/\bformat\s+[A-Za-z]:/i,
|
|
21970
|
-
// format C: — wipes a Windows volume
|
|
21971
|
-
/\bdiskpart\b/i,
|
|
21972
|
-
// Windows partition editor
|
|
21973
|
-
/\bdd\b[^|]*\bof=(?:\/dev\/|\\\\[.?]\\)/i,
|
|
21974
|
-
// dd writing straight to a raw device
|
|
21975
|
-
/>\s*\/dev\/(?:sd|hd|nvme|disk|mapper|vd)/i,
|
|
21976
|
-
// redirect into a raw block device
|
|
21977
|
-
/:\(\)\s*\{\s*:\|:&\s*\}\s*;/
|
|
21978
|
-
// classic fork bomb
|
|
21979
|
-
];
|
|
21980
|
-
var HIGH_IMPACT_PATTERNS = [
|
|
21981
|
-
/\b(?:curl|wget|fetch|httpie|http|irm|iwr|Invoke-WebRequest|Invoke-RestMethod)\b[\s\S]{0,300}\|\s*(?:sudo\s+)?(?:sh|bash|zsh|fish|pwsh|powershell|iex|Invoke-Expression)\b/i,
|
|
21982
|
-
/\b(?:powershell|pwsh)(?:\.exe)?\b[\s\S]{0,120}-(?:enc|encodedcommand)\b/i,
|
|
21983
|
-
/\b(?:shutdown|reboot)\b/i
|
|
21984
|
-
];
|
|
21985
|
-
var CATASTROPHIC_POSIX_ROOTS = /* @__PURE__ */ new Set([
|
|
21986
|
-
"/etc",
|
|
21987
|
-
"/usr",
|
|
21988
|
-
"/bin",
|
|
21989
|
-
"/sbin",
|
|
21990
|
-
"/lib",
|
|
21991
|
-
"/lib64",
|
|
21992
|
-
"/var",
|
|
21993
|
-
"/boot",
|
|
21994
|
-
"/dev",
|
|
21995
|
-
"/sys",
|
|
21996
|
-
"/proc",
|
|
21997
|
-
"/opt",
|
|
21998
|
-
"/root",
|
|
21999
|
-
"/home",
|
|
22000
|
-
"/srv",
|
|
22001
|
-
"/run",
|
|
22002
|
-
"/system",
|
|
22003
|
-
"/library",
|
|
22004
|
-
"/applications",
|
|
22005
|
-
"/users"
|
|
22006
|
-
]);
|
|
22007
|
-
var CATASTROPHIC_WIN_SUBDIRS = /* @__PURE__ */ new Set([
|
|
22008
|
-
"windows",
|
|
22009
|
-
"system32",
|
|
22010
|
-
"winnt",
|
|
22011
|
-
"program files",
|
|
22012
|
-
"program files (x86)",
|
|
22013
|
-
"programdata",
|
|
22014
|
-
"users"
|
|
22015
|
-
]);
|
|
22016
|
-
var SHELL_OPERATORS = /* @__PURE__ */ new Set(["&&", "||", "|", ";", ">", ">>", "<", "2>", "2>>"]);
|
|
22435
|
+
|
|
22436
|
+
// src/security/yolo-risk.ts
|
|
22017
22437
|
function getInputString(input, key) {
|
|
22018
22438
|
if (!input || typeof input !== "object") return void 0;
|
|
22019
22439
|
const value = input[key];
|
|
22020
22440
|
return typeof value === "string" ? value : void 0;
|
|
22021
22441
|
}
|
|
22022
|
-
function pathLooksInsideProject(rawPath, projectRoot) {
|
|
22023
|
-
if (!projectRoot) return false;
|
|
22024
|
-
if (rawPath === "~" || rawPath.startsWith("~/") || rawPath.startsWith("~\\")) return false;
|
|
22025
|
-
const resolved = path4.resolve(projectRoot, rawPath);
|
|
22026
|
-
const relative6 = path4.relative(projectRoot, resolved);
|
|
22027
|
-
return !!relative6 && !relative6.startsWith("..") && !path4.isAbsolute(relative6);
|
|
22028
|
-
}
|
|
22029
|
-
function tokenizeShell(command) {
|
|
22030
|
-
return command.match(/"[^"]*"|'[^']*'|\S+/g)?.map((token) => token.replace(/^['"]|['"]$/g, "")) ?? [];
|
|
22031
|
-
}
|
|
22032
|
-
function commandSegment(tokens, start) {
|
|
22033
|
-
const out = [];
|
|
22034
|
-
for (let i = start; i < tokens.length; i++) {
|
|
22035
|
-
const token = tokens[i];
|
|
22036
|
-
if (token === void 0 || SHELL_OPERATORS.has(token)) break;
|
|
22037
|
-
out.push(token);
|
|
22038
|
-
}
|
|
22039
|
-
return out;
|
|
22040
|
-
}
|
|
22041
|
-
function hasShortFlag(args, letters) {
|
|
22042
|
-
const seen = /* @__PURE__ */ new Set();
|
|
22043
|
-
for (const arg of args) {
|
|
22044
|
-
if (!arg.startsWith("-") || arg.startsWith("--")) continue;
|
|
22045
|
-
for (const ch of arg.replace(/^-+/, "")) seen.add(ch.toLowerCase());
|
|
22046
|
-
}
|
|
22047
|
-
return letters.split("").every((letter) => seen.has(letter));
|
|
22048
|
-
}
|
|
22049
|
-
function hasRecursiveForceDelete(command, projectRoot) {
|
|
22050
|
-
const tokens = tokenizeShell(command);
|
|
22051
|
-
for (let i = 0; i < tokens.length; i++) {
|
|
22052
|
-
const token = tokens[i]?.toLowerCase();
|
|
22053
|
-
if (!token) continue;
|
|
22054
|
-
if (token === "rm" || token === "rmdir") {
|
|
22055
|
-
const args = commandSegment(tokens, i + 1);
|
|
22056
|
-
const recursiveForce = hasShortFlag(args, "rf") || args.some((arg) => arg === "--recursive") && args.some((arg) => arg === "--force");
|
|
22057
|
-
if (recursiveForce) {
|
|
22058
|
-
const targets = args.filter((arg) => !arg.startsWith("-") && !SHELL_OPERATORS.has(arg));
|
|
22059
|
-
if (targets.length > 0 && targets.every((target) => target.trim().length === 0)) {
|
|
22060
|
-
continue;
|
|
22061
|
-
}
|
|
22062
|
-
if (targets.length === 0) return true;
|
|
22063
|
-
if (targets.some(isCatastrophicDeleteTarget)) return true;
|
|
22064
|
-
if (targets.some((target) => !pathLooksInsideProject(target, projectRoot))) return true;
|
|
22065
|
-
}
|
|
22066
|
-
}
|
|
22067
|
-
if (token === "remove-item" || token === "ri") {
|
|
22068
|
-
const args = commandSegment(tokens, i + 1).map((arg) => arg.toLowerCase());
|
|
22069
|
-
const recurse = args.some((arg) => arg === "-recurse" || arg === "-r");
|
|
22070
|
-
const force = args.some((arg) => arg === "-force" || arg === "-f");
|
|
22071
|
-
if (recurse && force && !args.includes("-whatif")) {
|
|
22072
|
-
const targets = args.filter((arg) => !arg.startsWith("-") && !SHELL_OPERATORS.has(arg));
|
|
22073
|
-
if (targets.length === 0) return true;
|
|
22074
|
-
if (targets.some(isCatastrophicDeleteTarget)) return true;
|
|
22075
|
-
if (targets.some((target) => !pathLooksInsideProject(target, projectRoot))) return true;
|
|
22076
|
-
}
|
|
22077
|
-
}
|
|
22078
|
-
if (token === "rd" || token === "rmdir") {
|
|
22079
|
-
const args = commandSegment(tokens, i + 1).map((arg) => arg.toLowerCase());
|
|
22080
|
-
if (args.includes("/s")) {
|
|
22081
|
-
const targets = args.filter((arg) => !arg.startsWith("-") && !arg.startsWith("/") && !SHELL_OPERATORS.has(arg));
|
|
22082
|
-
if (targets.length === 0) return true;
|
|
22083
|
-
if (targets.some(isCatastrophicDeleteTarget)) return true;
|
|
22084
|
-
if (targets.some((target) => !pathLooksInsideProject(target, projectRoot))) return true;
|
|
22085
|
-
}
|
|
22086
|
-
}
|
|
22087
|
-
}
|
|
22088
|
-
return false;
|
|
22089
|
-
}
|
|
22090
|
-
function hasGitHistoryRewrite(command) {
|
|
22091
|
-
const tokens = tokenizeShell(command).map((token) => token.toLowerCase());
|
|
22092
|
-
for (let i = 0; i < tokens.length; i++) {
|
|
22093
|
-
if (tokens[i] !== "git") continue;
|
|
22094
|
-
const args = commandSegment(tokens, i + 1);
|
|
22095
|
-
if (args.includes("reset") && args.some((arg) => arg === "--hard" || arg.startsWith("--hard="))) {
|
|
22096
|
-
return true;
|
|
22097
|
-
}
|
|
22098
|
-
const cleanIdx = args.indexOf("clean");
|
|
22099
|
-
if (cleanIdx >= 0) {
|
|
22100
|
-
const cleanArgs = args.slice(cleanIdx + 1);
|
|
22101
|
-
if (cleanArgs.some((arg) => arg === "-f" || arg === "--force" || /^-[a-z]*f[a-z]*$/i.test(arg))) {
|
|
22102
|
-
return true;
|
|
22103
|
-
}
|
|
22104
|
-
}
|
|
22105
|
-
const pushIdx = args.indexOf("push");
|
|
22106
|
-
if (pushIdx >= 0) {
|
|
22107
|
-
const pushArgs = args.slice(pushIdx + 1);
|
|
22108
|
-
if (pushArgs.some(
|
|
22109
|
-
(arg) => arg === "-f" || arg === "--force" || arg === "--force-with-lease" || arg.startsWith("--force=") || arg.startsWith("--force-with-lease=")
|
|
22110
|
-
)) {
|
|
22111
|
-
return true;
|
|
22112
|
-
}
|
|
22113
|
-
}
|
|
22114
|
-
}
|
|
22115
|
-
return false;
|
|
22116
|
-
}
|
|
22117
|
-
function hasExternalPublish(command) {
|
|
22118
|
-
const tokens = tokenizeShell(command).map((token) => token.toLowerCase());
|
|
22119
|
-
for (let i = 0; i < tokens.length; i++) {
|
|
22120
|
-
const cmd = tokens[i];
|
|
22121
|
-
if (!cmd) continue;
|
|
22122
|
-
const args = commandSegment(tokens, i + 1);
|
|
22123
|
-
if (["npm", "pnpm", "yarn", "bun"].includes(cmd) && (args.includes("publish") || args.includes("deploy"))) {
|
|
22124
|
-
return true;
|
|
22125
|
-
}
|
|
22126
|
-
if (cmd === "cargo" && (args.includes("publish") || args.includes("yank"))) return true;
|
|
22127
|
-
if ((cmd === "docker" || cmd === "podman") && args.includes("push")) return true;
|
|
22128
|
-
if (cmd === "kubectl") {
|
|
22129
|
-
const deleteIdx = args.indexOf("delete");
|
|
22130
|
-
if (deleteIdx >= 0 && (args[deleteIdx + 1] === "namespace" || args[deleteIdx + 1] === "ns")) {
|
|
22131
|
-
return true;
|
|
22132
|
-
}
|
|
22133
|
-
if (args.includes("drain")) return true;
|
|
22134
|
-
}
|
|
22135
|
-
}
|
|
22136
|
-
return false;
|
|
22137
|
-
}
|
|
22138
|
-
function hasFindExec(command) {
|
|
22139
|
-
const tokens = tokenizeShell(command).map((token) => token.toLowerCase());
|
|
22140
|
-
for (let i = 0; i < tokens.length; i++) {
|
|
22141
|
-
if (tokens[i] !== "find") continue;
|
|
22142
|
-
const args = commandSegment(tokens, i + 1);
|
|
22143
|
-
if (args.some((arg) => arg === "-exec" || arg === "-ok" || arg === "-execdir")) return true;
|
|
22144
|
-
}
|
|
22145
|
-
return false;
|
|
22146
|
-
}
|
|
22147
|
-
function isCatastrophicDeleteTarget(rawTarget) {
|
|
22148
|
-
const t = rawTarget.replace(/^['"]|['"]$/g, "").trim();
|
|
22149
|
-
if (!t) return false;
|
|
22150
|
-
if (t === "*" || t === "." || t === "./" || t === ".\\" || t === "./*" || t === ".\\*") return true;
|
|
22151
|
-
const s = t.replace(/[\\/]\*+$/, "").replace(/[\\/]+$/, "");
|
|
22152
|
-
if (s === "") return true;
|
|
22153
|
-
if (s === "~" || /^\$HOME$/i.test(s) || /^%USERPROFILE%$/i.test(s)) return true;
|
|
22154
|
-
if (/^[A-Za-z]:$/.test(s)) return true;
|
|
22155
|
-
const norm = s.toLowerCase().replace(/\\/g, "/");
|
|
22156
|
-
if (CATASTROPHIC_POSIX_ROOTS.has(norm)) return true;
|
|
22157
|
-
const win = norm.match(/^[a-z]:\/([^/]+)$/);
|
|
22158
|
-
if (win?.[1] && CATASTROPHIC_WIN_SUBDIRS.has(win[1])) return true;
|
|
22159
|
-
return false;
|
|
22160
|
-
}
|
|
22161
|
-
function hasCatastrophicDelete(command) {
|
|
22162
|
-
const tokens = tokenizeShell(command);
|
|
22163
|
-
for (let i = 0; i < tokens.length; i++) {
|
|
22164
|
-
const token = tokens[i]?.toLowerCase();
|
|
22165
|
-
if (!token) continue;
|
|
22166
|
-
if (token === "rm") {
|
|
22167
|
-
const args = tokens.slice(i + 1);
|
|
22168
|
-
const recursiveOrForce = args.some(
|
|
22169
|
-
(arg) => /^-[^-]*[rf]/i.test(arg) || arg === "--recursive" || arg === "--force" || arg === "--no-preserve-root"
|
|
22170
|
-
);
|
|
22171
|
-
if (!recursiveOrForce) continue;
|
|
22172
|
-
const targets = args.filter((arg) => !arg.startsWith("-") && !SHELL_OPERATORS.has(arg));
|
|
22173
|
-
if (targets.length === 0) return true;
|
|
22174
|
-
if (targets.some(isCatastrophicDeleteTarget)) return true;
|
|
22175
|
-
}
|
|
22176
|
-
if (token === "remove-item" || token === "ri") {
|
|
22177
|
-
const args = tokens.slice(i + 1);
|
|
22178
|
-
const recursive = args.some((arg) => {
|
|
22179
|
-
const a = arg.toLowerCase();
|
|
22180
|
-
return a === "-recurse" || a === "-force";
|
|
22181
|
-
});
|
|
22182
|
-
if (!recursive) continue;
|
|
22183
|
-
const targets = args.filter((arg) => !arg.startsWith("-") && !SHELL_OPERATORS.has(arg));
|
|
22184
|
-
if (targets.some(isCatastrophicDeleteTarget)) return true;
|
|
22185
|
-
}
|
|
22186
|
-
if (token === "rmdir" || token === "rd") {
|
|
22187
|
-
const args = tokens.slice(i + 1);
|
|
22188
|
-
const recursive = args.some((arg) => arg.toLowerCase() === "/s");
|
|
22189
|
-
if (!recursive) continue;
|
|
22190
|
-
const targets = args.filter((arg) => !arg.startsWith("-") && !arg.startsWith("/") && !SHELL_OPERATORS.has(arg));
|
|
22191
|
-
if (targets.some(isCatastrophicDeleteTarget)) return true;
|
|
22192
|
-
}
|
|
22193
|
-
if (token === "del" || token === "erase") {
|
|
22194
|
-
const args = tokens.slice(i + 1);
|
|
22195
|
-
const targets = args.filter((arg) => !arg.startsWith("-") && !arg.startsWith("/") && !SHELL_OPERATORS.has(arg));
|
|
22196
|
-
if (targets.some(isCatastrophicDeleteTarget)) return true;
|
|
22197
|
-
}
|
|
22198
|
-
}
|
|
22199
|
-
return false;
|
|
22200
|
-
}
|
|
22201
|
-
function isClearlyDestructiveBashCommand(command, projectRoot) {
|
|
22202
|
-
const trimmed = command.trim();
|
|
22203
|
-
if (!trimmed) return false;
|
|
22204
|
-
if (hasRecursiveForceDelete(trimmed, projectRoot)) return true;
|
|
22205
|
-
if (hasGitHistoryRewrite(trimmed)) return true;
|
|
22206
|
-
if (hasExternalPublish(trimmed)) return true;
|
|
22207
|
-
if (hasFindExec(trimmed)) return true;
|
|
22208
|
-
if (hasCatastrophicDelete(trimmed)) return true;
|
|
22209
|
-
if (CATASTROPHIC_PATTERNS.some((pattern) => pattern.test(trimmed))) return true;
|
|
22210
|
-
if (HIGH_IMPACT_PATTERNS.some((pattern) => pattern.test(trimmed))) return true;
|
|
22211
|
-
return false;
|
|
22212
|
-
}
|
|
22213
22442
|
|
|
22214
22443
|
// src/security/permission-policy.ts
|
|
22215
22444
|
function matchesTrust(patterns, subject) {
|
|
@@ -22288,7 +22517,7 @@ var DefaultPermissionPolicy = class {
|
|
|
22288
22517
|
trustFile;
|
|
22289
22518
|
yolo;
|
|
22290
22519
|
yoloDestructive;
|
|
22291
|
-
/**
|
|
22520
|
+
/** Deprecated compatibility flag; no longer gates YOLO calls. */
|
|
22292
22521
|
confirmDestructive;
|
|
22293
22522
|
/**
|
|
22294
22523
|
* Session-scoped "soft deny" map. When the user presses 'n' (block once),
|
|
@@ -22323,7 +22552,7 @@ var DefaultPermissionPolicy = class {
|
|
|
22323
22552
|
/**
|
|
22324
22553
|
* Evaluate-result cache. Keyed by `tool.name::subject` so repeated calls
|
|
22325
22554
|
* with the same tool+input skip namespace matching, subject computation,
|
|
22326
|
-
* pattern matching (matchAny)
|
|
22555
|
+
* and pattern matching (matchAny).
|
|
22327
22556
|
*
|
|
22328
22557
|
* Cleared on any state change (reload, trust, deny, yolo toggle) because
|
|
22329
22558
|
* the result depends on the full policy state. The write-tool smart-bypass
|
|
@@ -22341,7 +22570,7 @@ var DefaultPermissionPolicy = class {
|
|
|
22341
22570
|
this.trustFile = opts.trustFile;
|
|
22342
22571
|
this.yolo = opts.yolo ?? false;
|
|
22343
22572
|
this.yoloDestructive = opts.yoloDestructive ?? opts.forceAllYolo ?? false;
|
|
22344
|
-
this.confirmDestructive =
|
|
22573
|
+
this.confirmDestructive = opts.confirmDestructive ?? false;
|
|
22345
22574
|
this.promptDelegate = opts.promptDelegate;
|
|
22346
22575
|
}
|
|
22347
22576
|
/**
|
|
@@ -22371,18 +22600,18 @@ var DefaultPermissionPolicy = class {
|
|
|
22371
22600
|
getYoloDestructive() {
|
|
22372
22601
|
return this.yoloDestructive;
|
|
22373
22602
|
}
|
|
22374
|
-
/** Toggle destructive confirmation
|
|
22375
|
-
setConfirmDestructive(
|
|
22376
|
-
if (
|
|
22377
|
-
this.confirmDestructive =
|
|
22603
|
+
/** Toggle deprecated destructive confirmation compatibility flag. */
|
|
22604
|
+
setConfirmDestructive(enabled) {
|
|
22605
|
+
if (this.confirmDestructive !== enabled) this._evalCache.clear();
|
|
22606
|
+
this.confirmDestructive = enabled;
|
|
22378
22607
|
}
|
|
22379
|
-
/** Check
|
|
22608
|
+
/** Check deprecated destructive confirmation compatibility flag. */
|
|
22380
22609
|
getConfirmDestructive() {
|
|
22381
22610
|
return this.confirmDestructive;
|
|
22382
22611
|
}
|
|
22383
22612
|
async reload() {
|
|
22384
22613
|
try {
|
|
22385
|
-
const raw = await
|
|
22614
|
+
const raw = await fs10.readFile(this.trustFile, "utf8");
|
|
22386
22615
|
const parsed = safeParse(raw);
|
|
22387
22616
|
if (parsed.ok && parsed.value) this.policy = parsed.value;
|
|
22388
22617
|
} catch {
|
|
@@ -22431,29 +22660,6 @@ var DefaultPermissionPolicy = class {
|
|
|
22431
22660
|
this._evalCache.set(cacheKey, decision);
|
|
22432
22661
|
return decision;
|
|
22433
22662
|
}
|
|
22434
|
-
if (this.yolo) {
|
|
22435
|
-
const destructive = this.isDestructiveYoloCall(tool, input, ctx);
|
|
22436
|
-
if (destructive) {
|
|
22437
|
-
if (this.promptDelegate) {
|
|
22438
|
-
const decision = await this.promptDelegate(tool, input, subject ?? tool.name);
|
|
22439
|
-
if (decision === "deny") {
|
|
22440
|
-
await this.deny({ tool: tool.name, pattern: subject ?? tool.name });
|
|
22441
|
-
return { permission: "deny", source: "user", reason: "user denied destructive yolo" };
|
|
22442
|
-
}
|
|
22443
|
-
return {
|
|
22444
|
-
permission: decision === "yes" || decision === "always" ? "auto" : "deny",
|
|
22445
|
-
source: "user",
|
|
22446
|
-
reason: "destructive yolo approved for this call"
|
|
22447
|
-
};
|
|
22448
|
-
}
|
|
22449
|
-
return {
|
|
22450
|
-
permission: "confirm",
|
|
22451
|
-
source: "yolo_destructive",
|
|
22452
|
-
riskTier: "destructive",
|
|
22453
|
-
reason: "destructive tool needs explicit approval in YOLO mode"
|
|
22454
|
-
};
|
|
22455
|
-
}
|
|
22456
|
-
}
|
|
22457
22663
|
if (entry?.allow && subject && matchesTrust(entry.allow, subject)) {
|
|
22458
22664
|
const decision = { permission: "auto", source: "trust", reason: "matched allow pattern" };
|
|
22459
22665
|
this._evalCache.set(cacheKey, decision);
|
|
@@ -22535,47 +22741,6 @@ var DefaultPermissionPolicy = class {
|
|
|
22535
22741
|
}
|
|
22536
22742
|
return { permission: "confirm", source: "default" };
|
|
22537
22743
|
}
|
|
22538
|
-
// Capability-based destructive check (preferred over name-based)
|
|
22539
|
-
isDestructiveByCapability(tool) {
|
|
22540
|
-
const caps = tool.capabilities ?? [];
|
|
22541
|
-
if (caps.includes(ToolCapabilities.SHELL_ARBITRARY)) return true;
|
|
22542
|
-
if (caps.includes(ToolCapabilities.SHELL_RESTRICTED)) return true;
|
|
22543
|
-
if (caps.includes(ToolCapabilities.SHELL_EXEC)) return true;
|
|
22544
|
-
if (caps.includes(ToolCapabilities.FS_WRITE)) return true;
|
|
22545
|
-
if (caps.includes(ToolCapabilities.FS_WRITE_OUTSIDE_PROJECT)) return true;
|
|
22546
|
-
return false;
|
|
22547
|
-
}
|
|
22548
|
-
isDestructiveYoloCall(tool, input, ctx) {
|
|
22549
|
-
if (tool.name === "mcp_control") {
|
|
22550
|
-
const action = getInputString(input, "action");
|
|
22551
|
-
if (action === "list" || action === "search" || action === "activate" || action === "deactivate") {
|
|
22552
|
-
return false;
|
|
22553
|
-
}
|
|
22554
|
-
}
|
|
22555
|
-
if (this.isDestructiveByCapability(tool)) {
|
|
22556
|
-
const caps = tool.capabilities ?? [];
|
|
22557
|
-
if (caps.includes(ToolCapabilities.SHELL_ARBITRARY) || caps.includes(ToolCapabilities.SHELL_RESTRICTED) || caps.includes(ToolCapabilities.SHELL_EXEC)) {
|
|
22558
|
-
const command = shellCommandLineFromInput(input);
|
|
22559
|
-
return command ? isClearlyDestructiveBashCommand(command, ctx.projectRoot) : tool.riskTier === "destructive";
|
|
22560
|
-
}
|
|
22561
|
-
if (caps.includes(ToolCapabilities.FS_WRITE_OUTSIDE_PROJECT)) return true;
|
|
22562
|
-
if (caps.includes(ToolCapabilities.FS_WRITE)) {
|
|
22563
|
-
const targetPath = getInputString(input, "path") ?? getInputString(input, "file");
|
|
22564
|
-
if (!targetPath || !ctx.projectRoot) return false;
|
|
22565
|
-
return !pathLooksInsideProject(targetPath, ctx.projectRoot);
|
|
22566
|
-
}
|
|
22567
|
-
}
|
|
22568
|
-
if (tool.name === "bash" || tool.name === "shell" || tool.name === "exec") {
|
|
22569
|
-
const command = shellCommandLineFromInput(input);
|
|
22570
|
-
return command ? isClearlyDestructiveBashCommand(command, ctx.projectRoot) : tool.riskTier === "destructive";
|
|
22571
|
-
}
|
|
22572
|
-
if (tool.name === "write" || tool.name === "edit" || tool.name === "replace" || tool.name === "patch") {
|
|
22573
|
-
const targetPath = getInputString(input, "path") ?? getInputString(input, "file");
|
|
22574
|
-
if (!targetPath || !ctx.projectRoot) return false;
|
|
22575
|
-
return !pathLooksInsideProject(targetPath, ctx.projectRoot);
|
|
22576
|
-
}
|
|
22577
|
-
return tool.riskTier === "destructive";
|
|
22578
|
-
}
|
|
22579
22744
|
isSensitiveReadCall(tool, input) {
|
|
22580
22745
|
const isReadTool = hasCapability(tool, ToolCapabilities.FS_READ) || tool.name === "read" || tool.name === "grep" || tool.name === "glob" || tool.name === "tree";
|
|
22581
22746
|
if (isReadTool && inputPathLooksSensitive(input)) return true;
|
|
@@ -22873,12 +23038,61 @@ var DefaultSecretScrubber = class {
|
|
|
22873
23038
|
}
|
|
22874
23039
|
};
|
|
22875
23040
|
|
|
23041
|
+
// src/security/secret-vault.ts
|
|
23042
|
+
import { createCipheriv, createDecipheriv, randomBytes as randomBytes4, scryptSync } from "node:crypto";
|
|
23043
|
+
import * as fs11 from "node:fs";
|
|
23044
|
+
import * as fsp12 from "node:fs/promises";
|
|
23045
|
+
import * as path23 from "node:path";
|
|
23046
|
+
|
|
22876
23047
|
// src/types/secret-vault.ts
|
|
22877
23048
|
var ENCRYPTED_PREFIX_PATTERN = /^enc:v(\d+):/;
|
|
22878
23049
|
function encryptedPrefixForVersion(version) {
|
|
22879
23050
|
return `enc:v${version}:`;
|
|
22880
23051
|
}
|
|
22881
23052
|
|
|
23053
|
+
// src/security/config-secrets.ts
|
|
23054
|
+
function decryptConfigSecrets(cfg, vault, opts) {
|
|
23055
|
+
const warn = opts?.warn ?? ((msg) => console.warn(msg));
|
|
23056
|
+
return walk2(cfg, vault, (v, key) => {
|
|
23057
|
+
try {
|
|
23058
|
+
return vault.decrypt(v);
|
|
23059
|
+
} catch (err) {
|
|
23060
|
+
warn(
|
|
23061
|
+
`[secret-vault] Failed to decrypt "${key}": ${err instanceof Error ? err.message : err}`
|
|
23062
|
+
);
|
|
23063
|
+
return "";
|
|
23064
|
+
}
|
|
23065
|
+
});
|
|
23066
|
+
}
|
|
23067
|
+
function encryptConfigSecrets(cfg, vault, _opts) {
|
|
23068
|
+
return walk2(cfg, vault, (v) => vault.encrypt(v));
|
|
23069
|
+
}
|
|
23070
|
+
function walk2(node, vault, transform) {
|
|
23071
|
+
if (node === null || node === void 0) return node;
|
|
23072
|
+
if (typeof node !== "object") return node;
|
|
23073
|
+
if (Array.isArray(node)) {
|
|
23074
|
+
return node.map((item) => walk2(item, vault, transform));
|
|
23075
|
+
}
|
|
23076
|
+
const out = /* @__PURE__ */ Object.create(null);
|
|
23077
|
+
for (const [k, v] of Object.entries(node)) {
|
|
23078
|
+
if (typeof v === "string" && isSecretField(k)) {
|
|
23079
|
+
out[k] = transform(v, k);
|
|
23080
|
+
} else if (typeof v === "object" && v !== null) {
|
|
23081
|
+
out[k] = walk2(v, vault, transform);
|
|
23082
|
+
} else {
|
|
23083
|
+
out[k] = v;
|
|
23084
|
+
}
|
|
23085
|
+
}
|
|
23086
|
+
return out;
|
|
23087
|
+
}
|
|
23088
|
+
var SECRET_KEY_PATTERN = /(?:apikey|api_key|authtoken|auth_token|bearer|secret|password|passwd|pwd|refreshtoken|refresh_token|sessionkey|session_key|access[_-]?token|private[_-]?key)/i;
|
|
23089
|
+
var NON_SECRET_OVERRIDES = /* @__PURE__ */ new Set(["publickey", "public_key"]);
|
|
23090
|
+
function isSecretField(name) {
|
|
23091
|
+
const lc = name.toLowerCase();
|
|
23092
|
+
if (NON_SECRET_OVERRIDES.has(lc)) return false;
|
|
23093
|
+
return SECRET_KEY_PATTERN.test(lc);
|
|
23094
|
+
}
|
|
23095
|
+
|
|
22882
23096
|
// src/security/secret-vault.ts
|
|
22883
23097
|
var KEY_BYTES = 32;
|
|
22884
23098
|
var IV_BYTES = 12;
|
|
@@ -22910,8 +23124,8 @@ function deriveKEK(passphrase, salt) {
|
|
|
22910
23124
|
});
|
|
22911
23125
|
}
|
|
22912
23126
|
function wrapDataKey(dataKey, keyVersion, passphrase) {
|
|
22913
|
-
const salt =
|
|
22914
|
-
const iv =
|
|
23127
|
+
const salt = randomBytes4(KEK_SALT_BYTES);
|
|
23128
|
+
const iv = randomBytes4(IV_BYTES);
|
|
22915
23129
|
const kek = deriveKEK(passphrase, salt);
|
|
22916
23130
|
const cipher = createCipheriv(ALGO, kek, iv);
|
|
22917
23131
|
const ct = Buffer.concat([cipher.update(dataKey), cipher.final()]);
|
|
@@ -23001,7 +23215,7 @@ var DefaultSecretVault = class {
|
|
|
23001
23215
|
encrypt(plaintext) {
|
|
23002
23216
|
if (this.isEncrypted(plaintext)) return plaintext;
|
|
23003
23217
|
const key = this.loadOrCreateKey();
|
|
23004
|
-
const iv =
|
|
23218
|
+
const iv = randomBytes4(IV_BYTES);
|
|
23005
23219
|
const cipher = createCipheriv(ALGO, key, iv);
|
|
23006
23220
|
const ct = Buffer.concat([cipher.update(plaintext, "utf8"), cipher.final()]);
|
|
23007
23221
|
const tag = cipher.getAuthTag();
|
|
@@ -23054,9 +23268,9 @@ var DefaultSecretVault = class {
|
|
|
23054
23268
|
*/
|
|
23055
23269
|
rotateKey() {
|
|
23056
23270
|
const oldVersion = this._keyVersion;
|
|
23057
|
-
const newKey =
|
|
23271
|
+
const newKey = randomBytes4(KEY_BYTES);
|
|
23058
23272
|
const newVersion = oldVersion + 1;
|
|
23059
|
-
fs11.mkdirSync(
|
|
23273
|
+
fs11.mkdirSync(path23.dirname(this.keyFile), { recursive: true });
|
|
23060
23274
|
const passphrase = getVaultPassphrase();
|
|
23061
23275
|
if (passphrase) {
|
|
23062
23276
|
fs11.writeFileSync(this.keyFile, wrapDataKey(newKey, newVersion, passphrase), { mode: 384 });
|
|
@@ -23140,8 +23354,8 @@ var DefaultSecretVault = class {
|
|
|
23140
23354
|
} catch (err) {
|
|
23141
23355
|
if (err.code !== "ENOENT") throw err;
|
|
23142
23356
|
}
|
|
23143
|
-
fs11.mkdirSync(
|
|
23144
|
-
const key =
|
|
23357
|
+
fs11.mkdirSync(path23.dirname(this.keyFile), { recursive: true });
|
|
23358
|
+
const key = randomBytes4(KEY_BYTES);
|
|
23145
23359
|
const passphrase = getVaultPassphrase();
|
|
23146
23360
|
const initialBytes = passphrase ? wrapDataKey(key, 1, passphrase) : key;
|
|
23147
23361
|
try {
|
|
@@ -23189,64 +23403,23 @@ var DefaultSecretVault = class {
|
|
|
23189
23403
|
return key;
|
|
23190
23404
|
}
|
|
23191
23405
|
};
|
|
23192
|
-
function decryptConfigSecrets(cfg, vault, opts) {
|
|
23193
|
-
const warn = opts?.warn ?? ((msg) => console.warn(msg));
|
|
23194
|
-
return walk2(cfg, vault, (v, key) => {
|
|
23195
|
-
try {
|
|
23196
|
-
return vault.decrypt(v);
|
|
23197
|
-
} catch (err) {
|
|
23198
|
-
warn(
|
|
23199
|
-
`[secret-vault] Failed to decrypt "${key}": ${err instanceof Error ? err.message : err}`
|
|
23200
|
-
);
|
|
23201
|
-
return "";
|
|
23202
|
-
}
|
|
23203
|
-
});
|
|
23204
|
-
}
|
|
23205
|
-
function encryptConfigSecrets(cfg, vault, _opts) {
|
|
23206
|
-
return walk2(cfg, vault, (v) => vault.encrypt(v));
|
|
23207
|
-
}
|
|
23208
|
-
function walk2(node, vault, transform) {
|
|
23209
|
-
if (node === null || node === void 0) return node;
|
|
23210
|
-
if (typeof node !== "object") return node;
|
|
23211
|
-
if (Array.isArray(node)) {
|
|
23212
|
-
return node.map((item) => walk2(item, vault, transform));
|
|
23213
|
-
}
|
|
23214
|
-
const out = /* @__PURE__ */ Object.create(null);
|
|
23215
|
-
for (const [k, v] of Object.entries(node)) {
|
|
23216
|
-
if (typeof v === "string" && isSecretField(k)) {
|
|
23217
|
-
out[k] = transform(v, k);
|
|
23218
|
-
} else if (typeof v === "object" && v !== null) {
|
|
23219
|
-
out[k] = walk2(v, vault, transform);
|
|
23220
|
-
} else {
|
|
23221
|
-
out[k] = v;
|
|
23222
|
-
}
|
|
23223
|
-
}
|
|
23224
|
-
return out;
|
|
23225
|
-
}
|
|
23226
|
-
var SECRET_KEY_PATTERN = /(?:apikey|api_key|authtoken|auth_token|bearer|secret|password|passwd|pwd|refreshtoken|refresh_token|sessionkey|session_key|access[_-]?token|private[_-]?key)/i;
|
|
23227
|
-
var NON_SECRET_OVERRIDES = /* @__PURE__ */ new Set(["publickey", "public_key"]);
|
|
23228
|
-
function isSecretField(name) {
|
|
23229
|
-
const lc = name.toLowerCase();
|
|
23230
|
-
if (NON_SECRET_OVERRIDES.has(lc)) return false;
|
|
23231
|
-
return SECRET_KEY_PATTERN.test(lc);
|
|
23232
|
-
}
|
|
23233
23406
|
async function rewriteConfigEncrypted(configPath, vault, patch) {
|
|
23234
23407
|
let current = {};
|
|
23235
23408
|
try {
|
|
23236
|
-
const raw = await
|
|
23409
|
+
const raw = await fsp12.readFile(configPath, "utf8");
|
|
23237
23410
|
current = JSON.parse(raw);
|
|
23238
23411
|
} catch {
|
|
23239
23412
|
}
|
|
23240
23413
|
const merged = deepMerge(current, patch ?? {});
|
|
23241
23414
|
const encrypted = encryptConfigSecrets(merged, vault);
|
|
23242
|
-
await
|
|
23415
|
+
await fsp12.mkdir(path23.dirname(configPath), { recursive: true });
|
|
23243
23416
|
await atomicWrite(configPath, JSON.stringify(encrypted, null, 2), { mode: 384 });
|
|
23244
23417
|
await restrictFilePermissions(configPath);
|
|
23245
23418
|
}
|
|
23246
23419
|
async function migratePlaintextSecrets(configPath, vault, logger) {
|
|
23247
23420
|
let raw;
|
|
23248
23421
|
try {
|
|
23249
|
-
raw = await
|
|
23422
|
+
raw = await fsp12.readFile(configPath, "utf8");
|
|
23250
23423
|
} catch {
|
|
23251
23424
|
return { migrated: 0, file: configPath };
|
|
23252
23425
|
}
|
|
@@ -23270,8 +23443,8 @@ async function restrictFilePermissions(filePath, opts) {
|
|
|
23270
23443
|
const warn = opts?.warn ?? ((msg) => console.warn(msg));
|
|
23271
23444
|
if (process.platform === "win32") {
|
|
23272
23445
|
try {
|
|
23273
|
-
const { execFile: execFile2 } = await import(
|
|
23274
|
-
const { promisify: promisify2 } = await import(
|
|
23446
|
+
const { execFile: execFile2 } = await import("node:child_process");
|
|
23447
|
+
const { promisify: promisify2 } = await import("node:util");
|
|
23275
23448
|
const execFileAsync = promisify2(execFile2);
|
|
23276
23449
|
const user = windowsAccountName();
|
|
23277
23450
|
if (!user) {
|
|
@@ -23288,7 +23461,7 @@ async function restrictFilePermissions(filePath, opts) {
|
|
|
23288
23461
|
}
|
|
23289
23462
|
} else {
|
|
23290
23463
|
try {
|
|
23291
|
-
await
|
|
23464
|
+
await fsp12.chmod(filePath, 384);
|
|
23292
23465
|
} catch {
|
|
23293
23466
|
}
|
|
23294
23467
|
}
|
|
@@ -23319,6 +23492,11 @@ function walkCount(node, vault, counter) {
|
|
|
23319
23492
|
}
|
|
23320
23493
|
return out;
|
|
23321
23494
|
}
|
|
23495
|
+
|
|
23496
|
+
// src/storage/attachment-store.ts
|
|
23497
|
+
import { randomBytes as randomBytes5 } from "node:crypto";
|
|
23498
|
+
import * as fsp13 from "node:fs/promises";
|
|
23499
|
+
import * as path24 from "node:path";
|
|
23322
23500
|
var DEFAULT_SPOOL_THRESHOLD = 256 * 1024;
|
|
23323
23501
|
var PLACEHOLDER_RE = /\[(pasted|image|file) #(\d+)[^\]]*\]|\[file:([^\]]+)\]/g;
|
|
23324
23502
|
var DefaultAttachmentStore = class {
|
|
@@ -23333,13 +23511,13 @@ var DefaultAttachmentStore = class {
|
|
|
23333
23511
|
}
|
|
23334
23512
|
async add(input) {
|
|
23335
23513
|
const seq = ++this.nextSeq[input.kind];
|
|
23336
|
-
const id = `${kindPrefix(input.kind)}-${seq}-${
|
|
23514
|
+
const id = `${kindPrefix(input.kind)}-${seq}-${randomBytes5(3).toString("hex")}`;
|
|
23337
23515
|
const bytes = Buffer.byteLength(input.data, input.kind === "image" ? "base64" : "utf8");
|
|
23338
23516
|
let spooledPath;
|
|
23339
23517
|
let data = input.data;
|
|
23340
23518
|
if (this.spoolDir && bytes >= this.spoolThreshold) {
|
|
23341
|
-
await
|
|
23342
|
-
spooledPath =
|
|
23519
|
+
await fsp13.mkdir(this.spoolDir, { recursive: true });
|
|
23520
|
+
spooledPath = path24.join(this.spoolDir, `${id}.bin`);
|
|
23343
23521
|
await atomicWrite(spooledPath, input.data, {
|
|
23344
23522
|
encoding: input.kind === "image" ? "base64" : "utf8"
|
|
23345
23523
|
});
|
|
@@ -23401,7 +23579,7 @@ var DefaultAttachmentStore = class {
|
|
|
23401
23579
|
for (const att of this.items.values()) {
|
|
23402
23580
|
if (att.path) toDelete.push(att.path);
|
|
23403
23581
|
}
|
|
23404
|
-
await Promise.all(toDelete.map((p) =>
|
|
23582
|
+
await Promise.all(toDelete.map((p) => fsp13.unlink(p).catch(() => void 0)));
|
|
23405
23583
|
}
|
|
23406
23584
|
this.items.clear();
|
|
23407
23585
|
this.refs.length = 0;
|
|
@@ -23409,7 +23587,7 @@ var DefaultAttachmentStore = class {
|
|
|
23409
23587
|
}
|
|
23410
23588
|
async toBlock(att) {
|
|
23411
23589
|
if (att.kind === "image") {
|
|
23412
|
-
const data = att.data ?? (att.path ? await
|
|
23590
|
+
const data = att.data ?? (att.path ? await fsp13.readFile(att.path, { encoding: "base64" }) : "");
|
|
23413
23591
|
return {
|
|
23414
23592
|
type: "image",
|
|
23415
23593
|
source: {
|
|
@@ -23419,7 +23597,7 @@ var DefaultAttachmentStore = class {
|
|
|
23419
23597
|
}
|
|
23420
23598
|
};
|
|
23421
23599
|
}
|
|
23422
|
-
const raw = att.data ?? (att.path ? await
|
|
23600
|
+
const raw = att.data ?? (att.path ? await fsp13.readFile(att.path, "utf8") : "");
|
|
23423
23601
|
const label = att.meta.filename ? `<file path="${att.meta.filename}">` : "<pasted>";
|
|
23424
23602
|
const close = att.meta.filename ? "</file>" : "</pasted>";
|
|
23425
23603
|
return { type: "text", text: `${label}
|
|
@@ -23457,6 +23635,10 @@ function mergeAdjacentText(blocks) {
|
|
|
23457
23635
|
return out;
|
|
23458
23636
|
}
|
|
23459
23637
|
|
|
23638
|
+
// src/storage/config-loader.ts
|
|
23639
|
+
import * as fs12 from "node:fs/promises";
|
|
23640
|
+
import * as path25 from "node:path";
|
|
23641
|
+
|
|
23460
23642
|
// src/types/config.ts
|
|
23461
23643
|
var DEFAULT_TUI_THINKING_WORD = "thinking";
|
|
23462
23644
|
|
|
@@ -23555,12 +23737,38 @@ var BEHAVIOR_DEFAULTS = {
|
|
|
23555
23737
|
tokenSavingMode: "off",
|
|
23556
23738
|
allowOutsideProjectRoot: true
|
|
23557
23739
|
},
|
|
23740
|
+
superMemory: {
|
|
23741
|
+
enabled: true,
|
|
23742
|
+
storage: {
|
|
23743
|
+
projectLocal: true,
|
|
23744
|
+
directory: ".wrongstack/memories"
|
|
23745
|
+
},
|
|
23746
|
+
inject: {
|
|
23747
|
+
turnContext: true,
|
|
23748
|
+
toolResults: true,
|
|
23749
|
+
maxHintsPerTool: 4,
|
|
23750
|
+
maxCharsPerTool: 1200,
|
|
23751
|
+
maxTurnMemories: 8,
|
|
23752
|
+
maxCharsPerTurn: 2400,
|
|
23753
|
+
minScore: 0.65,
|
|
23754
|
+
repeatCooldownMs: 30 * 6e4
|
|
23755
|
+
},
|
|
23756
|
+
hygiene: {
|
|
23757
|
+
autoAfterSession: true,
|
|
23758
|
+
autoOnFileChange: true,
|
|
23759
|
+
retentionDays: 90,
|
|
23760
|
+
archiveLowConfidenceAfterDays: 30
|
|
23761
|
+
},
|
|
23762
|
+
embeddings: {
|
|
23763
|
+
enabled: false
|
|
23764
|
+
}
|
|
23765
|
+
},
|
|
23558
23766
|
skills: { readClaudeSkills: true },
|
|
23559
23767
|
mcpServers: {},
|
|
23560
23768
|
fallbackAuto: true,
|
|
23561
23769
|
maxConcurrent: 4,
|
|
23562
|
-
// YOLO on by default: auto-approve
|
|
23563
|
-
// prompt.
|
|
23770
|
+
// YOLO on by default: auto-approve non-denied tool calls without a per-call
|
|
23771
|
+
// prompt. Users
|
|
23564
23772
|
// who want the per-call prompts set `yolo: false`. Existing installs whose
|
|
23565
23773
|
// config lacks this key pick it up via fillMissingDefaults; an explicit
|
|
23566
23774
|
// `false` is preserved by the deep-merge (opt-out respected).
|
|
@@ -23579,8 +23787,8 @@ var BEHAVIOR_DEFAULTS = {
|
|
|
23579
23787
|
autonomy: {
|
|
23580
23788
|
// 'auto' by default: the agent self-drives (picks the top next-step after
|
|
23581
23789
|
// each turn). This is a startup default, not a runtime flip — the
|
|
23582
|
-
// autoProceedMaxIterations cap + autoProceedDelayMs cooldown +
|
|
23583
|
-
//
|
|
23790
|
+
// autoProceedMaxIterations cap + autoProceedDelayMs cooldown + Ctrl+C /
|
|
23791
|
+
// [GOAL_COMPLETE] stops remain in force. Explicit 'off'
|
|
23584
23792
|
// in a config file is preserved (opt-out respected).
|
|
23585
23793
|
defaultMode: "auto",
|
|
23586
23794
|
autoProceedDelayMs: DEFAULT_AUTONOMY_CONFIG.autoProceedDelayMs,
|
|
@@ -23695,6 +23903,7 @@ var IN_PROJECT_ALLOWED_KEYS = /* @__PURE__ */ new Set([
|
|
|
23695
23903
|
"context",
|
|
23696
23904
|
"tools",
|
|
23697
23905
|
"features",
|
|
23906
|
+
"superMemory",
|
|
23698
23907
|
"skills",
|
|
23699
23908
|
"autonomy",
|
|
23700
23909
|
"indexing",
|
|
@@ -23734,6 +23943,10 @@ var KNOWN_DENIED_IN_PROJECT = [
|
|
|
23734
23943
|
{
|
|
23735
23944
|
key: "fleet",
|
|
23736
23945
|
reason: "Fleet supervision knobs: a repo-committed config could enable autonomous subagent spawning/steering/termination and mailbox traffic on the victim machine."
|
|
23946
|
+
},
|
|
23947
|
+
{
|
|
23948
|
+
key: "git",
|
|
23949
|
+
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)."
|
|
23737
23950
|
}
|
|
23738
23951
|
];
|
|
23739
23952
|
var KNOWN_CONFIG_TOP_LEVEL_KEYS = /* @__PURE__ */ new Set([
|
|
@@ -23759,6 +23972,7 @@ var KNOWN_CONFIG_TOP_LEVEL_KEYS = /* @__PURE__ */ new Set([
|
|
|
23759
23972
|
"plugins",
|
|
23760
23973
|
"log",
|
|
23761
23974
|
"features",
|
|
23975
|
+
"superMemory",
|
|
23762
23976
|
"skills",
|
|
23763
23977
|
"yolo",
|
|
23764
23978
|
"nextPrediction",
|
|
@@ -23777,7 +23991,8 @@ var KNOWN_CONFIG_TOP_LEVEL_KEYS = /* @__PURE__ */ new Set([
|
|
|
23777
23991
|
"sync",
|
|
23778
23992
|
"extensions",
|
|
23779
23993
|
"acp",
|
|
23780
|
-
"fleet"
|
|
23994
|
+
"fleet",
|
|
23995
|
+
"git"
|
|
23781
23996
|
]);
|
|
23782
23997
|
function assertInProjectAllowListComplete() {
|
|
23783
23998
|
const missingFromBoth = [];
|
|
@@ -23870,6 +24085,19 @@ function stripUnsafeInProjectFields(inProject, sourcePath, warn = (msg) => conso
|
|
|
23870
24085
|
out["skills"] = clonedSkills;
|
|
23871
24086
|
}
|
|
23872
24087
|
}
|
|
24088
|
+
const outSuperMemory = out["superMemory"];
|
|
24089
|
+
if (outSuperMemory && typeof outSuperMemory === "object") {
|
|
24090
|
+
const storage = outSuperMemory["storage"];
|
|
24091
|
+
if (storage && typeof storage === "object" && "directory" in storage) {
|
|
24092
|
+
const clonedStorage = { ...storage };
|
|
24093
|
+
delete clonedStorage["directory"];
|
|
24094
|
+
out["superMemory"] = {
|
|
24095
|
+
...outSuperMemory,
|
|
24096
|
+
storage: clonedStorage
|
|
24097
|
+
};
|
|
24098
|
+
stripped.push("superMemory.storage.directory");
|
|
24099
|
+
}
|
|
24100
|
+
}
|
|
23873
24101
|
if (stripped.length > 0) {
|
|
23874
24102
|
warn(
|
|
23875
24103
|
JSON.stringify({
|
|
@@ -23885,8 +24113,8 @@ function stripUnsafeInProjectFields(inProject, sourcePath, warn = (msg) => conso
|
|
|
23885
24113
|
return out;
|
|
23886
24114
|
}
|
|
23887
24115
|
function samePath(a, b) {
|
|
23888
|
-
let ra =
|
|
23889
|
-
let rb =
|
|
24116
|
+
let ra = path25.resolve(a);
|
|
24117
|
+
let rb = path25.resolve(b);
|
|
23890
24118
|
if (process.platform === "win32" || process.platform === "darwin") {
|
|
23891
24119
|
ra = ra.toLowerCase();
|
|
23892
24120
|
rb = rb.toLowerCase();
|
|
@@ -23988,7 +24216,7 @@ var DefaultConfigLoader = class {
|
|
|
23988
24216
|
}
|
|
23989
24217
|
}
|
|
23990
24218
|
this.validateBehavior(cfg);
|
|
23991
|
-
if (this.strict) {
|
|
24219
|
+
if (this.strict && !opts.skipIdentityValidation) {
|
|
23992
24220
|
this.validateIdentity(cfg);
|
|
23993
24221
|
}
|
|
23994
24222
|
return Object.freeze(cfg);
|
|
@@ -24000,7 +24228,7 @@ var DefaultConfigLoader = class {
|
|
|
24000
24228
|
await withFileLock(fp, async () => {
|
|
24001
24229
|
let parsed;
|
|
24002
24230
|
try {
|
|
24003
|
-
const raw = await
|
|
24231
|
+
const raw = await fs12.readFile(fp, "utf8");
|
|
24004
24232
|
const result = safeParse(raw);
|
|
24005
24233
|
if (!result.ok || !isPlainRecord(result.value)) {
|
|
24006
24234
|
return;
|
|
@@ -24119,7 +24347,7 @@ var DefaultConfigLoader = class {
|
|
|
24119
24347
|
const fp = this.paths.syncConfig;
|
|
24120
24348
|
const t0 = Date.now();
|
|
24121
24349
|
try {
|
|
24122
|
-
const raw = await
|
|
24350
|
+
const raw = await fs12.readFile(fp, "utf8");
|
|
24123
24351
|
const parsed = safeParse(raw);
|
|
24124
24352
|
if (!parsed.ok || !parsed.value) {
|
|
24125
24353
|
this.events?.emit("storage.read", {
|
|
@@ -24185,7 +24413,7 @@ var DefaultConfigLoader = class {
|
|
|
24185
24413
|
const t0 = Date.now();
|
|
24186
24414
|
let mtimeMs = null;
|
|
24187
24415
|
try {
|
|
24188
|
-
const stat13 = await
|
|
24416
|
+
const stat13 = await fs12.stat(file);
|
|
24189
24417
|
mtimeMs = stat13.mtimeMs;
|
|
24190
24418
|
const cached = this.jsonCache.get(file);
|
|
24191
24419
|
if (cached && cached.mtimeMs === mtimeMs) {
|
|
@@ -24219,7 +24447,7 @@ var DefaultConfigLoader = class {
|
|
|
24219
24447
|
}
|
|
24220
24448
|
let raw;
|
|
24221
24449
|
try {
|
|
24222
|
-
raw = await
|
|
24450
|
+
raw = await fs12.readFile(file, "utf8");
|
|
24223
24451
|
} catch (err) {
|
|
24224
24452
|
if (err.code !== "ENOENT") {
|
|
24225
24453
|
this.events?.emit("storage.read", {
|
|
@@ -24458,6 +24686,11 @@ function deepFreeze(obj) {
|
|
|
24458
24686
|
return Object.freeze(obj);
|
|
24459
24687
|
}
|
|
24460
24688
|
|
|
24689
|
+
// src/storage/memory-backend.ts
|
|
24690
|
+
import { randomUUID as randomUUID11 } from "node:crypto";
|
|
24691
|
+
import * as fs13 from "node:fs/promises";
|
|
24692
|
+
import * as path26 from "node:path";
|
|
24693
|
+
|
|
24461
24694
|
// src/types/memory.ts
|
|
24462
24695
|
var MEMORY_TYPE_LABELS = {
|
|
24463
24696
|
fact: "Fact",
|
|
@@ -24623,7 +24856,7 @@ var FileMemoryBackend = class {
|
|
|
24623
24856
|
}
|
|
24624
24857
|
async getMtime(file) {
|
|
24625
24858
|
try {
|
|
24626
|
-
const stat13 = await
|
|
24859
|
+
const stat13 = await fs13.stat(file);
|
|
24627
24860
|
return stat13.mtimeMs;
|
|
24628
24861
|
} catch {
|
|
24629
24862
|
return 0;
|
|
@@ -24670,13 +24903,13 @@ var FileMemoryBackend = class {
|
|
|
24670
24903
|
}
|
|
24671
24904
|
async remember(scope, entry, filePath) {
|
|
24672
24905
|
const file = this.resolveFile(filePath, scope);
|
|
24673
|
-
await ensureDir(
|
|
24906
|
+
await ensureDir(path26.dirname(file));
|
|
24674
24907
|
let existing = "";
|
|
24675
24908
|
try {
|
|
24676
|
-
existing = await
|
|
24909
|
+
existing = await fs13.readFile(file, "utf8");
|
|
24677
24910
|
} catch {
|
|
24678
24911
|
}
|
|
24679
|
-
const id = `mem_${Date.now()}_${
|
|
24912
|
+
const id = `mem_${Date.now()}_${randomUUID11().slice(0, 8)}`;
|
|
24680
24913
|
const meta = formatMetadata(entry);
|
|
24681
24914
|
const line = `
|
|
24682
24915
|
- [${entry.ts}] ${id}${meta} ${entry.text.replace(/\n/g, " ")}
|
|
@@ -24691,7 +24924,7 @@ ${line}`;
|
|
|
24691
24924
|
return withFileLock(file, async () => {
|
|
24692
24925
|
let existing;
|
|
24693
24926
|
try {
|
|
24694
|
-
existing = await
|
|
24927
|
+
existing = await fs13.readFile(file, "utf8");
|
|
24695
24928
|
} catch {
|
|
24696
24929
|
return 0;
|
|
24697
24930
|
}
|
|
@@ -24728,7 +24961,7 @@ ${line}`;
|
|
|
24728
24961
|
async readAll(scope, filePath) {
|
|
24729
24962
|
const file = this.resolveFile(filePath, scope);
|
|
24730
24963
|
try {
|
|
24731
|
-
return await
|
|
24964
|
+
return await fs13.readFile(file, "utf8");
|
|
24732
24965
|
} catch {
|
|
24733
24966
|
return "";
|
|
24734
24967
|
}
|
|
@@ -24752,7 +24985,7 @@ ${line}`;
|
|
|
24752
24985
|
const file = this.resolveFile(filePath, scope);
|
|
24753
24986
|
let existing;
|
|
24754
24987
|
try {
|
|
24755
|
-
existing = await
|
|
24988
|
+
existing = await fs13.readFile(file, "utf8");
|
|
24756
24989
|
} catch {
|
|
24757
24990
|
return 0;
|
|
24758
24991
|
}
|
|
@@ -24772,7 +25005,7 @@ ${line}`;
|
|
|
24772
25005
|
const next = lines.join("\n");
|
|
24773
25006
|
const backup = `${file}.bak.${Date.now()}`;
|
|
24774
25007
|
try {
|
|
24775
|
-
await
|
|
25008
|
+
await fs13.copyFile(file, backup);
|
|
24776
25009
|
await pruneConsolidateBackups(file);
|
|
24777
25010
|
} catch {
|
|
24778
25011
|
}
|
|
@@ -24786,14 +25019,14 @@ ${line}`;
|
|
|
24786
25019
|
}
|
|
24787
25020
|
};
|
|
24788
25021
|
async function pruneConsolidateBackups(file) {
|
|
24789
|
-
const dir =
|
|
24790
|
-
const base =
|
|
25022
|
+
const dir = path26.dirname(file);
|
|
25023
|
+
const base = path26.basename(file);
|
|
24791
25024
|
const prefix = `${base}.bak.`;
|
|
24792
|
-
const backups = (await
|
|
25025
|
+
const backups = (await fs13.readdir(dir)).filter((name) => name.startsWith(prefix)).sort().reverse();
|
|
24793
25026
|
await Promise.all(
|
|
24794
25027
|
backups.slice(MAX_MEMORY_CONSOLIDATE_BACKUPS).map(async (name) => {
|
|
24795
25028
|
try {
|
|
24796
|
-
await
|
|
25029
|
+
await fs13.unlink(path26.join(dir, name));
|
|
24797
25030
|
} catch {
|
|
24798
25031
|
}
|
|
24799
25032
|
})
|
|
@@ -25153,6 +25386,10 @@ ${body.trim()}`);
|
|
|
25153
25386
|
score += 1;
|
|
25154
25387
|
reasons.push("preference");
|
|
25155
25388
|
break;
|
|
25389
|
+
case "reference":
|
|
25390
|
+
break;
|
|
25391
|
+
case "fact":
|
|
25392
|
+
break;
|
|
25156
25393
|
}
|
|
25157
25394
|
const ageDays = (now - new Date(entry.ts).getTime()) / (1e3 * 60 * 60 * 24);
|
|
25158
25395
|
if (ageDays < 1) score += 1;
|
|
@@ -25360,7 +25597,7 @@ ${body.trim()}`);
|
|
|
25360
25597
|
if (!this.persistBackup || scope === "project-agents") return;
|
|
25361
25598
|
try {
|
|
25362
25599
|
const content = await this.backend.readAll(scope, this.files[scope]);
|
|
25363
|
-
const { writeFile: writeFile7, mkdir: mkdir10 } = await import(
|
|
25600
|
+
const { writeFile: writeFile7, mkdir: mkdir10 } = await import("node:fs/promises");
|
|
25364
25601
|
await mkdir10(this.backupDir, { recursive: true });
|
|
25365
25602
|
await writeFile7(`${this.backupDir}/${scope}.md`, content, "utf8");
|
|
25366
25603
|
} catch {
|
|
@@ -25377,11 +25614,15 @@ function labelOf(scope) {
|
|
|
25377
25614
|
return "User memory";
|
|
25378
25615
|
}
|
|
25379
25616
|
}
|
|
25617
|
+
|
|
25618
|
+
// src/storage/plan-store.ts
|
|
25619
|
+
import * as fsp14 from "node:fs/promises";
|
|
25620
|
+
import { randomUUID as randomUUID12 } from "node:crypto";
|
|
25380
25621
|
async function loadPlan(filePath, events) {
|
|
25381
25622
|
const t0 = Date.now();
|
|
25382
25623
|
let raw;
|
|
25383
25624
|
try {
|
|
25384
|
-
raw = await
|
|
25625
|
+
raw = await fsp14.readFile(filePath, "utf8");
|
|
25385
25626
|
} catch (err) {
|
|
25386
25627
|
events?.emit("storage.error", {
|
|
25387
25628
|
sessionId: "~boot~",
|
|
@@ -25470,7 +25711,7 @@ function emptyPlan(sessionId, title) {
|
|
|
25470
25711
|
function addPlanItem(plan, title, details) {
|
|
25471
25712
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
25472
25713
|
const item = {
|
|
25473
|
-
id: `plan_${Date.now()}_${
|
|
25714
|
+
id: `plan_${Date.now()}_${randomUUID12().slice(0, 6)}`,
|
|
25474
25715
|
title,
|
|
25475
25716
|
details,
|
|
25476
25717
|
status: "open",
|
|
@@ -25544,7 +25785,7 @@ function deriveTodosFromPlanItem(plan, idOrIndex, subtasks) {
|
|
|
25544
25785
|
if (subtasks && subtasks.length > 0) {
|
|
25545
25786
|
for (const st of subtasks) {
|
|
25546
25787
|
todos.push({
|
|
25547
|
-
id: `todo_${Date.now()}_${
|
|
25788
|
+
id: `todo_${Date.now()}_${randomUUID12().slice(0, 6)}`,
|
|
25548
25789
|
content: st,
|
|
25549
25790
|
status: "pending",
|
|
25550
25791
|
promotedFromPlan: item.id
|
|
@@ -25669,6 +25910,10 @@ ${cat}:`);
|
|
|
25669
25910
|
}
|
|
25670
25911
|
return lines.join("\n");
|
|
25671
25912
|
}
|
|
25913
|
+
|
|
25914
|
+
// src/storage/queue-store.ts
|
|
25915
|
+
import * as fsp15 from "node:fs/promises";
|
|
25916
|
+
import * as path27 from "node:path";
|
|
25672
25917
|
var QueueStore = class {
|
|
25673
25918
|
file;
|
|
25674
25919
|
// Use `| undefined` (not `?`) so exactOptionalPropertyTypes doesn't
|
|
@@ -25676,7 +25921,7 @@ var QueueStore = class {
|
|
|
25676
25921
|
events;
|
|
25677
25922
|
traceId;
|
|
25678
25923
|
constructor(opts) {
|
|
25679
|
-
this.file =
|
|
25924
|
+
this.file = path27.join(opts.dir, "queue.json");
|
|
25680
25925
|
this.events = opts.events;
|
|
25681
25926
|
this.traceId = opts.traceId;
|
|
25682
25927
|
}
|
|
@@ -25721,7 +25966,7 @@ var QueueStore = class {
|
|
|
25721
25966
|
const t0 = Date.now();
|
|
25722
25967
|
let raw;
|
|
25723
25968
|
try {
|
|
25724
|
-
raw = await
|
|
25969
|
+
raw = await fsp15.readFile(this.file, "utf8");
|
|
25725
25970
|
} catch (err) {
|
|
25726
25971
|
const code = err.code;
|
|
25727
25972
|
if (code === "ENOENT") {
|
|
@@ -25802,7 +26047,7 @@ var QueueStore = class {
|
|
|
25802
26047
|
async clear() {
|
|
25803
26048
|
const t0 = Date.now();
|
|
25804
26049
|
try {
|
|
25805
|
-
await
|
|
26050
|
+
await fsp15.unlink(this.file);
|
|
25806
26051
|
this.events?.emit("storage.write", {
|
|
25807
26052
|
sessionId: this.traceId ?? "~boot~",
|
|
25808
26053
|
store: "queue",
|
|
@@ -25840,6 +26085,11 @@ function isPersistedQueueItem(v) {
|
|
|
25840
26085
|
const o = v;
|
|
25841
26086
|
return typeof o["displayText"] === "string" && Array.isArray(o["blocks"]);
|
|
25842
26087
|
}
|
|
26088
|
+
|
|
26089
|
+
// src/storage/recovery-lock.ts
|
|
26090
|
+
import * as fsp16 from "node:fs/promises";
|
|
26091
|
+
import * as os3 from "node:os";
|
|
26092
|
+
import * as path28 from "node:path";
|
|
25843
26093
|
var LOCK_FILE = "active.json";
|
|
25844
26094
|
var DEFAULT_MAX_AGE_MS = 24 * 60 * 60 * 1e3;
|
|
25845
26095
|
var RecoveryLock = class {
|
|
@@ -25850,9 +26100,9 @@ var RecoveryLock = class {
|
|
|
25850
26100
|
sessionStore;
|
|
25851
26101
|
probe;
|
|
25852
26102
|
constructor(opts) {
|
|
25853
|
-
this.file =
|
|
26103
|
+
this.file = path28.join(opts.dir, LOCK_FILE);
|
|
25854
26104
|
this.pid = opts.pid ?? process.pid;
|
|
25855
|
-
this.hostname = opts.hostname ??
|
|
26105
|
+
this.hostname = opts.hostname ?? os3.hostname();
|
|
25856
26106
|
this.maxAgeMs = opts.maxAgeMs ?? DEFAULT_MAX_AGE_MS;
|
|
25857
26107
|
this.sessionStore = opts.sessionStore;
|
|
25858
26108
|
this.probe = opts.isPidAlive ?? defaultIsPidAlive;
|
|
@@ -25911,7 +26161,7 @@ var RecoveryLock = class {
|
|
|
25911
26161
|
* null return before calling this.
|
|
25912
26162
|
*/
|
|
25913
26163
|
async write(sessionId) {
|
|
25914
|
-
await ensureDir(
|
|
26164
|
+
await ensureDir(path28.dirname(this.file));
|
|
25915
26165
|
const lock = {
|
|
25916
26166
|
v: 1,
|
|
25917
26167
|
sessionId,
|
|
@@ -25920,7 +26170,7 @@ var RecoveryLock = class {
|
|
|
25920
26170
|
startedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
25921
26171
|
};
|
|
25922
26172
|
try {
|
|
25923
|
-
await
|
|
26173
|
+
await fsp16.writeFile(this.file, JSON.stringify(lock), { flag: "wx", mode: 384 });
|
|
25924
26174
|
} catch (err) {
|
|
25925
26175
|
const code = err.code;
|
|
25926
26176
|
if (code === "EEXIST") {
|
|
@@ -25936,7 +26186,7 @@ var RecoveryLock = class {
|
|
|
25936
26186
|
*/
|
|
25937
26187
|
async clear() {
|
|
25938
26188
|
try {
|
|
25939
|
-
await
|
|
26189
|
+
await fsp16.unlink(this.file);
|
|
25940
26190
|
} catch (err) {
|
|
25941
26191
|
const code = err.code;
|
|
25942
26192
|
if (code === "ENOENT") return;
|
|
@@ -25946,7 +26196,7 @@ var RecoveryLock = class {
|
|
|
25946
26196
|
async readLock() {
|
|
25947
26197
|
let raw;
|
|
25948
26198
|
try {
|
|
25949
|
-
raw = await
|
|
26199
|
+
raw = await fsp16.readFile(this.file, "utf8");
|
|
25950
26200
|
} catch (err) {
|
|
25951
26201
|
const code = err.code;
|
|
25952
26202
|
if (code === "ENOENT") return null;
|
|
@@ -26196,6 +26446,9 @@ function resolveSessionLoggingConfig(cfg) {
|
|
|
26196
26446
|
}
|
|
26197
26447
|
};
|
|
26198
26448
|
}
|
|
26449
|
+
|
|
26450
|
+
// src/storage/session-reader.ts
|
|
26451
|
+
import * as fs14 from "node:fs/promises";
|
|
26199
26452
|
var DefaultSessionReader = class _DefaultSessionReader {
|
|
26200
26453
|
store;
|
|
26201
26454
|
eventCache = /* @__PURE__ */ new Map();
|
|
@@ -26213,7 +26466,7 @@ var DefaultSessionReader = class _DefaultSessionReader {
|
|
|
26213
26466
|
const sessionPath = sessionScopedPath(rootDir, sessionId, ".jsonl");
|
|
26214
26467
|
let mtimeMs = null;
|
|
26215
26468
|
try {
|
|
26216
|
-
const stat13 = await
|
|
26469
|
+
const stat13 = await fs14.stat(sessionPath);
|
|
26217
26470
|
mtimeMs = stat13.mtimeMs;
|
|
26218
26471
|
} catch {
|
|
26219
26472
|
this.eventCache.delete(sessionId);
|
|
@@ -26533,6 +26786,8 @@ function renderMarkdown(meta, events) {
|
|
|
26533
26786
|
lines.push("");
|
|
26534
26787
|
break;
|
|
26535
26788
|
}
|
|
26789
|
+
default:
|
|
26790
|
+
break;
|
|
26536
26791
|
}
|
|
26537
26792
|
}
|
|
26538
26793
|
return lines.join("\n");
|
|
@@ -26566,15 +26821,20 @@ function renderPlainText(meta, events) {
|
|
|
26566
26821
|
case "error":
|
|
26567
26822
|
lines.push(`[${e.ts}] ERROR (${e.phase}): ${e.message}`);
|
|
26568
26823
|
break;
|
|
26824
|
+
default:
|
|
26825
|
+
break;
|
|
26569
26826
|
}
|
|
26570
26827
|
}
|
|
26571
26828
|
return lines.join("\n");
|
|
26572
26829
|
}
|
|
26830
|
+
|
|
26831
|
+
// src/storage/todos-checkpoint.ts
|
|
26832
|
+
import * as fsp17 from "node:fs/promises";
|
|
26573
26833
|
async function loadTodosCheckpoint(filePath, events, traceId) {
|
|
26574
26834
|
const t0 = Date.now();
|
|
26575
26835
|
let raw;
|
|
26576
26836
|
try {
|
|
26577
|
-
raw = await
|
|
26837
|
+
raw = await fsp17.readFile(filePath, "utf8");
|
|
26578
26838
|
} catch (err) {
|
|
26579
26839
|
events?.emit("storage.error", {
|
|
26580
26840
|
sessionId: traceId ?? "~boot~",
|
|
@@ -26709,7 +26969,185 @@ function attachTodosCheckpoint(state, filePath, sessionId, events, traceId) {
|
|
|
26709
26969
|
}
|
|
26710
26970
|
};
|
|
26711
26971
|
}
|
|
26712
|
-
|
|
26713
|
-
|
|
26972
|
+
export {
|
|
26973
|
+
AGENTS_BY_PHASE,
|
|
26974
|
+
AGENT_CATALOG,
|
|
26975
|
+
ALL_AGENT_DEFINITIONS,
|
|
26976
|
+
ALL_FLEET_AGENTS,
|
|
26977
|
+
AUDIT_LOG_AGENT,
|
|
26978
|
+
AutoApprovePermissionPolicy,
|
|
26979
|
+
AutoCompactionMiddleware,
|
|
26980
|
+
AutonomousRunner,
|
|
26981
|
+
BUG_HUNTER_AGENT,
|
|
26982
|
+
BudgetExceededError,
|
|
26983
|
+
CODEX_MODELS,
|
|
26984
|
+
ConfigMigrationError,
|
|
26985
|
+
DEFAULT_AUTONOMY_CONFIG,
|
|
26986
|
+
DEFAULT_CONFIG_MIGRATIONS,
|
|
26987
|
+
DEFAULT_CONTEXT_CONFIG,
|
|
26988
|
+
DEFAULT_DIRECTOR_PREAMBLE,
|
|
26989
|
+
DEFAULT_DISPATCH_ROLE,
|
|
26990
|
+
DEFAULT_SUBAGENT_BASELINE,
|
|
26991
|
+
DEFAULT_TOOLS_CONFIG,
|
|
26992
|
+
DefaultAttachmentStore,
|
|
26993
|
+
DefaultConfigLoader,
|
|
26994
|
+
DefaultConfigStore,
|
|
26995
|
+
DefaultDesignKitLoader,
|
|
26996
|
+
DefaultErrorHandler,
|
|
26997
|
+
DefaultHealthRegistry,
|
|
26998
|
+
DefaultLogger,
|
|
26999
|
+
DefaultMemoryStore,
|
|
27000
|
+
DefaultModeStore,
|
|
27001
|
+
DefaultModelsRegistry,
|
|
27002
|
+
DefaultMultiAgentCoordinator,
|
|
27003
|
+
DefaultPermissionPolicy,
|
|
27004
|
+
DefaultPromptLoader,
|
|
27005
|
+
DefaultProviderRunner,
|
|
27006
|
+
DefaultRetryPolicy,
|
|
27007
|
+
DefaultSecretScrubber,
|
|
27008
|
+
DefaultSecretVault,
|
|
27009
|
+
DefaultSessionReader,
|
|
27010
|
+
DefaultSessionStore,
|
|
27011
|
+
DefaultSkillLoader,
|
|
27012
|
+
Director,
|
|
27013
|
+
DirectorStateCheckpoint,
|
|
27014
|
+
DoneConditionChecker,
|
|
27015
|
+
EternalAutonomyEngine,
|
|
27016
|
+
FLEET_ROSTER,
|
|
27017
|
+
FLEET_ROSTER_BUDGETS,
|
|
27018
|
+
FleetBus,
|
|
27019
|
+
FleetSpawnBudgetError,
|
|
27020
|
+
FleetUsageAggregator,
|
|
27021
|
+
HybridCompactor,
|
|
27022
|
+
InMemoryAgentBridge,
|
|
27023
|
+
InMemoryBridgeTransport,
|
|
27024
|
+
InMemoryMetricsSink,
|
|
27025
|
+
IntelligentCompactor,
|
|
27026
|
+
LLMSelector,
|
|
27027
|
+
NULL_FLEET_BUS,
|
|
27028
|
+
NoopMetricsSink,
|
|
27029
|
+
NoopTracer,
|
|
27030
|
+
OTelTracer,
|
|
27031
|
+
PROMETHEUS_CONTENT_TYPE,
|
|
27032
|
+
ParallelEternalEngine,
|
|
27033
|
+
QueueStore,
|
|
27034
|
+
REFACTOR_PLANNER_AGENT,
|
|
27035
|
+
RecoveryLock,
|
|
27036
|
+
SECURITY_SCANNER_AGENT,
|
|
27037
|
+
SelectiveCompactor,
|
|
27038
|
+
SessionAnalyzer,
|
|
27039
|
+
SubagentBudget,
|
|
27040
|
+
ToolExecutor,
|
|
27041
|
+
_resetDesignKitLoaderMemo,
|
|
27042
|
+
_resetDesignRulesCache,
|
|
27043
|
+
activateDesign,
|
|
27044
|
+
addPlanItem,
|
|
27045
|
+
allServers,
|
|
27046
|
+
applyRosterBudget,
|
|
27047
|
+
applyTokenOverrides,
|
|
27048
|
+
attachAutoExtend,
|
|
27049
|
+
attachPlanCheckpoint,
|
|
27050
|
+
attachTodosCheckpoint,
|
|
27051
|
+
awsServer,
|
|
27052
|
+
blockServer,
|
|
27053
|
+
braveSearchServer,
|
|
27054
|
+
buildGoalPreamble,
|
|
27055
|
+
buildOtlpMetricsRequest,
|
|
27056
|
+
buildOtlpTracesRequest,
|
|
27057
|
+
classifyFamily,
|
|
27058
|
+
clearActiveKit,
|
|
27059
|
+
clearPersistedActiveKit,
|
|
27060
|
+
clearPlan,
|
|
27061
|
+
codexModelMeta,
|
|
27062
|
+
colorToHex,
|
|
27063
|
+
composeDirectorPrompt,
|
|
27064
|
+
composeSubagentPrompt,
|
|
27065
|
+
context7Server,
|
|
27066
|
+
contextManagerTool,
|
|
27067
|
+
createContextManagerTool,
|
|
27068
|
+
createDelegateTool,
|
|
27069
|
+
createMessage,
|
|
27070
|
+
createSessionEventBridge,
|
|
27071
|
+
createStrategyCompactor,
|
|
27072
|
+
decryptConfigSecrets,
|
|
27073
|
+
deriveTodosFromPlanItem,
|
|
27074
|
+
describeCatalogModel,
|
|
27075
|
+
designProjectDir,
|
|
27076
|
+
detectFrontendFile,
|
|
27077
|
+
detectFrontendIntent,
|
|
27078
|
+
dispatchAgent,
|
|
27079
|
+
emptyPlan,
|
|
27080
|
+
encryptConfigSecrets,
|
|
27081
|
+
everArtServer,
|
|
27082
|
+
filesystemServer,
|
|
27083
|
+
formatPlan,
|
|
27084
|
+
formatPlanTemplates,
|
|
27085
|
+
getAgentDefinition,
|
|
27086
|
+
getDesignKitLoader,
|
|
27087
|
+
getDesignState,
|
|
27088
|
+
getPlanTemplate,
|
|
27089
|
+
githubServer,
|
|
27090
|
+
googleMapsServer,
|
|
27091
|
+
installDesignStudioMiddleware,
|
|
27092
|
+
isColorToken,
|
|
27093
|
+
listPlanTemplates,
|
|
27094
|
+
loadActiveKit,
|
|
27095
|
+
loadDirectorState,
|
|
27096
|
+
loadPlan,
|
|
27097
|
+
loadProjectDesignRules,
|
|
27098
|
+
loadProjectModes,
|
|
27099
|
+
loadTodosCheckpoint,
|
|
27100
|
+
loadUserModes,
|
|
27101
|
+
makeAgentSubagentRunner,
|
|
27102
|
+
makeAskTool,
|
|
27103
|
+
makeAssignTool,
|
|
27104
|
+
makeAutonomyPromptContributor,
|
|
27105
|
+
makeAwaitTasksTool,
|
|
27106
|
+
makeCollabDebugTool,
|
|
27107
|
+
makeDesignDetectToolCallMiddleware,
|
|
27108
|
+
makeDesignDetectUserInputMiddleware,
|
|
27109
|
+
makeDesignStudioRequestMiddleware,
|
|
27110
|
+
makeDesignVerifyToolCallMiddleware,
|
|
27111
|
+
makeDirectorSessionFactory,
|
|
27112
|
+
makeFleetEmitTool,
|
|
27113
|
+
makeFleetTool,
|
|
27114
|
+
makeLLMClassifier,
|
|
27115
|
+
makeRollUpTool,
|
|
27116
|
+
makeSpawnTool,
|
|
27117
|
+
makeTerminateTool,
|
|
27118
|
+
materializeTokens,
|
|
27119
|
+
migratePlaintextSecrets,
|
|
27120
|
+
miniMaxVisionServer,
|
|
27121
|
+
oklchToHex,
|
|
27122
|
+
parseOklch,
|
|
27123
|
+
playwrightServer,
|
|
27124
|
+
recordKitChoice,
|
|
27125
|
+
recordOverrides,
|
|
27126
|
+
removePlanItem,
|
|
27127
|
+
renderPrometheus,
|
|
27128
|
+
renderPrompt,
|
|
27129
|
+
resolveAuditLevel,
|
|
27130
|
+
resolveBundledDesignKitsDir,
|
|
27131
|
+
resolveProviderModelList,
|
|
27132
|
+
resolveSessionLoggingConfig,
|
|
27133
|
+
rewriteConfigEncrypted,
|
|
27134
|
+
rosterSummaryFromConfigs,
|
|
27135
|
+
runConfigMigrations,
|
|
27136
|
+
runDesignVerify,
|
|
27137
|
+
savePlan,
|
|
27138
|
+
saveTodosCheckpoint,
|
|
27139
|
+
scoreAgents,
|
|
27140
|
+
sentinelServer,
|
|
27141
|
+
setActiveKit,
|
|
27142
|
+
setDesignOverrides,
|
|
27143
|
+
setPlanItemStatus,
|
|
27144
|
+
slackServer,
|
|
27145
|
+
sshManagerServer,
|
|
27146
|
+
startMetricsServer,
|
|
27147
|
+
startOtlpMetricsExporter,
|
|
27148
|
+
startOtlpTraceExporter,
|
|
27149
|
+
verifyFiles,
|
|
27150
|
+
wireMetricsToEvents,
|
|
27151
|
+
zaiVisionServer
|
|
27152
|
+
};
|
|
26714
27153
|
//# sourceMappingURL=index.js.map
|
|
26715
|
-
//# sourceMappingURL=index.js.map
|