@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 +1 @@
1
- {"version":3,"sources":["../../../src/__tests__/capacity/codex.test.ts"],"sourcesContent":["import { describe, expect, it, vi } from 'vitest';\nimport {\n CODEX_APP_SERVER_ARGS,\n parseUsage,\n probeCodexCapacity,\n resolveCodexAuthPath,\n toRateWindow\n} from '../../capacity/codex.js';\n\nconst checkedAt = '2026-08-20T10:00:00.000Z';\nconst context = { installed: true, checkedAt };\n\nfunction apiUsage(overrides: Record<string, unknown> = {}) {\n return {\n rate_limit: {\n primary_window: { used_percent: 20, limit_window_seconds: 18_000, reset_at: 1_787_220_000 },\n secondary_window: { used_percent: 60, limit_window_seconds: 604_800, reset_at: 1_787_824_800 },\n ...overrides\n },\n credits: { balance: 12.5 },\n additional_rate_limits: [{\n limit_name: 'reviews',\n rate_limit: {\n primary_window: { used_percent: 10, limit_window_seconds: 3_600, reset_at: 1_787_220_000 }\n }\n }]\n };\n}\n\ndescribe('Codex auth resolution', () => {\n it('uses CODEX_HOME before HOME', () => {\n expect(resolveCodexAuthPath({ CODEX_HOME: '/custom/codex', HOME: '/users/test' })).toBe('/custom/codex/auth.json');\n });\n\n it('falls back to ~/.codex/auth.json', () => {\n expect(resolveCodexAuthPath({ HOME: '/users/test' })).toBe('/users/test/.codex/auth.json');\n });\n});\n\ndescribe('Codex API usage mapping', () => {\n it('converts an API window without treating missing data as zero', () => {\n expect(toRateWindow({ used_percent: 25, limit_window_seconds: 18_000, reset_at: 1_787_220_000 }, 'session', 'Session')).toEqual({\n id: 'session', label: 'Session', durationMinutes: 300, usedPercent: 25,\n resetsAt: '2026-08-20T10:00:00.000Z'\n });\n expect(toRateWindow({}, 'session', 'Session')).toMatchObject({ usedPercent: null });\n });\n\n it('maps session, weekly, credits, and extra limits', () => {\n const snapshot = parseUsage(apiUsage(), 'pat');\n expect(snapshot).toMatchObject({ source: 'pat', creditsRemaining: 12.5 });\n expect(snapshot.windows).toEqual([\n expect.objectContaining({ id: 'session', durationMinutes: 300 }),\n expect.objectContaining({ id: 'weekly', durationMinutes: 10080 }),\n expect.objectContaining({ id: 'reviews:primary', durationMinutes: 60 })\n ]);\n });\n\n it('represents missing limits as unavailable rather than zero', () => {\n const snapshot = parseUsage({ credits: {} }, 'oauth');\n expect(snapshot.windows).toEqual([]);\n expect(snapshot.creditsRemaining).toBeNull();\n });\n});\n\ndescribe('tiered Codex probing', () => {\n it('selects PAT, calls whoami then usage, and never invokes the CLI', async () => {\n const fetch = vi.fn()\n .mockResolvedValueOnce(new Response(JSON.stringify({ chatgpt_account_id: 'acct-1' }), { status: 200 }))\n .mockResolvedValueOnce(new Response(JSON.stringify(apiUsage()), { status: 200 }));\n const rpc = vi.fn();\n const result = await probeCodexCapacity({\n ...context, readFile: async () => JSON.stringify({\n personal_access_token: 'pat-secret',\n tokens: { access_token: 'ignored-oauth', account_id: 'ignored-account' }\n }), fetch, rpc\n });\n expect(fetch).toHaveBeenCalledTimes(2);\n expect(fetch.mock.calls[0][0]).toBe('https://auth.openai.com/api/accounts/v1/user-auth-credential/whoami');\n expect(fetch.mock.calls[1][0]).toBe('https://chatgpt.com/backend-api/wham/usage');\n expect(fetch.mock.calls[1][1].headers).toMatchObject({ Authorization: 'Bearer pat-secret', 'ChatGPT-Account-Id': 'acct-1' });\n expect(rpc).not.toHaveBeenCalled();\n expect(result).toMatchObject({ provider: 'codex', available: 'yes', creditsRemaining: 12.5, authenticated: true });\n expect(result.windows.map(window => window.id)).toEqual(['session', 'weekly', 'reviews:primary']);\n });\n\n it('selects a fresh OAuth token without calling whoami', async () => {\n const fetch = vi.fn().mockResolvedValue(new Response(JSON.stringify(apiUsage()), { status: 200 }));\n const result = await probeCodexCapacity({\n ...context,\n readFile: async () => JSON.stringify({ tokens: { access_token: 'oauth-secret', account_id: 'acct-2', expires_at: 1_800_000_000 } }),\n fetch,\n now: () => new Date('2026-08-20T10:00:00.000Z')\n });\n expect(fetch).toHaveBeenCalledOnce();\n expect(fetch.mock.calls[0][1].headers).toMatchObject({ Authorization: 'Bearer oauth-secret', 'ChatGPT-Account-Id': 'acct-2' });\n expect(result.available).toBe('yes');\n });\n\n it.each([\n ['missing auth file', async () => { throw Object.assign(new Error('missing'), { code: 'ENOENT' }); }],\n ['stale OAuth token', async () => JSON.stringify({ tokens: { access_token: 'stale-secret', account_id: 'acct', expires_at: 1 } })],\n ['OAuth 401', async () => JSON.stringify({ tokens: { access_token: 'oauth-secret', account_id: 'acct', expires_at: 1_800_000_000 } })]\n ])('falls back to the CLI for %s', async (name, readFile) => {\n const fetch = vi.fn().mockResolvedValue(new Response('', { status: name === 'OAuth 401' ? 401 : 200 }));\n const rpc = vi.fn(async () => ({\n rateLimits: { rateLimits: { primary: { usedPercent: 5, windowDurationMins: 300, resetsAt: null } } },\n account: { account: { type: 'chatgpt' } }\n }));\n const result = await probeCodexCapacity({ ...context, readFile, fetch, rpc, now: () => new Date(checkedAt) });\n expect(rpc).toHaveBeenCalledOnce();\n expect(result.windows).toHaveLength(1);\n });\n\n it('falls back to CLI if PAT requests fail', async () => {\n const rpc = vi.fn(async () => ({ rateLimits: {}, account: { account: null } }));\n const result = await probeCodexCapacity({\n ...context,\n readFile: async () => JSON.stringify({ personal_access_token: 'pat-secret' }),\n fetch: vi.fn().mockRejectedValue(new Error('network failure pat-secret')),\n rpc\n });\n expect(rpc).toHaveBeenCalledOnce();\n expect(result.available).toBe('unknown');\n });\n\n it('tries fresh OAuth after a PAT request fails', async () => {\n const fetch = vi.fn()\n .mockRejectedValueOnce(new Error('PAT failed'))\n .mockResolvedValueOnce(new Response(JSON.stringify(apiUsage()), { status: 200 }));\n const rpc = vi.fn();\n const result = await probeCodexCapacity({\n ...context,\n readFile: async () => JSON.stringify({\n personal_access_token: 'pat-secret',\n tokens: { access_token: 'oauth-secret', account_id: 'acct', expires_at: 1_800_000_000 }\n }),\n fetch,\n rpc,\n now: () => new Date(checkedAt)\n });\n expect(fetch).toHaveBeenCalledTimes(2);\n expect(result.available).toBe('yes');\n expect(rpc).not.toHaveBeenCalled();\n });\n\n it('uses hardened read-only app-server arguments and both account methods', async () => {\n const rpc = vi.fn(async () => ({\n rateLimits: { rateLimits: { primary: { usedPercent: 5, windowDurationMins: 300, resetsAt: null } } },\n account: { account: { type: 'chatgpt' } }\n }));\n await probeCodexCapacity({ ...context, readFile: async () => '{}', rpc });\n const messages = rpc.mock.calls[0][0];\n expect(messages.map(message => message.method)).toEqual([\n 'initialize', 'initialized', 'account/rateLimits/read', 'account/read'\n ]);\n expect(JSON.stringify(messages)).not.toMatch(/prompt|turn\\/start/);\n expect(CODEX_APP_SERVER_ARGS).toEqual(['-s', 'read-only', '-a', 'untrusted', 'app-server']);\n });\n\n it('uses account/read to distinguish logged-out CLI state', async () => {\n const result = await probeCodexCapacity({\n ...context,\n readFile: async () => '{}',\n rpc: async () => ({ rateLimits: {}, account: { account: null } })\n });\n expect(result).toMatchObject({ authenticated: false, available: 'unknown' });\n });\n\n it('never exposes tokens or raw auth content through failures', async () => {\n const secrets = ['pat-secret-value', 'oauth-secret-value', 'refresh-secret-value'];\n const result = await probeCodexCapacity({\n ...context,\n readFile: async () => JSON.stringify({\n personal_access_token: secrets[0],\n tokens: { access_token: secrets[1], refresh_token: secrets[2] }\n }),\n fetch: vi.fn().mockRejectedValue(new Error(secrets.join(' '))),\n rpc: async () => { throw new Error(secrets.join(' ')); }\n });\n const output = JSON.stringify(result);\n for (const secret of secrets) expect(output).not.toContain(secret);\n });\n});\n"],"names":["describe","expect","it","vi","CODEX_APP_SERVER_ARGS","parseUsage","probeCodexCapacity","resolveCodexAuthPath","toRateWindow","checkedAt","context","installed","apiUsage","overrides","rate_limit","primary_window","used_percent","limit_window_seconds","reset_at","secondary_window","credits","balance","additional_rate_limits","limit_name","CODEX_HOME","HOME","toBe","toEqual","id","label","durationMinutes","usedPercent","resetsAt","toMatchObject","snapshot","source","creditsRemaining","windows","objectContaining","toBeNull","fetch","fn","mockResolvedValueOnce","Response","JSON","stringify","chatgpt_account_id","status","rpc","result","readFile","personal_access_token","tokens","access_token","account_id","toHaveBeenCalledTimes","mock","calls","headers","Authorization","not","toHaveBeenCalled","provider","available","authenticated","map","window","mockResolvedValue","expires_at","now","Date","toHaveBeenCalledOnce","each","Object","assign","Error","code","name","rateLimits","primary","windowDurationMins","account","type","toHaveLength","mockRejectedValue","mockRejectedValueOnce","messages","message","method","toMatch","secrets","refresh_token","join","output","secret","toContain"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/__tests__/capacity/codex.test.ts"],"sourcesContent":["import { describe, expect, it, vi } from \"vitest\";\nimport {\n CODEX_APP_SERVER_ARGS,\n parseUsage,\n probeCodexCapacity,\n resolveCodexAuthPath,\n toRateWindow,\n} from \"../../capacity/codex.js\";\n\nconst checkedAt = \"2026-08-20T10:00:00.000Z\";\nconst context = { installed: true, checkedAt };\n\nfunction apiUsage(overrides: Record<string, unknown> = {}) {\n return {\n rate_limit: {\n primary_window: { used_percent: 20, limit_window_seconds: 18_000, reset_at: 1_787_220_000 },\n secondary_window: {\n used_percent: 60,\n limit_window_seconds: 604_800,\n reset_at: 1_787_824_800,\n },\n ...overrides,\n },\n credits: { balance: 12.5 },\n additional_rate_limits: [\n {\n limit_name: \"reviews\",\n rate_limit: {\n primary_window: {\n used_percent: 10,\n limit_window_seconds: 3_600,\n reset_at: 1_787_220_000,\n },\n },\n },\n ],\n };\n}\n\ndescribe(\"Codex auth resolution\", () => {\n it(\"uses CODEX_HOME before HOME\", () => {\n expect(resolveCodexAuthPath({ CODEX_HOME: \"/custom/codex\", HOME: \"/users/test\" })).toBe(\n \"/custom/codex/auth.json\",\n );\n });\n\n it(\"falls back to ~/.codex/auth.json\", () => {\n expect(resolveCodexAuthPath({ HOME: \"/users/test\" })).toBe(\"/users/test/.codex/auth.json\");\n });\n});\n\ndescribe(\"Codex API usage mapping\", () => {\n it(\"converts an API window without treating missing data as zero\", () => {\n expect(\n toRateWindow(\n { used_percent: 25, limit_window_seconds: 18_000, reset_at: 1_787_220_000 },\n \"session\",\n \"Session\",\n ),\n ).toEqual({\n id: \"session\",\n label: \"Session\",\n durationMinutes: 300,\n usedPercent: 25,\n resetsAt: \"2026-08-20T10:00:00.000Z\",\n });\n expect(toRateWindow({}, \"session\", \"Session\")).toMatchObject({ usedPercent: null });\n });\n\n it(\"maps session, weekly, credits, and extra limits\", () => {\n const snapshot = parseUsage(apiUsage(), \"pat\");\n expect(snapshot).toMatchObject({ source: \"pat\", creditsRemaining: 12.5 });\n expect(snapshot.windows).toEqual([\n expect.objectContaining({ id: \"session\", durationMinutes: 300 }),\n expect.objectContaining({ id: \"weekly\", durationMinutes: 10080 }),\n expect.objectContaining({ id: \"reviews:primary\", durationMinutes: 60 }),\n ]);\n });\n\n it(\"represents missing limits as unavailable rather than zero\", () => {\n const snapshot = parseUsage({ credits: {} }, \"oauth\");\n expect(snapshot.windows).toEqual([]);\n expect(snapshot.creditsRemaining).toBeNull();\n });\n});\n\ndescribe(\"tiered Codex probing\", () => {\n it(\"selects PAT, calls whoami then usage, and never invokes the CLI\", async () => {\n const fetch = vi\n .fn()\n .mockResolvedValueOnce(\n new Response(JSON.stringify({ chatgpt_account_id: \"acct-1\" }), { status: 200 }),\n )\n .mockResolvedValueOnce(new Response(JSON.stringify(apiUsage()), { status: 200 }));\n const rpc = vi.fn();\n const result = await probeCodexCapacity({\n ...context,\n readFile: async () =>\n JSON.stringify({\n personal_access_token: \"pat-secret\",\n tokens: { access_token: \"ignored-oauth\", account_id: \"ignored-account\" },\n }),\n fetch,\n rpc,\n });\n expect(fetch).toHaveBeenCalledTimes(2);\n expect(fetch.mock.calls[0][0]).toBe(\n \"https://auth.openai.com/api/accounts/v1/user-auth-credential/whoami\",\n );\n expect(fetch.mock.calls[1][0]).toBe(\"https://chatgpt.com/backend-api/wham/usage\");\n expect(fetch.mock.calls[1][1].headers).toMatchObject({\n Authorization: \"Bearer pat-secret\",\n \"ChatGPT-Account-Id\": \"acct-1\",\n });\n expect(rpc).not.toHaveBeenCalled();\n expect(result).toMatchObject({\n provider: \"codex\",\n available: \"yes\",\n creditsRemaining: 12.5,\n authenticated: true,\n });\n expect(result.windows.map((window) => window.id)).toEqual([\n \"session\",\n \"weekly\",\n \"reviews:primary\",\n ]);\n });\n\n it(\"selects a fresh OAuth token without calling whoami\", async () => {\n const fetch = vi\n .fn()\n .mockResolvedValue(new Response(JSON.stringify(apiUsage()), { status: 200 }));\n const result = await probeCodexCapacity({\n ...context,\n readFile: async () =>\n JSON.stringify({\n tokens: { access_token: \"oauth-secret\", account_id: \"acct-2\", expires_at: 1_800_000_000 },\n }),\n fetch,\n now: () => new Date(\"2026-08-20T10:00:00.000Z\"),\n });\n expect(fetch).toHaveBeenCalledOnce();\n expect(fetch.mock.calls[0][1].headers).toMatchObject({\n Authorization: \"Bearer oauth-secret\",\n \"ChatGPT-Account-Id\": \"acct-2\",\n });\n expect(result.available).toBe(\"yes\");\n });\n\n it.each([\n [\n \"missing auth file\",\n async () => {\n throw Object.assign(new Error(\"missing\"), { code: \"ENOENT\" });\n },\n ],\n [\n \"stale OAuth token\",\n async () =>\n JSON.stringify({\n tokens: { access_token: \"stale-secret\", account_id: \"acct\", expires_at: 1 },\n }),\n ],\n [\n \"OAuth 401\",\n async () =>\n JSON.stringify({\n tokens: { access_token: \"oauth-secret\", account_id: \"acct\", expires_at: 1_800_000_000 },\n }),\n ],\n ])(\"falls back to the CLI for %s\", async (name, readFile) => {\n const fetch = vi\n .fn()\n .mockResolvedValue(new Response(\"\", { status: name === \"OAuth 401\" ? 401 : 200 }));\n const rpc = vi.fn(async () => ({\n rateLimits: {\n rateLimits: { primary: { usedPercent: 5, windowDurationMins: 300, resetsAt: null } },\n },\n account: { account: { type: \"chatgpt\" } },\n }));\n const result = await probeCodexCapacity({\n ...context,\n readFile,\n fetch,\n rpc,\n now: () => new Date(checkedAt),\n });\n expect(rpc).toHaveBeenCalledOnce();\n expect(result.windows).toHaveLength(1);\n });\n\n it(\"falls back to CLI if PAT requests fail\", async () => {\n const rpc = vi.fn(async () => ({ rateLimits: {}, account: { account: null } }));\n const result = await probeCodexCapacity({\n ...context,\n readFile: async () => JSON.stringify({ personal_access_token: \"pat-secret\" }),\n fetch: vi.fn().mockRejectedValue(new Error(\"network failure pat-secret\")),\n rpc,\n });\n expect(rpc).toHaveBeenCalledOnce();\n expect(result.available).toBe(\"unknown\");\n });\n\n it(\"tries fresh OAuth after a PAT request fails\", async () => {\n const fetch = vi\n .fn()\n .mockRejectedValueOnce(new Error(\"PAT failed\"))\n .mockResolvedValueOnce(new Response(JSON.stringify(apiUsage()), { status: 200 }));\n const rpc = vi.fn();\n const result = await probeCodexCapacity({\n ...context,\n readFile: async () =>\n JSON.stringify({\n personal_access_token: \"pat-secret\",\n tokens: { access_token: \"oauth-secret\", account_id: \"acct\", expires_at: 1_800_000_000 },\n }),\n fetch,\n rpc,\n now: () => new Date(checkedAt),\n });\n expect(fetch).toHaveBeenCalledTimes(2);\n expect(result.available).toBe(\"yes\");\n expect(rpc).not.toHaveBeenCalled();\n });\n\n it(\"uses hardened read-only app-server arguments and both account methods\", async () => {\n const rpc = vi.fn(async () => ({\n rateLimits: {\n rateLimits: { primary: { usedPercent: 5, windowDurationMins: 300, resetsAt: null } },\n },\n account: { account: { type: \"chatgpt\" } },\n }));\n await probeCodexCapacity({ ...context, readFile: async () => \"{}\", rpc });\n const messages = rpc.mock.calls[0][0];\n expect(messages.map((message) => message.method)).toEqual([\n \"initialize\",\n \"initialized\",\n \"account/rateLimits/read\",\n \"account/read\",\n ]);\n expect(JSON.stringify(messages)).not.toMatch(/prompt|turn\\/start/);\n expect(CODEX_APP_SERVER_ARGS).toEqual([\"-s\", \"read-only\", \"-a\", \"untrusted\", \"app-server\"]);\n });\n\n it(\"uses account/read to distinguish logged-out CLI state\", async () => {\n const result = await probeCodexCapacity({\n ...context,\n readFile: async () => \"{}\",\n rpc: async () => ({ rateLimits: {}, account: { account: null } }),\n });\n expect(result).toMatchObject({ authenticated: false, available: \"unknown\" });\n });\n\n it(\"never exposes tokens or raw auth content through failures\", async () => {\n const secrets = [\"pat-secret-value\", \"oauth-secret-value\", \"refresh-secret-value\"];\n const result = await probeCodexCapacity({\n ...context,\n readFile: async () =>\n JSON.stringify({\n personal_access_token: secrets[0],\n tokens: { access_token: secrets[1], refresh_token: secrets[2] },\n }),\n fetch: vi.fn().mockRejectedValue(new Error(secrets.join(\" \"))),\n rpc: async () => {\n throw new Error(secrets.join(\" \"));\n },\n });\n const output = JSON.stringify(result);\n for (const secret of secrets) expect(output).not.toContain(secret);\n });\n});\n"],"names":["describe","expect","it","vi","CODEX_APP_SERVER_ARGS","parseUsage","probeCodexCapacity","resolveCodexAuthPath","toRateWindow","checkedAt","context","installed","apiUsage","overrides","rate_limit","primary_window","used_percent","limit_window_seconds","reset_at","secondary_window","credits","balance","additional_rate_limits","limit_name","CODEX_HOME","HOME","toBe","toEqual","id","label","durationMinutes","usedPercent","resetsAt","toMatchObject","snapshot","source","creditsRemaining","windows","objectContaining","toBeNull","fetch","fn","mockResolvedValueOnce","Response","JSON","stringify","chatgpt_account_id","status","rpc","result","readFile","personal_access_token","tokens","access_token","account_id","toHaveBeenCalledTimes","mock","calls","headers","Authorization","not","toHaveBeenCalled","provider","available","authenticated","map","window","mockResolvedValue","expires_at","now","Date","toHaveBeenCalledOnce","each","Object","assign","Error","code","name","rateLimits","primary","windowDurationMins","account","type","toHaveLength","mockRejectedValue","mockRejectedValueOnce","messages","message","method","toMatch","secrets","refresh_token","join","output","secret","toContain"],"mappings":"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"}
@@ -1,21 +1,21 @@
1
- import { describe, expect, it, vi } from 'vitest';
2
- import { getCodexCapacityReport } from '../../capacity/index.js';
3
- const checkedAt = '2026-08-09T10:00:00.000Z';
4
- describe('getCodexCapacityReport', ()=>{
5
- it('checks Codex installation before probing', async ()=>{
1
+ import { describe, expect, it, vi } from "vitest";
2
+ import { getCodexCapacityReport } from "../../capacity/index.js";
3
+ const checkedAt = "2026-08-09T10:00:00.000Z";
4
+ describe("getCodexCapacityReport", ()=>{
5
+ it("checks Codex installation before probing", async ()=>{
6
6
  const probe = vi.fn(async (context)=>({
7
- provider: 'codex',
7
+ provider: "codex",
8
8
  generatedAt: context.checkedAt,
9
9
  authenticated: true,
10
- available: 'yes',
10
+ available: "yes",
11
11
  windows: [],
12
12
  creditsRemaining: null
13
13
  }));
14
14
  const report = await getCodexCapacityReport({
15
15
  now: ()=>new Date(checkedAt),
16
- path: '/usr/bin:/opt/bin',
16
+ path: "/usr/bin:/opt/bin",
17
17
  access: async (target)=>{
18
- if (target !== '/opt/bin/codex') throw new Error('missing');
18
+ if (target !== "/opt/bin/codex") throw new Error("missing");
19
19
  },
20
20
  probe
21
21
  });
@@ -24,26 +24,26 @@ describe('getCodexCapacityReport', ()=>{
24
24
  checkedAt
25
25
  });
26
26
  expect(report).toMatchObject({
27
- provider: 'codex',
27
+ provider: "codex",
28
28
  generatedAt: checkedAt,
29
- available: 'yes'
29
+ available: "yes"
30
30
  });
31
31
  });
32
- it('redacts unexpected probe failures into a stable unknown result', async ()=>{
32
+ it("redacts unexpected probe failures into a stable unknown result", async ()=>{
33
33
  const report = await getCodexCapacityReport({
34
34
  now: ()=>new Date(checkedAt),
35
- path: '',
35
+ path: "",
36
36
  probe: async ()=>{
37
- throw new Error('private provider response');
37
+ throw new Error("private provider response");
38
38
  }
39
39
  });
40
40
  expect(report).toMatchObject({
41
- provider: 'codex',
42
- available: 'unknown',
41
+ provider: "codex",
42
+ available: "unknown",
43
43
  authenticated: null,
44
44
  windows: []
45
45
  });
46
- expect(JSON.stringify(report)).not.toContain('private provider response');
46
+ expect(JSON.stringify(report)).not.toContain("private provider response");
47
47
  });
48
48
  });
49
49
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/__tests__/capacity/index.test.ts"],"sourcesContent":["import { describe, expect, it, vi } from 'vitest';\nimport { getCodexCapacityReport } from '../../capacity/index.js';\n\nconst checkedAt = '2026-08-09T10:00:00.000Z';\n\ndescribe('getCodexCapacityReport', () => {\n it('checks Codex installation before probing', async () => {\n const probe = vi.fn(async context => ({\n provider: 'codex', generatedAt: context.checkedAt,\n authenticated: true, available: 'yes' as const, windows: [], creditsRemaining: null\n }));\n\n const report = await getCodexCapacityReport({\n now: () => new Date(checkedAt),\n path: '/usr/bin:/opt/bin',\n access: async target => {\n if (target !== '/opt/bin/codex') throw new Error('missing');\n },\n probe\n });\n\n expect(probe).toHaveBeenCalledWith({ installed: true, checkedAt });\n expect(report).toMatchObject({ provider: 'codex', generatedAt: checkedAt, available: 'yes' });\n });\n\n it('redacts unexpected probe failures into a stable unknown result', async () => {\n const report = await getCodexCapacityReport({\n now: () => new Date(checkedAt),\n path: '',\n probe: async () => { throw new Error('private provider response'); }\n });\n\n expect(report).toMatchObject({\n provider: 'codex', available: 'unknown', authenticated: null, windows: []\n });\n expect(JSON.stringify(report)).not.toContain('private provider response');\n });\n});\n"],"names":["describe","expect","it","vi","getCodexCapacityReport","checkedAt","probe","fn","context","provider","generatedAt","authenticated","available","windows","creditsRemaining","report","now","Date","path","access","target","Error","toHaveBeenCalledWith","installed","toMatchObject","JSON","stringify","not","toContain"],"mappings":"AAAA,SAASA,QAAQ,EAAEC,MAAM,EAAEC,EAAE,EAAEC,EAAE,QAAQ,SAAS;AAClD,SAASC,sBAAsB,QAAQ,0BAA0B;AAEjE,MAAMC,YAAY;AAElBL,SAAS,0BAA0B;IACjCE,GAAG,4CAA4C;QAC7C,MAAMI,QAAQH,GAAGI,EAAE,CAAC,OAAMC,UAAY,CAAA;gBACpCC,UAAU;gBAASC,aAAaF,QAAQH,SAAS;gBACjDM,eAAe;gBAAMC,WAAW;gBAAgBC,SAAS,EAAE;gBAAEC,kBAAkB;YACjF,CAAA;QAEA,MAAMC,SAAS,MAAMX,uBAAuB;YAC1CY,KAAK,IAAM,IAAIC,KAAKZ;YACpBa,MAAM;YACNC,QAAQ,OAAMC;gBACZ,IAAIA,WAAW,kBAAkB,MAAM,IAAIC,MAAM;YACnD;YACAf;QACF;QAEAL,OAAOK,OAAOgB,oBAAoB,CAAC;YAAEC,WAAW;YAAMlB;QAAU;QAChEJ,OAAOc,QAAQS,aAAa,CAAC;YAAEf,UAAU;YAASC,aAAaL;YAAWO,WAAW;QAAM;IAC7F;IAEAV,GAAG,kEAAkE;QACnE,MAAMa,SAAS,MAAMX,uBAAuB;YAC1CY,KAAK,IAAM,IAAIC,KAAKZ;YACpBa,MAAM;YACNZ,OAAO;gBAAc,MAAM,IAAIe,MAAM;YAA8B;QACrE;QAEApB,OAAOc,QAAQS,aAAa,CAAC;YAC3Bf,UAAU;YAASG,WAAW;YAAWD,eAAe;YAAME,SAAS,EAAE;QAC3E;QACAZ,OAAOwB,KAAKC,SAAS,CAACX,SAASY,GAAG,CAACC,SAAS,CAAC;IAC/C;AACF"}
1
+ {"version":3,"sources":["../../../src/__tests__/capacity/index.test.ts"],"sourcesContent":["import { describe, expect, it, vi } from \"vitest\";\nimport { getCodexCapacityReport } from \"../../capacity/index.js\";\n\nconst checkedAt = \"2026-08-09T10:00:00.000Z\";\n\ndescribe(\"getCodexCapacityReport\", () => {\n it(\"checks Codex installation before probing\", async () => {\n const probe = vi.fn(async (context) => ({\n provider: \"codex\",\n generatedAt: context.checkedAt,\n authenticated: true,\n available: \"yes\" as const,\n windows: [],\n creditsRemaining: null,\n }));\n\n const report = await getCodexCapacityReport({\n now: () => new Date(checkedAt),\n path: \"/usr/bin:/opt/bin\",\n access: async (target) => {\n if (target !== \"/opt/bin/codex\") throw new Error(\"missing\");\n },\n probe,\n });\n\n expect(probe).toHaveBeenCalledWith({ installed: true, checkedAt });\n expect(report).toMatchObject({ provider: \"codex\", generatedAt: checkedAt, available: \"yes\" });\n });\n\n it(\"redacts unexpected probe failures into a stable unknown result\", async () => {\n const report = await getCodexCapacityReport({\n now: () => new Date(checkedAt),\n path: \"\",\n probe: async () => {\n throw new Error(\"private provider response\");\n },\n });\n\n expect(report).toMatchObject({\n provider: \"codex\",\n available: \"unknown\",\n authenticated: null,\n windows: [],\n });\n expect(JSON.stringify(report)).not.toContain(\"private provider response\");\n });\n});\n"],"names":["describe","expect","it","vi","getCodexCapacityReport","checkedAt","probe","fn","context","provider","generatedAt","authenticated","available","windows","creditsRemaining","report","now","Date","path","access","target","Error","toHaveBeenCalledWith","installed","toMatchObject","JSON","stringify","not","toContain"],"mappings":"AAAA,SAASA,QAAQ,EAAEC,MAAM,EAAEC,EAAE,EAAEC,EAAE,QAAQ,SAAS;AAClD,SAASC,sBAAsB,QAAQ,0BAA0B;AAEjE,MAAMC,YAAY;AAElBL,SAAS,0BAA0B;IACjCE,GAAG,4CAA4C;QAC7C,MAAMI,QAAQH,GAAGI,EAAE,CAAC,OAAOC,UAAa,CAAA;gBACtCC,UAAU;gBACVC,aAAaF,QAAQH,SAAS;gBAC9BM,eAAe;gBACfC,WAAW;gBACXC,SAAS,EAAE;gBACXC,kBAAkB;YACpB,CAAA;QAEA,MAAMC,SAAS,MAAMX,uBAAuB;YAC1CY,KAAK,IAAM,IAAIC,KAAKZ;YACpBa,MAAM;YACNC,QAAQ,OAAOC;gBACb,IAAIA,WAAW,kBAAkB,MAAM,IAAIC,MAAM;YACnD;YACAf;QACF;QAEAL,OAAOK,OAAOgB,oBAAoB,CAAC;YAAEC,WAAW;YAAMlB;QAAU;QAChEJ,OAAOc,QAAQS,aAAa,CAAC;YAAEf,UAAU;YAASC,aAAaL;YAAWO,WAAW;QAAM;IAC7F;IAEAV,GAAG,kEAAkE;QACnE,MAAMa,SAAS,MAAMX,uBAAuB;YAC1CY,KAAK,IAAM,IAAIC,KAAKZ;YACpBa,MAAM;YACNZ,OAAO;gBACL,MAAM,IAAIe,MAAM;YAClB;QACF;QAEApB,OAAOc,QAAQS,aAAa,CAAC;YAC3Bf,UAAU;YACVG,WAAW;YACXD,eAAe;YACfE,SAAS,EAAE;QACb;QACAZ,OAAOwB,KAAKC,SAAS,CAACX,SAASY,GAAG,CAACC,SAAS,CAAC;IAC/C;AACF"}
@@ -1,127 +1,127 @@
1
- import { describe, expect, it, vi } from 'vitest';
2
- describe('CodexCliProbe', ()=>{
3
- it('validates version, exec JSON/stdin, and resume capabilities without a model call', async ()=>{
4
- const api = await import('../../index.js');
5
- expect(api).toHaveProperty('CodexCliProbe');
1
+ import { describe, expect, it, vi } from "vitest";
2
+ describe("CodexCliProbe", ()=>{
3
+ it("validates version, exec JSON/stdin, and resume capabilities without a model call", async ()=>{
4
+ const api = await import("../../index.js");
5
+ expect(api).toHaveProperty("CodexCliProbe");
6
6
  const exec = vi.fn().mockResolvedValueOnce({
7
- stdout: 'codex-cli 0.147.0',
8
- stderr: ''
7
+ stdout: "codex-cli 0.147.0",
8
+ stderr: ""
9
9
  }).mockResolvedValueOnce({
10
- stdout: 'Usage: codex exec [PROMPT]\n--json\n- read from stdin\nresume',
11
- stderr: ''
10
+ stdout: "Usage: codex exec [PROMPT]\n--json\n- read from stdin\nresume",
11
+ stderr: ""
12
12
  }).mockResolvedValueOnce({
13
- stdout: 'Usage: codex exec resume [SESSION_ID] [PROMPT]\n--json\n- stdin',
14
- stderr: ''
13
+ stdout: "Usage: codex exec resume [SESSION_ID] [PROMPT]\n--json\n- stdin",
14
+ stderr: ""
15
15
  });
16
16
  const Probe = api.CodexCliProbe;
17
17
  await expect(new Probe({
18
- executable: 'fake-codex',
18
+ executable: "fake-codex",
19
19
  exec
20
20
  }).validate()).resolves.toEqual({
21
- executable: 'fake-codex',
22
- version: 'codex-cli 0.147.0'
21
+ executable: "fake-codex",
22
+ version: "codex-cli 0.147.0"
23
23
  });
24
24
  expect(exec.mock.calls).toEqual([
25
25
  [
26
- 'fake-codex',
26
+ "fake-codex",
27
27
  [
28
- '--version'
28
+ "--version"
29
29
  ]
30
30
  ],
31
31
  [
32
- 'fake-codex',
32
+ "fake-codex",
33
33
  [
34
- 'exec',
35
- '--help'
34
+ "exec",
35
+ "--help"
36
36
  ]
37
37
  ],
38
38
  [
39
- 'fake-codex',
39
+ "fake-codex",
40
40
  [
41
- 'exec',
42
- 'resume',
43
- '--help'
41
+ "exec",
42
+ "resume",
43
+ "--help"
44
44
  ]
45
45
  ]
46
46
  ]);
47
47
  });
48
- it('rejects unsupported and unavailable CLIs with bounded sanitized errors', async ()=>{
49
- const api = await import('../../index.js');
48
+ it("rejects unsupported and unavailable CLIs with bounded sanitized errors", async ()=>{
49
+ const api = await import("../../index.js");
50
50
  const Probe = api.CodexCliProbe;
51
51
  const unsupported = new Probe({
52
52
  exec: vi.fn().mockResolvedValueOnce({
53
- stdout: 'version',
54
- stderr: ''
53
+ stdout: "version",
54
+ stderr: ""
55
55
  }).mockResolvedValueOnce({
56
- stdout: 'exec',
57
- stderr: ''
56
+ stdout: "exec",
57
+ stderr: ""
58
58
  }).mockResolvedValueOnce({
59
- stdout: 'resume',
60
- stderr: ''
59
+ stdout: "resume",
60
+ stderr: ""
61
61
  })
62
62
  });
63
63
  await expect(unsupported.validate()).rejects.toMatchObject({
64
- code: 'CODEX_CLI_UNSUPPORTED'
64
+ code: "CODEX_CLI_UNSUPPORTED"
65
65
  });
66
66
  const missingCommands = new Probe({
67
67
  exec: vi.fn().mockResolvedValueOnce({
68
- stdout: 'version',
69
- stderr: ''
68
+ stdout: "version",
69
+ stderr: ""
70
70
  }).mockResolvedValueOnce({
71
- stdout: '',
72
- stderr: ''
71
+ stdout: "",
72
+ stderr: ""
73
73
  }).mockResolvedValueOnce({
74
- stdout: '',
75
- stderr: ''
74
+ stdout: "",
75
+ stderr: ""
76
76
  })
77
77
  });
78
78
  await expect(missingCommands.validate()).rejects.toMatchObject({
79
- code: 'CODEX_CLI_UNSUPPORTED'
79
+ code: "CODEX_CLI_UNSUPPORTED"
80
80
  });
81
81
  const unavailable = new Probe({
82
- exec: vi.fn().mockRejectedValue(new Error(`bad\0${'x'.repeat(1000)}`))
82
+ exec: vi.fn().mockRejectedValue(new Error(`bad\0${"x".repeat(1000)}`))
83
83
  });
84
84
  const error = await unavailable.validate().catch((value)=>value);
85
- expect(error.code).toBe('CODEX_CLI_UNAVAILABLE');
86
- expect(error.message).not.toContain('\0');
85
+ expect(error.code).toBe("CODEX_CLI_UNAVAILABLE");
86
+ expect(error.message).not.toContain("\0");
87
87
  expect(error.message.length).toBeLessThan(600);
88
88
  });
89
- it('reports an empty version response as unknown', async ()=>{
90
- const api = await import('../../index.js');
89
+ it("reports an empty version response as unknown", async ()=>{
90
+ const api = await import("../../index.js");
91
91
  const Probe = api.CodexCliProbe;
92
92
  const exec = vi.fn().mockResolvedValueOnce({
93
- stdout: ' \n',
94
- stderr: ''
93
+ stdout: " \n",
94
+ stderr: ""
95
95
  }).mockResolvedValueOnce({
96
- stdout: 'exec --json -',
97
- stderr: ''
96
+ stdout: "exec --json -",
97
+ stderr: ""
98
98
  }).mockResolvedValueOnce({
99
- stdout: 'resume --json -',
100
- stderr: ''
99
+ stdout: "resume --json -",
100
+ stderr: ""
101
101
  });
102
102
  await expect(new Probe({
103
103
  exec
104
104
  }).validate()).resolves.toMatchObject({
105
- version: 'unknown'
105
+ version: "unknown"
106
106
  });
107
107
  });
108
- it('requires a standalone stdin dash rather than accepting flag hyphens', async ()=>{
109
- const api = await import('../../index.js');
108
+ it("requires a standalone stdin dash rather than accepting flag hyphens", async ()=>{
109
+ const api = await import("../../index.js");
110
110
  const Probe = api.CodexCliProbe;
111
111
  const exec = vi.fn().mockResolvedValueOnce({
112
- stdout: 'version',
113
- stderr: ''
112
+ stdout: "version",
113
+ stderr: ""
114
114
  }).mockResolvedValueOnce({
115
- stdout: 'exec --json',
116
- stderr: ''
115
+ stdout: "exec --json",
116
+ stderr: ""
117
117
  }).mockResolvedValueOnce({
118
- stdout: 'resume --json',
119
- stderr: ''
118
+ stdout: "resume --json",
119
+ stderr: ""
120
120
  });
121
121
  await expect(new Probe({
122
122
  exec
123
123
  }).validate()).rejects.toMatchObject({
124
- code: 'CODEX_CLI_UNSUPPORTED'
124
+ code: "CODEX_CLI_UNSUPPORTED"
125
125
  });
126
126
  });
127
127
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/__tests__/durable/CodexCliProbe.test.ts"],"sourcesContent":["import { describe, expect, it, vi } from 'vitest';\n\ndescribe('CodexCliProbe', () => {\n it('validates version, exec JSON/stdin, and resume capabilities without a model call', async () => {\n const api = await import('../../index.js') as Record<string, unknown>;\n expect(api).toHaveProperty('CodexCliProbe');\n const exec = vi.fn()\n .mockResolvedValueOnce({ stdout: 'codex-cli 0.147.0', stderr: '' })\n .mockResolvedValueOnce({ stdout: 'Usage: codex exec [PROMPT]\\n--json\\n- read from stdin\\nresume', stderr: '' })\n .mockResolvedValueOnce({ stdout: 'Usage: codex exec resume [SESSION_ID] [PROMPT]\\n--json\\n- stdin', stderr: '' });\n const Probe = api.CodexCliProbe as new (options: unknown) => any;\n\n await expect(new Probe({ executable: 'fake-codex', exec }).validate()).resolves.toEqual({\n executable: 'fake-codex', version: 'codex-cli 0.147.0',\n });\n expect(exec.mock.calls).toEqual([\n ['fake-codex', ['--version']],\n ['fake-codex', ['exec', '--help']],\n ['fake-codex', ['exec', 'resume', '--help']],\n ]);\n });\n\n it('rejects unsupported and unavailable CLIs with bounded sanitized errors', async () => {\n const api = await import('../../index.js') as Record<string, unknown>;\n const Probe = api.CodexCliProbe as new (options: unknown) => any;\n const unsupported = new Probe({ exec: vi.fn()\n .mockResolvedValueOnce({ stdout: 'version', stderr: '' })\n .mockResolvedValueOnce({ stdout: 'exec', stderr: '' })\n .mockResolvedValueOnce({ stdout: 'resume', stderr: '' }) });\n await expect(unsupported.validate()).rejects.toMatchObject({ code: 'CODEX_CLI_UNSUPPORTED' });\n const missingCommands = new Probe({ exec: vi.fn()\n .mockResolvedValueOnce({ stdout: 'version', stderr: '' })\n .mockResolvedValueOnce({ stdout: '', stderr: '' })\n .mockResolvedValueOnce({ stdout: '', stderr: '' }) });\n await expect(missingCommands.validate()).rejects.toMatchObject({ code: 'CODEX_CLI_UNSUPPORTED' });\n\n const unavailable = new Probe({ exec: vi.fn().mockRejectedValue(new Error(`bad\\0${'x'.repeat(1000)}`)) });\n const error = await unavailable.validate().catch((value: Error & { code: string }) => value);\n expect(error.code).toBe('CODEX_CLI_UNAVAILABLE');\n expect(error.message).not.toContain('\\0');\n expect(error.message.length).toBeLessThan(600);\n });\n\n it('reports an empty version response as unknown', async () => {\n const api = await import('../../index.js') as Record<string, unknown>;\n const Probe = api.CodexCliProbe as new (options: unknown) => any;\n const exec = vi.fn()\n .mockResolvedValueOnce({ stdout: ' \\n', stderr: '' })\n .mockResolvedValueOnce({ stdout: 'exec --json -', stderr: '' })\n .mockResolvedValueOnce({ stdout: 'resume --json -', stderr: '' });\n await expect(new Probe({ exec }).validate()).resolves.toMatchObject({ version: 'unknown' });\n });\n\n it('requires a standalone stdin dash rather than accepting flag hyphens', async () => {\n const api = await import('../../index.js') as Record<string, unknown>;\n const Probe = api.CodexCliProbe as new (options: unknown) => any;\n const exec = vi.fn()\n .mockResolvedValueOnce({ stdout: 'version', stderr: '' })\n .mockResolvedValueOnce({ stdout: 'exec --json', stderr: '' })\n .mockResolvedValueOnce({ stdout: 'resume --json', stderr: '' });\n await expect(new Probe({ exec }).validate()).rejects.toMatchObject({ code: 'CODEX_CLI_UNSUPPORTED' });\n });\n});\n"],"names":["describe","expect","it","vi","api","toHaveProperty","exec","fn","mockResolvedValueOnce","stdout","stderr","Probe","CodexCliProbe","executable","validate","resolves","toEqual","version","mock","calls","unsupported","rejects","toMatchObject","code","missingCommands","unavailable","mockRejectedValue","Error","repeat","error","catch","value","toBe","message","not","toContain","length","toBeLessThan"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/__tests__/durable/CodexCliProbe.test.ts"],"sourcesContent":["import { describe, expect, it, vi } from \"vitest\";\n\ndescribe(\"CodexCliProbe\", () => {\n it(\"validates version, exec JSON/stdin, and resume capabilities without a model call\", async () => {\n const api = (await import(\"../../index.js\")) as Record<string, unknown>;\n expect(api).toHaveProperty(\"CodexCliProbe\");\n const exec = vi\n .fn()\n .mockResolvedValueOnce({ stdout: \"codex-cli 0.147.0\", stderr: \"\" })\n .mockResolvedValueOnce({\n stdout: \"Usage: codex exec [PROMPT]\\n--json\\n- read from stdin\\nresume\",\n stderr: \"\",\n })\n .mockResolvedValueOnce({\n stdout: \"Usage: codex exec resume [SESSION_ID] [PROMPT]\\n--json\\n- stdin\",\n stderr: \"\",\n });\n const Probe = api.CodexCliProbe as new (options: unknown) => any;\n\n await expect(new Probe({ executable: \"fake-codex\", exec }).validate()).resolves.toEqual({\n executable: \"fake-codex\",\n version: \"codex-cli 0.147.0\",\n });\n expect(exec.mock.calls).toEqual([\n [\"fake-codex\", [\"--version\"]],\n [\"fake-codex\", [\"exec\", \"--help\"]],\n [\"fake-codex\", [\"exec\", \"resume\", \"--help\"]],\n ]);\n });\n\n it(\"rejects unsupported and unavailable CLIs with bounded sanitized errors\", async () => {\n const api = (await import(\"../../index.js\")) as Record<string, unknown>;\n const Probe = api.CodexCliProbe as new (options: unknown) => any;\n const unsupported = new Probe({\n exec: vi\n .fn()\n .mockResolvedValueOnce({ stdout: \"version\", stderr: \"\" })\n .mockResolvedValueOnce({ stdout: \"exec\", stderr: \"\" })\n .mockResolvedValueOnce({ stdout: \"resume\", stderr: \"\" }),\n });\n await expect(unsupported.validate()).rejects.toMatchObject({ code: \"CODEX_CLI_UNSUPPORTED\" });\n const missingCommands = new Probe({\n exec: vi\n .fn()\n .mockResolvedValueOnce({ stdout: \"version\", stderr: \"\" })\n .mockResolvedValueOnce({ stdout: \"\", stderr: \"\" })\n .mockResolvedValueOnce({ stdout: \"\", stderr: \"\" }),\n });\n await expect(missingCommands.validate()).rejects.toMatchObject({\n code: \"CODEX_CLI_UNSUPPORTED\",\n });\n\n const unavailable = new Probe({\n exec: vi.fn().mockRejectedValue(new Error(`bad\\0${\"x\".repeat(1000)}`)),\n });\n const error = await unavailable.validate().catch((value: Error & { code: string }) => value);\n expect(error.code).toBe(\"CODEX_CLI_UNAVAILABLE\");\n expect(error.message).not.toContain(\"\\0\");\n expect(error.message.length).toBeLessThan(600);\n });\n\n it(\"reports an empty version response as unknown\", async () => {\n const api = (await import(\"../../index.js\")) as Record<string, unknown>;\n const Probe = api.CodexCliProbe as new (options: unknown) => any;\n const exec = vi\n .fn()\n .mockResolvedValueOnce({ stdout: \" \\n\", stderr: \"\" })\n .mockResolvedValueOnce({ stdout: \"exec --json -\", stderr: \"\" })\n .mockResolvedValueOnce({ stdout: \"resume --json -\", stderr: \"\" });\n await expect(new Probe({ exec }).validate()).resolves.toMatchObject({ version: \"unknown\" });\n });\n\n it(\"requires a standalone stdin dash rather than accepting flag hyphens\", async () => {\n const api = (await import(\"../../index.js\")) as Record<string, unknown>;\n const Probe = api.CodexCliProbe as new (options: unknown) => any;\n const exec = vi\n .fn()\n .mockResolvedValueOnce({ stdout: \"version\", stderr: \"\" })\n .mockResolvedValueOnce({ stdout: \"exec --json\", stderr: \"\" })\n .mockResolvedValueOnce({ stdout: \"resume --json\", stderr: \"\" });\n await expect(new Probe({ exec }).validate()).rejects.toMatchObject({\n code: \"CODEX_CLI_UNSUPPORTED\",\n });\n });\n});\n"],"names":["describe","expect","it","vi","api","toHaveProperty","exec","fn","mockResolvedValueOnce","stdout","stderr","Probe","CodexCliProbe","executable","validate","resolves","toEqual","version","mock","calls","unsupported","rejects","toMatchObject","code","missingCommands","unavailable","mockRejectedValue","Error","repeat","error","catch","value","toBe","message","not","toContain","length","toBeLessThan"],"mappings":"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"}
@@ -1,10 +1,10 @@
1
- import fs from 'node:fs';
2
- import os from 'node:os';
3
- import path from 'node:path';
4
- import { afterEach, describe, expect, it } from 'vitest';
5
- import { DurableAgentRepository } from '../../durable/DurableAgentRepository.js';
6
- const SESSION = '22222222-2222-4222-8222-222222222222';
7
- const OTHER_SESSION = '33333333-3333-4333-8333-333333333333';
1
+ import fs from "node:fs";
2
+ import os from "node:os";
3
+ import path from "node:path";
4
+ import { afterEach, describe, expect, it } from "vitest";
5
+ import { DurableAgentRepository } from "../../durable/DurableAgentRepository.js";
6
+ const SESSION = "22222222-2222-4222-8222-222222222222";
7
+ const OTHER_SESSION = "33333333-3333-4333-8333-333333333333";
8
8
  const roots = [];
9
9
  afterEach(()=>{
10
10
  for (const root of roots.splice(0))fs.rmSync(root, {
@@ -13,35 +13,35 @@ afterEach(()=>{
13
13
  });
14
14
  });
15
15
  function fixture() {
16
- const root = fs.mkdtempSync(path.join(os.tmpdir(), 'codex-durable-repository-'));
16
+ const root = fs.mkdtempSync(path.join(os.tmpdir(), "codex-durable-repository-"));
17
17
  roots.push(root);
18
- const cwd = path.join(root, 'project');
18
+ const cwd = path.join(root, "project");
19
19
  fs.mkdirSync(cwd);
20
20
  const processInspector = {
21
21
  getIdentity: (pid)=>({
22
22
  pid,
23
- startedAt: 'owner-start'
23
+ startedAt: "owner-start"
24
24
  })
25
25
  };
26
26
  return {
27
27
  cwd,
28
28
  repository: new DurableAgentRepository({
29
- dbPath: path.join(root, 'agents.db'),
29
+ dbPath: path.join(root, "agents.db"),
30
30
  processInspector
31
31
  })
32
32
  };
33
33
  }
34
- describe('Codex durable-agent repository binding', ()=>{
35
- it('creates Codex agents unbound and binds during the owned run', async ()=>{
34
+ describe("Codex durable-agent repository binding", ()=>{
35
+ it("creates Codex agents unbound and binds during the owned run", async ()=>{
36
36
  const { cwd, repository } = fixture();
37
37
  const agent = await repository.create({
38
- name: 'reviewer',
38
+ name: "reviewer",
39
39
  cwd,
40
- provider: 'codex'
40
+ provider: "codex"
41
41
  });
42
42
  expect(agent).toMatchObject({
43
- provider: 'codex',
44
- mode: 'durable',
43
+ provider: "codex",
44
+ mode: "durable",
45
45
  providerSessionId: null
46
46
  });
47
47
  const run = await repository.acquireRun(agent.id);
@@ -51,32 +51,32 @@ describe('Codex durable-agent repository binding', ()=>{
51
51
  providerSessionId: SESSION
52
52
  });
53
53
  });
54
- it('rejects invalid, stale, replacement, and duplicate bindings', async ()=>{
54
+ it("rejects invalid, stale, replacement, and duplicate bindings", async ()=>{
55
55
  const { cwd, repository } = fixture();
56
56
  const first = await repository.create({
57
- name: 'first',
57
+ name: "first",
58
58
  cwd,
59
- provider: 'codex'
59
+ provider: "codex"
60
60
  });
61
61
  const second = await repository.create({
62
- name: 'second',
62
+ name: "second",
63
63
  cwd,
64
- provider: 'codex'
64
+ provider: "codex"
65
65
  });
66
66
  const firstRun = await repository.acquireRun(first.id);
67
67
  const secondRun = await repository.acquireRun(second.id);
68
- await expect(repository.bindProviderSession(first.id, 'stale', SESSION)).rejects.toMatchObject({
69
- code: 'DURABLE_AGENT_REPOSITORY'
68
+ await expect(repository.bindProviderSession(first.id, "stale", SESSION)).rejects.toMatchObject({
69
+ code: "DURABLE_AGENT_REPOSITORY"
70
70
  });
71
- await expect(repository.bindProviderSession(first.id, firstRun.token, 'invalid')).rejects.toMatchObject({
72
- code: 'DURABLE_AGENT_REPOSITORY'
71
+ await expect(repository.bindProviderSession(first.id, firstRun.token, "invalid")).rejects.toMatchObject({
72
+ code: "DURABLE_AGENT_REPOSITORY"
73
73
  });
74
74
  await repository.bindProviderSession(first.id, firstRun.token, SESSION);
75
75
  await expect(repository.bindProviderSession(first.id, firstRun.token, OTHER_SESSION)).rejects.toMatchObject({
76
- code: 'CODEX_SESSION_MISMATCH'
76
+ code: "CODEX_SESSION_MISMATCH"
77
77
  });
78
78
  await expect(repository.bindProviderSession(second.id, secondRun.token, SESSION)).rejects.toMatchObject({
79
- code: 'CODEX_SESSION_MISMATCH'
79
+ code: "CODEX_SESSION_MISMATCH"
80
80
  });
81
81
  });
82
82
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/__tests__/durable/CodexDurableAgentRepository.test.ts"],"sourcesContent":["import fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\nimport { afterEach, describe, expect, it } from 'vitest';\nimport { DurableAgentRepository } from '../../durable/DurableAgentRepository.js';\n\nconst SESSION = '22222222-2222-4222-8222-222222222222';\nconst OTHER_SESSION = '33333333-3333-4333-8333-333333333333';\nconst roots: string[] = [];\n\nafterEach(() => {\n for (const root of roots.splice(0)) fs.rmSync(root, { recursive: true, force: true });\n});\n\nfunction fixture() {\n const root = fs.mkdtempSync(path.join(os.tmpdir(), 'codex-durable-repository-'));\n roots.push(root);\n const cwd = path.join(root, 'project');\n fs.mkdirSync(cwd);\n const processInspector = { getIdentity: (pid: number) => ({ pid, startedAt: 'owner-start' }) };\n return { cwd, repository: new DurableAgentRepository({ dbPath: path.join(root, 'agents.db'), processInspector }) };\n}\n\ndescribe('Codex durable-agent repository binding', () => {\n it('creates Codex agents unbound and binds during the owned run', async () => {\n const { cwd, repository } = fixture();\n const agent = await repository.create({ name: 'reviewer', cwd, provider: 'codex' });\n expect(agent).toMatchObject({ provider: 'codex', mode: 'durable', providerSessionId: null });\n\n const run = await repository.acquireRun(agent.id);\n const bound = await repository.bindProviderSession(agent.id, run.token, SESSION);\n expect(bound.providerSessionId).toBe(SESSION);\n await expect(repository.bindProviderSession(agent.id, run.token, SESSION))\n .resolves.toMatchObject({ providerSessionId: SESSION });\n });\n\n it('rejects invalid, stale, replacement, and duplicate bindings', async () => {\n const { cwd, repository } = fixture();\n const first = await repository.create({ name: 'first', cwd, provider: 'codex' });\n const second = await repository.create({ name: 'second', cwd, provider: 'codex' });\n const firstRun = await repository.acquireRun(first.id);\n const secondRun = await repository.acquireRun(second.id);\n\n await expect(repository.bindProviderSession(first.id, 'stale', SESSION))\n .rejects.toMatchObject({ code: 'DURABLE_AGENT_REPOSITORY' });\n await expect(repository.bindProviderSession(first.id, firstRun.token, 'invalid'))\n .rejects.toMatchObject({ code: 'DURABLE_AGENT_REPOSITORY' });\n await repository.bindProviderSession(first.id, firstRun.token, SESSION);\n await expect(repository.bindProviderSession(first.id, firstRun.token, OTHER_SESSION))\n .rejects.toMatchObject({ code: 'CODEX_SESSION_MISMATCH' });\n await expect(repository.bindProviderSession(second.id, secondRun.token, SESSION))\n .rejects.toMatchObject({ code: 'CODEX_SESSION_MISMATCH' });\n });\n});\n"],"names":["fs","os","path","afterEach","describe","expect","it","DurableAgentRepository","SESSION","OTHER_SESSION","roots","root","splice","rmSync","recursive","force","fixture","mkdtempSync","join","tmpdir","push","cwd","mkdirSync","processInspector","getIdentity","pid","startedAt","repository","dbPath","agent","create","name","provider","toMatchObject","mode","providerSessionId","run","acquireRun","id","bound","bindProviderSession","token","toBe","resolves","first","second","firstRun","secondRun","rejects","code"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/__tests__/durable/CodexDurableAgentRepository.test.ts"],"sourcesContent":["import fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { afterEach, describe, expect, it } from \"vitest\";\nimport { DurableAgentRepository } from \"../../durable/DurableAgentRepository.js\";\n\nconst SESSION = \"22222222-2222-4222-8222-222222222222\";\nconst OTHER_SESSION = \"33333333-3333-4333-8333-333333333333\";\nconst roots: string[] = [];\n\nafterEach(() => {\n for (const root of roots.splice(0)) fs.rmSync(root, { recursive: true, force: true });\n});\n\nfunction fixture() {\n const root = fs.mkdtempSync(path.join(os.tmpdir(), \"codex-durable-repository-\"));\n roots.push(root);\n const cwd = path.join(root, \"project\");\n fs.mkdirSync(cwd);\n const processInspector = { getIdentity: (pid: number) => ({ pid, startedAt: \"owner-start\" }) };\n return {\n cwd,\n repository: new DurableAgentRepository({\n dbPath: path.join(root, \"agents.db\"),\n processInspector,\n }),\n };\n}\n\ndescribe(\"Codex durable-agent repository binding\", () => {\n it(\"creates Codex agents unbound and binds during the owned run\", async () => {\n const { cwd, repository } = fixture();\n const agent = await repository.create({ name: \"reviewer\", cwd, provider: \"codex\" });\n expect(agent).toMatchObject({ provider: \"codex\", mode: \"durable\", providerSessionId: null });\n\n const run = await repository.acquireRun(agent.id);\n const bound = await repository.bindProviderSession(agent.id, run.token, SESSION);\n expect(bound.providerSessionId).toBe(SESSION);\n await expect(\n repository.bindProviderSession(agent.id, run.token, SESSION),\n ).resolves.toMatchObject({ providerSessionId: SESSION });\n });\n\n it(\"rejects invalid, stale, replacement, and duplicate bindings\", async () => {\n const { cwd, repository } = fixture();\n const first = await repository.create({ name: \"first\", cwd, provider: \"codex\" });\n const second = await repository.create({ name: \"second\", cwd, provider: \"codex\" });\n const firstRun = await repository.acquireRun(first.id);\n const secondRun = await repository.acquireRun(second.id);\n\n await expect(repository.bindProviderSession(first.id, \"stale\", SESSION)).rejects.toMatchObject({\n code: \"DURABLE_AGENT_REPOSITORY\",\n });\n await expect(\n repository.bindProviderSession(first.id, firstRun.token, \"invalid\"),\n ).rejects.toMatchObject({ code: \"DURABLE_AGENT_REPOSITORY\" });\n await repository.bindProviderSession(first.id, firstRun.token, SESSION);\n await expect(\n repository.bindProviderSession(first.id, firstRun.token, OTHER_SESSION),\n ).rejects.toMatchObject({ code: \"CODEX_SESSION_MISMATCH\" });\n await expect(\n repository.bindProviderSession(second.id, secondRun.token, SESSION),\n ).rejects.toMatchObject({ code: \"CODEX_SESSION_MISMATCH\" });\n });\n});\n"],"names":["fs","os","path","afterEach","describe","expect","it","DurableAgentRepository","SESSION","OTHER_SESSION","roots","root","splice","rmSync","recursive","force","fixture","mkdtempSync","join","tmpdir","push","cwd","mkdirSync","processInspector","getIdentity","pid","startedAt","repository","dbPath","agent","create","name","provider","toMatchObject","mode","providerSessionId","run","acquireRun","id","bound","bindProviderSession","token","toBe","resolves","first","second","firstRun","secondRun","rejects","code"],"mappings":"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"}