gsd-pi 2.44.0 → 2.45.0-dev.1afbdaa
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 +63 -77
- package/dist/resources/extensions/gsd/auto/run-unit.js +6 -3
- package/dist/resources/extensions/gsd/auto/session.js +0 -11
- package/dist/resources/extensions/gsd/auto-artifact-paths.js +112 -0
- package/dist/resources/extensions/gsd/auto-post-unit.js +25 -96
- package/dist/resources/extensions/gsd/auto-prompts.js +24 -1
- package/dist/resources/extensions/gsd/auto-start.js +33 -5
- 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 +42 -60
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +170 -11
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +18 -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/context.js +0 -4
- 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/parallel.js +1 -1
- 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/crash-recovery.js +2 -4
- package/dist/resources/extensions/gsd/dashboard-overlay.js +0 -44
- package/dist/resources/extensions/gsd/db-writer.js +40 -22
- package/dist/resources/extensions/gsd/doctor-checks.js +167 -2
- package/dist/resources/extensions/gsd/doctor.js +13 -3
- package/dist/resources/extensions/gsd/git-service.js +8 -3
- package/dist/resources/extensions/gsd/gsd-db.js +28 -4
- package/dist/resources/extensions/gsd/guided-flow.js +1 -2
- package/dist/resources/extensions/gsd/markdown-renderer.js +1 -1
- package/dist/resources/extensions/gsd/parallel-merge.js +1 -1
- package/dist/resources/extensions/gsd/parallel-orchestrator.js +5 -18
- 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 +21 -10
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +10 -23
- package/dist/resources/extensions/gsd/prompts/discuss.md +2 -2
- package/dist/resources/extensions/gsd/prompts/execute-task.md +5 -15
- package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/guided-plan-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/guided-research-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +5 -3
- package/dist/resources/extensions/gsd/prompts/queue.md +2 -2
- package/dist/resources/extensions/gsd/prompts/quick-task.md +2 -0
- package/dist/resources/extensions/gsd/prompts/reactive-execute.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/research-slice.md +3 -3
- package/dist/resources/extensions/gsd/prompts/rethink.md +83 -0
- package/dist/resources/extensions/gsd/prompts/system.md +1 -1
- 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/session-lock.js +1 -3
- package/dist/resources/extensions/gsd/state.js +48 -3
- package/dist/resources/extensions/gsd/sync-lock.js +89 -0
- package/dist/resources/extensions/gsd/tools/complete-milestone.js +61 -11
- package/dist/resources/extensions/gsd/tools/complete-slice.js +56 -11
- package/dist/resources/extensions/gsd/tools/complete-task.js +50 -2
- package/dist/resources/extensions/gsd/tools/plan-milestone.js +37 -1
- package/dist/resources/extensions/gsd/tools/plan-slice.js +31 -1
- package/dist/resources/extensions/gsd/tools/plan-task.js +28 -1
- package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +32 -2
- package/dist/resources/extensions/gsd/tools/reopen-slice.js +86 -0
- package/dist/resources/extensions/gsd/tools/reopen-task.js +90 -0
- package/dist/resources/extensions/gsd/tools/replan-slice.js +34 -2
- package/dist/resources/extensions/gsd/tools/validate-milestone.js +88 -0
- package/dist/resources/extensions/gsd/unit-ownership.js +85 -0
- package/dist/resources/extensions/gsd/workflow-events.js +102 -0
- package/dist/resources/extensions/gsd/workflow-logger.js +193 -0
- package/dist/resources/extensions/gsd/workflow-manifest.js +244 -0
- package/dist/resources/extensions/gsd/workflow-migration.js +280 -0
- package/dist/resources/extensions/gsd/workflow-projections.js +373 -0
- package/dist/resources/extensions/gsd/workflow-reconcile.js +411 -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/gsd/write-intercept.js +84 -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 +12 -12
- 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 +12 -12
- 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 +2 -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/loop-deps.ts +0 -19
- package/src/resources/extensions/gsd/auto/phases.ts +69 -91
- package/src/resources/extensions/gsd/auto/run-unit.ts +6 -3
- package/src/resources/extensions/gsd/auto/session.ts +0 -18
- package/src/resources/extensions/gsd/auto-artifact-paths.ts +131 -0
- package/src/resources/extensions/gsd/auto-dashboard.ts +0 -1
- package/src/resources/extensions/gsd/auto-post-unit.ts +25 -106
- package/src/resources/extensions/gsd/auto-prompts.ts +24 -1
- package/src/resources/extensions/gsd/auto-start.ts +40 -5
- 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 +44 -86
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +162 -11
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +22 -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/context.ts +0 -5
- 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/parallel.ts +1 -1
- 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/crash-recovery.ts +1 -5
- package/src/resources/extensions/gsd/dashboard-overlay.ts +0 -50
- package/src/resources/extensions/gsd/db-writer.ts +41 -27
- package/src/resources/extensions/gsd/doctor-checks.ts +180 -2
- package/src/resources/extensions/gsd/doctor-types.ts +7 -1
- package/src/resources/extensions/gsd/doctor.ts +13 -4
- package/src/resources/extensions/gsd/git-service.ts +6 -2
- package/src/resources/extensions/gsd/gsd-db.ts +32 -4
- package/src/resources/extensions/gsd/guided-flow.ts +1 -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/parallel-merge.ts +1 -1
- package/src/resources/extensions/gsd/parallel-orchestrator.ts +5 -21
- 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 +21 -10
- package/src/resources/extensions/gsd/prompts/complete-slice.md +10 -23
- package/src/resources/extensions/gsd/prompts/discuss.md +2 -2
- package/src/resources/extensions/gsd/prompts/execute-task.md +5 -15
- package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/guided-plan-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/guided-research-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/plan-slice.md +5 -3
- package/src/resources/extensions/gsd/prompts/queue.md +2 -2
- package/src/resources/extensions/gsd/prompts/quick-task.md +2 -0
- package/src/resources/extensions/gsd/prompts/reactive-execute.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/research-slice.md +3 -3
- package/src/resources/extensions/gsd/prompts/rethink.md +83 -0
- package/src/resources/extensions/gsd/prompts/system.md +1 -1
- 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/session-lock.ts +0 -4
- package/src/resources/extensions/gsd/state.ts +49 -1
- package/src/resources/extensions/gsd/sync-lock.ts +94 -0
- 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 +19 -29
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +6 -10
- 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 +134 -59
- package/src/resources/extensions/gsd/tests/complete-slice.test.ts +15 -14
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +27 -12
- 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 +26 -40
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +0 -3
- 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 +82 -103
- 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 +33 -42
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +0 -3
- 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 +81 -94
- 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/milestone-transition-state-rebuild.test.ts +8 -9
- 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-budget-atomicity.test.ts +0 -1
- package/src/resources/extensions/gsd/tests/parallel-crash-recovery.test.ts +39 -53
- package/src/resources/extensions/gsd/tests/parallel-merge.test.ts +7 -8
- package/src/resources/extensions/gsd/tests/parallel-orchestration.test.ts +20 -24
- package/src/resources/extensions/gsd/tests/parallel-worker-monitoring.test.ts +24 -29
- 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/plan-milestone.test.ts +9 -6
- package/src/resources/extensions/gsd/tests/post-mutation-hook.test.ts +171 -0
- 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/projection-regression.test.ts +174 -0
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +26 -21
- 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/reopen-slice.test.ts +155 -0
- package/src/resources/extensions/gsd/tests/reopen-task.test.ts +165 -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 -47
- 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/stop-auto-remote.test.ts +2 -3
- 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/sync-lock.test.ts +122 -0
- 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-ownership.test.ts +175 -0
- 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-events.test.ts +205 -0
- package/src/resources/extensions/gsd/tests/workflow-logger.test.ts +275 -0
- package/src/resources/extensions/gsd/tests/workflow-manifest.test.ts +186 -0
- package/src/resources/extensions/gsd/tests/workflow-projections.test.ts +171 -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/tests/write-intercept.test.ts +76 -0
- package/src/resources/extensions/gsd/tools/complete-milestone.ts +74 -11
- package/src/resources/extensions/gsd/tools/complete-slice.ts +68 -11
- package/src/resources/extensions/gsd/tools/complete-task.ts +63 -1
- package/src/resources/extensions/gsd/tools/plan-milestone.ts +45 -0
- package/src/resources/extensions/gsd/tools/plan-slice.ts +40 -0
- package/src/resources/extensions/gsd/tools/plan-task.ts +37 -1
- package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +39 -1
- package/src/resources/extensions/gsd/tools/reopen-slice.ts +125 -0
- package/src/resources/extensions/gsd/tools/reopen-task.ts +129 -0
- package/src/resources/extensions/gsd/tools/replan-slice.ts +41 -1
- package/src/resources/extensions/gsd/tools/validate-milestone.ts +127 -0
- package/src/resources/extensions/gsd/types.ts +8 -0
- package/src/resources/extensions/gsd/unit-ownership.ts +104 -0
- package/src/resources/extensions/gsd/workflow-events.ts +154 -0
- package/src/resources/extensions/gsd/workflow-logger.ts +243 -0
- package/src/resources/extensions/gsd/workflow-manifest.ts +334 -0
- package/src/resources/extensions/gsd/workflow-migration.ts +345 -0
- package/src/resources/extensions/gsd/workflow-projections.ts +425 -0
- package/src/resources/extensions/gsd/workflow-reconcile.ts +503 -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/gsd/write-intercept.ts +90 -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_ → j-BskPs0nxxPeYY-bSrab}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{mgkxN0mGP6gSUmGPEzbk_ → j-BskPs0nxxPeYY-bSrab}/_ssgManifest.js +0 -0
|
@@ -17,9 +17,9 @@ import {
|
|
|
17
17
|
} from "../worktree.ts";
|
|
18
18
|
import { readIntegrationBranch } from "../git-service.ts";
|
|
19
19
|
import { _resetHasChangesCache } from "../native-git-bridge.ts";
|
|
20
|
-
import {
|
|
20
|
+
import { describe, test } from 'node:test';
|
|
21
|
+
import assert from 'node:assert/strict';
|
|
21
22
|
|
|
22
|
-
const { assertEq, assertTrue, report } = createTestContext();
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
25
|
* Normalize a path for reliable comparison on Windows CI runners.
|
|
@@ -47,56 +47,56 @@ writeFileSync(join(base, ".gsd", "milestones", "M001", "slices", "S01", "S01-PLA
|
|
|
47
47
|
run("git add .", base);
|
|
48
48
|
run('git commit -m "chore: init"', base);
|
|
49
49
|
|
|
50
|
-
async
|
|
50
|
+
describe('worktree', async () => {
|
|
51
51
|
|
|
52
52
|
console.log("\n=== autoCommitCurrentBranch ===");
|
|
53
53
|
// Clean — should return null
|
|
54
54
|
const cleanResult = autoCommitCurrentBranch(base, "execute-task", "M001/S01/T01");
|
|
55
|
-
|
|
55
|
+
assert.deepStrictEqual(cleanResult, null, "returns null for clean repo");
|
|
56
56
|
|
|
57
57
|
// Make dirty — reset the nativeHasChanges cache so the fresh dirt is detected
|
|
58
58
|
_resetHasChangesCache();
|
|
59
59
|
writeFileSync(join(base, "dirty.txt"), "uncommitted\n", "utf-8");
|
|
60
60
|
const dirtyResult = autoCommitCurrentBranch(base, "execute-task", "M001/S01/T01");
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
61
|
+
assert.ok(dirtyResult !== null, "returns commit message for dirty repo");
|
|
62
|
+
assert.ok(dirtyResult!.includes("M001/S01/T01"), "commit message includes unit id");
|
|
63
|
+
assert.deepStrictEqual(run("git status --short", base), "", "repo is clean after auto-commit");
|
|
64
64
|
|
|
65
65
|
console.log("\n=== getSliceBranchName ===");
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
66
|
+
assert.deepStrictEqual(getSliceBranchName("M001", "S01"), "gsd/M001/S01", "branch name format correct");
|
|
67
|
+
assert.deepStrictEqual(getSliceBranchName("M001", "S01", null), "gsd/M001/S01", "null worktree = plain branch");
|
|
68
|
+
assert.deepStrictEqual(getSliceBranchName("M001", "S01", "my-wt"), "gsd/my-wt/M001/S01", "worktree-namespaced branch");
|
|
69
69
|
|
|
70
70
|
console.log("\n=== parseSliceBranch ===");
|
|
71
71
|
const plain = parseSliceBranch("gsd/M001/S01");
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
72
|
+
assert.ok(plain !== null, "parses plain branch");
|
|
73
|
+
assert.deepStrictEqual(plain!.worktreeName, null, "plain branch has no worktree name");
|
|
74
|
+
assert.deepStrictEqual(plain!.milestoneId, "M001", "plain branch milestone");
|
|
75
|
+
assert.deepStrictEqual(plain!.sliceId, "S01", "plain branch slice");
|
|
76
76
|
|
|
77
77
|
const namespaced = parseSliceBranch("gsd/feature-auth/M001/S01");
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
78
|
+
assert.ok(namespaced !== null, "parses worktree-namespaced branch");
|
|
79
|
+
assert.deepStrictEqual(namespaced!.worktreeName, "feature-auth", "worktree name extracted");
|
|
80
|
+
assert.deepStrictEqual(namespaced!.milestoneId, "M001", "namespaced branch milestone");
|
|
81
|
+
assert.deepStrictEqual(namespaced!.sliceId, "S01", "namespaced branch slice");
|
|
82
82
|
|
|
83
83
|
const invalid = parseSliceBranch("main");
|
|
84
|
-
|
|
84
|
+
assert.deepStrictEqual(invalid, null, "non-slice branch returns null");
|
|
85
85
|
|
|
86
86
|
const worktreeBranch = parseSliceBranch("worktree/foo");
|
|
87
|
-
|
|
87
|
+
assert.deepStrictEqual(worktreeBranch, null, "worktree/ prefix is not a slice branch");
|
|
88
88
|
|
|
89
89
|
console.log("\n=== SLICE_BRANCH_RE ===");
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
90
|
+
assert.ok(SLICE_BRANCH_RE.test("gsd/M001/S01"), "regex matches plain branch");
|
|
91
|
+
assert.ok(SLICE_BRANCH_RE.test("gsd/my-wt/M001/S01"), "regex matches worktree branch");
|
|
92
|
+
assert.ok(!SLICE_BRANCH_RE.test("main"), "regex rejects main");
|
|
93
|
+
assert.ok(!SLICE_BRANCH_RE.test("gsd/"), "regex rejects bare gsd/");
|
|
94
|
+
assert.ok(!SLICE_BRANCH_RE.test("worktree/foo"), "regex rejects worktree/foo");
|
|
95
95
|
|
|
96
96
|
console.log("\n=== detectWorktreeName ===");
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
97
|
+
assert.deepStrictEqual(detectWorktreeName("/projects/myapp"), null, "no worktree in plain path");
|
|
98
|
+
assert.deepStrictEqual(detectWorktreeName("/projects/myapp/.gsd/worktrees/feature-auth"), "feature-auth", "detects worktree name");
|
|
99
|
+
assert.deepStrictEqual(detectWorktreeName("/projects/myapp/.gsd/worktrees/my-wt/subdir"), "my-wt", "detects worktree with subdir");
|
|
100
100
|
|
|
101
101
|
// ═══════════════════════════════════════════════════════════════════════
|
|
102
102
|
// Integration branch — facade-level tests
|
|
@@ -115,16 +115,16 @@ async function main(): Promise<void> {
|
|
|
115
115
|
run("git add -A && git commit -m init", repo);
|
|
116
116
|
|
|
117
117
|
run("git checkout -b f-123-thing", repo);
|
|
118
|
-
|
|
118
|
+
assert.deepStrictEqual(getCurrentBranch(repo), "f-123-thing", "on feature branch");
|
|
119
119
|
|
|
120
120
|
const commitsBefore = run("git rev-list --count HEAD", repo);
|
|
121
121
|
captureIntegrationBranch(repo, "M001");
|
|
122
|
-
|
|
122
|
+
assert.deepStrictEqual(readIntegrationBranch(repo, "M001"), "f-123-thing",
|
|
123
123
|
"captureIntegrationBranch records the current branch");
|
|
124
124
|
|
|
125
125
|
// Metadata is stored in external state, not committed to git.
|
|
126
126
|
const commitsAfter = run("git rev-list --count HEAD", repo);
|
|
127
|
-
|
|
127
|
+
assert.deepStrictEqual(commitsAfter, commitsBefore, "captureIntegrationBranch does not create a git commit");
|
|
128
128
|
|
|
129
129
|
rmSync(repo, { recursive: true, force: true });
|
|
130
130
|
}
|
|
@@ -144,7 +144,7 @@ async function main(): Promise<void> {
|
|
|
144
144
|
run("git checkout -b gsd/M001/S01", repo);
|
|
145
145
|
captureIntegrationBranch(repo, "M001");
|
|
146
146
|
|
|
147
|
-
|
|
147
|
+
assert.deepStrictEqual(readIntegrationBranch(repo, "M001"), null,
|
|
148
148
|
"capture from slice branch is a no-op");
|
|
149
149
|
|
|
150
150
|
rmSync(repo, { recursive: true, force: true });
|
|
@@ -167,12 +167,12 @@ async function main(): Promise<void> {
|
|
|
167
167
|
|
|
168
168
|
// Without milestone set, getMainBranch returns "main"
|
|
169
169
|
setActiveMilestoneId(repo, null);
|
|
170
|
-
|
|
170
|
+
assert.deepStrictEqual(getMainBranch(repo), "main",
|
|
171
171
|
"getMainBranch returns main without milestone set");
|
|
172
172
|
|
|
173
173
|
// With milestone set, getMainBranch returns feature branch
|
|
174
174
|
setActiveMilestoneId(repo, "M001");
|
|
175
|
-
|
|
175
|
+
assert.deepStrictEqual(getMainBranch(repo), "my-feature",
|
|
176
176
|
"getMainBranch returns integration branch with milestone set");
|
|
177
177
|
|
|
178
178
|
rmSync(repo, { recursive: true, force: true });
|
|
@@ -180,22 +180,22 @@ async function main(): Promise<void> {
|
|
|
180
180
|
|
|
181
181
|
// ── detectWorktreeName: symlink-resolved paths ───────────────────────────
|
|
182
182
|
console.log("\n=== detectWorktreeName (symlink-resolved paths) ===");
|
|
183
|
-
|
|
183
|
+
assert.deepStrictEqual(
|
|
184
184
|
detectWorktreeName("/Users/fran/.gsd/projects/89e1c9ad49bf/worktrees/M001"),
|
|
185
185
|
"M001",
|
|
186
186
|
"detects milestone in symlink-resolved path",
|
|
187
187
|
);
|
|
188
|
-
|
|
188
|
+
assert.deepStrictEqual(
|
|
189
189
|
detectWorktreeName("/Users/fran/.gsd/projects/abc123/worktrees/M002/subdir"),
|
|
190
190
|
"M002",
|
|
191
191
|
"detects milestone with trailing subdir in symlink-resolved path",
|
|
192
192
|
);
|
|
193
|
-
|
|
193
|
+
assert.deepStrictEqual(
|
|
194
194
|
detectWorktreeName("/Users/fran/.gsd/projects/abc123"),
|
|
195
195
|
null,
|
|
196
196
|
"returns null for project root without worktrees segment",
|
|
197
197
|
);
|
|
198
|
-
|
|
198
|
+
assert.deepStrictEqual(
|
|
199
199
|
detectWorktreeName("/foo/.gsd/worktrees/M001"),
|
|
200
200
|
"M001",
|
|
201
201
|
"still detects direct layout path",
|
|
@@ -211,7 +211,7 @@ async function main(): Promise<void> {
|
|
|
211
211
|
|
|
212
212
|
// With GSD_PROJECT_ROOT env var set (layer 1 — coordinator passes it)
|
|
213
213
|
process.env.GSD_PROJECT_ROOT = "/real/project";
|
|
214
|
-
|
|
214
|
+
assert.deepStrictEqual(
|
|
215
215
|
resolveProjectRoot("/Users/fran/.gsd/projects/89e1c9ad49bf/worktrees/M001"),
|
|
216
216
|
"/real/project",
|
|
217
217
|
"uses GSD_PROJECT_ROOT when set",
|
|
@@ -219,7 +219,7 @@ async function main(): Promise<void> {
|
|
|
219
219
|
delete process.env.GSD_PROJECT_ROOT;
|
|
220
220
|
|
|
221
221
|
// Without GSD_PROJECT_ROOT, direct layout still works (no ~/.gsd collision)
|
|
222
|
-
|
|
222
|
+
assert.deepStrictEqual(
|
|
223
223
|
resolveProjectRoot("/some/repo"),
|
|
224
224
|
"/some/repo",
|
|
225
225
|
"ignores GSD_PROJECT_ROOT override for non-worktree paths",
|
|
@@ -227,19 +227,19 @@ async function main(): Promise<void> {
|
|
|
227
227
|
delete process.env.GSD_PROJECT_ROOT;
|
|
228
228
|
|
|
229
229
|
// Without GSD_PROJECT_ROOT, direct layout still works (no ~/.gsd collision)
|
|
230
|
-
|
|
230
|
+
assert.deepStrictEqual(
|
|
231
231
|
resolveProjectRoot("/foo/.gsd/worktrees/M001"),
|
|
232
232
|
"/foo",
|
|
233
233
|
"still resolves direct layout path",
|
|
234
234
|
);
|
|
235
|
-
|
|
235
|
+
assert.deepStrictEqual(
|
|
236
236
|
resolveProjectRoot("/some/repo"),
|
|
237
237
|
"/some/repo",
|
|
238
238
|
"returns unchanged for non-worktree path",
|
|
239
239
|
);
|
|
240
240
|
|
|
241
241
|
// Without GSD_PROJECT_ROOT, direct layout with nested subdirs
|
|
242
|
-
|
|
242
|
+
assert.deepStrictEqual(
|
|
243
243
|
resolveProjectRoot("/data/.gsd/worktrees/M003/nested"),
|
|
244
244
|
"/data",
|
|
245
245
|
"resolves correctly with nested subdirs after worktree name (direct layout)",
|
|
@@ -264,7 +264,7 @@ async function main(): Promise<void> {
|
|
|
264
264
|
mkdirSync(deep, { recursive: true });
|
|
265
265
|
|
|
266
266
|
process.env.GSD_HOME = join(fakeHome, ".gsd");
|
|
267
|
-
|
|
267
|
+
assert.deepStrictEqual(
|
|
268
268
|
normalizePath(resolveProjectRoot(realpathSync(deep))),
|
|
269
269
|
normalizePath(project),
|
|
270
270
|
"resolves to real project root from deep symlink-resolved worktree path",
|
|
@@ -276,10 +276,4 @@ async function main(): Promise<void> {
|
|
|
276
276
|
}
|
|
277
277
|
|
|
278
278
|
rmSync(base, { recursive: true, force: true });
|
|
279
|
-
report();
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
main().catch((error) => {
|
|
283
|
-
console.error(error);
|
|
284
|
-
process.exit(1);
|
|
285
279
|
});
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
// GSD Extension — write-intercept unit tests
|
|
2
|
+
// Tests isBlockedStateFile() and BLOCKED_WRITE_ERROR constant.
|
|
3
|
+
|
|
4
|
+
import test from 'node:test';
|
|
5
|
+
import assert from 'node:assert/strict';
|
|
6
|
+
import { isBlockedStateFile, BLOCKED_WRITE_ERROR } from '../write-intercept.ts';
|
|
7
|
+
|
|
8
|
+
// ─── isBlockedStateFile: blocked paths ───────────────────────────────────
|
|
9
|
+
|
|
10
|
+
test('write-intercept: blocks unix .gsd/STATE.md path', () => {
|
|
11
|
+
assert.strictEqual(isBlockedStateFile('/project/.gsd/STATE.md'), true);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
test('write-intercept: blocks relative path with dir prefix before .gsd/STATE.md', () => {
|
|
15
|
+
assert.strictEqual(isBlockedStateFile('project/.gsd/STATE.md'), true);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
test('write-intercept: blocks bare relative .gsd/STATE.md (no leading separator)', () => {
|
|
19
|
+
// (^|[/\\]) matches paths that start with .gsd/ — covers the case where write
|
|
20
|
+
// tools receive a bare relative path before the file exists (realpathSync fails).
|
|
21
|
+
assert.strictEqual(isBlockedStateFile('.gsd/STATE.md'), true);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test('write-intercept: blocks nested project .gsd/STATE.md path', () => {
|
|
25
|
+
assert.strictEqual(isBlockedStateFile('/Users/dev/my-project/.gsd/STATE.md'), true);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test('write-intercept: blocks .gsd/projects/<name>/STATE.md (symlinked projects path)', () => {
|
|
29
|
+
assert.strictEqual(isBlockedStateFile('/home/user/.gsd/projects/my-project/STATE.md'), true);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
// ─── isBlockedStateFile: allowed paths ───────────────────────────────────
|
|
33
|
+
|
|
34
|
+
test('write-intercept: allows .gsd/ROADMAP.md', () => {
|
|
35
|
+
assert.strictEqual(isBlockedStateFile('/project/.gsd/ROADMAP.md'), false);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
test('write-intercept: allows .gsd/PLAN.md', () => {
|
|
39
|
+
assert.strictEqual(isBlockedStateFile('/project/.gsd/PLAN.md'), false);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
test('write-intercept: allows .gsd/REQUIREMENTS.md', () => {
|
|
43
|
+
assert.strictEqual(isBlockedStateFile('/project/.gsd/REQUIREMENTS.md'), false);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
test('write-intercept: allows .gsd/SUMMARY.md', () => {
|
|
47
|
+
assert.strictEqual(isBlockedStateFile('/project/.gsd/SUMMARY.md'), false);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
test('write-intercept: allows .gsd/PROJECT.md', () => {
|
|
51
|
+
assert.strictEqual(isBlockedStateFile('/project/.gsd/PROJECT.md'), false);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
test('write-intercept: allows regular source files', () => {
|
|
55
|
+
assert.strictEqual(isBlockedStateFile('/project/src/index.ts'), false);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
test('write-intercept: allows slice plan files', () => {
|
|
59
|
+
assert.strictEqual(isBlockedStateFile('/project/.gsd/milestones/M001/slices/S01/S01-PLAN.md'), false);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
test('write-intercept: does not block files named STATE.md outside .gsd/', () => {
|
|
63
|
+
assert.strictEqual(isBlockedStateFile('/project/docs/STATE.md'), false);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// ─── BLOCKED_WRITE_ERROR: content ────────────────────────────────────────
|
|
67
|
+
|
|
68
|
+
test('write-intercept: BLOCKED_WRITE_ERROR is a non-empty string', () => {
|
|
69
|
+
assert.strictEqual(typeof BLOCKED_WRITE_ERROR, 'string');
|
|
70
|
+
assert.ok(BLOCKED_WRITE_ERROR.length > 0);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
test('write-intercept: BLOCKED_WRITE_ERROR mentions engine tool calls', () => {
|
|
74
|
+
assert.ok(BLOCKED_WRITE_ERROR.includes('gsd_complete_task'), 'should mention gsd_complete_task');
|
|
75
|
+
assert.ok(BLOCKED_WRITE_ERROR.includes('engine tool calls'), 'should mention engine tool calls');
|
|
76
|
+
});
|
|
@@ -11,12 +11,17 @@ import { mkdirSync } from "node:fs";
|
|
|
11
11
|
|
|
12
12
|
import {
|
|
13
13
|
transaction,
|
|
14
|
+
getMilestone,
|
|
14
15
|
getMilestoneSlices,
|
|
16
|
+
getSliceTasks,
|
|
15
17
|
_getAdapter,
|
|
16
18
|
} from "../gsd-db.js";
|
|
17
19
|
import { resolveMilestonePath, clearPathCache } from "../paths.js";
|
|
18
20
|
import { saveFile, clearParseCache } from "../files.js";
|
|
19
21
|
import { invalidateStateCache } from "../state.js";
|
|
22
|
+
import { renderAllProjections } from "../workflow-projections.js";
|
|
23
|
+
import { writeManifest } from "../workflow-manifest.js";
|
|
24
|
+
import { appendEvent } from "../workflow-events.js";
|
|
20
25
|
|
|
21
26
|
export interface CompleteMilestoneParams {
|
|
22
27
|
milestoneId: string;
|
|
@@ -31,6 +36,11 @@ export interface CompleteMilestoneParams {
|
|
|
31
36
|
lessonsLearned: string[];
|
|
32
37
|
followUps: string;
|
|
33
38
|
deviations: string;
|
|
39
|
+
verificationPassed: boolean;
|
|
40
|
+
/** Optional caller-provided identity for audit trail */
|
|
41
|
+
actorName?: string;
|
|
42
|
+
/** Optional caller-provided reason this action was triggered */
|
|
43
|
+
triggerReason?: string;
|
|
34
44
|
}
|
|
35
45
|
|
|
36
46
|
export interface CompleteMilestoneResult {
|
|
@@ -108,22 +118,53 @@ export async function handleCompleteMilestone(
|
|
|
108
118
|
return { error: "title is required and must be a non-empty string" };
|
|
109
119
|
}
|
|
110
120
|
|
|
111
|
-
// ── Verify
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
return { error: `no slices found for milestone ${params.milestoneId}` };
|
|
121
|
+
// ── Verify that verification passed ─────────────────────────────────────
|
|
122
|
+
if (params.verificationPassed !== true) {
|
|
123
|
+
return { error: "verification did not pass — milestone completion blocked. verificationPassed must be explicitly set to true after all verification steps succeed" };
|
|
115
124
|
}
|
|
116
125
|
|
|
117
|
-
|
|
118
|
-
if (incompleteSlices.length > 0) {
|
|
119
|
-
const incompleteIds = incompleteSlices.map(s => `${s.id} (status: ${s.status})`).join(", ");
|
|
120
|
-
return { error: `incomplete slices: ${incompleteIds}` };
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
// ── DB writes inside a transaction ──────────────────────────────────────
|
|
126
|
+
// ── Guards + DB writes inside a single transaction (prevents TOCTOU) ───
|
|
124
127
|
const completedAt = new Date().toISOString();
|
|
128
|
+
let guardError: string | null = null;
|
|
125
129
|
|
|
126
130
|
transaction(() => {
|
|
131
|
+
// State machine preconditions (inside txn for atomicity)
|
|
132
|
+
const milestone = getMilestone(params.milestoneId);
|
|
133
|
+
if (!milestone) {
|
|
134
|
+
guardError = `milestone not found: ${params.milestoneId}`;
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
if (milestone.status === "complete" || milestone.status === "done") {
|
|
138
|
+
guardError = `milestone ${params.milestoneId} is already complete`;
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Verify all slices are complete
|
|
143
|
+
const slices = getMilestoneSlices(params.milestoneId);
|
|
144
|
+
if (slices.length === 0) {
|
|
145
|
+
guardError = `no slices found for milestone ${params.milestoneId}`;
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const incompleteSlices = slices.filter(s => s.status !== "complete" && s.status !== "done");
|
|
150
|
+
if (incompleteSlices.length > 0) {
|
|
151
|
+
const incompleteIds = incompleteSlices.map(s => `${s.id} (status: ${s.status})`).join(", ");
|
|
152
|
+
guardError = `incomplete slices: ${incompleteIds}`;
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Deep check: verify all tasks in all slices are complete
|
|
157
|
+
for (const slice of slices) {
|
|
158
|
+
const tasks = getSliceTasks(params.milestoneId, slice.id);
|
|
159
|
+
const incompleteTasks = tasks.filter(t => t.status !== "complete" && t.status !== "done");
|
|
160
|
+
if (incompleteTasks.length > 0) {
|
|
161
|
+
const ids = incompleteTasks.map(t => `${t.id} (status: ${t.status})`).join(", ");
|
|
162
|
+
guardError = `slice ${slice.id} has incomplete tasks: ${ids}`;
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// All guards passed — perform write
|
|
127
168
|
const adapter = _getAdapter()!;
|
|
128
169
|
adapter.prepare(
|
|
129
170
|
`UPDATE milestones SET status = 'complete', completed_at = :completed_at WHERE id = :mid`,
|
|
@@ -133,6 +174,10 @@ export async function handleCompleteMilestone(
|
|
|
133
174
|
});
|
|
134
175
|
});
|
|
135
176
|
|
|
177
|
+
if (guardError) {
|
|
178
|
+
return { error: guardError };
|
|
179
|
+
}
|
|
180
|
+
|
|
136
181
|
// ── Filesystem operations (outside transaction) ─────────────────────────
|
|
137
182
|
const summaryMd = renderMilestoneSummaryMarkdown(params);
|
|
138
183
|
|
|
@@ -169,6 +214,24 @@ export async function handleCompleteMilestone(
|
|
|
169
214
|
clearPathCache();
|
|
170
215
|
clearParseCache();
|
|
171
216
|
|
|
217
|
+
// ── Post-mutation hook: projections, manifest, event log ───────────────
|
|
218
|
+
try {
|
|
219
|
+
await renderAllProjections(basePath, params.milestoneId);
|
|
220
|
+
writeManifest(basePath);
|
|
221
|
+
appendEvent(basePath, {
|
|
222
|
+
cmd: "complete-milestone",
|
|
223
|
+
params: { milestoneId: params.milestoneId },
|
|
224
|
+
ts: new Date().toISOString(),
|
|
225
|
+
actor: "agent",
|
|
226
|
+
actor_name: params.actorName,
|
|
227
|
+
trigger_reason: params.triggerReason,
|
|
228
|
+
});
|
|
229
|
+
} catch (hookErr) {
|
|
230
|
+
process.stderr.write(
|
|
231
|
+
`gsd: complete-milestone post-mutation hook warning: ${(hookErr as Error).message}\n`,
|
|
232
|
+
);
|
|
233
|
+
}
|
|
234
|
+
|
|
172
235
|
return {
|
|
173
236
|
milestoneId: params.milestoneId,
|
|
174
237
|
summaryPath,
|
|
@@ -15,14 +15,20 @@ import {
|
|
|
15
15
|
transaction,
|
|
16
16
|
insertMilestone,
|
|
17
17
|
insertSlice,
|
|
18
|
+
getSlice,
|
|
18
19
|
getSliceTasks,
|
|
20
|
+
getMilestone,
|
|
19
21
|
updateSliceStatus,
|
|
20
22
|
_getAdapter,
|
|
21
23
|
} from "../gsd-db.js";
|
|
22
24
|
import { resolveSliceFile, resolveSlicePath, clearPathCache } from "../paths.js";
|
|
25
|
+
import { checkOwnership, sliceUnitKey } from "../unit-ownership.js";
|
|
23
26
|
import { saveFile, clearParseCache } from "../files.js";
|
|
24
27
|
import { invalidateStateCache } from "../state.js";
|
|
25
28
|
import { renderRoadmapCheckboxes } from "../markdown-renderer.js";
|
|
29
|
+
import { renderAllProjections } from "../workflow-projections.js";
|
|
30
|
+
import { writeManifest } from "../workflow-manifest.js";
|
|
31
|
+
import { appendEvent } from "../workflow-events.js";
|
|
26
32
|
|
|
27
33
|
export interface CompleteSliceResult {
|
|
28
34
|
sliceId: string;
|
|
@@ -200,27 +206,60 @@ export async function handleCompleteSlice(
|
|
|
200
206
|
return { error: "milestoneId is required and must be a non-empty string" };
|
|
201
207
|
}
|
|
202
208
|
|
|
203
|
-
// ──
|
|
204
|
-
const
|
|
205
|
-
|
|
206
|
-
|
|
209
|
+
// ── Ownership check (opt-in: only enforced when claim file exists) ──────
|
|
210
|
+
const ownershipErr = checkOwnership(
|
|
211
|
+
basePath,
|
|
212
|
+
sliceUnitKey(params.milestoneId, params.sliceId),
|
|
213
|
+
params.actorName,
|
|
214
|
+
);
|
|
215
|
+
if (ownershipErr) {
|
|
216
|
+
return { error: ownershipErr };
|
|
207
217
|
}
|
|
208
218
|
|
|
209
|
-
|
|
210
|
-
if (incompleteTasks.length > 0) {
|
|
211
|
-
const incompleteIds = incompleteTasks.map(t => `${t.id} (status: ${t.status})`).join(", ");
|
|
212
|
-
return { error: `incomplete tasks: ${incompleteIds}` };
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
// ── DB writes inside a transaction ──────────────────────────────────────
|
|
219
|
+
// ── Guards + DB writes inside a single transaction (prevents TOCTOU) ───
|
|
216
220
|
const completedAt = new Date().toISOString();
|
|
221
|
+
let guardError: string | null = null;
|
|
217
222
|
|
|
218
223
|
transaction(() => {
|
|
224
|
+
// State machine preconditions (inside txn for atomicity).
|
|
225
|
+
// Milestone/slice not existing is OK — insertMilestone/insertSlice below will auto-create.
|
|
226
|
+
// Only block if they exist and are closed.
|
|
227
|
+
const milestone = getMilestone(params.milestoneId);
|
|
228
|
+
if (milestone && (milestone.status === "complete" || milestone.status === "done")) {
|
|
229
|
+
guardError = `cannot complete slice in a closed milestone: ${params.milestoneId} (status: ${milestone.status})`;
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
const slice = getSlice(params.milestoneId, params.sliceId);
|
|
234
|
+
if (slice && (slice.status === "complete" || slice.status === "done")) {
|
|
235
|
+
guardError = `slice ${params.sliceId} is already complete — use gsd_slice_reopen first if you need to redo it`;
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// Verify all tasks are complete
|
|
240
|
+
const tasks = getSliceTasks(params.milestoneId, params.sliceId);
|
|
241
|
+
if (tasks.length === 0) {
|
|
242
|
+
guardError = `no tasks found for slice ${params.sliceId} in milestone ${params.milestoneId}`;
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
const incompleteTasks = tasks.filter(t => t.status !== "complete" && t.status !== "done");
|
|
247
|
+
if (incompleteTasks.length > 0) {
|
|
248
|
+
const incompleteIds = incompleteTasks.map(t => `${t.id} (status: ${t.status})`).join(", ");
|
|
249
|
+
guardError = `incomplete tasks: ${incompleteIds}`;
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// All guards passed — perform writes
|
|
219
254
|
insertMilestone({ id: params.milestoneId });
|
|
220
255
|
insertSlice({ id: params.sliceId, milestoneId: params.milestoneId });
|
|
221
256
|
updateSliceStatus(params.milestoneId, params.sliceId, "complete", completedAt);
|
|
222
257
|
});
|
|
223
258
|
|
|
259
|
+
if (guardError) {
|
|
260
|
+
return { error: guardError };
|
|
261
|
+
}
|
|
262
|
+
|
|
224
263
|
// ── Filesystem operations (outside transaction) ─────────────────────────
|
|
225
264
|
// If disk render fails, roll back the DB status so deriveState() and
|
|
226
265
|
// verifyExpectedArtifact() stay consistent (both say "not done").
|
|
@@ -291,6 +330,24 @@ export async function handleCompleteSlice(
|
|
|
291
330
|
clearPathCache();
|
|
292
331
|
clearParseCache();
|
|
293
332
|
|
|
333
|
+
// ── Post-mutation hook: projections, manifest, event log ───────────────
|
|
334
|
+
try {
|
|
335
|
+
await renderAllProjections(basePath, params.milestoneId);
|
|
336
|
+
writeManifest(basePath);
|
|
337
|
+
appendEvent(basePath, {
|
|
338
|
+
cmd: "complete-slice",
|
|
339
|
+
params: { milestoneId: params.milestoneId, sliceId: params.sliceId },
|
|
340
|
+
ts: new Date().toISOString(),
|
|
341
|
+
actor: "agent",
|
|
342
|
+
actor_name: params.actorName,
|
|
343
|
+
trigger_reason: params.triggerReason,
|
|
344
|
+
});
|
|
345
|
+
} catch (hookErr) {
|
|
346
|
+
process.stderr.write(
|
|
347
|
+
`gsd: complete-slice post-mutation hook warning: ${(hookErr as Error).message}\n`,
|
|
348
|
+
);
|
|
349
|
+
}
|
|
350
|
+
|
|
294
351
|
return {
|
|
295
352
|
sliceId: params.sliceId,
|
|
296
353
|
milestoneId: params.milestoneId,
|
|
@@ -17,12 +17,19 @@ import {
|
|
|
17
17
|
insertSlice,
|
|
18
18
|
insertTask,
|
|
19
19
|
insertVerificationEvidence,
|
|
20
|
+
getMilestone,
|
|
21
|
+
getSlice,
|
|
22
|
+
getTask,
|
|
20
23
|
_getAdapter,
|
|
21
24
|
} from "../gsd-db.js";
|
|
22
25
|
import { resolveSliceFile, resolveTasksDir, clearPathCache } from "../paths.js";
|
|
26
|
+
import { checkOwnership, taskUnitKey } from "../unit-ownership.js";
|
|
23
27
|
import { saveFile, clearParseCache } from "../files.js";
|
|
24
28
|
import { invalidateStateCache } from "../state.js";
|
|
25
29
|
import { renderPlanCheckboxes } from "../markdown-renderer.js";
|
|
30
|
+
import { renderAllProjections } from "../workflow-projections.js";
|
|
31
|
+
import { writeManifest } from "../workflow-manifest.js";
|
|
32
|
+
import { appendEvent } from "../workflow-events.js";
|
|
26
33
|
|
|
27
34
|
export interface CompleteTaskResult {
|
|
28
35
|
taskId: string;
|
|
@@ -131,10 +138,43 @@ export async function handleCompleteTask(
|
|
|
131
138
|
return { error: "milestoneId is required and must be a non-empty string" };
|
|
132
139
|
}
|
|
133
140
|
|
|
134
|
-
// ──
|
|
141
|
+
// ── Ownership check (opt-in: only enforced when claim file exists) ──────
|
|
142
|
+
const ownershipErr = checkOwnership(
|
|
143
|
+
basePath,
|
|
144
|
+
taskUnitKey(params.milestoneId, params.sliceId, params.taskId),
|
|
145
|
+
params.actorName,
|
|
146
|
+
);
|
|
147
|
+
if (ownershipErr) {
|
|
148
|
+
return { error: ownershipErr };
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// ── Guards + DB writes inside a single transaction (prevents TOCTOU) ───
|
|
135
152
|
const completedAt = new Date().toISOString();
|
|
153
|
+
let guardError: string | null = null;
|
|
136
154
|
|
|
137
155
|
transaction(() => {
|
|
156
|
+
// State machine preconditions (inside txn for atomicity).
|
|
157
|
+
// Milestone/slice not existing is OK — insertMilestone/insertSlice below will auto-create.
|
|
158
|
+
// Only block if they exist and are closed.
|
|
159
|
+
const milestone = getMilestone(params.milestoneId);
|
|
160
|
+
if (milestone && (milestone.status === "complete" || milestone.status === "done")) {
|
|
161
|
+
guardError = `cannot complete task in a closed milestone: ${params.milestoneId} (status: ${milestone.status})`;
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const slice = getSlice(params.milestoneId, params.sliceId);
|
|
166
|
+
if (slice && (slice.status === "complete" || slice.status === "done")) {
|
|
167
|
+
guardError = `cannot complete task in a closed slice: ${params.sliceId} (status: ${slice.status})`;
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const existingTask = getTask(params.milestoneId, params.sliceId, params.taskId);
|
|
172
|
+
if (existingTask && (existingTask.status === "complete" || existingTask.status === "done")) {
|
|
173
|
+
guardError = `task ${params.taskId} is already complete — use gsd_task_reopen first if you need to redo it`;
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// All guards passed — perform writes
|
|
138
178
|
insertMilestone({ id: params.milestoneId });
|
|
139
179
|
insertSlice({ id: params.sliceId, milestoneId: params.milestoneId });
|
|
140
180
|
insertTask({
|
|
@@ -167,6 +207,10 @@ export async function handleCompleteTask(
|
|
|
167
207
|
}
|
|
168
208
|
});
|
|
169
209
|
|
|
210
|
+
if (guardError) {
|
|
211
|
+
return { error: guardError };
|
|
212
|
+
}
|
|
213
|
+
|
|
170
214
|
// ── Filesystem operations (outside transaction) ─────────────────────────
|
|
171
215
|
// If disk render fails, roll back the DB status so deriveState() and
|
|
172
216
|
// verifyExpectedArtifact() stay consistent (both say "not done").
|
|
@@ -236,6 +280,24 @@ export async function handleCompleteTask(
|
|
|
236
280
|
clearPathCache();
|
|
237
281
|
clearParseCache();
|
|
238
282
|
|
|
283
|
+
// ── Post-mutation hook: projections, manifest, event log ───────────────
|
|
284
|
+
try {
|
|
285
|
+
await renderAllProjections(basePath, params.milestoneId);
|
|
286
|
+
writeManifest(basePath);
|
|
287
|
+
appendEvent(basePath, {
|
|
288
|
+
cmd: "complete-task",
|
|
289
|
+
params: { milestoneId: params.milestoneId, sliceId: params.sliceId, taskId: params.taskId },
|
|
290
|
+
ts: new Date().toISOString(),
|
|
291
|
+
actor: "agent",
|
|
292
|
+
actor_name: params.actorName,
|
|
293
|
+
trigger_reason: params.triggerReason,
|
|
294
|
+
});
|
|
295
|
+
} catch (hookErr) {
|
|
296
|
+
process.stderr.write(
|
|
297
|
+
`gsd: complete-task post-mutation hook warning: ${(hookErr as Error).message}\n`,
|
|
298
|
+
);
|
|
299
|
+
}
|
|
300
|
+
|
|
239
301
|
return {
|
|
240
302
|
taskId: params.taskId,
|
|
241
303
|
sliceId: params.sliceId,
|