gsd-pi 2.80.0-dev.42bd34838 → 2.80.0-dev.488219eb6

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 (509) hide show
  1. package/dist/claude-cli-check.d.ts +30 -0
  2. package/dist/claude-cli-check.js +18 -7
  3. package/dist/cli.js +0 -19
  4. package/dist/headless-query.d.ts +10 -0
  5. package/dist/headless-query.js +6 -4
  6. package/dist/loader-entrypoint.d.ts +8 -0
  7. package/dist/loader-entrypoint.js +27 -0
  8. package/dist/loader.js +2 -11
  9. package/dist/mcp-server.d.ts +1 -0
  10. package/dist/mcp-server.js +6 -3
  11. package/dist/resources/.managed-resources-content-hash +1 -1
  12. package/dist/resources/extensions/claude-code-cli/readiness.js +18 -7
  13. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +29 -0
  14. package/dist/resources/extensions/github-sync/sync.js +4 -1
  15. package/dist/resources/extensions/gsd/auto/loop.js +71 -8
  16. package/dist/resources/extensions/gsd/auto/phases.js +179 -99
  17. package/dist/resources/extensions/gsd/auto/resolve.js +12 -0
  18. package/dist/resources/extensions/gsd/auto/run-unit.js +10 -30
  19. package/dist/resources/extensions/gsd/auto/session.js +8 -0
  20. package/dist/resources/extensions/gsd/auto/workflow-dispatch-claim.js +33 -1
  21. package/dist/resources/extensions/gsd/auto/workflow-worker-heartbeat.js +9 -1
  22. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +5 -32
  23. package/dist/resources/extensions/gsd/auto-dispatch.js +16 -0
  24. package/dist/resources/extensions/gsd/auto-post-unit.js +94 -76
  25. package/dist/resources/extensions/gsd/auto-prompts.js +90 -15
  26. package/dist/resources/extensions/gsd/auto-start.js +238 -12
  27. package/dist/resources/extensions/gsd/auto-worktree.js +209 -81
  28. package/dist/resources/extensions/gsd/auto.js +95 -44
  29. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +96 -26
  30. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +44 -37
  31. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +37 -10
  32. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +6 -3
  33. package/dist/resources/extensions/gsd/bootstrap/journal-tools.js +4 -1
  34. package/dist/resources/extensions/gsd/bootstrap/memory-tools.js +6 -4
  35. package/dist/resources/extensions/gsd/bootstrap/query-tools.js +5 -3
  36. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +1 -1
  37. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +298 -54
  38. package/dist/resources/extensions/gsd/bootstrap/sanitize-complete-milestone.js +4 -0
  39. package/dist/resources/extensions/gsd/bootstrap/system-context.js +82 -23
  40. package/dist/resources/extensions/gsd/clean-root-preflight.js +24 -6
  41. package/dist/resources/extensions/gsd/commands/handlers/ops.js +2 -2
  42. package/dist/resources/extensions/gsd/commands-config.js +1 -1
  43. package/dist/resources/extensions/gsd/commands-eval-review.js +2 -2
  44. package/dist/resources/extensions/gsd/commands-handlers.js +23 -9
  45. package/dist/resources/extensions/gsd/dashboard-overlay.js +1 -1
  46. package/dist/resources/extensions/gsd/db/unit-dispatches.js +53 -0
  47. package/dist/resources/extensions/gsd/ecosystem/gsd-extension-api.js +2 -0
  48. package/dist/resources/extensions/gsd/git-service.js +37 -1
  49. package/dist/resources/extensions/gsd/guided-flow.js +61 -32
  50. package/dist/resources/extensions/gsd/init-wizard.js +4 -1
  51. package/dist/resources/extensions/gsd/native-git-bridge.js +32 -8
  52. package/dist/resources/extensions/gsd/orphan-stash-audit.js +101 -0
  53. package/dist/resources/extensions/gsd/parallel-orchestrator.js +13 -3
  54. package/dist/resources/extensions/gsd/pre-execution-checks.js +22 -0
  55. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +8 -4
  56. package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  57. package/dist/resources/extensions/gsd/prompts/execute-task.md +4 -2
  58. package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  59. package/dist/resources/extensions/gsd/prompts/replan-slice.md +2 -2
  60. package/dist/resources/extensions/gsd/slice-cadence.js +45 -2
  61. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +15 -9
  62. package/dist/resources/extensions/gsd/tools/complete-milestone.js +6 -7
  63. package/dist/resources/extensions/gsd/tools/complete-task.js +1 -1
  64. package/dist/resources/extensions/gsd/workflow-protocol.js +131 -0
  65. package/dist/resources/extensions/gsd/worktree-resolver.js +57 -5
  66. package/dist/resources/skills/web-quality-audit/scripts/analyze.sh +0 -0
  67. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  68. package/dist/web/standalone/.next/BUILD_ID +1 -1
  69. package/dist/web/standalone/.next/app-path-routes-manifest.json +11 -11
  70. package/dist/web/standalone/.next/build-manifest.json +3 -3
  71. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  72. package/dist/web/standalone/.next/react-loadable-manifest.json +2 -2
  73. package/dist/web/standalone/.next/required-server-files.json +1 -1
  74. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  75. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  76. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  77. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  78. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  79. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  80. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  81. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  82. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  83. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  84. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  85. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  86. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  87. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  88. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  89. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  90. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  91. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  92. package/dist/web/standalone/.next/server/app/index.html +1 -1
  93. package/dist/web/standalone/.next/server/app/index.rsc +2 -2
  94. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  95. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +2 -2
  96. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  97. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  98. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  99. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  100. package/dist/web/standalone/.next/server/app-paths-manifest.json +11 -11
  101. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  102. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  103. package/dist/web/standalone/.next/server/middleware.js +3 -3
  104. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  105. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  106. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  107. package/dist/web/standalone/.next/static/chunks/8359.e059d86b255fce1c.js +10 -0
  108. package/dist/web/standalone/.next/static/chunks/app/{page-fab3ebb85b006001.js → page-752f1e2ebdaa3e45.js} +1 -1
  109. package/dist/web/standalone/.next/static/chunks/{webpack-0481f1221120a7c6.js → webpack-de742b64187e13fe.js} +1 -1
  110. package/dist/web/standalone/server.js +1 -1
  111. package/dist/welcome-screen.d.ts +2 -0
  112. package/dist/welcome-screen.js +9 -7
  113. package/package.json +1 -1
  114. package/packages/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  115. package/packages/pi-agent-core/dist/agent-loop.js +4 -1
  116. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  117. package/packages/pi-agent-core/dist/agent.d.ts +5 -0
  118. package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
  119. package/packages/pi-agent-core/dist/agent.js +2 -0
  120. package/packages/pi-agent-core/dist/agent.js.map +1 -1
  121. package/packages/pi-agent-core/dist/index.d.ts +1 -0
  122. package/packages/pi-agent-core/dist/index.d.ts.map +1 -1
  123. package/packages/pi-agent-core/dist/index.js +2 -0
  124. package/packages/pi-agent-core/dist/index.js.map +1 -1
  125. package/packages/pi-agent-core/dist/token-audit.d.ts +47 -0
  126. package/packages/pi-agent-core/dist/token-audit.d.ts.map +1 -0
  127. package/packages/pi-agent-core/dist/token-audit.js +221 -0
  128. package/packages/pi-agent-core/dist/token-audit.js.map +1 -0
  129. package/packages/pi-agent-core/dist/types.d.ts +9 -0
  130. package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
  131. package/packages/pi-agent-core/dist/types.js.map +1 -1
  132. package/packages/pi-agent-core/src/agent-loop.test.ts +128 -0
  133. package/packages/pi-agent-core/src/agent-loop.ts +4 -1
  134. package/packages/pi-agent-core/src/agent.ts +8 -0
  135. package/packages/pi-agent-core/src/index.ts +2 -0
  136. package/packages/pi-agent-core/src/token-audit.test.ts +189 -0
  137. package/packages/pi-agent-core/src/token-audit.ts +287 -0
  138. package/packages/pi-agent-core/src/types.ts +14 -0
  139. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  140. package/packages/pi-ai/dist/providers/anthropic-auth.test.js +35 -13
  141. package/packages/pi-ai/dist/providers/anthropic-auth.test.js.map +1 -1
  142. package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.js +21 -11
  143. package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.js.map +1 -1
  144. package/packages/pi-ai/dist/providers/anthropic.d.ts +7 -0
  145. package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  146. package/packages/pi-ai/dist/providers/anthropic.js +9 -7
  147. package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
  148. package/packages/pi-ai/dist/providers/minimax-tool-name.test.js +23 -14
  149. package/packages/pi-ai/dist/providers/minimax-tool-name.test.js.map +1 -1
  150. package/packages/pi-ai/dist/utils/oauth/github-copilot.test.js +48 -21
  151. package/packages/pi-ai/dist/utils/oauth/github-copilot.test.js.map +1 -1
  152. package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.js +22 -21
  153. package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.js.map +1 -1
  154. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.js +22 -21
  155. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.js.map +1 -1
  156. package/packages/pi-ai/src/providers/anthropic-auth.test.ts +39 -25
  157. package/packages/pi-ai/src/providers/anthropic-bearer-auth.test.ts +26 -22
  158. package/packages/pi-ai/src/providers/anthropic.ts +22 -9
  159. package/packages/pi-ai/src/providers/minimax-tool-name.test.ts +34 -21
  160. package/packages/pi-ai/src/utils/oauth/github-copilot.test.ts +56 -22
  161. package/packages/pi-ai/src/utils/oauth/google-antigravity.test.ts +24 -28
  162. package/packages/pi-ai/src/utils/oauth/google-gemini-cli.test.ts +24 -28
  163. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  164. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js +18 -0
  165. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js.map +1 -1
  166. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +12 -0
  167. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  168. package/packages/pi-coding-agent/dist/core/agent-session.js +36 -7
  169. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  170. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +3 -1
  171. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
  172. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  173. package/packages/pi-coding-agent/dist/core/extensions/loader.js +8 -0
  174. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  175. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +2 -0
  176. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
  177. package/packages/pi-coding-agent/dist/core/extensions/runner.js +3 -6
  178. package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
  179. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +3 -3
  180. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js.map +1 -1
  181. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +34 -3
  182. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  183. package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  184. package/packages/pi-coding-agent/dist/core/hooks-runner.test.js +2 -0
  185. package/packages/pi-coding-agent/dist/core/hooks-runner.test.js.map +1 -1
  186. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.d.ts +2 -0
  187. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.d.ts.map +1 -0
  188. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.js +46 -0
  189. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.js.map +1 -0
  190. package/packages/pi-coding-agent/dist/core/sdk.d.ts +10 -2
  191. package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
  192. package/packages/pi-coding-agent/dist/core/sdk.js +74 -2
  193. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  194. package/packages/pi-coding-agent/dist/core/skill-tool.test.js +22 -0
  195. package/packages/pi-coding-agent/dist/core/skill-tool.test.js.map +1 -1
  196. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts +6 -7
  197. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
  198. package/packages/pi-coding-agent/dist/core/system-prompt.js +2 -3
  199. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  200. package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.js +22 -56
  201. package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.js.map +1 -1
  202. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts +1 -0
  203. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts.map +1 -1
  204. package/packages/pi-coding-agent/dist/core/tools/bash.js +3 -1
  205. package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
  206. package/packages/pi-coding-agent/dist/core/tools/edit.d.ts +2 -0
  207. package/packages/pi-coding-agent/dist/core/tools/edit.d.ts.map +1 -1
  208. package/packages/pi-coding-agent/dist/core/tools/edit.js +12 -1
  209. package/packages/pi-coding-agent/dist/core/tools/edit.js.map +1 -1
  210. package/packages/pi-coding-agent/dist/core/tools/find.d.ts +2 -0
  211. package/packages/pi-coding-agent/dist/core/tools/find.d.ts.map +1 -1
  212. package/packages/pi-coding-agent/dist/core/tools/find.js +14 -6
  213. package/packages/pi-coding-agent/dist/core/tools/find.js.map +1 -1
  214. package/packages/pi-coding-agent/dist/core/tools/grep.d.ts +2 -0
  215. package/packages/pi-coding-agent/dist/core/tools/grep.d.ts.map +1 -1
  216. package/packages/pi-coding-agent/dist/core/tools/grep.js +12 -3
  217. package/packages/pi-coding-agent/dist/core/tools/grep.js.map +1 -1
  218. package/packages/pi-coding-agent/dist/core/tools/hashline-read.d.ts +2 -0
  219. package/packages/pi-coding-agent/dist/core/tools/hashline-read.d.ts.map +1 -1
  220. package/packages/pi-coding-agent/dist/core/tools/hashline-read.js +3 -1
  221. package/packages/pi-coding-agent/dist/core/tools/hashline-read.js.map +1 -1
  222. package/packages/pi-coding-agent/dist/core/tools/index.d.ts +2 -1
  223. package/packages/pi-coding-agent/dist/core/tools/index.d.ts.map +1 -1
  224. package/packages/pi-coding-agent/dist/core/tools/index.js +1 -0
  225. package/packages/pi-coding-agent/dist/core/tools/index.js.map +1 -1
  226. package/packages/pi-coding-agent/dist/core/tools/ls.d.ts +2 -0
  227. package/packages/pi-coding-agent/dist/core/tools/ls.d.ts.map +1 -1
  228. package/packages/pi-coding-agent/dist/core/tools/ls.js +10 -3
  229. package/packages/pi-coding-agent/dist/core/tools/ls.js.map +1 -1
  230. package/packages/pi-coding-agent/dist/core/tools/read.d.ts +2 -0
  231. package/packages/pi-coding-agent/dist/core/tools/read.d.ts.map +1 -1
  232. package/packages/pi-coding-agent/dist/core/tools/read.js +3 -1
  233. package/packages/pi-coding-agent/dist/core/tools/read.js.map +1 -1
  234. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js +7 -62
  235. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js.map +1 -1
  236. package/packages/pi-coding-agent/dist/core/tools/tool-target-metadata.test.d.ts +2 -0
  237. package/packages/pi-coding-agent/dist/core/tools/tool-target-metadata.test.d.ts.map +1 -0
  238. package/packages/pi-coding-agent/dist/core/tools/tool-target-metadata.test.js +115 -0
  239. package/packages/pi-coding-agent/dist/core/tools/tool-target-metadata.test.js.map +1 -0
  240. package/packages/pi-coding-agent/dist/core/tools/tool-target.d.ts +19 -0
  241. package/packages/pi-coding-agent/dist/core/tools/tool-target.d.ts.map +1 -0
  242. package/packages/pi-coding-agent/dist/core/tools/tool-target.js +20 -0
  243. package/packages/pi-coding-agent/dist/core/tools/tool-target.js.map +1 -0
  244. package/packages/pi-coding-agent/dist/core/tools/write.d.ts +4 -0
  245. package/packages/pi-coding-agent/dist/core/tools/write.d.ts.map +1 -1
  246. package/packages/pi-coding-agent/dist/core/tools/write.js +9 -1
  247. package/packages/pi-coding-agent/dist/core/tools/write.js.map +1 -1
  248. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +89 -2
  249. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
  250. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js +25 -1
  251. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js.map +1 -1
  252. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +5 -0
  253. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  254. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +153 -8
  255. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  256. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  257. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +18 -1
  258. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  259. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js +23 -5
  260. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js.map +1 -1
  261. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +2 -0
  262. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  263. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +19 -0
  264. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  265. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.js +23 -5
  266. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.js.map +1 -1
  267. package/packages/pi-coding-agent/src/core/agent-session-tool-refresh.test.ts +25 -0
  268. package/packages/pi-coding-agent/src/core/agent-session.ts +40 -7
  269. package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +3 -1
  270. package/packages/pi-coding-agent/src/core/extensions/loader.ts +10 -0
  271. package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +3 -3
  272. package/packages/pi-coding-agent/src/core/extensions/runner.ts +5 -5
  273. package/packages/pi-coding-agent/src/core/extensions/types.ts +37 -2
  274. package/packages/pi-coding-agent/src/core/hooks-runner.test.ts +2 -0
  275. package/packages/pi-coding-agent/src/core/sdk-tool-filter.test.ts +60 -0
  276. package/packages/pi-coding-agent/src/core/sdk.ts +85 -3
  277. package/packages/pi-coding-agent/src/core/skill-tool.test.ts +28 -0
  278. package/packages/pi-coding-agent/src/core/system-prompt.ts +8 -10
  279. package/packages/pi-coding-agent/src/core/tools/bash-spawn-windows.test.ts +22 -66
  280. package/packages/pi-coding-agent/src/core/tools/bash.ts +4 -1
  281. package/packages/pi-coding-agent/src/core/tools/edit.ts +13 -1
  282. package/packages/pi-coding-agent/src/core/tools/find.ts +15 -6
  283. package/packages/pi-coding-agent/src/core/tools/grep.ts +13 -3
  284. package/packages/pi-coding-agent/src/core/tools/hashline-read.ts +4 -1
  285. package/packages/pi-coding-agent/src/core/tools/index.ts +8 -0
  286. package/packages/pi-coding-agent/src/core/tools/ls.ts +11 -3
  287. package/packages/pi-coding-agent/src/core/tools/read.ts +4 -1
  288. package/packages/pi-coding-agent/src/core/tools/spawn-shell-windows.test.ts +11 -72
  289. package/packages/pi-coding-agent/src/core/tools/tool-target-metadata.test.ts +127 -0
  290. package/packages/pi-coding-agent/src/core/tools/tool-target.ts +48 -0
  291. package/packages/pi-coding-agent/src/core/tools/write.ts +14 -2
  292. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +119 -2
  293. package/packages/pi-coding-agent/src/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.ts +31 -1
  294. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +177 -8
  295. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.test.ts +24 -5
  296. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +17 -1
  297. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +21 -0
  298. package/packages/pi-coding-agent/src/resources/extensions/memory/storage-safety-guard.test.ts +25 -8
  299. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  300. package/src/resources/extensions/claude-code-cli/readiness.ts +25 -7
  301. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +30 -0
  302. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +26 -0
  303. package/src/resources/extensions/github-sync/sync.ts +8 -1
  304. package/src/resources/extensions/github-sync/tests/sync-source.test.ts +6 -18
  305. package/src/resources/extensions/gsd/auto/loop-deps.ts +2 -2
  306. package/src/resources/extensions/gsd/auto/loop.ts +84 -8
  307. package/src/resources/extensions/gsd/auto/phases.ts +258 -159
  308. package/src/resources/extensions/gsd/auto/resolve.ts +19 -0
  309. package/src/resources/extensions/gsd/auto/run-unit.ts +10 -29
  310. package/src/resources/extensions/gsd/auto/session.ts +8 -0
  311. package/src/resources/extensions/gsd/auto/workflow-dispatch-claim.ts +63 -1
  312. package/src/resources/extensions/gsd/auto/workflow-worker-heartbeat.ts +14 -1
  313. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +8 -34
  314. package/src/resources/extensions/gsd/auto-dispatch.ts +16 -0
  315. package/src/resources/extensions/gsd/auto-post-unit.ts +107 -78
  316. package/src/resources/extensions/gsd/auto-prompts.ts +95 -14
  317. package/src/resources/extensions/gsd/auto-start.ts +286 -15
  318. package/src/resources/extensions/gsd/auto-worktree.ts +241 -72
  319. package/src/resources/extensions/gsd/auto.ts +132 -40
  320. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +116 -24
  321. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +45 -37
  322. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +36 -10
  323. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +8 -3
  324. package/src/resources/extensions/gsd/bootstrap/journal-tools.ts +5 -1
  325. package/src/resources/extensions/gsd/bootstrap/memory-tools.ts +7 -4
  326. package/src/resources/extensions/gsd/bootstrap/query-tools.ts +6 -3
  327. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +1 -1
  328. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +347 -54
  329. package/src/resources/extensions/gsd/bootstrap/sanitize-complete-milestone.ts +4 -0
  330. package/src/resources/extensions/gsd/bootstrap/system-context.ts +90 -22
  331. package/src/resources/extensions/gsd/clean-root-preflight.ts +32 -7
  332. package/src/resources/extensions/gsd/commands/handlers/ops.ts +4 -2
  333. package/src/resources/extensions/gsd/commands-config.ts +1 -1
  334. package/src/resources/extensions/gsd/commands-eval-review.ts +2 -2
  335. package/src/resources/extensions/gsd/commands-handlers.ts +34 -15
  336. package/src/resources/extensions/gsd/dashboard-overlay.ts +1 -1
  337. package/src/resources/extensions/gsd/db/unit-dispatches.ts +66 -0
  338. package/src/resources/extensions/gsd/ecosystem/gsd-extension-api.ts +3 -0
  339. package/src/resources/extensions/gsd/git-service.ts +41 -2
  340. package/src/resources/extensions/gsd/guided-flow.ts +71 -39
  341. package/src/resources/extensions/gsd/init-wizard.ts +5 -1
  342. package/src/resources/extensions/gsd/native-git-bridge.ts +39 -6
  343. package/src/resources/extensions/gsd/orphan-stash-audit.ts +117 -0
  344. package/src/resources/extensions/gsd/parallel-orchestrator.ts +13 -3
  345. package/src/resources/extensions/gsd/pre-execution-checks.ts +23 -0
  346. package/src/resources/extensions/gsd/prompts/complete-milestone.md +8 -4
  347. package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  348. package/src/resources/extensions/gsd/prompts/execute-task.md +4 -2
  349. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  350. package/src/resources/extensions/gsd/prompts/replan-slice.md +2 -2
  351. package/src/resources/extensions/gsd/slice-cadence.ts +49 -2
  352. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +23 -9
  353. package/src/resources/extensions/gsd/tests/agent-end-retry.test.ts +59 -89
  354. package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +47 -172
  355. package/src/resources/extensions/gsd/tests/artifacts-table-preserved-on-cache-invalidate.test.ts +0 -35
  356. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +35 -9
  357. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +361 -10
  358. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +80 -59
  359. package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +3 -47
  360. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +76 -18
  361. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +106 -0
  362. package/src/resources/extensions/gsd/tests/auto-pr-bugs.test.ts +54 -95
  363. package/src/resources/extensions/gsd/tests/auto-project-root-env.test.ts +67 -26
  364. package/src/resources/extensions/gsd/tests/auto-remediate-slice-status.test.ts +32 -30
  365. package/src/resources/extensions/gsd/tests/auto-start-bootstrap-await-3420.test.ts +32 -128
  366. package/src/resources/extensions/gsd/tests/auto-start-clean-runtime-db-gated.test.ts +20 -54
  367. package/src/resources/extensions/gsd/tests/auto-start-cold-db-bootstrap.test.ts +20 -30
  368. package/src/resources/extensions/gsd/tests/auto-start-index-lock.test.ts +17 -29
  369. package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +138 -0
  370. package/src/resources/extensions/gsd/tests/auto-start-time-persistence.test.ts +21 -39
  371. package/src/resources/extensions/gsd/tests/auto-start-worktree-db-path.test.ts +15 -24
  372. package/src/resources/extensions/gsd/tests/auto-thinking-restore.test.ts +44 -29
  373. package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +39 -51
  374. package/src/resources/extensions/gsd/tests/auto-wrapup-inflight-guard.test.ts +159 -213
  375. package/src/resources/extensions/gsd/tests/bootstrap-derive-state-db-open.test.ts +15 -32
  376. package/src/resources/extensions/gsd/tests/browser-teardown.test.ts +0 -41
  377. package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +15 -6
  378. package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +34 -27
  379. package/src/resources/extensions/gsd/tests/cmux.test.ts +51 -53
  380. package/src/resources/extensions/gsd/tests/cold-resume-db-reopen.test.ts +39 -61
  381. package/src/resources/extensions/gsd/tests/commands-config.test.ts +26 -19
  382. package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +31 -0
  383. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +140 -0
  384. package/src/resources/extensions/gsd/tests/complete-slice-composer.test.ts +3 -2
  385. package/src/resources/extensions/gsd/tests/complete-task-normalize-lists.test.ts +29 -33
  386. package/src/resources/extensions/gsd/tests/completed-units-metrics-sync.test.ts +45 -108
  387. package/src/resources/extensions/gsd/tests/context-store.test.ts +7 -1
  388. package/src/resources/extensions/gsd/tests/crash-handler-secondary.test.ts +35 -31
  389. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +5 -1
  390. package/src/resources/extensions/gsd/tests/cwd-fallback-hardening.test.ts +138 -0
  391. package/src/resources/extensions/gsd/tests/dashboard-custom-engine.test.ts +4 -68
  392. package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +4 -9
  393. package/src/resources/extensions/gsd/tests/deferred-milestone-dir-4996.test.ts +14 -65
  394. package/src/resources/extensions/gsd/tests/discuss-tool-scoping.test.ts +44 -37
  395. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +58 -40
  396. package/src/resources/extensions/gsd/tests/dispatch-guard-closed-status.test.ts +25 -15
  397. package/src/resources/extensions/gsd/tests/dispatcher-stuck-planning.test.ts +35 -17
  398. package/src/resources/extensions/gsd/tests/error-success-mask.test.ts +16 -21
  399. package/src/resources/extensions/gsd/tests/est-annotation-timeout.test.ts +15 -82
  400. package/src/resources/extensions/gsd/tests/execute-task-rendering.test.ts +5 -2
  401. package/src/resources/extensions/gsd/tests/fast-forward-reused-milestone-branch.test.ts +219 -0
  402. package/src/resources/extensions/gsd/tests/finalize-survivor-branch.test.ts +132 -0
  403. package/src/resources/extensions/gsd/tests/flat-rate-routing-guard.test.ts +2 -20
  404. package/src/resources/extensions/gsd/tests/frontmatter-parse-noise.test.ts +18 -26
  405. package/src/resources/extensions/gsd/tests/init-skip-git.test.ts +9 -12
  406. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +40 -0
  407. package/src/resources/extensions/gsd/tests/integration/commands-eval-review.integration.test.ts +4 -2
  408. package/src/resources/extensions/gsd/tests/integration/git-locale.test.ts +31 -20
  409. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +12 -0
  410. package/src/resources/extensions/gsd/tests/integration/milestone-transition-worktree.test.ts +0 -47
  411. package/src/resources/extensions/gsd/tests/interactive-routing-bypass.test.ts +60 -202
  412. package/src/resources/extensions/gsd/tests/isolation-none-branch-guard.test.ts +13 -56
  413. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +5 -1
  414. package/src/resources/extensions/gsd/tests/journal-query-tool.test.ts +32 -0
  415. package/src/resources/extensions/gsd/tests/knowledge.test.ts +47 -0
  416. package/src/resources/extensions/gsd/tests/lazy-pi-tui-import.test.ts +44 -6
  417. package/src/resources/extensions/gsd/tests/memory-pressure-stuck-state.test.ts +21 -35
  418. package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +1 -0
  419. package/src/resources/extensions/gsd/tests/milestone-merge-stash-restore.test.ts +242 -0
  420. package/src/resources/extensions/gsd/tests/milestone-transition-state-rebuild.test.ts +79 -98
  421. package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +70 -278
  422. package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +34 -2
  423. package/src/resources/extensions/gsd/tests/needs-remediation-revalidation.test.ts +37 -30
  424. package/src/resources/extensions/gsd/tests/note-captures-executed.test.ts +32 -28
  425. package/src/resources/extensions/gsd/tests/originalbase-path-comparison.test.ts +3 -0
  426. package/src/resources/extensions/gsd/tests/orphan-merge-bootstrap.test.ts +133 -0
  427. package/src/resources/extensions/gsd/tests/orphan-stash-audit.test.ts +201 -0
  428. package/src/resources/extensions/gsd/tests/parallel-orchestrator-fast-forward.test.ts +113 -0
  429. package/src/resources/extensions/gsd/tests/phantom-ghost-detection.test.ts +24 -37
  430. package/src/resources/extensions/gsd/tests/phantom-milestone-default-queued.test.ts +9 -24
  431. package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +91 -75
  432. package/src/resources/extensions/gsd/tests/post-unit-state-rebuild.test.ts +36 -22
  433. package/src/resources/extensions/gsd/tests/pre-exec-backtick-strip.test.ts +36 -30
  434. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +45 -5
  435. package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +74 -4
  436. package/src/resources/extensions/gsd/tests/preferences-worktree-sync.test.ts +20 -22
  437. package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +130 -32
  438. package/src/resources/extensions/gsd/tests/project-root-cwd-crash.test.ts +18 -36
  439. package/src/resources/extensions/gsd/tests/projection-no-plan-overwrite.test.ts +35 -73
  440. package/src/resources/extensions/gsd/tests/prompt-budget-enforcement.test.ts +76 -138
  441. package/src/resources/extensions/gsd/tests/prompt-duplication-cuts.test.ts +230 -0
  442. package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +70 -125
  443. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +59 -161
  444. package/src/resources/extensions/gsd/tests/query-tools-db-open.test.ts +33 -29
  445. package/src/resources/extensions/gsd/tests/queue-auto-guard.test.ts +22 -196
  446. package/src/resources/extensions/gsd/tests/quick-auto-guard.test.ts +23 -93
  447. package/src/resources/extensions/gsd/tests/quick-turn-end-cleanup.test.ts +50 -79
  448. package/src/resources/extensions/gsd/tests/reassess-default-optin.test.ts +27 -13
  449. package/src/resources/extensions/gsd/tests/remote-questions.test.ts +151 -251
  450. package/src/resources/extensions/gsd/tests/resource-loader-import-path.test.ts +41 -29
  451. package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +58 -69
  452. package/src/resources/extensions/gsd/tests/resume-dispatch-worktree.test.ts +32 -164
  453. package/src/resources/extensions/gsd/tests/run-uat-replay-cap.test.ts +57 -41
  454. package/src/resources/extensions/gsd/tests/select-resumable-milestone.test.ts +96 -0
  455. package/src/resources/extensions/gsd/tests/session-model-override.test.ts +14 -9
  456. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +77 -0
  457. package/src/resources/extensions/gsd/tests/session-switch-abort-misclassification.test.ts +166 -0
  458. package/src/resources/extensions/gsd/tests/show-config-command.test.ts +44 -42
  459. package/src/resources/extensions/gsd/tests/skip-slice-state-rebuild.test.ts +56 -24
  460. package/src/resources/extensions/gsd/tests/skipped-validation-db-atomicity.test.ts +51 -11
  461. package/src/resources/extensions/gsd/tests/slice-cadence.test.ts +23 -0
  462. package/src/resources/extensions/gsd/tests/slice-context-injection.test.ts +66 -50
  463. package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +68 -107
  464. package/src/resources/extensions/gsd/tests/slice-sequence-insert.test.ts +115 -42
  465. package/src/resources/extensions/gsd/tests/smart-entry-complete.test.ts +21 -97
  466. package/src/resources/extensions/gsd/tests/smart-entry-draft.test.ts +25 -116
  467. package/src/resources/extensions/gsd/tests/sqlite-unavailable-gate.test.ts +21 -57
  468. package/src/resources/extensions/gsd/tests/stale-dirlistcache-4648.test.ts +29 -76
  469. package/src/resources/extensions/gsd/tests/stale-lockfile-recovery.test.ts +33 -24
  470. package/src/resources/extensions/gsd/tests/stale-slice-rows.test.ts +39 -30
  471. package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +1 -0
  472. package/src/resources/extensions/gsd/tests/status-db-open.test.ts +33 -47
  473. package/src/resources/extensions/gsd/tests/stop-auto-merge-back.test.ts +48 -46
  474. package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +14 -102
  475. package/src/resources/extensions/gsd/tests/subagent-model-dispatch.test.ts +78 -232
  476. package/src/resources/extensions/gsd/tests/sync-worktree-skip-current.test.ts +32 -35
  477. package/src/resources/extensions/gsd/tests/system-context-memory.test.ts +112 -0
  478. package/src/resources/extensions/gsd/tests/system-context-message-routing.test.ts +7 -9
  479. package/src/resources/extensions/gsd/tests/token-profile.test.ts +84 -309
  480. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +291 -0
  481. package/src/resources/extensions/gsd/tests/triage-dispatch.test.ts +134 -341
  482. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +8 -25
  483. package/src/resources/extensions/gsd/tests/unit-dispatches.test.ts +50 -1
  484. package/src/resources/extensions/gsd/tests/unstructured-continue-context-injection.test.ts +5 -99
  485. package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +43 -36
  486. package/src/resources/extensions/gsd/tests/visualizer-data.test.ts +84 -444
  487. package/src/resources/extensions/gsd/tests/workflow-dispatch-claim.test.ts +142 -0
  488. package/src/resources/extensions/gsd/tests/workflow-logger-wiring.test.ts +44 -189
  489. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +2 -57
  490. package/src/resources/extensions/gsd/tests/workflow-protocol-excerpt.test.ts +99 -0
  491. package/src/resources/extensions/gsd/tests/workflow-worker-heartbeat.test.ts +32 -1
  492. package/src/resources/extensions/gsd/tests/worktree-db-same-file.test.ts +21 -44
  493. package/src/resources/extensions/gsd/tests/worktree-expected-warnings.test.ts +27 -26
  494. package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +14 -13
  495. package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +1 -0
  496. package/src/resources/extensions/gsd/tests/worktree-main-branch.test.ts +20 -18
  497. package/src/resources/extensions/gsd/tests/worktree-path-injection.test.ts +22 -19
  498. package/src/resources/extensions/gsd/tests/worktree-project-root-degrade.test.ts +66 -0
  499. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +140 -3
  500. package/src/resources/extensions/gsd/tests/zero-slice-roadmap-guided.test.ts +19 -13
  501. package/src/resources/extensions/gsd/tools/complete-milestone.ts +14 -15
  502. package/src/resources/extensions/gsd/tools/complete-task.ts +1 -1
  503. package/src/resources/extensions/gsd/workflow-protocol.ts +160 -0
  504. package/src/resources/extensions/gsd/worktree-resolver.ts +83 -5
  505. package/src/resources/skills/create-gsd-extension/templates/templates.test.ts +86 -40
  506. package/src/resources/skills/web-quality-audit/scripts/analyze.sh +0 -0
  507. package/dist/web/standalone/.next/static/chunks/8336.631939fb583761fa.js +0 -10
  508. /package/dist/web/standalone/.next/static/{tht0ltP8EIjsohPOA_WZf → G68KoLv5claox_Dyd4pZn}/_buildManifest.js +0 -0
  509. /package/dist/web/standalone/.next/static/{tht0ltP8EIjsohPOA_WZf → G68KoLv5claox_Dyd4pZn}/_ssgManifest.js +0 -0
@@ -2,63 +2,19 @@
2
2
  * auto-paused-session-validation.test.ts — Validates milestone existence
3
3
  * before restoring from paused-session.json (#1664).
4
4
  *
5
- * Two layers:
6
- * 1. Source-code regression: ensures auto.ts validates the milestone before
7
- * trusting paused-session.json (guards against accidental removal).
8
- * 2. Filesystem unit: confirms resolveMilestonePath / resolveMilestoneFile
9
- * correctly detect missing and completed milestones.
5
+ * Filesystem unit coverage confirms resolveMilestonePath / resolveMilestoneFile
6
+ * correctly detect missing and completed milestones.
10
7
  */
11
8
 
12
9
  import test from "node:test";
13
10
  import assert from "node:assert/strict";
14
- import { mkdirSync, writeFileSync, rmSync, readFileSync } from "node:fs";
11
+ import { mkdirSync, writeFileSync, rmSync } from "node:fs";
15
12
  import { join } from "node:path";
16
13
  import { tmpdir } from "node:os";
17
14
  import { randomUUID } from "node:crypto";
18
- import { fileURLToPath } from "node:url";
19
- import { dirname } from "node:path";
20
15
 
21
16
  import { resolveMilestonePath, resolveMilestoneFile } from "../paths.ts";
22
17
 
23
- const __dirname = dirname(fileURLToPath(import.meta.url));
24
- const AUTO_TS_PATH = join(__dirname, "..", "auto.ts");
25
-
26
- // ─── Source-code regression guard ───────────────────────────────────────────
27
-
28
- test("auto.ts validates milestone before restoring paused session (#1664)", () => {
29
- const source = readFileSync(AUTO_TS_PATH, "utf-8");
30
-
31
- // The resume block must call resolveMilestonePath to verify the milestone dir exists
32
- assert.ok(
33
- source.includes('resolveMilestonePath(base, meta.milestoneId)'),
34
- "auto.ts must call resolveMilestonePath to verify paused milestone exists",
35
- );
36
-
37
- // The resume block must check for a SUMMARY file to detect completed milestones
38
- assert.ok(
39
- source.includes('resolveMilestoneFile(base, meta.milestoneId, "SUMMARY")'),
40
- "auto.ts must check for SUMMARY file to detect completed milestones",
41
- );
42
-
43
- assert.ok(
44
- source.includes("await ensureDbOpen(base)") &&
45
- source.indexOf("await ensureDbOpen(base)") < source.indexOf('resolveMilestoneFile(base, meta.milestoneId, "SUMMARY")'),
46
- "auto.ts must open the canonical DB before using SUMMARY as a paused-session fallback",
47
- );
48
-
49
- // Resume path must sanitize paused session file metadata before unlink/recovery.
50
- assert.ok(
51
- source.includes("normalizeSessionFilePath(meta.sessionFile ?? null)"),
52
- "auto.ts must sanitize paused-session metadata sessionFile before using it",
53
- );
54
-
55
- // Pause path must sanitize live session file path before persisting metadata.
56
- assert.ok(
57
- source.includes("normalizeSessionFilePath(ctx?.sessionManager?.getSessionFile() ?? null)"),
58
- "auto.ts must sanitize sessionManager getSessionFile output before persisting",
59
- );
60
- });
61
-
62
18
  // ─── Filesystem validation unit tests ───────────────────────────────────────
63
19
 
64
20
  function makeTmpBase(): string {
@@ -1,27 +1,85 @@
1
+ // Project/App: GSD-2
2
+ // File Purpose: Behavior tests for auto-loop cleanup after paused provider exits.
1
3
  import { test } from "node:test";
2
4
  import assert from "node:assert/strict";
3
- import { readFileSync } from "node:fs";
4
- import { dirname, join } from "node:path";
5
- import { fileURLToPath } from "node:url";
5
+ import { mkdtempSync, rmSync } from "node:fs";
6
+ import { tmpdir } from "node:os";
7
+ import { join } from "node:path";
6
8
 
7
- const __dirname = dirname(fileURLToPath(import.meta.url));
8
- const autoSource = readFileSync(join(__dirname, "..", "auto.ts"), "utf-8");
9
+ import { cleanupAfterLoopExit, rerootCommandSession } from "../auto.ts";
10
+ import { autoSession } from "../auto-runtime-state.ts";
9
11
 
10
- test("#3370: cleanupAfterLoopExit preserves paused auto badge after provider pause", () => {
11
- const cleanupIdx = autoSource.indexOf("function cleanupAfterLoopExit");
12
- assert.ok(cleanupIdx > -1, "auto.ts should define cleanupAfterLoopExit");
12
+ test("cleanupAfterLoopExit preserves paused auto badge after provider pause", async () => {
13
+ const base = mkdtempSync(join(tmpdir(), "gsd-paused-cleanup-"));
14
+ const previousCwd = process.cwd();
15
+ const statuses: Array<[string, string | undefined]> = [];
13
16
 
14
- const dispatchIdx = autoSource.indexOf("export async function dispatchHookUnit", cleanupIdx);
15
- assert.ok(dispatchIdx > cleanupIdx, "cleanupAfterLoopExit body should be bounded by the next export");
17
+ autoSession.reset();
18
+ autoSession.active = true;
19
+ autoSession.paused = true;
20
+ autoSession.basePath = join(base, ".gsd", "worktrees", "M001");
21
+ autoSession.originalBasePath = base;
16
22
 
17
- const cleanupBody = autoSource.slice(cleanupIdx, dispatchIdx);
18
- const pausedGuardIdx = cleanupBody.indexOf("if (!s.paused) {");
19
- const clearStatusIdx = cleanupBody.indexOf('ctx.ui.setStatus("gsd-auto", undefined);');
23
+ try {
24
+ await cleanupAfterLoopExit({
25
+ ui: {
26
+ setStatus: (key: string, value: string | undefined) => {
27
+ statuses.push([key, value]);
28
+ },
29
+ setWidget: () => {},
30
+ notify: () => {},
31
+ },
32
+ } as any);
20
33
 
21
- assert.ok(pausedGuardIdx > -1, "loop-exit cleanup must guard UI clearing when auto is paused");
22
- assert.ok(clearStatusIdx > pausedGuardIdx, "status clearing must live behind the paused guard");
23
- assert.ok(
24
- autoSource.includes('ctx?.ui.setStatus("gsd-auto", "paused");'),
25
- "pauseAuto must still set the paused badge for transient provider pauses",
34
+ assert.equal(statuses.some(([key]) => key === "gsd-auto"), false);
35
+ assert.equal(autoSession.active, false);
36
+ assert.equal(autoSession.paused, true);
37
+ } finally {
38
+ autoSession.reset();
39
+ process.chdir(previousCwd);
40
+ rmSync(base, { recursive: true, force: true });
41
+ }
42
+ });
43
+
44
+ test("cleanupAfterLoopExit clears status and widget when auto is not paused", async () => {
45
+ const statusCalls: unknown[] = [];
46
+ const widgetCalls: unknown[] = [];
47
+
48
+ autoSession.reset();
49
+ autoSession.active = true;
50
+ autoSession.paused = false;
51
+
52
+ try {
53
+ await cleanupAfterLoopExit({
54
+ hasUI: false,
55
+ ui: {
56
+ setStatus: (...args: unknown[]) => statusCalls.push(args),
57
+ setWidget: (...args: unknown[]) => widgetCalls.push(args),
58
+ notify: () => {},
59
+ },
60
+ } as any);
61
+
62
+ assert.deepEqual(statusCalls, [["gsd-auto", undefined]]);
63
+ assert.deepEqual(widgetCalls, [["gsd-progress", undefined]]);
64
+ assert.equal(autoSession.active, false);
65
+ assert.equal(autoSession.paused, false);
66
+ } finally {
67
+ autoSession.reset();
68
+ }
69
+ });
70
+
71
+ test("rerootCommandSession refreshes command workspace to project root", async () => {
72
+ const calls: string[] = [];
73
+ const result = await rerootCommandSession(
74
+ {
75
+ newSession: async ({ workspaceRoot }: { workspaceRoot: string }) => {
76
+ calls.push(workspaceRoot);
77
+ return { cancelled: false };
78
+ },
79
+ } as any,
80
+ "/project/root",
26
81
  );
82
+
83
+ assert.deepEqual(result, { status: "ok" });
84
+ assert.deepEqual(calls, ["/project/root"]);
27
85
  });
@@ -1,3 +1,5 @@
1
+ // Project/App: GSD-2
2
+ // File Purpose: Auto-loop phase lifecycle regression tests.
1
3
  import test from "node:test";
2
4
  import assert from "node:assert/strict";
3
5
  import { mkdtempSync, rmSync } from "node:fs";
@@ -60,6 +62,59 @@ async function runSuccessfulFinalize(s: AutoSession) {
60
62
  );
61
63
  }
62
64
 
65
+ async function runFinalizeWithDeps(s: AutoSession, depsOverrides: Record<string, unknown>) {
66
+ const unit = s.currentUnit;
67
+ assert.ok(unit, "test setup must provide currentUnit");
68
+
69
+ writeUnitRuntimeRecord(s.basePath, unit.type, unit.id, unit.startedAt, {
70
+ phase: "dispatched",
71
+ });
72
+
73
+ const deps = {
74
+ clearUnitTimeout() {},
75
+ buildSnapshotOpts() {
76
+ return {};
77
+ },
78
+ stopAuto: async () => {},
79
+ pauseAuto: async () => {},
80
+ updateProgressWidget() {},
81
+ postUnitPreVerification: async () => "continue",
82
+ runPostUnitVerification: async () => "continue",
83
+ postUnitPostVerification: async () => "continue",
84
+ ...depsOverrides,
85
+ };
86
+
87
+ return runFinalize(
88
+ {
89
+ ctx: { ui: { notify() {} } },
90
+ pi: {},
91
+ s,
92
+ deps,
93
+ prefs: undefined,
94
+ iteration: 1,
95
+ flowId: "flow-1",
96
+ nextSeq: () => 1,
97
+ } as any,
98
+ {
99
+ unitType: unit.type,
100
+ unitId: unit.id,
101
+ prompt: "",
102
+ finalPrompt: "",
103
+ pauseAfterUatDispatch: false,
104
+ state: {} as any,
105
+ mid: "M001",
106
+ midTitle: "Milestone",
107
+ isRetry: false,
108
+ previousTier: undefined,
109
+ },
110
+ {
111
+ recentUnits: [],
112
+ stuckRecoveryAttempts: 0,
113
+ consecutiveFinalizeTimeouts: 0,
114
+ },
115
+ );
116
+ }
117
+
63
118
  test("runFinalize clears currentUnit after successful finalize", async () => {
64
119
  const base = mkdtempSync(join(tmpdir(), "gsd-finalize-current-unit-"));
65
120
  const s = new AutoSession();
@@ -102,3 +157,54 @@ test("runFinalize marks unit runtime finalized after successful finalize", async
102
157
  rmSync(base, { recursive: true, force: true });
103
158
  }
104
159
  });
160
+
161
+ test("runFinalize merges a verified complete-milestone immediately and only once", async (t) => {
162
+ const base = mkdtempSync(join(tmpdir(), "gsd-finalize-merge-"));
163
+ t.after(() => {
164
+ rmSync(base, { recursive: true, force: true });
165
+ });
166
+
167
+ const s = new AutoSession();
168
+ const startedAt = Date.now();
169
+ let mergeCalls = 0;
170
+ s.basePath = base;
171
+ s.originalBasePath = base;
172
+ s.currentMilestoneId = "M001";
173
+ s.currentUnit = {
174
+ type: "complete-milestone",
175
+ id: "M001",
176
+ startedAt,
177
+ };
178
+
179
+ const result = await runFinalizeWithDeps(s, {
180
+ preflightCleanRoot: () => ({ stashPushed: false }),
181
+ postflightPopStash: () => ({ needsManualRecovery: false }),
182
+ resolver: {
183
+ mergeAndExit() {
184
+ mergeCalls++;
185
+ },
186
+ },
187
+ });
188
+
189
+ assert.equal(result.action, "next");
190
+ assert.equal(mergeCalls, 1);
191
+ assert.equal(s.milestoneMergedInPhases, true);
192
+
193
+ s.currentUnit = {
194
+ type: "complete-milestone",
195
+ id: "M001",
196
+ startedAt: startedAt + 1,
197
+ };
198
+ const second = await runFinalizeWithDeps(s, {
199
+ preflightCleanRoot: () => ({ stashPushed: false }),
200
+ postflightPopStash: () => ({ needsManualRecovery: false }),
201
+ resolver: {
202
+ mergeAndExit() {
203
+ mergeCalls++;
204
+ },
205
+ },
206
+ });
207
+
208
+ assert.equal(second.action, "next");
209
+ assert.equal(mergeCalls, 1);
210
+ });
@@ -1,107 +1,66 @@
1
1
  /**
2
2
  * auto-pr-bugs.test.ts — Regression tests for #2302.
3
3
  *
4
- * Three interacting bugs prevented auto_pr from ever creating a PR:
5
- * 1. auto_pr was gated on `pushed` (which requires auto_push)
6
- * 2. Milestone branch was not pushed to remote before PR creation
7
- * 3. createDraftPR in git-service.ts lacked --head/--base parameters
4
+ * Verifies the PR creation command behavior directly instead of asserting on
5
+ * git-service.ts source text.
8
6
  */
9
7
 
10
8
  import test from "node:test";
11
9
  import assert from "node:assert/strict";
12
- import { readFileSync } from "node:fs";
10
+ import { chmodSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
13
11
  import { join } from "node:path";
14
-
15
- // ─── Bug 1: auto_pr should not depend on auto_push / pushed flag ────────────
16
-
17
- const autoWorktreeSrcPath = join(import.meta.dirname, "..", "auto-worktree.ts");
18
- const autoWorktreeSrc = readFileSync(autoWorktreeSrcPath, "utf-8");
19
-
20
- test("#2302 bug 1: auto_pr condition should not require pushed flag", () => {
21
- // Find the auto_pr block in mergeMilestoneToMain
22
- const autoPrIdx = autoWorktreeSrc.indexOf("auto_pr");
23
- assert.ok(autoPrIdx !== -1, "auto_pr reference exists in auto-worktree.ts");
24
-
25
- // Get context around the auto_pr check
26
- const lineStart = autoWorktreeSrc.lastIndexOf("\n", autoPrIdx) + 1;
27
- const lineEnd = autoWorktreeSrc.indexOf("\n", autoPrIdx);
28
- const autoPrLine = autoWorktreeSrc.slice(lineStart, lineEnd);
29
-
30
- // The condition should NOT include `&& pushed`
31
- assert.ok(
32
- !autoPrLine.includes("&& pushed"),
33
- "auto_pr condition should not be gated on pushed flag (auto_push dependency)",
34
- );
35
- });
36
-
37
- test("auto_pr skips milestone branch push when configured remote is absent", () => {
38
- const autoPrIdx = autoWorktreeSrc.indexOf("prefs.auto_pr === true");
39
- assert.ok(autoPrIdx !== -1, "auto_pr block exists in auto-worktree.ts");
40
-
41
- const autoPrBlock = autoWorktreeSrc.slice(
42
- autoPrIdx,
43
- autoWorktreeSrc.indexOf("// 11. Guard removed", autoPrIdx),
12
+ import { tmpdir } from "node:os";
13
+
14
+ import { createDraftPR } from "../git-service.ts";
15
+
16
+ function makeTempDir(prefix: string): string {
17
+ return mkdtempSync(join(tmpdir(), prefix));
18
+ }
19
+
20
+ test("#2302 createDraftPR passes head and base branch parameters to gh", (t) => {
21
+ const dir = makeTempDir("gsd-auto-pr-");
22
+ const bin = join(dir, "bin");
23
+ const logPath = join(dir, "gh-args.json");
24
+ t.after(() => rmSync(dir, { recursive: true, force: true }));
25
+
26
+ mkdirSync(bin, { recursive: true });
27
+ const ghPath = join(bin, "gh");
28
+ writeFileSync(
29
+ ghPath,
30
+ [
31
+ "#!/usr/bin/env node",
32
+ "const fs = require('node:fs');",
33
+ `fs.writeFileSync(${JSON.stringify(logPath)}, JSON.stringify(process.argv.slice(2)));`,
34
+ "process.stdout.write('https://example.test/pr/1\\n');",
35
+ ].join("\n"),
36
+ "utf-8",
44
37
  );
45
- const remoteExistsIdx = autoPrBlock.indexOf("gitRemoteExists(originalBasePath_, remote)");
46
- const pushIdx = autoPrBlock.indexOf('execFileSync("git", ["push", remote, milestoneBranch]');
47
-
48
- assert.ok(remoteExistsIdx !== -1, "auto_pr must check that the configured remote exists");
49
- assert.ok(pushIdx !== -1, "auto_pr still pushes the milestone branch before creating the PR");
50
- assert.ok(
51
- remoteExistsIdx < pushIdx,
52
- "auto_pr must check remote existence before pushing the milestone branch",
38
+ chmodSync(ghPath, 0o755);
39
+
40
+ const prUrl = createDraftPR(
41
+ dir,
42
+ "M001",
43
+ "Draft title",
44
+ "Draft body",
45
+ {
46
+ head: "milestone/M001",
47
+ base: "main",
48
+ env: { ...process.env, PATH: `${bin}:${process.env.PATH ?? ""}` },
49
+ },
53
50
  );
54
- });
55
-
56
- // ─── Bug 2: phases.ts should not duplicate PR creation ──────────────────────
57
-
58
- const phasesSrcPath = join(import.meta.dirname, "..", "auto", "phases.ts");
59
- const phasesSrc = readFileSync(phasesSrcPath, "utf-8");
60
-
61
- test("#2302 bug 2: phases.ts should not call createDraftPR (handled by mergeMilestoneToMain)", () => {
62
- // After fix, phases.ts should not import or call createDraftPR because
63
- // PR creation is handled inside mergeMilestoneToMain in auto-worktree.ts
64
- const createDraftPRCalls = phasesSrc.match(/createDraftPR\(/g) || [];
65
51
 
66
- assert.equal(
67
- createDraftPRCalls.length,
68
- 0,
69
- "phases.ts should not call createDraftPR — it's handled by mergeMilestoneToMain",
70
- );
71
- });
72
-
73
- // ─── Bug 3: createDraftPR should accept head and base branch parameters ─────
74
-
75
- const gitServiceSrcPath = join(import.meta.dirname, "..", "git-service.ts");
76
- const gitServiceSrc = readFileSync(gitServiceSrcPath, "utf-8");
77
-
78
- test("#2302 bug 3: createDraftPR should accept head and base branch parameters", () => {
79
- // Find the createDraftPR function signature
80
- const fnIdx = gitServiceSrc.indexOf("function createDraftPR");
81
- assert.ok(fnIdx !== -1, "createDraftPR function exists");
82
-
83
- // Get the function signature (up to the closing paren)
84
- const sigEnd = gitServiceSrc.indexOf(")", fnIdx);
85
- const signature = gitServiceSrc.slice(fnIdx, sigEnd);
86
-
87
- // Should have head and base parameters
88
- assert.ok(
89
- signature.includes("head") || signature.includes("branch"),
90
- "createDraftPR should accept a head/branch parameter",
91
- );
92
- });
93
-
94
- test("#2302 bug 3: createDraftPR should pass --head and --base to gh pr create", () => {
95
- const fnIdx = gitServiceSrc.indexOf("function createDraftPR");
96
- const fnEnd = gitServiceSrc.indexOf("\n}", fnIdx);
97
- const fnBody = gitServiceSrc.slice(fnIdx, fnEnd);
98
-
99
- assert.ok(
100
- fnBody.includes("--head"),
101
- "createDraftPR should pass --head to gh pr create",
102
- );
103
- assert.ok(
104
- fnBody.includes("--base"),
105
- "createDraftPR should pass --base to gh pr create",
106
- );
52
+ assert.equal(prUrl, "https://example.test/pr/1");
53
+ assert.deepEqual(JSON.parse(readFileSync(logPath, "utf-8")), [
54
+ "pr",
55
+ "create",
56
+ "--draft",
57
+ "--title",
58
+ "Draft title",
59
+ "--body",
60
+ "Draft body",
61
+ "--head",
62
+ "milestone/M001",
63
+ "--base",
64
+ "main",
65
+ ]);
107
66
  });
@@ -1,33 +1,74 @@
1
+ // Project/App: GSD-2
2
+ // File Purpose: Behavior tests for auto-mode project-root environment cleanup.
1
3
  import test from "node:test";
2
4
  import assert from "node:assert/strict";
3
- import { readFileSync } from "node:fs";
5
+ import { mkdtempSync, rmSync } from "node:fs";
6
+ import { tmpdir } from "node:os";
4
7
  import { join } from "node:path";
5
8
 
6
- const sourcePath = join(import.meta.dirname, "..", "auto.ts");
7
- const source = readFileSync(sourcePath, "utf-8");
8
-
9
- test("auto-mode captures GSD_PROJECT_ROOT before entering the dispatch loop", () => {
10
- const captureDeclIdx = source.indexOf("function captureProjectRootEnv(projectRoot: string): void {");
11
- assert.ok(captureDeclIdx > -1, "auto.ts should define captureProjectRootEnv()");
12
-
13
- const resumeCallIdx = source.indexOf("captureProjectRootEnv(s.originalBasePath || s.basePath);");
14
- assert.ok(resumeCallIdx > -1, "auto.ts should capture GSD_PROJECT_ROOT before resume autoLoop");
15
-
16
- const firstLoopIdxCandidates = [
17
- source.indexOf("await runAutoLoopWithUok({"),
18
- source.indexOf("await autoLoop(ctx, pi, s, buildLoopDeps());"),
19
- ].filter((idx) => idx > -1);
20
- const firstAutoLoopIdx = firstLoopIdxCandidates.length > 0 ? Math.min(...firstLoopIdxCandidates) : -1;
21
- assert.ok(firstAutoLoopIdx > -1, "auto.ts should invoke the auto dispatch loop");
22
- assert.ok(
23
- resumeCallIdx < firstAutoLoopIdx,
24
- "auto.ts must set GSD_PROJECT_ROOT before the first loop call",
25
- );
9
+ import {
10
+ cleanupAfterLoopExit,
11
+ _captureProjectRootEnvForTest,
12
+ _restoreProjectRootEnvForTest,
13
+ } from "../auto.ts";
14
+ import { autoSession } from "../auto-runtime-state.ts";
15
+
16
+ test.afterEach(() => {
17
+ _restoreProjectRootEnvForTest();
18
+ });
19
+
20
+ test("auto-mode project-root env capture sets GSD_PROJECT_ROOT and restores an existing value", () => {
21
+ process.env.GSD_PROJECT_ROOT = "/before";
22
+
23
+ _captureProjectRootEnvForTest("/project");
24
+ assert.equal(process.env.GSD_PROJECT_ROOT, "/project");
25
+
26
+ _restoreProjectRootEnvForTest();
27
+ assert.equal(process.env.GSD_PROJECT_ROOT, "/before");
28
+ delete process.env.GSD_PROJECT_ROOT;
29
+ });
30
+
31
+ test("auto-mode project-root env restore deletes GSD_PROJECT_ROOT when it was initially absent", () => {
32
+ delete process.env.GSD_PROJECT_ROOT;
33
+
34
+ _captureProjectRootEnvForTest("/project");
35
+ assert.equal(process.env.GSD_PROJECT_ROOT, "/project");
36
+
37
+ _restoreProjectRootEnvForTest();
38
+ assert.equal(process.env.GSD_PROJECT_ROOT, undefined);
26
39
  });
27
40
 
28
- test("auto-mode restores GSD_PROJECT_ROOT when execution stops or pauses", () => {
29
- assert.match(source, /function restoreProjectRootEnv\(\): void \{/);
30
- assert.match(source, /cleanupAfterLoopExit\(ctx: ExtensionContext\): void \{[\s\S]*restoreProjectRootEnv\(\);/);
31
- assert.match(source, /export async function pauseAuto\([\s\S]*restoreProjectRootEnv\(\);/);
32
- assert.match(source, /\} finally \{[\s\S]*restoreProjectRootEnv\(\);[\s\S]*s\.reset\(\);/);
41
+ test("cleanupAfterLoopExit restores captured GSD_PROJECT_ROOT", async () => {
42
+ const base = mkdtempSync(join(tmpdir(), "gsd-project-root-env-"));
43
+ const previousCwd = process.cwd();
44
+ const previousProjectRoot = process.env.GSD_PROJECT_ROOT;
45
+
46
+ autoSession.reset();
47
+ autoSession.active = true;
48
+ autoSession.basePath = join(base, ".gsd", "worktrees", "M001");
49
+ autoSession.originalBasePath = base;
50
+ autoSession.projectRootEnvCaptured = true;
51
+ autoSession.hadProjectRootEnv = true;
52
+ autoSession.previousProjectRootEnv = "/previous/project";
53
+ process.env.GSD_PROJECT_ROOT = base;
54
+
55
+ try {
56
+ await cleanupAfterLoopExit({
57
+ ui: {
58
+ setStatus: () => {},
59
+ setWidget: () => {},
60
+ notify: () => {},
61
+ },
62
+ } as any);
63
+
64
+ assert.equal(process.env.GSD_PROJECT_ROOT, "/previous/project");
65
+ assert.equal(autoSession.projectRootEnvCaptured, false);
66
+ assert.equal(autoSession.previousProjectRootEnv, null);
67
+ } finally {
68
+ autoSession.reset();
69
+ process.chdir(previousCwd);
70
+ if (previousProjectRoot === undefined) delete process.env.GSD_PROJECT_ROOT;
71
+ else process.env.GSD_PROJECT_ROOT = previousProjectRoot;
72
+ rmSync(base, { recursive: true, force: true });
73
+ }
33
74
  });
@@ -4,43 +4,45 @@
4
4
  * A SUMMARY.md on disk is a projection/diagnostic. Runtime post-unit checks
5
5
  * must not use it to mark the DB slice complete; explicit import/recovery
6
6
  * commands own markdown-to-DB behavior.
7
- *
8
- * This structural test verifies the complete-slice rogue branch reports the
9
- * stale projection without calling updateSliceStatus().
10
7
  */
11
8
 
12
- import { describe, test } from 'node:test';
13
- import assert from 'node:assert/strict';
14
- import { readFileSync } from 'node:fs';
15
- import { fileURLToPath } from 'node:url';
16
- import { dirname, join } from 'node:path';
17
- import { extractSourceRegion } from "./test-helpers.ts";
9
+ import { afterEach, describe, test } from "node:test";
10
+ import assert from "node:assert/strict";
11
+ import { mkdtempSync, mkdirSync, realpathSync, rmSync, writeFileSync } from "node:fs";
12
+ import { dirname, join } from "node:path";
13
+ import { tmpdir } from "node:os";
18
14
 
19
- const __filename = fileURLToPath(import.meta.url);
20
- const __dirname = dirname(__filename);
15
+ import { detectRogueFileWrites } from "../auto-post-unit.ts";
16
+ import {
17
+ closeDatabase,
18
+ getSlice,
19
+ insertMilestone,
20
+ insertSlice,
21
+ isDbAvailable,
22
+ openDatabase,
23
+ } from "../gsd-db.ts";
21
24
 
22
- const source = readFileSync(join(__dirname, '..', 'auto-post-unit.ts'), 'utf-8');
25
+ afterEach(() => {
26
+ if (isDbAvailable()) closeDatabase();
27
+ });
23
28
 
24
- describe('DB-authoritative slice rogue detection', () => {
25
- test('updateSliceStatus is not imported for post-unit rogue reconciliation', () => {
26
- assert.doesNotMatch(source, /import\s*\{[^}]*updateSliceStatus[^}]*\}\s*from\s*["']\.\/gsd-db/,
27
- 'auto-post-unit must not import updateSliceStatus for disk-to-DB reconciliation');
28
- });
29
+ describe("DB-authoritative slice rogue detection", () => {
30
+ test("complete-slice SUMMARY.md is reported as rogue without marking DB complete", (t) => {
31
+ const base = realpathSync(mkdtempSync(join(tmpdir(), "gsd-rogue-slice-")));
32
+ t.after(() => rmSync(base, { recursive: true, force: true }));
29
33
 
30
- test('complete-slice rogue branch does not mark DB complete from disk', () => {
31
- assert.doesNotMatch(source, /updateSliceStatus\(mid,\s*sid,\s*["']complete["']/,
32
- 'SUMMARY.md on disk must not mark slice complete in DB');
33
- });
34
+ mkdirSync(join(base, ".gsd"), { recursive: true });
35
+ openDatabase(join(base, ".gsd", "gsd.db"));
36
+ insertMilestone({ id: "M001", title: "Milestone", status: "active" });
37
+ insertSlice({ milestoneId: "M001", id: "S01", title: "Slice", status: "pending", sequence: 1 });
34
38
 
35
- test('explicit rogue diagnostic reports stale slice summary projection', () => {
36
- const branch = extractSourceRegion(source, 'unitType === "complete-slice"', 'unitType === "plan-milestone"');
37
- assert.match(branch, /rogues\.push\(\{\s*path:\s*summaryPath,\s*unitType,\s*unitId\s*\}\)/,
38
- 'complete-slice branch should report stale SUMMARY.md as rogue');
39
- });
39
+ const summaryPath = join(base, ".gsd", "milestones", "M001", "slices", "S01", "S01-SUMMARY.md");
40
+ mkdirSync(dirname(summaryPath), { recursive: true });
41
+ writeFileSync(summaryPath, "# Summary\n", "utf-8");
42
+
43
+ const rogues = detectRogueFileWrites("complete-slice", "M001/S01", base);
40
44
 
41
- test('post-unit runtime does not call rogue diagnostics automatically', () => {
42
- const postUnit = extractSourceRegion(source, 'export async function postUnitPostVerification');
43
- assert.doesNotMatch(postUnit, /detectRogueFileWrites\(/,
44
- 'runtime post-unit path must not scan disk projections for rogue files');
45
+ assert.deepEqual(rogues, [{ path: summaryPath, unitType: "complete-slice", unitId: "M001/S01" }]);
46
+ assert.equal(getSlice("M001", "S01")?.status, "pending");
45
47
  });
46
48
  });