@slkiser/opencode-quota 5.0.3 → 6.0.0-beta.1

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 (794) hide show
  1. package/README.md +30 -44
  2. package/dist/agent-tools.d.ts +24 -0
  3. package/dist/agent-tools.d.ts.map +1 -0
  4. package/dist/agent-tools.js +578 -0
  5. package/dist/agent-tools.js.map +1 -0
  6. package/dist/bin/opencode-quota.d.ts.map +1 -1
  7. package/dist/bin/opencode-quota.js +1 -32
  8. package/dist/bin/opencode-quota.js.map +1 -1
  9. package/dist/core/errors.d.ts +12 -0
  10. package/dist/core/errors.d.ts.map +1 -0
  11. package/dist/core/errors.js +141 -0
  12. package/dist/core/errors.js.map +1 -0
  13. package/dist/core/pace.d.ts +13 -0
  14. package/dist/core/pace.d.ts.map +1 -0
  15. package/dist/core/pace.js +52 -0
  16. package/dist/core/pace.js.map +1 -0
  17. package/dist/core/persist.d.ts +44 -0
  18. package/dist/core/persist.d.ts.map +1 -0
  19. package/dist/core/persist.js +210 -0
  20. package/dist/core/persist.js.map +1 -0
  21. package/dist/core/provider-source.d.ts +40 -0
  22. package/dist/core/provider-source.d.ts.map +1 -0
  23. package/dist/core/provider-source.js +210 -0
  24. package/dist/core/provider-source.js.map +1 -0
  25. package/dist/core/redact.d.ts +17 -0
  26. package/dist/core/redact.d.ts.map +1 -0
  27. package/dist/core/redact.js +217 -0
  28. package/dist/core/redact.js.map +1 -0
  29. package/dist/core/rows.d.ts +20 -0
  30. package/dist/core/rows.d.ts.map +1 -0
  31. package/dist/core/rows.js +142 -0
  32. package/dist/core/rows.js.map +1 -0
  33. package/dist/core/selection.d.ts +15 -0
  34. package/dist/core/selection.d.ts.map +1 -0
  35. package/dist/core/selection.js +43 -0
  36. package/dist/core/selection.js.map +1 -0
  37. package/dist/core/snapshot-publisher.d.ts +15 -0
  38. package/dist/core/snapshot-publisher.d.ts.map +1 -0
  39. package/dist/core/snapshot-publisher.js +57 -0
  40. package/dist/core/snapshot-publisher.js.map +1 -0
  41. package/dist/core/store.d.ts +93 -0
  42. package/dist/core/store.d.ts.map +1 -0
  43. package/dist/core/store.js +563 -0
  44. package/dist/core/store.js.map +1 -0
  45. package/dist/core/types.d.ts +186 -0
  46. package/dist/core/types.d.ts.map +1 -0
  47. package/dist/core/types.js +2 -0
  48. package/dist/core/types.js.map +1 -0
  49. package/dist/core/usage-ranges.d.ts +46 -0
  50. package/dist/core/usage-ranges.d.ts.map +1 -0
  51. package/dist/core/usage-ranges.js +72 -0
  52. package/dist/core/usage-ranges.js.map +1 -0
  53. package/dist/core/usage.d.ts +100 -0
  54. package/dist/core/usage.d.ts.map +1 -0
  55. package/dist/core/usage.js +373 -0
  56. package/dist/core/usage.js.map +1 -0
  57. package/dist/core/validate.d.ts +8 -0
  58. package/dist/core/validate.d.ts.map +1 -0
  59. package/dist/core/validate.js +167 -0
  60. package/dist/core/validate.js.map +1 -0
  61. package/dist/core/windows.d.ts +24 -0
  62. package/dist/core/windows.d.ts.map +1 -0
  63. package/dist/core/windows.js +43 -0
  64. package/dist/core/windows.js.map +1 -0
  65. package/dist/index.d.ts +2 -1
  66. package/dist/index.d.ts.map +1 -1
  67. package/dist/index.js.map +1 -1
  68. package/dist/lib/accounting-format.d.ts +2 -52
  69. package/dist/lib/accounting-format.d.ts.map +1 -1
  70. package/dist/lib/accounting-format.js +6 -255
  71. package/dist/lib/accounting-format.js.map +1 -1
  72. package/dist/lib/alibaba-auth.d.ts +14 -21
  73. package/dist/lib/alibaba-auth.d.ts.map +1 -1
  74. package/dist/lib/alibaba-auth.js +36 -149
  75. package/dist/lib/alibaba-auth.js.map +1 -1
  76. package/dist/lib/alibaba-coding-plan-local-quota.d.ts +1 -6
  77. package/dist/lib/alibaba-coding-plan-local-quota.d.ts.map +1 -1
  78. package/dist/lib/alibaba-coding-plan-local-quota.js +1 -1
  79. package/dist/lib/alibaba-coding-plan-local-quota.js.map +1 -1
  80. package/dist/lib/alibaba-token-plan.d.ts +18 -27
  81. package/dist/lib/alibaba-token-plan.d.ts.map +1 -1
  82. package/dist/lib/alibaba-token-plan.js +121 -285
  83. package/dist/lib/alibaba-token-plan.js.map +1 -1
  84. package/dist/lib/anthropic-auth.d.ts +3 -5
  85. package/dist/lib/anthropic-auth.d.ts.map +1 -1
  86. package/dist/lib/anthropic-auth.js +6 -9
  87. package/dist/lib/anthropic-auth.js.map +1 -1
  88. package/dist/lib/anthropic.d.ts +12 -37
  89. package/dist/lib/anthropic.d.ts.map +1 -1
  90. package/dist/lib/anthropic.js +348 -698
  91. package/dist/lib/anthropic.js.map +1 -1
  92. package/dist/lib/api-key-resolver.d.ts +165 -192
  93. package/dist/lib/api-key-resolver.d.ts.map +1 -1
  94. package/dist/lib/api-key-resolver.js +208 -234
  95. package/dist/lib/api-key-resolver.js.map +1 -1
  96. package/dist/lib/atomic-json.d.ts +4 -1
  97. package/dist/lib/atomic-json.d.ts.map +1 -1
  98. package/dist/lib/atomic-json.js +2 -3
  99. package/dist/lib/atomic-json.js.map +1 -1
  100. package/dist/lib/calendar-date.d.ts +15 -0
  101. package/dist/lib/calendar-date.d.ts.map +1 -0
  102. package/dist/lib/calendar-date.js +21 -0
  103. package/dist/lib/calendar-date.js.map +1 -0
  104. package/dist/lib/chutes.d.ts +0 -1
  105. package/dist/lib/chutes.d.ts.map +1 -1
  106. package/dist/lib/chutes.js +2 -4
  107. package/dist/lib/chutes.js.map +1 -1
  108. package/dist/lib/cli-reports.d.ts +15 -11
  109. package/dist/lib/cli-reports.d.ts.map +1 -1
  110. package/dist/lib/cli-reports.js +34 -107
  111. package/dist/lib/cli-reports.js.map +1 -1
  112. package/dist/lib/cli-show.d.ts +9 -22
  113. package/dist/lib/cli-show.d.ts.map +1 -1
  114. package/dist/lib/cli-show.js +104 -75
  115. package/dist/lib/cli-show.js.map +1 -1
  116. package/dist/lib/config-file-utils.d.ts +3 -15
  117. package/dist/lib/config-file-utils.d.ts.map +1 -1
  118. package/dist/lib/config-file-utils.js +4 -63
  119. package/dist/lib/config-file-utils.js.map +1 -1
  120. package/dist/lib/config-write-target.d.ts +4 -7
  121. package/dist/lib/config-write-target.d.ts.map +1 -1
  122. package/dist/lib/config-write-target.js +4 -18
  123. package/dist/lib/config-write-target.js.map +1 -1
  124. package/dist/lib/copilot.d.ts +29 -20
  125. package/dist/lib/copilot.d.ts.map +1 -1
  126. package/dist/lib/copilot.js +392 -649
  127. package/dist/lib/copilot.js.map +1 -1
  128. package/dist/lib/cursor-detection.d.ts +3 -3
  129. package/dist/lib/cursor-detection.d.ts.map +1 -1
  130. package/dist/lib/cursor-detection.js +44 -88
  131. package/dist/lib/cursor-detection.js.map +1 -1
  132. package/dist/lib/cursor-pricing.d.ts +71 -8
  133. package/dist/lib/cursor-pricing.d.ts.map +1 -1
  134. package/dist/lib/cursor-pricing.js +33 -125
  135. package/dist/lib/cursor-pricing.js.map +1 -1
  136. package/dist/lib/cursor-usage.d.ts +6 -4
  137. package/dist/lib/cursor-usage.d.ts.map +1 -1
  138. package/dist/lib/cursor-usage.js +27 -40
  139. package/dist/lib/cursor-usage.js.map +1 -1
  140. package/dist/lib/deepseek.d.ts +9 -17
  141. package/dist/lib/deepseek.d.ts.map +1 -1
  142. package/dist/lib/deepseek.js +24 -54
  143. package/dist/lib/deepseek.js.map +1 -1
  144. package/dist/lib/display-sanitize.d.ts +0 -8
  145. package/dist/lib/display-sanitize.d.ts.map +1 -1
  146. package/dist/lib/display-sanitize.js +0 -139
  147. package/dist/lib/display-sanitize.js.map +1 -1
  148. package/dist/lib/entries.d.ts +13 -239
  149. package/dist/lib/entries.d.ts.map +1 -1
  150. package/dist/lib/entries.js +1 -46
  151. package/dist/lib/entries.js.map +1 -1
  152. package/dist/lib/file-lock.d.ts +23 -0
  153. package/dist/lib/file-lock.d.ts.map +1 -0
  154. package/dist/lib/file-lock.js +122 -0
  155. package/dist/lib/file-lock.js.map +1 -0
  156. package/dist/lib/format-utils.d.ts +2 -82
  157. package/dist/lib/format-utils.d.ts.map +1 -1
  158. package/dist/lib/format-utils.js +2 -191
  159. package/dist/lib/format-utils.js.map +1 -1
  160. package/dist/lib/glm-coding-plan.d.ts +6 -5
  161. package/dist/lib/glm-coding-plan.d.ts.map +1 -1
  162. package/dist/lib/glm-coding-plan.js +19 -1
  163. package/dist/lib/glm-coding-plan.js.map +1 -1
  164. package/dist/lib/google-agy.d.ts +8 -40
  165. package/dist/lib/google-agy.d.ts.map +1 -1
  166. package/dist/lib/google-agy.js +88 -519
  167. package/dist/lib/google-agy.js.map +1 -1
  168. package/dist/lib/google-companion-credentials.d.ts +9 -40
  169. package/dist/lib/google-companion-credentials.d.ts.map +1 -1
  170. package/dist/lib/google-companion-credentials.js +167 -224
  171. package/dist/lib/google-companion-credentials.js.map +1 -1
  172. package/dist/lib/google-gemini-cli.d.ts +5 -38
  173. package/dist/lib/google-gemini-cli.d.ts.map +1 -1
  174. package/dist/lib/google-gemini-cli.js +71 -442
  175. package/dist/lib/google-gemini-cli.js.map +1 -1
  176. package/dist/lib/google-oauth-quota.d.ts +76 -0
  177. package/dist/lib/google-oauth-quota.d.ts.map +1 -0
  178. package/dist/lib/google-oauth-quota.js +297 -0
  179. package/dist/lib/google-oauth-quota.js.map +1 -0
  180. package/dist/lib/google-token-cache.d.ts +3 -5
  181. package/dist/lib/google-token-cache.d.ts.map +1 -1
  182. package/dist/lib/google-token-cache.js +2 -14
  183. package/dist/lib/google-token-cache.js.map +1 -1
  184. package/dist/lib/home-dir-display.d.ts.map +1 -1
  185. package/dist/lib/home-dir-display.js +21 -39
  186. package/dist/lib/home-dir-display.js.map +1 -1
  187. package/dist/lib/http.d.ts +4 -1
  188. package/dist/lib/http.d.ts.map +1 -1
  189. package/dist/lib/http.js +2 -1
  190. package/dist/lib/http.js.map +1 -1
  191. package/dist/lib/json-guards.d.ts +11 -0
  192. package/dist/lib/json-guards.d.ts.map +1 -0
  193. package/dist/lib/json-guards.js +25 -0
  194. package/dist/lib/json-guards.js.map +1 -0
  195. package/dist/lib/kilo.d.ts +0 -2
  196. package/dist/lib/kilo.d.ts.map +1 -1
  197. package/dist/lib/kilo.js +33 -116
  198. package/dist/lib/kilo.js.map +1 -1
  199. package/dist/lib/kimi-endpoints.d.ts +2 -2
  200. package/dist/lib/kimi-endpoints.d.ts.map +1 -1
  201. package/dist/lib/kimi-endpoints.js +1 -1
  202. package/dist/lib/kimi-endpoints.js.map +1 -1
  203. package/dist/lib/kimi.d.ts.map +1 -1
  204. package/dist/lib/kimi.js +40 -86
  205. package/dist/lib/kimi.js.map +1 -1
  206. package/dist/lib/maintainer-announcements.d.ts +4 -17
  207. package/dist/lib/maintainer-announcements.d.ts.map +1 -1
  208. package/dist/lib/maintainer-announcements.js +7 -44
  209. package/dist/lib/maintainer-announcements.js.map +1 -1
  210. package/dist/lib/maintainer-home-notice.d.ts +19 -0
  211. package/dist/lib/maintainer-home-notice.d.ts.map +1 -0
  212. package/dist/lib/maintainer-home-notice.js +92 -0
  213. package/dist/lib/maintainer-home-notice.js.map +1 -0
  214. package/dist/lib/mimo-config.d.ts +6 -9
  215. package/dist/lib/mimo-config.d.ts.map +1 -1
  216. package/dist/lib/mimo-config.js +43 -74
  217. package/dist/lib/mimo-config.js.map +1 -1
  218. package/dist/lib/mimo.d.ts +2 -5
  219. package/dist/lib/mimo.d.ts.map +1 -1
  220. package/dist/lib/mimo.js +57 -109
  221. package/dist/lib/mimo.js.map +1 -1
  222. package/dist/lib/minimax-endpoints.d.ts +2 -2
  223. package/dist/lib/minimax-endpoints.d.ts.map +1 -1
  224. package/dist/lib/minimax-endpoints.js +1 -1
  225. package/dist/lib/minimax-endpoints.js.map +1 -1
  226. package/dist/lib/modelsdev-pricing.d.ts +22 -16
  227. package/dist/lib/modelsdev-pricing.d.ts.map +1 -1
  228. package/dist/lib/modelsdev-pricing.js +279 -560
  229. package/dist/lib/modelsdev-pricing.js.map +1 -1
  230. package/dist/lib/nanogpt.d.ts +6 -6
  231. package/dist/lib/nanogpt.d.ts.map +1 -1
  232. package/dist/lib/nanogpt.js +19 -72
  233. package/dist/lib/nanogpt.js.map +1 -1
  234. package/dist/lib/ollama-cloud.d.ts +3 -6
  235. package/dist/lib/ollama-cloud.d.ts.map +1 -1
  236. package/dist/lib/ollama-cloud.js +26 -37
  237. package/dist/lib/ollama-cloud.js.map +1 -1
  238. package/dist/lib/openai.d.ts +18 -29
  239. package/dist/lib/openai.d.ts.map +1 -1
  240. package/dist/lib/openai.js +108 -182
  241. package/dist/lib/openai.js.map +1 -1
  242. package/dist/lib/opencode-auth-sqlite.d.ts.map +1 -1
  243. package/dist/lib/opencode-auth-sqlite.js +22 -23
  244. package/dist/lib/opencode-auth-sqlite.js.map +1 -1
  245. package/dist/lib/opencode-auth.d.ts +17 -11
  246. package/dist/lib/opencode-auth.d.ts.map +1 -1
  247. package/dist/lib/opencode-auth.js +39 -46
  248. package/dist/lib/opencode-auth.js.map +1 -1
  249. package/dist/lib/opencode-config-editor.d.ts +3 -34
  250. package/dist/lib/opencode-config-editor.d.ts.map +1 -1
  251. package/dist/lib/opencode-config-editor.js +23 -142
  252. package/dist/lib/opencode-config-editor.js.map +1 -1
  253. package/dist/lib/opencode-config-providers.d.ts +4 -3
  254. package/dist/lib/opencode-config-providers.d.ts.map +1 -1
  255. package/dist/lib/opencode-config-providers.js +7 -11
  256. package/dist/lib/opencode-config-providers.js.map +1 -1
  257. package/dist/lib/opencode-config-read.d.ts +2 -1
  258. package/dist/lib/opencode-config-read.d.ts.map +1 -1
  259. package/dist/lib/opencode-config-read.js +3 -2
  260. package/dist/lib/opencode-config-read.js.map +1 -1
  261. package/dist/lib/opencode-console-auth.d.ts +2 -3
  262. package/dist/lib/opencode-console-auth.d.ts.map +1 -1
  263. package/dist/lib/opencode-console-auth.js +2 -2
  264. package/dist/lib/opencode-console-auth.js.map +1 -1
  265. package/dist/lib/opencode-go.d.ts.map +1 -1
  266. package/dist/lib/opencode-go.js +51 -79
  267. package/dist/lib/opencode-go.js.map +1 -1
  268. package/dist/lib/opencode-storage.d.ts +18 -3
  269. package/dist/lib/opencode-storage.d.ts.map +1 -1
  270. package/dist/lib/opencode-storage.js +134 -2
  271. package/dist/lib/opencode-storage.js.map +1 -1
  272. package/dist/lib/opencode-zen.d.ts +15 -12
  273. package/dist/lib/opencode-zen.d.ts.map +1 -1
  274. package/dist/lib/opencode-zen.js +139 -147
  275. package/dist/lib/opencode-zen.js.map +1 -1
  276. package/dist/lib/openrouter.d.ts.map +1 -1
  277. package/dist/lib/openrouter.js +1 -13
  278. package/dist/lib/openrouter.js.map +1 -1
  279. package/dist/lib/pricing-key.d.ts +48 -0
  280. package/dist/lib/pricing-key.d.ts.map +1 -0
  281. package/dist/lib/pricing-key.js +371 -0
  282. package/dist/lib/pricing-key.js.map +1 -0
  283. package/dist/lib/provider-metadata.d.ts +16 -20
  284. package/dist/lib/provider-metadata.d.ts.map +1 -1
  285. package/dist/lib/provider-metadata.js +69 -69
  286. package/dist/lib/provider-metadata.js.map +1 -1
  287. package/dist/lib/provider-model-matching.d.ts +2 -1
  288. package/dist/lib/provider-model-matching.d.ts.map +1 -1
  289. package/dist/lib/provider-registration.d.ts +1 -177
  290. package/dist/lib/provider-registration.d.ts.map +1 -1
  291. package/dist/lib/provider-registration.js +1 -163
  292. package/dist/lib/provider-registration.js.map +1 -1
  293. package/dist/lib/quota-dialog-commands.d.ts +87 -53
  294. package/dist/lib/quota-dialog-commands.d.ts.map +1 -1
  295. package/dist/lib/quota-dialog-commands.js +259 -519
  296. package/dist/lib/quota-dialog-commands.js.map +1 -1
  297. package/dist/lib/quota-export-types.d.ts +29 -23
  298. package/dist/lib/quota-export-types.d.ts.map +1 -1
  299. package/dist/lib/quota-export.d.ts +16 -26
  300. package/dist/lib/quota-export.d.ts.map +1 -1
  301. package/dist/lib/quota-export.js +105 -147
  302. package/dist/lib/quota-export.js.map +1 -1
  303. package/dist/lib/quota-providers-local.d.ts +12 -8
  304. package/dist/lib/quota-providers-local.d.ts.map +1 -1
  305. package/dist/lib/quota-providers-local.js +150 -223
  306. package/dist/lib/quota-providers-local.js.map +1 -1
  307. package/dist/lib/quota-providers-remote.d.ts +3 -8
  308. package/dist/lib/quota-providers-remote.d.ts.map +1 -1
  309. package/dist/lib/quota-providers-remote.js +309 -449
  310. package/dist/lib/quota-providers-remote.js.map +1 -1
  311. package/dist/lib/quota-providers.d.ts +57 -15
  312. package/dist/lib/quota-providers.d.ts.map +1 -1
  313. package/dist/lib/quota-providers.js +157 -64
  314. package/dist/lib/quota-providers.js.map +1 -1
  315. package/dist/lib/quota-report-message.d.ts +23 -10
  316. package/dist/lib/quota-report-message.d.ts.map +1 -1
  317. package/dist/lib/quota-report-message.js +37 -13
  318. package/dist/lib/quota-report-message.js.map +1 -1
  319. package/dist/lib/quota-retry-wait.d.ts +14 -6
  320. package/dist/lib/quota-retry-wait.d.ts.map +1 -1
  321. package/dist/lib/quota-retry-wait.js +37 -39
  322. package/dist/lib/quota-retry-wait.js.map +1 -1
  323. package/dist/lib/quota-status.d.ts +50 -33
  324. package/dist/lib/quota-status.d.ts.map +1 -1
  325. package/dist/lib/quota-status.js +1113 -773
  326. package/dist/lib/quota-status.js.map +1 -1
  327. package/dist/lib/quota-telemetry.d.ts +7 -14
  328. package/dist/lib/quota-telemetry.d.ts.map +1 -1
  329. package/dist/lib/quota-telemetry.js +46 -97
  330. package/dist/lib/quota-telemetry.js.map +1 -1
  331. package/dist/lib/report-document.d.ts +5 -65
  332. package/dist/lib/report-document.d.ts.map +1 -1
  333. package/dist/lib/report-document.js +14 -167
  334. package/dist/lib/report-document.js.map +1 -1
  335. package/dist/lib/resolved-auth-identity.d.ts +1 -2
  336. package/dist/lib/resolved-auth-identity.d.ts.map +1 -1
  337. package/dist/lib/resolved-auth-identity.js +0 -4
  338. package/dist/lib/resolved-auth-identity.js.map +1 -1
  339. package/dist/lib/session-tokens.d.ts +19 -19
  340. package/dist/lib/session-tokens.d.ts.map +1 -1
  341. package/dist/lib/session-tokens.js +58 -44
  342. package/dist/lib/session-tokens.js.map +1 -1
  343. package/dist/lib/synthetic.d.ts +0 -1
  344. package/dist/lib/synthetic.d.ts.map +1 -1
  345. package/dist/lib/synthetic.js +43 -94
  346. package/dist/lib/synthetic.js.map +1 -1
  347. package/dist/lib/token-buckets.d.ts +0 -1
  348. package/dist/lib/token-buckets.d.ts.map +1 -1
  349. package/dist/lib/token-buckets.js +0 -3
  350. package/dist/lib/token-buckets.js.map +1 -1
  351. package/dist/lib/token-cost.d.ts +2 -1
  352. package/dist/lib/token-cost.d.ts.map +1 -1
  353. package/dist/lib/types.d.ts +25 -333
  354. package/dist/lib/types.d.ts.map +1 -1
  355. package/dist/lib/types.js +2 -70
  356. package/dist/lib/types.js.map +1 -1
  357. package/dist/lib/xai.d.ts +6 -6
  358. package/dist/lib/xai.d.ts.map +1 -1
  359. package/dist/lib/xai.js +51 -90
  360. package/dist/lib/xai.js.map +1 -1
  361. package/dist/plugin.d.ts +6 -3
  362. package/dist/plugin.d.ts.map +1 -1
  363. package/dist/plugin.js +315 -90
  364. package/dist/plugin.js.map +1 -1
  365. package/dist/providers/alibaba-coding-plan.d.ts +4 -0
  366. package/dist/providers/alibaba-coding-plan.d.ts.map +1 -1
  367. package/dist/providers/alibaba-coding-plan.js +47 -77
  368. package/dist/providers/alibaba-coding-plan.js.map +1 -1
  369. package/dist/providers/alibaba-token-plan.d.ts.map +1 -1
  370. package/dist/providers/alibaba-token-plan.js +34 -46
  371. package/dist/providers/alibaba-token-plan.js.map +1 -1
  372. package/dist/providers/anthropic.d.ts +2 -4
  373. package/dist/providers/anthropic.d.ts.map +1 -1
  374. package/dist/providers/anthropic.js +80 -162
  375. package/dist/providers/anthropic.js.map +1 -1
  376. package/dist/providers/cache-policies.d.ts +0 -2
  377. package/dist/providers/cache-policies.d.ts.map +1 -1
  378. package/dist/providers/cache-policies.js +38 -88
  379. package/dist/providers/cache-policies.js.map +1 -1
  380. package/dist/providers/chutes.d.ts +0 -3
  381. package/dist/providers/chutes.d.ts.map +1 -1
  382. package/dist/providers/chutes.js +16 -28
  383. package/dist/providers/chutes.js.map +1 -1
  384. package/dist/providers/contract.d.ts +128 -0
  385. package/dist/providers/contract.d.ts.map +1 -0
  386. package/dist/providers/contract.js +101 -0
  387. package/dist/providers/contract.js.map +1 -0
  388. package/dist/providers/copilot.d.ts.map +1 -1
  389. package/dist/providers/copilot.js +171 -175
  390. package/dist/providers/copilot.js.map +1 -1
  391. package/dist/providers/cursor.d.ts.map +1 -1
  392. package/dist/providers/cursor.js +56 -109
  393. package/dist/providers/cursor.js.map +1 -1
  394. package/dist/providers/deepseek.d.ts +1 -6
  395. package/dist/providers/deepseek.d.ts.map +1 -1
  396. package/dist/providers/deepseek.js +46 -81
  397. package/dist/providers/deepseek.js.map +1 -1
  398. package/dist/providers/glm-coding-plan.d.ts +8 -0
  399. package/dist/providers/glm-coding-plan.d.ts.map +1 -0
  400. package/dist/providers/glm-coding-plan.js +106 -0
  401. package/dist/providers/glm-coding-plan.js.map +1 -0
  402. package/dist/providers/google-agy.d.ts +0 -1
  403. package/dist/providers/google-agy.d.ts.map +1 -1
  404. package/dist/providers/google-agy.js +41 -192
  405. package/dist/providers/google-agy.js.map +1 -1
  406. package/dist/providers/google-gemini-cli.d.ts.map +1 -1
  407. package/dist/providers/google-gemini-cli.js +51 -151
  408. package/dist/providers/google-gemini-cli.js.map +1 -1
  409. package/dist/providers/google-oauth-provider.d.ts +39 -0
  410. package/dist/providers/google-oauth-provider.d.ts.map +1 -0
  411. package/dist/providers/google-oauth-provider.js +161 -0
  412. package/dist/providers/google-oauth-provider.js.map +1 -0
  413. package/dist/providers/kilo.d.ts +0 -3
  414. package/dist/providers/kilo.d.ts.map +1 -1
  415. package/dist/providers/kilo.js +69 -123
  416. package/dist/providers/kilo.js.map +1 -1
  417. package/dist/providers/kimi-code.d.ts +5 -0
  418. package/dist/providers/kimi-code.d.ts.map +1 -1
  419. package/dist/providers/kimi-code.js +91 -136
  420. package/dist/providers/kimi-code.js.map +1 -1
  421. package/dist/providers/mimo.d.ts.map +1 -1
  422. package/dist/providers/mimo.js +55 -94
  423. package/dist/providers/mimo.js.map +1 -1
  424. package/dist/providers/minimax-coding-plan.d.ts +2 -23
  425. package/dist/providers/minimax-coding-plan.d.ts.map +1 -1
  426. package/dist/providers/minimax-coding-plan.js +161 -277
  427. package/dist/providers/minimax-coding-plan.js.map +1 -1
  428. package/dist/providers/nanogpt.d.ts +0 -3
  429. package/dist/providers/nanogpt.d.ts.map +1 -1
  430. package/dist/providers/nanogpt.js +61 -95
  431. package/dist/providers/nanogpt.js.map +1 -1
  432. package/dist/providers/ollama-cloud.d.ts +0 -6
  433. package/dist/providers/ollama-cloud.d.ts.map +1 -1
  434. package/dist/providers/ollama-cloud.js +86 -112
  435. package/dist/providers/ollama-cloud.js.map +1 -1
  436. package/dist/providers/openai.d.ts.map +1 -1
  437. package/dist/providers/openai.js +144 -166
  438. package/dist/providers/openai.js.map +1 -1
  439. package/dist/providers/opencode-go.d.ts.map +1 -1
  440. package/dist/providers/opencode-go.js +157 -199
  441. package/dist/providers/opencode-go.js.map +1 -1
  442. package/dist/providers/opencode-zen.d.ts.map +1 -1
  443. package/dist/providers/opencode-zen.js +100 -150
  444. package/dist/providers/opencode-zen.js.map +1 -1
  445. package/dist/providers/openrouter.d.ts +0 -3
  446. package/dist/providers/openrouter.d.ts.map +1 -1
  447. package/dist/providers/openrouter.js +26 -13
  448. package/dist/providers/openrouter.js.map +1 -1
  449. package/dist/providers/quota-providers.d.ts +7 -3
  450. package/dist/providers/quota-providers.d.ts.map +1 -1
  451. package/dist/providers/quota-providers.js +111 -217
  452. package/dist/providers/quota-providers.js.map +1 -1
  453. package/dist/providers/registry.d.ts.map +1 -1
  454. package/dist/providers/registry.js +1 -2
  455. package/dist/providers/registry.js.map +1 -1
  456. package/dist/providers/result-helpers.d.ts +10 -37
  457. package/dist/providers/result-helpers.d.ts.map +1 -1
  458. package/dist/providers/result-helpers.js +23 -56
  459. package/dist/providers/result-helpers.js.map +1 -1
  460. package/dist/providers/synthetic.d.ts +0 -3
  461. package/dist/providers/synthetic.d.ts.map +1 -1
  462. package/dist/providers/synthetic.js +16 -58
  463. package/dist/providers/synthetic.js.map +1 -1
  464. package/dist/providers/xai.d.ts +2 -1
  465. package/dist/providers/xai.d.ts.map +1 -1
  466. package/dist/providers/xai.js +49 -71
  467. package/dist/providers/xai.js.map +1 -1
  468. package/dist/rpc.d.ts +110 -38
  469. package/dist/rpc.d.ts.map +1 -1
  470. package/dist/rpc.js +125 -37
  471. package/dist/rpc.js.map +1 -1
  472. package/dist/settings/convert.d.ts +60 -0
  473. package/dist/settings/convert.d.ts.map +1 -0
  474. package/dist/settings/convert.js +473 -0
  475. package/dist/settings/convert.js.map +1 -0
  476. package/dist/settings/file.d.ts +89 -0
  477. package/dist/settings/file.d.ts.map +1 -0
  478. package/dist/settings/file.js +452 -0
  479. package/dist/settings/file.js.map +1 -0
  480. package/dist/settings/index.d.ts +10 -0
  481. package/dist/settings/index.d.ts.map +1 -0
  482. package/dist/settings/index.js +3 -0
  483. package/dist/settings/index.js.map +1 -0
  484. package/dist/settings/schema.d.ts +607 -0
  485. package/dist/settings/schema.d.ts.map +1 -0
  486. package/dist/settings/schema.js +479 -0
  487. package/dist/settings/schema.js.map +1 -0
  488. package/dist/tui/client.d.ts +86 -0
  489. package/dist/tui/client.d.ts.map +1 -0
  490. package/dist/tui/client.js +229 -0
  491. package/dist/tui/client.js.map +1 -0
  492. package/dist/tui/display.d.ts +127 -0
  493. package/dist/tui/display.d.ts.map +1 -0
  494. package/dist/tui/display.js +474 -0
  495. package/dist/tui/display.js.map +1 -0
  496. package/dist/tui/index.d.ts +21 -0
  497. package/dist/tui/index.d.ts.map +1 -0
  498. package/dist/tui/index.js +305 -0
  499. package/dist/tui/server-settings.d.ts +43 -0
  500. package/dist/tui/server-settings.d.ts.map +1 -0
  501. package/dist/tui/server-settings.js +233 -0
  502. package/dist/tui/server-settings.js.map +1 -0
  503. package/dist/tui/sidebar.d.ts +41 -0
  504. package/dist/tui/sidebar.d.ts.map +1 -0
  505. package/dist/tui/sidebar.js +148 -0
  506. package/dist/tui/status-line.d.ts +14 -0
  507. package/dist/tui/status-line.d.ts.map +1 -0
  508. package/dist/tui/status-line.js +225 -0
  509. package/dist/tui/theme.d.ts +41 -0
  510. package/dist/tui/theme.d.ts.map +1 -0
  511. package/dist/tui/theme.js +52 -0
  512. package/dist/tui/theme.js.map +1 -0
  513. package/dist/tui/toast-colors.d.ts +37 -0
  514. package/dist/tui/toast-colors.d.ts.map +1 -0
  515. package/dist/tui/toast-colors.js +77 -0
  516. package/dist/tui/toasts.d.ts +59 -0
  517. package/dist/tui/toasts.d.ts.map +1 -0
  518. package/dist/tui/toasts.js +148 -0
  519. package/dist/tui/toasts.js.map +1 -0
  520. package/dist/tui/window/drag.d.ts +26 -0
  521. package/dist/tui/window/drag.d.ts.map +1 -0
  522. package/dist/tui/window/drag.js +80 -0
  523. package/dist/tui/window/drag.js.map +1 -0
  524. package/dist/tui/window/limits.d.ts +15 -0
  525. package/dist/tui/window/limits.d.ts.map +1 -0
  526. package/dist/tui/window/limits.js +227 -0
  527. package/dist/tui/window/limits.js.map +1 -0
  528. package/dist/tui/window/rail.d.ts +21 -0
  529. package/dist/tui/window/rail.d.ts.map +1 -0
  530. package/dist/tui/window/rail.js +81 -0
  531. package/dist/tui/window/settings.d.ts +164 -0
  532. package/dist/tui/window/settings.d.ts.map +1 -0
  533. package/dist/tui/window/settings.js +1679 -0
  534. package/dist/tui/window/shell.d.ts +108 -0
  535. package/dist/tui/window/shell.d.ts.map +1 -0
  536. package/dist/tui/window/shell.js +1003 -0
  537. package/dist/tui/window/usage.d.ts +75 -0
  538. package/dist/tui/window/usage.d.ts.map +1 -0
  539. package/dist/tui/window/usage.js +928 -0
  540. package/dist/tui/window/views.d.ts +61 -0
  541. package/dist/tui/window/views.d.ts.map +1 -0
  542. package/dist/tui/window/views.js +242 -0
  543. package/dist/tui.d.ts +1 -5
  544. package/dist/tui.js +1 -894
  545. package/dist/view/columns.d.ts +15 -0
  546. package/dist/view/columns.d.ts.map +1 -0
  547. package/dist/view/columns.js +48 -0
  548. package/dist/view/columns.js.map +1 -0
  549. package/dist/view/format.d.ts +82 -0
  550. package/dist/view/format.d.ts.map +1 -0
  551. package/dist/view/format.js +201 -0
  552. package/dist/view/format.js.map +1 -0
  553. package/dist/view/quick-look.d.ts +28 -0
  554. package/dist/view/quick-look.d.ts.map +1 -0
  555. package/dist/view/quick-look.js +150 -0
  556. package/dist/view/quick-look.js.map +1 -0
  557. package/dist/view/select.d.ts +67 -0
  558. package/dist/view/select.d.ts.map +1 -0
  559. package/dist/view/select.js +87 -0
  560. package/dist/view/select.js.map +1 -0
  561. package/dist/view/text.d.ts +153 -0
  562. package/dist/view/text.d.ts.map +1 -0
  563. package/dist/view/text.js +642 -0
  564. package/dist/view/text.js.map +1 -0
  565. package/dist/view/usage.d.ts +86 -0
  566. package/dist/view/usage.d.ts.map +1 -0
  567. package/dist/view/usage.js +724 -0
  568. package/dist/view/usage.js.map +1 -0
  569. package/package.json +4 -6
  570. package/dist/lib/chutes-config.d.ts +0 -15
  571. package/dist/lib/chutes-config.d.ts.map +0 -1
  572. package/dist/lib/chutes-config.js +0 -28
  573. package/dist/lib/chutes-config.js.map +0 -1
  574. package/dist/lib/cli-status.d.ts +0 -8
  575. package/dist/lib/cli-status.d.ts.map +0 -1
  576. package/dist/lib/cli-status.js +0 -98
  577. package/dist/lib/cli-status.js.map +0 -1
  578. package/dist/lib/command-parsing.d.ts +0 -43
  579. package/dist/lib/command-parsing.d.ts.map +0 -1
  580. package/dist/lib/command-parsing.js +0 -103
  581. package/dist/lib/command-parsing.js.map +0 -1
  582. package/dist/lib/config.d.ts +0 -63
  583. package/dist/lib/config.d.ts.map +0 -1
  584. package/dist/lib/config.js +0 -1092
  585. package/dist/lib/config.js.map +0 -1
  586. package/dist/lib/deepseek-auth.d.ts +0 -15
  587. package/dist/lib/deepseek-auth.d.ts.map +0 -1
  588. package/dist/lib/deepseek-auth.js +0 -28
  589. package/dist/lib/deepseek-auth.js.map +0 -1
  590. package/dist/lib/format.d.ts +0 -25
  591. package/dist/lib/format.d.ts.map +0 -1
  592. package/dist/lib/format.js +0 -300
  593. package/dist/lib/format.js.map +0 -1
  594. package/dist/lib/google-agy-companion.d.ts +0 -8
  595. package/dist/lib/google-agy-companion.d.ts.map +0 -1
  596. package/dist/lib/google-agy-companion.js +0 -64
  597. package/dist/lib/google-agy-companion.js.map +0 -1
  598. package/dist/lib/google-gemini-cli-companion.d.ts +0 -8
  599. package/dist/lib/google-gemini-cli-companion.d.ts.map +0 -1
  600. package/dist/lib/google-gemini-cli-companion.js +0 -64
  601. package/dist/lib/google-gemini-cli-companion.js.map +0 -1
  602. package/dist/lib/grouped-entry-normalization.d.ts +0 -12
  603. package/dist/lib/grouped-entry-normalization.d.ts.map +0 -1
  604. package/dist/lib/grouped-entry-normalization.js +0 -124
  605. package/dist/lib/grouped-entry-normalization.js.map +0 -1
  606. package/dist/lib/grouped-header-format.d.ts +0 -5
  607. package/dist/lib/grouped-header-format.d.ts.map +0 -1
  608. package/dist/lib/grouped-header-format.js +0 -16
  609. package/dist/lib/grouped-header-format.js.map +0 -1
  610. package/dist/lib/init-installer.d.ts +0 -123
  611. package/dist/lib/init-installer.d.ts.map +0 -1
  612. package/dist/lib/init-installer.js +0 -1111
  613. package/dist/lib/init-installer.js.map +0 -1
  614. package/dist/lib/jsonc.d.ts +0 -17
  615. package/dist/lib/jsonc.d.ts.map +0 -1
  616. package/dist/lib/jsonc.js +0 -23
  617. package/dist/lib/jsonc.js.map +0 -1
  618. package/dist/lib/kilo-config.d.ts +0 -15
  619. package/dist/lib/kilo-config.d.ts.map +0 -1
  620. package/dist/lib/kilo-config.js +0 -27
  621. package/dist/lib/kilo-config.js.map +0 -1
  622. package/dist/lib/kimi-auth.d.ts +0 -49
  623. package/dist/lib/kimi-auth.d.ts.map +0 -1
  624. package/dist/lib/kimi-auth.js +0 -82
  625. package/dist/lib/kimi-auth.js.map +0 -1
  626. package/dist/lib/markdown-table.d.ts +0 -51
  627. package/dist/lib/markdown-table.d.ts.map +0 -1
  628. package/dist/lib/markdown-table.js +0 -179
  629. package/dist/lib/markdown-table.js.map +0 -1
  630. package/dist/lib/minimax-auth.d.ts +0 -62
  631. package/dist/lib/minimax-auth.d.ts.map +0 -1
  632. package/dist/lib/minimax-auth.js +0 -206
  633. package/dist/lib/minimax-auth.js.map +0 -1
  634. package/dist/lib/nanogpt-config.d.ts +0 -15
  635. package/dist/lib/nanogpt-config.d.ts.map +0 -1
  636. package/dist/lib/nanogpt-config.js +0 -31
  637. package/dist/lib/nanogpt-config.js.map +0 -1
  638. package/dist/lib/ollama-cloud-config.d.ts +0 -15
  639. package/dist/lib/ollama-cloud-config.d.ts.map +0 -1
  640. package/dist/lib/ollama-cloud-config.js +0 -27
  641. package/dist/lib/ollama-cloud-config.js.map +0 -1
  642. package/dist/lib/opencode-go-auth.d.ts +0 -16
  643. package/dist/lib/opencode-go-auth.d.ts.map +0 -1
  644. package/dist/lib/opencode-go-auth.js +0 -42
  645. package/dist/lib/opencode-go-auth.js.map +0 -1
  646. package/dist/lib/opencode-version.d.ts +0 -6
  647. package/dist/lib/opencode-version.d.ts.map +0 -1
  648. package/dist/lib/opencode-version.js +0 -26
  649. package/dist/lib/opencode-version.js.map +0 -1
  650. package/dist/lib/provider-add-command.d.ts +0 -35
  651. package/dist/lib/provider-add-command.d.ts.map +0 -1
  652. package/dist/lib/provider-add-command.js +0 -204
  653. package/dist/lib/provider-add-command.js.map +0 -1
  654. package/dist/lib/provider-add-json-v1-questionnaire.d.ts +0 -32
  655. package/dist/lib/provider-add-json-v1-questionnaire.d.ts.map +0 -1
  656. package/dist/lib/provider-add-json-v1-questionnaire.js +0 -336
  657. package/dist/lib/provider-add-json-v1-questionnaire.js.map +0 -1
  658. package/dist/lib/provider-add.d.ts +0 -21
  659. package/dist/lib/provider-add.d.ts.map +0 -1
  660. package/dist/lib/provider-add.js +0 -219
  661. package/dist/lib/provider-add.js.map +0 -1
  662. package/dist/lib/quota-accounting-projection.d.ts +0 -9
  663. package/dist/lib/quota-accounting-projection.d.ts.map +0 -1
  664. package/dist/lib/quota-accounting-projection.js +0 -254
  665. package/dist/lib/quota-accounting-projection.js.map +0 -1
  666. package/dist/lib/quota-columns.d.ts +0 -38
  667. package/dist/lib/quota-columns.d.ts.map +0 -1
  668. package/dist/lib/quota-columns.js +0 -129
  669. package/dist/lib/quota-columns.js.map +0 -1
  670. package/dist/lib/quota-command-format.d.ts +0 -34
  671. package/dist/lib/quota-command-format.d.ts.map +0 -1
  672. package/dist/lib/quota-command-format.js +0 -240
  673. package/dist/lib/quota-command-format.js.map +0 -1
  674. package/dist/lib/quota-dialog-command-specs.d.ts +0 -63
  675. package/dist/lib/quota-dialog-command-specs.d.ts.map +0 -1
  676. package/dist/lib/quota-dialog-command-specs.js +0 -145
  677. package/dist/lib/quota-dialog-command-specs.js.map +0 -1
  678. package/dist/lib/quota-entry-display.d.ts +0 -7
  679. package/dist/lib/quota-entry-display.d.ts.map +0 -1
  680. package/dist/lib/quota-entry-display.js +0 -59
  681. package/dist/lib/quota-entry-display.js.map +0 -1
  682. package/dist/lib/quota-exhaustion-projection.d.ts +0 -11
  683. package/dist/lib/quota-exhaustion-projection.d.ts.map +0 -1
  684. package/dist/lib/quota-exhaustion-projection.js +0 -105
  685. package/dist/lib/quota-exhaustion-projection.js.map +0 -1
  686. package/dist/lib/quota-format-style.d.ts +0 -21
  687. package/dist/lib/quota-format-style.d.ts.map +0 -1
  688. package/dist/lib/quota-format-style.js +0 -38
  689. package/dist/lib/quota-format-style.js.map +0 -1
  690. package/dist/lib/quota-render-data.d.ts +0 -102
  691. package/dist/lib/quota-render-data.d.ts.map +0 -1
  692. package/dist/lib/quota-render-data.js +0 -419
  693. package/dist/lib/quota-render-data.js.map +0 -1
  694. package/dist/lib/quota-reset-notifications.d.ts +0 -20
  695. package/dist/lib/quota-reset-notifications.d.ts.map +0 -1
  696. package/dist/lib/quota-reset-notifications.js +0 -331
  697. package/dist/lib/quota-reset-notifications.js.map +0 -1
  698. package/dist/lib/quota-runtime-context.d.ts +0 -54
  699. package/dist/lib/quota-runtime-context.d.ts.map +0 -1
  700. package/dist/lib/quota-runtime-context.js +0 -110
  701. package/dist/lib/quota-runtime-context.js.map +0 -1
  702. package/dist/lib/quota-state-codec.d.ts +0 -16
  703. package/dist/lib/quota-state-codec.d.ts.map +0 -1
  704. package/dist/lib/quota-state-codec.js +0 -412
  705. package/dist/lib/quota-state-codec.js.map +0 -1
  706. package/dist/lib/quota-state.d.ts +0 -28
  707. package/dist/lib/quota-state.d.ts.map +0 -1
  708. package/dist/lib/quota-state.js +0 -473
  709. package/dist/lib/quota-state.js.map +0 -1
  710. package/dist/lib/quota-stats-format.d.ts +0 -29
  711. package/dist/lib/quota-stats-format.d.ts.map +0 -1
  712. package/dist/lib/quota-stats-format.js +0 -459
  713. package/dist/lib/quota-stats-format.js.map +0 -1
  714. package/dist/lib/quota-stats.d.ts +0 -126
  715. package/dist/lib/quota-stats.d.ts.map +0 -1
  716. package/dist/lib/quota-stats.js +0 -695
  717. package/dist/lib/quota-stats.js.map +0 -1
  718. package/dist/lib/quota-surface-data.d.ts +0 -21
  719. package/dist/lib/quota-surface-data.d.ts.map +0 -1
  720. package/dist/lib/quota-surface-data.js +0 -362
  721. package/dist/lib/quota-surface-data.js.map +0 -1
  722. package/dist/lib/scoped-update-migration.d.ts +0 -103
  723. package/dist/lib/scoped-update-migration.d.ts.map +0 -1
  724. package/dist/lib/scoped-update-migration.js +0 -344
  725. package/dist/lib/scoped-update-migration.js.map +0 -1
  726. package/dist/lib/scoped-update.d.ts +0 -77
  727. package/dist/lib/scoped-update.d.ts.map +0 -1
  728. package/dist/lib/scoped-update.js +0 -590
  729. package/dist/lib/scoped-update.js.map +0 -1
  730. package/dist/lib/session-tokens-format.d.ts +0 -36
  731. package/dist/lib/session-tokens-format.d.ts.map +0 -1
  732. package/dist/lib/session-tokens-format.js +0 -111
  733. package/dist/lib/session-tokens-format.js.map +0 -1
  734. package/dist/lib/synthetic-config.d.ts +0 -15
  735. package/dist/lib/synthetic-config.d.ts.map +0 -1
  736. package/dist/lib/synthetic-config.js +0 -28
  737. package/dist/lib/synthetic-config.js.map +0 -1
  738. package/dist/lib/toast-format-grouped.d.ts +0 -25
  739. package/dist/lib/toast-format-grouped.d.ts.map +0 -1
  740. package/dist/lib/toast-format-grouped.js +0 -296
  741. package/dist/lib/toast-format-grouped.js.map +0 -1
  742. package/dist/lib/tui-compact-format.d.ts +0 -10
  743. package/dist/lib/tui-compact-format.d.ts.map +0 -1
  744. package/dist/lib/tui-compact-format.js +0 -460
  745. package/dist/lib/tui-compact-format.js.map +0 -1
  746. package/dist/lib/tui-panel-state.d.ts +0 -15
  747. package/dist/lib/tui-panel-state.d.ts.map +0 -1
  748. package/dist/lib/tui-panel-state.js +0 -2
  749. package/dist/lib/tui-panel-state.js.map +0 -1
  750. package/dist/lib/tui-prompt-bar-format.d.ts +0 -25
  751. package/dist/lib/tui-prompt-bar-format.d.ts.map +0 -1
  752. package/dist/lib/tui-prompt-bar-format.js +0 -206
  753. package/dist/lib/tui-prompt-bar-format.js.map +0 -1
  754. package/dist/lib/tui-sidebar-format.d.ts +0 -13
  755. package/dist/lib/tui-sidebar-format.d.ts.map +0 -1
  756. package/dist/lib/tui-sidebar-format.js +0 -34
  757. package/dist/lib/tui-sidebar-format.js.map +0 -1
  758. package/dist/lib/zai-auth.d.ts +0 -15
  759. package/dist/lib/zai-auth.d.ts.map +0 -1
  760. package/dist/lib/zai-auth.js +0 -37
  761. package/dist/lib/zai-auth.js.map +0 -1
  762. package/dist/lib/zai.d.ts +0 -5
  763. package/dist/lib/zai.d.ts.map +0 -1
  764. package/dist/lib/zai.js +0 -14
  765. package/dist/lib/zai.js.map +0 -1
  766. package/dist/lib/zhipu-auth.d.ts +0 -15
  767. package/dist/lib/zhipu-auth.d.ts.map +0 -1
  768. package/dist/lib/zhipu-auth.js +0 -42
  769. package/dist/lib/zhipu-auth.js.map +0 -1
  770. package/dist/lib/zhipu.d.ts +0 -5
  771. package/dist/lib/zhipu.d.ts.map +0 -1
  772. package/dist/lib/zhipu.js +0 -13
  773. package/dist/lib/zhipu.js.map +0 -1
  774. package/dist/providers/glm-coding-plan-provider.d.ts +0 -56
  775. package/dist/providers/glm-coding-plan-provider.d.ts.map +0 -1
  776. package/dist/providers/glm-coding-plan-provider.js +0 -115
  777. package/dist/providers/glm-coding-plan-provider.js.map +0 -1
  778. package/dist/providers/google-account-format.d.ts +0 -7
  779. package/dist/providers/google-account-format.d.ts.map +0 -1
  780. package/dist/providers/google-account-format.js +0 -52
  781. package/dist/providers/google-account-format.js.map +0 -1
  782. package/dist/providers/zai.d.ts +0 -2
  783. package/dist/providers/zai.d.ts.map +0 -1
  784. package/dist/providers/zai.js +0 -24
  785. package/dist/providers/zai.js.map +0 -1
  786. package/dist/providers/zhipu.d.ts +0 -2
  787. package/dist/providers/zhipu.d.ts.map +0 -1
  788. package/dist/providers/zhipu.js +0 -21
  789. package/dist/providers/zhipu.js.map +0 -1
  790. package/dist/tui-v2.d.ts +0 -5
  791. package/dist/tui-v2.d.ts.map +0 -1
  792. package/dist/tui-v2.jsx +0 -624
  793. package/dist/tui-v2.jsx.map +0 -1
  794. package/dist/tui.d.ts.map +0 -1
@@ -1,36 +1,31 @@
1
- import { createProviderApiKeyResolver, getApiKeyCheckedPaths, getGlobalOpencodeConfigCandidatePaths, } from "./api-key-resolver.js";
1
+ import { isIsoTime } from "../core/validate.js";
2
+ import { getApiKeyCheckedPaths, resolveApiKey } from "./api-key-resolver.js";
2
3
  import { sanitizeSingleLineDisplayText } from "./display-sanitize.js";
3
- import { getCredentialDatabasePaths, readAuthFile } from "./opencode-auth.js";
4
- import { JSON_V1_MAX_DISPLAY_CODE_POINTS, JSON_V1_MAX_NUMBER_MAGNITUDE, normalizeJsonV1Timestamp, } from "./quota-providers.js";
5
- import { REQUEST_TIMEOUT_MS } from "./types.js";
4
+ import { fmtUsdAmount } from "./format-utils.js";
5
+ import { REQUEST_TIMEOUT_MS } from "./http.js";
6
+ import { hasOnlyKeys, isRecord } from "./json-guards.js";
7
+ import { getCredentialDatabasePaths } from "./opencode-auth.js";
8
+ import { CUSTOM_RESULT_TYPES, customRow, customRowKey, JSON_V1_MAX_DISPLAY_CODE_POINTS, JSON_V1_MAX_NUMBER_MAGNITUDE, normalizeJsonV1Timestamp, } from "./quota-providers.js";
6
9
  export const QUOTA_PROVIDER_MAX_BODY_BYTES = 256 * 1024;
7
- export const QUOTA_PROVIDER_MAX_REMOTE_ROWS = 100;
8
- export const JSON_V1_MAX_RESPONSE_DEPTH = 32;
9
- export const JSON_V1_MAX_CANDIDATES = 1_600;
10
- export const JSON_V1_MAX_ENTRIES = 100;
11
- export const JSON_V1_MAX_DETAILED_ERRORS = 16;
12
- export const QUOTA_PROVIDER_CONCURRENCY = 4;
13
- const RESULT_TYPES = new Set([
14
- "quota",
15
- "rate_limit",
16
- "usage",
17
- "spend",
18
- "budget",
19
- "balance",
20
- "status",
21
- ]);
22
- const ISO_TIMESTAMP_RE = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$/;
10
+ const MAX_REMOTE_ROWS = 100;
11
+ const JSON_V1_MAX_RESPONSE_DEPTH = 32;
12
+ const JSON_V1_MAX_CANDIDATES = 1_600;
13
+ const JSON_V1_MAX_ENTRIES = 100;
14
+ const JSON_V1_MAX_DETAILED_ERRORS = 16;
15
+ const PERCENT_RESULT_TYPES = new Set(["quota", "rate_limit", "budget"]);
16
+ /** `right` and `observedAtIso` are checked but not shown. */
17
+ const QUOTA_V1_ROW_KEYS = [
18
+ "kind",
19
+ "name",
20
+ "resultType",
21
+ "percentRemaining",
22
+ "value",
23
+ "label",
24
+ "right",
25
+ "resetTimeIso",
26
+ "observedAtIso",
27
+ ];
23
28
  const JSON_V1_DECIMAL_TEXT_RE = /^-?\d+(?:\.\d+)?$/;
24
- function isRecord(value) {
25
- return Boolean(value) && typeof value === "object" && !Array.isArray(value);
26
- }
27
- function hasOnlyKeys(value, allowed) {
28
- const allowedSet = new Set(allowed);
29
- return Object.keys(value).every((key) => allowedSet.has(key));
30
- }
31
- function isIsoTimestamp(value) {
32
- return (typeof value === "string" && ISO_TIMESTAMP_RE.test(value) && Number.isFinite(Date.parse(value)));
33
- }
34
29
  function boundedDisplayText(value, maxCodePoints) {
35
30
  if (typeof value !== "string")
36
31
  return null;
@@ -38,185 +33,156 @@ function boundedDisplayText(value, maxCodePoints) {
38
33
  const length = Array.from(normalized).length;
39
34
  return length >= 1 && length <= maxCodePoints ? normalized : null;
40
35
  }
41
- function formatUsd(value) {
42
- return `$${value.toFixed(2)}`;
43
- }
44
- function accountingMetadata(resultType, observedAtIso) {
45
- return {
46
- resultType,
47
- acquisitionMethod: "remote_api",
48
- ownership: "user_configured",
49
- authority: "provider_reported",
50
- ...(observedAtIso ? { observedAtIso } : {}),
51
- };
52
- }
53
36
  export async function resolveQuotaProviderApiKey(source) {
54
- const resolver = createProviderApiKeyResolver({
55
- envVars: source.apiKeyEnv ? [{ name: source.apiKeyEnv, source: "env" }] : [],
37
+ // A switched-off provider's key is never read, whoever asks.
38
+ if (source.enabled === false) {
39
+ return { source: null, checkedPaths: [], credentialDatabasePaths: [] };
40
+ }
41
+ const spec = {
42
+ envVars: source.apiKeyEnv ? [source.apiKeyEnv] : [],
56
43
  providerKeys: [source.providerId],
57
- allowedEnvVars: source.apiKeyEnv ? [source.apiKeyEnv] : [],
58
- configJsonSource: "opencode.json",
59
- configJsoncSource: "opencode.jsonc",
60
- getConfigCandidates: getGlobalOpencodeConfigCandidatePaths,
61
- auth: {
62
- // Key logins only: `providerId` can name an integration with OAuth sign-ins
63
- // (for example `opencode`), and resolving one could refresh its token for nothing.
64
- readAuth: () => readAuthFile({ integrationIds: [source.providerId], methods: ["key"] }),
65
- authKeys: [source.providerId],
66
- authSource: "opencode.db",
67
- },
68
- });
69
- const resolved = await resolver.resolve();
44
+ // Key logins only: `providerId` can name an integration with OAuth sign-ins
45
+ // (for example `opencode`), and resolving one could refresh its token for nothing.
46
+ keyLoginsOnly: true,
47
+ };
48
+ const resolved = await resolveApiKey(spec);
70
49
  return {
71
50
  ...(resolved ? { key: resolved.key } : {}),
72
- source: resolved?.source ?? null,
73
- checkedPaths: getApiKeyCheckedPaths({
74
- envVarNames: source.apiKeyEnv ? [source.apiKeyEnv] : [],
75
- getConfigCandidates: getGlobalOpencodeConfigCandidatePaths,
76
- }),
51
+ // Custom providers report every environment variable source as plain "env".
52
+ source: !resolved
53
+ ? null
54
+ : resolved.source.startsWith("env:")
55
+ ? "env"
56
+ : resolved.source,
57
+ checkedPaths: getApiKeyCheckedPaths(spec),
77
58
  credentialDatabasePaths: getCredentialDatabasePaths(),
78
59
  };
79
60
  }
61
+ function isJsonContentType(response) {
62
+ const type = response.headers.get("content-type")?.split(";", 1)[0]?.trim().toLowerCase();
63
+ if (!type)
64
+ return false;
65
+ return type === "application/json" || (type.startsWith("application/") && type.endsWith("+json"));
66
+ }
67
+ /** Reads at most QUOTA_PROVIDER_MAX_BODY_BYTES, so a huge reply never sits in memory. */
80
68
  async function readBoundedJson(response) {
81
- const contentType = response.headers.get("content-type")?.split(";", 1)[0]?.trim().toLowerCase();
82
- if (!contentType ||
83
- (contentType !== "application/json" &&
84
- !(contentType.startsWith("application/") && contentType.endsWith("+json")))) {
85
- throw new Error("Expected a JSON response");
86
- }
87
- const contentLength = response.headers.get("content-length");
88
- if (contentLength) {
89
- const parsedLength = Number(contentLength);
90
- if (Number.isFinite(parsedLength) && parsedLength > QUOTA_PROVIDER_MAX_BODY_BYTES) {
91
- throw new Error("Response exceeded 262144 bytes");
92
- }
69
+ const tooLarge = {
70
+ ok: false,
71
+ error: `Response exceeded ${QUOTA_PROVIDER_MAX_BODY_BYTES} bytes`,
72
+ };
73
+ if (!isJsonContentType(response))
74
+ return { ok: false, error: "Expected a JSON response" };
75
+ const declaredLength = Number(response.headers.get("content-length"));
76
+ if (Number.isFinite(declaredLength) && declaredLength > QUOTA_PROVIDER_MAX_BODY_BYTES) {
77
+ return tooLarge;
93
78
  }
94
- let bytes;
79
+ let text = "";
95
80
  if (response.body) {
96
81
  const reader = response.body.getReader();
97
- const chunks = [];
82
+ const decoder = new TextDecoder();
98
83
  let total = 0;
99
84
  try {
100
- while (true) {
101
- const next = await reader.read();
102
- if (next.done)
103
- break;
85
+ for (let next = await reader.read(); !next.done; next = await reader.read()) {
104
86
  total += next.value.byteLength;
105
87
  if (total > QUOTA_PROVIDER_MAX_BODY_BYTES) {
106
88
  await reader.cancel();
107
- throw new Error("Response exceeded 262144 bytes");
89
+ return tooLarge;
108
90
  }
109
- chunks.push(next.value);
91
+ text += decoder.decode(next.value, { stream: true });
110
92
  }
93
+ text += decoder.decode();
111
94
  }
112
95
  finally {
113
96
  reader.releaseLock();
114
97
  }
115
- bytes = new Uint8Array(total);
116
- let offset = 0;
117
- for (const chunk of chunks) {
118
- bytes.set(chunk, offset);
119
- offset += chunk.byteLength;
120
- }
121
- }
122
- else {
123
- const buffer = new Uint8Array(await response.arrayBuffer());
124
- if (buffer.byteLength > QUOTA_PROVIDER_MAX_BODY_BYTES) {
125
- throw new Error("Response exceeded 262144 bytes");
126
- }
127
- bytes = buffer;
128
98
  }
129
99
  try {
130
- return JSON.parse(new TextDecoder().decode(bytes));
100
+ return { ok: true, body: JSON.parse(text) };
131
101
  }
132
102
  catch {
133
- throw new Error("Invalid JSON response");
103
+ return { ok: false, error: "Invalid JSON response" };
104
+ }
105
+ }
106
+ /** A quota-v1 row keyed by its name. */
107
+ function parseQuotaV1Row(raw) {
108
+ if (!isRecord(raw) || !hasOnlyKeys(raw, QUOTA_V1_ROW_KEYS))
109
+ return null;
110
+ const name = boundedDisplayText(raw.name, 80);
111
+ const resultType = typeof raw.resultType === "string" &&
112
+ CUSTOM_RESULT_TYPES.has(raw.resultType)
113
+ ? raw.resultType
114
+ : null;
115
+ // Optional fields are undefined when absent and null when present but invalid.
116
+ const label = raw.label === undefined ? undefined : boundedDisplayText(raw.label, 80);
117
+ const right = raw.right === undefined ? undefined : boundedDisplayText(raw.right, 160);
118
+ const resetTimeIso = raw.resetTimeIso === undefined
119
+ ? undefined
120
+ : isIsoTime(raw.resetTimeIso)
121
+ ? raw.resetTimeIso
122
+ : null;
123
+ const observedAtIso = raw.observedAtIso === undefined
124
+ ? undefined
125
+ : isIsoTime(raw.observedAtIso)
126
+ ? raw.observedAtIso
127
+ : null;
128
+ if (!name ||
129
+ !resultType ||
130
+ label === null ||
131
+ right === null ||
132
+ resetTimeIso === null ||
133
+ observedAtIso === null) {
134
+ return null;
134
135
  }
136
+ const row = (value) => customRow({
137
+ key: customRowKey(name),
138
+ name,
139
+ label,
140
+ resultType,
141
+ method: "remote_api",
142
+ value,
143
+ resetsAt: resetTimeIso,
144
+ });
145
+ if (raw.kind === "percent" &&
146
+ typeof raw.percentRemaining === "number" &&
147
+ Number.isFinite(raw.percentRemaining) &&
148
+ raw.percentRemaining <= 100 &&
149
+ PERCENT_RESULT_TYPES.has(resultType) &&
150
+ raw.value === undefined) {
151
+ return row({ percentRemaining: raw.percentRemaining });
152
+ }
153
+ const value = boundedDisplayText(raw.value, 160);
154
+ if (raw.kind === "value" && value !== null && raw.percentRemaining === undefined) {
155
+ return row({ text: value });
156
+ }
157
+ return null;
135
158
  }
136
- function parseQuotaV1(source, body) {
159
+ function parseQuotaV1(body) {
160
+ const invalid = { success: false, error: "Invalid quota-v1 response" };
137
161
  if (!isRecord(body) ||
138
162
  !hasOnlyKeys(body, ["version", "entries"]) ||
139
163
  body.version !== "quota-v1" ||
140
- !Array.isArray(body.entries)) {
141
- return { success: false, error: "Invalid quota-v1 response" };
164
+ !Array.isArray(body.entries) ||
165
+ body.entries.length < 1 ||
166
+ body.entries.length > MAX_REMOTE_ROWS) {
167
+ return invalid;
142
168
  }
143
- if (body.entries.length < 1 || body.entries.length > QUOTA_PROVIDER_MAX_REMOTE_ROWS) {
144
- return { success: false, error: "Invalid quota-v1 response" };
145
- }
146
- const entries = [];
169
+ const rows = [];
147
170
  for (const raw of body.entries) {
148
- if (!isRecord(raw) ||
149
- !hasOnlyKeys(raw, [
150
- "kind",
151
- "name",
152
- "resultType",
153
- "percentRemaining",
154
- "value",
155
- "label",
156
- "right",
157
- "resetTimeIso",
158
- "observedAtIso",
159
- ])) {
160
- return { success: false, error: "Invalid quota-v1 response" };
161
- }
162
- const name = boundedDisplayText(raw.name, 80);
163
- const resultType = typeof raw.resultType === "string" && RESULT_TYPES.has(raw.resultType)
164
- ? raw.resultType
165
- : null;
166
- const label = raw.label === undefined ? undefined : boundedDisplayText(raw.label, 80);
167
- const right = raw.right === undefined ? undefined : boundedDisplayText(raw.right, 160);
168
- const resetTimeIso = raw.resetTimeIso === undefined
169
- ? undefined
170
- : isIsoTimestamp(raw.resetTimeIso)
171
- ? raw.resetTimeIso
172
- : null;
173
- const observedAtIso = raw.observedAtIso === undefined
174
- ? undefined
175
- : isIsoTimestamp(raw.observedAtIso)
176
- ? raw.observedAtIso
177
- : null;
178
- if (!name ||
179
- !resultType ||
180
- (raw.label !== undefined && label === null) ||
181
- (raw.right !== undefined && right === null) ||
182
- resetTimeIso === null ||
183
- observedAtIso === null) {
184
- return { success: false, error: "Invalid quota-v1 response" };
185
- }
186
- const common = {
187
- accounting: accountingMetadata(resultType, observedAtIso),
188
- name: `${source.label} ${name}`,
189
- group: source.label,
190
- ...(label ? { label } : {}),
191
- ...(right ? { right } : {}),
192
- ...(resetTimeIso ? { resetTimeIso } : {}),
193
- };
194
- if (raw.kind === "percent" &&
195
- typeof raw.percentRemaining === "number" &&
196
- Number.isFinite(raw.percentRemaining) &&
197
- raw.percentRemaining <= 100 &&
198
- ["quota", "rate_limit", "budget"].includes(resultType) &&
199
- raw.value === undefined) {
200
- entries.push({ ...common, kind: "percent", percentRemaining: raw.percentRemaining });
201
- continue;
202
- }
203
- const value = boundedDisplayText(raw.value, 160);
204
- if (raw.kind === "value" && value !== null && raw.percentRemaining === undefined) {
205
- entries.push({ ...common, kind: "value", value });
206
- continue;
207
- }
208
- return { success: false, error: "Invalid quota-v1 response" };
171
+ const row = parseQuotaV1Row(raw);
172
+ if (!row)
173
+ return invalid;
174
+ rows.push(row);
209
175
  }
210
- return { success: true, entries };
176
+ return { success: true, rows };
211
177
  }
212
- function isJsonV1ResponseDepthValid(value) {
178
+ function exceedsJsonDepth(value, maxDepth) {
213
179
  if (!value || typeof value !== "object")
214
- return true;
180
+ return false;
215
181
  const stack = [{ value, depth: 1 }];
216
182
  while (stack.length > 0) {
217
183
  const current = stack.pop();
218
- if (current.depth > JSON_V1_MAX_RESPONSE_DEPTH)
219
- return false;
184
+ if (current.depth > maxDepth)
185
+ return true;
220
186
  const children = Array.isArray(current.value) ? current.value : Object.values(current.value);
221
187
  for (const child of children) {
222
188
  if (child && typeof child === "object") {
@@ -224,270 +190,169 @@ function isJsonV1ResponseDepthValid(value) {
224
190
  }
225
191
  }
226
192
  }
227
- return true;
193
+ return false;
228
194
  }
229
195
  function resolveJsonV1Path(root, path) {
230
196
  let current = root;
231
- for (let index = 0; index < path.length; index += 1) {
197
+ for (const segment of path) {
232
198
  if (!isRecord(current))
233
- return { state: "wrong-type" };
234
- const segment = path[index];
199
+ return { ok: false, issue: "had wrong type" };
235
200
  if (!Object.hasOwn(current, segment))
236
- return { state: "missing" };
201
+ return { ok: false, issue: "was missing" };
237
202
  current = current[segment];
238
203
  if (current === null)
239
- return { state: "null" };
240
- if (index < path.length - 1 && !isRecord(current))
241
- return { state: "wrong-type" };
204
+ return { ok: false, issue: "was null" };
242
205
  }
243
- return { state: "value", value: current };
206
+ return { ok: true, value: current };
244
207
  }
245
- function jsonV1SourceValue(row, source) {
246
- if ("literal" in source) {
247
- return source.literal === null ? { state: "null" } : { state: "value", value: source.literal };
248
- }
249
- return resolveJsonV1Path(row, source.path);
250
- }
251
- function jsonV1ResolutionIssue(resolution) {
252
- switch (resolution.state) {
253
- case "missing":
254
- return "was missing";
255
- case "null":
256
- return "was null";
257
- case "wrong-type":
258
- return "had wrong type";
259
- }
208
+ function resolveJsonV1Source(row, source) {
209
+ return "literal" in source
210
+ ? { ok: true, value: source.literal }
211
+ : resolveJsonV1Path(row, source.path);
260
212
  }
261
213
  function resolveJsonV1Number(row, source) {
262
- const resolution = jsonV1SourceValue(row, source);
263
- if (resolution.state !== "value") {
264
- return { ok: false, issue: jsonV1ResolutionIssue(resolution) };
265
- }
214
+ const resolved = resolveJsonV1Source(row, source);
215
+ if (!resolved.ok)
216
+ return resolved;
266
217
  // Some APIs write numbers as text (`"95.50"`); only a plain decimal is read as a number.
267
- const raw = typeof resolution.value === "string" && JSON_V1_DECIMAL_TEXT_RE.test(resolution.value.trim())
268
- ? Number(resolution.value.trim())
269
- : resolution.value;
218
+ const raw = typeof resolved.value === "string" && JSON_V1_DECIMAL_TEXT_RE.test(resolved.value.trim())
219
+ ? Number(resolved.value.trim())
220
+ : resolved.value;
270
221
  if (typeof raw !== "number" || !Number.isFinite(raw)) {
271
222
  return { ok: false, issue: "had wrong type" };
272
223
  }
273
224
  if (Math.abs(raw) > JSON_V1_MAX_NUMBER_MAGNITUDE) {
274
225
  return { ok: false, issue: "exceeded the numeric magnitude limit" };
275
226
  }
276
- const value = "path" in source && source.divideBy !== undefined ? raw / source.divideBy : raw;
277
- return Number.isFinite(value)
278
- ? { ok: true, value }
279
- : { ok: false, issue: "did not resolve to a finite number" };
227
+ const divideBy = "path" in source ? source.divideBy : undefined;
228
+ return { ok: true, value: divideBy === undefined ? raw : raw / divideBy };
280
229
  }
281
230
  function resolveJsonV1Text(row, source) {
282
- const resolution = jsonV1SourceValue(row, source);
283
- if (resolution.state !== "value") {
284
- return { ok: false, issue: jsonV1ResolutionIssue(resolution) };
285
- }
286
- if (typeof resolution.value !== "string") {
231
+ const resolved = resolveJsonV1Source(row, source);
232
+ if (!resolved.ok)
233
+ return resolved;
234
+ if (typeof resolved.value !== "string")
287
235
  return { ok: false, issue: "had wrong type" };
288
- }
289
- const normalized = boundedDisplayText(resolution.value, JSON_V1_MAX_DISPLAY_CODE_POINTS);
290
- return normalized
291
- ? { ok: true, value: normalized }
236
+ const text = boundedDisplayText(resolved.value, JSON_V1_MAX_DISPLAY_CODE_POINTS);
237
+ return text
238
+ ? { ok: true, value: text }
292
239
  : { ok: false, issue: "did not resolve to bounded display text" };
293
240
  }
294
- function resolveJsonV1TimestampSource(row, source) {
295
- const resolution = jsonV1SourceValue(row, source);
296
- if (resolution.state !== "value") {
297
- return { ok: false, issue: jsonV1ResolutionIssue(resolution) };
298
- }
299
- const normalized = normalizeJsonV1Timestamp(resolution.value, source.encoding);
300
- return normalized
301
- ? { ok: true, value: normalized }
241
+ function resolveJsonV1Timestamp(row, source) {
242
+ const resolved = resolveJsonV1Source(row, source);
243
+ if (!resolved.ok)
244
+ return resolved;
245
+ const timestamp = normalizeJsonV1Timestamp(resolved.value, source.encoding);
246
+ return timestamp
247
+ ? { ok: true, value: timestamp }
302
248
  : { ok: false, issue: "did not resolve to a valid timestamp" };
303
249
  }
304
250
  function jsonV1CandidateError(mappingIndex, field, issue, rowIndex) {
305
251
  return `adapter.mappings[${mappingIndex}].${field} ${issue} at row ${rowIndex}`;
306
252
  }
307
253
  function formatJsonV1Value(value, mapping) {
308
- const text = String(value);
309
- if (!mapping.unit)
310
- return text;
311
- return mapping.unitPosition === "prefix" ? `${mapping.unit}${text}` : `${text} ${mapping.unit}`;
312
- }
313
- function formatJsonV1Pair(left, right, mapping) {
314
- const pair = `${String(left)}/${String(right)}`;
315
254
  if (!mapping.unit)
316
- return pair;
317
- return mapping.unitPosition === "prefix"
318
- ? `${mapping.unit}${String(left)}/${mapping.unit}${String(right)}`
319
- : `${pair} ${mapping.unit}`;
255
+ return `${value}`;
256
+ return mapping.unitPosition === "prefix" ? `${mapping.unit}${value}` : `${value} ${mapping.unit}`;
320
257
  }
321
- function jsonV1DerivedPercentageIssue(value) {
322
- if (!Number.isFinite(value))
323
- return "produced a non-finite percentage";
324
- if (Math.abs(value) > JSON_V1_MAX_NUMBER_MAGNITUDE) {
325
- return "produced a percentage beyond the numeric magnitude limit";
326
- }
327
- return null;
328
- }
329
- function mapJsonV1Candidate(source, row, rowIndex, mapping, mappingIndex) {
258
+ /** One mapping applied to one reply row: a row keyed by the mapping's name, or why not. */
259
+ function mapJsonV1Candidate(row, rowIndex, mapping, mappingIndex) {
330
260
  const fail = (field, issue) => ({
331
261
  error: jsonV1CandidateError(mappingIndex, field, issue, rowIndex),
332
262
  });
333
263
  let resetTimeIso;
334
264
  if (mapping.resetTime) {
335
- const resolved = resolveJsonV1TimestampSource(row, mapping.resetTime);
265
+ const resolved = resolveJsonV1Timestamp(row, mapping.resetTime);
336
266
  if (!resolved.ok)
337
267
  return fail("resetTime", resolved.issue);
338
268
  resetTimeIso = resolved.value;
339
269
  }
340
- let observedAtIso;
270
+ // The observed time is checked but not shown.
341
271
  if (mapping.observedTime) {
342
- const resolved = resolveJsonV1TimestampSource(row, mapping.observedTime);
272
+ const resolved = resolveJsonV1Timestamp(row, mapping.observedTime);
343
273
  if (!resolved.ok)
344
274
  return fail("observedTime", resolved.issue);
345
- observedAtIso = resolved.value;
346
275
  }
347
- const common = {
348
- accounting: accountingMetadata(mapping.resultType, observedAtIso),
349
- name: `${source.label} ${mapping.name}`,
350
- group: source.label,
351
- ...(mapping.label ? { label: mapping.label } : {}),
352
- ...(resetTimeIso ? { resetTimeIso } : {}),
276
+ const mapped = (value) => ({
277
+ row: customRow({
278
+ key: customRowKey(mapping.name),
279
+ name: mapping.name,
280
+ label: mapping.label,
281
+ resultType: mapping.resultType,
282
+ method: "remote_api",
283
+ value,
284
+ resetsAt: resetTimeIso,
285
+ }),
286
+ });
287
+ // Shared by used-limit, remaining-limit, spend-budget and remaining-budget:
288
+ // an amount (used, spent, or remaining) out of a positive total.
289
+ const share = (amountKey, amountSource, totalKey, totalSource) => {
290
+ const amountField = `metric.${amountKey}`;
291
+ const totalField = `metric.${totalKey}`;
292
+ const amountIsRemaining = amountKey === "remaining";
293
+ const amount = resolveJsonV1Number(row, amountSource);
294
+ if (!amount.ok)
295
+ return fail(amountField, amount.issue);
296
+ const total = resolveJsonV1Number(row, totalSource);
297
+ if (!total.ok)
298
+ return fail(totalField, total.issue);
299
+ if (!amountIsRemaining && amount.value < 0)
300
+ return fail(amountField, "must be non-negative");
301
+ if (total.value <= 0)
302
+ return fail(totalField, "must be greater than zero");
303
+ if (amountIsRemaining && amount.value > total.value) {
304
+ return fail(amountField, `must not exceed ${totalKey}`);
305
+ }
306
+ const percentRemaining = amountIsRemaining
307
+ ? (amount.value / total.value) * 100
308
+ : ((total.value - amount.value) / total.value) * 100;
309
+ // Finite operands can still overflow, for example a tiny literal total.
310
+ if (!Number.isFinite(percentRemaining)) {
311
+ return fail(totalField, "produced a non-finite percentage");
312
+ }
313
+ if (Math.abs(percentRemaining) > JSON_V1_MAX_NUMBER_MAGNITUDE) {
314
+ return fail(totalField, "produced a percentage beyond the numeric magnitude limit");
315
+ }
316
+ return mapped({ percentRemaining });
353
317
  };
354
- switch (mapping.metric.type) {
318
+ const { metric } = mapping;
319
+ switch (metric.type) {
355
320
  case "percentage": {
356
- const percentage = resolveJsonV1Number(row, mapping.metric.percentage);
321
+ const percentage = resolveJsonV1Number(row, metric.percentage);
357
322
  if (!percentage.ok)
358
323
  return fail("metric.percentage", percentage.issue);
359
- if (mapping.metric.meaning === "remaining" && percentage.value > 100) {
324
+ if (metric.meaning === "remaining" && percentage.value > 100) {
360
325
  return fail("metric.percentage", "must not exceed 100 for remaining meaning");
361
326
  }
362
- if (mapping.metric.meaning === "used" && percentage.value < 0) {
327
+ if (metric.meaning === "used" && percentage.value < 0) {
363
328
  return fail("metric.percentage", "must be non-negative for used meaning");
364
329
  }
365
- return {
366
- entry: {
367
- ...common,
368
- kind: "percent",
369
- percentRemaining: mapping.metric.meaning === "remaining" ? percentage.value : 100 - percentage.value,
370
- },
371
- };
372
- }
373
- case "used-limit": {
374
- const used = resolveJsonV1Number(row, mapping.metric.used);
375
- if (!used.ok)
376
- return fail("metric.used", used.issue);
377
- const limit = resolveJsonV1Number(row, mapping.metric.limit);
378
- if (!limit.ok)
379
- return fail("metric.limit", limit.issue);
380
- if (used.value < 0)
381
- return fail("metric.used", "must be non-negative");
382
- if (limit.value <= 0)
383
- return fail("metric.limit", "must be greater than zero");
384
- const percentRemaining = ((limit.value - used.value) / limit.value) * 100;
385
- const percentageIssue = jsonV1DerivedPercentageIssue(percentRemaining);
386
- if (percentageIssue)
387
- return fail("metric.limit", percentageIssue);
388
- return {
389
- entry: {
390
- ...common,
391
- kind: "percent",
392
- percentRemaining,
393
- right: formatJsonV1Pair(used.value, limit.value, mapping),
394
- },
395
- };
396
- }
397
- case "remaining-limit": {
398
- const remaining = resolveJsonV1Number(row, mapping.metric.remaining);
399
- if (!remaining.ok)
400
- return fail("metric.remaining", remaining.issue);
401
- const limit = resolveJsonV1Number(row, mapping.metric.limit);
402
- if (!limit.ok)
403
- return fail("metric.limit", limit.issue);
404
- if (limit.value <= 0)
405
- return fail("metric.limit", "must be greater than zero");
406
- if (remaining.value > limit.value) {
407
- return fail("metric.remaining", "must not exceed limit");
408
- }
409
- const percentRemaining = (remaining.value / limit.value) * 100;
410
- const percentageIssue = jsonV1DerivedPercentageIssue(percentRemaining);
411
- if (percentageIssue)
412
- return fail("metric.limit", percentageIssue);
413
- return {
414
- entry: {
415
- ...common,
416
- kind: "percent",
417
- percentRemaining,
418
- right: formatJsonV1Pair(remaining.value, limit.value, mapping),
419
- },
420
- };
421
- }
422
- case "spend-budget": {
423
- const spend = resolveJsonV1Number(row, mapping.metric.spend);
424
- if (!spend.ok)
425
- return fail("metric.spend", spend.issue);
426
- const budget = resolveJsonV1Number(row, mapping.metric.budget);
427
- if (!budget.ok)
428
- return fail("metric.budget", budget.issue);
429
- if (spend.value < 0)
430
- return fail("metric.spend", "must be non-negative");
431
- if (budget.value <= 0)
432
- return fail("metric.budget", "must be greater than zero");
433
- const percentRemaining = ((budget.value - spend.value) / budget.value) * 100;
434
- const percentageIssue = jsonV1DerivedPercentageIssue(percentRemaining);
435
- if (percentageIssue)
436
- return fail("metric.budget", percentageIssue);
437
- return {
438
- entry: {
439
- ...common,
440
- kind: "percent",
441
- percentRemaining,
442
- right: formatJsonV1Pair(spend.value, budget.value, mapping),
443
- },
444
- };
445
- }
446
- case "remaining-budget": {
447
- const remaining = resolveJsonV1Number(row, mapping.metric.remaining);
448
- if (!remaining.ok)
449
- return fail("metric.remaining", remaining.issue);
450
- const budget = resolveJsonV1Number(row, mapping.metric.budget);
451
- if (!budget.ok)
452
- return fail("metric.budget", budget.issue);
453
- if (budget.value <= 0)
454
- return fail("metric.budget", "must be greater than zero");
455
- if (remaining.value > budget.value) {
456
- return fail("metric.remaining", "must not exceed budget");
457
- }
458
- const percentRemaining = (remaining.value / budget.value) * 100;
459
- const percentageIssue = jsonV1DerivedPercentageIssue(percentRemaining);
460
- if (percentageIssue)
461
- return fail("metric.budget", percentageIssue);
462
- return {
463
- entry: {
464
- ...common,
465
- kind: "percent",
466
- percentRemaining,
467
- right: formatJsonV1Pair(remaining.value, budget.value, mapping),
468
- },
469
- };
330
+ const percentRemaining = metric.meaning === "remaining" ? percentage.value : 100 - percentage.value;
331
+ return mapped({ percentRemaining });
470
332
  }
333
+ case "used-limit":
334
+ return share("used", metric.used, "limit", metric.limit);
335
+ case "remaining-limit":
336
+ return share("remaining", metric.remaining, "limit", metric.limit);
337
+ case "spend-budget":
338
+ return share("spend", metric.spend, "budget", metric.budget);
339
+ case "remaining-budget":
340
+ return share("remaining", metric.remaining, "budget", metric.budget);
471
341
  case "value": {
472
- const value = resolveJsonV1Number(row, mapping.metric.value);
342
+ const value = resolveJsonV1Number(row, metric.value);
473
343
  if (!value.ok)
474
344
  return fail("metric.value", value.issue);
475
- if (!["remaining", "balance"].includes(mapping.metric.valueType) && value.value < 0) {
345
+ // Remaining and balance values may legitimately be negative (overdrawn).
346
+ const mayBeNegative = metric.valueType === "remaining" || metric.valueType === "balance";
347
+ if (!mayBeNegative && value.value < 0)
476
348
  return fail("metric.value", "must be non-negative");
477
- }
478
- return {
479
- entry: {
480
- ...common,
481
- kind: "value",
482
- value: formatJsonV1Value(value.value, mapping),
483
- },
484
- };
349
+ return mapped({ text: formatJsonV1Value(value.value, mapping) });
485
350
  }
486
351
  case "status": {
487
- const value = resolveJsonV1Text(row, mapping.metric.value);
352
+ const value = resolveJsonV1Text(row, metric.value);
488
353
  if (!value.ok)
489
354
  return fail("metric.value", value.issue);
490
- return { entry: { ...common, kind: "value", value: value.value } };
355
+ return mapped({ text: value.value });
491
356
  }
492
357
  }
493
358
  }
@@ -496,7 +361,7 @@ function parseJsonV1(source, body) {
496
361
  success: false,
497
362
  error: `Invalid json-v1 response: ${message}`,
498
363
  });
499
- if (!isJsonV1ResponseDepthValid(body)) {
364
+ if (exceedsJsonDepth(body, JSON_V1_MAX_RESPONSE_DEPTH)) {
500
365
  return invalid(`nesting depth exceeded ${JSON_V1_MAX_RESPONSE_DEPTH}`);
501
366
  }
502
367
  let rows;
@@ -504,9 +369,8 @@ function parseJsonV1(source, body) {
504
369
  if (!isRecord(body))
505
370
  return invalid("adapter.rowsPath requires an object root");
506
371
  const resolved = resolveJsonV1Path(body, source.adapter.rowsPath);
507
- if (resolved.state !== "value") {
508
- return invalid(`adapter.rowsPath ${jsonV1ResolutionIssue(resolved)}`);
509
- }
372
+ if (!resolved.ok)
373
+ return invalid(`adapter.rowsPath ${resolved.issue}`);
510
374
  if (!Array.isArray(resolved.value)) {
511
375
  return invalid("adapter.rowsPath did not resolve to an array");
512
376
  }
@@ -521,13 +385,14 @@ function parseJsonV1(source, body) {
521
385
  else {
522
386
  return invalid("expected an object or array root");
523
387
  }
524
- if (rows.length < 1 || rows.length > QUOTA_PROVIDER_MAX_REMOTE_ROWS) {
525
- return invalid(`selected rows must contain 1-${QUOTA_PROVIDER_MAX_REMOTE_ROWS} elements`);
388
+ if (rows.length < 1 || rows.length > MAX_REMOTE_ROWS) {
389
+ return invalid(`selected rows must contain 1-${MAX_REMOTE_ROWS} elements`);
526
390
  }
527
- if (rows.length * source.adapter.mappings.length > JSON_V1_MAX_CANDIDATES) {
391
+ const { mappings } = source.adapter;
392
+ if (rows.length * mappings.length > JSON_V1_MAX_CANDIDATES) {
528
393
  return invalid(`candidate count exceeded ${JSON_V1_MAX_CANDIDATES}`);
529
394
  }
530
- const entries = [];
395
+ const mappedRows = [];
531
396
  const rowErrors = [];
532
397
  let errorCount = 0;
533
398
  const recordError = (error) => {
@@ -535,25 +400,24 @@ function parseJsonV1(source, body) {
535
400
  if (rowErrors.length < JSON_V1_MAX_DETAILED_ERRORS)
536
401
  rowErrors.push(error);
537
402
  };
538
- for (let rowIndex = 0; rowIndex < rows.length; rowIndex += 1) {
539
- const row = rows[rowIndex];
540
- for (let mappingIndex = 0; mappingIndex < source.adapter.mappings.length; mappingIndex += 1) {
403
+ for (const [rowIndex, row] of rows.entries()) {
404
+ for (const [mappingIndex, mapping] of mappings.entries()) {
541
405
  if (!isRecord(row)) {
542
406
  recordError(jsonV1CandidateError(mappingIndex, "metric", "requires an object row", rowIndex));
543
407
  continue;
544
408
  }
545
- const mapped = mapJsonV1Candidate(source, row, rowIndex, source.adapter.mappings[mappingIndex], mappingIndex);
409
+ const mapped = mapJsonV1Candidate(row, rowIndex, mapping, mappingIndex);
546
410
  if ("error" in mapped) {
547
411
  recordError(mapped.error);
548
412
  continue;
549
413
  }
550
- entries.push(mapped.entry);
551
- if (entries.length > JSON_V1_MAX_ENTRIES) {
414
+ mappedRows.push(mapped.row);
415
+ if (mappedRows.length > JSON_V1_MAX_ENTRIES) {
552
416
  return invalid(`more than ${JSON_V1_MAX_ENTRIES} entries were produced`);
553
417
  }
554
418
  }
555
419
  }
556
- if (entries.length === 0) {
420
+ if (mappedRows.length === 0) {
557
421
  return invalid(rowErrors[0] ?? "no mappings produced entries");
558
422
  }
559
423
  if (errorCount > rowErrors.length) {
@@ -561,70 +425,71 @@ function parseJsonV1(source, body) {
561
425
  }
562
426
  return {
563
427
  success: true,
564
- entries,
428
+ rows: mappedRows,
565
429
  ...(rowErrors.length > 0 ? { rowErrors } : {}),
566
430
  };
567
431
  }
568
- function parseOpenRouterKeyV1(source, body) {
569
- if (!isRecord(body) || !isRecord(body.data)) {
570
- return { success: false, error: "Invalid openrouter-key-v1 response" };
571
- }
572
- const data = body.data;
573
- const usage = data.usage;
574
- const limit = data.limit;
575
- const remaining = data.limit_remaining;
576
- if (typeof usage !== "number" ||
577
- !Number.isFinite(usage) ||
578
- usage < 0 ||
579
- (limit !== null &&
580
- limit !== undefined &&
581
- (typeof limit !== "number" || !Number.isFinite(limit) || limit < 0)) ||
582
- (remaining === null && limit !== null) ||
583
- (remaining !== null &&
584
- remaining !== undefined &&
585
- (typeof remaining !== "number" || !Number.isFinite(remaining)))) {
586
- return { success: false, error: "Invalid openrouter-key-v1 response" };
587
- }
432
+ /**
433
+ * The key's budget (percent left), or its spend when the key has no limit: this month's
434
+ * (`usage_monthly`, the current UTC month) when the reply has it, else all time.
435
+ */
436
+ function parseOpenRouterKeyV1(body) {
437
+ const invalid = { success: false, error: "Invalid openrouter-key-v1 response" };
438
+ if (!isRecord(body) || !isRecord(body.data))
439
+ return invalid;
440
+ const { usage, usage_monthly: usageMonthly, limit, limit_remaining: remaining } = body.data;
441
+ const isValidUsage = typeof usage === "number" && Number.isFinite(usage) && usage >= 0;
442
+ const isValidLimit = limit === null ||
443
+ limit === undefined ||
444
+ (typeof limit === "number" && Number.isFinite(limit) && limit >= 0);
445
+ // A null remaining is valid only for a key without a limit (free tier).
446
+ const isValidRemaining = remaining === undefined ||
447
+ (remaining === null
448
+ ? limit === null
449
+ : typeof remaining === "number" && Number.isFinite(remaining));
450
+ if (!isValidUsage || !isValidLimit || !isValidRemaining)
451
+ return invalid;
588
452
  if (typeof limit === "number" && limit > 0) {
589
- const remainingValue = typeof remaining === "number" ? remaining : limit - usage;
590
- if (remainingValue > limit) {
591
- return {
592
- success: false,
593
- error: "Invalid openrouter-key-v1 response",
594
- };
595
- }
596
- const percentRemaining = (remainingValue / limit) * 100;
597
- const usedUsd = typeof remaining === "number" ? limit - remainingValue : usage;
453
+ // `limit_remaining` covers the current limit window, while `usage` is the key's lifetime total.
454
+ const remainingUsd = typeof remaining === "number" ? remaining : limit - usage;
455
+ if (remainingUsd > limit)
456
+ return invalid;
457
+ const percentRemaining = (remainingUsd / limit) * 100;
598
458
  return {
599
459
  success: true,
600
- entries: [
601
- {
602
- accounting: accountingMetadata("budget"),
603
- kind: "percent",
604
- name: `${source.label} budget`,
605
- group: source.label,
606
- label: "Budget:",
607
- right: `${formatUsd(usedUsd)}/${formatUsd(limit)}`,
608
- percentRemaining,
609
- },
460
+ rows: [
461
+ customRow({
462
+ key: "budget",
463
+ name: "budget",
464
+ label: "Budget",
465
+ resultType: "budget",
466
+ method: "remote_api",
467
+ value: { percentRemaining },
468
+ }),
610
469
  ],
611
470
  };
612
471
  }
472
+ // A reply without a usable monthly figure (an older or compatible endpoint) keeps the
473
+ // all-time spend.
474
+ const hasMonthly = typeof usageMonthly === "number" && Number.isFinite(usageMonthly) && usageMonthly >= 0;
613
475
  return {
614
476
  success: true,
615
- entries: [
616
- {
617
- accounting: accountingMetadata("spend"),
618
- kind: "value",
619
- name: `${source.label} spend`,
620
- group: source.label,
621
- label: "Spend:",
622
- value: formatUsd(usage),
623
- },
477
+ rows: [
478
+ customRow({
479
+ key: "spend",
480
+ name: "spend",
481
+ label: hasMonthly ? "This month" : "Spend",
482
+ resultType: "spend",
483
+ method: "remote_api",
484
+ value: { text: fmtUsdAmount(hasMonthly ? usageMonthly : usage) },
485
+ }),
624
486
  ],
625
487
  };
626
488
  }
627
489
  export async function fetchRemoteQuotaProvider(source, apiKey, requestTimeoutMs) {
490
+ // A switched-off provider is never sent a request or its key, whoever asks.
491
+ if (source.enabled === false)
492
+ return { success: false, error: "Provider is switched off" };
628
493
  const timeoutMs = requestTimeoutMs ?? REQUEST_TIMEOUT_MS;
629
494
  const controller = new AbortController();
630
495
  const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
@@ -644,14 +509,16 @@ export async function fetchRemoteQuotaProvider(source, apiKey, requestTimeoutMs)
644
509
  if (!response.ok) {
645
510
  return { success: false, error: `HTTP ${response.status}` };
646
511
  }
647
- const body = await readBoundedJson(response);
512
+ const read = await readBoundedJson(response);
513
+ if (!read.ok)
514
+ return { success: false, error: read.error };
648
515
  switch (source.format) {
649
516
  case "quota-v1":
650
- return parseQuotaV1(source, body);
517
+ return parseQuotaV1(read.body);
651
518
  case "openrouter-key-v1":
652
- return parseOpenRouterKeyV1(source, body);
519
+ return parseOpenRouterKeyV1(read.body);
653
520
  case "json-v1":
654
- return parseJsonV1(source, body);
521
+ return parseJsonV1(source, read.body);
655
522
  }
656
523
  }
657
524
  catch (error) {
@@ -661,14 +528,7 @@ export async function fetchRemoteQuotaProvider(source, apiKey, requestTimeoutMs)
661
528
  error: `Request timeout after ${Math.round(timeoutMs / 1000)}s`,
662
529
  };
663
530
  }
664
- if (error instanceof Error &&
665
- [
666
- "Response exceeded 262144 bytes",
667
- "Expected a JSON response",
668
- "Invalid JSON response",
669
- ].includes(error.message)) {
670
- return { success: false, error: error.message };
671
- }
531
+ // Never echo thrown text: it can contain the endpoint or response data.
672
532
  return { success: false, error: "Failed to read accounting data" };
673
533
  }
674
534
  finally {