gsd-pi 2.78.1-dev.b0759e59b → 2.78.1-dev.d8826a445
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 -5
- package/dist/headless-recover.d.ts +23 -0
- package/dist/headless-recover.js +93 -0
- package/dist/headless.js +9 -0
- package/dist/help-text.js +1 -0
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/extensions/browser-tools/tools/intent.js +8 -1
- package/dist/resources/extensions/gsd/auto/phases.js +7 -2
- package/dist/resources/extensions/gsd/auto/session.js +3 -0
- package/dist/resources/extensions/gsd/auto-dispatch.js +7 -58
- package/dist/resources/extensions/gsd/auto-post-unit.js +14 -28
- package/dist/resources/extensions/gsd/auto-start.js +1 -8
- package/dist/resources/extensions/gsd/auto-worktree.js +244 -216
- package/dist/resources/extensions/gsd/auto.js +86 -7
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +1 -1
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +9 -77
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +17 -16
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +67 -55
- package/dist/resources/extensions/gsd/commands-codebase.js +2 -2
- package/dist/resources/extensions/gsd/commands-handlers.js +5 -5
- package/dist/resources/extensions/gsd/commands-logs.js +2 -2
- package/dist/resources/extensions/gsd/commands-scan.js +2 -2
- package/dist/resources/extensions/gsd/commands-ship.js +2 -2
- package/dist/resources/extensions/gsd/commands-workflow-templates.js +5 -5
- package/dist/resources/extensions/gsd/db-writer.js +106 -95
- package/dist/resources/extensions/gsd/delegation-policy.js +155 -0
- package/dist/resources/extensions/gsd/dispatch-guard.js +6 -10
- package/dist/resources/extensions/gsd/doctor-engine-checks.js +2 -2
- package/dist/resources/extensions/gsd/gsd-db.js +268 -8
- package/dist/resources/extensions/gsd/guided-flow-queue.js +1 -1
- package/dist/resources/extensions/gsd/guided-flow.js +141 -32
- package/dist/resources/extensions/gsd/markdown-renderer.js +14 -51
- package/dist/resources/extensions/gsd/metrics.js +287 -1
- package/dist/resources/extensions/gsd/parallel-merge.js +14 -13
- package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +5 -2
- package/dist/resources/extensions/gsd/paths.js +114 -9
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +4 -4
- package/dist/resources/extensions/gsd/prompts/execute-task.md +3 -3
- package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +8 -1
- package/dist/resources/extensions/gsd/prompts/guided-discuss-project.md +22 -7
- package/dist/resources/extensions/gsd/prompts/guided-discuss-requirements.md +6 -2
- package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +8 -1
- package/dist/resources/extensions/gsd/prompts/plan-milestone.md +6 -0
- package/dist/resources/extensions/gsd/queue-order.js +6 -1
- package/dist/resources/extensions/gsd/rethink.js +2 -2
- package/dist/resources/extensions/gsd/state.js +91 -372
- package/dist/resources/extensions/gsd/templates/project.md +10 -0
- package/dist/resources/extensions/gsd/tools/complete-milestone.js +6 -5
- package/dist/resources/extensions/gsd/tools/complete-slice.js +7 -12
- package/dist/resources/extensions/gsd/tools/complete-task.js +19 -31
- package/dist/resources/extensions/gsd/tools/validate-milestone.js +7 -5
- package/dist/resources/extensions/gsd/workflow-manifest.js +2 -1
- package/dist/resources/extensions/gsd/workflow-mcp-auto-prep.js +3 -21
- package/dist/resources/extensions/gsd/workflow-mcp.js +2 -2
- package/dist/resources/extensions/gsd/workflow-reconcile.js +3 -3
- package/dist/resources/extensions/gsd/workspace.js +59 -0
- package/dist/resources/extensions/gsd/worktree-command.js +4 -3
- package/dist/resources/extensions/gsd/worktree-resolver.js +15 -2
- package/dist/resources/extensions/gsd/write-intercept.js +3 -3
- 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 +12 -12
- package/dist/web/standalone/.next/build-manifest.json +2 -2
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/required-server-files.json +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.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- 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 +1 -1
- 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 +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
- 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 +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +12 -12
- package/dist/web/standalone/.next/server/chunks/6336.js +1 -0
- package/dist/web/standalone/.next/server/chunks/6897.js +1 -1
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- 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/server.js +1 -1
- package/package.json +1 -1
- package/packages/mcp-server/README.md +2 -11
- package/packages/mcp-server/dist/remote-questions.d.ts +27 -0
- package/packages/mcp-server/dist/remote-questions.d.ts.map +1 -1
- package/packages/mcp-server/dist/remote-questions.js +28 -0
- package/packages/mcp-server/dist/remote-questions.js.map +1 -1
- package/packages/mcp-server/dist/server.d.ts +28 -0
- package/packages/mcp-server/dist/server.d.ts.map +1 -1
- package/packages/mcp-server/dist/server.js +94 -4
- package/packages/mcp-server/dist/server.js.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts +6 -0
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +56 -2
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/src/mcp-server.test.ts +226 -0
- package/packages/mcp-server/src/parse-workflow-args.test.ts +80 -0
- package/packages/mcp-server/src/remote-questions.test.ts +103 -0
- package/packages/mcp-server/src/remote-questions.ts +35 -0
- package/packages/mcp-server/src/server.ts +129 -6
- package/packages/mcp-server/src/workflow-tools.ts +62 -3
- package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
- package/src/resources/extensions/browser-tools/tools/intent.ts +13 -2
- package/src/resources/extensions/gsd/auto/phases.ts +8 -2
- package/src/resources/extensions/gsd/auto/session.ts +4 -0
- package/src/resources/extensions/gsd/auto-dispatch.ts +14 -62
- package/src/resources/extensions/gsd/auto-post-unit.ts +15 -27
- package/src/resources/extensions/gsd/auto-start.ts +1 -8
- package/src/resources/extensions/gsd/auto-worktree.ts +286 -251
- package/src/resources/extensions/gsd/auto.ts +102 -7
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +1 -1
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +9 -84
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +17 -17
- package/src/resources/extensions/gsd/bootstrap/tests/write-gate-basepath.test.ts +103 -0
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +80 -55
- package/src/resources/extensions/gsd/commands-codebase.ts +2 -2
- package/src/resources/extensions/gsd/commands-handlers.ts +5 -5
- package/src/resources/extensions/gsd/commands-logs.ts +2 -2
- package/src/resources/extensions/gsd/commands-scan.ts +2 -2
- package/src/resources/extensions/gsd/commands-ship.ts +2 -2
- package/src/resources/extensions/gsd/commands-workflow-templates.ts +5 -5
- package/src/resources/extensions/gsd/db-writer.ts +123 -94
- package/src/resources/extensions/gsd/delegation-policy.ts +197 -0
- package/src/resources/extensions/gsd/dispatch-guard.ts +6 -11
- package/src/resources/extensions/gsd/doctor-engine-checks.ts +2 -2
- package/src/resources/extensions/gsd/gsd-db.ts +269 -8
- package/src/resources/extensions/gsd/guided-flow-queue.ts +1 -1
- package/src/resources/extensions/gsd/guided-flow.ts +181 -32
- package/src/resources/extensions/gsd/markdown-renderer.ts +13 -64
- package/src/resources/extensions/gsd/metrics.ts +321 -1
- package/src/resources/extensions/gsd/parallel-merge.ts +14 -13
- package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +5 -2
- package/src/resources/extensions/gsd/paths.ts +122 -9
- package/src/resources/extensions/gsd/prompts/complete-slice.md +4 -4
- package/src/resources/extensions/gsd/prompts/execute-task.md +3 -3
- package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +8 -1
- package/src/resources/extensions/gsd/prompts/guided-discuss-project.md +22 -7
- package/src/resources/extensions/gsd/prompts/guided-discuss-requirements.md +6 -2
- package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +8 -1
- package/src/resources/extensions/gsd/prompts/plan-milestone.md +6 -0
- package/src/resources/extensions/gsd/queue-order.ts +6 -1
- package/src/resources/extensions/gsd/rethink.ts +2 -2
- package/src/resources/extensions/gsd/state.ts +91 -389
- package/src/resources/extensions/gsd/templates/project.md +10 -0
- package/src/resources/extensions/gsd/tests/artifact-corruption-2630.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/auto-discuss-milestone-deadlock-4973.test.ts +14 -14
- package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +6 -0
- package/src/resources/extensions/gsd/tests/auto-remediate-slice-status.test.ts +21 -34
- package/src/resources/extensions/gsd/tests/auto-session-scope.test.ts +331 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +176 -0
- package/src/resources/extensions/gsd/tests/complete-task-rollback-evidence.test.ts +6 -7
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +8 -6
- package/src/resources/extensions/gsd/tests/completed-at-reconcile.test.ts +12 -27
- package/src/resources/extensions/gsd/tests/completed-units-metrics-sync.test.ts +18 -5
- package/src/resources/extensions/gsd/tests/db-path-worktree-symlink.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/db-writer-path-containment.test.ts +152 -0
- package/src/resources/extensions/gsd/tests/db-writer-root-artifact.test.ts +221 -0
- package/src/resources/extensions/gsd/tests/db-writer-scope.test.ts +230 -0
- package/src/resources/extensions/gsd/tests/db-writer.test.ts +14 -16
- package/src/resources/extensions/gsd/tests/delegation-policy.test.ts +151 -0
- package/src/resources/extensions/gsd/tests/derive-state-crossval.test.ts +6 -5
- package/src/resources/extensions/gsd/tests/derive-state-db-disk-reconcile.test.ts +10 -38
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +136 -56
- package/src/resources/extensions/gsd/tests/derive-state-draft.test.ts +3 -0
- package/src/resources/extensions/gsd/tests/derive-state-helpers.test.ts +119 -61
- package/src/resources/extensions/gsd/tests/derive-state.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/dispatch-backgroundable-annotation.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +6 -20
- package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +4 -5
- package/src/resources/extensions/gsd/tests/dispatcher-stuck-planning.test.ts +14 -15
- package/src/resources/extensions/gsd/tests/draft-promotion.test.ts +3 -23
- package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +11 -16
- package/src/resources/extensions/gsd/tests/escalation.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/gate-1b-orphan-discrimination.test.ts +193 -0
- package/src/resources/extensions/gsd/tests/gate-1b-recovery-bound-corrections.test.ts +246 -0
- package/src/resources/extensions/gsd/tests/gate-1b-recovery-bound.test.ts +218 -0
- package/src/resources/extensions/gsd/tests/gsd-db-failed-open-restore.test.ts +117 -0
- package/src/resources/extensions/gsd/tests/gsd-db-workspace-scope.test.ts +226 -0
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/gsd-root-canonical.test.ts +66 -0
- package/src/resources/extensions/gsd/tests/gsd-root-home-guard.test.ts +68 -5
- package/src/resources/extensions/gsd/tests/gsdroot-worktree-detection.test.ts +15 -36
- package/src/resources/extensions/gsd/tests/guided-flow-prompt-consolidation.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/handler-worktree-write-isolation.test.ts +57 -0
- package/src/resources/extensions/gsd/tests/integration/parallel-merge.test.ts +15 -15
- package/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts +15 -5
- package/src/resources/extensions/gsd/tests/integration/workspace-collapse-integration.test.ts +371 -0
- package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +14 -8
- package/src/resources/extensions/gsd/tests/md-importer.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/memory-store.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/metrics-atomic-merge.test.ts +222 -0
- package/src/resources/extensions/gsd/tests/metrics-lock-hardening.test.ts +400 -0
- package/src/resources/extensions/gsd/tests/metrics-lock-not-acquired.test.ts +141 -0
- package/src/resources/extensions/gsd/tests/metrics-lock-retry-sleep.test.ts +287 -0
- package/src/resources/extensions/gsd/tests/metrics-prune-cache-invalidation.test.ts +149 -0
- package/src/resources/extensions/gsd/tests/metrics-scope.test.ts +378 -0
- package/src/resources/extensions/gsd/tests/originalbase-path-comparison.test.ts +329 -0
- package/src/resources/extensions/gsd/tests/park-milestone.test.ts +2 -0
- package/src/resources/extensions/gsd/tests/path-cache-decoupled.test.ts +209 -0
- package/src/resources/extensions/gsd/tests/path-normalization-unified.test.ts +175 -0
- package/src/resources/extensions/gsd/tests/paths-cache.test.ts +170 -0
- package/src/resources/extensions/gsd/tests/pending-autostart-scope.test.ts +120 -0
- package/src/resources/extensions/gsd/tests/progressive-planning.test.ts +25 -16
- package/src/resources/extensions/gsd/tests/projection-regression.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +150 -7
- package/src/resources/extensions/gsd/tests/ready-phrase-no-files-4573.test.ts +184 -0
- package/src/resources/extensions/gsd/tests/register-hooks-compaction-checkpoint.test.ts +6 -1
- package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +28 -16
- package/src/resources/extensions/gsd/tests/replan-slice.test.ts +3 -0
- package/src/resources/extensions/gsd/tests/resolve-ts.mjs +4 -0
- package/src/resources/extensions/gsd/tests/resume-missing-worktree-warning.test.ts +209 -0
- package/src/resources/extensions/gsd/tests/rogue-file-detection.test.ts +3 -4
- package/src/resources/extensions/gsd/tests/slice-disk-reconcile.test.ts +10 -56
- package/src/resources/extensions/gsd/tests/stale-slice-rows.test.ts +15 -16
- package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/state-machine-full-walkthrough.test.ts +23 -27
- package/src/resources/extensions/gsd/tests/steer-worktree-path.test.ts +13 -14
- package/src/resources/extensions/gsd/tests/stop-auto-remote.test.ts +4 -3
- package/src/resources/extensions/gsd/tests/sync-layer-scope.test.ts +453 -0
- package/src/resources/extensions/gsd/tests/sync-worktree-skip-current.test.ts +10 -33
- package/src/resources/extensions/gsd/tests/teardown-chdir-failure-clears-registry.test.ts +162 -0
- package/src/resources/extensions/gsd/tests/teardown-cleanup-parity.test.ts +102 -0
- package/src/resources/extensions/gsd/tests/teardown-failure-clears-registry.test.ts +186 -0
- package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +7 -8
- package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +9 -15
- package/src/resources/extensions/gsd/tests/validator-scope-parity.test.ts +239 -0
- package/src/resources/extensions/gsd/tests/workflow-logger-wiring.test.ts +12 -7
- package/src/resources/extensions/gsd/tests/workflow-mcp-auto-prep.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +26 -3
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +9 -15
- package/src/resources/extensions/gsd/tests/workspace.test.ts +190 -0
- package/src/resources/extensions/gsd/tests/worktree-db-same-file.test.ts +13 -0
- package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +65 -71
- package/src/resources/extensions/gsd/tests/worktree-sync-tasks.test.ts +26 -151
- package/src/resources/extensions/gsd/tests/write-gate-predicates.test.ts +35 -35
- package/src/resources/extensions/gsd/tests/write-gate.test.ts +67 -52
- package/src/resources/extensions/gsd/tests/write-intercept.test.ts +1 -1
- package/src/resources/extensions/gsd/tools/complete-milestone.ts +7 -5
- package/src/resources/extensions/gsd/tools/complete-slice.ts +7 -14
- package/src/resources/extensions/gsd/tools/complete-task.ts +19 -34
- package/src/resources/extensions/gsd/tools/validate-milestone.ts +7 -5
- package/src/resources/extensions/gsd/workflow-manifest.ts +4 -1
- package/src/resources/extensions/gsd/workflow-mcp-auto-prep.ts +2 -18
- package/src/resources/extensions/gsd/workflow-mcp.ts +2 -2
- package/src/resources/extensions/gsd/workflow-reconcile.ts +3 -3
- package/src/resources/extensions/gsd/workspace.ts +95 -0
- package/src/resources/extensions/gsd/worktree-command.ts +4 -3
- package/src/resources/extensions/gsd/worktree-resolver.ts +16 -2
- package/src/resources/extensions/gsd/write-intercept.ts +3 -3
- package/dist/web/standalone/.next/server/chunks/8527.js +0 -1
- /package/dist/web/standalone/.next/static/{rk1EN3FQTE6Z1yalkW_GE → AT5qi39nKXkdmQIOIoh0f}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{rk1EN3FQTE6Z1yalkW_GE → AT5qi39nKXkdmQIOIoh0f}/_ssgManifest.js +0 -0
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
* from the main repo's .gsd/ into the worktree's .gsd/ for the
|
|
6
6
|
* specified milestone, and deletes gsd.db so it rebuilds from fresh state.
|
|
7
7
|
*
|
|
8
|
-
* Also verifies that syncWorktreeStateBack
|
|
9
|
-
*
|
|
8
|
+
* Also verifies that syncWorktreeStateBack does not import worktree markdown
|
|
9
|
+
* projections back into the project root.
|
|
10
10
|
*
|
|
11
11
|
* Covers:
|
|
12
12
|
* - Milestone directory synced from main to worktree
|
|
@@ -15,12 +15,12 @@
|
|
|
15
15
|
* - No-op when paths are equal
|
|
16
16
|
* - No-op when milestoneId is null
|
|
17
17
|
* - Non-existent directories handled gracefully
|
|
18
|
-
* - syncWorktreeStateBack
|
|
19
|
-
* - syncWorktreeStateBack
|
|
20
|
-
* - syncWorktreeStateBack
|
|
21
|
-
* - syncWorktreeStateBack
|
|
18
|
+
* - syncWorktreeStateBack skips milestone markdown projections
|
|
19
|
+
* - syncWorktreeStateBack does not import root-level .gsd/ state projections
|
|
20
|
+
* - syncWorktreeStateBack does not copy worktree milestone projections back
|
|
21
|
+
* - syncWorktreeStateBack leaves next-milestone projections DB/project-root authoritative
|
|
22
22
|
* - syncGsdStateToWorktree syncs non-standard milestone dir names (#1547)
|
|
23
|
-
* - syncWorktreeStateBack
|
|
23
|
+
* - syncWorktreeStateBack skips non-standard milestone projection dir names
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
26
|
import { mkdtempSync, mkdirSync, writeFileSync, rmSync, existsSync, readFileSync } from 'node:fs';
|
|
@@ -213,8 +213,8 @@ describe('worktree-sync-milestones', async () => {
|
|
|
213
213
|
}
|
|
214
214
|
}
|
|
215
215
|
|
|
216
|
-
// ─── 8. syncWorktreeStateBack
|
|
217
|
-
console.log('\n=== 8. syncWorktreeStateBack
|
|
216
|
+
// ─── 8. syncWorktreeStateBack does not copy task projections ───────────
|
|
217
|
+
console.log('\n=== 8. syncWorktreeStateBack leaves task projections in worktree ===');
|
|
218
218
|
{
|
|
219
219
|
const mainBase = mkdtempSync(join(tmpdir(), 'gsd-wt-back-main-'));
|
|
220
220
|
const wtBase = mkdtempSync(join(tmpdir(), 'gsd-wt-back-wt-'));
|
|
@@ -232,27 +232,26 @@ describe('worktree-sync-milestones', async () => {
|
|
|
232
232
|
// Main project root starts with only the milestone directory (no slices yet)
|
|
233
233
|
mkdirSync(join(mainBase, '.gsd', 'milestones', 'M002'), { recursive: true });
|
|
234
234
|
|
|
235
|
-
// Pass M001 as milestoneId (the one being merged/skipped), M002 should still sync
|
|
236
235
|
const { synced } = syncWorktreeStateBack(mainBase, wtBase, 'M001');
|
|
237
236
|
|
|
238
237
|
const mainSliceDir = join(mainBase, '.gsd', 'milestones', 'M002', 'slices', 'S01');
|
|
239
238
|
const mainTasksDir = join(mainSliceDir, 'tasks');
|
|
240
239
|
|
|
241
240
|
assert.ok(
|
|
242
|
-
existsSync(join(mainSliceDir, 'S01-SUMMARY.md')),
|
|
243
|
-
'
|
|
241
|
+
!existsSync(join(mainSliceDir, 'S01-SUMMARY.md')),
|
|
242
|
+
'slice SUMMARY projection is not copied to project root',
|
|
244
243
|
);
|
|
245
244
|
assert.ok(
|
|
246
|
-
existsSync(join(mainTasksDir, 'T01-SUMMARY.md')),
|
|
247
|
-
'
|
|
245
|
+
!existsSync(join(mainTasksDir, 'T01-SUMMARY.md')),
|
|
246
|
+
'task T01-SUMMARY projection is not copied to project root',
|
|
248
247
|
);
|
|
249
248
|
assert.ok(
|
|
250
|
-
existsSync(join(mainTasksDir, 'T02-SUMMARY.md')),
|
|
251
|
-
'
|
|
249
|
+
!existsSync(join(mainTasksDir, 'T02-SUMMARY.md')),
|
|
250
|
+
'task T02-SUMMARY projection is not copied to project root',
|
|
252
251
|
);
|
|
253
252
|
assert.ok(
|
|
254
|
-
synced.some((p) => p.includes('tasks/T01-SUMMARY.md')),
|
|
255
|
-
'
|
|
253
|
+
!synced.some((p) => p.includes('tasks/T01-SUMMARY.md')),
|
|
254
|
+
'task summary does not appear in synced list',
|
|
256
255
|
);
|
|
257
256
|
} finally {
|
|
258
257
|
rmSync(mainBase, { recursive: true, force: true });
|
|
@@ -260,8 +259,8 @@ describe('worktree-sync-milestones', async () => {
|
|
|
260
259
|
}
|
|
261
260
|
}
|
|
262
261
|
|
|
263
|
-
// ─── 9. syncWorktreeStateBack
|
|
264
|
-
console.log('\n=== 9. syncWorktreeStateBack
|
|
262
|
+
// ─── 9. syncWorktreeStateBack does not import root-level state projections ──────────
|
|
263
|
+
console.log('\n=== 9. syncWorktreeStateBack leaves root-level state projections authoritative ===');
|
|
265
264
|
{
|
|
266
265
|
const mainBase = mkdtempSync(join(tmpdir(), 'gsd-wt-back-root-main-'));
|
|
267
266
|
const wtBase = mkdtempSync(join(tmpdir(), 'gsd-wt-back-root-wt-'));
|
|
@@ -281,31 +280,31 @@ describe('worktree-sync-milestones', async () => {
|
|
|
281
280
|
|
|
282
281
|
const { synced } = syncWorktreeStateBack(mainBase, wtBase, 'M001');
|
|
283
282
|
|
|
284
|
-
// Root-level
|
|
283
|
+
// Root-level state projections must not be overwritten with worktree versions.
|
|
285
284
|
const reqContent = readFileSync(join(mainBase, '.gsd', 'REQUIREMENTS.md'), 'utf-8');
|
|
286
285
|
assert.ok(
|
|
287
|
-
reqContent.includes('R002'),
|
|
288
|
-
'REQUIREMENTS.md
|
|
286
|
+
!reqContent.includes('R002'),
|
|
287
|
+
'REQUIREMENTS.md ignores worktree projection content',
|
|
289
288
|
);
|
|
290
289
|
|
|
291
290
|
const projContent = readFileSync(join(mainBase, '.gsd', 'PROJECT.md'), 'utf-8');
|
|
292
291
|
assert.ok(
|
|
293
|
-
projContent.includes('M002'),
|
|
294
|
-
'PROJECT.md
|
|
292
|
+
!projContent.includes('M002'),
|
|
293
|
+
'PROJECT.md ignores worktree projection content',
|
|
295
294
|
);
|
|
296
295
|
|
|
297
296
|
assert.ok(
|
|
298
|
-
existsSync(join(mainBase, '.gsd', 'KNOWLEDGE.md')),
|
|
299
|
-
'KNOWLEDGE.md
|
|
297
|
+
!existsSync(join(mainBase, '.gsd', 'KNOWLEDGE.md')),
|
|
298
|
+
'KNOWLEDGE.md is not copied back from worktree',
|
|
300
299
|
);
|
|
301
300
|
|
|
302
301
|
assert.ok(
|
|
303
|
-
synced.includes('REQUIREMENTS.md'),
|
|
304
|
-
'REQUIREMENTS.md
|
|
302
|
+
!synced.includes('REQUIREMENTS.md'),
|
|
303
|
+
'REQUIREMENTS.md does not appear in synced list',
|
|
305
304
|
);
|
|
306
305
|
assert.ok(
|
|
307
|
-
synced.includes('PROJECT.md'),
|
|
308
|
-
'PROJECT.md
|
|
306
|
+
!synced.includes('PROJECT.md'),
|
|
307
|
+
'PROJECT.md does not appear in synced list',
|
|
309
308
|
);
|
|
310
309
|
} finally {
|
|
311
310
|
rmSync(mainBase, { recursive: true, force: true });
|
|
@@ -313,8 +312,8 @@ describe('worktree-sync-milestones', async () => {
|
|
|
313
312
|
}
|
|
314
313
|
}
|
|
315
314
|
|
|
316
|
-
// ─── 10. syncWorktreeStateBack
|
|
317
|
-
console.log('\n=== 10. syncWorktreeStateBack
|
|
315
|
+
// ─── 10. syncWorktreeStateBack does not copy milestone directories ─────
|
|
316
|
+
console.log('\n=== 10. syncWorktreeStateBack does not copy milestone dirs ===');
|
|
318
317
|
{
|
|
319
318
|
const mainBase = mkdtempSync(join(tmpdir(), 'gsd-wt-back-all-main-'));
|
|
320
319
|
const wtBase = mkdtempSync(join(tmpdir(), 'gsd-wt-back-all-wt-'));
|
|
@@ -352,19 +351,19 @@ describe('worktree-sync-milestones', async () => {
|
|
|
352
351
|
'M001 SUMMARY NOT synced (current milestone skipped to prevent merge conflicts)',
|
|
353
352
|
);
|
|
354
353
|
|
|
355
|
-
// M002 should be synced
|
|
354
|
+
// M002 should not be synced either; worktree projections are not authoritative.
|
|
356
355
|
assert.ok(
|
|
357
|
-
existsSync(join(mainBase, '.gsd', 'milestones', 'M002-abc123', 'M002-abc123-CONTEXT.md')),
|
|
358
|
-
'M002 CONTEXT
|
|
356
|
+
!existsSync(join(mainBase, '.gsd', 'milestones', 'M002-abc123', 'M002-abc123-CONTEXT.md')),
|
|
357
|
+
'M002 CONTEXT projection is not copied to main',
|
|
359
358
|
);
|
|
360
359
|
assert.ok(
|
|
361
|
-
existsSync(join(mainBase, '.gsd', 'milestones', 'M002-abc123', 'M002-abc123-ROADMAP.md')),
|
|
362
|
-
'M002 ROADMAP
|
|
360
|
+
!existsSync(join(mainBase, '.gsd', 'milestones', 'M002-abc123', 'M002-abc123-ROADMAP.md')),
|
|
361
|
+
'M002 ROADMAP projection is not copied to main',
|
|
363
362
|
);
|
|
364
363
|
|
|
365
364
|
assert.ok(
|
|
366
|
-
synced.some((p) => p.includes('M002-abc123')),
|
|
367
|
-
'M002
|
|
365
|
+
!synced.some((p) => p.includes('M002-abc123')),
|
|
366
|
+
'M002 does not appear in synced list',
|
|
368
367
|
);
|
|
369
368
|
} finally {
|
|
370
369
|
rmSync(mainBase, { recursive: true, force: true });
|
|
@@ -373,7 +372,7 @@ describe('worktree-sync-milestones', async () => {
|
|
|
373
372
|
}
|
|
374
373
|
|
|
375
374
|
// ─── 11. Full M006→M007 transition scenario ───────────────────────────
|
|
376
|
-
console.log('\n=== 11. complete-milestone
|
|
375
|
+
console.log('\n=== 11. complete-milestone worktree projections do not overwrite project root ===');
|
|
377
376
|
{
|
|
378
377
|
const mainBase = mkdtempSync(join(tmpdir(), 'gsd-wt-transition-main-'));
|
|
379
378
|
const wtBase = mkdtempSync(join(tmpdir(), 'gsd-wt-transition-wt-'));
|
|
@@ -419,27 +418,27 @@ describe('worktree-sync-milestones', async () => {
|
|
|
419
418
|
'M006 SUMMARY NOT synced (current milestone skipped)',
|
|
420
419
|
);
|
|
421
420
|
|
|
422
|
-
// Verify M007
|
|
421
|
+
// Verify M007 worktree projections are not copied back.
|
|
423
422
|
assert.ok(
|
|
424
|
-
existsSync(join(mainBase, '.gsd', 'milestones', 'M007-wortc8', 'M007-wortc8-CONTEXT.md')),
|
|
425
|
-
'M007 CONTEXT
|
|
423
|
+
!existsSync(join(mainBase, '.gsd', 'milestones', 'M007-wortc8', 'M007-wortc8-CONTEXT.md')),
|
|
424
|
+
'M007 CONTEXT projection is not copied to main',
|
|
426
425
|
);
|
|
427
426
|
assert.ok(
|
|
428
|
-
existsSync(join(mainBase, '.gsd', 'milestones', 'M007-wortc8', 'M007-wortc8-ROADMAP.md')),
|
|
429
|
-
'M007 ROADMAP
|
|
427
|
+
!existsSync(join(mainBase, '.gsd', 'milestones', 'M007-wortc8', 'M007-wortc8-ROADMAP.md')),
|
|
428
|
+
'M007 ROADMAP projection is not copied to main',
|
|
430
429
|
);
|
|
431
430
|
|
|
432
|
-
// Verify root-level
|
|
431
|
+
// Verify root-level projections remain project-root authoritative.
|
|
433
432
|
const reqContent = readFileSync(join(mainBase, '.gsd', 'REQUIREMENTS.md'), 'utf-8');
|
|
434
433
|
assert.ok(
|
|
435
|
-
reqContent.includes('R090'),
|
|
436
|
-
'REQUIREMENTS.md
|
|
434
|
+
!reqContent.includes('R090'),
|
|
435
|
+
'REQUIREMENTS.md ignores worktree projection updates',
|
|
437
436
|
);
|
|
438
437
|
|
|
439
438
|
const projContent = readFileSync(join(mainBase, '.gsd', 'PROJECT.md'), 'utf-8');
|
|
440
439
|
assert.ok(
|
|
441
|
-
projContent.includes('M007'),
|
|
442
|
-
'PROJECT.md
|
|
440
|
+
!projContent.includes('M007'),
|
|
441
|
+
'PROJECT.md ignores worktree projection updates',
|
|
443
442
|
);
|
|
444
443
|
} finally {
|
|
445
444
|
rmSync(mainBase, { recursive: true, force: true });
|
|
@@ -478,8 +477,8 @@ describe('worktree-sync-milestones', async () => {
|
|
|
478
477
|
}
|
|
479
478
|
}
|
|
480
479
|
|
|
481
|
-
// ─── 13. syncWorktreeStateBack
|
|
482
|
-
console.log('\n=== 13. QUEUE.md
|
|
480
|
+
// ─── 13. syncWorktreeStateBack skips QUEUE.md but preserves completed-units diagnostics ──
|
|
481
|
+
console.log('\n=== 13. QUEUE.md skipped; completed-units.json diagnostic synced ===');
|
|
483
482
|
{
|
|
484
483
|
const mainBase = mkdtempSync(join(tmpdir(), 'gsd-wt-back-queue-main-'));
|
|
485
484
|
const wtBase = mkdtempSync(join(tmpdir(), 'gsd-wt-back-queue-wt-'));
|
|
@@ -488,7 +487,7 @@ describe('worktree-sync-milestones', async () => {
|
|
|
488
487
|
mkdirSync(join(mainBase, '.gsd', 'milestones', 'M001'), { recursive: true });
|
|
489
488
|
mkdirSync(join(wtBase, '.gsd', 'milestones', 'M001'), { recursive: true });
|
|
490
489
|
|
|
491
|
-
// Worktree has QUEUE.md and completed-units.json
|
|
490
|
+
// Worktree has QUEUE.md projection and completed-units.json diagnostic.
|
|
492
491
|
writeFileSync(join(wtBase, '.gsd', 'QUEUE.md'), '# Queue\n- M002 next');
|
|
493
492
|
writeFileSync(
|
|
494
493
|
join(wtBase, '.gsd', 'completed-units.json'),
|
|
@@ -507,22 +506,17 @@ describe('worktree-sync-milestones', async () => {
|
|
|
507
506
|
|
|
508
507
|
const { synced } = syncWorktreeStateBack(mainBase, wtBase, 'M001');
|
|
509
508
|
|
|
510
|
-
// QUEUE.md should be
|
|
511
|
-
assert.ok(
|
|
512
|
-
existsSync(join(mainBase, '.gsd', 'QUEUE.md')),
|
|
513
|
-
'#1787: QUEUE.md synced from worktree to main',
|
|
514
|
-
);
|
|
515
|
-
const queueContent = readFileSync(join(mainBase, '.gsd', 'QUEUE.md'), 'utf-8');
|
|
509
|
+
// QUEUE.md is state/projection content and should not be copied back.
|
|
516
510
|
assert.ok(
|
|
517
|
-
|
|
518
|
-
'
|
|
511
|
+
!existsSync(join(mainBase, '.gsd', 'QUEUE.md')),
|
|
512
|
+
'QUEUE.md is not synced from worktree to main',
|
|
519
513
|
);
|
|
520
514
|
assert.ok(
|
|
521
|
-
synced.includes('QUEUE.md'),
|
|
522
|
-
'
|
|
515
|
+
!synced.includes('QUEUE.md'),
|
|
516
|
+
'QUEUE.md does not appear in synced list',
|
|
523
517
|
);
|
|
524
518
|
|
|
525
|
-
// completed-units.json
|
|
519
|
+
// completed-units.json is diagnostic and may be copied for operator visibility.
|
|
526
520
|
assert.ok(
|
|
527
521
|
existsSync(join(mainBase, '.gsd', 'completed-units.json')),
|
|
528
522
|
'#1787: completed-units.json synced from worktree to main',
|
|
@@ -578,8 +572,8 @@ describe('worktree-sync-milestones', async () => {
|
|
|
578
572
|
}
|
|
579
573
|
}
|
|
580
574
|
|
|
581
|
-
// ─── 15. syncWorktreeStateBack
|
|
582
|
-
console.log('\n=== 15. syncWorktreeStateBack
|
|
575
|
+
// ─── 15. syncWorktreeStateBack skips non-standard milestone dir names ──
|
|
576
|
+
console.log('\n=== 15. syncWorktreeStateBack skips non-standard milestone dir names ===');
|
|
583
577
|
{
|
|
584
578
|
const mainBase = mkdtempSync(join(tmpdir(), 'gsd-wt-back-custom-main-'));
|
|
585
579
|
const wtBase = mkdtempSync(join(tmpdir(), 'gsd-wt-back-custom-wt-'));
|
|
@@ -601,12 +595,12 @@ describe('worktree-sync-milestones', async () => {
|
|
|
601
595
|
const { synced } = syncWorktreeStateBack(mainBase, wtBase, 'M001');
|
|
602
596
|
|
|
603
597
|
assert.ok(
|
|
604
|
-
existsSync(join(mainBase, '.gsd', 'milestones', 'sprint-beta', 'SUMMARY.md')),
|
|
605
|
-
'
|
|
598
|
+
!existsSync(join(mainBase, '.gsd', 'milestones', 'sprint-beta', 'SUMMARY.md')),
|
|
599
|
+
'non-standard milestone projection is not copied back to main',
|
|
606
600
|
);
|
|
607
601
|
assert.ok(
|
|
608
|
-
synced.some((p) => p.includes('sprint-beta')),
|
|
609
|
-
'
|
|
602
|
+
!synced.some((p) => p.includes('sprint-beta')),
|
|
603
|
+
'sprint-beta does not appear in synced list',
|
|
610
604
|
);
|
|
611
605
|
} finally {
|
|
612
606
|
rmSync(mainBase, { recursive: true, force: true });
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* worktree-sync-tasks.test.ts
|
|
2
|
+
* worktree-sync-tasks.test.ts
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* DB-authoritative worktree contract: task and milestone markdown under a
|
|
5
|
+
* worktree .gsd directory are legacy projections. syncWorktreeStateBack must
|
|
6
|
+
* not copy them into the canonical project .gsd tree.
|
|
6
7
|
*/
|
|
7
8
|
|
|
8
9
|
import test from "node:test";
|
|
@@ -11,7 +12,6 @@ import {
|
|
|
11
12
|
existsSync,
|
|
12
13
|
mkdirSync,
|
|
13
14
|
mkdtempSync,
|
|
14
|
-
readFileSync,
|
|
15
15
|
rmSync,
|
|
16
16
|
writeFileSync,
|
|
17
17
|
} from "node:fs";
|
|
@@ -20,19 +20,13 @@ import { tmpdir } from "node:os";
|
|
|
20
20
|
|
|
21
21
|
import { syncWorktreeStateBack } from "../auto-worktree.ts";
|
|
22
22
|
|
|
23
|
-
// ─── Helpers ─────────────────────────────────────────────────────────
|
|
24
|
-
|
|
25
23
|
function makeTempDir(prefix: string): string {
|
|
26
24
|
return mkdtempSync(join(tmpdir(), `gsd-sync-test-${prefix}-`));
|
|
27
25
|
}
|
|
28
26
|
|
|
29
27
|
function cleanup(...dirs: string[]): void {
|
|
30
28
|
for (const dir of dirs) {
|
|
31
|
-
|
|
32
|
-
rmSync(dir, { recursive: true, force: true });
|
|
33
|
-
} catch {
|
|
34
|
-
// ignore
|
|
35
|
-
}
|
|
29
|
+
rmSync(dir, { recursive: true, force: true });
|
|
36
30
|
}
|
|
37
31
|
}
|
|
38
32
|
|
|
@@ -42,168 +36,49 @@ function writeFile(dir: string, relativePath: string, content: string): void {
|
|
|
42
36
|
writeFileSync(fullPath, content, "utf-8");
|
|
43
37
|
}
|
|
44
38
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
test("syncWorktreeStateBack copies task summaries from tasks/ subdirectory (#1678)", () => {
|
|
39
|
+
test("syncWorktreeStateBack does not copy task markdown projections from worktree", () => {
|
|
48
40
|
const mainBase = makeTempDir("main");
|
|
49
41
|
const wtBase = makeTempDir("wt");
|
|
50
|
-
const currentMid = "M000"; // milestone being merged (skipped by sync)
|
|
51
|
-
const mid = "M001"; // other milestone that should be synced
|
|
52
42
|
|
|
53
43
|
try {
|
|
54
|
-
|
|
55
|
-
writeFile(wtBase,
|
|
56
|
-
writeFile(wtBase,
|
|
57
|
-
writeFile(wtBase, `.gsd/milestones/${mid}/slices/S01/S01-PLAN.md`, "# Plan\n");
|
|
58
|
-
writeFile(wtBase, `.gsd/milestones/${mid}/slices/S01/S01-SUMMARY.md`, "# Slice Summary\n");
|
|
59
|
-
writeFile(wtBase, `.gsd/milestones/${mid}/slices/S01/S01-UAT.md`, "# UAT\n");
|
|
60
|
-
writeFile(wtBase, `.gsd/milestones/${mid}/slices/S01/tasks/T01-PLAN.md`, "# Task 1 Plan\n");
|
|
61
|
-
writeFile(wtBase, `.gsd/milestones/${mid}/slices/S01/tasks/T01-SUMMARY.md`, "# Task 1 Summary\n");
|
|
62
|
-
writeFile(wtBase, `.gsd/milestones/${mid}/slices/S01/tasks/T02-PLAN.md`, "# Task 2 Plan\n");
|
|
63
|
-
writeFile(wtBase, `.gsd/milestones/${mid}/slices/S01/tasks/T02-SUMMARY.md`, "# Task 2 Summary\n");
|
|
64
|
-
|
|
65
|
-
// Set up main with empty .gsd
|
|
44
|
+
writeFile(wtBase, ".gsd/milestones/M001/M001-ROADMAP.md", "# Roadmap\n");
|
|
45
|
+
writeFile(wtBase, ".gsd/milestones/M001/slices/S01/S01-PLAN.md", "# Plan\n");
|
|
46
|
+
writeFile(wtBase, ".gsd/milestones/M001/slices/S01/tasks/T01-SUMMARY.md", "# Task Summary\n");
|
|
66
47
|
mkdirSync(join(mainBase, ".gsd"), { recursive: true });
|
|
67
48
|
|
|
68
|
-
|
|
69
|
-
const result = syncWorktreeStateBack(mainBase, wtBase, currentMid);
|
|
70
|
-
|
|
71
|
-
// Verify milestone-level files synced
|
|
72
|
-
assert.ok(
|
|
73
|
-
existsSync(join(mainBase, `.gsd/milestones/${mid}/${mid}-ROADMAP.md`)),
|
|
74
|
-
"ROADMAP should be synced",
|
|
75
|
-
);
|
|
76
|
-
assert.ok(
|
|
77
|
-
existsSync(join(mainBase, `.gsd/milestones/${mid}/${mid}-SUMMARY.md`)),
|
|
78
|
-
"SUMMARY should be synced",
|
|
79
|
-
);
|
|
80
|
-
|
|
81
|
-
// Verify slice-level files synced
|
|
82
|
-
assert.ok(
|
|
83
|
-
existsSync(join(mainBase, `.gsd/milestones/${mid}/slices/S01/S01-PLAN.md`)),
|
|
84
|
-
"S01-PLAN should be synced",
|
|
85
|
-
);
|
|
86
|
-
assert.ok(
|
|
87
|
-
existsSync(join(mainBase, `.gsd/milestones/${mid}/slices/S01/S01-SUMMARY.md`)),
|
|
88
|
-
"S01-SUMMARY should be synced",
|
|
89
|
-
);
|
|
49
|
+
const result = syncWorktreeStateBack(mainBase, wtBase, "M000");
|
|
90
50
|
|
|
91
|
-
|
|
92
|
-
assert.
|
|
93
|
-
existsSync(join(mainBase,
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
assert.ok(
|
|
97
|
-
existsSync(join(mainBase, `.gsd/milestones/${mid}/slices/S01/tasks/T01-SUMMARY.md`)),
|
|
98
|
-
"T01-SUMMARY should be synced (was dropped before fix)",
|
|
99
|
-
);
|
|
100
|
-
assert.ok(
|
|
101
|
-
existsSync(join(mainBase, `.gsd/milestones/${mid}/slices/S01/tasks/T02-PLAN.md`)),
|
|
102
|
-
"T02-PLAN should be synced (was dropped before fix)",
|
|
103
|
-
);
|
|
104
|
-
assert.ok(
|
|
105
|
-
existsSync(join(mainBase, `.gsd/milestones/${mid}/slices/S01/tasks/T02-SUMMARY.md`)),
|
|
106
|
-
"T02-SUMMARY should be synced (was dropped before fix)",
|
|
107
|
-
);
|
|
108
|
-
|
|
109
|
-
// Verify task files appear in synced list
|
|
110
|
-
const taskSynced = result.synced.filter(p => p.includes("/tasks/"));
|
|
111
|
-
assert.ok(
|
|
112
|
-
taskSynced.length >= 4,
|
|
113
|
-
`Expected at least 4 task files in synced list, got ${taskSynced.length}: ${taskSynced.join(", ")}`,
|
|
114
|
-
);
|
|
115
|
-
|
|
116
|
-
// Verify content integrity
|
|
117
|
-
const t1Summary = readFileSync(
|
|
118
|
-
join(mainBase, `.gsd/milestones/${mid}/slices/S01/tasks/T01-SUMMARY.md`),
|
|
119
|
-
"utf-8",
|
|
51
|
+
assert.equal(result.synced.some((p) => p.includes("milestones/")), false);
|
|
52
|
+
assert.equal(
|
|
53
|
+
existsSync(join(mainBase, ".gsd/milestones/M001/M001-ROADMAP.md")),
|
|
54
|
+
false,
|
|
55
|
+
"milestone markdown projection must not be copied",
|
|
120
56
|
);
|
|
121
|
-
assert.equal(t1Summary, "# Task 1 Summary\n");
|
|
122
|
-
} finally {
|
|
123
|
-
cleanup(mainBase, wtBase);
|
|
124
|
-
}
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
test("syncWorktreeStateBack handles multiple slices with tasks (#1678)", () => {
|
|
128
|
-
const mainBase = makeTempDir("main");
|
|
129
|
-
const wtBase = makeTempDir("wt");
|
|
130
|
-
const currentMid = "M000"; // milestone being merged (skipped)
|
|
131
|
-
const mid = "M002"; // other milestone that should be synced
|
|
132
|
-
|
|
133
|
-
try {
|
|
134
|
-
// Set up two slices with tasks
|
|
135
|
-
writeFile(wtBase, `.gsd/milestones/${mid}/slices/S01/S01-SUMMARY.md`, "# S01\n");
|
|
136
|
-
writeFile(wtBase, `.gsd/milestones/${mid}/slices/S01/tasks/T01-SUMMARY.md`, "# S01-T01\n");
|
|
137
|
-
writeFile(wtBase, `.gsd/milestones/${mid}/slices/S02/S02-SUMMARY.md`, "# S02\n");
|
|
138
|
-
writeFile(wtBase, `.gsd/milestones/${mid}/slices/S02/tasks/T01-SUMMARY.md`, "# S02-T01\n");
|
|
139
|
-
writeFile(wtBase, `.gsd/milestones/${mid}/slices/S02/tasks/T02-SUMMARY.md`, "# S02-T02\n");
|
|
140
|
-
writeFile(wtBase, `.gsd/milestones/${mid}/slices/S02/tasks/T03-SUMMARY.md`, "# S02-T03\n");
|
|
141
|
-
|
|
142
|
-
mkdirSync(join(mainBase, ".gsd"), { recursive: true });
|
|
143
|
-
|
|
144
|
-
const result = syncWorktreeStateBack(mainBase, wtBase, currentMid);
|
|
145
|
-
|
|
146
|
-
// All task summaries from both slices should be synced
|
|
147
|
-
assert.ok(existsSync(join(mainBase, `.gsd/milestones/${mid}/slices/S01/tasks/T01-SUMMARY.md`)));
|
|
148
|
-
assert.ok(existsSync(join(mainBase, `.gsd/milestones/${mid}/slices/S02/tasks/T01-SUMMARY.md`)));
|
|
149
|
-
assert.ok(existsSync(join(mainBase, `.gsd/milestones/${mid}/slices/S02/tasks/T02-SUMMARY.md`)));
|
|
150
|
-
assert.ok(existsSync(join(mainBase, `.gsd/milestones/${mid}/slices/S02/tasks/T03-SUMMARY.md`)));
|
|
151
|
-
|
|
152
|
-
// Verify content integrity across slices
|
|
153
57
|
assert.equal(
|
|
154
|
-
|
|
155
|
-
|
|
58
|
+
existsSync(join(mainBase, ".gsd/milestones/M001/slices/S01/tasks/T01-SUMMARY.md")),
|
|
59
|
+
false,
|
|
60
|
+
"task summary projection must not be copied",
|
|
156
61
|
);
|
|
157
62
|
} finally {
|
|
158
63
|
cleanup(mainBase, wtBase);
|
|
159
64
|
}
|
|
160
65
|
});
|
|
161
66
|
|
|
162
|
-
test("syncWorktreeStateBack
|
|
163
|
-
const mainBase = makeTempDir("main");
|
|
164
|
-
const wtBase = makeTempDir("wt");
|
|
165
|
-
const currentMid = "M000"; // milestone being merged (skipped)
|
|
166
|
-
const mid = "M003"; // other milestone that should be synced
|
|
167
|
-
|
|
168
|
-
try {
|
|
169
|
-
// Slice with no tasks/ subdirectory (legitimate case: pre-planning)
|
|
170
|
-
writeFile(wtBase, `.gsd/milestones/${mid}/slices/S01/S01-RESEARCH.md`, "# Research\n");
|
|
171
|
-
|
|
172
|
-
mkdirSync(join(mainBase, ".gsd"), { recursive: true });
|
|
173
|
-
|
|
174
|
-
const result = syncWorktreeStateBack(mainBase, wtBase, currentMid);
|
|
175
|
-
|
|
176
|
-
// Should sync the slice file without errors
|
|
177
|
-
assert.ok(existsSync(join(mainBase, `.gsd/milestones/${mid}/slices/S01/S01-RESEARCH.md`)));
|
|
178
|
-
// Should not have any task entries
|
|
179
|
-
const taskSynced = result.synced.filter(p => p.includes("/tasks/"));
|
|
180
|
-
assert.equal(taskSynced.length, 0);
|
|
181
|
-
} finally {
|
|
182
|
-
cleanup(mainBase, wtBase);
|
|
183
|
-
}
|
|
184
|
-
});
|
|
185
|
-
|
|
186
|
-
test("syncWorktreeStateBack ignores non-md files in tasks/", () => {
|
|
67
|
+
test("syncWorktreeStateBack still copies diagnostic root files", () => {
|
|
187
68
|
const mainBase = makeTempDir("main");
|
|
188
69
|
const wtBase = makeTempDir("wt");
|
|
189
|
-
const currentMid = "M000"; // milestone being merged (skipped)
|
|
190
|
-
const mid = "M004"; // other milestone that should be synced
|
|
191
70
|
|
|
192
71
|
try {
|
|
193
|
-
writeFile(wtBase,
|
|
194
|
-
writeFile(wtBase,
|
|
195
|
-
// Non-md file should be ignored
|
|
196
|
-
writeFile(wtBase, `.gsd/milestones/${mid}/slices/S01/tasks/.DS_Store`, "junk");
|
|
197
|
-
writeFile(wtBase, `.gsd/milestones/${mid}/slices/S01/tasks/notes.txt`, "notes");
|
|
198
|
-
|
|
72
|
+
writeFile(wtBase, ".gsd/completed-units.json", JSON.stringify({ units: ["M001/S01/T01"] }));
|
|
73
|
+
writeFile(wtBase, ".gsd/metrics.json", JSON.stringify({ version: 1, units: [] }));
|
|
199
74
|
mkdirSync(join(mainBase, ".gsd"), { recursive: true });
|
|
200
75
|
|
|
201
|
-
const result = syncWorktreeStateBack(mainBase, wtBase,
|
|
76
|
+
const result = syncWorktreeStateBack(mainBase, wtBase, "M001");
|
|
202
77
|
|
|
203
|
-
|
|
204
|
-
assert.ok(
|
|
205
|
-
assert.ok(
|
|
206
|
-
assert.ok(
|
|
78
|
+
assert.ok(result.synced.includes("completed-units.json"));
|
|
79
|
+
assert.ok(result.synced.includes("metrics.json"));
|
|
80
|
+
assert.ok(existsSync(join(mainBase, ".gsd/completed-units.json")));
|
|
81
|
+
assert.ok(existsSync(join(mainBase, ".gsd/metrics.json")));
|
|
207
82
|
} finally {
|
|
208
83
|
cleanup(mainBase, wtBase);
|
|
209
84
|
}
|