gsd-pi 2.63.0-dev.026d309 → 2.63.0-dev.786f0ff
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -134
- package/dist/cli.js +48 -6
- package/dist/headless-query.js +11 -1
- package/dist/help-text.js +4 -1
- package/dist/onboarding.js +15 -8
- package/dist/resource-loader.js +18 -3
- package/dist/resources/extensions/cmux/index.js +21 -12
- package/dist/resources/extensions/gsd/auto/detect-stuck.js +27 -0
- package/dist/resources/extensions/gsd/auto/finalize-timeout.js +40 -0
- package/dist/resources/extensions/gsd/auto/loop.js +4 -0
- package/dist/resources/extensions/gsd/auto/phases.js +157 -22
- package/dist/resources/extensions/gsd/auto/session.js +12 -0
- package/dist/resources/extensions/gsd/auto-dashboard.js +9 -3
- package/dist/resources/extensions/gsd/auto-model-selection.js +32 -0
- package/dist/resources/extensions/gsd/auto-post-unit.js +124 -10
- package/dist/resources/extensions/gsd/auto-prompts.js +25 -0
- package/dist/resources/extensions/gsd/auto-recovery.js +15 -7
- package/dist/resources/extensions/gsd/auto-start.js +10 -21
- package/dist/resources/extensions/gsd/auto-timers.js +2 -1
- package/dist/resources/extensions/gsd/auto-tool-tracking.js +17 -0
- package/dist/resources/extensions/gsd/auto-worktree.js +13 -7
- package/dist/resources/extensions/gsd/auto.js +19 -2
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +147 -75
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +13 -0
- package/dist/resources/extensions/gsd/bootstrap/query-tools.js +85 -0
- package/dist/resources/extensions/gsd/bootstrap/register-extension.js +3 -0
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +32 -1
- package/dist/resources/extensions/gsd/bootstrap/sanitize-complete-milestone.js +54 -0
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +30 -2
- package/dist/resources/extensions/gsd/commands-handlers.js +9 -4
- package/dist/resources/extensions/gsd/constants.js +42 -0
- package/dist/resources/extensions/gsd/db-writer.js +72 -4
- package/dist/resources/extensions/gsd/forensics.js +20 -4
- package/dist/resources/extensions/gsd/gsd-db.js +64 -17
- package/dist/resources/extensions/gsd/guided-flow.js +19 -0
- package/dist/resources/extensions/gsd/metrics.js +27 -1
- package/dist/resources/extensions/gsd/native-git-bridge.js +5 -3
- package/dist/resources/extensions/gsd/preferences-types.js +2 -0
- package/dist/resources/extensions/gsd/preferences.js +7 -2
- package/dist/resources/extensions/gsd/prompt-loader.js +7 -0
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +2 -0
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +2 -0
- package/dist/resources/extensions/gsd/prompts/doctor-heal.md +1 -0
- package/dist/resources/extensions/gsd/prompts/forensics.md +2 -0
- package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +2 -0
- package/dist/resources/extensions/gsd/prompts/system.md +4 -7
- package/dist/resources/extensions/gsd/prompts/validate-milestone.md +2 -0
- package/dist/resources/extensions/gsd/roadmap-mutations.js +1 -1
- package/dist/resources/extensions/gsd/roadmap-slices.js +9 -5
- package/dist/resources/extensions/gsd/safety/content-validator.js +73 -0
- package/dist/resources/extensions/gsd/safety/destructive-guard.js +34 -0
- package/dist/resources/extensions/gsd/safety/evidence-collector.js +109 -0
- package/dist/resources/extensions/gsd/safety/evidence-cross-ref.js +83 -0
- package/dist/resources/extensions/gsd/safety/file-change-validator.js +71 -0
- package/dist/resources/extensions/gsd/safety/git-checkpoint.js +91 -0
- package/dist/resources/extensions/gsd/safety/safety-harness.js +64 -0
- package/dist/resources/extensions/gsd/slice-parallel-conflict.js +67 -0
- package/dist/resources/extensions/gsd/slice-parallel-eligibility.js +51 -0
- package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +378 -0
- package/dist/resources/extensions/gsd/state.js +74 -14
- package/dist/resources/extensions/gsd/status-guards.js +11 -0
- package/dist/resources/extensions/gsd/tools/complete-milestone.js +17 -12
- package/dist/resources/extensions/gsd/tools/complete-slice.js +40 -26
- package/dist/resources/extensions/gsd/tools/complete-task.js +12 -12
- package/dist/resources/extensions/gsd/tools/plan-milestone.js +33 -25
- package/dist/resources/extensions/gsd/tools/plan-slice.js +5 -8
- package/dist/resources/extensions/gsd/workflow-projections.js +21 -5
- package/dist/resources/extensions/gsd/worktree-manager.js +82 -29
- package/dist/resources/extensions/gsd/worktree-resolver.js +4 -3
- package/dist/resources/extensions/mcp-client/auth.js +101 -0
- package/dist/resources/extensions/mcp-client/index.js +10 -1
- package/dist/resources/extensions/ollama/index.js +28 -22
- package/dist/resources/extensions/ollama/model-capabilities.js +37 -34
- package/dist/resources/extensions/ollama/ndjson-stream.js +54 -0
- package/dist/resources/extensions/ollama/ollama-chat-provider.js +380 -0
- package/dist/resources/extensions/ollama/ollama-client.js +23 -32
- package/dist/resources/extensions/ollama/ollama-discovery.js +2 -7
- package/dist/resources/extensions/ollama/ollama-tool.js +62 -0
- package/dist/resources/extensions/ollama/thinking-parser.js +104 -0
- package/dist/update-cmd.js +4 -2
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +20 -20
- package/dist/web/standalone/.next/build-manifest.json +2 -2
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +20 -20
- package/dist/web/standalone/.next/server/chunks/6897.js +12 -0
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +2 -2
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/package.json +1 -1
- package/packages/pi-agent-core/dist/agent-loop.d.ts +8 -0
- package/packages/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/agent-loop.js +50 -0
- package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/packages/pi-agent-core/src/agent-loop.test.ts +221 -5
- package/packages/pi-agent-core/src/agent-loop.ts +53 -0
- package/packages/pi-ai/dist/types.d.ts +16 -1
- package/packages/pi-ai/dist/types.d.ts.map +1 -1
- package/packages/pi-ai/dist/types.js.map +1 -1
- package/packages/pi-ai/src/types.ts +18 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +9 -0
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.js +50 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.test.js +41 -0
- package/packages/pi-coding-agent/dist/core/auth-storage.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts +7 -0
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.js +31 -4
- package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.test.js +28 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/provider-registration.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/extensions/provider-registration.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/provider-registration.test.js +46 -0
- package/packages/pi-coding-agent/dist/core/extensions/provider-registration.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.d.ts +1 -0
- package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.js +12 -0
- package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-resolver.js +3 -3
- package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader.d.ts +23 -1
- package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader.js +80 -56
- package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.js +9 -0
- package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
- package/packages/pi-coding-agent/src/core/auth-storage.test.ts +53 -0
- package/packages/pi-coding-agent/src/core/auth-storage.ts +66 -1
- package/packages/pi-coding-agent/src/core/extensions/loader.test.ts +39 -1
- package/packages/pi-coding-agent/src/core/extensions/loader.ts +34 -4
- package/packages/pi-coding-agent/src/core/extensions/provider-registration.test.ts +81 -0
- package/packages/pi-coding-agent/src/core/extensions/types.ts +2 -0
- package/packages/pi-coding-agent/src/core/model-registry.ts +14 -0
- package/packages/pi-coding-agent/src/core/model-resolver.ts +3 -3
- package/packages/pi-coding-agent/src/core/resource-loader.ts +89 -56
- package/packages/pi-coding-agent/src/core/sdk.ts +10 -0
- package/src/resources/extensions/cmux/index.ts +18 -12
- package/src/resources/extensions/gsd/auto/detect-stuck.ts +27 -0
- package/src/resources/extensions/gsd/auto/finalize-timeout.ts +46 -0
- package/src/resources/extensions/gsd/auto/loop.ts +5 -0
- package/src/resources/extensions/gsd/auto/phases.ts +194 -33
- package/src/resources/extensions/gsd/auto/session.ts +14 -0
- package/src/resources/extensions/gsd/auto-dashboard.ts +11 -3
- package/src/resources/extensions/gsd/auto-model-selection.ts +36 -0
- package/src/resources/extensions/gsd/auto-post-unit.ts +141 -12
- package/src/resources/extensions/gsd/auto-prompts.ts +21 -0
- package/src/resources/extensions/gsd/auto-recovery.ts +9 -8
- package/src/resources/extensions/gsd/auto-start.ts +11 -20
- package/src/resources/extensions/gsd/auto-timers.ts +2 -1
- package/src/resources/extensions/gsd/auto-tool-tracking.ts +19 -0
- package/src/resources/extensions/gsd/auto-worktree.ts +14 -6
- package/src/resources/extensions/gsd/auto.ts +22 -1
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +160 -88
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +15 -0
- package/src/resources/extensions/gsd/bootstrap/query-tools.ts +98 -0
- package/src/resources/extensions/gsd/bootstrap/register-extension.ts +4 -0
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +36 -1
- package/src/resources/extensions/gsd/bootstrap/sanitize-complete-milestone.ts +57 -0
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +31 -2
- package/src/resources/extensions/gsd/commands-handlers.ts +10 -4
- package/src/resources/extensions/gsd/constants.ts +44 -0
- package/src/resources/extensions/gsd/db-writer.ts +78 -4
- package/src/resources/extensions/gsd/forensics.ts +21 -5
- package/src/resources/extensions/gsd/gsd-db.ts +64 -17
- package/src/resources/extensions/gsd/guided-flow.ts +22 -0
- package/src/resources/extensions/gsd/metrics.ts +28 -1
- package/src/resources/extensions/gsd/native-git-bridge.ts +5 -3
- package/src/resources/extensions/gsd/preferences-types.ts +16 -0
- package/src/resources/extensions/gsd/preferences.ts +9 -2
- package/src/resources/extensions/gsd/prompt-loader.ts +8 -0
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +2 -0
- package/src/resources/extensions/gsd/prompts/complete-slice.md +2 -0
- package/src/resources/extensions/gsd/prompts/doctor-heal.md +1 -0
- package/src/resources/extensions/gsd/prompts/forensics.md +2 -0
- package/src/resources/extensions/gsd/prompts/reassess-roadmap.md +2 -0
- package/src/resources/extensions/gsd/prompts/system.md +4 -7
- package/src/resources/extensions/gsd/prompts/validate-milestone.md +2 -0
- package/src/resources/extensions/gsd/roadmap-mutations.ts +1 -1
- package/src/resources/extensions/gsd/roadmap-slices.ts +10 -5
- package/src/resources/extensions/gsd/safety/content-validator.ts +98 -0
- package/src/resources/extensions/gsd/safety/destructive-guard.ts +49 -0
- package/src/resources/extensions/gsd/safety/evidence-collector.ts +151 -0
- package/src/resources/extensions/gsd/safety/evidence-cross-ref.ts +120 -0
- package/src/resources/extensions/gsd/safety/file-change-validator.ts +108 -0
- package/src/resources/extensions/gsd/safety/git-checkpoint.ts +106 -0
- package/src/resources/extensions/gsd/safety/safety-harness.ts +105 -0
- package/src/resources/extensions/gsd/slice-parallel-conflict.ts +86 -0
- package/src/resources/extensions/gsd/slice-parallel-eligibility.ts +73 -0
- package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +477 -0
- package/src/resources/extensions/gsd/state.ts +67 -12
- package/src/resources/extensions/gsd/status-guards.ts +13 -0
- package/src/resources/extensions/gsd/tests/artifact-corruption-2630.test.ts +288 -0
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +34 -13
- package/src/resources/extensions/gsd/tests/cmux.test.ts +58 -0
- package/src/resources/extensions/gsd/tests/cold-resume-db-reopen.test.ts +51 -0
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +140 -0
- package/src/resources/extensions/gsd/tests/complete-slice-string-coercion.test.ts +211 -0
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/dashboard-model-label-ordering.test.ts +107 -0
- package/src/resources/extensions/gsd/tests/db-access-guardrails.test.ts +109 -0
- package/src/resources/extensions/gsd/tests/db-path-worktree-symlink.test.ts +13 -9
- package/src/resources/extensions/gsd/tests/db-writer.test.ts +134 -0
- package/src/resources/extensions/gsd/tests/deferred-slice-dispatch.test.ts +203 -0
- package/src/resources/extensions/gsd/tests/discuss-tool-scoping.test.ts +130 -0
- package/src/resources/extensions/gsd/tests/doctor-fix-flag.test.ts +92 -0
- package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +116 -0
- package/src/resources/extensions/gsd/tests/flat-rate-routing-guard.test.ts +50 -0
- package/src/resources/extensions/gsd/tests/forensics-stuck-loops.test.ts +103 -0
- package/src/resources/extensions/gsd/tests/git-checkpoint.test.ts +94 -0
- package/src/resources/extensions/gsd/tests/insert-slice-no-wipe.test.ts +88 -0
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +27 -7
- package/src/resources/extensions/gsd/tests/integration/idle-recovery.test.ts +34 -0
- package/src/resources/extensions/gsd/tests/metrics.test.ts +116 -1
- package/src/resources/extensions/gsd/tests/milestone-status-tool.test.ts +201 -0
- package/src/resources/extensions/gsd/tests/plan-milestone-title.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +82 -18
- package/src/resources/extensions/gsd/tests/preferences.test.ts +10 -0
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +25 -0
- package/src/resources/extensions/gsd/tests/roadmap-slices.test.ts +69 -0
- package/src/resources/extensions/gsd/tests/shared-wal.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/slice-context-injection.test.ts +50 -0
- package/src/resources/extensions/gsd/tests/slice-parallel-conflict.test.ts +92 -0
- package/src/resources/extensions/gsd/tests/slice-parallel-eligibility.test.ts +95 -0
- package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +83 -0
- package/src/resources/extensions/gsd/tests/stuck-detection-coverage.test.ts +42 -0
- package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +103 -0
- package/src/resources/extensions/gsd/tests/tool-param-optionality.test.ts +349 -0
- package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +35 -2
- package/src/resources/extensions/gsd/tests/worktree-health-monorepo.test.ts +73 -0
- package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +34 -0
- package/src/resources/extensions/gsd/tests/worktree-submodule-safety.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-teardown-safety.test.ts +148 -0
- package/src/resources/extensions/gsd/tools/complete-milestone.ts +34 -20
- package/src/resources/extensions/gsd/tools/complete-slice.ts +41 -26
- package/src/resources/extensions/gsd/tools/complete-task.ts +12 -12
- package/src/resources/extensions/gsd/tools/plan-milestone.ts +55 -30
- package/src/resources/extensions/gsd/tools/plan-slice.ts +13 -8
- package/src/resources/extensions/gsd/types.ts +44 -22
- package/src/resources/extensions/gsd/workflow-logger.ts +2 -1
- package/src/resources/extensions/gsd/workflow-projections.ts +23 -5
- package/src/resources/extensions/gsd/worktree-manager.ts +76 -28
- package/src/resources/extensions/gsd/worktree-resolver.ts +4 -3
- package/src/resources/extensions/mcp-client/auth.ts +149 -0
- package/src/resources/extensions/mcp-client/index.ts +16 -1
- package/src/resources/extensions/ollama/index.ts +26 -25
- package/src/resources/extensions/ollama/model-capabilities.ts +41 -34
- package/src/resources/extensions/ollama/ndjson-stream.ts +63 -0
- package/src/resources/extensions/ollama/ollama-auth-mode.test.ts +20 -0
- package/src/resources/extensions/ollama/ollama-chat-provider.ts +459 -0
- package/src/resources/extensions/ollama/ollama-client.ts +30 -30
- package/src/resources/extensions/ollama/ollama-discovery.ts +5 -8
- package/src/resources/extensions/ollama/ollama-tool.ts +69 -0
- package/src/resources/extensions/ollama/tests/ollama-chat-provider-stream.test.ts +82 -0
- package/src/resources/extensions/ollama/tests/ollama-discovery.test.ts +0 -27
- package/src/resources/extensions/ollama/thinking-parser.ts +116 -0
- package/src/resources/extensions/ollama/types.ts +23 -0
- package/dist/web/standalone/.next/server/chunks/2229.js +0 -12
- /package/dist/web/standalone/.next/static/{TTlAguZQ5vR9EOv6G8cel → SDB1T-4NqkMjYirjjqQhr}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{TTlAguZQ5vR9EOv6G8cel → SDB1T-4NqkMjYirjjqQhr}/_ssgManifest.js +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
|
|
2
2
|
import { homedir } from "node:os";
|
|
3
|
-
import { basename, dirname, join, resolve, sep } from "node:path";
|
|
3
|
+
import { basename, dirname, join, relative, resolve, sep } from "node:path";
|
|
4
4
|
import chalk from "chalk";
|
|
5
5
|
import { CONFIG_DIR_NAME, getAgentDir } from "../config.js";
|
|
6
6
|
import { loadThemeFromPath, type Theme } from "../modes/interactive/theme/theme.js";
|
|
@@ -121,6 +121,7 @@ export interface DefaultResourceLoaderOptions {
|
|
|
121
121
|
additionalPromptTemplatePaths?: string[];
|
|
122
122
|
additionalThemePaths?: string[];
|
|
123
123
|
extensionFactories?: ExtensionFactory[];
|
|
124
|
+
bundledExtensionKeys?: Set<string>;
|
|
124
125
|
noExtensions?: boolean;
|
|
125
126
|
noSkills?: boolean;
|
|
126
127
|
noPromptTemplates?: boolean;
|
|
@@ -161,6 +162,7 @@ export class DefaultResourceLoader implements ResourceLoader {
|
|
|
161
162
|
private settingsManager: SettingsManager;
|
|
162
163
|
private eventBus: EventBus;
|
|
163
164
|
private packageManager: DefaultPackageManager;
|
|
165
|
+
private bundledExtensionKeys: Set<string>;
|
|
164
166
|
private additionalExtensionPaths: string[];
|
|
165
167
|
private additionalSkillPaths: string[];
|
|
166
168
|
private additionalPromptTemplatePaths: string[];
|
|
@@ -218,6 +220,7 @@ export class DefaultResourceLoader implements ResourceLoader {
|
|
|
218
220
|
agentDir: this.agentDir,
|
|
219
221
|
settingsManager: this.settingsManager,
|
|
220
222
|
});
|
|
223
|
+
this.bundledExtensionKeys = options.bundledExtensionKeys ?? new Set();
|
|
221
224
|
this.additionalExtensionPaths = options.additionalExtensionPaths ?? [];
|
|
222
225
|
this.additionalSkillPaths = options.additionalSkillPaths ?? [];
|
|
223
226
|
this.additionalPromptTemplatePaths = options.additionalPromptTemplatePaths ?? [];
|
|
@@ -827,66 +830,96 @@ export class DefaultResourceLoader implements ResourceLoader {
|
|
|
827
830
|
}
|
|
828
831
|
|
|
829
832
|
private detectExtensionConflicts(extensions: Extension[]): Array<{ path: string; message: string }> {
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
const toolOwners = new Map<string, string>();
|
|
834
|
-
const commandOwners = new Map<string, string>();
|
|
835
|
-
const flagOwners = new Map<string, string>();
|
|
836
|
-
|
|
837
|
-
for (const ext of extensions) {
|
|
838
|
-
// Check tools
|
|
839
|
-
for (const toolName of ext.tools.keys()) {
|
|
840
|
-
const existingOwner = toolOwners.get(toolName);
|
|
841
|
-
if (existingOwner && existingOwner !== ext.path) {
|
|
842
|
-
// Determine if the existing owner is a bundled extension by checking
|
|
843
|
-
// its name against the canonical bundled extensions list
|
|
844
|
-
const ownerName = this.getExtensionNameFromPath(existingOwner);
|
|
845
|
-
const isBuiltIn = this.bundledExtensionNames.has(ownerName);
|
|
846
|
-
const hint = isBuiltIn
|
|
847
|
-
? ` (built-in tool supersedes — consider removing ${ext.path})`
|
|
848
|
-
: "";
|
|
849
|
-
conflicts.push({
|
|
850
|
-
path: ext.path,
|
|
851
|
-
message: `Tool "${toolName}" conflicts with ${existingOwner}${hint}`,
|
|
852
|
-
});
|
|
853
|
-
} else {
|
|
854
|
-
toolOwners.set(toolName, ext.path);
|
|
855
|
-
}
|
|
856
|
-
}
|
|
833
|
+
return detectExtensionConflicts(extensions, this.bundledExtensionKeys, join(this.agentDir, "extensions"));
|
|
834
|
+
}
|
|
835
|
+
}
|
|
857
836
|
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
837
|
+
/**
|
|
838
|
+
* Extract the extension directory name (key) from a full extension path.
|
|
839
|
+
* Given extensionsDir `/home/user/.gsd/agent/extensions` and
|
|
840
|
+
* ownerPath `/home/user/.gsd/agent/extensions/mcp-client/index.js`,
|
|
841
|
+
* returns `"mcp-client"`. Returns `undefined` when the path is not
|
|
842
|
+
* under extensionsDir.
|
|
843
|
+
*/
|
|
844
|
+
export function extractExtensionKey(ownerPath: string, extensionsDir: string): string | undefined {
|
|
845
|
+
const normalizedDir = resolve(extensionsDir);
|
|
846
|
+
const normalizedPath = resolve(ownerPath);
|
|
847
|
+
const prefix = normalizedDir.endsWith(sep) ? normalizedDir : `${normalizedDir}${sep}`;
|
|
848
|
+
if (!normalizedPath.startsWith(prefix)) {
|
|
849
|
+
return undefined;
|
|
850
|
+
}
|
|
851
|
+
const relPath = relative(normalizedDir, normalizedPath);
|
|
852
|
+
const firstSegment = relPath.split(/[\\/]/)[0];
|
|
853
|
+
return firstSegment?.replace(/\.(?:ts|js)$/, "") || undefined;
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
/**
|
|
857
|
+
* Detect tool/command/flag name collisions across loaded extensions.
|
|
858
|
+
*
|
|
859
|
+
* When the first-registered owner of a name is a bundled extension
|
|
860
|
+
* (its key appears in `bundledExtensionKeys`), the conflict message
|
|
861
|
+
* includes a "supersedes" hint so downstream display can downgrade the
|
|
862
|
+
* severity from "Extension load error" to "Extension conflict".
|
|
863
|
+
*/
|
|
864
|
+
export function detectExtensionConflicts(
|
|
865
|
+
extensions: Extension[],
|
|
866
|
+
bundledExtensionKeys: Set<string>,
|
|
867
|
+
extensionsDir: string,
|
|
868
|
+
): Array<{ path: string; message: string }> {
|
|
869
|
+
const conflicts: Array<{ path: string; message: string }> = [];
|
|
870
|
+
|
|
871
|
+
const toolOwners = new Map<string, string>();
|
|
872
|
+
const commandOwners = new Map<string, string>();
|
|
873
|
+
const flagOwners = new Map<string, string>();
|
|
874
|
+
|
|
875
|
+
const isBundled = (ownerPath: string): boolean => {
|
|
876
|
+
const key = extractExtensionKey(ownerPath, extensionsDir);
|
|
877
|
+
return key !== undefined && bundledExtensionKeys.has(key);
|
|
878
|
+
};
|
|
879
|
+
|
|
880
|
+
for (const ext of extensions) {
|
|
881
|
+
for (const toolName of ext.tools.keys()) {
|
|
882
|
+
const existingOwner = toolOwners.get(toolName);
|
|
883
|
+
if (existingOwner && existingOwner !== ext.path) {
|
|
884
|
+
const hint = isBundled(existingOwner)
|
|
885
|
+
? ` (built-in tool supersedes — consider removing ${ext.path})`
|
|
886
|
+
: "";
|
|
887
|
+
conflicts.push({
|
|
888
|
+
path: ext.path,
|
|
889
|
+
message: `Tool "${toolName}" conflicts with ${existingOwner}${hint}`,
|
|
890
|
+
});
|
|
891
|
+
} else {
|
|
892
|
+
toolOwners.set(toolName, ext.path);
|
|
874
893
|
}
|
|
894
|
+
}
|
|
875
895
|
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
896
|
+
for (const commandName of ext.commands.keys()) {
|
|
897
|
+
const existingOwner = commandOwners.get(commandName);
|
|
898
|
+
if (existingOwner && existingOwner !== ext.path) {
|
|
899
|
+
const hint = isBundled(existingOwner)
|
|
900
|
+
? ` (built-in command supersedes — consider removing ${ext.path})`
|
|
901
|
+
: "";
|
|
902
|
+
conflicts.push({
|
|
903
|
+
path: ext.path,
|
|
904
|
+
message: `Command "/${commandName}" conflicts with ${existingOwner}${hint}`,
|
|
905
|
+
});
|
|
906
|
+
} else {
|
|
907
|
+
commandOwners.set(commandName, ext.path);
|
|
887
908
|
}
|
|
888
909
|
}
|
|
889
910
|
|
|
890
|
-
|
|
911
|
+
for (const flagName of ext.flags.keys()) {
|
|
912
|
+
const existingOwner = flagOwners.get(flagName);
|
|
913
|
+
if (existingOwner && existingOwner !== ext.path) {
|
|
914
|
+
conflicts.push({
|
|
915
|
+
path: ext.path,
|
|
916
|
+
message: `Flag "--${flagName}" conflicts with ${existingOwner}`,
|
|
917
|
+
});
|
|
918
|
+
} else {
|
|
919
|
+
flagOwners.set(flagName, ext.path);
|
|
920
|
+
}
|
|
921
|
+
}
|
|
891
922
|
}
|
|
923
|
+
|
|
924
|
+
return conflicts;
|
|
892
925
|
}
|
|
@@ -214,6 +214,16 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
214
214
|
}
|
|
215
215
|
}
|
|
216
216
|
|
|
217
|
+
// Flush extension provider registrations so extension-provided models (e.g. claude-code/*)
|
|
218
|
+
// are available in the registry before model resolution. Without this, findInitialModel()
|
|
219
|
+
// cannot find extension models and falls back to built-in providers (#3534).
|
|
220
|
+
const extensionsForModelResolution = resourceLoader.getExtensions();
|
|
221
|
+
for (const { name, config } of extensionsForModelResolution.runtime.pendingProviderRegistrations) {
|
|
222
|
+
modelRegistry.registerProvider(name, config);
|
|
223
|
+
}
|
|
224
|
+
// Clear the queue so bindCore() doesn't re-register the same providers.
|
|
225
|
+
extensionsForModelResolution.runtime.pendingProviderRegistrations = [];
|
|
226
|
+
|
|
217
227
|
// If still no model, use findInitialModel (checks settings default, then provider defaults)
|
|
218
228
|
if (!model) {
|
|
219
229
|
const result = await findInitialModel({
|
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { execFileSync, spawn } from "node:child_process";
|
|
2
2
|
import { existsSync } from "node:fs";
|
|
3
3
|
import { tmpdir } from "node:os";
|
|
4
4
|
import { join } from "node:path";
|
|
5
|
-
import { promisify } from "node:util";
|
|
6
5
|
import type { GSDPreferences } from "../gsd/preferences.js";
|
|
7
6
|
import type { GSDState, Phase } from "../gsd/types.js";
|
|
8
|
-
|
|
9
|
-
const execFileAsync = promisify(execFile);
|
|
10
7
|
const DEFAULT_SOCKET_PATH = "/tmp/cmux.sock";
|
|
11
8
|
const STATUS_KEY = "gsd";
|
|
12
9
|
const lastSidebarSnapshots = new Map<string, string>();
|
|
@@ -200,6 +197,7 @@ export class CmuxClient {
|
|
|
200
197
|
return execFileSync("cmux", args, {
|
|
201
198
|
encoding: "utf-8",
|
|
202
199
|
timeout: 3000,
|
|
200
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
203
201
|
env: process.env,
|
|
204
202
|
});
|
|
205
203
|
} catch {
|
|
@@ -209,16 +207,24 @@ export class CmuxClient {
|
|
|
209
207
|
|
|
210
208
|
private async runAsync(args: string[]): Promise<string | null> {
|
|
211
209
|
if (!this.canRun()) return null;
|
|
212
|
-
|
|
213
|
-
const
|
|
214
|
-
|
|
215
|
-
timeout: 5000,
|
|
210
|
+
return new Promise<string | null>((resolve) => {
|
|
211
|
+
const child = spawn("cmux", args, {
|
|
212
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
216
213
|
env: process.env,
|
|
217
214
|
});
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
215
|
+
const chunks: Buffer[] = [];
|
|
216
|
+
let settled = false;
|
|
217
|
+
const done = (result: string | null) => {
|
|
218
|
+
if (!settled) { settled = true; resolve(result); }
|
|
219
|
+
};
|
|
220
|
+
const timer = setTimeout(() => { child.kill(); done(null); }, 5000);
|
|
221
|
+
child.stdout!.on("data", (chunk: Buffer) => chunks.push(chunk));
|
|
222
|
+
child.on("close", (code) => {
|
|
223
|
+
clearTimeout(timer);
|
|
224
|
+
done(code === 0 ? Buffer.concat(chunks).toString("utf-8") : null);
|
|
225
|
+
});
|
|
226
|
+
child.on("error", () => { clearTimeout(timer); done(null); });
|
|
227
|
+
});
|
|
222
228
|
}
|
|
223
229
|
|
|
224
230
|
getCapabilities(): unknown | null {
|
|
@@ -6,6 +6,13 @@
|
|
|
6
6
|
|
|
7
7
|
import type { WindowEntry } from "./types.js";
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
* Pattern matching ENOENT errors with a file path.
|
|
11
|
+
* Matches: "ENOENT: no such file or directory, access '/path/to/file'"
|
|
12
|
+
* and similar Node.js filesystem error messages.
|
|
13
|
+
*/
|
|
14
|
+
const ENOENT_PATH_RE = /ENOENT[^']*'([^']+)'/;
|
|
15
|
+
|
|
9
16
|
/**
|
|
10
17
|
* Analyze a sliding window of recent unit dispatches for stuck patterns.
|
|
11
18
|
* Returns a signal with reason if stuck, null otherwise.
|
|
@@ -13,6 +20,8 @@ import type { WindowEntry } from "./types.js";
|
|
|
13
20
|
* Rule 1: Same error string twice in a row → stuck immediately.
|
|
14
21
|
* Rule 2: Same unit key 3+ consecutive times → stuck (preserves prior behavior).
|
|
15
22
|
* Rule 3: Oscillation A→B→A→B in last 4 entries → stuck.
|
|
23
|
+
* Rule 4: Same ENOENT path in any 2 entries within the window → stuck (#3575).
|
|
24
|
+
* Missing files don't self-heal between retries — retrying wastes budget.
|
|
16
25
|
*/
|
|
17
26
|
export function detectStuck(
|
|
18
27
|
window: readonly WindowEntry[],
|
|
@@ -56,5 +65,23 @@ export function detectStuck(
|
|
|
56
65
|
}
|
|
57
66
|
}
|
|
58
67
|
|
|
68
|
+
// Rule 4: Same ENOENT path seen twice in window (#3575)
|
|
69
|
+
// Missing files don't appear between retries — stop immediately.
|
|
70
|
+
const enoentPaths = new Map<string, number>();
|
|
71
|
+
for (const entry of window) {
|
|
72
|
+
if (!entry.error) continue;
|
|
73
|
+
const match = ENOENT_PATH_RE.exec(entry.error);
|
|
74
|
+
if (!match) continue;
|
|
75
|
+
const filePath = match[1];
|
|
76
|
+
const count = (enoentPaths.get(filePath) ?? 0) + 1;
|
|
77
|
+
if (count >= 2) {
|
|
78
|
+
return {
|
|
79
|
+
stuck: true,
|
|
80
|
+
reason: `Missing file referenced twice: ${filePath} (ENOENT)`,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
enoentPaths.set(filePath, count);
|
|
84
|
+
}
|
|
85
|
+
|
|
59
86
|
return null;
|
|
60
87
|
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* auto/finalize-timeout.ts — Timeout guard for post-unit finalization.
|
|
3
|
+
*
|
|
4
|
+
* Prevents the auto-loop from hanging indefinitely when
|
|
5
|
+
* postUnitPostVerification() never resolves (#2344).
|
|
6
|
+
*
|
|
7
|
+
* Leaf module — no imports from auto/ to avoid circular dependencies.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/** Timeout for postUnitPostVerification in runFinalize (ms). */
|
|
11
|
+
export const FINALIZE_POST_TIMEOUT_MS = 60_000;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Race a promise against a timeout. Returns an object indicating whether
|
|
15
|
+
* the timeout fired and the resolved value (if any).
|
|
16
|
+
*
|
|
17
|
+
* Unlike Promise.race with a rejection, this returns a discriminated
|
|
18
|
+
* result so callers can handle timeouts as a recoverable condition
|
|
19
|
+
* rather than an exception.
|
|
20
|
+
*
|
|
21
|
+
* The timeout timer is always cleaned up, whether the promise resolves
|
|
22
|
+
* or the timeout fires.
|
|
23
|
+
*/
|
|
24
|
+
export async function withTimeout<T>(
|
|
25
|
+
promise: Promise<T>,
|
|
26
|
+
timeoutMs: number,
|
|
27
|
+
label: string,
|
|
28
|
+
): Promise<{ value: T; timedOut: false } | { value: undefined; timedOut: true }> {
|
|
29
|
+
let timeoutHandle: ReturnType<typeof setTimeout> | undefined;
|
|
30
|
+
|
|
31
|
+
const timeoutPromise = new Promise<{ value: undefined; timedOut: true }>((resolve) => {
|
|
32
|
+
timeoutHandle = setTimeout(() => {
|
|
33
|
+
resolve({ value: undefined, timedOut: true });
|
|
34
|
+
}, timeoutMs);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
try {
|
|
38
|
+
const result = await Promise.race([
|
|
39
|
+
promise.then((value) => ({ value, timedOut: false as const })),
|
|
40
|
+
timeoutPromise,
|
|
41
|
+
]);
|
|
42
|
+
return result;
|
|
43
|
+
} finally {
|
|
44
|
+
if (timeoutHandle) clearTimeout(timeoutHandle);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -259,6 +259,11 @@ export async function autoLoop(
|
|
|
259
259
|
// ── Blanket catch: absorb unexpected exceptions, apply graduated recovery ──
|
|
260
260
|
const msg = loopErr instanceof Error ? loopErr.message : String(loopErr);
|
|
261
261
|
|
|
262
|
+
// Always emit iteration-end on error so the journal records iteration
|
|
263
|
+
// completion even on failure (#2344). Without this, errors in
|
|
264
|
+
// runFinalize leave the journal incomplete, making diagnosis harder.
|
|
265
|
+
deps.emitJournalEvent({ ts: new Date().toISOString(), flowId, seq: nextSeq(), eventType: "iteration-end", data: { iteration, error: msg } });
|
|
266
|
+
|
|
262
267
|
// ── Infrastructure errors: immediate stop, no retry ──
|
|
263
268
|
// These are unrecoverable (disk full, OOM, etc.). Retrying just burns
|
|
264
269
|
// LLM budget on guaranteed failures.
|