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,162 +0,0 @@
1
- import { describe, it } from "node:test";
2
- import assert from "node:assert/strict";
3
- import { readFileSync } from "node:fs";
4
- import { join, dirname } from "node:path";
5
- import { fileURLToPath } from "node:url";
6
-
7
- const __dirname = dirname(fileURLToPath(import.meta.url));
8
- const gsdDir = join(__dirname, "..");
9
-
10
- describe("forensics journal & activity log awareness", () => {
11
- const forensicsSrc = readFileSync(join(gsdDir, "forensics.ts"), "utf-8");
12
- const promptSrc = readFileSync(join(gsdDir, "prompts", "forensics.md"), "utf-8");
13
-
14
- it("scanJournalForForensics reads journal files directly (no full queryJournal load)", () => {
15
- // Must NOT use queryJournal which loads ALL entries into memory
16
- assert.ok(
17
- !forensicsSrc.includes('queryJournal('),
18
- "forensics.ts must NOT call queryJournal() which loads all entries at once",
19
- );
20
- // Must have its own journal scanning with file-level limits
21
- assert.ok(
22
- forensicsSrc.includes("scanJournalForForensics"),
23
- "forensics.ts must have scanJournalForForensics function",
24
- );
25
- });
26
-
27
- it("journal scanning limits files parsed to avoid memory bloat", () => {
28
- assert.ok(
29
- forensicsSrc.includes("MAX_JOURNAL_RECENT_FILES"),
30
- "must have MAX_JOURNAL_RECENT_FILES constant to limit parsed files",
31
- );
32
- assert.ok(
33
- forensicsSrc.includes("MAX_JOURNAL_RECENT_EVENTS"),
34
- "must have MAX_JOURNAL_RECENT_EVENTS constant to limit events extracted",
35
- );
36
- });
37
-
38
- it("older journal files are line-counted without full JSON parse", () => {
39
- assert.ok(
40
- forensicsSrc.includes("olderEntryCount") || forensicsSrc.includes("olderFiles"),
41
- "must handle older files separately from recent files",
42
- );
43
- });
44
-
45
- it("ForensicReport includes journalSummary field", () => {
46
- assert.ok(
47
- forensicsSrc.includes("journalSummary"),
48
- "ForensicReport must include journalSummary field",
49
- );
50
- });
51
-
52
- it("ForensicReport includes activityLogMeta field", () => {
53
- assert.ok(
54
- forensicsSrc.includes("activityLogMeta"),
55
- "ForensicReport must include activityLogMeta field",
56
- );
57
- });
58
-
59
- it("buildForensicReport calls scanJournalForForensics", () => {
60
- assert.ok(
61
- forensicsSrc.includes("scanJournalForForensics"),
62
- "buildForensicReport must call scanJournalForForensics",
63
- );
64
- });
65
-
66
- it("buildForensicReport calls gatherActivityLogMeta", () => {
67
- assert.ok(
68
- forensicsSrc.includes("gatherActivityLogMeta"),
69
- "buildForensicReport must call gatherActivityLogMeta",
70
- );
71
- });
72
-
73
- it("forensics detects journal-based anomalies", () => {
74
- assert.ok(
75
- forensicsSrc.includes("detectJournalAnomalies"),
76
- "forensics.ts must have detectJournalAnomalies function",
77
- );
78
- // Check for specific journal anomaly types
79
- assert.ok(forensicsSrc.includes('"journal-stuck"'), "must detect journal-stuck anomalies");
80
- assert.ok(forensicsSrc.includes('"journal-guard-block"'), "must detect journal-guard-block anomalies");
81
- assert.ok(forensicsSrc.includes('"journal-rapid-iterations"'), "must detect journal-rapid-iterations anomalies");
82
- assert.ok(forensicsSrc.includes('"journal-worktree-failure"'), "must detect journal-worktree-failure anomalies");
83
- });
84
-
85
- it("formatReportForPrompt includes journal summary section", () => {
86
- assert.ok(
87
- forensicsSrc.includes("Journal Summary"),
88
- "prompt formatter must include a Journal Summary section",
89
- );
90
- });
91
-
92
- it("formatReportForPrompt includes activity log overview section", () => {
93
- assert.ok(
94
- forensicsSrc.includes("Activity Log Overview"),
95
- "prompt formatter must include an Activity Log Overview section",
96
- );
97
- });
98
-
99
- it("activity log scanning uses tail-read with byte cap (not full file load)", () => {
100
- // scanActivityLogs uses nativeParseJsonlTail + MAX_JSONL_BYTES for efficient reading
101
- assert.ok(
102
- forensicsSrc.includes("nativeParseJsonlTail"),
103
- "activity log scanning must use nativeParseJsonlTail for tail-reading",
104
- );
105
- assert.ok(
106
- forensicsSrc.includes("MAX_JSONL_BYTES"),
107
- "activity log scanning must respect MAX_JSONL_BYTES cap",
108
- );
109
- // Only reads last 5 files
110
- assert.ok(
111
- forensicsSrc.includes("slice(-5)"),
112
- "activity log scanning must limit to last 5 files",
113
- );
114
- });
115
-
116
- it("activity log entries are distilled through extractTrace, not sent raw", () => {
117
- assert.ok(
118
- forensicsSrc.includes("extractTrace("),
119
- "activity log entries must be distilled through extractTrace before reporting",
120
- );
121
- });
122
-
123
- it("prompt output is hard-capped at 30KB", () => {
124
- assert.ok(
125
- forensicsSrc.includes("MAX_BYTES") && forensicsSrc.includes("30 * 1024"),
126
- "formatReportForPrompt must have a 30KB hard cap",
127
- );
128
- assert.ok(
129
- forensicsSrc.includes("truncated at 30KB"),
130
- "prompt must show truncation message when capped",
131
- );
132
- });
133
-
134
- it("forensics prompt documents journal format", () => {
135
- assert.ok(
136
- promptSrc.includes("### Journal Format"),
137
- "forensics.md must document the journal format",
138
- );
139
- assert.ok(
140
- promptSrc.includes("flowId"),
141
- "forensics.md must reference flowId concept",
142
- );
143
- assert.ok(
144
- promptSrc.includes("causedBy"),
145
- "forensics.md must reference causedBy for causal chains",
146
- );
147
- });
148
-
149
- it("forensics prompt includes journal directory in runtime path reference", () => {
150
- assert.ok(
151
- promptSrc.includes("journal/"),
152
- "forensics.md runtime path reference must include journal/",
153
- );
154
- });
155
-
156
- it("investigation protocol references journal data", () => {
157
- assert.ok(
158
- promptSrc.includes("journal timeline") || promptSrc.includes("journal events"),
159
- "investigation protocol must reference journal data for tracing",
160
- );
161
- });
162
- });
@@ -1,145 +0,0 @@
1
- /**
2
- * Tests for the #4764 forensics integration — verifies that
3
- * buildForensicReport picks up worktree telemetry aggregates and emits
4
- * anomalies for orphans and auto-exits with unmerged work.
5
- */
6
-
7
- import { describe, it } from "node:test";
8
- import assert from "node:assert/strict";
9
- import { readFileSync, mkdirSync, rmSync } from "node:fs";
10
- import { join, dirname } from "node:path";
11
- import { tmpdir } from "node:os";
12
- import { randomUUID } from "node:crypto";
13
- import { fileURLToPath } from "node:url";
14
-
15
- import {
16
- emitWorktreeOrphaned,
17
- emitAutoExit,
18
- emitWorktreeCreated,
19
- emitWorktreeMerged,
20
- } from "../worktree-telemetry.ts";
21
-
22
- const __dirname = dirname(fileURLToPath(import.meta.url));
23
- const gsdDir = join(__dirname, "..");
24
-
25
- function makeTmpBase(): string {
26
- const base = join(tmpdir(), `gsd-for-tel-test-${randomUUID()}`);
27
- mkdirSync(join(base, ".gsd"), { recursive: true });
28
- return base;
29
- }
30
-
31
- function cleanup(base: string): void {
32
- try { rmSync(base, { recursive: true, force: true }); } catch { /* */ }
33
- }
34
-
35
- describe("#4764 forensics + worktree telemetry integration", () => {
36
- const forensicsSrc = readFileSync(join(gsdDir, "forensics.ts"), "utf-8");
37
-
38
- it("forensics.ts imports the telemetry summarizer", () => {
39
- assert.ok(
40
- forensicsSrc.includes("summarizeWorktreeTelemetry"),
41
- "forensics must consume the telemetry aggregator",
42
- );
43
- });
44
-
45
- it("forensics.ts does NOT call queryJournal directly (memory guard)", () => {
46
- // The same invariant guarded by forensics-journal.test.ts — re-asserted
47
- // here so this feature change doesn't regress it.
48
- assert.ok(
49
- !forensicsSrc.includes("queryJournal("),
50
- "forensics.ts must route journal reads through aggregators, not queryJournal",
51
- );
52
- });
53
-
54
- it("ForensicReport includes worktreeTelemetry field", () => {
55
- assert.ok(
56
- forensicsSrc.includes("worktreeTelemetry"),
57
- "report shape must include the telemetry summary",
58
- );
59
- });
60
-
61
- it("formatReportForPrompt gates Worktree Telemetry section on signal", () => {
62
- assert.ok(
63
- forensicsSrc.includes("Worktree Telemetry"),
64
- "prompt formatter must include a Worktree Telemetry section",
65
- );
66
- });
67
-
68
- it("new anomaly types worktree-orphan and worktree-unmerged-exit exist on the union", () => {
69
- assert.ok(forensicsSrc.includes('"worktree-orphan"'));
70
- assert.ok(forensicsSrc.includes('"worktree-unmerged-exit"'));
71
- });
72
-
73
- it("buildForensicReport surfaces worktree-orphan anomaly when the journal shows an in-progress orphan", async () => {
74
- const base = makeTmpBase();
75
- try {
76
- // Seed the journal with one in-progress orphan event
77
- emitWorktreeOrphaned(base, "M001", {
78
- reason: "in-progress-unmerged",
79
- commitsAhead: 3,
80
- worktreeDirExists: true,
81
- });
82
-
83
- const { buildForensicReport } = await import("../forensics.ts");
84
- const report = await buildForensicReport(base);
85
-
86
- const orphanAnomalies = report.anomalies.filter(a => a.type === "worktree-orphan");
87
- assert.ok(orphanAnomalies.length >= 1, `expected a worktree-orphan anomaly; got ${JSON.stringify(report.anomalies.map(a => a.type))}`);
88
- assert.equal(orphanAnomalies[0].severity, "warning", "in-progress orphan should be a warning");
89
-
90
- // Aggregate fields surface in the telemetry summary
91
- assert.ok(report.worktreeTelemetry, "report should carry the telemetry summary");
92
- assert.equal(report.worktreeTelemetry!.orphansDetected, 1);
93
- assert.equal(report.worktreeTelemetry!.orphansByReason["in-progress-unmerged"], 1);
94
- } finally { cleanup(base); }
95
- });
96
-
97
- it("buildForensicReport surfaces worktree-unmerged-exit anomaly when auto-exit left work unmerged", async () => {
98
- const base = makeTmpBase();
99
- try {
100
- emitAutoExit(base, { reason: "pause", milestoneId: "M002", milestoneMerged: false });
101
- emitAutoExit(base, { reason: "stop", milestoneId: "M002", milestoneMerged: false });
102
- emitAutoExit(base, { reason: "all-complete", milestoneId: "M001", milestoneMerged: true });
103
-
104
- const { buildForensicReport } = await import("../forensics.ts");
105
- const report = await buildForensicReport(base);
106
-
107
- const unmergedExitAnomalies = report.anomalies.filter(a => a.type === "worktree-unmerged-exit");
108
- assert.equal(unmergedExitAnomalies.length, 1, "exactly one aggregate unmerged-exit anomaly");
109
- assert.equal(unmergedExitAnomalies[0].severity, "warning");
110
- assert.ok(
111
- unmergedExitAnomalies[0].summary.includes("2"),
112
- "summary should mention the count (2 unmerged exits out of 3 total)",
113
- );
114
-
115
- assert.equal(report.worktreeTelemetry!.exitsWithUnmergedWork, 2);
116
- } finally { cleanup(base); }
117
- });
118
-
119
- it("buildForensicReport emits no telemetry anomalies when there are no signals", async () => {
120
- const base = makeTmpBase();
121
- try {
122
- // Healthy path — worktree created and merged without incident
123
- emitWorktreeCreated(base, "M001");
124
- emitWorktreeMerged(base, "M001", {
125
- reason: "milestone-complete",
126
- durationMs: 250,
127
- conflict: false,
128
- });
129
- emitAutoExit(base, { reason: "all-complete", milestoneId: "M001", milestoneMerged: true });
130
-
131
- const { buildForensicReport } = await import("../forensics.ts");
132
- const report = await buildForensicReport(base);
133
-
134
- const telemetryAnomalies = report.anomalies.filter(a =>
135
- a.type === "worktree-orphan" || a.type === "worktree-unmerged-exit"
136
- );
137
- assert.deepStrictEqual(telemetryAnomalies, [], "no orphans, no unmerged exits → no telemetry anomalies");
138
-
139
- assert.equal(report.worktreeTelemetry!.worktreesCreated, 1);
140
- assert.equal(report.worktreeTelemetry!.worktreesMerged, 1);
141
- assert.equal(report.worktreeTelemetry!.orphansDetected, 0);
142
- assert.equal(report.worktreeTelemetry!.exitsWithUnmergedWork, 0);
143
- } finally { cleanup(base); }
144
- });
145
- });
@@ -1,38 +0,0 @@
1
- /**
2
- * Regression test — .bg-shell/ added to BASELINE_PATTERNS in gitignore.ts
3
- *
4
- * The bg-shell background process directory was not included in the
5
- * baseline gitignore patterns, causing it to appear as untracked in
6
- * git status and potentially be committed.
7
- *
8
- * Structural verification test — reads source to confirm .bg-shell/
9
- * is in BASELINE_PATTERNS.
10
- */
11
-
12
- import { describe, test } from 'node:test';
13
- import assert from 'node:assert/strict';
14
- import { readFileSync } from 'node:fs';
15
- import { fileURLToPath } from 'node:url';
16
- import { dirname, join } from 'node:path';
17
-
18
- const __filename = fileURLToPath(import.meta.url);
19
- const __dirname = dirname(__filename);
20
-
21
- const source = readFileSync(join(__dirname, '..', 'gitignore.ts'), 'utf-8');
22
-
23
- describe('.bg-shell/ in BASELINE_PATTERNS', () => {
24
- test('BASELINE_PATTERNS array is defined', () => {
25
- assert.match(source, /const BASELINE_PATTERNS\s*=/,
26
- 'BASELINE_PATTERNS should be defined');
27
- });
28
-
29
- test('.bg-shell/ is included in BASELINE_PATTERNS', () => {
30
- // Extract the BASELINE_PATTERNS array content
31
- const patternsStart = source.indexOf('BASELINE_PATTERNS');
32
- const arrayStart = source.indexOf('[', patternsStart);
33
- const arrayEnd = source.indexOf('] as const', arrayStart);
34
- const patternsContent = source.slice(arrayStart, arrayEnd);
35
- assert.match(patternsContent, /\.bg-shell\//,
36
- '.bg-shell/ should be in BASELINE_PATTERNS');
37
- });
38
- });
@@ -1,73 +0,0 @@
1
- /**
2
- * GSDNoProjectError — tests for friendly home-directory error handling.
3
- *
4
- * Verifies that GSDNoProjectError is thrown for blocked directories and
5
- * that the dispatcher catches it with a user-friendly message.
6
- */
7
-
8
- import test from "node:test";
9
- import assert from "node:assert/strict";
10
- import { readFileSync } from "node:fs";
11
- import { join, dirname } from "node:path";
12
- import { fileURLToPath } from "node:url";
13
-
14
- const __dirname = dirname(fileURLToPath(import.meta.url));
15
-
16
- const contextSrc = readFileSync(join(__dirname, "..", "commands", "context.ts"), "utf-8");
17
- const dispatcherSrc = readFileSync(join(__dirname, "..", "commands", "dispatcher.ts"), "utf-8");
18
-
19
- // ─── GSDNoProjectError class ──────────────────────────────────────────────
20
-
21
- test("GSDNoProjectError class is exported from context.ts", () => {
22
- assert.ok(
23
- contextSrc.includes("export class GSDNoProjectError extends Error"),
24
- "GSDNoProjectError should be an exported Error subclass",
25
- );
26
- });
27
-
28
- test("GSDNoProjectError sets name property", () => {
29
- assert.ok(
30
- contextSrc.includes('this.name = "GSDNoProjectError"'),
31
- "GSDNoProjectError should set its name for instanceof checks",
32
- );
33
- });
34
-
35
- // ─── projectRoot blocked directory handling ───────────────────────────────
36
-
37
- test("projectRoot uses validateDirectory and checks for blocked severity", () => {
38
- assert.ok(
39
- contextSrc.includes("validateDirectory(pathToCheck)"),
40
- "projectRoot should call validateDirectory",
41
- );
42
- assert.ok(
43
- contextSrc.includes('result.severity === "blocked"'),
44
- "projectRoot should check for blocked severity",
45
- );
46
- });
47
-
48
- test("projectRoot throws GSDNoProjectError on blocked directory", () => {
49
- assert.ok(
50
- contextSrc.includes("throw new GSDNoProjectError"),
51
- "projectRoot should throw GSDNoProjectError when directory is blocked",
52
- );
53
- });
54
-
55
- // ─── Dispatcher catch ─────────────────────────────────────────────────────
56
-
57
- test("dispatcher catches GSDNoProjectError with user-friendly message", () => {
58
- assert.ok(
59
- dispatcherSrc.includes("err instanceof GSDNoProjectError"),
60
- "dispatcher should catch GSDNoProjectError specifically",
61
- );
62
- assert.ok(
63
- dispatcherSrc.includes("cd"),
64
- "error message should suggest cd-ing into a project directory",
65
- );
66
- });
67
-
68
- test("dispatcher re-throws non-GSDNoProjectError exceptions", () => {
69
- assert.ok(
70
- dispatcherSrc.includes("throw err"),
71
- "dispatcher should re-throw unexpected errors",
72
- );
73
- });
@@ -1,130 +0,0 @@
1
- /**
2
- * Regression tests for #2527: idle watchdog stalled-tool detection.
3
- *
4
- * Bug 1: When a tool is stalled longer than idle_timeout, the watchdog
5
- * notifies but falls through to detectWorkingTreeActivity(), which
6
- * resets lastProgressAt if files were modified earlier. Recovery is
7
- * never called — the session burns tokens indefinitely.
8
- *
9
- * Bug 2: After async recoverTimedOutUnit(), pauseAuto/stopAuto may set
10
- * s.currentUnit = null, but the next line accesses .startedAt — crash.
11
- *
12
- * These tests verify the auto-timers.ts source contains the structural
13
- * fixes: the stalledToolDetected flag, clearInFlightTools() call, the
14
- * filesystem-check guard, and the null guard after recovery.
15
- */
16
-
17
- import { readFileSync } from "node:fs";
18
- import { join } from "node:path";
19
- import { test, describe } from "node:test";
20
- import assert from "node:assert/strict";
21
- import { extractSourceRegion } from "./test-helpers.ts";
22
-
23
- const TIMERS_SRC = readFileSync(
24
- join(import.meta.dirname, "..", "auto-timers.ts"),
25
- "utf-8",
26
- );
27
-
28
- // ═══ Bug 1: stalledToolDetected flag prevents filesystem-activity override ═══
29
-
30
- describe("#2527 Bug 1: stalled tool should not be overridden by filesystem activity", () => {
31
- test("auto-timers.ts imports clearInFlightTools", () => {
32
- assert.ok(
33
- TIMERS_SRC.includes("clearInFlightTools"),
34
- "clearInFlightTools must be imported from auto-tool-tracking",
35
- );
36
- });
37
-
38
- test("auto-timers.ts declares stalledToolDetected flag", () => {
39
- assert.ok(
40
- TIMERS_SRC.includes("stalledToolDetected"),
41
- "stalledToolDetected flag must exist in idle watchdog",
42
- );
43
- });
44
-
45
- test("stalled tool sets flag to true", () => {
46
- // The flag must be set before the filesystem check
47
- const flagSet = TIMERS_SRC.indexOf("stalledToolDetected = true");
48
- assert.ok(flagSet > -1, "stalledToolDetected must be set to true when tool is stalled");
49
-
50
- const notify = TIMERS_SRC.indexOf("Stalled tool detected:");
51
- assert.ok(flagSet < notify, "flag must be set before the stall notification");
52
- });
53
-
54
- test("stalled tool calls clearInFlightTools", () => {
55
- // clearInFlightTools() must be called when tool is stalled, so subsequent
56
- // watchdog ticks don't re-detect the same stale entries
57
- const clearCall = TIMERS_SRC.indexOf("clearInFlightTools()");
58
- assert.ok(clearCall > -1, "clearInFlightTools() must be called when tool is stalled");
59
-
60
- const flagSet = TIMERS_SRC.indexOf("stalledToolDetected = true");
61
- assert.ok(
62
- Math.abs(clearCall - flagSet) < 200,
63
- "clearInFlightTools() should be near stalledToolDetected = true",
64
- );
65
- });
66
-
67
- test("filesystem-activity check is guarded by stalledToolDetected", () => {
68
- // The detectWorkingTreeActivity check must be skipped when stalledToolDetected is true
69
- assert.ok(
70
- TIMERS_SRC.includes("!stalledToolDetected && detectWorkingTreeActivity"),
71
- "detectWorkingTreeActivity must be guarded by !stalledToolDetected",
72
- );
73
- });
74
-
75
- test("control flow: stalled tool → skip filesystem check → reach recovery", () => {
76
- // Verify the structural ordering: flag declaration → stall block → guarded fs check → recovery
77
- const flagDecl = TIMERS_SRC.indexOf("let stalledToolDetected = false");
78
- const stallBlock = TIMERS_SRC.indexOf("stalledToolDetected = true");
79
- const fsGuard = TIMERS_SRC.indexOf("!stalledToolDetected && detectWorkingTreeActivity");
80
- const recovery = TIMERS_SRC.indexOf("recoverTimedOutUnit(ctx, pi, unitType, unitId, \"idle\"");
81
-
82
- assert.ok(flagDecl > -1, "flag declaration must exist");
83
- assert.ok(flagDecl < stallBlock, "flag declared before stall block");
84
- assert.ok(stallBlock < fsGuard, "stall block before filesystem guard");
85
- assert.ok(fsGuard < recovery, "filesystem guard before recovery call");
86
- });
87
- });
88
-
89
- // ═══ Bug 2: null guard after async recoverTimedOutUnit ═══════════════════════
90
-
91
- describe("#2527 Bug 2: null guard after async recovery prevents crash", () => {
92
- test("idle watchdog has null guard after recoverTimedOutUnit", () => {
93
- // Find the idle recovery call
94
- const idleRecovery = TIMERS_SRC.indexOf(
95
- 'recoverTimedOutUnit(ctx, pi, unitType, unitId, "idle"',
96
- );
97
- assert.ok(idleRecovery > -1, "idle recovery call must exist");
98
-
99
- // The null guard must appear between the recovery call and the next
100
- // writeUnitRuntimeRecord that accesses s.currentUnit.startedAt
101
- const afterRecovery = extractSourceRegion(
102
- TIMERS_SRC,
103
- 'recoverTimedOutUnit(ctx, pi, unitType, unitId, "idle"',
104
- { fromIdx: idleRecovery },
105
- );
106
- assert.ok(
107
- afterRecovery.includes("if (!s.currentUnit) return"),
108
- "null guard for s.currentUnit must exist after idle recoverTimedOutUnit",
109
- );
110
- });
111
-
112
- test("null guard is between recovery and writeUnitRuntimeRecord", () => {
113
- const idleRecovery = TIMERS_SRC.indexOf(
114
- 'recoverTimedOutUnit(ctx, pi, unitType, unitId, "idle"',
115
- );
116
- const afterRecovery = TIMERS_SRC.slice(idleRecovery);
117
-
118
- const recoveredReturn = afterRecovery.indexOf('if (recovery === "recovered") return');
119
- const nullGuard = afterRecovery.indexOf("if (!s.currentUnit) return");
120
- const writeRecord = afterRecovery.indexOf("writeUnitRuntimeRecord(s.basePath");
121
-
122
- assert.ok(recoveredReturn > -1, "recovered return must exist");
123
- assert.ok(nullGuard > -1, "null guard must exist");
124
- assert.ok(writeRecord > -1, "writeUnitRuntimeRecord must exist after recovery");
125
- assert.ok(
126
- recoveredReturn < nullGuard && nullGuard < writeRecord,
127
- "order must be: recovered-return → null-guard → writeUnitRuntimeRecord",
128
- );
129
- });
130
- });
@@ -1,43 +0,0 @@
1
- /**
2
- * Regression test for #3699 — import milestones with all-done slices as complete
3
- *
4
- * During DB migration, milestones whose roadmap slices are all marked done
5
- * should be imported with status "complete" instead of "active".
6
- */
7
-
8
- import { describe, test } from 'node:test';
9
- import assert from 'node:assert/strict';
10
- import { readFileSync } from 'node:fs';
11
- import { fileURLToPath } from 'node:url';
12
- import { dirname, join } from 'node:path';
13
- import { extractSourceRegion } from "./test-helpers.ts";
14
-
15
- const __filename = fileURLToPath(import.meta.url);
16
- const __dirname = dirname(__filename);
17
-
18
- const importerSrc = readFileSync(
19
- join(__dirname, '..', 'md-importer.ts'),
20
- 'utf-8',
21
- );
22
-
23
- describe('import done milestones as complete (#3699)', () => {
24
- test('all-slices-done check sets milestoneStatus to complete', () => {
25
- // The importer should check if all roadmap slices are done
26
- assert.match(importerSrc, /roadmap\.slices\.every\(s\s*=>\s*s\.done\)/,
27
- 'should check roadmap.slices.every(s => s.done)');
28
- });
29
-
30
- test('milestoneStatus is set to complete when all slices done', () => {
31
- // Find the all-done guard and verify it sets 'complete'
32
- const everyIdx = importerSrc.indexOf('roadmap.slices.every(s => s.done)');
33
- assert.ok(everyIdx > -1, 'all-slices-done check should exist');
34
- const afterCheck = extractSourceRegion(importerSrc, 'roadmap.slices.every(s => s.done)');
35
- assert.match(afterCheck, /milestoneStatus\s*=\s*'complete'/,
36
- 'should set milestoneStatus to complete when all slices are done');
37
- });
38
-
39
- test('roadmap.slices.length > 0 guard prevents false positives', () => {
40
- assert.match(importerSrc, /roadmap\.slices\.length\s*>\s*0/,
41
- 'should guard against empty slices array');
42
- });
43
- });