@opengsd/gsd-pi 1.7.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.
Files changed (465) hide show
  1. package/README.md +8 -6
  2. package/dist/cli.js +5 -1
  3. package/dist/headless-events.d.ts +2 -1
  4. package/dist/headless-events.js +11 -3
  5. package/dist/headless-milestone-readiness.d.ts +29 -0
  6. package/dist/headless-milestone-readiness.js +161 -0
  7. package/dist/headless.js +25 -2
  8. package/dist/print-mode-exit.d.ts +12 -0
  9. package/dist/print-mode-exit.js +14 -0
  10. package/dist/resources/.managed-resources-content-hash +1 -1
  11. package/dist/resources/GSD-WORKFLOW.md +16 -47
  12. package/dist/resources/extensions/browser-tools/capture.js +2 -77
  13. package/dist/resources/extensions/browser-tools/screenshot-constraints.js +83 -0
  14. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +17 -2
  15. package/dist/resources/extensions/claude-code-cli/turn-assembler.js +30 -2
  16. package/dist/resources/extensions/gsd/auto-artifact-paths.js +2 -2
  17. package/dist/resources/extensions/gsd/auto-dispatch.js +74 -19
  18. package/dist/resources/extensions/gsd/auto-post-unit.js +4 -0
  19. package/dist/resources/extensions/gsd/auto-prompts.js +35 -1
  20. package/dist/resources/extensions/gsd/auto.js +5 -1
  21. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +78 -4
  22. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +84 -26
  23. package/dist/resources/extensions/gsd/command-feedback.js +16 -12
  24. package/dist/resources/extensions/gsd/compat/compat-marker.js +19 -2
  25. package/dist/resources/extensions/gsd/db/command-queue.js +7 -2
  26. package/dist/resources/extensions/gsd/db/engine.js +51 -16
  27. package/dist/resources/extensions/gsd/db/writers/cascades.js +5 -1
  28. package/dist/resources/extensions/gsd/db/writers/status.js +13 -3
  29. package/dist/resources/extensions/gsd/db-base-schema.js +28 -0
  30. package/dist/resources/extensions/gsd/db-migration-steps.js +30 -0
  31. package/dist/resources/extensions/gsd/db-schema-metadata.js +4 -1
  32. package/dist/resources/extensions/gsd/docs/preferences-reference.md +4 -4
  33. package/dist/resources/extensions/gsd/doctor-history.js +65 -0
  34. package/dist/resources/extensions/gsd/doctor-state-checks.js +509 -0
  35. package/dist/resources/extensions/gsd/doctor-workspace-checks.js +91 -0
  36. package/dist/resources/extensions/gsd/doctor.js +14 -653
  37. package/dist/resources/extensions/gsd/flat-phase-migration.js +156 -21
  38. package/dist/resources/extensions/gsd/gsd-db.js +187 -45
  39. package/dist/resources/extensions/gsd/guided-flow.js +29 -10
  40. package/dist/resources/extensions/gsd/markdown-renderer.js +16 -2
  41. package/dist/resources/extensions/gsd/md-importer.js +109 -16
  42. package/dist/resources/extensions/gsd/migrate/command.js +19 -162
  43. package/dist/resources/extensions/gsd/migrate/execution.js +98 -0
  44. package/dist/resources/extensions/gsd/migrate/plan.js +49 -0
  45. package/dist/resources/extensions/gsd/migrate/planning-writer.js +20 -19
  46. package/dist/resources/extensions/gsd/migrate/presentation.js +64 -0
  47. package/dist/resources/extensions/gsd/migration-auto-check.js +4 -0
  48. package/dist/resources/extensions/gsd/parallel-eligibility.js +5 -4
  49. package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +28 -43
  50. package/dist/resources/extensions/gsd/paths.js +4 -1
  51. package/dist/resources/extensions/gsd/phase-anchor.js +7 -2
  52. package/dist/resources/extensions/gsd/post-execution-checks.js +4 -4
  53. package/dist/resources/extensions/gsd/prompts/refine-slice.md +2 -2
  54. package/dist/resources/extensions/gsd/safety/evidence-collector.js +26 -1
  55. package/dist/resources/extensions/gsd/safety/evidence-cross-ref.js +30 -5
  56. package/dist/resources/extensions/gsd/state-reconciliation/drift/external-markdown-edit.js +27 -13
  57. package/dist/resources/extensions/gsd/state-reconciliation/drift/external-planning-edit.js +13 -3
  58. package/dist/resources/extensions/gsd/state-reconciliation/drift/project-md.js +54 -14
  59. package/dist/resources/extensions/gsd/state-reconciliation/drift/sketch-flag.js +48 -5
  60. package/dist/resources/extensions/gsd/stop-notice.js +15 -1
  61. package/dist/resources/extensions/gsd/sync-lock.js +13 -7
  62. package/dist/resources/extensions/gsd/tools/complete-task.js +82 -1
  63. package/dist/resources/extensions/gsd/tools/plan-task.js +13 -15
  64. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +18 -15
  65. package/dist/resources/extensions/gsd/tools/replan-task.js +128 -0
  66. package/dist/resources/extensions/gsd/tools/rework-brief.js +74 -0
  67. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +81 -0
  68. package/dist/resources/extensions/gsd/unit-registry.js +4 -0
  69. package/dist/resources/extensions/gsd/uok/plan-v2.js +19 -3
  70. package/dist/resources/extensions/gsd/worktree-state-projection.js +6 -0
  71. package/dist/resources/extensions/mac-tools/index.js +31 -9
  72. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  73. package/dist/web/standalone/.next/BUILD_ID +1 -1
  74. package/dist/web/standalone/.next/app-path-routes-manifest.json +9 -9
  75. package/dist/web/standalone/.next/build-manifest.json +3 -3
  76. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  77. package/dist/web/standalone/.next/required-server-files.json +3 -3
  78. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  79. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  80. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  81. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  82. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  83. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  84. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  85. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  86. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  87. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  88. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  89. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  90. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  91. package/dist/web/standalone/.next/server/app/_not-found.rsc +4 -4
  92. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -4
  93. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  94. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +4 -4
  95. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  96. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  97. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  98. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  99. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  100. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  101. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  102. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  103. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  104. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  105. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  106. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  107. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  108. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  109. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  110. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  111. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  112. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  113. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  114. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  115. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  116. package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
  117. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  118. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  119. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  120. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  121. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  122. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  123. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  124. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  125. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  126. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  127. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  128. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  129. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  130. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  131. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  132. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  133. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  134. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  135. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  136. package/dist/web/standalone/.next/server/app/api/mcp-connections/route.js +1 -1
  137. package/dist/web/standalone/.next/server/app/api/mcp-connections/route_client-reference-manifest.js +1 -1
  138. package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
  139. package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  141. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  143. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
  149. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  155. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  171. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  175. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  183. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  184. package/dist/web/standalone/.next/server/app/index.html +1 -1
  185. package/dist/web/standalone/.next/server/app/index.rsc +5 -5
  186. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  187. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +5 -5
  188. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  189. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +4 -4
  190. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  191. package/dist/web/standalone/.next/server/app/page.js +2 -2
  192. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  193. package/dist/web/standalone/.next/server/app-paths-manifest.json +9 -9
  194. package/dist/web/standalone/.next/server/chunks/2842.js +4 -4
  195. package/dist/web/standalone/.next/server/chunks/8357.js +3 -3
  196. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  197. package/dist/web/standalone/.next/server/middleware.js +3 -3
  198. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  199. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  200. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  201. package/dist/web/standalone/.next/static/chunks/app/_not-found/page-a6fb1847f67f167c.js +1 -0
  202. package/dist/web/standalone/.next/static/chunks/app/{layout-b35cbfff38aaf4cf.js → layout-4ae2d68984392bbf.js} +1 -1
  203. package/dist/web/standalone/.next/static/chunks/app/page-72a856634ad14c10.js +1 -0
  204. package/dist/web/standalone/.next/static/chunks/{main-app-590a74400e35f685.js → main-app-90d1d8d5e5d2dc6b.js} +1 -1
  205. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-1115d46ac61b9823.js +1 -0
  206. package/dist/web/standalone/.next/static/css/3b1ceb7abfb9a230.css +1 -0
  207. package/dist/web/standalone/node_modules/@gsd/native/package.json +1 -1
  208. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  209. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  210. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  211. package/dist/web/standalone/package.json +0 -1
  212. package/dist/web/standalone/server.js +1 -1
  213. package/dist/web-mode.js +31 -3
  214. package/integrations/hermes/open_gsd_hermes/gsd_client.py +1 -1
  215. package/integrations/hermes/pyproject.toml +1 -1
  216. package/package.json +12 -10
  217. package/packages/cloud-mcp-gateway/package.json +2 -2
  218. package/packages/contracts/dist/workflow.d.ts +14 -0
  219. package/packages/contracts/dist/workflow.d.ts.map +1 -1
  220. package/packages/contracts/dist/workflow.js +16 -0
  221. package/packages/contracts/dist/workflow.js.map +1 -1
  222. package/packages/contracts/package.json +1 -1
  223. package/packages/daemon/dist/cloud-config.d.ts +1 -1
  224. package/packages/daemon/dist/cloud-config.d.ts.map +1 -1
  225. package/packages/daemon/dist/cloud-config.js +30 -8
  226. package/packages/daemon/dist/cloud-config.js.map +1 -1
  227. package/packages/daemon/dist/cloud-config.test.js +69 -1
  228. package/packages/daemon/dist/cloud-config.test.js.map +1 -1
  229. package/packages/daemon/dist/local-tool-executor.d.ts.map +1 -1
  230. package/packages/daemon/dist/local-tool-executor.js +2 -0
  231. package/packages/daemon/dist/local-tool-executor.js.map +1 -1
  232. package/packages/daemon/package.json +6 -6
  233. package/packages/gsd-agent-core/package.json +5 -5
  234. package/packages/gsd-agent-modes/package.json +7 -7
  235. package/packages/gsd-cloud/README.md +18 -4
  236. package/packages/gsd-cloud/bin/gsd-cloud.js +6 -5
  237. package/packages/gsd-cloud/dist/cli.d.ts +5 -0
  238. package/packages/gsd-cloud/dist/cli.d.ts.map +1 -0
  239. package/packages/gsd-cloud/dist/cli.js +160 -0
  240. package/packages/gsd-cloud/dist/cli.js.map +1 -0
  241. package/packages/gsd-cloud/dist/cloud-config.d.ts +19 -0
  242. package/packages/gsd-cloud/dist/cloud-config.d.ts.map +1 -0
  243. package/packages/gsd-cloud/dist/cloud-config.js +231 -0
  244. package/packages/gsd-cloud/dist/cloud-config.js.map +1 -0
  245. package/packages/gsd-cloud/dist/cloud-config.test.d.ts +2 -0
  246. package/packages/gsd-cloud/dist/cloud-config.test.d.ts.map +1 -0
  247. package/packages/gsd-cloud/dist/cloud-config.test.js +118 -0
  248. package/packages/gsd-cloud/dist/cloud-config.test.js.map +1 -0
  249. package/packages/gsd-cloud/dist/cloud-gateway-lookup.test.d.ts +2 -0
  250. package/packages/gsd-cloud/dist/cloud-gateway-lookup.test.d.ts.map +1 -0
  251. package/packages/gsd-cloud/dist/cloud-gateway-lookup.test.js +37 -0
  252. package/packages/gsd-cloud/dist/cloud-gateway-lookup.test.js.map +1 -0
  253. package/packages/gsd-cloud/dist/cloud-runtime.d.ts +35 -0
  254. package/packages/gsd-cloud/dist/cloud-runtime.d.ts.map +1 -0
  255. package/packages/gsd-cloud/dist/cloud-runtime.js +258 -0
  256. package/packages/gsd-cloud/dist/cloud-runtime.js.map +1 -0
  257. package/packages/gsd-cloud/dist/cloud-runtime.test.d.ts +2 -0
  258. package/packages/gsd-cloud/dist/cloud-runtime.test.d.ts.map +1 -0
  259. package/packages/gsd-cloud/dist/cloud-runtime.test.js +88 -0
  260. package/packages/gsd-cloud/dist/cloud-runtime.test.js.map +1 -0
  261. package/packages/gsd-cloud/dist/cloud-token.d.ts +3 -0
  262. package/packages/gsd-cloud/dist/cloud-token.d.ts.map +1 -0
  263. package/packages/gsd-cloud/dist/cloud-token.js +37 -0
  264. package/packages/gsd-cloud/dist/cloud-token.js.map +1 -0
  265. package/packages/gsd-cloud/dist/config.d.ts +17 -0
  266. package/packages/gsd-cloud/dist/config.d.ts.map +1 -0
  267. package/packages/gsd-cloud/dist/config.js +146 -0
  268. package/packages/gsd-cloud/dist/config.js.map +1 -0
  269. package/packages/gsd-cloud/dist/device-flow.d.ts +24 -0
  270. package/packages/gsd-cloud/dist/device-flow.d.ts.map +1 -0
  271. package/packages/gsd-cloud/dist/device-flow.js +128 -0
  272. package/packages/gsd-cloud/dist/device-flow.js.map +1 -0
  273. package/packages/gsd-cloud/dist/device-flow.test.d.ts +2 -0
  274. package/packages/gsd-cloud/dist/device-flow.test.d.ts.map +1 -0
  275. package/packages/gsd-cloud/dist/device-flow.test.js +155 -0
  276. package/packages/gsd-cloud/dist/device-flow.test.js.map +1 -0
  277. package/packages/gsd-cloud/dist/executors/claude-executor.d.ts +6 -0
  278. package/packages/gsd-cloud/dist/executors/claude-executor.d.ts.map +1 -0
  279. package/packages/gsd-cloud/dist/executors/claude-executor.js +15 -0
  280. package/packages/gsd-cloud/dist/executors/claude-executor.js.map +1 -0
  281. package/packages/gsd-cloud/dist/executors/codex-executor.d.ts +6 -0
  282. package/packages/gsd-cloud/dist/executors/codex-executor.d.ts.map +1 -0
  283. package/packages/gsd-cloud/dist/executors/codex-executor.js +15 -0
  284. package/packages/gsd-cloud/dist/executors/codex-executor.js.map +1 -0
  285. package/packages/gsd-cloud/dist/executors/executor.d.ts +28 -0
  286. package/packages/gsd-cloud/dist/executors/executor.d.ts.map +1 -0
  287. package/packages/gsd-cloud/dist/executors/executor.js +11 -0
  288. package/packages/gsd-cloud/dist/executors/executor.js.map +1 -0
  289. package/packages/gsd-cloud/dist/executors/gsd-pi-executor.d.ts +34 -0
  290. package/packages/gsd-cloud/dist/executors/gsd-pi-executor.d.ts.map +1 -0
  291. package/packages/gsd-cloud/dist/executors/gsd-pi-executor.js +179 -0
  292. package/packages/gsd-cloud/dist/executors/gsd-pi-executor.js.map +1 -0
  293. package/packages/gsd-cloud/dist/executors/gsd-pi-executor.test.d.ts +2 -0
  294. package/packages/gsd-cloud/dist/executors/gsd-pi-executor.test.d.ts.map +1 -0
  295. package/packages/gsd-cloud/dist/executors/gsd-pi-executor.test.js +44 -0
  296. package/packages/gsd-cloud/dist/executors/gsd-pi-executor.test.js.map +1 -0
  297. package/packages/gsd-cloud/dist/executors/index.d.ts +17 -0
  298. package/packages/gsd-cloud/dist/executors/index.d.ts.map +1 -0
  299. package/packages/gsd-cloud/dist/executors/index.js +29 -0
  300. package/packages/gsd-cloud/dist/executors/index.js.map +1 -0
  301. package/packages/gsd-cloud/dist/executors/mcp-stdio-client.d.ts +36 -0
  302. package/packages/gsd-cloud/dist/executors/mcp-stdio-client.d.ts.map +1 -0
  303. package/packages/gsd-cloud/dist/executors/mcp-stdio-client.js +176 -0
  304. package/packages/gsd-cloud/dist/executors/mcp-stdio-client.js.map +1 -0
  305. package/packages/gsd-cloud/dist/executors/mcp-stdio-client.test.d.ts +2 -0
  306. package/packages/gsd-cloud/dist/executors/mcp-stdio-client.test.d.ts.map +1 -0
  307. package/packages/gsd-cloud/dist/executors/mcp-stdio-client.test.js +34 -0
  308. package/packages/gsd-cloud/dist/executors/mcp-stdio-client.test.js.map +1 -0
  309. package/packages/gsd-cloud/dist/index.d.ts +7 -0
  310. package/packages/gsd-cloud/dist/index.d.ts.map +1 -0
  311. package/packages/gsd-cloud/dist/index.js +8 -0
  312. package/packages/gsd-cloud/dist/index.js.map +1 -0
  313. package/packages/gsd-cloud/dist/inject-gateway.d.ts +16 -0
  314. package/packages/gsd-cloud/dist/inject-gateway.d.ts.map +1 -0
  315. package/packages/gsd-cloud/dist/inject-gateway.js +29 -0
  316. package/packages/gsd-cloud/dist/inject-gateway.js.map +1 -0
  317. package/packages/gsd-cloud/dist/inject-gateway.test.d.ts +2 -0
  318. package/packages/gsd-cloud/dist/inject-gateway.test.d.ts.map +1 -0
  319. package/packages/gsd-cloud/dist/inject-gateway.test.js +41 -0
  320. package/packages/gsd-cloud/dist/inject-gateway.test.js.map +1 -0
  321. package/packages/gsd-cloud/dist/logger.d.ts +25 -0
  322. package/packages/gsd-cloud/dist/logger.d.ts.map +1 -0
  323. package/packages/gsd-cloud/dist/logger.js +72 -0
  324. package/packages/gsd-cloud/dist/logger.js.map +1 -0
  325. package/packages/gsd-cloud/dist/types.d.ts +51 -0
  326. package/packages/gsd-cloud/dist/types.d.ts.map +1 -0
  327. package/packages/gsd-cloud/dist/types.js +9 -0
  328. package/packages/gsd-cloud/dist/types.js.map +1 -0
  329. package/packages/gsd-cloud/package.json +7 -5
  330. package/packages/mcp-server/README.md +8 -0
  331. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  332. package/packages/mcp-server/dist/workflow-tools.js +64 -2
  333. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  334. package/packages/mcp-server/package.json +4 -4
  335. package/packages/native/package.json +1 -1
  336. package/packages/pi-agent-core/package.json +1 -1
  337. package/packages/pi-ai/dist/models.generated.d.ts +60 -0
  338. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  339. package/packages/pi-ai/dist/models.generated.js +54 -0
  340. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  341. package/packages/pi-ai/dist/providers/amazon-bedrock.js +1 -0
  342. package/packages/pi-ai/dist/providers/amazon-bedrock.js.map +1 -1
  343. package/packages/pi-ai/dist/providers/anthropic.js +19 -0
  344. package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
  345. package/packages/pi-ai/package.json +1 -1
  346. package/packages/pi-coding-agent/package.json +7 -7
  347. package/packages/pi-tui/package.json +2 -2
  348. package/packages/rpc-client/package.json +2 -2
  349. package/pkg/package.json +1 -1
  350. package/src/resources/GSD-WORKFLOW.md +16 -47
  351. package/src/resources/extensions/browser-tools/capture.ts +2 -86
  352. package/src/resources/extensions/browser-tools/screenshot-constraints.ts +94 -0
  353. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +18 -1
  354. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +108 -0
  355. package/src/resources/extensions/claude-code-cli/turn-assembler.ts +30 -2
  356. package/src/resources/extensions/gsd/auto-artifact-paths.ts +2 -2
  357. package/src/resources/extensions/gsd/auto-dispatch.ts +86 -19
  358. package/src/resources/extensions/gsd/auto-post-unit.ts +4 -0
  359. package/src/resources/extensions/gsd/auto-prompts.ts +38 -1
  360. package/src/resources/extensions/gsd/auto.ts +5 -1
  361. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +91 -4
  362. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +80 -24
  363. package/src/resources/extensions/gsd/command-feedback.ts +19 -12
  364. package/src/resources/extensions/gsd/compat/compat-marker.ts +21 -4
  365. package/src/resources/extensions/gsd/db/command-queue.ts +7 -1
  366. package/src/resources/extensions/gsd/db/engine.ts +53 -17
  367. package/src/resources/extensions/gsd/db/writers/cascades.ts +5 -1
  368. package/src/resources/extensions/gsd/db/writers/status.ts +25 -8
  369. package/src/resources/extensions/gsd/db-base-schema.ts +30 -0
  370. package/src/resources/extensions/gsd/db-migration-steps.ts +32 -0
  371. package/src/resources/extensions/gsd/db-schema-metadata.ts +4 -1
  372. package/src/resources/extensions/gsd/docs/preferences-reference.md +4 -4
  373. package/src/resources/extensions/gsd/doctor-history.ts +81 -0
  374. package/src/resources/extensions/gsd/doctor-state-checks.ts +527 -0
  375. package/src/resources/extensions/gsd/doctor-workspace-checks.ts +97 -0
  376. package/src/resources/extensions/gsd/doctor.ts +14 -673
  377. package/src/resources/extensions/gsd/flat-phase-migration.ts +160 -19
  378. package/src/resources/extensions/gsd/gsd-db.ts +255 -52
  379. package/src/resources/extensions/gsd/guided-flow.ts +39 -10
  380. package/src/resources/extensions/gsd/markdown-renderer.ts +23 -7
  381. package/src/resources/extensions/gsd/md-importer.ts +116 -13
  382. package/src/resources/extensions/gsd/migrate/command.ts +21 -227
  383. package/src/resources/extensions/gsd/migrate/execution.ts +136 -0
  384. package/src/resources/extensions/gsd/migrate/plan.ts +101 -0
  385. package/src/resources/extensions/gsd/migrate/planning-writer.ts +21 -23
  386. package/src/resources/extensions/gsd/migrate/presentation.ts +83 -0
  387. package/src/resources/extensions/gsd/migration-auto-check.ts +3 -0
  388. package/src/resources/extensions/gsd/parallel-eligibility.ts +5 -4
  389. package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +37 -40
  390. package/src/resources/extensions/gsd/paths.ts +4 -1
  391. package/src/resources/extensions/gsd/phase-anchor.ts +8 -2
  392. package/src/resources/extensions/gsd/post-execution-checks.ts +4 -4
  393. package/src/resources/extensions/gsd/prompts/refine-slice.md +2 -2
  394. package/src/resources/extensions/gsd/safety/evidence-collector.ts +28 -1
  395. package/src/resources/extensions/gsd/safety/evidence-cross-ref.ts +31 -5
  396. package/src/resources/extensions/gsd/state-reconciliation/drift/external-markdown-edit.ts +30 -13
  397. package/src/resources/extensions/gsd/state-reconciliation/drift/external-planning-edit.ts +16 -3
  398. package/src/resources/extensions/gsd/state-reconciliation/drift/project-md.ts +67 -20
  399. package/src/resources/extensions/gsd/state-reconciliation/drift/sketch-flag.ts +47 -5
  400. package/src/resources/extensions/gsd/state-reconciliation/types.ts +2 -2
  401. package/src/resources/extensions/gsd/stop-notice.ts +18 -1
  402. package/src/resources/extensions/gsd/sync-lock.ts +14 -6
  403. package/src/resources/extensions/gsd/tests/closeout-git-deferral.test.ts +96 -1
  404. package/src/resources/extensions/gsd/tests/command-feedback.test.ts +12 -0
  405. package/src/resources/extensions/gsd/tests/compat-marker.test.ts +104 -0
  406. package/src/resources/extensions/gsd/tests/complete-task.test.ts +286 -0
  407. package/src/resources/extensions/gsd/tests/db-authority-regression.test.ts +76 -1
  408. package/src/resources/extensions/gsd/tests/db-engine-migrate-guards.test.ts +186 -0
  409. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +29 -0
  410. package/src/resources/extensions/gsd/tests/discuss-routing-fixes.test.ts +123 -0
  411. package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +50 -0
  412. package/src/resources/extensions/gsd/tests/dispatch-rule-coverage.test.ts +49 -0
  413. package/src/resources/extensions/gsd/tests/doctor-history-public-api.test.ts +25 -0
  414. package/src/resources/extensions/gsd/tests/evidence-cross-ref.test.ts +81 -0
  415. package/src/resources/extensions/gsd/tests/evidence-xref-gsd-exec.test.ts +22 -0
  416. package/src/resources/extensions/gsd/tests/external-edit-scoped-import.test.ts +262 -0
  417. package/src/resources/extensions/gsd/tests/flat-phase-migration.test.ts +202 -0
  418. package/src/resources/extensions/gsd/tests/gate-storage.test.ts +29 -0
  419. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +25 -0
  420. package/src/resources/extensions/gsd/tests/import-slice-milestone-completion-preserve.test.ts +116 -0
  421. package/src/resources/extensions/gsd/tests/migrate-hierarchy.test.ts +53 -0
  422. package/src/resources/extensions/gsd/tests/migrate-plan.test.ts +68 -0
  423. package/src/resources/extensions/gsd/tests/migrate-presentation.test.ts +98 -0
  424. package/src/resources/extensions/gsd/tests/migrate-safety-audit.test.ts +1 -1
  425. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +53 -0
  426. package/src/resources/extensions/gsd/tests/milestone-leases.test.ts +55 -0
  427. package/src/resources/extensions/gsd/tests/parallel-eligibility-file-overlap.test.ts +146 -0
  428. package/src/resources/extensions/gsd/tests/parallel-monitor-overlay.test.ts +59 -0
  429. package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +4 -0
  430. package/src/resources/extensions/gsd/tests/phase-anchor.test.ts +32 -4
  431. package/src/resources/extensions/gsd/tests/plan-task.test.ts +26 -23
  432. package/src/resources/extensions/gsd/tests/planning-writer.test.ts +47 -1
  433. package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +22 -0
  434. package/src/resources/extensions/gsd/tests/progressive-planning.test.ts +18 -3
  435. package/src/resources/extensions/gsd/tests/reassess-handler.test.ts +50 -0
  436. package/src/resources/extensions/gsd/tests/replan-task-handler.test.ts +103 -0
  437. package/src/resources/extensions/gsd/tests/rework-brief.test.ts +197 -0
  438. package/src/resources/extensions/gsd/tests/skip-slice-cascades-tasks.test.ts +21 -0
  439. package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +177 -25
  440. package/src/resources/extensions/gsd/tests/stop-notice.test.ts +17 -0
  441. package/src/resources/extensions/gsd/tests/sync-lock.test.ts +19 -0
  442. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +34 -0
  443. package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +93 -1
  444. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +2 -0
  445. package/src/resources/extensions/gsd/tests/workflow-migration-gates.test.ts +139 -0
  446. package/src/resources/extensions/gsd/tests/worktree-state-projection.test.ts +36 -0
  447. package/src/resources/extensions/gsd/tests/write-gate-seam.test.ts +52 -0
  448. package/src/resources/extensions/gsd/tools/complete-task.ts +120 -0
  449. package/src/resources/extensions/gsd/tools/plan-task.ts +14 -16
  450. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +18 -17
  451. package/src/resources/extensions/gsd/tools/replan-task.ts +160 -0
  452. package/src/resources/extensions/gsd/tools/rework-brief.ts +91 -0
  453. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +92 -0
  454. package/src/resources/extensions/gsd/types.ts +11 -0
  455. package/src/resources/extensions/gsd/unit-registry.ts +4 -0
  456. package/src/resources/extensions/gsd/uok/plan-v2.ts +20 -3
  457. package/src/resources/extensions/gsd/worktree-state-projection.ts +12 -0
  458. package/src/resources/extensions/mac-tools/index.ts +52 -9
  459. package/src/resources/extensions/mac-tools/tests/mac-screenshot-payload.test.cjs +70 -0
  460. package/dist/web/standalone/.next/static/chunks/app/_not-found/page-49f565245e1e4afe.js +0 -1
  461. package/dist/web/standalone/.next/static/chunks/app/page-bc4c723c6a19c6f0.js +0 -1
  462. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ec3eaffc9785ba48.js +0 -1
  463. package/dist/web/standalone/.next/static/css/18c2fdf261bfc1b7.css +0 -1
  464. /package/dist/web/standalone/.next/static/{enWQFRY-aLTUq3wmxG2Qz → TezjdjSHBVRRr54XjAvte}/_buildManifest.js +0 -0
  465. /package/dist/web/standalone/.next/static/{enWQFRY-aLTUq3wmxG2Qz → TezjdjSHBVRRr54XjAvte}/_ssgManifest.js +0 -0
@@ -108,6 +108,65 @@ describe("parallel-monitor-overlay", () => {
108
108
  }
109
109
  });
110
110
 
111
+ it("merged worker query renders slice progress and completions across multiple slices", async () => {
112
+ // Regression guard for the single-open merge: queryWorkerProgress now
113
+ // returns { slices, completions } from ONE connection per worker per tick.
114
+ // A worker spanning two slices, each with a completed task, must still
115
+ // surface every slice's progress AND both completions (previously two
116
+ // separate DB opens produced these).
117
+ const base = mkdtempSync(join(tmpdir(), "gsd-parallel-overlay-multi-"));
118
+
119
+ try {
120
+ mkdirSync(join(base, ".gsd", "parallel"), { recursive: true });
121
+ assert.equal(openDatabase(join(base, ".gsd", "gsd.db")), true);
122
+ insertMilestone({ id: "M001", title: "Multi-slice Fixture" });
123
+ insertSlice({ milestoneId: "M001", id: "S01", title: "First", status: "pending", sequence: 1 });
124
+ insertSlice({ milestoneId: "M001", id: "S02", title: "Second", status: "pending", sequence: 2 });
125
+ insertTask({ milestoneId: "M001", sliceId: "S01", id: "T01", status: "complete", oneLiner: "alpha done", sequence: 1 });
126
+ insertTask({ milestoneId: "M001", sliceId: "S01", id: "T02", status: "pending", sequence: 2 });
127
+ insertTask({ milestoneId: "M001", sliceId: "S02", id: "T01", status: "complete", oneLiner: "beta done", sequence: 1 });
128
+ insertTask({ milestoneId: "M001", sliceId: "S02", id: "T02", status: "pending", sequence: 2 });
129
+ closeDatabase();
130
+
131
+ writeFileSync(
132
+ join(base, ".gsd", "parallel", "M001.status.json"),
133
+ JSON.stringify({
134
+ milestoneId: "M001",
135
+ pid: process.pid,
136
+ state: "running",
137
+ cost: 0,
138
+ lastHeartbeat: Date.now(),
139
+ startedAt: Date.now() - 30_000,
140
+ worktreePath: join(base, ".gsd-worktrees", "M001"),
141
+ }),
142
+ "utf-8",
143
+ );
144
+
145
+ const mod = await import("../parallel-monitor-overlay.js");
146
+ const mockTui = { requestRender: () => {} };
147
+ const mockTheme = {
148
+ fg: (_color: string, text: string) => text,
149
+ bold: (text: string) => text,
150
+ };
151
+ const overlay = new mod.ParallelMonitorOverlay(mockTui, mockTheme as any, () => {}, base);
152
+
153
+ try {
154
+ const joined = overlay.render(120).join("\n");
155
+ // Both slices' progress must come from the single merged query.
156
+ assert.match(joined, /S01:1\/2/, "S01 progress should render from the merged query");
157
+ assert.match(joined, /S02:1\/2/, "S02 progress should render from the merged query");
158
+ // Completions for tasks in both slices ride along on the same DB open.
159
+ assert.match(joined, /S01\/T01: alpha done/, "S01 completion should render");
160
+ assert.match(joined, /S02\/T01: beta done/, "S02 completion should render");
161
+ } finally {
162
+ overlay.dispose();
163
+ }
164
+ } finally {
165
+ try { closeDatabase(); } catch { /* already closed */ }
166
+ rmSync(base, { recursive: true, force: true });
167
+ }
168
+ });
169
+
111
170
  it("progressBar generates correct width", async () => {
112
171
  // Dynamic import to test the module loads cleanly
113
172
  const mod = await import("../parallel-monitor-overlay.js");
@@ -47,6 +47,9 @@ const ALLOWED_IMPORTERS = new Set([
47
47
  "gsd/migration-auto-check.ts",
48
48
  // drift detection: compares markdown projection against DB by design
49
49
  "gsd/state-reconciliation/drift/roadmap.ts",
50
+ // drift detection: reads PLAN.md tasks to distinguish a real plan from a
51
+ // stub before clearing a stale is_sketch flag (#1287)
52
+ "gsd/state-reconciliation/drift/sketch-flag.ts",
50
53
  // stale-render detection + render verification helpers over rendered output
51
54
  "gsd/markdown-renderer.ts",
52
55
  // pre-migration fallback: deriveState must work before the DB exists
@@ -58,6 +61,7 @@ const ALLOWED_IMPORTERS = new Set([
58
61
  "gsd/artifact-verification.ts",
59
62
  // diagnostics-only surfaces: report on projections, make no dispatch decisions
60
63
  "gsd/doctor.ts",
64
+ "gsd/doctor-state-checks.ts",
61
65
  // diagnostics-only: compares PLAN.md task checkboxes against DB status
62
66
  "gsd/doctor-engine-checks.ts",
63
67
  // display/telemetry-only surfaces
@@ -1,6 +1,6 @@
1
1
  import test from "node:test";
2
2
  import assert from "node:assert/strict";
3
- import { mkdtempSync, mkdirSync, rmSync, existsSync } from "node:fs";
3
+ import { mkdtempSync, mkdirSync, rmSync, existsSync, writeFileSync } from "node:fs";
4
4
  import { join } from "node:path";
5
5
  import { tmpdir } from "node:os";
6
6
 
@@ -9,11 +9,11 @@ import type { PhaseAnchor } from "../phase-anchor.js";
9
9
 
10
10
  function makeTempBase(): string {
11
11
  const tmp = mkdtempSync(join(tmpdir(), "gsd-anchor-test-"));
12
- mkdirSync(join(tmp, ".gsd", "milestones", "M001", "anchors"), { recursive: true });
12
+ mkdirSync(join(tmp, ".gsd"), { recursive: true });
13
13
  return tmp;
14
14
  }
15
15
 
16
- test("writePhaseAnchor creates anchor file in correct location", () => {
16
+ test("writePhaseAnchor creates anchor file under runtime state", () => {
17
17
  const base = makeTempBase();
18
18
  try {
19
19
  const anchor: PhaseAnchor = {
@@ -26,7 +26,35 @@ test("writePhaseAnchor creates anchor file in correct location", () => {
26
26
  nextSteps: ["Plan the implementation slices"],
27
27
  };
28
28
  writePhaseAnchor(base, "M001", anchor);
29
- assert.ok(existsSync(join(base, ".gsd", "milestones", "M001", "anchors", "discuss.json")));
29
+ assert.ok(existsSync(join(base, ".gsd", "runtime", "anchors", "M001", "discuss.json")));
30
+ assert.equal(existsSync(join(base, ".gsd", "milestones", "M001", "anchors", "discuss.json")), false);
31
+ } finally {
32
+ rmSync(base, { recursive: true, force: true });
33
+ }
34
+ });
35
+
36
+ test("readPhaseAnchor falls back to legacy anchor location", () => {
37
+ const base = makeTempBase();
38
+ try {
39
+ const legacyDir = join(base, ".gsd", "milestones", "M001", "anchors");
40
+ mkdirSync(legacyDir, { recursive: true });
41
+ writeFileSync(
42
+ join(legacyDir, "research-slice.json"),
43
+ JSON.stringify({
44
+ phase: "research-slice",
45
+ milestoneId: "M001",
46
+ generatedAt: "2026-07-07T00:00:00.000Z",
47
+ intent: "Keep reading old anchors during upgrade.",
48
+ decisions: [],
49
+ blockers: [],
50
+ nextSteps: [],
51
+ }),
52
+ "utf-8",
53
+ );
54
+
55
+ const read = readPhaseAnchor(base, "M001", "research-slice");
56
+ assert.ok(read);
57
+ assert.equal(read.intent, "Keep reading old anchors during upgrade.");
30
58
  } finally {
31
59
  rmSync(base, { recursive: true, force: true });
32
60
  }
@@ -6,7 +6,7 @@ import { tmpdir } from 'node:os';
6
6
 
7
7
  import { openDatabase, closeDatabase, insertMilestone, insertSlice, insertTask, getSlice, getTask, getSliceTasks, getGateResults } from '../gsd-db.ts';
8
8
  import { handlePlanTask } from '../tools/plan-task.ts';
9
- import { parseTaskPlanFile } from '../files.ts';
9
+ import { parsePlan } from '../parsers-legacy.ts';
10
10
 
11
11
  function makeTmpBase(): string {
12
12
  const base = mkdtempSync(join(tmpdir(), 'gsd-plan-task-'));
@@ -60,7 +60,7 @@ function validParams() {
60
60
  };
61
61
  }
62
62
 
63
- test('handlePlanTask writes planning state and renders task plan', async () => {
63
+ test('handlePlanTask writes planning state and renders the flat-phase slice plan', async () => {
64
64
  const base = makeTmpBase();
65
65
  openDatabase(join(base, '.gsd', 'gsd.db'));
66
66
 
@@ -75,11 +75,13 @@ test('handlePlanTask writes planning state and renders task plan', async () => {
75
75
  assert.equal(task?.description, 'Implement the DB-backed task planning handler.');
76
76
  assert.equal(task?.estimate, '30m');
77
77
 
78
- const taskPlanPath = join(base, '.gsd', 'phases', '01-test', 'T02-PLAN.md');
79
- assert.ok(existsSync(taskPlanPath), 'task plan should be rendered to disk');
80
- const taskPlan = parseTaskPlanFile(readFileSync(taskPlanPath, 'utf-8'));
81
- assert.equal(taskPlan.frontmatter.estimated_files, 1);
82
- assert.deepEqual(taskPlan.frontmatter.skills_used, []);
78
+ const slicePlanPath = join(base, '.gsd', 'phases', '01-test', '01-02-PLAN.md');
79
+ assert.equal(result.taskPlanPath, slicePlanPath);
80
+ assert.ok(existsSync(slicePlanPath), 'slice plan should be rendered to disk');
81
+ assert.equal(existsSync(join(base, '.gsd', 'phases', '01-test', 'T02-PLAN.md')), false);
82
+ const slicePlan = parsePlan(readFileSync(slicePlanPath, 'utf-8'));
83
+ assert.equal(slicePlan.tasks[0]?.id, 'T02');
84
+ assert.equal(slicePlan.tasks[0]?.files?.[0], 'src/resources/extensions/gsd/tools/plan-task.ts');
83
85
  } finally {
84
86
  cleanup(base);
85
87
  }
@@ -215,17 +217,17 @@ test('handlePlanTask rejects missing parent slice', async () => {
215
217
  }
216
218
  });
217
219
 
218
- test('handlePlanTask surfaces render failures without changing parse-visible task plan state', async () => {
220
+ test('handlePlanTask surfaces render failures without changing parse-visible slice plan state', async () => {
219
221
  const base = makeTmpBase();
220
222
  openDatabase(join(base, '.gsd', 'gsd.db'));
221
223
 
222
224
  try {
223
225
  seedParent();
224
226
  insertTask({ id: 'T02', sliceId: 'S02', milestoneId: 'M001', title: 'Cached task', status: 'pending' });
225
- const taskPlanPath = join(base, '.gsd', 'phases', '01-test', 'T02-PLAN.md');
226
- writeFileSync(taskPlanPath, '---\nestimated_steps: 1\nestimated_files: 1\nskills_used: []\n---\n\n# T02: Cached task\n', 'utf-8');
227
- rmSync(taskPlanPath, { force: true });
228
- mkdirSync(taskPlanPath, { recursive: true });
227
+ const slicePlanPath = join(base, '.gsd', 'phases', '01-test', '01-02-PLAN.md');
228
+ writeFileSync(slicePlanPath, '# S02: Cached slice\n\n<tasks>\n- [ ] **T02**: Cached task\n</tasks>\n', 'utf-8');
229
+ rmSync(slicePlanPath, { force: true });
230
+ mkdirSync(slicePlanPath, { recursive: true });
229
231
 
230
232
  const result = await handlePlanTask(validParams(), base);
231
233
  assert.ok('error' in result);
@@ -243,15 +245,16 @@ test('handlePlanTask keeps the sketch flag set when the flat-phase slice plan sy
243
245
  insertMilestone({ id: 'M001', title: 'Milestone', status: 'active' });
244
246
  insertSlice({ id: 'S02', milestoneId: 'M001', title: 'Planning slice', status: 'pending', demo: 'Rendered plans exist.', isSketch: true });
245
247
 
246
- // The per-task render writes T02-PLAN.md and succeeds, but the flat-phase
247
- // slice re-render (the canonical PLAN.md that embeds task checkboxes) targets
248
- // phases/01-test/01-02-PLAN.md. Pre-creating that path as a directory forces
249
- // EISDIR on the slice sync, so the canonical slice plan never reflects the
250
- // task. The sketch flag must therefore stay set — the slice keeps refining —
251
- // instead of leaving the slice out of refining over a stale plan.
248
+ // The flat-phase slice render targets phases/01-test/01-02-PLAN.md.
249
+ // Pre-creating that path as a directory forces EISDIR, so the canonical
250
+ // slice plan never reflects the task. The sketch flag must therefore stay
251
+ // set the slice keeps refining instead of leaving the slice out of
252
+ // refining over a stale plan.
252
253
  mkdirSync(join(base, '.gsd', 'phases', '01-test', '01-02-PLAN.md'), { recursive: true });
253
254
 
254
255
  const result = await handlePlanTask(validParams(), base);
256
+ assert.ok('error' in result);
257
+ assert.match(result.error, /render failed:/);
255
258
  assert.equal(getSlice('M001', 'S02')?.is_sketch, 1, 'sketch flag must stay set when the canonical slice plan could not sync');
256
259
  assert.ok(getTask('M001', 'S02', 'T02'), 'the task itself is still persisted so the slice can re-sync on retry');
257
260
  } finally {
@@ -265,8 +268,8 @@ test('handlePlanTask reruns idempotently and refreshes parse-visible state', asy
265
268
 
266
269
  try {
267
270
  seedParent();
268
- const taskPlanPath = join(base, '.gsd', 'phases', '01-test', 'T02-PLAN.md');
269
- writeFileSync(taskPlanPath, '---\nestimated_steps: 1\nestimated_files: 1\nskills_used: []\n---\n\n# T02: Cached task\n', 'utf-8');
271
+ const slicePlanPath = join(base, '.gsd', 'phases', '01-test', '01-02-PLAN.md');
272
+ writeFileSync(slicePlanPath, '# S02: Cached slice\n\n<tasks>\n- [ ] **T02**: Cached task\n</tasks>\n', 'utf-8');
270
273
 
271
274
  const first = await handlePlanTask(validParams(), base);
272
275
  assert.ok(!('error' in first));
@@ -282,9 +285,9 @@ test('handlePlanTask reruns idempotently and refreshes parse-visible state', asy
282
285
  assert.equal(task?.description, 'Updated task handler description.');
283
286
  assert.equal(task?.estimate, '1h');
284
287
 
285
- const parsed = parseTaskPlanFile(readFileSync(taskPlanPath, 'utf-8'));
286
- assert.equal(parsed.frontmatter.estimated_steps, 1);
287
- assert.match(readFileSync(taskPlanPath, 'utf-8'), /Updated task handler description\./);
288
+ const parsed = parsePlan(readFileSync(slicePlanPath, 'utf-8'));
289
+ assert.equal(parsed.tasks[0]?.id, 'T02');
290
+ assert.match(readFileSync(slicePlanPath, 'utf-8'), /Updated task handler description\./);
288
291
  } finally {
289
292
  cleanup(base);
290
293
  }
@@ -8,7 +8,7 @@ import { tmpdir } from "node:os";
8
8
  import { randomUUID } from "node:crypto";
9
9
 
10
10
  import { writePlanningDirectory } from "../migrate/planning-writer.ts";
11
- import { openDatabase, closeDatabase, insertMilestone, insertSlice, insertTask } from "../gsd-db.ts";
11
+ import { openDatabase, closeDatabase, insertMilestone, insertSlice, insertTask, updateTaskStatus } from "../gsd-db.ts";
12
12
 
13
13
  const tmpDirs: string[] = [];
14
14
  function makeTmp(): string {
@@ -65,6 +65,23 @@ test("writePlanningDirectory emits phase plan file with XML structure", async ()
65
65
  assert.match(plan, /<tasks>/);
66
66
  });
67
67
 
68
+ test("writePlanningDirectory renders completed task checkboxes as [x] (#1276)", async () => {
69
+ const base = makeTmp();
70
+ updateTaskStatus("M001", "S01", "T01", "complete");
71
+ await writePlanningDirectory(base, "flat-phases");
72
+
73
+ const phaseDir = readdirSync(join(base, ".planning", "phases"), { withFileTypes: true })
74
+ .filter((d) => d.isDirectory())
75
+ .map((d) => d.name)[0]!;
76
+ const planFile = readdirSync(join(base, ".planning", "phases", phaseDir))
77
+ .filter((f) => f.endsWith("PLAN.md"))[0]!;
78
+ const plan = readFileSync(join(base, ".planning", "phases", phaseDir, planFile), "utf-8");
79
+ assert.match(plan, /- \[x\] \*\*T01\*\*/, "completed task should project as [x], not [ ]");
80
+
81
+ const roadmap = readFileSync(join(base, ".planning", "ROADMAP.md"), "utf-8");
82
+ assert.match(roadmap, /- \[x\] 01 —/, "phase with all tasks complete should be [x] in ROADMAP");
83
+ });
84
+
68
85
  test("writePlanningDirectory is idempotent: writing twice produces stable content", async () => {
69
86
  const base = makeTmp();
70
87
  await writePlanningDirectory(base, "flat-phases");
@@ -75,6 +92,35 @@ test("writePlanningDirectory is idempotent: writing twice produces stable conten
75
92
  assert.equal(roadmap2, roadmap1);
76
93
  });
77
94
 
95
+ test("writePlanningDirectory does not emit an ingestible PLAN.md for a task-less (sketch) slice", async () => {
96
+ // Regression for #1285: a milestone-level sketch slice has zero DB tasks.
97
+ // The projection must not write a placeholder NN-01-PLAN.md — the reverse
98
+ // transform maps one task per plan file, so a placeholder would materialize
99
+ // a phantom "Plan NN" task and make auto-mode skip planning.
100
+ const base = makeTmp();
101
+ insertSlice({
102
+ milestoneId: "M001", id: "S02", title: "Sketch slice", status: "pending",
103
+ risk: "medium", depends: ["S01"], demo: "designed", sequence: 2,
104
+ });
105
+ // S02 intentionally has no tasks.
106
+
107
+ await writePlanningDirectory(base, "flat-phases");
108
+
109
+ const phaseDirs = readdirSync(join(base, ".planning", "phases"), { withFileTypes: true })
110
+ .filter((d) => d.isDirectory())
111
+ .map((d) => d.name);
112
+ const sketchDir = phaseDirs.find((d) => /^02-/.test(d));
113
+ assert.ok(sketchDir, `expected a 02- phase dir for the sketch slice, got ${JSON.stringify(phaseDirs)}`);
114
+
115
+ const planFiles = readdirSync(join(base, ".planning", "phases", sketchDir!))
116
+ .filter((f) => f.endsWith("PLAN.md"));
117
+ assert.equal(planFiles.length, 0, `sketch slice should have no PLAN.md, got ${JSON.stringify(planFiles)}`);
118
+
119
+ // The slice remains discoverable via ROADMAP.md.
120
+ const roadmap = readFileSync(join(base, ".planning", "ROADMAP.md"), "utf-8");
121
+ assert.match(roadmap, /Sketch slice/);
122
+ });
123
+
78
124
  test("writePlanningDirectory throws for unsupported layouts", async () => {
79
125
  const base = makeTmp();
80
126
  await assert.rejects(() => writePlanningDirectory(base, "multi-milestone"), /not yet supported/);
@@ -496,6 +496,28 @@ describe("checkImportResolution", () => {
496
496
  }
497
497
  });
498
498
 
499
+ test("ignores generated Convex _generated imports", () => {
500
+ tempDir = join(tmpdir(), `post-exec-test-${Date.now()}`);
501
+ mkdirSync(tempDir, { recursive: true });
502
+ mkdirSync(join(tempDir, "convex"), { recursive: true });
503
+ writeFileSync(
504
+ join(tempDir, "convex", "stagedLibraryEdits.ts"),
505
+ "import type { DataModel } from './_generated/dataModel';\nexport const model = {} as DataModel;"
506
+ );
507
+
508
+ try {
509
+ const task = createTask({
510
+ id: "T01",
511
+ key_files: ["convex/stagedLibraryEdits.ts"],
512
+ });
513
+
514
+ const results = checkImportResolution(task, [], tempDir);
515
+ assert.deepEqual(results, []);
516
+ } finally {
517
+ rmSync(tempDir, { recursive: true, force: true });
518
+ }
519
+ });
520
+
499
521
  test("fails when import doesn't resolve", () => {
500
522
  tempDir = join(tmpdir(), `post-exec-test-${Date.now()}`);
501
523
  mkdirSync(tempDir, { recursive: true });
@@ -76,6 +76,21 @@ function writeS01Artifacts(base: string): void {
76
76
  writeFileSync(join(base, ".gsd", "milestones", "M001", "slices", "S01", "S01-SUMMARY.md"), "# S01 Summary\n");
77
77
  }
78
78
 
79
+ // A *real* decomposed PLAN (>= 1 genuine task). #1287: the stale-sketch-flag
80
+ // detector requires a real plan — not a bare stub — before clearing is_sketch.
81
+ function realPlanContent(sliceId: string): string {
82
+ return [
83
+ `# ${sliceId}: Feature`,
84
+ "",
85
+ "**Goal:** Ship the feature",
86
+ "",
87
+ "## Tasks",
88
+ "",
89
+ "- [ ] **T01: Build the feature** `est:1h`",
90
+ "",
91
+ ].join("\n");
92
+ }
93
+
79
94
  function cleanup(base: string, originalCwd: string): void {
80
95
  try { closeDatabase(); } catch { /* noop */ }
81
96
  process.chdir(originalCwd);
@@ -185,7 +200,7 @@ test("ADR-011: existing PLAN + stale sketch flag heals via reconcileBeforeDispat
185
200
  writePreferences(base, "phases:\n progressive_planning: true");
186
201
  writeFileSync(
187
202
  join(base, ".gsd", "milestones", "M001", "slices", "S02", "S02-PLAN.md"),
188
- "# S02 Plan\n",
203
+ realPlanContent("S02"),
189
204
  );
190
205
  process.chdir(base);
191
206
 
@@ -252,7 +267,7 @@ test("ADR-011: reconcileBeforeDispatch auto-heals stale sketch flag when PLAN ex
252
267
  // Simulate plan-slice completion where PLAN exists but is_sketch was not flipped.
253
268
  writeFileSync(
254
269
  join(base, ".gsd", "milestones", "M001", "slices", "S02", "S02-PLAN.md"),
255
- "# S02 Plan\n",
270
+ realPlanContent("S02"),
256
271
  );
257
272
  process.chdir(base);
258
273
 
@@ -282,7 +297,7 @@ test("ADR-011: deriveState stays pure across worktree/canonical-root; healing be
282
297
  writePreferences(base, "phases:\n skip_research: false");
283
298
  writeFileSync(
284
299
  join(base, ".gsd", "milestones", "M001", "slices", "S02", "S02-PLAN.md"),
285
- "# S02 Plan\n",
300
+ realPlanContent("S02"),
286
301
  );
287
302
  const worktreePath = join(base, "worker");
288
303
  mkdirSync(worktreePath, { recursive: true });
@@ -210,6 +210,56 @@ test('handleReassessRoadmap succeeds when modifying only pending slices', async
210
210
  }
211
211
  });
212
212
 
213
+ test('handleReassessRoadmap writes legacy-layout reassessment to S##-ASSESSMENT.md', async () => {
214
+ const base = mkdtempSync(join(tmpdir(), 'gsd-reassess-legacy-'));
215
+ mkdirSync(join(base, '.gsd', 'milestones', 'M005-3qxqd7', 'slices', 'S04'), { recursive: true });
216
+ mkdirSync(join(base, '.gsd', 'phases', '05-3qxqd7-legacy-milestone'), { recursive: true });
217
+ openDatabase(join(base, '.gsd', 'gsd.db'));
218
+
219
+ try {
220
+ insertMilestone({ id: 'M005-3qxqd7', title: 'Legacy Milestone', status: 'active' });
221
+ insertSlice({
222
+ id: 'S04',
223
+ milestoneId: 'M005-3qxqd7',
224
+ title: 'Legacy Slice Four',
225
+ status: 'complete',
226
+ demo: 'Demo four.',
227
+ });
228
+
229
+ const result = await handleReassessRoadmap({
230
+ milestoneId: 'M005-3qxqd7',
231
+ completedSliceId: 'S04',
232
+ verdict: 'confirmed',
233
+ assessment: 'S04 completed successfully. Roadmap remains valid.',
234
+ sliceChanges: {
235
+ modified: [],
236
+ added: [],
237
+ removed: [],
238
+ },
239
+ }, base);
240
+
241
+ if ('error' in result) {
242
+ assert.fail(`unexpected error: ${result.error}`);
243
+ }
244
+
245
+ const correctPath = join(base, '.gsd', 'milestones', 'M005-3qxqd7', 'slices', 'S04', 'S04-ASSESSMENT.md');
246
+ const wrongFlatNameInLegacyDir = join(base, '.gsd', 'milestones', 'M005-3qxqd7', 'slices', 'S04', '05-04-ASSESSMENT.md');
247
+ const wrongFlatPhasePath = join(base, '.gsd', 'phases', '05-3qxqd7-legacy-milestone', '05-04-ASSESSMENT.md');
248
+ assert.match(
249
+ result.assessmentPath.replace(/\\/g, '/'),
250
+ /\/\.gsd\/milestones\/M005-3qxqd7\/slices\/S04\/S04-ASSESSMENT\.md$/,
251
+ );
252
+ assert.ok(existsSync(correctPath), 'legacy ASSESSMENT should use S## filename inside slices/S##/');
253
+ assert.equal(existsSync(wrongFlatNameInLegacyDir), false, 'legacy slice dir must not receive flat-phase assessment filename');
254
+ assert.equal(existsSync(wrongFlatPhasePath), false, 'legacy reassessment must not be diverted to a coexisting flat-phase dir');
255
+
256
+ const assessment = getAssessment('.gsd/milestones/M005-3qxqd7/slices/S04/S04-ASSESSMENT.md');
257
+ assert.ok(assessment, 'assessment row should use the legacy-layout path');
258
+ } finally {
259
+ cleanup(base);
260
+ }
261
+ });
262
+
213
263
  test('handleReassessRoadmap cache invalidation: getMilestoneSlices reflects mutations', async () => {
214
264
  const base = makeTmpBase();
215
265
  openDatabase(join(base, '.gsd', 'gsd.db'));
@@ -0,0 +1,103 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { mkdtempSync, mkdirSync, rmSync, readFileSync, existsSync } from 'node:fs';
4
+ import { join } from 'node:path';
5
+ import { tmpdir } from 'node:os';
6
+
7
+ import {
8
+ openDatabase,
9
+ closeDatabase,
10
+ insertMilestone,
11
+ insertSlice,
12
+ insertTask,
13
+ upsertTaskPlanning,
14
+ getTask,
15
+ getReplanHistory,
16
+ } from '../gsd-db.ts';
17
+ import { handleReplanTask } from '../tools/replan-task.ts';
18
+
19
+ function makeTmpBase(): string {
20
+ const base = mkdtempSync(join(tmpdir(), 'gsd-replan-task-'));
21
+ mkdirSync(join(base, '.gsd', 'phases', '01-test'), { recursive: true });
22
+ return base;
23
+ }
24
+
25
+ function cleanup(base: string): void {
26
+ try { closeDatabase(); } catch { /* noop */ }
27
+ try { rmSync(base, { recursive: true, force: true }); } catch { /* noop */ }
28
+ }
29
+
30
+ function seedTask(status = 'pending'): void {
31
+ insertMilestone({ id: 'M001', title: 'Test Milestone', status: 'active' });
32
+ insertSlice({ id: 'S01', milestoneId: 'M001', title: 'Test Slice', status: 'active', demo: 'Demo.' });
33
+ insertTask({ id: 'T01', sliceId: 'S01', milestoneId: 'M001', title: 'Original Task', status });
34
+ upsertTaskPlanning('M001', 'S01', 'T01', {
35
+ description: 'Original task description.',
36
+ estimate: '30m',
37
+ files: ['src/original.ts'],
38
+ verify: 'node --test original.test.ts',
39
+ inputs: ['src/original.ts'],
40
+ expectedOutput: ['src/original.ts'],
41
+ });
42
+ }
43
+
44
+ function validReplanTaskParams() {
45
+ return {
46
+ milestoneId: 'M001',
47
+ sliceId: 'S01',
48
+ taskId: 'T01',
49
+ title: 'Replanned Task',
50
+ description: 'Updated task description with blocking rework scope.',
51
+ estimate: '45m',
52
+ files: ['src/replanned.ts'],
53
+ verify: 'node --test replanned.test.ts',
54
+ inputs: ['src/original.ts'],
55
+ expectedOutput: ['src/replanned.ts'],
56
+ reworkBriefRef: 'RB-001',
57
+ };
58
+ }
59
+
60
+ test('handleReplanTask updates one pending task plan and records a task-scoped replan history entry', async () => {
61
+ const base = makeTmpBase();
62
+ openDatabase(join(base, '.gsd', 'gsd.db'));
63
+
64
+ try {
65
+ seedTask('pending');
66
+
67
+ const result = await handleReplanTask(validReplanTaskParams(), base);
68
+ assert.ok(!('error' in result), `unexpected error: ${'error' in result ? result.error : ''}`);
69
+
70
+ const task = getTask('M001', 'S01', 'T01');
71
+ assert.ok(task, 'task should still exist');
72
+ assert.equal(task.title, 'Replanned Task');
73
+ assert.equal(task.description, 'Updated task description with blocking rework scope.');
74
+ assert.equal(task.verify, 'node --test replanned.test.ts');
75
+ assert.deepEqual(task.files, ['src/replanned.ts']);
76
+
77
+ const history = getReplanHistory('M001', 'S01');
78
+ assert.ok(history.some((row) => row['task_id'] === 'T01' && String(row['summary']).includes('RB-001')));
79
+
80
+ const planPath = join(base, '.gsd', 'phases', '01-test', '01-01-PLAN.md');
81
+ assert.ok(existsSync(planPath), 'slice plan projection should be rendered');
82
+ const planContent = readFileSync(planPath, 'utf-8');
83
+ assert.match(planContent, /Replanned Task/);
84
+ assert.match(planContent, /node --test replanned\.test\.ts/);
85
+ } finally {
86
+ cleanup(base);
87
+ }
88
+ });
89
+
90
+ test('handleReplanTask rejects completed tasks', async () => {
91
+ const base = makeTmpBase();
92
+ openDatabase(join(base, '.gsd', 'gsd.db'));
93
+
94
+ try {
95
+ seedTask('complete');
96
+
97
+ const result = await handleReplanTask(validReplanTaskParams(), base);
98
+ assert.ok('error' in result);
99
+ assert.match(result.error, /cannot replan completed task T01/i);
100
+ } finally {
101
+ cleanup(base);
102
+ }
103
+ });