gsd-pi 2.64.0-dev.f8aad9b → 2.65.0-dev.16e10d7
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/headless.js +3 -1
- package/dist/mcp-server.js +6 -2
- package/dist/resources/extensions/bg-shell/bg-shell-lifecycle.js +22 -7
- package/dist/resources/extensions/bg-shell/process-manager.js +6 -1
- package/dist/resources/extensions/browser-tools/capture.js +20 -1
- package/dist/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +93 -0
- package/dist/resources/extensions/gsd/auto/run-unit.js +13 -2
- package/dist/resources/extensions/gsd/auto-dispatch.js +94 -8
- package/dist/resources/extensions/gsd/auto-model-selection.js +7 -5
- package/dist/resources/extensions/gsd/auto-post-unit.js +115 -7
- package/dist/resources/extensions/gsd/auto-prompts.js +24 -0
- package/dist/resources/extensions/gsd/auto-recovery.js +12 -8
- package/dist/resources/extensions/gsd/auto-start.js +35 -1
- package/dist/resources/extensions/gsd/auto-tool-tracking.js +10 -0
- package/dist/resources/extensions/gsd/auto-verification.js +138 -1
- package/dist/resources/extensions/gsd/auto-worktree.js +29 -7
- package/dist/resources/extensions/gsd/auto.js +2 -2
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +17 -4
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +34 -13
- package/dist/resources/extensions/gsd/bootstrap/notify-interceptor.js +28 -0
- package/dist/resources/extensions/gsd/bootstrap/query-tools.js +6 -4
- package/dist/resources/extensions/gsd/bootstrap/register-extension.js +5 -1
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +12 -1
- package/dist/resources/extensions/gsd/bootstrap/register-shortcuts.js +16 -0
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +20 -0
- package/dist/resources/extensions/gsd/commands/catalog.js +7 -1
- package/dist/resources/extensions/gsd/commands/context.js +8 -1
- package/dist/resources/extensions/gsd/commands/handlers/core.js +21 -0
- package/dist/resources/extensions/gsd/commands/handlers/notifications-handler.js +104 -0
- package/dist/resources/extensions/gsd/commands/handlers/ops.js +5 -0
- package/dist/resources/extensions/gsd/commands-extensions.js +1 -1
- package/dist/resources/extensions/gsd/config-overlay.js +312 -0
- package/dist/resources/extensions/gsd/detection.js +1 -1
- package/dist/resources/extensions/gsd/dispatch-guard.js +2 -1
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +1 -0
- package/dist/resources/extensions/gsd/doctor.js +2 -1
- package/dist/resources/extensions/gsd/gitignore.js +1 -0
- package/dist/resources/extensions/gsd/gsd-db.js +11 -2
- package/dist/resources/extensions/gsd/guided-flow.js +220 -29
- package/dist/resources/extensions/gsd/md-importer.js +14 -7
- package/dist/resources/extensions/gsd/notification-overlay.js +256 -0
- package/dist/resources/extensions/gsd/notification-store.js +273 -0
- package/dist/resources/extensions/gsd/notification-widget.js +56 -0
- package/dist/resources/extensions/gsd/parallel-orchestrator.js +17 -11
- package/dist/resources/extensions/gsd/post-execution-checks.js +407 -0
- package/dist/resources/extensions/gsd/pre-execution-checks.js +471 -0
- package/dist/resources/extensions/gsd/preferences-types.js +7 -0
- package/dist/resources/extensions/gsd/preferences-validation.js +78 -1
- package/dist/resources/extensions/gsd/preferences.js +13 -2
- package/dist/resources/extensions/gsd/preparation.js +1092 -0
- package/dist/resources/extensions/gsd/prompt-validation.js +67 -0
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +3 -3
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/discuss-prepared.md +424 -0
- package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +4 -1
- package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +5 -4
- package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +23 -0
- package/dist/resources/extensions/gsd/prompts/rethink.md +2 -1
- package/dist/resources/extensions/gsd/prompts/validate-milestone.md +56 -23
- package/dist/resources/extensions/gsd/quick.js +19 -15
- package/dist/resources/extensions/gsd/reactive-graph.js +12 -0
- package/dist/resources/extensions/gsd/roadmap-slices.js +24 -5
- package/dist/resources/extensions/gsd/safety/content-validator.js +3 -3
- package/dist/resources/extensions/gsd/session-lock.js +23 -1
- package/dist/resources/extensions/gsd/state.js +100 -12
- package/dist/resources/extensions/gsd/templates/context-enhanced.md +138 -0
- package/dist/resources/extensions/gsd/tools/complete-slice.js +12 -3
- package/dist/resources/extensions/gsd/tools/complete-task.js +16 -4
- package/dist/resources/extensions/gsd/tools/plan-milestone.js +7 -5
- package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +5 -2
- package/dist/resources/extensions/gsd/tools/reopen-milestone.js +119 -0
- package/dist/resources/extensions/gsd/tools/reopen-slice.js +30 -0
- package/dist/resources/extensions/gsd/tools/reopen-task.js +18 -0
- package/dist/resources/extensions/gsd/triage-resolution.js +25 -9
- package/dist/resources/extensions/gsd/verification-evidence.js +18 -0
- package/dist/resources/extensions/gsd/workflow-logger.js +8 -0
- package/dist/resources/extensions/gsd/workflow-projections.js +4 -7
- package/dist/resources/extensions/gsd/workflow-reconcile.js +2 -4
- package/dist/resources/extensions/gsd/workflow-templates.js +11 -2
- package/dist/resources/extensions/gsd/worktree-manager.js +5 -2
- package/dist/resources/extensions/gsd/worktree.js +9 -0
- package/dist/resources/extensions/shared/interview-ui.js +1 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +18 -17
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
- package/dist/web/standalone/.next/routes-manifest.json +6 -0
- 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/notifications/route.js +3 -0
- package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -0
- package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -0
- 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 +18 -17
- package/dist/web/standalone/.next/server/functions-config-manifest.json +1 -0
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
- 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/dist/web/standalone/.next/static/Z3TgDP0c7kG9j8CVQVGcl/_buildManifest.js +1 -0
- package/dist/web/standalone/.next/static/chunks/6502.8874bcae249c02e1.js +9 -0
- package/dist/web/standalone/.next/static/chunks/app/_global-error/page-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/boot/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/input/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/resize/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/stream/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/browse-directories/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/captures/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/cleanup/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/dev-mode/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/doctor/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/experimental/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/export-data/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/files/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/forensics/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/git/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/history/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/hooks/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/inspect/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/knowledge/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/live-state/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/notifications/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/onboarding/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/preferences/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/projects/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/recovery/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/remote-questions/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/session/browser/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/session/command/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/session/events/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/session/manage/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/settings-data/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/shutdown/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/skill-health/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/steer/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/switch-root/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/input/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/resize/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/sessions/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/stream/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/upload/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/undo/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/update/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/visualizer/route-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-8805a20e15762c3c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{webpack-a1c1e452c6b32d04.js → webpack-9fed74684e1c5bb1.js} +1 -1
- package/package.json +1 -1
- package/packages/pi-agent-core/dist/agent-loop.js +26 -9
- package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/packages/pi-agent-core/src/agent-loop.test.ts +100 -4
- package/packages/pi-agent-core/src/agent-loop.ts +43 -12
- package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js +38 -0
- package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js +11 -0
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.js +24 -0
- package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader.js +4 -1
- package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.js +30 -19
- package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.test.js +51 -0
- package/packages/pi-coding-agent/dist/core/retry-handler.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.js +9 -9
- package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.d.ts +2 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.js +10 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +28 -5
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +15 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +18 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +6 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +40 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/agent-session-tool-refresh.test.ts +64 -0
- package/packages/pi-coding-agent/src/core/agent-session.ts +10 -0
- package/packages/pi-coding-agent/src/core/resource-loader-cache-reset.test.ts +42 -0
- package/packages/pi-coding-agent/src/core/resource-loader.ts +5 -1
- package/packages/pi-coding-agent/src/core/retry-handler.test.ts +80 -0
- package/packages/pi-coding-agent/src/core/retry-handler.ts +37 -25
- package/packages/pi-coding-agent/src/core/sdk.ts +9 -9
- package/packages/pi-coding-agent/src/modes/interactive/components/provider-manager.ts +10 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +29 -4
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +27 -0
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +16 -1
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +38 -0
- package/packages/pi-tui/dist/__tests__/overlay-layout.test.d.ts +2 -0
- package/packages/pi-tui/dist/__tests__/overlay-layout.test.d.ts.map +1 -0
- package/packages/pi-tui/dist/__tests__/overlay-layout.test.js +66 -0
- package/packages/pi-tui/dist/__tests__/overlay-layout.test.js.map +1 -0
- package/packages/pi-tui/dist/components/image.d.ts +2 -0
- package/packages/pi-tui/dist/components/image.d.ts.map +1 -1
- package/packages/pi-tui/dist/components/image.js +4 -0
- package/packages/pi-tui/dist/components/image.js.map +1 -1
- package/packages/pi-tui/dist/components/image.test.d.ts +6 -0
- package/packages/pi-tui/dist/components/image.test.d.ts.map +1 -0
- package/packages/pi-tui/dist/components/image.test.js +32 -0
- package/packages/pi-tui/dist/components/image.test.js.map +1 -0
- package/packages/pi-tui/dist/components/loader.d.ts +4 -2
- package/packages/pi-tui/dist/components/loader.d.ts.map +1 -1
- package/packages/pi-tui/dist/components/loader.js +27 -9
- package/packages/pi-tui/dist/components/loader.js.map +1 -1
- package/packages/pi-tui/dist/components/text.d.ts.map +1 -1
- package/packages/pi-tui/dist/components/text.js +2 -0
- package/packages/pi-tui/dist/components/text.js.map +1 -1
- package/packages/pi-tui/dist/overlay-layout.d.ts.map +1 -1
- package/packages/pi-tui/dist/overlay-layout.js +12 -1
- package/packages/pi-tui/dist/overlay-layout.js.map +1 -1
- package/packages/pi-tui/dist/tui.d.ts +4 -0
- package/packages/pi-tui/dist/tui.d.ts.map +1 -1
- package/packages/pi-tui/dist/tui.js +35 -0
- package/packages/pi-tui/dist/tui.js.map +1 -1
- package/packages/pi-tui/src/__tests__/overlay-layout.test.ts +82 -0
- package/packages/pi-tui/src/components/image.test.ts +36 -0
- package/packages/pi-tui/src/components/image.ts +5 -0
- package/packages/pi-tui/src/components/loader.ts +27 -10
- package/packages/pi-tui/src/components/text.ts +1 -0
- package/packages/pi-tui/src/overlay-layout.ts +13 -1
- package/packages/pi-tui/src/tui.ts +34 -0
- package/pkg/package.json +1 -1
- package/src/resources/extensions/bg-shell/bg-shell-lifecycle.ts +19 -7
- package/src/resources/extensions/bg-shell/process-manager.ts +8 -2
- package/src/resources/extensions/browser-tools/capture.ts +19 -1
- package/src/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +93 -0
- package/src/resources/extensions/gsd/auto/run-unit.ts +12 -2
- package/src/resources/extensions/gsd/auto-dispatch.ts +105 -8
- package/src/resources/extensions/gsd/auto-model-selection.ts +7 -5
- package/src/resources/extensions/gsd/auto-post-unit.ts +138 -6
- package/src/resources/extensions/gsd/auto-prompts.ts +31 -0
- package/src/resources/extensions/gsd/auto-recovery.ts +10 -8
- package/src/resources/extensions/gsd/auto-start.ts +38 -0
- package/src/resources/extensions/gsd/auto-tool-tracking.ts +10 -0
- package/src/resources/extensions/gsd/auto-verification.ts +190 -2
- package/src/resources/extensions/gsd/auto-worktree.ts +28 -7
- package/src/resources/extensions/gsd/auto.ts +2 -1
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +16 -4
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +35 -13
- package/src/resources/extensions/gsd/bootstrap/notify-interceptor.ts +34 -0
- package/src/resources/extensions/gsd/bootstrap/query-tools.ts +5 -4
- package/src/resources/extensions/gsd/bootstrap/register-extension.ts +4 -1
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +12 -1
- package/src/resources/extensions/gsd/bootstrap/register-shortcuts.ts +20 -0
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +28 -0
- package/src/resources/extensions/gsd/commands/catalog.ts +7 -1
- package/src/resources/extensions/gsd/commands/context.ts +7 -1
- package/src/resources/extensions/gsd/commands/handlers/core.ts +24 -0
- package/src/resources/extensions/gsd/commands/handlers/notifications-handler.ts +140 -0
- package/src/resources/extensions/gsd/commands/handlers/ops.ts +5 -0
- package/src/resources/extensions/gsd/commands-extensions.ts +1 -1
- package/src/resources/extensions/gsd/config-overlay.ts +331 -0
- package/src/resources/extensions/gsd/detection.ts +1 -1
- package/src/resources/extensions/gsd/dispatch-guard.ts +2 -1
- package/src/resources/extensions/gsd/docs/preferences-reference.md +1 -0
- package/src/resources/extensions/gsd/doctor.ts +2 -1
- package/src/resources/extensions/gsd/gitignore.ts +1 -0
- package/src/resources/extensions/gsd/gsd-db.ts +13 -2
- package/src/resources/extensions/gsd/guided-flow.ts +254 -30
- package/src/resources/extensions/gsd/md-importer.ts +13 -6
- package/src/resources/extensions/gsd/notification-overlay.ts +295 -0
- package/src/resources/extensions/gsd/notification-store.ts +293 -0
- package/src/resources/extensions/gsd/notification-widget.ts +68 -0
- package/src/resources/extensions/gsd/parallel-orchestrator.ts +19 -11
- package/src/resources/extensions/gsd/post-execution-checks.ts +539 -0
- package/src/resources/extensions/gsd/pre-execution-checks.ts +581 -0
- package/src/resources/extensions/gsd/preferences-types.ts +53 -0
- package/src/resources/extensions/gsd/preferences-validation.ts +78 -1
- package/src/resources/extensions/gsd/preferences.ts +13 -2
- package/src/resources/extensions/gsd/preparation.ts +1419 -0
- package/src/resources/extensions/gsd/prompt-validation.ts +88 -0
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +3 -3
- package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/discuss-prepared.md +424 -0
- package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +4 -1
- package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +5 -4
- package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +23 -0
- package/src/resources/extensions/gsd/prompts/rethink.md +2 -1
- package/src/resources/extensions/gsd/prompts/validate-milestone.md +56 -23
- package/src/resources/extensions/gsd/quick.ts +20 -15
- package/src/resources/extensions/gsd/reactive-graph.ts +18 -0
- package/src/resources/extensions/gsd/roadmap-slices.ts +21 -5
- package/src/resources/extensions/gsd/safety/content-validator.ts +3 -3
- package/src/resources/extensions/gsd/session-lock.ts +17 -1
- package/src/resources/extensions/gsd/state.ts +101 -11
- package/src/resources/extensions/gsd/templates/context-enhanced.md +138 -0
- package/src/resources/extensions/gsd/tests/adversarial-review-fixes.test.ts +223 -0
- package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +33 -2
- package/src/resources/extensions/gsd/tests/auto-remediate-slice-status.test.ts +56 -0
- package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +41 -0
- package/src/resources/extensions/gsd/tests/complete-slice-string-coercion.test.ts +36 -0
- package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +72 -0
- package/src/resources/extensions/gsd/tests/complete-task-normalize-lists.test.ts +54 -0
- package/src/resources/extensions/gsd/tests/defer-milestone-stamp.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +4 -3
- package/src/resources/extensions/gsd/tests/discuss-incremental-persistence.test.ts +36 -0
- package/src/resources/extensions/gsd/tests/discuss-slice-structured-questions.test.ts +46 -0
- package/src/resources/extensions/gsd/tests/discuss-tool-scope-leak.test.ts +76 -0
- package/src/resources/extensions/gsd/tests/dispatch-guard-closed-status.test.ts +33 -0
- package/src/resources/extensions/gsd/tests/dispatcher-stuck-planning.test.ts +37 -0
- package/src/resources/extensions/gsd/tests/enhanced-verification-integration.test.ts +526 -0
- package/src/resources/extensions/gsd/tests/error-success-mask.test.ts +37 -0
- package/src/resources/extensions/gsd/tests/find-missing-summaries-closed.test.ts +48 -0
- package/src/resources/extensions/gsd/tests/frontmatter-parse-noise.test.ts +42 -0
- package/src/resources/extensions/gsd/tests/gitignore-bg-shell.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/guided-flow-state-rebuild.test.ts +103 -0
- package/src/resources/extensions/gsd/tests/import-done-milestones.test.ts +42 -0
- package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +5 -3
- package/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts +4 -2
- package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +28 -30
- package/src/resources/extensions/gsd/tests/integration/test-isolation.ts +53 -0
- package/src/resources/extensions/gsd/tests/integration-prepared-discussion.test.ts +525 -0
- package/src/resources/extensions/gsd/tests/isolation-none-branch-guard.test.ts +62 -0
- package/src/resources/extensions/gsd/tests/needs-remediation-revalidation.test.ts +48 -0
- package/src/resources/extensions/gsd/tests/note-captures-executed.test.ts +46 -0
- package/src/resources/extensions/gsd/tests/notification-overlay.test.ts +73 -0
- package/src/resources/extensions/gsd/tests/notification-store.test.ts +282 -0
- package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +77 -0
- package/src/resources/extensions/gsd/tests/phantom-ghost-detection.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/phantom-milestone-default-queued.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +312 -0
- package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +813 -0
- package/src/resources/extensions/gsd/tests/pre-exec-backtick-strip.test.ts +68 -0
- package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +1197 -0
- package/src/resources/extensions/gsd/tests/pre-execution-fail-closed.test.ts +266 -0
- package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +457 -0
- package/src/resources/extensions/gsd/tests/preparation.test.ts +1211 -0
- package/src/resources/extensions/gsd/tests/project-root-cwd-crash.test.ts +53 -0
- package/src/resources/extensions/gsd/tests/projection-no-plan-overwrite.test.ts +83 -0
- package/src/resources/extensions/gsd/tests/prompt-builder.test.ts +669 -0
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +7 -4
- package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +85 -0
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/query-tools-db-open.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/queued-discuss-fast-path.test.ts +107 -0
- package/src/resources/extensions/gsd/tests/reactive-graph.test.ts +45 -0
- package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +63 -0
- package/src/resources/extensions/gsd/tests/rogue-file-detection.test.ts +4 -5
- package/src/resources/extensions/gsd/tests/run-uat-replay-cap.test.ts +51 -0
- package/src/resources/extensions/gsd/tests/show-config-command.test.ts +56 -0
- package/src/resources/extensions/gsd/tests/skip-slice-state-rebuild.test.ts +31 -0
- package/src/resources/extensions/gsd/tests/skipped-validation-completion.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/slice-sequence-insert.test.ts +51 -0
- package/src/resources/extensions/gsd/tests/smart-entry-complete.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/stale-lockfile-recovery.test.ts +36 -0
- package/src/resources/extensions/gsd/tests/stale-queued-milestone.test.ts +147 -0
- package/src/resources/extensions/gsd/tests/stale-worktree-cwd.test.ts +13 -0
- package/src/resources/extensions/gsd/tests/stash-pop-gsd-conflict.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/stash-queued-context-files.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/state-machine-full-walkthrough.test.ts +6 -7
- package/src/resources/extensions/gsd/tests/status-db-open.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/stuck-detection-coverage.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/symlink-extension-discovery.test.ts +125 -0
- package/src/resources/extensions/gsd/tests/sync-worktree-skip-current.test.ts +65 -0
- package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +29 -1
- package/src/resources/extensions/gsd/tests/triage-resolution.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/unstructured-continue-context-injection.test.ts +163 -0
- package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +3 -4
- package/src/resources/extensions/gsd/tests/verification-operational-gate.test.ts +15 -0
- package/src/resources/extensions/gsd/tests/verify-artifact-tightened.test.ts +89 -0
- package/src/resources/extensions/gsd/tests/worker-model-override.test.ts +48 -0
- package/src/resources/extensions/gsd/tests/worktree-expected-warnings.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/worktree-integration.test.ts +16 -0
- package/src/resources/extensions/gsd/tests/worktree-main-branch.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +16 -17
- package/src/resources/extensions/gsd/tests/worktree-sync-tasks.test.ts +13 -9
- package/src/resources/extensions/gsd/tests/worktree.test.ts +26 -9
- package/src/resources/extensions/gsd/tests/zero-slice-roadmap-guided.test.ts +19 -0
- package/src/resources/extensions/gsd/tools/complete-slice.ts +13 -3
- package/src/resources/extensions/gsd/tools/complete-task.ts +16 -4
- package/src/resources/extensions/gsd/tools/plan-milestone.ts +11 -9
- package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +5 -2
- package/src/resources/extensions/gsd/tools/reopen-milestone.ts +152 -0
- package/src/resources/extensions/gsd/tools/reopen-slice.ts +27 -0
- package/src/resources/extensions/gsd/tools/reopen-task.ts +17 -0
- package/src/resources/extensions/gsd/triage-resolution.ts +29 -10
- package/src/resources/extensions/gsd/types.ts +4 -0
- package/src/resources/extensions/gsd/verification-evidence.ts +68 -0
- package/src/resources/extensions/gsd/workflow-logger.ts +13 -0
- package/src/resources/extensions/gsd/workflow-projections.ts +4 -6
- package/src/resources/extensions/gsd/workflow-reconcile.ts +2 -3
- package/src/resources/extensions/gsd/workflow-templates.ts +11 -2
- package/src/resources/extensions/gsd/worktree-manager.ts +4 -2
- package/src/resources/extensions/gsd/worktree.ts +10 -0
- package/src/resources/extensions/shared/interview-ui.ts +1 -1
- package/src/resources/extensions/shared/tests/interview-notes-loop.test.ts +8 -10
- package/dist/web/standalone/.next/static/F1mOwzgCW9R8N3Pt1Et87/_buildManifest.js +0 -1
- package/dist/web/standalone/.next/static/chunks/6502.7593d7797a4b3999.js +0 -9
- package/dist/web/standalone/.next/static/chunks/app/_global-error/page-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/boot/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/input/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/resize/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/stream/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/browse-directories/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/captures/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/cleanup/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/dev-mode/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/doctor/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/experimental/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/export-data/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/files/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/forensics/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/git/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/history/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/hooks/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/inspect/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/knowledge/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/live-state/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/onboarding/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/preferences/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/projects/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/recovery/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/remote-questions/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/session/browser/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/session/command/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/session/events/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/session/manage/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/settings-data/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/shutdown/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/skill-health/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/steer/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/switch-root/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/input/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/resize/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/sessions/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/stream/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/upload/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/undo/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/update/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/visualizer/route-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-c4cc189e7b117ea2.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-c4cc189e7b117ea2.js +0 -1
- /package/dist/web/standalone/.next/static/{F1mOwzgCW9R8N3Pt1Et87 → Z3TgDP0c7kG9j8CVQVGcl}/_ssgManifest.js +0 -0
|
@@ -18,6 +18,7 @@ import { loadFile, parseSummary, resolveAllOverrides } from "./files.js";
|
|
|
18
18
|
import { loadPrompt } from "./prompt-loader.js";
|
|
19
19
|
import {
|
|
20
20
|
resolveSliceFile,
|
|
21
|
+
resolveSlicePath,
|
|
21
22
|
resolveTaskFile,
|
|
22
23
|
resolveMilestoneFile,
|
|
23
24
|
resolveTasksDir,
|
|
@@ -38,7 +39,7 @@ import {
|
|
|
38
39
|
} from "./auto-recovery.js";
|
|
39
40
|
import { regenerateIfMissing } from "./workflow-projections.js";
|
|
40
41
|
import { syncStateToProjectRoot } from "./auto-worktree.js";
|
|
41
|
-
import { isDbAvailable, getTask, getSlice, getMilestone, updateTaskStatus, _getAdapter } from "./gsd-db.js";
|
|
42
|
+
import { isDbAvailable, getTask, getSlice, getMilestone, updateTaskStatus, updateSliceStatus, _getAdapter } from "./gsd-db.js";
|
|
42
43
|
import { renderPlanCheckboxes } from "./markdown-renderer.js";
|
|
43
44
|
import { consumeSignal } from "./session-status-io.js";
|
|
44
45
|
import {
|
|
@@ -59,6 +60,10 @@ import { validateFileChanges } from "./safety/file-change-validator.js";
|
|
|
59
60
|
import { validateContent } from "./safety/content-validator.js";
|
|
60
61
|
import { resolveSafetyHarnessConfig } from "./safety/safety-harness.js";
|
|
61
62
|
import { resolveExpectedArtifactPath as resolveArtifactForContent } from "./auto-artifact-paths.js";
|
|
63
|
+
import { loadEffectiveGSDPreferences } from "./preferences.js";
|
|
64
|
+
import { getSliceTasks } from "./gsd-db.js";
|
|
65
|
+
import { runPreExecutionChecks, type PreExecutionResult } from "./pre-execution-checks.js";
|
|
66
|
+
import { writePreExecutionEvidence } from "./verification-evidence.js";
|
|
62
67
|
|
|
63
68
|
/** Maximum verification retry attempts before escalating to blocker placeholder (#2653). */
|
|
64
69
|
const MAX_VERIFICATION_RETRIES = 3;
|
|
@@ -156,7 +161,14 @@ export function detectRogueFileWrites(
|
|
|
156
161
|
|
|
157
162
|
const dbRow = getSlice(mid, sid);
|
|
158
163
|
if (!dbRow || dbRow.status !== "complete") {
|
|
159
|
-
|
|
164
|
+
// Auto-remediate: SUMMARY exists on disk but DB is stale — sync DB to
|
|
165
|
+
// match filesystem instead of reporting as rogue (#3633).
|
|
166
|
+
try {
|
|
167
|
+
updateSliceStatus(mid, sid, "complete", new Date().toISOString());
|
|
168
|
+
} catch {
|
|
169
|
+
// If DB update fails, fall back to rogue detection so the issue is visible
|
|
170
|
+
rogues.push({ path: summaryPath, unitType, unitId });
|
|
171
|
+
}
|
|
160
172
|
}
|
|
161
173
|
} else if (unitType === "plan-milestone") {
|
|
162
174
|
if (!mid) return [];
|
|
@@ -577,11 +589,14 @@ export async function postUnitPreVerification(pctx: PostUnitContext, opts?: PreV
|
|
|
577
589
|
"error",
|
|
578
590
|
);
|
|
579
591
|
} else if (!triggerArtifactVerified) {
|
|
580
|
-
// #2883: If the artifact is missing because the tool invocation
|
|
581
|
-
// failed (malformed
|
|
582
|
-
// same failure. Pause auto-mode instead of
|
|
592
|
+
// #2883/#3595: If the artifact is missing because the tool invocation
|
|
593
|
+
// failed (malformed JSON) or was skipped (queued user message), retrying
|
|
594
|
+
// will produce the same failure. Pause auto-mode instead of looping.
|
|
583
595
|
if (s.lastToolInvocationError) {
|
|
584
|
-
const
|
|
596
|
+
const isUserSkip = /queued user message/i.test(s.lastToolInvocationError);
|
|
597
|
+
const errMsg = isUserSkip
|
|
598
|
+
? `Tool skipped for ${s.currentUnit.type}: ${s.lastToolInvocationError}. Queued user message interrupted the turn — pausing auto-mode.`
|
|
599
|
+
: `Tool invocation failed for ${s.currentUnit.type}: ${s.lastToolInvocationError}. Structured argument generation failed — pausing auto-mode.`;
|
|
585
600
|
debugLog("postUnit", { phase: "tool-invocation-error-pause", unitType: s.currentUnit.type, unitId: s.currentUnit.id, error: s.lastToolInvocationError });
|
|
586
601
|
ctx.ui.notify(errMsg, "error");
|
|
587
602
|
s.lastToolInvocationError = null;
|
|
@@ -772,6 +787,123 @@ export async function postUnitPostVerification(pctx: PostUnitContext): Promise<"
|
|
|
772
787
|
}
|
|
773
788
|
}
|
|
774
789
|
|
|
790
|
+
// ── Pre-execution checks (after plan-slice completes) ──
|
|
791
|
+
if (
|
|
792
|
+
s.currentUnit &&
|
|
793
|
+
s.currentUnit.type === "plan-slice"
|
|
794
|
+
) {
|
|
795
|
+
let preExecPauseNeeded = false;
|
|
796
|
+
await runSafely("postUnitPostVerification", "pre-execution-checks", async () => {
|
|
797
|
+
try {
|
|
798
|
+
// Check preferences — respect enhanced_verification and enhanced_verification_pre
|
|
799
|
+
const prefs = loadEffectiveGSDPreferences()?.preferences;
|
|
800
|
+
const enhancedEnabled = prefs?.enhanced_verification !== false; // default true
|
|
801
|
+
const preEnabled = prefs?.enhanced_verification_pre !== false; // default true
|
|
802
|
+
|
|
803
|
+
if (!enhancedEnabled || !preEnabled) {
|
|
804
|
+
debugLog("postUnitPostVerification", {
|
|
805
|
+
phase: "pre-execution-checks",
|
|
806
|
+
skipped: true,
|
|
807
|
+
reason: "disabled by preferences",
|
|
808
|
+
});
|
|
809
|
+
return;
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
// Parse the unit ID to get milestone/slice IDs
|
|
813
|
+
const { milestone: mid, slice: sid } = parseUnitId(s.currentUnit!.id);
|
|
814
|
+
if (!mid || !sid) {
|
|
815
|
+
debugLog("postUnitPostVerification", {
|
|
816
|
+
phase: "pre-execution-checks",
|
|
817
|
+
skipped: true,
|
|
818
|
+
reason: "could not parse milestone/slice from unit ID",
|
|
819
|
+
});
|
|
820
|
+
return;
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
// Get tasks for this slice from DB
|
|
824
|
+
const tasks = getSliceTasks(mid, sid);
|
|
825
|
+
if (tasks.length === 0) {
|
|
826
|
+
debugLog("postUnitPostVerification", {
|
|
827
|
+
phase: "pre-execution-checks",
|
|
828
|
+
skipped: true,
|
|
829
|
+
reason: "no tasks found for slice",
|
|
830
|
+
});
|
|
831
|
+
return;
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
// Run pre-execution checks
|
|
835
|
+
const result: PreExecutionResult = await runPreExecutionChecks(tasks, s.basePath);
|
|
836
|
+
|
|
837
|
+
// Log summary to stderr in existing verification output format
|
|
838
|
+
const emoji = result.status === "pass" ? "✅" : result.status === "warn" ? "⚠️" : "❌";
|
|
839
|
+
process.stderr.write(
|
|
840
|
+
`gsd-pre-exec: ${emoji} Pre-execution checks ${result.status} for ${mid}/${sid} (${result.durationMs}ms)\n`,
|
|
841
|
+
);
|
|
842
|
+
|
|
843
|
+
// Log individual check results
|
|
844
|
+
for (const check of result.checks) {
|
|
845
|
+
const checkEmoji = check.passed ? "✓" : check.blocking ? "✗" : "⚠";
|
|
846
|
+
process.stderr.write(
|
|
847
|
+
`gsd-pre-exec: ${checkEmoji} [${check.category}] ${check.target}: ${check.message}\n`,
|
|
848
|
+
);
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
// Write evidence JSON to slice artifacts directory
|
|
852
|
+
const slicePath = resolveSlicePath(s.basePath, mid, sid);
|
|
853
|
+
if (slicePath) {
|
|
854
|
+
writePreExecutionEvidence(result, slicePath, mid, sid);
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
// Notify UI
|
|
858
|
+
if (result.status === "fail") {
|
|
859
|
+
const blockingCount = result.checks.filter(c => !c.passed && c.blocking).length;
|
|
860
|
+
ctx.ui.notify(
|
|
861
|
+
`Pre-execution checks failed: ${blockingCount} blocking issue${blockingCount === 1 ? "" : "s"} found`,
|
|
862
|
+
"error",
|
|
863
|
+
);
|
|
864
|
+
preExecPauseNeeded = true;
|
|
865
|
+
} else if (result.status === "warn") {
|
|
866
|
+
ctx.ui.notify(
|
|
867
|
+
`Pre-execution checks passed with warnings`,
|
|
868
|
+
"warning",
|
|
869
|
+
);
|
|
870
|
+
// Strict mode: treat warnings as blocking
|
|
871
|
+
if (prefs?.enhanced_verification_strict === true) {
|
|
872
|
+
preExecPauseNeeded = true;
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
debugLog("postUnitPostVerification", {
|
|
877
|
+
phase: "pre-execution-checks",
|
|
878
|
+
status: result.status,
|
|
879
|
+
checkCount: result.checks.length,
|
|
880
|
+
durationMs: result.durationMs,
|
|
881
|
+
});
|
|
882
|
+
} catch (preExecError) {
|
|
883
|
+
// Fail-closed: if runPreExecutionChecks throws, pause auto-mode instead of silently continuing
|
|
884
|
+
const errorMessage = preExecError instanceof Error ? preExecError.message : String(preExecError);
|
|
885
|
+
debugLog("postUnitPostVerification", {
|
|
886
|
+
phase: "pre-execution-checks",
|
|
887
|
+
error: errorMessage,
|
|
888
|
+
failClosed: true,
|
|
889
|
+
});
|
|
890
|
+
logError("engine", `gsd-pre-exec: Pre-execution checks threw an error: ${errorMessage}`);
|
|
891
|
+
ctx.ui.notify(
|
|
892
|
+
`Pre-execution checks error: ${errorMessage} — pausing for human review`,
|
|
893
|
+
"error",
|
|
894
|
+
);
|
|
895
|
+
preExecPauseNeeded = true;
|
|
896
|
+
}
|
|
897
|
+
});
|
|
898
|
+
|
|
899
|
+
// Check for blocking failures after runSafely completes
|
|
900
|
+
if (preExecPauseNeeded) {
|
|
901
|
+
debugLog("postUnitPostVerification", { phase: "pre-execution-checks", pausing: true, reason: "blocking failures detected" });
|
|
902
|
+
await pauseAuto(ctx, pi);
|
|
903
|
+
return "stopped";
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
|
|
775
907
|
// ── Triage check ──
|
|
776
908
|
if (
|
|
777
909
|
!s.stepMode &&
|
|
@@ -858,6 +858,7 @@ export async function buildDiscussMilestonePrompt(mid: string, midTitle: string,
|
|
|
858
858
|
inlinedTemplates: discussTemplates,
|
|
859
859
|
structuredQuestionsAvailable: "true",
|
|
860
860
|
commitInstruction: "Do not commit planning artifacts — .gsd/ is managed externally.",
|
|
861
|
+
fastPathInstruction: "",
|
|
861
862
|
});
|
|
862
863
|
|
|
863
864
|
// If a CONTEXT-DRAFT.md exists, append it as seed material
|
|
@@ -1801,6 +1802,36 @@ const GATE_QUESTIONS: Record<string, { question: string; guidance: string }> = {
|
|
|
1801
1802
|
},
|
|
1802
1803
|
};
|
|
1803
1804
|
|
|
1805
|
+
export async function buildParallelResearchSlicesPrompt(
|
|
1806
|
+
mid: string,
|
|
1807
|
+
midTitle: string,
|
|
1808
|
+
slices: Array<{ id: string; title: string }>,
|
|
1809
|
+
basePath: string,
|
|
1810
|
+
): Promise<string> {
|
|
1811
|
+
// Build individual research-slice prompts for each slice
|
|
1812
|
+
const subagentSections: string[] = [];
|
|
1813
|
+
for (const slice of slices) {
|
|
1814
|
+
const slicePrompt = await buildResearchSlicePrompt(mid, midTitle, slice.id, slice.title, basePath);
|
|
1815
|
+
subagentSections.push([
|
|
1816
|
+
`### ${slice.id}: ${slice.title}`,
|
|
1817
|
+
"",
|
|
1818
|
+
"Use this as the prompt for a `subagent` call (agent: `gsd-executor` or the default agent):",
|
|
1819
|
+
"",
|
|
1820
|
+
"```",
|
|
1821
|
+
slicePrompt,
|
|
1822
|
+
"```",
|
|
1823
|
+
].join("\n"));
|
|
1824
|
+
}
|
|
1825
|
+
|
|
1826
|
+
return loadPrompt("parallel-research-slices", {
|
|
1827
|
+
mid,
|
|
1828
|
+
midTitle,
|
|
1829
|
+
sliceCount: String(slices.length),
|
|
1830
|
+
sliceList: slices.map((s) => `- **${s.id}**: ${s.title}`).join("\n"),
|
|
1831
|
+
subagentPrompts: subagentSections.join("\n\n---\n\n"),
|
|
1832
|
+
});
|
|
1833
|
+
}
|
|
1834
|
+
|
|
1804
1835
|
export async function buildGateEvaluatePrompt(
|
|
1805
1836
|
mid: string, midTitle: string, sid: string, sTitle: string,
|
|
1806
1837
|
base: string,
|
|
@@ -286,7 +286,7 @@ export function verifyExpectedArtifact(
|
|
|
286
286
|
if (!hasCheckboxTask && !hasHeadingTask) return false;
|
|
287
287
|
}
|
|
288
288
|
|
|
289
|
-
// execute-task: DB status is authoritative. Fall back to
|
|
289
|
+
// execute-task: DB status is authoritative. Fall back to checked-checkbox
|
|
290
290
|
// detection when the DB is unavailable (unmigrated projects).
|
|
291
291
|
if (unitType === "execute-task") {
|
|
292
292
|
const { milestone: mid, slice: sid, task: tid } = parseUnitId(unitId);
|
|
@@ -297,20 +297,22 @@ export function verifyExpectedArtifact(
|
|
|
297
297
|
if (dbTask.status !== "complete" && dbTask.status !== "done") return false;
|
|
298
298
|
} else if (!isDbAvailable()) {
|
|
299
299
|
// LEGACY: Pre-migration fallback for projects without DB.
|
|
300
|
-
//
|
|
301
|
-
//
|
|
302
|
-
//
|
|
300
|
+
// Require a CHECKED checkbox — a bare heading or unchecked checkbox
|
|
301
|
+
// does not prove gsd_complete_task ran. Summary file on disk alone
|
|
302
|
+
// is not sufficient evidence (could be a rogue write) (#3607).
|
|
303
303
|
const planAbs = resolveSliceFile(base, mid, sid, "PLAN");
|
|
304
304
|
if (planAbs && existsSync(planAbs)) {
|
|
305
305
|
const planContent = readFileSync(planAbs, "utf-8");
|
|
306
306
|
const escapedTid = tid.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
307
|
-
const hdRe = new RegExp(`^#{2,4}\\s+${escapedTid}\\s*(?:--|—|:)`, "m");
|
|
308
307
|
const cbRe = new RegExp(`^- \\[[xX]\\] \\*\\*${escapedTid}:`, "m");
|
|
309
|
-
if (!
|
|
308
|
+
if (!cbRe.test(planContent)) return false;
|
|
309
|
+
} else {
|
|
310
|
+
return false; // no plan file → cannot verify
|
|
310
311
|
}
|
|
312
|
+
} else {
|
|
313
|
+
// DB available but task row not found — completion tool never ran (#3607)
|
|
314
|
+
return false;
|
|
311
315
|
}
|
|
312
|
-
// else: DB available but task not found — summary file exists (checked above),
|
|
313
|
-
// so treat as verified (task may not be imported yet)
|
|
314
316
|
}
|
|
315
317
|
}
|
|
316
318
|
|
|
@@ -44,6 +44,9 @@ import {
|
|
|
44
44
|
nativeInit,
|
|
45
45
|
nativeAddAll,
|
|
46
46
|
nativeCommit,
|
|
47
|
+
nativeGetCurrentBranch,
|
|
48
|
+
nativeDetectMainBranch,
|
|
49
|
+
nativeCheckoutBranch,
|
|
47
50
|
} from "./native-git-bridge.js";
|
|
48
51
|
import { GitServiceImpl } from "./git-service.js";
|
|
49
52
|
import {
|
|
@@ -528,6 +531,22 @@ export async function bootstrapAutoSession(
|
|
|
528
531
|
setActiveMilestoneId(base, s.currentMilestoneId);
|
|
529
532
|
}
|
|
530
533
|
|
|
534
|
+
// Guard against stale milestone branch when isolation:none (#3613).
|
|
535
|
+
// A prior session with isolation:branch/worktree may have left HEAD on
|
|
536
|
+
// milestone/<MID>. Auto-checkout back to the integration branch.
|
|
537
|
+
if (getIsolationMode() === "none" && nativeIsRepo(base)) {
|
|
538
|
+
try {
|
|
539
|
+
const currentBranch = nativeGetCurrentBranch(base);
|
|
540
|
+
if (currentBranch.startsWith("milestone/")) {
|
|
541
|
+
const integrationBranch = nativeDetectMainBranch(base);
|
|
542
|
+
nativeCheckoutBranch(base, integrationBranch);
|
|
543
|
+
logWarning("bootstrap", `Returned to "${integrationBranch}" — HEAD was on stale milestone branch "${currentBranch}" (isolation: none does not use milestone branches).`);
|
|
544
|
+
}
|
|
545
|
+
} catch (err) {
|
|
546
|
+
logWarning("bootstrap", `Could not auto-checkout from stale milestone branch: ${err instanceof Error ? err.message : String(err)}`);
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
|
|
531
550
|
// ── Auto-worktree setup ──
|
|
532
551
|
s.originalBasePath = base;
|
|
533
552
|
|
|
@@ -614,6 +633,25 @@ export async function bootstrapAutoSession(
|
|
|
614
633
|
};
|
|
615
634
|
}
|
|
616
635
|
|
|
636
|
+
// Apply worker model override from parallel orchestrator (#worker-model).
|
|
637
|
+
// GSD_WORKER_MODEL is injected by the coordinator when parallel.worker_model
|
|
638
|
+
// is configured, so parallel milestone workers use a cheaper model than the
|
|
639
|
+
// coordinator session (e.g. Haiku for execution, Sonnet for planning).
|
|
640
|
+
const workerModelOverride = process.env.GSD_WORKER_MODEL;
|
|
641
|
+
if (workerModelOverride && process.env.GSD_PARALLEL_WORKER === "1") {
|
|
642
|
+
const availableModels = ctx.modelRegistry.getAvailable();
|
|
643
|
+
const { resolveModelId } = await import("./auto-model-selection.js");
|
|
644
|
+
const overrideModel = resolveModelId(workerModelOverride, availableModels, ctx.model?.provider);
|
|
645
|
+
if (overrideModel) {
|
|
646
|
+
const ok = await pi.setModel(overrideModel, { persist: false });
|
|
647
|
+
if (ok) {
|
|
648
|
+
// Update start model so all subsequent units use this as the baseline
|
|
649
|
+
s.autoModeStartModel = { provider: overrideModel.provider, id: overrideModel.id };
|
|
650
|
+
ctx.ui.notify(`Worker model override: ${overrideModel.provider}/${overrideModel.id}`, "info");
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
|
|
617
655
|
// Snapshot installed skills
|
|
618
656
|
if (resolveSkillDiscoveryMode() !== "off") {
|
|
619
657
|
snapshotSkills();
|
|
@@ -102,3 +102,13 @@ export function isToolInvocationError(errorMsg: string): boolean {
|
|
|
102
102
|
if (!errorMsg) return false;
|
|
103
103
|
return TOOL_INVOCATION_ERROR_RE.test(errorMsg);
|
|
104
104
|
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Returns true if the error message indicates the tool was skipped because
|
|
108
|
+
* a queued user message interrupted the turn (#3595). Retrying will produce
|
|
109
|
+
* the same skip, so the unit should be paused rather than retried.
|
|
110
|
+
*/
|
|
111
|
+
export function isQueuedUserMessageSkip(errorMsg: string): boolean {
|
|
112
|
+
if (!errorMsg) return false;
|
|
113
|
+
return /^Skipped due to queued user message\.?$/i.test(errorMsg.trim());
|
|
114
|
+
}
|
|
@@ -11,9 +11,10 @@
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
import type { ExtensionContext, ExtensionAPI } from "@gsd/pi-coding-agent";
|
|
14
|
+
import { mkdirSync, writeFileSync } from "node:fs";
|
|
14
15
|
import { resolveSliceFile, resolveSlicePath } from "./paths.js";
|
|
15
16
|
import { parseUnitId } from "./unit-id.js";
|
|
16
|
-
import { isDbAvailable, getTask } from "./gsd-db.js";
|
|
17
|
+
import { isDbAvailable, getTask, getSliceTasks, type TaskRow } from "./gsd-db.js";
|
|
17
18
|
import { loadEffectiveGSDPreferences } from "./preferences.js";
|
|
18
19
|
import {
|
|
19
20
|
runVerificationGate,
|
|
@@ -21,9 +22,11 @@ import {
|
|
|
21
22
|
captureRuntimeErrors,
|
|
22
23
|
runDependencyAudit,
|
|
23
24
|
} from "./verification-gate.js";
|
|
24
|
-
import { writeVerificationJSON } from "./verification-evidence.js";
|
|
25
|
+
import { writeVerificationJSON, type PostExecutionCheckJSON, type EvidenceJSON } from "./verification-evidence.js";
|
|
25
26
|
import { logWarning } from "./workflow-logger.js";
|
|
27
|
+
import { runPostExecutionChecks, type PostExecutionResult } from "./post-execution-checks.js";
|
|
26
28
|
import type { AutoSession } from "./auto/session.js";
|
|
29
|
+
import type { VerificationResult as VerificationGateResult } from "./types.js";
|
|
27
30
|
import { join } from "node:path";
|
|
28
31
|
|
|
29
32
|
export interface VerificationContext {
|
|
@@ -183,11 +186,140 @@ export async function runPostUnitVerification(
|
|
|
183
186
|
return "continue";
|
|
184
187
|
}
|
|
185
188
|
|
|
189
|
+
// ── Post-execution checks (run after main verification passes for execute-task units) ──
|
|
190
|
+
let postExecChecks: PostExecutionCheckJSON[] | undefined;
|
|
191
|
+
let postExecBlockingFailure = false;
|
|
192
|
+
|
|
193
|
+
if (result.passed && mid && sid && tid) {
|
|
194
|
+
// Check preferences — respect enhanced_verification and enhanced_verification_post
|
|
195
|
+
const enhancedEnabled = prefs?.enhanced_verification !== false; // default true
|
|
196
|
+
const postEnabled = prefs?.enhanced_verification_post !== false; // default true
|
|
197
|
+
|
|
198
|
+
if (enhancedEnabled && postEnabled && isDbAvailable()) {
|
|
199
|
+
try {
|
|
200
|
+
// Get the completed task from DB
|
|
201
|
+
const taskRow = getTask(mid, sid, tid);
|
|
202
|
+
if (taskRow && taskRow.key_files && taskRow.key_files.length > 0) {
|
|
203
|
+
// Get all tasks in the slice
|
|
204
|
+
const allTasks = getSliceTasks(mid, sid);
|
|
205
|
+
// Filter to prior completed tasks (status = 'complete' or 'done', before current task)
|
|
206
|
+
const priorTasks = allTasks.filter(
|
|
207
|
+
(t: TaskRow) =>
|
|
208
|
+
(t.status === "complete" || t.status === "done") &&
|
|
209
|
+
t.id !== tid &&
|
|
210
|
+
t.sequence < taskRow.sequence
|
|
211
|
+
);
|
|
212
|
+
|
|
213
|
+
// Run post-execution checks
|
|
214
|
+
const postExecResult: PostExecutionResult = runPostExecutionChecks(
|
|
215
|
+
taskRow,
|
|
216
|
+
priorTasks,
|
|
217
|
+
s.basePath
|
|
218
|
+
);
|
|
219
|
+
|
|
220
|
+
// Store checks for evidence JSON
|
|
221
|
+
postExecChecks = postExecResult.checks;
|
|
222
|
+
|
|
223
|
+
// Log summary to stderr with gsd-post-exec: prefix
|
|
224
|
+
const emoji =
|
|
225
|
+
postExecResult.status === "pass"
|
|
226
|
+
? "✅"
|
|
227
|
+
: postExecResult.status === "warn"
|
|
228
|
+
? "⚠️"
|
|
229
|
+
: "❌";
|
|
230
|
+
process.stderr.write(
|
|
231
|
+
`gsd-post-exec: ${emoji} Post-execution checks ${postExecResult.status} for ${mid}/${sid}/${tid} (${postExecResult.durationMs}ms)\n`
|
|
232
|
+
);
|
|
233
|
+
|
|
234
|
+
// Log individual check results
|
|
235
|
+
for (const check of postExecResult.checks) {
|
|
236
|
+
const checkEmoji = check.passed
|
|
237
|
+
? "✓"
|
|
238
|
+
: check.blocking
|
|
239
|
+
? "✗"
|
|
240
|
+
: "⚠";
|
|
241
|
+
process.stderr.write(
|
|
242
|
+
`gsd-post-exec: ${checkEmoji} [${check.category}] ${check.target}: ${check.message}\n`
|
|
243
|
+
);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// Check for blocking failures
|
|
247
|
+
if (postExecResult.status === "fail") {
|
|
248
|
+
postExecBlockingFailure = true;
|
|
249
|
+
const blockingCount = postExecResult.checks.filter(
|
|
250
|
+
(c) => !c.passed && c.blocking
|
|
251
|
+
).length;
|
|
252
|
+
ctx.ui.notify(
|
|
253
|
+
`Post-execution checks failed: ${blockingCount} blocking issue${blockingCount === 1 ? "" : "s"} found`,
|
|
254
|
+
"error"
|
|
255
|
+
);
|
|
256
|
+
} else if (postExecResult.status === "warn") {
|
|
257
|
+
ctx.ui.notify(
|
|
258
|
+
`Post-execution checks passed with warnings`,
|
|
259
|
+
"warning"
|
|
260
|
+
);
|
|
261
|
+
// Strict mode: treat warnings as blocking
|
|
262
|
+
if (prefs?.enhanced_verification_strict === true) {
|
|
263
|
+
postExecBlockingFailure = true;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
} catch (postExecErr) {
|
|
268
|
+
// Post-execution check errors are non-fatal — log and continue
|
|
269
|
+
logWarning("engine", `gsd-post-exec: error — ${(postExecErr as Error).message}`);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// Re-write verification evidence JSON with post-execution checks
|
|
275
|
+
if (postExecChecks && postExecChecks.length > 0 && mid && sid && tid) {
|
|
276
|
+
try {
|
|
277
|
+
const sDir = resolveSlicePath(s.basePath, mid, sid);
|
|
278
|
+
if (sDir) {
|
|
279
|
+
const tasksDir = join(sDir, "tasks");
|
|
280
|
+
// Add postExecutionChecks to the result for the JSON write
|
|
281
|
+
const resultWithPostExec = {
|
|
282
|
+
...result,
|
|
283
|
+
// Mark as failed if there was a blocking post-exec failure
|
|
284
|
+
passed: result.passed && !postExecBlockingFailure,
|
|
285
|
+
};
|
|
286
|
+
// Manually write with postExecutionChecks field
|
|
287
|
+
writeVerificationJSONWithPostExec(
|
|
288
|
+
resultWithPostExec,
|
|
289
|
+
tasksDir,
|
|
290
|
+
tid,
|
|
291
|
+
s.currentUnit.id,
|
|
292
|
+
postExecChecks,
|
|
293
|
+
postExecBlockingFailure ? attempt + 1 : undefined,
|
|
294
|
+
postExecBlockingFailure ? maxRetries : undefined
|
|
295
|
+
);
|
|
296
|
+
}
|
|
297
|
+
} catch (evidenceErr) {
|
|
298
|
+
logWarning("engine", `verification-evidence: post-exec write error — ${(evidenceErr as Error).message}`);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// Update result.passed based on post-execution checks
|
|
303
|
+
if (postExecBlockingFailure) {
|
|
304
|
+
result.passed = false;
|
|
305
|
+
}
|
|
306
|
+
|
|
186
307
|
// ── Auto-fix retry logic ──
|
|
187
308
|
if (result.passed) {
|
|
188
309
|
s.verificationRetryCount.delete(s.currentUnit.id);
|
|
189
310
|
s.pendingVerificationRetry = null;
|
|
190
311
|
return "continue";
|
|
312
|
+
} else if (postExecBlockingFailure) {
|
|
313
|
+
// Post-execution failures are cross-task consistency issues — retrying the same task won't fix them.
|
|
314
|
+
// Skip retry and pause immediately for human review.
|
|
315
|
+
s.verificationRetryCount.delete(s.currentUnit.id);
|
|
316
|
+
s.pendingVerificationRetry = null;
|
|
317
|
+
ctx.ui.notify(
|
|
318
|
+
`Post-execution checks failed — cross-task consistency issue detected, pausing for human review`,
|
|
319
|
+
"error",
|
|
320
|
+
);
|
|
321
|
+
await pauseAuto(ctx, pi);
|
|
322
|
+
return "pause";
|
|
191
323
|
} else if (autoFixEnabled && attempt + 1 <= maxRetries) {
|
|
192
324
|
const nextAttempt = attempt + 1;
|
|
193
325
|
s.verificationRetryCount.set(s.currentUnit.id, nextAttempt);
|
|
@@ -231,3 +363,59 @@ export async function runPostUnitVerification(
|
|
|
231
363
|
return "continue";
|
|
232
364
|
}
|
|
233
365
|
}
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* Write verification evidence JSON with post-execution checks included.
|
|
369
|
+
* This is a variant of writeVerificationJSON that adds the postExecutionChecks field.
|
|
370
|
+
*/
|
|
371
|
+
function writeVerificationJSONWithPostExec(
|
|
372
|
+
result: VerificationGateResult,
|
|
373
|
+
tasksDir: string,
|
|
374
|
+
taskId: string,
|
|
375
|
+
unitId: string,
|
|
376
|
+
postExecutionChecks: PostExecutionCheckJSON[],
|
|
377
|
+
retryAttempt?: number,
|
|
378
|
+
maxRetries?: number,
|
|
379
|
+
): void {
|
|
380
|
+
mkdirSync(tasksDir, { recursive: true });
|
|
381
|
+
|
|
382
|
+
const evidence: EvidenceJSON = {
|
|
383
|
+
schemaVersion: 1,
|
|
384
|
+
taskId,
|
|
385
|
+
unitId: unitId ?? taskId,
|
|
386
|
+
timestamp: result.timestamp,
|
|
387
|
+
passed: result.passed,
|
|
388
|
+
discoverySource: result.discoverySource,
|
|
389
|
+
checks: result.checks.map((check) => ({
|
|
390
|
+
command: check.command,
|
|
391
|
+
exitCode: check.exitCode,
|
|
392
|
+
durationMs: check.durationMs,
|
|
393
|
+
verdict: check.exitCode === 0 ? "pass" : "fail",
|
|
394
|
+
})),
|
|
395
|
+
...(retryAttempt !== undefined ? { retryAttempt } : {}),
|
|
396
|
+
...(maxRetries !== undefined ? { maxRetries } : {}),
|
|
397
|
+
postExecutionChecks,
|
|
398
|
+
};
|
|
399
|
+
|
|
400
|
+
if (result.runtimeErrors && result.runtimeErrors.length > 0) {
|
|
401
|
+
evidence.runtimeErrors = result.runtimeErrors.map(e => ({
|
|
402
|
+
source: e.source,
|
|
403
|
+
severity: e.severity,
|
|
404
|
+
message: e.message,
|
|
405
|
+
blocking: e.blocking,
|
|
406
|
+
}));
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
if (result.auditWarnings && result.auditWarnings.length > 0) {
|
|
410
|
+
evidence.auditWarnings = result.auditWarnings.map(w => ({
|
|
411
|
+
name: w.name,
|
|
412
|
+
severity: w.severity,
|
|
413
|
+
title: w.title,
|
|
414
|
+
url: w.url,
|
|
415
|
+
fixAvailable: w.fixAvailable,
|
|
416
|
+
}));
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
const filePath = join(tasksDir, `${taskId}-VERIFY.json`);
|
|
420
|
+
writeFileSync(filePath, JSON.stringify(evidence, null, 2) + "\n", "utf-8");
|
|
421
|
+
}
|
|
@@ -188,8 +188,10 @@ function clearProjectRootStateFiles(basePath: string, milestoneId: string): void
|
|
|
188
188
|
try {
|
|
189
189
|
unlinkSync(file);
|
|
190
190
|
} catch (err) {
|
|
191
|
-
|
|
192
|
-
|
|
191
|
+
// ENOENT is expected — file may not exist (#3597)
|
|
192
|
+
if ((err as NodeJS.ErrnoException).code !== "ENOENT") {
|
|
193
|
+
logWarning("worktree", `file unlink failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
194
|
+
}
|
|
193
195
|
}
|
|
194
196
|
}
|
|
195
197
|
|
|
@@ -218,8 +220,11 @@ function clearProjectRootStateFiles(basePath: string, milestoneId: string): void
|
|
|
218
220
|
try {
|
|
219
221
|
unlinkSync(join(basePath, f));
|
|
220
222
|
} catch (err) {
|
|
221
|
-
|
|
222
|
-
|
|
223
|
+
// ENOENT/EISDIR are expected for already-removed or directory entries (#3597)
|
|
224
|
+
const code = (err as NodeJS.ErrnoException).code;
|
|
225
|
+
if (code !== "ENOENT" && code !== "EISDIR") {
|
|
226
|
+
logWarning("worktree", `untracked file unlink failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
227
|
+
}
|
|
223
228
|
}
|
|
224
229
|
}
|
|
225
230
|
}
|
|
@@ -770,6 +775,9 @@ export function syncWorktreeStateBack(
|
|
|
770
775
|
.map((d) => d.name);
|
|
771
776
|
|
|
772
777
|
for (const mid of wtMilestones) {
|
|
778
|
+
// Skip the current milestone being merged — its files are already in the
|
|
779
|
+
// milestone branch and would conflict with the squash merge (#3641).
|
|
780
|
+
if (mid === milestoneId) continue;
|
|
773
781
|
syncMilestoneDir(wtGsd, mainGsd, mid, synced);
|
|
774
782
|
}
|
|
775
783
|
} catch (err) {
|
|
@@ -1049,12 +1057,20 @@ export function createAutoWorktree(
|
|
|
1049
1057
|
reuseExistingBranch: true,
|
|
1050
1058
|
});
|
|
1051
1059
|
} else {
|
|
1052
|
-
// Fresh start — create branch from integration branch
|
|
1060
|
+
// Fresh start — create branch from integration branch.
|
|
1061
|
+
// Use the same 3-tier fallback as mergeMilestoneToMain (#3461):
|
|
1062
|
+
// 1. META.json integration branch (explicit per-milestone override)
|
|
1063
|
+
// 2. git.main_branch preference (user's configured working branch)
|
|
1064
|
+
// 3. nativeDetectMainBranch (origin/HEAD auto-detection)
|
|
1065
|
+
// Without tier 2, projects with main_branch=dev but origin/HEAD→master
|
|
1066
|
+
// would fork worktrees from the wrong (stale) branch.
|
|
1053
1067
|
const integrationBranch =
|
|
1054
1068
|
readIntegrationBranch(basePath, milestoneId) ?? undefined;
|
|
1069
|
+
const gitPrefs = loadEffectiveGSDPreferences()?.preferences?.git;
|
|
1070
|
+
const startPoint = integrationBranch ?? gitPrefs?.main_branch ?? undefined;
|
|
1055
1071
|
info = createWorktree(basePath, milestoneId, {
|
|
1056
1072
|
branch,
|
|
1057
|
-
startPoint
|
|
1073
|
+
startPoint,
|
|
1058
1074
|
});
|
|
1059
1075
|
}
|
|
1060
1076
|
|
|
@@ -1453,8 +1469,13 @@ export function mergeMilestoneToMain(
|
|
|
1453
1469
|
originalBasePath_,
|
|
1454
1470
|
milestoneId,
|
|
1455
1471
|
);
|
|
1472
|
+
// Validate prefs.main_branch exists before using it — a stale preference
|
|
1473
|
+
// (e.g. "master" when repo uses "main") causes merge failure (#3589).
|
|
1474
|
+
const validatedPrefBranch = prefs.main_branch && nativeBranchExists(originalBasePath_, prefs.main_branch)
|
|
1475
|
+
? prefs.main_branch
|
|
1476
|
+
: undefined;
|
|
1456
1477
|
const mainBranch =
|
|
1457
|
-
integrationBranch ??
|
|
1478
|
+
integrationBranch ?? validatedPrefBranch ?? nativeDetectMainBranch(originalBasePath_);
|
|
1458
1479
|
|
|
1459
1480
|
// Remove transient project-root state files before any branch or merge
|
|
1460
1481
|
// operation. Untracked milestone metadata can otherwise block squash merges.
|
|
@@ -76,6 +76,7 @@ import {
|
|
|
76
76
|
hasInteractiveToolInFlight,
|
|
77
77
|
clearInFlightTools,
|
|
78
78
|
isToolInvocationError,
|
|
79
|
+
isQueuedUserMessageSkip,
|
|
79
80
|
} from "./auto-tool-tracking.js";
|
|
80
81
|
import { closeoutUnit } from "./auto-unit-closeout.js";
|
|
81
82
|
import { recoverTimedOutUnit } from "./auto-timeout-recovery.js";
|
|
@@ -397,7 +398,7 @@ export function markToolEnd(toolCallId: string): void {
|
|
|
397
398
|
*/
|
|
398
399
|
export function recordToolInvocationError(toolName: string, errorMsg: string): void {
|
|
399
400
|
if (!s.active) return;
|
|
400
|
-
if (isToolInvocationError(errorMsg)) {
|
|
401
|
+
if (isToolInvocationError(errorMsg) || isQueuedUserMessageSkip(errorMsg)) {
|
|
401
402
|
s.lastToolInvocationError = `${toolName}: ${errorMsg}`;
|
|
402
403
|
}
|
|
403
404
|
}
|