gsd-pi 2.60.0-dev.d9052f5 → 2.61.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/resources/extensions/ask-user-questions.js +7 -4
- package/dist/resources/extensions/gsd/auto/phases.js +15 -7
- package/dist/resources/extensions/gsd/auto-dashboard.js +21 -8
- package/dist/resources/extensions/gsd/auto-dispatch.js +6 -3
- package/dist/resources/extensions/gsd/auto-model-selection.js +58 -9
- package/dist/resources/extensions/gsd/auto-post-unit.js +3 -2
- package/dist/resources/extensions/gsd/auto-prompts.js +36 -20
- package/dist/resources/extensions/gsd/auto-recovery.js +37 -18
- package/dist/resources/extensions/gsd/auto-start.js +9 -5
- package/dist/resources/extensions/gsd/auto-timers.js +11 -5
- package/dist/resources/extensions/gsd/auto-unit-closeout.js +5 -3
- package/dist/resources/extensions/gsd/auto-verification.js +3 -2
- package/dist/resources/extensions/gsd/auto-worktree.js +120 -55
- package/dist/resources/extensions/gsd/auto.js +39 -17
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +6 -3
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +2 -2
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +4 -10
- package/dist/resources/extensions/gsd/bootstrap/journal-tools.js +2 -1
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +7 -0
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +11 -10
- package/dist/resources/extensions/gsd/commands/catalog.js +2 -0
- package/dist/resources/extensions/gsd/commands-codebase.js +48 -21
- package/dist/resources/extensions/gsd/commands-inspect.js +2 -1
- package/dist/resources/extensions/gsd/commands-maintenance.js +32 -19
- package/dist/resources/extensions/gsd/complexity-classifier.js +8 -4
- package/dist/resources/extensions/gsd/custom-verification.js +3 -2
- package/dist/resources/extensions/gsd/gsd-db.js +33 -13
- package/dist/resources/extensions/gsd/guided-flow.js +19 -9
- package/dist/resources/extensions/gsd/init-wizard.js +12 -0
- package/dist/resources/extensions/gsd/markdown-renderer.js +11 -9
- package/dist/resources/extensions/gsd/md-importer.js +5 -4
- package/dist/resources/extensions/gsd/milestone-actions.js +3 -2
- package/dist/resources/extensions/gsd/milestone-ids.js +2 -1
- package/dist/resources/extensions/gsd/model-router.js +156 -121
- package/dist/resources/extensions/gsd/parallel-merge.js +5 -3
- package/dist/resources/extensions/gsd/parallel-orchestrator.js +26 -14
- package/dist/resources/extensions/gsd/preferences-types.js +1 -0
- package/dist/resources/extensions/gsd/preferences-validation.js +45 -0
- package/dist/resources/extensions/gsd/preferences.js +15 -3
- package/dist/resources/extensions/gsd/prompt-loader.js +3 -2
- package/dist/resources/extensions/gsd/prompts/rethink.md +1 -1
- package/dist/resources/extensions/gsd/rule-registry.js +7 -6
- package/dist/resources/extensions/gsd/safe-fs.js +6 -8
- package/dist/resources/extensions/gsd/tools/complete-milestone.js +3 -2
- package/dist/resources/extensions/gsd/tools/complete-slice.js +3 -2
- package/dist/resources/extensions/gsd/tools/complete-task.js +3 -2
- package/dist/resources/extensions/gsd/tools/plan-milestone.js +3 -2
- package/dist/resources/extensions/gsd/tools/plan-slice.js +3 -2
- package/dist/resources/extensions/gsd/tools/plan-task.js +2 -1
- package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +4 -4
- package/dist/resources/extensions/gsd/tools/reopen-slice.js +2 -1
- package/dist/resources/extensions/gsd/tools/reopen-task.js +2 -1
- package/dist/resources/extensions/gsd/tools/replan-slice.js +2 -1
- package/dist/resources/extensions/gsd/tools/validate-milestone.js +2 -1
- package/dist/resources/extensions/gsd/triage-resolution.js +11 -4
- package/dist/resources/extensions/gsd/workflow-events.js +2 -1
- package/dist/resources/extensions/gsd/workflow-logger.js +37 -4
- package/dist/resources/extensions/gsd/workflow-migration.js +14 -12
- package/dist/resources/extensions/gsd/workflow-projections.js +2 -2
- package/dist/resources/extensions/gsd/workflow-reconcile.js +2 -2
- package/dist/resources/extensions/gsd/worktree-manager.js +26 -14
- package/dist/resources/extensions/shared/interview-ui.js +3 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +14 -14
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/required-server-files.json +3 -3
- 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/experimental/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/experimental/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 +2 -2
- 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 +14 -14
- package/dist/web/standalone/.next/server/chunks/2229.js +1 -1
- package/dist/web/standalone/.next/server/chunks/7471.js +3 -3
- package/dist/web/standalone/.next/server/middleware-build-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/app/_not-found/{page-f2a7482d42a5614b.js → page-2f24283c162b6ab3.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/{layout-a16c7a7ecdf0c2cf.js → layout-9ecfd95f343793f0.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/page-62be3b5fa91e4c8f.js +1 -0
- package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +1 -0
- 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/package.json +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.js +5 -0
- package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +2 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.js +16 -0
- package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +26 -0
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/config.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/config.js +6 -1
- package/packages/pi-coding-agent/dist/core/lsp/config.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/defaults.json +2 -2
- package/packages/pi-coding-agent/dist/core/lsp/lsp-legacy-alias.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/lsp/lsp-legacy-alias.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/lsp/lsp-legacy-alias.test.js +47 -0
- package/packages/pi-coding-agent/dist/core/lsp/lsp-legacy-alias.test.js.map +1 -0
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/extensions/loader.ts +6 -0
- package/packages/pi-coding-agent/src/core/extensions/runner.ts +19 -0
- package/packages/pi-coding-agent/src/core/extensions/types.ts +26 -0
- package/packages/pi-coding-agent/src/core/lsp/config.ts +7 -1
- package/packages/pi-coding-agent/src/core/lsp/defaults.json +2 -2
- package/packages/pi-coding-agent/src/core/lsp/lsp-legacy-alias.test.ts +70 -0
- package/pkg/package.json +1 -1
- package/src/resources/extensions/ask-user-questions.ts +7 -3
- package/src/resources/extensions/gsd/auto/phases.ts +17 -7
- package/src/resources/extensions/gsd/auto-dashboard.ts +22 -8
- package/src/resources/extensions/gsd/auto-dispatch.ts +7 -3
- package/src/resources/extensions/gsd/auto-model-selection.ts +77 -15
- package/src/resources/extensions/gsd/auto-post-unit.ts +4 -4
- package/src/resources/extensions/gsd/auto-prompts.ts +37 -20
- package/src/resources/extensions/gsd/auto-recovery.ts +38 -18
- package/src/resources/extensions/gsd/auto-start.ts +10 -9
- package/src/resources/extensions/gsd/auto-timers.ts +12 -5
- package/src/resources/extensions/gsd/auto-unit-closeout.ts +6 -2
- package/src/resources/extensions/gsd/auto-verification.ts +3 -6
- package/src/resources/extensions/gsd/auto-worktree.ts +121 -55
- package/src/resources/extensions/gsd/auto.ts +40 -17
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +4 -3
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +2 -2
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +4 -16
- package/src/resources/extensions/gsd/bootstrap/journal-tools.ts +2 -1
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +8 -0
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +11 -10
- package/src/resources/extensions/gsd/commands/catalog.ts +2 -0
- package/src/resources/extensions/gsd/commands-codebase.ts +52 -20
- package/src/resources/extensions/gsd/commands-inspect.ts +2 -1
- package/src/resources/extensions/gsd/commands-maintenance.ts +28 -19
- package/src/resources/extensions/gsd/complexity-classifier.ts +9 -4
- package/src/resources/extensions/gsd/custom-verification.ts +3 -2
- package/src/resources/extensions/gsd/gsd-db.ts +12 -14
- package/src/resources/extensions/gsd/guided-flow.ts +9 -8
- package/src/resources/extensions/gsd/init-wizard.ts +12 -0
- package/src/resources/extensions/gsd/markdown-renderer.ts +11 -17
- package/src/resources/extensions/gsd/md-importer.ts +5 -4
- package/src/resources/extensions/gsd/milestone-actions.ts +3 -2
- package/src/resources/extensions/gsd/milestone-ids.ts +2 -1
- package/src/resources/extensions/gsd/model-router.ts +199 -173
- package/src/resources/extensions/gsd/parallel-merge.ts +5 -3
- package/src/resources/extensions/gsd/parallel-orchestrator.ts +18 -14
- package/src/resources/extensions/gsd/preferences-types.ts +13 -0
- package/src/resources/extensions/gsd/preferences-validation.ts +45 -0
- package/src/resources/extensions/gsd/preferences.ts +16 -3
- package/src/resources/extensions/gsd/prompt-loader.ts +3 -2
- package/src/resources/extensions/gsd/prompts/rethink.md +1 -1
- package/src/resources/extensions/gsd/rule-registry.ts +7 -6
- package/src/resources/extensions/gsd/safe-fs.ts +6 -5
- package/src/resources/extensions/gsd/tests/capability-router.test.ts +347 -0
- package/src/resources/extensions/gsd/tests/codebase-generator.test.ts +63 -0
- package/src/resources/extensions/gsd/tests/complexity-classifier.test.ts +27 -2
- package/src/resources/extensions/gsd/tests/db-path-worktree-symlink.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts +1188 -0
- package/src/resources/extensions/gsd/tests/integration/state-machine-runtime-failures.test.ts +841 -0
- package/src/resources/extensions/gsd/tests/model-router.test.ts +403 -3
- package/src/resources/extensions/gsd/tests/preferences.test.ts +62 -0
- package/src/resources/extensions/gsd/tests/remote-questions.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/silent-catch-diagnostics.test.ts +284 -0
- package/src/resources/extensions/gsd/tests/workflow-logger-audit.test.ts +120 -0
- package/src/resources/extensions/gsd/tests/workflow-logger.test.ts +6 -6
- package/src/resources/extensions/gsd/tools/complete-milestone.ts +3 -6
- package/src/resources/extensions/gsd/tools/complete-slice.ts +3 -6
- package/src/resources/extensions/gsd/tools/complete-task.ts +3 -6
- package/src/resources/extensions/gsd/tools/plan-milestone.ts +3 -6
- package/src/resources/extensions/gsd/tools/plan-slice.ts +3 -6
- package/src/resources/extensions/gsd/tools/plan-task.ts +2 -3
- package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +4 -6
- package/src/resources/extensions/gsd/tools/reopen-slice.ts +2 -3
- package/src/resources/extensions/gsd/tools/reopen-task.ts +2 -3
- package/src/resources/extensions/gsd/tools/replan-slice.ts +2 -3
- package/src/resources/extensions/gsd/tools/validate-milestone.ts +2 -3
- package/src/resources/extensions/gsd/triage-resolution.ts +11 -4
- package/src/resources/extensions/gsd/types.ts +1 -0
- package/src/resources/extensions/gsd/workflow-events.ts +2 -1
- package/src/resources/extensions/gsd/workflow-logger.ts +52 -5
- package/src/resources/extensions/gsd/workflow-migration.ts +14 -12
- package/src/resources/extensions/gsd/workflow-projections.ts +2 -2
- package/src/resources/extensions/gsd/workflow-reconcile.ts +2 -2
- package/src/resources/extensions/gsd/worktree-manager.ts +16 -14
- package/src/resources/extensions/shared/interview-ui.ts +3 -1
- package/src/resources/extensions/shared/tests/interview-notes-loop.test.ts +144 -0
- package/dist/web/standalone/.next/static/chunks/app/page-0c485498795110d6.js +0 -1
- package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +0 -1
- /package/dist/web/standalone/.next/static/{JVkoVYumy0cDhOQISEYdG → 72_sVF0fdrMZX707jm10G}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{JVkoVYumy0cDhOQISEYdG → 72_sVF0fdrMZX707jm10G}/_ssgManifest.js +0 -0
|
@@ -82,11 +82,14 @@ export default function AskUserQuestions(pi) {
|
|
|
82
82
|
return errorResult(`Error: ask_user_questions requires non-empty options for every question (question "${q.id}" has none)`, params.questions);
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
|
+
// Try remote first if configured (works in both interactive and headless modes).
|
|
86
|
+
// tryRemoteQuestions returns null when no remote channel is configured, so
|
|
87
|
+
// this is a no-op when the user has not set up Slack/Discord/Telegram.
|
|
88
|
+
const { tryRemoteQuestions } = await import("./remote-questions/manager.js");
|
|
89
|
+
const remoteResult = await tryRemoteQuestions(params.questions, signal);
|
|
90
|
+
if (remoteResult)
|
|
91
|
+
return { ...remoteResult, details: remoteResult.details };
|
|
85
92
|
if (!ctx.hasUI) {
|
|
86
|
-
const { tryRemoteQuestions } = await import("./remote-questions/manager.js");
|
|
87
|
-
const remoteResult = await tryRemoteQuestions(params.questions, signal);
|
|
88
|
-
if (remoteResult)
|
|
89
|
-
return { ...remoteResult, details: remoteResult.details };
|
|
90
93
|
return errorResult("Error: UI not available (non-interactive mode)", params.questions);
|
|
91
94
|
}
|
|
92
95
|
// Delegate to shared interview UI
|
|
@@ -495,6 +495,8 @@ export async function runGuards(ic, mid) {
|
|
|
495
495
|
// ── Stop/Backtrack directive guard (#3487) ──
|
|
496
496
|
// Check for unexecuted stop or backtrack captures BEFORE dispatching any unit.
|
|
497
497
|
// This ensures user "halt" directives are honored immediately.
|
|
498
|
+
// IMPORTANT: Fail-closed — any exception during stop handling still breaks the loop
|
|
499
|
+
// to ensure user halt intent is never silently dropped.
|
|
498
500
|
try {
|
|
499
501
|
const { loadStopCaptures, markCaptureExecuted } = await import("../captures.js");
|
|
500
502
|
const stopCaptures = loadStopCaptures(s.basePath);
|
|
@@ -506,11 +508,9 @@ export async function runGuards(ic, mid) {
|
|
|
506
508
|
: `Stop directive: ${first.text}`;
|
|
507
509
|
ctx.ui.notify(label, "warning");
|
|
508
510
|
deps.sendDesktopNotification("GSD", label, "warning", "stop-directive", basename(s.originalBasePath || s.basePath));
|
|
509
|
-
//
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
}
|
|
513
|
-
// For backtrack captures, write the backtrack trigger before pausing
|
|
511
|
+
// Pause first — ensures auto-mode stops even if later steps fail
|
|
512
|
+
await deps.pauseAuto(ctx, pi);
|
|
513
|
+
// For backtrack captures, write the backtrack trigger after pausing
|
|
514
514
|
if (isBacktrack) {
|
|
515
515
|
try {
|
|
516
516
|
const { executeBacktrack } = await import("../triage-resolution.js");
|
|
@@ -520,13 +520,19 @@ export async function runGuards(ic, mid) {
|
|
|
520
520
|
debugLog("guards", { phase: "backtrack-execution-error", error: String(e) });
|
|
521
521
|
}
|
|
522
522
|
}
|
|
523
|
-
|
|
523
|
+
// Mark captures as executed only after successful pause/transition
|
|
524
|
+
for (const cap of stopCaptures) {
|
|
525
|
+
markCaptureExecuted(s.basePath, cap.id);
|
|
526
|
+
}
|
|
524
527
|
debugLog("autoLoop", { phase: "exit", reason: isBacktrack ? "user-backtrack" : "user-stop" });
|
|
525
528
|
return { action: "break", reason: isBacktrack ? "user-backtrack" : "user-stop" };
|
|
526
529
|
}
|
|
527
530
|
}
|
|
528
531
|
catch (e) {
|
|
532
|
+
// Fail-closed: if anything in the stop guard throws, break the loop
|
|
533
|
+
// rather than silently continuing and dropping user halt intent
|
|
529
534
|
debugLog("guards", { phase: "stop-guard-error", error: String(e) });
|
|
535
|
+
return { action: "break", reason: "stop-guard-error" };
|
|
530
536
|
}
|
|
531
537
|
// Budget ceiling guard
|
|
532
538
|
const budgetCeiling = prefs?.budget_ceiling;
|
|
@@ -894,7 +900,9 @@ export async function runUnitPhase(ic, iterData, loopState, sidecarItem) {
|
|
|
894
900
|
nextSteps: [],
|
|
895
901
|
});
|
|
896
902
|
}
|
|
897
|
-
catch { /* non-fatal — anchor is advisory */
|
|
903
|
+
catch (err) { /* non-fatal — anchor is advisory */
|
|
904
|
+
logWarning("engine", `phase anchor failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
905
|
+
}
|
|
898
906
|
}
|
|
899
907
|
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 } });
|
|
900
908
|
return { action: "next", data: { unitStartedAt: s.currentUnit?.startedAt } };
|
|
@@ -20,6 +20,7 @@ import { loadEffectiveGSDPreferences, getGlobalGSDPreferencesPath } from "./pref
|
|
|
20
20
|
import { resolveServiceTierIcon, getEffectiveServiceTier } from "./service-tier.js";
|
|
21
21
|
import { parseUnitId } from "./unit-id.js";
|
|
22
22
|
import { formatRtkSavingsLabel, getRtkSessionSavings, } from "../shared/rtk-session-stats.js";
|
|
23
|
+
import { logWarning } from "./workflow-logger.js";
|
|
23
24
|
// ─── UAT Slice Extraction ─────────────────────────────────────────────────────
|
|
24
25
|
/**
|
|
25
26
|
* Extract the target slice ID from a run-uat unit ID (e.g. "M001/S01" → "S01").
|
|
@@ -220,8 +221,9 @@ export function updateSliceProgressCache(base, mid, activeSid) {
|
|
|
220
221
|
}
|
|
221
222
|
}
|
|
222
223
|
}
|
|
223
|
-
catch {
|
|
224
|
+
catch (err) {
|
|
224
225
|
// Non-fatal — just omit task count
|
|
226
|
+
logWarning("dashboard", `operation failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
225
227
|
}
|
|
226
228
|
}
|
|
227
229
|
cachedSliceProgress = {
|
|
@@ -232,8 +234,9 @@ export function updateSliceProgressCache(base, mid, activeSid) {
|
|
|
232
234
|
taskDetails,
|
|
233
235
|
};
|
|
234
236
|
}
|
|
235
|
-
catch {
|
|
237
|
+
catch (err) {
|
|
236
238
|
// Non-fatal — widget just won't show progress bar
|
|
239
|
+
logWarning("dashboard", `operation failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
237
240
|
}
|
|
238
241
|
}
|
|
239
242
|
export function getRoadmapSlicesSync() {
|
|
@@ -263,8 +266,9 @@ function refreshLastCommit(basePath) {
|
|
|
263
266
|
}
|
|
264
267
|
lastCommitFetchedAt = Date.now();
|
|
265
268
|
}
|
|
266
|
-
catch {
|
|
269
|
+
catch (err) {
|
|
267
270
|
// Non-fatal — just skip last commit display
|
|
271
|
+
logWarning("dashboard", `operation failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
268
272
|
}
|
|
269
273
|
}
|
|
270
274
|
function getLastCommit(basePath) {
|
|
@@ -300,7 +304,9 @@ function ensureWidgetModeLoaded() {
|
|
|
300
304
|
widgetMode = saved;
|
|
301
305
|
}
|
|
302
306
|
}
|
|
303
|
-
catch { /* non-fatal — use default */
|
|
307
|
+
catch (err) { /* non-fatal — use default */
|
|
308
|
+
logWarning("dashboard", `operation failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
309
|
+
}
|
|
304
310
|
}
|
|
305
311
|
/** Persist widget mode to global preferences YAML. */
|
|
306
312
|
function persistWidgetMode(mode) {
|
|
@@ -320,7 +326,9 @@ function persistWidgetMode(mode) {
|
|
|
320
326
|
}
|
|
321
327
|
writeFileSync(prefsPath, content, "utf-8");
|
|
322
328
|
}
|
|
323
|
-
catch { /* non-fatal — mode still set in memory */
|
|
329
|
+
catch (err) { /* non-fatal — mode still set in memory */
|
|
330
|
+
logWarning("dashboard", `file write failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
331
|
+
}
|
|
324
332
|
}
|
|
325
333
|
/** Cycle to the next widget mode. Returns the new mode. */
|
|
326
334
|
export function cycleWidgetMode() {
|
|
@@ -360,7 +368,9 @@ export function updateProgressWidget(ctx, unitType, unitId, state, accessors, ti
|
|
|
360
368
|
try {
|
|
361
369
|
cachedBranch = getCurrentBranch(accessors.getBasePath());
|
|
362
370
|
}
|
|
363
|
-
catch { /* not in git repo */
|
|
371
|
+
catch (err) { /* not in git repo */
|
|
372
|
+
logWarning("dashboard", `git branch detection failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
373
|
+
}
|
|
364
374
|
// Cache short pwd (last 2 path segments only) + worktree/branch info
|
|
365
375
|
let widgetPwd;
|
|
366
376
|
{
|
|
@@ -394,7 +404,8 @@ export function updateProgressWidget(ctx, unitType, unitId, state, accessors, ti
|
|
|
394
404
|
const savings = sessionId ? getRtkSessionSavings(accessors.getBasePath(), sessionId) : null;
|
|
395
405
|
cachedRtkLabel = formatRtkSavingsLabel(savings);
|
|
396
406
|
}
|
|
397
|
-
catch {
|
|
407
|
+
catch (err) {
|
|
408
|
+
logWarning("dashboard", `RTK savings lookup failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
398
409
|
cachedRtkLabel = null;
|
|
399
410
|
}
|
|
400
411
|
};
|
|
@@ -416,7 +427,9 @@ export function updateProgressWidget(ctx, unitType, unitId, state, accessors, ti
|
|
|
416
427
|
refreshRtkLabel();
|
|
417
428
|
cachedLines = undefined;
|
|
418
429
|
}
|
|
419
|
-
catch { /* non-fatal */
|
|
430
|
+
catch (err) { /* non-fatal */
|
|
431
|
+
logWarning("dashboard", `DB status update failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
432
|
+
}
|
|
420
433
|
}, 15_000);
|
|
421
434
|
return {
|
|
422
435
|
render(width) {
|
|
@@ -13,7 +13,7 @@ import { isDbAvailable, getMilestoneSlices, getPendingGates, markAllGatesOmitted
|
|
|
13
13
|
import { extractVerdict, isAcceptableUatVerdict } from "./verdict-parser.js";
|
|
14
14
|
import { gsdRoot, resolveMilestoneFile, resolveMilestonePath, resolveSliceFile, resolveTaskFile, relSliceFile, buildMilestoneFileName, } from "./paths.js";
|
|
15
15
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
16
|
-
import { logError } from "./workflow-logger.js";
|
|
16
|
+
import { logWarning, logError } from "./workflow-logger.js";
|
|
17
17
|
import { join } from "node:path";
|
|
18
18
|
import { hasImplementationArtifacts } from "./auto-recovery.js";
|
|
19
19
|
import { buildDiscussMilestonePrompt, buildResearchMilestonePrompt, buildPlanMilestonePrompt, buildResearchSlicePrompt, buildPlanSlicePrompt, buildExecuteTaskPrompt, buildCompleteSlicePrompt, buildCompleteMilestonePrompt, buildValidateMilestonePrompt, buildReplanSlicePrompt, buildRunUatPrompt, buildReassessRoadmapPrompt, buildRewriteDocsPrompt, buildReactiveExecutePrompt, buildGateEvaluatePrompt, checkNeedsReassessment, checkNeedsRunUat, } from "./auto-prompts.js";
|
|
@@ -564,7 +564,9 @@ export const DISPATCH_RULES = [
|
|
|
564
564
|
}
|
|
565
565
|
}
|
|
566
566
|
}
|
|
567
|
-
catch { /* fall through — don't block on DB errors */
|
|
567
|
+
catch (err) { /* fall through — don't block on DB errors */
|
|
568
|
+
logWarning("dispatch", `verification class check failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
569
|
+
}
|
|
568
570
|
return {
|
|
569
571
|
action: "dispatch",
|
|
570
572
|
unitType: "complete-milestone",
|
|
@@ -602,8 +604,9 @@ export async function resolveDispatch(ctx) {
|
|
|
602
604
|
const registry = getRegistry();
|
|
603
605
|
return await registry.evaluateDispatch(ctx);
|
|
604
606
|
}
|
|
605
|
-
catch {
|
|
607
|
+
catch (err) {
|
|
606
608
|
// Registry not initialized — fall back to inline loop
|
|
609
|
+
logWarning("dispatch", `registry dispatch failed, falling back to inline rules: ${err instanceof Error ? err.message : String(err)}`);
|
|
607
610
|
}
|
|
608
611
|
for (const rule of DISPATCH_RULES) {
|
|
609
612
|
const result = await rule.match(ctx);
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* and fallback chains.
|
|
5
5
|
*/
|
|
6
6
|
import { resolveModelWithFallbacksForUnit, resolveDynamicRoutingConfig } from "./preferences.js";
|
|
7
|
-
import { classifyUnitComplexity, tierLabel
|
|
8
|
-
import { resolveModelForComplexity, escalateTier } from "./model-router.js";
|
|
7
|
+
import { classifyUnitComplexity, tierLabel } from "./complexity-classifier.js";
|
|
8
|
+
import { resolveModelForComplexity, escalateTier, getEligibleModels, loadCapabilityOverrides } from "./model-router.js";
|
|
9
9
|
import { getLedger, getProjectTotals } from "./metrics.js";
|
|
10
10
|
import { unitPhaseLabel } from "./auto-dashboard.js";
|
|
11
11
|
export function resolvePreferredModelConfig(unitType, autoModeStartModel) {
|
|
@@ -68,19 +68,68 @@ export async function selectAndApplyModel(ctx, pi, unitType, unitId, basePath, p
|
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
|
-
//
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
71
|
+
// Load user capability overrides from preferences (D-17: deep-merged with built-in profiles)
|
|
72
|
+
const capabilityOverrides = loadCapabilityOverrides(prefs ?? {});
|
|
73
|
+
// Fire before_model_select hook (ADR-004, D-03)
|
|
74
|
+
// Hook can override model selection entirely by returning { modelId }
|
|
75
|
+
let hookOverride;
|
|
76
|
+
if (routingConfig.hooks !== false) {
|
|
77
|
+
const eligible = getEligibleModels(classification.tier, availableModelIds, routingConfig);
|
|
78
|
+
const hookResult = await pi.emitBeforeModelSelect({
|
|
79
|
+
unitType,
|
|
80
|
+
unitId,
|
|
81
|
+
classification: {
|
|
82
|
+
tier: classification.tier,
|
|
83
|
+
reason: classification.reason,
|
|
84
|
+
downgraded: classification.downgraded,
|
|
85
|
+
},
|
|
86
|
+
taskMetadata: classification.taskMetadata,
|
|
87
|
+
eligibleModels: eligible,
|
|
88
|
+
phaseConfig: modelConfig ? {
|
|
89
|
+
primary: modelConfig.primary,
|
|
90
|
+
fallbacks: modelConfig.fallbacks ?? [],
|
|
91
|
+
} : undefined,
|
|
92
|
+
});
|
|
93
|
+
if (hookResult?.modelId) {
|
|
94
|
+
hookOverride = hookResult.modelId;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
let routingResult;
|
|
98
|
+
if (hookOverride) {
|
|
99
|
+
// Hook override bypasses capability scoring entirely
|
|
100
|
+
routingResult = {
|
|
101
|
+
modelId: hookOverride,
|
|
102
|
+
fallbacks: [
|
|
103
|
+
...(modelConfig?.fallbacks ?? []).filter(f => f !== hookOverride),
|
|
104
|
+
...(modelConfig?.primary && modelConfig.primary !== hookOverride ? [modelConfig.primary] : []),
|
|
105
|
+
],
|
|
106
|
+
tier: classification.tier,
|
|
107
|
+
wasDowngraded: hookOverride !== modelConfig?.primary,
|
|
108
|
+
reason: `hook override: ${hookOverride}`,
|
|
109
|
+
selectionMethod: "tier-only",
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
routingResult = resolveModelForComplexity(classification, modelConfig, routingConfig, availableModelIds, unitType, classification.taskMetadata, capabilityOverrides);
|
|
114
|
+
}
|
|
76
115
|
if (routingResult.wasDowngraded) {
|
|
77
116
|
effectiveModelConfig = {
|
|
78
117
|
primary: routingResult.modelId,
|
|
79
118
|
fallbacks: routingResult.fallbacks,
|
|
80
119
|
};
|
|
81
120
|
if (verbose) {
|
|
82
|
-
|
|
83
|
-
|
|
121
|
+
if (routingResult.selectionMethod === "capability-scored" && routingResult.capabilityScores) {
|
|
122
|
+
// Verbose scoring breakdown for capability-scored decisions (D-20)
|
|
123
|
+
const tierLbl = tierLabel(classification.tier);
|
|
124
|
+
const scores = Object.entries(routingResult.capabilityScores)
|
|
125
|
+
.sort(([, a], [, b]) => b - a)
|
|
126
|
+
.map(([id, score]) => `${id}: ${score.toFixed(1)}`)
|
|
127
|
+
.join(", ");
|
|
128
|
+
ctx.ui.notify(`Dynamic routing [${tierLbl}]: ${routingResult.modelId} (capability-scored) — ${scores}`, "info");
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
ctx.ui.notify(`Dynamic routing [${tierLabel(classification.tier)}]: ${routingResult.modelId} (${classification.reason})`, "info");
|
|
132
|
+
}
|
|
84
133
|
}
|
|
85
134
|
}
|
|
86
135
|
routingTierLabel = ` [${tierLabel(classification.tier)}]`;
|
|
@@ -208,8 +208,9 @@ export async function postUnitPreVerification(pctx, opts) {
|
|
|
208
208
|
const { getTaskIssueNumberForCommit } = await import("../github-sync/sync.js");
|
|
209
209
|
ghIssueNumber = getTaskIssueNumberForCommit(s.basePath, mid, sid, tid) ?? undefined;
|
|
210
210
|
}
|
|
211
|
-
catch {
|
|
211
|
+
catch (err) {
|
|
212
212
|
// GitHub sync not available — skip
|
|
213
|
+
logWarning("engine", `GitHub issue lookup failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
213
214
|
}
|
|
214
215
|
taskContext = {
|
|
215
216
|
taskId: `${sid}/${tid}`,
|
|
@@ -448,7 +449,7 @@ export async function postUnitPostVerification(pctx) {
|
|
|
448
449
|
catch (dbErr) {
|
|
449
450
|
// DB unavailable — fail explicitly rather than silently reverting to markdown mutation.
|
|
450
451
|
// Use 'gsd recover' to rebuild DB state from disk if needed.
|
|
451
|
-
|
|
452
|
+
logError("engine", `retry state-reset failed (DB unavailable): ${dbErr.message}. Run 'gsd recover' to reconcile.`);
|
|
452
453
|
}
|
|
453
454
|
}
|
|
454
455
|
// 2. Delete SUMMARY.md for the task
|
|
@@ -18,6 +18,7 @@ import { computeBudgets, resolveExecutorContextWindow, truncateAtSectionBoundary
|
|
|
18
18
|
import { getPendingGates } from "./gsd-db.js";
|
|
19
19
|
import { formatDecisionsCompact, formatRequirementsCompact } from "./structured-data-formatter.js";
|
|
20
20
|
import { readPhaseAnchor, formatAnchorForPrompt } from "./phase-anchor.js";
|
|
21
|
+
import { logWarning } from "./workflow-logger.js";
|
|
21
22
|
// ─── Preamble Cap ─────────────────────────────────────────────────────────────
|
|
22
23
|
const MAX_PREAMBLE_CHARS = 30_000;
|
|
23
24
|
function capPreamble(preamble) {
|
|
@@ -37,7 +38,8 @@ function formatExecutorConstraints() {
|
|
|
37
38
|
const prefs = loadEffectiveGSDPreferences();
|
|
38
39
|
windowTokens = resolveExecutorContextWindow(undefined, prefs?.preferences);
|
|
39
40
|
}
|
|
40
|
-
catch {
|
|
41
|
+
catch (e) {
|
|
42
|
+
logWarning("prompt", `resolveExecutorContextWindow failed: ${e.message}`);
|
|
41
43
|
windowTokens = 200_000; // safe default
|
|
42
44
|
}
|
|
43
45
|
const budgets = computeBudgets(windowTokens);
|
|
@@ -161,7 +163,9 @@ export async function inlineDependencySummaries(mid, sid, base, budgetChars) {
|
|
|
161
163
|
// If slice not found in DB, fall through to file-based parsing
|
|
162
164
|
}
|
|
163
165
|
}
|
|
164
|
-
catch {
|
|
166
|
+
catch (err) {
|
|
167
|
+
logWarning("prompt", `inlineDependencySummaries DB lookup failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
168
|
+
}
|
|
165
169
|
// If DB didn't provide depends, fall back to roadmap parsing
|
|
166
170
|
if (!depends) {
|
|
167
171
|
const roadmapPath = resolveMilestoneFile(base, mid, "ROADMAP");
|
|
@@ -233,8 +237,8 @@ export async function inlineDecisionsFromDb(base, milestoneId, scope, level) {
|
|
|
233
237
|
}
|
|
234
238
|
}
|
|
235
239
|
}
|
|
236
|
-
catch {
|
|
237
|
-
|
|
240
|
+
catch (err) {
|
|
241
|
+
logWarning("prompt", `inlineDecisionsFromDb failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
238
242
|
}
|
|
239
243
|
return inlineGsdRootFile(base, "decisions.md", "Decisions");
|
|
240
244
|
}
|
|
@@ -258,8 +262,8 @@ export async function inlineRequirementsFromDb(base, sliceId, level) {
|
|
|
258
262
|
}
|
|
259
263
|
}
|
|
260
264
|
}
|
|
261
|
-
catch {
|
|
262
|
-
|
|
265
|
+
catch (err) {
|
|
266
|
+
logWarning("prompt", `inlineRequirementsFromDb failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
263
267
|
}
|
|
264
268
|
return inlineGsdRootFile(base, "requirements.md", "Requirements");
|
|
265
269
|
}
|
|
@@ -278,8 +282,8 @@ export async function inlineProjectFromDb(base) {
|
|
|
278
282
|
}
|
|
279
283
|
}
|
|
280
284
|
}
|
|
281
|
-
catch {
|
|
282
|
-
|
|
285
|
+
catch (err) {
|
|
286
|
+
logWarning("prompt", `inlineProjectFromDb failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
283
287
|
}
|
|
284
288
|
return inlineGsdRootFile(base, "project.md", "Project");
|
|
285
289
|
}
|
|
@@ -399,8 +403,8 @@ export function buildSkillActivationBlock(params) {
|
|
|
399
403
|
matched.add(normalizeSkillReference(skillName));
|
|
400
404
|
}
|
|
401
405
|
}
|
|
402
|
-
catch {
|
|
403
|
-
|
|
406
|
+
catch (err) {
|
|
407
|
+
logWarning("prompt", `parseTaskPlanFile failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
404
408
|
}
|
|
405
409
|
}
|
|
406
410
|
const ordered = [...matched]
|
|
@@ -619,7 +623,9 @@ export async function checkNeedsReassessment(base, mid, state) {
|
|
|
619
623
|
}
|
|
620
624
|
}
|
|
621
625
|
}
|
|
622
|
-
catch {
|
|
626
|
+
catch (err) {
|
|
627
|
+
logWarning("prompt", `checkNeedsReassessment DB lookup failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
628
|
+
}
|
|
623
629
|
// File-based fallback using roadmap checkboxes
|
|
624
630
|
const roadmapPath = resolveMilestoneFile(base, mid, "ROADMAP");
|
|
625
631
|
if (!roadmapPath)
|
|
@@ -694,7 +700,9 @@ export async function checkNeedsRunUat(base, mid, state, prefs) {
|
|
|
694
700
|
}
|
|
695
701
|
}
|
|
696
702
|
}
|
|
697
|
-
catch {
|
|
703
|
+
catch (err) {
|
|
704
|
+
logWarning("prompt", `checkNeedsRunUat DB lookup failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
705
|
+
}
|
|
698
706
|
// File-based fallback using roadmap checkboxes
|
|
699
707
|
if (!prefs?.uat_dispatch)
|
|
700
708
|
return null;
|
|
@@ -1150,7 +1158,9 @@ export async function buildCompleteMilestonePrompt(mid, midTitle, base, level) {
|
|
|
1150
1158
|
sliceIds = getMilestoneSlices(mid).map(s => s.id);
|
|
1151
1159
|
}
|
|
1152
1160
|
}
|
|
1153
|
-
catch {
|
|
1161
|
+
catch (err) {
|
|
1162
|
+
logWarning("prompt", `buildCompleteMilestonePrompt DB lookup failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
1163
|
+
}
|
|
1154
1164
|
// File-based fallback: parse roadmap for slice IDs when DB has no data
|
|
1155
1165
|
if (sliceIds.length === 0 && roadmapPath) {
|
|
1156
1166
|
const roadmapContent = await loadFile(roadmapPath);
|
|
@@ -1233,7 +1243,9 @@ export async function buildValidateMilestonePrompt(mid, midTitle, base, level) {
|
|
|
1233
1243
|
}
|
|
1234
1244
|
}
|
|
1235
1245
|
}
|
|
1236
|
-
catch {
|
|
1246
|
+
catch (err) {
|
|
1247
|
+
logWarning("prompt", `buildValidateMilestonePrompt verification classes lookup failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
1248
|
+
}
|
|
1237
1249
|
// Inline all slice summaries and UAT results
|
|
1238
1250
|
let valSliceIds = [];
|
|
1239
1251
|
try {
|
|
@@ -1242,7 +1254,9 @@ export async function buildValidateMilestonePrompt(mid, midTitle, base, level) {
|
|
|
1242
1254
|
valSliceIds = getMilestoneSlices(mid).map(s => s.id);
|
|
1243
1255
|
}
|
|
1244
1256
|
}
|
|
1245
|
-
catch {
|
|
1257
|
+
catch (err) {
|
|
1258
|
+
logWarning("prompt", `buildValidateMilestonePrompt slice IDs lookup failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
1259
|
+
}
|
|
1246
1260
|
// File-based fallback: parse roadmap for slice IDs when DB has no data
|
|
1247
1261
|
if (valSliceIds.length === 0 && roadmapPath) {
|
|
1248
1262
|
const roadmapContent = await loadFile(roadmapPath);
|
|
@@ -1378,8 +1392,8 @@ export async function buildReplanSlicePrompt(mid, midTitle, sid, sTitle, base) {
|
|
|
1378
1392
|
captureContext = replanCaptures.map(c => `- **${c.id}**: "${c.text}" — ${c.rationale ?? "no rationale"}`).join("\n");
|
|
1379
1393
|
}
|
|
1380
1394
|
}
|
|
1381
|
-
catch {
|
|
1382
|
-
|
|
1395
|
+
catch (err) {
|
|
1396
|
+
logWarning("prompt", `loadReplanCaptures failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
1383
1397
|
}
|
|
1384
1398
|
return loadPrompt("replan-slice", {
|
|
1385
1399
|
workingDirectory: base,
|
|
@@ -1468,8 +1482,8 @@ export async function buildReassessRoadmapPrompt(mid, midTitle, completedSliceId
|
|
|
1468
1482
|
deferredCaptures = deferred.map(c => `- **${c.id}**: "${c.text}" — ${c.rationale ?? "deferred during triage"}`).join("\n");
|
|
1469
1483
|
}
|
|
1470
1484
|
}
|
|
1471
|
-
catch {
|
|
1472
|
-
|
|
1485
|
+
catch (err) {
|
|
1486
|
+
logWarning("prompt", `loadDeferredCaptures failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
1473
1487
|
}
|
|
1474
1488
|
const reassessCommitInstruction = "Do not commit — .gsd/ planning docs are managed externally and not tracked in git.";
|
|
1475
1489
|
return loadPrompt("reassess-roadmap", {
|
|
@@ -1646,7 +1660,9 @@ export async function buildRewriteDocsPrompt(mid, midTitle, activeSlice, base, o
|
|
|
1646
1660
|
.map(t => ({ id: t.id }));
|
|
1647
1661
|
}
|
|
1648
1662
|
}
|
|
1649
|
-
catch {
|
|
1663
|
+
catch (err) {
|
|
1664
|
+
logWarning("prompt", `buildRewriteDocsPrompt DB task lookup failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
1665
|
+
}
|
|
1650
1666
|
if (!incompleteTasks) {
|
|
1651
1667
|
// DB unavailable — no task data to inline
|
|
1652
1668
|
incompleteTasks = [];
|
|
@@ -12,6 +12,7 @@ import { parseRoadmap as parseLegacyRoadmap, parsePlan as parseLegacyPlan } from
|
|
|
12
12
|
import { isDbAvailable, getTask, getSlice, getSliceTasks, updateTaskStatus } from "./gsd-db.js";
|
|
13
13
|
import { isValidationTerminal } from "./state.js";
|
|
14
14
|
import { getErrorMessage } from "./error-utils.js";
|
|
15
|
+
import { logWarning, logError } from "./workflow-logger.js";
|
|
15
16
|
import { nativeConflictFiles, nativeCommit, nativeCheckoutTheirs, nativeAddPaths, nativeMergeAbort, nativeResetHard, } from "./native-git-bridge.js";
|
|
16
17
|
import { resolveSlicePath, resolveSliceFile, resolveTasksDir, resolveTaskFiles, relMilestoneFile, relSliceFile, buildSliceFileName, resolveMilestoneFile, clearPathCache, resolveGsdRootFile, } from "./paths.js";
|
|
17
18
|
import { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync, } from "node:fs";
|
|
@@ -40,7 +41,8 @@ export function hasImplementationArtifacts(basePath) {
|
|
|
40
41
|
encoding: "utf-8",
|
|
41
42
|
});
|
|
42
43
|
}
|
|
43
|
-
catch {
|
|
44
|
+
catch (e) {
|
|
45
|
+
logWarning("recovery", `git rev-parse check failed: ${e.message}`);
|
|
44
46
|
return true;
|
|
45
47
|
}
|
|
46
48
|
// Strategy: check `git diff --name-only` against the merge-base with the
|
|
@@ -59,8 +61,9 @@ export function hasImplementationArtifacts(basePath) {
|
|
|
59
61
|
const implFiles = changedFiles.filter(f => !f.startsWith(".gsd/") && !f.startsWith(".gsd\\"));
|
|
60
62
|
return implFiles.length > 0;
|
|
61
63
|
}
|
|
62
|
-
catch {
|
|
64
|
+
catch (e) {
|
|
63
65
|
// Non-fatal — if git operations fail, don't block the pipeline
|
|
66
|
+
logWarning("recovery", `implementation artifact check failed: ${e.message}`);
|
|
64
67
|
return true;
|
|
65
68
|
}
|
|
66
69
|
}
|
|
@@ -77,8 +80,9 @@ function detectMainBranch(basePath) {
|
|
|
77
80
|
if (result.trim())
|
|
78
81
|
return "main";
|
|
79
82
|
}
|
|
80
|
-
catch {
|
|
81
|
-
// main doesn't exist
|
|
83
|
+
catch (_) {
|
|
84
|
+
// Expected — main doesn't exist, try master next
|
|
85
|
+
void _;
|
|
82
86
|
}
|
|
83
87
|
try {
|
|
84
88
|
const result = execFileSync("git", ["rev-parse", "--verify", "master"], {
|
|
@@ -89,10 +93,13 @@ function detectMainBranch(basePath) {
|
|
|
89
93
|
if (result.trim())
|
|
90
94
|
return "master";
|
|
91
95
|
}
|
|
92
|
-
catch {
|
|
93
|
-
// master doesn't exist either
|
|
96
|
+
catch (_) {
|
|
97
|
+
// Expected — master doesn't exist either
|
|
98
|
+
void _;
|
|
94
99
|
}
|
|
95
|
-
|
|
100
|
+
// Neither main nor master found — warn and fall back
|
|
101
|
+
logWarning("recovery", "neither main nor master branch found, defaulting to main");
|
|
102
|
+
return "main";
|
|
96
103
|
}
|
|
97
104
|
/**
|
|
98
105
|
* Get files changed since the branch diverged from the target branch.
|
|
@@ -107,15 +114,17 @@ function getChangedFilesSinceBranch(basePath, targetBranch) {
|
|
|
107
114
|
return result ? result.split("\n").filter(Boolean) : [];
|
|
108
115
|
}
|
|
109
116
|
}
|
|
110
|
-
catch {
|
|
117
|
+
catch (err) {
|
|
111
118
|
// merge-base failed — fall back
|
|
119
|
+
logWarning("recovery", `merge-base detection failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
112
120
|
}
|
|
113
121
|
// Fallback: check last 20 commits
|
|
114
122
|
try {
|
|
115
123
|
const result = execFileSync("git", ["log", "--name-only", "--pretty=format:", "-20", "HEAD"], { cwd: basePath, stdio: ["ignore", "pipe", "pipe"], encoding: "utf-8" }).trim();
|
|
116
124
|
return result ? [...new Set(result.split("\n").filter(Boolean))] : [];
|
|
117
125
|
}
|
|
118
|
-
catch {
|
|
126
|
+
catch (e) {
|
|
127
|
+
logWarning("recovery", `git log fallback failed: ${e.message}`);
|
|
119
128
|
return [];
|
|
120
129
|
}
|
|
121
130
|
}
|
|
@@ -198,8 +207,9 @@ export function verifyExpectedArtifact(unitType, unitId, base) {
|
|
|
198
207
|
return false;
|
|
199
208
|
}
|
|
200
209
|
}
|
|
201
|
-
catch {
|
|
210
|
+
catch (err) {
|
|
202
211
|
// DB unavailable — treat as verified to avoid blocking
|
|
212
|
+
logWarning("recovery", `gate-evaluate DB check failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
203
213
|
}
|
|
204
214
|
return true;
|
|
205
215
|
}
|
|
@@ -291,8 +301,9 @@ export function verifyExpectedArtifact(unitType, unitId, base) {
|
|
|
291
301
|
}
|
|
292
302
|
}
|
|
293
303
|
}
|
|
294
|
-
catch {
|
|
304
|
+
catch (err) {
|
|
295
305
|
// Parse failure — don't block; slice plan may have non-standard format
|
|
306
|
+
logWarning("recovery", `plan-slice task plan verification failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
296
307
|
}
|
|
297
308
|
}
|
|
298
309
|
}
|
|
@@ -325,7 +336,8 @@ export function verifyExpectedArtifact(unitType, unitId, base) {
|
|
|
325
336
|
if (slice && !slice.done)
|
|
326
337
|
return false;
|
|
327
338
|
}
|
|
328
|
-
catch {
|
|
339
|
+
catch (e) {
|
|
340
|
+
logWarning("recovery", `roadmap parse failed: ${e.message}`);
|
|
329
341
|
return false;
|
|
330
342
|
}
|
|
331
343
|
}
|
|
@@ -374,7 +386,9 @@ export function writeBlockerPlaceholder(unitType, unitId, base, reason) {
|
|
|
374
386
|
try {
|
|
375
387
|
updateTaskStatus(mid, sid, tid, "complete", new Date().toISOString());
|
|
376
388
|
}
|
|
377
|
-
catch { /* non-fatal */
|
|
389
|
+
catch (err) { /* non-fatal */
|
|
390
|
+
logError("recovery", `DB status update failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
391
|
+
}
|
|
378
392
|
}
|
|
379
393
|
}
|
|
380
394
|
return diagnoseExpectedArtifact(unitType, unitId, base);
|
|
@@ -389,23 +403,26 @@ function abortAndResetMerge(basePath, hasMergeHead, squashMsgPath) {
|
|
|
389
403
|
try {
|
|
390
404
|
nativeMergeAbort(basePath);
|
|
391
405
|
}
|
|
392
|
-
catch {
|
|
406
|
+
catch (err) {
|
|
393
407
|
/* best-effort */
|
|
408
|
+
logWarning("recovery", `git merge-abort failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
394
409
|
}
|
|
395
410
|
}
|
|
396
411
|
else if (squashMsgPath) {
|
|
397
412
|
try {
|
|
398
413
|
unlinkSync(squashMsgPath);
|
|
399
414
|
}
|
|
400
|
-
catch {
|
|
415
|
+
catch (err) {
|
|
401
416
|
/* best-effort */
|
|
417
|
+
logWarning("recovery", `file unlink failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
402
418
|
}
|
|
403
419
|
}
|
|
404
420
|
try {
|
|
405
421
|
nativeResetHard(basePath);
|
|
406
422
|
}
|
|
407
|
-
catch {
|
|
423
|
+
catch (err) {
|
|
408
424
|
/* best-effort */
|
|
425
|
+
logError("recovery", `git reset failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
409
426
|
}
|
|
410
427
|
}
|
|
411
428
|
/**
|
|
@@ -452,7 +469,8 @@ export function reconcileMergeState(basePath, ctx) {
|
|
|
452
469
|
nativeCheckoutTheirs(basePath, gsdConflicts);
|
|
453
470
|
nativeAddPaths(basePath, gsdConflicts);
|
|
454
471
|
}
|
|
455
|
-
catch {
|
|
472
|
+
catch (e) {
|
|
473
|
+
logError("recovery", `auto-resolve .gsd/ conflicts failed: ${e.message}`);
|
|
456
474
|
resolved = false;
|
|
457
475
|
}
|
|
458
476
|
if (resolved) {
|
|
@@ -460,7 +478,8 @@ export function reconcileMergeState(basePath, ctx) {
|
|
|
460
478
|
nativeCommit(basePath, "chore: auto-resolve .gsd/ state file conflicts");
|
|
461
479
|
ctx.ui.notify(`Auto-resolved ${gsdConflicts.length} .gsd/ state file conflict(s) from prior merge.`, "info");
|
|
462
480
|
}
|
|
463
|
-
catch {
|
|
481
|
+
catch (e) {
|
|
482
|
+
logError("recovery", `auto-commit .gsd/ conflict resolution failed: ${e.message}`);
|
|
464
483
|
resolved = false;
|
|
465
484
|
}
|
|
466
485
|
}
|