@opengsd/gsd-pi 1.8.1 → 1.9.0-dev.5c1a3ff2
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 +10 -8
- package/dist/cli.js +5 -1
- package/dist/headless-events.d.ts +2 -1
- package/dist/headless-events.js +11 -3
- package/dist/headless-milestone-readiness.d.ts +29 -0
- package/dist/headless-milestone-readiness.js +161 -0
- package/dist/headless.js +25 -2
- package/dist/print-mode-exit.d.ts +12 -0
- package/dist/print-mode-exit.js +14 -0
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/GSD-WORKFLOW.md +18 -49
- package/dist/resources/extensions/browser-tools/capture.js +2 -77
- package/dist/resources/extensions/browser-tools/screenshot-constraints.js +83 -0
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +17 -2
- package/dist/resources/extensions/claude-code-cli/turn-assembler.js +30 -2
- package/dist/resources/extensions/gsd/artifact-verification.js +3 -4
- package/dist/resources/extensions/gsd/auto-artifact-paths.js +16 -10
- package/dist/resources/extensions/gsd/auto-dispatch.js +74 -19
- package/dist/resources/extensions/gsd/auto-post-unit.js +4 -0
- package/dist/resources/extensions/gsd/auto-prompts.js +125 -18
- package/dist/resources/extensions/gsd/auto-recovery.js +10 -5
- package/dist/resources/extensions/gsd/auto-worktree-cleanup.js +4 -0
- package/dist/resources/extensions/gsd/auto-worktree-teardown.js +1 -1
- package/dist/resources/extensions/gsd/auto.js +5 -1
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +80 -4
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +31 -5
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +10 -3
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +88 -50
- package/dist/resources/extensions/gsd/command-feedback.js +16 -12
- package/dist/resources/extensions/gsd/compat/compat-marker.js +19 -2
- package/dist/resources/extensions/gsd/constants.js +12 -13
- package/dist/resources/extensions/gsd/context-masker.js +97 -21
- package/dist/resources/extensions/gsd/db/command-queue.js +7 -2
- package/dist/resources/extensions/gsd/db/engine.js +51 -16
- package/dist/resources/extensions/gsd/db/writers/cascades.js +5 -1
- package/dist/resources/extensions/gsd/db/writers/status.js +13 -3
- package/dist/resources/extensions/gsd/db-base-schema.js +28 -0
- package/dist/resources/extensions/gsd/db-migration-steps.js +30 -0
- package/dist/resources/extensions/gsd/db-schema-metadata.js +4 -1
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +26 -4
- package/dist/resources/extensions/gsd/doctor-engine-checks.js +3 -6
- package/dist/resources/extensions/gsd/flat-phase-migration.js +156 -21
- package/dist/resources/extensions/gsd/git-service.js +19 -7
- package/dist/resources/extensions/gsd/gsd-db.js +187 -45
- package/dist/resources/extensions/gsd/guided-flow.js +38 -13
- package/dist/resources/extensions/gsd/markdown-renderer.js +17 -13
- package/dist/resources/extensions/gsd/md-importer.js +107 -20
- package/dist/resources/extensions/gsd/migrate/command.js +19 -162
- package/dist/resources/extensions/gsd/migrate/execution.js +98 -0
- package/dist/resources/extensions/gsd/migrate/plan.js +49 -0
- package/dist/resources/extensions/gsd/migrate/planning-writer.js +12 -17
- package/dist/resources/extensions/gsd/migrate/presentation.js +64 -0
- package/dist/resources/extensions/gsd/model-cost-table.js +2 -0
- package/dist/resources/extensions/gsd/model-router.js +11 -0
- package/dist/resources/extensions/gsd/parallel-eligibility.js +5 -4
- package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +28 -43
- package/dist/resources/extensions/gsd/paths.js +55 -11
- package/dist/resources/extensions/gsd/phase-anchor.js +7 -2
- package/dist/resources/extensions/gsd/planning-subagent-policy.js +37 -0
- package/dist/resources/extensions/gsd/planning-subagent-registry.js +25 -0
- package/dist/resources/extensions/gsd/post-execution-checks.js +4 -4
- package/dist/resources/extensions/gsd/preferences-types.js +5 -0
- package/dist/resources/extensions/gsd/preferences-validation.js +48 -1
- package/dist/resources/extensions/gsd/preferences.js +17 -0
- package/dist/resources/extensions/gsd/prompts/refine-slice.md +2 -2
- package/dist/resources/extensions/gsd/provider-payload-policy.js +16 -5
- package/dist/resources/extensions/gsd/safety/destructive-guard.js +1 -1
- package/dist/resources/extensions/gsd/safety/evidence-collector.js +26 -1
- package/dist/resources/extensions/gsd/safety/evidence-cross-ref.js +30 -5
- package/dist/resources/extensions/gsd/skill-activation.js +17 -3
- package/dist/resources/extensions/gsd/state-reconciliation/drift/external-markdown-edit.js +27 -13
- package/dist/resources/extensions/gsd/state-reconciliation/drift/external-planning-edit.js +13 -3
- package/dist/resources/extensions/gsd/stop-notice.js +15 -1
- package/dist/resources/extensions/gsd/sync-lock.js +13 -7
- package/dist/resources/extensions/gsd/templates/PREFERENCES.md +5 -0
- package/dist/resources/extensions/gsd/tools/complete-task.js +94 -6
- package/dist/resources/extensions/gsd/tools/plan-task.js +13 -15
- package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +18 -15
- package/dist/resources/extensions/gsd/tools/reopen-milestone.js +14 -5
- package/dist/resources/extensions/gsd/tools/reopen-slice.js +15 -5
- package/dist/resources/extensions/gsd/tools/reopen-task.js +16 -10
- package/dist/resources/extensions/gsd/tools/replan-task.js +128 -0
- package/dist/resources/extensions/gsd/tools/rework-brief.js +74 -0
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +81 -0
- package/dist/resources/extensions/gsd/unit-context-composer.js +28 -5
- package/dist/resources/extensions/gsd/unit-registry.js +4 -0
- package/dist/resources/extensions/gsd/uok/plan-v2.js +19 -3
- package/dist/resources/extensions/gsd/workflow-projections.js +2 -3
- package/dist/resources/extensions/gsd/workspace.js +2 -1
- package/dist/resources/extensions/gsd/worktree-state-projection.js +6 -0
- package/dist/resources/extensions/mac-tools/index.js +31 -9
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +8 -8
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- 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 +1 -1
- 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 +4 -4
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -4
- 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/experimental/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/experimental/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/mcp-connections/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/mcp-connections/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/notifications/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 +2 -2
- 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 +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.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 +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.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 +5 -5
- 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 +5 -5
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +4 -4
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/page.js +2 -2
- package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +8 -8
- package/dist/web/standalone/.next/server/chunks/2842.js +4 -4
- package/dist/web/standalone/.next/server/chunks/8357.js +3 -3
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware.js +3 -3
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/app/_not-found/page-a6fb1847f67f167c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/{layout-b35cbfff38aaf4cf.js → layout-4ae2d68984392bbf.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/page-72a856634ad14c10.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{main-app-590a74400e35f685.js → main-app-90d1d8d5e5d2dc6b.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-1115d46ac61b9823.js +1 -0
- package/dist/web/standalone/.next/static/css/3b1ceb7abfb9a230.css +1 -0
- package/dist/web/standalone/node_modules/@gsd/native/package.json +1 -1
- 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/package.json +0 -1
- package/dist/web/standalone/server.js +1 -1
- package/dist/web-mode.js +31 -3
- package/integrations/hermes/open_gsd_hermes/gsd_client.py +1 -1
- package/integrations/hermes/pyproject.toml +1 -1
- package/package.json +12 -10
- package/packages/cloud-mcp-gateway/package.json +2 -2
- package/packages/contracts/dist/workflow.d.ts +14 -0
- package/packages/contracts/dist/workflow.d.ts.map +1 -1
- package/packages/contracts/dist/workflow.js +16 -0
- package/packages/contracts/dist/workflow.js.map +1 -1
- package/packages/contracts/package.json +1 -1
- package/packages/daemon/dist/cloud-config.d.ts +1 -1
- package/packages/daemon/dist/cloud-config.d.ts.map +1 -1
- package/packages/daemon/dist/cloud-config.js +5 -1
- package/packages/daemon/dist/cloud-config.js.map +1 -1
- package/packages/daemon/dist/cloud-config.test.js +51 -1
- package/packages/daemon/dist/cloud-config.test.js.map +1 -1
- package/packages/daemon/dist/local-tool-executor.d.ts.map +1 -1
- package/packages/daemon/dist/local-tool-executor.js +2 -0
- package/packages/daemon/dist/local-tool-executor.js.map +1 -1
- package/packages/daemon/package.json +6 -6
- package/packages/gsd-agent-core/dist/compaction/compaction.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/compaction/compaction.js +36 -4
- package/packages/gsd-agent-core/dist/compaction/compaction.js.map +1 -1
- package/packages/gsd-agent-core/dist/sdk.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/sdk.js +1 -0
- package/packages/gsd-agent-core/dist/sdk.js.map +1 -1
- package/packages/gsd-agent-core/package.json +5 -5
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/gsd-cloud/dist/cli.d.ts +5 -0
- package/packages/gsd-cloud/dist/cli.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/cli.js +160 -0
- package/packages/gsd-cloud/dist/cli.js.map +1 -0
- package/packages/gsd-cloud/dist/cloud-config.d.ts +19 -0
- package/packages/gsd-cloud/dist/cloud-config.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/cloud-config.js +231 -0
- package/packages/gsd-cloud/dist/cloud-config.js.map +1 -0
- package/packages/gsd-cloud/dist/cloud-config.test.d.ts +2 -0
- package/packages/gsd-cloud/dist/cloud-config.test.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/cloud-config.test.js +118 -0
- package/packages/gsd-cloud/dist/cloud-config.test.js.map +1 -0
- package/packages/gsd-cloud/dist/cloud-gateway-lookup.test.d.ts +2 -0
- package/packages/gsd-cloud/dist/cloud-gateway-lookup.test.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/cloud-gateway-lookup.test.js +37 -0
- package/packages/gsd-cloud/dist/cloud-gateway-lookup.test.js.map +1 -0
- package/packages/gsd-cloud/dist/cloud-runtime.d.ts +35 -0
- package/packages/gsd-cloud/dist/cloud-runtime.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/cloud-runtime.js +258 -0
- package/packages/gsd-cloud/dist/cloud-runtime.js.map +1 -0
- package/packages/gsd-cloud/dist/cloud-runtime.test.d.ts +2 -0
- package/packages/gsd-cloud/dist/cloud-runtime.test.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/cloud-runtime.test.js +88 -0
- package/packages/gsd-cloud/dist/cloud-runtime.test.js.map +1 -0
- package/packages/gsd-cloud/dist/cloud-token.d.ts +3 -0
- package/packages/gsd-cloud/dist/cloud-token.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/cloud-token.js +37 -0
- package/packages/gsd-cloud/dist/cloud-token.js.map +1 -0
- package/packages/gsd-cloud/dist/config.d.ts +17 -0
- package/packages/gsd-cloud/dist/config.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/config.js +146 -0
- package/packages/gsd-cloud/dist/config.js.map +1 -0
- package/packages/gsd-cloud/dist/device-flow.d.ts +24 -0
- package/packages/gsd-cloud/dist/device-flow.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/device-flow.js +128 -0
- package/packages/gsd-cloud/dist/device-flow.js.map +1 -0
- package/packages/gsd-cloud/dist/device-flow.test.d.ts +2 -0
- package/packages/gsd-cloud/dist/device-flow.test.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/device-flow.test.js +155 -0
- package/packages/gsd-cloud/dist/device-flow.test.js.map +1 -0
- package/packages/gsd-cloud/dist/executors/claude-executor.d.ts +6 -0
- package/packages/gsd-cloud/dist/executors/claude-executor.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/executors/claude-executor.js +15 -0
- package/packages/gsd-cloud/dist/executors/claude-executor.js.map +1 -0
- package/packages/gsd-cloud/dist/executors/codex-executor.d.ts +6 -0
- package/packages/gsd-cloud/dist/executors/codex-executor.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/executors/codex-executor.js +15 -0
- package/packages/gsd-cloud/dist/executors/codex-executor.js.map +1 -0
- package/packages/gsd-cloud/dist/executors/executor.d.ts +28 -0
- package/packages/gsd-cloud/dist/executors/executor.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/executors/executor.js +11 -0
- package/packages/gsd-cloud/dist/executors/executor.js.map +1 -0
- package/packages/gsd-cloud/dist/executors/gsd-pi-executor.d.ts +34 -0
- package/packages/gsd-cloud/dist/executors/gsd-pi-executor.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/executors/gsd-pi-executor.js +179 -0
- package/packages/gsd-cloud/dist/executors/gsd-pi-executor.js.map +1 -0
- package/packages/gsd-cloud/dist/executors/gsd-pi-executor.test.d.ts +2 -0
- package/packages/gsd-cloud/dist/executors/gsd-pi-executor.test.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/executors/gsd-pi-executor.test.js +44 -0
- package/packages/gsd-cloud/dist/executors/gsd-pi-executor.test.js.map +1 -0
- package/packages/gsd-cloud/dist/executors/index.d.ts +17 -0
- package/packages/gsd-cloud/dist/executors/index.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/executors/index.js +29 -0
- package/packages/gsd-cloud/dist/executors/index.js.map +1 -0
- package/packages/gsd-cloud/dist/executors/mcp-stdio-client.d.ts +36 -0
- package/packages/gsd-cloud/dist/executors/mcp-stdio-client.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/executors/mcp-stdio-client.js +176 -0
- package/packages/gsd-cloud/dist/executors/mcp-stdio-client.js.map +1 -0
- package/packages/gsd-cloud/dist/executors/mcp-stdio-client.test.d.ts +2 -0
- package/packages/gsd-cloud/dist/executors/mcp-stdio-client.test.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/executors/mcp-stdio-client.test.js +34 -0
- package/packages/gsd-cloud/dist/executors/mcp-stdio-client.test.js.map +1 -0
- package/packages/gsd-cloud/dist/index.d.ts +7 -0
- package/packages/gsd-cloud/dist/index.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/index.js +8 -0
- package/packages/gsd-cloud/dist/index.js.map +1 -0
- package/packages/gsd-cloud/dist/inject-gateway.d.ts +16 -0
- package/packages/gsd-cloud/dist/inject-gateway.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/inject-gateway.js +29 -0
- package/packages/gsd-cloud/dist/inject-gateway.js.map +1 -0
- package/packages/gsd-cloud/dist/inject-gateway.test.d.ts +2 -0
- package/packages/gsd-cloud/dist/inject-gateway.test.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/inject-gateway.test.js +41 -0
- package/packages/gsd-cloud/dist/inject-gateway.test.js.map +1 -0
- package/packages/gsd-cloud/dist/logger.d.ts +25 -0
- package/packages/gsd-cloud/dist/logger.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/logger.js +72 -0
- package/packages/gsd-cloud/dist/logger.js.map +1 -0
- package/packages/gsd-cloud/dist/types.d.ts +51 -0
- package/packages/gsd-cloud/dist/types.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/types.js +9 -0
- package/packages/gsd-cloud/dist/types.js.map +1 -0
- package/packages/gsd-cloud/package.json +3 -3
- package/packages/mcp-server/README.md +15 -2
- package/packages/mcp-server/dist/server.d.ts.map +1 -1
- package/packages/mcp-server/dist/server.js +5 -5
- package/packages/mcp-server/dist/server.js.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts +4 -3
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +64 -2
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +4 -4
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/dist/agent.d.ts +5 -1
- package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/agent.js +2 -0
- package/packages/pi-agent-core/dist/agent.js.map +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/dist/models.generated.d.ts +119 -0
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +107 -0
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/dist/providers/amazon-bedrock.js +1 -0
- package/packages/pi-ai/dist/providers/amazon-bedrock.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.js +25 -1
- package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-codex-responses.js +1 -1
- package/packages/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-responses.js +1 -1
- package/packages/pi-ai/dist/providers/openai-responses.js.map +1 -1
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-coding-agent/dist/core/capability-patches.js +1 -1
- package/packages/pi-coding-agent/dist/core/capability-patches.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-resolver.js +1 -1
- package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +11 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.js +8 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
- package/packages/pi-coding-agent/package.json +7 -7
- package/packages/pi-tui/package.json +2 -2
- package/packages/rpc-client/package.json +2 -2
- package/pkg/package.json +1 -1
- package/src/resources/GSD-WORKFLOW.md +18 -49
- package/src/resources/extensions/browser-tools/capture.ts +2 -86
- package/src/resources/extensions/browser-tools/screenshot-constraints.ts +94 -0
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +18 -1
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +108 -0
- package/src/resources/extensions/claude-code-cli/turn-assembler.ts +30 -2
- package/src/resources/extensions/gsd/artifact-verification.ts +3 -8
- package/src/resources/extensions/gsd/auto-artifact-paths.ts +16 -9
- package/src/resources/extensions/gsd/auto-dispatch.ts +86 -19
- package/src/resources/extensions/gsd/auto-post-unit.ts +4 -0
- package/src/resources/extensions/gsd/auto-prompts.ts +142 -16
- package/src/resources/extensions/gsd/auto-recovery.ts +10 -8
- package/src/resources/extensions/gsd/auto-worktree-cleanup.ts +4 -0
- package/src/resources/extensions/gsd/auto-worktree-teardown.ts +1 -1
- package/src/resources/extensions/gsd/auto.ts +5 -1
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +92 -4
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +39 -10
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +11 -3
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +87 -53
- package/src/resources/extensions/gsd/command-feedback.ts +19 -12
- package/src/resources/extensions/gsd/compat/compat-marker.ts +21 -4
- package/src/resources/extensions/gsd/constants.ts +14 -13
- package/src/resources/extensions/gsd/context-masker.ts +98 -2
- package/src/resources/extensions/gsd/db/command-queue.ts +7 -1
- package/src/resources/extensions/gsd/db/engine.ts +53 -17
- package/src/resources/extensions/gsd/db/writers/cascades.ts +5 -1
- package/src/resources/extensions/gsd/db/writers/status.ts +25 -8
- package/src/resources/extensions/gsd/db-base-schema.ts +30 -0
- package/src/resources/extensions/gsd/db-migration-steps.ts +32 -0
- package/src/resources/extensions/gsd/db-schema-metadata.ts +4 -1
- package/src/resources/extensions/gsd/docs/preferences-reference.md +26 -4
- package/src/resources/extensions/gsd/doctor-engine-checks.ts +3 -5
- package/src/resources/extensions/gsd/flat-phase-migration.ts +160 -19
- package/src/resources/extensions/gsd/git-service.ts +19 -6
- package/src/resources/extensions/gsd/gsd-db.ts +255 -52
- package/src/resources/extensions/gsd/guided-flow.ts +48 -12
- package/src/resources/extensions/gsd/markdown-renderer.ts +25 -21
- package/src/resources/extensions/gsd/md-importer.ts +114 -16
- package/src/resources/extensions/gsd/migrate/command.ts +21 -227
- package/src/resources/extensions/gsd/migrate/execution.ts +136 -0
- package/src/resources/extensions/gsd/migrate/plan.ts +101 -0
- package/src/resources/extensions/gsd/migrate/planning-writer.ts +12 -20
- package/src/resources/extensions/gsd/migrate/presentation.ts +83 -0
- package/src/resources/extensions/gsd/model-cost-table.ts +2 -0
- package/src/resources/extensions/gsd/model-router.ts +12 -0
- package/src/resources/extensions/gsd/parallel-eligibility.ts +5 -4
- package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +37 -40
- package/src/resources/extensions/gsd/paths.ts +62 -11
- package/src/resources/extensions/gsd/phase-anchor.ts +8 -2
- package/src/resources/extensions/gsd/planning-subagent-policy.ts +58 -0
- package/src/resources/extensions/gsd/planning-subagent-registry.ts +31 -0
- package/src/resources/extensions/gsd/post-execution-checks.ts +4 -4
- package/src/resources/extensions/gsd/preferences-types.ts +16 -0
- package/src/resources/extensions/gsd/preferences-validation.ts +62 -0
- package/src/resources/extensions/gsd/preferences.ts +25 -0
- package/src/resources/extensions/gsd/prompts/refine-slice.md +2 -2
- package/src/resources/extensions/gsd/provider-payload-policy.ts +18 -4
- package/src/resources/extensions/gsd/safety/destructive-guard.ts +1 -1
- package/src/resources/extensions/gsd/safety/evidence-collector.ts +28 -1
- package/src/resources/extensions/gsd/safety/evidence-cross-ref.ts +31 -5
- package/src/resources/extensions/gsd/skill-activation.ts +17 -3
- package/src/resources/extensions/gsd/state-reconciliation/drift/external-markdown-edit.ts +30 -13
- package/src/resources/extensions/gsd/state-reconciliation/drift/external-planning-edit.ts +16 -3
- package/src/resources/extensions/gsd/state-reconciliation/types.ts +2 -2
- package/src/resources/extensions/gsd/stop-notice.ts +18 -1
- package/src/resources/extensions/gsd/sync-lock.ts +14 -6
- package/src/resources/extensions/gsd/templates/PREFERENCES.md +5 -0
- package/src/resources/extensions/gsd/tests/auto-artifact-paths.test.ts +7 -7
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/before-provider-context-management.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/closeout-git-deferral.test.ts +96 -1
- package/src/resources/extensions/gsd/tests/command-feedback.test.ts +12 -0
- package/src/resources/extensions/gsd/tests/compat-marker.test.ts +104 -0
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +362 -1
- package/src/resources/extensions/gsd/tests/context-masker.test.ts +204 -8
- package/src/resources/extensions/gsd/tests/db-engine-migrate-guards.test.ts +186 -0
- package/src/resources/extensions/gsd/tests/db-tools-alias-suppression.test.ts +62 -0
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +29 -0
- package/src/resources/extensions/gsd/tests/destructive-confirmation.test.ts +33 -0
- package/src/resources/extensions/gsd/tests/destructive-guard.test.ts +14 -0
- package/src/resources/extensions/gsd/tests/discuss-routing-fixes.test.ts +123 -0
- package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +50 -0
- package/src/resources/extensions/gsd/tests/dispatch-rule-coverage.test.ts +49 -0
- package/src/resources/extensions/gsd/tests/evidence-cross-ref.test.ts +81 -0
- package/src/resources/extensions/gsd/tests/evidence-xref-gsd-exec.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/external-edit-scoped-import.test.ts +262 -0
- package/src/resources/extensions/gsd/tests/flat-phase-migration.test.ts +202 -0
- package/src/resources/extensions/gsd/tests/gate-storage.test.ts +29 -0
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +25 -0
- package/src/resources/extensions/gsd/tests/import-slice-milestone-completion-preserve.test.ts +116 -0
- package/src/resources/extensions/gsd/tests/integration/paths.test.ts +22 -4
- package/src/resources/extensions/gsd/tests/integration-branch-meta-location.test.ts +62 -0
- package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +5 -5
- package/src/resources/extensions/gsd/tests/migrate-plan.test.ts +68 -0
- package/src/resources/extensions/gsd/tests/migrate-presentation.test.ts +98 -0
- package/src/resources/extensions/gsd/tests/migrate-safety-audit.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/milestone-leases.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/model-cost-table.test.ts +9 -1
- package/src/resources/extensions/gsd/tests/model-router.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/parallel-eligibility-file-overlap.test.ts +146 -0
- package/src/resources/extensions/gsd/tests/parallel-monitor-overlay.test.ts +59 -0
- package/src/resources/extensions/gsd/tests/parallel-skill-prompt-integration.test.ts +7 -5
- package/src/resources/extensions/gsd/tests/phase-anchor.test.ts +32 -4
- package/src/resources/extensions/gsd/tests/plan-task.test.ts +26 -23
- package/src/resources/extensions/gsd/tests/planning-writer.test.ts +29 -0
- package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/preferences.test.ts +84 -0
- package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/prompt-budget-enforcement.test.ts +66 -0
- package/src/resources/extensions/gsd/tests/reactive-executor.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/reassess-handler.test.ts +50 -0
- package/src/resources/extensions/gsd/tests/replan-task-handler.test.ts +103 -0
- package/src/resources/extensions/gsd/tests/rework-brief.test.ts +197 -0
- package/src/resources/extensions/gsd/tests/service-tier.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/single-writer-v3-tool-surface.test.ts +33 -7
- package/src/resources/extensions/gsd/tests/skill-activation.test.ts +20 -16
- package/src/resources/extensions/gsd/tests/skip-slice-cascades-tasks.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/stop-notice.test.ts +17 -0
- package/src/resources/extensions/gsd/tests/sync-lock.test.ts +19 -0
- package/src/resources/extensions/gsd/tests/system-context-message-routing.test.ts +13 -7
- package/src/resources/extensions/gsd/tests/tool-naming.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +73 -0
- package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +93 -1
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +2 -0
- package/src/resources/extensions/gsd/tests/workflow-migration-gates.test.ts +139 -0
- package/src/resources/extensions/gsd/tests/workflow-projections.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/worktree-state-projection.test.ts +36 -0
- package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +34 -0
- package/src/resources/extensions/gsd/tests/write-gate-seam.test.ts +52 -0
- package/src/resources/extensions/gsd/tools/complete-task.ts +140 -5
- package/src/resources/extensions/gsd/tools/plan-task.ts +14 -16
- package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +18 -17
- package/src/resources/extensions/gsd/tools/reopen-milestone.ts +24 -5
- package/src/resources/extensions/gsd/tools/reopen-slice.ts +25 -5
- package/src/resources/extensions/gsd/tools/reopen-task.ts +23 -9
- package/src/resources/extensions/gsd/tools/replan-task.ts +160 -0
- package/src/resources/extensions/gsd/tools/rework-brief.ts +91 -0
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +92 -0
- package/src/resources/extensions/gsd/types.ts +11 -0
- package/src/resources/extensions/gsd/unit-context-composer.ts +34 -8
- package/src/resources/extensions/gsd/unit-registry.ts +4 -0
- package/src/resources/extensions/gsd/uok/plan-v2.ts +20 -3
- package/src/resources/extensions/gsd/workflow-projections.ts +2 -3
- package/src/resources/extensions/gsd/workspace.ts +2 -1
- package/src/resources/extensions/gsd/worktree-state-projection.ts +12 -0
- package/src/resources/extensions/mac-tools/index.ts +52 -9
- package/src/resources/extensions/mac-tools/tests/mac-screenshot-payload.test.cjs +70 -0
- package/dist/web/standalone/.next/static/chunks/app/_not-found/page-49f565245e1e4afe.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/page-bc4c723c6a19c6f0.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ec3eaffc9785ba48.js +0 -1
- package/dist/web/standalone/.next/static/css/18c2fdf261bfc1b7.css +0 -1
- /package/dist/web/standalone/.next/static/{UaXRrOYxBpG9QBINKhZkg → 6YWV7VAPg-jqjfPswrKZb}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{UaXRrOYxBpG9QBINKhZkg → 6YWV7VAPg-jqjfPswrKZb}/_ssgManifest.js +0 -0
|
@@ -37,22 +37,29 @@ function requireDb() {
|
|
|
37
37
|
export function applyStatusTransition(t) {
|
|
38
38
|
const db = requireDb();
|
|
39
39
|
const completedAt = t.completedAt ?? null;
|
|
40
|
+
const preserve = t.preserveCompletion ? 1 : 0;
|
|
40
41
|
switch (t.entity) {
|
|
41
42
|
case "task":
|
|
42
|
-
db.prepare(`UPDATE tasks SET status = :status,
|
|
43
|
+
db.prepare(`UPDATE tasks SET status = :status,
|
|
44
|
+
completed_at = CASE WHEN :preserve_completion = 1 AND tasks.completed_at IS NOT NULL
|
|
45
|
+
THEN tasks.completed_at ELSE :completed_at END
|
|
43
46
|
WHERE milestone_id = :milestone_id AND slice_id = :slice_id AND id = :id`).run({
|
|
44
47
|
":status": t.status,
|
|
45
48
|
":completed_at": completedAt,
|
|
49
|
+
":preserve_completion": preserve,
|
|
46
50
|
":milestone_id": t.milestoneId,
|
|
47
51
|
":slice_id": t.sliceId,
|
|
48
52
|
":id": t.taskId,
|
|
49
53
|
});
|
|
50
54
|
return;
|
|
51
55
|
case "slice":
|
|
52
|
-
db.prepare(`UPDATE slices SET status = :status,
|
|
56
|
+
db.prepare(`UPDATE slices SET status = :status,
|
|
57
|
+
completed_at = CASE WHEN :preserve_completion = 1 AND slices.completed_at IS NOT NULL
|
|
58
|
+
THEN slices.completed_at ELSE :completed_at END
|
|
53
59
|
WHERE milestone_id = :milestone_id AND id = :id`).run({
|
|
54
60
|
":status": t.status,
|
|
55
61
|
":completed_at": completedAt,
|
|
62
|
+
":preserve_completion": preserve,
|
|
56
63
|
":milestone_id": t.milestoneId,
|
|
57
64
|
":id": t.sliceId,
|
|
58
65
|
});
|
|
@@ -63,7 +70,10 @@ export function applyStatusTransition(t) {
|
|
|
63
70
|
if (currentStatus && isClosedStatus(currentStatus) && !isClosedStatus(t.status)) {
|
|
64
71
|
throw new Error(`Cannot update closed milestone ${t.milestoneId} from ${currentStatus} to ${t.status}; use gsd_milestone_reopen for an explicit reopen.`);
|
|
65
72
|
}
|
|
66
|
-
db.prepare(`UPDATE milestones SET status = :status,
|
|
73
|
+
db.prepare(`UPDATE milestones SET status = :status,
|
|
74
|
+
completed_at = CASE WHEN :preserve_completion = 1 AND milestones.completed_at IS NOT NULL
|
|
75
|
+
THEN milestones.completed_at ELSE :completed_at END
|
|
76
|
+
WHERE id = :id`).run({ ":status": t.status, ":completed_at": completedAt, ":preserve_completion": preserve, ":id": t.milestoneId });
|
|
67
77
|
return;
|
|
68
78
|
}
|
|
69
79
|
}
|
|
@@ -221,6 +221,32 @@ export function createBaseSchemaObjects(db, hooks) {
|
|
|
221
221
|
created_at TEXT NOT NULL DEFAULT '',
|
|
222
222
|
FOREIGN KEY (milestone_id) REFERENCES milestones(id)
|
|
223
223
|
)
|
|
224
|
+
`);
|
|
225
|
+
db.exec(`
|
|
226
|
+
CREATE TABLE IF NOT EXISTS rework_briefs (
|
|
227
|
+
id TEXT PRIMARY KEY,
|
|
228
|
+
milestone_id TEXT NOT NULL DEFAULT '',
|
|
229
|
+
slice_id TEXT NOT NULL DEFAULT '',
|
|
230
|
+
task_id TEXT NOT NULL DEFAULT '',
|
|
231
|
+
created_at TEXT NOT NULL DEFAULT '',
|
|
232
|
+
updated_at TEXT NOT NULL DEFAULT ''
|
|
233
|
+
)
|
|
234
|
+
`);
|
|
235
|
+
db.exec(`
|
|
236
|
+
CREATE TABLE IF NOT EXISTS rework_brief_findings (
|
|
237
|
+
brief_id TEXT NOT NULL,
|
|
238
|
+
finding_id TEXT NOT NULL,
|
|
239
|
+
severity TEXT NOT NULL DEFAULT 'blocking',
|
|
240
|
+
description TEXT NOT NULL DEFAULT '',
|
|
241
|
+
required_fix TEXT NOT NULL DEFAULT '',
|
|
242
|
+
verification_commands TEXT NOT NULL DEFAULT '[]',
|
|
243
|
+
status TEXT NOT NULL DEFAULT 'pending',
|
|
244
|
+
evidence TEXT NOT NULL DEFAULT '',
|
|
245
|
+
decision_ref TEXT NOT NULL DEFAULT '',
|
|
246
|
+
updated_at TEXT NOT NULL DEFAULT '',
|
|
247
|
+
PRIMARY KEY (brief_id, finding_id),
|
|
248
|
+
FOREIGN KEY (brief_id) REFERENCES rework_briefs(id)
|
|
249
|
+
)
|
|
224
250
|
`);
|
|
225
251
|
db.exec(`
|
|
226
252
|
CREATE TABLE IF NOT EXISTS assessments (
|
|
@@ -336,6 +362,8 @@ export function createBaseSchemaObjects(db, hooks) {
|
|
|
336
362
|
`);
|
|
337
363
|
db.exec("CREATE INDEX IF NOT EXISTS idx_memories_active ON memories(superseded_by)");
|
|
338
364
|
db.exec("CREATE INDEX IF NOT EXISTS idx_replan_history_milestone ON replan_history(milestone_id, created_at)");
|
|
365
|
+
db.exec("CREATE INDEX IF NOT EXISTS idx_rework_briefs_task ON rework_briefs(milestone_id, slice_id, task_id)");
|
|
366
|
+
db.exec("CREATE INDEX IF NOT EXISTS idx_rework_findings_status ON rework_brief_findings(brief_id, severity, status)");
|
|
339
367
|
db.exec("CREATE INDEX IF NOT EXISTS idx_tasks_active ON tasks(milestone_id, slice_id, status)");
|
|
340
368
|
db.exec("CREATE INDEX IF NOT EXISTS idx_slices_active ON slices(milestone_id, status)");
|
|
341
369
|
db.exec("CREATE INDEX IF NOT EXISTS idx_milestones_status ON milestones(status)");
|
|
@@ -418,3 +418,33 @@ export function applyMigrationV22QualityGateRepair(db, hooks) {
|
|
|
418
418
|
ensureColumn(db, "quality_gates", "scope", "ALTER TABLE quality_gates ADD COLUMN scope TEXT NOT NULL DEFAULT 'slice'");
|
|
419
419
|
ensureColumn(db, "assessments", "scope", "ALTER TABLE assessments ADD COLUMN scope TEXT NOT NULL DEFAULT ''");
|
|
420
420
|
}
|
|
421
|
+
export function applyMigrationV30ReworkBriefs(db) {
|
|
422
|
+
db.exec(`
|
|
423
|
+
CREATE TABLE IF NOT EXISTS rework_briefs (
|
|
424
|
+
id TEXT PRIMARY KEY,
|
|
425
|
+
milestone_id TEXT NOT NULL DEFAULT '',
|
|
426
|
+
slice_id TEXT NOT NULL DEFAULT '',
|
|
427
|
+
task_id TEXT NOT NULL DEFAULT '',
|
|
428
|
+
created_at TEXT NOT NULL DEFAULT '',
|
|
429
|
+
updated_at TEXT NOT NULL DEFAULT ''
|
|
430
|
+
)
|
|
431
|
+
`);
|
|
432
|
+
db.exec(`
|
|
433
|
+
CREATE TABLE IF NOT EXISTS rework_brief_findings (
|
|
434
|
+
brief_id TEXT NOT NULL,
|
|
435
|
+
finding_id TEXT NOT NULL,
|
|
436
|
+
severity TEXT NOT NULL DEFAULT 'blocking',
|
|
437
|
+
description TEXT NOT NULL DEFAULT '',
|
|
438
|
+
required_fix TEXT NOT NULL DEFAULT '',
|
|
439
|
+
verification_commands TEXT NOT NULL DEFAULT '[]',
|
|
440
|
+
status TEXT NOT NULL DEFAULT 'pending',
|
|
441
|
+
evidence TEXT NOT NULL DEFAULT '',
|
|
442
|
+
decision_ref TEXT NOT NULL DEFAULT '',
|
|
443
|
+
updated_at TEXT NOT NULL DEFAULT '',
|
|
444
|
+
PRIMARY KEY (brief_id, finding_id),
|
|
445
|
+
FOREIGN KEY (brief_id) REFERENCES rework_briefs(id)
|
|
446
|
+
)
|
|
447
|
+
`);
|
|
448
|
+
db.exec("CREATE INDEX IF NOT EXISTS idx_rework_briefs_task ON rework_briefs(milestone_id, slice_id, task_id)");
|
|
449
|
+
db.exec("CREATE INDEX IF NOT EXISTS idx_rework_findings_status ON rework_brief_findings(brief_id, severity, status)");
|
|
450
|
+
}
|
|
@@ -12,8 +12,11 @@ export function ensureColumn(db, table, column, ddl) {
|
|
|
12
12
|
db.exec(ddl);
|
|
13
13
|
}
|
|
14
14
|
export function getCurrentSchemaVersion(db) {
|
|
15
|
+
// MAX(version) on an empty table returns a row whose value is NULL —
|
|
16
|
+
// treat that (and any non-numeric value) as version 0, not NULL-as-number.
|
|
15
17
|
const row = db.prepare("SELECT MAX(version) as v FROM schema_version").get();
|
|
16
|
-
|
|
18
|
+
const v = row?.["v"];
|
|
19
|
+
return typeof v === "number" ? v : 0;
|
|
17
20
|
}
|
|
18
21
|
export function recordSchemaVersion(db, version) {
|
|
19
22
|
db.prepare("INSERT INTO schema_version (version, applied_at) VALUES (:version, :applied_at)").run({
|
|
@@ -128,7 +128,7 @@ Diagnostics record the file path, scope (global/project), severity (error/warnin
|
|
|
128
128
|
- Two equivalent ways to set it: inline as `models.<phase>.thinking`, or as a separate `thinking:` block keyed by phase. For the same phase, the inline value wins over the block; project preferences win over global; a phase that's unset inherits via the same sibling chain as `models` (e.g. `discuss → planning`).
|
|
129
129
|
- If no thinking is configured for a phase, the session level (set via `/model`) is used, exactly as before — this is fully backward-compatible.
|
|
130
130
|
- `execute-task` (code-writing) has a measured reasoning floor of `medium`: at lower levels models stop planning edits and thrash on file re-reads. The floor applies to the session/default path. An **explicit** `execution` thinking level bypasses the floor and is honored verbatim (with a one-time advisory) — set `execution: low` deliberately if you want it.
|
|
131
|
-
- Levels a model can't support are clamped to the nearest supported level at dispatch and never sent to the provider, so a model/level mismatch never fails a unit mid-run. `xhigh` is
|
|
131
|
+
- Levels a model can't support are clamped to the nearest supported level at dispatch and never sent to the provider, so a model/level mismatch never fails a unit mid-run. `xhigh` support is model-dependent; current examples include OpenAI Codex Max models and Claude Sonnet 5 on Amazon Bedrock.
|
|
132
132
|
|
|
133
133
|
- `skill_staleness_days`: number — skills unused for this many days get deprioritized during discovery. Set to `0` to disable staleness tracking. Default: `60`.
|
|
134
134
|
|
|
@@ -357,6 +357,28 @@ In `"parent"` mode, slice/task `targetRepositories` default to the declared chil
|
|
|
357
357
|
- `"replace"` requires `prompt`.
|
|
358
358
|
- `"skip"` is valid with no additional fields.
|
|
359
359
|
|
|
360
|
+
- `planning_subagents`: object — project-local widening for read-only planning subagent dispatch. Supported unit keys are `plan-milestone` and `plan-slice`; each has:
|
|
361
|
+
- `allowed`: string[] — additional planning-safe agents for that unit.
|
|
362
|
+
|
|
363
|
+
Agents must already be classified by GSD as read-only planning specialists: `mnemo`, `scout`, `planner`, `reviewer`, `security`, or `tester`. The write gate still blocks source writes outside `.gsd/**`, unrestricted bash, stale subagent calls without agent identities, agents outside the global read-only registry, and agents not listed for the active unit.
|
|
364
|
+
|
|
365
|
+
Example:
|
|
366
|
+
|
|
367
|
+
```yaml
|
|
368
|
+
planning_subagents:
|
|
369
|
+
plan-milestone:
|
|
370
|
+
allowed:
|
|
371
|
+
- scout
|
|
372
|
+
- planner
|
|
373
|
+
- security
|
|
374
|
+
plan-slice:
|
|
375
|
+
allowed:
|
|
376
|
+
- scout
|
|
377
|
+
- planner
|
|
378
|
+
- reviewer
|
|
379
|
+
- security
|
|
380
|
+
```
|
|
381
|
+
|
|
360
382
|
**Known unit types for `before`/`after`:** `research-milestone`, `plan-milestone`, `research-slice`, `plan-slice`, `execute-task`, `complete-slice`, `replan-slice`, `reassess-roadmap`, `run-uat`.
|
|
361
383
|
|
|
362
384
|
- `experimental`: opt-in experimental features. All features here are **off by default** — you must explicitly set each one to `true` to enable it. Features in this block may change or be removed without a deprecation cycle while in experimental status. Keys:
|
|
@@ -482,13 +504,13 @@ Inline form — thinking pinned alongside the model:
|
|
|
482
504
|
version: 1
|
|
483
505
|
models:
|
|
484
506
|
planning:
|
|
485
|
-
model:
|
|
507
|
+
model: bedrock/global.anthropic.claude-sonnet-5
|
|
486
508
|
thinking: xhigh
|
|
487
509
|
execution:
|
|
488
|
-
model:
|
|
510
|
+
model: bedrock/global.anthropic.claude-sonnet-5
|
|
489
511
|
thinking: low # explicit → bypasses the execute-task medium floor
|
|
490
512
|
validation:
|
|
491
|
-
model:
|
|
513
|
+
model: bedrock/global.anthropic.claude-sonnet-5
|
|
492
514
|
thinking: high
|
|
493
515
|
---
|
|
494
516
|
```
|
|
@@ -3,7 +3,7 @@ import { isAbsolute, join, relative, sep } from "node:path";
|
|
|
3
3
|
import { deleteArtifactByPath, getAllMilestones, getMilestoneSlices, getSliceTasks, isDbAvailable, isMemoriesFtsAvailable, repairTaskCompletionFromSummary, _getAdapter, } from "./gsd-db.js";
|
|
4
4
|
import { MEMORIES_FTS_REBUILT_KEY } from "./db-memory-fts-schema.js";
|
|
5
5
|
import { isAfter, latestExplicitReopenAt } from "./milestone-reopen-events.js";
|
|
6
|
-
import {
|
|
6
|
+
import { gsdProjectionRoot, gsdRoot, resolveGsdPathContract, resolveMilestoneFile, resolveSliceFile, resolveTaskFile, } from "./paths.js";
|
|
7
7
|
import { deriveState } from "./state.js";
|
|
8
8
|
import { isClosedStatus } from "./status-guards.js";
|
|
9
9
|
import { workflowEventLogPath } from "./workflow-event-ledger.js";
|
|
@@ -152,11 +152,8 @@ function resolveFlatPhaseArtifactDiskPath(basePath, row) {
|
|
|
152
152
|
if (!artifactType)
|
|
153
153
|
return null;
|
|
154
154
|
if (row.slice_id && row.task_id) {
|
|
155
|
-
const
|
|
156
|
-
|
|
157
|
-
return null;
|
|
158
|
-
const candidate = join(phaseDir, buildTaskFileName(row.task_id, artifactType));
|
|
159
|
-
return existsSync(candidate) ? candidate : null;
|
|
155
|
+
const candidate = resolveTaskFile(basePath, row.milestone_id, row.slice_id, row.task_id, artifactType);
|
|
156
|
+
return candidate && isFlatPhaseDiskPath(basePath, candidate) ? candidate : null;
|
|
160
157
|
}
|
|
161
158
|
const candidate = row.slice_id
|
|
162
159
|
? resolveSliceFile(basePath, row.milestone_id, row.slice_id, artifactType)
|
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
import { cpSync, existsSync, mkdirSync, readdirSync, renameSync, rmSync, statSync } from "node:fs";
|
|
5
5
|
import { join } from "node:path";
|
|
6
6
|
import { renderAllFromDb, renderRoadmapFromDb } from "./markdown-renderer.js";
|
|
7
|
-
import { deleteArtifactsByPathPrefix, getAllMilestones, getMilestoneSlices } from "./gsd-db.js";
|
|
7
|
+
import { deleteArtifactByPath, deleteArtifactsByPathPrefix, getAllMilestones, getArtifactsByPathPrefix, getMilestoneSlices, } from "./gsd-db.js";
|
|
8
8
|
import { migrateFromMarkdown } from "./md-importer.js";
|
|
9
9
|
import { countDbHierarchy } from "./migration-auto-check.js";
|
|
10
10
|
import { logWarning } from "./workflow-logger.js";
|
|
11
11
|
import { LAYOUT_SEGMENTS } from "./layout-policy.js";
|
|
12
|
-
import { canonicalPhaseDirName, dirIsContentBearingLegacyMilestone, milestonesDir, resolveMilestonePath, } from "./paths.js";
|
|
12
|
+
import { canonicalPhaseDirName, dirIsContentBearingLegacyMilestone, gsdProjectionRoot, milestonesDir, resolveMilestonePath, } from "./paths.js";
|
|
13
13
|
const LEGACY_MIGRATING_SEGMENT = "milestones.migrating";
|
|
14
14
|
const RETRYABLE_FS_ERROR_CODES = new Set(["EPERM", "EBUSY", "ENOTEMPTY"]);
|
|
15
15
|
const RM_RETRY_OPTIONS = { recursive: true, force: true, maxRetries: 5, retryDelay: 100 };
|
|
@@ -60,6 +60,46 @@ function expectedPhaseDirs(basePath) {
|
|
|
60
60
|
return getAllMilestones().map((milestone) => resolveMilestonePath(basePath, milestone.id) ??
|
|
61
61
|
join(milestonesDir(basePath), canonicalPhaseDirName(milestone.id, milestone.title)));
|
|
62
62
|
}
|
|
63
|
+
/**
|
|
64
|
+
* Return the most-recent existing `.gsd-backups/migrate-<ts>/` snapshot, or null.
|
|
65
|
+
*
|
|
66
|
+
* The flat-phase migration can re-fire on later dispatches when the legacy
|
|
67
|
+
* `.gsd/milestones/` layout reappears (e.g. a marker-key mismatch re-triggers a
|
|
68
|
+
* whole-tree re-import — issue #1292). The DB was already reconciled from that
|
|
69
|
+
* tree before the backup step runs, so re-snapshotting an identical legacy tree
|
|
70
|
+
* on every dispatch only leaks a fresh `migrate-<ts>/` directory each time. When
|
|
71
|
+
* a prior snapshot already exists we reuse it as the rollback fallback instead
|
|
72
|
+
* of creating a duplicate, bounding the accumulation to one recovery copy.
|
|
73
|
+
*/
|
|
74
|
+
function existingMigrateBackup(basePath) {
|
|
75
|
+
const backupRoot = join(basePath, ".gsd-backups");
|
|
76
|
+
if (!existsSync(backupRoot))
|
|
77
|
+
return null;
|
|
78
|
+
try {
|
|
79
|
+
let latest = null;
|
|
80
|
+
for (const entry of readdirSync(backupRoot)) {
|
|
81
|
+
if (!entry.startsWith("migrate-"))
|
|
82
|
+
continue;
|
|
83
|
+
const dirPath = join(backupRoot, entry);
|
|
84
|
+
try {
|
|
85
|
+
const st = statSync(dirPath);
|
|
86
|
+
if (!st.isDirectory())
|
|
87
|
+
continue;
|
|
88
|
+
if (!hasLegacyMilestoneSubdirs(dirPath))
|
|
89
|
+
continue;
|
|
90
|
+
if (!latest || st.mtimeMs > latest.mtimeMs)
|
|
91
|
+
latest = { path: dirPath, mtimeMs: st.mtimeMs };
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
// Non-fatal: skip unreadable entries.
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return latest?.path ?? null;
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
63
103
|
function hasLegacyMilestoneSubdirs(dirPath) {
|
|
64
104
|
if (!existsSync(dirPath))
|
|
65
105
|
return false;
|
|
@@ -70,7 +110,58 @@ function hasLegacyMilestoneSubdirs(dirPath) {
|
|
|
70
110
|
return false;
|
|
71
111
|
}
|
|
72
112
|
}
|
|
73
|
-
function
|
|
113
|
+
function backupFlatProjectionIfPresent(basePath, phasesPath, backupDir) {
|
|
114
|
+
if (!existsSync(phasesPath))
|
|
115
|
+
return;
|
|
116
|
+
const phaseBackupDir = join(backupDir, "__phases");
|
|
117
|
+
try {
|
|
118
|
+
mkdirSync(backupDir, { recursive: true });
|
|
119
|
+
if (existsSync(phaseBackupDir)) {
|
|
120
|
+
removePathWithRetries(phaseBackupDir);
|
|
121
|
+
}
|
|
122
|
+
fsOps.cpSync(phasesPath, phaseBackupDir, { recursive: true, force: true });
|
|
123
|
+
}
|
|
124
|
+
catch (err) {
|
|
125
|
+
logWarning("migration", `flat-phase projection backup failed: ${err.message}`);
|
|
126
|
+
throw err;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
function isInsideFlatProjectionBackup(backupDir, src) {
|
|
130
|
+
const phaseBackupDir = join(backupDir, "__phases");
|
|
131
|
+
return src === phaseBackupDir || src.startsWith(`${phaseBackupDir}/`) || src.startsWith(`${phaseBackupDir}\\`);
|
|
132
|
+
}
|
|
133
|
+
function restoreFlatProjectionFromBackup(basePath, backupDir) {
|
|
134
|
+
const phaseBackupDir = join(backupDir, "__phases");
|
|
135
|
+
if (!existsSync(phaseBackupDir))
|
|
136
|
+
return;
|
|
137
|
+
const phasesPath = join(basePath, ".gsd", LAYOUT_SEGMENTS.level1);
|
|
138
|
+
try {
|
|
139
|
+
if (existsSync(phasesPath)) {
|
|
140
|
+
removePathWithRetries(phasesPath);
|
|
141
|
+
}
|
|
142
|
+
mkdirSync(join(basePath, ".gsd"), { recursive: true });
|
|
143
|
+
cpSync(phaseBackupDir, phasesPath, { recursive: true });
|
|
144
|
+
}
|
|
145
|
+
catch (restoreErr) {
|
|
146
|
+
logWarning("migration", `rollback: could not restore ${LAYOUT_SEGMENTS.level1}/ from backup: ${restoreErr.message}`);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
function pruneStaleFlatPhaseArtifactRows(basePath) {
|
|
150
|
+
const projectionRoot = gsdProjectionRoot(basePath);
|
|
151
|
+
let pruned = 0;
|
|
152
|
+
for (const row of getArtifactsByPathPrefix(`${LAYOUT_SEGMENTS.level1}/`)) {
|
|
153
|
+
if (existsSync(join(projectionRoot, row.path)))
|
|
154
|
+
continue;
|
|
155
|
+
const staleTaskPlan = row.artifact_type.toUpperCase() === "PLAN" && Boolean(row.task_id);
|
|
156
|
+
const skippedEmptyArtifact = row.full_content.trim() === "";
|
|
157
|
+
if (!staleTaskPlan && !skippedEmptyArtifact)
|
|
158
|
+
continue;
|
|
159
|
+
deleteArtifactByPath(row.path);
|
|
160
|
+
pruned++;
|
|
161
|
+
}
|
|
162
|
+
return pruned;
|
|
163
|
+
}
|
|
164
|
+
function rollbackPartialMigration(basePath, backupDir, migratingPath, backupCreatedThisRun = true) {
|
|
74
165
|
// Remove the partially-written phases/ dir.
|
|
75
166
|
try {
|
|
76
167
|
removePathWithRetries(join(basePath, ".gsd", LAYOUT_SEGMENTS.level1));
|
|
@@ -83,7 +174,7 @@ function rollbackPartialMigration(basePath, backupDir, migratingPath) {
|
|
|
83
174
|
// preserved migrating tree (the sole surviving data source) and must never be
|
|
84
175
|
// removed here. Deleting the backup after a successful rollback keeps the gate
|
|
85
176
|
// from leaking one .gsd-backups/migrate-<ts>/ per session_start.
|
|
86
|
-
const isDisposableBackup = Boolean(backupDir) && backupDir !== migratingPath;
|
|
177
|
+
const isDisposableBackup = Boolean(backupDir) && backupDir !== migratingPath && backupCreatedThisRun;
|
|
87
178
|
const cleanupBackup = () => {
|
|
88
179
|
if (!isDisposableBackup || !existsSync(backupDir))
|
|
89
180
|
return;
|
|
@@ -99,11 +190,16 @@ function rollbackPartialMigration(basePath, backupDir, migratingPath) {
|
|
|
99
190
|
try {
|
|
100
191
|
if (migratingPath && existsSync(migratingPath) && !existsSync(milestonesPath)) {
|
|
101
192
|
movePathWithCopyDeleteFallback(migratingPath, milestonesPath);
|
|
193
|
+
restoreFlatProjectionFromBackup(basePath, backupDir);
|
|
102
194
|
cleanupBackup();
|
|
103
195
|
return;
|
|
104
196
|
}
|
|
105
197
|
if (existsSync(backupDir)) {
|
|
106
|
-
cpSync(backupDir, milestonesPath, {
|
|
198
|
+
cpSync(backupDir, milestonesPath, {
|
|
199
|
+
recursive: true,
|
|
200
|
+
filter: (src) => !isInsideFlatProjectionBackup(backupDir, src),
|
|
201
|
+
});
|
|
202
|
+
restoreFlatProjectionFromBackup(basePath, backupDir);
|
|
107
203
|
cleanupBackup();
|
|
108
204
|
}
|
|
109
205
|
if (migratingPath && existsSync(migratingPath)) {
|
|
@@ -204,17 +300,33 @@ export async function migrateToFlatPhase(basePath) {
|
|
|
204
300
|
return;
|
|
205
301
|
}
|
|
206
302
|
let backupDir = migratingPath;
|
|
303
|
+
let backupCreatedThisRun = false;
|
|
207
304
|
if (!resumingInterrupted) {
|
|
208
|
-
// 2. Backup (only reached when the DB has rows and migration will proceed)
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
305
|
+
// 2. Backup (only reached when the DB has rows and migration will proceed).
|
|
306
|
+
// migrateFromMarkdown above already reconciled the legacy tree into the DB,
|
|
307
|
+
// so its content is safely persisted. If a prior successful migration
|
|
308
|
+
// already snapshotted the legacy tree, a re-fire of this gate (issue #1292:
|
|
309
|
+
// marker-key mismatch re-importing the whole tree at dispatch boundaries)
|
|
310
|
+
// must not leak a fresh .gsd-backups/migrate-<ts>/ every dispatch. Treat it
|
|
311
|
+
// as a marker-refresh re-projection: reuse the existing snapshot as the
|
|
312
|
+
// rollback fallback instead of creating a duplicate.
|
|
313
|
+
const priorBackup = existingMigrateBackup(basePath);
|
|
314
|
+
if (priorBackup) {
|
|
315
|
+
backupDir = priorBackup;
|
|
316
|
+
logWarning("migration", `flat-phase migration re-fired; reusing existing backup ${priorBackup} instead of re-snapshotting (issue #1292)`);
|
|
214
317
|
}
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
318
|
+
else {
|
|
319
|
+
const ts = Date.now();
|
|
320
|
+
backupDir = join(basePath, ".gsd-backups", `migrate-${ts}`);
|
|
321
|
+
try {
|
|
322
|
+
mkdirSync(join(basePath, ".gsd-backups"), { recursive: true });
|
|
323
|
+
cpSync(milestonesPath, backupDir, { recursive: true });
|
|
324
|
+
backupCreatedThisRun = true;
|
|
325
|
+
}
|
|
326
|
+
catch (err) {
|
|
327
|
+
logWarning("migration", `flat-phase migration backup failed: ${err.message}`);
|
|
328
|
+
throw err;
|
|
329
|
+
}
|
|
218
330
|
}
|
|
219
331
|
if (existsSync(migratingPath)) {
|
|
220
332
|
removePathWithRetries(migratingPath);
|
|
@@ -230,14 +342,34 @@ export async function migrateToFlatPhase(basePath) {
|
|
|
230
342
|
throw err;
|
|
231
343
|
}
|
|
232
344
|
}
|
|
345
|
+
else {
|
|
346
|
+
const priorBackup = existingMigrateBackup(basePath);
|
|
347
|
+
if (priorBackup) {
|
|
348
|
+
backupDir = priorBackup;
|
|
349
|
+
}
|
|
350
|
+
else {
|
|
351
|
+
const ts = Date.now();
|
|
352
|
+
backupDir = join(basePath, ".gsd-backups", `migrate-${ts}`);
|
|
353
|
+
try {
|
|
354
|
+
mkdirSync(join(basePath, ".gsd-backups"), { recursive: true });
|
|
355
|
+
cpSync(migratingPath, backupDir, { recursive: true });
|
|
356
|
+
backupCreatedThisRun = true;
|
|
357
|
+
}
|
|
358
|
+
catch (err) {
|
|
359
|
+
logWarning("migration", `flat-phase migration backup failed during resume: ${err.message}`);
|
|
360
|
+
throw err;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
233
364
|
// Clear any stale or partially-rendered flat projection before this run
|
|
234
365
|
// writes. Verification below checks the current DB render, not leftovers.
|
|
235
366
|
try {
|
|
367
|
+
backupFlatProjectionIfPresent(basePath, phasesPath, backupDir);
|
|
236
368
|
removePathWithRetries(phasesPath);
|
|
237
369
|
}
|
|
238
370
|
catch (err) {
|
|
239
371
|
logWarning("migration", `failed to clear stale phases/ before render: ${err.message}`);
|
|
240
|
-
rollbackPartialMigration(basePath, backupDir, migratingPath);
|
|
372
|
+
rollbackPartialMigration(basePath, backupDir, migratingPath, backupCreatedThisRun);
|
|
241
373
|
throw err;
|
|
242
374
|
}
|
|
243
375
|
// 4. Render flat-phase from DB
|
|
@@ -260,35 +392,38 @@ export async function migrateToFlatPhase(basePath) {
|
|
|
260
392
|
}
|
|
261
393
|
catch (err) {
|
|
262
394
|
logWarning("migration", `flat-phase render failed: ${err.message}`);
|
|
263
|
-
rollbackPartialMigration(basePath, backupDir, migratingPath);
|
|
395
|
+
rollbackPartialMigration(basePath, backupDir, migratingPath, backupCreatedThisRun);
|
|
264
396
|
throw err;
|
|
265
397
|
}
|
|
266
398
|
// 5. Verify render succeeded and flat-phase projection was written
|
|
267
399
|
if (renderResult.errors.length > 0) {
|
|
268
400
|
logWarning("migration", `flat-phase render had ${renderResult.errors.length} error(s): ${renderResult.errors.join("; ")}`);
|
|
269
|
-
rollbackPartialMigration(basePath, backupDir, migratingPath);
|
|
401
|
+
rollbackPartialMigration(basePath, backupDir, migratingPath, backupCreatedThisRun);
|
|
270
402
|
throw new Error(`flat-phase migration render failed: ${renderResult.errors.slice(0, 3).join("; ")}`);
|
|
271
403
|
}
|
|
272
404
|
const db = countDbHierarchy();
|
|
273
405
|
const missingPhaseDirs = expectedPhaseDirs(basePath).filter((phaseDir) => !existsSync(phaseDir));
|
|
274
406
|
if (db.milestones > 0 && missingPhaseDirs.length > 0) {
|
|
275
407
|
logWarning("migration", `flat-phase migration missing ${missingPhaseDirs.length} expected phase dir(s): ${missingPhaseDirs.join(", ")}`);
|
|
276
|
-
rollbackPartialMigration(basePath, backupDir, migratingPath);
|
|
408
|
+
rollbackPartialMigration(basePath, backupDir, migratingPath, backupCreatedThisRun);
|
|
277
409
|
throw new Error("flat-phase migration verification failed: missing rendered phase directories");
|
|
278
410
|
}
|
|
279
411
|
if (db.slices > 0 && renderResult.rendered === 0) {
|
|
280
412
|
logWarning("migration", "flat-phase migration verification failed: render produced no artifacts for populated DB");
|
|
281
|
-
rollbackPartialMigration(basePath, backupDir, migratingPath);
|
|
413
|
+
rollbackPartialMigration(basePath, backupDir, migratingPath, backupCreatedThisRun);
|
|
282
414
|
throw new Error("flat-phase migration verification failed: no artifacts rendered");
|
|
283
415
|
}
|
|
284
416
|
// 6. Verified — prune legacy artifact rows now that renderAllFromDb has
|
|
285
|
-
// re-inserted flat-phase rows for artifacts that still have files.
|
|
417
|
+
// re-inserted flat-phase rows for artifacts that still have files. Also
|
|
418
|
+
// prune flat-phase rows whose files the renderer intentionally no longer
|
|
419
|
+
// materializes, such as task PLAN files and empty-content artifacts.
|
|
286
420
|
try {
|
|
287
421
|
deleteArtifactsByPathPrefix("milestones/");
|
|
422
|
+
pruneStaleFlatPhaseArtifactRows(basePath);
|
|
288
423
|
}
|
|
289
424
|
catch (err) {
|
|
290
425
|
logWarning("migration", `flat-phase migration could not prune legacy artifact rows: ${err.message}`);
|
|
291
|
-
rollbackPartialMigration(basePath, backupDir, migratingPath);
|
|
426
|
+
rollbackPartialMigration(basePath, backupDir, migratingPath, backupCreatedThisRun);
|
|
292
427
|
throw err;
|
|
293
428
|
}
|
|
294
429
|
// 7. Remove the renamed legacy tree (backup already on disk).
|
|
@@ -229,10 +229,15 @@ export const RUNTIME_EXCLUSION_PATHS = [
|
|
|
229
229
|
const runtimeFilesCleanedUpRepos = new Set();
|
|
230
230
|
// ─── Integration Branch Metadata ───────────────────────────────────────────
|
|
231
231
|
/**
|
|
232
|
-
* Path to the milestone metadata file
|
|
233
|
-
* Format: .gsd
|
|
232
|
+
* Path to the milestone integration-branch metadata file.
|
|
233
|
+
* Format: .gsd/<MID>-META.json (deliberately OUTSIDE milestones/<MID>/ so it
|
|
234
|
+
* cannot poison isLegacyMilestonesLayout — see ADR-045).
|
|
234
235
|
*/
|
|
235
|
-
function milestoneMetaPath(basePath, milestoneId) {
|
|
236
|
+
export function milestoneMetaPath(basePath, milestoneId) {
|
|
237
|
+
return join(gsdRoot(basePath), `${milestoneId}-META.json`);
|
|
238
|
+
}
|
|
239
|
+
/** Legacy location (pre-ADR-045). Read-only fallback for existing on-disk trees. */
|
|
240
|
+
function legacyMilestoneMetaPath(basePath, milestoneId) {
|
|
236
241
|
return join(gsdRoot(basePath), "milestones", milestoneId, `${milestoneId}-META.json`);
|
|
237
242
|
}
|
|
238
243
|
/**
|
|
@@ -241,9 +246,13 @@ function milestoneMetaPath(basePath, milestoneId) {
|
|
|
241
246
|
*/
|
|
242
247
|
export function readIntegrationBranch(basePath, milestoneId) {
|
|
243
248
|
try {
|
|
244
|
-
|
|
245
|
-
if (!existsSync(metaFile))
|
|
246
|
-
|
|
249
|
+
let metaFile = milestoneMetaPath(basePath, milestoneId);
|
|
250
|
+
if (!existsSync(metaFile)) {
|
|
251
|
+
const legacy = legacyMilestoneMetaPath(basePath, milestoneId);
|
|
252
|
+
if (!existsSync(legacy))
|
|
253
|
+
return null;
|
|
254
|
+
metaFile = legacy;
|
|
255
|
+
}
|
|
247
256
|
const data = JSON.parse(readFileSync(metaFile, "utf-8"));
|
|
248
257
|
const branch = data?.integrationBranch;
|
|
249
258
|
if (typeof branch === "string" && branch.trim() !== "" && VALID_BRANCH_NAME.test(branch)) {
|
|
@@ -295,7 +304,10 @@ export function writeIntegrationBranch(basePath, milestoneId, branch) {
|
|
|
295
304
|
if (existingBranch === branch)
|
|
296
305
|
return;
|
|
297
306
|
const metaFile = milestoneMetaPath(basePath, milestoneId);
|
|
298
|
-
|
|
307
|
+
// Ensure the flat .gsd/ root exists (never milestones/<MID>/ — that would
|
|
308
|
+
// poison layout detection, ADR-045). In production .gsd/ already exists; this
|
|
309
|
+
// guards fresh trees so the write below can't ENOENT.
|
|
310
|
+
mkdirSync(gsdRoot(basePath), { recursive: true });
|
|
299
311
|
// Merge with existing metadata if present
|
|
300
312
|
let existing = {};
|
|
301
313
|
try {
|