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
|
@@ -48,11 +48,17 @@ export function attachJsonlLineReader(stream: Readable, onLine: (line: string) =
|
|
|
48
48
|
}
|
|
49
49
|
};
|
|
50
50
|
|
|
51
|
+
const onError = (_err: Error) => {
|
|
52
|
+
// Stream errors are non-fatal for JSONL reading
|
|
53
|
+
};
|
|
54
|
+
|
|
51
55
|
stream.on("data", onData);
|
|
52
56
|
stream.on("end", onEnd);
|
|
57
|
+
stream.on("error", onError);
|
|
53
58
|
|
|
54
59
|
return () => {
|
|
55
60
|
stream.off("data", onData);
|
|
56
61
|
stream.off("end", onEnd);
|
|
62
|
+
stream.off("error", onError);
|
|
57
63
|
};
|
|
58
64
|
}
|
|
@@ -488,8 +488,6 @@ export class RpcClient {
|
|
|
488
488
|
const fullCommand = { ...command, id } as RpcCommand;
|
|
489
489
|
|
|
490
490
|
return new Promise((resolve, reject) => {
|
|
491
|
-
this.pendingRequests.set(id, { resolve, reject });
|
|
492
|
-
|
|
493
491
|
const timeout = setTimeout(() => {
|
|
494
492
|
this.pendingRequests.delete(id);
|
|
495
493
|
reject(new Error(`Timeout waiting for response to ${command.type}. Stderr: ${this.stderr}`));
|
|
@@ -710,8 +710,8 @@ export async function runRpcMode(session: AgentSession): Promise<never> {
|
|
|
710
710
|
}
|
|
711
711
|
|
|
712
712
|
default: {
|
|
713
|
-
const unknownCommand = command as { type: string };
|
|
714
|
-
return error(
|
|
713
|
+
const unknownCommand = command as { type: string; id?: string };
|
|
714
|
+
return error(unknownCommand.id, unknownCommand.type, `Unknown command: ${unknownCommand.type}`);
|
|
715
715
|
}
|
|
716
716
|
}
|
|
717
717
|
};
|
package/pkg/package.json
CHANGED
|
@@ -10,7 +10,8 @@ describe("commit linking", () => {
|
|
|
10
10
|
issueNumber: 43,
|
|
11
11
|
});
|
|
12
12
|
assert.ok(msg.includes("Resolves #43"), "should include Resolves trailer");
|
|
13
|
-
assert.ok(msg.startsWith("feat
|
|
13
|
+
assert.ok(msg.startsWith("feat:"), "subject line has no scope");
|
|
14
|
+
assert.ok(msg.includes("GSD-Task: S01/T02"), "GSD-Task trailer present");
|
|
14
15
|
});
|
|
15
16
|
|
|
16
17
|
it("includes both key files and Resolves #N", () => {
|
|
@@ -22,10 +23,13 @@ describe("commit linking", () => {
|
|
|
22
23
|
});
|
|
23
24
|
assert.ok(msg.includes("- src/auth.ts"), "key files present");
|
|
24
25
|
assert.ok(msg.includes("Resolves #43"), "Resolves trailer present");
|
|
25
|
-
|
|
26
|
+
assert.ok(msg.includes("GSD-Task: S01/T02"), "GSD-Task trailer present");
|
|
27
|
+
// GSD-Task should come after key files but before Resolves
|
|
26
28
|
const keyFilesIdx = msg.indexOf("- src/auth.ts");
|
|
29
|
+
const taskIdx = msg.indexOf("GSD-Task: S01/T02");
|
|
27
30
|
const resolvesIdx = msg.indexOf("Resolves #43");
|
|
28
|
-
assert.ok(
|
|
31
|
+
assert.ok(taskIdx > keyFilesIdx, "GSD-Task after key files");
|
|
32
|
+
assert.ok(resolvesIdx > taskIdx, "Resolves after GSD-Task");
|
|
29
33
|
});
|
|
30
34
|
|
|
31
35
|
it("no Resolves trailer when issueNumber is not set", () => {
|
|
@@ -34,6 +38,6 @@ describe("commit linking", () => {
|
|
|
34
38
|
taskTitle: "implement auth",
|
|
35
39
|
});
|
|
36
40
|
assert.ok(!msg.includes("Resolves"), "no Resolves when no issueNumber");
|
|
37
|
-
assert.ok(
|
|
41
|
+
assert.ok(msg.includes("GSD-Task: S01/T02"), "GSD-Task trailer still present");
|
|
38
42
|
});
|
|
39
43
|
});
|
|
@@ -18,6 +18,7 @@ export const INFRA_ERROR_CODES: ReadonlySet<string> = new Set([
|
|
|
18
18
|
"EDQUOT", // disk quota exceeded
|
|
19
19
|
"EMFILE", // too many open files (process)
|
|
20
20
|
"ENFILE", // too many open files (system)
|
|
21
|
+
"EAGAIN", // resource temporarily unavailable (resource exhaustion)
|
|
21
22
|
"ECONNREFUSED", // connection refused (offline / local server down)
|
|
22
23
|
"ENOTFOUND", // DNS lookup failed (offline / no network)
|
|
23
24
|
"ENETUNREACH", // network unreachable (offline / no route)
|
|
@@ -1039,17 +1039,16 @@ export async function runUnitPhase(
|
|
|
1039
1039
|
);
|
|
1040
1040
|
|
|
1041
1041
|
// Tag the most recent window entry with error info for stuck detection
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
if (
|
|
1042
|
+
const lastEntry = loopState.recentUnits[loopState.recentUnits.length - 1];
|
|
1043
|
+
if (lastEntry) {
|
|
1044
|
+
if (unitResult.errorContext) {
|
|
1045
|
+
lastEntry.error = `${unitResult.errorContext.category}:${unitResult.errorContext.message}`.slice(0, 200);
|
|
1046
|
+
} else if (unitResult.status === "error" || unitResult.status === "cancelled") {
|
|
1045
1047
|
lastEntry.error = `${unitResult.status}:${unitType}/${unitId}`;
|
|
1046
|
-
}
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
if (/error|fail|exception/i.test(msgStr)) {
|
|
1051
|
-
const lastEntry = loopState.recentUnits[loopState.recentUnits.length - 1];
|
|
1052
|
-
if (lastEntry) {
|
|
1048
|
+
} else if (unitResult.event?.messages?.length) {
|
|
1049
|
+
const lastMsg = unitResult.event.messages[unitResult.event.messages.length - 1];
|
|
1050
|
+
const msgStr = typeof lastMsg === "string" ? lastMsg : JSON.stringify(lastMsg);
|
|
1051
|
+
if (/error|fail|exception/i.test(msgStr)) {
|
|
1053
1052
|
lastEntry.error = msgStr.slice(0, 200);
|
|
1054
1053
|
}
|
|
1055
1054
|
}
|
|
@@ -1122,7 +1121,7 @@ export async function runUnitPhase(
|
|
|
1122
1121
|
s.unitRecoveryCount.delete(`${unitType}/${unitId}`);
|
|
1123
1122
|
}
|
|
1124
1123
|
|
|
1125
|
-
deps.emitJournalEvent({ ts: new Date().toISOString(), flowId: ic.flowId, seq: ic.nextSeq(), eventType: "unit-end", data: { unitType, unitId, status: unitResult.status, artifactVerified }, causedBy: { flowId: ic.flowId, seq: unitStartSeq } });
|
|
1124
|
+
deps.emitJournalEvent({ ts: new Date().toISOString(), flowId: ic.flowId, seq: ic.nextSeq(), eventType: "unit-end", data: { unitType, unitId, status: unitResult.status, artifactVerified, ...(unitResult.errorContext ? { errorContext: unitResult.errorContext } : {}) }, causedBy: { flowId: ic.flowId, seq: unitStartSeq } });
|
|
1126
1125
|
|
|
1127
1126
|
return { action: "next", data: { unitStartedAt: s.currentUnit.startedAt } };
|
|
1128
1127
|
}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* Imports from: auto/types
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import type { UnitResult, AgentEndEvent } from "./types.js";
|
|
11
|
+
import type { UnitResult, AgentEndEvent, ErrorContext } from "./types.js";
|
|
12
12
|
import type { AutoSession } from "./session.js";
|
|
13
13
|
import { debugLog } from "../debug-logger.js";
|
|
14
14
|
|
|
@@ -77,12 +77,12 @@ export function isSessionSwitchInFlight(): boolean {
|
|
|
77
77
|
* blocks to ensure the autoLoop is never stuck awaiting a promise that
|
|
78
78
|
* will never resolve. Safe to call when no resolver is pending (no-op).
|
|
79
79
|
*/
|
|
80
|
-
export function resolveAgentEndCancelled(): void {
|
|
80
|
+
export function resolveAgentEndCancelled(errorContext?: ErrorContext): void {
|
|
81
81
|
if (_currentResolve) {
|
|
82
82
|
debugLog("resolveAgentEndCancelled", { status: "resolving-cancelled" });
|
|
83
83
|
const r = _currentResolve;
|
|
84
84
|
_currentResolve = null;
|
|
85
|
-
r({ status: "cancelled" });
|
|
85
|
+
r({ status: "cancelled", ...(errorContext ? { errorContext } : {}) });
|
|
86
86
|
}
|
|
87
87
|
}
|
|
88
88
|
|
|
@@ -58,13 +58,13 @@ export async function runUnit(
|
|
|
58
58
|
unitId,
|
|
59
59
|
error: msg,
|
|
60
60
|
});
|
|
61
|
-
return { status: "cancelled" };
|
|
61
|
+
return { status: "cancelled", errorContext: { message: `Session creation failed: ${msg}`, category: "session-failed", isTransient: true } };
|
|
62
62
|
}
|
|
63
63
|
if (sessionTimeoutHandle) clearTimeout(sessionTimeoutHandle);
|
|
64
64
|
|
|
65
65
|
if (sessionResult.cancelled) {
|
|
66
66
|
debugLog("runUnit-session-timeout", { unitType, unitId });
|
|
67
|
-
return { status: "cancelled" };
|
|
67
|
+
return { status: "cancelled", errorContext: { message: "Session creation timed out", category: "timeout", isTransient: true } };
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
if (!s.active) {
|
|
@@ -118,6 +118,10 @@ export class AutoSession {
|
|
|
118
118
|
// ── Sidecar queue ─────────────────────────────────────────────────────
|
|
119
119
|
sidecarQueue: SidecarItem[] = [];
|
|
120
120
|
|
|
121
|
+
// ── Isolation degradation ────────────────────────────────────────────
|
|
122
|
+
/** Set to true when worktree creation fails; prevents merge of nonexistent branch. */
|
|
123
|
+
isolationDegraded = false;
|
|
124
|
+
|
|
121
125
|
// ── Dispatch circuit breakers ──────────────────────────────────────
|
|
122
126
|
rewriteAttemptCount = 0;
|
|
123
127
|
|
|
@@ -200,6 +204,7 @@ export class AutoSession {
|
|
|
200
204
|
this.pendingQuickTasks = [];
|
|
201
205
|
this.sidecarQueue = [];
|
|
202
206
|
this.rewriteAttemptCount = 0;
|
|
207
|
+
this.isolationDegraded = false;
|
|
203
208
|
|
|
204
209
|
// Signal handler
|
|
205
210
|
this.sigtermHandler = null;
|
|
@@ -47,12 +47,25 @@ export interface AgentEndEvent {
|
|
|
47
47
|
messages: unknown[];
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
+
/**
|
|
51
|
+
* Structured error context attached to a UnitResult when the unit ends
|
|
52
|
+
* due to an infrastructure or timeout error (not user-driven cancellation).
|
|
53
|
+
*/
|
|
54
|
+
export interface ErrorContext {
|
|
55
|
+
message: string;
|
|
56
|
+
category: "provider" | "timeout" | "idle" | "network" | "aborted" | "session-failed" | "unknown";
|
|
57
|
+
stopReason?: string;
|
|
58
|
+
isTransient?: boolean;
|
|
59
|
+
retryAfterMs?: number;
|
|
60
|
+
}
|
|
61
|
+
|
|
50
62
|
/**
|
|
51
63
|
* Result of a single unit execution (one iteration of the loop).
|
|
52
64
|
*/
|
|
53
65
|
export interface UnitResult {
|
|
54
66
|
status: "completed" | "cancelled" | "error";
|
|
55
67
|
event?: AgentEndEvent;
|
|
68
|
+
errorContext?: ErrorContext;
|
|
56
69
|
}
|
|
57
70
|
|
|
58
71
|
// ─── Phase pipeline types ────────────────────────────────────────────────────
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
buildSliceFileName,
|
|
14
14
|
buildTaskFileName,
|
|
15
15
|
} from "./paths.js";
|
|
16
|
+
import { parseUnitId } from "./unit-id.js";
|
|
16
17
|
import { join } from "node:path";
|
|
17
18
|
|
|
18
19
|
/**
|
|
@@ -23,9 +24,7 @@ export function resolveExpectedArtifactPath(
|
|
|
23
24
|
unitId: string,
|
|
24
25
|
base: string,
|
|
25
26
|
): string | null {
|
|
26
|
-
const
|
|
27
|
-
const mid = parts[0]!;
|
|
28
|
-
const sid = parts[1];
|
|
27
|
+
const { milestone: mid, slice: sid, task: tid } = parseUnitId(unitId);
|
|
29
28
|
switch (unitType) {
|
|
30
29
|
case "discuss-milestone": {
|
|
31
30
|
const dir = resolveMilestonePath(base, mid);
|
|
@@ -53,10 +52,9 @@ export function resolveExpectedArtifactPath(
|
|
|
53
52
|
}
|
|
54
53
|
case "run-uat": {
|
|
55
54
|
const dir = resolveSlicePath(base, mid, sid!);
|
|
56
|
-
return dir ? join(dir, buildSliceFileName(sid!, "UAT
|
|
55
|
+
return dir ? join(dir, buildSliceFileName(sid!, "UAT")) : null;
|
|
57
56
|
}
|
|
58
57
|
case "execute-task": {
|
|
59
|
-
const tid = parts[2];
|
|
60
58
|
const dir = resolveSlicePath(base, mid, sid!);
|
|
61
59
|
return dir && tid
|
|
62
60
|
? join(dir, "tasks", buildTaskFileName(tid, "SUMMARY"))
|
|
@@ -80,6 +78,9 @@ export function resolveExpectedArtifactPath(
|
|
|
80
78
|
}
|
|
81
79
|
case "rewrite-docs":
|
|
82
80
|
return null;
|
|
81
|
+
case "gate-evaluate":
|
|
82
|
+
// Gate evaluate writes to DB quality_gates table — verified via state derivation
|
|
83
|
+
return null;
|
|
83
84
|
case "reactive-execute":
|
|
84
85
|
// Reactive execute produces multiple task summaries — verified separately
|
|
85
86
|
return null;
|
|
@@ -93,38 +94,35 @@ export function diagnoseExpectedArtifact(
|
|
|
93
94
|
unitId: string,
|
|
94
95
|
base: string,
|
|
95
96
|
): string | null {
|
|
96
|
-
const
|
|
97
|
-
const mid = parts[0];
|
|
98
|
-
const sid = parts[1];
|
|
97
|
+
const { milestone: mid, slice: sid, task: tid } = parseUnitId(unitId);
|
|
99
98
|
switch (unitType) {
|
|
100
99
|
case "discuss-milestone":
|
|
101
|
-
return `${relMilestoneFile(base, mid
|
|
100
|
+
return `${relMilestoneFile(base, mid, "CONTEXT")} (milestone context from discussion)`;
|
|
102
101
|
case "research-milestone":
|
|
103
|
-
return `${relMilestoneFile(base, mid
|
|
102
|
+
return `${relMilestoneFile(base, mid, "RESEARCH")} (milestone research)`;
|
|
104
103
|
case "plan-milestone":
|
|
105
|
-
return `${relMilestoneFile(base, mid
|
|
104
|
+
return `${relMilestoneFile(base, mid, "ROADMAP")} (milestone roadmap)`;
|
|
106
105
|
case "research-slice":
|
|
107
|
-
return `${relSliceFile(base, mid
|
|
106
|
+
return `${relSliceFile(base, mid, sid!, "RESEARCH")} (slice research)`;
|
|
108
107
|
case "plan-slice":
|
|
109
|
-
return `${relSliceFile(base, mid
|
|
108
|
+
return `${relSliceFile(base, mid, sid!, "PLAN")} (slice plan)`;
|
|
110
109
|
case "execute-task": {
|
|
111
|
-
|
|
112
|
-
return `Task ${tid} marked [x] in ${relSliceFile(base, mid!, sid!, "PLAN")} + summary written`;
|
|
110
|
+
return `Task ${tid} marked [x] in ${relSliceFile(base, mid, sid!, "PLAN")} + summary written`;
|
|
113
111
|
}
|
|
114
112
|
case "complete-slice":
|
|
115
|
-
return `Slice ${sid} marked [x] in ${relMilestoneFile(base, mid
|
|
113
|
+
return `Slice ${sid} marked [x] in ${relMilestoneFile(base, mid, "ROADMAP")} + summary + UAT written`;
|
|
116
114
|
case "replan-slice":
|
|
117
|
-
return `${relSliceFile(base, mid
|
|
115
|
+
return `${relSliceFile(base, mid, sid!, "REPLAN")} + updated ${relSliceFile(base, mid, sid!, "PLAN")}`;
|
|
118
116
|
case "rewrite-docs":
|
|
119
117
|
return "Active overrides resolved in .gsd/OVERRIDES.md + plan documents updated";
|
|
120
118
|
case "reassess-roadmap":
|
|
121
|
-
return `${relSliceFile(base, mid
|
|
119
|
+
return `${relSliceFile(base, mid, sid!, "ASSESSMENT")} (roadmap reassessment)`;
|
|
122
120
|
case "run-uat":
|
|
123
|
-
return `${relSliceFile(base, mid
|
|
121
|
+
return `${relSliceFile(base, mid, sid!, "UAT")} (UAT result)`;
|
|
124
122
|
case "validate-milestone":
|
|
125
|
-
return `${relMilestoneFile(base, mid
|
|
123
|
+
return `${relMilestoneFile(base, mid, "VALIDATION")} (milestone validation report)`;
|
|
126
124
|
case "complete-milestone":
|
|
127
|
-
return `${relMilestoneFile(base, mid
|
|
125
|
+
return `${relMilestoneFile(base, mid, "SUMMARY")} (milestone summary)`;
|
|
128
126
|
default:
|
|
129
127
|
return null;
|
|
130
128
|
}
|
|
@@ -25,6 +25,7 @@ import { computeProgressScore } from "./progress-score.js";
|
|
|
25
25
|
import { getActiveWorktreeName } from "./worktree-command.js";
|
|
26
26
|
import { loadEffectiveGSDPreferences, getGlobalGSDPreferencesPath } from "./preferences.js";
|
|
27
27
|
import { resolveServiceTierIcon, getEffectiveServiceTier } from "./service-tier.js";
|
|
28
|
+
import { parseUnitId } from "./unit-id.js";
|
|
28
29
|
|
|
29
30
|
// ─── UAT Slice Extraction ─────────────────────────────────────────────────────
|
|
30
31
|
|
|
@@ -33,8 +34,8 @@ import { resolveServiceTierIcon, getEffectiveServiceTier } from "./service-tier.
|
|
|
33
34
|
* Returns null if the format doesn't match.
|
|
34
35
|
*/
|
|
35
36
|
export function extractUatSliceId(unitId: string): string | null {
|
|
36
|
-
const
|
|
37
|
-
if (
|
|
37
|
+
const { slice } = parseUnitId(unitId);
|
|
38
|
+
if (slice?.startsWith("S")) return slice;
|
|
38
39
|
return null;
|
|
39
40
|
}
|
|
40
41
|
|
|
@@ -151,6 +152,8 @@ export function describeNextUnit(state: GSDState): { label: string; description:
|
|
|
151
152
|
return { label: `Replan ${sid}: ${sTitle}`, description: "Blocker found — replan the slice." };
|
|
152
153
|
case "completing-milestone":
|
|
153
154
|
return { label: "Complete milestone", description: "Write milestone summary." };
|
|
155
|
+
case "evaluating-gates":
|
|
156
|
+
return { label: `Evaluate gates for ${sid}: ${sTitle}`, description: "Parallel quality gate assessment before execution." };
|
|
154
157
|
default:
|
|
155
158
|
return { label: "Continue", description: "Execute the next step." };
|
|
156
159
|
}
|
|
@@ -13,7 +13,8 @@ import type { GSDState } from "./types.js";
|
|
|
13
13
|
import type { GSDPreferences } from "./preferences.js";
|
|
14
14
|
import type { UatType } from "./files.js";
|
|
15
15
|
import { loadFile, extractUatType, loadActiveOverrides } from "./files.js";
|
|
16
|
-
import { isDbAvailable, getMilestoneSlices } from "./gsd-db.js";
|
|
16
|
+
import { isDbAvailable, getMilestoneSlices, getPendingGates, markAllGatesOmitted } from "./gsd-db.js";
|
|
17
|
+
import { extractVerdict, isAcceptableUatVerdict } from "./verdict-parser.js";
|
|
17
18
|
|
|
18
19
|
import {
|
|
19
20
|
resolveMilestoneFile,
|
|
@@ -43,6 +44,7 @@ import {
|
|
|
43
44
|
buildReassessRoadmapPrompt,
|
|
44
45
|
buildRewriteDocsPrompt,
|
|
45
46
|
buildReactiveExecutePrompt,
|
|
47
|
+
buildGateEvaluatePrompt,
|
|
46
48
|
checkNeedsReassessment,
|
|
47
49
|
checkNeedsRunUat,
|
|
48
50
|
} from "./auto-prompts.js";
|
|
@@ -184,13 +186,14 @@ export const DISPATCH_RULES: DispatchRule[] = [
|
|
|
184
186
|
}
|
|
185
187
|
|
|
186
188
|
for (const sliceId of completedSliceIds) {
|
|
187
|
-
const resultFile = resolveSliceFile(basePath, mid, sliceId, "UAT
|
|
189
|
+
const resultFile = resolveSliceFile(basePath, mid, sliceId, "UAT");
|
|
188
190
|
if (!resultFile) continue;
|
|
189
191
|
const content = await loadFile(resultFile);
|
|
190
192
|
if (!content) continue;
|
|
191
|
-
const
|
|
192
|
-
const
|
|
193
|
-
|
|
193
|
+
const verdict = extractVerdict(content);
|
|
194
|
+
const uatType = extractUatType(content);
|
|
195
|
+
|
|
196
|
+
if (verdict && !isAcceptableUatVerdict(verdict, uatType)) {
|
|
194
197
|
return {
|
|
195
198
|
action: "stop" as const,
|
|
196
199
|
reason: `UAT verdict for ${sliceId} is "${verdict}" — blocking progression until resolved.\nReview the UAT result and update the verdict to PASS, or re-run /gsd auto after fixing.`,
|
|
@@ -331,6 +334,38 @@ export const DISPATCH_RULES: DispatchRule[] = [
|
|
|
331
334
|
};
|
|
332
335
|
},
|
|
333
336
|
},
|
|
337
|
+
{
|
|
338
|
+
name: "evaluating-gates → gate-evaluate",
|
|
339
|
+
match: async ({ state, mid, midTitle, basePath, prefs }) => {
|
|
340
|
+
if (state.phase !== "evaluating-gates") return null;
|
|
341
|
+
if (!state.activeSlice) return missingSliceStop(mid, state.phase);
|
|
342
|
+
const sid = state.activeSlice.id;
|
|
343
|
+
const sTitle = state.activeSlice.title;
|
|
344
|
+
|
|
345
|
+
// Gate evaluation is opt-in via preferences
|
|
346
|
+
const gateConfig = prefs?.gate_evaluation;
|
|
347
|
+
if (!gateConfig?.enabled) {
|
|
348
|
+
markAllGatesOmitted(mid, sid);
|
|
349
|
+
return { action: "skip" };
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
const pending = getPendingGates(mid, sid, "slice");
|
|
353
|
+
if (pending.length === 0) return { action: "skip" };
|
|
354
|
+
|
|
355
|
+
return {
|
|
356
|
+
action: "dispatch",
|
|
357
|
+
unitType: "gate-evaluate",
|
|
358
|
+
unitId: `${mid}/${sid}/gates+${pending.map(g => g.gate_id).join(",")}`,
|
|
359
|
+
prompt: await buildGateEvaluatePrompt(
|
|
360
|
+
mid,
|
|
361
|
+
midTitle,
|
|
362
|
+
sid,
|
|
363
|
+
sTitle,
|
|
364
|
+
basePath,
|
|
365
|
+
),
|
|
366
|
+
};
|
|
367
|
+
},
|
|
368
|
+
},
|
|
334
369
|
{
|
|
335
370
|
name: "replanning-slice → replan-slice",
|
|
336
371
|
match: async ({ state, mid, midTitle, basePath }) => {
|
|
@@ -13,4 +13,4 @@ export { resolveAgentEnd, resolveAgentEndCancelled, isSessionSwitchInFlight, _re
|
|
|
13
13
|
export { detectStuck } from "./auto/detect-stuck.js";
|
|
14
14
|
export { runUnit } from "./auto/run-unit.js";
|
|
15
15
|
export type { LoopDeps } from "./auto/loop-deps.js";
|
|
16
|
-
export type { AgentEndEvent, UnitResult } from "./auto/types.js";
|
|
16
|
+
export type { AgentEndEvent, ErrorContext, UnitResult } from "./auto/types.js";
|
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
buildTaskFileName,
|
|
24
24
|
} from "./paths.js";
|
|
25
25
|
import { invalidateAllCaches } from "./cache.js";
|
|
26
|
+
import { parseUnitId } from "./unit-id.js";
|
|
26
27
|
import { closeoutUnit, type CloseoutOptions } from "./auto-unit-closeout.js";
|
|
27
28
|
import {
|
|
28
29
|
autoCommitCurrentBranch,
|
|
@@ -33,7 +34,7 @@ import {
|
|
|
33
34
|
resolveExpectedArtifactPath,
|
|
34
35
|
} from "./auto-recovery.js";
|
|
35
36
|
import { regenerateIfMissing } from "./workflow-projections.js";
|
|
36
|
-
import { syncStateToProjectRoot } from "./auto-worktree
|
|
37
|
+
import { syncStateToProjectRoot } from "./auto-worktree.js";
|
|
37
38
|
import { isDbAvailable, getTask, getSlice, getMilestone, updateTaskStatus, _getAdapter } from "./gsd-db.js";
|
|
38
39
|
import { renderPlanCheckboxes } from "./markdown-renderer.js";
|
|
39
40
|
import { consumeSignal } from "./session-status-io.js";
|
|
@@ -47,6 +48,16 @@ import {
|
|
|
47
48
|
import { hasPendingCaptures, loadPendingCaptures } from "./captures.js";
|
|
48
49
|
import { debugLog } from "./debug-logger.js";
|
|
49
50
|
import type { AutoSession } from "./auto/session.js";
|
|
51
|
+
|
|
52
|
+
/** Unit types that only touch `.gsd/` internal state files (no code changes).
|
|
53
|
+
* Auto-commit is skipped for these — their state files are picked up by the
|
|
54
|
+
* next actual task commit via `smartStage()`. */
|
|
55
|
+
const LIFECYCLE_ONLY_UNITS = new Set([
|
|
56
|
+
"research-milestone", "discuss-milestone", "plan-milestone",
|
|
57
|
+
"validate-milestone", "research-slice", "plan-slice",
|
|
58
|
+
"replan-slice", "complete-slice", "run-uat",
|
|
59
|
+
"reassess-roadmap", "rewrite-docs",
|
|
60
|
+
]);
|
|
50
61
|
import {
|
|
51
62
|
updateProgressWidget as _updateProgressWidget,
|
|
52
63
|
updateSliceProgressCache,
|
|
@@ -74,6 +85,15 @@ export interface RogueFileWrite {
|
|
|
74
85
|
* in postUnitPostVerification() eventually ingests rogue files, but explicit
|
|
75
86
|
* detection provides immediate diagnostics so operators know the prompt failed.
|
|
76
87
|
*/
|
|
88
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
89
|
+
function hasNonEmptyFields(row: Record<string, any> | null, fields: string[]): boolean {
|
|
90
|
+
if (!row) return false;
|
|
91
|
+
return fields.some(f => String(row[f] || "").trim().length > 0);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const MILESTONE_PLANNING_FIELDS = ["title", "vision", "requirement_coverage", "boundary_map_markdown"];
|
|
95
|
+
const SLICE_PLANNING_FIELDS = ["title", "demo", "risk", "depends"];
|
|
96
|
+
|
|
77
97
|
export function detectRogueFileWrites(
|
|
78
98
|
unitType: string,
|
|
79
99
|
unitId: string,
|
|
@@ -81,11 +101,10 @@ export function detectRogueFileWrites(
|
|
|
81
101
|
): RogueFileWrite[] {
|
|
82
102
|
if (!isDbAvailable()) return [];
|
|
83
103
|
|
|
84
|
-
const
|
|
104
|
+
const { milestone: mid, slice: sid, task: tid } = parseUnitId(unitId);
|
|
85
105
|
const rogues: RogueFileWrite[] = [];
|
|
86
106
|
|
|
87
107
|
if (unitType === "execute-task") {
|
|
88
|
-
const [mid, sid, tid] = parts;
|
|
89
108
|
if (!mid || !sid || !tid) return [];
|
|
90
109
|
|
|
91
110
|
const summaryPath = resolveTaskFile(basePath, mid, sid, tid, "SUMMARY");
|
|
@@ -96,7 +115,6 @@ export function detectRogueFileWrites(
|
|
|
96
115
|
rogues.push({ path: summaryPath, unitType, unitId });
|
|
97
116
|
}
|
|
98
117
|
} else if (unitType === "complete-slice") {
|
|
99
|
-
const [mid, sid] = parts;
|
|
100
118
|
if (!mid || !sid) return [];
|
|
101
119
|
|
|
102
120
|
const summaryPath = resolveSliceFile(basePath, mid, sid, "SUMMARY");
|
|
@@ -107,37 +125,25 @@ export function detectRogueFileWrites(
|
|
|
107
125
|
rogues.push({ path: summaryPath, unitType, unitId });
|
|
108
126
|
}
|
|
109
127
|
} else if (unitType === "plan-milestone") {
|
|
110
|
-
const [mid] = parts;
|
|
111
128
|
if (!mid) return [];
|
|
112
129
|
|
|
113
130
|
const roadmapPath = resolveMilestoneFile(basePath, mid, "ROADMAP");
|
|
114
131
|
if (!roadmapPath || !existsSync(roadmapPath)) return [];
|
|
115
132
|
|
|
116
133
|
const dbRow = getMilestone(mid);
|
|
117
|
-
const hasPlanningState =
|
|
118
|
-
String(dbRow.title || "").trim().length > 0 ||
|
|
119
|
-
String(dbRow.vision || "").trim().length > 0 ||
|
|
120
|
-
String(dbRow.requirement_coverage || "").trim().length > 0 ||
|
|
121
|
-
String(dbRow.boundary_map_markdown || "").trim().length > 0
|
|
122
|
-
);
|
|
134
|
+
const hasPlanningState = hasNonEmptyFields(dbRow, MILESTONE_PLANNING_FIELDS);
|
|
123
135
|
|
|
124
136
|
if (!hasPlanningState) {
|
|
125
137
|
rogues.push({ path: roadmapPath, unitType, unitId });
|
|
126
138
|
}
|
|
127
139
|
} else if (unitType === "plan-slice" || unitType === "replan-slice") {
|
|
128
|
-
const [mid, sid] = parts;
|
|
129
140
|
if (!mid || !sid) return [];
|
|
130
141
|
|
|
131
142
|
const planPath = resolveSliceFile(basePath, mid, sid, "PLAN");
|
|
132
143
|
if (!planPath || !existsSync(planPath)) return [];
|
|
133
144
|
|
|
134
145
|
const dbRow = getSlice(mid, sid);
|
|
135
|
-
const hasPlanningState =
|
|
136
|
-
String(dbRow.title || "").trim().length > 0 ||
|
|
137
|
-
String(dbRow.demo || "").trim().length > 0 ||
|
|
138
|
-
String(dbRow.risk || "").trim().length > 0 ||
|
|
139
|
-
String(dbRow.depends || "").trim().length > 0
|
|
140
|
-
);
|
|
146
|
+
const hasPlanningState = hasNonEmptyFields(dbRow, SLICE_PLANNING_FIELDS);
|
|
141
147
|
|
|
142
148
|
if (!hasPlanningState) {
|
|
143
149
|
rogues.push({ path: planPath, unitType, unitId });
|
|
@@ -149,7 +155,6 @@ export function detectRogueFileWrites(
|
|
|
149
155
|
rogues.push({ path: replanPath, unitType, unitId });
|
|
150
156
|
}
|
|
151
157
|
} else if (unitType === "reassess-roadmap") {
|
|
152
|
-
const [mid, sid] = parts;
|
|
153
158
|
if (!mid || !sid) return [];
|
|
154
159
|
|
|
155
160
|
const assessPath = resolveSliceFile(basePath, mid, sid, "ASSESSMENT");
|
|
@@ -166,7 +171,6 @@ export function detectRogueFileWrites(
|
|
|
166
171
|
}
|
|
167
172
|
}
|
|
168
173
|
} else if (unitType === "plan-task") {
|
|
169
|
-
const [mid, sid, tid] = parts;
|
|
170
174
|
if (!mid || !sid || !tid) return [];
|
|
171
175
|
|
|
172
176
|
const taskPlanPath = resolveTaskFile(basePath, mid, sid, tid, "PLAN");
|
|
@@ -239,8 +243,7 @@ export async function postUnitPreVerification(pctx: PostUnitContext, opts?: PreV
|
|
|
239
243
|
let taskContext: TaskCommitContext | undefined;
|
|
240
244
|
|
|
241
245
|
if (s.currentUnit.type === "execute-task") {
|
|
242
|
-
const
|
|
243
|
-
const [mid, sid, tid] = parts;
|
|
246
|
+
const { milestone: mid, slice: sid, task: tid } = parseUnitId(s.currentUnit.id);
|
|
244
247
|
if (mid && sid && tid) {
|
|
245
248
|
const summaryPath = resolveTaskFile(s.basePath, mid, sid, tid, "SUMMARY");
|
|
246
249
|
if (summaryPath) {
|
|
@@ -279,9 +282,14 @@ export async function postUnitPreVerification(pctx: PostUnitContext, opts?: PreV
|
|
|
279
282
|
// `git worktree remove --force` during teardown.
|
|
280
283
|
_resetHasChangesCache();
|
|
281
284
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
+
// Skip auto-commit for lifecycle-only units (#2553) — they only touch
|
|
286
|
+
// `.gsd/` internal state files. Those files are picked up by the next
|
|
287
|
+
// actual task commit via smartStage().
|
|
288
|
+
if (!LIFECYCLE_ONLY_UNITS.has(s.currentUnit.type)) {
|
|
289
|
+
const commitMsg = autoCommitCurrentBranch(s.basePath, s.currentUnit.type, s.currentUnit.id, taskContext);
|
|
290
|
+
if (commitMsg) {
|
|
291
|
+
ctx.ui.notify(`Committed: ${commitMsg.split("\n")[0]}`, "info");
|
|
292
|
+
}
|
|
285
293
|
}
|
|
286
294
|
} catch (e) {
|
|
287
295
|
debugLog("postUnit", { phase: "auto-commit", error: String(e) });
|
|
@@ -339,8 +347,7 @@ export async function postUnitPreVerification(pctx: PostUnitContext, opts?: PreV
|
|
|
339
347
|
// Reactive state cleanup on slice completion
|
|
340
348
|
if (s.currentUnit.type === "complete-slice") {
|
|
341
349
|
try {
|
|
342
|
-
const
|
|
343
|
-
const [mid, sid] = parts;
|
|
350
|
+
const { milestone: mid, slice: sid } = parseUnitId(s.currentUnit.id);
|
|
344
351
|
if (mid && sid) {
|
|
345
352
|
const { clearReactiveState } = await import("./reactive-graph.js");
|
|
346
353
|
clearReactiveState(s.basePath, mid, sid);
|
|
@@ -425,8 +432,7 @@ export async function postUnitPreVerification(pctx: PostUnitContext, opts?: PreV
|
|
|
425
432
|
// from DB data before giving up (e.g. research-slice produces PLAN from engine).
|
|
426
433
|
if (!triggerArtifactVerified) {
|
|
427
434
|
try {
|
|
428
|
-
const
|
|
429
|
-
const [mid, sid] = parts;
|
|
435
|
+
const { milestone: mid, slice: sid } = parseUnitId(s.currentUnit.id);
|
|
430
436
|
if (mid && sid) {
|
|
431
437
|
const regenerated = regenerateIfMissing(s.basePath, mid, sid, "PLAN");
|
|
432
438
|
if (regenerated) {
|
|
@@ -526,8 +532,7 @@ export async function postUnitPostVerification(pctx: PostUnitContext): Promise<"
|
|
|
526
532
|
|
|
527
533
|
// ── State reset: undo the completion so deriveState re-derives the unit ──
|
|
528
534
|
try {
|
|
529
|
-
const
|
|
530
|
-
const [mid, sid, tid] = parts;
|
|
535
|
+
const { milestone: mid, slice: sid, task: tid } = parseUnitId(trigger.unitId);
|
|
531
536
|
|
|
532
537
|
// 1. Reset task status in DB and re-render plan checkboxes
|
|
533
538
|
if (mid && sid && tid) {
|