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
|
@@ -169,7 +169,6 @@ export function acquireSessionLock(basePath) {
|
|
|
169
169
|
unitType: "starting",
|
|
170
170
|
unitId: "bootstrap",
|
|
171
171
|
unitStartedAt: new Date().toISOString(),
|
|
172
|
-
completedUnits: 0,
|
|
173
172
|
};
|
|
174
173
|
let lockfile;
|
|
175
174
|
try {
|
|
@@ -314,7 +313,7 @@ function acquireFallbackLock(basePath, lp, lockData) {
|
|
|
314
313
|
* Update the lock file metadata (called on each unit dispatch).
|
|
315
314
|
* Does NOT re-acquire the OS lock — just updates the JSON content.
|
|
316
315
|
*/
|
|
317
|
-
export function updateSessionLock(basePath, unitType, unitId,
|
|
316
|
+
export function updateSessionLock(basePath, unitType, unitId, sessionFile) {
|
|
318
317
|
if (_lockedPath !== basePath && _lockedPath !== null)
|
|
319
318
|
return;
|
|
320
319
|
const lp = lockPath(basePath);
|
|
@@ -325,7 +324,6 @@ export function updateSessionLock(basePath, unitType, unitId, completedUnits, se
|
|
|
325
324
|
unitType,
|
|
326
325
|
unitId,
|
|
327
326
|
unitStartedAt: new Date().toISOString(),
|
|
328
|
-
completedUnits,
|
|
329
327
|
sessionFile,
|
|
330
328
|
};
|
|
331
329
|
atomicWriteSync(lp, JSON.stringify(data, null, 2));
|
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
import { parseRoadmap, parsePlan, } from './parsers-legacy.js';
|
|
5
5
|
import { parseSummary, loadFile, parseRequirementCounts, parseContextDependsOn, } from './files.js';
|
|
6
6
|
import { resolveMilestoneFile, resolveSlicePath, resolveSliceFile, resolveTaskFile, resolveTasksDir, resolveGsdRootFile, gsdRoot, } from './paths.js';
|
|
7
|
-
import { findMilestoneIds } from './milestone-ids.js';
|
|
7
|
+
import { milestoneIdSort, findMilestoneIds } from './milestone-ids.js';
|
|
8
8
|
import { nativeBatchParseGsdFiles } from './native-parser-bridge.js';
|
|
9
9
|
import { join, resolve } from 'path';
|
|
10
10
|
import { existsSync, readdirSync } from 'node:fs';
|
|
11
11
|
import { debugCount, debugTime } from './debug-logger.js';
|
|
12
|
-
import { isDbAvailable, getAllMilestones, getMilestoneSlices, getSliceTasks, getReplanHistory, getSlice, } from './gsd-db.js';
|
|
12
|
+
import { isDbAvailable, getAllMilestones, getMilestoneSlices, getSliceTasks, getReplanHistory, getSlice, insertMilestone, } from './gsd-db.js';
|
|
13
13
|
/**
|
|
14
14
|
* A "ghost" milestone directory contains only META.json (and no substantive
|
|
15
15
|
* files like CONTEXT, CONTEXT-DRAFT, ROADMAP, or SUMMARY). These appear when
|
|
@@ -57,6 +57,10 @@ export function isValidationTerminal(validationContent) {
|
|
|
57
57
|
}
|
|
58
58
|
const CACHE_TTL_MS = 100;
|
|
59
59
|
let _stateCache = null;
|
|
60
|
+
// ── Telemetry counters for derive-path observability ────────────────────────
|
|
61
|
+
let _telemetry = { dbDeriveCount: 0, markdownDeriveCount: 0 };
|
|
62
|
+
export function getDeriveTelemetry() { return { ..._telemetry }; }
|
|
63
|
+
export function resetDeriveTelemetry() { _telemetry = { dbDeriveCount: 0, markdownDeriveCount: 0 }; }
|
|
60
64
|
/**
|
|
61
65
|
* Invalidate the deriveState() cache. Call this whenever planning files on disk
|
|
62
66
|
* may have changed (unit completion, merges, file writes).
|
|
@@ -141,14 +145,17 @@ export async function deriveState(basePath) {
|
|
|
141
145
|
const stopDbTimer = debugTime("derive-state-db");
|
|
142
146
|
result = await deriveStateFromDb(basePath);
|
|
143
147
|
stopDbTimer({ phase: result.phase, milestone: result.activeMilestone?.id });
|
|
148
|
+
_telemetry.dbDeriveCount++;
|
|
144
149
|
}
|
|
145
150
|
else {
|
|
146
151
|
// DB open but empty hierarchy tables — pre-migration project, use filesystem
|
|
147
152
|
result = await _deriveStateImpl(basePath);
|
|
153
|
+
_telemetry.markdownDeriveCount++;
|
|
148
154
|
}
|
|
149
155
|
}
|
|
150
156
|
else {
|
|
151
157
|
result = await _deriveStateImpl(basePath);
|
|
158
|
+
_telemetry.markdownDeriveCount++;
|
|
152
159
|
}
|
|
153
160
|
stopTimer({ phase: result.phase, milestone: result.activeMilestone?.id });
|
|
154
161
|
debugCount("deriveStateCalls");
|
|
@@ -192,7 +199,45 @@ function isStatusDone(status) {
|
|
|
192
199
|
*/
|
|
193
200
|
export async function deriveStateFromDb(basePath) {
|
|
194
201
|
const requirements = parseRequirementCounts(await loadFile(resolveGsdRootFile(basePath, "REQUIREMENTS")));
|
|
195
|
-
|
|
202
|
+
let allMilestones = getAllMilestones();
|
|
203
|
+
// Incremental disk→DB sync: milestone directories created outside the DB
|
|
204
|
+
// write path (via /gsd queue, manual mkdir, or complete-milestone writing the
|
|
205
|
+
// next CONTEXT.md) are never inserted by the initial migration guard in
|
|
206
|
+
// auto-start.ts because that guard only runs when gsd.db doesn't exist yet.
|
|
207
|
+
// Reconcile here so deriveStateFromDb never silently misses queued milestones.
|
|
208
|
+
// insertMilestone uses INSERT OR IGNORE, so this is safe to call every time.
|
|
209
|
+
const dbIdSet = new Set(allMilestones.map(m => m.id));
|
|
210
|
+
const diskIds = findMilestoneIds(basePath);
|
|
211
|
+
let synced = false;
|
|
212
|
+
for (const diskId of diskIds) {
|
|
213
|
+
if (!dbIdSet.has(diskId) && !isGhostMilestone(basePath, diskId)) {
|
|
214
|
+
insertMilestone({ id: diskId, status: 'active' });
|
|
215
|
+
synced = true;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
if (synced)
|
|
219
|
+
allMilestones = getAllMilestones();
|
|
220
|
+
// Reconcile: discover milestones that exist on disk but are missing from
|
|
221
|
+
// the DB. This happens when milestones were created before the DB migration
|
|
222
|
+
// or were manually added to the filesystem. Without this, disk-only
|
|
223
|
+
// milestones are invisible after migration (#2416).
|
|
224
|
+
const dbMilestoneIds = new Set(allMilestones.map(m => m.id));
|
|
225
|
+
const diskMilestoneIds = findMilestoneIds(basePath);
|
|
226
|
+
for (const diskId of diskMilestoneIds) {
|
|
227
|
+
if (!dbMilestoneIds.has(diskId)) {
|
|
228
|
+
// Synthesize a minimal MilestoneRow for the disk-only milestone.
|
|
229
|
+
// Title and status will be resolved from disk files in the loop below.
|
|
230
|
+
allMilestones.push({
|
|
231
|
+
id: diskId,
|
|
232
|
+
title: diskId,
|
|
233
|
+
status: 'active',
|
|
234
|
+
depends_on: [],
|
|
235
|
+
created_at: new Date().toISOString(),
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
// Re-sort so milestones are in canonical order after injection
|
|
240
|
+
allMilestones.sort((a, b) => milestoneIdSort(a.id, b.id));
|
|
196
241
|
// Parallel worker isolation: when locked, filter to just the locked milestone
|
|
197
242
|
const milestoneLock = process.env.GSD_MILESTONE_LOCK;
|
|
198
243
|
const milestones = milestoneLock
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
// GSD Extension — Advisory Sync Lock
|
|
2
|
+
// Prevents concurrent worktree syncs from colliding via a simple file lock.
|
|
3
|
+
// Stale locks (mtime > 60s) are auto-overridden. Lock acquisition waits up
|
|
4
|
+
// to 5 seconds then skips non-fatally.
|
|
5
|
+
import { existsSync, statSync, unlinkSync } from "node:fs";
|
|
6
|
+
import { join } from "node:path";
|
|
7
|
+
import { atomicWriteSync } from "./atomic-write.js";
|
|
8
|
+
const STALE_THRESHOLD_MS = 60_000; // 60 seconds
|
|
9
|
+
const DEFAULT_TIMEOUT_MS = 5_000; // 5 seconds
|
|
10
|
+
const SPIN_INTERVAL_MS = 100; // 100ms polling interval
|
|
11
|
+
// SharedArrayBuffer for synchronous sleep via Atomics.wait
|
|
12
|
+
const SLEEP_BUFFER = new SharedArrayBuffer(4);
|
|
13
|
+
const SLEEP_VIEW = new Int32Array(SLEEP_BUFFER);
|
|
14
|
+
function lockFilePath(basePath) {
|
|
15
|
+
return join(basePath, ".gsd", "sync.lock");
|
|
16
|
+
}
|
|
17
|
+
function sleepSync(ms) {
|
|
18
|
+
Atomics.wait(SLEEP_VIEW, 0, 0, ms);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Acquire an advisory sync lock for the given basePath.
|
|
22
|
+
* Returns { acquired: true } on success, { acquired: false } after timeout.
|
|
23
|
+
*
|
|
24
|
+
* - Creates lock file at {basePath}/.gsd/sync.lock with JSON { pid, acquired_at }
|
|
25
|
+
* - If lock exists and mtime > 60s (stale), overrides it
|
|
26
|
+
* - If lock exists and not stale, spins up to timeoutMs before giving up
|
|
27
|
+
*/
|
|
28
|
+
export function acquireSyncLock(basePath, timeoutMs = DEFAULT_TIMEOUT_MS) {
|
|
29
|
+
const lp = lockFilePath(basePath);
|
|
30
|
+
const deadline = Date.now() + timeoutMs;
|
|
31
|
+
while (true) {
|
|
32
|
+
// Check if lock file exists
|
|
33
|
+
if (existsSync(lp)) {
|
|
34
|
+
// Check staleness
|
|
35
|
+
try {
|
|
36
|
+
const stat = statSync(lp);
|
|
37
|
+
const age = Date.now() - stat.mtimeMs;
|
|
38
|
+
if (age > STALE_THRESHOLD_MS) {
|
|
39
|
+
// Stale lock — override it
|
|
40
|
+
try {
|
|
41
|
+
unlinkSync(lp);
|
|
42
|
+
}
|
|
43
|
+
catch { /* race: already removed */ }
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
// Lock is held and not stale — wait or give up
|
|
47
|
+
if (Date.now() >= deadline) {
|
|
48
|
+
return { acquired: false };
|
|
49
|
+
}
|
|
50
|
+
sleepSync(SPIN_INTERVAL_MS);
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
// stat failed (file removed between exists check and stat) — try to acquire
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// Lock file does not exist (or was just removed) — try to write it
|
|
59
|
+
try {
|
|
60
|
+
const lockData = {
|
|
61
|
+
pid: process.pid,
|
|
62
|
+
acquired_at: new Date().toISOString(),
|
|
63
|
+
};
|
|
64
|
+
atomicWriteSync(lp, JSON.stringify(lockData, null, 2));
|
|
65
|
+
return { acquired: true };
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
// Write failed (race condition with another process) — retry or give up
|
|
69
|
+
if (Date.now() >= deadline) {
|
|
70
|
+
return { acquired: false };
|
|
71
|
+
}
|
|
72
|
+
sleepSync(SPIN_INTERVAL_MS);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Release the advisory sync lock. No-op if lock file does not exist.
|
|
78
|
+
*/
|
|
79
|
+
export function releaseSyncLock(basePath) {
|
|
80
|
+
const lp = lockFilePath(basePath);
|
|
81
|
+
try {
|
|
82
|
+
if (existsSync(lp)) {
|
|
83
|
+
unlinkSync(lp);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
// Non-fatal — lock may have been released by another process
|
|
88
|
+
}
|
|
89
|
+
}
|
|
@@ -7,10 +7,13 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { join } from "node:path";
|
|
9
9
|
import { mkdirSync } from "node:fs";
|
|
10
|
-
import { transaction, getMilestoneSlices, _getAdapter, } from "../gsd-db.js";
|
|
10
|
+
import { transaction, getMilestone, getMilestoneSlices, getSliceTasks, _getAdapter, } from "../gsd-db.js";
|
|
11
11
|
import { resolveMilestonePath, clearPathCache } from "../paths.js";
|
|
12
12
|
import { saveFile, clearParseCache } from "../files.js";
|
|
13
13
|
import { invalidateStateCache } from "../state.js";
|
|
14
|
+
import { renderAllProjections } from "../workflow-projections.js";
|
|
15
|
+
import { writeManifest } from "../workflow-manifest.js";
|
|
16
|
+
import { appendEvent } from "../workflow-events.js";
|
|
14
17
|
function renderMilestoneSummaryMarkdown(params) {
|
|
15
18
|
const now = new Date().toISOString();
|
|
16
19
|
const keyDecisionsYaml = params.keyDecisions.length > 0
|
|
@@ -72,25 +75,56 @@ export async function handleCompleteMilestone(params, basePath) {
|
|
|
72
75
|
if (!params.title || typeof params.title !== "string" || params.title.trim() === "") {
|
|
73
76
|
return { error: "title is required and must be a non-empty string" };
|
|
74
77
|
}
|
|
75
|
-
// ── Verify
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
return { error: `no slices found for milestone ${params.milestoneId}` };
|
|
78
|
+
// ── Verify that verification passed ─────────────────────────────────────
|
|
79
|
+
if (params.verificationPassed !== true) {
|
|
80
|
+
return { error: "verification did not pass — milestone completion blocked. verificationPassed must be explicitly set to true after all verification steps succeed" };
|
|
79
81
|
}
|
|
80
|
-
|
|
81
|
-
if (incompleteSlices.length > 0) {
|
|
82
|
-
const incompleteIds = incompleteSlices.map(s => `${s.id} (status: ${s.status})`).join(", ");
|
|
83
|
-
return { error: `incomplete slices: ${incompleteIds}` };
|
|
84
|
-
}
|
|
85
|
-
// ── DB writes inside a transaction ──────────────────────────────────────
|
|
82
|
+
// ── Guards + DB writes inside a single transaction (prevents TOCTOU) ───
|
|
86
83
|
const completedAt = new Date().toISOString();
|
|
84
|
+
let guardError = null;
|
|
87
85
|
transaction(() => {
|
|
86
|
+
// State machine preconditions (inside txn for atomicity)
|
|
87
|
+
const milestone = getMilestone(params.milestoneId);
|
|
88
|
+
if (!milestone) {
|
|
89
|
+
guardError = `milestone not found: ${params.milestoneId}`;
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
if (milestone.status === "complete" || milestone.status === "done") {
|
|
93
|
+
guardError = `milestone ${params.milestoneId} is already complete`;
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
// Verify all slices are complete
|
|
97
|
+
const slices = getMilestoneSlices(params.milestoneId);
|
|
98
|
+
if (slices.length === 0) {
|
|
99
|
+
guardError = `no slices found for milestone ${params.milestoneId}`;
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
const incompleteSlices = slices.filter(s => s.status !== "complete" && s.status !== "done");
|
|
103
|
+
if (incompleteSlices.length > 0) {
|
|
104
|
+
const incompleteIds = incompleteSlices.map(s => `${s.id} (status: ${s.status})`).join(", ");
|
|
105
|
+
guardError = `incomplete slices: ${incompleteIds}`;
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
// Deep check: verify all tasks in all slices are complete
|
|
109
|
+
for (const slice of slices) {
|
|
110
|
+
const tasks = getSliceTasks(params.milestoneId, slice.id);
|
|
111
|
+
const incompleteTasks = tasks.filter(t => t.status !== "complete" && t.status !== "done");
|
|
112
|
+
if (incompleteTasks.length > 0) {
|
|
113
|
+
const ids = incompleteTasks.map(t => `${t.id} (status: ${t.status})`).join(", ");
|
|
114
|
+
guardError = `slice ${slice.id} has incomplete tasks: ${ids}`;
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
// All guards passed — perform write
|
|
88
119
|
const adapter = _getAdapter();
|
|
89
120
|
adapter.prepare(`UPDATE milestones SET status = 'complete', completed_at = :completed_at WHERE id = :mid`).run({
|
|
90
121
|
":completed_at": completedAt,
|
|
91
122
|
":mid": params.milestoneId,
|
|
92
123
|
});
|
|
93
124
|
});
|
|
125
|
+
if (guardError) {
|
|
126
|
+
return { error: guardError };
|
|
127
|
+
}
|
|
94
128
|
// ── Filesystem operations (outside transaction) ─────────────────────────
|
|
95
129
|
const summaryMd = renderMilestoneSummaryMarkdown(params);
|
|
96
130
|
let summaryPath;
|
|
@@ -121,6 +155,22 @@ export async function handleCompleteMilestone(params, basePath) {
|
|
|
121
155
|
invalidateStateCache();
|
|
122
156
|
clearPathCache();
|
|
123
157
|
clearParseCache();
|
|
158
|
+
// ── Post-mutation hook: projections, manifest, event log ───────────────
|
|
159
|
+
try {
|
|
160
|
+
await renderAllProjections(basePath, params.milestoneId);
|
|
161
|
+
writeManifest(basePath);
|
|
162
|
+
appendEvent(basePath, {
|
|
163
|
+
cmd: "complete-milestone",
|
|
164
|
+
params: { milestoneId: params.milestoneId },
|
|
165
|
+
ts: new Date().toISOString(),
|
|
166
|
+
actor: "agent",
|
|
167
|
+
actor_name: params.actorName,
|
|
168
|
+
trigger_reason: params.triggerReason,
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
catch (hookErr) {
|
|
172
|
+
process.stderr.write(`gsd: complete-milestone post-mutation hook warning: ${hookErr.message}\n`);
|
|
173
|
+
}
|
|
124
174
|
return {
|
|
125
175
|
milestoneId: params.milestoneId,
|
|
126
176
|
summaryPath,
|
|
@@ -8,11 +8,15 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { join } from "node:path";
|
|
10
10
|
import { mkdirSync } from "node:fs";
|
|
11
|
-
import { transaction, insertMilestone, insertSlice, getSliceTasks, updateSliceStatus, _getAdapter, } from "../gsd-db.js";
|
|
11
|
+
import { transaction, insertMilestone, insertSlice, getSlice, getSliceTasks, getMilestone, updateSliceStatus, _getAdapter, } from "../gsd-db.js";
|
|
12
12
|
import { resolveSlicePath, clearPathCache } from "../paths.js";
|
|
13
|
+
import { checkOwnership, sliceUnitKey } from "../unit-ownership.js";
|
|
13
14
|
import { saveFile, clearParseCache } from "../files.js";
|
|
14
15
|
import { invalidateStateCache } from "../state.js";
|
|
15
16
|
import { renderRoadmapCheckboxes } from "../markdown-renderer.js";
|
|
17
|
+
import { renderAllProjections } from "../workflow-projections.js";
|
|
18
|
+
import { writeManifest } from "../workflow-manifest.js";
|
|
19
|
+
import { appendEvent } from "../workflow-events.js";
|
|
16
20
|
/**
|
|
17
21
|
* Render slice summary markdown matching the template format.
|
|
18
22
|
* YAML frontmatter uses snake_case keys for parseSummary() compatibility.
|
|
@@ -162,23 +166,48 @@ export async function handleCompleteSlice(params, basePath) {
|
|
|
162
166
|
if (!params.milestoneId || typeof params.milestoneId !== "string" || params.milestoneId.trim() === "") {
|
|
163
167
|
return { error: "milestoneId is required and must be a non-empty string" };
|
|
164
168
|
}
|
|
165
|
-
// ──
|
|
166
|
-
const
|
|
167
|
-
if (
|
|
168
|
-
return { error:
|
|
169
|
+
// ── Ownership check (opt-in: only enforced when claim file exists) ──────
|
|
170
|
+
const ownershipErr = checkOwnership(basePath, sliceUnitKey(params.milestoneId, params.sliceId), params.actorName);
|
|
171
|
+
if (ownershipErr) {
|
|
172
|
+
return { error: ownershipErr };
|
|
169
173
|
}
|
|
170
|
-
|
|
171
|
-
if (incompleteTasks.length > 0) {
|
|
172
|
-
const incompleteIds = incompleteTasks.map(t => `${t.id} (status: ${t.status})`).join(", ");
|
|
173
|
-
return { error: `incomplete tasks: ${incompleteIds}` };
|
|
174
|
-
}
|
|
175
|
-
// ── DB writes inside a transaction ──────────────────────────────────────
|
|
174
|
+
// ── Guards + DB writes inside a single transaction (prevents TOCTOU) ───
|
|
176
175
|
const completedAt = new Date().toISOString();
|
|
176
|
+
let guardError = null;
|
|
177
177
|
transaction(() => {
|
|
178
|
+
// State machine preconditions (inside txn for atomicity).
|
|
179
|
+
// Milestone/slice not existing is OK — insertMilestone/insertSlice below will auto-create.
|
|
180
|
+
// Only block if they exist and are closed.
|
|
181
|
+
const milestone = getMilestone(params.milestoneId);
|
|
182
|
+
if (milestone && (milestone.status === "complete" || milestone.status === "done")) {
|
|
183
|
+
guardError = `cannot complete slice in a closed milestone: ${params.milestoneId} (status: ${milestone.status})`;
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
const slice = getSlice(params.milestoneId, params.sliceId);
|
|
187
|
+
if (slice && (slice.status === "complete" || slice.status === "done")) {
|
|
188
|
+
guardError = `slice ${params.sliceId} is already complete — use gsd_slice_reopen first if you need to redo it`;
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
// Verify all tasks are complete
|
|
192
|
+
const tasks = getSliceTasks(params.milestoneId, params.sliceId);
|
|
193
|
+
if (tasks.length === 0) {
|
|
194
|
+
guardError = `no tasks found for slice ${params.sliceId} in milestone ${params.milestoneId}`;
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
const incompleteTasks = tasks.filter(t => t.status !== "complete" && t.status !== "done");
|
|
198
|
+
if (incompleteTasks.length > 0) {
|
|
199
|
+
const incompleteIds = incompleteTasks.map(t => `${t.id} (status: ${t.status})`).join(", ");
|
|
200
|
+
guardError = `incomplete tasks: ${incompleteIds}`;
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
// All guards passed — perform writes
|
|
178
204
|
insertMilestone({ id: params.milestoneId });
|
|
179
205
|
insertSlice({ id: params.sliceId, milestoneId: params.milestoneId });
|
|
180
206
|
updateSliceStatus(params.milestoneId, params.sliceId, "complete", completedAt);
|
|
181
207
|
});
|
|
208
|
+
if (guardError) {
|
|
209
|
+
return { error: guardError };
|
|
210
|
+
}
|
|
182
211
|
// ── Filesystem operations (outside transaction) ─────────────────────────
|
|
183
212
|
// If disk render fails, roll back the DB status so deriveState() and
|
|
184
213
|
// verifyExpectedArtifact() stay consistent (both say "not done").
|
|
@@ -235,6 +264,22 @@ export async function handleCompleteSlice(params, basePath) {
|
|
|
235
264
|
invalidateStateCache();
|
|
236
265
|
clearPathCache();
|
|
237
266
|
clearParseCache();
|
|
267
|
+
// ── Post-mutation hook: projections, manifest, event log ───────────────
|
|
268
|
+
try {
|
|
269
|
+
await renderAllProjections(basePath, params.milestoneId);
|
|
270
|
+
writeManifest(basePath);
|
|
271
|
+
appendEvent(basePath, {
|
|
272
|
+
cmd: "complete-slice",
|
|
273
|
+
params: { milestoneId: params.milestoneId, sliceId: params.sliceId },
|
|
274
|
+
ts: new Date().toISOString(),
|
|
275
|
+
actor: "agent",
|
|
276
|
+
actor_name: params.actorName,
|
|
277
|
+
trigger_reason: params.triggerReason,
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
catch (hookErr) {
|
|
281
|
+
process.stderr.write(`gsd: complete-slice post-mutation hook warning: ${hookErr.message}\n`);
|
|
282
|
+
}
|
|
238
283
|
return {
|
|
239
284
|
sliceId: params.sliceId,
|
|
240
285
|
milestoneId: params.milestoneId,
|
|
@@ -8,11 +8,15 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { join } from "node:path";
|
|
10
10
|
import { mkdirSync } from "node:fs";
|
|
11
|
-
import { transaction, insertMilestone, insertSlice, insertTask, insertVerificationEvidence, _getAdapter, } from "../gsd-db.js";
|
|
11
|
+
import { transaction, insertMilestone, insertSlice, insertTask, insertVerificationEvidence, getMilestone, getSlice, getTask, _getAdapter, } from "../gsd-db.js";
|
|
12
12
|
import { resolveSliceFile, resolveTasksDir, clearPathCache } from "../paths.js";
|
|
13
|
+
import { checkOwnership, taskUnitKey } from "../unit-ownership.js";
|
|
13
14
|
import { saveFile, clearParseCache } from "../files.js";
|
|
14
15
|
import { invalidateStateCache } from "../state.js";
|
|
15
16
|
import { renderPlanCheckboxes } from "../markdown-renderer.js";
|
|
17
|
+
import { renderAllProjections } from "../workflow-projections.js";
|
|
18
|
+
import { writeManifest } from "../workflow-manifest.js";
|
|
19
|
+
import { appendEvent } from "../workflow-events.js";
|
|
16
20
|
/**
|
|
17
21
|
* Render task summary markdown matching the template format.
|
|
18
22
|
* YAML frontmatter uses snake_case keys for parseSummary() compatibility.
|
|
@@ -105,9 +109,34 @@ export async function handleCompleteTask(params, basePath) {
|
|
|
105
109
|
if (!params.milestoneId || typeof params.milestoneId !== "string" || params.milestoneId.trim() === "") {
|
|
106
110
|
return { error: "milestoneId is required and must be a non-empty string" };
|
|
107
111
|
}
|
|
108
|
-
// ──
|
|
112
|
+
// ── Ownership check (opt-in: only enforced when claim file exists) ──────
|
|
113
|
+
const ownershipErr = checkOwnership(basePath, taskUnitKey(params.milestoneId, params.sliceId, params.taskId), params.actorName);
|
|
114
|
+
if (ownershipErr) {
|
|
115
|
+
return { error: ownershipErr };
|
|
116
|
+
}
|
|
117
|
+
// ── Guards + DB writes inside a single transaction (prevents TOCTOU) ───
|
|
109
118
|
const completedAt = new Date().toISOString();
|
|
119
|
+
let guardError = null;
|
|
110
120
|
transaction(() => {
|
|
121
|
+
// State machine preconditions (inside txn for atomicity).
|
|
122
|
+
// Milestone/slice not existing is OK — insertMilestone/insertSlice below will auto-create.
|
|
123
|
+
// Only block if they exist and are closed.
|
|
124
|
+
const milestone = getMilestone(params.milestoneId);
|
|
125
|
+
if (milestone && (milestone.status === "complete" || milestone.status === "done")) {
|
|
126
|
+
guardError = `cannot complete task in a closed milestone: ${params.milestoneId} (status: ${milestone.status})`;
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
const slice = getSlice(params.milestoneId, params.sliceId);
|
|
130
|
+
if (slice && (slice.status === "complete" || slice.status === "done")) {
|
|
131
|
+
guardError = `cannot complete task in a closed slice: ${params.sliceId} (status: ${slice.status})`;
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
const existingTask = getTask(params.milestoneId, params.sliceId, params.taskId);
|
|
135
|
+
if (existingTask && (existingTask.status === "complete" || existingTask.status === "done")) {
|
|
136
|
+
guardError = `task ${params.taskId} is already complete — use gsd_task_reopen first if you need to redo it`;
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
// All guards passed — perform writes
|
|
111
140
|
insertMilestone({ id: params.milestoneId });
|
|
112
141
|
insertSlice({ id: params.sliceId, milestoneId: params.milestoneId });
|
|
113
142
|
insertTask({
|
|
@@ -138,6 +167,9 @@ export async function handleCompleteTask(params, basePath) {
|
|
|
138
167
|
});
|
|
139
168
|
}
|
|
140
169
|
});
|
|
170
|
+
if (guardError) {
|
|
171
|
+
return { error: guardError };
|
|
172
|
+
}
|
|
141
173
|
// ── Filesystem operations (outside transaction) ─────────────────────────
|
|
142
174
|
// If disk render fails, roll back the DB status so deriveState() and
|
|
143
175
|
// verifyExpectedArtifact() stay consistent (both say "not done").
|
|
@@ -195,6 +227,22 @@ export async function handleCompleteTask(params, basePath) {
|
|
|
195
227
|
invalidateStateCache();
|
|
196
228
|
clearPathCache();
|
|
197
229
|
clearParseCache();
|
|
230
|
+
// ── Post-mutation hook: projections, manifest, event log ───────────────
|
|
231
|
+
try {
|
|
232
|
+
await renderAllProjections(basePath, params.milestoneId);
|
|
233
|
+
writeManifest(basePath);
|
|
234
|
+
appendEvent(basePath, {
|
|
235
|
+
cmd: "complete-task",
|
|
236
|
+
params: { milestoneId: params.milestoneId, sliceId: params.sliceId, taskId: params.taskId },
|
|
237
|
+
ts: new Date().toISOString(),
|
|
238
|
+
actor: "agent",
|
|
239
|
+
actor_name: params.actorName,
|
|
240
|
+
trigger_reason: params.triggerReason,
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
catch (hookErr) {
|
|
244
|
+
process.stderr.write(`gsd: complete-task post-mutation hook warning: ${hookErr.message}\n`);
|
|
245
|
+
}
|
|
198
246
|
return {
|
|
199
247
|
taskId: params.taskId,
|
|
200
248
|
sliceId: params.sliceId,
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { clearParseCache } from "../files.js";
|
|
2
|
-
import { transaction, insertMilestone, insertSlice, upsertMilestonePlanning, upsertSlicePlanning, } from "../gsd-db.js";
|
|
2
|
+
import { transaction, getMilestone, insertMilestone, insertSlice, upsertMilestonePlanning, upsertSlicePlanning, } from "../gsd-db.js";
|
|
3
3
|
import { invalidateStateCache } from "../state.js";
|
|
4
4
|
import { renderRoadmapFromDb } from "../markdown-renderer.js";
|
|
5
|
+
import { renderAllProjections } from "../workflow-projections.js";
|
|
6
|
+
import { writeManifest } from "../workflow-manifest.js";
|
|
7
|
+
import { appendEvent } from "../workflow-events.js";
|
|
5
8
|
function isNonEmptyString(value) {
|
|
6
9
|
return typeof value === "string" && value.trim().length > 0;
|
|
7
10
|
}
|
|
@@ -142,6 +145,23 @@ export async function handlePlanMilestone(rawParams, basePath) {
|
|
|
142
145
|
catch (err) {
|
|
143
146
|
return { error: `validation failed: ${err.message}` };
|
|
144
147
|
}
|
|
148
|
+
// ── State machine preconditions ─────────────────────────────────────────
|
|
149
|
+
const existingMilestone = getMilestone(params.milestoneId);
|
|
150
|
+
if (existingMilestone && (existingMilestone.status === "complete" || existingMilestone.status === "done")) {
|
|
151
|
+
return { error: `cannot re-plan milestone ${params.milestoneId}: it is already complete` };
|
|
152
|
+
}
|
|
153
|
+
// Validate depends_on: all dependencies must exist and be complete
|
|
154
|
+
if (params.dependsOn && params.dependsOn.length > 0) {
|
|
155
|
+
for (const depId of params.dependsOn) {
|
|
156
|
+
const dep = getMilestone(depId);
|
|
157
|
+
if (!dep) {
|
|
158
|
+
return { error: `depends_on references unknown milestone: ${depId}` };
|
|
159
|
+
}
|
|
160
|
+
if (dep.status !== "complete" && dep.status !== "done") {
|
|
161
|
+
return { error: `depends_on milestone ${depId} is not yet complete (status: ${dep.status})` };
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
145
165
|
try {
|
|
146
166
|
transaction(() => {
|
|
147
167
|
insertMilestone({
|
|
@@ -198,6 +218,22 @@ export async function handlePlanMilestone(rawParams, basePath) {
|
|
|
198
218
|
}
|
|
199
219
|
invalidateStateCache();
|
|
200
220
|
clearParseCache();
|
|
221
|
+
// ── Post-mutation hook: projections, manifest, event log ───────────────
|
|
222
|
+
try {
|
|
223
|
+
await renderAllProjections(basePath, params.milestoneId);
|
|
224
|
+
writeManifest(basePath);
|
|
225
|
+
appendEvent(basePath, {
|
|
226
|
+
cmd: "plan-milestone",
|
|
227
|
+
params: { milestoneId: params.milestoneId },
|
|
228
|
+
ts: new Date().toISOString(),
|
|
229
|
+
actor: "agent",
|
|
230
|
+
actor_name: params.actorName,
|
|
231
|
+
trigger_reason: params.triggerReason,
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
catch (hookErr) {
|
|
235
|
+
process.stderr.write(`gsd: plan-milestone post-mutation hook warning: ${hookErr.message}\n`);
|
|
236
|
+
}
|
|
201
237
|
return {
|
|
202
238
|
milestoneId: params.milestoneId,
|
|
203
239
|
roadmapPath,
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { clearParseCache } from "../files.js";
|
|
2
|
-
import { transaction, getSlice, insertTask, upsertSlicePlanning, upsertTaskPlanning, } from "../gsd-db.js";
|
|
2
|
+
import { transaction, getMilestone, getSlice, insertTask, upsertSlicePlanning, upsertTaskPlanning, } from "../gsd-db.js";
|
|
3
3
|
import { invalidateStateCache } from "../state.js";
|
|
4
4
|
import { renderPlanFromDb } from "../markdown-renderer.js";
|
|
5
|
+
import { renderAllProjections } from "../workflow-projections.js";
|
|
6
|
+
import { writeManifest } from "../workflow-manifest.js";
|
|
7
|
+
import { appendEvent } from "../workflow-events.js";
|
|
5
8
|
function isNonEmptyString(value) {
|
|
6
9
|
return typeof value === "string" && value.trim().length > 0;
|
|
7
10
|
}
|
|
@@ -99,10 +102,20 @@ export async function handlePlanSlice(rawParams, basePath) {
|
|
|
99
102
|
catch (err) {
|
|
100
103
|
return { error: `validation failed: ${err.message}` };
|
|
101
104
|
}
|
|
105
|
+
const parentMilestone = getMilestone(params.milestoneId);
|
|
106
|
+
if (!parentMilestone) {
|
|
107
|
+
return { error: `milestone not found: ${params.milestoneId}` };
|
|
108
|
+
}
|
|
109
|
+
if (parentMilestone.status === "complete" || parentMilestone.status === "done") {
|
|
110
|
+
return { error: `cannot plan slice in a closed milestone: ${params.milestoneId} (status: ${parentMilestone.status})` };
|
|
111
|
+
}
|
|
102
112
|
const parentSlice = getSlice(params.milestoneId, params.sliceId);
|
|
103
113
|
if (!parentSlice) {
|
|
104
114
|
return { error: `missing parent slice: ${params.milestoneId}/${params.sliceId}` };
|
|
105
115
|
}
|
|
116
|
+
if (parentSlice.status === "complete" || parentSlice.status === "done") {
|
|
117
|
+
return { error: `cannot re-plan slice ${params.sliceId}: it is already complete — use gsd_slice_reopen first` };
|
|
118
|
+
}
|
|
106
119
|
try {
|
|
107
120
|
transaction(() => {
|
|
108
121
|
upsertSlicePlanning(params.milestoneId, params.sliceId, {
|
|
@@ -129,6 +142,7 @@ export async function handlePlanSlice(rawParams, basePath) {
|
|
|
129
142
|
inputs: task.inputs,
|
|
130
143
|
expectedOutput: task.expectedOutput,
|
|
131
144
|
observabilityImpact: task.observabilityImpact ?? "",
|
|
145
|
+
fullPlanMd: task.fullPlanMd,
|
|
132
146
|
});
|
|
133
147
|
}
|
|
134
148
|
});
|
|
@@ -140,6 +154,22 @@ export async function handlePlanSlice(rawParams, basePath) {
|
|
|
140
154
|
const renderResult = await renderPlanFromDb(basePath, params.milestoneId, params.sliceId);
|
|
141
155
|
invalidateStateCache();
|
|
142
156
|
clearParseCache();
|
|
157
|
+
// ── Post-mutation hook: projections, manifest, event log ─────────────
|
|
158
|
+
try {
|
|
159
|
+
await renderAllProjections(basePath, params.milestoneId);
|
|
160
|
+
writeManifest(basePath);
|
|
161
|
+
appendEvent(basePath, {
|
|
162
|
+
cmd: "plan-slice",
|
|
163
|
+
params: { milestoneId: params.milestoneId, sliceId: params.sliceId },
|
|
164
|
+
ts: new Date().toISOString(),
|
|
165
|
+
actor: "agent",
|
|
166
|
+
actor_name: params.actorName,
|
|
167
|
+
trigger_reason: params.triggerReason,
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
catch (hookErr) {
|
|
171
|
+
process.stderr.write(`gsd: plan-slice post-mutation hook warning: ${hookErr.message}\n`);
|
|
172
|
+
}
|
|
143
173
|
return {
|
|
144
174
|
milestoneId: params.milestoneId,
|
|
145
175
|
sliceId: params.sliceId,
|