gsd-pi 2.48.0 → 2.49.0-dev.9e177e9
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-ui.js +12 -2
- package/dist/headless.js +29 -13
- package/dist/resources/extensions/gsd/auto/infra-errors.js +1 -0
- package/dist/resources/extensions/gsd/auto/phases.js +11 -11
- package/dist/resources/extensions/gsd/auto/resolve.js +2 -2
- package/dist/resources/extensions/gsd/auto/run-unit.js +2 -2
- package/dist/resources/extensions/gsd/auto/session.js +4 -0
- package/dist/resources/extensions/gsd/auto-artifact-paths.js +8 -10
- package/dist/resources/extensions/gsd/auto-dashboard.js +6 -3
- package/dist/resources/extensions/gsd/auto-dispatch.js +34 -7
- package/dist/resources/extensions/gsd/auto-post-unit.js +34 -27
- package/dist/resources/extensions/gsd/auto-prompts.js +102 -21
- package/dist/resources/extensions/gsd/auto-recovery.js +62 -184
- package/dist/resources/extensions/gsd/auto-start.js +4 -31
- package/dist/resources/extensions/gsd/auto-timers.js +2 -2
- package/dist/resources/extensions/gsd/auto-verification.js +4 -7
- package/dist/resources/extensions/gsd/auto-worktree.js +262 -115
- package/dist/resources/extensions/gsd/auto.js +7 -5
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +89 -0
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +8 -1
- package/dist/resources/extensions/gsd/branch-patterns.js +13 -0
- package/dist/resources/extensions/gsd/commands/handlers/auto.js +43 -3
- package/dist/resources/extensions/gsd/doctor-checks.js +5 -1234
- package/dist/resources/extensions/gsd/doctor-engine-checks.js +168 -0
- package/dist/resources/extensions/gsd/doctor-environment.js +28 -7
- package/dist/resources/extensions/gsd/doctor-git-checks.js +405 -0
- package/dist/resources/extensions/gsd/doctor-global-checks.js +74 -0
- package/dist/resources/extensions/gsd/doctor-runtime-checks.js +600 -0
- package/dist/resources/extensions/gsd/doctor.js +9 -1
- package/dist/resources/extensions/gsd/extension-manifest.json +1 -1
- package/dist/resources/extensions/gsd/git-service.js +20 -20
- package/dist/resources/extensions/gsd/gsd-db.js +124 -1
- package/dist/resources/extensions/gsd/guided-flow-queue.js +10 -11
- package/dist/resources/extensions/gsd/markdown-renderer.js +33 -5
- package/dist/resources/extensions/gsd/preferences-types.js +2 -1
- package/dist/resources/extensions/gsd/preferences-validation.js +39 -0
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +27 -8
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +9 -8
- package/dist/resources/extensions/gsd/prompts/discuss-headless.md +223 -56
- package/dist/resources/extensions/gsd/prompts/execute-task.md +16 -13
- package/dist/resources/extensions/gsd/prompts/forensics.md +12 -5
- package/dist/resources/extensions/gsd/prompts/gate-evaluate.md +32 -0
- package/dist/resources/extensions/gsd/prompts/guided-complete-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/guided-execute-task.md +1 -1
- package/dist/resources/extensions/gsd/prompts/guided-plan-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/guided-plan-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +8 -3
- package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +3 -0
- package/dist/resources/extensions/gsd/prompts/replan-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/run-uat.md +4 -4
- package/dist/resources/extensions/gsd/repo-identity.js +29 -0
- package/dist/resources/extensions/gsd/roadmap-slices.js +2 -2
- package/dist/resources/extensions/gsd/session-forensics.js +6 -11
- package/dist/resources/extensions/gsd/session-lock.js +67 -56
- package/dist/resources/extensions/gsd/state.js +34 -7
- package/dist/resources/extensions/gsd/templates/milestone-summary.md +8 -0
- package/dist/resources/extensions/gsd/templates/plan.md +16 -0
- package/dist/resources/extensions/gsd/templates/roadmap.md +13 -0
- package/dist/resources/extensions/gsd/templates/slice-summary.md +9 -0
- package/dist/resources/extensions/gsd/templates/task-plan.md +24 -0
- package/dist/resources/extensions/gsd/tools/plan-slice.js +14 -1
- package/dist/resources/extensions/gsd/tools/validate-milestone.js +3 -3
- package/dist/resources/extensions/gsd/verdict-parser.js +84 -0
- package/dist/resources/extensions/gsd/worktree-command.js +1 -1
- package/dist/resources/extensions/gsd/worktree-resolver.js +24 -0
- package/dist/resources/extensions/gsd/worktree.js +3 -2
- package/dist/resources/extensions/remote-questions/config.js +3 -5
- package/dist/resources/extensions/search-the-web/native-search.js +8 -3
- package/dist/resources/extensions/search-the-web/tool-search.js +19 -2
- package/dist/resources/skills/github-workflows/references/gh/SKILL.md +22 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +17 -17
- package/dist/web/standalone/.next/build-manifest.json +4 -4
- 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/required-server-files.json +4 -4
- package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- 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/page.js +2 -2
- package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
- 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 +3 -3
- 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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +5 -5
- package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +4 -4
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
- 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 +3 -3
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/page.js +2 -2
- package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +17 -17
- package/dist/web/standalone/.next/server/chunks/229.js +2 -2
- package/dist/web/standalone/.next/server/chunks/471.js +3 -3
- 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/middleware.js +2 -2
- package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
- package/dist/web/standalone/.next/server/next-font-manifest.json +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/chunks/4024.7c75ac378de0f2b5.js +9 -0
- package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/page-6654a8cca61a3d1c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{webpack-0a4cd455ec4197d2.js → webpack-2473ce2c3879fff4.js} +1 -1
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
- package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
- package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
- package/dist/web/standalone/server.js +1 -1
- package/dist/worktree-cli.js +1 -1
- package/package.json +1 -1
- package/packages/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/agent-loop.js +4 -1
- package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/packages/pi-agent-core/src/agent-loop.ts +4 -1
- package/packages/pi-ai/dist/providers/openai-codex-responses.js +39 -10
- package/packages/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
- package/packages/pi-ai/src/providers/openai-codex-responses.ts +39 -8
- package/packages/pi-coding-agent/dist/core/blob-store.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/blob-store.js +8 -3
- package/packages/pi-coding-agent/dist/core/blob-store.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/discovery-cache.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/discovery-cache.js +9 -2
- package/packages/pi-coding-agent/dist/core/discovery-cache.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.js +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -1
- 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 +7 -32
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/jsonl.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/jsonl.js +5 -0
- package/packages/pi-coding-agent/dist/modes/rpc/jsonl.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.js +0 -1
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/blob-store.ts +6 -3
- package/packages/pi-coding-agent/src/core/discovery-cache.ts +9 -2
- package/packages/pi-coding-agent/src/core/retry-handler.ts +1 -1
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +7 -32
- package/packages/pi-coding-agent/src/modes/rpc/jsonl.ts +6 -0
- package/packages/pi-coding-agent/src/modes/rpc/rpc-client.ts +0 -2
- package/packages/pi-coding-agent/src/modes/rpc/rpc-mode.ts +2 -2
- package/pkg/package.json +1 -1
- package/src/resources/extensions/github-sync/tests/commit-linking.test.ts +8 -4
- package/src/resources/extensions/gsd/auto/infra-errors.ts +1 -0
- package/src/resources/extensions/gsd/auto/phases.ts +10 -11
- package/src/resources/extensions/gsd/auto/resolve.ts +3 -3
- package/src/resources/extensions/gsd/auto/run-unit.ts +2 -2
- package/src/resources/extensions/gsd/auto/session.ts +5 -0
- package/src/resources/extensions/gsd/auto/types.ts +13 -0
- package/src/resources/extensions/gsd/auto-artifact-paths.ts +19 -21
- package/src/resources/extensions/gsd/auto-dashboard.ts +5 -2
- package/src/resources/extensions/gsd/auto-dispatch.ts +40 -5
- package/src/resources/extensions/gsd/auto-loop.ts +1 -1
- package/src/resources/extensions/gsd/auto-post-unit.ts +36 -31
- package/src/resources/extensions/gsd/auto-prompts.ts +113 -19
- package/src/resources/extensions/gsd/auto-recovery.ts +65 -199
- package/src/resources/extensions/gsd/auto-start.ts +7 -27
- package/src/resources/extensions/gsd/auto-timers.ts +2 -2
- package/src/resources/extensions/gsd/auto-verification.ts +4 -7
- package/src/resources/extensions/gsd/auto-worktree.ts +309 -110
- package/src/resources/extensions/gsd/auto.ts +11 -10
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +93 -0
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +8 -0
- package/src/resources/extensions/gsd/branch-patterns.ts +16 -0
- package/src/resources/extensions/gsd/commands/handlers/auto.ts +46 -3
- package/src/resources/extensions/gsd/doctor-checks.ts +5 -1291
- package/src/resources/extensions/gsd/doctor-engine-checks.ts +182 -0
- package/src/resources/extensions/gsd/doctor-environment.ts +30 -7
- package/src/resources/extensions/gsd/doctor-git-checks.ts +415 -0
- package/src/resources/extensions/gsd/doctor-global-checks.ts +84 -0
- package/src/resources/extensions/gsd/doctor-runtime-checks.ts +626 -0
- package/src/resources/extensions/gsd/doctor.ts +9 -1
- package/src/resources/extensions/gsd/extension-manifest.json +1 -1
- package/src/resources/extensions/gsd/git-service.ts +19 -26
- package/src/resources/extensions/gsd/gsd-db.ts +150 -2
- package/src/resources/extensions/gsd/guided-flow-queue.ts +11 -12
- package/src/resources/extensions/gsd/markdown-renderer.ts +37 -4
- package/src/resources/extensions/gsd/preferences-types.ts +5 -1
- package/src/resources/extensions/gsd/preferences-validation.ts +37 -0
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +27 -8
- package/src/resources/extensions/gsd/prompts/complete-slice.md +9 -8
- package/src/resources/extensions/gsd/prompts/discuss-headless.md +223 -56
- package/src/resources/extensions/gsd/prompts/execute-task.md +16 -13
- package/src/resources/extensions/gsd/prompts/forensics.md +12 -5
- package/src/resources/extensions/gsd/prompts/gate-evaluate.md +32 -0
- package/src/resources/extensions/gsd/prompts/guided-complete-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/guided-execute-task.md +1 -1
- package/src/resources/extensions/gsd/prompts/guided-plan-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/guided-plan-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/plan-slice.md +8 -3
- package/src/resources/extensions/gsd/prompts/reassess-roadmap.md +3 -0
- package/src/resources/extensions/gsd/prompts/replan-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/run-uat.md +4 -4
- package/src/resources/extensions/gsd/repo-identity.ts +28 -0
- package/src/resources/extensions/gsd/roadmap-slices.ts +2 -2
- package/src/resources/extensions/gsd/session-forensics.ts +6 -11
- package/src/resources/extensions/gsd/session-lock.ts +92 -64
- package/src/resources/extensions/gsd/state.ts +38 -5
- package/src/resources/extensions/gsd/templates/milestone-summary.md +8 -0
- package/src/resources/extensions/gsd/templates/plan.md +16 -0
- package/src/resources/extensions/gsd/templates/roadmap.md +13 -0
- package/src/resources/extensions/gsd/templates/slice-summary.md +9 -0
- package/src/resources/extensions/gsd/templates/task-plan.md +24 -0
- package/src/resources/extensions/gsd/tests/agent-end-retry.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/all-milestones-complete-merge.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +35 -0
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +1 -81
- package/src/resources/extensions/gsd/tests/auto-stash-merge.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/auto-worktree-milestone-merge.test.ts +14 -12
- package/src/resources/extensions/gsd/tests/complete-slice.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/completed-units-metrics-sync.test.ts +9 -12
- package/src/resources/extensions/gsd/tests/doctor-environment.test.ts +115 -1
- package/src/resources/extensions/gsd/tests/doctor-fixlevel.test.ts +65 -1
- package/src/resources/extensions/gsd/tests/doctor-git.test.ts +50 -0
- package/src/resources/extensions/gsd/tests/feature-branch-lifecycle-integration.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/gate-dispatch.test.ts +189 -0
- package/src/resources/extensions/gsd/tests/gate-storage.test.ts +156 -0
- package/src/resources/extensions/gsd/tests/git-service.test.ts +68 -9
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/infra-error.test.ts +12 -2
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/md-importer.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/milestone-transition-worktree.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/parallel-merge.test.ts +6 -6
- package/src/resources/extensions/gsd/tests/quality-gates.test.ts +347 -0
- package/src/resources/extensions/gsd/tests/queue-completed-milestone-perf.test.ts +155 -0
- package/src/resources/extensions/gsd/tests/replan-slice.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +32 -0
- package/src/resources/extensions/gsd/tests/roadmap-slices.test.ts +26 -0
- package/src/resources/extensions/gsd/tests/run-uat.test.ts +87 -15
- package/src/resources/extensions/gsd/tests/session-lock-transient-read.test.ts +223 -0
- package/src/resources/extensions/gsd/tests/skill-activation.test.ts +44 -4
- package/src/resources/extensions/gsd/tests/tool-naming.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/verification-gate.test.ts +0 -16
- package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +67 -0
- package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-sync-overwrite-loop.test.ts +204 -0
- package/src/resources/extensions/gsd/tools/plan-slice.ts +16 -0
- package/src/resources/extensions/gsd/tools/validate-milestone.ts +3 -3
- package/src/resources/extensions/gsd/types.ts +30 -0
- package/src/resources/extensions/gsd/verdict-parser.ts +95 -0
- package/src/resources/extensions/gsd/verification-gate.ts +0 -2
- package/src/resources/extensions/gsd/worktree-command.ts +1 -1
- package/src/resources/extensions/gsd/worktree-resolver.ts +31 -0
- package/src/resources/extensions/gsd/worktree.ts +3 -2
- package/src/resources/extensions/remote-questions/config.ts +3 -5
- package/src/resources/extensions/search-the-web/native-search.ts +8 -3
- package/src/resources/extensions/search-the-web/tool-search.ts +22 -2
- package/src/resources/skills/github-workflows/references/gh/SKILL.md +22 -1
- package/dist/resources/extensions/gsd/auto-worktree-sync.js +0 -191
- package/dist/resources/extensions/gsd/resource-version.js +0 -97
- package/dist/web/standalone/.next/static/chunks/4024.11ca5c01938e5948.js +0 -9
- package/dist/web/standalone/.next/static/chunks/app/page-12dd5ece0df4badc.js +0 -1
- package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
- package/src/resources/extensions/gsd/auto-worktree-sync.ts +0 -234
- package/src/resources/extensions/gsd/resource-version.ts +0 -101
- /package/dist/web/standalone/.next/static/{zGWUKFTfjCQerNgsPpAbF → vNN0h0emdEi8l_npi8poE}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{zGWUKFTfjCQerNgsPpAbF → vNN0h0emdEi8l_npi8poE}/_ssgManifest.js +0 -0
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
* state, no globals — every dependency is passed as a parameter or imported as a
|
|
6
6
|
* utility.
|
|
7
7
|
*/
|
|
8
|
-
import { loadFile, parseContinue, parseSummary,
|
|
8
|
+
import { loadFile, parseContinue, parseSummary, loadActiveOverrides, formatOverridesSection, parseTaskPlanFile } from "./files.js";
|
|
9
|
+
import { hasVerdict, getUatType } from "./verdict-parser.js";
|
|
9
10
|
import { loadPrompt, inlineTemplate } from "./prompt-loader.js";
|
|
10
11
|
import { resolveMilestoneFile, resolveSliceFile, resolveSlicePath, resolveTasksDir, resolveTaskFiles, resolveTaskFile, relMilestoneFile, relSliceFile, relSlicePath, relMilestonePath, resolveGsdRootFile, relGsdRootFile, resolveRuntimeFile, } from "./paths.js";
|
|
11
12
|
import { resolveSkillDiscoveryMode, resolveInlineLevel, loadEffectiveGSDPreferences, resolveAllSkillReferences } from "./preferences.js";
|
|
@@ -14,6 +15,7 @@ import { getLoadedSkills } from "@gsd/pi-coding-agent";
|
|
|
14
15
|
import { join, basename } from "node:path";
|
|
15
16
|
import { existsSync } from "node:fs";
|
|
16
17
|
import { computeBudgets, resolveExecutorContextWindow, truncateAtSectionBoundary } from "./context-budget.js";
|
|
18
|
+
import { getPendingGates } from "./gsd-db.js";
|
|
17
19
|
import { formatDecisionsCompact, formatRequirementsCompact } from "./structured-data-formatter.js";
|
|
18
20
|
// ─── Preamble Cap ─────────────────────────────────────────────────────────────
|
|
19
21
|
const MAX_PREAMBLE_CHARS = 30_000;
|
|
@@ -354,10 +356,17 @@ function resolvePreferredSkillNames(prefs, visibleSkills, contextTokens, base) {
|
|
|
354
356
|
.filter(skill => preferred.has(normalizeSkillReference(skill.name)) && skillMatchesContext(skill, contextTokens))
|
|
355
357
|
.map(skill => normalizeSkillReference(skill.name));
|
|
356
358
|
}
|
|
359
|
+
/** Skill names must be lowercase alphanumeric with hyphens — reject anything else
|
|
360
|
+
* to prevent prompt injection via crafted directory names. */
|
|
361
|
+
const SAFE_SKILL_NAME = /^[a-z0-9][a-z0-9-]*$/;
|
|
357
362
|
function formatSkillActivationBlock(skillNames) {
|
|
358
|
-
|
|
363
|
+
const safe = skillNames.filter(name => SAFE_SKILL_NAME.test(name));
|
|
364
|
+
if (safe.length === 0)
|
|
359
365
|
return "";
|
|
360
|
-
|
|
366
|
+
// Use explicit parameter syntax so LLMs pass { skill: "..." } instead of { name: "..." }.
|
|
367
|
+
// The function-call-like syntax `Skill('name')` led LLMs to infer a positional
|
|
368
|
+
// parameter name, causing tool validation failures — see #2224.
|
|
369
|
+
const calls = safe.map(name => `Call Skill({ skill: '${name}' })`).join('. ');
|
|
361
370
|
return `<skill_activation>${calls}.</skill_activation>`;
|
|
362
371
|
}
|
|
363
372
|
export function buildSkillActivationBlock(params) {
|
|
@@ -663,13 +672,10 @@ export async function checkNeedsRunUat(base, mid, state, prefs) {
|
|
|
663
672
|
const uatContent = await loadFile(uatFile);
|
|
664
673
|
if (!uatContent)
|
|
665
674
|
return null;
|
|
666
|
-
|
|
667
|
-
if (
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
return null;
|
|
671
|
-
}
|
|
672
|
-
const uatType = extractUatType(uatContent) ?? "artifact-driven";
|
|
675
|
+
// If the UAT file already contains a verdict, UAT has been run — skip
|
|
676
|
+
if (hasVerdict(uatContent))
|
|
677
|
+
return null;
|
|
678
|
+
const uatType = getUatType(uatContent);
|
|
673
679
|
return { sliceId: sid, uatType };
|
|
674
680
|
}
|
|
675
681
|
}
|
|
@@ -697,13 +703,10 @@ export async function checkNeedsRunUat(base, mid, state, prefs) {
|
|
|
697
703
|
const uatContentFb = await loadFile(uatFileFb);
|
|
698
704
|
if (!uatContentFb)
|
|
699
705
|
return null;
|
|
700
|
-
|
|
701
|
-
if (
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
return null;
|
|
705
|
-
}
|
|
706
|
-
const uatTypeFb = extractUatType(uatContentFb) ?? "artifact-driven";
|
|
706
|
+
// If the UAT file already contains a verdict, UAT has been run — skip
|
|
707
|
+
if (hasVerdict(uatContentFb))
|
|
708
|
+
return null;
|
|
709
|
+
const uatTypeFb = getUatType(uatContentFb);
|
|
707
710
|
return { sliceId: uatSid, uatType: uatTypeFb };
|
|
708
711
|
}
|
|
709
712
|
// ─── Prompt Builders ──────────────────────────────────────────────────────
|
|
@@ -1194,8 +1197,8 @@ export async function buildValidateMilestonePrompt(mid, midTitle, base, level) {
|
|
|
1194
1197
|
const summaryPath = resolveSliceFile(base, mid, sid, "SUMMARY");
|
|
1195
1198
|
const summaryRel = relSliceFile(base, mid, sid, "SUMMARY");
|
|
1196
1199
|
inlined.push(await inlineFile(summaryPath, summaryRel, `${sid} Summary`));
|
|
1197
|
-
const uatPath = resolveSliceFile(base, mid, sid, "UAT
|
|
1198
|
-
const uatRel = relSliceFile(base, mid, sid, "UAT
|
|
1200
|
+
const uatPath = resolveSliceFile(base, mid, sid, "UAT");
|
|
1201
|
+
const uatRel = relSliceFile(base, mid, sid, "UAT");
|
|
1199
1202
|
const uatInline = await inlineFileOptional(uatPath, uatRel, `${sid} UAT Result`);
|
|
1200
1203
|
if (uatInline)
|
|
1201
1204
|
inlined.push(uatInline);
|
|
@@ -1334,8 +1337,8 @@ export async function buildRunUatPrompt(mid, sliceId, uatPath, uatContent, base)
|
|
|
1334
1337
|
if (projectInline)
|
|
1335
1338
|
inlined.push(projectInline);
|
|
1336
1339
|
const inlinedContext = capPreamble(`## Inlined Context (preloaded — do not re-read these files)\n\n${inlined.join("\n\n---\n\n")}`);
|
|
1337
|
-
const uatResultPath = join(base, relSliceFile(base, mid, sliceId, "UAT
|
|
1338
|
-
const uatType =
|
|
1340
|
+
const uatResultPath = join(base, relSliceFile(base, mid, sliceId, "UAT"));
|
|
1341
|
+
const uatType = getUatType(uatContent);
|
|
1339
1342
|
return loadPrompt("run-uat", {
|
|
1340
1343
|
workingDirectory: base,
|
|
1341
1344
|
milestoneId: mid,
|
|
@@ -1465,6 +1468,84 @@ export async function buildReactiveExecutePrompt(mid, midTitle, sid, sTitle, rea
|
|
|
1465
1468
|
inlinedTemplates,
|
|
1466
1469
|
});
|
|
1467
1470
|
}
|
|
1471
|
+
// ─── Gate Evaluation ──────────────────────────────────────────────────────
|
|
1472
|
+
const GATE_QUESTIONS = {
|
|
1473
|
+
Q3: {
|
|
1474
|
+
question: "How can this be exploited?",
|
|
1475
|
+
guidance: [
|
|
1476
|
+
"Identify abuse scenarios: parameter tampering, replay attacks, privilege escalation.",
|
|
1477
|
+
"Map data exposure risks: PII, tokens, secrets accessible through this slice.",
|
|
1478
|
+
"Define input trust boundaries: untrusted user input reaching DB, API, or filesystem.",
|
|
1479
|
+
"If none apply, return verdict 'omitted' with rationale explaining why.",
|
|
1480
|
+
].join("\n"),
|
|
1481
|
+
},
|
|
1482
|
+
Q4: {
|
|
1483
|
+
question: "What existing promises does this break?",
|
|
1484
|
+
guidance: [
|
|
1485
|
+
"List which existing requirements (R001, R003, etc.) are touched by this slice.",
|
|
1486
|
+
"Identify what must be re-tested after shipping.",
|
|
1487
|
+
"Flag decisions that should be revisited given the new scope.",
|
|
1488
|
+
"If no existing requirements are affected, return verdict 'omitted'.",
|
|
1489
|
+
].join("\n"),
|
|
1490
|
+
},
|
|
1491
|
+
};
|
|
1492
|
+
export async function buildGateEvaluatePrompt(mid, midTitle, sid, sTitle, base) {
|
|
1493
|
+
const pending = getPendingGates(mid, sid, "slice");
|
|
1494
|
+
// Load the slice plan for context
|
|
1495
|
+
const planFile = resolveSliceFile(base, mid, sid, "PLAN");
|
|
1496
|
+
const planContent = planFile ? (await loadFile(planFile)) ?? "(plan file empty)" : "(plan file not found)";
|
|
1497
|
+
// Build per-gate subagent prompts
|
|
1498
|
+
const subagentSections = [];
|
|
1499
|
+
const gateListLines = [];
|
|
1500
|
+
for (const gate of pending) {
|
|
1501
|
+
const meta = GATE_QUESTIONS[gate.gate_id];
|
|
1502
|
+
if (!meta)
|
|
1503
|
+
continue;
|
|
1504
|
+
gateListLines.push(`- **${gate.gate_id}**: ${meta.question}`);
|
|
1505
|
+
const subPrompt = [
|
|
1506
|
+
`You are evaluating quality gate **${gate.gate_id}** for slice ${sid} (${sTitle}).`,
|
|
1507
|
+
"",
|
|
1508
|
+
`## Question: ${meta.question}`,
|
|
1509
|
+
"",
|
|
1510
|
+
meta.guidance,
|
|
1511
|
+
"",
|
|
1512
|
+
"## Slice Plan",
|
|
1513
|
+
"",
|
|
1514
|
+
planContent,
|
|
1515
|
+
"",
|
|
1516
|
+
"## Instructions",
|
|
1517
|
+
"",
|
|
1518
|
+
"Analyze the slice plan above and answer the gate question.",
|
|
1519
|
+
`Call the \`gsd_save_gate_result\` tool with:`,
|
|
1520
|
+
`- \`milestoneId\`: "${mid}"`,
|
|
1521
|
+
`- \`sliceId\`: "${sid}"`,
|
|
1522
|
+
`- \`gateId\`: "${gate.gate_id}"`,
|
|
1523
|
+
"- `verdict`: \"pass\" (no concerns), \"flag\" (concerns found), or \"omitted\" (not applicable)",
|
|
1524
|
+
"- `rationale`: one-sentence justification",
|
|
1525
|
+
"- `findings`: detailed markdown findings (or empty if omitted)",
|
|
1526
|
+
].join("\n");
|
|
1527
|
+
subagentSections.push([
|
|
1528
|
+
`### ${gate.gate_id}: ${meta.question}`,
|
|
1529
|
+
"",
|
|
1530
|
+
"Use this as the prompt for a `subagent` call:",
|
|
1531
|
+
"",
|
|
1532
|
+
"```",
|
|
1533
|
+
subPrompt,
|
|
1534
|
+
"```",
|
|
1535
|
+
].join("\n"));
|
|
1536
|
+
}
|
|
1537
|
+
return loadPrompt("gate-evaluate", {
|
|
1538
|
+
workingDirectory: base,
|
|
1539
|
+
milestoneId: mid,
|
|
1540
|
+
milestoneTitle: midTitle,
|
|
1541
|
+
sliceId: sid,
|
|
1542
|
+
sliceTitle: sTitle,
|
|
1543
|
+
slicePlanContent: planContent,
|
|
1544
|
+
gateCount: String(pending.length),
|
|
1545
|
+
gateList: gateListLines.join("\n"),
|
|
1546
|
+
subagentPrompts: subagentSections.join("\n\n---\n\n"),
|
|
1547
|
+
});
|
|
1548
|
+
}
|
|
1468
1549
|
export async function buildRewriteDocsPrompt(mid, midTitle, activeSlice, base, overrides) {
|
|
1469
1550
|
const sid = activeSlice?.id;
|
|
1470
1551
|
const sTitle = activeSlice?.title ?? "";
|
|
@@ -6,85 +6,19 @@
|
|
|
6
6
|
* Pure functions that receive all needed state as parameters — no module-level
|
|
7
7
|
* globals or AutoContext dependency.
|
|
8
8
|
*/
|
|
9
|
-
import { clearUnitRuntimeRecord } from "./unit-runtime.js";
|
|
10
9
|
import { clearParseCache } from "./files.js";
|
|
11
10
|
import { parseRoadmap as parseLegacyRoadmap, parsePlan as parseLegacyPlan } from "./parsers-legacy.js";
|
|
12
11
|
import { isDbAvailable, getTask, getSlice, getSliceTasks } from "./gsd-db.js";
|
|
13
12
|
import { isValidationTerminal } from "./state.js";
|
|
14
13
|
import { nativeConflictFiles, nativeCommit, nativeCheckoutTheirs, nativeAddPaths, nativeMergeAbort, nativeResetHard, } from "./native-git-bridge.js";
|
|
15
|
-
import {
|
|
14
|
+
import { resolveSlicePath, resolveSliceFile, resolveTasksDir, resolveTaskFiles, relMilestoneFile, relSliceFile, buildSliceFileName, resolveMilestoneFile, clearPathCache, resolveGsdRootFile, } from "./paths.js";
|
|
16
15
|
import { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync, } from "node:fs";
|
|
17
16
|
import { execFileSync } from "node:child_process";
|
|
18
17
|
import { dirname, join } from "node:path";
|
|
18
|
+
import { resolveExpectedArtifactPath, diagnoseExpectedArtifact, } from "./auto-artifact-paths.js";
|
|
19
|
+
// Re-export so existing consumers of auto-recovery.ts keep working.
|
|
20
|
+
export { resolveExpectedArtifactPath, diagnoseExpectedArtifact };
|
|
19
21
|
// ─── Artifact Resolution & Verification ───────────────────────────────────────
|
|
20
|
-
/**
|
|
21
|
-
* Resolve the expected artifact for a unit to an absolute path.
|
|
22
|
-
*/
|
|
23
|
-
export function resolveExpectedArtifactPath(unitType, unitId, base) {
|
|
24
|
-
const parts = unitId.split("/");
|
|
25
|
-
const mid = parts[0];
|
|
26
|
-
const sid = parts[1];
|
|
27
|
-
switch (unitType) {
|
|
28
|
-
case "discuss-milestone": {
|
|
29
|
-
const dir = resolveMilestonePath(base, mid);
|
|
30
|
-
return dir ? join(dir, buildMilestoneFileName(mid, "CONTEXT")) : null;
|
|
31
|
-
}
|
|
32
|
-
case "research-milestone": {
|
|
33
|
-
const dir = resolveMilestonePath(base, mid);
|
|
34
|
-
return dir ? join(dir, buildMilestoneFileName(mid, "RESEARCH")) : null;
|
|
35
|
-
}
|
|
36
|
-
case "plan-milestone": {
|
|
37
|
-
const dir = resolveMilestonePath(base, mid);
|
|
38
|
-
return dir ? join(dir, buildMilestoneFileName(mid, "ROADMAP")) : null;
|
|
39
|
-
}
|
|
40
|
-
case "research-slice": {
|
|
41
|
-
const dir = resolveSlicePath(base, mid, sid);
|
|
42
|
-
return dir ? join(dir, buildSliceFileName(sid, "RESEARCH")) : null;
|
|
43
|
-
}
|
|
44
|
-
case "plan-slice": {
|
|
45
|
-
const dir = resolveSlicePath(base, mid, sid);
|
|
46
|
-
return dir ? join(dir, buildSliceFileName(sid, "PLAN")) : null;
|
|
47
|
-
}
|
|
48
|
-
case "reassess-roadmap": {
|
|
49
|
-
const dir = resolveSlicePath(base, mid, sid);
|
|
50
|
-
return dir ? join(dir, buildSliceFileName(sid, "ASSESSMENT")) : null;
|
|
51
|
-
}
|
|
52
|
-
case "run-uat": {
|
|
53
|
-
const dir = resolveSlicePath(base, mid, sid);
|
|
54
|
-
return dir ? join(dir, buildSliceFileName(sid, "UAT-RESULT")) : null;
|
|
55
|
-
}
|
|
56
|
-
case "execute-task": {
|
|
57
|
-
const tid = parts[2];
|
|
58
|
-
const dir = resolveSlicePath(base, mid, sid);
|
|
59
|
-
return dir && tid
|
|
60
|
-
? join(dir, "tasks", buildTaskFileName(tid, "SUMMARY"))
|
|
61
|
-
: null;
|
|
62
|
-
}
|
|
63
|
-
case "complete-slice": {
|
|
64
|
-
const dir = resolveSlicePath(base, mid, sid);
|
|
65
|
-
return dir ? join(dir, buildSliceFileName(sid, "SUMMARY")) : null;
|
|
66
|
-
}
|
|
67
|
-
case "validate-milestone": {
|
|
68
|
-
const dir = resolveMilestonePath(base, mid);
|
|
69
|
-
return dir ? join(dir, buildMilestoneFileName(mid, "VALIDATION")) : null;
|
|
70
|
-
}
|
|
71
|
-
case "complete-milestone": {
|
|
72
|
-
const dir = resolveMilestonePath(base, mid);
|
|
73
|
-
return dir ? join(dir, buildMilestoneFileName(mid, "SUMMARY")) : null;
|
|
74
|
-
}
|
|
75
|
-
case "replan-slice": {
|
|
76
|
-
const dir = resolveSlicePath(base, mid, sid);
|
|
77
|
-
return dir ? join(dir, buildSliceFileName(sid, "REPLAN")) : null;
|
|
78
|
-
}
|
|
79
|
-
case "rewrite-docs":
|
|
80
|
-
return null;
|
|
81
|
-
case "reactive-execute":
|
|
82
|
-
// Reactive execute produces multiple task summaries — verified separately
|
|
83
|
-
return null;
|
|
84
|
-
default:
|
|
85
|
-
return null;
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
22
|
/**
|
|
89
23
|
* Check whether a milestone produced implementation artifacts (non-`.gsd/` files)
|
|
90
24
|
* in the git history. Uses `git log --name-only` to inspect all commits on the
|
|
@@ -244,6 +178,36 @@ export function verifyExpectedArtifact(unitType, unitId, base) {
|
|
|
244
178
|
}
|
|
245
179
|
return true;
|
|
246
180
|
}
|
|
181
|
+
// Gate-evaluate: verify that each dispatched gate has been resolved in the DB.
|
|
182
|
+
// The unitId encodes the batch: "{mid}/{sid}/gates+Q3,Q4"
|
|
183
|
+
if (unitType === "gate-evaluate") {
|
|
184
|
+
const parts = unitId.split("/");
|
|
185
|
+
const mid = parts[0];
|
|
186
|
+
const sid = parts[1];
|
|
187
|
+
const batchPart = parts[2]; // "gates+Q3,Q4"
|
|
188
|
+
if (!mid || !sid || !batchPart)
|
|
189
|
+
return false;
|
|
190
|
+
const plusIdx = batchPart.indexOf("+");
|
|
191
|
+
if (plusIdx === -1)
|
|
192
|
+
return true; // no specific gates encoded — pass
|
|
193
|
+
const gateIds = batchPart.slice(plusIdx + 1).split(",").filter(Boolean);
|
|
194
|
+
if (gateIds.length === 0)
|
|
195
|
+
return true;
|
|
196
|
+
try {
|
|
197
|
+
const { getPendingGates: getPending } = require("./gsd-db.js");
|
|
198
|
+
const pending = getPending(mid, sid, "slice");
|
|
199
|
+
const pendingIds = new Set(pending.map((g) => g.gate_id));
|
|
200
|
+
// All dispatched gates must no longer be pending
|
|
201
|
+
for (const gid of gateIds) {
|
|
202
|
+
if (pendingIds.has(gid))
|
|
203
|
+
return false;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
catch {
|
|
207
|
+
// DB unavailable — treat as verified to avoid blocking
|
|
208
|
+
}
|
|
209
|
+
return true;
|
|
210
|
+
}
|
|
247
211
|
const absPath = resolveExpectedArtifactPath(unitType, unitId, base);
|
|
248
212
|
// For unit types with no verifiable artifact (null path), the parent directory
|
|
249
213
|
// is missing on disk — treat as stale completion state so the key gets evicted (#313).
|
|
@@ -415,44 +379,35 @@ export function writeBlockerPlaceholder(unitType, unitId, base, reason) {
|
|
|
415
379
|
writeFileSync(absPath, content, "utf-8");
|
|
416
380
|
return diagnoseExpectedArtifact(unitType, unitId, base);
|
|
417
381
|
}
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
382
|
+
// ─── Merge State Reconciliation ───────────────────────────────────────────────
|
|
383
|
+
/**
|
|
384
|
+
* Best-effort abort of a pending merge/squash and hard-reset to HEAD.
|
|
385
|
+
* Handles both real merges (MERGE_HEAD) and squash merges (SQUASH_MSG).
|
|
386
|
+
*/
|
|
387
|
+
function abortAndResetMerge(basePath, hasMergeHead, squashMsgPath) {
|
|
388
|
+
if (hasMergeHead) {
|
|
389
|
+
try {
|
|
390
|
+
nativeMergeAbort(basePath);
|
|
391
|
+
}
|
|
392
|
+
catch {
|
|
393
|
+
/* best-effort */
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
else if (squashMsgPath) {
|
|
397
|
+
try {
|
|
398
|
+
unlinkSync(squashMsgPath);
|
|
399
|
+
}
|
|
400
|
+
catch {
|
|
401
|
+
/* best-effort */
|
|
436
402
|
}
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
case "reassess-roadmap":
|
|
444
|
-
return `${relSliceFile(base, mid, sid, "ASSESSMENT")} (roadmap reassessment)`;
|
|
445
|
-
case "run-uat":
|
|
446
|
-
return `${relSliceFile(base, mid, sid, "UAT-RESULT")} (UAT result)`;
|
|
447
|
-
case "validate-milestone":
|
|
448
|
-
return `${relMilestoneFile(base, mid, "VALIDATION")} (milestone validation report)`;
|
|
449
|
-
case "complete-milestone":
|
|
450
|
-
return `${relMilestoneFile(base, mid, "SUMMARY")} (milestone summary)`;
|
|
451
|
-
default:
|
|
452
|
-
return null;
|
|
403
|
+
}
|
|
404
|
+
try {
|
|
405
|
+
nativeResetHard(basePath);
|
|
406
|
+
}
|
|
407
|
+
catch {
|
|
408
|
+
/* best-effort */
|
|
453
409
|
}
|
|
454
410
|
}
|
|
455
|
-
// ─── Merge State Reconciliation ───────────────────────────────────────────────
|
|
456
411
|
/**
|
|
457
412
|
* Detect leftover merge state from a prior session and reconcile it.
|
|
458
413
|
* If MERGE_HEAD or SQUASH_MSG exists, check whether conflicts are resolved.
|
|
@@ -503,95 +458,18 @@ export function reconcileMergeState(basePath, ctx) {
|
|
|
503
458
|
}
|
|
504
459
|
}
|
|
505
460
|
if (!resolved) {
|
|
506
|
-
|
|
507
|
-
try {
|
|
508
|
-
nativeMergeAbort(basePath);
|
|
509
|
-
}
|
|
510
|
-
catch {
|
|
511
|
-
/* best-effort */
|
|
512
|
-
}
|
|
513
|
-
}
|
|
514
|
-
else if (hasSquashMsg) {
|
|
515
|
-
try {
|
|
516
|
-
unlinkSync(squashMsgPath);
|
|
517
|
-
}
|
|
518
|
-
catch {
|
|
519
|
-
/* best-effort */
|
|
520
|
-
}
|
|
521
|
-
}
|
|
522
|
-
try {
|
|
523
|
-
nativeResetHard(basePath);
|
|
524
|
-
}
|
|
525
|
-
catch {
|
|
526
|
-
/* best-effort */
|
|
527
|
-
}
|
|
461
|
+
abortAndResetMerge(basePath, hasMergeHead, squashMsgPath);
|
|
528
462
|
ctx.ui.notify("Detected leftover merge state — auto-resolve failed, cleaned up. Re-deriving state.", "warning");
|
|
529
463
|
}
|
|
530
464
|
}
|
|
531
465
|
else {
|
|
532
466
|
// Code conflicts present — abort and reset
|
|
533
|
-
|
|
534
|
-
try {
|
|
535
|
-
nativeMergeAbort(basePath);
|
|
536
|
-
}
|
|
537
|
-
catch {
|
|
538
|
-
/* best-effort */
|
|
539
|
-
}
|
|
540
|
-
}
|
|
541
|
-
else if (hasSquashMsg) {
|
|
542
|
-
try {
|
|
543
|
-
unlinkSync(squashMsgPath);
|
|
544
|
-
}
|
|
545
|
-
catch {
|
|
546
|
-
/* best-effort */
|
|
547
|
-
}
|
|
548
|
-
}
|
|
549
|
-
try {
|
|
550
|
-
nativeResetHard(basePath);
|
|
551
|
-
}
|
|
552
|
-
catch {
|
|
553
|
-
/* best-effort */
|
|
554
|
-
}
|
|
467
|
+
abortAndResetMerge(basePath, hasMergeHead, squashMsgPath);
|
|
555
468
|
ctx.ui.notify("Detected leftover merge state with unresolved conflicts — cleaned up. Re-deriving state.", "warning");
|
|
556
469
|
}
|
|
557
470
|
}
|
|
558
471
|
return true;
|
|
559
472
|
}
|
|
560
|
-
// ─── Self-Heal Runtime Records ────────────────────────────────────────────────
|
|
561
|
-
/**
|
|
562
|
-
* Self-heal: scan runtime records in .gsd/ and clear stale ones.
|
|
563
|
-
* Clears dispatched records older than 1 hour (process crashed before
|
|
564
|
-
* completing the unit). deriveState() handles re-derivation — no need
|
|
565
|
-
* for completion key persistence here.
|
|
566
|
-
*/
|
|
567
|
-
export async function selfHealRuntimeRecords(base, ctx) {
|
|
568
|
-
try {
|
|
569
|
-
const { listUnitRuntimeRecords } = await import("./unit-runtime.js");
|
|
570
|
-
const records = listUnitRuntimeRecords(base);
|
|
571
|
-
let healed = 0;
|
|
572
|
-
const STALE_THRESHOLD_MS = 60 * 60 * 1000; // 1 hour
|
|
573
|
-
const now = Date.now();
|
|
574
|
-
for (const record of records) {
|
|
575
|
-
const { unitType, unitId } = record;
|
|
576
|
-
// Case 0 removed — roadmap checkbox auto-fix is no longer needed.
|
|
577
|
-
// With DB-as-truth, stale checkboxes are fixed by repairStaleRenders().
|
|
578
|
-
// Clear stale dispatched records (dispatched > 1h ago, process crashed)
|
|
579
|
-
const age = now - (record.startedAt ?? 0);
|
|
580
|
-
if (record.phase === "dispatched" && age > STALE_THRESHOLD_MS) {
|
|
581
|
-
clearUnitRuntimeRecord(base, unitType, unitId);
|
|
582
|
-
healed++;
|
|
583
|
-
continue;
|
|
584
|
-
}
|
|
585
|
-
}
|
|
586
|
-
if (healed > 0) {
|
|
587
|
-
ctx.ui.notify(`Self-heal: cleared ${healed} stale runtime record(s).`, "info");
|
|
588
|
-
}
|
|
589
|
-
}
|
|
590
|
-
catch (e) {
|
|
591
|
-
// Non-fatal — self-heal should never block auto-mode start
|
|
592
|
-
void e;
|
|
593
|
-
}
|
|
594
|
-
}
|
|
595
473
|
// ─── Loop Remediation ─────────────────────────────────────────────────────────
|
|
596
474
|
/**
|
|
597
475
|
* Build concrete, manual remediation steps for a loop-detected unit failure.
|
|
@@ -24,7 +24,7 @@ import { nativeInit, nativeAddAll, nativeCommit, } from "./native-git-bridge.js"
|
|
|
24
24
|
import { GitServiceImpl } from "./git-service.js";
|
|
25
25
|
import { captureIntegrationBranch, detectWorktreeName, setActiveMilestoneId, } from "./worktree.js";
|
|
26
26
|
import { getAutoWorktreePath } from "./auto-worktree.js";
|
|
27
|
-
import { readResourceVersion } from "./auto-worktree
|
|
27
|
+
import { readResourceVersion, cleanStaleRuntimeUnits } from "./auto-worktree.js";
|
|
28
28
|
import { initMetrics } from "./metrics.js";
|
|
29
29
|
import { initRoutingHistory } from "./routing-history.js";
|
|
30
30
|
import { restoreHookState, resetHookState } from "./post-unit-hooks.js";
|
|
@@ -33,6 +33,7 @@ import { snapshotSkills } from "./skill-discovery.js";
|
|
|
33
33
|
import { isDbAvailable, getMilestone } from "./gsd-db.js";
|
|
34
34
|
import { hideFooter } from "./auto-dashboard.js";
|
|
35
35
|
import { debugLog, enableDebug, isDebugEnabled, getDebugLogPath, } from "./debug-logger.js";
|
|
36
|
+
import { parseUnitId } from "./unit-id.js";
|
|
36
37
|
import { existsSync, mkdirSync, readdirSync, statSync, unlinkSync, } from "node:fs";
|
|
37
38
|
import { join } from "node:path";
|
|
38
39
|
import { sep as pathSep } from "node:path";
|
|
@@ -119,7 +120,7 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
|
|
|
119
120
|
ctx.ui.notify(`Another auto-mode session (PID ${crashLock.pid}) appears to be running.\nStop it with \`kill ${crashLock.pid}\` before starting a new session.`, "error");
|
|
120
121
|
return releaseLockAndReturn();
|
|
121
122
|
}
|
|
122
|
-
const recoveredMid = crashLock.unitId.
|
|
123
|
+
const recoveredMid = parseUnitId(crashLock.unitId).milestone;
|
|
123
124
|
const milestoneAlreadyComplete = recoveredMid
|
|
124
125
|
? !!resolveMilestoneFile(base, recoveredMid, "SUMMARY")
|
|
125
126
|
: false;
|
|
@@ -159,35 +160,7 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
|
|
|
159
160
|
// Invalidate caches before initial state derivation
|
|
160
161
|
invalidateAllCaches();
|
|
161
162
|
// Clean stale runtime unit files for completed milestones (#887)
|
|
162
|
-
|
|
163
|
-
const runtimeUnitsDir = join(gsdRoot(base), "runtime", "units");
|
|
164
|
-
if (existsSync(runtimeUnitsDir)) {
|
|
165
|
-
for (const file of readdirSync(runtimeUnitsDir)) {
|
|
166
|
-
if (!file.endsWith(".json"))
|
|
167
|
-
continue;
|
|
168
|
-
const midMatch = file.match(/(M\d+(?:-[a-z0-9]{6})?)/);
|
|
169
|
-
if (!midMatch)
|
|
170
|
-
continue;
|
|
171
|
-
const mid = midMatch[1];
|
|
172
|
-
if (resolveMilestoneFile(base, mid, "SUMMARY")) {
|
|
173
|
-
try {
|
|
174
|
-
unlinkSync(join(runtimeUnitsDir, file));
|
|
175
|
-
}
|
|
176
|
-
catch (e) {
|
|
177
|
-
debugLog("stale-unit-cleanup-failed", {
|
|
178
|
-
file,
|
|
179
|
-
error: e instanceof Error ? e.message : String(e),
|
|
180
|
-
});
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
catch (e) {
|
|
187
|
-
debugLog("stale-unit-dir-cleanup-failed", {
|
|
188
|
-
error: e instanceof Error ? e.message : String(e),
|
|
189
|
-
});
|
|
190
|
-
}
|
|
163
|
+
cleanStaleRuntimeUnits(gsdRoot(base), (mid) => !!resolveMilestoneFile(base, mid, "SUMMARY"));
|
|
191
164
|
let state = await deriveState(base);
|
|
192
165
|
// Stale worktree state recovery (#654)
|
|
193
166
|
if (state.activeMilestone &&
|
|
@@ -155,7 +155,7 @@ export function startUnitSupervision(sctx) {
|
|
|
155
155
|
const message = err instanceof Error ? err.message : String(err);
|
|
156
156
|
console.error(`[idle-watchdog] Unhandled error: ${message}`);
|
|
157
157
|
// Unblock any pending unit promise so the auto-loop is not orphaned.
|
|
158
|
-
resolveAgentEndCancelled();
|
|
158
|
+
resolveAgentEndCancelled({ message: `Idle watchdog error: ${message}`, category: "idle", isTransient: true });
|
|
159
159
|
try {
|
|
160
160
|
ctx.ui.notify(`Idle watchdog error: ${message}`, "warning");
|
|
161
161
|
}
|
|
@@ -188,7 +188,7 @@ export function startUnitSupervision(sctx) {
|
|
|
188
188
|
const message = err instanceof Error ? err.message : String(err);
|
|
189
189
|
console.error(`[hard-timeout] Unhandled error: ${message}`);
|
|
190
190
|
// Unblock any pending unit promise so the auto-loop is not orphaned.
|
|
191
|
-
resolveAgentEndCancelled();
|
|
191
|
+
resolveAgentEndCancelled({ message: `Hard timeout error: ${message}`, category: "timeout", isTransient: true });
|
|
192
192
|
try {
|
|
193
193
|
ctx.ui.notify(`Hard timeout error: ${message}`, "warning");
|
|
194
194
|
}
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
* checks the result and handles control flow.
|
|
11
11
|
*/
|
|
12
12
|
import { resolveSlicePath } from "./paths.js";
|
|
13
|
+
import { parseUnitId } from "./unit-id.js";
|
|
13
14
|
import { isDbAvailable, getTask } from "./gsd-db.js";
|
|
14
15
|
import { loadEffectiveGSDPreferences } from "./preferences.js";
|
|
15
16
|
import { runVerificationGate, formatFailureContext, captureRuntimeErrors, runDependencyAudit, } from "./verification-gate.js";
|
|
@@ -34,18 +35,15 @@ export async function runPostUnitVerification(vctx, pauseAuto) {
|
|
|
34
35
|
const effectivePrefs = loadEffectiveGSDPreferences();
|
|
35
36
|
const prefs = effectivePrefs?.preferences;
|
|
36
37
|
// Read task plan verify field
|
|
37
|
-
const
|
|
38
|
+
const { milestone: mid, slice: sid, task: tid } = parseUnitId(s.currentUnit.id);
|
|
38
39
|
let taskPlanVerify;
|
|
39
|
-
if (
|
|
40
|
-
const [mid, sid, tid] = parts;
|
|
40
|
+
if (mid && sid && tid) {
|
|
41
41
|
if (isDbAvailable()) {
|
|
42
42
|
taskPlanVerify = getTask(mid, sid, tid)?.verify;
|
|
43
43
|
}
|
|
44
44
|
// When DB unavailable, taskPlanVerify stays undefined — gate runs without task-specific checks
|
|
45
45
|
}
|
|
46
46
|
const result = runVerificationGate({
|
|
47
|
-
basePath: s.basePath,
|
|
48
|
-
unitId: s.currentUnit.id,
|
|
49
47
|
cwd: s.basePath,
|
|
50
48
|
preferenceCommands: prefs?.verification_commands,
|
|
51
49
|
taskPlanVerify,
|
|
@@ -100,9 +98,8 @@ export async function runPostUnitVerification(vctx, pauseAuto) {
|
|
|
100
98
|
}
|
|
101
99
|
// Write verification evidence JSON
|
|
102
100
|
const attempt = s.verificationRetryCount.get(s.currentUnit.id) ?? 0;
|
|
103
|
-
if (
|
|
101
|
+
if (mid && sid && tid) {
|
|
104
102
|
try {
|
|
105
|
-
const [mid, sid, tid] = parts;
|
|
106
103
|
const sDir = resolveSlicePath(s.basePath, mid, sid);
|
|
107
104
|
if (sDir) {
|
|
108
105
|
const tasksDir = join(sDir, "tasks");
|