sliccy 6.211.0 → 6.212.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 (195) hide show
  1. package/dist/node-server/_shared/index.d.ts +1 -0
  2. package/dist/node-server/_shared/index.d.ts.map +1 -1
  3. package/dist/node-server/_shared/index.js +1 -0
  4. package/dist/node-server/_shared/index.js.map +1 -1
  5. package/dist/node-server/_shared/raw-fetch-protocol.d.ts +149 -0
  6. package/dist/node-server/_shared/raw-fetch-protocol.d.ts.map +1 -0
  7. package/dist/node-server/_shared/raw-fetch-protocol.js +296 -0
  8. package/dist/node-server/_shared/raw-fetch-protocol.js.map +1 -0
  9. package/dist/node-server/fetch-proxy-headers.d.ts +3 -1
  10. package/dist/node-server/fetch-proxy-headers.js +5 -1
  11. package/dist/node-server/index.js +14 -3
  12. package/dist/node-server/routes/fetch-proxy-raw.d.ts +43 -0
  13. package/dist/node-server/routes/fetch-proxy-raw.js +205 -0
  14. package/dist/node-server/routes/fetch-proxy.d.ts +23 -0
  15. package/dist/node-server/routes/fetch-proxy.js +4 -3
  16. package/dist/ui/.vite/manifest.json +182 -182
  17. package/dist/ui/assets/SKILL-CN4LOg1h.js +1 -0
  18. package/dist/ui/assets/{account-store-CwNcf5Wq.js → account-store-DdclMpWp.js} +1 -1
  19. package/dist/ui/assets/{account-store-nlKbTUhJ.js → account-store-DnIs5WZM.js} +1 -1
  20. package/dist/ui/assets/{adobe-DBVa9oOG.js → adobe-BNRJjQn6.js} +1 -1
  21. package/dist/ui/assets/{adobe-D7sqH2X_.js → adobe-w_RhhSWv.js} +1 -1
  22. package/dist/ui/assets/{agent-panels-B0VuA3mU.js → agent-panels-B-6e5X0F.js} +1 -1
  23. package/dist/ui/assets/{almost-bash-shell-headless-C0x2DyFh.js → almost-bash-shell-headless-D19kpvHY.js} +154 -149
  24. package/dist/ui/assets/{apply-layout-fciODM2t.js → apply-layout-oUk89jk1.js} +1 -1
  25. package/dist/ui/assets/{apps-RVxpwEfn.js → apps-oJ_nTgiK.js} +1 -1
  26. package/dist/ui/assets/{azure-openai-QS8TU-7m.js → azure-openai-BKBBD2Dq.js} +1 -1
  27. package/dist/ui/assets/{azure-openai-JxdRj-Iq.js → azure-openai-zqUyJv0c.js} +1 -1
  28. package/dist/ui/assets/{backend-hostfs-CITljQVo.js → backend-hostfs-BotdHD_S.js} +1 -1
  29. package/dist/ui/assets/{bsh-watchdog-BTB0exmo.js → bsh-watchdog-TYuawE-B.js} +1 -1
  30. package/dist/ui/assets/{cdp-Djm-AVXd.js → cdp-C0InCdRQ.js} +1 -1
  31. package/dist/ui/assets/{cerebras-DvIFsdoW.js → cerebras-ChWjfEi0.js} +1 -1
  32. package/dist/ui/assets/{cerebras-Czq0QoYg.js → cerebras-DL4U9Vjg.js} +1 -1
  33. package/dist/ui/assets/{client-CwxmlQM-.js → client-dISfU5Wf.js} +1 -1
  34. package/dist/ui/assets/{composer-speech-DgLXFFNQ.js → composer-speech-d-ejBNSK.js} +1 -1
  35. package/dist/ui/assets/{connect-surface-YjzKwUub.js → connect-surface-DNUrGg9g.js} +1 -1
  36. package/dist/ui/assets/{core-C7UGykIC.js → core-DZ0CleVD.js} +2 -2
  37. package/dist/ui/assets/{directed-approval-BMnSWjrJ.js → directed-approval-ol0Z6v9I.js} +1 -1
  38. package/dist/ui/assets/{emscripten-vfs-hook-CwbQLP-I.js → emscripten-vfs-hook-fCUbQRCb.js} +1 -1
  39. package/dist/ui/assets/{ensure-speech-assets-Bqf-swhU.js → ensure-speech-assets-S71yPbdv.js} +1 -1
  40. package/dist/ui/assets/{esbuild-wasm-DIcMVR3g.js → esbuild-wasm-llEEkCQu.js} +1 -1
  41. package/dist/ui/assets/{extension-ops-CF2mLDRW.js → extension-ops-CEprwZyb.js} +1 -1
  42. package/dist/ui/assets/{ffmpeg-wasm-B5jofhIa.js → ffmpeg-wasm-DGDKCZ27.js} +1 -1
  43. package/dist/ui/assets/{frozen-archive-writer-BV51qDTg.js → frozen-archive-writer-khicEqGd.js} +1 -1
  44. package/dist/ui/assets/{fs-ZnsLbva1.js → fs-CIR1p_m7.js} +1 -1
  45. package/dist/ui/assets/{fs-pBJBtnUm.js → fs-D6QJU-ZE.js} +2 -2
  46. package/dist/ui/assets/{gelatiere-store-B-PMFWOJ.js → gelatiere-store-CYdUzk1p.js} +1 -1
  47. package/dist/ui/assets/{gelatiere-unit-B7YUbTOe.js → gelatiere-unit-Dzkphhv5.js} +1 -1
  48. package/dist/ui/assets/{github-CRKKUq6c.js → github-8QTzsnR3.js} +1 -1
  49. package/dist/ui/assets/{github-q7aLpavT.js → github-BdQ6NNi6.js} +2 -2
  50. package/dist/ui/assets/{github-auth-DPBopdHy.js → github-auth-CgSRRmdA.js} +1 -1
  51. package/dist/ui/assets/{github-copilot-Cn5WeEVQ.js → github-copilot-Beq3TkEz.js} +1 -1
  52. package/dist/ui/assets/{github-copilot-BOqjn_pA.js → github-copilot-C6ZXCgIT.js} +1 -1
  53. package/dist/ui/assets/{github-install-Dlx1x9oP.js → github-install-BV6F_EyI.js} +1 -1
  54. package/dist/ui/assets/{github-zip-BKesEE7T.js → github-zip-nn7aW2E1.js} +1 -1
  55. package/dist/ui/assets/{guest-tool-gate-DbuM_BFG.js → guest-tool-gate-4cZHoDbf.js} +1 -1
  56. package/dist/ui/assets/{hear-BAlAHUln.js → hear-HND90jpV.js} +1 -1
  57. package/dist/ui/assets/{help-MPD6QjSi.js → help-Dgt88ySg.js} +1 -1
  58. package/dist/ui/assets/{installer-DR7izkMG.js → installer-BdG_mJUp.js} +1 -1
  59. package/dist/ui/assets/{interrupted-work-recovery-DKlfO3Dk.js → interrupted-work-recovery-niFgJlYA.js} +1 -1
  60. package/dist/ui/assets/{ipk-mamba-B7DsVAHB.js → ipk-mamba-DMPz0Na-.js} +1 -1
  61. package/dist/ui/assets/{js-realm-worker-Dj6E7cem.js → js-realm-worker-Dt6CkC-q.js} +2 -2
  62. package/dist/ui/assets/{jsh-executor-DOTwZy5W.js → jsh-executor-m_BRqJJW.js} +2 -2
  63. package/dist/ui/assets/{kernel-worker-C6evRbt8.js → kernel-worker-Bejt-Ojz.js} +10 -10
  64. package/dist/ui/assets/{lick-ws-bridge-DEO3vHuX.js → lick-ws-bridge-DoT1E5ir.js} +1 -1
  65. package/dist/ui/assets/{lick-ws-bridge-cpYoem5_.js → lick-ws-bridge-Nul1wz09.js} +1 -1
  66. package/dist/ui/assets/{live-session-curation-BM8tZX-r.js → live-session-curation-BKsScSRB.js} +1 -1
  67. package/dist/ui/assets/{live-session-snapshot-C2NMVRMF.js → live-session-snapshot-6V9mPUM5.js} +1 -1
  68. package/dist/ui/assets/{local-llm-Cfh9VuPq.js → local-llm-C0NdLczW.js} +1 -1
  69. package/dist/ui/assets/{local-llm-z-cBJlKf.js → local-llm-DoZ2LiSE.js} +1 -1
  70. package/dist/ui/assets/{magick-wasm-agWGi-e0.js → magick-wasm-BL5NYmcE.js} +1 -1
  71. package/dist/ui/assets/{main-tEtVPbXh.js → main-DmLxMDGT.js} +3 -3
  72. package/dist/ui/assets/{main-cherry-CbQUCau8.js → main-cherry-C3pK2VKW.js} +1 -1
  73. package/dist/ui/assets/{memory-curation-seam-CjBglHNa.js → memory-curation-seam-B_5OPYdP.js} +1 -1
  74. package/dist/ui/assets/{memory-health-CPzWzT1P.js → memory-health-CRH2Blzq.js} +1 -1
  75. package/dist/ui/assets/{memory-write-execute-DqWqBfwf.js → memory-write-execute-BfCExMYN.js} +1 -1
  76. package/dist/ui/assets/{merge-folded-cost-into-frozen-DCuPhNTk.js → merge-folded-cost-into-frozen-CoL4Bfzs.js} +1 -1
  77. package/dist/ui/assets/{mount-ydk0WHgG.js → mount-B3v77n4z.js} +3 -3
  78. package/dist/ui/assets/{mount-4dZRjkrQ.js → mount-TnWJttSG.js} +1 -1
  79. package/dist/ui/assets/{mount-bridge-client-Dz_UHbPE.js → mount-bridge-client-DkrmF1xh.js} +1 -1
  80. package/dist/ui/assets/{new-session-C5MEP_cK.js → new-session-C8MNLQeR.js} +2 -2
  81. package/dist/ui/assets/{oauth-bootstrap-BVUK3GEs.js → oauth-bootstrap-BW3jawLe.js} +2 -2
  82. package/dist/ui/assets/{oauth-service-DP3Rx6V_.js → oauth-service-B_A2Hp66.js} +1 -1
  83. package/dist/ui/assets/{onboarding-orchestrator-DftSEsKa.js → onboarding-orchestrator-Ca5D3wWS.js} +1 -1
  84. package/dist/ui/assets/{openai-codex-fJtQGV69.js → openai-codex-B-c0ZWNV.js} +1 -1
  85. package/dist/ui/assets/{openai-codex-Cwz1FT-z.js → openai-codex-CMsdDz1G.js} +1 -1
  86. package/dist/ui/assets/{openrouter-rcqoBXaw.js → openrouter-B7Sm8SVp.js} +1 -1
  87. package/dist/ui/assets/{openrouter-DmEz5WxK.js → openrouter-ChF-ckvt.js} +1 -1
  88. package/dist/ui/assets/{openrouter-free-C5O97xvy.js → openrouter-free-D6PoJTox.js} +1 -1
  89. package/dist/ui/assets/{openrouter-free-DRw-DHQn.js → openrouter-free-F9UehDw-.js} +1 -1
  90. package/dist/ui/assets/{openrouter-oauth-Csq32wt2.js → openrouter-oauth-CWDz3gd8.js} +1 -1
  91. package/dist/ui/assets/{openrouter-oauth-C4uIzDcA.js → openrouter-oauth-ClC2jnRu.js} +1 -1
  92. package/dist/ui/assets/{opfs-mount-C0Lus0Cz.js → opfs-mount-mkZhMkc1.js} +1 -1
  93. package/dist/ui/assets/{panel-rpc-handlers-B9LenTR0.js → panel-rpc-handlers-BGopQTZk.js} +2 -2
  94. package/dist/ui/assets/{panelize-shell-Dzogbbfc.js → panelize-shell-RRJ2rlAy.js} +1 -1
  95. package/dist/ui/assets/{pi-edit-execution-D9D4FDIQ.js → pi-edit-execution-Cn6P8kEd.js} +1 -1
  96. package/dist/ui/assets/{port-bridge-client-B-l7cQTC.js → port-bridge-client-DvO4atpq.js} +1 -1
  97. package/dist/ui/assets/{provider-CTPdODd7.js → provider-BkkOFpKq.js} +1 -1
  98. package/dist/ui/assets/{provider-Do-gc4OB.js → provider-CFbeLwlx.js} +2 -2
  99. package/dist/ui/assets/{provider-settings-DzDdkFMx.js → provider-settings-Df1UWum6.js} +1 -1
  100. package/dist/ui/assets/provider-store-access-440PUQnq.js +1 -0
  101. package/dist/ui/assets/provider-store-access-ioP6z6ei.js +1 -0
  102. package/dist/ui/assets/{providers-1_CCXdq3.js → providers-DelYSiJM.js} +2 -2
  103. package/dist/ui/assets/{providers-BdG-aC29.js → providers-narfgv33.js} +1 -1
  104. package/dist/ui/assets/proxied-fetch-Ba8A2Dlh.js +1 -0
  105. package/dist/ui/assets/proxied-fetch-raw-CzaxeyeU.js +1 -0
  106. package/dist/ui/assets/proxy-error-BVzVNPvv.js +1 -0
  107. package/dist/ui/assets/{quick-llm-B07QXQ0s.js → quick-llm-t5wZbj0G.js} +1 -1
  108. package/dist/ui/assets/{realm-inprocess-wC9VuVQf.js → realm-inprocess-DIZ0NkAs.js} +2 -2
  109. package/dist/ui/assets/{realm-unhandled-rejections-CEAHL08q.js → realm-unhandled-rejections-BIyM8soC.js} +1 -1
  110. package/dist/ui/assets/{realm-unhandled-rejections-CuAh-NpD.js → realm-unhandled-rejections-DzT6eKFi.js} +1 -1
  111. package/dist/ui/assets/{recovery-screen-mPjIBgPH.js → recovery-screen-DvZoe1eu.js} +1 -1
  112. package/dist/ui/assets/{redirect-uri-CBCnYKsl.js → redirect-uri-DvNqGm3U.js} +1 -1
  113. package/dist/ui/assets/{remote-terminal-view-DTmUlQlW.js → remote-terminal-view-BeYl7akD.js} +2 -2
  114. package/dist/ui/assets/{require-guards-CyhsDWYg.js → require-guards-Du4bUc9R.js} +1 -1
  115. package/dist/ui/assets/{resolver-BjX48SSL.js → resolver-Cuxoosmc.js} +4 -4
  116. package/dist/ui/assets/{rest-ops-CLliBy-9.js → rest-ops-B4SFZmC5.js} +1 -1
  117. package/dist/ui/assets/{restore-BSMRZD-l.js → restore-B7CtAq9P.js} +1 -1
  118. package/dist/ui/assets/{run-CyMKLTKU.js → run-BBYfg5ni.js} +1 -1
  119. package/dist/ui/assets/run-BUXpkB7_.js +14 -0
  120. package/dist/ui/assets/{run-CM8a7Cc3.js → run-BVpDhce0.js} +1 -1
  121. package/dist/ui/assets/{run-C8OfqJcF.js → run-BySbsyjF.js} +2 -2
  122. package/dist/ui/assets/{run-CJfA-Obt.js → run-C2YgBAHx.js} +1 -1
  123. package/dist/ui/assets/{run-DMO7-CuA.js → run-DVDUpupT.js} +1 -1
  124. package/dist/ui/assets/{run-BSt_FVlm.js → run-DkUy3OHx.js} +2 -2
  125. package/dist/ui/assets/{run-KLXVoIYy.js → run-DpwgbNbp.js} +1 -1
  126. package/dist/ui/assets/{run-BoxCVicT.js → run-NrNIVu5b.js} +3 -3
  127. package/dist/ui/assets/{run-CjBpwwpL.js → run-VCYF-r1b.js} +1 -1
  128. package/dist/ui/assets/{screencapture-run-C3Y7V44Z.js → screencapture-run-DUAmyetz.js} +1 -1
  129. package/dist/ui/assets/{secrets-bridge-client-BiJrSKN9.js → secrets-bridge-client-Cxg_UIbw.js} +1 -1
  130. package/dist/ui/assets/{session-command-memory-D9pTlYAY.js → session-command-memory-CwZxueuC.js} +2 -2
  131. package/dist/ui/assets/{session-jsonl-AoJrx9pb.js → session-jsonl-B0APtun9.js} +1 -1
  132. package/dist/ui/assets/{session-jsonl-CJzYIghQ.js → session-jsonl-Bf2fgFhg.js} +1 -1
  133. package/dist/ui/assets/{session-search-index-qOmoZUJy.js → session-search-index-Cj0yWWuZ.js} +1 -1
  134. package/dist/ui/assets/{setup-feature-flags-remote-BKACONdE.js → setup-feature-flags-remote-DobdVTx1.js} +1 -1
  135. package/dist/ui/assets/{setup-model-catalog-WWCUCy79.js → setup-model-catalog-D4LHaeXg.js} +1 -1
  136. package/dist/ui/assets/{shared-Crk4gYF8.js → shared-dvo4ZY2y.js} +1 -1
  137. package/dist/ui/assets/{signed-fetch-CwZ1-qSJ.js → signed-fetch-i5c9uHzg.js} +1 -1
  138. package/dist/ui/assets/{silent-renew-backoff-L4eA7UKO.js → silent-renew-backoff-BUgLOZtF.js} +1 -1
  139. package/dist/ui/assets/slicc-version-CyiNVflt.js +1 -0
  140. package/dist/ui/assets/{snapshot-D4DlVVCr.js → snapshot-CxBYeic7.js} +1 -1
  141. package/dist/ui/assets/{snapshot-features-Cp2XSvVD.js → snapshot-features-D9YdXtgT.js} +1 -1
  142. package/dist/ui/assets/{soundscape-CcHroDUu.js → soundscape-VpddA9af.js} +1 -1
  143. package/dist/ui/assets/{speak-5UMXEj6t.js → speak-DU6xYfaW.js} +1 -1
  144. package/dist/ui/assets/{sprinkle-manager-ByfWs52B.js → sprinkle-manager-B23UQfKW.js} +1 -1
  145. package/dist/ui/assets/{sprinkle-renderer-Dw0Oo-mB.js → sprinkle-renderer-D_eHK453.js} +1 -1
  146. package/dist/ui/assets/{ssh-ChyTtRdf.js → ssh-DYTFFLnN.js} +1 -1
  147. package/dist/ui/assets/{state-BPcLy39T.js → state-BEL8NQ3N.js} +1 -1
  148. package/dist/ui/assets/{store-BA5jRQLQ.js → store-C8pkV9xX.js} +1 -1
  149. package/dist/ui/assets/{store-BCOFBOmf.js → store-Ce8lHof4.js} +1 -1
  150. package/dist/ui/assets/{sudo-CZL3U0lj.js → sudo-Dz77pSRv.js} +1 -1
  151. package/dist/ui/assets/{supervisor-n5AQXVdz.js → supervisor-CODgsiun.js} +1 -1
  152. package/dist/ui/assets/{sync-dialog-CLv-AjS5.js → sync-dialog-DEd-6_ea.js} +1 -1
  153. package/dist/ui/assets/{transformers-env-DuP48CFD.js → transformers-env-DDxx-_yr.js} +1 -1
  154. package/dist/ui/assets/{tray-leader-oK24Tenu.js → tray-leader-PwhN5FVH.js} +1 -1
  155. package/dist/ui/assets/{tray-leave-runtime-BtmhGDJl.js → tray-leave-runtime-BLeKsvgA.js} +1 -1
  156. package/dist/ui/assets/{tray-runtime-config-CTm013-K.js → tray-runtime-config-CEuo4NwB.js} +1 -1
  157. package/dist/ui/assets/{tray-sidecar-x9PQcB2n.js → tray-sidecar-B5Rwvi0w.js} +1 -1
  158. package/dist/ui/assets/{turn-journal-CScxev4H.js → turn-journal-DgrDAXyz.js} +1 -1
  159. package/dist/ui/assets/{upgrade-detection-DS5evAII.js → upgrade-detection-DkrC9knp.js} +1 -1
  160. package/dist/ui/assets/{upskill-lick-skip-DsgHyVv5.js → upskill-lick-skip-x-HPkkoo.js} +1 -1
  161. package/dist/ui/assets/{voice-reply-ebSU1_qk.js → voice-reply-DN-og12Q.js} +1 -1
  162. package/dist/ui/assets/{wc-attach-525SvDTY.js → wc-attach-BxBMMvBD.js} +2 -2
  163. package/dist/ui/assets/{wc-browser-BWykEy-8.js → wc-browser-Bx_tyqby.js} +1 -1
  164. package/dist/ui/assets/{wc-computers-D3Avqz55.js → wc-computers--Hh_a1eS.js} +1 -1
  165. package/dist/ui/assets/{wc-detached-Cy1E6He4.js → wc-detached-Cfb7cdsS.js} +1 -1
  166. package/dist/ui/assets/{wc-extension-CVhWXV2w.js → wc-extension-DtmFrIBz.js} +2 -2
  167. package/dist/ui/assets/{wc-follower-C1kJ0lF_.js → wc-follower-CY8MJG2d.js} +3 -3
  168. package/dist/ui/assets/{wc-follower-oauth-qqfI5zJ5.js → wc-follower-oauth-Qp2Onk42.js} +1 -1
  169. package/dist/ui/assets/{wc-gelatiere-DFV5mBJW.js → wc-gelatiere-CIqpoRvp.js} +1 -1
  170. package/dist/ui/assets/{wc-live-Eu6ghZAo.js → wc-live-kIulpDGT.js} +5 -5
  171. package/dist/ui/assets/{wc-nav-BJ1Fg_hB.js → wc-nav-CKLAJB62.js} +2 -2
  172. package/dist/ui/assets/{wc-onboarding-D_k6jMGA.js → wc-onboarding-CCfbxIFk.js} +2 -2
  173. package/dist/ui/assets/{wc-permissions-CbwZeya-.js → wc-permissions-gkkaKIYQ.js} +2 -2
  174. package/dist/ui/assets/{wc-placeholder-DzHKpyEK.js → wc-placeholder-CPbGysCM.js} +3 -3
  175. package/dist/ui/assets/{wc-secret-request-bOcP6m9U.js → wc-secret-request-C-t_JIqx.js} +1 -1
  176. package/dist/ui/assets/{wc-settings-BNekAbpv.js → wc-settings-C3gOS2HO.js} +3 -3
  177. package/dist/ui/assets/{wc-shell-DdE40qZj.js → wc-shell-C5TUWPbD.js} +3 -3
  178. package/dist/ui/assets/{wc-shortcut-config-KdvTJp27.js → wc-shortcut-config-CxyrO44G.js} +1 -1
  179. package/dist/ui/assets/{wc-sprinkles-Bnnb88mU.js → wc-sprinkles-CdV_-XON.js} +2 -2
  180. package/dist/ui/assets/{wc-transcript-export-DWOEgP2-.js → wc-transcript-export-uviFziTO.js} +2 -2
  181. package/dist/ui/assets/{wc-tray-Dpx-EoMd.js → wc-tray-C_LlCq8n.js} +4 -4
  182. package/dist/ui/assets/welcome-detection-62JgQjpE.js +1 -0
  183. package/dist/ui/assets/{whisper-session-CB6rG-eD.js → whisper-session-DpmN2H-S.js} +2 -2
  184. package/dist/ui/assets/{xai-grok-CuIlQYpM.js → xai-grok-DqHHYruF.js} +1 -1
  185. package/dist/ui/assets/{xai-grok-BGPDFi9z.js → xai-grok-Qkm8D-bR.js} +1 -1
  186. package/dist/ui/index.html +3 -3
  187. package/dist/ui/packages/webapp/index.html +3 -3
  188. package/package.json +1 -1
  189. package/dist/ui/assets/SKILL-lcwLWMKp.js +0 -1
  190. package/dist/ui/assets/provider-store-access-BbvRUwZT.js +0 -1
  191. package/dist/ui/assets/provider-store-access-CrrW9eCi.js +0 -1
  192. package/dist/ui/assets/proxied-fetch-DXaTHROw.js +0 -1
  193. package/dist/ui/assets/run-Y1uUJvV7.js +0 -14
  194. package/dist/ui/assets/slicc-version-jRBuHQmT.js +0 -1
  195. package/dist/ui/assets/welcome-detection-BdEfH_d7.js +0 -1
@@ -21,6 +21,7 @@ export * from './loopback.js';
21
21
  export * from './oauth-extra-domains-storage.js';
22
22
  export * from './preview-url.js';
23
23
  export * from './proxy-headers.js';
24
+ export * from './raw-fetch-protocol.js';
24
25
  export * from './runtime-env.js';
25
26
  export * from './secret-env-schema.js';
26
27
  export * from './secret-masking.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,cAAc,uBAAuB,CAAC;AACtC,cAAc,aAAa,CAAC;AAC5B,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,kCAAkC,CAAC;AACjD,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,YAAY,CAAC;AAC3B,cAAc,oBAAoB,CAAC;AACnC,cAAc,cAAc,CAAC;AAC7B,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,cAAc,uBAAuB,CAAC;AACtC,cAAc,aAAa,CAAC;AAC5B,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,kCAAkC,CAAC;AACjD,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC;AACxC,cAAc,kBAAkB,CAAC;AACjC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,YAAY,CAAC;AAC3B,cAAc,oBAAoB,CAAC;AACnC,cAAc,cAAc,CAAC;AAC7B,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC"}
@@ -22,6 +22,7 @@ export * from './loopback.js';
22
22
  export * from './oauth-extra-domains-storage.js';
23
23
  export * from './preview-url.js';
24
24
  export * from './proxy-headers.js';
25
+ export * from './raw-fetch-protocol.js';
25
26
  export * from './runtime-env.js';
26
27
  export * from './secret-env-schema.js';
27
28
  export * from './secret-masking.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iFAAiF;AAEjF,cAAc,uBAAuB,CAAC;AACtC,cAAc,aAAa,CAAC;AAC5B,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,kCAAkC,CAAC;AACjD,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,YAAY,CAAC;AAC3B,cAAc,oBAAoB,CAAC;AACnC,cAAc,cAAc,CAAC;AAC7B,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iFAAiF;AAEjF,cAAc,uBAAuB,CAAC;AACtC,cAAc,aAAa,CAAC;AAC5B,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,kCAAkC,CAAC;AACjD,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC;AACxC,cAAc,kBAAkB,CAAC;AACjC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,YAAY,CAAC;AAC3B,cAAc,oBAAoB,CAAC;AACnC,cAAc,cAAc,CAAC;AAC7B,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC"}
@@ -0,0 +1,149 @@
1
+ /**
2
+ * Raw-mode fetch-proxy contract (#3571). The default proxied fetch behaves like
3
+ * a browser (follows redirects, folds Set-Cookie into an out-of-band header,
4
+ * buffers bodies). Raw mode behaves like an HTTP client, so the wasm realm's
5
+ * HTTP proxy can hand each response to curl or git as the origin sent it:
6
+ *
7
+ * - redirects are NOT followed; the 3xx, `Location` and `Set-Cookie` reach
8
+ * the caller;
9
+ * - headers travel as an ordered name/value list, so every `Set-Cookie`
10
+ * stays a separate entry;
11
+ * - the body is always delivered DECODED: `Content-Encoding` is removed
12
+ * whenever a coding was undone, and `Content-Length` survives only when
13
+ * it still counts the delivered bytes (see {@link rawResponseHeaders});
14
+ * - the body streams, and nothing is read from the float's hop until the
15
+ * caller asks. Chrome's own `fetch` still reads a response off the
16
+ * network ahead of the reader (measured on Chrome 146: 400 MiB drained
17
+ * while a page held one chunk), so the upstream itself is not throttled.
18
+ *
19
+ * Every float speaks this contract; each one frames it for its own hop. The
20
+ * CLI/cloud node-server route reads the request head from
21
+ * {@link RAW_FETCH_REQUEST_HEADER} and answers `200` with
22
+ * {@link RAW_FETCH_CONTENT_TYPE}, whose body is one response-head frame
23
+ * ({@link encodeRawResponseFrame}) followed by the upstream body bytes.
24
+ */
25
+ /** Ordered header list. Names keep their case; repeats stay separate. */
26
+ export type RawHeaderList = Array<[string, string]>;
27
+ /** What the caller wants sent upstream. */
28
+ export interface RawFetchRequestHead {
29
+ url: string;
30
+ method: string;
31
+ headers: RawHeaderList;
32
+ }
33
+ /** What the upstream answered, before the body. */
34
+ export interface RawFetchResponseHead {
35
+ status: number;
36
+ statusText: string;
37
+ headers: RawHeaderList;
38
+ /** The URL that answered; with manual redirects always the request URL. */
39
+ url: string;
40
+ }
41
+ /**
42
+ * Request header carrying the JSON {@link RawFetchRequestHead} on the
43
+ * node-server hop. The hop itself is always `POST` so neither the method nor
44
+ * the caller's headers are subject to the browser's forbidden-name filter.
45
+ * Its presence (instead of `X-Target-URL`) is what selects raw mode, so a
46
+ * bridge that predates raw mode answers 400 rather than sending the request
47
+ * the default way.
48
+ */
49
+ export declare const RAW_FETCH_REQUEST_HEADER = "X-Slicc-Raw-Request";
50
+ /**
51
+ * Capability probe on the node-server hop: a `POST /api/fetch-proxy` carrying
52
+ * only this header (no `X-Target-URL`, no request head). A bridge with raw
53
+ * mode answers `200` JSON {@link RawFetchProbeReply}; one without it answers
54
+ * 400 (node-server before raw mode, swift-server) or 404 (no bridge at all),
55
+ * and nothing is fetched upstream either way.
56
+ */
57
+ export declare const RAW_FETCH_PROBE_HEADER = "X-Slicc-Raw-Probe";
58
+ /** Raw-mode protocol revision a bridge reports in its probe reply. */
59
+ export declare const RAW_FETCH_PROTOCOL_VERSION = 1;
60
+ /** What a raw-capable bridge reports about itself. */
61
+ export interface RawFetchProbeReply {
62
+ rawFetch: number;
63
+ requestBodyStreaming: boolean;
64
+ maxRequestBodyBytes: number;
65
+ }
66
+ /** Validate a probe reply; `null` when it is not one. */
67
+ export declare function parseRawFetchProbeReply(value: unknown): RawFetchProbeReply | null;
68
+ /** Content type of a raw-mode answer on the node-server hop. */
69
+ export declare const RAW_FETCH_CONTENT_TYPE = "application/vnd.slicc.raw-fetch";
70
+ /**
71
+ * Request-body ceiling on the node-server hop (CLI and cloud). This hop
72
+ * buffers the upload on both ends for now; past this size the bridge answers
73
+ * 413 and the webapp refuses before sending.
74
+ */
75
+ export declare const RAW_FETCH_BRIDGE_REQUEST_BODY_CAP: number;
76
+ /** Upper bound on one encoded response-head frame. */
77
+ export declare const RAW_FETCH_MAX_HEAD_BYTES: number;
78
+ /** `Accept-Encoding` a float sends upstream: exactly the codings it decodes. */
79
+ export declare const RAW_FETCH_ACCEPT_ENCODING = "gzip, deflate, br";
80
+ /**
81
+ * The `Accept-Encoding` a float sets for a request with these (folded,
82
+ * lowercase) headers, or `undefined` to set none. A ranged request (`Range`,
83
+ * `If-Range`) must not offer a compressed coding: a 206 over a compressed
84
+ * representation carries `Content-Range` offsets into the compressed bytes,
85
+ * which no longer describe the body once the float decodes it, so a resumed
86
+ * or ranged download would assemble corrupt data. With no `Accept-Encoding`
87
+ * set, `fetch` itself sends `identity` for a request carrying `Range` (Fetch
88
+ * standard, HTTP-network-or-cache fetch), in Node and in Chrome alike.
89
+ */
90
+ export declare function rawAcceptEncoding(headers: Record<string, string>): string | undefined;
91
+ /**
92
+ * Whether a partial response came back with a coding the float undid
93
+ * (an origin that ignored `Accept-Encoding: identity`). Its `Content-Range`
94
+ * counts encoded bytes the caller never sees, so the float must refuse it
95
+ * rather than deliver it.
96
+ */
97
+ export declare function isDecodedPartialResponse(input: {
98
+ status: number;
99
+ headers: RawHeaderList;
100
+ }): boolean;
101
+ /** Drop hop-by-hop and float-owned request headers, keeping order. */
102
+ export declare function stripRawRequestHeaders(headers: RawHeaderList): RawHeaderList;
103
+ /**
104
+ * Fold a raw list into the name → value record `fetch` sends. Repeats join
105
+ * with `, ` (RFC 9110 §5.3), except `Cookie`, which joins with `; `. No float
106
+ * can put two lines with one name on the wire: `fetch` folds them the same way.
107
+ */
108
+ export declare function foldRawRequestHeaders(headers: RawHeaderList): Record<string, string>;
109
+ export interface RawResponseHeaderInput {
110
+ method: string;
111
+ status: number;
112
+ headers: RawHeaderList;
113
+ /**
114
+ * The float may rewrite the body (secret scrub, gunzip sniff), so the
115
+ * upstream `Content-Length` would no longer count the delivered bytes.
116
+ */
117
+ bodyRewritten: boolean;
118
+ }
119
+ /** Whether a response to `method` with `status` carries a body at all. */
120
+ export declare function rawResponseHasBody(method: string, status: number): boolean;
121
+ /**
122
+ * The head a raw caller sees. Hop-by-hop headers go, and so do the fields
123
+ * the response's `Connection` header names (RFC 9110 §7.6.1). A bodiless response
124
+ * (HEAD, 1xx/204/205/304) keeps `Content-Encoding` and `Content-Length` as
125
+ * sent, since they describe the representation, not bytes on this hop.
126
+ * Otherwise a decoded coding drops both headers, and `Content-Length` also
127
+ * goes when the float rewrote the body. An unknown coding stays with its
128
+ * encoded bytes.
129
+ */
130
+ export declare function rawResponseHeaders(input: RawResponseHeaderInput): RawHeaderList;
131
+ /**
132
+ * JSON for {@link RAW_FETCH_REQUEST_HEADER}. Non-ASCII is `\u`-escaped so the
133
+ * value is a valid header ByteString whatever the caller's headers hold.
134
+ */
135
+ export declare function encodeRawRequestHead(head: RawFetchRequestHead): string;
136
+ /** Parse a {@link RAW_FETCH_REQUEST_HEADER} value; `null` when malformed. */
137
+ export declare function decodeRawRequestHead(value: string): RawFetchRequestHead | null;
138
+ /** One response-head frame: a big-endian u32 length, then UTF-8 JSON. */
139
+ export declare function encodeRawResponseFrame(head: RawFetchResponseHead): Uint8Array;
140
+ /**
141
+ * Split a response-head frame off the front of `buffer`. Returns `null` while
142
+ * the frame is still incomplete, and throws when it is malformed or larger
143
+ * than {@link RAW_FETCH_MAX_HEAD_BYTES}.
144
+ */
145
+ export declare function decodeRawResponseFrame(buffer: Uint8Array): {
146
+ head: RawFetchResponseHead;
147
+ rest: Uint8Array;
148
+ } | null;
149
+ //# sourceMappingURL=raw-fetch-protocol.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"raw-fetch-protocol.d.ts","sourceRoot":"","sources":["../src/raw-fetch-protocol.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,yEAAyE;AACzE,MAAM,MAAM,aAAa,GAAG,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAEpD,2CAA2C;AAC3C,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,aAAa,CAAC;CACxB;AAED,mDAAmD;AACnD,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,aAAa,CAAC;IACvB,2EAA2E;IAC3E,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,wBAAwB,wBAAwB,CAAC;AAE9D;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,sBAAsB,CAAC;AAE1D,sEAAsE;AACtE,eAAO,MAAM,0BAA0B,IAAI,CAAC;AAE5C,sDAAsD;AACtD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,oBAAoB,EAAE,OAAO,CAAC;IAC9B,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAED,yDAAyD;AACzD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,kBAAkB,GAAG,IAAI,CAWjF;AAED,gEAAgE;AAChE,eAAO,MAAM,sBAAsB,oCAAoC,CAAC;AAExE;;;;GAIG;AACH,eAAO,MAAM,iCAAiC,QAAoB,CAAC;AAEnE,sDAAsD;AACtD,eAAO,MAAM,wBAAwB,QAAc,CAAC;AAoCpD,gFAAgF;AAChF,eAAO,MAAM,yBAAyB,sBAAsB,CAAC;AAE7D;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,GAAG,SAAS,CAIrF;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE;IAC9C,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,aAAa,CAAC;CACxB,GAAG,OAAO,CAOV;AA2BD,sEAAsE;AACtE,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,aAAa,GAAG,aAAa,CAM5E;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CASpF;AAWD,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,aAAa,CAAC;IACvB;;;OAGG;IACH,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,0EAA0E;AAC1E,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAE1E;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,sBAAsB,GAAG,aAAa,CAoB/E;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,mBAAmB,GAAG,MAAM,CAKtE;AAED,6EAA6E;AAC7E,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,mBAAmB,GAAG,IAAI,CAkB9E;AAED,yEAAyE;AACzE,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,oBAAoB,GAAG,UAAU,CAM7E;AAcD;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,UAAU,GACjB;IAAE,IAAI,EAAE,oBAAoB,CAAC;IAAC,IAAI,EAAE,UAAU,CAAA;CAAE,GAAG,IAAI,CAezD"}
@@ -0,0 +1,296 @@
1
+ /**
2
+ * Raw-mode fetch-proxy contract (#3571). The default proxied fetch behaves like
3
+ * a browser (follows redirects, folds Set-Cookie into an out-of-band header,
4
+ * buffers bodies). Raw mode behaves like an HTTP client, so the wasm realm's
5
+ * HTTP proxy can hand each response to curl or git as the origin sent it:
6
+ *
7
+ * - redirects are NOT followed; the 3xx, `Location` and `Set-Cookie` reach
8
+ * the caller;
9
+ * - headers travel as an ordered name/value list, so every `Set-Cookie`
10
+ * stays a separate entry;
11
+ * - the body is always delivered DECODED: `Content-Encoding` is removed
12
+ * whenever a coding was undone, and `Content-Length` survives only when
13
+ * it still counts the delivered bytes (see {@link rawResponseHeaders});
14
+ * - the body streams, and nothing is read from the float's hop until the
15
+ * caller asks. Chrome's own `fetch` still reads a response off the
16
+ * network ahead of the reader (measured on Chrome 146: 400 MiB drained
17
+ * while a page held one chunk), so the upstream itself is not throttled.
18
+ *
19
+ * Every float speaks this contract; each one frames it for its own hop. The
20
+ * CLI/cloud node-server route reads the request head from
21
+ * {@link RAW_FETCH_REQUEST_HEADER} and answers `200` with
22
+ * {@link RAW_FETCH_CONTENT_TYPE}, whose body is one response-head frame
23
+ * ({@link encodeRawResponseFrame}) followed by the upstream body bytes.
24
+ */
25
+ /**
26
+ * Request header carrying the JSON {@link RawFetchRequestHead} on the
27
+ * node-server hop. The hop itself is always `POST` so neither the method nor
28
+ * the caller's headers are subject to the browser's forbidden-name filter.
29
+ * Its presence (instead of `X-Target-URL`) is what selects raw mode, so a
30
+ * bridge that predates raw mode answers 400 rather than sending the request
31
+ * the default way.
32
+ */
33
+ export const RAW_FETCH_REQUEST_HEADER = 'X-Slicc-Raw-Request';
34
+ /**
35
+ * Capability probe on the node-server hop: a `POST /api/fetch-proxy` carrying
36
+ * only this header (no `X-Target-URL`, no request head). A bridge with raw
37
+ * mode answers `200` JSON {@link RawFetchProbeReply}; one without it answers
38
+ * 400 (node-server before raw mode, swift-server) or 404 (no bridge at all),
39
+ * and nothing is fetched upstream either way.
40
+ */
41
+ export const RAW_FETCH_PROBE_HEADER = 'X-Slicc-Raw-Probe';
42
+ /** Raw-mode protocol revision a bridge reports in its probe reply. */
43
+ export const RAW_FETCH_PROTOCOL_VERSION = 1;
44
+ /** Validate a probe reply; `null` when it is not one. */
45
+ export function parseRawFetchProbeReply(value) {
46
+ if (!value || typeof value !== 'object')
47
+ return null;
48
+ const reply = value;
49
+ if (typeof reply.rawFetch !== 'number' || reply.rawFetch < 1)
50
+ return null;
51
+ if (typeof reply.requestBodyStreaming !== 'boolean')
52
+ return null;
53
+ if (typeof reply.maxRequestBodyBytes !== 'number')
54
+ return null;
55
+ return {
56
+ rawFetch: reply.rawFetch,
57
+ requestBodyStreaming: reply.requestBodyStreaming,
58
+ maxRequestBodyBytes: reply.maxRequestBodyBytes,
59
+ };
60
+ }
61
+ /** Content type of a raw-mode answer on the node-server hop. */
62
+ export const RAW_FETCH_CONTENT_TYPE = 'application/vnd.slicc.raw-fetch';
63
+ /**
64
+ * Request-body ceiling on the node-server hop (CLI and cloud). This hop
65
+ * buffers the upload on both ends for now; past this size the bridge answers
66
+ * 413 and the webapp refuses before sending.
67
+ */
68
+ export const RAW_FETCH_BRIDGE_REQUEST_BODY_CAP = 256 * 1024 * 1024;
69
+ /** Upper bound on one encoded response-head frame. */
70
+ export const RAW_FETCH_MAX_HEAD_BYTES = 1024 * 1024;
71
+ /**
72
+ * Hop-by-hop request headers (RFC 9110 §7.6.1) plus the ones the forwarding
73
+ * fetch owns: `host` and `content-length` are derived from the URL and body,
74
+ * `accept-encoding` is chosen by the float so it can decode what it asked for,
75
+ * and `expect` is answered by the realm proxy, not the origin.
76
+ */
77
+ const RAW_REQUEST_SKIP_HEADERS = new Set([
78
+ 'connection',
79
+ 'keep-alive',
80
+ 'proxy-connection',
81
+ 'te',
82
+ 'trailer',
83
+ 'transfer-encoding',
84
+ 'upgrade',
85
+ 'host',
86
+ 'content-length',
87
+ 'accept-encoding',
88
+ 'expect',
89
+ ]);
90
+ /** Hop-by-hop response headers; never part of the delivered head. */
91
+ const RAW_RESPONSE_SKIP_HEADERS = new Set([
92
+ 'connection',
93
+ 'keep-alive',
94
+ 'proxy-connection',
95
+ 'te',
96
+ 'trailer',
97
+ 'transfer-encoding',
98
+ 'upgrade',
99
+ ]);
100
+ /** Content codings every float's fetch decodes on its own. */
101
+ const DECODED_CODINGS = new Set(['gzip', 'x-gzip', 'deflate', 'br']);
102
+ /** `Accept-Encoding` a float sends upstream: exactly the codings it decodes. */
103
+ export const RAW_FETCH_ACCEPT_ENCODING = 'gzip, deflate, br';
104
+ /**
105
+ * The `Accept-Encoding` a float sets for a request with these (folded,
106
+ * lowercase) headers, or `undefined` to set none. A ranged request (`Range`,
107
+ * `If-Range`) must not offer a compressed coding: a 206 over a compressed
108
+ * representation carries `Content-Range` offsets into the compressed bytes,
109
+ * which no longer describe the body once the float decodes it, so a resumed
110
+ * or ranged download would assemble corrupt data. With no `Accept-Encoding`
111
+ * set, `fetch` itself sends `identity` for a request carrying `Range` (Fetch
112
+ * standard, HTTP-network-or-cache fetch), in Node and in Chrome alike.
113
+ */
114
+ export function rawAcceptEncoding(headers) {
115
+ return headers.range !== undefined || headers['if-range'] !== undefined
116
+ ? undefined
117
+ : RAW_FETCH_ACCEPT_ENCODING;
118
+ }
119
+ /**
120
+ * Whether a partial response came back with a coding the float undid
121
+ * (an origin that ignored `Accept-Encoding: identity`). Its `Content-Range`
122
+ * counts encoded bytes the caller never sees, so the float must refuse it
123
+ * rather than deliver it.
124
+ */
125
+ export function isDecodedPartialResponse(input) {
126
+ if (input.status !== 206)
127
+ return false;
128
+ const encoding = input.headers
129
+ .filter(([name]) => name.toLowerCase() === 'content-encoding')
130
+ .map(([, value]) => value)
131
+ .join(',');
132
+ return codingsWereDecoded(encoding);
133
+ }
134
+ /** Statuses whose responses never carry a body. */
135
+ const NULL_BODY_STATUSES = new Set([101, 103, 204, 205, 304]);
136
+ function isHeaderPair(value) {
137
+ return (Array.isArray(value) &&
138
+ value.length === 2 &&
139
+ typeof value[0] === 'string' &&
140
+ typeof value[1] === 'string');
141
+ }
142
+ /** Tokens a `Connection` header names, lowercased. */
143
+ function connectionTokens(headers) {
144
+ const tokens = new Set();
145
+ for (const [name, value] of headers) {
146
+ if (name.toLowerCase() !== 'connection')
147
+ continue;
148
+ for (const token of value.split(',')) {
149
+ const trimmed = token.trim().toLowerCase();
150
+ if (trimmed)
151
+ tokens.add(trimmed);
152
+ }
153
+ }
154
+ return tokens;
155
+ }
156
+ /** Drop hop-by-hop and float-owned request headers, keeping order. */
157
+ export function stripRawRequestHeaders(headers) {
158
+ const named = connectionTokens(headers);
159
+ return headers.filter(([name]) => {
160
+ const lower = name.toLowerCase();
161
+ return !RAW_REQUEST_SKIP_HEADERS.has(lower) && !named.has(lower);
162
+ });
163
+ }
164
+ /**
165
+ * Fold a raw list into the name → value record `fetch` sends. Repeats join
166
+ * with `, ` (RFC 9110 §5.3), except `Cookie`, which joins with `; `. No float
167
+ * can put two lines with one name on the wire: `fetch` folds them the same way.
168
+ */
169
+ export function foldRawRequestHeaders(headers) {
170
+ const out = {};
171
+ for (const [name, value] of headers) {
172
+ const lower = name.toLowerCase();
173
+ const prior = out[lower];
174
+ if (prior === undefined)
175
+ out[lower] = value;
176
+ else
177
+ out[lower] = `${prior}${lower === 'cookie' ? '; ' : ', '}${value}`;
178
+ }
179
+ return out;
180
+ }
181
+ /** True when every listed coding is one the float's fetch undid. */
182
+ function codingsWereDecoded(contentEncoding) {
183
+ const codings = contentEncoding
184
+ .split(',')
185
+ .map((c) => c.trim().toLowerCase())
186
+ .filter((c) => c !== '' && c !== 'identity');
187
+ return codings.length > 0 && codings.every((c) => DECODED_CODINGS.has(c));
188
+ }
189
+ /** Whether a response to `method` with `status` carries a body at all. */
190
+ export function rawResponseHasBody(method, status) {
191
+ return method.toUpperCase() !== 'HEAD' && !NULL_BODY_STATUSES.has(status);
192
+ }
193
+ /**
194
+ * The head a raw caller sees. Hop-by-hop headers go, and so do the fields
195
+ * the response's `Connection` header names (RFC 9110 §7.6.1). A bodiless response
196
+ * (HEAD, 1xx/204/205/304) keeps `Content-Encoding` and `Content-Length` as
197
+ * sent, since they describe the representation, not bytes on this hop.
198
+ * Otherwise a decoded coding drops both headers, and `Content-Length` also
199
+ * goes when the float rewrote the body. An unknown coding stays with its
200
+ * encoded bytes.
201
+ */
202
+ export function rawResponseHeaders(input) {
203
+ const named = connectionTokens(input.headers);
204
+ const withoutHop = input.headers.filter(([name]) => {
205
+ const lower = name.toLowerCase();
206
+ return !RAW_RESPONSE_SKIP_HEADERS.has(lower) && !named.has(lower);
207
+ });
208
+ if (!rawResponseHasBody(input.method, input.status))
209
+ return withoutHop;
210
+ const encoding = withoutHop
211
+ .filter(([name]) => name.toLowerCase() === 'content-encoding')
212
+ .map(([, value]) => value)
213
+ .join(',');
214
+ const decoded = codingsWereDecoded(encoding);
215
+ const dropLength = decoded || input.bodyRewritten;
216
+ return withoutHop.filter(([name]) => {
217
+ const lower = name.toLowerCase();
218
+ if (lower === 'content-length')
219
+ return !dropLength;
220
+ if (lower === 'content-encoding')
221
+ return !decoded && encoding.trim().toLowerCase() !== 'identity';
222
+ return true;
223
+ });
224
+ }
225
+ /**
226
+ * JSON for {@link RAW_FETCH_REQUEST_HEADER}. Non-ASCII is `\u`-escaped so the
227
+ * value is a valid header ByteString whatever the caller's headers hold.
228
+ */
229
+ export function encodeRawRequestHead(head) {
230
+ return JSON.stringify(head).replace(/[\u007f-￿]/g, (c) => `\\u${c.charCodeAt(0).toString(16).padStart(4, '0')}`);
231
+ }
232
+ /** Parse a {@link RAW_FETCH_REQUEST_HEADER} value; `null` when malformed. */
233
+ export function decodeRawRequestHead(value) {
234
+ let parsed;
235
+ try {
236
+ parsed = JSON.parse(value);
237
+ }
238
+ catch {
239
+ return null;
240
+ }
241
+ if (!parsed || typeof parsed !== 'object')
242
+ return null;
243
+ const { url, method, headers } = parsed;
244
+ if (typeof url !== 'string' ||
245
+ typeof method !== 'string' ||
246
+ !/^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/.test(method)) {
247
+ return null;
248
+ }
249
+ if (!Array.isArray(headers) || !headers.every(isHeaderPair))
250
+ return null;
251
+ return { url, method, headers };
252
+ }
253
+ /** One response-head frame: a big-endian u32 length, then UTF-8 JSON. */
254
+ export function encodeRawResponseFrame(head) {
255
+ const json = new TextEncoder().encode(JSON.stringify(head));
256
+ const frame = new Uint8Array(4 + json.byteLength);
257
+ new DataView(frame.buffer).setUint32(0, json.byteLength);
258
+ frame.set(json, 4);
259
+ return frame;
260
+ }
261
+ function isRawResponseHead(value) {
262
+ if (!value || typeof value !== 'object')
263
+ return false;
264
+ const head = value;
265
+ return (typeof head.status === 'number' &&
266
+ typeof head.statusText === 'string' &&
267
+ typeof head.url === 'string' &&
268
+ Array.isArray(head.headers) &&
269
+ head.headers.every(isHeaderPair));
270
+ }
271
+ /**
272
+ * Split a response-head frame off the front of `buffer`. Returns `null` while
273
+ * the frame is still incomplete, and throws when it is malformed or larger
274
+ * than {@link RAW_FETCH_MAX_HEAD_BYTES}.
275
+ */
276
+ export function decodeRawResponseFrame(buffer) {
277
+ if (buffer.byteLength < 4)
278
+ return null;
279
+ const length = new DataView(buffer.buffer, buffer.byteOffset, 4).getUint32(0);
280
+ if (length > RAW_FETCH_MAX_HEAD_BYTES) {
281
+ throw new Error(`raw fetch: response head of ${length} bytes exceeds the limit`);
282
+ }
283
+ if (buffer.byteLength < 4 + length)
284
+ return null;
285
+ let head;
286
+ try {
287
+ head = JSON.parse(new TextDecoder().decode(buffer.subarray(4, 4 + length)));
288
+ }
289
+ catch {
290
+ throw new Error('raw fetch: malformed response head');
291
+ }
292
+ if (!isRawResponseHead(head))
293
+ throw new Error('raw fetch: malformed response head');
294
+ return { head, rest: buffer.subarray(4 + length) };
295
+ }
296
+ //# sourceMappingURL=raw-fetch-protocol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"raw-fetch-protocol.js","sourceRoot":"","sources":["../src/raw-fetch-protocol.ts"],"names":[],"mappings":"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"}
@@ -68,11 +68,13 @@ export declare const FETCH_PROXY_BASE_EXPOSE_HEADERS: readonly string[];
68
68
  */
69
69
  export declare function buildFetchProxyExposeHeaders(forwardedHeaderNames: Iterable<string>): string;
70
70
  /**
71
- * Which requests the global `express.json()` consumes. Two exclusions:
71
+ * Which requests the global `express.json()` consumes. Three exclusions:
72
72
  *
73
73
  * - `X-Slicc-Raw-Body: 1` — SigV4-signed bodies must reach the
74
74
  * /api/fetch-proxy handler byte-for-byte (the parser would re-serialize
75
75
  * them via JSON.stringify and break the signature);
76
+ * - `X-Slicc-Raw-Request` — raw-mode fetch-proxy uploads, read as a
77
+ * bounded byte stream by `routes/fetch-proxy-raw.ts`;
76
78
  * - the stable hostfs dispatcher — it owns a bounded 1 MiB parser and an
77
79
  * errno error adapter, and this parser is mounted ahead of
78
80
  * `registerHostFsRoutes`, so without the exclusion it would consume the
@@ -121,11 +121,13 @@ export function buildFetchProxyExposeHeaders(forwardedHeaderNames) {
121
121
  return out.join(', ');
122
122
  }
123
123
  /**
124
- * Which requests the global `express.json()` consumes. Two exclusions:
124
+ * Which requests the global `express.json()` consumes. Three exclusions:
125
125
  *
126
126
  * - `X-Slicc-Raw-Body: 1` — SigV4-signed bodies must reach the
127
127
  * /api/fetch-proxy handler byte-for-byte (the parser would re-serialize
128
128
  * them via JSON.stringify and break the signature);
129
+ * - `X-Slicc-Raw-Request` — raw-mode fetch-proxy uploads, read as a
130
+ * bounded byte stream by `routes/fetch-proxy-raw.ts`;
129
131
  * - the stable hostfs dispatcher — it owns a bounded 1 MiB parser and an
130
132
  * errno error adapter, and this parser is mounted ahead of
131
133
  * `registerHostFsRoutes`, so without the exclusion it would consume the
@@ -134,6 +136,8 @@ export function buildFetchProxyExposeHeaders(forwardedHeaderNames) {
134
136
  export function shouldParseGlobalJson(req) {
135
137
  if (req.headers['x-slicc-raw-body'] === '1')
136
138
  return false;
139
+ if (req.headers['x-slicc-raw-request'] !== undefined)
140
+ return false;
137
141
  if (isHostFsStableBodyRequest(req))
138
142
  return false;
139
143
  return (req.headers['content-type'] ?? '').includes('application/json');
@@ -42,7 +42,9 @@ import { runInstallCli } from './install-cli.js';
42
42
  import { resolveCliBrowserLaunchUrl } from './launch-url.js';
43
43
  import { createHttpCdp, registerLeaderRestartEndpoint } from './leader-restart.js';
44
44
  import { buildLocalApiDescriptor, sliccLinksMiddleware } from './links-middleware.js';
45
+ import { AgentActivityTracker } from './routes/agent-activity.js';
45
46
  import { registerFetchProxyRoute } from './routes/fetch-proxy.js';
47
+ import { registerRawFetchProxyRoute } from './routes/fetch-proxy-raw.js';
46
48
  import { registerHandoffRoute } from './routes/handoff.js';
47
49
  import { registerLickApiRoutes } from './routes/lick-api.js';
48
50
  import { createLickBridge } from './routes/lick-bridge.js';
@@ -1194,6 +1196,17 @@ function createCdpWebSocketServer(bridgeToken) {
1194
1196
  },
1195
1197
  });
1196
1198
  }
1199
+ /**
1200
+ * Fetch proxy — forwards cross-origin requests from the browser to bypass CORS,
1201
+ * injecting/unmasking secrets and streaming the response with a UTF-8-safe
1202
+ * scrub. Raw mode (#3571) is mounted first and falls through for default
1203
+ * requests; both share one agent-activity window.
1204
+ */
1205
+ function mountFetchProxy(app, secretProxy) {
1206
+ const activityTracker = new AgentActivityTracker();
1207
+ registerRawFetchProxyRoute(app, { secretProxy, activityTracker });
1208
+ registerFetchProxyRoute(app, { secretProxy, activityTracker });
1209
+ }
1197
1210
  async function main() {
1198
1211
  // Resolve ports first; `launchBrowser` is deferred until AFTER
1199
1212
  // `server.listen()` so the /cdp bridge is accepting connections before
@@ -1297,9 +1310,7 @@ async function main() {
1297
1310
  const computerDemo = RUNTIME_FLAGS.computerDemo ? new ComputerDemoState() : null;
1298
1311
  if (computerDemo)
1299
1312
  registerComputerDemoRoutes(app, computerDemo);
1300
- // Fetch proxy — forwards cross-origin requests from the browser to bypass CORS,
1301
- // injecting/unmasking secrets and streaming the response with a UTF-8-safe scrub.
1302
- registerFetchProxyRoute(app, { secretProxy });
1313
+ mountFetchProxy(app, secretProxy);
1303
1314
  // node-server serves no UI in any mode: it is a pure /cdp bridge + /api
1304
1315
  // surface. Chrome opens the sliccy.ai-hosted leader which talks to /cdp +
1305
1316
  // /api cross-origin. Create the HTTP server so we can attach the /cdp WS
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Raw mode of `/api/fetch-proxy` (#3571): the HTTP-client flavor the wasm
3
+ * realm's proxy forwards curl and git through. The wire contract lives in
4
+ * `@slicc/shared-ts` `raw-fetch-protocol.ts`; this module is the CLI/cloud
5
+ * float's side of it. Differences from the default route:
6
+ *
7
+ * - the request head (URL, method, ordered headers) arrives as JSON in
8
+ * `X-Slicc-Raw-Request`, so the browser's forbidden-header filter and the
9
+ * page's own headers (User-Agent, Sec-Fetch-*) never reach upstream;
10
+ * - redirects are manual: the 3xx, `Location` and every `Set-Cookie` go
11
+ * back to the caller in an ordered header list;
12
+ * - the answer is always `200` + `application/vnd.slicc.raw-fetch`: one
13
+ * response-head frame, then the body streamed through (Node `pipe`
14
+ * pauses upstream whenever the browser stops reading, though Chrome's
15
+ * `fetch` reads ahead of its JS reader, so in practice it rarely does).
16
+ *
17
+ * Secret handling is the default route's: masked values in headers, URL
18
+ * credentials and text bodies are unmasked for allowed domains only (403
19
+ * otherwise), `x-slicc-hmac-sign` is honored, and response header values and
20
+ * text bodies are scrubbed, including `Location`.
21
+ */
22
+ import type { Express, Request, Response } from 'express';
23
+ import type { SecretProxyManager } from '../secrets/proxy-manager.js';
24
+ import type { AgentActivityTracker } from './agent-activity.js';
25
+ export interface RawFetchProxyDeps {
26
+ secretProxy: SecretProxyManager;
27
+ activityTracker: AgentActivityTracker;
28
+ logger?: Pick<Console, 'log' | 'warn' | 'error'>;
29
+ /** Request-body ceiling; tests shrink it. */
30
+ maxRequestBodyBytes?: number;
31
+ }
32
+ /** Whether this `/api/fetch-proxy` request selected raw mode. */
33
+ export declare function isRawFetchProxyRequest(req: Request): boolean;
34
+ /** Whether this `/api/fetch-proxy` request asks what raw mode can do. */
35
+ export declare function isRawFetchProbe(req: Request): boolean;
36
+ /** Answer the capability probe; nothing is fetched upstream. */
37
+ export declare function answerRawFetchProbe(res: Response, maxRequestBodyBytes: number): void;
38
+ export declare function handleRawFetchProxy(req: Request, res: Response, deps: RawFetchProxyDeps): Promise<void>;
39
+ /**
40
+ * Mount raw mode ahead of the default `/api/fetch-proxy` handler; requests
41
+ * without `X-Slicc-Raw-Request` fall through to it untouched.
42
+ */
43
+ export declare function registerRawFetchProxyRoute(app: Express, deps: RawFetchProxyDeps): void;