@ai-devkit/agent-manager 0.32.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 +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/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 -43
  171. package/dist/index.d.ts.map +1 -1
  172. package/dist/index.js +27 -26
  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 +6 -6
  279. package/dist/readiness/AgentReadiness.d.ts.map +1 -1
  280. package/dist/readiness/AgentReadiness.js +130 -130
  281. package/dist/readiness/AgentReadiness.js.map +1 -1
  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 +217 -169
  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 +144 -103
  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 +585 -513
  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,182 +1,269 @@
1
- import { describe, expect, it, vi } from 'vitest';
1
+ import { describe, expect, it, vi } from "vitest";
2
2
  import {
3
3
  CODEX_APP_SERVER_ARGS,
4
4
  parseUsage,
5
5
  probeCodexCapacity,
6
6
  resolveCodexAuthPath,
7
- toRateWindow
8
- } from '../../capacity/codex.js';
7
+ toRateWindow,
8
+ } from "../../capacity/codex.js";
9
9
 
10
- const checkedAt = '2026-08-20T10:00:00.000Z';
10
+ const checkedAt = "2026-08-20T10:00:00.000Z";
11
11
  const context = { installed: true, checkedAt };
12
12
 
13
13
  function apiUsage(overrides: Record<string, unknown> = {}) {
14
14
  return {
15
15
  rate_limit: {
16
16
  primary_window: { used_percent: 20, limit_window_seconds: 18_000, reset_at: 1_787_220_000 },
17
- secondary_window: { used_percent: 60, limit_window_seconds: 604_800, reset_at: 1_787_824_800 },
18
- ...overrides
17
+ secondary_window: {
18
+ used_percent: 60,
19
+ limit_window_seconds: 604_800,
20
+ reset_at: 1_787_824_800,
21
+ },
22
+ ...overrides,
19
23
  },
20
24
  credits: { balance: 12.5 },
21
- additional_rate_limits: [{
22
- limit_name: 'reviews',
23
- rate_limit: {
24
- primary_window: { used_percent: 10, limit_window_seconds: 3_600, reset_at: 1_787_220_000 }
25
- }
26
- }]
25
+ additional_rate_limits: [
26
+ {
27
+ limit_name: "reviews",
28
+ rate_limit: {
29
+ primary_window: {
30
+ used_percent: 10,
31
+ limit_window_seconds: 3_600,
32
+ reset_at: 1_787_220_000,
33
+ },
34
+ },
35
+ },
36
+ ],
27
37
  };
28
38
  }
29
39
 
30
- describe('Codex auth resolution', () => {
31
- it('uses CODEX_HOME before HOME', () => {
32
- expect(resolveCodexAuthPath({ CODEX_HOME: '/custom/codex', HOME: '/users/test' })).toBe('/custom/codex/auth.json');
40
+ describe("Codex auth resolution", () => {
41
+ it("uses CODEX_HOME before HOME", () => {
42
+ expect(resolveCodexAuthPath({ CODEX_HOME: "/custom/codex", HOME: "/users/test" })).toBe(
43
+ "/custom/codex/auth.json",
44
+ );
33
45
  });
34
46
 
35
- it('falls back to ~/.codex/auth.json', () => {
36
- expect(resolveCodexAuthPath({ HOME: '/users/test' })).toBe('/users/test/.codex/auth.json');
47
+ it("falls back to ~/.codex/auth.json", () => {
48
+ expect(resolveCodexAuthPath({ HOME: "/users/test" })).toBe("/users/test/.codex/auth.json");
37
49
  });
38
50
  });
39
51
 
40
- describe('Codex API usage mapping', () => {
41
- it('converts an API window without treating missing data as zero', () => {
42
- expect(toRateWindow({ used_percent: 25, limit_window_seconds: 18_000, reset_at: 1_787_220_000 }, 'session', 'Session')).toEqual({
43
- id: 'session', label: 'Session', durationMinutes: 300, usedPercent: 25,
44
- resetsAt: '2026-08-20T10:00:00.000Z'
52
+ describe("Codex API usage mapping", () => {
53
+ it("converts an API window without treating missing data as zero", () => {
54
+ expect(
55
+ toRateWindow(
56
+ { used_percent: 25, limit_window_seconds: 18_000, reset_at: 1_787_220_000 },
57
+ "session",
58
+ "Session",
59
+ ),
60
+ ).toEqual({
61
+ id: "session",
62
+ label: "Session",
63
+ durationMinutes: 300,
64
+ usedPercent: 25,
65
+ resetsAt: "2026-08-20T10:00:00.000Z",
45
66
  });
46
- expect(toRateWindow({}, 'session', 'Session')).toMatchObject({ usedPercent: null });
67
+ expect(toRateWindow({}, "session", "Session")).toMatchObject({ usedPercent: null });
47
68
  });
48
69
 
49
- it('maps session, weekly, credits, and extra limits', () => {
50
- const snapshot = parseUsage(apiUsage(), 'pat');
51
- expect(snapshot).toMatchObject({ source: 'pat', creditsRemaining: 12.5 });
70
+ it("maps session, weekly, credits, and extra limits", () => {
71
+ const snapshot = parseUsage(apiUsage(), "pat");
72
+ expect(snapshot).toMatchObject({ source: "pat", creditsRemaining: 12.5 });
52
73
  expect(snapshot.windows).toEqual([
53
- expect.objectContaining({ id: 'session', durationMinutes: 300 }),
54
- expect.objectContaining({ id: 'weekly', durationMinutes: 10080 }),
55
- expect.objectContaining({ id: 'reviews:primary', durationMinutes: 60 })
74
+ expect.objectContaining({ id: "session", durationMinutes: 300 }),
75
+ expect.objectContaining({ id: "weekly", durationMinutes: 10080 }),
76
+ expect.objectContaining({ id: "reviews:primary", durationMinutes: 60 }),
56
77
  ]);
57
78
  });
58
79
 
59
- it('represents missing limits as unavailable rather than zero', () => {
60
- const snapshot = parseUsage({ credits: {} }, 'oauth');
80
+ it("represents missing limits as unavailable rather than zero", () => {
81
+ const snapshot = parseUsage({ credits: {} }, "oauth");
61
82
  expect(snapshot.windows).toEqual([]);
62
83
  expect(snapshot.creditsRemaining).toBeNull();
63
84
  });
64
85
  });
65
86
 
66
- describe('tiered Codex probing', () => {
67
- it('selects PAT, calls whoami then usage, and never invokes the CLI', async () => {
68
- const fetch = vi.fn()
69
- .mockResolvedValueOnce(new Response(JSON.stringify({ chatgpt_account_id: 'acct-1' }), { status: 200 }))
87
+ describe("tiered Codex probing", () => {
88
+ it("selects PAT, calls whoami then usage, and never invokes the CLI", async () => {
89
+ const fetch = vi
90
+ .fn()
91
+ .mockResolvedValueOnce(
92
+ new Response(JSON.stringify({ chatgpt_account_id: "acct-1" }), { status: 200 }),
93
+ )
70
94
  .mockResolvedValueOnce(new Response(JSON.stringify(apiUsage()), { status: 200 }));
71
95
  const rpc = vi.fn();
72
96
  const result = await probeCodexCapacity({
73
- ...context, readFile: async () => JSON.stringify({
74
- personal_access_token: 'pat-secret',
75
- tokens: { access_token: 'ignored-oauth', account_id: 'ignored-account' }
76
- }), fetch, rpc
97
+ ...context,
98
+ readFile: async () =>
99
+ JSON.stringify({
100
+ personal_access_token: "pat-secret",
101
+ tokens: { access_token: "ignored-oauth", account_id: "ignored-account" },
102
+ }),
103
+ fetch,
104
+ rpc,
77
105
  });
78
106
  expect(fetch).toHaveBeenCalledTimes(2);
79
- expect(fetch.mock.calls[0][0]).toBe('https://auth.openai.com/api/accounts/v1/user-auth-credential/whoami');
80
- expect(fetch.mock.calls[1][0]).toBe('https://chatgpt.com/backend-api/wham/usage');
81
- expect(fetch.mock.calls[1][1].headers).toMatchObject({ Authorization: 'Bearer pat-secret', 'ChatGPT-Account-Id': 'acct-1' });
107
+ expect(fetch.mock.calls[0][0]).toBe(
108
+ "https://auth.openai.com/api/accounts/v1/user-auth-credential/whoami",
109
+ );
110
+ expect(fetch.mock.calls[1][0]).toBe("https://chatgpt.com/backend-api/wham/usage");
111
+ expect(fetch.mock.calls[1][1].headers).toMatchObject({
112
+ Authorization: "Bearer pat-secret",
113
+ "ChatGPT-Account-Id": "acct-1",
114
+ });
82
115
  expect(rpc).not.toHaveBeenCalled();
83
- expect(result).toMatchObject({ provider: 'codex', available: 'yes', creditsRemaining: 12.5, authenticated: true });
84
- expect(result.windows.map(window => window.id)).toEqual(['session', 'weekly', 'reviews:primary']);
116
+ expect(result).toMatchObject({
117
+ provider: "codex",
118
+ available: "yes",
119
+ creditsRemaining: 12.5,
120
+ authenticated: true,
121
+ });
122
+ expect(result.windows.map((window) => window.id)).toEqual([
123
+ "session",
124
+ "weekly",
125
+ "reviews:primary",
126
+ ]);
85
127
  });
86
128
 
87
- it('selects a fresh OAuth token without calling whoami', async () => {
88
- const fetch = vi.fn().mockResolvedValue(new Response(JSON.stringify(apiUsage()), { status: 200 }));
129
+ it("selects a fresh OAuth token without calling whoami", async () => {
130
+ const fetch = vi
131
+ .fn()
132
+ .mockResolvedValue(new Response(JSON.stringify(apiUsage()), { status: 200 }));
89
133
  const result = await probeCodexCapacity({
90
134
  ...context,
91
- readFile: async () => JSON.stringify({ tokens: { access_token: 'oauth-secret', account_id: 'acct-2', expires_at: 1_800_000_000 } }),
135
+ readFile: async () =>
136
+ JSON.stringify({
137
+ tokens: { access_token: "oauth-secret", account_id: "acct-2", expires_at: 1_800_000_000 },
138
+ }),
92
139
  fetch,
93
- now: () => new Date('2026-08-20T10:00:00.000Z')
140
+ now: () => new Date("2026-08-20T10:00:00.000Z"),
94
141
  });
95
142
  expect(fetch).toHaveBeenCalledOnce();
96
- expect(fetch.mock.calls[0][1].headers).toMatchObject({ Authorization: 'Bearer oauth-secret', 'ChatGPT-Account-Id': 'acct-2' });
97
- expect(result.available).toBe('yes');
143
+ expect(fetch.mock.calls[0][1].headers).toMatchObject({
144
+ Authorization: "Bearer oauth-secret",
145
+ "ChatGPT-Account-Id": "acct-2",
146
+ });
147
+ expect(result.available).toBe("yes");
98
148
  });
99
149
 
100
150
  it.each([
101
- ['missing auth file', async () => { throw Object.assign(new Error('missing'), { code: 'ENOENT' }); }],
102
- ['stale OAuth token', async () => JSON.stringify({ tokens: { access_token: 'stale-secret', account_id: 'acct', expires_at: 1 } })],
103
- ['OAuth 401', async () => JSON.stringify({ tokens: { access_token: 'oauth-secret', account_id: 'acct', expires_at: 1_800_000_000 } })]
104
- ])('falls back to the CLI for %s', async (name, readFile) => {
105
- const fetch = vi.fn().mockResolvedValue(new Response('', { status: name === 'OAuth 401' ? 401 : 200 }));
151
+ [
152
+ "missing auth file",
153
+ async () => {
154
+ throw Object.assign(new Error("missing"), { code: "ENOENT" });
155
+ },
156
+ ],
157
+ [
158
+ "stale OAuth token",
159
+ async () =>
160
+ JSON.stringify({
161
+ tokens: { access_token: "stale-secret", account_id: "acct", expires_at: 1 },
162
+ }),
163
+ ],
164
+ [
165
+ "OAuth 401",
166
+ async () =>
167
+ JSON.stringify({
168
+ tokens: { access_token: "oauth-secret", account_id: "acct", expires_at: 1_800_000_000 },
169
+ }),
170
+ ],
171
+ ])("falls back to the CLI for %s", async (name, readFile) => {
172
+ const fetch = vi
173
+ .fn()
174
+ .mockResolvedValue(new Response("", { status: name === "OAuth 401" ? 401 : 200 }));
106
175
  const rpc = vi.fn(async () => ({
107
- rateLimits: { rateLimits: { primary: { usedPercent: 5, windowDurationMins: 300, resetsAt: null } } },
108
- account: { account: { type: 'chatgpt' } }
176
+ rateLimits: {
177
+ rateLimits: { primary: { usedPercent: 5, windowDurationMins: 300, resetsAt: null } },
178
+ },
179
+ account: { account: { type: "chatgpt" } },
109
180
  }));
110
- const result = await probeCodexCapacity({ ...context, readFile, fetch, rpc, now: () => new Date(checkedAt) });
181
+ const result = await probeCodexCapacity({
182
+ ...context,
183
+ readFile,
184
+ fetch,
185
+ rpc,
186
+ now: () => new Date(checkedAt),
187
+ });
111
188
  expect(rpc).toHaveBeenCalledOnce();
112
189
  expect(result.windows).toHaveLength(1);
113
190
  });
114
191
 
115
- it('falls back to CLI if PAT requests fail', async () => {
192
+ it("falls back to CLI if PAT requests fail", async () => {
116
193
  const rpc = vi.fn(async () => ({ rateLimits: {}, account: { account: null } }));
117
194
  const result = await probeCodexCapacity({
118
195
  ...context,
119
- readFile: async () => JSON.stringify({ personal_access_token: 'pat-secret' }),
120
- fetch: vi.fn().mockRejectedValue(new Error('network failure pat-secret')),
121
- rpc
196
+ readFile: async () => JSON.stringify({ personal_access_token: "pat-secret" }),
197
+ fetch: vi.fn().mockRejectedValue(new Error("network failure pat-secret")),
198
+ rpc,
122
199
  });
123
200
  expect(rpc).toHaveBeenCalledOnce();
124
- expect(result.available).toBe('unknown');
201
+ expect(result.available).toBe("unknown");
125
202
  });
126
203
 
127
- it('tries fresh OAuth after a PAT request fails', async () => {
128
- const fetch = vi.fn()
129
- .mockRejectedValueOnce(new Error('PAT failed'))
204
+ it("tries fresh OAuth after a PAT request fails", async () => {
205
+ const fetch = vi
206
+ .fn()
207
+ .mockRejectedValueOnce(new Error("PAT failed"))
130
208
  .mockResolvedValueOnce(new Response(JSON.stringify(apiUsage()), { status: 200 }));
131
209
  const rpc = vi.fn();
132
210
  const result = await probeCodexCapacity({
133
211
  ...context,
134
- readFile: async () => JSON.stringify({
135
- personal_access_token: 'pat-secret',
136
- tokens: { access_token: 'oauth-secret', account_id: 'acct', expires_at: 1_800_000_000 }
137
- }),
212
+ readFile: async () =>
213
+ JSON.stringify({
214
+ personal_access_token: "pat-secret",
215
+ tokens: { access_token: "oauth-secret", account_id: "acct", expires_at: 1_800_000_000 },
216
+ }),
138
217
  fetch,
139
218
  rpc,
140
- now: () => new Date(checkedAt)
219
+ now: () => new Date(checkedAt),
141
220
  });
142
221
  expect(fetch).toHaveBeenCalledTimes(2);
143
- expect(result.available).toBe('yes');
222
+ expect(result.available).toBe("yes");
144
223
  expect(rpc).not.toHaveBeenCalled();
145
224
  });
146
225
 
147
- it('uses hardened read-only app-server arguments and both account methods', async () => {
226
+ it("uses hardened read-only app-server arguments and both account methods", async () => {
148
227
  const rpc = vi.fn(async () => ({
149
- rateLimits: { rateLimits: { primary: { usedPercent: 5, windowDurationMins: 300, resetsAt: null } } },
150
- account: { account: { type: 'chatgpt' } }
228
+ rateLimits: {
229
+ rateLimits: { primary: { usedPercent: 5, windowDurationMins: 300, resetsAt: null } },
230
+ },
231
+ account: { account: { type: "chatgpt" } },
151
232
  }));
152
- await probeCodexCapacity({ ...context, readFile: async () => '{}', rpc });
233
+ await probeCodexCapacity({ ...context, readFile: async () => "{}", rpc });
153
234
  const messages = rpc.mock.calls[0][0];
154
- expect(messages.map(message => message.method)).toEqual([
155
- 'initialize', 'initialized', 'account/rateLimits/read', 'account/read'
235
+ expect(messages.map((message) => message.method)).toEqual([
236
+ "initialize",
237
+ "initialized",
238
+ "account/rateLimits/read",
239
+ "account/read",
156
240
  ]);
157
241
  expect(JSON.stringify(messages)).not.toMatch(/prompt|turn\/start/);
158
- expect(CODEX_APP_SERVER_ARGS).toEqual(['-s', 'read-only', '-a', 'untrusted', 'app-server']);
242
+ expect(CODEX_APP_SERVER_ARGS).toEqual(["-s", "read-only", "-a", "untrusted", "app-server"]);
159
243
  });
160
244
 
161
- it('uses account/read to distinguish logged-out CLI state', async () => {
245
+ it("uses account/read to distinguish logged-out CLI state", async () => {
162
246
  const result = await probeCodexCapacity({
163
247
  ...context,
164
- readFile: async () => '{}',
165
- rpc: async () => ({ rateLimits: {}, account: { account: null } })
248
+ readFile: async () => "{}",
249
+ rpc: async () => ({ rateLimits: {}, account: { account: null } }),
166
250
  });
167
- expect(result).toMatchObject({ authenticated: false, available: 'unknown' });
251
+ expect(result).toMatchObject({ authenticated: false, available: "unknown" });
168
252
  });
169
253
 
170
- it('never exposes tokens or raw auth content through failures', async () => {
171
- const secrets = ['pat-secret-value', 'oauth-secret-value', 'refresh-secret-value'];
254
+ it("never exposes tokens or raw auth content through failures", async () => {
255
+ const secrets = ["pat-secret-value", "oauth-secret-value", "refresh-secret-value"];
172
256
  const result = await probeCodexCapacity({
173
257
  ...context,
174
- readFile: async () => JSON.stringify({
175
- personal_access_token: secrets[0],
176
- tokens: { access_token: secrets[1], refresh_token: secrets[2] }
177
- }),
178
- fetch: vi.fn().mockRejectedValue(new Error(secrets.join(' '))),
179
- rpc: async () => { throw new Error(secrets.join(' ')); }
258
+ readFile: async () =>
259
+ JSON.stringify({
260
+ personal_access_token: secrets[0],
261
+ tokens: { access_token: secrets[1], refresh_token: secrets[2] },
262
+ }),
263
+ fetch: vi.fn().mockRejectedValue(new Error(secrets.join(" "))),
264
+ rpc: async () => {
265
+ throw new Error(secrets.join(" "));
266
+ },
180
267
  });
181
268
  const output = JSON.stringify(result);
182
269
  for (const secret of secrets) expect(output).not.toContain(secret);
@@ -1,38 +1,47 @@
1
- import { describe, expect, it, vi } from 'vitest';
2
- import { getCodexCapacityReport } from '../../capacity/index.js';
1
+ import { describe, expect, it, vi } from "vitest";
2
+ import { getCodexCapacityReport } from "../../capacity/index.js";
3
3
 
4
- const checkedAt = '2026-08-09T10:00:00.000Z';
4
+ const checkedAt = "2026-08-09T10:00:00.000Z";
5
5
 
6
- describe('getCodexCapacityReport', () => {
7
- it('checks Codex installation before probing', async () => {
8
- const probe = vi.fn(async context => ({
9
- provider: 'codex', generatedAt: context.checkedAt,
10
- authenticated: true, available: 'yes' as const, windows: [], creditsRemaining: null
6
+ describe("getCodexCapacityReport", () => {
7
+ it("checks Codex installation before probing", async () => {
8
+ const probe = vi.fn(async (context) => ({
9
+ provider: "codex",
10
+ generatedAt: context.checkedAt,
11
+ authenticated: true,
12
+ available: "yes" as const,
13
+ windows: [],
14
+ creditsRemaining: null,
11
15
  }));
12
16
 
13
17
  const report = await getCodexCapacityReport({
14
18
  now: () => new Date(checkedAt),
15
- path: '/usr/bin:/opt/bin',
16
- access: async target => {
17
- if (target !== '/opt/bin/codex') throw new Error('missing');
19
+ path: "/usr/bin:/opt/bin",
20
+ access: async (target) => {
21
+ if (target !== "/opt/bin/codex") throw new Error("missing");
18
22
  },
19
- probe
23
+ probe,
20
24
  });
21
25
 
22
26
  expect(probe).toHaveBeenCalledWith({ installed: true, checkedAt });
23
- expect(report).toMatchObject({ provider: 'codex', generatedAt: checkedAt, available: 'yes' });
27
+ expect(report).toMatchObject({ provider: "codex", generatedAt: checkedAt, available: "yes" });
24
28
  });
25
29
 
26
- it('redacts unexpected probe failures into a stable unknown result', async () => {
30
+ it("redacts unexpected probe failures into a stable unknown result", async () => {
27
31
  const report = await getCodexCapacityReport({
28
32
  now: () => new Date(checkedAt),
29
- path: '',
30
- probe: async () => { throw new Error('private provider response'); }
33
+ path: "",
34
+ probe: async () => {
35
+ throw new Error("private provider response");
36
+ },
31
37
  });
32
38
 
33
39
  expect(report).toMatchObject({
34
- provider: 'codex', available: 'unknown', authenticated: null, windows: []
40
+ provider: "codex",
41
+ available: "unknown",
42
+ authenticated: null,
43
+ windows: [],
35
44
  });
36
- expect(JSON.stringify(report)).not.toContain('private provider response');
45
+ expect(JSON.stringify(report)).not.toContain("private provider response");
37
46
  });
38
47
  });
@@ -1,63 +1,85 @@
1
- import { describe, expect, it, vi } from 'vitest';
1
+ import { describe, expect, it, vi } from "vitest";
2
2
 
3
- describe('CodexCliProbe', () => {
4
- it('validates version, exec JSON/stdin, and resume capabilities without a model call', async () => {
5
- const api = await import('../../index.js') as Record<string, unknown>;
6
- expect(api).toHaveProperty('CodexCliProbe');
7
- const exec = vi.fn()
8
- .mockResolvedValueOnce({ stdout: 'codex-cli 0.147.0', stderr: '' })
9
- .mockResolvedValueOnce({ stdout: 'Usage: codex exec [PROMPT]\n--json\n- read from stdin\nresume', stderr: '' })
10
- .mockResolvedValueOnce({ stdout: 'Usage: codex exec resume [SESSION_ID] [PROMPT]\n--json\n- stdin', stderr: '' });
11
- const Probe = api.CodexCliProbe as new (options: unknown) => any;
3
+ describe("CodexCliProbe", () => {
4
+ it("validates version, exec JSON/stdin, and resume capabilities without a model call", async () => {
5
+ const api = (await import("../../index.js")) as Record<string, unknown>;
6
+ expect(api).toHaveProperty("CodexCliProbe");
7
+ const exec = vi
8
+ .fn()
9
+ .mockResolvedValueOnce({ stdout: "codex-cli 0.147.0", stderr: "" })
10
+ .mockResolvedValueOnce({
11
+ stdout: "Usage: codex exec [PROMPT]\n--json\n- read from stdin\nresume",
12
+ stderr: "",
13
+ })
14
+ .mockResolvedValueOnce({
15
+ stdout: "Usage: codex exec resume [SESSION_ID] [PROMPT]\n--json\n- stdin",
16
+ stderr: "",
17
+ });
18
+ const Probe = api.CodexCliProbe as new (options: unknown) => any;
12
19
 
13
- await expect(new Probe({ executable: 'fake-codex', exec }).validate()).resolves.toEqual({
14
- executable: 'fake-codex', version: 'codex-cli 0.147.0',
15
- });
16
- expect(exec.mock.calls).toEqual([
17
- ['fake-codex', ['--version']],
18
- ['fake-codex', ['exec', '--help']],
19
- ['fake-codex', ['exec', 'resume', '--help']],
20
- ]);
20
+ await expect(new Probe({ executable: "fake-codex", exec }).validate()).resolves.toEqual({
21
+ executable: "fake-codex",
22
+ version: "codex-cli 0.147.0",
21
23
  });
24
+ expect(exec.mock.calls).toEqual([
25
+ ["fake-codex", ["--version"]],
26
+ ["fake-codex", ["exec", "--help"]],
27
+ ["fake-codex", ["exec", "resume", "--help"]],
28
+ ]);
29
+ });
22
30
 
23
- it('rejects unsupported and unavailable CLIs with bounded sanitized errors', async () => {
24
- const api = await import('../../index.js') as Record<string, unknown>;
25
- const Probe = api.CodexCliProbe as new (options: unknown) => any;
26
- const unsupported = new Probe({ exec: vi.fn()
27
- .mockResolvedValueOnce({ stdout: 'version', stderr: '' })
28
- .mockResolvedValueOnce({ stdout: 'exec', stderr: '' })
29
- .mockResolvedValueOnce({ stdout: 'resume', stderr: '' }) });
30
- await expect(unsupported.validate()).rejects.toMatchObject({ code: 'CODEX_CLI_UNSUPPORTED' });
31
- const missingCommands = new Probe({ exec: vi.fn()
32
- .mockResolvedValueOnce({ stdout: 'version', stderr: '' })
33
- .mockResolvedValueOnce({ stdout: '', stderr: '' })
34
- .mockResolvedValueOnce({ stdout: '', stderr: '' }) });
35
- await expect(missingCommands.validate()).rejects.toMatchObject({ code: 'CODEX_CLI_UNSUPPORTED' });
36
-
37
- const unavailable = new Probe({ exec: vi.fn().mockRejectedValue(new Error(`bad\0${'x'.repeat(1000)}`)) });
38
- const error = await unavailable.validate().catch((value: Error & { code: string }) => value);
39
- expect(error.code).toBe('CODEX_CLI_UNAVAILABLE');
40
- expect(error.message).not.toContain('\0');
41
- expect(error.message.length).toBeLessThan(600);
31
+ it("rejects unsupported and unavailable CLIs with bounded sanitized errors", async () => {
32
+ const api = (await import("../../index.js")) as Record<string, unknown>;
33
+ const Probe = api.CodexCliProbe as new (options: unknown) => any;
34
+ const unsupported = new Probe({
35
+ exec: vi
36
+ .fn()
37
+ .mockResolvedValueOnce({ stdout: "version", stderr: "" })
38
+ .mockResolvedValueOnce({ stdout: "exec", stderr: "" })
39
+ .mockResolvedValueOnce({ stdout: "resume", stderr: "" }),
40
+ });
41
+ await expect(unsupported.validate()).rejects.toMatchObject({ code: "CODEX_CLI_UNSUPPORTED" });
42
+ const missingCommands = new Probe({
43
+ exec: vi
44
+ .fn()
45
+ .mockResolvedValueOnce({ stdout: "version", stderr: "" })
46
+ .mockResolvedValueOnce({ stdout: "", stderr: "" })
47
+ .mockResolvedValueOnce({ stdout: "", stderr: "" }),
48
+ });
49
+ await expect(missingCommands.validate()).rejects.toMatchObject({
50
+ code: "CODEX_CLI_UNSUPPORTED",
42
51
  });
43
52
 
44
- it('reports an empty version response as unknown', async () => {
45
- const api = await import('../../index.js') as Record<string, unknown>;
46
- const Probe = api.CodexCliProbe as new (options: unknown) => any;
47
- const exec = vi.fn()
48
- .mockResolvedValueOnce({ stdout: ' \n', stderr: '' })
49
- .mockResolvedValueOnce({ stdout: 'exec --json -', stderr: '' })
50
- .mockResolvedValueOnce({ stdout: 'resume --json -', stderr: '' });
51
- await expect(new Probe({ exec }).validate()).resolves.toMatchObject({ version: 'unknown' });
53
+ const unavailable = new Probe({
54
+ exec: vi.fn().mockRejectedValue(new Error(`bad\0${"x".repeat(1000)}`)),
52
55
  });
56
+ const error = await unavailable.validate().catch((value: Error & { code: string }) => value);
57
+ expect(error.code).toBe("CODEX_CLI_UNAVAILABLE");
58
+ expect(error.message).not.toContain("\0");
59
+ expect(error.message.length).toBeLessThan(600);
60
+ });
61
+
62
+ it("reports an empty version response as unknown", async () => {
63
+ const api = (await import("../../index.js")) as Record<string, unknown>;
64
+ const Probe = api.CodexCliProbe as new (options: unknown) => any;
65
+ const exec = vi
66
+ .fn()
67
+ .mockResolvedValueOnce({ stdout: " \n", stderr: "" })
68
+ .mockResolvedValueOnce({ stdout: "exec --json -", stderr: "" })
69
+ .mockResolvedValueOnce({ stdout: "resume --json -", stderr: "" });
70
+ await expect(new Probe({ exec }).validate()).resolves.toMatchObject({ version: "unknown" });
71
+ });
53
72
 
54
- it('requires a standalone stdin dash rather than accepting flag hyphens', async () => {
55
- const api = await import('../../index.js') as Record<string, unknown>;
56
- const Probe = api.CodexCliProbe as new (options: unknown) => any;
57
- const exec = vi.fn()
58
- .mockResolvedValueOnce({ stdout: 'version', stderr: '' })
59
- .mockResolvedValueOnce({ stdout: 'exec --json', stderr: '' })
60
- .mockResolvedValueOnce({ stdout: 'resume --json', stderr: '' });
61
- await expect(new Probe({ exec }).validate()).rejects.toMatchObject({ code: 'CODEX_CLI_UNSUPPORTED' });
73
+ it("requires a standalone stdin dash rather than accepting flag hyphens", async () => {
74
+ const api = (await import("../../index.js")) as Record<string, unknown>;
75
+ const Probe = api.CodexCliProbe as new (options: unknown) => any;
76
+ const exec = vi
77
+ .fn()
78
+ .mockResolvedValueOnce({ stdout: "version", stderr: "" })
79
+ .mockResolvedValueOnce({ stdout: "exec --json", stderr: "" })
80
+ .mockResolvedValueOnce({ stdout: "resume --json", stderr: "" });
81
+ await expect(new Probe({ exec }).validate()).rejects.toMatchObject({
82
+ code: "CODEX_CLI_UNSUPPORTED",
62
83
  });
84
+ });
63
85
  });