gsd-pi 2.80.0-dev.96f4d89d5 → 2.80.0-dev.a947d025c

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 (720) hide show
  1. package/README.md +35 -59
  2. package/dist/claude-cli-check.d.ts +30 -0
  3. package/dist/claude-cli-check.js +18 -7
  4. package/dist/cli.js +0 -19
  5. package/dist/headless-query.d.ts +10 -0
  6. package/dist/headless-query.js +6 -4
  7. package/dist/loader-entrypoint.d.ts +8 -0
  8. package/dist/loader-entrypoint.js +27 -0
  9. package/dist/loader.js +2 -11
  10. package/dist/mcp-server.d.ts +1 -0
  11. package/dist/mcp-server.js +6 -3
  12. package/dist/resources/.managed-resources-content-hash +1 -1
  13. package/dist/resources/GSD-WORKFLOW.md +2 -2
  14. package/dist/resources/extensions/claude-code-cli/readiness.js +18 -7
  15. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +40 -3
  16. package/dist/resources/extensions/github-sync/sync.js +4 -1
  17. package/dist/resources/extensions/gsd/auto/contracts.js +2 -0
  18. package/dist/resources/extensions/gsd/auto/loop.js +103 -9
  19. package/dist/resources/extensions/gsd/auto/orchestrator.js +48 -4
  20. package/dist/resources/extensions/gsd/auto/phases.js +311 -154
  21. package/dist/resources/extensions/gsd/auto/resolve.js +29 -0
  22. package/dist/resources/extensions/gsd/auto/run-unit.js +22 -30
  23. package/dist/resources/extensions/gsd/auto/session.js +9 -1
  24. package/dist/resources/extensions/gsd/auto/unit-runner-events.js +7 -0
  25. package/dist/resources/extensions/gsd/auto/workflow-dispatch-claim.js +33 -1
  26. package/dist/resources/extensions/gsd/auto/workflow-worker-heartbeat.js +9 -1
  27. package/dist/resources/extensions/gsd/auto-dashboard.js +18 -0
  28. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +5 -32
  29. package/dist/resources/extensions/gsd/auto-dispatch.js +26 -0
  30. package/dist/resources/extensions/gsd/auto-post-unit.js +122 -88
  31. package/dist/resources/extensions/gsd/auto-prompts.js +214 -17
  32. package/dist/resources/extensions/gsd/auto-recovery.js +197 -9
  33. package/dist/resources/extensions/gsd/auto-start.js +254 -17
  34. package/dist/resources/extensions/gsd/auto-supervisor.js +8 -1
  35. package/dist/resources/extensions/gsd/auto-timeout-recovery.js +2 -2
  36. package/dist/resources/extensions/gsd/auto-worktree.js +229 -336
  37. package/dist/resources/extensions/gsd/auto.js +273 -87
  38. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +122 -11
  39. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +44 -37
  40. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +37 -10
  41. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +30 -20
  42. package/dist/resources/extensions/gsd/bootstrap/journal-tools.js +4 -1
  43. package/dist/resources/extensions/gsd/bootstrap/memory-tools.js +6 -4
  44. package/dist/resources/extensions/gsd/bootstrap/query-tools.js +5 -3
  45. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +1 -1
  46. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +341 -55
  47. package/dist/resources/extensions/gsd/bootstrap/sanitize-complete-milestone.js +4 -0
  48. package/dist/resources/extensions/gsd/bootstrap/system-context.js +82 -23
  49. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +147 -2
  50. package/dist/resources/extensions/gsd/clean-root-preflight.js +65 -9
  51. package/dist/resources/extensions/gsd/commands/dispatcher.js +5 -0
  52. package/dist/resources/extensions/gsd/commands/handlers/ops.js +2 -2
  53. package/dist/resources/extensions/gsd/commands-config.js +1 -1
  54. package/dist/resources/extensions/gsd/commands-eval-review.js +2 -2
  55. package/dist/resources/extensions/gsd/commands-extract-learnings.js +17 -12
  56. package/dist/resources/extensions/gsd/commands-handlers.js +23 -9
  57. package/dist/resources/extensions/gsd/context-budget.js +37 -2
  58. package/dist/resources/extensions/gsd/crash-recovery.js +56 -10
  59. package/dist/resources/extensions/gsd/dashboard-overlay.js +1 -1
  60. package/dist/resources/extensions/gsd/db/unit-dispatches.js +92 -0
  61. package/dist/resources/extensions/gsd/db-base-schema.js +18 -2
  62. package/dist/resources/extensions/gsd/db-migration-steps.js +22 -0
  63. package/dist/resources/extensions/gsd/detection.js +106 -0
  64. package/dist/resources/extensions/gsd/ecosystem/gsd-extension-api.js +2 -0
  65. package/dist/resources/extensions/gsd/git-service.js +73 -5
  66. package/dist/resources/extensions/gsd/gsd-db.js +146 -13
  67. package/dist/resources/extensions/gsd/guided-flow.js +149 -48
  68. package/dist/resources/extensions/gsd/health-widget.js +3 -0
  69. package/dist/resources/extensions/gsd/init-wizard.js +4 -1
  70. package/dist/resources/extensions/gsd/memory-store.js +69 -12
  71. package/dist/resources/extensions/gsd/migrate/command.js +40 -1
  72. package/dist/resources/extensions/gsd/migration-auto-check.js +87 -0
  73. package/dist/resources/extensions/gsd/native-git-bridge.js +32 -8
  74. package/dist/resources/extensions/gsd/orphan-stash-audit.js +101 -0
  75. package/dist/resources/extensions/gsd/parallel-orchestrator.js +13 -3
  76. package/dist/resources/extensions/gsd/planning-path-scope.js +26 -0
  77. package/dist/resources/extensions/gsd/pre-execution-checks.js +22 -0
  78. package/dist/resources/extensions/gsd/prompt-loader.js +28 -2
  79. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +27 -23
  80. package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  81. package/dist/resources/extensions/gsd/prompts/execute-task.md +4 -2
  82. package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +1 -1
  83. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +3 -1
  84. package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  85. package/dist/resources/extensions/gsd/prompts/quick-task.md +1 -5
  86. package/dist/resources/extensions/gsd/prompts/replan-slice.md +2 -2
  87. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +2 -2
  88. package/dist/resources/extensions/gsd/quick.js +34 -2
  89. package/dist/resources/extensions/gsd/recovery-classification.js +94 -0
  90. package/dist/resources/extensions/gsd/safety/evidence-collector.js +10 -2
  91. package/dist/resources/extensions/gsd/slice-cadence.js +45 -2
  92. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +15 -9
  93. package/dist/resources/extensions/gsd/state-reconciliation.js +27 -0
  94. package/dist/resources/extensions/gsd/tool-contract.js +50 -0
  95. package/dist/resources/extensions/gsd/tools/complete-milestone.js +6 -7
  96. package/dist/resources/extensions/gsd/tools/complete-task.js +1 -1
  97. package/dist/resources/extensions/gsd/tools/context-mode-tool-result.js +15 -0
  98. package/dist/resources/extensions/gsd/tools/exec-search-tool.js +5 -0
  99. package/dist/resources/extensions/gsd/tools/exec-tool.js +3 -15
  100. package/dist/resources/extensions/gsd/tools/memory-tools.js +1 -0
  101. package/dist/resources/extensions/gsd/tools/plan-slice.js +9 -0
  102. package/dist/resources/extensions/gsd/tools/plan-task.js +9 -0
  103. package/dist/resources/extensions/gsd/tools/resume-tool.js +5 -0
  104. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +1 -1
  105. package/dist/resources/extensions/gsd/unit-context-composer.js +12 -3
  106. package/dist/resources/extensions/gsd/unit-runtime.js +22 -0
  107. package/dist/resources/extensions/gsd/workflow-protocol.js +131 -0
  108. package/dist/resources/extensions/gsd/worktree-lifecycle.js +958 -0
  109. package/dist/resources/extensions/gsd/worktree-manager.js +16 -14
  110. package/dist/resources/extensions/gsd/worktree-safety.js +119 -0
  111. package/dist/resources/extensions/gsd/worktree-state-projection.js +317 -0
  112. package/dist/resources/skills/web-quality-audit/scripts/analyze.sh +0 -0
  113. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  114. package/dist/web/standalone/.next/BUILD_ID +1 -1
  115. package/dist/web/standalone/.next/app-path-routes-manifest.json +14 -14
  116. package/dist/web/standalone/.next/build-manifest.json +3 -3
  117. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  118. package/dist/web/standalone/.next/react-loadable-manifest.json +2 -2
  119. package/dist/web/standalone/.next/required-server-files.json +1 -1
  120. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  121. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  122. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  123. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  124. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  125. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  126. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  127. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  128. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  129. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  130. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  131. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  132. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  133. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  134. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  135. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  136. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  137. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  138. package/dist/web/standalone/.next/server/app/index.html +1 -1
  139. package/dist/web/standalone/.next/server/app/index.rsc +2 -2
  140. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  141. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +2 -2
  142. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  143. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  144. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  145. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  146. package/dist/web/standalone/.next/server/app-paths-manifest.json +14 -14
  147. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  148. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  149. package/dist/web/standalone/.next/server/middleware.js +3 -3
  150. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  151. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  152. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  153. package/dist/web/standalone/.next/static/chunks/8359.e059d86b255fce1c.js +10 -0
  154. package/dist/web/standalone/.next/static/chunks/app/{page-fab3ebb85b006001.js → page-752f1e2ebdaa3e45.js} +1 -1
  155. package/dist/web/standalone/.next/static/chunks/{webpack-0481f1221120a7c6.js → webpack-de742b64187e13fe.js} +1 -1
  156. package/dist/web/standalone/server.js +1 -1
  157. package/dist/welcome-screen.d.ts +2 -0
  158. package/dist/welcome-screen.js +9 -7
  159. package/package.json +6 -4
  160. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  161. package/packages/mcp-server/dist/workflow-tools.js +22 -17
  162. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  163. package/packages/mcp-server/src/workflow-tools.test.ts +75 -2
  164. package/packages/mcp-server/src/workflow-tools.ts +30 -16
  165. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  166. package/packages/native/tsconfig.tsbuildinfo +1 -1
  167. package/packages/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  168. package/packages/pi-agent-core/dist/agent-loop.js +4 -1
  169. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  170. package/packages/pi-agent-core/dist/agent.d.ts +9 -2
  171. package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
  172. package/packages/pi-agent-core/dist/agent.js +43 -11
  173. package/packages/pi-agent-core/dist/agent.js.map +1 -1
  174. package/packages/pi-agent-core/dist/index.d.ts +1 -0
  175. package/packages/pi-agent-core/dist/index.d.ts.map +1 -1
  176. package/packages/pi-agent-core/dist/index.js +2 -0
  177. package/packages/pi-agent-core/dist/index.js.map +1 -1
  178. package/packages/pi-agent-core/dist/token-audit.d.ts +47 -0
  179. package/packages/pi-agent-core/dist/token-audit.d.ts.map +1 -0
  180. package/packages/pi-agent-core/dist/token-audit.js +221 -0
  181. package/packages/pi-agent-core/dist/token-audit.js.map +1 -0
  182. package/packages/pi-agent-core/dist/types.d.ts +31 -0
  183. package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
  184. package/packages/pi-agent-core/dist/types.js.map +1 -1
  185. package/packages/pi-agent-core/src/agent-loop.test.ts +128 -0
  186. package/packages/pi-agent-core/src/agent-loop.ts +4 -1
  187. package/packages/pi-agent-core/src/agent.ts +52 -11
  188. package/packages/pi-agent-core/src/index.ts +2 -0
  189. package/packages/pi-agent-core/src/token-audit.test.ts +189 -0
  190. package/packages/pi-agent-core/src/token-audit.ts +287 -0
  191. package/packages/pi-agent-core/src/types.ts +26 -10
  192. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  193. package/packages/pi-ai/dist/providers/anthropic-auth.test.js +35 -13
  194. package/packages/pi-ai/dist/providers/anthropic-auth.test.js.map +1 -1
  195. package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.js +21 -11
  196. package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.js.map +1 -1
  197. package/packages/pi-ai/dist/providers/anthropic.d.ts +7 -0
  198. package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  199. package/packages/pi-ai/dist/providers/anthropic.js +9 -7
  200. package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
  201. package/packages/pi-ai/dist/providers/minimax-tool-name.test.js +23 -14
  202. package/packages/pi-ai/dist/providers/minimax-tool-name.test.js.map +1 -1
  203. package/packages/pi-ai/dist/types.d.ts +2 -0
  204. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  205. package/packages/pi-ai/dist/types.js.map +1 -1
  206. package/packages/pi-ai/dist/utils/oauth/github-copilot.test.js +48 -21
  207. package/packages/pi-ai/dist/utils/oauth/github-copilot.test.js.map +1 -1
  208. package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.js +22 -21
  209. package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.js.map +1 -1
  210. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.js +22 -21
  211. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.js.map +1 -1
  212. package/packages/pi-ai/src/providers/anthropic-auth.test.ts +39 -25
  213. package/packages/pi-ai/src/providers/anthropic-bearer-auth.test.ts +26 -22
  214. package/packages/pi-ai/src/providers/anthropic.ts +22 -9
  215. package/packages/pi-ai/src/providers/minimax-tool-name.test.ts +34 -21
  216. package/packages/pi-ai/src/types.ts +3 -0
  217. package/packages/pi-ai/src/utils/oauth/github-copilot.test.ts +56 -22
  218. package/packages/pi-ai/src/utils/oauth/google-antigravity.test.ts +24 -28
  219. package/packages/pi-ai/src/utils/oauth/google-gemini-cli.test.ts +24 -28
  220. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  221. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +36 -1
  222. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js.map +1 -1
  223. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js +30 -1
  224. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js.map +1 -1
  225. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +21 -2
  226. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  227. package/packages/pi-coding-agent/dist/core/agent-session.js +94 -16
  228. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  229. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +78 -0
  230. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
  231. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +11 -0
  232. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
  233. package/packages/pi-coding-agent/dist/core/compaction/compaction.js +9 -0
  234. package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
  235. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.d.ts +2 -0
  236. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.d.ts.map +1 -0
  237. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.js +103 -0
  238. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.js.map +1 -0
  239. package/packages/pi-coding-agent/dist/core/db-snapshot.d.ts +15 -0
  240. package/packages/pi-coding-agent/dist/core/db-snapshot.d.ts.map +1 -0
  241. package/packages/pi-coding-agent/dist/core/db-snapshot.js +66 -0
  242. package/packages/pi-coding-agent/dist/core/db-snapshot.js.map +1 -0
  243. package/packages/pi-coding-agent/dist/core/db-snapshot.test.d.ts +2 -0
  244. package/packages/pi-coding-agent/dist/core/db-snapshot.test.d.ts.map +1 -0
  245. package/packages/pi-coding-agent/dist/core/db-snapshot.test.js +24 -0
  246. package/packages/pi-coding-agent/dist/core/db-snapshot.test.js.map +1 -0
  247. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  248. package/packages/pi-coding-agent/dist/core/extensions/loader.js +8 -0
  249. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  250. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +5 -0
  251. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
  252. package/packages/pi-coding-agent/dist/core/extensions/runner.js +20 -7
  253. package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
  254. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +102 -3
  255. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js.map +1 -1
  256. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +60 -4
  257. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  258. package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  259. package/packages/pi-coding-agent/dist/core/hooks-runner.test.js +2 -0
  260. package/packages/pi-coding-agent/dist/core/hooks-runner.test.js.map +1 -1
  261. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.d.ts +2 -0
  262. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.d.ts.map +1 -0
  263. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.js +46 -0
  264. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.js.map +1 -0
  265. package/packages/pi-coding-agent/dist/core/sdk.d.ts +10 -2
  266. package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
  267. package/packages/pi-coding-agent/dist/core/sdk.js +81 -4
  268. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  269. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +20 -0
  270. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  271. package/packages/pi-coding-agent/dist/core/settings-manager.js +25 -0
  272. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  273. package/packages/pi-coding-agent/dist/core/skill-tool.test.js +22 -0
  274. package/packages/pi-coding-agent/dist/core/skill-tool.test.js.map +1 -1
  275. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts +6 -7
  276. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
  277. package/packages/pi-coding-agent/dist/core/system-prompt.js +2 -3
  278. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  279. package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.js +22 -56
  280. package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.js.map +1 -1
  281. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts +1 -0
  282. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts.map +1 -1
  283. package/packages/pi-coding-agent/dist/core/tools/bash.js +3 -1
  284. package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
  285. package/packages/pi-coding-agent/dist/core/tools/edit.d.ts +2 -0
  286. package/packages/pi-coding-agent/dist/core/tools/edit.d.ts.map +1 -1
  287. package/packages/pi-coding-agent/dist/core/tools/edit.js +12 -1
  288. package/packages/pi-coding-agent/dist/core/tools/edit.js.map +1 -1
  289. package/packages/pi-coding-agent/dist/core/tools/find.d.ts +2 -0
  290. package/packages/pi-coding-agent/dist/core/tools/find.d.ts.map +1 -1
  291. package/packages/pi-coding-agent/dist/core/tools/find.js +14 -6
  292. package/packages/pi-coding-agent/dist/core/tools/find.js.map +1 -1
  293. package/packages/pi-coding-agent/dist/core/tools/grep.d.ts +2 -0
  294. package/packages/pi-coding-agent/dist/core/tools/grep.d.ts.map +1 -1
  295. package/packages/pi-coding-agent/dist/core/tools/grep.js +12 -3
  296. package/packages/pi-coding-agent/dist/core/tools/grep.js.map +1 -1
  297. package/packages/pi-coding-agent/dist/core/tools/hashline-read.d.ts +2 -0
  298. package/packages/pi-coding-agent/dist/core/tools/hashline-read.d.ts.map +1 -1
  299. package/packages/pi-coding-agent/dist/core/tools/hashline-read.js +3 -1
  300. package/packages/pi-coding-agent/dist/core/tools/hashline-read.js.map +1 -1
  301. package/packages/pi-coding-agent/dist/core/tools/index.d.ts +2 -1
  302. package/packages/pi-coding-agent/dist/core/tools/index.d.ts.map +1 -1
  303. package/packages/pi-coding-agent/dist/core/tools/index.js +1 -0
  304. package/packages/pi-coding-agent/dist/core/tools/index.js.map +1 -1
  305. package/packages/pi-coding-agent/dist/core/tools/ls.d.ts +2 -0
  306. package/packages/pi-coding-agent/dist/core/tools/ls.d.ts.map +1 -1
  307. package/packages/pi-coding-agent/dist/core/tools/ls.js +10 -3
  308. package/packages/pi-coding-agent/dist/core/tools/ls.js.map +1 -1
  309. package/packages/pi-coding-agent/dist/core/tools/read.d.ts +2 -0
  310. package/packages/pi-coding-agent/dist/core/tools/read.d.ts.map +1 -1
  311. package/packages/pi-coding-agent/dist/core/tools/read.js +3 -1
  312. package/packages/pi-coding-agent/dist/core/tools/read.js.map +1 -1
  313. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js +7 -62
  314. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js.map +1 -1
  315. package/packages/pi-coding-agent/dist/core/tools/tool-target-metadata.test.d.ts +2 -0
  316. package/packages/pi-coding-agent/dist/core/tools/tool-target-metadata.test.d.ts.map +1 -0
  317. package/packages/pi-coding-agent/dist/core/tools/tool-target-metadata.test.js +115 -0
  318. package/packages/pi-coding-agent/dist/core/tools/tool-target-metadata.test.js.map +1 -0
  319. package/packages/pi-coding-agent/dist/core/tools/tool-target.d.ts +19 -0
  320. package/packages/pi-coding-agent/dist/core/tools/tool-target.d.ts.map +1 -0
  321. package/packages/pi-coding-agent/dist/core/tools/tool-target.js +20 -0
  322. package/packages/pi-coding-agent/dist/core/tools/tool-target.js.map +1 -0
  323. package/packages/pi-coding-agent/dist/core/tools/write.d.ts +4 -0
  324. package/packages/pi-coding-agent/dist/core/tools/write.d.ts.map +1 -1
  325. package/packages/pi-coding-agent/dist/core/tools/write.js +9 -1
  326. package/packages/pi-coding-agent/dist/core/tools/write.js.map +1 -1
  327. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.js +6 -4
  328. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.js.map +1 -1
  329. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +137 -19
  330. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
  331. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.js +2 -2
  332. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.js.map +1 -1
  333. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  334. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
  335. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts.map +1 -1
  336. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js +2 -1
  337. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js.map +1 -1
  338. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js +32 -7
  339. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js.map +1 -1
  340. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +18 -0
  341. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  342. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +225 -16
  343. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  344. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  345. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +85 -2
  346. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  347. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js +71 -0
  348. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js.map +1 -1
  349. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +2 -0
  350. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  351. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +25 -3
  352. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  353. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  354. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +36 -27
  355. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -1
  356. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.js +21 -0
  357. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.js.map +1 -1
  358. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js +1 -1
  359. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js.map +1 -1
  360. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.d.ts +2 -0
  361. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.d.ts.map +1 -0
  362. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.js +28 -0
  363. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.js.map +1 -0
  364. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.d.ts.map +1 -1
  365. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.js +3 -2
  366. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.js.map +1 -1
  367. package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +40 -1
  368. package/packages/pi-coding-agent/src/core/agent-session-tool-refresh.test.ts +40 -1
  369. package/packages/pi-coding-agent/src/core/agent-session.ts +102 -16
  370. package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +91 -0
  371. package/packages/pi-coding-agent/src/core/compaction/compaction.ts +18 -0
  372. package/packages/pi-coding-agent/src/core/compaction-threshold.test.ts +121 -0
  373. package/packages/pi-coding-agent/src/core/db-snapshot.test.ts +32 -0
  374. package/packages/pi-coding-agent/src/core/db-snapshot.ts +66 -0
  375. package/packages/pi-coding-agent/src/core/extensions/loader.ts +10 -0
  376. package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +113 -3
  377. package/packages/pi-coding-agent/src/core/extensions/runner.ts +24 -6
  378. package/packages/pi-coding-agent/src/core/extensions/types.ts +63 -2
  379. package/packages/pi-coding-agent/src/core/hooks-runner.test.ts +2 -0
  380. package/packages/pi-coding-agent/src/core/sdk-tool-filter.test.ts +60 -0
  381. package/packages/pi-coding-agent/src/core/sdk.ts +92 -4
  382. package/packages/pi-coding-agent/src/core/settings-manager.ts +39 -1
  383. package/packages/pi-coding-agent/src/core/skill-tool.test.ts +28 -0
  384. package/packages/pi-coding-agent/src/core/system-prompt.ts +8 -10
  385. package/packages/pi-coding-agent/src/core/tools/bash-spawn-windows.test.ts +22 -66
  386. package/packages/pi-coding-agent/src/core/tools/bash.ts +4 -1
  387. package/packages/pi-coding-agent/src/core/tools/edit.ts +13 -1
  388. package/packages/pi-coding-agent/src/core/tools/find.ts +15 -6
  389. package/packages/pi-coding-agent/src/core/tools/grep.ts +13 -3
  390. package/packages/pi-coding-agent/src/core/tools/hashline-read.ts +4 -1
  391. package/packages/pi-coding-agent/src/core/tools/index.ts +8 -0
  392. package/packages/pi-coding-agent/src/core/tools/ls.ts +11 -3
  393. package/packages/pi-coding-agent/src/core/tools/read.ts +4 -1
  394. package/packages/pi-coding-agent/src/core/tools/spawn-shell-windows.test.ts +11 -72
  395. package/packages/pi-coding-agent/src/core/tools/tool-target-metadata.test.ts +127 -0
  396. package/packages/pi-coding-agent/src/core/tools/tool-target.ts +48 -0
  397. package/packages/pi-coding-agent/src/core/tools/write.ts +14 -2
  398. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.ts +7 -5
  399. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +185 -19
  400. package/packages/pi-coding-agent/src/modes/interactive/components/adaptive-layout.ts +2 -2
  401. package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +1 -0
  402. package/packages/pi-coding-agent/src/modes/interactive/components/chat-frame.ts +2 -1
  403. package/packages/pi-coding-agent/src/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.ts +41 -10
  404. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +260 -16
  405. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.test.ts +75 -0
  406. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +107 -3
  407. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +27 -3
  408. package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +36 -27
  409. package/packages/pi-coding-agent/src/modes/interactive/tui-mode.test.ts +25 -0
  410. package/packages/pi-coding-agent/src/modes/rpc/rpc-mode.ts +1 -1
  411. package/packages/pi-coding-agent/src/resources/extensions/memory/storage-safety-guard.test.ts +31 -0
  412. package/packages/pi-coding-agent/src/resources/extensions/memory/storage.ts +3 -2
  413. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  414. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  415. package/packages/pi-tui/dist/tui.js +18 -8
  416. package/packages/pi-tui/dist/tui.js.map +1 -1
  417. package/packages/pi-tui/src/tui.ts +20 -8
  418. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  419. package/packages/rpc-client/README.md +7 -0
  420. package/pkg/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  421. package/pkg/dist/modes/interactive/theme/themes.js +36 -27
  422. package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
  423. package/src/resources/GSD-WORKFLOW.md +2 -2
  424. package/src/resources/extensions/claude-code-cli/readiness.ts +25 -7
  425. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +42 -3
  426. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +67 -0
  427. package/src/resources/extensions/github-sync/sync.ts +8 -1
  428. package/src/resources/extensions/github-sync/tests/sync-source.test.ts +6 -18
  429. package/src/resources/extensions/gsd/auto/contracts.ts +19 -2
  430. package/src/resources/extensions/gsd/auto/loop-deps.ts +11 -11
  431. package/src/resources/extensions/gsd/auto/loop.ts +134 -16
  432. package/src/resources/extensions/gsd/auto/orchestrator.ts +52 -4
  433. package/src/resources/extensions/gsd/auto/phases.ts +427 -220
  434. package/src/resources/extensions/gsd/auto/resolve.ts +42 -1
  435. package/src/resources/extensions/gsd/auto/run-unit.ts +28 -30
  436. package/src/resources/extensions/gsd/auto/session.ts +9 -1
  437. package/src/resources/extensions/gsd/auto/types.ts +3 -0
  438. package/src/resources/extensions/gsd/auto/unit-runner-events.ts +15 -0
  439. package/src/resources/extensions/gsd/auto/workflow-dispatch-claim.ts +63 -1
  440. package/src/resources/extensions/gsd/auto/workflow-worker-heartbeat.ts +14 -1
  441. package/src/resources/extensions/gsd/auto-dashboard.ts +20 -0
  442. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +8 -34
  443. package/src/resources/extensions/gsd/auto-dispatch.ts +33 -0
  444. package/src/resources/extensions/gsd/auto-post-unit.ts +134 -90
  445. package/src/resources/extensions/gsd/auto-prompts.ts +228 -16
  446. package/src/resources/extensions/gsd/auto-recovery.ts +207 -7
  447. package/src/resources/extensions/gsd/auto-start.ts +326 -25
  448. package/src/resources/extensions/gsd/auto-supervisor.ts +7 -0
  449. package/src/resources/extensions/gsd/auto-timeout-recovery.ts +2 -2
  450. package/src/resources/extensions/gsd/auto-worktree.ts +259 -360
  451. package/src/resources/extensions/gsd/auto.ts +336 -89
  452. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +147 -11
  453. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +45 -37
  454. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +36 -10
  455. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +32 -19
  456. package/src/resources/extensions/gsd/bootstrap/journal-tools.ts +5 -1
  457. package/src/resources/extensions/gsd/bootstrap/memory-tools.ts +7 -4
  458. package/src/resources/extensions/gsd/bootstrap/query-tools.ts +6 -3
  459. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +1 -1
  460. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +396 -55
  461. package/src/resources/extensions/gsd/bootstrap/sanitize-complete-milestone.ts +4 -0
  462. package/src/resources/extensions/gsd/bootstrap/system-context.ts +90 -22
  463. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +153 -2
  464. package/src/resources/extensions/gsd/clean-root-preflight.ts +72 -9
  465. package/src/resources/extensions/gsd/commands/dispatcher.ts +6 -0
  466. package/src/resources/extensions/gsd/commands/handlers/ops.ts +4 -2
  467. package/src/resources/extensions/gsd/commands-config.ts +1 -1
  468. package/src/resources/extensions/gsd/commands-eval-review.ts +2 -2
  469. package/src/resources/extensions/gsd/commands-extract-learnings.ts +17 -12
  470. package/src/resources/extensions/gsd/commands-handlers.ts +34 -15
  471. package/src/resources/extensions/gsd/context-budget.ts +44 -2
  472. package/src/resources/extensions/gsd/crash-recovery.ts +67 -10
  473. package/src/resources/extensions/gsd/dashboard-overlay.ts +1 -1
  474. package/src/resources/extensions/gsd/db/unit-dispatches.ts +107 -0
  475. package/src/resources/extensions/gsd/db-base-schema.ts +19 -2
  476. package/src/resources/extensions/gsd/db-migration-steps.ts +25 -0
  477. package/src/resources/extensions/gsd/detection.ts +128 -0
  478. package/src/resources/extensions/gsd/ecosystem/gsd-extension-api.ts +3 -0
  479. package/src/resources/extensions/gsd/git-service.ts +87 -10
  480. package/src/resources/extensions/gsd/gsd-db.ts +168 -13
  481. package/src/resources/extensions/gsd/guided-flow.ts +175 -55
  482. package/src/resources/extensions/gsd/health-widget.ts +3 -0
  483. package/src/resources/extensions/gsd/init-wizard.ts +5 -1
  484. package/src/resources/extensions/gsd/memory-store.ts +77 -12
  485. package/src/resources/extensions/gsd/migrate/command.ts +47 -1
  486. package/src/resources/extensions/gsd/migration-auto-check.ts +129 -0
  487. package/src/resources/extensions/gsd/native-git-bridge.ts +39 -6
  488. package/src/resources/extensions/gsd/orphan-stash-audit.ts +117 -0
  489. package/src/resources/extensions/gsd/parallel-orchestrator.ts +13 -3
  490. package/src/resources/extensions/gsd/planning-path-scope.ts +35 -0
  491. package/src/resources/extensions/gsd/pre-execution-checks.ts +23 -0
  492. package/src/resources/extensions/gsd/preferences-types.ts +1 -1
  493. package/src/resources/extensions/gsd/prompt-loader.ts +27 -2
  494. package/src/resources/extensions/gsd/prompts/complete-milestone.md +27 -23
  495. package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  496. package/src/resources/extensions/gsd/prompts/execute-task.md +4 -2
  497. package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +1 -1
  498. package/src/resources/extensions/gsd/prompts/plan-milestone.md +3 -1
  499. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  500. package/src/resources/extensions/gsd/prompts/quick-task.md +1 -5
  501. package/src/resources/extensions/gsd/prompts/replan-slice.md +2 -2
  502. package/src/resources/extensions/gsd/prompts/validate-milestone.md +2 -2
  503. package/src/resources/extensions/gsd/quick.ts +37 -2
  504. package/src/resources/extensions/gsd/recovery-classification.ts +122 -0
  505. package/src/resources/extensions/gsd/safety/evidence-collector.ts +11 -2
  506. package/src/resources/extensions/gsd/slice-cadence.ts +49 -2
  507. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +23 -9
  508. package/src/resources/extensions/gsd/state-reconciliation.ts +57 -0
  509. package/src/resources/extensions/gsd/tests/agent-end-retry.test.ts +59 -89
  510. package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +47 -172
  511. package/src/resources/extensions/gsd/tests/artifacts-table-preserved-on-cache-invalidate.test.ts +0 -35
  512. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +35 -9
  513. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +544 -41
  514. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +80 -59
  515. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +119 -2
  516. package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +3 -47
  517. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +76 -18
  518. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +175 -11
  519. package/src/resources/extensions/gsd/tests/auto-pr-bugs.test.ts +54 -95
  520. package/src/resources/extensions/gsd/tests/auto-project-root-env.test.ts +67 -26
  521. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +184 -2
  522. package/src/resources/extensions/gsd/tests/auto-remediate-slice-status.test.ts +32 -30
  523. package/src/resources/extensions/gsd/tests/auto-start-bootstrap-await-3420.test.ts +32 -128
  524. package/src/resources/extensions/gsd/tests/auto-start-clean-runtime-db-gated.test.ts +20 -54
  525. package/src/resources/extensions/gsd/tests/auto-start-cold-db-bootstrap.test.ts +20 -30
  526. package/src/resources/extensions/gsd/tests/auto-start-index-lock.test.ts +17 -29
  527. package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +142 -0
  528. package/src/resources/extensions/gsd/tests/auto-start-time-persistence.test.ts +21 -39
  529. package/src/resources/extensions/gsd/tests/auto-start-worktree-db-path.test.ts +15 -24
  530. package/src/resources/extensions/gsd/tests/auto-thinking-restore.test.ts +44 -29
  531. package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +39 -51
  532. package/src/resources/extensions/gsd/tests/auto-wrapup-inflight-guard.test.ts +159 -213
  533. package/src/resources/extensions/gsd/tests/bootstrap-derive-state-db-open.test.ts +15 -32
  534. package/src/resources/extensions/gsd/tests/browser-teardown.test.ts +0 -41
  535. package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +97 -2
  536. package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +34 -27
  537. package/src/resources/extensions/gsd/tests/cmux.test.ts +51 -53
  538. package/src/resources/extensions/gsd/tests/cold-resume-db-reopen.test.ts +39 -61
  539. package/src/resources/extensions/gsd/tests/commands-config.test.ts +26 -19
  540. package/src/resources/extensions/gsd/tests/commands-extract-learnings.test.ts +9 -0
  541. package/src/resources/extensions/gsd/tests/compaction-snapshot.test.ts +14 -1
  542. package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +31 -0
  543. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +140 -0
  544. package/src/resources/extensions/gsd/tests/complete-slice-composer.test.ts +3 -2
  545. package/src/resources/extensions/gsd/tests/complete-task-normalize-lists.test.ts +29 -33
  546. package/src/resources/extensions/gsd/tests/completed-units-metrics-sync.test.ts +45 -108
  547. package/src/resources/extensions/gsd/tests/context-budget.test.ts +10 -1
  548. package/src/resources/extensions/gsd/tests/context-store.test.ts +7 -1
  549. package/src/resources/extensions/gsd/tests/crash-handler-secondary.test.ts +90 -31
  550. package/src/resources/extensions/gsd/tests/crash-recovery-via-db.test.ts +22 -0
  551. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +18 -10
  552. package/src/resources/extensions/gsd/tests/cwd-fallback-hardening.test.ts +138 -0
  553. package/src/resources/extensions/gsd/tests/dashboard-custom-engine.test.ts +4 -68
  554. package/src/resources/extensions/gsd/tests/db-schema-metadata.test.ts +2 -2
  555. package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +6 -11
  556. package/src/resources/extensions/gsd/tests/deferred-milestone-dir-4996.test.ts +14 -65
  557. package/src/resources/extensions/gsd/tests/detection.test.ts +140 -0
  558. package/src/resources/extensions/gsd/tests/discuss-tool-scoping.test.ts +44 -37
  559. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +58 -40
  560. package/src/resources/extensions/gsd/tests/dispatch-guard-closed-status.test.ts +25 -15
  561. package/src/resources/extensions/gsd/tests/dispatch-rule-coverage.test.ts +313 -0
  562. package/src/resources/extensions/gsd/tests/dispatcher-stuck-planning.test.ts +35 -17
  563. package/src/resources/extensions/gsd/tests/error-success-mask.test.ts +16 -21
  564. package/src/resources/extensions/gsd/tests/est-annotation-timeout.test.ts +15 -82
  565. package/src/resources/extensions/gsd/tests/exec-history.test.ts +15 -0
  566. package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +65 -0
  567. package/src/resources/extensions/gsd/tests/execute-task-rendering.test.ts +5 -2
  568. package/src/resources/extensions/gsd/tests/fast-forward-reused-milestone-branch.test.ts +219 -0
  569. package/src/resources/extensions/gsd/tests/finalize-survivor-branch.test.ts +151 -0
  570. package/src/resources/extensions/gsd/tests/flat-rate-routing-guard.test.ts +2 -20
  571. package/src/resources/extensions/gsd/tests/frontmatter-parse-noise.test.ts +18 -26
  572. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +44 -0
  573. package/src/resources/extensions/gsd/tests/has-pending-deep-stage.test.ts +33 -1
  574. package/src/resources/extensions/gsd/tests/init-skip-git.test.ts +9 -12
  575. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +40 -0
  576. package/src/resources/extensions/gsd/tests/integration/commands-eval-review.integration.test.ts +4 -2
  577. package/src/resources/extensions/gsd/tests/integration/git-locale.test.ts +31 -20
  578. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +66 -0
  579. package/src/resources/extensions/gsd/tests/integration/milestone-transition-worktree.test.ts +0 -47
  580. package/src/resources/extensions/gsd/tests/interactive-routing-bypass.test.ts +60 -202
  581. package/src/resources/extensions/gsd/tests/isolation-none-branch-guard.test.ts +13 -56
  582. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +248 -10
  583. package/src/resources/extensions/gsd/tests/journal-query-tool.test.ts +32 -0
  584. package/src/resources/extensions/gsd/tests/knowledge.test.ts +47 -0
  585. package/src/resources/extensions/gsd/tests/lazy-pi-tui-import.test.ts +44 -6
  586. package/src/resources/extensions/gsd/tests/memory-decay-factor.test.ts +90 -0
  587. package/src/resources/extensions/gsd/tests/memory-pressure-stuck-state.test.ts +21 -35
  588. package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +37 -7
  589. package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +48 -0
  590. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +127 -0
  591. package/src/resources/extensions/gsd/tests/milestone-merge-stash-restore.test.ts +267 -0
  592. package/src/resources/extensions/gsd/tests/milestone-transition-state-rebuild.test.ts +88 -98
  593. package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +70 -278
  594. package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +34 -2
  595. package/src/resources/extensions/gsd/tests/needs-remediation-revalidation.test.ts +37 -30
  596. package/src/resources/extensions/gsd/tests/note-captures-executed.test.ts +32 -28
  597. package/src/resources/extensions/gsd/tests/originalbase-path-comparison.test.ts +44 -9
  598. package/src/resources/extensions/gsd/tests/orphan-merge-bootstrap.test.ts +144 -0
  599. package/src/resources/extensions/gsd/tests/orphan-stash-audit.test.ts +201 -0
  600. package/src/resources/extensions/gsd/tests/parallel-orchestrator-fast-forward.test.ts +113 -0
  601. package/src/resources/extensions/gsd/tests/phantom-ghost-detection.test.ts +24 -37
  602. package/src/resources/extensions/gsd/tests/phantom-milestone-default-queued.test.ts +9 -24
  603. package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +95 -75
  604. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +50 -0
  605. package/src/resources/extensions/gsd/tests/plan-task.test.ts +21 -0
  606. package/src/resources/extensions/gsd/tests/post-unit-state-rebuild.test.ts +36 -22
  607. package/src/resources/extensions/gsd/tests/pre-exec-backtick-strip.test.ts +36 -30
  608. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +45 -5
  609. package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +74 -4
  610. package/src/resources/extensions/gsd/tests/preferences-worktree-sync.test.ts +20 -22
  611. package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +130 -32
  612. package/src/resources/extensions/gsd/tests/project-root-cwd-crash.test.ts +18 -36
  613. package/src/resources/extensions/gsd/tests/projection-no-plan-overwrite.test.ts +35 -73
  614. package/src/resources/extensions/gsd/tests/prompt-budget-enforcement.test.ts +76 -138
  615. package/src/resources/extensions/gsd/tests/prompt-duplication-cuts.test.ts +230 -0
  616. package/src/resources/extensions/gsd/tests/prompt-path-audit.test.ts +40 -0
  617. package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +70 -106
  618. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +59 -161
  619. package/src/resources/extensions/gsd/tests/query-tools-db-open.test.ts +33 -29
  620. package/src/resources/extensions/gsd/tests/queue-auto-guard.test.ts +22 -196
  621. package/src/resources/extensions/gsd/tests/quick-auto-guard.test.ts +23 -93
  622. package/src/resources/extensions/gsd/tests/quick-external-gsd.test.ts +40 -0
  623. package/src/resources/extensions/gsd/tests/quick-turn-end-cleanup.test.ts +50 -79
  624. package/src/resources/extensions/gsd/tests/reassess-default-optin.test.ts +27 -13
  625. package/src/resources/extensions/gsd/tests/remote-questions.test.ts +151 -251
  626. package/src/resources/extensions/gsd/tests/resource-loader-import-path.test.ts +41 -29
  627. package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +58 -69
  628. package/src/resources/extensions/gsd/tests/resume-dispatch-worktree.test.ts +32 -164
  629. package/src/resources/extensions/gsd/tests/right-sized-workflow-prompts.test.ts +192 -0
  630. package/src/resources/extensions/gsd/tests/run-uat-replay-cap.test.ts +57 -41
  631. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +91 -0
  632. package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +29 -0
  633. package/src/resources/extensions/gsd/tests/schema-v27-v28-sequence.test.ts +156 -0
  634. package/src/resources/extensions/gsd/tests/select-resumable-milestone.test.ts +96 -0
  635. package/src/resources/extensions/gsd/tests/session-model-override.test.ts +14 -9
  636. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +77 -0
  637. package/src/resources/extensions/gsd/tests/session-switch-abort-misclassification.test.ts +222 -0
  638. package/src/resources/extensions/gsd/tests/show-config-command.test.ts +44 -42
  639. package/src/resources/extensions/gsd/tests/signal-handlers.test.ts +27 -0
  640. package/src/resources/extensions/gsd/tests/skip-slice-state-rebuild.test.ts +56 -24
  641. package/src/resources/extensions/gsd/tests/skipped-validation-db-atomicity.test.ts +51 -11
  642. package/src/resources/extensions/gsd/tests/slice-cadence.test.ts +23 -0
  643. package/src/resources/extensions/gsd/tests/slice-context-injection.test.ts +66 -50
  644. package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +68 -107
  645. package/src/resources/extensions/gsd/tests/slice-sequence-insert.test.ts +115 -42
  646. package/src/resources/extensions/gsd/tests/smart-entry-complete.test.ts +21 -59
  647. package/src/resources/extensions/gsd/tests/smart-entry-draft.test.ts +25 -116
  648. package/src/resources/extensions/gsd/tests/sqlite-unavailable-gate.test.ts +21 -57
  649. package/src/resources/extensions/gsd/tests/stale-dirlistcache-4648.test.ts +29 -76
  650. package/src/resources/extensions/gsd/tests/stale-lockfile-recovery.test.ts +33 -24
  651. package/src/resources/extensions/gsd/tests/stale-slice-rows.test.ts +39 -30
  652. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +49 -1
  653. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +101 -2
  654. package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +6 -4
  655. package/src/resources/extensions/gsd/tests/status-db-open.test.ts +35 -40
  656. package/src/resources/extensions/gsd/tests/stop-auto-merge-back.test.ts +48 -46
  657. package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +14 -102
  658. package/src/resources/extensions/gsd/tests/subagent-model-dispatch.test.ts +78 -232
  659. package/src/resources/extensions/gsd/tests/sync-worktree-skip-current.test.ts +32 -35
  660. package/src/resources/extensions/gsd/tests/system-context-memory.test.ts +112 -0
  661. package/src/resources/extensions/gsd/tests/system-context-message-routing.test.ts +7 -9
  662. package/src/resources/extensions/gsd/tests/token-profile.test.ts +84 -309
  663. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +291 -0
  664. package/src/resources/extensions/gsd/tests/triage-dispatch.test.ts +134 -341
  665. package/src/resources/extensions/gsd/tests/tui-header-lifecycle.test.ts +210 -0
  666. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +136 -4
  667. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +8 -25
  668. package/src/resources/extensions/gsd/tests/unit-dispatches.test.ts +80 -1
  669. package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +37 -0
  670. package/src/resources/extensions/gsd/tests/unstructured-continue-context-injection.test.ts +5 -99
  671. package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +43 -36
  672. package/src/resources/extensions/gsd/tests/visualizer-data.test.ts +84 -444
  673. package/src/resources/extensions/gsd/tests/workflow-dispatch-claim.test.ts +142 -0
  674. package/src/resources/extensions/gsd/tests/workflow-logger-wiring.test.ts +44 -189
  675. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +2 -57
  676. package/src/resources/extensions/gsd/tests/workflow-protocol-excerpt.test.ts +99 -0
  677. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +3 -0
  678. package/src/resources/extensions/gsd/tests/workflow-worker-heartbeat.test.ts +32 -1
  679. package/src/resources/extensions/gsd/tests/worktree-db-same-file.test.ts +21 -44
  680. package/src/resources/extensions/gsd/tests/worktree-expected-warnings.test.ts +27 -26
  681. package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +38 -6
  682. package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +50 -31
  683. package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +434 -0
  684. package/src/resources/extensions/gsd/tests/worktree-main-branch.test.ts +20 -18
  685. package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +7 -0
  686. package/src/resources/extensions/gsd/tests/worktree-nested-git-safety.test.ts +9 -2
  687. package/src/resources/extensions/gsd/tests/worktree-path-injection.test.ts +22 -19
  688. package/src/resources/extensions/gsd/tests/worktree-project-root-degrade.test.ts +66 -0
  689. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +373 -76
  690. package/src/resources/extensions/gsd/tests/worktree-safety.test.ts +327 -0
  691. package/src/resources/extensions/gsd/tests/worktree-state-projection.test.ts +120 -0
  692. package/src/resources/extensions/gsd/tests/worktree-write-gate.test.ts +179 -0
  693. package/src/resources/extensions/gsd/tests/write-gate.test.ts +40 -1
  694. package/src/resources/extensions/gsd/tests/zero-slice-roadmap-guided.test.ts +19 -13
  695. package/src/resources/extensions/gsd/tool-contract.ts +82 -0
  696. package/src/resources/extensions/gsd/tools/complete-milestone.ts +14 -15
  697. package/src/resources/extensions/gsd/tools/complete-task.ts +1 -1
  698. package/src/resources/extensions/gsd/tools/context-mode-tool-result.ts +25 -0
  699. package/src/resources/extensions/gsd/tools/exec-search-tool.ts +7 -7
  700. package/src/resources/extensions/gsd/tools/exec-tool.ts +4 -23
  701. package/src/resources/extensions/gsd/tools/memory-tools.ts +1 -0
  702. package/src/resources/extensions/gsd/tools/plan-slice.ts +13 -0
  703. package/src/resources/extensions/gsd/tools/plan-task.ts +10 -0
  704. package/src/resources/extensions/gsd/tools/resume-tool.ts +7 -7
  705. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +1 -1
  706. package/src/resources/extensions/gsd/unit-context-composer.ts +19 -4
  707. package/src/resources/extensions/gsd/unit-runtime.ts +25 -0
  708. package/src/resources/extensions/gsd/workflow-protocol.ts +160 -0
  709. package/src/resources/extensions/gsd/worktree-lifecycle.ts +1255 -0
  710. package/src/resources/extensions/gsd/worktree-manager.ts +15 -4
  711. package/src/resources/extensions/gsd/worktree-safety.ts +282 -0
  712. package/src/resources/extensions/gsd/worktree-state-projection.ts +404 -0
  713. package/src/resources/skills/create-gsd-extension/templates/templates.test.ts +86 -40
  714. package/src/resources/skills/web-quality-audit/scripts/analyze.sh +0 -0
  715. package/dist/resources/extensions/gsd/worktree-resolver.js +0 -733
  716. package/dist/web/standalone/.next/static/chunks/8336.631939fb583761fa.js +0 -10
  717. package/src/resources/extensions/gsd/tests/sync-layer-scope.test.ts +0 -434
  718. package/src/resources/extensions/gsd/worktree-resolver.ts +0 -909
  719. /package/dist/web/standalone/.next/static/{y7d--cnc6Cibuva-Lzzw_ → 8G7Lc96dfT0V6VXh6O6Ka}/_buildManifest.js +0 -0
  720. /package/dist/web/standalone/.next/static/{y7d--cnc6Cibuva-Lzzw_ → 8G7Lc96dfT0V6VXh6O6Ka}/_ssgManifest.js +0 -0
@@ -34,12 +34,43 @@ import {
34
34
  } from "../auto-worktree.ts";
35
35
  import { normalizeWorktreePathForCompare } from "../worktree-root.ts";
36
36
  import {
37
- WorktreeResolver,
38
- type WorktreeResolverDeps,
37
+ WorktreeLifecycle,
38
+ type WorktreeLifecycleDeps,
39
39
  type NotifyCtx,
40
- } from "../worktree-resolver.ts";
40
+ } from "../worktree-lifecycle.ts";
41
+ import { WorktreeStateProjection } from "../worktree-state-projection.ts";
42
+ import { resolveWorktreeProjectRoot } from "../worktree-root.ts";
41
43
  import { AutoSession } from "../auto/session.ts";
42
44
 
45
+ // Test-local: LegacyTestDeps had three fields Lifecycle does not need
46
+ // (shouldUseWorktreeIsolation, syncWorktreeStateBack, captureIntegrationBranch).
47
+ // Permit them in test fixtures so existing override patterns keep working —
48
+ // Lifecycle ignores the extras via structural typing.
49
+ type LegacyTestDeps = WorktreeLifecycleDeps & {
50
+ shouldUseWorktreeIsolation?: () => boolean;
51
+ syncWorktreeStateBack?: (
52
+ mainBasePath: string,
53
+ worktreePath: string,
54
+ milestoneId: string,
55
+ ) => { synced: string[] };
56
+ captureIntegrationBranch?: (basePath: string, mid: string | undefined) => void;
57
+ };
58
+
59
+ /** Shim factory preserving the legacy WorktreeResolver throw shape for tests. */
60
+ function makeResolver(s: AutoSession, deps: LegacyTestDeps) {
61
+ const lifecycle = new WorktreeLifecycle(s, deps);
62
+ return {
63
+ get workPath(): string { return s.basePath; },
64
+ get projectRoot(): string {
65
+ return resolveWorktreeProjectRoot(s.basePath, s.originalBasePath);
66
+ },
67
+ mergeAndExit: (mid: string, ctx: NotifyCtx) => {
68
+ const r = lifecycle.exitMilestone(mid, { merge: true }, ctx);
69
+ if (!r.ok && r.cause instanceof Error) throw r.cause;
70
+ },
71
+ };
72
+ }
73
+
43
74
  // ─── Helpers ──────────────────────────────────────────────────────────────────
44
75
 
45
76
  function git(args: string[], cwd: string): void {
@@ -69,10 +100,10 @@ function makeSession(overrides?: Partial<{ basePath: string; originalBasePath: s
69
100
 
70
101
  interface CallLog { fn: string; args: unknown[] }
71
102
 
72
- function makeDeps(overrides?: Partial<WorktreeResolverDeps>): WorktreeResolverDeps & { calls: CallLog[] } {
103
+ function makeDeps(overrides?: Partial<LegacyTestDeps>): LegacyTestDeps & { calls: CallLog[] } {
73
104
  const calls: CallLog[] = [];
74
105
 
75
- const deps: WorktreeResolverDeps & { calls: CallLog[] } = {
106
+ const deps: LegacyTestDeps & { calls: CallLog[] } = {
76
107
  calls,
77
108
  isInAutoWorktree: (basePath: string) => {
78
109
  calls.push({ fn: "isInAutoWorktree", args: [basePath] });
@@ -110,6 +141,9 @@ function makeDeps(overrides?: Partial<WorktreeResolverDeps>): WorktreeResolverDe
110
141
  calls.push({ fn: "getCurrentBranch", args: [basePath] });
111
142
  return "main";
112
143
  },
144
+ checkoutBranch: (basePath: string, branch: string) => {
145
+ calls.push({ fn: "checkoutBranch", args: [basePath, branch] });
146
+ },
113
147
  autoWorktreeBranch: (milestoneId: string) => `milestone/${milestoneId}`,
114
148
  resolveMilestoneFile: (basePath: string, milestoneId: string, fileType: string) => {
115
149
  calls.push({ fn: "resolveMilestoneFile", args: [basePath, milestoneId, fileType] });
@@ -121,11 +155,12 @@ function makeDeps(overrides?: Partial<WorktreeResolverDeps>): WorktreeResolverDe
121
155
  },
122
156
  GitServiceImpl: class {
123
157
  constructor(_basePath: string, _gitConfig: unknown) {}
124
- } as unknown as WorktreeResolverDeps["GitServiceImpl"],
158
+ } as unknown as LegacyTestDeps["GitServiceImpl"],
125
159
  loadEffectiveGSDPreferences: () => ({ preferences: { git: {} } }),
126
160
  invalidateAllCaches: () => { calls.push({ fn: "invalidateAllCaches", args: [] }); },
127
- captureIntegrationBranch: (_basePath: string, _mid: string) => {},
161
+ captureIntegrationBranch: (_basePath: string, _mid: string | undefined) => {},
128
162
  enterBranchModeForMilestone: (_basePath: string, _milestoneId: string) => {},
163
+ worktreeProjection: new WorktreeStateProjection(),
129
164
  ...overrides,
130
165
  };
131
166
 
@@ -270,7 +305,7 @@ describe("WorktreeResolver: roadmap-fallback skipped when basePath is same physi
270
305
  // Override calls ref so we can inspect it directly
271
306
  (deps as unknown as { calls: CallLog[] }).calls = calls;
272
307
 
273
- const resolver = new WorktreeResolver(s, deps);
308
+ const resolver = makeResolver(s, deps);
274
309
  const ctx = makeNotifyCtx();
275
310
 
276
311
  // mergeAndExit → _mergeWorktreeMode
@@ -316,7 +351,7 @@ describe("WorktreeResolver: roadmap-fallback skipped when basePath is same physi
316
351
  });
317
352
  (deps as unknown as { calls: CallLog[] }).calls = calls;
318
353
 
319
- const resolver = new WorktreeResolver(s, deps);
354
+ const resolver = makeResolver(s, deps);
320
355
  const ctx = makeNotifyCtx();
321
356
 
322
357
  resolver.mergeAndExit("M002", ctx);
@@ -0,0 +1,144 @@
1
+ // GSD-2 + src/resources/extensions/gsd/tests/orphan-merge-bootstrap.test.ts
2
+ // Regression: bootstrap must actively merge orphan completed-but-unmerged
3
+ // milestones, not just seed `s.currentMilestoneId` (the seed approach was
4
+ // silently overwritten at auto-start.ts:948 — caught in audit of PR #5549).
5
+ //
6
+ // After ADR-016 / slice 7 step E, _mergeOrphanCompletedMilestone takes a
7
+ // WorktreeLifecycle and inspects the typed ExitResult instead of catching
8
+ // a throw — the fakeLifecycle below returns {ok:false, cause} to model the
9
+ // previous throw shape.
10
+
11
+ import test from "node:test";
12
+ import assert from "node:assert/strict";
13
+
14
+ import { _mergeOrphanCompletedMilestone } from "../auto-start.js";
15
+ import type { WorktreeLifecycle } from "../worktree-lifecycle.js";
16
+
17
+ interface FakeLifecycleState {
18
+ mergeCalls: Array<{ milestoneId: string }>;
19
+ causeOnFail?: unknown;
20
+ }
21
+
22
+ function fakeLifecycle(state: FakeLifecycleState): WorktreeLifecycle {
23
+ return {
24
+ exitMilestone: (milestoneId: string) => {
25
+ state.mergeCalls.push({ milestoneId });
26
+ if (state.causeOnFail !== undefined) {
27
+ return { ok: false, reason: "teardown-failed", cause: state.causeOnFail };
28
+ }
29
+ return { ok: true, merged: true, codeFilesChanged: false };
30
+ },
31
+ } as unknown as WorktreeLifecycle;
32
+ }
33
+
34
+ interface FakeUiState {
35
+ notifications: Array<{ message: string; level: string }>;
36
+ }
37
+
38
+ function fakeUi(state: FakeUiState): {
39
+ notify: (msg: string, level?: "info" | "warning" | "error" | "success") => void;
40
+ } {
41
+ return {
42
+ notify: (message: string, level?: "info" | "warning" | "error" | "success") => {
43
+ state.notifications.push({ message, level: level ?? "info" });
44
+ },
45
+ };
46
+ }
47
+
48
+ test("happy path: orphan merge runs, returns merged:true, emits info notify", () => {
49
+ const lcState: FakeLifecycleState = { mergeCalls: [] };
50
+ const uiState: FakeUiState = { notifications: [] };
51
+ const result = _mergeOrphanCompletedMilestone(
52
+ fakeLifecycle(lcState),
53
+ "M002",
54
+ fakeUi(uiState),
55
+ );
56
+
57
+ assert.deepEqual(result, { merged: true });
58
+ assert.deepEqual(lcState.mergeCalls, [{ milestoneId: "M002" }]);
59
+ assert.equal(uiState.notifications.length, 1);
60
+ assert.deepEqual(uiState.notifications[0], {
61
+ message: "Detected unmerged completed milestone M002. Merging now.",
62
+ level: "info",
63
+ });
64
+ });
65
+
66
+ test("regression: failure from exitMilestone (e.g. wrong-branch from PR #5549 commit 5) does not bubble out", () => {
67
+ // Commit 5 (68ef58a3c) made `_mergeBranchMode` throw on wrong branch
68
+ // instead of silently returning false. Lifecycle now wraps the throw in
69
+ // {ok:false, cause}; _mergeOrphanCompletedMilestone must surface that as
70
+ // a notify, never re-throwing into the slash-command caller.
71
+ const boom = new Error("dirty working tree blocks checkout");
72
+ const lcState: FakeLifecycleState = { mergeCalls: [], causeOnFail: boom };
73
+ const uiState: FakeUiState = { notifications: [] };
74
+
75
+ const result = _mergeOrphanCompletedMilestone(
76
+ fakeLifecycle(lcState),
77
+ "M002",
78
+ fakeUi(uiState),
79
+ );
80
+
81
+ assert.equal(result.merged, false);
82
+ assert.equal(result.error, boom);
83
+
84
+ // First notify announces the merge attempt; second notify reports the failure.
85
+ assert.equal(uiState.notifications.length, 2);
86
+ assert.equal(uiState.notifications[0].level, "info");
87
+ assert.equal(uiState.notifications[1].level, "warning");
88
+ assert.match(
89
+ uiState.notifications[1].message,
90
+ /Could not merge orphan milestone M002/,
91
+ );
92
+ assert.match(uiState.notifications[1].message, /dirty working tree blocks checkout/);
93
+ assert.match(uiState.notifications[1].message, /Resolve manually/);
94
+ });
95
+
96
+ test("non-Error failure causes are still captured and notified", () => {
97
+ // Defensive: non-Error causes (strings, numbers) must not crash the formatter.
98
+ const lcState: FakeLifecycleState = {
99
+ mergeCalls: [],
100
+ // mimic a non-Error cause
101
+ causeOnFail: "git lock held",
102
+ };
103
+ const uiState: FakeUiState = { notifications: [] };
104
+
105
+ const result = _mergeOrphanCompletedMilestone(
106
+ fakeLifecycle(lcState),
107
+ "M002",
108
+ fakeUi(uiState),
109
+ );
110
+
111
+ assert.equal(result.merged, false);
112
+ assert.equal(uiState.notifications[1].level, "warning");
113
+ assert.match(uiState.notifications[1].message, /git lock held/);
114
+ });
115
+
116
+ test("the exitMilestone call receives a notify-bound NotifyCtx the lifecycle can invoke", () => {
117
+ // The lifecycle's NotifyCtx must be wired to ui.notify so user-facing
118
+ // messages from inside exitMilestone (e.g. "Milestone Mxxx merged") still
119
+ // reach the UI. Verify by having the fake invoke ctx.notify.
120
+ const uiState: FakeUiState = { notifications: [] };
121
+ const ui = fakeUi(uiState);
122
+
123
+ const lifecycle = {
124
+ exitMilestone: (
125
+ _milestoneId: string,
126
+ _opts: { merge: boolean },
127
+ ctx: { notify: (msg: string, level?: "info" | "warning" | "error" | "success") => void },
128
+ ) => {
129
+ ctx.notify("inner success message", "success");
130
+ return { ok: true, merged: true, codeFilesChanged: false };
131
+ },
132
+ } as unknown as WorktreeLifecycle;
133
+
134
+ const result = _mergeOrphanCompletedMilestone(lifecycle, "M002", ui);
135
+
136
+ assert.equal(result.merged, true);
137
+ // 1: outer "Detected unmerged completed milestone..."
138
+ // 2: inner "inner success message" emitted via the bound ctx.notify
139
+ assert.equal(uiState.notifications.length, 2);
140
+ assert.deepEqual(uiState.notifications[1], {
141
+ message: "inner success message",
142
+ level: "success",
143
+ });
144
+ });
@@ -0,0 +1,201 @@
1
+ // GSD-2 + src/resources/extensions/gsd/tests/orphan-stash-audit.test.ts
2
+ // Regression: orphaned gsd-preflight-stash entries from completed milestones
3
+ // must be auto-applied at startup so the user's pre-merge work returns.
4
+
5
+ import { describe, test, beforeEach, afterEach } from "node:test";
6
+ import assert from "node:assert/strict";
7
+ import { execFileSync } from "node:child_process";
8
+ import { mkdtempSync, rmSync, writeFileSync, readFileSync, existsSync } from "node:fs";
9
+ import { tmpdir } from "node:os";
10
+ import { join } from "node:path";
11
+
12
+ import {
13
+ auditOrphanedPreflightStashes,
14
+ _isAlreadyRestoredApplyError,
15
+ } from "../orphan-stash-audit.js";
16
+
17
+ function git(cwd: string, ...args: string[]): string {
18
+ return execFileSync("git", args, {
19
+ cwd,
20
+ stdio: ["ignore", "pipe", "pipe"],
21
+ encoding: "utf-8",
22
+ env: {
23
+ ...process.env,
24
+ GIT_TERMINAL_PROMPT: "0",
25
+ GIT_AUTHOR_NAME: "test",
26
+ GIT_AUTHOR_EMAIL: "test@example.com",
27
+ GIT_COMMITTER_NAME: "test",
28
+ GIT_COMMITTER_EMAIL: "test@example.com",
29
+ },
30
+ });
31
+ }
32
+
33
+ function pushPreflightStash(repo: string, milestoneId: string, fileName: string, content: string): string {
34
+ writeFileSync(join(repo, fileName), content);
35
+ const marker = `gsd-preflight-stash:${milestoneId}:42:1700000000000:abcd`;
36
+ git(repo, "stash", "push", "--include-untracked", "-m", `gsd-preflight-stash [${marker}]`);
37
+ return marker;
38
+ }
39
+
40
+ describe("auditOrphanedPreflightStashes", () => {
41
+ let repo: string;
42
+
43
+ beforeEach(() => {
44
+ repo = mkdtempSync(join(tmpdir(), "orphan-stash-audit-"));
45
+ git(repo, "init", "-q");
46
+ git(repo, "config", "user.email", "test@example.com");
47
+ git(repo, "config", "user.name", "test");
48
+ writeFileSync(join(repo, "seed.txt"), "seed\n");
49
+ git(repo, "add", "seed.txt");
50
+ git(repo, "commit", "-q", "-m", "initial");
51
+ });
52
+
53
+ afterEach(() => {
54
+ if (repo && existsSync(repo)) {
55
+ rmSync(repo, { recursive: true, force: true });
56
+ }
57
+ });
58
+
59
+ test("returns empty result when there are no stashes", () => {
60
+ const result = auditOrphanedPreflightStashes(repo, () => true);
61
+ assert.deepEqual(result, { applied: [], warnings: [] });
62
+ });
63
+
64
+ test("applies an orphan preflight stash when its milestone is complete", () => {
65
+ pushPreflightStash(repo, "M002", "leftover.txt", "lost work\n");
66
+
67
+ // Verify the file is gone (stashed away) before the audit runs.
68
+ assert.equal(existsSync(join(repo, "leftover.txt")), false, "stash push must remove the file");
69
+
70
+ const result = auditOrphanedPreflightStashes(repo, (id) => id === "M002");
71
+
72
+ assert.equal(result.applied.length, 1, "expected exactly one stash applied");
73
+ assert.equal(result.applied[0].milestoneId, "M002");
74
+ assert.match(result.applied[0].stashRef, /^stash@\{\d+\}$/);
75
+ assert.equal(result.warnings.length, 0);
76
+
77
+ // The user's pre-merge content must be back in the working tree.
78
+ assert.equal(existsSync(join(repo, "leftover.txt")), true);
79
+ assert.equal(readFileSync(join(repo, "leftover.txt"), "utf-8"), "lost work\n");
80
+
81
+ // The stash entry must remain (apply, not pop) so the user has a backup.
82
+ const list = git(repo, "stash", "list");
83
+ assert.match(list, /gsd-preflight-stash:M002:/);
84
+ });
85
+
86
+ test("ignores stashes whose milestone is not complete", () => {
87
+ pushPreflightStash(repo, "M003", "wip.txt", "still-working\n");
88
+
89
+ const result = auditOrphanedPreflightStashes(repo, () => false);
90
+
91
+ assert.deepEqual(result, { applied: [], warnings: [] });
92
+ // File stays stashed.
93
+ assert.equal(existsSync(join(repo, "wip.txt")), false);
94
+ });
95
+
96
+ test("ignores non-gsd stash entries", () => {
97
+ writeFileSync(join(repo, "manual.txt"), "manual\n");
98
+ git(repo, "stash", "push", "--include-untracked", "-m", "user manual stash");
99
+
100
+ const result = auditOrphanedPreflightStashes(repo, () => true);
101
+
102
+ assert.deepEqual(result, { applied: [], warnings: [] });
103
+ });
104
+
105
+ test("collects a warning when the completion callback throws", () => {
106
+ pushPreflightStash(repo, "M004", "danger.txt", "boom\n");
107
+
108
+ const result = auditOrphanedPreflightStashes(repo, () => {
109
+ throw new Error("db unavailable");
110
+ });
111
+
112
+ assert.equal(result.applied.length, 0);
113
+ assert.equal(result.warnings.length, 1);
114
+ assert.match(result.warnings[0], /Could not determine completion status for M004/);
115
+ assert.match(result.warnings[0], /db unavailable/);
116
+ });
117
+
118
+ test("collects a warning when stash apply fails (conflicting working tree)", () => {
119
+ // Push a stash containing a change to seed.txt; then dirty seed.txt with
120
+ // a conflicting modification before the audit runs so apply fails.
121
+ writeFileSync(join(repo, "seed.txt"), "stashed\n");
122
+ const marker = `gsd-preflight-stash:M005:42:1700:zz`;
123
+ git(repo, "stash", "push", "-m", `gsd-preflight-stash [${marker}]`);
124
+
125
+ // Dirty the working tree so apply will conflict.
126
+ writeFileSync(join(repo, "seed.txt"), "conflicting modification\n");
127
+
128
+ const result = auditOrphanedPreflightStashes(repo, () => true);
129
+
130
+ assert.equal(result.applied.length, 0);
131
+ assert.equal(result.warnings.length, 1);
132
+ assert.match(result.warnings[0], /Could not apply orphaned preflight stash/);
133
+ assert.match(result.warnings[0], /M005/);
134
+ assert.match(result.warnings[0], /git stash apply/);
135
+
136
+ const list = git(repo, "stash", "list");
137
+ assert.match(list, /gsd-preflight-stash:M005:/);
138
+ });
139
+
140
+ test("returns empty result when basePath is not a git repo", () => {
141
+ const nonRepo = mkdtempSync(join(tmpdir(), "orphan-stash-not-repo-"));
142
+ try {
143
+ const result = auditOrphanedPreflightStashes(nonRepo, () => true);
144
+ assert.deepEqual(result, { applied: [], warnings: [] });
145
+ } finally {
146
+ rmSync(nonRepo, { recursive: true, force: true });
147
+ }
148
+ });
149
+
150
+ test("repeat run is a silent no-op when files were already restored (peer-review regression)", () => {
151
+ // Codex peer review caught: the first audit applies the stash and the
152
+ // file appears in the working tree. The stash entry stays in `git stash
153
+ // list` (apply, not pop). On the next audit, `git stash apply` exits
154
+ // non-zero with "already exists, no checkout" because the untracked file
155
+ // already exists. The original code surfaced that as a warning every
156
+ // startup. The fix detects that error and treats it as the idempotent
157
+ // steady state.
158
+ pushPreflightStash(repo, "M002", "leftover.txt", "lost work\n");
159
+
160
+ const first = auditOrphanedPreflightStashes(repo, () => true);
161
+ assert.equal(first.applied.length, 1, "first run applies");
162
+ assert.equal(first.warnings.length, 0);
163
+
164
+ const second = auditOrphanedPreflightStashes(repo, () => true);
165
+ assert.equal(second.applied.length, 0, "second run skips silently");
166
+ assert.equal(
167
+ second.warnings.length,
168
+ 0,
169
+ "second run must NOT warn — files are already restored from first run",
170
+ );
171
+ });
172
+ });
173
+
174
+ test("_isAlreadyRestoredApplyError detects the git stash apply already-exists error", () => {
175
+ // Real-world stderr produced by git when an --include-untracked stash is
176
+ // applied while the file already exists in the working tree.
177
+ const realError: { stderr: string } = {
178
+ stderr: "leftover.txt already exists, no checkout\nCould not restore untracked files from stash entry\n",
179
+ };
180
+ assert.equal(_isAlreadyRestoredApplyError(realError), true);
181
+
182
+ // Buffer-form stderr (when encoding is not set explicitly).
183
+ const bufErr = { stderr: Buffer.from("foo.ts already exists, no checkout\n") };
184
+ assert.equal(_isAlreadyRestoredApplyError(bufErr), true);
185
+
186
+ // Some Node versions surface the message in err.message.
187
+ const messageOnly = new Error("Command failed: git stash apply\nfoo.ts already exists, no checkout");
188
+ assert.equal(_isAlreadyRestoredApplyError(messageOnly), true);
189
+
190
+ // Unrelated errors must NOT be classified as already-restored.
191
+ const realConflict: { stderr: string } = {
192
+ stderr: "CONFLICT (content): Merge conflict in lib/models.ts\n",
193
+ };
194
+ assert.equal(_isAlreadyRestoredApplyError(realConflict), false);
195
+
196
+ // Defensive null/undefined handling.
197
+ assert.equal(_isAlreadyRestoredApplyError(null), false);
198
+ assert.equal(_isAlreadyRestoredApplyError(undefined), false);
199
+ assert.equal(_isAlreadyRestoredApplyError("not an error"), false);
200
+ assert.equal(_isAlreadyRestoredApplyError({}), false);
201
+ });
@@ -0,0 +1,113 @@
1
+ // GSD-2 + src/resources/extensions/gsd/tests/parallel-orchestrator-fast-forward.test.ts
2
+ // Regression: parallel-orchestrator's `_createMilestoneWorktree` must
3
+ // fast-forward a reused milestone branch onto integration before creating
4
+ // the worktree, matching the behavior added to the auto-mode path in
5
+ // commit 8996cb68e (#5549 post-merge audit, R3).
6
+
7
+ import { describe, test, beforeEach, afterEach } from "node:test";
8
+ import assert from "node:assert/strict";
9
+ import { execFileSync } from "node:child_process";
10
+ import { mkdtempSync, rmSync, writeFileSync, mkdirSync } from "node:fs";
11
+ import { tmpdir } from "node:os";
12
+ import { join } from "node:path";
13
+
14
+ import { _createMilestoneWorktree } from "../parallel-orchestrator.js";
15
+
16
+ const NO_PROMPT_ENV = {
17
+ ...process.env,
18
+ GIT_TERMINAL_PROMPT: "0",
19
+ GIT_AUTHOR_NAME: "test",
20
+ GIT_AUTHOR_EMAIL: "test@example.com",
21
+ GIT_COMMITTER_NAME: "test",
22
+ GIT_COMMITTER_EMAIL: "test@example.com",
23
+ };
24
+
25
+ function git(cwd: string, ...args: string[]): string {
26
+ return execFileSync("git", args, {
27
+ cwd,
28
+ stdio: ["ignore", "pipe", "pipe"],
29
+ encoding: "utf-8",
30
+ env: NO_PROMPT_ENV,
31
+ });
32
+ }
33
+
34
+ function rev(cwd: string, ref: string): string {
35
+ return git(cwd, "rev-parse", ref).trim();
36
+ }
37
+
38
+ describe("_createMilestoneWorktree fast-forwards reused milestone branches (#5549 R3)", () => {
39
+ let repo: string;
40
+
41
+ beforeEach(() => {
42
+ repo = mkdtempSync(join(tmpdir(), "parallel-orch-ff-"));
43
+ git(repo, "init", "-q", "-b", "main");
44
+ git(repo, "config", "user.email", "test@example.com");
45
+ git(repo, "config", "user.name", "test");
46
+ writeFileSync(join(repo, "seed.txt"), "seed\n");
47
+ git(repo, "add", "seed.txt");
48
+ git(repo, "commit", "-q", "-m", "initial");
49
+ // Minimal .gsd/ structure so syncGsdStateToWorktree doesn't crash on a
50
+ // bare repo. We don't care if it copies anything — only that the FF ran.
51
+ mkdirSync(join(repo, ".gsd"), { recursive: true });
52
+ });
53
+
54
+ afterEach(() => {
55
+ rmSync(repo, { recursive: true, force: true });
56
+ });
57
+
58
+ test("reused milestone branch behind main is fast-forwarded before worktree creation", () => {
59
+ // Worker N drained M001 in a previous run, leaving milestone/M001 forked
60
+ // from old main. Worker N+1 picks up M002 — but the milestone/M002 branch
61
+ // was created from old main in a sibling run, so it's now N commits behind.
62
+ git(repo, "branch", "milestone/M002");
63
+ const m002Initial = rev(repo, "milestone/M002");
64
+
65
+ writeFileSync(join(repo, "seed.txt"), "main moved forward\n");
66
+ git(repo, "add", "seed.txt");
67
+ git(repo, "commit", "-q", "-m", "main advanced");
68
+ const mainTip = rev(repo, "main");
69
+
70
+ assert.notEqual(m002Initial, mainTip, "main must be ahead before the test");
71
+
72
+ // _createMilestoneWorktree may throw inside createWorktree/syncGsdStateToWorktree
73
+ // (e.g. if the worktree-manager has stricter requirements than this minimal
74
+ // repo provides). The fast-forward runs BEFORE those calls, so the branch
75
+ // ref should have moved regardless. Catch and assert on observable state.
76
+ try {
77
+ _createMilestoneWorktree(repo, "M002");
78
+ } catch {
79
+ // Fine — we only care that FF executed.
80
+ }
81
+
82
+ assert.equal(
83
+ rev(repo, "milestone/M002"),
84
+ mainTip,
85
+ "milestone/M002 must be fast-forwarded to main's tip before worktree is built",
86
+ );
87
+ });
88
+
89
+ test("diverged milestone branch is NOT touched (would lose work)", () => {
90
+ git(repo, "checkout", "-q", "-b", "milestone/M002");
91
+ writeFileSync(join(repo, "wip.txt"), "milestone-only work\n");
92
+ git(repo, "add", "wip.txt");
93
+ git(repo, "commit", "-q", "-m", "M002 work");
94
+ const m002Tip = rev(repo, "milestone/M002");
95
+
96
+ git(repo, "checkout", "-q", "main");
97
+ writeFileSync(join(repo, "seed.txt"), "main moved forward\n");
98
+ git(repo, "add", "seed.txt");
99
+ git(repo, "commit", "-q", "-m", "main advanced");
100
+
101
+ try {
102
+ _createMilestoneWorktree(repo, "M002");
103
+ } catch {
104
+ // ignored
105
+ }
106
+
107
+ assert.equal(
108
+ rev(repo, "milestone/M002"),
109
+ m002Tip,
110
+ "diverged milestone branch must NOT be touched — would lose committed work",
111
+ );
112
+ });
113
+ });
@@ -8,48 +8,35 @@
8
8
  * The fix makes isGhostMilestone treat a "queued" DB row with no disk
9
9
  * artifacts (CONTEXT, ROADMAP, SUMMARY) as a ghost.
10
10
  *
11
- * This structural test verifies the dbRow.status === 'queued' guard exists.
11
+ * This behavior test exercises isGhostMilestone against real DB rows and
12
+ * milestone artifacts.
12
13
  */
13
14
 
14
15
  import { describe, test } from 'node:test';
15
16
  import assert from 'node:assert/strict';
16
- import { readFileSync } from 'node:fs';
17
- import { fileURLToPath } from 'node:url';
18
- import { dirname, join } from 'node:path';
19
-
20
- const __filename = fileURLToPath(import.meta.url);
21
- const __dirname = dirname(__filename);
22
-
23
- const source = readFileSync(join(__dirname, '..', 'state.ts'), 'utf-8');
17
+ import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs';
18
+ import { join } from 'node:path';
19
+ import { tmpdir } from 'node:os';
20
+ import { closeDatabase, insertMilestone, openDatabase } from '../gsd-db.ts';
21
+ import { clearPathCache } from '../paths.ts';
22
+ import { isGhostMilestone } from '../state.ts';
24
23
 
25
24
  describe('isGhostMilestone phantom queued detection (#3671)', () => {
26
- test('isGhostMilestone function exists', () => {
27
- assert.match(source, /export function isGhostMilestone\(/,
28
- 'isGhostMilestone should be exported');
29
- });
30
-
31
- test('checks dbRow.status === queued', () => {
32
- assert.match(source, /dbRow\.status\s*===\s*['"]queued['"]/,
33
- 'isGhostMilestone should check dbRow.status === "queued"');
34
- });
35
-
36
- test('checks for CONTEXT disk artifact', () => {
37
- assert.match(source, /resolveMilestoneFile\(basePath,\s*mid,\s*["']CONTEXT["']\)/,
38
- 'should check for CONTEXT file');
39
- });
40
-
41
- test('checks for ROADMAP disk artifact', () => {
42
- assert.match(source, /resolveMilestoneFile\(basePath,\s*mid,\s*["']ROADMAP["']\)/,
43
- 'should check for ROADMAP file');
44
- });
45
-
46
- test('checks for SUMMARY disk artifact', () => {
47
- assert.match(source, /resolveMilestoneFile\(basePath,\s*mid,\s*["']SUMMARY["']\)/,
48
- 'should check for SUMMARY file');
49
- });
50
-
51
- test('returns !hasContent for queued rows (ghost if no artifacts)', () => {
52
- assert.match(source, /return !hasContent/,
53
- 'should return !hasContent for queued phantom milestones');
25
+ test('queued DB row with no artifacts is a ghost, but content makes it real', () => {
26
+ const base = mkdtempSync(join(tmpdir(), 'gsd-phantom-ghost-'));
27
+ try {
28
+ openDatabase(':memory:');
29
+ insertMilestone({ id: 'M001', title: 'Reserved only', status: 'queued' });
30
+ mkdirSync(join(base, '.gsd', 'milestones', 'M001'), { recursive: true });
31
+
32
+ assert.equal(isGhostMilestone(base, 'M001'), true);
33
+
34
+ writeFileSync(join(base, '.gsd', 'milestones', 'M001', 'M001-CONTEXT.md'), '# Context\n');
35
+ clearPathCache();
36
+ assert.equal(isGhostMilestone(base, 'M001'), false);
37
+ } finally {
38
+ closeDatabase();
39
+ rmSync(base, { recursive: true, force: true });
40
+ }
54
41
  });
55
42
  });
@@ -8,32 +8,17 @@
8
8
 
9
9
  import { describe, test } from 'node:test';
10
10
  import assert from 'node:assert/strict';
11
- import { readFileSync } from 'node:fs';
12
- import { fileURLToPath } from 'node:url';
13
- import { dirname, join } from 'node:path';
14
-
15
- const __filename = fileURLToPath(import.meta.url);
16
- const __dirname = dirname(__filename);
17
-
18
- const dbSrc = readFileSync(
19
- join(__dirname, '..', 'gsd-db.ts'),
20
- 'utf-8',
21
- );
11
+ import { closeDatabase, getMilestone, insertMilestone, openDatabase } from '../gsd-db.ts';
22
12
 
23
13
  describe('insertMilestone defaults status to queued (#3695)', () => {
24
- test('insertMilestone function exists', () => {
25
- assert.match(dbSrc, /export function insertMilestone\(/,
26
- 'insertMilestone should be exported from gsd-db.ts');
27
- });
28
-
29
- test('default status is "queued" not "active"', () => {
30
- // The status parameter should default to "queued" via nullish coalescing
31
- assert.match(dbSrc, /m\.status\s*\?\?\s*"queued"/,
32
- 'insertMilestone should default status to "queued"');
33
- });
14
+ test('omitted status persists as queued, not active', () => {
15
+ try {
16
+ openDatabase(':memory:');
17
+ insertMilestone({ id: 'M001', title: 'Reserved milestone' });
34
18
 
35
- test('comment explains the rationale', () => {
36
- assert.match(dbSrc, /never auto-create milestones as "active"/i,
37
- 'should have a comment explaining why default is queued');
19
+ assert.equal(getMilestone('M001')?.status, 'queued');
20
+ } finally {
21
+ closeDatabase();
22
+ }
38
23
  });
39
24
  });