@cortexkit/opencode-antigravity-auth 3.0.5 → 3.0.6

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 (370) hide show
  1. package/README.md +38 -352
  2. package/dist/cli.js +9199 -8799
  3. package/dist/cli.js.map +4 -4
  4. package/dist/cli.meta.json +1286 -1064
  5. package/dist/index.js +13641 -14559
  6. package/dist/index.js.map +4 -4
  7. package/dist/index.meta.json +1333 -1342
  8. package/dist/server.js +10618 -11080
  9. package/dist/server.js.map +4 -4
  10. package/dist/server.meta.json +1 -1
  11. package/dist/src/auth-method-labels.d.ts +3 -0
  12. package/dist/src/auth-method-labels.d.ts.map +1 -0
  13. package/dist/src/auth-method-labels.js +5 -0
  14. package/dist/src/auth-method-labels.js.map +1 -0
  15. package/dist/src/cli.d.ts +3 -1
  16. package/dist/src/cli.d.ts.map +1 -1
  17. package/dist/src/cli.js +98 -12
  18. package/dist/src/cli.js.map +1 -1
  19. package/dist/src/common-auth-embedded/claustrum/consumer.d.ts +33 -3
  20. package/dist/src/common-auth-embedded/claustrum/consumer.js +96 -1
  21. package/dist/src/common-auth-embedded/claustrum/custody.d.ts +4 -1
  22. package/dist/src/common-auth-embedded/claustrum/enrollment.d.ts +6 -1
  23. package/dist/src/common-auth-embedded/claustrum/enrollment.js +6 -1
  24. package/dist/src/common-auth-embedded/claustrum/index.d.ts +2 -1
  25. package/dist/src/common-auth-embedded/claustrum/index.js +5 -3
  26. package/dist/src/common-auth-embedded/claustrum/insula.d.ts +69 -0
  27. package/dist/src/common-auth-embedded/claustrum/insula.js +152 -0
  28. package/dist/src/common-auth-embedded/claustrum/roster.d.ts +13 -0
  29. package/dist/src/common-auth-embedded/claustrum/roster.js +33 -3
  30. package/dist/src/common-auth-embedded/fs/refresh-file-lock.js +20 -11
  31. package/dist/src/common-auth-embedded/quota/codec.d.ts +2 -0
  32. package/dist/src/common-auth-embedded/quota/codec.js +2 -1
  33. package/dist/src/common-auth-embedded/quota/format.d.ts +26 -0
  34. package/dist/src/common-auth-embedded/quota/format.js +78 -42
  35. package/dist/src/common-auth-embedded/quota/index.d.ts +4 -4
  36. package/dist/src/common-auth-embedded/quota/index.js +2 -2
  37. package/dist/src/common-auth-embedded/quota/map.d.ts +11 -0
  38. package/dist/src/common-auth-embedded/quota/map.js +36 -1
  39. package/dist/src/common-auth-embedded/quota/merge.d.ts +3 -1
  40. package/dist/src/common-auth-embedded/quota/merge.js +21 -5
  41. package/dist/src/common-auth-embedded/quota/projection.d.ts +2 -1
  42. package/dist/src/common-auth-embedded/quota/projection.js +3 -1
  43. package/dist/src/common-auth-embedded/setup/command-runner.js +49 -0
  44. package/dist/src/common-auth-embedded/setup/command.d.ts +3 -0
  45. package/dist/src/common-auth-embedded/setup/command.js +215 -0
  46. package/dist/src/common-auth-embedded/setup/config-write.js +60 -0
  47. package/dist/src/common-auth-embedded/setup/detect.d.ts +6 -0
  48. package/dist/src/common-auth-embedded/setup/detect.js +224 -0
  49. package/dist/src/common-auth-embedded/setup/enroll.js +70 -0
  50. package/dist/src/common-auth-embedded/setup/index.d.ts +5 -0
  51. package/dist/src/common-auth-embedded/setup/index.js +4 -0
  52. package/dist/src/common-auth-embedded/setup/paths.js +33 -0
  53. package/dist/src/common-auth-embedded/setup/process-fence.d.ts +43 -0
  54. package/dist/src/common-auth-embedded/setup/process-fence.js +270 -0
  55. package/dist/src/common-auth-embedded/setup/prompts.js +26 -0
  56. package/dist/src/common-auth-embedded/setup/register.d.ts +11 -0
  57. package/dist/src/common-auth-embedded/setup/register.js +130 -0
  58. package/dist/src/common-auth-embedded/setup/types.d.ts +136 -0
  59. package/dist/src/common-auth-embedded/source-output.json +228 -80
  60. package/dist/src/common-auth-embedded/store/schema.d.ts +2 -0
  61. package/dist/src/common-auth-embedded/store/schema.js +3 -2
  62. package/dist/src/ga/rpc/protocol.d.ts +4 -7
  63. package/dist/src/ga/rpc/protocol.d.ts.map +1 -1
  64. package/dist/src/ga/rpc/protocol.js +5 -13
  65. package/dist/src/ga/rpc/protocol.js.map +1 -1
  66. package/dist/src/ga/server/auth.d.ts +8 -3
  67. package/dist/src/ga/server/auth.d.ts.map +1 -1
  68. package/dist/src/ga/server/auth.js +25 -9
  69. package/dist/src/ga/server/auth.js.map +1 -1
  70. package/dist/src/ga/server/index.d.ts +39 -12
  71. package/dist/src/ga/server/index.d.ts.map +1 -1
  72. package/dist/src/ga/server/index.js +214 -53
  73. package/dist/src/ga/server/index.js.map +1 -1
  74. package/dist/src/ga/server/pool-login.d.ts +22 -0
  75. package/dist/src/ga/server/pool-login.d.ts.map +1 -0
  76. package/dist/src/ga/server/pool-login.js +150 -0
  77. package/dist/src/ga/server/pool-login.js.map +1 -0
  78. package/dist/src/ga/tui/host-ga.d.ts +2 -5
  79. package/dist/src/ga/tui/host-ga.d.ts.map +1 -1
  80. package/dist/src/ga/tui/host-ga.js +17 -49
  81. package/dist/src/ga/tui/host-ga.js.map +1 -1
  82. package/dist/src/plugin/accounts.d.ts +1 -1
  83. package/dist/src/plugin/accounts.d.ts.map +1 -1
  84. package/dist/src/plugin/accounts.js +1 -0
  85. package/dist/src/plugin/accounts.js.map +1 -1
  86. package/dist/src/plugin/background-vault-quota-refresh.d.ts +2 -0
  87. package/dist/src/plugin/background-vault-quota-refresh.d.ts.map +1 -1
  88. package/dist/src/plugin/background-vault-quota-refresh.js +125 -10
  89. package/dist/src/plugin/background-vault-quota-refresh.js.map +1 -1
  90. package/dist/src/plugin/command-apply.d.ts +2 -2
  91. package/dist/src/plugin/command-apply.d.ts.map +1 -1
  92. package/dist/src/plugin/command-apply.js +3 -10
  93. package/dist/src/plugin/command-apply.js.map +1 -1
  94. package/dist/src/plugin/commands.d.ts +1 -0
  95. package/dist/src/plugin/commands.d.ts.map +1 -1
  96. package/dist/src/plugin/commands.js +2 -2
  97. package/dist/src/plugin/commands.js.map +1 -1
  98. package/dist/src/plugin/config/operator-settings-schema.d.ts +0 -4
  99. package/dist/src/plugin/config/operator-settings-schema.d.ts.map +1 -1
  100. package/dist/src/plugin/config/operator-settings-schema.js +0 -5
  101. package/dist/src/plugin/config/operator-settings-schema.js.map +1 -1
  102. package/dist/src/plugin/config/schema.d.ts +0 -7
  103. package/dist/src/plugin/config/schema.d.ts.map +1 -1
  104. package/dist/src/plugin/config/schema.js +0 -43
  105. package/dist/src/plugin/config/schema.js.map +1 -1
  106. package/dist/src/plugin/config/writer.d.ts +1 -1
  107. package/dist/src/plugin/config/writer.js +1 -1
  108. package/dist/src/plugin/fetch/retry-state.d.ts +19 -3
  109. package/dist/src/plugin/fetch/retry-state.d.ts.map +1 -1
  110. package/dist/src/plugin/fetch/retry-state.js +0 -6
  111. package/dist/src/plugin/fetch/retry-state.js.map +1 -1
  112. package/dist/src/plugin/fetch-interceptor.d.ts.map +1 -1
  113. package/dist/src/plugin/fetch-interceptor.js +0 -3
  114. package/dist/src/plugin/fetch-interceptor.js.map +1 -1
  115. package/dist/src/plugin/fetch-routing.d.ts +0 -16
  116. package/dist/src/plugin/fetch-routing.d.ts.map +1 -1
  117. package/dist/src/plugin/fetch-routing.js +0 -49
  118. package/dist/src/plugin/fetch-routing.js.map +1 -1
  119. package/dist/src/plugin/ga-location-services.d.ts +14 -9
  120. package/dist/src/plugin/ga-location-services.d.ts.map +1 -1
  121. package/dist/src/plugin/ga-location-services.js +120 -40
  122. package/dist/src/plugin/ga-location-services.js.map +1 -1
  123. package/dist/src/plugin/google-origin.d.ts +7 -0
  124. package/dist/src/plugin/google-origin.d.ts.map +1 -0
  125. package/dist/src/plugin/google-origin.js +14 -0
  126. package/dist/src/plugin/google-origin.js.map +1 -0
  127. package/dist/src/plugin/index.d.ts.map +1 -1
  128. package/dist/src/plugin/index.js +15 -4
  129. package/dist/src/plugin/index.js.map +1 -1
  130. package/dist/src/plugin/oauth-methods.d.ts.map +1 -1
  131. package/dist/src/plugin/oauth-methods.js +0 -33
  132. package/dist/src/plugin/oauth-methods.js.map +1 -1
  133. package/dist/src/plugin/operator-settings.d.ts +1 -1
  134. package/dist/src/plugin/operator-settings.d.ts.map +1 -1
  135. package/dist/src/plugin/operator-settings.js +1 -8
  136. package/dist/src/plugin/operator-settings.js.map +1 -1
  137. package/dist/src/plugin/quota.d.ts +11 -7
  138. package/dist/src/plugin/quota.d.ts.map +1 -1
  139. package/dist/src/plugin/quota.js +128 -102
  140. package/dist/src/plugin/quota.js.map +1 -1
  141. package/dist/src/plugin/request.d.ts +5 -3
  142. package/dist/src/plugin/request.d.ts.map +1 -1
  143. package/dist/src/plugin/request.js +87 -168
  144. package/dist/src/plugin/request.js.map +1 -1
  145. package/dist/src/plugin/server.d.ts.map +1 -1
  146. package/dist/src/plugin/server.js +60 -53
  147. package/dist/src/plugin/server.js.map +1 -1
  148. package/dist/src/plugin/shared/advisory-repository.d.ts +20 -0
  149. package/dist/src/plugin/shared/advisory-repository.d.ts.map +1 -0
  150. package/dist/src/plugin/shared/advisory-repository.js +91 -0
  151. package/dist/src/plugin/shared/advisory-repository.js.map +1 -0
  152. package/dist/src/plugin/shared/request-services.d.ts +19 -25
  153. package/dist/src/plugin/shared/request-services.d.ts.map +1 -1
  154. package/dist/src/plugin/shared/request-services.js +105 -188
  155. package/dist/src/plugin/shared/request-services.js.map +1 -1
  156. package/dist/src/plugin/shared/runtime.js +4 -2
  157. package/dist/src/plugin/shared/runtime.js.map +1 -1
  158. package/dist/src/plugin/shared/vault-request-credentials.d.ts +4 -1
  159. package/dist/src/plugin/shared/vault-request-credentials.d.ts.map +1 -1
  160. package/dist/src/plugin/shared/vault-request-credentials.js +41 -7
  161. package/dist/src/plugin/shared/vault-request-credentials.js.map +1 -1
  162. package/dist/src/plugin/storage.d.ts +2 -2
  163. package/dist/src/plugin/storage.d.ts.map +1 -1
  164. package/dist/src/plugin/storage.js.map +1 -1
  165. package/dist/src/plugin/vault-custody.d.ts.map +1 -1
  166. package/dist/src/plugin/vault-custody.js +147 -35
  167. package/dist/src/plugin/vault-custody.js.map +1 -1
  168. package/dist/src/plugin/vault-quota-outcome.d.ts +19 -0
  169. package/dist/src/plugin/vault-quota-outcome.d.ts.map +1 -0
  170. package/dist/src/plugin/vault-quota-outcome.js +47 -0
  171. package/dist/src/plugin/vault-quota-outcome.js.map +1 -0
  172. package/dist/src/quota-presentation.d.ts +29 -1
  173. package/dist/src/quota-presentation.d.ts.map +1 -1
  174. package/dist/src/quota-presentation.js +52 -17
  175. package/dist/src/quota-presentation.js.map +1 -1
  176. package/dist/src/setup.d.ts +15 -0
  177. package/dist/src/setup.d.ts.map +1 -0
  178. package/dist/src/setup.js +320 -0
  179. package/dist/src/setup.js.map +1 -0
  180. package/dist/src/sidebar-projection.d.ts +1 -1
  181. package/dist/src/sidebar-projection.d.ts.map +1 -1
  182. package/dist/src/sidebar-state.d.ts +1 -1
  183. package/dist/src/sidebar-state.d.ts.map +1 -1
  184. package/dist/src/sidebar-state.js +19 -1
  185. package/dist/src/sidebar-state.js.map +1 -1
  186. package/dist/src/tui.d.ts.map +1 -1
  187. package/dist/src/tui.js +205 -110
  188. package/dist/src/tui.js.map +1 -1
  189. package/dist/tui-build-map.json +37 -37
  190. package/dist/tui-ga-build-map.json +33 -33
  191. package/dist/types/src/auth-method-labels.d.ts +3 -0
  192. package/dist/types/src/auth-method-labels.d.ts.map +1 -0
  193. package/dist/types/src/cli.d.ts +3 -1
  194. package/dist/types/src/cli.d.ts.map +1 -1
  195. package/dist/types/src/common-auth-embedded/auth-menu/terminal.d.ts +43 -0
  196. package/dist/types/src/common-auth-embedded/claustrum/consumer.d.ts +132 -0
  197. package/dist/types/src/common-auth-embedded/claustrum/custody.d.ts +178 -0
  198. package/dist/types/src/common-auth-embedded/claustrum/enrollment.d.ts +164 -0
  199. package/dist/types/src/common-auth-embedded/claustrum/errors.d.ts +16 -0
  200. package/dist/types/src/common-auth-embedded/claustrum/host-slot.d.ts +39 -0
  201. package/dist/types/src/common-auth-embedded/claustrum/index.d.ts +19 -0
  202. package/dist/types/src/common-auth-embedded/claustrum/insula.d.ts +69 -0
  203. package/dist/types/src/common-auth-embedded/claustrum/interlock.d.ts +27 -0
  204. package/dist/types/src/common-auth-embedded/claustrum/roster.d.ts +221 -0
  205. package/dist/types/src/common-auth-embedded/opencode2/errors.d.ts +25 -0
  206. package/dist/types/src/common-auth-embedded/opencode2/index.d.ts +8 -0
  207. package/dist/types/src/common-auth-embedded/opencode2/install.d.ts +55 -0
  208. package/dist/types/src/common-auth-embedded/opencode2/integration.d.ts +112 -0
  209. package/dist/types/src/common-auth-embedded/opencode2/sse.d.ts +12 -0
  210. package/dist/types/src/common-auth-embedded/opencode2/types.d.ts +413 -0
  211. package/dist/types/src/common-auth-embedded/quota/codec.d.ts +2 -0
  212. package/dist/types/src/common-auth-embedded/quota/format.d.ts +26 -0
  213. package/dist/types/src/common-auth-embedded/quota/index.d.ts +4 -4
  214. package/dist/types/src/common-auth-embedded/quota/map.d.ts +11 -0
  215. package/dist/types/src/common-auth-embedded/quota/merge.d.ts +3 -1
  216. package/dist/types/src/common-auth-embedded/quota/projection.d.ts +2 -1
  217. package/dist/types/src/common-auth-embedded/routing/admission.d.ts +93 -0
  218. package/dist/types/src/common-auth-embedded/routing/index.d.ts +8 -0
  219. package/dist/types/src/common-auth-embedded/routing/ordered.d.ts +47 -0
  220. package/dist/types/src/common-auth-embedded/routing/pins.d.ts +22 -0
  221. package/dist/types/src/common-auth-embedded/routing/sticky.d.ts +158 -0
  222. package/dist/types/src/common-auth-embedded/setup/command.d.ts +3 -0
  223. package/dist/types/src/common-auth-embedded/setup/detect.d.ts +6 -0
  224. package/dist/types/src/common-auth-embedded/setup/index.d.ts +5 -0
  225. package/dist/types/src/common-auth-embedded/setup/process-fence.d.ts +43 -0
  226. package/dist/types/src/common-auth-embedded/setup/register.d.ts +11 -0
  227. package/dist/types/src/common-auth-embedded/setup/types.d.ts +136 -0
  228. package/dist/types/src/common-auth-embedded/store/schema.d.ts +2 -0
  229. package/dist/types/src/ga/rpc/protocol.d.ts +4 -7
  230. package/dist/types/src/ga/rpc/protocol.d.ts.map +1 -1
  231. package/dist/types/src/ga/server/auth.d.ts +8 -3
  232. package/dist/types/src/ga/server/auth.d.ts.map +1 -1
  233. package/dist/types/src/ga/server/index.d.ts +39 -12
  234. package/dist/types/src/ga/server/index.d.ts.map +1 -1
  235. package/dist/types/src/ga/server/pool-login.d.ts +22 -0
  236. package/dist/types/src/ga/server/pool-login.d.ts.map +1 -0
  237. package/dist/types/src/plugin/accounts.d.ts +1 -1
  238. package/dist/types/src/plugin/accounts.d.ts.map +1 -1
  239. package/dist/types/src/plugin/background-vault-quota-refresh.d.ts +2 -0
  240. package/dist/types/src/plugin/background-vault-quota-refresh.d.ts.map +1 -1
  241. package/dist/types/src/plugin/command-apply.d.ts +2 -2
  242. package/dist/types/src/plugin/command-apply.d.ts.map +1 -1
  243. package/dist/types/src/plugin/commands.d.ts +1 -0
  244. package/dist/types/src/plugin/commands.d.ts.map +1 -1
  245. package/dist/types/src/plugin/config/operator-settings-schema.d.ts +0 -4
  246. package/dist/types/src/plugin/config/operator-settings-schema.d.ts.map +1 -1
  247. package/dist/types/src/plugin/config/schema.d.ts +0 -7
  248. package/dist/types/src/plugin/config/schema.d.ts.map +1 -1
  249. package/dist/types/src/plugin/config/writer.d.ts +1 -1
  250. package/dist/types/src/plugin/fetch/retry-state.d.ts +19 -3
  251. package/dist/types/src/plugin/fetch/retry-state.d.ts.map +1 -1
  252. package/dist/types/src/plugin/fetch-interceptor.d.ts.map +1 -1
  253. package/dist/types/src/plugin/fetch-routing.d.ts +0 -16
  254. package/dist/types/src/plugin/fetch-routing.d.ts.map +1 -1
  255. package/dist/types/src/plugin/ga-location-services.d.ts +14 -9
  256. package/dist/types/src/plugin/ga-location-services.d.ts.map +1 -1
  257. package/dist/types/src/plugin/google-origin.d.ts +7 -0
  258. package/dist/types/src/plugin/google-origin.d.ts.map +1 -0
  259. package/dist/types/src/plugin/index.d.ts.map +1 -1
  260. package/dist/types/src/plugin/oauth-methods.d.ts.map +1 -1
  261. package/dist/types/src/plugin/operator-settings.d.ts +1 -1
  262. package/dist/types/src/plugin/operator-settings.d.ts.map +1 -1
  263. package/dist/types/src/plugin/quota.d.ts +11 -7
  264. package/dist/types/src/plugin/quota.d.ts.map +1 -1
  265. package/dist/types/src/plugin/request.d.ts +5 -3
  266. package/dist/types/src/plugin/request.d.ts.map +1 -1
  267. package/dist/types/src/plugin/server.d.ts.map +1 -1
  268. package/dist/types/src/plugin/shared/advisory-repository.d.ts +20 -0
  269. package/dist/types/src/plugin/shared/advisory-repository.d.ts.map +1 -0
  270. package/dist/types/src/plugin/shared/request-services.d.ts +19 -25
  271. package/dist/types/src/plugin/shared/request-services.d.ts.map +1 -1
  272. package/dist/types/src/plugin/shared/vault-request-credentials.d.ts +4 -1
  273. package/dist/types/src/plugin/shared/vault-request-credentials.d.ts.map +1 -1
  274. package/dist/types/src/plugin/storage.d.ts +2 -2
  275. package/dist/types/src/plugin/storage.d.ts.map +1 -1
  276. package/dist/types/src/plugin/vault-custody.d.ts.map +1 -1
  277. package/dist/types/src/plugin/vault-quota-outcome.d.ts +19 -0
  278. package/dist/types/src/plugin/vault-quota-outcome.d.ts.map +1 -0
  279. package/dist/types/src/setup.d.ts +15 -0
  280. package/dist/types/src/setup.d.ts.map +1 -0
  281. package/dist/types/src/sidebar-state.d.ts +1 -1
  282. package/dist/types/src/sidebar-state.d.ts.map +1 -1
  283. package/package.json +5 -4
  284. package/src/common-auth-embedded/claustrum/consumer.d.ts +33 -3
  285. package/src/common-auth-embedded/claustrum/consumer.js +96 -1
  286. package/src/common-auth-embedded/claustrum/custody.d.ts +4 -1
  287. package/src/common-auth-embedded/claustrum/enrollment.d.ts +6 -1
  288. package/src/common-auth-embedded/claustrum/enrollment.js +6 -1
  289. package/src/common-auth-embedded/claustrum/index.d.ts +2 -1
  290. package/src/common-auth-embedded/claustrum/index.js +5 -3
  291. package/src/common-auth-embedded/claustrum/insula.d.ts +69 -0
  292. package/src/common-auth-embedded/claustrum/insula.js +152 -0
  293. package/src/common-auth-embedded/claustrum/roster.d.ts +13 -0
  294. package/src/common-auth-embedded/claustrum/roster.js +33 -3
  295. package/src/common-auth-embedded/fs/refresh-file-lock.js +20 -11
  296. package/src/common-auth-embedded/quota/codec.d.ts +2 -0
  297. package/src/common-auth-embedded/quota/codec.js +2 -1
  298. package/src/common-auth-embedded/quota/format.d.ts +26 -0
  299. package/src/common-auth-embedded/quota/format.js +78 -42
  300. package/src/common-auth-embedded/quota/index.d.ts +4 -4
  301. package/src/common-auth-embedded/quota/index.js +2 -2
  302. package/src/common-auth-embedded/quota/map.d.ts +11 -0
  303. package/src/common-auth-embedded/quota/map.js +36 -1
  304. package/src/common-auth-embedded/quota/merge.d.ts +3 -1
  305. package/src/common-auth-embedded/quota/merge.js +21 -5
  306. package/src/common-auth-embedded/quota/projection.d.ts +2 -1
  307. package/src/common-auth-embedded/quota/projection.js +3 -1
  308. package/src/common-auth-embedded/setup/command-runner.js +49 -0
  309. package/src/common-auth-embedded/setup/command.d.ts +3 -0
  310. package/src/common-auth-embedded/setup/command.js +215 -0
  311. package/src/common-auth-embedded/setup/config-write.js +60 -0
  312. package/src/common-auth-embedded/setup/detect.d.ts +6 -0
  313. package/src/common-auth-embedded/setup/detect.js +224 -0
  314. package/src/common-auth-embedded/setup/enroll.js +70 -0
  315. package/src/common-auth-embedded/setup/index.d.ts +5 -0
  316. package/src/common-auth-embedded/setup/index.js +4 -0
  317. package/src/common-auth-embedded/setup/paths.js +33 -0
  318. package/src/common-auth-embedded/setup/process-fence.d.ts +43 -0
  319. package/src/common-auth-embedded/setup/process-fence.js +270 -0
  320. package/src/common-auth-embedded/setup/prompts.js +26 -0
  321. package/src/common-auth-embedded/setup/register.d.ts +11 -0
  322. package/src/common-auth-embedded/setup/register.js +130 -0
  323. package/src/common-auth-embedded/setup/types.d.ts +136 -0
  324. package/src/common-auth-embedded/source-output.json +228 -80
  325. package/src/common-auth-embedded/store/schema.d.ts +2 -0
  326. package/src/common-auth-embedded/store/schema.js +3 -2
  327. package/src/sidebar-state.ts +19 -2
  328. package/src/tui-compiled/common-auth-embedded/quota/codec.js +2 -1
  329. package/src/tui-compiled/common-auth-embedded/quota/format.js +78 -42
  330. package/src/tui-compiled/common-auth-embedded/quota/index.js +2 -2
  331. package/src/tui-compiled/common-auth-embedded/quota/map.js +36 -1
  332. package/src/tui-compiled/common-auth-embedded/quota/merge.js +21 -5
  333. package/src/tui-compiled/common-auth-embedded/quota/projection.js +3 -1
  334. package/src/tui-compiled/quota-presentation.js +42 -9
  335. package/src/tui-compiled/sidebar-state.js +15 -1
  336. package/src/tui-compiled/tui.js +516 -334
  337. package/src/tui-ga-compiled/host-ga.js +11 -38
  338. package/src/tui-ga-compiled/shared/1ff34afa7c42d196-projection.js +3 -1
  339. package/src/tui-ga-compiled/shared/77138df80c7ae006-map.js +36 -1
  340. package/src/tui-ga-compiled/shared/98cc0c186c46c42d-quota-presentation.js +42 -9
  341. package/src/tui-ga-compiled/shared/aef2402f8fc342f0-format.js +78 -42
  342. package/src/tui-ga-compiled/shared/bf17cbee28e58197-index.js +2 -2
  343. package/src/tui-ga-compiled/shared/ca21dc417b36dc5d-codec.js +2 -1
  344. package/src/tui-ga-compiled/shared/ecc214300932dfb6-merge.js +21 -5
  345. package/src/tui-ga-raw/host-ga.tsx +31 -62
  346. package/src/tui-ga-raw/shared/1ff34afa7c42d196-projection.js +3 -1
  347. package/src/tui-ga-raw/shared/77138df80c7ae006-map.js +36 -1
  348. package/src/tui-ga-raw/shared/98cc0c186c46c42d-quota-presentation.js +42 -9
  349. package/src/tui-ga-raw/shared/aef2402f8fc342f0-format.js +78 -42
  350. package/src/tui-ga-raw/shared/bf17cbee28e58197-index.js +2 -2
  351. package/src/tui-ga-raw/shared/ca21dc417b36dc5d-codec.js +2 -1
  352. package/src/tui-ga-raw/shared/ecc214300932dfb6-merge.js +21 -5
  353. package/src/tui-raw/common-auth-embedded/quota/codec.js +2 -1
  354. package/src/tui-raw/common-auth-embedded/quota/format.js +78 -42
  355. package/src/tui-raw/common-auth-embedded/quota/index.js +2 -2
  356. package/src/tui-raw/common-auth-embedded/quota/map.js +36 -1
  357. package/src/tui-raw/common-auth-embedded/quota/merge.js +21 -5
  358. package/src/tui-raw/common-auth-embedded/quota/projection.js +3 -1
  359. package/src/tui-raw/quota-presentation.js +42 -9
  360. package/src/tui-raw/sidebar-state.js +15 -1
  361. package/src/tui-raw/tui.tsx +423 -218
  362. package/src/tui.tsx +423 -218
  363. package/dist/src/tui/vault-setup.d.ts +0 -98
  364. package/dist/src/tui/vault-setup.d.ts.map +0 -1
  365. package/dist/src/tui/vault-setup.js +0 -198
  366. package/dist/src/tui/vault-setup.js.map +0 -1
  367. package/dist/types/src/plugin/transform/model-resolver.d.ts +0 -2
  368. package/dist/types/src/plugin/transform/model-resolver.d.ts.map +0 -1
  369. package/dist/types/src/quota-presentation.d.ts +0 -18
  370. package/dist/types/src/quota-presentation.d.ts.map +0 -1
@@ -0,0 +1,413 @@
1
+ import type { Plugin } from '@opencode/plugin';
2
+ import type { SessionRequestKind, SessionRetryDecision } from '@opencode/plugin/promise/session';
3
+ /** The parts of the OpenCode 2 plugin context the installer uses. */
4
+ export type OpenCode2HookContext = {
5
+ readonly session: Pick<Plugin.Context['session'], 'hook'>;
6
+ /** Used only to forget per-session records when a session is deleted. */
7
+ readonly event?: Pick<Plugin.Context['event'], 'subscribe'>;
8
+ };
9
+ export type RequestKind = SessionRequestKind;
10
+ /** Which request a hook call belongs to, as the host reports it. */
11
+ export interface RequestScope {
12
+ readonly providerID: string;
13
+ readonly modelID: string;
14
+ readonly sessionID: string;
15
+ readonly agent: string;
16
+ readonly kind: RequestKind;
17
+ }
18
+ /** Where a reading or a refusal was seen. */
19
+ export type Transport = 'http' | 'ws';
20
+ /**
21
+ * A provider refusal that should move the request to another account: a rate
22
+ * limit, an exhausted usage window, or anything else the adapter decides is
23
+ * tied to the account rather than to the request.
24
+ */
25
+ export interface LimitSignal {
26
+ /** Short machine-readable reason, such as the provider's error code. */
27
+ readonly reason: string;
28
+ readonly status?: number;
29
+ /** How long the provider asked the account to wait, when it said. */
30
+ readonly retryAfterMs?: number;
31
+ }
32
+ /** What the adapter learned from one streamed event or WebSocket frame. */
33
+ export interface EventVerdict<Q> {
34
+ /** The user has seen output from this response: a retry would repeat it. */
35
+ readonly outputStarted?: boolean;
36
+ readonly quota?: Q;
37
+ readonly limit?: LimitSignal;
38
+ /**
39
+ * This is the last event of the response (completed or failed); the
40
+ * attempt ends here. On WebSocket this is the only way an attempt ends
41
+ * normally, because the socket stays open between responses.
42
+ */
43
+ readonly done?: boolean;
44
+ /**
45
+ * The response failed with this message. Ends the attempt with
46
+ * `error.reason` `failed`; implies `done`.
47
+ */
48
+ readonly error?: string;
49
+ }
50
+ /**
51
+ * Header changes for one account. A string sets the header (replacing every
52
+ * spelling of its name); `null` removes it.
53
+ */
54
+ export type HeaderEdits = Readonly<Record<string, string | null>>;
55
+ export interface ChooseAccountInput extends RequestScope {
56
+ /**
57
+ * The account of the attempt this one retries, when the retry hook just
58
+ * asked the host to retry an attempt of this session and kind; otherwise
59
+ * the account of the newest attempt of this session and kind.
60
+ */
61
+ readonly previousAccountId?: string;
62
+ /**
63
+ * Set when the attempt this one retries was refused for a limit before any
64
+ * output and the retry hook asked the host to try again. The adapter
65
+ * should not pick `accountId` again unless it has nothing else.
66
+ */
67
+ readonly rerouteFrom?: {
68
+ readonly accountId: string;
69
+ readonly limit: LimitSignal;
70
+ };
71
+ }
72
+ export interface AccountRequest extends RequestScope {
73
+ readonly accountId: string;
74
+ }
75
+ /**
76
+ * One physical send: created when an account is chosen for a request, and
77
+ * handed back on every hook call and event that belongs to that send, so a
78
+ * plugin can tie a response, a frame, a limit, a retry decision and the end
79
+ * of the send to the credential it chose for it.
80
+ *
81
+ * `A` is the plugin's own per-attempt value, returned by `accountHeaders`
82
+ * next to the headers (a served credential receipt, say); the installer
83
+ * only carries it.
84
+ */
85
+ export interface Attempt<A = unknown> extends AccountRequest {
86
+ /** Unique within one installation. */
87
+ readonly attemptId: string;
88
+ /**
89
+ * The transport that carried the send. `undefined` until `http.request` or
90
+ * `experimental.ws.handshake` has run for it: an account chosen in
91
+ * `model.request` is chosen before the host has picked the transport.
92
+ */
93
+ readonly transport: Transport | undefined;
94
+ /**
95
+ * What `accountHeaders` returned as `attempt`, if anything, or what
96
+ * `answeredBy` replaced it with.
97
+ */
98
+ readonly data: A | undefined;
99
+ /**
100
+ * Set when `answeredBy` said another account answered this attempt's HTTP
101
+ * response: the account `chooseAccount` picked. `accountId` is then the
102
+ * account that answered, and everything from the response on is attributed
103
+ * to it.
104
+ */
105
+ readonly reboundFrom?: string;
106
+ }
107
+ /**
108
+ * The account that actually answered an HTTP response, as `answeredBy`
109
+ * reports it. `data`, when the key is present, replaces the attempt's `data`
110
+ * (the answering account's own credential receipt, say).
111
+ */
112
+ export interface ResponseAccount<A = unknown> {
113
+ readonly accountId: string;
114
+ readonly data?: A;
115
+ }
116
+ /**
117
+ * Why an attempt ended without completing.
118
+ *
119
+ * - `failed`: the response stream errored, or the adapter's `inspectEvent`
120
+ * reported the response as failed;
121
+ * - `cancelled`: the host cancelled the HTTP response body (the user stopped
122
+ * the turn, say);
123
+ * - `abandoned`: the attempt can no longer be observed: it was on WebSocket
124
+ * (or the retry hook had already judged it) when a newer attempt of the
125
+ * same session and kind began, another attempt of its session and kind
126
+ * went out over WebSocket, its session was forgotten, it was dropped for
127
+ * space, or the installation was disposed. A WebSocket closed or cancelled
128
+ * mid-response ends this way, since the host has no hook for either.
129
+ */
130
+ export type AttemptEndReason = 'failed' | 'cancelled' | 'abandoned';
131
+ /** How an attempt ended, as `onAttemptEnd` reports it. */
132
+ export interface AttemptOutcome {
133
+ /** The HTTP status of the response, when an HTTP response was seen. */
134
+ readonly status?: number;
135
+ /** Output from this attempt had reached the user. */
136
+ readonly outputStarted: boolean;
137
+ /** The account-level refusal recorded for this attempt, if any. */
138
+ readonly limit?: LimitSignal;
139
+ /** Absent when the response completed, whatever its status. */
140
+ readonly error?: {
141
+ readonly reason: AttemptEndReason;
142
+ readonly message?: string;
143
+ };
144
+ }
145
+ /**
146
+ * `accountHeaders` may return the header edits alone, or the edits together
147
+ * with a per-attempt value that the installer hands back in
148
+ * `Attempt.data`.
149
+ */
150
+ export interface AccountHeadersResult<A = unknown> {
151
+ readonly headers: HeaderEdits;
152
+ readonly attempt?: A;
153
+ }
154
+ /** A host-supplied error, as the retry hook reports it. */
155
+ export interface HostError {
156
+ readonly type: string;
157
+ readonly message: string;
158
+ readonly status?: number;
159
+ }
160
+ /**
161
+ * Everything provider-specific the installer needs. `Q` is the plugin's own
162
+ * quota reading type; the installer only carries it to the `quota` event.
163
+ * `A` is the plugin's per-attempt value (see `Attempt`).
164
+ */
165
+ export interface OpenCode2AuthAdapter<Q = unknown, A = unknown> {
166
+ /** Every hook is scoped to this provider; other providers are untouched. */
167
+ readonly providerID: string;
168
+ /**
169
+ * Picks the account for one model request. Called again for every retry,
170
+ * so a refused account can be skipped. Returning `undefined` stops the
171
+ * request with `OpenCode2AuthError` kind `no-account`.
172
+ */
173
+ chooseAccount(input: ChooseAccountInput): Promise<string | undefined> | string | undefined;
174
+ /**
175
+ * The credential and per-account headers for an account, applied in
176
+ * `model.request`, `http.request` and `experimental.ws.handshake`. The last
177
+ * two run after the host has applied its own credential, so these headers
178
+ * win on the wire. With `gateOnPlaceholder`, only the transport hook applies
179
+ * them, and only to owned requests. Put per-account and session headers here
180
+ * rather than in a separate `model.request` hook.
181
+ *
182
+ * Called once per attempt, when the account is chosen. Returning
183
+ * `{headers, attempt}` instead of the bare edits stores `attempt` as the
184
+ * attempt's `data`, handed back on everything that belongs to the attempt.
185
+ */
186
+ accountHeaders(input: AccountRequest): Promise<HeaderEdits | AccountHeadersResult<A>> | HeaderEdits | AccountHeadersResult<A>;
187
+ /**
188
+ * Optional request rewrite (URL, body) before the account headers are
189
+ * applied. Return `undefined` to keep the request. With `gateOnPlaceholder`,
190
+ * runs only for owned requests; move endpoint and body edits here rather
191
+ * than changing `model.request`.
192
+ */
193
+ rewriteRequest?(input: AccountRequest & {
194
+ readonly request: Request;
195
+ readonly attempt: Attempt<A>;
196
+ }): Promise<Request | undefined> | Request | undefined;
197
+ /**
198
+ * Optional response rewrite (body stream, status). It receives the
199
+ * response after quota, limit and output detection have been attached, so
200
+ * detection always sees the provider's own events.
201
+ */
202
+ rewriteResponse?(input: AccountRequest & {
203
+ readonly request: Request;
204
+ readonly response: Response;
205
+ readonly attempt: Attempt<A>;
206
+ }): Promise<Response | undefined> | Response | undefined;
207
+ /**
208
+ * Optional. For an adapter whose own sender can move a request to another
209
+ * account after `rewriteRequest` (a bridge that answers a 401 or 403 by
210
+ * retrying on the next account, say): runs first in `http.response`,
211
+ * before quota, refusal, output or end detection, and returns the account
212
+ * that actually answered, or `undefined` when the attempt's own account
213
+ * did. A different account rebinds the attempt to it (`Attempt.accountId`
214
+ * becomes that account and `reboundFrom` the one chosen), so the response's
215
+ * quota, refusal, stream events, end and any retry reroute are attributed
216
+ * to the answering account, once, and never to the chosen one. What the
217
+ * sender saw from the chosen account before it moved on (the 401 itself)
218
+ * never reaches the installer: the adapter accounts for it itself.
219
+ * Throwing ends the attempt as `failed` and fails the response hook.
220
+ */
221
+ answeredBy?(input: {
222
+ readonly request: Request;
223
+ readonly response: Response;
224
+ readonly attempt: Attempt<A>;
225
+ }): Promise<ResponseAccount<A> | undefined> | ResponseAccount<A> | undefined;
226
+ /**
227
+ * Optional WebSocket URL rewrite. With `gateOnPlaceholder`, runs only for
228
+ * handshakes whose prepared credential belongs to this plugin's login.
229
+ * Return `undefined` to keep the URL.
230
+ */
231
+ rewriteHandshakeURL?(input: AccountRequest & {
232
+ readonly url: string;
233
+ readonly attempt: Attempt<A>;
234
+ }): string | undefined;
235
+ /**
236
+ * Optional rewrite of each outgoing WebSocket frame of this provider,
237
+ * from `experimental.ws.send`. Return the frame to send, or `undefined` to
238
+ * send it unchanged.
239
+ *
240
+ * The rewrite must be a deterministic function of the frame (stable for
241
+ * the session): the host chains turns with `previous_response_id` by
242
+ * diffing its own request as it was before this hook ran, so the server
243
+ * only stays in step when every frame is rewritten the same way. Never
244
+ * alter, drop or reorder the `input` items the host put in the frame, and
245
+ * never touch `previous_response_id`: the host's next frame assumes the
246
+ * server holds exactly what it sent. Adding items to `input`, or adding or
247
+ * changing settings fields, keeps the host's order and continuation when
248
+ * done the same way for every frame: the added items become part of the
249
+ * server's history and the follow-up turn stays incremental.
250
+ *
251
+ * What inserting `input` items into every frame does not keep is the
252
+ * equivalence of the two ways a history reaches the server (settings
253
+ * fields carry no history, so they are not affected). Incrementally, each
254
+ * frame carries only
255
+ * the new items, so an item the rewrite inserts into every frame lands at
256
+ * every network boundary of the accumulated history. After a reconnect the
257
+ * host replays the whole history in one frame, and the same rewrite
258
+ * inserts that item once. The two server-side histories, and their cache
259
+ * prefixes, then differ. A rewrite that only adds or changes settings
260
+ * fields is unaffected. An adapter that inserts `input` items must show,
261
+ * for its own insertion, that the accumulated incremental history equals
262
+ * the rewritten full replay (including across tool loops), or accept the
263
+ * divergence and name what it costs (a cache miss and a different prompt
264
+ * after every reconnect).
265
+ *
266
+ * It runs for every frame, including one no attempt can be tied to
267
+ * (`attempt` is then `undefined`), so the rewrite never depends on
268
+ * attribution. With `gateOnPlaceholder`, it runs only after an owned
269
+ * handshake, including frames after that socket's attempt has ended.
270
+ */
271
+ rewriteWebSocketFrame?(input: RequestScope & {
272
+ readonly attempt: Attempt<A> | undefined;
273
+ readonly frame: string;
274
+ }): Promise<string | undefined> | string | undefined;
275
+ /** Quota carried in HTTP response headers. */
276
+ quotaFromHeaders?(headers: Headers, status: number, attempt: Attempt<A>): Q | undefined;
277
+ /**
278
+ * Recognises an account-level refusal from an HTTP response before its
279
+ * body is streamed. `body()` reads a copy, so the host still gets the body.
280
+ */
281
+ limitFromResponse?(input: {
282
+ readonly status: number;
283
+ readonly headers: Headers;
284
+ readonly body: () => Promise<string>;
285
+ readonly attempt: Attempt<A>;
286
+ }): Promise<LimitSignal | undefined> | LimitSignal | undefined;
287
+ /**
288
+ * Inspects one server-sent event (`data` payload) or one WebSocket frame.
289
+ * Detects output, quota, refusals and the end of the response inside the
290
+ * stream.
291
+ */
292
+ inspectEvent?(input: {
293
+ readonly transport: Transport;
294
+ readonly data: string;
295
+ readonly event?: string;
296
+ readonly attempt: Attempt<A>;
297
+ }): EventVerdict<Q> | undefined;
298
+ /**
299
+ * Recognises an account-level refusal from the error the host hands the
300
+ * retry hook, for refusals no other hook saw. `attempt` is the attempt
301
+ * the retry hook judged.
302
+ */
303
+ limitFromError?(error: HostError, attempt: Attempt<A>): LimitSignal | undefined;
304
+ /**
305
+ * Called once per attempt when it ends: an HTTP response body finished,
306
+ * errored or was cancelled; an HTTP response with an error status or no
307
+ * body arrived; an event's verdict said `done` or `error`; or the attempt
308
+ * was abandoned (see `AttemptEndReason`). Errors are logged and never
309
+ * reach the host. The retry hook waits for this call to settle before it
310
+ * decides, so a plugin that records a refusal here has it in place when
311
+ * `chooseAccount` runs again.
312
+ */
313
+ onAttemptEnd?(attempt: Attempt<A>, outcome: AttemptOutcome): Promise<void> | void;
314
+ }
315
+ export interface OpenCode2AuthLogger {
316
+ warn(message: string, data?: unknown): void;
317
+ }
318
+ export interface InstallOpenCode2AuthOptions {
319
+ /**
320
+ * Opt in to acting only on this plugin's login. Extract the request-bound
321
+ * prepared secret from the host's transport headers (not global connection
322
+ * state). The installer compares it byte for byte with
323
+ * `placeholderSecret(adapter.providerID)`; any other value passes untouched.
324
+ * `model.request` becomes a no-op; selection and rewrites happen at transport.
325
+ */
326
+ readonly gateOnPlaceholder?: {
327
+ readonly credential: (headers: Headers) => string | undefined;
328
+ };
329
+ /**
330
+ * Values that must never reach the wire, normally the placeholder the host
331
+ * holds as its credential. Defaults to the placeholder secret for the
332
+ * adapter's provider. With `gateOnPlaceholder`, that placeholder is always
333
+ * forbidden, even if this list is customized.
334
+ */
335
+ readonly hostCredentials?: readonly string[];
336
+ /** Most attempts kept before the oldest is abandoned and dropped. */
337
+ readonly maxRecords?: number;
338
+ readonly logger?: OpenCode2AuthLogger;
339
+ }
340
+ export type RetryReason = 'reroute' | 'output-started' | 'no-account' | 'host-decides';
341
+ /**
342
+ * The hook that picked an account. Normally `model.request`; a transport hook
343
+ * picks only when the host skipped `model.request` for that request, which a
344
+ * plugin may want to log as a host change.
345
+ */
346
+ export type SelectingHook = 'model.request' | 'http.request' | 'experimental.ws.handshake';
347
+ /**
348
+ * Every event that belongs to one attempt carries it as `handle` (the
349
+ * `retry` event already uses `attempt` for the host's retry count).
350
+ */
351
+ export interface OpenCode2AuthEvents<Q, A = unknown> {
352
+ /** An account was picked for a model request. */
353
+ readonly select: AccountRequest & {
354
+ readonly hook: SelectingHook;
355
+ readonly previousAccountId?: string;
356
+ readonly rerouteFrom?: ChooseAccountInput['rerouteFrom'];
357
+ readonly handle: Attempt<A>;
358
+ };
359
+ /** A quota reading, attributed through this installer's own record. */
360
+ readonly quota: AccountRequest & {
361
+ readonly transport: Transport;
362
+ readonly status?: number;
363
+ readonly quota: Q;
364
+ readonly handle: Attempt<A>;
365
+ };
366
+ /**
367
+ * An account-level refusal. The retry hook waits for every listener of
368
+ * this event before asking the host to retry, so a plugin that marks the
369
+ * account limited here has the mark in place when `chooseAccount` runs.
370
+ */
371
+ readonly limit: AccountRequest & {
372
+ readonly via: Transport | 'error';
373
+ readonly limit: LimitSignal;
374
+ readonly outputStarted: boolean;
375
+ readonly handle: Attempt<A>;
376
+ };
377
+ /** The retry hook ran for this provider. */
378
+ readonly retry: {
379
+ readonly sessionID: string;
380
+ readonly accountId?: string;
381
+ readonly kind?: RequestKind;
382
+ readonly attempt: number;
383
+ readonly reason: RetryReason;
384
+ readonly hostDecision: SessionRetryDecision;
385
+ readonly decision: SessionRetryDecision;
386
+ /** The attempt the decision was about, when it had an account. */
387
+ readonly handle?: Attempt<A>;
388
+ };
389
+ }
390
+ export type OpenCode2AuthEventName = keyof OpenCode2AuthEvents<unknown>;
391
+ export interface OpenCode2AuthInstallation<Q, A = unknown> {
392
+ /**
393
+ * Listens to an event. Listener errors are logged and never reach the
394
+ * host. Returns a function that removes the listener.
395
+ */
396
+ on<E extends OpenCode2AuthEventName>(event: E, listener: (payload: OpenCode2AuthEvents<Q, A>[E]) => void | Promise<void>): () => void;
397
+ /**
398
+ * The account of the newest attempt of a session and request kind (after
399
+ * any `answeredBy` rebind). With several attempts of one session and kind
400
+ * in flight it names only the newest; each attempt's own account is on its
401
+ * handle.
402
+ */
403
+ accountFor(sessionID: string, kind: RequestKind): string | undefined;
404
+ /**
405
+ * Drops every attempt and revokes in-flight auth selections of a session.
406
+ * Session deletion does this itself. Later requests may reuse the session id.
407
+ */
408
+ forgetSession(sessionID: string): void;
409
+ /** Number of attempts held. */
410
+ readonly size: number;
411
+ /** Removes every hook, revokes in-flight auth and stops listening for session deletion. */
412
+ dispose(): Promise<void>;
413
+ }
@@ -1,5 +1,7 @@
1
1
  export interface QuotaCodec {
2
2
  readonly validate: (value: unknown) => boolean;
3
+ /** Normalize persisted data before validation; older codecs may omit this. */
4
+ readonly decode?: (value: unknown) => unknown;
3
5
  readonly merge: (stored: unknown, observation: unknown) => unknown;
4
6
  }
5
7
  /**
@@ -21,6 +21,26 @@ export interface QuotaTextOptions {
21
21
  /** Defaults to `QUOTA_STALE_AFTER_MS`. */
22
22
  staleAfterMs?: number;
23
23
  }
24
+ export interface QuotaWindowPart {
25
+ kind: 'window' | 'budget';
26
+ /** The display name of a quota window, or `credits` for the budget. */
27
+ name: string;
28
+ /** The shared figure wording, including `credits` for budget figures. */
29
+ figure: string;
30
+ /** The unrounded remaining percentage, clamped to 0–100, when known. */
31
+ remainingPercent?: number;
32
+ /** A bare relative reset span such as `4d`, only when the reset is future. */
33
+ resetIn?: string;
34
+ checkedAt: number;
35
+ /** Whether the reset followed this reading and has arrived by `now`. */
36
+ resetSinceReading: boolean;
37
+ }
38
+ export interface QuotaParts {
39
+ /** Reported windows in display order, followed by the budget when present. */
40
+ windows: QuotaWindowPart[];
41
+ /** The shared checked-age wording, present only when the reading is stale. */
42
+ age?: string;
43
+ }
24
44
  /**
25
45
  * The name a window is shown under. A general window (scope `all`) is named
26
46
  * by its stored length; a model-scoped window keeps the label the plugin
@@ -29,6 +49,12 @@ export interface QuotaTextOptions {
29
49
  * were recorded) falls back to its label.
30
50
  */
31
51
  export declare function quotaWindowName(limit: Pick<ProjectedLimit, 'scope' | 'label' | 'windowMinutes'>): string;
52
+ /**
53
+ * Structured quota wording for layouts that need one row per window. The
54
+ * windows use the same filtering and order as `quotaTextParts`; future resets
55
+ * and the optional age keep the shared formatter's wording.
56
+ */
57
+ export declare function quotaWindowParts(quota: ProjectedQuota | undefined, options: QuotaTextOptions): QuotaParts;
32
58
  /**
33
59
  * The pieces of a quota text, in order: one per reported window
34
60
  * (`5h 58% left, resets 2h`), then the credit budget when there is one, then
@@ -1,9 +1,9 @@
1
1
  export type { QuotaCodec } from './codec.js';
2
2
  export { quotaCodec } from './codec.js';
3
- export type { QuotaTextForm, QuotaTextOptions } from './format.js';
4
- export { formatQuota, NO_LIMITS_REPORTED, NO_QUOTA_READING, QUOTA_STALE_AFTER_MS, quotaTextParts, quotaWindowName, } from './format.js';
5
- export type { CreditBudgetCleared, CreditBudgetEntry, CreditBudgetReading, QuotaAbsentEntry, QuotaEntry, QuotaMap, QuotaReadingEntry, QuotaRetiredEntry, } from './map.js';
6
- export { ALL_SCOPE, DEFAULT_REQUIRED_LABELS, emptyQuotaMap, isQuotaMap, } from './map.js';
3
+ export type { QuotaParts, QuotaTextForm, QuotaTextOptions, QuotaWindowPart, } from './format.js';
4
+ export { formatQuota, NO_LIMITS_REPORTED, NO_QUOTA_READING, QUOTA_STALE_AFTER_MS, quotaTextParts, quotaWindowName, quotaWindowParts, } from './format.js';
5
+ export type { CreditBudgetCleared, CreditBudgetEntry, CreditBudgetReading, QuotaAbsentEntry, QuotaCounter, QuotaEntry, QuotaMap, QuotaReadingEntry, QuotaRetiredEntry, } from './map.js';
6
+ export { ALL_SCOPE, DEFAULT_REQUIRED_LABELS, decodeQuotaMap, emptyQuotaMap, isQuotaMap, } from './map.js';
7
7
  export type { ObservedBudget, ObservedPair, ObservedReading, QuotaObservation, } from './merge.js';
8
8
  export { isQuotaObservation, mergeQuotaObservation, QuotaCodecError, } from './merge.js';
9
9
  export type { ExhaustionReset, ProjectedBudget, ProjectedLimit, ProjectedQuota, } from './projection.js';
@@ -44,16 +44,27 @@ export interface CreditBudgetCleared {
44
44
  checkedAt: number;
45
45
  }
46
46
  export type CreditBudgetEntry = CreditBudgetReading | CreditBudgetCleared;
47
+ export interface QuotaCounter {
48
+ value: number;
49
+ checkedAt: number;
50
+ }
47
51
  export interface QuotaMap {
48
52
  limits: QuotaEntry[];
49
53
  /** Absent means no observation has reported on the budget yet. */
50
54
  budget?: CreditBudgetEntry;
55
+ /** Provider-named counts, each with its own observation time. */
56
+ counters?: Record<string, QuotaCounter>;
51
57
  }
52
58
  export declare function emptyQuotaMap(): QuotaMap;
53
59
  /** The time an entry speaks for: its reading, retirement or absence time. */
54
60
  export declare function entryTime(entry: QuotaEntry): number;
55
61
  export declare function limitKey(scope: string, label: string): string;
56
62
  export declare function isCreditBudgetEntry(value: unknown): value is CreditBudgetEntry;
63
+ export declare function isQuotaCounters(value: unknown): value is Record<string, QuotaCounter>;
64
+ /** Keep usable counters without letting one malformed count hide a quota map. */
65
+ export declare function readQuotaCounters(value: unknown): Record<string, QuotaCounter> | undefined;
66
+ /** Decode persisted quota, dropping malformed counters but not limit evidence. */
67
+ export declare function decodeQuotaMap(value: unknown): QuotaMap | undefined;
57
68
  /**
58
69
  * True when `value` is a well-formed quota map. Unrecognised top-level keys
59
70
  * are tolerated (and preserved by merge) so a newer writer's additions
@@ -1,4 +1,4 @@
1
- import { type QuotaMap } from './map.js';
1
+ import { type QuotaCounter, type QuotaMap } from './map.js';
2
2
  export interface ObservedReading {
3
3
  /** Defaults to `all`. */
4
4
  scope?: string;
@@ -32,6 +32,8 @@ export interface QuotaObservation {
32
32
  coverage?: ObservedPair[];
33
33
  /** Absent means the observation says nothing about the budget. */
34
34
  budget?: ObservedBudget;
35
+ /** Each named count uses its own time, independently of limits and budget. */
36
+ counters?: Record<string, QuotaCounter>;
35
37
  }
36
38
  /** Thrown by `mergeQuotaObservation` when either argument is malformed. */
37
39
  export declare class QuotaCodecError extends TypeError {
@@ -1,4 +1,4 @@
1
- import { type QuotaMap } from './map.js';
1
+ import { type QuotaCounter, type QuotaMap } from './map.js';
2
2
  export interface ProjectedLimit {
3
3
  scope: string;
4
4
  label: string;
@@ -30,6 +30,7 @@ export interface ProjectedQuota {
30
30
  checkedAt?: number;
31
31
  /** Present only when the stored budget is a reading, not cleared. */
32
32
  budget?: ProjectedBudget;
33
+ counters?: Record<string, QuotaCounter>;
33
34
  }
34
35
  /**
35
36
  * Resolves `map` for a request in `scope` (`all` or a model family). A family
@@ -0,0 +1,93 @@
1
+ import { type QuotaMap } from '../quota/map.js';
2
+ import { type ProjectedQuota } from '../quota/projection.js';
3
+ export type RowKind = 'oauth' | 'api-key';
4
+ export interface RoutingRow {
5
+ id: string;
6
+ kind: RowKind;
7
+ /** The row's stored quota map; absent is the same as an empty map. */
8
+ quota?: QuotaMap;
9
+ }
10
+ export interface WindowRef {
11
+ scope: string;
12
+ label: string;
13
+ }
14
+ export interface ExclusionInputs {
15
+ /** Row id to the time (ms) a rate-limit mark expires. */
16
+ rateLimitMarks?: ReadonlyMap<string, number>;
17
+ /** Row id to the time (ms) a failed refresh may be retried. */
18
+ refreshBackoff?: ReadonlyMap<string, number>;
19
+ }
20
+ export interface AdmissionInput extends ExclusionInputs {
21
+ rows: readonly RoutingRow[];
22
+ /** `all` (the default) or a model family. */
23
+ scope?: string;
24
+ /** Labels the scope requires an entry for; defaults to `['primary']`. */
25
+ requiredLabels?: readonly string[];
26
+ now: number;
27
+ /**
28
+ * Called synchronously, once per refusal at gates 2 to 4, with the row id.
29
+ * Its return value is ignored and never awaited, so a pull the caller
30
+ * starts from here cannot delay the refusal.
31
+ */
32
+ requestPull?: (rowId: string) => void;
33
+ }
34
+ export type AdmissionRefusal = {
35
+ id: string;
36
+ stage: 1;
37
+ gate: 2;
38
+ reason: 'needs-first-reading';
39
+ pullRequested: true;
40
+ } | {
41
+ id: string;
42
+ stage: 1;
43
+ gate: 3;
44
+ reason: 'unknown-window';
45
+ window: WindowRef;
46
+ pullRequested: true;
47
+ } | {
48
+ id: string;
49
+ stage: 1;
50
+ gate: 4;
51
+ reason: 'unknown-reset';
52
+ window: WindowRef;
53
+ pullRequested: true;
54
+ } | {
55
+ id: string;
56
+ stage: 1;
57
+ gate: 5;
58
+ reason: 'exhausted';
59
+ window: WindowRef;
60
+ resetsAt: string;
61
+ resetAtMs: number;
62
+ } | {
63
+ id: string;
64
+ stage: 2;
65
+ reason: 'budget-spent';
66
+ resetsAt: string;
67
+ resetAtMs: number;
68
+ };
69
+ export interface AdmissionExclusion {
70
+ id: string;
71
+ reason: 'rate-limited' | 'refresh-backoff';
72
+ until: number;
73
+ }
74
+ export interface AdmittedRow {
75
+ id: string;
76
+ kind: RowKind;
77
+ /** The projection admission judged; absent for API-key rows. */
78
+ projection?: ProjectedQuota;
79
+ /** Set when a spent budget was kept because no other path survived. */
80
+ lastPath?: true;
81
+ }
82
+ export interface AdmissionResult {
83
+ /** In input order. */
84
+ admitted: AdmittedRow[];
85
+ refused: AdmissionRefusal[];
86
+ excluded: AdmissionExclusion[];
87
+ /** Ids a pull was requested for, in input order. */
88
+ pulls: string[];
89
+ }
90
+ /** The exclusion that applies to `id` at `now`, if any. */
91
+ export declare function exclusionFor(id: string, inputs: ExclusionInputs, now: number): AdmissionExclusion | undefined;
92
+ /** Runs both admission stages over `input.rows`. */
93
+ export declare function admit(input: AdmissionInput): AdmissionResult;
@@ -0,0 +1,8 @@
1
+ export type { AdmissionExclusion, AdmissionInput, AdmissionRefusal, AdmissionResult, AdmittedRow, ExclusionInputs, RoutingRow, RowKind, WindowRef, } from './admission.js';
2
+ export { admit, exclusionFor } from './admission.js';
3
+ export type { OrderedAttempt, OrderedPlacement, OrderedRoute, OrderedRouteInput, ResolvedRoutingMode, RoutingMode, } from './ordered.js';
4
+ export { DEFAULT_FORMER_MAIN_ID, nextOrderedAttempt, orderForPlacement, resolveRoutingMode, routeOrdered, } from './ordered.js';
5
+ export type { StickyPin } from './pins.js';
6
+ export { isPinValid, pendingBytesForPins } from './pins.js';
7
+ export type { PinAction, StickyBreakDecision, StickyRoute, StickyRouteInput, StickySelection, StickySelectionCandidate, StickySelectionInput, StickyStatusClass, StickyStatusClassifier, } from './sticky.js';
8
+ export { decideStickyBreak, defaultStickyStatusClass, MIN_RESET_HOURS, MIN_WEIGHT, QUOTA_STALENESS_MS, routeSticky, selectStickyCandidate, snapshotCheckedAt, sustainableWindowWeight, } from './sticky.js';