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
|
@@ -14,14 +14,21 @@ import {
|
|
|
14
14
|
getCodebaseMapStats,
|
|
15
15
|
readCodebaseMap,
|
|
16
16
|
} from "./codebase-generator.js";
|
|
17
|
+
import { loadEffectiveGSDPreferences } from "./preferences.js";
|
|
18
|
+
import type { CodebaseMapOptions } from "./codebase-generator.js";
|
|
17
19
|
|
|
18
20
|
const USAGE =
|
|
19
21
|
"Usage: /gsd codebase [generate|update|stats]\n\n" +
|
|
20
|
-
" generate [--max-files N] — Generate or regenerate CODEBASE.md\n" +
|
|
21
|
-
" update
|
|
22
|
-
" stats
|
|
23
|
-
" help
|
|
24
|
-
"With no subcommand, shows stats if a map exists or help if not
|
|
22
|
+
" generate [--max-files N] [--collapse-threshold N] — Generate or regenerate CODEBASE.md\n" +
|
|
23
|
+
" update [--max-files N] [--collapse-threshold N] — Incremental update (preserves descriptions)\n" +
|
|
24
|
+
" stats — Show file count, coverage, and generation time\n" +
|
|
25
|
+
" help — Show this help\n\n" +
|
|
26
|
+
"With no subcommand, shows stats if a map exists or help if not.\n\n" +
|
|
27
|
+
"Configure defaults via preferences.md:\n" +
|
|
28
|
+
" codebase:\n" +
|
|
29
|
+
" exclude_patterns: [\"docs/\", \"fixtures/\"]\n" +
|
|
30
|
+
" max_files: 1000\n" +
|
|
31
|
+
" collapse_threshold: 15";
|
|
25
32
|
|
|
26
33
|
export async function handleCodebase(
|
|
27
34
|
args: string,
|
|
@@ -34,15 +41,15 @@ export async function handleCodebase(
|
|
|
34
41
|
|
|
35
42
|
switch (sub) {
|
|
36
43
|
case "generate": {
|
|
37
|
-
const
|
|
38
|
-
if (
|
|
44
|
+
const options = resolveCodebaseOptions(args, ctx);
|
|
45
|
+
if (options === false) return; // validation failed, message already shown
|
|
39
46
|
|
|
40
47
|
const existing = readCodebaseMap(basePath);
|
|
41
48
|
const existingDescriptions = existing
|
|
42
49
|
? (await import("./codebase-generator.js")).parseCodebaseMap(existing)
|
|
43
50
|
: undefined;
|
|
44
51
|
|
|
45
|
-
const result = generateCodebaseMap(basePath,
|
|
52
|
+
const result = generateCodebaseMap(basePath, options, existingDescriptions);
|
|
46
53
|
|
|
47
54
|
if (result.fileCount === 0) {
|
|
48
55
|
ctx.ui.notify(
|
|
@@ -73,10 +80,10 @@ export async function handleCodebase(
|
|
|
73
80
|
return;
|
|
74
81
|
}
|
|
75
82
|
|
|
76
|
-
const
|
|
77
|
-
if (
|
|
83
|
+
const options = resolveCodebaseOptions(args, ctx);
|
|
84
|
+
if (options === false) return;
|
|
78
85
|
|
|
79
|
-
const result = updateCodebaseMap(basePath,
|
|
86
|
+
const result = updateCodebaseMap(basePath, options);
|
|
80
87
|
writeCodebaseMap(basePath, result.content);
|
|
81
88
|
|
|
82
89
|
ctx.ui.notify(
|
|
@@ -141,19 +148,44 @@ function showStats(basePath: string, ctx: ExtensionCommandContext): void {
|
|
|
141
148
|
}
|
|
142
149
|
|
|
143
150
|
/**
|
|
144
|
-
*
|
|
145
|
-
*
|
|
151
|
+
* Resolve codebase map options by merging preferences with CLI flags.
|
|
152
|
+
* CLI flags override preferences; preferences override built-in defaults.
|
|
153
|
+
* Returns false if validation failed (error already shown to user).
|
|
146
154
|
*/
|
|
147
|
-
function
|
|
155
|
+
function resolveCodebaseOptions(args: string, ctx: ExtensionCommandContext): CodebaseMapOptions | false {
|
|
156
|
+
// Load preferences defaults
|
|
157
|
+
const prefs = loadEffectiveGSDPreferences()?.preferences?.codebase;
|
|
158
|
+
|
|
159
|
+
// Parse CLI flags
|
|
148
160
|
const maxFilesStr = extractFlag(args, "--max-files");
|
|
149
|
-
|
|
161
|
+
const collapseStr = extractFlag(args, "--collapse-threshold");
|
|
162
|
+
|
|
163
|
+
// Validate --max-files
|
|
164
|
+
let maxFiles: number | undefined;
|
|
165
|
+
if (maxFilesStr) {
|
|
166
|
+
maxFiles = parseInt(maxFilesStr, 10);
|
|
167
|
+
if (isNaN(maxFiles) || maxFiles < 1) {
|
|
168
|
+
ctx.ui.notify("--max-files must be a positive integer (e.g. --max-files 200).", "warning");
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
150
172
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
173
|
+
// Validate --collapse-threshold
|
|
174
|
+
let collapseThreshold: number | undefined;
|
|
175
|
+
if (collapseStr) {
|
|
176
|
+
collapseThreshold = parseInt(collapseStr, 10);
|
|
177
|
+
if (isNaN(collapseThreshold) || collapseThreshold < 1) {
|
|
178
|
+
ctx.ui.notify("--collapse-threshold must be a positive integer (e.g. --collapse-threshold 15).", "warning");
|
|
179
|
+
return false;
|
|
180
|
+
}
|
|
155
181
|
}
|
|
156
|
-
|
|
182
|
+
|
|
183
|
+
return {
|
|
184
|
+
// CLI flags override preferences
|
|
185
|
+
maxFiles: maxFiles ?? prefs?.max_files,
|
|
186
|
+
collapseThreshold: collapseThreshold ?? prefs?.collapse_threshold,
|
|
187
|
+
excludePatterns: prefs?.exclude_patterns,
|
|
188
|
+
};
|
|
157
189
|
}
|
|
158
190
|
|
|
159
191
|
function extractFlag(args: string, flag: string): string | undefined {
|
|
@@ -8,6 +8,7 @@ import type { ExtensionCommandContext } from "@gsd/pi-coding-agent";
|
|
|
8
8
|
import { existsSync } from "node:fs";
|
|
9
9
|
import { join } from "node:path";
|
|
10
10
|
import { gsdRoot } from "./paths.js";
|
|
11
|
+
import { logWarning } from "./workflow-logger.js";
|
|
11
12
|
import { getErrorMessage } from "./error-utils.js";
|
|
12
13
|
|
|
13
14
|
export interface InspectData {
|
|
@@ -92,7 +93,7 @@ export async function handleInspect(ctx: ExtensionCommandContext): Promise<void>
|
|
|
92
93
|
|
|
93
94
|
ctx.ui.notify(formatInspectOutput(data), "info");
|
|
94
95
|
} catch (err) {
|
|
95
|
-
|
|
96
|
+
logWarning("command", `/gsd inspect failed: ${getErrorMessage(err)}`);
|
|
96
97
|
ctx.ui.notify("Failed to inspect GSD database. Check stderr for details.", "error");
|
|
97
98
|
}
|
|
98
99
|
}
|
|
@@ -7,12 +7,14 @@
|
|
|
7
7
|
import type { ExtensionCommandContext } from "@gsd/pi-coding-agent";
|
|
8
8
|
import { deriveState } from "./state.js";
|
|
9
9
|
import { nativeBranchList, nativeDetectMainBranch, nativeBranchListMerged, nativeBranchDelete, nativeForEachRef, nativeUpdateRef } from "./native-git-bridge.js";
|
|
10
|
+
import { logWarning } from "./workflow-logger.js";
|
|
10
11
|
|
|
11
12
|
export async function handleCleanupBranches(ctx: ExtensionCommandContext, basePath: string): Promise<void> {
|
|
12
13
|
let branches: string[];
|
|
13
14
|
try {
|
|
14
15
|
branches = nativeBranchList(basePath, "gsd/*");
|
|
15
|
-
} catch {
|
|
16
|
+
} catch (e) {
|
|
17
|
+
logWarning("command", `branch list failed: ${(e as Error).message}`);
|
|
16
18
|
ctx.ui.notify("No GSD branches to clean up.", "info");
|
|
17
19
|
return;
|
|
18
20
|
}
|
|
@@ -23,7 +25,8 @@ export async function handleCleanupBranches(ctx: ExtensionCommandContext, basePa
|
|
|
23
25
|
let merged: string[];
|
|
24
26
|
try {
|
|
25
27
|
merged = nativeBranchListMerged(basePath, mainBranch, "gsd/*");
|
|
26
|
-
} catch {
|
|
28
|
+
} catch (e) {
|
|
29
|
+
logWarning("command", `merged branch list failed: ${(e as Error).message}`);
|
|
27
30
|
merged = [];
|
|
28
31
|
}
|
|
29
32
|
|
|
@@ -33,8 +36,8 @@ export async function handleCleanupBranches(ctx: ExtensionCommandContext, basePa
|
|
|
33
36
|
try {
|
|
34
37
|
nativeBranchDelete(basePath, branch, false);
|
|
35
38
|
deletedMerged++;
|
|
36
|
-
} catch {
|
|
37
|
-
|
|
39
|
+
} catch (e) {
|
|
40
|
+
logWarning("command", `branch delete failed for ${branch}: ${(e as Error).message}`);
|
|
38
41
|
}
|
|
39
42
|
}
|
|
40
43
|
|
|
@@ -66,7 +69,7 @@ export async function handleCleanupBranches(ctx: ExtensionCommandContext, basePa
|
|
|
66
69
|
try {
|
|
67
70
|
nativeBranchDelete(basePath, branch, true);
|
|
68
71
|
deletedStaleMilestones++;
|
|
69
|
-
} catch {
|
|
72
|
+
} catch (e) { logWarning("command", `stale milestone branch delete failed for ${branch}: ${(e as Error).message}`); }
|
|
70
73
|
continue;
|
|
71
74
|
}
|
|
72
75
|
}
|
|
@@ -77,7 +80,8 @@ export async function handleCleanupBranches(ctx: ExtensionCommandContext, basePa
|
|
|
77
80
|
let roadmapContent: string | null = null;
|
|
78
81
|
try {
|
|
79
82
|
roadmapContent = await loadFile(roadmapPath);
|
|
80
|
-
} catch {
|
|
83
|
+
} catch (e) {
|
|
84
|
+
logWarning("command", `loadFile failed for ${roadmapPath}: ${(e as Error).message}`);
|
|
81
85
|
roadmapContent = null;
|
|
82
86
|
}
|
|
83
87
|
if (!roadmapContent) continue;
|
|
@@ -85,12 +89,12 @@ export async function handleCleanupBranches(ctx: ExtensionCommandContext, basePa
|
|
|
85
89
|
try {
|
|
86
90
|
nativeBranchDelete(basePath, branch, true);
|
|
87
91
|
deletedStaleMilestones++;
|
|
88
|
-
} catch {
|
|
89
|
-
|
|
92
|
+
} catch (e) {
|
|
93
|
+
logWarning("command", `milestone branch delete failed for ${branch}: ${(e as Error).message}`);
|
|
90
94
|
}
|
|
91
95
|
}
|
|
92
|
-
} catch {
|
|
93
|
-
|
|
96
|
+
} catch (e) {
|
|
97
|
+
logWarning("command", `stale milestone cleanup failed: ${(e as Error).message}`);
|
|
94
98
|
}
|
|
95
99
|
|
|
96
100
|
const summary: string[] = [];
|
|
@@ -122,7 +126,8 @@ export async function handleCleanupSnapshots(ctx: ExtensionCommandContext, baseP
|
|
|
122
126
|
let refs: string[];
|
|
123
127
|
try {
|
|
124
128
|
refs = nativeForEachRef(basePath, "refs/gsd/snapshots/");
|
|
125
|
-
} catch {
|
|
129
|
+
} catch (e) {
|
|
130
|
+
logWarning("command", `snapshot ref list failed: ${(e as Error).message}`);
|
|
126
131
|
ctx.ui.notify("No snapshot refs to clean up.", "info");
|
|
127
132
|
return;
|
|
128
133
|
}
|
|
@@ -147,8 +152,8 @@ export async function handleCleanupSnapshots(ctx: ExtensionCommandContext, baseP
|
|
|
147
152
|
try {
|
|
148
153
|
nativeUpdateRef(basePath, old);
|
|
149
154
|
pruned++;
|
|
150
|
-
} catch {
|
|
151
|
-
|
|
155
|
+
} catch (e) {
|
|
156
|
+
logWarning("command", `snapshot ref update failed for ${old}: ${(e as Error).message}`);
|
|
152
157
|
}
|
|
153
158
|
}
|
|
154
159
|
}
|
|
@@ -164,7 +169,8 @@ export async function handleCleanupWorktrees(ctx: ExtensionCommandContext, baseP
|
|
|
164
169
|
let statuses;
|
|
165
170
|
try {
|
|
166
171
|
statuses = getAllWorktreeHealth(basePath);
|
|
167
|
-
} catch {
|
|
172
|
+
} catch (e) {
|
|
173
|
+
logWarning("command", `worktree health inspection failed: ${(e as Error).message}`);
|
|
168
174
|
ctx.ui.notify("Failed to inspect worktrees.", "error");
|
|
169
175
|
return;
|
|
170
176
|
}
|
|
@@ -197,7 +203,8 @@ export async function handleCleanupWorktrees(ctx: ExtensionCommandContext, baseP
|
|
|
197
203
|
removeWorktree(basePath, wt.name, { deleteBranch: true });
|
|
198
204
|
lines.push(` ✓ ${wt.name} removed (branch ${wt.branch} deleted)`);
|
|
199
205
|
removed++;
|
|
200
|
-
} catch {
|
|
206
|
+
} catch (e) {
|
|
207
|
+
logWarning("command", `worktree removal failed for ${wt.name}: ${(e as Error).message}`);
|
|
201
208
|
lines.push(` ✗ ${wt.name} failed to remove`);
|
|
202
209
|
}
|
|
203
210
|
}
|
|
@@ -246,7 +253,7 @@ export async function handleSkip(unitArg: string, ctx: ExtensionCommandContext,
|
|
|
246
253
|
if (fileExists(completedKeysFile)) {
|
|
247
254
|
keys = JSON.parse(readFile(completedKeysFile, "utf-8"));
|
|
248
255
|
}
|
|
249
|
-
} catch {
|
|
256
|
+
} catch (e) { logWarning("command", `completed-units.json parse failed: ${(e as Error).message}`); }
|
|
250
257
|
|
|
251
258
|
// Normalize: accept "execute-task/M001/S01/T03", "M001/S01/T03", or just "T03"
|
|
252
259
|
let skipKey = unitArg;
|
|
@@ -371,7 +378,8 @@ export async function handleCleanupProjects(args: string, ctx: ExtensionCommandC
|
|
|
371
378
|
hashList = readdirSync(projectsDir, { withFileTypes: true })
|
|
372
379
|
.filter(e => e.isDirectory())
|
|
373
380
|
.map(e => e.name);
|
|
374
|
-
} catch {
|
|
381
|
+
} catch (e) {
|
|
382
|
+
logWarning("command", `readdir failed for project-state directory: ${(e as Error).message}`);
|
|
375
383
|
ctx.ui.notify(`Failed to read project-state directory at ${projectsDir}.`, "error");
|
|
376
384
|
return;
|
|
377
385
|
}
|
|
@@ -454,7 +462,8 @@ export async function handleCleanupProjects(args: string, ctx: ExtensionCommandC
|
|
|
454
462
|
try {
|
|
455
463
|
fsRmSync(pathJoin(projectsDir, e.hash), { recursive: true, force: true });
|
|
456
464
|
removed++;
|
|
457
|
-
} catch {
|
|
465
|
+
} catch (err) {
|
|
466
|
+
logWarning("command", `project cleanup rm failed for ${e.hash}: ${(err as Error).message}`);
|
|
458
467
|
failed.push(e.hash);
|
|
459
468
|
}
|
|
460
469
|
}
|
|
@@ -529,7 +538,7 @@ export async function handleRecover(ctx: ExtensionCommandContext, basePath: stri
|
|
|
529
538
|
ctx.ui.notify(lines.join("\n"), "success");
|
|
530
539
|
} catch (err) {
|
|
531
540
|
const msg = err instanceof Error ? err.message : String(err);
|
|
532
|
-
|
|
541
|
+
logWarning("command", `recover failed: ${msg}`);
|
|
533
542
|
ctx.ui.notify(`gsd recover failed: ${msg}`, "error");
|
|
534
543
|
}
|
|
535
544
|
}
|
|
@@ -16,6 +16,7 @@ export interface ClassificationResult {
|
|
|
16
16
|
tier: ComplexityTier;
|
|
17
17
|
reason: string;
|
|
18
18
|
downgraded: boolean; // true if budget pressure lowered the tier
|
|
19
|
+
taskMetadata?: TaskMetadata;
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
export interface TaskMetadata {
|
|
@@ -71,17 +72,20 @@ export function classifyUnitComplexity(
|
|
|
71
72
|
): ClassificationResult {
|
|
72
73
|
// Hook units default to light
|
|
73
74
|
if (unitType.startsWith("hook/")) {
|
|
74
|
-
const result: ClassificationResult = { tier: "light", reason: "hook unit", downgraded: false };
|
|
75
|
+
const result: ClassificationResult = { tier: "light", reason: "hook unit", downgraded: false, taskMetadata: undefined };
|
|
75
76
|
return applyBudgetPressure(result, budgetPct);
|
|
76
77
|
}
|
|
77
78
|
|
|
78
79
|
// Start with the default tier for this unit type
|
|
79
80
|
let tier = UNIT_TYPE_TIERS[unitType] ?? "standard";
|
|
80
81
|
let reason = `unit type: ${unitType}`;
|
|
82
|
+
let taskMeta: TaskMetadata | undefined;
|
|
81
83
|
|
|
82
84
|
// For execute-task, analyze task metadata for complexity signals
|
|
83
85
|
if (unitType === "execute-task") {
|
|
84
|
-
|
|
86
|
+
// Extract metadata once and reuse throughout to avoid double-extraction
|
|
87
|
+
taskMeta = metadata ?? extractTaskMetadata(unitId, basePath);
|
|
88
|
+
const taskAnalysis = analyzeTaskComplexity(unitId, basePath, taskMeta);
|
|
85
89
|
tier = taskAnalysis.tier;
|
|
86
90
|
reason = taskAnalysis.reason;
|
|
87
91
|
}
|
|
@@ -96,14 +100,15 @@ export function classifyUnitComplexity(
|
|
|
96
100
|
}
|
|
97
101
|
|
|
98
102
|
// Adaptive learning: check if history suggests bumping the tier
|
|
99
|
-
|
|
103
|
+
// Use already-extracted taskMeta.tags if available to avoid double-extraction
|
|
104
|
+
const tags = taskMeta?.tags ?? metadata?.tags;
|
|
100
105
|
const adaptiveAdjustment = getAdaptiveTierAdjustment(unitType, tier, tags);
|
|
101
106
|
if (adaptiveAdjustment && tierOrdinal(adaptiveAdjustment) > tierOrdinal(tier)) {
|
|
102
107
|
reason = `${reason} (adaptive: high failure rate at ${tier})`;
|
|
103
108
|
tier = adaptiveAdjustment;
|
|
104
109
|
}
|
|
105
110
|
|
|
106
|
-
const result: ClassificationResult = { tier, reason, downgraded: false };
|
|
111
|
+
const result: ClassificationResult = { tier, reason, downgraded: false, taskMetadata: taskMeta };
|
|
107
112
|
return applyBudgetPressure(result, budgetPct);
|
|
108
113
|
}
|
|
109
114
|
|
|
@@ -212,7 +217,7 @@ function analyzePlanComplexity(
|
|
|
212
217
|
/**
|
|
213
218
|
* Extract task metadata from the task plan file on disk.
|
|
214
219
|
*/
|
|
215
|
-
function extractTaskMetadata(unitId: string, basePath: string): TaskMetadata {
|
|
220
|
+
export function extractTaskMetadata(unitId: string, basePath: string): TaskMetadata {
|
|
216
221
|
const meta: TaskMetadata = {};
|
|
217
222
|
const { milestone: mid, slice: sid, task: tid } = parseUnitId(unitId);
|
|
218
223
|
if (!mid || !sid || !tid) return meta;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Observation masking for GSD auto-mode sessions.
|
|
3
|
+
*
|
|
4
|
+
* Replaces tool result content older than N turns with a placeholder.
|
|
5
|
+
* Reduces context bloat between compactions with zero LLM overhead.
|
|
6
|
+
* Preserves message ordering, roles, and all assistant/user messages.
|
|
7
|
+
*
|
|
8
|
+
* Operates on the pi-ai Message[] format (post-convertToLlm, pre-provider):
|
|
9
|
+
* - toolResult messages: { role: "toolResult", content: TextContent[] }
|
|
10
|
+
* - bash results are already converted to: { role: "user", content: [{type:"text",text:"..."}] }
|
|
11
|
+
* and start with "Ran `" from bashExecutionToText.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
interface MaskableMessage {
|
|
15
|
+
role: string;
|
|
16
|
+
content: unknown;
|
|
17
|
+
type?: string;
|
|
18
|
+
[key: string]: unknown;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const MASK_PLACEHOLDER = "[result masked — within summarized history]";
|
|
22
|
+
const MASK_CONTENT_BLOCK = [{ type: "text" as const, text: MASK_PLACEHOLDER }];
|
|
23
|
+
|
|
24
|
+
function findTurnBoundary(messages: MaskableMessage[], keepRecentTurns: number): number {
|
|
25
|
+
let turnsSeen = 0;
|
|
26
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
27
|
+
const m = messages[i];
|
|
28
|
+
// In the LLM payload, genuine user turns have role "user".
|
|
29
|
+
// Tool results have role "toolResult" and are excluded by this check.
|
|
30
|
+
if (m.role === "user") {
|
|
31
|
+
// Skip bash-result user messages (converted from bashExecution) — these aren't real user turns
|
|
32
|
+
if (isBashResultUserMessage(m)) continue;
|
|
33
|
+
turnsSeen++;
|
|
34
|
+
if (turnsSeen >= keepRecentTurns) return i;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return 0;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Detect user messages that originated from bashExecution.
|
|
42
|
+
* After convertToLlm, these are {role: "user", content: [{type:"text", text:"Ran `cmd`\n..."}]}.
|
|
43
|
+
* The bashExecutionToText format always starts with "Ran `".
|
|
44
|
+
*/
|
|
45
|
+
function isBashResultUserMessage(m: MaskableMessage): boolean {
|
|
46
|
+
if (m.role !== "user" || !Array.isArray(m.content)) return false;
|
|
47
|
+
const first = m.content[0];
|
|
48
|
+
return first && typeof first === "object" && "text" in first &&
|
|
49
|
+
typeof first.text === "string" && first.text.startsWith("Ran `");
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function isMaskableMessage(m: MaskableMessage): boolean {
|
|
53
|
+
// Tool result messages (role: "toolResult" in pi-ai format)
|
|
54
|
+
if (m.role === "toolResult") return true;
|
|
55
|
+
// Bash-result user messages (converted from bashExecution by convertToLlm)
|
|
56
|
+
if (isBashResultUserMessage(m)) return true;
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function createObservationMask(keepRecentTurns: number = 8) {
|
|
61
|
+
return (messages: MaskableMessage[]): MaskableMessage[] => {
|
|
62
|
+
const boundary = findTurnBoundary(messages, keepRecentTurns);
|
|
63
|
+
if (boundary === 0) return messages;
|
|
64
|
+
|
|
65
|
+
return messages.map((m, i) => {
|
|
66
|
+
if (i >= boundary) return m;
|
|
67
|
+
if (isMaskableMessage(m)) {
|
|
68
|
+
// Content may be string or array of content blocks — always replace with array
|
|
69
|
+
return { ...m, content: MASK_CONTENT_BLOCK };
|
|
70
|
+
}
|
|
71
|
+
return m;
|
|
72
|
+
});
|
|
73
|
+
};
|
|
74
|
+
}
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
* - The frozen DEFINITION.yaml on disk is the single source of truth for step policies.
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
+
import { logWarning } from "./workflow-logger.js";
|
|
20
21
|
import { readFileSync, existsSync, statSync } from "node:fs";
|
|
21
22
|
import { join, resolve, sep } from "node:path";
|
|
22
23
|
import { spawnSync } from "node:child_process";
|
|
@@ -130,8 +131,8 @@ function handleContentHeuristic(
|
|
|
130
131
|
if (!new RegExp(verify.pattern).test(content)) {
|
|
131
132
|
return "pause";
|
|
132
133
|
}
|
|
133
|
-
} catch {
|
|
134
|
-
|
|
134
|
+
} catch (e) {
|
|
135
|
+
logWarning("engine", `content-heuristic regex failed: ${(e as Error).message}`);
|
|
135
136
|
return "pause";
|
|
136
137
|
}
|
|
137
138
|
}
|
|
@@ -189,6 +189,13 @@ Setting `prefer_skills: []` does **not** disable skill discovery — it just mea
|
|
|
189
189
|
- `budget_pressure`: boolean — downgrade model tier when budget is under pressure. Default: `true`.
|
|
190
190
|
- `cross_provider`: boolean — allow routing across different providers. Default: `true`.
|
|
191
191
|
- `hooks`: boolean — enable routing hooks. Default: `true`.
|
|
192
|
+
- `capability_routing`: boolean — enable capability-profile scoring for model selection within a tier. Requires `enabled: true`. Default: `false`.
|
|
193
|
+
|
|
194
|
+
- `context_management`: configures context hygiene for auto-mode sessions. Keys:
|
|
195
|
+
- `observation_masking`: boolean — mask old tool results to reduce context bloat. Default: `true`.
|
|
196
|
+
- `observation_mask_turns`: number — keep this many recent turns verbatim (1-50). Default: `8`.
|
|
197
|
+
- `compaction_threshold_percent`: number — trigger compaction at this % of context window (0.5-0.95). Lower values fire compaction earlier, reducing drift. Default: `0.70`.
|
|
198
|
+
- `tool_result_max_chars`: number — max chars per tool result in GSD sessions (200-10000). Default: `800`.
|
|
192
199
|
|
|
193
200
|
- `auto_visualize`: boolean — show a visualizer hint after each milestone completion in auto-mode. Default: `false`.
|
|
194
201
|
|
|
@@ -10,7 +10,7 @@ import { existsSync, copyFileSync, mkdirSync, realpathSync } from "node:fs";
|
|
|
10
10
|
import { dirname } from "node:path";
|
|
11
11
|
import type { Decision, Requirement, GateRow, GateId, GateScope, GateStatus, GateVerdict } from "./types.js";
|
|
12
12
|
import { GSDError, GSD_STALE_STATE } from "./errors.js";
|
|
13
|
-
import { logError } from "./workflow-logger.js";
|
|
13
|
+
import { logError, logWarning } from "./workflow-logger.js";
|
|
14
14
|
|
|
15
15
|
const _require = createRequire(import.meta.url);
|
|
16
16
|
|
|
@@ -787,11 +787,11 @@ export function openDatabase(path: string): boolean {
|
|
|
787
787
|
initSchema(adapter, fileBacked);
|
|
788
788
|
process.stderr.write("gsd-db: recovered corrupt database via VACUUM\n");
|
|
789
789
|
} catch (retryErr) {
|
|
790
|
-
try { adapter.close(); } catch {
|
|
790
|
+
try { adapter.close(); } catch (e) { logWarning("db", `close after VACUUM failed: ${(e as Error).message}`); }
|
|
791
791
|
throw retryErr;
|
|
792
792
|
}
|
|
793
793
|
} else {
|
|
794
|
-
try { adapter.close(); } catch {
|
|
794
|
+
try { adapter.close(); } catch (e) { logWarning("db", `close after VACUUM failed: ${(e as Error).message}`); }
|
|
795
795
|
throw err;
|
|
796
796
|
}
|
|
797
797
|
}
|
|
@@ -802,7 +802,7 @@ export function openDatabase(path: string): boolean {
|
|
|
802
802
|
|
|
803
803
|
if (!_exitHandlerRegistered) {
|
|
804
804
|
_exitHandlerRegistered = true;
|
|
805
|
-
process.on("exit", () => { try { closeDatabase(); } catch {} });
|
|
805
|
+
process.on("exit", () => { try { closeDatabase(); } catch (e) { logWarning("db", `exit handler close failed: ${(e as Error).message}`); } });
|
|
806
806
|
}
|
|
807
807
|
|
|
808
808
|
return true;
|
|
@@ -812,16 +812,14 @@ export function closeDatabase(): void {
|
|
|
812
812
|
if (currentDb) {
|
|
813
813
|
try {
|
|
814
814
|
currentDb.exec('PRAGMA wal_checkpoint(TRUNCATE)');
|
|
815
|
-
} catch {
|
|
815
|
+
} catch (e) { logWarning("db", `WAL checkpoint failed: ${(e as Error).message}`); }
|
|
816
816
|
try {
|
|
817
817
|
// Incremental vacuum to reclaim space without blocking
|
|
818
818
|
currentDb.exec('PRAGMA incremental_vacuum(64)');
|
|
819
|
-
} catch {
|
|
819
|
+
} catch (e) { logWarning("db", `incremental vacuum failed: ${(e as Error).message}`); }
|
|
820
820
|
try {
|
|
821
821
|
currentDb.close();
|
|
822
|
-
} catch {
|
|
823
|
-
// swallow close errors
|
|
824
|
-
}
|
|
822
|
+
} catch (e) { logWarning("db", `database close failed: ${(e as Error).message}`); }
|
|
825
823
|
currentDb = null;
|
|
826
824
|
currentPath = null;
|
|
827
825
|
currentPid = 0;
|
|
@@ -833,7 +831,7 @@ export function vacuumDatabase(): void {
|
|
|
833
831
|
if (!currentDb) return;
|
|
834
832
|
try {
|
|
835
833
|
currentDb.exec('VACUUM');
|
|
836
|
-
} catch {
|
|
834
|
+
} catch (e) { logWarning("db", `VACUUM failed: ${(e as Error).message}`); }
|
|
837
835
|
}
|
|
838
836
|
|
|
839
837
|
let _txDepth = 0;
|
|
@@ -1038,7 +1036,7 @@ export function upsertRequirement(r: Requirement): void {
|
|
|
1038
1036
|
|
|
1039
1037
|
export function clearArtifacts(): void {
|
|
1040
1038
|
if (!currentDb) return;
|
|
1041
|
-
try { currentDb.exec("DELETE FROM artifacts"); } catch {
|
|
1039
|
+
try { currentDb.exec("DELETE FROM artifacts"); } catch (e) { logWarning("db", `clearArtifacts failed: ${(e as Error).message}`); }
|
|
1042
1040
|
}
|
|
1043
1041
|
|
|
1044
1042
|
export function insertArtifact(a: {
|
|
@@ -1661,11 +1659,11 @@ export function getActiveSliceFromDb(milestoneId: string): SliceRow | null {
|
|
|
1661
1659
|
const row = currentDb.prepare(
|
|
1662
1660
|
`SELECT s.* FROM slices s
|
|
1663
1661
|
WHERE s.milestone_id = :mid
|
|
1664
|
-
AND s.status NOT IN ('complete', 'done')
|
|
1662
|
+
AND s.status NOT IN ('complete', 'done', 'skipped')
|
|
1665
1663
|
AND NOT EXISTS (
|
|
1666
1664
|
SELECT 1 FROM json_each(s.depends) AS dep
|
|
1667
1665
|
WHERE dep.value NOT IN (
|
|
1668
|
-
SELECT id FROM slices WHERE milestone_id = :mid AND status IN ('complete', 'done')
|
|
1666
|
+
SELECT id FROM slices WHERE milestone_id = :mid AND status IN ('complete', 'done', 'skipped')
|
|
1669
1667
|
)
|
|
1670
1668
|
)
|
|
1671
1669
|
ORDER BY s.sequence, s.id
|
|
@@ -1801,7 +1799,7 @@ export function reconcileWorktreeDb(
|
|
|
1801
1799
|
// ATTACHing a WAL-mode DB to itself corrupts the WAL (#2823).
|
|
1802
1800
|
try {
|
|
1803
1801
|
if (realpathSync(mainDbPath) === realpathSync(worktreeDbPath)) return zero;
|
|
1804
|
-
} catch {
|
|
1802
|
+
} catch (e) { logWarning("db", `realpathSync failed: ${(e as Error).message}`); }
|
|
1805
1803
|
// Sanitize path: reject any characters that could break ATTACH syntax.
|
|
1806
1804
|
// ATTACH DATABASE doesn't support parameterized paths in all providers,
|
|
1807
1805
|
// so we use strict allowlist validation instead.
|
|
@@ -1938,12 +1936,12 @@ export function reconcileWorktreeDb(
|
|
|
1938
1936
|
|
|
1939
1937
|
adapter.exec("COMMIT");
|
|
1940
1938
|
} catch (txErr) {
|
|
1941
|
-
try { adapter.exec("ROLLBACK"); } catch {
|
|
1939
|
+
try { adapter.exec("ROLLBACK"); } catch (e) { logWarning("db", `rollback failed: ${(e as Error).message}`); }
|
|
1942
1940
|
throw txErr;
|
|
1943
1941
|
}
|
|
1944
1942
|
return { ...merged, conflicts };
|
|
1945
1943
|
} finally {
|
|
1946
|
-
try { adapter.exec("DETACH DATABASE wt"); } catch {
|
|
1944
|
+
try { adapter.exec("DETACH DATABASE wt"); } catch (e) { logWarning("db", `detach worktree DB failed: ${(e as Error).message}`); }
|
|
1947
1945
|
}
|
|
1948
1946
|
} catch (err) {
|
|
1949
1947
|
logError("db", "worktree DB reconciliation failed", { error: (err as Error).message });
|
|
@@ -52,6 +52,7 @@ export {
|
|
|
52
52
|
buildExistingMilestonesContext,
|
|
53
53
|
} from "./guided-flow-queue.js";
|
|
54
54
|
import { getErrorMessage } from "./error-utils.js";
|
|
55
|
+
import { logWarning } from "./workflow-logger.js";
|
|
55
56
|
|
|
56
57
|
// ─── ID Generation with Reservation ─────────────────────────────────────────
|
|
57
58
|
|
|
@@ -180,7 +181,7 @@ export function checkAutoStartAfterDiscuss(): boolean {
|
|
|
180
181
|
);
|
|
181
182
|
}
|
|
182
183
|
}
|
|
183
|
-
} catch {
|
|
184
|
+
} catch (e) { logWarning("guided", `PROJECT.md parsing failed: ${(e as Error).message}`); }
|
|
184
185
|
}
|
|
185
186
|
|
|
186
187
|
// Gate 4: Discussion manifest process verification (multi-milestone only)
|
|
@@ -212,7 +213,7 @@ export function checkAutoStartAfterDiscuss(): boolean {
|
|
|
212
213
|
);
|
|
213
214
|
}
|
|
214
215
|
}
|
|
215
|
-
} catch {
|
|
216
|
+
} catch (e) { logWarning("guided", `discussion manifest verification failed: ${(e as Error).message}`); }
|
|
216
217
|
}
|
|
217
218
|
|
|
218
219
|
// Draft promotion cleanup: if a CONTEXT-DRAFT.md exists alongside the new
|
|
@@ -220,16 +221,16 @@ export function checkAutoStartAfterDiscuss(): boolean {
|
|
|
220
221
|
try {
|
|
221
222
|
const draftFile = resolveMilestoneFile(basePath, milestoneId, "CONTEXT-DRAFT");
|
|
222
223
|
if (draftFile) unlinkSync(draftFile);
|
|
223
|
-
} catch {
|
|
224
|
+
} catch (e) { logWarning("guided", `CONTEXT-DRAFT.md unlink failed: ${(e as Error).message}`); }
|
|
224
225
|
|
|
225
226
|
// Cleanup: remove discussion manifest after auto-start (only needed during discussion)
|
|
226
|
-
try { unlinkSync(manifestPath); } catch {
|
|
227
|
+
try { unlinkSync(manifestPath); } catch (e) { logWarning("guided", `manifest unlink failed: ${(e as Error).message}`); }
|
|
227
228
|
|
|
228
229
|
pendingAutoStartMap.delete(basePath);
|
|
229
230
|
ctx.ui.notify(`Milestone ${milestoneId} ready.`, "info");
|
|
230
231
|
startAuto(ctx, pi, basePath, false, { step }).catch((err) => {
|
|
231
232
|
ctx.ui.notify(`Auto-start failed: ${getErrorMessage(err)}`, "error");
|
|
232
|
-
|
|
233
|
+
logWarning("guided", `auto start error: ${getErrorMessage(err)}`);
|
|
233
234
|
debugLog("auto-start-failed", { error: getErrorMessage(err) });
|
|
234
235
|
});
|
|
235
236
|
return true;
|
|
@@ -895,8 +896,8 @@ function selfHealRuntimeRecords(basePath: string, ctx: ExtensionContext): { clea
|
|
|
895
896
|
ctx.ui.notify(`Self-heal: cleared ${cleared} stale runtime record(s) from a previous session.`, "info");
|
|
896
897
|
}
|
|
897
898
|
return { cleared };
|
|
898
|
-
} catch {
|
|
899
|
-
|
|
899
|
+
} catch (e) {
|
|
900
|
+
logWarning("guided", `self-heal stale runtime records failed: ${(e as Error).message}`);
|
|
900
901
|
return { cleared: 0 };
|
|
901
902
|
}
|
|
902
903
|
}
|
|
@@ -1142,7 +1143,7 @@ export async function showSmartEntry(
|
|
|
1142
1143
|
);
|
|
1143
1144
|
return;
|
|
1144
1145
|
}
|
|
1145
|
-
} catch {
|
|
1146
|
+
} catch (e) { logWarning("guided", `directory read failed: ${(e as Error).message}`); }
|
|
1146
1147
|
}
|
|
1147
1148
|
}
|
|
1148
1149
|
|
|
@@ -16,6 +16,7 @@ import { gsdRoot } from "./paths.js";
|
|
|
16
16
|
import { assertSafeDirectory } from "./validate-directory.js";
|
|
17
17
|
import type { ProjectDetection, ProjectSignals } from "./detection.js";
|
|
18
18
|
import { runSkillInstallStep } from "./skill-catalog.js";
|
|
19
|
+
import { generateCodebaseMap, writeCodebaseMap } from "./codebase-generator.js";
|
|
19
20
|
|
|
20
21
|
// ─── Types ──────────────────────────────────────────────────────────────────────
|
|
21
22
|
|
|
@@ -238,6 +239,17 @@ export async function showProjectInit(
|
|
|
238
239
|
ensureGitignore(basePath);
|
|
239
240
|
untrackRuntimeFiles(basePath);
|
|
240
241
|
|
|
242
|
+
// Auto-generate codebase map for instant agent orientation
|
|
243
|
+
try {
|
|
244
|
+
const result = generateCodebaseMap(basePath);
|
|
245
|
+
if (result.fileCount > 0) {
|
|
246
|
+
writeCodebaseMap(basePath, result.content);
|
|
247
|
+
ctx.ui.notify(`Codebase map generated: ${result.fileCount} files`, "info");
|
|
248
|
+
}
|
|
249
|
+
} catch {
|
|
250
|
+
// Non-fatal — codebase map generation failure should never block project init
|
|
251
|
+
}
|
|
252
|
+
|
|
241
253
|
ctx.ui.notify("GSD initialized. Starting your first milestone...", "info");
|
|
242
254
|
|
|
243
255
|
return { completed: true, bootstrapped: true };
|