gsd-pi 2.77.0-dev.58d3d4d6c → 2.77.0-dev.cfd69e714

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 (429) hide show
  1. package/README.md +1 -1
  2. package/dist/claude-cli-check.js +5 -1
  3. package/dist/headless.js +49 -4
  4. package/dist/resource-loader.d.ts +40 -0
  5. package/dist/resource-loader.js +32 -13
  6. package/dist/resources/extensions/browser-tools/capture.js +9 -0
  7. package/dist/resources/extensions/browser-tools/tests/browser-tools-integration.test.mjs +8 -59
  8. package/dist/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +36 -24
  9. package/dist/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +69 -71
  10. package/dist/resources/extensions/browser-tools/tools/forms.js +5 -1
  11. package/dist/resources/extensions/browser-tools/tools/intent.js +5 -1
  12. package/dist/resources/extensions/claude-code-cli/readiness.js +5 -1
  13. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +481 -17
  14. package/dist/resources/extensions/gsd/auto/loop.js +43 -0
  15. package/dist/resources/extensions/gsd/auto/phases.js +15 -21
  16. package/dist/resources/extensions/gsd/auto/session.js +0 -2
  17. package/dist/resources/extensions/gsd/auto-dispatch.js +102 -24
  18. package/dist/resources/extensions/gsd/auto-model-selection.js +124 -4
  19. package/dist/resources/extensions/gsd/auto-post-unit.js +71 -64
  20. package/dist/resources/extensions/gsd/auto-prompts.js +329 -102
  21. package/dist/resources/extensions/gsd/auto-recovery.js +195 -23
  22. package/dist/resources/extensions/gsd/auto-start.js +34 -24
  23. package/dist/resources/extensions/gsd/auto-tool-tracking.js +47 -7
  24. package/dist/resources/extensions/gsd/auto-worktree.js +122 -26
  25. package/dist/resources/extensions/gsd/auto.js +31 -20
  26. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +9 -1
  27. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +209 -0
  28. package/dist/resources/extensions/gsd/bootstrap/provider-error-resume.js +3 -6
  29. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +7 -3
  30. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +127 -9
  31. package/dist/resources/extensions/gsd/component-loader.js +447 -0
  32. package/dist/resources/extensions/gsd/component-types.js +69 -0
  33. package/dist/resources/extensions/gsd/detection.js +49 -1
  34. package/dist/resources/extensions/gsd/docs/preferences-reference.md +1 -1
  35. package/dist/resources/extensions/gsd/gate-registry.js +2 -2
  36. package/dist/resources/extensions/gsd/git-constants.js +28 -1
  37. package/dist/resources/extensions/gsd/git-self-heal.js +27 -0
  38. package/dist/resources/extensions/gsd/git-service.js +126 -2
  39. package/dist/resources/extensions/gsd/gsd-db.js +6 -3
  40. package/dist/resources/extensions/gsd/guided-flow.js +17 -5
  41. package/dist/resources/extensions/gsd/memory-extractor.js +7 -1
  42. package/dist/resources/extensions/gsd/milestone-scope-classifier.js +299 -0
  43. package/dist/resources/extensions/gsd/model-cost-table.js +3 -0
  44. package/dist/resources/extensions/gsd/model-router.js +6 -0
  45. package/dist/resources/extensions/gsd/native-git-bridge.js +34 -4
  46. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +6 -2
  47. package/dist/resources/extensions/gsd/prompts/plan-slice.md +15 -2
  48. package/dist/resources/extensions/gsd/safety/git-checkpoint.js +11 -0
  49. package/dist/resources/extensions/gsd/service-tier.js +5 -2
  50. package/dist/resources/extensions/gsd/session-lock.js +19 -10
  51. package/dist/resources/extensions/gsd/skill-manifest.js +168 -0
  52. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +278 -8
  53. package/dist/resources/extensions/gsd/state.js +44 -33
  54. package/dist/resources/extensions/gsd/sync-lock.js +98 -42
  55. package/dist/resources/extensions/gsd/unit-context-composer.js +147 -0
  56. package/dist/resources/extensions/gsd/unit-context-manifest.js +370 -0
  57. package/dist/resources/extensions/gsd/uok/gate-runner.js +53 -5
  58. package/dist/resources/extensions/gsd/workflow-mcp.js +6 -0
  59. package/dist/resources/extensions/gsd/worktree-manager.js +34 -8
  60. package/dist/resources/extensions/mcp-client/index.js +3 -1
  61. package/dist/resources/extensions/ollama/index.js +5 -1
  62. package/dist/resources/extensions/remote-questions/manager.js +11 -5
  63. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  64. package/dist/web/standalone/.next/BUILD_ID +1 -1
  65. package/dist/web/standalone/.next/app-path-routes-manifest.json +5 -5
  66. package/dist/web/standalone/.next/build-manifest.json +2 -2
  67. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  68. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  69. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  70. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  71. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  72. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  73. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  74. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  75. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  76. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  77. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  78. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  79. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  80. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  81. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  82. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  83. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  84. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  85. package/dist/web/standalone/.next/server/app/index.html +1 -1
  86. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  87. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  88. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  89. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  90. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  91. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  92. package/dist/web/standalone/.next/server/app-paths-manifest.json +5 -5
  93. package/dist/web/standalone/.next/server/chunks/1926.js +1 -1
  94. package/dist/web/standalone/.next/server/chunks/6897.js +1 -1
  95. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  96. package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
  97. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  98. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  99. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  100. package/package.json +2 -3
  101. package/packages/daemon/src/logger.ts +4 -3
  102. package/packages/mcp-server/dist/server.d.ts +24 -0
  103. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  104. package/packages/mcp-server/dist/server.js +88 -87
  105. package/packages/mcp-server/dist/server.js.map +1 -1
  106. package/packages/mcp-server/src/mcp-server.test.ts +25 -3
  107. package/packages/mcp-server/src/readers/graph.test.ts +87 -15
  108. package/packages/mcp-server/src/secure-env-collect.test.ts +232 -237
  109. package/packages/mcp-server/src/server.ts +131 -105
  110. package/packages/mcp-server/src/workflow-tools.test.ts +80 -39
  111. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  112. package/packages/native/package.json +1 -1
  113. package/packages/native/src/__tests__/_test-coverage-guard.test.mjs +98 -0
  114. package/packages/native/src/__tests__/module-compat.test.mjs +59 -27
  115. package/packages/native/src/__tests__/ps.test.mjs +14 -8
  116. package/packages/native/src/__tests__/stream-process.test.mjs +23 -2
  117. package/packages/native/src/__tests__/truncate.test.mjs +17 -2
  118. package/packages/pi-agent-core/src/agent-loop.test.ts +5 -15
  119. package/packages/pi-agent-core/src/agent.test.ts +96 -102
  120. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  121. package/packages/pi-ai/dist/models/capability-patches.d.ts.map +1 -1
  122. package/packages/pi-ai/dist/models/capability-patches.js +9 -2
  123. package/packages/pi-ai/dist/models/capability-patches.js.map +1 -1
  124. package/packages/pi-ai/dist/models/generated/index.d.ts +34 -0
  125. package/packages/pi-ai/dist/models/generated/index.d.ts.map +1 -1
  126. package/packages/pi-ai/dist/models/generated/openai-codex.d.ts +17 -0
  127. package/packages/pi-ai/dist/models/generated/openai-codex.d.ts.map +1 -1
  128. package/packages/pi-ai/dist/models/generated/openai-codex.js +17 -0
  129. package/packages/pi-ai/dist/models/generated/openai-codex.js.map +1 -1
  130. package/packages/pi-ai/dist/models/generated/openai.d.ts +17 -0
  131. package/packages/pi-ai/dist/models/generated/openai.d.ts.map +1 -1
  132. package/packages/pi-ai/dist/models/generated/openai.js +17 -0
  133. package/packages/pi-ai/dist/models/generated/openai.js.map +1 -1
  134. package/packages/pi-ai/dist/models.generated.test.js +43 -70
  135. package/packages/pi-ai/dist/models.generated.test.js.map +1 -1
  136. package/packages/pi-ai/dist/models.test.js +36 -11
  137. package/packages/pi-ai/dist/models.test.js.map +1 -1
  138. package/packages/pi-ai/scripts/generate-models.ts +44 -0
  139. package/packages/pi-ai/src/models/capability-patches.ts +10 -2
  140. package/packages/pi-ai/src/models/generated/openai-codex.ts +17 -0
  141. package/packages/pi-ai/src/models/generated/openai.ts +17 -0
  142. package/packages/pi-ai/src/models.generated.test.ts +46 -73
  143. package/packages/pi-ai/src/models.test.ts +48 -11
  144. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  145. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +96 -32
  146. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js.map +1 -1
  147. package/packages/pi-coding-agent/dist/core/agent-session-model-switch.test.js +75 -12
  148. package/packages/pi-coding-agent/dist/core/agent-session-model-switch.test.js.map +1 -1
  149. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js +99 -31
  150. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js.map +1 -1
  151. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts +5 -0
  152. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  153. package/packages/pi-coding-agent/dist/core/extensions/loader.js +61 -0
  154. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  155. package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.js +30 -4
  156. package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.js.map +1 -1
  157. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +17 -0
  158. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -1
  159. package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.js +76 -18
  160. package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.js.map +1 -1
  161. package/packages/pi-coding-agent/dist/core/retry-handler.d.ts.map +1 -1
  162. package/packages/pi-coding-agent/dist/core/retry-handler.js +2 -6
  163. package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -1
  164. package/packages/pi-coding-agent/dist/core/retry-handler.test.js +5 -1
  165. package/packages/pi-coding-agent/dist/core/retry-handler.test.js.map +1 -1
  166. package/packages/pi-coding-agent/dist/core/retryable-error-regex.d.ts +18 -0
  167. package/packages/pi-coding-agent/dist/core/retryable-error-regex.d.ts.map +1 -0
  168. package/packages/pi-coding-agent/dist/core/retryable-error-regex.js +18 -0
  169. package/packages/pi-coding-agent/dist/core/retryable-error-regex.js.map +1 -0
  170. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts +20 -0
  171. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
  172. package/packages/pi-coding-agent/dist/core/system-prompt.js +16 -2
  173. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  174. package/packages/pi-coding-agent/dist/index.d.ts +1 -0
  175. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  176. package/packages/pi-coding-agent/dist/index.js +1 -0
  177. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  178. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.js +20 -13
  179. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.js.map +1 -1
  180. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
  181. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +18 -3
  182. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  183. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +125 -0
  184. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
  185. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts +2 -0
  186. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -1
  187. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.js.map +1 -1
  188. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +4 -0
  189. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  190. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +105 -13
  191. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  192. package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.d.ts +2 -0
  193. package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.d.ts.map +1 -0
  194. package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.js +130 -0
  195. package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.js.map +1 -0
  196. package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +113 -37
  197. package/packages/pi-coding-agent/src/core/agent-session-model-switch.test.ts +89 -17
  198. package/packages/pi-coding-agent/src/core/agent-session-tool-refresh.test.ts +112 -43
  199. package/packages/pi-coding-agent/src/core/extensions/loader.ts +58 -0
  200. package/packages/pi-coding-agent/src/core/lsp/lsp-integration.test.ts +35 -4
  201. package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +20 -0
  202. package/packages/pi-coding-agent/src/core/resource-loader-cache-reset.test.ts +93 -28
  203. package/packages/pi-coding-agent/src/core/retry-handler.test.ts +5 -1
  204. package/packages/pi-coding-agent/src/core/retry-handler.ts +2 -8
  205. package/packages/pi-coding-agent/src/core/retryable-error-regex.ts +18 -0
  206. package/packages/pi-coding-agent/src/core/system-prompt.ts +35 -1
  207. package/packages/pi-coding-agent/src/index.ts +1 -0
  208. package/packages/pi-coding-agent/src/modes/interactive/components/dynamic-border.test.ts +26 -20
  209. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +146 -1
  210. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +20 -3
  211. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-state.ts +2 -0
  212. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +119 -13
  213. package/packages/pi-coding-agent/src/tests/system-prompt-skill-filter.test.ts +157 -0
  214. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  215. package/packages/pi-tui/dist/__tests__/autocomplete.test.js +18 -8
  216. package/packages/pi-tui/dist/__tests__/autocomplete.test.js.map +1 -1
  217. package/packages/pi-tui/dist/__tests__/overlay-layout.test.js +128 -17
  218. package/packages/pi-tui/dist/__tests__/overlay-layout.test.js.map +1 -1
  219. package/packages/pi-tui/dist/__tests__/stdin-buffer.test.js +36 -12
  220. package/packages/pi-tui/dist/__tests__/stdin-buffer.test.js.map +1 -1
  221. package/packages/pi-tui/dist/__tests__/tui.test.js +18 -30
  222. package/packages/pi-tui/dist/__tests__/tui.test.js.map +1 -1
  223. package/packages/pi-tui/dist/components/__tests__/input.test.js +10 -3
  224. package/packages/pi-tui/dist/components/__tests__/input.test.js.map +1 -1
  225. package/packages/pi-tui/dist/components/__tests__/loader.test.js +53 -9
  226. package/packages/pi-tui/dist/components/__tests__/loader.test.js.map +1 -1
  227. package/packages/pi-tui/dist/components/__tests__/markdown-maxlines.test.js +6 -2
  228. package/packages/pi-tui/dist/components/__tests__/markdown-maxlines.test.js.map +1 -1
  229. package/packages/pi-tui/dist/components/editor.d.ts +14 -0
  230. package/packages/pi-tui/dist/components/editor.d.ts.map +1 -1
  231. package/packages/pi-tui/dist/components/editor.js +19 -0
  232. package/packages/pi-tui/dist/components/editor.js.map +1 -1
  233. package/packages/pi-tui/dist/components/image.test.js +6 -5
  234. package/packages/pi-tui/dist/components/image.test.js.map +1 -1
  235. package/packages/pi-tui/dist/editor-component.d.ts +2 -0
  236. package/packages/pi-tui/dist/editor-component.d.ts.map +1 -1
  237. package/packages/pi-tui/dist/editor-component.js.map +1 -1
  238. package/packages/pi-tui/src/__tests__/autocomplete.test.ts +24 -8
  239. package/packages/pi-tui/src/__tests__/overlay-layout.test.ts +140 -17
  240. package/packages/pi-tui/src/__tests__/stdin-buffer.test.ts +41 -12
  241. package/packages/pi-tui/src/__tests__/tui.test.ts +18 -37
  242. package/packages/pi-tui/src/components/__tests__/input.test.ts +19 -3
  243. package/packages/pi-tui/src/components/__tests__/loader.test.ts +112 -35
  244. package/packages/pi-tui/src/components/__tests__/markdown-maxlines.test.ts +9 -2
  245. package/packages/pi-tui/src/components/editor.ts +22 -0
  246. package/packages/pi-tui/src/components/image.test.ts +10 -5
  247. package/packages/pi-tui/src/editor-component.ts +3 -0
  248. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  249. package/packages/rpc-client/dist/rpc-client.test.js +101 -51
  250. package/packages/rpc-client/dist/rpc-client.test.js.map +1 -1
  251. package/packages/rpc-client/src/rpc-client.test.ts +109 -52
  252. package/packages/rpc-client/tsconfig.tsbuildinfo +1 -1
  253. package/scripts/install.js +15 -1
  254. package/src/resources/extensions/browser-tools/capture.ts +12 -0
  255. package/src/resources/extensions/browser-tools/tests/browser-tools-integration.test.mjs +8 -59
  256. package/src/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +36 -24
  257. package/src/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +69 -71
  258. package/src/resources/extensions/browser-tools/tools/forms.ts +5 -1
  259. package/src/resources/extensions/browser-tools/tools/intent.ts +5 -1
  260. package/src/resources/extensions/claude-code-cli/readiness.ts +5 -1
  261. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +518 -19
  262. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +919 -75
  263. package/src/resources/extensions/github-sync/tests/cli.test.ts +76 -7
  264. package/src/resources/extensions/github-sync/tests/templates.test.ts +33 -1
  265. package/src/resources/extensions/gsd/auto/loop.ts +47 -0
  266. package/src/resources/extensions/gsd/auto/phases.ts +16 -20
  267. package/src/resources/extensions/gsd/auto/session.ts +0 -2
  268. package/src/resources/extensions/gsd/auto-dispatch.ts +113 -24
  269. package/src/resources/extensions/gsd/auto-model-selection.ts +131 -4
  270. package/src/resources/extensions/gsd/auto-post-unit.ts +82 -73
  271. package/src/resources/extensions/gsd/auto-prompts.ts +330 -90
  272. package/src/resources/extensions/gsd/auto-recovery.ts +225 -24
  273. package/src/resources/extensions/gsd/auto-start.ts +54 -6
  274. package/src/resources/extensions/gsd/auto-tool-tracking.ts +51 -7
  275. package/src/resources/extensions/gsd/auto-worktree.ts +130 -26
  276. package/src/resources/extensions/gsd/auto.ts +43 -22
  277. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +9 -1
  278. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +221 -0
  279. package/src/resources/extensions/gsd/bootstrap/provider-error-resume.ts +3 -7
  280. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +7 -3
  281. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +158 -9
  282. package/src/resources/extensions/gsd/component-loader.ts +598 -0
  283. package/src/resources/extensions/gsd/component-types.ts +362 -0
  284. package/src/resources/extensions/gsd/detection.ts +58 -1
  285. package/src/resources/extensions/gsd/docs/preferences-reference.md +1 -1
  286. package/src/resources/extensions/gsd/gate-registry.ts +2 -2
  287. package/src/resources/extensions/gsd/git-constants.ts +30 -1
  288. package/src/resources/extensions/gsd/git-self-heal.ts +31 -0
  289. package/src/resources/extensions/gsd/git-service.ts +133 -2
  290. package/src/resources/extensions/gsd/gsd-db.ts +6 -3
  291. package/src/resources/extensions/gsd/guided-flow.ts +20 -5
  292. package/src/resources/extensions/gsd/memory-extractor.ts +11 -3
  293. package/src/resources/extensions/gsd/milestone-scope-classifier.ts +366 -0
  294. package/src/resources/extensions/gsd/model-cost-table.ts +3 -0
  295. package/src/resources/extensions/gsd/model-router.ts +6 -0
  296. package/src/resources/extensions/gsd/native-git-bridge.ts +34 -4
  297. package/src/resources/extensions/gsd/prompts/complete-milestone.md +6 -2
  298. package/src/resources/extensions/gsd/prompts/plan-slice.md +15 -2
  299. package/src/resources/extensions/gsd/safety/git-checkpoint.ts +15 -0
  300. package/src/resources/extensions/gsd/service-tier.ts +5 -2
  301. package/src/resources/extensions/gsd/session-lock.ts +20 -10
  302. package/src/resources/extensions/gsd/skill-manifest.ts +175 -0
  303. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +309 -8
  304. package/src/resources/extensions/gsd/state.ts +49 -44
  305. package/src/resources/extensions/gsd/sync-lock.ts +97 -39
  306. package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +270 -0
  307. package/src/resources/extensions/gsd/tests/auto-deterministic-error-classification-4973.test.ts +341 -0
  308. package/src/resources/extensions/gsd/tests/auto-discuss-milestone-deadlock-4973.test.ts +264 -0
  309. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +94 -289
  310. package/src/resources/extensions/gsd/tests/auto-model-selection-tool-poisoning.test.ts +742 -0
  311. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +78 -0
  312. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +61 -0
  313. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +93 -0
  314. package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +8 -197
  315. package/src/resources/extensions/gsd/tests/auto-start-needs-discussion.test.ts +15 -58
  316. package/src/resources/extensions/gsd/tests/cache-staleness-regression.test.ts +17 -21
  317. package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +263 -0
  318. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +25 -0
  319. package/src/resources/extensions/gsd/tests/complete-slice-composer.test.ts +192 -0
  320. package/src/resources/extensions/gsd/tests/complete-task.test.ts +16 -8
  321. package/src/resources/extensions/gsd/tests/component-loader.test.ts +589 -0
  322. package/src/resources/extensions/gsd/tests/component-types.test.ts +127 -0
  323. package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +50 -1
  324. package/src/resources/extensions/gsd/tests/derive-state-crossval.test.ts +3 -3
  325. package/src/resources/extensions/gsd/tests/derive-state-db-disk-reconcile.test.ts +40 -0
  326. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +91 -3
  327. package/src/resources/extensions/gsd/tests/derive-state.test.ts +4 -3
  328. package/src/resources/extensions/gsd/tests/dispatcher-stuck-planning.test.ts +3 -2
  329. package/src/resources/extensions/gsd/tests/extension-bootstrap-isolation.test.ts +139 -129
  330. package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +9 -105
  331. package/src/resources/extensions/gsd/tests/gate-state-canonicalization.test.ts +102 -0
  332. package/src/resources/extensions/gsd/tests/gate-storage.test.ts +1 -1
  333. package/src/resources/extensions/gsd/tests/hook-key-parsing.test.ts +4 -55
  334. package/src/resources/extensions/gsd/tests/integration/all-milestones-complete-merge.test.ts +7 -57
  335. package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +20 -0
  336. package/src/resources/extensions/gsd/tests/integration/doctor-proactive.test.ts +18 -2
  337. package/src/resources/extensions/gsd/tests/integration/queue-completed-milestone-perf.test.ts +10 -4
  338. package/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts +144 -7
  339. package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +4 -0
  340. package/src/resources/extensions/gsd/tests/integration/state-machine-runtime-failures.test.ts +2 -16
  341. package/src/resources/extensions/gsd/tests/interrupted-session-ui.test.ts +6 -9
  342. package/src/resources/extensions/gsd/tests/mcp-client-security.test.ts +8 -37
  343. package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +5 -15
  344. package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +227 -62
  345. package/src/resources/extensions/gsd/tests/milestone-scope-classifier.test.ts +187 -0
  346. package/src/resources/extensions/gsd/tests/model-cost-table.test.ts +9 -1
  347. package/src/resources/extensions/gsd/tests/model-router.test.ts +1 -1
  348. package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +6 -49
  349. package/src/resources/extensions/gsd/tests/notification-widget.test.ts +6 -3
  350. package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +273 -133
  351. package/src/resources/extensions/gsd/tests/pipeline-variant-dispatch.test.ts +301 -0
  352. package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +32 -1
  353. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +23 -24
  354. package/src/resources/extensions/gsd/tests/queue-auto-guard.test.ts +32 -0
  355. package/src/resources/extensions/gsd/tests/ready-phrase-no-files-4573.test.ts +75 -2
  356. package/src/resources/extensions/gsd/tests/reassess-default-optin.test.ts +132 -0
  357. package/src/resources/extensions/gsd/tests/recovery-attempts-reset.test.ts +8 -40
  358. package/src/resources/extensions/gsd/tests/regex-hardening.test.ts +136 -256
  359. package/src/resources/extensions/gsd/tests/research-milestone-composer.test.ts +114 -0
  360. package/src/resources/extensions/gsd/tests/run-uat-composer.test.ts +148 -0
  361. package/src/resources/extensions/gsd/tests/service-tier.test.ts +4 -0
  362. package/src/resources/extensions/gsd/tests/session-lock-regression.test.ts +29 -0
  363. package/src/resources/extensions/gsd/tests/silent-catch-diagnostics.test.ts +55 -95
  364. package/src/resources/extensions/gsd/tests/single-writer-v3-tool-surface.test.ts +158 -0
  365. package/src/resources/extensions/gsd/tests/skill-activation.test.ts +120 -1
  366. package/src/resources/extensions/gsd/tests/skill-manifest.test.ts +112 -0
  367. package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +164 -1
  368. package/src/resources/extensions/gsd/tests/state-machine-full-walkthrough.test.ts +5 -5
  369. package/src/resources/extensions/gsd/tests/structured-data-formatter.test.ts +11 -92
  370. package/src/resources/extensions/gsd/tests/survivor-branch-complete.test.ts +102 -101
  371. package/src/resources/extensions/gsd/tests/sync-lock.test.ts +31 -0
  372. package/src/resources/extensions/gsd/tests/test-helpers.test.ts +12 -61
  373. package/src/resources/extensions/gsd/tests/test-helpers.ts +21 -8
  374. package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +61 -1
  375. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +8 -1
  376. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +355 -0
  377. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +258 -0
  378. package/src/resources/extensions/gsd/tests/uok-gate-runner.test.ts +75 -0
  379. package/src/resources/extensions/gsd/tests/uok-gitops-wiring.test.ts +49 -26
  380. package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +1 -0
  381. package/src/resources/extensions/gsd/tests/verify-artifact-tightened.test.ts +144 -81
  382. package/src/resources/extensions/gsd/tests/visualizer-critical-path.test.ts +20 -54
  383. package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +342 -277
  384. package/src/resources/extensions/gsd/tests/worker-model-override.test.ts +37 -29
  385. package/src/resources/extensions/gsd/tests/worktree-db.test.ts +226 -266
  386. package/src/resources/extensions/gsd/tests/worktree-health-monorepo.test.ts +103 -67
  387. package/src/resources/extensions/gsd/tests/worktree-nested-git-safety.test.ts +92 -90
  388. package/src/resources/extensions/gsd/tests/worktree-submodule-safety.test.ts +238 -59
  389. package/src/resources/extensions/gsd/tests/worktree-sync-overwrite-loop.test.ts +113 -161
  390. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +262 -0
  391. package/src/resources/extensions/gsd/tests/write-gate-predicates.test.ts +186 -0
  392. package/src/resources/extensions/gsd/tests/write-gate.test.ts +7 -5
  393. package/src/resources/extensions/gsd/tests/zombie-gsd-state.test.ts +80 -96
  394. package/src/resources/extensions/gsd/types.ts +3 -3
  395. package/src/resources/extensions/gsd/unit-context-composer.ts +218 -0
  396. package/src/resources/extensions/gsd/unit-context-manifest.ts +574 -0
  397. package/src/resources/extensions/gsd/uok/gate-runner.ts +65 -5
  398. package/src/resources/extensions/gsd/workflow-mcp.ts +6 -0
  399. package/src/resources/extensions/gsd/worktree-manager.ts +55 -7
  400. package/src/resources/extensions/mcp-client/index.ts +3 -1
  401. package/src/resources/extensions/mcp-client/tests/server-name-spaces.test.ts +70 -36
  402. package/src/resources/extensions/ollama/index.ts +5 -1
  403. package/src/resources/extensions/ollama/ollama-auth-mode.test.ts +123 -15
  404. package/src/resources/extensions/ollama/ollama-status-indicator.test.ts +206 -19
  405. package/src/resources/extensions/remote-questions/manager.ts +36 -4
  406. package/src/resources/extensions/remote-questions/tests/command-polling.test.ts +200 -190
  407. package/src/resources/extensions/shared/tests/interview-preview.test.ts +11 -3
  408. package/src/resources/extensions/voice/tests/linux-ready.test.ts +129 -113
  409. package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.d.ts +0 -2
  410. package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.d.ts.map +0 -1
  411. package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.js +0 -289
  412. package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.js.map +0 -1
  413. package/packages/pi-ai/src/utils/oauth/oauth-providers.test.ts +0 -363
  414. package/src/resources/extensions/gsd/tests/auto-start-model-capture.test.ts +0 -144
  415. package/src/resources/extensions/gsd/tests/complete-milestone-false-merge.test.ts +0 -157
  416. package/src/resources/extensions/gsd/tests/dashboard-model-label-ordering.test.ts +0 -107
  417. package/src/resources/extensions/gsd/tests/find-missing-summaries-closed.test.ts +0 -48
  418. package/src/resources/extensions/gsd/tests/forensics-context-persist.test.ts +0 -159
  419. package/src/resources/extensions/gsd/tests/forensics-db-completion.test.ts +0 -96
  420. package/src/resources/extensions/gsd/tests/forensics-dedup.test.ts +0 -79
  421. package/src/resources/extensions/gsd/tests/forensics-hook-key-parse.test.ts +0 -75
  422. package/src/resources/extensions/gsd/tests/forensics-journal.test.ts +0 -162
  423. package/src/resources/extensions/gsd/tests/forensics-worktree-telemetry.test.ts +0 -145
  424. package/src/resources/extensions/gsd/tests/gitignore-bg-shell.test.ts +0 -38
  425. package/src/resources/extensions/gsd/tests/gsd-no-project-error.test.ts +0 -73
  426. package/src/resources/extensions/gsd/tests/idle-watchdog-stall-override.test.ts +0 -130
  427. package/src/resources/extensions/gsd/tests/import-done-milestones.test.ts +0 -43
  428. /package/dist/web/standalone/.next/static/{Cev5xrAYA3ZGTRLyjR2fX → SvCJDZPQW104bR1KnBQg1}/_buildManifest.js +0 -0
  429. /package/dist/web/standalone/.next/static/{Cev5xrAYA3ZGTRLyjR2fX → SvCJDZPQW104bR1KnBQg1}/_ssgManifest.js +0 -0
@@ -1,35 +1,58 @@
1
+ /**
2
+ * UOK gitops wiring — post-unit pre-verification policy.
3
+ *
4
+ * Tests the pure policy bit that selects the turn-level git action from
5
+ * resolved UOK flags. The integration wiring (postUnitPreVerification
6
+ * calling runTurnGitAction, writeTurnGitTransaction, the UokGateRunner
7
+ * closeout pathway, and buildSnapshotOpts' trace/turn ID plumbing) is
8
+ * exercised end-to-end by the auto-loop and UOK kernel integration tests;
9
+ * the earlier source-grep assertions duplicated that coverage without
10
+ * actually exercising the code, and have been removed.
11
+ */
12
+
1
13
  import test from "node:test";
2
14
  import assert from "node:assert/strict";
3
- import { readFileSync } from "node:fs";
4
- import { join, dirname } from "node:path";
5
- import { fileURLToPath } from "node:url";
6
15
 
7
- const __dirname = dirname(fileURLToPath(import.meta.url));
8
- const gsdDir = join(__dirname, "..");
16
+ import { resolveUokFlags } from "../uok/flags.ts";
17
+
18
+ test("turn action defaults to commit when uok.gitops is enabled with no override", () => {
19
+ const flags = resolveUokFlags({ uok: { gitops: { enabled: true } } } as any);
20
+ assert.equal(flags.gitops, true);
21
+ assert.equal(flags.gitopsTurnAction, "commit");
22
+ });
23
+
24
+ test("turn action reflects uok.gitops.turn_action when set to snapshot", () => {
25
+ const flags = resolveUokFlags({
26
+ uok: { gitops: { enabled: true, turn_action: "snapshot" } },
27
+ } as any);
28
+ assert.equal(flags.gitops, true);
29
+ assert.equal(flags.gitopsTurnAction, "snapshot");
30
+ });
9
31
 
10
- test("post-unit pre-verification selects turn git action from UOK gitops flags", () => {
11
- const source = readFileSync(join(gsdDir, "auto-post-unit.ts"), "utf-8");
12
- assert.ok(
13
- source.includes("const turnAction: TurnGitActionMode = uokFlags.gitops ? uokFlags.gitopsTurnAction : \"commit\""),
14
- "postUnitPreVerification should derive turn action from uok.gitops.turn_action when enabled",
15
- );
32
+ test("turn action reflects uok.gitops.turn_action when set to status-only", () => {
33
+ const flags = resolveUokFlags({
34
+ uok: { gitops: { enabled: true, turn_action: "status-only" } },
35
+ } as any);
36
+ assert.equal(flags.gitops, true);
37
+ assert.equal(flags.gitopsTurnAction, "status-only");
16
38
  });
17
39
 
18
- test("post-unit pre-verification routes git failures through closeout gate", () => {
19
- const source = readFileSync(join(gsdDir, "auto-post-unit.ts"), "utf-8");
20
- assert.ok(
21
- source.includes('id: "closeout-git-action"') &&
22
- source.includes('type: "closeout"') &&
23
- source.includes('failureClass: "git"'),
24
- "git failures should be persisted via a closeout gate with failureClass=git",
25
- );
40
+ test("turn_push flag round-trips through resolveUokFlags", () => {
41
+ const on = resolveUokFlags({
42
+ uok: { gitops: { enabled: true, turn_push: true } },
43
+ } as any);
44
+ const off = resolveUokFlags({
45
+ uok: { gitops: { enabled: true, turn_push: false } },
46
+ } as any);
47
+ assert.equal(on.gitopsTurnPush, true);
48
+ assert.equal(off.gitopsTurnPush, false);
26
49
  });
27
50
 
28
- test("auto snapshot opts carry trace/turn IDs for turn closeout records", () => {
29
- const source = readFileSync(join(gsdDir, "auto.ts"), "utf-8");
30
- assert.ok(
31
- source.includes("traceId: s.currentTraceId ?? undefined") &&
32
- source.includes("turnId: s.currentTurnId ?? undefined"),
33
- "buildSnapshotOpts should pass trace/turn IDs into closeout options",
34
- );
51
+ test("gitops disabled when uok.gitops.enabled is explicitly false", () => {
52
+ const flags = resolveUokFlags({
53
+ uok: { gitops: { enabled: false, turn_action: "snapshot" } },
54
+ } as any);
55
+ assert.equal(flags.gitops, false);
56
+ // Turn_action is still surfaced so callers can read their policy cleanly.
57
+ assert.equal(flags.gitopsTurnAction, "snapshot");
35
58
  });
@@ -271,6 +271,7 @@ Test
271
271
  assert.match(prompt, /S01 Summary/i, "prompt should inline non-skipped slice summaries");
272
272
  assert.doesNotMatch(prompt, /### S02 Summary/i, "prompt should not inline skipped slice summaries");
273
273
  assert.doesNotMatch(prompt, /not found — file does not exist yet/i, "prompt should not emit skipped-slice missing-file placeholders");
274
+ assert.doesNotMatch(prompt, /S02-SUMMARY\.md/, "skipped slice must not appear in on-demand path list (#4780)");
274
275
  } finally {
275
276
  cleanup(base);
276
277
  }
@@ -1,90 +1,153 @@
1
1
  /**
2
- * Regression test for #3607 — tighten verifyExpectedArtifact legacy branch
2
+ * Regression test for #3607 — tighten verifyExpectedArtifact legacy branch.
3
3
  *
4
4
  * The legacy (pre-migration) fallback in verifyExpectedArtifact previously
5
5
  * accepted either a heading match (### T01 --) or a checked checkbox as proof
6
6
  * that gsd_complete_task ran. A heading alone does not prove completion —
7
7
  * it could result from a rogue write.
8
8
  *
9
- * The fix removes the hdRe heading regex and requires only a checked checkbox
10
- * (cbRe) in the legacy branch, ensuring that only actual tool-completed tasks
11
- * are treated as verified.
9
+ * These tests exercise verifyExpectedArtifact directly for execute-task units
10
+ * when the DB is unavailable (legacy branch). Only a checked checkbox in the
11
+ * slice plan counts as evidence of completion; a bare heading or an unchecked
12
+ * checkbox must not pass.
12
13
  */
13
14
 
14
- import { describe, it } from 'node:test'
15
- import assert from 'node:assert/strict'
16
- import { readFileSync } from 'node:fs'
17
- import { resolve } from 'node:path'
18
- import { extractSourceRegion } from "./test-helpers.ts";
19
-
20
- const src = readFileSync(
21
- resolve(process.cwd(), 'src', 'resources', 'extensions', 'gsd', 'auto-recovery.ts'),
22
- 'utf-8',
23
- )
24
-
25
- describe('verifyExpectedArtifact legacy branch tightened (#3607)', () => {
26
- it('legacy branch does NOT define hdRe heading regex', () => {
27
- // Find the legacy fallback section
28
- const legacyIdx = src.indexOf('LEGACY: Pre-migration fallback')
29
- assert.ok(legacyIdx !== -1, 'LEGACY comment must exist')
30
-
31
- // Check the code within a reasonable window after the LEGACY comment
32
- const legacyBlock = extractSourceRegion(src, 'LEGACY: Pre-migration fallback')
33
-
34
- assert.ok(
35
- !legacyBlock.includes('hdRe'),
36
- 'hdRe heading regex must NOT exist in legacy branch heading alone is not proof of completion',
37
- )
38
- })
39
-
40
- it('legacy branch requires checked checkbox via cbRe', () => {
41
- const legacyIdx = src.indexOf('LEGACY: Pre-migration fallback')
42
- assert.ok(legacyIdx !== -1)
43
-
44
- const legacyBlock = extractSourceRegion(src, 'LEGACY: Pre-migration fallback')
45
-
46
- assert.ok(
47
- legacyBlock.includes('cbRe'),
48
- 'cbRe checked-checkbox regex must exist in legacy branch',
49
- )
50
-
51
- // cbRe must match checked checkboxes [x] or [X]
52
- assert.ok(
53
- legacyBlock.includes('[xX]'),
54
- 'cbRe must match both [x] and [X] checkbox variants',
55
- )
56
- })
57
-
58
- it('legacy branch returns false when no plan file exists', () => {
59
- const legacyIdx = src.indexOf('LEGACY: Pre-migration fallback')
60
- assert.ok(legacyIdx !== -1)
61
-
62
- const legacyBlock = extractSourceRegion(src, 'LEGACY: Pre-migration fallback')
63
-
64
- // The else branch: no plan file means cannot verify
65
- assert.ok(
66
- legacyBlock.includes('no plan file'),
67
- 'missing plan file must be handled with return false',
68
- )
69
- })
70
-
71
- it('DB available but task not found returns false', () => {
72
- const legacyIdx = src.indexOf('LEGACY: Pre-migration fallback')
73
- assert.ok(legacyIdx !== -1)
74
-
75
- const legacyBlock = extractSourceRegion(src, 'LEGACY: Pre-migration fallback')
76
-
77
- assert.ok(
78
- legacyBlock.includes('DB available but task row not found'),
79
- 'must handle case where DB is available but task row is missing',
80
- )
81
-
82
- // The comment should be followed by a return false
83
- const commentIdx = legacyBlock.indexOf('DB available but task row not found')
84
- const afterComment = extractSourceRegion(legacyBlock, 'DB available but task row not found')
85
- assert.ok(
86
- afterComment.includes('return false'),
87
- 'missing task row when DB available must return false',
88
- )
89
- })
90
- })
15
+ import { test } from "node:test";
16
+ import assert from "node:assert/strict";
17
+ import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from "node:fs";
18
+ import { join } from "node:path";
19
+ import { tmpdir } from "node:os";
20
+
21
+ import { verifyExpectedArtifact } from "../auto-recovery.ts";
22
+ import { closeDatabase, isDbAvailable } from "../gsd-db.ts";
23
+
24
+ /** Scaffold .gsd/milestones/M001/slices/S01/ with tasks/ and a T01-SUMMARY.md. */
25
+ function scaffoldProject(t: { after: (fn: () => void) => void }): {
26
+ base: string;
27
+ planPath: string;
28
+ } {
29
+ const base = mkdtempSync(join(tmpdir(), "gsd-verify-artifact-"));
30
+ t.after(() => {
31
+ closeDatabase();
32
+ rmSync(base, { recursive: true, force: true });
33
+ });
34
+
35
+ const sliceDir = join(base, ".gsd", "milestones", "M001", "slices", "S01");
36
+ mkdirSync(join(sliceDir, "tasks"), { recursive: true });
37
+ // Summary file must exist so verifyExpectedArtifact reaches the legacy branch
38
+ writeFileSync(join(sliceDir, "tasks", "T01-SUMMARY.md"), "# T01 summary\n");
39
+ return { base, planPath: join(sliceDir, "S01-PLAN.md") };
40
+ }
41
+
42
+ test("#3607: execute-task legacy branch — checked checkbox [x] passes verification", (t) => {
43
+ closeDatabase();
44
+ assert.equal(isDbAvailable(), false, "DB must be closed to hit legacy branch");
45
+
46
+ const { base, planPath } = scaffoldProject(t);
47
+ writeFileSync(
48
+ planPath,
49
+ [
50
+ "# S01 plan",
51
+ "",
52
+ "- [x] **T01: Implement feature**",
53
+ "",
54
+ ].join("\n"),
55
+ );
56
+
57
+ assert.equal(
58
+ verifyExpectedArtifact("execute-task", "M001/S01/T01", base),
59
+ true,
60
+ "checked checkbox [x] is accepted as completion evidence",
61
+ );
62
+ });
63
+
64
+ test("#3607: execute-task legacy branch — checked checkbox [X] (uppercase) also passes", (t) => {
65
+ closeDatabase();
66
+ const { base, planPath } = scaffoldProject(t);
67
+ writeFileSync(
68
+ planPath,
69
+ [
70
+ "# S01 plan",
71
+ "",
72
+ "- [X] **T01: Implement feature**",
73
+ ].join("\n"),
74
+ );
75
+
76
+ assert.equal(
77
+ verifyExpectedArtifact("execute-task", "M001/S01/T01", base),
78
+ true,
79
+ "uppercase [X] checkbox is accepted",
80
+ );
81
+ });
82
+
83
+ test("#3607: execute-task legacy branch unchecked checkbox [ ] is rejected", (t) => {
84
+ closeDatabase();
85
+ const { base, planPath } = scaffoldProject(t);
86
+ writeFileSync(
87
+ planPath,
88
+ [
89
+ "# S01 plan",
90
+ "",
91
+ "- [ ] **T01: Implement feature**",
92
+ ].join("\n"),
93
+ );
94
+
95
+ assert.equal(
96
+ verifyExpectedArtifact("execute-task", "M001/S01/T01", base),
97
+ false,
98
+ "unchecked checkbox [ ] must not pass verification (#3607)",
99
+ );
100
+ });
101
+
102
+ test("#3607: execute-task legacy branch — bare heading ### T01 is no longer sufficient", (t) => {
103
+ closeDatabase();
104
+ const { base, planPath } = scaffoldProject(t);
105
+ // Old buggy behaviour would pass on a heading alone. This must now fail.
106
+ writeFileSync(
107
+ planPath,
108
+ [
109
+ "# S01 plan",
110
+ "",
111
+ "### T01 -- Implement feature",
112
+ "",
113
+ "Some description here, but no checkbox.",
114
+ ].join("\n"),
115
+ );
116
+
117
+ assert.equal(
118
+ verifyExpectedArtifact("execute-task", "M001/S01/T01", base),
119
+ false,
120
+ "heading alone must not pass verification after #3607 fix",
121
+ );
122
+ });
123
+
124
+ test("#3607: execute-task legacy branch — missing plan file returns false", (t) => {
125
+ closeDatabase();
126
+ const { base } = scaffoldProject(t);
127
+ // Do not create S01-PLAN.md at all.
128
+
129
+ assert.equal(
130
+ verifyExpectedArtifact("execute-task", "M001/S01/T01", base),
131
+ false,
132
+ "missing plan file must cause verification to return false",
133
+ );
134
+ });
135
+
136
+ test("#3607: execute-task legacy branch — wrong task id in checkbox does not match", (t) => {
137
+ closeDatabase();
138
+ const { base, planPath } = scaffoldProject(t);
139
+ writeFileSync(
140
+ planPath,
141
+ [
142
+ "# S01 plan",
143
+ "",
144
+ "- [x] **T02: Some other task**",
145
+ ].join("\n"),
146
+ );
147
+
148
+ assert.equal(
149
+ verifyExpectedArtifact("execute-task", "M001/S01/T01", base),
150
+ false,
151
+ "checkbox for a different task id must not count as T01 completion",
152
+ );
153
+ });
@@ -3,9 +3,8 @@
3
3
 
4
4
  import { computeCriticalPath } from "../visualizer-data.js";
5
5
  import type { VisualizerMilestone } from "../visualizer-data.js";
6
- import { test } from 'node:test';
7
- import assert from 'node:assert/strict';
8
-
6
+ import { test } from "node:test";
7
+ import assert from "node:assert/strict";
9
8
 
10
9
  function makeMs(id: string, status: "complete" | "active" | "pending", dependsOn: string[], slices: any[] = []): VisualizerMilestone {
11
10
  return { id, title: id, status, dependsOn, slices };
@@ -15,12 +14,7 @@ function makeSlice(id: string, done: boolean, depends: string[] = []) {
15
14
  return { id, title: id, done, active: false, risk: "low", depends, tasks: [] };
16
15
  }
17
16
 
18
- // ─── Linear chain ───────────────────────────────────────────────────────────
19
-
20
- console.log("\n=== Critical Path: Linear Chain ===");
21
-
22
- {
23
- // M001 -> M002 -> M003
17
+ test("critical path: linear chain M001 → M002 → M003", () => {
24
18
  const milestones = [
25
19
  makeMs("M001", "complete", []),
26
20
  makeMs("M002", "active", ["M001"], [
@@ -34,15 +28,11 @@ console.log("\n=== Critical Path: Linear Chain ===");
34
28
  assert.ok(cp.milestonePath.length > 0, "linear chain has critical path");
35
29
  assert.ok(cp.milestonePath.includes("M002"), "M002 is on critical path");
36
30
  assert.ok(cp.milestonePath.includes("M003"), "M003 is on critical path");
37
- assert.deepStrictEqual(cp.milestoneSlack.get("M002"), 0, "M002 has zero slack");
38
- assert.deepStrictEqual(cp.milestoneSlack.get("M003"), 0, "M003 has zero slack");
39
- }
40
-
41
- // ─── Diamond DAG ────────────────────────────────────────────────────────────
31
+ assert.equal(cp.milestoneSlack.get("M002"), 0, "M002 has zero slack");
32
+ assert.equal(cp.milestoneSlack.get("M003"), 0, "M003 has zero slack");
33
+ });
42
34
 
43
- console.log("\n=== Critical Path: Diamond DAG ===");
44
-
45
- {
35
+ test("critical path: diamond DAG picks heavier branch", () => {
46
36
  // M001 -> M002 -> M004
47
37
  // M001 -> M003 -> M004
48
38
  // M002 has 3 incomplete slices, M003 has 1 incomplete slice
@@ -61,21 +51,13 @@ console.log("\n=== Critical Path: Diamond DAG ===");
61
51
 
62
52
  const cp = computeCriticalPath(milestones);
63
53
  assert.ok(cp.milestonePath.length >= 2, "diamond DAG has critical path");
64
- // M002 has weight 3 (3 incomplete), M003 has weight 1
65
- // Critical path should go through M002 (longer)
66
54
  assert.ok(cp.milestonePath.includes("M002"), "M002 (heavier) is on critical path");
67
55
 
68
- // M003 should have non-zero slack since it's lighter
69
56
  const m003Slack = cp.milestoneSlack.get("M003") ?? -1;
70
57
  assert.ok(m003Slack > 0, "M003 has positive slack (lighter branch)");
71
- }
72
-
73
- // ─── Independent branches ───────────────────────────────────────────────────
58
+ });
74
59
 
75
- console.log("\n=== Critical Path: Independent Branches ===");
76
-
77
- {
78
- // M001 (no deps), M002 (no deps), M003 (no deps)
60
+ test("critical path: independent branches selects longest", () => {
79
61
  const milestones = [
80
62
  makeMs("M001", "active", [], [makeSlice("S01", false)]),
81
63
  makeMs("M002", "pending", [], [makeSlice("S01", false), makeSlice("S02", false)]),
@@ -84,15 +66,10 @@ console.log("\n=== Critical Path: Independent Branches ===");
84
66
 
85
67
  const cp = computeCriticalPath(milestones);
86
68
  assert.ok(cp.milestonePath.length >= 1, "independent branches have at least one critical node");
87
- // M002 has the most incomplete slices, should be critical
88
69
  assert.ok(cp.milestonePath.includes("M002"), "M002 (longest) is on critical path");
89
- }
70
+ });
90
71
 
91
- // ─── Slice-level critical path ──────────────────────────────────────────────
92
-
93
- console.log("\n=== Critical Path: Slice-level ===");
94
-
95
- {
72
+ test("critical path: slice-level path within an active milestone", () => {
96
73
  // Active milestone with slice dependencies: S01 -> S02 -> S04, S01 -> S03
97
74
  const milestones = [
98
75
  makeMs("M001", "active", [], [
@@ -108,26 +85,17 @@ console.log("\n=== Critical Path: Slice-level ===");
108
85
  assert.ok(cp.slicePath.includes("S02"), "S02 is on slice critical path");
109
86
  assert.ok(cp.slicePath.includes("S04"), "S04 is on slice critical path");
110
87
 
111
- // S03 should have non-zero slack (it's a shorter branch)
112
88
  const s03Slack = cp.sliceSlack.get("S03") ?? -1;
113
89
  assert.ok(s03Slack > 0, "S03 has positive slack (shorter branch)");
114
- }
115
-
116
- // ─── Empty milestones ───────────────────────────────────────────────────────
117
-
118
- console.log("\n=== Critical Path: Empty ===");
90
+ });
119
91
 
120
- {
92
+ test("critical path: empty milestones produce empty paths", () => {
121
93
  const cp = computeCriticalPath([]);
122
- assert.deepStrictEqual(cp.milestonePath.length, 0, "empty milestones produce empty path");
123
- assert.deepStrictEqual(cp.slicePath.length, 0, "empty milestones produce empty slice path");
124
- }
125
-
126
- // ─── Single milestone ───────────────────────────────────────────────────────
127
-
128
- console.log("\n=== Critical Path: Single Milestone ===");
94
+ assert.equal(cp.milestonePath.length, 0, "empty milestones produce empty path");
95
+ assert.equal(cp.slicePath.length, 0, "empty milestones produce empty slice path");
96
+ });
129
97
 
130
- {
98
+ test("critical path: single milestone is its own critical path", () => {
131
99
  const milestones = [
132
100
  makeMs("M001", "active", [], [
133
101
  makeSlice("S01", false),
@@ -136,8 +104,6 @@ console.log("\n=== Critical Path: Single Milestone ===");
136
104
  ];
137
105
 
138
106
  const cp = computeCriticalPath(milestones);
139
- assert.ok(cp.milestonePath.length === 1, "single milestone is its own critical path");
140
- assert.deepStrictEqual(cp.milestonePath[0], "M001", "M001 is the critical node");
141
- }
142
-
143
- // ─── Report ─────────────────────────────────────────────────────────────────
107
+ assert.equal(cp.milestonePath.length, 1, "single milestone is its own critical path");
108
+ assert.equal(cp.milestonePath[0], "M001", "M001 is the critical node");
109
+ });