gsd-pi 2.44.0 → 2.45.0-dev.6b9da3e
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/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 +37 -36
- 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 +9 -6
- package/dist/resources/extensions/gsd/auto.js +30 -3
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +156 -0
- 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 +34 -16
- package/dist/resources/extensions/gsd/doctor.js +8 -0
- package/dist/resources/extensions/gsd/git-service.js +8 -3
- package/dist/resources/extensions/gsd/gsd-db.js +12 -1
- package/dist/resources/extensions/gsd/markdown-renderer.js +1 -1
- package/dist/resources/extensions/gsd/preferences.js +9 -1
- 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/worktree-manager.js +32 -2
- package/dist/resources/extensions/gsd/worktree-resolver.js +6 -0
- package/dist/resources/extensions/mcp-client/index.js +14 -0
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +8 -8
- 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 +8 -8
- 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/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/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/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.d.ts +11 -0
- package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.js +20 -1
- package/packages/pi-coding-agent/dist/core/model-registry.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/extensions/runner.test.ts +26 -26
- package/packages/pi-coding-agent/src/core/fs-utils.test.ts +31 -43
- package/packages/pi-coding-agent/src/core/local-model-check.ts +45 -0
- package/packages/pi-coding-agent/src/core/model-registry.ts +21 -1
- 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 +46 -48
- 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 +9 -6
- package/src/resources/extensions/gsd/auto.ts +37 -3
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +148 -0
- 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 +39 -17
- package/src/resources/extensions/gsd/doctor.ts +7 -1
- package/src/resources/extensions/gsd/git-service.ts +6 -2
- package/src/resources/extensions/gsd/gsd-db.ts +16 -1
- package/src/resources/extensions/gsd/markdown-renderer.ts +1 -1
- package/src/resources/extensions/gsd/preferences.ts +11 -1
- 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 +35 -36
- 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 +27 -0
- 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-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-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/worktree-manager.ts +43 -2
- package/src/resources/extensions/gsd/worktree-resolver.ts +7 -0
- package/src/resources/extensions/mcp-client/index.ts +20 -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_ → rzO54ZboyINyEt7cVM_uS}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{mgkxN0mGP6gSUmGPEzbk_ → rzO54ZboyINyEt7cVM_uS}/_ssgManifest.js +0 -0
|
@@ -1,14 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
// resolveSliceFile / extractUatType on real fixture files).
|
|
4
|
-
//
|
|
5
|
-
// Sections:
|
|
6
|
-
// (a)–(j) extractUatType classification (17 assertions from T01)
|
|
7
|
-
// (k) run-uat prompt template loading and content integrity (8 assertions)
|
|
8
|
-
// (l) dispatch precondition assertions via resolveSliceFile (4 assertions)
|
|
9
|
-
// (m) non-artifact UAT skip: human-experience UATs are not dispatched (1 assertion)
|
|
10
|
-
// (n) stale replay guard: existing UAT-RESULT never re-dispatches (1 assertion)
|
|
11
|
-
|
|
1
|
+
import { describe, test } from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
12
3
|
import { mkdtempSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
|
|
13
4
|
import { join, dirname } from 'node:path';
|
|
14
5
|
import { tmpdir } from 'node:os';
|
|
@@ -17,11 +8,6 @@ import { fileURLToPath } from 'node:url';
|
|
|
17
8
|
import { extractUatType } from '../files.ts';
|
|
18
9
|
import { resolveSliceFile } from '../paths.ts';
|
|
19
10
|
import { checkNeedsRunUat } from '../auto-prompts.ts';
|
|
20
|
-
import { createTestContext } from './test-helpers.ts';
|
|
21
|
-
|
|
22
|
-
// ─── Worktree-aware prompt loader ──────────────────────────────────────────
|
|
23
|
-
// Resolves prompts relative to this test file so the worktree copy is used
|
|
24
|
-
// instead of the main checkout copy (matches complete-milestone.test.ts pattern).
|
|
25
11
|
|
|
26
12
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
27
13
|
const worktreePromptsDir = join(__dirname, '..', 'prompts');
|
|
@@ -39,10 +25,6 @@ function loadPromptFromWorktree(name: string, vars: Record<string, string> = {})
|
|
|
39
25
|
return content.trim();
|
|
40
26
|
}
|
|
41
27
|
|
|
42
|
-
|
|
43
|
-
const { assertEq, assertTrue, report } = createTestContext();
|
|
44
|
-
// ─── Fixture helpers ───────────────────────────────────────────────────────
|
|
45
|
-
|
|
46
28
|
function createFixtureBase(): string {
|
|
47
29
|
const base = mkdtempSync(join(tmpdir(), 'gsd-run-uat-test-'));
|
|
48
30
|
mkdirSync(join(base, '.gsd', 'milestones'), { recursive: true });
|
|
@@ -69,154 +51,129 @@ function makeUatContent(mode: string): string {
|
|
|
69
51
|
return `# UAT File\n\n## UAT Type\n\n- UAT mode: ${mode}\n- Some other bullet: value\n`;
|
|
70
52
|
}
|
|
71
53
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
async function main(): Promise<void> {
|
|
77
|
-
|
|
78
|
-
// ─── (a) artifact-driven ──────────────────────────────────────────────────
|
|
79
|
-
console.log('\n── (a) artifact-driven');
|
|
80
|
-
|
|
81
|
-
assertEq(
|
|
54
|
+
describe('run-uat', () => {
|
|
55
|
+
test('(a) artifact-driven', () => {
|
|
56
|
+
assert.deepStrictEqual(
|
|
82
57
|
extractUatType(makeUatContent('artifact-driven')),
|
|
83
58
|
'artifact-driven',
|
|
84
59
|
'plain artifact-driven → artifact-driven',
|
|
85
60
|
);
|
|
86
|
-
|
|
87
|
-
assertEq(
|
|
61
|
+
assert.deepStrictEqual(
|
|
88
62
|
extractUatType('## UAT Type\n\n- UAT mode: artifact-driven\n'),
|
|
89
63
|
'artifact-driven',
|
|
90
64
|
'minimal content, artifact-driven',
|
|
91
65
|
);
|
|
66
|
+
});
|
|
92
67
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
assertEq(
|
|
68
|
+
test('(b) live-runtime', () => {
|
|
69
|
+
assert.deepStrictEqual(
|
|
97
70
|
extractUatType(makeUatContent('live-runtime')),
|
|
98
71
|
'live-runtime',
|
|
99
72
|
'plain live-runtime → live-runtime',
|
|
100
73
|
);
|
|
74
|
+
});
|
|
101
75
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
assertEq(
|
|
76
|
+
test('(c) human-experience', () => {
|
|
77
|
+
assert.deepStrictEqual(
|
|
106
78
|
extractUatType(makeUatContent('human-experience')),
|
|
107
79
|
'human-experience',
|
|
108
80
|
'plain human-experience → human-experience',
|
|
109
81
|
);
|
|
82
|
+
});
|
|
110
83
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
assertEq(
|
|
84
|
+
test('(d) mixed standalone', () => {
|
|
85
|
+
assert.deepStrictEqual(
|
|
115
86
|
extractUatType(makeUatContent('mixed')),
|
|
116
87
|
'mixed',
|
|
117
88
|
'plain mixed → mixed',
|
|
118
89
|
);
|
|
90
|
+
});
|
|
119
91
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
assertEq(
|
|
92
|
+
test('(e) mixed parenthetical', () => {
|
|
93
|
+
assert.deepStrictEqual(
|
|
124
94
|
extractUatType(makeUatContent('mixed (artifact-driven + live-runtime)')),
|
|
125
95
|
'mixed',
|
|
126
96
|
'mixed (artifact-driven + live-runtime) → mixed (leading keyword only)',
|
|
127
97
|
);
|
|
128
|
-
|
|
129
|
-
assertEq(
|
|
98
|
+
assert.deepStrictEqual(
|
|
130
99
|
extractUatType(makeUatContent('mixed (some other description)')),
|
|
131
100
|
'mixed',
|
|
132
101
|
'mixed with arbitrary parenthetical → mixed',
|
|
133
102
|
);
|
|
103
|
+
});
|
|
134
104
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
assertEq(
|
|
105
|
+
test('(f) missing UAT Type section', () => {
|
|
106
|
+
assert.deepStrictEqual(
|
|
139
107
|
extractUatType('# UAT File\n\n## Overview\n\nSome content.\n'),
|
|
140
108
|
undefined,
|
|
141
109
|
'no ## UAT Type section → undefined',
|
|
142
110
|
);
|
|
143
|
-
|
|
144
|
-
assertEq(
|
|
111
|
+
assert.deepStrictEqual(
|
|
145
112
|
extractUatType(''),
|
|
146
113
|
undefined,
|
|
147
114
|
'empty content → undefined',
|
|
148
115
|
);
|
|
116
|
+
});
|
|
149
117
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
assertEq(
|
|
118
|
+
test('(g) UAT Type section present, no UAT mode: bullet', () => {
|
|
119
|
+
assert.deepStrictEqual(
|
|
154
120
|
extractUatType('## UAT Type\n\n- Some other bullet: value\n- Another bullet\n'),
|
|
155
121
|
undefined,
|
|
156
122
|
'section present but no UAT mode: bullet → undefined',
|
|
157
123
|
);
|
|
158
|
-
|
|
159
|
-
assertEq(
|
|
124
|
+
assert.deepStrictEqual(
|
|
160
125
|
extractUatType('## UAT Type\n\n'),
|
|
161
126
|
undefined,
|
|
162
127
|
'section present but empty → undefined',
|
|
163
128
|
);
|
|
129
|
+
});
|
|
164
130
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
assertEq(
|
|
131
|
+
test('(h) unknown keyword', () => {
|
|
132
|
+
assert.deepStrictEqual(
|
|
169
133
|
extractUatType(makeUatContent('automated')),
|
|
170
134
|
undefined,
|
|
171
135
|
'unknown keyword automated → undefined',
|
|
172
136
|
);
|
|
173
|
-
|
|
174
|
-
assertEq(
|
|
137
|
+
assert.deepStrictEqual(
|
|
175
138
|
extractUatType(makeUatContent('fully-automated')),
|
|
176
139
|
undefined,
|
|
177
140
|
'unknown keyword fully-automated → undefined',
|
|
178
141
|
);
|
|
142
|
+
});
|
|
179
143
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
assertEq(
|
|
144
|
+
test('(i) extra whitespace', () => {
|
|
145
|
+
assert.deepStrictEqual(
|
|
184
146
|
extractUatType('## UAT Type\n\n- UAT mode: artifact-driven \n'),
|
|
185
147
|
'artifact-driven',
|
|
186
148
|
'leading/trailing whitespace around value → still classified correctly',
|
|
187
149
|
);
|
|
188
|
-
|
|
189
|
-
assertEq(
|
|
150
|
+
assert.deepStrictEqual(
|
|
190
151
|
extractUatType('## UAT Type\n\n- UAT mode: mixed (artifact-driven + live-runtime) \n'),
|
|
191
152
|
'mixed',
|
|
192
153
|
'whitespace around mixed parenthetical → mixed',
|
|
193
154
|
);
|
|
155
|
+
});
|
|
194
156
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
assertEq(
|
|
157
|
+
test('(j) case sensitivity', () => {
|
|
158
|
+
assert.deepStrictEqual(
|
|
199
159
|
extractUatType(makeUatContent('Artifact-Driven')),
|
|
200
160
|
'artifact-driven',
|
|
201
161
|
'Artifact-Driven (title case) → artifact-driven (function lowercases before matching)',
|
|
202
162
|
);
|
|
203
|
-
|
|
204
|
-
assertEq(
|
|
163
|
+
assert.deepStrictEqual(
|
|
205
164
|
extractUatType(makeUatContent('MIXED')),
|
|
206
165
|
'mixed',
|
|
207
166
|
'MIXED (upper case) → mixed (function lowercases before matching)',
|
|
208
167
|
);
|
|
168
|
+
});
|
|
209
169
|
|
|
210
|
-
|
|
211
|
-
console.log('\n── (k) run-uat prompt template');
|
|
212
|
-
|
|
170
|
+
test('(k) run-uat prompt template', () => {
|
|
213
171
|
const milestoneId = 'M001';
|
|
214
172
|
const sliceId = 'S01';
|
|
215
173
|
const uatPath = '.gsd/milestones/M001/slices/S01/S01-UAT.md';
|
|
216
174
|
const uatResultPath = '.gsd/milestones/M001/slices/S01/S01-UAT-RESULT.md';
|
|
217
175
|
const uatType = 'live-runtime';
|
|
218
176
|
const inlinedContext = '<!-- no context -->';
|
|
219
|
-
|
|
220
177
|
let promptResult: string | undefined;
|
|
221
178
|
let promptThrew = false;
|
|
222
179
|
try {
|
|
@@ -232,71 +189,66 @@ async function main(): Promise<void> {
|
|
|
232
189
|
} catch {
|
|
233
190
|
promptThrew = true;
|
|
234
191
|
}
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
assertTrue(
|
|
192
|
+
assert.ok(!promptThrew, 'loadPromptFromWorktree("run-uat", vars) does not throw');
|
|
193
|
+
assert.ok(
|
|
238
194
|
typeof promptResult === 'string' && promptResult.length > 0,
|
|
239
195
|
'run-uat prompt result is a non-empty string',
|
|
240
196
|
);
|
|
241
|
-
|
|
197
|
+
assert.ok(
|
|
242
198
|
promptResult?.includes(milestoneId) ?? false,
|
|
243
199
|
`prompt contains milestoneId value "${milestoneId}" after substitution`,
|
|
244
200
|
);
|
|
245
|
-
|
|
201
|
+
assert.ok(
|
|
246
202
|
promptResult?.includes(sliceId) ?? false,
|
|
247
203
|
`prompt contains sliceId value "${sliceId}" after substitution`,
|
|
248
204
|
);
|
|
249
|
-
|
|
205
|
+
assert.ok(
|
|
250
206
|
promptResult?.includes(uatResultPath) ?? false,
|
|
251
207
|
`prompt contains uatResultPath value after substitution`,
|
|
252
208
|
);
|
|
253
|
-
|
|
209
|
+
assert.ok(
|
|
254
210
|
promptResult?.includes(`Detected UAT mode:** \`${uatType}\``) ?? false,
|
|
255
211
|
`prompt contains detected dynamic uatType value "${uatType}" after substitution`,
|
|
256
212
|
);
|
|
257
|
-
|
|
213
|
+
assert.ok(
|
|
258
214
|
promptResult?.includes(`uatType: ${uatType}`) ?? false,
|
|
259
215
|
`prompt contains dynamic uatType frontmatter value "${uatType}" after substitution`,
|
|
260
216
|
);
|
|
261
|
-
|
|
217
|
+
assert.ok(
|
|
262
218
|
!/\{\{[^}]+\}\}/.test(promptResult ?? ''),
|
|
263
219
|
'no unreplaced {{...}} tokens remain after variable substitution',
|
|
264
220
|
);
|
|
265
|
-
|
|
221
|
+
assert.ok(
|
|
266
222
|
/browser|runtime|execute|run/i.test(promptResult ?? ''),
|
|
267
223
|
'prompt contains runtime execution language (browser/runtime/execute/run)',
|
|
268
224
|
);
|
|
269
|
-
|
|
225
|
+
assert.ok(
|
|
270
226
|
!/surfaced for human review/i.test(promptResult ?? ''),
|
|
271
227
|
'prompt does not contain "surfaced for human review" (non-artifact UATs are skipped, not dispatched)',
|
|
272
228
|
);
|
|
229
|
+
});
|
|
273
230
|
|
|
274
|
-
|
|
275
|
-
console.log('\n── (l) dispatch preconditions via resolveSliceFile');
|
|
276
|
-
|
|
277
|
-
// State A: UAT file exists, UAT-RESULT file does NOT — triggers dispatch
|
|
278
|
-
{
|
|
231
|
+
test('(l) dispatch preconditions via resolveSliceFile', () => {
|
|
279
232
|
const base = createFixtureBase();
|
|
280
233
|
const uatContent = makeUatContent('artifact-driven');
|
|
281
234
|
try {
|
|
282
235
|
writeSliceFile(base, 'M001', 'S01', 'UAT', uatContent);
|
|
283
236
|
|
|
284
237
|
const uatFilePath = resolveSliceFile(base, 'M001', 'S01', 'UAT');
|
|
285
|
-
|
|
238
|
+
assert.ok(
|
|
286
239
|
uatFilePath !== null,
|
|
287
240
|
'resolveSliceFile(..., "UAT") returns non-null when UAT file exists (dispatch trigger state)',
|
|
288
241
|
);
|
|
289
242
|
|
|
290
243
|
const uatResultFilePath = resolveSliceFile(base, 'M001', 'S01', 'UAT-RESULT');
|
|
291
|
-
|
|
244
|
+
assert.deepStrictEqual(
|
|
292
245
|
uatResultFilePath,
|
|
293
246
|
null,
|
|
294
247
|
'resolveSliceFile(..., "UAT-RESULT") returns null when result file missing (dispatch trigger state)',
|
|
295
248
|
);
|
|
296
249
|
|
|
297
|
-
// End-to-end: file content → parse → classify
|
|
298
250
|
const rawContent = readFileSync(uatFilePath!, 'utf-8');
|
|
299
|
-
|
|
251
|
+
assert.deepStrictEqual(
|
|
300
252
|
extractUatType(rawContent),
|
|
301
253
|
'artifact-driven',
|
|
302
254
|
'extractUatType on fixture UAT file returns expected type (end-to-end data flow)',
|
|
@@ -304,29 +256,25 @@ async function main(): Promise<void> {
|
|
|
304
256
|
} finally {
|
|
305
257
|
cleanup(base);
|
|
306
258
|
}
|
|
307
|
-
|
|
259
|
+
});
|
|
308
260
|
|
|
309
|
-
|
|
310
|
-
{
|
|
261
|
+
test('test block at line 307', () => {
|
|
311
262
|
const base = createFixtureBase();
|
|
312
263
|
try {
|
|
313
264
|
writeSliceFile(base, 'M001', 'S01', 'UAT', makeUatContent('artifact-driven'));
|
|
314
265
|
writeSliceFile(base, 'M001', 'S01', 'UAT-RESULT', '# UAT Result\n\nverdict: PASS\n');
|
|
315
266
|
|
|
316
267
|
const uatResultFilePath = resolveSliceFile(base, 'M001', 'S01', 'UAT-RESULT');
|
|
317
|
-
|
|
268
|
+
assert.ok(
|
|
318
269
|
uatResultFilePath !== null,
|
|
319
270
|
'resolveSliceFile(..., "UAT-RESULT") returns non-null when result file exists (idempotent skip state)',
|
|
320
271
|
);
|
|
321
272
|
} finally {
|
|
322
273
|
cleanup(base);
|
|
323
274
|
}
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
// ─── (m) non-artifact UATs are skipped (not dispatched) ─────────────────
|
|
327
|
-
console.log('\n── (m) non-artifact UAT skip');
|
|
275
|
+
});
|
|
328
276
|
|
|
329
|
-
|
|
277
|
+
test('(m) non-artifact UAT skip', async () => {
|
|
330
278
|
const base = createFixtureBase();
|
|
331
279
|
try {
|
|
332
280
|
const roadmapDir = join(base, '.gsd', 'milestones', 'M001');
|
|
@@ -346,7 +294,6 @@ async function main(): Promise<void> {
|
|
|
346
294
|
].join('\n'),
|
|
347
295
|
);
|
|
348
296
|
|
|
349
|
-
// human-experience UAT still dispatches, but auto-mode later pauses for manual review
|
|
350
297
|
writeSliceFile(base, 'M001', 'S01', 'UAT', makeUatContent('human-experience'));
|
|
351
298
|
|
|
352
299
|
const state = {
|
|
@@ -361,7 +308,7 @@ async function main(): Promise<void> {
|
|
|
361
308
|
} as const;
|
|
362
309
|
|
|
363
310
|
const result = await checkNeedsRunUat(base, 'M001', state as any, { uat_dispatch: true } as any);
|
|
364
|
-
|
|
311
|
+
assert.deepStrictEqual(
|
|
365
312
|
result,
|
|
366
313
|
{ sliceId: 'S01', uatType: 'human-experience' },
|
|
367
314
|
'human-experience UAT dispatches so auto-mode can pause for manual review',
|
|
@@ -369,12 +316,9 @@ async function main(): Promise<void> {
|
|
|
369
316
|
} finally {
|
|
370
317
|
cleanup(base);
|
|
371
318
|
}
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
// ─── (n) existing UAT-RESULT never re-dispatches ──────────────────────
|
|
375
|
-
console.log('\n── (n) stale replay guard');
|
|
319
|
+
});
|
|
376
320
|
|
|
377
|
-
|
|
321
|
+
test('(n) stale replay guard', async () => {
|
|
378
322
|
const base = createFixtureBase();
|
|
379
323
|
try {
|
|
380
324
|
const roadmapDir = join(base, '.gsd', 'milestones', 'M001');
|
|
@@ -409,7 +353,7 @@ async function main(): Promise<void> {
|
|
|
409
353
|
} as const;
|
|
410
354
|
|
|
411
355
|
const result = await checkNeedsRunUat(base, 'M001', state as any, { uat_dispatch: true } as any);
|
|
412
|
-
|
|
356
|
+
assert.deepStrictEqual(
|
|
413
357
|
result,
|
|
414
358
|
null,
|
|
415
359
|
'existing UAT-RESULT with FAIL verdict does not re-dispatch; verdict gate owns blocking',
|
|
@@ -417,12 +361,6 @@ async function main(): Promise<void> {
|
|
|
417
361
|
} finally {
|
|
418
362
|
cleanup(base);
|
|
419
363
|
}
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
report();
|
|
423
|
-
}
|
|
364
|
+
});
|
|
424
365
|
|
|
425
|
-
main().catch((error) => {
|
|
426
|
-
console.error(error);
|
|
427
|
-
process.exit(1);
|
|
428
366
|
});
|
|
@@ -20,11 +20,11 @@ import {
|
|
|
20
20
|
_getRegisteredLockDirs,
|
|
21
21
|
} from '../session-lock.ts';
|
|
22
22
|
import { gsdRoot } from '../paths.ts';
|
|
23
|
-
import {
|
|
23
|
+
import { describe, test } from 'node:test';
|
|
24
|
+
import assert from 'node:assert/strict';
|
|
24
25
|
|
|
25
|
-
const { assertEq, assertTrue, report } = createTestContext();
|
|
26
26
|
|
|
27
|
-
async
|
|
27
|
+
describe('session-lock-multipath', async () => {
|
|
28
28
|
|
|
29
29
|
// ─── 1. Lock dir registry tracks gsdDir on acquisition ──────────────────
|
|
30
30
|
console.log('\n=== 1. Lock dir registry tracks gsdDir on acquisition ===');
|
|
@@ -34,17 +34,17 @@ async function main(): Promise<void> {
|
|
|
34
34
|
|
|
35
35
|
try {
|
|
36
36
|
const result = acquireSessionLock(base);
|
|
37
|
-
|
|
37
|
+
assert.ok(result.acquired, 'lock acquired');
|
|
38
38
|
|
|
39
39
|
const registered = _getRegisteredLockDirs();
|
|
40
40
|
const gsdDir = gsdRoot(base);
|
|
41
|
-
|
|
41
|
+
assert.ok(registered.includes(gsdDir), 'gsdDir is registered in lock dir registry');
|
|
42
42
|
|
|
43
43
|
releaseSessionLock(base);
|
|
44
44
|
|
|
45
45
|
// After release, registry should be cleared
|
|
46
46
|
const afterRelease = _getRegisteredLockDirs();
|
|
47
|
-
|
|
47
|
+
assert.deepStrictEqual(afterRelease.length, 0, 'lock dir registry cleared after release');
|
|
48
48
|
} finally {
|
|
49
49
|
rmSync(base, { recursive: true, force: true });
|
|
50
50
|
}
|
|
@@ -62,7 +62,7 @@ async function main(): Promise<void> {
|
|
|
62
62
|
|
|
63
63
|
try {
|
|
64
64
|
const result = acquireSessionLock(base);
|
|
65
|
-
|
|
65
|
+
assert.ok(result.acquired, 'lock acquired');
|
|
66
66
|
|
|
67
67
|
// Manually plant a stale lock file at the secondary path to simulate
|
|
68
68
|
// multi-path lock accumulation
|
|
@@ -72,8 +72,8 @@ async function main(): Promise<void> {
|
|
|
72
72
|
mkdirSync(secondaryLockDir, { recursive: true });
|
|
73
73
|
|
|
74
74
|
// Verify they exist before release
|
|
75
|
-
|
|
76
|
-
|
|
75
|
+
assert.ok(existsSync(secondaryLockFile), 'secondary lock file exists before release');
|
|
76
|
+
assert.ok(existsSync(secondaryLockDir), 'secondary lock dir exists before release');
|
|
77
77
|
|
|
78
78
|
// Manually add the secondary dir to the registry (simulating ensureExitHandler call)
|
|
79
79
|
// We do this by acquiring knowledge of internals — the registry is populated
|
|
@@ -83,10 +83,10 @@ async function main(): Promise<void> {
|
|
|
83
83
|
|
|
84
84
|
// Primary lock artifacts should be cleaned
|
|
85
85
|
const primaryLockFile = join(gsdRoot(base), 'auto.lock');
|
|
86
|
-
|
|
86
|
+
assert.ok(!existsSync(primaryLockFile), 'primary auto.lock removed after release');
|
|
87
87
|
|
|
88
88
|
const primaryLockDir = gsdRoot(base) + '.lock';
|
|
89
|
-
|
|
89
|
+
assert.ok(!existsSync(primaryLockDir), 'primary .gsd.lock/ removed after release');
|
|
90
90
|
} finally {
|
|
91
91
|
rmSync(base, { recursive: true, force: true });
|
|
92
92
|
}
|
|
@@ -106,7 +106,7 @@ async function main(): Promise<void> {
|
|
|
106
106
|
const gsdDir = gsdRoot(base);
|
|
107
107
|
// Should only appear once (Set deduplication)
|
|
108
108
|
const count = registered.filter(d => d === gsdDir).length;
|
|
109
|
-
|
|
109
|
+
assert.deepStrictEqual(count, 1, 'gsdDir registered exactly once after re-entrant acquisition');
|
|
110
110
|
|
|
111
111
|
releaseSessionLock(base);
|
|
112
112
|
} finally {
|
|
@@ -124,17 +124,17 @@ async function main(): Promise<void> {
|
|
|
124
124
|
|
|
125
125
|
try {
|
|
126
126
|
const r1 = acquireSessionLock(base1);
|
|
127
|
-
|
|
127
|
+
assert.ok(r1.acquired, 'first base lock acquired');
|
|
128
128
|
|
|
129
129
|
// Release first to acquire second (module state is single-lock)
|
|
130
130
|
releaseSessionLock(base1);
|
|
131
131
|
|
|
132
132
|
const r2 = acquireSessionLock(base2);
|
|
133
|
-
|
|
133
|
+
assert.ok(r2.acquired, 'second base lock acquired');
|
|
134
134
|
|
|
135
135
|
const registered = _getRegisteredLockDirs();
|
|
136
136
|
const gsd2 = gsdRoot(base2);
|
|
137
|
-
|
|
137
|
+
assert.ok(registered.includes(gsd2), 'second gsdDir is registered');
|
|
138
138
|
|
|
139
139
|
releaseSessionLock(base2);
|
|
140
140
|
} finally {
|
|
@@ -156,18 +156,11 @@ async function main(): Promise<void> {
|
|
|
156
156
|
// Verify everything is clean
|
|
157
157
|
const lockFile = join(gsdRoot(base), 'auto.lock');
|
|
158
158
|
const lockDir = gsdRoot(base) + '.lock';
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
159
|
+
assert.ok(!existsSync(lockFile), 'auto.lock cleaned');
|
|
160
|
+
assert.ok(!existsSync(lockDir), '.gsd.lock/ cleaned');
|
|
161
|
+
assert.deepStrictEqual(_getRegisteredLockDirs().length, 0, 'registry empty');
|
|
162
162
|
} finally {
|
|
163
163
|
rmSync(base, { recursive: true, force: true });
|
|
164
164
|
}
|
|
165
165
|
}
|
|
166
|
-
|
|
167
|
-
report();
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
main().catch((error) => {
|
|
171
|
-
console.error(error);
|
|
172
|
-
process.exit(1);
|
|
173
166
|
});
|