@rynx-ai/server 0.1.11-beta.25 → 0.1.11-beta.27

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 (440) hide show
  1. package/dist/control-api.js +488 -68
  2. package/dist/control-web/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  3. package/dist/control-web/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  4. package/dist/control-web/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  5. package/dist/control-web/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  6. package/dist/control-web/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  7. package/dist/control-web/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  8. package/dist/control-web/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  9. package/dist/control-web/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  10. package/dist/control-web/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  11. package/dist/control-web/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  12. package/dist/control-web/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  13. package/dist/control-web/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  14. package/dist/control-web/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  15. package/dist/control-web/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  16. package/dist/control-web/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  17. package/dist/control-web/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  18. package/dist/control-web/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  19. package/dist/control-web/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  20. package/dist/control-web/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  21. package/dist/control-web/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  22. package/dist/control-web/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  23. package/dist/control-web/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  24. package/dist/control-web/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  25. package/dist/control-web/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  26. package/dist/control-web/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  27. package/dist/control-web/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  28. package/dist/control-web/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  29. package/dist/control-web/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  30. package/dist/control-web/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  31. package/dist/control-web/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  32. package/dist/control-web/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  33. package/dist/control-web/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  34. package/dist/control-web/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  35. package/dist/control-web/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  36. package/dist/control-web/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  37. package/dist/control-web/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  38. package/dist/control-web/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  39. package/dist/control-web/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  40. package/dist/control-web/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  41. package/dist/control-web/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  42. package/dist/control-web/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  43. package/dist/control-web/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  44. package/dist/control-web/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  45. package/dist/control-web/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  46. package/dist/control-web/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  47. package/dist/control-web/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  48. package/dist/control-web/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  49. package/dist/control-web/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  50. package/dist/control-web/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  51. package/dist/control-web/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  52. package/dist/control-web/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  53. package/dist/control-web/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  54. package/dist/control-web/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  55. package/dist/control-web/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  56. package/dist/control-web/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  57. package/dist/control-web/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  58. package/dist/control-web/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  59. package/dist/control-web/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  60. package/dist/control-web/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  61. package/dist/control-web/assets/abap-BdImnpbu.js +1 -0
  62. package/dist/control-web/assets/abnfDiagram-VRR7QNED-COu02MlJ.js +1 -0
  63. package/dist/control-web/assets/actionscript-3-CoDkCxhg.js +1 -0
  64. package/dist/control-web/assets/ada-bCR0ucgS.js +1 -0
  65. package/dist/control-web/assets/andromeeda-C4gqWexZ.js +1 -0
  66. package/dist/control-web/assets/angular-html-CU67Zn6k.js +1 -0
  67. package/dist/control-web/assets/angular-ts-BwZT4LLn.js +1 -0
  68. package/dist/control-web/assets/apache-Pmp26Uib.js +1 -0
  69. package/dist/control-web/assets/apex-D8_7TLub.js +1 -0
  70. package/dist/control-web/assets/apl-dKokRX4l.js +1 -0
  71. package/dist/control-web/assets/applescript-Co6uUVPk.js +1 -0
  72. package/dist/control-web/assets/ara-BRHolxvo.js +1 -0
  73. package/dist/control-web/assets/arc-DqiFeYAM.js +1 -0
  74. package/dist/control-web/assets/architectureDiagram-ZJ3FMSHR-BWFGgUV4.js +36 -0
  75. package/dist/control-web/assets/asciidoc-Ve4PFQV2.js +1 -0
  76. package/dist/control-web/assets/asm-D_Q5rh1f.js +1 -0
  77. package/dist/control-web/assets/astro-CbQHKStN.js +1 -0
  78. package/dist/control-web/assets/aurora-x-D-2ljcwZ.js +1 -0
  79. package/dist/control-web/assets/awk-DMzUqQB5.js +1 -0
  80. package/dist/control-web/assets/ayu-dark-DYE7WIF3.js +1 -0
  81. package/dist/control-web/assets/ayu-light-BA47KaF1.js +1 -0
  82. package/dist/control-web/assets/ayu-mirage-32ctXXKs.js +1 -0
  83. package/dist/control-web/assets/ballerina-BFfxhgS-.js +1 -0
  84. package/dist/control-web/assets/bat-BkioyH1T.js +1 -0
  85. package/dist/control-web/assets/beancount-k_qm7-4y.js +1 -0
  86. package/dist/control-web/assets/berry-uYugtg8r.js +1 -0
  87. package/dist/control-web/assets/bibtex-CHM0blh-.js +1 -0
  88. package/dist/control-web/assets/bicep-Bmn6On1c.js +1 -0
  89. package/dist/control-web/assets/bird2-DPOp833l.js +1 -0
  90. package/dist/control-web/assets/blade-D4QpJJKB.js +1 -0
  91. package/dist/control-web/assets/blockDiagram-677ZJIJ3-ZC0bXDzB.js +132 -0
  92. package/dist/control-web/assets/bsl-BO_Y6i37.js +1 -0
  93. package/dist/control-web/assets/c-BIGW1oBm.js +1 -0
  94. package/dist/control-web/assets/c3-eo99z4R2.js +1 -0
  95. package/dist/control-web/assets/c4Diagram-LMCZKHZV-Uupq5I-s.js +10 -0
  96. package/dist/control-web/assets/cadence-Bv_4Rxtq.js +1 -0
  97. package/dist/control-web/assets/cairo-KRGpt6FW.js +1 -0
  98. package/dist/control-web/assets/catppuccin-frappe-DFWUc33u.js +1 -0
  99. package/dist/control-web/assets/catppuccin-latte-C9dUb6Cb.js +1 -0
  100. package/dist/control-web/assets/catppuccin-macchiato-DQyhUUbL.js +1 -0
  101. package/dist/control-web/assets/catppuccin-mocha-D87Tk5Gz.js +1 -0
  102. package/dist/control-web/assets/channel-3HG15wfa.js +1 -0
  103. package/dist/control-web/assets/chunk-2Q5K7J3B-C77vwuDM.js +1 -0
  104. package/dist/control-web/assets/chunk-32BRIVSS-BkfLE_TX.js +1 -0
  105. package/dist/control-web/assets/chunk-5VM5RSS4-By6zfDWW.js +15 -0
  106. package/dist/control-web/assets/chunk-EX3LRPZG-CO439p_3.js +231 -0
  107. package/dist/control-web/assets/chunk-JWPE2WC7-B9BPEwug.js +1 -0
  108. package/dist/control-web/assets/chunk-MOJQB5TN-CYKygWZz.js +88 -0
  109. package/dist/control-web/assets/chunk-RYQCIY6F-ug-An4HG.js +1 -0
  110. package/dist/control-web/assets/chunk-V7JOEXUC-3UFQGnKX.js +206 -0
  111. package/dist/control-web/assets/chunk-VR4S4FIN-DjspjYUb.js +1 -0
  112. package/dist/control-web/assets/chunk-XXDRQBXY-3znnutie.js +1 -0
  113. package/dist/control-web/assets/clarity-D53aC0YG.js +1 -0
  114. package/dist/control-web/assets/classDiagram-OUVF2IWQ-WmU4L9YT.js +1 -0
  115. package/dist/control-web/assets/classDiagram-v2-EOCWNBFH-WmU4L9YT.js +1 -0
  116. package/dist/control-web/assets/clojure-P80f7IUj.js +1 -0
  117. package/dist/control-web/assets/cmake-D1j8_8rp.js +1 -0
  118. package/dist/control-web/assets/cobol-nwyudZeR.js +1 -0
  119. package/dist/control-web/assets/codeowners-Bp6g37R7.js +1 -0
  120. package/dist/control-web/assets/codeql-DsOJ9woJ.js +1 -0
  121. package/dist/control-web/assets/coffee-Ch7k5sss.js +1 -0
  122. package/dist/control-web/assets/common-lisp-Cg-RD9OK.js +1 -0
  123. package/dist/control-web/assets/coq-DkFqJrB1.js +1 -0
  124. package/dist/control-web/assets/cose-bilkent-JH36ORCC-Dr28goCd.js +1 -0
  125. package/dist/control-web/assets/cpp-CofmeUqb.js +1 -0
  126. package/dist/control-web/assets/crystal-tKQVLTB8.js +1 -0
  127. package/dist/control-web/assets/csharp-COcwbKMJ.js +1 -0
  128. package/dist/control-web/assets/css-DPfMkruS.js +1 -0
  129. package/dist/control-web/assets/csv-fuZLfV_i.js +1 -0
  130. package/dist/control-web/assets/cue-D82EKSYY.js +1 -0
  131. package/dist/control-web/assets/cynefin-VYW2F7L2-Be5uJhnw.js +178 -0
  132. package/dist/control-web/assets/cynefinDiagram-TSTJHNR4-BLxtSvL6.js +62 -0
  133. package/dist/control-web/assets/cypher-COkxafJQ.js +1 -0
  134. package/dist/control-web/assets/cytoscape.esm-DTSO7Bv0.js +331 -0
  135. package/dist/control-web/assets/d-85-TOEBH.js +1 -0
  136. package/dist/control-web/assets/dagre-VKFMJZFB-DPRuDV5p.js +4 -0
  137. package/dist/control-web/assets/dark-plus-C3mMm8J8.js +1 -0
  138. package/dist/control-web/assets/dart-CF10PKvl.js +1 -0
  139. package/dist/control-web/assets/dax-CEL-wOlO.js +1 -0
  140. package/dist/control-web/assets/defaultLocale-DX6XiGOO.js +1 -0
  141. package/dist/control-web/assets/desktop-BmXAJ9_W.js +1 -0
  142. package/dist/control-web/assets/diagram-FQU43EPY-Cybg22U0.js +3 -0
  143. package/dist/control-web/assets/diagram-G47NLZAW-CGeIKUfW.js +24 -0
  144. package/dist/control-web/assets/diagram-NH7WQ7WH-BJq5MBRm.js +24 -0
  145. package/dist/control-web/assets/diagram-OA4YK3LP-DquOQGwg.js +30 -0
  146. package/dist/control-web/assets/diagram-WEI45ONY-Cblb4xP2.js +41 -0
  147. package/dist/control-web/assets/diff-D97Zzqfu.js +1 -0
  148. package/dist/control-web/assets/docker-BcOcwvcX.js +1 -0
  149. package/dist/control-web/assets/dotenv-Da5cRb03.js +1 -0
  150. package/dist/control-web/assets/dracula-BzJJZx-M.js +1 -0
  151. package/dist/control-web/assets/dracula-soft-BXkSAIEj.js +1 -0
  152. package/dist/control-web/assets/dream-maker-BtqSS_iP.js +1 -0
  153. package/dist/control-web/assets/ebnfDiagram-CCIWWBDH-CQjHiOqj.js +1 -0
  154. package/dist/control-web/assets/edge-BkV0erSs.js +1 -0
  155. package/dist/control-web/assets/elixir-CDX3lj18.js +1 -0
  156. package/dist/control-web/assets/elm-DbKCFpqz.js +1 -0
  157. package/dist/control-web/assets/emacs-lisp-C9XAeP06.js +1 -0
  158. package/dist/control-web/assets/erDiagram-Q63AITRT-Bspr3uKJ.js +85 -0
  159. package/dist/control-web/assets/erb-B12qg9BL.js +1 -0
  160. package/dist/control-web/assets/erlang-DsQrWhSR.js +1 -0
  161. package/dist/control-web/assets/everforest-dark-BgDCqdQA.js +1 -0
  162. package/dist/control-web/assets/everforest-light-C8M2exoo.js +1 -0
  163. package/dist/control-web/assets/fennel-BYunw83y.js +1 -0
  164. package/dist/control-web/assets/fish-BvzEVeQv.js +1 -0
  165. package/dist/control-web/assets/flowDiagram-23GEKE2U-CxcZyBA-.js +156 -0
  166. package/dist/control-web/assets/fluent-C4IJs8-o.js +1 -0
  167. package/dist/control-web/assets/fortran-fixed-form-CkoXwp7k.js +1 -0
  168. package/dist/control-web/assets/fortran-free-form-BxgE0vQu.js +1 -0
  169. package/dist/control-web/assets/fsharp-CXgrBDvD.js +1 -0
  170. package/dist/control-web/assets/ganttDiagram-NO4QXBWP-qBdh7A-P.js +292 -0
  171. package/dist/control-web/assets/gdresource-BOOCDP_w.js +1 -0
  172. package/dist/control-web/assets/gdscript-C5YyOfLZ.js +1 -0
  173. package/dist/control-web/assets/gdshader-DkwncUOv.js +1 -0
  174. package/dist/control-web/assets/genie-D0YGMca9.js +1 -0
  175. package/dist/control-web/assets/gherkin-DyxjwDmM.js +1 -0
  176. package/dist/control-web/assets/git-commit-F4YmCXRG.js +1 -0
  177. package/dist/control-web/assets/git-rebase-r7XF79zn.js +1 -0
  178. package/dist/control-web/assets/gitGraphDiagram-IHSO6WYX-BTYub2KT.js +106 -0
  179. package/dist/control-web/assets/github-dark-DHJKELXO.js +1 -0
  180. package/dist/control-web/assets/github-dark-default-Cuk6v7N8.js +1 -0
  181. package/dist/control-web/assets/github-dark-dimmed-DH5Ifo-i.js +1 -0
  182. package/dist/control-web/assets/github-dark-high-contrast-E3gJ1_iC.js +1 -0
  183. package/dist/control-web/assets/github-light-DAi9KRSo.js +1 -0
  184. package/dist/control-web/assets/github-light-default-D7oLnXFd.js +1 -0
  185. package/dist/control-web/assets/github-light-high-contrast-BfjtVDDH.js +1 -0
  186. package/dist/control-web/assets/gleam-BspZqrRM.js +1 -0
  187. package/dist/control-web/assets/glimmer-js-Rg0-pVw9.js +1 -0
  188. package/dist/control-web/assets/glimmer-ts-U6CK756n.js +1 -0
  189. package/dist/control-web/assets/glsl-DplSGwfg.js +1 -0
  190. package/dist/control-web/assets/gn-n2N0HUVH.js +1 -0
  191. package/dist/control-web/assets/gnuplot-DdkO51Og.js +1 -0
  192. package/dist/control-web/assets/go-CxLEBnE3.js +1 -0
  193. package/dist/control-web/assets/graph-C9eacEi8.js +1 -0
  194. package/dist/control-web/assets/graphql-ChdNCCLP.js +1 -0
  195. package/dist/control-web/assets/groovy-gcz8RCvz.js +1 -0
  196. package/dist/control-web/assets/gruvbox-dark-hard-CFHQjOhq.js +1 -0
  197. package/dist/control-web/assets/gruvbox-dark-medium-GsRaNv29.js +1 -0
  198. package/dist/control-web/assets/gruvbox-dark-soft-CVdnzihN.js +1 -0
  199. package/dist/control-web/assets/gruvbox-light-hard-CH1njM8p.js +1 -0
  200. package/dist/control-web/assets/gruvbox-light-medium-DRw_LuNl.js +1 -0
  201. package/dist/control-web/assets/gruvbox-light-soft-hJgmCMqR.js +1 -0
  202. package/dist/control-web/assets/hack-CaT9iCJl.js +1 -0
  203. package/dist/control-web/assets/haml-B8DHNrY2.js +1 -0
  204. package/dist/control-web/assets/handlebars-BL8al0AC.js +1 -0
  205. package/dist/control-web/assets/haskell-Df6bDoY_.js +1 -0
  206. package/dist/control-web/assets/haxe-CzTSHFRz.js +1 -0
  207. package/dist/control-web/assets/hcl-BWvSN4gD.js +1 -0
  208. package/dist/control-web/assets/{highlighted-body-OFNGDK62-BBc3aRDM.js → highlighted-body-OFNGDK62-DyksUrwu.js} +1 -1
  209. package/dist/control-web/assets/hjson-D5-asLiD.js +1 -0
  210. package/dist/control-web/assets/hlsl-D3lLCCz7.js +1 -0
  211. package/dist/control-web/assets/horizon-BUw7H-hv.js +1 -0
  212. package/dist/control-web/assets/horizon-bright-Cn-bp-IR.js +1 -0
  213. package/dist/control-web/assets/houston-DnULxvSX.js +1 -0
  214. package/dist/control-web/assets/html-GMplVEZG.js +1 -0
  215. package/dist/control-web/assets/html-derivative-BFtXZ54Q.js +1 -0
  216. package/dist/control-web/assets/http-jrhK8wxY.js +1 -0
  217. package/dist/control-web/assets/hurl-irOxFIW8.js +1 -0
  218. package/dist/control-web/assets/hxml-Bvhsp5Yf.js +1 -0
  219. package/dist/control-web/assets/hy-DFXneXwc.js +1 -0
  220. package/dist/control-web/assets/imba-DGztddWO.js +1 -0
  221. package/dist/control-web/assets/{index-C1ODT189.js → index-B9SAq_63.js} +151 -147
  222. package/dist/control-web/assets/index-BDaSctIT.js +153 -0
  223. package/dist/control-web/assets/index-CtaYRNgJ.css +32 -0
  224. package/dist/control-web/assets/infoDiagram-FWYZ7A6U-ChbQR3Zo.js +2 -0
  225. package/dist/control-web/assets/ini-BEwlwnbL.js +1 -0
  226. package/dist/control-web/assets/init-Gi6I4Gst.js +1 -0
  227. package/dist/control-web/assets/ishikawaDiagram-FXEZZL3T-C-4_qGzn.js +70 -0
  228. package/dist/control-web/assets/java-CylS5w8V.js +1 -0
  229. package/dist/control-web/assets/javascript-wDzz0qaB.js +1 -0
  230. package/dist/control-web/assets/jinja-4LBKfQ-Z.js +1 -0
  231. package/dist/control-web/assets/jison-wvAkD_A8.js +1 -0
  232. package/dist/control-web/assets/journeyDiagram-5HDEW3XC-B090zN18.js +139 -0
  233. package/dist/control-web/assets/json-Cp-IABpG.js +1 -0
  234. package/dist/control-web/assets/json5-C9tS-k6U.js +1 -0
  235. package/dist/control-web/assets/jsonc-Des-eS-w.js +1 -0
  236. package/dist/control-web/assets/jsonl-DcaNXYhu.js +1 -0
  237. package/dist/control-web/assets/jsonnet-DFQXde-d.js +1 -0
  238. package/dist/control-web/assets/jssm-C2t-YnRu.js +1 -0
  239. package/dist/control-web/assets/jsx-g9-lgVsj.js +1 -0
  240. package/dist/control-web/assets/julia-CxzCAyBv.js +1 -0
  241. package/dist/control-web/assets/just-Cw27pwNe.js +1 -0
  242. package/dist/control-web/assets/kanagawa-dragon-CkXjmgJE.js +1 -0
  243. package/dist/control-web/assets/kanagawa-lotus-CfQXZHmo.js +1 -0
  244. package/dist/control-web/assets/kanagawa-wave-DWedfzmr.js +1 -0
  245. package/dist/control-web/assets/kanban-definition-HUTT4EX6-RlTcRbPs.js +89 -0
  246. package/dist/control-web/assets/kdl-DV7GczEv.js +1 -0
  247. package/dist/control-web/assets/kotlin-BdnUsdx6.js +1 -0
  248. package/dist/control-web/assets/kusto-DZf3V79B.js +1 -0
  249. package/dist/control-web/assets/laserwave-DUszq2jm.js +1 -0
  250. package/dist/control-web/assets/latex-CWtU0Tv5.js +1 -0
  251. package/dist/control-web/assets/layout-DEXfKzaS.js +1 -0
  252. package/dist/control-web/assets/lean-BZvkOJ9d.js +1 -0
  253. package/dist/control-web/assets/less-B1dDrJ26.js +1 -0
  254. package/dist/control-web/assets/light-plus-B7mTdjB0.js +1 -0
  255. package/dist/control-web/assets/linear-DTuNxDqu.js +1 -0
  256. package/dist/control-web/assets/liquid-DYVedYrR.js +1 -0
  257. package/dist/control-web/assets/llvm-DjAJT7YJ.js +1 -0
  258. package/dist/control-web/assets/log-2UxHyX5q.js +1 -0
  259. package/dist/control-web/assets/logo-BtOb2qkB.js +1 -0
  260. package/dist/control-web/assets/lua-BaeVxFsk.js +1 -0
  261. package/dist/control-web/assets/luau-C-HG3fhB.js +1 -0
  262. package/dist/control-web/assets/make-CHLpvVh8.js +1 -0
  263. package/dist/control-web/assets/map-Czzmt4hB.js +1 -0
  264. package/dist/control-web/assets/markdown-Cvjx9yec.js +1 -0
  265. package/dist/control-web/assets/marko-CnJfTvn9.js +1 -0
  266. package/dist/control-web/assets/material-theme-D5KoaKCx.js +1 -0
  267. package/dist/control-web/assets/material-theme-darker-BfHTSMKl.js +1 -0
  268. package/dist/control-web/assets/material-theme-lighter-B0m2ddpp.js +1 -0
  269. package/dist/control-web/assets/material-theme-ocean-CyktbL80.js +1 -0
  270. package/dist/control-web/assets/material-theme-palenight-Csfq5Kiy.js +1 -0
  271. package/dist/control-web/assets/matlab-D7o27uSR.js +1 -0
  272. package/dist/control-web/assets/mdc-BMNejdWA.js +1 -0
  273. package/dist/control-web/assets/mdx-Cmh6b_Ma.js +1 -0
  274. package/dist/control-web/assets/mermaid-GHXKKRXX-BYZTj3zW.css +1 -0
  275. package/dist/control-web/assets/mermaid-GHXKKRXX-BkcV3dgg.js +710 -0
  276. package/dist/control-web/assets/mermaid-mWjccvbQ.js +1 -0
  277. package/dist/control-web/assets/min-dark-CafNBF8u.js +1 -0
  278. package/dist/control-web/assets/min-light-CTRr51gU.js +1 -0
  279. package/dist/control-web/assets/mindmap-definition-LN4V7U3C-DYby41E9.js +96 -0
  280. package/dist/control-web/assets/mipsasm-CKIfxQSi.js +1 -0
  281. package/dist/control-web/assets/mojo-rZm6bMo-.js +1 -0
  282. package/dist/control-web/assets/monokai-D4h5O-jR.js +1 -0
  283. package/dist/control-web/assets/moonbit-_H4v1dQx.js +1 -0
  284. package/dist/control-web/assets/move-IF9eRakj.js +1 -0
  285. package/dist/control-web/assets/narrat-DRg8JJMk.js +1 -0
  286. package/dist/control-web/assets/nextflow-Zz6hmt5N.js +1 -0
  287. package/dist/control-web/assets/nextflow-groovy-BeH2EWoN.js +1 -0
  288. package/dist/control-web/assets/nginx-BpAMiNFr.js +1 -0
  289. package/dist/control-web/assets/night-owl-C39BiMTA.js +1 -0
  290. package/dist/control-web/assets/night-owl-light-CMTm3GFP.js +1 -0
  291. package/dist/control-web/assets/nim-CVrawwO9.js +1 -0
  292. package/dist/control-web/assets/nix-CwoSXNpI.js +1 -0
  293. package/dist/control-web/assets/nord-Ddv68eIx.js +1 -0
  294. package/dist/control-web/assets/nushell-Cz2AlsmD.js +1 -0
  295. package/dist/control-web/assets/objective-c-DXmwc3jG.js +1 -0
  296. package/dist/control-web/assets/objective-cpp-CLxacb5B.js +1 -0
  297. package/dist/control-web/assets/ocaml-C0hk2d4L.js +1 -0
  298. package/dist/control-web/assets/odin-BBf5iR-q.js +1 -0
  299. package/dist/control-web/assets/one-dark-pro-DVMEJ2y_.js +1 -0
  300. package/dist/control-web/assets/one-light-C3Wv6jpd.js +1 -0
  301. package/dist/control-web/assets/openscad-C4EeE6gA.js +1 -0
  302. package/dist/control-web/assets/ordinal-Cboi1Yqb.js +1 -0
  303. package/dist/control-web/assets/pascal-D93ZcfNL.js +1 -0
  304. package/dist/control-web/assets/pegDiagram-2B236MQR-CPK6GaEv.js +1 -0
  305. package/dist/control-web/assets/perl-C0TMdlhV.js +1 -0
  306. package/dist/control-web/assets/php-Dhbhpdrm.js +1 -0
  307. package/dist/control-web/assets/pieDiagram-ENE6RG2P-DLCmXuji.js +39 -0
  308. package/dist/control-web/assets/pkl-u5AG7uiY.js +1 -0
  309. package/dist/control-web/assets/plastic-3e1v2bzS.js +1 -0
  310. package/dist/control-web/assets/plsql-ChMvpjG-.js +1 -0
  311. package/dist/control-web/assets/po-BTJTHyun.js +1 -0
  312. package/dist/control-web/assets/poimandres-CS3Unz2-.js +1 -0
  313. package/dist/control-web/assets/polar-C0HS_06l.js +1 -0
  314. package/dist/control-web/assets/postcss-CXtECtnM.js +1 -0
  315. package/dist/control-web/assets/powerquery-CEu0bR-o.js +1 -0
  316. package/dist/control-web/assets/powershell-Dpen1YoG.js +1 -0
  317. package/dist/control-web/assets/prisma-Dd19v3D-.js +1 -0
  318. package/dist/control-web/assets/prolog-CbFg5uaA.js +1 -0
  319. package/dist/control-web/assets/proto-C7zT0LnQ.js +1 -0
  320. package/dist/control-web/assets/pug-CGlum2m_.js +1 -0
  321. package/dist/control-web/assets/puppet-BMWR74SV.js +1 -0
  322. package/dist/control-web/assets/purescript-CklMAg4u.js +1 -0
  323. package/dist/control-web/assets/python-B6aJPvgy.js +1 -0
  324. package/dist/control-web/assets/qml-3beO22l8.js +1 -0
  325. package/dist/control-web/assets/qmldir-C8lEn-DE.js +1 -0
  326. package/dist/control-web/assets/qss-IeuSbFQv.js +1 -0
  327. package/dist/control-web/assets/quadrantDiagram-ABIIQ3AL-RIS8r7CA.js +7 -0
  328. package/dist/control-web/assets/r-Dspwwk_N.js +1 -0
  329. package/dist/control-web/assets/racket-BqYA7rlc.js +1 -0
  330. package/dist/control-web/assets/railroadDiagram-RFXS5EU6-B1HB7xsg.js +1 -0
  331. package/dist/control-web/assets/raku-DXvB9xmW.js +1 -0
  332. package/dist/control-web/assets/razor-Uh8Bk_45.js +1 -0
  333. package/dist/control-web/assets/red-bN70gL4F.js +1 -0
  334. package/dist/control-web/assets/reg-C-SQnVFl.js +1 -0
  335. package/dist/control-web/assets/regexp-CDVJQ6XC.js +1 -0
  336. package/dist/control-web/assets/rel-C3B-1QV4.js +1 -0
  337. package/dist/control-web/assets/requirementDiagram-TGXJPOKE-Inh_4hU0.js +84 -0
  338. package/dist/control-web/assets/riscv-BM1_JUlF.js +1 -0
  339. package/dist/control-web/assets/ron-D8l8udqQ.js +1 -0
  340. package/dist/control-web/assets/rose-pine-dawn-DHQR4-dF.js +1 -0
  341. package/dist/control-web/assets/rose-pine-moon-D4_iv3hh.js +1 -0
  342. package/dist/control-web/assets/rose-pine-qdsjHGoJ.js +1 -0
  343. package/dist/control-web/assets/rosmsg-BJDFO7_C.js +1 -0
  344. package/dist/control-web/assets/rst-BrH8l1NY.js +1 -0
  345. package/dist/control-web/assets/ruby-Dw2BHqvy.js +1 -0
  346. package/dist/control-web/assets/rust-B1yitclQ.js +1 -0
  347. package/dist/control-web/assets/sankeyDiagram-HTMAVEWB-DPF33kPB.js +40 -0
  348. package/dist/control-web/assets/sas-cz2c8ADy.js +1 -0
  349. package/dist/control-web/assets/sass-Cj5Yp3dK.js +1 -0
  350. package/dist/control-web/assets/scala-C151Ov-r.js +1 -0
  351. package/dist/control-web/assets/scheme-C98Dy4si.js +1 -0
  352. package/dist/control-web/assets/scss-OYdSNvt2.js +1 -0
  353. package/dist/control-web/assets/sdbl-DVxCFoDh.js +1 -0
  354. package/dist/control-web/assets/sequenceDiagram-DBY2YBRQ-iywKWoYc.js +162 -0
  355. package/dist/control-web/assets/shaderlab-Dg9Lc6iA.js +1 -0
  356. package/dist/control-web/assets/shellscript-Yzrsuije.js +1 -0
  357. package/dist/control-web/assets/shellsession-BADoaaVG.js +1 -0
  358. package/dist/control-web/assets/sizeCapture-X5ZJPWSS-DlnHubz9.js +1 -0
  359. package/dist/control-web/assets/slack-dark-BthQWCQV.js +1 -0
  360. package/dist/control-web/assets/slack-ochin-DqwNpetd.js +1 -0
  361. package/dist/control-web/assets/smalltalk-BERRCDM3.js +1 -0
  362. package/dist/control-web/assets/snazzy-light-Bw305WKR.js +1 -0
  363. package/dist/control-web/assets/solarized-dark-DXbdFlpD.js +1 -0
  364. package/dist/control-web/assets/solarized-light-L9t79GZl.js +1 -0
  365. package/dist/control-web/assets/solidity-rGO070M0.js +1 -0
  366. package/dist/control-web/assets/soy-Brmx7dQM.js +1 -0
  367. package/dist/control-web/assets/sparql-rVzFXLq3.js +1 -0
  368. package/dist/control-web/assets/splunk-BtCnVYZw.js +1 -0
  369. package/dist/control-web/assets/sql-BLtJtn59.js +1 -0
  370. package/dist/control-web/assets/ssh-config-_ykCGR6B.js +1 -0
  371. package/dist/control-web/assets/stata-BH5u7GGu.js +1 -0
  372. package/dist/control-web/assets/stateDiagram-2N3HPSRC-CShzll2N.js +1 -0
  373. package/dist/control-web/assets/stateDiagram-v2-6OUMAXLB-Cdx0fWna.js +1 -0
  374. package/dist/control-web/assets/stylus-BEDo0Tqx.js +1 -0
  375. package/dist/control-web/assets/surrealql-Bq5Q-fJD.js +1 -0
  376. package/dist/control-web/assets/svelte-C_ipcX3V.js +1 -0
  377. package/dist/control-web/assets/swift-D82vCrfD.js +1 -0
  378. package/dist/control-web/assets/swimlanes-5IMT3BWC-CxlQpFBv.js +2 -0
  379. package/dist/control-web/assets/swimlanesDiagram-G3AALYLV-CoX0jnUu.js +8 -0
  380. package/dist/control-web/assets/synthwave-84-CbfX1IO0.js +1 -0
  381. package/dist/control-web/assets/system-verilog-CnnmHF94.js +1 -0
  382. package/dist/control-web/assets/systemd-4A_iFExJ.js +1 -0
  383. package/dist/control-web/assets/talonscript-CkByrt1z.js +1 -0
  384. package/dist/control-web/assets/tasl-QIJgUcNo.js +1 -0
  385. package/dist/control-web/assets/tcl-dwOrl1Do.js +1 -0
  386. package/dist/control-web/assets/templ-P3uqSqPl.js +1 -0
  387. package/dist/control-web/assets/terraform-BETggiCN.js +1 -0
  388. package/dist/control-web/assets/tex-idrVyKtj.js +1 -0
  389. package/dist/control-web/assets/timeline-definition-FHXFAJF6-Dlx59Xc3.js +120 -0
  390. package/dist/control-web/assets/tokyo-night-hegEt444.js +1 -0
  391. package/dist/control-web/assets/toml-vGWfd6FD.js +1 -0
  392. package/dist/control-web/assets/ts-tags-zn1MmPIZ.js +1 -0
  393. package/dist/control-web/assets/tsv-B_m7g4N7.js +1 -0
  394. package/dist/control-web/assets/tsx-COt5Ahok.js +1 -0
  395. package/dist/control-web/assets/turtle-BsS91CYL.js +1 -0
  396. package/dist/control-web/assets/twig-DNn4PbVi.js +1 -0
  397. package/dist/control-web/assets/typescript-BPQ3VLAy.js +1 -0
  398. package/dist/control-web/assets/typespec-BGHnOYBU.js +1 -0
  399. package/dist/control-web/assets/typst-DHCkPAjA.js +1 -0
  400. package/dist/control-web/assets/v-BcVCzyr7.js +1 -0
  401. package/dist/control-web/assets/vala-CsfeWuGM.js +1 -0
  402. package/dist/control-web/assets/vb-D17OF-Vu.js +1 -0
  403. package/dist/control-web/assets/vennDiagram-L72KCM5P-DLsv4i_t.js +34 -0
  404. package/dist/control-web/assets/verilog-BQ8w6xss.js +1 -0
  405. package/dist/control-web/assets/vesper-DU1UobuO.js +1 -0
  406. package/dist/control-web/assets/vhdl-CeAyd5Ju.js +1 -0
  407. package/dist/control-web/assets/viml-CJc9bBzg.js +1 -0
  408. package/dist/control-web/assets/vitesse-black-Bkuqu6BP.js +1 -0
  409. package/dist/control-web/assets/vitesse-dark-D0r3Knsf.js +1 -0
  410. package/dist/control-web/assets/vitesse-light-CVO1_9PV.js +1 -0
  411. package/dist/control-web/assets/vue-DN_0RTcg.js +1 -0
  412. package/dist/control-web/assets/vue-html-AaS7Mt5G.js +1 -0
  413. package/dist/control-web/assets/vue-vine-CQOfvN7w.js +1 -0
  414. package/dist/control-web/assets/vyper-CDx5xZoG.js +1 -0
  415. package/dist/control-web/assets/wardleyDiagram-EHGQE667-BazV8fpH.js +78 -0
  416. package/dist/control-web/assets/wasm-CG6Dc4jp.js +1 -0
  417. package/dist/control-web/assets/wasm-MzD3tlZU.js +1 -0
  418. package/dist/control-web/assets/wenyan-BV7otONQ.js +1 -0
  419. package/dist/control-web/assets/wgsl-Dx-B1_4e.js +1 -0
  420. package/dist/control-web/assets/wikitext-BhOHFoWU.js +1 -0
  421. package/dist/control-web/assets/wit-5i3qLPDT.js +1 -0
  422. package/dist/control-web/assets/wolfram-lXgVvXCa.js +1 -0
  423. package/dist/control-web/assets/xml-sdJ4AIDG.js +1 -0
  424. package/dist/control-web/assets/xsl-CtQFsRM5.js +1 -0
  425. package/dist/control-web/assets/xychartDiagram-FW5EYKEG-Bx9uDlYu.js +7 -0
  426. package/dist/control-web/assets/yaml-Buea-lGh.js +1 -0
  427. package/dist/control-web/assets/zenscript-DVFEvuxE.js +1 -0
  428. package/dist/control-web/assets/zig-VOosw3JB.js +1 -0
  429. package/dist/control-web/index.html +2 -2
  430. package/dist/machine-session-service.d.ts +58 -7
  431. package/dist/machine-session-service.js +510 -22
  432. package/dist/remote-runtime-dispatcher.d.ts +1 -1
  433. package/dist/remote-runtime-dispatcher.js +8 -0
  434. package/dist/remote-runtime-session-projection.js +3 -0
  435. package/dist/server.d.ts +9 -3
  436. package/dist/server.js +81 -4
  437. package/dist/session-runtime-index.js +13 -0
  438. package/package.json +7 -7
  439. package/dist/control-web/assets/index-DOUyXr2J.css +0 -32
  440. package/dist/control-web/assets/mermaid-GHXKKRXX-BkqCCgCk.js +0 -131
@@ -7,6 +7,7 @@
7
7
  * owns that state and exposes its own management application.
8
8
  */
9
9
  import { timingSafeEqual } from "node:crypto";
10
+ import { Readable } from "node:stream";
10
11
  import Router from "@koa/router";
11
12
  import { skillInstallRecipeSchema, } from "@rynx-ai/core";
12
13
  import { DAEMON_BROWSER_ARTIFACT_CLEAN_PATH, DAEMON_BROWSER_ARTIFACT_INSTALL_PATH, DAEMON_BROWSER_ARTIFACT_UPDATE_PATH, DAEMON_BROWSER_ARTIFACT_VERSION_PATH, DAEMON_CHROME_INSPECTION_PATH, DAEMON_CLEANUP_SESSIONS_PATH, DAEMON_MAINTENANCE_LEASE_HEADER, DAEMON_MAINTENANCE_LEASE_RELEASE_PATH, DAEMON_SHUTDOWN_IF_IDLE_PATH, parseDaemonBrowserArtifactInstallInput, parseDaemonBrowserArtifactUpdateInput, parseDaemonChromeInspectionConfigureInput, parseDaemonCleanupSessionsInput, } from "@rynx-ai/protocol/control";
@@ -859,7 +860,13 @@ export function createControlRouter(opts) {
859
860
  };
860
861
  const runtimeSessionResourceUpload = async (ctx) => {
861
862
  const uploadStarted = performance.now();
862
- const mediaType = ctx.get("content-type").split(";", 1)[0]?.trim();
863
+ const mediaType = ctx.get("content-type").split(";", 1)[0]?.trim().toLowerCase();
864
+ const requestedType = ctx.get("x-rynx-resource-type").trim();
865
+ const resourceType = requestedType === "input_image" || requestedType === "input_file"
866
+ ? requestedType
867
+ : SESSION_IMAGE_MEDIA_TYPES.includes(mediaType)
868
+ ? "input_image"
869
+ : "input_file";
863
870
  const clientUploadId = ctx.get("x-rynx-upload-id").trim();
864
871
  const encodedFilename = ctx.get("x-rynx-filename").trim();
865
872
  let filename = "";
@@ -872,7 +879,9 @@ export function createControlRouter(opts) {
872
879
  return;
873
880
  }
874
881
  if (!mediaType ||
875
- !SESSION_IMAGE_MEDIA_TYPES.includes(mediaType) ||
882
+ !isMediaType(mediaType) ||
883
+ (resourceType === "input_image" &&
884
+ !SESSION_IMAGE_MEDIA_TYPES.includes(mediaType)) ||
876
885
  !clientUploadId ||
877
886
  !filename ||
878
887
  filename.length > SESSION_RESOURCE_MAX_FILENAME_CHARS) {
@@ -880,23 +889,21 @@ export function createControlRouter(opts) {
880
889
  ctx.body = { error: "invalid_resource_upload" };
881
890
  return;
882
891
  }
883
- let bytes;
884
- const bodyReadStarted = performance.now();
885
- try {
886
- bytes = await readBoundedBinary(ctx, SESSION_RESOURCE_MAX_IMAGE_BYTES);
887
- }
888
- catch (error) {
889
- ctx.status = error instanceof RequestBodyTooLargeError ? 413 : 400;
890
- ctx.body = {
891
- error: error instanceof RequestBodyTooLargeError
892
- ? "request_too_large"
893
- : "invalid_resource_upload",
894
- };
892
+ const contentLengthHeader = ctx.get("content-length").trim();
893
+ if (!contentLengthHeader) {
894
+ ctx.status = 411;
895
+ ctx.body = { error: "content_length_required" };
895
896
  return;
896
897
  }
897
- if (bytes.byteLength === 0) {
898
+ const byteLength = Number(contentLengthHeader);
899
+ if (!Number.isSafeInteger(byteLength) || byteLength <= 0) {
898
900
  ctx.status = 400;
899
- ctx.body = { error: "empty_resource" };
901
+ ctx.body = { error: "invalid_content_length" };
902
+ return;
903
+ }
904
+ if (resourceType === "input_image" && byteLength > SESSION_RESOURCE_MAX_IMAGE_BYTES) {
905
+ ctx.status = 413;
906
+ ctx.body = { error: "request_too_large" };
900
907
  return;
901
908
  }
902
909
  const sessionId = ctx.params.id;
@@ -904,9 +911,7 @@ export function createControlRouter(opts) {
904
911
  const lease = local ? undefined : await acquireRuntimeLease(ctx);
905
912
  if (!local && !lease)
906
913
  return;
907
- const timings = new Map([
908
- ["body", performance.now() - bodyReadStarted],
909
- ]);
914
+ const timings = new Map();
910
915
  const timed = async (name, operation) => {
911
916
  const started = performance.now();
912
917
  try {
@@ -923,16 +928,18 @@ export function createControlRouter(opts) {
923
928
  ? local.beginResourceUpload({
924
929
  sessionId,
925
930
  clientUploadId,
931
+ type: resourceType,
926
932
  filename,
927
933
  mediaType,
928
- byteLength: bytes.byteLength,
934
+ byteLength,
929
935
  })
930
936
  : lease.call("session.resource.upload.begin", {
931
937
  sessionId,
932
938
  clientUploadId,
939
+ type: resourceType,
933
940
  filename,
934
941
  mediaType,
935
- byteLength: bytes.byteLength,
942
+ byteLength,
936
943
  }, { timeoutMs: REMOTE_RUNTIME_SESSION_TIMEOUT_MS }));
937
944
  const writeChunk = (uploadId, offset, data) => timed("chunks", () => local
938
945
  ? local.writeResourceUploadChunk({ sessionId, uploadId, offset, data })
@@ -940,44 +947,72 @@ export function createControlRouter(opts) {
940
947
  const commit = (uploadId) => timed("commit", () => local
941
948
  ? local.commitResourceUpload({ sessionId, uploadId })
942
949
  : lease.call("session.resource.upload.commit", { sessionId, uploadId }, { timeoutMs: REMOTE_RUNTIME_SESSION_TIMEOUT_MS }));
950
+ const discardPartial = (resourceId) => timed("restart", () => local
951
+ ? local.deleteResource({ sessionId, resourceId })
952
+ : lease.call("session.resource.delete", { sessionId, resourceId }, { timeoutMs: REMOTE_RUNTIME_SESSION_TIMEOUT_MS }));
953
+ let requestResourceId;
954
+ let resourceCommitted = false;
943
955
  try {
944
956
  const resourcePolicy = await policy();
945
957
  if (!resourcePolicy.enabled ||
946
- !resourcePolicy.mediaTypes.includes(mediaType) ||
947
- bytes.byteLength > resourcePolicy.maxImageBytes) {
958
+ (resourceType === "input_image" &&
959
+ (!resourcePolicy.mediaTypes.includes(mediaType) ||
960
+ byteLength > resourcePolicy.maxImageBytes))) {
948
961
  ctx.status = 413;
949
962
  ctx.body = { error: "resource_policy_rejected" };
950
963
  return;
951
964
  }
952
- const begun = await begin();
965
+ let begun = await begin();
953
966
  if (begun.complete && begun.resource) {
967
+ ctx.req.resume();
954
968
  ctx.set("Cache-Control", "no-store");
955
969
  ctx.body = { resource: begun.resource };
956
970
  return;
957
971
  }
958
- if (begun.offset < 0 || begun.offset > bytes.byteLength) {
972
+ if (begun.offset < 0 || begun.offset > byteLength) {
959
973
  throw runtimeProtocolError("Runtime Session resource upload offset is invalid");
960
974
  }
961
- let offset = begun.offset;
962
- while (offset < bytes.byteLength) {
963
- const chunk = bytes.subarray(offset, Math.min(offset + SESSION_RESOURCE_TRANSFER_CHUNK_BYTES, bytes.byteLength));
964
- const written = await writeChunk(begun.uploadId, offset, chunk.toString("base64"));
965
- if (written.offset <= offset || written.offset > bytes.byteLength) {
966
- throw runtimeProtocolError("Runtime Session resource upload did not advance");
975
+ // Browser retries send the complete File body again. A target-side
976
+ // partial cannot be blindly combined with the new body's suffix: the
977
+ // caller may have reused an upload id for changed bytes. Restart the
978
+ // incomplete upload so committed content always matches this request.
979
+ if (begun.offset > 0) {
980
+ const discarded = await discardPartial(begun.resourceId);
981
+ if (!discarded.deleted) {
982
+ throw runtimeProtocolError("Runtime Session partial upload could not be restarted");
983
+ }
984
+ begun = await begin();
985
+ if (begun.complete || begun.offset !== 0) {
986
+ throw runtimeProtocolError("Runtime Session resource upload did not restart");
967
987
  }
968
- offset = written.offset;
969
988
  }
989
+ requestResourceId = begun.resourceId;
990
+ const bodyStarted = performance.now();
991
+ await forwardResourceUploadBody(ctx, begun.uploadId, begun.offset, byteLength, writeChunk);
992
+ timings.set("body", performance.now() - bodyStarted);
970
993
  const committed = await commit(begun.uploadId);
971
994
  if (committed.resource.resourceId !== begun.resourceId ||
995
+ committed.resource.type !== resourceType ||
972
996
  committed.resource.mediaType !== mediaType ||
973
- committed.resource.byteLength !== bytes.byteLength) {
997
+ committed.resource.byteLength !== byteLength) {
974
998
  throw runtimeProtocolError("Runtime Session resource upload identity changed");
975
999
  }
1000
+ resourceCommitted = true;
976
1001
  ctx.status = 201;
977
1002
  ctx.set("Cache-Control", "no-store");
978
1003
  ctx.body = committed;
979
1004
  }
980
1005
  catch (error) {
1006
+ if (requestResourceId && !resourceCommitted) {
1007
+ try {
1008
+ await discardPartial(requestResourceId);
1009
+ }
1010
+ catch {
1011
+ // The original error remains authoritative. Targets also reap stale
1012
+ // uploads, so a disconnected target cannot make cleanup block the
1013
+ // browser response indefinitely.
1014
+ }
1015
+ }
981
1016
  runtimeTargetHostError(ctx, error);
982
1017
  }
983
1018
  finally {
@@ -993,7 +1028,7 @@ export function createControlRouter(opts) {
993
1028
  event: "session.resource.upload.slow",
994
1029
  selector: ctx.params.selector,
995
1030
  sessionId,
996
- byteLength: bytes.byteLength,
1031
+ byteLength,
997
1032
  status: ctx.status,
998
1033
  timings: Object.fromEntries([...timings.entries()].map(([name, duration]) => [
999
1034
  name,
@@ -1037,16 +1072,32 @@ export function createControlRouter(opts) {
1037
1072
  const sessionId = ctx.params.id;
1038
1073
  const resourceId = ctx.params.resourceId;
1039
1074
  const local = ctx.params.selector === "local" ? localSessionResources : undefined;
1040
- const lease = local ? undefined : await acquireRuntimeLease(ctx);
1041
- if (!local && !lease)
1075
+ const invocation = downloadInvocationAbortScope(ctx, shutdownSignal);
1076
+ const lease = local ? undefined : await acquireRuntimeLease(ctx, invocation.signal);
1077
+ if (!local && !lease) {
1078
+ invocation.dispose();
1042
1079
  return;
1080
+ }
1081
+ let streamOwnsLease = false;
1082
+ let cleanedUp = false;
1083
+ const cleanup = () => {
1084
+ if (cleanedUp)
1085
+ return;
1086
+ cleanedUp = true;
1087
+ lease?.release();
1088
+ invocation.dispose();
1089
+ };
1043
1090
  try {
1044
1091
  const { resource } = local
1045
1092
  ? await local.getResource({ sessionId, resourceId })
1046
- : await lease.call("session.resource.get", { sessionId, resourceId }, { timeoutMs: REMOTE_RUNTIME_SESSION_TIMEOUT_MS });
1093
+ : await lease.call("session.resource.get", { sessionId, resourceId }, { timeoutMs: REMOTE_RUNTIME_SESSION_TIMEOUT_MS, signal: invocation.signal });
1047
1094
  if (resource.resourceId !== resourceId) {
1048
1095
  throw runtimeProtocolError("Runtime Session resource identity changed");
1049
1096
  }
1097
+ const byteLength = resource.byteLength;
1098
+ if (!Number.isSafeInteger(byteLength) || !byteLength || byteLength < 1) {
1099
+ throw runtimeProtocolError("Runtime Session resource length is invalid");
1100
+ }
1050
1101
  const etag = `"sha256-${resource.sha256}"`;
1051
1102
  ctx.set("Cache-Control", "private, max-age=0, must-revalidate");
1052
1103
  ctx.set("ETag", etag);
@@ -1054,48 +1105,68 @@ export function createControlRouter(opts) {
1054
1105
  ctx.status = 304;
1055
1106
  return;
1056
1107
  }
1057
- const chunks = [];
1058
- let offset = 0;
1059
- while (offset < (resource.byteLength ?? 0)) {
1060
- const result = local
1061
- ? await local.readResource({
1062
- sessionId,
1063
- resourceId,
1064
- offset,
1065
- length: SESSION_RESOURCE_TRANSFER_CHUNK_BYTES,
1066
- })
1067
- : await lease.call("session.resource.read", {
1068
- sessionId,
1069
- resourceId,
1070
- offset,
1071
- length: SESSION_RESOURCE_TRANSFER_CHUNK_BYTES,
1072
- }, { timeoutMs: REMOTE_RUNTIME_SESSION_TIMEOUT_MS });
1073
- const chunk = Buffer.from(result.data, "base64");
1074
- if (result.offset !== offset + chunk.byteLength || (!result.eof && chunk.byteLength === 0)) {
1075
- throw runtimeProtocolError("Runtime Session resource read did not advance");
1076
- }
1077
- chunks.push(chunk);
1078
- offset = result.offset;
1079
- if (result.eof)
1080
- break;
1081
- }
1082
- const body = Buffer.concat(chunks);
1083
- if (body.byteLength !== resource.byteLength) {
1084
- throw runtimeProtocolError("Runtime Session resource length changed");
1108
+ const requestedRange = ctx.get("range");
1109
+ const ifRange = ctx.get("if-range");
1110
+ const range = ifRange && ifRange !== etag
1111
+ ? undefined
1112
+ : parseSingleByteRange(requestedRange, byteLength);
1113
+ if (range === "unsatisfiable") {
1114
+ ctx.status = 416;
1115
+ ctx.set("Content-Range", `bytes */${byteLength}`);
1116
+ return;
1085
1117
  }
1118
+ const start = range?.start ?? 0;
1119
+ const end = range?.end ?? byteLength - 1;
1120
+ const responseLength = end - start + 1;
1086
1121
  ctx.set("Content-Security-Policy", "default-src 'none'; sandbox");
1087
1122
  ctx.set("Cross-Origin-Resource-Policy", "same-origin");
1088
1123
  ctx.set("X-Content-Type-Options", "nosniff");
1089
- ctx.set("Content-Disposition", "inline");
1124
+ ctx.set("Accept-Ranges", "bytes");
1125
+ ctx.set("Content-Disposition", contentDisposition(resource.filename));
1126
+ if (range) {
1127
+ ctx.status = 206;
1128
+ ctx.set("Content-Range", `bytes ${start}-${end}/${byteLength}`);
1129
+ }
1090
1130
  ctx.type = resource.mediaType;
1091
- ctx.length = body.byteLength;
1131
+ ctx.length = responseLength;
1132
+ if (ctx.method === "HEAD") {
1133
+ ctx.status = range ? 206 : 200;
1134
+ return;
1135
+ }
1136
+ streamOwnsLease = true;
1137
+ const body = Readable.from((async function* () {
1138
+ let offset = start;
1139
+ try {
1140
+ while (offset <= end) {
1141
+ const length = Math.min(SESSION_RESOURCE_TRANSFER_CHUNK_BYTES, end - offset + 1);
1142
+ const result = local
1143
+ ? await local.readResource({ sessionId, resourceId, offset, length })
1144
+ : await lease.call("session.resource.read", { sessionId, resourceId, offset, length }, { timeoutMs: REMOTE_RUNTIME_SESSION_TIMEOUT_MS, signal: invocation.signal });
1145
+ const chunk = Buffer.from(result.data, "base64");
1146
+ if (result.offset !== offset + chunk.byteLength || chunk.byteLength === 0) {
1147
+ throw runtimeProtocolError("Runtime Session resource read did not advance");
1148
+ }
1149
+ offset = result.offset;
1150
+ yield chunk;
1151
+ }
1152
+ if (offset !== end + 1) {
1153
+ throw runtimeProtocolError("Runtime Session resource length changed");
1154
+ }
1155
+ }
1156
+ finally {
1157
+ cleanup();
1158
+ }
1159
+ })());
1160
+ body.once("close", cleanup);
1092
1161
  ctx.body = body;
1093
1162
  }
1094
1163
  catch (error) {
1095
1164
  runtimeTargetHostError(ctx, error);
1096
1165
  }
1097
1166
  finally {
1098
- lease?.release();
1167
+ if (!streamOwnsLease) {
1168
+ cleanup();
1169
+ }
1099
1170
  }
1100
1171
  };
1101
1172
  const runtimeSessionResourceDelete = async (ctx) => {
@@ -1119,6 +1190,243 @@ export function createControlRouter(opts) {
1119
1190
  if (outcome.ok)
1120
1191
  ctx.body = outcome.result;
1121
1192
  };
1193
+ const runtimeSessionItemFileContent = async (ctx) => {
1194
+ const sessionId = ctx.params.id;
1195
+ const itemId = ctx.params.itemId;
1196
+ const partIndex = Number(ctx.params.partIndex);
1197
+ if (!Number.isSafeInteger(partIndex) || partIndex < 0 || partIndex > 1_024) {
1198
+ ctx.status = 400;
1199
+ ctx.body = { error: "invalid_part_index" };
1200
+ return;
1201
+ }
1202
+ const local = ctx.params.selector === "local" ? localMachineSessions : undefined;
1203
+ const invocation = downloadInvocationAbortScope(ctx, shutdownSignal);
1204
+ const lease = local ? undefined : await acquireRuntimeLease(ctx, invocation.signal);
1205
+ if (!local && !lease) {
1206
+ invocation.dispose();
1207
+ return;
1208
+ }
1209
+ let streamOwnsLease = false;
1210
+ let cleanedUp = false;
1211
+ const cleanup = () => {
1212
+ if (cleanedUp)
1213
+ return;
1214
+ cleanedUp = true;
1215
+ lease?.release();
1216
+ invocation.dispose();
1217
+ };
1218
+ try {
1219
+ const { file } = local
1220
+ ? await local.getFile({ sessionId, itemId, partIndex })
1221
+ : await lease.call("session.file.get", { sessionId, itemId, partIndex }, { timeoutMs: REMOTE_RUNTIME_SESSION_TIMEOUT_MS, signal: invocation.signal });
1222
+ if (file.itemId !== itemId || file.partIndex !== partIndex) {
1223
+ throw runtimeProtocolError("Runtime Session file identity changed");
1224
+ }
1225
+ const etag = `"file-${file.version}"`;
1226
+ ctx.set("Cache-Control", "private, max-age=0, must-revalidate");
1227
+ ctx.set("ETag", etag);
1228
+ if (ctx.get("if-none-match").split(",").map((value) => value.trim()).includes(etag)) {
1229
+ ctx.status = 304;
1230
+ return;
1231
+ }
1232
+ const requestedRange = ctx.get("range");
1233
+ const ifRange = ctx.get("if-range");
1234
+ const range = ifRange && ifRange !== etag
1235
+ ? undefined
1236
+ : parseSingleByteRange(requestedRange, file.byteLength);
1237
+ if (range === "unsatisfiable") {
1238
+ ctx.status = 416;
1239
+ ctx.set("Content-Range", `bytes */${file.byteLength}`);
1240
+ return;
1241
+ }
1242
+ const start = range?.start ?? 0;
1243
+ const end = range?.end ?? file.byteLength - 1;
1244
+ ctx.set("Content-Security-Policy", "default-src 'none'; sandbox");
1245
+ ctx.set("Cross-Origin-Resource-Policy", "same-origin");
1246
+ ctx.set("X-Content-Type-Options", "nosniff");
1247
+ ctx.set("Accept-Ranges", "bytes");
1248
+ ctx.set("Content-Disposition", contentDisposition(file.filename));
1249
+ if (range) {
1250
+ ctx.status = 206;
1251
+ ctx.set("Content-Range", `bytes ${start}-${end}/${file.byteLength}`);
1252
+ }
1253
+ ctx.type = file.mediaType;
1254
+ ctx.length = end - start + 1;
1255
+ if (ctx.method === "HEAD") {
1256
+ ctx.status = range ? 206 : 200;
1257
+ return;
1258
+ }
1259
+ streamOwnsLease = true;
1260
+ const body = Readable.from((async function* () {
1261
+ let offset = start;
1262
+ try {
1263
+ while (offset <= end) {
1264
+ const length = Math.min(SESSION_RESOURCE_TRANSFER_CHUNK_BYTES, end - offset + 1);
1265
+ const result = local
1266
+ ? await local.readFile({
1267
+ sessionId,
1268
+ itemId,
1269
+ partIndex,
1270
+ version: file.version,
1271
+ offset,
1272
+ length,
1273
+ })
1274
+ : await lease.call("session.file.read", {
1275
+ sessionId,
1276
+ itemId,
1277
+ partIndex,
1278
+ version: file.version,
1279
+ offset,
1280
+ length,
1281
+ }, { timeoutMs: REMOTE_RUNTIME_SESSION_TIMEOUT_MS, signal: invocation.signal });
1282
+ const chunk = Buffer.from(result.data, "base64");
1283
+ if (result.offset !== offset + chunk.byteLength || chunk.byteLength === 0) {
1284
+ throw runtimeProtocolError("Runtime Session file read did not advance");
1285
+ }
1286
+ offset = result.offset;
1287
+ yield chunk;
1288
+ }
1289
+ }
1290
+ finally {
1291
+ cleanup();
1292
+ }
1293
+ })());
1294
+ body.once("close", cleanup);
1295
+ ctx.body = body;
1296
+ }
1297
+ catch (error) {
1298
+ runtimeTargetHostError(ctx, error);
1299
+ }
1300
+ finally {
1301
+ if (!streamOwnsLease) {
1302
+ cleanup();
1303
+ }
1304
+ }
1305
+ };
1306
+ const runtimeSessionWorkspaceFileContent = async (ctx) => {
1307
+ const sessionId = ctx.params.id;
1308
+ const path = ctx.query.path;
1309
+ if (typeof path !== "string" ||
1310
+ path.length === 0 ||
1311
+ path.length > 4_096 ||
1312
+ path.includes("\0")) {
1313
+ ctx.status = 400;
1314
+ ctx.body = { error: "invalid_workspace_file_path" };
1315
+ return;
1316
+ }
1317
+ const local = ctx.params.selector === "local" ? localMachineSessions : undefined;
1318
+ const invocation = downloadInvocationAbortScope(ctx, shutdownSignal);
1319
+ const lease = local ? undefined : await acquireRuntimeLease(ctx, invocation.signal);
1320
+ if (!local && !lease) {
1321
+ invocation.dispose();
1322
+ return;
1323
+ }
1324
+ let streamOwnsLease = false;
1325
+ let cleanedUp = false;
1326
+ const cleanup = () => {
1327
+ if (cleanedUp)
1328
+ return;
1329
+ cleanedUp = true;
1330
+ lease?.release();
1331
+ invocation.dispose();
1332
+ };
1333
+ try {
1334
+ const { file } = local
1335
+ ? await local.getWorkspaceFile({ sessionId, path })
1336
+ : await lease.call("session.workspace.file.get", { sessionId, path }, { timeoutMs: REMOTE_RUNTIME_SESSION_TIMEOUT_MS, signal: invocation.signal });
1337
+ if (file.path !== path) {
1338
+ throw runtimeProtocolError("Runtime Session workspace file identity changed");
1339
+ }
1340
+ const etag = `"workspace-file-${file.version}"`;
1341
+ ctx.set("Cache-Control", "private, max-age=0, must-revalidate");
1342
+ ctx.set("ETag", etag);
1343
+ if (ctx.get("if-none-match").split(",").map((value) => value.trim()).includes(etag)) {
1344
+ ctx.status = 304;
1345
+ return;
1346
+ }
1347
+ ctx.set("Content-Security-Policy", "default-src 'none'; sandbox");
1348
+ ctx.set("Cross-Origin-Resource-Policy", "same-origin");
1349
+ ctx.set("X-Content-Type-Options", "nosniff");
1350
+ ctx.set("Accept-Ranges", "bytes");
1351
+ ctx.set("Content-Disposition", contentDisposition(file.filename));
1352
+ ctx.type = file.mediaType;
1353
+ if (file.byteLength === 0) {
1354
+ if (ctx.get("range")) {
1355
+ ctx.status = 416;
1356
+ ctx.set("Content-Range", "bytes */0");
1357
+ return;
1358
+ }
1359
+ ctx.status = 200;
1360
+ ctx.length = 0;
1361
+ if (ctx.method !== "HEAD")
1362
+ ctx.body = Buffer.alloc(0);
1363
+ return;
1364
+ }
1365
+ const requestedRange = ctx.get("range");
1366
+ const ifRange = ctx.get("if-range");
1367
+ const range = ifRange && ifRange !== etag
1368
+ ? undefined
1369
+ : parseSingleByteRange(requestedRange, file.byteLength);
1370
+ if (range === "unsatisfiable") {
1371
+ ctx.status = 416;
1372
+ ctx.set("Content-Range", `bytes */${file.byteLength}`);
1373
+ return;
1374
+ }
1375
+ const start = range?.start ?? 0;
1376
+ const end = range?.end ?? file.byteLength - 1;
1377
+ if (range) {
1378
+ ctx.status = 206;
1379
+ ctx.set("Content-Range", `bytes ${start}-${end}/${file.byteLength}`);
1380
+ }
1381
+ ctx.length = end - start + 1;
1382
+ if (ctx.method === "HEAD") {
1383
+ ctx.status = range ? 206 : 200;
1384
+ return;
1385
+ }
1386
+ streamOwnsLease = true;
1387
+ const body = Readable.from((async function* () {
1388
+ let offset = start;
1389
+ try {
1390
+ while (offset <= end) {
1391
+ const length = Math.min(SESSION_RESOURCE_TRANSFER_CHUNK_BYTES, end - offset + 1);
1392
+ const result = local
1393
+ ? await local.readWorkspaceFile({
1394
+ sessionId,
1395
+ path,
1396
+ version: file.version,
1397
+ offset,
1398
+ length,
1399
+ })
1400
+ : await lease.call("session.workspace.file.read", {
1401
+ sessionId,
1402
+ path,
1403
+ version: file.version,
1404
+ offset,
1405
+ length,
1406
+ }, { timeoutMs: REMOTE_RUNTIME_SESSION_TIMEOUT_MS, signal: invocation.signal });
1407
+ const chunk = Buffer.from(result.data, "base64");
1408
+ if (result.offset !== offset + chunk.byteLength || chunk.byteLength === 0) {
1409
+ throw runtimeProtocolError("Runtime Session workspace file read did not advance");
1410
+ }
1411
+ offset = result.offset;
1412
+ yield chunk;
1413
+ }
1414
+ }
1415
+ finally {
1416
+ cleanup();
1417
+ }
1418
+ })());
1419
+ body.once("close", cleanup);
1420
+ ctx.body = body;
1421
+ }
1422
+ catch (error) {
1423
+ runtimeTargetHostError(ctx, error);
1424
+ }
1425
+ finally {
1426
+ if (!streamOwnsLease)
1427
+ cleanup();
1428
+ }
1429
+ };
1122
1430
  const runtimeSessionMessageEnqueue = async (ctx) => {
1123
1431
  const body = await readRuntimeBody(ctx);
1124
1432
  if (!body)
@@ -1750,6 +2058,11 @@ export function createControlRouter(opts) {
1750
2058
  router.post("/api/runtimes/:selector/sessions/:id/resources", publicRuntimeMutation(runtimeSessionResourceUpload));
1751
2059
  router.get("/api/runtimes/:selector/sessions/:id/resources/:resourceId", publicRuntimeRead(runtimeSessionResourceMetadata));
1752
2060
  router.get("/api/runtimes/:selector/sessions/:id/resources/:resourceId/content", publicRuntimeRead(runtimeSessionResourceContent));
2061
+ router.head("/api/runtimes/:selector/sessions/:id/resources/:resourceId/content", publicRuntimeRead(runtimeSessionResourceContent));
2062
+ router.get("/api/runtimes/:selector/sessions/:id/items/:itemId/files/:partIndex/content", publicRuntimeRead(runtimeSessionItemFileContent));
2063
+ router.head("/api/runtimes/:selector/sessions/:id/items/:itemId/files/:partIndex/content", publicRuntimeRead(runtimeSessionItemFileContent));
2064
+ router.get("/api/runtimes/:selector/sessions/:id/workspace/files/content", publicRuntimeRead(runtimeSessionWorkspaceFileContent));
2065
+ router.head("/api/runtimes/:selector/sessions/:id/workspace/files/content", publicRuntimeRead(runtimeSessionWorkspaceFileContent));
1753
2066
  router.delete("/api/runtimes/:selector/sessions/:id/resources/:resourceId", publicRuntimeMutation(runtimeSessionResourceDelete));
1754
2067
  router.post("/api/runtimes/:selector/sessions/:id/messages/queue", publicRuntimeMutation(runtimeSessionMessageEnqueue));
1755
2068
  router.post("/api/runtimes/:selector/sessions/:id/terminal/start", publicRuntimeMutation(runtimeSessionTerminalStart));
@@ -3709,6 +4022,36 @@ function pluginInstallInvocationAbortScope(ctx, shutdownSignal) {
3709
4022
  function browserArtifactInvocationAbortScope(ctx, shutdownSignal) {
3710
4023
  return managementInvocationAbortScope(ctx, shutdownSignal, BROWSER_ARTIFACT_OPERATION_TIMEOUT_MS, "Browser artifact operation");
3711
4024
  }
4025
+ function downloadInvocationAbortScope(ctx, shutdownSignal) {
4026
+ const controller = new AbortController();
4027
+ const abort = (reason) => {
4028
+ if (!controller.signal.aborted)
4029
+ controller.abort(reason);
4030
+ };
4031
+ const onRequestAborted = () => abort(namedError("download request aborted", "AbortError"));
4032
+ const onResponseClose = () => {
4033
+ if (!ctx.res.writableEnded) {
4034
+ abort(namedError("download client disconnected", "AbortError"));
4035
+ }
4036
+ };
4037
+ const onShutdown = () => abort(shutdownSignal?.reason ?? namedError("daemon is shutting down", "AbortError"));
4038
+ ctx.req.once("aborted", onRequestAborted);
4039
+ ctx.res.once("close", onResponseClose);
4040
+ if (shutdownSignal?.aborted)
4041
+ onShutdown();
4042
+ else
4043
+ shutdownSignal?.addEventListener("abort", onShutdown, { once: true });
4044
+ if (ctx.req.aborted)
4045
+ onRequestAborted();
4046
+ return {
4047
+ signal: controller.signal,
4048
+ dispose() {
4049
+ ctx.req.removeListener("aborted", onRequestAborted);
4050
+ ctx.res.removeListener("close", onResponseClose);
4051
+ shutdownSignal?.removeEventListener("abort", onShutdown);
4052
+ },
4053
+ };
4054
+ }
3712
4055
  function managementInvocationAbortScope(ctx, shutdownSignal, timeoutMs, label) {
3713
4056
  const controller = new AbortController();
3714
4057
  const abort = (reason) => {
@@ -4024,6 +4367,83 @@ function publicRuntimeStreamError(error) {
4024
4367
  }
4025
4368
  class RequestBodyTooLargeError extends Error {
4026
4369
  }
4370
+ function isMediaType(value) {
4371
+ return value.length <= 255 && /^[a-z0-9!#$&^_.+-]+\/[a-z0-9!#$&^_.+-]+$/.test(value);
4372
+ }
4373
+ async function forwardResourceUploadBody(ctx, uploadId, resumeOffset, expectedBytes, writeChunk) {
4374
+ let received = 0;
4375
+ let remoteOffset = resumeOffset;
4376
+ let carry = Buffer.alloc(0);
4377
+ for await (const raw of ctx.req) {
4378
+ const incoming = Buffer.isBuffer(raw) ? raw : Buffer.from(raw);
4379
+ if (received + incoming.byteLength > expectedBytes) {
4380
+ throw runtimeProtocolError("Resource upload exceeds Content-Length");
4381
+ }
4382
+ const skip = Math.min(incoming.byteLength, Math.max(0, resumeOffset - received));
4383
+ received += incoming.byteLength;
4384
+ let cursor = skip;
4385
+ while (cursor < incoming.byteLength) {
4386
+ const needed = SESSION_RESOURCE_TRANSFER_CHUNK_BYTES - carry.byteLength;
4387
+ const take = Math.min(needed, incoming.byteLength - cursor);
4388
+ carry = carry.byteLength === 0
4389
+ ? incoming.subarray(cursor, cursor + take)
4390
+ : Buffer.concat([carry, incoming.subarray(cursor, cursor + take)]);
4391
+ cursor += take;
4392
+ if (carry.byteLength < SESSION_RESOURCE_TRANSFER_CHUNK_BYTES)
4393
+ continue;
4394
+ const written = await writeChunk(uploadId, remoteOffset, carry.toString("base64"));
4395
+ if (written.offset !== remoteOffset + carry.byteLength) {
4396
+ throw runtimeProtocolError("Runtime Session resource upload did not advance");
4397
+ }
4398
+ remoteOffset = written.offset;
4399
+ carry = Buffer.alloc(0);
4400
+ }
4401
+ }
4402
+ if (received !== expectedBytes) {
4403
+ throw runtimeProtocolError("Resource upload ended before Content-Length");
4404
+ }
4405
+ if (carry.byteLength > 0) {
4406
+ const written = await writeChunk(uploadId, remoteOffset, carry.toString("base64"));
4407
+ if (written.offset !== remoteOffset + carry.byteLength) {
4408
+ throw runtimeProtocolError("Runtime Session resource upload did not advance");
4409
+ }
4410
+ remoteOffset = written.offset;
4411
+ }
4412
+ if (remoteOffset !== expectedBytes) {
4413
+ throw runtimeProtocolError("Runtime Session resource upload length changed");
4414
+ }
4415
+ }
4416
+ function parseSingleByteRange(header, byteLength) {
4417
+ if (!header)
4418
+ return undefined;
4419
+ const match = /^bytes=(\d*)-(\d*)$/.exec(header.trim());
4420
+ if (!match || byteLength <= 0)
4421
+ return "unsatisfiable";
4422
+ const [, startText, endText] = match;
4423
+ if (!startText && !endText)
4424
+ return "unsatisfiable";
4425
+ if (!startText) {
4426
+ const suffix = Number(endText);
4427
+ if (!Number.isSafeInteger(suffix) || suffix <= 0)
4428
+ return "unsatisfiable";
4429
+ return { start: Math.max(0, byteLength - suffix), end: byteLength - 1 };
4430
+ }
4431
+ const start = Number(startText);
4432
+ const requestedEnd = endText ? Number(endText) : byteLength - 1;
4433
+ if (!Number.isSafeInteger(start) ||
4434
+ !Number.isSafeInteger(requestedEnd) ||
4435
+ start < 0 ||
4436
+ requestedEnd < start ||
4437
+ start >= byteLength) {
4438
+ return "unsatisfiable";
4439
+ }
4440
+ return { start, end: Math.min(requestedEnd, byteLength - 1) };
4441
+ }
4442
+ function contentDisposition(filename) {
4443
+ if (!filename)
4444
+ return "inline";
4445
+ return `inline; filename*=UTF-8''${encodeURIComponent(filename)}`;
4446
+ }
4027
4447
  async function readBoundedBinary(ctx, maxBytes) {
4028
4448
  const declaredLength = Number(ctx.get("content-length"));
4029
4449
  if (Number.isFinite(declaredLength) && declaredLength > maxBytes) {