@ai-devkit/agent-manager 0.31.0 → 0.33.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (519) hide show
  1. package/dist/AgentManager.d.ts +3 -3
  2. package/dist/AgentManager.d.ts.map +1 -1
  3. package/dist/AgentManager.js +80 -79
  4. package/dist/AgentManager.js.map +1 -1
  5. package/dist/__tests__/AgentManager.test.js +413 -388
  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/CopilotAdapter.test.js +254 -248
  12. package/dist/__tests__/adapters/CopilotAdapter.test.js.map +1 -1
  13. package/dist/__tests__/adapters/GeminiCliAdapter.test.js +564 -558
  14. package/dist/__tests__/adapters/GeminiCliAdapter.test.js.map +1 -1
  15. package/dist/__tests__/adapters/GrokCliAdapter.test.js +114 -114
  16. package/dist/__tests__/adapters/GrokCliAdapter.test.js.map +1 -1
  17. package/dist/__tests__/adapters/OpenCodeAdapter.test.js +169 -169
  18. package/dist/__tests__/adapters/OpenCodeAdapter.test.js.map +1 -1
  19. package/dist/__tests__/capacity/codex.test.js +93 -93
  20. package/dist/__tests__/capacity/codex.test.js.map +1 -1
  21. package/dist/__tests__/capacity/index.test.js +17 -17
  22. package/dist/__tests__/capacity/index.test.js.map +1 -1
  23. package/dist/__tests__/durable/CodexCliProbe.test.js +60 -60
  24. package/dist/__tests__/durable/CodexCliProbe.test.js.map +1 -1
  25. package/dist/__tests__/durable/CodexDurableAgentRepository.test.js +28 -28
  26. package/dist/__tests__/durable/CodexDurableAgentRepository.test.js.map +1 -1
  27. package/dist/__tests__/durable/CodexPrintAgent.integration.test.js +30 -30
  28. package/dist/__tests__/durable/CodexPrintAgent.integration.test.js.map +1 -1
  29. package/dist/__tests__/durable/CodexPrintAgentService.test.js +71 -71
  30. package/dist/__tests__/durable/CodexPrintAgentService.test.js.map +1 -1
  31. package/dist/__tests__/durable/CodexPrintRunner.test.js +125 -125
  32. package/dist/__tests__/durable/CodexPrintRunner.test.js.map +1 -1
  33. package/dist/__tests__/print/ClaudeCliProbe.test.js +20 -20
  34. package/dist/__tests__/print/ClaudeCliProbe.test.js.map +1 -1
  35. package/dist/__tests__/print/ClaudePrintAgent.integration.test.js +20 -20
  36. package/dist/__tests__/print/ClaudePrintAgent.integration.test.js.map +1 -1
  37. package/dist/__tests__/print/ClaudePrintAgentService.test.js +58 -58
  38. package/dist/__tests__/print/ClaudePrintAgentService.test.js.map +1 -1
  39. package/dist/__tests__/print/ClaudePrintRunner.test.js +55 -55
  40. package/dist/__tests__/print/ClaudePrintRunner.test.js.map +1 -1
  41. package/dist/__tests__/print/DurableAgent.test.js +9 -9
  42. package/dist/__tests__/print/DurableAgent.test.js.map +1 -1
  43. package/dist/__tests__/print/DurableAgentRepository.sqlite.test.js +40 -40
  44. package/dist/__tests__/print/DurableAgentRepository.sqlite.test.js.map +1 -1
  45. package/dist/__tests__/print/DurableAgentRepository.test.js +66 -66
  46. package/dist/__tests__/print/DurableAgentRepository.test.js.map +1 -1
  47. package/dist/__tests__/providers/claude/ClaudeAgentMapper.test.js +34 -34
  48. package/dist/__tests__/providers/claude/ClaudeAgentMapper.test.js.map +1 -1
  49. package/dist/__tests__/providers/claude/ClaudeSessionLocator.test.js +132 -132
  50. package/dist/__tests__/providers/claude/ClaudeSessionLocator.test.js.map +1 -1
  51. package/dist/__tests__/providers/codex/CodexSessionLocator.test.js +194 -0
  52. package/dist/__tests__/providers/codex/CodexSessionLocator.test.js.map +1 -0
  53. package/dist/__tests__/providers/codex/CodexSessionMapping.test.js +86 -0
  54. package/dist/__tests__/providers/codex/CodexSessionMapping.test.js.map +1 -0
  55. package/dist/__tests__/providers/codex/CodexSessionParser.test.js +254 -0
  56. package/dist/__tests__/providers/codex/CodexSessionParser.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 +301 -0
  76. package/dist/__tests__/readiness/AgentReadiness.test.js.map +1 -0
  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/HerdrAgentRuntime.test.js +452 -0
  80. package/dist/__tests__/runtime/HerdrAgentRuntime.test.js.map +1 -0
  81. package/dist/__tests__/runtime/ManagedAgentRuntime.test.js +588 -0
  82. package/dist/__tests__/runtime/ManagedAgentRuntime.test.js.map +1 -0
  83. package/dist/__tests__/terminal/TerminalFocusManager.test.js +100 -100
  84. package/dist/__tests__/terminal/TerminalFocusManager.test.js.map +1 -1
  85. package/dist/__tests__/terminal/TmuxManager.test.js +101 -101
  86. package/dist/__tests__/terminal/TmuxManager.test.js.map +1 -1
  87. package/dist/__tests__/terminal/TtyWriter.test.js +185 -185
  88. package/dist/__tests__/terminal/TtyWriter.test.js.map +1 -1
  89. package/dist/__tests__/utils/AgentRegistry.test.js +335 -217
  90. package/dist/__tests__/utils/AgentRegistry.test.js.map +1 -1
  91. package/dist/__tests__/utils/ClaudeSessionParser.test.js +103 -101
  92. package/dist/__tests__/utils/ClaudeSessionParser.test.js.map +1 -1
  93. package/dist/__tests__/utils/agent-requests.test.js +43 -43
  94. package/dist/__tests__/utils/agent-requests.test.js.map +1 -1
  95. package/dist/__tests__/utils/agents.test.js +17 -17
  96. package/dist/__tests__/utils/agents.test.js.map +1 -1
  97. package/dist/__tests__/utils/matching.test.js +92 -92
  98. package/dist/__tests__/utils/matching.test.js.map +1 -1
  99. package/dist/__tests__/utils/process.test.js +108 -108
  100. package/dist/__tests__/utils/process.test.js.map +1 -1
  101. package/dist/__tests__/utils/session.test.js +53 -53
  102. package/dist/__tests__/utils/session.test.js.map +1 -1
  103. package/dist/adapters/AgentAdapter.d.ts +2 -2
  104. package/dist/adapters/AgentAdapter.d.ts.map +1 -1
  105. package/dist/adapters/AgentAdapter.js +1 -1
  106. package/dist/adapters/AgentAdapter.js.map +1 -1
  107. package/dist/adapters/CopilotAdapter.d.ts +2 -2
  108. package/dist/adapters/CopilotAdapter.d.ts.map +1 -1
  109. package/dist/adapters/CopilotAdapter.js +51 -51
  110. package/dist/adapters/CopilotAdapter.js.map +1 -1
  111. package/dist/adapters/GeminiCliAdapter.d.ts +2 -2
  112. package/dist/adapters/GeminiCliAdapter.d.ts.map +1 -1
  113. package/dist/adapters/GeminiCliAdapter.js +86 -86
  114. package/dist/adapters/GeminiCliAdapter.js.map +1 -1
  115. package/dist/adapters/GrokCliAdapter.d.ts +1 -1
  116. package/dist/adapters/GrokCliAdapter.d.ts.map +1 -1
  117. package/dist/adapters/GrokCliAdapter.js +80 -80
  118. package/dist/adapters/GrokCliAdapter.js.map +1 -1
  119. package/dist/adapters/OpenCodeAdapter.d.ts +1 -1
  120. package/dist/adapters/OpenCodeAdapter.d.ts.map +1 -1
  121. package/dist/adapters/OpenCodeAdapter.js +37 -36
  122. package/dist/adapters/OpenCodeAdapter.js.map +1 -1
  123. package/dist/adapters/index.d.ts +9 -9
  124. package/dist/adapters/index.d.ts.map +1 -1
  125. package/dist/adapters/index.js +8 -8
  126. package/dist/adapters/index.js.map +1 -1
  127. package/dist/capacity/codex.d.ts +3 -3
  128. package/dist/capacity/codex.d.ts.map +1 -1
  129. package/dist/capacity/codex.js +57 -57
  130. package/dist/capacity/codex.js.map +1 -1
  131. package/dist/capacity/index.d.ts +3 -3
  132. package/dist/capacity/index.d.ts.map +1 -1
  133. package/dist/capacity/index.js +8 -8
  134. package/dist/capacity/index.js.map +1 -1
  135. package/dist/capacity/types.d.ts +1 -1
  136. package/dist/capacity/types.js.map +1 -1
  137. package/dist/database/connection.d.ts +1 -1
  138. package/dist/database/connection.d.ts.map +1 -1
  139. package/dist/database/connection.js +15 -15
  140. package/dist/database/connection.js.map +1 -1
  141. package/dist/database/index.d.ts +3 -3
  142. package/dist/database/index.d.ts.map +1 -1
  143. package/dist/database/index.js +2 -2
  144. package/dist/database/index.js.map +1 -1
  145. package/dist/database/migrations/005_agent_runtime.sql +2 -0
  146. package/dist/database/schema.d.ts +1 -1
  147. package/dist/database/schema.d.ts.map +1 -1
  148. package/dist/database/schema.js +7 -7
  149. package/dist/database/schema.js.map +1 -1
  150. package/dist/durable/DurableAgent.d.ts +9 -9
  151. package/dist/durable/DurableAgent.d.ts.map +1 -1
  152. package/dist/durable/DurableAgent.js +16 -16
  153. package/dist/durable/DurableAgent.js.map +1 -1
  154. package/dist/durable/DurableAgentRepository.d.ts +4 -4
  155. package/dist/durable/DurableAgentRepository.d.ts.map +1 -1
  156. package/dist/durable/DurableAgentRepository.js +49 -48
  157. package/dist/durable/DurableAgentRepository.js.map +1 -1
  158. package/dist/durable/process.d.ts +1 -1
  159. package/dist/durable/process.d.ts.map +1 -1
  160. package/dist/durable/process.js +14 -14
  161. package/dist/durable/process.js.map +1 -1
  162. package/dist/durable/run.d.ts +2 -2
  163. package/dist/durable/run.d.ts.map +1 -1
  164. package/dist/durable/run.js +6 -6
  165. package/dist/durable/run.js.map +1 -1
  166. package/dist/durable/utils.d.ts +1 -1
  167. package/dist/durable/utils.d.ts.map +1 -1
  168. package/dist/durable/utils.js +4 -4
  169. package/dist/durable/utils.js.map +1 -1
  170. package/dist/index.d.ts +46 -41
  171. package/dist/index.d.ts.map +1 -1
  172. package/dist/index.js +27 -25
  173. package/dist/index.js.map +1 -1
  174. package/dist/providers/claude/ClaudeAgentMapper.d.ts +4 -4
  175. package/dist/providers/claude/ClaudeAgentMapper.d.ts.map +1 -1
  176. package/dist/providers/claude/ClaudeAgentMapper.js +10 -10
  177. package/dist/providers/claude/ClaudeAgentMapper.js.map +1 -1
  178. package/dist/providers/claude/ClaudeCodeAdapter.d.ts +1 -1
  179. package/dist/providers/claude/ClaudeCodeAdapter.d.ts.map +1 -1
  180. package/dist/providers/claude/ClaudeCodeAdapter.js +14 -14
  181. package/dist/providers/claude/ClaudeCodeAdapter.js.map +1 -1
  182. package/dist/providers/claude/ClaudeSessionLocator.d.ts +4 -4
  183. package/dist/providers/claude/ClaudeSessionLocator.d.ts.map +1 -1
  184. package/dist/providers/claude/ClaudeSessionLocator.js +79 -79
  185. package/dist/providers/claude/ClaudeSessionLocator.js.map +1 -1
  186. package/dist/providers/claude/ClaudeSessionParser.d.ts +2 -2
  187. package/dist/providers/claude/ClaudeSessionParser.d.ts.map +1 -1
  188. package/dist/providers/claude/ClaudeSessionParser.js +99 -99
  189. package/dist/providers/claude/ClaudeSessionParser.js.map +1 -1
  190. package/dist/providers/claude/durable/ClaudeCliProbe.d.ts.map +1 -1
  191. package/dist/providers/claude/durable/ClaudeCliProbe.js +16 -16
  192. package/dist/providers/claude/durable/ClaudeCliProbe.js.map +1 -1
  193. package/dist/providers/claude/durable/ClaudePrintAgentService.d.ts +5 -5
  194. package/dist/providers/claude/durable/ClaudePrintAgentService.d.ts.map +1 -1
  195. package/dist/providers/claude/durable/ClaudePrintAgentService.js +10 -10
  196. package/dist/providers/claude/durable/ClaudePrintAgentService.js.map +1 -1
  197. package/dist/providers/claude/durable/ClaudePrintRunner.d.ts +4 -4
  198. package/dist/providers/claude/durable/ClaudePrintRunner.d.ts.map +1 -1
  199. package/dist/providers/claude/durable/ClaudePrintRunner.js +18 -18
  200. package/dist/providers/claude/durable/ClaudePrintRunner.js.map +1 -1
  201. package/dist/providers/claude/durable/ClaudeStreamParser.d.ts +2 -2
  202. package/dist/providers/claude/durable/ClaudeStreamParser.d.ts.map +1 -1
  203. package/dist/providers/claude/durable/ClaudeStreamParser.js +17 -17
  204. package/dist/providers/claude/durable/ClaudeStreamParser.js.map +1 -1
  205. package/dist/providers/codex/CodexAdapter.d.ts +27 -0
  206. package/dist/providers/codex/CodexAdapter.d.ts.map +1 -0
  207. package/dist/providers/codex/CodexAdapter.js +162 -0
  208. package/dist/providers/codex/CodexAdapter.js.map +1 -0
  209. package/dist/providers/codex/CodexAgentMapper.d.ts +9 -0
  210. package/dist/providers/codex/CodexAgentMapper.d.ts.map +1 -0
  211. package/dist/providers/codex/CodexAgentMapper.js +35 -0
  212. package/dist/providers/codex/CodexAgentMapper.js.map +1 -0
  213. package/dist/providers/codex/CodexSessionLocator.d.ts +44 -0
  214. package/dist/providers/codex/CodexSessionLocator.d.ts.map +1 -0
  215. package/dist/providers/codex/CodexSessionLocator.js +207 -0
  216. package/dist/providers/codex/CodexSessionLocator.js.map +1 -0
  217. package/dist/providers/codex/CodexSessionMapping.d.ts +23 -0
  218. package/dist/providers/codex/CodexSessionMapping.d.ts.map +1 -0
  219. package/dist/providers/codex/CodexSessionMapping.js +68 -0
  220. package/dist/providers/codex/CodexSessionMapping.js.map +1 -0
  221. package/dist/providers/codex/CodexSessionParser.d.ts +58 -0
  222. package/dist/providers/codex/CodexSessionParser.d.ts.map +1 -0
  223. package/dist/providers/codex/CodexSessionParser.js +262 -0
  224. package/dist/providers/codex/CodexSessionParser.js.map +1 -0
  225. package/dist/providers/codex/durable/CodexCliProbe.d.ts.map +1 -1
  226. package/dist/providers/codex/durable/CodexCliProbe.js +22 -22
  227. package/dist/providers/codex/durable/CodexCliProbe.js.map +1 -1
  228. package/dist/providers/codex/durable/CodexPrintAgentService.d.ts +6 -6
  229. package/dist/providers/codex/durable/CodexPrintAgentService.d.ts.map +1 -1
  230. package/dist/providers/codex/durable/CodexPrintAgentService.js +10 -10
  231. package/dist/providers/codex/durable/CodexPrintAgentService.js.map +1 -1
  232. package/dist/providers/codex/durable/CodexPrintRunner.d.ts +4 -4
  233. package/dist/providers/codex/durable/CodexPrintRunner.d.ts.map +1 -1
  234. package/dist/providers/codex/durable/CodexPrintRunner.js +20 -20
  235. package/dist/providers/codex/durable/CodexPrintRunner.js.map +1 -1
  236. package/dist/providers/codex/durable/CodexStreamParser.d.ts +2 -2
  237. package/dist/providers/codex/durable/CodexStreamParser.d.ts.map +1 -1
  238. package/dist/providers/codex/durable/CodexStreamParser.js +21 -21
  239. package/dist/providers/codex/durable/CodexStreamParser.js.map +1 -1
  240. package/dist/providers/pi/PiAdapter.d.ts +28 -0
  241. package/dist/providers/pi/PiAdapter.d.ts.map +1 -0
  242. package/dist/providers/pi/PiAdapter.js +153 -0
  243. package/dist/providers/pi/PiAdapter.js.map +1 -0
  244. package/dist/providers/pi/PiAgentMapper.d.ts +9 -0
  245. package/dist/providers/pi/PiAgentMapper.d.ts.map +1 -0
  246. package/dist/providers/pi/PiAgentMapper.js +37 -0
  247. package/dist/providers/pi/PiAgentMapper.js.map +1 -0
  248. package/dist/providers/pi/PiSessionLocator.d.ts +23 -0
  249. package/dist/providers/pi/PiSessionLocator.d.ts.map +1 -0
  250. package/dist/providers/pi/PiSessionLocator.js +79 -0
  251. package/dist/providers/pi/PiSessionLocator.js.map +1 -0
  252. package/dist/providers/pi/PiSessionParser.d.ts +36 -0
  253. package/dist/providers/pi/PiSessionParser.d.ts.map +1 -0
  254. package/dist/providers/pi/PiSessionParser.js +191 -0
  255. package/dist/providers/pi/PiSessionParser.js.map +1 -0
  256. package/dist/providers/pi/PiSessionTracker.d.ts +23 -0
  257. package/dist/providers/pi/PiSessionTracker.d.ts.map +1 -0
  258. package/dist/providers/pi/PiSessionTracker.js +69 -0
  259. package/dist/providers/pi/PiSessionTracker.js.map +1 -0
  260. package/dist/providers/pi/durable/PiCliProbe.d.ts.map +1 -1
  261. package/dist/providers/pi/durable/PiCliProbe.js +15 -15
  262. package/dist/providers/pi/durable/PiCliProbe.js.map +1 -1
  263. package/dist/providers/pi/durable/PiPrintAgentService.d.ts +6 -6
  264. package/dist/providers/pi/durable/PiPrintAgentService.d.ts.map +1 -1
  265. package/dist/providers/pi/durable/PiPrintAgentService.js +10 -10
  266. package/dist/providers/pi/durable/PiPrintAgentService.js.map +1 -1
  267. package/dist/providers/pi/durable/PiPrintProtocol.d.ts.map +1 -1
  268. package/dist/providers/pi/durable/PiPrintProtocol.js +18 -18
  269. package/dist/providers/pi/durable/PiPrintProtocol.js.map +1 -1
  270. package/dist/providers/pi/durable/PiPrintRunner.d.ts +4 -4
  271. package/dist/providers/pi/durable/PiPrintRunner.d.ts.map +1 -1
  272. package/dist/providers/pi/durable/PiPrintRunner.js +15 -15
  273. package/dist/providers/pi/durable/PiPrintRunner.js.map +1 -1
  274. package/dist/providers/pi/durable/PiStreamParser.d.ts +1 -1
  275. package/dist/providers/pi/durable/PiStreamParser.d.ts.map +1 -1
  276. package/dist/providers/pi/durable/PiStreamParser.js +16 -16
  277. package/dist/providers/pi/durable/PiStreamParser.js.map +1 -1
  278. package/dist/readiness/AgentReadiness.d.ts +67 -0
  279. package/dist/readiness/AgentReadiness.d.ts.map +1 -0
  280. package/dist/readiness/AgentReadiness.js +614 -0
  281. package/dist/readiness/AgentReadiness.js.map +1 -0
  282. package/dist/runtime/ManagedAgentRuntime.d.ts +69 -0
  283. package/dist/runtime/ManagedAgentRuntime.d.ts.map +1 -0
  284. package/dist/runtime/ManagedAgentRuntime.js +156 -0
  285. package/dist/runtime/ManagedAgentRuntime.js.map +1 -0
  286. package/dist/runtime/RuntimeFactory.d.ts +4 -0
  287. package/dist/runtime/RuntimeFactory.d.ts.map +1 -0
  288. package/dist/runtime/RuntimeFactory.js +11 -0
  289. package/dist/runtime/RuntimeFactory.js.map +1 -0
  290. package/dist/runtime/errors.d.ts +27 -0
  291. package/dist/runtime/errors.d.ts.map +1 -0
  292. package/dist/runtime/errors.js +42 -0
  293. package/dist/runtime/errors.js.map +1 -0
  294. package/dist/runtime/herdr/HerdrAgentRuntime.d.ts +31 -0
  295. package/dist/runtime/herdr/HerdrAgentRuntime.d.ts.map +1 -0
  296. package/dist/runtime/herdr/HerdrAgentRuntime.js +184 -0
  297. package/dist/runtime/herdr/HerdrAgentRuntime.js.map +1 -0
  298. package/dist/runtime/herdr/HerdrCliClient.d.ts +13 -0
  299. package/dist/runtime/herdr/HerdrCliClient.d.ts.map +1 -0
  300. package/dist/runtime/herdr/HerdrCliClient.js +60 -0
  301. package/dist/runtime/herdr/HerdrCliClient.js.map +1 -0
  302. package/dist/runtime/herdr/HerdrErrors.d.ts +7 -0
  303. package/dist/runtime/herdr/HerdrErrors.d.ts.map +1 -0
  304. package/dist/runtime/herdr/HerdrErrors.js +10 -0
  305. package/dist/runtime/herdr/HerdrErrors.js.map +1 -0
  306. package/dist/runtime/herdr/HerdrResponseParsers.d.ts +14 -0
  307. package/dist/runtime/herdr/HerdrResponseParsers.d.ts.map +1 -0
  308. package/dist/runtime/herdr/HerdrResponseParsers.js +96 -0
  309. package/dist/runtime/herdr/HerdrResponseParsers.js.map +1 -0
  310. package/dist/runtime/herdr/HerdrRuntimeRef.d.ts +9 -0
  311. package/dist/runtime/herdr/HerdrRuntimeRef.d.ts.map +1 -0
  312. package/dist/runtime/herdr/HerdrRuntimeRef.js +33 -0
  313. package/dist/runtime/herdr/HerdrRuntimeRef.js.map +1 -0
  314. package/dist/runtime/tmux/PidPolling.d.ts +5 -0
  315. package/dist/runtime/tmux/PidPolling.d.ts.map +1 -0
  316. package/dist/runtime/tmux/PidPolling.js +24 -0
  317. package/dist/runtime/tmux/PidPolling.js.map +1 -0
  318. package/dist/runtime/tmux/TmuxAgentRuntime.d.ts +17 -0
  319. package/dist/runtime/tmux/TmuxAgentRuntime.d.ts.map +1 -0
  320. package/dist/runtime/tmux/TmuxAgentRuntime.js +80 -0
  321. package/dist/runtime/tmux/TmuxAgentRuntime.js.map +1 -0
  322. package/dist/runtime/tmux/TmuxRuntimeRef.d.ts +5 -0
  323. package/dist/runtime/tmux/TmuxRuntimeRef.d.ts.map +1 -0
  324. package/dist/runtime/tmux/TmuxRuntimeRef.js +9 -0
  325. package/dist/runtime/tmux/TmuxRuntimeRef.js.map +1 -0
  326. package/dist/runtime/types.d.ts +54 -0
  327. package/dist/runtime/types.d.ts.map +1 -0
  328. package/dist/runtime/types.js +3 -0
  329. package/dist/runtime/types.js.map +1 -0
  330. package/dist/terminal/TerminalFocusManager.d.ts.map +1 -1
  331. package/dist/terminal/TerminalFocusManager.js +50 -50
  332. package/dist/terminal/TerminalFocusManager.js.map +1 -1
  333. package/dist/terminal/TmuxManager.d.ts.map +1 -1
  334. package/dist/terminal/TmuxManager.js +47 -47
  335. package/dist/terminal/TmuxManager.js.map +1 -1
  336. package/dist/terminal/TtyWriter.d.ts +1 -1
  337. package/dist/terminal/TtyWriter.d.ts.map +1 -1
  338. package/dist/terminal/TtyWriter.js +89 -89
  339. package/dist/terminal/TtyWriter.js.map +1 -1
  340. package/dist/terminal/index.d.ts +4 -4
  341. package/dist/terminal/index.js +3 -3
  342. package/dist/terminal/index.js.map +1 -1
  343. package/dist/utils/AgentRegistry.d.ts +10 -2
  344. package/dist/utils/AgentRegistry.d.ts.map +1 -1
  345. package/dist/utils/AgentRegistry.js +57 -24
  346. package/dist/utils/AgentRegistry.js.map +1 -1
  347. package/dist/utils/agent-requests.d.ts.map +1 -1
  348. package/dist/utils/agent-requests.js +5 -5
  349. package/dist/utils/agent-requests.js.map +1 -1
  350. package/dist/utils/agents.d.ts +2 -2
  351. package/dist/utils/agents.d.ts.map +1 -1
  352. package/dist/utils/agents.js +15 -15
  353. package/dist/utils/agents.js.map +1 -1
  354. package/dist/utils/applescript.js +1 -1
  355. package/dist/utils/applescript.js.map +1 -1
  356. package/dist/utils/index.d.ts +6 -6
  357. package/dist/utils/index.d.ts.map +1 -1
  358. package/dist/utils/index.js +4 -4
  359. package/dist/utils/index.js.map +1 -1
  360. package/dist/utils/matching.d.ts +2 -2
  361. package/dist/utils/matching.d.ts.map +1 -1
  362. package/dist/utils/matching.js +4 -4
  363. package/dist/utils/matching.js.map +1 -1
  364. package/dist/utils/process.d.ts +1 -1
  365. package/dist/utils/process.d.ts.map +1 -1
  366. package/dist/utils/process.js +74 -74
  367. package/dist/utils/process.js.map +1 -1
  368. package/dist/utils/session.d.ts +1 -1
  369. package/dist/utils/session.d.ts.map +1 -1
  370. package/dist/utils/session.js +7 -7
  371. package/dist/utils/session.js.map +1 -1
  372. package/dist/utils/sortAgents.d.ts +2 -2
  373. package/dist/utils/sortAgents.d.ts.map +1 -1
  374. package/dist/utils/sortAgents.js +5 -5
  375. package/dist/utils/sortAgents.js.map +1 -1
  376. package/package.json +18 -19
  377. package/src/AgentManager.ts +283 -281
  378. package/src/__tests__/AgentManager.test.ts +917 -907
  379. package/src/__tests__/adapters/ClaudeCodeAdapter.test.ts +1657 -1368
  380. package/src/__tests__/adapters/CodexAdapter.test.ts +365 -1698
  381. package/src/__tests__/adapters/CopilotAdapter.test.ts +576 -481
  382. package/src/__tests__/adapters/GeminiCliAdapter.test.ts +1189 -1157
  383. package/src/__tests__/adapters/GrokCliAdapter.test.ts +325 -272
  384. package/src/__tests__/adapters/OpenCodeAdapter.test.ts +510 -455
  385. package/src/__tests__/capacity/codex.test.ts +178 -91
  386. package/src/__tests__/capacity/index.test.ts +27 -18
  387. package/src/__tests__/durable/CodexCliProbe.test.ts +75 -53
  388. package/src/__tests__/durable/CodexDurableAgentRepository.test.ts +51 -40
  389. package/src/__tests__/durable/CodexPrintAgent.integration.test.ts +89 -64
  390. package/src/__tests__/durable/CodexPrintAgentService.test.ts +196 -118
  391. package/src/__tests__/durable/CodexPrintRunner.test.ts +282 -162
  392. package/src/__tests__/fixtures/fake-claude.cjs +20 -13
  393. package/src/__tests__/fixtures/fake-codex.cjs +41 -30
  394. package/src/__tests__/print/ClaudeCliProbe.test.ts +27 -21
  395. package/src/__tests__/print/ClaudePrintAgent.integration.test.ts +48 -40
  396. package/src/__tests__/print/ClaudePrintAgentService.test.ts +118 -67
  397. package/src/__tests__/print/ClaudePrintRunner.test.ts +136 -83
  398. package/src/__tests__/print/DurableAgent.test.ts +19 -16
  399. package/src/__tests__/print/DurableAgentRepository.sqlite.test.ts +109 -86
  400. package/src/__tests__/print/DurableAgentRepository.test.ts +170 -137
  401. package/src/__tests__/providers/claude/ClaudeAgentMapper.test.ts +65 -65
  402. package/src/__tests__/providers/claude/ClaudeSessionLocator.test.ts +400 -377
  403. package/src/__tests__/providers/codex/CodexSessionLocator.test.ts +182 -0
  404. package/src/__tests__/providers/codex/CodexSessionMapping.test.ts +63 -0
  405. package/src/__tests__/providers/codex/CodexSessionParser.test.ts +192 -0
  406. package/src/__tests__/providers/pi/PiAdapter.test.ts +310 -0
  407. package/src/__tests__/providers/pi/PiSessionParser.test.ts +190 -0
  408. package/src/__tests__/providers/pi/PiSessionTracker.test.ts +79 -0
  409. package/src/__tests__/providers/pi/durable/PiCliProbe.test.ts +48 -32
  410. package/src/__tests__/providers/pi/durable/PiDurableAgentRepository.test.ts +24 -23
  411. package/src/__tests__/providers/pi/durable/PiPrintAgentService.test.ts +131 -59
  412. package/src/__tests__/providers/pi/durable/PiPrintProtocol.test.ts +66 -28
  413. package/src/__tests__/providers/pi/durable/PiPrintRunner.test.ts +236 -90
  414. package/src/__tests__/providers/pi/durable/PiStreamParser.test.ts +20 -18
  415. package/src/__tests__/readiness/AgentReadiness.test.ts +242 -0
  416. package/src/__tests__/runtime/AgentRuntime.test.ts +8 -0
  417. package/src/__tests__/runtime/HerdrAgentRuntime.test.ts +358 -0
  418. package/src/__tests__/runtime/ManagedAgentRuntime.test.ts +555 -0
  419. package/src/__tests__/terminal/TerminalFocusManager.test.ts +254 -253
  420. package/src/__tests__/terminal/TmuxManager.test.ts +157 -157
  421. package/src/__tests__/terminal/TtyWriter.test.ts +423 -419
  422. package/src/__tests__/utils/AgentRegistry.test.ts +506 -402
  423. package/src/__tests__/utils/ClaudeSessionParser.test.ts +276 -242
  424. package/src/__tests__/utils/agent-requests.test.ts +76 -56
  425. package/src/__tests__/utils/agents.test.ts +20 -20
  426. package/src/__tests__/utils/matching.test.ts +206 -171
  427. package/src/__tests__/utils/process.test.ts +276 -262
  428. package/src/__tests__/utils/session.test.ts +133 -139
  429. package/src/adapters/AgentAdapter.ts +134 -126
  430. package/src/adapters/CopilotAdapter.ts +405 -395
  431. package/src/adapters/GeminiCliAdapter.ts +598 -600
  432. package/src/adapters/GrokCliAdapter.ts +353 -342
  433. package/src/adapters/OpenCodeAdapter.ts +285 -259
  434. package/src/adapters/index.ts +15 -9
  435. package/src/capacity/codex.ts +137 -84
  436. package/src/capacity/index.ts +18 -13
  437. package/src/capacity/types.ts +1 -1
  438. package/src/database/connection.ts +73 -68
  439. package/src/database/index.ts +6 -6
  440. package/src/database/migrations/005_agent_runtime.sql +2 -0
  441. package/src/database/schema.ts +40 -38
  442. package/src/durable/DurableAgent.ts +85 -85
  443. package/src/durable/DurableAgentRepository.ts +409 -260
  444. package/src/durable/process.ts +22 -21
  445. package/src/durable/run.ts +61 -51
  446. package/src/durable/utils.ts +46 -41
  447. package/src/index.ts +145 -86
  448. package/src/providers/claude/ClaudeAgentMapper.ts +51 -50
  449. package/src/providers/claude/ClaudeCodeAdapter.ts +144 -136
  450. package/src/providers/claude/ClaudeSessionLocator.ts +291 -293
  451. package/src/providers/claude/ClaudeSessionParser.ts +322 -338
  452. package/src/providers/claude/durable/ClaudeCliProbe.ts +42 -37
  453. package/src/providers/claude/durable/ClaudePrintAgentService.ts +63 -50
  454. package/src/providers/claude/durable/ClaudePrintRunner.ts +79 -69
  455. package/src/providers/claude/durable/ClaudeStreamParser.ts +91 -62
  456. package/src/providers/codex/CodexAdapter.ts +205 -0
  457. package/src/providers/codex/CodexAgentMapper.ts +35 -0
  458. package/src/providers/codex/CodexSessionLocator.ts +279 -0
  459. package/src/providers/codex/CodexSessionMapping.ts +89 -0
  460. package/src/providers/codex/CodexSessionParser.ts +385 -0
  461. package/src/providers/codex/durable/CodexCliProbe.ts +50 -42
  462. package/src/providers/codex/durable/CodexPrintAgentService.ts +63 -49
  463. package/src/providers/codex/durable/CodexPrintRunner.ts +79 -69
  464. package/src/providers/codex/durable/CodexStreamParser.ts +97 -84
  465. package/src/providers/pi/PiAdapter.ts +183 -0
  466. package/src/providers/pi/PiAgentMapper.ts +36 -0
  467. package/src/providers/pi/PiSessionLocator.ts +95 -0
  468. package/src/providers/pi/PiSessionParser.ts +284 -0
  469. package/src/providers/pi/PiSessionTracker.ts +87 -0
  470. package/src/providers/pi/durable/PiCliProbe.ts +42 -34
  471. package/src/providers/pi/durable/PiPrintAgentService.ts +61 -53
  472. package/src/providers/pi/durable/PiPrintProtocol.ts +31 -29
  473. package/src/providers/pi/durable/PiPrintRunner.ts +75 -68
  474. package/src/providers/pi/durable/PiStreamParser.ts +82 -72
  475. package/src/readiness/AgentReadiness.ts +727 -0
  476. package/src/runtime/ManagedAgentRuntime.ts +266 -0
  477. package/src/runtime/RuntimeFactory.ts +13 -0
  478. package/src/runtime/errors.ts +50 -0
  479. package/src/runtime/herdr/HerdrAgentRuntime.ts +190 -0
  480. package/src/runtime/herdr/HerdrCliClient.ts +78 -0
  481. package/src/runtime/herdr/HerdrErrors.ts +9 -0
  482. package/src/runtime/herdr/HerdrResponseParsers.ts +76 -0
  483. package/src/runtime/herdr/HerdrRuntimeRef.ts +41 -0
  484. package/src/runtime/tmux/PidPolling.ts +34 -0
  485. package/src/runtime/tmux/TmuxAgentRuntime.ts +113 -0
  486. package/src/runtime/tmux/TmuxRuntimeRef.ts +9 -0
  487. package/src/runtime/types.ts +56 -0
  488. package/src/terminal/TerminalFocusManager.ts +215 -212
  489. package/src/terminal/TmuxManager.ts +99 -92
  490. package/src/terminal/TtyWriter.ts +203 -194
  491. package/src/terminal/index.ts +4 -4
  492. package/src/utils/AgentRegistry.ts +299 -238
  493. package/src/utils/agent-requests.ts +16 -16
  494. package/src/utils/agents.ts +41 -38
  495. package/src/utils/applescript.ts +4 -4
  496. package/src/utils/index.ts +12 -6
  497. package/src/utils/matching.ts +43 -43
  498. package/src/utils/process.ts +261 -258
  499. package/src/utils/session.ts +66 -66
  500. package/src/utils/sortAgents.ts +35 -33
  501. package/tsconfig.json +2 -8
  502. package/vitest.config.ts +16 -16
  503. package/.eslintrc.json +0 -31
  504. package/dist/__tests__/adapters/PiAdapter.test.js +0 -618
  505. package/dist/__tests__/adapters/PiAdapter.test.js.map +0 -1
  506. package/dist/__tests__/database/DurableAgentsDatabase.test.js +0 -128
  507. package/dist/__tests__/database/DurableAgentsDatabase.test.js.map +0 -1
  508. package/dist/adapters/CodexAdapter.d.ts +0 -109
  509. package/dist/adapters/CodexAdapter.d.ts.map +0 -1
  510. package/dist/adapters/CodexAdapter.js +0 -710
  511. package/dist/adapters/CodexAdapter.js.map +0 -1
  512. package/dist/adapters/PiAdapter.d.ts +0 -63
  513. package/dist/adapters/PiAdapter.d.ts.map +0 -1
  514. package/dist/adapters/PiAdapter.js +0 -453
  515. package/dist/adapters/PiAdapter.js.map +0 -1
  516. package/src/__tests__/adapters/PiAdapter.test.ts +0 -458
  517. package/src/__tests__/database/DurableAgentsDatabase.test.ts +0 -102
  518. package/src/adapters/CodexAdapter.ts +0 -923
  519. 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
  });