gsd-pi 2.77.0-dev.1d17f366c → 2.77.0-dev.2daa994b6

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 (368) hide show
  1. package/dist/headless.js +25 -4
  2. package/dist/resource-loader.d.ts +40 -0
  3. package/dist/resource-loader.js +32 -13
  4. package/dist/resources/extensions/browser-tools/capture.js +9 -0
  5. package/dist/resources/extensions/browser-tools/tests/browser-tools-integration.test.mjs +8 -59
  6. package/dist/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +36 -24
  7. package/dist/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +69 -71
  8. package/dist/resources/extensions/browser-tools/tools/forms.js +5 -1
  9. package/dist/resources/extensions/browser-tools/tools/intent.js +5 -1
  10. package/dist/resources/extensions/gsd/auto/phases.js +5 -18
  11. package/dist/resources/extensions/gsd/auto/session.js +6 -0
  12. package/dist/resources/extensions/gsd/auto-dispatch.js +37 -8
  13. package/dist/resources/extensions/gsd/auto-post-unit.js +79 -0
  14. package/dist/resources/extensions/gsd/auto-prompts.js +372 -104
  15. package/dist/resources/extensions/gsd/auto-start.js +75 -24
  16. package/dist/resources/extensions/gsd/auto.js +34 -0
  17. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +9 -1
  18. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +7 -1
  19. package/dist/resources/extensions/gsd/component-loader.js +447 -0
  20. package/dist/resources/extensions/gsd/component-types.js +69 -0
  21. package/dist/resources/extensions/gsd/context-store.js +23 -7
  22. package/dist/resources/extensions/gsd/detection.js +49 -1
  23. package/dist/resources/extensions/gsd/docs/preferences-reference.md +1 -1
  24. package/dist/resources/extensions/gsd/forensics.js +106 -0
  25. package/dist/resources/extensions/gsd/gsd-db.js +1 -1
  26. package/dist/resources/extensions/gsd/guided-flow.js +2 -4
  27. package/dist/resources/extensions/gsd/memory-extractor.js +7 -1
  28. package/dist/resources/extensions/gsd/milestone-scope-classifier.js +299 -0
  29. package/dist/resources/extensions/gsd/model-cost-table.js +3 -0
  30. package/dist/resources/extensions/gsd/model-router.js +6 -0
  31. package/dist/resources/extensions/gsd/preferences-validation.js +23 -0
  32. package/dist/resources/extensions/gsd/prompt-cache-optimizer.js +4 -0
  33. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +5 -1
  34. package/dist/resources/extensions/gsd/prompts/plan-slice.md +15 -2
  35. package/dist/resources/extensions/gsd/service-tier.js +5 -2
  36. package/dist/resources/extensions/gsd/skill-manifest.js +168 -0
  37. package/dist/resources/extensions/gsd/slice-cadence.js +238 -0
  38. package/dist/resources/extensions/gsd/tools/validate-milestone.js +7 -2
  39. package/dist/resources/extensions/gsd/unit-context-composer.js +147 -0
  40. package/dist/resources/extensions/gsd/unit-context-manifest.js +334 -0
  41. package/dist/resources/extensions/gsd/worktree-manager.js +51 -0
  42. package/dist/resources/extensions/gsd/worktree-resolver.js +86 -7
  43. package/dist/resources/extensions/gsd/worktree-telemetry.js +198 -0
  44. package/dist/resources/extensions/mcp-client/index.js +3 -1
  45. package/dist/resources/extensions/ollama/index.js +5 -1
  46. package/dist/resources/extensions/remote-questions/manager.js +11 -5
  47. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  48. package/dist/web/standalone/.next/BUILD_ID +1 -1
  49. package/dist/web/standalone/.next/app-path-routes-manifest.json +17 -17
  50. package/dist/web/standalone/.next/build-manifest.json +2 -2
  51. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  52. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  53. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  54. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  55. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  56. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  57. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  58. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  59. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  60. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  61. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  62. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  63. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  64. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  65. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  66. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  67. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  68. package/dist/web/standalone/.next/server/app/index.html +1 -1
  69. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  70. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  71. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  72. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  73. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  74. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  75. package/dist/web/standalone/.next/server/app-paths-manifest.json +17 -17
  76. package/dist/web/standalone/.next/server/chunks/6897.js +1 -1
  77. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  78. package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
  79. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  80. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  81. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  82. package/package.json +1 -3
  83. package/packages/mcp-server/src/mcp-server.test.ts +25 -3
  84. package/packages/mcp-server/src/readers/graph.test.ts +87 -15
  85. package/packages/mcp-server/src/workflow-tools.test.ts +80 -39
  86. package/packages/native/package.json +1 -1
  87. package/packages/native/src/__tests__/_test-coverage-guard.test.mjs +98 -0
  88. package/packages/native/src/__tests__/module-compat.test.mjs +59 -27
  89. package/packages/native/src/__tests__/ps.test.mjs +14 -8
  90. package/packages/native/src/__tests__/stream-process.test.mjs +23 -2
  91. package/packages/native/src/__tests__/truncate.test.mjs +17 -2
  92. package/packages/pi-agent-core/src/agent-loop.test.ts +5 -15
  93. package/packages/pi-agent-core/src/agent.test.ts +96 -102
  94. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  95. package/packages/pi-ai/dist/models/generated/index.d.ts +34 -0
  96. package/packages/pi-ai/dist/models/generated/index.d.ts.map +1 -1
  97. package/packages/pi-ai/dist/models/generated/openai-codex.d.ts +17 -0
  98. package/packages/pi-ai/dist/models/generated/openai-codex.d.ts.map +1 -1
  99. package/packages/pi-ai/dist/models/generated/openai-codex.js +17 -0
  100. package/packages/pi-ai/dist/models/generated/openai-codex.js.map +1 -1
  101. package/packages/pi-ai/dist/models/generated/openai.d.ts +17 -0
  102. package/packages/pi-ai/dist/models/generated/openai.d.ts.map +1 -1
  103. package/packages/pi-ai/dist/models/generated/openai.js +17 -0
  104. package/packages/pi-ai/dist/models/generated/openai.js.map +1 -1
  105. package/packages/pi-ai/dist/models.generated.test.js +43 -70
  106. package/packages/pi-ai/dist/models.generated.test.js.map +1 -1
  107. package/packages/pi-ai/dist/models.test.js +29 -11
  108. package/packages/pi-ai/dist/models.test.js.map +1 -1
  109. package/packages/pi-ai/scripts/generate-models.ts +44 -0
  110. package/packages/pi-ai/src/models/generated/openai-codex.ts +17 -0
  111. package/packages/pi-ai/src/models/generated/openai.ts +17 -0
  112. package/packages/pi-ai/src/models.generated.test.ts +46 -73
  113. package/packages/pi-ai/src/models.test.ts +39 -11
  114. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  115. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +96 -32
  116. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js.map +1 -1
  117. package/packages/pi-coding-agent/dist/core/agent-session-model-switch.test.js +75 -12
  118. package/packages/pi-coding-agent/dist/core/agent-session-model-switch.test.js.map +1 -1
  119. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js +99 -31
  120. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js.map +1 -1
  121. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts +5 -0
  122. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  123. package/packages/pi-coding-agent/dist/core/extensions/loader.js +61 -0
  124. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  125. package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.js +30 -4
  126. package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.js.map +1 -1
  127. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +17 -0
  128. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -1
  129. package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.js +76 -18
  130. package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.js.map +1 -1
  131. package/packages/pi-coding-agent/dist/core/retry-handler.d.ts.map +1 -1
  132. package/packages/pi-coding-agent/dist/core/retry-handler.js +2 -6
  133. package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -1
  134. package/packages/pi-coding-agent/dist/core/retry-handler.test.js +5 -1
  135. package/packages/pi-coding-agent/dist/core/retry-handler.test.js.map +1 -1
  136. package/packages/pi-coding-agent/dist/core/retryable-error-regex.d.ts +18 -0
  137. package/packages/pi-coding-agent/dist/core/retryable-error-regex.d.ts.map +1 -0
  138. package/packages/pi-coding-agent/dist/core/retryable-error-regex.js +18 -0
  139. package/packages/pi-coding-agent/dist/core/retryable-error-regex.js.map +1 -0
  140. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts +20 -0
  141. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
  142. package/packages/pi-coding-agent/dist/core/system-prompt.js +16 -2
  143. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  144. package/packages/pi-coding-agent/dist/index.d.ts +1 -0
  145. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  146. package/packages/pi-coding-agent/dist/index.js +1 -0
  147. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  148. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +36 -5
  149. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
  150. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.js +20 -13
  151. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.js.map +1 -1
  152. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  153. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +30 -12
  154. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  155. package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.d.ts +2 -0
  156. package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.d.ts.map +1 -0
  157. package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.js +130 -0
  158. package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.js.map +1 -0
  159. package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +113 -37
  160. package/packages/pi-coding-agent/src/core/agent-session-model-switch.test.ts +89 -17
  161. package/packages/pi-coding-agent/src/core/agent-session-tool-refresh.test.ts +112 -43
  162. package/packages/pi-coding-agent/src/core/extensions/loader.ts +58 -0
  163. package/packages/pi-coding-agent/src/core/lsp/lsp-integration.test.ts +35 -4
  164. package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +20 -0
  165. package/packages/pi-coding-agent/src/core/resource-loader-cache-reset.test.ts +93 -28
  166. package/packages/pi-coding-agent/src/core/retry-handler.test.ts +5 -1
  167. package/packages/pi-coding-agent/src/core/retry-handler.ts +2 -8
  168. package/packages/pi-coding-agent/src/core/retryable-error-regex.ts +18 -0
  169. package/packages/pi-coding-agent/src/core/system-prompt.ts +35 -1
  170. package/packages/pi-coding-agent/src/index.ts +1 -0
  171. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +49 -3
  172. package/packages/pi-coding-agent/src/modes/interactive/components/dynamic-border.test.ts +26 -20
  173. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +48 -9
  174. package/packages/pi-coding-agent/src/tests/system-prompt-skill-filter.test.ts +157 -0
  175. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  176. package/packages/pi-tui/dist/__tests__/autocomplete.test.js +18 -8
  177. package/packages/pi-tui/dist/__tests__/autocomplete.test.js.map +1 -1
  178. package/packages/pi-tui/dist/__tests__/overlay-layout.test.js +128 -17
  179. package/packages/pi-tui/dist/__tests__/overlay-layout.test.js.map +1 -1
  180. package/packages/pi-tui/dist/__tests__/stdin-buffer.test.js +36 -12
  181. package/packages/pi-tui/dist/__tests__/stdin-buffer.test.js.map +1 -1
  182. package/packages/pi-tui/dist/__tests__/tui.test.js +18 -30
  183. package/packages/pi-tui/dist/__tests__/tui.test.js.map +1 -1
  184. package/packages/pi-tui/dist/components/__tests__/input.test.js +10 -3
  185. package/packages/pi-tui/dist/components/__tests__/input.test.js.map +1 -1
  186. package/packages/pi-tui/dist/components/__tests__/loader.test.js +53 -9
  187. package/packages/pi-tui/dist/components/__tests__/loader.test.js.map +1 -1
  188. package/packages/pi-tui/dist/components/__tests__/markdown-maxlines.test.js +6 -2
  189. package/packages/pi-tui/dist/components/__tests__/markdown-maxlines.test.js.map +1 -1
  190. package/packages/pi-tui/dist/components/image.test.js +6 -5
  191. package/packages/pi-tui/dist/components/image.test.js.map +1 -1
  192. package/packages/pi-tui/src/__tests__/autocomplete.test.ts +24 -8
  193. package/packages/pi-tui/src/__tests__/overlay-layout.test.ts +140 -17
  194. package/packages/pi-tui/src/__tests__/stdin-buffer.test.ts +41 -12
  195. package/packages/pi-tui/src/__tests__/tui.test.ts +18 -37
  196. package/packages/pi-tui/src/components/__tests__/input.test.ts +19 -3
  197. package/packages/pi-tui/src/components/__tests__/loader.test.ts +112 -35
  198. package/packages/pi-tui/src/components/__tests__/markdown-maxlines.test.ts +9 -2
  199. package/packages/pi-tui/src/components/image.test.ts +10 -5
  200. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  201. package/packages/rpc-client/dist/rpc-client.test.js +101 -51
  202. package/packages/rpc-client/dist/rpc-client.test.js.map +1 -1
  203. package/packages/rpc-client/src/rpc-client.test.ts +109 -52
  204. package/packages/rpc-client/tsconfig.tsbuildinfo +1 -1
  205. package/scripts/install.js +15 -1
  206. package/src/resources/extensions/browser-tools/capture.ts +12 -0
  207. package/src/resources/extensions/browser-tools/tests/browser-tools-integration.test.mjs +8 -59
  208. package/src/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +36 -24
  209. package/src/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +69 -71
  210. package/src/resources/extensions/browser-tools/tools/forms.ts +5 -1
  211. package/src/resources/extensions/browser-tools/tools/intent.ts +5 -1
  212. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +80 -72
  213. package/src/resources/extensions/github-sync/tests/cli.test.ts +76 -7
  214. package/src/resources/extensions/github-sync/tests/templates.test.ts +33 -1
  215. package/src/resources/extensions/gsd/auto/phases.ts +6 -17
  216. package/src/resources/extensions/gsd/auto/session.ts +7 -0
  217. package/src/resources/extensions/gsd/auto-dispatch.ts +40 -8
  218. package/src/resources/extensions/gsd/auto-post-unit.ts +81 -0
  219. package/src/resources/extensions/gsd/auto-prompts.ts +385 -93
  220. package/src/resources/extensions/gsd/auto-start.ts +97 -4
  221. package/src/resources/extensions/gsd/auto.ts +37 -0
  222. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +9 -1
  223. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +7 -1
  224. package/src/resources/extensions/gsd/component-loader.ts +598 -0
  225. package/src/resources/extensions/gsd/component-types.ts +362 -0
  226. package/src/resources/extensions/gsd/context-store.ts +25 -8
  227. package/src/resources/extensions/gsd/detection.ts +58 -1
  228. package/src/resources/extensions/gsd/docs/preferences-reference.md +1 -1
  229. package/src/resources/extensions/gsd/forensics.ts +118 -1
  230. package/src/resources/extensions/gsd/git-service.ts +16 -0
  231. package/src/resources/extensions/gsd/gsd-db.ts +1 -1
  232. package/src/resources/extensions/gsd/guided-flow.ts +2 -4
  233. package/src/resources/extensions/gsd/journal.ts +11 -1
  234. package/src/resources/extensions/gsd/memory-extractor.ts +11 -3
  235. package/src/resources/extensions/gsd/milestone-scope-classifier.ts +366 -0
  236. package/src/resources/extensions/gsd/model-cost-table.ts +3 -0
  237. package/src/resources/extensions/gsd/model-router.ts +6 -0
  238. package/src/resources/extensions/gsd/preferences-validation.ts +21 -0
  239. package/src/resources/extensions/gsd/prompt-cache-optimizer.ts +4 -0
  240. package/src/resources/extensions/gsd/prompts/complete-milestone.md +5 -1
  241. package/src/resources/extensions/gsd/prompts/plan-slice.md +15 -2
  242. package/src/resources/extensions/gsd/service-tier.ts +5 -2
  243. package/src/resources/extensions/gsd/skill-manifest.ts +175 -0
  244. package/src/resources/extensions/gsd/slice-cadence.ts +299 -0
  245. package/src/resources/extensions/gsd/tests/artifacts-table-preserved-on-cache-invalidate.test.ts +2 -1
  246. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +25 -292
  247. package/src/resources/extensions/gsd/tests/auto-remediate-slice-status.test.ts +4 -1
  248. package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +8 -194
  249. package/src/resources/extensions/gsd/tests/auto-start-clean-runtime-db-gated.test.ts +3 -2
  250. package/src/resources/extensions/gsd/tests/auto-start-cold-db-bootstrap.test.ts +2 -2
  251. package/src/resources/extensions/gsd/tests/auto-start-needs-discussion.test.ts +15 -58
  252. package/src/resources/extensions/gsd/tests/auto-start-worktree-db-path.test.ts +2 -2
  253. package/src/resources/extensions/gsd/tests/auto-thinking-restore.test.ts +3 -2
  254. package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +3 -2
  255. package/src/resources/extensions/gsd/tests/bootstrap-derive-state-db-open.test.ts +2 -1
  256. package/src/resources/extensions/gsd/tests/cache-staleness-regression.test.ts +17 -21
  257. package/src/resources/extensions/gsd/tests/canonical-milestone-root.test.ts +108 -0
  258. package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +263 -0
  259. package/src/resources/extensions/gsd/tests/complete-slice-composer.test.ts +192 -0
  260. package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +2 -1
  261. package/src/resources/extensions/gsd/tests/complete-task.test.ts +8 -4
  262. package/src/resources/extensions/gsd/tests/component-loader.test.ts +589 -0
  263. package/src/resources/extensions/gsd/tests/component-types.test.ts +127 -0
  264. package/src/resources/extensions/gsd/tests/context-store.test.ts +79 -0
  265. package/src/resources/extensions/gsd/tests/copy-planning-artifacts-samepath.test.ts +2 -1
  266. package/src/resources/extensions/gsd/tests/discuss-slice-structured-questions.test.ts +2 -1
  267. package/src/resources/extensions/gsd/tests/discuss-tool-scope-leak.test.ts +2 -1
  268. package/src/resources/extensions/gsd/tests/double-merge-guard.test.ts +4 -3
  269. package/src/resources/extensions/gsd/tests/empty-content-abort-loop.test.ts +4 -3
  270. package/src/resources/extensions/gsd/tests/extension-bootstrap-isolation.test.ts +139 -129
  271. package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +8 -104
  272. package/src/resources/extensions/gsd/tests/hook-key-parsing.test.ts +4 -55
  273. package/src/resources/extensions/gsd/tests/integration/all-milestones-complete-merge.test.ts +7 -56
  274. package/src/resources/extensions/gsd/tests/integration/doctor-proactive.test.ts +18 -2
  275. package/src/resources/extensions/gsd/tests/integration/queue-completed-milestone-perf.test.ts +10 -4
  276. package/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts +1 -1
  277. package/src/resources/extensions/gsd/tests/interactive-routing-bypass.test.ts +9 -3
  278. package/src/resources/extensions/gsd/tests/interrupted-session-ui.test.ts +6 -9
  279. package/src/resources/extensions/gsd/tests/knowledge.test.ts +93 -1
  280. package/src/resources/extensions/gsd/tests/mcp-client-security.test.ts +8 -37
  281. package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +5 -15
  282. package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +227 -55
  283. package/src/resources/extensions/gsd/tests/milestone-scope-classifier.test.ts +187 -0
  284. package/src/resources/extensions/gsd/tests/model-cost-table.test.ts +9 -1
  285. package/src/resources/extensions/gsd/tests/model-router.test.ts +1 -1
  286. package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +6 -48
  287. package/src/resources/extensions/gsd/tests/notification-widget.test.ts +6 -3
  288. package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +59 -2
  289. package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +273 -130
  290. package/src/resources/extensions/gsd/tests/pipeline-variant-dispatch.test.ts +301 -0
  291. package/src/resources/extensions/gsd/tests/preferences-worktree-sync.test.ts +2 -1
  292. package/src/resources/extensions/gsd/tests/prompt-cache-optimizer.test.ts +12 -0
  293. package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +15 -4
  294. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +22 -16
  295. package/src/resources/extensions/gsd/tests/queue-draft-detection.test.ts +3 -2
  296. package/src/resources/extensions/gsd/tests/queued-discuss-fast-path.test.ts +4 -5
  297. package/src/resources/extensions/gsd/tests/reassess-default-optin.test.ts +132 -0
  298. package/src/resources/extensions/gsd/tests/recovery-attempts-reset.test.ts +8 -40
  299. package/src/resources/extensions/gsd/tests/regex-hardening.test.ts +136 -256
  300. package/src/resources/extensions/gsd/tests/research-milestone-composer.test.ts +114 -0
  301. package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +6 -3
  302. package/src/resources/extensions/gsd/tests/run-uat-composer.test.ts +148 -0
  303. package/src/resources/extensions/gsd/tests/service-tier.test.ts +4 -0
  304. package/src/resources/extensions/gsd/tests/sidecar-queue.test.ts +3 -2
  305. package/src/resources/extensions/gsd/tests/silent-catch-diagnostics.test.ts +55 -95
  306. package/src/resources/extensions/gsd/tests/skill-activation.test.ts +120 -1
  307. package/src/resources/extensions/gsd/tests/skill-manifest.test.ts +112 -0
  308. package/src/resources/extensions/gsd/tests/slice-cadence.test.ts +242 -0
  309. package/src/resources/extensions/gsd/tests/slice-context-injection.test.ts +3 -2
  310. package/src/resources/extensions/gsd/tests/smart-entry-draft.test.ts +2 -1
  311. package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +3 -3
  312. package/src/resources/extensions/gsd/tests/structured-data-formatter.test.ts +11 -92
  313. package/src/resources/extensions/gsd/tests/subagent-model-dispatch.test.ts +7 -6
  314. package/src/resources/extensions/gsd/tests/survivor-branch-complete.test.ts +102 -101
  315. package/src/resources/extensions/gsd/tests/sync-worktree-skip-current.test.ts +4 -3
  316. package/src/resources/extensions/gsd/tests/test-helpers.test.ts +98 -0
  317. package/src/resources/extensions/gsd/tests/test-helpers.ts +153 -0
  318. package/src/resources/extensions/gsd/tests/token-profile.test.ts +8 -1
  319. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +355 -0
  320. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +203 -0
  321. package/src/resources/extensions/gsd/tests/uok-gitops-wiring.test.ts +49 -26
  322. package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +1 -0
  323. package/src/resources/extensions/gsd/tests/verify-artifact-tightened.test.ts +144 -80
  324. package/src/resources/extensions/gsd/tests/visualizer-critical-path.test.ts +20 -54
  325. package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +342 -277
  326. package/src/resources/extensions/gsd/tests/worker-model-override.test.ts +37 -29
  327. package/src/resources/extensions/gsd/tests/worktree-db.test.ts +226 -266
  328. package/src/resources/extensions/gsd/tests/worktree-health-monorepo.test.ts +103 -67
  329. package/src/resources/extensions/gsd/tests/worktree-nested-git-safety.test.ts +92 -90
  330. package/src/resources/extensions/gsd/tests/worktree-submodule-safety.test.ts +238 -59
  331. package/src/resources/extensions/gsd/tests/worktree-sync-overwrite-loop.test.ts +113 -161
  332. package/src/resources/extensions/gsd/tests/worktree-telemetry.test.ts +210 -0
  333. package/src/resources/extensions/gsd/tests/zombie-gsd-state.test.ts +80 -96
  334. package/src/resources/extensions/gsd/tools/validate-milestone.ts +8 -2
  335. package/src/resources/extensions/gsd/unit-context-composer.ts +218 -0
  336. package/src/resources/extensions/gsd/unit-context-manifest.ts +492 -0
  337. package/src/resources/extensions/gsd/worktree-manager.ts +53 -0
  338. package/src/resources/extensions/gsd/worktree-resolver.ts +96 -9
  339. package/src/resources/extensions/gsd/worktree-telemetry.ts +322 -0
  340. package/src/resources/extensions/mcp-client/index.ts +3 -1
  341. package/src/resources/extensions/mcp-client/tests/server-name-spaces.test.ts +70 -36
  342. package/src/resources/extensions/ollama/index.ts +5 -1
  343. package/src/resources/extensions/ollama/ollama-auth-mode.test.ts +123 -15
  344. package/src/resources/extensions/ollama/ollama-status-indicator.test.ts +206 -19
  345. package/src/resources/extensions/remote-questions/manager.ts +36 -4
  346. package/src/resources/extensions/remote-questions/tests/command-polling.test.ts +200 -190
  347. package/src/resources/extensions/shared/tests/interview-preview.test.ts +11 -3
  348. package/src/resources/extensions/voice/tests/linux-ready.test.ts +129 -113
  349. package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.d.ts +0 -2
  350. package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.d.ts.map +0 -1
  351. package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.js +0 -289
  352. package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.js.map +0 -1
  353. package/packages/pi-ai/src/utils/oauth/oauth-providers.test.ts +0 -363
  354. package/src/resources/extensions/gsd/tests/auto-start-model-capture.test.ts +0 -143
  355. package/src/resources/extensions/gsd/tests/complete-milestone-false-merge.test.ts +0 -157
  356. package/src/resources/extensions/gsd/tests/dashboard-model-label-ordering.test.ts +0 -107
  357. package/src/resources/extensions/gsd/tests/find-missing-summaries-closed.test.ts +0 -48
  358. package/src/resources/extensions/gsd/tests/forensics-context-persist.test.ts +0 -159
  359. package/src/resources/extensions/gsd/tests/forensics-db-completion.test.ts +0 -96
  360. package/src/resources/extensions/gsd/tests/forensics-dedup.test.ts +0 -79
  361. package/src/resources/extensions/gsd/tests/forensics-hook-key-parse.test.ts +0 -74
  362. package/src/resources/extensions/gsd/tests/forensics-journal.test.ts +0 -162
  363. package/src/resources/extensions/gsd/tests/gitignore-bg-shell.test.ts +0 -38
  364. package/src/resources/extensions/gsd/tests/gsd-no-project-error.test.ts +0 -73
  365. package/src/resources/extensions/gsd/tests/idle-watchdog-stall-override.test.ts +0 -125
  366. package/src/resources/extensions/gsd/tests/import-done-milestones.test.ts +0 -42
  367. /package/dist/web/standalone/.next/static/{vidAVJkURvTJ0_V2-64ro → gYYky7yfxW8txb9vU2TrJ}/_buildManifest.js +0 -0
  368. /package/dist/web/standalone/.next/static/{vidAVJkURvTJ0_V2-64ro → gYYky7yfxW8txb9vU2TrJ}/_ssgManifest.js +0 -0
@@ -1,89 +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
-
19
- const src = readFileSync(
20
- resolve(process.cwd(), 'src', 'resources', 'extensions', 'gsd', 'auto-recovery.ts'),
21
- 'utf-8',
22
- )
23
-
24
- describe('verifyExpectedArtifact legacy branch tightened (#3607)', () => {
25
- it('legacy branch does NOT define hdRe heading regex', () => {
26
- // Find the legacy fallback section
27
- const legacyIdx = src.indexOf('LEGACY: Pre-migration fallback')
28
- assert.ok(legacyIdx !== -1, 'LEGACY comment must exist')
29
-
30
- // Check the code within a reasonable window after the LEGACY comment
31
- const legacyBlock = src.slice(legacyIdx, legacyIdx + 600)
32
-
33
- assert.ok(
34
- !legacyBlock.includes('hdRe'),
35
- 'hdRe heading regex must NOT exist in legacy branch — heading alone is not proof of completion',
36
- )
37
- })
38
-
39
- it('legacy branch requires checked checkbox via cbRe', () => {
40
- const legacyIdx = src.indexOf('LEGACY: Pre-migration fallback')
41
- assert.ok(legacyIdx !== -1)
42
-
43
- const legacyBlock = src.slice(legacyIdx, legacyIdx + 600)
44
-
45
- assert.ok(
46
- legacyBlock.includes('cbRe'),
47
- 'cbRe checked-checkbox regex must exist in legacy branch',
48
- )
49
-
50
- // cbRe must match checked checkboxes [x] or [X]
51
- assert.ok(
52
- legacyBlock.includes('[xX]'),
53
- 'cbRe must match both [x] and [X] checkbox variants',
54
- )
55
- })
56
-
57
- it('legacy branch returns false when no plan file exists', () => {
58
- const legacyIdx = src.indexOf('LEGACY: Pre-migration fallback')
59
- assert.ok(legacyIdx !== -1)
60
-
61
- const legacyBlock = src.slice(legacyIdx, legacyIdx + 1000)
62
-
63
- // The else branch: no plan file means cannot verify
64
- assert.ok(
65
- legacyBlock.includes('no plan file'),
66
- 'missing plan file must be handled with return false',
67
- )
68
- })
69
-
70
- it('DB available but task not found returns false', () => {
71
- const legacyIdx = src.indexOf('LEGACY: Pre-migration fallback')
72
- assert.ok(legacyIdx !== -1)
73
-
74
- const legacyBlock = src.slice(legacyIdx, legacyIdx + 1000)
75
-
76
- assert.ok(
77
- legacyBlock.includes('DB available but task row not found'),
78
- 'must handle case where DB is available but task row is missing',
79
- )
80
-
81
- // The comment should be followed by a return false
82
- const commentIdx = legacyBlock.indexOf('DB available but task row not found')
83
- const afterComment = legacyBlock.slice(commentIdx, commentIdx + 200)
84
- assert.ok(
85
- afterComment.includes('return false'),
86
- 'missing task row when DB available must return false',
87
- )
88
- })
89
- })
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
+ });