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,27 @@
1
+ import { spawnSync } from "node:child_process";
2
+ const defaultSpawn = (cmd, args) => {
3
+ spawnSync(cmd, args, { stdio: "ignore" });
4
+ };
5
+ function notify(payload, deps) {
6
+ if (!process.env.NOTIFY_SOCKET)
7
+ return;
8
+ const spawn = deps?.spawn ?? defaultSpawn;
9
+ try {
10
+ spawn("systemd-notify", [payload]);
11
+ }
12
+ catch {
13
+ /*
14
+ * systemd-notify missing (e.g. NOTIFY_SOCKET leaked from an unusual env
15
+ * without systemd installed) must not crash the server -- the watchdog
16
+ * will still fire via systemd's own timeout and the operator will see
17
+ * the restart in journalctl.
18
+ */
19
+ }
20
+ }
21
+ export function notifyReady(deps) {
22
+ notify("READY=1", deps);
23
+ }
24
+ export function notifyWatchdog(deps) {
25
+ notify("WATCHDOG=1", deps);
26
+ }
27
+ //# sourceMappingURL=sd-notify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sd-notify.js","sourceRoot":"","sources":["../../src/lib/sd-notify.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAoB/C,MAAM,YAAY,GAAY,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE;IAC1C,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;AAC5C,CAAC,CAAC;AAEF,SAAS,MAAM,CAAC,OAAe,EAAE,IAAmB;IAClD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa;QAAE,OAAO;IACvC,MAAM,KAAK,GAAG,IAAI,EAAE,KAAK,IAAI,YAAY,CAAC;IAC1C,IAAI,CAAC;QACH,KAAK,CAAC,gBAAgB,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP;;;;;WAKG;IACL,CAAC;AACH,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,IAAmB;IAC7C,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAAmB;IAChD,MAAM,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;AAC7B,CAAC"}
@@ -0,0 +1,7 @@
1
+ export interface LocalMachineAddressOptions {
2
+ interfaceAddresses?: Iterable<string>;
3
+ }
4
+ export declare function isLocalMachineAddress(remoteAddress: string | null, options?: LocalMachineAddressOptions): boolean;
5
+ export declare function collectHostInterfaceAddresses(): string[];
6
+ export declare function normalizeAddress(address: string | null): string | null;
7
+ //# sourceMappingURL=local-machine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-machine.d.ts","sourceRoot":"","sources":["../../src/net/local-machine.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,0BAA0B;IACzC,kBAAkB,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;CACvC;AAED,wBAAgB,qBAAqB,CACnC,aAAa,EAAE,MAAM,GAAG,IAAI,EAC5B,OAAO,GAAE,0BAA+B,GACvC,OAAO,CAWT;AAED,wBAAgB,6BAA6B,IAAI,MAAM,EAAE,CAUxD;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CA6BtE"}
@@ -0,0 +1,79 @@
1
+ import { isIP } from "node:net";
2
+ import { networkInterfaces } from "node:os";
3
+ const LOOPBACK_LITERALS = new Set(["localhost", "::1"]);
4
+ export function isLocalMachineAddress(remoteAddress, options = {}) {
5
+ const normalized = normalizeAddress(remoteAddress);
6
+ if (!normalized)
7
+ return false;
8
+ if (isLoopbackAddress(normalized))
9
+ return true;
10
+ const localAddresses = options.interfaceAddresses ?? collectHostInterfaceAddresses();
11
+ for (const address of localAddresses) {
12
+ if (normalizeAddress(address) === normalized)
13
+ return true;
14
+ }
15
+ return false;
16
+ }
17
+ export function collectHostInterfaceAddresses() {
18
+ const result = [];
19
+ for (const entries of Object.values(networkInterfaces())) {
20
+ if (!entries)
21
+ continue;
22
+ for (const entry of entries) {
23
+ const normalized = normalizeAddress(entry.address);
24
+ if (normalized)
25
+ result.push(normalized);
26
+ }
27
+ }
28
+ return result;
29
+ }
30
+ export function normalizeAddress(address) {
31
+ if (!address)
32
+ return null;
33
+ let value = address.trim().toLowerCase();
34
+ if (!value)
35
+ return null;
36
+ if (value.startsWith("[") && value.endsWith("]")) {
37
+ value = value.slice(1, -1);
38
+ }
39
+ const zoneIndex = value.indexOf("%");
40
+ if (zoneIndex >= 0)
41
+ value = value.slice(0, zoneIndex);
42
+ const dottedMapped = /^::ffff:(\d{1,3}(?:\.\d{1,3}){3})$/i.exec(value);
43
+ if (dottedMapped)
44
+ return normalizeIpv4(dottedMapped[1]);
45
+ const hexMapped = /^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/i.exec(value);
46
+ if (hexMapped) {
47
+ const high = parseInt(hexMapped[1], 16);
48
+ const low = parseInt(hexMapped[2], 16);
49
+ return [
50
+ (high >>> 8) & 0xff,
51
+ high & 0xff,
52
+ (low >>> 8) & 0xff,
53
+ low & 0xff,
54
+ ].join(".");
55
+ }
56
+ const ipv4 = normalizeIpv4(value);
57
+ if (ipv4)
58
+ return ipv4;
59
+ if (isIP(value) === 6 || value === "localhost")
60
+ return value;
61
+ return null;
62
+ }
63
+ function normalizeIpv4(value) {
64
+ const parts = value.split(".");
65
+ if (parts.length !== 4)
66
+ return null;
67
+ const numbers = parts.map((part) => Number(part));
68
+ if (numbers.some((part) => !Number.isInteger(part) || part < 0 || part > 255)) {
69
+ return null;
70
+ }
71
+ return numbers.join(".");
72
+ }
73
+ function isLoopbackAddress(address) {
74
+ if (LOOPBACK_LITERALS.has(address))
75
+ return true;
76
+ const ipv4 = normalizeIpv4(address);
77
+ return ipv4 !== null && ipv4.split(".")[0] === "127";
78
+ }
79
+ //# sourceMappingURL=local-machine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-machine.js","sourceRoot":"","sources":["../../src/net/local-machine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Resolve the address a per-port TCP forwarder should bind on, given the
3
+ * address parasor's own HTTP server is bound to:
4
+ * - loopback (`127.0.0.0/8` / `::1` / `localhost`) ⇒ `null` -- the viewer is on
5
+ * this machine, `localhost:<port>` already works, so no forwarder.
6
+ * - anything else (a specific address, or `0.0.0.0` / `::`) ⇒ that host
7
+ * verbatim. The forwarder listens on an OS-assigned free port so binding
8
+ * `0.0.0.0` does not collide with the dev server's own `127.0.0.1:<port>`.
9
+ * Exposure is ≤ parasor's own, which the viewer already reached it through.
10
+ */
11
+ export declare function resolveForwarderBindHost(parasorBindHost: string): string | null;
12
+ //# sourceMappingURL=reachable-host.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reachable-host.d.ts","sourceRoot":"","sources":["../../src/net/reachable-host.ts"],"names":[],"mappings":"AAYA;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CACtC,eAAe,EAAE,MAAM,GACtB,MAAM,GAAG,IAAI,CAGf"}
@@ -0,0 +1,25 @@
1
+ const LOOPBACK_HOSTS = new Set(["localhost", "::1"]);
2
+ function isLoopbackHost(host) {
3
+ if (LOOPBACK_HOSTS.has(host))
4
+ return true;
5
+ const parts = host.split(".").map(Number);
6
+ return (parts.length === 4 &&
7
+ parts.every((n) => Number.isInteger(n) && n >= 0 && n <= 255) &&
8
+ parts[0] === 127);
9
+ }
10
+ /**
11
+ * Resolve the address a per-port TCP forwarder should bind on, given the
12
+ * address parasor's own HTTP server is bound to:
13
+ * - loopback (`127.0.0.0/8` / `::1` / `localhost`) ⇒ `null` -- the viewer is on
14
+ * this machine, `localhost:<port>` already works, so no forwarder.
15
+ * - anything else (a specific address, or `0.0.0.0` / `::`) ⇒ that host
16
+ * verbatim. The forwarder listens on an OS-assigned free port so binding
17
+ * `0.0.0.0` does not collide with the dev server's own `127.0.0.1:<port>`.
18
+ * Exposure is ≤ parasor's own, which the viewer already reached it through.
19
+ */
20
+ export function resolveForwarderBindHost(parasorBindHost) {
21
+ if (isLoopbackHost(parasorBindHost))
22
+ return null;
23
+ return parasorBindHost;
24
+ }
25
+ //# sourceMappingURL=reachable-host.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reachable-host.js","sourceRoot":"","sources":["../../src/net/reachable-host.ts"],"names":[],"mappings":"AAAA,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC,CAAC;AAErD,SAAS,cAAc,CAAC,IAAY;IAClC,IAAI,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC1C,OAAO,CACL,KAAK,CAAC,MAAM,KAAK,CAAC;QAClB,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC;QAC7D,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,CACjB,CAAC;AACJ,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,wBAAwB,CACtC,eAAuB;IAEvB,IAAI,cAAc,CAAC,eAAe,CAAC;QAAE,OAAO,IAAI,CAAC;IACjD,OAAO,eAAe,CAAC;AACzB,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { NetworkInterfaceInfo } from "node:os";
2
+ export interface NetworkEndpoint {
3
+ category: "Local" | "LAN" | "Tailscale" | "VPN";
4
+ address: string;
5
+ iface?: string;
6
+ }
7
+ export interface TailscaleStatus {
8
+ state: "running" | "stopped" | "not-installed";
9
+ magicDNS?: string;
10
+ }
11
+ export declare function classifyInterfaces(ifaces?: Record<string, NetworkInterfaceInfo[]>): NetworkEndpoint[];
12
+ export declare function checkTailscale(): Promise<TailscaleStatus>;
13
+ export declare function withMagicDNS(endpoints: NetworkEndpoint[], magicDNS: string | undefined): NetworkEndpoint[];
14
+ //# sourceMappingURL=endpoints.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"endpoints.d.ts","sourceRoot":"","sources":["../../src/network/endpoints.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAMpD,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,OAAO,GAAG,KAAK,GAAG,WAAW,GAAG,KAAK,CAAC;IAChD,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,SAAS,GAAG,SAAS,GAAG,eAAe,CAAC;IAC/C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAiBD,wBAAgB,kBAAkB,CAChC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,EAAE,CAAC,GAC9C,eAAe,EAAE,CAmCnB;AAUD,wBAAsB,cAAc,IAAI,OAAO,CAAC,eAAe,CAAC,CAkB/D;AAED,wBAAgB,YAAY,CAC1B,SAAS,EAAE,eAAe,EAAE,EAC5B,QAAQ,EAAE,MAAM,GAAG,SAAS,GAC3B,eAAe,EAAE,CAkBnB"}
@@ -0,0 +1,104 @@
1
+ import { execFile } from "node:child_process";
2
+ import { networkInterfaces } from "node:os";
3
+ import { promisify } from "node:util";
4
+ const execFileAsync = promisify(execFile);
5
+ const VPN_IFACE_RE = /^(utun|tun|ppp|ipsec|wg)/;
6
+ function isCGNAT(addr) {
7
+ const parts = addr.split(".").map(Number);
8
+ return parts[0] === 100 && parts[1] >= 64 && parts[1] <= 127;
9
+ }
10
+ function isRFC1918(addr) {
11
+ const parts = addr.split(".").map(Number);
12
+ if (parts[0] === 10)
13
+ return true;
14
+ if (parts[0] === 172 && parts[1] >= 16 && parts[1] <= 31)
15
+ return true;
16
+ if (parts[0] === 192 && parts[1] === 168)
17
+ return true;
18
+ return false;
19
+ }
20
+ export function classifyInterfaces(ifaces) {
21
+ const raw = ifaces ?? networkInterfaces();
22
+ const endpoints = [
23
+ { category: "Local", address: "127.0.0.1" },
24
+ ];
25
+ for (const [name, addrs] of Object.entries(raw)) {
26
+ if (!addrs)
27
+ continue;
28
+ for (const info of addrs) {
29
+ if (info.internal || info.family !== "IPv4")
30
+ continue;
31
+ // Tailscale: CGNAT range or tailscale0 interface
32
+ if (isCGNAT(info.address) || name === "tailscale0") {
33
+ endpoints.push({
34
+ category: "Tailscale",
35
+ address: info.address,
36
+ iface: name,
37
+ });
38
+ continue;
39
+ }
40
+ // VPN: utun/tun/ppp/ipsec/wg interface with non-CGNAT address
41
+ if (VPN_IFACE_RE.test(name)) {
42
+ endpoints.push({ category: "VPN", address: info.address, iface: name });
43
+ continue;
44
+ }
45
+ // LAN: RFC1918
46
+ if (isRFC1918(info.address)) {
47
+ endpoints.push({ category: "LAN", address: info.address, iface: name });
48
+ }
49
+ }
50
+ }
51
+ return endpoints;
52
+ }
53
+ function extractMagicDNS(data) {
54
+ if (!data || typeof data !== "object")
55
+ return undefined;
56
+ const self = data.Self;
57
+ const dnsName = self?.DNSName;
58
+ if (typeof dnsName !== "string" || dnsName.length === 0)
59
+ return undefined;
60
+ return dnsName.replace(/\.$/, "");
61
+ }
62
+ export async function checkTailscale() {
63
+ try {
64
+ const { stdout } = await execFileAsync("tailscale", ["status", "--json"], {
65
+ timeout: 3000,
66
+ });
67
+ const data = JSON.parse(stdout);
68
+ if (data.BackendState !== "Running")
69
+ return { state: "stopped" };
70
+ const magicDNS = extractMagicDNS(data);
71
+ return magicDNS ? { state: "running", magicDNS } : { state: "running" };
72
+ }
73
+ catch (err) {
74
+ const isNotFound = err instanceof Error &&
75
+ ("code" in err
76
+ ? err.code === "ENOENT"
77
+ : false);
78
+ if (isNotFound)
79
+ return { state: "not-installed" };
80
+ return { state: "stopped" };
81
+ }
82
+ }
83
+ export function withMagicDNS(endpoints, magicDNS) {
84
+ if (!magicDNS)
85
+ return endpoints;
86
+ const entry = {
87
+ category: "Tailscale",
88
+ address: magicDNS,
89
+ iface: "MagicDNS",
90
+ };
91
+ const result = [];
92
+ let inserted = false;
93
+ for (const e of endpoints) {
94
+ result.push(e);
95
+ if (!inserted && e.category === "Tailscale" && e.iface !== "MagicDNS") {
96
+ result.push(entry);
97
+ inserted = true;
98
+ }
99
+ }
100
+ if (!inserted)
101
+ result.push(entry);
102
+ return result;
103
+ }
104
+ //# sourceMappingURL=endpoints.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"endpoints.js","sourceRoot":"","sources":["../../src/network/endpoints.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { NetworkEndpoint } from "./endpoints.js";
2
+ export declare function selectQrEndpoint(endpoints: NetworkEndpoint[], iface?: string): NetworkEndpoint | undefined;
3
+ export declare function buildAuthUrl(address: string, port: number, authMode: "token" | "allowlist" | "none", token: string): string;
4
+ export declare function buildPairingUrl(address: string, port: number, token: string, path?: string): string;
5
+ export declare function renderQrLines(url: string): string[];
6
+ export interface QrSectionOptions {
7
+ endpoints: NetworkEndpoint[];
8
+ port: number;
9
+ authMode: "token" | "allowlist" | "none";
10
+ token?: string;
11
+ makeAccessUrl?: (endpoint: NetworkEndpoint) => string;
12
+ iface?: string;
13
+ clickable?: boolean;
14
+ }
15
+ export declare function buildQrSection({ endpoints, port, authMode, token, makeAccessUrl, iface, clickable, }: QrSectionOptions): string[];
16
+ //# sourceMappingURL=qr.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qr.d.ts","sourceRoot":"","sources":["../../src/network/qr.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAKtD,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,eAAe,EAAE,EAC5B,KAAK,CAAC,EAAE,MAAM,GACb,eAAe,GAAG,SAAS,CAU7B;AAED,wBAAgB,YAAY,CAC1B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,OAAO,GAAG,WAAW,GAAG,MAAM,EACxC,KAAK,EAAE,MAAM,GACZ,MAAM,CAGR;AAED,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,IAAI,SAAM,GACT,MAAM,CAIR;AA6BD,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAMnD;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,eAAe,EAAE,CAAC;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,GAAG,WAAW,GAAG,MAAM,CAAC;IACzC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,CAAC,QAAQ,EAAE,eAAe,KAAK,MAAM,CAAC;IACtD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAiBD,wBAAgB,cAAc,CAAC,EAC7B,SAAS,EACT,IAAI,EACJ,QAAQ,EACR,KAAK,EACL,aAAa,EACb,KAAK,EACL,SAAiB,GAClB,EAAE,gBAAgB,GAAG,MAAM,EAAE,CA6B7B"}
@@ -0,0 +1,89 @@
1
+ import qrcodeTerminal from "qrcode-terminal";
2
+ // macOS virtual / ephemeral interfaces we never want to surface to a phone.
3
+ const VIRTUAL_IFACE_RE = /^(bridge|awdl|llw|anpi|ap|pktap|gif|stf)/;
4
+ export function selectQrEndpoint(endpoints, iface) {
5
+ if (iface) {
6
+ return endpoints.find((e) => e.iface === iface);
7
+ }
8
+ const tailscale = endpoints.find((e) => e.category === "Tailscale");
9
+ if (tailscale)
10
+ return tailscale;
11
+ return endpoints.find((e) => e.category === "LAN" && (!e.iface || !VIRTUAL_IFACE_RE.test(e.iface)));
12
+ }
13
+ export function buildAuthUrl(address, port, authMode, token) {
14
+ const base = `http://${address}:${port}`;
15
+ return authMode === "token" ? `${base}/?t=${token}` : base;
16
+ }
17
+ export function buildPairingUrl(address, port, token, path = "/") {
18
+ const url = new URL(`http://${address}:${port}${normalizeAccessPath(path)}`);
19
+ url.searchParams.set("t", token);
20
+ return url.toString();
21
+ }
22
+ // biome-ignore lint/suspicious/noControlCharactersInRegex: access paths must reject terminal/header control bytes.
23
+ const CONTROL_CHAR_RE = /[\x00-\x1f\x7f]/;
24
+ function normalizeAccessPath(path) {
25
+ if (!path.startsWith("/") ||
26
+ path.startsWith("//") ||
27
+ path.includes("\\") ||
28
+ CONTROL_CHAR_RE.test(path)) {
29
+ throw new Error("access URL path must be same-origin relative");
30
+ }
31
+ return path;
32
+ }
33
+ function buildDefaultAccessUrl(address, port, authMode, token) {
34
+ if (authMode === "token" && !token) {
35
+ throw new Error("token or makeAccessUrl is required for token auth URLs");
36
+ }
37
+ return buildAuthUrl(address, port, authMode, token ?? "");
38
+ }
39
+ export function renderQrLines(url) {
40
+ let output = "";
41
+ qrcodeTerminal.generate(url, { small: true }, (rendered) => {
42
+ output = rendered;
43
+ });
44
+ return output.replace(/\n$/, "").split("\n");
45
+ }
46
+ /*
47
+ * OSC 8 hyperlink. Refuse to wrap when the URL or label contains a
48
+ * terminal control character, since those would break the escape
49
+ * sequence (and could be used to inject other escapes if the input is
50
+ * untrusted).
51
+ */
52
+ // biome-ignore lint/suspicious/noControlCharactersInRegex: OSC8 labels/URLs must reject terminal control bytes.
53
+ const TERMINAL_CONTROL_RE = /[\x00-\x1f\x7f]/;
54
+ const OSC8_HYPERLINK = (url, label) => {
55
+ if (TERMINAL_CONTROL_RE.test(url) || TERMINAL_CONTROL_RE.test(label)) {
56
+ return label;
57
+ }
58
+ return `\x1b]8;;${url}\x1b\\${label}\x1b]8;;\x1b\\`;
59
+ };
60
+ export function buildQrSection({ endpoints, port, authMode, token, makeAccessUrl, iface, clickable = false, }) {
61
+ const target = selectQrEndpoint(endpoints, iface);
62
+ if (!target) {
63
+ if (iface) {
64
+ const candidates = endpoints
65
+ .map((e) => e.iface)
66
+ .filter(Boolean)
67
+ .join(", ");
68
+ return [
69
+ `QR: interface "${iface}" not found. Available: ${candidates || "(none)"}`,
70
+ ];
71
+ }
72
+ return [
73
+ "QR: no remote endpoint detected. Run `tailscale up` or connect to a LAN.",
74
+ ];
75
+ }
76
+ const url = makeAccessUrl?.(target) ??
77
+ buildDefaultAccessUrl(target.address, port, authMode, token);
78
+ const label = target.iface
79
+ ? `${target.category} (${target.iface})`
80
+ : target.category;
81
+ const linkedUrl = clickable ? OSC8_HYPERLINK(url, url) : url;
82
+ return [
83
+ `Scan to open on mobile -- ${label}`,
84
+ ` ${linkedUrl}`,
85
+ "",
86
+ ...renderQrLines(url),
87
+ ];
88
+ }
89
+ //# sourceMappingURL=qr.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qr.js","sourceRoot":"","sources":["../../src/network/qr.ts"],"names":[],"mappings":"AAAA,OAAO,cAAc,MAAM,iBAAiB,CAAC;AAG7C,4EAA4E;AAC5E,MAAM,gBAAgB,GAAG,0CAA0C,CAAC;AAEpE,MAAM,UAAU,gBAAgB,CAC9B,SAA4B,EAC5B,KAAc;IAEd,IAAI,KAAK,EAAE,CAAC;QACV,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC;IAClD,CAAC;IACD,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,WAAW,CAAC,CAAC;IACpE,IAAI,SAAS;QAAE,OAAO,SAAS,CAAC;IAChC,OAAO,SAAS,CAAC,IAAI,CACnB,CAAC,CAAC,EAAE,EAAE,CACJ,CAAC,CAAC,QAAQ,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CACxE,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,YAAY,CAC1B,OAAe,EACf,IAAY,EACZ,QAAwC,EACxC,KAAa;IAEb,MAAM,IAAI,GAAG,UAAU,OAAO,IAAI,IAAI,EAAE,CAAC;IACzC,OAAO,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AAC7D,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,OAAe,EACf,IAAY,EACZ,KAAa,EACb,IAAI,GAAG,GAAG;IAEV,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,UAAU,OAAO,IAAI,IAAI,GAAG,mBAAmB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC7E,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACjC,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAC;AACxB,CAAC;AAED,mHAAmH;AACnH,MAAM,eAAe,GAAG,iBAAiB,CAAC;AAE1C,SAAS,mBAAmB,CAAC,IAAY;IACvC,IACE,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QACrB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QACrB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;QACnB,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,EAC1B,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAClE,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,qBAAqB,CAC5B,OAAe,EACf,IAAY,EACZ,QAAwC,EACxC,KAAyB;IAEzB,IAAI,QAAQ,KAAK,OAAO,IAAI,CAAC,KAAK,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;IAC5E,CAAC;IACD,OAAO,YAAY,CAAC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;AAC5D,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,GAAW;IACvC,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,cAAc,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,QAAQ,EAAE,EAAE;QACzD,MAAM,GAAG,QAAQ,CAAC;IACpB,CAAC,CAAC,CAAC;IACH,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AAC/C,CAAC;AAYD;;;;;GAKG;AACH,gHAAgH;AAChH,MAAM,mBAAmB,GAAG,iBAAiB,CAAC;AAC9C,MAAM,cAAc,GAAG,CAAC,GAAW,EAAE,KAAa,EAAU,EAAE;IAC5D,IAAI,mBAAmB,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACrE,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,WAAW,GAAG,SAAS,KAAK,gBAAgB,CAAC;AACtD,CAAC,CAAC;AAEF,MAAM,UAAU,cAAc,CAAC,EAC7B,SAAS,EACT,IAAI,EACJ,QAAQ,EACR,KAAK,EACL,aAAa,EACb,KAAK,EACL,SAAS,GAAG,KAAK,GACA;IACjB,MAAM,MAAM,GAAG,gBAAgB,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IAClD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,UAAU,GAAG,SAAS;iBACzB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;iBACnB,MAAM,CAAC,OAAO,CAAC;iBACf,IAAI,CAAC,IAAI,CAAC,CAAC;YACd,OAAO;gBACL,kBAAkB,KAAK,2BAA2B,UAAU,IAAI,QAAQ,EAAE;aAC3E,CAAC;QACJ,CAAC;QACD,OAAO;YACL,0EAA0E;SAC3E,CAAC;IACJ,CAAC;IACD,MAAM,GAAG,GACP,aAAa,EAAE,CAAC,MAAM,CAAC;QACvB,qBAAqB,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;IAC/D,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK;QACxB,CAAC,CAAC,GAAG,MAAM,CAAC,QAAQ,KAAK,MAAM,CAAC,KAAK,GAAG;QACxC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC;IACpB,MAAM,SAAS,GAAG,SAAS,CAAC,CAAC,CAAC,cAAc,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IAC7D,OAAO;QACL,6BAA6B,KAAK,EAAE;QACpC,KAAK,SAAS,EAAE;QAChB,EAAE;QACF,GAAG,aAAa,CAAC,GAAG,CAAC;KACtB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,47 @@
1
+ export interface ForwardedPortSpec {
2
+ port: number;
3
+ bindsAll: boolean;
4
+ }
5
+ /**
6
+ * Per-port raw TCP forwarder (Tier A .). For each detected
7
+ * dev-server port that is *not* already bound to all interfaces, a
8
+ * `net.Server` listens on `<bindHost>:0` (an OS-assigned free port) and pipes
9
+ * every connection byte-for-byte to `localhost:<devPort>` (both loopback
10
+ * families -- a `localhost` dev server often binds only `::1`). No HTTP parsing
11
+ * -- HMR/WebSocket pass through transparently because it is L4. Using a free
12
+ * listen port means binding `0.0.0.0` does not collide with the dev server's
13
+ * own `localhost:<devPort>`.
14
+ *
15
+ * `bindHost === null` ⇒ the forwarder is inert: parasor is loopback-bound so
16
+ * the viewer is on this machine and `localhost:<port>` already works. `sync`
17
+ * is a no-op and `getReachablePort` always returns `null`.
18
+ *
19
+ * Forwarders are keyed by `projectId` -> `devPort` so a project going inactive
20
+ * (next `sync` with `[]`) tears its forwarders down.
21
+ */
22
+ export declare class PortForwarder {
23
+ private readonly bindHost;
24
+ private readonly byProject;
25
+ private onChange;
26
+ constructor(bindHost: string | null);
27
+ isInert(): boolean;
28
+ /**
29
+ * Register a callback invoked whenever a forwarder finishes binding (its
30
+ * `reachablePort` becomes available) or its bind errors (it is torn down).
31
+ * `PortForwarder`'s state changes out-of-band of `sync` here -- `listen` is
32
+ * async -- so callers that mirror `getReachablePort` results (e.g. the
33
+ * runtime's `ports-updated` broadcast) must re-read on this signal.
34
+ */
35
+ setOnChange(cb: (projectId: string) => void): void;
36
+ sync(projectId: string, ports: ForwardedPortSpec[]): void;
37
+ /**
38
+ * The OS-assigned listen port for `devPort` in `projectId`, or `null` if no
39
+ * forwarder exists, it has not finished binding, or its bind errored.
40
+ */
41
+ getReachablePort(projectId: string, devPort: number): number | null;
42
+ stop(): void;
43
+ private teardownForwarder;
44
+ private createForwarder;
45
+ private wirePair;
46
+ }
47
+ //# sourceMappingURL=forwarder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"forwarder.d.ts","sourceRoot":"","sources":["../../src/port-forwarder/forwarder.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;CACnB;AAYD;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,aAAa;IAIZ,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAHrC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAiD;IAC3E,OAAO,CAAC,QAAQ,CAA8C;gBAEjC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAEpD,OAAO,IAAI,OAAO;IAIlB;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAIlD,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,iBAAiB,EAAE,GAAG,IAAI;IAqBzD;;;OAGG;IACH,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAOnE,IAAI,IAAI,IAAI;IASZ,OAAO,CAAC,iBAAiB;IAMzB,OAAO,CAAC,eAAe;IAsDvB,OAAO,CAAC,QAAQ;CAuBjB"}
@@ -0,0 +1,159 @@
1
+ import net from "node:net";
2
+ /**
3
+ * Per-port raw TCP forwarder (Tier A .). For each detected
4
+ * dev-server port that is *not* already bound to all interfaces, a
5
+ * `net.Server` listens on `<bindHost>:0` (an OS-assigned free port) and pipes
6
+ * every connection byte-for-byte to `localhost:<devPort>` (both loopback
7
+ * families -- a `localhost` dev server often binds only `::1`). No HTTP parsing
8
+ * -- HMR/WebSocket pass through transparently because it is L4. Using a free
9
+ * listen port means binding `0.0.0.0` does not collide with the dev server's
10
+ * own `localhost:<devPort>`.
11
+ *
12
+ * `bindHost === null` ⇒ the forwarder is inert: parasor is loopback-bound so
13
+ * the viewer is on this machine and `localhost:<port>` already works. `sync`
14
+ * is a no-op and `getReachablePort` always returns `null`.
15
+ *
16
+ * Forwarders are keyed by `projectId` -> `devPort` so a project going inactive
17
+ * (next `sync` with `[]`) tears its forwarders down.
18
+ */
19
+ export class PortForwarder {
20
+ bindHost;
21
+ byProject = new Map();
22
+ onChange = null;
23
+ constructor(bindHost) {
24
+ this.bindHost = bindHost;
25
+ }
26
+ isInert() {
27
+ return this.bindHost === null;
28
+ }
29
+ /**
30
+ * Register a callback invoked whenever a forwarder finishes binding (its
31
+ * `reachablePort` becomes available) or its bind errors (it is torn down).
32
+ * `PortForwarder`'s state changes out-of-band of `sync` here -- `listen` is
33
+ * async -- so callers that mirror `getReachablePort` results (e.g. the
34
+ * runtime's `ports-updated` broadcast) must re-read on this signal.
35
+ */
36
+ setOnChange(cb) {
37
+ this.onChange = cb;
38
+ }
39
+ sync(projectId, ports) {
40
+ if (this.bindHost === null)
41
+ return;
42
+ const wanted = new Set(ports.filter((p) => !p.bindsAll).map((p) => p.port));
43
+ const current = this.byProject.get(projectId) ?? new Map();
44
+ for (const [devPort, forwarder] of current) {
45
+ if (!wanted.has(devPort)) {
46
+ this.teardownForwarder(forwarder);
47
+ current.delete(devPort);
48
+ }
49
+ }
50
+ for (const devPort of wanted) {
51
+ if (current.has(devPort))
52
+ continue;
53
+ const forwarder = this.createForwarder(projectId, devPort);
54
+ if (forwarder)
55
+ current.set(devPort, forwarder);
56
+ }
57
+ if (current.size === 0)
58
+ this.byProject.delete(projectId);
59
+ else
60
+ this.byProject.set(projectId, current);
61
+ }
62
+ /**
63
+ * The OS-assigned listen port for `devPort` in `projectId`, or `null` if no
64
+ * forwarder exists, it has not finished binding, or its bind errored.
65
+ */
66
+ getReachablePort(projectId, devPort) {
67
+ if (this.bindHost === null)
68
+ return null;
69
+ const forwarder = this.byProject.get(projectId)?.get(devPort);
70
+ if (!forwarder?.server.listening)
71
+ return null;
72
+ return forwarder.reachablePort;
73
+ }
74
+ stop() {
75
+ for (const forwarders of this.byProject.values()) {
76
+ for (const forwarder of forwarders.values()) {
77
+ this.teardownForwarder(forwarder);
78
+ }
79
+ }
80
+ this.byProject.clear();
81
+ }
82
+ teardownForwarder(forwarder) {
83
+ forwarder.server.close();
84
+ for (const socket of forwarder.sockets)
85
+ socket.destroy();
86
+ forwarder.sockets.clear();
87
+ }
88
+ createForwarder(projectId, devPort) {
89
+ const bindHost = this.bindHost;
90
+ if (bindHost === null)
91
+ return null;
92
+ const sockets = new Set();
93
+ const server = net.createServer((clientSocket) => {
94
+ // `localhost`, not `127.0.0.1`: a dev server started on `localhost` often
95
+ // binds only `::1` (Node's default resolution order on macOS), so an
96
+ // IPv4-only upstream would `ECONNREFUSED`. Node ≥18 `autoSelectFamily`
97
+ // tries both loopback families.
98
+ const upstream = net.connect(devPort, "localhost");
99
+ this.wirePair(sockets, clientSocket, upstream);
100
+ });
101
+ const forwarder = {
102
+ server,
103
+ devPort,
104
+ reachablePort: null,
105
+ sockets,
106
+ };
107
+ server.on("listening", () => {
108
+ const addr = server.address();
109
+ forwarder.reachablePort =
110
+ addr && typeof addr === "object" ? addr.port : null;
111
+ // The listen completed asynchronously, after the `sync` tick -- signal
112
+ // upward so any mirrored reachability state is re-read and re-broadcast.
113
+ this.onChange?.(projectId);
114
+ });
115
+ server.on("error", (err) => {
116
+ // Best effort: a preview forwarder must never crash the server. On any
117
+ // listen error (EADDRINUSE is unlikely on a free port) drop this
118
+ // forwarder; the dev server stays loopback-only and the port is
119
+ // reported unreachable.
120
+ if (err.code !== "EADDRINUSE") {
121
+ console.warn(`[port-forwarder] failed to bind ${bindHost} for dev port ${devPort}: ${err.message}`);
122
+ }
123
+ let removed = false;
124
+ for (const [pid, forwarders] of this.byProject) {
125
+ if (forwarders.get(devPort) === forwarder) {
126
+ this.teardownForwarder(forwarder);
127
+ forwarders.delete(devPort);
128
+ if (forwarders.size === 0)
129
+ this.byProject.delete(pid);
130
+ removed = true;
131
+ }
132
+ }
133
+ if (removed)
134
+ this.onChange?.(projectId);
135
+ });
136
+ server.listen(0, bindHost);
137
+ return forwarder;
138
+ }
139
+ wirePair(sockets, clientSocket, upstream) {
140
+ sockets.add(clientSocket);
141
+ sockets.add(upstream);
142
+ const closePeer = (peer) => {
143
+ peer.destroy();
144
+ };
145
+ clientSocket.on("error", () => closePeer(upstream));
146
+ upstream.on("error", () => closePeer(clientSocket));
147
+ clientSocket.on("close", () => {
148
+ sockets.delete(clientSocket);
149
+ closePeer(upstream);
150
+ });
151
+ upstream.on("close", () => {
152
+ sockets.delete(upstream);
153
+ closePeer(clientSocket);
154
+ });
155
+ clientSocket.pipe(upstream);
156
+ upstream.pipe(clientSocket);
157
+ }
158
+ }
159
+ //# sourceMappingURL=forwarder.js.map