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
@@ -0,0 +1,205 @@
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 { decodeRawRequestHead, encodeRawResponseFrame, foldRawRequestHeaders, HMAC_SIGN_HEADER, isDecodedPartialResponse, isTextContentType, RAW_FETCH_BRIDGE_REQUEST_BODY_CAP, RAW_FETCH_CONTENT_TYPE, RAW_FETCH_PROBE_HEADER, RAW_FETCH_PROTOCOL_VERSION, RAW_FETCH_REQUEST_HEADER, rawAcceptEncoding, rawResponseHasBody, rawResponseHeaders, stripRawRequestHeaders, } from '../_shared/index.js';
23
+ import { applyHmacSigning, attachUpstreamAbort, injectRequestSecrets, streamUpstreamBody, unmaskRequestBody, } from './fetch-proxy.js';
24
+ const RAW_REQUEST_HEADER_LOWER = RAW_FETCH_REQUEST_HEADER.toLowerCase();
25
+ const RAW_PROBE_HEADER_LOWER = RAW_FETCH_PROBE_HEADER.toLowerCase();
26
+ class RequestBodyTooLargeError extends Error {
27
+ }
28
+ function sendProxyError(res, status, error) {
29
+ res.setHeader('X-Proxy-Error', '1');
30
+ res.status(status).json({ error });
31
+ }
32
+ /** Read the upload, refusing it as soon as it passes `limit`. */
33
+ async function readBoundedBody(req, limit) {
34
+ const declared = Number(req.headers['content-length']);
35
+ if (Number.isFinite(declared) && declared > limit)
36
+ throw new RequestBodyTooLargeError();
37
+ const chunks = [];
38
+ let size = 0;
39
+ for await (const chunk of req) {
40
+ const buf = Buffer.from(chunk);
41
+ size += buf.byteLength;
42
+ if (size > limit)
43
+ throw new RequestBodyTooLargeError();
44
+ chunks.push(buf);
45
+ }
46
+ return Buffer.concat(chunks);
47
+ }
48
+ /** Upstream response headers as an ordered list, each `Set-Cookie` separate. */
49
+ function upstreamHeaderList(upstream) {
50
+ const list = [];
51
+ upstream.headers.forEach((value, name) => {
52
+ if (name !== 'set-cookie')
53
+ list.push([name, value]);
54
+ });
55
+ for (const cookie of upstream.headers.getSetCookie())
56
+ list.push(['set-cookie', cookie]);
57
+ return list;
58
+ }
59
+ /** Build the upstream request with secrets injected, or name the forbidden one. */
60
+ async function prepareUpstream(secretProxy, head, rawBody) {
61
+ const headers = foldRawRequestHeaders(stripRawRequestHeaders(head.headers));
62
+ const hmacSpec = headers[HMAC_SIGN_HEADER];
63
+ delete headers[HMAC_SIGN_HEADER];
64
+ const acceptEncoding = rawAcceptEncoding(headers);
65
+ if (acceptEncoding !== undefined)
66
+ headers['accept-encoding'] = acceptEncoding;
67
+ let hostname = '';
68
+ try {
69
+ hostname = new URL(head.url).hostname;
70
+ }
71
+ catch {
72
+ // Malformed URL: the upstream fetch rejects it below.
73
+ }
74
+ const injection = injectRequestSecrets(secretProxy, headers, head.url, hostname);
75
+ if ('forbidden' in injection)
76
+ return injection;
77
+ const method = head.method.toUpperCase();
78
+ let body;
79
+ if (rawBody.length > 0 && method !== 'GET' && method !== 'HEAD') {
80
+ body = unmaskRequestBody(secretProxy, headers, rawBody, hostname);
81
+ }
82
+ const signing = await applyHmacSigning(secretProxy, headers, hmacSpec, body, hostname);
83
+ if (signing)
84
+ return signing;
85
+ const init = { method: head.method, headers, redirect: 'manual' };
86
+ if (body)
87
+ init.body = body;
88
+ return { url: injection.cleanedUrl, init };
89
+ }
90
+ /** Write the response-head frame, then stream (or skip) the body. */
91
+ function relayUpstream(res, head, upstream, secretProxy, detachClientClose) {
92
+ const hasBody = rawResponseHasBody(head.method, upstream.status) && upstream.body !== null;
93
+ // Text bodies pass the gunzip sniff and the secret scrub, so their length
94
+ // is not the upstream one; binary bodies pass through byte for byte.
95
+ const bodyRewritten = isTextContentType(upstream.headers.get('content-type') ?? '');
96
+ const headers = rawResponseHeaders({
97
+ method: head.method,
98
+ status: upstream.status,
99
+ headers: upstreamHeaderList(upstream),
100
+ bodyRewritten,
101
+ }).map(([name, value]) => [name, secretProxy.scrubResponse(value)]);
102
+ res.status(200);
103
+ res.setHeader('Content-Type', RAW_FETCH_CONTENT_TYPE);
104
+ res.setHeader('Cache-Control', 'no-store, no-cache');
105
+ res.write(encodeRawResponseFrame({
106
+ status: upstream.status,
107
+ statusText: upstream.statusText,
108
+ headers,
109
+ url: head.url,
110
+ }));
111
+ if (!hasBody || !upstream.body) {
112
+ void upstream.body?.cancel().catch(() => undefined);
113
+ res.end();
114
+ detachClientClose();
115
+ return;
116
+ }
117
+ streamUpstreamBody(res, upstream, secretProxy, detachClientClose);
118
+ }
119
+ /** Whether this `/api/fetch-proxy` request selected raw mode. */
120
+ export function isRawFetchProxyRequest(req) {
121
+ return typeof req.headers[RAW_REQUEST_HEADER_LOWER] === 'string';
122
+ }
123
+ /** Whether this `/api/fetch-proxy` request asks what raw mode can do. */
124
+ export function isRawFetchProbe(req) {
125
+ return req.headers[RAW_PROBE_HEADER_LOWER] !== undefined;
126
+ }
127
+ /** Answer the capability probe; nothing is fetched upstream. */
128
+ export function answerRawFetchProbe(res, maxRequestBodyBytes) {
129
+ const reply = {
130
+ rawFetch: RAW_FETCH_PROTOCOL_VERSION,
131
+ requestBodyStreaming: false,
132
+ maxRequestBodyBytes,
133
+ };
134
+ res.setHeader('Cache-Control', 'no-store');
135
+ res.status(200).json(reply);
136
+ }
137
+ export async function handleRawFetchProxy(req, res, deps) {
138
+ const { secretProxy, logger = console } = deps;
139
+ const limit = deps.maxRequestBodyBytes ?? RAW_FETCH_BRIDGE_REQUEST_BODY_CAP;
140
+ const head = decodeRawRequestHead(String(req.headers[RAW_REQUEST_HEADER_LOWER]));
141
+ if (!head) {
142
+ sendProxyError(res, 400, `Malformed ${RAW_FETCH_REQUEST_HEADER} header`);
143
+ return;
144
+ }
145
+ let rawBody;
146
+ try {
147
+ rawBody = await readBoundedBody(req, limit);
148
+ }
149
+ catch (err) {
150
+ if (!(err instanceof RequestBodyTooLargeError))
151
+ throw err;
152
+ logger.warn(`[fetch-proxy:raw] ${head.method} ${head.url} → 413`);
153
+ res.setHeader('Connection', 'close');
154
+ sendProxyError(res, 413, `Request body exceeds the ${limit} byte limit of this float`);
155
+ return;
156
+ }
157
+ logger.log(`[fetch-proxy:raw] ${head.method} ${head.url}`);
158
+ const prepared = await prepareUpstream(secretProxy, head, rawBody);
159
+ if ('forbidden' in prepared) {
160
+ const { secretName, hostname } = prepared.forbidden;
161
+ logger.warn(`[fetch-proxy:raw] ${head.method} ${head.url} → 403 (secret "${secretName}")`);
162
+ sendProxyError(res, 403, `Secret "${secretName}" is not allowed for domain "${hostname}"`);
163
+ return;
164
+ }
165
+ const upstreamAbort = attachUpstreamAbort(res);
166
+ prepared.init.signal = upstreamAbort.controller.signal;
167
+ let upstream;
168
+ try {
169
+ upstream = await fetch(prepared.url, prepared.init);
170
+ }
171
+ catch (err) {
172
+ upstreamAbort.detach();
173
+ const message = err instanceof Error ? err.message : String(err);
174
+ logger.error(`[fetch-proxy:raw] ${head.method} ${head.url} ← 502 (${message})`);
175
+ sendProxyError(res, 502, `Proxy fetch failed: ${message}`);
176
+ return;
177
+ }
178
+ logger.log(`[fetch-proxy:raw] ${head.method} ${head.url} ← ${upstream.status}`);
179
+ if (isDecodedPartialResponse({ status: upstream.status, headers: upstreamHeaderList(upstream) })) {
180
+ upstreamAbort.detach();
181
+ await upstream.body?.cancel().catch(() => undefined);
182
+ logger.warn(`[fetch-proxy:raw] ${head.method} ${head.url} ← 206 encoded despite identity`);
183
+ sendProxyError(res, 502, 'Upstream answered a range request with an encoded partial body');
184
+ return;
185
+ }
186
+ relayUpstream(res, head, upstream, secretProxy, upstreamAbort.detach);
187
+ }
188
+ /**
189
+ * Mount raw mode ahead of the default `/api/fetch-proxy` handler; requests
190
+ * without `X-Slicc-Raw-Request` fall through to it untouched.
191
+ */
192
+ export function registerRawFetchProxyRoute(app, deps) {
193
+ app.post('/api/fetch-proxy', (req, res, next) => {
194
+ if (isRawFetchProbe(req) && !isRawFetchProxyRequest(req)) {
195
+ answerRawFetchProbe(res, deps.maxRequestBodyBytes ?? RAW_FETCH_BRIDGE_REQUEST_BODY_CAP);
196
+ return;
197
+ }
198
+ if (!isRawFetchProxyRequest(req)) {
199
+ next();
200
+ return;
201
+ }
202
+ deps.activityTracker.recordActivity();
203
+ handleRawFetchProxy(req, res, deps).catch(next);
204
+ });
205
+ }
@@ -42,6 +42,29 @@ export declare function injectRequestSecrets(secretProxy: SecretProxyManager, he
42
42
  } | {
43
43
  cleanedUrl: string;
44
44
  };
45
+ /**
46
+ * Apply the `x-slicc-hmac-sign` directive, if present: sign `body` with the
47
+ * named secret's real value and attach the hex result under the header the
48
+ * client requested. Mutates `headers` and always removes the sentinel
49
+ * (already stripped from `headers` by `buildForwardHeaders`'s skip-list;
50
+ * this only needs to read it off the raw request).
51
+ */
52
+ export declare function applyHmacSigning(secretProxy: SecretProxyManager, headers: Record<string, string>, hmacSpec: string | undefined, body: Buffer | undefined, targetHostname: string): Promise<{
53
+ forbidden: ForbiddenSecret;
54
+ } | undefined>;
55
+ /**
56
+ * Unmask masked secrets in a text request body. Non-text bodies (git
57
+ * packfiles, octet-stream, images, …) are left untouched — `toString('utf-8')`
58
+ * on arbitrary bytes corrupts them, and masked values never appear in binary.
59
+ *
60
+ * Uses the request-side predicate so form POSTs count as text: swift-server
61
+ * unmasks them and a masked `client_secret` reaching an upstream OAuth token
62
+ * endpoint verbatim is a silent auth failure, not a corrupt-bytes risk (#2821).
63
+ * A form body then takes the encoding-aware `unmaskFormBody` path — a plain
64
+ * substring splice would corrupt it whenever the real secret carries a
65
+ * form-reserved character (base64 `+` / `/` / `=`).
66
+ */
67
+ export declare function unmaskRequestBody(secretProxy: SecretProxyManager, headers: Record<string, string>, rawBody: Buffer, targetHostname: string): Buffer;
45
68
  /**
46
69
  * Buffer-aware UTF-8 secret scrubber. A `StringDecoder` keeps trailing partial
47
70
  * multi-byte sequences out of the scrub so codepoints straddling a chunk
@@ -116,7 +116,7 @@ export function injectRequestSecrets(secretProxy, headers, targetUrl, targetHost
116
116
  * (already stripped from `headers` by `buildForwardHeaders`'s skip-list;
117
117
  * this only needs to read it off the raw request).
118
118
  */
119
- async function applyHmacSigning(secretProxy, headers, hmacSpec, body, targetHostname) {
119
+ export async function applyHmacSigning(secretProxy, headers, hmacSpec, body, targetHostname) {
120
120
  if (!hmacSpec)
121
121
  return undefined;
122
122
  const signResult = await secretProxy.signHmac(hmacSpec, body ?? Buffer.alloc(0), targetHostname);
@@ -142,7 +142,7 @@ async function applyHmacSigning(secretProxy, headers, hmacSpec, body, targetHost
142
142
  * substring splice would corrupt it whenever the real secret carries a
143
143
  * form-reserved character (base64 `+` / `/` / `=`).
144
144
  */
145
- function unmaskRequestBody(secretProxy, headers, rawBody, targetHostname) {
145
+ export function unmaskRequestBody(secretProxy, headers, rawBody, targetHostname) {
146
146
  const contentType = headers['content-type'] ?? headers['Content-Type'] ?? '';
147
147
  if (!isTextRequestContentType(contentType) || !secretProxy.hasSecrets())
148
148
  return rawBody;
@@ -268,7 +268,8 @@ export function streamUpstreamBody(res, upstream, secretProxy, detachClientClose
268
268
  const decoded = isText
269
269
  ? createMaybeGunzipStream({
270
270
  onDecided: (inflating) => {
271
- if (inflating)
271
+ // Raw mode (`fetch-proxy-raw.ts`) has already sent its head frame.
272
+ if (inflating && !res.headersSent)
272
273
  res.removeHeader(FETCH_PROXY_CONTENT_LENGTH_HEADER);
273
274
  },
274
275
  })