gsd-pi 2.59.0 → 2.60.0-dev.2580e65
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 +62 -1
- 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 +57 -3
- package/dist/resources/extensions/gsd/auto-post-unit.js +43 -3
- package/dist/resources/extensions/gsd/auto-prompts.js +49 -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 +72 -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 +58 -5
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +11 -10
- package/dist/resources/extensions/gsd/captures.js +54 -1
- 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 +9 -5
- package/dist/resources/extensions/gsd/context-masker.js +68 -0
- package/dist/resources/extensions/gsd/custom-verification.js +3 -2
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +7 -0
- package/dist/resources/extensions/gsd/gsd-db.js +35 -15
- 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 +199 -45
- 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/phase-anchor.js +56 -0
- package/dist/resources/extensions/gsd/preferences-types.js +2 -0
- package/dist/resources/extensions/gsd/preferences-validation.js +91 -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/execute-task.md +2 -0
- package/dist/resources/extensions/gsd/prompts/rethink.md +7 -0
- package/dist/resources/extensions/gsd/prompts/triage-captures.md +6 -1
- package/dist/resources/extensions/gsd/rethink.js +5 -2
- 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/state.js +1 -1
- package/dist/resources/extensions/gsd/status-guards.js +4 -3
- 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 +135 -1
- package/dist/resources/extensions/gsd/triage-ui.js +12 -3
- 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/resources/skills/btw/SKILL.md +42 -0
- 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 +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 +17 -17
- 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-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-0c485498795110d6.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/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/dist/modes/interactive/controllers/input-controller.d.ts +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +6 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +122 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +30 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js +1 -7
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js.map +1 -1
- 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/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +156 -0
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +7 -0
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +38 -0
- package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.ts +1 -8
- package/pkg/package.json +1 -1
- package/src/resources/extensions/ask-user-questions.ts +7 -3
- package/src/resources/extensions/gsd/auto/phases.ts +70 -1
- 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 -6
- package/src/resources/extensions/gsd/auto-post-unit.ts +52 -5
- package/src/resources/extensions/gsd/auto-prompts.ts +54 -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 +80 -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 +61 -4
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +11 -10
- package/src/resources/extensions/gsd/captures.ts +71 -2
- 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 +10 -5
- package/src/resources/extensions/gsd/context-masker.ts +74 -0
- package/src/resources/extensions/gsd/custom-verification.ts +3 -2
- package/src/resources/extensions/gsd/docs/preferences-reference.md +7 -0
- package/src/resources/extensions/gsd/gsd-db.ts +14 -16
- 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 +245 -56
- 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/phase-anchor.ts +71 -0
- package/src/resources/extensions/gsd/preferences-types.ts +22 -0
- package/src/resources/extensions/gsd/preferences-validation.ts +83 -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/execute-task.md +2 -0
- package/src/resources/extensions/gsd/prompts/rethink.md +7 -0
- package/src/resources/extensions/gsd/prompts/triage-captures.md +6 -1
- package/src/resources/extensions/gsd/rethink.ts +5 -2
- 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/state.ts +1 -1
- package/src/resources/extensions/gsd/status-guards.ts +4 -3
- 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/context-masker.test.ts +122 -0
- 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 +488 -2
- package/src/resources/extensions/gsd/tests/phase-anchor.test.ts +83 -0
- 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/status-guards.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/stop-backtrack.test.ts +216 -0
- package/src/resources/extensions/gsd/tests/tool-naming.test.ts +1 -1
- 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 +151 -1
- package/src/resources/extensions/gsd/triage-ui.ts +12 -3
- 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/src/resources/skills/btw/SKILL.md +42 -0
- package/dist/web/standalone/.next/static/chunks/app/page-62be3b5fa91e4c8f.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/dist/web/standalone/.next/static/{DGvT_c5Vb7Wu3X-fEOVUU → ogyMN7M-3bGGuRY08L5HR}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{DGvT_c5Vb7Wu3X-fEOVUU → ogyMN7M-3bGGuRY08L5HR}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phase handoff anchors — compact structured summaries written between
|
|
3
|
+
* GSD auto-mode phases so downstream agents inherit decisions, blockers,
|
|
4
|
+
* and intent without re-inferring from scratch.
|
|
5
|
+
*/
|
|
6
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
7
|
+
import { join } from "node:path";
|
|
8
|
+
import { gsdRoot } from "./paths.js";
|
|
9
|
+
function anchorsDir(basePath, milestoneId) {
|
|
10
|
+
return join(gsdRoot(basePath), "milestones", milestoneId, "anchors");
|
|
11
|
+
}
|
|
12
|
+
function anchorPath(basePath, milestoneId, phase) {
|
|
13
|
+
return join(anchorsDir(basePath, milestoneId), `${phase}.json`);
|
|
14
|
+
}
|
|
15
|
+
export function writePhaseAnchor(basePath, milestoneId, anchor) {
|
|
16
|
+
const dir = anchorsDir(basePath, milestoneId);
|
|
17
|
+
if (!existsSync(dir)) {
|
|
18
|
+
mkdirSync(dir, { recursive: true });
|
|
19
|
+
}
|
|
20
|
+
writeFileSync(anchorPath(basePath, milestoneId, anchor.phase), JSON.stringify(anchor, null, 2), "utf-8");
|
|
21
|
+
}
|
|
22
|
+
export function readPhaseAnchor(basePath, milestoneId, phase) {
|
|
23
|
+
const path = anchorPath(basePath, milestoneId, phase);
|
|
24
|
+
if (!existsSync(path))
|
|
25
|
+
return null;
|
|
26
|
+
try {
|
|
27
|
+
return JSON.parse(readFileSync(path, "utf-8"));
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
export function formatAnchorForPrompt(anchor) {
|
|
34
|
+
const lines = [
|
|
35
|
+
`## Handoff from ${anchor.phase}`,
|
|
36
|
+
"",
|
|
37
|
+
`**Intent:** ${anchor.intent}`,
|
|
38
|
+
];
|
|
39
|
+
if (anchor.decisions.length > 0) {
|
|
40
|
+
lines.push("", "**Decisions:**");
|
|
41
|
+
for (const d of anchor.decisions)
|
|
42
|
+
lines.push(`- ${d}`);
|
|
43
|
+
}
|
|
44
|
+
if (anchor.blockers.length > 0) {
|
|
45
|
+
lines.push("", "**Blockers:**");
|
|
46
|
+
for (const b of anchor.blockers)
|
|
47
|
+
lines.push(`- ${b}`);
|
|
48
|
+
}
|
|
49
|
+
if (anchor.nextSteps.length > 0) {
|
|
50
|
+
lines.push("", "**Next steps:**");
|
|
51
|
+
for (const s of anchor.nextSteps)
|
|
52
|
+
lines.push(`- ${s}`);
|
|
53
|
+
}
|
|
54
|
+
lines.push("", "---");
|
|
55
|
+
return lines.join("\n");
|
|
56
|
+
}
|
|
@@ -71,7 +71,9 @@ export const KNOWN_PREFERENCE_KEYS = new Set([
|
|
|
71
71
|
"forensics_dedup",
|
|
72
72
|
"show_token_cost",
|
|
73
73
|
"stale_commit_threshold_minutes",
|
|
74
|
+
"context_management",
|
|
74
75
|
"experimental",
|
|
76
|
+
"codebase",
|
|
75
77
|
]);
|
|
76
78
|
/** Canonical list of all dispatch unit types. */
|
|
77
79
|
export const KNOWN_UNIT_TYPES = [
|
|
@@ -425,6 +425,12 @@ export function validatePreferences(preferences) {
|
|
|
425
425
|
else
|
|
426
426
|
errors.push("dynamic_routing.hooks must be a boolean");
|
|
427
427
|
}
|
|
428
|
+
if (dr.capability_routing !== undefined) {
|
|
429
|
+
if (typeof dr.capability_routing === "boolean")
|
|
430
|
+
validDr.capability_routing = dr.capability_routing;
|
|
431
|
+
else
|
|
432
|
+
errors.push("dynamic_routing.capability_routing must be a boolean");
|
|
433
|
+
}
|
|
428
434
|
if (dr.tier_models !== undefined) {
|
|
429
435
|
if (typeof dr.tier_models === "object" && dr.tier_models !== null) {
|
|
430
436
|
const tm = dr.tier_models;
|
|
@@ -452,6 +458,46 @@ export function validatePreferences(preferences) {
|
|
|
452
458
|
errors.push("dynamic_routing must be an object");
|
|
453
459
|
}
|
|
454
460
|
}
|
|
461
|
+
// ─── Context Management ──────────────────────────────────────────────
|
|
462
|
+
if (preferences.context_management !== undefined) {
|
|
463
|
+
if (typeof preferences.context_management === "object" && preferences.context_management !== null) {
|
|
464
|
+
const cm = preferences.context_management;
|
|
465
|
+
const validCm = {};
|
|
466
|
+
if (cm.observation_masking !== undefined) {
|
|
467
|
+
if (typeof cm.observation_masking === "boolean")
|
|
468
|
+
validCm.observation_masking = cm.observation_masking;
|
|
469
|
+
else
|
|
470
|
+
errors.push("context_management.observation_masking must be a boolean");
|
|
471
|
+
}
|
|
472
|
+
if (cm.observation_mask_turns !== undefined) {
|
|
473
|
+
const turns = cm.observation_mask_turns;
|
|
474
|
+
if (typeof turns === "number" && turns >= 1 && turns <= 50)
|
|
475
|
+
validCm.observation_mask_turns = turns;
|
|
476
|
+
else
|
|
477
|
+
errors.push("context_management.observation_mask_turns must be a number between 1 and 50");
|
|
478
|
+
}
|
|
479
|
+
if (cm.compaction_threshold_percent !== undefined) {
|
|
480
|
+
const pct = cm.compaction_threshold_percent;
|
|
481
|
+
if (typeof pct === "number" && pct >= 0.5 && pct <= 0.95)
|
|
482
|
+
validCm.compaction_threshold_percent = pct;
|
|
483
|
+
else
|
|
484
|
+
errors.push("context_management.compaction_threshold_percent must be a number between 0.5 and 0.95");
|
|
485
|
+
}
|
|
486
|
+
if (cm.tool_result_max_chars !== undefined) {
|
|
487
|
+
const chars = cm.tool_result_max_chars;
|
|
488
|
+
if (typeof chars === "number" && chars >= 200 && chars <= 10000)
|
|
489
|
+
validCm.tool_result_max_chars = chars;
|
|
490
|
+
else
|
|
491
|
+
errors.push("context_management.tool_result_max_chars must be a number between 200 and 10000");
|
|
492
|
+
}
|
|
493
|
+
if (Object.keys(validCm).length > 0) {
|
|
494
|
+
validated.context_management = validCm;
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
else {
|
|
498
|
+
errors.push("context_management must be an object");
|
|
499
|
+
}
|
|
500
|
+
}
|
|
455
501
|
// ─── Parallel Config ────────────────────────────────────────────────────
|
|
456
502
|
if (preferences.parallel && typeof preferences.parallel === "object") {
|
|
457
503
|
const p = preferences.parallel;
|
|
@@ -848,5 +894,50 @@ export function validatePreferences(preferences) {
|
|
|
848
894
|
errors.push("experimental must be an object");
|
|
849
895
|
}
|
|
850
896
|
}
|
|
897
|
+
// ─── Codebase Map ──────────────────────────────────────────────────
|
|
898
|
+
if (preferences.codebase !== undefined) {
|
|
899
|
+
if (typeof preferences.codebase === "object" && preferences.codebase !== null) {
|
|
900
|
+
const cb = preferences.codebase;
|
|
901
|
+
const validCb = {};
|
|
902
|
+
if (cb.exclude_patterns !== undefined) {
|
|
903
|
+
if (Array.isArray(cb.exclude_patterns) && cb.exclude_patterns.every((p) => typeof p === "string")) {
|
|
904
|
+
validCb.exclude_patterns = cb.exclude_patterns;
|
|
905
|
+
}
|
|
906
|
+
else {
|
|
907
|
+
errors.push("codebase.exclude_patterns must be an array of strings");
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
if (cb.max_files !== undefined) {
|
|
911
|
+
const mf = typeof cb.max_files === "number" ? cb.max_files : Number(cb.max_files);
|
|
912
|
+
if (Number.isFinite(mf) && mf >= 1) {
|
|
913
|
+
validCb.max_files = Math.floor(mf);
|
|
914
|
+
}
|
|
915
|
+
else {
|
|
916
|
+
errors.push("codebase.max_files must be a positive integer");
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
if (cb.collapse_threshold !== undefined) {
|
|
920
|
+
const ct = typeof cb.collapse_threshold === "number" ? cb.collapse_threshold : Number(cb.collapse_threshold);
|
|
921
|
+
if (Number.isFinite(ct) && ct >= 1) {
|
|
922
|
+
validCb.collapse_threshold = Math.floor(ct);
|
|
923
|
+
}
|
|
924
|
+
else {
|
|
925
|
+
errors.push("codebase.collapse_threshold must be a positive integer");
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
const knownCbKeys = new Set(["exclude_patterns", "max_files", "collapse_threshold"]);
|
|
929
|
+
for (const key of Object.keys(cb)) {
|
|
930
|
+
if (!knownCbKeys.has(key)) {
|
|
931
|
+
warnings.push(`unknown codebase key "${key}" — ignored`);
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
if (Object.keys(validCb).length > 0) {
|
|
935
|
+
validated.codebase = validCb;
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
else {
|
|
939
|
+
errors.push("codebase must be an object");
|
|
940
|
+
}
|
|
941
|
+
}
|
|
851
942
|
return { preferences: validated, errors, warnings };
|
|
852
943
|
}
|
|
@@ -15,6 +15,7 @@ import { join } from "node:path";
|
|
|
15
15
|
import { gsdRoot } from "./paths.js";
|
|
16
16
|
import { parse as parseYaml } from "yaml";
|
|
17
17
|
import { normalizeStringArray } from "../shared/format-utils.js";
|
|
18
|
+
import { logWarning } from "./workflow-logger.js";
|
|
18
19
|
import { resolveProfileDefaults as _resolveProfileDefaults } from "./preferences-models.js";
|
|
19
20
|
import { KNOWN_PREFERENCE_KEYS, MODE_DEFAULTS, } from "./preferences-types.js";
|
|
20
21
|
import { validatePreferences } from "./preferences-validation.js";
|
|
@@ -162,7 +163,7 @@ function parseFrontmatterBlock(frontmatter) {
|
|
|
162
163
|
return parsed;
|
|
163
164
|
}
|
|
164
165
|
catch (e) {
|
|
165
|
-
|
|
166
|
+
logWarning("guided", `YAML parse error in frontmatter block: ${e.message}`);
|
|
166
167
|
return {};
|
|
167
168
|
}
|
|
168
169
|
}
|
|
@@ -217,8 +218,8 @@ function parseHeadingListFormat(content) {
|
|
|
217
218
|
}
|
|
218
219
|
typed[targetSection] = value;
|
|
219
220
|
}
|
|
220
|
-
catch {
|
|
221
|
-
|
|
221
|
+
catch (e) {
|
|
222
|
+
logWarning("guided", `preferences section parse failed: ${e.message}`);
|
|
222
223
|
}
|
|
223
224
|
}
|
|
224
225
|
return typed;
|
|
@@ -289,6 +290,17 @@ function mergePreferences(base, override) {
|
|
|
289
290
|
service_tier: override.service_tier ?? base.service_tier,
|
|
290
291
|
forensics_dedup: override.forensics_dedup ?? base.forensics_dedup,
|
|
291
292
|
show_token_cost: override.show_token_cost ?? base.show_token_cost,
|
|
293
|
+
codebase: (base.codebase || override.codebase)
|
|
294
|
+
? {
|
|
295
|
+
...(base.codebase ?? {}),
|
|
296
|
+
...(override.codebase ?? {}),
|
|
297
|
+
// Merge exclude_patterns arrays rather than overriding
|
|
298
|
+
exclude_patterns: [
|
|
299
|
+
...((base.codebase?.exclude_patterns) ?? []),
|
|
300
|
+
...((override.codebase?.exclude_patterns) ?? []),
|
|
301
|
+
].filter(Boolean),
|
|
302
|
+
}
|
|
303
|
+
: undefined,
|
|
292
304
|
};
|
|
293
305
|
}
|
|
294
306
|
function mergeStringLists(base, override) {
|
|
@@ -21,6 +21,7 @@ import { GSDError, GSD_PARSE_ERROR } from "./errors.js";
|
|
|
21
21
|
import { join, dirname } from "node:path";
|
|
22
22
|
import { fileURLToPath } from "node:url";
|
|
23
23
|
import { homedir } from "node:os";
|
|
24
|
+
import { logWarning } from "./workflow-logger.js";
|
|
24
25
|
/**
|
|
25
26
|
* Resolve the GSD extension directory.
|
|
26
27
|
*
|
|
@@ -69,7 +70,7 @@ function warmCache() {
|
|
|
69
70
|
// prompts/ may not exist in test environments — lazy loading still works.
|
|
70
71
|
// Emit a diagnostic when running outside tests so wrong-path bugs are visible.
|
|
71
72
|
if (!process.env.VITEST && !process.env.NODE_TEST) {
|
|
72
|
-
|
|
73
|
+
logWarning("prompt", `warmCache: prompts dir not found: ${promptsDir}`);
|
|
73
74
|
}
|
|
74
75
|
}
|
|
75
76
|
try {
|
|
@@ -85,7 +86,7 @@ function warmCache() {
|
|
|
85
86
|
catch {
|
|
86
87
|
// templates/ may not exist in test environments — lazy loading still works.
|
|
87
88
|
if (!process.env.VITEST && !process.env.NODE_TEST) {
|
|
88
|
-
|
|
89
|
+
logWarning("prompt", `warmCache: templates dir not found: ${templatesDir}`);
|
|
89
90
|
}
|
|
90
91
|
}
|
|
91
92
|
}
|
|
@@ -45,6 +45,13 @@ reason: "<reason>"
|
|
|
45
45
|
### Unpark a milestone
|
|
46
46
|
Remove the `{ID}-PARKED.md` file from the milestone directory to reactivate it.
|
|
47
47
|
|
|
48
|
+
### Skip a slice
|
|
49
|
+
Mark a slice as skipped so auto-mode advances past it without executing. Use the `gsd_skip_slice` tool:
|
|
50
|
+
```
|
|
51
|
+
gsd_skip_slice({ milestoneId: "M003", sliceId: "S02", reason: "Descoped — feature moved to M005" })
|
|
52
|
+
```
|
|
53
|
+
Skipped slices are treated as closed by the state machine (like "complete" but distinct). Use when a slice is no longer needed or has been superseded. The slice data is preserved for reference.
|
|
54
|
+
|
|
48
55
|
### Discard a milestone
|
|
49
56
|
**Permanently** delete a milestone directory and prune it from QUEUE-ORDER.json. **Always confirm with the user before discarding.** Warn explicitly if the milestone has completed work.
|
|
50
57
|
|
|
@@ -20,6 +20,8 @@ The user captured thoughts during execution using `/gsd capture`. Your job is to
|
|
|
20
20
|
|
|
21
21
|
For each capture, classify it as one of:
|
|
22
22
|
|
|
23
|
+
- **stop**: User directive to halt auto-mode immediately. Use when the user says "stop", "halt", "abort", "don't continue", "pause", or otherwise wants execution to cease. Auto-mode will pause after the current unit completes. Examples: "stop running", "halt execution", "don't continue".
|
|
24
|
+
- **backtrack**: User directive to abandon the current milestone and return to a previous one. The user believes earlier milestones missed critical features or need rework. Include the target milestone ID (e.g., M003) in the Resolution field. Auto-mode will pause and write a regression marker. Examples: "restart from M003", "go back to milestone 3", "M004 and M005 failed, restart from M003".
|
|
23
25
|
- **quick-task**: Small, self-contained, no downstream impact. Can be done in minutes without modifying the plan. Examples: fix a typo, add a missing import, tweak a config value.
|
|
24
26
|
- **inject**: Belongs in the current slice but wasn't planned. Needs a new task added to the slice plan. Examples: add error handling to a module being built, add a missing test case for current work.
|
|
25
27
|
- **defer**: Belongs in a future slice or milestone. Not urgent for current work. Examples: performance optimization, feature that depends on unbuilt infrastructure, nice-to-have enhancement.
|
|
@@ -28,10 +30,12 @@ For each capture, classify it as one of:
|
|
|
28
30
|
|
|
29
31
|
## Decision Guidelines
|
|
30
32
|
|
|
33
|
+
- **ALWAYS classify as stop** when the user explicitly says "stop", "halt", "abort", or "don't continue". Never shoe-horn a stop directive into "replan" or "note".
|
|
34
|
+
- **ALWAYS classify as backtrack** when the user references returning to a previous milestone, restarting from an earlier point, or abandoning current milestone work. Include the target milestone ID in the Resolution field (e.g., "Backtrack to M003").
|
|
31
35
|
- Prefer **quick-task** when the work is clearly small and self-contained.
|
|
32
36
|
- Prefer **inject** over **replan** when only a new task is needed, not rewriting existing ones.
|
|
33
37
|
- Prefer **defer** over **inject** when the work doesn't belong in the current slice's scope.
|
|
34
|
-
- Use **replan** only when remaining incomplete tasks need to change — not
|
|
38
|
+
- Use **replan** only when remaining incomplete tasks in the *current slice* need to change — not for cross-milestone issues.
|
|
35
39
|
- Use **note** for observations that don't require action.
|
|
36
40
|
- When unsure between quick-task and inject, consider: will this take more than 10 minutes? If yes, inject.
|
|
37
41
|
|
|
@@ -46,6 +50,7 @@ For each capture, classify it as one of:
|
|
|
46
50
|
- If applicable, which files would be affected
|
|
47
51
|
|
|
48
52
|
For captures classified as **note** or **defer**, auto-confirm without asking — these are low-impact.
|
|
53
|
+
For captures classified as **stop** or **backtrack**, auto-confirm without asking — these are urgent user directives that must be honored immediately.
|
|
49
54
|
For captures classified as **quick-task**, **inject**, or **replan**, ask the user to confirm or choose a different classification.
|
|
50
55
|
|
|
51
56
|
3. **Update** `.gsd/CAPTURES.md` — for each capture, update its section with the confirmed classification:
|
|
@@ -81,8 +81,11 @@ function buildRethinkData(basePath, milestoneIds, state, queueOrder) {
|
|
|
81
81
|
if (dbAvailable && status !== "complete") {
|
|
82
82
|
const slices = getMilestoneSlices(mid);
|
|
83
83
|
if (slices.length > 0) {
|
|
84
|
-
const done = slices.filter(s => s.status === "complete").length;
|
|
85
|
-
|
|
84
|
+
const done = slices.filter(s => s.status === "complete" || s.status === "done").length;
|
|
85
|
+
const skipped = slices.filter(s => s.status === "skipped").length;
|
|
86
|
+
sliceInfo = skipped > 0
|
|
87
|
+
? `${done}/${slices.length} complete, ${skipped} skipped`
|
|
88
|
+
: `${done}/${slices.length} complete`;
|
|
86
89
|
}
|
|
87
90
|
}
|
|
88
91
|
// Add parked reason if applicable
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
// and encapsulates mutable hook state as instance fields.
|
|
6
6
|
//
|
|
7
7
|
// A module-level singleton accessor allows existing code to migrate incrementally.
|
|
8
|
+
import { logWarning } from "./workflow-logger.js";
|
|
8
9
|
import { resolvePostUnitHooks, resolvePreDispatchHooks } from "./preferences.js";
|
|
9
10
|
import { existsSync, readFileSync, writeFileSync, mkdirSync } from "node:fs";
|
|
10
11
|
import { join } from "node:path";
|
|
@@ -310,8 +311,8 @@ export class RuleRegistry {
|
|
|
310
311
|
mkdirSync(dir, { recursive: true });
|
|
311
312
|
writeFileSync(this._hookStatePath(basePath), JSON.stringify(state, null, 2), "utf-8");
|
|
312
313
|
}
|
|
313
|
-
catch {
|
|
314
|
-
|
|
314
|
+
catch (e) {
|
|
315
|
+
logWarning("registry", `failed to persist hook state: ${e.message}`);
|
|
315
316
|
}
|
|
316
317
|
}
|
|
317
318
|
/** Restore hook cycle counts from disk after a crash/restart. */
|
|
@@ -331,8 +332,8 @@ export class RuleRegistry {
|
|
|
331
332
|
}
|
|
332
333
|
}
|
|
333
334
|
}
|
|
334
|
-
catch {
|
|
335
|
-
|
|
335
|
+
catch (e) {
|
|
336
|
+
logWarning("registry", `failed to restore hook state: ${e.message}`);
|
|
336
337
|
}
|
|
337
338
|
}
|
|
338
339
|
/** Clear persisted hook state file from disk. */
|
|
@@ -343,8 +344,8 @@ export class RuleRegistry {
|
|
|
343
344
|
writeFileSync(filePath, JSON.stringify({ cycleCounts: {}, savedAt: new Date().toISOString() }, null, 2), "utf-8");
|
|
344
345
|
}
|
|
345
346
|
}
|
|
346
|
-
catch {
|
|
347
|
-
|
|
347
|
+
catch (e) {
|
|
348
|
+
logWarning("registry", `failed to clear hook state: ${e.message}`);
|
|
348
349
|
}
|
|
349
350
|
}
|
|
350
351
|
// ── Hook status reporting ───────────────────────────────────────────
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, cpSync } from "node:fs";
|
|
2
2
|
import { dirname } from "node:path";
|
|
3
|
+
import { logWarning } from "./workflow-logger.js";
|
|
3
4
|
/**
|
|
4
5
|
* Safely creates a directory. Returns true if successful, false on error.
|
|
5
|
-
* Logs
|
|
6
|
+
* Logs warnings via workflow-logger on failure.
|
|
6
7
|
*/
|
|
7
8
|
export function safeMkdir(dirPath) {
|
|
8
9
|
try {
|
|
@@ -10,14 +11,13 @@ export function safeMkdir(dirPath) {
|
|
|
10
11
|
return true;
|
|
11
12
|
}
|
|
12
13
|
catch (err) {
|
|
13
|
-
|
|
14
|
-
console.error(`[gsd] mkdir failed: ${dirPath}`, err);
|
|
14
|
+
logWarning("fs", `mkdir failed: ${dirPath}: ${err.message}`);
|
|
15
15
|
return false;
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
/**
|
|
19
19
|
* Safely copies src to dst. Returns true if successful, false if src doesn't exist or copy fails.
|
|
20
|
-
* Logs
|
|
20
|
+
* Logs warnings via workflow-logger on failure.
|
|
21
21
|
*/
|
|
22
22
|
export function safeCopy(src, dst, opts) {
|
|
23
23
|
if (!existsSync(src))
|
|
@@ -27,8 +27,7 @@ export function safeCopy(src, dst, opts) {
|
|
|
27
27
|
return true;
|
|
28
28
|
}
|
|
29
29
|
catch (err) {
|
|
30
|
-
|
|
31
|
-
console.error(`[gsd] copy failed: ${src} → ${dst}`, err);
|
|
30
|
+
logWarning("fs", `copy failed: ${src} → ${dst}: ${err.message}`);
|
|
32
31
|
return false;
|
|
33
32
|
}
|
|
34
33
|
}
|
|
@@ -45,8 +44,7 @@ export function safeCopyRecursive(src, dst, opts) {
|
|
|
45
44
|
return true;
|
|
46
45
|
}
|
|
47
46
|
catch (err) {
|
|
48
|
-
|
|
49
|
-
console.error(`[gsd] recursive copy failed: ${src} → ${dst}`, err);
|
|
47
|
+
logWarning("fs", `recursive copy failed: ${src} → ${dst}: ${err.message}`);
|
|
50
48
|
return false;
|
|
51
49
|
}
|
|
52
50
|
}
|
|
@@ -223,7 +223,7 @@ function extractContextTitle(content, fallback) {
|
|
|
223
223
|
* Helper: check if a DB status counts as "done" (handles K002 ambiguity).
|
|
224
224
|
*/
|
|
225
225
|
function isStatusDone(status) {
|
|
226
|
-
return status === 'complete' || status === 'done';
|
|
226
|
+
return status === 'complete' || status === 'done' || status === 'skipped';
|
|
227
227
|
}
|
|
228
228
|
/**
|
|
229
229
|
* Derive GSD state from the milestones/slices/tasks DB tables.
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Status predicates for GSD state-machine guards.
|
|
3
3
|
*
|
|
4
|
-
* The DB stores status as free-form strings.
|
|
5
|
-
* "closed": "complete" (canonical)
|
|
4
|
+
* The DB stores status as free-form strings. Three values indicate
|
|
5
|
+
* "closed": "complete" (canonical), "done" (legacy / alias), and
|
|
6
|
+
* "skipped" (user-directed skip via rethink or backtrack).
|
|
6
7
|
* Every inline `status === "complete" || status === "done"` should
|
|
7
8
|
* use isClosedStatus() instead.
|
|
8
9
|
*/
|
|
9
10
|
/** Returns true when a milestone, slice, or task status indicates closure. */
|
|
10
11
|
export function isClosedStatus(status) {
|
|
11
|
-
return status === "complete" || status === "done";
|
|
12
|
+
return status === "complete" || status === "done" || status === "skipped";
|
|
12
13
|
}
|
|
@@ -15,6 +15,7 @@ import { invalidateStateCache } from "../state.js";
|
|
|
15
15
|
import { renderAllProjections } from "../workflow-projections.js";
|
|
16
16
|
import { writeManifest } from "../workflow-manifest.js";
|
|
17
17
|
import { appendEvent } from "../workflow-events.js";
|
|
18
|
+
import { logWarning } from "../workflow-logger.js";
|
|
18
19
|
function renderMilestoneSummaryMarkdown(params) {
|
|
19
20
|
const now = new Date().toISOString();
|
|
20
21
|
const keyDecisionsYaml = params.keyDecisions.length > 0
|
|
@@ -140,7 +141,7 @@ export async function handleCompleteMilestone(params, basePath) {
|
|
|
140
141
|
}
|
|
141
142
|
catch (renderErr) {
|
|
142
143
|
// Disk render failed — roll back DB status so state stays consistent
|
|
143
|
-
|
|
144
|
+
logWarning("tool", `complete_milestone — disk render failed, rolling back DB status: ${renderErr.message}`);
|
|
144
145
|
updateMilestoneStatus(params.milestoneId, 'active', null);
|
|
145
146
|
invalidateStateCache();
|
|
146
147
|
return { error: `disk render failed: ${renderErr.message}` };
|
|
@@ -163,7 +164,7 @@ export async function handleCompleteMilestone(params, basePath) {
|
|
|
163
164
|
});
|
|
164
165
|
}
|
|
165
166
|
catch (hookErr) {
|
|
166
|
-
|
|
167
|
+
logWarning("tool", `complete-milestone post-mutation hook warning: ${hookErr.message}`);
|
|
167
168
|
}
|
|
168
169
|
return {
|
|
169
170
|
milestoneId: params.milestoneId,
|
|
@@ -18,6 +18,7 @@ import { renderRoadmapCheckboxes } from "../markdown-renderer.js";
|
|
|
18
18
|
import { renderAllProjections } from "../workflow-projections.js";
|
|
19
19
|
import { writeManifest } from "../workflow-manifest.js";
|
|
20
20
|
import { appendEvent } from "../workflow-events.js";
|
|
21
|
+
import { logWarning } from "../workflow-logger.js";
|
|
21
22
|
/**
|
|
22
23
|
* Render slice summary markdown matching the template format.
|
|
23
24
|
* YAML frontmatter uses snake_case keys for parseSummary() compatibility.
|
|
@@ -240,7 +241,7 @@ export async function handleCompleteSlice(params, basePath) {
|
|
|
240
241
|
}
|
|
241
242
|
catch (renderErr) {
|
|
242
243
|
// Disk render failed — roll back DB status so state stays consistent
|
|
243
|
-
|
|
244
|
+
logWarning("tool", `complete_slice — disk render failed, rolling back DB status: ${renderErr.message}`);
|
|
244
245
|
updateSliceStatus(params.milestoneId, params.sliceId, 'pending');
|
|
245
246
|
invalidateStateCache();
|
|
246
247
|
return { error: `disk render failed: ${renderErr.message}` };
|
|
@@ -265,7 +266,7 @@ export async function handleCompleteSlice(params, basePath) {
|
|
|
265
266
|
});
|
|
266
267
|
}
|
|
267
268
|
catch (hookErr) {
|
|
268
|
-
|
|
269
|
+
logWarning("tool", `complete-slice post-mutation hook warning: ${hookErr.message}`);
|
|
269
270
|
}
|
|
270
271
|
return {
|
|
271
272
|
sliceId: params.sliceId,
|
|
@@ -18,6 +18,7 @@ import { renderPlanCheckboxes } from "../markdown-renderer.js";
|
|
|
18
18
|
import { renderAllProjections, renderSummaryContent } from "../workflow-projections.js";
|
|
19
19
|
import { writeManifest } from "../workflow-manifest.js";
|
|
20
20
|
import { appendEvent } from "../workflow-events.js";
|
|
21
|
+
import { logWarning } from "../workflow-logger.js";
|
|
21
22
|
/**
|
|
22
23
|
* Build a TaskRow-shaped object from CompleteTaskParams so the unified
|
|
23
24
|
* renderSummaryContent() can be used at completion time (#2720).
|
|
@@ -165,7 +166,7 @@ export async function handleCompleteTask(params, basePath) {
|
|
|
165
166
|
}
|
|
166
167
|
catch (renderErr) {
|
|
167
168
|
// Disk render failed — roll back DB status so state stays consistent
|
|
168
|
-
|
|
169
|
+
logWarning("tool", `complete_task — disk render failed, rolling back DB status: ${renderErr.message}`);
|
|
169
170
|
// Delete orphaned verification_evidence rows first (FK constraint
|
|
170
171
|
// references tasks, so evidence must go before status change).
|
|
171
172
|
// Without this, retries accumulate duplicate evidence rows (#2724).
|
|
@@ -194,7 +195,7 @@ export async function handleCompleteTask(params, basePath) {
|
|
|
194
195
|
});
|
|
195
196
|
}
|
|
196
197
|
catch (hookErr) {
|
|
197
|
-
|
|
198
|
+
logWarning("tool", `complete-task post-mutation hook warning: ${hookErr.message}`);
|
|
198
199
|
}
|
|
199
200
|
return {
|
|
200
201
|
taskId: params.taskId,
|
|
@@ -7,6 +7,7 @@ import { renderRoadmapFromDb } from "../markdown-renderer.js";
|
|
|
7
7
|
import { renderAllProjections } from "../workflow-projections.js";
|
|
8
8
|
import { writeManifest } from "../workflow-manifest.js";
|
|
9
9
|
import { appendEvent } from "../workflow-events.js";
|
|
10
|
+
import { logWarning } from "../workflow-logger.js";
|
|
10
11
|
function validateRiskEntries(value) {
|
|
11
12
|
if (!Array.isArray(value)) {
|
|
12
13
|
throw new Error("keyRisks must be an array");
|
|
@@ -221,7 +222,7 @@ export async function handlePlanMilestone(rawParams, basePath) {
|
|
|
221
222
|
roadmapPath = renderResult.roadmapPath;
|
|
222
223
|
}
|
|
223
224
|
catch (renderErr) {
|
|
224
|
-
|
|
225
|
+
logWarning("tool", `plan_milestone — render failed (DB rows preserved for debugging): ${renderErr.message}`);
|
|
225
226
|
invalidateStateCache();
|
|
226
227
|
return { error: `render failed: ${renderErr.message}` };
|
|
227
228
|
}
|
|
@@ -241,7 +242,7 @@ export async function handlePlanMilestone(rawParams, basePath) {
|
|
|
241
242
|
});
|
|
242
243
|
}
|
|
243
244
|
catch (hookErr) {
|
|
244
|
-
|
|
245
|
+
logWarning("tool", `plan-milestone post-mutation hook warning: ${hookErr.message}`);
|
|
245
246
|
}
|
|
246
247
|
return {
|
|
247
248
|
milestoneId: params.milestoneId,
|
|
@@ -7,6 +7,7 @@ import { renderPlanFromDb } from "../markdown-renderer.js";
|
|
|
7
7
|
import { renderAllProjections } from "../workflow-projections.js";
|
|
8
8
|
import { writeManifest } from "../workflow-manifest.js";
|
|
9
9
|
import { appendEvent } from "../workflow-events.js";
|
|
10
|
+
import { logWarning } from "../workflow-logger.js";
|
|
10
11
|
function validateTasks(value) {
|
|
11
12
|
if (!Array.isArray(value) || value.length === 0) {
|
|
12
13
|
throw new Error("tasks must be a non-empty array");
|
|
@@ -182,7 +183,7 @@ export async function handlePlanSlice(rawParams, basePath) {
|
|
|
182
183
|
});
|
|
183
184
|
}
|
|
184
185
|
catch (hookErr) {
|
|
185
|
-
|
|
186
|
+
logWarning("tool", `plan-slice post-mutation hook warning: ${hookErr.message}`);
|
|
186
187
|
}
|
|
187
188
|
return {
|
|
188
189
|
milestoneId: params.milestoneId,
|
|
@@ -192,7 +193,7 @@ export async function handlePlanSlice(rawParams, basePath) {
|
|
|
192
193
|
};
|
|
193
194
|
}
|
|
194
195
|
catch (renderErr) {
|
|
195
|
-
|
|
196
|
+
logWarning("tool", `plan_slice — render failed (DB rows preserved for debugging): ${renderErr.message}`);
|
|
196
197
|
invalidateStateCache();
|
|
197
198
|
return { error: `render failed: ${renderErr.message}` };
|
|
198
199
|
}
|
|
@@ -7,6 +7,7 @@ import { renderTaskPlanFromDb } from "../markdown-renderer.js";
|
|
|
7
7
|
import { renderAllProjections } from "../workflow-projections.js";
|
|
8
8
|
import { writeManifest } from "../workflow-manifest.js";
|
|
9
9
|
import { appendEvent } from "../workflow-events.js";
|
|
10
|
+
import { logWarning } from "../workflow-logger.js";
|
|
10
11
|
function validateParams(params) {
|
|
11
12
|
if (!isNonEmptyString(params?.milestoneId))
|
|
12
13
|
throw new Error("milestoneId is required");
|
|
@@ -106,7 +107,7 @@ export async function handlePlanTask(rawParams, basePath) {
|
|
|
106
107
|
});
|
|
107
108
|
}
|
|
108
109
|
catch (hookErr) {
|
|
109
|
-
|
|
110
|
+
logWarning("tool", `plan-task post-mutation hook warning: ${hookErr.message}`);
|
|
110
111
|
}
|
|
111
112
|
return {
|
|
112
113
|
milestoneId: params.milestoneId,
|
|
@@ -9,6 +9,7 @@ import { renderRoadmapFromDb, renderAssessmentFromDb } from "../markdown-rendere
|
|
|
9
9
|
import { renderAllProjections } from "../workflow-projections.js";
|
|
10
10
|
import { writeManifest } from "../workflow-manifest.js";
|
|
11
11
|
import { appendEvent } from "../workflow-events.js";
|
|
12
|
+
import { logWarning } from "../workflow-logger.js";
|
|
12
13
|
function validateParams(params) {
|
|
13
14
|
if (!isNonEmptyString(params?.milestoneId))
|
|
14
15
|
throw new Error("milestoneId is required");
|
|
@@ -182,9 +183,8 @@ export async function handleReassessRoadmap(rawParams, basePath) {
|
|
|
182
183
|
if (existsSync(validationFile))
|
|
183
184
|
unlinkSync(validationFile);
|
|
184
185
|
}
|
|
185
|
-
catch {
|
|
186
|
-
|
|
187
|
-
// will not see the file-based verdict as authoritative.
|
|
186
|
+
catch (e) {
|
|
187
|
+
logWarning("tool", `validation file cleanup failed: ${e.message}`);
|
|
188
188
|
}
|
|
189
189
|
}
|
|
190
190
|
// ── Invalidate caches ─────────────────────────────────────────
|
|
@@ -204,7 +204,7 @@ export async function handleReassessRoadmap(rawParams, basePath) {
|
|
|
204
204
|
});
|
|
205
205
|
}
|
|
206
206
|
catch (hookErr) {
|
|
207
|
-
|
|
207
|
+
logWarning("tool", `reassess-roadmap post-mutation hook warning: ${hookErr.message}`);
|
|
208
208
|
}
|
|
209
209
|
return {
|
|
210
210
|
milestoneId: params.milestoneId,
|
|
@@ -15,6 +15,7 @@ import { isClosedStatus } from "../status-guards.js";
|
|
|
15
15
|
import { renderAllProjections } from "../workflow-projections.js";
|
|
16
16
|
import { writeManifest } from "../workflow-manifest.js";
|
|
17
17
|
import { appendEvent } from "../workflow-events.js";
|
|
18
|
+
import { logWarning } from "../workflow-logger.js";
|
|
18
19
|
export async function handleReopenSlice(params, basePath) {
|
|
19
20
|
// ── Validate required fields ────────────────────────────────────────────
|
|
20
21
|
if (!params.sliceId || typeof params.sliceId !== "string" || params.sliceId.trim() === "") {
|
|
@@ -77,7 +78,7 @@ export async function handleReopenSlice(params, basePath) {
|
|
|
77
78
|
});
|
|
78
79
|
}
|
|
79
80
|
catch (hookErr) {
|
|
80
|
-
|
|
81
|
+
logWarning("tool", `reopen-slice post-mutation hook warning: ${hookErr.message}`);
|
|
81
82
|
}
|
|
82
83
|
return {
|
|
83
84
|
milestoneId: params.milestoneId,
|