@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
@@ -0,0 +1,216 @@
1
+ import { HerdrCliClient, isCommandMissing, type HerdrCommandRunner } from "./HerdrCliClient.js";
2
+ import { HerdrRuntimeError } from "./HerdrErrors.js";
3
+ import { parseHerdrRuntimeRef } from "./HerdrRuntimeRef.js";
4
+ import {
5
+ extractAgentRuntimeRef,
6
+ extractForegroundProcessInfoPid,
7
+ extractProcessInfoPid,
8
+ extractWorkspaceStart,
9
+ } from "./HerdrResponseParsers.js";
10
+ import type {
11
+ AgentRuntimeAvailability,
12
+ InteractiveAgentRuntime,
13
+ RuntimeFocusInput,
14
+ RuntimeSendInput,
15
+ RuntimeStartInput,
16
+ RuntimeStartResult,
17
+ RuntimeStopInput,
18
+ } from "../types.js";
19
+
20
+ const AGENT_START_BUSY_RETRY_MS = 5000;
21
+ const AGENT_START_BUSY_RETRY_INTERVAL_MS = 100;
22
+ const PROCESS_INFO_POLL_MS = 3000;
23
+ const PROCESS_INFO_POLL_INTERVAL_MS = 100;
24
+
25
+ export interface HerdrRuntimeOptions {
26
+ runner?: HerdrCommandRunner;
27
+ env?: NodeJS.ProcessEnv;
28
+ agentStartBusyRetryMs?: number;
29
+ agentStartBusyRetryIntervalMs?: number;
30
+ processInfoPollMs?: number;
31
+ processInfoPollIntervalMs?: number;
32
+ }
33
+
34
+ export class HerdrAgentRuntime implements InteractiveAgentRuntime {
35
+ readonly provider = "herdr" as const;
36
+
37
+ private readonly client: HerdrCliClient;
38
+ private readonly env: NodeJS.ProcessEnv;
39
+ private readonly agentStartBusyRetryMs: number;
40
+ private readonly agentStartBusyRetryIntervalMs: number;
41
+ private readonly processInfoPollMs: number;
42
+ private readonly processInfoPollIntervalMs: number;
43
+
44
+ constructor(options: HerdrRuntimeOptions = {}) {
45
+ this.client = new HerdrCliClient(options.runner);
46
+ this.env = options.env ?? process.env;
47
+ this.agentStartBusyRetryMs = options.agentStartBusyRetryMs ?? AGENT_START_BUSY_RETRY_MS;
48
+ this.agentStartBusyRetryIntervalMs =
49
+ options.agentStartBusyRetryIntervalMs ?? AGENT_START_BUSY_RETRY_INTERVAL_MS;
50
+ this.processInfoPollMs = options.processInfoPollMs ?? PROCESS_INFO_POLL_MS;
51
+ this.processInfoPollIntervalMs =
52
+ options.processInfoPollIntervalMs ?? PROCESS_INFO_POLL_INTERVAL_MS;
53
+ }
54
+
55
+ async isAvailable(): Promise<AgentRuntimeAvailability> {
56
+ try {
57
+ await this.client.run(["--version"]);
58
+ } catch (error) {
59
+ if (isCommandMissing(error)) {
60
+ return {
61
+ ok: false,
62
+ reason: "binary-missing",
63
+ detail: "herdr command was not found in PATH.",
64
+ };
65
+ }
66
+ return {
67
+ ok: false,
68
+ reason: "backend-unreachable",
69
+ detail: (error as Error).message,
70
+ };
71
+ }
72
+
73
+ try {
74
+ await this.client.run(["api", "snapshot"]);
75
+ } catch (error) {
76
+ return {
77
+ ok: false,
78
+ reason: "backend-unreachable",
79
+ detail: (error as Error).message,
80
+ };
81
+ }
82
+
83
+ const currentPaneId = nonEmptyString(this.env.HERDR_PANE_ID);
84
+ return {
85
+ ok: true,
86
+ insideRuntime: this.env.HERDR_ENV === "1",
87
+ ...(currentPaneId ? { currentPaneId } : {}),
88
+ };
89
+ }
90
+
91
+ async startAgent(input: RuntimeStartInput): Promise<RuntimeStartResult> {
92
+ const workspace = extractWorkspaceStart(
93
+ await this.client.runJson(["workspace", "create", "--cwd", input.cwd, "--label", input.name]),
94
+ );
95
+
96
+ const agentResponse = await this.runAgentStartJson([
97
+ "agent",
98
+ "start",
99
+ input.name,
100
+ "--kind",
101
+ input.kind,
102
+ "--pane",
103
+ workspace.paneId,
104
+ ...(input.timeoutMs ? ["--timeout", String(input.timeoutMs)] : []),
105
+ ...(input.args?.length ? ["--", ...input.args] : []),
106
+ ]);
107
+ const runtimeRef = extractAgentRuntimeRef(agentResponse, {
108
+ name: input.name,
109
+ paneId: workspace.paneId,
110
+ workspaceId: workspace.workspaceId,
111
+ });
112
+ const pid = await this.readStartedAgentPid(runtimeRef.paneId);
113
+ if (pid === null) {
114
+ throw new HerdrRuntimeError("Herdr pane process-info response did not include process pid.");
115
+ }
116
+
117
+ return { pid, runtimeRef };
118
+ }
119
+
120
+ async send(input: RuntimeSendInput): Promise<void> {
121
+ const ref = parseHerdrRuntimeRef(input.runtimeRef);
122
+ await this.client.run(["agent", "prompt", ref.paneId, input.prompt]);
123
+ }
124
+
125
+ async wait(input: { runtimeRef: unknown; timeoutMs: number }): Promise<void> {
126
+ const ref = parseHerdrRuntimeRef(input.runtimeRef);
127
+ await this.client.run([
128
+ "agent",
129
+ "wait",
130
+ ref.paneId,
131
+ "--until",
132
+ "done",
133
+ "--until",
134
+ "blocked",
135
+ "--timeout",
136
+ String(input.timeoutMs),
137
+ ]);
138
+ }
139
+
140
+ async readOutput(input: { runtimeRef: unknown; lines?: number }): Promise<string> {
141
+ const ref = parseHerdrRuntimeRef(input.runtimeRef);
142
+ const { stdout } = await this.client.run([
143
+ "agent",
144
+ "read",
145
+ ref.paneId,
146
+ "--source",
147
+ "recent-unwrapped",
148
+ "--lines",
149
+ String(input.lines ?? 120),
150
+ ]);
151
+ return stdout;
152
+ }
153
+
154
+ async focus(input: RuntimeFocusInput): Promise<boolean> {
155
+ const ref = parseHerdrRuntimeRef(input.runtimeRef);
156
+ await this.client.run(["agent", "focus", ref.paneId]);
157
+ return true;
158
+ }
159
+
160
+ async stop(input: RuntimeStopInput): Promise<void> {
161
+ const ref = parseHerdrRuntimeRef(input.runtimeRef);
162
+ await this.client.run(["pane", "close", ref.paneId]);
163
+ }
164
+
165
+ private async runAgentStartJson(args: string[]): Promise<unknown> {
166
+ const deadline = Date.now() + this.agentStartBusyRetryMs;
167
+ let lastBusyError: HerdrRuntimeError | null = null;
168
+ do {
169
+ try {
170
+ return await this.client.runJson(args);
171
+ } catch (error) {
172
+ if (!(error instanceof HerdrRuntimeError) || error.code !== "agent_pane_busy") throw error;
173
+ lastBusyError = error;
174
+ if (Date.now() >= deadline) break;
175
+ await sleep(this.agentStartBusyRetryIntervalMs);
176
+ }
177
+ } while (Date.now() < deadline);
178
+ throw (
179
+ lastBusyError ??
180
+ new HerdrRuntimeError("Herdr agent start failed because the target pane stayed busy.", {
181
+ code: "agent_pane_busy",
182
+ })
183
+ );
184
+ }
185
+
186
+ private async readStartedAgentPid(paneId: string): Promise<number | null> {
187
+ const deadline = Date.now() + this.processInfoPollMs;
188
+ let fallbackPid: number | null = null;
189
+
190
+ do {
191
+ const processInfoResponse = await this.client.runJson([
192
+ "pane",
193
+ "process-info",
194
+ "--pane",
195
+ paneId,
196
+ ]);
197
+ const foregroundPid = extractForegroundProcessInfoPid(processInfoResponse);
198
+ if (foregroundPid !== null) return foregroundPid;
199
+ fallbackPid ??= extractProcessInfoPid(processInfoResponse);
200
+
201
+ if (Date.now() >= deadline) break;
202
+ await sleep(this.processInfoPollIntervalMs);
203
+ } while (Date.now() < deadline);
204
+
205
+ return fallbackPid;
206
+ }
207
+ }
208
+
209
+ function sleep(ms: number): Promise<void> {
210
+ if (ms <= 0) return Promise.resolve();
211
+ return new Promise((resolve) => setTimeout(resolve, ms));
212
+ }
213
+
214
+ function nonEmptyString(value: unknown): string | undefined {
215
+ return typeof value === "string" && value.trim() ? value : undefined;
216
+ }
@@ -0,0 +1,78 @@
1
+ import { execFile } from "child_process";
2
+ import { promisify } from "util";
3
+ import { HerdrRuntimeError } from "./HerdrErrors.js";
4
+ import { herdrErrorFromResponse } from "./HerdrResponseParsers.js";
5
+
6
+ const execFileAsync = promisify(execFile);
7
+
8
+ export interface HerdrCommandResult {
9
+ stdout: string;
10
+ stderr: string;
11
+ }
12
+
13
+ export type HerdrCommandRunner = (command: string, args: string[]) => Promise<HerdrCommandResult>;
14
+
15
+ export class HerdrCliClient {
16
+ constructor(private readonly runner: HerdrCommandRunner = defaultRunner) {}
17
+
18
+ run(args: string[]): Promise<HerdrCommandResult> {
19
+ return this.runner("herdr", args);
20
+ }
21
+
22
+ async runJson(args: string[]): Promise<unknown> {
23
+ let stdout: string;
24
+ try {
25
+ ({ stdout } = await this.run(args));
26
+ } catch (error) {
27
+ throw parseHerdrCommandError(error);
28
+ }
29
+ try {
30
+ const parsed = JSON.parse(stdout) as unknown;
31
+ const herdrError = herdrErrorFromResponse(parsed);
32
+ if (herdrError) throw herdrError;
33
+ return parsed;
34
+ } catch (error) {
35
+ if (error instanceof HerdrRuntimeError) throw error;
36
+ throw new HerdrRuntimeError(`Herdr returned invalid JSON: ${(error as Error).message}`);
37
+ }
38
+ }
39
+ }
40
+
41
+ export function isCommandMissing(error: unknown): boolean {
42
+ return Boolean(
43
+ error &&
44
+ typeof error === "object" &&
45
+ "code" in error &&
46
+ (error as NodeJS.ErrnoException).code === "ENOENT",
47
+ );
48
+ }
49
+
50
+ function defaultRunner(command: string, args: string[]): Promise<HerdrCommandResult> {
51
+ return execFileAsync(command, args).then(({ stdout, stderr }) => ({ stdout, stderr }));
52
+ }
53
+
54
+ function parseHerdrCommandError(error: unknown): HerdrRuntimeError {
55
+ const stdout =
56
+ typeof error === "object" && error && "stdout" in error
57
+ ? String((error as { stdout?: unknown }).stdout ?? "")
58
+ : "";
59
+ const stderr =
60
+ typeof error === "object" && error && "stderr" in error
61
+ ? String((error as { stderr?: unknown }).stderr ?? "")
62
+ : "";
63
+ const parsed = parseJson(stdout) ?? parseJson(stderr);
64
+ if (parsed) {
65
+ const herdrError = herdrErrorFromResponse(parsed);
66
+ if (herdrError) return herdrError;
67
+ }
68
+ return new HerdrRuntimeError((error as Error).message);
69
+ }
70
+
71
+ function parseJson(value: string): unknown | null {
72
+ if (!value.trim()) return null;
73
+ try {
74
+ return JSON.parse(value) as unknown;
75
+ } catch {
76
+ return null;
77
+ }
78
+ }
@@ -0,0 +1,9 @@
1
+ export class HerdrRuntimeError extends Error {
2
+ readonly code?: string;
3
+
4
+ constructor(message: string, options: { code?: string } = {}) {
5
+ super(message);
6
+ this.name = "HerdrRuntimeError";
7
+ this.code = options.code;
8
+ }
9
+ }
@@ -0,0 +1,86 @@
1
+ import { HerdrRuntimeError } from "./HerdrErrors.js";
2
+ import type { HerdrRuntimeRef } from "./HerdrRuntimeRef.js";
3
+
4
+ export function extractWorkspaceStart(value: unknown): { workspaceId?: string; paneId: string } {
5
+ const workspaceId = getString(value, ["result", "workspace", "workspace_id"]);
6
+ const paneId = getString(value, ["result", "root_pane", "pane_id"]);
7
+ if (!paneId) {
8
+ throw new HerdrRuntimeError("Herdr workspace create response did not include root pane id.");
9
+ }
10
+ return {
11
+ ...(workspaceId ? { workspaceId } : {}),
12
+ paneId,
13
+ };
14
+ }
15
+
16
+ export function extractAgentRuntimeRef(
17
+ value: unknown,
18
+ fallback: { paneId: string; name: string; workspaceId?: string },
19
+ ): HerdrRuntimeRef {
20
+ const agentPaneId = getString(value, ["result", "agent", "pane_id"]) ?? fallback.paneId;
21
+ const agentName = getString(value, ["result", "agent", "name"]) ?? fallback.name;
22
+ const tabId = getString(value, ["result", "agent", "tab_id"]);
23
+ return {
24
+ session: "default",
25
+ ...(fallback.workspaceId ? { workspaceId: fallback.workspaceId } : {}),
26
+ ...(tabId ? { tabId } : {}),
27
+ paneId: agentPaneId,
28
+ agentName,
29
+ };
30
+ }
31
+
32
+ export function extractProcessInfoPid(value: unknown): number | null {
33
+ return extractForegroundProcessInfoPid(value) ?? extractShellPid(value);
34
+ }
35
+
36
+ export function extractForegroundProcessInfoPid(value: unknown): number | null {
37
+ const processInfo = getObject(value, ["result", "process_info"]);
38
+ if (!processInfo) return null;
39
+ const processes = processInfo.foreground_processes;
40
+ if (!Array.isArray(processes)) return null;
41
+ for (const processInfo of processes) {
42
+ if (!processInfo || typeof processInfo !== "object") continue;
43
+ const pid = numberOrNull((processInfo as { pid?: unknown }).pid);
44
+ if (pid !== null) return pid;
45
+ }
46
+ return null;
47
+ }
48
+
49
+ export function extractShellPid(value: unknown): number | null {
50
+ const processInfo = getObject(value, ["result", "process_info"]);
51
+ if (!processInfo) return null;
52
+ return numberOrNull(processInfo.shell_pid);
53
+ }
54
+
55
+ export function herdrErrorFromResponse(value: unknown): HerdrRuntimeError | null {
56
+ const error = getObject(value, ["error"]);
57
+ if (!error) return null;
58
+ const message = nonEmptyString(error.message) ?? "Herdr command failed.";
59
+ const code = nonEmptyString(error.code);
60
+ return new HerdrRuntimeError(message, code ? { code } : {});
61
+ }
62
+
63
+ function getObject(value: unknown, path: string[]): Record<string, unknown> | null {
64
+ let current = value;
65
+ for (const part of path) {
66
+ if (!current || typeof current !== "object" || Array.isArray(current) || !(part in current))
67
+ return null;
68
+ current = (current as Record<string, unknown>)[part];
69
+ }
70
+ return current && typeof current === "object" && !Array.isArray(current)
71
+ ? (current as Record<string, unknown>)
72
+ : null;
73
+ }
74
+
75
+ function getString(value: unknown, path: string[]): string | undefined {
76
+ const parent = getObject(value, path.slice(0, -1));
77
+ return parent ? nonEmptyString(parent[path[path.length - 1]!]) : undefined;
78
+ }
79
+
80
+ function nonEmptyString(value: unknown): string | undefined {
81
+ return typeof value === "string" && value.trim() ? value : undefined;
82
+ }
83
+
84
+ function numberOrNull(value: unknown): number | null {
85
+ return typeof value === "number" && Number.isInteger(value) && value > 0 ? value : null;
86
+ }
@@ -0,0 +1,41 @@
1
+ import { HerdrRuntimeError } from "./HerdrErrors.js";
2
+
3
+ export interface HerdrRuntimeRef {
4
+ session: string;
5
+ workspaceId?: string;
6
+ tabId?: string;
7
+ paneId: string;
8
+ agentName?: string;
9
+ }
10
+
11
+ export function parseHerdrRuntimeRef(value: unknown): HerdrRuntimeRef {
12
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
13
+ throw new HerdrRuntimeError("Herdr runtime ref is missing or invalid.");
14
+ }
15
+ const ref = value as {
16
+ session?: unknown;
17
+ workspaceId?: unknown;
18
+ tabId?: unknown;
19
+ paneId?: unknown;
20
+ agentName?: unknown;
21
+ };
22
+ const session = nonEmptyString(ref.session) ?? "default";
23
+ const workspaceId = nonEmptyString(ref.workspaceId);
24
+ const tabId = nonEmptyString(ref.tabId);
25
+ const paneId = nonEmptyString(ref.paneId);
26
+ const agentName = nonEmptyString(ref.agentName);
27
+ if (!paneId) {
28
+ throw new HerdrRuntimeError("Herdr runtime ref is missing paneId.");
29
+ }
30
+ return {
31
+ session,
32
+ paneId,
33
+ ...(workspaceId ? { workspaceId } : {}),
34
+ ...(tabId ? { tabId } : {}),
35
+ ...(agentName ? { agentName } : {}),
36
+ };
37
+ }
38
+
39
+ function nonEmptyString(value: unknown): string | undefined {
40
+ return typeof value === "string" && value.trim() ? value : undefined;
41
+ }
@@ -0,0 +1,34 @@
1
+ import type { TmuxManager } from "../../terminal/TmuxManager.js";
2
+
3
+ export const DEFAULT_PID_POLL_INTERVAL_MS = 500;
4
+ export const DEFAULT_PID_POLL_TIMEOUT_MS = 15_000;
5
+ const REQUIRED_STABLE_PID_POLLS = 5;
6
+
7
+ export async function pollForPid(
8
+ tmux: Pick<TmuxManager, "findAgentPid">,
9
+ session: string,
10
+ matches: (psCommand: string) => boolean,
11
+ intervalMs: number,
12
+ timeoutMs: number,
13
+ ): Promise<number | null> {
14
+ const deadline = Date.now() + timeoutMs;
15
+ let candidatePid: number | null = null;
16
+ let stablePolls = 0;
17
+
18
+ while (Date.now() < deadline) {
19
+ const pid = await tmux.findAgentPid(session, matches);
20
+ if (pid !== null) {
21
+ if (pid === candidatePid) {
22
+ stablePolls += 1;
23
+ } else {
24
+ candidatePid = pid;
25
+ stablePolls = 1;
26
+ }
27
+
28
+ if (stablePolls >= REQUIRED_STABLE_PID_POLLS) return pid;
29
+ }
30
+ await new Promise((resolve) => setTimeout(resolve, intervalMs));
31
+ }
32
+
33
+ return null;
34
+ }
@@ -0,0 +1,113 @@
1
+ import { TmuxManager } from "../../terminal/TmuxManager.js";
2
+ import { TtyWriter } from "../../terminal/TtyWriter.js";
3
+ import { AgentPidPollTimeoutError, AgentTerminalNotFoundError } from "../errors.js";
4
+ import { pollForPid } from "./PidPolling.js";
5
+ import { parseTmuxRuntimeRef } from "./TmuxRuntimeRef.js";
6
+ import type {
7
+ AgentRuntimeAvailability,
8
+ InteractiveAgentRuntime,
9
+ RuntimeFocusInput,
10
+ RuntimeSendDeps,
11
+ RuntimeSendInput,
12
+ RuntimeStartInput,
13
+ RuntimeStartResult,
14
+ RuntimeStopInput,
15
+ } from "../types.js";
16
+
17
+ export class TmuxAgentRuntime implements InteractiveAgentRuntime {
18
+ readonly provider = "tmux" as const;
19
+ private readonly tmux: TmuxManager;
20
+
21
+ constructor(tmux: TmuxManager = new TmuxManager()) {
22
+ this.tmux = tmux;
23
+ }
24
+
25
+ async isAvailable(): Promise<AgentRuntimeAvailability> {
26
+ if (await this.tmux.isAvailable()) {
27
+ return { ok: true, insideRuntime: Boolean(process.env.TMUX) };
28
+ }
29
+ return {
30
+ ok: false,
31
+ reason: "binary-missing",
32
+ detail: "tmux is not installed or not in PATH.",
33
+ };
34
+ }
35
+
36
+ async startAgent(
37
+ input: RuntimeStartInput & {
38
+ command?: string;
39
+ matches?: (psCommand: string) => boolean;
40
+ pollIntervalMs?: number;
41
+ },
42
+ ): Promise<RuntimeStartResult> {
43
+ if (!input.command || !input.matches || input.pollIntervalMs === undefined) {
44
+ throw new Error("Tmux start requires command, process matcher, and poll interval.");
45
+ }
46
+
47
+ if (await this.tmux.sessionExists(input.name)) {
48
+ await this.tmux.killSession(input.name);
49
+ }
50
+
51
+ await this.tmux.createSession(input.name, input.cwd);
52
+ await this.tmux.sendKeys(input.name, input.command);
53
+
54
+ const pid = await pollForPid(
55
+ this.tmux,
56
+ input.name,
57
+ input.matches,
58
+ input.pollIntervalMs,
59
+ input.timeoutMs,
60
+ );
61
+ if (pid === null) {
62
+ await this.tmux.killSession(input.name);
63
+ throw new AgentPidPollTimeoutError(input.name, input.command, input.timeoutMs);
64
+ }
65
+
66
+ return {
67
+ pid,
68
+ runtimeRef: { session: input.name },
69
+ };
70
+ }
71
+
72
+ async send(input: RuntimeSendInput, deps?: RuntimeSendDeps): Promise<void> {
73
+ if (!deps) {
74
+ throw new Error("Tmux send requires terminal lookup dependencies.");
75
+ }
76
+ const location = await deps.focusManager.findTerminal(input.agent.pid);
77
+ if (!location) {
78
+ throw new AgentTerminalNotFoundError(input.agent.name, input.agent.pid);
79
+ }
80
+ await (deps.writer ?? TtyWriter.send)(location, input.prompt);
81
+ }
82
+
83
+ async focus(input: RuntimeFocusInput): Promise<boolean> {
84
+ const location = await input.focusManager.findTerminal(input.agent.pid);
85
+ if (!location) return false;
86
+ return await input.focusManager.focusTerminal(location);
87
+ }
88
+
89
+ async stop(input: RuntimeStopInput): Promise<void> {
90
+ const killProcess = input.killProcess ?? ((pid, signal) => process.kill(pid, signal));
91
+ try {
92
+ killProcess(input.agent.pid, "SIGTERM");
93
+ } catch (error) {
94
+ if (!isProcessAlreadyGone(error)) {
95
+ throw error;
96
+ }
97
+ }
98
+
99
+ const tmuxRef = parseTmuxRuntimeRef(input.runtimeRef);
100
+ if (tmuxRef) {
101
+ await this.tmux.killSession(tmuxRef.session);
102
+ }
103
+ }
104
+ }
105
+
106
+ function isProcessAlreadyGone(error: unknown): boolean {
107
+ return (
108
+ typeof error === "object" &&
109
+ error !== null &&
110
+ "code" in error &&
111
+ (error as NodeJS.ErrnoException).code === "ESRCH"
112
+ );
113
+ }
@@ -0,0 +1,9 @@
1
+ export interface TmuxRuntimeRef {
2
+ session: string;
3
+ }
4
+
5
+ export function parseTmuxRuntimeRef(value: unknown): TmuxRuntimeRef | null {
6
+ if (!value || typeof value !== "object" || Array.isArray(value)) return null;
7
+ const session = (value as { session?: unknown }).session;
8
+ return typeof session === "string" && session.trim() ? { session } : null;
9
+ }
@@ -0,0 +1,56 @@
1
+ import type { AgentInfo } from "../adapters/AgentAdapter.js";
2
+ import type { TerminalLocation } from "../terminal/TerminalFocusManager.js";
3
+ import type { AgentRuntimeProvider } from "../utils/AgentRegistry.js";
4
+
5
+ export type AgentRuntimeAvailability =
6
+ | { ok: true; insideRuntime: boolean; currentPaneId?: string }
7
+ | { ok: false; reason: "binary-missing" | "backend-unreachable"; detail: string };
8
+
9
+ export interface RuntimeStartInput {
10
+ name: string;
11
+ cwd: string;
12
+ kind: string;
13
+ args: string[];
14
+ timeoutMs: number;
15
+ }
16
+
17
+ export interface RuntimeStartResult {
18
+ pid: number;
19
+ runtimeRef: unknown;
20
+ }
21
+
22
+ export interface RuntimeTargetInput {
23
+ agent: Pick<AgentInfo, "name" | "pid">;
24
+ runtimeRef: unknown | null;
25
+ }
26
+
27
+ export interface RuntimeSendInput extends RuntimeTargetInput {
28
+ prompt: string;
29
+ }
30
+
31
+ export interface RuntimeFocusInput extends RuntimeTargetInput {
32
+ focusManager: {
33
+ findTerminal(pid: number): Promise<TerminalLocation | null>;
34
+ focusTerminal(location: TerminalLocation): Promise<boolean>;
35
+ };
36
+ }
37
+
38
+ export interface RuntimeStopInput extends RuntimeTargetInput {
39
+ killProcess?: (pid: number, signal: NodeJS.Signals) => void;
40
+ }
41
+
42
+ export interface RuntimeSendDeps {
43
+ focusManager: {
44
+ findTerminal(pid: number): Promise<TerminalLocation | null>;
45
+ };
46
+ writer?: (location: TerminalLocation, text: string) => Promise<void>;
47
+ }
48
+
49
+ export interface InteractiveAgentRuntime {
50
+ provider: AgentRuntimeProvider;
51
+ isAvailable(): Promise<AgentRuntimeAvailability>;
52
+ startAgent(input: RuntimeStartInput): Promise<RuntimeStartResult>;
53
+ send(input: RuntimeSendInput, deps?: RuntimeSendDeps): Promise<void>;
54
+ focus(input: RuntimeFocusInput): Promise<boolean>;
55
+ stop(input: RuntimeStopInput): Promise<void>;
56
+ }