gsd-pi 2.77.0-dev.eaa4973bc → 2.78.0-dev.aeeb2ca00

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 (545) hide show
  1. package/README.md +53 -17
  2. package/dist/claude-cli-check.js +46 -10
  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 +72 -16
  13. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +481 -17
  14. package/dist/resources/extensions/github-sync/templates.js +103 -0
  15. package/dist/resources/extensions/google-search/index.js +3 -2
  16. package/dist/resources/extensions/gsd/auto/loop.js +124 -2
  17. package/dist/resources/extensions/gsd/auto/phases.js +57 -39
  18. package/dist/resources/extensions/gsd/auto/session.js +6 -2
  19. package/dist/resources/extensions/gsd/auto-dispatch.js +142 -29
  20. package/dist/resources/extensions/gsd/auto-model-selection.js +124 -4
  21. package/dist/resources/extensions/gsd/auto-post-unit.js +150 -64
  22. package/dist/resources/extensions/gsd/auto-prompts.js +372 -104
  23. package/dist/resources/extensions/gsd/auto-recovery.js +197 -48
  24. package/dist/resources/extensions/gsd/auto-start.js +107 -29
  25. package/dist/resources/extensions/gsd/auto-tool-tracking.js +47 -7
  26. package/dist/resources/extensions/gsd/auto-worktree.js +122 -26
  27. package/dist/resources/extensions/gsd/auto.js +76 -21
  28. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +19 -1
  29. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +209 -0
  30. package/dist/resources/extensions/gsd/bootstrap/provider-error-resume.js +3 -6
  31. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +7 -3
  32. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +127 -9
  33. package/dist/resources/extensions/gsd/component-loader.js +447 -0
  34. package/dist/resources/extensions/gsd/component-types.js +69 -0
  35. package/dist/resources/extensions/gsd/context-store.js +23 -7
  36. package/dist/resources/extensions/gsd/detection.js +49 -1
  37. package/dist/resources/extensions/gsd/dispatch-guard.js +2 -17
  38. package/dist/resources/extensions/gsd/docs/preferences-reference.md +1 -1
  39. package/dist/resources/extensions/gsd/forensics.js +106 -0
  40. package/dist/resources/extensions/gsd/gate-registry.js +2 -2
  41. package/dist/resources/extensions/gsd/git-constants.js +28 -1
  42. package/dist/resources/extensions/gsd/git-self-heal.js +27 -0
  43. package/dist/resources/extensions/gsd/git-service.js +126 -2
  44. package/dist/resources/extensions/gsd/gsd-db.js +6 -3
  45. package/dist/resources/extensions/gsd/guided-flow.js +39 -13
  46. package/dist/resources/extensions/gsd/memory-extractor.js +7 -1
  47. package/dist/resources/extensions/gsd/milestone-scope-classifier.js +299 -0
  48. package/dist/resources/extensions/gsd/milestone-summary-classifier.js +37 -0
  49. package/dist/resources/extensions/gsd/model-cost-table.js +3 -0
  50. package/dist/resources/extensions/gsd/model-router.js +6 -0
  51. package/dist/resources/extensions/gsd/native-git-bridge.js +34 -4
  52. package/dist/resources/extensions/gsd/preferences-validation.js +23 -0
  53. package/dist/resources/extensions/gsd/prompt-cache-optimizer.js +4 -0
  54. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +6 -2
  55. package/dist/resources/extensions/gsd/prompts/discuss-headless.md +23 -4
  56. package/dist/resources/extensions/gsd/prompts/doctor-heal.md +5 -4
  57. package/dist/resources/extensions/gsd/prompts/plan-slice.md +15 -2
  58. package/dist/resources/extensions/gsd/safety/git-checkpoint.js +11 -0
  59. package/dist/resources/extensions/gsd/service-tier.js +5 -2
  60. package/dist/resources/extensions/gsd/session-lock.js +19 -10
  61. package/dist/resources/extensions/gsd/skill-manifest.js +168 -0
  62. package/dist/resources/extensions/gsd/slice-cadence.js +238 -0
  63. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +278 -8
  64. package/dist/resources/extensions/gsd/state-transition-matrix.js +118 -0
  65. package/dist/resources/extensions/gsd/state.js +69 -58
  66. package/dist/resources/extensions/gsd/sync-lock.js +98 -42
  67. package/dist/resources/extensions/gsd/tools/validate-milestone.js +7 -2
  68. package/dist/resources/extensions/gsd/unit-context-composer.js +147 -0
  69. package/dist/resources/extensions/gsd/unit-context-manifest.js +370 -0
  70. package/dist/resources/extensions/gsd/uok/dispatch-envelope.js +33 -0
  71. package/dist/resources/extensions/gsd/uok/execution-graph.js +10 -0
  72. package/dist/resources/extensions/gsd/uok/gate-runner.js +53 -5
  73. package/dist/resources/extensions/gsd/uok/gitops.js +2 -1
  74. package/dist/resources/extensions/gsd/uok/loop-adapter.js +37 -10
  75. package/dist/resources/extensions/gsd/uok/parity-report.js +58 -0
  76. package/dist/resources/extensions/gsd/uok/plan-v2.js +10 -4
  77. package/dist/resources/extensions/gsd/uok/writer.js +82 -0
  78. package/dist/resources/extensions/gsd/workflow-mcp.js +6 -0
  79. package/dist/resources/extensions/gsd/worktree-manager.js +85 -8
  80. package/dist/resources/extensions/gsd/worktree-resolver.js +86 -7
  81. package/dist/resources/extensions/gsd/worktree-telemetry.js +198 -0
  82. package/dist/resources/extensions/mcp-client/index.js +3 -1
  83. package/dist/resources/extensions/ollama/index.js +5 -1
  84. package/dist/resources/extensions/remote-questions/manager.js +11 -5
  85. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  86. package/dist/web/standalone/.next/BUILD_ID +1 -1
  87. package/dist/web/standalone/.next/app-path-routes-manifest.json +11 -11
  88. package/dist/web/standalone/.next/build-manifest.json +2 -2
  89. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  90. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  91. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  92. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  93. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  94. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  95. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  96. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  97. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  98. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  99. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  100. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  101. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  102. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  103. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  104. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  105. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  106. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  107. package/dist/web/standalone/.next/server/app/index.html +1 -1
  108. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  109. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  110. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  111. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  112. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  113. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  114. package/dist/web/standalone/.next/server/app-paths-manifest.json +11 -11
  115. package/dist/web/standalone/.next/server/chunks/1926.js +1 -1
  116. package/dist/web/standalone/.next/server/chunks/6897.js +1 -1
  117. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  118. package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
  119. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  120. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  121. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  122. package/package.json +2 -3
  123. package/packages/daemon/package.json +2 -2
  124. package/packages/daemon/src/logger.ts +4 -3
  125. package/packages/mcp-server/dist/server.d.ts +24 -0
  126. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  127. package/packages/mcp-server/dist/server.js +88 -87
  128. package/packages/mcp-server/dist/server.js.map +1 -1
  129. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  130. package/packages/mcp-server/dist/workflow-tools.js +15 -6
  131. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  132. package/packages/mcp-server/package.json +2 -2
  133. package/packages/mcp-server/src/mcp-server.test.ts +25 -3
  134. package/packages/mcp-server/src/readers/graph.test.ts +87 -15
  135. package/packages/mcp-server/src/secure-env-collect.test.ts +232 -237
  136. package/packages/mcp-server/src/server.ts +131 -105
  137. package/packages/mcp-server/src/workflow-tools.test.ts +85 -0
  138. package/packages/mcp-server/src/workflow-tools.ts +19 -6
  139. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  140. package/packages/native/package.json +2 -2
  141. package/packages/native/src/__tests__/_test-coverage-guard.test.mjs +98 -0
  142. package/packages/native/src/__tests__/module-compat.test.mjs +59 -27
  143. package/packages/native/src/__tests__/ps.test.mjs +14 -8
  144. package/packages/native/src/__tests__/stream-process.test.mjs +23 -2
  145. package/packages/native/src/__tests__/truncate.test.mjs +17 -2
  146. package/packages/pi-agent-core/package.json +1 -1
  147. package/packages/pi-agent-core/src/agent-loop.test.ts +5 -15
  148. package/packages/pi-agent-core/src/agent.test.ts +96 -102
  149. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  150. package/packages/pi-ai/dist/models/capability-patches.d.ts.map +1 -1
  151. package/packages/pi-ai/dist/models/capability-patches.js +9 -2
  152. package/packages/pi-ai/dist/models/capability-patches.js.map +1 -1
  153. package/packages/pi-ai/dist/models/generated/index.d.ts +34 -0
  154. package/packages/pi-ai/dist/models/generated/index.d.ts.map +1 -1
  155. package/packages/pi-ai/dist/models/generated/openai-codex.d.ts +17 -0
  156. package/packages/pi-ai/dist/models/generated/openai-codex.d.ts.map +1 -1
  157. package/packages/pi-ai/dist/models/generated/openai-codex.js +17 -0
  158. package/packages/pi-ai/dist/models/generated/openai-codex.js.map +1 -1
  159. package/packages/pi-ai/dist/models/generated/openai.d.ts +17 -0
  160. package/packages/pi-ai/dist/models/generated/openai.d.ts.map +1 -1
  161. package/packages/pi-ai/dist/models/generated/openai.js +17 -0
  162. package/packages/pi-ai/dist/models/generated/openai.js.map +1 -1
  163. package/packages/pi-ai/dist/models.generated.test.js +43 -70
  164. package/packages/pi-ai/dist/models.generated.test.js.map +1 -1
  165. package/packages/pi-ai/dist/models.test.js +36 -11
  166. package/packages/pi-ai/dist/models.test.js.map +1 -1
  167. package/packages/pi-ai/package.json +1 -1
  168. package/packages/pi-ai/scripts/generate-models.ts +44 -0
  169. package/packages/pi-ai/src/models/capability-patches.ts +10 -2
  170. package/packages/pi-ai/src/models/generated/openai-codex.ts +17 -0
  171. package/packages/pi-ai/src/models/generated/openai.ts +17 -0
  172. package/packages/pi-ai/src/models.generated.test.ts +46 -73
  173. package/packages/pi-ai/src/models.test.ts +48 -11
  174. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  175. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +96 -32
  176. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js.map +1 -1
  177. package/packages/pi-coding-agent/dist/core/agent-session-model-switch.test.js +75 -12
  178. package/packages/pi-coding-agent/dist/core/agent-session-model-switch.test.js.map +1 -1
  179. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js +99 -31
  180. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js.map +1 -1
  181. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts +5 -0
  182. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  183. package/packages/pi-coding-agent/dist/core/extensions/loader.js +61 -0
  184. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  185. package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.js +30 -4
  186. package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.js.map +1 -1
  187. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +17 -0
  188. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -1
  189. package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.js +76 -18
  190. package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.js.map +1 -1
  191. package/packages/pi-coding-agent/dist/core/retry-handler.d.ts.map +1 -1
  192. package/packages/pi-coding-agent/dist/core/retry-handler.js +2 -6
  193. package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -1
  194. package/packages/pi-coding-agent/dist/core/retry-handler.test.js +5 -1
  195. package/packages/pi-coding-agent/dist/core/retry-handler.test.js.map +1 -1
  196. package/packages/pi-coding-agent/dist/core/retryable-error-regex.d.ts +18 -0
  197. package/packages/pi-coding-agent/dist/core/retryable-error-regex.d.ts.map +1 -0
  198. package/packages/pi-coding-agent/dist/core/retryable-error-regex.js +18 -0
  199. package/packages/pi-coding-agent/dist/core/retryable-error-regex.js.map +1 -0
  200. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts +20 -0
  201. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
  202. package/packages/pi-coding-agent/dist/core/system-prompt.js +16 -2
  203. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  204. package/packages/pi-coding-agent/dist/index.d.ts +1 -0
  205. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  206. package/packages/pi-coding-agent/dist/index.js +1 -0
  207. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  208. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +36 -5
  209. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
  210. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.js +20 -13
  211. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.js.map +1 -1
  212. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  213. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +30 -12
  214. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  215. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
  216. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +18 -3
  217. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  218. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +125 -0
  219. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
  220. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts +2 -0
  221. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -1
  222. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.js.map +1 -1
  223. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +4 -0
  224. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  225. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +105 -13
  226. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  227. package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.d.ts +2 -0
  228. package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.d.ts.map +1 -0
  229. package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.js +130 -0
  230. package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.js.map +1 -0
  231. package/packages/pi-coding-agent/package.json +1 -1
  232. package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +113 -37
  233. package/packages/pi-coding-agent/src/core/agent-session-model-switch.test.ts +89 -17
  234. package/packages/pi-coding-agent/src/core/agent-session-tool-refresh.test.ts +112 -43
  235. package/packages/pi-coding-agent/src/core/extensions/loader.ts +58 -0
  236. package/packages/pi-coding-agent/src/core/lsp/lsp-integration.test.ts +35 -4
  237. package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +20 -0
  238. package/packages/pi-coding-agent/src/core/resource-loader-cache-reset.test.ts +93 -28
  239. package/packages/pi-coding-agent/src/core/retry-handler.test.ts +5 -1
  240. package/packages/pi-coding-agent/src/core/retry-handler.ts +2 -8
  241. package/packages/pi-coding-agent/src/core/retryable-error-regex.ts +18 -0
  242. package/packages/pi-coding-agent/src/core/system-prompt.ts +35 -1
  243. package/packages/pi-coding-agent/src/index.ts +1 -0
  244. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +49 -3
  245. package/packages/pi-coding-agent/src/modes/interactive/components/dynamic-border.test.ts +26 -20
  246. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +48 -9
  247. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +146 -1
  248. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +20 -3
  249. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-state.ts +2 -0
  250. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +119 -13
  251. package/packages/pi-coding-agent/src/tests/system-prompt-skill-filter.test.ts +157 -0
  252. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  253. package/packages/pi-tui/dist/__tests__/autocomplete.test.js +18 -8
  254. package/packages/pi-tui/dist/__tests__/autocomplete.test.js.map +1 -1
  255. package/packages/pi-tui/dist/__tests__/overlay-layout.test.js +128 -17
  256. package/packages/pi-tui/dist/__tests__/overlay-layout.test.js.map +1 -1
  257. package/packages/pi-tui/dist/__tests__/stdin-buffer.test.js +37 -11
  258. package/packages/pi-tui/dist/__tests__/stdin-buffer.test.js.map +1 -1
  259. package/packages/pi-tui/dist/__tests__/tui.test.js +18 -30
  260. package/packages/pi-tui/dist/__tests__/tui.test.js.map +1 -1
  261. package/packages/pi-tui/dist/components/__tests__/input.test.js +10 -3
  262. package/packages/pi-tui/dist/components/__tests__/input.test.js.map +1 -1
  263. package/packages/pi-tui/dist/components/__tests__/loader.test.js +53 -9
  264. package/packages/pi-tui/dist/components/__tests__/loader.test.js.map +1 -1
  265. package/packages/pi-tui/dist/components/__tests__/markdown-maxlines.test.js +6 -2
  266. package/packages/pi-tui/dist/components/__tests__/markdown-maxlines.test.js.map +1 -1
  267. package/packages/pi-tui/dist/components/editor.d.ts +14 -0
  268. package/packages/pi-tui/dist/components/editor.d.ts.map +1 -1
  269. package/packages/pi-tui/dist/components/editor.js +19 -0
  270. package/packages/pi-tui/dist/components/editor.js.map +1 -1
  271. package/packages/pi-tui/dist/components/image.test.js +6 -5
  272. package/packages/pi-tui/dist/components/image.test.js.map +1 -1
  273. package/packages/pi-tui/dist/editor-component.d.ts +2 -0
  274. package/packages/pi-tui/dist/editor-component.d.ts.map +1 -1
  275. package/packages/pi-tui/dist/editor-component.js.map +1 -1
  276. package/packages/pi-tui/package.json +1 -1
  277. package/packages/pi-tui/src/__tests__/autocomplete.test.ts +24 -8
  278. package/packages/pi-tui/src/__tests__/overlay-layout.test.ts +140 -17
  279. package/packages/pi-tui/src/__tests__/stdin-buffer.test.ts +42 -11
  280. package/packages/pi-tui/src/__tests__/tui.test.ts +18 -37
  281. package/packages/pi-tui/src/components/__tests__/input.test.ts +19 -3
  282. package/packages/pi-tui/src/components/__tests__/loader.test.ts +112 -35
  283. package/packages/pi-tui/src/components/__tests__/markdown-maxlines.test.ts +9 -2
  284. package/packages/pi-tui/src/components/editor.ts +22 -0
  285. package/packages/pi-tui/src/components/image.test.ts +10 -5
  286. package/packages/pi-tui/src/editor-component.ts +3 -0
  287. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  288. package/packages/rpc-client/dist/rpc-client.test.js +101 -51
  289. package/packages/rpc-client/dist/rpc-client.test.js.map +1 -1
  290. package/packages/rpc-client/package.json +1 -1
  291. package/packages/rpc-client/src/rpc-client.test.ts +109 -52
  292. package/packages/rpc-client/tsconfig.tsbuildinfo +1 -1
  293. package/pkg/package.json +1 -1
  294. package/scripts/install.js +15 -1
  295. package/src/resources/extensions/browser-tools/capture.ts +12 -0
  296. package/src/resources/extensions/browser-tools/tests/browser-tools-integration.test.mjs +8 -59
  297. package/src/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +36 -24
  298. package/src/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +69 -71
  299. package/src/resources/extensions/browser-tools/tools/forms.ts +5 -1
  300. package/src/resources/extensions/browser-tools/tools/intent.ts +5 -1
  301. package/src/resources/extensions/claude-code-cli/readiness.ts +75 -16
  302. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +518 -19
  303. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +919 -75
  304. package/src/resources/extensions/github-sync/templates.ts +151 -0
  305. package/src/resources/extensions/github-sync/tests/cli.test.ts +76 -7
  306. package/src/resources/extensions/github-sync/tests/templates.test.ts +92 -1
  307. package/src/resources/extensions/google-search/index.ts +3 -2
  308. package/src/resources/extensions/gsd/auto/loop.ts +142 -2
  309. package/src/resources/extensions/gsd/auto/phases.ts +62 -38
  310. package/src/resources/extensions/gsd/auto/session.ts +7 -2
  311. package/src/resources/extensions/gsd/auto-dispatch.ts +156 -29
  312. package/src/resources/extensions/gsd/auto-model-selection.ts +131 -4
  313. package/src/resources/extensions/gsd/auto-post-unit.ts +163 -73
  314. package/src/resources/extensions/gsd/auto-prompts.ts +385 -93
  315. package/src/resources/extensions/gsd/auto-recovery.ts +230 -51
  316. package/src/resources/extensions/gsd/auto-start.ts +127 -9
  317. package/src/resources/extensions/gsd/auto-tool-tracking.ts +51 -7
  318. package/src/resources/extensions/gsd/auto-worktree.ts +130 -26
  319. package/src/resources/extensions/gsd/auto.ts +90 -23
  320. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +20 -1
  321. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +221 -0
  322. package/src/resources/extensions/gsd/bootstrap/provider-error-resume.ts +3 -7
  323. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +7 -3
  324. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +158 -9
  325. package/src/resources/extensions/gsd/component-loader.ts +598 -0
  326. package/src/resources/extensions/gsd/component-types.ts +362 -0
  327. package/src/resources/extensions/gsd/context-store.ts +25 -8
  328. package/src/resources/extensions/gsd/detection.ts +58 -1
  329. package/src/resources/extensions/gsd/dispatch-guard.ts +2 -20
  330. package/src/resources/extensions/gsd/docs/preferences-reference.md +1 -1
  331. package/src/resources/extensions/gsd/forensics.ts +118 -1
  332. package/src/resources/extensions/gsd/gate-registry.ts +2 -2
  333. package/src/resources/extensions/gsd/git-constants.ts +30 -1
  334. package/src/resources/extensions/gsd/git-self-heal.ts +31 -0
  335. package/src/resources/extensions/gsd/git-service.ts +149 -2
  336. package/src/resources/extensions/gsd/gsd-db.ts +6 -3
  337. package/src/resources/extensions/gsd/guided-flow.ts +57 -14
  338. package/src/resources/extensions/gsd/journal.ts +11 -1
  339. package/src/resources/extensions/gsd/memory-extractor.ts +11 -3
  340. package/src/resources/extensions/gsd/milestone-scope-classifier.ts +366 -0
  341. package/src/resources/extensions/gsd/milestone-summary-classifier.ts +42 -0
  342. package/src/resources/extensions/gsd/model-cost-table.ts +3 -0
  343. package/src/resources/extensions/gsd/model-router.ts +6 -0
  344. package/src/resources/extensions/gsd/native-git-bridge.ts +34 -4
  345. package/src/resources/extensions/gsd/preferences-validation.ts +21 -0
  346. package/src/resources/extensions/gsd/prompt-cache-optimizer.ts +4 -0
  347. package/src/resources/extensions/gsd/prompts/complete-milestone.md +6 -2
  348. package/src/resources/extensions/gsd/prompts/discuss-headless.md +23 -4
  349. package/src/resources/extensions/gsd/prompts/doctor-heal.md +5 -4
  350. package/src/resources/extensions/gsd/prompts/plan-slice.md +15 -2
  351. package/src/resources/extensions/gsd/safety/git-checkpoint.ts +15 -0
  352. package/src/resources/extensions/gsd/service-tier.ts +5 -2
  353. package/src/resources/extensions/gsd/session-lock.ts +20 -10
  354. package/src/resources/extensions/gsd/skill-manifest.ts +175 -0
  355. package/src/resources/extensions/gsd/slice-cadence.ts +299 -0
  356. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +309 -8
  357. package/src/resources/extensions/gsd/state-transition-matrix.ts +152 -0
  358. package/src/resources/extensions/gsd/state.ts +76 -66
  359. package/src/resources/extensions/gsd/sync-lock.ts +97 -39
  360. package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +270 -0
  361. package/src/resources/extensions/gsd/tests/artifacts-table-preserved-on-cache-invalidate.test.ts +2 -1
  362. package/src/resources/extensions/gsd/tests/auto-deterministic-error-classification-4973.test.ts +341 -0
  363. package/src/resources/extensions/gsd/tests/auto-discuss-milestone-deadlock-4973.test.ts +264 -0
  364. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +133 -292
  365. package/src/resources/extensions/gsd/tests/auto-model-selection-tool-poisoning.test.ts +742 -0
  366. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +78 -0
  367. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +61 -0
  368. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +93 -0
  369. package/src/resources/extensions/gsd/tests/auto-remediate-slice-status.test.ts +4 -1
  370. package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +8 -194
  371. package/src/resources/extensions/gsd/tests/auto-start-clean-runtime-db-gated.test.ts +3 -2
  372. package/src/resources/extensions/gsd/tests/auto-start-cold-db-bootstrap.test.ts +2 -2
  373. package/src/resources/extensions/gsd/tests/auto-start-needs-discussion.test.ts +15 -58
  374. package/src/resources/extensions/gsd/tests/auto-start-worktree-db-path.test.ts +2 -2
  375. package/src/resources/extensions/gsd/tests/auto-thinking-restore.test.ts +3 -2
  376. package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +3 -2
  377. package/src/resources/extensions/gsd/tests/bootstrap-derive-state-db-open.test.ts +2 -1
  378. package/src/resources/extensions/gsd/tests/cache-staleness-regression.test.ts +17 -21
  379. package/src/resources/extensions/gsd/tests/canonical-milestone-root.test.ts +108 -0
  380. package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +263 -0
  381. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +25 -0
  382. package/src/resources/extensions/gsd/tests/complete-slice-composer.test.ts +192 -0
  383. package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +2 -1
  384. package/src/resources/extensions/gsd/tests/complete-task.test.ts +16 -8
  385. package/src/resources/extensions/gsd/tests/component-loader.test.ts +589 -0
  386. package/src/resources/extensions/gsd/tests/component-types.test.ts +127 -0
  387. package/src/resources/extensions/gsd/tests/context-store.test.ts +79 -0
  388. package/src/resources/extensions/gsd/tests/copy-planning-artifacts-samepath.test.ts +2 -1
  389. package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +50 -1
  390. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +159 -0
  391. package/src/resources/extensions/gsd/tests/db-access-guardrails.test.ts +1 -0
  392. package/src/resources/extensions/gsd/tests/derive-state-crossval.test.ts +3 -3
  393. package/src/resources/extensions/gsd/tests/derive-state-db-disk-reconcile.test.ts +40 -0
  394. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +91 -3
  395. package/src/resources/extensions/gsd/tests/derive-state.test.ts +4 -4
  396. package/src/resources/extensions/gsd/tests/discuss-slice-structured-questions.test.ts +2 -1
  397. package/src/resources/extensions/gsd/tests/discuss-tool-scope-leak.test.ts +2 -1
  398. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +5 -0
  399. package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +25 -0
  400. package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +14 -0
  401. package/src/resources/extensions/gsd/tests/dispatcher-stuck-planning.test.ts +3 -2
  402. package/src/resources/extensions/gsd/tests/double-merge-guard.test.ts +4 -3
  403. package/src/resources/extensions/gsd/tests/empty-content-abort-loop.test.ts +4 -3
  404. package/src/resources/extensions/gsd/tests/execution-entry-missing-context-4671.test.ts +173 -0
  405. package/src/resources/extensions/gsd/tests/extension-bootstrap-isolation.test.ts +139 -129
  406. package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +8 -104
  407. package/src/resources/extensions/gsd/tests/gate-state-canonicalization.test.ts +102 -0
  408. package/src/resources/extensions/gsd/tests/gate-storage.test.ts +1 -1
  409. package/src/resources/extensions/gsd/tests/google-search-stub.test.ts +14 -4
  410. package/src/resources/extensions/gsd/tests/headless-milestone-parity.test.ts +117 -0
  411. package/src/resources/extensions/gsd/tests/hook-key-parsing.test.ts +4 -55
  412. package/src/resources/extensions/gsd/tests/integration/all-milestones-complete-merge.test.ts +7 -56
  413. package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +20 -0
  414. package/src/resources/extensions/gsd/tests/integration/doctor-proactive.test.ts +18 -2
  415. package/src/resources/extensions/gsd/tests/integration/queue-completed-milestone-perf.test.ts +10 -4
  416. package/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts +144 -7
  417. package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +4 -0
  418. package/src/resources/extensions/gsd/tests/integration/state-machine-runtime-failures.test.ts +2 -16
  419. package/src/resources/extensions/gsd/tests/interactive-routing-bypass.test.ts +9 -3
  420. package/src/resources/extensions/gsd/tests/interrupted-session-ui.test.ts +6 -9
  421. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +64 -0
  422. package/src/resources/extensions/gsd/tests/knowledge.test.ts +93 -1
  423. package/src/resources/extensions/gsd/tests/mcp-client-security.test.ts +8 -37
  424. package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +5 -15
  425. package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +227 -55
  426. package/src/resources/extensions/gsd/tests/milestone-scope-classifier.test.ts +187 -0
  427. package/src/resources/extensions/gsd/tests/milestone-summary-classifier.test.ts +30 -0
  428. package/src/resources/extensions/gsd/tests/model-cost-table.test.ts +9 -1
  429. package/src/resources/extensions/gsd/tests/model-router.test.ts +1 -1
  430. package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +6 -48
  431. package/src/resources/extensions/gsd/tests/notification-widget.test.ts +6 -3
  432. package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +59 -2
  433. package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +273 -130
  434. package/src/resources/extensions/gsd/tests/pipeline-variant-dispatch.test.ts +301 -0
  435. package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +32 -1
  436. package/src/resources/extensions/gsd/tests/preferences-worktree-sync.test.ts +2 -1
  437. package/src/resources/extensions/gsd/tests/prompt-cache-optimizer.test.ts +12 -0
  438. package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +15 -4
  439. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +23 -24
  440. package/src/resources/extensions/gsd/tests/queue-auto-guard.test.ts +32 -0
  441. package/src/resources/extensions/gsd/tests/queue-draft-detection.test.ts +3 -2
  442. package/src/resources/extensions/gsd/tests/queued-discuss-fast-path.test.ts +4 -5
  443. package/src/resources/extensions/gsd/tests/ready-phrase-no-files-4573.test.ts +75 -2
  444. package/src/resources/extensions/gsd/tests/reassess-default-optin.test.ts +132 -0
  445. package/src/resources/extensions/gsd/tests/recovery-attempts-reset.test.ts +8 -40
  446. package/src/resources/extensions/gsd/tests/regex-hardening.test.ts +136 -256
  447. package/src/resources/extensions/gsd/tests/research-milestone-composer.test.ts +114 -0
  448. package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +6 -3
  449. package/src/resources/extensions/gsd/tests/run-uat-composer.test.ts +148 -0
  450. package/src/resources/extensions/gsd/tests/service-tier.test.ts +4 -0
  451. package/src/resources/extensions/gsd/tests/session-lock-regression.test.ts +29 -0
  452. package/src/resources/extensions/gsd/tests/sidecar-queue.test.ts +3 -2
  453. package/src/resources/extensions/gsd/tests/silent-catch-diagnostics.test.ts +55 -95
  454. package/src/resources/extensions/gsd/tests/single-writer-v3-tool-surface.test.ts +158 -0
  455. package/src/resources/extensions/gsd/tests/skill-activation.test.ts +120 -1
  456. package/src/resources/extensions/gsd/tests/skill-manifest.test.ts +112 -0
  457. package/src/resources/extensions/gsd/tests/slice-cadence.test.ts +242 -0
  458. package/src/resources/extensions/gsd/tests/slice-context-injection.test.ts +3 -2
  459. package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +164 -1
  460. package/src/resources/extensions/gsd/tests/smart-entry-draft.test.ts +2 -1
  461. package/src/resources/extensions/gsd/tests/stale-dirlistcache-4648.test.ts +112 -0
  462. package/src/resources/extensions/gsd/tests/state-machine-full-walkthrough.test.ts +29 -5
  463. package/src/resources/extensions/gsd/tests/state-transition-matrix.test.ts +44 -0
  464. package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +3 -3
  465. package/src/resources/extensions/gsd/tests/structured-data-formatter.test.ts +11 -92
  466. package/src/resources/extensions/gsd/tests/subagent-model-dispatch.test.ts +7 -6
  467. package/src/resources/extensions/gsd/tests/survivor-branch-complete.test.ts +102 -101
  468. package/src/resources/extensions/gsd/tests/sync-lock.test.ts +31 -0
  469. package/src/resources/extensions/gsd/tests/sync-worktree-skip-current.test.ts +4 -3
  470. package/src/resources/extensions/gsd/tests/test-helpers.test.ts +98 -0
  471. package/src/resources/extensions/gsd/tests/test-helpers.ts +153 -0
  472. package/src/resources/extensions/gsd/tests/token-profile.test.ts +8 -1
  473. package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +61 -1
  474. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +8 -1
  475. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +355 -0
  476. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +258 -0
  477. package/src/resources/extensions/gsd/tests/uok-contracts.test.ts +51 -0
  478. package/src/resources/extensions/gsd/tests/uok-execution-graph.test.ts +16 -0
  479. package/src/resources/extensions/gsd/tests/uok-gate-runner.test.ts +75 -0
  480. package/src/resources/extensions/gsd/tests/uok-gitops-wiring.test.ts +49 -26
  481. package/src/resources/extensions/gsd/tests/uok-loop-adapter-writer.test.ts +65 -0
  482. package/src/resources/extensions/gsd/tests/uok-parity-report.test.ts +42 -0
  483. package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +19 -2
  484. package/src/resources/extensions/gsd/tests/uok-writer.test.ts +75 -0
  485. package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +12 -0
  486. package/src/resources/extensions/gsd/tests/verify-artifact-tightened.test.ts +144 -80
  487. package/src/resources/extensions/gsd/tests/visualizer-critical-path.test.ts +20 -54
  488. package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +342 -277
  489. package/src/resources/extensions/gsd/tests/worker-model-override.test.ts +37 -29
  490. package/src/resources/extensions/gsd/tests/worktree-db.test.ts +226 -266
  491. package/src/resources/extensions/gsd/tests/worktree-health-monorepo.test.ts +103 -67
  492. package/src/resources/extensions/gsd/tests/worktree-nested-git-safety.test.ts +92 -90
  493. package/src/resources/extensions/gsd/tests/worktree-submodule-safety.test.ts +238 -59
  494. package/src/resources/extensions/gsd/tests/worktree-sync-overwrite-loop.test.ts +113 -161
  495. package/src/resources/extensions/gsd/tests/worktree-telemetry.test.ts +210 -0
  496. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +262 -0
  497. package/src/resources/extensions/gsd/tests/write-gate-predicates.test.ts +186 -0
  498. package/src/resources/extensions/gsd/tests/write-gate.test.ts +7 -5
  499. package/src/resources/extensions/gsd/tests/zombie-gsd-state.test.ts +80 -96
  500. package/src/resources/extensions/gsd/tools/validate-milestone.ts +8 -2
  501. package/src/resources/extensions/gsd/types.ts +3 -3
  502. package/src/resources/extensions/gsd/unit-context-composer.ts +218 -0
  503. package/src/resources/extensions/gsd/unit-context-manifest.ts +574 -0
  504. package/src/resources/extensions/gsd/uok/contracts.ts +65 -0
  505. package/src/resources/extensions/gsd/uok/dispatch-envelope.ts +56 -0
  506. package/src/resources/extensions/gsd/uok/execution-graph.ts +22 -0
  507. package/src/resources/extensions/gsd/uok/gate-runner.ts +65 -5
  508. package/src/resources/extensions/gsd/uok/gitops.ts +6 -1
  509. package/src/resources/extensions/gsd/uok/loop-adapter.ts +45 -10
  510. package/src/resources/extensions/gsd/uok/parity-report.ts +84 -0
  511. package/src/resources/extensions/gsd/uok/plan-v2.ts +13 -5
  512. package/src/resources/extensions/gsd/uok/writer.ts +113 -0
  513. package/src/resources/extensions/gsd/workflow-mcp.ts +6 -0
  514. package/src/resources/extensions/gsd/worktree-manager.ts +108 -7
  515. package/src/resources/extensions/gsd/worktree-resolver.ts +96 -9
  516. package/src/resources/extensions/gsd/worktree-telemetry.ts +322 -0
  517. package/src/resources/extensions/mcp-client/index.ts +3 -1
  518. package/src/resources/extensions/mcp-client/tests/server-name-spaces.test.ts +70 -36
  519. package/src/resources/extensions/ollama/index.ts +5 -1
  520. package/src/resources/extensions/ollama/ollama-auth-mode.test.ts +123 -15
  521. package/src/resources/extensions/ollama/ollama-status-indicator.test.ts +206 -19
  522. package/src/resources/extensions/remote-questions/manager.ts +36 -4
  523. package/src/resources/extensions/remote-questions/tests/command-polling.test.ts +200 -190
  524. package/src/resources/extensions/shared/tests/interview-preview.test.ts +11 -3
  525. package/src/resources/extensions/voice/tests/linux-ready.test.ts +129 -113
  526. package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.d.ts +0 -2
  527. package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.d.ts.map +0 -1
  528. package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.js +0 -289
  529. package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.js.map +0 -1
  530. package/packages/pi-ai/src/utils/oauth/oauth-providers.test.ts +0 -363
  531. package/src/resources/extensions/gsd/tests/auto-start-model-capture.test.ts +0 -143
  532. package/src/resources/extensions/gsd/tests/complete-milestone-false-merge.test.ts +0 -157
  533. package/src/resources/extensions/gsd/tests/dashboard-model-label-ordering.test.ts +0 -107
  534. package/src/resources/extensions/gsd/tests/find-missing-summaries-closed.test.ts +0 -48
  535. package/src/resources/extensions/gsd/tests/forensics-context-persist.test.ts +0 -159
  536. package/src/resources/extensions/gsd/tests/forensics-db-completion.test.ts +0 -96
  537. package/src/resources/extensions/gsd/tests/forensics-dedup.test.ts +0 -79
  538. package/src/resources/extensions/gsd/tests/forensics-hook-key-parse.test.ts +0 -74
  539. package/src/resources/extensions/gsd/tests/forensics-journal.test.ts +0 -162
  540. package/src/resources/extensions/gsd/tests/gitignore-bg-shell.test.ts +0 -38
  541. package/src/resources/extensions/gsd/tests/gsd-no-project-error.test.ts +0 -73
  542. package/src/resources/extensions/gsd/tests/idle-watchdog-stall-override.test.ts +0 -125
  543. package/src/resources/extensions/gsd/tests/import-done-milestones.test.ts +0 -42
  544. /package/dist/web/standalone/.next/static/{5wbu35_C2_MQ3Jj1lEVDx → cAJH99yNS1UPbeSEiNRrV}/_buildManifest.js +0 -0
  545. /package/dist/web/standalone/.next/static/{5wbu35_C2_MQ3Jj1lEVDx → cAJH99yNS1UPbeSEiNRrV}/_ssgManifest.js +0 -0
@@ -4,7 +4,13 @@ import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
4
4
  import { join } from "node:path";
5
5
  import { tmpdir } from "node:os";
6
6
  import { loadSkills } from "@gsd/pi-coding-agent";
7
- import { buildSkillActivationBlock } from "../auto-prompts.js";
7
+ import {
8
+ buildPlanMilestonePrompt,
9
+ buildResearchMilestonePrompt,
10
+ buildSkillActivationBlock,
11
+ } from "../auto-prompts.js";
12
+ import { warnIfManifestHasMissingSkills } from "../skill-manifest.js";
13
+ import { _resetLogs, drainLogs, setStderrLoggingEnabled } from "../workflow-logger.js";
8
14
  import type { GSDPreferences } from "../preferences.js";
9
15
 
10
16
  function makeTempBase(): string {
@@ -25,6 +31,11 @@ function loadOnlyTestSkills(base: string): void {
25
31
  loadSkills({ cwd: base, includeDefaults: false, skillPaths: [join(base, "skills")] });
26
32
  }
27
33
 
34
+ function writeProjectPreferences(base: string, preferences: string): void {
35
+ mkdirSync(join(base, ".gsd"), { recursive: true });
36
+ writeFileSync(join(base, ".gsd", "PREFERENCES.md"), `---\n${preferences}---\n`);
37
+ }
38
+
28
39
  function buildBlock(
29
40
  base: string,
30
41
  params: Partial<Parameters<typeof buildSkillActivationBlock>[0]> = {},
@@ -231,3 +242,111 @@ test("buildSkillActivationBlock allows valid skill names and rejects invalid one
231
242
  cleanup(base);
232
243
  }
233
244
  });
245
+
246
+ // ─── Per-unit-type skill manifest (RFC #4779) ─────────────────────────────────
247
+
248
+ test("buildSkillActivationBlock: explicit always_use_skills bypass the unit-type manifest", () => {
249
+ const base = makeTempBase();
250
+ try {
251
+ // write-docs is in the research-milestone manifest; swiftui is not.
252
+ // Both are in always_use_skills — a user-explicit source — so BOTH
253
+ // should activate regardless of the manifest. User intent wins over
254
+ // unit-type defaults. See RFC #4779 and skill-manifest.ts rationale.
255
+ writeSkill(base, "write-docs", "Use when writing docs or RFCs.");
256
+ writeSkill(base, "swiftui", "Use for SwiftUI views.");
257
+ loadOnlyTestSkills(base);
258
+
259
+ const result = buildBlock(base, { unitType: "research-milestone" }, {
260
+ always_use_skills: ["write-docs", "swiftui"],
261
+ });
262
+
263
+ assert.match(result, /Call Skill\(\{ skill: 'write-docs' \}\)/);
264
+ assert.match(result, /Call Skill\(\{ skill: 'swiftui' \}\)/);
265
+ } finally {
266
+ cleanup(base);
267
+ }
268
+ });
269
+
270
+ test("buildSkillActivationBlock falls through to all skills for unknown unit type", () => {
271
+ const base = makeTempBase();
272
+ try {
273
+ writeSkill(base, "swiftui", "Use for SwiftUI views.");
274
+ loadOnlyTestSkills(base);
275
+
276
+ const result = buildBlock(base, { unitType: "unknown-unit-type" }, {
277
+ always_use_skills: ["swiftui"],
278
+ });
279
+
280
+ // Unknown unit type = wildcard fallback (pre-manifest behavior).
281
+ assert.match(result, /Call Skill\(\{ skill: 'swiftui' \}\)/);
282
+ } finally {
283
+ cleanup(base);
284
+ }
285
+ });
286
+
287
+ test("buildSkillActivationBlock without unitType preserves pre-manifest behavior", () => {
288
+ const base = makeTempBase();
289
+ try {
290
+ writeSkill(base, "swiftui", "Use for SwiftUI views.");
291
+ loadOnlyTestSkills(base);
292
+
293
+ // No unitType param — filter should no-op.
294
+ const result = buildBlock(base, {}, {
295
+ always_use_skills: ["swiftui"],
296
+ });
297
+
298
+ assert.match(result, /Call Skill\(\{ skill: 'swiftui' \}\)/);
299
+ } finally {
300
+ cleanup(base);
301
+ }
302
+ });
303
+
304
+ test("milestone prompt builders propagate always_use_skills through buildSkillActivationBlock", async () => {
305
+ const base = makeTempBase();
306
+ try {
307
+ // Both skills are in always_use_skills — explicit user intent bypasses
308
+ // the unit-type manifest, so both activate in both milestone flows.
309
+ writeSkill(base, "write-docs", "Use when writing docs or RFCs.");
310
+ writeSkill(base, "swiftui", "Use for SwiftUI views.");
311
+ writeProjectPreferences(base, "always_use_skills:\n - write-docs\n - swiftui\n");
312
+ loadOnlyTestSkills(base);
313
+
314
+ const researchPrompt = await buildResearchMilestonePrompt("M001", "Test", base);
315
+ assert.match(researchPrompt, /Call Skill\(\{ skill: 'write-docs' \}\)/);
316
+ assert.match(researchPrompt, /Call Skill\(\{ skill: 'swiftui' \}\)/);
317
+
318
+ const planPrompt = await buildPlanMilestonePrompt("M001", "Test", base);
319
+ assert.match(planPrompt, /Call Skill\(\{ skill: 'write-docs' \}\)/);
320
+ assert.match(planPrompt, /Call Skill\(\{ skill: 'swiftui' \}\)/);
321
+ } finally {
322
+ cleanup(base);
323
+ }
324
+ });
325
+
326
+ test("skill manifest strict warnings require GSD_SKILL_MANIFEST_STRICT=1", (t) => {
327
+ const previousStrict = process.env.GSD_SKILL_MANIFEST_STRICT;
328
+ const previousStderr = setStderrLoggingEnabled(false);
329
+ t.after(() => {
330
+ if (previousStrict === undefined) {
331
+ delete process.env.GSD_SKILL_MANIFEST_STRICT;
332
+ } else {
333
+ process.env.GSD_SKILL_MANIFEST_STRICT = previousStrict;
334
+ }
335
+ setStderrLoggingEnabled(previousStderr);
336
+ _resetLogs();
337
+ });
338
+
339
+ process.env.GSD_SKILL_MANIFEST_STRICT = "0";
340
+ _resetLogs();
341
+ warnIfManifestHasMissingSkills("research-milestone", new Set());
342
+ assert.equal(drainLogs().length, 0, "strict=0 must preserve silent behavior");
343
+
344
+ process.env.GSD_SKILL_MANIFEST_STRICT = "1";
345
+ _resetLogs();
346
+ warnIfManifestHasMissingSkills("research-milestone", new Set());
347
+ const logs = drainLogs();
348
+ assert.ok(
349
+ logs.some(log => log.message.includes("skill-manifest: references uninstalled skill")),
350
+ "strict=1 should warn about missing manifest entries",
351
+ );
352
+ });
@@ -0,0 +1,112 @@
1
+ // GSD2 + skill-manifest.test — unit coverage for the skill manifest resolver
2
+ //
3
+ // Focused tests for `resolveSkillManifest` and `filterSkillsByManifest`.
4
+ // Covers the wildcard semantics, the newly seeded unit-type entries
5
+ // (complete-milestone, validate-milestone, reassess-roadmap, research-slice,
6
+ // plan-slice, refine-slice, replan-slice, run-uat), and the deliberate
7
+ // wildcard fallback for the execute-task hot path (RFC #4779).
8
+
9
+ import test from "node:test";
10
+ import assert from "node:assert/strict";
11
+
12
+ import {
13
+ resolveSkillManifest,
14
+ filterSkillsByManifest,
15
+ } from "../skill-manifest.js";
16
+
17
+ const NEWLY_WIRED_UNIT_TYPES = [
18
+ "complete-milestone",
19
+ "validate-milestone",
20
+ "reassess-roadmap",
21
+ "research-slice",
22
+ "plan-slice",
23
+ "refine-slice",
24
+ "replan-slice",
25
+ "run-uat",
26
+ ] as const;
27
+
28
+ test("resolveSkillManifest returns null for undefined unit type (wildcard)", () => {
29
+ assert.equal(resolveSkillManifest(undefined), null);
30
+ });
31
+
32
+ test("resolveSkillManifest returns null for unknown unit types (wildcard fallback)", () => {
33
+ assert.equal(resolveSkillManifest("nonexistent-unit-type"), null);
34
+ });
35
+
36
+ test("resolveSkillManifest returns null for execute-task (intentional wildcard)", () => {
37
+ // execute-task is the implementation hot path; allowlisting it requires
38
+ // per-task skill hints from task-plan frontmatter. Documented in
39
+ // skill-manifest.ts — regression guard.
40
+ assert.equal(resolveSkillManifest("execute-task"), null);
41
+ });
42
+
43
+ for (const unitType of NEWLY_WIRED_UNIT_TYPES) {
44
+ test(`resolveSkillManifest returns a non-empty allowlist for '${unitType}'`, () => {
45
+ const allowlist = resolveSkillManifest(unitType);
46
+ assert.ok(allowlist !== null, `${unitType} should resolve to an allowlist, not wildcard`);
47
+ assert.ok(allowlist.length > 0, `${unitType} allowlist should not be empty`);
48
+ // Every entry must be lowercase (normalized).
49
+ for (const name of allowlist) {
50
+ assert.equal(name, name.toLowerCase(), `${unitType} entry '${name}' should be lowercase`);
51
+ }
52
+ });
53
+ }
54
+
55
+ test("resolveSkillManifest: slice-level manifests include decompose-into-slices", () => {
56
+ // Planning-shaped slice flows all benefit from the decomposition skill.
57
+ // Sanity-check a representative entry from each.
58
+ for (const unitType of ["research-slice", "plan-slice", "refine-slice", "replan-slice"] as const) {
59
+ const allowlist = resolveSkillManifest(unitType);
60
+ assert.ok(
61
+ allowlist?.includes("decompose-into-slices"),
62
+ `${unitType} should list decompose-into-slices`,
63
+ );
64
+ }
65
+ });
66
+
67
+ test("resolveSkillManifest: validation / completion flows include verify-before-complete", () => {
68
+ for (const unitType of ["complete-milestone", "validate-milestone", "run-uat"] as const) {
69
+ const allowlist = resolveSkillManifest(unitType);
70
+ assert.ok(
71
+ allowlist?.includes("verify-before-complete"),
72
+ `${unitType} should list verify-before-complete`,
73
+ );
74
+ }
75
+ });
76
+
77
+ test("filterSkillsByManifest: pass-through when unit type is unknown", () => {
78
+ const skills = [{ name: "swiftui" }, { name: "solidity-security" }];
79
+ const result = filterSkillsByManifest(skills, "nonexistent-unit-type");
80
+ assert.deepEqual(result, skills);
81
+ });
82
+
83
+ test("filterSkillsByManifest: pass-through when unitType is undefined", () => {
84
+ const skills = [{ name: "swiftui" }];
85
+ const result = filterSkillsByManifest(skills, undefined);
86
+ assert.deepEqual(result, skills);
87
+ });
88
+
89
+ test("filterSkillsByManifest: restricts to allowlisted names for known unit type", () => {
90
+ // research-slice allowlists include decompose-into-slices but not swiftui.
91
+ const skills = [
92
+ { name: "decompose-into-slices" },
93
+ { name: "swiftui" },
94
+ { name: "write-docs" },
95
+ ];
96
+ const result = filterSkillsByManifest(skills, "research-slice");
97
+ const names = result.map(s => s.name);
98
+ assert.ok(names.includes("decompose-into-slices"));
99
+ assert.ok(names.includes("write-docs"));
100
+ assert.ok(!names.includes("swiftui"));
101
+ });
102
+
103
+ test("filterSkillsByManifest: matching is case-insensitive via normalize", () => {
104
+ const skills = [
105
+ { name: "Write-Docs" }, // different case from manifest entry
106
+ { name: "SWIFTUI" },
107
+ ];
108
+ const result = filterSkillsByManifest(skills, "research-milestone");
109
+ const names = result.map(s => s.name);
110
+ assert.ok(names.includes("Write-Docs"));
111
+ assert.ok(!names.includes("SWIFTUI"));
112
+ });
@@ -0,0 +1,242 @@
1
+ /**
2
+ * Tests for slice-cadence collapse — #4765.
3
+ *
4
+ * Covers mergeSliceToMain (squash + advance), resquashMilestoneOnMain,
5
+ * and the preference accessors.
6
+ */
7
+
8
+ import { describe, test, beforeEach, afterEach } from "node:test";
9
+ import assert from "node:assert/strict";
10
+ import { mkdtempSync, mkdirSync, writeFileSync, rmSync, realpathSync, readFileSync, existsSync } from "node:fs";
11
+ import { join } from "node:path";
12
+ import { tmpdir } from "node:os";
13
+ import { execFileSync } from "node:child_process";
14
+
15
+ import {
16
+ mergeSliceToMain,
17
+ resquashMilestoneOnMain,
18
+ getCollapseCadence,
19
+ getMilestoneResquash,
20
+ } from "../slice-cadence.ts";
21
+ import { MergeConflictError } from "../git-service.ts";
22
+ import { summarizeWorktreeTelemetry } from "../worktree-telemetry.ts";
23
+
24
+ function git(args: string[], cwd: string): string {
25
+ return execFileSync("git", args, { cwd, stdio: ["ignore", "pipe", "pipe"], encoding: "utf-8" }).trim();
26
+ }
27
+
28
+ /** Create a temp git repo with an initial commit on main. */
29
+ function createRepo(): string {
30
+ const dir = realpathSync(mkdtempSync(join(tmpdir(), "slice-cad-test-")));
31
+ git(["init"], dir);
32
+ git(["config", "user.email", "test@test.com"], dir);
33
+ git(["config", "user.name", "Test"], dir);
34
+ writeFileSync(join(dir, "README.md"), "# test\n");
35
+ git(["add", "."], dir);
36
+ git(["commit", "-m", "init"], dir);
37
+ git(["branch", "-M", "main"], dir);
38
+ mkdirSync(join(dir, ".gsd"), { recursive: true });
39
+ return dir;
40
+ }
41
+
42
+ function enterMilestoneBranch(dir: string, milestoneId: string): void {
43
+ git(["checkout", "-b", `milestone/${milestoneId}`], dir);
44
+ }
45
+
46
+ function commitFile(dir: string, file: string, content: string, msg: string): string {
47
+ writeFileSync(join(dir, file), content);
48
+ git(["add", "."], dir);
49
+ git(["commit", "-m", msg], dir);
50
+ return git(["rev-parse", "HEAD"], dir);
51
+ }
52
+
53
+ describe("getCollapseCadence / getMilestoneResquash", () => {
54
+ test("defaults to milestone cadence", () => {
55
+ assert.equal(getCollapseCadence(undefined), "milestone");
56
+ assert.equal(getCollapseCadence(null), "milestone");
57
+ assert.equal(getCollapseCadence({}), "milestone");
58
+ assert.equal(getCollapseCadence({ git: {} }), "milestone");
59
+ });
60
+ test("reads slice cadence when set", () => {
61
+ assert.equal(getCollapseCadence({ git: { collapse_cadence: "slice" } }), "slice");
62
+ });
63
+ test("milestone_resquash defaults to true when not set", () => {
64
+ assert.equal(getMilestoneResquash(undefined), true);
65
+ assert.equal(getMilestoneResquash({ git: {} }), true);
66
+ assert.equal(getMilestoneResquash({ git: { milestone_resquash: true } }), true);
67
+ });
68
+ test("milestone_resquash can be disabled explicitly", () => {
69
+ assert.equal(getMilestoneResquash({ git: { milestone_resquash: false } }), false);
70
+ });
71
+ });
72
+
73
+ describe("mergeSliceToMain", () => {
74
+ let dir: string;
75
+ let originalCwd: string;
76
+
77
+ beforeEach(() => {
78
+ dir = createRepo();
79
+ originalCwd = process.cwd();
80
+ });
81
+
82
+ afterEach(() => {
83
+ try { process.chdir(originalCwd); } catch { /* */ }
84
+ rmSync(dir, { recursive: true, force: true });
85
+ });
86
+
87
+ test("squashes one slice's commits onto main and advances the milestone branch", () => {
88
+ enterMilestoneBranch(dir, "M001");
89
+ commitFile(dir, "feature.txt", "slice 1 work\n", "feat: S01 work");
90
+
91
+ process.chdir(dir);
92
+ const result = mergeSliceToMain(dir, "M001", "S01");
93
+
94
+ assert.equal(result.skipped, false);
95
+ assert.ok(result.commitSha, "expected a commit SHA");
96
+ assert.equal(result.milestoneBranch, "milestone/M001");
97
+ assert.equal(result.mainBranch, "main");
98
+
99
+ const mainLog = git(["log", "main", "--oneline"], dir);
100
+ assert.ok(mainLog.includes("S01 of M001 (slice-cadence)"), `main log: ${mainLog}`);
101
+ assert.equal(readFileSync(join(dir, "feature.txt"), "utf-8"), "slice 1 work\n");
102
+
103
+ const mainSha = git(["rev-parse", "main"], dir);
104
+ const milestoneSha = git(["rev-parse", "milestone/M001"], dir);
105
+ assert.equal(milestoneSha, mainSha, "milestone branch must be advanced to main");
106
+
107
+ const summary = summarizeWorktreeTelemetry(dir);
108
+ assert.equal(summary.slicesMerged, 1);
109
+ assert.equal(summary.sliceMergeConflicts, 0);
110
+ });
111
+
112
+ test("handles sequential slice merges cleanly", () => {
113
+ enterMilestoneBranch(dir, "M001");
114
+ commitFile(dir, "a.txt", "slice 1\n", "feat: S01");
115
+
116
+ process.chdir(dir);
117
+ mergeSliceToMain(dir, "M001", "S01");
118
+
119
+ git(["checkout", "milestone/M001"], dir);
120
+ commitFile(dir, "b.txt", "slice 2\n", "feat: S02");
121
+
122
+ const result = mergeSliceToMain(dir, "M001", "S02");
123
+ assert.equal(result.skipped, false);
124
+
125
+ const mainLog = git(["log", "main", "--oneline"], dir);
126
+ assert.ok(mainLog.includes("S01 of M001"));
127
+ assert.ok(mainLog.includes("S02 of M001"));
128
+
129
+ assert.equal(readFileSync(join(dir, "a.txt"), "utf-8"), "slice 1\n");
130
+ assert.equal(readFileSync(join(dir, "b.txt"), "utf-8"), "slice 2\n");
131
+
132
+ const summary = summarizeWorktreeTelemetry(dir);
133
+ assert.equal(summary.slicesMerged, 2);
134
+ });
135
+
136
+ test("returns skipped when milestone branch has no commits ahead of main", () => {
137
+ enterMilestoneBranch(dir, "M001");
138
+
139
+ process.chdir(dir);
140
+ const result = mergeSliceToMain(dir, "M001", "S01");
141
+
142
+ assert.equal(result.skipped, true);
143
+ assert.equal(result.skippedReason, "no-commits-ahead");
144
+ assert.equal(result.commitSha, null);
145
+ });
146
+
147
+ test("throws MergeConflictError on a real conflict and leaves no merge artifacts", () => {
148
+ writeFileSync(join(dir, "shared.txt"), "main version\n");
149
+ git(["add", "."], dir);
150
+ git(["commit", "-m", "main-seed"], dir);
151
+
152
+ enterMilestoneBranch(dir, "M001");
153
+ commitFile(dir, "shared.txt", "slice version\n", "feat: S01 conflicting");
154
+
155
+ git(["checkout", "main"], dir);
156
+ commitFile(dir, "shared.txt", "main evolved\n", "main evolved");
157
+ git(["checkout", "milestone/M001"], dir);
158
+
159
+ process.chdir(dir);
160
+ assert.throws(
161
+ () => mergeSliceToMain(dir, "M001", "S01"),
162
+ (err: unknown) => err instanceof MergeConflictError,
163
+ );
164
+
165
+ const gitDir = join(dir, ".git");
166
+ for (const f of ["SQUASH_MSG", "MERGE_MSG", "MERGE_HEAD"]) {
167
+ assert.ok(!existsSync(join(gitDir, f)), `${f} should be cleaned up`);
168
+ }
169
+
170
+ const summary = summarizeWorktreeTelemetry(dir);
171
+ assert.equal(summary.sliceMergeConflicts, 1);
172
+ });
173
+
174
+ test("restores cwd even when merge fails (dirty working tree)", () => {
175
+ enterMilestoneBranch(dir, "M001");
176
+ commitFile(dir, "feature.txt", "slice 1\n", "feat: S01");
177
+ // Introduce an untracked file AFTER the slice commit so it's still
178
+ // present when mergeSliceToMain runs its status check.
179
+ writeFileSync(join(dir, "dirty.txt"), "uncommitted\n");
180
+
181
+ process.chdir(dir);
182
+ const cwdBefore = process.cwd();
183
+ assert.throws(() => mergeSliceToMain(dir, "M001", "S01"));
184
+ assert.equal(process.cwd(), cwdBefore, "cwd must be restored on failure");
185
+ });
186
+ });
187
+
188
+ describe("resquashMilestoneOnMain", () => {
189
+ let dir: string;
190
+ let originalCwd: string;
191
+
192
+ beforeEach(() => {
193
+ dir = createRepo();
194
+ originalCwd = process.cwd();
195
+ });
196
+
197
+ afterEach(() => {
198
+ try { process.chdir(originalCwd); } catch { /* */ }
199
+ rmSync(dir, { recursive: true, force: true });
200
+ });
201
+
202
+ test("collapses N slice commits on main into one milestone commit", () => {
203
+ const startSha = git(["rev-parse", "main"], dir);
204
+
205
+ enterMilestoneBranch(dir, "M001");
206
+ commitFile(dir, "a.txt", "slice 1\n", "feat: S01");
207
+ process.chdir(dir);
208
+ mergeSliceToMain(dir, "M001", "S01");
209
+
210
+ git(["checkout", "milestone/M001"], dir);
211
+ commitFile(dir, "b.txt", "slice 2\n", "feat: S02");
212
+ mergeSliceToMain(dir, "M001", "S02");
213
+
214
+ const beforeCount = parseInt(git(["rev-list", "--count", `${startSha}..main`], dir), 10);
215
+ assert.equal(beforeCount, 2);
216
+
217
+ const result = resquashMilestoneOnMain(dir, "M001", startSha);
218
+ assert.equal(result.resquashed, true);
219
+ assert.ok(result.newSha);
220
+
221
+ git(["checkout", "main"], dir);
222
+ const afterCount = parseInt(git(["rev-list", "--count", `${startSha}..main`], dir), 10);
223
+ assert.equal(afterCount, 1, "slice commits collapsed into one milestone commit");
224
+
225
+ const msg = git(["log", "-1", "--format=%s", "main"], dir);
226
+ assert.ok(msg.includes("M001") && msg.includes("2 slices"), `commit message should describe the resquash; got: ${msg}`);
227
+
228
+ assert.equal(readFileSync(join(dir, "a.txt"), "utf-8"), "slice 1\n");
229
+ assert.equal(readFileSync(join(dir, "b.txt"), "utf-8"), "slice 2\n");
230
+
231
+ const summary = summarizeWorktreeTelemetry(dir);
232
+ assert.equal(summary.milestoneResquashes, 1);
233
+ });
234
+
235
+ test("no-op when startSha equals HEAD", () => {
236
+ const startSha = git(["rev-parse", "main"], dir);
237
+ process.chdir(dir);
238
+ const result = resquashMilestoneOnMain(dir, "M001", startSha);
239
+ assert.equal(result.resquashed, false);
240
+ assert.equal(result.newSha, null);
241
+ });
242
+ });
@@ -11,6 +11,7 @@ import assert from "node:assert/strict";
11
11
  import { readFileSync } from "node:fs";
12
12
  import { join, dirname } from "node:path";
13
13
  import { fileURLToPath } from "node:url";
14
+ import { extractSourceRegion } from "./test-helpers.ts";
14
15
 
15
16
  const __dirname = dirname(fileURLToPath(import.meta.url));
16
17
  const autoPromptsPath = join(__dirname, "..", "auto-prompts.ts");
@@ -32,7 +33,7 @@ describe("slice CONTEXT.md injection into prompt builders (#3452)", () => {
32
33
  assert.ok(fnStart !== -1, `${builder} should exist in auto-prompts.ts`);
33
34
 
34
35
  // Get a reasonable chunk after the function start
35
- const chunk = source.slice(fnStart, fnStart + 3000);
36
+ const chunk = extractSourceRegion(source, `export async function ${builder}`);
36
37
 
37
38
  // ADR-011: buildPlanSlicePrompt / buildRefineSlicePrompt now delegate to
38
39
  // a shared helper (renderSlicePrompt) that performs the slice CONTEXT
@@ -42,7 +43,7 @@ describe("slice CONTEXT.md injection into prompt builders (#3452)", () => {
42
43
  ? (() => {
43
44
  const helperStart = source.indexOf("async function renderSlicePrompt");
44
45
  assert.ok(helperStart !== -1, "renderSlicePrompt helper must exist");
45
- return source.slice(helperStart, helperStart + 3000);
46
+ return extractSourceRegion(source, "async function renderSlicePrompt");
46
47
  })()
47
48
  : chunk;
48
49