@rynx-ai/server 0.1.11-beta.4 → 0.1.11-beta.41
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.d.ts +17 -4
- package/dist/control-api.js +722 -84
- 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-CLvhMVsD.js +1 -0
- package/dist/control-web/assets/abnfDiagram-VRR7QNED-D_NL89dn.js +1 -0
- package/dist/control-web/assets/actionscript-3--17pq3dv.js +1 -0
- package/dist/control-web/assets/ada-C5qYipkI.js +1 -0
- package/dist/control-web/assets/andromeeda-vGVdxbeo.js +1 -0
- package/dist/control-web/assets/angular-html-DlZBZkSp.js +1 -0
- package/dist/control-web/assets/angular-ts-BVPGOT0K.js +1 -0
- package/dist/control-web/assets/apache-U0d_L8uA.js +1 -0
- package/dist/control-web/assets/apex-CGTLDQj6.js +1 -0
- package/dist/control-web/assets/apl-cDmXqmZ-.js +1 -0
- package/dist/control-web/assets/applescript-CCn79oCD.js +1 -0
- package/dist/control-web/assets/ara-4CJ0cIlV.js +1 -0
- package/dist/control-web/assets/arc-Pry-7G1_.js +1 -0
- package/dist/control-web/assets/architecture-TIHT7OUA-C9wU1KtW.js +1 -0
- package/dist/control-web/assets/architectureDiagram-ZJ3FMSHR-CV0rxVH6.js +36 -0
- package/dist/control-web/assets/array-BifhSqXX.js +1 -0
- package/dist/control-web/assets/asciidoc-DE70LPWp.js +1 -0
- package/dist/control-web/assets/asm-Cmm7eHzH.js +1 -0
- package/dist/control-web/assets/astro-B1Q6BwBx.js +1 -0
- package/dist/control-web/assets/aurora-x-CDeNXAV0.js +1 -0
- package/dist/control-web/assets/awk-BWXHIvNe.js +1 -0
- package/dist/control-web/assets/ayu-dark-DluEY0Gj.js +1 -0
- package/dist/control-web/assets/ayu-light-C3h-C4tm.js +1 -0
- package/dist/control-web/assets/ayu-mirage-Bqwy1Gya.js +1 -0
- package/dist/control-web/assets/ballerina-B7ZEbQpA.js +1 -0
- package/dist/control-web/assets/bat-Bo4NYOV-.js +1 -0
- package/dist/control-web/assets/beancount-D-usSTwE.js +1 -0
- package/dist/control-web/assets/berry-DKpUyyne.js +1 -0
- package/dist/control-web/assets/bibtex-Ci_nEsc7.js +1 -0
- package/dist/control-web/assets/bicep-CUHmPFLl.js +1 -0
- package/dist/control-web/assets/bird2-C2hNVINV.js +1 -0
- package/dist/control-web/assets/blade-Xpu-LGTm.js +1 -0
- package/dist/control-web/assets/blockDiagram-677ZJIJ3-Cc7nrkZh.js +132 -0
- package/dist/control-web/assets/bsl-BkkzgIyY.js +1 -0
- package/dist/control-web/assets/c-iCihek07.js +1 -0
- package/dist/control-web/assets/c3-CnJL0r0V.js +1 -0
- package/dist/control-web/assets/c4Diagram-LMCZKHZV-BPRU9m-F.js +10 -0
- package/dist/control-web/assets/cadence-CQ2zXKGN.js +1 -0
- package/dist/control-web/assets/cairo-DLTphjLi.js +1 -0
- package/dist/control-web/assets/catppuccin-frappe-3VR1Za6u.js +1 -0
- package/dist/control-web/assets/catppuccin-latte-DwIHMF0Q.js +1 -0
- package/dist/control-web/assets/catppuccin-macchiato-DYnBP6_5.js +1 -0
- package/dist/control-web/assets/catppuccin-mocha-DYhrFGRu.js +1 -0
- package/dist/control-web/assets/channel-BFm2_j8K.js +1 -0
- package/dist/control-web/assets/chunk-2Q5K7J3B-C1jixKkw.js +1 -0
- package/dist/control-web/assets/chunk-32BRIVSS-Bbq3O54m.js +1 -0
- package/dist/control-web/assets/chunk-52WLFC77-sD4al-Ob.js +10 -0
- package/dist/control-web/assets/chunk-5VM5RSS4-ZNzvKenW.js +15 -0
- package/dist/control-web/assets/chunk-7BUUIJ7U-Bb538aSH.js +1 -0
- package/dist/control-web/assets/chunk-C7G6YPKG-DqHaDS1O.js +1 -0
- package/dist/control-web/assets/chunk-EX3LRPZG-36GNQ5wp.js +231 -0
- package/dist/control-web/assets/chunk-HOUHSVGY-DeZ63q1j.js +1 -0
- package/dist/control-web/assets/chunk-ICXQ74PX-D2yF6lD_.js +2 -0
- package/dist/control-web/assets/chunk-JWPE2WC7-DVXcaiue.js +1 -0
- package/dist/control-web/assets/chunk-KEIR6QF5-BICK3FdT.js +161 -0
- package/dist/control-web/assets/chunk-MOJQB5TN-CdaKyBz5.js +88 -0
- package/dist/control-web/assets/chunk-OGEWGWER-eOXC7kiH.js +1 -0
- package/dist/control-web/assets/chunk-PUDLZKDR-6w0LILL_.js +156 -0
- package/dist/control-web/assets/chunk-Q4XR5HBZ-CXgD5TGL.js +70 -0
- package/dist/control-web/assets/chunk-RYQCIY6F-BsoV8yK2.js +1 -0
- package/dist/control-web/assets/chunk-V7JOEXUC-BfoZ78b6.js +206 -0
- package/dist/control-web/assets/chunk-VR4S4FIN-BW2gCEMQ.js +1 -0
- package/dist/control-web/assets/chunk-WYO6CB5R-CHn7hulw.js +128 -0
- package/dist/control-web/assets/chunk-XXDRQBXY-DqAYeljN.js +1 -0
- package/dist/control-web/assets/chunk-Y2CYZVJY-DsF7k-Jl.js +1 -0
- package/dist/control-web/assets/chunk-ZGVPDNZ5-CmFP0-fr.js +62 -0
- package/dist/control-web/assets/clarity-SemFz856.js +1 -0
- package/dist/control-web/assets/classDiagram-OUVF2IWQ-CUe_bETB.js +1 -0
- package/dist/control-web/assets/classDiagram-v2-EOCWNBFH-CUe_bETB.js +1 -0
- package/dist/control-web/assets/clojure-DqKBuwfJ.js +1 -0
- package/dist/control-web/assets/cmake-Bj61d0ZC.js +1 -0
- package/dist/control-web/assets/cobol-BsV-839J.js +1 -0
- package/dist/control-web/assets/codeowners-C8r90Shi.js +1 -0
- package/dist/control-web/assets/codeql-oeQT6MSM.js +1 -0
- package/dist/control-web/assets/coffee-CiiSLhB6.js +1 -0
- package/dist/control-web/assets/common-lisp-Cv5bFMCO.js +1 -0
- package/dist/control-web/assets/coq-BrsZFFmf.js +1 -0
- package/dist/control-web/assets/cose-bilkent-JH36ORCC-lJEhNiw_.js +1 -0
- package/dist/control-web/assets/cpp-DjoE5qBx.js +1 -0
- package/dist/control-web/assets/crystal-DDxHDkHz.js +1 -0
- package/dist/control-web/assets/csharp-Ct8U2NOr.js +1 -0
- package/dist/control-web/assets/css-LjpOdHib.js +1 -0
- package/dist/control-web/assets/csv-Dx-8-gkx.js +1 -0
- package/dist/control-web/assets/cue-CE9AQfxI.js +1 -0
- package/dist/control-web/assets/cynefin-VYW2F7L2-NaLr7Qlq.js +1 -0
- package/dist/control-web/assets/cynefinDiagram-TSTJHNR4-C90wpjAI.js +62 -0
- package/dist/control-web/assets/cypher-ClKdZ_lG.js +1 -0
- package/dist/control-web/assets/cytoscape.esm-B-NFISlW.js +321 -0
- package/dist/control-web/assets/d-qD-0Kul2.js +1 -0
- package/dist/control-web/assets/dagre-Buvkdvvj.js +1 -0
- package/dist/control-web/assets/dagre-VKFMJZFB-BxrPFWTb.js +4 -0
- package/dist/control-web/assets/dark-plus-Cs2F2srj.js +1 -0
- package/dist/control-web/assets/dart-DkHntEIa.js +1 -0
- package/dist/control-web/assets/dax-BkyTk9wS.js +1 -0
- package/dist/control-web/assets/defaultLocale-BFoDCU3G.js +1 -0
- package/dist/control-web/assets/desktop-Dlh5hvp9.js +1 -0
- package/dist/control-web/assets/diagram-FQU43EPY-VIQINsvz.js +3 -0
- package/dist/control-web/assets/diagram-G47NLZAW-DFeAfYXn.js +24 -0
- package/dist/control-web/assets/diagram-NH7WQ7WH-ATzdppDd.js +24 -0
- package/dist/control-web/assets/diagram-OA4YK3LP-DJZpWmbl.js +30 -0
- package/dist/control-web/assets/diagram-WEI45ONY-CqDHcW3g.js +41 -0
- package/dist/control-web/assets/diff-woXpYk--.js +1 -0
- package/dist/control-web/assets/dist-Dx9YWgcW.js +153 -0
- package/dist/control-web/assets/dist-v5Q1xZ2K.js +1 -0
- package/dist/control-web/assets/docker-IyjqRm3v.js +1 -0
- package/dist/control-web/assets/dotenv-_5a1GRtc.js +1 -0
- package/dist/control-web/assets/dracula-BHWKrbxM.js +1 -0
- package/dist/control-web/assets/dracula-soft-5eyTD99u.js +1 -0
- package/dist/control-web/assets/dream-maker-DW3nJb8Q.js +1 -0
- package/dist/control-web/assets/ebnfDiagram-CCIWWBDH-DnP6dHND.js +1 -0
- package/dist/control-web/assets/edge-8z7Jp9dO.js +1 -0
- package/dist/control-web/assets/elixir-CUV54ev5.js +1 -0
- package/dist/control-web/assets/elm-o4NJxfws.js +1 -0
- package/dist/control-web/assets/emacs-lisp-C9PiwqqW.js +1 -0
- package/dist/control-web/assets/erDiagram-Q63AITRT-Bo8bFqrZ.js +85 -0
- package/dist/control-web/assets/erb-CIsHcwm1.js +1 -0
- package/dist/control-web/assets/erlang-Cphh6RMH.js +1 -0
- package/dist/control-web/assets/eventmodeling-45OFAUF4-DTN8wqsu.js +1 -0
- package/dist/control-web/assets/everforest-dark-sB-x3p7T.js +1 -0
- package/dist/control-web/assets/everforest-light-Df2xbC6M.js +1 -0
- package/dist/control-web/assets/fennel-DQxkIbk2.js +1 -0
- package/dist/control-web/assets/fish-BJitypiv.js +1 -0
- package/dist/control-web/assets/flowDiagram-23GEKE2U-BwjqRyvd.js +1 -0
- package/dist/control-web/assets/fluent-C03EYrpw.js +1 -0
- package/dist/control-web/assets/fortran-fixed-form-DEKoE2YW.js +1 -0
- package/dist/control-web/assets/fortran-free-form-CYNrtFtB.js +1 -0
- package/dist/control-web/assets/fsharp-D13ZGOAj.js +1 -0
- package/dist/control-web/assets/ganttDiagram-NO4QXBWP-kxQaBTzd.js +292 -0
- package/dist/control-web/assets/gdresource-C0sCabJj.js +1 -0
- package/dist/control-web/assets/gdscript-Cp2uCuqX.js +1 -0
- package/dist/control-web/assets/gdshader-CBce3t8t.js +1 -0
- package/dist/control-web/assets/genie-CV2tkWYe.js +1 -0
- package/dist/control-web/assets/gherkin-DExj1W_8.js +1 -0
- package/dist/control-web/assets/git-commit-BSykSTBG.js +1 -0
- package/dist/control-web/assets/git-rebase-BDPpS8w6.js +1 -0
- package/dist/control-web/assets/gitGraph-TEB2WS4Q-a646NnuJ.js +1 -0
- package/dist/control-web/assets/gitGraphDiagram-IHSO6WYX-BBe0q0At.js +106 -0
- package/dist/control-web/assets/github-dark-C-LZuMrd.js +1 -0
- package/dist/control-web/assets/github-dark-default-DXG-b-1a.js +1 -0
- package/dist/control-web/assets/github-dark-dimmed-Bx1FflLF.js +1 -0
- package/dist/control-web/assets/github-dark-high-contrast-B_tTalzw.js +1 -0
- package/dist/control-web/assets/github-light-EUqPIrTm.js +1 -0
- package/dist/control-web/assets/github-light-default-BXViO-2h.js +1 -0
- package/dist/control-web/assets/github-light-high-contrast-B68TUdTA.js +1 -0
- package/dist/control-web/assets/gleam-CSRkHgEL.js +1 -0
- package/dist/control-web/assets/glimmer-js-OEO36pDk.js +1 -0
- package/dist/control-web/assets/glimmer-ts-BnAPyISE.js +1 -0
- package/dist/control-web/assets/glsl-D5MA2a_X.js +1 -0
- package/dist/control-web/assets/gn-ilITqXS6.js +1 -0
- package/dist/control-web/assets/gnuplot-7GGW24-e.js +1 -0
- package/dist/control-web/assets/go-BJwz_mda.js +1 -0
- package/dist/control-web/assets/graphlib-DS17s2tU.js +1 -0
- package/dist/control-web/assets/graphql-Ctjuxyvl.js +1 -0
- package/dist/control-web/assets/groovy-CacY0gHj.js +1 -0
- package/dist/control-web/assets/gruvbox-dark-hard-C820rvS2.js +1 -0
- package/dist/control-web/assets/gruvbox-dark-medium-BPjhmG05.js +1 -0
- package/dist/control-web/assets/gruvbox-dark-soft-MrdJrrXF.js +1 -0
- package/dist/control-web/assets/gruvbox-light-hard-BC_s9l72.js +1 -0
- package/dist/control-web/assets/gruvbox-light-medium-BAWPOn9u.js +1 -0
- package/dist/control-web/assets/gruvbox-light-soft-BSMLrYjP.js +1 -0
- package/dist/control-web/assets/hack-D_mkkoLd.js +1 -0
- package/dist/control-web/assets/haml-mpgecWZ6.js +1 -0
- package/dist/control-web/assets/handlebars-CAx_777f.js +1 -0
- package/dist/control-web/assets/haskell-D8IpX4py.js +1 -0
- package/dist/control-web/assets/haxe-OTjmBuCE.js +1 -0
- package/dist/control-web/assets/hcl-Dh228itO.js +1 -0
- package/dist/control-web/assets/highlighted-body-OFNGDK62-DVCHy9oI.js +1 -0
- package/dist/control-web/assets/hjson-CxZEssPk.js +1 -0
- package/dist/control-web/assets/hlsl-Cvrh5tZx.js +1 -0
- package/dist/control-web/assets/horizon-CE9ld1lL.js +1 -0
- package/dist/control-web/assets/horizon-bright-Br1oVSNq.js +1 -0
- package/dist/control-web/assets/houston-CsvMBhTu.js +1 -0
- package/dist/control-web/assets/html-B2lrdnWr.js +1 -0
- package/dist/control-web/assets/html-derivative-CDfZYcul.js +1 -0
- package/dist/control-web/assets/http-kmH8AyfE.js +1 -0
- package/dist/control-web/assets/hurl-DCZHXKU4.js +1 -0
- package/dist/control-web/assets/hxml-B0Qn7Nwc.js +1 -0
- package/dist/control-web/assets/hy-CZbG8q4J.js +1 -0
- package/dist/control-web/assets/imba-DsUTQ-LC.js +1 -0
- package/dist/control-web/assets/index-D7URT6K_.js +140 -0
- package/dist/control-web/assets/index-uEpvRMX9.css +1 -0
- package/dist/control-web/assets/info-DKCQHKI2-Cp_JrY-b.js +1 -0
- package/dist/control-web/assets/infoDiagram-FWYZ7A6U-CAm-h4F_.js +2 -0
- package/dist/control-web/assets/ini-B5eOa1yu.js +1 -0
- package/dist/control-web/assets/init-C-OQMol4.js +1 -0
- package/dist/control-web/assets/ishikawaDiagram-FXEZZL3T-O17pqcWr.js +70 -0
- package/dist/control-web/assets/java-DdHNQ9hk.js +1 -0
- package/dist/control-web/assets/javascript-obGGvMPs.js +1 -0
- package/dist/control-web/assets/jinja-BMiPVedm.js +1 -0
- package/dist/control-web/assets/jison-CBjhYtSs.js +1 -0
- package/dist/control-web/assets/journeyDiagram-5HDEW3XC-DQ-JuSoR.js +139 -0
- package/dist/control-web/assets/json-DAgxKhMr.js +1 -0
- package/dist/control-web/assets/json5-BR5RXkoi.js +1 -0
- package/dist/control-web/assets/jsonc-CYpm1nAK.js +1 -0
- package/dist/control-web/assets/jsonl-CmCQp5Yx.js +1 -0
- package/dist/control-web/assets/jsonnet-CJTPZ8u_.js +1 -0
- package/dist/control-web/assets/jssm-DXw9l8Rf.js +1 -0
- package/dist/control-web/assets/jsx-gTgmArGx.js +1 -0
- package/dist/control-web/assets/julia-CjHxn3vf.js +1 -0
- package/dist/control-web/assets/just-DMArCiVH.js +1 -0
- package/dist/control-web/assets/kanagawa-dragon-CXtmUGW6.js +1 -0
- package/dist/control-web/assets/kanagawa-lotus-BN08jTvb.js +1 -0
- package/dist/control-web/assets/kanagawa-wave-CTweb8Dz.js +1 -0
- package/dist/control-web/assets/kanban-definition-HUTT4EX6-Cgv3kPbm.js +89 -0
- package/dist/control-web/assets/katex-CyHG4N6b.js +1 -0
- package/dist/control-web/assets/kdl-CsD5j6eV.js +1 -0
- package/dist/control-web/assets/kotlin-DhhofPvG.js +1 -0
- package/dist/control-web/assets/kusto-BUv0MjJC.js +1 -0
- package/dist/control-web/assets/laserwave-C_8bwKvT.js +1 -0
- package/dist/control-web/assets/latex-D9bvcAJr.js +1 -0
- package/dist/control-web/assets/lean-CewbzKMR.js +1 -0
- package/dist/control-web/assets/less-DVTAwKKz.js +1 -0
- package/dist/control-web/assets/lib-BZ_F5vVH.js +1 -0
- package/dist/control-web/assets/light-plus-DVQuIRkW.js +1 -0
- package/dist/control-web/assets/line-DUsXzGJZ.js +1 -0
- package/dist/control-web/assets/linear-DmucvK78.js +1 -0
- package/dist/control-web/assets/liquid-CCX5qouA.js +1 -0
- package/dist/control-web/assets/llvm-Cm23YOpf.js +1 -0
- package/dist/control-web/assets/log-BNLmms1o.js +1 -0
- package/dist/control-web/assets/logo-Cluzi2Zq.js +1 -0
- package/dist/control-web/assets/lua-FONpmTUP.js +1 -0
- package/dist/control-web/assets/luau-CNKltnaQ.js +1 -0
- package/dist/control-web/assets/make-Dixweg8N.js +1 -0
- package/dist/control-web/assets/map-BaFkSB1l.js +1 -0
- package/dist/control-web/assets/markdown-BYOwaDjH.js +1 -0
- package/dist/control-web/assets/markdown-streamdown-4N4AcNp5.js +433 -0
- package/dist/control-web/assets/markdown-streamdown-DEcVZfaU.css +1 -0
- package/dist/control-web/assets/marko-oPGh3KfH.js +1 -0
- package/dist/control-web/assets/material-theme-Bm3Qr25_.js +1 -0
- package/dist/control-web/assets/material-theme-darker-2IIEA8gg.js +1 -0
- package/dist/control-web/assets/material-theme-lighter-uhdI0v04.js +1 -0
- package/dist/control-web/assets/material-theme-ocean-CHQ94UKr.js +1 -0
- package/dist/control-web/assets/material-theme-palenight-B5W6OYN7.js +1 -0
- package/dist/control-web/assets/matlab-D7qyCx1q.js +1 -0
- package/dist/control-web/assets/mdc-B_uQHOlt.js +1 -0
- package/dist/control-web/assets/mdx-DQZ5AkYe.js +1 -0
- package/dist/control-web/assets/mermaid-Bk4SNUv9.js +1 -0
- package/dist/control-web/assets/mermaid-GHXKKRXX-BElZGKGd.js +1 -0
- package/dist/control-web/assets/mermaid-parser.core-VMln12Kd.js +7 -0
- package/dist/control-web/assets/min-dark-BSWPekZh.js +1 -0
- package/dist/control-web/assets/min-light-DDpmG2fV.js +1 -0
- package/dist/control-web/assets/mindmap-definition-LN4V7U3C-Bn0lH-UM.js +96 -0
- package/dist/control-web/assets/mipsasm-BMqwQI7S.js +1 -0
- package/dist/control-web/assets/mojo-BgCJLMeH.js +1 -0
- package/dist/control-web/assets/monokai-CdkpiU2Y.js +1 -0
- package/dist/control-web/assets/moonbit-CaWjb8XO.js +1 -0
- package/dist/control-web/assets/move-B1IS1UjX.js +1 -0
- package/dist/control-web/assets/narrat-_X_XdTYD.js +1 -0
- package/dist/control-web/assets/nextflow-Bbiyy34d.js +1 -0
- package/dist/control-web/assets/nextflow-groovy-Dc_ddanL.js +1 -0
- package/dist/control-web/assets/nginx-BTMw9COX.js +1 -0
- package/dist/control-web/assets/night-owl-DhmEMT88.js +1 -0
- package/dist/control-web/assets/night-owl-light-eJ-hLW7d.js +1 -0
- package/dist/control-web/assets/nim-8PQFL6ZB.js +1 -0
- package/dist/control-web/assets/nix-IvuFDN5E.js +1 -0
- package/dist/control-web/assets/nord-Cb4Vim4T.js +1 -0
- package/dist/control-web/assets/nushell-DcLAeLz5.js +1 -0
- package/dist/control-web/assets/objective-c-D1A_Heim.js +1 -0
- package/dist/control-web/assets/objective-cpp-BsSzOQcm.js +1 -0
- package/dist/control-web/assets/ocaml-O90oeIOV.js +1 -0
- package/dist/control-web/assets/odin-B1RWQWA5.js +1 -0
- package/dist/control-web/assets/one-dark-pro-CLwyXe_n.js +1 -0
- package/dist/control-web/assets/one-light-D7Lr4KcI.js +1 -0
- package/dist/control-web/assets/openscad-BUDT5pXO.js +1 -0
- package/dist/control-web/assets/ordinal-BDEzSJ7C.js +1 -0
- package/dist/control-web/assets/packet-7NZHBO7P-Zw8iJ8lo.js +1 -0
- package/dist/control-web/assets/pascal-4ZHwLPI5.js +1 -0
- package/dist/control-web/assets/path-fybaL0A-.js +1 -0
- package/dist/control-web/assets/pegDiagram-2B236MQR-CtF7vVs_.js +1 -0
- package/dist/control-web/assets/perl-Vf0i0hAx.js +1 -0
- package/dist/control-web/assets/php-am1OsKhm.js +1 -0
- package/dist/control-web/assets/pie-RZYD4A2V-su_3QGU2.js +1 -0
- package/dist/control-web/assets/pieDiagram-ENE6RG2P-BkMUBLE1.js +39 -0
- package/dist/control-web/assets/pkl-ot-7Btpt.js +1 -0
- package/dist/control-web/assets/plastic-DQwYfKfQ.js +1 -0
- package/dist/control-web/assets/plsql-DGHpHOYJ.js +1 -0
- package/dist/control-web/assets/po-BiJDBrnU.js +1 -0
- package/dist/control-web/assets/poimandres-DRFjx7u4.js +1 -0
- package/dist/control-web/assets/polar-C7UOKdEL.js +1 -0
- package/dist/control-web/assets/postcss-BXeXVLqQ.js +1 -0
- package/dist/control-web/assets/powerquery-DNMTfnFr.js +1 -0
- package/dist/control-web/assets/powershell-DshXNtvi.js +1 -0
- package/dist/control-web/assets/prisma-BsRQq5mF.js +1 -0
- package/dist/control-web/assets/prolog-iXnhIJG7.js +1 -0
- package/dist/control-web/assets/proto-DB4EqR-F.js +1 -0
- package/dist/control-web/assets/pug-DO6yvBr3.js +1 -0
- package/dist/control-web/assets/puppet-CDv2pdJW.js +1 -0
- package/dist/control-web/assets/purescript-9MfHhQsQ.js +1 -0
- package/dist/control-web/assets/python-gzcpVVnB.js +1 -0
- package/dist/control-web/assets/qml-_a-QhfPD.js +1 -0
- package/dist/control-web/assets/qmldir-DCQb3MpD.js +1 -0
- package/dist/control-web/assets/qss-Fe1Jh2GI.js +1 -0
- package/dist/control-web/assets/quadrantDiagram-ABIIQ3AL-ba-VaqMe.js +7 -0
- package/dist/control-web/assets/r-D6UWEOL2.js +1 -0
- package/dist/control-web/assets/racket-DcIDlBhZ.js +1 -0
- package/dist/control-web/assets/radar-I7S5WNFK-Dat0rqem.js +1 -0
- package/dist/control-web/assets/railroad-3IZDKUUU-Dh2-s8r8.js +1 -0
- package/dist/control-web/assets/railroad-abnf-AHOZXSZD-CNUwq0JR.js +1 -0
- package/dist/control-web/assets/railroad-ebnf-EBAXGLYW-RHr0duea.js +1 -0
- package/dist/control-web/assets/railroad-peg-LSFZ7HO6-CVBWS2eU.js +1 -0
- package/dist/control-web/assets/railroadDiagram-RFXS5EU6-BiJX3SY-.js +1 -0
- package/dist/control-web/assets/raku-B3gFvitq.js +1 -0
- package/dist/control-web/assets/razor-CMVBVp3T.js +1 -0
- package/dist/control-web/assets/red-CJ3rzSJv.js +1 -0
- package/dist/control-web/assets/reg-CRGYupPL.js +1 -0
- package/dist/control-web/assets/regexp-DR20uMnK.js +1 -0
- package/dist/control-web/assets/rel-BtDbiS_P.js +1 -0
- package/dist/control-web/assets/requirementDiagram-TGXJPOKE-CFfakCzs.js +84 -0
- package/dist/control-web/assets/riscv-Ckw8ddFX.js +1 -0
- package/dist/control-web/assets/rolldown-runtime-hePW80VL.js +1 -0
- package/dist/control-web/assets/ron-VUp2lXgN.js +1 -0
- package/dist/control-web/assets/rose-pine-BthvhNj6.js +1 -0
- package/dist/control-web/assets/rose-pine-dawn-Dg85fqjY.js +1 -0
- package/dist/control-web/assets/rose-pine-moon-hon4tzzS.js +1 -0
- package/dist/control-web/assets/rosmsg-CAekHB0j.js +1 -0
- package/dist/control-web/assets/rough.esm-Dy-Kn_BL.js +1 -0
- package/dist/control-web/assets/rst-CgIrbW_q.js +1 -0
- package/dist/control-web/assets/ruby-Dp6Zud9H.js +1 -0
- package/dist/control-web/assets/rust-Cfkwpbl8.js +1 -0
- package/dist/control-web/assets/sankeyDiagram-HTMAVEWB-jgDi0God.js +40 -0
- package/dist/control-web/assets/sas-B6p8-ynO.js +1 -0
- package/dist/control-web/assets/sass-DXrisJhu.js +1 -0
- package/dist/control-web/assets/scala-DKOlJaKm.js +1 -0
- package/dist/control-web/assets/scheme-DQCgrYNe.js +1 -0
- package/dist/control-web/assets/scss-DcoSS-ti.js +1 -0
- package/dist/control-web/assets/sdbl-bTVj8UrX.js +1 -0
- package/dist/control-web/assets/sequenceDiagram-DBY2YBRQ-DBfyyb0N.js +162 -0
- package/dist/control-web/assets/shaderlab-TOUzSsQk.js +1 -0
- package/dist/control-web/assets/shellscript-Da78Ox-3.js +1 -0
- package/dist/control-web/assets/shellsession-CVsQGYfZ.js +1 -0
- package/dist/control-web/assets/sizeCapture-X5ZJPWSS-B0uUizjq.js +1 -0
- package/dist/control-web/assets/slack-dark-DnToyrRv.js +1 -0
- package/dist/control-web/assets/slack-ochin-B2OO5cIa.js +1 -0
- package/dist/control-web/assets/smalltalk-B16xEiuN.js +1 -0
- package/dist/control-web/assets/snazzy-light-4G7pJPwS.js +1 -0
- package/dist/control-web/assets/solarized-dark-DV17i1UV.js +1 -0
- package/dist/control-web/assets/solarized-light-DSh2HLQt.js +1 -0
- package/dist/control-web/assets/solidity-CKzVLygQ.js +1 -0
- package/dist/control-web/assets/soy-B5n_eHSp.js +1 -0
- package/dist/control-web/assets/sparql-D_iOobhT.js +1 -0
- package/dist/control-web/assets/splunk-BC2Px7Mm.js +1 -0
- package/dist/control-web/assets/sql-ClgswhA6.js +1 -0
- package/dist/control-web/assets/src-B6xuSHsQ.js +1 -0
- package/dist/control-web/assets/ssh-config-BgfXC-Er.js +1 -0
- package/dist/control-web/assets/stata-RoaAgbqU.js +1 -0
- package/dist/control-web/assets/stateDiagram-2N3HPSRC-Dwb_ncVi.js +1 -0
- package/dist/control-web/assets/stateDiagram-v2-6OUMAXLB-DI0opaA1.js +1 -0
- package/dist/control-web/assets/stylus-B6D30XZt.js +1 -0
- package/dist/control-web/assets/surrealql-DIn4NJsS.js +1 -0
- package/dist/control-web/assets/svelte-CIt8Fl9I.js +1 -0
- package/dist/control-web/assets/swift-DonLKvLd.js +1 -0
- package/dist/control-web/assets/swimlanes-5IMT3BWC-DW0LuiIV.js +2 -0
- package/dist/control-web/assets/swimlanesDiagram-G3AALYLV-DDTVjcOR.js +8 -0
- package/dist/control-web/assets/synthwave-84-nFMaYfgc.js +1 -0
- package/dist/control-web/assets/system-verilog-DJ5XKQeo.js +1 -0
- package/dist/control-web/assets/systemd-BxMlprV5.js +1 -0
- package/dist/control-web/assets/talonscript-CohzipZa.js +1 -0
- package/dist/control-web/assets/tasl-DMoTqEGO.js +1 -0
- package/dist/control-web/assets/tcl-CZd0xW_V.js +1 -0
- package/dist/control-web/assets/templ-BREsJpNc.js +1 -0
- package/dist/control-web/assets/terraform-DswuEJGm.js +1 -0
- package/dist/control-web/assets/tex-0w6-Dtgt.js +1 -0
- package/dist/control-web/assets/timeline-definition-FHXFAJF6-DeX4B_B8.js +120 -0
- package/dist/control-web/assets/tokyo-night-oM2G3aXe.js +1 -0
- package/dist/control-web/assets/toml-CcmNWLt0.js +1 -0
- package/dist/control-web/assets/treeView-QDETBFTQ-D1UXtICj.js +1 -0
- package/dist/control-web/assets/treemap-6X3UGDF4-CrppzjZH.js +1 -0
- package/dist/control-web/assets/ts-tags-q3pptdMi.js +1 -0
- package/dist/control-web/assets/tsv-sltzmVWM.js +1 -0
- package/dist/control-web/assets/tsx-CUOciP0b.js +1 -0
- package/dist/control-web/assets/turtle-ByJddavk.js +1 -0
- package/dist/control-web/assets/twig-LIeLXgf5.js +1 -0
- package/dist/control-web/assets/typescript-BydbNFcO.js +1 -0
- package/dist/control-web/assets/typespec-B88KGewJ.js +1 -0
- package/dist/control-web/assets/typst-DI99ib-x.js +1 -0
- package/dist/control-web/assets/v-DETTlOr0.js +1 -0
- package/dist/control-web/assets/vala-zf12oZj6.js +1 -0
- package/dist/control-web/assets/vb-Djn5o6TS.js +1 -0
- package/dist/control-web/assets/vennDiagram-L72KCM5P-BYpf-7VR.js +34 -0
- package/dist/control-web/assets/verilog-CiiDBU1e.js +1 -0
- package/dist/control-web/assets/vesper-D5bVUKB1.js +1 -0
- package/dist/control-web/assets/vhdl-BroJfC0k.js +1 -0
- package/dist/control-web/assets/viml-DvXPmvsu.js +1 -0
- package/dist/control-web/assets/vitesse-black-fwtXNY1n.js +1 -0
- package/dist/control-web/assets/vitesse-dark-BZCL-v6S.js +1 -0
- package/dist/control-web/assets/vitesse-light-VbXTXTou.js +1 -0
- package/dist/control-web/assets/vue-DVSfBueU.js +1 -0
- package/dist/control-web/assets/vue-html-DkKkQnZL.js +1 -0
- package/dist/control-web/assets/vue-vine-pWqEcBkW.js +1 -0
- package/dist/control-web/assets/vyper-CgoNMtux.js +1 -0
- package/dist/control-web/assets/wardley-OPB4EBWU-B9rA0UsV.js +1 -0
- package/dist/control-web/assets/wardleyDiagram-EHGQE667-BdvAUa5F.js +78 -0
- package/dist/control-web/assets/wasm-BnjxR4X6.js +1 -0
- package/dist/control-web/assets/wasm-ByWQv1Qj.js +1 -0
- package/dist/control-web/assets/wenyan-C8pVoKbM.js +1 -0
- package/dist/control-web/assets/wgsl-BsKzXJz4.js +1 -0
- package/dist/control-web/assets/wikitext-ClFFjSW2.js +1 -0
- package/dist/control-web/assets/wit-DdvCle-K.js +1 -0
- package/dist/control-web/assets/wolfram-DLL8P-h_.js +1 -0
- package/dist/control-web/assets/xml-BlnrEAEy.js +1 -0
- package/dist/control-web/assets/xsl-BOPS8gLt.js +1 -0
- package/dist/control-web/assets/xychartDiagram-FW5EYKEG-BaEV3pGm.js +7 -0
- package/dist/control-web/assets/yaml-Du_6cdrH.js +1 -0
- package/dist/control-web/assets/zenscript-BnlCZFoB.js +1 -0
- package/dist/control-web/assets/zig-CMLA9XwU.js +1 -0
- package/dist/control-web/index.html +3 -2
- package/dist/control-web-dist.d.ts +1 -1
- package/dist/control-web-dist.js +4 -2
- package/dist/desktop-browser-host.d.ts +3 -1
- package/dist/desktop-browser-host.js +39 -4
- package/dist/direct-runtime-server.js +187 -153
- package/dist/machine-session-service.d.ts +105 -15
- package/dist/machine-session-service.js +781 -87
- package/dist/remote-runtime-dispatcher.d.ts +2 -2
- package/dist/remote-runtime-dispatcher.js +42 -2
- package/dist/remote-runtime-session-projection.d.ts +1 -0
- package/dist/remote-runtime-session-projection.js +12 -0
- package/dist/server.d.ts +64 -11
- package/dist/server.js +422 -55
- package/dist/session-browser-service.d.ts +24 -4
- package/dist/session-browser-service.js +127 -1
- package/dist/session-pending-inputs.d.ts +42 -0
- package/dist/session-pending-inputs.js +87 -0
- package/dist/session-portal.d.ts +54 -0
- package/dist/session-portal.js +997 -0
- package/dist/session-runtime-index.d.ts +3 -6
- package/dist/session-runtime-index.js +96 -38
- package/dist/session-terminal-host.d.ts +22 -2
- package/dist/session-terminal-host.js +66 -83
- package/dist/terminal-ws.d.ts +4 -1
- package/dist/terminal-ws.js +93 -27
- package/package.json +7 -7
- package/dist/control-web/assets/highlighted-body-OFNGDK62-DWWsUtHF.js +0 -1
- package/dist/control-web/assets/index-BnX7NWJX.js +0 -689
- package/dist/control-web/assets/index-CUoWRX2i.css +0 -32
- package/dist/control-web/assets/mermaid-GHXKKRXX-C1fxAgiw.js +0 -131
|
@@ -13,12 +13,6 @@ export interface SessionRuntimeActivitySnapshot {
|
|
|
13
13
|
*/
|
|
14
14
|
export declare class SessionRuntimeIndex {
|
|
15
15
|
private readonly sessions;
|
|
16
|
-
/**
|
|
17
|
-
* Make an accepted Turn visible before the request admission reservation is
|
|
18
|
-
* released. The returned callback only abandons the pre-created handoff; once
|
|
19
|
-
* response.created arrives, the native response remains authoritative.
|
|
20
|
-
*/
|
|
21
|
-
beginResponseHandoff(sessionId: string, responseId: string): () => void;
|
|
22
16
|
observe(sessionId: string, event: SessionEvent): void;
|
|
23
17
|
snapshot(sessionId: string): SessionRuntimeSnapshot;
|
|
24
18
|
/** Aggregate only process-live work; durable Session history is not activity. */
|
|
@@ -27,4 +21,7 @@ export declare class SessionRuntimeIndex {
|
|
|
27
21
|
private state;
|
|
28
22
|
private removeResponseInteractions;
|
|
29
23
|
private hasRunningTurn;
|
|
24
|
+
private statusAfterResponseTerminal;
|
|
25
|
+
private retireStatusResponses;
|
|
26
|
+
private markResponseTerminal;
|
|
30
27
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const MAX_TERMINAL_RESPONSE_IDS = 2_000;
|
|
1
2
|
/**
|
|
2
3
|
* Process-local index of live Session state. Durable transcript items explain
|
|
3
4
|
* history; this index says which historical requests still have a real runtime
|
|
@@ -6,57 +7,81 @@
|
|
|
6
7
|
*/
|
|
7
8
|
export class SessionRuntimeIndex {
|
|
8
9
|
sessions = new Map();
|
|
9
|
-
/**
|
|
10
|
-
* Make an accepted Turn visible before the request admission reservation is
|
|
11
|
-
* released. The returned callback only abandons the pre-created handoff; once
|
|
12
|
-
* response.created arrives, the native response remains authoritative.
|
|
13
|
-
*/
|
|
14
|
-
beginResponseHandoff(sessionId, responseId) {
|
|
15
|
-
const state = this.state(sessionId);
|
|
16
|
-
state.pendingResponseIds.add(responseId);
|
|
17
|
-
state.status = "running";
|
|
18
|
-
state.statusKind = "startup";
|
|
19
|
-
let pending = true;
|
|
20
|
-
return () => {
|
|
21
|
-
if (!pending)
|
|
22
|
-
return;
|
|
23
|
-
pending = false;
|
|
24
|
-
state.pendingResponseIds.delete(responseId);
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
10
|
observe(sessionId, event) {
|
|
28
11
|
const state = this.state(sessionId);
|
|
29
12
|
switch (event.type) {
|
|
30
13
|
case "response.created":
|
|
31
|
-
state.
|
|
14
|
+
if (state.terminalResponseIds.has(event.responseId))
|
|
15
|
+
return;
|
|
32
16
|
state.activeResponseIds.add(event.responseId);
|
|
33
17
|
state.status = "running";
|
|
34
18
|
state.statusKind = undefined;
|
|
19
|
+
state.backgroundTaskCount = undefined;
|
|
35
20
|
return;
|
|
36
21
|
case "response.completed":
|
|
37
|
-
|
|
22
|
+
this.markResponseTerminal(state, event.responseId);
|
|
38
23
|
state.activeResponseIds.delete(event.responseId);
|
|
39
24
|
this.removeResponseInteractions(state, event.responseId);
|
|
40
|
-
state.status = this.
|
|
25
|
+
state.status = this.statusAfterResponseTerminal(state);
|
|
41
26
|
state.statusKind = undefined;
|
|
42
27
|
return;
|
|
43
28
|
case "response.failed":
|
|
44
|
-
|
|
29
|
+
this.markResponseTerminal(state, event.responseId);
|
|
45
30
|
state.activeResponseIds.delete(event.responseId);
|
|
46
31
|
this.removeResponseInteractions(state, event.responseId);
|
|
47
32
|
// Response failure is Turn-local. It must not poison a reusable Session.
|
|
48
|
-
state.status = this.
|
|
33
|
+
state.status = this.statusAfterResponseTerminal(state);
|
|
34
|
+
state.statusKind = undefined;
|
|
35
|
+
return;
|
|
36
|
+
case "session.interrupted":
|
|
37
|
+
this.markResponseTerminal(state, event.responseId);
|
|
38
|
+
state.activeResponseIds.delete(event.responseId);
|
|
39
|
+
this.removeResponseInteractions(state, event.responseId);
|
|
40
|
+
state.status = this.statusAfterResponseTerminal(state);
|
|
49
41
|
state.statusKind = undefined;
|
|
50
42
|
return;
|
|
51
|
-
case "session.status":
|
|
52
|
-
|
|
53
|
-
state.
|
|
54
|
-
?
|
|
55
|
-
:
|
|
56
|
-
|
|
43
|
+
case "session.status": {
|
|
44
|
+
if (event.backgroundTaskCount !== undefined) {
|
|
45
|
+
state.backgroundTaskCount = event.backgroundTaskCount > 0
|
|
46
|
+
? event.backgroundTaskCount
|
|
47
|
+
: undefined;
|
|
48
|
+
}
|
|
49
|
+
else if (event.status === "running" || event.status === "failed") {
|
|
50
|
+
state.backgroundTaskCount = undefined;
|
|
51
|
+
}
|
|
52
|
+
if (event.status === "running") {
|
|
53
|
+
if (event.responseId && state.terminalResponseIds.has(event.responseId))
|
|
54
|
+
return;
|
|
55
|
+
if (event.responseId)
|
|
56
|
+
state.activeResponseIds.add(event.responseId);
|
|
57
|
+
state.status = "running";
|
|
58
|
+
state.statusKind = event.statusKind;
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
// A provider interaction is a stronger in-flight fact than a quiet-pane
|
|
62
|
+
// idle observation. Claude's status-file path reports waiting as running;
|
|
63
|
+
// this guard preserves the same truth on its legacy PTY fallback.
|
|
64
|
+
if (event.status === "idle" && state.pendingInteractions.size > 0) {
|
|
65
|
+
state.status = "running";
|
|
66
|
+
state.statusKind = undefined;
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
this.retireStatusResponses(state, event.responseId);
|
|
70
|
+
if (event.status === "failed") {
|
|
71
|
+
state.status = "failed";
|
|
72
|
+
}
|
|
73
|
+
else if (state.status !== "failed") {
|
|
74
|
+
// Provider idle is authoritative even when final transcript records
|
|
75
|
+
// arrive later. Response identity remains on those events themselves;
|
|
76
|
+
// it must not keep Session activity/loading alive.
|
|
77
|
+
state.status = this.hasRunningTurn(state) ? "running" : "idle";
|
|
78
|
+
}
|
|
79
|
+
state.statusKind = undefined;
|
|
57
80
|
return;
|
|
81
|
+
}
|
|
58
82
|
case "session.interaction.requested":
|
|
59
|
-
state.
|
|
83
|
+
if (state.terminalResponseIds.has(event.responseId))
|
|
84
|
+
return;
|
|
60
85
|
state.pendingInteractions.set(event.interaction.interactionId, {
|
|
61
86
|
responseId: event.responseId,
|
|
62
87
|
interaction: event.interaction,
|
|
@@ -68,14 +93,15 @@ export class SessionRuntimeIndex {
|
|
|
68
93
|
case "session.interaction.resolved":
|
|
69
94
|
case "session.interaction.cancelled":
|
|
70
95
|
state.pendingInteractions.delete(event.interactionId);
|
|
71
|
-
|
|
96
|
+
if (this.hasRunningTurn(state))
|
|
97
|
+
state.status = "running";
|
|
72
98
|
return;
|
|
73
99
|
case "session.rotated":
|
|
74
|
-
state.pendingResponseIds.clear();
|
|
75
100
|
state.activeResponseIds.clear();
|
|
76
101
|
state.pendingInteractions.clear();
|
|
77
102
|
state.status = "idle";
|
|
78
103
|
state.statusKind = undefined;
|
|
104
|
+
state.backgroundTaskCount = undefined;
|
|
79
105
|
return;
|
|
80
106
|
default:
|
|
81
107
|
return;
|
|
@@ -86,10 +112,11 @@ export class SessionRuntimeIndex {
|
|
|
86
112
|
if (!state)
|
|
87
113
|
return { status: "idle", activeResponseIds: [], pendingInteractions: [] };
|
|
88
114
|
return {
|
|
89
|
-
status: state.pendingInteractions.size > 0
|
|
90
|
-
? "running"
|
|
91
|
-
: state.status,
|
|
115
|
+
status: state.pendingInteractions.size > 0 ? "running" : state.status,
|
|
92
116
|
...(state.statusKind === undefined ? {} : { statusKind: state.statusKind }),
|
|
117
|
+
...(state.backgroundTaskCount === undefined
|
|
118
|
+
? {}
|
|
119
|
+
: { backgroundTaskCount: state.backgroundTaskCount }),
|
|
93
120
|
activeResponseIds: [...state.activeResponseIds],
|
|
94
121
|
pendingInteractions: [...state.pendingInteractions.values()],
|
|
95
122
|
};
|
|
@@ -99,7 +126,9 @@ export class SessionRuntimeIndex {
|
|
|
99
126
|
let runningTurns = 0;
|
|
100
127
|
let pendingInteractions = 0;
|
|
101
128
|
for (const state of this.sessions.values()) {
|
|
102
|
-
|
|
129
|
+
if (state.status === "running" || state.pendingInteractions.size > 0) {
|
|
130
|
+
runningTurns += Math.max(1, state.activeResponseIds.size);
|
|
131
|
+
}
|
|
103
132
|
pendingInteractions += state.pendingInteractions.size;
|
|
104
133
|
}
|
|
105
134
|
return { runningTurns, pendingInteractions };
|
|
@@ -112,8 +141,8 @@ export class SessionRuntimeIndex {
|
|
|
112
141
|
if (!state) {
|
|
113
142
|
state = {
|
|
114
143
|
status: "idle",
|
|
115
|
-
pendingResponseIds: new Set(),
|
|
116
144
|
activeResponseIds: new Set(),
|
|
145
|
+
terminalResponseIds: new Set(),
|
|
117
146
|
pendingInteractions: new Map(),
|
|
118
147
|
};
|
|
119
148
|
this.sessions.set(sessionId, state);
|
|
@@ -127,6 +156,35 @@ export class SessionRuntimeIndex {
|
|
|
127
156
|
}
|
|
128
157
|
}
|
|
129
158
|
hasRunningTurn(state) {
|
|
130
|
-
return state.
|
|
159
|
+
return state.activeResponseIds.size > 0;
|
|
160
|
+
}
|
|
161
|
+
statusAfterResponseTerminal(state) {
|
|
162
|
+
if (state.pendingInteractions.size > 0 || this.hasRunningTurn(state))
|
|
163
|
+
return "running";
|
|
164
|
+
return state.status === "failed" ? "failed" : "idle";
|
|
165
|
+
}
|
|
166
|
+
retireStatusResponses(state, responseId) {
|
|
167
|
+
// session.status is Session-wide. Match reference implementation's
|
|
168
|
+
// _session_active_response_cache: every idle/failed edge closes the one
|
|
169
|
+
// in-flight native response projection, even when the edge happens to be
|
|
170
|
+
// stamped with that response id. A late transcript event may still carry
|
|
171
|
+
// the old id for grouping, but it cannot keep activity alive.
|
|
172
|
+
for (const activeResponseId of state.activeResponseIds) {
|
|
173
|
+
this.markResponseTerminal(state, activeResponseId);
|
|
174
|
+
}
|
|
175
|
+
if (responseId)
|
|
176
|
+
this.markResponseTerminal(state, responseId);
|
|
177
|
+
state.activeResponseIds.clear();
|
|
178
|
+
state.pendingInteractions.clear();
|
|
179
|
+
}
|
|
180
|
+
markResponseTerminal(state, responseId) {
|
|
181
|
+
state.terminalResponseIds.delete(responseId);
|
|
182
|
+
state.terminalResponseIds.add(responseId);
|
|
183
|
+
while (state.terminalResponseIds.size > MAX_TERMINAL_RESPONSE_IDS) {
|
|
184
|
+
const oldest = state.terminalResponseIds.values().next().value;
|
|
185
|
+
if (oldest === undefined)
|
|
186
|
+
break;
|
|
187
|
+
state.terminalResponseIds.delete(oldest);
|
|
188
|
+
}
|
|
131
189
|
}
|
|
132
190
|
}
|
|
@@ -11,12 +11,32 @@ export type SessionTerminalCloseReason = "client_closed" | "terminal_exited" | "
|
|
|
11
11
|
export interface SessionTerminalCloseInfo {
|
|
12
12
|
reason: SessionTerminalCloseReason;
|
|
13
13
|
exitCode?: number;
|
|
14
|
+
finalOffset?: number;
|
|
14
15
|
}
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
export interface SessionTerminalRead {
|
|
17
|
+
data: Uint8Array;
|
|
18
|
+
nextOffset: number;
|
|
19
|
+
done: boolean;
|
|
20
|
+
finalOffset?: number;
|
|
21
|
+
}
|
|
22
|
+
/** One demand-driven attachment; close detaches only this viewer. */
|
|
23
|
+
export interface SessionTerminalAttachment {
|
|
17
24
|
readonly sessionId: string;
|
|
18
25
|
readonly role: SessionTerminalRole;
|
|
26
|
+
readonly seedBytes: number;
|
|
27
|
+
/** Actual tmux pane size captured with the seed. */
|
|
28
|
+
readonly dimensions?: {
|
|
29
|
+
cols: number;
|
|
30
|
+
rows: number;
|
|
31
|
+
};
|
|
19
32
|
readonly closed: Promise<SessionTerminalCloseInfo>;
|
|
33
|
+
readSeed(offset: number, maxBytes: number): Promise<SessionTerminalRead>;
|
|
34
|
+
start(): Promise<void>;
|
|
35
|
+
read(offset: number, maxBytes: number): Promise<SessionTerminalRead>;
|
|
36
|
+
onResize?(listener: (dimensions: {
|
|
37
|
+
cols: number;
|
|
38
|
+
rows: number;
|
|
39
|
+
}) => void): void;
|
|
20
40
|
write(data: Uint8Array): void | Promise<void>;
|
|
21
41
|
resize(cols: number, rows: number): void | Promise<void>;
|
|
22
42
|
close(): Promise<void>;
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import { TerminalOpenError } from "@rynx-ai/runtime";
|
|
2
|
-
const MAX_QUEUED_OUTPUT_FRAMES = 128;
|
|
3
|
-
const MAX_QUEUED_OUTPUT_BYTES = 512 * 1024;
|
|
4
2
|
const MAX_TERMINAL_DIMENSION = 1_000;
|
|
5
3
|
export class SessionTerminalOpenError extends Error {
|
|
6
4
|
code;
|
|
@@ -55,7 +53,7 @@ export function createRunnerSessionTerminalHost(options) {
|
|
|
55
53
|
void attachment.closed.then(releaseActivity, releaseActivity);
|
|
56
54
|
try {
|
|
57
55
|
const opened = await waitFor(parent.ready, openOptions.signal);
|
|
58
|
-
attachment.opened(opened.role);
|
|
56
|
+
attachment.opened(opened.role, opened.dimensions, opened.seedBytes);
|
|
59
57
|
attachment.throwIfOpeningFailed();
|
|
60
58
|
return attachment;
|
|
61
59
|
}
|
|
@@ -107,13 +105,13 @@ class RunnerSessionTerminalAttachment {
|
|
|
107
105
|
sessionId;
|
|
108
106
|
parent;
|
|
109
107
|
signal;
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
ended = false;
|
|
114
|
-
terminalError;
|
|
115
|
-
openingFailure;
|
|
108
|
+
detached = false;
|
|
109
|
+
readerFinished = false;
|
|
110
|
+
closeSettled = false;
|
|
116
111
|
currentRole;
|
|
112
|
+
currentDimensions;
|
|
113
|
+
currentSeedBytes = 0;
|
|
114
|
+
resizeListener;
|
|
117
115
|
resolveClosed;
|
|
118
116
|
closed;
|
|
119
117
|
onAbort;
|
|
@@ -128,8 +126,18 @@ class RunnerSessionTerminalAttachment {
|
|
|
128
126
|
this.onAbort = () => {
|
|
129
127
|
void this.close().catch(() => undefined);
|
|
130
128
|
};
|
|
131
|
-
parent.
|
|
132
|
-
|
|
129
|
+
parent.onResize?.((dimensions) => {
|
|
130
|
+
this.currentDimensions = dimensions;
|
|
131
|
+
this.resizeListener?.(dimensions);
|
|
132
|
+
});
|
|
133
|
+
void parent.readerDone.then((info) => {
|
|
134
|
+
this.readerFinished = true;
|
|
135
|
+
this.settleClosed({
|
|
136
|
+
reason: info.reason,
|
|
137
|
+
exitCode: info.exitCode,
|
|
138
|
+
finalOffset: info.finalOffset,
|
|
139
|
+
});
|
|
140
|
+
});
|
|
133
141
|
if (signal?.aborted)
|
|
134
142
|
this.onAbort();
|
|
135
143
|
else
|
|
@@ -138,97 +146,72 @@ class RunnerSessionTerminalAttachment {
|
|
|
138
146
|
get role() {
|
|
139
147
|
return this.currentRole;
|
|
140
148
|
}
|
|
141
|
-
|
|
149
|
+
get dimensions() {
|
|
150
|
+
return this.currentDimensions;
|
|
151
|
+
}
|
|
152
|
+
get seedBytes() {
|
|
153
|
+
return this.currentSeedBytes;
|
|
154
|
+
}
|
|
155
|
+
onResize(listener) {
|
|
156
|
+
this.resizeListener = listener;
|
|
157
|
+
if (this.currentDimensions)
|
|
158
|
+
queueMicrotask(() => listener(this.currentDimensions));
|
|
159
|
+
}
|
|
160
|
+
opened(role, dimensions, seedBytes = 0) {
|
|
142
161
|
this.currentRole = role;
|
|
162
|
+
this.currentDimensions = dimensions;
|
|
163
|
+
this.currentSeedBytes = seedBytes;
|
|
143
164
|
}
|
|
144
165
|
throwIfOpeningFailed() {
|
|
145
|
-
if (this.
|
|
146
|
-
throw this.openingFailure;
|
|
147
|
-
if (this.ended) {
|
|
166
|
+
if (this.detached || this.readerFinished) {
|
|
148
167
|
throw new SessionTerminalOpenError("internal", "Session terminal closed while opening");
|
|
149
168
|
}
|
|
150
169
|
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
next() {
|
|
155
|
-
const queued = this.queue.shift();
|
|
156
|
-
if (queued) {
|
|
157
|
-
this.queuedBytes -= queued.bytes;
|
|
158
|
-
return Promise.resolve({ done: false, value: queued.data });
|
|
159
|
-
}
|
|
160
|
-
if (this.terminalError !== undefined)
|
|
161
|
-
return Promise.reject(this.terminalError);
|
|
162
|
-
if (this.ended)
|
|
163
|
-
return Promise.resolve({ done: true, value: undefined });
|
|
164
|
-
if (this.waiter) {
|
|
165
|
-
return Promise.reject(new SessionTerminalStreamError("internal", "Concurrent reads from one Session terminal are not allowed"));
|
|
170
|
+
readSeed(offset, maxBytes) {
|
|
171
|
+
if (this.detached || this.readerFinished) {
|
|
172
|
+
return Promise.reject(new Error("Session terminal is closed"));
|
|
166
173
|
}
|
|
167
|
-
return
|
|
168
|
-
|
|
169
|
-
|
|
174
|
+
return this.parent.readSeed(offset, maxBytes);
|
|
175
|
+
}
|
|
176
|
+
async start() {
|
|
177
|
+
if (this.detached || this.readerFinished)
|
|
178
|
+
throw new Error("Session terminal is closed");
|
|
179
|
+
await this.parent.start();
|
|
170
180
|
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
181
|
+
read(offset, maxBytes) {
|
|
182
|
+
// Reader completion publishes the final offset before the consumer has
|
|
183
|
+
// necessarily pulled the final bytes. Only detaching makes that tail
|
|
184
|
+
// unreadable.
|
|
185
|
+
if (this.detached)
|
|
186
|
+
return Promise.reject(new Error("Session terminal is closed"));
|
|
187
|
+
return this.parent.read(offset, maxBytes);
|
|
174
188
|
}
|
|
175
|
-
write(data) {
|
|
176
|
-
if (this.
|
|
189
|
+
async write(data) {
|
|
190
|
+
if (this.detached ||
|
|
191
|
+
this.readerFinished ||
|
|
192
|
+
this.currentRole !== "owner" ||
|
|
193
|
+
data.byteLength === 0)
|
|
177
194
|
return;
|
|
178
|
-
this.parent.write(
|
|
195
|
+
await this.parent.write(data);
|
|
179
196
|
}
|
|
180
|
-
resize(cols, rows) {
|
|
197
|
+
async resize(cols, rows) {
|
|
181
198
|
validateDimensions(cols, rows);
|
|
182
|
-
if (!this.
|
|
183
|
-
this.parent.resize(cols, rows);
|
|
199
|
+
if (!this.detached && !this.readerFinished) {
|
|
200
|
+
await this.parent.resize(cols, rows);
|
|
201
|
+
}
|
|
184
202
|
}
|
|
185
203
|
async close() {
|
|
186
|
-
if (this.
|
|
204
|
+
if (this.detached)
|
|
187
205
|
return;
|
|
206
|
+
this.detached = true;
|
|
188
207
|
this.parent.close();
|
|
189
|
-
this.
|
|
190
|
-
}
|
|
191
|
-
push(data) {
|
|
192
|
-
if (this.ended || data.byteLength === 0)
|
|
193
|
-
return;
|
|
194
|
-
if (this.waiter) {
|
|
195
|
-
const waiter = this.waiter;
|
|
196
|
-
this.waiter = undefined;
|
|
197
|
-
waiter.resolve({ done: false, value: data });
|
|
198
|
-
return;
|
|
199
|
-
}
|
|
200
|
-
if (this.queue.length >= MAX_QUEUED_OUTPUT_FRAMES ||
|
|
201
|
-
this.queuedBytes + data.byteLength > MAX_QUEUED_OUTPUT_BYTES) {
|
|
202
|
-
const error = new SessionTerminalStreamError("backpressure", "Session terminal output exceeded its bounded queue");
|
|
203
|
-
this.openingFailure = new SessionTerminalOpenError("capacity", error.message, {
|
|
204
|
-
cause: error,
|
|
205
|
-
});
|
|
206
|
-
this.parent.close();
|
|
207
|
-
this.finish({ reason: "backpressure" }, error, true);
|
|
208
|
-
return;
|
|
209
|
-
}
|
|
210
|
-
const copy = Uint8Array.from(data);
|
|
211
|
-
this.queue.push({ data: copy, bytes: copy.byteLength });
|
|
212
|
-
this.queuedBytes += copy.byteLength;
|
|
208
|
+
this.settleClosed({ reason: "client_closed" });
|
|
213
209
|
}
|
|
214
|
-
|
|
215
|
-
if (this.
|
|
210
|
+
settleClosed(info) {
|
|
211
|
+
if (this.closeSettled)
|
|
216
212
|
return;
|
|
217
|
-
this.
|
|
218
|
-
this.terminalError = error;
|
|
213
|
+
this.closeSettled = true;
|
|
219
214
|
this.signal?.removeEventListener("abort", this.onAbort);
|
|
220
|
-
if (discardQueue) {
|
|
221
|
-
this.queue.length = 0;
|
|
222
|
-
this.queuedBytes = 0;
|
|
223
|
-
}
|
|
224
|
-
const waiter = this.waiter;
|
|
225
|
-
this.waiter = undefined;
|
|
226
|
-
if (waiter) {
|
|
227
|
-
if (error === undefined)
|
|
228
|
-
waiter.resolve({ done: true, value: undefined });
|
|
229
|
-
else
|
|
230
|
-
waiter.reject(error);
|
|
231
|
-
}
|
|
232
215
|
this.resolveClosed(info);
|
|
233
216
|
}
|
|
234
217
|
}
|
package/dist/terminal-ws.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Server } from "node:http";
|
|
2
|
-
import { WebSocketServer } from "ws";
|
|
2
|
+
import { WebSocketServer, type RawData } from "ws";
|
|
3
3
|
import { type RuntimeWebAccessPolicy } from "./runtime-web-auth.js";
|
|
4
4
|
import { type SessionTerminalHost } from "./session-terminal-host.js";
|
|
5
5
|
import type { RuntimeConnectionResolverHost } from "./server.js";
|
|
@@ -15,3 +15,6 @@ export interface TerminalWsDeps {
|
|
|
15
15
|
}
|
|
16
16
|
/** Attach the authenticated Runtime-scoped terminal bridge to an HTTP server. */
|
|
17
17
|
export declare function attachTerminalWs(server: Server, deps: TerminalWsDeps): WebSocketServer;
|
|
18
|
+
/** Reuse the terminal protocol's canonical parser at proxy boundaries that
|
|
19
|
+
* must admit resize controls while rejecting every form of terminal input. */
|
|
20
|
+
export declare function isBrowserTerminalResizeFrame(data: RawData, isBinary: boolean): boolean;
|
package/dist/terminal-ws.js
CHANGED
|
@@ -8,10 +8,10 @@ const MAX_DIMENSION = 1_000;
|
|
|
8
8
|
const MAX_BROWSER_MESSAGE_BYTES = 64 * 1024;
|
|
9
9
|
const MAX_PENDING_BROWSER_MESSAGES = 32;
|
|
10
10
|
const MAX_PENDING_BROWSER_BYTES = 128 * 1024;
|
|
11
|
-
const MAX_BROWSER_BUFFERED_BYTES = 1024 * 1024;
|
|
12
11
|
const INTERACTIVE_OUTPUT_CHUNK_BYTES = 2 * 1024;
|
|
13
|
-
const NORMAL_OUTPUT_CHUNK_BYTES =
|
|
12
|
+
const NORMAL_OUTPUT_CHUNK_BYTES = 64 * 1024;
|
|
14
13
|
const INTERACTIVE_ECHO_WINDOW_MS = 750;
|
|
14
|
+
const TERMINAL_OUTPUT_DRAIN_TIMEOUT_MS = 5_000;
|
|
15
15
|
const WS_CLOSE_BAD_REQUEST = 4400;
|
|
16
16
|
const WS_CLOSE_UNAUTHORIZED = 4403;
|
|
17
17
|
/** Reserved exclusively for an attachment that was not live at open time. */
|
|
@@ -76,7 +76,7 @@ async function handleConnection(ws, url, route, deps) {
|
|
|
76
76
|
let terminal;
|
|
77
77
|
let browserClosed = false;
|
|
78
78
|
let cleanupPromise;
|
|
79
|
-
let
|
|
79
|
+
let lastAcknowledgedInputAt = Number.NEGATIVE_INFINITY;
|
|
80
80
|
let liveInputTail = Promise.resolve();
|
|
81
81
|
let liveInputFrames = 0;
|
|
82
82
|
let liveInputBytes = 0;
|
|
@@ -95,6 +95,7 @@ async function handleConnection(ws, url, route, deps) {
|
|
|
95
95
|
cleanupPromise = (async () => {
|
|
96
96
|
try {
|
|
97
97
|
await opened?.close();
|
|
98
|
+
await liveInputTail.catch(() => undefined);
|
|
98
99
|
}
|
|
99
100
|
finally {
|
|
100
101
|
acquired?.release();
|
|
@@ -122,8 +123,6 @@ async function handleConnection(ws, url, route, deps) {
|
|
|
122
123
|
void cleanup();
|
|
123
124
|
return;
|
|
124
125
|
}
|
|
125
|
-
if (input.type === "input")
|
|
126
|
-
lastClientInputAt = Date.now();
|
|
127
126
|
const bytes = input.type === "input" ? input.data.byteLength : 16;
|
|
128
127
|
const opened = terminal;
|
|
129
128
|
if (opened && inputReady) {
|
|
@@ -135,7 +134,11 @@ async function handleConnection(ws, url, route, deps) {
|
|
|
135
134
|
}
|
|
136
135
|
liveInputFrames += 1;
|
|
137
136
|
liveInputBytes += bytes;
|
|
138
|
-
const operation = liveInputTail.then(() =>
|
|
137
|
+
const operation = liveInputTail.then(async () => {
|
|
138
|
+
const acknowledgedInput = await applyBrowserInput(opened, input);
|
|
139
|
+
if (acknowledgedInput)
|
|
140
|
+
lastAcknowledgedInputAt = performance.now();
|
|
141
|
+
});
|
|
139
142
|
liveInputTail = operation
|
|
140
143
|
.catch((error) => {
|
|
141
144
|
closeForError(ws, error);
|
|
@@ -205,26 +208,42 @@ async function handleConnection(ws, url, route, deps) {
|
|
|
205
208
|
return;
|
|
206
209
|
}
|
|
207
210
|
terminal = opened;
|
|
208
|
-
sendText(ws, {
|
|
211
|
+
sendText(ws, {
|
|
212
|
+
t: "opened",
|
|
213
|
+
role: opened.role,
|
|
214
|
+
...(opened.dimensions ?? {}),
|
|
215
|
+
});
|
|
216
|
+
opened.onResize?.(({ cols, rows }) => {
|
|
217
|
+
if (!browserClosed)
|
|
218
|
+
sendText(ws, { t: "dimensions", cols, rows });
|
|
219
|
+
});
|
|
220
|
+
let seedOffset = 0;
|
|
221
|
+
while (seedOffset < opened.seedBytes) {
|
|
222
|
+
const seed = await opened.readSeed(seedOffset, NORMAL_OUTPUT_CHUNK_BYTES);
|
|
223
|
+
if (seed.data.byteLength > 0)
|
|
224
|
+
await sendBinary(ws, seed.data);
|
|
225
|
+
seedOffset = seed.nextOffset;
|
|
226
|
+
if (seed.done)
|
|
227
|
+
break;
|
|
228
|
+
}
|
|
229
|
+
if (seedOffset !== opened.seedBytes) {
|
|
230
|
+
throw new Error(`Terminal history ended at ${seedOffset}, expected ${opened.seedBytes}`);
|
|
231
|
+
}
|
|
232
|
+
await opened.start();
|
|
209
233
|
while (pendingInputs.length > 0) {
|
|
210
234
|
const batch = pendingInputs.splice(0);
|
|
211
235
|
for (const queued of batch) {
|
|
212
236
|
pendingInputBytes -= queued.bytes;
|
|
213
|
-
await applyBrowserInput(opened, queued.input);
|
|
237
|
+
const acknowledgedInput = await applyBrowserInput(opened, queued.input);
|
|
238
|
+
if (acknowledgedInput)
|
|
239
|
+
lastAcknowledgedInputAt = performance.now();
|
|
214
240
|
}
|
|
215
241
|
}
|
|
216
242
|
pendingInputBytes = 0;
|
|
217
243
|
inputReady = true;
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
const chunkSize = Date.now() - lastClientInputAt < INTERACTIVE_ECHO_WINDOW_MS
|
|
222
|
-
? INTERACTIVE_OUTPUT_CHUNK_BYTES
|
|
223
|
-
: NORMAL_OUTPUT_CHUNK_BYTES;
|
|
224
|
-
for (let offset = 0; offset < output.byteLength; offset += chunkSize) {
|
|
225
|
-
await sendBinary(ws, output.subarray(offset, Math.min(offset + chunkSize, output.byteLength)));
|
|
226
|
-
}
|
|
227
|
-
}
|
|
244
|
+
await forwardTerminalOutput(ws, opened, () => (performance.now() - lastAcknowledgedInputAt < INTERACTIVE_ECHO_WINDOW_MS
|
|
245
|
+
? INTERACTIVE_OUTPUT_CHUNK_BYTES
|
|
246
|
+
: NORMAL_OUTPUT_CHUNK_BYTES));
|
|
228
247
|
if (browserClosed)
|
|
229
248
|
return;
|
|
230
249
|
const closed = await opened.closed;
|
|
@@ -297,23 +316,34 @@ function parseBrowserInput(data, isBinary) {
|
|
|
297
316
|
}
|
|
298
317
|
throw new Error("Unknown or invalid terminal control frame");
|
|
299
318
|
}
|
|
319
|
+
/** Reuse the terminal protocol's canonical parser at proxy boundaries that
|
|
320
|
+
* must admit resize controls while rejecting every form of terminal input. */
|
|
321
|
+
export function isBrowserTerminalResizeFrame(data, isBinary) {
|
|
322
|
+
try {
|
|
323
|
+
return parseBrowserInput(data, isBinary).type === "resize";
|
|
324
|
+
}
|
|
325
|
+
catch {
|
|
326
|
+
return false;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
300
329
|
async function applyBrowserInput(terminal, input) {
|
|
301
330
|
if (input.type === "input") {
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
return;
|
|
331
|
+
if (terminal.role !== "owner")
|
|
332
|
+
return false;
|
|
333
|
+
await terminal.write(input.data);
|
|
334
|
+
return true;
|
|
306
335
|
}
|
|
307
336
|
await terminal.resize(input.cols, input.rows);
|
|
337
|
+
return false;
|
|
308
338
|
}
|
|
309
339
|
async function sendBinary(ws, data) {
|
|
310
340
|
if (ws.readyState !== WebSocket.OPEN)
|
|
311
341
|
throw transportError("Browser terminal is closed");
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
342
|
+
// Await every send and admit only one frame at a time. Terminal output may
|
|
343
|
+
// legitimately arrive in multi-megabyte bursts; a fixed bufferedAmount
|
|
344
|
+
// cutoff turns a temporarily slow browser into a detached healthy pane.
|
|
345
|
+
// The terminal forwarder coalesces normal output to 64 KiB frames and uses
|
|
346
|
+
// 2 KiB frames in the interactive echo window.
|
|
317
347
|
await new Promise((resolve, reject) => {
|
|
318
348
|
ws.send(data, { binary: true, compress: false }, (error) => {
|
|
319
349
|
if (error)
|
|
@@ -323,6 +353,42 @@ async function sendBinary(ws, data) {
|
|
|
323
353
|
});
|
|
324
354
|
});
|
|
325
355
|
}
|
|
356
|
+
async function forwardTerminalOutput(ws, terminal, frameLimit) {
|
|
357
|
+
let drainTimer;
|
|
358
|
+
const drainDeadline = terminal.closed.then((closed) => new Promise((_, reject) => {
|
|
359
|
+
if (closed.reason !== "terminal_exited")
|
|
360
|
+
return;
|
|
361
|
+
drainTimer = setTimeout(() => {
|
|
362
|
+
const error = new Error(`Terminal output did not drain within ${TERMINAL_OUTPUT_DRAIN_TIMEOUT_MS}ms after exit`);
|
|
363
|
+
error.name = "BackpressureError";
|
|
364
|
+
// A pending ws send has no cancellation primitive. Terminating the
|
|
365
|
+
// transport is the only way to guarantee teardown after the deadline.
|
|
366
|
+
if (ws.readyState === WebSocket.OPEN || ws.readyState === WebSocket.CLOSING) {
|
|
367
|
+
ws.terminate();
|
|
368
|
+
}
|
|
369
|
+
reject(error);
|
|
370
|
+
}, TERMINAL_OUTPUT_DRAIN_TIMEOUT_MS);
|
|
371
|
+
drainTimer.unref?.();
|
|
372
|
+
}));
|
|
373
|
+
const forwarding = (async () => {
|
|
374
|
+
let offset = 0;
|
|
375
|
+
for (;;) {
|
|
376
|
+
const next = await terminal.read(offset, frameLimit());
|
|
377
|
+
if (next.data.byteLength > 0)
|
|
378
|
+
await sendBinary(ws, next.data);
|
|
379
|
+
offset = next.nextOffset;
|
|
380
|
+
if (next.done)
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
383
|
+
})();
|
|
384
|
+
try {
|
|
385
|
+
await Promise.race([forwarding, drainDeadline]);
|
|
386
|
+
}
|
|
387
|
+
finally {
|
|
388
|
+
if (drainTimer)
|
|
389
|
+
clearTimeout(drainTimer);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
326
392
|
function sendText(ws, value) {
|
|
327
393
|
if (ws.readyState === WebSocket.OPEN) {
|
|
328
394
|
ws.send(JSON.stringify(value), { binary: false, compress: false });
|