gsd-pi 2.44.0-dev.d25d507 → 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/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 +23 -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/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-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 +8 -4
- 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 +14 -14
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- 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/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 +1 -1
- 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 +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
- 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 +2 -2
- 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_client-reference-manifest.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_client-reference-manifest.js +1 -1
- 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_client-reference-manifest.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_client-reference-manifest.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_client-reference-manifest.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_client-reference-manifest.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_client-reference-manifest.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_client-reference-manifest.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_client-reference-manifest.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_client-reference-manifest.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_client-reference-manifest.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_client-reference-manifest.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_client-reference-manifest.js +1 -1
- 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_client-reference-manifest.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_client-reference-manifest.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_client-reference-manifest.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_client-reference-manifest.js +1 -1
- 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_client-reference-manifest.js +1 -1
- 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_client-reference-manifest.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_client-reference-manifest.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 +4 -4
- 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 +4 -4
- 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 +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/page.js +1 -1
- package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +14 -14
- 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/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/{page-b9367c5ae13b99c6.js → page-6654a8cca61a3d1c.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/webpack-0a4cd455ec4197d2.js +1 -0
- package/dist/web/standalone/.next/static/css/dd4ae3f58ac9b600.css +1 -0
- 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/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/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/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/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/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/package.json +1 -1
- 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/types.ts +2 -1
- 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/settings-manager.ts +9 -0
- 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/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 +26 -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/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-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 +7 -3
- 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/auto-lock-creation.test.ts +5 -13
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +6 -10
- package/src/resources/extensions/gsd/tests/auto-pr-bugs.test.ts +88 -0
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +96 -0
- package/src/resources/extensions/gsd/tests/complete-slice.test.ts +264 -228
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +317 -250
- package/src/resources/extensions/gsd/tests/completed-units-metrics-sync.test.ts +114 -0
- package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +2 -8
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +0 -3
- package/src/resources/extensions/gsd/tests/db-writer.test.ts +79 -0
- 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 +60 -0
- package/src/resources/extensions/gsd/tests/est-annotation-timeout.test.ts +120 -0
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/idle-recovery.test.ts +1 -1
- 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/integration-proof.test.ts +15 -24
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +0 -3
- package/src/resources/extensions/gsd/tests/mcp-status.test.ts +103 -0
- package/src/resources/extensions/gsd/tests/md-importer.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +66 -0
- package/src/resources/extensions/gsd/tests/milestone-transition-state-rebuild.test.ts +8 -9
- package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +42 -3
- package/src/resources/extensions/gsd/tests/parallel-budget-atomicity.test.ts +0 -1
- package/src/resources/extensions/gsd/tests/parallel-crash-recovery.test.ts +0 -7
- 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 +0 -2
- 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/preferences.test.ts +7 -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/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/session-lock-regression.test.ts +1 -4
- 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/sync-lock.test.ts +122 -0
- package/src/resources/extensions/gsd/tests/terminated-transient.test.ts +49 -0
- package/src/resources/extensions/gsd/tests/tool-naming.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/unit-ownership.test.ts +175 -0
- 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/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/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/webpack-9014b5adb127a98a.js +0 -1
- package/dist/web/standalone/.next/static/css/8a727f372cf53002.css +0 -1
- /package/dist/web/standalone/.next/static/{tokoGmfkYfWf1_Yl_Gz7i → j-BskPs0nxxPeYY-bSrab}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{tokoGmfkYfWf1_Yl_Gz7i → j-BskPs0nxxPeYY-bSrab}/_ssgManifest.js +0 -0
|
@@ -26,7 +26,7 @@ You are executing **multiple tasks in parallel** for this slice. The task graph
|
|
|
26
26
|
2. **Wait for all subagents** to complete.
|
|
27
27
|
3. **Verify each dispatched task's outputs** — check that expected files were created/modified, that verification commands pass where applicable, and that each task wrote its own `T##-SUMMARY.md`.
|
|
28
28
|
4. **Do not rewrite successful task summaries or duplicate completion tool calls.** Treat a subagent-written summary as authoritative for that task.
|
|
29
|
-
5. **If a failed task produced no summary,
|
|
29
|
+
5. **If a failed task produced no summary, call `gsd_summary_save`** with `milestone_id: {{milestoneId}}`, `slice_id: {{sliceId}}`, the failed task's `task_id`, and `artifact_type: "SUMMARY"` — include `blocker_discovered: true` and clear failure details in the `content`. Do NOT call `gsd_task_complete` for the failed task — leave it uncompleted so replan/retry has an authoritative record.
|
|
30
30
|
6. **Preserve successful sibling tasks exactly as they landed.** Do not roll back good work because another parallel task failed.
|
|
31
31
|
7. **Do NOT create a batch commit.** The surrounding unit lifecycle owns commits; this parent batch agent should not invent a second commit layer.
|
|
32
32
|
8. **Report the batch outcome** — which tasks succeeded, which failed, and any output collisions or dependency surprises.
|
|
@@ -50,14 +50,14 @@ If all criteria have at least one remaining owning slice, the coverage check pas
|
|
|
50
50
|
|
|
51
51
|
**If the roadmap is still good:**
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
Use `gsd_reassess_roadmap` with `verdict: "roadmap-confirmed"`, an empty `sliceChanges` object, and the assessment text — the tool writes the assessment to the DB and renders `{{assessmentPath}}`. If requirements exist, explicitly note whether requirement coverage remains sound.
|
|
54
54
|
|
|
55
55
|
**If changes are needed:**
|
|
56
56
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
57
|
+
**Persist changes through `gsd_reassess_roadmap`.** Pass: `milestoneId`, `completedSliceId`, `verdict` (e.g. "roadmap-adjusted"), `assessment` (text explaining the decision), and `sliceChanges` with `modified` (array of sliceId, title, risk, depends, demo), `added` (same shape), `removed` (array of slice ID strings). The tool structurally enforces preservation of completed slices, writes the assessment to the DB, re-renders `{{roadmapPath}}`, and renders `{{assessmentPath}}`.
|
|
58
|
+
|
|
59
|
+
If `.gsd/REQUIREMENTS.md` exists and requirement ownership or status changed, update it.
|
|
60
|
+
|
|
61
|
+
{{commitInstruction}}
|
|
62
62
|
|
|
63
63
|
When done, say: "Roadmap reassessed."
|
|
@@ -32,19 +32,8 @@ Consider these captures when rewriting the remaining tasks — they represent th
|
|
|
32
32
|
|
|
33
33
|
1. Read the blocker task summary carefully. Understand exactly what was discovered and why it blocks the current plan.
|
|
34
34
|
2. Analyze the remaining `[ ]` tasks in the slice plan. Determine which are still valid, which need modification, and which should be replaced.
|
|
35
|
-
3. **Persist replan state through `gsd_replan_slice`.** Call it with
|
|
36
|
-
4.
|
|
37
|
-
|
|
38
|
-
- What changed in the plan and why
|
|
39
|
-
- Which incomplete tasks were modified, added, or removed
|
|
40
|
-
- Any new risks or considerations introduced by the replan
|
|
41
|
-
5. If using the degraded fallback, rewrite `{{planPath}}` with the updated slice plan:
|
|
42
|
-
- Keep all `[x]` tasks exactly as they were (same IDs, same descriptions, same checkmarks)
|
|
43
|
-
- Update the `[ ]` tasks to address the blocker
|
|
44
|
-
- Ensure the slice Goal and Demo sections are still achievable with the new tasks, or update them if the blocker fundamentally changes what the slice can deliver
|
|
45
|
-
- Update the Files Likely Touched section if the replan changes which files are affected
|
|
46
|
-
- If a DB-backed planning tool exists for this phase, use it as the source of truth and make any rewritten `PLAN.md` reflect that persisted state rather than bypassing it
|
|
47
|
-
6. If any incomplete task had a `T0x-PLAN.md`, remove or rewrite it to match the new task description.
|
|
48
|
-
7. Do not commit manually — the system auto-commits your changes after this unit completes.
|
|
35
|
+
3. **Persist replan state through `gsd_replan_slice`.** Call it with: `milestoneId`, `sliceId`, `blockerTaskId`, `blockerDescription`, `whatChanged`, `updatedTasks` (array of task objects with taskId, title, description, estimate, files, verify, inputs, expectedOutput), `removedTaskIds` (array of task ID strings). The tool structurally enforces preservation of completed tasks, writes replan history to the DB, re-renders `{{planPath}}`, and renders `{{replanPath}}`.
|
|
36
|
+
4. If any incomplete task had a `T0x-PLAN.md`, remove or rewrite it to match the new task description.
|
|
37
|
+
5. Do not commit manually — the system auto-commits your changes after this unit completes.
|
|
49
38
|
|
|
50
39
|
When done, say: "Slice {{sliceId}} replanned."
|
|
@@ -48,10 +48,10 @@ Research what this slice needs. Narrate key findings and surprises as you go —
|
|
|
48
48
|
4. Use `resolve_library` / `get_library_docs` for unfamiliar libraries — skip this for libraries already used in the codebase
|
|
49
49
|
5. **Web search budget:** You have a limited budget of web searches (max ~15 per session). Use them strategically — prefer `resolve_library` / `get_library_docs` for library documentation. Do NOT repeat the same or similar queries. If a search didn't find what you need, rephrase once or move on. Target 3-5 total web searches for a typical research unit.
|
|
50
50
|
6. Use the **Research** output template from the inlined context above — include only sections that have real content. The template is already inlined above; do NOT attempt to read any template file from disk (there is no `templates/SLICE-RESEARCH.md` — the correct template is already present in this prompt).
|
|
51
|
-
7.
|
|
51
|
+
7. Call `gsd_summary_save` with `milestone_id: {{milestoneId}}`, `slice_id: {{sliceId}}`, `artifact_type: "RESEARCH"`, and the full research markdown as `content` — the tool computes the file path and persists to both DB and disk.
|
|
52
52
|
|
|
53
|
-
The slice directory already exists at `{{slicePath}}/`. Do NOT mkdir
|
|
53
|
+
The slice directory already exists at `{{slicePath}}/`. Do NOT mkdir.
|
|
54
54
|
|
|
55
|
-
**You MUST
|
|
55
|
+
**You MUST call `gsd_summary_save` with the research content before finishing.**
|
|
56
56
|
|
|
57
57
|
When done, say: "Slice {{sliceId}} researched."
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
You are a project reorganization assistant for a GSD (Get Shit Done) project. The user wants to rethink their milestone plan — reorder priorities, remove work that's no longer needed, add new milestones, or restructure dependencies.
|
|
2
|
+
|
|
3
|
+
## Current Milestone Landscape
|
|
4
|
+
|
|
5
|
+
{{rethinkData}}
|
|
6
|
+
|
|
7
|
+
## Detailed Milestone Context
|
|
8
|
+
|
|
9
|
+
{{existingMilestonesContext}}
|
|
10
|
+
|
|
11
|
+
## Your Role
|
|
12
|
+
|
|
13
|
+
1. Present the current milestone order as a clear numbered list with status indicators (e.g. ✅ complete, ▶ active, ⏳ pending, ⏸ parked)
|
|
14
|
+
2. Ask: **"What would you like to change?"**
|
|
15
|
+
3. Execute changes conversationally, confirming destructive operations before proceeding
|
|
16
|
+
|
|
17
|
+
## Supported Operations
|
|
18
|
+
|
|
19
|
+
<!-- NOTE: Park, unpark, reorder, discard, and dependency-update operations are intentionally
|
|
20
|
+
file-based. No gsd_* tool API exists for these milestone-lifecycle mutations yet.
|
|
21
|
+
The single-writer DB tools (gsd_plan_milestone, gsd_complete_milestone, etc.) own
|
|
22
|
+
create and complete; queue management is file-driven until tool support is added. -->
|
|
23
|
+
|
|
24
|
+
### Reorder milestones
|
|
25
|
+
Change execution order of pending/active milestones. Write `.gsd/QUEUE-ORDER.json`:
|
|
26
|
+
```json
|
|
27
|
+
{ "order": ["M003", "M001", "M002"], "updatedAt": "<ISO timestamp>" }
|
|
28
|
+
```
|
|
29
|
+
Only include non-complete milestone IDs. Validate dependency constraints before saving.
|
|
30
|
+
|
|
31
|
+
### Park a milestone
|
|
32
|
+
Temporarily shelve a milestone (reversible). Create a `{ID}-PARKED.md` file in the milestone directory:
|
|
33
|
+
```markdown
|
|
34
|
+
---
|
|
35
|
+
parked_at: <ISO timestamp>
|
|
36
|
+
reason: "<reason>"
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
# {ID} — Parked
|
|
40
|
+
|
|
41
|
+
> <reason>
|
|
42
|
+
```
|
|
43
|
+
**Bias toward parking over discarding** when a milestone has any completed slices or tasks.
|
|
44
|
+
|
|
45
|
+
### Unpark a milestone
|
|
46
|
+
Remove the `{ID}-PARKED.md` file from the milestone directory to reactivate it.
|
|
47
|
+
|
|
48
|
+
### Discard a milestone
|
|
49
|
+
**Permanently** delete a milestone directory and prune it from QUEUE-ORDER.json. **Always confirm with the user before discarding.** Warn explicitly if the milestone has completed work.
|
|
50
|
+
|
|
51
|
+
### Add a new milestone
|
|
52
|
+
Use the `gsd_milestone_generate_id` tool to get the next ID, then call `gsd_summary_save` with `milestone_id: {ID}`, `artifact_type: "CONTEXT"`, and the scope/goals/success criteria as `content` — the tool writes the context file to disk and persists to DB. Update QUEUE-ORDER.json to place it at the desired position.
|
|
53
|
+
|
|
54
|
+
### Update dependencies
|
|
55
|
+
Edit `depends_on` in the YAML frontmatter of a milestone's `{ID}-CONTEXT.md` file. For example:
|
|
56
|
+
```yaml
|
|
57
|
+
depends_on: [M001, M003]
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Dependency Validation Rules
|
|
61
|
+
|
|
62
|
+
Before applying any reorder, verify:
|
|
63
|
+
- A milestone **cannot** be scheduled before any milestone in its `depends_on` list (would_block)
|
|
64
|
+
- Circular dependencies are forbidden
|
|
65
|
+
- Dependencies on non-existent milestones are invalid (missing_dep)
|
|
66
|
+
- Completed milestones always satisfy dependencies regardless of position
|
|
67
|
+
|
|
68
|
+
If a proposed order would violate constraints, explain the issue and suggest alternatives (e.g. removing the dependency, reordering differently, or parking the blocker).
|
|
69
|
+
|
|
70
|
+
## After Each Change
|
|
71
|
+
|
|
72
|
+
1. Execute the change (write/delete files, update QUEUE-ORDER.json)
|
|
73
|
+
2. Show the updated milestone order
|
|
74
|
+
3. Note if the active milestone changed as a result
|
|
75
|
+
4. Ask if there's anything else to adjust
|
|
76
|
+
|
|
77
|
+
## Important Constraints
|
|
78
|
+
|
|
79
|
+
- Do NOT modify completed milestones — they're done
|
|
80
|
+
- Do NOT park completed milestones — it would corrupt dependency satisfaction
|
|
81
|
+
- Park is preferred over discard when a milestone has any completed work
|
|
82
|
+
- Always persist queue order changes to `.gsd/QUEUE-ORDER.json`
|
|
83
|
+
- After changes, run `git add .gsd/ && git commit -m "docs(gsd): rethink milestone plan"` to persist (rethink runs interactively outside auto-mode, so no system auto-commit)
|
|
@@ -112,7 +112,7 @@ In all modes, slices commit sequentially on the active branch; there are no per-
|
|
|
112
112
|
- **Milestones** are major project phases (M001, M002, ...)
|
|
113
113
|
- **Slices** are demoable vertical increments (S01, S02, ...) ordered by risk. After each slice completes, the roadmap is reassessed before the next slice begins.
|
|
114
114
|
- **Tasks** are single-context-window units of work (T01, T02, ...)
|
|
115
|
-
- Checkboxes in roadmap and plan files track completion (`[ ]` → `[x]`)
|
|
115
|
+
- Checkboxes in roadmap and plan files track completion (`[ ]` → `[x]`) — toggled automatically by gsd_* tools, never edited manually
|
|
116
116
|
- Summaries compress prior work - read them instead of re-reading all task details
|
|
117
117
|
- `STATE.md` is a system-managed status file — rebuilt automatically after each unit completes
|
|
118
118
|
|
|
@@ -16,6 +16,8 @@ All relevant context has been preloaded below — the roadmap, all slice summari
|
|
|
16
16
|
|
|
17
17
|
{{inlinedContext}}
|
|
18
18
|
|
|
19
|
+
{{skillActivation}}
|
|
20
|
+
|
|
19
21
|
## Validation Steps
|
|
20
22
|
|
|
21
23
|
1. For each **success criterion** in `{{roadmapPath}}`, check whether slice summaries and UAT results provide evidence that it was met. Record pass/fail per criterion.
|
|
@@ -25,47 +27,15 @@ All relevant context has been preloaded below — the roadmap, all slice summari
|
|
|
25
27
|
5. Determine a verdict:
|
|
26
28
|
- `pass` — all criteria met, all slices delivered, no gaps
|
|
27
29
|
- `needs-attention` — minor gaps that do not block completion (document them)
|
|
28
|
-
- `needs-remediation` — material gaps found;
|
|
29
|
-
|
|
30
|
-
## Output
|
|
31
|
-
|
|
32
|
-
Write `{{validationPath}}` with this structure:
|
|
33
|
-
|
|
34
|
-
```markdown
|
|
35
|
-
---
|
|
36
|
-
verdict: <pass|needs-attention|needs-remediation>
|
|
37
|
-
remediation_round: {{remediationRound}}
|
|
38
|
-
---
|
|
39
|
-
|
|
40
|
-
# Milestone Validation: {{milestoneId}}
|
|
30
|
+
- `needs-remediation` — material gaps found; remediation slices must be added to the roadmap
|
|
41
31
|
|
|
42
|
-
##
|
|
43
|
-
- [x] Criterion 1 — evidence: ...
|
|
44
|
-
- [ ] Criterion 2 — gap: ...
|
|
32
|
+
## Persist Validation
|
|
45
33
|
|
|
46
|
-
|
|
47
|
-
| Slice | Claimed | Delivered | Status |
|
|
48
|
-
|-------|---------|-----------|--------|
|
|
49
|
-
| S01 | ... | ... | pass |
|
|
50
|
-
|
|
51
|
-
## Cross-Slice Integration
|
|
52
|
-
(any boundary mismatches)
|
|
53
|
-
|
|
54
|
-
## Requirement Coverage
|
|
55
|
-
(any unaddressed requirements)
|
|
56
|
-
|
|
57
|
-
## Verdict Rationale
|
|
58
|
-
(why this verdict was chosen)
|
|
59
|
-
|
|
60
|
-
## Remediation Plan
|
|
61
|
-
(only if verdict is needs-remediation — list new slices to add to the roadmap)
|
|
62
|
-
```
|
|
34
|
+
**Persist validation results through `gsd_validate_milestone`.** Call it with: `milestoneId`, `verdict`, `remediationRound`, `successCriteriaChecklist`, `sliceDeliveryAudit`, `crossSliceIntegration`, `requirementCoverage`, `verdictRationale`, and `remediationPlan` (if verdict is `needs-remediation`). The tool writes the validation to the DB and renders VALIDATION.md to disk.
|
|
63
35
|
|
|
64
36
|
If verdict is `needs-remediation`:
|
|
65
|
-
-
|
|
66
|
-
- These slices will be planned and executed before validation re-runs
|
|
67
|
-
|
|
68
|
-
**You MUST write `{{validationPath}}` before finishing.**
|
|
37
|
+
- After calling `gsd_validate_milestone`, use `gsd_reassess_roadmap` to add remediation slices. Pass `milestoneId`, a synthetic `completedSliceId` (e.g. "VALIDATION"), `verdict: "roadmap-adjusted"`, `assessment` text, and `sliceChanges` with the new slices in the `added` array. The tool persists the changes to the DB and re-renders ROADMAP.md.
|
|
38
|
+
- These remediation slices will be planned and executed before validation re-runs.
|
|
69
39
|
|
|
70
40
|
**File system safety:** When scanning milestone directories for evidence, use `ls` or `find` to list directory contents first — never pass a directory path (e.g. `tasks/`, `slices/`) directly to the `read` tool. The `read` tool only accepts file paths, not directories.
|
|
71
41
|
|
|
@@ -10,6 +10,10 @@
|
|
|
10
10
|
export function classifyProviderError(errorMsg) {
|
|
11
11
|
const isRateLimit = /rate.?limit|too many requests|429/i.test(errorMsg);
|
|
12
12
|
const isServerError = /internal server error|500|502|503|overloaded|server_error|api_error|service.?unavailable/i.test(errorMsg);
|
|
13
|
+
// Connection/process errors — transient, auto-resume after brief backoff (#2309).
|
|
14
|
+
// These indicate the process was killed, the connection was reset, or a network
|
|
15
|
+
// blip occurred. They are NOT permanent failures.
|
|
16
|
+
const isConnectionError = /terminated|connection.?reset|connection.?refused|other side closed|fetch failed|network.?(?:is\s+)?unavailable|ECONNREFUSED|ECONNRESET|EPIPE/i.test(errorMsg);
|
|
13
17
|
// Permanent errors — never auto-resume
|
|
14
18
|
const isPermanent = /auth|unauthorized|forbidden|invalid.*key|invalid.*api|billing|quota exceeded|account/i.test(errorMsg);
|
|
15
19
|
if (isPermanent && !isRateLimit) {
|
|
@@ -24,6 +28,9 @@ export function classifyProviderError(errorMsg) {
|
|
|
24
28
|
if (isServerError) {
|
|
25
29
|
return { isTransient: true, isRateLimit: false, suggestedDelayMs: 30_000 }; // 30s for server errors
|
|
26
30
|
}
|
|
31
|
+
if (isConnectionError) {
|
|
32
|
+
return { isTransient: true, isRateLimit: false, suggestedDelayMs: 15_000 }; // 15s for connection errors
|
|
33
|
+
}
|
|
27
34
|
// Unknown error — treat as permanent (user reviews)
|
|
28
35
|
return { isTransient: false, isRateLimit: false, suggestedDelayMs: 0 };
|
|
29
36
|
}
|
|
@@ -89,16 +89,17 @@ export function readRepoMeta(externalPath) {
|
|
|
89
89
|
* Returns true when ALL of:
|
|
90
90
|
* 1. basePath is inside a git repo (git rev-parse succeeds)
|
|
91
91
|
* 2. The resolved git root is a proper ancestor of basePath
|
|
92
|
-
* 3. There is no `.gsd` directory at the git root
|
|
93
|
-
* has not been
|
|
92
|
+
* 3. There is no *project* `.gsd` directory at the git root or any
|
|
93
|
+
* intermediate ancestor (the parent project has not been
|
|
94
|
+
* initialised with GSD)
|
|
94
95
|
*
|
|
95
96
|
* When true, the caller should run `git init` at basePath so that
|
|
96
97
|
* `repoIdentity()` produces a hash unique to this directory, preventing
|
|
97
98
|
* cross-project state leaks (#1639).
|
|
98
99
|
*
|
|
99
|
-
* When the git root already has `.gsd`, the directory is a
|
|
100
|
-
* subdirectory of an existing GSD project — `cd src/ && /gsd`
|
|
101
|
-
* still load the parent project's milestones.
|
|
100
|
+
* When the git root already has a project `.gsd`, the directory is a
|
|
101
|
+
* legitimate subdirectory of an existing GSD project — `cd src/ && /gsd`
|
|
102
|
+
* should still load the parent project's milestones.
|
|
102
103
|
*/
|
|
103
104
|
export function isInheritedRepo(basePath) {
|
|
104
105
|
try {
|
|
@@ -109,12 +110,12 @@ export function isInheritedRepo(basePath) {
|
|
|
109
110
|
return false; // basePath IS the root
|
|
110
111
|
// The git root is a proper ancestor. Check whether it already has .gsd
|
|
111
112
|
// (i.e. the parent project was initialised with GSD).
|
|
112
|
-
if (
|
|
113
|
+
if (isProjectGsd(join(root, ".gsd")))
|
|
113
114
|
return false;
|
|
114
115
|
// Also walk up from basePath to the git root checking for .gsd
|
|
115
116
|
let dir = normalizedBase;
|
|
116
117
|
while (dir !== normalizedRoot && dir !== dirname(dir)) {
|
|
117
|
-
if (
|
|
118
|
+
if (isProjectGsd(join(dir, ".gsd")))
|
|
118
119
|
return false;
|
|
119
120
|
dir = dirname(dir);
|
|
120
121
|
}
|
|
@@ -124,6 +125,43 @@ export function isInheritedRepo(basePath) {
|
|
|
124
125
|
return false;
|
|
125
126
|
}
|
|
126
127
|
}
|
|
128
|
+
/**
|
|
129
|
+
* Distinguish a *project* `.gsd` from the global `~/.gsd` state directory.
|
|
130
|
+
*
|
|
131
|
+
* A project `.gsd` is either:
|
|
132
|
+
* - A symlink to an external state directory (normal post-migration layout)
|
|
133
|
+
* - A legacy real directory that is NOT the global GSD home
|
|
134
|
+
*
|
|
135
|
+
* When the user's home directory is itself a git repo (e.g. dotfile managers),
|
|
136
|
+
* `~/.gsd` exists but is the global state directory — not a project `.gsd`.
|
|
137
|
+
* Treating it as a project `.gsd` would cause isInheritedRepo() to wrongly
|
|
138
|
+
* conclude that subdirectories are part of the home "project" (#2393).
|
|
139
|
+
*/
|
|
140
|
+
function isProjectGsd(gsdPath) {
|
|
141
|
+
if (!existsSync(gsdPath))
|
|
142
|
+
return false;
|
|
143
|
+
try {
|
|
144
|
+
const stat = lstatSync(gsdPath);
|
|
145
|
+
// Symlinks are always project .gsd (created by ensureGsdSymlink).
|
|
146
|
+
if (stat.isSymbolicLink())
|
|
147
|
+
return true;
|
|
148
|
+
// For real directories, check that this isn't the global GSD home.
|
|
149
|
+
// Recompute gsdHome dynamically so env overrides (GSD_HOME) are
|
|
150
|
+
// picked up at call time, not just at module load time.
|
|
151
|
+
if (stat.isDirectory()) {
|
|
152
|
+
const currentGsdHome = process.env.GSD_HOME || join(homedir(), ".gsd");
|
|
153
|
+
const normalizedGsdPath = canonicalizeExistingPath(gsdPath);
|
|
154
|
+
const normalizedGsdHome = canonicalizeExistingPath(currentGsdHome);
|
|
155
|
+
if (normalizedGsdPath === normalizedGsdHome)
|
|
156
|
+
return false;
|
|
157
|
+
return true;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
// lstat failed — treat as no .gsd present
|
|
162
|
+
}
|
|
163
|
+
return false;
|
|
164
|
+
}
|
|
127
165
|
// ─── Repo Identity ──────────────────────────────────────────────────────────
|
|
128
166
|
/**
|
|
129
167
|
* Get the git remote URL for "origin", or "" if no remote is configured.
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GSD Rethink — Conversational project reorganization.
|
|
3
|
+
*
|
|
4
|
+
* Collects a snapshot of all milestones (status, dependencies, slice progress,
|
|
5
|
+
* queue order) and dispatches a prompt that turns Claude into a reorganization
|
|
6
|
+
* assistant. Claude can then reorder, park, unpark, discard, or add milestones
|
|
7
|
+
* through conversation.
|
|
8
|
+
*/
|
|
9
|
+
import { existsSync } from "node:fs";
|
|
10
|
+
import { isAutoActive } from "./auto.js";
|
|
11
|
+
import { deriveState } from "./state.js";
|
|
12
|
+
import { gsdRoot } from "./paths.js";
|
|
13
|
+
import { findMilestoneIds } from "./milestone-ids.js";
|
|
14
|
+
import { loadQueueOrder, validateQueueOrder } from "./queue-order.js";
|
|
15
|
+
import { getParkedReason } from "./milestone-actions.js";
|
|
16
|
+
import { getMilestoneSlices, isDbAvailable } from "./gsd-db.js";
|
|
17
|
+
import { buildExistingMilestonesContext } from "./guided-flow-queue.js";
|
|
18
|
+
import { loadPrompt } from "./prompt-loader.js";
|
|
19
|
+
// ─── Entry Point ──────────────────────────────────────────────────────────────
|
|
20
|
+
export async function handleRethink(_args, ctx, pi) {
|
|
21
|
+
if (isAutoActive()) {
|
|
22
|
+
ctx.ui.notify("Cannot rethink while auto-mode is active. Stop auto-mode first.", "error");
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const basePath = process.cwd();
|
|
26
|
+
const root = gsdRoot(basePath);
|
|
27
|
+
if (!existsSync(root)) {
|
|
28
|
+
ctx.ui.notify("No GSD project found. Run /gsd init first.", "warning");
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
ctx.ui.notify("Building project snapshot for rethink...", "info");
|
|
32
|
+
const state = await deriveState(basePath);
|
|
33
|
+
const milestoneIds = findMilestoneIds(basePath);
|
|
34
|
+
if (milestoneIds.length === 0) {
|
|
35
|
+
ctx.ui.notify("No milestones exist yet. Nothing to rethink.", "warning");
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
const queueOrder = loadQueueOrder(basePath);
|
|
39
|
+
const rethinkData = buildRethinkData(basePath, milestoneIds, state, queueOrder);
|
|
40
|
+
const existingMilestonesContext = await buildExistingMilestonesContext(basePath, milestoneIds, state);
|
|
41
|
+
const content = loadPrompt("rethink", {
|
|
42
|
+
rethinkData,
|
|
43
|
+
existingMilestonesContext,
|
|
44
|
+
});
|
|
45
|
+
pi.sendMessage({ customType: "gsd-rethink", content, display: false }, { triggerTurn: true });
|
|
46
|
+
}
|
|
47
|
+
// ─── Data Builder ─────────────────────────────────────────────────────────────
|
|
48
|
+
function buildRethinkData(basePath, milestoneIds, state, queueOrder) {
|
|
49
|
+
const lines = [];
|
|
50
|
+
const dbAvailable = isDbAvailable();
|
|
51
|
+
// ── Summary stats ───────────────────────────────────────────────────
|
|
52
|
+
const counts = { complete: 0, active: 0, pending: 0, parked: 0 };
|
|
53
|
+
for (const entry of state.registry) {
|
|
54
|
+
if (entry.status in counts)
|
|
55
|
+
counts[entry.status]++;
|
|
56
|
+
}
|
|
57
|
+
lines.push("### Summary");
|
|
58
|
+
lines.push(`${counts.complete} complete, ${counts.active} active, ${counts.pending} pending, ${counts.parked} parked — ${milestoneIds.length} total`);
|
|
59
|
+
lines.push(`Queue order source: ${queueOrder ? "explicit QUEUE-ORDER.json" : "default numeric (by ID)"}`);
|
|
60
|
+
if (state.activeMilestone) {
|
|
61
|
+
lines.push(`Active milestone: ${state.activeMilestone}`);
|
|
62
|
+
}
|
|
63
|
+
lines.push("");
|
|
64
|
+
// ── Milestone table ─────────────────────────────────────────────────
|
|
65
|
+
lines.push("### Execution Order");
|
|
66
|
+
lines.push("");
|
|
67
|
+
lines.push("| # | ID | Title | Status | Dependencies | Slices |");
|
|
68
|
+
lines.push("|---|-----|-------|--------|--------------|--------|");
|
|
69
|
+
for (let i = 0; i < milestoneIds.length; i++) {
|
|
70
|
+
const mid = milestoneIds[i];
|
|
71
|
+
const entry = state.registry.find(m => m.id === mid);
|
|
72
|
+
const title = entry?.title ?? mid;
|
|
73
|
+
const status = entry?.status ?? "unknown";
|
|
74
|
+
const deps = entry?.dependsOn?.length ? entry.dependsOn.join(", ") : "—";
|
|
75
|
+
let sliceInfo = "—";
|
|
76
|
+
if (dbAvailable && status !== "complete") {
|
|
77
|
+
const slices = getMilestoneSlices(mid);
|
|
78
|
+
if (slices.length > 0) {
|
|
79
|
+
const done = slices.filter(s => s.status === "complete").length;
|
|
80
|
+
sliceInfo = `${done}/${slices.length} complete`;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
// Add parked reason if applicable
|
|
84
|
+
let statusDisplay = status;
|
|
85
|
+
if (status === "parked") {
|
|
86
|
+
const reason = getParkedReason(basePath, mid);
|
|
87
|
+
if (reason)
|
|
88
|
+
statusDisplay = `parked (${reason})`;
|
|
89
|
+
}
|
|
90
|
+
lines.push(`| ${i + 1} | ${mid} | ${title} | ${statusDisplay} | ${deps} | ${sliceInfo} |`);
|
|
91
|
+
}
|
|
92
|
+
// ── Dependency validation ───────────────────────────────────────────
|
|
93
|
+
const pendingIds = milestoneIds.filter(mid => {
|
|
94
|
+
const entry = state.registry.find(m => m.id === mid);
|
|
95
|
+
return entry?.status !== "complete";
|
|
96
|
+
});
|
|
97
|
+
const completedIds = new Set(state.registry.filter(m => m.status === "complete").map(m => m.id));
|
|
98
|
+
const depsMap = new Map();
|
|
99
|
+
for (const entry of state.registry) {
|
|
100
|
+
if (entry.dependsOn?.length) {
|
|
101
|
+
depsMap.set(entry.id, entry.dependsOn);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
if (pendingIds.length > 0 && depsMap.size > 0) {
|
|
105
|
+
const validation = validateQueueOrder(pendingIds, depsMap, completedIds);
|
|
106
|
+
if (validation.violations.length > 0) {
|
|
107
|
+
lines.push("");
|
|
108
|
+
lines.push("### Dependency Issues");
|
|
109
|
+
for (const v of validation.violations) {
|
|
110
|
+
lines.push(`- **${v.type}**: ${v.message}`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return lines.join("\n");
|
|
115
|
+
}
|
|
@@ -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
|