gsd-pi 2.77.0-dev.c9c8932c6 → 2.77.0-dev.cfd69e714

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (708) hide show
  1. package/README.md +1 -1
  2. package/dist/claude-cli-check.js +5 -1
  3. package/dist/cli-web-branch.d.ts +1 -0
  4. package/dist/cli-web-branch.js +3 -0
  5. package/dist/cli.js +24 -2
  6. package/dist/headless.js +49 -4
  7. package/dist/provider-migrations.d.ts +18 -0
  8. package/dist/provider-migrations.js +14 -0
  9. package/dist/resource-loader.d.ts +40 -0
  10. package/dist/resource-loader.js +32 -13
  11. package/dist/resources/extensions/browser-tools/capture.js +9 -0
  12. package/dist/resources/extensions/browser-tools/tests/browser-tools-integration.test.mjs +8 -59
  13. package/dist/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +36 -24
  14. package/dist/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +69 -71
  15. package/dist/resources/extensions/browser-tools/tools/forms.js +5 -1
  16. package/dist/resources/extensions/browser-tools/tools/intent.js +5 -1
  17. package/dist/resources/extensions/claude-code-cli/readiness.js +5 -1
  18. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +495 -27
  19. package/dist/resources/extensions/github-sync/templates.js +103 -0
  20. package/dist/resources/extensions/google-search/index.js +3 -2
  21. package/dist/resources/extensions/gsd/abandon-detect.js +44 -0
  22. package/dist/resources/extensions/gsd/auto/loop.js +124 -2
  23. package/dist/resources/extensions/gsd/auto/phases.js +57 -39
  24. package/dist/resources/extensions/gsd/auto/resolve.js +24 -0
  25. package/dist/resources/extensions/gsd/auto/run-unit.js +10 -2
  26. package/dist/resources/extensions/gsd/auto/session.js +6 -2
  27. package/dist/resources/extensions/gsd/auto/turn-epoch.js +95 -0
  28. package/dist/resources/extensions/gsd/auto-dispatch.js +166 -29
  29. package/dist/resources/extensions/gsd/auto-loop.js +1 -1
  30. package/dist/resources/extensions/gsd/auto-model-selection.js +124 -4
  31. package/dist/resources/extensions/gsd/auto-post-unit.js +181 -64
  32. package/dist/resources/extensions/gsd/auto-prompts.js +372 -104
  33. package/dist/resources/extensions/gsd/auto-recovery.js +197 -48
  34. package/dist/resources/extensions/gsd/auto-start.js +107 -29
  35. package/dist/resources/extensions/gsd/auto-timeout-recovery.js +11 -5
  36. package/dist/resources/extensions/gsd/auto-tool-tracking.js +47 -7
  37. package/dist/resources/extensions/gsd/auto-unit-closeout.js +11 -2
  38. package/dist/resources/extensions/gsd/auto-worktree.js +180 -34
  39. package/dist/resources/extensions/gsd/auto.js +80 -21
  40. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +19 -1
  41. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +209 -0
  42. package/dist/resources/extensions/gsd/bootstrap/provider-error-resume.js +5 -6
  43. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +7 -3
  44. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +127 -9
  45. package/dist/resources/extensions/gsd/commands/handlers/workflow.js +31 -4
  46. package/dist/resources/extensions/gsd/component-loader.js +447 -0
  47. package/dist/resources/extensions/gsd/component-types.js +69 -0
  48. package/dist/resources/extensions/gsd/context-store.js +23 -7
  49. package/dist/resources/extensions/gsd/detection.js +49 -1
  50. package/dist/resources/extensions/gsd/dispatch-guard.js +2 -17
  51. package/dist/resources/extensions/gsd/docs/preferences-reference.md +1 -1
  52. package/dist/resources/extensions/gsd/file-lock.js +49 -9
  53. package/dist/resources/extensions/gsd/forensics.js +106 -0
  54. package/dist/resources/extensions/gsd/gate-registry.js +2 -2
  55. package/dist/resources/extensions/gsd/git-constants.js +28 -1
  56. package/dist/resources/extensions/gsd/git-self-heal.js +27 -0
  57. package/dist/resources/extensions/gsd/git-service.js +127 -2
  58. package/dist/resources/extensions/gsd/gitignore.js +1 -0
  59. package/dist/resources/extensions/gsd/gsd-db.js +6 -3
  60. package/dist/resources/extensions/gsd/guided-flow-queue.js +4 -1
  61. package/dist/resources/extensions/gsd/guided-flow.js +39 -13
  62. package/dist/resources/extensions/gsd/journal.js +17 -2
  63. package/dist/resources/extensions/gsd/memory-extractor.js +7 -1
  64. package/dist/resources/extensions/gsd/milestone-actions.js +15 -0
  65. package/dist/resources/extensions/gsd/milestone-scope-classifier.js +299 -0
  66. package/dist/resources/extensions/gsd/milestone-summary-classifier.js +37 -0
  67. package/dist/resources/extensions/gsd/model-cost-table.js +3 -0
  68. package/dist/resources/extensions/gsd/model-router.js +6 -0
  69. package/dist/resources/extensions/gsd/native-git-bridge.js +34 -4
  70. package/dist/resources/extensions/gsd/preferences-validation.js +23 -0
  71. package/dist/resources/extensions/gsd/prompt-cache-optimizer.js +4 -0
  72. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +6 -2
  73. package/dist/resources/extensions/gsd/prompts/discuss-headless.md +23 -4
  74. package/dist/resources/extensions/gsd/prompts/doctor-heal.md +5 -4
  75. package/dist/resources/extensions/gsd/prompts/plan-slice.md +15 -2
  76. package/dist/resources/extensions/gsd/reports.js +5 -4
  77. package/dist/resources/extensions/gsd/safety/git-checkpoint.js +11 -0
  78. package/dist/resources/extensions/gsd/service-tier.js +5 -2
  79. package/dist/resources/extensions/gsd/session-lock.js +19 -10
  80. package/dist/resources/extensions/gsd/skill-manifest.js +168 -0
  81. package/dist/resources/extensions/gsd/slice-cadence.js +238 -0
  82. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +278 -8
  83. package/dist/resources/extensions/gsd/state-transition-matrix.js +118 -0
  84. package/dist/resources/extensions/gsd/state.js +69 -58
  85. package/dist/resources/extensions/gsd/sync-lock.js +98 -42
  86. package/dist/resources/extensions/gsd/tools/complete-slice.js +21 -0
  87. package/dist/resources/extensions/gsd/tools/complete-task.js +31 -0
  88. package/dist/resources/extensions/gsd/tools/validate-milestone.js +7 -2
  89. package/dist/resources/extensions/gsd/unit-context-composer.js +147 -0
  90. package/dist/resources/extensions/gsd/unit-context-manifest.js +370 -0
  91. package/dist/resources/extensions/gsd/uok/audit.js +18 -2
  92. package/dist/resources/extensions/gsd/uok/dispatch-envelope.js +33 -0
  93. package/dist/resources/extensions/gsd/uok/execution-graph.js +10 -0
  94. package/dist/resources/extensions/gsd/uok/gate-runner.js +53 -5
  95. package/dist/resources/extensions/gsd/uok/gitops.js +2 -1
  96. package/dist/resources/extensions/gsd/uok/loop-adapter.js +37 -10
  97. package/dist/resources/extensions/gsd/uok/parity-report.js +58 -0
  98. package/dist/resources/extensions/gsd/uok/plan-v2.js +10 -4
  99. package/dist/resources/extensions/gsd/uok/writer.js +82 -0
  100. package/dist/resources/extensions/gsd/workflow-logger.js +10 -2
  101. package/dist/resources/extensions/gsd/workflow-mcp.js +6 -0
  102. package/dist/resources/extensions/gsd/worktree-manager.js +86 -8
  103. package/dist/resources/extensions/gsd/worktree-resolver.js +86 -7
  104. package/dist/resources/extensions/gsd/worktree-telemetry.js +198 -0
  105. package/dist/resources/extensions/mcp-client/auth.js +10 -1
  106. package/dist/resources/extensions/mcp-client/index.js +121 -10
  107. package/dist/resources/extensions/ollama/index.js +5 -1
  108. package/dist/resources/extensions/remote-questions/manager.js +11 -5
  109. package/dist/resources/skills/create-skill/SKILL.md +2 -2
  110. package/dist/resources/skills/create-skill/references/gsd-skill-ecosystem.md +4 -4
  111. package/dist/resources/skills/create-skill/workflows/audit-skill.md +4 -4
  112. package/dist/resources/skills/create-skill/workflows/create-new-skill.md +5 -5
  113. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  114. package/dist/web/standalone/.next/BUILD_ID +1 -1
  115. package/dist/web/standalone/.next/app-path-routes-manifest.json +12 -12
  116. package/dist/web/standalone/.next/build-manifest.json +3 -3
  117. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  118. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  119. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  120. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  121. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  122. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  123. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  124. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  125. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  126. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  127. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  128. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  129. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  130. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  131. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  132. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  133. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  134. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  135. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  136. package/dist/web/standalone/.next/server/app/api/boot/route.js.nft.json +1 -1
  137. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  138. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
  139. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
  141. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
  143. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
  145. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
  147. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
  149. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
  151. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
  153. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
  155. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
  157. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
  159. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
  161. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
  163. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
  165. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
  167. package/dist/web/standalone/.next/server/app/api/notifications/route.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
  169. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
  171. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
  173. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
  175. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
  177. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
  179. package/dist/web/standalone/.next/server/app/api/session/events/route.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
  181. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
  183. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  184. package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
  185. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  186. package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
  187. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  188. package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
  189. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  190. package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
  191. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +1 -1
  192. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
  193. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +1 -1
  194. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
  195. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  196. package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
  197. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  198. package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +1 -1
  199. package/dist/web/standalone/.next/server/app/index.html +1 -1
  200. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  201. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  202. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  203. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  204. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  205. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  206. package/dist/web/standalone/.next/server/app-paths-manifest.json +12 -12
  207. package/dist/web/standalone/.next/server/chunks/1926.js +1 -0
  208. package/dist/web/standalone/.next/server/chunks/6897.js +2 -2
  209. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  210. package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
  211. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  212. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  213. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  214. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  215. package/dist/web/standalone/.next/static/chunks/2826.e9f5195e91f9cad2.js +11 -0
  216. package/dist/web/standalone/.next/static/chunks/{webpack-1832629448831fdc.js → webpack-2e68521d7c82f7c2.js} +1 -1
  217. package/package.json +4 -5
  218. package/packages/daemon/src/logger.ts +4 -3
  219. package/packages/mcp-server/README.md +3 -3
  220. package/packages/mcp-server/dist/env-writer.d.ts +1 -0
  221. package/packages/mcp-server/dist/env-writer.d.ts.map +1 -1
  222. package/packages/mcp-server/dist/env-writer.js +74 -6
  223. package/packages/mcp-server/dist/env-writer.js.map +1 -1
  224. package/packages/mcp-server/dist/server.d.ts +24 -0
  225. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  226. package/packages/mcp-server/dist/server.js +111 -87
  227. package/packages/mcp-server/dist/server.js.map +1 -1
  228. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  229. package/packages/mcp-server/dist/workflow-tools.js +15 -6
  230. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  231. package/packages/mcp-server/src/env-writer.test.ts +79 -1
  232. package/packages/mcp-server/src/env-writer.ts +76 -6
  233. package/packages/mcp-server/src/mcp-server.test.ts +25 -3
  234. package/packages/mcp-server/src/readers/graph.test.ts +87 -15
  235. package/packages/mcp-server/src/secure-env-collect.test.ts +232 -237
  236. package/packages/mcp-server/src/server.ts +158 -105
  237. package/packages/mcp-server/src/workflow-tools.test.ts +85 -0
  238. package/packages/mcp-server/src/workflow-tools.ts +19 -6
  239. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  240. package/packages/native/package.json +1 -1
  241. package/packages/native/src/__tests__/_test-coverage-guard.test.mjs +98 -0
  242. package/packages/native/src/__tests__/module-compat.test.mjs +59 -27
  243. package/packages/native/src/__tests__/ps.test.mjs +14 -8
  244. package/packages/native/src/__tests__/stream-process.test.mjs +23 -2
  245. package/packages/native/src/__tests__/truncate.test.mjs +17 -2
  246. package/packages/pi-agent-core/src/agent-loop.test.ts +5 -15
  247. package/packages/pi-agent-core/src/agent.test.ts +96 -102
  248. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  249. package/packages/pi-ai/dist/models/capability-patches.d.ts.map +1 -1
  250. package/packages/pi-ai/dist/models/capability-patches.js +9 -2
  251. package/packages/pi-ai/dist/models/capability-patches.js.map +1 -1
  252. package/packages/pi-ai/dist/models/generated/index.d.ts +34 -0
  253. package/packages/pi-ai/dist/models/generated/index.d.ts.map +1 -1
  254. package/packages/pi-ai/dist/models/generated/openai-codex.d.ts +17 -0
  255. package/packages/pi-ai/dist/models/generated/openai-codex.d.ts.map +1 -1
  256. package/packages/pi-ai/dist/models/generated/openai-codex.js +17 -0
  257. package/packages/pi-ai/dist/models/generated/openai-codex.js.map +1 -1
  258. package/packages/pi-ai/dist/models/generated/openai.d.ts +17 -0
  259. package/packages/pi-ai/dist/models/generated/openai.d.ts.map +1 -1
  260. package/packages/pi-ai/dist/models/generated/openai.js +17 -0
  261. package/packages/pi-ai/dist/models/generated/openai.js.map +1 -1
  262. package/packages/pi-ai/dist/models.generated.test.js +43 -70
  263. package/packages/pi-ai/dist/models.generated.test.js.map +1 -1
  264. package/packages/pi-ai/dist/models.test.js +36 -11
  265. package/packages/pi-ai/dist/models.test.js.map +1 -1
  266. package/packages/pi-ai/scripts/generate-models.ts +44 -0
  267. package/packages/pi-ai/src/models/capability-patches.ts +10 -2
  268. package/packages/pi-ai/src/models/generated/openai-codex.ts +17 -0
  269. package/packages/pi-ai/src/models/generated/openai.ts +17 -0
  270. package/packages/pi-ai/src/models.generated.test.ts +46 -73
  271. package/packages/pi-ai/src/models.test.ts +48 -11
  272. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  273. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +96 -32
  274. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js.map +1 -1
  275. package/packages/pi-coding-agent/dist/core/agent-session-model-switch.test.js +75 -12
  276. package/packages/pi-coding-agent/dist/core/agent-session-model-switch.test.js.map +1 -1
  277. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js +99 -31
  278. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js.map +1 -1
  279. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.d.ts +1 -0
  280. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.d.ts.map +1 -1
  281. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js +21 -16
  282. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js.map +1 -1
  283. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.test.d.ts +2 -0
  284. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.test.d.ts.map +1 -0
  285. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.test.js +130 -0
  286. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.test.js.map +1 -0
  287. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts +5 -0
  288. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  289. package/packages/pi-coding-agent/dist/core/extensions/loader.js +61 -0
  290. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  291. package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.js +30 -4
  292. package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.js.map +1 -1
  293. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +17 -0
  294. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -1
  295. package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.js +76 -18
  296. package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.js.map +1 -1
  297. package/packages/pi-coding-agent/dist/core/retry-handler.d.ts.map +1 -1
  298. package/packages/pi-coding-agent/dist/core/retry-handler.js +2 -6
  299. package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -1
  300. package/packages/pi-coding-agent/dist/core/retry-handler.test.js +5 -1
  301. package/packages/pi-coding-agent/dist/core/retry-handler.test.js.map +1 -1
  302. package/packages/pi-coding-agent/dist/core/retryable-error-regex.d.ts +18 -0
  303. package/packages/pi-coding-agent/dist/core/retryable-error-regex.d.ts.map +1 -0
  304. package/packages/pi-coding-agent/dist/core/retryable-error-regex.js +18 -0
  305. package/packages/pi-coding-agent/dist/core/retryable-error-regex.js.map +1 -0
  306. package/packages/pi-coding-agent/dist/core/sdk.d.ts +1 -0
  307. package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
  308. package/packages/pi-coding-agent/dist/core/sdk.js +4 -1
  309. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  310. package/packages/pi-coding-agent/dist/core/sdk.test.js +19 -1
  311. package/packages/pi-coding-agent/dist/core/sdk.test.js.map +1 -1
  312. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts +20 -0
  313. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
  314. package/packages/pi-coding-agent/dist/core/system-prompt.js +16 -2
  315. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  316. package/packages/pi-coding-agent/dist/index.d.ts +1 -0
  317. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  318. package/packages/pi-coding-agent/dist/index.js +1 -0
  319. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  320. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/provider-display-name.test.js +15 -6
  321. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/provider-display-name.test.js.map +1 -1
  322. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +36 -5
  323. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
  324. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.js +20 -13
  325. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.js.map +1 -1
  326. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
  327. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +14 -5
  328. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  329. package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.d.ts +7 -1
  330. package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  331. package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.js +31 -9
  332. package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.js.map +1 -1
  333. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  334. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +30 -12
  335. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  336. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
  337. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +18 -3
  338. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  339. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +125 -0
  340. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
  341. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts +2 -0
  342. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -1
  343. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.js.map +1 -1
  344. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +4 -0
  345. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  346. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +105 -13
  347. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  348. package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.d.ts +2 -0
  349. package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.d.ts.map +1 -0
  350. package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.js +130 -0
  351. package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.js.map +1 -0
  352. package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +113 -37
  353. package/packages/pi-coding-agent/src/core/agent-session-model-switch.test.ts +89 -17
  354. package/packages/pi-coding-agent/src/core/agent-session-tool-refresh.test.ts +112 -43
  355. package/packages/pi-coding-agent/src/core/compaction-orchestrator.test.ts +154 -0
  356. package/packages/pi-coding-agent/src/core/compaction-orchestrator.ts +24 -17
  357. package/packages/pi-coding-agent/src/core/extensions/loader.ts +58 -0
  358. package/packages/pi-coding-agent/src/core/lsp/lsp-integration.test.ts +35 -4
  359. package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +20 -0
  360. package/packages/pi-coding-agent/src/core/resource-loader-cache-reset.test.ts +93 -28
  361. package/packages/pi-coding-agent/src/core/retry-handler.test.ts +5 -1
  362. package/packages/pi-coding-agent/src/core/retry-handler.ts +2 -8
  363. package/packages/pi-coding-agent/src/core/retryable-error-regex.ts +18 -0
  364. package/packages/pi-coding-agent/src/core/sdk.test.ts +25 -1
  365. package/packages/pi-coding-agent/src/core/sdk.ts +10 -3
  366. package/packages/pi-coding-agent/src/core/system-prompt.ts +35 -1
  367. package/packages/pi-coding-agent/src/index.ts +1 -0
  368. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/provider-display-name.test.ts +17 -7
  369. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +49 -3
  370. package/packages/pi-coding-agent/src/modes/interactive/components/dynamic-border.test.ts +26 -20
  371. package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +14 -5
  372. package/packages/pi-coding-agent/src/modes/interactive/components/model-selector.ts +45 -11
  373. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +48 -9
  374. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +146 -1
  375. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +20 -3
  376. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-state.ts +2 -0
  377. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +119 -13
  378. package/packages/pi-coding-agent/src/tests/system-prompt-skill-filter.test.ts +157 -0
  379. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  380. package/packages/pi-tui/dist/__tests__/autocomplete.test.js +18 -8
  381. package/packages/pi-tui/dist/__tests__/autocomplete.test.js.map +1 -1
  382. package/packages/pi-tui/dist/__tests__/overlay-layout.test.js +128 -17
  383. package/packages/pi-tui/dist/__tests__/overlay-layout.test.js.map +1 -1
  384. package/packages/pi-tui/dist/__tests__/stdin-buffer.test.js +51 -6
  385. package/packages/pi-tui/dist/__tests__/stdin-buffer.test.js.map +1 -1
  386. package/packages/pi-tui/dist/__tests__/tui.test.js +18 -30
  387. package/packages/pi-tui/dist/__tests__/tui.test.js.map +1 -1
  388. package/packages/pi-tui/dist/components/__tests__/input.test.js +10 -3
  389. package/packages/pi-tui/dist/components/__tests__/input.test.js.map +1 -1
  390. package/packages/pi-tui/dist/components/__tests__/loader.test.js +53 -9
  391. package/packages/pi-tui/dist/components/__tests__/loader.test.js.map +1 -1
  392. package/packages/pi-tui/dist/components/__tests__/markdown-maxlines.test.js +6 -2
  393. package/packages/pi-tui/dist/components/__tests__/markdown-maxlines.test.js.map +1 -1
  394. package/packages/pi-tui/dist/components/editor.d.ts +14 -0
  395. package/packages/pi-tui/dist/components/editor.d.ts.map +1 -1
  396. package/packages/pi-tui/dist/components/editor.js +19 -0
  397. package/packages/pi-tui/dist/components/editor.js.map +1 -1
  398. package/packages/pi-tui/dist/components/image.test.js +6 -5
  399. package/packages/pi-tui/dist/components/image.test.js.map +1 -1
  400. package/packages/pi-tui/dist/editor-component.d.ts +2 -0
  401. package/packages/pi-tui/dist/editor-component.d.ts.map +1 -1
  402. package/packages/pi-tui/dist/editor-component.js.map +1 -1
  403. package/packages/pi-tui/dist/stdin-buffer.d.ts +7 -0
  404. package/packages/pi-tui/dist/stdin-buffer.d.ts.map +1 -1
  405. package/packages/pi-tui/dist/stdin-buffer.js +20 -0
  406. package/packages/pi-tui/dist/stdin-buffer.js.map +1 -1
  407. package/packages/pi-tui/src/__tests__/autocomplete.test.ts +24 -8
  408. package/packages/pi-tui/src/__tests__/overlay-layout.test.ts +140 -17
  409. package/packages/pi-tui/src/__tests__/stdin-buffer.test.ts +62 -6
  410. package/packages/pi-tui/src/__tests__/tui.test.ts +18 -37
  411. package/packages/pi-tui/src/components/__tests__/input.test.ts +19 -3
  412. package/packages/pi-tui/src/components/__tests__/loader.test.ts +112 -35
  413. package/packages/pi-tui/src/components/__tests__/markdown-maxlines.test.ts +9 -2
  414. package/packages/pi-tui/src/components/editor.ts +22 -0
  415. package/packages/pi-tui/src/components/image.test.ts +10 -5
  416. package/packages/pi-tui/src/editor-component.ts +3 -0
  417. package/packages/pi-tui/src/stdin-buffer.ts +26 -0
  418. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  419. package/packages/rpc-client/dist/rpc-client.test.js +101 -51
  420. package/packages/rpc-client/dist/rpc-client.test.js.map +1 -1
  421. package/packages/rpc-client/src/rpc-client.test.ts +109 -52
  422. package/packages/rpc-client/tsconfig.tsbuildinfo +1 -1
  423. package/scripts/install.js +15 -1
  424. package/src/resources/extensions/browser-tools/capture.ts +12 -0
  425. package/src/resources/extensions/browser-tools/tests/browser-tools-integration.test.mjs +8 -59
  426. package/src/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +36 -24
  427. package/src/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +69 -71
  428. package/src/resources/extensions/browser-tools/tools/forms.ts +5 -1
  429. package/src/resources/extensions/browser-tools/tools/intent.ts +5 -1
  430. package/src/resources/extensions/claude-code-cli/readiness.ts +5 -1
  431. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +532 -29
  432. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +941 -91
  433. package/src/resources/extensions/github-sync/templates.ts +151 -0
  434. package/src/resources/extensions/github-sync/tests/cli.test.ts +76 -7
  435. package/src/resources/extensions/github-sync/tests/templates.test.ts +92 -1
  436. package/src/resources/extensions/google-search/index.ts +3 -2
  437. package/src/resources/extensions/gsd/abandon-detect.ts +62 -0
  438. package/src/resources/extensions/gsd/auto/loop.ts +142 -2
  439. package/src/resources/extensions/gsd/auto/phases.ts +62 -38
  440. package/src/resources/extensions/gsd/auto/resolve.ts +29 -0
  441. package/src/resources/extensions/gsd/auto/run-unit.ts +16 -2
  442. package/src/resources/extensions/gsd/auto/session.ts +7 -2
  443. package/src/resources/extensions/gsd/auto/turn-epoch.ts +108 -0
  444. package/src/resources/extensions/gsd/auto-dispatch.ts +176 -29
  445. package/src/resources/extensions/gsd/auto-loop.ts +1 -1
  446. package/src/resources/extensions/gsd/auto-model-selection.ts +131 -4
  447. package/src/resources/extensions/gsd/auto-post-unit.ts +193 -73
  448. package/src/resources/extensions/gsd/auto-prompts.ts +385 -93
  449. package/src/resources/extensions/gsd/auto-recovery.ts +230 -51
  450. package/src/resources/extensions/gsd/auto-start.ts +127 -9
  451. package/src/resources/extensions/gsd/auto-timeout-recovery.ts +12 -5
  452. package/src/resources/extensions/gsd/auto-tool-tracking.ts +51 -7
  453. package/src/resources/extensions/gsd/auto-unit-closeout.ts +14 -3
  454. package/src/resources/extensions/gsd/auto-worktree.ts +190 -31
  455. package/src/resources/extensions/gsd/auto.ts +95 -23
  456. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +20 -1
  457. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +221 -0
  458. package/src/resources/extensions/gsd/bootstrap/provider-error-resume.ts +6 -6
  459. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +7 -3
  460. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +158 -9
  461. package/src/resources/extensions/gsd/commands/handlers/workflow.ts +27 -8
  462. package/src/resources/extensions/gsd/component-loader.ts +598 -0
  463. package/src/resources/extensions/gsd/component-types.ts +362 -0
  464. package/src/resources/extensions/gsd/context-store.ts +25 -8
  465. package/src/resources/extensions/gsd/detection.ts +58 -1
  466. package/src/resources/extensions/gsd/dispatch-guard.ts +2 -20
  467. package/src/resources/extensions/gsd/docs/preferences-reference.md +1 -1
  468. package/src/resources/extensions/gsd/file-lock.ts +84 -11
  469. package/src/resources/extensions/gsd/forensics.ts +118 -1
  470. package/src/resources/extensions/gsd/gate-registry.ts +2 -2
  471. package/src/resources/extensions/gsd/git-constants.ts +30 -1
  472. package/src/resources/extensions/gsd/git-self-heal.ts +31 -0
  473. package/src/resources/extensions/gsd/git-service.ts +150 -2
  474. package/src/resources/extensions/gsd/gitignore.ts +1 -0
  475. package/src/resources/extensions/gsd/gsd-db.ts +6 -3
  476. package/src/resources/extensions/gsd/guided-flow-queue.ts +4 -1
  477. package/src/resources/extensions/gsd/guided-flow.ts +57 -14
  478. package/src/resources/extensions/gsd/journal.ts +38 -3
  479. package/src/resources/extensions/gsd/memory-extractor.ts +11 -3
  480. package/src/resources/extensions/gsd/milestone-actions.ts +18 -0
  481. package/src/resources/extensions/gsd/milestone-scope-classifier.ts +366 -0
  482. package/src/resources/extensions/gsd/milestone-summary-classifier.ts +42 -0
  483. package/src/resources/extensions/gsd/model-cost-table.ts +3 -0
  484. package/src/resources/extensions/gsd/model-router.ts +6 -0
  485. package/src/resources/extensions/gsd/native-git-bridge.ts +34 -4
  486. package/src/resources/extensions/gsd/preferences-validation.ts +21 -0
  487. package/src/resources/extensions/gsd/prompt-cache-optimizer.ts +4 -0
  488. package/src/resources/extensions/gsd/prompts/complete-milestone.md +6 -2
  489. package/src/resources/extensions/gsd/prompts/discuss-headless.md +23 -4
  490. package/src/resources/extensions/gsd/prompts/doctor-heal.md +5 -4
  491. package/src/resources/extensions/gsd/prompts/plan-slice.md +15 -2
  492. package/src/resources/extensions/gsd/reports.ts +5 -4
  493. package/src/resources/extensions/gsd/safety/git-checkpoint.ts +15 -0
  494. package/src/resources/extensions/gsd/service-tier.ts +5 -2
  495. package/src/resources/extensions/gsd/session-lock.ts +20 -10
  496. package/src/resources/extensions/gsd/skill-manifest.ts +175 -0
  497. package/src/resources/extensions/gsd/slice-cadence.ts +299 -0
  498. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +309 -8
  499. package/src/resources/extensions/gsd/state-transition-matrix.ts +152 -0
  500. package/src/resources/extensions/gsd/state.ts +76 -66
  501. package/src/resources/extensions/gsd/sync-lock.ts +97 -39
  502. package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +270 -0
  503. package/src/resources/extensions/gsd/tests/artifacts-table-preserved-on-cache-invalidate.test.ts +2 -1
  504. package/src/resources/extensions/gsd/tests/auto-deterministic-error-classification-4973.test.ts +341 -0
  505. package/src/resources/extensions/gsd/tests/auto-discuss-milestone-deadlock-4973.test.ts +264 -0
  506. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +135 -285
  507. package/src/resources/extensions/gsd/tests/auto-mode-guards.test.ts +79 -0
  508. package/src/resources/extensions/gsd/tests/auto-model-selection-tool-poisoning.test.ts +742 -0
  509. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +78 -0
  510. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +61 -0
  511. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +93 -0
  512. package/src/resources/extensions/gsd/tests/auto-remediate-slice-status.test.ts +4 -1
  513. package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +8 -194
  514. package/src/resources/extensions/gsd/tests/auto-start-clean-runtime-db-gated.test.ts +3 -2
  515. package/src/resources/extensions/gsd/tests/auto-start-cold-db-bootstrap.test.ts +2 -2
  516. package/src/resources/extensions/gsd/tests/auto-start-needs-discussion.test.ts +15 -58
  517. package/src/resources/extensions/gsd/tests/auto-start-worktree-db-path.test.ts +2 -2
  518. package/src/resources/extensions/gsd/tests/auto-thinking-restore.test.ts +3 -2
  519. package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +3 -2
  520. package/src/resources/extensions/gsd/tests/bootstrap-derive-state-db-open.test.ts +2 -1
  521. package/src/resources/extensions/gsd/tests/cache-staleness-regression.test.ts +17 -21
  522. package/src/resources/extensions/gsd/tests/canonical-milestone-root.test.ts +108 -0
  523. package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +263 -0
  524. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +25 -0
  525. package/src/resources/extensions/gsd/tests/complete-slice-composer.test.ts +192 -0
  526. package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +2 -1
  527. package/src/resources/extensions/gsd/tests/complete-task.test.ts +16 -8
  528. package/src/resources/extensions/gsd/tests/component-loader.test.ts +589 -0
  529. package/src/resources/extensions/gsd/tests/component-types.test.ts +127 -0
  530. package/src/resources/extensions/gsd/tests/context-store.test.ts +79 -0
  531. package/src/resources/extensions/gsd/tests/copy-planning-artifacts-samepath.test.ts +2 -1
  532. package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +50 -1
  533. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +159 -0
  534. package/src/resources/extensions/gsd/tests/db-access-guardrails.test.ts +1 -0
  535. package/src/resources/extensions/gsd/tests/derive-state-crossval.test.ts +3 -3
  536. package/src/resources/extensions/gsd/tests/derive-state-db-disk-reconcile.test.ts +40 -0
  537. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +91 -3
  538. package/src/resources/extensions/gsd/tests/derive-state.test.ts +4 -4
  539. package/src/resources/extensions/gsd/tests/discuss-slice-structured-questions.test.ts +2 -1
  540. package/src/resources/extensions/gsd/tests/discuss-tool-scope-leak.test.ts +2 -1
  541. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +5 -0
  542. package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +25 -0
  543. package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +14 -0
  544. package/src/resources/extensions/gsd/tests/dispatcher-stuck-planning.test.ts +3 -2
  545. package/src/resources/extensions/gsd/tests/double-merge-guard.test.ts +4 -3
  546. package/src/resources/extensions/gsd/tests/empty-content-abort-loop.test.ts +4 -3
  547. package/src/resources/extensions/gsd/tests/execution-entry-missing-context-4671.test.ts +173 -0
  548. package/src/resources/extensions/gsd/tests/extension-bootstrap-isolation.test.ts +139 -129
  549. package/src/resources/extensions/gsd/tests/file-lock.test.ts +86 -12
  550. package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +8 -104
  551. package/src/resources/extensions/gsd/tests/gate-state-canonicalization.test.ts +102 -0
  552. package/src/resources/extensions/gsd/tests/gate-storage.test.ts +1 -1
  553. package/src/resources/extensions/gsd/tests/google-search-stub.test.ts +14 -4
  554. package/src/resources/extensions/gsd/tests/headless-milestone-parity.test.ts +117 -0
  555. package/src/resources/extensions/gsd/tests/hook-key-parsing.test.ts +4 -55
  556. package/src/resources/extensions/gsd/tests/integration/all-milestones-complete-merge.test.ts +7 -56
  557. package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +20 -0
  558. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +30 -0
  559. package/src/resources/extensions/gsd/tests/integration/doctor-proactive.test.ts +18 -2
  560. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +3 -2
  561. package/src/resources/extensions/gsd/tests/integration/queue-completed-milestone-perf.test.ts +10 -4
  562. package/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts +144 -7
  563. package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +4 -0
  564. package/src/resources/extensions/gsd/tests/integration/state-machine-runtime-failures.test.ts +2 -16
  565. package/src/resources/extensions/gsd/tests/interactive-routing-bypass.test.ts +9 -3
  566. package/src/resources/extensions/gsd/tests/interrupted-session-ui.test.ts +6 -9
  567. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +64 -0
  568. package/src/resources/extensions/gsd/tests/knowledge.test.ts +93 -1
  569. package/src/resources/extensions/gsd/tests/mcp-client-security.test.ts +47 -0
  570. package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +5 -15
  571. package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +227 -55
  572. package/src/resources/extensions/gsd/tests/milestone-scope-classifier.test.ts +187 -0
  573. package/src/resources/extensions/gsd/tests/milestone-summary-classifier.test.ts +30 -0
  574. package/src/resources/extensions/gsd/tests/model-cost-table.test.ts +9 -1
  575. package/src/resources/extensions/gsd/tests/model-router.test.ts +1 -1
  576. package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +6 -48
  577. package/src/resources/extensions/gsd/tests/notification-widget.test.ts +6 -3
  578. package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +59 -2
  579. package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +273 -130
  580. package/src/resources/extensions/gsd/tests/pipeline-variant-dispatch.test.ts +301 -0
  581. package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +32 -1
  582. package/src/resources/extensions/gsd/tests/preferences-worktree-sync.test.ts +2 -1
  583. package/src/resources/extensions/gsd/tests/prompt-cache-optimizer.test.ts +12 -0
  584. package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +15 -4
  585. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +54 -41
  586. package/src/resources/extensions/gsd/tests/queue-auto-guard.test.ts +213 -0
  587. package/src/resources/extensions/gsd/tests/queue-draft-detection.test.ts +3 -2
  588. package/src/resources/extensions/gsd/tests/queued-discuss-fast-path.test.ts +4 -5
  589. package/src/resources/extensions/gsd/tests/quick-auto-guard.test.ts +13 -7
  590. package/src/resources/extensions/gsd/tests/ready-phrase-no-files-4573.test.ts +75 -2
  591. package/src/resources/extensions/gsd/tests/reassess-default-optin.test.ts +132 -0
  592. package/src/resources/extensions/gsd/tests/recovery-attempts-reset.test.ts +8 -40
  593. package/src/resources/extensions/gsd/tests/regex-hardening.test.ts +136 -256
  594. package/src/resources/extensions/gsd/tests/require-slice-discussion-dispatch.test.ts +170 -0
  595. package/src/resources/extensions/gsd/tests/research-milestone-composer.test.ts +114 -0
  596. package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +6 -3
  597. package/src/resources/extensions/gsd/tests/rewrite-docs-abandon-detect.test.ts +195 -0
  598. package/src/resources/extensions/gsd/tests/run-uat-composer.test.ts +148 -0
  599. package/src/resources/extensions/gsd/tests/service-tier.test.ts +4 -0
  600. package/src/resources/extensions/gsd/tests/session-lock-regression.test.ts +29 -0
  601. package/src/resources/extensions/gsd/tests/sidecar-queue.test.ts +3 -2
  602. package/src/resources/extensions/gsd/tests/silent-catch-diagnostics.test.ts +55 -95
  603. package/src/resources/extensions/gsd/tests/single-writer-v3-tool-surface.test.ts +158 -0
  604. package/src/resources/extensions/gsd/tests/skill-activation.test.ts +120 -1
  605. package/src/resources/extensions/gsd/tests/skill-manifest.test.ts +112 -0
  606. package/src/resources/extensions/gsd/tests/slice-cadence.test.ts +242 -0
  607. package/src/resources/extensions/gsd/tests/slice-context-injection.test.ts +3 -2
  608. package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +164 -1
  609. package/src/resources/extensions/gsd/tests/smart-entry-draft.test.ts +2 -1
  610. package/src/resources/extensions/gsd/tests/stale-dirlistcache-4648.test.ts +112 -0
  611. package/src/resources/extensions/gsd/tests/state-machine-full-walkthrough.test.ts +29 -5
  612. package/src/resources/extensions/gsd/tests/state-transition-matrix.test.ts +44 -0
  613. package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +3 -3
  614. package/src/resources/extensions/gsd/tests/structured-data-formatter.test.ts +11 -92
  615. package/src/resources/extensions/gsd/tests/stuck-detection-coverage.test.ts +2 -2
  616. package/src/resources/extensions/gsd/tests/subagent-model-dispatch.test.ts +7 -6
  617. package/src/resources/extensions/gsd/tests/survivor-branch-complete.test.ts +102 -101
  618. package/src/resources/extensions/gsd/tests/sync-lock.test.ts +31 -0
  619. package/src/resources/extensions/gsd/tests/sync-worktree-skip-current.test.ts +4 -3
  620. package/src/resources/extensions/gsd/tests/test-helpers.test.ts +98 -0
  621. package/src/resources/extensions/gsd/tests/test-helpers.ts +153 -0
  622. package/src/resources/extensions/gsd/tests/token-profile.test.ts +8 -1
  623. package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +61 -1
  624. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +8 -1
  625. package/src/resources/extensions/gsd/tests/triage-resolution.test.ts +50 -2
  626. package/src/resources/extensions/gsd/tests/turn-epoch.test.ts +162 -0
  627. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +355 -0
  628. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +258 -0
  629. package/src/resources/extensions/gsd/tests/uok-contracts.test.ts +51 -0
  630. package/src/resources/extensions/gsd/tests/uok-execution-graph.test.ts +16 -0
  631. package/src/resources/extensions/gsd/tests/uok-gate-runner.test.ts +75 -0
  632. package/src/resources/extensions/gsd/tests/uok-gitops-wiring.test.ts +49 -26
  633. package/src/resources/extensions/gsd/tests/uok-loop-adapter-writer.test.ts +65 -0
  634. package/src/resources/extensions/gsd/tests/uok-parity-report.test.ts +42 -0
  635. package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +19 -2
  636. package/src/resources/extensions/gsd/tests/uok-writer.test.ts +75 -0
  637. package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +12 -0
  638. package/src/resources/extensions/gsd/tests/verify-artifact-tightened.test.ts +144 -80
  639. package/src/resources/extensions/gsd/tests/visualizer-critical-path.test.ts +20 -54
  640. package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +342 -277
  641. package/src/resources/extensions/gsd/tests/worker-model-override.test.ts +37 -29
  642. package/src/resources/extensions/gsd/tests/worktree-db.test.ts +226 -266
  643. package/src/resources/extensions/gsd/tests/worktree-health-monorepo.test.ts +103 -67
  644. package/src/resources/extensions/gsd/tests/worktree-nested-git-safety.test.ts +92 -90
  645. package/src/resources/extensions/gsd/tests/worktree-submodule-safety.test.ts +238 -59
  646. package/src/resources/extensions/gsd/tests/worktree-sync-overwrite-loop.test.ts +113 -161
  647. package/src/resources/extensions/gsd/tests/worktree-telemetry.test.ts +210 -0
  648. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +262 -0
  649. package/src/resources/extensions/gsd/tests/write-gate-predicates.test.ts +186 -0
  650. package/src/resources/extensions/gsd/tests/write-gate.test.ts +7 -5
  651. package/src/resources/extensions/gsd/tests/zombie-gsd-state.test.ts +80 -96
  652. package/src/resources/extensions/gsd/tools/complete-slice.ts +38 -0
  653. package/src/resources/extensions/gsd/tools/complete-task.ts +49 -0
  654. package/src/resources/extensions/gsd/tools/validate-milestone.ts +8 -2
  655. package/src/resources/extensions/gsd/types.ts +3 -3
  656. package/src/resources/extensions/gsd/unit-context-composer.ts +218 -0
  657. package/src/resources/extensions/gsd/unit-context-manifest.ts +574 -0
  658. package/src/resources/extensions/gsd/uok/audit.ts +20 -2
  659. package/src/resources/extensions/gsd/uok/contracts.ts +65 -0
  660. package/src/resources/extensions/gsd/uok/dispatch-envelope.ts +56 -0
  661. package/src/resources/extensions/gsd/uok/execution-graph.ts +22 -0
  662. package/src/resources/extensions/gsd/uok/gate-runner.ts +65 -5
  663. package/src/resources/extensions/gsd/uok/gitops.ts +6 -1
  664. package/src/resources/extensions/gsd/uok/loop-adapter.ts +45 -10
  665. package/src/resources/extensions/gsd/uok/parity-report.ts +84 -0
  666. package/src/resources/extensions/gsd/uok/plan-v2.ts +13 -5
  667. package/src/resources/extensions/gsd/uok/writer.ts +113 -0
  668. package/src/resources/extensions/gsd/workflow-logger.ts +22 -3
  669. package/src/resources/extensions/gsd/workflow-mcp.ts +6 -0
  670. package/src/resources/extensions/gsd/worktree-manager.ts +109 -7
  671. package/src/resources/extensions/gsd/worktree-resolver.ts +96 -9
  672. package/src/resources/extensions/gsd/worktree-telemetry.ts +322 -0
  673. package/src/resources/extensions/mcp-client/auth.ts +12 -1
  674. package/src/resources/extensions/mcp-client/index.ts +132 -11
  675. package/src/resources/extensions/mcp-client/tests/server-name-spaces.test.ts +70 -36
  676. package/src/resources/extensions/ollama/index.ts +5 -1
  677. package/src/resources/extensions/ollama/ollama-auth-mode.test.ts +123 -15
  678. package/src/resources/extensions/ollama/ollama-status-indicator.test.ts +206 -19
  679. package/src/resources/extensions/remote-questions/manager.ts +36 -4
  680. package/src/resources/extensions/remote-questions/tests/command-polling.test.ts +200 -190
  681. package/src/resources/extensions/shared/tests/interview-preview.test.ts +11 -3
  682. package/src/resources/extensions/voice/tests/linux-ready.test.ts +129 -113
  683. package/src/resources/skills/create-skill/SKILL.md +2 -2
  684. package/src/resources/skills/create-skill/references/gsd-skill-ecosystem.md +4 -4
  685. package/src/resources/skills/create-skill/workflows/audit-skill.md +4 -4
  686. package/src/resources/skills/create-skill/workflows/create-new-skill.md +5 -5
  687. package/dist/web/standalone/.next/server/chunks/7461.js +0 -1
  688. package/dist/web/standalone/.next/static/chunks/2826.d445fb428ef41fa1.js +0 -9
  689. package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.d.ts +0 -2
  690. package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.d.ts.map +0 -1
  691. package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.js +0 -289
  692. package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.js.map +0 -1
  693. package/packages/pi-ai/src/utils/oauth/oauth-providers.test.ts +0 -363
  694. package/src/resources/extensions/gsd/tests/auto-start-model-capture.test.ts +0 -143
  695. package/src/resources/extensions/gsd/tests/complete-milestone-false-merge.test.ts +0 -157
  696. package/src/resources/extensions/gsd/tests/dashboard-model-label-ordering.test.ts +0 -107
  697. package/src/resources/extensions/gsd/tests/find-missing-summaries-closed.test.ts +0 -48
  698. package/src/resources/extensions/gsd/tests/forensics-context-persist.test.ts +0 -159
  699. package/src/resources/extensions/gsd/tests/forensics-db-completion.test.ts +0 -96
  700. package/src/resources/extensions/gsd/tests/forensics-dedup.test.ts +0 -79
  701. package/src/resources/extensions/gsd/tests/forensics-hook-key-parse.test.ts +0 -74
  702. package/src/resources/extensions/gsd/tests/forensics-journal.test.ts +0 -162
  703. package/src/resources/extensions/gsd/tests/gitignore-bg-shell.test.ts +0 -38
  704. package/src/resources/extensions/gsd/tests/gsd-no-project-error.test.ts +0 -73
  705. package/src/resources/extensions/gsd/tests/idle-watchdog-stall-override.test.ts +0 -125
  706. package/src/resources/extensions/gsd/tests/import-done-milestones.test.ts +0 -42
  707. /package/dist/web/standalone/.next/static/{H51SzzS_EEgdBsDVhrLBv → SvCJDZPQW104bR1KnBQg1}/_buildManifest.js +0 -0
  708. /package/dist/web/standalone/.next/static/{H51SzzS_EEgdBsDVhrLBv → SvCJDZPQW104bR1KnBQg1}/_ssgManifest.js +0 -0
@@ -1,165 +1,308 @@
1
1
  /**
2
- * Parallel research slices dispatch — structural tests.
2
+ * parallel-research-dispatch.test.ts — behaviour tests for the
3
+ * "planning (multiple slices need research) → parallel-research-slices"
4
+ * dispatch rule and its prompt builder.
3
5
  *
4
- * Verifies the dispatch rule and prompt builder exist with correct structure.
6
+ * These tests invoke the real functions (resolveDispatch,
7
+ * buildParallelResearchSlicesPrompt) against on-disk fixtures. They do
8
+ * not read source files and string-match identifiers.
9
+ *
10
+ * See #4784 for why the previous source-grep version of this file was
11
+ * replaced.
5
12
  */
6
13
 
7
- import test, { afterEach } from "node:test";
14
+ import { describe, test, beforeEach, afterEach, after } from "node:test";
8
15
  import assert from "node:assert/strict";
9
- import { mkdtempSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
10
- import { join, dirname } from "node:path";
16
+ import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
17
+ import { join } from "node:path";
11
18
  import { tmpdir } from "node:os";
12
- import { fileURLToPath } from "node:url";
13
19
 
14
- import { resolveDispatch } from "../auto-dispatch.ts";
20
+ // Point GSD_HOME at a throwaway directory *before* the prompt-loader
21
+ // module is imported (via the dynamic imports below) so templates
22
+ // resolve from the in-tree prompts/ directory instead of a developer's
23
+ // ~/.gsd/ copy (which may be a stale cached version from a prior
24
+ // install — see #4784 fallout). Static imports above are hoisted, so
25
+ // `tmpdir` and `join` are already available at this point; the dynamic
26
+ // imports below observe the value we set here. The previous value is
27
+ // captured and restored in an after() hook to avoid leaking module-scope
28
+ // env mutation into other suites if the runner ever moves to a shared
29
+ // process model.
30
+ const previousGsdHome = process.env.GSD_HOME;
31
+ process.env.GSD_HOME = process.env.GSD_HOME_TEST_OVERRIDE
32
+ ?? join(tmpdir(), `gsd-test-home-${process.pid}-${Date.now()}`);
15
33
 
16
- const __dirname = dirname(fileURLToPath(import.meta.url));
34
+ after(() => {
35
+ if (previousGsdHome === undefined) {
36
+ delete process.env.GSD_HOME;
37
+ } else {
38
+ process.env.GSD_HOME = previousGsdHome;
39
+ }
40
+ });
17
41
 
18
- const dispatchSrc = readFileSync(join(__dirname, "..", "auto-dispatch.ts"), "utf-8");
19
- const promptsSrc = readFileSync(join(__dirname, "..", "auto-prompts.ts"), "utf-8");
20
- const templatePath = join(__dirname, "..", "prompts", "parallel-research-slices.md");
21
- const templateSrc = readFileSync(templatePath, "utf-8");
42
+ const { resolveDispatch } = await import("../auto-dispatch.ts");
43
+ const { buildParallelResearchSlicesPrompt } = await import("../auto-prompts.ts");
22
44
 
23
- const tmpDirs: string[] = [];
45
+ type DispatchState = Parameters<typeof resolveDispatch>[0]["state"];
24
46
 
25
- function makeTmpProject(): string {
26
- const base = mkdtempSync(join(tmpdir(), "parallel-research-"));
27
- tmpDirs.push(base);
28
- const milestoneDir = join(base, ".gsd", "milestones", "M001");
47
+ function writeRoadmap(
48
+ base: string,
49
+ mid: string,
50
+ slices: Array<{ id: string; title: string; done?: boolean; depends?: string[] }>,
51
+ ): void {
52
+ const milestoneDir = join(base, ".gsd", "milestones", mid);
29
53
  mkdirSync(milestoneDir, { recursive: true });
54
+ const lines = [
55
+ `# ${mid}: Parallel Research Milestone`,
56
+ "",
57
+ "**Vision:** Research-ready slices.",
58
+ "",
59
+ "**Success Criteria:**",
60
+ "- Research all slices",
61
+ "",
62
+ "## Slices",
63
+ "",
64
+ ];
65
+ for (const s of slices) {
66
+ const box = s.done ? "x" : " ";
67
+ const deps = s.depends ? `depends:[${s.depends.join(",")}]` : "depends:[]";
68
+ lines.push(`- [${box}] **${s.id}: ${s.title}** \`risk:low\` \`${deps}\``);
69
+ }
70
+ lines.push("", "## Boundary Map", "");
30
71
  writeFileSync(
31
- join(milestoneDir, "M001-ROADMAP.md"),
32
- [
33
- "# M001: Parallel Research Milestone",
34
- "",
35
- "**Vision:** Research-ready slices.",
36
- "",
37
- "**Success Criteria:**",
38
- "- Research both slices",
39
- "",
40
- "## Slices",
41
- "",
42
- "- [ ] **S01: Alpha** `risk:low` `depends:[]`",
43
- "- [ ] **S02: Beta** `risk:low` `depends:[]`",
44
- "",
45
- "## Boundary Map",
46
- "",
47
- ].join("\n"),
72
+ join(milestoneDir, `${mid}-ROADMAP.md`),
73
+ lines.join("\n"),
48
74
  "utf-8",
49
75
  );
50
- return base;
51
76
  }
52
77
 
53
- afterEach(() => {
54
- for (const dir of tmpDirs) {
55
- try {
56
- rmSync(dir, { recursive: true, force: true });
57
- } catch {
58
- // Best-effort cleanup only.
59
- }
78
+ function assertNotParallelResearchDispatch(
79
+ action: Awaited<ReturnType<typeof resolveDispatch>>,
80
+ mid = "M001",
81
+ ): void {
82
+ if (action.action === "dispatch") {
83
+ assert.notEqual(action.unitId, `${mid}/parallel-research`);
60
84
  }
61
- tmpDirs.length = 0;
62
- });
85
+ }
63
86
 
64
- // ─── Dispatch rule ────────────────────────────────────────────────────────
87
+ function baseState(activeSliceId = "S01", activeSliceTitle = "Alpha"): DispatchState {
88
+ return {
89
+ phase: "planning",
90
+ activeMilestone: { id: "M001", title: "Parallel Research Milestone", status: "active" },
91
+ activeSlice: { id: activeSliceId, title: activeSliceTitle },
92
+ activeTask: null,
93
+ registry: [],
94
+ blockers: [],
95
+ } as unknown as DispatchState;
96
+ }
65
97
 
66
- test("dispatch: parallel-research-slices rule exists", () => {
67
- assert.ok(
68
- dispatchSrc.includes("parallel-research-slices"),
69
- "dispatch table should have parallel-research-slices rule",
70
- );
71
- });
98
+ describe("parallel-research-slices dispatch rule", () => {
99
+ let base: string;
72
100
 
73
- test("dispatch: parallel-research-slices requires 2+ slices", () => {
74
- assert.ok(
75
- dispatchSrc.includes("researchReadySlices.length < 2"),
76
- "rule should require at least 2 slices for parallel dispatch",
77
- );
78
- });
101
+ beforeEach(() => {
102
+ base = mkdtempSync(join(tmpdir(), "parallel-research-"));
103
+ });
79
104
 
80
- test("dispatch: parallel-research-slices respects skip_research", () => {
81
- const ruleIdx = dispatchSrc.indexOf("parallel-research-slices");
82
- const ruleBlock = dispatchSrc.slice(ruleIdx, ruleIdx + 500);
83
- assert.ok(
84
- ruleBlock.includes("skip_research") || dispatchSrc.slice(ruleIdx - 300, ruleIdx).includes("skip_research"),
85
- "rule should check skip_research preference",
86
- );
87
- });
105
+ afterEach(() => {
106
+ rmSync(base, { recursive: true, force: true });
107
+ });
88
108
 
89
- // ─── Prompt builder ───────────────────────────────────────────────────────
109
+ test("dispatches parallel research when 2+ slices need research", async () => {
110
+ writeRoadmap(base, "M001", [
111
+ { id: "S01", title: "Alpha" },
112
+ { id: "S02", title: "Beta" },
113
+ ]);
90
114
 
91
- test("prompt: buildParallelResearchSlicesPrompt exported", () => {
92
- assert.ok(
93
- promptsSrc.includes("export async function buildParallelResearchSlicesPrompt"),
94
- "buildParallelResearchSlicesPrompt should be exported",
95
- );
96
- });
115
+ const action = await resolveDispatch({
116
+ basePath: base,
117
+ mid: "M001",
118
+ midTitle: "Parallel Research Milestone",
119
+ state: baseState(),
120
+ prefs: undefined,
121
+ });
97
122
 
98
- test("prompt: builds per-slice subagent prompts", () => {
99
- assert.ok(
100
- promptsSrc.includes("buildResearchSlicePrompt"),
101
- "parallel prompt builder should delegate to per-slice research prompts",
102
- );
103
- });
123
+ assert.equal(action.action, "dispatch");
124
+ if (action.action === "dispatch") {
125
+ assert.equal(action.unitType, "research-slice");
126
+ assert.equal(action.unitId, "M001/parallel-research");
127
+ }
128
+ });
104
129
 
105
- // ─── Template ─────────────────────────────────────────────────────────────
130
+ test("does not dispatch parallel research with only one ready slice", async () => {
131
+ writeRoadmap(base, "M001", [{ id: "S01", title: "Alpha" }]);
106
132
 
107
- test("template: parallel-research-slices.md has required variables", () => {
108
- assert.ok(templateSrc.includes("{{sliceCount}}"), "template should use sliceCount");
109
- assert.ok(templateSrc.includes("{{mid}}"), "template should use mid");
110
- assert.ok(templateSrc.includes("{{subagentPrompts}}"), "template should use subagentPrompts");
111
- });
133
+ const action = await resolveDispatch({
134
+ basePath: base,
135
+ mid: "M001",
136
+ midTitle: "Parallel Research Milestone",
137
+ state: baseState(),
138
+ prefs: undefined,
139
+ });
112
140
 
113
- test("#4068: template: parallel-research-slices retry cap prevents infinite subagent loop", () => {
114
- // The template must cap retries at 1 ("retry it once") and instruct the
115
- // agent to write a BLOCKER note on the second failure rather than looping.
116
- // Without this, a timing-out subagent causes the orchestrating agent to
117
- // retry indefinitely (issue #4068 / #4355).
118
- assert.ok(
119
- templateSrc.includes("once") || templateSrc.includes("one retry") || templateSrc.match(/retry.{0,20}once/),
120
- "template should cap subagent retries at one",
121
- );
122
- assert.ok(
123
- templateSrc.toLowerCase().includes("blocker"),
124
- "template should instruct writing a BLOCKER note instead of infinite retries",
125
- );
126
- assert.ok(
127
- !templateSrc.match(/re-run it individually\s*\n/),
128
- "template must not have unbounded re-run instruction without a retry cap",
129
- );
130
- });
141
+ assertNotParallelResearchDispatch(action);
142
+ });
131
143
 
132
- // ─── Validate milestone prompt ────────────────────────────────────────────
144
+ test("does not dispatch parallel research when skip_research is set", async () => {
145
+ writeRoadmap(base, "M001", [
146
+ { id: "S01", title: "Alpha" },
147
+ { id: "S02", title: "Beta" },
148
+ ]);
133
149
 
134
- test("template: validate-milestone uses parallel reviewers", () => {
135
- const validateSrc = readFileSync(join(__dirname, "..", "prompts", "validate-milestone.md"), "utf-8");
136
- assert.ok(
137
- validateSrc.includes("Reviewer A") && validateSrc.includes("Reviewer B") && validateSrc.includes("Reviewer C"),
138
- "validate-milestone should dispatch 3 parallel reviewers",
139
- );
150
+ const action = await resolveDispatch({
151
+ basePath: base,
152
+ mid: "M001",
153
+ midTitle: "Parallel Research Milestone",
154
+ state: baseState(),
155
+ prefs: { phases: { skip_research: true } } as Parameters<typeof resolveDispatch>[0]["prefs"],
156
+ });
157
+
158
+ assertNotParallelResearchDispatch(action);
159
+ });
160
+
161
+ test("does not dispatch parallel research when skip_slice_research is set", async () => {
162
+ writeRoadmap(base, "M001", [
163
+ { id: "S01", title: "Alpha" },
164
+ { id: "S02", title: "Beta" },
165
+ ]);
166
+
167
+ const action = await resolveDispatch({
168
+ basePath: base,
169
+ mid: "M001",
170
+ midTitle: "Parallel Research Milestone",
171
+ state: baseState(),
172
+ prefs: { phases: { skip_slice_research: true } } as Parameters<typeof resolveDispatch>[0]["prefs"],
173
+ });
174
+
175
+ assertNotParallelResearchDispatch(action);
176
+ });
177
+
178
+ test("does not dispatch when a PARALLEL-BLOCKER placeholder exists (#4414)", async () => {
179
+ writeRoadmap(base, "M001", [
180
+ { id: "S01", title: "Alpha" },
181
+ { id: "S02", title: "Beta" },
182
+ ]);
183
+ const milestoneDir = join(base, ".gsd", "milestones", "M001");
184
+ writeFileSync(
185
+ join(milestoneDir, "M001-PARALLEL-BLOCKER.md"),
186
+ "# Parallel research escalated\nPrevious dispatch failed; need per-slice fallback.\n",
187
+ "utf-8",
188
+ );
189
+
190
+ const action = await resolveDispatch({
191
+ basePath: base,
192
+ mid: "M001",
193
+ midTitle: "Parallel Research Milestone",
194
+ state: baseState(),
195
+ prefs: undefined,
196
+ });
197
+
198
+ assertNotParallelResearchDispatch(action);
199
+ });
200
+
201
+ test("excludes slices that already have a RESEARCH file (falls back to <2)", async () => {
202
+ writeRoadmap(base, "M001", [
203
+ { id: "S01", title: "Alpha" },
204
+ { id: "S02", title: "Beta" },
205
+ ]);
206
+ // S01 already has research → only S02 remains → <2 ready → no parallel dispatch
207
+ const s01Dir = join(base, ".gsd", "milestones", "M001", "slices", "S01");
208
+ mkdirSync(s01Dir, { recursive: true });
209
+ writeFileSync(
210
+ join(s01Dir, "S01-RESEARCH.md"),
211
+ "# Research\n",
212
+ "utf-8",
213
+ );
214
+
215
+ const action = await resolveDispatch({
216
+ basePath: base,
217
+ mid: "M001",
218
+ midTitle: "Parallel Research Milestone",
219
+ state: baseState(),
220
+ prefs: undefined,
221
+ });
222
+
223
+ assertNotParallelResearchDispatch(action);
224
+ });
140
225
  });
141
226
 
142
- test("resolveDispatch prefers parallel research when multiple slices are ready", async () => {
143
- const base = makeTmpProject();
144
-
145
- const action = await resolveDispatch({
146
- basePath: base,
147
- mid: "M001",
148
- midTitle: "Parallel Research Milestone",
149
- state: {
150
- phase: "planning",
151
- activeMilestone: { id: "M001", title: "Parallel Research Milestone", status: "active" },
152
- activeSlice: { id: "S01", title: "Alpha" },
153
- activeTask: null,
154
- registry: [],
155
- blockers: [],
156
- } as any,
157
- prefs: undefined,
227
+ describe("buildParallelResearchSlicesPrompt", () => {
228
+ let base: string;
229
+
230
+ beforeEach(() => {
231
+ base = mkdtempSync(join(tmpdir(), "parallel-research-prompt-"));
232
+ mkdirSync(join(base, ".gsd", "milestones", "M001"), { recursive: true });
158
233
  });
159
234
 
160
- assert.equal(action.action, "dispatch");
161
- if (action.action === "dispatch") {
162
- assert.equal(action.unitType, "research-slice");
163
- assert.equal(action.unitId, "M001/parallel-research");
164
- }
235
+ afterEach(() => {
236
+ rmSync(base, { recursive: true, force: true });
237
+ });
238
+
239
+ test("renders slice count and every slice title into the prompt", async () => {
240
+ const prompt = await buildParallelResearchSlicesPrompt(
241
+ "M001",
242
+ "Parallel Research Milestone",
243
+ [
244
+ { id: "S01", title: "Alpha slice title" },
245
+ { id: "S02", title: "Beta slice title" },
246
+ { id: "S03", title: "Gamma slice title" },
247
+ ],
248
+ base,
249
+ );
250
+
251
+ assert.match(
252
+ prompt,
253
+ /\b3\b[^.\n]{0,40}\bslices?\b/i,
254
+ "prompt should include slice count 3 in slice context",
255
+ );
256
+ assert.match(prompt, /Alpha slice title/);
257
+ assert.match(prompt, /Beta slice title/);
258
+ assert.match(prompt, /Gamma slice title/);
259
+ });
260
+
261
+ test("#4068: prompt caps subagent retries at one and instructs writing a BLOCKER on second failure", async () => {
262
+ // Regression for infinite-retry loop (#4068 / #4355 / #4570). A correct
263
+ // fix must both cap retries AND instruct the agent to escalate to a
264
+ // BLOCKER note on the second failure.
265
+ const prompt = await buildParallelResearchSlicesPrompt(
266
+ "M001",
267
+ "Parallel Research Milestone",
268
+ [
269
+ { id: "S01", title: "Alpha" },
270
+ { id: "S02", title: "Beta" },
271
+ ],
272
+ base,
273
+ );
274
+
275
+ // Cap: the rendered prompt must bound retries. "once" alone is too
276
+ // permissive — the word appears for unrelated reasons across a ~10KB
277
+ // rendered prompt — so the pattern must require retry-context
278
+ // pairing: either "retry ... once" within 30 chars, or the phrase
279
+ // "one retry", or "retry it once".
280
+ assert.match(
281
+ prompt,
282
+ /\bone retry\b|retry[^.?!]{0,30}\bonce\b|retry it \*{0,2}once/i,
283
+ "rendered prompt should cap retries to one",
284
+ );
285
+
286
+ // Escalation: on second failure the agent must write a BLOCKER
287
+ // rather than loop. Bare /blocker/i is too permissive — require
288
+ // retry/failure context within the same sentence so a stray
289
+ // "blocker" elsewhere in the ~10KB prompt cannot satisfy the
290
+ // assertion.
291
+ assert.match(
292
+ prompt,
293
+ /blocker[^.?!]{0,100}(second|retry|fail)|(second|retry|fail)[^.?!]{0,100}blocker/i,
294
+ "rendered prompt should instruct writing a BLOCKER on repeated failure",
295
+ );
296
+
297
+ // Anti-pattern: the unbounded "re-run it individually" instruction
298
+ // that caused the original infinite loop must not appear on its own.
299
+ // The negative lookahead is bounded to the surrounding 100
300
+ // characters so a later unrelated "once" elsewhere in the prompt
301
+ // cannot falsely satisfy the "paired with a retry bound" exception.
302
+ assert.doesNotMatch(
303
+ prompt,
304
+ /re-run it individually(?![\s\S]{0,100}\bonce\b)/i,
305
+ "rendered prompt must not contain the unbounded re-run instruction",
306
+ );
307
+ });
165
308
  });