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,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=entry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entry.d.ts","sourceRoot":"","sources":["../../../src/pty/host-daemon/entry.ts"],"names":[],"mappings":""}
@@ -0,0 +1,72 @@
1
+ #!/usr/bin/env node
2
+ /*
3
+ * -- `parasor-pty-host` CLI entry point.
4
+ *
5
+ * Boots a daemon, runs until SIGTERM/SIGINT, exits 0 on graceful stop or
6
+ * non-zero on bootstrap failure. No subcommands yet; this entry is what
7
+ * lifecycle commands invoke under the hood (or what a launchd/systemd unit
8
+ * wraps directly).
9
+ *
10
+ * Logging: opt-in via `PARASOR_PTY_HOST_DEBUG=1`. Default is silent so
11
+ * background-spawned daemons don't pollute the terminal that started
12
+ * them.
13
+ */
14
+ import { appendFileSync } from "node:fs";
15
+ import { UploadStaging } from "../../fs/upload-staging.js";
16
+ import { bootstrapDaemon } from "./bootstrap.js";
17
+ import { DaemonAlreadyRunningError } from "./lockfile.js";
18
+ import { resolveDaemonPaths } from "./paths.js";
19
+ async function main() {
20
+ const paths = resolveDaemonPaths();
21
+ const debug = process.env.PARASOR_PTY_HOST_DEBUG === "1";
22
+ const log = (line) => {
23
+ const stamped = `${new Date().toISOString()} [pty-host] ${line}\n`;
24
+ try {
25
+ appendFileSync(paths.logFile, stamped);
26
+ }
27
+ catch {
28
+ /* log file write best-effort */
29
+ }
30
+ if (debug)
31
+ process.stderr.write(stamped);
32
+ };
33
+ try {
34
+ /*
35
+ * Upload staging isolation -- daemon-side per-session env injection.
36
+ * The daemon is its own process so it cannot share the server's
37
+ * `UploadStaging` instance; we instantiate one here purely for the
38
+ * canonical `uploadsDir` path. The constructor's symlink/owner
39
+ * guards run again as a defence-in-depth check (cheap idempotent
40
+ * mkdir + lstat). The L3 sweep stays in the server process -- the
41
+ * daemon never ticks `sweepStale` to avoid duplicate work, but it
42
+ * does need the canonical path so `InProcessPtyHost.buildSessionEnv`
43
+ * can stamp `PARASOR_UPLOAD_DIR=<dir>/<sid>` on every spawned PTY.
44
+ */
45
+ const uploadStaging = new UploadStaging({});
46
+ const running = await bootstrapDaemon({
47
+ paths,
48
+ log,
49
+ uploadsDir: uploadStaging.uploadsDir,
50
+ });
51
+ log(`pid=${process.pid} ready socket=${running.paths.socketPath}`);
52
+ }
53
+ catch (err) {
54
+ if (err instanceof DaemonAlreadyRunningError) {
55
+ // R4 -- when foreground bootstrap collides with an
56
+ // installed daemon the bare error doesn't tell the user *why* their
57
+ // socket is busy or how to coexist. Emit an explicit hint pointing
58
+ // at `parasor service status` (verifies installed daemon ownership)
59
+ // and the per-PID opt-in (`PARASOR_PTY_SOCK_PER_PID=1`) which gives
60
+ // the foreground process its own socket basename.
61
+ process.stderr.write(`${err.message}\n`);
62
+ process.stderr.write("\nThe installed parasor service may own this socket. Try:\n");
63
+ process.stderr.write(" parasor service status # check installed service state\n");
64
+ process.stderr.write(" PARASOR_PTY_SOCK_PER_PID=1 parasor server # foreground daemon on a per-PID socket\n");
65
+ process.exit(2);
66
+ }
67
+ process.stderr.write(`parasor-pty-host fatal: ${err.stack ?? err}\n`);
68
+ process.exit(1);
69
+ }
70
+ }
71
+ void main();
72
+ //# sourceMappingURL=entry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entry.js","sourceRoot":"","sources":["../../../src/pty/host-daemon/entry.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAEhD,KAAK,UAAU,IAAI;IACjB,MAAM,KAAK,GAAG,kBAAkB,EAAE,CAAC;IACnC,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,sBAAsB,KAAK,GAAG,CAAC;IAEzD,MAAM,GAAG,GAAG,CAAC,IAAY,EAAQ,EAAE;QACjC,MAAM,OAAO,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,eAAe,IAAI,IAAI,CAAC;QACnE,IAAI,CAAC;YACH,cAAc,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACzC,CAAC;QAAC,MAAM,CAAC;YACP,gCAAgC;QAClC,CAAC;QACD,IAAI,KAAK;YAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC3C,CAAC,CAAC;IAEF,IAAI,CAAC;QACH;;;;;;;;;;WAUG;QACH,MAAM,aAAa,GAAG,IAAI,aAAa,CAAC,EAAE,CAAC,CAAC;QAC5C,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC;YACpC,KAAK;YACL,GAAG;YACH,UAAU,EAAE,aAAa,CAAC,UAAU;SACrC,CAAC,CAAC;QACH,GAAG,CAAC,OAAO,OAAO,CAAC,GAAG,iBAAiB,OAAO,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC;IACrE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,yBAAyB,EAAE,CAAC;YAC7C,oDAAoD;YACpD,oEAAoE;YACpE,mEAAmE;YACnE,oEAAoE;YACpE,oEAAoE;YACpE,kDAAkD;YAClD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC;YACzC,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,6DAA6D,CAC9D,CAAC;YACF,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,oEAAoE,CACrE,CAAC;YACF,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,yFAAyF,CAC1F,CAAC;YACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,2BAA4B,GAAa,CAAC,KAAK,IAAI,GAAG,IAAI,CAC3D,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,KAAK,IAAI,EAAE,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { DaemonPaths } from "./paths.js";
2
+ export interface DaemonLock {
3
+ pidFile: string;
4
+ release: () => Promise<void>;
5
+ }
6
+ export declare class DaemonAlreadyRunningError extends Error {
7
+ readonly pid: number;
8
+ readonly pidFile: string;
9
+ constructor(pid: number, pidFile: string);
10
+ }
11
+ export declare function acquireDaemonLock(paths: DaemonPaths, ourPid?: number): Promise<DaemonLock>;
12
+ //# sourceMappingURL=lockfile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lockfile.d.ts","sourceRoot":"","sources":["../../../src/pty/host-daemon/lockfile.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAED,qBAAa,yBAA0B,SAAQ,KAAK;IAEhD,QAAQ,CAAC,GAAG,EAAE,MAAM;IACpB,QAAQ,CAAC,OAAO,EAAE,MAAM;gBADf,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM;CAK3B;AAED,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,WAAW,EAClB,MAAM,GAAE,MAAoB,GAC3B,OAAO,CAAC,UAAU,CAAC,CA+CrB"}
@@ -0,0 +1,120 @@
1
+ /*
2
+ * -- daemon single-instance enforcement.
3
+ *
4
+ * `proper-lockfile` advisory flock on `paths.lockFile` is the *sole*
5
+ * source of truth for "another daemon owns this runtime dir". It is held
6
+ * across the daemon's whole lifetime and released either by graceful
7
+ * shutdown or by stale-timeout (60s) if the holder dies.
8
+ *
9
+ * The pidfile is purely informational: humans (and `parasor pty-host
10
+ * status`) read it to find the daemon's PID; the recorded pid liveness
11
+ * probe (`kill(pid, 0)`) is only consulted to populate
12
+ * `DaemonAlreadyRunningError.pid` for nicer error messages. We do *not*
13
+ * cross-validate the pidfile post-flock -- once flock returned success,
14
+ * the recycled-PID corner case (previous daemon died, OS handed the same
15
+ * PID to an unrelated process before stale-timeout fired) would
16
+ * otherwise spuriously block startup. *
17
+ * Mode marker is enforced by the server-side factory
18
+ * (`createPtyHost`) because it polices in-process vs daemon ownership of
19
+ * the AppStateStore -- out of scope here.
20
+ */
21
+ import { existsSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
22
+ import lockfile from "proper-lockfile";
23
+ export class DaemonAlreadyRunningError extends Error {
24
+ pid;
25
+ pidFile;
26
+ constructor(pid, pidFile) {
27
+ super(`parasor-pty-host already running (pid=${pid}, lock=${pidFile})`);
28
+ this.pid = pid;
29
+ this.pidFile = pidFile;
30
+ this.name = "DaemonAlreadyRunningError";
31
+ }
32
+ }
33
+ export async function acquireDaemonLock(paths, ourPid = process.pid) {
34
+ if (!existsSync(paths.lockFile)) {
35
+ writeFileSync(paths.lockFile, "");
36
+ }
37
+ let release;
38
+ try {
39
+ release = await lockfile.lock(paths.lockFile, {
40
+ stale: 60_000,
41
+ retries: 0,
42
+ });
43
+ }
44
+ catch (err) {
45
+ // ELOCKED is the only signal that another live daemon owns the
46
+ // lockfile. We surface the recorded pid (if alive) for diagnostics,
47
+ // but the rejection itself is decided entirely by flock -- the
48
+ // pidfile content cannot vote.
49
+ if (isLockHeldError(err)) {
50
+ const livePid = readPidIfAlive(paths.pidFile);
51
+ throw new DaemonAlreadyRunningError(livePid ?? -1, paths.pidFile);
52
+ }
53
+ throw err;
54
+ }
55
+ // flock acquired: we own the runtime dir. Stamp our pid for `parasor
56
+ // pty-host status` consumers; do NOT recheck the pidfile, because a
57
+ // stale pid that has been recycled by an unrelated live process would
58
+ // otherwise block legitimate takeover.
59
+ writeFileSync(paths.pidFile, `${ourPid}\n`);
60
+ return {
61
+ pidFile: paths.pidFile,
62
+ release: async () => {
63
+ try {
64
+ if (existsSync(paths.pidFile)) {
65
+ const recorded = readPidStrict(paths.pidFile);
66
+ if (recorded === ourPid)
67
+ unlinkSync(paths.pidFile);
68
+ }
69
+ }
70
+ catch {
71
+ /* best-effort cleanup */
72
+ }
73
+ try {
74
+ await release();
75
+ }
76
+ catch {
77
+ /* lockfile already released or removed */
78
+ }
79
+ },
80
+ };
81
+ }
82
+ function readPidIfAlive(pidFile) {
83
+ if (!existsSync(pidFile))
84
+ return null;
85
+ let raw;
86
+ try {
87
+ raw = readFileSync(pidFile, "utf8").trim();
88
+ }
89
+ catch {
90
+ return null;
91
+ }
92
+ const pid = Number(raw);
93
+ if (!Number.isFinite(pid) || pid <= 0)
94
+ return null;
95
+ try {
96
+ process.kill(pid, 0);
97
+ return pid;
98
+ }
99
+ catch {
100
+ return null;
101
+ }
102
+ }
103
+ function isLockHeldError(err) {
104
+ if (!(err instanceof Error))
105
+ return false;
106
+ const code = err.code;
107
+ if (code === "ELOCKED")
108
+ return true;
109
+ return /lock file is already being held/i.test(err.message);
110
+ }
111
+ function readPidStrict(pidFile) {
112
+ try {
113
+ const pid = Number(readFileSync(pidFile, "utf8").trim());
114
+ return Number.isFinite(pid) && pid > 0 ? pid : null;
115
+ }
116
+ catch {
117
+ return null;
118
+ }
119
+ }
120
+ //# sourceMappingURL=lockfile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lockfile.js","sourceRoot":"","sources":["../../../src/pty/host-daemon/lockfile.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,77 @@
1
+ export type AppStateMode = "in-process" | "daemon";
2
+ export interface ModeMarker {
3
+ mode: AppStateMode;
4
+ pid: number;
5
+ startedAt: string;
6
+ hostname: string;
7
+ }
8
+ export declare class AppStateOwnerConflictError extends Error {
9
+ readonly currentMode: AppStateMode;
10
+ readonly existing: ModeMarker | null;
11
+ readonly markerFile: string;
12
+ constructor(currentMode: AppStateMode, existing: ModeMarker | null, markerFile: string);
13
+ }
14
+ export interface AppStateOwner {
15
+ marker: ModeMarker;
16
+ release: () => Promise<void>;
17
+ }
18
+ /**
19
+ * Read and parse the marker file body. Returns null when the file does
20
+ * not exist or is malformed. Body is purely informational -- readers
21
+ * MUST NOT use it as a mutex; the proper-lockfile lock on the same
22
+ * path is what serialises ownership.
23
+ */
24
+ export declare function readMarker(markerFile: string): ModeMarker | null;
25
+ /**
26
+ * Write the marker body. Caller MUST already hold the proper-lockfile
27
+ * advisory lock on `markerFile` (see `acquireAppStateOwnership`).
28
+ */
29
+ export declare function writeMarker(markerFile: string, mode: AppStateMode, pid?: number, startedAt?: string, hostname?: string): ModeMarker;
30
+ /** Best-effort delete; not an error if the file is already gone. */
31
+ export declare function unlinkMarker(markerFile: string): void;
32
+ /**
33
+ * Liveness probe via `process.kill(pid, 0)`. Used only to enrich the
34
+ * conflict error -- the proper-lockfile hold is the source of truth for
35
+ * whether the recorded owner is still alive.
36
+ */
37
+ export declare function isPidAlive(pid: number): boolean;
38
+ /**
39
+ * Conventional marker location: the AppState dir (i.e. the directory
40
+ * that holds `state.json`). Co-locating with state.json -- rather than
41
+ * the daemon runtime dir -- means any process that opens this state.json
42
+ * passes through the same marker file, which is the actual mutual-
43
+ * exclusion target. The daemon runtime dir varies with `XDG_RUNTIME_DIR`
44
+ * / `PARASOR_PTY_SOCK` overrides, so an in-process server with a custom
45
+ * `PARASOR_CONFIG_DIR` and a daemon with a custom `XDG_RUNTIME_DIR`
46
+ * could otherwise both write the same `state.json` undetected.
47
+ */
48
+ export declare function markerFileFor(appStateDir: string): string;
49
+ interface AcquireOptions {
50
+ pid?: number;
51
+ startedAt?: string;
52
+ hostname?: string;
53
+ /** Test seam -- production callers always use proper-lockfile defaults. */
54
+ retries?: number;
55
+ }
56
+ /**
57
+ * Acquire exclusive ownership of the AppState directory. On success
58
+ * returns an `AppStateOwner` whose `release()` MUST be called from the
59
+ * graceful-shutdown path. The lock is held until release; long-running
60
+ * owners are kept alive by proper-lockfile's mtime refresh interval
61
+ * (default `stale/2 = 30s`).
62
+ *
63
+ * `proper-lockfile.lock()` is the *sole* mutex (mirrors
64
+ * `host-daemon/lockfile.ts`'s decision for the daemon runtime lock).
65
+ * The marker file body is purely informational -- populated for
66
+ * `AppStateOwnerConflictError` diagnostics, NOT cross-validated post-
67
+ * acquisition. a post-flock `kill(pid, 0)` recheck
68
+ * spuriously rejects legitimate stale takeover when the OS has
69
+ * recycled the prior owner's PID to an unrelated live process during
70
+ * the 60s stale window. The daemon lockfile path documents the same
71
+ * choice ("flock acquired: we own the runtime dir … do NOT recheck …
72
+ * because a stale pid that has been recycled by an unrelated live
73
+ * process would otherwise block legitimate takeover").
74
+ */
75
+ export declare function acquireAppStateOwnership(markerFile: string, currentMode: AppStateMode, opts?: AcquireOptions): Promise<AppStateOwner>;
76
+ export {};
77
+ //# sourceMappingURL=mode-marker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mode-marker.d.ts","sourceRoot":"","sources":["../../../src/pty/host-daemon/mode-marker.ts"],"names":[],"mappings":"AA+BA,MAAM,MAAM,YAAY,GAAG,YAAY,GAAG,QAAQ,CAAC;AAEnD,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,YAAY,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,0BAA2B,SAAQ,KAAK;IAEjD,QAAQ,CAAC,WAAW,EAAE,YAAY;IAClC,QAAQ,CAAC,QAAQ,EAAE,UAAU,GAAG,IAAI;IACpC,QAAQ,CAAC,UAAU,EAAE,MAAM;gBAFlB,WAAW,EAAE,YAAY,EACzB,QAAQ,EAAE,UAAU,GAAG,IAAI,EAC3B,UAAU,EAAE,MAAM;CAY9B;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,UAAU,CAAC;IACnB,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAkBhE;AAED;;;GAGG;AACH,wBAAgB,WAAW,CACzB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,YAAY,EAClB,GAAG,GAAE,MAAoB,EACzB,SAAS,GAAE,MAAiC,EAC5C,QAAQ,GAAE,MAAqB,GAC9B,UAAU,CAIZ;AAED,oEAAoE;AACpE,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAMrD;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAc/C;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED,UAAU,cAAc;IACtB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2EAA2E;IAC3E,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,wBAAwB,CAC5C,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,YAAY,EACzB,IAAI,GAAE,cAAmB,GACxB,OAAO,CAAC,aAAa,CAAC,CAiFxB"}
@@ -0,0 +1,228 @@
1
+ /*
2
+ * -- cross-mode mutual exclusion ownership lock.
3
+ *
4
+ * Both runtime modes (in-process server / daemon) write to the same
5
+ * AppStateStore on disk. If both run concurrently against the same
6
+ * runtime dir they corrupt each other's view. This module acquires an
7
+ * exclusive `proper-lockfile` advisory lock on a marker file next to
8
+ * `state.json` and holds it for the lifetime of the owning process.
9
+ *
10
+ * Design parallels `host-daemon/lockfile.ts`:
11
+ * - `proper-lockfile` is the *sole* mutex (kernel-backed via
12
+ * graceful-fs's atomic mkdir of `<marker>.lock`/). Held across the
13
+ * owner's whole lifetime; released via `AppStateOwner.release()` on
14
+ * graceful shutdown or by stale-timeout (60s) if the holder dies.
15
+ * - The marker file body is purely informational -- humans (and a
16
+ * future `parasor doctor`) read it to see who owns the dir; the
17
+ * conflict error pretty-prints those fields. Body content cannot
18
+ * vote against the lockfile decision.
19
+ * - PID liveness (`process.kill(pid, 0)`) is consulted only to
20
+ * populate `AppStateOwnerConflictError` for nicer messages.
21
+ *
22
+ * Wire format: a single TSV line `mode\tpid\tstartedAt\thostname`. TSV
23
+ * keeps the file shell-readable during incident response (`cat
24
+ * appstate.mode`). The parser rejects lines that don't match the
25
+ * 4-field shape.
26
+ */
27
+ import { existsSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
28
+ import { hostname as osHostname } from "node:os";
29
+ import lockfile from "proper-lockfile";
30
+ export class AppStateOwnerConflictError extends Error {
31
+ currentMode;
32
+ existing;
33
+ markerFile;
34
+ constructor(currentMode, existing, markerFile) {
35
+ const tail = existing !== null
36
+ ? `${existing.mode} mode (pid=${existing.pid}, host=${existing.hostname}, started=${existing.startedAt})`
37
+ : "an unidentified owner (lockfile held but marker body unreadable)";
38
+ super(`appstate is owned by ${tail}; refusing to start ${currentMode} mode against the same runtime dir. ` +
39
+ `Marker file: ${markerFile}`);
40
+ this.currentMode = currentMode;
41
+ this.existing = existing;
42
+ this.markerFile = markerFile;
43
+ this.name = "AppStateOwnerConflictError";
44
+ }
45
+ }
46
+ /**
47
+ * Read and parse the marker file body. Returns null when the file does
48
+ * not exist or is malformed. Body is purely informational -- readers
49
+ * MUST NOT use it as a mutex; the proper-lockfile lock on the same
50
+ * path is what serialises ownership.
51
+ */
52
+ export function readMarker(markerFile) {
53
+ if (!existsSync(markerFile))
54
+ return null;
55
+ let raw;
56
+ try {
57
+ raw = readFileSync(markerFile, "utf8");
58
+ }
59
+ catch {
60
+ return null;
61
+ }
62
+ const line = raw.split(/\r?\n/)[0] ?? "";
63
+ const fields = line.split("\t");
64
+ if (fields.length !== 4)
65
+ return null;
66
+ const [mode, pidStr, startedAt, hostname] = fields;
67
+ if (mode !== "in-process" && mode !== "daemon")
68
+ return null;
69
+ const pid = Number(pidStr);
70
+ if (!Number.isFinite(pid) || pid <= 0)
71
+ return null;
72
+ if (typeof startedAt !== "string" || startedAt.length === 0)
73
+ return null;
74
+ if (typeof hostname !== "string" || hostname.length === 0)
75
+ return null;
76
+ return { mode, pid, startedAt, hostname };
77
+ }
78
+ /**
79
+ * Write the marker body. Caller MUST already hold the proper-lockfile
80
+ * advisory lock on `markerFile` (see `acquireAppStateOwnership`).
81
+ */
82
+ export function writeMarker(markerFile, mode, pid = process.pid, startedAt = new Date().toISOString(), hostname = osHostname()) {
83
+ const line = `${mode}\t${pid}\t${startedAt}\t${hostname}\n`;
84
+ writeFileSync(markerFile, line, { encoding: "utf8", mode: 0o600 });
85
+ return { mode, pid, startedAt, hostname };
86
+ }
87
+ /** Best-effort delete; not an error if the file is already gone. */
88
+ export function unlinkMarker(markerFile) {
89
+ try {
90
+ if (existsSync(markerFile))
91
+ unlinkSync(markerFile);
92
+ }
93
+ catch {
94
+ /* leave-on-error */
95
+ }
96
+ }
97
+ /**
98
+ * Liveness probe via `process.kill(pid, 0)`. Used only to enrich the
99
+ * conflict error -- the proper-lockfile hold is the source of truth for
100
+ * whether the recorded owner is still alive.
101
+ */
102
+ export function isPidAlive(pid) {
103
+ if (!Number.isFinite(pid) || pid <= 0)
104
+ return false;
105
+ try {
106
+ process.kill(pid, 0);
107
+ return true;
108
+ }
109
+ catch (err) {
110
+ /*
111
+ * EPERM = PID exists but belongs to another user. From this
112
+ * module's standpoint that is "alive" because the runtime dir is
113
+ * per-user -- another user's PID inside our home dir would be a
114
+ * permissions misconfiguration we should not paper over.
115
+ */
116
+ return err.code === "EPERM";
117
+ }
118
+ }
119
+ /**
120
+ * Conventional marker location: the AppState dir (i.e. the directory
121
+ * that holds `state.json`). Co-locating with state.json -- rather than
122
+ * the daemon runtime dir -- means any process that opens this state.json
123
+ * passes through the same marker file, which is the actual mutual-
124
+ * exclusion target. The daemon runtime dir varies with `XDG_RUNTIME_DIR`
125
+ * / `PARASOR_PTY_SOCK` overrides, so an in-process server with a custom
126
+ * `PARASOR_CONFIG_DIR` and a daemon with a custom `XDG_RUNTIME_DIR`
127
+ * could otherwise both write the same `state.json` undetected.
128
+ */
129
+ export function markerFileFor(appStateDir) {
130
+ return `${appStateDir}/appstate.mode`;
131
+ }
132
+ /**
133
+ * Acquire exclusive ownership of the AppState directory. On success
134
+ * returns an `AppStateOwner` whose `release()` MUST be called from the
135
+ * graceful-shutdown path. The lock is held until release; long-running
136
+ * owners are kept alive by proper-lockfile's mtime refresh interval
137
+ * (default `stale/2 = 30s`).
138
+ *
139
+ * `proper-lockfile.lock()` is the *sole* mutex (mirrors
140
+ * `host-daemon/lockfile.ts`'s decision for the daemon runtime lock).
141
+ * The marker file body is purely informational -- populated for
142
+ * `AppStateOwnerConflictError` diagnostics, NOT cross-validated post-
143
+ * acquisition. a post-flock `kill(pid, 0)` recheck
144
+ * spuriously rejects legitimate stale takeover when the OS has
145
+ * recycled the prior owner's PID to an unrelated live process during
146
+ * the 60s stale window. The daemon lockfile path documents the same
147
+ * choice ("flock acquired: we own the runtime dir … do NOT recheck …
148
+ * because a stale pid that has been recycled by an unrelated live
149
+ * process would otherwise block legitimate takeover").
150
+ */
151
+ export async function acquireAppStateOwnership(markerFile, currentMode, opts = {}) {
152
+ const ourPid = opts.pid ?? process.pid;
153
+ const startedAt = opts.startedAt ?? new Date().toISOString();
154
+ const hostname = opts.hostname ?? osHostname();
155
+ /*
156
+ * `proper-lockfile.lock()` resolves the file's realpath and stats it,
157
+ * so the marker file must already exist. Touch an empty file when
158
+ * none is present; the body is overwritten further down once we own
159
+ * the lock. Same pattern as `host-daemon/lockfile.ts`.
160
+ */
161
+ if (!existsSync(markerFile)) {
162
+ writeFileSync(markerFile, "", { mode: 0o600 });
163
+ }
164
+ let release;
165
+ try {
166
+ release = await lockfile.lock(markerFile, {
167
+ stale: 60_000,
168
+ retries: opts.retries ?? 0,
169
+ });
170
+ }
171
+ catch (err) {
172
+ if (isLockHeldError(err)) {
173
+ const existing = readMarker(markerFile);
174
+ throw new AppStateOwnerConflictError(currentMode, existing, markerFile);
175
+ }
176
+ throw err;
177
+ }
178
+ // Lock acquired: we own the AppState dir. Stamp the marker body for
179
+ // diagnostics (`parasor doctor`, incident response). Stale body
180
+ // content from a previous owner is overwritten unconditionally --
181
+ // proper-lockfile already decided that owner is gone.
182
+ const marker = writeMarker(markerFile, currentMode, ourPid, startedAt, hostname);
183
+ return {
184
+ marker,
185
+ release: async () => {
186
+ /*
187
+ * Owner-verified body unlink (reviewed for correctness): only delete the
188
+ * marker body if it still names *us*. A previous owner whose
189
+ * lock got stale-stolen could otherwise unlink the new owner's
190
+ * body during a delayed shutdown handler. Same pattern as the
191
+ * daemon pidfile cleanup in `host-daemon/lockfile.ts`.
192
+ */
193
+ try {
194
+ const recorded = readMarker(markerFile);
195
+ if (recorded !== null &&
196
+ recorded.pid === ourPid &&
197
+ recorded.startedAt === startedAt) {
198
+ unlinkMarker(markerFile);
199
+ }
200
+ }
201
+ catch {
202
+ /* best-effort body cleanup */
203
+ }
204
+ try {
205
+ await release();
206
+ }
207
+ catch (err) {
208
+ /*
209
+ * surface release failure to stderr so a
210
+ * leftover `<marker>.lock/` directory after a crashy shutdown
211
+ * is observable. proper-lockfile's stale-timeout (60s) makes
212
+ * the next boot self-recover, but the operator still wants to
213
+ * know.
214
+ */
215
+ console.error(`[mode-marker] release error for ${markerFile}: ${err.message}`);
216
+ }
217
+ },
218
+ };
219
+ }
220
+ function isLockHeldError(err) {
221
+ if (!(err instanceof Error))
222
+ return false;
223
+ const code = err.code;
224
+ if (code === "ELOCKED")
225
+ return true;
226
+ return /lock file is already being held/i.test(err.message);
227
+ }
228
+ //# sourceMappingURL=mode-marker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mode-marker.js","sourceRoot":"","sources":["../../../src/pty/host-daemon/mode-marker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ import type { SessionRecord } from "@parasor/shared";
2
+ export type OrphanReconcileTransition = {
3
+ type: "kept";
4
+ id: string;
5
+ } | {
6
+ type: "orphaned";
7
+ id: string;
8
+ previousDaemonPid: number;
9
+ } | {
10
+ type: "lost";
11
+ id: string;
12
+ reason: "no-pid" | "dead-pid";
13
+ };
14
+ export interface OrphanReconcileResult {
15
+ /** Snapshots after reconciliation, in input order. */
16
+ records: SessionRecord[];
17
+ /** Per-id transition summary (helpful for logging / tests). */
18
+ transitions: OrphanReconcileTransition[];
19
+ }
20
+ export interface ReconcileOpts {
21
+ currentDaemonPid: number;
22
+ /**
23
+ * ISO8601 timestamp of *this* daemon's start. Combined with
24
+ * `currentDaemonPid` to form the writer-generation tuple -- a record
25
+ * with a matching pid but a stale `daemonStartedAt` is treated as
26
+ * orphaned, defending against PID recycling between daemon restarts
27
+ * (reviewed for correctness). Required for correctness; an undefined value
28
+ * would silently degrade to PID-only matching.
29
+ */
30
+ currentDaemonStartedAt: string;
31
+ /** Liveness probe; defaults to `process.kill(pid, 0)`. Test seam. */
32
+ isPidAlive?: (pid: number) => boolean;
33
+ }
34
+ /**
35
+ * Pure function -- no side effects. Caller is responsible for persisting
36
+ * the resulting array via `AppStateStore.internalMutate`.
37
+ *
38
+ * Already-terminal records (state in {exited,lost,orphaned}) are passed
39
+ * through unchanged. Only `state === "running"` records are evaluated.
40
+ */
41
+ export declare function reconcileSessionRecords(input: readonly SessionRecord[], opts: ReconcileOpts): OrphanReconcileResult;
42
+ //# sourceMappingURL=orphan-cleanup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orphan-cleanup.d.ts","sourceRoot":"","sources":["../../../src/pty/host-daemon/orphan-cleanup.ts"],"names":[],"mappings":"AAgCA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD,MAAM,MAAM,yBAAyB,GACjC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAC5B;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,iBAAiB,EAAE,MAAM,CAAA;CAAE,GAC3D;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,QAAQ,GAAG,UAAU,CAAA;CAAE,CAAC;AAEhE,MAAM,WAAW,qBAAqB;IACpC,sDAAsD;IACtD,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,+DAA+D;IAC/D,WAAW,EAAE,yBAAyB,EAAE,CAAC;CAC1C;AAED,MAAM,WAAW,aAAa;IAC5B,gBAAgB,EAAE,MAAM,CAAC;IACzB;;;;;;;OAOG;IACH,sBAAsB,EAAE,MAAM,CAAC;IAC/B,qEAAqE;IACrE,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;CACvC;AAYD;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,SAAS,aAAa,EAAE,EAC/B,IAAI,EAAE,aAAa,GAClB,qBAAqB,CAyCvB"}