parasor 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (633) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +208 -0
  3. package/THIRD-PARTY-NOTICES.md +138 -0
  4. package/bin/parasor.mjs +3 -0
  5. package/node_modules/@parasor/shared/dist/client.d.ts +8 -0
  6. package/node_modules/@parasor/shared/dist/client.d.ts.map +1 -0
  7. package/node_modules/@parasor/shared/dist/client.js +2 -0
  8. package/node_modules/@parasor/shared/dist/client.js.map +1 -0
  9. package/node_modules/@parasor/shared/dist/drops.d.ts +24 -0
  10. package/node_modules/@parasor/shared/dist/drops.d.ts.map +1 -0
  11. package/node_modules/@parasor/shared/dist/drops.js +2 -0
  12. package/node_modules/@parasor/shared/dist/drops.js.map +1 -0
  13. package/node_modules/@parasor/shared/dist/file-uploads.d.ts +56 -0
  14. package/node_modules/@parasor/shared/dist/file-uploads.d.ts.map +1 -0
  15. package/node_modules/@parasor/shared/dist/file-uploads.js +13 -0
  16. package/node_modules/@parasor/shared/dist/file-uploads.js.map +1 -0
  17. package/node_modules/@parasor/shared/dist/ide-commands.d.ts +8 -0
  18. package/node_modules/@parasor/shared/dist/ide-commands.d.ts.map +1 -0
  19. package/node_modules/@parasor/shared/dist/ide-commands.js +59 -0
  20. package/node_modules/@parasor/shared/dist/ide-commands.js.map +1 -0
  21. package/node_modules/@parasor/shared/dist/pane-commands.d.ts +7 -0
  22. package/node_modules/@parasor/shared/dist/pane-commands.d.ts.map +1 -0
  23. package/node_modules/@parasor/shared/dist/pane-commands.js +47 -0
  24. package/node_modules/@parasor/shared/dist/pane-commands.js.map +1 -0
  25. package/node_modules/@parasor/shared/dist/pane-model.d.ts +63 -0
  26. package/node_modules/@parasor/shared/dist/pane-model.d.ts.map +1 -0
  27. package/node_modules/@parasor/shared/dist/pane-model.js +89 -0
  28. package/node_modules/@parasor/shared/dist/pane-model.js.map +1 -0
  29. package/node_modules/@parasor/shared/dist/panes.d.ts +33 -0
  30. package/node_modules/@parasor/shared/dist/panes.d.ts.map +1 -0
  31. package/node_modules/@parasor/shared/dist/panes.js +2 -0
  32. package/node_modules/@parasor/shared/dist/panes.js.map +1 -0
  33. package/node_modules/@parasor/shared/dist/runtime.d.ts +180 -0
  34. package/node_modules/@parasor/shared/dist/runtime.d.ts.map +1 -0
  35. package/node_modules/@parasor/shared/dist/runtime.js +2 -0
  36. package/node_modules/@parasor/shared/dist/runtime.js.map +1 -0
  37. package/node_modules/@parasor/shared/dist/state.d.ts +192 -0
  38. package/node_modules/@parasor/shared/dist/state.d.ts.map +1 -0
  39. package/node_modules/@parasor/shared/dist/state.js +10 -0
  40. package/node_modules/@parasor/shared/dist/state.js.map +1 -0
  41. package/node_modules/@parasor/shared/dist/terminal.d.ts +191 -0
  42. package/node_modules/@parasor/shared/dist/terminal.d.ts.map +1 -0
  43. package/node_modules/@parasor/shared/dist/terminal.js +174 -0
  44. package/node_modules/@parasor/shared/dist/terminal.js.map +1 -0
  45. package/node_modules/@parasor/shared/dist/types.d.ts +13 -0
  46. package/node_modules/@parasor/shared/dist/types.d.ts.map +1 -0
  47. package/node_modules/@parasor/shared/dist/types.js +13 -0
  48. package/node_modules/@parasor/shared/dist/types.js.map +1 -0
  49. package/node_modules/@parasor/shared/dist/worktree-local-files.d.ts +14 -0
  50. package/node_modules/@parasor/shared/dist/worktree-local-files.d.ts.map +1 -0
  51. package/node_modules/@parasor/shared/dist/worktree-local-files.js +41 -0
  52. package/node_modules/@parasor/shared/dist/worktree-local-files.js.map +1 -0
  53. package/node_modules/@parasor/shared/dist/ws-events.d.ts +152 -0
  54. package/node_modules/@parasor/shared/dist/ws-events.d.ts.map +1 -0
  55. package/node_modules/@parasor/shared/dist/ws-events.js +2 -0
  56. package/node_modules/@parasor/shared/dist/ws-events.js.map +1 -0
  57. package/node_modules/@parasor/shared/package.json +13 -0
  58. package/package.json +61 -0
  59. package/server/agent-detector/agent-state-store.d.ts +23 -0
  60. package/server/agent-detector/agent-state-store.d.ts.map +1 -0
  61. package/server/agent-detector/agent-state-store.js +110 -0
  62. package/server/agent-detector/agent-state-store.js.map +1 -0
  63. package/server/agent-detector/detector.d.ts +80 -0
  64. package/server/agent-detector/detector.d.ts.map +1 -0
  65. package/server/agent-detector/detector.js +219 -0
  66. package/server/agent-detector/detector.js.map +1 -0
  67. package/server/agent-detector/event-map.d.ts +25 -0
  68. package/server/agent-detector/event-map.d.ts.map +1 -0
  69. package/server/agent-detector/event-map.js +136 -0
  70. package/server/agent-detector/event-map.js.map +1 -0
  71. package/server/agent-detector/manual-agent-tracker.d.ts +19 -0
  72. package/server/agent-detector/manual-agent-tracker.d.ts.map +1 -0
  73. package/server/agent-detector/manual-agent-tracker.js +123 -0
  74. package/server/agent-detector/manual-agent-tracker.js.map +1 -0
  75. package/server/agent-detector/output-eligibility.d.ts +3 -0
  76. package/server/agent-detector/output-eligibility.d.ts.map +1 -0
  77. package/server/agent-detector/output-eligibility.js +39 -0
  78. package/server/agent-detector/output-eligibility.js.map +1 -0
  79. package/server/application/files/errors.d.ts +28 -0
  80. package/server/application/files/errors.d.ts.map +1 -0
  81. package/server/application/files/errors.js +55 -0
  82. package/server/application/files/errors.js.map +1 -0
  83. package/server/application/files/local-filesystem.d.ts +36 -0
  84. package/server/application/files/local-filesystem.d.ts.map +1 -0
  85. package/server/application/files/local-filesystem.js +171 -0
  86. package/server/application/files/local-filesystem.js.map +1 -0
  87. package/server/application/files/project-file-queries.d.ts +16 -0
  88. package/server/application/files/project-file-queries.d.ts.map +1 -0
  89. package/server/application/files/project-file-queries.js +126 -0
  90. package/server/application/files/project-file-queries.js.map +1 -0
  91. package/server/application/integrations/errors.d.ts +16 -0
  92. package/server/application/integrations/errors.d.ts.map +1 -0
  93. package/server/application/integrations/errors.js +31 -0
  94. package/server/application/integrations/errors.js.map +1 -0
  95. package/server/application/integrations/hook-notify.d.ts +32 -0
  96. package/server/application/integrations/hook-notify.d.ts.map +1 -0
  97. package/server/application/integrations/hook-notify.js +118 -0
  98. package/server/application/integrations/hook-notify.js.map +1 -0
  99. package/server/application/integrations/open-url.d.ts +11 -0
  100. package/server/application/integrations/open-url.d.ts.map +1 -0
  101. package/server/application/integrations/open-url.js +23 -0
  102. package/server/application/integrations/open-url.js.map +1 -0
  103. package/server/application/ports.d.ts +11 -0
  104. package/server/application/ports.d.ts.map +1 -0
  105. package/server/application/ports.js +2 -0
  106. package/server/application/ports.js.map +1 -0
  107. package/server/application/workspace/errors.d.ts +21 -0
  108. package/server/application/workspace/errors.d.ts.map +1 -0
  109. package/server/application/workspace/errors.js +21 -0
  110. package/server/application/workspace/errors.js.map +1 -0
  111. package/server/application/workspace/pane-commands.d.ts +47 -0
  112. package/server/application/workspace/pane-commands.d.ts.map +1 -0
  113. package/server/application/workspace/pane-commands.js +193 -0
  114. package/server/application/workspace/pane-commands.js.map +1 -0
  115. package/server/application/workspace/project-commands.d.ts +34 -0
  116. package/server/application/workspace/project-commands.d.ts.map +1 -0
  117. package/server/application/workspace/project-commands.js +81 -0
  118. package/server/application/workspace/project-commands.js.map +1 -0
  119. package/server/application/workspace/project-queries.d.ts +21 -0
  120. package/server/application/workspace/project-queries.d.ts.map +1 -0
  121. package/server/application/workspace/project-queries.js +216 -0
  122. package/server/application/workspace/project-queries.js.map +1 -0
  123. package/server/application/workspace/session-commands.d.ts +24 -0
  124. package/server/application/workspace/session-commands.d.ts.map +1 -0
  125. package/server/application/workspace/session-commands.js +123 -0
  126. package/server/application/workspace/session-commands.js.map +1 -0
  127. package/server/application/workspace/session-queries.d.ts +14 -0
  128. package/server/application/workspace/session-queries.d.ts.map +1 -0
  129. package/server/application/workspace/session-queries.js +47 -0
  130. package/server/application/workspace/session-queries.js.map +1 -0
  131. package/server/application/workspace/worktree-commands.d.ts +98 -0
  132. package/server/application/workspace/worktree-commands.d.ts.map +1 -0
  133. package/server/application/workspace/worktree-commands.js +323 -0
  134. package/server/application/workspace/worktree-commands.js.map +1 -0
  135. package/server/application/workspace/worktree-local-files.d.ts +11 -0
  136. package/server/application/workspace/worktree-local-files.d.ts.map +1 -0
  137. package/server/application/workspace/worktree-local-files.js +223 -0
  138. package/server/application/workspace/worktree-local-files.js.map +1 -0
  139. package/server/application/workspace/worktree-reconcile.d.ts +21 -0
  140. package/server/application/workspace/worktree-reconcile.d.ts.map +1 -0
  141. package/server/application/workspace/worktree-reconcile.js +49 -0
  142. package/server/application/workspace/worktree-reconcile.js.map +1 -0
  143. package/server/auth/origin.d.ts +17 -0
  144. package/server/auth/origin.d.ts.map +1 -0
  145. package/server/auth/origin.js +93 -0
  146. package/server/auth/origin.js.map +1 -0
  147. package/server/auth/pairing-token.d.ts +28 -0
  148. package/server/auth/pairing-token.d.ts.map +1 -0
  149. package/server/auth/pairing-token.js +46 -0
  150. package/server/auth/pairing-token.js.map +1 -0
  151. package/server/auth/token-exchange.d.ts +11 -0
  152. package/server/auth/token-exchange.d.ts.map +1 -0
  153. package/server/auth/token-exchange.js +27 -0
  154. package/server/auth/token-exchange.js.map +1 -0
  155. package/server/auth/token.d.ts +18 -0
  156. package/server/auth/token.d.ts.map +1 -0
  157. package/server/auth/token.js +115 -0
  158. package/server/auth/token.js.map +1 -0
  159. package/server/bootstrap/create-app-server.d.ts +49 -0
  160. package/server/bootstrap/create-app-server.d.ts.map +1 -0
  161. package/server/bootstrap/create-app-server.js +154 -0
  162. package/server/bootstrap/create-app-server.js.map +1 -0
  163. package/server/bootstrap/project-runtime.d.ts +29 -0
  164. package/server/bootstrap/project-runtime.d.ts.map +1 -0
  165. package/server/bootstrap/project-runtime.js +253 -0
  166. package/server/bootstrap/project-runtime.js.map +1 -0
  167. package/server/bootstrap/pty-env.d.ts +3 -0
  168. package/server/bootstrap/pty-env.d.ts.map +1 -0
  169. package/server/bootstrap/pty-env.js +15 -0
  170. package/server/bootstrap/pty-env.js.map +1 -0
  171. package/server/bootstrap/reconcile-state.d.ts +16 -0
  172. package/server/bootstrap/reconcile-state.d.ts.map +1 -0
  173. package/server/bootstrap/reconcile-state.js +73 -0
  174. package/server/bootstrap/reconcile-state.js.map +1 -0
  175. package/server/bootstrap/runtime-loops.d.ts +51 -0
  176. package/server/bootstrap/runtime-loops.d.ts.map +1 -0
  177. package/server/bootstrap/runtime-loops.js +189 -0
  178. package/server/bootstrap/runtime-loops.js.map +1 -0
  179. package/server/bootstrap/runtime-port.d.ts +4 -0
  180. package/server/bootstrap/runtime-port.d.ts.map +1 -0
  181. package/server/bootstrap/runtime-port.js +52 -0
  182. package/server/bootstrap/runtime-port.js.map +1 -0
  183. package/server/bootstrap/safety-gate.d.ts +22 -0
  184. package/server/bootstrap/safety-gate.d.ts.map +1 -0
  185. package/server/bootstrap/safety-gate.js +43 -0
  186. package/server/bootstrap/safety-gate.js.map +1 -0
  187. package/server/bootstrap/shutdown-marker.d.ts +35 -0
  188. package/server/bootstrap/shutdown-marker.d.ts.map +1 -0
  189. package/server/bootstrap/shutdown-marker.js +100 -0
  190. package/server/bootstrap/shutdown-marker.js.map +1 -0
  191. package/server/bootstrap/shutdown-runtime.d.ts +62 -0
  192. package/server/bootstrap/shutdown-runtime.d.ts.map +1 -0
  193. package/server/bootstrap/shutdown-runtime.js +66 -0
  194. package/server/bootstrap/shutdown-runtime.js.map +1 -0
  195. package/server/bootstrap/startup-banner.d.ts +34 -0
  196. package/server/bootstrap/startup-banner.d.ts.map +1 -0
  197. package/server/bootstrap/startup-banner.js +114 -0
  198. package/server/bootstrap/startup-banner.js.map +1 -0
  199. package/server/bootstrap/wire-runtime.d.ts +42 -0
  200. package/server/bootstrap/wire-runtime.d.ts.map +1 -0
  201. package/server/bootstrap/wire-runtime.js +205 -0
  202. package/server/bootstrap/wire-runtime.js.map +1 -0
  203. package/server/cli/help.d.ts +3 -0
  204. package/server/cli/help.d.ts.map +1 -0
  205. package/server/cli/help.js +39 -0
  206. package/server/cli/help.js.map +1 -0
  207. package/server/cli/hook-client.d.ts +12 -0
  208. package/server/cli/hook-client.d.ts.map +1 -0
  209. package/server/cli/hook-client.js +81 -0
  210. package/server/cli/hook-client.js.map +1 -0
  211. package/server/cli/hook.d.ts +3 -0
  212. package/server/cli/hook.d.ts.map +1 -0
  213. package/server/cli/hook.js +152 -0
  214. package/server/cli/hook.js.map +1 -0
  215. package/server/cli/main.d.ts +2 -0
  216. package/server/cli/main.d.ts.map +1 -0
  217. package/server/cli/main.js +133 -0
  218. package/server/cli/main.js.map +1 -0
  219. package/server/cli/notify.d.ts +19 -0
  220. package/server/cli/notify.d.ts.map +1 -0
  221. package/server/cli/notify.js +77 -0
  222. package/server/cli/notify.js.map +1 -0
  223. package/server/cli/open.d.ts +2 -0
  224. package/server/cli/open.d.ts.map +1 -0
  225. package/server/cli/open.js +47 -0
  226. package/server/cli/open.js.map +1 -0
  227. package/server/cli/probe-daemon-version.d.ts +46 -0
  228. package/server/cli/probe-daemon-version.d.ts.map +1 -0
  229. package/server/cli/probe-daemon-version.js +167 -0
  230. package/server/cli/probe-daemon-version.js.map +1 -0
  231. package/server/cli/pty-host.d.ts +36 -0
  232. package/server/cli/pty-host.d.ts.map +1 -0
  233. package/server/cli/pty-host.js +390 -0
  234. package/server/cli/pty-host.js.map +1 -0
  235. package/server/cli/qr.d.ts +2 -0
  236. package/server/cli/qr.d.ts.map +1 -0
  237. package/server/cli/qr.js +70 -0
  238. package/server/cli/qr.js.map +1 -0
  239. package/server/cli/restart-confirm.d.ts +33 -0
  240. package/server/cli/restart-confirm.d.ts.map +1 -0
  241. package/server/cli/restart-confirm.js +107 -0
  242. package/server/cli/restart-confirm.js.map +1 -0
  243. package/server/cli/restart.d.ts +17 -0
  244. package/server/cli/restart.d.ts.map +1 -0
  245. package/server/cli/restart.js +145 -0
  246. package/server/cli/restart.js.map +1 -0
  247. package/server/cli/service-darwin.d.ts +70 -0
  248. package/server/cli/service-darwin.d.ts.map +1 -0
  249. package/server/cli/service-darwin.js +562 -0
  250. package/server/cli/service-darwin.js.map +1 -0
  251. package/server/cli/service-linux.d.ts +81 -0
  252. package/server/cli/service-linux.d.ts.map +1 -0
  253. package/server/cli/service-linux.js +412 -0
  254. package/server/cli/service-linux.js.map +1 -0
  255. package/server/cli/service.d.ts +33 -0
  256. package/server/cli/service.d.ts.map +1 -0
  257. package/server/cli/service.js +133 -0
  258. package/server/cli/service.js.map +1 -0
  259. package/server/cli/shim-installer.d.ts +35 -0
  260. package/server/cli/shim-installer.d.ts.map +1 -0
  261. package/server/cli/shim-installer.js +662 -0
  262. package/server/cli/shim-installer.js.map +1 -0
  263. package/server/cli/shim-open.d.ts +2 -0
  264. package/server/cli/shim-open.d.ts.map +1 -0
  265. package/server/cli/shim-open.js +128 -0
  266. package/server/cli/shim-open.js.map +1 -0
  267. package/server/cli/shutdown-deps.d.ts +41 -0
  268. package/server/cli/shutdown-deps.d.ts.map +1 -0
  269. package/server/cli/shutdown-deps.js +158 -0
  270. package/server/cli/shutdown-deps.js.map +1 -0
  271. package/server/cli/stop.d.ts +11 -0
  272. package/server/cli/stop.d.ts.map +1 -0
  273. package/server/cli/stop.js +123 -0
  274. package/server/cli/stop.js.map +1 -0
  275. package/server/cli/unknown-command.d.ts +8 -0
  276. package/server/cli/unknown-command.d.ts.map +1 -0
  277. package/server/cli/unknown-command.js +14 -0
  278. package/server/cli/unknown-command.js.map +1 -0
  279. package/server/debug/agent-status-recorder.d.ts +57 -0
  280. package/server/debug/agent-status-recorder.d.ts.map +1 -0
  281. package/server/debug/agent-status-recorder.js +209 -0
  282. package/server/debug/agent-status-recorder.js.map +1 -0
  283. package/server/debug/terminal-trace-recorder.d.ts +41 -0
  284. package/server/debug/terminal-trace-recorder.d.ts.map +1 -0
  285. package/server/debug/terminal-trace-recorder.js +112 -0
  286. package/server/debug/terminal-trace-recorder.js.map +1 -0
  287. package/server/fonts/catalog.d.ts +35 -0
  288. package/server/fonts/catalog.d.ts.map +1 -0
  289. package/server/fonts/catalog.js +76 -0
  290. package/server/fonts/catalog.js.map +1 -0
  291. package/server/fonts/installer.d.ts +45 -0
  292. package/server/fonts/installer.d.ts.map +1 -0
  293. package/server/fonts/installer.js +201 -0
  294. package/server/fonts/installer.js.map +1 -0
  295. package/server/fonts/routes.d.ts +4 -0
  296. package/server/fonts/routes.d.ts.map +1 -0
  297. package/server/fonts/routes.js +91 -0
  298. package/server/fonts/routes.js.map +1 -0
  299. package/server/fs/drops.d.ts +50 -0
  300. package/server/fs/drops.d.ts.map +1 -0
  301. package/server/fs/drops.js +137 -0
  302. package/server/fs/drops.js.map +1 -0
  303. package/server/fs/file-uploads.d.ts +57 -0
  304. package/server/fs/file-uploads.d.ts.map +1 -0
  305. package/server/fs/file-uploads.js +214 -0
  306. package/server/fs/file-uploads.js.map +1 -0
  307. package/server/fs/file-watcher.d.ts +22 -0
  308. package/server/fs/file-watcher.d.ts.map +1 -0
  309. package/server/fs/file-watcher.js +105 -0
  310. package/server/fs/file-watcher.js.map +1 -0
  311. package/server/fs/git-watcher.d.ts +76 -0
  312. package/server/fs/git-watcher.d.ts.map +1 -0
  313. package/server/fs/git-watcher.js +356 -0
  314. package/server/fs/git-watcher.js.map +1 -0
  315. package/server/fs/media.d.ts +35 -0
  316. package/server/fs/media.d.ts.map +1 -0
  317. package/server/fs/media.js +271 -0
  318. package/server/fs/media.js.map +1 -0
  319. package/server/fs/service.d.ts +97 -0
  320. package/server/fs/service.d.ts.map +1 -0
  321. package/server/fs/service.js +306 -0
  322. package/server/fs/service.js.map +1 -0
  323. package/server/fs/upload-staging.d.ts +76 -0
  324. package/server/fs/upload-staging.d.ts.map +1 -0
  325. package/server/fs/upload-staging.js +283 -0
  326. package/server/fs/upload-staging.js.map +1 -0
  327. package/server/fs/watcher-lifecycle.d.ts +24 -0
  328. package/server/fs/watcher-lifecycle.d.ts.map +1 -0
  329. package/server/fs/watcher-lifecycle.js +105 -0
  330. package/server/fs/watcher-lifecycle.js.map +1 -0
  331. package/server/index.d.ts +17 -0
  332. package/server/index.d.ts.map +1 -0
  333. package/server/index.js +510 -0
  334. package/server/index.js.map +1 -0
  335. package/server/ipc/socket-server.d.ts +28 -0
  336. package/server/ipc/socket-server.d.ts.map +1 -0
  337. package/server/ipc/socket-server.js +206 -0
  338. package/server/ipc/socket-server.js.map +1 -0
  339. package/server/lib/git-exec.d.ts +38 -0
  340. package/server/lib/git-exec.d.ts.map +1 -0
  341. package/server/lib/git-exec.js +96 -0
  342. package/server/lib/git-exec.js.map +1 -0
  343. package/server/lib/open-in-ide.d.ts +22 -0
  344. package/server/lib/open-in-ide.d.ts.map +1 -0
  345. package/server/lib/open-in-ide.js +90 -0
  346. package/server/lib/open-in-ide.js.map +1 -0
  347. package/server/lib/open-in-os.d.ts +20 -0
  348. package/server/lib/open-in-os.d.ts.map +1 -0
  349. package/server/lib/open-in-os.js +51 -0
  350. package/server/lib/open-in-os.js.map +1 -0
  351. package/server/lib/path.d.ts +2 -0
  352. package/server/lib/path.d.ts.map +1 -0
  353. package/server/lib/path.js +10 -0
  354. package/server/lib/path.js.map +1 -0
  355. package/server/lib/promise-mutex.d.ts +7 -0
  356. package/server/lib/promise-mutex.d.ts.map +1 -0
  357. package/server/lib/promise-mutex.js +26 -0
  358. package/server/lib/promise-mutex.js.map +1 -0
  359. package/server/lib/sd-notify.d.ts +8 -0
  360. package/server/lib/sd-notify.d.ts.map +1 -0
  361. package/server/lib/sd-notify.js +27 -0
  362. package/server/lib/sd-notify.js.map +1 -0
  363. package/server/net/local-machine.d.ts +7 -0
  364. package/server/net/local-machine.d.ts.map +1 -0
  365. package/server/net/local-machine.js +79 -0
  366. package/server/net/local-machine.js.map +1 -0
  367. package/server/net/reachable-host.d.ts +12 -0
  368. package/server/net/reachable-host.d.ts.map +1 -0
  369. package/server/net/reachable-host.js +25 -0
  370. package/server/net/reachable-host.js.map +1 -0
  371. package/server/network/endpoints.d.ts +14 -0
  372. package/server/network/endpoints.d.ts.map +1 -0
  373. package/server/network/endpoints.js +104 -0
  374. package/server/network/endpoints.js.map +1 -0
  375. package/server/network/qr.d.ts +16 -0
  376. package/server/network/qr.d.ts.map +1 -0
  377. package/server/network/qr.js +89 -0
  378. package/server/network/qr.js.map +1 -0
  379. package/server/port-forwarder/forwarder.d.ts +47 -0
  380. package/server/port-forwarder/forwarder.d.ts.map +1 -0
  381. package/server/port-forwarder/forwarder.js +159 -0
  382. package/server/port-forwarder/forwarder.js.map +1 -0
  383. package/server/port-scanner/scanner.d.ts +24 -0
  384. package/server/port-scanner/scanner.d.ts.map +1 -0
  385. package/server/port-scanner/scanner.js +193 -0
  386. package/server/port-scanner/scanner.js.map +1 -0
  387. package/server/pty/connection-lifecycle.d.ts +50 -0
  388. package/server/pty/connection-lifecycle.d.ts.map +1 -0
  389. package/server/pty/connection-lifecycle.js +113 -0
  390. package/server/pty/connection-lifecycle.js.map +1 -0
  391. package/server/pty/daemon-connect.d.ts +52 -0
  392. package/server/pty/daemon-connect.d.ts.map +1 -0
  393. package/server/pty/daemon-connect.js +62 -0
  394. package/server/pty/daemon-connect.js.map +1 -0
  395. package/server/pty/handshake-timeout-race.d.ts +22 -0
  396. package/server/pty/handshake-timeout-race.d.ts.map +1 -0
  397. package/server/pty/handshake-timeout-race.js +23 -0
  398. package/server/pty/handshake-timeout-race.js.map +1 -0
  399. package/server/pty/headless-replay-snapshot.d.ts +28 -0
  400. package/server/pty/headless-replay-snapshot.d.ts.map +1 -0
  401. package/server/pty/headless-replay-snapshot.js +285 -0
  402. package/server/pty/headless-replay-snapshot.js.map +1 -0
  403. package/server/pty/headless-terminal-state-cache.d.ts +31 -0
  404. package/server/pty/headless-terminal-state-cache.d.ts.map +1 -0
  405. package/server/pty/headless-terminal-state-cache.js +119 -0
  406. package/server/pty/headless-terminal-state-cache.js.map +1 -0
  407. package/server/pty/hello-ack-validator.d.ts +15 -0
  408. package/server/pty/hello-ack-validator.d.ts.map +1 -0
  409. package/server/pty/hello-ack-validator.js +30 -0
  410. package/server/pty/hello-ack-validator.js.map +1 -0
  411. package/server/pty/host-daemon/bootstrap.d.ts +100 -0
  412. package/server/pty/host-daemon/bootstrap.d.ts.map +1 -0
  413. package/server/pty/host-daemon/bootstrap.js +611 -0
  414. package/server/pty/host-daemon/bootstrap.js.map +1 -0
  415. package/server/pty/host-daemon/daemon.d.ts +111 -0
  416. package/server/pty/host-daemon/daemon.d.ts.map +1 -0
  417. package/server/pty/host-daemon/daemon.js +648 -0
  418. package/server/pty/host-daemon/daemon.js.map +1 -0
  419. package/server/pty/host-daemon/entry.d.ts +3 -0
  420. package/server/pty/host-daemon/entry.d.ts.map +1 -0
  421. package/server/pty/host-daemon/entry.js +72 -0
  422. package/server/pty/host-daemon/entry.js.map +1 -0
  423. package/server/pty/host-daemon/lockfile.d.ts +12 -0
  424. package/server/pty/host-daemon/lockfile.d.ts.map +1 -0
  425. package/server/pty/host-daemon/lockfile.js +120 -0
  426. package/server/pty/host-daemon/lockfile.js.map +1 -0
  427. package/server/pty/host-daemon/mode-marker.d.ts +77 -0
  428. package/server/pty/host-daemon/mode-marker.d.ts.map +1 -0
  429. package/server/pty/host-daemon/mode-marker.js +228 -0
  430. package/server/pty/host-daemon/mode-marker.js.map +1 -0
  431. package/server/pty/host-daemon/orphan-cleanup.d.ts +42 -0
  432. package/server/pty/host-daemon/orphan-cleanup.d.ts.map +1 -0
  433. package/server/pty/host-daemon/orphan-cleanup.js +84 -0
  434. package/server/pty/host-daemon/orphan-cleanup.js.map +1 -0
  435. package/server/pty/host-daemon/paths.d.ts +10 -0
  436. package/server/pty/host-daemon/paths.d.ts.map +1 -0
  437. package/server/pty/host-daemon/paths.js +56 -0
  438. package/server/pty/host-daemon/paths.js.map +1 -0
  439. package/server/pty/host-daemon/server-connection.d.ts +44 -0
  440. package/server/pty/host-daemon/server-connection.d.ts.map +1 -0
  441. package/server/pty/host-daemon/server-connection.js +100 -0
  442. package/server/pty/host-daemon/server-connection.js.map +1 -0
  443. package/server/pty/host-daemon/service-detection.d.ts +24 -0
  444. package/server/pty/host-daemon/service-detection.d.ts.map +1 -0
  445. package/server/pty/host-daemon/service-detection.js +16 -0
  446. package/server/pty/host-daemon/service-detection.js.map +1 -0
  447. package/server/pty/host-daemon/socket-ready.d.ts +22 -0
  448. package/server/pty/host-daemon/socket-ready.d.ts.map +1 -0
  449. package/server/pty/host-daemon/socket-ready.js +33 -0
  450. package/server/pty/host-daemon/socket-ready.js.map +1 -0
  451. package/server/pty/host-daemon/spawn-daemon.d.ts +45 -0
  452. package/server/pty/host-daemon/spawn-daemon.d.ts.map +1 -0
  453. package/server/pty/host-daemon/spawn-daemon.js +155 -0
  454. package/server/pty/host-daemon/spawn-daemon.js.map +1 -0
  455. package/server/pty/host-daemon/terminate-daemon.d.ts +16 -0
  456. package/server/pty/host-daemon/terminate-daemon.d.ts.map +1 -0
  457. package/server/pty/host-daemon/terminate-daemon.js +128 -0
  458. package/server/pty/host-daemon/terminate-daemon.js.map +1 -0
  459. package/server/pty/host-protocol/frames.d.ts +110 -0
  460. package/server/pty/host-protocol/frames.d.ts.map +1 -0
  461. package/server/pty/host-protocol/frames.js +255 -0
  462. package/server/pty/host-protocol/frames.js.map +1 -0
  463. package/server/pty/host-protocol/messages.d.ts +140 -0
  464. package/server/pty/host-protocol/messages.d.ts.map +1 -0
  465. package/server/pty/host-protocol/messages.js +117 -0
  466. package/server/pty/host-protocol/messages.js.map +1 -0
  467. package/server/pty/host.d.ts +273 -0
  468. package/server/pty/host.d.ts.map +1 -0
  469. package/server/pty/host.js +184 -0
  470. package/server/pty/host.js.map +1 -0
  471. package/server/pty/in-process-host.d.ts +224 -0
  472. package/server/pty/in-process-host.d.ts.map +1 -0
  473. package/server/pty/in-process-host.js +1183 -0
  474. package/server/pty/in-process-host.js.map +1 -0
  475. package/server/pty/osc7-lifecycle.d.ts +8 -0
  476. package/server/pty/osc7-lifecycle.d.ts.map +1 -0
  477. package/server/pty/osc7-lifecycle.js +22 -0
  478. package/server/pty/osc7-lifecycle.js.map +1 -0
  479. package/server/pty/osc7-parser.d.ts +23 -0
  480. package/server/pty/osc7-parser.d.ts.map +1 -0
  481. package/server/pty/osc7-parser.js +91 -0
  482. package/server/pty/osc7-parser.js.map +1 -0
  483. package/server/pty/remote-host.d.ts +188 -0
  484. package/server/pty/remote-host.d.ts.map +1 -0
  485. package/server/pty/remote-host.js +810 -0
  486. package/server/pty/remote-host.js.map +1 -0
  487. package/server/pty/request-correlator.d.ts +59 -0
  488. package/server/pty/request-correlator.d.ts.map +1 -0
  489. package/server/pty/request-correlator.js +75 -0
  490. package/server/pty/request-correlator.js.map +1 -0
  491. package/server/pty/scrollback-log.d.ts +130 -0
  492. package/server/pty/scrollback-log.d.ts.map +1 -0
  493. package/server/pty/scrollback-log.js +344 -0
  494. package/server/pty/scrollback-log.js.map +1 -0
  495. package/server/pty/scrollback-sanitize.d.ts +2 -0
  496. package/server/pty/scrollback-sanitize.d.ts.map +1 -0
  497. package/server/pty/scrollback-sanitize.js +54 -0
  498. package/server/pty/scrollback-sanitize.js.map +1 -0
  499. package/server/pty/session-mirror.d.ts +67 -0
  500. package/server/pty/session-mirror.d.ts.map +1 -0
  501. package/server/pty/session-mirror.js +112 -0
  502. package/server/pty/session-mirror.js.map +1 -0
  503. package/server/pty/session-policy.d.ts +85 -0
  504. package/server/pty/session-policy.d.ts.map +1 -0
  505. package/server/pty/session-policy.js +186 -0
  506. package/server/pty/session-policy.js.map +1 -0
  507. package/server/pty/version-mismatch-recovery.d.ts +71 -0
  508. package/server/pty/version-mismatch-recovery.d.ts.map +1 -0
  509. package/server/pty/version-mismatch-recovery.js +63 -0
  510. package/server/pty/version-mismatch-recovery.js.map +1 -0
  511. package/server/routes/debug-agent-status.d.ts +5 -0
  512. package/server/routes/debug-agent-status.d.ts.map +1 -0
  513. package/server/routes/debug-agent-status.js +22 -0
  514. package/server/routes/debug-agent-status.js.map +1 -0
  515. package/server/routes/debug-diagnostics.d.ts +8 -0
  516. package/server/routes/debug-diagnostics.d.ts.map +1 -0
  517. package/server/routes/debug-diagnostics.js +34 -0
  518. package/server/routes/debug-diagnostics.js.map +1 -0
  519. package/server/routes/debug-terminal-trace.d.ts +16 -0
  520. package/server/routes/debug-terminal-trace.d.ts.map +1 -0
  521. package/server/routes/debug-terminal-trace.js +545 -0
  522. package/server/routes/debug-terminal-trace.js.map +1 -0
  523. package/server/routes/drops.d.ts +13 -0
  524. package/server/routes/drops.d.ts.map +1 -0
  525. package/server/routes/drops.js +126 -0
  526. package/server/routes/drops.js.map +1 -0
  527. package/server/routes/file-uploads.d.ts +9 -0
  528. package/server/routes/file-uploads.d.ts.map +1 -0
  529. package/server/routes/file-uploads.js +119 -0
  530. package/server/routes/file-uploads.js.map +1 -0
  531. package/server/routes/files.d.ts +9 -0
  532. package/server/routes/files.d.ts.map +1 -0
  533. package/server/routes/files.js +441 -0
  534. package/server/routes/files.js.map +1 -0
  535. package/server/routes/filesystem.d.ts +6 -0
  536. package/server/routes/filesystem.d.ts.map +1 -0
  537. package/server/routes/filesystem.js +76 -0
  538. package/server/routes/filesystem.js.map +1 -0
  539. package/server/routes/git.d.ts +38 -0
  540. package/server/routes/git.d.ts.map +1 -0
  541. package/server/routes/git.js +585 -0
  542. package/server/routes/git.js.map +1 -0
  543. package/server/routes/healthz.d.ts +8 -0
  544. package/server/routes/healthz.d.ts.map +1 -0
  545. package/server/routes/healthz.js +24 -0
  546. package/server/routes/healthz.js.map +1 -0
  547. package/server/routes/hook.d.ts +14 -0
  548. package/server/routes/hook.d.ts.map +1 -0
  549. package/server/routes/hook.js +86 -0
  550. package/server/routes/hook.js.map +1 -0
  551. package/server/routes/ide-commands.d.ts +9 -0
  552. package/server/routes/ide-commands.d.ts.map +1 -0
  553. package/server/routes/ide-commands.js +23 -0
  554. package/server/routes/ide-commands.js.map +1 -0
  555. package/server/routes/lib/resolve-worktree.d.ts +30 -0
  556. package/server/routes/lib/resolve-worktree.d.ts.map +1 -0
  557. package/server/routes/lib/resolve-worktree.js +35 -0
  558. package/server/routes/lib/resolve-worktree.js.map +1 -0
  559. package/server/routes/open.d.ts +4 -0
  560. package/server/routes/open.d.ts.map +1 -0
  561. package/server/routes/open.js +21 -0
  562. package/server/routes/open.js.map +1 -0
  563. package/server/routes/pane-commands.d.ts +9 -0
  564. package/server/routes/pane-commands.d.ts.map +1 -0
  565. package/server/routes/pane-commands.js +23 -0
  566. package/server/routes/pane-commands.js.map +1 -0
  567. package/server/routes/projects.d.ts +15 -0
  568. package/server/routes/projects.d.ts.map +1 -0
  569. package/server/routes/projects.js +363 -0
  570. package/server/routes/projects.js.map +1 -0
  571. package/server/routes/server-notices.d.ts +4 -0
  572. package/server/routes/server-notices.d.ts.map +1 -0
  573. package/server/routes/server-notices.js +29 -0
  574. package/server/routes/server-notices.js.map +1 -0
  575. package/server/routes/service-config.d.ts +11 -0
  576. package/server/routes/service-config.d.ts.map +1 -0
  577. package/server/routes/service-config.js +64 -0
  578. package/server/routes/service-config.js.map +1 -0
  579. package/server/routes/sessions.d.ts +7 -0
  580. package/server/routes/sessions.d.ts.map +1 -0
  581. package/server/routes/sessions.js +218 -0
  582. package/server/routes/sessions.js.map +1 -0
  583. package/server/service/caffeinate.d.ts +33 -0
  584. package/server/service/caffeinate.d.ts.map +1 -0
  585. package/server/service/caffeinate.js +72 -0
  586. package/server/service/caffeinate.js.map +1 -0
  587. package/server/state/app-state.d.ts +167 -0
  588. package/server/state/app-state.d.ts.map +1 -0
  589. package/server/state/app-state.js +335 -0
  590. package/server/state/app-state.js.map +1 -0
  591. package/server/state/project-manager.d.ts +30 -0
  592. package/server/state/project-manager.d.ts.map +1 -0
  593. package/server/state/project-manager.js +128 -0
  594. package/server/state/project-manager.js.map +1 -0
  595. package/server/state/server-notices.d.ts +12 -0
  596. package/server/state/server-notices.d.ts.map +1 -0
  597. package/server/state/server-notices.js +32 -0
  598. package/server/state/server-notices.js.map +1 -0
  599. package/server/state/worktree-cache.d.ts +25 -0
  600. package/server/state/worktree-cache.d.ts.map +1 -0
  601. package/server/state/worktree-cache.js +53 -0
  602. package/server/state/worktree-cache.js.map +1 -0
  603. package/server/ws/events.d.ts +45 -0
  604. package/server/ws/events.d.ts.map +1 -0
  605. package/server/ws/events.js +134 -0
  606. package/server/ws/events.js.map +1 -0
  607. package/server/ws/keepalive.d.ts +27 -0
  608. package/server/ws/keepalive.d.ts.map +1 -0
  609. package/server/ws/keepalive.js +63 -0
  610. package/server/ws/keepalive.js.map +1 -0
  611. package/server/ws/terminal-attach.d.ts +13 -0
  612. package/server/ws/terminal-attach.d.ts.map +1 -0
  613. package/server/ws/terminal-attach.js +233 -0
  614. package/server/ws/terminal-attach.js.map +1 -0
  615. package/server/ws/terminal-flow.d.ts +17 -0
  616. package/server/ws/terminal-flow.d.ts.map +1 -0
  617. package/server/ws/terminal-flow.js +64 -0
  618. package/server/ws/terminal-flow.js.map +1 -0
  619. package/server/ws/terminal.d.ts +69 -0
  620. package/server/ws/terminal.d.ts.map +1 -0
  621. package/server/ws/terminal.js +311 -0
  622. package/server/ws/terminal.js.map +1 -0
  623. package/web/assets/EditorPane-CzzT3iYY.js +123 -0
  624. package/web/assets/SymbolsNerdFontMono-Regular-CwEZqMeU.woff2 +0 -0
  625. package/web/assets/TerminalPane-CjbYzePr.js +68 -0
  626. package/web/assets/TerminalPane-DkTCHfhq.css +1 -0
  627. package/web/assets/file-icons-JBi09j0r.js +6 -0
  628. package/web/assets/index-CTTkRpnn.css +2 -0
  629. package/web/assets/index-CmhewzMp.js +34 -0
  630. package/web/assets/session-resume-7f-tB-ZU.js +2 -0
  631. package/web/assets/terminal-trace-PuuFRybC.js +2803 -0
  632. package/web/assets/useVirtualKeyboard-DgJb9u9d.js +1 -0
  633. package/web/index.html +52 -0
@@ -0,0 +1,45 @@
1
+ import { type AgentState, type AppState, type GitState, type Notification, type PortInfo, type Worktree, type WsEventMessage } from "@parasor/shared";
2
+ import type { WSContext } from "hono/ws";
3
+ export interface HydrationSources {
4
+ getState: () => Readonly<AppState>;
5
+ getAgentStates: () => Record<string, AgentState>;
6
+ getNotifications: () => Notification[];
7
+ getPorts: () => Record<string, PortInfo[]>;
8
+ getGitStates: () => Record<string, Record<string, GitState | null>>;
9
+ /**
10
+ * Per-project worktree snapshot. Sync because it reads from a
11
+ * runtime-maintained `WorktreeCache` -- see `wireRuntime`. Keeping
12
+ * this synchronous lets `addClient` capture seq + state + worktrees
13
+ * atomically in one tick, avoiding the broadcast/snapshot race that
14
+ * would otherwise leak events to a connecting client.
15
+ */
16
+ getWorktrees: () => Record<string, Worktree[]>;
17
+ }
18
+ export type ClientCountListener = (count: number) => void;
19
+ export declare class EventBus {
20
+ private clients;
21
+ private seq;
22
+ private lock;
23
+ private sources;
24
+ private notifications;
25
+ private clientCountListeners;
26
+ setHydrationSources(sources: HydrationSources): void;
27
+ addNotification(n: Notification): void;
28
+ getNotifications(): Notification[];
29
+ getClientCount(): number;
30
+ onClientCountChanged(listener: ClientCountListener): () => void;
31
+ addClient(ws: WSContext): Promise<void>;
32
+ removeClient(ws: WSContext): void;
33
+ private emitClientCount;
34
+ broadcast(message: WsEventMessage): void;
35
+ }
36
+ /**
37
+ * Handle a single client->server frame on `/ws/events`. The browser
38
+ * cannot issue WS-protocol pings from JS, so we offer an app-layer
39
+ * ping that detects silent-dead TCP paths (NAT idle timeout, mobile
40
+ * background freeze) where neither side observes a close. Echoes
41
+ * `pong` with the same `ts`. Unknown / malformed frames are ignored
42
+ * -- forward-compat for future client->server messages.
43
+ */
44
+ export declare function handleEventClientMessage(ws: Pick<WSContext, "send">, raw: unknown): void;
45
+ //# sourceMappingURL=events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/ws/events.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,UAAU,EACf,KAAK,QAAQ,EAGb,KAAK,QAAQ,EAEb,KAAK,YAAY,EACjB,KAAK,QAAQ,EACb,KAAK,QAAQ,EAEb,KAAK,cAAc,EACpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAGzC,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACnC,cAAc,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACjD,gBAAgB,EAAE,MAAM,YAAY,EAAE,CAAC;IACvC,QAAQ,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC3C,YAAY,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC;IACpE;;;;;;OAMG;IACH,YAAY,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;CAChD;AAED,MAAM,MAAM,mBAAmB,GAAG,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;AAM1D,qBAAa,QAAQ;IACnB,OAAO,CAAC,OAAO,CAAwB;IACvC,OAAO,CAAC,GAAG,CAAK;IAChB,OAAO,CAAC,IAAI,CAAsB;IAClC,OAAO,CAAC,OAAO,CAAiC;IAChD,OAAO,CAAC,aAAa,CAAsB;IAC3C,OAAO,CAAC,oBAAoB,CAAkC;IAE9D,mBAAmB,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI;IAIpD,eAAe,CAAC,CAAC,EAAE,YAAY,GAAG,IAAI;IAMtC,gBAAgB,IAAI,YAAY,EAAE;IAIlC,cAAc,IAAI,MAAM;IAIxB,oBAAoB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,MAAM,IAAI;IAOzD,SAAS,CAAC,EAAE,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IA8C7C,YAAY,CAAC,EAAE,EAAE,SAAS,GAAG,IAAI;IAKjC,OAAO,CAAC,eAAe;IAOvB,SAAS,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;CAiBzC;AAED;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CACtC,EAAE,EAAE,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,EAC3B,GAAG,EAAE,OAAO,GACX,IAAI,CAiBN"}
@@ -0,0 +1,134 @@
1
+ import { DEFAULT_DROP_SIZE_HARD_MAX_BYTES, DEFAULT_DROP_SIZE_MAX_BYTES, } from "@parasor/shared";
2
+ import { PromiseMutex } from "../lib/promise-mutex.js";
3
+ // Cap retained notifications so a long-running daemon does not grow the
4
+ // hydration payload without bound (every reconnect ships the full list).
5
+ const NOTIFICATION_RETENTION_LIMIT = 200;
6
+ export class EventBus {
7
+ clients = new Set();
8
+ seq = 0;
9
+ lock = new PromiseMutex();
10
+ sources = null;
11
+ notifications = [];
12
+ clientCountListeners = new Set();
13
+ setHydrationSources(sources) {
14
+ this.sources = sources;
15
+ }
16
+ addNotification(n) {
17
+ this.notifications.push(n);
18
+ const overflow = this.notifications.length - NOTIFICATION_RETENTION_LIMIT;
19
+ if (overflow > 0)
20
+ this.notifications.splice(0, overflow);
21
+ }
22
+ getNotifications() {
23
+ return this.notifications;
24
+ }
25
+ getClientCount() {
26
+ return this.clients.size;
27
+ }
28
+ onClientCountChanged(listener) {
29
+ this.clientCountListeners.add(listener);
30
+ return () => {
31
+ this.clientCountListeners.delete(listener);
32
+ };
33
+ }
34
+ async addClient(ws) {
35
+ const release = await this.lock.acquire();
36
+ const snapshotSeq = this.seq;
37
+ const payload = this.sources
38
+ ? {
39
+ seq: snapshotSeq,
40
+ state: structuredClone(this.sources.getState()),
41
+ agentStates: this.sources.getAgentStates(),
42
+ notifications: this.sources.getNotifications(),
43
+ ports: this.sources.getPorts(),
44
+ gitStates: this.sources.getGitStates(),
45
+ worktrees: this.sources.getWorktrees(),
46
+ hostPlatform: process.platform,
47
+ }
48
+ : {
49
+ seq: snapshotSeq,
50
+ state: {
51
+ version: 1,
52
+ projects: [],
53
+ projectStates: {},
54
+ sessions: [],
55
+ sessionRecords: [],
56
+ ideCommands: [],
57
+ paneCommands: [],
58
+ serviceConfig: {
59
+ preventIdleSleep: false,
60
+ portDetection: "all-interfaces",
61
+ dropSizeMaxBytes: DEFAULT_DROP_SIZE_MAX_BYTES,
62
+ dropSizeHardMaxBytes: DEFAULT_DROP_SIZE_HARD_MAX_BYTES,
63
+ },
64
+ },
65
+ agentStates: {},
66
+ notifications: [],
67
+ ports: {},
68
+ gitStates: {},
69
+ worktrees: {},
70
+ hostPlatform: process.platform,
71
+ };
72
+ this.clients.add(ws);
73
+ ws.send(JSON.stringify({ type: "app-state-snapshot", payload }));
74
+ release();
75
+ this.emitClientCount();
76
+ }
77
+ removeClient(ws) {
78
+ const had = this.clients.delete(ws);
79
+ if (had)
80
+ this.emitClientCount();
81
+ }
82
+ emitClientCount() {
83
+ const count = this.clients.size;
84
+ for (const listener of this.clientCountListeners) {
85
+ listener(count);
86
+ }
87
+ }
88
+ broadcast(message) {
89
+ this.seq++;
90
+ const envelope = { seq: this.seq, message };
91
+ const data = JSON.stringify(envelope);
92
+ let dropped = false;
93
+ for (const client of this.clients) {
94
+ if (client.readyState === 1) {
95
+ try {
96
+ client.send(data);
97
+ }
98
+ catch {
99
+ this.clients.delete(client);
100
+ dropped = true;
101
+ }
102
+ }
103
+ }
104
+ if (dropped)
105
+ this.emitClientCount();
106
+ }
107
+ }
108
+ /**
109
+ * Handle a single client->server frame on `/ws/events`. The browser
110
+ * cannot issue WS-protocol pings from JS, so we offer an app-layer
111
+ * ping that detects silent-dead TCP paths (NAT idle timeout, mobile
112
+ * background freeze) where neither side observes a close. Echoes
113
+ * `pong` with the same `ts`. Unknown / malformed frames are ignored
114
+ * -- forward-compat for future client->server messages.
115
+ */
116
+ export function handleEventClientMessage(ws, raw) {
117
+ if (typeof raw !== "string")
118
+ return;
119
+ let parsed;
120
+ try {
121
+ parsed = JSON.parse(raw);
122
+ }
123
+ catch {
124
+ return;
125
+ }
126
+ if (parsed === null ||
127
+ typeof parsed !== "object" ||
128
+ parsed.type !== "ping" ||
129
+ !Number.isFinite(parsed.ts)) {
130
+ return;
131
+ }
132
+ ws.send(JSON.stringify({ type: "pong", ts: parsed.ts }));
133
+ }
134
+ //# sourceMappingURL=events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/ws/events.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Minimal shape of the `ws` package WebSocket we rely on. Declared locally so
3
+ * the server package does not need a direct dependency on `ws` (it arrives
4
+ * transitively through @hono/node-ws).
5
+ */
6
+ export interface KeepaliveSocket {
7
+ readyState: number;
8
+ readonly OPEN: number;
9
+ ping(): void;
10
+ terminate(): void;
11
+ on(event: "pong", listener: () => void): void;
12
+ off(event: "pong", listener: () => void): void;
13
+ }
14
+ export interface KeepaliveOptions {
15
+ pingIntervalMs: number;
16
+ pongTimeoutMs: number;
17
+ onTimeout?: () => void;
18
+ }
19
+ /**
20
+ * Attach ping/pong keepalive to a ws WebSocket. Mobile carriers, corporate
21
+ * proxies, and Tailscale can silently drop idle TCP connections; without a
22
+ * keepalive the client thinks the socket is healthy while the server sees
23
+ * nothing. The interval ping forces a half-open state to surface, and the
24
+ * pong deadline tears the connection down so the client reconnects.
25
+ */
26
+ export declare function attachKeepalive(raw: KeepaliveSocket, options: KeepaliveOptions): () => void;
27
+ //# sourceMappingURL=keepalive.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keepalive.d.ts","sourceRoot":"","sources":["../../src/ws/keepalive.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,IAAI,IAAI,IAAI,CAAC;IACb,SAAS,IAAI,IAAI,CAAC;IAClB,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IAC9C,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;CAChD;AAED,MAAM,WAAW,gBAAgB;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;CACxB;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,eAAe,EACpB,OAAO,EAAE,gBAAgB,GACxB,MAAM,IAAI,CAmDZ"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Attach ping/pong keepalive to a ws WebSocket. Mobile carriers, corporate
3
+ * proxies, and Tailscale can silently drop idle TCP connections; without a
4
+ * keepalive the client thinks the socket is healthy while the server sees
5
+ * nothing. The interval ping forces a half-open state to surface, and the
6
+ * pong deadline tears the connection down so the client reconnects.
7
+ */
8
+ export function attachKeepalive(raw, options) {
9
+ const { pingIntervalMs, pongTimeoutMs, onTimeout } = options;
10
+ if (pingIntervalMs <= 0)
11
+ return () => { };
12
+ let disposed = false;
13
+ let pongDeadline = null;
14
+ const clearDeadline = () => {
15
+ if (pongDeadline !== null) {
16
+ clearTimeout(pongDeadline);
17
+ pongDeadline = null;
18
+ }
19
+ };
20
+ const onPong = () => {
21
+ clearDeadline();
22
+ };
23
+ raw.on("pong", onPong);
24
+ const pingTimer = setInterval(() => {
25
+ if (disposed)
26
+ return;
27
+ if (raw.readyState !== raw.OPEN)
28
+ return;
29
+ if (pongDeadline !== null)
30
+ return;
31
+ try {
32
+ raw.ping();
33
+ }
34
+ catch {
35
+ return;
36
+ }
37
+ if (pongTimeoutMs <= 0)
38
+ return;
39
+ pongDeadline = setTimeout(() => {
40
+ pongDeadline = null;
41
+ if (disposed)
42
+ return;
43
+ onTimeout?.();
44
+ try {
45
+ raw.terminate();
46
+ }
47
+ catch {
48
+ // already closed; nothing to do
49
+ }
50
+ }, pongTimeoutMs);
51
+ pongDeadline.unref?.();
52
+ }, pingIntervalMs);
53
+ pingTimer.unref?.();
54
+ return () => {
55
+ if (disposed)
56
+ return;
57
+ disposed = true;
58
+ clearInterval(pingTimer);
59
+ clearDeadline();
60
+ raw.off("pong", onPong);
61
+ };
62
+ }
63
+ //# sourceMappingURL=keepalive.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keepalive.js","sourceRoot":"","sources":["../../src/ws/keepalive.ts"],"names":[],"mappings":"AAoBA;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAC7B,GAAoB,EACpB,OAAyB;IAEzB,MAAM,EAAE,cAAc,EAAE,aAAa,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;IAC7D,IAAI,cAAc,IAAI,CAAC;QAAE,OAAO,GAAG,EAAE,GAAE,CAAC,CAAC;IAEzC,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,IAAI,YAAY,GAAyC,IAAI,CAAC;IAE9D,MAAM,aAAa,GAAG,GAAG,EAAE;QACzB,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;YAC1B,YAAY,CAAC,YAAY,CAAC,CAAC;YAC3B,YAAY,GAAG,IAAI,CAAC;QACtB,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,MAAM,GAAG,GAAG,EAAE;QAClB,aAAa,EAAE,CAAC;IAClB,CAAC,CAAC;IAEF,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEvB,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE;QACjC,IAAI,QAAQ;YAAE,OAAO;QACrB,IAAI,GAAG,CAAC,UAAU,KAAK,GAAG,CAAC,IAAI;YAAE,OAAO;QACxC,IAAI,YAAY,KAAK,IAAI;YAAE,OAAO;QAClC,IAAI,CAAC;YACH,GAAG,CAAC,IAAI,EAAE,CAAC;QACb,CAAC;QAAC,MAAM,CAAC;YACP,OAAO;QACT,CAAC;QACD,IAAI,aAAa,IAAI,CAAC;YAAE,OAAO;QAC/B,YAAY,GAAG,UAAU,CAAC,GAAG,EAAE;YAC7B,YAAY,GAAG,IAAI,CAAC;YACpB,IAAI,QAAQ;gBAAE,OAAO;YACrB,SAAS,EAAE,EAAE,CAAC;YACd,IAAI,CAAC;gBACH,GAAG,CAAC,SAAS,EAAE,CAAC;YAClB,CAAC;YAAC,MAAM,CAAC;gBACP,gCAAgC;YAClC,CAAC;QACH,CAAC,EAAE,aAAa,CAAC,CAAC;QAClB,YAAY,CAAC,KAAK,EAAE,EAAE,CAAC;IACzB,CAAC,EAAE,cAAc,CAAC,CAAC;IACnB,SAAS,CAAC,KAAK,EAAE,EAAE,CAAC;IAEpB,OAAO,GAAG,EAAE;QACV,IAAI,QAAQ;YAAE,OAAO;QACrB,QAAQ,GAAG,IAAI,CAAC;QAChB,aAAa,CAAC,SAAS,CAAC,CAAC;QACzB,aAAa,EAAE,CAAC;QAChB,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1B,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { type WsTerminalClientMessage } from "@parasor/shared";
2
+ import type { RelayContext } from "./terminal.js";
3
+ type WsTerminalInitMessage = Extract<WsTerminalClientMessage, {
4
+ type: "init";
5
+ }>;
6
+ /**
7
+ * First-frame attach: choose the binary or legacy path from declared
8
+ * capabilities. The caller ({@link handleInitFrame}) has already validated that
9
+ * `msg` is the mandatory `init` and recorded the handshake.
10
+ */
11
+ export declare function attachClient(ctx: RelayContext, msg: WsTerminalInitMessage): Promise<void>;
12
+ export {};
13
+ //# sourceMappingURL=terminal-attach.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal-attach.d.ts","sourceRoot":"","sources":["../../src/ws/terminal-attach.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,uBAAuB,EAE7B,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,YAAY,EAAc,MAAM,eAAe,CAAC;AAG9D,KAAK,qBAAqB,GAAG,OAAO,CAAC,uBAAuB,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAmFhF;;;;GAIG;AACH,wBAAsB,YAAY,CAChC,GAAG,EAAE,YAAY,EACjB,GAAG,EAAE,qBAAqB,GACzB,OAAO,CAAC,IAAI,CAAC,CAOf"}
@@ -0,0 +1,233 @@
1
+ import { encodeExitFrame, encodeOutputFrame, } from "@parasor/shared";
2
+ import { applyServerBackpressure } from "./terminal-flow.js";
3
+ const OUTPUT_TRACE_SAMPLE_CHUNKS = 100;
4
+ const OUTPUT_TRACE_SAMPLE_BYTES = 64 * 1024;
5
+ const OUTPUT_TRACE_SAMPLE_MS = 1000;
6
+ function sendJson(ws, msg) {
7
+ if (ws.readyState === 1)
8
+ ws.send(JSON.stringify(msg));
9
+ }
10
+ class OutputTraceSampler {
11
+ ctx;
12
+ wire;
13
+ chunks = 0;
14
+ bytes = 0;
15
+ firstAt = 0;
16
+ firstGeneration = null;
17
+ lastGeneration = null;
18
+ firstSeq = null;
19
+ lastSeq = null;
20
+ emittedFirst = false;
21
+ constructor(ctx, wire) {
22
+ this.ctx = ctx;
23
+ this.wire = wire;
24
+ }
25
+ record(chunk) {
26
+ if (!this.ctx.traceRecorder?.isEnabled())
27
+ return;
28
+ const now = performance.now();
29
+ if (this.chunks === 0) {
30
+ this.firstAt = now;
31
+ this.firstGeneration = chunk.generation ?? null;
32
+ this.firstSeq = chunk.seq === undefined ? null : String(chunk.seq);
33
+ }
34
+ this.chunks += 1;
35
+ this.bytes += chunk.byteLength;
36
+ this.lastGeneration = chunk.generation ?? this.lastGeneration;
37
+ this.lastSeq = chunk.seq === undefined ? this.lastSeq : String(chunk.seq);
38
+ if (!this.emittedFirst ||
39
+ this.chunks >= OUTPUT_TRACE_SAMPLE_CHUNKS ||
40
+ this.bytes >= OUTPUT_TRACE_SAMPLE_BYTES ||
41
+ now - this.firstAt >= OUTPUT_TRACE_SAMPLE_MS) {
42
+ this.flush(now);
43
+ }
44
+ }
45
+ flush(now) {
46
+ if (this.chunks === 0)
47
+ return;
48
+ this.ctx.traceRecorder?.record("ws-output", {
49
+ wire: this.wire,
50
+ chunks: this.chunks,
51
+ byteLength: this.bytes,
52
+ windowMs: Math.round((now - this.firstAt) * 10) / 10,
53
+ firstGeneration: this.firstGeneration,
54
+ lastGeneration: this.lastGeneration,
55
+ firstSeq: this.firstSeq,
56
+ lastSeq: this.lastSeq,
57
+ }, { sessionId: this.ctx.sessionId, clientId: this.ctx.clientId });
58
+ this.emittedFirst = true;
59
+ this.chunks = 0;
60
+ this.bytes = 0;
61
+ this.firstAt = 0;
62
+ this.firstGeneration = null;
63
+ this.lastGeneration = null;
64
+ this.firstSeq = null;
65
+ this.lastSeq = null;
66
+ }
67
+ }
68
+ /**
69
+ * First-frame attach: choose the binary or legacy path from declared
70
+ * capabilities. The caller ({@link handleInitFrame}) has already validated that
71
+ * `msg` is the mandatory `init` and recorded the handshake.
72
+ */
73
+ export async function attachClient(ctx, msg) {
74
+ const declared = msg.capabilities;
75
+ if (declared?.binary) {
76
+ await attachBinaryClient(ctx, msg, declared);
77
+ return;
78
+ }
79
+ await attachLegacyClient(ctx, msg);
80
+ }
81
+ /**
82
+ * Binary capability path: atomically attach (replay decision + chunk listener
83
+ * registered under the host mutex), ack, then flush full/delta replay. Honors
84
+ * the attach fencing mid-await close race by releasing the freshly minted entry.
85
+ */
86
+ async function attachBinaryClient(ctx, msg, declared) {
87
+ const { ws, state, sessionId, clientId, ptyManager, traceRecorder } = ctx;
88
+ const outputTrace = new OutputTraceSampler(ctx, "binary");
89
+ // -- the host method holds
90
+ // its own mutex while computing the replay decision and registering
91
+ // the chunk listener, so init-ack / replay / live OUTPUT cannot
92
+ // interleave on the wire.
93
+ traceRecorder?.record("pty-attach-start", { mode: "binary", cols: msg.cols, rows: msg.rows }, { sessionId, clientId });
94
+ const attachStart = performance.now();
95
+ const result = await ptyManager.attachClient(sessionId, clientId, msg.cols, msg.rows, {
96
+ binary: declared.binary,
97
+ chunkedReplay: declared.chunkedReplay,
98
+ lastSeen: declared.lastSeen,
99
+ }, {
100
+ onChunk: (generation, seq, data) => {
101
+ outputTrace.record({ byteLength: data.byteLength, generation, seq });
102
+ if (ws.readyState === 1) {
103
+ ws.send(encodeOutputFrame(generation, seq, data));
104
+ applyServerBackpressure(ws, state, sessionId, clientId, ptyManager);
105
+ }
106
+ },
107
+ onExit: (exitCode) => {
108
+ if (ws.readyState === 1) {
109
+ ws.send(encodeExitFrame(exitCode));
110
+ }
111
+ },
112
+ });
113
+ if (!result.ok) {
114
+ traceRecorder?.record("pty-attach-failed", {
115
+ mode: "binary",
116
+ durationMs: Math.round((performance.now() - attachStart) * 10) / 10,
117
+ reason: "unavailable",
118
+ }, { sessionId, clientId });
119
+ ws.close(1008, "Session unavailable");
120
+ traceRecorder?.record("ws-close", { code: 1008, reason: "Session unavailable" }, { sessionId, clientId });
121
+ return;
122
+ }
123
+ state.attachToken = result.attachToken;
124
+ traceRecorder?.record("pty-attach-complete", {
125
+ mode: "binary",
126
+ durationMs: Math.round((performance.now() - attachStart) * 10) / 10,
127
+ replay: result.replay,
128
+ binary: result.capabilities.binary,
129
+ chunkedReplay: result.capabilities.chunkedReplay,
130
+ ...(result.replayDiagnostics
131
+ ? { replayDiagnostics: result.replayDiagnostics }
132
+ : {}),
133
+ }, { sessionId, clientId });
134
+ // Attach fencing: WS may have closed while attachClient() was awaiting.
135
+ // The host has already minted a fresh entry under our token; if we
136
+ // skip the cleanup detach (no init-ack will fire), the entry leaks
137
+ // forever. Release it now using the just-captured token so a future
138
+ // reconnect with the same clientId is not blocked by ghost state.
139
+ if (ws.readyState !== 1) {
140
+ ptyManager.detachClient(sessionId, clientId, result.attachToken);
141
+ traceRecorder?.record("pty-attach-abandoned", {
142
+ mode: "binary",
143
+ durationMs: Math.round((performance.now() - attachStart) * 10) / 10,
144
+ attachToken: result.attachToken,
145
+ }, { sessionId, clientId });
146
+ return;
147
+ }
148
+ sendJson(ws, {
149
+ type: "init-ack",
150
+ capabilities: result.capabilities,
151
+ serverState: result.serverState,
152
+ replay: result.replay,
153
+ });
154
+ traceRecorder?.record("ws-init-ack", {
155
+ replay: result.replay,
156
+ generation: result.serverState.generation,
157
+ binary: result.capabilities.binary,
158
+ chunkedReplay: result.capabilities.chunkedReplay,
159
+ }, { sessionId, clientId });
160
+ if (result.replay === "full" && result.fullReplay) {
161
+ const fullReplay = result.fullReplay;
162
+ traceRecorder?.recordLazy("ws-replay", () => ({
163
+ replay: "full",
164
+ dataLength: fullReplay.length,
165
+ ...(result.replayDiagnostics
166
+ ? { replayDiagnostics: result.replayDiagnostics }
167
+ : {}),
168
+ }), { sessionId, clientId });
169
+ sendJson(ws, { type: "replay", data: fullReplay });
170
+ }
171
+ else if (result.replay === "delta" && result.chunks) {
172
+ for (const chunk of result.chunks) {
173
+ if (ws.readyState !== 1)
174
+ break;
175
+ traceRecorder?.recordLazy("ws-replay", () => ({
176
+ replay: "delta",
177
+ byteLength: chunk.data.byteLength,
178
+ generation: chunk.generation,
179
+ seq: String(chunk.seq),
180
+ }), { sessionId, clientId });
181
+ ws.send(encodeOutputFrame(chunk.generation, chunk.seq, chunk.data));
182
+ }
183
+ }
184
+ // If the negotiated path turned out to be legacy (server doesn't
185
+ // support binary, e.g. RemotePtyHost), `binaryAttached` stays
186
+ // false so subsequent JSON input/resize/refresh keeps working.
187
+ state.binaryAttached = result.capabilities.binary;
188
+ }
189
+ /**
190
+ * Legacy path -- old client without capabilities. String OUTPUT is relayed
191
+ * verbatim via the host's `initClient` listener. Honors the same attach fencing
192
+ * mid-await close race as the binary path.
193
+ */
194
+ async function attachLegacyClient(ctx, msg) {
195
+ const { ws, state, sessionId, clientId, ptyManager, traceRecorder } = ctx;
196
+ const outputTrace = new OutputTraceSampler(ctx, "legacy");
197
+ traceRecorder?.record("pty-attach-start", { mode: "legacy", cols: msg.cols, rows: msg.rows }, { sessionId, clientId });
198
+ const legacyAttachStart = performance.now();
199
+ const initResult = await ptyManager.initClient(sessionId, clientId, msg.cols, msg.rows, (data) => {
200
+ outputTrace.record({ byteLength: Buffer.byteLength(data, "utf8") });
201
+ if (ws.readyState === 1) {
202
+ ws.send(data);
203
+ applyServerBackpressure(ws, state, sessionId, clientId, ptyManager);
204
+ }
205
+ });
206
+ if (!initResult.ok) {
207
+ traceRecorder?.record("pty-attach-failed", {
208
+ mode: "legacy",
209
+ durationMs: Math.round((performance.now() - legacyAttachStart) * 10) / 10,
210
+ reason: "unavailable",
211
+ }, { sessionId, clientId });
212
+ ws.close(1008, "Session unavailable");
213
+ traceRecorder?.record("ws-close", { code: 1008, reason: "Session unavailable" }, { sessionId, clientId });
214
+ return;
215
+ }
216
+ state.attachToken = initResult.attachToken;
217
+ traceRecorder?.record("pty-attach-complete", {
218
+ mode: "legacy",
219
+ durationMs: Math.round((performance.now() - legacyAttachStart) * 10) / 10,
220
+ }, { sessionId, clientId });
221
+ // Attach fencing: same race as the binary path -- release the freshly-
222
+ // minted entry if the WS closed mid-await so we do not leak a ghost
223
+ // listener under this clientId.
224
+ if (ws.readyState !== 1) {
225
+ ptyManager.detachClient(sessionId, clientId, initResult.attachToken);
226
+ traceRecorder?.record("pty-attach-abandoned", {
227
+ mode: "legacy",
228
+ durationMs: Math.round((performance.now() - legacyAttachStart) * 10) / 10,
229
+ attachToken: initResult.attachToken,
230
+ }, { sessionId, clientId });
231
+ }
232
+ }
233
+ //# sourceMappingURL=terminal-attach.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal-attach.js","sourceRoot":"","sources":["../../src/ws/terminal-attach.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { PtyHost } from "../pty/host.js";
2
+ import type { TerminalRelayState, TerminalWs } from "./terminal.js";
3
+ /**
4
+ * Reconcile the host's single per-client `flowPaused` bit against the relay's
5
+ * two independent pause reasons. Pause when either the client or the server
6
+ * wants it; resume only when both are clear. Idempotent -- the host no-ops a
7
+ * repeated pause/resume -- so it is safe to call after any reason flips.
8
+ */
9
+ export declare function syncPtyFlow(state: TerminalRelayState, sessionId: string, clientId: string, ptyManager: PtyHost): void;
10
+ /**
11
+ * Apply send backpressure after relaying a chunk to {@link ws}. Pauses the PTY
12
+ * when the socket's send buffer is congested and starts a drain poll that
13
+ * resumes it once the buffer empties; closes 1013 if the buffer blows past the
14
+ * hard ceiling. No-op when the transport does not expose `bufferedAmount`.
15
+ */
16
+ export declare function applyServerBackpressure(ws: TerminalWs, state: TerminalRelayState, sessionId: string, clientId: string, ptyManager: PtyHost): void;
17
+ //# sourceMappingURL=terminal-flow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal-flow.d.ts","sourceRoot":"","sources":["../../src/ws/terminal-flow.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,KAAK,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAgBpE;;;;;GAKG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,kBAAkB,EACzB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,OAAO,GAClB,IAAI,CAMN;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,EAAE,EAAE,UAAU,EACd,KAAK,EAAE,kBAAkB,EACzB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,OAAO,GAClB,IAAI,CA6BN"}
@@ -0,0 +1,64 @@
1
+ /*
2
+ * Server-side send backpressure for the terminal socket. A client that stops
3
+ * draining its socket (mobile background, slow link, frozen tab the keepalive
4
+ * has not yet reaped) would otherwise grow the server's per-socket send buffer
5
+ * without bound. When `bufferedAmount` reaches the high-water mark we pause the
6
+ * PTY via the existing flow-control path; a poll resumes it once the buffer
7
+ * drains to the low-water mark. The hard ceiling is the backstop: a socket that
8
+ * blows past it is closed (1013) and the client reconnects + replays.
9
+ */
10
+ const BACKPRESSURE_HIGH_WATER = 1024 * 1024; // 1 MiB -- pause the PTY
11
+ const BACKPRESSURE_LOW_WATER = 256 * 1024; // 256 KiB -- resume the PTY
12
+ const BACKPRESSURE_HARD_LIMIT = 8 * 1024 * 1024; // 8 MiB -- give up, close 1013
13
+ const BACKPRESSURE_DRAIN_POLL_MS = 100;
14
+ /**
15
+ * Reconcile the host's single per-client `flowPaused` bit against the relay's
16
+ * two independent pause reasons. Pause when either the client or the server
17
+ * wants it; resume only when both are clear. Idempotent -- the host no-ops a
18
+ * repeated pause/resume -- so it is safe to call after any reason flips.
19
+ */
20
+ export function syncPtyFlow(state, sessionId, clientId, ptyManager) {
21
+ if (state.clientPaused || state.serverPaused) {
22
+ ptyManager.pauseOutput(sessionId, clientId);
23
+ }
24
+ else {
25
+ ptyManager.resumeOutput(sessionId, clientId);
26
+ }
27
+ }
28
+ /**
29
+ * Apply send backpressure after relaying a chunk to {@link ws}. Pauses the PTY
30
+ * when the socket's send buffer is congested and starts a drain poll that
31
+ * resumes it once the buffer empties; closes 1013 if the buffer blows past the
32
+ * hard ceiling. No-op when the transport does not expose `bufferedAmount`.
33
+ */
34
+ export function applyServerBackpressure(ws, state, sessionId, clientId, ptyManager) {
35
+ const buffered = ws.raw?.bufferedAmount ?? 0;
36
+ if (buffered > BACKPRESSURE_HARD_LIMIT) {
37
+ ws.close(1013, "backpressure");
38
+ return;
39
+ }
40
+ if (buffered < BACKPRESSURE_HIGH_WATER)
41
+ return;
42
+ if (state.serverPaused)
43
+ return;
44
+ state.serverPaused = true;
45
+ syncPtyFlow(state, sessionId, clientId, ptyManager);
46
+ const timer = setInterval(() => {
47
+ const depth = ws.raw?.bufferedAmount ?? 0;
48
+ if (ws.readyState !== 1 || depth <= BACKPRESSURE_LOW_WATER) {
49
+ clearInterval(timer);
50
+ state.drainTimer = undefined;
51
+ if (state.serverPaused) {
52
+ state.serverPaused = false;
53
+ // Honor a still-active client-driven pause: resume only if the client
54
+ // is not itself paused (syncPtyFlow ANDs the two reasons).
55
+ if (ws.readyState === 1) {
56
+ syncPtyFlow(state, sessionId, clientId, ptyManager);
57
+ }
58
+ }
59
+ }
60
+ }, BACKPRESSURE_DRAIN_POLL_MS);
61
+ timer.unref?.();
62
+ state.drainTimer = timer;
63
+ }
64
+ //# sourceMappingURL=terminal-flow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal-flow.js","sourceRoot":"","sources":["../../src/ws/terminal-flow.ts"],"names":[],"mappings":"AAGA;;;;;;;;GAQG;AACH,MAAM,uBAAuB,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,yBAAyB;AACtE,MAAM,sBAAsB,GAAG,GAAG,GAAG,IAAI,CAAC,CAAC,4BAA4B;AACvE,MAAM,uBAAuB,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,+BAA+B;AAChF,MAAM,0BAA0B,GAAG,GAAG,CAAC;AAEvC;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CACzB,KAAyB,EACzB,SAAiB,EACjB,QAAgB,EAChB,UAAmB;IAEnB,IAAI,KAAK,CAAC,YAAY,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC;QAC7C,UAAU,CAAC,WAAW,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAC9C,CAAC;SAAM,CAAC;QACN,UAAU,CAAC,YAAY,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAC/C,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,uBAAuB,CACrC,EAAc,EACd,KAAyB,EACzB,SAAiB,EACjB,QAAgB,EAChB,UAAmB;IAEnB,MAAM,QAAQ,GAAG,EAAE,CAAC,GAAG,EAAE,cAAc,IAAI,CAAC,CAAC;IAC7C,IAAI,QAAQ,GAAG,uBAAuB,EAAE,CAAC;QACvC,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;QAC/B,OAAO;IACT,CAAC;IACD,IAAI,QAAQ,GAAG,uBAAuB;QAAE,OAAO;IAE/C,IAAI,KAAK,CAAC,YAAY;QAAE,OAAO;IAC/B,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC;IAC1B,WAAW,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;IAEpD,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE;QAC7B,MAAM,KAAK,GAAG,EAAE,CAAC,GAAG,EAAE,cAAc,IAAI,CAAC,CAAC;QAC1C,IAAI,EAAE,CAAC,UAAU,KAAK,CAAC,IAAI,KAAK,IAAI,sBAAsB,EAAE,CAAC;YAC3D,aAAa,CAAC,KAAK,CAAC,CAAC;YACrB,KAAK,CAAC,UAAU,GAAG,SAAS,CAAC;YAC7B,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC;gBACvB,KAAK,CAAC,YAAY,GAAG,KAAK,CAAC;gBAC3B,sEAAsE;gBACtE,2DAA2D;gBAC3D,IAAI,EAAE,CAAC,UAAU,KAAK,CAAC,EAAE,CAAC;oBACxB,WAAW,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;gBACtD,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC,EAAE,0BAA0B,CAAC,CAAC;IAC/B,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;IAChB,KAAK,CAAC,UAAU,GAAG,KAAK,CAAC;AAC3B,CAAC"}