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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (545) hide show
  1. package/README.md +53 -17
  2. package/dist/claude-cli-check.js +46 -10
  3. package/dist/headless.js +49 -4
  4. package/dist/resource-loader.d.ts +40 -0
  5. package/dist/resource-loader.js +32 -13
  6. package/dist/resources/extensions/browser-tools/capture.js +9 -0
  7. package/dist/resources/extensions/browser-tools/tests/browser-tools-integration.test.mjs +8 -59
  8. package/dist/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +36 -24
  9. package/dist/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +69 -71
  10. package/dist/resources/extensions/browser-tools/tools/forms.js +5 -1
  11. package/dist/resources/extensions/browser-tools/tools/intent.js +5 -1
  12. package/dist/resources/extensions/claude-code-cli/readiness.js +72 -16
  13. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +481 -17
  14. package/dist/resources/extensions/github-sync/templates.js +103 -0
  15. package/dist/resources/extensions/google-search/index.js +3 -2
  16. package/dist/resources/extensions/gsd/auto/loop.js +124 -2
  17. package/dist/resources/extensions/gsd/auto/phases.js +57 -39
  18. package/dist/resources/extensions/gsd/auto/session.js +6 -2
  19. package/dist/resources/extensions/gsd/auto-dispatch.js +142 -29
  20. package/dist/resources/extensions/gsd/auto-model-selection.js +124 -4
  21. package/dist/resources/extensions/gsd/auto-post-unit.js +150 -64
  22. package/dist/resources/extensions/gsd/auto-prompts.js +372 -104
  23. package/dist/resources/extensions/gsd/auto-recovery.js +197 -48
  24. package/dist/resources/extensions/gsd/auto-start.js +107 -29
  25. package/dist/resources/extensions/gsd/auto-tool-tracking.js +47 -7
  26. package/dist/resources/extensions/gsd/auto-worktree.js +122 -26
  27. package/dist/resources/extensions/gsd/auto.js +76 -21
  28. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +19 -1
  29. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +209 -0
  30. package/dist/resources/extensions/gsd/bootstrap/provider-error-resume.js +3 -6
  31. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +7 -3
  32. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +127 -9
  33. package/dist/resources/extensions/gsd/component-loader.js +447 -0
  34. package/dist/resources/extensions/gsd/component-types.js +69 -0
  35. package/dist/resources/extensions/gsd/context-store.js +23 -7
  36. package/dist/resources/extensions/gsd/detection.js +49 -1
  37. package/dist/resources/extensions/gsd/dispatch-guard.js +2 -17
  38. package/dist/resources/extensions/gsd/docs/preferences-reference.md +1 -1
  39. package/dist/resources/extensions/gsd/forensics.js +106 -0
  40. package/dist/resources/extensions/gsd/gate-registry.js +2 -2
  41. package/dist/resources/extensions/gsd/git-constants.js +28 -1
  42. package/dist/resources/extensions/gsd/git-self-heal.js +27 -0
  43. package/dist/resources/extensions/gsd/git-service.js +126 -2
  44. package/dist/resources/extensions/gsd/gsd-db.js +6 -3
  45. package/dist/resources/extensions/gsd/guided-flow.js +39 -13
  46. package/dist/resources/extensions/gsd/memory-extractor.js +7 -1
  47. package/dist/resources/extensions/gsd/milestone-scope-classifier.js +299 -0
  48. package/dist/resources/extensions/gsd/milestone-summary-classifier.js +37 -0
  49. package/dist/resources/extensions/gsd/model-cost-table.js +3 -0
  50. package/dist/resources/extensions/gsd/model-router.js +6 -0
  51. package/dist/resources/extensions/gsd/native-git-bridge.js +34 -4
  52. package/dist/resources/extensions/gsd/preferences-validation.js +23 -0
  53. package/dist/resources/extensions/gsd/prompt-cache-optimizer.js +4 -0
  54. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +6 -2
  55. package/dist/resources/extensions/gsd/prompts/discuss-headless.md +23 -4
  56. package/dist/resources/extensions/gsd/prompts/doctor-heal.md +5 -4
  57. package/dist/resources/extensions/gsd/prompts/plan-slice.md +15 -2
  58. package/dist/resources/extensions/gsd/safety/git-checkpoint.js +11 -0
  59. package/dist/resources/extensions/gsd/service-tier.js +5 -2
  60. package/dist/resources/extensions/gsd/session-lock.js +19 -10
  61. package/dist/resources/extensions/gsd/skill-manifest.js +168 -0
  62. package/dist/resources/extensions/gsd/slice-cadence.js +238 -0
  63. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +278 -8
  64. package/dist/resources/extensions/gsd/state-transition-matrix.js +118 -0
  65. package/dist/resources/extensions/gsd/state.js +69 -58
  66. package/dist/resources/extensions/gsd/sync-lock.js +98 -42
  67. package/dist/resources/extensions/gsd/tools/validate-milestone.js +7 -2
  68. package/dist/resources/extensions/gsd/unit-context-composer.js +147 -0
  69. package/dist/resources/extensions/gsd/unit-context-manifest.js +370 -0
  70. package/dist/resources/extensions/gsd/uok/dispatch-envelope.js +33 -0
  71. package/dist/resources/extensions/gsd/uok/execution-graph.js +10 -0
  72. package/dist/resources/extensions/gsd/uok/gate-runner.js +53 -5
  73. package/dist/resources/extensions/gsd/uok/gitops.js +2 -1
  74. package/dist/resources/extensions/gsd/uok/loop-adapter.js +37 -10
  75. package/dist/resources/extensions/gsd/uok/parity-report.js +58 -0
  76. package/dist/resources/extensions/gsd/uok/plan-v2.js +10 -4
  77. package/dist/resources/extensions/gsd/uok/writer.js +82 -0
  78. package/dist/resources/extensions/gsd/workflow-mcp.js +6 -0
  79. package/dist/resources/extensions/gsd/worktree-manager.js +85 -8
  80. package/dist/resources/extensions/gsd/worktree-resolver.js +86 -7
  81. package/dist/resources/extensions/gsd/worktree-telemetry.js +198 -0
  82. package/dist/resources/extensions/mcp-client/index.js +3 -1
  83. package/dist/resources/extensions/ollama/index.js +5 -1
  84. package/dist/resources/extensions/remote-questions/manager.js +11 -5
  85. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  86. package/dist/web/standalone/.next/BUILD_ID +1 -1
  87. package/dist/web/standalone/.next/app-path-routes-manifest.json +11 -11
  88. package/dist/web/standalone/.next/build-manifest.json +2 -2
  89. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  90. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  91. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  92. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  93. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  94. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  95. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  96. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  97. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  98. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  99. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  100. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  101. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  102. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  103. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  104. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  105. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  106. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  107. package/dist/web/standalone/.next/server/app/index.html +1 -1
  108. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  109. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  110. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  111. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  112. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  113. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  114. package/dist/web/standalone/.next/server/app-paths-manifest.json +11 -11
  115. package/dist/web/standalone/.next/server/chunks/1926.js +1 -1
  116. package/dist/web/standalone/.next/server/chunks/6897.js +1 -1
  117. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  118. package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
  119. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  120. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  121. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  122. package/package.json +2 -3
  123. package/packages/daemon/package.json +2 -2
  124. package/packages/daemon/src/logger.ts +4 -3
  125. package/packages/mcp-server/dist/server.d.ts +24 -0
  126. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  127. package/packages/mcp-server/dist/server.js +88 -87
  128. package/packages/mcp-server/dist/server.js.map +1 -1
  129. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  130. package/packages/mcp-server/dist/workflow-tools.js +15 -6
  131. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  132. package/packages/mcp-server/package.json +2 -2
  133. package/packages/mcp-server/src/mcp-server.test.ts +25 -3
  134. package/packages/mcp-server/src/readers/graph.test.ts +87 -15
  135. package/packages/mcp-server/src/secure-env-collect.test.ts +232 -237
  136. package/packages/mcp-server/src/server.ts +131 -105
  137. package/packages/mcp-server/src/workflow-tools.test.ts +85 -0
  138. package/packages/mcp-server/src/workflow-tools.ts +19 -6
  139. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  140. package/packages/native/package.json +2 -2
  141. package/packages/native/src/__tests__/_test-coverage-guard.test.mjs +98 -0
  142. package/packages/native/src/__tests__/module-compat.test.mjs +59 -27
  143. package/packages/native/src/__tests__/ps.test.mjs +14 -8
  144. package/packages/native/src/__tests__/stream-process.test.mjs +23 -2
  145. package/packages/native/src/__tests__/truncate.test.mjs +17 -2
  146. package/packages/pi-agent-core/package.json +1 -1
  147. package/packages/pi-agent-core/src/agent-loop.test.ts +5 -15
  148. package/packages/pi-agent-core/src/agent.test.ts +96 -102
  149. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  150. package/packages/pi-ai/dist/models/capability-patches.d.ts.map +1 -1
  151. package/packages/pi-ai/dist/models/capability-patches.js +9 -2
  152. package/packages/pi-ai/dist/models/capability-patches.js.map +1 -1
  153. package/packages/pi-ai/dist/models/generated/index.d.ts +34 -0
  154. package/packages/pi-ai/dist/models/generated/index.d.ts.map +1 -1
  155. package/packages/pi-ai/dist/models/generated/openai-codex.d.ts +17 -0
  156. package/packages/pi-ai/dist/models/generated/openai-codex.d.ts.map +1 -1
  157. package/packages/pi-ai/dist/models/generated/openai-codex.js +17 -0
  158. package/packages/pi-ai/dist/models/generated/openai-codex.js.map +1 -1
  159. package/packages/pi-ai/dist/models/generated/openai.d.ts +17 -0
  160. package/packages/pi-ai/dist/models/generated/openai.d.ts.map +1 -1
  161. package/packages/pi-ai/dist/models/generated/openai.js +17 -0
  162. package/packages/pi-ai/dist/models/generated/openai.js.map +1 -1
  163. package/packages/pi-ai/dist/models.generated.test.js +43 -70
  164. package/packages/pi-ai/dist/models.generated.test.js.map +1 -1
  165. package/packages/pi-ai/dist/models.test.js +36 -11
  166. package/packages/pi-ai/dist/models.test.js.map +1 -1
  167. package/packages/pi-ai/package.json +1 -1
  168. package/packages/pi-ai/scripts/generate-models.ts +44 -0
  169. package/packages/pi-ai/src/models/capability-patches.ts +10 -2
  170. package/packages/pi-ai/src/models/generated/openai-codex.ts +17 -0
  171. package/packages/pi-ai/src/models/generated/openai.ts +17 -0
  172. package/packages/pi-ai/src/models.generated.test.ts +46 -73
  173. package/packages/pi-ai/src/models.test.ts +48 -11
  174. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  175. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +96 -32
  176. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js.map +1 -1
  177. package/packages/pi-coding-agent/dist/core/agent-session-model-switch.test.js +75 -12
  178. package/packages/pi-coding-agent/dist/core/agent-session-model-switch.test.js.map +1 -1
  179. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js +99 -31
  180. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js.map +1 -1
  181. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts +5 -0
  182. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  183. package/packages/pi-coding-agent/dist/core/extensions/loader.js +61 -0
  184. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  185. package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.js +30 -4
  186. package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.js.map +1 -1
  187. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +17 -0
  188. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -1
  189. package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.js +76 -18
  190. package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.js.map +1 -1
  191. package/packages/pi-coding-agent/dist/core/retry-handler.d.ts.map +1 -1
  192. package/packages/pi-coding-agent/dist/core/retry-handler.js +2 -6
  193. package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -1
  194. package/packages/pi-coding-agent/dist/core/retry-handler.test.js +5 -1
  195. package/packages/pi-coding-agent/dist/core/retry-handler.test.js.map +1 -1
  196. package/packages/pi-coding-agent/dist/core/retryable-error-regex.d.ts +18 -0
  197. package/packages/pi-coding-agent/dist/core/retryable-error-regex.d.ts.map +1 -0
  198. package/packages/pi-coding-agent/dist/core/retryable-error-regex.js +18 -0
  199. package/packages/pi-coding-agent/dist/core/retryable-error-regex.js.map +1 -0
  200. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts +20 -0
  201. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
  202. package/packages/pi-coding-agent/dist/core/system-prompt.js +16 -2
  203. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  204. package/packages/pi-coding-agent/dist/index.d.ts +1 -0
  205. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  206. package/packages/pi-coding-agent/dist/index.js +1 -0
  207. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  208. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +36 -5
  209. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
  210. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.js +20 -13
  211. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.js.map +1 -1
  212. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  213. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +30 -12
  214. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  215. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
  216. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +18 -3
  217. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  218. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +125 -0
  219. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
  220. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts +2 -0
  221. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -1
  222. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.js.map +1 -1
  223. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +4 -0
  224. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  225. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +105 -13
  226. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  227. package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.d.ts +2 -0
  228. package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.d.ts.map +1 -0
  229. package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.js +130 -0
  230. package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.js.map +1 -0
  231. package/packages/pi-coding-agent/package.json +1 -1
  232. package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +113 -37
  233. package/packages/pi-coding-agent/src/core/agent-session-model-switch.test.ts +89 -17
  234. package/packages/pi-coding-agent/src/core/agent-session-tool-refresh.test.ts +112 -43
  235. package/packages/pi-coding-agent/src/core/extensions/loader.ts +58 -0
  236. package/packages/pi-coding-agent/src/core/lsp/lsp-integration.test.ts +35 -4
  237. package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +20 -0
  238. package/packages/pi-coding-agent/src/core/resource-loader-cache-reset.test.ts +93 -28
  239. package/packages/pi-coding-agent/src/core/retry-handler.test.ts +5 -1
  240. package/packages/pi-coding-agent/src/core/retry-handler.ts +2 -8
  241. package/packages/pi-coding-agent/src/core/retryable-error-regex.ts +18 -0
  242. package/packages/pi-coding-agent/src/core/system-prompt.ts +35 -1
  243. package/packages/pi-coding-agent/src/index.ts +1 -0
  244. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +49 -3
  245. package/packages/pi-coding-agent/src/modes/interactive/components/dynamic-border.test.ts +26 -20
  246. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +48 -9
  247. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +146 -1
  248. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +20 -3
  249. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-state.ts +2 -0
  250. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +119 -13
  251. package/packages/pi-coding-agent/src/tests/system-prompt-skill-filter.test.ts +157 -0
  252. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  253. package/packages/pi-tui/dist/__tests__/autocomplete.test.js +18 -8
  254. package/packages/pi-tui/dist/__tests__/autocomplete.test.js.map +1 -1
  255. package/packages/pi-tui/dist/__tests__/overlay-layout.test.js +128 -17
  256. package/packages/pi-tui/dist/__tests__/overlay-layout.test.js.map +1 -1
  257. package/packages/pi-tui/dist/__tests__/stdin-buffer.test.js +37 -11
  258. package/packages/pi-tui/dist/__tests__/stdin-buffer.test.js.map +1 -1
  259. package/packages/pi-tui/dist/__tests__/tui.test.js +18 -30
  260. package/packages/pi-tui/dist/__tests__/tui.test.js.map +1 -1
  261. package/packages/pi-tui/dist/components/__tests__/input.test.js +10 -3
  262. package/packages/pi-tui/dist/components/__tests__/input.test.js.map +1 -1
  263. package/packages/pi-tui/dist/components/__tests__/loader.test.js +53 -9
  264. package/packages/pi-tui/dist/components/__tests__/loader.test.js.map +1 -1
  265. package/packages/pi-tui/dist/components/__tests__/markdown-maxlines.test.js +6 -2
  266. package/packages/pi-tui/dist/components/__tests__/markdown-maxlines.test.js.map +1 -1
  267. package/packages/pi-tui/dist/components/editor.d.ts +14 -0
  268. package/packages/pi-tui/dist/components/editor.d.ts.map +1 -1
  269. package/packages/pi-tui/dist/components/editor.js +19 -0
  270. package/packages/pi-tui/dist/components/editor.js.map +1 -1
  271. package/packages/pi-tui/dist/components/image.test.js +6 -5
  272. package/packages/pi-tui/dist/components/image.test.js.map +1 -1
  273. package/packages/pi-tui/dist/editor-component.d.ts +2 -0
  274. package/packages/pi-tui/dist/editor-component.d.ts.map +1 -1
  275. package/packages/pi-tui/dist/editor-component.js.map +1 -1
  276. package/packages/pi-tui/package.json +1 -1
  277. package/packages/pi-tui/src/__tests__/autocomplete.test.ts +24 -8
  278. package/packages/pi-tui/src/__tests__/overlay-layout.test.ts +140 -17
  279. package/packages/pi-tui/src/__tests__/stdin-buffer.test.ts +42 -11
  280. package/packages/pi-tui/src/__tests__/tui.test.ts +18 -37
  281. package/packages/pi-tui/src/components/__tests__/input.test.ts +19 -3
  282. package/packages/pi-tui/src/components/__tests__/loader.test.ts +112 -35
  283. package/packages/pi-tui/src/components/__tests__/markdown-maxlines.test.ts +9 -2
  284. package/packages/pi-tui/src/components/editor.ts +22 -0
  285. package/packages/pi-tui/src/components/image.test.ts +10 -5
  286. package/packages/pi-tui/src/editor-component.ts +3 -0
  287. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  288. package/packages/rpc-client/dist/rpc-client.test.js +101 -51
  289. package/packages/rpc-client/dist/rpc-client.test.js.map +1 -1
  290. package/packages/rpc-client/package.json +1 -1
  291. package/packages/rpc-client/src/rpc-client.test.ts +109 -52
  292. package/packages/rpc-client/tsconfig.tsbuildinfo +1 -1
  293. package/pkg/package.json +1 -1
  294. package/scripts/install.js +15 -1
  295. package/src/resources/extensions/browser-tools/capture.ts +12 -0
  296. package/src/resources/extensions/browser-tools/tests/browser-tools-integration.test.mjs +8 -59
  297. package/src/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +36 -24
  298. package/src/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +69 -71
  299. package/src/resources/extensions/browser-tools/tools/forms.ts +5 -1
  300. package/src/resources/extensions/browser-tools/tools/intent.ts +5 -1
  301. package/src/resources/extensions/claude-code-cli/readiness.ts +75 -16
  302. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +518 -19
  303. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +919 -75
  304. package/src/resources/extensions/github-sync/templates.ts +151 -0
  305. package/src/resources/extensions/github-sync/tests/cli.test.ts +76 -7
  306. package/src/resources/extensions/github-sync/tests/templates.test.ts +92 -1
  307. package/src/resources/extensions/google-search/index.ts +3 -2
  308. package/src/resources/extensions/gsd/auto/loop.ts +142 -2
  309. package/src/resources/extensions/gsd/auto/phases.ts +62 -38
  310. package/src/resources/extensions/gsd/auto/session.ts +7 -2
  311. package/src/resources/extensions/gsd/auto-dispatch.ts +156 -29
  312. package/src/resources/extensions/gsd/auto-model-selection.ts +131 -4
  313. package/src/resources/extensions/gsd/auto-post-unit.ts +163 -73
  314. package/src/resources/extensions/gsd/auto-prompts.ts +385 -93
  315. package/src/resources/extensions/gsd/auto-recovery.ts +230 -51
  316. package/src/resources/extensions/gsd/auto-start.ts +127 -9
  317. package/src/resources/extensions/gsd/auto-tool-tracking.ts +51 -7
  318. package/src/resources/extensions/gsd/auto-worktree.ts +130 -26
  319. package/src/resources/extensions/gsd/auto.ts +90 -23
  320. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +20 -1
  321. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +221 -0
  322. package/src/resources/extensions/gsd/bootstrap/provider-error-resume.ts +3 -7
  323. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +7 -3
  324. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +158 -9
  325. package/src/resources/extensions/gsd/component-loader.ts +598 -0
  326. package/src/resources/extensions/gsd/component-types.ts +362 -0
  327. package/src/resources/extensions/gsd/context-store.ts +25 -8
  328. package/src/resources/extensions/gsd/detection.ts +58 -1
  329. package/src/resources/extensions/gsd/dispatch-guard.ts +2 -20
  330. package/src/resources/extensions/gsd/docs/preferences-reference.md +1 -1
  331. package/src/resources/extensions/gsd/forensics.ts +118 -1
  332. package/src/resources/extensions/gsd/gate-registry.ts +2 -2
  333. package/src/resources/extensions/gsd/git-constants.ts +30 -1
  334. package/src/resources/extensions/gsd/git-self-heal.ts +31 -0
  335. package/src/resources/extensions/gsd/git-service.ts +149 -2
  336. package/src/resources/extensions/gsd/gsd-db.ts +6 -3
  337. package/src/resources/extensions/gsd/guided-flow.ts +57 -14
  338. package/src/resources/extensions/gsd/journal.ts +11 -1
  339. package/src/resources/extensions/gsd/memory-extractor.ts +11 -3
  340. package/src/resources/extensions/gsd/milestone-scope-classifier.ts +366 -0
  341. package/src/resources/extensions/gsd/milestone-summary-classifier.ts +42 -0
  342. package/src/resources/extensions/gsd/model-cost-table.ts +3 -0
  343. package/src/resources/extensions/gsd/model-router.ts +6 -0
  344. package/src/resources/extensions/gsd/native-git-bridge.ts +34 -4
  345. package/src/resources/extensions/gsd/preferences-validation.ts +21 -0
  346. package/src/resources/extensions/gsd/prompt-cache-optimizer.ts +4 -0
  347. package/src/resources/extensions/gsd/prompts/complete-milestone.md +6 -2
  348. package/src/resources/extensions/gsd/prompts/discuss-headless.md +23 -4
  349. package/src/resources/extensions/gsd/prompts/doctor-heal.md +5 -4
  350. package/src/resources/extensions/gsd/prompts/plan-slice.md +15 -2
  351. package/src/resources/extensions/gsd/safety/git-checkpoint.ts +15 -0
  352. package/src/resources/extensions/gsd/service-tier.ts +5 -2
  353. package/src/resources/extensions/gsd/session-lock.ts +20 -10
  354. package/src/resources/extensions/gsd/skill-manifest.ts +175 -0
  355. package/src/resources/extensions/gsd/slice-cadence.ts +299 -0
  356. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +309 -8
  357. package/src/resources/extensions/gsd/state-transition-matrix.ts +152 -0
  358. package/src/resources/extensions/gsd/state.ts +76 -66
  359. package/src/resources/extensions/gsd/sync-lock.ts +97 -39
  360. package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +270 -0
  361. package/src/resources/extensions/gsd/tests/artifacts-table-preserved-on-cache-invalidate.test.ts +2 -1
  362. package/src/resources/extensions/gsd/tests/auto-deterministic-error-classification-4973.test.ts +341 -0
  363. package/src/resources/extensions/gsd/tests/auto-discuss-milestone-deadlock-4973.test.ts +264 -0
  364. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +133 -292
  365. package/src/resources/extensions/gsd/tests/auto-model-selection-tool-poisoning.test.ts +742 -0
  366. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +78 -0
  367. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +61 -0
  368. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +93 -0
  369. package/src/resources/extensions/gsd/tests/auto-remediate-slice-status.test.ts +4 -1
  370. package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +8 -194
  371. package/src/resources/extensions/gsd/tests/auto-start-clean-runtime-db-gated.test.ts +3 -2
  372. package/src/resources/extensions/gsd/tests/auto-start-cold-db-bootstrap.test.ts +2 -2
  373. package/src/resources/extensions/gsd/tests/auto-start-needs-discussion.test.ts +15 -58
  374. package/src/resources/extensions/gsd/tests/auto-start-worktree-db-path.test.ts +2 -2
  375. package/src/resources/extensions/gsd/tests/auto-thinking-restore.test.ts +3 -2
  376. package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +3 -2
  377. package/src/resources/extensions/gsd/tests/bootstrap-derive-state-db-open.test.ts +2 -1
  378. package/src/resources/extensions/gsd/tests/cache-staleness-regression.test.ts +17 -21
  379. package/src/resources/extensions/gsd/tests/canonical-milestone-root.test.ts +108 -0
  380. package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +263 -0
  381. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +25 -0
  382. package/src/resources/extensions/gsd/tests/complete-slice-composer.test.ts +192 -0
  383. package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +2 -1
  384. package/src/resources/extensions/gsd/tests/complete-task.test.ts +16 -8
  385. package/src/resources/extensions/gsd/tests/component-loader.test.ts +589 -0
  386. package/src/resources/extensions/gsd/tests/component-types.test.ts +127 -0
  387. package/src/resources/extensions/gsd/tests/context-store.test.ts +79 -0
  388. package/src/resources/extensions/gsd/tests/copy-planning-artifacts-samepath.test.ts +2 -1
  389. package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +50 -1
  390. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +159 -0
  391. package/src/resources/extensions/gsd/tests/db-access-guardrails.test.ts +1 -0
  392. package/src/resources/extensions/gsd/tests/derive-state-crossval.test.ts +3 -3
  393. package/src/resources/extensions/gsd/tests/derive-state-db-disk-reconcile.test.ts +40 -0
  394. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +91 -3
  395. package/src/resources/extensions/gsd/tests/derive-state.test.ts +4 -4
  396. package/src/resources/extensions/gsd/tests/discuss-slice-structured-questions.test.ts +2 -1
  397. package/src/resources/extensions/gsd/tests/discuss-tool-scope-leak.test.ts +2 -1
  398. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +5 -0
  399. package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +25 -0
  400. package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +14 -0
  401. package/src/resources/extensions/gsd/tests/dispatcher-stuck-planning.test.ts +3 -2
  402. package/src/resources/extensions/gsd/tests/double-merge-guard.test.ts +4 -3
  403. package/src/resources/extensions/gsd/tests/empty-content-abort-loop.test.ts +4 -3
  404. package/src/resources/extensions/gsd/tests/execution-entry-missing-context-4671.test.ts +173 -0
  405. package/src/resources/extensions/gsd/tests/extension-bootstrap-isolation.test.ts +139 -129
  406. package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +8 -104
  407. package/src/resources/extensions/gsd/tests/gate-state-canonicalization.test.ts +102 -0
  408. package/src/resources/extensions/gsd/tests/gate-storage.test.ts +1 -1
  409. package/src/resources/extensions/gsd/tests/google-search-stub.test.ts +14 -4
  410. package/src/resources/extensions/gsd/tests/headless-milestone-parity.test.ts +117 -0
  411. package/src/resources/extensions/gsd/tests/hook-key-parsing.test.ts +4 -55
  412. package/src/resources/extensions/gsd/tests/integration/all-milestones-complete-merge.test.ts +7 -56
  413. package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +20 -0
  414. package/src/resources/extensions/gsd/tests/integration/doctor-proactive.test.ts +18 -2
  415. package/src/resources/extensions/gsd/tests/integration/queue-completed-milestone-perf.test.ts +10 -4
  416. package/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts +144 -7
  417. package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +4 -0
  418. package/src/resources/extensions/gsd/tests/integration/state-machine-runtime-failures.test.ts +2 -16
  419. package/src/resources/extensions/gsd/tests/interactive-routing-bypass.test.ts +9 -3
  420. package/src/resources/extensions/gsd/tests/interrupted-session-ui.test.ts +6 -9
  421. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +64 -0
  422. package/src/resources/extensions/gsd/tests/knowledge.test.ts +93 -1
  423. package/src/resources/extensions/gsd/tests/mcp-client-security.test.ts +8 -37
  424. package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +5 -15
  425. package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +227 -55
  426. package/src/resources/extensions/gsd/tests/milestone-scope-classifier.test.ts +187 -0
  427. package/src/resources/extensions/gsd/tests/milestone-summary-classifier.test.ts +30 -0
  428. package/src/resources/extensions/gsd/tests/model-cost-table.test.ts +9 -1
  429. package/src/resources/extensions/gsd/tests/model-router.test.ts +1 -1
  430. package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +6 -48
  431. package/src/resources/extensions/gsd/tests/notification-widget.test.ts +6 -3
  432. package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +59 -2
  433. package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +273 -130
  434. package/src/resources/extensions/gsd/tests/pipeline-variant-dispatch.test.ts +301 -0
  435. package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +32 -1
  436. package/src/resources/extensions/gsd/tests/preferences-worktree-sync.test.ts +2 -1
  437. package/src/resources/extensions/gsd/tests/prompt-cache-optimizer.test.ts +12 -0
  438. package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +15 -4
  439. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +23 -24
  440. package/src/resources/extensions/gsd/tests/queue-auto-guard.test.ts +32 -0
  441. package/src/resources/extensions/gsd/tests/queue-draft-detection.test.ts +3 -2
  442. package/src/resources/extensions/gsd/tests/queued-discuss-fast-path.test.ts +4 -5
  443. package/src/resources/extensions/gsd/tests/ready-phrase-no-files-4573.test.ts +75 -2
  444. package/src/resources/extensions/gsd/tests/reassess-default-optin.test.ts +132 -0
  445. package/src/resources/extensions/gsd/tests/recovery-attempts-reset.test.ts +8 -40
  446. package/src/resources/extensions/gsd/tests/regex-hardening.test.ts +136 -256
  447. package/src/resources/extensions/gsd/tests/research-milestone-composer.test.ts +114 -0
  448. package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +6 -3
  449. package/src/resources/extensions/gsd/tests/run-uat-composer.test.ts +148 -0
  450. package/src/resources/extensions/gsd/tests/service-tier.test.ts +4 -0
  451. package/src/resources/extensions/gsd/tests/session-lock-regression.test.ts +29 -0
  452. package/src/resources/extensions/gsd/tests/sidecar-queue.test.ts +3 -2
  453. package/src/resources/extensions/gsd/tests/silent-catch-diagnostics.test.ts +55 -95
  454. package/src/resources/extensions/gsd/tests/single-writer-v3-tool-surface.test.ts +158 -0
  455. package/src/resources/extensions/gsd/tests/skill-activation.test.ts +120 -1
  456. package/src/resources/extensions/gsd/tests/skill-manifest.test.ts +112 -0
  457. package/src/resources/extensions/gsd/tests/slice-cadence.test.ts +242 -0
  458. package/src/resources/extensions/gsd/tests/slice-context-injection.test.ts +3 -2
  459. package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +164 -1
  460. package/src/resources/extensions/gsd/tests/smart-entry-draft.test.ts +2 -1
  461. package/src/resources/extensions/gsd/tests/stale-dirlistcache-4648.test.ts +112 -0
  462. package/src/resources/extensions/gsd/tests/state-machine-full-walkthrough.test.ts +29 -5
  463. package/src/resources/extensions/gsd/tests/state-transition-matrix.test.ts +44 -0
  464. package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +3 -3
  465. package/src/resources/extensions/gsd/tests/structured-data-formatter.test.ts +11 -92
  466. package/src/resources/extensions/gsd/tests/subagent-model-dispatch.test.ts +7 -6
  467. package/src/resources/extensions/gsd/tests/survivor-branch-complete.test.ts +102 -101
  468. package/src/resources/extensions/gsd/tests/sync-lock.test.ts +31 -0
  469. package/src/resources/extensions/gsd/tests/sync-worktree-skip-current.test.ts +4 -3
  470. package/src/resources/extensions/gsd/tests/test-helpers.test.ts +98 -0
  471. package/src/resources/extensions/gsd/tests/test-helpers.ts +153 -0
  472. package/src/resources/extensions/gsd/tests/token-profile.test.ts +8 -1
  473. package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +61 -1
  474. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +8 -1
  475. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +355 -0
  476. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +258 -0
  477. package/src/resources/extensions/gsd/tests/uok-contracts.test.ts +51 -0
  478. package/src/resources/extensions/gsd/tests/uok-execution-graph.test.ts +16 -0
  479. package/src/resources/extensions/gsd/tests/uok-gate-runner.test.ts +75 -0
  480. package/src/resources/extensions/gsd/tests/uok-gitops-wiring.test.ts +49 -26
  481. package/src/resources/extensions/gsd/tests/uok-loop-adapter-writer.test.ts +65 -0
  482. package/src/resources/extensions/gsd/tests/uok-parity-report.test.ts +42 -0
  483. package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +19 -2
  484. package/src/resources/extensions/gsd/tests/uok-writer.test.ts +75 -0
  485. package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +12 -0
  486. package/src/resources/extensions/gsd/tests/verify-artifact-tightened.test.ts +144 -80
  487. package/src/resources/extensions/gsd/tests/visualizer-critical-path.test.ts +20 -54
  488. package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +342 -277
  489. package/src/resources/extensions/gsd/tests/worker-model-override.test.ts +37 -29
  490. package/src/resources/extensions/gsd/tests/worktree-db.test.ts +226 -266
  491. package/src/resources/extensions/gsd/tests/worktree-health-monorepo.test.ts +103 -67
  492. package/src/resources/extensions/gsd/tests/worktree-nested-git-safety.test.ts +92 -90
  493. package/src/resources/extensions/gsd/tests/worktree-submodule-safety.test.ts +238 -59
  494. package/src/resources/extensions/gsd/tests/worktree-sync-overwrite-loop.test.ts +113 -161
  495. package/src/resources/extensions/gsd/tests/worktree-telemetry.test.ts +210 -0
  496. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +262 -0
  497. package/src/resources/extensions/gsd/tests/write-gate-predicates.test.ts +186 -0
  498. package/src/resources/extensions/gsd/tests/write-gate.test.ts +7 -5
  499. package/src/resources/extensions/gsd/tests/zombie-gsd-state.test.ts +80 -96
  500. package/src/resources/extensions/gsd/tools/validate-milestone.ts +8 -2
  501. package/src/resources/extensions/gsd/types.ts +3 -3
  502. package/src/resources/extensions/gsd/unit-context-composer.ts +218 -0
  503. package/src/resources/extensions/gsd/unit-context-manifest.ts +574 -0
  504. package/src/resources/extensions/gsd/uok/contracts.ts +65 -0
  505. package/src/resources/extensions/gsd/uok/dispatch-envelope.ts +56 -0
  506. package/src/resources/extensions/gsd/uok/execution-graph.ts +22 -0
  507. package/src/resources/extensions/gsd/uok/gate-runner.ts +65 -5
  508. package/src/resources/extensions/gsd/uok/gitops.ts +6 -1
  509. package/src/resources/extensions/gsd/uok/loop-adapter.ts +45 -10
  510. package/src/resources/extensions/gsd/uok/parity-report.ts +84 -0
  511. package/src/resources/extensions/gsd/uok/plan-v2.ts +13 -5
  512. package/src/resources/extensions/gsd/uok/writer.ts +113 -0
  513. package/src/resources/extensions/gsd/workflow-mcp.ts +6 -0
  514. package/src/resources/extensions/gsd/worktree-manager.ts +108 -7
  515. package/src/resources/extensions/gsd/worktree-resolver.ts +96 -9
  516. package/src/resources/extensions/gsd/worktree-telemetry.ts +322 -0
  517. package/src/resources/extensions/mcp-client/index.ts +3 -1
  518. package/src/resources/extensions/mcp-client/tests/server-name-spaces.test.ts +70 -36
  519. package/src/resources/extensions/ollama/index.ts +5 -1
  520. package/src/resources/extensions/ollama/ollama-auth-mode.test.ts +123 -15
  521. package/src/resources/extensions/ollama/ollama-status-indicator.test.ts +206 -19
  522. package/src/resources/extensions/remote-questions/manager.ts +36 -4
  523. package/src/resources/extensions/remote-questions/tests/command-polling.test.ts +200 -190
  524. package/src/resources/extensions/shared/tests/interview-preview.test.ts +11 -3
  525. package/src/resources/extensions/voice/tests/linux-ready.test.ts +129 -113
  526. package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.d.ts +0 -2
  527. package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.d.ts.map +0 -1
  528. package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.js +0 -289
  529. package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.js.map +0 -1
  530. package/packages/pi-ai/src/utils/oauth/oauth-providers.test.ts +0 -363
  531. package/src/resources/extensions/gsd/tests/auto-start-model-capture.test.ts +0 -143
  532. package/src/resources/extensions/gsd/tests/complete-milestone-false-merge.test.ts +0 -157
  533. package/src/resources/extensions/gsd/tests/dashboard-model-label-ordering.test.ts +0 -107
  534. package/src/resources/extensions/gsd/tests/find-missing-summaries-closed.test.ts +0 -48
  535. package/src/resources/extensions/gsd/tests/forensics-context-persist.test.ts +0 -159
  536. package/src/resources/extensions/gsd/tests/forensics-db-completion.test.ts +0 -96
  537. package/src/resources/extensions/gsd/tests/forensics-dedup.test.ts +0 -79
  538. package/src/resources/extensions/gsd/tests/forensics-hook-key-parse.test.ts +0 -74
  539. package/src/resources/extensions/gsd/tests/forensics-journal.test.ts +0 -162
  540. package/src/resources/extensions/gsd/tests/gitignore-bg-shell.test.ts +0 -38
  541. package/src/resources/extensions/gsd/tests/gsd-no-project-error.test.ts +0 -73
  542. package/src/resources/extensions/gsd/tests/idle-watchdog-stall-override.test.ts +0 -125
  543. package/src/resources/extensions/gsd/tests/import-done-milestones.test.ts +0 -42
  544. /package/dist/web/standalone/.next/static/{5wbu35_C2_MQ3Jj1lEVDx → cAJH99yNS1UPbeSEiNRrV}/_buildManifest.js +0 -0
  545. /package/dist/web/standalone/.next/static/{5wbu35_C2_MQ3Jj1lEVDx → cAJH99yNS1UPbeSEiNRrV}/_ssgManifest.js +0 -0
@@ -1,8 +1,20 @@
1
1
  import { describe, it } from "node:test";
2
2
  import assert from "node:assert/strict";
3
3
  import { PassThrough } from "node:stream";
4
+ import { once } from "node:events";
4
5
  import { serializeJsonLine, attachJsonlLineReader } from "./jsonl.js";
5
6
  import { RpcClient } from "./rpc-client.js";
7
+ /**
8
+ * Flush pending microtasks and one turn of the macrotask queue.
9
+ *
10
+ * Used in places where the test needs "every already-queued stream event has
11
+ * been delivered" — cheaper than a wall-clock sleep and deterministic because
12
+ * `setImmediate` runs strictly after any I/O callbacks already queued by a
13
+ * synchronous `stream.write(...)`.
14
+ */
15
+ function flushIO() {
16
+ return new Promise((resolve) => setImmediate(resolve));
17
+ }
6
18
  // ============================================================================
7
19
  // JSONL Tests
8
20
  // ============================================================================
@@ -37,8 +49,9 @@ describe("attachJsonlLineReader", () => {
37
49
  attachJsonlLineReader(stream, (line) => lines.push(line));
38
50
  stream.write('{"a":1}\n{"b":2}\n');
39
51
  stream.end();
40
- // Let microtask queue flush
41
- await new Promise((r) => setTimeout(r, 10));
52
+ // The reader registers its `end` listener first; awaiting `end` here
53
+ // runs strictly after the reader has drained any trailing buffer.
54
+ await once(stream, "end");
42
55
  assert.equal(lines.length, 2);
43
56
  assert.equal(JSON.parse(lines[0]).a, 1);
44
57
  assert.equal(JSON.parse(lines[1]).b, 2);
@@ -52,7 +65,7 @@ describe("attachJsonlLineReader", () => {
52
65
  stream.write('lo"}\n{"type":"w');
53
66
  stream.write('orld"}\n');
54
67
  stream.end();
55
- await new Promise((r) => setTimeout(r, 10));
68
+ await once(stream, "end");
56
69
  assert.equal(lines.length, 2);
57
70
  assert.equal(JSON.parse(lines[0]).type, "hello");
58
71
  assert.equal(JSON.parse(lines[1]).type, "world");
@@ -63,21 +76,34 @@ describe("attachJsonlLineReader", () => {
63
76
  attachJsonlLineReader(stream, (line) => lines.push(line));
64
77
  stream.write('{"final":true}');
65
78
  stream.end();
66
- await new Promise((r) => setTimeout(r, 10));
79
+ await once(stream, "end");
67
80
  assert.equal(lines.length, 1);
68
81
  assert.equal(JSON.parse(lines[0]).final, true);
69
82
  });
70
83
  it("returns a detach function that stops reading", async () => {
71
84
  const stream = new PassThrough();
72
85
  const lines = [];
73
- const detach = attachJsonlLineReader(stream, (line) => lines.push(line));
86
+ // Use an explicit promise to signal "first line has been observed".
87
+ // This is deterministic — we resume exactly when the reader fires the
88
+ // callback, not after an arbitrary wall-clock delay.
89
+ let signalFirstLine;
90
+ const firstLineSeen = new Promise((resolve) => {
91
+ signalFirstLine = resolve;
92
+ });
93
+ const detach = attachJsonlLineReader(stream, (line) => {
94
+ lines.push(line);
95
+ if (lines.length === 1)
96
+ signalFirstLine();
97
+ });
74
98
  stream.write('{"a":1}\n');
75
- await new Promise((r) => setTimeout(r, 10));
99
+ await firstLineSeen;
76
100
  assert.equal(lines.length, 1);
77
101
  detach();
78
102
  stream.write('{"b":2}\n');
79
103
  stream.end();
80
- await new Promise((r) => setTimeout(r, 10));
104
+ // Drain any queued data events post-detach. `setImmediate` runs strictly
105
+ // after any 'data' events that were already queued by the write above.
106
+ await flushIO();
81
107
  // Should still be 1 — detach removed listeners
82
108
  assert.equal(lines.length, 1);
83
109
  });
@@ -87,16 +113,30 @@ describe("attachJsonlLineReader", () => {
87
113
  attachJsonlLineReader(stream, (line) => lines.push(line));
88
114
  stream.write('{"v":1}\r\n');
89
115
  stream.end();
90
- await new Promise((r) => setTimeout(r, 10));
116
+ await once(stream, "end");
91
117
  assert.equal(lines.length, 1);
92
118
  assert.equal(JSON.parse(lines[0]).v, 1);
93
119
  });
94
120
  });
95
121
  // ============================================================================
96
- // Type Shape Tests
122
+ // JSONL Round-Trip Tests
123
+ //
124
+ // These previously lived under a "type shapes" block that only asserted that
125
+ // a typed literal retained its own field values — pure type-system
126
+ // tautologies. They are now replaced with round-trips through
127
+ // `serializeJsonLine` + `JSON.parse`, which exercises the actual framing
128
+ // pipeline the wire protocol uses. A regression where `serializeJsonLine`
129
+ // mangles payloads or the LF terminator will now fail these tests.
97
130
  // ============================================================================
98
- describe("type shapes", () => {
99
- it("RpcInitResult has protocolVersion, sessionId, capabilities", () => {
131
+ describe("JSONL round-trip of v2 payloads", () => {
132
+ function roundTrip(value) {
133
+ const serialized = serializeJsonLine(value);
134
+ assert.ok(serialized.endsWith("\n"), "wire format must terminate with LF");
135
+ // Ensure we did not emit embedded unescaped LFs that would corrupt framing
136
+ assert.equal(serialized.indexOf("\n"), serialized.length - 1, "no unescaped LF inside payload");
137
+ return JSON.parse(serialized.trim());
138
+ }
139
+ it("RpcInitResult round-trips through serializeJsonLine", () => {
100
140
  const init = {
101
141
  protocolVersion: 2,
102
142
  sessionId: "sess_123",
@@ -105,12 +145,10 @@ describe("type shapes", () => {
105
145
  commands: ["prompt", "steer"],
106
146
  },
107
147
  };
108
- assert.equal(init.protocolVersion, 2);
109
- assert.equal(init.sessionId, "sess_123");
110
- assert.ok(Array.isArray(init.capabilities.events));
111
- assert.ok(Array.isArray(init.capabilities.commands));
148
+ const parsed = roundTrip(init);
149
+ assert.deepEqual(parsed, init);
112
150
  });
113
- it("RpcExecutionCompleteEvent has required fields", () => {
151
+ it("RpcExecutionCompleteEvent round-trips preserving nested stats", () => {
114
152
  const event = {
115
153
  type: "execution_complete",
116
154
  runId: "run_abc",
@@ -127,13 +165,10 @@ describe("type shapes", () => {
127
165
  cost: 0.05,
128
166
  },
129
167
  };
130
- assert.equal(event.type, "execution_complete");
131
- assert.equal(event.runId, "run_abc");
132
- assert.equal(event.status, "completed");
133
- assert.ok(event.stats);
134
- assert.equal(event.stats.sessionId, "sess_123");
168
+ const parsed = roundTrip(event);
169
+ assert.deepEqual(parsed, event);
135
170
  });
136
- it("RpcCostUpdateEvent has required fields", () => {
171
+ it("RpcCostUpdateEvent round-trips with numeric precision intact", () => {
137
172
  const event = {
138
173
  type: "cost_update",
139
174
  runId: "run_abc",
@@ -141,13 +176,10 @@ describe("type shapes", () => {
141
176
  cumulativeCost: 0.05,
142
177
  tokens: { input: 500, output: 200, cacheRead: 100, cacheWrite: 50 },
143
178
  };
144
- assert.equal(event.type, "cost_update");
145
- assert.equal(event.runId, "run_abc");
146
- assert.equal(event.turnCost, 0.01);
147
- assert.equal(event.cumulativeCost, 0.05);
148
- assert.ok(event.tokens);
179
+ const parsed = roundTrip(event);
180
+ assert.deepEqual(parsed, event);
149
181
  });
150
- it("SessionStats has all expected fields", () => {
182
+ it("SessionStats round-trips preserving totals", () => {
151
183
  const stats = {
152
184
  sessionFile: "/tmp/session.json",
153
185
  sessionId: "s1",
@@ -157,20 +189,19 @@ describe("type shapes", () => {
157
189
  toolResults: 5,
158
190
  totalMessages: 20,
159
191
  tokens: { input: 2000, output: 1000, cacheRead: 500, cacheWrite: 200, total: 3700 },
160
- cost: 0.10,
192
+ cost: 0.1,
161
193
  };
162
- assert.equal(stats.sessionId, "s1");
163
- assert.equal(stats.userMessages, 10);
164
- assert.equal(stats.tokens.total, 3700);
165
- assert.equal(stats.cost, 0.10);
194
+ const parsed = roundTrip(stats);
195
+ assert.deepEqual(parsed, stats);
196
+ assert.equal(parsed.tokens.input + parsed.tokens.output + parsed.tokens.cacheRead + parsed.tokens.cacheWrite, parsed.tokens.total, "tokens.total should equal the sum of components after round-trip");
166
197
  });
167
- it("RpcProtocolVersion accepts 1 and 2", () => {
198
+ it("RpcProtocolVersion values 1 and 2 survive round-trip", () => {
168
199
  const v1 = 1;
169
200
  const v2 = 2;
170
- assert.equal(v1, 1);
171
- assert.equal(v2, 2);
201
+ assert.strictEqual(roundTrip({ v: v1 }).v, 1);
202
+ assert.strictEqual(roundTrip({ v: v2 }).v, 2);
172
203
  });
173
- it("RpcV2Event discriminated union covers both event types", () => {
204
+ it("RpcV2Event discriminated union survives round-trip for each arm", () => {
174
205
  const events = [
175
206
  {
176
207
  type: "execution_complete",
@@ -196,9 +227,20 @@ describe("type shapes", () => {
196
227
  tokens: { input: 100, output: 50, cacheRead: 0, cacheWrite: 0 },
197
228
  },
198
229
  ];
199
- assert.equal(events.length, 2);
200
- assert.equal(events[0].type, "execution_complete");
201
- assert.equal(events[1].type, "cost_update");
230
+ for (const evt of events) {
231
+ const parsed = roundTrip(evt);
232
+ assert.equal(parsed.type, evt.type, "discriminator must round-trip");
233
+ if (parsed.type === "execution_complete" && evt.type === "execution_complete") {
234
+ // `sessionFile: undefined` is dropped by JSON.stringify by design;
235
+ // compare the remaining observable fields.
236
+ assert.equal(parsed.runId, evt.runId);
237
+ assert.equal(parsed.status, evt.status);
238
+ assert.deepEqual(parsed.stats.tokens, evt.stats.tokens);
239
+ }
240
+ if (parsed.type === "cost_update" && evt.type === "cost_update") {
241
+ assert.deepEqual(parsed, evt);
242
+ }
243
+ }
202
244
  });
203
245
  });
204
246
  // ============================================================================
@@ -261,12 +303,14 @@ describe("events() async generator", () => {
261
303
  break;
262
304
  }
263
305
  })();
264
- // Simulate server sending events
265
- await new Promise((r) => setTimeout(r, 20));
306
+ // Drive the mock stream. The PassThrough pipeline delivers 'data'
307
+ // synchronously off the write; yielding one macrotask between writes
308
+ // lets the generator's awaiting promise resolve before we queue the
309
+ // next event, preserving the observable ordering.
266
310
  mockStdout.write(serializeJsonLine({ type: "agent_start", runId: "r1" }));
267
- await new Promise((r) => setTimeout(r, 20));
311
+ await flushIO();
268
312
  mockStdout.write(serializeJsonLine({ type: "token", text: "hello" }));
269
- await new Promise((r) => setTimeout(r, 20));
313
+ await flushIO();
270
314
  mockStdout.write(serializeJsonLine({ type: "done" }));
271
315
  await genPromise;
272
316
  assert.equal(received.length, 3);
@@ -306,10 +350,9 @@ describe("events() async generator", () => {
306
350
  received.push(event);
307
351
  }
308
352
  })();
309
- // Send one event, then simulate process exit
310
- await new Promise((r) => setTimeout(r, 20));
353
+ // Send one event, let it propagate, then simulate process exit.
311
354
  mockStdout.write(serializeJsonLine({ type: "agent_start" }));
312
- await new Promise((r) => setTimeout(r, 20));
355
+ await flushIO();
313
356
  // Fire exit handlers
314
357
  for (const h of exitHandlers)
315
358
  h();
@@ -396,9 +439,12 @@ describe("v2 command serialization", () => {
396
439
  write: (data) => {
397
440
  const parsed = JSON.parse(data.trim());
398
441
  sent.push(parsed);
399
- // Auto-respond with success after a tick
442
+ // Auto-respond on the microtask queue. This is deterministic —
443
+ // any `await` in the caller yields before the callback runs,
444
+ // so the caller's `pendingRequests` entry is installed before
445
+ // `handleLine` tries to resolve it.
400
446
  if (respondFn) {
401
- setTimeout(() => respondFn(parsed), 5);
447
+ queueMicrotask(() => respondFn(parsed));
402
448
  }
403
449
  return true;
404
450
  },
@@ -449,9 +495,13 @@ describe("v2 command serialization", () => {
449
495
  },
450
496
  };
451
497
  respondNext();
452
- // Call shutdown and simulate process exit
498
+ // Call shutdown and simulate process exit. `flushIO` drains the
499
+ // queued stdin write -> auto-respond -> handleLine chain that our
500
+ // mock triggers on every `send`, so by the time we fire the exit
501
+ // handlers the shutdown ack has been observed.
453
502
  const shutdownPromise = client.shutdown();
454
- await new Promise((r) => setTimeout(r, 20));
503
+ await flushIO();
504
+ await flushIO();
455
505
  for (const h of exitHandlers)
456
506
  h(0);
457
507
  await shutdownPromise;
@@ -1 +1 @@
1
- {"version":3,"file":"rpc-client.test.js","sourceRoot":"","sources":["../src/rpc-client.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { describe, it, beforeEach, afterEach } from \"node:test\";\nimport assert from \"node:assert/strict\";\nimport { PassThrough } from \"node:stream\";\nimport { serializeJsonLine, attachJsonlLineReader } from \"./jsonl.js\";\nimport type {\n\tRpcInitResult,\n\tRpcExecutionCompleteEvent,\n\tRpcCostUpdateEvent,\n\tRpcProtocolVersion,\n\tSessionStats,\n\tRpcV2Event,\n} from \"./rpc-types.js\";\nimport { RpcClient } from \"./rpc-client.js\";\nimport type { SdkAgentEvent } from \"./rpc-client.js\";\n\n// ============================================================================\n// JSONL Tests\n// ============================================================================\n\ndescribe(\"serializeJsonLine\", () => {\n\tit(\"produces valid JSON terminated with LF\", () => {\n\t\tconst result = serializeJsonLine({ type: \"test\", value: 42 });\n\t\tassert.ok(result.endsWith(\"\\n\"), \"must end with LF\");\n\t\tconst parsed = JSON.parse(result.trim());\n\t\tassert.equal(parsed.type, \"test\");\n\t\tassert.equal(parsed.value, 42);\n\t});\n\n\tit(\"serializes strings with special characters\", () => {\n\t\tconst result = serializeJsonLine({ msg: \"hello\\nworld\" });\n\t\tassert.ok(result.endsWith(\"\\n\"));\n\t\t// The embedded \\n must be escaped inside the JSON — only the trailing LF is the framing delimiter\n\t\tconst lines = result.split(\"\\n\");\n\t\t// Should be exactly 2 parts: the JSON line and the empty string after trailing LF\n\t\tassert.equal(lines.length, 2);\n\t\tassert.equal(lines[1], \"\");\n\t\tconst parsed = JSON.parse(lines[0]);\n\t\tassert.equal(parsed.msg, \"hello\\nworld\");\n\t});\n\n\tit(\"handles empty objects\", () => {\n\t\tconst result = serializeJsonLine({});\n\t\tassert.equal(result, \"{}\\n\");\n\t});\n});\n\ndescribe(\"attachJsonlLineReader\", () => {\n\tit(\"splits on LF correctly\", async () => {\n\t\tconst stream = new PassThrough();\n\t\tconst lines: string[] = [];\n\n\t\tattachJsonlLineReader(stream, (line) => lines.push(line));\n\n\t\tstream.write('{\"a\":1}\\n{\"b\":2}\\n');\n\t\tstream.end();\n\n\t\t// Let microtask queue flush\n\t\tawait new Promise((r) => setTimeout(r, 10));\n\n\t\tassert.equal(lines.length, 2);\n\t\tassert.equal(JSON.parse(lines[0]).a, 1);\n\t\tassert.equal(JSON.parse(lines[1]).b, 2);\n\t});\n\n\tit(\"handles chunked data across boundaries\", async () => {\n\t\tconst stream = new PassThrough();\n\t\tconst lines: string[] = [];\n\n\t\tattachJsonlLineReader(stream, (line) => lines.push(line));\n\n\t\t// Write in fragments that split mid-line\n\t\tstream.write('{\"type\":\"hel');\n\t\tstream.write('lo\"}\\n{\"type\":\"w');\n\t\tstream.write('orld\"}\\n');\n\t\tstream.end();\n\n\t\tawait new Promise((r) => setTimeout(r, 10));\n\n\t\tassert.equal(lines.length, 2);\n\t\tassert.equal(JSON.parse(lines[0]).type, \"hello\");\n\t\tassert.equal(JSON.parse(lines[1]).type, \"world\");\n\t});\n\n\tit(\"emits trailing data on stream end\", async () => {\n\t\tconst stream = new PassThrough();\n\t\tconst lines: string[] = [];\n\n\t\tattachJsonlLineReader(stream, (line) => lines.push(line));\n\n\t\tstream.write('{\"final\":true}');\n\t\tstream.end();\n\n\t\tawait new Promise((r) => setTimeout(r, 10));\n\n\t\tassert.equal(lines.length, 1);\n\t\tassert.equal(JSON.parse(lines[0]).final, true);\n\t});\n\n\tit(\"returns a detach function that stops reading\", async () => {\n\t\tconst stream = new PassThrough();\n\t\tconst lines: string[] = [];\n\n\t\tconst detach = attachJsonlLineReader(stream, (line) => lines.push(line));\n\n\t\tstream.write('{\"a\":1}\\n');\n\t\tawait new Promise((r) => setTimeout(r, 10));\n\t\tassert.equal(lines.length, 1);\n\n\t\tdetach();\n\n\t\tstream.write('{\"b\":2}\\n');\n\t\tstream.end();\n\t\tawait new Promise((r) => setTimeout(r, 10));\n\n\t\t// Should still be 1 — detach removed listeners\n\t\tassert.equal(lines.length, 1);\n\t});\n\n\tit(\"strips CR from CRLF line endings\", async () => {\n\t\tconst stream = new PassThrough();\n\t\tconst lines: string[] = [];\n\n\t\tattachJsonlLineReader(stream, (line) => lines.push(line));\n\n\t\tstream.write('{\"v\":1}\\r\\n');\n\t\tstream.end();\n\n\t\tawait new Promise((r) => setTimeout(r, 10));\n\n\t\tassert.equal(lines.length, 1);\n\t\tassert.equal(JSON.parse(lines[0]).v, 1);\n\t});\n});\n\n// ============================================================================\n// Type Shape Tests\n// ============================================================================\n\ndescribe(\"type shapes\", () => {\n\tit(\"RpcInitResult has protocolVersion, sessionId, capabilities\", () => {\n\t\tconst init: RpcInitResult = {\n\t\t\tprotocolVersion: 2,\n\t\t\tsessionId: \"sess_123\",\n\t\t\tcapabilities: {\n\t\t\t\tevents: [\"execution_complete\", \"cost_update\"],\n\t\t\t\tcommands: [\"prompt\", \"steer\"],\n\t\t\t},\n\t\t};\n\t\tassert.equal(init.protocolVersion, 2);\n\t\tassert.equal(init.sessionId, \"sess_123\");\n\t\tassert.ok(Array.isArray(init.capabilities.events));\n\t\tassert.ok(Array.isArray(init.capabilities.commands));\n\t});\n\n\tit(\"RpcExecutionCompleteEvent has required fields\", () => {\n\t\tconst event: RpcExecutionCompleteEvent = {\n\t\t\ttype: \"execution_complete\",\n\t\t\trunId: \"run_abc\",\n\t\t\tstatus: \"completed\",\n\t\t\tstats: {\n\t\t\t\tsessionFile: \"/tmp/session.json\",\n\t\t\t\tsessionId: \"sess_123\",\n\t\t\t\tuserMessages: 5,\n\t\t\t\tassistantMessages: 5,\n\t\t\t\ttoolCalls: 3,\n\t\t\t\ttoolResults: 3,\n\t\t\t\ttotalMessages: 10,\n\t\t\t\ttokens: { input: 1000, output: 500, cacheRead: 200, cacheWrite: 100, total: 1800 },\n\t\t\t\tcost: 0.05,\n\t\t\t},\n\t\t};\n\t\tassert.equal(event.type, \"execution_complete\");\n\t\tassert.equal(event.runId, \"run_abc\");\n\t\tassert.equal(event.status, \"completed\");\n\t\tassert.ok(event.stats);\n\t\tassert.equal(event.stats.sessionId, \"sess_123\");\n\t});\n\n\tit(\"RpcCostUpdateEvent has required fields\", () => {\n\t\tconst event: RpcCostUpdateEvent = {\n\t\t\ttype: \"cost_update\",\n\t\t\trunId: \"run_abc\",\n\t\t\tturnCost: 0.01,\n\t\t\tcumulativeCost: 0.05,\n\t\t\ttokens: { input: 500, output: 200, cacheRead: 100, cacheWrite: 50 },\n\t\t};\n\t\tassert.equal(event.type, \"cost_update\");\n\t\tassert.equal(event.runId, \"run_abc\");\n\t\tassert.equal(event.turnCost, 0.01);\n\t\tassert.equal(event.cumulativeCost, 0.05);\n\t\tassert.ok(event.tokens);\n\t});\n\n\tit(\"SessionStats has all expected fields\", () => {\n\t\tconst stats: SessionStats = {\n\t\t\tsessionFile: \"/tmp/session.json\",\n\t\t\tsessionId: \"s1\",\n\t\t\tuserMessages: 10,\n\t\t\tassistantMessages: 10,\n\t\t\ttoolCalls: 5,\n\t\t\ttoolResults: 5,\n\t\t\ttotalMessages: 20,\n\t\t\ttokens: { input: 2000, output: 1000, cacheRead: 500, cacheWrite: 200, total: 3700 },\n\t\t\tcost: 0.10,\n\t\t};\n\t\tassert.equal(stats.sessionId, \"s1\");\n\t\tassert.equal(stats.userMessages, 10);\n\t\tassert.equal(stats.tokens.total, 3700);\n\t\tassert.equal(stats.cost, 0.10);\n\t});\n\n\tit(\"RpcProtocolVersion accepts 1 and 2\", () => {\n\t\tconst v1: RpcProtocolVersion = 1;\n\t\tconst v2: RpcProtocolVersion = 2;\n\t\tassert.equal(v1, 1);\n\t\tassert.equal(v2, 2);\n\t});\n\n\tit(\"RpcV2Event discriminated union covers both event types\", () => {\n\t\tconst events: RpcV2Event[] = [\n\t\t\t{\n\t\t\t\ttype: \"execution_complete\",\n\t\t\t\trunId: \"r1\",\n\t\t\t\tstatus: \"completed\",\n\t\t\t\tstats: {\n\t\t\t\t\tsessionFile: undefined,\n\t\t\t\t\tsessionId: \"s1\",\n\t\t\t\t\tuserMessages: 1,\n\t\t\t\t\tassistantMessages: 1,\n\t\t\t\t\ttoolCalls: 0,\n\t\t\t\t\ttoolResults: 0,\n\t\t\t\t\ttotalMessages: 2,\n\t\t\t\t\ttokens: { input: 100, output: 50, cacheRead: 0, cacheWrite: 0, total: 150 },\n\t\t\t\t\tcost: 0.001,\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\ttype: \"cost_update\",\n\t\t\t\trunId: \"r1\",\n\t\t\t\tturnCost: 0.001,\n\t\t\t\tcumulativeCost: 0.001,\n\t\t\t\ttokens: { input: 100, output: 50, cacheRead: 0, cacheWrite: 0 },\n\t\t\t},\n\t\t];\n\t\tassert.equal(events.length, 2);\n\t\tassert.equal(events[0].type, \"execution_complete\");\n\t\tassert.equal(events[1].type, \"cost_update\");\n\t});\n});\n\n// ============================================================================\n// RpcClient Construction Tests\n// ============================================================================\n\ndescribe(\"RpcClient construction\", () => {\n\tit(\"creates with default options\", () => {\n\t\tconst client = new RpcClient();\n\t\tassert.ok(client);\n\t});\n\n\tit(\"creates with custom options\", () => {\n\t\tconst client = new RpcClient({\n\t\t\tcliPath: \"/usr/local/bin/gsd\",\n\t\t\tcwd: \"/tmp\",\n\t\t\tenv: { NODE_ENV: \"test\" },\n\t\t\tprovider: \"anthropic\",\n\t\t\tmodel: \"claude-sonnet\",\n\t\t\targs: [\"--verbose\"],\n\t\t});\n\t\tassert.ok(client);\n\t});\n});\n\n// ============================================================================\n// events() Generator Tests\n// ============================================================================\n\ndescribe(\"events() async generator\", () => {\n\tit(\"yields events from a mock stream in order\", async () => {\n\t\tconst client = new RpcClient();\n\n\t\t// Reach into the client to set up a mock process with a PassThrough stdout\n\t\tconst mockStdout = new PassThrough();\n\t\tconst mockStderr = new PassThrough();\n\t\tconst mockStdin = new PassThrough();\n\n\t\t// Simulate a started process by setting internal state\n\t\t// We use Object.assign to set private fields for testing\n\t\tconst clientAny = client as any;\n\t\tclientAny.process = {\n\t\t\tstdout: mockStdout,\n\t\t\tstderr: mockStderr,\n\t\t\tstdin: mockStdin,\n\t\t\texitCode: null,\n\t\t\tkill: () => {},\n\t\t\ton: (event: string, handler: (...args: any[]) => void) => {\n\t\t\t\tif (event === \"exit\") {\n\t\t\t\t\t// Store exit handler so we can trigger it\n\t\t\t\t\tclientAny._testExitHandler = handler;\n\t\t\t\t}\n\t\t\t},\n\t\t\tremoveListener: () => {},\n\t\t};\n\n\t\t// Attach the JSONL reader like start() does\n\t\tclientAny.stopReadingStdout = attachJsonlLineReader(mockStdout, (line: string) => {\n\t\t\tclientAny.handleLine(line);\n\t\t});\n\n\t\t// Collect events from the generator\n\t\tconst received: SdkAgentEvent[] = [];\n\t\tconst genPromise = (async () => {\n\t\t\tfor await (const event of client.events()) {\n\t\t\t\treceived.push(event);\n\t\t\t\tif (event.type === \"done\") break;\n\t\t\t}\n\t\t})();\n\n\t\t// Simulate server sending events\n\t\tawait new Promise((r) => setTimeout(r, 20));\n\t\tmockStdout.write(serializeJsonLine({ type: \"agent_start\", runId: \"r1\" }));\n\t\tawait new Promise((r) => setTimeout(r, 20));\n\t\tmockStdout.write(serializeJsonLine({ type: \"token\", text: \"hello\" }));\n\t\tawait new Promise((r) => setTimeout(r, 20));\n\t\tmockStdout.write(serializeJsonLine({ type: \"done\" }));\n\n\t\tawait genPromise;\n\n\t\tassert.equal(received.length, 3);\n\t\tassert.equal(received[0].type, \"agent_start\");\n\t\tassert.equal(received[1].type, \"token\");\n\t\tassert.equal(received[2].type, \"done\");\n\t});\n\n\tit(\"terminates when process exits\", async () => {\n\t\tconst client = new RpcClient();\n\t\tconst mockStdout = new PassThrough();\n\t\tconst mockStderr = new PassThrough();\n\t\tconst mockStdin = new PassThrough();\n\n\t\tconst exitHandlers: Array<() => void> = [];\n\t\tconst clientAny = client as any;\n\t\tclientAny.process = {\n\t\t\tstdout: mockStdout,\n\t\t\tstderr: mockStderr,\n\t\t\tstdin: mockStdin,\n\t\t\texitCode: null,\n\t\t\tkill: () => {},\n\t\t\ton: (event: string, handler: () => void) => {\n\t\t\t\tif (event === \"exit\") exitHandlers.push(handler);\n\t\t\t},\n\t\t\tremoveListener: (event: string, handler: () => void) => {\n\t\t\t\tconst idx = exitHandlers.indexOf(handler);\n\t\t\t\tif (idx !== -1) exitHandlers.splice(idx, 1);\n\t\t\t},\n\t\t};\n\n\t\tclientAny.stopReadingStdout = attachJsonlLineReader(mockStdout, (line: string) => {\n\t\t\tclientAny.handleLine(line);\n\t\t});\n\n\t\tconst received: SdkAgentEvent[] = [];\n\t\tconst genPromise = (async () => {\n\t\t\tfor await (const event of client.events()) {\n\t\t\t\treceived.push(event);\n\t\t\t}\n\t\t})();\n\n\t\t// Send one event, then simulate process exit\n\t\tawait new Promise((r) => setTimeout(r, 20));\n\t\tmockStdout.write(serializeJsonLine({ type: \"agent_start\" }));\n\t\tawait new Promise((r) => setTimeout(r, 20));\n\n\t\t// Fire exit handlers\n\t\tfor (const h of exitHandlers) h();\n\n\t\tawait genPromise;\n\n\t\tassert.equal(received.length, 1);\n\t\tassert.equal(received[0].type, \"agent_start\");\n\t});\n\n\tit(\"throws if client not started\", async () => {\n\t\tconst client = new RpcClient();\n\t\tawait assert.rejects(async () => {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unused-vars\n\t\t\tfor await (const _event of client.events()) {\n\t\t\t\t// should not reach\n\t\t\t}\n\t\t}, /Client not started/);\n\t});\n});\n\n// ============================================================================\n// sendUIResponse Serialization Test\n// ============================================================================\n\ndescribe(\"sendUIResponse serialization\", () => {\n\tit(\"writes correct JSONL to stdin\", () => {\n\t\tconst client = new RpcClient();\n\t\tconst chunks: string[] = [];\n\t\tconst mockStdin = {\n\t\t\twrite: (data: string) => {\n\t\t\t\tchunks.push(data);\n\t\t\t\treturn true;\n\t\t\t},\n\t\t};\n\n\t\tconst clientAny = client as any;\n\t\tclientAny.process = { stdin: mockStdin };\n\n\t\tclient.sendUIResponse(\"ui_1\", { value: \"hello\" });\n\n\t\tassert.equal(chunks.length, 1);\n\t\tconst parsed = JSON.parse(chunks[0].trim());\n\t\tassert.equal(parsed.type, \"extension_ui_response\");\n\t\tassert.equal(parsed.id, \"ui_1\");\n\t\tassert.equal(parsed.value, \"hello\");\n\t});\n\n\tit(\"serializes confirmed response\", () => {\n\t\tconst client = new RpcClient();\n\t\tconst chunks: string[] = [];\n\t\tconst mockStdin = {\n\t\t\twrite: (data: string) => {\n\t\t\t\tchunks.push(data);\n\t\t\t\treturn true;\n\t\t\t},\n\t\t};\n\t\tconst clientAny = client as any;\n\t\tclientAny.process = { stdin: mockStdin };\n\n\t\tclient.sendUIResponse(\"ui_2\", { confirmed: true });\n\n\t\tconst parsed = JSON.parse(chunks[0].trim());\n\t\tassert.equal(parsed.confirmed, true);\n\t\tassert.equal(parsed.id, \"ui_2\");\n\t});\n\n\tit(\"serializes cancelled response\", () => {\n\t\tconst client = new RpcClient();\n\t\tconst chunks: string[] = [];\n\t\tconst mockStdin = {\n\t\t\twrite: (data: string) => {\n\t\t\t\tchunks.push(data);\n\t\t\t\treturn true;\n\t\t\t},\n\t\t};\n\t\tconst clientAny = client as any;\n\t\tclientAny.process = { stdin: mockStdin };\n\n\t\tclient.sendUIResponse(\"ui_3\", { cancelled: true });\n\n\t\tconst parsed = JSON.parse(chunks[0].trim());\n\t\tassert.equal(parsed.cancelled, true);\n\t});\n});\n\n// ============================================================================\n// init/shutdown/subscribe Serialization Tests\n// ============================================================================\n\ndescribe(\"v2 command serialization\", () => {\n\t// Helper: capture what the client sends to stdin\n\tfunction createMockClient(): { client: RpcClient; sent: any[]; respondNext: (data?: any) => void } {\n\t\tconst client = new RpcClient();\n\t\tconst sent: any[] = [];\n\t\tlet respondFn: ((data: any) => void) | null = null;\n\n\t\tconst clientAny = client as any;\n\t\tclientAny.process = {\n\t\t\tstdin: {\n\t\t\t\twrite: (data: string) => {\n\t\t\t\t\tconst parsed = JSON.parse(data.trim());\n\t\t\t\t\tsent.push(parsed);\n\t\t\t\t\t// Auto-respond with success after a tick\n\t\t\t\t\tif (respondFn) {\n\t\t\t\t\t\tsetTimeout(() => respondFn!(parsed), 5);\n\t\t\t\t\t}\n\t\t\t\t\treturn true;\n\t\t\t\t},\n\t\t\t},\n\t\t\tstderr: new PassThrough(),\n\t\t\texitCode: null,\n\t\t\tkill: () => {},\n\t\t\ton: () => {},\n\t\t\tremoveListener: () => {},\n\t\t};\n\n\t\tconst respondNext = (overrides: any = {}) => {\n\t\t\trespondFn = (parsed) => {\n\t\t\t\tconst response = {\n\t\t\t\t\ttype: \"response\",\n\t\t\t\t\tid: parsed.id,\n\t\t\t\t\tcommand: parsed.type,\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\tdata: {},\n\t\t\t\t\t...overrides,\n\t\t\t\t};\n\t\t\t\tclientAny.handleLine(JSON.stringify(response));\n\t\t\t};\n\t\t};\n\n\t\treturn { client, sent, respondNext };\n\t}\n\n\tit(\"init sends correct v2 init command\", async () => {\n\t\tconst { client, sent, respondNext } = createMockClient();\n\t\trespondNext({ data: { protocolVersion: 2, sessionId: \"s1\", capabilities: { events: [], commands: [] } } });\n\n\t\tconst result = await client.init({ clientId: \"test-app\" });\n\n\t\tassert.equal(sent.length, 1);\n\t\tassert.equal(sent[0].type, \"init\");\n\t\tassert.equal(sent[0].protocolVersion, 2);\n\t\tassert.equal(sent[0].clientId, \"test-app\");\n\t\tassert.equal(result.protocolVersion, 2);\n\t\tassert.equal(result.sessionId, \"s1\");\n\t});\n\n\tit(\"shutdown sends shutdown command\", async () => {\n\t\tconst { client, sent, respondNext } = createMockClient();\n\n\t\t// Override the process exit wait\n\t\tconst clientAny = client as any;\n\t\tconst originalProcess = clientAny.process;\n\t\tconst exitHandlers: Array<(code: number) => void> = [];\n\t\tclientAny.process = {\n\t\t\t...originalProcess,\n\t\t\ton: (event: string, handler: (code: number) => void) => {\n\t\t\t\tif (event === \"exit\") exitHandlers.push(handler);\n\t\t\t},\n\t\t};\n\n\t\trespondNext();\n\n\t\t// Call shutdown and simulate process exit\n\t\tconst shutdownPromise = client.shutdown();\n\t\tawait new Promise((r) => setTimeout(r, 20));\n\t\tfor (const h of exitHandlers) h(0);\n\n\t\tawait shutdownPromise;\n\n\t\tassert.equal(sent.length, 1);\n\t\tassert.equal(sent[0].type, \"shutdown\");\n\t});\n\n\tit(\"subscribe sends subscribe command with event list\", async () => {\n\t\tconst { client, sent, respondNext } = createMockClient();\n\t\trespondNext();\n\n\t\tawait client.subscribe([\"execution_complete\", \"cost_update\"]);\n\n\t\tassert.equal(sent.length, 1);\n\t\tassert.equal(sent[0].type, \"subscribe\");\n\t\tassert.deepEqual(sent[0].events, [\"execution_complete\", \"cost_update\"]);\n\t});\n\n\tit(\"subscribe with wildcard\", async () => {\n\t\tconst { client, sent, respondNext } = createMockClient();\n\t\trespondNext();\n\n\t\tawait client.subscribe([\"*\"]);\n\n\t\tassert.equal(sent[0].events.length, 1);\n\t\tassert.equal(sent[0].events[0], \"*\");\n\t});\n});\n"]}
1
+ {"version":3,"file":"rpc-client.test.js","sourceRoot":"","sources":["../src/rpc-client.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { describe, it } from \"node:test\";\nimport assert from \"node:assert/strict\";\nimport { PassThrough } from \"node:stream\";\nimport { once } from \"node:events\";\nimport { serializeJsonLine, attachJsonlLineReader } from \"./jsonl.js\";\nimport type {\n\tRpcInitResult,\n\tRpcExecutionCompleteEvent,\n\tRpcCostUpdateEvent,\n\tRpcProtocolVersion,\n\tSessionStats,\n\tRpcV2Event,\n} from \"./rpc-types.js\";\nimport { RpcClient } from \"./rpc-client.js\";\nimport type { SdkAgentEvent } from \"./rpc-client.js\";\n\n/**\n * Flush pending microtasks and one turn of the macrotask queue.\n *\n * Used in places where the test needs \"every already-queued stream event has\n * been delivered\" — cheaper than a wall-clock sleep and deterministic because\n * `setImmediate` runs strictly after any I/O callbacks already queued by a\n * synchronous `stream.write(...)`.\n */\nfunction flushIO(): Promise<void> {\n\treturn new Promise((resolve) => setImmediate(resolve));\n}\n\n// ============================================================================\n// JSONL Tests\n// ============================================================================\n\ndescribe(\"serializeJsonLine\", () => {\n\tit(\"produces valid JSON terminated with LF\", () => {\n\t\tconst result = serializeJsonLine({ type: \"test\", value: 42 });\n\t\tassert.ok(result.endsWith(\"\\n\"), \"must end with LF\");\n\t\tconst parsed = JSON.parse(result.trim());\n\t\tassert.equal(parsed.type, \"test\");\n\t\tassert.equal(parsed.value, 42);\n\t});\n\n\tit(\"serializes strings with special characters\", () => {\n\t\tconst result = serializeJsonLine({ msg: \"hello\\nworld\" });\n\t\tassert.ok(result.endsWith(\"\\n\"));\n\t\t// The embedded \\n must be escaped inside the JSON — only the trailing LF is the framing delimiter\n\t\tconst lines = result.split(\"\\n\");\n\t\t// Should be exactly 2 parts: the JSON line and the empty string after trailing LF\n\t\tassert.equal(lines.length, 2);\n\t\tassert.equal(lines[1], \"\");\n\t\tconst parsed = JSON.parse(lines[0]);\n\t\tassert.equal(parsed.msg, \"hello\\nworld\");\n\t});\n\n\tit(\"handles empty objects\", () => {\n\t\tconst result = serializeJsonLine({});\n\t\tassert.equal(result, \"{}\\n\");\n\t});\n});\n\ndescribe(\"attachJsonlLineReader\", () => {\n\tit(\"splits on LF correctly\", async () => {\n\t\tconst stream = new PassThrough();\n\t\tconst lines: string[] = [];\n\n\t\tattachJsonlLineReader(stream, (line) => lines.push(line));\n\n\t\tstream.write('{\"a\":1}\\n{\"b\":2}\\n');\n\t\tstream.end();\n\n\t\t// The reader registers its `end` listener first; awaiting `end` here\n\t\t// runs strictly after the reader has drained any trailing buffer.\n\t\tawait once(stream, \"end\");\n\n\t\tassert.equal(lines.length, 2);\n\t\tassert.equal(JSON.parse(lines[0]).a, 1);\n\t\tassert.equal(JSON.parse(lines[1]).b, 2);\n\t});\n\n\tit(\"handles chunked data across boundaries\", async () => {\n\t\tconst stream = new PassThrough();\n\t\tconst lines: string[] = [];\n\n\t\tattachJsonlLineReader(stream, (line) => lines.push(line));\n\n\t\t// Write in fragments that split mid-line\n\t\tstream.write('{\"type\":\"hel');\n\t\tstream.write('lo\"}\\n{\"type\":\"w');\n\t\tstream.write('orld\"}\\n');\n\t\tstream.end();\n\n\t\tawait once(stream, \"end\");\n\n\t\tassert.equal(lines.length, 2);\n\t\tassert.equal(JSON.parse(lines[0]).type, \"hello\");\n\t\tassert.equal(JSON.parse(lines[1]).type, \"world\");\n\t});\n\n\tit(\"emits trailing data on stream end\", async () => {\n\t\tconst stream = new PassThrough();\n\t\tconst lines: string[] = [];\n\n\t\tattachJsonlLineReader(stream, (line) => lines.push(line));\n\n\t\tstream.write('{\"final\":true}');\n\t\tstream.end();\n\n\t\tawait once(stream, \"end\");\n\n\t\tassert.equal(lines.length, 1);\n\t\tassert.equal(JSON.parse(lines[0]).final, true);\n\t});\n\n\tit(\"returns a detach function that stops reading\", async () => {\n\t\tconst stream = new PassThrough();\n\t\tconst lines: string[] = [];\n\n\t\t// Use an explicit promise to signal \"first line has been observed\".\n\t\t// This is deterministic — we resume exactly when the reader fires the\n\t\t// callback, not after an arbitrary wall-clock delay.\n\t\tlet signalFirstLine!: () => void;\n\t\tconst firstLineSeen = new Promise<void>((resolve) => {\n\t\t\tsignalFirstLine = resolve;\n\t\t});\n\n\t\tconst detach = attachJsonlLineReader(stream, (line) => {\n\t\t\tlines.push(line);\n\t\t\tif (lines.length === 1) signalFirstLine();\n\t\t});\n\n\t\tstream.write('{\"a\":1}\\n');\n\t\tawait firstLineSeen;\n\t\tassert.equal(lines.length, 1);\n\n\t\tdetach();\n\n\t\tstream.write('{\"b\":2}\\n');\n\t\tstream.end();\n\t\t// Drain any queued data events post-detach. `setImmediate` runs strictly\n\t\t// after any 'data' events that were already queued by the write above.\n\t\tawait flushIO();\n\n\t\t// Should still be 1 — detach removed listeners\n\t\tassert.equal(lines.length, 1);\n\t});\n\n\tit(\"strips CR from CRLF line endings\", async () => {\n\t\tconst stream = new PassThrough();\n\t\tconst lines: string[] = [];\n\n\t\tattachJsonlLineReader(stream, (line) => lines.push(line));\n\n\t\tstream.write('{\"v\":1}\\r\\n');\n\t\tstream.end();\n\n\t\tawait once(stream, \"end\");\n\n\t\tassert.equal(lines.length, 1);\n\t\tassert.equal(JSON.parse(lines[0]).v, 1);\n\t});\n});\n\n// ============================================================================\n// JSONL Round-Trip Tests\n//\n// These previously lived under a \"type shapes\" block that only asserted that\n// a typed literal retained its own field values — pure type-system\n// tautologies. They are now replaced with round-trips through\n// `serializeJsonLine` + `JSON.parse`, which exercises the actual framing\n// pipeline the wire protocol uses. A regression where `serializeJsonLine`\n// mangles payloads or the LF terminator will now fail these tests.\n// ============================================================================\n\ndescribe(\"JSONL round-trip of v2 payloads\", () => {\n\tfunction roundTrip<T>(value: T): T {\n\t\tconst serialized = serializeJsonLine(value);\n\t\tassert.ok(serialized.endsWith(\"\\n\"), \"wire format must terminate with LF\");\n\t\t// Ensure we did not emit embedded unescaped LFs that would corrupt framing\n\t\tassert.equal(serialized.indexOf(\"\\n\"), serialized.length - 1, \"no unescaped LF inside payload\");\n\t\treturn JSON.parse(serialized.trim()) as T;\n\t}\n\n\tit(\"RpcInitResult round-trips through serializeJsonLine\", () => {\n\t\tconst init: RpcInitResult = {\n\t\t\tprotocolVersion: 2,\n\t\t\tsessionId: \"sess_123\",\n\t\t\tcapabilities: {\n\t\t\t\tevents: [\"execution_complete\", \"cost_update\"],\n\t\t\t\tcommands: [\"prompt\", \"steer\"],\n\t\t\t},\n\t\t};\n\t\tconst parsed = roundTrip(init);\n\t\tassert.deepEqual(parsed, init);\n\t});\n\n\tit(\"RpcExecutionCompleteEvent round-trips preserving nested stats\", () => {\n\t\tconst event: RpcExecutionCompleteEvent = {\n\t\t\ttype: \"execution_complete\",\n\t\t\trunId: \"run_abc\",\n\t\t\tstatus: \"completed\",\n\t\t\tstats: {\n\t\t\t\tsessionFile: \"/tmp/session.json\",\n\t\t\t\tsessionId: \"sess_123\",\n\t\t\t\tuserMessages: 5,\n\t\t\t\tassistantMessages: 5,\n\t\t\t\ttoolCalls: 3,\n\t\t\t\ttoolResults: 3,\n\t\t\t\ttotalMessages: 10,\n\t\t\t\ttokens: { input: 1000, output: 500, cacheRead: 200, cacheWrite: 100, total: 1800 },\n\t\t\t\tcost: 0.05,\n\t\t\t},\n\t\t};\n\t\tconst parsed = roundTrip(event);\n\t\tassert.deepEqual(parsed, event);\n\t});\n\n\tit(\"RpcCostUpdateEvent round-trips with numeric precision intact\", () => {\n\t\tconst event: RpcCostUpdateEvent = {\n\t\t\ttype: \"cost_update\",\n\t\t\trunId: \"run_abc\",\n\t\t\tturnCost: 0.01,\n\t\t\tcumulativeCost: 0.05,\n\t\t\ttokens: { input: 500, output: 200, cacheRead: 100, cacheWrite: 50 },\n\t\t};\n\t\tconst parsed = roundTrip(event);\n\t\tassert.deepEqual(parsed, event);\n\t});\n\n\tit(\"SessionStats round-trips preserving totals\", () => {\n\t\tconst stats: SessionStats = {\n\t\t\tsessionFile: \"/tmp/session.json\",\n\t\t\tsessionId: \"s1\",\n\t\t\tuserMessages: 10,\n\t\t\tassistantMessages: 10,\n\t\t\ttoolCalls: 5,\n\t\t\ttoolResults: 5,\n\t\t\ttotalMessages: 20,\n\t\t\ttokens: { input: 2000, output: 1000, cacheRead: 500, cacheWrite: 200, total: 3700 },\n\t\t\tcost: 0.1,\n\t\t};\n\t\tconst parsed = roundTrip(stats);\n\t\tassert.deepEqual(parsed, stats);\n\t\tassert.equal(\n\t\t\tparsed.tokens.input + parsed.tokens.output + parsed.tokens.cacheRead + parsed.tokens.cacheWrite,\n\t\t\tparsed.tokens.total,\n\t\t\t\"tokens.total should equal the sum of components after round-trip\",\n\t\t);\n\t});\n\n\tit(\"RpcProtocolVersion values 1 and 2 survive round-trip\", () => {\n\t\tconst v1: RpcProtocolVersion = 1;\n\t\tconst v2: RpcProtocolVersion = 2;\n\t\tassert.strictEqual(roundTrip({ v: v1 }).v, 1);\n\t\tassert.strictEqual(roundTrip({ v: v2 }).v, 2);\n\t});\n\n\tit(\"RpcV2Event discriminated union survives round-trip for each arm\", () => {\n\t\tconst events: RpcV2Event[] = [\n\t\t\t{\n\t\t\t\ttype: \"execution_complete\",\n\t\t\t\trunId: \"r1\",\n\t\t\t\tstatus: \"completed\",\n\t\t\t\tstats: {\n\t\t\t\t\tsessionFile: undefined,\n\t\t\t\t\tsessionId: \"s1\",\n\t\t\t\t\tuserMessages: 1,\n\t\t\t\t\tassistantMessages: 1,\n\t\t\t\t\ttoolCalls: 0,\n\t\t\t\t\ttoolResults: 0,\n\t\t\t\t\ttotalMessages: 2,\n\t\t\t\t\ttokens: { input: 100, output: 50, cacheRead: 0, cacheWrite: 0, total: 150 },\n\t\t\t\t\tcost: 0.001,\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\ttype: \"cost_update\",\n\t\t\t\trunId: \"r1\",\n\t\t\t\tturnCost: 0.001,\n\t\t\t\tcumulativeCost: 0.001,\n\t\t\t\ttokens: { input: 100, output: 50, cacheRead: 0, cacheWrite: 0 },\n\t\t\t},\n\t\t];\n\n\t\tfor (const evt of events) {\n\t\t\tconst parsed = roundTrip(evt);\n\t\t\tassert.equal(parsed.type, evt.type, \"discriminator must round-trip\");\n\t\t\tif (parsed.type === \"execution_complete\" && evt.type === \"execution_complete\") {\n\t\t\t\t// `sessionFile: undefined` is dropped by JSON.stringify by design;\n\t\t\t\t// compare the remaining observable fields.\n\t\t\t\tassert.equal(parsed.runId, evt.runId);\n\t\t\t\tassert.equal(parsed.status, evt.status);\n\t\t\t\tassert.deepEqual(parsed.stats.tokens, evt.stats.tokens);\n\t\t\t}\n\t\t\tif (parsed.type === \"cost_update\" && evt.type === \"cost_update\") {\n\t\t\t\tassert.deepEqual(parsed, evt);\n\t\t\t}\n\t\t}\n\t});\n});\n\n// ============================================================================\n// RpcClient Construction Tests\n// ============================================================================\n\ndescribe(\"RpcClient construction\", () => {\n\tit(\"creates with default options\", () => {\n\t\tconst client = new RpcClient();\n\t\tassert.ok(client);\n\t});\n\n\tit(\"creates with custom options\", () => {\n\t\tconst client = new RpcClient({\n\t\t\tcliPath: \"/usr/local/bin/gsd\",\n\t\t\tcwd: \"/tmp\",\n\t\t\tenv: { NODE_ENV: \"test\" },\n\t\t\tprovider: \"anthropic\",\n\t\t\tmodel: \"claude-sonnet\",\n\t\t\targs: [\"--verbose\"],\n\t\t});\n\t\tassert.ok(client);\n\t});\n});\n\n// ============================================================================\n// events() Generator Tests\n// ============================================================================\n\ndescribe(\"events() async generator\", () => {\n\tit(\"yields events from a mock stream in order\", async () => {\n\t\tconst client = new RpcClient();\n\n\t\t// Reach into the client to set up a mock process with a PassThrough stdout\n\t\tconst mockStdout = new PassThrough();\n\t\tconst mockStderr = new PassThrough();\n\t\tconst mockStdin = new PassThrough();\n\n\t\t// Simulate a started process by setting internal state\n\t\t// We use Object.assign to set private fields for testing\n\t\tconst clientAny = client as any;\n\t\tclientAny.process = {\n\t\t\tstdout: mockStdout,\n\t\t\tstderr: mockStderr,\n\t\t\tstdin: mockStdin,\n\t\t\texitCode: null,\n\t\t\tkill: () => {},\n\t\t\ton: (event: string, handler: (...args: any[]) => void) => {\n\t\t\t\tif (event === \"exit\") {\n\t\t\t\t\t// Store exit handler so we can trigger it\n\t\t\t\t\tclientAny._testExitHandler = handler;\n\t\t\t\t}\n\t\t\t},\n\t\t\tremoveListener: () => {},\n\t\t};\n\n\t\t// Attach the JSONL reader like start() does\n\t\tclientAny.stopReadingStdout = attachJsonlLineReader(mockStdout, (line: string) => {\n\t\t\tclientAny.handleLine(line);\n\t\t});\n\n\t\t// Collect events from the generator\n\t\tconst received: SdkAgentEvent[] = [];\n\t\tconst genPromise = (async () => {\n\t\t\tfor await (const event of client.events()) {\n\t\t\t\treceived.push(event);\n\t\t\t\tif (event.type === \"done\") break;\n\t\t\t}\n\t\t})();\n\n\t\t// Drive the mock stream. The PassThrough pipeline delivers 'data'\n\t\t// synchronously off the write; yielding one macrotask between writes\n\t\t// lets the generator's awaiting promise resolve before we queue the\n\t\t// next event, preserving the observable ordering.\n\t\tmockStdout.write(serializeJsonLine({ type: \"agent_start\", runId: \"r1\" }));\n\t\tawait flushIO();\n\t\tmockStdout.write(serializeJsonLine({ type: \"token\", text: \"hello\" }));\n\t\tawait flushIO();\n\t\tmockStdout.write(serializeJsonLine({ type: \"done\" }));\n\n\t\tawait genPromise;\n\n\t\tassert.equal(received.length, 3);\n\t\tassert.equal(received[0].type, \"agent_start\");\n\t\tassert.equal(received[1].type, \"token\");\n\t\tassert.equal(received[2].type, \"done\");\n\t});\n\n\tit(\"terminates when process exits\", async () => {\n\t\tconst client = new RpcClient();\n\t\tconst mockStdout = new PassThrough();\n\t\tconst mockStderr = new PassThrough();\n\t\tconst mockStdin = new PassThrough();\n\n\t\tconst exitHandlers: Array<() => void> = [];\n\t\tconst clientAny = client as any;\n\t\tclientAny.process = {\n\t\t\tstdout: mockStdout,\n\t\t\tstderr: mockStderr,\n\t\t\tstdin: mockStdin,\n\t\t\texitCode: null,\n\t\t\tkill: () => {},\n\t\t\ton: (event: string, handler: () => void) => {\n\t\t\t\tif (event === \"exit\") exitHandlers.push(handler);\n\t\t\t},\n\t\t\tremoveListener: (event: string, handler: () => void) => {\n\t\t\t\tconst idx = exitHandlers.indexOf(handler);\n\t\t\t\tif (idx !== -1) exitHandlers.splice(idx, 1);\n\t\t\t},\n\t\t};\n\n\t\tclientAny.stopReadingStdout = attachJsonlLineReader(mockStdout, (line: string) => {\n\t\t\tclientAny.handleLine(line);\n\t\t});\n\n\t\tconst received: SdkAgentEvent[] = [];\n\t\tconst genPromise = (async () => {\n\t\t\tfor await (const event of client.events()) {\n\t\t\t\treceived.push(event);\n\t\t\t}\n\t\t})();\n\n\t\t// Send one event, let it propagate, then simulate process exit.\n\t\tmockStdout.write(serializeJsonLine({ type: \"agent_start\" }));\n\t\tawait flushIO();\n\n\t\t// Fire exit handlers\n\t\tfor (const h of exitHandlers) h();\n\n\t\tawait genPromise;\n\n\t\tassert.equal(received.length, 1);\n\t\tassert.equal(received[0].type, \"agent_start\");\n\t});\n\n\tit(\"throws if client not started\", async () => {\n\t\tconst client = new RpcClient();\n\t\tawait assert.rejects(async () => {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unused-vars\n\t\t\tfor await (const _event of client.events()) {\n\t\t\t\t// should not reach\n\t\t\t}\n\t\t}, /Client not started/);\n\t});\n});\n\n// ============================================================================\n// sendUIResponse Serialization Test\n// ============================================================================\n\ndescribe(\"sendUIResponse serialization\", () => {\n\tit(\"writes correct JSONL to stdin\", () => {\n\t\tconst client = new RpcClient();\n\t\tconst chunks: string[] = [];\n\t\tconst mockStdin = {\n\t\t\twrite: (data: string) => {\n\t\t\t\tchunks.push(data);\n\t\t\t\treturn true;\n\t\t\t},\n\t\t};\n\n\t\tconst clientAny = client as any;\n\t\tclientAny.process = { stdin: mockStdin };\n\n\t\tclient.sendUIResponse(\"ui_1\", { value: \"hello\" });\n\n\t\tassert.equal(chunks.length, 1);\n\t\tconst parsed = JSON.parse(chunks[0].trim());\n\t\tassert.equal(parsed.type, \"extension_ui_response\");\n\t\tassert.equal(parsed.id, \"ui_1\");\n\t\tassert.equal(parsed.value, \"hello\");\n\t});\n\n\tit(\"serializes confirmed response\", () => {\n\t\tconst client = new RpcClient();\n\t\tconst chunks: string[] = [];\n\t\tconst mockStdin = {\n\t\t\twrite: (data: string) => {\n\t\t\t\tchunks.push(data);\n\t\t\t\treturn true;\n\t\t\t},\n\t\t};\n\t\tconst clientAny = client as any;\n\t\tclientAny.process = { stdin: mockStdin };\n\n\t\tclient.sendUIResponse(\"ui_2\", { confirmed: true });\n\n\t\tconst parsed = JSON.parse(chunks[0].trim());\n\t\tassert.equal(parsed.confirmed, true);\n\t\tassert.equal(parsed.id, \"ui_2\");\n\t});\n\n\tit(\"serializes cancelled response\", () => {\n\t\tconst client = new RpcClient();\n\t\tconst chunks: string[] = [];\n\t\tconst mockStdin = {\n\t\t\twrite: (data: string) => {\n\t\t\t\tchunks.push(data);\n\t\t\t\treturn true;\n\t\t\t},\n\t\t};\n\t\tconst clientAny = client as any;\n\t\tclientAny.process = { stdin: mockStdin };\n\n\t\tclient.sendUIResponse(\"ui_3\", { cancelled: true });\n\n\t\tconst parsed = JSON.parse(chunks[0].trim());\n\t\tassert.equal(parsed.cancelled, true);\n\t});\n});\n\n// ============================================================================\n// init/shutdown/subscribe Serialization Tests\n// ============================================================================\n\ndescribe(\"v2 command serialization\", () => {\n\t// Helper: capture what the client sends to stdin\n\tfunction createMockClient(): { client: RpcClient; sent: any[]; respondNext: (data?: any) => void } {\n\t\tconst client = new RpcClient();\n\t\tconst sent: any[] = [];\n\t\tlet respondFn: ((data: any) => void) | null = null;\n\n\t\tconst clientAny = client as any;\n\t\tclientAny.process = {\n\t\t\tstdin: {\n\t\t\t\twrite: (data: string) => {\n\t\t\t\t\tconst parsed = JSON.parse(data.trim());\n\t\t\t\t\tsent.push(parsed);\n\t\t\t\t\t// Auto-respond on the microtask queue. This is deterministic —\n\t\t\t\t\t// any `await` in the caller yields before the callback runs,\n\t\t\t\t\t// so the caller's `pendingRequests` entry is installed before\n\t\t\t\t\t// `handleLine` tries to resolve it.\n\t\t\t\t\tif (respondFn) {\n\t\t\t\t\t\tqueueMicrotask(() => respondFn!(parsed));\n\t\t\t\t\t}\n\t\t\t\t\treturn true;\n\t\t\t\t},\n\t\t\t},\n\t\t\tstderr: new PassThrough(),\n\t\t\texitCode: null,\n\t\t\tkill: () => {},\n\t\t\ton: () => {},\n\t\t\tremoveListener: () => {},\n\t\t};\n\n\t\tconst respondNext = (overrides: any = {}) => {\n\t\t\trespondFn = (parsed) => {\n\t\t\t\tconst response = {\n\t\t\t\t\ttype: \"response\",\n\t\t\t\t\tid: parsed.id,\n\t\t\t\t\tcommand: parsed.type,\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\tdata: {},\n\t\t\t\t\t...overrides,\n\t\t\t\t};\n\t\t\t\tclientAny.handleLine(JSON.stringify(response));\n\t\t\t};\n\t\t};\n\n\t\treturn { client, sent, respondNext };\n\t}\n\n\tit(\"init sends correct v2 init command\", async () => {\n\t\tconst { client, sent, respondNext } = createMockClient();\n\t\trespondNext({ data: { protocolVersion: 2, sessionId: \"s1\", capabilities: { events: [], commands: [] } } });\n\n\t\tconst result = await client.init({ clientId: \"test-app\" });\n\n\t\tassert.equal(sent.length, 1);\n\t\tassert.equal(sent[0].type, \"init\");\n\t\tassert.equal(sent[0].protocolVersion, 2);\n\t\tassert.equal(sent[0].clientId, \"test-app\");\n\t\tassert.equal(result.protocolVersion, 2);\n\t\tassert.equal(result.sessionId, \"s1\");\n\t});\n\n\tit(\"shutdown sends shutdown command\", async () => {\n\t\tconst { client, sent, respondNext } = createMockClient();\n\n\t\t// Override the process exit wait\n\t\tconst clientAny = client as any;\n\t\tconst originalProcess = clientAny.process;\n\t\tconst exitHandlers: Array<(code: number) => void> = [];\n\t\tclientAny.process = {\n\t\t\t...originalProcess,\n\t\t\ton: (event: string, handler: (code: number) => void) => {\n\t\t\t\tif (event === \"exit\") exitHandlers.push(handler);\n\t\t\t},\n\t\t};\n\n\t\trespondNext();\n\n\t\t// Call shutdown and simulate process exit. `flushIO` drains the\n\t\t// queued stdin write -> auto-respond -> handleLine chain that our\n\t\t// mock triggers on every `send`, so by the time we fire the exit\n\t\t// handlers the shutdown ack has been observed.\n\t\tconst shutdownPromise = client.shutdown();\n\t\tawait flushIO();\n\t\tawait flushIO();\n\t\tfor (const h of exitHandlers) h(0);\n\n\t\tawait shutdownPromise;\n\n\t\tassert.equal(sent.length, 1);\n\t\tassert.equal(sent[0].type, \"shutdown\");\n\t});\n\n\tit(\"subscribe sends subscribe command with event list\", async () => {\n\t\tconst { client, sent, respondNext } = createMockClient();\n\t\trespondNext();\n\n\t\tawait client.subscribe([\"execution_complete\", \"cost_update\"]);\n\n\t\tassert.equal(sent.length, 1);\n\t\tassert.equal(sent[0].type, \"subscribe\");\n\t\tassert.deepEqual(sent[0].events, [\"execution_complete\", \"cost_update\"]);\n\t});\n\n\tit(\"subscribe with wildcard\", async () => {\n\t\tconst { client, sent, respondNext } = createMockClient();\n\t\trespondNext();\n\n\t\tawait client.subscribe([\"*\"]);\n\n\t\tassert.equal(sent[0].events.length, 1);\n\t\tassert.equal(sent[0].events[0], \"*\");\n\t});\n});\n"]}
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gsd-build/rpc-client",
3
- "version": "2.77.0",
3
+ "version": "2.78.0",
4
4
  "description": "Standalone RPC client SDK for GSD — zero internal dependencies",
5
5
  "license": "MIT",
6
6
  "gsd": {