@opengsd/gsd-pi 1.1.1-dev.616a1a1 → 1.1.1-dev.75048e7

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 (452) hide show
  1. package/dist/cli.js +3 -2
  2. package/dist/help-text.js +10 -6
  3. package/dist/resources/.managed-resources-content-hash +1 -1
  4. package/dist/resources/extensions/browser-tools/engine/managed-gsd-browser.js +495 -0
  5. package/dist/resources/extensions/browser-tools/engine/selection.js +16 -0
  6. package/dist/resources/extensions/browser-tools/extension-manifest.json +2 -2
  7. package/dist/resources/extensions/browser-tools/index.js +57 -9
  8. package/dist/resources/extensions/browser-tools/package.json +5 -1
  9. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +167 -16
  10. package/dist/resources/extensions/gsd/auto/orchestrator.js +0 -1
  11. package/dist/resources/extensions/gsd/auto/phases.js +4 -3
  12. package/dist/resources/extensions/gsd/auto-dashboard.js +92 -17
  13. package/dist/resources/extensions/gsd/auto-dispatch.js +55 -0
  14. package/dist/resources/extensions/gsd/auto-post-unit.js +134 -10
  15. package/dist/resources/extensions/gsd/auto-prompts.js +72 -22
  16. package/dist/resources/extensions/gsd/auto-recovery.js +7 -8
  17. package/dist/resources/extensions/gsd/auto-runtime-state.js +3 -0
  18. package/dist/resources/extensions/gsd/auto-start.js +94 -15
  19. package/dist/resources/extensions/gsd/auto-tool-tracking.js +1 -1
  20. package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +18 -65
  21. package/dist/resources/extensions/gsd/auto-worktree.js +18 -5
  22. package/dist/resources/extensions/gsd/auto.js +31 -6
  23. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +89 -4
  24. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +43 -0
  25. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +56 -20
  26. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +33 -38
  27. package/dist/resources/extensions/gsd/browser-evidence.js +29 -2
  28. package/dist/resources/extensions/gsd/closeout-consistency-gate.js +61 -0
  29. package/dist/resources/extensions/gsd/commands/catalog.js +6 -1
  30. package/dist/resources/extensions/gsd/commands/handlers/core.js +6 -2
  31. package/dist/resources/extensions/gsd/commands/handlers/ops.js +9 -5
  32. package/dist/resources/extensions/gsd/commands-handlers.js +76 -11
  33. package/dist/resources/extensions/gsd/commands-maintenance.js +172 -2
  34. package/dist/resources/extensions/gsd/commands-mcp-status.js +109 -60
  35. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +3 -1
  36. package/dist/resources/extensions/gsd/commands-verdict.js +1 -1
  37. package/dist/resources/extensions/gsd/config-overlay.js +2 -1
  38. package/dist/resources/extensions/gsd/dashboard-overlay.js +21 -7
  39. package/dist/resources/extensions/gsd/docs/preferences-reference.md +8 -0
  40. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +2 -2
  41. package/dist/resources/extensions/gsd/error-classifier.js +2 -1
  42. package/dist/resources/extensions/gsd/escalation.js +4 -4
  43. package/dist/resources/extensions/gsd/exec-sandbox.js +2 -0
  44. package/dist/resources/extensions/gsd/forensics.js +74 -2
  45. package/dist/resources/extensions/gsd/gsd-db.js +42 -6
  46. package/dist/resources/extensions/gsd/guided-flow.js +119 -176
  47. package/dist/resources/extensions/gsd/mcp-filter.js +3 -0
  48. package/dist/resources/extensions/gsd/mcp-project-config.js +76 -84
  49. package/dist/resources/extensions/gsd/memory-store.js +4 -1
  50. package/dist/resources/extensions/gsd/migration-auto-check.js +2 -2
  51. package/dist/resources/extensions/gsd/milestone-closeout.js +3 -1
  52. package/dist/resources/extensions/gsd/pending-auto-start.js +0 -1
  53. package/dist/resources/extensions/gsd/post-unit-hooks.js +9 -0
  54. package/dist/resources/extensions/gsd/preferences-validation.js +39 -0
  55. package/dist/resources/extensions/gsd/prompt-loader.js +7 -0
  56. package/dist/resources/extensions/gsd/prompts/forensics.md +61 -1
  57. package/dist/resources/extensions/gsd/prompts/gate-evaluate.md +3 -1
  58. package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +3 -1
  59. package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  60. package/dist/resources/extensions/gsd/prompts/reactive-execute.md +3 -1
  61. package/dist/resources/extensions/gsd/prompts/run-uat.md +33 -23
  62. package/dist/resources/extensions/gsd/prompts/system.md +3 -1
  63. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +3 -3
  64. package/dist/resources/extensions/gsd/recovery-classification.js +20 -0
  65. package/dist/resources/extensions/gsd/rule-registry.js +428 -52
  66. package/dist/resources/extensions/gsd/safety/destructive-guard.js +3 -0
  67. package/dist/resources/extensions/gsd/skill-activation.js +20 -3
  68. package/dist/resources/extensions/gsd/state-reconciliation/drift/artifact-db.js +4 -2
  69. package/dist/resources/extensions/gsd/state-reconciliation/drift/project-md.js +1 -1
  70. package/dist/resources/extensions/gsd/state-reconciliation/drift/roadmap.js +18 -1
  71. package/dist/resources/extensions/gsd/state-reconciliation/index.js +6 -0
  72. package/dist/resources/extensions/gsd/state.js +17 -14
  73. package/dist/resources/extensions/gsd/templates/plan.md +3 -1
  74. package/dist/resources/extensions/gsd/tool-contract.js +5 -0
  75. package/dist/resources/extensions/gsd/tool-presentation-plan.js +143 -0
  76. package/dist/resources/extensions/gsd/tools/complete-slice.js +15 -1
  77. package/dist/resources/extensions/gsd/tools/complete-task.js +11 -1
  78. package/dist/resources/extensions/gsd/tools/exec-tool.js +109 -0
  79. package/dist/resources/extensions/gsd/tools/plan-slice.js +14 -9
  80. package/dist/resources/extensions/gsd/tools/reopen-milestone.js +2 -2
  81. package/dist/resources/extensions/gsd/tools/validate-milestone.js +46 -16
  82. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +483 -6
  83. package/dist/resources/extensions/gsd/unit-context-manifest.js +8 -3
  84. package/dist/resources/extensions/gsd/unit-tool-contracts.js +169 -0
  85. package/dist/resources/extensions/gsd/validation-block-guard.js +2 -0
  86. package/dist/resources/extensions/gsd/verdict-parser.js +59 -15
  87. package/dist/resources/extensions/gsd/verification-gate.js +72 -1
  88. package/dist/resources/extensions/gsd/workflow-mcp-auto-prep.js +3 -1
  89. package/dist/resources/extensions/gsd/workflow-mcp.js +5 -73
  90. package/dist/resources/extensions/gsd/worktree-lifecycle.js +24 -0
  91. package/dist/resources/extensions/mcp-client/manager.js +31 -1
  92. package/dist/resources/extensions/shared/gsd-browser-cli.js +145 -0
  93. package/dist/rtk.d.ts +7 -1
  94. package/dist/rtk.js +27 -11
  95. package/dist/update-check.d.ts +15 -1
  96. package/dist/update-check.js +87 -12
  97. package/dist/update-cmd.d.ts +1 -0
  98. package/dist/update-cmd.js +53 -2
  99. package/dist/web/standalone/.next/BUILD_ID +1 -1
  100. package/dist/web/standalone/.next/app-path-routes-manifest.json +5 -5
  101. package/dist/web/standalone/.next/build-manifest.json +2 -2
  102. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  103. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  104. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  105. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  106. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  107. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  108. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  109. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  110. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  111. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  112. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  113. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  114. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  115. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  116. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  117. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  118. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  119. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  120. package/dist/web/standalone/.next/server/app/index.html +1 -1
  121. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  122. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  123. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  124. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  125. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  126. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  127. package/dist/web/standalone/.next/server/app-paths-manifest.json +5 -5
  128. package/dist/web/standalone/.next/server/chunks/8357.js +1 -1
  129. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  130. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  131. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  132. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  133. package/package.json +5 -3
  134. package/packages/cloud-mcp-gateway/package.json +2 -2
  135. package/packages/contracts/dist/workflow.d.ts +14 -0
  136. package/packages/contracts/dist/workflow.d.ts.map +1 -1
  137. package/packages/contracts/dist/workflow.js +16 -0
  138. package/packages/contracts/dist/workflow.js.map +1 -1
  139. package/packages/contracts/package.json +1 -1
  140. package/packages/daemon/package.json +4 -4
  141. package/packages/gsd-agent-core/dist/agent-session.d.ts +9 -0
  142. package/packages/gsd-agent-core/dist/agent-session.d.ts.map +1 -1
  143. package/packages/gsd-agent-core/dist/agent-session.js +32 -0
  144. package/packages/gsd-agent-core/dist/agent-session.js.map +1 -1
  145. package/packages/gsd-agent-core/dist/index.d.ts +1 -0
  146. package/packages/gsd-agent-core/dist/index.d.ts.map +1 -1
  147. package/packages/gsd-agent-core/dist/index.js +1 -0
  148. package/packages/gsd-agent-core/dist/index.js.map +1 -1
  149. package/packages/gsd-agent-core/dist/session/agent-session-compaction.d.ts +2 -0
  150. package/packages/gsd-agent-core/dist/session/agent-session-compaction.d.ts.map +1 -1
  151. package/packages/gsd-agent-core/dist/session/agent-session-compaction.js +8 -2
  152. package/packages/gsd-agent-core/dist/session/agent-session-compaction.js.map +1 -1
  153. package/packages/gsd-agent-core/dist/session/agent-session-host.d.ts +7 -0
  154. package/packages/gsd-agent-core/dist/session/agent-session-host.d.ts.map +1 -1
  155. package/packages/gsd-agent-core/dist/session/agent-session-host.js.map +1 -1
  156. package/packages/gsd-agent-core/dist/session/agent-session-prompt.d.ts.map +1 -1
  157. package/packages/gsd-agent-core/dist/session/agent-session-prompt.js +69 -1
  158. package/packages/gsd-agent-core/dist/session/agent-session-prompt.js.map +1 -1
  159. package/packages/gsd-agent-core/dist/turn-latency.d.ts +47 -0
  160. package/packages/gsd-agent-core/dist/turn-latency.d.ts.map +1 -0
  161. package/packages/gsd-agent-core/dist/turn-latency.js +123 -0
  162. package/packages/gsd-agent-core/dist/turn-latency.js.map +1 -0
  163. package/packages/gsd-agent-core/package.json +6 -6
  164. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.d.ts +21 -0
  165. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.d.ts.map +1 -0
  166. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.js +213 -0
  167. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.js.map +1 -0
  168. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts +2 -0
  169. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  170. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js +10 -0
  171. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js.map +1 -1
  172. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  173. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +5 -0
  174. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
  175. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts +1 -0
  176. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  177. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +92 -31
  178. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  179. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
  180. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js +7 -1
  181. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  182. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-command-handlers.d.ts.map +1 -1
  183. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-command-handlers.js +6 -0
  184. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-command-handlers.js.map +1 -1
  185. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-dialogs.d.ts.map +1 -1
  186. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-dialogs.js +2 -0
  187. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-dialogs.js.map +1 -1
  188. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.d.ts +1 -1
  189. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.d.ts.map +1 -1
  190. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.js +1 -1
  191. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.js.map +1 -1
  192. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  193. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js +1 -0
  194. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js.map +1 -1
  195. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.d.ts.map +1 -1
  196. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.js +5 -0
  197. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.js.map +1 -1
  198. package/packages/gsd-agent-modes/package.json +7 -7
  199. package/packages/mcp-server/dist/remote-questions.d.ts.map +1 -1
  200. package/packages/mcp-server/dist/remote-questions.js +23 -9
  201. package/packages/mcp-server/dist/remote-questions.js.map +1 -1
  202. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  203. package/packages/mcp-server/dist/workflow-tools.js +84 -2
  204. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  205. package/packages/mcp-server/package.json +3 -3
  206. package/packages/native/package.json +1 -1
  207. package/packages/pi-agent-core/dist/agent-loop.js +42 -3
  208. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  209. package/packages/pi-agent-core/dist/agent.d.ts +5 -1
  210. package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
  211. package/packages/pi-agent-core/dist/agent.js +2 -0
  212. package/packages/pi-agent-core/dist/agent.js.map +1 -1
  213. package/packages/pi-agent-core/dist/harness/agent-harness.d.ts.map +1 -1
  214. package/packages/pi-agent-core/dist/harness/agent-harness.js +3 -1
  215. package/packages/pi-agent-core/dist/harness/agent-harness.js.map +1 -1
  216. package/packages/pi-agent-core/dist/harness/types.d.ts +1 -0
  217. package/packages/pi-agent-core/dist/harness/types.d.ts.map +1 -1
  218. package/packages/pi-agent-core/dist/harness/types.js.map +1 -1
  219. package/packages/pi-agent-core/dist/types.d.ts +6 -1
  220. package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
  221. package/packages/pi-agent-core/dist/types.js.map +1 -1
  222. package/packages/pi-agent-core/package.json +1 -1
  223. package/packages/pi-ai/dist/api-registry.d.ts +2 -0
  224. package/packages/pi-ai/dist/api-registry.d.ts.map +1 -1
  225. package/packages/pi-ai/dist/api-registry.js +23 -0
  226. package/packages/pi-ai/dist/api-registry.js.map +1 -1
  227. package/packages/pi-ai/dist/image-models.generated.d.ts +15 -0
  228. package/packages/pi-ai/dist/image-models.generated.d.ts.map +1 -1
  229. package/packages/pi-ai/dist/image-models.generated.js +15 -0
  230. package/packages/pi-ai/dist/image-models.generated.js.map +1 -1
  231. package/packages/pi-ai/dist/models.generated.d.ts +411 -39
  232. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  233. package/packages/pi-ai/dist/models.generated.js +504 -153
  234. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  235. package/packages/pi-ai/dist/stream.js +6 -6
  236. package/packages/pi-ai/dist/stream.js.map +1 -1
  237. package/packages/pi-ai/package.json +1 -1
  238. package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.d.ts +3 -0
  239. package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.d.ts.map +1 -1
  240. package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.js.map +1 -1
  241. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  242. package/packages/pi-coding-agent/dist/core/model-registry.js +2 -2
  243. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  244. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +3 -0
  245. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  246. package/packages/pi-coding-agent/dist/core/settings-manager.js +11 -0
  247. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  248. package/packages/pi-coding-agent/dist/core/tools/bash.js +2 -2
  249. package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
  250. package/packages/pi-coding-agent/dist/core/tools/edit.d.ts.map +1 -1
  251. package/packages/pi-coding-agent/dist/core/tools/edit.js +3 -2
  252. package/packages/pi-coding-agent/dist/core/tools/edit.js.map +1 -1
  253. package/packages/pi-coding-agent/dist/core/tools/render-utils.d.ts +1 -0
  254. package/packages/pi-coding-agent/dist/core/tools/render-utils.d.ts.map +1 -1
  255. package/packages/pi-coding-agent/dist/core/tools/render-utils.js +6 -0
  256. package/packages/pi-coding-agent/dist/core/tools/render-utils.js.map +1 -1
  257. package/packages/pi-coding-agent/dist/core/tools/write.d.ts.map +1 -1
  258. package/packages/pi-coding-agent/dist/core/tools/write.js +3 -2
  259. package/packages/pi-coding-agent/dist/core/tools/write.js.map +1 -1
  260. package/packages/pi-coding-agent/package.json +7 -7
  261. package/packages/pi-tui/dist/terminal.d.ts +1 -0
  262. package/packages/pi-tui/dist/terminal.d.ts.map +1 -1
  263. package/packages/pi-tui/dist/terminal.js +8 -4
  264. package/packages/pi-tui/dist/terminal.js.map +1 -1
  265. package/packages/pi-tui/package.json +1 -1
  266. package/packages/rpc-client/package.json +2 -2
  267. package/pkg/package.json +1 -1
  268. package/src/resources/extensions/browser-tools/engine/managed-gsd-browser.ts +579 -0
  269. package/src/resources/extensions/browser-tools/engine/selection.ts +19 -0
  270. package/src/resources/extensions/browser-tools/extension-manifest.json +2 -2
  271. package/src/resources/extensions/browser-tools/index.ts +60 -9
  272. package/src/resources/extensions/browser-tools/package.json +5 -1
  273. package/src/resources/extensions/browser-tools/tests/browser-engine-selection.test.mjs +35 -0
  274. package/src/resources/extensions/browser-tools/tests/managed-gsd-browser-tools.test.mjs +33 -0
  275. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +196 -16
  276. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +239 -63
  277. package/src/resources/extensions/gsd/auto/orchestrator.ts +0 -1
  278. package/src/resources/extensions/gsd/auto/phases.ts +5 -3
  279. package/src/resources/extensions/gsd/auto-dashboard.ts +98 -18
  280. package/src/resources/extensions/gsd/auto-dispatch.ts +67 -0
  281. package/src/resources/extensions/gsd/auto-post-unit.ts +166 -9
  282. package/src/resources/extensions/gsd/auto-prompts.ts +106 -15
  283. package/src/resources/extensions/gsd/auto-recovery.ts +7 -7
  284. package/src/resources/extensions/gsd/auto-runtime-state.ts +4 -0
  285. package/src/resources/extensions/gsd/auto-start.ts +112 -17
  286. package/src/resources/extensions/gsd/auto-tool-tracking.ts +1 -1
  287. package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +43 -73
  288. package/src/resources/extensions/gsd/auto-worktree.ts +23 -5
  289. package/src/resources/extensions/gsd/auto.ts +47 -5
  290. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +96 -4
  291. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +51 -0
  292. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +81 -25
  293. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +70 -63
  294. package/src/resources/extensions/gsd/browser-evidence.ts +26 -2
  295. package/src/resources/extensions/gsd/closeout-consistency-gate.ts +137 -0
  296. package/src/resources/extensions/gsd/commands/catalog.ts +6 -1
  297. package/src/resources/extensions/gsd/commands/handlers/core.ts +6 -2
  298. package/src/resources/extensions/gsd/commands/handlers/ops.ts +9 -5
  299. package/src/resources/extensions/gsd/commands-handlers.ts +76 -11
  300. package/src/resources/extensions/gsd/commands-maintenance.ts +197 -2
  301. package/src/resources/extensions/gsd/commands-mcp-status.ts +136 -58
  302. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +4 -1
  303. package/src/resources/extensions/gsd/commands-verdict.ts +1 -1
  304. package/src/resources/extensions/gsd/config-overlay.ts +3 -1
  305. package/src/resources/extensions/gsd/dashboard-overlay.ts +28 -7
  306. package/src/resources/extensions/gsd/docs/preferences-reference.md +8 -0
  307. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +2 -2
  308. package/src/resources/extensions/gsd/error-classifier.ts +2 -1
  309. package/src/resources/extensions/gsd/escalation.ts +4 -4
  310. package/src/resources/extensions/gsd/exec-sandbox.ts +4 -0
  311. package/src/resources/extensions/gsd/forensics.ts +99 -5
  312. package/src/resources/extensions/gsd/gsd-db.ts +46 -8
  313. package/src/resources/extensions/gsd/guided-flow.ts +215 -217
  314. package/src/resources/extensions/gsd/mcp-filter.ts +3 -0
  315. package/src/resources/extensions/gsd/mcp-project-config.ts +105 -88
  316. package/src/resources/extensions/gsd/memory-store.ts +4 -1
  317. package/src/resources/extensions/gsd/migration-auto-check.ts +2 -2
  318. package/src/resources/extensions/gsd/milestone-closeout.ts +3 -1
  319. package/src/resources/extensions/gsd/pending-auto-start.ts +0 -2
  320. package/src/resources/extensions/gsd/post-unit-hooks.ts +14 -1
  321. package/src/resources/extensions/gsd/preferences-types.ts +1 -1
  322. package/src/resources/extensions/gsd/preferences-validation.ts +36 -0
  323. package/src/resources/extensions/gsd/prompt-loader.ts +8 -0
  324. package/src/resources/extensions/gsd/prompts/forensics.md +61 -1
  325. package/src/resources/extensions/gsd/prompts/gate-evaluate.md +3 -1
  326. package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +3 -1
  327. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  328. package/src/resources/extensions/gsd/prompts/reactive-execute.md +3 -1
  329. package/src/resources/extensions/gsd/prompts/run-uat.md +33 -23
  330. package/src/resources/extensions/gsd/prompts/system.md +3 -1
  331. package/src/resources/extensions/gsd/prompts/validate-milestone.md +3 -3
  332. package/src/resources/extensions/gsd/recovery-classification.ts +20 -0
  333. package/src/resources/extensions/gsd/rule-registry.ts +558 -58
  334. package/src/resources/extensions/gsd/rule-types.ts +2 -0
  335. package/src/resources/extensions/gsd/safety/destructive-guard.ts +3 -0
  336. package/src/resources/extensions/gsd/skill-activation.ts +20 -2
  337. package/src/resources/extensions/gsd/state-reconciliation/drift/artifact-db.ts +4 -2
  338. package/src/resources/extensions/gsd/state-reconciliation/drift/project-md.ts +1 -1
  339. package/src/resources/extensions/gsd/state-reconciliation/drift/roadmap.ts +20 -0
  340. package/src/resources/extensions/gsd/state-reconciliation/index.ts +6 -0
  341. package/src/resources/extensions/gsd/state-reconciliation/types.ts +1 -0
  342. package/src/resources/extensions/gsd/state.ts +18 -14
  343. package/src/resources/extensions/gsd/templates/plan.md +3 -1
  344. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +156 -4
  345. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +123 -0
  346. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +10 -2
  347. package/src/resources/extensions/gsd/tests/auto-start-bootstrap-await-3420.test.ts +4 -1
  348. package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +143 -2
  349. package/src/resources/extensions/gsd/tests/auto-start-project-milestone-reconcile.test.ts +24 -2
  350. package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +12 -2
  351. package/src/resources/extensions/gsd/tests/browser-evidence.test.ts +142 -0
  352. package/src/resources/extensions/gsd/tests/check-auto-start-pending-gate.test.ts +9 -15
  353. package/src/resources/extensions/gsd/tests/check-auto-start-ready-guard.test.ts +26 -16
  354. package/src/resources/extensions/gsd/tests/commands-dispatcher-unmerged-milestone.test.ts +21 -0
  355. package/src/resources/extensions/gsd/tests/commands-dispatcher-validation-block.test.ts +38 -3
  356. package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +6 -2
  357. package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +30 -0
  358. package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +42 -0
  359. package/src/resources/extensions/gsd/tests/dashboard-overlay.test.ts +45 -0
  360. package/src/resources/extensions/gsd/tests/deep-planning-mode-dispatch.test.ts +53 -0
  361. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +8 -0
  362. package/src/resources/extensions/gsd/tests/derive-state-helpers.test.ts +50 -13
  363. package/src/resources/extensions/gsd/tests/discuss-milestone-structured-questions.test.ts +31 -0
  364. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +40 -1
  365. package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +60 -0
  366. package/src/resources/extensions/gsd/tests/doctor-runtime-checks.test.ts +27 -0
  367. package/src/resources/extensions/gsd/tests/escalation.test.ts +16 -27
  368. package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +18 -0
  369. package/src/resources/extensions/gsd/tests/exec-tool.test.ts +69 -0
  370. package/src/resources/extensions/gsd/tests/forensics-issue-routing.test.ts +20 -0
  371. package/src/resources/extensions/gsd/tests/forensics-prompt-rendering.test.ts +3 -0
  372. package/src/resources/extensions/gsd/tests/forensics-tool-scope.test.ts +69 -0
  373. package/src/resources/extensions/gsd/tests/gate-1b-orphan-discrimination.test.ts +31 -79
  374. package/src/resources/extensions/gsd/tests/gsd-rebuild.test.ts +199 -0
  375. package/src/resources/extensions/gsd/tests/gsd-recover.test.ts +75 -0
  376. package/src/resources/extensions/gsd/tests/guided-discuss-milestone-prompt-rendering.test.ts +40 -1
  377. package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +86 -0
  378. package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +5 -3
  379. package/src/resources/extensions/gsd/tests/guided-flow-state-rebuild.test.ts +40 -4
  380. package/src/resources/extensions/gsd/tests/guided-flow.test.ts +12 -9
  381. package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +4 -4
  382. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +8 -0
  383. package/src/resources/extensions/gsd/tests/integration/parallel-merge.test.ts +16 -0
  384. package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +72 -10
  385. package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +13 -6
  386. package/src/resources/extensions/gsd/tests/mcp-filter.test.ts +15 -0
  387. package/src/resources/extensions/gsd/tests/mcp-project-config.test.ts +100 -0
  388. package/src/resources/extensions/gsd/tests/mcp-status.test.ts +179 -0
  389. package/src/resources/extensions/gsd/tests/memory-maintenance.test.ts +39 -8
  390. package/src/resources/extensions/gsd/tests/merge-closeout-consistency-gate.test.ts +63 -0
  391. package/src/resources/extensions/gsd/tests/merge-db-cycle.test.ts +10 -1
  392. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +3 -3
  393. package/src/resources/extensions/gsd/tests/milestone-closeout.test.ts +9 -1
  394. package/src/resources/extensions/gsd/tests/new-milestone-discuss-routing.test.ts +3 -3
  395. package/src/resources/extensions/gsd/tests/parallel-skill-prompt-integration.test.ts +54 -7
  396. package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +9 -0
  397. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +39 -1
  398. package/src/resources/extensions/gsd/tests/post-unit-hooks.test.ts +157 -0
  399. package/src/resources/extensions/gsd/tests/post-unit-retry-on-orchestrator-bridge.test.ts +179 -0
  400. package/src/resources/extensions/gsd/tests/preferences.test.ts +29 -0
  401. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +83 -1
  402. package/src/resources/extensions/gsd/tests/prompt-loader-extension-dir.test.ts +14 -0
  403. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +18 -1
  404. package/src/resources/extensions/gsd/tests/queued-discuss-fast-path.test.ts +7 -8
  405. package/src/resources/extensions/gsd/tests/reactive-executor.test.ts +36 -0
  406. package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +79 -0
  407. package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +1 -1
  408. package/src/resources/extensions/gsd/tests/rule-registry.test.ts +75 -0
  409. package/src/resources/extensions/gsd/tests/run-uat-composer.test.ts +4 -0
  410. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +36 -0
  411. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +100 -0
  412. package/src/resources/extensions/gsd/tests/skill-activation.test.ts +55 -0
  413. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +6 -2
  414. package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +191 -0
  415. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +84 -10
  416. package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +19 -0
  417. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +12 -2
  418. package/src/resources/extensions/gsd/tests/tool-param-optionality.test.ts +7 -1
  419. package/src/resources/extensions/gsd/tests/tui-header-lifecycle.test.ts +29 -6
  420. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +29 -6
  421. package/src/resources/extensions/gsd/tests/validate-milestone-prompt-verification-classes.test.ts +6 -3
  422. package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +133 -0
  423. package/src/resources/extensions/gsd/tests/validation-block-guard.test.ts +21 -0
  424. package/src/resources/extensions/gsd/tests/verification-gate.test.ts +51 -0
  425. package/src/resources/extensions/gsd/tests/workflow-mcp-auto-prep.test.ts +17 -2
  426. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +493 -0
  427. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +40 -0
  428. package/src/resources/extensions/gsd/tool-contract.ts +6 -0
  429. package/src/resources/extensions/gsd/tool-presentation-plan.ts +223 -0
  430. package/src/resources/extensions/gsd/tools/complete-slice.ts +14 -1
  431. package/src/resources/extensions/gsd/tools/complete-task.ts +20 -2
  432. package/src/resources/extensions/gsd/tools/exec-tool.ts +130 -0
  433. package/src/resources/extensions/gsd/tools/plan-slice.ts +14 -9
  434. package/src/resources/extensions/gsd/tools/reopen-milestone.ts +2 -2
  435. package/src/resources/extensions/gsd/tools/validate-milestone.ts +46 -15
  436. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +589 -8
  437. package/src/resources/extensions/gsd/types.ts +69 -5
  438. package/src/resources/extensions/gsd/unit-context-manifest.ts +14 -5
  439. package/src/resources/extensions/gsd/unit-tool-contracts.ts +186 -0
  440. package/src/resources/extensions/gsd/validation-block-guard.ts +2 -0
  441. package/src/resources/extensions/gsd/verdict-parser.ts +54 -13
  442. package/src/resources/extensions/gsd/verification-gate.ts +87 -1
  443. package/src/resources/extensions/gsd/workflow-mcp-auto-prep.ts +2 -1
  444. package/src/resources/extensions/gsd/workflow-mcp.ts +5 -73
  445. package/src/resources/extensions/gsd/worktree-lifecycle.ts +26 -0
  446. package/src/resources/extensions/mcp-client/manager.ts +33 -1
  447. package/src/resources/extensions/mcp-client/tests/manager.test.ts +35 -0
  448. package/src/resources/extensions/shared/gsd-browser-cli.ts +172 -0
  449. package/src/resources/extensions/gsd/tests/gate-1b-recovery-bound-corrections.test.ts +0 -246
  450. package/src/resources/extensions/gsd/tests/gate-1b-recovery-bound.test.ts +0 -218
  451. /package/dist/web/standalone/.next/static/{L9N5SPFi7f-Ne4u2uXzCe → h4TGni4xJzlZjGkxaT6uU}/_buildManifest.js +0 -0
  452. /package/dist/web/standalone/.next/static/{L9N5SPFi7f-Ne4u2uXzCe → h4TGni4xJzlZjGkxaT6uU}/_ssgManifest.js +0 -0
@@ -0,0 +1,63 @@
1
+ // Project/App: gsd-pi
2
+ // File Purpose: Regression tests for DB-backed closeout consistency before merge.
3
+
4
+ import test from "node:test";
5
+ import assert from "node:assert/strict";
6
+ import { existsSync, mkdtempSync, mkdirSync, realpathSync, rmSync, writeFileSync } from "node:fs";
7
+ import { join } from "node:path";
8
+ import { tmpdir } from "node:os";
9
+ import { execFileSync } from "node:child_process";
10
+
11
+ import { mergeMilestoneToMain } from "../auto-worktree.ts";
12
+ import { closeDatabase, insertMilestone, openDatabase } from "../gsd-db.ts";
13
+
14
+ function git(args: string[], cwd: string): string {
15
+ return execFileSync("git", args, {
16
+ cwd,
17
+ stdio: ["ignore", "pipe", "pipe"],
18
+ encoding: "utf-8",
19
+ }).trim();
20
+ }
21
+
22
+ function createRepo(): string {
23
+ const dir = realpathSync(mkdtempSync(join(tmpdir(), "merge-closeout-gate-")));
24
+ git(["init"], dir);
25
+ git(["config", "user.email", "test@test.com"], dir);
26
+ git(["config", "user.name", "Test"], dir);
27
+ mkdirSync(join(dir, ".gsd"), { recursive: true });
28
+ writeFileSync(join(dir, "README.md"), "# test\n");
29
+ git(["add", "."], dir);
30
+ git(["commit", "-m", "init"], dir);
31
+ git(["branch", "-M", "main"], dir);
32
+
33
+ git(["checkout", "-b", "milestone/M001"], dir);
34
+ writeFileSync(join(dir, "feature.ts"), "export const feature = true;\n");
35
+ git(["add", "feature.ts"], dir);
36
+ git(["commit", "-m", "feat: milestone work"], dir);
37
+ git(["checkout", "main"], dir);
38
+ return dir;
39
+ }
40
+
41
+ test("mergeMilestoneToMain blocks when project DB closeout is still open", () => {
42
+ const savedCwd = process.cwd();
43
+ const repo = createRepo();
44
+ try {
45
+ assert.equal(openDatabase(join(repo, ".gsd", "gsd.db")), true);
46
+ insertMilestone({ id: "M001", title: "Milestone One", status: "active" });
47
+
48
+ const mainHeadBefore = git(["rev-parse", "main"], repo);
49
+ process.chdir(repo);
50
+
51
+ assert.throws(
52
+ () => mergeMilestoneToMain(repo, "M001", "# M001\n- [x] **S01: Done**\n"),
53
+ /closeout-consistency-blocked/,
54
+ );
55
+
56
+ assert.equal(git(["rev-parse", "main"], repo), mainHeadBefore);
57
+ assert.equal(git(["branch", "--show-current"], repo), "main");
58
+ } finally {
59
+ closeDatabase();
60
+ process.chdir(savedCwd);
61
+ if (existsSync(repo)) rmSync(repo, { recursive: true, force: true });
62
+ }
63
+ });
@@ -15,7 +15,7 @@ import { delimiter, join } from "node:path";
15
15
  import { execFileSync } from "node:child_process";
16
16
 
17
17
  import { mergeMilestoneToMain } from "../auto-worktree.ts";
18
- import { closeDatabase, openDatabase } from "../gsd-db.ts";
18
+ import { closeDatabase, insertAssessment, insertMilestone, insertSlice, openDatabase } from "../gsd-db.ts";
19
19
  import { GIT_NO_PROMPT_ENV } from "../git-constants.js";
20
20
  import { _clearGsdRootCache } from "../paths.ts";
21
21
  import { _resetServiceCache } from "../worktree.ts";
@@ -145,6 +145,15 @@ test("mergeMilestoneToMain keeps the Windows DB cycle closed through squash merg
145
145
 
146
146
  withPlatform("win32", () => {
147
147
  assert.equal(openDatabase(join(repo, ".gsd", "gsd.db")), true);
148
+ insertMilestone({ id: "M001", title: "Windows DB cycle", status: "complete" });
149
+ insertSlice({ id: "S01", milestoneId: "M001", title: "Done Slice", status: "complete" });
150
+ insertAssessment({
151
+ path: "milestones/M001/M001-VALIDATION.md",
152
+ milestoneId: "M001",
153
+ status: "pass",
154
+ scope: "milestone-validation",
155
+ fullContent: "verdict: pass",
156
+ });
148
157
  assert.equal(existsSync(join(repo, ".gsd", "gsd.db-shm")), true);
149
158
 
150
159
  process.env.PATH = `${bin}${delimiter}${originalPath}`;
@@ -102,8 +102,8 @@ test("migration auto-check preserves empty DB and reports explicit recovery", as
102
102
  assert.equal(result.action, "recovery-required");
103
103
  assert.equal(result.reason, "db-empty");
104
104
  assert.deepEqual(result.afterDb, { milestones: 0, slices: 0, tasks: 0 });
105
- assert.equal(result.recoveryCommand, "/gsd recover");
106
- assert.match(result.message ?? "", /run `\/gsd recover`/);
105
+ assert.equal(result.recoveryCommand, "/gsd recover --confirm");
106
+ assert.match(result.message ?? "", /run `\/gsd recover --confirm`/);
107
107
  assert.equal(getAllMilestones().length, 0);
108
108
  assert.equal(getSliceTasks("M001", "S01").length, 0);
109
109
  } finally {
@@ -125,7 +125,7 @@ test("migration auto-check preserves DB on hierarchy count mismatch", async () =
125
125
  assert.equal(result.reason, "count-mismatch");
126
126
  assert.deepEqual(result.beforeDb, { milestones: 1, slices: 1, tasks: 0 });
127
127
  assert.deepEqual(result.afterDb, { milestones: 1, slices: 1, tasks: 0 });
128
- assert.equal(result.recoveryCommand, "/gsd recover");
128
+ assert.equal(result.recoveryCommand, "/gsd recover --confirm");
129
129
  assert.equal(getSliceTasks("M001", "S01").length, 0);
130
130
  } finally {
131
131
  cleanup(base);
@@ -6,7 +6,7 @@ import assert from "node:assert/strict";
6
6
  import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from "node:fs";
7
7
  import { join } from "node:path";
8
8
  import { tmpdir } from "node:os";
9
- import { openDatabase, insertMilestone, closeDatabase } from "../gsd-db.js";
9
+ import { openDatabase, insertAssessment, insertMilestone, insertSlice, closeDatabase } from "../gsd-db.js";
10
10
  import {
11
11
  isMilestoneCloseoutSettled,
12
12
  evaluateCompleteMilestoneDispatch,
@@ -39,6 +39,14 @@ test("isMilestoneCloseoutSettled requires DB closed and summary artifact", async
39
39
  mkdirSync(join(base, ".gsd"), { recursive: true });
40
40
  openDatabase(join(base, ".gsd", "gsd.db"));
41
41
  insertMilestone({ id: "M001", title: "Done", status: "complete" });
42
+ insertSlice({ id: "S01", milestoneId: "M001", title: "Done Slice", status: "complete" });
43
+ insertAssessment({
44
+ path: "milestones/M001/M001-VALIDATION.md",
45
+ milestoneId: "M001",
46
+ status: "pass",
47
+ scope: "milestone-validation",
48
+ fullContent: "verdict: pass",
49
+ });
42
50
  const milestoneDir = join(base, ".gsd", "milestones", "M001");
43
51
  mkdirSync(milestoneDir, { recursive: true });
44
52
  writeFileSync(join(milestoneDir, "M001-SUMMARY.md"), "# Milestone Summary\n");
@@ -13,10 +13,10 @@ test("dispatchNewMilestoneDiscuss uses discuss.md only on greenfield projects",
13
13
 
14
14
  assert.match(fnBody, /findMilestoneIds\(basePath\)\.length === 0/);
15
15
  assert.match(fnBody, /prepareAndBuildDiscussPrompt/);
16
- assert.match(fnBody, /loadPrompt\("guided-discuss-milestone"/);
16
+ assert.match(fnBody, /buildDiscussMilestonePrompt/);
17
17
  assert.match(
18
18
  fnBody,
19
- /if \(isGreenfield\)[\s\S]*prepareAndBuildDiscussPrompt[\s\S]*loadPrompt\("guided-discuss-milestone"/,
19
+ /if \(isGreenfield\)[\s\S]*prepareAndBuildDiscussPrompt[\s\S]*buildDiscussMilestonePrompt/,
20
20
  "greenfield branch must precede guided-discuss-milestone branch",
21
21
  );
22
22
  });
@@ -24,7 +24,7 @@ test("dispatchNewMilestoneDiscuss uses discuss.md only on greenfield projects",
24
24
  test("dispatchNewMilestoneDiscuss uses milestone-specific preparation guidance", () => {
25
25
  const source = readFileSync(join(__dirname, "..", "guided-flow.ts"), "utf-8");
26
26
  const fnBody = extractSourceRegion(source, "async function dispatchNewMilestoneDiscuss(");
27
- assert.match(fnBody, /buildDiscussPreparationContext\(ctx, basePath, "milestone"\)/);
27
+ assert.match(fnBody, /buildDiscussPreparationContext\(ctx, basePath, "milestone", true\)/);
28
28
  });
29
29
 
30
30
  test("launchNextMilestoneDiscuss routes through dispatchNewMilestoneDiscuss for normal path", () => {
@@ -22,23 +22,31 @@ import { tmpdir } from "node:os";
22
22
 
23
23
  import { loadSkills } from "@gsd/pi-coding-agent";
24
24
  import {
25
- buildResearchSlicePrompt,
25
+ buildCompleteSlicePrompt,
26
26
  buildParallelResearchSlicesPrompt,
27
+ buildResearchSlicePrompt,
27
28
  } from "../auto-prompts.ts";
28
29
 
29
30
  const SKILL_NAME = "testskill";
31
+ const COMPLETE_SLICE_SKILL_NAME = "complete-slice-policies";
30
32
  const SKILL_ACTIVATION_SUBSTRING = `Call Skill({ skill: '${SKILL_NAME}' })`;
33
+ const COMPLETE_SLICE_SKILL_ACTIVATION_SUBSTRING = `Call Skill({ skill: '${COMPLETE_SLICE_SKILL_NAME}' })`;
31
34
 
32
35
  const tmpDirs: string[] = [];
33
36
  let savedCwd: string | undefined;
34
37
 
35
- function setupProjectWithSkill(): string {
38
+ function setupProjectWithSkill(options: {
39
+ skillName?: string;
40
+ preferencesLines?: string[];
41
+ } = {}): string {
42
+ const skillName = options.skillName ?? SKILL_NAME;
36
43
  const base = mkdtempSync(join(tmpdir(), "gsd-worker-skill-int-"));
37
44
  tmpDirs.push(base);
38
45
 
39
46
  // Milestone roadmap — buildResearchSlicePrompt inlines the roadmap excerpt.
40
47
  const milestoneDir = join(base, ".gsd", "milestones", "M001");
41
- mkdirSync(join(milestoneDir, "slices", "S01"), { recursive: true });
48
+ const sliceOneDir = join(milestoneDir, "slices", "S01");
49
+ mkdirSync(join(sliceOneDir, "tasks"), { recursive: true });
42
50
  mkdirSync(join(milestoneDir, "slices", "S02"), { recursive: true });
43
51
  writeFileSync(
44
52
  join(milestoneDir, "M001-ROADMAP.md"),
@@ -55,27 +63,41 @@ function setupProjectWithSkill(): string {
55
63
  ].join("\n"),
56
64
  "utf-8",
57
65
  );
66
+ writeFileSync(
67
+ join(sliceOneDir, "S01-PLAN.md"),
68
+ [
69
+ "# S01: Alpha",
70
+ "",
71
+ "**Goal:** Verify worker x skill prompt plumbing.",
72
+ "**Demo:** Rendered prompts include the skill activation block.",
73
+ "",
74
+ "## Tasks",
75
+ "- [x] **T01: Task** `est:10m`",
76
+ "",
77
+ ].join("\n"),
78
+ "utf-8",
79
+ );
58
80
 
59
81
  // Project preferences — buildSkillActivationBlock picks these up via
60
82
  // loadEffectiveGSDPreferences(), which reads from `${cwd}/.gsd/PREFERENCES.md`.
61
83
  writeFileSync(
62
84
  join(base, ".gsd", "PREFERENCES.md"),
63
- ["---", `always_use_skills:`, ` - ${SKILL_NAME}`, "---", ""].join("\n"),
85
+ ["---", ...(options.preferencesLines ?? [`always_use_skills:`, ` - ${skillName}`]), "---", ""].join("\n"),
64
86
  "utf-8",
65
87
  );
66
88
 
67
89
  // Project-scoped skill — resolveSkillReference scans `${cwd}/.agents/skills/`.
68
- const skillDir = join(base, ".agents", "skills", SKILL_NAME);
90
+ const skillDir = join(base, ".agents", "skills", skillName);
69
91
  mkdirSync(skillDir, { recursive: true });
70
92
  writeFileSync(
71
93
  join(skillDir, "SKILL.md"),
72
94
  [
73
95
  "---",
74
- `name: ${SKILL_NAME}`,
96
+ `name: ${skillName}`,
75
97
  `description: Integration-test skill for worker × skill prompt plumbing.`,
76
98
  "---",
77
99
  "",
78
- `# ${SKILL_NAME}`,
100
+ `# ${skillName}`,
79
101
  "",
80
102
  "Test skill body.",
81
103
  ].join("\n"),
@@ -122,6 +144,31 @@ test("worker prompt (buildResearchSlicePrompt) includes <skill_activation> from
122
144
  );
123
145
  });
124
146
 
147
+ test("complete-slice prompt includes <skill_activation> from unit-specific skill_rules", async () => {
148
+ const base = setupProjectWithSkill({
149
+ skillName: COMPLETE_SLICE_SKILL_NAME,
150
+ preferencesLines: [
151
+ "skill_rules:",
152
+ " - when: complete-slice",
153
+ " use:",
154
+ ` - ${COMPLETE_SLICE_SKILL_NAME}`,
155
+ ],
156
+ });
157
+ savedCwd = process.cwd();
158
+ process.chdir(base);
159
+
160
+ const prompt = await buildCompleteSlicePrompt("M001", "Test Milestone", "S01", "Alpha", base, "minimal");
161
+
162
+ assert.ok(
163
+ prompt.includes("<skill_activation>"),
164
+ "complete-slice prompt should contain a <skill_activation> block",
165
+ );
166
+ assert.ok(
167
+ prompt.includes(COMPLETE_SLICE_SKILL_ACTIVATION_SUBSTRING),
168
+ `complete-slice prompt should reference the skill-rule skill '${COMPLETE_SLICE_SKILL_NAME}'`,
169
+ );
170
+ });
171
+
125
172
  test("subagent dispatch prompt (buildParallelResearchSlicesPrompt) carries <skill_activation> into each embedded per-slice section", async () => {
126
173
  const base = setupProjectWithSkill();
127
174
  savedCwd = process.cwd();
@@ -83,6 +83,15 @@ test("plan-slice prompt: compact planning gates survive template substitution",
83
83
  assert.ok(!result.includes("{{"));
84
84
  });
85
85
 
86
+ test("plan-slice prompt: absence checks use negated quiet searches", () => {
87
+ const result = loadPrompt("plan-slice", { ...BASE_VARS, commitInstruction: "Do not commit." });
88
+ assert.ok(result.includes("For absence checks"));
89
+ assert.ok(result.includes("`! grep -q 'pattern' file`"));
90
+ assert.ok(result.includes("`! rg -q 'pattern' file`"));
91
+ assert.ok(result.includes("do not use `grep -c` or `rg -c`"));
92
+ assert.ok(result.includes("count commands exit 1 when they find zero matches"));
93
+ });
94
+
86
95
  test("plan-slice prompt: footer references gsd_plan_slice tool, not direct write", () => {
87
96
  const result = loadPrompt("plan-slice", { ...BASE_VARS, commitInstruction: "Do not commit." });
88
97
  assert.ok(
@@ -6,7 +6,7 @@ import { mkdtempSync, mkdirSync, rmSync, readFileSync, existsSync, writeFileSync
6
6
  import { join } from 'node:path';
7
7
  import { tmpdir } from 'node:os';
8
8
 
9
- import { openDatabase, closeDatabase, insertMilestone, insertSlice, getSlice, getSliceTasks, getTask, getGateResults, updateTaskStatus } from '../gsd-db.ts';
9
+ import { openDatabase, closeDatabase, insertMilestone, insertSlice, insertTask, getSlice, getSliceTasks, getTask, getGateResults, updateTaskStatus } from '../gsd-db.ts';
10
10
  import { handlePlanSlice } from '../tools/plan-slice.ts';
11
11
  import { parsePlan } from '../parsers-legacy.ts';
12
12
  import { parseTaskPlanFile } from '../files.ts';
@@ -265,6 +265,44 @@ test('handlePlanSlice renders plan artifacts under worktree-local .gsd while usi
265
265
  }
266
266
  });
267
267
 
268
+ test('handlePlanSlice preserves completed task closeout state when replanning the same task', async () => {
269
+ const base = makeTmpBase();
270
+ openDatabase(join(base, '.gsd', 'gsd.db'));
271
+
272
+ try {
273
+ seedParentSlice();
274
+ insertTask({
275
+ id: 'T01',
276
+ sliceId: 'S02',
277
+ milestoneId: 'M001',
278
+ title: 'Completed implementation',
279
+ status: 'complete',
280
+ oneLiner: 'Completed implementation',
281
+ narrative: 'Already finished.',
282
+ verificationResult: 'passed',
283
+ fullSummaryMd: '# T01 Summary\n\nAlready finished.\n',
284
+ });
285
+
286
+ const before = getTask('M001', 'S02', 'T01');
287
+ assert.equal(before?.status, 'complete');
288
+ assert.ok(before?.completed_at, 'completed task should have a completion timestamp');
289
+ assert.equal(before?.full_summary_md, '# T01 Summary\n\nAlready finished.\n');
290
+
291
+ const result = await handlePlanSlice(validParams(), base);
292
+ assert.ok(!('error' in result), `unexpected error: ${'error' in result ? result.error : ''}`);
293
+
294
+ const after = getTask('M001', 'S02', 'T01');
295
+ assert.equal(after?.status, 'complete', 'replanning must not reset completed task status to pending');
296
+ assert.equal(after?.completed_at, before?.completed_at, 'replanning must not clear completed_at');
297
+ assert.equal(after?.full_summary_md, before?.full_summary_md, 'replanning must not clear task summary content');
298
+ assert.equal(after?.verification_result, 'passed', 'replanning must not clear closeout verification');
299
+ assert.equal(after?.description, 'Implement the slice planning handler.', 'planning fields should still refresh');
300
+ assert.equal(getTask('M001', 'S02', 'T02')?.status, 'pending', 'new tasks are still inserted as pending');
301
+ } finally {
302
+ cleanup(base);
303
+ }
304
+ });
305
+
268
306
  test('handlePlanSlice advances DB-derived state out of planning immediately', async () => {
269
307
  const base = makeTmpBase();
270
308
  openDatabase(join(base, '.gsd', 'gsd.db'));
@@ -11,6 +11,7 @@ import {
11
11
  resetHookState,
12
12
  isRetryPending,
13
13
  consumeRetryTrigger,
14
+ consumeGateBlock,
14
15
  resolveHookArtifactPath,
15
16
  runPreDispatchHooks,
16
17
  persistHookState,
@@ -20,6 +21,7 @@ import {
20
21
  formatHookStatus,
21
22
  triggerHookManually,
22
23
  } from "../post-unit-hooks.ts";
24
+ import { invalidateAllCaches } from "../cache.ts";
23
25
 
24
26
  // ─── Fixture Helpers ───────────────────────────────────────────────────────
25
27
 
@@ -29,6 +31,11 @@ function createFixtureBase(): string {
29
31
  return base;
30
32
  }
31
33
 
34
+ function writeHookPreferences(base: string, hookYaml: string): void {
35
+ writeFileSync(join(base, ".gsd", "PREFERENCES.md"), `---\npost_unit_hooks:\n${hookYaml}\n---\n`, "utf-8");
36
+ invalidateAllCaches();
37
+ }
38
+
32
39
  // ═══════════════════════════════════════════════════════════════════════════
33
40
  // Phase 1: Post-Unit Hook Tests
34
41
  // ═══════════════════════════════════════════════════════════════════════════
@@ -104,6 +111,156 @@ test('consumeRetryTrigger clears state', () => {
104
111
  assert.ok(!isRetryPending(), "no retry initially");
105
112
  });
106
113
 
114
+ test('Advisory hook keeps artifact idempotency without verdict frontmatter', () => {
115
+ resetHookState();
116
+ const base = createFixtureBase();
117
+ try {
118
+ writeHookPreferences(base, ` - name: docs-hint
119
+ after:
120
+ - execute-task
121
+ prompt: Review docs
122
+ artifact: DOCS-HINT.md
123
+ `);
124
+ writeFileSync(resolveHookArtifactPath(base, "M001/S01/T01", "DOCS-HINT.md"), "plain advisory note", "utf-8");
125
+
126
+ const result = checkPostUnitHooks("execute-task", "M001/S01/T01", base);
127
+ assert.deepStrictEqual(result, null, "existing advisory artifact remains idempotent");
128
+ assert.deepStrictEqual(consumeGateBlock(), null, "advisory hook does not create gate block");
129
+ } finally {
130
+ resetHookState();
131
+ invalidateAllCaches();
132
+ rmSync(base, { recursive: true, force: true });
133
+ }
134
+ });
135
+
136
+ test('Blocking hook skips only after passing frontmatter verdict', () => {
137
+ resetHookState();
138
+ const base = createFixtureBase();
139
+ try {
140
+ writeHookPreferences(base, ` - name: security-review
141
+ after:
142
+ - execute-task
143
+ prompt: Review security
144
+ artifact: SECURITY-REVIEW.md
145
+ criticality: blocking
146
+ `);
147
+ writeFileSync(
148
+ resolveHookArtifactPath(base, "M001/S01/T01", "SECURITY-REVIEW.md"),
149
+ "---\nverdict: pass\n---\n\nNo blocking findings.\n",
150
+ "utf-8",
151
+ );
152
+
153
+ const result = checkPostUnitHooks("execute-task", "M001/S01/T01", base);
154
+ assert.deepStrictEqual(result, null, "passing gate artifact is idempotent");
155
+ assert.deepStrictEqual(consumeGateBlock(), null, "passing gate does not block");
156
+ } finally {
157
+ resetHookState();
158
+ invalidateAllCaches();
159
+ rmSync(base, { recursive: true, force: true });
160
+ }
161
+ });
162
+
163
+ test('Blocking hook reruns invalid artifact once then blocks at cycle budget', () => {
164
+ resetHookState();
165
+ const base = createFixtureBase();
166
+ try {
167
+ writeHookPreferences(base, ` - name: security-review
168
+ after:
169
+ - execute-task
170
+ prompt: Review security
171
+ artifact: SECURITY-REVIEW.md
172
+ criticality: blocking
173
+ `);
174
+ writeFileSync(resolveHookArtifactPath(base, "M001/S01/T01", "SECURITY-REVIEW.md"), "partial output", "utf-8");
175
+
176
+ const dispatch = checkPostUnitHooks("execute-task", "M001/S01/T01", base);
177
+ assert.ok(dispatch, "invalid gate artifact dispatches the blocking hook");
178
+ assert.equal(dispatch.unitType, "hook/security-review");
179
+
180
+ const afterHook = checkPostUnitHooks("hook/security-review", "M001/S01/T01", base);
181
+ assert.deepStrictEqual(afterHook, null, "no further hook dispatch after max_cycles=1");
182
+ const block = consumeGateBlock();
183
+ assert.ok(block, "gate block is recorded");
184
+ assert.equal(block.hookName, "security-review");
185
+ assert.match(block.reason, /missing frontmatter verdict/);
186
+ } finally {
187
+ resetHookState();
188
+ invalidateAllCaches();
189
+ rmSync(base, { recursive: true, force: true });
190
+ }
191
+ });
192
+
193
+ test('Blocking hook restored from disk does not trust artifact without clean hook completion', () => {
194
+ resetHookState();
195
+ const base = createFixtureBase();
196
+ try {
197
+ writeHookPreferences(base, ` - name: security-review
198
+ after:
199
+ - execute-task
200
+ prompt: Review security
201
+ artifact: SECURITY-REVIEW.md
202
+ criticality: blocking
203
+ max_cycles: 2
204
+ `);
205
+ const firstDispatch = checkPostUnitHooks("execute-task", "M001/S01/T01", base);
206
+ assert.ok(firstDispatch, "gate dispatches first cycle");
207
+ persistHookState(base);
208
+
209
+ writeFileSync(
210
+ resolveHookArtifactPath(base, "M001/S01/T01", "SECURITY-REVIEW.md"),
211
+ "---\noutcome:\n verdict: pass\n---\n",
212
+ "utf-8",
213
+ );
214
+
215
+ resetHookState();
216
+ restoreHookState(base);
217
+
218
+ const resumed = checkPostUnitHooks("execute-task", "M001/S01/T01", base);
219
+ assert.ok(resumed, "persisted active gate reruns when clean hook completion was not observed");
220
+ assert.equal(resumed.unitType, "hook/security-review");
221
+ } finally {
222
+ resetHookState();
223
+ invalidateAllCaches();
224
+ rmSync(base, { recursive: true, force: true });
225
+ }
226
+ });
227
+
228
+ test('Blocking hook needs-rework verdict requests trigger unit retry', () => {
229
+ resetHookState();
230
+ const base = createFixtureBase();
231
+ try {
232
+ writeHookPreferences(base, ` - name: review-arbiter
233
+ after:
234
+ - execute-task
235
+ prompt: Review task
236
+ artifact: REVIEW-DEBATE.md
237
+ criticality: blocking
238
+ max_cycles: 2
239
+ on_block:
240
+ action: retry-unit
241
+ `);
242
+ const dispatch = checkPostUnitHooks("execute-task", "M001/S01/T01", base);
243
+ assert.ok(dispatch, "gate dispatches");
244
+ writeFileSync(
245
+ resolveHookArtifactPath(base, "M001/S01/T01", "REVIEW-DEBATE.md"),
246
+ "---\nverdict: needs-rework\n---\n\nRework required.\n",
247
+ "utf-8",
248
+ );
249
+
250
+ const afterHook = checkPostUnitHooks("hook/review-arbiter", "M001/S01/T01", base);
251
+ assert.deepStrictEqual(afterHook, null, "needs-rework routes via retry signal");
252
+ assert.ok(isRetryPending(), "retry is pending");
253
+ assert.deepStrictEqual(consumeRetryTrigger(), {
254
+ unitType: "execute-task",
255
+ unitId: "M001/S01/T01",
256
+ });
257
+ } finally {
258
+ resetHookState();
259
+ invalidateAllCaches();
260
+ rmSync(base, { recursive: true, force: true });
261
+ }
262
+ });
263
+
107
264
  // ─── Variable substitution in prompts ──────────────────────────────────────
108
265
  test('Variable substitution', () => {
109
266
  const base = "/project";