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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (429) hide show
  1. package/README.md +1 -1
  2. package/dist/claude-cli-check.js +5 -1
  3. package/dist/headless.js +49 -4
  4. package/dist/resource-loader.d.ts +40 -0
  5. package/dist/resource-loader.js +32 -13
  6. package/dist/resources/extensions/browser-tools/capture.js +9 -0
  7. package/dist/resources/extensions/browser-tools/tests/browser-tools-integration.test.mjs +8 -59
  8. package/dist/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +36 -24
  9. package/dist/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +69 -71
  10. package/dist/resources/extensions/browser-tools/tools/forms.js +5 -1
  11. package/dist/resources/extensions/browser-tools/tools/intent.js +5 -1
  12. package/dist/resources/extensions/claude-code-cli/readiness.js +5 -1
  13. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +481 -17
  14. package/dist/resources/extensions/gsd/auto/loop.js +43 -0
  15. package/dist/resources/extensions/gsd/auto/phases.js +15 -21
  16. package/dist/resources/extensions/gsd/auto/session.js +0 -2
  17. package/dist/resources/extensions/gsd/auto-dispatch.js +102 -24
  18. package/dist/resources/extensions/gsd/auto-model-selection.js +124 -4
  19. package/dist/resources/extensions/gsd/auto-post-unit.js +71 -64
  20. package/dist/resources/extensions/gsd/auto-prompts.js +329 -102
  21. package/dist/resources/extensions/gsd/auto-recovery.js +195 -23
  22. package/dist/resources/extensions/gsd/auto-start.js +34 -24
  23. package/dist/resources/extensions/gsd/auto-tool-tracking.js +47 -7
  24. package/dist/resources/extensions/gsd/auto-worktree.js +122 -26
  25. package/dist/resources/extensions/gsd/auto.js +31 -20
  26. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +9 -1
  27. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +209 -0
  28. package/dist/resources/extensions/gsd/bootstrap/provider-error-resume.js +3 -6
  29. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +7 -3
  30. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +127 -9
  31. package/dist/resources/extensions/gsd/component-loader.js +447 -0
  32. package/dist/resources/extensions/gsd/component-types.js +69 -0
  33. package/dist/resources/extensions/gsd/detection.js +49 -1
  34. package/dist/resources/extensions/gsd/docs/preferences-reference.md +1 -1
  35. package/dist/resources/extensions/gsd/gate-registry.js +2 -2
  36. package/dist/resources/extensions/gsd/git-constants.js +28 -1
  37. package/dist/resources/extensions/gsd/git-self-heal.js +27 -0
  38. package/dist/resources/extensions/gsd/git-service.js +126 -2
  39. package/dist/resources/extensions/gsd/gsd-db.js +6 -3
  40. package/dist/resources/extensions/gsd/guided-flow.js +17 -5
  41. package/dist/resources/extensions/gsd/memory-extractor.js +7 -1
  42. package/dist/resources/extensions/gsd/milestone-scope-classifier.js +299 -0
  43. package/dist/resources/extensions/gsd/model-cost-table.js +3 -0
  44. package/dist/resources/extensions/gsd/model-router.js +6 -0
  45. package/dist/resources/extensions/gsd/native-git-bridge.js +34 -4
  46. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +6 -2
  47. package/dist/resources/extensions/gsd/prompts/plan-slice.md +15 -2
  48. package/dist/resources/extensions/gsd/safety/git-checkpoint.js +11 -0
  49. package/dist/resources/extensions/gsd/service-tier.js +5 -2
  50. package/dist/resources/extensions/gsd/session-lock.js +19 -10
  51. package/dist/resources/extensions/gsd/skill-manifest.js +168 -0
  52. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +278 -8
  53. package/dist/resources/extensions/gsd/state.js +44 -33
  54. package/dist/resources/extensions/gsd/sync-lock.js +98 -42
  55. package/dist/resources/extensions/gsd/unit-context-composer.js +147 -0
  56. package/dist/resources/extensions/gsd/unit-context-manifest.js +370 -0
  57. package/dist/resources/extensions/gsd/uok/gate-runner.js +53 -5
  58. package/dist/resources/extensions/gsd/workflow-mcp.js +6 -0
  59. package/dist/resources/extensions/gsd/worktree-manager.js +34 -8
  60. package/dist/resources/extensions/mcp-client/index.js +3 -1
  61. package/dist/resources/extensions/ollama/index.js +5 -1
  62. package/dist/resources/extensions/remote-questions/manager.js +11 -5
  63. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  64. package/dist/web/standalone/.next/BUILD_ID +1 -1
  65. package/dist/web/standalone/.next/app-path-routes-manifest.json +5 -5
  66. package/dist/web/standalone/.next/build-manifest.json +2 -2
  67. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  68. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  69. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  70. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  71. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  72. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  73. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  74. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  75. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  76. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  77. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  78. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  79. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  80. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  81. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  82. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  83. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  84. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  85. package/dist/web/standalone/.next/server/app/index.html +1 -1
  86. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  87. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  88. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  89. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  90. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  91. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  92. package/dist/web/standalone/.next/server/app-paths-manifest.json +5 -5
  93. package/dist/web/standalone/.next/server/chunks/1926.js +1 -1
  94. package/dist/web/standalone/.next/server/chunks/6897.js +1 -1
  95. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  96. package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
  97. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  98. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  99. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  100. package/package.json +2 -3
  101. package/packages/daemon/src/logger.ts +4 -3
  102. package/packages/mcp-server/dist/server.d.ts +24 -0
  103. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  104. package/packages/mcp-server/dist/server.js +88 -87
  105. package/packages/mcp-server/dist/server.js.map +1 -1
  106. package/packages/mcp-server/src/mcp-server.test.ts +25 -3
  107. package/packages/mcp-server/src/readers/graph.test.ts +87 -15
  108. package/packages/mcp-server/src/secure-env-collect.test.ts +232 -237
  109. package/packages/mcp-server/src/server.ts +131 -105
  110. package/packages/mcp-server/src/workflow-tools.test.ts +80 -39
  111. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  112. package/packages/native/package.json +1 -1
  113. package/packages/native/src/__tests__/_test-coverage-guard.test.mjs +98 -0
  114. package/packages/native/src/__tests__/module-compat.test.mjs +59 -27
  115. package/packages/native/src/__tests__/ps.test.mjs +14 -8
  116. package/packages/native/src/__tests__/stream-process.test.mjs +23 -2
  117. package/packages/native/src/__tests__/truncate.test.mjs +17 -2
  118. package/packages/pi-agent-core/src/agent-loop.test.ts +5 -15
  119. package/packages/pi-agent-core/src/agent.test.ts +96 -102
  120. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  121. package/packages/pi-ai/dist/models/capability-patches.d.ts.map +1 -1
  122. package/packages/pi-ai/dist/models/capability-patches.js +9 -2
  123. package/packages/pi-ai/dist/models/capability-patches.js.map +1 -1
  124. package/packages/pi-ai/dist/models/generated/index.d.ts +34 -0
  125. package/packages/pi-ai/dist/models/generated/index.d.ts.map +1 -1
  126. package/packages/pi-ai/dist/models/generated/openai-codex.d.ts +17 -0
  127. package/packages/pi-ai/dist/models/generated/openai-codex.d.ts.map +1 -1
  128. package/packages/pi-ai/dist/models/generated/openai-codex.js +17 -0
  129. package/packages/pi-ai/dist/models/generated/openai-codex.js.map +1 -1
  130. package/packages/pi-ai/dist/models/generated/openai.d.ts +17 -0
  131. package/packages/pi-ai/dist/models/generated/openai.d.ts.map +1 -1
  132. package/packages/pi-ai/dist/models/generated/openai.js +17 -0
  133. package/packages/pi-ai/dist/models/generated/openai.js.map +1 -1
  134. package/packages/pi-ai/dist/models.generated.test.js +43 -70
  135. package/packages/pi-ai/dist/models.generated.test.js.map +1 -1
  136. package/packages/pi-ai/dist/models.test.js +36 -11
  137. package/packages/pi-ai/dist/models.test.js.map +1 -1
  138. package/packages/pi-ai/scripts/generate-models.ts +44 -0
  139. package/packages/pi-ai/src/models/capability-patches.ts +10 -2
  140. package/packages/pi-ai/src/models/generated/openai-codex.ts +17 -0
  141. package/packages/pi-ai/src/models/generated/openai.ts +17 -0
  142. package/packages/pi-ai/src/models.generated.test.ts +46 -73
  143. package/packages/pi-ai/src/models.test.ts +48 -11
  144. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  145. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +96 -32
  146. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js.map +1 -1
  147. package/packages/pi-coding-agent/dist/core/agent-session-model-switch.test.js +75 -12
  148. package/packages/pi-coding-agent/dist/core/agent-session-model-switch.test.js.map +1 -1
  149. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js +99 -31
  150. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js.map +1 -1
  151. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts +5 -0
  152. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  153. package/packages/pi-coding-agent/dist/core/extensions/loader.js +61 -0
  154. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  155. package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.js +30 -4
  156. package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.js.map +1 -1
  157. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +17 -0
  158. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -1
  159. package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.js +76 -18
  160. package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.js.map +1 -1
  161. package/packages/pi-coding-agent/dist/core/retry-handler.d.ts.map +1 -1
  162. package/packages/pi-coding-agent/dist/core/retry-handler.js +2 -6
  163. package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -1
  164. package/packages/pi-coding-agent/dist/core/retry-handler.test.js +5 -1
  165. package/packages/pi-coding-agent/dist/core/retry-handler.test.js.map +1 -1
  166. package/packages/pi-coding-agent/dist/core/retryable-error-regex.d.ts +18 -0
  167. package/packages/pi-coding-agent/dist/core/retryable-error-regex.d.ts.map +1 -0
  168. package/packages/pi-coding-agent/dist/core/retryable-error-regex.js +18 -0
  169. package/packages/pi-coding-agent/dist/core/retryable-error-regex.js.map +1 -0
  170. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts +20 -0
  171. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
  172. package/packages/pi-coding-agent/dist/core/system-prompt.js +16 -2
  173. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  174. package/packages/pi-coding-agent/dist/index.d.ts +1 -0
  175. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  176. package/packages/pi-coding-agent/dist/index.js +1 -0
  177. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  178. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.js +20 -13
  179. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.js.map +1 -1
  180. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
  181. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +18 -3
  182. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  183. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +125 -0
  184. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
  185. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts +2 -0
  186. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -1
  187. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.js.map +1 -1
  188. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +4 -0
  189. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  190. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +105 -13
  191. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  192. package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.d.ts +2 -0
  193. package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.d.ts.map +1 -0
  194. package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.js +130 -0
  195. package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.js.map +1 -0
  196. package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +113 -37
  197. package/packages/pi-coding-agent/src/core/agent-session-model-switch.test.ts +89 -17
  198. package/packages/pi-coding-agent/src/core/agent-session-tool-refresh.test.ts +112 -43
  199. package/packages/pi-coding-agent/src/core/extensions/loader.ts +58 -0
  200. package/packages/pi-coding-agent/src/core/lsp/lsp-integration.test.ts +35 -4
  201. package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +20 -0
  202. package/packages/pi-coding-agent/src/core/resource-loader-cache-reset.test.ts +93 -28
  203. package/packages/pi-coding-agent/src/core/retry-handler.test.ts +5 -1
  204. package/packages/pi-coding-agent/src/core/retry-handler.ts +2 -8
  205. package/packages/pi-coding-agent/src/core/retryable-error-regex.ts +18 -0
  206. package/packages/pi-coding-agent/src/core/system-prompt.ts +35 -1
  207. package/packages/pi-coding-agent/src/index.ts +1 -0
  208. package/packages/pi-coding-agent/src/modes/interactive/components/dynamic-border.test.ts +26 -20
  209. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +146 -1
  210. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +20 -3
  211. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-state.ts +2 -0
  212. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +119 -13
  213. package/packages/pi-coding-agent/src/tests/system-prompt-skill-filter.test.ts +157 -0
  214. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  215. package/packages/pi-tui/dist/__tests__/autocomplete.test.js +18 -8
  216. package/packages/pi-tui/dist/__tests__/autocomplete.test.js.map +1 -1
  217. package/packages/pi-tui/dist/__tests__/overlay-layout.test.js +128 -17
  218. package/packages/pi-tui/dist/__tests__/overlay-layout.test.js.map +1 -1
  219. package/packages/pi-tui/dist/__tests__/stdin-buffer.test.js +36 -12
  220. package/packages/pi-tui/dist/__tests__/stdin-buffer.test.js.map +1 -1
  221. package/packages/pi-tui/dist/__tests__/tui.test.js +18 -30
  222. package/packages/pi-tui/dist/__tests__/tui.test.js.map +1 -1
  223. package/packages/pi-tui/dist/components/__tests__/input.test.js +10 -3
  224. package/packages/pi-tui/dist/components/__tests__/input.test.js.map +1 -1
  225. package/packages/pi-tui/dist/components/__tests__/loader.test.js +53 -9
  226. package/packages/pi-tui/dist/components/__tests__/loader.test.js.map +1 -1
  227. package/packages/pi-tui/dist/components/__tests__/markdown-maxlines.test.js +6 -2
  228. package/packages/pi-tui/dist/components/__tests__/markdown-maxlines.test.js.map +1 -1
  229. package/packages/pi-tui/dist/components/editor.d.ts +14 -0
  230. package/packages/pi-tui/dist/components/editor.d.ts.map +1 -1
  231. package/packages/pi-tui/dist/components/editor.js +19 -0
  232. package/packages/pi-tui/dist/components/editor.js.map +1 -1
  233. package/packages/pi-tui/dist/components/image.test.js +6 -5
  234. package/packages/pi-tui/dist/components/image.test.js.map +1 -1
  235. package/packages/pi-tui/dist/editor-component.d.ts +2 -0
  236. package/packages/pi-tui/dist/editor-component.d.ts.map +1 -1
  237. package/packages/pi-tui/dist/editor-component.js.map +1 -1
  238. package/packages/pi-tui/src/__tests__/autocomplete.test.ts +24 -8
  239. package/packages/pi-tui/src/__tests__/overlay-layout.test.ts +140 -17
  240. package/packages/pi-tui/src/__tests__/stdin-buffer.test.ts +41 -12
  241. package/packages/pi-tui/src/__tests__/tui.test.ts +18 -37
  242. package/packages/pi-tui/src/components/__tests__/input.test.ts +19 -3
  243. package/packages/pi-tui/src/components/__tests__/loader.test.ts +112 -35
  244. package/packages/pi-tui/src/components/__tests__/markdown-maxlines.test.ts +9 -2
  245. package/packages/pi-tui/src/components/editor.ts +22 -0
  246. package/packages/pi-tui/src/components/image.test.ts +10 -5
  247. package/packages/pi-tui/src/editor-component.ts +3 -0
  248. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  249. package/packages/rpc-client/dist/rpc-client.test.js +101 -51
  250. package/packages/rpc-client/dist/rpc-client.test.js.map +1 -1
  251. package/packages/rpc-client/src/rpc-client.test.ts +109 -52
  252. package/packages/rpc-client/tsconfig.tsbuildinfo +1 -1
  253. package/scripts/install.js +15 -1
  254. package/src/resources/extensions/browser-tools/capture.ts +12 -0
  255. package/src/resources/extensions/browser-tools/tests/browser-tools-integration.test.mjs +8 -59
  256. package/src/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +36 -24
  257. package/src/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +69 -71
  258. package/src/resources/extensions/browser-tools/tools/forms.ts +5 -1
  259. package/src/resources/extensions/browser-tools/tools/intent.ts +5 -1
  260. package/src/resources/extensions/claude-code-cli/readiness.ts +5 -1
  261. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +518 -19
  262. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +919 -75
  263. package/src/resources/extensions/github-sync/tests/cli.test.ts +76 -7
  264. package/src/resources/extensions/github-sync/tests/templates.test.ts +33 -1
  265. package/src/resources/extensions/gsd/auto/loop.ts +47 -0
  266. package/src/resources/extensions/gsd/auto/phases.ts +16 -20
  267. package/src/resources/extensions/gsd/auto/session.ts +0 -2
  268. package/src/resources/extensions/gsd/auto-dispatch.ts +113 -24
  269. package/src/resources/extensions/gsd/auto-model-selection.ts +131 -4
  270. package/src/resources/extensions/gsd/auto-post-unit.ts +82 -73
  271. package/src/resources/extensions/gsd/auto-prompts.ts +330 -90
  272. package/src/resources/extensions/gsd/auto-recovery.ts +225 -24
  273. package/src/resources/extensions/gsd/auto-start.ts +54 -6
  274. package/src/resources/extensions/gsd/auto-tool-tracking.ts +51 -7
  275. package/src/resources/extensions/gsd/auto-worktree.ts +130 -26
  276. package/src/resources/extensions/gsd/auto.ts +43 -22
  277. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +9 -1
  278. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +221 -0
  279. package/src/resources/extensions/gsd/bootstrap/provider-error-resume.ts +3 -7
  280. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +7 -3
  281. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +158 -9
  282. package/src/resources/extensions/gsd/component-loader.ts +598 -0
  283. package/src/resources/extensions/gsd/component-types.ts +362 -0
  284. package/src/resources/extensions/gsd/detection.ts +58 -1
  285. package/src/resources/extensions/gsd/docs/preferences-reference.md +1 -1
  286. package/src/resources/extensions/gsd/gate-registry.ts +2 -2
  287. package/src/resources/extensions/gsd/git-constants.ts +30 -1
  288. package/src/resources/extensions/gsd/git-self-heal.ts +31 -0
  289. package/src/resources/extensions/gsd/git-service.ts +133 -2
  290. package/src/resources/extensions/gsd/gsd-db.ts +6 -3
  291. package/src/resources/extensions/gsd/guided-flow.ts +20 -5
  292. package/src/resources/extensions/gsd/memory-extractor.ts +11 -3
  293. package/src/resources/extensions/gsd/milestone-scope-classifier.ts +366 -0
  294. package/src/resources/extensions/gsd/model-cost-table.ts +3 -0
  295. package/src/resources/extensions/gsd/model-router.ts +6 -0
  296. package/src/resources/extensions/gsd/native-git-bridge.ts +34 -4
  297. package/src/resources/extensions/gsd/prompts/complete-milestone.md +6 -2
  298. package/src/resources/extensions/gsd/prompts/plan-slice.md +15 -2
  299. package/src/resources/extensions/gsd/safety/git-checkpoint.ts +15 -0
  300. package/src/resources/extensions/gsd/service-tier.ts +5 -2
  301. package/src/resources/extensions/gsd/session-lock.ts +20 -10
  302. package/src/resources/extensions/gsd/skill-manifest.ts +175 -0
  303. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +309 -8
  304. package/src/resources/extensions/gsd/state.ts +49 -44
  305. package/src/resources/extensions/gsd/sync-lock.ts +97 -39
  306. package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +270 -0
  307. package/src/resources/extensions/gsd/tests/auto-deterministic-error-classification-4973.test.ts +341 -0
  308. package/src/resources/extensions/gsd/tests/auto-discuss-milestone-deadlock-4973.test.ts +264 -0
  309. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +94 -289
  310. package/src/resources/extensions/gsd/tests/auto-model-selection-tool-poisoning.test.ts +742 -0
  311. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +78 -0
  312. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +61 -0
  313. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +93 -0
  314. package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +8 -197
  315. package/src/resources/extensions/gsd/tests/auto-start-needs-discussion.test.ts +15 -58
  316. package/src/resources/extensions/gsd/tests/cache-staleness-regression.test.ts +17 -21
  317. package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +263 -0
  318. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +25 -0
  319. package/src/resources/extensions/gsd/tests/complete-slice-composer.test.ts +192 -0
  320. package/src/resources/extensions/gsd/tests/complete-task.test.ts +16 -8
  321. package/src/resources/extensions/gsd/tests/component-loader.test.ts +589 -0
  322. package/src/resources/extensions/gsd/tests/component-types.test.ts +127 -0
  323. package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +50 -1
  324. package/src/resources/extensions/gsd/tests/derive-state-crossval.test.ts +3 -3
  325. package/src/resources/extensions/gsd/tests/derive-state-db-disk-reconcile.test.ts +40 -0
  326. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +91 -3
  327. package/src/resources/extensions/gsd/tests/derive-state.test.ts +4 -3
  328. package/src/resources/extensions/gsd/tests/dispatcher-stuck-planning.test.ts +3 -2
  329. package/src/resources/extensions/gsd/tests/extension-bootstrap-isolation.test.ts +139 -129
  330. package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +9 -105
  331. package/src/resources/extensions/gsd/tests/gate-state-canonicalization.test.ts +102 -0
  332. package/src/resources/extensions/gsd/tests/gate-storage.test.ts +1 -1
  333. package/src/resources/extensions/gsd/tests/hook-key-parsing.test.ts +4 -55
  334. package/src/resources/extensions/gsd/tests/integration/all-milestones-complete-merge.test.ts +7 -57
  335. package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +20 -0
  336. package/src/resources/extensions/gsd/tests/integration/doctor-proactive.test.ts +18 -2
  337. package/src/resources/extensions/gsd/tests/integration/queue-completed-milestone-perf.test.ts +10 -4
  338. package/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts +144 -7
  339. package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +4 -0
  340. package/src/resources/extensions/gsd/tests/integration/state-machine-runtime-failures.test.ts +2 -16
  341. package/src/resources/extensions/gsd/tests/interrupted-session-ui.test.ts +6 -9
  342. package/src/resources/extensions/gsd/tests/mcp-client-security.test.ts +8 -37
  343. package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +5 -15
  344. package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +227 -62
  345. package/src/resources/extensions/gsd/tests/milestone-scope-classifier.test.ts +187 -0
  346. package/src/resources/extensions/gsd/tests/model-cost-table.test.ts +9 -1
  347. package/src/resources/extensions/gsd/tests/model-router.test.ts +1 -1
  348. package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +6 -49
  349. package/src/resources/extensions/gsd/tests/notification-widget.test.ts +6 -3
  350. package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +273 -133
  351. package/src/resources/extensions/gsd/tests/pipeline-variant-dispatch.test.ts +301 -0
  352. package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +32 -1
  353. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +23 -24
  354. package/src/resources/extensions/gsd/tests/queue-auto-guard.test.ts +32 -0
  355. package/src/resources/extensions/gsd/tests/ready-phrase-no-files-4573.test.ts +75 -2
  356. package/src/resources/extensions/gsd/tests/reassess-default-optin.test.ts +132 -0
  357. package/src/resources/extensions/gsd/tests/recovery-attempts-reset.test.ts +8 -40
  358. package/src/resources/extensions/gsd/tests/regex-hardening.test.ts +136 -256
  359. package/src/resources/extensions/gsd/tests/research-milestone-composer.test.ts +114 -0
  360. package/src/resources/extensions/gsd/tests/run-uat-composer.test.ts +148 -0
  361. package/src/resources/extensions/gsd/tests/service-tier.test.ts +4 -0
  362. package/src/resources/extensions/gsd/tests/session-lock-regression.test.ts +29 -0
  363. package/src/resources/extensions/gsd/tests/silent-catch-diagnostics.test.ts +55 -95
  364. package/src/resources/extensions/gsd/tests/single-writer-v3-tool-surface.test.ts +158 -0
  365. package/src/resources/extensions/gsd/tests/skill-activation.test.ts +120 -1
  366. package/src/resources/extensions/gsd/tests/skill-manifest.test.ts +112 -0
  367. package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +164 -1
  368. package/src/resources/extensions/gsd/tests/state-machine-full-walkthrough.test.ts +5 -5
  369. package/src/resources/extensions/gsd/tests/structured-data-formatter.test.ts +11 -92
  370. package/src/resources/extensions/gsd/tests/survivor-branch-complete.test.ts +102 -101
  371. package/src/resources/extensions/gsd/tests/sync-lock.test.ts +31 -0
  372. package/src/resources/extensions/gsd/tests/test-helpers.test.ts +12 -61
  373. package/src/resources/extensions/gsd/tests/test-helpers.ts +21 -8
  374. package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +61 -1
  375. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +8 -1
  376. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +355 -0
  377. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +258 -0
  378. package/src/resources/extensions/gsd/tests/uok-gate-runner.test.ts +75 -0
  379. package/src/resources/extensions/gsd/tests/uok-gitops-wiring.test.ts +49 -26
  380. package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +1 -0
  381. package/src/resources/extensions/gsd/tests/verify-artifact-tightened.test.ts +144 -81
  382. package/src/resources/extensions/gsd/tests/visualizer-critical-path.test.ts +20 -54
  383. package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +342 -277
  384. package/src/resources/extensions/gsd/tests/worker-model-override.test.ts +37 -29
  385. package/src/resources/extensions/gsd/tests/worktree-db.test.ts +226 -266
  386. package/src/resources/extensions/gsd/tests/worktree-health-monorepo.test.ts +103 -67
  387. package/src/resources/extensions/gsd/tests/worktree-nested-git-safety.test.ts +92 -90
  388. package/src/resources/extensions/gsd/tests/worktree-submodule-safety.test.ts +238 -59
  389. package/src/resources/extensions/gsd/tests/worktree-sync-overwrite-loop.test.ts +113 -161
  390. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +262 -0
  391. package/src/resources/extensions/gsd/tests/write-gate-predicates.test.ts +186 -0
  392. package/src/resources/extensions/gsd/tests/write-gate.test.ts +7 -5
  393. package/src/resources/extensions/gsd/tests/zombie-gsd-state.test.ts +80 -96
  394. package/src/resources/extensions/gsd/types.ts +3 -3
  395. package/src/resources/extensions/gsd/unit-context-composer.ts +218 -0
  396. package/src/resources/extensions/gsd/unit-context-manifest.ts +574 -0
  397. package/src/resources/extensions/gsd/uok/gate-runner.ts +65 -5
  398. package/src/resources/extensions/gsd/workflow-mcp.ts +6 -0
  399. package/src/resources/extensions/gsd/worktree-manager.ts +55 -7
  400. package/src/resources/extensions/mcp-client/index.ts +3 -1
  401. package/src/resources/extensions/mcp-client/tests/server-name-spaces.test.ts +70 -36
  402. package/src/resources/extensions/ollama/index.ts +5 -1
  403. package/src/resources/extensions/ollama/ollama-auth-mode.test.ts +123 -15
  404. package/src/resources/extensions/ollama/ollama-status-indicator.test.ts +206 -19
  405. package/src/resources/extensions/remote-questions/manager.ts +36 -4
  406. package/src/resources/extensions/remote-questions/tests/command-polling.test.ts +200 -190
  407. package/src/resources/extensions/shared/tests/interview-preview.test.ts +11 -3
  408. package/src/resources/extensions/voice/tests/linux-ready.test.ts +129 -113
  409. package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.d.ts +0 -2
  410. package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.d.ts.map +0 -1
  411. package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.js +0 -289
  412. package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.js.map +0 -1
  413. package/packages/pi-ai/src/utils/oauth/oauth-providers.test.ts +0 -363
  414. package/src/resources/extensions/gsd/tests/auto-start-model-capture.test.ts +0 -144
  415. package/src/resources/extensions/gsd/tests/complete-milestone-false-merge.test.ts +0 -157
  416. package/src/resources/extensions/gsd/tests/dashboard-model-label-ordering.test.ts +0 -107
  417. package/src/resources/extensions/gsd/tests/find-missing-summaries-closed.test.ts +0 -48
  418. package/src/resources/extensions/gsd/tests/forensics-context-persist.test.ts +0 -159
  419. package/src/resources/extensions/gsd/tests/forensics-db-completion.test.ts +0 -96
  420. package/src/resources/extensions/gsd/tests/forensics-dedup.test.ts +0 -79
  421. package/src/resources/extensions/gsd/tests/forensics-hook-key-parse.test.ts +0 -75
  422. package/src/resources/extensions/gsd/tests/forensics-journal.test.ts +0 -162
  423. package/src/resources/extensions/gsd/tests/forensics-worktree-telemetry.test.ts +0 -145
  424. package/src/resources/extensions/gsd/tests/gitignore-bg-shell.test.ts +0 -38
  425. package/src/resources/extensions/gsd/tests/gsd-no-project-error.test.ts +0 -73
  426. package/src/resources/extensions/gsd/tests/idle-watchdog-stall-override.test.ts +0 -130
  427. package/src/resources/extensions/gsd/tests/import-done-milestones.test.ts +0 -43
  428. /package/dist/web/standalone/.next/static/{Cev5xrAYA3ZGTRLyjR2fX → SvCJDZPQW104bR1KnBQg1}/_buildManifest.js +0 -0
  429. /package/dist/web/standalone/.next/static/{Cev5xrAYA3ZGTRLyjR2fX → SvCJDZPQW104bR1KnBQg1}/_ssgManifest.js +0 -0
@@ -1,108 +1,109 @@
1
1
  /**
2
- * Regression test for #2358: Survivor branch recovery skipped in phase=complete.
2
+ * survivor-branch-complete.test.ts #2358
3
3
  *
4
- * When bootstrapAutoSession finds a survivor milestone branch and the derived
5
- * state phase is "complete", recovery/finalization is skipped entirely because
6
- * the survivor branch detection only triggers when phase === "pre-planning".
7
- * The milestone finalization (merge, cleanup) never runs, leaving the worktree
8
- * and branch alive.
4
+ * The bug: `bootstrapAutoSession` found a survivor milestone branch
5
+ * (previous session's worktree/branch that was never merged) but only
6
+ * triggered recovery when `state.phase === "pre-planning"`. In
7
+ * `phase === "complete"` the milestone artifacts existed but the
8
+ * finalization path (merge + cleanup) never ran, leaving the worktree
9
+ * and branch alive indefinitely.
9
10
  *
10
- * The fix broadens the survivor branch detection to also check phase === "complete",
11
- * and adds a finalization path that runs mergeAndExit before falling through to
12
- * the normal "complete" handling.
11
+ * The fix broadens the detection to include `phase === "complete"` and
12
+ * routes to a finalize-via-mergeAndExit path.
13
+ *
14
+ * The previous version of this file was 4 scenarios that re-implemented
15
+ * the decision logic inline and called `.includes(phase)` on
16
+ * locally-declared arrays — testing the test, not the code. Called out
17
+ * in #4832 and parent #4784 as a pure-tautology case (zero imports
18
+ * from production).
19
+ *
20
+ * This rewrite imports `decideSurvivorAction` from auto-start.ts (a
21
+ * helper extracted in the accompanying refactor) and drives the full
22
+ * decision table through the real function. The helper is wired into
23
+ * `bootstrapAutoSession` at the two call sites that previously used
24
+ * inline conditionals, so the assertions here fail if someone reverts
25
+ * the helper or narrows its branches.
13
26
  */
14
27
 
15
- import { createTestContext } from "./test-helpers.ts";
16
-
17
- const { assertTrue, assertEq, report } = createTestContext();
18
-
19
- // ═══ Test: survivor branch detection conditions ══════════════════════════════
20
-
21
- // The survivor branch detection block in auto-start.ts checks:
22
- // state.activeMilestone &&
23
- // state.phase === "pre-planning" && // <-- BUG: too restrictive
24
- // shouldUseWorktreeIsolation() &&
25
- // !detectWorktreeName(base) &&
26
- // !base.includes(...)
27
- //
28
- // The fix should also include state.phase === "complete".
29
-
30
- {
31
- console.log("\n=== #2358: survivor branch should be detected in phase=complete ===");
32
-
33
- // Simulate the condition check before the fix (only pre-planning)
34
- const phasesBeforeFix = ["pre-planning"];
35
- const phasesAfterFix = ["pre-planning", "complete"];
36
-
37
- const testPhase = "complete";
38
-
39
- const detectedBefore = phasesBeforeFix.includes(testPhase);
40
- assertEq(detectedBefore, false, "before fix: phase=complete should NOT trigger survivor detection");
41
-
42
- const detectedAfter = phasesAfterFix.includes(testPhase);
43
- assertEq(detectedAfter, true, "after fix: phase=complete SHOULD trigger survivor detection");
44
- }
45
-
46
- // ═══ Test: pre-planning survivor detection still works ═══════════════════════
47
-
48
- {
49
- console.log("\n=== #2358: pre-planning survivor detection is not broken ===");
50
-
51
- const phasesAfterFix = ["pre-planning", "complete"];
52
- const testPhase = "pre-planning";
53
-
54
- const detected = phasesAfterFix.includes(testPhase);
55
- assertEq(detected, true, "pre-planning should still trigger survivor detection after fix");
56
- }
57
-
58
- // ═══ Test: other phases do NOT trigger survivor detection ════════════════════
59
-
60
- {
61
- console.log("\n=== #2358: other phases should NOT trigger survivor detection ===");
62
-
63
- const phasesAfterFix = ["pre-planning", "complete"];
64
-
65
- for (const phase of ["planning", "executing", "blocked", "needs-discussion"]) {
66
- const detected = phasesAfterFix.includes(phase);
67
- assertEq(detected, false, `phase=${phase} should NOT trigger survivor detection`);
68
- }
69
- }
70
-
71
- // ═══ Test: phase=complete + hasSurvivorBranch should trigger finalization ═════
72
-
73
- {
74
- console.log("\n=== #2358: phase=complete + survivor branch triggers finalization path ===");
75
-
76
- // Simulate the decision logic after the fix:
77
- // if (hasSurvivorBranch && state.phase === "complete") -> finalize
78
- // if (hasSurvivorBranch && state.phase === "needs-discussion") -> discuss
79
- // if (!hasSurvivorBranch && state.phase === "complete") -> showSmartEntry
80
-
81
- const scenarios = [
82
- { hasSurvivorBranch: true, phase: "complete", expected: "finalize" },
83
- { hasSurvivorBranch: true, phase: "needs-discussion", expected: "discuss" },
84
- { hasSurvivorBranch: true, phase: "pre-planning", expected: "continue" },
85
- { hasSurvivorBranch: false, phase: "complete", expected: "showSmartEntry" },
86
- ];
87
-
88
- for (const { hasSurvivorBranch, phase, expected } of scenarios) {
89
- let result: string;
90
- if (hasSurvivorBranch && phase === "complete") {
91
- result = "finalize";
92
- } else if (hasSurvivorBranch && phase === "needs-discussion") {
93
- result = "discuss";
94
- } else if (!hasSurvivorBranch && (!phase || phase === "complete")) {
95
- result = "showSmartEntry";
96
- } else {
97
- result = "continue";
28
+ import { describe, test } from "node:test";
29
+ import assert from "node:assert/strict";
30
+
31
+ import { decideSurvivorAction } from "../auto-start.ts";
32
+ import type { SurvivorAction } from "../auto-start.ts";
33
+
34
+ describe("decideSurvivorAction (#2358)", () => {
35
+ test("no survivor branch → no action, regardless of phase", () => {
36
+ const phases = [
37
+ "pre-planning",
38
+ "planning",
39
+ "executing",
40
+ "complete",
41
+ "needs-discussion",
42
+ "blocked",
43
+ "",
44
+ null,
45
+ undefined,
46
+ ];
47
+ for (const phase of phases) {
48
+ const got: SurvivorAction = decideSurvivorAction(false, phase);
49
+ assert.equal(got, "none", `phase=${phase ?? "(nullish)"} → expected 'none', got '${got}'`);
98
50
  }
99
-
100
- assertEq(
101
- result,
102
- expected,
103
- `hasSurvivorBranch=${hasSurvivorBranch}, phase=${phase} -> expected ${expected}, got ${result}`,
51
+ });
52
+
53
+ test("survivor + needs-discussion → 'discuss' (#1726)", () => {
54
+ assert.equal(decideSurvivorAction(true, "needs-discussion"), "discuss");
55
+ });
56
+
57
+ test("survivor + complete → 'finalize' (#2358 — the bug this regression guards)", () => {
58
+ // This is THE assertion that fails if someone reverts the fix and
59
+ // narrows the recovery to pre-planning only.
60
+ assert.equal(decideSurvivorAction(true, "complete"), "finalize");
61
+ });
62
+
63
+ test("survivor + other phase → 'none' (caller continues normal flow)", () => {
64
+ // pre-planning, planning, executing, blocked — survivor alone is
65
+ // not sufficient to trigger recovery. Normal auto-mode picks up
66
+ // from state. This protects against regressions that try to run
67
+ // finalize on every survivor regardless of phase.
68
+ const passThroughPhases = ["pre-planning", "planning", "executing", "blocked", ""];
69
+ for (const phase of passThroughPhases) {
70
+ assert.equal(
71
+ decideSurvivorAction(true, phase),
72
+ "none",
73
+ `survivor + phase=${phase} → expected 'none', got ${decideSurvivorAction(true, phase)}`,
74
+ );
75
+ }
76
+ });
77
+
78
+ test("decision table covers the three outcomes the bootstrap code needs", () => {
79
+ // Belt-and-suspenders: enumerate (hasSurvivor, phase) and assert
80
+ // the complete truth table. If someone adds a 4th outcome, this
81
+ // test fails loudly so they must update both the helper and the
82
+ // bootstrap wiring.
83
+ const cases: Array<{ hasSurvivor: boolean; phase: string | null; expected: SurvivorAction }> = [
84
+ { hasSurvivor: true, phase: "needs-discussion", expected: "discuss" },
85
+ { hasSurvivor: true, phase: "complete", expected: "finalize" },
86
+ { hasSurvivor: true, phase: "pre-planning", expected: "none" },
87
+ { hasSurvivor: true, phase: "planning", expected: "none" },
88
+ { hasSurvivor: true, phase: null, expected: "none" },
89
+ { hasSurvivor: false, phase: "complete", expected: "none" },
90
+ { hasSurvivor: false, phase: "needs-discussion", expected: "none" },
91
+ { hasSurvivor: false, phase: null, expected: "none" },
92
+ ];
93
+ const outcomes = new Set<SurvivorAction>();
94
+ for (const { hasSurvivor, phase, expected } of cases) {
95
+ const got = decideSurvivorAction(hasSurvivor, phase);
96
+ outcomes.add(got);
97
+ assert.equal(
98
+ got,
99
+ expected,
100
+ `(hasSurvivor=${hasSurvivor}, phase=${phase}) → expected '${expected}', got '${got}'`,
101
+ );
102
+ }
103
+ assert.deepEqual(
104
+ [...outcomes].sort(),
105
+ ["discuss", "finalize", "none"],
106
+ "decision function should produce exactly three outcomes",
104
107
  );
105
- }
106
- }
107
-
108
- report();
108
+ });
109
+ });
@@ -120,3 +120,34 @@ test('sync-lock: overrides stale lock file (mtime backdated)', (t) => {
120
120
  cleanupDir(base);
121
121
  }
122
122
  });
123
+
124
+ test('sync-lock: EPERM from live owner PID prevents stale lock stealing', () => {
125
+ const base = tempDir();
126
+ fs.mkdirSync(path.join(base, '.gsd'), { recursive: true });
127
+ const lockPath = path.join(base, '.gsd', 'sync.lock');
128
+ const fakePid = process.pid + 100_000;
129
+ const originalKill = process.kill;
130
+
131
+ try {
132
+ fs.writeFileSync(lockPath, JSON.stringify({ pid: fakePid, acquired_at: new Date(0).toISOString() }));
133
+ const staleTime = new Date(Date.now() - 120_000);
134
+ fs.utimesSync(lockPath, staleTime, staleTime);
135
+
136
+ process.kill = ((pid: number, signal?: NodeJS.Signals | number) => {
137
+ if (pid === fakePid && signal === 0) {
138
+ const err = new Error('operation not permitted') as NodeJS.ErrnoException;
139
+ err.code = 'EPERM';
140
+ throw err;
141
+ }
142
+ return originalKill(pid, signal);
143
+ }) as typeof process.kill;
144
+
145
+ const result = acquireSyncLock(base, 100);
146
+ assert.strictEqual(result.acquired, false, 'EPERM owner should be treated as live');
147
+ const content = JSON.parse(fs.readFileSync(lockPath, 'utf-8'));
148
+ assert.strictEqual(content.pid, fakePid, 'lock file should not be overwritten');
149
+ } finally {
150
+ process.kill = originalKill;
151
+ cleanupDir(base);
152
+ }
153
+ });
@@ -1,70 +1,21 @@
1
1
  /**
2
- * Tests for test-helpers.ts — the source-inspection and timing helpers
3
- * introduced in #4773 / #4774 to replace brittle fixed-byte slice and
4
- * magic-number sleep patterns in the test suite.
2
+ * Tests for test-helpers.ts — the timing helpers (waitForCondition,
3
+ * findLine) used to replace magic-number sleeps and positional line
4
+ * indexing in the test suite.
5
+ *
6
+ * The `extractSourceRegion` helper (introduced in #4773/#4774) is
7
+ * deliberately NOT tested here. It is the source-grep antipattern that
8
+ * #4784 names as the root problem; tests against toy fixtures only
9
+ * legitimize the pattern without validating behaviour. Its test cases
10
+ * were removed as part of #4834 — callers are being migrated to
11
+ * behaviour tests one file at a time, after which the helper is slated
12
+ * for deletion.
5
13
  */
6
14
 
7
15
  import test from "node:test";
8
16
  import assert from "node:assert/strict";
9
17
 
10
- import { extractSourceRegion, waitForCondition, findLine } from "./test-helpers.ts";
11
-
12
- // ─── extractSourceRegion ──────────────────────────────────────────────────
13
-
14
- test("extractSourceRegion returns empty string when start anchor missing", () => {
15
- assert.equal(extractSourceRegion("const x = 1;", "missing"), "");
16
- });
17
-
18
- test("extractSourceRegion uses explicit end anchor when provided", () => {
19
- const src = "START_TOKEN\nbody line\nEND_TOKEN tail";
20
- const region = extractSourceRegion(src, "START_TOKEN", "END_TOKEN");
21
- assert.ok(region.includes("START_TOKEN"));
22
- assert.ok(region.includes("body line"));
23
- assert.ok(!region.includes("END_TOKEN"));
24
- });
25
-
26
- test("extractSourceRegion stops at next private method boundary", () => {
27
- const src = [
28
- "class Foo {",
29
- " private alpha(): void {",
30
- " const a = 1;",
31
- " someCall();",
32
- " }",
33
- "",
34
- " private beta(): void {",
35
- " const b = 2;",
36
- " }",
37
- "}",
38
- ].join("\n");
39
-
40
- // Anchor on alpha's declaration; helper should stop at the next
41
- // private method (beta), not on alpha itself.
42
- const region = extractSourceRegion(src, "private alpha");
43
- assert.ok(region.includes("alpha"));
44
- assert.ok(region.includes("someCall()"));
45
- assert.ok(!region.includes("beta"));
46
- });
47
-
48
- test("extractSourceRegion stops at next top-level function", () => {
49
- const src = [
50
- "function alpha() {",
51
- " throw new Error('alpha');",
52
- "}",
53
- "",
54
- "function beta() {",
55
- " return 2;",
56
- "}",
57
- ].join("\n");
58
-
59
- const region = extractSourceRegion(src, "function alpha");
60
- assert.ok(region.includes("throw new Error"));
61
- assert.ok(!region.includes("beta"));
62
- });
63
-
64
- test("extractSourceRegion returns to end-of-source when no terminator found", () => {
65
- const src = "just one line";
66
- assert.equal(extractSourceRegion(src, "just"), "just one line");
67
- });
18
+ import { waitForCondition, findLine } from "./test-helpers.ts";
68
19
 
69
20
  // ─── waitForCondition ─────────────────────────────────────────────────────
70
21
 
@@ -60,22 +60,35 @@ export function createTestContext() {
60
60
  return { assertEq, assertTrue, assertMatch, assertNoMatch, report };
61
61
  }
62
62
 
63
- // ─── Source-inspection helpers ────────────────────────────────────────────────
63
+ // ─── Source-inspection helpers (DEPRECATED — do not add new callers) ──────────
64
64
  //
65
- // Replace brittle fixed-byte slice patterns like `src.slice(idx, idx + 6000)`
66
- // with structural boundary detection. See #4773, #4774.
65
+ // `extractSourceRegion` was introduced in #4773 / #4774 as a more-durable
66
+ // replacement for hand-rolled `src.slice(idx, idx + N)` patterns. Issue
67
+ // #4784 surfaced that the helper is the wrong target: its use case —
68
+ // testing that an identifier or phrase exists in production source text
69
+ // — is the source-grep antipattern that causes false coverage in the
70
+ // first place. Tests should exercise behaviour (call the function,
71
+ // assert on its return value or observable effects) rather than check
72
+ // whether specific identifier strings remain in source.
73
+ //
74
+ // CONTRIBUTING.md forbids new callers of this helper. Existing callers
75
+ // are being migrated one file at a time; the helper is slated for
76
+ // removal once the last caller is converted.
77
+ //
78
+ // Do not add new callers. If you are tempted to, file an issue
79
+ // describing the behavioural invariant you want to test and we will
80
+ // find a runtime assertion instead.
67
81
 
68
82
  /**
83
+ * @deprecated Use a real behaviour test against the function under
84
+ * inspection instead. See #4784 and CONTRIBUTING.md > "Test behaviour,
85
+ * not source shape". No new callers.
86
+ *
69
87
  * Extract a region of source between a start anchor and either an explicit
70
88
  * end anchor or, if none is given, a set of reasonable structural
71
89
  * terminators (next `private `/`export `/`function `/`class `/`interface `/
72
90
  * `//` section separator). Falls back to end-of-source if none match.
73
91
  *
74
- * Use this instead of `src.slice(startIdx, startIdx + N)` when searching
75
- * for patterns within a specific method or region — the start anchor is
76
- * what the caller already has, and the end is determined by structure,
77
- * not by a magic byte count that breaks under refactors.
78
- *
79
92
  * @param src The source text.
80
93
  * @param startAnchor Literal substring that marks the start of the region.
81
94
  * Typically a function name, a section header comment, or
@@ -44,7 +44,19 @@ describe("#2883: tool invocation error tracking on AutoSession", () => {
44
44
 
45
45
  // ─── isToolInvocationError classifier ────────────────────────────────────
46
46
 
47
- import { isToolInvocationError, isQueuedUserMessageSkip } from "../auto-tool-tracking.ts";
47
+ import {
48
+ isDeterministicPolicyError,
49
+ isToolInvocationError,
50
+ isQueuedUserMessageSkip,
51
+ } from "../auto-tool-tracking.ts";
52
+ import {
53
+ shouldBlockContextWrite,
54
+ shouldBlockPendingGateInSnapshot,
55
+ shouldBlockQueueExecutionInSnapshot,
56
+ resetWriteGateState,
57
+ type WriteGateSnapshot,
58
+ } from "../bootstrap/write-gate.ts";
59
+ import { BLOCKED_WRITE_ERROR } from "../write-intercept.ts";
48
60
 
49
61
  describe("#2883: isToolInvocationError classification", () => {
50
62
  test("detects JSON validation failure pattern", () => {
@@ -89,11 +101,59 @@ describe("#2883: isToolInvocationError classification", () => {
89
101
  );
90
102
  });
91
103
 
104
+ test("detects raw write-gate CONTEXT failures for non-GSD write tools", () => {
105
+ resetWriteGateState();
106
+ const result = shouldBlockContextWrite(
107
+ "write",
108
+ "/tmp/project/.gsd/milestones/M001/M001-CONTEXT.md",
109
+ "M001",
110
+ false,
111
+ );
112
+
113
+ assert.equal(result.block, true);
114
+ assert.equal(isDeterministicPolicyError(result.reason ?? ""), true);
115
+ assert.equal(isToolInvocationError(result.reason ?? ""), true);
116
+ });
117
+
118
+ test("detects raw pending-gate failures for non-GSD write tools", () => {
119
+ const snapshot: WriteGateSnapshot = {
120
+ verifiedDepthMilestones: [],
121
+ activeQueuePhase: false,
122
+ pendingGateId: "depth_verification_M001",
123
+ };
124
+ const result = shouldBlockPendingGateInSnapshot(snapshot, "write", "M001", false);
125
+
126
+ assert.equal(result.block, true);
127
+ assert.equal(isDeterministicPolicyError(result.reason ?? ""), true);
128
+ assert.equal(isToolInvocationError(result.reason ?? ""), true);
129
+ });
130
+
131
+ test("detects queue-mode policy blocks for raw write/edit/bash tools", () => {
132
+ const snapshot: WriteGateSnapshot = {
133
+ verifiedDepthMilestones: [],
134
+ activeQueuePhase: true,
135
+ pendingGateId: null,
136
+ };
137
+ const writeResult = shouldBlockQueueExecutionInSnapshot(snapshot, "write", "src/app.ts", true);
138
+ const bashResult = shouldBlockQueueExecutionInSnapshot(snapshot, "bash", "npm run build", true);
139
+
140
+ assert.equal(writeResult.block, true);
141
+ assert.equal(bashResult.block, true);
142
+ assert.equal(isDeterministicPolicyError(writeResult.reason ?? ""), true);
143
+ assert.equal(isToolInvocationError(bashResult.reason ?? ""), true);
144
+ });
145
+
146
+ test("detects direct STATE.md/gsd.db write-intercept policy blocks", () => {
147
+ assert.equal(isDeterministicPolicyError(BLOCKED_WRITE_ERROR), true);
148
+ assert.equal(isToolInvocationError(BLOCKED_WRITE_ERROR), true);
149
+ });
150
+
92
151
  test("returns false for normal tool errors (business logic)", () => {
93
152
  assert.equal(
94
153
  isToolInvocationError("Slice S01 is already complete"),
95
154
  false,
96
155
  );
156
+ assert.equal(isDeterministicPolicyError("Slice S01 is already complete"), false);
97
157
  });
98
158
 
99
159
  test("returns false for empty string", () => {
@@ -36,6 +36,9 @@ const RENAME_MAP: Array<{ canonical: string; alias: string }> = [
36
36
  { canonical: "gsd_reassess_roadmap", alias: "gsd_roadmap_reassess" },
37
37
  { canonical: "gsd_complete_milestone", alias: "gsd_milestone_complete" },
38
38
  { canonical: "gsd_validate_milestone", alias: "gsd_milestone_validate" },
39
+ { canonical: "gsd_task_reopen", alias: "gsd_reopen_task" },
40
+ { canonical: "gsd_slice_reopen", alias: "gsd_reopen_slice" },
41
+ { canonical: "gsd_milestone_reopen", alias: "gsd_reopen_milestone" },
39
42
  ];
40
43
 
41
44
  // ─── Registration count ──────────────────────────────────────────────────────
@@ -45,7 +48,11 @@ console.log('\n── Tool naming: registration count ──');
45
48
  const pi = makeMockPi();
46
49
  registerDbTools(pi);
47
50
 
48
- assert.deepStrictEqual(pi.tools.length, 30, 'Should register exactly 30 tools (14 canonical + 14 aliases + 1 gate tool + 1 gsd_skip_slice)');
51
+ assert.deepStrictEqual(
52
+ pi.tools.length,
53
+ RENAME_MAP.length * 2 + 2,
54
+ 'Should register canonical/alias tool pairs plus 1 gate tool and 1 gsd_skip_slice',
55
+ );
49
56
 
50
57
  // ─── Both names exist for each pair ──────────────────────────────────────────
51
58