@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,24 @@
1
- import { describe, expect, it } from 'vitest';
1
+ import { describe, expect, it } from "vitest";
2
2
 
3
- describe('durable-agent public domain', () => {
4
- it('exports a classified busy error without exposing prompt data', async () => {
5
- const api = await import('../../index.js') as Record<string, unknown>;
3
+ describe("durable-agent public domain", () => {
4
+ it("exports a classified busy error without exposing prompt data", async () => {
5
+ const api = (await import("../../index.js")) as Record<string, unknown>;
6
6
 
7
- expect(api).toHaveProperty('DurableAgentBusyError');
8
- const ErrorType = api.DurableAgentBusyError as new (agentId: string, name: string) => Error & {
9
- code: string;
10
- agentId: string;
11
- };
12
- const error = new ErrorType('agent-id', 'reviewer');
7
+ expect(api).toHaveProperty("DurableAgentBusyError");
8
+ const ErrorType = api.DurableAgentBusyError as new (
9
+ agentId: string,
10
+ name: string,
11
+ ) => Error & {
12
+ code: string;
13
+ agentId: string;
14
+ };
15
+ const error = new ErrorType("agent-id", "reviewer");
13
16
 
14
- expect(error).toMatchObject({
15
- name: 'DurableAgentBusyError',
16
- code: 'DURABLE_AGENT_BUSY',
17
- agentId: 'agent-id',
18
- message: 'Durable agent "reviewer" is busy.',
19
- });
17
+ expect(error).toMatchObject({
18
+ name: "DurableAgentBusyError",
19
+ code: "DURABLE_AGENT_BUSY",
20
+ agentId: "agent-id",
21
+ message: 'Durable agent "reviewer" is busy.',
20
22
  });
23
+ });
21
24
  });
@@ -1,105 +1,128 @@
1
- import fs from 'fs';
2
- import os from 'os';
3
- import path from 'path';
4
- import Database from 'better-sqlite3';
5
- import { afterEach, describe, expect, it } from 'vitest';
6
- import { DurableAgentRepository } from '../../durable/DurableAgentRepository.js';
1
+ import fs from "fs";
2
+ import os from "os";
3
+ import path from "path";
4
+ import Database from "better-sqlite3";
5
+ import { afterEach, describe, expect, it } from "vitest";
6
+ import { DurableAgentRepository } from "../../durable/DurableAgentRepository.js";
7
7
 
8
8
  const roots: string[] = [];
9
9
  afterEach(() => {
10
- for (const root of roots.splice(0)) fs.rmSync(root, { recursive: true, force: true });
10
+ for (const root of roots.splice(0)) fs.rmSync(root, { recursive: true, force: true });
11
11
  });
12
12
 
13
13
  function fixture() {
14
- const root = fs.mkdtempSync(path.join(os.tmpdir(), 'durable-agent-sqlite-'));
15
- roots.push(root);
16
- const cwd = path.join(root, 'project');
17
- fs.mkdirSync(cwd);
18
- return { root, cwd, dbPath: path.join(root, 'state', 'agents.db') };
14
+ const root = fs.mkdtempSync(path.join(os.tmpdir(), "durable-agent-sqlite-"));
15
+ roots.push(root);
16
+ const cwd = path.join(root, "project");
17
+ fs.mkdirSync(cwd);
18
+ return { root, cwd, dbPath: path.join(root, "state", "agents.db") };
19
19
  }
20
20
 
21
- describe('DurableAgentRepository SQLite concurrency', () => {
22
- it('allows exactly one acquisition across two connections', async () => {
23
- const { cwd, dbPath } = fixture();
24
- const identity = { pid: process.pid, startedAt: 'owner-start' };
25
- const processInspector = { getIdentity: (pid: number) => pid === process.pid ? identity : null };
26
- const first = new DurableAgentRepository({ dbPath, processInspector });
27
- const second = new DurableAgentRepository({ dbPath, processInspector });
28
- const agent = await first.create({ name: 'race', cwd });
29
- const results = await Promise.allSettled([first.acquireRun(agent.id), second.acquireRun(agent.id)]);
30
- expect(results.filter(({ status }) => status === 'fulfilled')).toHaveLength(1);
31
- const rejected = results.find(({ status }) => status === 'rejected');
32
- expect(rejected).toMatchObject({ reason: { code: 'DURABLE_AGENT_BUSY' } });
33
- });
21
+ describe("DurableAgentRepository SQLite concurrency", () => {
22
+ it("allows exactly one acquisition across two connections", async () => {
23
+ const { cwd, dbPath } = fixture();
24
+ const identity = { pid: process.pid, startedAt: "owner-start" };
25
+ const processInspector = {
26
+ getIdentity: (pid: number) => (pid === process.pid ? identity : null),
27
+ };
28
+ const first = new DurableAgentRepository({ dbPath, processInspector });
29
+ const second = new DurableAgentRepository({ dbPath, processInspector });
30
+ const agent = await first.create({ name: "race", cwd });
31
+ const results = await Promise.allSettled([
32
+ first.acquireRun(agent.id),
33
+ second.acquireRun(agent.id),
34
+ ]);
35
+ expect(results.filter(({ status }) => status === "fulfilled")).toHaveLength(1);
36
+ const rejected = results.find(({ status }) => status === "rejected");
37
+ expect(rejected).toMatchObject({ reason: { code: "DURABLE_AGENT_BUSY" } });
38
+ });
34
39
 
35
- it('accepts deprecated lock options without creating lock artifacts', async () => {
36
- const { root, cwd, dbPath } = fixture();
37
- const repository = new DurableAgentRepository({
38
- dbPath, lockTimeoutMs: 1, incompleteLockGraceMs: 1, mutationLockStaleMs: 1,
39
- });
40
- await repository.create({ name: 'lockless', cwd });
41
- expect(fs.existsSync(`${dbPath}.lock`)).toBe(false);
42
- expect(fs.existsSync(path.join(root, 'state', 'durable-agent-locks'))).toBe(false);
40
+ it("accepts deprecated lock options without creating lock artifacts", async () => {
41
+ const { root, cwd, dbPath } = fixture();
42
+ const repository = new DurableAgentRepository({
43
+ dbPath,
44
+ lockTimeoutMs: 1,
45
+ incompleteLockGraceMs: 1,
46
+ mutationLockStaleMs: 1,
43
47
  });
48
+ await repository.create({ name: "lockless", cwd });
49
+ expect(fs.existsSync(`${dbPath}.lock`)).toBe(false);
50
+ expect(fs.existsSync(path.join(root, "state", "durable-agent-locks"))).toBe(false);
51
+ });
44
52
 
45
- it('keeps readonly listing pure', async () => {
46
- const { cwd, dbPath } = fixture();
47
- const live = new Map([[process.pid, 'owner-start']]);
48
- const processInspector = { getIdentity: (pid: number) => {
49
- const startedAt = live.get(pid);
50
- return startedAt ? { pid, startedAt } : null;
51
- } };
52
- const writable = new DurableAgentRepository({ dbPath, processInspector });
53
- const agent = await writable.create({ name: 'readonly', cwd });
54
- await writable.acquireRun(agent.id);
55
- live.clear();
56
- const readonly = new DurableAgentRepository({ dbPath, readonly: true, processInspector });
57
- expect((await readonly.list())[0]?.state).toBe('running');
58
- });
53
+ it("keeps readonly listing pure", async () => {
54
+ const { cwd, dbPath } = fixture();
55
+ const live = new Map([[process.pid, "owner-start"]]);
56
+ const processInspector = {
57
+ getIdentity: (pid: number) => {
58
+ const startedAt = live.get(pid);
59
+ return startedAt ? { pid, startedAt } : null;
60
+ },
61
+ };
62
+ const writable = new DurableAgentRepository({ dbPath, processInspector });
63
+ const agent = await writable.create({ name: "readonly", cwd });
64
+ await writable.acquireRun(agent.id);
65
+ live.clear();
66
+ const readonly = new DurableAgentRepository({ dbPath, readonly: true, processInspector });
67
+ expect((await readonly.list())[0]?.state).toBe("running");
68
+ });
59
69
 
60
- it('rejects stale tokens and caps the persisted completion summary', async () => {
61
- const { cwd, dbPath } = fixture();
62
- const processInspector = { getIdentity: (pid: number) => ({ pid, startedAt: 'owner-start' }) };
63
- const repository = new DurableAgentRepository({ dbPath, processInspector });
64
- const agent = await repository.create({ name: 'token', cwd });
65
- const run = await repository.acquireRun(agent.id);
66
- await expect(repository.recordProviderProcess(agent.id, 'stale', { pid: 42, startedAt: 'provider' }))
67
- .rejects.toMatchObject({ code: 'DURABLE_AGENT_REPOSITORY' });
68
- const completed = await repository.completeRun(agent.id, run.token, {
69
- status: 'succeeded', exitCode: 0, summary: 'x'.repeat(5000), sessionHealth: 'healthy',
70
- });
71
- expect(completed.lastResult?.summary).toHaveLength(4096);
70
+ it("rejects stale tokens and caps the persisted completion summary", async () => {
71
+ const { cwd, dbPath } = fixture();
72
+ const processInspector = { getIdentity: (pid: number) => ({ pid, startedAt: "owner-start" }) };
73
+ const repository = new DurableAgentRepository({ dbPath, processInspector });
74
+ const agent = await repository.create({ name: "token", cwd });
75
+ const run = await repository.acquireRun(agent.id);
76
+ await expect(
77
+ repository.recordProviderProcess(agent.id, "stale", { pid: 42, startedAt: "provider" }),
78
+ ).rejects.toMatchObject({ code: "DURABLE_AGENT_REPOSITORY" });
79
+ const completed = await repository.completeRun(agent.id, run.token, {
80
+ status: "succeeded",
81
+ exitCode: 0,
82
+ summary: "x".repeat(5000),
83
+ sessionHealth: "healthy",
72
84
  });
85
+ expect(completed.lastResult?.summary).toHaveLength(4096);
86
+ });
73
87
 
74
- it('does not reconcile over ownership changed after process inspection', async () => {
75
- const { cwd, dbPath } = fixture();
76
- let inspect: (() => void) | undefined;
77
- const processInspector = { getIdentity: (pid: number) => {
78
- if (inspect) inspect();
79
- return inspect ? null : { pid, startedAt: 'owner-start' };
80
- } };
81
- const repository = new DurableAgentRepository({ dbPath, processInspector });
82
- const agent = await repository.create({ name: 'cas', cwd });
83
- await repository.acquireRun(agent.id);
84
- const other = new Database(dbPath);
85
- inspect = () => {
86
- inspect = undefined;
87
- other.prepare(`UPDATE durable_agents SET
88
+ it("does not reconcile over ownership changed after process inspection", async () => {
89
+ const { cwd, dbPath } = fixture();
90
+ let inspect: (() => void) | undefined;
91
+ const processInspector = {
92
+ getIdentity: (pid: number) => {
93
+ if (inspect) inspect();
94
+ return inspect ? null : { pid, startedAt: "owner-start" };
95
+ },
96
+ };
97
+ const repository = new DurableAgentRepository({ dbPath, processInspector });
98
+ const agent = await repository.create({ name: "cas", cwd });
99
+ await repository.acquireRun(agent.id);
100
+ const other = new Database(dbPath);
101
+ inspect = () => {
102
+ inspect = undefined;
103
+ other
104
+ .prepare(`UPDATE durable_agents SET
88
105
  active_run_token = 'replacement-token', active_owner_started_at = 'replacement-owner'
89
- WHERE id = ?`).run(agent.id);
90
- };
106
+ WHERE id = ?`)
107
+ .run(agent.id);
108
+ };
91
109
 
92
- await repository.reconcile();
110
+ await repository.reconcile();
93
111
 
94
- expect(other.prepare('SELECT state, active_run_token FROM durable_agents WHERE id = ?').get(agent.id))
95
- .toEqual({ state: 'running', active_run_token: 'replacement-token' });
96
- other.close();
97
- });
112
+ expect(
113
+ other
114
+ .prepare("SELECT state, active_run_token FROM durable_agents WHERE id = ?")
115
+ .get(agent.id),
116
+ ).toEqual({ state: "running", active_run_token: "replacement-token" });
117
+ other.close();
118
+ });
98
119
 
99
- it('maps a corrupt database to a store error', () => {
100
- const { dbPath } = fixture();
101
- fs.mkdirSync(path.dirname(dbPath), { recursive: true });
102
- fs.writeFileSync(dbPath, 'not sqlite');
103
- expect(() => new DurableAgentRepository({ dbPath })).toThrow(/Cannot open durable-agent database/);
104
- });
120
+ it("maps a corrupt database to a store error", () => {
121
+ const { dbPath } = fixture();
122
+ fs.mkdirSync(path.dirname(dbPath), { recursive: true });
123
+ fs.writeFileSync(dbPath, "not sqlite");
124
+ expect(() => new DurableAgentRepository({ dbPath })).toThrow(
125
+ /Cannot open durable-agent database/,
126
+ );
127
+ });
105
128
  });
@@ -1,163 +1,196 @@
1
- import fs from 'fs';
2
- import os from 'os';
3
- import path from 'path';
4
- import { afterEach, describe, expect, it } from 'vitest';
1
+ import fs from "fs";
2
+ import os from "os";
3
+ import path from "path";
4
+ import { afterEach, describe, expect, it } from "vitest";
5
5
 
6
6
  const tempDirs: string[] = [];
7
7
 
8
8
  afterEach(() => {
9
- for (const dir of tempDirs.splice(0)) fs.rmSync(dir, { recursive: true, force: true });
9
+ for (const dir of tempDirs.splice(0)) fs.rmSync(dir, { recursive: true, force: true });
10
10
  });
11
11
 
12
12
  async function loadStore(): Promise<any> {
13
- const api = await import('../../index.js') as Record<string, unknown>;
14
- expect(api).toHaveProperty('DurableAgentRepository');
15
- return api.DurableAgentRepository;
13
+ const api = (await import("../../index.js")) as Record<string, unknown>;
14
+ expect(api).toHaveProperty("DurableAgentRepository");
15
+ return api.DurableAgentRepository;
16
16
  }
17
17
 
18
18
  function fixture(): { root: string; cwd: string; dbPath: string } {
19
- const root = fs.mkdtempSync(path.join(os.tmpdir(), 'durable-agent-store-'));
20
- tempDirs.push(root);
21
- const cwd = path.join(root, 'project');
22
- fs.mkdirSync(cwd);
23
- return { root, cwd, dbPath: path.join(root, 'state', 'agents.db') };
19
+ const root = fs.mkdtempSync(path.join(os.tmpdir(), "durable-agent-store-"));
20
+ tempDirs.push(root);
21
+ const cwd = path.join(root, "project");
22
+ fs.mkdirSync(cwd);
23
+ return { root, cwd, dbPath: path.join(root, "state", "agents.db") };
24
24
  }
25
25
 
26
- describe('DurableAgentRepository create/list/resolve', () => {
27
- it('creates distinct durable identities with a canonical cwd and lists them', async () => {
28
- const DurableAgentRepository = await loadStore();
29
- const { cwd, dbPath } = fixture();
30
- const repository = new DurableAgentRepository({ dbPath, now: () => new Date('2026-08-07T09:00:00Z') });
31
-
32
- const agent = await repository.create({ name: 'reviewer', cwd });
33
-
34
- expect(agent).toMatchObject({
35
- name: 'reviewer',
36
- provider: 'claude',
37
- mode: 'durable',
38
- cwd: fs.realpathSync(cwd),
39
- state: 'ready',
40
- sessionHealth: 'uninitialized',
41
- activeRun: null,
42
- });
43
- expect(agent.id).toMatch(/^[0-9a-f-]{36}$/);
44
- expect(agent.providerSessionId).toMatch(/^[0-9a-f-]{36}$/);
45
- expect(agent.id).not.toBe(agent.providerSessionId);
46
- expect(await repository.list()).toEqual([agent]);
47
- expect(fs.existsSync(dbPath)).toBe(true);
26
+ describe("DurableAgentRepository create/list/resolve", () => {
27
+ it("creates distinct durable identities with a canonical cwd and lists them", async () => {
28
+ const DurableAgentRepository = await loadStore();
29
+ const { cwd, dbPath } = fixture();
30
+ const repository = new DurableAgentRepository({
31
+ dbPath,
32
+ now: () => new Date("2026-08-07T09:00:00Z"),
48
33
  });
49
34
 
50
- it('resolves exact ids and names and rejects duplicate names', async () => {
51
- const DurableAgentRepository = await loadStore();
52
- const { cwd, dbPath } = fixture();
53
- const repository = new DurableAgentRepository({ dbPath });
54
- const agent = await repository.create({ name: 'Reviewer', cwd });
55
-
56
- expect(await repository.resolve(agent.id)).toMatchObject({ id: agent.id });
57
- expect(await repository.resolve('reviewer')).toMatchObject({ id: agent.id });
58
- expect(await repository.resolve('view')).toBeNull();
59
- await expect(repository.create({ name: 'reviewer', cwd })).rejects.toMatchObject({
60
- code: 'DURABLE_AGENT_NAME_CONFLICT',
61
- });
35
+ const agent = await repository.create({ name: "reviewer", cwd });
36
+
37
+ expect(agent).toMatchObject({
38
+ name: "reviewer",
39
+ provider: "claude",
40
+ mode: "durable",
41
+ cwd: fs.realpathSync(cwd),
42
+ state: "ready",
43
+ sessionHealth: "uninitialized",
44
+ activeRun: null,
45
+ });
46
+ expect(agent.id).toMatch(/^[0-9a-f-]{36}$/);
47
+ expect(agent.providerSessionId).toMatch(/^[0-9a-f-]{36}$/);
48
+ expect(agent.id).not.toBe(agent.providerSessionId);
49
+ expect(await repository.list()).toEqual([agent]);
50
+ expect(fs.existsSync(dbPath)).toBe(true);
51
+ });
52
+
53
+ it("resolves exact ids and names and rejects duplicate names", async () => {
54
+ const DurableAgentRepository = await loadStore();
55
+ const { cwd, dbPath } = fixture();
56
+ const repository = new DurableAgentRepository({ dbPath });
57
+ const agent = await repository.create({ name: "Reviewer", cwd });
58
+
59
+ expect(await repository.resolve(agent.id)).toMatchObject({ id: agent.id });
60
+ expect(await repository.resolve("reviewer")).toMatchObject({ id: agent.id });
61
+ expect(await repository.resolve("view")).toBeNull();
62
+ await expect(repository.create({ name: "reviewer", cwd })).rejects.toMatchObject({
63
+ code: "DURABLE_AGENT_NAME_CONFLICT",
62
64
  });
65
+ });
63
66
 
64
- it('rejects a missing cwd', async () => {
65
- const DurableAgentRepository = await loadStore();
66
- const { root, dbPath } = fixture();
67
- const repository = new DurableAgentRepository({ dbPath });
67
+ it("rejects a missing cwd", async () => {
68
+ const DurableAgentRepository = await loadStore();
69
+ const { root, dbPath } = fixture();
70
+ const repository = new DurableAgentRepository({ dbPath });
68
71
 
69
- await expect(repository.create({ name: 'missing', cwd: path.join(root, 'missing') }))
70
- .rejects.toMatchObject({ code: 'DURABLE_AGENT_REPOSITORY' });
71
- });
72
+ await expect(
73
+ repository.create({ name: "missing", cwd: path.join(root, "missing") }),
74
+ ).rejects.toMatchObject({ code: "DURABLE_AGENT_REPOSITORY" });
75
+ });
72
76
  });
73
77
 
74
- describe('DurableAgentRepository run ownership', () => {
75
- it('fails fast when another exact owner is live and completes only for its token', async () => {
76
- const DurableAgentRepository = await loadStore();
77
- const { cwd, dbPath } = fixture();
78
- const live = new Map<number, string>([[process.pid, 'owner-start']]);
79
- const processInspector = { getIdentity: (pid: number) => {
80
- const startedAt = live.get(pid);
81
- return startedAt ? { pid, startedAt } : null;
82
- } };
83
- const repository = new DurableAgentRepository({ dbPath, processInspector });
84
- const agent = await repository.create({ name: 'runner', cwd });
85
-
86
- const acquired = await repository.acquireRun(agent.id);
87
- await expect(repository.acquireRun(agent.id)).rejects.toMatchObject({ code: 'DURABLE_AGENT_BUSY' });
88
- await expect(repository.completeRun(agent.id, 'wrong-token', {
89
- status: 'succeeded', exitCode: 0, summary: 'done', sessionHealth: 'healthy',
90
- })).rejects.toMatchObject({ code: 'DURABLE_AGENT_REPOSITORY' });
91
-
92
- const completed = await repository.completeRun(agent.id, acquired.token, {
93
- status: 'succeeded', exitCode: 0, summary: 'done', sessionHealth: 'healthy',
94
- });
95
- expect(completed).toMatchObject({ state: 'ready', sessionHealth: 'healthy', activeRun: null });
78
+ describe("DurableAgentRepository run ownership", () => {
79
+ it("fails fast when another exact owner is live and completes only for its token", async () => {
80
+ const DurableAgentRepository = await loadStore();
81
+ const { cwd, dbPath } = fixture();
82
+ const live = new Map<number, string>([[process.pid, "owner-start"]]);
83
+ const processInspector = {
84
+ getIdentity: (pid: number) => {
85
+ const startedAt = live.get(pid);
86
+ return startedAt ? { pid, startedAt } : null;
87
+ },
88
+ };
89
+ const repository = new DurableAgentRepository({ dbPath, processInspector });
90
+ const agent = await repository.create({ name: "runner", cwd });
91
+
92
+ const acquired = await repository.acquireRun(agent.id);
93
+ await expect(repository.acquireRun(agent.id)).rejects.toMatchObject({
94
+ code: "DURABLE_AGENT_BUSY",
96
95
  });
97
-
98
- it('retains busy for a live provider then recovers a dead run without signaling it', async () => {
99
- const DurableAgentRepository = await loadStore();
100
- const { cwd, dbPath } = fixture();
101
- const live = new Map<number, string>([[process.pid, 'owner-start'], [4242, 'provider-start']]);
102
- const processInspector = { getIdentity: (pid: number) => {
103
- const startedAt = live.get(pid);
104
- return startedAt ? { pid, startedAt } : null;
105
- } };
106
- const first = new DurableAgentRepository({ dbPath, processInspector });
107
- const agent = await first.create({ name: 'recoverable', cwd });
108
- const run = await first.acquireRun(agent.id);
109
- await first.recordProviderProcess(agent.id, run.token, { pid: 4242, startedAt: 'provider-start' });
110
-
111
- live.delete(process.pid);
112
- await expect(first.acquireRun(agent.id)).rejects.toMatchObject({ code: 'DURABLE_AGENT_BUSY' });
113
-
114
- live.delete(4242);
115
- live.set(process.pid, 'replacement-owner-start');
116
- const recovered = await first.acquireRun(agent.id);
117
- expect(recovered.agent).toMatchObject({
118
- state: 'running',
119
- lastResult: { status: 'interrupted' },
120
- });
121
- await first.completeRun(agent.id, recovered.token, {
122
- status: 'failed', exitCode: 1, summary: 'failed', sessionHealth: 'unknown',
123
- });
96
+ await expect(
97
+ repository.completeRun(agent.id, "wrong-token", {
98
+ status: "succeeded",
99
+ exitCode: 0,
100
+ summary: "done",
101
+ sessionHealth: "healthy",
102
+ }),
103
+ ).rejects.toMatchObject({ code: "DURABLE_AGENT_REPOSITORY" });
104
+
105
+ const completed = await repository.completeRun(agent.id, acquired.token, {
106
+ status: "succeeded",
107
+ exitCode: 0,
108
+ summary: "done",
109
+ sessionHealth: "healthy",
110
+ });
111
+ expect(completed).toMatchObject({ state: "ready", sessionHealth: "healthy", activeRun: null });
112
+ });
113
+
114
+ it("retains busy for a live provider then recovers a dead run without signaling it", async () => {
115
+ const DurableAgentRepository = await loadStore();
116
+ const { cwd, dbPath } = fixture();
117
+ const live = new Map<number, string>([
118
+ [process.pid, "owner-start"],
119
+ [4242, "provider-start"],
120
+ ]);
121
+ const processInspector = {
122
+ getIdentity: (pid: number) => {
123
+ const startedAt = live.get(pid);
124
+ return startedAt ? { pid, startedAt } : null;
125
+ },
126
+ };
127
+ const first = new DurableAgentRepository({ dbPath, processInspector });
128
+ const agent = await first.create({ name: "recoverable", cwd });
129
+ const run = await first.acquireRun(agent.id);
130
+ await first.recordProviderProcess(agent.id, run.token, {
131
+ pid: 4242,
132
+ startedAt: "provider-start",
124
133
  });
125
134
 
126
- it('reconciles an interrupted run to degraded during list', async () => {
127
- const DurableAgentRepository = await loadStore();
128
- const { cwd, dbPath } = fixture();
129
- const live = new Map<number, string>([[process.pid, 'owner-start']]);
130
- const repository = new DurableAgentRepository({ dbPath, incompleteLockGraceMs: 10, processInspector: {
131
- getIdentity: (pid: number) => {
132
- const startedAt = live.get(pid);
133
- return startedAt ? { pid, startedAt } : null;
134
- },
135
- } });
136
- const agent = await repository.create({ name: 'crashed', cwd });
137
- await repository.acquireRun(agent.id);
138
- live.clear();
139
-
140
- const listed = await repository.list();
141
-
142
- expect(listed[0]).toMatchObject({
143
- state: 'degraded',
144
- sessionHealth: 'unknown',
145
- activeRun: null,
146
- lastResult: { status: 'interrupted' },
147
- });
135
+ live.delete(process.pid);
136
+ await expect(first.acquireRun(agent.id)).rejects.toMatchObject({ code: "DURABLE_AGENT_BUSY" });
137
+
138
+ live.delete(4242);
139
+ live.set(process.pid, "replacement-owner-start");
140
+ const recovered = await first.acquireRun(agent.id);
141
+ expect(recovered.agent).toMatchObject({
142
+ state: "running",
143
+ lastResult: { status: "interrupted" },
144
+ });
145
+ await first.completeRun(agent.id, recovered.token, {
146
+ status: "failed",
147
+ exitCode: 1,
148
+ summary: "failed",
149
+ sessionHealth: "unknown",
150
+ });
151
+ });
152
+
153
+ it("reconciles an interrupted run to degraded during list", async () => {
154
+ const DurableAgentRepository = await loadStore();
155
+ const { cwd, dbPath } = fixture();
156
+ const live = new Map<number, string>([[process.pid, "owner-start"]]);
157
+ const repository = new DurableAgentRepository({
158
+ dbPath,
159
+ incompleteLockGraceMs: 10,
160
+ processInspector: {
161
+ getIdentity: (pid: number) => {
162
+ const startedAt = live.get(pid);
163
+ return startedAt ? { pid, startedAt } : null;
164
+ },
165
+ },
148
166
  });
167
+ const agent = await repository.create({ name: "crashed", cwd });
168
+ await repository.acquireRun(agent.id);
169
+ live.clear();
149
170
 
150
- it('rejects send acquisition when the bound cwd is replaced by a symlink', async () => {
151
- const DurableAgentRepository = await loadStore();
152
- const { root, cwd, dbPath } = fixture();
153
- const repository = new DurableAgentRepository({ dbPath });
154
- const agent = await repository.create({ name: 'bound', cwd });
155
- const moved = path.join(root, 'moved-project');
156
- const other = path.join(root, 'other-project');
157
- fs.renameSync(cwd, moved);
158
- fs.mkdirSync(other);
159
- fs.symlinkSync(other, cwd);
160
-
161
- await expect(repository.acquireRun(agent.id)).rejects.toMatchObject({ code: 'DURABLE_AGENT_REPOSITORY' });
171
+ const listed = await repository.list();
172
+
173
+ expect(listed[0]).toMatchObject({
174
+ state: "degraded",
175
+ sessionHealth: "unknown",
176
+ activeRun: null,
177
+ lastResult: { status: "interrupted" },
178
+ });
179
+ });
180
+
181
+ it("rejects send acquisition when the bound cwd is replaced by a symlink", async () => {
182
+ const DurableAgentRepository = await loadStore();
183
+ const { root, cwd, dbPath } = fixture();
184
+ const repository = new DurableAgentRepository({ dbPath });
185
+ const agent = await repository.create({ name: "bound", cwd });
186
+ const moved = path.join(root, "moved-project");
187
+ const other = path.join(root, "other-project");
188
+ fs.renameSync(cwd, moved);
189
+ fs.mkdirSync(other);
190
+ fs.symlinkSync(other, cwd);
191
+
192
+ await expect(repository.acquireRun(agent.id)).rejects.toMatchObject({
193
+ code: "DURABLE_AGENT_REPOSITORY",
162
194
  });
195
+ });
163
196
  });