@ai-devkit/agent-manager 0.37.0 → 0.39.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 (357) hide show
  1. package/dist/AgentManager.d.ts +0 -4
  2. package/dist/AgentManager.d.ts.map +1 -1
  3. package/dist/AgentManager.js +2 -2
  4. package/dist/AgentManager.js.map +1 -1
  5. package/dist/__tests__/capacity/anthropic.test.js +115 -0
  6. package/dist/__tests__/capacity/anthropic.test.js.map +1 -0
  7. package/dist/__tests__/capacity/boundaries.test.js +45 -0
  8. package/dist/__tests__/capacity/boundaries.test.js.map +1 -0
  9. package/dist/__tests__/capacity/claude.test.js +3 -3
  10. package/dist/__tests__/capacity/claude.test.js.map +1 -1
  11. package/dist/__tests__/capacity/codex.test.js +3 -1
  12. package/dist/__tests__/capacity/codex.test.js.map +1 -1
  13. package/dist/__tests__/capacity/openai.test.js +21 -12
  14. package/dist/__tests__/capacity/openai.test.js.map +1 -1
  15. package/dist/__tests__/capacity/wham.test.js +1 -1
  16. package/dist/__tests__/capacity/wham.test.js.map +1 -1
  17. package/dist/__tests__/capacity/zai.test.js +7 -8
  18. package/dist/__tests__/capacity/zai.test.js.map +1 -1
  19. package/dist/__tests__/harnesses/claude/durable/ClaudePrintAgent.integration.test.js +2 -1
  20. package/dist/__tests__/harnesses/claude/durable/ClaudePrintAgent.integration.test.js.map +1 -1
  21. package/dist/__tests__/harnesses/claude/durable/ClaudePrintRunner.test.js.map +1 -1
  22. package/dist/__tests__/harnesses/codex/durable/CodexCliProbe.test.js +7 -15
  23. package/dist/__tests__/harnesses/codex/durable/CodexCliProbe.test.js.map +1 -1
  24. package/dist/__tests__/harnesses/codex/durable/CodexPrintAgent.integration.test.js +3 -1
  25. package/dist/__tests__/harnesses/codex/durable/CodexPrintAgent.integration.test.js.map +1 -1
  26. package/dist/__tests__/harnesses/codex/durable/CodexPrintAgentService.test.js +11 -26
  27. package/dist/__tests__/harnesses/codex/durable/CodexPrintAgentService.test.js.map +1 -1
  28. package/dist/__tests__/harnesses/codex/durable/CodexPrintRunner.test.js +3 -7
  29. package/dist/__tests__/harnesses/codex/durable/CodexPrintRunner.test.js.map +1 -1
  30. package/dist/__tests__/harnesses/devin/DevinAdapter.test.js +597 -0
  31. package/dist/__tests__/harnesses/devin/DevinAdapter.test.js.map +1 -0
  32. package/dist/__tests__/harnesses/devin/DevinAgentMapper.test.js +91 -0
  33. package/dist/__tests__/harnesses/devin/DevinAgentMapper.test.js.map +1 -0
  34. package/dist/__tests__/harnesses/devin/DevinSessionLocator.test.js +192 -0
  35. package/dist/__tests__/harnesses/devin/DevinSessionLocator.test.js.map +1 -0
  36. package/dist/__tests__/harnesses/devin/DevinSessionParser.test.js +407 -0
  37. package/dist/__tests__/harnesses/devin/DevinSessionParser.test.js.map +1 -0
  38. package/dist/__tests__/harnesses/devin/fixtures.js +95 -0
  39. package/dist/__tests__/harnesses/devin/fixtures.js.map +1 -0
  40. package/dist/__tests__/harnesses/pi/durable/PiCliProbe.test.js +5 -11
  41. package/dist/__tests__/harnesses/pi/durable/PiCliProbe.test.js.map +1 -1
  42. package/dist/__tests__/harnesses/pi/durable/PiPrintAgentService.test.js +9 -19
  43. package/dist/__tests__/harnesses/pi/durable/PiPrintAgentService.test.js.map +1 -1
  44. package/dist/__tests__/harnesses/pi/durable/PiPrintRunner.test.js +3 -7
  45. package/dist/__tests__/harnesses/pi/durable/PiPrintRunner.test.js.map +1 -1
  46. package/dist/__tests__/{readiness → harnesses/readiness}/AgentReadiness.test.js +95 -11
  47. package/dist/__tests__/harnesses/readiness/AgentReadiness.test.js.map +1 -0
  48. package/dist/__tests__/harnesses/runtimeProfiles.test.js +89 -0
  49. package/dist/__tests__/harnesses/runtimeProfiles.test.js.map +1 -0
  50. package/dist/__tests__/print/DurableAgent.test.js +4 -6
  51. package/dist/__tests__/print/DurableAgent.test.js.map +1 -1
  52. package/dist/__tests__/print/DurableAgentRepository.test.js +1 -12
  53. package/dist/__tests__/print/DurableAgentRepository.test.js.map +1 -1
  54. package/dist/__tests__/runtime/ManagedAgentRuntime.test.js.map +1 -1
  55. package/dist/__tests__/terminal/GhosttyBackend.test.js +334 -0
  56. package/dist/__tests__/terminal/GhosttyBackend.test.js.map +1 -0
  57. package/dist/__tests__/terminal/TmuxManager.test.js +1 -1
  58. package/dist/__tests__/terminal/TmuxManager.test.js.map +1 -1
  59. package/dist/adapters/AgentAdapter.d.ts +1 -1
  60. package/dist/adapters/AgentAdapter.d.ts.map +1 -1
  61. package/dist/adapters/AgentAdapter.js +2 -1
  62. package/dist/adapters/AgentAdapter.js.map +1 -1
  63. package/dist/capacity/index.d.ts +9 -19
  64. package/dist/capacity/index.d.ts.map +1 -1
  65. package/dist/capacity/index.js +11 -4
  66. package/dist/capacity/index.js.map +1 -1
  67. package/dist/capacity/providers/anthropic.d.ts +9 -0
  68. package/dist/capacity/providers/anthropic.d.ts.map +1 -0
  69. package/dist/capacity/{claude.js → providers/anthropic.js} +10 -128
  70. package/dist/capacity/providers/anthropic.js.map +1 -0
  71. package/dist/capacity/providers/openai-platform.d.ts +14 -0
  72. package/dist/capacity/providers/openai-platform.d.ts.map +1 -0
  73. package/dist/capacity/providers/openai-platform.js +120 -0
  74. package/dist/capacity/providers/openai-platform.js.map +1 -0
  75. package/dist/capacity/providers/openai-subscription.d.ts +20 -0
  76. package/dist/capacity/providers/openai-subscription.d.ts.map +1 -0
  77. package/dist/capacity/providers/openai-subscription.js +129 -0
  78. package/dist/capacity/providers/openai-subscription.js.map +1 -0
  79. package/dist/capacity/providers/zai.d.ts +8 -0
  80. package/dist/capacity/providers/zai.d.ts.map +1 -0
  81. package/dist/capacity/{zai.js → providers/zai.js} +17 -62
  82. package/dist/capacity/providers/zai.js.map +1 -0
  83. package/dist/capacity/sources/claude.d.ts +9 -0
  84. package/dist/capacity/sources/claude.d.ts.map +1 -0
  85. package/dist/capacity/sources/claude.js +17 -0
  86. package/dist/capacity/sources/claude.js.map +1 -0
  87. package/dist/capacity/{codex.d.ts → sources/codex.d.ts} +5 -9
  88. package/dist/capacity/sources/codex.d.ts.map +1 -0
  89. package/dist/capacity/{codex.js → sources/codex.js} +31 -84
  90. package/dist/capacity/sources/codex.js.map +1 -0
  91. package/dist/capacity/sources/pi.d.ts +30 -0
  92. package/dist/capacity/sources/pi.d.ts.map +1 -0
  93. package/dist/capacity/sources/pi.js +81 -0
  94. package/dist/capacity/sources/pi.js.map +1 -0
  95. package/dist/capacity/types.d.ts +2 -0
  96. package/dist/capacity/types.d.ts.map +1 -1
  97. package/dist/capacity/types.js +1 -1
  98. package/dist/capacity/types.js.map +1 -1
  99. package/dist/harnesses/claude/credentials.d.ts +10 -0
  100. package/dist/harnesses/claude/credentials.d.ts.map +1 -0
  101. package/dist/harnesses/claude/credentials.js +112 -0
  102. package/dist/harnesses/claude/credentials.js.map +1 -0
  103. package/dist/harnesses/claude/readiness.d.ts +3 -0
  104. package/dist/harnesses/claude/readiness.d.ts.map +1 -0
  105. package/dist/harnesses/claude/readiness.js +63 -0
  106. package/dist/harnesses/claude/readiness.js.map +1 -0
  107. package/dist/harnesses/codex/credentials.d.ts +15 -0
  108. package/dist/harnesses/codex/credentials.d.ts.map +1 -0
  109. package/dist/harnesses/codex/credentials.js +58 -0
  110. package/dist/harnesses/codex/credentials.js.map +1 -0
  111. package/dist/harnesses/codex/readiness.d.ts +3 -0
  112. package/dist/harnesses/codex/readiness.d.ts.map +1 -0
  113. package/dist/harnesses/codex/readiness.js +60 -0
  114. package/dist/harnesses/codex/readiness.js.map +1 -0
  115. package/dist/harnesses/copilot/readiness.d.ts +3 -0
  116. package/dist/harnesses/copilot/readiness.d.ts.map +1 -0
  117. package/dist/harnesses/copilot/readiness.js +39 -0
  118. package/dist/harnesses/copilot/readiness.js.map +1 -0
  119. package/dist/harnesses/devin/DevinAdapter.d.ts +39 -0
  120. package/dist/harnesses/devin/DevinAdapter.d.ts.map +1 -0
  121. package/dist/harnesses/devin/DevinAdapter.js +177 -0
  122. package/dist/harnesses/devin/DevinAdapter.js.map +1 -0
  123. package/dist/harnesses/devin/DevinAgentMapper.d.ts +11 -0
  124. package/dist/harnesses/devin/DevinAgentMapper.d.ts.map +1 -0
  125. package/dist/harnesses/devin/DevinAgentMapper.js +35 -0
  126. package/dist/harnesses/devin/DevinAgentMapper.js.map +1 -0
  127. package/dist/harnesses/devin/DevinSessionLocator.d.ts +46 -0
  128. package/dist/harnesses/devin/DevinSessionLocator.d.ts.map +1 -0
  129. package/dist/harnesses/devin/DevinSessionLocator.js +176 -0
  130. package/dist/harnesses/devin/DevinSessionLocator.js.map +1 -0
  131. package/dist/harnesses/devin/DevinSessionParser.d.ts +29 -0
  132. package/dist/harnesses/devin/DevinSessionParser.d.ts.map +1 -0
  133. package/dist/harnesses/devin/DevinSessionParser.js +166 -0
  134. package/dist/harnesses/devin/DevinSessionParser.js.map +1 -0
  135. package/dist/harnesses/devin/readiness.d.ts +3 -0
  136. package/dist/harnesses/devin/readiness.d.ts.map +1 -0
  137. package/dist/harnesses/devin/readiness.js +39 -0
  138. package/dist/harnesses/devin/readiness.js.map +1 -0
  139. package/dist/harnesses/index.d.ts.map +1 -1
  140. package/dist/harnesses/index.js +3 -1
  141. package/dist/harnesses/index.js.map +1 -1
  142. package/dist/harnesses/opencode/readiness.d.ts +3 -0
  143. package/dist/harnesses/opencode/readiness.d.ts.map +1 -0
  144. package/dist/harnesses/opencode/readiness.js +50 -0
  145. package/dist/harnesses/opencode/readiness.js.map +1 -0
  146. package/dist/harnesses/pi/credentials.d.ts +22 -0
  147. package/dist/harnesses/pi/credentials.d.ts.map +1 -0
  148. package/dist/harnesses/pi/credentials.js +98 -0
  149. package/dist/harnesses/pi/credentials.js.map +1 -0
  150. package/dist/harnesses/pi/readiness.d.ts +3 -0
  151. package/dist/harnesses/pi/readiness.d.ts.map +1 -0
  152. package/dist/harnesses/pi/readiness.js +96 -0
  153. package/dist/harnesses/pi/readiness.js.map +1 -0
  154. package/dist/harnesses/readiness/AgentReadiness.d.ts +6 -0
  155. package/dist/harnesses/readiness/AgentReadiness.d.ts.map +1 -0
  156. package/dist/harnesses/readiness/AgentReadiness.js +70 -0
  157. package/dist/harnesses/readiness/AgentReadiness.js.map +1 -0
  158. package/dist/harnesses/readiness/checks.d.ts +31 -0
  159. package/dist/harnesses/readiness/checks.d.ts.map +1 -0
  160. package/dist/harnesses/readiness/checks.js +270 -0
  161. package/dist/harnesses/readiness/checks.js.map +1 -0
  162. package/dist/{readiness/AgentReadiness.d.ts → harnesses/readiness/types.d.ts} +19 -10
  163. package/dist/harnesses/readiness/types.d.ts.map +1 -0
  164. package/dist/harnesses/readiness/types.js +4 -0
  165. package/dist/harnesses/readiness/types.js.map +1 -0
  166. package/dist/harnesses/runtimeProfiles.d.ts +11 -0
  167. package/dist/harnesses/runtimeProfiles.d.ts.map +1 -0
  168. package/dist/harnesses/runtimeProfiles.js +100 -0
  169. package/dist/harnesses/runtimeProfiles.js.map +1 -0
  170. package/dist/index.d.ts +16 -42
  171. package/dist/index.d.ts.map +1 -1
  172. package/dist/index.js +9 -23
  173. package/dist/index.js.map +1 -1
  174. package/dist/runtime/ManagedAgentRuntime.d.ts +3 -3
  175. package/dist/runtime/ManagedAgentRuntime.d.ts.map +1 -1
  176. package/dist/runtime/ManagedAgentRuntime.js +6 -20
  177. package/dist/runtime/ManagedAgentRuntime.js.map +1 -1
  178. package/dist/runtime/herdr/HerdrAgentDiscovery.d.ts.map +1 -1
  179. package/dist/runtime/herdr/HerdrAgentDiscovery.js +2 -43
  180. package/dist/runtime/herdr/HerdrAgentDiscovery.js.map +1 -1
  181. package/dist/runtime/tmux/PidPolling.d.ts +1 -1
  182. package/dist/runtime/tmux/PidPolling.d.ts.map +1 -1
  183. package/dist/runtime/tmux/PidPolling.js.map +1 -1
  184. package/dist/runtime/tmux/TmuxAgentRuntime.d.ts +1 -1
  185. package/dist/runtime/tmux/TmuxAgentRuntime.d.ts.map +1 -1
  186. package/dist/runtime/tmux/TmuxAgentRuntime.js +1 -1
  187. package/dist/runtime/tmux/TmuxAgentRuntime.js.map +1 -1
  188. package/dist/runtime/tmux/TmuxManager.d.ts +12 -0
  189. package/dist/runtime/tmux/TmuxManager.d.ts.map +1 -0
  190. package/dist/{terminal → runtime/tmux}/TmuxManager.js +9 -28
  191. package/dist/runtime/tmux/TmuxManager.js.map +1 -0
  192. package/dist/runtime/types.d.ts +1 -1
  193. package/dist/runtime/types.d.ts.map +1 -1
  194. package/dist/runtime/types.js.map +1 -1
  195. package/dist/terminal/TerminalFocusManager.d.ts +4 -32
  196. package/dist/terminal/TerminalFocusManager.d.ts.map +1 -1
  197. package/dist/terminal/TerminalFocusManager.js +17 -267
  198. package/dist/terminal/TerminalFocusManager.js.map +1 -1
  199. package/dist/terminal/TtyWriter.d.ts +1 -44
  200. package/dist/terminal/TtyWriter.d.ts.map +1 -1
  201. package/dist/terminal/TtyWriter.js +12 -347
  202. package/dist/terminal/TtyWriter.js.map +1 -1
  203. package/dist/terminal/backends/ghostty.d.ts +3 -0
  204. package/dist/terminal/backends/ghostty.d.ts.map +1 -0
  205. package/dist/terminal/backends/ghostty.js +161 -0
  206. package/dist/terminal/backends/ghostty.js.map +1 -0
  207. package/dist/terminal/backends/index.d.ts +5 -0
  208. package/dist/terminal/backends/index.d.ts.map +1 -0
  209. package/dist/terminal/backends/index.js +21 -0
  210. package/dist/terminal/backends/index.js.map +1 -0
  211. package/dist/terminal/backends/iterm2.d.ts +3 -0
  212. package/dist/terminal/backends/iterm2.d.ts.map +1 -0
  213. package/dist/terminal/backends/iterm2.js +135 -0
  214. package/dist/terminal/backends/iterm2.js.map +1 -0
  215. package/dist/terminal/backends/shared.d.ts +9 -0
  216. package/dist/terminal/backends/shared.d.ts.map +1 -0
  217. package/dist/terminal/backends/shared.js +38 -0
  218. package/dist/terminal/backends/shared.js.map +1 -0
  219. package/dist/terminal/backends/terminal-app.d.ts +3 -0
  220. package/dist/terminal/backends/terminal-app.d.ts.map +1 -0
  221. package/dist/terminal/backends/terminal-app.js +129 -0
  222. package/dist/terminal/backends/terminal-app.js.map +1 -0
  223. package/dist/terminal/backends/tmux.d.ts +3 -0
  224. package/dist/terminal/backends/tmux.d.ts.map +1 -0
  225. package/dist/terminal/backends/tmux.js +76 -0
  226. package/dist/terminal/backends/tmux.js.map +1 -0
  227. package/dist/terminal/backends/wezterm.d.ts +3 -0
  228. package/dist/terminal/backends/wezterm.d.ts.map +1 -0
  229. package/dist/terminal/backends/wezterm.js +71 -0
  230. package/dist/terminal/backends/wezterm.js.map +1 -0
  231. package/dist/terminal/types.d.ts +22 -0
  232. package/dist/terminal/types.d.ts.map +1 -0
  233. package/dist/terminal/types.js +11 -0
  234. package/dist/terminal/types.js.map +1 -0
  235. package/dist/utils/process.d.ts +2 -0
  236. package/dist/utils/process.d.ts.map +1 -1
  237. package/dist/utils/process.js +3 -0
  238. package/dist/utils/process.js.map +1 -1
  239. package/package.json +1 -1
  240. package/src/AgentManager.ts +1 -1
  241. package/src/__tests__/capacity/anthropic.test.ts +105 -0
  242. package/src/__tests__/capacity/boundaries.test.ts +36 -0
  243. package/src/__tests__/capacity/claude.test.ts +3 -8
  244. package/src/__tests__/capacity/codex.test.ts +12 -35
  245. package/src/__tests__/capacity/fixtures/openai-codex-auth.json +1 -1
  246. package/src/__tests__/capacity/openai.test.ts +15 -15
  247. package/src/__tests__/capacity/wham.test.ts +1 -1
  248. package/src/__tests__/capacity/zai.test.ts +27 -62
  249. package/src/__tests__/harnesses/claude/durable/ClaudePrintAgent.integration.test.ts +2 -2
  250. package/src/__tests__/harnesses/claude/durable/ClaudePrintRunner.test.ts +1 -1
  251. package/src/__tests__/harnesses/codex/durable/CodexCliProbe.test.ts +14 -19
  252. package/src/__tests__/harnesses/codex/durable/CodexPrintAgent.integration.test.ts +3 -3
  253. package/src/__tests__/harnesses/codex/durable/CodexPrintAgentService.test.ts +24 -30
  254. package/src/__tests__/harnesses/codex/durable/CodexPrintRunner.test.ts +4 -8
  255. package/src/__tests__/harnesses/devin/DevinAdapter.test.ts +292 -0
  256. package/src/__tests__/harnesses/devin/DevinAgentMapper.test.ts +88 -0
  257. package/src/__tests__/harnesses/devin/DevinSessionLocator.test.ts +139 -0
  258. package/src/__tests__/harnesses/devin/DevinSessionParser.test.ts +218 -0
  259. package/src/__tests__/harnesses/devin/fixtures.ts +144 -0
  260. package/src/__tests__/harnesses/pi/durable/PiCliProbe.test.ts +7 -11
  261. package/src/__tests__/harnesses/pi/durable/PiPrintAgentService.test.ts +19 -22
  262. package/src/__tests__/harnesses/pi/durable/PiPrintRunner.test.ts +7 -8
  263. package/src/__tests__/{readiness → harnesses/readiness}/AgentReadiness.test.ts +77 -9
  264. package/src/__tests__/harnesses/runtimeProfiles.test.ts +110 -0
  265. package/src/__tests__/print/DurableAgent.test.ts +4 -13
  266. package/src/__tests__/print/DurableAgentRepository.test.ts +1 -13
  267. package/src/__tests__/runtime/ManagedAgentRuntime.test.ts +1 -1
  268. package/src/__tests__/terminal/GhosttyBackend.test.ts +271 -0
  269. package/src/__tests__/terminal/TmuxManager.test.ts +1 -1
  270. package/src/adapters/AgentAdapter.ts +1 -0
  271. package/src/capacity/index.ts +29 -23
  272. package/src/capacity/{claude.ts → providers/anthropic.ts} +16 -131
  273. package/src/capacity/providers/openai-platform.ts +150 -0
  274. package/src/capacity/{wham.ts → providers/openai-subscription.ts} +86 -8
  275. package/src/capacity/{zai.ts → providers/zai.ts} +29 -111
  276. package/src/capacity/sources/claude.ts +30 -0
  277. package/src/capacity/{codex.ts → sources/codex.ts} +54 -124
  278. package/src/capacity/sources/pi.ts +131 -0
  279. package/src/capacity/types.ts +3 -0
  280. package/src/harnesses/claude/credentials.ts +122 -0
  281. package/src/harnesses/claude/readiness.ts +69 -0
  282. package/src/harnesses/codex/credentials.ts +81 -0
  283. package/src/harnesses/codex/readiness.ts +72 -0
  284. package/src/harnesses/copilot/readiness.ts +33 -0
  285. package/src/harnesses/devin/DevinAdapter.ts +224 -0
  286. package/src/harnesses/devin/DevinAgentMapper.ts +43 -0
  287. package/src/harnesses/devin/DevinSessionLocator.ts +230 -0
  288. package/src/harnesses/devin/DevinSessionParser.ts +236 -0
  289. package/src/harnesses/devin/readiness.ts +36 -0
  290. package/src/harnesses/index.ts +2 -0
  291. package/src/harnesses/opencode/readiness.ts +48 -0
  292. package/src/harnesses/pi/credentials.ts +129 -0
  293. package/src/harnesses/pi/readiness.ts +104 -0
  294. package/src/harnesses/readiness/AgentReadiness.ts +89 -0
  295. package/src/harnesses/readiness/checks.ts +336 -0
  296. package/src/harnesses/readiness/types.ts +90 -0
  297. package/src/{utils/agents.ts → harnesses/runtimeProfiles.ts} +35 -38
  298. package/src/index.ts +15 -128
  299. package/src/runtime/ManagedAgentRuntime.ts +7 -22
  300. package/src/runtime/herdr/HerdrAgentDiscovery.ts +3 -19
  301. package/src/runtime/tmux/PidPolling.ts +1 -1
  302. package/src/runtime/tmux/TmuxAgentRuntime.ts +1 -1
  303. package/src/{terminal → runtime/tmux}/TmuxManager.ts +9 -30
  304. package/src/runtime/types.ts +1 -1
  305. package/src/terminal/TerminalFocusManager.ts +19 -292
  306. package/src/terminal/TtyWriter.ts +15 -335
  307. package/src/terminal/backends/ghostty.ts +180 -0
  308. package/src/terminal/backends/index.ts +23 -0
  309. package/src/terminal/backends/iterm2.ts +126 -0
  310. package/src/terminal/backends/shared.ts +47 -0
  311. package/src/terminal/backends/terminal-app.ts +122 -0
  312. package/src/terminal/backends/tmux.ts +62 -0
  313. package/src/terminal/backends/wezterm.ts +65 -0
  314. package/src/terminal/types.ts +23 -0
  315. package/src/utils/process.ts +5 -0
  316. package/dist/__tests__/readiness/AgentReadiness.test.js.map +0 -1
  317. package/dist/__tests__/utils/agents.test.js +0 -93
  318. package/dist/__tests__/utils/agents.test.js.map +0 -1
  319. package/dist/capacity/claude.d.ts +0 -17
  320. package/dist/capacity/claude.d.ts.map +0 -1
  321. package/dist/capacity/claude.js.map +0 -1
  322. package/dist/capacity/codex.d.ts.map +0 -1
  323. package/dist/capacity/codex.js.map +0 -1
  324. package/dist/capacity/openai.d.ts +0 -47
  325. package/dist/capacity/openai.d.ts.map +0 -1
  326. package/dist/capacity/openai.js +0 -307
  327. package/dist/capacity/openai.js.map +0 -1
  328. package/dist/capacity/wham.d.ts +0 -16
  329. package/dist/capacity/wham.d.ts.map +0 -1
  330. package/dist/capacity/wham.js +0 -66
  331. package/dist/capacity/wham.js.map +0 -1
  332. package/dist/capacity/zai.d.ts +0 -14
  333. package/dist/capacity/zai.d.ts.map +0 -1
  334. package/dist/capacity/zai.js.map +0 -1
  335. package/dist/readiness/AgentReadiness.d.ts.map +0 -1
  336. package/dist/readiness/AgentReadiness.js +0 -614
  337. package/dist/readiness/AgentReadiness.js.map +0 -1
  338. package/dist/terminal/TmuxManager.d.ts +0 -28
  339. package/dist/terminal/TmuxManager.d.ts.map +0 -1
  340. package/dist/terminal/TmuxManager.js.map +0 -1
  341. package/dist/terminal/index.d.ts +0 -5
  342. package/dist/terminal/index.d.ts.map +0 -1
  343. package/dist/terminal/index.js +0 -5
  344. package/dist/terminal/index.js.map +0 -1
  345. package/dist/utils/agents.d.ts +0 -16
  346. package/dist/utils/agents.d.ts.map +0 -1
  347. package/dist/utils/agents.js +0 -117
  348. package/dist/utils/agents.js.map +0 -1
  349. package/dist/utils/index.d.ts +0 -8
  350. package/dist/utils/index.d.ts.map +0 -1
  351. package/dist/utils/index.js +0 -6
  352. package/dist/utils/index.js.map +0 -1
  353. package/src/__tests__/utils/agents.test.ts +0 -105
  354. package/src/capacity/openai.ts +0 -355
  355. package/src/readiness/AgentReadiness.ts +0 -730
  356. package/src/terminal/index.ts +0 -4
  357. package/src/utils/index.ts +0 -14
@@ -1,8 +1,4 @@
1
- import { readFile } from "node:fs/promises";
2
- import { homedir } from "node:os";
3
- import { join } from "node:path";
4
1
  const ZAI_QUOTA_URL = "https://api.z.ai/api/monitor/usage/quota/limit";
5
- const MISSING_API_KEY_MESSAGE = "z.ai API key not found; set Z_AI_API_KEY or configure Pi provider zai";
6
2
  const LIMIT_METADATA = {
7
3
  TOKENS_LIMIT: {
8
4
  id: "tokens",
@@ -50,9 +46,6 @@ const UNIT_METADATA = new Map([
50
46
  function record(value) {
51
47
  return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
52
48
  }
53
- function nonEmptyText(value) {
54
- return typeof value === "string" && value.trim() ? value.trim() : null;
55
- }
56
49
  function optionalNumber(value, field) {
57
50
  if (value === undefined || value === null) return null;
58
51
  if (typeof value !== "number" || !Number.isFinite(value)) {
@@ -60,26 +53,23 @@ function optionalNumber(value, field) {
60
53
  }
61
54
  return value;
62
55
  }
63
- function clampPercent(value) {
64
- return Math.max(0, Math.min(100, value));
65
- }
66
56
  function integer(value) {
67
57
  return typeof value === "number" && Number.isInteger(value) ? value : null;
68
58
  }
69
59
  function isCapacityLimitType(value) {
70
60
  return Object.hasOwn(LIMIT_METADATA, value);
71
61
  }
72
- function durationMinutes(unit, number, type) {
73
- if (type === "TIME_LIMIT" && unit === 5 && number === 1) return 30 * 24 * 60;
62
+ function durationMinutes(unit, count, type) {
63
+ if (type === "TIME_LIMIT" && unit === 5 && count === 1) return 30 * 24 * 60;
74
64
  const metadata = UNIT_METADATA.get(unit);
75
- return metadata === undefined || number <= 0 ? null : metadata.minutes * number;
65
+ return metadata === undefined || count <= 0 ? null : metadata.minutes * count;
76
66
  }
77
- function windowLabel(type, unit, number) {
78
- if (type === "TIME_LIMIT" && unit === 5 && number === 1) return "MCP · monthly";
67
+ function windowLabel(type, unit, count) {
68
+ if (type === "TIME_LIMIT" && unit === 5 && count === 1) return "MCP · monthly";
79
69
  const kind = LIMIT_METADATA[type].label;
80
70
  const unitLabel = UNIT_METADATA.get(unit)?.label;
81
71
  if (!unitLabel) return kind;
82
- return `${kind} · ${number} ${unitLabel}${number === 1 ? "" : "s"}`;
72
+ return `${kind} · ${count} ${unitLabel}${count === 1 ? "" : "s"}`;
83
73
  }
84
74
  function resetTime(value) {
85
75
  const milliseconds = optionalNumber(value, "limit nextResetTime");
@@ -90,10 +80,7 @@ function resetTime(value) {
90
80
  }
91
81
  function availability(windows) {
92
82
  if (windows.length === 0) return "unknown";
93
- if (windows.some((window)=>window.usedPercent !== null && window.usedPercent < 100)) {
94
- return "yes";
95
- }
96
- return "no";
83
+ return windows.some((window)=>window.usedPercent !== null && window.usedPercent < 100) ? "yes" : "no";
97
84
  }
98
85
  function parseLimit(value, index) {
99
86
  const limit = record(value);
@@ -121,39 +108,14 @@ function parseLimit(value, index) {
121
108
  label: windowLabel(limit.type, unit, count),
122
109
  limitType: limit.type,
123
110
  durationMinutes: durationMinutes(unit, count, limit.type),
124
- usedPercent: clampPercent(usedPercent),
111
+ usedPercent: Math.max(0, Math.min(100, usedPercent)),
125
112
  resetsAt: resetTime(limit.nextResetTime),
126
113
  total,
127
114
  current,
128
115
  remaining
129
116
  };
130
117
  }
131
- export async function resolveZaiApiKey(options = {}) {
132
- const env = options.env ?? process.env;
133
- const environmentKey = nonEmptyText(env.Z_AI_API_KEY);
134
- if (environmentKey) return environmentKey;
135
- const authPath = join(env.HOME || homedir(), ".pi", "agent", "auth.json");
136
- let parsed;
137
- try {
138
- const contents = await (options.readFile ?? readFile)(authPath, "utf8");
139
- const root = record(JSON.parse(contents));
140
- if (!root) throw new Error("invalid");
141
- parsed = root;
142
- } catch (error) {
143
- if (record(error)?.code === "ENOENT") {
144
- throw new Error(MISSING_API_KEY_MESSAGE);
145
- }
146
- throw new Error("z.ai Pi auth file is malformed");
147
- }
148
- const credential = record(parsed.zai);
149
- if (!credential) {
150
- throw new Error(MISSING_API_KEY_MESSAGE);
151
- }
152
- const key = credential.type === "api_key" ? nonEmptyText(credential.key) : null;
153
- if (!key) throw new Error("z.ai Pi auth file has a malformed zai credential");
154
- return key;
155
- }
156
- export function parseZaiQuota(raw, checkedAt) {
118
+ export function parseZaiCapacity(raw) {
157
119
  const root = record(raw);
158
120
  const data = record(root?.data);
159
121
  if (root?.success !== true || root.code !== 200 || !data || !Array.isArray(data.limits)) {
@@ -161,19 +123,13 @@ export function parseZaiQuota(raw, checkedAt) {
161
123
  }
162
124
  const windows = data.limits.map(parseLimit).filter((window)=>window !== null);
163
125
  return {
164
- harness: "pi",
165
- provider: "zai",
166
- generatedAt: checkedAt,
167
126
  authenticated: true,
168
127
  available: availability(windows),
169
128
  windows,
170
129
  creditsRemaining: null
171
130
  };
172
131
  }
173
- export async function probeZaiCapacity(options) {
174
- const key = await resolveZaiApiKey(options);
175
- const controller = new AbortController();
176
- const timer = setTimeout(()=>controller.abort(), options.timeoutMs ?? 5000);
132
+ export async function fetchZaiCapacity(key, options = {}) {
177
133
  let response;
178
134
  try {
179
135
  response = await (options.fetch ?? globalThis.fetch)(ZAI_QUOTA_URL, {
@@ -181,23 +137,22 @@ export async function probeZaiCapacity(options) {
181
137
  headers: {
182
138
  Authorization: `Bearer ${key}`
183
139
  },
184
- signal: controller.signal
140
+ signal: AbortSignal.timeout(options.timeoutMs ?? 5000)
185
141
  });
186
142
  } catch {
187
143
  throw new Error("z.ai quota request failed");
188
- } finally{
189
- clearTimeout(timer);
190
144
  }
191
145
  if (response.status !== 200) {
192
146
  throw new Error(`z.ai quota request failed: HTTP ${response.status}`);
193
147
  }
194
- let raw;
195
148
  try {
196
- raw = await response.json();
197
- } catch {
198
- throw new Error("z.ai quota response is not valid JSON");
149
+ return parseZaiCapacity(await response.json());
150
+ } catch (error) {
151
+ if (error instanceof SyntaxError) {
152
+ throw new Error("z.ai quota response is not valid JSON");
153
+ }
154
+ throw error;
199
155
  }
200
- return parseZaiQuota(raw, options.checkedAt);
201
156
  }
202
157
 
203
158
  //# sourceMappingURL=zai.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/capacity/providers/zai.ts"],"sourcesContent":["import type {\n Availability,\n CapacityLimitType,\n CapacityWindow,\n ProviderCapacitySnapshot,\n} from \"../types.js\";\n\nconst ZAI_QUOTA_URL = \"https://api.z.ai/api/monitor/usage/quota/limit\";\nconst LIMIT_METADATA = {\n TOKENS_LIMIT: { id: \"tokens\", label: \"Tokens\" },\n CREDIT_LIMIT: { id: \"credit\", label: \"Credit\" },\n TIME_LIMIT: { id: \"time\", label: \"Time\" },\n} as const satisfies Record<CapacityLimitType, { id: string; label: string }>;\nconst UNIT_METADATA = new Map<number, { minutes: number; label: string }>([\n [1, { minutes: 24 * 60, label: \"day\" }],\n [3, { minutes: 60, label: \"hour\" }],\n [5, { minutes: 1, label: \"minute\" }],\n [6, { minutes: 7 * 24 * 60, label: \"week\" }],\n]);\ntype UnknownRecord = Record<string, unknown>;\n\nexport type ZaiRequestOptions = {\n fetch?: typeof globalThis.fetch;\n timeoutMs?: number;\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 optionalNumber(value: unknown, field: string): number | null {\n if (value === undefined || value === null) return null;\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n throw new Error(`Invalid z.ai quota ${field}`);\n }\n return value;\n}\n\nfunction integer(value: unknown): number | null {\n return typeof value === \"number\" && Number.isInteger(value) ? value : null;\n}\n\nfunction isCapacityLimitType(value: string): value is CapacityLimitType {\n return Object.hasOwn(LIMIT_METADATA, value);\n}\n\nfunction durationMinutes(unit: number, count: number, type: CapacityLimitType): number | null {\n if (type === \"TIME_LIMIT\" && unit === 5 && count === 1) return 30 * 24 * 60;\n const metadata = UNIT_METADATA.get(unit);\n return metadata === undefined || count <= 0 ? null : metadata.minutes * count;\n}\n\nfunction windowLabel(type: CapacityLimitType, unit: number, count: number): string {\n if (type === \"TIME_LIMIT\" && unit === 5 && count === 1) return \"MCP · monthly\";\n const kind = LIMIT_METADATA[type].label;\n const unitLabel = UNIT_METADATA.get(unit)?.label;\n if (!unitLabel) return kind;\n return `${kind} · ${count} ${unitLabel}${count === 1 ? \"\" : \"s\"}`;\n}\n\nfunction resetTime(value: unknown): string | null {\n const milliseconds = optionalNumber(value, \"limit nextResetTime\");\n if (milliseconds === null) return null;\n const date = new Date(milliseconds);\n if (Number.isNaN(date.getTime())) throw new Error(\"Invalid z.ai quota limit nextResetTime\");\n return date.toISOString();\n}\n\nfunction availability(windows: CapacityWindow[]): Availability {\n if (windows.length === 0) return \"unknown\";\n return windows.some((window) => window.usedPercent !== null && window.usedPercent < 100)\n ? \"yes\"\n : \"no\";\n}\n\nfunction parseLimit(value: unknown, index: number): CapacityWindow | null {\n const limit = record(value);\n if (!limit) throw new Error(\"Invalid z.ai quota limit entry\");\n const unit = integer(limit.unit);\n const count = integer(limit.number);\n if (typeof limit.type !== \"string\" || unit === null || count === null) {\n throw new Error(\"Invalid z.ai quota limit entry\");\n }\n const serverPercent = optionalNumber(limit.percentage, \"limit percentage\");\n if (serverPercent === null) throw new Error(\"Invalid z.ai quota limit percentage\");\n if (!isCapacityLimitType(limit.type)) return null;\n\n const total = optionalNumber(limit.usage, \"limit usage\");\n const current = optionalNumber(limit.currentValue, \"limit currentValue\");\n const remaining = optionalNumber(limit.remaining, \"limit remaining\");\n let consumed = total !== null && remaining !== null ? total - remaining : null;\n if (current !== null) consumed = Math.max(consumed ?? current, current);\n let usedPercent = serverPercent;\n if (total !== null && total > 0 && consumed !== null) {\n usedPercent = (consumed / total) * 100;\n }\n const metadata = LIMIT_METADATA[limit.type];\n return {\n id: `zai:${metadata.id}:${index + 1}`,\n label: windowLabel(limit.type, unit, count),\n limitType: limit.type,\n durationMinutes: durationMinutes(unit, count, limit.type),\n usedPercent: Math.max(0, Math.min(100, usedPercent)),\n resetsAt: resetTime(limit.nextResetTime),\n total,\n current,\n remaining,\n };\n}\n\nexport function parseZaiCapacity(raw: unknown): ProviderCapacitySnapshot {\n const root = record(raw);\n const data = record(root?.data);\n if (root?.success !== true || root.code !== 200 || !data || !Array.isArray(data.limits)) {\n throw new Error(\"Invalid z.ai quota response\");\n }\n const windows = data.limits\n .map(parseLimit)\n .filter((window): window is CapacityWindow => window !== null);\n return {\n authenticated: true,\n available: availability(windows),\n windows,\n creditsRemaining: null,\n };\n}\n\nexport async function fetchZaiCapacity(\n key: string,\n options: ZaiRequestOptions = {},\n): Promise<ProviderCapacitySnapshot> {\n let response: Response;\n try {\n response = await (options.fetch ?? globalThis.fetch)(ZAI_QUOTA_URL, {\n method: \"GET\",\n headers: { Authorization: `Bearer ${key}` },\n signal: AbortSignal.timeout(options.timeoutMs ?? 5000),\n });\n } catch {\n throw new Error(\"z.ai quota request failed\");\n }\n if (response.status !== 200) {\n throw new Error(`z.ai quota request failed: HTTP ${response.status}`);\n }\n try {\n return parseZaiCapacity(await response.json());\n } catch (error) {\n if (error instanceof SyntaxError) {\n throw new Error(\"z.ai quota response is not valid JSON\");\n }\n throw error;\n }\n}\n"],"names":["ZAI_QUOTA_URL","LIMIT_METADATA","TOKENS_LIMIT","id","label","CREDIT_LIMIT","TIME_LIMIT","UNIT_METADATA","Map","minutes","record","value","Array","isArray","optionalNumber","field","undefined","Number","isFinite","Error","integer","isInteger","isCapacityLimitType","Object","hasOwn","durationMinutes","unit","count","type","metadata","get","windowLabel","kind","unitLabel","resetTime","milliseconds","date","Date","isNaN","getTime","toISOString","availability","windows","length","some","window","usedPercent","parseLimit","index","limit","number","serverPercent","percentage","total","usage","current","currentValue","remaining","consumed","Math","max","limitType","min","resetsAt","nextResetTime","parseZaiCapacity","raw","root","data","success","code","limits","map","filter","authenticated","available","creditsRemaining","fetchZaiCapacity","key","options","response","fetch","globalThis","method","headers","Authorization","signal","AbortSignal","timeout","timeoutMs","status","json","error","SyntaxError"],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { type AnthropicCapacityRequestOptions } from "../providers/anthropic.js";
2
+ import type { CapacityReport } from "../types.js";
3
+ import { type ClaudeCredentialOptions } from "../../harnesses/claude/credentials.js";
4
+ export type ClaudeCapacityOptions = ClaudeCredentialOptions & AnthropicCapacityRequestOptions;
5
+ export type ClaudeProbeOptions = ClaudeCapacityOptions & {
6
+ checkedAt: string;
7
+ };
8
+ export declare function probeClaudeCapacity(options: ClaudeProbeOptions): Promise<CapacityReport>;
9
+ //# sourceMappingURL=claude.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../../src/capacity/sources/claude.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,+BAA+B,EACrC,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,cAAc,EAA4B,MAAM,aAAa,CAAC;AAC5E,OAAO,EAEL,KAAK,uBAAuB,EAC7B,MAAM,uCAAuC,CAAC;AAE/C,MAAM,MAAM,qBAAqB,GAAG,uBAAuB,GAAG,+BAA+B,CAAC;AAE9F,MAAM,MAAM,kBAAkB,GAAG,qBAAqB,GAAG;IACvD,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAWF,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,cAAc,CAAC,CAI9F"}
@@ -0,0 +1,17 @@
1
+ import { fetchAnthropicCapacity } from "../providers/anthropic.js";
2
+ import { resolveClaudeAnthropicToken } from "../../harnesses/claude/credentials.js";
3
+ function claudeReport(snapshot, checkedAt) {
4
+ return {
5
+ harness: "claude",
6
+ provider: "anthropic",
7
+ generatedAt: checkedAt,
8
+ ...snapshot
9
+ };
10
+ }
11
+ export async function probeClaudeCapacity(options) {
12
+ const token = await resolveClaudeAnthropicToken(options);
13
+ const snapshot = await fetchAnthropicCapacity(token, options);
14
+ return claudeReport(snapshot, options.checkedAt);
15
+ }
16
+
17
+ //# sourceMappingURL=claude.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/capacity/sources/claude.ts"],"sourcesContent":["import {\n fetchAnthropicCapacity,\n type AnthropicCapacityRequestOptions,\n} from \"../providers/anthropic.js\";\nimport type { CapacityReport, ProviderCapacitySnapshot } from \"../types.js\";\nimport {\n resolveClaudeAnthropicToken,\n type ClaudeCredentialOptions,\n} from \"../../harnesses/claude/credentials.js\";\n\nexport type ClaudeCapacityOptions = ClaudeCredentialOptions & AnthropicCapacityRequestOptions;\n\nexport type ClaudeProbeOptions = ClaudeCapacityOptions & {\n checkedAt: string;\n};\n\nfunction claudeReport(snapshot: ProviderCapacitySnapshot, checkedAt: string): CapacityReport {\n return {\n harness: \"claude\",\n provider: \"anthropic\",\n generatedAt: checkedAt,\n ...snapshot,\n };\n}\n\nexport async function probeClaudeCapacity(options: ClaudeProbeOptions): Promise<CapacityReport> {\n const token = await resolveClaudeAnthropicToken(options);\n const snapshot = await fetchAnthropicCapacity(token, options);\n return claudeReport(snapshot, options.checkedAt);\n}\n"],"names":["fetchAnthropicCapacity","resolveClaudeAnthropicToken","claudeReport","snapshot","checkedAt","harness","provider","generatedAt","probeClaudeCapacity","options","token"],"mappings":"AAAA,SACEA,sBAAsB,QAEjB,4BAA4B;AAEnC,SACEC,2BAA2B,QAEtB,wCAAwC;AAQ/C,SAASC,aAAaC,QAAkC,EAAEC,SAAiB;IACzE,OAAO;QACLC,SAAS;QACTC,UAAU;QACVC,aAAaH;QACb,GAAGD,QAAQ;IACb;AACF;AAEA,OAAO,eAAeK,oBAAoBC,OAA2B;IACnE,MAAMC,QAAQ,MAAMT,4BAA4BQ;IAChD,MAAMN,WAAW,MAAMH,uBAAuBU,OAAOD;IACrD,OAAOP,aAAaC,UAAUM,QAAQL,SAAS;AACjD"}
@@ -1,5 +1,5 @@
1
- import type { CapacityReport, CapacityWindow } from "./types.js";
2
- export { toRateWindow } from "./wham.js";
1
+ import type { CapacityReport, CapacityWindow } from "../types.js";
2
+ import { type CodexCredentialOptions } from "../../harnesses/codex/credentials.js";
3
3
  type CodexUsageSource = "pat" | "oauth" | "cli";
4
4
  type UsageSnapshot = {
5
5
  windows: CapacityWindow[];
@@ -17,20 +17,16 @@ type CliResponses = {
17
17
  account: unknown;
18
18
  };
19
19
  type CodexRpc = (messages: RpcMessage[]) => Promise<CliResponses>;
20
- export declare const CODEX_APP_SERVER_ARGS: readonly ["-s", "read-only", "-a", "untrusted", "app-server"];
21
- type CodexProbeOptions = {
20
+ export type CodexProbeOptions = CodexCredentialOptions & {
22
21
  installed: boolean;
23
22
  checkedAt: string;
24
- readFile?: (path: string, encoding: BufferEncoding) => Promise<string>;
25
23
  fetch?: typeof globalThis.fetch;
26
24
  rpc?: CodexRpc;
27
25
  timeoutMs?: number;
28
- env?: NodeJS.ProcessEnv;
29
- now?: () => Date;
30
26
  };
31
- export declare function resolveCodexAuthPath(env?: NodeJS.ProcessEnv): string;
27
+ export declare const CODEX_APP_SERVER_ARGS: readonly ["-s", "read-only", "-a", "untrusted", "app-server"];
32
28
  export declare function parseUsage(raw: unknown, source: "pat" | "oauth"): UsageSnapshot;
33
- export declare function parseCliUsage(raw: unknown): UsageSnapshot;
34
29
  export declare function codexUnavailableReport(checkedAt: string): CapacityReport;
35
30
  export declare function probeCodexCapacity(options: CodexProbeOptions): Promise<CapacityReport>;
31
+ export {};
36
32
  //# sourceMappingURL=codex.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex.d.ts","sourceRoot":"","sources":["../../../src/capacity/sources/codex.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClE,OAAO,EAEL,KAAK,sBAAsB,EAC5B,MAAM,sCAAsC,CAAC;AAE9C,KAAK,gBAAgB,GAAG,KAAK,GAAG,OAAO,GAAG,KAAK,CAAC;AAChD,KAAK,aAAa,GAAG;IACnB,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,MAAM,EAAE,gBAAgB,CAAC;CAC1B,CAAC;AAEF,KAAK,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAC7C,KAAK,UAAU,GAAG;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,aAAa,CAAA;CAAE,CAAC;AAC1E,KAAK,YAAY,GAAG;IAAE,UAAU,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC;AAC9D,KAAK,QAAQ,GAAG,CAAC,QAAQ,EAAE,UAAU,EAAE,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;AAElE,MAAM,MAAM,iBAAiB,GAAG,sBAAsB,GAAG;IACvD,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;IAChC,GAAG,CAAC,EAAE,QAAQ,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,eAAO,MAAM,qBAAqB,+DAAgE,CAAC;AAgBnG,wBAAgB,UAAU,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,GAAG,OAAO,GAAG,aAAa,CAG/E;AA8GD,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,CAUxE;AAuDD,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,cAAc,CAAC,CAiC5F"}
@@ -1,8 +1,6 @@
1
1
  import { spawn } from "node:child_process";
2
- import { readFile } from "node:fs/promises";
3
- import { join } from "node:path";
4
- import { parseWhamUsage, resetTime, safeIdentifier } from "./wham.js";
5
- export { toRateWindow } from "./wham.js";
2
+ import { fetchOpenAiPatAccountId, fetchOpenAiSubscriptionCapacity, parseWhamUsage, resetTime, safeIdentifier } from "../providers/openai-subscription.js";
3
+ import { resolveCodexCredentials } from "../../harnesses/codex/credentials.js";
6
4
  export const CODEX_APP_SERVER_ARGS = [
7
5
  "-s",
8
6
  "read-only",
@@ -19,10 +17,6 @@ function finiteNumber(value) {
19
17
  function nonEmptyText(value) {
20
18
  return typeof value === "string" && value.length > 0 ? value : null;
21
19
  }
22
- export function resolveCodexAuthPath(env = process.env) {
23
- const root = env.CODEX_HOME || join(env.HOME || "", ".codex");
24
- return join(root, "auth.json");
25
- }
26
20
  export function parseUsage(raw, source) {
27
21
  const { windows, creditsRemaining } = parseWhamUsage(raw);
28
22
  return {
@@ -51,13 +45,15 @@ function cliSnapshotWindows(value, fallbackId) {
51
45
  cliWindow(snapshot.secondary, `${scope}:secondary`, `${scope} secondary`)
52
46
  ].filter((item)=>item !== null);
53
47
  }
54
- export function parseCliUsage(raw) {
48
+ function parseCliUsage(raw) {
55
49
  const response = record(raw) ?? {};
56
50
  const primary = record(response.rateLimits);
57
51
  const windows = primary ? cliSnapshotWindows(primary, "codex") : [];
58
52
  const buckets = record(response.rateLimitsByLimitId);
59
53
  if (buckets) {
60
- for (const [id, snapshot] of Object.entries(buckets))windows.push(...cliSnapshotWindows(snapshot, id));
54
+ for (const [id, snapshot] of Object.entries(buckets)){
55
+ windows.push(...cliSnapshotWindows(snapshot, id));
56
+ }
61
57
  }
62
58
  const unique = [
63
59
  ...new Map(windows.map((window)=>[
@@ -71,7 +67,7 @@ export function parseCliUsage(raw) {
71
67
  source: "cli"
72
68
  };
73
69
  }
74
- function capacityFromSnapshot(snapshot, context, raw) {
70
+ function capacityFromSnapshot(snapshot, options, raw) {
75
71
  const hasUsage = snapshot.windows.some((window)=>window.usedPercent !== null);
76
72
  const rateLimits = record(record(raw)?.rateLimits);
77
73
  const reached = nonEmptyText(rateLimits?.rateLimitReachedType);
@@ -79,56 +75,13 @@ function capacityFromSnapshot(snapshot, context, raw) {
79
75
  return {
80
76
  harness: "codex",
81
77
  provider: "openai",
82
- generatedAt: context.checkedAt,
78
+ generatedAt: options.checkedAt,
83
79
  authenticated: true,
84
80
  available: reached ? "no" : hasUsage ? "yes" : "unknown",
85
81
  windows: snapshot.windows,
86
82
  creditsRemaining: snapshot.creditsRemaining ?? finiteNumber(resetCredits?.availableCount)
87
83
  };
88
84
  }
89
- function jwtExpiry(token) {
90
- const part = token.split(".")[1];
91
- if (!part) return null;
92
- try {
93
- return finiteNumber(record(JSON.parse(Buffer.from(part, "base64url").toString("utf8")))?.exp);
94
- } catch {
95
- return null;
96
- }
97
- }
98
- function staleOAuth(tokens, token, now) {
99
- const metadata = tokens.expires_at ?? tokens.expiresAt ?? tokens.expiry;
100
- let expiry = finiteNumber(metadata);
101
- if (typeof metadata === "string") {
102
- const parsed = Date.parse(metadata);
103
- expiry = Number.isNaN(parsed) ? null : parsed / 1000;
104
- }
105
- expiry ??= jwtExpiry(token);
106
- return expiry !== null && expiry <= now.getTime() / 1000;
107
- }
108
- async function fetchJson(fetcher, url, init, timeoutMs) {
109
- const controller = new AbortController();
110
- const timer = setTimeout(()=>controller.abort(), timeoutMs);
111
- try {
112
- const response = await fetcher(url, {
113
- ...init,
114
- signal: controller.signal
115
- });
116
- if (!response.ok) throw new Error(response.status === 401 ? "unauthorized" : "request failed");
117
- return await response.json();
118
- } finally{
119
- clearTimeout(timer);
120
- }
121
- }
122
- async function apiSnapshot(token, accountId, source, options) {
123
- const fetcher = options.fetch ?? globalThis.fetch;
124
- const raw = await fetchJson(fetcher, "https://chatgpt.com/backend-api/wham/usage", {
125
- headers: {
126
- Authorization: `Bearer ${token}`,
127
- "ChatGPT-Account-Id": accountId
128
- }
129
- }, options.timeoutMs ?? 5000);
130
- return parseUsage(raw, source);
131
- }
132
85
  function appServerRpc(messages, timeoutMs = 5000) {
133
86
  return new Promise((resolve, reject)=>{
134
87
  const child = spawn("codex", CODEX_APP_SERVER_ARGS, {
@@ -195,11 +148,8 @@ export function codexUnavailableReport(checkedAt) {
195
148
  creditsRemaining: null
196
149
  };
197
150
  }
198
- function unavailable(options) {
199
- return codexUnavailableReport(options.checkedAt);
200
- }
201
151
  async function cliFallback(options) {
202
- if (!options.installed) return unavailable(options);
152
+ if (!options.installed) return codexUnavailableReport(options.checkedAt);
203
153
  const messages = [
204
154
  {
205
155
  id: 1,
@@ -236,40 +186,37 @@ async function cliFallback(options) {
236
186
  }
237
187
  return result;
238
188
  } catch {
239
- return unavailable(options);
189
+ return codexUnavailableReport(options.checkedAt);
240
190
  }
241
191
  }
192
+ async function subscriptionSnapshot(access, accountId, source, options) {
193
+ const snapshot = await fetchOpenAiSubscriptionCapacity({
194
+ access,
195
+ accountId
196
+ }, options);
197
+ if (snapshot.authenticated === false) throw new Error("unauthorized");
198
+ return {
199
+ windows: snapshot.windows,
200
+ creditsRemaining: snapshot.creditsRemaining,
201
+ source
202
+ };
203
+ }
242
204
  export async function probeCodexCapacity(options) {
243
- let parsed = null;
244
- try {
245
- const contents = await (options.readFile ?? readFile)(resolveCodexAuthPath(options.env), "utf8");
246
- parsed = record(JSON.parse(contents));
247
- } catch {
248
- return cliFallback(options);
249
- }
250
- const auth = parsed ?? {};
251
- const pat = nonEmptyText(auth.personal_access_token);
252
- if (pat) {
205
+ const credentials = await resolveCodexCredentials(options);
206
+ if (!credentials) return cliFallback(options);
207
+ if (credentials.personalAccessToken) {
253
208
  try {
254
- const fetcher = options.fetch ?? globalThis.fetch;
255
- const whoami = record(await fetchJson(fetcher, "https://auth.openai.com/api/accounts/v1/user-auth-credential/whoami", {
256
- headers: {
257
- Authorization: `Bearer ${pat}`
258
- }
259
- }, options.timeoutMs ?? 5000));
260
- const accountId = nonEmptyText(whoami?.chatgpt_account_id);
261
- if (!accountId) throw new Error("account unavailable");
262
- return capacityFromSnapshot(await apiSnapshot(pat, accountId, "pat", options), options);
209
+ const accountId = await fetchOpenAiPatAccountId(credentials.personalAccessToken, options);
210
+ const snapshot = await subscriptionSnapshot(credentials.personalAccessToken, accountId, "pat", options);
211
+ return capacityFromSnapshot(snapshot, options);
263
212
  } catch {
264
213
  // Continue to a separately available OAuth credential before using the CLI.
265
214
  }
266
215
  }
267
- const tokens = record(auth.tokens);
268
- const accessToken = nonEmptyText(tokens?.access_token);
269
- const accountId = nonEmptyText(tokens?.account_id);
270
- if (tokens && accessToken && accountId && !staleOAuth(tokens, accessToken, (options.now ?? (()=>new Date()))())) {
216
+ if (credentials.oauth) {
271
217
  try {
272
- return capacityFromSnapshot(await apiSnapshot(accessToken, accountId, "oauth", options), options);
218
+ const snapshot = await subscriptionSnapshot(credentials.oauth.access, credentials.oauth.accountId, "oauth", options);
219
+ return capacityFromSnapshot(snapshot, options);
273
220
  } catch {
274
221
  return cliFallback(options);
275
222
  }
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/capacity/sources/codex.ts"],"sourcesContent":["import { spawn } from \"node:child_process\";\nimport {\n fetchOpenAiPatAccountId,\n fetchOpenAiSubscriptionCapacity,\n parseWhamUsage,\n resetTime,\n safeIdentifier,\n} from \"../providers/openai-subscription.js\";\nimport type { CapacityReport, CapacityWindow } from \"../types.js\";\nimport {\n resolveCodexCredentials,\n type CodexCredentialOptions,\n} from \"../../harnesses/codex/credentials.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 type CodexProbeOptions = CodexCredentialOptions & {\n installed: boolean;\n checkedAt: string;\n fetch?: typeof globalThis.fetch;\n rpc?: CodexRpc;\n timeoutMs?: number;\n};\n\nexport const CODEX_APP_SERVER_ARGS = [\"-s\", \"read-only\", \"-a\", \"untrusted\", \"app-server\"] as const;\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\nexport function parseUsage(raw: unknown, source: \"pat\" | \"oauth\"): UsageSnapshot {\n const { windows, creditsRemaining } = parseWhamUsage(raw);\n return { windows, creditsRemaining, source };\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\nfunction 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 }\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 options: 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 harness: \"codex\",\n provider: \"openai\",\n generatedAt: options.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 appServerRpc(messages: RpcMessage[], timeoutMs = 5000): Promise<CliResponses> {\n return new Promise((resolve, reject) => {\n const child = spawn(\"codex\", CODEX_APP_SERVER_ARGS, { stdio: [\"pipe\", \"pipe\", \"ignore\"] });\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\nexport function codexUnavailableReport(checkedAt: string): CapacityReport {\n return {\n harness: \"codex\",\n provider: \"openai\",\n generatedAt: 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 codexUnavailableReport(options.checkedAt);\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 codexUnavailableReport(options.checkedAt);\n }\n}\n\nasync function subscriptionSnapshot(\n access: string,\n accountId: string,\n source: \"pat\" | \"oauth\",\n options: CodexProbeOptions,\n): Promise<UsageSnapshot> {\n const snapshot = await fetchOpenAiSubscriptionCapacity({ access, accountId }, options);\n if (snapshot.authenticated === false) throw new Error(\"unauthorized\");\n return {\n windows: snapshot.windows,\n creditsRemaining: snapshot.creditsRemaining,\n source,\n };\n}\n\nexport async function probeCodexCapacity(options: CodexProbeOptions): Promise<CapacityReport> {\n const credentials = await resolveCodexCredentials(options);\n if (!credentials) return cliFallback(options);\n\n if (credentials.personalAccessToken) {\n try {\n const accountId = await fetchOpenAiPatAccountId(credentials.personalAccessToken, options);\n const snapshot = await subscriptionSnapshot(\n credentials.personalAccessToken,\n accountId,\n \"pat\",\n options,\n );\n return capacityFromSnapshot(snapshot, options);\n } catch {\n // Continue to a separately available OAuth credential before using the CLI.\n }\n }\n\n if (credentials.oauth) {\n try {\n const snapshot = await subscriptionSnapshot(\n credentials.oauth.access,\n credentials.oauth.accountId,\n \"oauth\",\n options,\n );\n return capacityFromSnapshot(snapshot, options);\n } catch {\n return cliFallback(options);\n }\n }\n return cliFallback(options);\n}\n"],"names":["spawn","fetchOpenAiPatAccountId","fetchOpenAiSubscriptionCapacity","parseWhamUsage","resetTime","safeIdentifier","resolveCodexCredentials","CODEX_APP_SERVER_ARGS","record","value","Array","isArray","finiteNumber","Number","isFinite","nonEmptyText","length","parseUsage","raw","source","windows","creditsRemaining","cliWindow","id","label","input","durationMinutes","windowDurationMins","usedPercent","resetsAt","cliSnapshotWindows","fallbackId","snapshot","scope","limitId","primary","secondary","filter","item","parseCliUsage","response","rateLimits","buckets","rateLimitsByLimitId","Object","entries","push","unique","Map","map","window","values","capacityFromSnapshot","options","hasUsage","some","reached","rateLimitReachedType","resetCredits","rateLimitResetCredits","usageLimitResetCredits","harness","provider","generatedAt","checkedAt","authenticated","available","availableCount","appServerRpc","messages","timeoutMs","Promise","resolve","reject","child","stdio","results","buffer","settled","finish","error","clearTimeout","timer","kill","setTimeout","Error","once","stdout","setEncoding","on","chunk","newline","indexOf","line","slice","trim","message","JSON","parse","request","stdin","write","stringify","result","account","codexUnavailableReport","cliFallback","installed","method","params","clientInfo","name","title","version","capabilities","rpc","requests","accountEnvelope","hasOwn","subscriptionSnapshot","access","accountId","probeCodexCapacity","credentials","personalAccessToken","oauth"],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import type { CapacityReport } from "../types.js";
2
+ import { type PiCredentialOptions } from "../../harnesses/pi/credentials.js";
3
+ export type PiAnthropicCapacityOptions = PiCredentialOptions & {
4
+ now?: () => Date;
5
+ fetch?: typeof globalThis.fetch;
6
+ timeoutMs?: number;
7
+ };
8
+ export type PiAnthropicProbeOptions = PiAnthropicCapacityOptions & {
9
+ checkedAt: string;
10
+ };
11
+ export type PiOpenAiCapacityOptions = PiCredentialOptions & {
12
+ now?: () => Date;
13
+ fetch?: typeof globalThis.fetch;
14
+ timeoutMs?: number;
15
+ };
16
+ export type PiOpenAiProbeOptions = PiOpenAiCapacityOptions & {
17
+ checkedAt: string;
18
+ };
19
+ export type PiZaiCapacityOptions = PiCredentialOptions & {
20
+ now?: () => Date;
21
+ fetch?: typeof globalThis.fetch;
22
+ timeoutMs?: number;
23
+ };
24
+ export type PiZaiProbeOptions = PiZaiCapacityOptions & {
25
+ checkedAt: string;
26
+ };
27
+ export declare function probePiAnthropicCapacity(options: PiAnthropicProbeOptions): Promise<CapacityReport>;
28
+ export declare function probeOpenAiCapacity(options: PiOpenAiProbeOptions): Promise<CapacityReport>;
29
+ export declare function probeZaiCapacity(options: PiZaiProbeOptions): Promise<CapacityReport>;
30
+ //# sourceMappingURL=pi.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pi.d.ts","sourceRoot":"","sources":["../../../src/capacity/sources/pi.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAA4B,MAAM,aAAa,CAAC;AAC5E,OAAO,EAIL,KAAK,mBAAmB,EAEzB,MAAM,mCAAmC,CAAC;AAE3C,MAAM,MAAM,0BAA0B,GAAG,mBAAmB,GAAG;IAC7D,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG,0BAA0B,GAAG;IACjE,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG,mBAAmB,GAAG;IAC1D,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG,uBAAuB,GAAG;IAC3D,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG,mBAAmB,GAAG;IACvD,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,oBAAoB,GAAG;IACrD,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,cAAc,CAAC,CAqBzB;AAgCD,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,cAAc,CAAC,CAqBhG;AAED,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,cAAc,CAAC,CAS1F"}
@@ -0,0 +1,81 @@
1
+ import { fetchAnthropicCapacity } from "../providers/anthropic.js";
2
+ import { fetchOpenAiPlatformCapacity } from "../providers/openai-platform.js";
3
+ import { fetchOpenAiSubscriptionCapacity } from "../providers/openai-subscription.js";
4
+ import { fetchZaiCapacity } from "../providers/zai.js";
5
+ import { resolvePiAnthropicCredential, resolvePiOpenAiCredential, resolvePiZaiApiKey } from "../../harnesses/pi/credentials.js";
6
+ export async function probePiAnthropicCapacity(options) {
7
+ const credential = await resolvePiAnthropicCredential(options);
8
+ const now = options.now?.() ?? new Date();
9
+ if (credential.expiresMs !== null && credential.expiresMs <= now.getTime()) {
10
+ return {
11
+ harness: "pi",
12
+ provider: "anthropic",
13
+ generatedAt: options.checkedAt,
14
+ authenticated: true,
15
+ available: "unknown",
16
+ windows: [],
17
+ creditsRemaining: null
18
+ };
19
+ }
20
+ const snapshot = await fetchAnthropicCapacity(credential.access, options);
21
+ return {
22
+ harness: "pi",
23
+ provider: "anthropic",
24
+ generatedAt: options.checkedAt,
25
+ ...snapshot
26
+ };
27
+ }
28
+ function piOpenAiReport(snapshot, checkedAt) {
29
+ return {
30
+ harness: "pi",
31
+ provider: "openai",
32
+ generatedAt: checkedAt,
33
+ ...snapshot
34
+ };
35
+ }
36
+ function jwtExpiryMs(token) {
37
+ const part = token.split(".")[1];
38
+ if (!part) return null;
39
+ try {
40
+ const payload = JSON.parse(Buffer.from(part, "base64url").toString("utf8"));
41
+ if (!payload || typeof payload !== "object" || Array.isArray(payload)) return null;
42
+ const exp = payload.exp;
43
+ return typeof exp === "number" && Number.isFinite(exp) ? exp * 1000 : null;
44
+ } catch {
45
+ return null;
46
+ }
47
+ }
48
+ function oauthExpired(credential, nowMs) {
49
+ const expiryMs = credential.expiresMs ?? jwtExpiryMs(credential.access);
50
+ return expiryMs !== null && expiryMs <= nowMs;
51
+ }
52
+ export async function probeOpenAiCapacity(options) {
53
+ const credential = await resolvePiOpenAiCredential(options);
54
+ if (credential.kind === "platform") {
55
+ const snapshot = await fetchOpenAiPlatformCapacity(credential.key, options);
56
+ return piOpenAiReport(snapshot, options.checkedAt);
57
+ }
58
+ const nowMs = Date.parse(options.checkedAt);
59
+ if (Number.isNaN(nowMs) || oauthExpired(credential, nowMs)) {
60
+ return piOpenAiReport({
61
+ authenticated: true,
62
+ available: "unknown",
63
+ windows: [],
64
+ creditsRemaining: null
65
+ }, options.checkedAt);
66
+ }
67
+ const snapshot = await fetchOpenAiSubscriptionCapacity(credential, options);
68
+ return piOpenAiReport(snapshot, options.checkedAt);
69
+ }
70
+ export async function probeZaiCapacity(options) {
71
+ const key = await resolvePiZaiApiKey(options);
72
+ const snapshot = await fetchZaiCapacity(key, options);
73
+ return {
74
+ harness: "pi",
75
+ provider: "zai",
76
+ generatedAt: options.checkedAt,
77
+ ...snapshot
78
+ };
79
+ }
80
+
81
+ //# sourceMappingURL=pi.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/capacity/sources/pi.ts"],"sourcesContent":["import { fetchAnthropicCapacity } from \"../providers/anthropic.js\";\nimport { fetchOpenAiPlatformCapacity } from \"../providers/openai-platform.js\";\nimport { fetchOpenAiSubscriptionCapacity } from \"../providers/openai-subscription.js\";\nimport { fetchZaiCapacity } from \"../providers/zai.js\";\nimport type { CapacityReport, ProviderCapacitySnapshot } from \"../types.js\";\nimport {\n resolvePiAnthropicCredential,\n resolvePiOpenAiCredential,\n resolvePiZaiApiKey,\n type PiCredentialOptions,\n type PiOpenAiCredential,\n} from \"../../harnesses/pi/credentials.js\";\n\nexport type PiAnthropicCapacityOptions = PiCredentialOptions & {\n now?: () => Date;\n fetch?: typeof globalThis.fetch;\n timeoutMs?: number;\n};\n\nexport type PiAnthropicProbeOptions = PiAnthropicCapacityOptions & {\n checkedAt: string;\n};\n\nexport type PiOpenAiCapacityOptions = PiCredentialOptions & {\n now?: () => Date;\n fetch?: typeof globalThis.fetch;\n timeoutMs?: number;\n};\n\nexport type PiOpenAiProbeOptions = PiOpenAiCapacityOptions & {\n checkedAt: string;\n};\n\nexport type PiZaiCapacityOptions = PiCredentialOptions & {\n now?: () => Date;\n fetch?: typeof globalThis.fetch;\n timeoutMs?: number;\n};\n\nexport type PiZaiProbeOptions = PiZaiCapacityOptions & {\n checkedAt: string;\n};\n\nexport async function probePiAnthropicCapacity(\n options: PiAnthropicProbeOptions,\n): Promise<CapacityReport> {\n const credential = await resolvePiAnthropicCredential(options);\n const now = options.now?.() ?? new Date();\n if (credential.expiresMs !== null && credential.expiresMs <= now.getTime()) {\n return {\n harness: \"pi\",\n provider: \"anthropic\",\n generatedAt: options.checkedAt,\n authenticated: true,\n available: \"unknown\",\n windows: [],\n creditsRemaining: null,\n };\n }\n const snapshot = await fetchAnthropicCapacity(credential.access, options);\n return {\n harness: \"pi\",\n provider: \"anthropic\",\n generatedAt: options.checkedAt,\n ...snapshot,\n };\n}\n\nfunction piOpenAiReport(snapshot: ProviderCapacitySnapshot, checkedAt: string): CapacityReport {\n return {\n harness: \"pi\",\n provider: \"openai\",\n generatedAt: checkedAt,\n ...snapshot,\n };\n}\n\nfunction jwtExpiryMs(token: string): number | null {\n const part = token.split(\".\")[1];\n if (!part) return null;\n try {\n const payload = JSON.parse(Buffer.from(part, \"base64url\").toString(\"utf8\")) as unknown;\n if (!payload || typeof payload !== \"object\" || Array.isArray(payload)) return null;\n const exp = (payload as Record<string, unknown>).exp;\n return typeof exp === \"number\" && Number.isFinite(exp) ? exp * 1000 : null;\n } catch {\n return null;\n }\n}\n\nfunction oauthExpired(\n credential: Extract<PiOpenAiCredential, { kind: \"oauth\" }>,\n nowMs: number,\n): boolean {\n const expiryMs = credential.expiresMs ?? jwtExpiryMs(credential.access);\n return expiryMs !== null && expiryMs <= nowMs;\n}\n\nexport async function probeOpenAiCapacity(options: PiOpenAiProbeOptions): Promise<CapacityReport> {\n const credential = await resolvePiOpenAiCredential(options);\n if (credential.kind === \"platform\") {\n const snapshot = await fetchOpenAiPlatformCapacity(credential.key, options);\n return piOpenAiReport(snapshot, options.checkedAt);\n }\n\n const nowMs = Date.parse(options.checkedAt);\n if (Number.isNaN(nowMs) || oauthExpired(credential, nowMs)) {\n return piOpenAiReport(\n {\n authenticated: true,\n available: \"unknown\",\n windows: [],\n creditsRemaining: null,\n },\n options.checkedAt,\n );\n }\n const snapshot = await fetchOpenAiSubscriptionCapacity(credential, options);\n return piOpenAiReport(snapshot, options.checkedAt);\n}\n\nexport async function probeZaiCapacity(options: PiZaiProbeOptions): Promise<CapacityReport> {\n const key = await resolvePiZaiApiKey(options);\n const snapshot = await fetchZaiCapacity(key, options);\n return {\n harness: \"pi\",\n provider: \"zai\",\n generatedAt: options.checkedAt,\n ...snapshot,\n };\n}\n"],"names":["fetchAnthropicCapacity","fetchOpenAiPlatformCapacity","fetchOpenAiSubscriptionCapacity","fetchZaiCapacity","resolvePiAnthropicCredential","resolvePiOpenAiCredential","resolvePiZaiApiKey","probePiAnthropicCapacity","options","credential","now","Date","expiresMs","getTime","harness","provider","generatedAt","checkedAt","authenticated","available","windows","creditsRemaining","snapshot","access","piOpenAiReport","jwtExpiryMs","token","part","split","payload","JSON","parse","Buffer","from","toString","Array","isArray","exp","Number","isFinite","oauthExpired","nowMs","expiryMs","probeOpenAiCapacity","kind","key","isNaN","probeZaiCapacity"],"mappings":"AAAA,SAASA,sBAAsB,QAAQ,4BAA4B;AACnE,SAASC,2BAA2B,QAAQ,kCAAkC;AAC9E,SAASC,+BAA+B,QAAQ,sCAAsC;AACtF,SAASC,gBAAgB,QAAQ,sBAAsB;AAEvD,SACEC,4BAA4B,EAC5BC,yBAAyB,EACzBC,kBAAkB,QAGb,oCAAoC;AAgC3C,OAAO,eAAeC,yBACpBC,OAAgC;IAEhC,MAAMC,aAAa,MAAML,6BAA6BI;IACtD,MAAME,MAAMF,QAAQE,GAAG,QAAQ,IAAIC;IACnC,IAAIF,WAAWG,SAAS,KAAK,QAAQH,WAAWG,SAAS,IAAIF,IAAIG,OAAO,IAAI;QAC1E,OAAO;YACLC,SAAS;YACTC,UAAU;YACVC,aAAaR,QAAQS,SAAS;YAC9BC,eAAe;YACfC,WAAW;YACXC,SAAS,EAAE;YACXC,kBAAkB;QACpB;IACF;IACA,MAAMC,WAAW,MAAMtB,uBAAuBS,WAAWc,MAAM,EAAEf;IACjE,OAAO;QACLM,SAAS;QACTC,UAAU;QACVC,aAAaR,QAAQS,SAAS;QAC9B,GAAGK,QAAQ;IACb;AACF;AAEA,SAASE,eAAeF,QAAkC,EAAEL,SAAiB;IAC3E,OAAO;QACLH,SAAS;QACTC,UAAU;QACVC,aAAaC;QACb,GAAGK,QAAQ;IACb;AACF;AAEA,SAASG,YAAYC,KAAa;IAChC,MAAMC,OAAOD,MAAME,KAAK,CAAC,IAAI,CAAC,EAAE;IAChC,IAAI,CAACD,MAAM,OAAO;IAClB,IAAI;QACF,MAAME,UAAUC,KAAKC,KAAK,CAACC,OAAOC,IAAI,CAACN,MAAM,aAAaO,QAAQ,CAAC;QACnE,IAAI,CAACL,WAAW,OAAOA,YAAY,YAAYM,MAAMC,OAAO,CAACP,UAAU,OAAO;QAC9E,MAAMQ,MAAM,AAACR,QAAoCQ,GAAG;QACpD,OAAO,OAAOA,QAAQ,YAAYC,OAAOC,QAAQ,CAACF,OAAOA,MAAM,OAAO;IACxE,EAAE,OAAM;QACN,OAAO;IACT;AACF;AAEA,SAASG,aACP/B,UAA0D,EAC1DgC,KAAa;IAEb,MAAMC,WAAWjC,WAAWG,SAAS,IAAIa,YAAYhB,WAAWc,MAAM;IACtE,OAAOmB,aAAa,QAAQA,YAAYD;AAC1C;AAEA,OAAO,eAAeE,oBAAoBnC,OAA6B;IACrE,MAAMC,aAAa,MAAMJ,0BAA0BG;IACnD,IAAIC,WAAWmC,IAAI,KAAK,YAAY;QAClC,MAAMtB,WAAW,MAAMrB,4BAA4BQ,WAAWoC,GAAG,EAAErC;QACnE,OAAOgB,eAAeF,UAAUd,QAAQS,SAAS;IACnD;IAEA,MAAMwB,QAAQ9B,KAAKoB,KAAK,CAACvB,QAAQS,SAAS;IAC1C,IAAIqB,OAAOQ,KAAK,CAACL,UAAUD,aAAa/B,YAAYgC,QAAQ;QAC1D,OAAOjB,eACL;YACEN,eAAe;YACfC,WAAW;YACXC,SAAS,EAAE;YACXC,kBAAkB;QACpB,GACAb,QAAQS,SAAS;IAErB;IACA,MAAMK,WAAW,MAAMpB,gCAAgCO,YAAYD;IACnE,OAAOgB,eAAeF,UAAUd,QAAQS,SAAS;AACnD;AAEA,OAAO,eAAe8B,iBAAiBvC,OAA0B;IAC/D,MAAMqC,MAAM,MAAMvC,mBAAmBE;IACrC,MAAMc,WAAW,MAAMnB,iBAAiB0C,KAAKrC;IAC7C,OAAO;QACLM,SAAS;QACTC,UAAU;QACVC,aAAaR,QAAQS,SAAS;QAC9B,GAAGK,QAAQ;IACb;AACF"}
@@ -22,4 +22,6 @@ export interface CapacityReport {
22
22
  windows: CapacityWindow[];
23
23
  creditsRemaining: number | null;
24
24
  }
25
+ /** Provider quota data before a harness/source identity is attached. */
26
+ export type ProviderCapacitySnapshot = Omit<CapacityReport, "harness" | "provider" | "generatedAt">;
25
27
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/capacity/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG,IAAI,GAAG,SAAS,CAAC;AACpD,MAAM,MAAM,iBAAiB,GAAG,cAAc,GAAG,cAAc,GAAG,YAAY,CAAC;AAE/E,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,CAAC,EAAE,iBAAiB,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,cAAc;IAC7B,kEAAkE;IAClE,OAAO,EAAE,MAAM,CAAC;IAChB,kEAAkE;IAClE,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,OAAO,GAAG,IAAI,CAAC;IAC9B,SAAS,EAAE,YAAY,CAAC;IACxB,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/capacity/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG,IAAI,GAAG,SAAS,CAAC;AACpD,MAAM,MAAM,iBAAiB,GAAG,cAAc,GAAG,cAAc,GAAG,YAAY,CAAC;AAE/E,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,CAAC,EAAE,iBAAiB,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,cAAc;IAC7B,kEAAkE;IAClE,OAAO,EAAE,MAAM,CAAC;IAChB,kEAAkE;IAClE,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,OAAO,GAAG,IAAI,CAAC;IAC9B,SAAS,EAAE,YAAY,CAAC;IACxB,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAED,wEAAwE;AACxE,MAAM,MAAM,wBAAwB,GAAG,IAAI,CAAC,cAAc,EAAE,SAAS,GAAG,UAAU,GAAG,aAAa,CAAC,CAAC"}