@opengsd/gsd-pi 1.8.0 → 1.8.1-dev.897b3c90
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 +8 -3
- 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 +16 -47
- 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/auto-artifact-paths.js +2 -2
- 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 +35 -1
- package/dist/resources/extensions/gsd/auto.js +5 -1
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +78 -4
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +84 -26
- 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/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 +4 -4
- package/dist/resources/extensions/gsd/doctor-history.js +65 -0
- package/dist/resources/extensions/gsd/doctor-state-checks.js +509 -0
- package/dist/resources/extensions/gsd/doctor-workspace-checks.js +91 -0
- package/dist/resources/extensions/gsd/doctor.js +14 -653
- package/dist/resources/extensions/gsd/flat-phase-migration.js +156 -21
- package/dist/resources/extensions/gsd/gsd-db.js +187 -45
- package/dist/resources/extensions/gsd/guided-flow.js +29 -10
- package/dist/resources/extensions/gsd/markdown-renderer.js +16 -2
- package/dist/resources/extensions/gsd/md-importer.js +109 -16
- 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 +20 -19
- package/dist/resources/extensions/gsd/migrate/presentation.js +64 -0
- package/dist/resources/extensions/gsd/migration-auto-check.js +4 -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 +4 -1
- package/dist/resources/extensions/gsd/phase-anchor.js +7 -2
- package/dist/resources/extensions/gsd/post-execution-checks.js +4 -4
- package/dist/resources/extensions/gsd/prompts/refine-slice.md +2 -2
- 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/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/state-reconciliation/drift/project-md.js +54 -14
- package/dist/resources/extensions/gsd/state-reconciliation/drift/sketch-flag.js +48 -5
- 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/tools/complete-task.js +82 -1
- 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/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-registry.js +4 -0
- package/dist/resources/extensions/gsd/uok/plan-v2.js +19 -3
- 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 +5 -5
- 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 +5 -5
- 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/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 +8 -0
- 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/package.json +1 -1
- package/packages/pi-ai/dist/models.generated.d.ts +60 -0
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +54 -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 +19 -0
- package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
- package/packages/pi-ai/package.json +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 +16 -47
- 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/auto-artifact-paths.ts +2 -2
- 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 +38 -1
- package/src/resources/extensions/gsd/auto.ts +5 -1
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +91 -4
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +80 -24
- 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/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 +4 -4
- package/src/resources/extensions/gsd/doctor-history.ts +81 -0
- package/src/resources/extensions/gsd/doctor-state-checks.ts +527 -0
- package/src/resources/extensions/gsd/doctor-workspace-checks.ts +97 -0
- package/src/resources/extensions/gsd/doctor.ts +14 -673
- package/src/resources/extensions/gsd/flat-phase-migration.ts +160 -19
- package/src/resources/extensions/gsd/gsd-db.ts +255 -52
- package/src/resources/extensions/gsd/guided-flow.ts +39 -10
- package/src/resources/extensions/gsd/markdown-renderer.ts +23 -7
- package/src/resources/extensions/gsd/md-importer.ts +116 -13
- 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 +21 -23
- package/src/resources/extensions/gsd/migrate/presentation.ts +83 -0
- package/src/resources/extensions/gsd/migration-auto-check.ts +3 -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 +4 -1
- package/src/resources/extensions/gsd/phase-anchor.ts +8 -2
- package/src/resources/extensions/gsd/post-execution-checks.ts +4 -4
- package/src/resources/extensions/gsd/prompts/refine-slice.md +2 -2
- 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/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/drift/project-md.ts +67 -20
- package/src/resources/extensions/gsd/state-reconciliation/drift/sketch-flag.ts +47 -5
- 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/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 +286 -0
- package/src/resources/extensions/gsd/tests/db-authority-regression.test.ts +76 -1
- package/src/resources/extensions/gsd/tests/db-engine-migrate-guards.test.ts +186 -0
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +29 -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/doctor-history-public-api.test.ts +25 -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/migrate-hierarchy.test.ts +53 -0
- 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/migration-auto-check.test.ts +53 -0
- package/src/resources/extensions/gsd/tests/milestone-leases.test.ts +55 -0
- 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/parsers-legacy-importers.test.ts +4 -0
- 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 +47 -1
- package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/progressive-planning.test.ts +18 -3
- 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/skip-slice-cascades-tasks.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +177 -25
- 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/unit-context-composer.test.ts +34 -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/worktree-state-projection.test.ts +36 -0
- package/src/resources/extensions/gsd/tests/write-gate-seam.test.ts +52 -0
- package/src/resources/extensions/gsd/tools/complete-task.ts +120 -0
- 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/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-registry.ts +4 -0
- package/src/resources/extensions/gsd/uok/plan-v2.ts +20 -3
- 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/{seHIUVbR1mm7LfG83nWJO → TezjdjSHBVRRr54XjAvte}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{seHIUVbR1mm7LfG83nWJO → TezjdjSHBVRRr54XjAvte}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
// gsd-pi - /gsd migrate execution service.
|
|
2
|
+
// File Purpose: Write migrated .gsd files, import them into the DB, verify projection/readiness, and rollback on failure.
|
|
3
|
+
|
|
4
|
+
import { ensureDbOpen } from "../bootstrap/dynamic-tools.js";
|
|
5
|
+
import { closeWorkflowDatabase } from "../db-workspace.js";
|
|
6
|
+
import { clearArtifacts, clearDecisions, clearEngineHierarchy, clearRequirements, transaction } from "../gsd-db.js";
|
|
7
|
+
import { migrateFromMarkdown } from "../md-importer.js";
|
|
8
|
+
import { deriveState, invalidateStateCache } from "../state.js";
|
|
9
|
+
import {
|
|
10
|
+
archiveLegacyPlanningDirectory,
|
|
11
|
+
verifyMigrationProjection,
|
|
12
|
+
writeMigrationAudit,
|
|
13
|
+
type LegacyArchiveResult,
|
|
14
|
+
type MigrationAuditResult,
|
|
15
|
+
type MigrationProjectionVerification,
|
|
16
|
+
} from "./audit.js";
|
|
17
|
+
import {
|
|
18
|
+
prepareMigrationTarget,
|
|
19
|
+
restoreMigrationTarget,
|
|
20
|
+
type MigrationBackup,
|
|
21
|
+
} from "./safety.js";
|
|
22
|
+
import { writeGSDDirectory, type MigrationPreview, type WrittenFiles } from "./writer.js";
|
|
23
|
+
import type { GSDProject } from "./types.js";
|
|
24
|
+
|
|
25
|
+
export type MigrationImportCounts = ReturnType<typeof migrateFromMarkdown>;
|
|
26
|
+
|
|
27
|
+
export interface MigrationExecutionResult {
|
|
28
|
+
backup: MigrationBackup;
|
|
29
|
+
written: WrittenFiles;
|
|
30
|
+
imported: MigrationImportCounts;
|
|
31
|
+
legacyArchive: LegacyArchiveResult;
|
|
32
|
+
verification: MigrationProjectionVerification;
|
|
33
|
+
audit: MigrationAuditResult;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function assertMigrationImportMatchesPreview(imported: MigrationImportCounts, preview: MigrationPreview): void {
|
|
37
|
+
const mismatches: string[] = [];
|
|
38
|
+
if (imported.decisions !== preview.decisions.total) {
|
|
39
|
+
mismatches.push(`decisions ${imported.decisions}/${preview.decisions.total}`);
|
|
40
|
+
}
|
|
41
|
+
if (imported.hierarchy.milestones !== preview.milestoneCount) {
|
|
42
|
+
mismatches.push(`milestones ${imported.hierarchy.milestones}/${preview.milestoneCount}`);
|
|
43
|
+
}
|
|
44
|
+
if (imported.hierarchy.slices !== preview.totalSlices) {
|
|
45
|
+
mismatches.push(`slices ${imported.hierarchy.slices}/${preview.totalSlices}`);
|
|
46
|
+
}
|
|
47
|
+
if (imported.hierarchy.tasks !== preview.totalTasks) {
|
|
48
|
+
mismatches.push(`tasks ${imported.hierarchy.tasks}/${preview.totalTasks}`);
|
|
49
|
+
}
|
|
50
|
+
if (imported.requirements !== preview.requirements.total) {
|
|
51
|
+
mismatches.push(`requirements ${imported.requirements}/${preview.requirements.total}`);
|
|
52
|
+
}
|
|
53
|
+
if (mismatches.length > 0) {
|
|
54
|
+
throw new Error(`migration DB import verification failed: ${mismatches.join(", ")}`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export async function importWrittenMigrationToDb(
|
|
59
|
+
basePath: string,
|
|
60
|
+
preview?: MigrationPreview,
|
|
61
|
+
): Promise<MigrationImportCounts> {
|
|
62
|
+
const opened = await ensureDbOpen(basePath);
|
|
63
|
+
if (!opened) {
|
|
64
|
+
throw new Error(`failed to open or create the GSD database at ${basePath}`);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const counts = transaction(() => {
|
|
68
|
+
clearEngineHierarchy();
|
|
69
|
+
clearArtifacts();
|
|
70
|
+
clearDecisions();
|
|
71
|
+
clearRequirements();
|
|
72
|
+
const imported = migrateFromMarkdown(basePath);
|
|
73
|
+
if (preview) assertMigrationImportMatchesPreview(imported, preview);
|
|
74
|
+
return imported;
|
|
75
|
+
});
|
|
76
|
+
invalidateStateCache();
|
|
77
|
+
return counts;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export async function assertMigrationDbReadiness(
|
|
81
|
+
targetRoot: string,
|
|
82
|
+
preview: MigrationPreview,
|
|
83
|
+
): Promise<{ phase: string; registry: number }> {
|
|
84
|
+
invalidateStateCache();
|
|
85
|
+
const state = await deriveState(targetRoot);
|
|
86
|
+
const dbUnavailable = state.blockers.some((blocker) => blocker.includes("DB unavailable"));
|
|
87
|
+
if (dbUnavailable) {
|
|
88
|
+
throw new Error(`migration DB readiness failed: ${state.blockers.join("; ")}`);
|
|
89
|
+
}
|
|
90
|
+
if (state.registry.length !== preview.milestoneCount) {
|
|
91
|
+
throw new Error(`migration DB readiness failed: registry ${state.registry.length}/${preview.milestoneCount}`);
|
|
92
|
+
}
|
|
93
|
+
return {
|
|
94
|
+
phase: state.phase,
|
|
95
|
+
registry: state.registry.length,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export async function executeMigrationWrite(
|
|
100
|
+
sourcePath: string,
|
|
101
|
+
targetRoot: string,
|
|
102
|
+
project: GSDProject,
|
|
103
|
+
preview: MigrationPreview,
|
|
104
|
+
startedAt: string = new Date().toISOString(),
|
|
105
|
+
): Promise<MigrationExecutionResult> {
|
|
106
|
+
const backup = prepareMigrationTarget(targetRoot);
|
|
107
|
+
|
|
108
|
+
try {
|
|
109
|
+
const written = await writeGSDDirectory(project, targetRoot);
|
|
110
|
+
const legacyArchive = await archiveLegacyPlanningDirectory(sourcePath, targetRoot);
|
|
111
|
+
const imported = await importWrittenMigrationToDb(targetRoot, preview);
|
|
112
|
+
const verification = await verifyMigrationProjection(targetRoot, preview);
|
|
113
|
+
verification.dbReadiness = await assertMigrationDbReadiness(targetRoot, preview);
|
|
114
|
+
const audit = await writeMigrationAudit({
|
|
115
|
+
sourcePath,
|
|
116
|
+
targetRoot,
|
|
117
|
+
backupPath: backup.backupPath,
|
|
118
|
+
preview,
|
|
119
|
+
written,
|
|
120
|
+
imported,
|
|
121
|
+
legacyArchive,
|
|
122
|
+
verification,
|
|
123
|
+
startedAt,
|
|
124
|
+
completedAt: new Date().toISOString(),
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
return { backup, written, imported, legacyArchive, verification, audit };
|
|
128
|
+
} catch (error) {
|
|
129
|
+
// The import transaction may have committed and the process may hold an
|
|
130
|
+
// open handle to the target gsd.db; close before the restore replaces the
|
|
131
|
+
// file on disk, and leave closed so the next open rebinds to the restored file.
|
|
132
|
+
try { closeWorkflowDatabase(); } catch { /* best-effort: restore must proceed */ }
|
|
133
|
+
restoreMigrationTarget(backup);
|
|
134
|
+
throw error;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// gsd-pi - /gsd migrate planning service.
|
|
2
|
+
// File Purpose: Resolve, validate, parse, transform, preview, and guard a migration before UI confirmation.
|
|
3
|
+
|
|
4
|
+
import { existsSync } from "node:fs";
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
assertMigrationHasSlices,
|
|
8
|
+
assertMigrationTargetAvailable,
|
|
9
|
+
resolveMigrationPaths,
|
|
10
|
+
type MigrationPaths,
|
|
11
|
+
} from "./safety.js";
|
|
12
|
+
import { parsePlanningDirectory } from "./parser.js";
|
|
13
|
+
import { generatePreview } from "./preview.js";
|
|
14
|
+
import { transformToGSD } from "./transformer.js";
|
|
15
|
+
import { validatePlanningDirectory } from "./validator.js";
|
|
16
|
+
import type { GSDProject, ValidationIssue, ValidationResult } from "./types.js";
|
|
17
|
+
import type { MigrationPreview } from "./writer.js";
|
|
18
|
+
|
|
19
|
+
export interface SplitValidationIssues {
|
|
20
|
+
warnings: ValidationIssue[];
|
|
21
|
+
fatals: ValidationIssue[];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
interface MigrationPlanBase extends MigrationPaths {
|
|
25
|
+
warnings: ValidationIssue[];
|
|
26
|
+
fatals: ValidationIssue[];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface MissingMigrationSourceResult extends MigrationPaths {
|
|
30
|
+
status: "missing-source";
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface InvalidMigrationPlanResult extends MigrationPlanBase {
|
|
34
|
+
status: "invalid";
|
|
35
|
+
validation: ValidationResult;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface BlockedMigrationPlanResult extends MigrationPlanBase {
|
|
39
|
+
status: "blocked";
|
|
40
|
+
validation: ValidationResult;
|
|
41
|
+
message: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface ReadyMigrationPlanResult extends MigrationPlanBase {
|
|
45
|
+
status: "ready";
|
|
46
|
+
validation: ValidationResult;
|
|
47
|
+
project: GSDProject;
|
|
48
|
+
preview: MigrationPreview;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export type MigrationPlanResult =
|
|
52
|
+
| MissingMigrationSourceResult
|
|
53
|
+
| InvalidMigrationPlanResult
|
|
54
|
+
| BlockedMigrationPlanResult
|
|
55
|
+
| ReadyMigrationPlanResult;
|
|
56
|
+
|
|
57
|
+
export function splitValidationIssues(validation: ValidationResult): SplitValidationIssues {
|
|
58
|
+
return {
|
|
59
|
+
warnings: validation.issues.filter((issue) => issue.severity === "warning"),
|
|
60
|
+
fatals: validation.issues.filter((issue) => issue.severity === "fatal"),
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export async function createMigrationPlan(args: string, cwd: string = process.cwd()): Promise<MigrationPlanResult> {
|
|
65
|
+
const paths = resolveMigrationPaths(args, cwd);
|
|
66
|
+
if (!existsSync(paths.sourcePath)) {
|
|
67
|
+
return { status: "missing-source", ...paths };
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const validation = await validatePlanningDirectory(paths.sourcePath);
|
|
71
|
+
const issues = splitValidationIssues(validation);
|
|
72
|
+
if (!validation.valid) {
|
|
73
|
+
return { status: "invalid", ...paths, validation, ...issues };
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const parsed = await parsePlanningDirectory(paths.sourcePath);
|
|
77
|
+
const project = transformToGSD(parsed);
|
|
78
|
+
const preview = generatePreview(project);
|
|
79
|
+
|
|
80
|
+
try {
|
|
81
|
+
assertMigrationHasSlices(preview);
|
|
82
|
+
await assertMigrationTargetAvailable(paths.targetRoot);
|
|
83
|
+
} catch (error) {
|
|
84
|
+
return {
|
|
85
|
+
status: "blocked",
|
|
86
|
+
...paths,
|
|
87
|
+
validation,
|
|
88
|
+
...issues,
|
|
89
|
+
message: error instanceof Error ? error.message : String(error),
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return {
|
|
94
|
+
status: "ready",
|
|
95
|
+
...paths,
|
|
96
|
+
validation,
|
|
97
|
+
...issues,
|
|
98
|
+
project,
|
|
99
|
+
preview,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
@@ -11,6 +11,7 @@ import { join, relative } from "node:path";
|
|
|
11
11
|
|
|
12
12
|
import { getAllMilestones, getMilestoneSlices, getSliceTasks } from "../gsd-db.js";
|
|
13
13
|
import { saveFile } from "../files.js";
|
|
14
|
+
import { isClosedStatus } from "../status-guards.js";
|
|
14
15
|
import type { PlanningLayout } from "../compat/compat-marker.js";
|
|
15
16
|
import {
|
|
16
17
|
applyPlanningProjectionWrites,
|
|
@@ -104,7 +105,7 @@ function formatPlanningPlan(
|
|
|
104
105
|
phaseNum: number,
|
|
105
106
|
planNum: number,
|
|
106
107
|
title: string,
|
|
107
|
-
tasks: Array<{ id: string; title: string; estimate?: string }>,
|
|
108
|
+
tasks: Array<{ id: string; title: string; estimate?: string; done?: boolean }>,
|
|
108
109
|
): string {
|
|
109
110
|
const lines: string[] = [];
|
|
110
111
|
lines.push(`# ${pad(phaseNum)}-${pad(planNum)}: ${title}`, "");
|
|
@@ -115,7 +116,11 @@ function formatPlanningPlan(
|
|
|
115
116
|
lines.push("<tasks>");
|
|
116
117
|
for (const t of tasks) {
|
|
117
118
|
const est = t.estimate ? ` _(${t.estimate})_` : "";
|
|
118
|
-
|
|
119
|
+
// Render the checkbox from the task's DB status so a DB→.planning
|
|
120
|
+
// projection preserves completion. Hardcoding `[ ]` here silently reset
|
|
121
|
+
// every completed historical task to unchecked on each reconcile (#1276).
|
|
122
|
+
const box = t.done ? "[x]" : "[ ]";
|
|
123
|
+
lines.push(`- ${box} **${t.id}**: ${t.title}${est}`);
|
|
119
124
|
}
|
|
120
125
|
lines.push("</tasks>");
|
|
121
126
|
lines.push("");
|
|
@@ -173,7 +178,7 @@ export async function writePlanningDirectory(
|
|
|
173
178
|
|
|
174
179
|
const tasks = getSliceTasks(milestone.id, slice.id);
|
|
175
180
|
const isDone =
|
|
176
|
-
tasks.length > 0 && tasks.every((t) => t.status
|
|
181
|
+
tasks.length > 0 && tasks.every((t) => isClosedStatus(t.status));
|
|
177
182
|
roadmapEntries.push({
|
|
178
183
|
number: phaseNum,
|
|
179
184
|
title: slice.title || slice.id,
|
|
@@ -181,17 +186,14 @@ export async function writePlanningDirectory(
|
|
|
181
186
|
});
|
|
182
187
|
|
|
183
188
|
if (tasks.length === 0) {
|
|
184
|
-
//
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
)
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
relPath: toPlanningRel(planPath),
|
|
193
|
-
entities: [`${milestone.id}/${slice.id}`],
|
|
194
|
-
});
|
|
189
|
+
// Sketch / undecomposed slice — zero tasks. Do NOT emit an ingestible
|
|
190
|
+
// *-PLAN.md here: the reverse transform maps one GSDTask per plan file
|
|
191
|
+
// (transformer.ts mapSlice), so a placeholder would materialize a
|
|
192
|
+
// phantom "Plan NN" task and flip the slice from "needs planning" to
|
|
193
|
+
// "has a planned task", causing auto-mode to skip planning (issue #1285).
|
|
194
|
+
// The phase dir is already created (mkdirSync above) and the slice is
|
|
195
|
+
// listed in ROADMAP.md, so it round-trips with tasks = [] — the correct
|
|
196
|
+
// sketch-slice shape.
|
|
195
197
|
} else {
|
|
196
198
|
for (let ti = 0; ti < tasks.length; ti++) {
|
|
197
199
|
const task = tasks[ti]!;
|
|
@@ -204,6 +206,7 @@ export async function writePlanningDirectory(
|
|
|
204
206
|
id: task.id,
|
|
205
207
|
title: task.title || task.id,
|
|
206
208
|
estimate: task.estimate || undefined,
|
|
209
|
+
done: isClosedStatus(task.status),
|
|
207
210
|
},
|
|
208
211
|
]),
|
|
209
212
|
);
|
|
@@ -217,19 +220,14 @@ export async function writePlanningDirectory(
|
|
|
217
220
|
}
|
|
218
221
|
}
|
|
219
222
|
|
|
220
|
-
// If no slices produced any phases,
|
|
221
|
-
//
|
|
223
|
+
// If no slices produced any phases, emit a single empty phase dir + ROADMAP
|
|
224
|
+
// entry so the layout stays discoverable. Do NOT write a placeholder
|
|
225
|
+
// *-PLAN.md — an ingestible plan file would round-trip into a phantom task
|
|
226
|
+
// (see the tasks.length === 0 branch above, issue #1285).
|
|
222
227
|
if (roadmapEntries.length === 0) {
|
|
223
228
|
const phaseDirName = `${pad(1)}-milestone`;
|
|
224
229
|
const phaseDir = join(root, "phases", phaseDirName);
|
|
225
230
|
mkdirSync(phaseDir, { recursive: true });
|
|
226
|
-
const planPath = join(phaseDir, `${pad(1)}-01-PLAN.md`);
|
|
227
|
-
await saveFile(planPath, formatPlanningPlan(1, 1, milestones[0]!.title || milestones[0]!.id, []));
|
|
228
|
-
paths.push(planPath);
|
|
229
|
-
projectionWrites.push({
|
|
230
|
-
relPath: toPlanningRel(planPath),
|
|
231
|
-
entities: [milestones[0]!.id],
|
|
232
|
-
});
|
|
233
231
|
roadmapEntries.push({ number: 1, title: milestones[0]!.title || milestones[0]!.id, done: false });
|
|
234
232
|
}
|
|
235
233
|
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// gsd-pi - /gsd migrate presentation helpers.
|
|
2
|
+
// File Purpose: Pure formatting for migration previews and post-write review prompts.
|
|
3
|
+
|
|
4
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
5
|
+
import { dirname, join } from "node:path";
|
|
6
|
+
import { fileURLToPath } from "node:url";
|
|
7
|
+
|
|
8
|
+
import { gsdRoot } from "../paths.js";
|
|
9
|
+
import type { MigrationPreview } from "./writer.js";
|
|
10
|
+
|
|
11
|
+
export interface ReviewPromptInput {
|
|
12
|
+
sourcePath: string;
|
|
13
|
+
gsdPath: string;
|
|
14
|
+
preview: MigrationPreview;
|
|
15
|
+
templatePath?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function formatRequirements(preview: MigrationPreview): string | null {
|
|
19
|
+
if (preview.requirements.total === 0) return null;
|
|
20
|
+
return `Requirements: ${preview.requirements.total} (${preview.requirements.validated} validated, ${preview.requirements.active} active, ${preview.requirements.deferred} deferred, ${preview.requirements.outOfScope} out of scope)`;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function formatLegacyInputs(preview: MigrationPreview): string | null {
|
|
24
|
+
if (!preview.migrationInputs) return null;
|
|
25
|
+
return `Legacy inputs: ${preview.migrationInputs.milestonePhaseDirs} milestone phase dir(s), ${preview.migrationInputs.decisions} decision file(s), ${preview.migrationInputs.seeds} seed file(s)`;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function buildMigrationPreviewSummary(preview: MigrationPreview, targetRoot: string): string[] {
|
|
29
|
+
const lines: string[] = [
|
|
30
|
+
`Decisions: ${preview.decisions.total}`,
|
|
31
|
+
`Milestones: ${preview.milestoneCount}`,
|
|
32
|
+
`Slices: ${preview.totalSlices} (${preview.doneSlices} done — ${preview.sliceCompletionPct}%)`,
|
|
33
|
+
`Tasks: ${preview.totalTasks} (${preview.doneTasks} done — ${preview.taskCompletionPct}%)`,
|
|
34
|
+
];
|
|
35
|
+
|
|
36
|
+
const requirements = formatRequirements(preview);
|
|
37
|
+
if (requirements) lines.push(requirements);
|
|
38
|
+
|
|
39
|
+
const legacyInputs = formatLegacyInputs(preview);
|
|
40
|
+
if (legacyInputs) lines.push(legacyInputs);
|
|
41
|
+
|
|
42
|
+
const targetGsdPath = gsdRoot(targetRoot);
|
|
43
|
+
if (existsSync(targetGsdPath)) {
|
|
44
|
+
lines.push("");
|
|
45
|
+
lines.push(`⚠ A .gsd directory already exists at ${targetGsdPath}.`);
|
|
46
|
+
lines.push("It will be backed up, deleted, and rewritten fresh before DB import.");
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return lines;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function formatMigrationPreviewStats(preview: MigrationPreview): string {
|
|
53
|
+
const lines = [
|
|
54
|
+
`- Decisions: ${preview.decisions.total}`,
|
|
55
|
+
`- Milestones: ${preview.milestoneCount}`,
|
|
56
|
+
`- Slices: ${preview.totalSlices} (${preview.doneSlices} done — ${preview.sliceCompletionPct}%)`,
|
|
57
|
+
`- Tasks: ${preview.totalTasks} (${preview.doneTasks} done — ${preview.taskCompletionPct}%)`,
|
|
58
|
+
];
|
|
59
|
+
|
|
60
|
+
const requirements = formatRequirements(preview);
|
|
61
|
+
if (requirements) lines.push(`- ${requirements}`);
|
|
62
|
+
|
|
63
|
+
const legacyInputs = formatLegacyInputs(preview);
|
|
64
|
+
if (legacyInputs) lines.push(`- ${legacyInputs}`);
|
|
65
|
+
|
|
66
|
+
return lines.join("\n");
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function defaultReviewTemplatePath(): string {
|
|
70
|
+
const promptsDir = join(dirname(fileURLToPath(import.meta.url)), "..", "prompts");
|
|
71
|
+
return join(promptsDir, "review-migration.md");
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function buildReviewPrompt(input: ReviewPromptInput): string {
|
|
75
|
+
const templatePath = input.templatePath ?? defaultReviewTemplatePath();
|
|
76
|
+
let content = readFileSync(templatePath, "utf-8");
|
|
77
|
+
|
|
78
|
+
content = content.replaceAll("{{sourcePath}}", input.sourcePath);
|
|
79
|
+
content = content.replaceAll("{{gsdPath}}", input.gsdPath);
|
|
80
|
+
content = content.replaceAll("{{previewStats}}", formatMigrationPreviewStats(input.preview));
|
|
81
|
+
|
|
82
|
+
return content.trim();
|
|
83
|
+
}
|
|
@@ -169,6 +169,9 @@ export function scanMarkdownHierarchy(basePath: string): HierarchyScan {
|
|
|
169
169
|
|
|
170
170
|
for (const slice of roadmap.slices) {
|
|
171
171
|
scan.slices.add(`${milestoneId}/${slice.id}`);
|
|
172
|
+
// Sketch slices carry only a stub PLAN until refined; match migrateHierarchyToDb
|
|
173
|
+
// and do not count placeholder tasks from the <tasks> block (#1286).
|
|
174
|
+
if (slice.isSketch) continue;
|
|
172
175
|
const planPath = resolveSliceFile(basePath, milestoneId, slice.id, "PLAN");
|
|
173
176
|
if (!planPath || !existsSync(planPath)) continue;
|
|
174
177
|
const plan = parsePlan(readFileSync(planPath, "utf-8"));
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
import { deriveState } from "./state.js";
|
|
9
9
|
import { resolveMilestoneFile, resolveSliceFile } from "./paths.js";
|
|
10
10
|
import { findMilestoneIds } from "./guided-flow.js";
|
|
11
|
-
import { isDbAvailable, getMilestoneSlices,
|
|
11
|
+
import { isDbAvailable, getMilestoneSlices, getTasksBySliceIds } from "./gsd-db.js";
|
|
12
12
|
import { openExistingWorkflowDatabase } from "./db-workspace.js";
|
|
13
13
|
import type { MilestoneRegistryEntry } from "./types.js";
|
|
14
14
|
|
|
@@ -40,10 +40,11 @@ async function collectTouchedFiles(
|
|
|
40
40
|
const files = new Set<string>();
|
|
41
41
|
|
|
42
42
|
if (isDbAvailable()) {
|
|
43
|
-
// DB path: query slices and their tasks for file lists
|
|
43
|
+
// DB path: query slices and their tasks for file lists (one batched task
|
|
44
|
+
// query instead of one per slice; file order is irrelevant here — Set dedup)
|
|
44
45
|
const slices = getMilestoneSlices(milestoneId);
|
|
45
|
-
|
|
46
|
-
|
|
46
|
+
const tasksBySlice = getTasksBySliceIds(slices.map((slice) => ({ milestoneId, sliceId: slice.id })));
|
|
47
|
+
for (const tasks of tasksBySlice.values()) {
|
|
47
48
|
for (const task of tasks) {
|
|
48
49
|
if (Array.isArray(task.files)) {
|
|
49
50
|
for (const f of task.files) {
|
|
@@ -72,6 +72,7 @@ interface WorkerView {
|
|
|
72
72
|
totalSlices: number;
|
|
73
73
|
doneSlices: number;
|
|
74
74
|
slices: SliceProgress[];
|
|
75
|
+
completions: string[];
|
|
75
76
|
errors: string[];
|
|
76
77
|
}
|
|
77
78
|
|
|
@@ -143,14 +144,21 @@ function discoverWorkers(basePath: string): string[] {
|
|
|
143
144
|
return [...mids].sort();
|
|
144
145
|
}
|
|
145
146
|
|
|
146
|
-
|
|
147
|
+
// Slice progress + recent completions share one DB connection per worker per
|
|
148
|
+
// tick. Opening the isolated worker DB twice per refresh (once for each) was
|
|
149
|
+
// pure churn on the 5s interval.
|
|
150
|
+
function queryWorkerProgress(
|
|
151
|
+
basePath: string,
|
|
152
|
+
mid: string,
|
|
153
|
+
workRoot: string = worktreePathFor(basePath, mid),
|
|
154
|
+
): { slices: SliceProgress[]; completions: string[] } {
|
|
147
155
|
const dbPath = resolveGsdPathContract(workRoot, basePath).projectDb;
|
|
148
|
-
if (!existsSync(dbPath)) return [];
|
|
156
|
+
if (!existsSync(dbPath)) return { slices: [], completions: [] };
|
|
149
157
|
|
|
150
158
|
const db = openWorkflowDatabaseIsolated(dbPath);
|
|
151
|
-
if (!db) return [];
|
|
159
|
+
if (!db) return { slices: [], completions: [] };
|
|
152
160
|
try {
|
|
153
|
-
const
|
|
161
|
+
const sliceRows = db.prepare(
|
|
154
162
|
`SELECT
|
|
155
163
|
s.id AS id,
|
|
156
164
|
s.status AS status,
|
|
@@ -162,14 +170,32 @@ function querySliceProgress(basePath: string, mid: string, workRoot: string = wo
|
|
|
162
170
|
GROUP BY s.id
|
|
163
171
|
ORDER BY s.id`,
|
|
164
172
|
).all({ ":mid": mid });
|
|
165
|
-
|
|
173
|
+
const slices = sliceRows.map((row) => ({
|
|
166
174
|
id: String(row["id"] ?? ""),
|
|
167
175
|
status: String(row["status"] ?? ""),
|
|
168
176
|
total: Number(row["total"] ?? 0),
|
|
169
177
|
done: Number(row["done"] ?? 0),
|
|
170
178
|
}));
|
|
179
|
+
|
|
180
|
+
const completionRows = db.prepare(
|
|
181
|
+
`SELECT id, slice_id, one_liner
|
|
182
|
+
FROM tasks
|
|
183
|
+
WHERE milestone_id=:mid
|
|
184
|
+
AND status='complete'
|
|
185
|
+
AND completed_at IS NOT NULL
|
|
186
|
+
ORDER BY completed_at DESC
|
|
187
|
+
LIMIT 5`,
|
|
188
|
+
).all({ ":mid": mid });
|
|
189
|
+
const completions = completionRows.map((row) => {
|
|
190
|
+
const taskId = String(row["id"] ?? "");
|
|
191
|
+
const sliceId = String(row["slice_id"] ?? "");
|
|
192
|
+
const oneLiner = String(row["one_liner"] ?? "");
|
|
193
|
+
return `✓ ${mid}/${sliceId}/${taskId}${oneLiner ? ": " + oneLiner : ""}`;
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
return { slices, completions };
|
|
171
197
|
} catch {
|
|
172
|
-
return [];
|
|
198
|
+
return { slices: [], completions: [] };
|
|
173
199
|
} finally {
|
|
174
200
|
try { db.close(); } catch { /* ignore */ }
|
|
175
201
|
}
|
|
@@ -276,36 +302,6 @@ function extractCostFromNdjson(basePath: string, mid: string): number {
|
|
|
276
302
|
}
|
|
277
303
|
}
|
|
278
304
|
|
|
279
|
-
function queryRecentCompletions(basePath: string, mid: string): string[] {
|
|
280
|
-
const workRoot = worktreePathFor(basePath, mid);
|
|
281
|
-
const dbPath = resolveGsdPathContract(workRoot, basePath).projectDb;
|
|
282
|
-
if (!existsSync(dbPath)) return [];
|
|
283
|
-
|
|
284
|
-
const db = openWorkflowDatabaseIsolated(dbPath);
|
|
285
|
-
if (!db) return [];
|
|
286
|
-
try {
|
|
287
|
-
const rows = db.prepare(
|
|
288
|
-
`SELECT id, slice_id, one_liner
|
|
289
|
-
FROM tasks
|
|
290
|
-
WHERE milestone_id=:mid
|
|
291
|
-
AND status='complete'
|
|
292
|
-
AND completed_at IS NOT NULL
|
|
293
|
-
ORDER BY completed_at DESC
|
|
294
|
-
LIMIT 5`,
|
|
295
|
-
).all({ ":mid": mid });
|
|
296
|
-
return rows.map((row) => {
|
|
297
|
-
const taskId = String(row["id"] ?? "");
|
|
298
|
-
const sliceId = String(row["slice_id"] ?? "");
|
|
299
|
-
const oneLiner = String(row["one_liner"] ?? "");
|
|
300
|
-
return `✓ ${mid}/${sliceId}/${taskId}${oneLiner ? ": " + oneLiner : ""}`;
|
|
301
|
-
});
|
|
302
|
-
} catch {
|
|
303
|
-
return [];
|
|
304
|
-
} finally {
|
|
305
|
-
try { db.close(); } catch { /* ignore */ }
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
|
|
309
305
|
function collectWorkerData(basePath: string): WorkerView[] {
|
|
310
306
|
const mids = discoverWorkers(basePath);
|
|
311
307
|
const parallelDir = join(basePath, ".gsd", "parallel");
|
|
@@ -317,7 +313,7 @@ function collectWorkerData(basePath: string): WorkerView[] {
|
|
|
317
313
|
const workRoot = worktreePathFor(basePath, mid);
|
|
318
314
|
const status = readJsonSafe<StatusJson>(join(parallelDir, `${mid}.status.json`));
|
|
319
315
|
const lock = readJsonSafe<AutoLock>(join(workRoot, ".gsd", "auto.lock"));
|
|
320
|
-
const slices =
|
|
316
|
+
const { slices, completions } = queryWorkerProgress(basePath, mid, workRoot);
|
|
321
317
|
|
|
322
318
|
const pid = lock?.pid || status?.pid || 0;
|
|
323
319
|
const alive = pid ? isPidAlive(pid) : false;
|
|
@@ -378,6 +374,7 @@ function collectWorkerData(basePath: string): WorkerView[] {
|
|
|
378
374
|
totalSlices: slices.length,
|
|
379
375
|
doneSlices,
|
|
380
376
|
slices,
|
|
377
|
+
completions,
|
|
381
378
|
errors,
|
|
382
379
|
});
|
|
383
380
|
}
|
|
@@ -443,10 +440,10 @@ export class ParallelMonitorOverlay {
|
|
|
443
440
|
if (this.disposed) return;
|
|
444
441
|
this.workers = collectWorkerData(this.basePath);
|
|
445
442
|
|
|
446
|
-
// Collect completion events
|
|
443
|
+
// Collect completion events (already read during collectWorkerData's single
|
|
444
|
+
// DB open per worker — no second connection here).
|
|
447
445
|
for (const wk of this.workers) {
|
|
448
|
-
const
|
|
449
|
-
for (const evt of completions) {
|
|
446
|
+
for (const evt of wk.completions) {
|
|
450
447
|
if (!this.events.includes(evt)) this.events.push(evt);
|
|
451
448
|
}
|
|
452
449
|
}
|
|
@@ -618,17 +618,20 @@ function legacyMilestonesHasSubdirs(basePath: string): boolean {
|
|
|
618
618
|
* See the matching TODO in markdown-renderer.ts detectStaleRenders, which
|
|
619
619
|
* disabled stale-render detection for the same reason.
|
|
620
620
|
*/
|
|
621
|
+
const LEGACY_MILESTONE_RUNTIME_DIRS = new Set(["anchors"]);
|
|
622
|
+
|
|
621
623
|
export function dirIsContentBearingLegacyMilestone(dir: string): boolean {
|
|
622
624
|
try {
|
|
623
625
|
const entries = readdirSync(dir, { withFileTypes: true });
|
|
624
626
|
// 1. Any non-META regular file → real legacy content.
|
|
625
627
|
if (entries.some(e => e.isFile() && !e.name.endsWith("-META.json"))) return true;
|
|
626
|
-
// 2. A non-empty subdirectory → real legacy content (e.g. slices/ with slice dirs).
|
|
628
|
+
// 2. A non-empty non-runtime subdirectory → real legacy content (e.g. slices/ with slice dirs).
|
|
627
629
|
// An *empty* subdir is treated as scaffolding (e.g. git-service.ts may create
|
|
628
630
|
// an empty slices/ alongside the integration META file) and must NOT flip the
|
|
629
631
|
// layout — that is the Bugbot finding this guard addresses.
|
|
630
632
|
return entries.some(e => {
|
|
631
633
|
if (!e.isDirectory()) return false;
|
|
634
|
+
if (LEGACY_MILESTONE_RUNTIME_DIRS.has(e.name)) return false;
|
|
632
635
|
try { return readdirSync(join(dir, e.name)).length > 0; } catch { return false; }
|
|
633
636
|
});
|
|
634
637
|
} catch {
|
|
@@ -19,13 +19,17 @@ export interface PhaseAnchor {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
function anchorsDir(basePath: string, milestoneId: string): string {
|
|
22
|
-
return join(gsdRoot(basePath), "
|
|
22
|
+
return join(gsdRoot(basePath), "runtime", "anchors", milestoneId);
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
function anchorPath(basePath: string, milestoneId: string, phase: string): string {
|
|
26
26
|
return join(anchorsDir(basePath, milestoneId), `${phase}.json`);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
function legacyAnchorPath(basePath: string, milestoneId: string, phase: string): string {
|
|
30
|
+
return join(gsdRoot(basePath), "milestones", milestoneId, "anchors", `${phase}.json`);
|
|
31
|
+
}
|
|
32
|
+
|
|
29
33
|
export function writePhaseAnchor(basePath: string, milestoneId: string, anchor: PhaseAnchor): void {
|
|
30
34
|
const dir = anchorsDir(basePath, milestoneId);
|
|
31
35
|
if (!existsSync(dir)) {
|
|
@@ -35,7 +39,9 @@ export function writePhaseAnchor(basePath: string, milestoneId: string, anchor:
|
|
|
35
39
|
}
|
|
36
40
|
|
|
37
41
|
export function readPhaseAnchor(basePath: string, milestoneId: string, phase: string): PhaseAnchor | null {
|
|
38
|
-
const path = anchorPath(basePath, milestoneId, phase)
|
|
42
|
+
const path = existsSync(anchorPath(basePath, milestoneId, phase))
|
|
43
|
+
? anchorPath(basePath, milestoneId, phase)
|
|
44
|
+
: legacyAnchorPath(basePath, milestoneId, phase);
|
|
39
45
|
if (!existsSync(path)) return null;
|
|
40
46
|
try {
|
|
41
47
|
return JSON.parse(readFileSync(path, "utf-8")) as PhaseAnchor;
|
|
@@ -318,12 +318,12 @@ export function checkImportResolution(
|
|
|
318
318
|
const imports = extractRelativeImports(source);
|
|
319
319
|
|
|
320
320
|
for (const { importPath, lineNum } of imports) {
|
|
321
|
-
// Framework-generated
|
|
322
|
-
// checks
|
|
323
|
-
// block task completion on these imports.
|
|
321
|
+
// Framework/codegen-generated modules may not exist on disk during
|
|
322
|
+
// post-exec checks. Don't block task completion on these imports.
|
|
324
323
|
if (
|
|
325
324
|
/^\.{1,2}\/\+types\//.test(importPath) ||
|
|
326
|
-
/^(?:\.{1,2}\/)+(?:[^/]+\/)*\$types(?:$|\/)/.test(importPath)
|
|
325
|
+
/^(?:\.{1,2}\/)+(?:[^/]+\/)*\$types(?:$|\/)/.test(importPath) ||
|
|
326
|
+
/^(?:\.{1,2}\/)+(?:[^/]+\/)*_generated(?:$|\/)/.test(importPath)
|
|
327
327
|
) {
|
|
328
328
|
continue;
|
|
329
329
|
}
|