@ai-devkit/agent-manager 0.32.0 → 0.33.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 (572) hide show
  1. package/dist/AgentManager.d.ts +13 -4
  2. package/dist/AgentManager.d.ts.map +1 -1
  3. package/dist/AgentManager.js +116 -84
  4. package/dist/AgentManager.js.map +1 -1
  5. package/dist/__tests__/AgentManager.test.js +623 -391
  6. package/dist/__tests__/AgentManager.test.js.map +1 -1
  7. package/dist/__tests__/adapters/ClaudeCodeAdapter.test.js +642 -642
  8. package/dist/__tests__/adapters/ClaudeCodeAdapter.test.js.map +1 -1
  9. package/dist/__tests__/adapters/CodexAdapter.test.js +322 -2321
  10. package/dist/__tests__/adapters/CodexAdapter.test.js.map +1 -1
  11. package/dist/__tests__/adapters/GrokCliAdapter.test.js +114 -114
  12. package/dist/__tests__/adapters/GrokCliAdapter.test.js.map +1 -1
  13. package/dist/__tests__/adapters/OpenCodeAdapter.test.js +170 -169
  14. package/dist/__tests__/adapters/OpenCodeAdapter.test.js.map +1 -1
  15. package/dist/__tests__/capacity/codex.test.js +93 -93
  16. package/dist/__tests__/capacity/codex.test.js.map +1 -1
  17. package/dist/__tests__/capacity/index.test.js +17 -17
  18. package/dist/__tests__/capacity/index.test.js.map +1 -1
  19. package/dist/__tests__/durable/CodexCliProbe.test.js +60 -60
  20. package/dist/__tests__/durable/CodexCliProbe.test.js.map +1 -1
  21. package/dist/__tests__/durable/CodexDurableAgentRepository.test.js +28 -28
  22. package/dist/__tests__/durable/CodexDurableAgentRepository.test.js.map +1 -1
  23. package/dist/__tests__/durable/CodexPrintAgent.integration.test.js +30 -30
  24. package/dist/__tests__/durable/CodexPrintAgent.integration.test.js.map +1 -1
  25. package/dist/__tests__/durable/CodexPrintAgentService.test.js +71 -71
  26. package/dist/__tests__/durable/CodexPrintAgentService.test.js.map +1 -1
  27. package/dist/__tests__/durable/CodexPrintRunner.test.js +125 -125
  28. package/dist/__tests__/durable/CodexPrintRunner.test.js.map +1 -1
  29. package/dist/__tests__/print/ClaudeCliProbe.test.js +20 -20
  30. package/dist/__tests__/print/ClaudeCliProbe.test.js.map +1 -1
  31. package/dist/__tests__/print/ClaudePrintAgent.integration.test.js +20 -20
  32. package/dist/__tests__/print/ClaudePrintAgent.integration.test.js.map +1 -1
  33. package/dist/__tests__/print/ClaudePrintAgentService.test.js +58 -58
  34. package/dist/__tests__/print/ClaudePrintAgentService.test.js.map +1 -1
  35. package/dist/__tests__/print/ClaudePrintRunner.test.js +55 -55
  36. package/dist/__tests__/print/ClaudePrintRunner.test.js.map +1 -1
  37. package/dist/__tests__/print/DurableAgent.test.js +9 -9
  38. package/dist/__tests__/print/DurableAgent.test.js.map +1 -1
  39. package/dist/__tests__/print/DurableAgentRepository.sqlite.test.js +40 -40
  40. package/dist/__tests__/print/DurableAgentRepository.sqlite.test.js.map +1 -1
  41. package/dist/__tests__/print/DurableAgentRepository.test.js +66 -66
  42. package/dist/__tests__/print/DurableAgentRepository.test.js.map +1 -1
  43. package/dist/__tests__/providers/claude/ClaudeAgentMapper.test.js +34 -34
  44. package/dist/__tests__/providers/claude/ClaudeAgentMapper.test.js.map +1 -1
  45. package/dist/__tests__/providers/claude/ClaudeSessionLocator.test.js +132 -132
  46. package/dist/__tests__/providers/claude/ClaudeSessionLocator.test.js.map +1 -1
  47. package/dist/__tests__/providers/codex/CodexSessionLocator.test.js +194 -0
  48. package/dist/__tests__/providers/codex/CodexSessionLocator.test.js.map +1 -0
  49. package/dist/__tests__/providers/codex/CodexSessionMapping.test.js +86 -0
  50. package/dist/__tests__/providers/codex/CodexSessionMapping.test.js.map +1 -0
  51. package/dist/__tests__/providers/codex/CodexSessionParser.test.js +254 -0
  52. package/dist/__tests__/providers/codex/CodexSessionParser.test.js.map +1 -0
  53. package/dist/__tests__/providers/copilot/CopilotAdapter.test.js +641 -0
  54. package/dist/__tests__/providers/copilot/CopilotAdapter.test.js.map +1 -0
  55. package/dist/__tests__/providers/gemini/GeminiCliAdapter.test.js +1398 -0
  56. package/dist/__tests__/providers/gemini/GeminiCliAdapter.test.js.map +1 -0
  57. package/dist/__tests__/providers/pi/PiAdapter.test.js +337 -0
  58. package/dist/__tests__/providers/pi/PiAdapter.test.js.map +1 -0
  59. package/dist/__tests__/providers/pi/PiSessionParser.test.js +246 -0
  60. package/dist/__tests__/providers/pi/PiSessionParser.test.js.map +1 -0
  61. package/dist/__tests__/providers/pi/PiSessionTracker.test.js +108 -0
  62. package/dist/__tests__/providers/pi/PiSessionTracker.test.js.map +1 -0
  63. package/dist/__tests__/providers/pi/durable/PiCliProbe.test.js +33 -33
  64. package/dist/__tests__/providers/pi/durable/PiCliProbe.test.js.map +1 -1
  65. package/dist/__tests__/providers/pi/durable/PiDurableAgentRepository.test.js +16 -16
  66. package/dist/__tests__/providers/pi/durable/PiDurableAgentRepository.test.js.map +1 -1
  67. package/dist/__tests__/providers/pi/durable/PiPrintAgentService.test.js +52 -52
  68. package/dist/__tests__/providers/pi/durable/PiPrintAgentService.test.js.map +1 -1
  69. package/dist/__tests__/providers/pi/durable/PiPrintProtocol.test.js +44 -44
  70. package/dist/__tests__/providers/pi/durable/PiPrintProtocol.test.js.map +1 -1
  71. package/dist/__tests__/providers/pi/durable/PiPrintRunner.test.js +126 -126
  72. package/dist/__tests__/providers/pi/durable/PiPrintRunner.test.js.map +1 -1
  73. package/dist/__tests__/providers/pi/durable/PiStreamParser.test.js +14 -14
  74. package/dist/__tests__/providers/pi/durable/PiStreamParser.test.js.map +1 -1
  75. package/dist/__tests__/readiness/AgentReadiness.test.js +134 -134
  76. package/dist/__tests__/readiness/AgentReadiness.test.js.map +1 -1
  77. package/dist/__tests__/runtime/AgentRuntime.test.js +13 -0
  78. package/dist/__tests__/runtime/AgentRuntime.test.js.map +1 -0
  79. package/dist/__tests__/runtime/HerdrAgentDiscovery.test.js +164 -0
  80. package/dist/__tests__/runtime/HerdrAgentDiscovery.test.js.map +1 -0
  81. package/dist/__tests__/runtime/HerdrAgentRuntime.test.js +488 -0
  82. package/dist/__tests__/runtime/HerdrAgentRuntime.test.js.map +1 -0
  83. package/dist/__tests__/runtime/ManagedAgentRuntime.test.js +588 -0
  84. package/dist/__tests__/runtime/ManagedAgentRuntime.test.js.map +1 -0
  85. package/dist/__tests__/terminal/TerminalFocusManager.test.js +100 -100
  86. package/dist/__tests__/terminal/TerminalFocusManager.test.js.map +1 -1
  87. package/dist/__tests__/terminal/TmuxManager.test.js +101 -101
  88. package/dist/__tests__/terminal/TmuxManager.test.js.map +1 -1
  89. package/dist/__tests__/terminal/TtyWriter.test.js +185 -185
  90. package/dist/__tests__/terminal/TtyWriter.test.js.map +1 -1
  91. package/dist/__tests__/utils/AgentRegistry.test.js +343 -218
  92. package/dist/__tests__/utils/AgentRegistry.test.js.map +1 -1
  93. package/dist/__tests__/utils/ClaudeSessionParser.test.js +103 -101
  94. package/dist/__tests__/utils/ClaudeSessionParser.test.js.map +1 -1
  95. package/dist/__tests__/utils/agent-requests.test.js +43 -43
  96. package/dist/__tests__/utils/agent-requests.test.js.map +1 -1
  97. package/dist/__tests__/utils/agents.test.js +17 -17
  98. package/dist/__tests__/utils/agents.test.js.map +1 -1
  99. package/dist/__tests__/utils/matching.test.js +92 -92
  100. package/dist/__tests__/utils/matching.test.js.map +1 -1
  101. package/dist/__tests__/utils/process.test.js +108 -108
  102. package/dist/__tests__/utils/process.test.js.map +1 -1
  103. package/dist/__tests__/utils/session.test.js +53 -53
  104. package/dist/__tests__/utils/session.test.js.map +1 -1
  105. package/dist/adapters/AgentAdapter.d.ts +2 -2
  106. package/dist/adapters/AgentAdapter.d.ts.map +1 -1
  107. package/dist/adapters/AgentAdapter.js +1 -1
  108. package/dist/adapters/AgentAdapter.js.map +1 -1
  109. package/dist/adapters/GrokCliAdapter.d.ts +1 -1
  110. package/dist/adapters/GrokCliAdapter.d.ts.map +1 -1
  111. package/dist/adapters/GrokCliAdapter.js +80 -80
  112. package/dist/adapters/GrokCliAdapter.js.map +1 -1
  113. package/dist/adapters/OpenCodeAdapter.d.ts +2 -1
  114. package/dist/adapters/OpenCodeAdapter.d.ts.map +1 -1
  115. package/dist/adapters/OpenCodeAdapter.js +41 -37
  116. package/dist/adapters/OpenCodeAdapter.js.map +1 -1
  117. package/dist/adapters/index.d.ts +9 -9
  118. package/dist/adapters/index.d.ts.map +1 -1
  119. package/dist/adapters/index.js +8 -8
  120. package/dist/adapters/index.js.map +1 -1
  121. package/dist/capacity/codex.d.ts +3 -3
  122. package/dist/capacity/codex.d.ts.map +1 -1
  123. package/dist/capacity/codex.js +57 -57
  124. package/dist/capacity/codex.js.map +1 -1
  125. package/dist/capacity/index.d.ts +3 -3
  126. package/dist/capacity/index.d.ts.map +1 -1
  127. package/dist/capacity/index.js +8 -8
  128. package/dist/capacity/index.js.map +1 -1
  129. package/dist/capacity/types.d.ts +1 -1
  130. package/dist/capacity/types.js.map +1 -1
  131. package/dist/database/connection.d.ts +1 -1
  132. package/dist/database/connection.d.ts.map +1 -1
  133. package/dist/database/connection.js +15 -15
  134. package/dist/database/connection.js.map +1 -1
  135. package/dist/database/index.d.ts +3 -3
  136. package/dist/database/index.d.ts.map +1 -1
  137. package/dist/database/index.js +2 -2
  138. package/dist/database/index.js.map +1 -1
  139. package/dist/database/migrations/005_agent_runtime.sql +2 -0
  140. package/dist/database/schema.d.ts +1 -1
  141. package/dist/database/schema.d.ts.map +1 -1
  142. package/dist/database/schema.js +7 -7
  143. package/dist/database/schema.js.map +1 -1
  144. package/dist/durable/DurableAgent.d.ts +9 -9
  145. package/dist/durable/DurableAgent.d.ts.map +1 -1
  146. package/dist/durable/DurableAgent.js +16 -16
  147. package/dist/durable/DurableAgent.js.map +1 -1
  148. package/dist/durable/DurableAgentRepository.d.ts +4 -4
  149. package/dist/durable/DurableAgentRepository.d.ts.map +1 -1
  150. package/dist/durable/DurableAgentRepository.js +49 -48
  151. package/dist/durable/DurableAgentRepository.js.map +1 -1
  152. package/dist/durable/process.d.ts +1 -1
  153. package/dist/durable/process.d.ts.map +1 -1
  154. package/dist/durable/process.js +14 -14
  155. package/dist/durable/process.js.map +1 -1
  156. package/dist/durable/run.d.ts +2 -2
  157. package/dist/durable/run.d.ts.map +1 -1
  158. package/dist/durable/run.js +6 -6
  159. package/dist/durable/run.js.map +1 -1
  160. package/dist/durable/utils.d.ts +1 -1
  161. package/dist/durable/utils.d.ts.map +1 -1
  162. package/dist/durable/utils.js +4 -4
  163. package/dist/durable/utils.js.map +1 -1
  164. package/dist/index.d.ts +48 -43
  165. package/dist/index.d.ts.map +1 -1
  166. package/dist/index.js +28 -26
  167. package/dist/index.js.map +1 -1
  168. package/dist/providers/claude/ClaudeAgentMapper.d.ts +4 -4
  169. package/dist/providers/claude/ClaudeAgentMapper.d.ts.map +1 -1
  170. package/dist/providers/claude/ClaudeAgentMapper.js +10 -10
  171. package/dist/providers/claude/ClaudeAgentMapper.js.map +1 -1
  172. package/dist/providers/claude/ClaudeCodeAdapter.d.ts +1 -1
  173. package/dist/providers/claude/ClaudeCodeAdapter.d.ts.map +1 -1
  174. package/dist/providers/claude/ClaudeCodeAdapter.js +14 -14
  175. package/dist/providers/claude/ClaudeCodeAdapter.js.map +1 -1
  176. package/dist/providers/claude/ClaudeSessionLocator.d.ts +4 -4
  177. package/dist/providers/claude/ClaudeSessionLocator.d.ts.map +1 -1
  178. package/dist/providers/claude/ClaudeSessionLocator.js +79 -79
  179. package/dist/providers/claude/ClaudeSessionLocator.js.map +1 -1
  180. package/dist/providers/claude/ClaudeSessionParser.d.ts +2 -2
  181. package/dist/providers/claude/ClaudeSessionParser.d.ts.map +1 -1
  182. package/dist/providers/claude/ClaudeSessionParser.js +99 -99
  183. package/dist/providers/claude/ClaudeSessionParser.js.map +1 -1
  184. package/dist/providers/claude/durable/ClaudeCliProbe.d.ts.map +1 -1
  185. package/dist/providers/claude/durable/ClaudeCliProbe.js +16 -16
  186. package/dist/providers/claude/durable/ClaudeCliProbe.js.map +1 -1
  187. package/dist/providers/claude/durable/ClaudePrintAgentService.d.ts +5 -5
  188. package/dist/providers/claude/durable/ClaudePrintAgentService.d.ts.map +1 -1
  189. package/dist/providers/claude/durable/ClaudePrintAgentService.js +10 -10
  190. package/dist/providers/claude/durable/ClaudePrintAgentService.js.map +1 -1
  191. package/dist/providers/claude/durable/ClaudePrintRunner.d.ts +4 -4
  192. package/dist/providers/claude/durable/ClaudePrintRunner.d.ts.map +1 -1
  193. package/dist/providers/claude/durable/ClaudePrintRunner.js +18 -18
  194. package/dist/providers/claude/durable/ClaudePrintRunner.js.map +1 -1
  195. package/dist/providers/claude/durable/ClaudeStreamParser.d.ts +2 -2
  196. package/dist/providers/claude/durable/ClaudeStreamParser.d.ts.map +1 -1
  197. package/dist/providers/claude/durable/ClaudeStreamParser.js +17 -17
  198. package/dist/providers/claude/durable/ClaudeStreamParser.js.map +1 -1
  199. package/dist/providers/codex/CodexAdapter.d.ts +27 -0
  200. package/dist/providers/codex/CodexAdapter.d.ts.map +1 -0
  201. package/dist/providers/codex/CodexAdapter.js +162 -0
  202. package/dist/providers/codex/CodexAdapter.js.map +1 -0
  203. package/dist/providers/codex/CodexAgentMapper.d.ts +9 -0
  204. package/dist/providers/codex/CodexAgentMapper.d.ts.map +1 -0
  205. package/dist/providers/codex/CodexAgentMapper.js +35 -0
  206. package/dist/providers/codex/CodexAgentMapper.js.map +1 -0
  207. package/dist/providers/codex/CodexSessionLocator.d.ts +44 -0
  208. package/dist/providers/codex/CodexSessionLocator.d.ts.map +1 -0
  209. package/dist/providers/codex/CodexSessionLocator.js +207 -0
  210. package/dist/providers/codex/CodexSessionLocator.js.map +1 -0
  211. package/dist/providers/codex/CodexSessionMapping.d.ts +23 -0
  212. package/dist/providers/codex/CodexSessionMapping.d.ts.map +1 -0
  213. package/dist/providers/codex/CodexSessionMapping.js +68 -0
  214. package/dist/providers/codex/CodexSessionMapping.js.map +1 -0
  215. package/dist/providers/codex/CodexSessionParser.d.ts +58 -0
  216. package/dist/providers/codex/CodexSessionParser.d.ts.map +1 -0
  217. package/dist/providers/codex/CodexSessionParser.js +262 -0
  218. package/dist/providers/codex/CodexSessionParser.js.map +1 -0
  219. package/dist/providers/codex/durable/CodexCliProbe.d.ts.map +1 -1
  220. package/dist/providers/codex/durable/CodexCliProbe.js +22 -22
  221. package/dist/providers/codex/durable/CodexCliProbe.js.map +1 -1
  222. package/dist/providers/codex/durable/CodexPrintAgentService.d.ts +6 -6
  223. package/dist/providers/codex/durable/CodexPrintAgentService.d.ts.map +1 -1
  224. package/dist/providers/codex/durable/CodexPrintAgentService.js +10 -10
  225. package/dist/providers/codex/durable/CodexPrintAgentService.js.map +1 -1
  226. package/dist/providers/codex/durable/CodexPrintRunner.d.ts +4 -4
  227. package/dist/providers/codex/durable/CodexPrintRunner.d.ts.map +1 -1
  228. package/dist/providers/codex/durable/CodexPrintRunner.js +20 -20
  229. package/dist/providers/codex/durable/CodexPrintRunner.js.map +1 -1
  230. package/dist/providers/codex/durable/CodexStreamParser.d.ts +2 -2
  231. package/dist/providers/codex/durable/CodexStreamParser.d.ts.map +1 -1
  232. package/dist/providers/codex/durable/CodexStreamParser.js +21 -21
  233. package/dist/providers/codex/durable/CodexStreamParser.js.map +1 -1
  234. package/dist/{adapters → providers/copilot}/CopilotAdapter.d.ts +11 -25
  235. package/dist/providers/copilot/CopilotAdapter.d.ts.map +1 -0
  236. package/dist/providers/copilot/CopilotAdapter.js +108 -0
  237. package/dist/providers/copilot/CopilotAdapter.js.map +1 -0
  238. package/dist/providers/copilot/CopilotAgentMapper.d.ts +9 -0
  239. package/dist/providers/copilot/CopilotAgentMapper.d.ts.map +1 -0
  240. package/dist/providers/copilot/CopilotAgentMapper.js +37 -0
  241. package/dist/providers/copilot/CopilotAgentMapper.js.map +1 -0
  242. package/dist/providers/copilot/CopilotSessionLocator.d.ts +19 -0
  243. package/dist/providers/copilot/CopilotSessionLocator.d.ts.map +1 -0
  244. package/dist/providers/copilot/CopilotSessionLocator.js +41 -0
  245. package/dist/providers/copilot/CopilotSessionLocator.js.map +1 -0
  246. package/dist/providers/copilot/CopilotSessionParser.d.ts +30 -0
  247. package/dist/providers/copilot/CopilotSessionParser.d.ts.map +1 -0
  248. package/dist/providers/copilot/CopilotSessionParser.js +181 -0
  249. package/dist/providers/copilot/CopilotSessionParser.js.map +1 -0
  250. package/dist/providers/gemini/GeminiAgentMapper.d.ts +9 -0
  251. package/dist/providers/gemini/GeminiAgentMapper.d.ts.map +1 -0
  252. package/dist/providers/gemini/GeminiAgentMapper.js +37 -0
  253. package/dist/providers/gemini/GeminiAgentMapper.js.map +1 -0
  254. package/dist/providers/gemini/GeminiCliAdapter.d.ts +52 -0
  255. package/dist/providers/gemini/GeminiCliAdapter.d.ts.map +1 -0
  256. package/dist/providers/gemini/GeminiCliAdapter.js +188 -0
  257. package/dist/providers/gemini/GeminiCliAdapter.js.map +1 -0
  258. package/dist/providers/gemini/GeminiSessionLocator.d.ts +30 -0
  259. package/dist/providers/gemini/GeminiSessionLocator.d.ts.map +1 -0
  260. package/dist/providers/gemini/GeminiSessionLocator.js +142 -0
  261. package/dist/providers/gemini/GeminiSessionLocator.js.map +1 -0
  262. package/dist/providers/gemini/GeminiSessionParser.d.ts +94 -0
  263. package/dist/providers/gemini/GeminiSessionParser.d.ts.map +1 -0
  264. package/dist/providers/gemini/GeminiSessionParser.js +166 -0
  265. package/dist/providers/gemini/GeminiSessionParser.js.map +1 -0
  266. package/dist/providers/pi/PiAdapter.d.ts +28 -0
  267. package/dist/providers/pi/PiAdapter.d.ts.map +1 -0
  268. package/dist/providers/pi/PiAdapter.js +153 -0
  269. package/dist/providers/pi/PiAdapter.js.map +1 -0
  270. package/dist/providers/pi/PiAgentMapper.d.ts +9 -0
  271. package/dist/providers/pi/PiAgentMapper.d.ts.map +1 -0
  272. package/dist/providers/pi/PiAgentMapper.js +37 -0
  273. package/dist/providers/pi/PiAgentMapper.js.map +1 -0
  274. package/dist/providers/pi/PiSessionLocator.d.ts +23 -0
  275. package/dist/providers/pi/PiSessionLocator.d.ts.map +1 -0
  276. package/dist/providers/pi/PiSessionLocator.js +79 -0
  277. package/dist/providers/pi/PiSessionLocator.js.map +1 -0
  278. package/dist/providers/pi/PiSessionParser.d.ts +36 -0
  279. package/dist/providers/pi/PiSessionParser.d.ts.map +1 -0
  280. package/dist/providers/pi/PiSessionParser.js +191 -0
  281. package/dist/providers/pi/PiSessionParser.js.map +1 -0
  282. package/dist/providers/pi/PiSessionTracker.d.ts +23 -0
  283. package/dist/providers/pi/PiSessionTracker.d.ts.map +1 -0
  284. package/dist/providers/pi/PiSessionTracker.js +69 -0
  285. package/dist/providers/pi/PiSessionTracker.js.map +1 -0
  286. package/dist/providers/pi/durable/PiCliProbe.d.ts.map +1 -1
  287. package/dist/providers/pi/durable/PiCliProbe.js +15 -15
  288. package/dist/providers/pi/durable/PiCliProbe.js.map +1 -1
  289. package/dist/providers/pi/durable/PiPrintAgentService.d.ts +6 -6
  290. package/dist/providers/pi/durable/PiPrintAgentService.d.ts.map +1 -1
  291. package/dist/providers/pi/durable/PiPrintAgentService.js +10 -10
  292. package/dist/providers/pi/durable/PiPrintAgentService.js.map +1 -1
  293. package/dist/providers/pi/durable/PiPrintProtocol.d.ts.map +1 -1
  294. package/dist/providers/pi/durable/PiPrintProtocol.js +18 -18
  295. package/dist/providers/pi/durable/PiPrintProtocol.js.map +1 -1
  296. package/dist/providers/pi/durable/PiPrintRunner.d.ts +4 -4
  297. package/dist/providers/pi/durable/PiPrintRunner.d.ts.map +1 -1
  298. package/dist/providers/pi/durable/PiPrintRunner.js +15 -15
  299. package/dist/providers/pi/durable/PiPrintRunner.js.map +1 -1
  300. package/dist/providers/pi/durable/PiStreamParser.d.ts +1 -1
  301. package/dist/providers/pi/durable/PiStreamParser.d.ts.map +1 -1
  302. package/dist/providers/pi/durable/PiStreamParser.js +16 -16
  303. package/dist/providers/pi/durable/PiStreamParser.js.map +1 -1
  304. package/dist/readiness/AgentReadiness.d.ts +6 -6
  305. package/dist/readiness/AgentReadiness.d.ts.map +1 -1
  306. package/dist/readiness/AgentReadiness.js +130 -130
  307. package/dist/readiness/AgentReadiness.js.map +1 -1
  308. package/dist/runtime/ManagedAgentRuntime.d.ts +69 -0
  309. package/dist/runtime/ManagedAgentRuntime.d.ts.map +1 -0
  310. package/dist/runtime/ManagedAgentRuntime.js +156 -0
  311. package/dist/runtime/ManagedAgentRuntime.js.map +1 -0
  312. package/dist/runtime/RuntimeFactory.d.ts +4 -0
  313. package/dist/runtime/RuntimeFactory.d.ts.map +1 -0
  314. package/dist/runtime/RuntimeFactory.js +11 -0
  315. package/dist/runtime/RuntimeFactory.js.map +1 -0
  316. package/dist/runtime/errors.d.ts +27 -0
  317. package/dist/runtime/errors.d.ts.map +1 -0
  318. package/dist/runtime/errors.js +42 -0
  319. package/dist/runtime/errors.js.map +1 -0
  320. package/dist/runtime/herdr/HerdrAgentDiscovery.d.ts +18 -0
  321. package/dist/runtime/herdr/HerdrAgentDiscovery.d.ts.map +1 -0
  322. package/dist/runtime/herdr/HerdrAgentDiscovery.js +183 -0
  323. package/dist/runtime/herdr/HerdrAgentDiscovery.js.map +1 -0
  324. package/dist/runtime/herdr/HerdrAgentRuntime.d.ts +36 -0
  325. package/dist/runtime/herdr/HerdrAgentRuntime.d.ts.map +1 -0
  326. package/dist/runtime/herdr/HerdrAgentRuntime.js +202 -0
  327. package/dist/runtime/herdr/HerdrAgentRuntime.js.map +1 -0
  328. package/dist/runtime/herdr/HerdrCliClient.d.ts +13 -0
  329. package/dist/runtime/herdr/HerdrCliClient.d.ts.map +1 -0
  330. package/dist/runtime/herdr/HerdrCliClient.js +60 -0
  331. package/dist/runtime/herdr/HerdrCliClient.js.map +1 -0
  332. package/dist/runtime/herdr/HerdrErrors.d.ts +7 -0
  333. package/dist/runtime/herdr/HerdrErrors.d.ts.map +1 -0
  334. package/dist/runtime/herdr/HerdrErrors.js +10 -0
  335. package/dist/runtime/herdr/HerdrErrors.js.map +1 -0
  336. package/dist/runtime/herdr/HerdrResponseParsers.d.ts +16 -0
  337. package/dist/runtime/herdr/HerdrResponseParsers.d.ts.map +1 -0
  338. package/dist/runtime/herdr/HerdrResponseParsers.js +107 -0
  339. package/dist/runtime/herdr/HerdrResponseParsers.js.map +1 -0
  340. package/dist/runtime/herdr/HerdrRuntimeRef.d.ts +9 -0
  341. package/dist/runtime/herdr/HerdrRuntimeRef.d.ts.map +1 -0
  342. package/dist/runtime/herdr/HerdrRuntimeRef.js +33 -0
  343. package/dist/runtime/herdr/HerdrRuntimeRef.js.map +1 -0
  344. package/dist/runtime/tmux/PidPolling.d.ts +5 -0
  345. package/dist/runtime/tmux/PidPolling.d.ts.map +1 -0
  346. package/dist/runtime/tmux/PidPolling.js +24 -0
  347. package/dist/runtime/tmux/PidPolling.js.map +1 -0
  348. package/dist/runtime/tmux/TmuxAgentRuntime.d.ts +17 -0
  349. package/dist/runtime/tmux/TmuxAgentRuntime.d.ts.map +1 -0
  350. package/dist/runtime/tmux/TmuxAgentRuntime.js +80 -0
  351. package/dist/runtime/tmux/TmuxAgentRuntime.js.map +1 -0
  352. package/dist/runtime/tmux/TmuxRuntimeRef.d.ts +5 -0
  353. package/dist/runtime/tmux/TmuxRuntimeRef.d.ts.map +1 -0
  354. package/dist/runtime/tmux/TmuxRuntimeRef.js +9 -0
  355. package/dist/runtime/tmux/TmuxRuntimeRef.js.map +1 -0
  356. package/dist/runtime/types.d.ts +54 -0
  357. package/dist/runtime/types.d.ts.map +1 -0
  358. package/dist/runtime/types.js +3 -0
  359. package/dist/runtime/types.js.map +1 -0
  360. package/dist/terminal/TerminalFocusManager.d.ts.map +1 -1
  361. package/dist/terminal/TerminalFocusManager.js +50 -50
  362. package/dist/terminal/TerminalFocusManager.js.map +1 -1
  363. package/dist/terminal/TmuxManager.d.ts.map +1 -1
  364. package/dist/terminal/TmuxManager.js +47 -47
  365. package/dist/terminal/TmuxManager.js.map +1 -1
  366. package/dist/terminal/TtyWriter.d.ts +1 -1
  367. package/dist/terminal/TtyWriter.d.ts.map +1 -1
  368. package/dist/terminal/TtyWriter.js +89 -89
  369. package/dist/terminal/TtyWriter.js.map +1 -1
  370. package/dist/terminal/index.d.ts +4 -4
  371. package/dist/terminal/index.js +3 -3
  372. package/dist/terminal/index.js.map +1 -1
  373. package/dist/utils/AgentRegistry.d.ts +10 -2
  374. package/dist/utils/AgentRegistry.d.ts.map +1 -1
  375. package/dist/utils/AgentRegistry.js +59 -26
  376. package/dist/utils/AgentRegistry.js.map +1 -1
  377. package/dist/utils/agent-requests.d.ts.map +1 -1
  378. package/dist/utils/agent-requests.js +5 -5
  379. package/dist/utils/agent-requests.js.map +1 -1
  380. package/dist/utils/agents.d.ts +2 -2
  381. package/dist/utils/agents.d.ts.map +1 -1
  382. package/dist/utils/agents.js +15 -15
  383. package/dist/utils/agents.js.map +1 -1
  384. package/dist/utils/applescript.js +1 -1
  385. package/dist/utils/applescript.js.map +1 -1
  386. package/dist/utils/index.d.ts +6 -6
  387. package/dist/utils/index.d.ts.map +1 -1
  388. package/dist/utils/index.js +4 -4
  389. package/dist/utils/index.js.map +1 -1
  390. package/dist/utils/matching.d.ts +2 -2
  391. package/dist/utils/matching.d.ts.map +1 -1
  392. package/dist/utils/matching.js +4 -4
  393. package/dist/utils/matching.js.map +1 -1
  394. package/dist/utils/process.d.ts +1 -1
  395. package/dist/utils/process.d.ts.map +1 -1
  396. package/dist/utils/process.js +74 -74
  397. package/dist/utils/process.js.map +1 -1
  398. package/dist/utils/session.d.ts +1 -1
  399. package/dist/utils/session.d.ts.map +1 -1
  400. package/dist/utils/session.js +7 -7
  401. package/dist/utils/session.js.map +1 -1
  402. package/dist/utils/sortAgents.d.ts +2 -2
  403. package/dist/utils/sortAgents.d.ts.map +1 -1
  404. package/dist/utils/sortAgents.js +5 -5
  405. package/dist/utils/sortAgents.js.map +1 -1
  406. package/package.json +18 -19
  407. package/src/AgentManager.ts +338 -274
  408. package/src/__tests__/AgentManager.test.ts +1143 -907
  409. package/src/__tests__/adapters/ClaudeCodeAdapter.test.ts +1657 -1368
  410. package/src/__tests__/adapters/CodexAdapter.test.ts +365 -1698
  411. package/src/__tests__/adapters/GrokCliAdapter.test.ts +325 -272
  412. package/src/__tests__/adapters/OpenCodeAdapter.test.ts +511 -455
  413. package/src/__tests__/capacity/codex.test.ts +178 -91
  414. package/src/__tests__/capacity/index.test.ts +27 -18
  415. package/src/__tests__/durable/CodexCliProbe.test.ts +75 -53
  416. package/src/__tests__/durable/CodexDurableAgentRepository.test.ts +51 -40
  417. package/src/__tests__/durable/CodexPrintAgent.integration.test.ts +89 -64
  418. package/src/__tests__/durable/CodexPrintAgentService.test.ts +196 -118
  419. package/src/__tests__/durable/CodexPrintRunner.test.ts +282 -162
  420. package/src/__tests__/fixtures/fake-claude.cjs +20 -13
  421. package/src/__tests__/fixtures/fake-codex.cjs +41 -30
  422. package/src/__tests__/print/ClaudeCliProbe.test.ts +27 -21
  423. package/src/__tests__/print/ClaudePrintAgent.integration.test.ts +48 -40
  424. package/src/__tests__/print/ClaudePrintAgentService.test.ts +118 -67
  425. package/src/__tests__/print/ClaudePrintRunner.test.ts +136 -83
  426. package/src/__tests__/print/DurableAgent.test.ts +19 -16
  427. package/src/__tests__/print/DurableAgentRepository.sqlite.test.ts +109 -86
  428. package/src/__tests__/print/DurableAgentRepository.test.ts +170 -137
  429. package/src/__tests__/providers/claude/ClaudeAgentMapper.test.ts +65 -65
  430. package/src/__tests__/providers/claude/ClaudeSessionLocator.test.ts +400 -377
  431. package/src/__tests__/providers/codex/CodexSessionLocator.test.ts +182 -0
  432. package/src/__tests__/providers/codex/CodexSessionMapping.test.ts +63 -0
  433. package/src/__tests__/providers/codex/CodexSessionParser.test.ts +192 -0
  434. package/src/__tests__/providers/copilot/CopilotAdapter.test.ts +602 -0
  435. package/src/__tests__/providers/gemini/GeminiCliAdapter.test.ts +1299 -0
  436. package/src/__tests__/providers/pi/PiAdapter.test.ts +310 -0
  437. package/src/__tests__/providers/pi/PiSessionParser.test.ts +190 -0
  438. package/src/__tests__/providers/pi/PiSessionTracker.test.ts +79 -0
  439. package/src/__tests__/providers/pi/durable/PiCliProbe.test.ts +48 -32
  440. package/src/__tests__/providers/pi/durable/PiDurableAgentRepository.test.ts +24 -23
  441. package/src/__tests__/providers/pi/durable/PiPrintAgentService.test.ts +131 -59
  442. package/src/__tests__/providers/pi/durable/PiPrintProtocol.test.ts +66 -28
  443. package/src/__tests__/providers/pi/durable/PiPrintRunner.test.ts +236 -90
  444. package/src/__tests__/providers/pi/durable/PiStreamParser.test.ts +20 -18
  445. package/src/__tests__/readiness/AgentReadiness.test.ts +217 -169
  446. package/src/__tests__/runtime/AgentRuntime.test.ts +8 -0
  447. package/src/__tests__/runtime/HerdrAgentDiscovery.test.ts +131 -0
  448. package/src/__tests__/runtime/HerdrAgentRuntime.test.ts +377 -0
  449. package/src/__tests__/runtime/ManagedAgentRuntime.test.ts +555 -0
  450. package/src/__tests__/terminal/TerminalFocusManager.test.ts +254 -253
  451. package/src/__tests__/terminal/TmuxManager.test.ts +157 -157
  452. package/src/__tests__/terminal/TtyWriter.test.ts +423 -419
  453. package/src/__tests__/utils/AgentRegistry.test.ts +516 -402
  454. package/src/__tests__/utils/ClaudeSessionParser.test.ts +276 -242
  455. package/src/__tests__/utils/agent-requests.test.ts +76 -56
  456. package/src/__tests__/utils/agents.test.ts +20 -20
  457. package/src/__tests__/utils/matching.test.ts +206 -171
  458. package/src/__tests__/utils/process.test.ts +276 -262
  459. package/src/__tests__/utils/session.test.ts +133 -139
  460. package/src/adapters/AgentAdapter.ts +134 -126
  461. package/src/adapters/GrokCliAdapter.ts +353 -342
  462. package/src/adapters/OpenCodeAdapter.ts +289 -259
  463. package/src/adapters/index.ts +15 -9
  464. package/src/capacity/codex.ts +137 -84
  465. package/src/capacity/index.ts +18 -13
  466. package/src/capacity/types.ts +1 -1
  467. package/src/database/connection.ts +73 -68
  468. package/src/database/index.ts +6 -6
  469. package/src/database/migrations/005_agent_runtime.sql +2 -0
  470. package/src/database/schema.ts +40 -38
  471. package/src/durable/DurableAgent.ts +85 -85
  472. package/src/durable/DurableAgentRepository.ts +409 -260
  473. package/src/durable/process.ts +22 -21
  474. package/src/durable/run.ts +61 -51
  475. package/src/durable/utils.ts +46 -41
  476. package/src/index.ts +151 -103
  477. package/src/providers/claude/ClaudeAgentMapper.ts +51 -50
  478. package/src/providers/claude/ClaudeCodeAdapter.ts +144 -136
  479. package/src/providers/claude/ClaudeSessionLocator.ts +291 -293
  480. package/src/providers/claude/ClaudeSessionParser.ts +322 -338
  481. package/src/providers/claude/durable/ClaudeCliProbe.ts +42 -37
  482. package/src/providers/claude/durable/ClaudePrintAgentService.ts +63 -50
  483. package/src/providers/claude/durable/ClaudePrintRunner.ts +79 -69
  484. package/src/providers/claude/durable/ClaudeStreamParser.ts +91 -62
  485. package/src/providers/codex/CodexAdapter.ts +205 -0
  486. package/src/providers/codex/CodexAgentMapper.ts +35 -0
  487. package/src/providers/codex/CodexSessionLocator.ts +279 -0
  488. package/src/providers/codex/CodexSessionMapping.ts +89 -0
  489. package/src/providers/codex/CodexSessionParser.ts +385 -0
  490. package/src/providers/codex/durable/CodexCliProbe.ts +50 -42
  491. package/src/providers/codex/durable/CodexPrintAgentService.ts +63 -49
  492. package/src/providers/codex/durable/CodexPrintRunner.ts +79 -69
  493. package/src/providers/codex/durable/CodexStreamParser.ts +97 -84
  494. package/src/providers/copilot/CopilotAdapter.ts +145 -0
  495. package/src/providers/copilot/CopilotAgentMapper.ts +36 -0
  496. package/src/providers/copilot/CopilotSessionLocator.ts +57 -0
  497. package/src/providers/copilot/CopilotSessionParser.ts +289 -0
  498. package/src/providers/gemini/GeminiAgentMapper.ts +36 -0
  499. package/src/providers/gemini/GeminiCliAdapter.ts +266 -0
  500. package/src/providers/gemini/GeminiSessionLocator.ts +183 -0
  501. package/src/providers/gemini/GeminiSessionParser.ts +271 -0
  502. package/src/providers/pi/PiAdapter.ts +183 -0
  503. package/src/providers/pi/PiAgentMapper.ts +36 -0
  504. package/src/providers/pi/PiSessionLocator.ts +95 -0
  505. package/src/providers/pi/PiSessionParser.ts +284 -0
  506. package/src/providers/pi/PiSessionTracker.ts +87 -0
  507. package/src/providers/pi/durable/PiCliProbe.ts +42 -34
  508. package/src/providers/pi/durable/PiPrintAgentService.ts +61 -53
  509. package/src/providers/pi/durable/PiPrintProtocol.ts +31 -29
  510. package/src/providers/pi/durable/PiPrintRunner.ts +75 -68
  511. package/src/providers/pi/durable/PiStreamParser.ts +82 -72
  512. package/src/readiness/AgentReadiness.ts +585 -513
  513. package/src/runtime/ManagedAgentRuntime.ts +266 -0
  514. package/src/runtime/RuntimeFactory.ts +13 -0
  515. package/src/runtime/errors.ts +50 -0
  516. package/src/runtime/herdr/HerdrAgentDiscovery.ts +178 -0
  517. package/src/runtime/herdr/HerdrAgentRuntime.ts +216 -0
  518. package/src/runtime/herdr/HerdrCliClient.ts +78 -0
  519. package/src/runtime/herdr/HerdrErrors.ts +9 -0
  520. package/src/runtime/herdr/HerdrResponseParsers.ts +86 -0
  521. package/src/runtime/herdr/HerdrRuntimeRef.ts +41 -0
  522. package/src/runtime/tmux/PidPolling.ts +34 -0
  523. package/src/runtime/tmux/TmuxAgentRuntime.ts +113 -0
  524. package/src/runtime/tmux/TmuxRuntimeRef.ts +9 -0
  525. package/src/runtime/types.ts +56 -0
  526. package/src/terminal/TerminalFocusManager.ts +215 -212
  527. package/src/terminal/TmuxManager.ts +99 -92
  528. package/src/terminal/TtyWriter.ts +203 -194
  529. package/src/terminal/index.ts +4 -4
  530. package/src/utils/AgentRegistry.ts +301 -238
  531. package/src/utils/agent-requests.ts +16 -16
  532. package/src/utils/agents.ts +41 -38
  533. package/src/utils/applescript.ts +4 -4
  534. package/src/utils/index.ts +12 -6
  535. package/src/utils/matching.ts +43 -43
  536. package/src/utils/process.ts +261 -258
  537. package/src/utils/session.ts +66 -66
  538. package/src/utils/sortAgents.ts +35 -33
  539. package/tsconfig.json +2 -8
  540. package/vitest.config.ts +16 -16
  541. package/.eslintrc.json +0 -31
  542. package/dist/__tests__/adapters/CopilotAdapter.test.js +0 -630
  543. package/dist/__tests__/adapters/CopilotAdapter.test.js.map +0 -1
  544. package/dist/__tests__/adapters/GeminiCliAdapter.test.js +0 -1384
  545. package/dist/__tests__/adapters/GeminiCliAdapter.test.js.map +0 -1
  546. package/dist/__tests__/adapters/PiAdapter.test.js +0 -618
  547. package/dist/__tests__/adapters/PiAdapter.test.js.map +0 -1
  548. package/dist/__tests__/database/DurableAgentsDatabase.test.js +0 -128
  549. package/dist/__tests__/database/DurableAgentsDatabase.test.js.map +0 -1
  550. package/dist/adapters/CodexAdapter.d.ts +0 -109
  551. package/dist/adapters/CodexAdapter.d.ts.map +0 -1
  552. package/dist/adapters/CodexAdapter.js +0 -710
  553. package/dist/adapters/CodexAdapter.js.map +0 -1
  554. package/dist/adapters/CopilotAdapter.d.ts.map +0 -1
  555. package/dist/adapters/CopilotAdapter.js +0 -329
  556. package/dist/adapters/CopilotAdapter.js.map +0 -1
  557. package/dist/adapters/GeminiCliAdapter.d.ts +0 -98
  558. package/dist/adapters/GeminiCliAdapter.d.ts.map +0 -1
  559. package/dist/adapters/GeminiCliAdapter.js +0 -513
  560. package/dist/adapters/GeminiCliAdapter.js.map +0 -1
  561. package/dist/adapters/PiAdapter.d.ts +0 -63
  562. package/dist/adapters/PiAdapter.d.ts.map +0 -1
  563. package/dist/adapters/PiAdapter.js +0 -453
  564. package/dist/adapters/PiAdapter.js.map +0 -1
  565. package/src/__tests__/adapters/CopilotAdapter.test.ts +0 -510
  566. package/src/__tests__/adapters/GeminiCliAdapter.test.ts +0 -1259
  567. package/src/__tests__/adapters/PiAdapter.test.ts +0 -458
  568. package/src/__tests__/database/DurableAgentsDatabase.test.ts +0 -102
  569. package/src/adapters/CodexAdapter.ts +0 -923
  570. package/src/adapters/CopilotAdapter.ts +0 -473
  571. package/src/adapters/GeminiCliAdapter.ts +0 -701
  572. package/src/adapters/PiAdapter.ts +0 -598
@@ -1,21 +1,26 @@
1
- import os from 'os';
2
- import path from 'path';
3
- import { DatabaseConnection, resolveAgentRegistryDbPath } from '../database/index.js';
1
+ import os from "os";
2
+ import path from "path";
3
+ import { DatabaseConnection, resolveAgentRegistryDbPath } from "../database/index.js";
4
+ import { parseTmuxRuntimeRef } from "../runtime/tmux/TmuxRuntimeRef.js";
4
5
  export class RenameNotFoundError extends Error {
5
6
  agentName;
6
7
  constructor(agentName){
7
8
  super(`Agent "${agentName}" not found in registry.`), this.agentName = agentName;
8
- this.name = 'RenameNotFoundError';
9
+ this.name = "RenameNotFoundError";
9
10
  }
10
11
  }
11
12
  export class RenameConflictError extends Error {
12
13
  agentName;
13
14
  constructor(agentName){
14
15
  super(`Agent "${agentName}" is already in use.`), this.agentName = agentName;
15
- this.name = 'RenameConflictError';
16
+ this.name = "RenameConflictError";
16
17
  }
17
18
  }
18
- const DEFAULT_REGISTRY_PATH = path.join(os.homedir(), '.ai-devkit', 'agents.json');
19
+ export const AGENT_RUNTIME_PROVIDERS = [
20
+ "tmux",
21
+ "herdr"
22
+ ];
23
+ const DEFAULT_REGISTRY_PATH = path.join(os.homedir(), ".ai-devkit", "agents.json");
19
24
  const DEFAULT_PRUNE_INTERVAL_MS = 30_000;
20
25
  let defaultInstance = null;
21
26
  export class AgentRegistry {
@@ -41,11 +46,13 @@ export class AgentRegistry {
41
46
  return defaultInstance;
42
47
  }
43
48
  rowToEntry(row) {
49
+ const runtime = this.parseRuntime(row.runtime);
44
50
  return {
45
51
  name: row.name,
46
52
  type: row.type,
47
53
  pid: row.pid,
48
- tmuxSession: row.tmux_session,
54
+ runtime,
55
+ runtimeRef: this.parseRuntimeRef(runtime, row.runtime_ref, row.tmux_session),
49
56
  cwd: row.cwd,
50
57
  startedAt: row.started_at,
51
58
  sessionId: row.session_id,
@@ -54,47 +61,66 @@ export class AgentRegistry {
54
61
  updatedAt: row.updated_at
55
62
  };
56
63
  }
64
+ parseRuntime(value) {
65
+ return value === "herdr" ? "herdr" : "tmux";
66
+ }
67
+ parseRuntimeRef(runtime, raw, legacyTmuxSession) {
68
+ if (raw) {
69
+ try {
70
+ return JSON.parse(raw);
71
+ } catch {
72
+ return null;
73
+ }
74
+ }
75
+ if (runtime === "tmux" && legacyTmuxSession) {
76
+ return {
77
+ session: legacyTmuxSession
78
+ };
79
+ }
80
+ return null;
81
+ }
57
82
  mergeEntry(incoming, existing) {
58
83
  if (!existing) return incoming;
59
- const incomingIsManaged = Boolean(incoming.tmuxSession);
84
+ const keepExistingRuntime = existing.runtime === "herdr" || Boolean(parseTmuxRuntimeRef(existing.runtimeRef)) || incoming.runtime !== "herdr";
60
85
  return {
61
86
  ...existing,
62
- name: incomingIsManaged ? incoming.name : existing.name,
63
- tmuxSession: incoming.tmuxSession || existing.tmuxSession,
64
- cwd: incoming.cwd || existing.cwd,
87
+ name: existing.name,
88
+ runtime: keepExistingRuntime ? existing.runtime : incoming.runtime,
89
+ runtimeRef: keepExistingRuntime ? existing.runtimeRef : incoming.runtimeRef,
90
+ cwd: existing.cwd || incoming.cwd,
65
91
  startedAt: existing.startedAt || incoming.startedAt,
66
92
  sessionId: incoming.sessionId || existing.sessionId,
67
93
  sessionFilePath: incoming.sessionFilePath || existing.sessionFilePath
68
94
  };
69
95
  }
70
96
  findByIdentity(type, pid) {
71
- const row = this.db.queryOne('SELECT * FROM agents WHERE type = ? AND pid = ?', [
97
+ const row = this.db.queryOne("SELECT * FROM agents WHERE type = ? AND pid = ?", [
72
98
  type,
73
99
  pid
74
100
  ]);
75
101
  return row ? this.rowToEntry(row) : undefined;
76
102
  }
77
103
  findByName(name) {
78
- const row = this.db.queryOne('SELECT * FROM agents WHERE name = ?', [
104
+ const row = this.db.queryOne("SELECT * FROM agents WHERE name = ?", [
79
105
  name
80
106
  ]);
81
107
  return row ? this.rowToEntry(row) : undefined;
82
108
  }
83
109
  findPidConflicts(type, pid) {
84
- return this.db.query('SELECT * FROM agents WHERE pid = ? AND type <> ?', [
110
+ return this.db.query("SELECT * FROM agents WHERE pid = ? AND type <> ?", [
85
111
  pid,
86
112
  type
87
113
  ]).map((row)=>this.rowToEntry(row));
88
114
  }
89
115
  entriesEqual(left, right) {
90
- return left.name === right.name && left.type === right.type && left.pid === right.pid && left.tmuxSession === right.tmuxSession && left.cwd === right.cwd && left.startedAt === right.startedAt && left.sessionId === right.sessionId && left.sessionFilePath === right.sessionFilePath;
116
+ return left.name === right.name && left.type === right.type && left.pid === right.pid && left.runtime === right.runtime && JSON.stringify(left.runtimeRef ?? null) === JSON.stringify(right.runtimeRef ?? null) && left.cwd === right.cwd && left.startedAt === right.startedAt && left.sessionId === right.sessionId && left.sessionFilePath === right.sessionFilePath;
91
117
  }
92
118
  deleteNameConflict(name, type, pid) {
93
119
  const conflict = this.findByName(name);
94
120
  if (!conflict) return;
95
121
  if (conflict.type === type && conflict.pid === pid) return;
96
122
  if (!this.isAlive(conflict)) {
97
- this.db.execute('DELETE FROM agents WHERE type = ? AND pid = ?', [
123
+ this.db.execute("DELETE FROM agents WHERE type = ? AND pid = ?", [
98
124
  conflict.type,
99
125
  conflict.pid
100
126
  ]);
@@ -104,13 +130,17 @@ export class AgentRegistry {
104
130
  this.db.instance.prepare(`
105
131
  INSERT INTO agents (
106
132
  type, pid, name, tmux_session, cwd, started_at, session_id, session_file_path, updated_at
133
+ , runtime, runtime_ref
107
134
  )
108
135
  VALUES (
109
- @type, @pid, @name, @tmuxSession, @cwd, @startedAt, @sessionId, @sessionFilePath, @updatedAt
136
+ @type, @pid, @name, @legacyTmuxSession, @cwd, @startedAt, @sessionId, @sessionFilePath, @updatedAt
137
+ , @runtime, @runtimeRefJson
110
138
  )
111
139
  ON CONFLICT(type, pid) DO UPDATE SET
112
140
  name = excluded.name,
113
141
  tmux_session = excluded.tmux_session,
142
+ runtime = excluded.runtime,
143
+ runtime_ref = excluded.runtime_ref,
114
144
  cwd = excluded.cwd,
115
145
  started_at = agents.started_at,
116
146
  session_id = excluded.session_id,
@@ -118,6 +148,8 @@ export class AgentRegistry {
118
148
  updated_at = excluded.updated_at
119
149
  `).run({
120
150
  ...entry,
151
+ legacyTmuxSession: parseTmuxRuntimeRef(entry.runtimeRef)?.session ?? "",
152
+ runtimeRefJson: JSON.stringify(entry.runtimeRef ?? null),
121
153
  updatedAt: this.now().toISOString()
122
154
  });
123
155
  }
@@ -132,7 +164,7 @@ export class AgentRegistry {
132
164
  const pidConflicts = this.findPidConflicts(incoming.type, incoming.pid);
133
165
  if (existing && this.entriesEqual(merged, existing) && pidConflicts.length === 0) return;
134
166
  for (const conflict of pidConflicts){
135
- this.db.execute('DELETE FROM agents WHERE type = ? AND pid = ?', [
167
+ this.db.execute("DELETE FROM agents WHERE type = ? AND pid = ?", [
136
168
  conflict.type,
137
169
  conflict.pid
138
170
  ]);
@@ -146,8 +178,8 @@ export class AgentRegistry {
146
178
  process.kill(entry.pid, 0);
147
179
  return true;
148
180
  } catch (error) {
149
- const code = error && typeof error === 'object' && 'code' in error ? error.code : undefined;
150
- return code !== 'ESRCH';
181
+ const code = error && typeof error === "object" && "code" in error ? error.code : undefined;
182
+ return code !== "ESRCH";
151
183
  }
152
184
  }
153
185
  pruneAt(nowMs) {
@@ -156,7 +188,7 @@ export class AgentRegistry {
156
188
  if (stale.length > 0) {
157
189
  this.db.transaction(()=>{
158
190
  for (const entry of stale){
159
- this.db.execute('DELETE FROM agents WHERE type = ? AND pid = ?', [
191
+ this.db.execute("DELETE FROM agents WHERE type = ? AND pid = ?", [
160
192
  entry.type,
161
193
  entry.pid
162
194
  ]);
@@ -199,12 +231,12 @@ export class AgentRegistry {
199
231
  }
200
232
  this.db.transaction(()=>{
201
233
  if (conflict) {
202
- this.db.execute('DELETE FROM agents WHERE type = ? AND pid = ?', [
234
+ this.db.execute("DELETE FROM agents WHERE type = ? AND pid = ?", [
203
235
  conflict.type,
204
236
  conflict.pid
205
237
  ]);
206
238
  }
207
- this.db.execute('UPDATE agents SET name = ?, updated_at = ? WHERE type = ? AND pid = ?', [
239
+ this.db.execute("UPDATE agents SET name = ?, updated_at = ? WHERE type = ? AND pid = ?", [
208
240
  newName,
209
241
  this.now().toISOString(),
210
242
  existing.type,
@@ -214,9 +246,9 @@ export class AgentRegistry {
214
246
  }
215
247
  togglePin(type, pid) {
216
248
  if (this.readonly) {
217
- throw new Error('Agent registry is readonly; cannot toggle pin.');
249
+ throw new Error("Agent registry is readonly; cannot toggle pin.");
218
250
  }
219
- const result = this.db.execute('UPDATE agents SET pinned = NOT pinned, updated_at = ? WHERE type = ? AND pid = ?', [
251
+ const result = this.db.execute("UPDATE agents SET pinned = NOT pinned, updated_at = ? WHERE type = ? AND pid = ?", [
220
252
  this.now().toISOString(),
221
253
  type,
222
254
  pid
@@ -228,9 +260,10 @@ export class AgentRegistry {
228
260
  return this.findByName(name) ?? null;
229
261
  }
230
262
  list() {
231
- const rows = this.db.query('SELECT * FROM agents ORDER BY started_at ASC, name ASC');
263
+ const rows = this.db.query("SELECT * FROM agents ORDER BY started_at ASC, name ASC");
232
264
  return rows.map((row)=>this.rowToEntry(row));
233
265
  }
234
266
  }
267
+ export { parseTmuxRuntimeRef };
235
268
 
236
269
  //# sourceMappingURL=AgentRegistry.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/AgentRegistry.ts"],"sourcesContent":["import os from 'os';\nimport path from 'path';\nimport type { AgentType } from '../adapters/AgentAdapter.js';\nimport {\n DatabaseConnection,\n resolveAgentRegistryDbPath,\n} from '../database/index.js';\n\nexport class RenameNotFoundError extends Error {\n constructor(public agentName: string) {\n super(`Agent \"${agentName}\" not found in registry.`);\n this.name = 'RenameNotFoundError';\n }\n}\n\nexport class RenameConflictError extends Error {\n constructor(public agentName: string) {\n super(`Agent \"${agentName}\" is already in use.`);\n this.name = 'RenameConflictError';\n }\n}\n\nexport interface RegistryEntry {\n name: string;\n type: AgentType;\n pid: number;\n tmuxSession: string;\n cwd: string;\n startedAt: string; // ISO 8601\n sessionId: string;\n sessionFilePath: string;\n pinned: boolean;\n updatedAt?: string;\n}\n\ninterface RegistryRow {\n name: string;\n type: AgentType;\n pid: number;\n tmux_session: string;\n cwd: string;\n started_at: string;\n session_id: string;\n session_file_path: string;\n updated_at: string;\n pinned: number;\n}\n\nconst DEFAULT_REGISTRY_PATH = path.join(os.homedir(), '.ai-devkit', 'agents.json');\nconst DEFAULT_PRUNE_INTERVAL_MS = 30_000;\n\nlet defaultInstance: AgentRegistry | null = null;\n\nexport interface AgentRegistryOptions {\n now?: () => Date;\n pruneIntervalMs?: number;\n onDatabaseOperation?: (sql: string) => void;\n readonly?: boolean;\n}\n\nexport class AgentRegistry {\n private db: DatabaseConnection;\n private readonly now: () => Date;\n private readonly pruneIntervalMs: number;\n private readonly readonly: boolean;\n private lastPrunedAt: number | undefined;\n\n constructor(filePath: string = DEFAULT_REGISTRY_PATH, options: AgentRegistryOptions = {}) {\n this.now = options.now ?? (() => new Date());\n this.pruneIntervalMs = options.pruneIntervalMs ?? DEFAULT_PRUNE_INTERVAL_MS;\n this.readonly = options.readonly ?? false;\n this.db = new DatabaseConnection({\n dbPath: resolveAgentRegistryDbPath(filePath),\n verbose: options.onDatabaseOperation,\n readonly: this.readonly,\n });\n }\n\n static default(): AgentRegistry {\n if (!defaultInstance) {\n defaultInstance = new AgentRegistry();\n }\n return defaultInstance;\n }\n\n private rowToEntry(row: RegistryRow): RegistryEntry {\n return {\n name: row.name,\n type: row.type,\n pid: row.pid,\n tmuxSession: row.tmux_session,\n cwd: row.cwd,\n startedAt: row.started_at,\n sessionId: row.session_id,\n sessionFilePath: row.session_file_path,\n pinned: row.pinned !== 0,\n updatedAt: row.updated_at,\n };\n }\n\n private mergeEntry(incoming: RegistryEntry, existing: RegistryEntry | undefined): RegistryEntry {\n if (!existing) return incoming;\n const incomingIsManaged = Boolean(incoming.tmuxSession);\n return {\n ...existing,\n name: incomingIsManaged ? incoming.name : existing.name,\n tmuxSession: incoming.tmuxSession || existing.tmuxSession,\n cwd: incoming.cwd || existing.cwd,\n startedAt: existing.startedAt || incoming.startedAt,\n sessionId: incoming.sessionId || existing.sessionId,\n sessionFilePath: incoming.sessionFilePath || existing.sessionFilePath,\n };\n }\n\n private findByIdentity(type: AgentType, pid: number): RegistryEntry | undefined {\n const row = this.db.queryOne<RegistryRow>(\n 'SELECT * FROM agents WHERE type = ? AND pid = ?',\n [type, pid],\n );\n return row ? this.rowToEntry(row) : undefined;\n }\n\n private findByName(name: string): RegistryEntry | undefined {\n const row = this.db.queryOne<RegistryRow>('SELECT * FROM agents WHERE name = ?', [name]);\n return row ? this.rowToEntry(row) : undefined;\n }\n\n private findPidConflicts(type: AgentType, pid: number): RegistryEntry[] {\n return this.db.query<RegistryRow>(\n 'SELECT * FROM agents WHERE pid = ? AND type <> ?',\n [pid, type],\n ).map((row) => this.rowToEntry(row));\n }\n\n private entriesEqual(left: RegistryEntry, right: RegistryEntry): boolean {\n return left.name === right.name\n && left.type === right.type\n && left.pid === right.pid\n && left.tmuxSession === right.tmuxSession\n && left.cwd === right.cwd\n && left.startedAt === right.startedAt\n && left.sessionId === right.sessionId\n && left.sessionFilePath === right.sessionFilePath;\n }\n\n private deleteNameConflict(name: string, type: AgentType, pid: number): void {\n const conflict = this.findByName(name);\n if (!conflict) return;\n if (conflict.type === type && conflict.pid === pid) return;\n if (!this.isAlive(conflict)) {\n this.db.execute('DELETE FROM agents WHERE type = ? AND pid = ?', [conflict.type, conflict.pid]);\n }\n }\n\n private insertOrUpdate(entry: RegistryEntry): void {\n this.db.instance.prepare(`\n INSERT INTO agents (\n type, pid, name, tmux_session, cwd, started_at, session_id, session_file_path, updated_at\n )\n VALUES (\n @type, @pid, @name, @tmuxSession, @cwd, @startedAt, @sessionId, @sessionFilePath, @updatedAt\n )\n ON CONFLICT(type, pid) DO UPDATE SET\n name = excluded.name,\n tmux_session = excluded.tmux_session,\n cwd = excluded.cwd,\n started_at = agents.started_at,\n session_id = excluded.session_id,\n session_file_path = excluded.session_file_path,\n updated_at = excluded.updated_at\n `).run({ ...entry, updatedAt: this.now().toISOString() });\n }\n\n private needsWrite(incoming: RegistryEntry): boolean {\n const existing = this.findByIdentity(incoming.type, incoming.pid);\n const merged = this.mergeEntry(incoming, existing);\n return !existing\n || !this.entriesEqual(merged, existing)\n || this.findPidConflicts(incoming.type, incoming.pid).length > 0;\n }\n\n private save(incoming: RegistryEntry): void {\n const existing = this.findByIdentity(incoming.type, incoming.pid);\n const merged = this.mergeEntry(incoming, existing);\n const pidConflicts = this.findPidConflicts(incoming.type, incoming.pid);\n if (existing && this.entriesEqual(merged, existing) && pidConflicts.length === 0) return;\n\n for (const conflict of pidConflicts) {\n this.db.execute('DELETE FROM agents WHERE type = ? AND pid = ?', [conflict.type, conflict.pid]);\n }\n if (existing && this.entriesEqual(merged, existing)) return;\n\n this.deleteNameConflict(merged.name, merged.type, merged.pid);\n this.insertOrUpdate(merged);\n }\n\n isAlive(entry: RegistryEntry): boolean {\n try {\n process.kill(entry.pid, 0);\n return true;\n } catch (error) {\n const code = error && typeof error === 'object' && 'code' in error\n ? error.code\n : undefined;\n return code !== 'ESRCH';\n }\n }\n\n private pruneAt(nowMs: number): void {\n const entries = this.list();\n const stale = entries.filter((e) => !this.isAlive(e));\n if (stale.length > 0) {\n this.db.transaction(() => {\n for (const entry of stale) {\n this.db.execute('DELETE FROM agents WHERE type = ? AND pid = ?', [entry.type, entry.pid]);\n }\n });\n }\n this.lastPrunedAt = nowMs;\n }\n\n prune(): void {\n this.pruneAt(this.now().getTime());\n }\n\n pruneIfDue(): void {\n const nowMs = this.now().getTime();\n const elapsed = this.lastPrunedAt === undefined ? undefined : nowMs - this.lastPrunedAt;\n if (elapsed !== undefined && elapsed >= 0 && elapsed < this.pruneIntervalMs) return;\n this.pruneAt(nowMs);\n }\n\n register(entry: RegistryEntry): void {\n this.registerBatch([entry]);\n }\n\n registerBatch(entries: RegistryEntry[]): void {\n if (entries.length === 0) return;\n if (!entries.some((entry) => this.needsWrite(entry))) return;\n this.db.transaction(() => {\n for (const incoming of entries) {\n this.save(incoming);\n }\n });\n }\n\n rename(currentName: string, newName: string): void {\n const existing = this.findByName(currentName);\n if (!existing) {\n throw new RenameNotFoundError(currentName);\n }\n const conflict = this.findByName(newName);\n if (conflict && this.isAlive(conflict)) {\n throw new RenameConflictError(newName);\n }\n\n this.db.transaction(() => {\n if (conflict) {\n this.db.execute('DELETE FROM agents WHERE type = ? AND pid = ?', [conflict.type, conflict.pid]);\n }\n this.db.execute(\n 'UPDATE agents SET name = ?, updated_at = ? WHERE type = ? AND pid = ?',\n [newName, this.now().toISOString(), existing.type, existing.pid],\n );\n });\n }\n\n togglePin(type: AgentType, pid: number): boolean | null {\n if (this.readonly) {\n throw new Error('Agent registry is readonly; cannot toggle pin.');\n }\n const result = this.db.execute(\n 'UPDATE agents SET pinned = NOT pinned, updated_at = ? WHERE type = ? AND pid = ?',\n [this.now().toISOString(), type, pid],\n );\n if (result.changes === 0) return null;\n return this.findByIdentity(type, pid)?.pinned ?? null;\n }\n\n lookup(name: string): RegistryEntry | null {\n return this.findByName(name) ?? null;\n }\n\n list(): RegistryEntry[] {\n const rows = this.db.query<RegistryRow>('SELECT * FROM agents ORDER BY started_at ASC, name ASC');\n return rows.map((row) => this.rowToEntry(row));\n }\n}\n"],"names":["os","path","DatabaseConnection","resolveAgentRegistryDbPath","RenameNotFoundError","Error","agentName","name","RenameConflictError","DEFAULT_REGISTRY_PATH","join","homedir","DEFAULT_PRUNE_INTERVAL_MS","defaultInstance","AgentRegistry","db","now","pruneIntervalMs","readonly","lastPrunedAt","filePath","options","Date","dbPath","verbose","onDatabaseOperation","default","rowToEntry","row","type","pid","tmuxSession","tmux_session","cwd","startedAt","started_at","sessionId","session_id","sessionFilePath","session_file_path","pinned","updatedAt","updated_at","mergeEntry","incoming","existing","incomingIsManaged","Boolean","findByIdentity","queryOne","undefined","findByName","findPidConflicts","query","map","entriesEqual","left","right","deleteNameConflict","conflict","isAlive","execute","insertOrUpdate","entry","instance","prepare","run","toISOString","needsWrite","merged","length","save","pidConflicts","process","kill","error","code","pruneAt","nowMs","entries","list","stale","filter","e","transaction","prune","getTime","pruneIfDue","elapsed","register","registerBatch","some","rename","currentName","newName","togglePin","result","changes","lookup","rows"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/utils/AgentRegistry.ts"],"sourcesContent":["import os from \"os\";\nimport path from \"path\";\nimport type { AgentType } from \"../adapters/AgentAdapter.js\";\nimport { DatabaseConnection, resolveAgentRegistryDbPath } from \"../database/index.js\";\nimport { parseTmuxRuntimeRef, type TmuxRuntimeRef } from \"../runtime/tmux/TmuxRuntimeRef.js\";\n\nexport class RenameNotFoundError extends Error {\n constructor(public agentName: string) {\n super(`Agent \"${agentName}\" not found in registry.`);\n this.name = \"RenameNotFoundError\";\n }\n}\n\nexport class RenameConflictError extends Error {\n constructor(public agentName: string) {\n super(`Agent \"${agentName}\" is already in use.`);\n this.name = \"RenameConflictError\";\n }\n}\n\nexport interface RegistryEntry {\n name: string;\n type: AgentType;\n pid: number;\n runtime: AgentRuntimeProvider;\n runtimeRef: unknown | null;\n cwd: string;\n startedAt: string; // ISO 8601\n sessionId: string;\n sessionFilePath: string;\n pinned: boolean;\n updatedAt?: string;\n}\n\ninterface RegistryRow {\n name: string;\n type: AgentType;\n pid: number;\n tmux_session: string;\n runtime?: string;\n runtime_ref?: string;\n cwd: string;\n started_at: string;\n session_id: string;\n session_file_path: string;\n updated_at: string;\n pinned: number;\n}\n\nexport const AGENT_RUNTIME_PROVIDERS = [\"tmux\", \"herdr\"] as const;\nexport type AgentRuntimeProvider = (typeof AGENT_RUNTIME_PROVIDERS)[number];\n\nconst DEFAULT_REGISTRY_PATH = path.join(os.homedir(), \".ai-devkit\", \"agents.json\");\nconst DEFAULT_PRUNE_INTERVAL_MS = 30_000;\n\nlet defaultInstance: AgentRegistry | null = null;\n\nexport interface AgentRegistryOptions {\n now?: () => Date;\n pruneIntervalMs?: number;\n onDatabaseOperation?: (sql: string) => void;\n readonly?: boolean;\n}\n\nexport class AgentRegistry {\n private db: DatabaseConnection;\n private readonly now: () => Date;\n private readonly pruneIntervalMs: number;\n private readonly readonly: boolean;\n private lastPrunedAt: number | undefined;\n\n constructor(filePath: string = DEFAULT_REGISTRY_PATH, options: AgentRegistryOptions = {}) {\n this.now = options.now ?? (() => new Date());\n this.pruneIntervalMs = options.pruneIntervalMs ?? DEFAULT_PRUNE_INTERVAL_MS;\n this.readonly = options.readonly ?? false;\n this.db = new DatabaseConnection({\n dbPath: resolveAgentRegistryDbPath(filePath),\n verbose: options.onDatabaseOperation,\n readonly: this.readonly,\n });\n }\n\n static default(): AgentRegistry {\n if (!defaultInstance) {\n defaultInstance = new AgentRegistry();\n }\n return defaultInstance;\n }\n\n private rowToEntry(row: RegistryRow): RegistryEntry {\n const runtime = this.parseRuntime(row.runtime);\n return {\n name: row.name,\n type: row.type,\n pid: row.pid,\n runtime,\n runtimeRef: this.parseRuntimeRef(runtime, row.runtime_ref, row.tmux_session),\n cwd: row.cwd,\n startedAt: row.started_at,\n sessionId: row.session_id,\n sessionFilePath: row.session_file_path,\n pinned: row.pinned !== 0,\n updatedAt: row.updated_at,\n };\n }\n\n private parseRuntime(value: string | undefined): AgentRuntimeProvider {\n return value === \"herdr\" ? \"herdr\" : \"tmux\";\n }\n\n private parseRuntimeRef(\n runtime: AgentRuntimeProvider,\n raw: string | undefined,\n legacyTmuxSession: string,\n ): unknown | null {\n if (raw) {\n try {\n return JSON.parse(raw) as unknown;\n } catch {\n return null;\n }\n }\n\n if (runtime === \"tmux\" && legacyTmuxSession) {\n return { session: legacyTmuxSession };\n }\n\n return null;\n }\n\n private mergeEntry(incoming: RegistryEntry, existing: RegistryEntry | undefined): RegistryEntry {\n if (!existing) return incoming;\n const keepExistingRuntime =\n existing.runtime === \"herdr\" ||\n Boolean(parseTmuxRuntimeRef(existing.runtimeRef)) ||\n incoming.runtime !== \"herdr\";\n return {\n ...existing,\n name: existing.name,\n runtime: keepExistingRuntime ? existing.runtime : incoming.runtime,\n runtimeRef: keepExistingRuntime ? existing.runtimeRef : incoming.runtimeRef,\n cwd: existing.cwd || incoming.cwd,\n startedAt: existing.startedAt || incoming.startedAt,\n sessionId: incoming.sessionId || existing.sessionId,\n sessionFilePath: incoming.sessionFilePath || existing.sessionFilePath,\n };\n }\n\n private findByIdentity(type: AgentType, pid: number): RegistryEntry | undefined {\n const row = this.db.queryOne<RegistryRow>(\"SELECT * FROM agents WHERE type = ? AND pid = ?\", [\n type,\n pid,\n ]);\n return row ? this.rowToEntry(row) : undefined;\n }\n\n private findByName(name: string): RegistryEntry | undefined {\n const row = this.db.queryOne<RegistryRow>(\"SELECT * FROM agents WHERE name = ?\", [name]);\n return row ? this.rowToEntry(row) : undefined;\n }\n\n private findPidConflicts(type: AgentType, pid: number): RegistryEntry[] {\n return this.db\n .query<RegistryRow>(\"SELECT * FROM agents WHERE pid = ? AND type <> ?\", [pid, type])\n .map((row) => this.rowToEntry(row));\n }\n\n private entriesEqual(left: RegistryEntry, right: RegistryEntry): boolean {\n return (\n left.name === right.name &&\n left.type === right.type &&\n left.pid === right.pid &&\n left.runtime === right.runtime &&\n JSON.stringify(left.runtimeRef ?? null) === JSON.stringify(right.runtimeRef ?? null) &&\n left.cwd === right.cwd &&\n left.startedAt === right.startedAt &&\n left.sessionId === right.sessionId &&\n left.sessionFilePath === right.sessionFilePath\n );\n }\n\n private deleteNameConflict(name: string, type: AgentType, pid: number): void {\n const conflict = this.findByName(name);\n if (!conflict) return;\n if (conflict.type === type && conflict.pid === pid) return;\n if (!this.isAlive(conflict)) {\n this.db.execute(\"DELETE FROM agents WHERE type = ? AND pid = ?\", [\n conflict.type,\n conflict.pid,\n ]);\n }\n }\n\n private insertOrUpdate(entry: RegistryEntry): void {\n this.db.instance\n .prepare(`\n INSERT INTO agents (\n type, pid, name, tmux_session, cwd, started_at, session_id, session_file_path, updated_at\n , runtime, runtime_ref\n )\n VALUES (\n @type, @pid, @name, @legacyTmuxSession, @cwd, @startedAt, @sessionId, @sessionFilePath, @updatedAt\n , @runtime, @runtimeRefJson\n )\n ON CONFLICT(type, pid) DO UPDATE SET\n name = excluded.name,\n tmux_session = excluded.tmux_session,\n runtime = excluded.runtime,\n runtime_ref = excluded.runtime_ref,\n cwd = excluded.cwd,\n started_at = agents.started_at,\n session_id = excluded.session_id,\n session_file_path = excluded.session_file_path,\n updated_at = excluded.updated_at\n `)\n .run({\n ...entry,\n legacyTmuxSession: parseTmuxRuntimeRef(entry.runtimeRef)?.session ?? \"\",\n runtimeRefJson: JSON.stringify(entry.runtimeRef ?? null),\n updatedAt: this.now().toISOString(),\n });\n }\n\n private needsWrite(incoming: RegistryEntry): boolean {\n const existing = this.findByIdentity(incoming.type, incoming.pid);\n const merged = this.mergeEntry(incoming, existing);\n return (\n !existing ||\n !this.entriesEqual(merged, existing) ||\n this.findPidConflicts(incoming.type, incoming.pid).length > 0\n );\n }\n\n private save(incoming: RegistryEntry): void {\n const existing = this.findByIdentity(incoming.type, incoming.pid);\n const merged = this.mergeEntry(incoming, existing);\n const pidConflicts = this.findPidConflicts(incoming.type, incoming.pid);\n if (existing && this.entriesEqual(merged, existing) && pidConflicts.length === 0) return;\n\n for (const conflict of pidConflicts) {\n this.db.execute(\"DELETE FROM agents WHERE type = ? AND pid = ?\", [\n conflict.type,\n conflict.pid,\n ]);\n }\n if (existing && this.entriesEqual(merged, existing)) return;\n\n this.deleteNameConflict(merged.name, merged.type, merged.pid);\n this.insertOrUpdate(merged);\n }\n\n isAlive(entry: RegistryEntry): boolean {\n try {\n process.kill(entry.pid, 0);\n return true;\n } catch (error) {\n const code = error && typeof error === \"object\" && \"code\" in error ? error.code : undefined;\n return code !== \"ESRCH\";\n }\n }\n\n private pruneAt(nowMs: number): void {\n const entries = this.list();\n const stale = entries.filter((e) => !this.isAlive(e));\n if (stale.length > 0) {\n this.db.transaction(() => {\n for (const entry of stale) {\n this.db.execute(\"DELETE FROM agents WHERE type = ? AND pid = ?\", [entry.type, entry.pid]);\n }\n });\n }\n this.lastPrunedAt = nowMs;\n }\n\n prune(): void {\n this.pruneAt(this.now().getTime());\n }\n\n pruneIfDue(): void {\n const nowMs = this.now().getTime();\n const elapsed = this.lastPrunedAt === undefined ? undefined : nowMs - this.lastPrunedAt;\n if (elapsed !== undefined && elapsed >= 0 && elapsed < this.pruneIntervalMs) return;\n this.pruneAt(nowMs);\n }\n\n register(entry: RegistryEntry): void {\n this.registerBatch([entry]);\n }\n\n registerBatch(entries: RegistryEntry[]): void {\n if (entries.length === 0) return;\n if (!entries.some((entry) => this.needsWrite(entry))) return;\n this.db.transaction(() => {\n for (const incoming of entries) {\n this.save(incoming);\n }\n });\n }\n\n rename(currentName: string, newName: string): void {\n const existing = this.findByName(currentName);\n if (!existing) {\n throw new RenameNotFoundError(currentName);\n }\n const conflict = this.findByName(newName);\n if (conflict && this.isAlive(conflict)) {\n throw new RenameConflictError(newName);\n }\n\n this.db.transaction(() => {\n if (conflict) {\n this.db.execute(\"DELETE FROM agents WHERE type = ? AND pid = ?\", [\n conflict.type,\n conflict.pid,\n ]);\n }\n this.db.execute(\"UPDATE agents SET name = ?, updated_at = ? WHERE type = ? AND pid = ?\", [\n newName,\n this.now().toISOString(),\n existing.type,\n existing.pid,\n ]);\n });\n }\n\n togglePin(type: AgentType, pid: number): boolean | null {\n if (this.readonly) {\n throw new Error(\"Agent registry is readonly; cannot toggle pin.\");\n }\n const result = this.db.execute(\n \"UPDATE agents SET pinned = NOT pinned, updated_at = ? WHERE type = ? AND pid = ?\",\n [this.now().toISOString(), type, pid],\n );\n if (result.changes === 0) return null;\n return this.findByIdentity(type, pid)?.pinned ?? null;\n }\n\n lookup(name: string): RegistryEntry | null {\n return this.findByName(name) ?? null;\n }\n\n list(): RegistryEntry[] {\n const rows = this.db.query<RegistryRow>(\n \"SELECT * FROM agents ORDER BY started_at ASC, name ASC\",\n );\n return rows.map((row) => this.rowToEntry(row));\n }\n}\n\nexport { parseTmuxRuntimeRef };\nexport type { TmuxRuntimeRef };\n"],"names":["os","path","DatabaseConnection","resolveAgentRegistryDbPath","parseTmuxRuntimeRef","RenameNotFoundError","Error","agentName","name","RenameConflictError","AGENT_RUNTIME_PROVIDERS","DEFAULT_REGISTRY_PATH","join","homedir","DEFAULT_PRUNE_INTERVAL_MS","defaultInstance","AgentRegistry","db","now","pruneIntervalMs","readonly","lastPrunedAt","filePath","options","Date","dbPath","verbose","onDatabaseOperation","default","rowToEntry","row","runtime","parseRuntime","type","pid","runtimeRef","parseRuntimeRef","runtime_ref","tmux_session","cwd","startedAt","started_at","sessionId","session_id","sessionFilePath","session_file_path","pinned","updatedAt","updated_at","value","raw","legacyTmuxSession","JSON","parse","session","mergeEntry","incoming","existing","keepExistingRuntime","Boolean","findByIdentity","queryOne","undefined","findByName","findPidConflicts","query","map","entriesEqual","left","right","stringify","deleteNameConflict","conflict","isAlive","execute","insertOrUpdate","entry","instance","prepare","run","runtimeRefJson","toISOString","needsWrite","merged","length","save","pidConflicts","process","kill","error","code","pruneAt","nowMs","entries","list","stale","filter","e","transaction","prune","getTime","pruneIfDue","elapsed","register","registerBatch","some","rename","currentName","newName","togglePin","result","changes","lookup","rows"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"agent-requests.d.ts","sourceRoot":"","sources":["../../src/utils/agent-requests.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,YAAY;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,SAAS,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAE9E;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAO9F;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,IAAI,CAI5E"}
1
+ {"version":3,"file":"agent-requests.d.ts","sourceRoot":"","sources":["../../src/utils/agent-requests.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAE9E;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAO9F;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,IAAI,CAI5E"}
@@ -1,11 +1,11 @@
1
- import * as fs from 'fs';
2
- import * as path from 'path';
1
+ import * as fs from "fs";
2
+ import * as path from "path";
3
3
  export function getAgentRequestPath(homeDir, sessionId) {
4
- return path.join(homeDir, '.ai-devkit', 'agent-requests', `${sessionId}.json`);
4
+ return path.join(homeDir, ".ai-devkit", "agent-requests", `${sessionId}.json`);
5
5
  }
6
6
  export function readLatestAgentRequest(homeDir, sessionId) {
7
7
  try {
8
- const raw = fs.readFileSync(getAgentRequestPath(homeDir, sessionId), 'utf-8');
8
+ const raw = fs.readFileSync(getAgentRequestPath(homeDir, sessionId), "utf-8");
9
9
  return JSON.parse(raw);
10
10
  } catch {
11
11
  return null;
@@ -16,7 +16,7 @@ export function writeAgentRequest(homeDir, entry) {
16
16
  fs.mkdirSync(path.dirname(filePath), {
17
17
  recursive: true
18
18
  });
19
- fs.writeFileSync(filePath, JSON.stringify(entry, null, 2), 'utf-8');
19
+ fs.writeFileSync(filePath, JSON.stringify(entry, null, 2), "utf-8");
20
20
  }
21
21
 
22
22
  //# sourceMappingURL=agent-requests.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/agent-requests.ts"],"sourcesContent":["import * as fs from 'fs';\nimport * as path from 'path';\n\nexport interface AgentRequest {\n sessionId: string;\n toolName: string;\n toolInput: Record<string, unknown>;\n timestamp: string;\n}\n\nexport function getAgentRequestPath(homeDir: string, sessionId: string): string {\n return path.join(homeDir, '.ai-devkit', 'agent-requests', `${sessionId}.json`);\n}\n\nexport function readLatestAgentRequest(homeDir: string, sessionId: string): AgentRequest | null {\n try {\n const raw = fs.readFileSync(getAgentRequestPath(homeDir, sessionId), 'utf-8');\n return JSON.parse(raw) as AgentRequest;\n } catch {\n return null;\n }\n}\n\nexport function writeAgentRequest(homeDir: string, entry: AgentRequest): void {\n const filePath = getAgentRequestPath(homeDir, entry.sessionId);\n fs.mkdirSync(path.dirname(filePath), { recursive: true });\n fs.writeFileSync(filePath, JSON.stringify(entry, null, 2), 'utf-8');\n}\n"],"names":["fs","path","getAgentRequestPath","homeDir","sessionId","join","readLatestAgentRequest","raw","readFileSync","JSON","parse","writeAgentRequest","entry","filePath","mkdirSync","dirname","recursive","writeFileSync","stringify"],"mappings":"AAAA,YAAYA,QAAQ,KAAK;AACzB,YAAYC,UAAU,OAAO;AAS7B,OAAO,SAASC,oBAAoBC,OAAe,EAAEC,SAAiB;IAClE,OAAOH,KAAKI,IAAI,CAACF,SAAS,cAAc,kBAAkB,GAAGC,UAAU,KAAK,CAAC;AACjF;AAEA,OAAO,SAASE,uBAAuBH,OAAe,EAAEC,SAAiB;IACrE,IAAI;QACA,MAAMG,MAAMP,GAAGQ,YAAY,CAACN,oBAAoBC,SAASC,YAAY;QACrE,OAAOK,KAAKC,KAAK,CAACH;IACtB,EAAE,OAAM;QACJ,OAAO;IACX;AACJ;AAEA,OAAO,SAASI,kBAAkBR,OAAe,EAAES,KAAmB;IAClE,MAAMC,WAAWX,oBAAoBC,SAASS,MAAMR,SAAS;IAC7DJ,GAAGc,SAAS,CAACb,KAAKc,OAAO,CAACF,WAAW;QAAEG,WAAW;IAAK;IACvDhB,GAAGiB,aAAa,CAACJ,UAAUJ,KAAKS,SAAS,CAACN,OAAO,MAAM,IAAI;AAC/D"}
1
+ {"version":3,"sources":["../../src/utils/agent-requests.ts"],"sourcesContent":["import * as fs from \"fs\";\nimport * as path from \"path\";\n\nexport interface AgentRequest {\n sessionId: string;\n toolName: string;\n toolInput: Record<string, unknown>;\n timestamp: string;\n}\n\nexport function getAgentRequestPath(homeDir: string, sessionId: string): string {\n return path.join(homeDir, \".ai-devkit\", \"agent-requests\", `${sessionId}.json`);\n}\n\nexport function readLatestAgentRequest(homeDir: string, sessionId: string): AgentRequest | null {\n try {\n const raw = fs.readFileSync(getAgentRequestPath(homeDir, sessionId), \"utf-8\");\n return JSON.parse(raw) as AgentRequest;\n } catch {\n return null;\n }\n}\n\nexport function writeAgentRequest(homeDir: string, entry: AgentRequest): void {\n const filePath = getAgentRequestPath(homeDir, entry.sessionId);\n fs.mkdirSync(path.dirname(filePath), { recursive: true });\n fs.writeFileSync(filePath, JSON.stringify(entry, null, 2), \"utf-8\");\n}\n"],"names":["fs","path","getAgentRequestPath","homeDir","sessionId","join","readLatestAgentRequest","raw","readFileSync","JSON","parse","writeAgentRequest","entry","filePath","mkdirSync","dirname","recursive","writeFileSync","stringify"],"mappings":"AAAA,YAAYA,QAAQ,KAAK;AACzB,YAAYC,UAAU,OAAO;AAS7B,OAAO,SAASC,oBAAoBC,OAAe,EAAEC,SAAiB;IACpE,OAAOH,KAAKI,IAAI,CAACF,SAAS,cAAc,kBAAkB,GAAGC,UAAU,KAAK,CAAC;AAC/E;AAEA,OAAO,SAASE,uBAAuBH,OAAe,EAAEC,SAAiB;IACvE,IAAI;QACF,MAAMG,MAAMP,GAAGQ,YAAY,CAACN,oBAAoBC,SAASC,YAAY;QACrE,OAAOK,KAAKC,KAAK,CAACH;IACpB,EAAE,OAAM;QACN,OAAO;IACT;AACF;AAEA,OAAO,SAASI,kBAAkBR,OAAe,EAAES,KAAmB;IACpE,MAAMC,WAAWX,oBAAoBC,SAASS,MAAMR,SAAS;IAC7DJ,GAAGc,SAAS,CAACb,KAAKc,OAAO,CAACF,WAAW;QAAEG,WAAW;IAAK;IACvDhB,GAAGiB,aAAa,CAACJ,UAAUJ,KAAKS,SAAS,CAACN,OAAO,MAAM,IAAI;AAC7D"}
@@ -1,5 +1,5 @@
1
- import type { AgentType } from '../adapters/AgentAdapter.js';
2
- export type StartableAgentType = Extract<AgentType, 'claude' | 'codex' | 'copilot' | 'gemini_cli' | 'grok_cli' | 'opencode' | 'pi'>;
1
+ import type { AgentType } from "../adapters/AgentAdapter.js";
2
+ export type StartableAgentType = Extract<AgentType, "claude" | "codex" | "copilot" | "gemini_cli" | "grok_cli" | "opencode" | "pi">;
3
3
  export interface AgentConfig {
4
4
  /** Shell command to launch the agent (sent to tmux via `send-keys`). */
5
5
  command: string;
@@ -1 +1 @@
1
- {"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../src/utils/agents.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAE7D,MAAM,MAAM,kBAAkB,GAAG,OAAO,CAAC,SAAS,EAAE,QAAQ,GAAG,OAAO,GAAG,SAAS,GAAG,YAAY,GAAG,UAAU,GAAG,UAAU,GAAG,IAAI,CAAC,CAAC;AAEpI,MAAM,WAAW,WAAW;IACxB,wEAAwE;IACxE,OAAO,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,OAAO,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC;CAC3C;AAED;;;;GAIG;AACH,eAAO,MAAM,MAAM,EAAE,MAAM,CAAC,kBAAkB,EAAE,WAAW,CAQ1D,CAAC"}
1
+ {"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../src/utils/agents.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAE7D,MAAM,MAAM,kBAAkB,GAAG,OAAO,CACtC,SAAS,EACT,QAAQ,GAAG,OAAO,GAAG,SAAS,GAAG,YAAY,GAAG,UAAU,GAAG,UAAU,GAAG,IAAI,CAC/E,CAAC;AAEF,MAAM,WAAW,WAAW;IAC1B,wEAAwE;IACxE,OAAO,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,OAAO,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC;CACzC;AAED;;;;GAIG;AACH,eAAO,MAAM,MAAM,EAAE,MAAM,CAAC,kBAAkB,EAAE,WAAW,CAQ1D,CAAC"}
@@ -1,37 +1,37 @@
1
- import path from 'path';
1
+ import path from "path";
2
2
  /**
3
3
  * Per-agent configuration: launch command plus a matcher that recognizes the
4
4
  * agent's process in `ps` output. Each matcher knows that agent's distribution
5
5
  * quirks (e.g. gemini ships as a Node script so its real binary is in argv[1..]).
6
6
  */ export const AGENTS = {
7
7
  claude: {
8
- command: 'claude',
9
- matches: matchArgv0('claude')
8
+ command: "claude",
9
+ matches: matchArgv0("claude")
10
10
  },
11
11
  codex: {
12
- command: 'codex',
13
- matches: matchArgv0('codex')
12
+ command: "codex",
13
+ matches: matchArgv0("codex")
14
14
  },
15
15
  copilot: {
16
- command: 'copilot',
17
- matches: matchArgv0Name('copilot-cli')
16
+ command: "copilot",
17
+ matches: matchArgv0Name("copilot-cli")
18
18
  },
19
19
  gemini_cli: {
20
- command: 'gemini',
21
- matches: matchAnyToken('gemini')
20
+ command: "gemini",
21
+ matches: matchAnyToken("gemini")
22
22
  },
23
23
  grok_cli: {
24
- command: 'grok',
25
- matches: matchArgv0('grok')
24
+ command: "grok",
25
+ matches: matchArgv0("grok")
26
26
  },
27
27
  opencode: {
28
- command: 'opencode',
29
- matches: matchArgv0('opencode')
28
+ command: "opencode",
29
+ matches: matchArgv0("opencode")
30
30
  },
31
31
  pi: {
32
- command: 'pi',
32
+ command: "pi",
33
33
  matches: matchAnyBasename([
34
- 'pi'
34
+ "pi"
35
35
  ])
36
36
  }
37
37
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/agents.ts"],"sourcesContent":["import path from 'path';\nimport type { AgentType } from '../adapters/AgentAdapter.js';\n\nexport type StartableAgentType = Extract<AgentType, 'claude' | 'codex' | 'copilot' | 'gemini_cli' | 'grok_cli' | 'opencode' | 'pi'>;\n\nexport interface AgentConfig {\n /** Shell command to launch the agent (sent to tmux via `send-keys`). */\n command: string;\n /** Returns true if the given `ps` command line belongs to this agent. */\n matches: (psCommand: string) => boolean;\n}\n\n/**\n * Per-agent configuration: launch command plus a matcher that recognizes the\n * agent's process in `ps` output. Each matcher knows that agent's distribution\n * quirks (e.g. gemini ships as a Node script so its real binary is in argv[1..]).\n */\nexport const AGENTS: Record<StartableAgentType, AgentConfig> = {\n claude: { command: 'claude', matches: matchArgv0('claude') },\n codex: { command: 'codex', matches: matchArgv0('codex') },\n copilot: { command: 'copilot', matches: matchArgv0Name('copilot-cli') },\n gemini_cli: { command: 'gemini', matches: matchAnyToken('gemini') },\n grok_cli: { command: 'grok', matches: matchArgv0('grok') },\n opencode: { command: 'opencode', matches: matchArgv0('opencode') },\n pi: { command: 'pi', matches: matchAnyBasename(['pi']) },\n};\n\nfunction matchArgv0(name: string): (psCommand: string) => boolean {\n const lower = name.toLowerCase();\n return (psCommand) => {\n const token = psCommand.trim().split(/\\s+/)[0];\n return token ? path.basename(token).toLowerCase() === lower : false;\n };\n}\n\nfunction matchArgv0Name(name: string): (psCommand: string) => boolean {\n const lower = name.toLowerCase();\n return (psCommand) => {\n const token = psCommand.trim().split(/\\s+/)[0];\n return token ? token.toLowerCase().includes(lower) : false;\n };\n}\n\nfunction matchAnyToken(name: string): (psCommand: string) => boolean {\n const lower = name.toLowerCase();\n return (psCommand) => {\n for (const token of psCommand.trim().split(/\\s+/)) {\n if (path.basename(token).toLowerCase() === lower) return true;\n }\n return false;\n };\n}\n\nfunction matchAnyBasename(names: string[]): (psCommand: string) => boolean {\n const lowers = new Set(names.map((name) => name.toLowerCase()));\n return (psCommand) => {\n for (const token of psCommand.trim().split(/\\s+/)) {\n if (lowers.has(path.basename(token).toLowerCase())) return true;\n }\n return false;\n };\n}\n"],"names":["path","AGENTS","claude","command","matches","matchArgv0","codex","copilot","matchArgv0Name","gemini_cli","matchAnyToken","grok_cli","opencode","pi","matchAnyBasename","name","lower","toLowerCase","psCommand","token","trim","split","basename","includes","names","lowers","Set","map","has"],"mappings":"AAAA,OAAOA,UAAU,OAAO;AAYxB;;;;CAIC,GACD,OAAO,MAAMC,SAAkD;IAC3DC,QAAY;QAAEC,SAAS;QAAYC,SAASC,WAAW;IAAU;IACjEC,OAAY;QAAEH,SAAS;QAAYC,SAASC,WAAW;IAAS;IAChEE,SAAY;QAAEJ,SAAS;QAAYC,SAASI,eAAe;IAAe;IAC1EC,YAAY;QAAEN,SAAS;QAAYC,SAASM,cAAc;IAAU;IACpEC,UAAY;QAAER,SAAS;QAAYC,SAASC,WAAW;IAAQ;IAC/DO,UAAY;QAAET,SAAS;QAAYC,SAASC,WAAW;IAAY;IACnEQ,IAAY;QAAEV,SAAS;QAAYC,SAASU,iBAAiB;YAAC;SAAK;IAAE;AACzE,EAAE;AAEF,SAAST,WAAWU,IAAY;IAC5B,MAAMC,QAAQD,KAAKE,WAAW;IAC9B,OAAO,CAACC;QACJ,MAAMC,QAAQD,UAAUE,IAAI,GAAGC,KAAK,CAAC,MAAM,CAAC,EAAE;QAC9C,OAAOF,QAAQnB,KAAKsB,QAAQ,CAACH,OAAOF,WAAW,OAAOD,QAAQ;IAClE;AACJ;AAEA,SAASR,eAAeO,IAAY;IAChC,MAAMC,QAAQD,KAAKE,WAAW;IAC9B,OAAO,CAACC;QACJ,MAAMC,QAAQD,UAAUE,IAAI,GAAGC,KAAK,CAAC,MAAM,CAAC,EAAE;QAC9C,OAAOF,QAAQA,MAAMF,WAAW,GAAGM,QAAQ,CAACP,SAAS;IACzD;AACJ;AAEA,SAASN,cAAcK,IAAY;IAC/B,MAAMC,QAAQD,KAAKE,WAAW;IAC9B,OAAO,CAACC;QACJ,KAAK,MAAMC,SAASD,UAAUE,IAAI,GAAGC,KAAK,CAAC,OAAQ;YAC/C,IAAIrB,KAAKsB,QAAQ,CAACH,OAAOF,WAAW,OAAOD,OAAO,OAAO;QAC7D;QACA,OAAO;IACX;AACJ;AAEA,SAASF,iBAAiBU,KAAe;IACrC,MAAMC,SAAS,IAAIC,IAAIF,MAAMG,GAAG,CAAC,CAACZ,OAASA,KAAKE,WAAW;IAC3D,OAAO,CAACC;QACJ,KAAK,MAAMC,SAASD,UAAUE,IAAI,GAAGC,KAAK,CAAC,OAAQ;YAC/C,IAAII,OAAOG,GAAG,CAAC5B,KAAKsB,QAAQ,CAACH,OAAOF,WAAW,KAAK,OAAO;QAC/D;QACA,OAAO;IACX;AACJ"}
1
+ {"version":3,"sources":["../../src/utils/agents.ts"],"sourcesContent":["import path from \"path\";\nimport type { AgentType } from \"../adapters/AgentAdapter.js\";\n\nexport type StartableAgentType = Extract<\n AgentType,\n \"claude\" | \"codex\" | \"copilot\" | \"gemini_cli\" | \"grok_cli\" | \"opencode\" | \"pi\"\n>;\n\nexport interface AgentConfig {\n /** Shell command to launch the agent (sent to tmux via `send-keys`). */\n command: string;\n /** Returns true if the given `ps` command line belongs to this agent. */\n matches: (psCommand: string) => boolean;\n}\n\n/**\n * Per-agent configuration: launch command plus a matcher that recognizes the\n * agent's process in `ps` output. Each matcher knows that agent's distribution\n * quirks (e.g. gemini ships as a Node script so its real binary is in argv[1..]).\n */\nexport const AGENTS: Record<StartableAgentType, AgentConfig> = {\n claude: { command: \"claude\", matches: matchArgv0(\"claude\") },\n codex: { command: \"codex\", matches: matchArgv0(\"codex\") },\n copilot: { command: \"copilot\", matches: matchArgv0Name(\"copilot-cli\") },\n gemini_cli: { command: \"gemini\", matches: matchAnyToken(\"gemini\") },\n grok_cli: { command: \"grok\", matches: matchArgv0(\"grok\") },\n opencode: { command: \"opencode\", matches: matchArgv0(\"opencode\") },\n pi: { command: \"pi\", matches: matchAnyBasename([\"pi\"]) },\n};\n\nfunction matchArgv0(name: string): (psCommand: string) => boolean {\n const lower = name.toLowerCase();\n return (psCommand) => {\n const token = psCommand.trim().split(/\\s+/)[0];\n return token ? path.basename(token).toLowerCase() === lower : false;\n };\n}\n\nfunction matchArgv0Name(name: string): (psCommand: string) => boolean {\n const lower = name.toLowerCase();\n return (psCommand) => {\n const token = psCommand.trim().split(/\\s+/)[0];\n return token ? token.toLowerCase().includes(lower) : false;\n };\n}\n\nfunction matchAnyToken(name: string): (psCommand: string) => boolean {\n const lower = name.toLowerCase();\n return (psCommand) => {\n for (const token of psCommand.trim().split(/\\s+/)) {\n if (path.basename(token).toLowerCase() === lower) return true;\n }\n return false;\n };\n}\n\nfunction matchAnyBasename(names: string[]): (psCommand: string) => boolean {\n const lowers = new Set(names.map((name) => name.toLowerCase()));\n return (psCommand) => {\n for (const token of psCommand.trim().split(/\\s+/)) {\n if (lowers.has(path.basename(token).toLowerCase())) return true;\n }\n return false;\n };\n}\n"],"names":["path","AGENTS","claude","command","matches","matchArgv0","codex","copilot","matchArgv0Name","gemini_cli","matchAnyToken","grok_cli","opencode","pi","matchAnyBasename","name","lower","toLowerCase","psCommand","token","trim","split","basename","includes","names","lowers","Set","map","has"],"mappings":"AAAA,OAAOA,UAAU,OAAO;AAexB;;;;CAIC,GACD,OAAO,MAAMC,SAAkD;IAC7DC,QAAQ;QAAEC,SAAS;QAAUC,SAASC,WAAW;IAAU;IAC3DC,OAAO;QAAEH,SAAS;QAASC,SAASC,WAAW;IAAS;IACxDE,SAAS;QAAEJ,SAAS;QAAWC,SAASI,eAAe;IAAe;IACtEC,YAAY;QAAEN,SAAS;QAAUC,SAASM,cAAc;IAAU;IAClEC,UAAU;QAAER,SAAS;QAAQC,SAASC,WAAW;IAAQ;IACzDO,UAAU;QAAET,SAAS;QAAYC,SAASC,WAAW;IAAY;IACjEQ,IAAI;QAAEV,SAAS;QAAMC,SAASU,iBAAiB;YAAC;SAAK;IAAE;AACzD,EAAE;AAEF,SAAST,WAAWU,IAAY;IAC9B,MAAMC,QAAQD,KAAKE,WAAW;IAC9B,OAAO,CAACC;QACN,MAAMC,QAAQD,UAAUE,IAAI,GAAGC,KAAK,CAAC,MAAM,CAAC,EAAE;QAC9C,OAAOF,QAAQnB,KAAKsB,QAAQ,CAACH,OAAOF,WAAW,OAAOD,QAAQ;IAChE;AACF;AAEA,SAASR,eAAeO,IAAY;IAClC,MAAMC,QAAQD,KAAKE,WAAW;IAC9B,OAAO,CAACC;QACN,MAAMC,QAAQD,UAAUE,IAAI,GAAGC,KAAK,CAAC,MAAM,CAAC,EAAE;QAC9C,OAAOF,QAAQA,MAAMF,WAAW,GAAGM,QAAQ,CAACP,SAAS;IACvD;AACF;AAEA,SAASN,cAAcK,IAAY;IACjC,MAAMC,QAAQD,KAAKE,WAAW;IAC9B,OAAO,CAACC;QACN,KAAK,MAAMC,SAASD,UAAUE,IAAI,GAAGC,KAAK,CAAC,OAAQ;YACjD,IAAIrB,KAAKsB,QAAQ,CAACH,OAAOF,WAAW,OAAOD,OAAO,OAAO;QAC3D;QACA,OAAO;IACT;AACF;AAEA,SAASF,iBAAiBU,KAAe;IACvC,MAAMC,SAAS,IAAIC,IAAIF,MAAMG,GAAG,CAAC,CAACZ,OAASA,KAAKE,WAAW;IAC3D,OAAO,CAACC;QACN,KAAK,MAAMC,SAASD,UAAUE,IAAI,GAAGC,KAAK,CAAC,OAAQ;YACjD,IAAII,OAAOG,GAAG,CAAC5B,KAAKsB,QAAQ,CAACH,OAAOF,WAAW,KAAK,OAAO;QAC7D;QACA,OAAO;IACT;AACF"}
@@ -2,7 +2,7 @@
2
2
  * Escape a string for safe use inside an AppleScript double-quoted string.
3
3
  * Backslashes, double quotes, and newlines must be escaped.
4
4
  */ export function escapeAppleScript(text) {
5
- return text.replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\r\n|\r|\n/g, '\\n');
5
+ return text.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\r\n|\r|\n/g, "\\n");
6
6
  }
7
7
 
8
8
  //# sourceMappingURL=applescript.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/applescript.ts"],"sourcesContent":["/**\n * Escape a string for safe use inside an AppleScript double-quoted string.\n * Backslashes, double quotes, and newlines must be escaped.\n */\nexport function escapeAppleScript(text: string): string {\n return text\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(/\"/g, '\\\\\"')\n .replace(/\\r\\n|\\r|\\n/g, '\\\\n');\n}\n"],"names":["escapeAppleScript","text","replace"],"mappings":"AAAA;;;CAGC,GACD,OAAO,SAASA,kBAAkBC,IAAY;IAC1C,OAAOA,KACFC,OAAO,CAAC,OAAO,QACfA,OAAO,CAAC,MAAM,OACdA,OAAO,CAAC,eAAe;AAChC"}
1
+ {"version":3,"sources":["../../src/utils/applescript.ts"],"sourcesContent":["/**\n * Escape a string for safe use inside an AppleScript double-quoted string.\n * Backslashes, double quotes, and newlines must be escaped.\n */\nexport function escapeAppleScript(text: string): string {\n return text\n .replace(/\\\\/g, \"\\\\\\\\\")\n .replace(/\"/g, '\\\\\"')\n .replace(/\\r\\n|\\r|\\n/g, \"\\\\n\");\n}\n"],"names":["escapeAppleScript","text","replace"],"mappings":"AAAA;;;CAGC,GACD,OAAO,SAASA,kBAAkBC,IAAY;IAC5C,OAAOA,KACJC,OAAO,CAAC,OAAO,QACfA,OAAO,CAAC,MAAM,OACdA,OAAO,CAAC,eAAe;AAC5B"}
@@ -1,7 +1,7 @@
1
- export { listAgentProcesses, batchGetProcessCwds, batchGetProcessStartTimes, enrichProcesses, captureProcessSnapshot } from './process.js';
2
- export { getProcessTty } from './process.js';
3
- export { batchGetSessionFileBirthtimes } from './session.js';
4
- export type { SessionFile } from './session.js';
5
- export { matchProcessesToSessions, generateAgentName } from './matching.js';
6
- export type { MatchResult } from './matching.js';
1
+ export { listAgentProcesses, batchGetProcessCwds, batchGetProcessStartTimes, enrichProcesses, captureProcessSnapshot, } from "./process.js";
2
+ export { getProcessTty } from "./process.js";
3
+ export { batchGetSessionFileBirthtimes } from "./session.js";
4
+ export type { SessionFile } from "./session.js";
5
+ export { matchProcessesToSessions, generateAgentName } from "./matching.js";
6
+ export type { MatchResult } from "./matching.js";
7
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAC3I,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,6BAA6B,EAAE,MAAM,cAAc,CAAC;AAC7D,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,wBAAwB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAC5E,YAAY,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,yBAAyB,EACzB,eAAe,EACf,sBAAsB,GACvB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,6BAA6B,EAAE,MAAM,cAAc,CAAC;AAC7D,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,wBAAwB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAC5E,YAAY,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC"}
@@ -1,6 +1,6 @@
1
- export { listAgentProcesses, batchGetProcessCwds, batchGetProcessStartTimes, enrichProcesses, captureProcessSnapshot } from './process.js';
2
- export { getProcessTty } from './process.js';
3
- export { batchGetSessionFileBirthtimes } from './session.js';
4
- export { matchProcessesToSessions, generateAgentName } from './matching.js';
1
+ export { listAgentProcesses, batchGetProcessCwds, batchGetProcessStartTimes, enrichProcesses, captureProcessSnapshot } from "./process.js";
2
+ export { getProcessTty } from "./process.js";
3
+ export { batchGetSessionFileBirthtimes } from "./session.js";
4
+ export { matchProcessesToSessions, generateAgentName } from "./matching.js";
5
5
 
6
6
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/index.ts"],"sourcesContent":["export { listAgentProcesses, batchGetProcessCwds, batchGetProcessStartTimes, enrichProcesses, captureProcessSnapshot } from './process.js';\nexport { getProcessTty } from './process.js';\nexport { batchGetSessionFileBirthtimes } from './session.js';\nexport type { SessionFile } from './session.js';\nexport { matchProcessesToSessions, generateAgentName } from './matching.js';\nexport type { MatchResult } from './matching.js';\n"],"names":["listAgentProcesses","batchGetProcessCwds","batchGetProcessStartTimes","enrichProcesses","captureProcessSnapshot","getProcessTty","batchGetSessionFileBirthtimes","matchProcessesToSessions","generateAgentName"],"mappings":"AAAA,SAASA,kBAAkB,EAAEC,mBAAmB,EAAEC,yBAAyB,EAAEC,eAAe,EAAEC,sBAAsB,QAAQ,eAAe;AAC3I,SAASC,aAAa,QAAQ,eAAe;AAC7C,SAASC,6BAA6B,QAAQ,eAAe;AAE7D,SAASC,wBAAwB,EAAEC,iBAAiB,QAAQ,gBAAgB"}
1
+ {"version":3,"sources":["../../src/utils/index.ts"],"sourcesContent":["export {\n listAgentProcesses,\n batchGetProcessCwds,\n batchGetProcessStartTimes,\n enrichProcesses,\n captureProcessSnapshot,\n} from \"./process.js\";\nexport { getProcessTty } from \"./process.js\";\nexport { batchGetSessionFileBirthtimes } from \"./session.js\";\nexport type { SessionFile } from \"./session.js\";\nexport { matchProcessesToSessions, generateAgentName } from \"./matching.js\";\nexport type { MatchResult } from \"./matching.js\";\n"],"names":["listAgentProcesses","batchGetProcessCwds","batchGetProcessStartTimes","enrichProcesses","captureProcessSnapshot","getProcessTty","batchGetSessionFileBirthtimes","matchProcessesToSessions","generateAgentName"],"mappings":"AAAA,SACEA,kBAAkB,EAClBC,mBAAmB,EACnBC,yBAAyB,EACzBC,eAAe,EACfC,sBAAsB,QACjB,eAAe;AACtB,SAASC,aAAa,QAAQ,eAAe;AAC7C,SAASC,6BAA6B,QAAQ,eAAe;AAE7D,SAASC,wBAAwB,EAAEC,iBAAiB,QAAQ,gBAAgB"}
@@ -4,8 +4,8 @@
4
4
  * Shared 1:1 greedy matching algorithm that pairs running processes with session files
5
5
  * based on CWD and birth-time proximity to process start time.
6
6
  */
7
- import type { ProcessInfo } from '../adapters/AgentAdapter.js';
8
- import type { SessionFile } from './session.js';
7
+ import type { ProcessInfo } from "../adapters/AgentAdapter.js";
8
+ import type { SessionFile } from "./session.js";
9
9
  /**
10
10
  * Result of matching a process to a session file.
11
11
  */
@@ -1 +1 @@
1
- {"version":3,"file":"matching.d.ts","sourceRoot":"","sources":["../../src/utils/matching.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAKhD;;GAEG;AACH,MAAM,WAAW,WAAW;IACxB,0BAA0B;IAC1B,OAAO,EAAE,WAAW,CAAC;IAErB,+BAA+B;IAC/B,OAAO,EAAE,WAAW,CAAC;IAErB,6EAA6E;IAC7E,OAAO,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,wBAAwB,CACpC,SAAS,EAAE,WAAW,EAAE,EACxB,QAAQ,EAAE,WAAW,EAAE,GACxB,WAAW,EAAE,CAsCf;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAOlE"}
1
+ {"version":3,"file":"matching.d.ts","sourceRoot":"","sources":["../../src/utils/matching.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAKhD;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,0BAA0B;IAC1B,OAAO,EAAE,WAAW,CAAC;IAErB,+BAA+B;IAC/B,OAAO,EAAE,WAAW,CAAC;IAErB,6EAA6E;IAC7E,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,WAAW,EAAE,EACxB,QAAQ,EAAE,WAAW,EAAE,GACtB,WAAW,EAAE,CAsCf;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAOlE"}
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Shared 1:1 greedy matching algorithm that pairs running processes with session files
5
5
  * based on CWD and birth-time proximity to process start time.
6
- */ import * as path from 'path';
6
+ */ import * as path from "path";
7
7
  /** Maximum allowed delta between process start time and session file birth time. */ const TOLERANCE_MS = 3 * 60 * 1000; // 3 minutes
8
8
  /**
9
9
  * Match processes to session files using 1:1 greedy assignment.
@@ -54,9 +54,9 @@
54
54
  *
55
55
  * Format: "folder-name-pid" (lowercase kebab-case)
56
56
  */ export function generateAgentName(cwd, pid) {
57
- const folderName = path.basename(cwd) || 'unknown';
58
- const kebab = folderName.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '');
59
- return `${kebab || 'unknown'}-${pid}`;
57
+ const folderName = path.basename(cwd) || "unknown";
58
+ const kebab = folderName.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
59
+ return `${kebab || "unknown"}-${pid}`;
60
60
  }
61
61
 
62
62
  //# sourceMappingURL=matching.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/matching.ts"],"sourcesContent":["/**\n * Session Matching Utilities\n *\n * Shared 1:1 greedy matching algorithm that pairs running processes with session files\n * based on CWD and birth-time proximity to process start time.\n */\n\nimport * as path from 'path';\nimport type { ProcessInfo } from '../adapters/AgentAdapter.js';\nimport type { SessionFile } from './session.js';\n\n/** Maximum allowed delta between process start time and session file birth time. */\nconst TOLERANCE_MS = 3 * 60 * 1000; // 3 minutes\n\n/**\n * Result of matching a process to a session file.\n */\nexport interface MatchResult {\n /** The matched process */\n process: ProcessInfo;\n\n /** The matched session file */\n session: SessionFile;\n\n /** Absolute time delta in ms between process start and session birth time */\n deltaMs: number;\n}\n\n/**\n * Match processes to session files using 1:1 greedy assignment.\n *\n * Algorithm:\n * 1. Exclude processes without startTime (they become process-only fallback).\n * 2. Build candidate pairs where process.cwd === session.resolvedCwd\n * and |process.startTime - session.birthtimeMs| <= 3 minutes.\n * 3. Sort candidates by deltaMs ascending (best matches first).\n * 4. Greedily assign: once a process or session is matched, skip it.\n *\n * Adapters must set session.resolvedCwd before calling this function.\n */\nexport function matchProcessesToSessions(\n processes: ProcessInfo[],\n sessions: SessionFile[],\n): MatchResult[] {\n // Build all candidate pairs\n const candidates: Array<{ process: ProcessInfo; session: SessionFile; deltaMs: number }> = [];\n\n for (const proc of processes) {\n if (!proc.startTime || !proc.cwd) continue;\n\n const processStartMs = proc.startTime.getTime();\n\n for (const session of sessions) {\n if (!session.resolvedCwd) continue;\n if (proc.cwd !== session.resolvedCwd) continue;\n\n const deltaMs = Math.abs(processStartMs - session.birthtimeMs);\n if (deltaMs > TOLERANCE_MS) continue;\n\n candidates.push({ process: proc, session, deltaMs });\n }\n }\n\n // Sort by smallest delta first\n candidates.sort((a, b) => a.deltaMs - b.deltaMs);\n\n // Greedy 1:1 assignment\n const matchedPids = new Set<number>();\n const matchedSessionIds = new Set<string>();\n const results: MatchResult[] = [];\n\n for (const candidate of candidates) {\n if (matchedPids.has(candidate.process.pid)) continue;\n if (matchedSessionIds.has(candidate.session.sessionId)) continue;\n\n matchedPids.add(candidate.process.pid);\n matchedSessionIds.add(candidate.session.sessionId);\n results.push(candidate);\n }\n\n return results;\n}\n\n/**\n * Generate a deterministic agent name from CWD and PID.\n *\n * Format: \"folder-name-pid\" (lowercase kebab-case)\n */\nexport function generateAgentName(cwd: string, pid: number): string {\n const folderName = path.basename(cwd) || 'unknown';\n const kebab = folderName\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '');\n return `${kebab || 'unknown'}-${pid}`;\n}\n"],"names":["path","TOLERANCE_MS","matchProcessesToSessions","processes","sessions","candidates","proc","startTime","cwd","processStartMs","getTime","session","resolvedCwd","deltaMs","Math","abs","birthtimeMs","push","process","sort","a","b","matchedPids","Set","matchedSessionIds","results","candidate","has","pid","sessionId","add","generateAgentName","folderName","basename","kebab","toLowerCase","replace"],"mappings":"AAAA;;;;;CAKC,GAED,YAAYA,UAAU,OAAO;AAI7B,kFAAkF,GAClF,MAAMC,eAAe,IAAI,KAAK,MAAM,YAAY;AAgBhD;;;;;;;;;;;CAWC,GACD,OAAO,SAASC,yBACZC,SAAwB,EACxBC,QAAuB;IAEvB,4BAA4B;IAC5B,MAAMC,aAAqF,EAAE;IAE7F,KAAK,MAAMC,QAAQH,UAAW;QAC1B,IAAI,CAACG,KAAKC,SAAS,IAAI,CAACD,KAAKE,GAAG,EAAE;QAElC,MAAMC,iBAAiBH,KAAKC,SAAS,CAACG,OAAO;QAE7C,KAAK,MAAMC,WAAWP,SAAU;YAC5B,IAAI,CAACO,QAAQC,WAAW,EAAE;YAC1B,IAAIN,KAAKE,GAAG,KAAKG,QAAQC,WAAW,EAAE;YAEtC,MAAMC,UAAUC,KAAKC,GAAG,CAACN,iBAAiBE,QAAQK,WAAW;YAC7D,IAAIH,UAAUZ,cAAc;YAE5BI,WAAWY,IAAI,CAAC;gBAAEC,SAASZ;gBAAMK;gBAASE;YAAQ;QACtD;IACJ;IAEA,+BAA+B;IAC/BR,WAAWc,IAAI,CAAC,CAACC,GAAGC,IAAMD,EAAEP,OAAO,GAAGQ,EAAER,OAAO;IAE/C,wBAAwB;IACxB,MAAMS,cAAc,IAAIC;IACxB,MAAMC,oBAAoB,IAAID;IAC9B,MAAME,UAAyB,EAAE;IAEjC,KAAK,MAAMC,aAAarB,WAAY;QAChC,IAAIiB,YAAYK,GAAG,CAACD,UAAUR,OAAO,CAACU,GAAG,GAAG;QAC5C,IAAIJ,kBAAkBG,GAAG,CAACD,UAAUf,OAAO,CAACkB,SAAS,GAAG;QAExDP,YAAYQ,GAAG,CAACJ,UAAUR,OAAO,CAACU,GAAG;QACrCJ,kBAAkBM,GAAG,CAACJ,UAAUf,OAAO,CAACkB,SAAS;QACjDJ,QAAQR,IAAI,CAACS;IACjB;IAEA,OAAOD;AACX;AAEA;;;;CAIC,GACD,OAAO,SAASM,kBAAkBvB,GAAW,EAAEoB,GAAW;IACtD,MAAMI,aAAahC,KAAKiC,QAAQ,CAACzB,QAAQ;IACzC,MAAM0B,QAAQF,WACTG,WAAW,GACXC,OAAO,CAAC,eAAe,KACvBA,OAAO,CAAC,YAAY;IACzB,OAAO,GAAGF,SAAS,UAAU,CAAC,EAAEN,KAAK;AACzC"}
1
+ {"version":3,"sources":["../../src/utils/matching.ts"],"sourcesContent":["/**\n * Session Matching Utilities\n *\n * Shared 1:1 greedy matching algorithm that pairs running processes with session files\n * based on CWD and birth-time proximity to process start time.\n */\n\nimport * as path from \"path\";\nimport type { ProcessInfo } from \"../adapters/AgentAdapter.js\";\nimport type { SessionFile } from \"./session.js\";\n\n/** Maximum allowed delta between process start time and session file birth time. */\nconst TOLERANCE_MS = 3 * 60 * 1000; // 3 minutes\n\n/**\n * Result of matching a process to a session file.\n */\nexport interface MatchResult {\n /** The matched process */\n process: ProcessInfo;\n\n /** The matched session file */\n session: SessionFile;\n\n /** Absolute time delta in ms between process start and session birth time */\n deltaMs: number;\n}\n\n/**\n * Match processes to session files using 1:1 greedy assignment.\n *\n * Algorithm:\n * 1. Exclude processes without startTime (they become process-only fallback).\n * 2. Build candidate pairs where process.cwd === session.resolvedCwd\n * and |process.startTime - session.birthtimeMs| <= 3 minutes.\n * 3. Sort candidates by deltaMs ascending (best matches first).\n * 4. Greedily assign: once a process or session is matched, skip it.\n *\n * Adapters must set session.resolvedCwd before calling this function.\n */\nexport function matchProcessesToSessions(\n processes: ProcessInfo[],\n sessions: SessionFile[],\n): MatchResult[] {\n // Build all candidate pairs\n const candidates: Array<{ process: ProcessInfo; session: SessionFile; deltaMs: number }> = [];\n\n for (const proc of processes) {\n if (!proc.startTime || !proc.cwd) continue;\n\n const processStartMs = proc.startTime.getTime();\n\n for (const session of sessions) {\n if (!session.resolvedCwd) continue;\n if (proc.cwd !== session.resolvedCwd) continue;\n\n const deltaMs = Math.abs(processStartMs - session.birthtimeMs);\n if (deltaMs > TOLERANCE_MS) continue;\n\n candidates.push({ process: proc, session, deltaMs });\n }\n }\n\n // Sort by smallest delta first\n candidates.sort((a, b) => a.deltaMs - b.deltaMs);\n\n // Greedy 1:1 assignment\n const matchedPids = new Set<number>();\n const matchedSessionIds = new Set<string>();\n const results: MatchResult[] = [];\n\n for (const candidate of candidates) {\n if (matchedPids.has(candidate.process.pid)) continue;\n if (matchedSessionIds.has(candidate.session.sessionId)) continue;\n\n matchedPids.add(candidate.process.pid);\n matchedSessionIds.add(candidate.session.sessionId);\n results.push(candidate);\n }\n\n return results;\n}\n\n/**\n * Generate a deterministic agent name from CWD and PID.\n *\n * Format: \"folder-name-pid\" (lowercase kebab-case)\n */\nexport function generateAgentName(cwd: string, pid: number): string {\n const folderName = path.basename(cwd) || \"unknown\";\n const kebab = folderName\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n return `${kebab || \"unknown\"}-${pid}`;\n}\n"],"names":["path","TOLERANCE_MS","matchProcessesToSessions","processes","sessions","candidates","proc","startTime","cwd","processStartMs","getTime","session","resolvedCwd","deltaMs","Math","abs","birthtimeMs","push","process","sort","a","b","matchedPids","Set","matchedSessionIds","results","candidate","has","pid","sessionId","add","generateAgentName","folderName","basename","kebab","toLowerCase","replace"],"mappings":"AAAA;;;;;CAKC,GAED,YAAYA,UAAU,OAAO;AAI7B,kFAAkF,GAClF,MAAMC,eAAe,IAAI,KAAK,MAAM,YAAY;AAgBhD;;;;;;;;;;;CAWC,GACD,OAAO,SAASC,yBACdC,SAAwB,EACxBC,QAAuB;IAEvB,4BAA4B;IAC5B,MAAMC,aAAqF,EAAE;IAE7F,KAAK,MAAMC,QAAQH,UAAW;QAC5B,IAAI,CAACG,KAAKC,SAAS,IAAI,CAACD,KAAKE,GAAG,EAAE;QAElC,MAAMC,iBAAiBH,KAAKC,SAAS,CAACG,OAAO;QAE7C,KAAK,MAAMC,WAAWP,SAAU;YAC9B,IAAI,CAACO,QAAQC,WAAW,EAAE;YAC1B,IAAIN,KAAKE,GAAG,KAAKG,QAAQC,WAAW,EAAE;YAEtC,MAAMC,UAAUC,KAAKC,GAAG,CAACN,iBAAiBE,QAAQK,WAAW;YAC7D,IAAIH,UAAUZ,cAAc;YAE5BI,WAAWY,IAAI,CAAC;gBAAEC,SAASZ;gBAAMK;gBAASE;YAAQ;QACpD;IACF;IAEA,+BAA+B;IAC/BR,WAAWc,IAAI,CAAC,CAACC,GAAGC,IAAMD,EAAEP,OAAO,GAAGQ,EAAER,OAAO;IAE/C,wBAAwB;IACxB,MAAMS,cAAc,IAAIC;IACxB,MAAMC,oBAAoB,IAAID;IAC9B,MAAME,UAAyB,EAAE;IAEjC,KAAK,MAAMC,aAAarB,WAAY;QAClC,IAAIiB,YAAYK,GAAG,CAACD,UAAUR,OAAO,CAACU,GAAG,GAAG;QAC5C,IAAIJ,kBAAkBG,GAAG,CAACD,UAAUf,OAAO,CAACkB,SAAS,GAAG;QAExDP,YAAYQ,GAAG,CAACJ,UAAUR,OAAO,CAACU,GAAG;QACrCJ,kBAAkBM,GAAG,CAACJ,UAAUf,OAAO,CAACkB,SAAS;QACjDJ,QAAQR,IAAI,CAACS;IACf;IAEA,OAAOD;AACT;AAEA;;;;CAIC,GACD,OAAO,SAASM,kBAAkBvB,GAAW,EAAEoB,GAAW;IACxD,MAAMI,aAAahC,KAAKiC,QAAQ,CAACzB,QAAQ;IACzC,MAAM0B,QAAQF,WACXG,WAAW,GACXC,OAAO,CAAC,eAAe,KACvBA,OAAO,CAAC,YAAY;IACvB,OAAO,GAAGF,SAAS,UAAU,CAAC,EAAEN,KAAK;AACvC"}
@@ -5,7 +5,7 @@
5
5
  * Built-in refresh discovery uses captureProcessSnapshot(); synchronous helpers
6
6
  * remain exported for compatibility with existing consumers.
7
7
  */
8
- import type { ProcessInfo } from '../adapters/AgentAdapter.js';
8
+ import type { ProcessInfo } from "../adapters/AgentAdapter.js";
9
9
  export declare function executableBasename(command: string): string;
10
10
  export declare function filterByProcessNames(processes: readonly ProcessInfo[], namePatterns: readonly string[]): ProcessInfo[];
11
11
  /**