@jacques-ai/server 0.0.7-alpha.1

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 (384) hide show
  1. package/dist/config/config.d.ts +34 -0
  2. package/dist/config/config.d.ts.map +1 -0
  3. package/dist/config/config.js +32 -0
  4. package/dist/config/config.js.map +1 -0
  5. package/dist/connection/applescript.d.ts +46 -0
  6. package/dist/connection/applescript.d.ts.map +1 -0
  7. package/dist/connection/applescript.js +62 -0
  8. package/dist/connection/applescript.js.map +1 -0
  9. package/dist/connection/applescript.test.d.ts +5 -0
  10. package/dist/connection/applescript.test.d.ts.map +1 -0
  11. package/dist/connection/applescript.test.js +64 -0
  12. package/dist/connection/applescript.test.js.map +1 -0
  13. package/dist/connection/constants.d.ts +88 -0
  14. package/dist/connection/constants.d.ts.map +1 -0
  15. package/dist/connection/constants.js +110 -0
  16. package/dist/connection/constants.js.map +1 -0
  17. package/dist/connection/git-info.d.ts +30 -0
  18. package/dist/connection/git-info.d.ts.map +1 -0
  19. package/dist/connection/git-info.js +52 -0
  20. package/dist/connection/git-info.js.map +1 -0
  21. package/dist/connection/git-info.test.d.ts +5 -0
  22. package/dist/connection/git-info.test.d.ts.map +1 -0
  23. package/dist/connection/git-info.test.js +35 -0
  24. package/dist/connection/git-info.test.js.map +1 -0
  25. package/dist/connection/index.d.ts +19 -0
  26. package/dist/connection/index.d.ts.map +1 -0
  27. package/dist/connection/index.js +36 -0
  28. package/dist/connection/index.js.map +1 -0
  29. package/dist/connection/process-detection.d.ts +58 -0
  30. package/dist/connection/process-detection.d.ts.map +1 -0
  31. package/dist/connection/process-detection.js +239 -0
  32. package/dist/connection/process-detection.js.map +1 -0
  33. package/dist/connection/process-detection.test.d.ts +5 -0
  34. package/dist/connection/process-detection.test.d.ts.map +1 -0
  35. package/dist/connection/process-detection.test.js +43 -0
  36. package/dist/connection/process-detection.test.js.map +1 -0
  37. package/dist/connection/session-discovery.d.ts +55 -0
  38. package/dist/connection/session-discovery.d.ts.map +1 -0
  39. package/dist/connection/session-discovery.js +311 -0
  40. package/dist/connection/session-discovery.js.map +1 -0
  41. package/dist/connection/terminal-key.d.ts +126 -0
  42. package/dist/connection/terminal-key.d.ts.map +1 -0
  43. package/dist/connection/terminal-key.js +271 -0
  44. package/dist/connection/terminal-key.js.map +1 -0
  45. package/dist/connection/terminal-key.test.d.ts +5 -0
  46. package/dist/connection/terminal-key.test.d.ts.map +1 -0
  47. package/dist/connection/terminal-key.test.js +221 -0
  48. package/dist/connection/terminal-key.test.js.map +1 -0
  49. package/dist/connection/worktree.d.ts +114 -0
  50. package/dist/connection/worktree.d.ts.map +1 -0
  51. package/dist/connection/worktree.js +320 -0
  52. package/dist/connection/worktree.js.map +1 -0
  53. package/dist/connection/worktree.test.d.ts +5 -0
  54. package/dist/connection/worktree.test.d.ts.map +1 -0
  55. package/dist/connection/worktree.test.js +113 -0
  56. package/dist/connection/worktree.test.js.map +1 -0
  57. package/dist/focus-watcher.d.ts +51 -0
  58. package/dist/focus-watcher.d.ts.map +1 -0
  59. package/dist/focus-watcher.js +169 -0
  60. package/dist/focus-watcher.js.map +1 -0
  61. package/dist/handlers/event-handler.d.ts +93 -0
  62. package/dist/handlers/event-handler.d.ts.map +1 -0
  63. package/dist/handlers/event-handler.js +196 -0
  64. package/dist/handlers/event-handler.js.map +1 -0
  65. package/dist/handlers/event-handler.test.d.ts +5 -0
  66. package/dist/handlers/event-handler.test.d.ts.map +1 -0
  67. package/dist/handlers/event-handler.test.js +305 -0
  68. package/dist/handlers/event-handler.test.js.map +1 -0
  69. package/dist/handlers/session-handler.d.ts +23 -0
  70. package/dist/handlers/session-handler.d.ts.map +1 -0
  71. package/dist/handlers/session-handler.js +104 -0
  72. package/dist/handlers/session-handler.js.map +1 -0
  73. package/dist/handlers/session-handler.test.d.ts +5 -0
  74. package/dist/handlers/session-handler.test.d.ts.map +1 -0
  75. package/dist/handlers/session-handler.test.js +89 -0
  76. package/dist/handlers/session-handler.test.js.map +1 -0
  77. package/dist/handlers/settings-handler.d.ts +32 -0
  78. package/dist/handlers/settings-handler.d.ts.map +1 -0
  79. package/dist/handlers/settings-handler.js +127 -0
  80. package/dist/handlers/settings-handler.js.map +1 -0
  81. package/dist/handlers/settings-handler.test.d.ts +5 -0
  82. package/dist/handlers/settings-handler.test.d.ts.map +1 -0
  83. package/dist/handlers/settings-handler.test.js +105 -0
  84. package/dist/handlers/settings-handler.test.js.map +1 -0
  85. package/dist/handlers/window-handler.d.ts +30 -0
  86. package/dist/handlers/window-handler.d.ts.map +1 -0
  87. package/dist/handlers/window-handler.js +486 -0
  88. package/dist/handlers/window-handler.js.map +1 -0
  89. package/dist/handlers/window-handler.test.d.ts +8 -0
  90. package/dist/handlers/window-handler.test.d.ts.map +1 -0
  91. package/dist/handlers/window-handler.test.js +167 -0
  92. package/dist/handlers/window-handler.test.js.map +1 -0
  93. package/dist/handlers/worktree-handler.d.ts +28 -0
  94. package/dist/handlers/worktree-handler.d.ts.map +1 -0
  95. package/dist/handlers/worktree-handler.js +268 -0
  96. package/dist/handlers/worktree-handler.js.map +1 -0
  97. package/dist/handlers/worktree-handler.test.d.ts +8 -0
  98. package/dist/handlers/worktree-handler.test.d.ts.map +1 -0
  99. package/dist/handlers/worktree-handler.test.js +118 -0
  100. package/dist/handlers/worktree-handler.test.js.map +1 -0
  101. package/dist/handlers/ws-utils.d.ts +12 -0
  102. package/dist/handlers/ws-utils.d.ts.map +1 -0
  103. package/dist/handlers/ws-utils.js +16 -0
  104. package/dist/handlers/ws-utils.js.map +1 -0
  105. package/dist/http-api.d.ts +26 -0
  106. package/dist/http-api.d.ts.map +1 -0
  107. package/dist/http-api.js +148 -0
  108. package/dist/http-api.js.map +1 -0
  109. package/dist/logger.d.ts +42 -0
  110. package/dist/logger.d.ts.map +1 -0
  111. package/dist/logger.js +147 -0
  112. package/dist/logger.js.map +1 -0
  113. package/dist/logging/logger-factory.d.ts +51 -0
  114. package/dist/logging/logger-factory.d.ts.map +1 -0
  115. package/dist/logging/logger-factory.js +59 -0
  116. package/dist/logging/logger-factory.js.map +1 -0
  117. package/dist/mcp/search-tool.d.ts +65 -0
  118. package/dist/mcp/search-tool.d.ts.map +1 -0
  119. package/dist/mcp/search-tool.js +176 -0
  120. package/dist/mcp/search-tool.js.map +1 -0
  121. package/dist/mcp/server.d.ts +9 -0
  122. package/dist/mcp/server.d.ts.map +1 -0
  123. package/dist/mcp/server.js +152 -0
  124. package/dist/mcp/server.js.map +1 -0
  125. package/dist/process-scanner.d.ts +96 -0
  126. package/dist/process-scanner.d.ts.map +1 -0
  127. package/dist/process-scanner.js +194 -0
  128. package/dist/process-scanner.js.map +1 -0
  129. package/dist/routes/__tests__/archive-routes.test.d.ts +5 -0
  130. package/dist/routes/__tests__/archive-routes.test.d.ts.map +1 -0
  131. package/dist/routes/__tests__/archive-routes.test.js +158 -0
  132. package/dist/routes/__tests__/archive-routes.test.js.map +1 -0
  133. package/dist/routes/__tests__/config-routes.test.d.ts +5 -0
  134. package/dist/routes/__tests__/config-routes.test.d.ts.map +1 -0
  135. package/dist/routes/__tests__/config-routes.test.js +112 -0
  136. package/dist/routes/__tests__/config-routes.test.js.map +1 -0
  137. package/dist/routes/__tests__/http-utils.test.d.ts +5 -0
  138. package/dist/routes/__tests__/http-utils.test.d.ts.map +1 -0
  139. package/dist/routes/__tests__/http-utils.test.js +102 -0
  140. package/dist/routes/__tests__/http-utils.test.js.map +1 -0
  141. package/dist/routes/__tests__/notification-routes.test.d.ts +5 -0
  142. package/dist/routes/__tests__/notification-routes.test.d.ts.map +1 -0
  143. package/dist/routes/__tests__/notification-routes.test.js +91 -0
  144. package/dist/routes/__tests__/notification-routes.test.js.map +1 -0
  145. package/dist/routes/__tests__/project-routes.test.d.ts +5 -0
  146. package/dist/routes/__tests__/project-routes.test.d.ts.map +1 -0
  147. package/dist/routes/__tests__/project-routes.test.js +168 -0
  148. package/dist/routes/__tests__/project-routes.test.js.map +1 -0
  149. package/dist/routes/__tests__/session-routes.test.d.ts +5 -0
  150. package/dist/routes/__tests__/session-routes.test.d.ts.map +1 -0
  151. package/dist/routes/__tests__/session-routes.test.js +198 -0
  152. package/dist/routes/__tests__/session-routes.test.js.map +1 -0
  153. package/dist/routes/__tests__/source-routes.test.d.ts +5 -0
  154. package/dist/routes/__tests__/source-routes.test.d.ts.map +1 -0
  155. package/dist/routes/__tests__/source-routes.test.js +142 -0
  156. package/dist/routes/__tests__/source-routes.test.js.map +1 -0
  157. package/dist/routes/__tests__/sync-routes.test.d.ts +5 -0
  158. package/dist/routes/__tests__/sync-routes.test.d.ts.map +1 -0
  159. package/dist/routes/__tests__/sync-routes.test.js +77 -0
  160. package/dist/routes/__tests__/sync-routes.test.js.map +1 -0
  161. package/dist/routes/__tests__/test-helpers.d.ts +47 -0
  162. package/dist/routes/__tests__/test-helpers.d.ts.map +1 -0
  163. package/dist/routes/__tests__/test-helpers.js +97 -0
  164. package/dist/routes/__tests__/test-helpers.js.map +1 -0
  165. package/dist/routes/archive-routes.d.ts +15 -0
  166. package/dist/routes/archive-routes.d.ts.map +1 -0
  167. package/dist/routes/archive-routes.js +181 -0
  168. package/dist/routes/archive-routes.js.map +1 -0
  169. package/dist/routes/claude-routes.d.ts +9 -0
  170. package/dist/routes/claude-routes.d.ts.map +1 -0
  171. package/dist/routes/claude-routes.js +47 -0
  172. package/dist/routes/claude-routes.js.map +1 -0
  173. package/dist/routes/config-routes.d.ts +9 -0
  174. package/dist/routes/config-routes.d.ts.map +1 -0
  175. package/dist/routes/config-routes.js +56 -0
  176. package/dist/routes/config-routes.js.map +1 -0
  177. package/dist/routes/config-store.d.ts +41 -0
  178. package/dist/routes/config-store.d.ts.map +1 -0
  179. package/dist/routes/config-store.js +52 -0
  180. package/dist/routes/config-store.js.map +1 -0
  181. package/dist/routes/http-utils.d.ts +32 -0
  182. package/dist/routes/http-utils.d.ts.map +1 -0
  183. package/dist/routes/http-utils.js +123 -0
  184. package/dist/routes/http-utils.js.map +1 -0
  185. package/dist/routes/index.d.ts +19 -0
  186. package/dist/routes/index.d.ts.map +1 -0
  187. package/dist/routes/index.js +17 -0
  188. package/dist/routes/index.js.map +1 -0
  189. package/dist/routes/notification-routes.d.ts +10 -0
  190. package/dist/routes/notification-routes.d.ts.map +1 -0
  191. package/dist/routes/notification-routes.js +64 -0
  192. package/dist/routes/notification-routes.js.map +1 -0
  193. package/dist/routes/project-routes.d.ts +22 -0
  194. package/dist/routes/project-routes.d.ts.map +1 -0
  195. package/dist/routes/project-routes.js +415 -0
  196. package/dist/routes/project-routes.js.map +1 -0
  197. package/dist/routes/session-routes.d.ts +18 -0
  198. package/dist/routes/session-routes.d.ts.map +1 -0
  199. package/dist/routes/session-routes.js +609 -0
  200. package/dist/routes/session-routes.js.map +1 -0
  201. package/dist/routes/source-routes.d.ts +12 -0
  202. package/dist/routes/source-routes.d.ts.map +1 -0
  203. package/dist/routes/source-routes.js +119 -0
  204. package/dist/routes/source-routes.js.map +1 -0
  205. package/dist/routes/static-routes.d.ts +12 -0
  206. package/dist/routes/static-routes.d.ts.map +1 -0
  207. package/dist/routes/static-routes.js +52 -0
  208. package/dist/routes/static-routes.js.map +1 -0
  209. package/dist/routes/sync-routes.d.ts +9 -0
  210. package/dist/routes/sync-routes.d.ts.map +1 -0
  211. package/dist/routes/sync-routes.js +78 -0
  212. package/dist/routes/sync-routes.js.map +1 -0
  213. package/dist/routes/tile-routes.d.ts +10 -0
  214. package/dist/routes/tile-routes.d.ts.map +1 -0
  215. package/dist/routes/tile-routes.js +108 -0
  216. package/dist/routes/tile-routes.js.map +1 -0
  217. package/dist/routes/types.d.ts +17 -0
  218. package/dist/routes/types.d.ts.map +1 -0
  219. package/dist/routes/types.js +5 -0
  220. package/dist/routes/types.js.map +1 -0
  221. package/dist/routes/usage-routes.d.ts +8 -0
  222. package/dist/routes/usage-routes.d.ts.map +1 -0
  223. package/dist/routes/usage-routes.js +18 -0
  224. package/dist/routes/usage-routes.js.map +1 -0
  225. package/dist/server.d.ts +8 -0
  226. package/dist/server.d.ts.map +1 -0
  227. package/dist/server.js +173 -0
  228. package/dist/server.js.map +1 -0
  229. package/dist/services/branch-divergence-service.d.ts +48 -0
  230. package/dist/services/branch-divergence-service.d.ts.map +1 -0
  231. package/dist/services/branch-divergence-service.js +156 -0
  232. package/dist/services/branch-divergence-service.js.map +1 -0
  233. package/dist/services/broadcast-service.d.ts +68 -0
  234. package/dist/services/broadcast-service.d.ts.map +1 -0
  235. package/dist/services/broadcast-service.js +78 -0
  236. package/dist/services/broadcast-service.js.map +1 -0
  237. package/dist/services/broadcast-service.test.d.ts +5 -0
  238. package/dist/services/broadcast-service.test.d.ts.map +1 -0
  239. package/dist/services/broadcast-service.test.js +130 -0
  240. package/dist/services/broadcast-service.test.js.map +1 -0
  241. package/dist/services/chat-service.d.ts +72 -0
  242. package/dist/services/chat-service.d.ts.map +1 -0
  243. package/dist/services/chat-service.js +342 -0
  244. package/dist/services/chat-service.js.map +1 -0
  245. package/dist/services/chat-system-prompt.d.ts +14 -0
  246. package/dist/services/chat-system-prompt.d.ts.map +1 -0
  247. package/dist/services/chat-system-prompt.js +68 -0
  248. package/dist/services/chat-system-prompt.js.map +1 -0
  249. package/dist/services/notification-service.d.ts +115 -0
  250. package/dist/services/notification-service.d.ts.map +1 -0
  251. package/dist/services/notification-service.js +424 -0
  252. package/dist/services/notification-service.js.map +1 -0
  253. package/dist/services/notification-service.test.d.ts +5 -0
  254. package/dist/services/notification-service.test.d.ts.map +1 -0
  255. package/dist/services/notification-service.test.js +918 -0
  256. package/dist/services/notification-service.test.js.map +1 -0
  257. package/dist/session/cleanup-service.d.ts +51 -0
  258. package/dist/session/cleanup-service.d.ts.map +1 -0
  259. package/dist/session/cleanup-service.js +98 -0
  260. package/dist/session/cleanup-service.js.map +1 -0
  261. package/dist/session/cleanup-service.test.d.ts +5 -0
  262. package/dist/session/cleanup-service.test.d.ts.map +1 -0
  263. package/dist/session/cleanup-service.test.js +121 -0
  264. package/dist/session/cleanup-service.test.js.map +1 -0
  265. package/dist/session/process-monitor.d.ts +79 -0
  266. package/dist/session/process-monitor.d.ts.map +1 -0
  267. package/dist/session/process-monitor.js +270 -0
  268. package/dist/session/process-monitor.js.map +1 -0
  269. package/dist/session/process-monitor.test.d.ts +5 -0
  270. package/dist/session/process-monitor.test.d.ts.map +1 -0
  271. package/dist/session/process-monitor.test.js +367 -0
  272. package/dist/session/process-monitor.test.js.map +1 -0
  273. package/dist/session/session-factory.d.ts +29 -0
  274. package/dist/session/session-factory.d.ts.map +1 -0
  275. package/dist/session/session-factory.js +123 -0
  276. package/dist/session/session-factory.js.map +1 -0
  277. package/dist/session/session-factory.test.d.ts +5 -0
  278. package/dist/session/session-factory.test.d.ts.map +1 -0
  279. package/dist/session/session-factory.test.js +299 -0
  280. package/dist/session/session-factory.test.js.map +1 -0
  281. package/dist/session-registry.d.ts +168 -0
  282. package/dist/session-registry.d.ts.map +1 -0
  283. package/dist/session-registry.js +626 -0
  284. package/dist/session-registry.js.map +1 -0
  285. package/dist/session-registry.test.d.ts +5 -0
  286. package/dist/session-registry.test.d.ts.map +1 -0
  287. package/dist/session-registry.test.js +582 -0
  288. package/dist/session-registry.test.js.map +1 -0
  289. package/dist/start-server.d.ts +31 -0
  290. package/dist/start-server.d.ts.map +1 -0
  291. package/dist/start-server.js +408 -0
  292. package/dist/start-server.js.map +1 -0
  293. package/dist/terminal-activator.d.ts +29 -0
  294. package/dist/terminal-activator.d.ts.map +1 -0
  295. package/dist/terminal-activator.js +264 -0
  296. package/dist/terminal-activator.js.map +1 -0
  297. package/dist/terminal-activator.test.d.ts +9 -0
  298. package/dist/terminal-activator.test.d.ts.map +1 -0
  299. package/dist/terminal-activator.test.js +95 -0
  300. package/dist/terminal-activator.test.js.map +1 -0
  301. package/dist/terminal-launcher.d.ts +51 -0
  302. package/dist/terminal-launcher.d.ts.map +1 -0
  303. package/dist/terminal-launcher.js +298 -0
  304. package/dist/terminal-launcher.js.map +1 -0
  305. package/dist/terminal-launcher.test.d.ts +8 -0
  306. package/dist/terminal-launcher.test.d.ts.map +1 -0
  307. package/dist/terminal-launcher.test.js +222 -0
  308. package/dist/terminal-launcher.test.js.map +1 -0
  309. package/dist/types.d.ts +796 -0
  310. package/dist/types.d.ts.map +1 -0
  311. package/dist/types.js +15 -0
  312. package/dist/types.js.map +1 -0
  313. package/dist/unix-socket.d.ts +68 -0
  314. package/dist/unix-socket.d.ts.map +1 -0
  315. package/dist/unix-socket.js +180 -0
  316. package/dist/unix-socket.js.map +1 -0
  317. package/dist/usage-limits.d.ts +13 -0
  318. package/dist/usage-limits.d.ts.map +1 -0
  319. package/dist/usage-limits.js +112 -0
  320. package/dist/usage-limits.js.map +1 -0
  321. package/dist/watchers/handoff-watcher.d.ts +74 -0
  322. package/dist/watchers/handoff-watcher.d.ts.map +1 -0
  323. package/dist/watchers/handoff-watcher.js +124 -0
  324. package/dist/watchers/handoff-watcher.js.map +1 -0
  325. package/dist/watchers/handoff-watcher.test.d.ts +8 -0
  326. package/dist/watchers/handoff-watcher.test.d.ts.map +1 -0
  327. package/dist/watchers/handoff-watcher.test.js +142 -0
  328. package/dist/watchers/handoff-watcher.test.js.map +1 -0
  329. package/dist/websocket.d.ts +107 -0
  330. package/dist/websocket.d.ts.map +1 -0
  331. package/dist/websocket.js +268 -0
  332. package/dist/websocket.js.map +1 -0
  333. package/dist/window-manager/index.d.ts +28 -0
  334. package/dist/window-manager/index.d.ts.map +1 -0
  335. package/dist/window-manager/index.js +56 -0
  336. package/dist/window-manager/index.js.map +1 -0
  337. package/dist/window-manager/layouts.d.ts +42 -0
  338. package/dist/window-manager/layouts.d.ts.map +1 -0
  339. package/dist/window-manager/layouts.js +133 -0
  340. package/dist/window-manager/layouts.js.map +1 -0
  341. package/dist/window-manager/linux-manager.d.ts +45 -0
  342. package/dist/window-manager/linux-manager.d.ts.map +1 -0
  343. package/dist/window-manager/linux-manager.js +299 -0
  344. package/dist/window-manager/linux-manager.js.map +1 -0
  345. package/dist/window-manager/macos-manager.d.ts +103 -0
  346. package/dist/window-manager/macos-manager.d.ts.map +1 -0
  347. package/dist/window-manager/macos-manager.js +637 -0
  348. package/dist/window-manager/macos-manager.js.map +1 -0
  349. package/dist/window-manager/smart-layouts.d.ts +116 -0
  350. package/dist/window-manager/smart-layouts.d.ts.map +1 -0
  351. package/dist/window-manager/smart-layouts.js +188 -0
  352. package/dist/window-manager/smart-layouts.js.map +1 -0
  353. package/dist/window-manager/smart-layouts.test.d.ts +8 -0
  354. package/dist/window-manager/smart-layouts.test.d.ts.map +1 -0
  355. package/dist/window-manager/smart-layouts.test.js +311 -0
  356. package/dist/window-manager/smart-layouts.test.js.map +1 -0
  357. package/dist/window-manager/tile-state.d.ts +87 -0
  358. package/dist/window-manager/tile-state.d.ts.map +1 -0
  359. package/dist/window-manager/tile-state.js +136 -0
  360. package/dist/window-manager/tile-state.js.map +1 -0
  361. package/dist/window-manager/tile-state.test.d.ts +8 -0
  362. package/dist/window-manager/tile-state.test.d.ts.map +1 -0
  363. package/dist/window-manager/tile-state.test.js +179 -0
  364. package/dist/window-manager/tile-state.test.js.map +1 -0
  365. package/dist/window-manager/types.d.ts +104 -0
  366. package/dist/window-manager/types.d.ts.map +1 -0
  367. package/dist/window-manager/types.js +8 -0
  368. package/dist/window-manager/types.js.map +1 -0
  369. package/dist/window-manager/windows-manager.d.ts +44 -0
  370. package/dist/window-manager/windows-manager.d.ts.map +1 -0
  371. package/dist/window-manager/windows-manager.js +281 -0
  372. package/dist/window-manager/windows-manager.js.map +1 -0
  373. package/dist/window-manager/windows-manager.test.d.ts +8 -0
  374. package/dist/window-manager/windows-manager.test.d.ts.map +1 -0
  375. package/dist/window-manager/windows-manager.test.js +183 -0
  376. package/dist/window-manager/windows-manager.test.js.map +1 -0
  377. package/gui-dist/assets/index-BmYIHRYe.js +142 -0
  378. package/gui-dist/assets/index-D_N5RH8O.css +1 -0
  379. package/gui-dist/assets/vendor-icons-ByXNrcwf.js +336 -0
  380. package/gui-dist/assets/vendor-markdown-DWPYwU1x.js +22 -0
  381. package/gui-dist/assets/vendor-react-CpILBTDM.js +59 -0
  382. package/gui-dist/index.html +17 -0
  383. package/gui-dist/jacsub.png +0 -0
  384. package/package.json +67 -0
@@ -0,0 +1,270 @@
1
+ /**
2
+ * Process Monitor
3
+ *
4
+ * Handles process verification, bypass detection, and PID management.
5
+ * Extracted from SessionRegistry to separate process-level concerns
6
+ * from session state management.
7
+ */
8
+ import { createLogger } from '../logging/logger-factory.js';
9
+ import { IDLE_TIMEOUT_MS, PROCESS_VERIFY_INTERVAL_MS, } from '../connection/constants.js';
10
+ import { extractPid } from '../connection/terminal-key.js';
11
+ import { isProcessRunning, isProcessBypass, getClaudeProcesses } from '../connection/process-detection.js';
12
+ /** Grace period for newly registered sessions before considering them dead (ms) */
13
+ const NEW_SESSION_GRACE_MS = 60_000; // 60 seconds
14
+ export class ProcessMonitor {
15
+ callbacks;
16
+ processVerifyInterval = null;
17
+ logger;
18
+ // CWDs where a session was launched with --dangerously-skip-permissions
19
+ pendingBypassCwds = new Set();
20
+ constructor(options) {
21
+ this.callbacks = options.callbacks;
22
+ this.logger = options.logger ?? createLogger({ silent: true });
23
+ }
24
+ get log() { return this.logger.log.bind(this.logger); }
25
+ get warn() { return this.logger.warn.bind(this.logger); }
26
+ /**
27
+ * Get PID for a session from any available source.
28
+ * Priority: terminal_key → session.terminal.terminal_pid
29
+ */
30
+ getSessionPid(session) {
31
+ const keyPid = extractPid(session.terminal_key);
32
+ if (keyPid !== null) {
33
+ return keyPid;
34
+ }
35
+ if (session.terminal?.terminal_pid) {
36
+ return session.terminal.terminal_pid;
37
+ }
38
+ return null;
39
+ }
40
+ /**
41
+ * Store terminal_pid on a session if not already known.
42
+ * When a PID is first stored, checks if the process is running with
43
+ * --dangerously-skip-permissions and marks the session accordingly.
44
+ */
45
+ storeTerminalPid(session, terminalPid) {
46
+ if (!terminalPid || terminalPid <= 0)
47
+ return;
48
+ const existingPid = this.getSessionPid(session);
49
+ if (existingPid === null) {
50
+ if (!session.terminal) {
51
+ session.terminal = {
52
+ tty: null,
53
+ terminal_pid: terminalPid,
54
+ term_program: null,
55
+ iterm_session_id: null,
56
+ term_session_id: null,
57
+ kitty_window_id: null,
58
+ wezterm_pane: null,
59
+ vscode_injection: null,
60
+ windowid: null,
61
+ term: null,
62
+ };
63
+ }
64
+ else if (!session.terminal.terminal_pid) {
65
+ session.terminal.terminal_pid = terminalPid;
66
+ }
67
+ this.log(`[Registry] Stored terminal_pid ${terminalPid} for session ${session.session_id}`);
68
+ }
69
+ // Now check if this process is bypass (async, non-blocking)
70
+ if (!session.is_bypass) {
71
+ isProcessBypass(terminalPid).then((bypass) => {
72
+ if (bypass) {
73
+ session.is_bypass = true;
74
+ this.log(`[Registry] Detected bypass from stored PID ${terminalPid} for session ${session.session_id}`);
75
+ }
76
+ }).catch(() => { });
77
+ }
78
+ }
79
+ /**
80
+ * Verify sessions are still valid:
81
+ * 1. Process is still running (checks all PID sources)
82
+ * 2. CWD is not in Trash
83
+ * 3. Session is not idle beyond timeout
84
+ * 4. PID-less sessions cross-referenced against running Claude processes
85
+ */
86
+ async verifyProcesses() {
87
+ const sessionsToRemove = [];
88
+ const pidlessSessions = [];
89
+ const now = Date.now();
90
+ for (const [id, session] of this.callbacks.getAllSessions()) {
91
+ // 1. Check if process is still running
92
+ const pid = this.getSessionPid(session);
93
+ if (pid !== null) {
94
+ const isRunning = await isProcessRunning(pid);
95
+ if (!isRunning) {
96
+ this.log(`[Registry] Process ${pid} no longer running for session ${id}`);
97
+ sessionsToRemove.push(id);
98
+ continue;
99
+ }
100
+ }
101
+ else {
102
+ // Track PID-less sessions for batch process scan
103
+ pidlessSessions.push([id, session]);
104
+ }
105
+ // 2. Check if CWD is in Trash
106
+ if (session.cwd && session.cwd.includes('.Trash')) {
107
+ this.log(`[Registry] CWD in Trash for session ${id}: ${session.cwd}`);
108
+ sessionsToRemove.push(id);
109
+ continue;
110
+ }
111
+ // 3. Check for idle timeout
112
+ if (now - session.last_activity > IDLE_TIMEOUT_MS) {
113
+ const hoursIdle = ((now - session.last_activity) / (1000 * 60 * 60)).toFixed(1);
114
+ this.log(`[Registry] Session ${id} idle for ${hoursIdle}h, marking as stale`);
115
+ sessionsToRemove.push(id);
116
+ continue;
117
+ }
118
+ }
119
+ // 4. Process re-scan for PID-less sessions
120
+ if (pidlessSessions.length > 0) {
121
+ const removeSet = new Set(sessionsToRemove);
122
+ const remainingPidless = pidlessSessions.filter(([id]) => !removeSet.has(id));
123
+ if (remainingPidless.length > 0) {
124
+ await this.verifyPidlessSessions(remainingPidless, sessionsToRemove, now);
125
+ }
126
+ }
127
+ for (const id of sessionsToRemove) {
128
+ this.log(`[Registry] Removing stale/dead session: ${id}`);
129
+ this.callbacks.removeSession(id);
130
+ }
131
+ if (sessionsToRemove.length > 0) {
132
+ this.log(`[Registry] Removed ${sessionsToRemove.length} stale/dead session(s)`);
133
+ }
134
+ }
135
+ /**
136
+ * Verify PID-less sessions by scanning running Claude processes.
137
+ *
138
+ * For sessions without a PID, we can't use `kill -0`. Instead:
139
+ * 1. Enumerate all running Claude processes
140
+ * 2. Exclude PIDs already claimed by verified-alive sessions
141
+ * 3. Match PID-less sessions to unclaimed processes by CWD
142
+ * 4. If matched: enrich session with PID for future fast verification
143
+ * 5. If unmatched: session is dead, mark for removal
144
+ */
145
+ async verifyPidlessSessions(pidlessSessions, sessionsToRemove, now) {
146
+ let processes;
147
+ try {
148
+ processes = await getClaudeProcesses();
149
+ }
150
+ catch (err) {
151
+ // If process enumeration fails, don't remove anything (fail-safe)
152
+ this.warn(`[Registry] Failed to enumerate Claude processes for PID-less verification: ${err}`);
153
+ return;
154
+ }
155
+ // Build set of PIDs already claimed by sessions WITH PIDs
156
+ const claimedPids = new Set();
157
+ for (const [, session] of this.callbacks.getAllSessions()) {
158
+ const pid = this.getSessionPid(session);
159
+ if (pid !== null) {
160
+ claimedPids.add(pid);
161
+ }
162
+ }
163
+ // Build pool of unclaimed processes, indexed by normalized CWD
164
+ const unclaimedByCwd = new Map();
165
+ for (const proc of processes) {
166
+ if (claimedPids.has(proc.pid))
167
+ continue;
168
+ const normalizedCwd = proc.cwd.replace(/\/+$/, '');
169
+ const existing = unclaimedByCwd.get(normalizedCwd) || [];
170
+ existing.push(proc);
171
+ unclaimedByCwd.set(normalizedCwd, existing);
172
+ }
173
+ for (const [id, session] of pidlessSessions) {
174
+ // Grace period: skip sessions registered less than 60s ago
175
+ if (now - session.registered_at < NEW_SESSION_GRACE_MS) {
176
+ this.log(`[Registry] Skipping PID-less session ${id} (within grace period)`);
177
+ continue;
178
+ }
179
+ const sessionCwd = (session.cwd || '').replace(/\/+$/, '');
180
+ const candidates = unclaimedByCwd.get(sessionCwd);
181
+ if (candidates && candidates.length > 0) {
182
+ // Match found — claim the first unclaimed process and enrich with PID
183
+ const matched = candidates.shift();
184
+ if (candidates.length === 0) {
185
+ unclaimedByCwd.delete(sessionCwd);
186
+ }
187
+ this.storeTerminalPid(session, matched.pid);
188
+ claimedPids.add(matched.pid);
189
+ this.log(`[Registry] Enriched PID-less session ${id} with PID ${matched.pid} (matched by CWD: ${sessionCwd})`);
190
+ }
191
+ else {
192
+ // No matching Claude process — session is dead
193
+ this.log(`[Registry] No matching Claude process for PID-less session ${id} (CWD: ${sessionCwd})`);
194
+ sessionsToRemove.push(id);
195
+ }
196
+ }
197
+ }
198
+ /**
199
+ * Detect bypass sessions by checking each session's actual process command line.
200
+ */
201
+ async detectBypassSessions() {
202
+ const updated = [];
203
+ for (const [id, session] of this.callbacks.getAllSessions()) {
204
+ if (session.is_bypass)
205
+ continue;
206
+ const pid = this.getSessionPid(session);
207
+ if (pid === null)
208
+ continue;
209
+ const bypass = await isProcessBypass(pid);
210
+ if (bypass) {
211
+ session.is_bypass = true;
212
+ updated.push(id);
213
+ this.log(`[Registry] Detected bypass from PID ${pid} for session ${id}`);
214
+ }
215
+ }
216
+ return updated;
217
+ }
218
+ /**
219
+ * Start periodic process verification.
220
+ */
221
+ startProcessVerification(intervalMs = PROCESS_VERIFY_INTERVAL_MS) {
222
+ if (this.processVerifyInterval) {
223
+ return;
224
+ }
225
+ // Run immediately on start
226
+ this.verifyProcesses().catch((err) => {
227
+ this.warn(`[Registry] Process verification failed: ${err}`);
228
+ });
229
+ // Then run periodically
230
+ this.processVerifyInterval = setInterval(() => {
231
+ this.verifyProcesses().catch((err) => {
232
+ this.warn(`[Registry] Process verification failed: ${err}`);
233
+ });
234
+ }, intervalMs);
235
+ this.log(`[Registry] Process verification started (interval: ${intervalMs / 1000}s)`);
236
+ }
237
+ /**
238
+ * Stop process verification interval.
239
+ */
240
+ stopProcessVerification() {
241
+ if (this.processVerifyInterval) {
242
+ clearInterval(this.processVerifyInterval);
243
+ this.processVerifyInterval = null;
244
+ }
245
+ }
246
+ /**
247
+ * Mark a CWD as expecting a bypass session.
248
+ * Auto-expires after 60s.
249
+ */
250
+ markPendingBypass(cwd) {
251
+ const normalized = cwd.replace(/\/+$/, '');
252
+ this.pendingBypassCwds.add(normalized);
253
+ this.log(`[Registry] Marked pending bypass for: ${normalized}`);
254
+ setTimeout(() => {
255
+ this.pendingBypassCwds.delete(normalized);
256
+ }, 60_000);
257
+ }
258
+ /**
259
+ * Check if a CWD has a pending bypass flag, and consume it if so.
260
+ */
261
+ consumePendingBypass(cwd) {
262
+ const normalized = cwd.replace(/\/+$/, '');
263
+ if (this.pendingBypassCwds.has(normalized)) {
264
+ this.pendingBypassCwds.delete(normalized);
265
+ return true;
266
+ }
267
+ return false;
268
+ }
269
+ }
270
+ //# sourceMappingURL=process-monitor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process-monitor.js","sourceRoot":"","sources":["../../src/session/process-monitor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Process Monitor Tests
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=process-monitor.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process-monitor.test.d.ts","sourceRoot":"","sources":["../../src/session/process-monitor.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,367 @@
1
+ /**
2
+ * Process Monitor Tests
3
+ */
4
+ import { jest } from '@jest/globals';
5
+ // Mock process-detection module before importing the module under test
6
+ const mockIsProcessRunning = jest.fn();
7
+ const mockIsProcessBypass = jest.fn();
8
+ const mockGetClaudeProcesses = jest.fn();
9
+ jest.unstable_mockModule('../connection/process-detection.js', () => ({
10
+ isProcessRunning: mockIsProcessRunning,
11
+ isProcessBypass: mockIsProcessBypass,
12
+ getClaudeProcesses: mockGetClaudeProcesses,
13
+ }));
14
+ // Import after mocking
15
+ const { ProcessMonitor } = await import('./process-monitor.js');
16
+ import { createLogger } from '../logging/logger-factory.js';
17
+ function makeSession(overrides) {
18
+ return {
19
+ source: 'claude_code',
20
+ session_title: null,
21
+ transcript_path: null,
22
+ cwd: '/test',
23
+ project: 'test',
24
+ model: null,
25
+ workspace: null,
26
+ terminal: null,
27
+ terminal_key: 'TTY:/dev/ttys001',
28
+ status: 'active',
29
+ last_activity: Date.now(),
30
+ registered_at: Date.now(),
31
+ context_metrics: null,
32
+ autocompact: null,
33
+ last_tool_name: null,
34
+ ...overrides,
35
+ };
36
+ }
37
+ describe('ProcessMonitor', () => {
38
+ let monitor;
39
+ let sessions;
40
+ let removedSessionIds;
41
+ const silentLogger = createLogger({ silent: true });
42
+ beforeEach(() => {
43
+ sessions = new Map();
44
+ removedSessionIds = [];
45
+ jest.clearAllMocks();
46
+ mockGetClaudeProcesses.mockResolvedValue([]);
47
+ const callbacks = {
48
+ getSession: (id) => sessions.get(id),
49
+ getAllSessions: () => Array.from(sessions.entries()),
50
+ removeSession: (id) => {
51
+ sessions.delete(id);
52
+ removedSessionIds.push(id);
53
+ },
54
+ };
55
+ monitor = new ProcessMonitor({ callbacks, logger: silentLogger });
56
+ });
57
+ describe('getSessionPid', () => {
58
+ it('should extract PID from DISCOVERED:PID: key', () => {
59
+ const session = makeSession({
60
+ session_id: 's1',
61
+ terminal_key: 'DISCOVERED:PID:12345',
62
+ });
63
+ expect(monitor.getSessionPid(session)).toBe(12345);
64
+ });
65
+ it('should extract PID from DISCOVERED:TTY: key', () => {
66
+ const session = makeSession({
67
+ session_id: 's1',
68
+ terminal_key: 'DISCOVERED:TTY:ttys001:67890',
69
+ });
70
+ expect(monitor.getSessionPid(session)).toBe(67890);
71
+ });
72
+ it('should fall back to terminal.terminal_pid', () => {
73
+ const session = makeSession({
74
+ session_id: 's1',
75
+ terminal_key: 'TTY:/dev/ttys001',
76
+ terminal: {
77
+ tty: '/dev/ttys001',
78
+ terminal_pid: 99999,
79
+ term_program: null,
80
+ iterm_session_id: null,
81
+ term_session_id: null,
82
+ kitty_window_id: null,
83
+ wezterm_pane: null,
84
+ vscode_injection: null,
85
+ windowid: null,
86
+ term: null,
87
+ },
88
+ });
89
+ expect(monitor.getSessionPid(session)).toBe(99999);
90
+ });
91
+ it('should return null when no PID available', () => {
92
+ const session = makeSession({
93
+ session_id: 's1',
94
+ terminal_key: 'AUTO:some-uuid',
95
+ });
96
+ expect(monitor.getSessionPid(session)).toBeNull();
97
+ });
98
+ });
99
+ describe('storeTerminalPid', () => {
100
+ it('should create terminal object when none exists', () => {
101
+ mockIsProcessBypass.mockResolvedValue(false);
102
+ const session = makeSession({ session_id: 's1', terminal_key: 'AUTO:uuid' });
103
+ monitor.storeTerminalPid(session, 12345);
104
+ expect(session.terminal).not.toBeNull();
105
+ expect(session.terminal.terminal_pid).toBe(12345);
106
+ });
107
+ it('should set terminal_pid on existing terminal object', () => {
108
+ mockIsProcessBypass.mockResolvedValue(false);
109
+ const session = makeSession({
110
+ session_id: 's1',
111
+ terminal_key: 'AUTO:uuid',
112
+ terminal: {
113
+ tty: '/dev/ttys001',
114
+ terminal_pid: 0,
115
+ term_program: 'iTerm2',
116
+ iterm_session_id: null,
117
+ term_session_id: null,
118
+ kitty_window_id: null,
119
+ wezterm_pane: null,
120
+ vscode_injection: null,
121
+ windowid: null,
122
+ term: null,
123
+ },
124
+ });
125
+ monitor.storeTerminalPid(session, 54321);
126
+ expect(session.terminal.terminal_pid).toBe(54321);
127
+ });
128
+ it('should not overwrite existing PID', () => {
129
+ mockIsProcessBypass.mockResolvedValue(false);
130
+ const session = makeSession({
131
+ session_id: 's1',
132
+ terminal_key: 'DISCOVERED:PID:11111',
133
+ });
134
+ monitor.storeTerminalPid(session, 22222);
135
+ // PID comes from terminal_key, should not create terminal object
136
+ expect(session.terminal).toBeNull();
137
+ });
138
+ it('should skip invalid PIDs', () => {
139
+ const session = makeSession({ session_id: 's1', terminal_key: 'AUTO:uuid' });
140
+ monitor.storeTerminalPid(session, 0);
141
+ monitor.storeTerminalPid(session, -1);
142
+ expect(session.terminal).toBeNull();
143
+ });
144
+ });
145
+ describe('verifyProcesses', () => {
146
+ it('should remove sessions with dead processes', async () => {
147
+ mockIsProcessRunning.mockResolvedValue(false);
148
+ const session = makeSession({
149
+ session_id: 's1',
150
+ terminal_key: 'DISCOVERED:PID:12345',
151
+ });
152
+ sessions.set('s1', session);
153
+ await monitor.verifyProcesses();
154
+ expect(removedSessionIds).toContain('s1');
155
+ });
156
+ it('should keep sessions with running processes', async () => {
157
+ mockIsProcessRunning.mockResolvedValue(true);
158
+ const session = makeSession({
159
+ session_id: 's1',
160
+ terminal_key: 'DISCOVERED:PID:12345',
161
+ });
162
+ sessions.set('s1', session);
163
+ await monitor.verifyProcesses();
164
+ expect(removedSessionIds).toHaveLength(0);
165
+ });
166
+ it('should remove sessions with CWD in Trash', async () => {
167
+ const session = makeSession({
168
+ session_id: 's1',
169
+ terminal_key: 'AUTO:uuid',
170
+ cwd: '/Users/test/.Trash/old-project',
171
+ });
172
+ sessions.set('s1', session);
173
+ await monitor.verifyProcesses();
174
+ expect(removedSessionIds).toContain('s1');
175
+ });
176
+ it('should remove sessions idle beyond timeout', async () => {
177
+ const session = makeSession({
178
+ session_id: 's1',
179
+ terminal_key: 'AUTO:uuid',
180
+ last_activity: Date.now() - (5 * 60 * 60 * 1000), // 5 hours ago
181
+ });
182
+ sessions.set('s1', session);
183
+ await monitor.verifyProcesses();
184
+ expect(removedSessionIds).toContain('s1');
185
+ });
186
+ it('should not remove recently active sessions without PID', async () => {
187
+ const session = makeSession({
188
+ session_id: 's1',
189
+ terminal_key: 'AUTO:uuid',
190
+ last_activity: Date.now(),
191
+ });
192
+ sessions.set('s1', session);
193
+ await monitor.verifyProcesses();
194
+ expect(removedSessionIds).toHaveLength(0);
195
+ });
196
+ });
197
+ describe('detectBypassSessions', () => {
198
+ it('should mark sessions as bypass when process has flag', async () => {
199
+ mockIsProcessBypass.mockResolvedValue(true);
200
+ const session = makeSession({
201
+ session_id: 's1',
202
+ terminal_key: 'DISCOVERED:PID:12345',
203
+ });
204
+ sessions.set('s1', session);
205
+ const updated = await monitor.detectBypassSessions();
206
+ expect(updated).toContain('s1');
207
+ expect(session.is_bypass).toBe(true);
208
+ });
209
+ it('should skip already-bypass sessions', async () => {
210
+ mockIsProcessBypass.mockResolvedValue(true);
211
+ const session = makeSession({
212
+ session_id: 's1',
213
+ terminal_key: 'DISCOVERED:PID:12345',
214
+ is_bypass: true,
215
+ });
216
+ sessions.set('s1', session);
217
+ const updated = await monitor.detectBypassSessions();
218
+ expect(updated).toHaveLength(0);
219
+ expect(mockIsProcessBypass).not.toHaveBeenCalled();
220
+ });
221
+ it('should skip sessions without PID', async () => {
222
+ const session = makeSession({
223
+ session_id: 's1',
224
+ terminal_key: 'AUTO:uuid',
225
+ });
226
+ sessions.set('s1', session);
227
+ const updated = await monitor.detectBypassSessions();
228
+ expect(updated).toHaveLength(0);
229
+ expect(mockIsProcessBypass).not.toHaveBeenCalled();
230
+ });
231
+ });
232
+ describe('verifyProcesses - PID-less session verification', () => {
233
+ it('should remove PID-less session when no Claude processes running', async () => {
234
+ mockGetClaudeProcesses.mockResolvedValue([]);
235
+ const session = makeSession({
236
+ session_id: 's1',
237
+ terminal_key: 'AUTO:some-uuid',
238
+ cwd: '/Users/test/project',
239
+ registered_at: Date.now() - 120_000, // 2 min ago, past grace period
240
+ });
241
+ sessions.set('s1', session);
242
+ await monitor.verifyProcesses();
243
+ expect(removedSessionIds).toContain('s1');
244
+ expect(mockGetClaudeProcesses).toHaveBeenCalledTimes(1);
245
+ });
246
+ it('should keep PID-less session when matching process found by CWD', async () => {
247
+ mockIsProcessBypass.mockResolvedValue(false);
248
+ mockGetClaudeProcesses.mockResolvedValue([
249
+ { pid: 55555, tty: 'ttys001', cwd: '/Users/test/project' },
250
+ ]);
251
+ const session = makeSession({
252
+ session_id: 's1',
253
+ terminal_key: 'AUTO:some-uuid',
254
+ cwd: '/Users/test/project',
255
+ registered_at: Date.now() - 120_000,
256
+ });
257
+ sessions.set('s1', session);
258
+ await monitor.verifyProcesses();
259
+ expect(removedSessionIds).toHaveLength(0);
260
+ // Verify PID was enriched
261
+ expect(monitor.getSessionPid(session)).toBe(55555);
262
+ });
263
+ it('should not remove PID-less session within grace period', async () => {
264
+ mockGetClaudeProcesses.mockResolvedValue([]); // No matching processes
265
+ const session = makeSession({
266
+ session_id: 's1',
267
+ terminal_key: 'AUTO:some-uuid',
268
+ cwd: '/Users/test/project',
269
+ registered_at: Date.now() - 10_000, // 10s ago, within grace period
270
+ });
271
+ sessions.set('s1', session);
272
+ await monitor.verifyProcesses();
273
+ expect(removedSessionIds).toHaveLength(0);
274
+ });
275
+ it('should not claim processes already owned by PID-bearing sessions', async () => {
276
+ mockIsProcessRunning.mockResolvedValue(true);
277
+ mockGetClaudeProcesses.mockResolvedValue([
278
+ { pid: 11111, tty: 'ttys001', cwd: '/Users/test/project' },
279
+ ]);
280
+ // Session with PID (already claims PID 11111)
281
+ const sessionWithPid = makeSession({
282
+ session_id: 's1',
283
+ terminal_key: 'DISCOVERED:PID:11111',
284
+ cwd: '/Users/test/project',
285
+ });
286
+ // PID-less session in same CWD
287
+ const sessionWithoutPid = makeSession({
288
+ session_id: 's2',
289
+ terminal_key: 'AUTO:uuid2',
290
+ cwd: '/Users/test/project',
291
+ registered_at: Date.now() - 120_000,
292
+ });
293
+ sessions.set('s1', sessionWithPid);
294
+ sessions.set('s2', sessionWithoutPid);
295
+ await monitor.verifyProcesses();
296
+ // s2 should be removed because the only process (PID 11111) is claimed by s1
297
+ expect(removedSessionIds).toContain('s2');
298
+ expect(removedSessionIds).not.toContain('s1');
299
+ });
300
+ it('should handle getClaudeProcesses failure gracefully', async () => {
301
+ mockGetClaudeProcesses.mockRejectedValue(new Error('pgrep failed'));
302
+ const session = makeSession({
303
+ session_id: 's1',
304
+ terminal_key: 'AUTO:some-uuid',
305
+ cwd: '/Users/test/project',
306
+ registered_at: Date.now() - 120_000,
307
+ });
308
+ sessions.set('s1', session);
309
+ await monitor.verifyProcesses();
310
+ // Should NOT remove the session (fail-safe)
311
+ expect(removedSessionIds).toHaveLength(0);
312
+ });
313
+ it('should match multiple PID-less sessions to multiple processes in same CWD', async () => {
314
+ mockIsProcessBypass.mockResolvedValue(false);
315
+ mockGetClaudeProcesses.mockResolvedValue([
316
+ { pid: 111, tty: 'ttys001', cwd: '/Users/test/project' },
317
+ { pid: 222, tty: 'ttys002', cwd: '/Users/test/project' },
318
+ ]);
319
+ const s1 = makeSession({
320
+ session_id: 's1',
321
+ terminal_key: 'AUTO:uuid1',
322
+ cwd: '/Users/test/project',
323
+ registered_at: Date.now() - 120_000,
324
+ });
325
+ const s2 = makeSession({
326
+ session_id: 's2',
327
+ terminal_key: 'AUTO:uuid2',
328
+ cwd: '/Users/test/project',
329
+ registered_at: Date.now() - 120_000,
330
+ });
331
+ sessions.set('s1', s1);
332
+ sessions.set('s2', s2);
333
+ await monitor.verifyProcesses();
334
+ expect(removedSessionIds).toHaveLength(0);
335
+ // Both sessions should be enriched with PIDs
336
+ expect(monitor.getSessionPid(s1)).not.toBeNull();
337
+ expect(monitor.getSessionPid(s2)).not.toBeNull();
338
+ });
339
+ it('should skip process scan when no PID-less sessions exist', async () => {
340
+ mockIsProcessRunning.mockResolvedValue(true);
341
+ const session = makeSession({
342
+ session_id: 's1',
343
+ terminal_key: 'DISCOVERED:PID:12345',
344
+ });
345
+ sessions.set('s1', session);
346
+ await monitor.verifyProcesses();
347
+ expect(mockGetClaudeProcesses).not.toHaveBeenCalled();
348
+ });
349
+ });
350
+ describe('pendingBypass', () => {
351
+ it('should consume pending bypass for matching CWD', () => {
352
+ monitor.markPendingBypass('/Users/test/project');
353
+ expect(monitor.consumePendingBypass('/Users/test/project')).toBe(true);
354
+ // Second consume should return false (already consumed)
355
+ expect(monitor.consumePendingBypass('/Users/test/project')).toBe(false);
356
+ });
357
+ it('should normalize trailing slashes', () => {
358
+ monitor.markPendingBypass('/Users/test/project/');
359
+ expect(monitor.consumePendingBypass('/Users/test/project')).toBe(true);
360
+ });
361
+ it('should return false for non-matching CWD', () => {
362
+ monitor.markPendingBypass('/Users/test/project-a');
363
+ expect(monitor.consumePendingBypass('/Users/test/project-b')).toBe(false);
364
+ });
365
+ });
366
+ });
367
+ //# sourceMappingURL=process-monitor.test.js.map