@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.
Files changed (497) hide show
  1. package/dist/control-api.d.ts +17 -4
  2. package/dist/control-api.js +722 -84
  3. package/dist/control-web/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  4. package/dist/control-web/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  5. package/dist/control-web/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  6. package/dist/control-web/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  7. package/dist/control-web/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  8. package/dist/control-web/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  9. package/dist/control-web/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  10. package/dist/control-web/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  11. package/dist/control-web/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  12. package/dist/control-web/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  13. package/dist/control-web/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  14. package/dist/control-web/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  15. package/dist/control-web/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  16. package/dist/control-web/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  17. package/dist/control-web/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  18. package/dist/control-web/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  19. package/dist/control-web/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  20. package/dist/control-web/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  21. package/dist/control-web/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  22. package/dist/control-web/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  23. package/dist/control-web/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  24. package/dist/control-web/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  25. package/dist/control-web/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  26. package/dist/control-web/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  27. package/dist/control-web/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  28. package/dist/control-web/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  29. package/dist/control-web/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  30. package/dist/control-web/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  31. package/dist/control-web/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  32. package/dist/control-web/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  33. package/dist/control-web/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  34. package/dist/control-web/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  35. package/dist/control-web/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  36. package/dist/control-web/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  37. package/dist/control-web/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  38. package/dist/control-web/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  39. package/dist/control-web/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  40. package/dist/control-web/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  41. package/dist/control-web/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  42. package/dist/control-web/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  43. package/dist/control-web/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  44. package/dist/control-web/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  45. package/dist/control-web/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  46. package/dist/control-web/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  47. package/dist/control-web/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  48. package/dist/control-web/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  49. package/dist/control-web/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  50. package/dist/control-web/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  51. package/dist/control-web/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  52. package/dist/control-web/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  53. package/dist/control-web/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  54. package/dist/control-web/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  55. package/dist/control-web/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  56. package/dist/control-web/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  57. package/dist/control-web/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  58. package/dist/control-web/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  59. package/dist/control-web/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  60. package/dist/control-web/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  61. package/dist/control-web/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  62. package/dist/control-web/assets/abap-CLvhMVsD.js +1 -0
  63. package/dist/control-web/assets/abnfDiagram-VRR7QNED-D_NL89dn.js +1 -0
  64. package/dist/control-web/assets/actionscript-3--17pq3dv.js +1 -0
  65. package/dist/control-web/assets/ada-C5qYipkI.js +1 -0
  66. package/dist/control-web/assets/andromeeda-vGVdxbeo.js +1 -0
  67. package/dist/control-web/assets/angular-html-DlZBZkSp.js +1 -0
  68. package/dist/control-web/assets/angular-ts-BVPGOT0K.js +1 -0
  69. package/dist/control-web/assets/apache-U0d_L8uA.js +1 -0
  70. package/dist/control-web/assets/apex-CGTLDQj6.js +1 -0
  71. package/dist/control-web/assets/apl-cDmXqmZ-.js +1 -0
  72. package/dist/control-web/assets/applescript-CCn79oCD.js +1 -0
  73. package/dist/control-web/assets/ara-4CJ0cIlV.js +1 -0
  74. package/dist/control-web/assets/arc-Pry-7G1_.js +1 -0
  75. package/dist/control-web/assets/architecture-TIHT7OUA-C9wU1KtW.js +1 -0
  76. package/dist/control-web/assets/architectureDiagram-ZJ3FMSHR-CV0rxVH6.js +36 -0
  77. package/dist/control-web/assets/array-BifhSqXX.js +1 -0
  78. package/dist/control-web/assets/asciidoc-DE70LPWp.js +1 -0
  79. package/dist/control-web/assets/asm-Cmm7eHzH.js +1 -0
  80. package/dist/control-web/assets/astro-B1Q6BwBx.js +1 -0
  81. package/dist/control-web/assets/aurora-x-CDeNXAV0.js +1 -0
  82. package/dist/control-web/assets/awk-BWXHIvNe.js +1 -0
  83. package/dist/control-web/assets/ayu-dark-DluEY0Gj.js +1 -0
  84. package/dist/control-web/assets/ayu-light-C3h-C4tm.js +1 -0
  85. package/dist/control-web/assets/ayu-mirage-Bqwy1Gya.js +1 -0
  86. package/dist/control-web/assets/ballerina-B7ZEbQpA.js +1 -0
  87. package/dist/control-web/assets/bat-Bo4NYOV-.js +1 -0
  88. package/dist/control-web/assets/beancount-D-usSTwE.js +1 -0
  89. package/dist/control-web/assets/berry-DKpUyyne.js +1 -0
  90. package/dist/control-web/assets/bibtex-Ci_nEsc7.js +1 -0
  91. package/dist/control-web/assets/bicep-CUHmPFLl.js +1 -0
  92. package/dist/control-web/assets/bird2-C2hNVINV.js +1 -0
  93. package/dist/control-web/assets/blade-Xpu-LGTm.js +1 -0
  94. package/dist/control-web/assets/blockDiagram-677ZJIJ3-Cc7nrkZh.js +132 -0
  95. package/dist/control-web/assets/bsl-BkkzgIyY.js +1 -0
  96. package/dist/control-web/assets/c-iCihek07.js +1 -0
  97. package/dist/control-web/assets/c3-CnJL0r0V.js +1 -0
  98. package/dist/control-web/assets/c4Diagram-LMCZKHZV-BPRU9m-F.js +10 -0
  99. package/dist/control-web/assets/cadence-CQ2zXKGN.js +1 -0
  100. package/dist/control-web/assets/cairo-DLTphjLi.js +1 -0
  101. package/dist/control-web/assets/catppuccin-frappe-3VR1Za6u.js +1 -0
  102. package/dist/control-web/assets/catppuccin-latte-DwIHMF0Q.js +1 -0
  103. package/dist/control-web/assets/catppuccin-macchiato-DYnBP6_5.js +1 -0
  104. package/dist/control-web/assets/catppuccin-mocha-DYhrFGRu.js +1 -0
  105. package/dist/control-web/assets/channel-BFm2_j8K.js +1 -0
  106. package/dist/control-web/assets/chunk-2Q5K7J3B-C1jixKkw.js +1 -0
  107. package/dist/control-web/assets/chunk-32BRIVSS-Bbq3O54m.js +1 -0
  108. package/dist/control-web/assets/chunk-52WLFC77-sD4al-Ob.js +10 -0
  109. package/dist/control-web/assets/chunk-5VM5RSS4-ZNzvKenW.js +15 -0
  110. package/dist/control-web/assets/chunk-7BUUIJ7U-Bb538aSH.js +1 -0
  111. package/dist/control-web/assets/chunk-C7G6YPKG-DqHaDS1O.js +1 -0
  112. package/dist/control-web/assets/chunk-EX3LRPZG-36GNQ5wp.js +231 -0
  113. package/dist/control-web/assets/chunk-HOUHSVGY-DeZ63q1j.js +1 -0
  114. package/dist/control-web/assets/chunk-ICXQ74PX-D2yF6lD_.js +2 -0
  115. package/dist/control-web/assets/chunk-JWPE2WC7-DVXcaiue.js +1 -0
  116. package/dist/control-web/assets/chunk-KEIR6QF5-BICK3FdT.js +161 -0
  117. package/dist/control-web/assets/chunk-MOJQB5TN-CdaKyBz5.js +88 -0
  118. package/dist/control-web/assets/chunk-OGEWGWER-eOXC7kiH.js +1 -0
  119. package/dist/control-web/assets/chunk-PUDLZKDR-6w0LILL_.js +156 -0
  120. package/dist/control-web/assets/chunk-Q4XR5HBZ-CXgD5TGL.js +70 -0
  121. package/dist/control-web/assets/chunk-RYQCIY6F-BsoV8yK2.js +1 -0
  122. package/dist/control-web/assets/chunk-V7JOEXUC-BfoZ78b6.js +206 -0
  123. package/dist/control-web/assets/chunk-VR4S4FIN-BW2gCEMQ.js +1 -0
  124. package/dist/control-web/assets/chunk-WYO6CB5R-CHn7hulw.js +128 -0
  125. package/dist/control-web/assets/chunk-XXDRQBXY-DqAYeljN.js +1 -0
  126. package/dist/control-web/assets/chunk-Y2CYZVJY-DsF7k-Jl.js +1 -0
  127. package/dist/control-web/assets/chunk-ZGVPDNZ5-CmFP0-fr.js +62 -0
  128. package/dist/control-web/assets/clarity-SemFz856.js +1 -0
  129. package/dist/control-web/assets/classDiagram-OUVF2IWQ-CUe_bETB.js +1 -0
  130. package/dist/control-web/assets/classDiagram-v2-EOCWNBFH-CUe_bETB.js +1 -0
  131. package/dist/control-web/assets/clojure-DqKBuwfJ.js +1 -0
  132. package/dist/control-web/assets/cmake-Bj61d0ZC.js +1 -0
  133. package/dist/control-web/assets/cobol-BsV-839J.js +1 -0
  134. package/dist/control-web/assets/codeowners-C8r90Shi.js +1 -0
  135. package/dist/control-web/assets/codeql-oeQT6MSM.js +1 -0
  136. package/dist/control-web/assets/coffee-CiiSLhB6.js +1 -0
  137. package/dist/control-web/assets/common-lisp-Cv5bFMCO.js +1 -0
  138. package/dist/control-web/assets/coq-BrsZFFmf.js +1 -0
  139. package/dist/control-web/assets/cose-bilkent-JH36ORCC-lJEhNiw_.js +1 -0
  140. package/dist/control-web/assets/cpp-DjoE5qBx.js +1 -0
  141. package/dist/control-web/assets/crystal-DDxHDkHz.js +1 -0
  142. package/dist/control-web/assets/csharp-Ct8U2NOr.js +1 -0
  143. package/dist/control-web/assets/css-LjpOdHib.js +1 -0
  144. package/dist/control-web/assets/csv-Dx-8-gkx.js +1 -0
  145. package/dist/control-web/assets/cue-CE9AQfxI.js +1 -0
  146. package/dist/control-web/assets/cynefin-VYW2F7L2-NaLr7Qlq.js +1 -0
  147. package/dist/control-web/assets/cynefinDiagram-TSTJHNR4-C90wpjAI.js +62 -0
  148. package/dist/control-web/assets/cypher-ClKdZ_lG.js +1 -0
  149. package/dist/control-web/assets/cytoscape.esm-B-NFISlW.js +321 -0
  150. package/dist/control-web/assets/d-qD-0Kul2.js +1 -0
  151. package/dist/control-web/assets/dagre-Buvkdvvj.js +1 -0
  152. package/dist/control-web/assets/dagre-VKFMJZFB-BxrPFWTb.js +4 -0
  153. package/dist/control-web/assets/dark-plus-Cs2F2srj.js +1 -0
  154. package/dist/control-web/assets/dart-DkHntEIa.js +1 -0
  155. package/dist/control-web/assets/dax-BkyTk9wS.js +1 -0
  156. package/dist/control-web/assets/defaultLocale-BFoDCU3G.js +1 -0
  157. package/dist/control-web/assets/desktop-Dlh5hvp9.js +1 -0
  158. package/dist/control-web/assets/diagram-FQU43EPY-VIQINsvz.js +3 -0
  159. package/dist/control-web/assets/diagram-G47NLZAW-DFeAfYXn.js +24 -0
  160. package/dist/control-web/assets/diagram-NH7WQ7WH-ATzdppDd.js +24 -0
  161. package/dist/control-web/assets/diagram-OA4YK3LP-DJZpWmbl.js +30 -0
  162. package/dist/control-web/assets/diagram-WEI45ONY-CqDHcW3g.js +41 -0
  163. package/dist/control-web/assets/diff-woXpYk--.js +1 -0
  164. package/dist/control-web/assets/dist-Dx9YWgcW.js +153 -0
  165. package/dist/control-web/assets/dist-v5Q1xZ2K.js +1 -0
  166. package/dist/control-web/assets/docker-IyjqRm3v.js +1 -0
  167. package/dist/control-web/assets/dotenv-_5a1GRtc.js +1 -0
  168. package/dist/control-web/assets/dracula-BHWKrbxM.js +1 -0
  169. package/dist/control-web/assets/dracula-soft-5eyTD99u.js +1 -0
  170. package/dist/control-web/assets/dream-maker-DW3nJb8Q.js +1 -0
  171. package/dist/control-web/assets/ebnfDiagram-CCIWWBDH-DnP6dHND.js +1 -0
  172. package/dist/control-web/assets/edge-8z7Jp9dO.js +1 -0
  173. package/dist/control-web/assets/elixir-CUV54ev5.js +1 -0
  174. package/dist/control-web/assets/elm-o4NJxfws.js +1 -0
  175. package/dist/control-web/assets/emacs-lisp-C9PiwqqW.js +1 -0
  176. package/dist/control-web/assets/erDiagram-Q63AITRT-Bo8bFqrZ.js +85 -0
  177. package/dist/control-web/assets/erb-CIsHcwm1.js +1 -0
  178. package/dist/control-web/assets/erlang-Cphh6RMH.js +1 -0
  179. package/dist/control-web/assets/eventmodeling-45OFAUF4-DTN8wqsu.js +1 -0
  180. package/dist/control-web/assets/everforest-dark-sB-x3p7T.js +1 -0
  181. package/dist/control-web/assets/everforest-light-Df2xbC6M.js +1 -0
  182. package/dist/control-web/assets/fennel-DQxkIbk2.js +1 -0
  183. package/dist/control-web/assets/fish-BJitypiv.js +1 -0
  184. package/dist/control-web/assets/flowDiagram-23GEKE2U-BwjqRyvd.js +1 -0
  185. package/dist/control-web/assets/fluent-C03EYrpw.js +1 -0
  186. package/dist/control-web/assets/fortran-fixed-form-DEKoE2YW.js +1 -0
  187. package/dist/control-web/assets/fortran-free-form-CYNrtFtB.js +1 -0
  188. package/dist/control-web/assets/fsharp-D13ZGOAj.js +1 -0
  189. package/dist/control-web/assets/ganttDiagram-NO4QXBWP-kxQaBTzd.js +292 -0
  190. package/dist/control-web/assets/gdresource-C0sCabJj.js +1 -0
  191. package/dist/control-web/assets/gdscript-Cp2uCuqX.js +1 -0
  192. package/dist/control-web/assets/gdshader-CBce3t8t.js +1 -0
  193. package/dist/control-web/assets/genie-CV2tkWYe.js +1 -0
  194. package/dist/control-web/assets/gherkin-DExj1W_8.js +1 -0
  195. package/dist/control-web/assets/git-commit-BSykSTBG.js +1 -0
  196. package/dist/control-web/assets/git-rebase-BDPpS8w6.js +1 -0
  197. package/dist/control-web/assets/gitGraph-TEB2WS4Q-a646NnuJ.js +1 -0
  198. package/dist/control-web/assets/gitGraphDiagram-IHSO6WYX-BBe0q0At.js +106 -0
  199. package/dist/control-web/assets/github-dark-C-LZuMrd.js +1 -0
  200. package/dist/control-web/assets/github-dark-default-DXG-b-1a.js +1 -0
  201. package/dist/control-web/assets/github-dark-dimmed-Bx1FflLF.js +1 -0
  202. package/dist/control-web/assets/github-dark-high-contrast-B_tTalzw.js +1 -0
  203. package/dist/control-web/assets/github-light-EUqPIrTm.js +1 -0
  204. package/dist/control-web/assets/github-light-default-BXViO-2h.js +1 -0
  205. package/dist/control-web/assets/github-light-high-contrast-B68TUdTA.js +1 -0
  206. package/dist/control-web/assets/gleam-CSRkHgEL.js +1 -0
  207. package/dist/control-web/assets/glimmer-js-OEO36pDk.js +1 -0
  208. package/dist/control-web/assets/glimmer-ts-BnAPyISE.js +1 -0
  209. package/dist/control-web/assets/glsl-D5MA2a_X.js +1 -0
  210. package/dist/control-web/assets/gn-ilITqXS6.js +1 -0
  211. package/dist/control-web/assets/gnuplot-7GGW24-e.js +1 -0
  212. package/dist/control-web/assets/go-BJwz_mda.js +1 -0
  213. package/dist/control-web/assets/graphlib-DS17s2tU.js +1 -0
  214. package/dist/control-web/assets/graphql-Ctjuxyvl.js +1 -0
  215. package/dist/control-web/assets/groovy-CacY0gHj.js +1 -0
  216. package/dist/control-web/assets/gruvbox-dark-hard-C820rvS2.js +1 -0
  217. package/dist/control-web/assets/gruvbox-dark-medium-BPjhmG05.js +1 -0
  218. package/dist/control-web/assets/gruvbox-dark-soft-MrdJrrXF.js +1 -0
  219. package/dist/control-web/assets/gruvbox-light-hard-BC_s9l72.js +1 -0
  220. package/dist/control-web/assets/gruvbox-light-medium-BAWPOn9u.js +1 -0
  221. package/dist/control-web/assets/gruvbox-light-soft-BSMLrYjP.js +1 -0
  222. package/dist/control-web/assets/hack-D_mkkoLd.js +1 -0
  223. package/dist/control-web/assets/haml-mpgecWZ6.js +1 -0
  224. package/dist/control-web/assets/handlebars-CAx_777f.js +1 -0
  225. package/dist/control-web/assets/haskell-D8IpX4py.js +1 -0
  226. package/dist/control-web/assets/haxe-OTjmBuCE.js +1 -0
  227. package/dist/control-web/assets/hcl-Dh228itO.js +1 -0
  228. package/dist/control-web/assets/highlighted-body-OFNGDK62-DVCHy9oI.js +1 -0
  229. package/dist/control-web/assets/hjson-CxZEssPk.js +1 -0
  230. package/dist/control-web/assets/hlsl-Cvrh5tZx.js +1 -0
  231. package/dist/control-web/assets/horizon-CE9ld1lL.js +1 -0
  232. package/dist/control-web/assets/horizon-bright-Br1oVSNq.js +1 -0
  233. package/dist/control-web/assets/houston-CsvMBhTu.js +1 -0
  234. package/dist/control-web/assets/html-B2lrdnWr.js +1 -0
  235. package/dist/control-web/assets/html-derivative-CDfZYcul.js +1 -0
  236. package/dist/control-web/assets/http-kmH8AyfE.js +1 -0
  237. package/dist/control-web/assets/hurl-DCZHXKU4.js +1 -0
  238. package/dist/control-web/assets/hxml-B0Qn7Nwc.js +1 -0
  239. package/dist/control-web/assets/hy-CZbG8q4J.js +1 -0
  240. package/dist/control-web/assets/imba-DsUTQ-LC.js +1 -0
  241. package/dist/control-web/assets/index-D7URT6K_.js +140 -0
  242. package/dist/control-web/assets/index-uEpvRMX9.css +1 -0
  243. package/dist/control-web/assets/info-DKCQHKI2-Cp_JrY-b.js +1 -0
  244. package/dist/control-web/assets/infoDiagram-FWYZ7A6U-CAm-h4F_.js +2 -0
  245. package/dist/control-web/assets/ini-B5eOa1yu.js +1 -0
  246. package/dist/control-web/assets/init-C-OQMol4.js +1 -0
  247. package/dist/control-web/assets/ishikawaDiagram-FXEZZL3T-O17pqcWr.js +70 -0
  248. package/dist/control-web/assets/java-DdHNQ9hk.js +1 -0
  249. package/dist/control-web/assets/javascript-obGGvMPs.js +1 -0
  250. package/dist/control-web/assets/jinja-BMiPVedm.js +1 -0
  251. package/dist/control-web/assets/jison-CBjhYtSs.js +1 -0
  252. package/dist/control-web/assets/journeyDiagram-5HDEW3XC-DQ-JuSoR.js +139 -0
  253. package/dist/control-web/assets/json-DAgxKhMr.js +1 -0
  254. package/dist/control-web/assets/json5-BR5RXkoi.js +1 -0
  255. package/dist/control-web/assets/jsonc-CYpm1nAK.js +1 -0
  256. package/dist/control-web/assets/jsonl-CmCQp5Yx.js +1 -0
  257. package/dist/control-web/assets/jsonnet-CJTPZ8u_.js +1 -0
  258. package/dist/control-web/assets/jssm-DXw9l8Rf.js +1 -0
  259. package/dist/control-web/assets/jsx-gTgmArGx.js +1 -0
  260. package/dist/control-web/assets/julia-CjHxn3vf.js +1 -0
  261. package/dist/control-web/assets/just-DMArCiVH.js +1 -0
  262. package/dist/control-web/assets/kanagawa-dragon-CXtmUGW6.js +1 -0
  263. package/dist/control-web/assets/kanagawa-lotus-BN08jTvb.js +1 -0
  264. package/dist/control-web/assets/kanagawa-wave-CTweb8Dz.js +1 -0
  265. package/dist/control-web/assets/kanban-definition-HUTT4EX6-Cgv3kPbm.js +89 -0
  266. package/dist/control-web/assets/katex-CyHG4N6b.js +1 -0
  267. package/dist/control-web/assets/kdl-CsD5j6eV.js +1 -0
  268. package/dist/control-web/assets/kotlin-DhhofPvG.js +1 -0
  269. package/dist/control-web/assets/kusto-BUv0MjJC.js +1 -0
  270. package/dist/control-web/assets/laserwave-C_8bwKvT.js +1 -0
  271. package/dist/control-web/assets/latex-D9bvcAJr.js +1 -0
  272. package/dist/control-web/assets/lean-CewbzKMR.js +1 -0
  273. package/dist/control-web/assets/less-DVTAwKKz.js +1 -0
  274. package/dist/control-web/assets/lib-BZ_F5vVH.js +1 -0
  275. package/dist/control-web/assets/light-plus-DVQuIRkW.js +1 -0
  276. package/dist/control-web/assets/line-DUsXzGJZ.js +1 -0
  277. package/dist/control-web/assets/linear-DmucvK78.js +1 -0
  278. package/dist/control-web/assets/liquid-CCX5qouA.js +1 -0
  279. package/dist/control-web/assets/llvm-Cm23YOpf.js +1 -0
  280. package/dist/control-web/assets/log-BNLmms1o.js +1 -0
  281. package/dist/control-web/assets/logo-Cluzi2Zq.js +1 -0
  282. package/dist/control-web/assets/lua-FONpmTUP.js +1 -0
  283. package/dist/control-web/assets/luau-CNKltnaQ.js +1 -0
  284. package/dist/control-web/assets/make-Dixweg8N.js +1 -0
  285. package/dist/control-web/assets/map-BaFkSB1l.js +1 -0
  286. package/dist/control-web/assets/markdown-BYOwaDjH.js +1 -0
  287. package/dist/control-web/assets/markdown-streamdown-4N4AcNp5.js +433 -0
  288. package/dist/control-web/assets/markdown-streamdown-DEcVZfaU.css +1 -0
  289. package/dist/control-web/assets/marko-oPGh3KfH.js +1 -0
  290. package/dist/control-web/assets/material-theme-Bm3Qr25_.js +1 -0
  291. package/dist/control-web/assets/material-theme-darker-2IIEA8gg.js +1 -0
  292. package/dist/control-web/assets/material-theme-lighter-uhdI0v04.js +1 -0
  293. package/dist/control-web/assets/material-theme-ocean-CHQ94UKr.js +1 -0
  294. package/dist/control-web/assets/material-theme-palenight-B5W6OYN7.js +1 -0
  295. package/dist/control-web/assets/matlab-D7qyCx1q.js +1 -0
  296. package/dist/control-web/assets/mdc-B_uQHOlt.js +1 -0
  297. package/dist/control-web/assets/mdx-DQZ5AkYe.js +1 -0
  298. package/dist/control-web/assets/mermaid-Bk4SNUv9.js +1 -0
  299. package/dist/control-web/assets/mermaid-GHXKKRXX-BElZGKGd.js +1 -0
  300. package/dist/control-web/assets/mermaid-parser.core-VMln12Kd.js +7 -0
  301. package/dist/control-web/assets/min-dark-BSWPekZh.js +1 -0
  302. package/dist/control-web/assets/min-light-DDpmG2fV.js +1 -0
  303. package/dist/control-web/assets/mindmap-definition-LN4V7U3C-Bn0lH-UM.js +96 -0
  304. package/dist/control-web/assets/mipsasm-BMqwQI7S.js +1 -0
  305. package/dist/control-web/assets/mojo-BgCJLMeH.js +1 -0
  306. package/dist/control-web/assets/monokai-CdkpiU2Y.js +1 -0
  307. package/dist/control-web/assets/moonbit-CaWjb8XO.js +1 -0
  308. package/dist/control-web/assets/move-B1IS1UjX.js +1 -0
  309. package/dist/control-web/assets/narrat-_X_XdTYD.js +1 -0
  310. package/dist/control-web/assets/nextflow-Bbiyy34d.js +1 -0
  311. package/dist/control-web/assets/nextflow-groovy-Dc_ddanL.js +1 -0
  312. package/dist/control-web/assets/nginx-BTMw9COX.js +1 -0
  313. package/dist/control-web/assets/night-owl-DhmEMT88.js +1 -0
  314. package/dist/control-web/assets/night-owl-light-eJ-hLW7d.js +1 -0
  315. package/dist/control-web/assets/nim-8PQFL6ZB.js +1 -0
  316. package/dist/control-web/assets/nix-IvuFDN5E.js +1 -0
  317. package/dist/control-web/assets/nord-Cb4Vim4T.js +1 -0
  318. package/dist/control-web/assets/nushell-DcLAeLz5.js +1 -0
  319. package/dist/control-web/assets/objective-c-D1A_Heim.js +1 -0
  320. package/dist/control-web/assets/objective-cpp-BsSzOQcm.js +1 -0
  321. package/dist/control-web/assets/ocaml-O90oeIOV.js +1 -0
  322. package/dist/control-web/assets/odin-B1RWQWA5.js +1 -0
  323. package/dist/control-web/assets/one-dark-pro-CLwyXe_n.js +1 -0
  324. package/dist/control-web/assets/one-light-D7Lr4KcI.js +1 -0
  325. package/dist/control-web/assets/openscad-BUDT5pXO.js +1 -0
  326. package/dist/control-web/assets/ordinal-BDEzSJ7C.js +1 -0
  327. package/dist/control-web/assets/packet-7NZHBO7P-Zw8iJ8lo.js +1 -0
  328. package/dist/control-web/assets/pascal-4ZHwLPI5.js +1 -0
  329. package/dist/control-web/assets/path-fybaL0A-.js +1 -0
  330. package/dist/control-web/assets/pegDiagram-2B236MQR-CtF7vVs_.js +1 -0
  331. package/dist/control-web/assets/perl-Vf0i0hAx.js +1 -0
  332. package/dist/control-web/assets/php-am1OsKhm.js +1 -0
  333. package/dist/control-web/assets/pie-RZYD4A2V-su_3QGU2.js +1 -0
  334. package/dist/control-web/assets/pieDiagram-ENE6RG2P-BkMUBLE1.js +39 -0
  335. package/dist/control-web/assets/pkl-ot-7Btpt.js +1 -0
  336. package/dist/control-web/assets/plastic-DQwYfKfQ.js +1 -0
  337. package/dist/control-web/assets/plsql-DGHpHOYJ.js +1 -0
  338. package/dist/control-web/assets/po-BiJDBrnU.js +1 -0
  339. package/dist/control-web/assets/poimandres-DRFjx7u4.js +1 -0
  340. package/dist/control-web/assets/polar-C7UOKdEL.js +1 -0
  341. package/dist/control-web/assets/postcss-BXeXVLqQ.js +1 -0
  342. package/dist/control-web/assets/powerquery-DNMTfnFr.js +1 -0
  343. package/dist/control-web/assets/powershell-DshXNtvi.js +1 -0
  344. package/dist/control-web/assets/prisma-BsRQq5mF.js +1 -0
  345. package/dist/control-web/assets/prolog-iXnhIJG7.js +1 -0
  346. package/dist/control-web/assets/proto-DB4EqR-F.js +1 -0
  347. package/dist/control-web/assets/pug-DO6yvBr3.js +1 -0
  348. package/dist/control-web/assets/puppet-CDv2pdJW.js +1 -0
  349. package/dist/control-web/assets/purescript-9MfHhQsQ.js +1 -0
  350. package/dist/control-web/assets/python-gzcpVVnB.js +1 -0
  351. package/dist/control-web/assets/qml-_a-QhfPD.js +1 -0
  352. package/dist/control-web/assets/qmldir-DCQb3MpD.js +1 -0
  353. package/dist/control-web/assets/qss-Fe1Jh2GI.js +1 -0
  354. package/dist/control-web/assets/quadrantDiagram-ABIIQ3AL-ba-VaqMe.js +7 -0
  355. package/dist/control-web/assets/r-D6UWEOL2.js +1 -0
  356. package/dist/control-web/assets/racket-DcIDlBhZ.js +1 -0
  357. package/dist/control-web/assets/radar-I7S5WNFK-Dat0rqem.js +1 -0
  358. package/dist/control-web/assets/railroad-3IZDKUUU-Dh2-s8r8.js +1 -0
  359. package/dist/control-web/assets/railroad-abnf-AHOZXSZD-CNUwq0JR.js +1 -0
  360. package/dist/control-web/assets/railroad-ebnf-EBAXGLYW-RHr0duea.js +1 -0
  361. package/dist/control-web/assets/railroad-peg-LSFZ7HO6-CVBWS2eU.js +1 -0
  362. package/dist/control-web/assets/railroadDiagram-RFXS5EU6-BiJX3SY-.js +1 -0
  363. package/dist/control-web/assets/raku-B3gFvitq.js +1 -0
  364. package/dist/control-web/assets/razor-CMVBVp3T.js +1 -0
  365. package/dist/control-web/assets/red-CJ3rzSJv.js +1 -0
  366. package/dist/control-web/assets/reg-CRGYupPL.js +1 -0
  367. package/dist/control-web/assets/regexp-DR20uMnK.js +1 -0
  368. package/dist/control-web/assets/rel-BtDbiS_P.js +1 -0
  369. package/dist/control-web/assets/requirementDiagram-TGXJPOKE-CFfakCzs.js +84 -0
  370. package/dist/control-web/assets/riscv-Ckw8ddFX.js +1 -0
  371. package/dist/control-web/assets/rolldown-runtime-hePW80VL.js +1 -0
  372. package/dist/control-web/assets/ron-VUp2lXgN.js +1 -0
  373. package/dist/control-web/assets/rose-pine-BthvhNj6.js +1 -0
  374. package/dist/control-web/assets/rose-pine-dawn-Dg85fqjY.js +1 -0
  375. package/dist/control-web/assets/rose-pine-moon-hon4tzzS.js +1 -0
  376. package/dist/control-web/assets/rosmsg-CAekHB0j.js +1 -0
  377. package/dist/control-web/assets/rough.esm-Dy-Kn_BL.js +1 -0
  378. package/dist/control-web/assets/rst-CgIrbW_q.js +1 -0
  379. package/dist/control-web/assets/ruby-Dp6Zud9H.js +1 -0
  380. package/dist/control-web/assets/rust-Cfkwpbl8.js +1 -0
  381. package/dist/control-web/assets/sankeyDiagram-HTMAVEWB-jgDi0God.js +40 -0
  382. package/dist/control-web/assets/sas-B6p8-ynO.js +1 -0
  383. package/dist/control-web/assets/sass-DXrisJhu.js +1 -0
  384. package/dist/control-web/assets/scala-DKOlJaKm.js +1 -0
  385. package/dist/control-web/assets/scheme-DQCgrYNe.js +1 -0
  386. package/dist/control-web/assets/scss-DcoSS-ti.js +1 -0
  387. package/dist/control-web/assets/sdbl-bTVj8UrX.js +1 -0
  388. package/dist/control-web/assets/sequenceDiagram-DBY2YBRQ-DBfyyb0N.js +162 -0
  389. package/dist/control-web/assets/shaderlab-TOUzSsQk.js +1 -0
  390. package/dist/control-web/assets/shellscript-Da78Ox-3.js +1 -0
  391. package/dist/control-web/assets/shellsession-CVsQGYfZ.js +1 -0
  392. package/dist/control-web/assets/sizeCapture-X5ZJPWSS-B0uUizjq.js +1 -0
  393. package/dist/control-web/assets/slack-dark-DnToyrRv.js +1 -0
  394. package/dist/control-web/assets/slack-ochin-B2OO5cIa.js +1 -0
  395. package/dist/control-web/assets/smalltalk-B16xEiuN.js +1 -0
  396. package/dist/control-web/assets/snazzy-light-4G7pJPwS.js +1 -0
  397. package/dist/control-web/assets/solarized-dark-DV17i1UV.js +1 -0
  398. package/dist/control-web/assets/solarized-light-DSh2HLQt.js +1 -0
  399. package/dist/control-web/assets/solidity-CKzVLygQ.js +1 -0
  400. package/dist/control-web/assets/soy-B5n_eHSp.js +1 -0
  401. package/dist/control-web/assets/sparql-D_iOobhT.js +1 -0
  402. package/dist/control-web/assets/splunk-BC2Px7Mm.js +1 -0
  403. package/dist/control-web/assets/sql-ClgswhA6.js +1 -0
  404. package/dist/control-web/assets/src-B6xuSHsQ.js +1 -0
  405. package/dist/control-web/assets/ssh-config-BgfXC-Er.js +1 -0
  406. package/dist/control-web/assets/stata-RoaAgbqU.js +1 -0
  407. package/dist/control-web/assets/stateDiagram-2N3HPSRC-Dwb_ncVi.js +1 -0
  408. package/dist/control-web/assets/stateDiagram-v2-6OUMAXLB-DI0opaA1.js +1 -0
  409. package/dist/control-web/assets/stylus-B6D30XZt.js +1 -0
  410. package/dist/control-web/assets/surrealql-DIn4NJsS.js +1 -0
  411. package/dist/control-web/assets/svelte-CIt8Fl9I.js +1 -0
  412. package/dist/control-web/assets/swift-DonLKvLd.js +1 -0
  413. package/dist/control-web/assets/swimlanes-5IMT3BWC-DW0LuiIV.js +2 -0
  414. package/dist/control-web/assets/swimlanesDiagram-G3AALYLV-DDTVjcOR.js +8 -0
  415. package/dist/control-web/assets/synthwave-84-nFMaYfgc.js +1 -0
  416. package/dist/control-web/assets/system-verilog-DJ5XKQeo.js +1 -0
  417. package/dist/control-web/assets/systemd-BxMlprV5.js +1 -0
  418. package/dist/control-web/assets/talonscript-CohzipZa.js +1 -0
  419. package/dist/control-web/assets/tasl-DMoTqEGO.js +1 -0
  420. package/dist/control-web/assets/tcl-CZd0xW_V.js +1 -0
  421. package/dist/control-web/assets/templ-BREsJpNc.js +1 -0
  422. package/dist/control-web/assets/terraform-DswuEJGm.js +1 -0
  423. package/dist/control-web/assets/tex-0w6-Dtgt.js +1 -0
  424. package/dist/control-web/assets/timeline-definition-FHXFAJF6-DeX4B_B8.js +120 -0
  425. package/dist/control-web/assets/tokyo-night-oM2G3aXe.js +1 -0
  426. package/dist/control-web/assets/toml-CcmNWLt0.js +1 -0
  427. package/dist/control-web/assets/treeView-QDETBFTQ-D1UXtICj.js +1 -0
  428. package/dist/control-web/assets/treemap-6X3UGDF4-CrppzjZH.js +1 -0
  429. package/dist/control-web/assets/ts-tags-q3pptdMi.js +1 -0
  430. package/dist/control-web/assets/tsv-sltzmVWM.js +1 -0
  431. package/dist/control-web/assets/tsx-CUOciP0b.js +1 -0
  432. package/dist/control-web/assets/turtle-ByJddavk.js +1 -0
  433. package/dist/control-web/assets/twig-LIeLXgf5.js +1 -0
  434. package/dist/control-web/assets/typescript-BydbNFcO.js +1 -0
  435. package/dist/control-web/assets/typespec-B88KGewJ.js +1 -0
  436. package/dist/control-web/assets/typst-DI99ib-x.js +1 -0
  437. package/dist/control-web/assets/v-DETTlOr0.js +1 -0
  438. package/dist/control-web/assets/vala-zf12oZj6.js +1 -0
  439. package/dist/control-web/assets/vb-Djn5o6TS.js +1 -0
  440. package/dist/control-web/assets/vennDiagram-L72KCM5P-BYpf-7VR.js +34 -0
  441. package/dist/control-web/assets/verilog-CiiDBU1e.js +1 -0
  442. package/dist/control-web/assets/vesper-D5bVUKB1.js +1 -0
  443. package/dist/control-web/assets/vhdl-BroJfC0k.js +1 -0
  444. package/dist/control-web/assets/viml-DvXPmvsu.js +1 -0
  445. package/dist/control-web/assets/vitesse-black-fwtXNY1n.js +1 -0
  446. package/dist/control-web/assets/vitesse-dark-BZCL-v6S.js +1 -0
  447. package/dist/control-web/assets/vitesse-light-VbXTXTou.js +1 -0
  448. package/dist/control-web/assets/vue-DVSfBueU.js +1 -0
  449. package/dist/control-web/assets/vue-html-DkKkQnZL.js +1 -0
  450. package/dist/control-web/assets/vue-vine-pWqEcBkW.js +1 -0
  451. package/dist/control-web/assets/vyper-CgoNMtux.js +1 -0
  452. package/dist/control-web/assets/wardley-OPB4EBWU-B9rA0UsV.js +1 -0
  453. package/dist/control-web/assets/wardleyDiagram-EHGQE667-BdvAUa5F.js +78 -0
  454. package/dist/control-web/assets/wasm-BnjxR4X6.js +1 -0
  455. package/dist/control-web/assets/wasm-ByWQv1Qj.js +1 -0
  456. package/dist/control-web/assets/wenyan-C8pVoKbM.js +1 -0
  457. package/dist/control-web/assets/wgsl-BsKzXJz4.js +1 -0
  458. package/dist/control-web/assets/wikitext-ClFFjSW2.js +1 -0
  459. package/dist/control-web/assets/wit-DdvCle-K.js +1 -0
  460. package/dist/control-web/assets/wolfram-DLL8P-h_.js +1 -0
  461. package/dist/control-web/assets/xml-BlnrEAEy.js +1 -0
  462. package/dist/control-web/assets/xsl-BOPS8gLt.js +1 -0
  463. package/dist/control-web/assets/xychartDiagram-FW5EYKEG-BaEV3pGm.js +7 -0
  464. package/dist/control-web/assets/yaml-Du_6cdrH.js +1 -0
  465. package/dist/control-web/assets/zenscript-BnlCZFoB.js +1 -0
  466. package/dist/control-web/assets/zig-CMLA9XwU.js +1 -0
  467. package/dist/control-web/index.html +3 -2
  468. package/dist/control-web-dist.d.ts +1 -1
  469. package/dist/control-web-dist.js +4 -2
  470. package/dist/desktop-browser-host.d.ts +3 -1
  471. package/dist/desktop-browser-host.js +39 -4
  472. package/dist/direct-runtime-server.js +187 -153
  473. package/dist/machine-session-service.d.ts +105 -15
  474. package/dist/machine-session-service.js +781 -87
  475. package/dist/remote-runtime-dispatcher.d.ts +2 -2
  476. package/dist/remote-runtime-dispatcher.js +42 -2
  477. package/dist/remote-runtime-session-projection.d.ts +1 -0
  478. package/dist/remote-runtime-session-projection.js +12 -0
  479. package/dist/server.d.ts +64 -11
  480. package/dist/server.js +422 -55
  481. package/dist/session-browser-service.d.ts +24 -4
  482. package/dist/session-browser-service.js +127 -1
  483. package/dist/session-pending-inputs.d.ts +42 -0
  484. package/dist/session-pending-inputs.js +87 -0
  485. package/dist/session-portal.d.ts +54 -0
  486. package/dist/session-portal.js +997 -0
  487. package/dist/session-runtime-index.d.ts +3 -6
  488. package/dist/session-runtime-index.js +96 -38
  489. package/dist/session-terminal-host.d.ts +22 -2
  490. package/dist/session-terminal-host.js +66 -83
  491. package/dist/terminal-ws.d.ts +4 -1
  492. package/dist/terminal-ws.js +93 -27
  493. package/package.json +7 -7
  494. package/dist/control-web/assets/highlighted-body-OFNGDK62-DWWsUtHF.js +0 -1
  495. package/dist/control-web/assets/index-BnX7NWJX.js +0 -689
  496. package/dist/control-web/assets/index-CUoWRX2i.css +0 -32
  497. 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.pendingResponseIds.delete(event.responseId);
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
- state.pendingResponseIds.delete(event.responseId);
22
+ this.markResponseTerminal(state, event.responseId);
38
23
  state.activeResponseIds.delete(event.responseId);
39
24
  this.removeResponseInteractions(state, event.responseId);
40
- state.status = this.hasRunningTurn(state) ? "running" : "idle";
25
+ state.status = this.statusAfterResponseTerminal(state);
41
26
  state.statusKind = undefined;
42
27
  return;
43
28
  case "response.failed":
44
- state.pendingResponseIds.delete(event.responseId);
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.hasRunningTurn(state) ? "running" : "idle";
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
- state.status =
53
- state.pendingInteractions.size > 0 || this.hasRunningTurn(state)
54
- ? "running"
55
- : event.status;
56
- state.statusKind = event.statusKind;
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.pendingResponseIds.delete(event.responseId);
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
- state.status = this.hasRunningTurn(state) ? "running" : state.status;
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 || this.hasRunningTurn(state)
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
- runningTurns += state.pendingResponseIds.size + state.activeResponseIds.size;
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.pendingResponseIds.size > 0 || state.activeResponseIds.size > 0;
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
- /** One attachment; close detaches this client and never kills the tmux pane. */
16
- export interface SessionTerminalAttachment extends AsyncIterable<Uint8Array> {
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
- queue = [];
111
- queuedBytes = 0;
112
- waiter;
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.onData((chunk) => this.push(Uint8Array.from(Buffer.from(chunk, "utf8"))));
132
- parent.onExit((info) => this.finish({ reason: "terminal_exited", exitCode: info.exitCode }));
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
- opened(role) {
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.openingFailure)
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
- [Symbol.asyncIterator]() {
152
- return this;
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 new Promise((resolve, reject) => {
168
- this.waiter = { resolve, reject };
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
- async return() {
172
- await this.close();
173
- return { done: true, value: undefined };
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.ended || this.currentRole !== "owner" || data.byteLength === 0)
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(Buffer.from(data).toString("utf8"));
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.ended)
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.ended)
204
+ if (this.detached)
187
205
  return;
206
+ this.detached = true;
188
207
  this.parent.close();
189
- this.finish({ reason: "client_closed" }, undefined, true);
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
- finish(info, error, discardQueue = false) {
215
- if (this.ended)
210
+ settleClosed(info) {
211
+ if (this.closeSettled)
216
212
  return;
217
- this.ended = true;
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
  }
@@ -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;
@@ -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 = 16 * 1024;
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 lastClientInputAt = 0;
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(() => applyBrowserInput(opened, input));
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, { t: "opened", role: opened.role });
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
- for await (const output of opened) {
219
- if (browserClosed)
220
- return;
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
- // Defense in depth: tmux -r also blocks writes, but bytes never reach it.
303
- if (terminal.role === "owner")
304
- await terminal.write(input.data);
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
- if (ws.bufferedAmount + data.byteLength > MAX_BROWSER_BUFFERED_BYTES) {
313
- const error = new Error("Browser terminal output exceeded its bounded buffer");
314
- error.name = "BackpressureError";
315
- throw error;
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 });