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
|
@@ -115,7 +115,7 @@ import {
|
|
|
115
115
|
formatCost,
|
|
116
116
|
formatTokenCount,
|
|
117
117
|
} from "./metrics.js";
|
|
118
|
-
import { setLogBasePath } from "./workflow-logger.js";
|
|
118
|
+
import { setLogBasePath, logWarning, logError } from "./workflow-logger.js";
|
|
119
119
|
import { join } from "node:path";
|
|
120
120
|
import { readFileSync, existsSync, mkdirSync, writeFileSync, unlinkSync } from "node:fs";
|
|
121
121
|
import { atomicWriteSync } from "./atomic-write.js";
|
|
@@ -316,8 +316,9 @@ export function getAutoDashboardData(): AutoDashboardData {
|
|
|
316
316
|
if (s.basePath) {
|
|
317
317
|
pendingCaptureCount = countPendingCaptures(s.basePath);
|
|
318
318
|
}
|
|
319
|
-
} catch {
|
|
319
|
+
} catch (err) {
|
|
320
320
|
// Non-fatal — captures module may not be loaded
|
|
321
|
+
logWarning("engine", `capture count failed: ${err instanceof Error ? err.message : String(err)}`, { file: "auto.ts" });
|
|
321
322
|
}
|
|
322
323
|
return {
|
|
323
324
|
active: s.active,
|
|
@@ -565,8 +566,9 @@ function cleanupAfterLoopExit(ctx: ExtensionContext): void {
|
|
|
565
566
|
try {
|
|
566
567
|
if (lockBase()) clearLock(lockBase());
|
|
567
568
|
if (lockBase()) releaseSessionLock(lockBase());
|
|
568
|
-
} catch {
|
|
569
|
+
} catch (err) {
|
|
569
570
|
/* best-effort — mirror stopAuto cleanup */
|
|
571
|
+
logWarning("session", `lock cleanup failed: ${err instanceof Error ? err.message : String(err)}`, { file: "auto.ts" });
|
|
570
572
|
}
|
|
571
573
|
|
|
572
574
|
ctx.ui.setStatus("gsd-auto", undefined);
|
|
@@ -578,8 +580,9 @@ function cleanupAfterLoopExit(ctx: ExtensionContext): void {
|
|
|
578
580
|
s.basePath = s.originalBasePath;
|
|
579
581
|
try {
|
|
580
582
|
process.chdir(s.basePath);
|
|
581
|
-
} catch {
|
|
583
|
+
} catch (err) {
|
|
582
584
|
/* best-effort */
|
|
585
|
+
logWarning("engine", `chdir failed: ${err instanceof Error ? err.message : String(err)}`, { file: "auto.ts" });
|
|
583
586
|
}
|
|
584
587
|
}
|
|
585
588
|
}
|
|
@@ -651,8 +654,9 @@ export async function stopAuto(
|
|
|
651
654
|
} else {
|
|
652
655
|
milestoneComplete = true;
|
|
653
656
|
}
|
|
654
|
-
} catch {
|
|
657
|
+
} catch (err) {
|
|
655
658
|
// Non-fatal — fall through to preserveBranch path
|
|
659
|
+
logWarning("engine", `milestone summary check failed: ${err instanceof Error ? err.message : String(err)}`, { file: "auto.ts" });
|
|
656
660
|
}
|
|
657
661
|
|
|
658
662
|
if (milestoneComplete) {
|
|
@@ -687,8 +691,9 @@ export async function stopAuto(
|
|
|
687
691
|
s.basePath = s.originalBasePath;
|
|
688
692
|
try {
|
|
689
693
|
process.chdir(s.basePath);
|
|
690
|
-
} catch {
|
|
694
|
+
} catch (err) {
|
|
691
695
|
/* best-effort */
|
|
696
|
+
logWarning("engine", `chdir failed: ${err instanceof Error ? err.message : String(err)}`, { file: "auto.ts" });
|
|
692
697
|
}
|
|
693
698
|
}
|
|
694
699
|
} catch (e) {
|
|
@@ -760,7 +765,9 @@ export async function stopAuto(
|
|
|
760
765
|
try {
|
|
761
766
|
const pausedPath = join(gsdRoot(s.originalBasePath || s.basePath), "runtime", "paused-session.json");
|
|
762
767
|
if (existsSync(pausedPath)) unlinkSync(pausedPath);
|
|
763
|
-
} catch { /* non-fatal */
|
|
768
|
+
} catch (err) { /* non-fatal */
|
|
769
|
+
logWarning("engine", `file unlink failed: ${err instanceof Error ? err.message : String(err)}`, { file: "auto.ts" });
|
|
770
|
+
}
|
|
764
771
|
|
|
765
772
|
// ── Step 13: Restore original model (before reset clears IDs) ──
|
|
766
773
|
try {
|
|
@@ -794,7 +801,9 @@ export async function stopAuto(
|
|
|
794
801
|
const { closeBrowser } = await import("../browser-tools/lifecycle.js");
|
|
795
802
|
await closeBrowser();
|
|
796
803
|
}
|
|
797
|
-
} catch { /* non-fatal: browser-tools may not be loaded */
|
|
804
|
+
} catch (err) { /* non-fatal: browser-tools may not be loaded */
|
|
805
|
+
logWarning("engine", `browser teardown failed: ${err instanceof Error ? err.message : String(err)}`, { file: "auto.ts" });
|
|
806
|
+
}
|
|
798
807
|
|
|
799
808
|
// External cleanup (not covered by session reset)
|
|
800
809
|
clearInFlightTools();
|
|
@@ -852,16 +861,18 @@ export async function pauseAuto(
|
|
|
852
861
|
JSON.stringify(pausedMeta, null, 2),
|
|
853
862
|
"utf-8",
|
|
854
863
|
);
|
|
855
|
-
} catch {
|
|
864
|
+
} catch (err) {
|
|
856
865
|
// Non-fatal — resume will still work via full bootstrap, just without worktree context
|
|
866
|
+
logWarning("engine", `paused-session file write failed: ${err instanceof Error ? err.message : String(err)}`, { file: "auto.ts" });
|
|
857
867
|
}
|
|
858
868
|
|
|
859
869
|
// Close out the current unit so its runtime record doesn't stay at "dispatched"
|
|
860
870
|
if (s.currentUnit && ctx) {
|
|
861
871
|
try {
|
|
862
872
|
await closeoutUnit(ctx, s.basePath, s.currentUnit.type, s.currentUnit.id, s.currentUnit.startedAt);
|
|
863
|
-
} catch {
|
|
873
|
+
} catch (err) {
|
|
864
874
|
// Non-fatal — best-effort closeout on pause
|
|
875
|
+
logWarning("engine", `unit closeout on pause failed: ${err instanceof Error ? err.message : String(err)}`, { file: "auto.ts" });
|
|
865
876
|
}
|
|
866
877
|
s.currentUnit = null;
|
|
867
878
|
}
|
|
@@ -1085,7 +1096,9 @@ export async function startAuto(
|
|
|
1085
1096
|
s.originalBasePath = meta.originalBasePath || base;
|
|
1086
1097
|
s.stepMode = meta.stepMode ?? requestedStepMode;
|
|
1087
1098
|
s.paused = true;
|
|
1088
|
-
try { unlinkSync(pausedPath); } catch { /* non-fatal */
|
|
1099
|
+
try { unlinkSync(pausedPath); } catch (err) { /* non-fatal */
|
|
1100
|
+
logWarning("session", `pause file cleanup failed: ${err instanceof Error ? err.message : String(err)}`, { file: "auto.ts" });
|
|
1101
|
+
}
|
|
1089
1102
|
ctx.ui.notify(
|
|
1090
1103
|
`Resuming paused custom workflow${meta.activeRunDir ? ` (${meta.activeRunDir})` : ""}.`,
|
|
1091
1104
|
"info",
|
|
@@ -1096,7 +1109,9 @@ export async function startAuto(
|
|
|
1096
1109
|
const summaryFile = resolveMilestoneFile(base, meta.milestoneId, "SUMMARY");
|
|
1097
1110
|
if (!mDir || summaryFile) {
|
|
1098
1111
|
// Stale milestone — clean up and fall through to fresh bootstrap
|
|
1099
|
-
try { unlinkSync(pausedPath); } catch { /* non-fatal */
|
|
1112
|
+
try { unlinkSync(pausedPath); } catch (err) { /* non-fatal */
|
|
1113
|
+
logWarning("session", `pause file cleanup failed: ${err instanceof Error ? err.message : String(err)}`, { file: "auto.ts" });
|
|
1114
|
+
}
|
|
1100
1115
|
ctx.ui.notify(
|
|
1101
1116
|
`Paused milestone ${meta.milestoneId} is ${!mDir ? "missing" : "already complete"}. Starting fresh.`,
|
|
1102
1117
|
"info",
|
|
@@ -1107,7 +1122,9 @@ export async function startAuto(
|
|
|
1107
1122
|
s.stepMode = meta.stepMode ?? requestedStepMode;
|
|
1108
1123
|
s.paused = true;
|
|
1109
1124
|
// Clean up the persisted file — we're consuming it
|
|
1110
|
-
try { unlinkSync(pausedPath); } catch { /* non-fatal */
|
|
1125
|
+
try { unlinkSync(pausedPath); } catch (err) { /* non-fatal */
|
|
1126
|
+
logWarning("session", `pause file cleanup failed: ${err instanceof Error ? err.message : String(err)}`, { file: "auto.ts" });
|
|
1127
|
+
}
|
|
1111
1128
|
ctx.ui.notify(
|
|
1112
1129
|
`Resuming paused session for ${meta.milestoneId}${meta.worktreePath ? ` (worktree)` : ""}.`,
|
|
1113
1130
|
"info",
|
|
@@ -1115,8 +1132,9 @@ export async function startAuto(
|
|
|
1115
1132
|
}
|
|
1116
1133
|
}
|
|
1117
1134
|
}
|
|
1118
|
-
} catch {
|
|
1135
|
+
} catch (err) {
|
|
1119
1136
|
// Malformed or missing — proceed with fresh bootstrap
|
|
1137
|
+
logWarning("session", `paused-session restore failed: ${err instanceof Error ? err.message : String(err)}`, { file: "auto.ts" });
|
|
1120
1138
|
}
|
|
1121
1139
|
}
|
|
1122
1140
|
|
|
@@ -1242,8 +1260,9 @@ export async function startAuto(
|
|
|
1242
1260
|
|
|
1243
1261
|
try {
|
|
1244
1262
|
syncCmuxSidebar(loadEffectiveGSDPreferences()?.preferences, await deriveState(s.basePath));
|
|
1245
|
-
} catch {
|
|
1263
|
+
} catch (err) {
|
|
1246
1264
|
// Best-effort only — sidebar sync must never block auto-mode startup
|
|
1265
|
+
logWarning("engine", `cmux sync failed: ${err instanceof Error ? err.message : String(err)}`, { file: "auto.ts" });
|
|
1247
1266
|
}
|
|
1248
1267
|
logCmuxEvent(loadEffectiveGSDPreferences()?.preferences, requestedStepMode ? "Step-mode started." : "Auto-mode started.", "progress");
|
|
1249
1268
|
|
|
@@ -1415,8 +1434,9 @@ export async function dispatchHookUnit(
|
|
|
1415
1434
|
if (match) {
|
|
1416
1435
|
try {
|
|
1417
1436
|
await pi.setModel(match);
|
|
1418
|
-
} catch {
|
|
1437
|
+
} catch (err) {
|
|
1419
1438
|
/* non-fatal */
|
|
1439
|
+
logWarning("dispatch", `hook model set failed: ${err instanceof Error ? err.message : String(err)}`, { file: "auto.ts" });
|
|
1420
1440
|
}
|
|
1421
1441
|
} else {
|
|
1422
1442
|
ctx.ui.notify(
|
|
@@ -1453,7 +1473,9 @@ export async function dispatchHookUnit(
|
|
|
1453
1473
|
ctx.ui.notify(`Running post-unit hook: ${hookName}`, "info");
|
|
1454
1474
|
|
|
1455
1475
|
// Ensure cwd matches basePath before hook dispatch (#1389)
|
|
1456
|
-
try { if (process.cwd() !== s.basePath) process.chdir(s.basePath); } catch {
|
|
1476
|
+
try { if (process.cwd() !== s.basePath) process.chdir(s.basePath); } catch (err) {
|
|
1477
|
+
logWarning("engine", `chdir failed before hook dispatch: ${err instanceof Error ? err.message : String(err)}`, { file: "auto.ts" });
|
|
1478
|
+
}
|
|
1457
1479
|
|
|
1458
1480
|
debugLog("dispatchHookUnit", {
|
|
1459
1481
|
phase: "send-message",
|
|
@@ -1475,3 +1497,4 @@ export {
|
|
|
1475
1497
|
buildLoopRemediationSteps,
|
|
1476
1498
|
} from "./auto-recovery.js";
|
|
1477
1499
|
export { resolveExpectedArtifactPath } from "./auto-artifact-paths.js";
|
|
1500
|
+
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ExtensionAPI, ExtensionContext } from "@gsd/pi-coding-agent";
|
|
2
2
|
|
|
3
|
+
import { logWarning } from "../workflow-logger.js";
|
|
3
4
|
import { checkAutoStartAfterDiscuss } from "../guided-flow.js";
|
|
4
5
|
import { getAutoDashboardData, getAutoModeStartModel, isAutoActive, pauseAuto } from "../auto.js";
|
|
5
6
|
import { getNextFallbackModel, resolveModelWithFallbacksForUnit } from "../preferences.js";
|
|
@@ -85,7 +86,7 @@ export async function handleAgentEnd(
|
|
|
85
86
|
} catch (err) {
|
|
86
87
|
const message = err instanceof Error ? err.message : String(err);
|
|
87
88
|
ctx.ui.notify(`Auto-mode error after empty-content abort: ${message}. Stopping auto-mode.`, "error");
|
|
88
|
-
try { await pauseAuto(ctx, pi); } catch {
|
|
89
|
+
try { await pauseAuto(ctx, pi); } catch (e) { logWarning("bootstrap", `pauseAuto failed after empty-content abort: ${(e as Error).message}`); }
|
|
89
90
|
}
|
|
90
91
|
return;
|
|
91
92
|
}
|
|
@@ -212,8 +213,8 @@ export async function handleAgentEnd(
|
|
|
212
213
|
ctx.ui.notify(`Auto-mode error in agent_end handler: ${message}. Stopping auto-mode.`, "error");
|
|
213
214
|
try {
|
|
214
215
|
await pauseAuto(ctx, pi);
|
|
215
|
-
} catch {
|
|
216
|
-
|
|
216
|
+
} catch (e) {
|
|
217
|
+
logWarning("bootstrap", `pauseAuto failed in agent_end handler: ${(e as Error).message}`);
|
|
217
218
|
}
|
|
218
219
|
}
|
|
219
220
|
}
|
|
@@ -413,8 +413,8 @@ export function registerDbTools(pi: ExtensionAPI): void {
|
|
|
413
413
|
try {
|
|
414
414
|
const { insertMilestone } = await import("../gsd-db.js");
|
|
415
415
|
insertMilestone({ id: milestoneId, status: "queued" });
|
|
416
|
-
} catch {
|
|
417
|
-
|
|
416
|
+
} catch (e) {
|
|
417
|
+
logError("tool", `insertMilestone failed for ${milestoneId}: ${(e as Error).message}`);
|
|
418
418
|
}
|
|
419
419
|
}
|
|
420
420
|
|
|
@@ -883,6 +883,84 @@ export function registerDbTools(pi: ExtensionAPI): void {
|
|
|
883
883
|
pi.registerTool(sliceCompleteTool);
|
|
884
884
|
registerAlias(pi, sliceCompleteTool, "gsd_complete_slice", "gsd_slice_complete");
|
|
885
885
|
|
|
886
|
+
// ─── gsd_skip_slice (#3477 / #3487) ───────────────────────────────────
|
|
887
|
+
|
|
888
|
+
const skipSliceExecute = async (_toolCallId: string, params: any, _signal: AbortSignal | undefined, _onUpdate: unknown, _ctx: unknown) => {
|
|
889
|
+
const dbAvailable = await ensureDbOpen();
|
|
890
|
+
if (!dbAvailable) {
|
|
891
|
+
return {
|
|
892
|
+
content: [{ type: "text" as const, text: "Error: GSD database is not available. Cannot skip slice." }],
|
|
893
|
+
details: { operation: "skip_slice", error: "db_unavailable" } as any,
|
|
894
|
+
};
|
|
895
|
+
}
|
|
896
|
+
try {
|
|
897
|
+
const { getSlice, updateSliceStatus } = await import("../gsd-db.js");
|
|
898
|
+
const { invalidateStateCache } = await import("../state.js");
|
|
899
|
+
|
|
900
|
+
const slice = getSlice(params.milestoneId, params.sliceId);
|
|
901
|
+
if (!slice) {
|
|
902
|
+
return {
|
|
903
|
+
content: [{ type: "text" as const, text: `Error: Slice ${params.sliceId} not found in milestone ${params.milestoneId}` }],
|
|
904
|
+
details: { operation: "skip_slice", error: "slice_not_found" } as any,
|
|
905
|
+
};
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
if (slice.status === "complete" || slice.status === "done") {
|
|
909
|
+
return {
|
|
910
|
+
content: [{ type: "text" as const, text: `Error: Slice ${params.sliceId} is already complete — cannot skip.` }],
|
|
911
|
+
details: { operation: "skip_slice", error: "already_complete" } as any,
|
|
912
|
+
};
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
if (slice.status === "skipped") {
|
|
916
|
+
return {
|
|
917
|
+
content: [{ type: "text" as const, text: `Slice ${params.sliceId} is already skipped.` }],
|
|
918
|
+
details: { operation: "skip_slice", sliceId: params.sliceId, milestoneId: params.milestoneId } as any,
|
|
919
|
+
};
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
updateSliceStatus(params.milestoneId, params.sliceId, "skipped");
|
|
923
|
+
invalidateStateCache();
|
|
924
|
+
|
|
925
|
+
return {
|
|
926
|
+
content: [{ type: "text" as const, text: `Skipped slice ${params.sliceId} (${params.milestoneId}). Reason: ${params.reason ?? "User-directed skip"}. Auto-mode will advance past this slice.` }],
|
|
927
|
+
details: {
|
|
928
|
+
operation: "skip_slice",
|
|
929
|
+
sliceId: params.sliceId,
|
|
930
|
+
milestoneId: params.milestoneId,
|
|
931
|
+
reason: params.reason,
|
|
932
|
+
} as any,
|
|
933
|
+
};
|
|
934
|
+
} catch (err) {
|
|
935
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
936
|
+
logError("tool", `skip_slice tool failed: ${msg}`, { tool: "gsd_skip_slice", error: String(err) });
|
|
937
|
+
return {
|
|
938
|
+
content: [{ type: "text" as const, text: `Error skipping slice: ${msg}` }],
|
|
939
|
+
details: { operation: "skip_slice", error: msg } as any,
|
|
940
|
+
};
|
|
941
|
+
}
|
|
942
|
+
};
|
|
943
|
+
|
|
944
|
+
pi.registerTool({
|
|
945
|
+
name: "gsd_skip_slice",
|
|
946
|
+
label: "Skip Slice",
|
|
947
|
+
description:
|
|
948
|
+
"Mark a slice as skipped so auto-mode advances past it without executing. " +
|
|
949
|
+
"The slice data is preserved for reference. The state machine treats skipped slices like completed ones for dependency satisfaction.",
|
|
950
|
+
promptSnippet: "Skip a GSD slice (mark as skipped, auto-mode will advance past it)",
|
|
951
|
+
promptGuidelines: [
|
|
952
|
+
"Use gsd_skip_slice when a slice should be bypassed — descoped, superseded, or no longer relevant.",
|
|
953
|
+
"Cannot skip a slice that is already complete.",
|
|
954
|
+
"Skipped slices satisfy downstream dependencies just like completed slices.",
|
|
955
|
+
],
|
|
956
|
+
parameters: Type.Object({
|
|
957
|
+
sliceId: Type.String({ description: "Slice ID (e.g. S02)" }),
|
|
958
|
+
milestoneId: Type.String({ description: "Milestone ID (e.g. M003)" }),
|
|
959
|
+
reason: Type.Optional(Type.String({ description: "Reason for skipping this slice" })),
|
|
960
|
+
}),
|
|
961
|
+
execute: skipSliceExecute,
|
|
962
|
+
});
|
|
963
|
+
|
|
886
964
|
// ─── gsd_complete_milestone ────────────────────────────────────────────
|
|
887
965
|
|
|
888
966
|
const milestoneCompleteExecute = async (_toolCallId: string, params: any, _signal: AbortSignal | undefined, _onUpdate: unknown, _ctx: unknown) => {
|
|
@@ -5,7 +5,7 @@ import type { ExtensionAPI } from "@gsd/pi-coding-agent";
|
|
|
5
5
|
import { createBashTool, createEditTool, createReadTool, createWriteTool } from "@gsd/pi-coding-agent";
|
|
6
6
|
|
|
7
7
|
import { DEFAULT_BASH_TIMEOUT_SECS } from "../constants.js";
|
|
8
|
-
import { setLogBasePath } from "../workflow-logger.js";
|
|
8
|
+
import { setLogBasePath, logWarning } from "../workflow-logger.js";
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Resolve the correct DB path for the current working directory.
|
|
@@ -92,9 +92,7 @@ export async function ensureDbOpen(): Promise<boolean> {
|
|
|
92
92
|
const { migrateFromMarkdown } = await import("../md-importer.js");
|
|
93
93
|
migrateFromMarkdown(basePath);
|
|
94
94
|
} catch (err) {
|
|
95
|
-
|
|
96
|
-
`gsd-db: ensureDbOpen auto-migration failed: ${(err as Error).message}\n`,
|
|
97
|
-
);
|
|
95
|
+
logWarning("bootstrap", `ensureDbOpen auto-migration failed: ${(err as Error).message}`);
|
|
98
96
|
}
|
|
99
97
|
}
|
|
100
98
|
return opened;
|
|
@@ -106,20 +104,10 @@ export async function ensureDbOpen(): Promise<boolean> {
|
|
|
106
104
|
return opened;
|
|
107
105
|
}
|
|
108
106
|
|
|
109
|
-
|
|
110
|
-
`gsd-db: ensureDbOpen failed — no .gsd directory found (resolvedPath=${resolveProjectRootDbPath(basePath)}, cwd=${basePath})\n`,
|
|
111
|
-
);
|
|
107
|
+
logWarning("bootstrap", "ensureDbOpen failed — no .gsd directory found");
|
|
112
108
|
return false;
|
|
113
109
|
} catch (err) {
|
|
114
|
-
|
|
115
|
-
const diagnostic = {
|
|
116
|
-
resolvedPath: resolveProjectRootDbPath(basePath),
|
|
117
|
-
cwd: basePath,
|
|
118
|
-
error: (err as Error).message ?? String(err),
|
|
119
|
-
};
|
|
120
|
-
process.stderr.write(
|
|
121
|
-
`gsd-db: ensureDbOpen failed — ${JSON.stringify(diagnostic)}\n`,
|
|
122
|
-
);
|
|
110
|
+
logWarning("bootstrap", `ensureDbOpen failed: ${(err as Error).message ?? String(err)}`);
|
|
123
111
|
return false;
|
|
124
112
|
}
|
|
125
113
|
}
|
|
@@ -2,6 +2,7 @@ import { Type } from "@sinclair/typebox";
|
|
|
2
2
|
import type { ExtensionAPI } from "@gsd/pi-coding-agent";
|
|
3
3
|
|
|
4
4
|
import { queryJournal } from "../journal.js";
|
|
5
|
+
import { logWarning } from "../workflow-logger.js";
|
|
5
6
|
|
|
6
7
|
export function registerJournalTools(pi: ExtensionAPI): void {
|
|
7
8
|
pi.registerTool({
|
|
@@ -51,7 +52,7 @@ export function registerJournalTools(pi: ExtensionAPI): void {
|
|
|
51
52
|
};
|
|
52
53
|
} catch (err) {
|
|
53
54
|
const msg = err instanceof Error ? err.message : String(err);
|
|
54
|
-
|
|
55
|
+
logWarning("tool", `gsd_journal_query tool failed: ${msg}`);
|
|
55
56
|
return {
|
|
56
57
|
content: [{ type: "text" as const, text: `Error querying journal: ${msg}` }],
|
|
57
58
|
details: { operation: "journal_query", error: msg } as any,
|
|
@@ -263,14 +263,71 @@ export function registerHooks(pi: ExtensionAPI): void {
|
|
|
263
263
|
});
|
|
264
264
|
|
|
265
265
|
pi.on("before_provider_request", async (event) => {
|
|
266
|
+
const payload = event.payload as Record<string, unknown> | null;
|
|
267
|
+
if (!payload || typeof payload !== "object") return;
|
|
268
|
+
|
|
269
|
+
// ── Observation Masking ─────────────────────────────────────────────
|
|
270
|
+
// Replace old tool results with placeholders to reduce context bloat.
|
|
271
|
+
// Only active during auto-mode when context_management.observation_masking is enabled.
|
|
272
|
+
if (isAutoActive()) {
|
|
273
|
+
try {
|
|
274
|
+
const { loadEffectiveGSDPreferences } = await import("../preferences.js");
|
|
275
|
+
const prefs = loadEffectiveGSDPreferences();
|
|
276
|
+
const cmConfig = prefs?.preferences.context_management;
|
|
277
|
+
|
|
278
|
+
// Observation masking: replace old tool results with placeholders
|
|
279
|
+
if (cmConfig?.observation_masking !== false) {
|
|
280
|
+
const keepTurns = cmConfig?.observation_mask_turns ?? 8;
|
|
281
|
+
const { createObservationMask } = await import("../context-masker.js");
|
|
282
|
+
const mask = createObservationMask(keepTurns);
|
|
283
|
+
const messages = payload.messages;
|
|
284
|
+
if (Array.isArray(messages)) {
|
|
285
|
+
payload.messages = mask(messages);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// Tool result truncation: cap individual tool result content length.
|
|
290
|
+
// In pi-ai format, toolResult messages have role: "toolResult" and content: TextContent[].
|
|
291
|
+
// Creates new objects to avoid mutating shared conversation state.
|
|
292
|
+
const maxChars = cmConfig?.tool_result_max_chars ?? 800;
|
|
293
|
+
const msgs = payload.messages;
|
|
294
|
+
if (Array.isArray(msgs)) {
|
|
295
|
+
payload.messages = msgs.map((msg: Record<string, unknown>) => {
|
|
296
|
+
// Match toolResult messages (role: "toolResult", content is array of content blocks)
|
|
297
|
+
if (msg?.role === "toolResult" && Array.isArray(msg.content)) {
|
|
298
|
+
const blocks = msg.content as Array<Record<string, unknown>>;
|
|
299
|
+
const totalLen = blocks.reduce((sum: number, b) => sum + (typeof b.text === "string" ? b.text.length : 0), 0);
|
|
300
|
+
if (totalLen > maxChars) {
|
|
301
|
+
const truncated = blocks.map(b => {
|
|
302
|
+
if (typeof b.text === "string" && b.text.length > maxChars) {
|
|
303
|
+
return { ...b, text: b.text.slice(0, maxChars) + "\n…[truncated]" };
|
|
304
|
+
}
|
|
305
|
+
return b;
|
|
306
|
+
});
|
|
307
|
+
return { ...msg, content: truncated };
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
return msg;
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
} catch { /* non-fatal */ }
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// ── Service Tier ────────────────────────────────────────────────────
|
|
266
317
|
const modelId = event.model?.id;
|
|
267
|
-
if (!modelId) return;
|
|
318
|
+
if (!modelId) return payload;
|
|
268
319
|
const { getEffectiveServiceTier, supportsServiceTier } = await import("../service-tier.js");
|
|
269
320
|
const tier = getEffectiveServiceTier();
|
|
270
|
-
if (!tier || !supportsServiceTier(modelId)) return;
|
|
271
|
-
const payload = event.payload as Record<string, unknown> | null;
|
|
272
|
-
if (!payload || typeof payload !== "object") return;
|
|
321
|
+
if (!tier || !supportsServiceTier(modelId)) return payload;
|
|
273
322
|
payload.service_tier = tier;
|
|
274
323
|
return payload;
|
|
275
324
|
});
|
|
325
|
+
|
|
326
|
+
// Capability-aware model routing hook (ADR-004)
|
|
327
|
+
// Extensions can override model selection by returning { modelId: "..." }
|
|
328
|
+
// Return undefined to let the built-in capability scoring proceed.
|
|
329
|
+
pi.on("before_model_select", async (_event) => {
|
|
330
|
+
// Default: no override — let capability scoring handle selection
|
|
331
|
+
return undefined;
|
|
332
|
+
});
|
|
276
333
|
}
|
|
@@ -4,6 +4,7 @@ import { join } from "node:path";
|
|
|
4
4
|
|
|
5
5
|
import type { ExtensionContext } from "@gsd/pi-coding-agent";
|
|
6
6
|
|
|
7
|
+
import { logWarning } from "../workflow-logger.js";
|
|
7
8
|
import { debugTime } from "../debug-logger.js";
|
|
8
9
|
import { loadPrompt } from "../prompt-loader.js";
|
|
9
10
|
import { readForensicsMarker } from "../forensics.js";
|
|
@@ -83,8 +84,8 @@ export async function buildBeforeAgentStartResult(
|
|
|
83
84
|
memoryBlock = `\n\n${formatted}`;
|
|
84
85
|
}
|
|
85
86
|
}
|
|
86
|
-
} catch {
|
|
87
|
-
|
|
87
|
+
} catch (e) {
|
|
88
|
+
logWarning("bootstrap", `memory block fetch failed: ${(e as Error).message}`);
|
|
88
89
|
}
|
|
89
90
|
|
|
90
91
|
let newSkillsBlock = "";
|
|
@@ -111,8 +112,8 @@ export async function buildBeforeAgentStartResult(
|
|
|
111
112
|
: rawContent;
|
|
112
113
|
codebaseBlock = `\n\n[PROJECT CODEBASE — File structure and descriptions (generated ${generatedAt}, may be stale — run /gsd codebase update to refresh)]\n\n${content}`;
|
|
113
114
|
}
|
|
114
|
-
} catch {
|
|
115
|
-
|
|
115
|
+
} catch (e) {
|
|
116
|
+
logWarning("bootstrap", `CODEBASE file read failed: ${(e as Error).message}`);
|
|
116
117
|
}
|
|
117
118
|
}
|
|
118
119
|
|
|
@@ -158,8 +159,8 @@ export function loadKnowledgeBlock(gsdHomeDir: string, cwd: string): { block: st
|
|
|
158
159
|
globalSizeKb = Buffer.byteLength(content, "utf-8") / 1024;
|
|
159
160
|
globalKnowledge = content;
|
|
160
161
|
}
|
|
161
|
-
} catch {
|
|
162
|
-
|
|
162
|
+
} catch (e) {
|
|
163
|
+
logWarning("bootstrap", `global knowledge file read failed: ${(e as Error).message}`);
|
|
163
164
|
}
|
|
164
165
|
}
|
|
165
166
|
|
|
@@ -170,8 +171,8 @@ export function loadKnowledgeBlock(gsdHomeDir: string, cwd: string): { block: st
|
|
|
170
171
|
try {
|
|
171
172
|
const content = readFileSync(knowledgePath, "utf-8").trim();
|
|
172
173
|
if (content) projectKnowledge = content;
|
|
173
|
-
} catch {
|
|
174
|
-
|
|
174
|
+
} catch (e) {
|
|
175
|
+
logWarning("bootstrap", `project knowledge file read failed: ${(e as Error).message}`);
|
|
175
176
|
}
|
|
176
177
|
}
|
|
177
178
|
|
|
@@ -429,8 +430,8 @@ export function clearForensicsMarker(basePath: string): void {
|
|
|
429
430
|
if (existsSync(markerPath)) {
|
|
430
431
|
try {
|
|
431
432
|
unlinkSync(markerPath);
|
|
432
|
-
} catch {
|
|
433
|
-
|
|
433
|
+
} catch (e) {
|
|
434
|
+
logWarning("bootstrap", `unlinkSync forensics marker failed: ${(e as Error).message}`);
|
|
434
435
|
}
|
|
435
436
|
}
|
|
436
437
|
}
|
|
@@ -15,7 +15,7 @@ import { gsdRoot } from "./paths.js";
|
|
|
15
15
|
|
|
16
16
|
// ─── Types ────────────────────────────────────────────────────────────────────
|
|
17
17
|
|
|
18
|
-
export type Classification = "quick-task" | "inject" | "defer" | "replan" | "note";
|
|
18
|
+
export type Classification = "quick-task" | "inject" | "defer" | "replan" | "note" | "stop" | "backtrack";
|
|
19
19
|
|
|
20
20
|
export interface CaptureEntry {
|
|
21
21
|
id: string;
|
|
@@ -42,7 +42,7 @@ export interface TriageResult {
|
|
|
42
42
|
|
|
43
43
|
const CAPTURES_FILENAME = "CAPTURES.md";
|
|
44
44
|
const VALID_CLASSIFICATIONS: readonly string[] = [
|
|
45
|
-
"quick-task", "inject", "defer", "replan", "note",
|
|
45
|
+
"quick-task", "inject", "defer", "replan", "note", "stop", "backtrack",
|
|
46
46
|
];
|
|
47
47
|
|
|
48
48
|
// ─── Path Resolution ──────────────────────────────────────────────────────────
|
|
@@ -285,6 +285,75 @@ export function loadActionableCaptures(basePath: string, currentMilestoneId?: st
|
|
|
285
285
|
);
|
|
286
286
|
}
|
|
287
287
|
|
|
288
|
+
/**
|
|
289
|
+
* Load unexecuted stop captures — user directives to halt auto-mode.
|
|
290
|
+
* These are checked in the pre-dispatch guard pipeline (runGuards) to
|
|
291
|
+
* pause auto-mode before the next unit is dispatched.
|
|
292
|
+
*/
|
|
293
|
+
export function loadStopCaptures(basePath: string): CaptureEntry[] {
|
|
294
|
+
return loadAllCaptures(basePath).filter(
|
|
295
|
+
c => c.status === "resolved" && !c.executed &&
|
|
296
|
+
(c.classification === "stop" || c.classification === "backtrack"),
|
|
297
|
+
);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* Load unexecuted backtrack captures specifically — captures directing
|
|
302
|
+
* auto-mode to abandon current milestone and return to a previous one.
|
|
303
|
+
*/
|
|
304
|
+
export function loadBacktrackCaptures(basePath: string): CaptureEntry[] {
|
|
305
|
+
return loadAllCaptures(basePath).filter(
|
|
306
|
+
c => c.status === "resolved" && !c.executed && c.classification === "backtrack",
|
|
307
|
+
);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* Revert captures that were silenced by non-triage agents.
|
|
312
|
+
*
|
|
313
|
+
* When an execute-task or other non-triage agent writes `**Status:** resolved`
|
|
314
|
+
* to CAPTURES.md, it bypasses the triage pipeline entirely. This function
|
|
315
|
+
* detects such captures (resolved but missing the Classification field that
|
|
316
|
+
* triage always writes) and reverts them to pending so the triage sidecar
|
|
317
|
+
* picks them up properly.
|
|
318
|
+
*
|
|
319
|
+
* Returns the number of captures reverted.
|
|
320
|
+
*/
|
|
321
|
+
export function revertExecutorResolvedCaptures(basePath: string): number {
|
|
322
|
+
const filePath = resolveCapturesPath(basePath);
|
|
323
|
+
if (!existsSync(filePath)) return 0;
|
|
324
|
+
|
|
325
|
+
let content = readFileSync(filePath, "utf-8");
|
|
326
|
+
let reverted = 0;
|
|
327
|
+
|
|
328
|
+
const all = loadAllCaptures(basePath);
|
|
329
|
+
for (const capture of all) {
|
|
330
|
+
// A properly triaged capture has both resolved status AND a classification.
|
|
331
|
+
// An executor-silenced capture has resolved status but NO classification.
|
|
332
|
+
if (capture.status === "resolved" && !capture.classification) {
|
|
333
|
+
const sectionRegex = new RegExp(
|
|
334
|
+
`(### ${escapeRegex(capture.id)}\\n(?:(?!### ).)*?)(?=### |$)`,
|
|
335
|
+
"s",
|
|
336
|
+
);
|
|
337
|
+
const match = sectionRegex.exec(content);
|
|
338
|
+
if (match) {
|
|
339
|
+
let section = match[1];
|
|
340
|
+
section = section.replace(
|
|
341
|
+
/\*\*Status:\*\*\s*resolved/i,
|
|
342
|
+
"**Status:** pending",
|
|
343
|
+
);
|
|
344
|
+
content = content.replace(sectionRegex, section);
|
|
345
|
+
reverted++;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
if (reverted > 0) {
|
|
351
|
+
writeFileSync(filePath, content, "utf-8");
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
return reverted;
|
|
355
|
+
}
|
|
356
|
+
|
|
288
357
|
/**
|
|
289
358
|
* Retroactively stamp a capture with a milestone ID.
|
|
290
359
|
*
|
|
@@ -229,8 +229,10 @@ const NESTED_COMPLETIONS: CompletionMap = {
|
|
|
229
229
|
codebase: [
|
|
230
230
|
{ cmd: "generate", desc: "Generate or regenerate CODEBASE.md" },
|
|
231
231
|
{ cmd: "generate --max-files", desc: "Generate with custom file limit (default: 500)" },
|
|
232
|
+
{ cmd: "generate --collapse-threshold", desc: "Generate with custom collapse threshold (default: 20)" },
|
|
232
233
|
{ cmd: "update", desc: "Incremental update (preserves descriptions)" },
|
|
233
234
|
{ cmd: "update --max-files", desc: "Update with custom file limit" },
|
|
235
|
+
{ cmd: "update --collapse-threshold", desc: "Update with custom collapse threshold" },
|
|
234
236
|
{ cmd: "stats", desc: "Show file count, description coverage, and generation time" },
|
|
235
237
|
{ cmd: "help", desc: "Show usage and available subcommands" },
|
|
236
238
|
],
|