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,187 @@
|
|
|
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
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
12
|
+
import { join } from "node:path";
|
|
13
|
+
function readMcpConfigs() {
|
|
14
|
+
const servers = [];
|
|
15
|
+
const seen = new Set();
|
|
16
|
+
const configPaths = [
|
|
17
|
+
join(process.cwd(), ".mcp.json"),
|
|
18
|
+
join(process.cwd(), ".gsd", "mcp.json"),
|
|
19
|
+
];
|
|
20
|
+
for (const configPath of configPaths) {
|
|
21
|
+
try {
|
|
22
|
+
if (!existsSync(configPath))
|
|
23
|
+
continue;
|
|
24
|
+
const raw = readFileSync(configPath, "utf-8");
|
|
25
|
+
const data = JSON.parse(raw);
|
|
26
|
+
const mcpServers = (data.mcpServers ?? data.servers);
|
|
27
|
+
if (!mcpServers || typeof mcpServers !== "object")
|
|
28
|
+
continue;
|
|
29
|
+
for (const [name, config] of Object.entries(mcpServers)) {
|
|
30
|
+
if (seen.has(name))
|
|
31
|
+
continue;
|
|
32
|
+
seen.add(name);
|
|
33
|
+
const hasCommand = typeof config.command === "string";
|
|
34
|
+
const hasUrl = typeof config.url === "string";
|
|
35
|
+
const transport = hasCommand
|
|
36
|
+
? "stdio"
|
|
37
|
+
: hasUrl
|
|
38
|
+
? "http"
|
|
39
|
+
: "unknown";
|
|
40
|
+
servers.push({
|
|
41
|
+
name,
|
|
42
|
+
transport,
|
|
43
|
+
...(hasCommand && {
|
|
44
|
+
command: config.command,
|
|
45
|
+
args: Array.isArray(config.args) ? config.args : undefined,
|
|
46
|
+
}),
|
|
47
|
+
...(hasUrl && { url: config.url }),
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
// Non-fatal — config file may not exist or be malformed
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return servers;
|
|
56
|
+
}
|
|
57
|
+
// ─── Formatters (exported for testing) ──────────────────────────────────────
|
|
58
|
+
export function formatMcpStatusReport(servers) {
|
|
59
|
+
if (servers.length === 0) {
|
|
60
|
+
return [
|
|
61
|
+
"No MCP servers configured.",
|
|
62
|
+
"",
|
|
63
|
+
"Add servers to .mcp.json or .gsd/mcp.json to enable MCP integrations.",
|
|
64
|
+
"See: https://modelcontextprotocol.io/quickstart",
|
|
65
|
+
].join("\n");
|
|
66
|
+
}
|
|
67
|
+
const lines = [`MCP Server Status — ${servers.length} server(s)\n`];
|
|
68
|
+
for (const s of servers) {
|
|
69
|
+
const icon = s.error ? "✗" : s.connected ? "✓" : "○";
|
|
70
|
+
const status = s.error
|
|
71
|
+
? `error: ${s.error}`
|
|
72
|
+
: s.connected
|
|
73
|
+
? `connected — ${s.toolCount} tools`
|
|
74
|
+
: "disconnected";
|
|
75
|
+
lines.push(` ${icon} ${s.name} (${s.transport}) — ${status}`);
|
|
76
|
+
}
|
|
77
|
+
lines.push("");
|
|
78
|
+
lines.push("Use /gsd mcp check <server> for details on a specific server.");
|
|
79
|
+
lines.push("Use mcp_discover to connect and list tools for a server.");
|
|
80
|
+
return lines.join("\n");
|
|
81
|
+
}
|
|
82
|
+
export function formatMcpServerDetail(server) {
|
|
83
|
+
const lines = [`MCP Server: ${server.name}\n`];
|
|
84
|
+
lines.push(` Transport: ${server.transport}`);
|
|
85
|
+
if (server.error) {
|
|
86
|
+
lines.push(` Status: error`);
|
|
87
|
+
lines.push(` Error: ${server.error}`);
|
|
88
|
+
}
|
|
89
|
+
else if (server.connected) {
|
|
90
|
+
lines.push(` Status: connected`);
|
|
91
|
+
lines.push(` Tools: ${server.toolCount}`);
|
|
92
|
+
if (server.tools.length > 0) {
|
|
93
|
+
lines.push("");
|
|
94
|
+
lines.push(" Available tools:");
|
|
95
|
+
for (const tool of server.tools) {
|
|
96
|
+
lines.push(` - ${tool}`);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
lines.push(` Status: disconnected`);
|
|
102
|
+
lines.push("");
|
|
103
|
+
lines.push(` Run mcp_discover("${server.name}") to connect and list tools.`);
|
|
104
|
+
}
|
|
105
|
+
return lines.join("\n");
|
|
106
|
+
}
|
|
107
|
+
// ─── Command handler ────────────────────────────────────────────────────────
|
|
108
|
+
/**
|
|
109
|
+
* Handle `/gsd mcp [status|check <server>]`.
|
|
110
|
+
*/
|
|
111
|
+
export async function handleMcpStatus(args, ctx) {
|
|
112
|
+
const trimmed = args.trim().toLowerCase();
|
|
113
|
+
const configs = readMcpConfigs();
|
|
114
|
+
// /gsd mcp check <server>
|
|
115
|
+
if (trimmed.startsWith("check ")) {
|
|
116
|
+
const serverName = args.trim().slice("check ".length).trim();
|
|
117
|
+
const config = configs.find((c) => c.name === serverName);
|
|
118
|
+
if (!config) {
|
|
119
|
+
const available = configs.map((c) => c.name).join(", ") || "(none)";
|
|
120
|
+
ctx.ui.notify(`Unknown MCP server: "${serverName}"\n\nAvailable: ${available}`, "warning");
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
// Try to get connection/tool info from the mcp-client module if available
|
|
124
|
+
let connected = false;
|
|
125
|
+
let toolNames = [];
|
|
126
|
+
let error;
|
|
127
|
+
try {
|
|
128
|
+
const mcpClient = await import("../mcp-client/index.js");
|
|
129
|
+
// Access the module's connection state if exported; fall back gracefully
|
|
130
|
+
const mod = mcpClient;
|
|
131
|
+
if (typeof mod.getConnectionStatus === "function") {
|
|
132
|
+
const status = mod.getConnectionStatus(serverName);
|
|
133
|
+
connected = status.connected;
|
|
134
|
+
toolNames = status.tools;
|
|
135
|
+
error = status.error;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
// mcp-client may not expose status helpers — that's fine
|
|
140
|
+
}
|
|
141
|
+
ctx.ui.notify(formatMcpServerDetail({
|
|
142
|
+
name: config.name,
|
|
143
|
+
transport: config.transport,
|
|
144
|
+
connected,
|
|
145
|
+
toolCount: toolNames.length,
|
|
146
|
+
tools: toolNames,
|
|
147
|
+
error,
|
|
148
|
+
}), "info");
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
// /gsd mcp or /gsd mcp status
|
|
152
|
+
if (!trimmed || trimmed === "status") {
|
|
153
|
+
// Build status for each server
|
|
154
|
+
const statuses = [];
|
|
155
|
+
for (const config of configs) {
|
|
156
|
+
let connected = false;
|
|
157
|
+
let toolCount = 0;
|
|
158
|
+
let error;
|
|
159
|
+
try {
|
|
160
|
+
const mcpClient = await import("../mcp-client/index.js");
|
|
161
|
+
const mod = mcpClient;
|
|
162
|
+
if (typeof mod.getConnectionStatus === "function") {
|
|
163
|
+
const status = mod.getConnectionStatus(config.name);
|
|
164
|
+
connected = status.connected;
|
|
165
|
+
toolCount = status.tools.length;
|
|
166
|
+
error = status.error;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
catch {
|
|
170
|
+
// Fall back to unknown state
|
|
171
|
+
}
|
|
172
|
+
statuses.push({
|
|
173
|
+
name: config.name,
|
|
174
|
+
transport: config.transport,
|
|
175
|
+
connected,
|
|
176
|
+
toolCount,
|
|
177
|
+
error,
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
ctx.ui.notify(formatMcpStatusReport(statuses), "info");
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
// Unknown subcommand
|
|
184
|
+
ctx.ui.notify("Usage: /gsd mcp [status|check <server>]\n\n" +
|
|
185
|
+
" status Show all MCP server statuses (default)\n" +
|
|
186
|
+
" check <server> Detailed status for a specific server", "warning");
|
|
187
|
+
}
|
|
@@ -8,10 +8,11 @@
|
|
|
8
8
|
// Critical invariant: generated markdown must round-trip through
|
|
9
9
|
// parseDecisionsTable() and parseRequirementsSections() with field fidelity.
|
|
10
10
|
import { resolve } from 'node:path';
|
|
11
|
-
import { readFileSync, existsSync } from 'node:fs';
|
|
11
|
+
import { readFileSync, existsSync, statSync } from 'node:fs';
|
|
12
12
|
import { resolveGsdRootFile } from './paths.js';
|
|
13
13
|
import { saveFile } from './files.js';
|
|
14
14
|
import { GSDError, GSD_STALE_STATE, GSD_IO_ERROR } from './errors.js';
|
|
15
|
+
import { logWarning, logError } from './workflow-logger.js';
|
|
15
16
|
import { invalidateStateCache } from './state.js';
|
|
16
17
|
import { clearPathCache } from './paths.js';
|
|
17
18
|
import { clearParseCache } from './files.js';
|
|
@@ -200,7 +201,7 @@ export async function nextDecisionId() {
|
|
|
200
201
|
return `D${String(next).padStart(3, '0')}`;
|
|
201
202
|
}
|
|
202
203
|
catch (err) {
|
|
203
|
-
|
|
204
|
+
logError('manifest', 'nextDecisionId failed', { fn: 'nextDecisionId', error: String(err.message) });
|
|
204
205
|
return 'D001';
|
|
205
206
|
}
|
|
206
207
|
}
|
|
@@ -269,7 +270,7 @@ export async function saveDecisionToDb(fields, basePath) {
|
|
|
269
270
|
await saveFile(filePath, md);
|
|
270
271
|
}
|
|
271
272
|
catch (diskErr) {
|
|
272
|
-
|
|
273
|
+
logError('manifest', 'disk write failed, rolling back DB row', { fn: 'saveDecisionToDb', error: String(diskErr.message) });
|
|
273
274
|
adapter?.prepare('DELETE FROM decisions WHERE id = :id').run({ ':id': id });
|
|
274
275
|
throw diskErr;
|
|
275
276
|
}
|
|
@@ -281,7 +282,7 @@ export async function saveDecisionToDb(fields, basePath) {
|
|
|
281
282
|
return { id };
|
|
282
283
|
}
|
|
283
284
|
catch (err) {
|
|
284
|
-
|
|
285
|
+
logError('manifest', 'saveDecisionToDb failed', { fn: 'saveDecisionToDb', error: String(err.message) });
|
|
285
286
|
throw err;
|
|
286
287
|
}
|
|
287
288
|
}
|
|
@@ -333,7 +334,7 @@ export async function updateRequirementInDb(id, updates, basePath) {
|
|
|
333
334
|
await saveFile(filePath, md);
|
|
334
335
|
}
|
|
335
336
|
catch (diskErr) {
|
|
336
|
-
|
|
337
|
+
logError('manifest', 'disk write failed, reverting DB row', { fn: 'updateRequirementInDb', error: String(diskErr.message) });
|
|
337
338
|
db.upsertRequirement(existing);
|
|
338
339
|
throw diskErr;
|
|
339
340
|
}
|
|
@@ -344,7 +345,7 @@ export async function updateRequirementInDb(id, updates, basePath) {
|
|
|
344
345
|
clearParseCache();
|
|
345
346
|
}
|
|
346
347
|
catch (err) {
|
|
347
|
-
|
|
348
|
+
logError('manifest', 'updateRequirementInDb failed', { fn: 'updateRequirementInDb', error: String(err.message) });
|
|
348
349
|
throw err;
|
|
349
350
|
}
|
|
350
351
|
}
|
|
@@ -356,28 +357,45 @@ export async function updateRequirementInDb(id, updates, basePath) {
|
|
|
356
357
|
export async function saveArtifactToDb(opts, basePath) {
|
|
357
358
|
try {
|
|
358
359
|
const db = await import('./gsd-db.js');
|
|
360
|
+
// Guard against path traversal before any reads/writes
|
|
361
|
+
const gsdDir = resolve(basePath, '.gsd');
|
|
362
|
+
const fullPath = resolve(basePath, '.gsd', opts.path);
|
|
363
|
+
if (!fullPath.startsWith(gsdDir)) {
|
|
364
|
+
throw new GSDError(GSD_IO_ERROR, `saveArtifactToDb: path escapes .gsd/ directory: ${opts.path}`);
|
|
365
|
+
}
|
|
366
|
+
// Shrinkage guard: if the file already exists and the new content is
|
|
367
|
+
// significantly smaller (<50%), preserve the richer file on disk and
|
|
368
|
+
// store its content in the DB instead of the abbreviated version.
|
|
369
|
+
let dbContent = opts.content;
|
|
370
|
+
let skipDiskWrite = false;
|
|
371
|
+
if (existsSync(fullPath)) {
|
|
372
|
+
const existingSize = statSync(fullPath).size;
|
|
373
|
+
const newSize = Buffer.byteLength(opts.content, 'utf-8');
|
|
374
|
+
if (existingSize > 0 && newSize < existingSize * 0.5) {
|
|
375
|
+
logWarning('manifest', `new content (${newSize}B) is <50% of existing file (${existingSize}B), preserving disk file`, { fn: 'saveArtifactToDb', path: opts.path });
|
|
376
|
+
dbContent = readFileSync(fullPath, 'utf-8');
|
|
377
|
+
skipDiskWrite = true;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
359
380
|
db.insertArtifact({
|
|
360
381
|
path: opts.path,
|
|
361
382
|
artifact_type: opts.artifact_type,
|
|
362
383
|
milestone_id: opts.milestone_id ?? null,
|
|
363
384
|
slice_id: opts.slice_id ?? null,
|
|
364
385
|
task_id: opts.task_id ?? null,
|
|
365
|
-
full_content:
|
|
386
|
+
full_content: dbContent,
|
|
366
387
|
});
|
|
367
|
-
// Write the file to disk (
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
const rollbackAdapter = db._getAdapter();
|
|
379
|
-
rollbackAdapter?.prepare('DELETE FROM artifacts WHERE path = :path').run({ ':path': opts.path });
|
|
380
|
-
throw diskErr;
|
|
388
|
+
// Write the file to disk (only if we're not preserving a richer existing file)
|
|
389
|
+
if (!skipDiskWrite) {
|
|
390
|
+
try {
|
|
391
|
+
await saveFile(fullPath, opts.content);
|
|
392
|
+
}
|
|
393
|
+
catch (diskErr) {
|
|
394
|
+
logError('manifest', 'disk write failed, rolling back DB row', { fn: 'saveArtifactToDb', error: String(diskErr.message) });
|
|
395
|
+
const rollbackAdapter = db._getAdapter();
|
|
396
|
+
rollbackAdapter?.prepare('DELETE FROM artifacts WHERE path = :path').run({ ':path': opts.path });
|
|
397
|
+
throw diskErr;
|
|
398
|
+
}
|
|
381
399
|
}
|
|
382
400
|
// Invalidate file-read caches so deriveState() sees the updated markdown.
|
|
383
401
|
// Do NOT clear the artifacts table — we just wrote to it intentionally.
|
|
@@ -386,7 +404,7 @@ export async function saveArtifactToDb(opts, basePath) {
|
|
|
386
404
|
clearParseCache();
|
|
387
405
|
}
|
|
388
406
|
catch (err) {
|
|
389
|
-
|
|
407
|
+
logError('manifest', 'saveArtifactToDb failed', { fn: 'saveArtifactToDb', error: String(err.message) });
|
|
390
408
|
throw err;
|
|
391
409
|
}
|
|
392
410
|
}
|
|
@@ -17,7 +17,7 @@ import { getAllWorktreeHealth } from "./worktree-health.js";
|
|
|
17
17
|
import { readAllSessionStatuses, isSessionStale, removeSessionStatus } from "./session-status-io.js";
|
|
18
18
|
import { recoverFailedMigration } from "./migrate-external.js";
|
|
19
19
|
import { loadEffectiveGSDPreferences } from "./preferences.js";
|
|
20
|
-
export async function checkGitHealth(basePath, issues, fixesApplied, shouldFix, isolationMode = "
|
|
20
|
+
export async function checkGitHealth(basePath, issues, fixesApplied, shouldFix, isolationMode = "none") {
|
|
21
21
|
// Degrade gracefully if not a git repo
|
|
22
22
|
if (!nativeIsRepo(basePath)) {
|
|
23
23
|
return; // Not a git repo — skip all git health checks
|
|
@@ -332,8 +332,8 @@ export async function runGSDDoctor(basePath, options) {
|
|
|
332
332
|
// Git health checks — timed
|
|
333
333
|
const t0git = Date.now();
|
|
334
334
|
const isolationMode = options?.isolationMode ??
|
|
335
|
-
(prefs?.preferences?.git?.isolation === "
|
|
336
|
-
prefs?.preferences?.git?.isolation === "branch" ? "branch" : "
|
|
335
|
+
(prefs?.preferences?.git?.isolation === "worktree" ? "worktree" :
|
|
336
|
+
prefs?.preferences?.git?.isolation === "branch" ? "branch" : "none");
|
|
337
337
|
await checkGitHealth(basePath, issues, fixesApplied, shouldFix, isolationMode);
|
|
338
338
|
const gitMs = Date.now() - t0git;
|
|
339
339
|
// Runtime health checks — timed
|
|
@@ -441,6 +441,7 @@ export async function runGSDDoctor(basePath, options) {
|
|
|
441
441
|
id: s.id,
|
|
442
442
|
title: s.title,
|
|
443
443
|
done: s.status === "complete",
|
|
444
|
+
pending: s.status === "pending",
|
|
444
445
|
risk: (s.risk || "medium"),
|
|
445
446
|
depends: s.depends,
|
|
446
447
|
demo: s.demo,
|
|
@@ -528,6 +529,10 @@ export async function runGSDDoctor(basePath, options) {
|
|
|
528
529
|
}
|
|
529
530
|
const slicePath = resolveSlicePath(basePath, milestoneId, slice.id);
|
|
530
531
|
if (!slicePath) {
|
|
532
|
+
// Pending slices haven't been planned yet — directories are created
|
|
533
|
+
// lazily by ensurePreconditions() at dispatch time. Skip them.
|
|
534
|
+
if (slice.pending)
|
|
535
|
+
continue;
|
|
531
536
|
const expectedPath = relSlicePath(basePath, milestoneId, slice.id);
|
|
532
537
|
issues.push({
|
|
533
538
|
severity: slice.done ? "warning" : "error",
|
|
@@ -549,6 +554,9 @@ export async function runGSDDoctor(basePath, options) {
|
|
|
549
554
|
}
|
|
550
555
|
const tasksDir = resolveTasksDir(basePath, milestoneId, slice.id);
|
|
551
556
|
if (!tasksDir) {
|
|
557
|
+
// Pending slices haven't been planned yet — tasks/ is created on demand.
|
|
558
|
+
if (slice.pending)
|
|
559
|
+
continue;
|
|
552
560
|
issues.push({
|
|
553
561
|
severity: slice.done ? "warning" : "error",
|
|
554
562
|
code: "missing_tasks_dir",
|
|
@@ -510,13 +510,18 @@ export class GitServiceImpl {
|
|
|
510
510
|
* Returns the PR URL on success, or null on failure.
|
|
511
511
|
* Non-fatal: callers should treat failure as best-effort.
|
|
512
512
|
*/
|
|
513
|
-
export function createDraftPR(basePath, milestoneId, title, body) {
|
|
513
|
+
export function createDraftPR(basePath, milestoneId, title, body, opts) {
|
|
514
514
|
try {
|
|
515
|
-
const
|
|
515
|
+
const args = [
|
|
516
516
|
"pr", "create", "--draft",
|
|
517
517
|
"--title", title,
|
|
518
518
|
"--body", body,
|
|
519
|
-
]
|
|
519
|
+
];
|
|
520
|
+
if (opts?.head)
|
|
521
|
+
args.push("--head", opts.head);
|
|
522
|
+
if (opts?.base)
|
|
523
|
+
args.push("--base", opts.base);
|
|
524
|
+
const result = execFileSync("gh", args, { cwd: basePath, encoding: "utf8", timeout: 30000, env: GIT_NO_PROMPT_ENV });
|
|
520
525
|
return result.trim();
|
|
521
526
|
}
|
|
522
527
|
catch {
|
|
@@ -56,7 +56,11 @@ function loadProvider() {
|
|
|
56
56
|
catch {
|
|
57
57
|
// unavailable
|
|
58
58
|
}
|
|
59
|
-
process.
|
|
59
|
+
const nodeMajor = parseInt(process.versions.node.split(".")[0], 10);
|
|
60
|
+
const versionHint = nodeMajor < 22
|
|
61
|
+
? ` GSD requires Node >= 22.0.0 (current: v${process.versions.node}). Upgrade Node to fix this.`
|
|
62
|
+
: "";
|
|
63
|
+
process.stderr.write(`gsd-db: No SQLite provider available (tried node:sqlite, better-sqlite3).${versionHint}\n`);
|
|
60
64
|
}
|
|
61
65
|
function normalizeRow(row) {
|
|
62
66
|
if (row == null)
|
|
@@ -253,6 +257,7 @@ function initSchema(db, fileBacked) {
|
|
|
253
257
|
inputs TEXT NOT NULL DEFAULT '[]',
|
|
254
258
|
expected_output TEXT NOT NULL DEFAULT '[]',
|
|
255
259
|
observability_impact TEXT NOT NULL DEFAULT '',
|
|
260
|
+
full_plan_md TEXT NOT NULL DEFAULT '',
|
|
256
261
|
sequence INTEGER DEFAULT 0, -- DEAD CODE: no tool exposes sequence — always 0
|
|
257
262
|
PRIMARY KEY (milestone_id, slice_id, id),
|
|
258
263
|
FOREIGN KEY (milestone_id, slice_id) REFERENCES slices(milestone_id, id)
|
|
@@ -542,6 +547,13 @@ function migrateSchema(db) {
|
|
|
542
547
|
":applied_at": new Date().toISOString(),
|
|
543
548
|
});
|
|
544
549
|
}
|
|
550
|
+
if (currentVersion < 11) {
|
|
551
|
+
ensureColumn(db, "tasks", "full_plan_md", `ALTER TABLE tasks ADD COLUMN full_plan_md TEXT NOT NULL DEFAULT ''`);
|
|
552
|
+
db.prepare("INSERT INTO schema_version (version, applied_at) VALUES (:version, :applied_at)").run({
|
|
553
|
+
":version": 11,
|
|
554
|
+
":applied_at": new Date().toISOString(),
|
|
555
|
+
});
|
|
556
|
+
}
|
|
545
557
|
db.exec("COMMIT");
|
|
546
558
|
}
|
|
547
559
|
catch (err) {
|
|
@@ -997,7 +1009,8 @@ export function upsertTaskPlanning(milestoneId, sliceId, taskId, planning) {
|
|
|
997
1009
|
verify = COALESCE(:verify, verify),
|
|
998
1010
|
inputs = COALESCE(:inputs, inputs),
|
|
999
1011
|
expected_output = COALESCE(:expected_output, expected_output),
|
|
1000
|
-
observability_impact = COALESCE(:observability_impact, observability_impact)
|
|
1012
|
+
observability_impact = COALESCE(:observability_impact, observability_impact),
|
|
1013
|
+
full_plan_md = COALESCE(:full_plan_md, full_plan_md)
|
|
1001
1014
|
WHERE milestone_id = :milestone_id AND slice_id = :slice_id AND id = :id`).run({
|
|
1002
1015
|
":milestone_id": milestoneId,
|
|
1003
1016
|
":slice_id": sliceId,
|
|
@@ -1010,6 +1023,7 @@ export function upsertTaskPlanning(milestoneId, sliceId, taskId, planning) {
|
|
|
1010
1023
|
":inputs": planning.inputs ? JSON.stringify(planning.inputs) : null,
|
|
1011
1024
|
":expected_output": planning.expectedOutput ? JSON.stringify(planning.expectedOutput) : null,
|
|
1012
1025
|
":observability_impact": planning.observabilityImpact ?? null,
|
|
1026
|
+
":full_plan_md": planning.fullPlanMd ?? null,
|
|
1013
1027
|
});
|
|
1014
1028
|
}
|
|
1015
1029
|
function rowToSlice(row) {
|
|
@@ -1078,6 +1092,7 @@ function rowToTask(row) {
|
|
|
1078
1092
|
inputs: JSON.parse(row["inputs"] || "[]"),
|
|
1079
1093
|
expected_output: JSON.parse(row["expected_output"] || "[]"),
|
|
1080
1094
|
observability_impact: row["observability_impact"] ?? "",
|
|
1095
|
+
full_plan_md: row["full_plan_md"] ?? "",
|
|
1081
1096
|
sequence: row["sequence"] ?? 0,
|
|
1082
1097
|
};
|
|
1083
1098
|
}
|
|
@@ -298,7 +298,7 @@ export async function renderTaskPlanFromDb(basePath, milestoneId, sliceId, taskI
|
|
|
298
298
|
mkdirSync(tasksDir, { recursive: true });
|
|
299
299
|
const absPath = join(tasksDir, buildTaskFileName(taskId, "PLAN"));
|
|
300
300
|
const artifactPath = toArtifactPath(absPath, basePath);
|
|
301
|
-
const content = renderTaskPlanMarkdown(task);
|
|
301
|
+
const content = task.full_plan_md.trim() ? task.full_plan_md : renderTaskPlanMarkdown(task);
|
|
302
302
|
await writeAndStore(absPath, artifactPath, content, {
|
|
303
303
|
artifact_type: "PLAN",
|
|
304
304
|
milestone_id: milestoneId,
|
|
@@ -13,7 +13,7 @@ export const MODE_DEFAULTS = {
|
|
|
13
13
|
push_branches: false,
|
|
14
14
|
pre_merge_check: false,
|
|
15
15
|
merge_strategy: "squash",
|
|
16
|
-
isolation: "
|
|
16
|
+
isolation: "none",
|
|
17
17
|
},
|
|
18
18
|
unique_milestone_ids: false,
|
|
19
19
|
},
|
|
@@ -23,7 +23,7 @@ export const MODE_DEFAULTS = {
|
|
|
23
23
|
push_branches: true,
|
|
24
24
|
pre_merge_check: true,
|
|
25
25
|
merge_strategy: "squash",
|
|
26
|
-
isolation: "
|
|
26
|
+
isolation: "none",
|
|
27
27
|
},
|
|
28
28
|
unique_milestone_ids: true,
|
|
29
29
|
},
|
|
@@ -125,6 +125,11 @@ function loadPreferencesFile(path, scope) {
|
|
|
125
125
|
...(allWarnings.length > 0 ? { warnings: allWarnings } : {}),
|
|
126
126
|
};
|
|
127
127
|
}
|
|
128
|
+
let _warnedUnrecognizedFormat = false;
|
|
129
|
+
/** @internal Reset the warn-once flag — exported for testing only. */
|
|
130
|
+
export function _resetParseWarningFlag() {
|
|
131
|
+
_warnedUnrecognizedFormat = false;
|
|
132
|
+
}
|
|
128
133
|
/** @internal Exported for testing only */
|
|
129
134
|
export function parsePreferencesMarkdown(content) {
|
|
130
135
|
// Use indexOf instead of [\s\S]*? regex to avoid backtracking (#468)
|
|
@@ -142,7 +147,10 @@ export function parsePreferencesMarkdown(content) {
|
|
|
142
147
|
if (/^##\s+\w/m.test(content)) {
|
|
143
148
|
return parseHeadingListFormat(content);
|
|
144
149
|
}
|
|
145
|
-
|
|
150
|
+
if (!_warnedUnrecognizedFormat) {
|
|
151
|
+
_warnedUnrecognizedFormat = true;
|
|
152
|
+
console.warn("[parsePreferencesMarkdown] preferences.md exists but uses an unrecognized format — skipping.");
|
|
153
|
+
}
|
|
146
154
|
return null;
|
|
147
155
|
}
|
|
148
156
|
function parseFrontmatterBlock(frontmatter) {
|
|
@@ -385,15 +393,19 @@ export function resolvePreDispatchHooks() {
|
|
|
385
393
|
// ─── Isolation & Parallel ─────────────────────────────────────────────────────
|
|
386
394
|
/**
|
|
387
395
|
* Resolve the effective git isolation mode from preferences.
|
|
388
|
-
* Returns "
|
|
396
|
+
* Returns "none" (default), "worktree", or "branch".
|
|
397
|
+
*
|
|
398
|
+
* Default is "none" so GSD works out of the box without preferences.md.
|
|
399
|
+
* Worktree isolation requires explicit opt-in because it depends on git
|
|
400
|
+
* branch infrastructure that must be set up before use.
|
|
389
401
|
*/
|
|
390
402
|
export function getIsolationMode() {
|
|
391
403
|
const prefs = loadEffectiveGSDPreferences()?.preferences?.git;
|
|
392
|
-
if (prefs?.isolation === "
|
|
393
|
-
return "
|
|
404
|
+
if (prefs?.isolation === "worktree")
|
|
405
|
+
return "worktree";
|
|
394
406
|
if (prefs?.isolation === "branch")
|
|
395
407
|
return "branch";
|
|
396
|
-
return "
|
|
408
|
+
return "none"; // default — no isolation, work on current branch
|
|
397
409
|
}
|
|
398
410
|
export function resolveParallelConfig(prefs) {
|
|
399
411
|
return {
|
|
@@ -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.
|
|
@@ -50,14 +50,14 @@ If all criteria have at least one remaining owning slice, the coverage check pas
|
|
|
50
50
|
|
|
51
51
|
**If the roadmap is still good:**
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
Use `gsd_reassess_roadmap` with `verdict: "roadmap-confirmed"`, an empty `sliceChanges` object, and the assessment text — the tool writes the assessment to the DB and renders `{{assessmentPath}}`. If requirements exist, explicitly note whether requirement coverage remains sound.
|
|
54
54
|
|
|
55
55
|
**If changes are needed:**
|
|
56
56
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
57
|
+
**Persist changes through `gsd_reassess_roadmap`.** Pass: `milestoneId`, `completedSliceId`, `verdict` (e.g. "roadmap-adjusted"), `assessment` (text explaining the decision), and `sliceChanges` with `modified` (array of sliceId, title, risk, depends, demo), `added` (same shape), `removed` (array of slice ID strings). The tool structurally enforces preservation of completed slices, writes the assessment to the DB, re-renders `{{roadmapPath}}`, and renders `{{assessmentPath}}`.
|
|
58
|
+
|
|
59
|
+
If `.gsd/REQUIREMENTS.md` exists and requirement ownership or status changed, update it.
|
|
60
|
+
|
|
61
|
+
{{commitInstruction}}
|
|
62
62
|
|
|
63
63
|
When done, say: "Roadmap reassessed."
|
|
@@ -32,19 +32,8 @@ Consider these captures when rewriting the remaining tasks — they represent th
|
|
|
32
32
|
|
|
33
33
|
1. Read the blocker task summary carefully. Understand exactly what was discovered and why it blocks the current plan.
|
|
34
34
|
2. Analyze the remaining `[ ]` tasks in the slice plan. Determine which are still valid, which need modification, and which should be replaced.
|
|
35
|
-
3. **Persist replan state through `gsd_replan_slice`.** Call it with
|
|
36
|
-
4.
|
|
37
|
-
|
|
38
|
-
- What changed in the plan and why
|
|
39
|
-
- Which incomplete tasks were modified, added, or removed
|
|
40
|
-
- Any new risks or considerations introduced by the replan
|
|
41
|
-
5. If using the degraded fallback, rewrite `{{planPath}}` with the updated slice plan:
|
|
42
|
-
- Keep all `[x]` tasks exactly as they were (same IDs, same descriptions, same checkmarks)
|
|
43
|
-
- Update the `[ ]` tasks to address the blocker
|
|
44
|
-
- Ensure the slice Goal and Demo sections are still achievable with the new tasks, or update them if the blocker fundamentally changes what the slice can deliver
|
|
45
|
-
- Update the Files Likely Touched section if the replan changes which files are affected
|
|
46
|
-
- If a DB-backed planning tool exists for this phase, use it as the source of truth and make any rewritten `PLAN.md` reflect that persisted state rather than bypassing it
|
|
47
|
-
6. If any incomplete task had a `T0x-PLAN.md`, remove or rewrite it to match the new task description.
|
|
48
|
-
7. Do not commit manually — the system auto-commits your changes after this unit completes.
|
|
35
|
+
3. **Persist replan state through `gsd_replan_slice`.** Call it with: `milestoneId`, `sliceId`, `blockerTaskId`, `blockerDescription`, `whatChanged`, `updatedTasks` (array of task objects with taskId, title, description, estimate, files, verify, inputs, expectedOutput), `removedTaskIds` (array of task ID strings). The tool structurally enforces preservation of completed tasks, writes replan history to the DB, re-renders `{{planPath}}`, and renders `{{replanPath}}`.
|
|
36
|
+
4. If any incomplete task had a `T0x-PLAN.md`, remove or rewrite it to match the new task description.
|
|
37
|
+
5. Do not commit manually — the system auto-commits your changes after this unit completes.
|
|
49
38
|
|
|
50
39
|
When done, say: "Slice {{sliceId}} replanned."
|