@opengsd/gsd-pi 1.9.0-dev.e10b60d4 → 1.10.0

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.
Files changed (228) hide show
  1. package/README.md +10 -10
  2. package/dist/resources/.managed-resources-content-hash +1 -1
  3. package/dist/resources/extensions/gsd/auto/loop.js +24 -4
  4. package/dist/resources/extensions/gsd/auto/run-unit.js +19 -1
  5. package/dist/resources/extensions/gsd/auto-start.js +29 -9
  6. package/dist/resources/extensions/gsd/auto-worktree-sync.js +7 -3
  7. package/dist/resources/extensions/gsd/auto.js +12 -1
  8. package/dist/resources/extensions/gsd/doctor-engine-checks.js +21 -2
  9. package/dist/resources/extensions/gsd/flat-phase-migration.js +12 -0
  10. package/dist/resources/extensions/gsd/gsd-db.js +75 -31
  11. package/dist/resources/extensions/gsd/worktree-state-projection.js +20 -18
  12. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  13. package/dist/web/standalone/.next/BUILD_ID +1 -1
  14. package/dist/web/standalone/.next/app-path-routes-manifest.json +8 -8
  15. package/dist/web/standalone/.next/build-manifest.json +3 -3
  16. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  17. package/dist/web/standalone/.next/required-server-files.json +3 -3
  18. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  19. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  20. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  21. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  22. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  23. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  24. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  25. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  26. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  27. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  28. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  29. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  30. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  31. package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
  32. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  33. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  34. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  35. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  36. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  37. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  38. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  39. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  40. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  41. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  42. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  43. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  44. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  45. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  46. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  47. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  48. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  49. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  50. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  51. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  52. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  53. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  54. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  55. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  56. package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
  57. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  58. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  59. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  60. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  61. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  62. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  63. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  64. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  65. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  66. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  67. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  68. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  69. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  70. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  71. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  72. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  73. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  74. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  75. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  76. package/dist/web/standalone/.next/server/app/api/mcp-connections/route.js +1 -1
  77. package/dist/web/standalone/.next/server/app/api/mcp-connections/route_client-reference-manifest.js +1 -1
  78. package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
  79. package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
  80. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  81. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  82. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  83. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  84. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  85. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  86. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  87. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  88. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
  89. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  90. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  91. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  92. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  93. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  94. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  95. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  96. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  97. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  98. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  99. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  100. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  101. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  102. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  103. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  104. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  105. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  106. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  107. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  108. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
  109. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  110. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  111. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  112. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +1 -1
  113. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  114. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  115. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  116. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  117. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  118. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  119. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  120. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  121. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  122. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  123. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  124. package/dist/web/standalone/.next/server/app/index.html +1 -1
  125. package/dist/web/standalone/.next/server/app/index.rsc +4 -4
  126. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  127. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
  128. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  129. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
  130. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  131. package/dist/web/standalone/.next/server/app/page.js +2 -2
  132. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  133. package/dist/web/standalone/.next/server/app-paths-manifest.json +8 -8
  134. package/dist/web/standalone/.next/server/chunks/1991.js +2 -2
  135. package/dist/web/standalone/.next/server/chunks/2842.js +4 -4
  136. package/dist/web/standalone/.next/server/chunks/5124.js +1 -1
  137. package/dist/web/standalone/.next/server/chunks/8357.js +3 -3
  138. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  139. package/dist/web/standalone/.next/server/middleware.js +3 -3
  140. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  141. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  142. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  143. package/dist/web/standalone/.next/static/chunks/app/_not-found/page-49f565245e1e4afe.js +1 -0
  144. package/dist/web/standalone/.next/static/chunks/app/{layout-4ae2d68984392bbf.js → layout-b35cbfff38aaf4cf.js} +1 -1
  145. package/dist/web/standalone/.next/static/chunks/app/page-bc4c723c6a19c6f0.js +1 -0
  146. package/dist/web/standalone/.next/static/chunks/{main-app-90d1d8d5e5d2dc6b.js → main-app-590a74400e35f685.js} +1 -1
  147. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ec3eaffc9785ba48.js +1 -0
  148. package/dist/web/standalone/node_modules/@gsd/native/package.json +1 -1
  149. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  150. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  151. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  152. package/dist/web/standalone/server.js +1 -1
  153. package/integrations/hermes/open_gsd_hermes/gsd_client.py +1 -1
  154. package/integrations/hermes/pyproject.toml +1 -1
  155. package/package.json +6 -6
  156. package/packages/cloud-mcp-gateway/package.json +2 -2
  157. package/packages/contracts/package.json +1 -1
  158. package/packages/daemon/package.json +4 -4
  159. package/packages/gsd-agent-core/package.json +5 -5
  160. package/packages/gsd-agent-modes/package.json +7 -7
  161. package/packages/gsd-cloud/README.md +9 -3
  162. package/packages/gsd-cloud/dist/background-cli.test.d.ts +2 -0
  163. package/packages/gsd-cloud/dist/background-cli.test.d.ts.map +1 -0
  164. package/packages/gsd-cloud/dist/background-cli.test.js +248 -0
  165. package/packages/gsd-cloud/dist/background-cli.test.js.map +1 -0
  166. package/packages/gsd-cloud/dist/cli.d.ts.map +1 -1
  167. package/packages/gsd-cloud/dist/cli.js +121 -15
  168. package/packages/gsd-cloud/dist/cli.js.map +1 -1
  169. package/packages/gsd-cloud/dist/cloud-config.d.ts +1 -1
  170. package/packages/gsd-cloud/dist/cloud-config.d.ts.map +1 -1
  171. package/packages/gsd-cloud/dist/cloud-config.js +7 -1
  172. package/packages/gsd-cloud/dist/cloud-config.js.map +1 -1
  173. package/packages/gsd-cloud/dist/cloud-runtime.d.ts +1 -3
  174. package/packages/gsd-cloud/dist/cloud-runtime.d.ts.map +1 -1
  175. package/packages/gsd-cloud/dist/cloud-runtime.js +9 -7
  176. package/packages/gsd-cloud/dist/cloud-runtime.js.map +1 -1
  177. package/packages/gsd-cloud/dist/runtime-process.d.ts +27 -0
  178. package/packages/gsd-cloud/dist/runtime-process.d.ts.map +1 -0
  179. package/packages/gsd-cloud/dist/runtime-process.js +272 -0
  180. package/packages/gsd-cloud/dist/runtime-process.js.map +1 -0
  181. package/packages/gsd-cloud/dist/runtime-process.test.d.ts +2 -0
  182. package/packages/gsd-cloud/dist/runtime-process.test.d.ts.map +1 -0
  183. package/packages/gsd-cloud/dist/runtime-process.test.js +97 -0
  184. package/packages/gsd-cloud/dist/runtime-process.test.js.map +1 -0
  185. package/packages/gsd-cloud/package.json +2 -2
  186. package/packages/mcp-server/dist/cli-runner.d.ts +3 -0
  187. package/packages/mcp-server/dist/cli-runner.d.ts.map +1 -1
  188. package/packages/mcp-server/dist/cli-runner.js +119 -33
  189. package/packages/mcp-server/dist/cli-runner.js.map +1 -1
  190. package/packages/mcp-server/package.json +4 -4
  191. package/packages/native/package.json +1 -1
  192. package/packages/pi-agent-core/package.json +1 -1
  193. package/packages/pi-ai/dist/models.generated.d.ts +17 -0
  194. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  195. package/packages/pi-ai/dist/models.generated.js +17 -0
  196. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  197. package/packages/pi-ai/package.json +1 -1
  198. package/packages/pi-coding-agent/dist/core/skills.d.ts +5 -0
  199. package/packages/pi-coding-agent/dist/core/skills.d.ts.map +1 -1
  200. package/packages/pi-coding-agent/dist/core/skills.js +54 -0
  201. package/packages/pi-coding-agent/dist/core/skills.js.map +1 -1
  202. package/packages/pi-coding-agent/package.json +7 -7
  203. package/packages/pi-tui/package.json +2 -2
  204. package/packages/rpc-client/package.json +2 -2
  205. package/pkg/package.json +1 -1
  206. package/src/resources/extensions/gsd/auto/loop.ts +48 -4
  207. package/src/resources/extensions/gsd/auto/run-unit.ts +20 -1
  208. package/src/resources/extensions/gsd/auto-start.ts +31 -8
  209. package/src/resources/extensions/gsd/auto-worktree-sync.ts +10 -3
  210. package/src/resources/extensions/gsd/auto.ts +13 -1
  211. package/src/resources/extensions/gsd/doctor-engine-checks.ts +27 -2
  212. package/src/resources/extensions/gsd/flat-phase-migration.ts +14 -0
  213. package/src/resources/extensions/gsd/gsd-db.ts +85 -33
  214. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +156 -0
  215. package/src/resources/extensions/gsd/tests/auto-start-index-lock.test.ts +21 -1
  216. package/src/resources/extensions/gsd/tests/auto-wrapup-inflight-guard.test.ts +74 -1
  217. package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +83 -0
  218. package/src/resources/extensions/gsd/tests/flat-phase-migration.test.ts +8 -9
  219. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +32 -0
  220. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +13 -0
  221. package/src/resources/extensions/gsd/tests/worktree-state-projection.test.ts +2 -2
  222. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +60 -0
  223. package/src/resources/extensions/gsd/worktree-state-projection.ts +21 -24
  224. package/dist/web/standalone/.next/static/chunks/app/_not-found/page-a6fb1847f67f167c.js +0 -1
  225. package/dist/web/standalone/.next/static/chunks/app/page-72a856634ad14c10.js +0 -1
  226. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-1115d46ac61b9823.js +0 -1
  227. /package/dist/web/standalone/.next/static/{V9MAVyYVPboQUB9KTTAMi → EAhnhYMt5UVOiG9-iPDjc}/_buildManifest.js +0 -0
  228. /package/dist/web/standalone/.next/static/{V9MAVyYVPboQUB9KTTAMi → EAhnhYMt5UVOiG9-iPDjc}/_ssgManifest.js +0 -0
@@ -1428,6 +1428,19 @@ process.exit(result.status ?? 0);
1428
1428
  rmSync(repo, { recursive: true, force: true });
1429
1429
  });
1430
1430
 
1431
+ test('Integration branch: write does not create legacy milestones scaffold', () => {
1432
+ const repo = initBranchTestRepo();
1433
+ mkdirSync(join(repo, ".gsd", "phases"), { recursive: true });
1434
+
1435
+ writeIntegrationBranch(repo, "M001", "f-123-new-thing");
1436
+
1437
+ assert.deepStrictEqual(readIntegrationBranch(repo, "M001"), "f-123-new-thing");
1438
+ assert.ok(existsSync(join(repo, ".gsd", "M001-META.json")), "metadata is written at the flat .gsd root");
1439
+ assert.ok(!existsSync(join(repo, ".gsd", "milestones")), "legacy milestones/ root is not created");
1440
+
1441
+ rmSync(repo, { recursive: true, force: true });
1442
+ });
1443
+
1431
1444
  // ─── writeIntegrationBranch: updates when branch changes (#300) ──────
1432
1445
 
1433
1446
  test('Integration branch: updates on branch change', () => {
@@ -117,8 +117,8 @@ test("projectRootToWorktree projects flat-phase discuss artifacts before dispatc
117
117
  new WorktreeStateProjection().projectRootToWorktree(scope);
118
118
 
119
119
  assert.ok(
120
- existsSync(join(worktree, ".gsd", "milestones", "M001", "M001-META.json")),
121
- "milestone metadata is projected into the worktree",
120
+ !existsSync(join(worktree, ".gsd", "milestones")),
121
+ "stale metadata-only legacy milestones/ scaffold is not projected into the worktree",
122
122
  );
123
123
  assert.ok(
124
124
  existsSync(join(worktree, ".gsd", "phases", "01-foundation", "01-CONTEXT.md")),
@@ -246,6 +246,66 @@ describe('worktree-sync-milestones', async () => {
246
246
  }
247
247
  }
248
248
 
249
+ // ─── 7b. flat-phase sync skips empty legacy milestones root ───────────
250
+ console.log('\n=== 7b. flat-phase sync skips empty legacy milestones root ===');
251
+ {
252
+ const mainBase = mkdtempSync(join(tmpdir(), 'gsd-wt-sync-flat-main-'));
253
+ const wtBase = mkdtempSync(join(tmpdir(), 'gsd-wt-sync-flat-wt-'));
254
+
255
+ try {
256
+ const phaseDir = join(mainBase, '.gsd', 'phases', '01-foundation');
257
+ mkdirSync(phaseDir, { recursive: true });
258
+ mkdirSync(join(mainBase, '.gsd', 'milestones'), { recursive: true });
259
+ mkdirSync(join(wtBase, '.gsd'), { recursive: true });
260
+ writeFileSync(join(phaseDir, '01-CONTEXT.md'), '# Foundation\n');
261
+
262
+ syncGsdStateToWorktree(mainBase, wtBase);
263
+
264
+ assert.ok(
265
+ existsSync(join(wtBase, '.gsd', 'phases', '01-foundation', '01-CONTEXT.md')),
266
+ 'flat-phase artifact is synced to worktree',
267
+ );
268
+ assert.ok(
269
+ !existsSync(join(wtBase, '.gsd', 'milestones')),
270
+ 'empty legacy milestones/ root is not recreated in worktree',
271
+ );
272
+ } finally {
273
+ rmSync(mainBase, { recursive: true, force: true });
274
+ rmSync(wtBase, { recursive: true, force: true });
275
+ }
276
+ }
277
+
278
+ // ─── 7c. flat-phase sync skips metadata-only legacy milestone dirs ────
279
+ console.log('\n=== 7c. flat-phase sync skips metadata-only legacy milestone dirs ===');
280
+ {
281
+ const mainBase = mkdtempSync(join(tmpdir(), 'gsd-wt-sync-flat-meta-main-'));
282
+ const wtBase = mkdtempSync(join(tmpdir(), 'gsd-wt-sync-flat-meta-wt-'));
283
+
284
+ try {
285
+ const phaseDir = join(mainBase, '.gsd', 'phases', '01-foundation');
286
+ const metaDir = join(mainBase, '.gsd', 'milestones', 'M001');
287
+ mkdirSync(phaseDir, { recursive: true });
288
+ mkdirSync(metaDir, { recursive: true });
289
+ mkdirSync(join(wtBase, '.gsd'), { recursive: true });
290
+ writeFileSync(join(phaseDir, '01-CONTEXT.md'), '# Foundation\n');
291
+ writeFileSync(join(metaDir, 'M001-META.json'), '{"integrationBranch":"main"}\n');
292
+
293
+ syncGsdStateToWorktree(mainBase, wtBase);
294
+
295
+ assert.ok(
296
+ existsSync(join(wtBase, '.gsd', 'phases', '01-foundation', '01-CONTEXT.md')),
297
+ 'flat-phase artifact is synced to worktree',
298
+ );
299
+ assert.ok(
300
+ !existsSync(join(wtBase, '.gsd', 'milestones')),
301
+ 'metadata-only legacy milestones/ scaffold is not recreated in worktree',
302
+ );
303
+ } finally {
304
+ rmSync(mainBase, { recursive: true, force: true });
305
+ rmSync(wtBase, { recursive: true, force: true });
306
+ }
307
+ }
308
+
249
309
  // ─── 8. syncWorktreeStateBack does not copy task projections ───────────
250
310
  console.log('\n=== 8. syncWorktreeStateBack leaves task projections in worktree ===');
251
311
  {
@@ -32,7 +32,7 @@ import {
32
32
  import { join } from "node:path";
33
33
 
34
34
  import { reconcileWorktreeDb } from "./gsd-db.js";
35
- import { resolveGsdPathContract } from "./paths.js";
35
+ import { dirIsContentBearingLegacyMilestone, resolveGsdPathContract } from "./paths.js";
36
36
  import { safeCopy, safeCopyRecursive } from "./safe-fs.js";
37
37
  import type { MilestoneScope } from "./workspace.js";
38
38
  import { logError, logWarning } from "./workflow-logger.js";
@@ -161,6 +161,7 @@ function syncOtherMilestoneArtifacts(
161
161
  // additive safeCopyRecursive; skip it here to avoid redundant work.
162
162
  if (milestoneEntry.name === currentMilestoneId) continue;
163
163
  const srcMilestoneDir = join(srcMilestonesDir, milestoneEntry.name);
164
+ if (!dirIsContentBearingLegacyMilestone(srcMilestoneDir)) continue;
164
165
  const dstMilestoneDir = join(dstMilestonesDir, milestoneEntry.name);
165
166
 
166
167
  // Additively project the entire milestone subtree (force:false), not just
@@ -271,36 +272,32 @@ export function _projectRootToWorktreeImpl(
271
272
  // Without this, worktree-local files (e.g. VALIDATION.md written
272
273
  // by validate-milestone) get clobbered by stale project root copies,
273
274
  // causing an infinite re-validation loop (#1886).
274
- safeCopyRecursive(
275
- join(prGsd, "milestones", milestoneId),
276
- join(wtGsd, "milestones", milestoneId),
277
- { force: false },
278
- );
275
+ const prMilestoneDir = join(prGsd, "milestones", milestoneId);
276
+ const wtMilestoneDir = join(wtGsd, "milestones", milestoneId);
277
+ if (dirIsContentBearingLegacyMilestone(prMilestoneDir)) {
278
+ safeCopyRecursive(prMilestoneDir, wtMilestoneDir, { force: false });
279
+
280
+ // Force-sync ASSESSMENT files that have a verdict from project root (#2821).
281
+ // The additive-only copy above preserves worktree-local files, but
282
+ // ASSESSMENT files are special: after run-uat writes a verdict and post-unit
283
+ // syncs it to the project root, the worktree may retain a stale copy (e.g.
284
+ // verdict:fail while the project root has verdict:pass from a retry). On
285
+ // session resume the DB is rebuilt from disk, and if the stale ASSESSMENT
286
+ // persists, checkNeedsRunUat finds no passing verdict → re-dispatches
287
+ // run-uat indefinitely (stuck-loop ×9).
288
+ forceOverwriteValidationWithVerdict(prMilestoneDir, wtMilestoneDir, milestoneId);
289
+ forceOverwriteAssessmentsWithVerdict(prMilestoneDir, wtMilestoneDir);
290
+ }
279
291
 
280
- // Additively project the full subtree of every OTHER milestone so
281
- // worktree-bound units can read prior-milestone context artifacts and so
282
- // completed milestones retain their per-slice/per-task SUMMARY.md and
283
- // UAT.md on the worktree filesystem (otherwise the stale-render detector
284
- // flags them as "complete in DB but missing on disk").
292
+ // Additively project the full subtree of every OTHER content-bearing legacy
293
+ // milestone so worktree-bound units can read prior-milestone context artifacts
294
+ // without recreating empty/meta-only milestones/ scaffolds in flat-phase projects.
285
295
  syncOtherMilestoneArtifacts(
286
296
  join(prGsd, "milestones"),
287
297
  join(wtGsd, "milestones"),
288
298
  milestoneId,
289
299
  );
290
300
 
291
- // Force-sync ASSESSMENT files that have a verdict from project root (#2821).
292
- // The additive-only copy above preserves worktree-local files, but
293
- // ASSESSMENT files are special: after run-uat writes a verdict and post-unit
294
- // syncs it to the project root, the worktree may retain a stale copy (e.g.
295
- // verdict:fail while the project root has verdict:pass from a retry). On
296
- // session resume the DB is rebuilt from disk, and if the stale ASSESSMENT
297
- // persists, checkNeedsRunUat finds no passing verdict → re-dispatches
298
- // run-uat indefinitely (stuck-loop ×9).
299
- const prMilestoneDir = join(prGsd, "milestones", milestoneId);
300
- const wtMilestoneDir = join(wtGsd, "milestones", milestoneId);
301
- forceOverwriteValidationWithVerdict(prMilestoneDir, wtMilestoneDir, milestoneId);
302
- forceOverwriteAssessmentsWithVerdict(prMilestoneDir, wtMilestoneDir);
303
-
304
301
  // Forward-sync completed-units.json from project root to worktree.
305
302
  // Project root is authoritative for completion state after crash recovery;
306
303
  // without this, the worktree re-dispatches already-completed units (#1886).
@@ -1 +0,0 @@
1
- (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[9492],{14040:(e,t,l)=>{(window.__NEXT_P=window.__NEXT_P||[]).push(["/_not-found/page",function(){return l(32910)}])},29999:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"styles",{enumerable:!0,get:function(){return l}});let l={error:{fontFamily:'system-ui,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji"',height:"100vh",textAlign:"center",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center"},desc:{display:"inline-block"},h1:{display:"inline-block",margin:"0 20px 0 0",padding:"0 23px 0 0",fontSize:24,fontWeight:500,verticalAlign:"top",lineHeight:"49px"},h2:{fontSize:14,fontWeight:400,lineHeight:"49px",margin:0}};("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},32910:(e,t,l)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"default",{enumerable:!0,get:function(){return o}});let r=l(18870),n=l(48664),o=function(){return(0,r.jsx)("html",{children:(0,r.jsx)("body",{children:(0,r.jsx)(n.HTTPAccessErrorFallback,{status:404,message:"This page could not be found."})})})};("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},48664:(e,t,l)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"HTTPAccessErrorFallback",{enumerable:!0,get:function(){return o}});let r=l(18870),n=l(29999);function o({status:e,message:t}){return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("title",{children:`${e}: ${t}`}),(0,r.jsx)("div",{style:n.styles.error,children:(0,r.jsxs)("div",{children:[(0,r.jsx)("style",{dangerouslySetInnerHTML:{__html:"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}),(0,r.jsx)("h1",{className:"next-error-h1",style:n.styles.h1,children:e}),(0,r.jsx)("div",{style:n.styles.desc,children:(0,r.jsx)("h2",{style:n.styles.h2,children:t})})]})})]})}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)}},e=>{e.O(0,[9990,686,7358],()=>e(e.s=14040)),_N_E=e.O()}]);
@@ -1 +0,0 @@
1
- (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[8974],{3267:(e,t,n)=>{Promise.resolve().then(n.bind(n,92703))},19013:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"workAsyncStorage",{enumerable:!0,get:function(){return r.workAsyncStorageInstance}});let r=n(34969)},23711:(e,t,n)=>{"use strict";n.d(t,{default:()=>u.a});var r=n(60276),u=n.n(r)},30039:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n={bindSnapshot:function(){return s},createAsyncLocalStorage:function(){return a},createSnapshot:function(){return i}};for(var r in n)Object.defineProperty(t,r,{enumerable:!0,get:n[r]});let u=Object.defineProperty(Error("Invariant: AsyncLocalStorage accessed in runtime where it is not available"),"__NEXT_ERROR_CODE",{value:"E504",enumerable:!1,configurable:!0});class l{disable(){throw u}getStore(){}run(){throw u}exit(){throw u}enterWith(){throw u}static bind(e){return e}}let o="u">typeof globalThis&&globalThis.AsyncLocalStorage;function a(){return o?new o:new l}function s(e){return o?o.bind(e):l.bind(e)}function i(){return o?o.snapshot():function(e,...t){return e(...t)}}},34969:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"workAsyncStorageInstance",{enumerable:!0,get:function(){return r}});let r=(0,n(30039).createAsyncLocalStorage)()},47811:(e,t,n)=>{"use strict";function r({reason:e,children:t}){return t}Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"BailoutToCSR",{enumerable:!0,get:function(){return r}}),n(71495)},60276:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"default",{enumerable:!0,get:function(){return u}});let r=n(51481)._(n(80260));function u(e,t){let n={};"function"==typeof e&&(n.loader=e);let u={...n,...t};return(0,r.default)({...u,modules:u.loadableGenerated?.modules})}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},76670:(e,t,n)=>{"use strict";function r({moduleIds:e}){return null}Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"PreloadChunks",{enumerable:!0,get:function(){return r}}),n(18870),n(29411),n(19013),n(19132),n(63632)},80260:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"default",{enumerable:!0,get:function(){return s}});let r=n(18870),u=n(45110),l=n(47811);function o(e){return{default:e&&"default"in e?e.default:e}}n(76670);let a={loader:()=>Promise.resolve(o(()=>null)),loading:null,ssr:!0},s=function(e){let t={...a,...e},n=(0,u.lazy)(()=>t.loader().then(o)),s=t.loading;function i(e){let o=s?(0,r.jsx)(s,{isLoading:!0,pastDelay:!0,error:null}):null,a=!t.ssr||!!t.loading,i=a?u.Suspense:u.Fragment,c=t.ssr?(0,r.jsxs)(r.Fragment,{children:[null,(0,r.jsx)(n,{...e})]}):(0,r.jsx)(l.BailoutToCSR,{reason:"next/dynamic",children:(0,r.jsx)(n,{...e})});return(0,r.jsx)(i,{...a?{fallback:o}:{},children:c})}return i.displayName="LoadableComponent",i}},92703:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>l});var r=n(18870);let u=(0,n(23711).default)(()=>Promise.all([n.e(4825),n.e(5395),n.e(7882),n.e(8937)]).then(n.bind(n,38937)).then(e=>e.GSDAppShell),{loadableGenerated:{webpack:()=>[38937]},ssr:!1,loading:()=>(0,r.jsx)("div",{className:"flex h-screen items-center justify-center bg-background text-sm text-muted-foreground",children:"Loading workspace…"})});function l(){return(0,r.jsx)(u,{})}}},e=>{e.O(0,[9990,686,7358],()=>e(e.s=3267)),_N_E=e.O()}]);
@@ -1 +0,0 @@
1
- (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[9337],{16951:(e,s,_)=>{Promise.resolve().then(_.t.bind(_,45336,23))}},e=>{e.O(0,[9990,686,7358],()=>e(e.s=16951)),_N_E=e.O()}]);