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
|
@@ -5,26 +5,32 @@
|
|
|
5
5
|
* Subcommands: generate, update, stats, help
|
|
6
6
|
*/
|
|
7
7
|
import { generateCodebaseMap, updateCodebaseMap, writeCodebaseMap, getCodebaseMapStats, readCodebaseMap, } from "./codebase-generator.js";
|
|
8
|
+
import { loadEffectiveGSDPreferences } from "./preferences.js";
|
|
8
9
|
const USAGE = "Usage: /gsd codebase [generate|update|stats]\n\n" +
|
|
9
|
-
" generate [--max-files N] — Generate or regenerate CODEBASE.md\n" +
|
|
10
|
-
" update
|
|
11
|
-
" stats
|
|
12
|
-
" help
|
|
13
|
-
"With no subcommand, shows stats if a map exists or help if not
|
|
10
|
+
" generate [--max-files N] [--collapse-threshold N] — Generate or regenerate CODEBASE.md\n" +
|
|
11
|
+
" update [--max-files N] [--collapse-threshold N] — Incremental update (preserves descriptions)\n" +
|
|
12
|
+
" stats — Show file count, coverage, and generation time\n" +
|
|
13
|
+
" help — Show this help\n\n" +
|
|
14
|
+
"With no subcommand, shows stats if a map exists or help if not.\n\n" +
|
|
15
|
+
"Configure defaults via preferences.md:\n" +
|
|
16
|
+
" codebase:\n" +
|
|
17
|
+
" exclude_patterns: [\"docs/\", \"fixtures/\"]\n" +
|
|
18
|
+
" max_files: 1000\n" +
|
|
19
|
+
" collapse_threshold: 15";
|
|
14
20
|
export async function handleCodebase(args, ctx, _pi) {
|
|
15
21
|
const basePath = process.cwd();
|
|
16
22
|
const parts = args.trim().split(/\s+/);
|
|
17
23
|
const sub = parts[0] ?? "";
|
|
18
24
|
switch (sub) {
|
|
19
25
|
case "generate": {
|
|
20
|
-
const
|
|
21
|
-
if (
|
|
26
|
+
const options = resolveCodebaseOptions(args, ctx);
|
|
27
|
+
if (options === false)
|
|
22
28
|
return; // validation failed, message already shown
|
|
23
29
|
const existing = readCodebaseMap(basePath);
|
|
24
30
|
const existingDescriptions = existing
|
|
25
31
|
? (await import("./codebase-generator.js")).parseCodebaseMap(existing)
|
|
26
32
|
: undefined;
|
|
27
|
-
const result = generateCodebaseMap(basePath,
|
|
33
|
+
const result = generateCodebaseMap(basePath, options, existingDescriptions);
|
|
28
34
|
if (result.fileCount === 0) {
|
|
29
35
|
ctx.ui.notify("Codebase map generated with 0 files.\n" +
|
|
30
36
|
"Is this a git repository? Run 'git ls-files' to verify.", "warning");
|
|
@@ -42,10 +48,10 @@ export async function handleCodebase(args, ctx, _pi) {
|
|
|
42
48
|
ctx.ui.notify("No codebase map found. Run /gsd codebase generate to create one.", "warning");
|
|
43
49
|
return;
|
|
44
50
|
}
|
|
45
|
-
const
|
|
46
|
-
if (
|
|
51
|
+
const options = resolveCodebaseOptions(args, ctx);
|
|
52
|
+
if (options === false)
|
|
47
53
|
return;
|
|
48
|
-
const result = updateCodebaseMap(basePath,
|
|
54
|
+
const result = updateCodebaseMap(basePath, options);
|
|
49
55
|
writeCodebaseMap(basePath, result.content);
|
|
50
56
|
ctx.ui.notify(`Codebase map updated: ${result.fileCount} files\n` +
|
|
51
57
|
` Added: ${result.added} | Removed: ${result.removed} | Unchanged: ${result.unchanged}` +
|
|
@@ -93,19 +99,40 @@ function showStats(basePath, ctx) {
|
|
|
93
99
|
: `Coverage is complete.`), "info");
|
|
94
100
|
}
|
|
95
101
|
/**
|
|
96
|
-
*
|
|
97
|
-
*
|
|
102
|
+
* Resolve codebase map options by merging preferences with CLI flags.
|
|
103
|
+
* CLI flags override preferences; preferences override built-in defaults.
|
|
104
|
+
* Returns false if validation failed (error already shown to user).
|
|
98
105
|
*/
|
|
99
|
-
function
|
|
106
|
+
function resolveCodebaseOptions(args, ctx) {
|
|
107
|
+
// Load preferences defaults
|
|
108
|
+
const prefs = loadEffectiveGSDPreferences()?.preferences?.codebase;
|
|
109
|
+
// Parse CLI flags
|
|
100
110
|
const maxFilesStr = extractFlag(args, "--max-files");
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
if (
|
|
105
|
-
|
|
106
|
-
|
|
111
|
+
const collapseStr = extractFlag(args, "--collapse-threshold");
|
|
112
|
+
// Validate --max-files
|
|
113
|
+
let maxFiles;
|
|
114
|
+
if (maxFilesStr) {
|
|
115
|
+
maxFiles = parseInt(maxFilesStr, 10);
|
|
116
|
+
if (isNaN(maxFiles) || maxFiles < 1) {
|
|
117
|
+
ctx.ui.notify("--max-files must be a positive integer (e.g. --max-files 200).", "warning");
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
// Validate --collapse-threshold
|
|
122
|
+
let collapseThreshold;
|
|
123
|
+
if (collapseStr) {
|
|
124
|
+
collapseThreshold = parseInt(collapseStr, 10);
|
|
125
|
+
if (isNaN(collapseThreshold) || collapseThreshold < 1) {
|
|
126
|
+
ctx.ui.notify("--collapse-threshold must be a positive integer (e.g. --collapse-threshold 15).", "warning");
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
107
129
|
}
|
|
108
|
-
return
|
|
130
|
+
return {
|
|
131
|
+
// CLI flags override preferences
|
|
132
|
+
maxFiles: maxFiles ?? prefs?.max_files,
|
|
133
|
+
collapseThreshold: collapseThreshold ?? prefs?.collapse_threshold,
|
|
134
|
+
excludePatterns: prefs?.exclude_patterns,
|
|
135
|
+
};
|
|
109
136
|
}
|
|
110
137
|
function extractFlag(args, flag) {
|
|
111
138
|
const escaped = flag.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
import { existsSync } from "node:fs";
|
|
7
7
|
import { join } from "node:path";
|
|
8
8
|
import { gsdRoot } from "./paths.js";
|
|
9
|
+
import { logWarning } from "./workflow-logger.js";
|
|
9
10
|
import { getErrorMessage } from "./error-utils.js";
|
|
10
11
|
export function formatInspectOutput(data) {
|
|
11
12
|
const lines = [];
|
|
@@ -71,7 +72,7 @@ export async function handleInspect(ctx) {
|
|
|
71
72
|
ctx.ui.notify(formatInspectOutput(data), "info");
|
|
72
73
|
}
|
|
73
74
|
catch (err) {
|
|
74
|
-
|
|
75
|
+
logWarning("command", `/gsd inspect failed: ${getErrorMessage(err)}`);
|
|
75
76
|
ctx.ui.notify("Failed to inspect GSD database. Check stderr for details.", "error");
|
|
76
77
|
}
|
|
77
78
|
}
|
|
@@ -5,12 +5,14 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { deriveState } from "./state.js";
|
|
7
7
|
import { nativeBranchList, nativeDetectMainBranch, nativeBranchListMerged, nativeBranchDelete, nativeForEachRef, nativeUpdateRef } from "./native-git-bridge.js";
|
|
8
|
+
import { logWarning } from "./workflow-logger.js";
|
|
8
9
|
export async function handleCleanupBranches(ctx, basePath) {
|
|
9
10
|
let branches;
|
|
10
11
|
try {
|
|
11
12
|
branches = nativeBranchList(basePath, "gsd/*");
|
|
12
13
|
}
|
|
13
|
-
catch {
|
|
14
|
+
catch (e) {
|
|
15
|
+
logWarning("command", `branch list failed: ${e.message}`);
|
|
14
16
|
ctx.ui.notify("No GSD branches to clean up.", "info");
|
|
15
17
|
return;
|
|
16
18
|
}
|
|
@@ -20,7 +22,8 @@ export async function handleCleanupBranches(ctx, basePath) {
|
|
|
20
22
|
try {
|
|
21
23
|
merged = nativeBranchListMerged(basePath, mainBranch, "gsd/*");
|
|
22
24
|
}
|
|
23
|
-
catch {
|
|
25
|
+
catch (e) {
|
|
26
|
+
logWarning("command", `merged branch list failed: ${e.message}`);
|
|
24
27
|
merged = [];
|
|
25
28
|
}
|
|
26
29
|
const mergedNonQuick = merged.filter((b) => !b.startsWith("gsd/quick/"));
|
|
@@ -30,8 +33,8 @@ export async function handleCleanupBranches(ctx, basePath) {
|
|
|
30
33
|
nativeBranchDelete(basePath, branch, false);
|
|
31
34
|
deletedMerged++;
|
|
32
35
|
}
|
|
33
|
-
catch {
|
|
34
|
-
|
|
36
|
+
catch (e) {
|
|
37
|
+
logWarning("command", `branch delete failed for ${branch}: ${e.message}`);
|
|
35
38
|
}
|
|
36
39
|
}
|
|
37
40
|
// Also delete stale milestone branches for completed milestones when detached
|
|
@@ -61,7 +64,9 @@ export async function handleCleanupBranches(ctx, basePath) {
|
|
|
61
64
|
nativeBranchDelete(basePath, branch, true);
|
|
62
65
|
deletedStaleMilestones++;
|
|
63
66
|
}
|
|
64
|
-
catch {
|
|
67
|
+
catch (e) {
|
|
68
|
+
logWarning("command", `stale milestone branch delete failed for ${branch}: ${e.message}`);
|
|
69
|
+
}
|
|
65
70
|
continue;
|
|
66
71
|
}
|
|
67
72
|
}
|
|
@@ -73,7 +78,8 @@ export async function handleCleanupBranches(ctx, basePath) {
|
|
|
73
78
|
try {
|
|
74
79
|
roadmapContent = await loadFile(roadmapPath);
|
|
75
80
|
}
|
|
76
|
-
catch {
|
|
81
|
+
catch (e) {
|
|
82
|
+
logWarning("command", `loadFile failed for ${roadmapPath}: ${e.message}`);
|
|
77
83
|
roadmapContent = null;
|
|
78
84
|
}
|
|
79
85
|
if (!roadmapContent)
|
|
@@ -84,13 +90,13 @@ export async function handleCleanupBranches(ctx, basePath) {
|
|
|
84
90
|
nativeBranchDelete(basePath, branch, true);
|
|
85
91
|
deletedStaleMilestones++;
|
|
86
92
|
}
|
|
87
|
-
catch {
|
|
88
|
-
|
|
93
|
+
catch (e) {
|
|
94
|
+
logWarning("command", `milestone branch delete failed for ${branch}: ${e.message}`);
|
|
89
95
|
}
|
|
90
96
|
}
|
|
91
97
|
}
|
|
92
|
-
catch {
|
|
93
|
-
|
|
98
|
+
catch (e) {
|
|
99
|
+
logWarning("command", `stale milestone cleanup failed: ${e.message}`);
|
|
94
100
|
}
|
|
95
101
|
const summary = [];
|
|
96
102
|
if (deletedMerged > 0) {
|
|
@@ -116,7 +122,8 @@ export async function handleCleanupSnapshots(ctx, basePath) {
|
|
|
116
122
|
try {
|
|
117
123
|
refs = nativeForEachRef(basePath, "refs/gsd/snapshots/");
|
|
118
124
|
}
|
|
119
|
-
catch {
|
|
125
|
+
catch (e) {
|
|
126
|
+
logWarning("command", `snapshot ref list failed: ${e.message}`);
|
|
120
127
|
ctx.ui.notify("No snapshot refs to clean up.", "info");
|
|
121
128
|
return;
|
|
122
129
|
}
|
|
@@ -140,8 +147,8 @@ export async function handleCleanupSnapshots(ctx, basePath) {
|
|
|
140
147
|
nativeUpdateRef(basePath, old);
|
|
141
148
|
pruned++;
|
|
142
149
|
}
|
|
143
|
-
catch {
|
|
144
|
-
|
|
150
|
+
catch (e) {
|
|
151
|
+
logWarning("command", `snapshot ref update failed for ${old}: ${e.message}`);
|
|
145
152
|
}
|
|
146
153
|
}
|
|
147
154
|
}
|
|
@@ -155,7 +162,8 @@ export async function handleCleanupWorktrees(ctx, basePath) {
|
|
|
155
162
|
try {
|
|
156
163
|
statuses = getAllWorktreeHealth(basePath);
|
|
157
164
|
}
|
|
158
|
-
catch {
|
|
165
|
+
catch (e) {
|
|
166
|
+
logWarning("command", `worktree health inspection failed: ${e.message}`);
|
|
159
167
|
ctx.ui.notify("Failed to inspect worktrees.", "error");
|
|
160
168
|
return;
|
|
161
169
|
}
|
|
@@ -185,7 +193,8 @@ export async function handleCleanupWorktrees(ctx, basePath) {
|
|
|
185
193
|
lines.push(` ✓ ${wt.name} removed (branch ${wt.branch} deleted)`);
|
|
186
194
|
removed++;
|
|
187
195
|
}
|
|
188
|
-
catch {
|
|
196
|
+
catch (e) {
|
|
197
|
+
logWarning("command", `worktree removal failed for ${wt.name}: ${e.message}`);
|
|
189
198
|
lines.push(` ✗ ${wt.name} failed to remove`);
|
|
190
199
|
}
|
|
191
200
|
}
|
|
@@ -228,7 +237,9 @@ export async function handleSkip(unitArg, ctx, basePath) {
|
|
|
228
237
|
keys = JSON.parse(readFile(completedKeysFile, "utf-8"));
|
|
229
238
|
}
|
|
230
239
|
}
|
|
231
|
-
catch {
|
|
240
|
+
catch (e) {
|
|
241
|
+
logWarning("command", `completed-units.json parse failed: ${e.message}`);
|
|
242
|
+
}
|
|
232
243
|
// Normalize: accept "execute-task/M001/S01/T03", "M001/S01/T03", or just "T03"
|
|
233
244
|
let skipKey = unitArg;
|
|
234
245
|
if (!skipKey.includes("execute-task") && !skipKey.includes("plan-") && !skipKey.includes("research-") && !skipKey.includes("complete-")) {
|
|
@@ -339,7 +350,8 @@ export async function handleCleanupProjects(args, ctx) {
|
|
|
339
350
|
.filter(e => e.isDirectory())
|
|
340
351
|
.map(e => e.name);
|
|
341
352
|
}
|
|
342
|
-
catch {
|
|
353
|
+
catch (e) {
|
|
354
|
+
logWarning("command", `readdir failed for project-state directory: ${e.message}`);
|
|
343
355
|
ctx.ui.notify(`Failed to read project-state directory at ${projectsDir}.`, "error");
|
|
344
356
|
return;
|
|
345
357
|
}
|
|
@@ -413,7 +425,8 @@ export async function handleCleanupProjects(args, ctx) {
|
|
|
413
425
|
fsRmSync(pathJoin(projectsDir, e.hash), { recursive: true, force: true });
|
|
414
426
|
removed++;
|
|
415
427
|
}
|
|
416
|
-
catch {
|
|
428
|
+
catch (err) {
|
|
429
|
+
logWarning("command", `project cleanup rm failed for ${e.hash}: ${err.message}`);
|
|
417
430
|
failed.push(e.hash);
|
|
418
431
|
}
|
|
419
432
|
}
|
|
@@ -479,7 +492,7 @@ export async function handleRecover(ctx, basePath) {
|
|
|
479
492
|
}
|
|
480
493
|
catch (err) {
|
|
481
494
|
const msg = err instanceof Error ? err.message : String(err);
|
|
482
|
-
|
|
495
|
+
logWarning("command", `recover failed: ${msg}`);
|
|
483
496
|
ctx.ui.notify(`gsd recover failed: ${msg}`, "error");
|
|
484
497
|
}
|
|
485
498
|
}
|
|
@@ -38,15 +38,18 @@ const UNIT_TYPE_TIERS = {
|
|
|
38
38
|
export function classifyUnitComplexity(unitType, unitId, basePath, budgetPct, metadata) {
|
|
39
39
|
// Hook units default to light
|
|
40
40
|
if (unitType.startsWith("hook/")) {
|
|
41
|
-
const result = { tier: "light", reason: "hook unit", downgraded: false };
|
|
41
|
+
const result = { tier: "light", reason: "hook unit", downgraded: false, taskMetadata: undefined };
|
|
42
42
|
return applyBudgetPressure(result, budgetPct);
|
|
43
43
|
}
|
|
44
44
|
// Start with the default tier for this unit type
|
|
45
45
|
let tier = UNIT_TYPE_TIERS[unitType] ?? "standard";
|
|
46
46
|
let reason = `unit type: ${unitType}`;
|
|
47
|
+
let taskMeta;
|
|
47
48
|
// For execute-task, analyze task metadata for complexity signals
|
|
48
49
|
if (unitType === "execute-task") {
|
|
49
|
-
|
|
50
|
+
// Extract metadata once and reuse throughout to avoid double-extraction
|
|
51
|
+
taskMeta = metadata ?? extractTaskMetadata(unitId, basePath);
|
|
52
|
+
const taskAnalysis = analyzeTaskComplexity(unitId, basePath, taskMeta);
|
|
50
53
|
tier = taskAnalysis.tier;
|
|
51
54
|
reason = taskAnalysis.reason;
|
|
52
55
|
}
|
|
@@ -59,13 +62,14 @@ export function classifyUnitComplexity(unitType, unitId, basePath, budgetPct, me
|
|
|
59
62
|
}
|
|
60
63
|
}
|
|
61
64
|
// Adaptive learning: check if history suggests bumping the tier
|
|
62
|
-
|
|
65
|
+
// Use already-extracted taskMeta.tags if available to avoid double-extraction
|
|
66
|
+
const tags = taskMeta?.tags ?? metadata?.tags;
|
|
63
67
|
const adaptiveAdjustment = getAdaptiveTierAdjustment(unitType, tier, tags);
|
|
64
68
|
if (adaptiveAdjustment && tierOrdinal(adaptiveAdjustment) > tierOrdinal(tier)) {
|
|
65
69
|
reason = `${reason} (adaptive: high failure rate at ${tier})`;
|
|
66
70
|
tier = adaptiveAdjustment;
|
|
67
71
|
}
|
|
68
|
-
const result = { tier, reason, downgraded: false };
|
|
72
|
+
const result = { tier, reason, downgraded: false, taskMetadata: taskMeta };
|
|
69
73
|
return applyBudgetPressure(result, budgetPct);
|
|
70
74
|
}
|
|
71
75
|
/**
|
|
@@ -149,7 +153,7 @@ function analyzePlanComplexity(unitId, basePath) {
|
|
|
149
153
|
/**
|
|
150
154
|
* Extract task metadata from the task plan file on disk.
|
|
151
155
|
*/
|
|
152
|
-
function extractTaskMetadata(unitId, basePath) {
|
|
156
|
+
export function extractTaskMetadata(unitId, basePath) {
|
|
153
157
|
const meta = {};
|
|
154
158
|
const { milestone: mid, slice: sid, task: tid } = parseUnitId(unitId);
|
|
155
159
|
if (!mid || !sid || !tid)
|
|
@@ -0,0 +1,68 @@
|
|
|
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
|
+
const MASK_PLACEHOLDER = "[result masked — within summarized history]";
|
|
14
|
+
const MASK_CONTENT_BLOCK = [{ type: "text", text: MASK_PLACEHOLDER }];
|
|
15
|
+
function findTurnBoundary(messages, keepRecentTurns) {
|
|
16
|
+
let turnsSeen = 0;
|
|
17
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
18
|
+
const m = messages[i];
|
|
19
|
+
// In the LLM payload, genuine user turns have role "user".
|
|
20
|
+
// Tool results have role "toolResult" and are excluded by this check.
|
|
21
|
+
if (m.role === "user") {
|
|
22
|
+
// Skip bash-result user messages (converted from bashExecution) — these aren't real user turns
|
|
23
|
+
if (isBashResultUserMessage(m))
|
|
24
|
+
continue;
|
|
25
|
+
turnsSeen++;
|
|
26
|
+
if (turnsSeen >= keepRecentTurns)
|
|
27
|
+
return i;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return 0;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Detect user messages that originated from bashExecution.
|
|
34
|
+
* After convertToLlm, these are {role: "user", content: [{type:"text", text:"Ran `cmd`\n..."}]}.
|
|
35
|
+
* The bashExecutionToText format always starts with "Ran `".
|
|
36
|
+
*/
|
|
37
|
+
function isBashResultUserMessage(m) {
|
|
38
|
+
if (m.role !== "user" || !Array.isArray(m.content))
|
|
39
|
+
return false;
|
|
40
|
+
const first = m.content[0];
|
|
41
|
+
return first && typeof first === "object" && "text" in first &&
|
|
42
|
+
typeof first.text === "string" && first.text.startsWith("Ran `");
|
|
43
|
+
}
|
|
44
|
+
function isMaskableMessage(m) {
|
|
45
|
+
// Tool result messages (role: "toolResult" in pi-ai format)
|
|
46
|
+
if (m.role === "toolResult")
|
|
47
|
+
return true;
|
|
48
|
+
// Bash-result user messages (converted from bashExecution by convertToLlm)
|
|
49
|
+
if (isBashResultUserMessage(m))
|
|
50
|
+
return true;
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
export function createObservationMask(keepRecentTurns = 8) {
|
|
54
|
+
return (messages) => {
|
|
55
|
+
const boundary = findTurnBoundary(messages, keepRecentTurns);
|
|
56
|
+
if (boundary === 0)
|
|
57
|
+
return messages;
|
|
58
|
+
return messages.map((m, i) => {
|
|
59
|
+
if (i >= boundary)
|
|
60
|
+
return m;
|
|
61
|
+
if (isMaskableMessage(m)) {
|
|
62
|
+
// Content may be string or array of content blocks — always replace with array
|
|
63
|
+
return { ...m, content: MASK_CONTENT_BLOCK };
|
|
64
|
+
}
|
|
65
|
+
return m;
|
|
66
|
+
});
|
|
67
|
+
};
|
|
68
|
+
}
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
* - content-heuristic logs the specific failure (missing file, below minSize, pattern mismatch).
|
|
17
17
|
* - The frozen DEFINITION.yaml on disk is the single source of truth for step policies.
|
|
18
18
|
*/
|
|
19
|
+
import { logWarning } from "./workflow-logger.js";
|
|
19
20
|
import { readFileSync, existsSync, statSync } from "node:fs";
|
|
20
21
|
import { resolve, sep } from "node:path";
|
|
21
22
|
import { spawnSync } from "node:child_process";
|
|
@@ -105,8 +106,8 @@ function handleContentHeuristic(runDir, step, verify) {
|
|
|
105
106
|
return "pause";
|
|
106
107
|
}
|
|
107
108
|
}
|
|
108
|
-
catch {
|
|
109
|
-
|
|
109
|
+
catch (e) {
|
|
110
|
+
logWarning("engine", `content-heuristic regex failed: ${e.message}`);
|
|
110
111
|
return "pause";
|
|
111
112
|
}
|
|
112
113
|
}
|
|
@@ -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
|
|
|
@@ -8,7 +8,7 @@ import { createRequire } from "node:module";
|
|
|
8
8
|
import { existsSync, copyFileSync, mkdirSync, realpathSync } from "node:fs";
|
|
9
9
|
import { dirname } from "node:path";
|
|
10
10
|
import { GSDError, GSD_STALE_STATE } from "./errors.js";
|
|
11
|
-
import { logError } from "./workflow-logger.js";
|
|
11
|
+
import { logError, logWarning } from "./workflow-logger.js";
|
|
12
12
|
const _require = createRequire(import.meta.url);
|
|
13
13
|
let providerName = null;
|
|
14
14
|
let providerModule = null;
|
|
@@ -710,7 +710,9 @@ export function openDatabase(path) {
|
|
|
710
710
|
try {
|
|
711
711
|
adapter.close();
|
|
712
712
|
}
|
|
713
|
-
catch {
|
|
713
|
+
catch (e) {
|
|
714
|
+
logWarning("db", `close after VACUUM failed: ${e.message}`);
|
|
715
|
+
}
|
|
714
716
|
throw retryErr;
|
|
715
717
|
}
|
|
716
718
|
}
|
|
@@ -718,7 +720,9 @@ export function openDatabase(path) {
|
|
|
718
720
|
try {
|
|
719
721
|
adapter.close();
|
|
720
722
|
}
|
|
721
|
-
catch {
|
|
723
|
+
catch (e) {
|
|
724
|
+
logWarning("db", `close after VACUUM failed: ${e.message}`);
|
|
725
|
+
}
|
|
722
726
|
throw err;
|
|
723
727
|
}
|
|
724
728
|
}
|
|
@@ -730,7 +734,9 @@ export function openDatabase(path) {
|
|
|
730
734
|
process.on("exit", () => { try {
|
|
731
735
|
closeDatabase();
|
|
732
736
|
}
|
|
733
|
-
catch {
|
|
737
|
+
catch (e) {
|
|
738
|
+
logWarning("db", `exit handler close failed: ${e.message}`);
|
|
739
|
+
} });
|
|
734
740
|
}
|
|
735
741
|
return true;
|
|
736
742
|
}
|
|
@@ -739,17 +745,21 @@ export function closeDatabase() {
|
|
|
739
745
|
try {
|
|
740
746
|
currentDb.exec('PRAGMA wal_checkpoint(TRUNCATE)');
|
|
741
747
|
}
|
|
742
|
-
catch {
|
|
748
|
+
catch (e) {
|
|
749
|
+
logWarning("db", `WAL checkpoint failed: ${e.message}`);
|
|
750
|
+
}
|
|
743
751
|
try {
|
|
744
752
|
// Incremental vacuum to reclaim space without blocking
|
|
745
753
|
currentDb.exec('PRAGMA incremental_vacuum(64)');
|
|
746
754
|
}
|
|
747
|
-
catch {
|
|
755
|
+
catch (e) {
|
|
756
|
+
logWarning("db", `incremental vacuum failed: ${e.message}`);
|
|
757
|
+
}
|
|
748
758
|
try {
|
|
749
759
|
currentDb.close();
|
|
750
760
|
}
|
|
751
|
-
catch {
|
|
752
|
-
|
|
761
|
+
catch (e) {
|
|
762
|
+
logWarning("db", `database close failed: ${e.message}`);
|
|
753
763
|
}
|
|
754
764
|
currentDb = null;
|
|
755
765
|
currentPath = null;
|
|
@@ -763,7 +773,9 @@ export function vacuumDatabase() {
|
|
|
763
773
|
try {
|
|
764
774
|
currentDb.exec('VACUUM');
|
|
765
775
|
}
|
|
766
|
-
catch {
|
|
776
|
+
catch (e) {
|
|
777
|
+
logWarning("db", `VACUUM failed: ${e.message}`);
|
|
778
|
+
}
|
|
767
779
|
}
|
|
768
780
|
let _txDepth = 0;
|
|
769
781
|
export function transaction(fn) {
|
|
@@ -961,7 +973,9 @@ export function clearArtifacts() {
|
|
|
961
973
|
try {
|
|
962
974
|
currentDb.exec("DELETE FROM artifacts");
|
|
963
975
|
}
|
|
964
|
-
catch {
|
|
976
|
+
catch (e) {
|
|
977
|
+
logWarning("db", `clearArtifacts failed: ${e.message}`);
|
|
978
|
+
}
|
|
965
979
|
}
|
|
966
980
|
export function insertArtifact(a) {
|
|
967
981
|
if (!currentDb)
|
|
@@ -1374,11 +1388,11 @@ export function getActiveSliceFromDb(milestoneId) {
|
|
|
1374
1388
|
// Uses json_each() to expand the JSON depends array and checks each dep is complete.
|
|
1375
1389
|
const row = currentDb.prepare(`SELECT s.* FROM slices s
|
|
1376
1390
|
WHERE s.milestone_id = :mid
|
|
1377
|
-
AND s.status NOT IN ('complete', 'done')
|
|
1391
|
+
AND s.status NOT IN ('complete', 'done', 'skipped')
|
|
1378
1392
|
AND NOT EXISTS (
|
|
1379
1393
|
SELECT 1 FROM json_each(s.depends) AS dep
|
|
1380
1394
|
WHERE dep.value NOT IN (
|
|
1381
|
-
SELECT id FROM slices WHERE milestone_id = :mid AND status IN ('complete', 'done')
|
|
1395
|
+
SELECT id FROM slices WHERE milestone_id = :mid AND status IN ('complete', 'done', 'skipped')
|
|
1382
1396
|
)
|
|
1383
1397
|
)
|
|
1384
1398
|
ORDER BY s.sequence, s.id
|
|
@@ -1488,7 +1502,9 @@ export function reconcileWorktreeDb(mainDbPath, worktreeDbPath) {
|
|
|
1488
1502
|
if (realpathSync(mainDbPath) === realpathSync(worktreeDbPath))
|
|
1489
1503
|
return zero;
|
|
1490
1504
|
}
|
|
1491
|
-
catch {
|
|
1505
|
+
catch (e) {
|
|
1506
|
+
logWarning("db", `realpathSync failed: ${e.message}`);
|
|
1507
|
+
}
|
|
1492
1508
|
// Sanitize path: reject any characters that could break ATTACH syntax.
|
|
1493
1509
|
// ATTACH DATABASE doesn't support parameterized paths in all providers,
|
|
1494
1510
|
// so we use strict allowlist validation instead.
|
|
@@ -1610,7 +1626,9 @@ export function reconcileWorktreeDb(mainDbPath, worktreeDbPath) {
|
|
|
1610
1626
|
try {
|
|
1611
1627
|
adapter.exec("ROLLBACK");
|
|
1612
1628
|
}
|
|
1613
|
-
catch {
|
|
1629
|
+
catch (e) {
|
|
1630
|
+
logWarning("db", `rollback failed: ${e.message}`);
|
|
1631
|
+
}
|
|
1614
1632
|
throw txErr;
|
|
1615
1633
|
}
|
|
1616
1634
|
return { ...merged, conflicts };
|
|
@@ -1619,7 +1637,9 @@ export function reconcileWorktreeDb(mainDbPath, worktreeDbPath) {
|
|
|
1619
1637
|
try {
|
|
1620
1638
|
adapter.exec("DETACH DATABASE wt");
|
|
1621
1639
|
}
|
|
1622
|
-
catch {
|
|
1640
|
+
catch (e) {
|
|
1641
|
+
logWarning("db", `detach worktree DB failed: ${e.message}`);
|
|
1642
|
+
}
|
|
1623
1643
|
}
|
|
1624
1644
|
}
|
|
1625
1645
|
catch (err) {
|
|
@@ -37,6 +37,7 @@ import { selectAndApplyModel } from "./auto-model-selection.js";
|
|
|
37
37
|
export { MILESTONE_ID_RE, generateMilestoneSuffix, nextMilestoneId, extractMilestoneSeq, parseMilestoneId, milestoneIdSort, maxMilestoneNum, findMilestoneIds, reserveMilestoneId, claimReservedId, getReservedMilestoneIds, clearReservedMilestoneIds, } from "./milestone-ids.js";
|
|
38
38
|
export { showQueue, handleQueueReorder, showQueueAdd, buildExistingMilestonesContext, } from "./guided-flow-queue.js";
|
|
39
39
|
import { getErrorMessage } from "./error-utils.js";
|
|
40
|
+
import { logWarning } from "./workflow-logger.js";
|
|
40
41
|
// ─── ID Generation with Reservation ─────────────────────────────────────────
|
|
41
42
|
/**
|
|
42
43
|
* Generate the next milestone ID, accounting for reserved IDs, and reserve it.
|
|
@@ -144,7 +145,9 @@ export function checkAutoStartAfterDiscuss() {
|
|
|
144
145
|
}
|
|
145
146
|
}
|
|
146
147
|
}
|
|
147
|
-
catch {
|
|
148
|
+
catch (e) {
|
|
149
|
+
logWarning("guided", `PROJECT.md parsing failed: ${e.message}`);
|
|
150
|
+
}
|
|
148
151
|
}
|
|
149
152
|
// Gate 4: Discussion manifest process verification (multi-milestone only)
|
|
150
153
|
// The LLM writes DISCUSSION-MANIFEST.json after each Phase 3 gate decision.
|
|
@@ -171,7 +174,9 @@ export function checkAutoStartAfterDiscuss() {
|
|
|
171
174
|
}
|
|
172
175
|
}
|
|
173
176
|
}
|
|
174
|
-
catch {
|
|
177
|
+
catch (e) {
|
|
178
|
+
logWarning("guided", `discussion manifest verification failed: ${e.message}`);
|
|
179
|
+
}
|
|
175
180
|
}
|
|
176
181
|
// Draft promotion cleanup: if a CONTEXT-DRAFT.md exists alongside the new
|
|
177
182
|
// CONTEXT.md, delete the draft — it's been consumed by the discussion.
|
|
@@ -180,18 +185,21 @@ export function checkAutoStartAfterDiscuss() {
|
|
|
180
185
|
if (draftFile)
|
|
181
186
|
unlinkSync(draftFile);
|
|
182
187
|
}
|
|
183
|
-
catch {
|
|
188
|
+
catch (e) {
|
|
189
|
+
logWarning("guided", `CONTEXT-DRAFT.md unlink failed: ${e.message}`);
|
|
190
|
+
}
|
|
184
191
|
// Cleanup: remove discussion manifest after auto-start (only needed during discussion)
|
|
185
192
|
try {
|
|
186
193
|
unlinkSync(manifestPath);
|
|
187
194
|
}
|
|
188
|
-
catch {
|
|
195
|
+
catch (e) {
|
|
196
|
+
logWarning("guided", `manifest unlink failed: ${e.message}`);
|
|
197
|
+
}
|
|
189
198
|
pendingAutoStartMap.delete(basePath);
|
|
190
199
|
ctx.ui.notify(`Milestone ${milestoneId} ready.`, "info");
|
|
191
200
|
startAuto(ctx, pi, basePath, false, { step }).catch((err) => {
|
|
192
201
|
ctx.ui.notify(`Auto-start failed: ${getErrorMessage(err)}`, "error");
|
|
193
|
-
|
|
194
|
-
console.error('[gsd] auto start error:', err);
|
|
202
|
+
logWarning("guided", `auto start error: ${getErrorMessage(err)}`);
|
|
195
203
|
debugLog("auto-start-failed", { error: getErrorMessage(err) });
|
|
196
204
|
});
|
|
197
205
|
return true;
|
|
@@ -744,8 +752,8 @@ function selfHealRuntimeRecords(basePath, ctx) {
|
|
|
744
752
|
}
|
|
745
753
|
return { cleared };
|
|
746
754
|
}
|
|
747
|
-
catch {
|
|
748
|
-
|
|
755
|
+
catch (e) {
|
|
756
|
+
logWarning("guided", `self-heal stale runtime records failed: ${e.message}`);
|
|
749
757
|
return { cleared: 0 };
|
|
750
758
|
}
|
|
751
759
|
}
|
|
@@ -952,7 +960,9 @@ export async function showSmartEntry(ctx, pi, basePath, options) {
|
|
|
952
960
|
return;
|
|
953
961
|
}
|
|
954
962
|
}
|
|
955
|
-
catch {
|
|
963
|
+
catch (e) {
|
|
964
|
+
logWarning("guided", `directory read failed: ${e.message}`);
|
|
965
|
+
}
|
|
956
966
|
}
|
|
957
967
|
}
|
|
958
968
|
const uniqueMilestoneIds = !!loadEffectiveGSDPreferences()?.preferences?.unique_milestone_ids;
|
|
@@ -13,6 +13,7 @@ import { ensureGitignore, untrackRuntimeFiles } from "./gitignore.js";
|
|
|
13
13
|
import { gsdRoot } from "./paths.js";
|
|
14
14
|
import { assertSafeDirectory } from "./validate-directory.js";
|
|
15
15
|
import { runSkillInstallStep } from "./skill-catalog.js";
|
|
16
|
+
import { generateCodebaseMap, writeCodebaseMap } from "./codebase-generator.js";
|
|
16
17
|
// ─── Defaults ───────────────────────────────────────────────────────────────────
|
|
17
18
|
const DEFAULT_PREFS = {
|
|
18
19
|
mode: "solo",
|
|
@@ -189,6 +190,17 @@ export async function showProjectInit(ctx, pi, basePath, detection) {
|
|
|
189
190
|
// Ensure .gitignore
|
|
190
191
|
ensureGitignore(basePath);
|
|
191
192
|
untrackRuntimeFiles(basePath);
|
|
193
|
+
// Auto-generate codebase map for instant agent orientation
|
|
194
|
+
try {
|
|
195
|
+
const result = generateCodebaseMap(basePath);
|
|
196
|
+
if (result.fileCount > 0) {
|
|
197
|
+
writeCodebaseMap(basePath, result.content);
|
|
198
|
+
ctx.ui.notify(`Codebase map generated: ${result.fileCount} files`, "info");
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
catch {
|
|
202
|
+
// Non-fatal — codebase map generation failure should never block project init
|
|
203
|
+
}
|
|
192
204
|
ctx.ui.notify("GSD initialized. Starting your first milestone...", "info");
|
|
193
205
|
return { completed: true, bootstrapped: true };
|
|
194
206
|
}
|