@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,2357 @@
1
+ import { createHash, randomBytes, randomUUID, timingSafeEqual } from "node:crypto";
2
+ import { promises as fs } from "node:fs";
3
+ import http2 from "node:http2";
4
+ import os from "node:os";
5
+ import path from "node:path";
6
+ import { decodeSandboxBridgeBody, encodeSandboxBridgeBody, sandboxBridgeBodyCodecSource, sandboxBridgeEnvelopeLimit, } from "./sandbox-callback-bridge-body.js";
7
+ import { runWithoutActiveStep, runWithRuntimeParent, } from "./acpx-engine/startup-timing.js";
8
+ import { preferredShellForSandbox, shellCommandArgs } from "./sandbox-shell.js";
9
+ const DEFAULT_BRIDGE_TOKEN_BYTES = 24;
10
+ const DEFAULT_BRIDGE_POLL_INTERVAL_MS = 100;
11
+ const DEFAULT_BRIDGE_RESPONSE_TIMEOUT_MS = 30_000;
12
+ const DEFAULT_BRIDGE_STOP_TIMEOUT_MS = 2_000;
13
+ const DEFAULT_BRIDGE_MAX_QUEUE_DEPTH = 64;
14
+ // A `BridgeBodyReservation` owner (`http2-bridge-server.ts`) now bounds the
15
+ // process-wide total of live request and response body bytes at
16
+ // `HTTP2_BRIDGE_MAX_PROCESS_BODY_BYTES` (1 GiB), so this per-body limit can
17
+ // rise to the same ceiling `MAX_ATTACHMENT_BYTES`
18
+ // (`server/src/attachment-types.ts`) already accepts, with no unbounded
19
+ // growth in process memory.
20
+ //
21
+ // The attachment upload route carries its file inside a multipart body, so a
22
+ // file at the exact `MAX_ATTACHMENT_BYTES` ceiling needs more than
23
+ // `MAX_ATTACHMENT_BYTES` raw bytes to cross the bridge: the multipart
24
+ // boundary line, each part's `Content-Disposition` and `Content-Type`
25
+ // headers, and the small JSON metadata field this route also accepts all add
26
+ // bytes on top of the file content the server measures. This headroom
27
+ // covers that framing with a wide margin, so a valid maximum-size attachment
28
+ // never fails at the bridge before the server ever sees it.
29
+ const BRIDGE_MULTIPART_FRAMING_HEADROOM_BYTES = 64 * 1024;
30
+ const DEFAULT_BRIDGE_MAX_BODY_BYTES = 10 * 1024 * 1024 + BRIDGE_MULTIPART_FRAMING_HEADROOM_BYTES;
31
+ // Per-iteration timeout for one poll-loop client call. A healthy control-plane
32
+ // round trip finishes in well under one second, so 10s is far above a normal
33
+ // iteration and never false-fires on a slow-but-live call. It is also well
34
+ // under the in-sandbox 30s response deadline
35
+ // (PAPERCLIP_BRIDGE_RESPONSE_TIMEOUT_MS), so the host loop fails fast and writes
36
+ // 503 responses before the in-sandbox client gives up. A silently unresponsive
37
+ // sandbox channel makes a client call hang with no reject; this timeout turns
38
+ // that hang into a caught error, so the poll loop can back off and retry while
39
+ // the watchdog below decides when to fail the queued requests.
40
+ const DEFAULT_BRIDGE_ITERATION_TIMEOUT_MS = 10_000;
41
+ // Watchdog backstop for a hang that the per-iteration timeout does not catch
42
+ // (for example many slow-but-under-timeout calls, or a stall outside the awaited
43
+ // calls). It is larger than one iteration timeout, so a single slow iteration
44
+ // never trips it, and it stays under the in-sandbox 30s response deadline.
45
+ const DEFAULT_BRIDGE_WATCHDOG_TIMEOUT_MS = 20_000;
46
+ // Grace period the recovery path gives an aborted in-flight handler to finalize
47
+ // its own response. The recovery path aborts the handler, then waits this long.
48
+ // A cooperating handler threads the abort signal into its work, rejects, and
49
+ // writes its own response inside the grace, so its accurate result wins. A
50
+ // handler that ignores the signal and never settles does not write inside the
51
+ // grace; the recovery path then writes a non-retryable 504 backstop, so the
52
+ // request never strands with no response. The grace is well under the in-sandbox
53
+ // 30s response deadline, so the backstop lands before the in-sandbox client
54
+ // gives up.
55
+ const DEFAULT_BRIDGE_ABORTED_HANDLER_GRACE_MS = 5_000;
56
+ // The recovery path retries the 504 backstop write this many times before it
57
+ // gives up. A single transient write failure, or one that exceeds the iteration
58
+ // timeout, then does not strand the caller with no terminal response.
59
+ const MAX_BACKSTOP_WRITE_ATTEMPTS = 3;
60
+ // The delay between two 504 backstop write attempts. It is short, so all retries
61
+ // finish well under the in-sandbox 30s response deadline.
62
+ const BACKSTOP_WRITE_RETRY_MS = 50;
63
+ // Backoff cap between poll-loop retries after a transient iteration failure.
64
+ // The cap keeps a recovering loop probing often enough to resume before the
65
+ // in-sandbox 30s response deadline strands queued callers, while the
66
+ // exponential ramp below it keeps a hard-down channel from burning an exec
67
+ // call every poll interval.
68
+ const MAX_TRANSIENT_ITERATION_BACKOFF_MS = 5_000;
69
+ const REMOTE_WRITE_BASE64_CHUNK_SIZE = 32 * 1024;
70
+ export const SANDBOX_CALLBACK_BRIDGE_ENTRYPOINT = "paperclip-bridge-server.mjs";
71
+ const SANDBOX_EXEC_CHANNEL_ENV = "PAPERCLIP_SANDBOX_EXEC_CHANNEL";
72
+ const SANDBOX_EXEC_CHANNEL_BRIDGE = "bridge";
73
+ // The bridge modes the generated gateway supports. The file mode polls a
74
+ // request/response queue on disk. The http2 mode runs one Node HTTP/2 client
75
+ // session directly on stdin/stdout, after it sends the one READY line the
76
+ // host readiness gate expects. The generated `.mjs` selects the mode from
77
+ // `PAPERCLIP_API_BRIDGE_MODE`. The generated gateway rejects every other
78
+ // value with a fixed startup error, including the retired duplex transport.
79
+ // HTTP/2 is the preferred transport. `queue_v1` is the soft-deprecated fallback.
80
+ const SANDBOX_CALLBACK_BRIDGE_FILE_MODE = "queue_v1";
81
+ /** The active non-file transport mode. */
82
+ export const SANDBOX_CALLBACK_BRIDGE_HTTP2_MODE = "http2_v1";
83
+ /** Span name that wraps one Paperclip-API callback request — read the request,
84
+ * write the response, and remove the request file. */
85
+ const CALLBACK_BRIDGE_RELAY_REQUEST_SPAN = "sandbox.callbackBridge.relayRequest";
86
+ /** Span name for a failed or hung bridge worker. The worker runs a throwing
87
+ * function under this span through `input.runtimeSpan`, so the failure lands in
88
+ * the run trace. The run and the orchestrator then see the hang, not only
89
+ * stdout. */
90
+ const CALLBACK_BRIDGE_WORKER_FAILED_SPAN = "sandbox.callbackBridge.workerFailed";
91
+ export const DEFAULT_SANDBOX_CALLBACK_BRIDGE_MAX_BODY_BYTES = DEFAULT_BRIDGE_MAX_BODY_BYTES;
92
+ // Routes the in-sandbox heartbeat skill is documented to call. The server
93
+ // still enforces actor-level permissions on top of this allowlist; the list
94
+ // exists to bound the surface area a compromised CLI could reach via the
95
+ // reverse bridge. Keep this in sync with the Paperclip skill in
96
+ // `skills/paperclip/SKILL.md` and `references/api-reference.md`.
97
+ export const DEFAULT_SANDBOX_CALLBACK_BRIDGE_ROUTE_ALLOWLIST = [
98
+ // Runtime capability authentication is independently checked by the controller.
99
+ { method: "POST", path: /^\/runtime-tools\/github\/credentials$/ },
100
+ // Identity, inbox, agent self-management
101
+ { method: "GET", path: /^\/api\/agents\/me$/ },
102
+ { method: "GET", path: /^\/api\/agents\/me\/inbox-lite$/ },
103
+ { method: "GET", path: /^\/api\/agents\/me\/inbox\/mine$/ },
104
+ { method: "GET", path: /^\/api\/agents\/[^/]+$/ },
105
+ { method: "GET", path: /^\/api\/agents\/[^/]+\/skills$/ },
106
+ { method: "POST", path: /^\/api\/agents\/[^/]+\/skills\/sync$/ },
107
+ { method: "PATCH", path: /^\/api\/agents\/[^/]+\/instructions-path$/ },
108
+ // Read-only schema discovery for validated control-plane requests.
109
+ { method: "GET", path: /^\/api\/openapi\.json$/ },
110
+ // Company-level reads used to discover work and context
111
+ { method: "GET", path: /^\/api\/companies\/[^/]+$/ },
112
+ { method: "GET", path: /^\/api\/companies\/[^/]+\/dashboard$/ },
113
+ { method: "GET", path: /^\/api\/companies\/[^/]+\/agents$/ },
114
+ { method: "GET", path: /^\/api\/companies\/[^/]+\/issues$/ },
115
+ { method: "GET", path: /^\/api\/companies\/[^/]+\/projects$/ },
116
+ { method: "GET", path: /^\/api\/companies\/[^/]+\/goals$/ },
117
+ { method: "GET", path: /^\/api\/companies\/[^/]+\/org$/ },
118
+ { method: "GET", path: /^\/api\/companies\/[^/]+\/approvals$/ },
119
+ { method: "GET", path: /^\/api\/companies\/[^/]+\/routines$/ },
120
+ { method: "GET", path: /^\/api\/companies\/[^/]+\/skills$/ },
121
+ { method: "GET", path: /^\/api\/projects\/[^/]+$/ },
122
+ { method: "GET", path: /^\/api\/goals\/[^/]+$/ },
123
+ // Task-bound email actions. Company, inbox ownership, task/run authority,
124
+ // and action policies are enforced by the controller; mailbox setup stays denied.
125
+ { method: "GET", path: /^\/api\/companies\/[^/]+\/email\/inboxes$/ },
126
+ { method: "GET", path: /^\/api\/companies\/[^/]+\/email\/tasks\/[^/]+$/ },
127
+ { method: "GET", path: /^\/api\/companies\/[^/]+\/email\/deliveries\/[^/]+$/ },
128
+ { method: "POST", path: /^\/api\/companies\/[^/]+\/email\/send$/ },
129
+ // Issue lifecycle: read context, checkout, update, comment, document, release
130
+ { method: "GET", path: /^\/api\/issues\/[^/]+$/ },
131
+ { method: "GET", path: /^\/api\/issues\/[^/]+\/heartbeat-context$/ },
132
+ { method: "GET", path: /^\/api\/issues\/[^/]+\/comments(?:\/[^/]+)?$/ },
133
+ { method: "POST", path: /^\/api\/issues\/[^/]+\/comments$/ },
134
+ { method: "GET", path: /^\/api\/issues\/[^/]+\/documents(?:\/[^/]+)?$/ },
135
+ { method: "GET", path: /^\/api\/issues\/[^/]+\/documents\/[^/]+\/revisions$/ },
136
+ { method: "PUT", path: /^\/api\/issues\/[^/]+\/documents\/[^/]+$/ },
137
+ { method: "POST", path: /^\/api\/issues\/[^/]+\/checkout$/ },
138
+ { method: "POST", path: /^\/api\/issues\/[^/]+\/release$/ },
139
+ { method: "PATCH", path: /^\/api\/issues\/[^/]+$/ },
140
+ { method: "GET", path: /^\/api\/issues\/[^/]+\/approvals$/ },
141
+ // Files: the queue encodes binary bodies; HTTP/2 carries the same bytes directly.
142
+ { method: "GET", path: /^\/api\/issues\/[^/]+\/attachments$/ },
143
+ { method: "POST", path: /^\/api\/companies\/[^/]+\/issues\/[^/]+\/attachments$/ },
144
+ { method: "GET", path: /^\/api\/attachments\/[^/]+\/content$/ },
145
+ // Work products: publish branch/commit/artifact metadata for completed work.
146
+ { method: "GET", path: /^\/api\/issues\/[^/]+\/work-products$/ },
147
+ { method: "POST", path: /^\/api\/issues\/[^/]+\/work-products$/ },
148
+ { method: "PATCH", path: /^\/api\/work-products\/[^/]+$/ },
149
+ // Issue-thread interactions (create, resolve, verdict, and withdraw)
150
+ { method: "GET", path: /^\/api\/issues\/[^/]+\/interactions(?:\/[^/]+)?$/ },
151
+ { method: "POST", path: /^\/api\/issues\/[^/]+\/interactions$/ },
152
+ { method: "POST", path: /^\/api\/issues\/[^/]+\/interactions\/[^/]+\/(?:accept|reject|respond|verdicts|withdraw)$/ },
153
+ // Subtasks / delegation
154
+ { method: "POST", path: /^\/api\/companies\/[^/]+\/issues$/ },
155
+ // Hiring (paperclip-create-agent skill): adapter/icon discovery, comparing
156
+ // existing agent configs, submitting the hire request, and linking the
157
+ // resulting approval to its source issue. Direct agent creation
158
+ // (POST /api/companies/:id/agents) stays denied — hires must go through the
159
+ // approval-gated agent-hires endpoint, which the server still permission-checks.
160
+ { method: "GET", path: /^\/llms\/agent-configuration\.txt$/ },
161
+ { method: "GET", path: /^\/llms\/agent-configuration\/[^/]+\.txt$/ },
162
+ { method: "GET", path: /^\/llms\/agent-icons\.txt$/ },
163
+ { method: "GET", path: /^\/api\/companies\/[^/]+\/agent-configurations$/ },
164
+ { method: "POST", path: /^\/api\/companies\/[^/]+\/agent-hires$/ },
165
+ { method: "POST", path: /^\/api\/issues\/[^/]+\/approvals$/ },
166
+ // Approvals (request, read, comment)
167
+ { method: "GET", path: /^\/api\/approvals\/[^/]+$/ },
168
+ { method: "GET", path: /^\/api\/approvals\/[^/]+\/issues$/ },
169
+ { method: "GET", path: /^\/api\/approvals\/[^/]+\/comments$/ },
170
+ { method: "POST", path: /^\/api\/approvals\/[^/]+\/comments$/ },
171
+ { method: "POST", path: /^\/api\/companies\/[^/]+\/approvals$/ },
172
+ // Execution workspaces and runtime services (start/stop/restart dev servers)
173
+ { method: "GET", path: /^\/api\/execution-workspaces\/[^/]+$/ },
174
+ { method: "POST", path: /^\/api\/execution-workspaces\/[^/]+\/runtime-services\/(?:start|stop|restart)$/ },
175
+ // Routines (agents manage their own routines and triggers)
176
+ { method: "GET", path: /^\/api\/routines\/[^/]+$/ },
177
+ { method: "GET", path: /^\/api\/routines\/[^/]+\/runs$/ },
178
+ { method: "POST", path: /^\/api\/companies\/[^/]+\/routines$/ },
179
+ { method: "PATCH", path: /^\/api\/routines\/[^/]+$/ },
180
+ { method: "POST", path: /^\/api\/routines\/[^/]+\/run$/ },
181
+ { method: "POST", path: /^\/api\/routines\/[^/]+\/triggers$/ },
182
+ { method: "PATCH", path: /^\/api\/routine-triggers\/[^/]+$/ },
183
+ { method: "DELETE", path: /^\/api\/routine-triggers\/[^/]+$/ },
184
+ ];
185
+ // Keep the public alias for callers selecting the HTTP/2 transport.
186
+ export const HTTP2_SANDBOX_CALLBACK_BRIDGE_ROUTE_ALLOWLIST = DEFAULT_SANDBOX_CALLBACK_BRIDGE_ROUTE_ALLOWLIST;
187
+ export const DEFAULT_SANDBOX_CALLBACK_BRIDGE_HEADER_ALLOWLIST = [
188
+ "accept",
189
+ "content-type",
190
+ "if-match",
191
+ "if-none-match",
192
+ "x-paperclip-github-capability",
193
+ ];
194
+ function shellQuote(value) {
195
+ return `'${value.replace(/'/g, `'"'"'`)}'`;
196
+ }
197
+ function normalizeMethod(value) {
198
+ return typeof value === "string" && value.trim().length > 0 ? value.trim().toUpperCase() : "GET";
199
+ }
200
+ function normalizeTimeoutMs(value, fallback) {
201
+ return typeof value === "number" && Number.isFinite(value) && value > 0 ? Math.trunc(value) : fallback;
202
+ }
203
+ /**
204
+ * Race a promise against a timeout. On timeout the returned promise rejects with
205
+ * a clear error. The helper clears the timer on every settle path, so it leaks
206
+ * no `setTimeout`. The wrapped promise is not cancelable; when it never settles,
207
+ * it keeps running in the background, but the caller already moved on through
208
+ * the reject.
209
+ */
210
+ function withTimeout(promise, timeoutMs, label) {
211
+ let timer;
212
+ const timeout = new Promise((_resolve, reject) => {
213
+ timer = setTimeout(() => {
214
+ reject(new Error(`${label} timed out after ${timeoutMs}ms.`));
215
+ }, timeoutMs);
216
+ });
217
+ return Promise.race([promise, timeout]).finally(() => {
218
+ if (timer !== undefined) {
219
+ clearTimeout(timer);
220
+ }
221
+ });
222
+ }
223
+ function toBuffer(bytes) {
224
+ if (Buffer.isBuffer(bytes))
225
+ return bytes;
226
+ if (bytes instanceof ArrayBuffer)
227
+ return Buffer.from(bytes);
228
+ return Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength);
229
+ }
230
+ function buildRunnerFailureMessage(action, result) {
231
+ const stderr = result.stderr.trim();
232
+ const stdout = result.stdout.trim();
233
+ const detail = stderr || stdout;
234
+ if (result.timedOut) {
235
+ return `${action} timed out${detail ? `: ${detail}` : ""}`;
236
+ }
237
+ return `${action} failed with exit code ${result.exitCode ?? "null"}${detail ? `: ${detail}` : ""}`;
238
+ }
239
+ async function runShell(runner, cwd, script, timeoutMs, shellCommand = "sh", stdin) {
240
+ return await runner.execute({
241
+ command: shellCommand,
242
+ args: shellCommandArgs(script),
243
+ cwd,
244
+ env: {
245
+ [SANDBOX_EXEC_CHANNEL_ENV]: SANDBOX_EXEC_CHANNEL_BRIDGE,
246
+ },
247
+ timeoutMs,
248
+ stdin,
249
+ // Every command that rides this helper is bridge control-plane plumbing:
250
+ // input delivery, output read, callback relay, and queue/setup bookkeeping.
251
+ // It must run concurrently with the agent, so force it off the persistent
252
+ // session. In streamed mode the agent holds that single serialized session
253
+ // for the whole run; a control write on the same session queues behind the
254
+ // agent command that never returns — a permanent deadlock.
255
+ bypassSession: true,
256
+ });
257
+ }
258
+ function requireSuccessfulResult(action, result) {
259
+ if (!result.timedOut && result.exitCode === 0)
260
+ return result;
261
+ throw new Error(buildRunnerFailureMessage(action, result));
262
+ }
263
+ function base64Chunks(body) {
264
+ const out = [];
265
+ for (let offset = 0; offset < body.length; offset += REMOTE_WRITE_BASE64_CHUNK_SIZE) {
266
+ out.push(body.slice(offset, offset + REMOTE_WRITE_BASE64_CHUNK_SIZE));
267
+ }
268
+ return out;
269
+ }
270
+ async function pathExists(filePath) {
271
+ return await fs.stat(filePath).then(() => true).catch(() => false);
272
+ }
273
+ function buildRemotePidLockAcquireScript(lockDirExpr, timeoutMessage) {
274
+ return [
275
+ "attempts=0",
276
+ `while ! mkdir ${lockDirExpr} 2>/dev/null; do`,
277
+ " holder_pid=\"\"",
278
+ ` if [ -s ${lockDirExpr}/pid ]; then`,
279
+ ` holder_pid="$(cat ${lockDirExpr}/pid 2>/dev/null || true)"`,
280
+ " fi",
281
+ " if [ -n \"$holder_pid\" ] && ! kill -0 \"$holder_pid\" 2>/dev/null; then",
282
+ ` rm -rf ${lockDirExpr}`,
283
+ " continue",
284
+ " fi",
285
+ " attempts=$((attempts + 1))",
286
+ " if [ \"$attempts\" -ge 600 ]; then",
287
+ ` echo ${shellQuote(timeoutMessage)} >&2`,
288
+ " exit 1",
289
+ " fi",
290
+ " sleep 0.05",
291
+ "done",
292
+ `printf '%s\\n' "$$" > ${lockDirExpr}/pid`,
293
+ ];
294
+ }
295
+ function buildRemotePidLockCleanupScript(lockDirExpr, cleanupLines) {
296
+ return [
297
+ "cleanup() {",
298
+ ...cleanupLines.map((line) => ` ${line}`),
299
+ ` rm -rf ${lockDirExpr}`,
300
+ "}",
301
+ "trap cleanup EXIT INT TERM",
302
+ ];
303
+ }
304
+ export function createSandboxCallbackBridgeToken(bytes = DEFAULT_BRIDGE_TOKEN_BYTES) {
305
+ return randomBytes(bytes).toString("base64url");
306
+ }
307
+ export function authorizeSandboxCallbackBridgeRequestWithRoutes(request, routes = DEFAULT_SANDBOX_CALLBACK_BRIDGE_ROUTE_ALLOWLIST) {
308
+ const method = normalizeMethod(request.method);
309
+ return routes.some((route) => route.method === method && route.path.test(request.path))
310
+ ? null
311
+ : `Route not allowed: ${method} ${request.path}`;
312
+ }
313
+ export function sanitizeSandboxCallbackBridgeHeaders(headers, allowlist = DEFAULT_SANDBOX_CALLBACK_BRIDGE_HEADER_ALLOWLIST) {
314
+ const allowed = new Set(allowlist.map((header) => header.toLowerCase()));
315
+ return Object.fromEntries(Object.entries(headers).filter(([key]) => allowed.has(key.toLowerCase())));
316
+ }
317
+ export function sandboxCallbackBridgeDirectories(rootDir) {
318
+ return {
319
+ rootDir,
320
+ requestsDir: path.posix.join(rootDir, "requests"),
321
+ responsesDir: path.posix.join(rootDir, "responses"),
322
+ logsDir: path.posix.join(rootDir, "logs"),
323
+ readyFile: path.posix.join(rootDir, "ready.json"),
324
+ pidFile: path.posix.join(rootDir, "server.pid"),
325
+ logFile: path.posix.join(rootDir, "logs", "bridge.log"),
326
+ };
327
+ }
328
+ export function buildSandboxCallbackBridgeEnv(input) {
329
+ return {
330
+ PAPERCLIP_API_BRIDGE_MODE: SANDBOX_CALLBACK_BRIDGE_FILE_MODE,
331
+ PAPERCLIP_BRIDGE_QUEUE_DIR: input.queueDir,
332
+ PAPERCLIP_BRIDGE_TOKEN: input.bridgeToken,
333
+ PAPERCLIP_BRIDGE_HOST: input.host?.trim() || "127.0.0.1",
334
+ PAPERCLIP_BRIDGE_PORT: String(input.port && input.port > 0 ? Math.trunc(input.port) : 0),
335
+ PAPERCLIP_BRIDGE_POLL_INTERVAL_MS: String(normalizeTimeoutMs(input.pollIntervalMs, DEFAULT_BRIDGE_POLL_INTERVAL_MS)),
336
+ PAPERCLIP_BRIDGE_RESPONSE_TIMEOUT_MS: String(normalizeTimeoutMs(input.responseTimeoutMs, DEFAULT_BRIDGE_RESPONSE_TIMEOUT_MS)),
337
+ PAPERCLIP_BRIDGE_MAX_QUEUE_DEPTH: String(normalizeTimeoutMs(input.maxQueueDepth, DEFAULT_BRIDGE_MAX_QUEUE_DEPTH)),
338
+ PAPERCLIP_BRIDGE_MAX_BODY_BYTES: String(normalizeTimeoutMs(input.maxBodyBytes, DEFAULT_BRIDGE_MAX_BODY_BYTES)),
339
+ };
340
+ }
341
+ export async function createSandboxCallbackBridgeAsset() {
342
+ const localDir = await fs.mkdtemp(path.join(os.tmpdir(), "paperclip-bridge-asset-"));
343
+ const entrypoint = path.join(localDir, SANDBOX_CALLBACK_BRIDGE_ENTRYPOINT);
344
+ await fs.writeFile(entrypoint, getSandboxCallbackBridgeServerSource(), "utf8");
345
+ return {
346
+ localDir,
347
+ entrypoint,
348
+ cleanup: async () => {
349
+ await fs.rm(localDir, { recursive: true, force: true }).catch(() => undefined);
350
+ },
351
+ };
352
+ }
353
+ export function createFileSystemSandboxCallbackBridgeQueueClient() {
354
+ return {
355
+ makeDir: async (remotePath) => {
356
+ await fs.mkdir(remotePath, { recursive: true });
357
+ },
358
+ makeDirs: async (remotePaths) => {
359
+ for (const remotePath of remotePaths) {
360
+ await fs.mkdir(remotePath, { recursive: true });
361
+ }
362
+ },
363
+ listJsonFiles: async (remotePath) => {
364
+ const entries = await fs.readdir(remotePath, { withFileTypes: true }).catch(() => []);
365
+ return entries
366
+ .filter((entry) => entry.isFile() && entry.name.endsWith(".json"))
367
+ .map((entry) => entry.name)
368
+ .sort((left, right) => left.localeCompare(right));
369
+ },
370
+ fileSize: async (remotePath) => (await fs.stat(remotePath)).size,
371
+ readTextFile: async (remotePath, maxBytes) => {
372
+ if (maxBytes === undefined)
373
+ return fs.readFile(remotePath, "utf8");
374
+ const file = await fs.open(remotePath, "r");
375
+ try {
376
+ const stat = await file.stat();
377
+ if (stat.size > maxBytes)
378
+ throw new Error("Bridge envelope exceeded the configured size limit.");
379
+ const bytes = Buffer.alloc(Math.min(stat.size, maxBytes) + 1);
380
+ let length = 0;
381
+ while (length < bytes.length) {
382
+ const read = await file.read(bytes, length, bytes.length - length, length);
383
+ if (!read.bytesRead)
384
+ break;
385
+ length += read.bytesRead;
386
+ }
387
+ if (length > stat.size)
388
+ throw new Error("Bridge envelope changed while reading.");
389
+ return bytes.subarray(0, length).toString("utf8");
390
+ }
391
+ finally {
392
+ await file.close();
393
+ }
394
+ },
395
+ writeTextFile: async (remotePath, body) => {
396
+ await fs.mkdir(path.posix.dirname(remotePath), { recursive: true });
397
+ // Write to a temporary path that does NOT end in `.json`, then rename it
398
+ // onto the final `.json` path. A direct `writeFile` truncates the final
399
+ // path first, so a `.json`-only reader (the stdin poller) can see an
400
+ // empty or partial file. The atomic rename never exposes partial content.
401
+ const tempPath = `${remotePath}.paperclip-upload.decoded`;
402
+ await fs.writeFile(tempPath, body, "utf8");
403
+ await fs.rename(tempPath, remotePath);
404
+ },
405
+ writeResponseFile: async (responsePath, body, options = {}) => {
406
+ const responseDir = path.posix.dirname(responsePath);
407
+ const tempPath = `${responsePath}.tmp`;
408
+ const lockDir = `${responsePath}.paperclip-write.lock`;
409
+ const lockPidFile = `${lockDir}/pid`;
410
+ if (options.requestPath) {
411
+ const requestExists = await pathExists(options.requestPath);
412
+ if (!requestExists) {
413
+ return { wrote: false };
414
+ }
415
+ }
416
+ await fs.mkdir(responseDir, { recursive: true });
417
+ // PID-liveness mkdir-mutex: mirrors the shell-based bridge mutex so a
418
+ // crashed holder (SIGKILL / OOM) doesn't deadlock subsequent writers
419
+ // for the full timeout window.
420
+ let attempts = 0;
421
+ while (true) {
422
+ try {
423
+ await fs.mkdir(lockDir);
424
+ await fs.writeFile(lockPidFile, `${process.pid}\n`, "utf8");
425
+ break;
426
+ }
427
+ catch (error) {
428
+ const code = error?.code;
429
+ if (code !== "EEXIST") {
430
+ throw error;
431
+ }
432
+ let holderPid = null;
433
+ try {
434
+ const raw = await fs.readFile(lockPidFile, "utf8");
435
+ const parsed = Number.parseInt(raw.trim(), 10);
436
+ if (Number.isFinite(parsed) && parsed > 0)
437
+ holderPid = parsed;
438
+ }
439
+ catch {
440
+ // pid file missing or unreadable — treat as stale lock
441
+ }
442
+ let holderAlive = false;
443
+ if (holderPid !== null) {
444
+ try {
445
+ process.kill(holderPid, 0);
446
+ holderAlive = true;
447
+ }
448
+ catch {
449
+ holderAlive = false;
450
+ }
451
+ }
452
+ if (!holderAlive) {
453
+ await fs.rm(lockDir, { recursive: true, force: true }).catch(() => undefined);
454
+ continue;
455
+ }
456
+ attempts += 1;
457
+ if (attempts >= 600) {
458
+ throw new Error("Timed out acquiring sandbox callback bridge response lock.");
459
+ }
460
+ await new Promise((resolve) => setTimeout(resolve, 50));
461
+ }
462
+ }
463
+ try {
464
+ if (options.requestPath) {
465
+ const requestExists = await pathExists(options.requestPath);
466
+ if (!requestExists) {
467
+ return { wrote: false };
468
+ }
469
+ }
470
+ const responseExists = await pathExists(responsePath);
471
+ if (responseExists) {
472
+ return { wrote: false };
473
+ }
474
+ await fs.writeFile(tempPath, body, "utf8");
475
+ await fs.rename(tempPath, responsePath);
476
+ return { wrote: true };
477
+ }
478
+ finally {
479
+ await fs.rm(tempPath, { force: true }).catch(() => undefined);
480
+ await fs.rm(lockDir, { recursive: true, force: true }).catch(() => undefined);
481
+ }
482
+ },
483
+ rename: async (fromPath, toPath) => {
484
+ await fs.mkdir(path.posix.dirname(toPath), { recursive: true });
485
+ await fs.rename(fromPath, toPath);
486
+ },
487
+ remove: async (remotePath) => {
488
+ await fs.rm(remotePath, { recursive: true, force: true }).catch(() => undefined);
489
+ },
490
+ };
491
+ }
492
+ export function createCommandManagedSandboxCallbackBridgeQueueClient(input) {
493
+ const timeoutMs = normalizeTimeoutMs(input.timeoutMs, DEFAULT_BRIDGE_RESPONSE_TIMEOUT_MS);
494
+ const shellCommand = preferredShellForSandbox(input.shellCommand);
495
+ const runChecked = async (action, script) => requireSuccessfulResult(action, await runShell(input.runner, input.remoteCwd, script, timeoutMs, shellCommand));
496
+ return {
497
+ makeDir: async (remotePath) => {
498
+ await runChecked(`mkdir ${remotePath}`, `mkdir -p ${shellQuote(remotePath)}`);
499
+ },
500
+ makeDirs: async (remotePaths) => {
501
+ if (remotePaths.length === 0) {
502
+ return;
503
+ }
504
+ const quoted = remotePaths.map((remotePath) => shellQuote(remotePath));
505
+ await runChecked(`mkdir ${remotePaths.join(" ")}`, `mkdir -p ${quoted.join(" ")}`);
506
+ },
507
+ listJsonFiles: async (remotePath) => {
508
+ const result = await runShell(input.runner, input.remoteCwd, [
509
+ `if [ -d ${shellQuote(remotePath)} ]; then`,
510
+ ` for file in ${shellQuote(remotePath)}/*.json; do`,
511
+ ` [ -f "$file" ] || continue`,
512
+ " basename \"$file\"",
513
+ " done",
514
+ "fi",
515
+ ].join("\n"), timeoutMs, shellCommand);
516
+ requireSuccessfulResult(`list ${remotePath}`, result);
517
+ return result.stdout
518
+ .split(/\r?\n/)
519
+ .map((line) => line.trim())
520
+ .filter((line) => line.length > 0)
521
+ .sort((left, right) => left.localeCompare(right));
522
+ },
523
+ fileSize: async (remotePath) => {
524
+ const result = await runChecked(`size ${remotePath}`, `wc -c < ${shellQuote(remotePath)}`);
525
+ return Number(result.stdout.trim());
526
+ },
527
+ readTextFile: async (remotePath, maxBytes) => {
528
+ const command = maxBytes === undefined
529
+ ? `base64 < ${shellQuote(remotePath)}`
530
+ : `head -c ${Math.trunc(maxBytes) + 1} ${shellQuote(remotePath)} | base64`;
531
+ const result = await runChecked(`read ${remotePath}`, command);
532
+ const bytes = Buffer.from(result.stdout.replace(/\s+/g, ""), "base64");
533
+ if (maxBytes !== undefined && bytes.length > maxBytes)
534
+ throw new Error("Bridge envelope exceeded the configured size limit.");
535
+ return bytes.toString("utf8");
536
+ },
537
+ writeTextFile: async (remotePath, body) => {
538
+ const remoteDir = path.posix.dirname(remotePath);
539
+ // Two temporary paths that do NOT end in `.json`, so a `.json`-only
540
+ // reader (the stdin poller) never lists them. The base64 upload lands in
541
+ // `tempPath`. The decode result lands in `decodedPath`. An atomic rename
542
+ // then moves the complete decoded content onto the final `.json` path.
543
+ // A direct `> remotePath` redirect truncates the final path before the
544
+ // decode writes it, so a reader can see an empty or partial file.
545
+ const tempPath = `${remotePath}.paperclip-upload.b64`;
546
+ const decodedPath = `${remotePath}.paperclip-upload.decoded`;
547
+ await runChecked(`prepare upload ${remotePath}`, `mkdir -p ${shellQuote(remoteDir)} && rm -f ${shellQuote(tempPath)} ${shellQuote(decodedPath)} && : > ${shellQuote(tempPath)}`);
548
+ const base64Body = toBuffer(Buffer.from(body, "utf8")).toString("base64");
549
+ for (const chunk of base64Chunks(base64Body)) {
550
+ await runChecked(`append upload chunk ${remotePath}`, `printf '%s' ${shellQuote(chunk)} >> ${shellQuote(tempPath)}`);
551
+ }
552
+ await runChecked(`finalize upload ${remotePath}`, `base64 -d < ${shellQuote(tempPath)} > ${shellQuote(decodedPath)} && mv ${shellQuote(decodedPath)} ${shellQuote(remotePath)} && rm -f ${shellQuote(tempPath)}`);
553
+ },
554
+ writeResponseFile: async (responsePath, body, options = {}) => {
555
+ const responseDir = path.posix.dirname(responsePath);
556
+ const tempPath = `${responsePath}.tmp`;
557
+ const lockDir = `${responsePath}.paperclip-write.lock`;
558
+ const requestPath = options.requestPath?.trim() || "";
559
+ const result = await runShell(input.runner, input.remoteCwd, [
560
+ "set -eu",
561
+ `response_dir=${shellQuote(responseDir)}`,
562
+ `response_path=${shellQuote(responsePath)}`,
563
+ `temp_path=${shellQuote(tempPath)}`,
564
+ `lock_dir=${shellQuote(lockDir)}`,
565
+ `request_path=${shellQuote(requestPath)}`,
566
+ "mkdir -p \"$response_dir\"",
567
+ ...buildRemotePidLockAcquireScript("\"$lock_dir\"", "Timed out acquiring sandbox callback bridge response lock."),
568
+ ...buildRemotePidLockCleanupScript("\"$lock_dir\"", [
569
+ "rm -f \"$temp_path\"",
570
+ ]),
571
+ "if [ -n \"$request_path\" ] && [ ! -f \"$request_path\" ]; then",
572
+ " printf '{\"wrote\":false}\\n'",
573
+ " exit 0",
574
+ "fi",
575
+ "if [ -f \"$response_path\" ]; then",
576
+ " printf '{\"wrote\":false}\\n'",
577
+ " exit 0",
578
+ "fi",
579
+ "cat > \"$temp_path\"",
580
+ "mv \"$temp_path\" \"$response_path\"",
581
+ "printf '{\"wrote\":true}\\n'",
582
+ ].join("\n"), timeoutMs, shellCommand, body);
583
+ requireSuccessfulResult(`write bridge response ${responsePath}`, result);
584
+ try {
585
+ return {
586
+ wrote: JSON.parse(result.stdout.trim())?.wrote === true,
587
+ };
588
+ }
589
+ catch (error) {
590
+ throw new Error(`Sandbox callback bridge response write wrote invalid result JSON: ${error instanceof Error ? error.message : String(error)}`);
591
+ }
592
+ },
593
+ rename: async (fromPath, toPath) => {
594
+ await runChecked(`rename ${fromPath}`, `mkdir -p ${shellQuote(path.posix.dirname(toPath))} && mv ${shellQuote(fromPath)} ${shellQuote(toPath)}`);
595
+ },
596
+ remove: async (remotePath) => {
597
+ await runChecked(`remove ${remotePath}`, `rm -rf ${shellQuote(remotePath)}`);
598
+ },
599
+ };
600
+ }
601
+ async function writeBridgeResponse(client, requestPath, responsePath, response, options = {}) {
602
+ const body = `${JSON.stringify(response)}\n`;
603
+ if (client.writeResponseFile) {
604
+ await client.writeResponseFile(responsePath, body, options.requireRequestPath === false ? {} : { requestPath });
605
+ return;
606
+ }
607
+ const tempPath = `${responsePath}.tmp`;
608
+ await client.writeTextFile(tempPath, body);
609
+ await client.rename(tempPath, responsePath);
610
+ }
611
+ export async function startSandboxCallbackBridgeWorker(input) {
612
+ const pollIntervalMs = normalizeTimeoutMs(input.pollIntervalMs, DEFAULT_BRIDGE_POLL_INTERVAL_MS);
613
+ const iterationTimeoutMs = normalizeTimeoutMs(input.iterationTimeoutMs, DEFAULT_BRIDGE_ITERATION_TIMEOUT_MS);
614
+ const watchdogTimeoutMs = normalizeTimeoutMs(input.watchdogTimeoutMs, DEFAULT_BRIDGE_WATCHDOG_TIMEOUT_MS);
615
+ const abortedHandlerGraceMs = normalizeTimeoutMs(input.abortedHandlerGraceMs, DEFAULT_BRIDGE_ABORTED_HANDLER_GRACE_MS);
616
+ const maxBodyBytes = normalizeTimeoutMs(input.maxBodyBytes, DEFAULT_BRIDGE_MAX_BODY_BYTES);
617
+ const maxEnvelopeBytes = sandboxBridgeEnvelopeLimit(maxBodyBytes);
618
+ // Load lazily to avoid the HTTP/2 module's constants depending on this module
619
+ // during initialization. Both transports share the host process memory ceiling.
620
+ const { createBridgeBodyReservation } = await import("./http2-bridge-server.js");
621
+ const directories = sandboxCallbackBridgeDirectories(input.queueDir);
622
+ const queueDirectories = [
623
+ directories.rootDir,
624
+ directories.requestsDir,
625
+ directories.responsesDir,
626
+ directories.logsDir,
627
+ ];
628
+ if (input.client.makeDirs) {
629
+ await input.client.makeDirs(queueDirectories);
630
+ }
631
+ else {
632
+ // Backward-compatible fallback for a queue client that omits the batched
633
+ // makeDirs method. Create each queue directory with a single makeDir.
634
+ for (const directory of queueDirectories) {
635
+ await input.client.makeDir(directory);
636
+ }
637
+ }
638
+ let stopping = false;
639
+ let inFlight = 0;
640
+ let settled = false;
641
+ let stopDeadline = Number.POSITIVE_INFINITY;
642
+ let settleResolve = null;
643
+ const settledPromise = new Promise((resolve) => {
644
+ settleResolve = resolve;
645
+ });
646
+ const authorizeRequest = input.authorizeRequest ??
647
+ ((request) => authorizeSandboxCallbackBridgeRequestWithRoutes(request));
648
+ const buildWorkerFailureMessage = (error) => `Sandbox callback bridge worker failed: ${error instanceof Error ? error.message : String(error)}`;
649
+ const inFlightRequestGuards = new Map();
650
+ const processRequestFile = async (fileName) => {
651
+ // Skip a request that already has an active attempt. The guard map holds only
652
+ // in-flight attempts; the attempt's finally removes its guard when it ends. A
653
+ // file that still has a guard is in flight, or it waits for its aborted-handler
654
+ // 504 backstop. A second attempt would register a new guard and re-run the host
655
+ // mutation, so the mutation could apply twice.
656
+ if (inFlightRequestGuards.has(fileName)) {
657
+ return;
658
+ }
659
+ const requestPath = path.posix.join(directories.requestsDir, fileName);
660
+ const responsePath = path.posix.join(directories.responsesDir, fileName);
661
+ const guard = {
662
+ claim: "unclaimed",
663
+ controller: new AbortController(),
664
+ finalized: false,
665
+ };
666
+ inFlightRequestGuards.set(fileName, guard);
667
+ const reservation = createBridgeBodyReservation();
668
+ const envelopeReadReservation = createBridgeBodyReservation();
669
+ // Claim the request for the handler. Return `false` when the recovery path
670
+ // already claimed it; the caller must then not run the mutation and must not
671
+ // write a response, because the recovery path writes a 503 and the caller
672
+ // may retry.
673
+ const claimForHandler = () => {
674
+ if (guard.claim === "abandon") {
675
+ return false;
676
+ }
677
+ guard.claim = "handler";
678
+ return true;
679
+ };
680
+ // Finalize the request exactly once. Claim it for the handler first. When the
681
+ // recovery path already won the claim, skip both the write and the remove.
682
+ // The `finalized` fence stops a double write when the backstop timer already
683
+ // wrote a 504 for a handler the recovery path aborted. The handler wins when
684
+ // it settles inside the grace; the backstop wins when the handler never
685
+ // settles.
686
+ const finalize = async (response) => {
687
+ if (!claimForHandler()) {
688
+ return;
689
+ }
690
+ if (guard.finalized) {
691
+ return;
692
+ }
693
+ guard.finalized = true;
694
+ // This finalize now owns delivery for the request, so drop a pending
695
+ // backstop timer. The handler settled inside the grace, so the backstop no
696
+ // longer needs to wait; `finalize` delivers the terminal response itself,
697
+ // inline, and never leaves the request file for a detached timer that the
698
+ // busy poll loop could starve.
699
+ if (guard.backstopTimer !== undefined) {
700
+ clearTimeout(guard.backstopTimer);
701
+ guard.backstopTimer = undefined;
702
+ }
703
+ // Write the handler response, bounded by the per-iteration timeout so a
704
+ // hung sandbox channel never strands the caller until its own generic
705
+ // deadline. Retry a transient write failure, exactly like the 504 backstop
706
+ // write.
707
+ let lastWriteError = "Sandbox callback bridge could not write the handler response.";
708
+ for (let attempt = 1; attempt <= MAX_BACKSTOP_WRITE_ATTEMPTS; attempt += 1) {
709
+ try {
710
+ await withTimeout(writeBridgeResponse(input.client, requestPath, responsePath, response), iterationTimeoutMs, `Sandbox callback bridge write response for ${response.id}`);
711
+ await input.client.remove(requestPath).catch(() => undefined);
712
+ return;
713
+ }
714
+ catch (error) {
715
+ lastWriteError = error instanceof Error ? error.message : String(error);
716
+ console.warn(`[paperclip] sandbox callback bridge failed to write response for ${response.id} (attempt ${attempt}/${MAX_BACKSTOP_WRITE_ATTEMPTS}): ${lastWriteError}`);
717
+ if (attempt < MAX_BACKSTOP_WRITE_ATTEMPTS) {
718
+ await new Promise((resolve) => setTimeout(resolve, BACKSTOP_WRITE_RETRY_MS));
719
+ }
720
+ }
721
+ }
722
+ // Every handler-response write failed. Deliver a non-retryable 504 backstop
723
+ // inline, so the caller gets a terminal response instead of a retryable 503
724
+ // that repeats a possibly-committed mutation, or a strand until its own
725
+ // deadline. Roll the `finalized` fence back so `writeAbortedHandlerBackstop`
726
+ // can proceed; it re-fences, retries the 504 write, and removes the request
727
+ // file. Await it, so the request file does not linger for the poll loop
728
+ // while the loop still runs.
729
+ guard.finalized = false;
730
+ await writeAbortedHandlerBackstop(fileName, guard, lastWriteError);
731
+ };
732
+ try {
733
+ // Bound the read and its encoded/parsed copies before allocating. Built-in
734
+ // clients stat first so a high configured file limit does not reserve that
735
+ // whole limit for a tiny request. Older clients use the conservative cap.
736
+ const envelopeBytes = input.client.fileSize
737
+ ? await input.client.fileSize(requestPath).catch(() => maxEnvelopeBytes)
738
+ : maxEnvelopeBytes;
739
+ if (envelopeBytes > maxEnvelopeBytes) {
740
+ await finalize({
741
+ id: fileName.replace(/\.json$/i, ""), status: 413,
742
+ headers: { "content-type": "application/json" },
743
+ body: JSON.stringify({ error: "Bridge request envelope exceeded the configured size limit." }),
744
+ completedAt: new Date().toISOString(),
745
+ });
746
+ return;
747
+ }
748
+ const readLimit = Number.isSafeInteger(envelopeBytes) && envelopeBytes >= 0
749
+ ? Math.min(envelopeBytes, maxEnvelopeBytes) : maxEnvelopeBytes;
750
+ if (!envelopeReadReservation.reserve(6 * readLimit)) {
751
+ await finalize({ id: fileName.replace(/\.json$/i, ""), status: 503,
752
+ headers: { "content-type": "application/json" },
753
+ body: JSON.stringify({ error: "Bridge host body capacity is busy. Retry later." }),
754
+ completedAt: new Date().toISOString() });
755
+ return;
756
+ }
757
+ let raw;
758
+ try {
759
+ raw = await input.client.readTextFile(requestPath, readLimit);
760
+ }
761
+ catch (error) {
762
+ // The gateway deletes a request file when its caller stops waiting
763
+ // (client-side timeout cleanup). A read that fails because the file is
764
+ // gone is that benign race, not a channel fault: confirm the file
765
+ // vanished and skip quietly instead of escalating into a recovery
766
+ // pass. A file that is still listed rethrows, so a real read fault
767
+ // keeps its existing handling.
768
+ const remaining = await input.client.listJsonFiles(directories.requestsDir).catch(() => null);
769
+ if (remaining !== null && !remaining.includes(fileName)) {
770
+ return;
771
+ }
772
+ throw error;
773
+ }
774
+ let request;
775
+ try {
776
+ if (Buffer.byteLength(raw) > maxEnvelopeBytes)
777
+ throw new Error("Bridge envelope too large");
778
+ request = JSON.parse(raw);
779
+ decodeSandboxBridgeBody(request, maxBodyBytes);
780
+ }
781
+ catch {
782
+ const requestId = fileName.replace(/\.json$/i, "") || randomUUID();
783
+ await finalize({
784
+ id: requestId,
785
+ status: 400,
786
+ headers: { "content-type": "application/json" },
787
+ body: JSON.stringify({ error: "Invalid bridge request payload." }),
788
+ completedAt: new Date().toISOString(),
789
+ });
790
+ return;
791
+ }
792
+ // Keep only the actual request allocation reserved while forwarding;
793
+ // an abandoned small request must not retain a maximum-sized reservation.
794
+ envelopeReadReservation.release();
795
+ if (!reservation.reserve(4 * Buffer.byteLength(raw) + 2 * Buffer.byteLength(request.body))) {
796
+ await finalize({ id: request.id, status: 503,
797
+ headers: { "content-type": "application/json" },
798
+ body: JSON.stringify({ error: "Bridge host body capacity is busy. Retry later." }),
799
+ completedAt: new Date().toISOString() });
800
+ return;
801
+ }
802
+ const denialReason = await authorizeRequest(request);
803
+ if (denialReason) {
804
+ await finalize({
805
+ id: request.id,
806
+ status: 403,
807
+ headers: { "content-type": "application/json" },
808
+ body: JSON.stringify({ error: denialReason }),
809
+ completedAt: new Date().toISOString(),
810
+ });
811
+ return;
812
+ }
813
+ // Claim the request for the handler before the host operation starts. When
814
+ // the recovery path already claimed it, it writes a 503 and the caller may
815
+ // retry, so do not run the mutation; the retry then applies it once. When
816
+ // the handler claims first, the recovery path leaves the request alone and
817
+ // the handler writes the real response.
818
+ if (!claimForHandler()) {
819
+ return;
820
+ }
821
+ // Build the response, then finalize once. The handler already holds the
822
+ // claim, so `finalize` writes the real response.
823
+ let response;
824
+ let handlerReturned = false;
825
+ try {
826
+ const { bodyEncoding, ...forwardRequest } = request;
827
+ const result = await input.handleRequest({ ...forwardRequest,
828
+ body: bodyEncoding === "base64" ? decodeSandboxBridgeBody(request, maxBodyBytes) : request.body,
829
+ }, { signal: guard.controller.signal, reservation });
830
+ handlerReturned = true;
831
+ const responseBytes = Buffer.byteLength(result.body ?? "");
832
+ if (responseBytes > maxBodyBytes)
833
+ throw new Error("Bridge response body exceeded the configured size limit.");
834
+ if (!reservation.reserve(4 * sandboxBridgeEnvelopeLimit(responseBytes))) {
835
+ throw new Error("Bridge host response body capacity is busy.");
836
+ }
837
+ const responseBody = encodeSandboxBridgeBody(result.body ?? "", maxBodyBytes);
838
+ response = {
839
+ id: request.id,
840
+ status: result.status,
841
+ headers: result.headers ?? {},
842
+ ...responseBody,
843
+ completedAt: new Date().toISOString(),
844
+ };
845
+ }
846
+ catch (error) {
847
+ console.warn(`[paperclip] sandbox callback bridge handler failed for ${request.id}: ${error instanceof Error ? error.message : String(error)}`);
848
+ // Tell a worker abort apart from a normal handler failure. The recovery
849
+ // path aborts `guard.controller` when the per-iteration timeout or the
850
+ // watchdog fires. The abort reaches this catch only after the handler
851
+ // claimed the request and started the host operation. The bridge cannot
852
+ // cancel a host operation that is in flight, so the mutation may have
853
+ // committed. A 502 (or 503) is a retryable status: the caller retries it
854
+ // and applies the mutation twice. So return a non-retryable 504 and mark
855
+ // the outcome indeterminate. The caller must not retry a 504 from the
856
+ // bridge, unlike the retry-safe 503 that the recovery path writes only
857
+ // before the host operation starts.
858
+ if (guard.controller.signal.aborted || (handlerReturned && !["GET", "HEAD", "OPTIONS", "TRACE"].includes(request.method))) {
859
+ response = {
860
+ id: request.id,
861
+ status: 504,
862
+ headers: {
863
+ "content-type": "application/json",
864
+ "x-paperclip-bridge-outcome": "indeterminate",
865
+ },
866
+ body: JSON.stringify({
867
+ error: error instanceof Error ? error.message : String(error),
868
+ outcome: "indeterminate",
869
+ retryable: false,
870
+ }),
871
+ completedAt: new Date().toISOString(),
872
+ };
873
+ }
874
+ else {
875
+ response = {
876
+ id: request.id,
877
+ status: 502,
878
+ headers: { "content-type": "application/json" },
879
+ body: JSON.stringify({
880
+ error: error instanceof Error ? error.message : String(error),
881
+ }),
882
+ completedAt: new Date().toISOString(),
883
+ };
884
+ }
885
+ }
886
+ await finalize(response);
887
+ }
888
+ finally {
889
+ envelopeReadReservation.release();
890
+ reservation.release();
891
+ // Drop the guard only when it still points to this attempt. A retry can
892
+ // register a new attempt under the same file name; that new guard must
893
+ // stay in the map. Keep the guard when a backstop is still pending: a
894
+ // failed terminal write re-arms the backstop and keeps the request file,
895
+ // so the guard must stay in the map. The poll loop then skips the file and
896
+ // does not re-run a possibly-committed mutation before the backstop writes
897
+ // its 504.
898
+ if (guard.backstopTimer === undefined && inFlightRequestGuards.get(fileName) === guard) {
899
+ inFlightRequestGuards.delete(fileName);
900
+ }
901
+ }
902
+ };
903
+ // Write the non-retryable 504 backstop for an aborted handler that did not
904
+ // finalize inside the grace. The `finalized` fence makes this a no-op when the
905
+ // handler already wrote its own response. The request file name is the request
906
+ // id plus `.json`, so derive the id from it without another client read that
907
+ // could hang on the same dead channel.
908
+ const writeAbortedHandlerBackstop = async (fileName, guard, message) => {
909
+ guard.backstopTimer = undefined;
910
+ if (guard.finalized) {
911
+ return;
912
+ }
913
+ guard.finalized = true;
914
+ const requestPath = path.posix.join(directories.requestsDir, fileName);
915
+ const responsePath = path.posix.join(directories.responsesDir, fileName);
916
+ const requestId = fileName.replace(/\.json$/i, "") || randomUUID();
917
+ for (let attempt = 1; attempt <= MAX_BACKSTOP_WRITE_ATTEMPTS; attempt += 1) {
918
+ try {
919
+ await withTimeout(writeBridgeResponse(input.client, requestPath, responsePath, {
920
+ id: requestId,
921
+ status: 504,
922
+ headers: {
923
+ "content-type": "application/json",
924
+ "x-paperclip-bridge-outcome": "indeterminate",
925
+ },
926
+ body: JSON.stringify({ error: message, outcome: "indeterminate", retryable: false }),
927
+ completedAt: new Date().toISOString(),
928
+ }, {
929
+ requireRequestPath: false,
930
+ }), iterationTimeoutMs, `Sandbox callback bridge write 504 backstop for ${requestId}`);
931
+ // The 504 backstop reached the caller. Remove the request file, so the
932
+ // poll loop does not list it again and re-run the mutation.
933
+ await input.client.remove(requestPath).catch(() => undefined);
934
+ return;
935
+ }
936
+ catch (error) {
937
+ console.warn(`[paperclip] sandbox callback bridge failed to write 504 backstop for ${requestId} (attempt ${attempt}/${MAX_BACKSTOP_WRITE_ATTEMPTS}): ${error instanceof Error ? error.message : String(error)}`);
938
+ if (attempt < MAX_BACKSTOP_WRITE_ATTEMPTS) {
939
+ await new Promise((resolve) => setTimeout(resolve, BACKSTOP_WRITE_RETRY_MS));
940
+ }
941
+ }
942
+ }
943
+ // Every backstop write failed. Keep the request file and clear the fence, so a
944
+ // late handler can still finalize its own 504. The guard stays in the map, so
945
+ // the poll loop skips the file and does not re-run the mutation. A removed
946
+ // file plus a set fence would strand the caller until its own deadline and
947
+ // give it a generic 502 instead of the terminal 504.
948
+ //
949
+ // Re-arm the backstop directly. A stuck handler never settles, so its
950
+ // `processRequestFile` never runs the `finally` that drops the guard. The
951
+ // poll loop then skips the file on each iteration, so every iteration
952
+ // succeeds and the watchdog never trips again. No later recovery pass runs,
953
+ // so a re-arm here is the only path that retries the 504 write. Clear the
954
+ // fence before the re-arm, because `scheduleAbortedHandlerBackstop` bails on
955
+ // a set fence. The re-arm only re-writes the 504 response; it never re-runs
956
+ // the mutation, so a retry cannot apply the mutation twice.
957
+ guard.finalized = false;
958
+ scheduleAbortedHandlerBackstop(fileName, guard, message);
959
+ };
960
+ // Arm the backstop timer for a handler the recovery path just aborted. It is
961
+ // idempotent: a second recovery pass (the watchdog and the loop catch both run
962
+ // `failPendingRequests`) does not re-arm a live timer or one that already
963
+ // finalized.
964
+ const scheduleAbortedHandlerBackstop = (fileName, guard, message) => {
965
+ if (guard.finalized || guard.backstopTimer !== undefined) {
966
+ return;
967
+ }
968
+ guard.backstopTimer = setTimeout(() => {
969
+ void writeAbortedHandlerBackstop(fileName, guard, message);
970
+ }, abortedHandlerGraceMs);
971
+ if (typeof guard.backstopTimer.unref === "function") {
972
+ guard.backstopTimer.unref();
973
+ }
974
+ };
975
+ // Abort every queued request with a 503. The `abandonInFlight` option controls
976
+ // the completion fence for a request a `processRequestFile` attempt still owns.
977
+ // The timeout and watchdog recovery pass `true`: the loop already gave up on
978
+ // the request. When the handler did not yet start the host operation, claim the
979
+ // request so a later handler claim bails, then write the 503. When the handler
980
+ // already started, skip the 503; the recovery cannot cancel an in-flight host
981
+ // operation, and a 503 there would make the caller retry and apply the mutation
982
+ // twice. The stop drain passes `false` (the default): a request the loop
983
+ // already picked up keeps its normal completion, so a late handler result still
984
+ // wins over the drain 503, exactly like the earlier stop behavior.
985
+ const failPendingRequests = async (message, options = {}) => {
986
+ if (options.abandonInFlight) {
987
+ // Abort every in-flight handler first, then arm its 504 backstop. The loop
988
+ // already gave up on the request. A handler that threads the signal into
989
+ // its work stops, rejects, and finalizes with its own error response inside
990
+ // the grace, so the request does not strand. A handler that ignores the
991
+ // signal and never settles does not finalize inside the grace; the backstop
992
+ // timer then writes a non-retryable 504, so the request still never
993
+ // strands. This reads the guard map directly, so it runs even when the
994
+ // request listing below fails on the same dead channel. It never writes a
995
+ // 503 for a handler-owned request: the recovery cannot cancel a committed
996
+ // host mutation, so a retryable status there could apply the mutation twice.
997
+ for (const [fileName, guard] of inFlightRequestGuards.entries()) {
998
+ if (guard.claim === "handler") {
999
+ guard.controller.abort(new Error(message));
1000
+ scheduleAbortedHandlerBackstop(fileName, guard, message);
1001
+ }
1002
+ }
1003
+ }
1004
+ // Wrap each client call in the per-iteration timeout. When the sandbox
1005
+ // channel is unresponsive, a client call hangs with no reject. The timeout
1006
+ // keeps this recovery path fail-fast, so it never re-hangs on the same dead
1007
+ // channel that triggered the recovery.
1008
+ const fileNames = await withTimeout(input.client.listJsonFiles(directories.requestsDir), iterationTimeoutMs, "Sandbox callback bridge list pending requests").catch(() => []);
1009
+ for (const fileName of fileNames) {
1010
+ const guard = inFlightRequestGuards.get(fileName);
1011
+ if (guard && guard.claim === "handler" && (options.abandonInFlight || guard.controller.signal.aborted)) {
1012
+ // The handler already started this request's host operation, or it already
1013
+ // finalized the request. The timeout and watchdog cannot cancel a host
1014
+ // operation that is in flight. A competing 503 here makes the caller retry
1015
+ // while the original mutation still completes, so the mutation applies
1016
+ // twice. Leave the request for the handler to finalize, or for the 504
1017
+ // backstop to finalize when the handler never settles. The recovery path
1018
+ // reaches this skip through `abandonInFlight`. The stop drain reaches it
1019
+ // only when the recovery path already aborted the handler, so a request
1020
+ // whose 504 backstop write failed and kept its file never gets a competing
1021
+ // 503 on stop. A normal in-flight handler at a graceful stop is not
1022
+ // aborted, so it still gets the stop drain 503.
1023
+ continue;
1024
+ }
1025
+ if (options.abandonInFlight && guard) {
1026
+ // The handler did not start the host operation yet. Claim the request, so
1027
+ // the handler bails at its host-operation claim instead of running the
1028
+ // mutation. A retry after the 503 then applies the mutation once.
1029
+ guard.claim = "abandon";
1030
+ }
1031
+ const requestPath = path.posix.join(directories.requestsDir, fileName);
1032
+ const responsePath = path.posix.join(directories.responsesDir, fileName);
1033
+ const requestId = fileName.replace(/\.json$/i, "") || randomUUID();
1034
+ let responseId = requestId;
1035
+ try {
1036
+ const raw = await withTimeout(input.client.readTextFile(requestPath), iterationTimeoutMs, `Sandbox callback bridge read pending request ${requestId}`);
1037
+ const parsed = JSON.parse(raw);
1038
+ if (typeof parsed.id === "string" && parsed.id.length > 0) {
1039
+ responseId = parsed.id;
1040
+ }
1041
+ }
1042
+ catch (error) {
1043
+ // The read or the parse failed, most likely on the same dead channel that
1044
+ // triggered this recovery. Keep the request file, so a later recovery pass
1045
+ // can still read it and deliver a terminal 503. A remove here drops the
1046
+ // request and strands the caller until its own deadline.
1047
+ console.warn(`[paperclip] sandbox callback bridge could not read pending request ${requestId}: ${error instanceof Error ? error.message : String(error)}`);
1048
+ continue;
1049
+ }
1050
+ // Write the 503 first, then remove the request file only after the write
1051
+ // lands. Retry a transient failure, bounded by the per-iteration timeout,
1052
+ // exactly like the finalize and 504 backstop writes. When every attempt
1053
+ // fails, keep the request file. A later recovery pass, or the caller retry,
1054
+ // then still finds the queued request and delivers a terminal 503, instead
1055
+ // of a silent drop that strands the caller until its own deadline. The
1056
+ // request is unclaimed or abandoned, so its host mutation never ran; a later
1057
+ // 503 stays exactly-once.
1058
+ let wrote503 = false;
1059
+ let lastWriteError = "Sandbox callback bridge could not write the recovery 503.";
1060
+ for (let attempt = 1; attempt <= MAX_BACKSTOP_WRITE_ATTEMPTS; attempt += 1) {
1061
+ try {
1062
+ await withTimeout(writeBridgeResponse(input.client, requestPath, responsePath, {
1063
+ id: responseId,
1064
+ status: 503,
1065
+ headers: { "content-type": "application/json" },
1066
+ body: JSON.stringify({ error: message }),
1067
+ completedAt: new Date().toISOString(),
1068
+ }, {
1069
+ requireRequestPath: false,
1070
+ }), iterationTimeoutMs, `Sandbox callback bridge write 503 for ${requestId}`);
1071
+ wrote503 = true;
1072
+ break;
1073
+ }
1074
+ catch (error) {
1075
+ lastWriteError = error instanceof Error ? error.message : String(error);
1076
+ console.warn(`[paperclip] sandbox callback bridge failed to write recovery 503 for ${requestId} (attempt ${attempt}/${MAX_BACKSTOP_WRITE_ATTEMPTS}): ${lastWriteError}`);
1077
+ if (attempt < MAX_BACKSTOP_WRITE_ATTEMPTS) {
1078
+ await new Promise((resolve) => setTimeout(resolve, BACKSTOP_WRITE_RETRY_MS));
1079
+ }
1080
+ }
1081
+ }
1082
+ if (wrote503) {
1083
+ // The 503 landed. Remove the request file, so the poll loop does not
1084
+ // re-process it.
1085
+ await input.client.remove(requestPath).catch(() => undefined);
1086
+ }
1087
+ else {
1088
+ // Every 503 write failed. Keep the request file for a later recovery pass.
1089
+ console.warn(`[paperclip] sandbox callback bridge kept queued request ${requestId} after every recovery 503 write failed: ${lastWriteError}`);
1090
+ }
1091
+ }
1092
+ };
1093
+ // Surface a bridge-worker failure through the run trace, not only stdout. A
1094
+ // failed span under `input.runtimeSpan` records the error against the live run
1095
+ // span, so the run and the orchestrator see the hang. When no `runtimeSpan`
1096
+ // runner is wired (no injected tracer), the helper still writes a warn line,
1097
+ // so the failure is never silent.
1098
+ const surfaceRunError = async (error) => {
1099
+ if (input.runtimeSpan) {
1100
+ try {
1101
+ await input.runtimeSpan(CALLBACK_BRIDGE_WORKER_FAILED_SPAN, async () => {
1102
+ throw error;
1103
+ });
1104
+ }
1105
+ catch {
1106
+ // `runtimeSpan` re-throws after it records the failed span. The error is
1107
+ // now on the trace; swallow it here so the worker recovery continues.
1108
+ }
1109
+ }
1110
+ console.warn(`[paperclip] ${error.message}`);
1111
+ };
1112
+ // The timestamp of the last successful loop iteration. The watchdog compares
1113
+ // it to the current time. The idle branch and every processed request update
1114
+ // it, so steady progress keeps the watchdog re-armed.
1115
+ let lastSuccessfulIterationAt = Date.now();
1116
+ let watchdogTrippedAt = null;
1117
+ let watchdogTripInFlight = false;
1118
+ // Check often enough to fire soon after the threshold, but not so often that
1119
+ // the check adds load. One fifth of the threshold, with a 10ms floor.
1120
+ const watchdogCheckIntervalMs = Math.max(10, Math.floor(watchdogTimeoutMs / 5));
1121
+ const handleWatchdogTrip = async (idleMs) => {
1122
+ const message = `Sandbox callback bridge made no successful poll iteration for ${idleMs}ms; the sandbox connection is unresponsive.`;
1123
+ await surfaceRunError(new Error(message));
1124
+ try {
1125
+ await failPendingRequests(message, { abandonInFlight: true });
1126
+ }
1127
+ catch (error) {
1128
+ console.warn(`[paperclip] sandbox callback bridge watchdog failed to abort queued requests: ${error instanceof Error ? error.message : String(error)}`);
1129
+ }
1130
+ };
1131
+ // Start the long-lived poll loop outside the measured startup-step store.
1132
+ // The `makeDir` calls above are startup work and must keep the active
1133
+ // `bridge.paperclip` step. The loop runs run-time execs for the whole run,
1134
+ // so each loop `sandbox.exec` span must not parent to the ended step or copy
1135
+ // its `criticalPath` flag. `runWithoutActiveStep` empties the store for the
1136
+ // loop only; Node keeps the empty store on every later poll continuation.
1137
+ const loop = runWithoutActiveStep(() => (async () => {
1138
+ // The watchdog runs on its own timer, so it fires even while the loop is
1139
+ // stuck on an awaited client call. It is the backstop for a hang the
1140
+ // per-iteration timeout does not catch. `unref` keeps it from holding the
1141
+ // process open. The loop `finally` clears it on every exit.
1142
+ const watchdogTimer = setInterval(() => {
1143
+ if (settled || stopping)
1144
+ return;
1145
+ const idleMs = Date.now() - lastSuccessfulIterationAt;
1146
+ if (idleMs < watchdogTimeoutMs)
1147
+ return;
1148
+ // Fire once per hang period. Re-arm only after the loop advances
1149
+ // `lastSuccessfulIterationAt` past the last trip (a new successful
1150
+ // iteration), so a persistent hang never fires the watchdog repeatedly.
1151
+ if (watchdogTrippedAt !== null && watchdogTrippedAt >= lastSuccessfulIterationAt)
1152
+ return;
1153
+ if (watchdogTripInFlight)
1154
+ return;
1155
+ watchdogTrippedAt = Date.now();
1156
+ watchdogTripInFlight = true;
1157
+ void handleWatchdogTrip(idleMs).finally(() => {
1158
+ watchdogTripInFlight = false;
1159
+ });
1160
+ }, watchdogCheckIntervalMs);
1161
+ if (typeof watchdogTimer.unref === "function") {
1162
+ watchdogTimer.unref();
1163
+ }
1164
+ try {
1165
+ // Consecutive transient poll failures. A single failed list call — one
1166
+ // reset or slow sandbox exec — must not end the relay for the rest of the
1167
+ // run: the in-sandbox gateway keeps queueing requests, so a dead loop
1168
+ // strands every later API call from the agent (its status writes then look
1169
+ // like connection failures and the issue loses its disposition). Back off
1170
+ // and retry the poll instead. The watchdog stays the escalation path for a
1171
+ // sustained outage — it fires after `watchdogTimeoutMs` without a
1172
+ // successful iteration and fails the queued requests fast, while this loop
1173
+ // keeps probing for recovery.
1174
+ let consecutivePollFailures = 0;
1175
+ while (true) {
1176
+ let fileNames;
1177
+ try {
1178
+ fileNames = await withTimeout(input.client.listJsonFiles(directories.requestsDir), iterationTimeoutMs, "Sandbox callback bridge list requests");
1179
+ consecutivePollFailures = 0;
1180
+ }
1181
+ catch (error) {
1182
+ if (stopping) {
1183
+ break;
1184
+ }
1185
+ consecutivePollFailures += 1;
1186
+ const message = `${buildWorkerFailureMessage(error)} (transient poll failure ${consecutivePollFailures}; retrying)`;
1187
+ if (consecutivePollFailures === 1) {
1188
+ // Put the first failure of a streak on the run trace; later repeats
1189
+ // only warn, so a flapping channel does not spam failed spans.
1190
+ await surfaceRunError(new Error(message));
1191
+ }
1192
+ else {
1193
+ console.warn(`[paperclip] ${message}`);
1194
+ }
1195
+ const backoffMs = Math.min(pollIntervalMs * 2 ** consecutivePollFailures, MAX_TRANSIENT_ITERATION_BACKOFF_MS);
1196
+ await new Promise((resolve) => setTimeout(resolve, backoffMs));
1197
+ continue;
1198
+ }
1199
+ // A file whose attempt is still in flight (or waiting on its 504
1200
+ // backstop) is not actionable: `processRequestFile` would skip it via
1201
+ // the guard map. Treat an all-guarded listing like an empty one and
1202
+ // sleep a poll interval. Re-listing immediately would spin the loop —
1203
+ // an exec storm against a real sandbox channel, and with an in-memory
1204
+ // client a pure-microtask loop that starves every timer in the process
1205
+ // (including the guard's own backstop and abort timers).
1206
+ const actionableFileNames = fileNames.filter((fileName) => !inFlightRequestGuards.has(fileName));
1207
+ if (actionableFileNames.length === 0) {
1208
+ lastSuccessfulIterationAt = Date.now();
1209
+ if (stopping) {
1210
+ break;
1211
+ }
1212
+ await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
1213
+ continue;
1214
+ }
1215
+ for (const fileName of actionableFileNames) {
1216
+ if (stopping && Date.now() >= stopDeadline)
1217
+ break;
1218
+ inFlight += 1;
1219
+ try {
1220
+ // A request is run-time work, not startup work. Wrap it in a
1221
+ // `sandbox.callbackBridge.relayRequest` span, so its read, write, and
1222
+ // remove execs group under one named span that parents to the live
1223
+ // run span. The span runner reads the run parent per request: the
1224
+ // live parent switches to `agent.turn` during the turn and back to
1225
+ // `task.run` after it. Without a runner, the request runs under the
1226
+ // run parent with no wrapper span, exactly like the earlier behavior.
1227
+ // The per-iteration timeout wraps the whole request, so a hung
1228
+ // request rejects and the catch below runs the recovery pass.
1229
+ await withTimeout(input.runtimeSpan
1230
+ ? input.runtimeSpan(CALLBACK_BRIDGE_RELAY_REQUEST_SPAN, () => processRequestFile(fileName))
1231
+ : runWithRuntimeParent(input.getRuntimeParentContext?.(), () => processRequestFile(fileName)), iterationTimeoutMs, `Sandbox callback bridge process request ${fileName}`);
1232
+ lastSuccessfulIterationAt = Date.now();
1233
+ }
1234
+ catch (error) {
1235
+ // A single request attempt failed or hung. Run the same recovery
1236
+ // pass the loop previously died on — abort the in-flight handler
1237
+ // (its 504 backstop keeps the caller from stranding) and 503 the
1238
+ // unclaimed queued requests — but keep the loop alive afterward. A
1239
+ // caller that sees the retry-safe 503 re-queues, and the recovered
1240
+ // loop serves the retry; the old terminal catch left every later
1241
+ // request to strand instead.
1242
+ const message = buildWorkerFailureMessage(error);
1243
+ await surfaceRunError(new Error(message));
1244
+ try {
1245
+ await failPendingRequests(message, { abandonInFlight: true });
1246
+ }
1247
+ catch (failPendingError) {
1248
+ console.warn(`[paperclip] sandbox callback bridge failed to abort queued requests after a request failure: ${failPendingError instanceof Error ? failPendingError.message : String(failPendingError)}`);
1249
+ }
1250
+ }
1251
+ finally {
1252
+ inFlight -= 1;
1253
+ }
1254
+ }
1255
+ lastSuccessfulIterationAt = Date.now();
1256
+ if (stopping && Date.now() >= stopDeadline) {
1257
+ break;
1258
+ }
1259
+ }
1260
+ }
1261
+ catch (error) {
1262
+ const message = buildWorkerFailureMessage(error);
1263
+ await surfaceRunError(new Error(message));
1264
+ try {
1265
+ await failPendingRequests(message, { abandonInFlight: true });
1266
+ }
1267
+ catch (failPendingError) {
1268
+ console.warn(`[paperclip] sandbox callback bridge failed to abort queued requests after worker failure: ${failPendingError instanceof Error ? failPendingError.message : String(failPendingError)}`);
1269
+ }
1270
+ }
1271
+ finally {
1272
+ clearInterval(watchdogTimer);
1273
+ settled = true;
1274
+ if (settleResolve) {
1275
+ settleResolve();
1276
+ }
1277
+ }
1278
+ })());
1279
+ void loop;
1280
+ return {
1281
+ stop: async (options = {}) => {
1282
+ stopping = true;
1283
+ const drainMs = normalizeTimeoutMs(options.drainTimeoutMs, DEFAULT_BRIDGE_STOP_TIMEOUT_MS);
1284
+ stopDeadline = Date.now() + drainMs;
1285
+ if (!settled) {
1286
+ await Promise.race([
1287
+ settledPromise,
1288
+ new Promise((resolve) => setTimeout(resolve, drainMs)),
1289
+ ]);
1290
+ }
1291
+ await failPendingRequests("Bridge worker stopped before request could be handled.");
1292
+ },
1293
+ };
1294
+ }
1295
+ /**
1296
+ * Content-hash-skip write of a Paperclip-authored text file into the sandbox, in
1297
+ * a SINGLE remote exec. The body's sha256 is computed on the host; the one shell
1298
+ * round-trip skips the write entirely when the remote file already hashes to the
1299
+ * same value (warm start — 0 write execs), otherwise it uploads (base64 over
1300
+ * stdin), verifies the decoded bytes, and atomically renames into place. A
1301
+ * PID-liveness lock serializes concurrent writers to the same path and the
1302
+ * verify step guards against a torn upload.
1303
+ *
1304
+ * Fail loudly: a non-zero remote exit (surfaced by `requireSuccessfulResult`) or
1305
+ * malformed result JSON throws rather than silently re-uploading and masking a
1306
+ * failed check. The only intentional degradation is when the remote has neither
1307
+ * `sha256sum` nor `shasum` — then the skip cannot be proven and we conservatively
1308
+ * re-upload (and the post-upload verify is best-effort, as noted inline).
1309
+ */
1310
+ export async function syncRemoteTextFileWithHashSkip(input) {
1311
+ const timeoutMs = normalizeTimeoutMs(input.timeoutMs, DEFAULT_BRIDGE_RESPONSE_TIMEOUT_MS);
1312
+ const shellCommand = preferredShellForSandbox(input.shellCommand);
1313
+ const remotePartial = `${input.remotePath}.partial`;
1314
+ const remoteUploadPath = `${input.remotePath}.paperclip-upload.b64`;
1315
+ const base64Body = toBuffer(Buffer.from(input.body, "utf8")).toString("base64");
1316
+ const sha256 = createHash("sha256").update(input.body, "utf8").digest("hex");
1317
+ const syncResult = await runShell(input.runner, input.remoteCwd, [
1318
+ "set -eu",
1319
+ `remote_dir=${shellQuote(input.remoteDir)}`,
1320
+ `remote_path=${shellQuote(input.remotePath)}`,
1321
+ `remote_partial=${shellQuote(remotePartial)}`,
1322
+ `remote_upload=${shellQuote(remoteUploadPath)}`,
1323
+ `lock_dir=${shellQuote(input.lockDir)}`,
1324
+ `expected_sha=${shellQuote(sha256)}`,
1325
+ "hash_file() {",
1326
+ " if command -v sha256sum >/dev/null 2>&1; then",
1327
+ " sha256sum \"$1\" | awk '{print $1}'",
1328
+ " return 0",
1329
+ " fi",
1330
+ " if command -v shasum >/dev/null 2>&1; then",
1331
+ " shasum -a 256 \"$1\" | awk '{print $1}'",
1332
+ " return 0",
1333
+ " fi",
1334
+ " return 127",
1335
+ "}",
1336
+ "mkdir -p \"$remote_dir\"",
1337
+ ...buildRemotePidLockAcquireScript("\"$lock_dir\"", `Timed out acquiring ${input.label} upload lock.`),
1338
+ ...buildRemotePidLockCleanupScript("\"$lock_dir\"", [
1339
+ "rm -f \"$remote_upload\" \"$remote_partial\"",
1340
+ ]),
1341
+ "current_sha=\"\"",
1342
+ "if [ -f \"$remote_path\" ]; then",
1343
+ " current_sha=\"$(hash_file \"$remote_path\" 2>/dev/null)\" || current_sha=\"\"",
1344
+ "fi",
1345
+ "if [ -n \"$current_sha\" ] && [ \"$current_sha\" = \"$expected_sha\" ]; then",
1346
+ " printf '{\"uploaded\":false}\\n'",
1347
+ " exit 0",
1348
+ "fi",
1349
+ "rm -f \"$remote_upload\" \"$remote_partial\"",
1350
+ "cat > \"$remote_upload\"",
1351
+ "base64 -d < \"$remote_upload\" > \"$remote_partial\"",
1352
+ // Verify upload integrity. If neither sha256sum nor shasum is on PATH
1353
+ // (minimal Alpine/scratch images), surface the missing-tool error
1354
+ // instead of a misleading "sha mismatch" — the verify step is then
1355
+ // best-effort and we trust base64-decode + atomic rename below.
1356
+ "if partial_sha=\"$(hash_file \"$remote_partial\" 2>/dev/null)\"; then",
1357
+ " if [ \"$partial_sha\" != \"$expected_sha\" ]; then",
1358
+ ` echo ${shellQuote(`${input.label} upload sha mismatch.`)} >&2`,
1359
+ " exit 1",
1360
+ " fi",
1361
+ "else",
1362
+ ` echo ${shellQuote(`${input.label} sha verify skipped: no sha256sum/shasum on remote.`)} >&2`,
1363
+ "fi",
1364
+ "mv \"$remote_partial\" \"$remote_path\"",
1365
+ "printf '{\"uploaded\":true}\\n'",
1366
+ ].join("\n"), timeoutMs, shellCommand, base64Body);
1367
+ requireSuccessfulResult(input.action, syncResult);
1368
+ let uploaded = false;
1369
+ try {
1370
+ uploaded = JSON.parse(syncResult.stdout.trim())?.uploaded === true;
1371
+ }
1372
+ catch (error) {
1373
+ throw new Error(`${input.label} sync wrote invalid result JSON: ${error instanceof Error ? error.message : String(error)}`);
1374
+ }
1375
+ return { uploaded, sha256 };
1376
+ }
1377
+ export async function syncSandboxCallbackBridgeEntrypoint(input) {
1378
+ const remoteEntrypoint = path.posix.join(input.assetRemoteDir, SANDBOX_CALLBACK_BRIDGE_ENTRYPOINT);
1379
+ const entrypointSource = await fs.readFile(input.bridgeAsset.entrypoint, "utf8");
1380
+ const { uploaded, sha256 } = await syncRemoteTextFileWithHashSkip({
1381
+ runner: input.runner,
1382
+ remoteCwd: input.remoteCwd,
1383
+ remoteDir: input.assetRemoteDir,
1384
+ remotePath: remoteEntrypoint,
1385
+ body: entrypointSource,
1386
+ label: "Sandbox callback bridge entrypoint",
1387
+ action: "sync sandbox callback bridge entrypoint",
1388
+ lockDir: path.posix.join(input.assetRemoteDir, ".paperclip-bridge-upload.lock"),
1389
+ timeoutMs: input.timeoutMs,
1390
+ shellCommand: input.shellCommand,
1391
+ });
1392
+ return {
1393
+ remoteEntrypoint,
1394
+ sha256,
1395
+ uploaded,
1396
+ };
1397
+ }
1398
+ export async function startSandboxCallbackBridgeServer(input) {
1399
+ const timeoutMs = normalizeTimeoutMs(input.timeoutMs, DEFAULT_BRIDGE_RESPONSE_TIMEOUT_MS);
1400
+ const shellCommand = preferredShellForSandbox(input.shellCommand);
1401
+ const directories = sandboxCallbackBridgeDirectories(input.queueDir);
1402
+ let remoteEntrypoint = path.posix.join(input.assetRemoteDir, SANDBOX_CALLBACK_BRIDGE_ENTRYPOINT);
1403
+ if (input.bridgeAsset) {
1404
+ const assetSync = await syncSandboxCallbackBridgeEntrypoint({
1405
+ runner: input.runner,
1406
+ remoteCwd: input.remoteCwd,
1407
+ assetRemoteDir: input.assetRemoteDir,
1408
+ bridgeAsset: input.bridgeAsset,
1409
+ timeoutMs,
1410
+ shellCommand,
1411
+ });
1412
+ remoteEntrypoint = assetSync.remoteEntrypoint;
1413
+ }
1414
+ const env = buildSandboxCallbackBridgeEnv({
1415
+ queueDir: input.queueDir,
1416
+ bridgeToken: input.bridgeToken,
1417
+ host: input.host,
1418
+ port: input.port,
1419
+ pollIntervalMs: input.pollIntervalMs,
1420
+ responseTimeoutMs: input.responseTimeoutMs,
1421
+ maxQueueDepth: input.maxQueueDepth,
1422
+ maxBodyBytes: input.maxBodyBytes,
1423
+ });
1424
+ const nodeCommand = input.nodeCommand?.trim() || "node";
1425
+ const startResult = await input.runner.execute({
1426
+ command: shellCommand,
1427
+ args: shellCommandArgs([
1428
+ `mkdir -p ${shellQuote(directories.requestsDir)} ${shellQuote(directories.responsesDir)} ${shellQuote(directories.logsDir)}`,
1429
+ `rm -f ${shellQuote(directories.readyFile)} ${shellQuote(directories.pidFile)}`,
1430
+ `nohup ${shellQuote(nodeCommand)} ${shellQuote(remoteEntrypoint)} ` +
1431
+ `>> ${shellQuote(directories.logFile)} 2>&1 < /dev/null &`,
1432
+ "pid=$!",
1433
+ `printf '%s\\n' \"$pid\" > ${shellQuote(directories.pidFile)}`,
1434
+ "printf '{\"pid\":%s}\\n' \"$pid\"",
1435
+ ].join("\n")),
1436
+ cwd: input.remoteCwd,
1437
+ env: {
1438
+ [SANDBOX_EXEC_CHANNEL_ENV]: SANDBOX_EXEC_CHANNEL_BRIDGE,
1439
+ ...env,
1440
+ },
1441
+ timeoutMs,
1442
+ });
1443
+ requireSuccessfulResult("start sandbox callback bridge", startResult);
1444
+ const readyResult = await runShell(input.runner, input.remoteCwd, [
1445
+ "i=0",
1446
+ `while [ \"$i\" -lt 200 ]; do`,
1447
+ ` if [ -s ${shellQuote(directories.readyFile)} ]; then`,
1448
+ ` cat ${shellQuote(directories.readyFile)}`,
1449
+ " exit 0",
1450
+ " fi",
1451
+ ` if [ -s ${shellQuote(directories.logFile)} ] && ! kill -0 \"$(cat ${shellQuote(directories.pidFile)} 2>/dev/null)\" 2>/dev/null; then`,
1452
+ ` cat ${shellQuote(directories.logFile)} >&2`,
1453
+ " exit 1",
1454
+ " fi",
1455
+ " i=$((i + 1))",
1456
+ " sleep 0.05",
1457
+ "done",
1458
+ `echo "Timed out waiting for bridge readiness." >&2`,
1459
+ `if [ -s ${shellQuote(directories.logFile)} ]; then cat ${shellQuote(directories.logFile)} >&2; fi`,
1460
+ "exit 1",
1461
+ ].join("\n"), timeoutMs, shellCommand);
1462
+ requireSuccessfulResult("wait for sandbox callback bridge readiness", readyResult);
1463
+ let readyData;
1464
+ try {
1465
+ readyData = JSON.parse(readyResult.stdout.trim());
1466
+ }
1467
+ catch (error) {
1468
+ throw new Error(`Sandbox callback bridge wrote invalid readiness JSON: ${error instanceof Error ? error.message : String(error)}`);
1469
+ }
1470
+ const host = typeof readyData.host === "string" && readyData.host.trim().length > 0
1471
+ ? readyData.host.trim()
1472
+ : "127.0.0.1";
1473
+ const port = typeof readyData.port === "number" && Number.isFinite(readyData.port) ? readyData.port : 0;
1474
+ if (!port) {
1475
+ throw new Error("Sandbox callback bridge did not report a listening port.");
1476
+ }
1477
+ const baseUrl = typeof readyData.baseUrl === "string" && readyData.baseUrl.trim().length > 0
1478
+ ? readyData.baseUrl.trim()
1479
+ : `http://${host}:${port}`;
1480
+ return {
1481
+ baseUrl,
1482
+ host,
1483
+ port,
1484
+ pid: typeof readyData.pid === "number" && Number.isFinite(readyData.pid) ? readyData.pid : 0,
1485
+ directories,
1486
+ stop: async () => {
1487
+ const stopResult = await input.runner.execute({
1488
+ command: shellCommand,
1489
+ args: shellCommandArgs([
1490
+ `if [ -s ${shellQuote(directories.pidFile)} ]; then`,
1491
+ ` pid="$(cat ${shellQuote(directories.pidFile)})"`,
1492
+ " kill \"$pid\" 2>/dev/null || true",
1493
+ " i=0",
1494
+ " while kill -0 \"$pid\" 2>/dev/null && [ \"$i\" -lt 40 ]; do",
1495
+ " i=$((i + 1))",
1496
+ " sleep 0.05",
1497
+ " done",
1498
+ "fi",
1499
+ `rm -f ${shellQuote(directories.pidFile)} ${shellQuote(directories.readyFile)}`,
1500
+ ].join("\n")),
1501
+ cwd: input.remoteCwd,
1502
+ env: {
1503
+ [SANDBOX_EXEC_CHANNEL_ENV]: SANDBOX_EXEC_CHANNEL_BRIDGE,
1504
+ },
1505
+ timeoutMs,
1506
+ });
1507
+ if (stopResult.timedOut) {
1508
+ throw new Error(buildRunnerFailureMessage("stop sandbox callback bridge", stopResult));
1509
+ }
1510
+ },
1511
+ };
1512
+ }
1513
+ // ---------------------------------------------------------------------------
1514
+ // Sandbox HTTP/2 client gateway
1515
+ //
1516
+ // This gateway turns each local loopback request into one HTTP/2 stream to
1517
+ // the host server in `http2-bridge-server.ts`. It sits beside the file-mode
1518
+ // gateway above; it changes neither of them. The generated in-sandbox
1519
+ // entrypoint and the transport-selection path already select it.
1520
+ // ---------------------------------------------------------------------------
1521
+ /**
1522
+ * Constant-time bridge-token compare. Both this sandbox gateway and the host
1523
+ * server in `http2-bridge-server.ts` import this one helper, so the gateway
1524
+ * check and the independent host check (accepted security fix 4) apply the
1525
+ * exact same comparison rule. A length mismatch returns `false` without a
1526
+ * `timingSafeEqual` call, because `timingSafeEqual` throws on unequal buffer
1527
+ * lengths; both operands are bridge tokens of near-fixed length, so this one
1528
+ * length branch leaks no useful timing signal.
1529
+ */
1530
+ export function compareBridgeTokensConstantTime(expected, received) {
1531
+ const expectedBytes = Buffer.from(expected, "utf8");
1532
+ const receivedBytes = Buffer.from(typeof received === "string" ? received : "", "utf8");
1533
+ if (expectedBytes.length !== receivedBytes.length)
1534
+ return false;
1535
+ return timingSafeEqual(expectedBytes, receivedBytes);
1536
+ }
1537
+ const SANDBOX_HTTP2_GATEWAY_DEFAULT_AUTHORITY = "bridge.internal";
1538
+ function forwardOneHttp2Request(session, request) {
1539
+ return new Promise((resolve, reject) => {
1540
+ const query = request.query.trim();
1541
+ const pathWithQuery = query.length === 0 ? request.path : `${request.path}${query.startsWith("?") ? query : `?${query}`}`;
1542
+ const requestHeaders = {
1543
+ ":method": request.method,
1544
+ ":path": pathWithQuery,
1545
+ authorization: `Bearer ${request.bridgeToken}`,
1546
+ ...request.headers,
1547
+ };
1548
+ let stream;
1549
+ try {
1550
+ stream = session.request(requestHeaders, { endStream: request.body.length === 0 });
1551
+ }
1552
+ catch (error) {
1553
+ reject(error instanceof Error ? error : new Error(String(error)));
1554
+ return;
1555
+ }
1556
+ const chunks = [];
1557
+ let responseHeaders = {};
1558
+ let status = 502;
1559
+ let settled = false;
1560
+ const settle = (run) => {
1561
+ if (settled)
1562
+ return;
1563
+ settled = true;
1564
+ run();
1565
+ };
1566
+ stream.on("response", (headers) => {
1567
+ const rawStatus = headers[":status"];
1568
+ status = typeof rawStatus === "number" ? rawStatus : Number(rawStatus) || 502;
1569
+ responseHeaders = {};
1570
+ for (const [key, value] of Object.entries(headers)) {
1571
+ if (key.startsWith(":") || value == null)
1572
+ continue;
1573
+ responseHeaders[key] = Array.isArray(value) ? value.join(", ") : String(value);
1574
+ }
1575
+ });
1576
+ stream.on("data", (chunk) => chunks.push(chunk));
1577
+ stream.once("end", () => settle(() => resolve({ status, headers: responseHeaders, body: Buffer.concat(chunks) })));
1578
+ stream.once("error", (error) => settle(() => reject(error instanceof Error ? error : new Error(String(error)))));
1579
+ stream.once("aborted", () => settle(() => reject(new Error("Bridge HTTP/2 stream aborted."))));
1580
+ if (request.body.length > 0) {
1581
+ stream.end(request.body);
1582
+ }
1583
+ else if (!stream.writableEnded) {
1584
+ stream.end();
1585
+ }
1586
+ });
1587
+ }
1588
+ /**
1589
+ * Create the sandbox HTTP/2 client gateway. It opens one HTTP/2 client
1590
+ * session on the transport `createConnection` returns, and forwards each
1591
+ * local request the caller hands it (already checked against the bridge
1592
+ * token — see {@link SandboxHttp2BridgeGatewayRequest.receivedToken}) as one
1593
+ * HTTP/2 stream. It keeps the header allowlist on the sandbox side, exactly
1594
+ * as the file-mode gateway does.
1595
+ */
1596
+ export function createSandboxHttp2BridgeGateway(options) {
1597
+ const authority = options.authority?.trim() || SANDBOX_HTTP2_GATEWAY_DEFAULT_AUTHORITY;
1598
+ const headerAllowlist = options.headerAllowlist ?? DEFAULT_SANDBOX_CALLBACK_BRIDGE_HEADER_ALLOWLIST;
1599
+ const session = http2.connect(`http://${authority}`, {
1600
+ createConnection: options.createConnection,
1601
+ });
1602
+ // A session-level fault fails every in-flight `forwardRequest` call through
1603
+ // that stream's own `error`/`aborted` handler. This listener only stops
1604
+ // Node from raising an unhandled `error` event for the session itself.
1605
+ session.on("error", () => undefined);
1606
+ session.on("goaway", (errorCode, lastStreamId) => {
1607
+ options.onGoaway?.({ lastStreamId, errorCode });
1608
+ });
1609
+ return {
1610
+ forwardRequest(request) {
1611
+ // The gateway check (accepted security fix 4 keeps this as well as the
1612
+ // independent host-side check): a request whose token does not match
1613
+ // the per-run bridge token never opens a stream.
1614
+ if (!compareBridgeTokensConstantTime(options.bridgeToken, request.receivedToken)) {
1615
+ return Promise.reject(new Error("Invalid bridge token."));
1616
+ }
1617
+ return forwardOneHttp2Request(session, {
1618
+ bridgeToken: options.bridgeToken,
1619
+ method: request.method,
1620
+ path: request.path,
1621
+ query: request.query,
1622
+ headers: sanitizeSandboxCallbackBridgeHeaders(request.headers, headerAllowlist),
1623
+ body: request.body,
1624
+ });
1625
+ },
1626
+ close() {
1627
+ return new Promise((resolve) => {
1628
+ if (session.closed || session.destroyed) {
1629
+ resolve();
1630
+ return;
1631
+ }
1632
+ session.close(() => resolve());
1633
+ });
1634
+ },
1635
+ };
1636
+ }
1637
+ /**
1638
+ * The zero-dependency codec the generated duplex gateway embeds. It is a plain
1639
+ * JavaScript copy of the encode side of the host codec in `duplex-frame-codec.ts`.
1640
+ * The generated gateway never decodes: it writes exactly one READY line, then
1641
+ * hands stdout to its transport. So this copy carries only the frame version and
1642
+ * the encode function, not a decoder. It uses only the `Buffer` and `JSON`
1643
+ * globals, so the generated `.mjs` needs no workspace import. It carries no
1644
+ * template literal and no `${` sequence, so it embeds inside the gateway
1645
+ * template literal with no escape.
1646
+ *
1647
+ * A shared fixture file (`duplex-frame-vectors.json`) proves the host encode side
1648
+ * stays wire compatible with this copy. {@link getSandboxDuplexGatewayCodecSource}
1649
+ * returns this exact source so a test can run the READY encode vector against it.
1650
+ */
1651
+ const DUPLEX_GATEWAY_CODEC_SOURCE = `const DUPLEX_FRAME_VERSION = 2;
1652
+
1653
+ function encodeDuplexFrame(frame) {
1654
+ return JSON.stringify(frame) + "\\n";
1655
+ }`;
1656
+ /**
1657
+ * Return the exact zero-dependency codec source the generated duplex gateway
1658
+ * embeds. A test wraps this source and calls `encodeDuplexFrame` to prove the
1659
+ * embedded copy encodes the READY frame the same way the host encode side does.
1660
+ * The source declares `encodeDuplexFrame` and `DUPLEX_FRAME_VERSION`, but exports
1661
+ * neither; a caller wraps it to read those names.
1662
+ */
1663
+ export function getSandboxDuplexGatewayCodecSource() {
1664
+ return DUPLEX_GATEWAY_CODEC_SOURCE;
1665
+ }
1666
+ /**
1667
+ * Zero-dependency source for the gateway's own aggregate body-byte ledger.
1668
+ * `readBodyBytes` in the generated gateway reserves against one instance of
1669
+ * this ledger before it retains a chunk and before it concatenates the final
1670
+ * buffer, so a burst of concurrent requests cannot grow the gateway
1671
+ * process's own memory without limit. This ledger is separate from, and
1672
+ * independent of, the ceiling `http2-bridge-server.ts` enforces on the host
1673
+ * side of the bridge connection: each side bounds only the memory in its own
1674
+ * process. It uses no global beyond plain JavaScript, so it embeds inside the
1675
+ * gateway template literal with no escape. A test wraps this source directly
1676
+ * to exercise `reserve`/`release`, the same way
1677
+ * {@link getSandboxDuplexGatewayCodecSource} lets a test exercise the codec.
1678
+ */
1679
+ const BRIDGE_PROCESS_BODY_LEDGER_SOURCE = `function createBridgeProcessBodyLedger(maxBytes) {
1680
+ let reservedBytes = 0;
1681
+ return {
1682
+ reserve(byteCount) {
1683
+ if (reservedBytes + byteCount > maxBytes) {
1684
+ return false;
1685
+ }
1686
+ reservedBytes += byteCount;
1687
+ return true;
1688
+ },
1689
+ release(byteCount) {
1690
+ reservedBytes -= byteCount;
1691
+ },
1692
+ get reservedBytes() {
1693
+ return reservedBytes;
1694
+ },
1695
+ };
1696
+ }`;
1697
+ /**
1698
+ * Return the exact zero-dependency ledger source the generated gateway
1699
+ * embeds. A test wraps this source and calls `createBridgeProcessBodyLedger`
1700
+ * to prove the embedded copy reserves and releases bytes correctly, with no
1701
+ * spawned process involved.
1702
+ */
1703
+ export function getSandboxBridgeProcessBodyLedgerSource() {
1704
+ return BRIDGE_PROCESS_BODY_LEDGER_SOURCE;
1705
+ }
1706
+ export function getSandboxCallbackBridgeServerSource() {
1707
+ return `import { randomUUID, timingSafeEqual } from "node:crypto";
1708
+ import { createServer } from "node:http";
1709
+ import { promises as fs } from "node:fs";
1710
+ import path from "node:path";
1711
+ import http2 from "node:http2";
1712
+ import { Duplex } from "node:stream";
1713
+
1714
+ const bridgeMode = process.env.PAPERCLIP_API_BRIDGE_MODE || "${SANDBOX_CALLBACK_BRIDGE_FILE_MODE}";
1715
+ const queueDir = process.env.PAPERCLIP_BRIDGE_QUEUE_DIR;
1716
+ const bridgeToken = process.env.PAPERCLIP_BRIDGE_TOKEN;
1717
+ const host = process.env.PAPERCLIP_BRIDGE_HOST || "127.0.0.1";
1718
+ const port = Number(process.env.PAPERCLIP_BRIDGE_PORT || "0");
1719
+ // The host assigns the loopback port and passes it through the launch
1720
+ // environment. The gateway binds exactly this port; it never selects a
1721
+ // different one. The host also passes one random per-open nonce here. The
1722
+ // gateway echoes it in the READY frame so the host correlates READY with this
1723
+ // channel open. The nonce is a liveness signal, not authentication.
1724
+ const bridgeNonce = process.env.PAPERCLIP_BRIDGE_NONCE || "";
1725
+ const pollIntervalMs = Number(process.env.PAPERCLIP_BRIDGE_POLL_INTERVAL_MS || "100");
1726
+ const responseTimeoutMs = Number(
1727
+ process.env.PAPERCLIP_BRIDGE_RESPONSE_TIMEOUT_MS || "${DEFAULT_BRIDGE_RESPONSE_TIMEOUT_MS}",
1728
+ );
1729
+ const maxQueueDepth = Number(process.env.PAPERCLIP_BRIDGE_MAX_QUEUE_DEPTH || "${DEFAULT_BRIDGE_MAX_QUEUE_DEPTH}");
1730
+ const maxBodyBytes = Number(process.env.PAPERCLIP_BRIDGE_MAX_BODY_BYTES || "${DEFAULT_BRIDGE_MAX_BODY_BYTES}");
1731
+ // The header allowlist. Both the file gateway and the http2 gateway strip an
1732
+ // inbound request to these headers before they forward it. One copy serves both
1733
+ // modes. The route allowlist stays on the host: both modes forward a request to
1734
+ // the host, and the host enforces the same route allowlist for each.
1735
+ const allowedHeaders = new Set(${JSON.stringify([...DEFAULT_SANDBOX_CALLBACK_BRIDGE_HEADER_ALLOWLIST])});
1736
+
1737
+ if (!bridgeToken) {
1738
+ throw new Error("PAPERCLIP_BRIDGE_TOKEN is required.");
1739
+ }
1740
+ // Closed allowlist for the bridge mode. The generated gateway supports exactly
1741
+ // two transports: http2 and the file-mode queue. Every other value, including
1742
+ // the retired duplex transport, fails startup at once instead of falling
1743
+ // through to a mode that never ran. This check runs before the queue-directory
1744
+ // check below, so an unsupported mode never reaches a state where a missing
1745
+ // queue directory masks the real problem.
1746
+ if (
1747
+ bridgeMode !== "${SANDBOX_CALLBACK_BRIDGE_HTTP2_MODE}" &&
1748
+ bridgeMode !== "${SANDBOX_CALLBACK_BRIDGE_FILE_MODE}"
1749
+ ) {
1750
+ throw new Error("Unsupported PAPERCLIP_API_BRIDGE_MODE: " + bridgeMode);
1751
+ }
1752
+ if (bridgeMode !== "${SANDBOX_CALLBACK_BRIDGE_HTTP2_MODE}" && !queueDir) {
1753
+ throw new Error("PAPERCLIP_BRIDGE_QUEUE_DIR and PAPERCLIP_BRIDGE_TOKEN are required.");
1754
+ }
1755
+
1756
+ // A crashed gateway is a dead loopback port for the rest of the run: nothing
1757
+ // inside the sandbox respawns this process, and every later agent API call
1758
+ // then fails at the connection level. Once the gateway is ready, log an
1759
+ // uncaught fault to stderr (the host redirects it into logs/bridge.log) and
1760
+ // keep serving — the relay holds no state a fault can corrupt beyond the one
1761
+ // request it interrupted. Before readiness the same fault means the gateway
1762
+ // can never become usable (a failed bind, a failed readiness write), so exit
1763
+ // instead: surviving there only leaves an un-ready zombie behind while the
1764
+ // host waits out its readiness poll.
1765
+ let gatewayReady = false;
1766
+ process.on("uncaughtException", (error) => {
1767
+ process.stderr.write(
1768
+ "[paperclip-bridge] uncaught exception: " + (error && error.stack ? error.stack : String(error)) + "\\n",
1769
+ );
1770
+ if (!gatewayReady) {
1771
+ process.exit(1);
1772
+ }
1773
+ });
1774
+ process.on("unhandledRejection", (reason) => {
1775
+ const detail = reason && typeof reason === "object" && "stack" in reason ? reason.stack : String(reason);
1776
+ process.stderr.write("[paperclip-bridge] unhandled rejection: " + detail + "\\n");
1777
+ if (!gatewayReady) {
1778
+ process.exit(1);
1779
+ }
1780
+ });
1781
+
1782
+ // The embedded zero-dependency frame codec. The duplex gateway uses it; the file
1783
+ // gateway ignores it.
1784
+ ${DUPLEX_GATEWAY_CODEC_SOURCE}
1785
+
1786
+ // The embedded zero-dependency process body-byte ledger. Both gateway modes
1787
+ // use it: readBodyBytes reserves against it, and each mode's request
1788
+ // handler releases what it reserved once the body is no longer needed.
1789
+ ${BRIDGE_PROCESS_BODY_LEDGER_SOURCE}
1790
+ ${sandboxBridgeBodyCodecSource()}
1791
+
1792
+ // HTTP/2's multiplier matches HTTP2_BRIDGE_MAX_CONCURRENT_STREAMS (4) in
1793
+ // http2-bridge-server.ts, doubled because readBodyBytes reserves a body's
1794
+ // bytes twice: once for the retained chunk array, once for the concatenated
1795
+ // copy, since both are live buffers at once. This gives the gateway process
1796
+ // its own aggregate ceiling on live request-body bytes, so a burst of
1797
+ // concurrent requests cannot grow this process's memory without limit, even
1798
+ // though every individual body already passes the maxBodyBytes check below.
1799
+ // This ceiling is independent of, and separate from, the ceiling the host
1800
+ // enforces on its own side of the bridge connection. Queue mode also counts
1801
+ // JSON/base64 envelopes; its aggregate ceiling never exceeds 1 GiB.
1802
+ const maxProcessBodyBytes = bridgeMode === "${SANDBOX_CALLBACK_BRIDGE_FILE_MODE}"
1803
+ ? Math.min(1024 * 1024 * 1024, 4 * (4 * sandboxBridgeEnvelopeLimit(maxBodyBytes) + 4 * maxBodyBytes))
1804
+ : maxBodyBytes * 8;
1805
+ const processBodyLedger = createBridgeProcessBodyLedger(maxProcessBodyBytes);
1806
+
1807
+ // A denied process-ledger reservation answers 503: the sandbox client should
1808
+ // retry once other in-flight bodies finish and release their bytes, the same
1809
+ // retry contract the host side gives for its own capacity denial.
1810
+ class BridgeProcessCapacityError extends Error {
1811
+ constructor() {
1812
+ super("The bridge gateway process reached its reserved body byte ceiling. Retry later.");
1813
+ }
1814
+ }
1815
+
1816
+ function sleep(ms) {
1817
+ return new Promise((resolve) => setTimeout(resolve, ms));
1818
+ }
1819
+
1820
+ function normalizeHeaders(headers) {
1821
+ const out = {};
1822
+ for (const [key, value] of Object.entries(headers)) {
1823
+ if (value == null) continue;
1824
+ const normalizedKey = key.toLowerCase();
1825
+ if (!allowedHeaders.has(normalizedKey)) {
1826
+ continue;
1827
+ }
1828
+ out[normalizedKey] = Array.isArray(value) ? value.join(", ") : String(value);
1829
+ }
1830
+ return out;
1831
+ }
1832
+
1833
+ // Reserves each chunk's bytes against the process ledger before the chunk
1834
+ // joins the retained array, and reserves the concatenated buffer's own byte
1835
+ // count before Buffer.concat allocates it, mirroring the order
1836
+ // readHttp2StreamBody enforces on the host side. Returns the body buffer
1837
+ // together with a release function: the caller must call release exactly
1838
+ // once, after the body is no longer needed, so its reserved bytes return to
1839
+ // the ledger on completion, on an error the caller raises later, on a client
1840
+ // abort, and on a timeout — every path funnels through the caller's own
1841
+ // finally block. A read that fails here (the size limit, or a denied
1842
+ // process reservation) releases its own partial reservation immediately, so
1843
+ // no caller-side release call is needed for that path.
1844
+ async function readBodyBytes(req) {
1845
+ const chunks = [];
1846
+ let totalBytes = 0;
1847
+ let reservedBytes = 0;
1848
+ try {
1849
+ for await (const chunk of req) {
1850
+ const nextChunk = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
1851
+ totalBytes += nextChunk.byteLength;
1852
+ if (totalBytes > maxBodyBytes) {
1853
+ throw new Error("Bridge request body exceeded the configured size limit.");
1854
+ }
1855
+ if (!processBodyLedger.reserve(nextChunk.byteLength)) {
1856
+ throw new BridgeProcessCapacityError();
1857
+ }
1858
+ reservedBytes += nextChunk.byteLength;
1859
+ chunks.push(nextChunk);
1860
+ }
1861
+ if (!processBodyLedger.reserve(totalBytes)) {
1862
+ throw new BridgeProcessCapacityError();
1863
+ }
1864
+ reservedBytes += totalBytes;
1865
+ const body = Buffer.concat(chunks);
1866
+ return { body, release: () => processBodyLedger.release(reservedBytes) };
1867
+ } catch (error) {
1868
+ processBodyLedger.release(reservedBytes);
1869
+ throw error;
1870
+ }
1871
+ }
1872
+
1873
+ function tokensMatch(received) {
1874
+ const expected = Buffer.from(bridgeToken, "utf8");
1875
+ const actual = Buffer.from(typeof received === "string" ? received : "", "utf8");
1876
+ if (expected.length !== actual.length) return false;
1877
+ return timingSafeEqual(expected, actual);
1878
+ }
1879
+
1880
+ function writeJsonResponse(res, status, body) {
1881
+ res.statusCode = status;
1882
+ res.setHeader("content-type", "application/json");
1883
+ res.end(JSON.stringify(body));
1884
+ }
1885
+
1886
+ async function runFileGateway() {
1887
+ const requestsDir = path.posix.join(queueDir, "requests");
1888
+ const responsesDir = path.posix.join(queueDir, "responses");
1889
+ const logsDir = path.posix.join(queueDir, "logs");
1890
+ const readyFile = path.posix.join(queueDir, "ready.json");
1891
+
1892
+ async function queueDepth() {
1893
+ const entries = await fs.readdir(requestsDir, { withFileTypes: true }).catch(() => []);
1894
+ return entries.filter((entry) => entry.isFile() && entry.name.endsWith(".json")).length;
1895
+ }
1896
+
1897
+ // Delete request files older than the response deadline. Every live caller
1898
+ // cleans its own request file when it times out, so a file this old is an
1899
+ // orphan: its writer was killed mid-wait, or a previous gateway process died
1900
+ // and left its queue behind. Orphans otherwise count toward the queue-depth
1901
+ // cap forever and wedge the gateway at a permanent 503.
1902
+ async function sweepStaleRequests() {
1903
+ const staleBefore = Date.now() - responseTimeoutMs - 2000;
1904
+ const entries = await fs.readdir(requestsDir, { withFileTypes: true }).catch(() => []);
1905
+ for (const entry of entries) {
1906
+ if (!entry.isFile() || !entry.name.endsWith(".json")) continue;
1907
+ const filePath = path.posix.join(requestsDir, entry.name);
1908
+ const stats = await fs.stat(filePath).catch(() => null);
1909
+ if (stats && stats.mtimeMs < staleBefore) {
1910
+ await fs.rm(filePath, { force: true }).catch(() => undefined);
1911
+ }
1912
+ }
1913
+ }
1914
+
1915
+ async function waitForResponse(requestId, reserveResponse) {
1916
+ const responsePath = path.posix.join(responsesDir, \`\${requestId}.json\`);
1917
+ const deadline = Date.now() + responseTimeoutMs;
1918
+ while (Date.now() < deadline) {
1919
+ const handle = await fs.open(responsePath, "r").catch(error => {
1920
+ if (error.code === "ENOENT") return null;
1921
+ throw error;
1922
+ });
1923
+ if (handle) {
1924
+ try {
1925
+ const stat = await handle.stat();
1926
+ if (stat.size > sandboxBridgeEnvelopeLimit(maxBodyBytes)) throw new Error("Bridge response envelope exceeded the configured size limit.");
1927
+ reserveResponse(6 * stat.size + 1);
1928
+ const bytes = Buffer.alloc(stat.size + 1);
1929
+ let length = 0;
1930
+ while (length < bytes.length) {
1931
+ const read = await handle.read(bytes, length, bytes.length - length, length);
1932
+ if (!read.bytesRead) break;
1933
+ length += read.bytesRead;
1934
+ }
1935
+ if (length !== stat.size) throw new Error("Bridge response envelope changed while reading.");
1936
+ return JSON.parse(bytes.subarray(0, length).toString("utf8"));
1937
+ } finally {
1938
+ await handle.close();
1939
+ await fs.rm(responsePath, { force: true }).catch(() => undefined);
1940
+ }
1941
+ }
1942
+ await sleep(pollIntervalMs);
1943
+ }
1944
+ throw new Error("Timed out waiting for host bridge response.");
1945
+ }
1946
+
1947
+ const server = createServer(async (req, res) => {
1948
+ // readBodyBytes reserves the body's bytes against the process ledger and
1949
+ // hands back a release function; this holds it so the finally below
1950
+ // releases those bytes exactly once no matter how this handler ends —
1951
+ // its normal completion, a thrown error, a client abort, or a deadline
1952
+ // timeout all reach the same finally.
1953
+ let releaseBodyReservation = null;
1954
+ let envelopeReservation = 0;
1955
+ let dispatched = false;
1956
+ try {
1957
+ const auth = req.headers.authorization || "";
1958
+ const receivedToken = auth.startsWith("Bearer ") ? auth.slice("Bearer ".length) : "";
1959
+ if (!tokensMatch(receivedToken)) {
1960
+ writeJsonResponse(res, 401, { error: "Invalid bridge token." });
1961
+ return;
1962
+ }
1963
+
1964
+ if (await queueDepth() >= maxQueueDepth) {
1965
+ // Reclaim orphaned request files before rejecting; only a queue that
1966
+ // is genuinely full of live requests gets the 503.
1967
+ await sweepStaleRequests();
1968
+ if (await queueDepth() >= maxQueueDepth) {
1969
+ writeJsonResponse(res, 503, { error: "Bridge request queue is full." });
1970
+ return;
1971
+ }
1972
+ }
1973
+
1974
+ const url = new URL(req.url || "/", "http://127.0.0.1");
1975
+ const contentType = typeof req.headers["content-type"] === "string" ? req.headers["content-type"] : "";
1976
+ const multipartAttachment = req.method === "POST"
1977
+ && /^\\/api\\/companies\\/[^/]+\\/issues\\/[^/]+\\/attachments$/.test(url.pathname)
1978
+ && /^multipart\\/form-data(?:;|$)/i.test(contentType);
1979
+ if (req.method && req.method !== "GET" && req.method !== "HEAD" && !/json/i.test(contentType) && !multipartAttachment) {
1980
+ writeJsonResponse(res, 415, { error: "Bridge only accepts JSON request bodies." });
1981
+ return;
1982
+ }
1983
+ const requestId = randomUUID();
1984
+ // Reserve encoded envelopes and response decoding separately from the
1985
+ // incoming byte buffers. Capacity rejection precedes dispatch, hence 503.
1986
+ const { body: requestBody, release } = await readBodyBytes(req);
1987
+ releaseBodyReservation = release;
1988
+ const reserveBytes = 4 * sandboxBridgeEnvelopeLimit(requestBody.length);
1989
+ if (!processBodyLedger.reserve(reserveBytes)) throw new BridgeProcessCapacityError();
1990
+ envelopeReservation = reserveBytes;
1991
+ const payload = {
1992
+ id: requestId,
1993
+ method: req.method || "GET",
1994
+ path: url.pathname,
1995
+ query: url.search,
1996
+ headers: normalizeHeaders(req.headers),
1997
+ ...encodeSandboxBridgeBody(multipartAttachment ? requestBody : requestBody.toString("utf8"), maxBodyBytes),
1998
+ createdAt: new Date().toISOString(),
1999
+ };
2000
+ const requestPath = path.posix.join(requestsDir, \`\${requestId}.json\`);
2001
+ const tempPath = \`\${requestPath}.tmp\`;
2002
+ await fs.writeFile(tempPath, \`\${JSON.stringify(payload)}\\n\`, "utf8");
2003
+ dispatched = true;
2004
+ await fs.rename(tempPath, requestPath);
2005
+
2006
+ let response;
2007
+ try {
2008
+ response = await waitForResponse(requestId, bytes => {
2009
+ if (!processBodyLedger.reserve(bytes)) throw new BridgeProcessCapacityError();
2010
+ envelopeReservation += bytes;
2011
+ });
2012
+ } catch (error) {
2013
+ // The host never delivered a response inside the deadline. Remove this
2014
+ // request's file so it cannot pile up toward the queue-depth cap. The
2015
+ // host's normal response write is guarded on the request file, so the
2016
+ // removal also tells the host that no caller waits anymore. Without
2017
+ // this cleanup a stalled host wedges the gateway at the cap and every
2018
+ // later request gets an immediate 503 until run end.
2019
+ await fs.rm(requestPath, { force: true }).catch(() => undefined);
2020
+ throw error;
2021
+ }
2022
+ const responseHeaders = response.headers || {};
2023
+ // The host marks a possibly-committed mutation with an indeterminate outcome.
2024
+ // The host cannot cancel a host operation that is in flight, so the mutation
2025
+ // may have committed before the worker aborted the handler. A 5xx status is
2026
+ // retryable by convention, so a caller that retries 5xx would apply the
2027
+ // mutation twice. Map the indeterminate outcome to a non-retryable 409, so a
2028
+ // standard retry policy does not repeat the request. The outcome header and
2029
+ // body stay, so a caller that reads them still sees the indeterminate result.
2030
+ const bridgeOutcome = responseHeaders["x-paperclip-bridge-outcome"];
2031
+ if (bridgeOutcome === "indeterminate") {
2032
+ res.statusCode = 409;
2033
+ } else {
2034
+ res.statusCode = typeof response.status === "number" ? response.status : 200;
2035
+ }
2036
+ for (const [key, value] of Object.entries(responseHeaders)) {
2037
+ if (typeof value !== "string" || key.toLowerCase() === "content-length") continue;
2038
+ res.setHeader(key, value);
2039
+ }
2040
+ res.end(decodeSandboxBridgeBody(response, maxBodyBytes));
2041
+ } catch (error) {
2042
+ // Capacity rejection before dispatch is retryable. After a mutation was
2043
+ // dispatched, a missing or corrupt receipt cannot prove that it failed.
2044
+ const uncertainWrite = dispatched && !["GET", "HEAD", "OPTIONS", "TRACE"].includes(req.method || "GET");
2045
+ const status = uncertainWrite ? 409 : error instanceof BridgeProcessCapacityError ? 503 : 502;
2046
+ if (uncertainWrite) res.setHeader("x-paperclip-bridge-outcome", "indeterminate");
2047
+ writeJsonResponse(res, status, {
2048
+ error: error instanceof Error ? error.message : String(error),
2049
+ ...(uncertainWrite ? { outcome: "indeterminate", retryable: false } : {}),
2050
+ });
2051
+ } finally {
2052
+ releaseBodyReservation?.();
2053
+ processBodyLedger.release(envelopeReservation);
2054
+ }
2055
+ });
2056
+
2057
+ async function shutdown() {
2058
+ server.close(() => {
2059
+ process.exit(0);
2060
+ });
2061
+ }
2062
+
2063
+ process.on("SIGINT", () => void shutdown());
2064
+ process.on("SIGTERM", () => void shutdown());
2065
+
2066
+ await fs.mkdir(requestsDir, { recursive: true });
2067
+ await fs.mkdir(responsesDir, { recursive: true });
2068
+ await fs.mkdir(logsDir, { recursive: true });
2069
+
2070
+ // Newer Node runtimes do not reliably surface a failed bind through
2071
+ // uncaughtException here: with nothing else keeping the event loop alive,
2072
+ // the process can drain and exit 0 before the error event is delivered
2073
+ // (observed on Node 24/25; Node 22 delivered it). Attach an explicit error
2074
+ // listener and pin the loop with a keepalive until the bind settles, so a
2075
+ // startup failure exits 1 with the fault on stderr on every runtime.
2076
+ const bindKeepalive = setInterval(() => {}, 1000);
2077
+ server.once("error", (error) => {
2078
+ clearInterval(bindKeepalive);
2079
+ process.stderr.write(
2080
+ "[paperclip-bridge] server error: " + (error && error.stack ? error.stack : String(error)) + "\\n",
2081
+ );
2082
+ if (!gatewayReady) {
2083
+ process.exit(1);
2084
+ }
2085
+ });
2086
+ server.listen(port, host, async () => {
2087
+ clearInterval(bindKeepalive);
2088
+ const address = server.address();
2089
+ if (!address || typeof address === "string") {
2090
+ throw new Error("Bridge server did not expose a TCP address.");
2091
+ }
2092
+ const ready = {
2093
+ pid: process.pid,
2094
+ host,
2095
+ port: address.port,
2096
+ baseUrl: \`http://\${host}:\${address.port}\`,
2097
+ startedAt: new Date().toISOString(),
2098
+ };
2099
+ const tempReadyFile = \`\${readyFile}.tmp\`;
2100
+ await fs.writeFile(tempReadyFile, JSON.stringify(ready), "utf8");
2101
+ await fs.rename(tempReadyFile, readyFile);
2102
+ // The readiness file is on disk, so the host will adopt this process.
2103
+ // From here on an uncaught fault must not kill the listener.
2104
+ gatewayReady = true;
2105
+ });
2106
+ }
2107
+
2108
+ // ---------------------------------------------------------------------------
2109
+ // http2_v1: run one Node HTTP/2 client session directly on stdin/stdout.
2110
+ //
2111
+ // This gateway writes exactly one frame-codec line before it hands stdin and
2112
+ // stdout to the HTTP/2 client: the READY line, so the host readiness gate
2113
+ // accepts the same handshake it already accepts for every mode. After that
2114
+ // one write, only the HTTP/2 client touches stdout: this function calls
2115
+ // writeFrame no more, and it starts no heartbeat timer, so no non-HTTP/2
2116
+ // writer can put a byte on stdout between the READY line and the client
2117
+ // connection preface.
2118
+ // ---------------------------------------------------------------------------
2119
+
2120
+ function createStdioDuplex() {
2121
+ const duplex = new Duplex({
2122
+ read() {
2123
+ // process.stdin pushes bytes through the "data" listener below; there
2124
+ // is nothing to pull on demand here.
2125
+ },
2126
+ write(chunk, _encoding, callback) {
2127
+ const flushed = process.stdout.write(chunk);
2128
+ if (flushed) {
2129
+ callback();
2130
+ } else {
2131
+ process.stdout.once("drain", () => callback());
2132
+ }
2133
+ },
2134
+ });
2135
+ process.stdin.on("data", (chunk) => {
2136
+ duplex.push(chunk);
2137
+ });
2138
+ process.stdin.on("end", () => {
2139
+ duplex.push(null);
2140
+ });
2141
+ process.stdin.on("error", (error) => {
2142
+ duplex.destroy(error instanceof Error ? error : new Error(String(error)));
2143
+ });
2144
+ return duplex;
2145
+ }
2146
+
2147
+ function runHttp2Gateway() {
2148
+ function diag(message) {
2149
+ // Diagnostics go to stderr only, the same as every other mode.
2150
+ process.stderr.write("[paperclip-bridge] " + message + "\\n");
2151
+ }
2152
+ function writeFrame(frame) {
2153
+ process.stdout.write(encodeDuplexFrame(frame));
2154
+ }
2155
+
2156
+ const authority = "bridge.internal";
2157
+ let session = null;
2158
+ let unavailable = false;
2159
+
2160
+ function openSession() {
2161
+ if (session) return session;
2162
+ const stdio = createStdioDuplex();
2163
+ session = http2.connect("http://" + authority, {
2164
+ createConnection: () => stdio,
2165
+ });
2166
+ session.on("error", () => {
2167
+ unavailable = true;
2168
+ });
2169
+ session.on("close", () => {
2170
+ unavailable = true;
2171
+ });
2172
+ session.on("goaway", (errorCode, lastStreamId) => {
2173
+ diag("host sent GOAWAY (errorCode=" + errorCode + ", lastStreamId=" + lastStreamId + ")");
2174
+ });
2175
+ return session;
2176
+ }
2177
+
2178
+ function forwardOverHttp2(request) {
2179
+ return new Promise((resolve, reject) => {
2180
+ const activeSession = openSession();
2181
+ const query = request.query || "";
2182
+ const pathWithQuery =
2183
+ query.length === 0 ? request.path : request.path + (query.charAt(0) === "?" ? query : "?" + query);
2184
+ const outboundHeaders = Object.assign(
2185
+ {
2186
+ ":method": request.method,
2187
+ ":path": pathWithQuery,
2188
+ authorization: "Bearer " + bridgeToken,
2189
+ },
2190
+ request.headers,
2191
+ );
2192
+ let stream;
2193
+ try {
2194
+ stream = activeSession.request(outboundHeaders, { endStream: request.body.length === 0 });
2195
+ } catch (error) {
2196
+ reject(error instanceof Error ? error : new Error(String(error)));
2197
+ return;
2198
+ }
2199
+ const chunks = [];
2200
+ let status = 502;
2201
+ let responseHeaders = {};
2202
+ let settled = false;
2203
+ const settle = (run) => {
2204
+ if (settled) return;
2205
+ settled = true;
2206
+ run();
2207
+ };
2208
+ stream.on("response", (headers) => {
2209
+ const raw = headers[":status"];
2210
+ status = typeof raw === "number" ? raw : Number(raw) || 502;
2211
+ responseHeaders = {};
2212
+ for (const [key, value] of Object.entries(headers)) {
2213
+ if (key.charAt(0) === ":" || value == null) continue;
2214
+ responseHeaders[key] = Array.isArray(value) ? value.join(", ") : String(value);
2215
+ }
2216
+ });
2217
+ stream.on("data", (chunk) => chunks.push(chunk));
2218
+ stream.once("end", () =>
2219
+ settle(() => resolve({ status: status, headers: responseHeaders, body: Buffer.concat(chunks) })),
2220
+ );
2221
+ stream.once("error", (error) =>
2222
+ settle(() => reject(error instanceof Error ? error : new Error(String(error)))),
2223
+ );
2224
+ stream.once("aborted", () => settle(() => reject(new Error("Bridge HTTP/2 stream aborted."))));
2225
+ if (request.body.length > 0) {
2226
+ stream.end(request.body);
2227
+ } else if (!stream.writableEnded) {
2228
+ stream.end();
2229
+ }
2230
+ });
2231
+ }
2232
+
2233
+ const server = createServer(async (req, res) => {
2234
+ // readBodyBytes reserves the body's bytes against the process ledger
2235
+ // and hands back a release function; this holds it so the finally
2236
+ // below releases those bytes exactly once no matter how this handler
2237
+ // ends — its normal completion, a thrown error, a client abort, or a
2238
+ // deadline timeout all reach the same finally.
2239
+ let releaseBodyReservation = null;
2240
+ try {
2241
+ const auth = req.headers.authorization || "";
2242
+ const receivedToken = auth.startsWith("Bearer ") ? auth.slice("Bearer ".length) : "";
2243
+ if (!tokensMatch(receivedToken)) {
2244
+ writeJsonResponse(res, 401, { error: "Invalid bridge token." });
2245
+ return;
2246
+ }
2247
+ if (unavailable) {
2248
+ writeJsonResponse(res, 503, { error: "bridge_unavailable" });
2249
+ return;
2250
+ }
2251
+ const url = new URL(req.url || "/", "http://127.0.0.1");
2252
+ const { body: requestBodyBuffer, release } = await readBodyBytes(req);
2253
+ releaseBodyReservation = release;
2254
+ let response;
2255
+ try {
2256
+ response = await forwardOverHttp2({
2257
+ method: req.method || "GET",
2258
+ path: url.pathname,
2259
+ query: url.search,
2260
+ headers: normalizeHeaders(req.headers),
2261
+ body: requestBodyBuffer,
2262
+ });
2263
+ } catch (error) {
2264
+ writeJsonResponse(res, 502, { error: error instanceof Error ? error.message : String(error) });
2265
+ return;
2266
+ }
2267
+ // The host marks a possibly-committed mutation with an indeterminate outcome.
2268
+ // The host cannot cancel a host operation that is in flight, so the mutation
2269
+ // may have committed before the worker aborted the handler. A 5xx status is
2270
+ // retryable by convention, so a caller that retries 5xx would apply the
2271
+ // mutation twice. Map the indeterminate outcome to a non-retryable 409, so a
2272
+ // standard retry policy does not repeat the request. The outcome header and
2273
+ // body stay, so a caller that reads them still sees the indeterminate result.
2274
+ const bridgeOutcome = (response.headers || {})["x-paperclip-bridge-outcome"];
2275
+ if (bridgeOutcome === "indeterminate") {
2276
+ res.statusCode = 409;
2277
+ } else {
2278
+ res.statusCode = typeof response.status === "number" ? response.status : 200;
2279
+ }
2280
+ for (const [key, value] of Object.entries(response.headers || {})) {
2281
+ if (typeof value !== "string" || key.toLowerCase() === "content-length") continue;
2282
+ res.setHeader(key, value);
2283
+ }
2284
+ res.end(response.body);
2285
+ } catch (error) {
2286
+ // A denied process-ledger reservation is retryable: the caller should
2287
+ // try again once other in-flight bodies release their bytes. Every
2288
+ // other body-read or handling fault stays a generic 502.
2289
+ const status = error instanceof BridgeProcessCapacityError ? 503 : 502;
2290
+ writeJsonResponse(res, status, { error: error instanceof Error ? error.message : String(error) });
2291
+ } finally {
2292
+ releaseBodyReservation?.();
2293
+ }
2294
+ });
2295
+
2296
+ process.on("SIGINT", () => {
2297
+ try {
2298
+ server.close();
2299
+ } catch (error) {
2300
+ diag("server close error: " + (error && error.message ? error.message : String(error)));
2301
+ }
2302
+ process.exit(0);
2303
+ });
2304
+ process.on("SIGTERM", () => {
2305
+ try {
2306
+ server.close();
2307
+ } catch (error) {
2308
+ diag("server close error: " + (error && error.message ? error.message : String(error)));
2309
+ }
2310
+ process.exit(0);
2311
+ });
2312
+
2313
+ // Bind-or-exit, the same rule every mode applies: the host assigns a
2314
+ // positive loopback port, and the gateway binds exactly that port or exits
2315
+ // nonzero. It never selects a different port.
2316
+ if (!Number.isInteger(port) || port <= 0) {
2317
+ diag("http2 gateway requires a positive assigned PAPERCLIP_BRIDGE_PORT; got " + String(port));
2318
+ process.exit(1);
2319
+ }
2320
+ server.on("error", (error) => {
2321
+ diag(
2322
+ "http2 gateway could not bind port " +
2323
+ String(port) +
2324
+ ": " +
2325
+ (error && error.message ? error.message : String(error)),
2326
+ );
2327
+ process.exit(1);
2328
+ });
2329
+ server.listen(port, host, () => {
2330
+ const address = server.address();
2331
+ if (!address || typeof address === "string") {
2332
+ diag("http2 gateway did not expose a TCP address");
2333
+ process.exit(1);
2334
+ return;
2335
+ }
2336
+ // Send the one frame-codec line on this path: the READY line the host
2337
+ // readiness gate expects. Open the HTTP/2 client session on the very next
2338
+ // statement, so the client connection preface is the next byte the host
2339
+ // sees after READY, with no other writer in between.
2340
+ writeFrame({ version: DUPLEX_FRAME_VERSION, type: "ready", nonce: bridgeNonce });
2341
+ gatewayReady = true;
2342
+ openSession();
2343
+ });
2344
+ }
2345
+
2346
+ // The startup check above already rejected every value except http2 and
2347
+ // queue, so this dispatch names both modes explicitly and never falls
2348
+ // through to the queue gateway for an unsupported mode.
2349
+ if (bridgeMode === "${SANDBOX_CALLBACK_BRIDGE_HTTP2_MODE}") {
2350
+ runHttp2Gateway();
2351
+ } else if (bridgeMode === "${SANDBOX_CALLBACK_BRIDGE_FILE_MODE}") {
2352
+ await runFileGateway();
2353
+ } else {
2354
+ throw new Error("Unsupported PAPERCLIP_API_BRIDGE_MODE: " + bridgeMode);
2355
+ }`;
2356
+ }
2357
+ //# sourceMappingURL=sandbox-callback-bridge.js.map