@tickernelz/paperclip-pro-adapter-utils 2026.925.0

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 (1826) hide show
  1. package/README.md +37 -0
  2. package/dist/acpx-engine/cli.d.ts +2 -0
  3. package/dist/acpx-engine/cli.d.ts.map +1 -0
  4. package/dist/acpx-engine/cli.js +128 -0
  5. package/dist/acpx-engine/cli.js.map +1 -0
  6. package/dist/acpx-engine/composed-run-characterization.test.d.ts +2 -0
  7. package/dist/acpx-engine/composed-run-characterization.test.d.ts.map +1 -0
  8. package/dist/acpx-engine/composed-run-characterization.test.js +739 -0
  9. package/dist/acpx-engine/composed-run-characterization.test.js.map +1 -0
  10. package/dist/acpx-engine/constants.d.ts +20 -0
  11. package/dist/acpx-engine/constants.d.ts.map +1 -0
  12. package/dist/acpx-engine/constants.js +37 -0
  13. package/dist/acpx-engine/constants.js.map +1 -0
  14. package/dist/acpx-engine/execute-identity.test.d.ts +2 -0
  15. package/dist/acpx-engine/execute-identity.test.d.ts.map +1 -0
  16. package/dist/acpx-engine/execute-identity.test.js +218 -0
  17. package/dist/acpx-engine/execute-identity.test.js.map +1 -0
  18. package/dist/acpx-engine/execute.d.ts +325 -0
  19. package/dist/acpx-engine/execute.d.ts.map +1 -0
  20. package/dist/acpx-engine/execute.js +4448 -0
  21. package/dist/acpx-engine/execute.js.map +1 -0
  22. package/dist/acpx-engine/execute.test.d.ts +2 -0
  23. package/dist/acpx-engine/execute.test.d.ts.map +1 -0
  24. package/dist/acpx-engine/execute.test.js +6694 -0
  25. package/dist/acpx-engine/execute.test.js.map +1 -0
  26. package/dist/acpx-engine/index.d.ts +6 -0
  27. package/dist/acpx-engine/index.d.ts.map +1 -0
  28. package/dist/acpx-engine/index.js +6 -0
  29. package/dist/acpx-engine/index.js.map +1 -0
  30. package/dist/acpx-engine/local-process-control.d.ts +5 -0
  31. package/dist/acpx-engine/local-process-control.d.ts.map +1 -0
  32. package/dist/acpx-engine/local-process-control.js +39 -0
  33. package/dist/acpx-engine/local-process-control.js.map +1 -0
  34. package/dist/acpx-engine/local-process-control.test.d.ts +2 -0
  35. package/dist/acpx-engine/local-process-control.test.d.ts.map +1 -0
  36. package/dist/acpx-engine/local-process-control.test.js +38 -0
  37. package/dist/acpx-engine/local-process-control.test.js.map +1 -0
  38. package/dist/acpx-engine/operator-stop.test.d.ts +2 -0
  39. package/dist/acpx-engine/operator-stop.test.d.ts.map +1 -0
  40. package/dist/acpx-engine/operator-stop.test.js +107 -0
  41. package/dist/acpx-engine/operator-stop.test.js.map +1 -0
  42. package/dist/acpx-engine/remote-spawn-smoke.test.d.ts +2 -0
  43. package/dist/acpx-engine/remote-spawn-smoke.test.d.ts.map +1 -0
  44. package/dist/acpx-engine/remote-spawn-smoke.test.js +151 -0
  45. package/dist/acpx-engine/remote-spawn-smoke.test.js.map +1 -0
  46. package/dist/acpx-engine/run-contracts.d.ts +413 -0
  47. package/dist/acpx-engine/run-contracts.d.ts.map +1 -0
  48. package/dist/acpx-engine/run-contracts.js +20 -0
  49. package/dist/acpx-engine/run-contracts.js.map +1 -0
  50. package/dist/acpx-engine/run-contracts.test.d.ts +2 -0
  51. package/dist/acpx-engine/run-contracts.test.d.ts.map +1 -0
  52. package/dist/acpx-engine/run-contracts.test.js +57 -0
  53. package/dist/acpx-engine/run-contracts.test.js.map +1 -0
  54. package/dist/acpx-engine/run-coordinator.d.ts +57 -0
  55. package/dist/acpx-engine/run-coordinator.d.ts.map +1 -0
  56. package/dist/acpx-engine/run-coordinator.js +63 -0
  57. package/dist/acpx-engine/run-coordinator.js.map +1 -0
  58. package/dist/acpx-engine/run-coordinator.test.d.ts +2 -0
  59. package/dist/acpx-engine/run-coordinator.test.d.ts.map +1 -0
  60. package/dist/acpx-engine/run-coordinator.test.js +160 -0
  61. package/dist/acpx-engine/run-coordinator.test.js.map +1 -0
  62. package/dist/acpx-engine/run-fault-matrix.test.d.ts +2 -0
  63. package/dist/acpx-engine/run-fault-matrix.test.d.ts.map +1 -0
  64. package/dist/acpx-engine/run-fault-matrix.test.js +829 -0
  65. package/dist/acpx-engine/run-fault-matrix.test.js.map +1 -0
  66. package/dist/acpx-engine/run-resource-ledger.d.ts +30 -0
  67. package/dist/acpx-engine/run-resource-ledger.d.ts.map +1 -0
  68. package/dist/acpx-engine/run-resource-ledger.js +148 -0
  69. package/dist/acpx-engine/run-resource-ledger.js.map +1 -0
  70. package/dist/acpx-engine/run-resource-ledger.test.d.ts +2 -0
  71. package/dist/acpx-engine/run-resource-ledger.test.d.ts.map +1 -0
  72. package/dist/acpx-engine/run-resource-ledger.test.js +154 -0
  73. package/dist/acpx-engine/run-resource-ledger.test.js.map +1 -0
  74. package/dist/acpx-engine/run-site-host.d.ts +73 -0
  75. package/dist/acpx-engine/run-site-host.d.ts.map +1 -0
  76. package/dist/acpx-engine/run-site-host.js +65 -0
  77. package/dist/acpx-engine/run-site-host.js.map +1 -0
  78. package/dist/acpx-engine/run-site-host.test.d.ts +2 -0
  79. package/dist/acpx-engine/run-site-host.test.d.ts.map +1 -0
  80. package/dist/acpx-engine/run-site-host.test.js +98 -0
  81. package/dist/acpx-engine/run-site-host.test.js.map +1 -0
  82. package/dist/acpx-engine/run-site-sandbox.d.ts +142 -0
  83. package/dist/acpx-engine/run-site-sandbox.d.ts.map +1 -0
  84. package/dist/acpx-engine/run-site-sandbox.js +278 -0
  85. package/dist/acpx-engine/run-site-sandbox.js.map +1 -0
  86. package/dist/acpx-engine/run-site-sandbox.test.d.ts +2 -0
  87. package/dist/acpx-engine/run-site-sandbox.test.d.ts.map +1 -0
  88. package/dist/acpx-engine/run-site-sandbox.test.js +275 -0
  89. package/dist/acpx-engine/run-site-sandbox.test.js.map +1 -0
  90. package/dist/acpx-engine/session-codec.d.ts +3 -0
  91. package/dist/acpx-engine/session-codec.d.ts.map +1 -0
  92. package/dist/acpx-engine/session-codec.js +49 -0
  93. package/dist/acpx-engine/session-codec.js.map +1 -0
  94. package/dist/acpx-engine/session-reuse-store.d.ts +62 -0
  95. package/dist/acpx-engine/session-reuse-store.d.ts.map +1 -0
  96. package/dist/acpx-engine/session-reuse-store.js +134 -0
  97. package/dist/acpx-engine/session-reuse-store.js.map +1 -0
  98. package/dist/acpx-engine/session-reuse-store.test.d.ts +2 -0
  99. package/dist/acpx-engine/session-reuse-store.test.d.ts.map +1 -0
  100. package/dist/acpx-engine/session-reuse-store.test.js +134 -0
  101. package/dist/acpx-engine/session-reuse-store.test.js.map +1 -0
  102. package/dist/acpx-engine/settlement-characterization.test.d.ts +2 -0
  103. package/dist/acpx-engine/settlement-characterization.test.d.ts.map +1 -0
  104. package/dist/acpx-engine/settlement-characterization.test.js +880 -0
  105. package/dist/acpx-engine/settlement-characterization.test.js.map +1 -0
  106. package/dist/acpx-engine/settlement-sequence.d.ts +77 -0
  107. package/dist/acpx-engine/settlement-sequence.d.ts.map +1 -0
  108. package/dist/acpx-engine/settlement-sequence.js +119 -0
  109. package/dist/acpx-engine/settlement-sequence.js.map +1 -0
  110. package/dist/acpx-engine/settlement-sequence.test.d.ts +2 -0
  111. package/dist/acpx-engine/settlement-sequence.test.d.ts.map +1 -0
  112. package/dist/acpx-engine/settlement-sequence.test.js +272 -0
  113. package/dist/acpx-engine/settlement-sequence.test.js.map +1 -0
  114. package/dist/acpx-engine/spawn-smoke.test.d.ts +2 -0
  115. package/dist/acpx-engine/spawn-smoke.test.d.ts.map +1 -0
  116. package/dist/acpx-engine/spawn-smoke.test.js +184 -0
  117. package/dist/acpx-engine/spawn-smoke.test.js.map +1 -0
  118. package/dist/acpx-engine/startup-cancellation.d.ts +8 -0
  119. package/dist/acpx-engine/startup-cancellation.d.ts.map +1 -0
  120. package/dist/acpx-engine/startup-cancellation.js +92 -0
  121. package/dist/acpx-engine/startup-cancellation.js.map +1 -0
  122. package/dist/acpx-engine/startup-cancellation.test.d.ts +2 -0
  123. package/dist/acpx-engine/startup-cancellation.test.d.ts.map +1 -0
  124. package/dist/acpx-engine/startup-cancellation.test.js +115 -0
  125. package/dist/acpx-engine/startup-cancellation.test.js.map +1 -0
  126. package/dist/acpx-engine/startup-characterization.test.d.ts +2 -0
  127. package/dist/acpx-engine/startup-characterization.test.d.ts.map +1 -0
  128. package/dist/acpx-engine/startup-characterization.test.js +742 -0
  129. package/dist/acpx-engine/startup-characterization.test.js.map +1 -0
  130. package/dist/acpx-engine/startup-timing.d.ts +419 -0
  131. package/dist/acpx-engine/startup-timing.d.ts.map +1 -0
  132. package/dist/acpx-engine/startup-timing.js +616 -0
  133. package/dist/acpx-engine/startup-timing.js.map +1 -0
  134. package/dist/acpx-engine/startup-timing.test.d.ts +2 -0
  135. package/dist/acpx-engine/startup-timing.test.d.ts.map +1 -0
  136. package/dist/acpx-engine/startup-timing.test.js +619 -0
  137. package/dist/acpx-engine/startup-timing.test.js.map +1 -0
  138. package/dist/acpx-engine/turn-characterization.test.d.ts +2 -0
  139. package/dist/acpx-engine/turn-characterization.test.d.ts.map +1 -0
  140. package/dist/acpx-engine/turn-characterization.test.js +566 -0
  141. package/dist/acpx-engine/turn-characterization.test.js.map +1 -0
  142. package/dist/acpx-engine/turn-sequence.d.ts +54 -0
  143. package/dist/acpx-engine/turn-sequence.d.ts.map +1 -0
  144. package/dist/acpx-engine/turn-sequence.js +75 -0
  145. package/dist/acpx-engine/turn-sequence.js.map +1 -0
  146. package/dist/acpx-engine/turn-sequence.test.d.ts +2 -0
  147. package/dist/acpx-engine/turn-sequence.test.d.ts.map +1 -0
  148. package/dist/acpx-engine/turn-sequence.test.js +177 -0
  149. package/dist/acpx-engine/turn-sequence.test.js.map +1 -0
  150. package/dist/acpx-engine/ui.d.ts +3 -0
  151. package/dist/acpx-engine/ui.d.ts.map +1 -0
  152. package/dist/acpx-engine/ui.js +162 -0
  153. package/dist/acpx-engine/ui.js.map +1 -0
  154. package/dist/billing.d.ts +2 -0
  155. package/dist/billing.d.ts.map +1 -0
  156. package/dist/billing.js +16 -0
  157. package/dist/billing.js.map +1 -0
  158. package/dist/billing.test.d.ts +2 -0
  159. package/dist/billing.test.d.ts.map +1 -0
  160. package/dist/billing.test.js +14 -0
  161. package/dist/billing.test.js.map +1 -0
  162. package/dist/bridge-transport-contract.d.ts +43 -0
  163. package/dist/bridge-transport-contract.d.ts.map +1 -0
  164. package/dist/bridge-transport-contract.js +33 -0
  165. package/dist/bridge-transport-contract.js.map +1 -0
  166. package/dist/chat-file-delivery.d.ts +10 -0
  167. package/dist/chat-file-delivery.d.ts.map +1 -0
  168. package/dist/chat-file-delivery.js +38 -0
  169. package/dist/chat-file-delivery.js.map +1 -0
  170. package/dist/chat-file-delivery.test.d.ts +2 -0
  171. package/dist/chat-file-delivery.test.d.ts.map +1 -0
  172. package/dist/chat-file-delivery.test.js +92 -0
  173. package/dist/chat-file-delivery.test.js.map +1 -0
  174. package/dist/command-managed-runtime.d.ts +162 -0
  175. package/dist/command-managed-runtime.d.ts.map +1 -0
  176. package/dist/command-managed-runtime.js +456 -0
  177. package/dist/command-managed-runtime.js.map +1 -0
  178. package/dist/command-managed-runtime.test.d.ts +2 -0
  179. package/dist/command-managed-runtime.test.d.ts.map +1 -0
  180. package/dist/command-managed-runtime.test.js +908 -0
  181. package/dist/command-managed-runtime.test.js.map +1 -0
  182. package/dist/command-redaction.d.ts +15 -0
  183. package/dist/command-redaction.d.ts.map +1 -0
  184. package/dist/command-redaction.js +97 -0
  185. package/dist/command-redaction.js.map +1 -0
  186. package/dist/command-redaction.test.d.ts +2 -0
  187. package/dist/command-redaction.test.d.ts.map +1 -0
  188. package/dist/command-redaction.test.js +80 -0
  189. package/dist/command-redaction.test.js.map +1 -0
  190. package/dist/duplex-frame-codec.d.ts +124 -0
  191. package/dist/duplex-frame-codec.d.ts.map +1 -0
  192. package/dist/duplex-frame-codec.js +134 -0
  193. package/dist/duplex-frame-codec.js.map +1 -0
  194. package/dist/duplex-frame-codec.test.d.ts +2 -0
  195. package/dist/duplex-frame-codec.test.d.ts.map +1 -0
  196. package/dist/duplex-frame-codec.test.js +172 -0
  197. package/dist/duplex-frame-codec.test.js.map +1 -0
  198. package/dist/duplex-observability.d.ts +220 -0
  199. package/dist/duplex-observability.d.ts.map +1 -0
  200. package/dist/duplex-observability.js +248 -0
  201. package/dist/duplex-observability.js.map +1 -0
  202. package/dist/duplex-observability.test.d.ts +2 -0
  203. package/dist/duplex-observability.test.d.ts.map +1 -0
  204. package/dist/duplex-observability.test.js +55 -0
  205. package/dist/duplex-observability.test.js.map +1 -0
  206. package/dist/env-bindings.d.ts +17 -0
  207. package/dist/env-bindings.d.ts.map +1 -0
  208. package/dist/env-bindings.js +98 -0
  209. package/dist/env-bindings.js.map +1 -0
  210. package/dist/env-bindings.test.d.ts +2 -0
  211. package/dist/env-bindings.test.d.ts.map +1 -0
  212. package/dist/env-bindings.test.js +66 -0
  213. package/dist/env-bindings.test.js.map +1 -0
  214. package/dist/exclude-patterns.d.ts +4 -0
  215. package/dist/exclude-patterns.d.ts.map +1 -0
  216. package/dist/exclude-patterns.js +26 -0
  217. package/dist/exclude-patterns.js.map +1 -0
  218. package/dist/execution-target-sandbox.test.d.ts +2 -0
  219. package/dist/execution-target-sandbox.test.d.ts.map +1 -0
  220. package/dist/execution-target-sandbox.test.js +6522 -0
  221. package/dist/execution-target-sandbox.test.js.map +1 -0
  222. package/dist/execution-target-stdin-race.test.d.ts +2 -0
  223. package/dist/execution-target-stdin-race.test.d.ts.map +1 -0
  224. package/dist/execution-target-stdin-race.test.js +1842 -0
  225. package/dist/execution-target-stdin-race.test.js.map +1 -0
  226. package/dist/execution-target.d.ts +537 -0
  227. package/dist/execution-target.d.ts.map +1 -0
  228. package/dist/execution-target.js +3877 -0
  229. package/dist/execution-target.js.map +1 -0
  230. package/dist/execution-target.test.d.ts +2 -0
  231. package/dist/execution-target.test.d.ts.map +1 -0
  232. package/dist/execution-target.test.js +346 -0
  233. package/dist/execution-target.test.js.map +1 -0
  234. package/dist/git-workspace-sync.d.ts +193 -0
  235. package/dist/git-workspace-sync.d.ts.map +1 -0
  236. package/dist/git-workspace-sync.js +786 -0
  237. package/dist/git-workspace-sync.js.map +1 -0
  238. package/dist/git-workspace-sync.test.d.ts +2 -0
  239. package/dist/git-workspace-sync.test.d.ts.map +1 -0
  240. package/dist/git-workspace-sync.test.js +830 -0
  241. package/dist/git-workspace-sync.test.js.map +1 -0
  242. package/dist/github-launcher-environment.test.d.ts +2 -0
  243. package/dist/github-launcher-environment.test.d.ts.map +1 -0
  244. package/dist/github-launcher-environment.test.js +285 -0
  245. package/dist/github-launcher-environment.test.js.map +1 -0
  246. package/dist/github-launcher.d.ts +8 -0
  247. package/dist/github-launcher.d.ts.map +1 -0
  248. package/dist/github-launcher.js +127 -0
  249. package/dist/github-launcher.js.map +1 -0
  250. package/dist/github-launcher.test.d.ts +2 -0
  251. package/dist/github-launcher.test.d.ts.map +1 -0
  252. package/dist/github-launcher.test.js +166 -0
  253. package/dist/github-launcher.test.js.map +1 -0
  254. package/dist/http2-bridge-server.d.ts +465 -0
  255. package/dist/http2-bridge-server.d.ts.map +1 -0
  256. package/dist/http2-bridge-server.js +1087 -0
  257. package/dist/http2-bridge-server.js.map +1 -0
  258. package/dist/http2-bridge-server.test.d.ts +2 -0
  259. package/dist/http2-bridge-server.test.d.ts.map +1 -0
  260. package/dist/http2-bridge-server.test.js +2129 -0
  261. package/dist/http2-bridge-server.test.js.map +1 -0
  262. package/dist/index.d.ts +20 -0
  263. package/dist/index.d.ts.map +1 -0
  264. package/dist/index.js +12 -0
  265. package/dist/index.js.map +1 -0
  266. package/dist/local-process-sandbox.d.ts +41 -0
  267. package/dist/local-process-sandbox.d.ts.map +1 -0
  268. package/dist/local-process-sandbox.js +432 -0
  269. package/dist/local-process-sandbox.js.map +1 -0
  270. package/dist/local-process-sandbox.test.d.ts +2 -0
  271. package/dist/local-process-sandbox.test.d.ts.map +1 -0
  272. package/dist/local-process-sandbox.test.js +399 -0
  273. package/dist/local-process-sandbox.test.js.map +1 -0
  274. package/dist/log-redaction.d.ts +9 -0
  275. package/dist/log-redaction.d.ts.map +1 -0
  276. package/dist/log-redaction.js +88 -0
  277. package/dist/log-redaction.js.map +1 -0
  278. package/dist/login-capability.d.ts +88 -0
  279. package/dist/login-capability.d.ts.map +1 -0
  280. package/dist/login-capability.js +78 -0
  281. package/dist/login-capability.js.map +1 -0
  282. package/dist/login-capability.test.d.ts +2 -0
  283. package/dist/login-capability.test.d.ts.map +1 -0
  284. package/dist/login-capability.test.js +78 -0
  285. package/dist/login-capability.test.js.map +1 -0
  286. package/dist/login-pty-transport.d.ts +80 -0
  287. package/dist/login-pty-transport.d.ts.map +1 -0
  288. package/dist/login-pty-transport.js +75 -0
  289. package/dist/login-pty-transport.js.map +1 -0
  290. package/dist/login-pty-transport.test.d.ts +2 -0
  291. package/dist/login-pty-transport.test.d.ts.map +1 -0
  292. package/dist/login-pty-transport.test.js +185 -0
  293. package/dist/login-pty-transport.test.js.map +1 -0
  294. package/dist/login-runner-lifecycle.d.ts +70 -0
  295. package/dist/login-runner-lifecycle.d.ts.map +1 -0
  296. package/dist/login-runner-lifecycle.js +52 -0
  297. package/dist/login-runner-lifecycle.js.map +1 -0
  298. package/dist/login-runner-lifecycle.test.d.ts +2 -0
  299. package/dist/login-runner-lifecycle.test.d.ts.map +1 -0
  300. package/dist/login-runner-lifecycle.test.js +122 -0
  301. package/dist/login-runner-lifecycle.test.js.map +1 -0
  302. package/dist/mcp-isolation.integration.test.d.ts +2 -0
  303. package/dist/mcp-isolation.integration.test.d.ts.map +1 -0
  304. package/dist/mcp-isolation.integration.test.js +202 -0
  305. package/dist/mcp-isolation.integration.test.js.map +1 -0
  306. package/dist/paperclip-runner-permissions.d.ts +110 -0
  307. package/dist/paperclip-runner-permissions.d.ts.map +1 -0
  308. package/dist/paperclip-runner-permissions.js +150 -0
  309. package/dist/paperclip-runner-permissions.js.map +1 -0
  310. package/dist/paperclip-runner-permissions.test.d.ts +2 -0
  311. package/dist/paperclip-runner-permissions.test.d.ts.map +1 -0
  312. package/dist/paperclip-runner-permissions.test.js +47 -0
  313. package/dist/paperclip-runner-permissions.test.js.map +1 -0
  314. package/dist/published-exports.test.d.ts +2 -0
  315. package/dist/published-exports.test.d.ts.map +1 -0
  316. package/dist/published-exports.test.js +17 -0
  317. package/dist/published-exports.test.js.map +1 -0
  318. package/dist/remote-execution-env.d.ts +2 -0
  319. package/dist/remote-execution-env.d.ts.map +1 -0
  320. package/dist/remote-execution-env.js +46 -0
  321. package/dist/remote-execution-env.js.map +1 -0
  322. package/dist/remote-managed-runtime.d.ts +45 -0
  323. package/dist/remote-managed-runtime.d.ts.map +1 -0
  324. package/dist/remote-managed-runtime.js +183 -0
  325. package/dist/remote-managed-runtime.js.map +1 -0
  326. package/dist/remote-managed-runtime.test.d.ts +2 -0
  327. package/dist/remote-managed-runtime.test.d.ts.map +1 -0
  328. package/dist/remote-managed-runtime.test.js +294 -0
  329. package/dist/remote-managed-runtime.test.js.map +1 -0
  330. package/dist/runner-connectivity.d.ts +61 -0
  331. package/dist/runner-connectivity.d.ts.map +1 -0
  332. package/dist/runner-connectivity.js +81 -0
  333. package/dist/runner-connectivity.js.map +1 -0
  334. package/dist/runner-connectivity.test.d.ts +2 -0
  335. package/dist/runner-connectivity.test.d.ts.map +1 -0
  336. package/dist/runner-connectivity.test.js +183 -0
  337. package/dist/runner-connectivity.test.js.map +1 -0
  338. package/dist/runtime-progress.d.ts +48 -0
  339. package/dist/runtime-progress.d.ts.map +1 -0
  340. package/dist/runtime-progress.js +99 -0
  341. package/dist/runtime-progress.js.map +1 -0
  342. package/dist/runtime-progress.test.d.ts +2 -0
  343. package/dist/runtime-progress.test.d.ts.map +1 -0
  344. package/dist/runtime-progress.test.js +240 -0
  345. package/dist/runtime-progress.test.js.map +1 -0
  346. package/dist/sandbox-callback-bridge-body.d.ts +12 -0
  347. package/dist/sandbox-callback-bridge-body.d.ts.map +1 -0
  348. package/dist/sandbox-callback-bridge-body.js +39 -0
  349. package/dist/sandbox-callback-bridge-body.js.map +1 -0
  350. package/dist/sandbox-callback-bridge-body.test.d.ts +2 -0
  351. package/dist/sandbox-callback-bridge-body.test.d.ts.map +1 -0
  352. package/dist/sandbox-callback-bridge-body.test.js +31 -0
  353. package/dist/sandbox-callback-bridge-body.test.js.map +1 -0
  354. package/dist/sandbox-callback-bridge.d.ts +268 -0
  355. package/dist/sandbox-callback-bridge.d.ts.map +1 -0
  356. package/dist/sandbox-callback-bridge.js +2357 -0
  357. package/dist/sandbox-callback-bridge.js.map +1 -0
  358. package/dist/sandbox-callback-bridge.test.d.ts +2 -0
  359. package/dist/sandbox-callback-bridge.test.d.ts.map +1 -0
  360. package/dist/sandbox-callback-bridge.test.js +3253 -0
  361. package/dist/sandbox-callback-bridge.test.js.map +1 -0
  362. package/dist/sandbox-file-sync.test.d.ts +2 -0
  363. package/dist/sandbox-file-sync.test.d.ts.map +1 -0
  364. package/dist/sandbox-file-sync.test.js +419 -0
  365. package/dist/sandbox-file-sync.test.js.map +1 -0
  366. package/dist/sandbox-install-command.d.ts +2 -0
  367. package/dist/sandbox-install-command.d.ts.map +1 -0
  368. package/dist/sandbox-install-command.js +47 -0
  369. package/dist/sandbox-install-command.js.map +1 -0
  370. package/dist/sandbox-install-command.test.d.ts +2 -0
  371. package/dist/sandbox-install-command.test.d.ts.map +1 -0
  372. package/dist/sandbox-install-command.test.js +22 -0
  373. package/dist/sandbox-install-command.test.js.map +1 -0
  374. package/dist/sandbox-managed-runtime.d.ts +417 -0
  375. package/dist/sandbox-managed-runtime.d.ts.map +1 -0
  376. package/dist/sandbox-managed-runtime.js +1337 -0
  377. package/dist/sandbox-managed-runtime.js.map +1 -0
  378. package/dist/sandbox-managed-runtime.test.d.ts +2 -0
  379. package/dist/sandbox-managed-runtime.test.d.ts.map +1 -0
  380. package/dist/sandbox-managed-runtime.test.js +3746 -0
  381. package/dist/sandbox-managed-runtime.test.js.map +1 -0
  382. package/dist/sandbox-run-log-stream.d.ts +44 -0
  383. package/dist/sandbox-run-log-stream.d.ts.map +1 -0
  384. package/dist/sandbox-run-log-stream.js +203 -0
  385. package/dist/sandbox-run-log-stream.js.map +1 -0
  386. package/dist/sandbox-shell.d.ts +3 -0
  387. package/dist/sandbox-shell.d.ts.map +1 -0
  388. package/dist/sandbox-shell.js +7 -0
  389. package/dist/sandbox-shell.js.map +1 -0
  390. package/dist/server-utils-env.test.d.ts +2 -0
  391. package/dist/server-utils-env.test.d.ts.map +1 -0
  392. package/dist/server-utils-env.test.js +15 -0
  393. package/dist/server-utils-env.test.js.map +1 -0
  394. package/dist/server-utils.d.ts +617 -0
  395. package/dist/server-utils.d.ts.map +1 -0
  396. package/dist/server-utils.js +3258 -0
  397. package/dist/server-utils.js.map +1 -0
  398. package/dist/server-utils.test.d.ts +2 -0
  399. package/dist/server-utils.test.d.ts.map +1 -0
  400. package/dist/server-utils.test.js +3047 -0
  401. package/dist/server-utils.test.js.map +1 -0
  402. package/dist/session-compaction.d.ts +25 -0
  403. package/dist/session-compaction.d.ts.map +1 -0
  404. package/dist/session-compaction.js +165 -0
  405. package/dist/session-compaction.js.map +1 -0
  406. package/dist/skill-library-manifest.d.ts +6 -0
  407. package/dist/skill-library-manifest.d.ts.map +1 -0
  408. package/dist/skill-library-manifest.js +53 -0
  409. package/dist/skill-library-manifest.js.map +1 -0
  410. package/dist/skill-library-manifest.test.d.ts +2 -0
  411. package/dist/skill-library-manifest.test.d.ts.map +1 -0
  412. package/dist/skill-library-manifest.test.js +84 -0
  413. package/dist/skill-library-manifest.test.js.map +1 -0
  414. package/dist/skills-staging-follow-symlinks.test.d.ts +2 -0
  415. package/dist/skills-staging-follow-symlinks.test.d.ts.map +1 -0
  416. package/dist/skills-staging-follow-symlinks.test.js +126 -0
  417. package/dist/skills-staging-follow-symlinks.test.js.map +1 -0
  418. package/dist/ssh-fixture.test.d.ts +2 -0
  419. package/dist/ssh-fixture.test.d.ts.map +1 -0
  420. package/dist/ssh-fixture.test.js +832 -0
  421. package/dist/ssh-fixture.test.js.map +1 -0
  422. package/dist/ssh.d.ts +124 -0
  423. package/dist/ssh.d.ts.map +1 -0
  424. package/dist/ssh.js +1667 -0
  425. package/dist/ssh.js.map +1 -0
  426. package/dist/sync-operation-schedule.d.ts +17 -0
  427. package/dist/sync-operation-schedule.d.ts.map +1 -0
  428. package/dist/sync-operation-schedule.js +66 -0
  429. package/dist/sync-operation-schedule.js.map +1 -0
  430. package/dist/sync-operation-schedule.test.d.ts +2 -0
  431. package/dist/sync-operation-schedule.test.d.ts.map +1 -0
  432. package/dist/sync-operation-schedule.test.js +130 -0
  433. package/dist/sync-operation-schedule.test.js.map +1 -0
  434. package/dist/test-support/mcp-isolation-harness.d.ts +23 -0
  435. package/dist/test-support/mcp-isolation-harness.d.ts.map +1 -0
  436. package/dist/test-support/mcp-isolation-harness.js +67 -0
  437. package/dist/test-support/mcp-isolation-harness.js.map +1 -0
  438. package/dist/types.d.ts +780 -0
  439. package/dist/types.d.ts.map +1 -0
  440. package/dist/types.js +5 -0
  441. package/dist/types.js.map +1 -0
  442. package/dist/workspace-restore-merge.d.ts +77 -0
  443. package/dist/workspace-restore-merge.d.ts.map +1 -0
  444. package/dist/workspace-restore-merge.js +396 -0
  445. package/dist/workspace-restore-merge.js.map +1 -0
  446. package/dist/workspace-restore-merge.test.d.ts +2 -0
  447. package/dist/workspace-restore-merge.test.d.ts.map +1 -0
  448. package/dist/workspace-restore-merge.test.js +438 -0
  449. package/dist/workspace-restore-merge.test.js.map +1 -0
  450. package/dist/workspace-restore-teardown.d.ts +29 -0
  451. package/dist/workspace-restore-teardown.d.ts.map +1 -0
  452. package/dist/workspace-restore-teardown.js +34 -0
  453. package/dist/workspace-restore-teardown.js.map +1 -0
  454. package/dist/workspace-restore-teardown.test.d.ts +2 -0
  455. package/dist/workspace-restore-teardown.test.d.ts.map +1 -0
  456. package/dist/workspace-restore-teardown.test.js +71 -0
  457. package/dist/workspace-restore-teardown.test.js.map +1 -0
  458. package/node_modules/@agentclientprotocol/sdk/LICENSE +191 -0
  459. package/node_modules/@agentclientprotocol/sdk/README.md +70 -0
  460. package/node_modules/@agentclientprotocol/sdk/dist/acp.d.ts +1803 -0
  461. package/node_modules/@agentclientprotocol/sdk/dist/acp.js +1869 -0
  462. package/node_modules/@agentclientprotocol/sdk/dist/acp.js.map +1 -0
  463. package/node_modules/@agentclientprotocol/sdk/dist/acp.test.d.ts +1 -0
  464. package/node_modules/@agentclientprotocol/sdk/dist/acp.test.js +5036 -0
  465. package/node_modules/@agentclientprotocol/sdk/dist/acp.test.js.map +1 -0
  466. package/node_modules/@agentclientprotocol/sdk/dist/connection.d.ts +89 -0
  467. package/node_modules/@agentclientprotocol/sdk/dist/connection.js +490 -0
  468. package/node_modules/@agentclientprotocol/sdk/dist/connection.js.map +1 -0
  469. package/node_modules/@agentclientprotocol/sdk/dist/connection.test.d.ts +1 -0
  470. package/node_modules/@agentclientprotocol/sdk/dist/connection.test.js +507 -0
  471. package/node_modules/@agentclientprotocol/sdk/dist/connection.test.js.map +1 -0
  472. package/node_modules/@agentclientprotocol/sdk/dist/cookie-store.d.ts +26 -0
  473. package/node_modules/@agentclientprotocol/sdk/dist/cookie-store.js +96 -0
  474. package/node_modules/@agentclientprotocol/sdk/dist/cookie-store.js.map +1 -0
  475. package/node_modules/@agentclientprotocol/sdk/dist/cookie-store.test.d.ts +1 -0
  476. package/node_modules/@agentclientprotocol/sdk/dist/cookie-store.test.js +77 -0
  477. package/node_modules/@agentclientprotocol/sdk/dist/cookie-store.test.js.map +1 -0
  478. package/node_modules/@agentclientprotocol/sdk/dist/examples/agent.d.ts +2 -0
  479. package/node_modules/@agentclientprotocol/sdk/dist/examples/agent.js +232 -0
  480. package/node_modules/@agentclientprotocol/sdk/dist/examples/agent.js.map +1 -0
  481. package/node_modules/@agentclientprotocol/sdk/dist/examples/client.d.ts +2 -0
  482. package/node_modules/@agentclientprotocol/sdk/dist/examples/client.js +132 -0
  483. package/node_modules/@agentclientprotocol/sdk/dist/examples/client.js.map +1 -0
  484. package/node_modules/@agentclientprotocol/sdk/dist/examples/dual-version-agent.d.ts +9 -0
  485. package/node_modules/@agentclientprotocol/sdk/dist/examples/dual-version-agent.js +221 -0
  486. package/node_modules/@agentclientprotocol/sdk/dist/examples/dual-version-agent.js.map +1 -0
  487. package/node_modules/@agentclientprotocol/sdk/dist/examples/http-client.d.ts +2 -0
  488. package/node_modules/@agentclientprotocol/sdk/dist/examples/http-client.js +86 -0
  489. package/node_modules/@agentclientprotocol/sdk/dist/examples/http-client.js.map +1 -0
  490. package/node_modules/@agentclientprotocol/sdk/dist/examples/http-server.d.ts +2 -0
  491. package/node_modules/@agentclientprotocol/sdk/dist/examples/http-server.js +112 -0
  492. package/node_modules/@agentclientprotocol/sdk/dist/examples/http-server.js.map +1 -0
  493. package/node_modules/@agentclientprotocol/sdk/dist/examples/ws-client.d.ts +2 -0
  494. package/node_modules/@agentclientprotocol/sdk/dist/examples/ws-client.js +88 -0
  495. package/node_modules/@agentclientprotocol/sdk/dist/examples/ws-client.js.map +1 -0
  496. package/node_modules/@agentclientprotocol/sdk/dist/http-stream.d.ts +33 -0
  497. package/node_modules/@agentclientprotocol/sdk/dist/http-stream.js +435 -0
  498. package/node_modules/@agentclientprotocol/sdk/dist/http-stream.js.map +1 -0
  499. package/node_modules/@agentclientprotocol/sdk/dist/http-stream.test.d.ts +1 -0
  500. package/node_modules/@agentclientprotocol/sdk/dist/http-stream.test.js +1380 -0
  501. package/node_modules/@agentclientprotocol/sdk/dist/http-stream.test.js.map +1 -0
  502. package/node_modules/@agentclientprotocol/sdk/dist/jsonrpc.d.ts +603 -0
  503. package/node_modules/@agentclientprotocol/sdk/dist/jsonrpc.js +1076 -0
  504. package/node_modules/@agentclientprotocol/sdk/dist/jsonrpc.js.map +1 -0
  505. package/node_modules/@agentclientprotocol/sdk/dist/jsonrpc.test.d.ts +1 -0
  506. package/node_modules/@agentclientprotocol/sdk/dist/jsonrpc.test.js +917 -0
  507. package/node_modules/@agentclientprotocol/sdk/dist/jsonrpc.test.js.map +1 -0
  508. package/node_modules/@agentclientprotocol/sdk/dist/line-buffer.d.ts +22 -0
  509. package/node_modules/@agentclientprotocol/sdk/dist/line-buffer.js +64 -0
  510. package/node_modules/@agentclientprotocol/sdk/dist/line-buffer.js.map +1 -0
  511. package/node_modules/@agentclientprotocol/sdk/dist/line-buffer.test.d.ts +1 -0
  512. package/node_modules/@agentclientprotocol/sdk/dist/line-buffer.test.js +45 -0
  513. package/node_modules/@agentclientprotocol/sdk/dist/line-buffer.test.js.map +1 -0
  514. package/node_modules/@agentclientprotocol/sdk/dist/node-adapter.d.ts +17 -0
  515. package/node_modules/@agentclientprotocol/sdk/dist/node-adapter.js +426 -0
  516. package/node_modules/@agentclientprotocol/sdk/dist/node-adapter.js.map +1 -0
  517. package/node_modules/@agentclientprotocol/sdk/dist/node-adapter.test.d.ts +1 -0
  518. package/node_modules/@agentclientprotocol/sdk/dist/node-adapter.test.js +499 -0
  519. package/node_modules/@agentclientprotocol/sdk/dist/node-adapter.test.js.map +1 -0
  520. package/node_modules/@agentclientprotocol/sdk/dist/protocol-router.d.ts +37 -0
  521. package/node_modules/@agentclientprotocol/sdk/dist/protocol-router.js +474 -0
  522. package/node_modules/@agentclientprotocol/sdk/dist/protocol-router.js.map +1 -0
  523. package/node_modules/@agentclientprotocol/sdk/dist/protocol-router.test.d.ts +1 -0
  524. package/node_modules/@agentclientprotocol/sdk/dist/protocol-router.test.js +535 -0
  525. package/node_modules/@agentclientprotocol/sdk/dist/protocol-router.test.js.map +1 -0
  526. package/node_modules/@agentclientprotocol/sdk/dist/protocol.d.ts +11 -0
  527. package/node_modules/@agentclientprotocol/sdk/dist/protocol.js +69 -0
  528. package/node_modules/@agentclientprotocol/sdk/dist/protocol.js.map +1 -0
  529. package/node_modules/@agentclientprotocol/sdk/dist/protocol.test.d.ts +1 -0
  530. package/node_modules/@agentclientprotocol/sdk/dist/protocol.test.js +82 -0
  531. package/node_modules/@agentclientprotocol/sdk/dist/protocol.test.js.map +1 -0
  532. package/node_modules/@agentclientprotocol/sdk/dist/schema/guards.gen.d.ts +183 -0
  533. package/node_modules/@agentclientprotocol/sdk/dist/schema/guards.gen.js +207 -0
  534. package/node_modules/@agentclientprotocol/sdk/dist/schema/guards.gen.js.map +1 -0
  535. package/node_modules/@agentclientprotocol/sdk/dist/schema/index.d.ts +51 -0
  536. package/node_modules/@agentclientprotocol/sdk/dist/schema/index.js +52 -0
  537. package/node_modules/@agentclientprotocol/sdk/dist/schema/index.js.map +1 -0
  538. package/node_modules/@agentclientprotocol/sdk/dist/schema/types.gen.d.ts +6219 -0
  539. package/node_modules/@agentclientprotocol/sdk/dist/schema/types.gen.js +3 -0
  540. package/node_modules/@agentclientprotocol/sdk/dist/schema/types.gen.js.map +1 -0
  541. package/node_modules/@agentclientprotocol/sdk/dist/schema/zod.gen.d.ts +15215 -0
  542. package/node_modules/@agentclientprotocol/sdk/dist/schema/zod.gen.js +3084 -0
  543. package/node_modules/@agentclientprotocol/sdk/dist/schema/zod.gen.js.map +1 -0
  544. package/node_modules/@agentclientprotocol/sdk/dist/schema-deserialize.d.ts +30 -0
  545. package/node_modules/@agentclientprotocol/sdk/dist/schema-deserialize.js +98 -0
  546. package/node_modules/@agentclientprotocol/sdk/dist/schema-deserialize.js.map +1 -0
  547. package/node_modules/@agentclientprotocol/sdk/dist/schema-deserialize.test.d.ts +1 -0
  548. package/node_modules/@agentclientprotocol/sdk/dist/schema-deserialize.test.js +93 -0
  549. package/node_modules/@agentclientprotocol/sdk/dist/schema-deserialize.test.js.map +1 -0
  550. package/node_modules/@agentclientprotocol/sdk/dist/server-permission.test.d.ts +1 -0
  551. package/node_modules/@agentclientprotocol/sdk/dist/server-permission.test.js +261 -0
  552. package/node_modules/@agentclientprotocol/sdk/dist/server-permission.test.js.map +1 -0
  553. package/node_modules/@agentclientprotocol/sdk/dist/server-session-sse.test.d.ts +1 -0
  554. package/node_modules/@agentclientprotocol/sdk/dist/server-session-sse.test.js +536 -0
  555. package/node_modules/@agentclientprotocol/sdk/dist/server-session-sse.test.js.map +1 -0
  556. package/node_modules/@agentclientprotocol/sdk/dist/server-sse.d.ts +2 -0
  557. package/node_modules/@agentclientprotocol/sdk/dist/server-sse.js +88 -0
  558. package/node_modules/@agentclientprotocol/sdk/dist/server-sse.js.map +1 -0
  559. package/node_modules/@agentclientprotocol/sdk/dist/server-sse.test.d.ts +1 -0
  560. package/node_modules/@agentclientprotocol/sdk/dist/server-sse.test.js +53 -0
  561. package/node_modules/@agentclientprotocol/sdk/dist/server-sse.test.js.map +1 -0
  562. package/node_modules/@agentclientprotocol/sdk/dist/server-websocket-upgrade.test.d.ts +1 -0
  563. package/node_modules/@agentclientprotocol/sdk/dist/server-websocket-upgrade.test.js +992 -0
  564. package/node_modules/@agentclientprotocol/sdk/dist/server-websocket-upgrade.test.js.map +1 -0
  565. package/node_modules/@agentclientprotocol/sdk/dist/server.d.ts +81 -0
  566. package/node_modules/@agentclientprotocol/sdk/dist/server.js +386 -0
  567. package/node_modules/@agentclientprotocol/sdk/dist/server.js.map +1 -0
  568. package/node_modules/@agentclientprotocol/sdk/dist/server.test.d.ts +1 -0
  569. package/node_modules/@agentclientprotocol/sdk/dist/server.test.js +1116 -0
  570. package/node_modules/@agentclientprotocol/sdk/dist/server.test.js.map +1 -0
  571. package/node_modules/@agentclientprotocol/sdk/dist/sse.d.ts +4 -0
  572. package/node_modules/@agentclientprotocol/sdk/dist/sse.js +91 -0
  573. package/node_modules/@agentclientprotocol/sdk/dist/sse.js.map +1 -0
  574. package/node_modules/@agentclientprotocol/sdk/dist/sse.test.d.ts +1 -0
  575. package/node_modules/@agentclientprotocol/sdk/dist/sse.test.js +126 -0
  576. package/node_modules/@agentclientprotocol/sdk/dist/sse.test.js.map +1 -0
  577. package/node_modules/@agentclientprotocol/sdk/dist/stream.d.ts +35 -0
  578. package/node_modules/@agentclientprotocol/sdk/dist/stream.js +115 -0
  579. package/node_modules/@agentclientprotocol/sdk/dist/stream.js.map +1 -0
  580. package/node_modules/@agentclientprotocol/sdk/dist/stream.test.d.ts +1 -0
  581. package/node_modules/@agentclientprotocol/sdk/dist/stream.test.js +195 -0
  582. package/node_modules/@agentclientprotocol/sdk/dist/stream.test.js.map +1 -0
  583. package/node_modules/@agentclientprotocol/sdk/dist/test-support/streams.d.ts +8 -0
  584. package/node_modules/@agentclientprotocol/sdk/dist/test-support/streams.js +51 -0
  585. package/node_modules/@agentclientprotocol/sdk/dist/test-support/streams.js.map +1 -0
  586. package/node_modules/@agentclientprotocol/sdk/dist/test-support/test-agent.d.ts +24 -0
  587. package/node_modules/@agentclientprotocol/sdk/dist/test-support/test-agent.js +163 -0
  588. package/node_modules/@agentclientprotocol/sdk/dist/test-support/test-agent.js.map +1 -0
  589. package/node_modules/@agentclientprotocol/sdk/dist/test-support/test-http-server.d.ts +9 -0
  590. package/node_modules/@agentclientprotocol/sdk/dist/test-support/test-http-server.js +74 -0
  591. package/node_modules/@agentclientprotocol/sdk/dist/test-support/test-http-server.js.map +1 -0
  592. package/node_modules/@agentclientprotocol/sdk/dist/v2/acp.d.ts +957 -0
  593. package/node_modules/@agentclientprotocol/sdk/dist/v2/acp.js +1484 -0
  594. package/node_modules/@agentclientprotocol/sdk/dist/v2/acp.js.map +1 -0
  595. package/node_modules/@agentclientprotocol/sdk/dist/v2/acp.test.d.ts +1 -0
  596. package/node_modules/@agentclientprotocol/sdk/dist/v2/acp.test.js +1287 -0
  597. package/node_modules/@agentclientprotocol/sdk/dist/v2/acp.test.js.map +1 -0
  598. package/node_modules/@agentclientprotocol/sdk/dist/v2/schema/guards.gen.d.ts +946 -0
  599. package/node_modules/@agentclientprotocol/sdk/dist/v2/schema/guards.gen.js +1046 -0
  600. package/node_modules/@agentclientprotocol/sdk/dist/v2/schema/guards.gen.js.map +1 -0
  601. package/node_modules/@agentclientprotocol/sdk/dist/v2/schema/index.d.ts +42 -0
  602. package/node_modules/@agentclientprotocol/sdk/dist/v2/schema/index.js +43 -0
  603. package/node_modules/@agentclientprotocol/sdk/dist/v2/schema/index.js.map +1 -0
  604. package/node_modules/@agentclientprotocol/sdk/dist/v2/schema/types.gen.d.ts +6208 -0
  605. package/node_modules/@agentclientprotocol/sdk/dist/v2/schema/types.gen.js +3 -0
  606. package/node_modules/@agentclientprotocol/sdk/dist/v2/schema/types.gen.js.map +1 -0
  607. package/node_modules/@agentclientprotocol/sdk/dist/v2/schema/zod.gen.d.ts +33267 -0
  608. package/node_modules/@agentclientprotocol/sdk/dist/v2/schema/zod.gen.js +3199 -0
  609. package/node_modules/@agentclientprotocol/sdk/dist/v2/schema/zod.gen.js.map +1 -0
  610. package/node_modules/@agentclientprotocol/sdk/dist/ws-server.d.ts +14 -0
  611. package/node_modules/@agentclientprotocol/sdk/dist/ws-server.js +357 -0
  612. package/node_modules/@agentclientprotocol/sdk/dist/ws-server.js.map +1 -0
  613. package/node_modules/@agentclientprotocol/sdk/dist/ws-stream.d.ts +54 -0
  614. package/node_modules/@agentclientprotocol/sdk/dist/ws-stream.js +253 -0
  615. package/node_modules/@agentclientprotocol/sdk/dist/ws-stream.js.map +1 -0
  616. package/node_modules/@agentclientprotocol/sdk/dist/ws-stream.test.d.ts +1 -0
  617. package/node_modules/@agentclientprotocol/sdk/dist/ws-stream.test.js +836 -0
  618. package/node_modules/@agentclientprotocol/sdk/dist/ws-stream.test.js.map +1 -0
  619. package/node_modules/@agentclientprotocol/sdk/dist/ws-utils.d.ts +13 -0
  620. package/node_modules/@agentclientprotocol/sdk/dist/ws-utils.js +78 -0
  621. package/node_modules/@agentclientprotocol/sdk/dist/ws-utils.js.map +1 -0
  622. package/node_modules/@agentclientprotocol/sdk/dist/ws-utils.test.d.ts +1 -0
  623. package/node_modules/@agentclientprotocol/sdk/dist/ws-utils.test.js +42 -0
  624. package/node_modules/@agentclientprotocol/sdk/dist/ws-utils.test.js.map +1 -0
  625. package/node_modules/@agentclientprotocol/sdk/package.json +104 -0
  626. package/node_modules/@agentclientprotocol/sdk/schema/schema.json +8967 -0
  627. package/node_modules/@agentclientprotocol/sdk/schema/v2/schema.unstable.json +10242 -0
  628. package/node_modules/@clack/core/LICENSE +9 -0
  629. package/node_modules/@clack/core/README.md +22 -0
  630. package/node_modules/@clack/core/dist/index.d.mts +503 -0
  631. package/node_modules/@clack/core/dist/index.mjs +1003 -0
  632. package/node_modules/@clack/core/package.json +63 -0
  633. package/node_modules/@clack/prompts/LICENSE +9 -0
  634. package/node_modules/@clack/prompts/README.md +396 -0
  635. package/node_modules/@clack/prompts/dist/index.d.mts +949 -0
  636. package/node_modules/@clack/prompts/dist/index.mjs +1423 -0
  637. package/node_modules/@clack/prompts/package.json +67 -0
  638. package/node_modules/@esbuild/linux-x64/README.md +3 -0
  639. package/node_modules/@esbuild/linux-x64/bin/esbuild +0 -0
  640. package/node_modules/@esbuild/linux-x64/package.json +20 -0
  641. package/node_modules/acpx/LICENSE +21 -0
  642. package/node_modules/acpx/README.md +424 -0
  643. package/node_modules/acpx/dist/cli-CxsS1XQp.js +197 -0
  644. package/node_modules/acpx/dist/cli-CxsS1XQp.js.map +1 -0
  645. package/node_modules/acpx/dist/cli.d.ts +14 -0
  646. package/node_modules/acpx/dist/cli.d.ts.map +1 -0
  647. package/node_modules/acpx/dist/cli.js +2683 -0
  648. package/node_modules/acpx/dist/cli.js.map +1 -0
  649. package/node_modules/acpx/dist/client-DwNyFauq.d.ts +192 -0
  650. package/node_modules/acpx/dist/client-DwNyFauq.d.ts.map +1 -0
  651. package/node_modules/acpx/dist/flags-Bjq_XQ4-.js +260 -0
  652. package/node_modules/acpx/dist/flags-Bjq_XQ4-.js.map +1 -0
  653. package/node_modules/acpx/dist/flows-Db_LZKu9.js +1920 -0
  654. package/node_modules/acpx/dist/flows-Db_LZKu9.js.map +1 -0
  655. package/node_modules/acpx/dist/flows.d.ts +318 -0
  656. package/node_modules/acpx/dist/flows.d.ts.map +1 -0
  657. package/node_modules/acpx/dist/flows.js +2 -0
  658. package/node_modules/acpx/dist/live-checkpoint-ClPCSdrW.js +6210 -0
  659. package/node_modules/acpx/dist/live-checkpoint-ClPCSdrW.js.map +1 -0
  660. package/node_modules/acpx/dist/output-CjdF5rHk.js +4593 -0
  661. package/node_modules/acpx/dist/output-CjdF5rHk.js.map +1 -0
  662. package/node_modules/acpx/dist/runtime.d.ts +472 -0
  663. package/node_modules/acpx/dist/runtime.d.ts.map +1 -0
  664. package/node_modules/acpx/dist/runtime.js +1711 -0
  665. package/node_modules/acpx/dist/runtime.js.map +1 -0
  666. package/node_modules/acpx/dist/session-options-jkYbBxGE.d.ts +278 -0
  667. package/node_modules/acpx/dist/session-options-jkYbBxGE.d.ts.map +1 -0
  668. package/node_modules/acpx/package.json +129 -0
  669. package/node_modules/acpx/skills/acpx/SKILL.md +617 -0
  670. package/node_modules/b4a/LICENSE +201 -0
  671. package/node_modules/b4a/README.md +153 -0
  672. package/node_modules/b4a/browser.js +546 -0
  673. package/node_modules/b4a/index.d.ts +144 -0
  674. package/node_modules/b4a/index.js +193 -0
  675. package/node_modules/b4a/lib/ascii.js +31 -0
  676. package/node_modules/b4a/lib/base64.js +64 -0
  677. package/node_modules/b4a/lib/hex.js +51 -0
  678. package/node_modules/b4a/lib/latin1.js +31 -0
  679. package/node_modules/b4a/lib/utf16le.js +40 -0
  680. package/node_modules/b4a/lib/utf8.js +144 -0
  681. package/node_modules/b4a/package.json +54 -0
  682. package/node_modules/b4a/react-native.js +5 -0
  683. package/node_modules/b4a/runtime.d.ts +14 -0
  684. package/node_modules/bare-events/LICENSE +201 -0
  685. package/node_modules/bare-events/README.md +25 -0
  686. package/node_modules/bare-events/global.d.ts +15 -0
  687. package/node_modules/bare-events/global.js +5 -0
  688. package/node_modules/bare-events/index.d.ts +89 -0
  689. package/node_modules/bare-events/index.js +397 -0
  690. package/node_modules/bare-events/lib/errors.js +23 -0
  691. package/node_modules/bare-events/package.json +63 -0
  692. package/node_modules/bare-events/web.d.ts +79 -0
  693. package/node_modules/bare-events/web.js +417 -0
  694. package/node_modules/bare-fs/CMakeLists.txt +13 -0
  695. package/node_modules/bare-fs/LICENSE +201 -0
  696. package/node_modules/bare-fs/README.md +33 -0
  697. package/node_modules/bare-fs/binding.c +2913 -0
  698. package/node_modules/bare-fs/binding.js +1 -0
  699. package/node_modules/bare-fs/index.d.ts +1502 -0
  700. package/node_modules/bare-fs/index.js +2855 -0
  701. package/node_modules/bare-fs/lib/constants.d.ts +50 -0
  702. package/node_modules/bare-fs/lib/constants.js +49 -0
  703. package/node_modules/bare-fs/lib/errors.d.ts +13 -0
  704. package/node_modules/bare-fs/lib/errors.js +55 -0
  705. package/node_modules/bare-fs/package.json +74 -0
  706. package/node_modules/bare-fs/prebuilds/android-arm/bare-fs.bare +0 -0
  707. package/node_modules/bare-fs/prebuilds/android-arm64/bare-fs.bare +0 -0
  708. package/node_modules/bare-fs/prebuilds/android-ia32/bare-fs.bare +0 -0
  709. package/node_modules/bare-fs/prebuilds/android-x64/bare-fs.bare +0 -0
  710. package/node_modules/bare-fs/prebuilds/darwin-arm64/bare-fs.bare +0 -0
  711. package/node_modules/bare-fs/prebuilds/darwin-x64/bare-fs.bare +0 -0
  712. package/node_modules/bare-fs/prebuilds/ios-arm64/bare-fs.bare +0 -0
  713. package/node_modules/bare-fs/prebuilds/ios-arm64-simulator/bare-fs.bare +0 -0
  714. package/node_modules/bare-fs/prebuilds/ios-x64-simulator/bare-fs.bare +0 -0
  715. package/node_modules/bare-fs/prebuilds/linux-arm64/bare-fs.bare +0 -0
  716. package/node_modules/bare-fs/prebuilds/linux-x64/bare-fs.bare +0 -0
  717. package/node_modules/bare-fs/prebuilds/win32-arm64/bare-fs.bare +0 -0
  718. package/node_modules/bare-fs/prebuilds/win32-x64/bare-fs.bare +0 -0
  719. package/node_modules/bare-fs/promises.d.ts +480 -0
  720. package/node_modules/bare-fs/promises.js +119 -0
  721. package/node_modules/bare-path/CMakeLists.txt +13 -0
  722. package/node_modules/bare-path/LICENSE +201 -0
  723. package/node_modules/bare-path/NOTICE +28 -0
  724. package/node_modules/bare-path/README.md +19 -0
  725. package/node_modules/bare-path/binding.c +106 -0
  726. package/node_modules/bare-path/binding.js +1 -0
  727. package/node_modules/bare-path/index.d.ts +27 -0
  728. package/node_modules/bare-path/index.js +9 -0
  729. package/node_modules/bare-path/lib/constants.js +11 -0
  730. package/node_modules/bare-path/lib/posix.js +263 -0
  731. package/node_modules/bare-path/lib/shared.js +81 -0
  732. package/node_modules/bare-path/lib/win32.js +564 -0
  733. package/node_modules/bare-path/package.json +47 -0
  734. package/node_modules/bare-path/prebuilds/android-arm/bare-path.bare +0 -0
  735. package/node_modules/bare-path/prebuilds/android-arm64/bare-path.bare +0 -0
  736. package/node_modules/bare-path/prebuilds/android-ia32/bare-path.bare +0 -0
  737. package/node_modules/bare-path/prebuilds/android-x64/bare-path.bare +0 -0
  738. package/node_modules/bare-path/prebuilds/darwin-arm64/bare-path.bare +0 -0
  739. package/node_modules/bare-path/prebuilds/darwin-x64/bare-path.bare +0 -0
  740. package/node_modules/bare-path/prebuilds/ios-arm64/bare-path.bare +0 -0
  741. package/node_modules/bare-path/prebuilds/ios-arm64-simulator/bare-path.bare +0 -0
  742. package/node_modules/bare-path/prebuilds/ios-x64-simulator/bare-path.bare +0 -0
  743. package/node_modules/bare-path/prebuilds/linux-arm64/bare-path.bare +0 -0
  744. package/node_modules/bare-path/prebuilds/linux-x64/bare-path.bare +0 -0
  745. package/node_modules/bare-path/prebuilds/win32-arm64/bare-path.bare +0 -0
  746. package/node_modules/bare-path/prebuilds/win32-x64/bare-path.bare +0 -0
  747. package/node_modules/bare-stream/LICENSE +201 -0
  748. package/node_modules/bare-stream/README.md +354 -0
  749. package/node_modules/bare-stream/global.d.ts +31 -0
  750. package/node_modules/bare-stream/global.js +15 -0
  751. package/node_modules/bare-stream/index.d.ts +235 -0
  752. package/node_modules/bare-stream/index.js +493 -0
  753. package/node_modules/bare-stream/package.json +75 -0
  754. package/node_modules/bare-stream/promises.js +3 -0
  755. package/node_modules/bare-stream/web.d.ts +152 -0
  756. package/node_modules/bare-stream/web.js +607 -0
  757. package/node_modules/bare-url/CMakeLists.txt +36 -0
  758. package/node_modules/bare-url/LICENSE +201 -0
  759. package/node_modules/bare-url/README.md +33 -0
  760. package/node_modules/bare-url/binding.c +422 -0
  761. package/node_modules/bare-url/binding.js +1 -0
  762. package/node_modules/bare-url/global.d.ts +24 -0
  763. package/node_modules/bare-url/global.js +2 -0
  764. package/node_modules/bare-url/index.d.ts +96 -0
  765. package/node_modules/bare-url/index.js +676 -0
  766. package/node_modules/bare-url/lib/errors.d.ts +10 -0
  767. package/node_modules/bare-url/lib/errors.js +33 -0
  768. package/node_modules/bare-url/lib/url-search-params.d.ts +66 -0
  769. package/node_modules/bare-url/lib/url-search-params.js +276 -0
  770. package/node_modules/bare-url/package.json +54 -0
  771. package/node_modules/bare-url/prebuilds/android-arm/bare-url.bare +0 -0
  772. package/node_modules/bare-url/prebuilds/android-arm64/bare-url.bare +0 -0
  773. package/node_modules/bare-url/prebuilds/android-ia32/bare-url.bare +0 -0
  774. package/node_modules/bare-url/prebuilds/android-x64/bare-url.bare +0 -0
  775. package/node_modules/bare-url/prebuilds/darwin-arm64/bare-url.bare +0 -0
  776. package/node_modules/bare-url/prebuilds/darwin-x64/bare-url.bare +0 -0
  777. package/node_modules/bare-url/prebuilds/ios-arm64/bare-url.bare +0 -0
  778. package/node_modules/bare-url/prebuilds/ios-arm64-simulator/bare-url.bare +0 -0
  779. package/node_modules/bare-url/prebuilds/ios-x64-simulator/bare-url.bare +0 -0
  780. package/node_modules/bare-url/prebuilds/linux-arm64/bare-url.bare +0 -0
  781. package/node_modules/bare-url/prebuilds/linux-x64/bare-url.bare +0 -0
  782. package/node_modules/bare-url/prebuilds/win32-arm64/bare-url.bare +0 -0
  783. package/node_modules/bare-url/prebuilds/win32-x64/bare-url.bare +0 -0
  784. package/node_modules/commander/LICENSE +22 -0
  785. package/node_modules/commander/Readme.md +1172 -0
  786. package/node_modules/commander/index.js +21 -0
  787. package/node_modules/commander/lib/argument.js +147 -0
  788. package/node_modules/commander/lib/command.js +2790 -0
  789. package/node_modules/commander/lib/error.js +36 -0
  790. package/node_modules/commander/lib/help.js +731 -0
  791. package/node_modules/commander/lib/option.js +377 -0
  792. package/node_modules/commander/lib/suggestSimilar.js +99 -0
  793. package/node_modules/commander/package-support.json +19 -0
  794. package/node_modules/commander/package.json +64 -0
  795. package/node_modules/commander/typings/index.d.ts +1113 -0
  796. package/node_modules/esbuild/LICENSE.md +21 -0
  797. package/node_modules/esbuild/README.md +3 -0
  798. package/node_modules/esbuild/bin/esbuild +223 -0
  799. package/node_modules/esbuild/install.js +300 -0
  800. package/node_modules/esbuild/lib/main.d.ts +720 -0
  801. package/node_modules/esbuild/lib/main.js +2536 -0
  802. package/node_modules/esbuild/package.json +74 -0
  803. package/node_modules/events-universal/LICENSE +201 -0
  804. package/node_modules/events-universal/README.md +17 -0
  805. package/node_modules/events-universal/bare.js +1 -0
  806. package/node_modules/events-universal/default.js +1 -0
  807. package/node_modules/events-universal/index.js +1 -0
  808. package/node_modules/events-universal/package.json +39 -0
  809. package/node_modules/events-universal/react-native.js +1 -0
  810. package/node_modules/fast-fifo/LICENSE +21 -0
  811. package/node_modules/fast-fifo/README.md +78 -0
  812. package/node_modules/fast-fifo/fixed-size.js +39 -0
  813. package/node_modules/fast-fifo/index.js +48 -0
  814. package/node_modules/fast-fifo/package.json +28 -0
  815. package/node_modules/fast-string-truncated-width/dist/index.d.ts +4 -0
  816. package/node_modules/fast-string-truncated-width/dist/index.js +111 -0
  817. package/node_modules/fast-string-truncated-width/dist/types.d.ts +19 -0
  818. package/node_modules/fast-string-truncated-width/dist/types.js +2 -0
  819. package/node_modules/fast-string-truncated-width/dist/utils.d.ts +4 -0
  820. package/node_modules/fast-string-truncated-width/dist/utils.js +20 -0
  821. package/node_modules/fast-string-truncated-width/license +21 -0
  822. package/node_modules/fast-string-truncated-width/package.json +35 -0
  823. package/node_modules/fast-string-truncated-width/readme.md +59 -0
  824. package/node_modules/fast-string-width/dist/index.d.ts +4 -0
  825. package/node_modules/fast-string-width/dist/index.js +14 -0
  826. package/node_modules/fast-string-width/license +21 -0
  827. package/node_modules/fast-string-width/package.json +34 -0
  828. package/node_modules/fast-string-width/readme.md +42 -0
  829. package/node_modules/fast-wrap-ansi/LICENSE +23 -0
  830. package/node_modules/fast-wrap-ansi/README.md +26 -0
  831. package/node_modules/fast-wrap-ansi/lib/main.d.ts +6 -0
  832. package/node_modules/fast-wrap-ansi/lib/main.js +218 -0
  833. package/node_modules/fast-wrap-ansi/package.json +51 -0
  834. package/node_modules/sisteransi/license +21 -0
  835. package/node_modules/sisteransi/package.json +34 -0
  836. package/node_modules/sisteransi/readme.md +113 -0
  837. package/node_modules/sisteransi/src/index.js +58 -0
  838. package/node_modules/sisteransi/src/sisteransi.d.ts +35 -0
  839. package/node_modules/skillflag/LICENSE +21 -0
  840. package/node_modules/skillflag/README.md +44 -0
  841. package/node_modules/skillflag/dist/bin/skill-install.d.ts +3 -0
  842. package/node_modules/skillflag/dist/bin/skill-install.d.ts.map +1 -0
  843. package/node_modules/skillflag/dist/bin/skill-install.js +6 -0
  844. package/node_modules/skillflag/dist/bin/skill-install.js.map +1 -0
  845. package/node_modules/skillflag/dist/bin/skillflag.d.ts +3 -0
  846. package/node_modules/skillflag/dist/bin/skillflag.d.ts.map +1 -0
  847. package/node_modules/skillflag/dist/bin/skillflag.js +25 -0
  848. package/node_modules/skillflag/dist/bin/skillflag.js.map +1 -0
  849. package/node_modules/skillflag/dist/core/digest.d.ts +2 -0
  850. package/node_modules/skillflag/dist/core/digest.d.ts.map +1 -0
  851. package/node_modules/skillflag/dist/core/digest.js +15 -0
  852. package/node_modules/skillflag/dist/core/digest.js.map +1 -0
  853. package/node_modules/skillflag/dist/core/errors.d.ts +6 -0
  854. package/node_modules/skillflag/dist/core/errors.d.ts.map +1 -0
  855. package/node_modules/skillflag/dist/core/errors.js +13 -0
  856. package/node_modules/skillflag/dist/core/errors.js.map +1 -0
  857. package/node_modules/skillflag/dist/core/export.d.ts +2 -0
  858. package/node_modules/skillflag/dist/core/export.d.ts.map +1 -0
  859. package/node_modules/skillflag/dist/core/export.js +28 -0
  860. package/node_modules/skillflag/dist/core/export.js.map +1 -0
  861. package/node_modules/skillflag/dist/core/list.d.ts +21 -0
  862. package/node_modules/skillflag/dist/core/list.d.ts.map +1 -0
  863. package/node_modules/skillflag/dist/core/list.js +71 -0
  864. package/node_modules/skillflag/dist/core/list.js.map +1 -0
  865. package/node_modules/skillflag/dist/core/paths.d.ts +15 -0
  866. package/node_modules/skillflag/dist/core/paths.d.ts.map +1 -0
  867. package/node_modules/skillflag/dist/core/paths.js +149 -0
  868. package/node_modules/skillflag/dist/core/paths.js.map +1 -0
  869. package/node_modules/skillflag/dist/core/show.d.ts +2 -0
  870. package/node_modules/skillflag/dist/core/show.d.ts.map +1 -0
  871. package/node_modules/skillflag/dist/core/show.js +8 -0
  872. package/node_modules/skillflag/dist/core/show.js.map +1 -0
  873. package/node_modules/skillflag/dist/core/skillflag.d.ts +3 -0
  874. package/node_modules/skillflag/dist/core/skillflag.d.ts.map +1 -0
  875. package/node_modules/skillflag/dist/core/skillflag.js +2 -0
  876. package/node_modules/skillflag/dist/core/skillflag.js.map +1 -0
  877. package/node_modules/skillflag/dist/core/tar.d.ts +16 -0
  878. package/node_modules/skillflag/dist/core/tar.d.ts.map +1 -0
  879. package/node_modules/skillflag/dist/core/tar.js +140 -0
  880. package/node_modules/skillflag/dist/core/tar.js.map +1 -0
  881. package/node_modules/skillflag/dist/index.d.ts +5 -0
  882. package/node_modules/skillflag/dist/index.d.ts.map +1 -0
  883. package/node_modules/skillflag/dist/index.js +3 -0
  884. package/node_modules/skillflag/dist/index.js.map +1 -0
  885. package/node_modules/skillflag/dist/install/cli.d.ts +57 -0
  886. package/node_modules/skillflag/dist/install/cli.d.ts.map +1 -0
  887. package/node_modules/skillflag/dist/install/cli.js +653 -0
  888. package/node_modules/skillflag/dist/install/cli.js.map +1 -0
  889. package/node_modules/skillflag/dist/install/copy.d.ts +2 -0
  890. package/node_modules/skillflag/dist/install/copy.d.ts.map +1 -0
  891. package/node_modules/skillflag/dist/install/copy.js +19 -0
  892. package/node_modules/skillflag/dist/install/copy.js.map +1 -0
  893. package/node_modules/skillflag/dist/install/errors.d.ts +6 -0
  894. package/node_modules/skillflag/dist/install/errors.d.ts.map +1 -0
  895. package/node_modules/skillflag/dist/install/errors.js +13 -0
  896. package/node_modules/skillflag/dist/install/errors.js.map +1 -0
  897. package/node_modules/skillflag/dist/install/extract.d.ts +3 -0
  898. package/node_modules/skillflag/dist/install/extract.d.ts.map +1 -0
  899. package/node_modules/skillflag/dist/install/extract.js +76 -0
  900. package/node_modules/skillflag/dist/install/extract.js.map +1 -0
  901. package/node_modules/skillflag/dist/install/install.d.ts +21 -0
  902. package/node_modules/skillflag/dist/install/install.d.ts.map +1 -0
  903. package/node_modules/skillflag/dist/install/install.js +35 -0
  904. package/node_modules/skillflag/dist/install/install.js.map +1 -0
  905. package/node_modules/skillflag/dist/install/resolve.d.ts +12 -0
  906. package/node_modules/skillflag/dist/install/resolve.d.ts.map +1 -0
  907. package/node_modules/skillflag/dist/install/resolve.js +119 -0
  908. package/node_modules/skillflag/dist/install/resolve.js.map +1 -0
  909. package/node_modules/skillflag/dist/install/validate.d.ts +7 -0
  910. package/node_modules/skillflag/dist/install/validate.d.ts.map +1 -0
  911. package/node_modules/skillflag/dist/install/validate.js +28 -0
  912. package/node_modules/skillflag/dist/install/validate.js.map +1 -0
  913. package/node_modules/skillflag/dist/shared/frontmatter.d.ts +2 -0
  914. package/node_modules/skillflag/dist/shared/frontmatter.d.ts.map +1 -0
  915. package/node_modules/skillflag/dist/shared/frontmatter.js +28 -0
  916. package/node_modules/skillflag/dist/shared/frontmatter.js.map +1 -0
  917. package/node_modules/skillflag/dist/skillflag.d.ts +29 -0
  918. package/node_modules/skillflag/dist/skillflag.d.ts.map +1 -0
  919. package/node_modules/skillflag/dist/skillflag.js +230 -0
  920. package/node_modules/skillflag/dist/skillflag.js.map +1 -0
  921. package/node_modules/skillflag/dist/utils/collections.d.ts +3 -0
  922. package/node_modules/skillflag/dist/utils/collections.d.ts.map +1 -0
  923. package/node_modules/skillflag/dist/utils/collections.js +18 -0
  924. package/node_modules/skillflag/dist/utils/collections.js.map +1 -0
  925. package/node_modules/skillflag/package.json +78 -0
  926. package/node_modules/skillflag/skills/skillflag/SKILL.md +144 -0
  927. package/node_modules/streamx/LICENSE +21 -0
  928. package/node_modules/streamx/README.md +550 -0
  929. package/node_modules/streamx/index.d.ts +198 -0
  930. package/node_modules/streamx/index.js +1314 -0
  931. package/node_modules/streamx/lib/errors.d.ts +13 -0
  932. package/node_modules/streamx/lib/errors.js +47 -0
  933. package/node_modules/streamx/package.json +51 -0
  934. package/node_modules/streamx/runtime.d.ts +55 -0
  935. package/node_modules/tar-stream/LICENSE +21 -0
  936. package/node_modules/tar-stream/README.md +183 -0
  937. package/node_modules/tar-stream/constants.js +14 -0
  938. package/node_modules/tar-stream/extract.js +418 -0
  939. package/node_modules/tar-stream/headers.js +322 -0
  940. package/node_modules/tar-stream/index.d.ts +60 -0
  941. package/node_modules/tar-stream/index.js +2 -0
  942. package/node_modules/tar-stream/pack.js +287 -0
  943. package/node_modules/tar-stream/package.json +50 -0
  944. package/node_modules/teex/LICENSE +21 -0
  945. package/node_modules/teex/README.md +31 -0
  946. package/node_modules/teex/example.js +16 -0
  947. package/node_modules/teex/index.js +52 -0
  948. package/node_modules/teex/package.json +26 -0
  949. package/node_modules/teex/test.js +68 -0
  950. package/node_modules/text-decoder/LICENSE +201 -0
  951. package/node_modules/text-decoder/README.md +36 -0
  952. package/node_modules/text-decoder/index.js +64 -0
  953. package/node_modules/text-decoder/lib/pass-through-decoder.js +19 -0
  954. package/node_modules/text-decoder/lib/utf8-decoder.js +185 -0
  955. package/node_modules/text-decoder/package.json +39 -0
  956. package/node_modules/tsx/LICENSE +21 -0
  957. package/node_modules/tsx/README.md +32 -0
  958. package/node_modules/tsx/dist/cjs/api/index.cjs +2 -0
  959. package/node_modules/tsx/dist/cjs/api/index.d.cts +35 -0
  960. package/node_modules/tsx/dist/cjs/api/index.d.mts +35 -0
  961. package/node_modules/tsx/dist/cjs/api/index.mjs +2 -0
  962. package/node_modules/tsx/dist/cjs/index.cjs +1 -0
  963. package/node_modules/tsx/dist/cli.mjs +55 -0
  964. package/node_modules/tsx/dist/client-XItNFmsq.cjs +1 -0
  965. package/node_modules/tsx/dist/esm/api/index.cjs +2 -0
  966. package/node_modules/tsx/dist/esm/api/index.d.cts +37 -0
  967. package/node_modules/tsx/dist/esm/api/index.d.mts +37 -0
  968. package/node_modules/tsx/dist/esm/api/index.mjs +2 -0
  969. package/node_modules/tsx/dist/esm/index.mjs +2 -0
  970. package/node_modules/tsx/dist/index-Bqjv9TxC.mjs +1 -0
  971. package/node_modules/tsx/dist/index-DE3OBZuV.mjs +14 -0
  972. package/node_modules/tsx/dist/lexer-CGfpMDSb.cjs +3 -0
  973. package/node_modules/tsx/dist/lexer-CanA6ArK.mjs +3 -0
  974. package/node_modules/tsx/dist/loader.mjs +2 -0
  975. package/node_modules/tsx/dist/package-Dj0mHsMt.mjs +1 -0
  976. package/node_modules/tsx/dist/patch-repl.cjs +1 -0
  977. package/node_modules/tsx/dist/preflight.cjs +1 -0
  978. package/node_modules/tsx/dist/register-B1c7OH6V.cjs +23 -0
  979. package/node_modules/tsx/dist/register-nyXW-TH3.mjs +2 -0
  980. package/node_modules/tsx/dist/repl.mjs +4 -0
  981. package/node_modules/tsx/dist/require-CBjy4Foe.mjs +10 -0
  982. package/node_modules/tsx/dist/require-CVaYn9z3.cjs +1 -0
  983. package/node_modules/tsx/dist/suppress-warnings.cjs +1 -0
  984. package/node_modules/tsx/dist/temporary-directory-Du7LpLp9.mjs +1 -0
  985. package/node_modules/tsx/package.json +70 -0
  986. package/node_modules/zod/LICENSE +21 -0
  987. package/node_modules/zod/README.md +218 -0
  988. package/node_modules/zod/compile.cjs +96 -0
  989. package/node_modules/zod/compile.d.cts +1 -0
  990. package/node_modules/zod/compile.d.ts +1 -0
  991. package/node_modules/zod/compile.js +52 -0
  992. package/node_modules/zod/index.cjs +52 -0
  993. package/node_modules/zod/index.d.cts +3 -0
  994. package/node_modules/zod/index.d.ts +3 -0
  995. package/node_modules/zod/index.js +7 -0
  996. package/node_modules/zod/locales/index.cjs +36 -0
  997. package/node_modules/zod/locales/index.d.cts +1 -0
  998. package/node_modules/zod/locales/index.d.ts +1 -0
  999. package/node_modules/zod/locales/index.js +1 -0
  1000. package/node_modules/zod/locales/package.json +7 -0
  1001. package/node_modules/zod/mini/index.cjs +51 -0
  1002. package/node_modules/zod/mini/index.d.cts +3 -0
  1003. package/node_modules/zod/mini/index.d.ts +3 -0
  1004. package/node_modules/zod/mini/index.js +3 -0
  1005. package/node_modules/zod/mini/package.json +7 -0
  1006. package/node_modules/zod/package.json +147 -0
  1007. package/node_modules/zod/src/compile.ts +56 -0
  1008. package/node_modules/zod/src/index.ts +7 -0
  1009. package/node_modules/zod/src/locales/index.ts +1 -0
  1010. package/node_modules/zod/src/mini/index.ts +3 -0
  1011. package/node_modules/zod/src/v3/ZodError.ts +340 -0
  1012. package/node_modules/zod/src/v3/benchmarks/datetime.ts +58 -0
  1013. package/node_modules/zod/src/v3/benchmarks/discriminatedUnion.ts +80 -0
  1014. package/node_modules/zod/src/v3/benchmarks/index.ts +59 -0
  1015. package/node_modules/zod/src/v3/benchmarks/ipv4.ts +57 -0
  1016. package/node_modules/zod/src/v3/benchmarks/object.ts +69 -0
  1017. package/node_modules/zod/src/v3/benchmarks/primitives.ts +162 -0
  1018. package/node_modules/zod/src/v3/benchmarks/realworld.ts +63 -0
  1019. package/node_modules/zod/src/v3/benchmarks/string.ts +55 -0
  1020. package/node_modules/zod/src/v3/benchmarks/union.ts +80 -0
  1021. package/node_modules/zod/src/v3/errors.ts +13 -0
  1022. package/node_modules/zod/src/v3/external.ts +6 -0
  1023. package/node_modules/zod/src/v3/helpers/enumUtil.ts +17 -0
  1024. package/node_modules/zod/src/v3/helpers/errorUtil.ts +8 -0
  1025. package/node_modules/zod/src/v3/helpers/parseUtil.ts +176 -0
  1026. package/node_modules/zod/src/v3/helpers/partialUtil.ts +34 -0
  1027. package/node_modules/zod/src/v3/helpers/typeAliases.ts +2 -0
  1028. package/node_modules/zod/src/v3/helpers/util.ts +224 -0
  1029. package/node_modules/zod/src/v3/index.ts +4 -0
  1030. package/node_modules/zod/src/v3/locales/en.ts +124 -0
  1031. package/node_modules/zod/src/v3/standard-schema.ts +113 -0
  1032. package/node_modules/zod/src/v3/tests/Mocker.ts +54 -0
  1033. package/node_modules/zod/src/v3/tests/all-errors.test.ts +157 -0
  1034. package/node_modules/zod/src/v3/tests/anyunknown.test.ts +28 -0
  1035. package/node_modules/zod/src/v3/tests/array.test.ts +71 -0
  1036. package/node_modules/zod/src/v3/tests/async-parsing.test.ts +388 -0
  1037. package/node_modules/zod/src/v3/tests/async-refinements.test.ts +46 -0
  1038. package/node_modules/zod/src/v3/tests/base.test.ts +29 -0
  1039. package/node_modules/zod/src/v3/tests/bigint.test.ts +55 -0
  1040. package/node_modules/zod/src/v3/tests/branded.test.ts +53 -0
  1041. package/node_modules/zod/src/v3/tests/catch.test.ts +220 -0
  1042. package/node_modules/zod/src/v3/tests/coerce.test.ts +133 -0
  1043. package/node_modules/zod/src/v3/tests/complex.test.ts +70 -0
  1044. package/node_modules/zod/src/v3/tests/custom.test.ts +31 -0
  1045. package/node_modules/zod/src/v3/tests/date.test.ts +32 -0
  1046. package/node_modules/zod/src/v3/tests/deepmasking.test.ts +186 -0
  1047. package/node_modules/zod/src/v3/tests/default.test.ts +112 -0
  1048. package/node_modules/zod/src/v3/tests/description.test.ts +33 -0
  1049. package/node_modules/zod/src/v3/tests/discriminated-unions.test.ts +315 -0
  1050. package/node_modules/zod/src/v3/tests/enum.test.ts +80 -0
  1051. package/node_modules/zod/src/v3/tests/error.test.ts +586 -0
  1052. package/node_modules/zod/src/v3/tests/firstparty.test.ts +87 -0
  1053. package/node_modules/zod/src/v3/tests/firstpartyschematypes.test.ts +21 -0
  1054. package/node_modules/zod/src/v3/tests/function.test.ts +261 -0
  1055. package/node_modules/zod/src/v3/tests/generics.test.ts +48 -0
  1056. package/node_modules/zod/src/v3/tests/instanceof.test.ts +37 -0
  1057. package/node_modules/zod/src/v3/tests/intersection.test.ts +128 -0
  1058. package/node_modules/zod/src/v3/tests/language-server.source.ts +76 -0
  1059. package/node_modules/zod/src/v3/tests/language-server.test.ts +206 -0
  1060. package/node_modules/zod/src/v3/tests/literal.test.ts +36 -0
  1061. package/node_modules/zod/src/v3/tests/map.test.ts +110 -0
  1062. package/node_modules/zod/src/v3/tests/masking.test.ts +4 -0
  1063. package/node_modules/zod/src/v3/tests/mocker.test.ts +19 -0
  1064. package/node_modules/zod/src/v3/tests/nan.test.ts +24 -0
  1065. package/node_modules/zod/src/v3/tests/nativeEnum.test.ts +87 -0
  1066. package/node_modules/zod/src/v3/tests/nullable.test.ts +42 -0
  1067. package/node_modules/zod/src/v3/tests/number.test.ts +176 -0
  1068. package/node_modules/zod/src/v3/tests/object-augmentation.test.ts +29 -0
  1069. package/node_modules/zod/src/v3/tests/object-in-es5-env.test.ts +29 -0
  1070. package/node_modules/zod/src/v3/tests/object.test.ts +431 -0
  1071. package/node_modules/zod/src/v3/tests/optional.test.ts +42 -0
  1072. package/node_modules/zod/src/v3/tests/parseUtil.test.ts +23 -0
  1073. package/node_modules/zod/src/v3/tests/parser.test.ts +41 -0
  1074. package/node_modules/zod/src/v3/tests/partials.test.ts +243 -0
  1075. package/node_modules/zod/src/v3/tests/pickomit.test.ts +111 -0
  1076. package/node_modules/zod/src/v3/tests/pipeline.test.ts +29 -0
  1077. package/node_modules/zod/src/v3/tests/preprocess.test.ts +186 -0
  1078. package/node_modules/zod/src/v3/tests/primitive.test.ts +440 -0
  1079. package/node_modules/zod/src/v3/tests/promise.test.ts +90 -0
  1080. package/node_modules/zod/src/v3/tests/readonly.test.ts +114 -0
  1081. package/node_modules/zod/src/v3/tests/record.test.ts +171 -0
  1082. package/node_modules/zod/src/v3/tests/recursive.test.ts +197 -0
  1083. package/node_modules/zod/src/v3/tests/refine.test.ts +313 -0
  1084. package/node_modules/zod/src/v3/tests/safeparse.test.ts +27 -0
  1085. package/node_modules/zod/src/v3/tests/set.test.ts +142 -0
  1086. package/node_modules/zod/src/v3/tests/standard-schema.test.ts +83 -0
  1087. package/node_modules/zod/src/v3/tests/string.test.ts +922 -0
  1088. package/node_modules/zod/src/v3/tests/transformer.test.ts +233 -0
  1089. package/node_modules/zod/src/v3/tests/tuple.test.ts +90 -0
  1090. package/node_modules/zod/src/v3/tests/unions.test.ts +57 -0
  1091. package/node_modules/zod/src/v3/tests/validations.test.ts +133 -0
  1092. package/node_modules/zod/src/v3/tests/void.test.ts +15 -0
  1093. package/node_modules/zod/src/v3/types.ts +5138 -0
  1094. package/node_modules/zod/src/v4/classic/checks.ts +33 -0
  1095. package/node_modules/zod/src/v4/classic/coerce.ts +27 -0
  1096. package/node_modules/zod/src/v4/classic/compat.ts +78 -0
  1097. package/node_modules/zod/src/v4/classic/deep-partial.ts +76 -0
  1098. package/node_modules/zod/src/v4/classic/errors.ts +97 -0
  1099. package/node_modules/zod/src/v4/classic/external.ts +57 -0
  1100. package/node_modules/zod/src/v4/classic/from-json-schema.ts +944 -0
  1101. package/node_modules/zod/src/v4/classic/in-out.ts +45 -0
  1102. package/node_modules/zod/src/v4/classic/index.ts +5 -0
  1103. package/node_modules/zod/src/v4/classic/iso.ts +20 -0
  1104. package/node_modules/zod/src/v4/classic/parse.ts +88 -0
  1105. package/node_modules/zod/src/v4/classic/schemas.ts +2937 -0
  1106. package/node_modules/zod/src/v4/classic/tests/anyunknown.test.ts +26 -0
  1107. package/node_modules/zod/src/v4/classic/tests/apply.test.ts +86 -0
  1108. package/node_modules/zod/src/v4/classic/tests/array.test.ts +264 -0
  1109. package/node_modules/zod/src/v4/classic/tests/assignability.test.ts +402 -0
  1110. package/node_modules/zod/src/v4/classic/tests/async-parsing.test.ts +381 -0
  1111. package/node_modules/zod/src/v4/classic/tests/async-refinements.test.ts +68 -0
  1112. package/node_modules/zod/src/v4/classic/tests/base.test.ts +7 -0
  1113. package/node_modules/zod/src/v4/classic/tests/bigint.test.ts +89 -0
  1114. package/node_modules/zod/src/v4/classic/tests/brand.test.ts +106 -0
  1115. package/node_modules/zod/src/v4/classic/tests/catch.test.ts +604 -0
  1116. package/node_modules/zod/src/v4/classic/tests/coalesce.test.ts +20 -0
  1117. package/node_modules/zod/src/v4/classic/tests/codec-examples.test.ts +572 -0
  1118. package/node_modules/zod/src/v4/classic/tests/codec.test.ts +704 -0
  1119. package/node_modules/zod/src/v4/classic/tests/coerce.test.ts +160 -0
  1120. package/node_modules/zod/src/v4/classic/tests/continuability.test.ts +374 -0
  1121. package/node_modules/zod/src/v4/classic/tests/credit-card.test.ts +76 -0
  1122. package/node_modules/zod/src/v4/classic/tests/custom.test.ts +40 -0
  1123. package/node_modules/zod/src/v4/classic/tests/cyclic-data.test.ts +985 -0
  1124. package/node_modules/zod/src/v4/classic/tests/date.test.ts +92 -0
  1125. package/node_modules/zod/src/v4/classic/tests/datetime.test.ts +316 -0
  1126. package/node_modules/zod/src/v4/classic/tests/deep-partial.test.ts +380 -0
  1127. package/node_modules/zod/src/v4/classic/tests/default-locale.test.ts +32 -0
  1128. package/node_modules/zod/src/v4/classic/tests/default.test.ts +455 -0
  1129. package/node_modules/zod/src/v4/classic/tests/describe-meta-checks.test.ts +27 -0
  1130. package/node_modules/zod/src/v4/classic/tests/description.test.ts +32 -0
  1131. package/node_modules/zod/src/v4/classic/tests/detached-methods.test.ts +221 -0
  1132. package/node_modules/zod/src/v4/classic/tests/discriminated-unions.test.ts +942 -0
  1133. package/node_modules/zod/src/v4/classic/tests/enum.test.ts +305 -0
  1134. package/node_modules/zod/src/v4/classic/tests/error-utils.test.ts +917 -0
  1135. package/node_modules/zod/src/v4/classic/tests/error.test.ts +1108 -0
  1136. package/node_modules/zod/src/v4/classic/tests/file.test.ts +96 -0
  1137. package/node_modules/zod/src/v4/classic/tests/firstparty.test.ts +179 -0
  1138. package/node_modules/zod/src/v4/classic/tests/fix-json-issue.test.ts +26 -0
  1139. package/node_modules/zod/src/v4/classic/tests/from-json-schema.test.ts +1467 -0
  1140. package/node_modules/zod/src/v4/classic/tests/function.test.ts +391 -0
  1141. package/node_modules/zod/src/v4/classic/tests/generics.test.ts +72 -0
  1142. package/node_modules/zod/src/v4/classic/tests/global-config.test.ts +32 -0
  1143. package/node_modules/zod/src/v4/classic/tests/hash.test.ts +67 -0
  1144. package/node_modules/zod/src/v4/classic/tests/iban.test.ts +81 -0
  1145. package/node_modules/zod/src/v4/classic/tests/in-out.test.ts +159 -0
  1146. package/node_modules/zod/src/v4/classic/tests/index.test.ts +958 -0
  1147. package/node_modules/zod/src/v4/classic/tests/instance-footprint.test.ts +319 -0
  1148. package/node_modules/zod/src/v4/classic/tests/instanceof.test.ts +127 -0
  1149. package/node_modules/zod/src/v4/classic/tests/intersection.test.ts +334 -0
  1150. package/node_modules/zod/src/v4/classic/tests/issue-schema.test.ts +215 -0
  1151. package/node_modules/zod/src/v4/classic/tests/jitless-allows-eval.test.ts +39 -0
  1152. package/node_modules/zod/src/v4/classic/tests/json.test.ts +109 -0
  1153. package/node_modules/zod/src/v4/classic/tests/lazy.test.ts +262 -0
  1154. package/node_modules/zod/src/v4/classic/tests/literal.test.ts +128 -0
  1155. package/node_modules/zod/src/v4/classic/tests/locales_ka.test.ts +29 -0
  1156. package/node_modules/zod/src/v4/classic/tests/locales_ro.test.ts +24 -0
  1157. package/node_modules/zod/src/v4/classic/tests/map.test.ts +342 -0
  1158. package/node_modules/zod/src/v4/classic/tests/nan.test.ts +21 -0
  1159. package/node_modules/zod/src/v4/classic/tests/nested-refine.test.ts +168 -0
  1160. package/node_modules/zod/src/v4/classic/tests/nonoptional.test.ts +101 -0
  1161. package/node_modules/zod/src/v4/classic/tests/nullable.test.ts +22 -0
  1162. package/node_modules/zod/src/v4/classic/tests/number.test.ts +401 -0
  1163. package/node_modules/zod/src/v4/classic/tests/object.test.ts +1006 -0
  1164. package/node_modules/zod/src/v4/classic/tests/optin-ladder.test.ts +235 -0
  1165. package/node_modules/zod/src/v4/classic/tests/optional.test.ts +366 -0
  1166. package/node_modules/zod/src/v4/classic/tests/partial.test.ts +497 -0
  1167. package/node_modules/zod/src/v4/classic/tests/pickomit.test.ts +211 -0
  1168. package/node_modules/zod/src/v4/classic/tests/pipe.test.ts +101 -0
  1169. package/node_modules/zod/src/v4/classic/tests/prefault.test.ts +144 -0
  1170. package/node_modules/zod/src/v4/classic/tests/preprocess-types.test.ts +44 -0
  1171. package/node_modules/zod/src/v4/classic/tests/preprocess.test.ts +351 -0
  1172. package/node_modules/zod/src/v4/classic/tests/primitive.test.ts +175 -0
  1173. package/node_modules/zod/src/v4/classic/tests/promise.test.ts +81 -0
  1174. package/node_modules/zod/src/v4/classic/tests/properties.test.ts +141 -0
  1175. package/node_modules/zod/src/v4/classic/tests/prototypes.test.ts +23 -0
  1176. package/node_modules/zod/src/v4/classic/tests/readonly.test.ts +184 -0
  1177. package/node_modules/zod/src/v4/classic/tests/record.test.ts +885 -0
  1178. package/node_modules/zod/src/v4/classic/tests/recursive-types.test.ts +707 -0
  1179. package/node_modules/zod/src/v4/classic/tests/redos.test.ts +68 -0
  1180. package/node_modules/zod/src/v4/classic/tests/refine.test.ts +693 -0
  1181. package/node_modules/zod/src/v4/classic/tests/registries.test.ts +243 -0
  1182. package/node_modules/zod/src/v4/classic/tests/set.test.ts +190 -0
  1183. package/node_modules/zod/src/v4/classic/tests/standard-schema.test.ts +153 -0
  1184. package/node_modules/zod/src/v4/classic/tests/string-formats.test.ts +125 -0
  1185. package/node_modules/zod/src/v4/classic/tests/string.test.ts +1440 -0
  1186. package/node_modules/zod/src/v4/classic/tests/stringbool.test.ts +124 -0
  1187. package/node_modules/zod/src/v4/classic/tests/template-literal.test.ts +812 -0
  1188. package/node_modules/zod/src/v4/classic/tests/to-json-schema-methods.test.ts +438 -0
  1189. package/node_modules/zod/src/v4/classic/tests/to-json-schema.test.ts +4733 -0
  1190. package/node_modules/zod/src/v4/classic/tests/transform.test.ts +378 -0
  1191. package/node_modules/zod/src/v4/classic/tests/tuple.test.ts +511 -0
  1192. package/node_modules/zod/src/v4/classic/tests/union.test.ts +310 -0
  1193. package/node_modules/zod/src/v4/classic/tests/url.test.ts +13 -0
  1194. package/node_modules/zod/src/v4/classic/tests/validate.test.ts +645 -0
  1195. package/node_modules/zod/src/v4/classic/tests/validations.test.ts +283 -0
  1196. package/node_modules/zod/src/v4/classic/tests/void.test.ts +12 -0
  1197. package/node_modules/zod/src/v4/core/api.ts +1875 -0
  1198. package/node_modules/zod/src/v4/core/checks.ts +1266 -0
  1199. package/node_modules/zod/src/v4/core/compile.ts +2313 -0
  1200. package/node_modules/zod/src/v4/core/core.ts +230 -0
  1201. package/node_modules/zod/src/v4/core/doc.ts +52 -0
  1202. package/node_modules/zod/src/v4/core/errors.ts +543 -0
  1203. package/node_modules/zod/src/v4/core/index.ts +19 -0
  1204. package/node_modules/zod/src/v4/core/json-schema-generator.ts +131 -0
  1205. package/node_modules/zod/src/v4/core/json-schema-processors.ts +934 -0
  1206. package/node_modules/zod/src/v4/core/json-schema.ts +148 -0
  1207. package/node_modules/zod/src/v4/core/memoizer.ts +331 -0
  1208. package/node_modules/zod/src/v4/core/parse.ts +309 -0
  1209. package/node_modules/zod/src/v4/core/regexes.ts +217 -0
  1210. package/node_modules/zod/src/v4/core/registries.ts +105 -0
  1211. package/node_modules/zod/src/v4/core/schemas.ts +5192 -0
  1212. package/node_modules/zod/src/v4/core/standard-schema.ts +159 -0
  1213. package/node_modules/zod/src/v4/core/tests/cached.test.ts +54 -0
  1214. package/node_modules/zod/src/v4/core/tests/compile-differential.test.ts +1004 -0
  1215. package/node_modules/zod/src/v4/core/tests/compile-generative.test.ts +445 -0
  1216. package/node_modules/zod/src/v4/core/tests/compile-global.test.ts +89 -0
  1217. package/node_modules/zod/src/v4/core/tests/compile-off-by-default.test.ts +26 -0
  1218. package/node_modules/zod/src/v4/core/tests/compile-stats.test.ts +34 -0
  1219. package/node_modules/zod/src/v4/core/tests/compile.test.ts +2036 -0
  1220. package/node_modules/zod/src/v4/core/tests/email-regex.test.ts +140 -0
  1221. package/node_modules/zod/src/v4/core/tests/extend.test.ts +59 -0
  1222. package/node_modules/zod/src/v4/core/tests/index.test.ts +46 -0
  1223. package/node_modules/zod/src/v4/core/tests/locales/be.test.ts +124 -0
  1224. package/node_modules/zod/src/v4/core/tests/locales/el.test.ts +214 -0
  1225. package/node_modules/zod/src/v4/core/tests/locales/en.test.ts +22 -0
  1226. package/node_modules/zod/src/v4/core/tests/locales/es.test.ts +180 -0
  1227. package/node_modules/zod/src/v4/core/tests/locales/fr.test.ts +72 -0
  1228. package/node_modules/zod/src/v4/core/tests/locales/he.test.ts +379 -0
  1229. package/node_modules/zod/src/v4/core/tests/locales/hr.test.ts +163 -0
  1230. package/node_modules/zod/src/v4/core/tests/locales/nl.test.ts +46 -0
  1231. package/node_modules/zod/src/v4/core/tests/locales/parity.test.ts +42 -0
  1232. package/node_modules/zod/src/v4/core/tests/locales/ru.test.ts +128 -0
  1233. package/node_modules/zod/src/v4/core/tests/locales/tg.test.ts +85 -0
  1234. package/node_modules/zod/src/v4/core/tests/locales/tk.test.ts +69 -0
  1235. package/node_modules/zod/src/v4/core/tests/locales/tr.test.ts +69 -0
  1236. package/node_modules/zod/src/v4/core/tests/locales/uz.test.ts +105 -0
  1237. package/node_modules/zod/src/v4/core/tests/polyfill-collision.test.ts +46 -0
  1238. package/node_modules/zod/src/v4/core/tests/record-constructor.test.ts +125 -0
  1239. package/node_modules/zod/src/v4/core/tests/recursive-tuples.test.ts +45 -0
  1240. package/node_modules/zod/src/v4/core/tests/treeshake.test.ts +51 -0
  1241. package/node_modules/zod/src/v4/core/tests/url-no-canparse.test.ts +133 -0
  1242. package/node_modules/zod/src/v4/core/to-json-schema.ts +857 -0
  1243. package/node_modules/zod/src/v4/core/util.ts +1280 -0
  1244. package/node_modules/zod/src/v4/core/versions.ts +5 -0
  1245. package/node_modules/zod/src/v4/core/visit.ts +193 -0
  1246. package/node_modules/zod/src/v4/core/zsf.ts +323 -0
  1247. package/node_modules/zod/src/v4/index.ts +4 -0
  1248. package/node_modules/zod/src/v4/locales/ar.ts +120 -0
  1249. package/node_modules/zod/src/v4/locales/az.ts +116 -0
  1250. package/node_modules/zod/src/v4/locales/be.ts +188 -0
  1251. package/node_modules/zod/src/v4/locales/bg.ts +133 -0
  1252. package/node_modules/zod/src/v4/locales/bn.ts +123 -0
  1253. package/node_modules/zod/src/v4/locales/ca.ts +121 -0
  1254. package/node_modules/zod/src/v4/locales/ckb.ts +140 -0
  1255. package/node_modules/zod/src/v4/locales/cs.ts +123 -0
  1256. package/node_modules/zod/src/v4/locales/da.ts +128 -0
  1257. package/node_modules/zod/src/v4/locales/de.ts +121 -0
  1258. package/node_modules/zod/src/v4/locales/el.ts +124 -0
  1259. package/node_modules/zod/src/v4/locales/en.ts +136 -0
  1260. package/node_modules/zod/src/v4/locales/eo.ts +123 -0
  1261. package/node_modules/zod/src/v4/locales/es.ts +145 -0
  1262. package/node_modules/zod/src/v4/locales/fa.ts +131 -0
  1263. package/node_modules/zod/src/v4/locales/fi.ts +126 -0
  1264. package/node_modules/zod/src/v4/locales/fr-CA.ts +121 -0
  1265. package/node_modules/zod/src/v4/locales/fr.ts +139 -0
  1266. package/node_modules/zod/src/v4/locales/gu.ts +123 -0
  1267. package/node_modules/zod/src/v4/locales/he.ts +253 -0
  1268. package/node_modules/zod/src/v4/locales/hi.ts +126 -0
  1269. package/node_modules/zod/src/v4/locales/hr.ts +135 -0
  1270. package/node_modules/zod/src/v4/locales/hu.ts +122 -0
  1271. package/node_modules/zod/src/v4/locales/hy.ts +175 -0
  1272. package/node_modules/zod/src/v4/locales/id.ts +120 -0
  1273. package/node_modules/zod/src/v4/locales/index.ts +63 -0
  1274. package/node_modules/zod/src/v4/locales/is.ts +124 -0
  1275. package/node_modules/zod/src/v4/locales/it.ts +121 -0
  1276. package/node_modules/zod/src/v4/locales/ja.ts +119 -0
  1277. package/node_modules/zod/src/v4/locales/ka.ts +128 -0
  1278. package/node_modules/zod/src/v4/locales/kh.ts +7 -0
  1279. package/node_modules/zod/src/v4/locales/km.ts +124 -0
  1280. package/node_modules/zod/src/v4/locales/kn.ts +126 -0
  1281. package/node_modules/zod/src/v4/locales/ko.ts +126 -0
  1282. package/node_modules/zod/src/v4/locales/lt.ts +243 -0
  1283. package/node_modules/zod/src/v4/locales/mk.ts +123 -0
  1284. package/node_modules/zod/src/v4/locales/ms.ts +120 -0
  1285. package/node_modules/zod/src/v4/locales/ne.ts +128 -0
  1286. package/node_modules/zod/src/v4/locales/nl.ts +126 -0
  1287. package/node_modules/zod/src/v4/locales/nn.ts +121 -0
  1288. package/node_modules/zod/src/v4/locales/no.ts +121 -0
  1289. package/node_modules/zod/src/v4/locales/ota.ts +122 -0
  1290. package/node_modules/zod/src/v4/locales/pl.ts +123 -0
  1291. package/node_modules/zod/src/v4/locales/ps.ts +131 -0
  1292. package/node_modules/zod/src/v4/locales/pt-BR.ts +161 -0
  1293. package/node_modules/zod/src/v4/locales/pt.ts +159 -0
  1294. package/node_modules/zod/src/v4/locales/ro.ts +132 -0
  1295. package/node_modules/zod/src/v4/locales/ru.ts +188 -0
  1296. package/node_modules/zod/src/v4/locales/sk.ts +123 -0
  1297. package/node_modules/zod/src/v4/locales/sl.ts +123 -0
  1298. package/node_modules/zod/src/v4/locales/sv.ts +124 -0
  1299. package/node_modules/zod/src/v4/locales/ta.ts +123 -0
  1300. package/node_modules/zod/src/v4/locales/tg.ts +135 -0
  1301. package/node_modules/zod/src/v4/locales/th.ts +124 -0
  1302. package/node_modules/zod/src/v4/locales/tk.ts +113 -0
  1303. package/node_modules/zod/src/v4/locales/tr.ts +116 -0
  1304. package/node_modules/zod/src/v4/locales/ua.ts +7 -0
  1305. package/node_modules/zod/src/v4/locales/uk.ts +122 -0
  1306. package/node_modules/zod/src/v4/locales/ur.ts +124 -0
  1307. package/node_modules/zod/src/v4/locales/uz.ts +120 -0
  1308. package/node_modules/zod/src/v4/locales/vi.ts +122 -0
  1309. package/node_modules/zod/src/v4/locales/yo.ts +129 -0
  1310. package/node_modules/zod/src/v4/locales/zh-CN.ts +121 -0
  1311. package/node_modules/zod/src/v4/locales/zh-TW.ts +120 -0
  1312. package/node_modules/zod/src/v4/mini/checks.ts +33 -0
  1313. package/node_modules/zod/src/v4/mini/coerce.ts +27 -0
  1314. package/node_modules/zod/src/v4/mini/deep-partial.ts +73 -0
  1315. package/node_modules/zod/src/v4/mini/external.ts +52 -0
  1316. package/node_modules/zod/src/v4/mini/in-out.ts +45 -0
  1317. package/node_modules/zod/src/v4/mini/index.ts +3 -0
  1318. package/node_modules/zod/src/v4/mini/iso.ts +66 -0
  1319. package/node_modules/zod/src/v4/mini/parse.ts +16 -0
  1320. package/node_modules/zod/src/v4/mini/schemas.ts +2051 -0
  1321. package/node_modules/zod/src/v4/mini/tests/apply.test.ts +57 -0
  1322. package/node_modules/zod/src/v4/mini/tests/assignability.test.ts +190 -0
  1323. package/node_modules/zod/src/v4/mini/tests/brand.test.ts +94 -0
  1324. package/node_modules/zod/src/v4/mini/tests/checks.test.ts +158 -0
  1325. package/node_modules/zod/src/v4/mini/tests/codec.test.ts +582 -0
  1326. package/node_modules/zod/src/v4/mini/tests/computed.test.ts +30 -0
  1327. package/node_modules/zod/src/v4/mini/tests/cyclic-data.test.ts +84 -0
  1328. package/node_modules/zod/src/v4/mini/tests/deep-partial.test.ts +54 -0
  1329. package/node_modules/zod/src/v4/mini/tests/error.test.ts +41 -0
  1330. package/node_modules/zod/src/v4/mini/tests/functions.test.ts +14 -0
  1331. package/node_modules/zod/src/v4/mini/tests/index.test.ts +1146 -0
  1332. package/node_modules/zod/src/v4/mini/tests/number.test.ts +109 -0
  1333. package/node_modules/zod/src/v4/mini/tests/object.test.ts +292 -0
  1334. package/node_modules/zod/src/v4/mini/tests/prototypes.test.ts +43 -0
  1335. package/node_modules/zod/src/v4/mini/tests/recursive-types.test.ts +341 -0
  1336. package/node_modules/zod/src/v4/mini/tests/standard-schema.test.ts +50 -0
  1337. package/node_modules/zod/src/v4/mini/tests/string.test.ts +396 -0
  1338. package/node_modules/zod/src/v4-mini/index.ts +3 -0
  1339. package/node_modules/zod/v3/ZodError.cjs +167 -0
  1340. package/node_modules/zod/v3/ZodError.d.cts +164 -0
  1341. package/node_modules/zod/v3/ZodError.d.ts +164 -0
  1342. package/node_modules/zod/v3/ZodError.js +143 -0
  1343. package/node_modules/zod/v3/errors.cjs +36 -0
  1344. package/node_modules/zod/v3/errors.d.cts +5 -0
  1345. package/node_modules/zod/v3/errors.d.ts +5 -0
  1346. package/node_modules/zod/v3/errors.js +9 -0
  1347. package/node_modules/zod/v3/external.cjs +41 -0
  1348. package/node_modules/zod/v3/external.d.cts +6 -0
  1349. package/node_modules/zod/v3/external.d.ts +6 -0
  1350. package/node_modules/zod/v3/external.js +6 -0
  1351. package/node_modules/zod/v3/helpers/enumUtil.cjs +21 -0
  1352. package/node_modules/zod/v3/helpers/enumUtil.d.cts +8 -0
  1353. package/node_modules/zod/v3/helpers/enumUtil.d.ts +8 -0
  1354. package/node_modules/zod/v3/helpers/enumUtil.js +1 -0
  1355. package/node_modules/zod/v3/helpers/errorUtil.cjs +28 -0
  1356. package/node_modules/zod/v3/helpers/errorUtil.d.cts +9 -0
  1357. package/node_modules/zod/v3/helpers/errorUtil.d.ts +9 -0
  1358. package/node_modules/zod/v3/helpers/errorUtil.js +6 -0
  1359. package/node_modules/zod/v3/helpers/parseUtil.cjs +143 -0
  1360. package/node_modules/zod/v3/helpers/parseUtil.d.cts +78 -0
  1361. package/node_modules/zod/v3/helpers/parseUtil.d.ts +78 -0
  1362. package/node_modules/zod/v3/helpers/parseUtil.js +109 -0
  1363. package/node_modules/zod/v3/helpers/partialUtil.cjs +21 -0
  1364. package/node_modules/zod/v3/helpers/partialUtil.d.cts +8 -0
  1365. package/node_modules/zod/v3/helpers/partialUtil.d.ts +8 -0
  1366. package/node_modules/zod/v3/helpers/partialUtil.js +1 -0
  1367. package/node_modules/zod/v3/helpers/typeAliases.cjs +21 -0
  1368. package/node_modules/zod/v3/helpers/typeAliases.d.cts +2 -0
  1369. package/node_modules/zod/v3/helpers/typeAliases.d.ts +2 -0
  1370. package/node_modules/zod/v3/helpers/typeAliases.js +1 -0
  1371. package/node_modules/zod/v3/helpers/util.cjs +156 -0
  1372. package/node_modules/zod/v3/helpers/util.d.cts +85 -0
  1373. package/node_modules/zod/v3/helpers/util.d.ts +85 -0
  1374. package/node_modules/zod/v3/helpers/util.js +133 -0
  1375. package/node_modules/zod/v3/index.cjs +52 -0
  1376. package/node_modules/zod/v3/index.d.cts +4 -0
  1377. package/node_modules/zod/v3/index.d.ts +4 -0
  1378. package/node_modules/zod/v3/index.js +4 -0
  1379. package/node_modules/zod/v3/locales/en.cjs +112 -0
  1380. package/node_modules/zod/v3/locales/en.d.cts +3 -0
  1381. package/node_modules/zod/v3/locales/en.d.ts +3 -0
  1382. package/node_modules/zod/v3/locales/en.js +109 -0
  1383. package/node_modules/zod/v3/package.json +7 -0
  1384. package/node_modules/zod/v3/standard-schema.cjs +21 -0
  1385. package/node_modules/zod/v3/standard-schema.d.cts +102 -0
  1386. package/node_modules/zod/v3/standard-schema.d.ts +102 -0
  1387. package/node_modules/zod/v3/standard-schema.js +1 -0
  1388. package/node_modules/zod/v3/types.cjs +3798 -0
  1389. package/node_modules/zod/v3/types.d.cts +1034 -0
  1390. package/node_modules/zod/v3/types.d.ts +1034 -0
  1391. package/node_modules/zod/v3/types.js +3697 -0
  1392. package/node_modules/zod/v4/classic/checks.cjs +53 -0
  1393. package/node_modules/zod/v4/classic/checks.d.cts +1 -0
  1394. package/node_modules/zod/v4/classic/checks.d.ts +1 -0
  1395. package/node_modules/zod/v4/classic/checks.js +1 -0
  1396. package/node_modules/zod/v4/classic/coerce.cjs +66 -0
  1397. package/node_modules/zod/v4/classic/coerce.d.cts +17 -0
  1398. package/node_modules/zod/v4/classic/coerce.d.ts +17 -0
  1399. package/node_modules/zod/v4/classic/coerce.js +17 -0
  1400. package/node_modules/zod/v4/classic/compat.cjs +80 -0
  1401. package/node_modules/zod/v4/classic/compat.d.cts +48 -0
  1402. package/node_modules/zod/v4/classic/compat.d.ts +48 -0
  1403. package/node_modules/zod/v4/classic/compat.js +31 -0
  1404. package/node_modules/zod/v4/classic/deep-partial.cjs +58 -0
  1405. package/node_modules/zod/v4/classic/deep-partial.d.cts +14 -0
  1406. package/node_modules/zod/v4/classic/deep-partial.d.ts +14 -0
  1407. package/node_modules/zod/v4/classic/deep-partial.js +13 -0
  1408. package/node_modules/zod/v4/classic/errors.cjs +102 -0
  1409. package/node_modules/zod/v4/classic/errors.d.cts +29 -0
  1410. package/node_modules/zod/v4/classic/errors.d.ts +29 -0
  1411. package/node_modules/zod/v4/classic/errors.js +57 -0
  1412. package/node_modules/zod/v4/classic/external.cjs +97 -0
  1413. package/node_modules/zod/v4/classic/external.d.cts +19 -0
  1414. package/node_modules/zod/v4/classic/external.d.ts +19 -0
  1415. package/node_modules/zod/v4/classic/external.js +17 -0
  1416. package/node_modules/zod/v4/classic/from-json-schema.cjs +926 -0
  1417. package/node_modules/zod/v4/classic/from-json-schema.d.cts +12 -0
  1418. package/node_modules/zod/v4/classic/from-json-schema.d.ts +12 -0
  1419. package/node_modules/zod/v4/classic/from-json-schema.js +881 -0
  1420. package/node_modules/zod/v4/classic/in-out.cjs +82 -0
  1421. package/node_modules/zod/v4/classic/in-out.d.cts +8 -0
  1422. package/node_modules/zod/v4/classic/in-out.d.ts +8 -0
  1423. package/node_modules/zod/v4/classic/in-out.js +36 -0
  1424. package/node_modules/zod/v4/classic/index.cjs +52 -0
  1425. package/node_modules/zod/v4/classic/index.d.cts +3 -0
  1426. package/node_modules/zod/v4/classic/index.d.ts +3 -0
  1427. package/node_modules/zod/v4/classic/index.js +4 -0
  1428. package/node_modules/zod/v4/classic/iso.cjs +68 -0
  1429. package/node_modules/zod/v4/classic/iso.d.cts +7 -0
  1430. package/node_modules/zod/v4/classic/iso.d.ts +7 -0
  1431. package/node_modules/zod/v4/classic/iso.js +15 -0
  1432. package/node_modules/zod/v4/classic/package.json +7 -0
  1433. package/node_modules/zod/v4/classic/parse.cjs +63 -0
  1434. package/node_modules/zod/v4/classic/parse.d.cts +44 -0
  1435. package/node_modules/zod/v4/classic/parse.d.ts +44 -0
  1436. package/node_modules/zod/v4/classic/parse.js +16 -0
  1437. package/node_modules/zod/v4/classic/schemas.cjs +1676 -0
  1438. package/node_modules/zod/v4/classic/schemas.d.cts +816 -0
  1439. package/node_modules/zod/v4/classic/schemas.d.ts +816 -0
  1440. package/node_modules/zod/v4/classic/schemas.js +1535 -0
  1441. package/node_modules/zod/v4/core/api.cjs +1269 -0
  1442. package/node_modules/zod/v4/core/api.d.cts +335 -0
  1443. package/node_modules/zod/v4/core/api.d.ts +335 -0
  1444. package/node_modules/zod/v4/core/api.js +1107 -0
  1445. package/node_modules/zod/v4/core/checks.cjs +561 -0
  1446. package/node_modules/zod/v4/core/checks.d.cts +294 -0
  1447. package/node_modules/zod/v4/core/checks.d.ts +294 -0
  1448. package/node_modules/zod/v4/core/checks.js +516 -0
  1449. package/node_modules/zod/v4/core/compile.cjs +1908 -0
  1450. package/node_modules/zod/v4/core/compile.d.cts +65 -0
  1451. package/node_modules/zod/v4/core/compile.d.ts +65 -0
  1452. package/node_modules/zod/v4/core/compile.js +1858 -0
  1453. package/node_modules/zod/v4/core/core.cjs +167 -0
  1454. package/node_modules/zod/v4/core/core.d.cts +82 -0
  1455. package/node_modules/zod/v4/core/core.d.ts +82 -0
  1456. package/node_modules/zod/v4/core/core.js +141 -0
  1457. package/node_modules/zod/v4/core/doc.cjs +61 -0
  1458. package/node_modules/zod/v4/core/doc.d.cts +16 -0
  1459. package/node_modules/zod/v4/core/doc.d.ts +16 -0
  1460. package/node_modules/zod/v4/core/doc.js +38 -0
  1461. package/node_modules/zod/v4/core/errors.cjs +317 -0
  1462. package/node_modules/zod/v4/core/errors.d.cts +225 -0
  1463. package/node_modules/zod/v4/core/errors.d.ts +225 -0
  1464. package/node_modules/zod/v4/core/errors.js +267 -0
  1465. package/node_modules/zod/v4/core/index.cjs +70 -0
  1466. package/node_modules/zod/v4/core/index.d.cts +19 -0
  1467. package/node_modules/zod/v4/core/index.d.ts +19 -0
  1468. package/node_modules/zod/v4/core/index.js +19 -0
  1469. package/node_modules/zod/v4/core/json-schema-generator.cjs +122 -0
  1470. package/node_modules/zod/v4/core/json-schema-generator.d.cts +65 -0
  1471. package/node_modules/zod/v4/core/json-schema-generator.d.ts +65 -0
  1472. package/node_modules/zod/v4/core/json-schema-generator.js +99 -0
  1473. package/node_modules/zod/v4/core/json-schema-processors.cjs +929 -0
  1474. package/node_modules/zod/v4/core/json-schema-processors.d.cts +65 -0
  1475. package/node_modules/zod/v4/core/json-schema-processors.d.ts +65 -0
  1476. package/node_modules/zod/v4/core/json-schema-processors.js +843 -0
  1477. package/node_modules/zod/v4/core/json-schema.cjs +21 -0
  1478. package/node_modules/zod/v4/core/json-schema.d.cts +89 -0
  1479. package/node_modules/zod/v4/core/json-schema.d.ts +89 -0
  1480. package/node_modules/zod/v4/core/json-schema.js +1 -0
  1481. package/node_modules/zod/v4/core/memoizer.cjs +360 -0
  1482. package/node_modules/zod/v4/core/memoizer.d.cts +15 -0
  1483. package/node_modules/zod/v4/core/memoizer.d.ts +15 -0
  1484. package/node_modules/zod/v4/core/memoizer.js +311 -0
  1485. package/node_modules/zod/v4/core/package.json +7 -0
  1486. package/node_modules/zod/v4/core/parse.cjs +233 -0
  1487. package/node_modules/zod/v4/core/parse.d.cts +52 -0
  1488. package/node_modules/zod/v4/core/parse.d.ts +52 -0
  1489. package/node_modules/zod/v4/core/parse.js +175 -0
  1490. package/node_modules/zod/v4/core/regexes.cjs +209 -0
  1491. package/node_modules/zod/v4/core/regexes.d.cts +90 -0
  1492. package/node_modules/zod/v4/core/regexes.d.ts +90 -0
  1493. package/node_modules/zod/v4/core/regexes.js +156 -0
  1494. package/node_modules/zod/v4/core/registries.cjs +75 -0
  1495. package/node_modules/zod/v4/core/registries.d.cts +35 -0
  1496. package/node_modules/zod/v4/core/registries.d.ts +35 -0
  1497. package/node_modules/zod/v4/core/registries.js +51 -0
  1498. package/node_modules/zod/v4/core/schemas.cjs +2669 -0
  1499. package/node_modules/zod/v4/core/schemas.d.cts +1273 -0
  1500. package/node_modules/zod/v4/core/schemas.d.ts +1273 -0
  1501. package/node_modules/zod/v4/core/schemas.js +2606 -0
  1502. package/node_modules/zod/v4/core/standard-schema.cjs +21 -0
  1503. package/node_modules/zod/v4/core/standard-schema.d.cts +126 -0
  1504. package/node_modules/zod/v4/core/standard-schema.d.ts +126 -0
  1505. package/node_modules/zod/v4/core/standard-schema.js +1 -0
  1506. package/node_modules/zod/v4/core/to-json-schema.cjs +681 -0
  1507. package/node_modules/zod/v4/core/to-json-schema.d.cts +154 -0
  1508. package/node_modules/zod/v4/core/to-json-schema.d.ts +154 -0
  1509. package/node_modules/zod/v4/core/to-json-schema.js +651 -0
  1510. package/node_modules/zod/v4/core/util.cjs +949 -0
  1511. package/node_modules/zod/v4/core/util.d.cts +278 -0
  1512. package/node_modules/zod/v4/core/util.d.ts +278 -0
  1513. package/node_modules/zod/v4/core/util.js +859 -0
  1514. package/node_modules/zod/v4/core/versions.cjs +27 -0
  1515. package/node_modules/zod/v4/core/versions.d.cts +5 -0
  1516. package/node_modules/zod/v4/core/versions.d.ts +5 -0
  1517. package/node_modules/zod/v4/core/versions.js +5 -0
  1518. package/node_modules/zod/v4/core/visit.cjs +214 -0
  1519. package/node_modules/zod/v4/core/visit.d.cts +30 -0
  1520. package/node_modules/zod/v4/core/visit.d.ts +30 -0
  1521. package/node_modules/zod/v4/core/visit.js +169 -0
  1522. package/node_modules/zod/v4/index.cjs +51 -0
  1523. package/node_modules/zod/v4/index.d.cts +3 -0
  1524. package/node_modules/zod/v4/index.d.ts +3 -0
  1525. package/node_modules/zod/v4/index.js +4 -0
  1526. package/node_modules/zod/v4/locales/ar.cjs +138 -0
  1527. package/node_modules/zod/v4/locales/ar.d.cts +5 -0
  1528. package/node_modules/zod/v4/locales/ar.d.ts +4 -0
  1529. package/node_modules/zod/v4/locales/ar.js +111 -0
  1530. package/node_modules/zod/v4/locales/az.cjs +137 -0
  1531. package/node_modules/zod/v4/locales/az.d.cts +5 -0
  1532. package/node_modules/zod/v4/locales/az.d.ts +4 -0
  1533. package/node_modules/zod/v4/locales/az.js +110 -0
  1534. package/node_modules/zod/v4/locales/be.cjs +195 -0
  1535. package/node_modules/zod/v4/locales/be.d.cts +5 -0
  1536. package/node_modules/zod/v4/locales/be.d.ts +4 -0
  1537. package/node_modules/zod/v4/locales/be.js +168 -0
  1538. package/node_modules/zod/v4/locales/bg.cjs +152 -0
  1539. package/node_modules/zod/v4/locales/bg.d.cts +5 -0
  1540. package/node_modules/zod/v4/locales/bg.d.ts +4 -0
  1541. package/node_modules/zod/v4/locales/bg.js +125 -0
  1542. package/node_modules/zod/v4/locales/bn.cjs +140 -0
  1543. package/node_modules/zod/v4/locales/bn.d.cts +5 -0
  1544. package/node_modules/zod/v4/locales/bn.d.ts +4 -0
  1545. package/node_modules/zod/v4/locales/bn.js +113 -0
  1546. package/node_modules/zod/v4/locales/ca.cjs +139 -0
  1547. package/node_modules/zod/v4/locales/ca.d.cts +5 -0
  1548. package/node_modules/zod/v4/locales/ca.d.ts +4 -0
  1549. package/node_modules/zod/v4/locales/ca.js +112 -0
  1550. package/node_modules/zod/v4/locales/ckb.cjs +160 -0
  1551. package/node_modules/zod/v4/locales/ckb.d.cts +5 -0
  1552. package/node_modules/zod/v4/locales/ckb.d.ts +4 -0
  1553. package/node_modules/zod/v4/locales/ckb.js +133 -0
  1554. package/node_modules/zod/v4/locales/cs.cjs +143 -0
  1555. package/node_modules/zod/v4/locales/cs.d.cts +5 -0
  1556. package/node_modules/zod/v4/locales/cs.d.ts +4 -0
  1557. package/node_modules/zod/v4/locales/cs.js +116 -0
  1558. package/node_modules/zod/v4/locales/da.cjs +147 -0
  1559. package/node_modules/zod/v4/locales/da.d.cts +5 -0
  1560. package/node_modules/zod/v4/locales/da.d.ts +4 -0
  1561. package/node_modules/zod/v4/locales/da.js +120 -0
  1562. package/node_modules/zod/v4/locales/de.cjs +140 -0
  1563. package/node_modules/zod/v4/locales/de.d.cts +5 -0
  1564. package/node_modules/zod/v4/locales/de.d.ts +4 -0
  1565. package/node_modules/zod/v4/locales/de.js +113 -0
  1566. package/node_modules/zod/v4/locales/el.cjs +139 -0
  1567. package/node_modules/zod/v4/locales/el.d.cts +5 -0
  1568. package/node_modules/zod/v4/locales/el.d.ts +4 -0
  1569. package/node_modules/zod/v4/locales/el.js +112 -0
  1570. package/node_modules/zod/v4/locales/en.cjs +152 -0
  1571. package/node_modules/zod/v4/locales/en.d.cts +5 -0
  1572. package/node_modules/zod/v4/locales/en.d.ts +4 -0
  1573. package/node_modules/zod/v4/locales/en.js +125 -0
  1574. package/node_modules/zod/v4/locales/eo.cjs +141 -0
  1575. package/node_modules/zod/v4/locales/eo.d.cts +5 -0
  1576. package/node_modules/zod/v4/locales/eo.d.ts +4 -0
  1577. package/node_modules/zod/v4/locales/eo.js +114 -0
  1578. package/node_modules/zod/v4/locales/es.cjs +163 -0
  1579. package/node_modules/zod/v4/locales/es.d.cts +5 -0
  1580. package/node_modules/zod/v4/locales/es.d.ts +4 -0
  1581. package/node_modules/zod/v4/locales/es.js +136 -0
  1582. package/node_modules/zod/v4/locales/fa.cjs +146 -0
  1583. package/node_modules/zod/v4/locales/fa.d.cts +5 -0
  1584. package/node_modules/zod/v4/locales/fa.d.ts +4 -0
  1585. package/node_modules/zod/v4/locales/fa.js +119 -0
  1586. package/node_modules/zod/v4/locales/fi.cjs +144 -0
  1587. package/node_modules/zod/v4/locales/fi.d.cts +5 -0
  1588. package/node_modules/zod/v4/locales/fi.d.ts +4 -0
  1589. package/node_modules/zod/v4/locales/fi.js +117 -0
  1590. package/node_modules/zod/v4/locales/fr-CA.cjs +139 -0
  1591. package/node_modules/zod/v4/locales/fr-CA.d.cts +5 -0
  1592. package/node_modules/zod/v4/locales/fr-CA.d.ts +4 -0
  1593. package/node_modules/zod/v4/locales/fr-CA.js +112 -0
  1594. package/node_modules/zod/v4/locales/fr.cjs +156 -0
  1595. package/node_modules/zod/v4/locales/fr.d.cts +5 -0
  1596. package/node_modules/zod/v4/locales/fr.d.ts +4 -0
  1597. package/node_modules/zod/v4/locales/fr.js +129 -0
  1598. package/node_modules/zod/v4/locales/gu.cjs +140 -0
  1599. package/node_modules/zod/v4/locales/gu.d.cts +5 -0
  1600. package/node_modules/zod/v4/locales/gu.d.ts +4 -0
  1601. package/node_modules/zod/v4/locales/gu.js +113 -0
  1602. package/node_modules/zod/v4/locales/he.cjs +248 -0
  1603. package/node_modules/zod/v4/locales/he.d.cts +5 -0
  1604. package/node_modules/zod/v4/locales/he.d.ts +4 -0
  1605. package/node_modules/zod/v4/locales/he.js +221 -0
  1606. package/node_modules/zod/v4/locales/hi.cjs +138 -0
  1607. package/node_modules/zod/v4/locales/hi.d.cts +5 -0
  1608. package/node_modules/zod/v4/locales/hi.d.ts +4 -0
  1609. package/node_modules/zod/v4/locales/hi.js +111 -0
  1610. package/node_modules/zod/v4/locales/hr.cjs +153 -0
  1611. package/node_modules/zod/v4/locales/hr.d.cts +5 -0
  1612. package/node_modules/zod/v4/locales/hr.d.ts +4 -0
  1613. package/node_modules/zod/v4/locales/hr.js +126 -0
  1614. package/node_modules/zod/v4/locales/hu.cjs +140 -0
  1615. package/node_modules/zod/v4/locales/hu.d.cts +5 -0
  1616. package/node_modules/zod/v4/locales/hu.d.ts +4 -0
  1617. package/node_modules/zod/v4/locales/hu.js +113 -0
  1618. package/node_modules/zod/v4/locales/hy.cjs +185 -0
  1619. package/node_modules/zod/v4/locales/hy.d.cts +5 -0
  1620. package/node_modules/zod/v4/locales/hy.d.ts +4 -0
  1621. package/node_modules/zod/v4/locales/hy.js +158 -0
  1622. package/node_modules/zod/v4/locales/id.cjs +138 -0
  1623. package/node_modules/zod/v4/locales/id.d.cts +5 -0
  1624. package/node_modules/zod/v4/locales/id.d.ts +4 -0
  1625. package/node_modules/zod/v4/locales/id.js +111 -0
  1626. package/node_modules/zod/v4/locales/index.cjs +152 -0
  1627. package/node_modules/zod/v4/locales/index.d.cts +63 -0
  1628. package/node_modules/zod/v4/locales/index.d.ts +63 -0
  1629. package/node_modules/zod/v4/locales/index.js +63 -0
  1630. package/node_modules/zod/v4/locales/is.cjs +141 -0
  1631. package/node_modules/zod/v4/locales/is.d.cts +5 -0
  1632. package/node_modules/zod/v4/locales/is.d.ts +4 -0
  1633. package/node_modules/zod/v4/locales/is.js +114 -0
  1634. package/node_modules/zod/v4/locales/it.cjs +140 -0
  1635. package/node_modules/zod/v4/locales/it.d.cts +5 -0
  1636. package/node_modules/zod/v4/locales/it.d.ts +4 -0
  1637. package/node_modules/zod/v4/locales/it.js +113 -0
  1638. package/node_modules/zod/v4/locales/ja.cjs +139 -0
  1639. package/node_modules/zod/v4/locales/ja.d.cts +5 -0
  1640. package/node_modules/zod/v4/locales/ja.d.ts +4 -0
  1641. package/node_modules/zod/v4/locales/ja.js +112 -0
  1642. package/node_modules/zod/v4/locales/ka.cjs +144 -0
  1643. package/node_modules/zod/v4/locales/ka.d.cts +5 -0
  1644. package/node_modules/zod/v4/locales/ka.d.ts +4 -0
  1645. package/node_modules/zod/v4/locales/ka.js +117 -0
  1646. package/node_modules/zod/v4/locales/kh.cjs +12 -0
  1647. package/node_modules/zod/v4/locales/kh.d.cts +5 -0
  1648. package/node_modules/zod/v4/locales/kh.d.ts +5 -0
  1649. package/node_modules/zod/v4/locales/kh.js +5 -0
  1650. package/node_modules/zod/v4/locales/km.cjs +142 -0
  1651. package/node_modules/zod/v4/locales/km.d.cts +5 -0
  1652. package/node_modules/zod/v4/locales/km.d.ts +4 -0
  1653. package/node_modules/zod/v4/locales/km.js +115 -0
  1654. package/node_modules/zod/v4/locales/kn.cjs +143 -0
  1655. package/node_modules/zod/v4/locales/kn.d.cts +5 -0
  1656. package/node_modules/zod/v4/locales/kn.d.ts +4 -0
  1657. package/node_modules/zod/v4/locales/kn.js +116 -0
  1658. package/node_modules/zod/v4/locales/ko.cjs +143 -0
  1659. package/node_modules/zod/v4/locales/ko.d.cts +5 -0
  1660. package/node_modules/zod/v4/locales/ko.d.ts +4 -0
  1661. package/node_modules/zod/v4/locales/ko.js +116 -0
  1662. package/node_modules/zod/v4/locales/lt.cjs +234 -0
  1663. package/node_modules/zod/v4/locales/lt.d.cts +5 -0
  1664. package/node_modules/zod/v4/locales/lt.d.ts +4 -0
  1665. package/node_modules/zod/v4/locales/lt.js +207 -0
  1666. package/node_modules/zod/v4/locales/mk.cjs +141 -0
  1667. package/node_modules/zod/v4/locales/mk.d.cts +5 -0
  1668. package/node_modules/zod/v4/locales/mk.d.ts +4 -0
  1669. package/node_modules/zod/v4/locales/mk.js +114 -0
  1670. package/node_modules/zod/v4/locales/ms.cjs +139 -0
  1671. package/node_modules/zod/v4/locales/ms.d.cts +5 -0
  1672. package/node_modules/zod/v4/locales/ms.d.ts +4 -0
  1673. package/node_modules/zod/v4/locales/ms.js +112 -0
  1674. package/node_modules/zod/v4/locales/ne.cjs +138 -0
  1675. package/node_modules/zod/v4/locales/ne.d.cts +5 -0
  1676. package/node_modules/zod/v4/locales/ne.d.ts +4 -0
  1677. package/node_modules/zod/v4/locales/ne.js +111 -0
  1678. package/node_modules/zod/v4/locales/nl.cjs +142 -0
  1679. package/node_modules/zod/v4/locales/nl.d.cts +5 -0
  1680. package/node_modules/zod/v4/locales/nl.d.ts +4 -0
  1681. package/node_modules/zod/v4/locales/nl.js +115 -0
  1682. package/node_modules/zod/v4/locales/nn.cjs +140 -0
  1683. package/node_modules/zod/v4/locales/nn.d.cts +5 -0
  1684. package/node_modules/zod/v4/locales/nn.d.ts +4 -0
  1685. package/node_modules/zod/v4/locales/nn.js +113 -0
  1686. package/node_modules/zod/v4/locales/no.cjs +140 -0
  1687. package/node_modules/zod/v4/locales/no.d.cts +5 -0
  1688. package/node_modules/zod/v4/locales/no.d.ts +4 -0
  1689. package/node_modules/zod/v4/locales/no.js +113 -0
  1690. package/node_modules/zod/v4/locales/ota.cjs +141 -0
  1691. package/node_modules/zod/v4/locales/ota.d.cts +5 -0
  1692. package/node_modules/zod/v4/locales/ota.d.ts +4 -0
  1693. package/node_modules/zod/v4/locales/ota.js +114 -0
  1694. package/node_modules/zod/v4/locales/package.json +7 -0
  1695. package/node_modules/zod/v4/locales/pl.cjs +141 -0
  1696. package/node_modules/zod/v4/locales/pl.d.cts +5 -0
  1697. package/node_modules/zod/v4/locales/pl.d.ts +4 -0
  1698. package/node_modules/zod/v4/locales/pl.js +114 -0
  1699. package/node_modules/zod/v4/locales/ps.cjs +146 -0
  1700. package/node_modules/zod/v4/locales/ps.d.cts +5 -0
  1701. package/node_modules/zod/v4/locales/ps.d.ts +4 -0
  1702. package/node_modules/zod/v4/locales/ps.js +119 -0
  1703. package/node_modules/zod/v4/locales/pt-BR.cjs +170 -0
  1704. package/node_modules/zod/v4/locales/pt-BR.d.cts +5 -0
  1705. package/node_modules/zod/v4/locales/pt-BR.d.ts +4 -0
  1706. package/node_modules/zod/v4/locales/pt-BR.js +143 -0
  1707. package/node_modules/zod/v4/locales/pt.cjs +169 -0
  1708. package/node_modules/zod/v4/locales/pt.d.cts +5 -0
  1709. package/node_modules/zod/v4/locales/pt.d.ts +4 -0
  1710. package/node_modules/zod/v4/locales/pt.js +142 -0
  1711. package/node_modules/zod/v4/locales/ro.cjs +149 -0
  1712. package/node_modules/zod/v4/locales/ro.d.cts +5 -0
  1713. package/node_modules/zod/v4/locales/ro.d.ts +4 -0
  1714. package/node_modules/zod/v4/locales/ro.js +122 -0
  1715. package/node_modules/zod/v4/locales/ru.cjs +195 -0
  1716. package/node_modules/zod/v4/locales/ru.d.cts +5 -0
  1717. package/node_modules/zod/v4/locales/ru.d.ts +4 -0
  1718. package/node_modules/zod/v4/locales/ru.js +168 -0
  1719. package/node_modules/zod/v4/locales/sk.cjs +143 -0
  1720. package/node_modules/zod/v4/locales/sk.d.cts +5 -0
  1721. package/node_modules/zod/v4/locales/sk.d.ts +4 -0
  1722. package/node_modules/zod/v4/locales/sk.js +116 -0
  1723. package/node_modules/zod/v4/locales/sl.cjs +141 -0
  1724. package/node_modules/zod/v4/locales/sl.d.cts +5 -0
  1725. package/node_modules/zod/v4/locales/sl.d.ts +4 -0
  1726. package/node_modules/zod/v4/locales/sl.js +114 -0
  1727. package/node_modules/zod/v4/locales/sv.cjs +142 -0
  1728. package/node_modules/zod/v4/locales/sv.d.cts +5 -0
  1729. package/node_modules/zod/v4/locales/sv.d.ts +4 -0
  1730. package/node_modules/zod/v4/locales/sv.js +115 -0
  1731. package/node_modules/zod/v4/locales/ta.cjs +142 -0
  1732. package/node_modules/zod/v4/locales/ta.d.cts +5 -0
  1733. package/node_modules/zod/v4/locales/ta.d.ts +4 -0
  1734. package/node_modules/zod/v4/locales/ta.js +115 -0
  1735. package/node_modules/zod/v4/locales/tg.cjs +144 -0
  1736. package/node_modules/zod/v4/locales/tg.d.cts +5 -0
  1737. package/node_modules/zod/v4/locales/tg.d.ts +4 -0
  1738. package/node_modules/zod/v4/locales/tg.js +117 -0
  1739. package/node_modules/zod/v4/locales/th.cjs +142 -0
  1740. package/node_modules/zod/v4/locales/th.d.cts +5 -0
  1741. package/node_modules/zod/v4/locales/th.d.ts +4 -0
  1742. package/node_modules/zod/v4/locales/th.js +115 -0
  1743. package/node_modules/zod/v4/locales/tk.cjs +134 -0
  1744. package/node_modules/zod/v4/locales/tk.d.cts +5 -0
  1745. package/node_modules/zod/v4/locales/tk.d.ts +4 -0
  1746. package/node_modules/zod/v4/locales/tk.js +107 -0
  1747. package/node_modules/zod/v4/locales/tr.cjs +137 -0
  1748. package/node_modules/zod/v4/locales/tr.d.cts +5 -0
  1749. package/node_modules/zod/v4/locales/tr.d.ts +4 -0
  1750. package/node_modules/zod/v4/locales/tr.js +110 -0
  1751. package/node_modules/zod/v4/locales/ua.cjs +12 -0
  1752. package/node_modules/zod/v4/locales/ua.d.cts +5 -0
  1753. package/node_modules/zod/v4/locales/ua.d.ts +5 -0
  1754. package/node_modules/zod/v4/locales/ua.js +5 -0
  1755. package/node_modules/zod/v4/locales/uk.cjs +140 -0
  1756. package/node_modules/zod/v4/locales/uk.d.cts +5 -0
  1757. package/node_modules/zod/v4/locales/uk.d.ts +4 -0
  1758. package/node_modules/zod/v4/locales/uk.js +113 -0
  1759. package/node_modules/zod/v4/locales/ur.cjs +142 -0
  1760. package/node_modules/zod/v4/locales/ur.d.cts +5 -0
  1761. package/node_modules/zod/v4/locales/ur.d.ts +4 -0
  1762. package/node_modules/zod/v4/locales/ur.js +115 -0
  1763. package/node_modules/zod/v4/locales/uz.cjs +140 -0
  1764. package/node_modules/zod/v4/locales/uz.d.cts +5 -0
  1765. package/node_modules/zod/v4/locales/uz.d.ts +4 -0
  1766. package/node_modules/zod/v4/locales/uz.js +113 -0
  1767. package/node_modules/zod/v4/locales/vi.cjs +140 -0
  1768. package/node_modules/zod/v4/locales/vi.d.cts +5 -0
  1769. package/node_modules/zod/v4/locales/vi.d.ts +4 -0
  1770. package/node_modules/zod/v4/locales/vi.js +113 -0
  1771. package/node_modules/zod/v4/locales/yo.cjs +139 -0
  1772. package/node_modules/zod/v4/locales/yo.d.cts +5 -0
  1773. package/node_modules/zod/v4/locales/yo.d.ts +4 -0
  1774. package/node_modules/zod/v4/locales/yo.js +112 -0
  1775. package/node_modules/zod/v4/locales/zh-CN.cjs +141 -0
  1776. package/node_modules/zod/v4/locales/zh-CN.d.cts +5 -0
  1777. package/node_modules/zod/v4/locales/zh-CN.d.ts +4 -0
  1778. package/node_modules/zod/v4/locales/zh-CN.js +114 -0
  1779. package/node_modules/zod/v4/locales/zh-TW.cjs +139 -0
  1780. package/node_modules/zod/v4/locales/zh-TW.d.cts +5 -0
  1781. package/node_modules/zod/v4/locales/zh-TW.d.ts +4 -0
  1782. package/node_modules/zod/v4/locales/zh-TW.js +112 -0
  1783. package/node_modules/zod/v4/mini/checks.cjs +54 -0
  1784. package/node_modules/zod/v4/mini/checks.d.cts +1 -0
  1785. package/node_modules/zod/v4/mini/checks.d.ts +1 -0
  1786. package/node_modules/zod/v4/mini/checks.js +1 -0
  1787. package/node_modules/zod/v4/mini/coerce.cjs +71 -0
  1788. package/node_modules/zod/v4/mini/coerce.d.cts +7 -0
  1789. package/node_modules/zod/v4/mini/coerce.d.ts +7 -0
  1790. package/node_modules/zod/v4/mini/coerce.js +22 -0
  1791. package/node_modules/zod/v4/mini/deep-partial.cjs +58 -0
  1792. package/node_modules/zod/v4/mini/deep-partial.d.cts +14 -0
  1793. package/node_modules/zod/v4/mini/deep-partial.d.ts +14 -0
  1794. package/node_modules/zod/v4/mini/deep-partial.js +13 -0
  1795. package/node_modules/zod/v4/mini/external.cjs +95 -0
  1796. package/node_modules/zod/v4/mini/external.d.cts +16 -0
  1797. package/node_modules/zod/v4/mini/external.d.ts +16 -0
  1798. package/node_modules/zod/v4/mini/external.js +16 -0
  1799. package/node_modules/zod/v4/mini/in-out.cjs +82 -0
  1800. package/node_modules/zod/v4/mini/in-out.d.cts +8 -0
  1801. package/node_modules/zod/v4/mini/in-out.d.ts +8 -0
  1802. package/node_modules/zod/v4/mini/in-out.js +36 -0
  1803. package/node_modules/zod/v4/mini/index.cjs +51 -0
  1804. package/node_modules/zod/v4/mini/index.d.cts +3 -0
  1805. package/node_modules/zod/v4/mini/index.d.ts +3 -0
  1806. package/node_modules/zod/v4/mini/index.js +3 -0
  1807. package/node_modules/zod/v4/mini/iso.cjs +83 -0
  1808. package/node_modules/zod/v4/mini/iso.d.cts +22 -0
  1809. package/node_modules/zod/v4/mini/iso.d.ts +22 -0
  1810. package/node_modules/zod/v4/mini/iso.js +34 -0
  1811. package/node_modules/zod/v4/mini/package.json +7 -0
  1812. package/node_modules/zod/v4/mini/parse.cjs +37 -0
  1813. package/node_modules/zod/v4/mini/parse.d.cts +1 -0
  1814. package/node_modules/zod/v4/mini/parse.d.ts +1 -0
  1815. package/node_modules/zod/v4/mini/parse.js +1 -0
  1816. package/node_modules/zod/v4/mini/schemas.cjs +1147 -0
  1817. package/node_modules/zod/v4/mini/schemas.d.cts +480 -0
  1818. package/node_modules/zod/v4/mini/schemas.d.ts +480 -0
  1819. package/node_modules/zod/v4/mini/schemas.js +1002 -0
  1820. package/node_modules/zod/v4/package.json +7 -0
  1821. package/node_modules/zod/v4-mini/index.cjs +51 -0
  1822. package/node_modules/zod/v4-mini/index.d.cts +3 -0
  1823. package/node_modules/zod/v4-mini/index.d.ts +3 -0
  1824. package/node_modules/zod/v4-mini/index.js +3 -0
  1825. package/node_modules/zod/v4-mini/package.json +7 -0
  1826. package/package.json +50 -0
@@ -0,0 +1,2129 @@
1
+ import { duplexPair } from "node:stream";
2
+ import http2 from "node:http2";
3
+ import { beforeEach, describe, expect, it, vi } from "vitest";
4
+ import { buildHttp2BridgeForwardUrl, classifyStreamAgainstGoaway, createBridgeBodyReservation, createBridgeRouteBodyLedger, createHttp2BridgeServer, getBridgeBodyReservedBytesForTest, parseCanonicalBridgeRequestPath, resetBridgeBodyReservationsForTest, wrapDuplexChannelAsNodeDuplex, BridgeProcessCapacityError, DEFAULT_HTTP2_BRIDGE_MAX_BUFFERED_READ_BYTES, DEFAULT_HTTP2_BRIDGE_PING_INTERVAL_MS, DEFAULT_HTTP2_BRIDGE_PING_STALL_MS, HTTP2_BRIDGE_ENABLE_PUSH, HTTP2_BRIDGE_HEADER_TABLE_SIZE, HTTP2_BRIDGE_MAX_CONCURRENT_STREAMS, HTTP2_BRIDGE_MAX_DEFLATE_DYNAMIC_TABLE_SIZE, HTTP2_BRIDGE_MAX_HEADER_LIST_PAIRS, HTTP2_BRIDGE_MAX_HEADER_LIST_SIZE, HTTP2_BRIDGE_MAX_PROCESS_BODY_BYTES, HTTP2_BRIDGE_MAX_ROUTE_BODY_BYTES, HTTP2_BRIDGE_MAX_SESSION_INVALID_FRAMES, HTTP2_BRIDGE_MAX_SESSION_MEMORY, HTTP2_BRIDGE_MAX_SESSION_REJECTED_STREAMS, HTTP2_BRIDGE_SERVER_OPTIONS, HTTP2_BRIDGE_STREAM_RESET_BURST, HTTP2_BRIDGE_STREAM_RESET_RATE, } from "./http2-bridge-server.js";
5
+ import { createSandboxHttp2BridgeGateway, DEFAULT_SANDBOX_CALLBACK_BRIDGE_MAX_BODY_BYTES, HTTP2_SANDBOX_CALLBACK_BRIDGE_ROUTE_ALLOWLIST, } from "./sandbox-callback-bridge.js";
6
+ /**
7
+ * Unit harness for the host HTTP/2 server and the sandbox HTTP/2 client
8
+ * gateway. Every test connects the pair over one paired in-memory `Duplex`
9
+ * (`node:stream`'s `duplexPair`) — no real TCP socket and no spawned sandbox
10
+ * process. This proves the two halves speak one wire-compatible HTTP/2
11
+ * session with no network in between.
12
+ */
13
+ const BRIDGE_TOKEN = "test-bridge-token-fixed-length-32";
14
+ /** Wrap one side of a paired `Duplex` as a minimal fake `CommandManagedDuplexChannel`. */
15
+ function fakeChannelFromDuplex(duplex) {
16
+ const dataListeners = [];
17
+ const exitListeners = [];
18
+ duplex.on("data", (chunk) => {
19
+ for (const listener of dataListeners)
20
+ listener(chunk);
21
+ });
22
+ duplex.on("end", () => {
23
+ for (const listener of exitListeners)
24
+ listener({ exitCode: null, transportClosed: true });
25
+ });
26
+ return {
27
+ write: (data) => {
28
+ duplex.write(Buffer.from(data));
29
+ },
30
+ onData: (listener) => {
31
+ dataListeners.push(listener);
32
+ },
33
+ onExit: (listener) => {
34
+ exitListeners.push(listener);
35
+ },
36
+ stop: () => {
37
+ duplex.destroy();
38
+ },
39
+ close: async () => {
40
+ duplex.end();
41
+ },
42
+ };
43
+ }
44
+ /** Bind the host server to one side of a fresh paired in-memory `Duplex`.
45
+ * Returns the other side, unbound, for a caller to connect a client to. */
46
+ function bindTestServer(options = {}) {
47
+ const bridgeToken = options.bridgeToken ?? BRIDGE_TOKEN;
48
+ const [serverSide, clientSide] = duplexPair();
49
+ const forwardRequest = options.forwardRequest ??
50
+ (async (request) => ({
51
+ status: 200,
52
+ headers: { "content-type": "application/json" },
53
+ body: Buffer.from(JSON.stringify({ echoedMethod: request.method, echoedPath: request.pathname }), "utf8"),
54
+ }));
55
+ const handle = createHttp2BridgeServer({
56
+ bridgeToken,
57
+ forwardRequest,
58
+ pingIntervalMs: options.pingIntervalMs,
59
+ pingStallMs: options.pingStallMs,
60
+ requestBodyTimeoutMs: options.requestBodyTimeoutMs,
61
+ requestBodyLifetimeCeilingMs: options.requestBodyLifetimeCeilingMs,
62
+ closeGraceMs: options.closeGraceMs,
63
+ capacityDenialSettleDeadlineMs: options.capacityDenialSettleDeadlineMs,
64
+ responseWriteSettleDeadlineMs: options.responseWriteSettleDeadlineMs,
65
+ maxBodyBytes: options.maxBodyBytes,
66
+ routes: options.routes,
67
+ onGoaway: options.onGoaway,
68
+ onSessionError: options.onSessionError,
69
+ onSession: options.onSession,
70
+ });
71
+ const channel = fakeChannelFromDuplex(serverSide);
72
+ handle.bindChannel(channel);
73
+ return { handle, bridgeToken, clientSide, serverSide };
74
+ }
75
+ /** Bind the server, then connect the sandbox HTTP/2 client gateway to the
76
+ * other side of the same paired in-memory `Duplex`. */
77
+ function createTestPair(options = {}) {
78
+ const { handle, bridgeToken, clientSide, serverSide } = bindTestServer(options);
79
+ const gateway = createSandboxHttp2BridgeGateway({
80
+ bridgeToken,
81
+ createConnection: () => clientSide,
82
+ });
83
+ return { handle, gateway, bridgeToken, clientSide, serverSide };
84
+ }
85
+ /** Open a raw HTTP/2 client session directly against one side of the pair,
86
+ * bypassing the sandbox gateway. Some tests need direct stream control (an
87
+ * explicit RST_STREAM, an explicit GOAWAY) the gateway's `forwardRequest`
88
+ * abstraction does not expose. `settings`, when given, rides the client's
89
+ * own initial SETTINGS frame — for example `{ initialWindowSize: 0 }` to
90
+ * deny the server any flow-control credit to send response bytes with, a
91
+ * deterministic stall independent of the fake transport's own buffering. */
92
+ function connectRawClient(clientSide, settings) {
93
+ return http2.connect("http://bridge.internal", { createConnection: () => clientSide, settings });
94
+ }
95
+ /** Track whether `forwardRequest` ran, so a test can prove a denied or
96
+ * destroyed stream never reached it. Call `markCalled()` from inside
97
+ * `forwardRequest`, then assert on `.called`. */
98
+ function createForwarderCallTracker() {
99
+ const tracker = {
100
+ called: false,
101
+ markCalled() {
102
+ tracker.called = true;
103
+ },
104
+ };
105
+ return tracker;
106
+ }
107
+ /** Send one more request over `rawClient` and wait for it to complete, so a
108
+ * test can prove the session survived a prior faulted, stalled, or denied
109
+ * stream. */
110
+ async function expectSessionStillServesARequest(rawClient, request) {
111
+ return new Promise((resolve, reject) => {
112
+ const req = rawClient.request({
113
+ ":method": request.method,
114
+ ":path": request.path,
115
+ authorization: `Bearer ${request.token}`,
116
+ });
117
+ let status = 0;
118
+ let body = "";
119
+ req.setEncoding("utf8");
120
+ req.on("response", (headers) => {
121
+ status = Number(headers[":status"]) || 0;
122
+ });
123
+ req.on("data", (chunk) => (body += chunk));
124
+ req.on("end", () => resolve({ status, body }));
125
+ req.on("error", reject);
126
+ req.end();
127
+ });
128
+ }
129
+ describe("createHttp2BridgeServer + createSandboxHttp2BridgeGateway", () => {
130
+ // Every test in this file shares the module-scope process reservation
131
+ // total. A reservation one test leaves unreleased would otherwise lower
132
+ // the ceiling every later test sees, so each test starts from zero.
133
+ beforeEach(() => {
134
+ resetBridgeBodyReservationsForTest();
135
+ });
136
+ it("test_one_session_over_a_fake_channel_forwards_a_request", async () => {
137
+ const { handle, gateway } = createTestPair();
138
+ try {
139
+ const response = await gateway.forwardRequest({
140
+ method: "GET",
141
+ path: "/api/agents/me",
142
+ query: "",
143
+ headers: {},
144
+ body: Buffer.alloc(0),
145
+ receivedToken: BRIDGE_TOKEN,
146
+ });
147
+ expect(response.status).toBe(200);
148
+ expect(JSON.parse(response.body.toString("utf8"))).toEqual({
149
+ echoedMethod: "GET",
150
+ echoedPath: "/api/agents/me",
151
+ });
152
+ }
153
+ finally {
154
+ await gateway.close();
155
+ await handle.close();
156
+ }
157
+ });
158
+ it("test_sixty_four_concurrent_streams_all_complete", async () => {
159
+ const seenPaths = new Set();
160
+ const { handle, gateway } = createTestPair({
161
+ forwardRequest: async (request) => {
162
+ // Force real overlap: every forward call waits one macrotask before it
163
+ // resolves, so 64 concurrent streams are genuinely in flight together.
164
+ await new Promise((resolve) => setTimeout(resolve, 5));
165
+ seenPaths.add(request.pathname);
166
+ return {
167
+ status: 200,
168
+ headers: {},
169
+ body: Buffer.from(JSON.stringify({ echoedPath: request.pathname }), "utf8"),
170
+ };
171
+ },
172
+ });
173
+ try {
174
+ const requests = Array.from({ length: 64 }, (_, index) => gateway.forwardRequest({
175
+ method: "GET",
176
+ path: `/api/issues/${index}`,
177
+ query: "",
178
+ headers: {},
179
+ body: Buffer.alloc(0),
180
+ receivedToken: BRIDGE_TOKEN,
181
+ }));
182
+ const responses = await Promise.all(requests);
183
+ expect(responses).toHaveLength(64);
184
+ for (const [index, response] of responses.entries()) {
185
+ expect(response.status).toBe(200);
186
+ expect(JSON.parse(response.body.toString("utf8"))).toEqual({
187
+ echoedPath: `/api/issues/${index}`,
188
+ });
189
+ }
190
+ expect(seenPaths.size).toBe(64);
191
+ }
192
+ finally {
193
+ await gateway.close();
194
+ await handle.close();
195
+ }
196
+ });
197
+ it("test_ping_detects_a_silent_stall_within_twenty_seconds", async () => {
198
+ // The production defaults name the twenty-second bound this test name
199
+ // promises. The mechanism test below exercises the same code path with
200
+ // small overrides, so the suite stays fast.
201
+ expect(DEFAULT_HTTP2_BRIDGE_PING_STALL_MS).toBe(20_000);
202
+ expect(DEFAULT_HTTP2_BRIDGE_PING_INTERVAL_MS).toBeLessThan(DEFAULT_HTTP2_BRIDGE_PING_STALL_MS);
203
+ const [serverSide] = duplexPair();
204
+ // Nothing consumes the other side of the pair, so every PING frame the
205
+ // server sends goes unacknowledged: a silent stall.
206
+ const stallErrors = [];
207
+ const handle = createHttp2BridgeServer({
208
+ bridgeToken: BRIDGE_TOKEN,
209
+ forwardRequest: async () => ({ status: 200 }),
210
+ pingIntervalMs: 15,
211
+ pingStallMs: 40,
212
+ onSessionError: (error) => stallErrors.push(error),
213
+ });
214
+ handle.bindChannel(fakeChannelFromDuplex(serverSide));
215
+ await new Promise((resolve) => setTimeout(resolve, 300));
216
+ expect(stallErrors).toHaveLength(1);
217
+ expect(stallErrors[0]?.message).toMatch(/stall/i);
218
+ await handle.close();
219
+ });
220
+ it("test_goaway_reports_the_last_processed_stream_identifier", async () => {
221
+ // GOAWAY's Last-Stream-ID names the highest stream the SENDER processed
222
+ // for the peer's own initiated streams. Every request stream in this
223
+ // transport originates from the sandbox, so the meaningful, valid
224
+ // direction is the host naming the last client stream it processed — not
225
+ // the reverse (a client-sent GOAWAY only ever carries 0 here, since
226
+ // server push is disabled). The sandbox gateway observes it and can
227
+ // classify its own dispatched stream IDs with `classifyStreamAgainstGoaway`.
228
+ let hostSession;
229
+ const goawayRecords = [];
230
+ const { handle, bridgeToken, clientSide } = bindTestServer({
231
+ onSession: (session) => {
232
+ hostSession = session;
233
+ },
234
+ });
235
+ const gateway = createSandboxHttp2BridgeGateway({
236
+ bridgeToken,
237
+ createConnection: () => clientSide,
238
+ onGoaway: (record) => goawayRecords.push(record),
239
+ });
240
+ try {
241
+ const response = await gateway.forwardRequest({
242
+ method: "GET",
243
+ path: "/api/agents/me",
244
+ query: "",
245
+ headers: {},
246
+ body: Buffer.alloc(0),
247
+ receivedToken: bridgeToken,
248
+ });
249
+ expect(response.status).toBe(200);
250
+ await new Promise((resolve) => {
251
+ hostSession?.goaway(http2.constants.NGHTTP2_NO_ERROR, 1);
252
+ setTimeout(resolve, 50);
253
+ });
254
+ expect(goawayRecords).toHaveLength(1);
255
+ expect(goawayRecords[0]?.lastStreamId).toBe(1);
256
+ expect(classifyStreamAgainstGoaway(1, goawayRecords[0].lastStreamId)).toBe("accepted");
257
+ expect(classifyStreamAgainstGoaway(3, goawayRecords[0].lastStreamId)).toBe("not_accepted");
258
+ }
259
+ finally {
260
+ await gateway.close();
261
+ await handle.close();
262
+ }
263
+ });
264
+ it("test_rst_stream_fails_one_request_and_keeps_the_session", async () => {
265
+ const { handle, bridgeToken, clientSide } = bindTestServer({
266
+ forwardRequest: async (request) => {
267
+ if (request.pathname === "/api/agents/me") {
268
+ // Hold this one open long enough for the test to RST it.
269
+ await new Promise((resolve) => setTimeout(resolve, 200));
270
+ }
271
+ return { status: 200, headers: {}, body: Buffer.from(JSON.stringify({ path: request.pathname }), "utf8") };
272
+ },
273
+ });
274
+ const rawClient = connectRawClient(clientSide);
275
+ try {
276
+ const abortedStream = rawClient.request({
277
+ ":method": "GET",
278
+ ":path": "/api/agents/me",
279
+ authorization: `Bearer ${bridgeToken}`,
280
+ });
281
+ const abortedOutcome = new Promise((resolve) => {
282
+ abortedStream.on("error", () => resolve("aborted"));
283
+ abortedStream.on("close", () => resolve("closed"));
284
+ });
285
+ abortedStream.end();
286
+ // Give the request time to reach the server before the reset.
287
+ await new Promise((resolve) => setTimeout(resolve, 20));
288
+ abortedStream.close(http2.constants.NGHTTP2_CANCEL);
289
+ await abortedOutcome;
290
+ // The session survives: a second request completes normally.
291
+ const survivingResponse = await expectSessionStillServesARequest(rawClient, {
292
+ method: "GET",
293
+ path: "/api/companies/co1",
294
+ token: bridgeToken,
295
+ });
296
+ expect(survivingResponse.status).toBe(200);
297
+ expect(JSON.parse(survivingResponse.body)).toEqual({ path: "/api/companies/co1" });
298
+ }
299
+ finally {
300
+ rawClient.close();
301
+ await handle.close();
302
+ }
303
+ });
304
+ it("test_the_server_aborts_the_forward_when_the_client_closes_the_stream", async () => {
305
+ let capturedRequest;
306
+ let releaseForward;
307
+ const forwardHeld = new Promise((resolve) => {
308
+ releaseForward = resolve;
309
+ });
310
+ const { handle, bridgeToken, clientSide } = bindTestServer({
311
+ forwardRequest: async (request) => {
312
+ capturedRequest = request;
313
+ // Hold the handler open, so the test controls exactly when the
314
+ // client-side stream close happens relative to the forward.
315
+ await forwardHeld;
316
+ return { status: 200, body: Buffer.from("{}", "utf8") };
317
+ },
318
+ });
319
+ const rawClient = connectRawClient(clientSide);
320
+ try {
321
+ const stream = rawClient.request({
322
+ ":method": "GET",
323
+ ":path": "/api/agents/me",
324
+ authorization: `Bearer ${bridgeToken}`,
325
+ });
326
+ const streamClosed = new Promise((resolve) => {
327
+ stream.on("error", () => resolve());
328
+ stream.on("close", () => resolve());
329
+ });
330
+ stream.end();
331
+ // Give the request time to reach the server and enter forwardRequest.
332
+ await new Promise((resolve) => setTimeout(resolve, 20));
333
+ expect(capturedRequest).toBeDefined();
334
+ expect(capturedRequest.signal.aborted).toBe(false);
335
+ stream.close(http2.constants.NGHTTP2_CANCEL);
336
+ await streamClosed;
337
+ // Give the server's own stream `close` listener a turn to run.
338
+ await new Promise((resolve) => setTimeout(resolve, 20));
339
+ expect(capturedRequest.signal.aborted).toBe(true);
340
+ releaseForward();
341
+ }
342
+ finally {
343
+ rawClient.close();
344
+ await handle.close();
345
+ }
346
+ });
347
+ it("test_one_aborted_stream_leaves_the_session_and_the_other_streams_open", async () => {
348
+ const signalsByPath = new Map();
349
+ let releaseSurvivor;
350
+ const survivorHeld = new Promise((resolve) => {
351
+ releaseSurvivor = resolve;
352
+ });
353
+ const { handle, bridgeToken, clientSide } = bindTestServer({
354
+ forwardRequest: async (request) => {
355
+ signalsByPath.set(request.pathname, request.signal);
356
+ if (request.pathname === "/api/agents/aborted") {
357
+ // The RST — not a manual release — is what must end this forward:
358
+ // it settles only when the stream's own signal fires, so the test
359
+ // proves the signal itself unblocks the handler.
360
+ await new Promise((_resolve, reject) => {
361
+ request.signal.addEventListener("abort", () => reject(new Error("aborted")), {
362
+ once: true,
363
+ });
364
+ }).catch(() => undefined);
365
+ }
366
+ else if (request.pathname === "/api/agents/survivor") {
367
+ await survivorHeld;
368
+ }
369
+ return { status: 200, body: Buffer.from(JSON.stringify({ path: request.pathname }), "utf8") };
370
+ },
371
+ });
372
+ const rawClient = connectRawClient(clientSide);
373
+ try {
374
+ const abortedStream = rawClient.request({
375
+ ":method": "GET",
376
+ ":path": "/api/agents/aborted",
377
+ authorization: `Bearer ${bridgeToken}`,
378
+ });
379
+ const survivorStream = rawClient.request({
380
+ ":method": "GET",
381
+ ":path": "/api/agents/survivor",
382
+ authorization: `Bearer ${bridgeToken}`,
383
+ });
384
+ const abortedStreamClosed = new Promise((resolve) => {
385
+ abortedStream.on("error", () => resolve());
386
+ abortedStream.on("close", () => resolve());
387
+ });
388
+ // Capture the survivor stream's own response, so the test proves this
389
+ // exact stream — the sibling of the aborted one, on the same session —
390
+ // completes normally, not merely that the session admits a fresh one.
391
+ const survivorResponse = new Promise((resolve, reject) => {
392
+ let status = 0;
393
+ let body = "";
394
+ survivorStream.setEncoding("utf8");
395
+ survivorStream.on("response", (h) => {
396
+ status = Number(h[":status"]) || 0;
397
+ });
398
+ survivorStream.on("data", (chunk) => (body += chunk));
399
+ survivorStream.on("end", () => resolve({ status, body }));
400
+ survivorStream.on("error", reject);
401
+ });
402
+ abortedStream.end();
403
+ survivorStream.end();
404
+ // Give both requests time to reach the server and enter forwardRequest.
405
+ await new Promise((resolve) => setTimeout(resolve, 20));
406
+ abortedStream.close(http2.constants.NGHTTP2_CANCEL);
407
+ await abortedStreamClosed;
408
+ // Give the server's own stream `close` listener a turn to run.
409
+ await new Promise((resolve) => setTimeout(resolve, 20));
410
+ // The one aborted stream's signal fires. The other, still-open stream's
411
+ // signal stays untouched: the abort is local to its own stream.
412
+ expect(signalsByPath.get("/api/agents/aborted")?.aborted).toBe(true);
413
+ expect(signalsByPath.get("/api/agents/survivor")?.aborted).toBe(false);
414
+ releaseSurvivor();
415
+ const response = await survivorResponse;
416
+ expect(response.status).toBe(200);
417
+ expect(JSON.parse(response.body)).toEqual({ path: "/api/agents/survivor" });
418
+ }
419
+ finally {
420
+ rawClient.close();
421
+ await handle.close();
422
+ }
423
+ });
424
+ it("test_live_forward_work_never_passes_the_stream_limit", async () => {
425
+ // A forward that is never aborted holds open until the caller aborts it
426
+ // — this stands in for a forward stuck at its own long timeout. Only the
427
+ // per-stream abort binding this file adds can free such a forward before
428
+ // that timeout, so this count proves the binding, not merely the HTTP/2
429
+ // session's own stream-slot accounting (a stream's protocol slot frees on
430
+ // RST regardless of whether its forward call ever settles).
431
+ let liveForwards = 0;
432
+ let maxLiveForwards = 0;
433
+ const { handle, bridgeToken, clientSide } = bindTestServer({
434
+ forwardRequest: async (request) => {
435
+ liveForwards += 1;
436
+ maxLiveForwards = Math.max(maxLiveForwards, liveForwards);
437
+ try {
438
+ await new Promise((resolve, reject) => {
439
+ if (request.signal.aborted) {
440
+ reject(new Error("aborted"));
441
+ return;
442
+ }
443
+ request.signal.addEventListener("abort", () => reject(new Error("aborted")), { once: true });
444
+ });
445
+ return { status: 200, body: Buffer.from(JSON.stringify({ path: request.pathname }), "utf8") };
446
+ }
447
+ finally {
448
+ liveForwards -= 1;
449
+ }
450
+ },
451
+ });
452
+ const rawClient = connectRawClient(clientSide);
453
+ try {
454
+ const openAndCancelOneBatch = async (label) => {
455
+ const streams = Array.from({ length: HTTP2_BRIDGE_MAX_CONCURRENT_STREAMS }, (_, index) => rawClient.request({
456
+ ":method": "GET",
457
+ ":path": `/api/issues/${label}-${index}`,
458
+ authorization: `Bearer ${bridgeToken}`,
459
+ }));
460
+ for (const stream of streams)
461
+ stream.end();
462
+ await new Promise((resolve) => setTimeout(resolve, 30));
463
+ for (const stream of streams)
464
+ stream.close(http2.constants.NGHTTP2_CANCEL);
465
+ await new Promise((resolve) => setTimeout(resolve, 30));
466
+ };
467
+ // One full batch of maximum-concurrency streams, closed while their
468
+ // forwards are still held open, then a second full batch opened right
469
+ // after. Without the abort binding, the first batch's forwards would
470
+ // still be alive when the second batch dispatches, doubling the live-
471
+ // forward count past the stream limit.
472
+ await openAndCancelOneBatch("first");
473
+ await openAndCancelOneBatch("second");
474
+ expect(maxLiveForwards).toBeLessThanOrEqual(HTTP2_BRIDGE_MAX_CONCURRENT_STREAMS);
475
+ expect(liveForwards).toBe(0);
476
+ }
477
+ finally {
478
+ rawClient.close();
479
+ await handle.close();
480
+ }
481
+ });
482
+ it("test_a_stalled_request_body_settles_instead_of_hanging_forever", async () => {
483
+ const forwarderTracker = createForwarderCallTracker();
484
+ const { handle, bridgeToken, clientSide } = bindTestServer({
485
+ requestBodyTimeoutMs: 30,
486
+ forwardRequest: async () => {
487
+ forwarderTracker.markCalled();
488
+ return { status: 200 };
489
+ },
490
+ });
491
+ const rawClient = connectRawClient(clientSide);
492
+ try {
493
+ const startMs = Date.now();
494
+ // A partial, never-ended body stalls the read. The timeout destroys the
495
+ // stream, so the request settles (through an `error` or a `close`, not
496
+ // a clean response) well inside the bound, instead of hanging forever.
497
+ await new Promise((resolve) => {
498
+ const req = rawClient.request({
499
+ ":method": "POST",
500
+ ":path": "/api/issues/abc/comments",
501
+ authorization: `Bearer ${bridgeToken}`,
502
+ });
503
+ req.on("error", () => resolve());
504
+ req.on("close", () => resolve());
505
+ req.write("partial-body");
506
+ });
507
+ expect(Date.now() - startMs).toBeLessThan(5_000);
508
+ expect(forwarderTracker.called).toBe(false);
509
+ // The session survives the timed-out stream: a second, complete request
510
+ // still succeeds.
511
+ const survivingResponse = await expectSessionStillServesARequest(rawClient, {
512
+ method: "POST",
513
+ path: "/api/issues/abc/comments",
514
+ token: bridgeToken,
515
+ });
516
+ expect(survivingResponse.status).toBe(200);
517
+ }
518
+ finally {
519
+ rawClient.close();
520
+ await handle.close();
521
+ }
522
+ });
523
+ it("test_a_slow_but_progressing_request_body_completes_instead_of_timing_out", async () => {
524
+ // The idle bound is well under the total time the whole body takes, so a
525
+ // one-shot bound over the full read would trip. Each chunk resets the
526
+ // bound, so the request still completes.
527
+ const { handle, bridgeToken, clientSide } = bindTestServer({
528
+ requestBodyTimeoutMs: 80,
529
+ forwardRequest: async (request) => ({
530
+ status: 200,
531
+ body: Buffer.from(JSON.stringify({ bodyLength: request.body.byteLength }), "utf8"),
532
+ }),
533
+ });
534
+ const rawClient = connectRawClient(clientSide);
535
+ try {
536
+ const response = await new Promise((resolve, reject) => {
537
+ const req = rawClient.request({
538
+ ":method": "POST",
539
+ ":path": "/api/issues/abc/comments",
540
+ authorization: `Bearer ${bridgeToken}`,
541
+ });
542
+ let status = 0;
543
+ let body = "";
544
+ req.setEncoding("utf8");
545
+ req.on("response", (headers) => {
546
+ status = Number(headers[":status"]) || 0;
547
+ });
548
+ req.on("data", (chunk) => (body += chunk));
549
+ req.on("end", () => resolve({ status, body }));
550
+ req.on("error", reject);
551
+ // Five chunks, each inside the idle bound, summing past it.
552
+ let sent = 0;
553
+ const sendNext = () => {
554
+ if (sent >= 5) {
555
+ req.end();
556
+ return;
557
+ }
558
+ sent += 1;
559
+ req.write("chunk");
560
+ setTimeout(sendNext, 40);
561
+ };
562
+ sendNext();
563
+ });
564
+ expect(response.status).toBe(200);
565
+ expect(JSON.parse(response.body)).toEqual({ bodyLength: "chunk".length * 5 });
566
+ }
567
+ finally {
568
+ rawClient.close();
569
+ await handle.close();
570
+ }
571
+ });
572
+ it("test_a_slow_trickle_that_never_ends_stops_at_the_one_shot_ceiling", async () => {
573
+ // The idle bound is generous, so a chunk every 40ms never lets it
574
+ // expire. The ceiling (150ms) arms once, when the read starts, and
575
+ // never renews on a chunk: this proves a peer that keeps every chunk
576
+ // gap under the idle bound, but never finishes the body, still loses
577
+ // the stream once the read's total age passes the ceiling. This is the
578
+ // failure mode an authenticated sandbox could otherwise use to hold one
579
+ // of the concurrent-stream slots open indefinitely: keep sending just
580
+ // enough to dodge the idle bound, and never finish the body.
581
+ //
582
+ // Every write below lands well before the ceiling, and the test makes
583
+ // no further call on the stream after the last one: nothing races the
584
+ // server's own reset of it once the ceiling passes, so this proves the
585
+ // bound from the server's own, deterministic effect (the forward
586
+ // handler never runs) instead of from a raw client-stream event whose
587
+ // timing Node does not guarantee here.
588
+ const forwarderTracker = createForwarderCallTracker();
589
+ const { handle, bridgeToken, clientSide } = bindTestServer({
590
+ requestBodyTimeoutMs: 5_000,
591
+ requestBodyLifetimeCeilingMs: 150,
592
+ forwardRequest: async () => {
593
+ forwarderTracker.markCalled();
594
+ return { status: 200 };
595
+ },
596
+ });
597
+ const rawClient = connectRawClient(clientSide);
598
+ try {
599
+ const req = rawClient.request({
600
+ ":method": "POST",
601
+ ":path": "/api/issues/abc/comments",
602
+ authorization: `Bearer ${bridgeToken}`,
603
+ });
604
+ req.on("error", () => undefined);
605
+ // Four chunks, 40ms apart, well inside the idle bound. The total send
606
+ // time, about 160ms, passes the 150ms ceiling. The body never ends:
607
+ // this request never calls `.end()`.
608
+ for (let chunkIndex = 0; chunkIndex < 4; chunkIndex += 1) {
609
+ req.write("chunk");
610
+ await new Promise((resolve) => setTimeout(resolve, 40));
611
+ }
612
+ // Wait past the ceiling with no further write, so the server has time
613
+ // to destroy the stalled stream on its own.
614
+ await new Promise((resolve) => setTimeout(resolve, 150));
615
+ expect(forwarderTracker.called).toBe(false);
616
+ // The session survives the stopped stream: a second, complete request
617
+ // still succeeds.
618
+ const survivingResponse = await expectSessionStillServesARequest(rawClient, {
619
+ method: "POST",
620
+ path: "/api/issues/abc/comments",
621
+ token: bridgeToken,
622
+ });
623
+ expect(survivingResponse.status).toBe(200);
624
+ }
625
+ finally {
626
+ rawClient.close();
627
+ await handle.close();
628
+ }
629
+ });
630
+ it("test_a_request_body_within_the_lifetime_bound_still_completes", async () => {
631
+ // A generous ceiling must not interfere with an ordinary request that
632
+ // finishes well inside it.
633
+ const { handle, bridgeToken, clientSide } = bindTestServer({
634
+ requestBodyTimeoutMs: 5_000,
635
+ requestBodyLifetimeCeilingMs: 5_000,
636
+ forwardRequest: async (request) => ({
637
+ status: 200,
638
+ body: Buffer.from(JSON.stringify({ bodyLength: request.body.byteLength }), "utf8"),
639
+ }),
640
+ });
641
+ const rawClient = connectRawClient(clientSide);
642
+ try {
643
+ const response = await new Promise((resolve, reject) => {
644
+ const req = rawClient.request({
645
+ ":method": "POST",
646
+ ":path": "/api/issues/abc/comments",
647
+ authorization: `Bearer ${bridgeToken}`,
648
+ });
649
+ let status = 0;
650
+ let body = "";
651
+ req.setEncoding("utf8");
652
+ req.on("response", (headers) => {
653
+ status = Number(headers[":status"]) || 0;
654
+ });
655
+ req.on("data", (chunk) => (body += chunk));
656
+ req.on("end", () => resolve({ status, body }));
657
+ req.on("error", reject);
658
+ req.write("chunk");
659
+ req.end();
660
+ });
661
+ expect(response.status).toBe(200);
662
+ expect(JSON.parse(response.body)).toEqual({ bodyLength: "chunk".length });
663
+ }
664
+ finally {
665
+ rawClient.close();
666
+ await handle.close();
667
+ }
668
+ });
669
+ it("test_a_slow_but_progressing_upload_completes_within_the_ceiling", async () => {
670
+ // The idle bound and the ceiling are both generous, so a slow but
671
+ // genuinely progressing upload completes normally, instead of losing
672
+ // its stream mid-upload.
673
+ const forwarderTracker = createForwarderCallTracker();
674
+ const { handle, bridgeToken, clientSide } = bindTestServer({
675
+ requestBodyTimeoutMs: 5_000,
676
+ requestBodyLifetimeCeilingMs: 5_000,
677
+ forwardRequest: async (request) => {
678
+ forwarderTracker.markCalled();
679
+ return { status: 200, body: Buffer.from(JSON.stringify({ bodyLength: request.body.byteLength }), "utf8") };
680
+ },
681
+ });
682
+ const rawClient = connectRawClient(clientSide);
683
+ try {
684
+ const response = await new Promise((resolve, reject) => {
685
+ const req = rawClient.request({
686
+ ":method": "POST",
687
+ ":path": "/api/issues/abc/comments",
688
+ authorization: `Bearer ${bridgeToken}`,
689
+ });
690
+ let status = 0;
691
+ let body = "";
692
+ req.setEncoding("utf8");
693
+ req.on("response", (headers) => {
694
+ status = Number(headers[":status"]) || 0;
695
+ });
696
+ req.on("data", (chunk) => (body += chunk));
697
+ req.on("end", () => resolve({ status, body }));
698
+ req.on("error", reject);
699
+ void (async () => {
700
+ // Six chunks, 40ms apart (well inside the idle bound), each real
701
+ // progress.
702
+ for (let sent = 0; sent < 6; sent += 1) {
703
+ req.write("chunk");
704
+ await new Promise((r) => setTimeout(r, 40));
705
+ }
706
+ req.end();
707
+ })();
708
+ });
709
+ expect(forwarderTracker.called).toBe(true);
710
+ expect(response.status).toBe(200);
711
+ expect(JSON.parse(response.body)).toEqual({ bodyLength: "chunk".length * 6 });
712
+ }
713
+ finally {
714
+ rawClient.close();
715
+ await handle.close();
716
+ }
717
+ });
718
+ it("test_close_force_destroys_a_session_with_a_stalled_stream_instead_of_waiting_forever", async () => {
719
+ const { handle, bridgeToken, clientSide } = bindTestServer({
720
+ // A body timeout far longer than the close grace, so `close()` is the
721
+ // only thing that bounds the wait in this test.
722
+ requestBodyTimeoutMs: 60_000,
723
+ closeGraceMs: 30,
724
+ });
725
+ const rawClient = connectRawClient(clientSide);
726
+ try {
727
+ const req = rawClient.request({
728
+ ":method": "POST",
729
+ ":path": "/api/issues/abc/comments",
730
+ authorization: `Bearer ${bridgeToken}`,
731
+ });
732
+ req.write("partial-body");
733
+ // Give the request time to reach the server before close() runs.
734
+ await new Promise((resolve) => setTimeout(resolve, 20));
735
+ const closeStart = Date.now();
736
+ await handle.close();
737
+ const closeElapsedMs = Date.now() - closeStart;
738
+ // `close()` force-destroyed the stalled session at the grace bound,
739
+ // instead of waiting on `session.close()` forever.
740
+ expect(closeElapsedMs).toBeLessThan(5_000);
741
+ }
742
+ finally {
743
+ rawClient.close();
744
+ }
745
+ });
746
+ it("test_the_server_sets_every_bounded_option", async () => {
747
+ expect(HTTP2_BRIDGE_SERVER_OPTIONS).toEqual({
748
+ settings: {
749
+ enablePush: HTTP2_BRIDGE_ENABLE_PUSH,
750
+ maxConcurrentStreams: HTTP2_BRIDGE_MAX_CONCURRENT_STREAMS,
751
+ maxHeaderListSize: HTTP2_BRIDGE_MAX_HEADER_LIST_SIZE,
752
+ headerTableSize: HTTP2_BRIDGE_HEADER_TABLE_SIZE,
753
+ },
754
+ maxSessionMemory: HTTP2_BRIDGE_MAX_SESSION_MEMORY,
755
+ maxHeaderListPairs: HTTP2_BRIDGE_MAX_HEADER_LIST_PAIRS,
756
+ maxDeflateDynamicTableSize: HTTP2_BRIDGE_MAX_DEFLATE_DYNAMIC_TABLE_SIZE,
757
+ maxSessionInvalidFrames: HTTP2_BRIDGE_MAX_SESSION_INVALID_FRAMES,
758
+ maxSessionRejectedStreams: HTTP2_BRIDGE_MAX_SESSION_REJECTED_STREAMS,
759
+ streamResetRate: HTTP2_BRIDGE_STREAM_RESET_RATE,
760
+ streamResetBurst: HTTP2_BRIDGE_STREAM_RESET_BURST,
761
+ });
762
+ expect(HTTP2_BRIDGE_ENABLE_PUSH).toBe(false);
763
+ expect(HTTP2_BRIDGE_MAX_CONCURRENT_STREAMS).toBe(4);
764
+ expect(HTTP2_BRIDGE_MAX_HEADER_LIST_SIZE).toBe(16384);
765
+ expect(HTTP2_BRIDGE_HEADER_TABLE_SIZE).toBe(4096);
766
+ expect(HTTP2_BRIDGE_MAX_SESSION_MEMORY).toBe(16);
767
+ expect(HTTP2_BRIDGE_MAX_HEADER_LIST_PAIRS).toBe(128);
768
+ expect(HTTP2_BRIDGE_MAX_DEFLATE_DYNAMIC_TABLE_SIZE).toBe(4096);
769
+ expect(HTTP2_BRIDGE_MAX_SESSION_INVALID_FRAMES).toBe(100);
770
+ expect(HTTP2_BRIDGE_MAX_SESSION_REJECTED_STREAMS).toBe(100);
771
+ expect(HTTP2_BRIDGE_STREAM_RESET_RATE).toBe(10);
772
+ expect(HTTP2_BRIDGE_STREAM_RESET_BURST).toBe(100);
773
+ // The running server actually carries the bound, not only the constant:
774
+ // the four `settings` values ride the server's outbound SETTINGS frame,
775
+ // so the connected client's `remoteSettings` reflects them after the
776
+ // handshake completes.
777
+ const { handle, clientSide } = bindTestServer();
778
+ const rawClient = connectRawClient(clientSide);
779
+ try {
780
+ const remoteSettings = await new Promise((resolve) => {
781
+ rawClient.once("remoteSettings", resolve);
782
+ });
783
+ expect(remoteSettings.enablePush).toBe(HTTP2_BRIDGE_ENABLE_PUSH);
784
+ expect(remoteSettings.maxConcurrentStreams).toBe(HTTP2_BRIDGE_MAX_CONCURRENT_STREAMS);
785
+ expect(remoteSettings.maxHeaderListSize).toBe(HTTP2_BRIDGE_MAX_HEADER_LIST_SIZE);
786
+ expect(remoteSettings.headerTableSize).toBe(HTTP2_BRIDGE_HEADER_TABLE_SIZE);
787
+ }
788
+ finally {
789
+ rawClient.close();
790
+ await handle.close();
791
+ }
792
+ });
793
+ it("test_the_host_body_budget_matches_the_stream_limit", () => {
794
+ // The multiplier counts every retained `Buffer` copy of one live
795
+ // forward's request and response body: four exact `Buffer` rows. The
796
+ // forward path decodes no body to a string, so no row applies the
797
+ // two-bytes-per-UTF-16-code-unit string overhead any more.
798
+ // `test_live_forward_work_never_passes_the_stream_limit` proves the
799
+ // count of live forwards never passes `HTTP2_BRIDGE_MAX_CONCURRENT_STREAMS`,
800
+ // so this multiplier bounds live forwards, not merely open streams.
801
+ // `HTTP2_BRIDGE_MAX_ROUTE_BODY_BYTES` uses this exact same formula to
802
+ // enforce it as a real per-route cap, not merely a derived figure.
803
+ const expectedRouteBudget = HTTP2_BRIDGE_MAX_CONCURRENT_STREAMS * 4 * DEFAULT_SANDBOX_CALLBACK_BRIDGE_MAX_BODY_BYTES;
804
+ expect(expectedRouteBudget).toBe(168_820_736);
805
+ expect(HTTP2_BRIDGE_MAX_ROUTE_BODY_BYTES).toBe(expectedRouteBudget);
806
+ });
807
+ describe("createBridgeBodyReservation", () => {
808
+ it("test_a_reservation_denies_a_chunk_that_passes_the_process_ceiling", () => {
809
+ const owner = createBridgeBodyReservation();
810
+ try {
811
+ expect(owner.reserve(HTTP2_BRIDGE_MAX_PROCESS_BODY_BYTES)).toBe(true);
812
+ expect(owner.heldBytes).toBe(HTTP2_BRIDGE_MAX_PROCESS_BODY_BYTES);
813
+ expect(getBridgeBodyReservedBytesForTest()).toBe(HTTP2_BRIDGE_MAX_PROCESS_BODY_BYTES);
814
+ // One more byte passes the ceiling: denied, and it holds no bytes.
815
+ expect(owner.reserve(1)).toBe(false);
816
+ expect(owner.heldBytes).toBe(HTTP2_BRIDGE_MAX_PROCESS_BODY_BYTES);
817
+ expect(getBridgeBodyReservedBytesForTest()).toBe(HTTP2_BRIDGE_MAX_PROCESS_BODY_BYTES);
818
+ }
819
+ finally {
820
+ owner.release();
821
+ }
822
+ });
823
+ it("test_a_reservation_denies_the_concatenated_copy_that_passes_the_process_ceiling", () => {
824
+ const owner = createBridgeBodyReservation();
825
+ try {
826
+ // The chunk-array reservation alone passes comfortably.
827
+ const chunkArrayBytes = Math.floor(HTTP2_BRIDGE_MAX_PROCESS_BODY_BYTES * 0.6);
828
+ expect(owner.reserve(chunkArrayBytes)).toBe(true);
829
+ // The concatenated `Buffer.concat` copy is a second, separate live
830
+ // copy of the same bytes: reserving it on top of the chunk array
831
+ // this owner already holds passes the ceiling, even though the
832
+ // chunk-array reservation alone did not.
833
+ expect(owner.reserve(chunkArrayBytes)).toBe(false);
834
+ expect(owner.heldBytes).toBe(chunkArrayBytes);
835
+ expect(getBridgeBodyReservedBytesForTest()).toBe(chunkArrayBytes);
836
+ }
837
+ finally {
838
+ owner.release();
839
+ }
840
+ });
841
+ it("test_a_reservation_releases_every_held_byte_one_time_only", () => {
842
+ const owner = createBridgeBodyReservation();
843
+ expect(owner.reserve(1_000)).toBe(true);
844
+ expect(getBridgeBodyReservedBytesForTest()).toBe(1_000);
845
+ owner.release();
846
+ expect(owner.heldBytes).toBe(0);
847
+ expect(getBridgeBodyReservedBytesForTest()).toBe(0);
848
+ // A second release must not double-subtract: the total must not go
849
+ // below zero.
850
+ owner.release();
851
+ expect(owner.heldBytes).toBe(0);
852
+ expect(getBridgeBodyReservedBytesForTest()).toBe(0);
853
+ });
854
+ });
855
+ describe("route isolation", () => {
856
+ it("test_a_route_ledger_denies_a_reservation_that_passes_its_own_ceiling_with_the_process_ceiling_still_open", () => {
857
+ // The process-wide ceiling has ample room (1 GiB); only this one
858
+ // route's own share is tight. A route-scoped owner must still deny
859
+ // the second reservation, proving the route ceiling is a real,
860
+ // independent check, not merely a reflection of the process total.
861
+ const routeLedger = createBridgeRouteBodyLedger();
862
+ const owner = createBridgeBodyReservation(routeLedger);
863
+ try {
864
+ expect(owner.reserve(HTTP2_BRIDGE_MAX_ROUTE_BODY_BYTES)).toBe(true);
865
+ expect(routeLedger.reservedBytes).toBe(HTTP2_BRIDGE_MAX_ROUTE_BODY_BYTES);
866
+ expect(owner.reserve(1)).toBe(false);
867
+ expect(owner.heldBytes).toBe(HTTP2_BRIDGE_MAX_ROUTE_BODY_BYTES);
868
+ expect(routeLedger.reservedBytes).toBe(HTTP2_BRIDGE_MAX_ROUTE_BODY_BYTES);
869
+ // The process-wide total only ever grew by what this owner actually
870
+ // holds: the denied byte reserved against neither total.
871
+ expect(getBridgeBodyReservedBytesForTest()).toBe(HTTP2_BRIDGE_MAX_ROUTE_BODY_BYTES);
872
+ }
873
+ finally {
874
+ owner.release();
875
+ }
876
+ });
877
+ it("test_one_route_at_its_own_ceiling_never_blocks_a_sibling_routes_reservation", () => {
878
+ // Two routes, two ledgers. Route A spends its own entire ceiling.
879
+ // Route B's reservation, against its own separate ledger, must still
880
+ // succeed: the process-wide total (1 GiB) has room for both routes'
881
+ // ceilings many times over, so only route isolation — not the shared
882
+ // total — could explain a denial here.
883
+ const routeLedgerA = createBridgeRouteBodyLedger();
884
+ const routeLedgerB = createBridgeRouteBodyLedger();
885
+ const ownerA = createBridgeBodyReservation(routeLedgerA);
886
+ const ownerB = createBridgeBodyReservation(routeLedgerB);
887
+ try {
888
+ expect(ownerA.reserve(HTTP2_BRIDGE_MAX_ROUTE_BODY_BYTES)).toBe(true);
889
+ expect(ownerA.reserve(1)).toBe(false);
890
+ expect(ownerB.reserve(HTTP2_BRIDGE_MAX_ROUTE_BODY_BYTES)).toBe(true);
891
+ }
892
+ finally {
893
+ ownerA.release();
894
+ ownerB.release();
895
+ }
896
+ });
897
+ it("test_two_bridge_server_routes_isolate_their_own_reservations_end_to_end", async () => {
898
+ // The end-to-end proof: while route A's own forward holds its own
899
+ // entire per-route ceiling in flight, a second, independent route's
900
+ // request must still succeed. Each `bindTestServer` call is its own
901
+ // route (its own `createHttp2BridgeServer` call, so its own route
902
+ // ledger). Route A's forward parks on `releaseRouteAHold` after it
903
+ // reserves, so its reservation stays live — not merely reserved and
904
+ // immediately released — for the whole time route B's request runs.
905
+ let markRouteAReserved;
906
+ const routeAReserved = new Promise((resolve) => {
907
+ markRouteAReserved = resolve;
908
+ });
909
+ let releaseRouteAHold;
910
+ const routeAHold = new Promise((resolve) => {
911
+ releaseRouteAHold = resolve;
912
+ });
913
+ const routeA = bindTestServer({
914
+ forwardRequest: async (request) => {
915
+ // Reserve this route's own entire ceiling against its own ledger,
916
+ // simulating route A at its own documented peak.
917
+ if (!request.reservation.reserve(HTTP2_BRIDGE_MAX_ROUTE_BODY_BYTES)) {
918
+ throw new BridgeProcessCapacityError();
919
+ }
920
+ markRouteAReserved();
921
+ await routeAHold;
922
+ return { status: 200 };
923
+ },
924
+ });
925
+ const routeB = bindTestServer({
926
+ forwardRequest: async () => ({ status: 200 }),
927
+ });
928
+ const rawClientA = connectRawClient(routeA.clientSide);
929
+ const rawClientB = connectRawClient(routeB.clientSide);
930
+ try {
931
+ const pendingResponseA = expectSessionStillServesARequest(rawClientA, {
932
+ method: "GET",
933
+ path: "/api/agents/me",
934
+ token: routeA.bridgeToken,
935
+ });
936
+ // Wait until route A's forward actually holds its own ceiling —
937
+ // not merely until the request was sent — before checking route B.
938
+ await routeAReserved;
939
+ expect(getBridgeBodyReservedBytesForTest()).toBeGreaterThanOrEqual(HTTP2_BRIDGE_MAX_ROUTE_BODY_BYTES);
940
+ // Route A now holds its own entire per-route ceiling, live. The
941
+ // process-wide total still has headroom (1 GiB minus one 161 MiB
942
+ // route), so route B's independent request succeeds only if its own
943
+ // ledger is genuinely separate from route A's.
944
+ const responseB = await expectSessionStillServesARequest(rawClientB, {
945
+ method: "GET",
946
+ path: "/api/agents/me",
947
+ token: routeB.bridgeToken,
948
+ });
949
+ expect(responseB.status).toBe(200);
950
+ releaseRouteAHold();
951
+ const responseA = await pendingResponseA;
952
+ expect(responseA.status).toBe(200);
953
+ }
954
+ finally {
955
+ rawClientA.close();
956
+ rawClientB.close();
957
+ await routeA.handle.close();
958
+ await routeB.handle.close();
959
+ }
960
+ });
961
+ });
962
+ it("test_the_stream_handler_releases_its_reservation_on_completion_error_abort_timeout_and_close", async () => {
963
+ // Every stream, no matter how it ends, must leave the process-wide
964
+ // reservation total at zero: `handleStream`'s `finally` block releases
965
+ // exactly one owner exactly one time on every exit path.
966
+ async function runCompletionCase() {
967
+ const { handle, bridgeToken, clientSide } = bindTestServer({
968
+ forwardRequest: async (request) => {
969
+ request.reservation.reserve(1_000);
970
+ return { status: 200, body: Buffer.from("{}", "utf8") };
971
+ },
972
+ });
973
+ const rawClient = connectRawClient(clientSide);
974
+ try {
975
+ const response = await expectSessionStillServesARequest(rawClient, {
976
+ method: "GET",
977
+ path: "/api/agents/me",
978
+ token: bridgeToken,
979
+ });
980
+ expect(response.status).toBe(200);
981
+ expect(getBridgeBodyReservedBytesForTest()).toBe(0);
982
+ }
983
+ finally {
984
+ rawClient.close();
985
+ await handle.close();
986
+ }
987
+ }
988
+ async function runErrorCase() {
989
+ const { handle, bridgeToken, clientSide } = bindTestServer({
990
+ forwardRequest: async (request) => {
991
+ request.reservation.reserve(1_000);
992
+ throw new Error("forward handler fault");
993
+ },
994
+ });
995
+ const rawClient = connectRawClient(clientSide);
996
+ try {
997
+ const response = await expectSessionStillServesARequest(rawClient, {
998
+ method: "GET",
999
+ path: "/api/agents/me",
1000
+ token: bridgeToken,
1001
+ });
1002
+ expect(response.status).toBe(502);
1003
+ expect(getBridgeBodyReservedBytesForTest()).toBe(0);
1004
+ }
1005
+ finally {
1006
+ rawClient.close();
1007
+ await handle.close();
1008
+ }
1009
+ }
1010
+ async function runAbortCase() {
1011
+ const { handle, bridgeToken, clientSide } = bindTestServer({
1012
+ forwardRequest: async (request) => {
1013
+ request.reservation.reserve(1_000);
1014
+ await new Promise((resolve) => {
1015
+ if (request.signal.aborted) {
1016
+ resolve();
1017
+ return;
1018
+ }
1019
+ request.signal.addEventListener("abort", () => resolve(), { once: true });
1020
+ });
1021
+ return { status: 200 };
1022
+ },
1023
+ });
1024
+ const rawClient = connectRawClient(clientSide);
1025
+ try {
1026
+ const stream = rawClient.request({
1027
+ ":method": "GET",
1028
+ ":path": "/api/agents/me",
1029
+ authorization: `Bearer ${bridgeToken}`,
1030
+ });
1031
+ const streamClosed = new Promise((resolve) => {
1032
+ stream.on("error", () => resolve());
1033
+ stream.on("close", () => resolve());
1034
+ });
1035
+ stream.end();
1036
+ await new Promise((resolve) => setTimeout(resolve, 20));
1037
+ stream.close(http2.constants.NGHTTP2_CANCEL);
1038
+ await streamClosed;
1039
+ await new Promise((resolve) => setTimeout(resolve, 20));
1040
+ expect(getBridgeBodyReservedBytesForTest()).toBe(0);
1041
+ }
1042
+ finally {
1043
+ rawClient.close();
1044
+ await handle.close();
1045
+ }
1046
+ }
1047
+ async function runTimeoutCase() {
1048
+ const { handle, bridgeToken, clientSide } = bindTestServer({
1049
+ requestBodyTimeoutMs: 30,
1050
+ forwardRequest: async () => ({ status: 200 }),
1051
+ });
1052
+ const rawClient = connectRawClient(clientSide);
1053
+ try {
1054
+ await new Promise((resolve) => {
1055
+ const req = rawClient.request({
1056
+ ":method": "POST",
1057
+ ":path": "/api/issues/abc/comments",
1058
+ authorization: `Bearer ${bridgeToken}`,
1059
+ });
1060
+ req.on("error", () => resolve());
1061
+ req.on("close", () => resolve());
1062
+ req.write("partial-body");
1063
+ });
1064
+ await new Promise((resolve) => setTimeout(resolve, 20));
1065
+ expect(getBridgeBodyReservedBytesForTest()).toBe(0);
1066
+ }
1067
+ finally {
1068
+ rawClient.close();
1069
+ await handle.close();
1070
+ }
1071
+ }
1072
+ async function runCloseCase() {
1073
+ const { handle, bridgeToken, clientSide } = bindTestServer({
1074
+ requestBodyTimeoutMs: 60_000,
1075
+ closeGraceMs: 30,
1076
+ });
1077
+ const rawClient = connectRawClient(clientSide);
1078
+ try {
1079
+ const req = rawClient.request({
1080
+ ":method": "POST",
1081
+ ":path": "/api/issues/abc/comments",
1082
+ authorization: `Bearer ${bridgeToken}`,
1083
+ });
1084
+ req.write("partial-body");
1085
+ await new Promise((resolve) => setTimeout(resolve, 20));
1086
+ await handle.close();
1087
+ await new Promise((resolve) => setTimeout(resolve, 20));
1088
+ expect(getBridgeBodyReservedBytesForTest()).toBe(0);
1089
+ }
1090
+ finally {
1091
+ rawClient.close();
1092
+ }
1093
+ }
1094
+ await runCompletionCase();
1095
+ await runErrorCase();
1096
+ await runAbortCase();
1097
+ await runTimeoutCase();
1098
+ await runCloseCase();
1099
+ }, 10_000);
1100
+ it("test_a_backpressured_response_holds_its_reservation_until_the_write_settles", async () => {
1101
+ // `stream.end(body)` only queues `body` for asynchronous transmission.
1102
+ // A client that never reads its response leaves those bytes in process
1103
+ // memory well after `end()` returns, so the reservation covering them
1104
+ // must stay held until the write actually settles, not merely until the
1105
+ // call to `end()` returns.
1106
+ const responseBytes = 4 * 1024 * 1024;
1107
+ const responseBody = Buffer.alloc(responseBytes, 0x61);
1108
+ const { handle, bridgeToken, clientSide } = bindTestServer({
1109
+ forwardRequest: async (request) => {
1110
+ // Mirror the real forward path: the handler reserves the response
1111
+ // body it read from the sandbox target before returning it.
1112
+ if (!request.reservation.reserve(responseBytes)) {
1113
+ throw new BridgeProcessCapacityError();
1114
+ }
1115
+ return { status: 200, body: responseBody };
1116
+ },
1117
+ });
1118
+ const rawClient = connectRawClient(clientSide);
1119
+ try {
1120
+ const req = rawClient.request({
1121
+ ":method": "GET",
1122
+ ":path": "/api/agents/me",
1123
+ authorization: `Bearer ${bridgeToken}`,
1124
+ });
1125
+ // Deliberately paused: no `resume()` and no `data` listener yet, so
1126
+ // the client never issues the flow-control credit the host needs to
1127
+ // finish writing a response this size.
1128
+ const headersReceived = new Promise((resolve) => {
1129
+ req.once("response", () => resolve());
1130
+ });
1131
+ req.end();
1132
+ await headersReceived;
1133
+ // Give the host's `stream.end()` call, and its microtask queue, a
1134
+ // turn to run — the write is now queued but the client still is not
1135
+ // draining it.
1136
+ await new Promise((resolve) => setImmediate(resolve));
1137
+ expect(getBridgeBodyReservedBytesForTest()).toBeGreaterThan(0);
1138
+ const drained = new Promise((resolve) => {
1139
+ req.on("data", () => {
1140
+ // Discard: this test only cares that the bytes left the host.
1141
+ });
1142
+ req.once("end", () => resolve());
1143
+ });
1144
+ req.resume();
1145
+ await drained;
1146
+ // Give the host's `finally` block a turn to run after the write
1147
+ // settles.
1148
+ await new Promise((resolve) => setImmediate(resolve));
1149
+ expect(getBridgeBodyReservedBytesForTest()).toBe(0);
1150
+ }
1151
+ finally {
1152
+ rawClient.close();
1153
+ await handle.close();
1154
+ }
1155
+ });
1156
+ it("test_a_peer_reset_holds_the_reservation_until_the_active_forward_settles", async () => {
1157
+ let capturedRequest;
1158
+ let releaseForward;
1159
+ const forwardHeld = new Promise((resolve) => {
1160
+ releaseForward = resolve;
1161
+ });
1162
+ let forwardSettled = false;
1163
+ const { handle, bridgeToken, clientSide } = bindTestServer({
1164
+ forwardRequest: async (request) => {
1165
+ capturedRequest = request;
1166
+ // Stand in for a live response-body copy `readBridgeForwardResponseBody`
1167
+ // (`execution-target.ts`) would reserve against this same owner.
1168
+ request.reservation.reserve(10_000);
1169
+ // The forward stays active past the peer's own reset: it settles
1170
+ // only when the test releases it below, not merely when the abort
1171
+ // signal fires — the same shape a real outbound `fetch` bound to
1172
+ // `request.signal` has, since an abort does not settle the fetch
1173
+ // promise synchronously.
1174
+ await new Promise((resolve) => {
1175
+ if (request.signal.aborted) {
1176
+ resolve();
1177
+ return;
1178
+ }
1179
+ request.signal.addEventListener("abort", () => resolve(), { once: true });
1180
+ });
1181
+ await forwardHeld;
1182
+ forwardSettled = true;
1183
+ return { status: 200, body: Buffer.from("{}", "utf8") };
1184
+ },
1185
+ });
1186
+ const rawClient = connectRawClient(clientSide);
1187
+ try {
1188
+ const stream = rawClient.request({
1189
+ ":method": "GET",
1190
+ ":path": "/api/agents/me",
1191
+ authorization: `Bearer ${bridgeToken}`,
1192
+ });
1193
+ const streamClosed = new Promise((resolve) => {
1194
+ stream.on("error", () => resolve());
1195
+ stream.on("close", () => resolve());
1196
+ });
1197
+ stream.end();
1198
+ // Give the request time to reach the server, enter `forwardRequest`,
1199
+ // and land its reservation.
1200
+ await new Promise((resolve) => setTimeout(resolve, 20));
1201
+ expect(capturedRequest).toBeDefined();
1202
+ expect(getBridgeBodyReservedBytesForTest()).toBe(10_000);
1203
+ // The peer resets the stream. The forward call is still pending.
1204
+ stream.close(http2.constants.NGHTTP2_CANCEL);
1205
+ await streamClosed;
1206
+ await new Promise((resolve) => setTimeout(resolve, 20));
1207
+ expect(capturedRequest.signal.aborted).toBe(true);
1208
+ // The owner still holds its bytes: the active forward has not
1209
+ // settled yet, so `handleStream`'s `finally` has not released it.
1210
+ expect(forwardSettled).toBe(false);
1211
+ expect(getBridgeBodyReservedBytesForTest()).toBe(10_000);
1212
+ // Let the forward settle. The `finally` block releases the owner
1213
+ // exactly one time, and the process total returns to zero.
1214
+ releaseForward();
1215
+ await new Promise((resolve) => setTimeout(resolve, 20));
1216
+ expect(forwardSettled).toBe(true);
1217
+ expect(getBridgeBodyReservedBytesForTest()).toBe(0);
1218
+ }
1219
+ finally {
1220
+ rawClient.close();
1221
+ await handle.close();
1222
+ }
1223
+ });
1224
+ it("test_a_stalled_body_releases_its_reservation_while_other_streams_hold_theirs", async () => {
1225
+ const releaseByPath = new Map();
1226
+ const { handle, bridgeToken, clientSide } = bindTestServer({
1227
+ requestBodyTimeoutMs: 60,
1228
+ forwardRequest: async (request) => {
1229
+ // Stand in for a live response-body buffer: reserve, then hold the
1230
+ // forward open until the test releases this exact path.
1231
+ request.reservation.reserve(20_000);
1232
+ await new Promise((resolve) => {
1233
+ releaseByPath.set(request.pathname, resolve);
1234
+ });
1235
+ return { status: 200, body: Buffer.from("{}", "utf8") };
1236
+ },
1237
+ });
1238
+ const rawClient = connectRawClient(clientSide);
1239
+ try {
1240
+ const streamA = rawClient.request({
1241
+ ":method": "GET",
1242
+ ":path": "/api/agents/a",
1243
+ authorization: `Bearer ${bridgeToken}`,
1244
+ });
1245
+ const streamB = rawClient.request({
1246
+ ":method": "GET",
1247
+ ":path": "/api/agents/b",
1248
+ authorization: `Bearer ${bridgeToken}`,
1249
+ });
1250
+ // Drain each response as it arrives: `session.close()` later in this
1251
+ // test's teardown waits for every stream to fully end on both sides,
1252
+ // and an unread response can hold a stream open past that point.
1253
+ streamA.resume();
1254
+ streamB.resume();
1255
+ streamA.end();
1256
+ streamB.end();
1257
+ await new Promise((resolve) => setTimeout(resolve, 20));
1258
+ expect(getBridgeBodyReservedBytesForTest()).toBe(40_000);
1259
+ // The third stream's request body stalls past the idle bound. It
1260
+ // never reaches `forwardRequest`, so it never reserves anything of
1261
+ // its own; its owner still holds zero bytes at the moment it releases.
1262
+ const streamC = rawClient.request({
1263
+ ":method": "POST",
1264
+ ":path": "/api/issues/abc/comments",
1265
+ authorization: `Bearer ${bridgeToken}`,
1266
+ });
1267
+ const streamCClosed = new Promise((resolve) => {
1268
+ streamC.on("error", () => resolve());
1269
+ streamC.on("close", () => resolve());
1270
+ });
1271
+ streamC.write("partial-body");
1272
+ await streamCClosed;
1273
+ await new Promise((resolve) => setTimeout(resolve, 20));
1274
+ // The stalled stream's release changed nothing: the other two streams
1275
+ // keep their reservations.
1276
+ expect(getBridgeBodyReservedBytesForTest()).toBe(40_000);
1277
+ releaseByPath.get("/api/agents/a")?.();
1278
+ releaseByPath.get("/api/agents/b")?.();
1279
+ await new Promise((resolve) => setTimeout(resolve, 20));
1280
+ expect(getBridgeBodyReservedBytesForTest()).toBe(0);
1281
+ }
1282
+ finally {
1283
+ rawClient.close();
1284
+ await handle.close();
1285
+ }
1286
+ });
1287
+ it("test_a_denied_stream_drains_its_body_and_holds_no_bytes", async () => {
1288
+ const { handle, clientSide } = bindTestServer({
1289
+ forwardRequest: async () => ({ status: 200 }),
1290
+ });
1291
+ const rawClient = connectRawClient(clientSide);
1292
+ try {
1293
+ const response = await new Promise((resolve, reject) => {
1294
+ // No `authorization` header: the token check denies this stream
1295
+ // before its body is ever read.
1296
+ const req = rawClient.request({ ":method": "POST", ":path": "/api/issues/abc/comments" });
1297
+ let status = 0;
1298
+ req.on("response", (headers) => {
1299
+ status = Number(headers[":status"]) || 0;
1300
+ });
1301
+ req.on("data", () => undefined);
1302
+ req.on("end", () => resolve({ status }));
1303
+ req.on("error", reject);
1304
+ req.write(Buffer.alloc(50_000, "a"));
1305
+ req.end();
1306
+ });
1307
+ expect(response.status).toBe(401);
1308
+ await new Promise((resolve) => setTimeout(resolve, 20));
1309
+ expect(getBridgeBodyReservedBytesForTest()).toBe(0);
1310
+ }
1311
+ finally {
1312
+ rawClient.close();
1313
+ await handle.close();
1314
+ }
1315
+ });
1316
+ it("test_a_request_body_reservation_denial_answers_503_on_the_wire", async () => {
1317
+ // A denied request-body chunk must leave the stream alive long enough
1318
+ // to answer 503 for real, on the wire — not merely destroy the stream
1319
+ // and leave the caller with a bare reset. `respondJson` only queues the
1320
+ // 503 write; the handler must wait for that write to settle before it
1321
+ // destroys the stream, or the client can see a reset instead of the
1322
+ // full response body asserted below.
1323
+ const filler = createBridgeBodyReservation();
1324
+ expect(filler.reserve(HTTP2_BRIDGE_MAX_PROCESS_BODY_BYTES - 100)).toBe(true);
1325
+ const forwarderTracker = createForwarderCallTracker();
1326
+ const { handle, bridgeToken, clientSide } = bindTestServer({
1327
+ forwardRequest: async () => {
1328
+ forwarderTracker.markCalled();
1329
+ return { status: 200 };
1330
+ },
1331
+ });
1332
+ const rawClient = connectRawClient(clientSide);
1333
+ try {
1334
+ const response = await new Promise((resolve, reject) => {
1335
+ const req = rawClient.request({
1336
+ ":method": "POST",
1337
+ ":path": "/api/issues/abc/comments",
1338
+ authorization: `Bearer ${bridgeToken}`,
1339
+ });
1340
+ let status = 0;
1341
+ let body = "";
1342
+ req.setEncoding("utf8");
1343
+ req.on("response", (headers) => {
1344
+ status = Number(headers[":status"]) || 0;
1345
+ });
1346
+ req.on("data", (chunk) => (body += chunk));
1347
+ req.on("end", () => resolve({ status, body }));
1348
+ req.on("error", reject);
1349
+ // Ten times the 100 bytes of headroom the filler above left.
1350
+ req.end(Buffer.alloc(1_000, "a"));
1351
+ });
1352
+ expect(response.status).toBe(503);
1353
+ expect(forwarderTracker.called).toBe(false);
1354
+ // A raw reset delivers no body at all: parsing it here proves the
1355
+ // full JSON response actually reached the client, not merely the
1356
+ // status line.
1357
+ expect(JSON.parse(response.body)).toEqual({
1358
+ error: "The bridge host reached its reserved process body byte ceiling. Retry later.",
1359
+ });
1360
+ // The stream ended with a real response, not a raw reset: the session
1361
+ // stays healthy, so a second, complete request still succeeds.
1362
+ const survivingResponse = await expectSessionStillServesARequest(rawClient, {
1363
+ method: "GET",
1364
+ path: "/api/agents/me",
1365
+ token: bridgeToken,
1366
+ });
1367
+ expect(survivingResponse.status).toBe(200);
1368
+ }
1369
+ finally {
1370
+ rawClient.close();
1371
+ await handle.close();
1372
+ filler.release();
1373
+ }
1374
+ });
1375
+ it("test_a_stalled_client_still_frees_the_capacity_denial_reservation_and_slot", async () => {
1376
+ // The capacity-denial (503) path must not wait forever for its queued
1377
+ // write to settle: a client that grants no flow-control credit for the
1378
+ // response would otherwise hold this stream's reservation and
1379
+ // concurrent-stream slot open indefinitely. A zero initial window
1380
+ // denies the server any credit to send the 503 body with, at the
1381
+ // protocol layer, regardless of the fake transport's own buffering —
1382
+ // the same deterministic stall a real stalled peer produces.
1383
+ const filler = createBridgeBodyReservation();
1384
+ expect(filler.reserve(HTTP2_BRIDGE_MAX_PROCESS_BODY_BYTES - 100)).toBe(true);
1385
+ const forwarderTracker = createForwarderCallTracker();
1386
+ const { handle, bridgeToken, clientSide } = bindTestServer({
1387
+ capacityDenialSettleDeadlineMs: 30,
1388
+ forwardRequest: async () => {
1389
+ forwarderTracker.markCalled();
1390
+ return { status: 200 };
1391
+ },
1392
+ });
1393
+ const rawClient = connectRawClient(clientSide, { initialWindowSize: 0 });
1394
+ try {
1395
+ const startMs = Date.now();
1396
+ const closed = new Promise((resolve) => {
1397
+ const req = rawClient.request({
1398
+ ":method": "POST",
1399
+ ":path": "/api/issues/abc/comments",
1400
+ authorization: `Bearer ${bridgeToken}`,
1401
+ });
1402
+ req.on("error", () => undefined);
1403
+ req.on("close", () => resolve());
1404
+ // Ten times the 100 bytes of headroom the filler above left: the
1405
+ // request body itself denies the reservation and enters the 503
1406
+ // path.
1407
+ req.end(Buffer.alloc(1_000, "a"));
1408
+ });
1409
+ await closed;
1410
+ // The deadline bounded the wait: the stream closed near the deadline
1411
+ // bound, not after some much longer natural settle that never comes.
1412
+ expect(Date.now() - startMs).toBeLessThan(5_000);
1413
+ expect(forwarderTracker.called).toBe(false);
1414
+ // The stream's own reservation released even though the client never
1415
+ // drained the 503 body — only the filler's own bytes remain held.
1416
+ await new Promise((resolve) => setTimeout(resolve, 20));
1417
+ expect(getBridgeBodyReservedBytesForTest()).toBe(filler.heldBytes);
1418
+ // The stream's slot freed too. Restore a normal flow-control window
1419
+ // first: only the denied stream above needs to stall.
1420
+ await new Promise((resolve) => rawClient.settings({ initialWindowSize: 65_535 }, () => resolve()));
1421
+ const survivingResponse = await expectSessionStillServesARequest(rawClient, {
1422
+ method: "GET",
1423
+ path: "/api/agents/me",
1424
+ token: bridgeToken,
1425
+ });
1426
+ expect(survivingResponse.status).toBe(200);
1427
+ }
1428
+ finally {
1429
+ rawClient.close();
1430
+ await handle.close();
1431
+ filler.release();
1432
+ }
1433
+ });
1434
+ it("test_a_stalled_normal_response_still_frees_its_reservation_and_slot", async () => {
1435
+ // The completed-response (200) write path must not wait forever for its
1436
+ // queued write to settle either: a client that grants no flow-control
1437
+ // credit for the response would otherwise hold this stream's
1438
+ // reservation and concurrent-stream slot open indefinitely, the same
1439
+ // failure mode the capacity-denial path already guards against. A zero
1440
+ // initial window denies the server any credit to send the response body
1441
+ // with, at the protocol layer, regardless of the fake transport's own
1442
+ // buffering.
1443
+ const forwarderTracker = createForwarderCallTracker();
1444
+ const { handle, bridgeToken, clientSide } = bindTestServer({
1445
+ responseWriteSettleDeadlineMs: 30,
1446
+ forwardRequest: async () => {
1447
+ forwarderTracker.markCalled();
1448
+ return { status: 200, headers: {}, body: Buffer.alloc(1_000, "a") };
1449
+ },
1450
+ });
1451
+ const rawClient = connectRawClient(clientSide, { initialWindowSize: 0 });
1452
+ try {
1453
+ const startMs = Date.now();
1454
+ const closed = new Promise((resolve) => {
1455
+ const req = rawClient.request({
1456
+ ":method": "GET",
1457
+ ":path": "/api/agents/me",
1458
+ authorization: `Bearer ${bridgeToken}`,
1459
+ });
1460
+ req.on("error", () => undefined);
1461
+ req.on("close", () => resolve());
1462
+ req.end();
1463
+ });
1464
+ await closed;
1465
+ expect(forwarderTracker.called).toBe(true);
1466
+ // The deadline bounded the wait: the stream closed near the deadline
1467
+ // bound, not after some much longer natural settle that never comes.
1468
+ expect(Date.now() - startMs).toBeLessThan(5_000);
1469
+ // This stream's own reservation released even though the client never
1470
+ // drained the response body.
1471
+ await new Promise((resolve) => setTimeout(resolve, 20));
1472
+ expect(getBridgeBodyReservedBytesForTest()).toBe(0);
1473
+ // The stream's slot freed too. Restore a normal flow-control window
1474
+ // first: only the stalled stream above needs to stall.
1475
+ await new Promise((resolve) => rawClient.settings({ initialWindowSize: 65_535 }, () => resolve()));
1476
+ const survivingResponse = await expectSessionStillServesARequest(rawClient, {
1477
+ method: "GET",
1478
+ path: "/api/agents/me",
1479
+ token: bridgeToken,
1480
+ });
1481
+ expect(survivingResponse.status).toBe(200);
1482
+ }
1483
+ finally {
1484
+ rawClient.close();
1485
+ await handle.close();
1486
+ }
1487
+ });
1488
+ it("test_a_normal_response_that_settles_in_time_is_left_alone", async () => {
1489
+ // A response that genuinely settles inside the deadline must not be
1490
+ // force-destroyed: the bounded wait exists only for a stream that never
1491
+ // settles on its own.
1492
+ const { handle, bridgeToken, clientSide } = bindTestServer({
1493
+ responseWriteSettleDeadlineMs: 5_000,
1494
+ forwardRequest: async () => ({
1495
+ status: 200,
1496
+ headers: { "content-type": "application/json" },
1497
+ body: Buffer.from(JSON.stringify({ ok: true }), "utf8"),
1498
+ }),
1499
+ });
1500
+ const rawClient = connectRawClient(clientSide);
1501
+ try {
1502
+ const response = await expectSessionStillServesARequest(rawClient, {
1503
+ method: "GET",
1504
+ path: "/api/agents/me",
1505
+ token: bridgeToken,
1506
+ });
1507
+ expect(response.status).toBe(200);
1508
+ expect(JSON.parse(response.body)).toEqual({ ok: true });
1509
+ expect(getBridgeBodyReservedBytesForTest()).toBe(0);
1510
+ }
1511
+ finally {
1512
+ rawClient.close();
1513
+ await handle.close();
1514
+ }
1515
+ });
1516
+ it("test_a_response_reservation_denial_answers_503_on_the_wire", async () => {
1517
+ // The response reader on the sandbox target side
1518
+ // (`readBridgeForwardResponseBody`) denies its own reservation and
1519
+ // throws `BridgeProcessCapacityError` from inside `forwardRequest`,
1520
+ // after the forward handler already ran — a different call site than
1521
+ // the request-body denial above, but the same 503-before-destroy
1522
+ // contract must hold: the stream must stay alive long enough to answer
1523
+ // 503 for real, on the wire, not merely destroy and leave the caller
1524
+ // with a bare reset.
1525
+ const forwarderTracker = createForwarderCallTracker();
1526
+ // Only the first call denies: the surviving-request check below reuses
1527
+ // the same session for a second, independent request, which must
1528
+ // succeed once this first stream's reservation released.
1529
+ let forwardCalls = 0;
1530
+ const { handle, bridgeToken, clientSide } = bindTestServer({
1531
+ forwardRequest: async () => {
1532
+ forwarderTracker.markCalled();
1533
+ forwardCalls += 1;
1534
+ if (forwardCalls === 1) {
1535
+ throw new BridgeProcessCapacityError();
1536
+ }
1537
+ return { status: 200 };
1538
+ },
1539
+ });
1540
+ const rawClient = connectRawClient(clientSide);
1541
+ try {
1542
+ const response = await new Promise((resolve, reject) => {
1543
+ const req = rawClient.request({
1544
+ ":method": "GET",
1545
+ ":path": "/api/agents/me",
1546
+ authorization: `Bearer ${bridgeToken}`,
1547
+ });
1548
+ let status = 0;
1549
+ let body = "";
1550
+ req.setEncoding("utf8");
1551
+ req.on("response", (headers) => {
1552
+ status = Number(headers[":status"]) || 0;
1553
+ });
1554
+ req.on("data", (chunk) => (body += chunk));
1555
+ req.on("end", () => resolve({ status, body }));
1556
+ req.on("error", reject);
1557
+ req.end();
1558
+ });
1559
+ expect(response.status).toBe(503);
1560
+ expect(forwarderTracker.called).toBe(true);
1561
+ // A raw reset delivers no body at all: parsing it here proves the
1562
+ // full JSON response actually reached the client, not merely the
1563
+ // status line.
1564
+ expect(JSON.parse(response.body)).toEqual({
1565
+ error: "The bridge host reached its reserved process body byte ceiling. Retry later.",
1566
+ });
1567
+ // The stream ended with a real response, not a raw reset: the session
1568
+ // stays healthy, so a second, complete request still succeeds.
1569
+ const survivingResponse = await expectSessionStillServesARequest(rawClient, {
1570
+ method: "GET",
1571
+ path: "/api/agents/me",
1572
+ token: bridgeToken,
1573
+ });
1574
+ expect(survivingResponse.status).toBe(200);
1575
+ }
1576
+ finally {
1577
+ rawClient.close();
1578
+ await handle.close();
1579
+ }
1580
+ });
1581
+ it("test_a_denied_concatenated_request_body_never_allocates_the_copy", async () => {
1582
+ // The chunk-array copy and the concatenated copy are two separate live
1583
+ // buffers, so each must reserve on its own. Leave room for the first but
1584
+ // not the second: a correct reader checks the reservation before
1585
+ // `Buffer.concat` allocates the copy, so the denied concatenated copy
1586
+ // must never call `Buffer.concat` at all.
1587
+ const chunkBytes = 200_000;
1588
+ const filler = createBridgeBodyReservation();
1589
+ expect(filler.reserve(HTTP2_BRIDGE_MAX_PROCESS_BODY_BYTES - Math.floor(chunkBytes * 1.5))).toBe(true);
1590
+ const concatSpy = vi.spyOn(Buffer, "concat");
1591
+ const forwarderTracker = createForwarderCallTracker();
1592
+ const { handle, bridgeToken, clientSide } = bindTestServer({
1593
+ forwardRequest: async () => {
1594
+ forwarderTracker.markCalled();
1595
+ return { status: 200 };
1596
+ },
1597
+ });
1598
+ const rawClient = connectRawClient(clientSide);
1599
+ try {
1600
+ const response = await new Promise((resolve, reject) => {
1601
+ const req = rawClient.request({
1602
+ ":method": "POST",
1603
+ ":path": "/api/issues/abc/comments",
1604
+ authorization: `Bearer ${bridgeToken}`,
1605
+ });
1606
+ let status = 0;
1607
+ let body = "";
1608
+ req.setEncoding("utf8");
1609
+ req.on("response", (headers) => {
1610
+ status = Number(headers[":status"]) || 0;
1611
+ });
1612
+ req.on("data", (chunk) => (body += chunk));
1613
+ req.on("end", () => resolve({ status, body }));
1614
+ req.on("error", reject);
1615
+ req.write(Buffer.alloc(chunkBytes, "a"), () => {
1616
+ // Give the host a turn to receive the one chunk and reserve its
1617
+ // bytes before this test ends the stream and triggers the
1618
+ // concatenated-copy reservation attempt.
1619
+ setTimeout(() => {
1620
+ // The chunk-array reservation alone must already hold, on top of
1621
+ // the filler above, exactly the one chunk's bytes: the
1622
+ // concatenated-copy reservation has not run yet, because the
1623
+ // stream has not ended.
1624
+ expect(getBridgeBodyReservedBytesForTest()).toBe(filler.heldBytes + chunkBytes);
1625
+ req.end();
1626
+ }, 50);
1627
+ });
1628
+ });
1629
+ expect(response.status).toBe(503);
1630
+ expect(forwarderTracker.called).toBe(false);
1631
+ expect(concatSpy).not.toHaveBeenCalled();
1632
+ }
1633
+ finally {
1634
+ concatSpy.mockRestore();
1635
+ rawClient.close();
1636
+ await handle.close();
1637
+ filler.release();
1638
+ }
1639
+ });
1640
+ describe("parseCanonicalBridgeRequestPath", () => {
1641
+ it("parses an origin-form path with a query exactly one time", () => {
1642
+ const result = parseCanonicalBridgeRequestPath({ ":path": "/api/issues/abc?foo=bar" });
1643
+ expect(result).toEqual({ ok: true, value: { pathname: "/api/issues/abc", query: "?foo=bar" } });
1644
+ });
1645
+ it("test_a_non_origin_form_path_is_rejected", () => {
1646
+ expect(parseCanonicalBridgeRequestPath({ ":path": "http://evil.example/api" })).toEqual({
1647
+ ok: false,
1648
+ reason: "non_origin_form",
1649
+ });
1650
+ expect(parseCanonicalBridgeRequestPath({ ":path": "//evil.example/api" })).toEqual({
1651
+ ok: false,
1652
+ reason: "non_origin_form",
1653
+ });
1654
+ expect(parseCanonicalBridgeRequestPath({ ":path": "*" })).toEqual({
1655
+ ok: false,
1656
+ reason: "non_origin_form",
1657
+ });
1658
+ });
1659
+ it("test_an_encoded_separator_or_a_dot_segment_is_rejected", () => {
1660
+ expect(parseCanonicalBridgeRequestPath({ ":path": "/api%2fissues/abc" })).toEqual({
1661
+ ok: false,
1662
+ reason: "encoded_slash",
1663
+ });
1664
+ expect(parseCanonicalBridgeRequestPath({ ":path": "/api\\issues/abc" })).toEqual({
1665
+ ok: false,
1666
+ reason: "backslash",
1667
+ });
1668
+ expect(parseCanonicalBridgeRequestPath({ ":path": "/api/issues\0/abc" })).toEqual({
1669
+ ok: false,
1670
+ reason: "nul_byte",
1671
+ });
1672
+ expect(parseCanonicalBridgeRequestPath({ ":path": "/api/%00/abc" })).toEqual({
1673
+ ok: false,
1674
+ reason: "nul_byte",
1675
+ });
1676
+ expect(parseCanonicalBridgeRequestPath({ ":path": "/api/../secrets" })).toEqual({
1677
+ ok: false,
1678
+ reason: "dot_segment",
1679
+ });
1680
+ expect(parseCanonicalBridgeRequestPath({ ":path": "/api/%2e%2e/secrets" })).toEqual({
1681
+ ok: false,
1682
+ reason: "dot_segment",
1683
+ });
1684
+ expect(parseCanonicalBridgeRequestPath({ ":path": "/api/./issues" })).toEqual({
1685
+ ok: false,
1686
+ reason: "dot_segment",
1687
+ });
1688
+ });
1689
+ it("rejects a duplicate pseudo-header", () => {
1690
+ expect(parseCanonicalBridgeRequestPath({ ":path": ["/api/agents/me", "/api/agents/other"] })).toEqual({ ok: false, reason: "duplicate_pseudo_header" });
1691
+ });
1692
+ it("rejects a missing path", () => {
1693
+ expect(parseCanonicalBridgeRequestPath({})).toEqual({ ok: false, reason: "missing_path" });
1694
+ });
1695
+ });
1696
+ it("buildHttp2BridgeForwardUrl resolves the parsed pathname and query against the base URL", () => {
1697
+ const url = buildHttp2BridgeForwardUrl("http://127.0.0.1:4000", {
1698
+ pathname: "/api/issues/abc",
1699
+ query: "?foo=bar",
1700
+ });
1701
+ expect(url.toString()).toBe("http://127.0.0.1:4000/api/issues/abc?foo=bar");
1702
+ });
1703
+ it("classifyStreamAgainstGoaway classifies by the last processed stream id", () => {
1704
+ expect(classifyStreamAgainstGoaway(1, 3)).toBe("accepted");
1705
+ expect(classifyStreamAgainstGoaway(3, 3)).toBe("accepted");
1706
+ expect(classifyStreamAgainstGoaway(5, 3)).toBe("not_accepted");
1707
+ });
1708
+ it("test_a_stream_without_the_bridge_token_never_reaches_the_forwarder", async () => {
1709
+ const forwarderTracker = createForwarderCallTracker();
1710
+ const { handle, clientSide } = bindTestServer({
1711
+ forwardRequest: async (request) => {
1712
+ forwarderTracker.markCalled();
1713
+ return { status: 200, body: Buffer.from(JSON.stringify({ path: request.pathname }), "utf8") };
1714
+ },
1715
+ });
1716
+ const rawClient = connectRawClient(clientSide);
1717
+ try {
1718
+ const response = await new Promise((resolve, reject) => {
1719
+ // No `authorization` header at all: the stream never carries a token.
1720
+ const req = rawClient.request({ ":method": "GET", ":path": "/api/agents/me" });
1721
+ let status = 0;
1722
+ let body = "";
1723
+ req.on("response", (headers) => {
1724
+ status = Number(headers[":status"]) || 0;
1725
+ });
1726
+ req.setEncoding("utf8");
1727
+ req.on("data", (chunk) => (body += chunk));
1728
+ req.on("end", () => resolve({ status, body }));
1729
+ req.on("error", reject);
1730
+ req.end();
1731
+ });
1732
+ expect(response.status).toBe(401);
1733
+ expect(forwarderTracker.called).toBe(false);
1734
+ }
1735
+ finally {
1736
+ rawClient.close();
1737
+ await handle.close();
1738
+ }
1739
+ });
1740
+ it("test_a_denied_stream_with_an_unfinished_body_still_frees_its_stream_slot", async () => {
1741
+ // The server answers a denied stream (an invalid token, here) at once,
1742
+ // before it ever reads the request body. A peer that leaves that body
1743
+ // unfinished must not hold the stream open past the same idle bound an
1744
+ // authenticated request gets — otherwise, up to
1745
+ // `HTTP2_BRIDGE_MAX_CONCURRENT_STREAMS` denied streams could each retain
1746
+ // a slot forever and block every legitimate callback.
1747
+ const forwarderTracker = createForwarderCallTracker();
1748
+ const { handle, clientSide } = bindTestServer({
1749
+ requestBodyTimeoutMs: 30,
1750
+ forwardRequest: async () => {
1751
+ forwarderTracker.markCalled();
1752
+ return { status: 200 };
1753
+ },
1754
+ });
1755
+ const rawClient = connectRawClient(clientSide);
1756
+ try {
1757
+ const startMs = Date.now();
1758
+ const closed = new Promise((resolve) => {
1759
+ const req = rawClient.request({
1760
+ ":method": "POST",
1761
+ ":path": "/api/issues/abc/comments",
1762
+ // No `authorization` header: the token check denies this stream
1763
+ // before the body is ever read.
1764
+ });
1765
+ req.on("error", () => undefined);
1766
+ req.on("close", () => resolve());
1767
+ // Drain the response so its readable side reaches `end`: nothing in
1768
+ // this test reads the response body otherwise, and an unread
1769
+ // response can itself hold the client stream open past `close`.
1770
+ req.resume();
1771
+ // A partial body the request never ends: without its own bound, the
1772
+ // inbound half of this stream would stay open indefinitely.
1773
+ req.write("partial-body");
1774
+ });
1775
+ await closed;
1776
+ expect(Date.now() - startMs).toBeLessThan(5_000);
1777
+ expect(forwarderTracker.called).toBe(false);
1778
+ // The session survives the freed stream: a second, complete request
1779
+ // still succeeds, proving the session itself stayed open and healthy.
1780
+ const survivingResponse = await expectSessionStillServesARequest(rawClient, {
1781
+ method: "GET",
1782
+ path: "/api/agents/me",
1783
+ token: BRIDGE_TOKEN,
1784
+ });
1785
+ expect(survivingResponse.status).toBe(200);
1786
+ }
1787
+ finally {
1788
+ rawClient.close();
1789
+ await handle.close();
1790
+ }
1791
+ });
1792
+ it("serves only exact GET schema discovery through HTTP/2", async () => {
1793
+ const schema = { openapi: "3.1.0", paths: {} };
1794
+ const forwarded = [];
1795
+ const { gateway, handle } = createTestPair({
1796
+ forwardRequest: async (request) => {
1797
+ forwarded.push(`${request.method} ${request.pathname}`);
1798
+ return { status: 200, body: Buffer.from(JSON.stringify(schema)) };
1799
+ },
1800
+ });
1801
+ try {
1802
+ for (const [method, path, status] of [
1803
+ ["GET", "/api/openapi.json", 200],
1804
+ ["POST", "/api/openapi.json", 403],
1805
+ ["PATCH", "/api/openapi.json", 403],
1806
+ ["DELETE", "/api/openapi.json", 403],
1807
+ ["GET", "/api/openapi.json/extra", 403],
1808
+ ["GET", "/api/openapiXjson", 403],
1809
+ ["GET", "/api/secrets", 403],
1810
+ ]) {
1811
+ const response = await gateway.forwardRequest({
1812
+ method, path, query: "", headers: {}, body: Buffer.alloc(0), receivedToken: BRIDGE_TOKEN,
1813
+ });
1814
+ expect(response.status).toBe(status);
1815
+ if (status === 200)
1816
+ expect(JSON.parse(response.body.toString())).toEqual(schema);
1817
+ }
1818
+ expect(forwarded).toEqual(["GET /api/openapi.json"]);
1819
+ }
1820
+ finally {
1821
+ await gateway.close();
1822
+ await handle.close();
1823
+ }
1824
+ });
1825
+ it("rejects a route the allowlist does not carry, before the forwarder runs", async () => {
1826
+ const forwarderTracker = createForwarderCallTracker();
1827
+ const { gateway, handle } = createTestPair({
1828
+ forwardRequest: async () => {
1829
+ forwarderTracker.markCalled();
1830
+ return { status: 200 };
1831
+ },
1832
+ });
1833
+ try {
1834
+ const response = await gateway.forwardRequest({
1835
+ method: "DELETE",
1836
+ path: "/api/agents/me",
1837
+ query: "",
1838
+ headers: {},
1839
+ body: Buffer.alloc(0),
1840
+ receivedToken: BRIDGE_TOKEN,
1841
+ });
1842
+ expect(response.status).toBe(403);
1843
+ expect(forwarderTracker.called).toBe(false);
1844
+ }
1845
+ finally {
1846
+ await gateway.close();
1847
+ await handle.close();
1848
+ }
1849
+ });
1850
+ it("test_a_maximum_size_multipart_attachment_upload_fits_through_the_bridge", async () => {
1851
+ // A file at the exact attachment content ceiling (10 MiB — the same
1852
+ // figure `MAX_ATTACHMENT_BYTES` in `server/src/attachment-types.ts`
1853
+ // enforces) still crosses the bridge wrapped in a multipart body: the
1854
+ // boundary line and the part's own headers add bytes on top of that file
1855
+ // content. The bridge's own body limit needs headroom for that framing,
1856
+ // or a valid maximum-size attachment fails here before the server ever
1857
+ // sees it.
1858
+ const maxAttachmentBytes = 10 * 1024 * 1024;
1859
+ const boundary = "----PaperclipTestBoundary1234567890abcdef";
1860
+ const preamble = Buffer.from(`--${boundary}\r\n` +
1861
+ `Content-Disposition: form-data; name="file"; filename="attachment.bin"\r\n` +
1862
+ `Content-Type: application/octet-stream\r\n\r\n`, "utf8");
1863
+ const fileContent = Buffer.alloc(maxAttachmentBytes, 0x61);
1864
+ const epilogue = Buffer.from(`\r\n--${boundary}--\r\n`, "utf8");
1865
+ const multipartBody = Buffer.concat([preamble, fileContent, epilogue]);
1866
+ // The wrapper really does add bytes on top of the file content alone —
1867
+ // otherwise this test would prove nothing about framing headroom.
1868
+ expect(multipartBody.byteLength).toBeGreaterThan(maxAttachmentBytes);
1869
+ expect(multipartBody.byteLength).toBeLessThanOrEqual(DEFAULT_SANDBOX_CALLBACK_BRIDGE_MAX_BODY_BYTES);
1870
+ let receivedBodyBytes = 0;
1871
+ const { gateway, handle } = createTestPair({
1872
+ routes: HTTP2_SANDBOX_CALLBACK_BRIDGE_ROUTE_ALLOWLIST,
1873
+ forwardRequest: async (request) => {
1874
+ receivedBodyBytes = request.body.byteLength;
1875
+ return { status: 201, body: Buffer.from("{}", "utf8") };
1876
+ },
1877
+ });
1878
+ try {
1879
+ const response = await gateway.forwardRequest({
1880
+ method: "POST",
1881
+ path: "/api/companies/co-1/issues/issue-1/attachments",
1882
+ query: "",
1883
+ headers: { "content-type": `multipart/form-data; boundary=${boundary}` },
1884
+ body: multipartBody,
1885
+ receivedToken: BRIDGE_TOKEN,
1886
+ });
1887
+ expect(response.status).toBe(201);
1888
+ expect(receivedBodyBytes).toBe(multipartBody.byteLength);
1889
+ }
1890
+ finally {
1891
+ await gateway.close();
1892
+ await handle.close();
1893
+ }
1894
+ }, 20_000);
1895
+ it("the sandbox gateway keeps its own token check before it opens a stream", async () => {
1896
+ const forwarderTracker = createForwarderCallTracker();
1897
+ const { gateway, handle } = createTestPair({
1898
+ forwardRequest: async () => {
1899
+ forwarderTracker.markCalled();
1900
+ return { status: 200 };
1901
+ },
1902
+ });
1903
+ try {
1904
+ await expect(gateway.forwardRequest({
1905
+ method: "GET",
1906
+ path: "/api/agents/me",
1907
+ query: "",
1908
+ headers: {},
1909
+ body: Buffer.alloc(0),
1910
+ receivedToken: "wrong-token",
1911
+ })).rejects.toThrow(/invalid bridge token/i);
1912
+ expect(forwarderTracker.called).toBe(false);
1913
+ }
1914
+ finally {
1915
+ await gateway.close();
1916
+ await handle.close();
1917
+ }
1918
+ });
1919
+ it("wrapDuplexChannelAsNodeDuplex relays writes and pushes through onData", async () => {
1920
+ const written = [];
1921
+ let dataListener;
1922
+ let exitListener;
1923
+ const channel = {
1924
+ write: (data) => {
1925
+ written.push(Buffer.from(data));
1926
+ },
1927
+ onData: (listener) => {
1928
+ dataListener = listener;
1929
+ },
1930
+ onExit: (listener) => {
1931
+ exitListener = listener;
1932
+ },
1933
+ stop: () => undefined,
1934
+ close: async () => undefined,
1935
+ };
1936
+ const duplex = wrapDuplexChannelAsNodeDuplex(channel);
1937
+ const received = [];
1938
+ duplex.on("data", (chunk) => received.push(chunk));
1939
+ duplex.write(Buffer.from("outbound"));
1940
+ await new Promise((resolve) => setImmediate(resolve));
1941
+ expect(Buffer.concat(written).toString("utf8")).toBe("outbound");
1942
+ dataListener?.(Buffer.from("inbound"));
1943
+ await new Promise((resolve) => setImmediate(resolve));
1944
+ expect(Buffer.concat(received).toString("utf8")).toBe("inbound");
1945
+ const ended = new Promise((resolve) => duplex.on("end", resolve));
1946
+ exitListener?.({ exitCode: 0 });
1947
+ await ended;
1948
+ });
1949
+ it("wrapDuplexChannelAsNodeDuplex queues chunks past a full readable side and drains them once the consumer reads again", async () => {
1950
+ let dataListener;
1951
+ const channel = {
1952
+ write: () => undefined,
1953
+ onData: (listener) => {
1954
+ dataListener = listener;
1955
+ },
1956
+ onExit: () => undefined,
1957
+ stop: () => undefined,
1958
+ close: async () => undefined,
1959
+ };
1960
+ const duplex = wrapDuplexChannelAsNodeDuplex(channel, { maxBufferedReadBytes: 1_000_000 });
1961
+ const received = [];
1962
+ // The first chunk alone passes the readable side's default 64 KiB
1963
+ // high-water mark, so `push()` reports the readable side full. The two
1964
+ // chunks that follow queue in the wrapper instead of pushing past that
1965
+ // signal — this is the bounded flow-control path this fix adds.
1966
+ dataListener?.(Buffer.alloc(70_000, "a"));
1967
+ dataListener?.(Buffer.from("-second-"));
1968
+ dataListener?.(Buffer.from("-third-"));
1969
+ // Attaching a "data" listener now starts flowing mode, which drives the
1970
+ // wrapper's own `read()` until every queued chunk drains, proving no
1971
+ // queued chunk was dropped and the arrival order held.
1972
+ const drainedAll = new Promise((resolve) => {
1973
+ duplex.on("data", (chunk) => {
1974
+ received.push(chunk);
1975
+ if (Buffer.concat(received).includes("-third-"))
1976
+ resolve();
1977
+ });
1978
+ });
1979
+ await drainedAll;
1980
+ expect(Buffer.concat(received).toString("utf8").endsWith("-second--third-")).toBe(true);
1981
+ });
1982
+ it("wrapDuplexChannelAsNodeDuplex stops the channel and destroys the duplex once the bounded read backpressure buffer overflows", async () => {
1983
+ let dataListener;
1984
+ let stopped = false;
1985
+ const channel = {
1986
+ write: () => undefined,
1987
+ onData: (listener) => {
1988
+ dataListener = listener;
1989
+ },
1990
+ onExit: () => undefined,
1991
+ stop: () => {
1992
+ stopped = true;
1993
+ },
1994
+ close: async () => undefined,
1995
+ };
1996
+ // The cap must clear the default 65,536-byte readable high-water mark,
1997
+ // so the first chunk below still passes the direct-push check and
1998
+ // forces `push()` to report the readable side full; the overflow this
1999
+ // test proves comes from the queue that follows, not from that first
2000
+ // chunk on its own.
2001
+ const duplex = wrapDuplexChannelAsNodeDuplex(channel, { maxBufferedReadBytes: 80_000 });
2002
+ // No consumer ever attaches, so the readable side never drains: every
2003
+ // chunk past the first, which alone passes the default high-water mark,
2004
+ // fills the bounded queue instead of the unbounded internal buffer a
2005
+ // caller ignoring `push()`'s return would grow.
2006
+ const errored = new Promise((resolve) => duplex.on("error", resolve));
2007
+ dataListener?.(Buffer.alloc(70_000, "a")); // passes the high-water mark and the cap; still pushed directly.
2008
+ dataListener?.(Buffer.alloc(30_000, "b")); // queues: 30,000 of the 80,000-byte cap.
2009
+ dataListener?.(Buffer.alloc(30_000, "b")); // queues: 60,000 of the 80,000-byte cap.
2010
+ dataListener?.(Buffer.alloc(30_000, "b")); // 90,000 queued bytes passes the cap.
2011
+ const error = await errored;
2012
+ expect(error.message).toMatch(/backpressure/i);
2013
+ expect(stopped).toBe(true);
2014
+ });
2015
+ it("stops the channel when the read queue passes the lowered byte bound", async () => {
2016
+ let dataListener;
2017
+ let stopped = false;
2018
+ const channel = {
2019
+ write: () => undefined,
2020
+ onData: (listener) => {
2021
+ dataListener = listener;
2022
+ },
2023
+ onExit: () => undefined,
2024
+ stop: () => {
2025
+ stopped = true;
2026
+ },
2027
+ close: async () => undefined,
2028
+ };
2029
+ // No override: this test proves the default bound itself is the direct
2030
+ // 524,288-byte value, no longer derived from `HTTP2_BRIDGE_MAX_SESSION_MEMORY`.
2031
+ // No consumer ever attaches, so the readable side never drains.
2032
+ expect(DEFAULT_HTTP2_BRIDGE_MAX_BUFFERED_READ_BYTES).toBe(524_288);
2033
+ const duplex = wrapDuplexChannelAsNodeDuplex(channel);
2034
+ const errored = new Promise((resolve) => duplex.on("error", resolve));
2035
+ dataListener?.(Buffer.alloc(70_000, "a")); // passes the default high-water mark; still pushed directly.
2036
+ dataListener?.(Buffer.alloc(500_000, "b")); // queues most of the 524,288-byte default cap.
2037
+ dataListener?.(Buffer.alloc(60_000, "b")); // passes the default cap.
2038
+ const error = await errored;
2039
+ expect(error.message).toMatch(/backpressure/i);
2040
+ expect(stopped).toBe(true);
2041
+ });
2042
+ it("wrapDuplexChannelAsNodeDuplex fails closed on one inbound chunk larger than the bounded read backpressure buffer, before the queue holds anything to compare it against", async () => {
2043
+ let dataListener;
2044
+ let stopped = false;
2045
+ const channel = {
2046
+ write: () => undefined,
2047
+ onData: (listener) => {
2048
+ dataListener = listener;
2049
+ },
2050
+ onExit: () => undefined,
2051
+ stop: () => {
2052
+ stopped = true;
2053
+ },
2054
+ close: async () => undefined,
2055
+ };
2056
+ // No consumer ever attaches, and the queue is empty when this chunk
2057
+ // arrives, so a check that only bounds the queue's cumulative size (and
2058
+ // not one chunk's own size) would let this chunk reach `push()` unbound.
2059
+ const duplex = wrapDuplexChannelAsNodeDuplex(channel, { maxBufferedReadBytes: 5_000 });
2060
+ const errored = new Promise((resolve) => duplex.on("error", resolve));
2061
+ dataListener?.(Buffer.alloc(10_000, "a")); // exceeds the 5,000-byte cap on its own, on the very first chunk.
2062
+ const error = await errored;
2063
+ expect(error.message).toMatch(/backpressure/i);
2064
+ expect(stopped).toBe(true);
2065
+ });
2066
+ it("wrapDuplexChannelAsNodeDuplex fails closed once the read backpressure queue stalls with no drain, even though it stays under the byte cap", async () => {
2067
+ let dataListener;
2068
+ let stopped = false;
2069
+ const channel = {
2070
+ write: () => undefined,
2071
+ onData: (listener) => {
2072
+ dataListener = listener;
2073
+ },
2074
+ onExit: () => undefined,
2075
+ stop: () => {
2076
+ stopped = true;
2077
+ },
2078
+ close: async () => undefined,
2079
+ };
2080
+ // A generous byte cap, so the byte-cap check above never fires: this
2081
+ // test proves the independent time bound catches a stuck consumer the
2082
+ // byte cap alone would miss.
2083
+ const duplex = wrapDuplexChannelAsNodeDuplex(channel, {
2084
+ maxBufferedReadBytes: 10_000_000,
2085
+ readBackpressureStallMs: 40,
2086
+ });
2087
+ const errored = new Promise((resolve) => duplex.on("error", resolve));
2088
+ dataListener?.(Buffer.alloc(70_000, "a")); // passes the high-water mark; pushed directly, no consumer drains it.
2089
+ dataListener?.(Buffer.from("queued-and-never-drained")); // queues; no "data" listener ever attaches to drain it.
2090
+ const error = await errored;
2091
+ expect(error.message).toMatch(/stall/i);
2092
+ expect(stopped).toBe(true);
2093
+ });
2094
+ it("wrapDuplexChannelAsNodeDuplex clears the stall bound once the queue fully drains, instead of firing later on an idle channel", async () => {
2095
+ let dataListener;
2096
+ const channel = {
2097
+ write: () => undefined,
2098
+ onData: (listener) => {
2099
+ dataListener = listener;
2100
+ },
2101
+ onExit: () => undefined,
2102
+ stop: () => undefined,
2103
+ close: async () => undefined,
2104
+ };
2105
+ // A short stall bound, so this test proves the drain below clears the
2106
+ // timer instead of merely finishing before a long one would have fired.
2107
+ const duplex = wrapDuplexChannelAsNodeDuplex(channel, {
2108
+ maxBufferedReadBytes: 10_000_000,
2109
+ readBackpressureStallMs: 20,
2110
+ });
2111
+ const received = [];
2112
+ const drainedAll = new Promise((resolve) => {
2113
+ duplex.on("data", (chunk) => {
2114
+ received.push(chunk);
2115
+ if (Buffer.concat(received).includes("-third-"))
2116
+ resolve();
2117
+ });
2118
+ });
2119
+ dataListener?.(Buffer.alloc(70_000, "a")); // passes the high-water mark; queues the chunks that follow.
2120
+ dataListener?.(Buffer.from("-second-"));
2121
+ dataListener?.(Buffer.from("-third-"));
2122
+ await drainedAll;
2123
+ // Wait past the stall bound with the channel now idle and the queue
2124
+ // empty. A timer the full drain above did not clear would fire here.
2125
+ await new Promise((resolve) => setTimeout(resolve, 60));
2126
+ expect(duplex.destroyed).toBe(false);
2127
+ });
2128
+ });
2129
+ //# sourceMappingURL=http2-bridge-server.test.js.map