@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,26 +1,26 @@
1
- import { spawn } from 'node:child_process';
2
- import { readFile } from 'node:fs/promises';
3
- import { join } from 'node:path';
1
+ import { spawn } from "node:child_process";
2
+ import { readFile } from "node:fs/promises";
3
+ import { join } from "node:path";
4
4
  export const CODEX_APP_SERVER_ARGS = [
5
- '-s',
6
- 'read-only',
7
- '-a',
8
- 'untrusted',
9
- 'app-server'
5
+ "-s",
6
+ "read-only",
7
+ "-a",
8
+ "untrusted",
9
+ "app-server"
10
10
  ];
11
11
  function record(value) {
12
- return value !== null && typeof value === 'object' && !Array.isArray(value) ? value : null;
12
+ return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
13
13
  }
14
14
  function finiteNumber(value) {
15
- return typeof value === 'number' && Number.isFinite(value) ? value : null;
15
+ return typeof value === "number" && Number.isFinite(value) ? value : null;
16
16
  }
17
17
  function nonEmptyText(value) {
18
- return typeof value === 'string' && value.length > 0 ? value : null;
18
+ return typeof value === "string" && value.length > 0 ? value : null;
19
19
  }
20
20
  function resetTime(value) {
21
21
  const seconds = finiteNumber(value);
22
22
  if (seconds !== null) return new Date(seconds * 1000).toISOString();
23
- if (typeof value === 'string' && !Number.isNaN(Date.parse(value))) return new Date(value).toISOString();
23
+ if (typeof value === "string" && !Number.isNaN(Date.parse(value))) return new Date(value).toISOString();
24
24
  return null;
25
25
  }
26
26
  function safeIdentifier(value) {
@@ -30,8 +30,8 @@ function safeIdentifier(value) {
30
30
  return candidate;
31
31
  }
32
32
  export function resolveCodexAuthPath(env = process.env) {
33
- const root = env.CODEX_HOME || join(env.HOME || '', '.codex');
34
- return join(root, 'auth.json');
33
+ const root = env.CODEX_HOME || join(env.HOME || "", ".codex");
34
+ return join(root, "auth.json");
35
35
  }
36
36
  export function toRateWindow(value, id, label) {
37
37
  const input = record(value);
@@ -65,8 +65,8 @@ export function parseUsage(raw, source) {
65
65
  const credits = record(response.credits) ?? {};
66
66
  return {
67
67
  windows: [
68
- toRateWindow(limits.primary_window, 'session', 'Session'),
69
- toRateWindow(limits.secondary_window, 'weekly', 'Weekly'),
68
+ toRateWindow(limits.primary_window, "session", "Session"),
69
+ toRateWindow(limits.secondary_window, "weekly", "Weekly"),
70
70
  ...extraWindows(response.additional_rate_limits)
71
71
  ].filter((window)=>window !== null),
72
72
  creditsRemaining: finiteNumber(credits.balance),
@@ -87,7 +87,7 @@ function cliWindow(value, id, label) {
87
87
  function cliSnapshotWindows(value, fallbackId) {
88
88
  const snapshot = record(value);
89
89
  if (!snapshot) return [];
90
- const scope = safeIdentifier(snapshot.limitId) ?? safeIdentifier(fallbackId) ?? 'codex';
90
+ const scope = safeIdentifier(snapshot.limitId) ?? safeIdentifier(fallbackId) ?? "codex";
91
91
  return [
92
92
  cliWindow(snapshot.primary, `${scope}:primary`, `${scope} primary`),
93
93
  cliWindow(snapshot.secondary, `${scope}:secondary`, `${scope} secondary`)
@@ -96,7 +96,7 @@ function cliSnapshotWindows(value, fallbackId) {
96
96
  export function parseCliUsage(raw) {
97
97
  const response = record(raw) ?? {};
98
98
  const primary = record(response.rateLimits);
99
- const windows = primary ? cliSnapshotWindows(primary, 'codex') : [];
99
+ const windows = primary ? cliSnapshotWindows(primary, "codex") : [];
100
100
  const buckets = record(response.rateLimitsByLimitId);
101
101
  if (buckets) {
102
102
  for (const [id, snapshot] of Object.entries(buckets))windows.push(...cliSnapshotWindows(snapshot, id));
@@ -110,7 +110,7 @@ export function parseCliUsage(raw) {
110
110
  return {
111
111
  windows: unique,
112
112
  creditsRemaining: null,
113
- source: 'cli'
113
+ source: "cli"
114
114
  };
115
115
  }
116
116
  function capacityFromSnapshot(snapshot, context, raw) {
@@ -119,19 +119,19 @@ function capacityFromSnapshot(snapshot, context, raw) {
119
119
  const reached = nonEmptyText(rateLimits?.rateLimitReachedType);
120
120
  const resetCredits = record(record(raw)?.rateLimitResetCredits) ?? record(record(raw)?.usageLimitResetCredits);
121
121
  return {
122
- provider: 'codex',
122
+ provider: "codex",
123
123
  generatedAt: context.checkedAt,
124
124
  authenticated: true,
125
- available: reached ? 'no' : hasUsage ? 'yes' : 'unknown',
125
+ available: reached ? "no" : hasUsage ? "yes" : "unknown",
126
126
  windows: snapshot.windows,
127
127
  creditsRemaining: snapshot.creditsRemaining ?? finiteNumber(resetCredits?.availableCount)
128
128
  };
129
129
  }
130
130
  function jwtExpiry(token) {
131
- const part = token.split('.')[1];
131
+ const part = token.split(".")[1];
132
132
  if (!part) return null;
133
133
  try {
134
- return finiteNumber(record(JSON.parse(Buffer.from(part, 'base64url').toString('utf8')))?.exp);
134
+ return finiteNumber(record(JSON.parse(Buffer.from(part, "base64url").toString("utf8")))?.exp);
135
135
  } catch {
136
136
  return null;
137
137
  }
@@ -139,7 +139,7 @@ function jwtExpiry(token) {
139
139
  function staleOAuth(tokens, token, now) {
140
140
  const metadata = tokens.expires_at ?? tokens.expiresAt ?? tokens.expiry;
141
141
  let expiry = finiteNumber(metadata);
142
- if (typeof metadata === 'string') {
142
+ if (typeof metadata === "string") {
143
143
  const parsed = Date.parse(metadata);
144
144
  expiry = Number.isNaN(parsed) ? null : parsed / 1000;
145
145
  }
@@ -154,7 +154,7 @@ async function fetchJson(fetcher, url, init, timeoutMs) {
154
154
  ...init,
155
155
  signal: controller.signal
156
156
  });
157
- if (!response.ok) throw new Error(response.status === 401 ? 'unauthorized' : 'request failed');
157
+ if (!response.ok) throw new Error(response.status === 401 ? "unauthorized" : "request failed");
158
158
  return await response.json();
159
159
  } finally{
160
160
  clearTimeout(timer);
@@ -162,25 +162,25 @@ async function fetchJson(fetcher, url, init, timeoutMs) {
162
162
  }
163
163
  async function apiSnapshot(token, accountId, source, options) {
164
164
  const fetcher = options.fetch ?? globalThis.fetch;
165
- const raw = await fetchJson(fetcher, 'https://chatgpt.com/backend-api/wham/usage', {
165
+ const raw = await fetchJson(fetcher, "https://chatgpt.com/backend-api/wham/usage", {
166
166
  headers: {
167
167
  Authorization: `Bearer ${token}`,
168
- 'ChatGPT-Account-Id': accountId
168
+ "ChatGPT-Account-Id": accountId
169
169
  }
170
170
  }, options.timeoutMs ?? 5000);
171
171
  return parseUsage(raw, source);
172
172
  }
173
173
  function appServerRpc(messages, timeoutMs = 5000) {
174
174
  return new Promise((resolve, reject)=>{
175
- const child = spawn('codex', CODEX_APP_SERVER_ARGS, {
175
+ const child = spawn("codex", CODEX_APP_SERVER_ARGS, {
176
176
  stdio: [
177
- 'pipe',
178
- 'pipe',
179
- 'ignore'
177
+ "pipe",
178
+ "pipe",
179
+ "ignore"
180
180
  ]
181
181
  });
182
182
  const results = {};
183
- let buffer = '';
183
+ let buffer = "";
184
184
  let settled = false;
185
185
  const finish = (error)=>{
186
186
  if (settled) return;
@@ -190,16 +190,16 @@ function appServerRpc(messages, timeoutMs = 5000) {
190
190
  if (error) reject(error);
191
191
  else resolve(results);
192
192
  };
193
- const timer = setTimeout(()=>finish(new Error('codex probe timed out')), timeoutMs);
194
- child.once('error', ()=>finish(new Error('codex app-server unavailable')));
195
- child.once('exit', ()=>{
196
- if (!settled) finish(new Error('codex app-server exited'));
193
+ const timer = setTimeout(()=>finish(new Error("codex probe timed out")), timeoutMs);
194
+ child.once("error", ()=>finish(new Error("codex app-server unavailable")));
195
+ child.once("exit", ()=>{
196
+ if (!settled) finish(new Error("codex app-server exited"));
197
197
  });
198
- child.stdout.setEncoding('utf8');
199
- child.stdout.on('data', (chunk)=>{
198
+ child.stdout.setEncoding("utf8");
199
+ child.stdout.on("data", (chunk)=>{
200
200
  buffer += chunk;
201
201
  for(;;){
202
- const newline = buffer.indexOf('\n');
202
+ const newline = buffer.indexOf("\n");
203
203
  if (newline < 0) break;
204
204
  const line = buffer.slice(0, newline).trim();
205
205
  buffer = buffer.slice(newline + 1);
@@ -213,13 +213,13 @@ function appServerRpc(messages, timeoutMs = 5000) {
213
213
  if (message.id === 1) {
214
214
  for (const request of messages.slice(1))child.stdin.write(`${JSON.stringify(request)}\n`);
215
215
  } else if (message.id === 2) {
216
- if (message.error) finish(new Error('codex rate-limit method failed'));
216
+ if (message.error) finish(new Error("codex rate-limit method failed"));
217
217
  else results.rateLimits = message.result;
218
218
  } else if (message.id === 3) {
219
- if (message.error) finish(new Error('codex account method failed'));
219
+ if (message.error) finish(new Error("codex account method failed"));
220
220
  else results.account = message.result;
221
221
  }
222
- if ('rateLimits' in results && 'account' in results) finish();
222
+ if ("rateLimits" in results && "account" in results) finish();
223
223
  }
224
224
  });
225
225
  child.stdin.write(`${JSON.stringify(messages[0])}\n`);
@@ -227,10 +227,10 @@ function appServerRpc(messages, timeoutMs = 5000) {
227
227
  }
228
228
  function unavailable(options) {
229
229
  return {
230
- provider: 'codex',
230
+ provider: "codex",
231
231
  generatedAt: options.checkedAt,
232
232
  authenticated: null,
233
- available: 'unknown',
233
+ available: "unknown",
234
234
  windows: [],
235
235
  creditsRemaining: null
236
236
  };
@@ -240,26 +240,26 @@ async function cliFallback(options) {
240
240
  const messages = [
241
241
  {
242
242
  id: 1,
243
- method: 'initialize',
243
+ method: "initialize",
244
244
  params: {
245
245
  clientInfo: {
246
- name: 'ai-devkit',
246
+ name: "ai-devkit",
247
247
  title: null,
248
- version: '1'
248
+ version: "1"
249
249
  },
250
250
  capabilities: null
251
251
  }
252
252
  },
253
253
  {
254
- method: 'initialized'
254
+ method: "initialized"
255
255
  },
256
256
  {
257
257
  id: 2,
258
- method: 'account/rateLimits/read'
258
+ method: "account/rateLimits/read"
259
259
  },
260
260
  {
261
261
  id: 3,
262
- method: 'account/read'
262
+ method: "account/read"
263
263
  }
264
264
  ];
265
265
  try {
@@ -267,9 +267,9 @@ async function cliFallback(options) {
267
267
  const response = await rpc(messages);
268
268
  const result = capacityFromSnapshot(parseCliUsage(response.rateLimits), options, response.rateLimits);
269
269
  const accountEnvelope = record(response.account);
270
- if (accountEnvelope && Object.hasOwn(accountEnvelope, 'account') && !record(accountEnvelope.account)) {
270
+ if (accountEnvelope && Object.hasOwn(accountEnvelope, "account") && !record(accountEnvelope.account)) {
271
271
  result.authenticated = false;
272
- result.available = 'unknown';
272
+ result.available = "unknown";
273
273
  }
274
274
  return result;
275
275
  } catch {
@@ -279,7 +279,7 @@ async function cliFallback(options) {
279
279
  export async function probeCodexCapacity(options) {
280
280
  let parsed = null;
281
281
  try {
282
- const contents = await (options.readFile ?? readFile)(resolveCodexAuthPath(options.env), 'utf8');
282
+ const contents = await (options.readFile ?? readFile)(resolveCodexAuthPath(options.env), "utf8");
283
283
  parsed = record(JSON.parse(contents));
284
284
  } catch {
285
285
  return cliFallback(options);
@@ -289,14 +289,14 @@ export async function probeCodexCapacity(options) {
289
289
  if (pat) {
290
290
  try {
291
291
  const fetcher = options.fetch ?? globalThis.fetch;
292
- const whoami = record(await fetchJson(fetcher, 'https://auth.openai.com/api/accounts/v1/user-auth-credential/whoami', {
292
+ const whoami = record(await fetchJson(fetcher, "https://auth.openai.com/api/accounts/v1/user-auth-credential/whoami", {
293
293
  headers: {
294
294
  Authorization: `Bearer ${pat}`
295
295
  }
296
296
  }, options.timeoutMs ?? 5000));
297
297
  const accountId = nonEmptyText(whoami?.chatgpt_account_id);
298
- if (!accountId) throw new Error('account unavailable');
299
- return capacityFromSnapshot(await apiSnapshot(pat, accountId, 'pat', options), options);
298
+ if (!accountId) throw new Error("account unavailable");
299
+ return capacityFromSnapshot(await apiSnapshot(pat, accountId, "pat", options), options);
300
300
  } catch {
301
301
  // Continue to a separately available OAuth credential before using the CLI.
302
302
  }
@@ -306,7 +306,7 @@ export async function probeCodexCapacity(options) {
306
306
  const accountId = nonEmptyText(tokens?.account_id);
307
307
  if (tokens && accessToken && accountId && !staleOAuth(tokens, accessToken, (options.now ?? (()=>new Date()))())) {
308
308
  try {
309
- return capacityFromSnapshot(await apiSnapshot(accessToken, accountId, 'oauth', options), options);
309
+ return capacityFromSnapshot(await apiSnapshot(accessToken, accountId, "oauth", options), options);
310
310
  } catch {
311
311
  return cliFallback(options);
312
312
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/capacity/codex.ts"],"sourcesContent":["import { spawn } from 'node:child_process';\nimport { readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport type { CapacityReport, CapacityWindow } from './types.js';\n\ntype CodexUsageSource = 'pat' | 'oauth' | 'cli';\ntype UsageSnapshot = { windows: CapacityWindow[]; creditsRemaining: number | null; source: CodexUsageSource };\n\ntype UnknownRecord = Record<string, unknown>;\ntype RpcMessage = { id?: number; method: string; params?: UnknownRecord };\ntype CliResponses = { rateLimits: unknown; account: unknown };\ntype CodexRpc = (messages: RpcMessage[]) => Promise<CliResponses>;\n\nexport const CODEX_APP_SERVER_ARGS = ['-s', 'read-only', '-a', 'untrusted', 'app-server'] as const;\n\ntype CodexProbeOptions = {\n installed: boolean;\n checkedAt: string;\n readFile?: (path: string, encoding: BufferEncoding) => Promise<string>;\n fetch?: typeof globalThis.fetch;\n rpc?: CodexRpc;\n timeoutMs?: number;\n env?: NodeJS.ProcessEnv;\n now?: () => Date;\n};\n\nfunction record(value: unknown): UnknownRecord | null {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n ? value as UnknownRecord\n : null;\n}\n\nfunction finiteNumber(value: unknown): number | null {\n return typeof value === 'number' && Number.isFinite(value) ? value : null;\n}\n\nfunction nonEmptyText(value: unknown): string | null {\n return typeof value === 'string' && value.length > 0 ? value : null;\n}\n\nfunction resetTime(value: unknown): string | null {\n const seconds = finiteNumber(value);\n if (seconds !== null) return new Date(seconds * 1000).toISOString();\n if (typeof value === 'string' && !Number.isNaN(Date.parse(value))) return new Date(value).toISOString();\n return null;\n}\n\nfunction safeIdentifier(value: unknown): string | null {\n const candidate = nonEmptyText(value);\n if (!candidate || !/^[a-z][a-z0-9_-]{0,63}$/i.test(candidate)) return null;\n if (/(?:account|token|secret|key)[_-]?\\d{6,}/i.test(candidate)) return null;\n return candidate;\n}\n\nexport function resolveCodexAuthPath(env: NodeJS.ProcessEnv = process.env): string {\n const root = env.CODEX_HOME || join(env.HOME || '', '.codex');\n return join(root, 'auth.json');\n}\n\nexport function toRateWindow(\n value: unknown,\n id: string,\n label: string\n): CapacityWindow | null {\n const input = record(value);\n if (!input) return null;\n const used = finiteNumber(input.used_percent);\n const seconds = finiteNumber(input.limit_window_seconds);\n return {\n id,\n label,\n durationMinutes: seconds === null ? null : seconds / 60,\n usedPercent: used,\n resetsAt: resetTime(input.reset_at)\n };\n}\n\nfunction extraWindows(value: unknown): CapacityWindow[] {\n if (!Array.isArray(value)) return [];\n return value.flatMap((entry, index) => {\n const limit = record(entry);\n if (!limit) return [];\n const scope = safeIdentifier(limit.limit_name) ?? `extra-${index + 1}`;\n const windows = record(limit.rate_limit) ?? limit;\n return [\n toRateWindow(windows.primary_window, `${scope}:primary`, `${scope} primary`),\n toRateWindow(windows.secondary_window, `${scope}:secondary`, `${scope} secondary`)\n ].filter((window): window is CapacityWindow => window !== null);\n });\n}\n\nexport function parseUsage(raw: unknown, source: 'pat' | 'oauth'): UsageSnapshot {\n const response = record(raw) ?? {};\n const limits = record(response.rate_limit) ?? {};\n const credits = record(response.credits) ?? {};\n return {\n windows: [\n toRateWindow(limits.primary_window, 'session', 'Session'),\n toRateWindow(limits.secondary_window, 'weekly', 'Weekly'),\n ...extraWindows(response.additional_rate_limits)\n ].filter((window): window is CapacityWindow => window !== null),\n creditsRemaining: finiteNumber(credits.balance),\n source\n };\n}\n\nfunction cliWindow(value: unknown, id: string, label: string): CapacityWindow | null {\n const input = record(value);\n if (!input) return null;\n return {\n id,\n label,\n durationMinutes: finiteNumber(input.windowDurationMins),\n usedPercent: finiteNumber(input.usedPercent),\n resetsAt: resetTime(input.resetsAt)\n };\n}\n\nfunction cliSnapshotWindows(value: unknown, fallbackId: string): CapacityWindow[] {\n const snapshot = record(value);\n if (!snapshot) return [];\n const scope = safeIdentifier(snapshot.limitId) ?? safeIdentifier(fallbackId) ?? 'codex';\n return [\n cliWindow(snapshot.primary, `${scope}:primary`, `${scope} primary`),\n cliWindow(snapshot.secondary, `${scope}:secondary`, `${scope} secondary`)\n ].filter((item): item is CapacityWindow => item !== null);\n}\n\nexport function parseCliUsage(raw: unknown): UsageSnapshot {\n const response = record(raw) ?? {};\n const primary = record(response.rateLimits);\n const windows = primary ? cliSnapshotWindows(primary, 'codex') : [];\n const buckets = record(response.rateLimitsByLimitId);\n if (buckets) {\n for (const [id, snapshot] of Object.entries(buckets)) windows.push(...cliSnapshotWindows(snapshot, id));\n }\n const unique = [...new Map(windows.map(window => [window.id, window])).values()];\n return { windows: unique, creditsRemaining: null, source: 'cli' };\n}\n\nfunction capacityFromSnapshot(snapshot: UsageSnapshot, context: CodexProbeOptions, raw?: unknown): CapacityReport {\n const hasUsage = snapshot.windows.some(window => window.usedPercent !== null);\n const rateLimits = record(record(raw)?.rateLimits);\n const reached = nonEmptyText(rateLimits?.rateLimitReachedType);\n const resetCredits = record(record(raw)?.rateLimitResetCredits) ?? record(record(raw)?.usageLimitResetCredits);\n return {\n provider: 'codex',\n generatedAt: context.checkedAt,\n authenticated: true,\n available: reached ? 'no' : hasUsage ? 'yes' : 'unknown',\n windows: snapshot.windows,\n creditsRemaining: snapshot.creditsRemaining ?? finiteNumber(resetCredits?.availableCount)\n };\n}\n\nfunction jwtExpiry(token: string): number | null {\n const part = token.split('.')[1];\n if (!part) return null;\n try {\n return finiteNumber(record(JSON.parse(Buffer.from(part, 'base64url').toString('utf8')))?.exp);\n } catch {\n return null;\n }\n}\n\nfunction staleOAuth(tokens: UnknownRecord, token: string, now: Date): boolean {\n const metadata = tokens.expires_at ?? tokens.expiresAt ?? tokens.expiry;\n let expiry: number | null = finiteNumber(metadata);\n if (typeof metadata === 'string') {\n const parsed = Date.parse(metadata);\n expiry = Number.isNaN(parsed) ? null : parsed / 1000;\n }\n expiry ??= jwtExpiry(token);\n return expiry !== null && expiry <= now.getTime() / 1000;\n}\n\nasync function fetchJson(fetcher: typeof globalThis.fetch, url: string, init: RequestInit, timeoutMs: number): Promise<unknown> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n try {\n const response = await fetcher(url, { ...init, signal: controller.signal });\n if (!response.ok) throw new Error(response.status === 401 ? 'unauthorized' : 'request failed');\n return await response.json();\n } finally {\n clearTimeout(timer);\n }\n}\n\nasync function apiSnapshot(\n token: string,\n accountId: string,\n source: 'pat' | 'oauth',\n options: CodexProbeOptions\n): Promise<UsageSnapshot> {\n const fetcher = options.fetch ?? globalThis.fetch;\n const raw = await fetchJson(fetcher, 'https://chatgpt.com/backend-api/wham/usage', {\n headers: { Authorization: `Bearer ${token}`, 'ChatGPT-Account-Id': accountId }\n }, options.timeoutMs ?? 5000);\n return parseUsage(raw, source);\n}\n\nfunction appServerRpc(messages: RpcMessage[], timeoutMs = 5000): Promise<CliResponses> {\n return new Promise((resolve, reject) => {\n const child = spawn('codex', CODEX_APP_SERVER_ARGS, {\n stdio: ['pipe', 'pipe', 'ignore']\n });\n const results: Partial<CliResponses> = {};\n let buffer = '';\n let settled = false;\n const finish = (error?: Error) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n child.kill();\n if (error) reject(error);\n else resolve(results as CliResponses);\n };\n const timer = setTimeout(() => finish(new Error('codex probe timed out')), timeoutMs);\n child.once('error', () => finish(new Error('codex app-server unavailable')));\n child.once('exit', () => { if (!settled) finish(new Error('codex app-server exited')); });\n child.stdout.setEncoding('utf8');\n child.stdout.on('data', (chunk: string) => {\n buffer += chunk;\n for (;;) {\n const newline = buffer.indexOf('\\n');\n if (newline < 0) break;\n const line = buffer.slice(0, newline).trim();\n buffer = buffer.slice(newline + 1);\n if (!line) continue;\n let message: UnknownRecord;\n try { message = JSON.parse(line) as UnknownRecord; } catch { continue; }\n if (message.id === 1) {\n for (const request of messages.slice(1)) child.stdin.write(`${JSON.stringify(request)}\\n`);\n } else if (message.id === 2) {\n if (message.error) finish(new Error('codex rate-limit method failed'));\n else results.rateLimits = message.result;\n } else if (message.id === 3) {\n if (message.error) finish(new Error('codex account method failed'));\n else results.account = message.result;\n }\n if ('rateLimits' in results && 'account' in results) finish();\n }\n });\n child.stdin.write(`${JSON.stringify(messages[0])}\\n`);\n });\n}\n\nfunction unavailable(options: CodexProbeOptions): CapacityReport {\n return {\n provider: 'codex',\n generatedAt: options.checkedAt,\n authenticated: null,\n available: 'unknown',\n windows: [],\n creditsRemaining: null\n };\n}\n\nasync function cliFallback(options: CodexProbeOptions): Promise<CapacityReport> {\n if (!options.installed) return unavailable(options);\n const messages: RpcMessage[] = [\n { id: 1, method: 'initialize', params: {\n clientInfo: { name: 'ai-devkit', title: null, version: '1' }, capabilities: null\n } },\n { method: 'initialized' },\n { id: 2, method: 'account/rateLimits/read' },\n { id: 3, method: 'account/read' }\n ];\n try {\n const rpc = options.rpc ?? (requests => appServerRpc(requests, options.timeoutMs));\n const response = await rpc(messages);\n const result = capacityFromSnapshot(parseCliUsage(response.rateLimits), options, response.rateLimits);\n const accountEnvelope = record(response.account);\n if (accountEnvelope && Object.hasOwn(accountEnvelope, 'account') && !record(accountEnvelope.account)) {\n result.authenticated = false;\n result.available = 'unknown';\n }\n return result;\n } catch {\n return unavailable(options);\n }\n}\n\nexport async function probeCodexCapacity(options: CodexProbeOptions): Promise<CapacityReport> {\n let parsed: UnknownRecord | null = null;\n try {\n const contents = await (options.readFile ?? readFile)(resolveCodexAuthPath(options.env), 'utf8');\n parsed = record(JSON.parse(contents));\n } catch {\n return cliFallback(options);\n }\n\n const auth = parsed ?? {};\n const pat = nonEmptyText(auth.personal_access_token);\n if (pat) {\n try {\n const fetcher = options.fetch ?? globalThis.fetch;\n const whoami = record(await fetchJson(fetcher,\n 'https://auth.openai.com/api/accounts/v1/user-auth-credential/whoami',\n { headers: { Authorization: `Bearer ${pat}` } }, options.timeoutMs ?? 5000));\n const accountId = nonEmptyText(whoami?.chatgpt_account_id);\n if (!accountId) throw new Error('account unavailable');\n return capacityFromSnapshot(await apiSnapshot(pat, accountId, 'pat', options), options);\n } catch {\n // Continue to a separately available OAuth credential before using the CLI.\n }\n }\n\n const tokens = record(auth.tokens);\n const accessToken = nonEmptyText(tokens?.access_token);\n const accountId = nonEmptyText(tokens?.account_id);\n if (tokens && accessToken && accountId && !staleOAuth(tokens, accessToken, (options.now ?? (() => new Date()))())) {\n try {\n return capacityFromSnapshot(await apiSnapshot(accessToken, accountId, 'oauth', options), options);\n } catch {\n return cliFallback(options);\n }\n }\n return cliFallback(options);\n}\n"],"names":["spawn","readFile","join","CODEX_APP_SERVER_ARGS","record","value","Array","isArray","finiteNumber","Number","isFinite","nonEmptyText","length","resetTime","seconds","Date","toISOString","isNaN","parse","safeIdentifier","candidate","test","resolveCodexAuthPath","env","process","root","CODEX_HOME","HOME","toRateWindow","id","label","input","used","used_percent","limit_window_seconds","durationMinutes","usedPercent","resetsAt","reset_at","extraWindows","flatMap","entry","index","limit","scope","limit_name","windows","rate_limit","primary_window","secondary_window","filter","window","parseUsage","raw","source","response","limits","credits","additional_rate_limits","creditsRemaining","balance","cliWindow","windowDurationMins","cliSnapshotWindows","fallbackId","snapshot","limitId","primary","secondary","item","parseCliUsage","rateLimits","buckets","rateLimitsByLimitId","Object","entries","push","unique","Map","map","values","capacityFromSnapshot","context","hasUsage","some","reached","rateLimitReachedType","resetCredits","rateLimitResetCredits","usageLimitResetCredits","provider","generatedAt","checkedAt","authenticated","available","availableCount","jwtExpiry","token","part","split","JSON","Buffer","from","toString","exp","staleOAuth","tokens","now","metadata","expires_at","expiresAt","expiry","parsed","getTime","fetchJson","fetcher","url","init","timeoutMs","controller","AbortController","timer","setTimeout","abort","signal","ok","Error","status","json","clearTimeout","apiSnapshot","accountId","options","fetch","globalThis","headers","Authorization","appServerRpc","messages","Promise","resolve","reject","child","stdio","results","buffer","settled","finish","error","kill","once","stdout","setEncoding","on","chunk","newline","indexOf","line","slice","trim","message","request","stdin","write","stringify","result","account","unavailable","cliFallback","installed","method","params","clientInfo","name","title","version","capabilities","rpc","requests","accountEnvelope","hasOwn","probeCodexCapacity","contents","auth","pat","personal_access_token","whoami","chatgpt_account_id","accessToken","access_token","account_id"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/capacity/codex.ts"],"sourcesContent":["import { spawn } from \"node:child_process\";\nimport { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type { CapacityReport, CapacityWindow } from \"./types.js\";\n\ntype CodexUsageSource = \"pat\" | \"oauth\" | \"cli\";\ntype UsageSnapshot = {\n windows: CapacityWindow[];\n creditsRemaining: number | null;\n source: CodexUsageSource;\n};\n\ntype UnknownRecord = Record<string, unknown>;\ntype RpcMessage = { id?: number; method: string; params?: UnknownRecord };\ntype CliResponses = { rateLimits: unknown; account: unknown };\ntype CodexRpc = (messages: RpcMessage[]) => Promise<CliResponses>;\n\nexport const CODEX_APP_SERVER_ARGS = [\"-s\", \"read-only\", \"-a\", \"untrusted\", \"app-server\"] as const;\n\ntype CodexProbeOptions = {\n installed: boolean;\n checkedAt: string;\n readFile?: (path: string, encoding: BufferEncoding) => Promise<string>;\n fetch?: typeof globalThis.fetch;\n rpc?: CodexRpc;\n timeoutMs?: number;\n env?: NodeJS.ProcessEnv;\n now?: () => Date;\n};\n\nfunction record(value: unknown): UnknownRecord | null {\n return value !== null && typeof value === \"object\" && !Array.isArray(value)\n ? (value as UnknownRecord)\n : null;\n}\n\nfunction finiteNumber(value: unknown): number | null {\n return typeof value === \"number\" && Number.isFinite(value) ? value : null;\n}\n\nfunction nonEmptyText(value: unknown): string | null {\n return typeof value === \"string\" && value.length > 0 ? value : null;\n}\n\nfunction resetTime(value: unknown): string | null {\n const seconds = finiteNumber(value);\n if (seconds !== null) return new Date(seconds * 1000).toISOString();\n if (typeof value === \"string\" && !Number.isNaN(Date.parse(value)))\n return new Date(value).toISOString();\n return null;\n}\n\nfunction safeIdentifier(value: unknown): string | null {\n const candidate = nonEmptyText(value);\n if (!candidate || !/^[a-z][a-z0-9_-]{0,63}$/i.test(candidate)) return null;\n if (/(?:account|token|secret|key)[_-]?\\d{6,}/i.test(candidate)) return null;\n return candidate;\n}\n\nexport function resolveCodexAuthPath(env: NodeJS.ProcessEnv = process.env): string {\n const root = env.CODEX_HOME || join(env.HOME || \"\", \".codex\");\n return join(root, \"auth.json\");\n}\n\nexport function toRateWindow(value: unknown, id: string, label: string): CapacityWindow | null {\n const input = record(value);\n if (!input) return null;\n const used = finiteNumber(input.used_percent);\n const seconds = finiteNumber(input.limit_window_seconds);\n return {\n id,\n label,\n durationMinutes: seconds === null ? null : seconds / 60,\n usedPercent: used,\n resetsAt: resetTime(input.reset_at),\n };\n}\n\nfunction extraWindows(value: unknown): CapacityWindow[] {\n if (!Array.isArray(value)) return [];\n return value.flatMap((entry, index) => {\n const limit = record(entry);\n if (!limit) return [];\n const scope = safeIdentifier(limit.limit_name) ?? `extra-${index + 1}`;\n const windows = record(limit.rate_limit) ?? limit;\n return [\n toRateWindow(windows.primary_window, `${scope}:primary`, `${scope} primary`),\n toRateWindow(windows.secondary_window, `${scope}:secondary`, `${scope} secondary`),\n ].filter((window): window is CapacityWindow => window !== null);\n });\n}\n\nexport function parseUsage(raw: unknown, source: \"pat\" | \"oauth\"): UsageSnapshot {\n const response = record(raw) ?? {};\n const limits = record(response.rate_limit) ?? {};\n const credits = record(response.credits) ?? {};\n return {\n windows: [\n toRateWindow(limits.primary_window, \"session\", \"Session\"),\n toRateWindow(limits.secondary_window, \"weekly\", \"Weekly\"),\n ...extraWindows(response.additional_rate_limits),\n ].filter((window): window is CapacityWindow => window !== null),\n creditsRemaining: finiteNumber(credits.balance),\n source,\n };\n}\n\nfunction cliWindow(value: unknown, id: string, label: string): CapacityWindow | null {\n const input = record(value);\n if (!input) return null;\n return {\n id,\n label,\n durationMinutes: finiteNumber(input.windowDurationMins),\n usedPercent: finiteNumber(input.usedPercent),\n resetsAt: resetTime(input.resetsAt),\n };\n}\n\nfunction cliSnapshotWindows(value: unknown, fallbackId: string): CapacityWindow[] {\n const snapshot = record(value);\n if (!snapshot) return [];\n const scope = safeIdentifier(snapshot.limitId) ?? safeIdentifier(fallbackId) ?? \"codex\";\n return [\n cliWindow(snapshot.primary, `${scope}:primary`, `${scope} primary`),\n cliWindow(snapshot.secondary, `${scope}:secondary`, `${scope} secondary`),\n ].filter((item): item is CapacityWindow => item !== null);\n}\n\nexport function parseCliUsage(raw: unknown): UsageSnapshot {\n const response = record(raw) ?? {};\n const primary = record(response.rateLimits);\n const windows = primary ? cliSnapshotWindows(primary, \"codex\") : [];\n const buckets = record(response.rateLimitsByLimitId);\n if (buckets) {\n for (const [id, snapshot] of Object.entries(buckets))\n windows.push(...cliSnapshotWindows(snapshot, id));\n }\n const unique = [...new Map(windows.map((window) => [window.id, window])).values()];\n return { windows: unique, creditsRemaining: null, source: \"cli\" };\n}\n\nfunction capacityFromSnapshot(\n snapshot: UsageSnapshot,\n context: CodexProbeOptions,\n raw?: unknown,\n): CapacityReport {\n const hasUsage = snapshot.windows.some((window) => window.usedPercent !== null);\n const rateLimits = record(record(raw)?.rateLimits);\n const reached = nonEmptyText(rateLimits?.rateLimitReachedType);\n const resetCredits =\n record(record(raw)?.rateLimitResetCredits) ?? record(record(raw)?.usageLimitResetCredits);\n return {\n provider: \"codex\",\n generatedAt: context.checkedAt,\n authenticated: true,\n available: reached ? \"no\" : hasUsage ? \"yes\" : \"unknown\",\n windows: snapshot.windows,\n creditsRemaining: snapshot.creditsRemaining ?? finiteNumber(resetCredits?.availableCount),\n };\n}\n\nfunction jwtExpiry(token: string): number | null {\n const part = token.split(\".\")[1];\n if (!part) return null;\n try {\n return finiteNumber(record(JSON.parse(Buffer.from(part, \"base64url\").toString(\"utf8\")))?.exp);\n } catch {\n return null;\n }\n}\n\nfunction staleOAuth(tokens: UnknownRecord, token: string, now: Date): boolean {\n const metadata = tokens.expires_at ?? tokens.expiresAt ?? tokens.expiry;\n let expiry: number | null = finiteNumber(metadata);\n if (typeof metadata === \"string\") {\n const parsed = Date.parse(metadata);\n expiry = Number.isNaN(parsed) ? null : parsed / 1000;\n }\n expiry ??= jwtExpiry(token);\n return expiry !== null && expiry <= now.getTime() / 1000;\n}\n\nasync function fetchJson(\n fetcher: typeof globalThis.fetch,\n url: string,\n init: RequestInit,\n timeoutMs: number,\n): Promise<unknown> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n try {\n const response = await fetcher(url, { ...init, signal: controller.signal });\n if (!response.ok) throw new Error(response.status === 401 ? \"unauthorized\" : \"request failed\");\n return await response.json();\n } finally {\n clearTimeout(timer);\n }\n}\n\nasync function apiSnapshot(\n token: string,\n accountId: string,\n source: \"pat\" | \"oauth\",\n options: CodexProbeOptions,\n): Promise<UsageSnapshot> {\n const fetcher = options.fetch ?? globalThis.fetch;\n const raw = await fetchJson(\n fetcher,\n \"https://chatgpt.com/backend-api/wham/usage\",\n {\n headers: { Authorization: `Bearer ${token}`, \"ChatGPT-Account-Id\": accountId },\n },\n options.timeoutMs ?? 5000,\n );\n return parseUsage(raw, source);\n}\n\nfunction appServerRpc(messages: RpcMessage[], timeoutMs = 5000): Promise<CliResponses> {\n return new Promise((resolve, reject) => {\n const child = spawn(\"codex\", CODEX_APP_SERVER_ARGS, {\n stdio: [\"pipe\", \"pipe\", \"ignore\"],\n });\n const results: Partial<CliResponses> = {};\n let buffer = \"\";\n let settled = false;\n const finish = (error?: Error) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n child.kill();\n if (error) reject(error);\n else resolve(results as CliResponses);\n };\n const timer = setTimeout(() => finish(new Error(\"codex probe timed out\")), timeoutMs);\n child.once(\"error\", () => finish(new Error(\"codex app-server unavailable\")));\n child.once(\"exit\", () => {\n if (!settled) finish(new Error(\"codex app-server exited\"));\n });\n child.stdout.setEncoding(\"utf8\");\n child.stdout.on(\"data\", (chunk: string) => {\n buffer += chunk;\n for (;;) {\n const newline = buffer.indexOf(\"\\n\");\n if (newline < 0) break;\n const line = buffer.slice(0, newline).trim();\n buffer = buffer.slice(newline + 1);\n if (!line) continue;\n let message: UnknownRecord;\n try {\n message = JSON.parse(line) as UnknownRecord;\n } catch {\n continue;\n }\n if (message.id === 1) {\n for (const request of messages.slice(1))\n child.stdin.write(`${JSON.stringify(request)}\\n`);\n } else if (message.id === 2) {\n if (message.error) finish(new Error(\"codex rate-limit method failed\"));\n else results.rateLimits = message.result;\n } else if (message.id === 3) {\n if (message.error) finish(new Error(\"codex account method failed\"));\n else results.account = message.result;\n }\n if (\"rateLimits\" in results && \"account\" in results) finish();\n }\n });\n child.stdin.write(`${JSON.stringify(messages[0])}\\n`);\n });\n}\n\nfunction unavailable(options: CodexProbeOptions): CapacityReport {\n return {\n provider: \"codex\",\n generatedAt: options.checkedAt,\n authenticated: null,\n available: \"unknown\",\n windows: [],\n creditsRemaining: null,\n };\n}\n\nasync function cliFallback(options: CodexProbeOptions): Promise<CapacityReport> {\n if (!options.installed) return unavailable(options);\n const messages: RpcMessage[] = [\n {\n id: 1,\n method: \"initialize\",\n params: {\n clientInfo: { name: \"ai-devkit\", title: null, version: \"1\" },\n capabilities: null,\n },\n },\n { method: \"initialized\" },\n { id: 2, method: \"account/rateLimits/read\" },\n { id: 3, method: \"account/read\" },\n ];\n try {\n const rpc = options.rpc ?? ((requests) => appServerRpc(requests, options.timeoutMs));\n const response = await rpc(messages);\n const result = capacityFromSnapshot(\n parseCliUsage(response.rateLimits),\n options,\n response.rateLimits,\n );\n const accountEnvelope = record(response.account);\n if (\n accountEnvelope &&\n Object.hasOwn(accountEnvelope, \"account\") &&\n !record(accountEnvelope.account)\n ) {\n result.authenticated = false;\n result.available = \"unknown\";\n }\n return result;\n } catch {\n return unavailable(options);\n }\n}\n\nexport async function probeCodexCapacity(options: CodexProbeOptions): Promise<CapacityReport> {\n let parsed: UnknownRecord | null = null;\n try {\n const contents = await (options.readFile ?? readFile)(\n resolveCodexAuthPath(options.env),\n \"utf8\",\n );\n parsed = record(JSON.parse(contents));\n } catch {\n return cliFallback(options);\n }\n\n const auth = parsed ?? {};\n const pat = nonEmptyText(auth.personal_access_token);\n if (pat) {\n try {\n const fetcher = options.fetch ?? globalThis.fetch;\n const whoami = record(\n await fetchJson(\n fetcher,\n \"https://auth.openai.com/api/accounts/v1/user-auth-credential/whoami\",\n { headers: { Authorization: `Bearer ${pat}` } },\n options.timeoutMs ?? 5000,\n ),\n );\n const accountId = nonEmptyText(whoami?.chatgpt_account_id);\n if (!accountId) throw new Error(\"account unavailable\");\n return capacityFromSnapshot(await apiSnapshot(pat, accountId, \"pat\", options), options);\n } catch {\n // Continue to a separately available OAuth credential before using the CLI.\n }\n }\n\n const tokens = record(auth.tokens);\n const accessToken = nonEmptyText(tokens?.access_token);\n const accountId = nonEmptyText(tokens?.account_id);\n if (\n tokens &&\n accessToken &&\n accountId &&\n !staleOAuth(tokens, accessToken, (options.now ?? (() => new Date()))())\n ) {\n try {\n return capacityFromSnapshot(\n await apiSnapshot(accessToken, accountId, \"oauth\", options),\n options,\n );\n } catch {\n return cliFallback(options);\n }\n }\n return cliFallback(options);\n}\n"],"names":["spawn","readFile","join","CODEX_APP_SERVER_ARGS","record","value","Array","isArray","finiteNumber","Number","isFinite","nonEmptyText","length","resetTime","seconds","Date","toISOString","isNaN","parse","safeIdentifier","candidate","test","resolveCodexAuthPath","env","process","root","CODEX_HOME","HOME","toRateWindow","id","label","input","used","used_percent","limit_window_seconds","durationMinutes","usedPercent","resetsAt","reset_at","extraWindows","flatMap","entry","index","limit","scope","limit_name","windows","rate_limit","primary_window","secondary_window","filter","window","parseUsage","raw","source","response","limits","credits","additional_rate_limits","creditsRemaining","balance","cliWindow","windowDurationMins","cliSnapshotWindows","fallbackId","snapshot","limitId","primary","secondary","item","parseCliUsage","rateLimits","buckets","rateLimitsByLimitId","Object","entries","push","unique","Map","map","values","capacityFromSnapshot","context","hasUsage","some","reached","rateLimitReachedType","resetCredits","rateLimitResetCredits","usageLimitResetCredits","provider","generatedAt","checkedAt","authenticated","available","availableCount","jwtExpiry","token","part","split","JSON","Buffer","from","toString","exp","staleOAuth","tokens","now","metadata","expires_at","expiresAt","expiry","parsed","getTime","fetchJson","fetcher","url","init","timeoutMs","controller","AbortController","timer","setTimeout","abort","signal","ok","Error","status","json","clearTimeout","apiSnapshot","accountId","options","fetch","globalThis","headers","Authorization","appServerRpc","messages","Promise","resolve","reject","child","stdio","results","buffer","settled","finish","error","kill","once","stdout","setEncoding","on","chunk","newline","indexOf","line","slice","trim","message","request","stdin","write","stringify","result","account","unavailable","cliFallback","installed","method","params","clientInfo","name","title","version","capabilities","rpc","requests","accountEnvelope","hasOwn","probeCodexCapacity","contents","auth","pat","personal_access_token","whoami","chatgpt_account_id","accessToken","access_token","account_id"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
- import { probeCodexCapacity } from './codex.js';
2
- import type { CapacityReport } from './types.js';
3
- export type { CapacityReport, CapacityWindow } from './types.js';
1
+ import { probeCodexCapacity } from "./codex.js";
2
+ import type { CapacityReport } from "./types.js";
3
+ export type { CapacityReport, CapacityWindow } from "./types.js";
4
4
  export type CapacityProbeOptions = {
5
5
  now?: () => Date;
6
6
  path?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/capacity/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjE,MAAM,MAAM,oBAAoB,GAAG;IACjC,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C,KAAK,CAAC,EAAE,OAAO,kBAAkB,CAAC;CACnC,CAAC;AA4BF,wBAAsB,sBAAsB,CAAC,OAAO,GAAE,oBAAyB,GAAG,OAAO,CAAC,cAAc,CAAC,CAexG"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/capacity/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjE,MAAM,MAAM,oBAAoB,GAAG;IACjC,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C,KAAK,CAAC,EAAE,OAAO,kBAAkB,CAAC;CACnC,CAAC;AA+BF,wBAAsB,sBAAsB,CAC1C,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,cAAc,CAAC,CAezB"}
@@ -1,7 +1,7 @@
1
- import { constants } from 'node:fs';
2
- import { access as fsAccess } from 'node:fs/promises';
3
- import path from 'node:path';
4
- import { probeCodexCapacity } from './codex.js';
1
+ import { constants } from "node:fs";
2
+ import { access as fsAccess } from "node:fs/promises";
3
+ import path from "node:path";
4
+ import { probeCodexCapacity } from "./codex.js";
5
5
  async function canAccess(target, mode) {
6
6
  try {
7
7
  await fsAccess(target, mode);
@@ -13,7 +13,7 @@ async function canAccess(target, mode) {
13
13
  async function isCodexInstalled(pathValue, checkAccess) {
14
14
  const directories = pathValue.split(path.delimiter).filter(Boolean);
15
15
  for (const directory of directories){
16
- const executable = path.join(directory, 'codex');
16
+ const executable = path.join(directory, "codex");
17
17
  if (checkAccess) {
18
18
  try {
19
19
  await checkAccess(executable);
@@ -28,7 +28,7 @@ async function isCodexInstalled(pathValue, checkAccess) {
28
28
  }
29
29
  export async function getCodexCapacityReport(options = {}) {
30
30
  const generatedAt = (options.now?.() ?? new Date()).toISOString();
31
- const installed = await isCodexInstalled(options.path ?? process.env.PATH ?? '', options.access);
31
+ const installed = await isCodexInstalled(options.path ?? process.env.PATH ?? "", options.access);
32
32
  try {
33
33
  return await (options.probe ?? probeCodexCapacity)({
34
34
  installed,
@@ -36,10 +36,10 @@ export async function getCodexCapacityReport(options = {}) {
36
36
  });
37
37
  } catch {
38
38
  return {
39
- provider: 'codex',
39
+ provider: "codex",
40
40
  generatedAt,
41
41
  authenticated: null,
42
- available: 'unknown',
42
+ available: "unknown",
43
43
  windows: [],
44
44
  creditsRemaining: null
45
45
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/capacity/index.ts"],"sourcesContent":["import { constants } from 'node:fs';\nimport { access as fsAccess } from 'node:fs/promises';\nimport path from 'node:path';\nimport { probeCodexCapacity } from './codex.js';\nimport type { CapacityReport } from './types.js';\n\nexport type { CapacityReport, CapacityWindow } from './types.js';\n\nexport type CapacityProbeOptions = {\n now?: () => Date;\n path?: string;\n access?: (target: string) => Promise<void>;\n probe?: typeof probeCodexCapacity;\n};\n\nasync function canAccess(target: string, mode: number): Promise<boolean> {\n try {\n await fsAccess(target, mode);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function isCodexInstalled(pathValue: string, checkAccess?: (target: string) => Promise<void>): Promise<boolean> {\n const directories = pathValue.split(path.delimiter).filter(Boolean);\n for (const directory of directories) {\n const executable = path.join(directory, 'codex');\n if (checkAccess) {\n try {\n await checkAccess(executable);\n return true;\n } catch {\n continue;\n }\n }\n if (await canAccess(executable, constants.X_OK)) return true;\n }\n return false;\n}\n\nexport async function getCodexCapacityReport(options: CapacityProbeOptions = {}): Promise<CapacityReport> {\n const generatedAt = (options.now?.() ?? new Date()).toISOString();\n const installed = await isCodexInstalled(options.path ?? process.env.PATH ?? '', options.access);\n try {\n return await (options.probe ?? probeCodexCapacity)({ installed, checkedAt: generatedAt });\n } catch {\n return {\n provider: 'codex',\n generatedAt,\n authenticated: null,\n available: 'unknown',\n windows: [],\n creditsRemaining: null\n };\n }\n}\n"],"names":["constants","access","fsAccess","path","probeCodexCapacity","canAccess","target","mode","isCodexInstalled","pathValue","checkAccess","directories","split","delimiter","filter","Boolean","directory","executable","join","X_OK","getCodexCapacityReport","options","generatedAt","now","Date","toISOString","installed","process","env","PATH","probe","checkedAt","provider","authenticated","available","windows","creditsRemaining"],"mappings":"AAAA,SAASA,SAAS,QAAQ,UAAU;AACpC,SAASC,UAAUC,QAAQ,QAAQ,mBAAmB;AACtD,OAAOC,UAAU,YAAY;AAC7B,SAASC,kBAAkB,QAAQ,aAAa;AAYhD,eAAeC,UAAUC,MAAc,EAAEC,IAAY;IACnD,IAAI;QACF,MAAML,SAASI,QAAQC;QACvB,OAAO;IACT,EAAE,OAAM;QACN,OAAO;IACT;AACF;AAEA,eAAeC,iBAAiBC,SAAiB,EAAEC,WAA+C;IAChG,MAAMC,cAAcF,UAAUG,KAAK,CAACT,KAAKU,SAAS,EAAEC,MAAM,CAACC;IAC3D,KAAK,MAAMC,aAAaL,YAAa;QACnC,MAAMM,aAAad,KAAKe,IAAI,CAACF,WAAW;QACxC,IAAIN,aAAa;YACf,IAAI;gBACF,MAAMA,YAAYO;gBAClB,OAAO;YACT,EAAE,OAAM;gBACN;YACF;QACF;QACA,IAAI,MAAMZ,UAAUY,YAAYjB,UAAUmB,IAAI,GAAG,OAAO;IAC1D;IACA,OAAO;AACT;AAEA,OAAO,eAAeC,uBAAuBC,UAAgC,CAAC,CAAC;IAC7E,MAAMC,cAAc,AAACD,CAAAA,QAAQE,GAAG,QAAQ,IAAIC,MAAK,EAAGC,WAAW;IAC/D,MAAMC,YAAY,MAAMlB,iBAAiBa,QAAQlB,IAAI,IAAIwB,QAAQC,GAAG,CAACC,IAAI,IAAI,IAAIR,QAAQpB,MAAM;IAC/F,IAAI;QACF,OAAO,MAAM,AAACoB,CAAAA,QAAQS,KAAK,IAAI1B,kBAAiB,EAAG;YAAEsB;YAAWK,WAAWT;QAAY;IACzF,EAAE,OAAM;QACN,OAAO;YACLU,UAAU;YACVV;YACAW,eAAe;YACfC,WAAW;YACXC,SAAS,EAAE;YACXC,kBAAkB;QACpB;IACF;AACF"}
1
+ {"version":3,"sources":["../../src/capacity/index.ts"],"sourcesContent":["import { constants } from \"node:fs\";\nimport { access as fsAccess } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { probeCodexCapacity } from \"./codex.js\";\nimport type { CapacityReport } from \"./types.js\";\n\nexport type { CapacityReport, CapacityWindow } from \"./types.js\";\n\nexport type CapacityProbeOptions = {\n now?: () => Date;\n path?: string;\n access?: (target: string) => Promise<void>;\n probe?: typeof probeCodexCapacity;\n};\n\nasync function canAccess(target: string, mode: number): Promise<boolean> {\n try {\n await fsAccess(target, mode);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function isCodexInstalled(\n pathValue: string,\n checkAccess?: (target: string) => Promise<void>,\n): Promise<boolean> {\n const directories = pathValue.split(path.delimiter).filter(Boolean);\n for (const directory of directories) {\n const executable = path.join(directory, \"codex\");\n if (checkAccess) {\n try {\n await checkAccess(executable);\n return true;\n } catch {\n continue;\n }\n }\n if (await canAccess(executable, constants.X_OK)) return true;\n }\n return false;\n}\n\nexport async function getCodexCapacityReport(\n options: CapacityProbeOptions = {},\n): Promise<CapacityReport> {\n const generatedAt = (options.now?.() ?? new Date()).toISOString();\n const installed = await isCodexInstalled(options.path ?? process.env.PATH ?? \"\", options.access);\n try {\n return await (options.probe ?? probeCodexCapacity)({ installed, checkedAt: generatedAt });\n } catch {\n return {\n provider: \"codex\",\n generatedAt,\n authenticated: null,\n available: \"unknown\",\n windows: [],\n creditsRemaining: null,\n };\n }\n}\n"],"names":["constants","access","fsAccess","path","probeCodexCapacity","canAccess","target","mode","isCodexInstalled","pathValue","checkAccess","directories","split","delimiter","filter","Boolean","directory","executable","join","X_OK","getCodexCapacityReport","options","generatedAt","now","Date","toISOString","installed","process","env","PATH","probe","checkedAt","provider","authenticated","available","windows","creditsRemaining"],"mappings":"AAAA,SAASA,SAAS,QAAQ,UAAU;AACpC,SAASC,UAAUC,QAAQ,QAAQ,mBAAmB;AACtD,OAAOC,UAAU,YAAY;AAC7B,SAASC,kBAAkB,QAAQ,aAAa;AAYhD,eAAeC,UAAUC,MAAc,EAAEC,IAAY;IACnD,IAAI;QACF,MAAML,SAASI,QAAQC;QACvB,OAAO;IACT,EAAE,OAAM;QACN,OAAO;IACT;AACF;AAEA,eAAeC,iBACbC,SAAiB,EACjBC,WAA+C;IAE/C,MAAMC,cAAcF,UAAUG,KAAK,CAACT,KAAKU,SAAS,EAAEC,MAAM,CAACC;IAC3D,KAAK,MAAMC,aAAaL,YAAa;QACnC,MAAMM,aAAad,KAAKe,IAAI,CAACF,WAAW;QACxC,IAAIN,aAAa;YACf,IAAI;gBACF,MAAMA,YAAYO;gBAClB,OAAO;YACT,EAAE,OAAM;gBACN;YACF;QACF;QACA,IAAI,MAAMZ,UAAUY,YAAYjB,UAAUmB,IAAI,GAAG,OAAO;IAC1D;IACA,OAAO;AACT;AAEA,OAAO,eAAeC,uBACpBC,UAAgC,CAAC,CAAC;IAElC,MAAMC,cAAc,AAACD,CAAAA,QAAQE,GAAG,QAAQ,IAAIC,MAAK,EAAGC,WAAW;IAC/D,MAAMC,YAAY,MAAMlB,iBAAiBa,QAAQlB,IAAI,IAAIwB,QAAQC,GAAG,CAACC,IAAI,IAAI,IAAIR,QAAQpB,MAAM;IAC/F,IAAI;QACF,OAAO,MAAM,AAACoB,CAAAA,QAAQS,KAAK,IAAI1B,kBAAiB,EAAG;YAAEsB;YAAWK,WAAWT;QAAY;IACzF,EAAE,OAAM;QACN,OAAO;YACLU,UAAU;YACVV;YACAW,eAAe;YACfC,WAAW;YACXC,SAAS,EAAE;YACXC,kBAAkB;QACpB;IACF;AACF"}
@@ -1,4 +1,4 @@
1
- export type Availability = 'yes' | 'no' | 'unknown';
1
+ export type Availability = "yes" | "no" | "unknown";
2
2
  export interface CapacityWindow {
3
3
  id: string;
4
4
  label: string;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/capacity/types.ts"],"sourcesContent":["export type Availability = 'yes' | 'no' | 'unknown';\n\nexport interface CapacityWindow {\n id: string;\n label: string;\n durationMinutes: number | null;\n usedPercent: number | null;\n resetsAt: string | null;\n}\n\nexport interface CapacityReport {\n provider: string;\n generatedAt: string;\n authenticated: boolean | null;\n available: Availability;\n windows: CapacityWindow[];\n creditsRemaining: number | null;\n}\n"],"names":[],"mappings":"AAUA,WAOC"}
1
+ {"version":3,"sources":["../../src/capacity/types.ts"],"sourcesContent":["export type Availability = \"yes\" | \"no\" | \"unknown\";\n\nexport interface CapacityWindow {\n id: string;\n label: string;\n durationMinutes: number | null;\n usedPercent: number | null;\n resetsAt: string | null;\n}\n\nexport interface CapacityReport {\n provider: string;\n generatedAt: string;\n authenticated: boolean | null;\n available: Availability;\n windows: CapacityWindow[];\n creditsRemaining: number | null;\n}\n"],"names":[],"mappings":"AAUA,WAOC"}
@@ -1,4 +1,4 @@
1
- import Database from 'better-sqlite3';
1
+ import Database from "better-sqlite3";
2
2
  export declare const DEFAULT_AGENT_REGISTRY_DB_PATH: string;
3
3
  export interface DatabaseOptions {
4
4
  dbPath?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../src/database/connection.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAMtC,eAAO,MAAM,8BAA8B,QAA6C,CAAC;AAEzF,MAAM,WAAW,eAAe;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC,CAAC;IAChD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,wBAAgB,0BAA0B,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAGpE;AAED,qBAAa,kBAAkB;IAC3B,OAAO,CAAC,EAAE,CAAoB;IAC9B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAU;gBAEvB,OAAO,GAAE,eAAoB;IA4BzC,OAAO,CAAC,SAAS;IASjB,IAAI,QAAQ,IAAI,QAAQ,CAAC,QAAQ,CAEhC;IAED,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,KAAK,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,OAAO,EAAO,GAAG,CAAC,EAAE;IAIlD,QAAQ,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,OAAO,EAAO,GAAG,CAAC,GAAG,SAAS;IAI/D,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,OAAO,EAAO,GAAG,QAAQ,CAAC,SAAS;IAIhE,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC;IAI9B,KAAK,IAAI,IAAI;CAKhB"}
1
+ {"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../src/database/connection.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAMtC,eAAO,MAAM,8BAA8B,QAA6C,CAAC;AAEzF,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC,CAAC;IAChD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,0BAA0B,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAGpE;AAED,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,EAAE,CAAoB;IAC9B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAU;gBAEvB,OAAO,GAAE,eAAoB;IAiCzC,OAAO,CAAC,SAAS;IASjB,IAAI,QAAQ,IAAI,QAAQ,CAAC,QAAQ,CAEhC;IAED,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,KAAK,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,OAAO,EAAO,GAAG,CAAC,EAAE;IAIlD,QAAQ,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,OAAO,EAAO,GAAG,CAAC,GAAG,SAAS;IAI/D,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,OAAO,EAAO,GAAG,QAAQ,CAAC,SAAS;IAIhE,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC;IAI9B,KAAK,IAAI,IAAI;CAKd"}
@@ -1,12 +1,12 @@
1
- import Database from 'better-sqlite3';
2
- import { existsSync, mkdirSync } from 'fs';
3
- import { dirname, join } from 'path';
4
- import { homedir } from 'os';
5
- import { initializeSchema } from './schema.js';
6
- export const DEFAULT_AGENT_REGISTRY_DB_PATH = join(homedir(), '.ai-devkit', 'agents.db');
1
+ import Database from "better-sqlite3";
2
+ import { existsSync, mkdirSync } from "fs";
3
+ import { dirname, join } from "path";
4
+ import { homedir } from "os";
5
+ import { initializeSchema } from "./schema.js";
6
+ export const DEFAULT_AGENT_REGISTRY_DB_PATH = join(homedir(), ".ai-devkit", "agents.db");
7
7
  export function resolveAgentRegistryDbPath(filePath) {
8
8
  if (!filePath) return DEFAULT_AGENT_REGISTRY_DB_PATH;
9
- return filePath.endsWith('.json') ? filePath.replace(/\.json$/, '.db') : filePath;
9
+ return filePath.endsWith(".json") ? filePath.replace(/\.json$/, ".db") : filePath;
10
10
  }
11
11
  export class DatabaseConnection {
12
12
  db;
@@ -24,10 +24,10 @@ export class DatabaseConnection {
24
24
  this.db = new Database(this.dbPath, {
25
25
  readonly: this.readonly,
26
26
  timeout: 5000,
27
- verbose: typeof options.verbose === 'function' ? options.verbose : options.verbose ? console.log : undefined
27
+ verbose: typeof options.verbose === "function" ? options.verbose : options.verbose ? console.log : undefined
28
28
  });
29
29
  if (this.readonly) {
30
- const version = this.db.pragma('user_version', {
30
+ const version = this.db.pragma("user_version", {
31
31
  simple: true
32
32
  });
33
33
  if (version < 3) {
@@ -40,14 +40,14 @@ export class DatabaseConnection {
40
40
  }
41
41
  }
42
42
  configure() {
43
- const journalMode = this.db.pragma('journal_mode', {
43
+ const journalMode = this.db.pragma("journal_mode", {
44
44
  simple: true
45
45
  });
46
- if (journalMode.toLowerCase() !== 'wal') this.db.pragma('journal_mode = WAL');
47
- this.db.pragma('foreign_keys = ON');
48
- this.db.pragma('synchronous = NORMAL');
49
- this.db.pragma('busy_timeout = 5000');
50
- this.db.pragma('mmap_size = 268435456');
46
+ if (journalMode.toLowerCase() !== "wal") this.db.pragma("journal_mode = WAL");
47
+ this.db.pragma("foreign_keys = ON");
48
+ this.db.pragma("synchronous = NORMAL");
49
+ this.db.pragma("busy_timeout = 5000");
50
+ this.db.pragma("mmap_size = 268435456");
51
51
  }
52
52
  get instance() {
53
53
  return this.db;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/database/connection.ts"],"sourcesContent":["import Database from 'better-sqlite3';\nimport { existsSync, mkdirSync } from 'fs';\nimport { dirname, join } from 'path';\nimport { homedir } from 'os';\nimport { initializeSchema } from './schema.js';\n\nexport const DEFAULT_AGENT_REGISTRY_DB_PATH = join(homedir(), '.ai-devkit', 'agents.db');\n\nexport interface DatabaseOptions {\n dbPath?: string;\n verbose?: boolean | ((message: string) => void);\n readonly?: boolean;\n}\n\nexport function resolveAgentRegistryDbPath(filePath?: string): string {\n if (!filePath) return DEFAULT_AGENT_REGISTRY_DB_PATH;\n return filePath.endsWith('.json') ? filePath.replace(/\\.json$/, '.db') : filePath;\n}\n\nexport class DatabaseConnection {\n private db: Database.Database;\n private readonly dbPath: string;\n private readonly readonly: boolean;\n\n constructor(options: DatabaseOptions = {}) {\n this.dbPath = options.dbPath ?? DEFAULT_AGENT_REGISTRY_DB_PATH;\n this.readonly = options.readonly ?? false;\n if (this.readonly && !existsSync(this.dbPath)) {\n throw new Error(`Cannot open readonly agent database because it does not exist: ${this.dbPath}`);\n }\n if (!this.readonly) mkdirSync(dirname(this.dbPath), { recursive: true });\n\n this.db = new Database(this.dbPath, {\n readonly: this.readonly,\n timeout: 5000,\n verbose: typeof options.verbose === 'function'\n ? options.verbose\n : options.verbose ? console.log : undefined,\n });\n\n if (this.readonly) {\n const version = this.db.pragma('user_version', { simple: true }) as number;\n if (version < 3) {\n this.db.close();\n throw new Error(`Readonly agent database requires schema version 3 (found ${version}).`);\n }\n } else {\n this.configure();\n initializeSchema(this);\n }\n }\n\n private configure(): void {\n const journalMode = this.db.pragma('journal_mode', { simple: true }) as string;\n if (journalMode.toLowerCase() !== 'wal') this.db.pragma('journal_mode = WAL');\n this.db.pragma('foreign_keys = ON');\n this.db.pragma('synchronous = NORMAL');\n this.db.pragma('busy_timeout = 5000');\n this.db.pragma('mmap_size = 268435456');\n }\n\n get instance(): Database.Database {\n return this.db;\n }\n\n get path(): string {\n return this.dbPath;\n }\n\n query<T>(sql: string, params: unknown[] = []): T[] {\n return this.db.prepare(sql).all(...params) as T[];\n }\n\n queryOne<T>(sql: string, params: unknown[] = []): T | undefined {\n return this.db.prepare(sql).get(...params) as T | undefined;\n }\n\n execute(sql: string, params: unknown[] = []): Database.RunResult {\n return this.db.prepare(sql).run(...params);\n }\n\n transaction<T>(fn: () => T): T {\n return this.db.transaction(fn)();\n }\n\n close(): void {\n if (this.db.open) {\n this.db.close();\n }\n }\n}\n"],"names":["Database","existsSync","mkdirSync","dirname","join","homedir","initializeSchema","DEFAULT_AGENT_REGISTRY_DB_PATH","resolveAgentRegistryDbPath","filePath","endsWith","replace","DatabaseConnection","db","dbPath","readonly","options","Error","recursive","timeout","verbose","console","log","undefined","version","pragma","simple","close","configure","journalMode","toLowerCase","instance","path","query","sql","params","prepare","all","queryOne","get","execute","run","transaction","fn","open"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/database/connection.ts"],"sourcesContent":["import Database from \"better-sqlite3\";\nimport { existsSync, mkdirSync } from \"fs\";\nimport { dirname, join } from \"path\";\nimport { homedir } from \"os\";\nimport { initializeSchema } from \"./schema.js\";\n\nexport const DEFAULT_AGENT_REGISTRY_DB_PATH = join(homedir(), \".ai-devkit\", \"agents.db\");\n\nexport interface DatabaseOptions {\n dbPath?: string;\n verbose?: boolean | ((message: string) => void);\n readonly?: boolean;\n}\n\nexport function resolveAgentRegistryDbPath(filePath?: string): string {\n if (!filePath) return DEFAULT_AGENT_REGISTRY_DB_PATH;\n return filePath.endsWith(\".json\") ? filePath.replace(/\\.json$/, \".db\") : filePath;\n}\n\nexport class DatabaseConnection {\n private db: Database.Database;\n private readonly dbPath: string;\n private readonly readonly: boolean;\n\n constructor(options: DatabaseOptions = {}) {\n this.dbPath = options.dbPath ?? DEFAULT_AGENT_REGISTRY_DB_PATH;\n this.readonly = options.readonly ?? false;\n if (this.readonly && !existsSync(this.dbPath)) {\n throw new Error(\n `Cannot open readonly agent database because it does not exist: ${this.dbPath}`,\n );\n }\n if (!this.readonly) mkdirSync(dirname(this.dbPath), { recursive: true });\n\n this.db = new Database(this.dbPath, {\n readonly: this.readonly,\n timeout: 5000,\n verbose:\n typeof options.verbose === \"function\"\n ? options.verbose\n : options.verbose\n ? console.log\n : undefined,\n });\n\n if (this.readonly) {\n const version = this.db.pragma(\"user_version\", { simple: true }) as number;\n if (version < 3) {\n this.db.close();\n throw new Error(`Readonly agent database requires schema version 3 (found ${version}).`);\n }\n } else {\n this.configure();\n initializeSchema(this);\n }\n }\n\n private configure(): void {\n const journalMode = this.db.pragma(\"journal_mode\", { simple: true }) as string;\n if (journalMode.toLowerCase() !== \"wal\") this.db.pragma(\"journal_mode = WAL\");\n this.db.pragma(\"foreign_keys = ON\");\n this.db.pragma(\"synchronous = NORMAL\");\n this.db.pragma(\"busy_timeout = 5000\");\n this.db.pragma(\"mmap_size = 268435456\");\n }\n\n get instance(): Database.Database {\n return this.db;\n }\n\n get path(): string {\n return this.dbPath;\n }\n\n query<T>(sql: string, params: unknown[] = []): T[] {\n return this.db.prepare(sql).all(...params) as T[];\n }\n\n queryOne<T>(sql: string, params: unknown[] = []): T | undefined {\n return this.db.prepare(sql).get(...params) as T | undefined;\n }\n\n execute(sql: string, params: unknown[] = []): Database.RunResult {\n return this.db.prepare(sql).run(...params);\n }\n\n transaction<T>(fn: () => T): T {\n return this.db.transaction(fn)();\n }\n\n close(): void {\n if (this.db.open) {\n this.db.close();\n }\n }\n}\n"],"names":["Database","existsSync","mkdirSync","dirname","join","homedir","initializeSchema","DEFAULT_AGENT_REGISTRY_DB_PATH","resolveAgentRegistryDbPath","filePath","endsWith","replace","DatabaseConnection","db","dbPath","readonly","options","Error","recursive","timeout","verbose","console","log","undefined","version","pragma","simple","close","configure","journalMode","toLowerCase","instance","path","query","sql","params","prepare","all","queryOne","get","execute","run","transaction","fn","open"],"mappings":"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"}