@rynx-ai/server 0.1.11-beta.25 → 0.1.11-beta.26
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.
- package/dist/control-api.js +488 -68
- package/dist/control-web/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
- package/dist/control-web/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
- package/dist/control-web/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
- package/dist/control-web/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
- package/dist/control-web/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
- package/dist/control-web/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
- package/dist/control-web/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
- package/dist/control-web/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
- package/dist/control-web/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
- package/dist/control-web/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
- package/dist/control-web/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
- package/dist/control-web/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
- package/dist/control-web/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
- package/dist/control-web/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
- package/dist/control-web/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
- package/dist/control-web/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
- package/dist/control-web/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
- package/dist/control-web/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
- package/dist/control-web/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
- package/dist/control-web/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
- package/dist/control-web/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
- package/dist/control-web/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
- package/dist/control-web/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
- package/dist/control-web/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
- package/dist/control-web/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
- package/dist/control-web/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
- package/dist/control-web/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
- package/dist/control-web/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
- package/dist/control-web/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
- package/dist/control-web/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
- package/dist/control-web/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
- package/dist/control-web/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
- package/dist/control-web/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
- package/dist/control-web/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
- package/dist/control-web/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
- package/dist/control-web/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
- package/dist/control-web/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
- package/dist/control-web/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
- package/dist/control-web/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
- package/dist/control-web/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
- package/dist/control-web/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
- package/dist/control-web/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
- package/dist/control-web/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
- package/dist/control-web/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
- package/dist/control-web/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
- package/dist/control-web/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
- package/dist/control-web/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
- package/dist/control-web/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
- package/dist/control-web/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
- package/dist/control-web/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
- package/dist/control-web/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
- package/dist/control-web/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
- package/dist/control-web/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
- package/dist/control-web/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
- package/dist/control-web/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
- package/dist/control-web/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
- package/dist/control-web/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
- package/dist/control-web/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
- package/dist/control-web/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
- package/dist/control-web/assets/abap-BdImnpbu.js +1 -0
- package/dist/control-web/assets/abnfDiagram-VRR7QNED-COu02MlJ.js +1 -0
- package/dist/control-web/assets/actionscript-3-CoDkCxhg.js +1 -0
- package/dist/control-web/assets/ada-bCR0ucgS.js +1 -0
- package/dist/control-web/assets/andromeeda-C4gqWexZ.js +1 -0
- package/dist/control-web/assets/angular-html-CU67Zn6k.js +1 -0
- package/dist/control-web/assets/angular-ts-BwZT4LLn.js +1 -0
- package/dist/control-web/assets/apache-Pmp26Uib.js +1 -0
- package/dist/control-web/assets/apex-D8_7TLub.js +1 -0
- package/dist/control-web/assets/apl-dKokRX4l.js +1 -0
- package/dist/control-web/assets/applescript-Co6uUVPk.js +1 -0
- package/dist/control-web/assets/ara-BRHolxvo.js +1 -0
- package/dist/control-web/assets/arc-DqiFeYAM.js +1 -0
- package/dist/control-web/assets/architectureDiagram-ZJ3FMSHR-BWFGgUV4.js +36 -0
- package/dist/control-web/assets/asciidoc-Ve4PFQV2.js +1 -0
- package/dist/control-web/assets/asm-D_Q5rh1f.js +1 -0
- package/dist/control-web/assets/astro-CbQHKStN.js +1 -0
- package/dist/control-web/assets/aurora-x-D-2ljcwZ.js +1 -0
- package/dist/control-web/assets/awk-DMzUqQB5.js +1 -0
- package/dist/control-web/assets/ayu-dark-DYE7WIF3.js +1 -0
- package/dist/control-web/assets/ayu-light-BA47KaF1.js +1 -0
- package/dist/control-web/assets/ayu-mirage-32ctXXKs.js +1 -0
- package/dist/control-web/assets/ballerina-BFfxhgS-.js +1 -0
- package/dist/control-web/assets/bat-BkioyH1T.js +1 -0
- package/dist/control-web/assets/beancount-k_qm7-4y.js +1 -0
- package/dist/control-web/assets/berry-uYugtg8r.js +1 -0
- package/dist/control-web/assets/bibtex-CHM0blh-.js +1 -0
- package/dist/control-web/assets/bicep-Bmn6On1c.js +1 -0
- package/dist/control-web/assets/bird2-DPOp833l.js +1 -0
- package/dist/control-web/assets/blade-D4QpJJKB.js +1 -0
- package/dist/control-web/assets/blockDiagram-677ZJIJ3-ZC0bXDzB.js +132 -0
- package/dist/control-web/assets/bsl-BO_Y6i37.js +1 -0
- package/dist/control-web/assets/c-BIGW1oBm.js +1 -0
- package/dist/control-web/assets/c3-eo99z4R2.js +1 -0
- package/dist/control-web/assets/c4Diagram-LMCZKHZV-Uupq5I-s.js +10 -0
- package/dist/control-web/assets/cadence-Bv_4Rxtq.js +1 -0
- package/dist/control-web/assets/cairo-KRGpt6FW.js +1 -0
- package/dist/control-web/assets/catppuccin-frappe-DFWUc33u.js +1 -0
- package/dist/control-web/assets/catppuccin-latte-C9dUb6Cb.js +1 -0
- package/dist/control-web/assets/catppuccin-macchiato-DQyhUUbL.js +1 -0
- package/dist/control-web/assets/catppuccin-mocha-D87Tk5Gz.js +1 -0
- package/dist/control-web/assets/channel-3HG15wfa.js +1 -0
- package/dist/control-web/assets/chunk-2Q5K7J3B-C77vwuDM.js +1 -0
- package/dist/control-web/assets/chunk-32BRIVSS-BkfLE_TX.js +1 -0
- package/dist/control-web/assets/chunk-5VM5RSS4-By6zfDWW.js +15 -0
- package/dist/control-web/assets/chunk-EX3LRPZG-CO439p_3.js +231 -0
- package/dist/control-web/assets/chunk-JWPE2WC7-B9BPEwug.js +1 -0
- package/dist/control-web/assets/chunk-MOJQB5TN-CYKygWZz.js +88 -0
- package/dist/control-web/assets/chunk-RYQCIY6F-ug-An4HG.js +1 -0
- package/dist/control-web/assets/chunk-V7JOEXUC-3UFQGnKX.js +206 -0
- package/dist/control-web/assets/chunk-VR4S4FIN-DjspjYUb.js +1 -0
- package/dist/control-web/assets/chunk-XXDRQBXY-3znnutie.js +1 -0
- package/dist/control-web/assets/clarity-D53aC0YG.js +1 -0
- package/dist/control-web/assets/classDiagram-OUVF2IWQ-WmU4L9YT.js +1 -0
- package/dist/control-web/assets/classDiagram-v2-EOCWNBFH-WmU4L9YT.js +1 -0
- package/dist/control-web/assets/clojure-P80f7IUj.js +1 -0
- package/dist/control-web/assets/cmake-D1j8_8rp.js +1 -0
- package/dist/control-web/assets/cobol-nwyudZeR.js +1 -0
- package/dist/control-web/assets/codeowners-Bp6g37R7.js +1 -0
- package/dist/control-web/assets/codeql-DsOJ9woJ.js +1 -0
- package/dist/control-web/assets/coffee-Ch7k5sss.js +1 -0
- package/dist/control-web/assets/common-lisp-Cg-RD9OK.js +1 -0
- package/dist/control-web/assets/coq-DkFqJrB1.js +1 -0
- package/dist/control-web/assets/cose-bilkent-JH36ORCC-Dr28goCd.js +1 -0
- package/dist/control-web/assets/cpp-CofmeUqb.js +1 -0
- package/dist/control-web/assets/crystal-tKQVLTB8.js +1 -0
- package/dist/control-web/assets/csharp-COcwbKMJ.js +1 -0
- package/dist/control-web/assets/css-DPfMkruS.js +1 -0
- package/dist/control-web/assets/csv-fuZLfV_i.js +1 -0
- package/dist/control-web/assets/cue-D82EKSYY.js +1 -0
- package/dist/control-web/assets/cynefin-VYW2F7L2-Be5uJhnw.js +178 -0
- package/dist/control-web/assets/cynefinDiagram-TSTJHNR4-BLxtSvL6.js +62 -0
- package/dist/control-web/assets/cypher-COkxafJQ.js +1 -0
- package/dist/control-web/assets/cytoscape.esm-DTSO7Bv0.js +331 -0
- package/dist/control-web/assets/d-85-TOEBH.js +1 -0
- package/dist/control-web/assets/dagre-VKFMJZFB-DPRuDV5p.js +4 -0
- package/dist/control-web/assets/dark-plus-C3mMm8J8.js +1 -0
- package/dist/control-web/assets/dart-CF10PKvl.js +1 -0
- package/dist/control-web/assets/dax-CEL-wOlO.js +1 -0
- package/dist/control-web/assets/defaultLocale-DX6XiGOO.js +1 -0
- package/dist/control-web/assets/desktop-BmXAJ9_W.js +1 -0
- package/dist/control-web/assets/diagram-FQU43EPY-Cybg22U0.js +3 -0
- package/dist/control-web/assets/diagram-G47NLZAW-CGeIKUfW.js +24 -0
- package/dist/control-web/assets/diagram-NH7WQ7WH-BJq5MBRm.js +24 -0
- package/dist/control-web/assets/diagram-OA4YK3LP-DquOQGwg.js +30 -0
- package/dist/control-web/assets/diagram-WEI45ONY-Cblb4xP2.js +41 -0
- package/dist/control-web/assets/diff-D97Zzqfu.js +1 -0
- package/dist/control-web/assets/docker-BcOcwvcX.js +1 -0
- package/dist/control-web/assets/dotenv-Da5cRb03.js +1 -0
- package/dist/control-web/assets/dracula-BzJJZx-M.js +1 -0
- package/dist/control-web/assets/dracula-soft-BXkSAIEj.js +1 -0
- package/dist/control-web/assets/dream-maker-BtqSS_iP.js +1 -0
- package/dist/control-web/assets/ebnfDiagram-CCIWWBDH-CQjHiOqj.js +1 -0
- package/dist/control-web/assets/edge-BkV0erSs.js +1 -0
- package/dist/control-web/assets/elixir-CDX3lj18.js +1 -0
- package/dist/control-web/assets/elm-DbKCFpqz.js +1 -0
- package/dist/control-web/assets/emacs-lisp-C9XAeP06.js +1 -0
- package/dist/control-web/assets/erDiagram-Q63AITRT-Bspr3uKJ.js +85 -0
- package/dist/control-web/assets/erb-B12qg9BL.js +1 -0
- package/dist/control-web/assets/erlang-DsQrWhSR.js +1 -0
- package/dist/control-web/assets/everforest-dark-BgDCqdQA.js +1 -0
- package/dist/control-web/assets/everforest-light-C8M2exoo.js +1 -0
- package/dist/control-web/assets/fennel-BYunw83y.js +1 -0
- package/dist/control-web/assets/fish-BvzEVeQv.js +1 -0
- package/dist/control-web/assets/flowDiagram-23GEKE2U-CxcZyBA-.js +156 -0
- package/dist/control-web/assets/fluent-C4IJs8-o.js +1 -0
- package/dist/control-web/assets/fortran-fixed-form-CkoXwp7k.js +1 -0
- package/dist/control-web/assets/fortran-free-form-BxgE0vQu.js +1 -0
- package/dist/control-web/assets/fsharp-CXgrBDvD.js +1 -0
- package/dist/control-web/assets/ganttDiagram-NO4QXBWP-qBdh7A-P.js +292 -0
- package/dist/control-web/assets/gdresource-BOOCDP_w.js +1 -0
- package/dist/control-web/assets/gdscript-C5YyOfLZ.js +1 -0
- package/dist/control-web/assets/gdshader-DkwncUOv.js +1 -0
- package/dist/control-web/assets/genie-D0YGMca9.js +1 -0
- package/dist/control-web/assets/gherkin-DyxjwDmM.js +1 -0
- package/dist/control-web/assets/git-commit-F4YmCXRG.js +1 -0
- package/dist/control-web/assets/git-rebase-r7XF79zn.js +1 -0
- package/dist/control-web/assets/gitGraphDiagram-IHSO6WYX-BTYub2KT.js +106 -0
- package/dist/control-web/assets/github-dark-DHJKELXO.js +1 -0
- package/dist/control-web/assets/github-dark-default-Cuk6v7N8.js +1 -0
- package/dist/control-web/assets/github-dark-dimmed-DH5Ifo-i.js +1 -0
- package/dist/control-web/assets/github-dark-high-contrast-E3gJ1_iC.js +1 -0
- package/dist/control-web/assets/github-light-DAi9KRSo.js +1 -0
- package/dist/control-web/assets/github-light-default-D7oLnXFd.js +1 -0
- package/dist/control-web/assets/github-light-high-contrast-BfjtVDDH.js +1 -0
- package/dist/control-web/assets/gleam-BspZqrRM.js +1 -0
- package/dist/control-web/assets/glimmer-js-Rg0-pVw9.js +1 -0
- package/dist/control-web/assets/glimmer-ts-U6CK756n.js +1 -0
- package/dist/control-web/assets/glsl-DplSGwfg.js +1 -0
- package/dist/control-web/assets/gn-n2N0HUVH.js +1 -0
- package/dist/control-web/assets/gnuplot-DdkO51Og.js +1 -0
- package/dist/control-web/assets/go-CxLEBnE3.js +1 -0
- package/dist/control-web/assets/graph-C9eacEi8.js +1 -0
- package/dist/control-web/assets/graphql-ChdNCCLP.js +1 -0
- package/dist/control-web/assets/groovy-gcz8RCvz.js +1 -0
- package/dist/control-web/assets/gruvbox-dark-hard-CFHQjOhq.js +1 -0
- package/dist/control-web/assets/gruvbox-dark-medium-GsRaNv29.js +1 -0
- package/dist/control-web/assets/gruvbox-dark-soft-CVdnzihN.js +1 -0
- package/dist/control-web/assets/gruvbox-light-hard-CH1njM8p.js +1 -0
- package/dist/control-web/assets/gruvbox-light-medium-DRw_LuNl.js +1 -0
- package/dist/control-web/assets/gruvbox-light-soft-hJgmCMqR.js +1 -0
- package/dist/control-web/assets/hack-CaT9iCJl.js +1 -0
- package/dist/control-web/assets/haml-B8DHNrY2.js +1 -0
- package/dist/control-web/assets/handlebars-BL8al0AC.js +1 -0
- package/dist/control-web/assets/haskell-Df6bDoY_.js +1 -0
- package/dist/control-web/assets/haxe-CzTSHFRz.js +1 -0
- package/dist/control-web/assets/hcl-BWvSN4gD.js +1 -0
- package/dist/control-web/assets/{highlighted-body-OFNGDK62-BBc3aRDM.js → highlighted-body-OFNGDK62-DyksUrwu.js} +1 -1
- package/dist/control-web/assets/hjson-D5-asLiD.js +1 -0
- package/dist/control-web/assets/hlsl-D3lLCCz7.js +1 -0
- package/dist/control-web/assets/horizon-BUw7H-hv.js +1 -0
- package/dist/control-web/assets/horizon-bright-Cn-bp-IR.js +1 -0
- package/dist/control-web/assets/houston-DnULxvSX.js +1 -0
- package/dist/control-web/assets/html-GMplVEZG.js +1 -0
- package/dist/control-web/assets/html-derivative-BFtXZ54Q.js +1 -0
- package/dist/control-web/assets/http-jrhK8wxY.js +1 -0
- package/dist/control-web/assets/hurl-irOxFIW8.js +1 -0
- package/dist/control-web/assets/hxml-Bvhsp5Yf.js +1 -0
- package/dist/control-web/assets/hy-DFXneXwc.js +1 -0
- package/dist/control-web/assets/imba-DGztddWO.js +1 -0
- package/dist/control-web/assets/{index-C1ODT189.js → index-B9SAq_63.js} +151 -147
- package/dist/control-web/assets/index-BDaSctIT.js +153 -0
- package/dist/control-web/assets/index-CtaYRNgJ.css +32 -0
- package/dist/control-web/assets/infoDiagram-FWYZ7A6U-ChbQR3Zo.js +2 -0
- package/dist/control-web/assets/ini-BEwlwnbL.js +1 -0
- package/dist/control-web/assets/init-Gi6I4Gst.js +1 -0
- package/dist/control-web/assets/ishikawaDiagram-FXEZZL3T-C-4_qGzn.js +70 -0
- package/dist/control-web/assets/java-CylS5w8V.js +1 -0
- package/dist/control-web/assets/javascript-wDzz0qaB.js +1 -0
- package/dist/control-web/assets/jinja-4LBKfQ-Z.js +1 -0
- package/dist/control-web/assets/jison-wvAkD_A8.js +1 -0
- package/dist/control-web/assets/journeyDiagram-5HDEW3XC-B090zN18.js +139 -0
- package/dist/control-web/assets/json-Cp-IABpG.js +1 -0
- package/dist/control-web/assets/json5-C9tS-k6U.js +1 -0
- package/dist/control-web/assets/jsonc-Des-eS-w.js +1 -0
- package/dist/control-web/assets/jsonl-DcaNXYhu.js +1 -0
- package/dist/control-web/assets/jsonnet-DFQXde-d.js +1 -0
- package/dist/control-web/assets/jssm-C2t-YnRu.js +1 -0
- package/dist/control-web/assets/jsx-g9-lgVsj.js +1 -0
- package/dist/control-web/assets/julia-CxzCAyBv.js +1 -0
- package/dist/control-web/assets/just-Cw27pwNe.js +1 -0
- package/dist/control-web/assets/kanagawa-dragon-CkXjmgJE.js +1 -0
- package/dist/control-web/assets/kanagawa-lotus-CfQXZHmo.js +1 -0
- package/dist/control-web/assets/kanagawa-wave-DWedfzmr.js +1 -0
- package/dist/control-web/assets/kanban-definition-HUTT4EX6-RlTcRbPs.js +89 -0
- package/dist/control-web/assets/kdl-DV7GczEv.js +1 -0
- package/dist/control-web/assets/kotlin-BdnUsdx6.js +1 -0
- package/dist/control-web/assets/kusto-DZf3V79B.js +1 -0
- package/dist/control-web/assets/laserwave-DUszq2jm.js +1 -0
- package/dist/control-web/assets/latex-CWtU0Tv5.js +1 -0
- package/dist/control-web/assets/layout-DEXfKzaS.js +1 -0
- package/dist/control-web/assets/lean-BZvkOJ9d.js +1 -0
- package/dist/control-web/assets/less-B1dDrJ26.js +1 -0
- package/dist/control-web/assets/light-plus-B7mTdjB0.js +1 -0
- package/dist/control-web/assets/linear-DTuNxDqu.js +1 -0
- package/dist/control-web/assets/liquid-DYVedYrR.js +1 -0
- package/dist/control-web/assets/llvm-DjAJT7YJ.js +1 -0
- package/dist/control-web/assets/log-2UxHyX5q.js +1 -0
- package/dist/control-web/assets/logo-BtOb2qkB.js +1 -0
- package/dist/control-web/assets/lua-BaeVxFsk.js +1 -0
- package/dist/control-web/assets/luau-C-HG3fhB.js +1 -0
- package/dist/control-web/assets/make-CHLpvVh8.js +1 -0
- package/dist/control-web/assets/map-Czzmt4hB.js +1 -0
- package/dist/control-web/assets/markdown-Cvjx9yec.js +1 -0
- package/dist/control-web/assets/marko-CnJfTvn9.js +1 -0
- package/dist/control-web/assets/material-theme-D5KoaKCx.js +1 -0
- package/dist/control-web/assets/material-theme-darker-BfHTSMKl.js +1 -0
- package/dist/control-web/assets/material-theme-lighter-B0m2ddpp.js +1 -0
- package/dist/control-web/assets/material-theme-ocean-CyktbL80.js +1 -0
- package/dist/control-web/assets/material-theme-palenight-Csfq5Kiy.js +1 -0
- package/dist/control-web/assets/matlab-D7o27uSR.js +1 -0
- package/dist/control-web/assets/mdc-BMNejdWA.js +1 -0
- package/dist/control-web/assets/mdx-Cmh6b_Ma.js +1 -0
- package/dist/control-web/assets/mermaid-GHXKKRXX-BYZTj3zW.css +1 -0
- package/dist/control-web/assets/mermaid-GHXKKRXX-BkcV3dgg.js +710 -0
- package/dist/control-web/assets/mermaid-mWjccvbQ.js +1 -0
- package/dist/control-web/assets/min-dark-CafNBF8u.js +1 -0
- package/dist/control-web/assets/min-light-CTRr51gU.js +1 -0
- package/dist/control-web/assets/mindmap-definition-LN4V7U3C-DYby41E9.js +96 -0
- package/dist/control-web/assets/mipsasm-CKIfxQSi.js +1 -0
- package/dist/control-web/assets/mojo-rZm6bMo-.js +1 -0
- package/dist/control-web/assets/monokai-D4h5O-jR.js +1 -0
- package/dist/control-web/assets/moonbit-_H4v1dQx.js +1 -0
- package/dist/control-web/assets/move-IF9eRakj.js +1 -0
- package/dist/control-web/assets/narrat-DRg8JJMk.js +1 -0
- package/dist/control-web/assets/nextflow-Zz6hmt5N.js +1 -0
- package/dist/control-web/assets/nextflow-groovy-BeH2EWoN.js +1 -0
- package/dist/control-web/assets/nginx-BpAMiNFr.js +1 -0
- package/dist/control-web/assets/night-owl-C39BiMTA.js +1 -0
- package/dist/control-web/assets/night-owl-light-CMTm3GFP.js +1 -0
- package/dist/control-web/assets/nim-CVrawwO9.js +1 -0
- package/dist/control-web/assets/nix-CwoSXNpI.js +1 -0
- package/dist/control-web/assets/nord-Ddv68eIx.js +1 -0
- package/dist/control-web/assets/nushell-Cz2AlsmD.js +1 -0
- package/dist/control-web/assets/objective-c-DXmwc3jG.js +1 -0
- package/dist/control-web/assets/objective-cpp-CLxacb5B.js +1 -0
- package/dist/control-web/assets/ocaml-C0hk2d4L.js +1 -0
- package/dist/control-web/assets/odin-BBf5iR-q.js +1 -0
- package/dist/control-web/assets/one-dark-pro-DVMEJ2y_.js +1 -0
- package/dist/control-web/assets/one-light-C3Wv6jpd.js +1 -0
- package/dist/control-web/assets/openscad-C4EeE6gA.js +1 -0
- package/dist/control-web/assets/ordinal-Cboi1Yqb.js +1 -0
- package/dist/control-web/assets/pascal-D93ZcfNL.js +1 -0
- package/dist/control-web/assets/pegDiagram-2B236MQR-CPK6GaEv.js +1 -0
- package/dist/control-web/assets/perl-C0TMdlhV.js +1 -0
- package/dist/control-web/assets/php-Dhbhpdrm.js +1 -0
- package/dist/control-web/assets/pieDiagram-ENE6RG2P-DLCmXuji.js +39 -0
- package/dist/control-web/assets/pkl-u5AG7uiY.js +1 -0
- package/dist/control-web/assets/plastic-3e1v2bzS.js +1 -0
- package/dist/control-web/assets/plsql-ChMvpjG-.js +1 -0
- package/dist/control-web/assets/po-BTJTHyun.js +1 -0
- package/dist/control-web/assets/poimandres-CS3Unz2-.js +1 -0
- package/dist/control-web/assets/polar-C0HS_06l.js +1 -0
- package/dist/control-web/assets/postcss-CXtECtnM.js +1 -0
- package/dist/control-web/assets/powerquery-CEu0bR-o.js +1 -0
- package/dist/control-web/assets/powershell-Dpen1YoG.js +1 -0
- package/dist/control-web/assets/prisma-Dd19v3D-.js +1 -0
- package/dist/control-web/assets/prolog-CbFg5uaA.js +1 -0
- package/dist/control-web/assets/proto-C7zT0LnQ.js +1 -0
- package/dist/control-web/assets/pug-CGlum2m_.js +1 -0
- package/dist/control-web/assets/puppet-BMWR74SV.js +1 -0
- package/dist/control-web/assets/purescript-CklMAg4u.js +1 -0
- package/dist/control-web/assets/python-B6aJPvgy.js +1 -0
- package/dist/control-web/assets/qml-3beO22l8.js +1 -0
- package/dist/control-web/assets/qmldir-C8lEn-DE.js +1 -0
- package/dist/control-web/assets/qss-IeuSbFQv.js +1 -0
- package/dist/control-web/assets/quadrantDiagram-ABIIQ3AL-RIS8r7CA.js +7 -0
- package/dist/control-web/assets/r-Dspwwk_N.js +1 -0
- package/dist/control-web/assets/racket-BqYA7rlc.js +1 -0
- package/dist/control-web/assets/railroadDiagram-RFXS5EU6-B1HB7xsg.js +1 -0
- package/dist/control-web/assets/raku-DXvB9xmW.js +1 -0
- package/dist/control-web/assets/razor-Uh8Bk_45.js +1 -0
- package/dist/control-web/assets/red-bN70gL4F.js +1 -0
- package/dist/control-web/assets/reg-C-SQnVFl.js +1 -0
- package/dist/control-web/assets/regexp-CDVJQ6XC.js +1 -0
- package/dist/control-web/assets/rel-C3B-1QV4.js +1 -0
- package/dist/control-web/assets/requirementDiagram-TGXJPOKE-Inh_4hU0.js +84 -0
- package/dist/control-web/assets/riscv-BM1_JUlF.js +1 -0
- package/dist/control-web/assets/ron-D8l8udqQ.js +1 -0
- package/dist/control-web/assets/rose-pine-dawn-DHQR4-dF.js +1 -0
- package/dist/control-web/assets/rose-pine-moon-D4_iv3hh.js +1 -0
- package/dist/control-web/assets/rose-pine-qdsjHGoJ.js +1 -0
- package/dist/control-web/assets/rosmsg-BJDFO7_C.js +1 -0
- package/dist/control-web/assets/rst-BrH8l1NY.js +1 -0
- package/dist/control-web/assets/ruby-Dw2BHqvy.js +1 -0
- package/dist/control-web/assets/rust-B1yitclQ.js +1 -0
- package/dist/control-web/assets/sankeyDiagram-HTMAVEWB-DPF33kPB.js +40 -0
- package/dist/control-web/assets/sas-cz2c8ADy.js +1 -0
- package/dist/control-web/assets/sass-Cj5Yp3dK.js +1 -0
- package/dist/control-web/assets/scala-C151Ov-r.js +1 -0
- package/dist/control-web/assets/scheme-C98Dy4si.js +1 -0
- package/dist/control-web/assets/scss-OYdSNvt2.js +1 -0
- package/dist/control-web/assets/sdbl-DVxCFoDh.js +1 -0
- package/dist/control-web/assets/sequenceDiagram-DBY2YBRQ-iywKWoYc.js +162 -0
- package/dist/control-web/assets/shaderlab-Dg9Lc6iA.js +1 -0
- package/dist/control-web/assets/shellscript-Yzrsuije.js +1 -0
- package/dist/control-web/assets/shellsession-BADoaaVG.js +1 -0
- package/dist/control-web/assets/sizeCapture-X5ZJPWSS-DlnHubz9.js +1 -0
- package/dist/control-web/assets/slack-dark-BthQWCQV.js +1 -0
- package/dist/control-web/assets/slack-ochin-DqwNpetd.js +1 -0
- package/dist/control-web/assets/smalltalk-BERRCDM3.js +1 -0
- package/dist/control-web/assets/snazzy-light-Bw305WKR.js +1 -0
- package/dist/control-web/assets/solarized-dark-DXbdFlpD.js +1 -0
- package/dist/control-web/assets/solarized-light-L9t79GZl.js +1 -0
- package/dist/control-web/assets/solidity-rGO070M0.js +1 -0
- package/dist/control-web/assets/soy-Brmx7dQM.js +1 -0
- package/dist/control-web/assets/sparql-rVzFXLq3.js +1 -0
- package/dist/control-web/assets/splunk-BtCnVYZw.js +1 -0
- package/dist/control-web/assets/sql-BLtJtn59.js +1 -0
- package/dist/control-web/assets/ssh-config-_ykCGR6B.js +1 -0
- package/dist/control-web/assets/stata-BH5u7GGu.js +1 -0
- package/dist/control-web/assets/stateDiagram-2N3HPSRC-CShzll2N.js +1 -0
- package/dist/control-web/assets/stateDiagram-v2-6OUMAXLB-Cdx0fWna.js +1 -0
- package/dist/control-web/assets/stylus-BEDo0Tqx.js +1 -0
- package/dist/control-web/assets/surrealql-Bq5Q-fJD.js +1 -0
- package/dist/control-web/assets/svelte-C_ipcX3V.js +1 -0
- package/dist/control-web/assets/swift-D82vCrfD.js +1 -0
- package/dist/control-web/assets/swimlanes-5IMT3BWC-CxlQpFBv.js +2 -0
- package/dist/control-web/assets/swimlanesDiagram-G3AALYLV-CoX0jnUu.js +8 -0
- package/dist/control-web/assets/synthwave-84-CbfX1IO0.js +1 -0
- package/dist/control-web/assets/system-verilog-CnnmHF94.js +1 -0
- package/dist/control-web/assets/systemd-4A_iFExJ.js +1 -0
- package/dist/control-web/assets/talonscript-CkByrt1z.js +1 -0
- package/dist/control-web/assets/tasl-QIJgUcNo.js +1 -0
- package/dist/control-web/assets/tcl-dwOrl1Do.js +1 -0
- package/dist/control-web/assets/templ-P3uqSqPl.js +1 -0
- package/dist/control-web/assets/terraform-BETggiCN.js +1 -0
- package/dist/control-web/assets/tex-idrVyKtj.js +1 -0
- package/dist/control-web/assets/timeline-definition-FHXFAJF6-Dlx59Xc3.js +120 -0
- package/dist/control-web/assets/tokyo-night-hegEt444.js +1 -0
- package/dist/control-web/assets/toml-vGWfd6FD.js +1 -0
- package/dist/control-web/assets/ts-tags-zn1MmPIZ.js +1 -0
- package/dist/control-web/assets/tsv-B_m7g4N7.js +1 -0
- package/dist/control-web/assets/tsx-COt5Ahok.js +1 -0
- package/dist/control-web/assets/turtle-BsS91CYL.js +1 -0
- package/dist/control-web/assets/twig-DNn4PbVi.js +1 -0
- package/dist/control-web/assets/typescript-BPQ3VLAy.js +1 -0
- package/dist/control-web/assets/typespec-BGHnOYBU.js +1 -0
- package/dist/control-web/assets/typst-DHCkPAjA.js +1 -0
- package/dist/control-web/assets/v-BcVCzyr7.js +1 -0
- package/dist/control-web/assets/vala-CsfeWuGM.js +1 -0
- package/dist/control-web/assets/vb-D17OF-Vu.js +1 -0
- package/dist/control-web/assets/vennDiagram-L72KCM5P-DLsv4i_t.js +34 -0
- package/dist/control-web/assets/verilog-BQ8w6xss.js +1 -0
- package/dist/control-web/assets/vesper-DU1UobuO.js +1 -0
- package/dist/control-web/assets/vhdl-CeAyd5Ju.js +1 -0
- package/dist/control-web/assets/viml-CJc9bBzg.js +1 -0
- package/dist/control-web/assets/vitesse-black-Bkuqu6BP.js +1 -0
- package/dist/control-web/assets/vitesse-dark-D0r3Knsf.js +1 -0
- package/dist/control-web/assets/vitesse-light-CVO1_9PV.js +1 -0
- package/dist/control-web/assets/vue-DN_0RTcg.js +1 -0
- package/dist/control-web/assets/vue-html-AaS7Mt5G.js +1 -0
- package/dist/control-web/assets/vue-vine-CQOfvN7w.js +1 -0
- package/dist/control-web/assets/vyper-CDx5xZoG.js +1 -0
- package/dist/control-web/assets/wardleyDiagram-EHGQE667-BazV8fpH.js +78 -0
- package/dist/control-web/assets/wasm-CG6Dc4jp.js +1 -0
- package/dist/control-web/assets/wasm-MzD3tlZU.js +1 -0
- package/dist/control-web/assets/wenyan-BV7otONQ.js +1 -0
- package/dist/control-web/assets/wgsl-Dx-B1_4e.js +1 -0
- package/dist/control-web/assets/wikitext-BhOHFoWU.js +1 -0
- package/dist/control-web/assets/wit-5i3qLPDT.js +1 -0
- package/dist/control-web/assets/wolfram-lXgVvXCa.js +1 -0
- package/dist/control-web/assets/xml-sdJ4AIDG.js +1 -0
- package/dist/control-web/assets/xsl-CtQFsRM5.js +1 -0
- package/dist/control-web/assets/xychartDiagram-FW5EYKEG-Bx9uDlYu.js +7 -0
- package/dist/control-web/assets/yaml-Buea-lGh.js +1 -0
- package/dist/control-web/assets/zenscript-DVFEvuxE.js +1 -0
- package/dist/control-web/assets/zig-VOosw3JB.js +1 -0
- package/dist/control-web/index.html +2 -2
- package/dist/machine-session-service.d.ts +58 -7
- package/dist/machine-session-service.js +510 -22
- package/dist/remote-runtime-dispatcher.d.ts +1 -1
- package/dist/remote-runtime-dispatcher.js +8 -0
- package/dist/remote-runtime-session-projection.js +3 -0
- package/dist/server.d.ts +9 -3
- package/dist/server.js +81 -4
- package/dist/session-runtime-index.js +13 -0
- package/package.json +7 -7
- package/dist/control-web/assets/index-DOUyXr2J.css +0 -32
- package/dist/control-web/assets/mermaid-GHXKKRXX-BkqCCgCk.js +0 -131
package/dist/control-api.js
CHANGED
|
@@ -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
|
-
!
|
|
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
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
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
|
-
|
|
898
|
+
const byteLength = Number(contentLengthHeader);
|
|
899
|
+
if (!Number.isSafeInteger(byteLength) || byteLength <= 0) {
|
|
898
900
|
ctx.status = 400;
|
|
899
|
-
ctx.body = { error: "
|
|
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
|
|
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
|
|
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
|
-
|
|
947
|
-
|
|
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
|
-
|
|
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 >
|
|
972
|
+
if (begun.offset < 0 || begun.offset > byteLength) {
|
|
959
973
|
throw runtimeProtocolError("Runtime Session resource upload offset is invalid");
|
|
960
974
|
}
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
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 !==
|
|
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
|
|
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
|
|
1041
|
-
|
|
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
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
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("
|
|
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 =
|
|
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
|
-
|
|
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) {
|