gsd-pi 2.44.0 → 2.45.0-dev.e0ee972
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/README.md +30 -12
- package/dist/help-text.js +1 -1
- package/dist/loader.js +34 -0
- package/dist/resources/extensions/gsd/activity-log.js +7 -0
- package/dist/resources/extensions/gsd/auto/infra-errors.js +3 -0
- package/dist/resources/extensions/gsd/auto/phases.js +52 -45
- package/dist/resources/extensions/gsd/auto/run-unit.js +6 -3
- package/dist/resources/extensions/gsd/auto-prompts.js +24 -1
- package/dist/resources/extensions/gsd/auto-start.js +31 -2
- package/dist/resources/extensions/gsd/auto-timers.js +57 -3
- package/dist/resources/extensions/gsd/auto-worktree-sync.js +4 -0
- package/dist/resources/extensions/gsd/auto-worktree.js +14 -10
- package/dist/resources/extensions/gsd/auto.js +34 -8
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +168 -11
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +46 -12
- package/dist/resources/extensions/gsd/commands/catalog.js +7 -1
- package/dist/resources/extensions/gsd/commands/handlers/core.js +2 -0
- package/dist/resources/extensions/gsd/commands/handlers/ops.js +10 -0
- package/dist/resources/extensions/gsd/commands/handlers/workflow.js +5 -0
- package/dist/resources/extensions/gsd/commands-mcp-status.js +187 -0
- package/dist/resources/extensions/gsd/db-writer.js +40 -22
- package/dist/resources/extensions/gsd/doctor-checks.js +1 -1
- package/dist/resources/extensions/gsd/doctor.js +10 -2
- package/dist/resources/extensions/gsd/git-service.js +8 -3
- package/dist/resources/extensions/gsd/gsd-db.js +17 -2
- package/dist/resources/extensions/gsd/markdown-renderer.js +1 -1
- package/dist/resources/extensions/gsd/preferences-types.js +2 -2
- package/dist/resources/extensions/gsd/preferences.js +17 -5
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +2 -4
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +6 -6
- package/dist/resources/extensions/gsd/prompts/replan-slice.md +3 -14
- package/dist/resources/extensions/gsd/prompts/rethink.md +78 -0
- package/dist/resources/extensions/gsd/prompts/validate-milestone.md +7 -37
- package/dist/resources/extensions/gsd/provider-error-pause.js +7 -0
- package/dist/resources/extensions/gsd/repo-identity.js +45 -7
- package/dist/resources/extensions/gsd/rethink.js +115 -0
- package/dist/resources/extensions/gsd/state.js +41 -3
- package/dist/resources/extensions/gsd/tools/plan-slice.js +1 -0
- package/dist/resources/extensions/gsd/tools/plan-task.js +1 -0
- package/dist/resources/extensions/gsd/tools/replan-slice.js +2 -0
- package/dist/resources/extensions/gsd/tools/validate-milestone.js +88 -0
- package/dist/resources/extensions/gsd/workflow-logger.js +138 -0
- package/dist/resources/extensions/gsd/worktree-manager.js +34 -3
- package/dist/resources/extensions/gsd/worktree-resolver.js +43 -0
- package/dist/resources/extensions/mcp-client/index.js +14 -0
- package/dist/resources/extensions/voice/index.js +11 -16
- package/dist/resources/extensions/voice/linux-ready.js +67 -0
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +15 -15
- package/dist/web/standalone/.next/build-manifest.json +4 -4
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/react-loadable-manifest.json +2 -2
- 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 +5 -5
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +5 -5
- 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 +4 -4
- 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 +2 -2
- 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/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 +5 -5
- 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 +6 -6
- 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 +6 -6
- 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 +4 -4
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- 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 +15 -15
- package/dist/web/standalone/.next/server/chunks/229.js +1 -1
- package/dist/web/standalone/.next/server/chunks/471.js +3 -3
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-react-loadable-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/4024.11ca5c01938e5948.js +9 -0
- package/dist/web/standalone/.next/static/chunks/{3721.bf31263de6d5fa46.js → 485.243af25f0cdf50d6.js} +2 -2
- 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-6654a8cca61a3d1c.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/.next/static/chunks/webpack-0a4cd455ec4197d2.js +1 -0
- package/dist/web/standalone/.next/static/css/dd4ae3f58ac9b600.css +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/native/dist/stream-process/index.js +2 -2
- package/packages/native/src/__tests__/stream-process.test.mjs +34 -0
- package/packages/native/src/stream-process/index.ts +2 -2
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +3 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.js +15 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.test.js +6 -8
- package/packages/pi-coding-agent/dist/core/auth-storage.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js +2 -0
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +24 -26
- package/packages/pi-coding-agent/dist/core/extensions/runner.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +2 -1
- 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/fs-utils.test.js +29 -48
- package/packages/pi-coding-agent/dist/core/fs-utils.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/lifecycle-hooks.d.ts +4 -0
- package/packages/pi-coding-agent/dist/core/lifecycle-hooks.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/lifecycle-hooks.js +10 -5
- package/packages/pi-coding-agent/dist/core/lifecycle-hooks.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/lifecycle-hooks.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/lifecycle-hooks.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/lifecycle-hooks.test.js +185 -0
- package/packages/pi-coding-agent/dist/core/lifecycle-hooks.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/local-model-check.d.ts +15 -0
- package/packages/pi-coding-agent/dist/core/local-model-check.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/local-model-check.js +41 -0
- package/packages/pi-coding-agent/dist/core/local-model-check.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +239 -10
- package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.d.ts +13 -1
- package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.js +40 -3
- package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/package-commands.test.js +206 -195
- package/packages/pi-coding-agent/dist/core/package-commands.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js +34 -44
- package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/session-manager.test.js +30 -34
- package/packages/pi-coding-agent/dist/core/session-manager.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +3 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.js +6 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js +10 -12
- package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/main.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/main.js +17 -0
- package/packages/pi-coding-agent/dist/main.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.js +32 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts +3 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js +8 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js +12 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.d.ts +15 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.js +40 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +4 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts +5 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js +13 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +17 -8
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- 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 +7 -3
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js +43 -47
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js.map +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/auth-storage.test.ts +7 -7
- package/packages/pi-coding-agent/src/core/auth-storage.ts +15 -1
- package/packages/pi-coding-agent/src/core/compaction-orchestrator.ts +2 -0
- package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +26 -26
- package/packages/pi-coding-agent/src/core/extensions/types.ts +2 -1
- package/packages/pi-coding-agent/src/core/fs-utils.test.ts +31 -43
- package/packages/pi-coding-agent/src/core/lifecycle-hooks.test.ts +227 -0
- package/packages/pi-coding-agent/src/core/lifecycle-hooks.ts +11 -5
- package/packages/pi-coding-agent/src/core/local-model-check.ts +45 -0
- package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +297 -11
- package/packages/pi-coding-agent/src/core/model-registry.ts +51 -4
- package/packages/pi-coding-agent/src/core/package-commands.test.ts +227 -205
- package/packages/pi-coding-agent/src/core/resolve-config-value.test.ts +40 -45
- package/packages/pi-coding-agent/src/core/session-manager.test.ts +33 -33
- package/packages/pi-coding-agent/src/core/settings-manager.ts +9 -0
- package/packages/pi-coding-agent/src/core/tools/edit-diff.test.ts +17 -17
- package/packages/pi-coding-agent/src/main.ts +19 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/timestamp.test.ts +38 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +10 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/settings-selector.ts +15 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/timestamp.ts +48 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +3 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/user-message.ts +18 -3
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +16 -7
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +8 -1
- package/packages/pi-coding-agent/src/resources/extensions/memory/storage.test.ts +74 -74
- package/pkg/package.json +1 -1
- package/src/resources/extensions/gsd/activity-log.ts +1 -0
- package/src/resources/extensions/gsd/auto/infra-errors.ts +3 -0
- package/src/resources/extensions/gsd/auto/phases.ts +61 -59
- package/src/resources/extensions/gsd/auto/run-unit.ts +6 -3
- package/src/resources/extensions/gsd/auto-prompts.ts +24 -1
- package/src/resources/extensions/gsd/auto-start.ts +39 -2
- package/src/resources/extensions/gsd/auto-timers.ts +64 -3
- package/src/resources/extensions/gsd/auto-worktree-sync.ts +5 -0
- package/src/resources/extensions/gsd/auto-worktree.ts +17 -11
- package/src/resources/extensions/gsd/auto.ts +40 -6
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +160 -11
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +48 -11
- package/src/resources/extensions/gsd/commands/catalog.ts +7 -1
- package/src/resources/extensions/gsd/commands/handlers/core.ts +2 -0
- package/src/resources/extensions/gsd/commands/handlers/ops.ts +10 -0
- package/src/resources/extensions/gsd/commands/handlers/workflow.ts +8 -0
- package/src/resources/extensions/gsd/commands-mcp-status.ts +247 -0
- package/src/resources/extensions/gsd/db-writer.ts +41 -27
- package/src/resources/extensions/gsd/doctor-checks.ts +1 -1
- package/src/resources/extensions/gsd/doctor.ts +9 -3
- package/src/resources/extensions/gsd/git-service.ts +6 -2
- package/src/resources/extensions/gsd/gsd-db.ts +21 -2
- package/src/resources/extensions/gsd/journal.ts +6 -1
- package/src/resources/extensions/gsd/markdown-renderer.ts +1 -1
- package/src/resources/extensions/gsd/preferences-types.ts +2 -2
- package/src/resources/extensions/gsd/preferences.ts +18 -4
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +2 -4
- package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/reassess-roadmap.md +6 -6
- package/src/resources/extensions/gsd/prompts/replan-slice.md +3 -14
- package/src/resources/extensions/gsd/prompts/rethink.md +78 -0
- package/src/resources/extensions/gsd/prompts/validate-milestone.md +7 -37
- package/src/resources/extensions/gsd/provider-error-pause.ts +9 -0
- package/src/resources/extensions/gsd/repo-identity.ts +46 -7
- package/src/resources/extensions/gsd/rethink.ts +154 -0
- package/src/resources/extensions/gsd/state.ts +41 -1
- package/src/resources/extensions/gsd/tests/all-milestones-complete-merge.test.ts +99 -99
- package/src/resources/extensions/gsd/tests/auto-lock-creation.test.ts +14 -16
- package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +43 -57
- package/src/resources/extensions/gsd/tests/auto-pr-bugs.test.ts +88 -0
- package/src/resources/extensions/gsd/tests/auto-preflight.test.ts +11 -13
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +465 -523
- package/src/resources/extensions/gsd/tests/auto-secrets-gate.test.ts +73 -75
- package/src/resources/extensions/gsd/tests/auto-start-needs-discussion.test.ts +34 -56
- package/src/resources/extensions/gsd/tests/auto-worktree-milestone-merge.test.ts +533 -656
- package/src/resources/extensions/gsd/tests/auto-worktree.test.ts +165 -143
- package/src/resources/extensions/gsd/tests/cache-staleness-regression.test.ts +29 -52
- package/src/resources/extensions/gsd/tests/captures.test.ts +148 -176
- package/src/resources/extensions/gsd/tests/claude-import-tui.test.ts +32 -33
- package/src/resources/extensions/gsd/tests/collect-from-manifest.test.ts +141 -143
- package/src/resources/extensions/gsd/tests/commands-inspect-open-db.test.ts +25 -25
- package/src/resources/extensions/gsd/tests/commands-logs.test.ts +81 -81
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +38 -59
- package/src/resources/extensions/gsd/tests/complete-slice.test.ts +228 -263
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +250 -302
- package/src/resources/extensions/gsd/tests/completed-units-metrics-sync.test.ts +114 -0
- package/src/resources/extensions/gsd/tests/context-store.test.ts +354 -367
- package/src/resources/extensions/gsd/tests/continue-here.test.ts +68 -72
- package/src/resources/extensions/gsd/tests/cost-projection.test.ts +92 -106
- package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +27 -35
- package/src/resources/extensions/gsd/tests/dashboard-budget.test.ts +220 -237
- package/src/resources/extensions/gsd/tests/db-writer.test.ts +465 -416
- package/src/resources/extensions/gsd/tests/definition-loader.test.ts +76 -92
- package/src/resources/extensions/gsd/tests/derive-state-crossval.test.ts +68 -83
- package/src/resources/extensions/gsd/tests/derive-state-db-disk-reconcile.test.ts +121 -0
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +210 -181
- package/src/resources/extensions/gsd/tests/derive-state-deps.test.ts +78 -101
- package/src/resources/extensions/gsd/tests/derive-state.test.ts +192 -227
- package/src/resources/extensions/gsd/tests/detection.test.ts +232 -278
- package/src/resources/extensions/gsd/tests/dev-engine-wrapper.test.ts +30 -34
- package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +164 -180
- package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +43 -49
- package/src/resources/extensions/gsd/tests/dispatch-uat-last-completed.test.ts +28 -32
- package/src/resources/extensions/gsd/tests/doctor-completion-deferral.test.ts +27 -29
- package/src/resources/extensions/gsd/tests/doctor-delimiter-fix.test.ts +34 -38
- package/src/resources/extensions/gsd/tests/doctor-enhancements.test.ts +54 -75
- package/src/resources/extensions/gsd/tests/doctor-environment-worktree.test.ts +21 -32
- package/src/resources/extensions/gsd/tests/doctor-environment.test.ts +72 -97
- package/src/resources/extensions/gsd/tests/doctor-fixlevel.test.ts +38 -44
- package/src/resources/extensions/gsd/tests/doctor-git.test.ts +104 -145
- package/src/resources/extensions/gsd/tests/doctor-proactive.test.ts +84 -106
- package/src/resources/extensions/gsd/tests/doctor-roadmap-summary-atomicity.test.ts +54 -60
- package/src/resources/extensions/gsd/tests/doctor-runtime.test.ts +72 -93
- package/src/resources/extensions/gsd/tests/doctor.test.ts +104 -134
- package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +123 -131
- package/src/resources/extensions/gsd/tests/est-annotation-timeout.test.ts +120 -0
- package/src/resources/extensions/gsd/tests/exit-command.test.ts +20 -24
- package/src/resources/extensions/gsd/tests/feature-branch-lifecycle-integration.test.ts +48 -57
- package/src/resources/extensions/gsd/tests/files-loadfile-eisdir.test.ts +5 -7
- package/src/resources/extensions/gsd/tests/flag-file-db.test.ts +30 -42
- package/src/resources/extensions/gsd/tests/freeform-decisions.test.ts +198 -206
- package/src/resources/extensions/gsd/tests/git-locale.test.ts +13 -27
- package/src/resources/extensions/gsd/tests/git-service.test.ts +285 -388
- package/src/resources/extensions/gsd/tests/gitignore-tracked-gsd.test.ts +31 -39
- package/src/resources/extensions/gsd/tests/graph-operations.test.ts +63 -69
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +255 -264
- package/src/resources/extensions/gsd/tests/gsd-inspect.test.ts +108 -119
- package/src/resources/extensions/gsd/tests/gsd-recover.test.ts +81 -103
- package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +229 -262
- package/src/resources/extensions/gsd/tests/headless-answers.test.ts +13 -13
- package/src/resources/extensions/gsd/tests/health-widget.test.ts +29 -37
- package/src/resources/extensions/gsd/tests/idle-recovery.test.ts +81 -102
- package/src/resources/extensions/gsd/tests/infra-error.test.ts +20 -2
- package/src/resources/extensions/gsd/tests/inherited-repo-home-dir.test.ts +121 -0
- package/src/resources/extensions/gsd/tests/init-wizard.test.ts +16 -18
- package/src/resources/extensions/gsd/tests/integration-edge.test.ts +41 -46
- package/src/resources/extensions/gsd/tests/integration-lifecycle.test.ts +42 -53
- package/src/resources/extensions/gsd/tests/integration-mixed-milestones.test.ts +75 -91
- package/src/resources/extensions/gsd/tests/integration-proof.test.ts +18 -18
- package/src/resources/extensions/gsd/tests/knowledge.test.ts +89 -0
- package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +150 -194
- package/src/resources/extensions/gsd/tests/mcp-status.test.ts +103 -0
- package/src/resources/extensions/gsd/tests/md-importer.test.ts +101 -125
- package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +45 -54
- package/src/resources/extensions/gsd/tests/memory-store.test.ts +80 -93
- package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +66 -0
- package/src/resources/extensions/gsd/tests/migrate-command.test.ts +57 -66
- package/src/resources/extensions/gsd/tests/migrate-hierarchy.test.ts +83 -93
- package/src/resources/extensions/gsd/tests/migrate-parser.test.ts +161 -170
- package/src/resources/extensions/gsd/tests/migrate-transformer.test.ts +125 -141
- package/src/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +107 -131
- package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +87 -96
- package/src/resources/extensions/gsd/tests/migrate-writer.test.ts +125 -164
- package/src/resources/extensions/gsd/tests/must-have-parser.test.ts +81 -94
- package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +75 -37
- package/src/resources/extensions/gsd/tests/overrides.test.ts +99 -106
- package/src/resources/extensions/gsd/tests/parallel-crash-recovery.test.ts +40 -47
- package/src/resources/extensions/gsd/tests/parallel-worker-monitoring.test.ts +25 -28
- package/src/resources/extensions/gsd/tests/parallel-workers-multi-milestone-e2e.test.ts +66 -83
- package/src/resources/extensions/gsd/tests/park-edge-cases.test.ts +54 -77
- package/src/resources/extensions/gsd/tests/park-milestone.test.ts +68 -115
- package/src/resources/extensions/gsd/tests/parsers.test.ts +546 -611
- package/src/resources/extensions/gsd/tests/paths.test.ts +72 -87
- package/src/resources/extensions/gsd/tests/post-unit-hooks.test.ts +77 -117
- package/src/resources/extensions/gsd/tests/preferences.test.ts +34 -9
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +11 -7
- package/src/resources/extensions/gsd/tests/prompt-db.test.ts +56 -56
- package/src/resources/extensions/gsd/tests/queue-draft-detection.test.ts +93 -119
- package/src/resources/extensions/gsd/tests/queue-order.test.ts +70 -82
- package/src/resources/extensions/gsd/tests/queue-reorder-e2e.test.ts +42 -55
- package/src/resources/extensions/gsd/tests/quick-auto-guard.test.ts +100 -0
- package/src/resources/extensions/gsd/tests/quick-branch-lifecycle.test.ts +45 -73
- package/src/resources/extensions/gsd/tests/reassess-prompt.test.ts +28 -38
- package/src/resources/extensions/gsd/tests/recovery-attempts-reset.test.ts +176 -0
- package/src/resources/extensions/gsd/tests/replan-slice.test.ts +73 -80
- package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +71 -74
- package/src/resources/extensions/gsd/tests/requirements.test.ts +70 -75
- package/src/resources/extensions/gsd/tests/retry-state-reset.test.ts +44 -66
- package/src/resources/extensions/gsd/tests/roadmap-parse-regression.test.ts +114 -181
- package/src/resources/extensions/gsd/tests/rule-registry.test.ts +63 -65
- package/src/resources/extensions/gsd/tests/run-uat.test.ts +66 -128
- package/src/resources/extensions/gsd/tests/session-lock-multipath.test.ts +18 -25
- package/src/resources/extensions/gsd/tests/session-lock-regression.test.ts +37 -44
- package/src/resources/extensions/gsd/tests/shared-wal.test.ts +19 -26
- package/src/resources/extensions/gsd/tests/sqlite-unavailable-gate.test.ts +63 -0
- package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +6 -8
- package/src/resources/extensions/gsd/tests/stop-auto-merge-back.test.ts +67 -0
- package/src/resources/extensions/gsd/tests/survivor-branch-complete.test.ts +108 -0
- package/src/resources/extensions/gsd/tests/symlink-numbered-variants.test.ts +22 -28
- package/src/resources/extensions/gsd/tests/terminated-transient.test.ts +49 -0
- package/src/resources/extensions/gsd/tests/token-savings.test.ts +54 -56
- package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +23 -25
- package/src/resources/extensions/gsd/tests/tool-naming.test.ts +10 -11
- package/src/resources/extensions/gsd/tests/unique-milestone-ids.test.ts +66 -82
- package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +46 -47
- package/src/resources/extensions/gsd/tests/visualizer-critical-path.test.ts +20 -22
- package/src/resources/extensions/gsd/tests/visualizer-data.test.ts +84 -86
- package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +41 -43
- package/src/resources/extensions/gsd/tests/visualizer-views.test.ts +94 -96
- package/src/resources/extensions/gsd/tests/windows-path-normalization.test.ts +11 -13
- package/src/resources/extensions/gsd/tests/worker-registry.test.ts +27 -29
- package/src/resources/extensions/gsd/tests/workflow-logger.test.ts +275 -0
- package/src/resources/extensions/gsd/tests/workflow-templates.test.ts +50 -52
- package/src/resources/extensions/gsd/tests/worktree-bugfix.test.ts +10 -13
- package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +14 -18
- package/src/resources/extensions/gsd/tests/worktree-db.test.ts +38 -39
- package/src/resources/extensions/gsd/tests/worktree-e2e.test.ts +17 -21
- package/src/resources/extensions/gsd/tests/worktree-health.test.ts +25 -30
- package/src/resources/extensions/gsd/tests/worktree-integration.test.ts +30 -37
- package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +220 -0
- package/src/resources/extensions/gsd/tests/worktree-submodule-safety.test.ts +65 -0
- package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +15 -22
- package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +59 -66
- package/src/resources/extensions/gsd/tests/worktree.test.ts +44 -50
- package/src/resources/extensions/gsd/tools/plan-slice.ts +2 -0
- package/src/resources/extensions/gsd/tools/plan-task.ts +2 -0
- package/src/resources/extensions/gsd/tools/replan-slice.ts +3 -0
- package/src/resources/extensions/gsd/tools/validate-milestone.ts +127 -0
- package/src/resources/extensions/gsd/workflow-logger.ts +193 -0
- package/src/resources/extensions/gsd/worktree-manager.ts +41 -5
- package/src/resources/extensions/gsd/worktree-resolver.ts +44 -0
- package/src/resources/extensions/mcp-client/index.ts +20 -0
- package/src/resources/extensions/voice/index.ts +11 -21
- package/src/resources/extensions/voice/linux-ready.ts +87 -0
- package/src/resources/extensions/voice/tests/linux-ready.test.ts +124 -0
- package/dist/web/standalone/.next/static/chunks/4024.0de81b543b28b9fe.js +0 -9
- package/dist/web/standalone/.next/static/chunks/app/page-7e9530a7122506c5.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/chunks/webpack-9014b5adb127a98a.js +0 -1
- package/dist/web/standalone/.next/static/css/8a727f372cf53002.css +0 -1
- /package/dist/web/standalone/.next/static/{mgkxN0mGP6gSUmGPEzbk_ → dFMji9G1LZ-Tv36el9pRT}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{mgkxN0mGP6gSUmGPEzbk_ → dFMji9G1LZ-Tv36el9pRT}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Status — `/gsd mcp` command handler.
|
|
3
|
+
*
|
|
4
|
+
* Shows configured MCP servers, their connection status, and available tools.
|
|
5
|
+
*
|
|
6
|
+
* Subcommands:
|
|
7
|
+
* /gsd mcp — Overview of all servers (alias: /gsd mcp status)
|
|
8
|
+
* /gsd mcp status — Same as bare /gsd mcp
|
|
9
|
+
* /gsd mcp check <srv> — Detailed status for a specific server
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import type { ExtensionCommandContext } from "@gsd/pi-coding-agent";
|
|
13
|
+
|
|
14
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
15
|
+
import { join } from "node:path";
|
|
16
|
+
|
|
17
|
+
// ─── Types ──────────────────────────────────────────────────────────────────
|
|
18
|
+
|
|
19
|
+
export interface McpServerStatus {
|
|
20
|
+
name: string;
|
|
21
|
+
transport: "stdio" | "http" | "unknown";
|
|
22
|
+
connected: boolean;
|
|
23
|
+
toolCount: number;
|
|
24
|
+
error: string | undefined;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface McpServerDetail extends McpServerStatus {
|
|
28
|
+
tools: string[];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// ─── Config reader (standalone — does not import mcp-client internals) ──────
|
|
32
|
+
|
|
33
|
+
interface McpServerRawConfig {
|
|
34
|
+
name: string;
|
|
35
|
+
transport: "stdio" | "http" | "unknown";
|
|
36
|
+
command?: string;
|
|
37
|
+
args?: string[];
|
|
38
|
+
url?: string;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function readMcpConfigs(): McpServerRawConfig[] {
|
|
42
|
+
const servers: McpServerRawConfig[] = [];
|
|
43
|
+
const seen = new Set<string>();
|
|
44
|
+
const configPaths = [
|
|
45
|
+
join(process.cwd(), ".mcp.json"),
|
|
46
|
+
join(process.cwd(), ".gsd", "mcp.json"),
|
|
47
|
+
];
|
|
48
|
+
|
|
49
|
+
for (const configPath of configPaths) {
|
|
50
|
+
try {
|
|
51
|
+
if (!existsSync(configPath)) continue;
|
|
52
|
+
const raw = readFileSync(configPath, "utf-8");
|
|
53
|
+
const data = JSON.parse(raw) as Record<string, unknown>;
|
|
54
|
+
const mcpServers = (data.mcpServers ?? data.servers) as
|
|
55
|
+
| Record<string, Record<string, unknown>>
|
|
56
|
+
| undefined;
|
|
57
|
+
if (!mcpServers || typeof mcpServers !== "object") continue;
|
|
58
|
+
|
|
59
|
+
for (const [name, config] of Object.entries(mcpServers)) {
|
|
60
|
+
if (seen.has(name)) continue;
|
|
61
|
+
seen.add(name);
|
|
62
|
+
|
|
63
|
+
const hasCommand = typeof config.command === "string";
|
|
64
|
+
const hasUrl = typeof config.url === "string";
|
|
65
|
+
const transport: McpServerRawConfig["transport"] = hasCommand
|
|
66
|
+
? "stdio"
|
|
67
|
+
: hasUrl
|
|
68
|
+
? "http"
|
|
69
|
+
: "unknown";
|
|
70
|
+
|
|
71
|
+
servers.push({
|
|
72
|
+
name,
|
|
73
|
+
transport,
|
|
74
|
+
...(hasCommand && {
|
|
75
|
+
command: config.command as string,
|
|
76
|
+
args: Array.isArray(config.args) ? (config.args as string[]) : undefined,
|
|
77
|
+
}),
|
|
78
|
+
...(hasUrl && { url: config.url as string }),
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
} catch {
|
|
82
|
+
// Non-fatal — config file may not exist or be malformed
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return servers;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// ─── Formatters (exported for testing) ──────────────────────────────────────
|
|
90
|
+
|
|
91
|
+
export function formatMcpStatusReport(servers: McpServerStatus[]): string {
|
|
92
|
+
if (servers.length === 0) {
|
|
93
|
+
return [
|
|
94
|
+
"No MCP servers configured.",
|
|
95
|
+
"",
|
|
96
|
+
"Add servers to .mcp.json or .gsd/mcp.json to enable MCP integrations.",
|
|
97
|
+
"See: https://modelcontextprotocol.io/quickstart",
|
|
98
|
+
].join("\n");
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const lines: string[] = [`MCP Server Status — ${servers.length} server(s)\n`];
|
|
102
|
+
|
|
103
|
+
for (const s of servers) {
|
|
104
|
+
const icon = s.error ? "✗" : s.connected ? "✓" : "○";
|
|
105
|
+
const status = s.error
|
|
106
|
+
? `error: ${s.error}`
|
|
107
|
+
: s.connected
|
|
108
|
+
? `connected — ${s.toolCount} tools`
|
|
109
|
+
: "disconnected";
|
|
110
|
+
lines.push(` ${icon} ${s.name} (${s.transport}) — ${status}`);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
lines.push("");
|
|
114
|
+
lines.push("Use /gsd mcp check <server> for details on a specific server.");
|
|
115
|
+
lines.push("Use mcp_discover to connect and list tools for a server.");
|
|
116
|
+
|
|
117
|
+
return lines.join("\n");
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export function formatMcpServerDetail(server: McpServerDetail): string {
|
|
121
|
+
const lines: string[] = [`MCP Server: ${server.name}\n`];
|
|
122
|
+
|
|
123
|
+
lines.push(` Transport: ${server.transport}`);
|
|
124
|
+
|
|
125
|
+
if (server.error) {
|
|
126
|
+
lines.push(` Status: error`);
|
|
127
|
+
lines.push(` Error: ${server.error}`);
|
|
128
|
+
} else if (server.connected) {
|
|
129
|
+
lines.push(` Status: connected`);
|
|
130
|
+
lines.push(` Tools: ${server.toolCount}`);
|
|
131
|
+
if (server.tools.length > 0) {
|
|
132
|
+
lines.push("");
|
|
133
|
+
lines.push(" Available tools:");
|
|
134
|
+
for (const tool of server.tools) {
|
|
135
|
+
lines.push(` - ${tool}`);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
} else {
|
|
139
|
+
lines.push(` Status: disconnected`);
|
|
140
|
+
lines.push("");
|
|
141
|
+
lines.push(` Run mcp_discover("${server.name}") to connect and list tools.`);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
return lines.join("\n");
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// ─── Command handler ────────────────────────────────────────────────────────
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Handle `/gsd mcp [status|check <server>]`.
|
|
151
|
+
*/
|
|
152
|
+
export async function handleMcpStatus(
|
|
153
|
+
args: string,
|
|
154
|
+
ctx: ExtensionCommandContext,
|
|
155
|
+
): Promise<void> {
|
|
156
|
+
const trimmed = args.trim().toLowerCase();
|
|
157
|
+
const configs = readMcpConfigs();
|
|
158
|
+
|
|
159
|
+
// /gsd mcp check <server>
|
|
160
|
+
if (trimmed.startsWith("check ")) {
|
|
161
|
+
const serverName = args.trim().slice("check ".length).trim();
|
|
162
|
+
const config = configs.find((c) => c.name === serverName);
|
|
163
|
+
if (!config) {
|
|
164
|
+
const available = configs.map((c) => c.name).join(", ") || "(none)";
|
|
165
|
+
ctx.ui.notify(
|
|
166
|
+
`Unknown MCP server: "${serverName}"\n\nAvailable: ${available}`,
|
|
167
|
+
"warning",
|
|
168
|
+
);
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Try to get connection/tool info from the mcp-client module if available
|
|
173
|
+
let connected = false;
|
|
174
|
+
let toolNames: string[] = [];
|
|
175
|
+
let error: string | undefined;
|
|
176
|
+
try {
|
|
177
|
+
const mcpClient = await import("../mcp-client/index.js");
|
|
178
|
+
// Access the module's connection state if exported; fall back gracefully
|
|
179
|
+
const mod = mcpClient as Record<string, unknown>;
|
|
180
|
+
if (typeof mod.getConnectionStatus === "function") {
|
|
181
|
+
const status = (mod.getConnectionStatus as (name: string) => { connected: boolean; tools: string[]; error?: string })(serverName);
|
|
182
|
+
connected = status.connected;
|
|
183
|
+
toolNames = status.tools;
|
|
184
|
+
error = status.error;
|
|
185
|
+
}
|
|
186
|
+
} catch {
|
|
187
|
+
// mcp-client may not expose status helpers — that's fine
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
ctx.ui.notify(
|
|
191
|
+
formatMcpServerDetail({
|
|
192
|
+
name: config.name,
|
|
193
|
+
transport: config.transport,
|
|
194
|
+
connected,
|
|
195
|
+
toolCount: toolNames.length,
|
|
196
|
+
tools: toolNames,
|
|
197
|
+
error,
|
|
198
|
+
}),
|
|
199
|
+
"info",
|
|
200
|
+
);
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// /gsd mcp or /gsd mcp status
|
|
205
|
+
if (!trimmed || trimmed === "status") {
|
|
206
|
+
// Build status for each server
|
|
207
|
+
const statuses: McpServerStatus[] = [];
|
|
208
|
+
|
|
209
|
+
for (const config of configs) {
|
|
210
|
+
let connected = false;
|
|
211
|
+
let toolCount = 0;
|
|
212
|
+
let error: string | undefined;
|
|
213
|
+
|
|
214
|
+
try {
|
|
215
|
+
const mcpClient = await import("../mcp-client/index.js");
|
|
216
|
+
const mod = mcpClient as Record<string, unknown>;
|
|
217
|
+
if (typeof mod.getConnectionStatus === "function") {
|
|
218
|
+
const status = (mod.getConnectionStatus as (name: string) => { connected: boolean; tools: string[]; error?: string })(config.name);
|
|
219
|
+
connected = status.connected;
|
|
220
|
+
toolCount = status.tools.length;
|
|
221
|
+
error = status.error;
|
|
222
|
+
}
|
|
223
|
+
} catch {
|
|
224
|
+
// Fall back to unknown state
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
statuses.push({
|
|
228
|
+
name: config.name,
|
|
229
|
+
transport: config.transport,
|
|
230
|
+
connected,
|
|
231
|
+
toolCount,
|
|
232
|
+
error,
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
ctx.ui.notify(formatMcpStatusReport(statuses), "info");
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// Unknown subcommand
|
|
241
|
+
ctx.ui.notify(
|
|
242
|
+
"Usage: /gsd mcp [status|check <server>]\n\n" +
|
|
243
|
+
" status Show all MCP server statuses (default)\n" +
|
|
244
|
+
" check <server> Detailed status for a specific server",
|
|
245
|
+
"warning",
|
|
246
|
+
);
|
|
247
|
+
}
|
|
@@ -9,11 +9,12 @@
|
|
|
9
9
|
// parseDecisionsTable() and parseRequirementsSections() with field fidelity.
|
|
10
10
|
|
|
11
11
|
import { join, resolve } from 'node:path';
|
|
12
|
-
import { readFileSync, existsSync } from 'node:fs';
|
|
12
|
+
import { readFileSync, existsSync, statSync } from 'node:fs';
|
|
13
13
|
import type { Decision, Requirement } from './types.js';
|
|
14
14
|
import { resolveGsdRootFile } from './paths.js';
|
|
15
15
|
import { saveFile } from './files.js';
|
|
16
16
|
import { GSDError, GSD_STALE_STATE, GSD_IO_ERROR } from './errors.js';
|
|
17
|
+
import { logWarning, logError } from './workflow-logger.js';
|
|
17
18
|
import { invalidateStateCache } from './state.js';
|
|
18
19
|
import { clearPathCache } from './paths.js';
|
|
19
20
|
import { clearParseCache } from './files.js';
|
|
@@ -221,7 +222,7 @@ export async function nextDecisionId(): Promise<string> {
|
|
|
221
222
|
const next = maxNum + 1;
|
|
222
223
|
return `D${String(next).padStart(3, '0')}`;
|
|
223
224
|
} catch (err) {
|
|
224
|
-
|
|
225
|
+
logError('manifest', 'nextDecisionId failed', { fn: 'nextDecisionId', error: String((err as Error).message) });
|
|
225
226
|
return 'D001';
|
|
226
227
|
}
|
|
227
228
|
}
|
|
@@ -311,9 +312,7 @@ export async function saveDecisionToDb(
|
|
|
311
312
|
try {
|
|
312
313
|
await saveFile(filePath, md);
|
|
313
314
|
} catch (diskErr) {
|
|
314
|
-
|
|
315
|
-
`gsd-db: saveDecisionToDb — disk write failed, rolling back DB row: ${(diskErr as Error).message}\n`,
|
|
316
|
-
);
|
|
315
|
+
logError('manifest', 'disk write failed, rolling back DB row', { fn: 'saveDecisionToDb', error: String((diskErr as Error).message) });
|
|
317
316
|
adapter?.prepare('DELETE FROM decisions WHERE id = :id').run({ ':id': id });
|
|
318
317
|
throw diskErr;
|
|
319
318
|
}
|
|
@@ -325,7 +324,7 @@ export async function saveDecisionToDb(
|
|
|
325
324
|
|
|
326
325
|
return { id };
|
|
327
326
|
} catch (err) {
|
|
328
|
-
|
|
327
|
+
logError('manifest', 'saveDecisionToDb failed', { fn: 'saveDecisionToDb', error: String((err as Error).message) });
|
|
329
328
|
throw err;
|
|
330
329
|
}
|
|
331
330
|
}
|
|
@@ -388,9 +387,7 @@ export async function updateRequirementInDb(
|
|
|
388
387
|
try {
|
|
389
388
|
await saveFile(filePath, md);
|
|
390
389
|
} catch (diskErr) {
|
|
391
|
-
|
|
392
|
-
`gsd-db: updateRequirementInDb — disk write failed, reverting DB row: ${(diskErr as Error).message}\n`,
|
|
393
|
-
);
|
|
390
|
+
logError('manifest', 'disk write failed, reverting DB row', { fn: 'updateRequirementInDb', error: String((diskErr as Error).message) });
|
|
394
391
|
db.upsertRequirement(existing);
|
|
395
392
|
throw diskErr;
|
|
396
393
|
}
|
|
@@ -400,7 +397,7 @@ export async function updateRequirementInDb(
|
|
|
400
397
|
clearPathCache();
|
|
401
398
|
clearParseCache();
|
|
402
399
|
} catch (err) {
|
|
403
|
-
|
|
400
|
+
logError('manifest', 'updateRequirementInDb failed', { fn: 'updateRequirementInDb', error: String((err as Error).message) });
|
|
404
401
|
throw err;
|
|
405
402
|
}
|
|
406
403
|
}
|
|
@@ -428,30 +425,47 @@ export async function saveArtifactToDb(
|
|
|
428
425
|
try {
|
|
429
426
|
const db = await import('./gsd-db.js');
|
|
430
427
|
|
|
428
|
+
// Guard against path traversal before any reads/writes
|
|
429
|
+
const gsdDir = resolve(basePath, '.gsd');
|
|
430
|
+
const fullPath = resolve(basePath, '.gsd', opts.path);
|
|
431
|
+
if (!fullPath.startsWith(gsdDir)) {
|
|
432
|
+
throw new GSDError(GSD_IO_ERROR, `saveArtifactToDb: path escapes .gsd/ directory: ${opts.path}`);
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
// Shrinkage guard: if the file already exists and the new content is
|
|
436
|
+
// significantly smaller (<50%), preserve the richer file on disk and
|
|
437
|
+
// store its content in the DB instead of the abbreviated version.
|
|
438
|
+
let dbContent = opts.content;
|
|
439
|
+
let skipDiskWrite = false;
|
|
440
|
+
if (existsSync(fullPath)) {
|
|
441
|
+
const existingSize = statSync(fullPath).size;
|
|
442
|
+
const newSize = Buffer.byteLength(opts.content, 'utf-8');
|
|
443
|
+
if (existingSize > 0 && newSize < existingSize * 0.5) {
|
|
444
|
+
logWarning('manifest', `new content (${newSize}B) is <50% of existing file (${existingSize}B), preserving disk file`, { fn: 'saveArtifactToDb', path: opts.path });
|
|
445
|
+
dbContent = readFileSync(fullPath, 'utf-8');
|
|
446
|
+
skipDiskWrite = true;
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
|
|
431
450
|
db.insertArtifact({
|
|
432
451
|
path: opts.path,
|
|
433
452
|
artifact_type: opts.artifact_type,
|
|
434
453
|
milestone_id: opts.milestone_id ?? null,
|
|
435
454
|
slice_id: opts.slice_id ?? null,
|
|
436
455
|
task_id: opts.task_id ?? null,
|
|
437
|
-
full_content:
|
|
456
|
+
full_content: dbContent,
|
|
438
457
|
});
|
|
439
458
|
|
|
440
|
-
// Write the file to disk (
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
`gsd-db: saveArtifactToDb — disk write failed, rolling back DB row: ${(diskErr as Error).message}\n`,
|
|
451
|
-
);
|
|
452
|
-
const rollbackAdapter = db._getAdapter();
|
|
453
|
-
rollbackAdapter?.prepare('DELETE FROM artifacts WHERE path = :path').run({ ':path': opts.path });
|
|
454
|
-
throw diskErr;
|
|
459
|
+
// Write the file to disk (only if we're not preserving a richer existing file)
|
|
460
|
+
if (!skipDiskWrite) {
|
|
461
|
+
try {
|
|
462
|
+
await saveFile(fullPath, opts.content);
|
|
463
|
+
} catch (diskErr) {
|
|
464
|
+
logError('manifest', 'disk write failed, rolling back DB row', { fn: 'saveArtifactToDb', error: String((diskErr as Error).message) });
|
|
465
|
+
const rollbackAdapter = db._getAdapter();
|
|
466
|
+
rollbackAdapter?.prepare('DELETE FROM artifacts WHERE path = :path').run({ ':path': opts.path });
|
|
467
|
+
throw diskErr;
|
|
468
|
+
}
|
|
455
469
|
}
|
|
456
470
|
// Invalidate file-read caches so deriveState() sees the updated markdown.
|
|
457
471
|
// Do NOT clear the artifacts table — we just wrote to it intentionally.
|
|
@@ -459,7 +473,7 @@ export async function saveArtifactToDb(
|
|
|
459
473
|
clearPathCache();
|
|
460
474
|
clearParseCache();
|
|
461
475
|
} catch (err) {
|
|
462
|
-
|
|
476
|
+
logError('manifest', 'saveArtifactToDb failed', { fn: 'saveArtifactToDb', error: String((err as Error).message) });
|
|
463
477
|
throw err;
|
|
464
478
|
}
|
|
465
479
|
}
|
|
@@ -25,7 +25,7 @@ export async function checkGitHealth(
|
|
|
25
25
|
issues: DoctorIssue[],
|
|
26
26
|
fixesApplied: string[],
|
|
27
27
|
shouldFix: (code: DoctorIssueCode) => boolean,
|
|
28
|
-
isolationMode: "none" | "worktree" | "branch" = "
|
|
28
|
+
isolationMode: "none" | "worktree" | "branch" = "none",
|
|
29
29
|
): Promise<void> {
|
|
30
30
|
// Degrade gracefully if not a git repo
|
|
31
31
|
if (!nativeIsRepo(basePath)) {
|
|
@@ -360,8 +360,8 @@ export async function runGSDDoctor(basePath: string, options?: { fix?: boolean;
|
|
|
360
360
|
// Git health checks — timed
|
|
361
361
|
const t0git = Date.now();
|
|
362
362
|
const isolationMode: "none" | "worktree" | "branch" = options?.isolationMode ??
|
|
363
|
-
(prefs?.preferences?.git?.isolation === "
|
|
364
|
-
prefs?.preferences?.git?.isolation === "branch" ? "branch" : "
|
|
363
|
+
(prefs?.preferences?.git?.isolation === "worktree" ? "worktree" :
|
|
364
|
+
prefs?.preferences?.git?.isolation === "branch" ? "branch" : "none");
|
|
365
365
|
await checkGitHealth(basePath, issues, fixesApplied, shouldFix, isolationMode);
|
|
366
366
|
const gitMs = Date.now() - t0git;
|
|
367
367
|
|
|
@@ -470,7 +470,7 @@ export async function runGSDDoctor(basePath: string, options?: { fix?: boolean;
|
|
|
470
470
|
if (!roadmapContent) continue;
|
|
471
471
|
|
|
472
472
|
// Normalize slices: prefer DB, fall back to parser
|
|
473
|
-
type NormSlice = RoadmapSliceEntry;
|
|
473
|
+
type NormSlice = RoadmapSliceEntry & { pending?: boolean };
|
|
474
474
|
let slices: NormSlice[];
|
|
475
475
|
if (isDbAvailable()) {
|
|
476
476
|
const dbSlices = getMilestoneSlices(milestoneId);
|
|
@@ -478,6 +478,7 @@ export async function runGSDDoctor(basePath: string, options?: { fix?: boolean;
|
|
|
478
478
|
id: s.id,
|
|
479
479
|
title: s.title,
|
|
480
480
|
done: s.status === "complete",
|
|
481
|
+
pending: s.status === "pending",
|
|
481
482
|
risk: (s.risk || "medium") as RoadmapSliceEntry["risk"],
|
|
482
483
|
depends: s.depends,
|
|
483
484
|
demo: s.demo,
|
|
@@ -564,6 +565,9 @@ export async function runGSDDoctor(basePath: string, options?: { fix?: boolean;
|
|
|
564
565
|
|
|
565
566
|
const slicePath = resolveSlicePath(basePath, milestoneId, slice.id);
|
|
566
567
|
if (!slicePath) {
|
|
568
|
+
// Pending slices haven't been planned yet — directories are created
|
|
569
|
+
// lazily by ensurePreconditions() at dispatch time. Skip them.
|
|
570
|
+
if (slice.pending) continue;
|
|
567
571
|
const expectedPath = relSlicePath(basePath, milestoneId, slice.id);
|
|
568
572
|
issues.push({
|
|
569
573
|
severity: slice.done ? "warning" : "error",
|
|
@@ -586,6 +590,8 @@ export async function runGSDDoctor(basePath: string, options?: { fix?: boolean;
|
|
|
586
590
|
|
|
587
591
|
const tasksDir = resolveTasksDir(basePath, milestoneId, slice.id);
|
|
588
592
|
if (!tasksDir) {
|
|
593
|
+
// Pending slices haven't been planned yet — tasks/ is created on demand.
|
|
594
|
+
if (slice.pending) continue;
|
|
589
595
|
issues.push({
|
|
590
596
|
severity: slice.done ? "warning" : "error",
|
|
591
597
|
code: "missing_tasks_dir",
|
|
@@ -684,13 +684,17 @@ export function createDraftPR(
|
|
|
684
684
|
milestoneId: string,
|
|
685
685
|
title: string,
|
|
686
686
|
body: string,
|
|
687
|
+
opts?: { head?: string; base?: string },
|
|
687
688
|
): string | null {
|
|
688
689
|
try {
|
|
689
|
-
const
|
|
690
|
+
const args = [
|
|
690
691
|
"pr", "create", "--draft",
|
|
691
692
|
"--title", title,
|
|
692
693
|
"--body", body,
|
|
693
|
-
]
|
|
694
|
+
];
|
|
695
|
+
if (opts?.head) args.push("--head", opts.head);
|
|
696
|
+
if (opts?.base) args.push("--base", opts.base);
|
|
697
|
+
const result = execFileSync("gh", args, { cwd: basePath, encoding: "utf8", timeout: 30000, env: GIT_NO_PROMPT_ENV });
|
|
694
698
|
return result.trim();
|
|
695
699
|
} catch {
|
|
696
700
|
return null;
|
|
@@ -78,8 +78,12 @@ function loadProvider(): void {
|
|
|
78
78
|
// unavailable
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
+
const nodeMajor = parseInt(process.versions.node.split(".")[0], 10);
|
|
82
|
+
const versionHint = nodeMajor < 22
|
|
83
|
+
? ` GSD requires Node >= 22.0.0 (current: v${process.versions.node}). Upgrade Node to fix this.`
|
|
84
|
+
: "";
|
|
81
85
|
process.stderr.write(
|
|
82
|
-
|
|
86
|
+
`gsd-db: No SQLite provider available (tried node:sqlite, better-sqlite3).${versionHint}\n`,
|
|
83
87
|
);
|
|
84
88
|
}
|
|
85
89
|
|
|
@@ -301,6 +305,7 @@ function initSchema(db: DbAdapter, fileBacked: boolean): void {
|
|
|
301
305
|
inputs TEXT NOT NULL DEFAULT '[]',
|
|
302
306
|
expected_output TEXT NOT NULL DEFAULT '[]',
|
|
303
307
|
observability_impact TEXT NOT NULL DEFAULT '',
|
|
308
|
+
full_plan_md TEXT NOT NULL DEFAULT '',
|
|
304
309
|
sequence INTEGER DEFAULT 0, -- DEAD CODE: no tool exposes sequence — always 0
|
|
305
310
|
PRIMARY KEY (milestone_id, slice_id, id),
|
|
306
311
|
FOREIGN KEY (milestone_id, slice_id) REFERENCES slices(milestone_id, id)
|
|
@@ -616,6 +621,15 @@ function migrateSchema(db: DbAdapter): void {
|
|
|
616
621
|
});
|
|
617
622
|
}
|
|
618
623
|
|
|
624
|
+
if (currentVersion < 11) {
|
|
625
|
+
ensureColumn(db, "tasks", "full_plan_md", `ALTER TABLE tasks ADD COLUMN full_plan_md TEXT NOT NULL DEFAULT ''`);
|
|
626
|
+
|
|
627
|
+
db.prepare("INSERT INTO schema_version (version, applied_at) VALUES (:version, :applied_at)").run({
|
|
628
|
+
":version": 11,
|
|
629
|
+
":applied_at": new Date().toISOString(),
|
|
630
|
+
});
|
|
631
|
+
}
|
|
632
|
+
|
|
619
633
|
db.exec("COMMIT");
|
|
620
634
|
} catch (err) {
|
|
621
635
|
db.exec("ROLLBACK");
|
|
@@ -923,6 +937,7 @@ export interface TaskPlanningRecord {
|
|
|
923
937
|
inputs: string[];
|
|
924
938
|
expectedOutput: string[];
|
|
925
939
|
observabilityImpact: string;
|
|
940
|
+
fullPlanMd?: string;
|
|
926
941
|
}
|
|
927
942
|
|
|
928
943
|
export function insertMilestone(m: {
|
|
@@ -1163,7 +1178,8 @@ export function upsertTaskPlanning(milestoneId: string, sliceId: string, taskId:
|
|
|
1163
1178
|
verify = COALESCE(:verify, verify),
|
|
1164
1179
|
inputs = COALESCE(:inputs, inputs),
|
|
1165
1180
|
expected_output = COALESCE(:expected_output, expected_output),
|
|
1166
|
-
observability_impact = COALESCE(:observability_impact, observability_impact)
|
|
1181
|
+
observability_impact = COALESCE(:observability_impact, observability_impact),
|
|
1182
|
+
full_plan_md = COALESCE(:full_plan_md, full_plan_md)
|
|
1167
1183
|
WHERE milestone_id = :milestone_id AND slice_id = :slice_id AND id = :id`,
|
|
1168
1184
|
).run({
|
|
1169
1185
|
":milestone_id": milestoneId,
|
|
@@ -1177,6 +1193,7 @@ export function upsertTaskPlanning(milestoneId: string, sliceId: string, taskId:
|
|
|
1177
1193
|
":inputs": planning.inputs ? JSON.stringify(planning.inputs) : null,
|
|
1178
1194
|
":expected_output": planning.expectedOutput ? JSON.stringify(planning.expectedOutput) : null,
|
|
1179
1195
|
":observability_impact": planning.observabilityImpact ?? null,
|
|
1196
|
+
":full_plan_md": planning.fullPlanMd ?? null,
|
|
1180
1197
|
});
|
|
1181
1198
|
}
|
|
1182
1199
|
|
|
@@ -1268,6 +1285,7 @@ export interface TaskRow {
|
|
|
1268
1285
|
inputs: string[];
|
|
1269
1286
|
expected_output: string[];
|
|
1270
1287
|
observability_impact: string;
|
|
1288
|
+
full_plan_md: string;
|
|
1271
1289
|
sequence: number;
|
|
1272
1290
|
}
|
|
1273
1291
|
|
|
@@ -1296,6 +1314,7 @@ function rowToTask(row: Record<string, unknown>): TaskRow {
|
|
|
1296
1314
|
inputs: JSON.parse((row["inputs"] as string) || "[]"),
|
|
1297
1315
|
expected_output: JSON.parse((row["expected_output"] as string) || "[]"),
|
|
1298
1316
|
observability_impact: (row["observability_impact"] as string) ?? "",
|
|
1317
|
+
full_plan_md: (row["full_plan_md"] as string) ?? "",
|
|
1299
1318
|
sequence: (row["sequence"] as number) ?? 0,
|
|
1300
1319
|
};
|
|
1301
1320
|
}
|
|
@@ -32,7 +32,12 @@ export type JournalEventType =
|
|
|
32
32
|
| "milestone-transition"
|
|
33
33
|
| "stuck-detected"
|
|
34
34
|
| "sidecar-dequeue"
|
|
35
|
-
| "iteration-end"
|
|
35
|
+
| "iteration-end"
|
|
36
|
+
| "worktree-enter"
|
|
37
|
+
| "worktree-create-failed"
|
|
38
|
+
| "worktree-skip"
|
|
39
|
+
| "worktree-merge-start"
|
|
40
|
+
| "worktree-merge-failed";
|
|
36
41
|
|
|
37
42
|
/** A single structured event in the journal. */
|
|
38
43
|
export interface JournalEntry {
|
|
@@ -387,7 +387,7 @@ export async function renderTaskPlanFromDb(
|
|
|
387
387
|
mkdirSync(tasksDir, { recursive: true });
|
|
388
388
|
const absPath = join(tasksDir, buildTaskFileName(taskId, "PLAN"));
|
|
389
389
|
const artifactPath = toArtifactPath(absPath, basePath);
|
|
390
|
-
const content = renderTaskPlanMarkdown(task);
|
|
390
|
+
const content = task.full_plan_md.trim() ? task.full_plan_md : renderTaskPlanMarkdown(task);
|
|
391
391
|
|
|
392
392
|
await writeAndStore(absPath, artifactPath, content, {
|
|
393
393
|
artifact_type: "PLAN",
|
|
@@ -34,7 +34,7 @@ export const MODE_DEFAULTS: Record<WorkflowMode, Partial<GSDPreferences>> = {
|
|
|
34
34
|
push_branches: false,
|
|
35
35
|
pre_merge_check: false,
|
|
36
36
|
merge_strategy: "squash",
|
|
37
|
-
isolation: "
|
|
37
|
+
isolation: "none",
|
|
38
38
|
},
|
|
39
39
|
unique_milestone_ids: false,
|
|
40
40
|
},
|
|
@@ -44,7 +44,7 @@ export const MODE_DEFAULTS: Record<WorkflowMode, Partial<GSDPreferences>> = {
|
|
|
44
44
|
push_branches: true,
|
|
45
45
|
pre_merge_check: true,
|
|
46
46
|
merge_strategy: "squash",
|
|
47
|
-
isolation: "
|
|
47
|
+
isolation: "none",
|
|
48
48
|
},
|
|
49
49
|
unique_milestone_ids: true,
|
|
50
50
|
},
|
|
@@ -196,6 +196,13 @@ function loadPreferencesFile(path: string, scope: "global" | "project"): LoadedG
|
|
|
196
196
|
};
|
|
197
197
|
}
|
|
198
198
|
|
|
199
|
+
let _warnedUnrecognizedFormat = false;
|
|
200
|
+
|
|
201
|
+
/** @internal Reset the warn-once flag — exported for testing only. */
|
|
202
|
+
export function _resetParseWarningFlag(): void {
|
|
203
|
+
_warnedUnrecognizedFormat = false;
|
|
204
|
+
}
|
|
205
|
+
|
|
199
206
|
/** @internal Exported for testing only */
|
|
200
207
|
export function parsePreferencesMarkdown(content: string): GSDPreferences | null {
|
|
201
208
|
// Use indexOf instead of [\s\S]*? regex to avoid backtracking (#468)
|
|
@@ -214,7 +221,10 @@ export function parsePreferencesMarkdown(content: string): GSDPreferences | null
|
|
|
214
221
|
return parseHeadingListFormat(content);
|
|
215
222
|
}
|
|
216
223
|
|
|
217
|
-
|
|
224
|
+
if (!_warnedUnrecognizedFormat) {
|
|
225
|
+
_warnedUnrecognizedFormat = true;
|
|
226
|
+
console.warn("[parsePreferencesMarkdown] preferences.md exists but uses an unrecognized format — skipping.");
|
|
227
|
+
}
|
|
218
228
|
return null;
|
|
219
229
|
}
|
|
220
230
|
|
|
@@ -487,13 +497,17 @@ export function resolvePreDispatchHooks(): PreDispatchHookConfig[] {
|
|
|
487
497
|
|
|
488
498
|
/**
|
|
489
499
|
* Resolve the effective git isolation mode from preferences.
|
|
490
|
-
* Returns "
|
|
500
|
+
* Returns "none" (default), "worktree", or "branch".
|
|
501
|
+
*
|
|
502
|
+
* Default is "none" so GSD works out of the box without preferences.md.
|
|
503
|
+
* Worktree isolation requires explicit opt-in because it depends on git
|
|
504
|
+
* branch infrastructure that must be set up before use.
|
|
491
505
|
*/
|
|
492
506
|
export function getIsolationMode(): "none" | "worktree" | "branch" {
|
|
493
507
|
const prefs = loadEffectiveGSDPreferences()?.preferences?.git;
|
|
494
|
-
if (prefs?.isolation === "
|
|
508
|
+
if (prefs?.isolation === "worktree") return "worktree";
|
|
495
509
|
if (prefs?.isolation === "branch") return "branch";
|
|
496
|
-
return "
|
|
510
|
+
return "none"; // default — no isolation, work on current branch
|
|
497
511
|
}
|
|
498
512
|
|
|
499
513
|
export function resolveParallelConfig(prefs: GSDPreferences | undefined): import("./types.js").ParallelConfig {
|
|
@@ -21,8 +21,8 @@ Then:
|
|
|
21
21
|
4. Verify each **success criterion** from the milestone definition in `{{roadmapPath}}`. For each criterion, confirm it was met with specific evidence from slice summaries, test results, or observable behavior. List any criterion that was NOT met.
|
|
22
22
|
5. Verify the milestone's **definition of done** — all slices are `[x]`, all slice summaries exist, and any cross-slice integration points work correctly.
|
|
23
23
|
6. Validate **requirement status transitions**. For each requirement that changed status during this milestone, confirm the transition is supported by evidence. Requirements can move between Active, Validated, Deferred, Blocked, or Out of Scope — but only with proof.
|
|
24
|
-
7.
|
|
25
|
-
8. Update `.gsd/REQUIREMENTS.md` if any requirement status transitions were validated in step
|
|
24
|
+
7. **Persist completion through `gsd_complete_milestone`.** Call it with: `milestoneId`, `title`, `oneLiner`, `narrative`, `successCriteriaResults`, `definitionOfDoneResults`, `requirementOutcomes`, `keyDecisions`, `keyFiles`, `lessonsLearned`, `followUps`, `deviations`. The tool updates the milestone status in the DB, renders `{{milestoneSummaryPath}}`, and validates all slices are complete before proceeding.
|
|
25
|
+
8. Update `.gsd/REQUIREMENTS.md` if any requirement status transitions were validated in step 6.
|
|
26
26
|
9. Update `.gsd/PROJECT.md` to reflect milestone completion and current project state.
|
|
27
27
|
10. Review all slice summaries for cross-cutting lessons, patterns, or gotchas that emerged during this milestone. Append any non-obvious, reusable insights to `.gsd/KNOWLEDGE.md`.
|
|
28
28
|
11. Do not commit manually — the system auto-commits your changes after this unit completes.
|
|
@@ -31,6 +31,4 @@ Then:
|
|
|
31
31
|
|
|
32
32
|
**File system safety:** When scanning milestone directories for evidence, use `ls` or `find` to list directory contents first — never pass a directory path (e.g. `tasks/`, `slices/`) directly to the `read` tool. The `read` tool only accepts file paths, not directories.
|
|
33
33
|
|
|
34
|
-
**You MUST write `{{milestoneSummaryPath}}` AND update PROJECT.md before finishing.**
|
|
35
|
-
|
|
36
34
|
When done, say: "Milestone {{milestoneId}} complete."
|
|
@@ -63,7 +63,7 @@ Then:
|
|
|
63
63
|
- a matching task plan file with description, steps, must-haves, verification, inputs, and expected output
|
|
64
64
|
- **Inputs and Expected Output must list concrete backtick-wrapped file paths** (e.g. `` `src/types.ts` ``). These are machine-parsed to derive task dependencies — vague prose without paths breaks parallel execution. Every task must have at least one output file path.
|
|
65
65
|
- Observability Impact section **only if the task touches runtime boundaries, async flows, or error paths** — omit it otherwise
|
|
66
|
-
6. **Persist planning state through
|
|
66
|
+
6. **Persist planning state through `gsd_plan_slice`.** Call it with the full slice planning payload (goal, demo, must-haves, verification, tasks, and metadata). The tool inserts all tasks in the same transaction, writes to the DB, and renders `{{outputPath}}` and `{{slicePath}}/tasks/T##-PLAN.md` files automatically. Do **not** call `gsd_plan_task` separately — `gsd_plan_slice` handles task persistence. Do **not** rely on direct `PLAN.md` writes as the source of truth; the DB-backed tool is the canonical write path for slice and task planning state.
|
|
67
67
|
7. **Self-audit the plan.** Walk through each check — if any fail, fix the plan files before moving on:
|
|
68
68
|
- **Completion semantics:** If every task were completed exactly as written, the slice goal/demo should actually be true.
|
|
69
69
|
- **Requirement coverage:** Every must-have in the slice maps to at least one task. No must-have is orphaned. If `REQUIREMENTS.md` exists, every Active requirement this slice owns maps to at least one task.
|