@percygfx/opencode-antigravity-auth 0.0.0-stage → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (296) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +876 -3
  3. package/dist/index.d.ts +4 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +3 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/rpc.d.ts +176 -0
  8. package/dist/rpc.d.ts.map +1 -0
  9. package/dist/rpc.js +91 -0
  10. package/dist/rpc.js.map +1 -0
  11. package/dist/server.d.ts +3 -0
  12. package/dist/server.d.ts.map +1 -0
  13. package/dist/server.js +5 -0
  14. package/dist/server.js.map +1 -0
  15. package/dist/src/antigravity/oauth.d.ts +31 -0
  16. package/dist/src/antigravity/oauth.d.ts.map +1 -0
  17. package/dist/src/antigravity/oauth.js +171 -0
  18. package/dist/src/antigravity/oauth.js.map +1 -0
  19. package/dist/src/constants.d.ts +148 -0
  20. package/dist/src/constants.d.ts.map +1 -0
  21. package/dist/src/constants.js +233 -0
  22. package/dist/src/constants.js.map +1 -0
  23. package/dist/src/hooks/auto-update-checker/cache.d.ts +3 -0
  24. package/dist/src/hooks/auto-update-checker/cache.d.ts.map +1 -0
  25. package/dist/src/hooks/auto-update-checker/cache.js +71 -0
  26. package/dist/src/hooks/auto-update-checker/cache.js.map +1 -0
  27. package/dist/src/hooks/auto-update-checker/checker.d.ts +16 -0
  28. package/dist/src/hooks/auto-update-checker/checker.d.ts.map +1 -0
  29. package/dist/src/hooks/auto-update-checker/checker.js +234 -0
  30. package/dist/src/hooks/auto-update-checker/checker.js.map +1 -0
  31. package/dist/src/hooks/auto-update-checker/constants.d.ts +11 -0
  32. package/dist/src/hooks/auto-update-checker/constants.d.ts.map +1 -0
  33. package/dist/src/hooks/auto-update-checker/constants.js +26 -0
  34. package/dist/src/hooks/auto-update-checker/constants.js.map +1 -0
  35. package/dist/src/hooks/auto-update-checker/index.d.ts +34 -0
  36. package/dist/src/hooks/auto-update-checker/index.d.ts.map +1 -0
  37. package/dist/src/hooks/auto-update-checker/index.js +122 -0
  38. package/dist/src/hooks/auto-update-checker/index.js.map +1 -0
  39. package/dist/src/hooks/auto-update-checker/logging.d.ts +3 -0
  40. package/dist/src/hooks/auto-update-checker/logging.d.ts.map +1 -0
  41. package/dist/src/hooks/auto-update-checker/logging.js +9 -0
  42. package/dist/src/hooks/auto-update-checker/logging.js.map +1 -0
  43. package/dist/src/hooks/auto-update-checker/types.d.ts +25 -0
  44. package/dist/src/hooks/auto-update-checker/types.d.ts.map +1 -0
  45. package/dist/src/hooks/auto-update-checker/types.js +1 -0
  46. package/dist/src/hooks/auto-update-checker/types.js.map +1 -0
  47. package/dist/src/opencode-v2/accounts.d.ts +24 -0
  48. package/dist/src/opencode-v2/accounts.d.ts.map +1 -0
  49. package/dist/src/opencode-v2/accounts.js +109 -0
  50. package/dist/src/opencode-v2/accounts.js.map +1 -0
  51. package/dist/src/opencode-v2/catalog.d.ts +31 -0
  52. package/dist/src/opencode-v2/catalog.d.ts.map +1 -0
  53. package/dist/src/opencode-v2/catalog.js +68 -0
  54. package/dist/src/opencode-v2/catalog.js.map +1 -0
  55. package/dist/src/opencode-v2/client-shim.d.ts +9 -0
  56. package/dist/src/opencode-v2/client-shim.d.ts.map +1 -0
  57. package/dist/src/opencode-v2/client-shim.js +42 -0
  58. package/dist/src/opencode-v2/client-shim.js.map +1 -0
  59. package/dist/src/opencode-v2/clipboard.d.ts +7 -0
  60. package/dist/src/opencode-v2/clipboard.d.ts.map +1 -0
  61. package/dist/src/opencode-v2/clipboard.js +54 -0
  62. package/dist/src/opencode-v2/clipboard.js.map +1 -0
  63. package/dist/src/opencode-v2/index.d.ts +5 -0
  64. package/dist/src/opencode-v2/index.d.ts.map +1 -0
  65. package/dist/src/opencode-v2/index.js +4 -0
  66. package/dist/src/opencode-v2/index.js.map +1 -0
  67. package/dist/src/opencode-v2/plugin.d.ts +23 -0
  68. package/dist/src/opencode-v2/plugin.d.ts.map +1 -0
  69. package/dist/src/opencode-v2/plugin.js +401 -0
  70. package/dist/src/opencode-v2/plugin.js.map +1 -0
  71. package/dist/src/opencode-v2/proxy.d.ts +23 -0
  72. package/dist/src/opencode-v2/proxy.d.ts.map +1 -0
  73. package/dist/src/opencode-v2/proxy.js +148 -0
  74. package/dist/src/opencode-v2/proxy.js.map +1 -0
  75. package/dist/src/opencode-v2/quota-format.d.ts +19 -0
  76. package/dist/src/opencode-v2/quota-format.d.ts.map +1 -0
  77. package/dist/src/opencode-v2/quota-format.js +71 -0
  78. package/dist/src/opencode-v2/quota-format.js.map +1 -0
  79. package/dist/src/opencode-v2/quota.d.ts +18 -0
  80. package/dist/src/opencode-v2/quota.d.ts.map +1 -0
  81. package/dist/src/opencode-v2/quota.js +118 -0
  82. package/dist/src/opencode-v2/quota.js.map +1 -0
  83. package/dist/src/opencode-v2/sign-in-attempts.d.ts +52 -0
  84. package/dist/src/opencode-v2/sign-in-attempts.d.ts.map +1 -0
  85. package/dist/src/opencode-v2/sign-in-attempts.js +81 -0
  86. package/dist/src/opencode-v2/sign-in-attempts.js.map +1 -0
  87. package/dist/src/plugin/accounts.d.ts +179 -0
  88. package/dist/src/plugin/accounts.d.ts.map +1 -0
  89. package/dist/src/plugin/accounts.js +1004 -0
  90. package/dist/src/plugin/accounts.js.map +1 -0
  91. package/dist/src/plugin/auth.d.ts +21 -0
  92. package/dist/src/plugin/auth.d.ts.map +1 -0
  93. package/dist/src/plugin/auth.js +46 -0
  94. package/dist/src/plugin/auth.js.map +1 -0
  95. package/dist/src/plugin/cache/index.d.ts +5 -0
  96. package/dist/src/plugin/cache/index.d.ts.map +1 -0
  97. package/dist/src/plugin/cache/index.js +5 -0
  98. package/dist/src/plugin/cache/index.js.map +1 -0
  99. package/dist/src/plugin/cache/signature-cache.d.ts +111 -0
  100. package/dist/src/plugin/cache/signature-cache.d.ts.map +1 -0
  101. package/dist/src/plugin/cache/signature-cache.js +375 -0
  102. package/dist/src/plugin/cache/signature-cache.js.map +1 -0
  103. package/dist/src/plugin/cache.d.ts +44 -0
  104. package/dist/src/plugin/cache.d.ts.map +1 -0
  105. package/dist/src/plugin/cache.js +200 -0
  106. package/dist/src/plugin/cache.js.map +1 -0
  107. package/dist/src/plugin/cli.d.ts +26 -0
  108. package/dist/src/plugin/cli.d.ts.map +1 -0
  109. package/dist/src/plugin/cli.js +119 -0
  110. package/dist/src/plugin/cli.js.map +1 -0
  111. package/dist/src/plugin/config/index.d.ts +16 -0
  112. package/dist/src/plugin/config/index.d.ts.map +1 -0
  113. package/dist/src/plugin/config/index.js +16 -0
  114. package/dist/src/plugin/config/index.js.map +1 -0
  115. package/dist/src/plugin/config/loader.d.ts +36 -0
  116. package/dist/src/plugin/config/loader.d.ts.map +1 -0
  117. package/dist/src/plugin/config/loader.js +140 -0
  118. package/dist/src/plugin/config/loader.js.map +1 -0
  119. package/dist/src/plugin/config/models.d.ts +41 -0
  120. package/dist/src/plugin/config/models.d.ts.map +1 -0
  121. package/dist/src/plugin/config/models.js +46 -0
  122. package/dist/src/plugin/config/models.js.map +1 -0
  123. package/dist/src/plugin/config/schema.d.ts +135 -0
  124. package/dist/src/plugin/config/schema.d.ts.map +1 -0
  125. package/dist/src/plugin/config/schema.js +438 -0
  126. package/dist/src/plugin/config/schema.js.map +1 -0
  127. package/dist/src/plugin/config/updater.d.ts +55 -0
  128. package/dist/src/plugin/config/updater.d.ts.map +1 -0
  129. package/dist/src/plugin/config/updater.js +125 -0
  130. package/dist/src/plugin/config/updater.js.map +1 -0
  131. package/dist/src/plugin/core/streaming/index.d.ts +3 -0
  132. package/dist/src/plugin/core/streaming/index.d.ts.map +1 -0
  133. package/dist/src/plugin/core/streaming/index.js +3 -0
  134. package/dist/src/plugin/core/streaming/index.js.map +1 -0
  135. package/dist/src/plugin/core/streaming/transformer.d.ts +10 -0
  136. package/dist/src/plugin/core/streaming/transformer.d.ts.map +1 -0
  137. package/dist/src/plugin/core/streaming/transformer.js +271 -0
  138. package/dist/src/plugin/core/streaming/transformer.js.map +1 -0
  139. package/dist/src/plugin/core/streaming/types.d.ts +27 -0
  140. package/dist/src/plugin/core/streaming/types.d.ts.map +1 -0
  141. package/dist/src/plugin/core/streaming/types.js +1 -0
  142. package/dist/src/plugin/core/streaming/types.js.map +1 -0
  143. package/dist/src/plugin/debug.d.ts +94 -0
  144. package/dist/src/plugin/debug.d.ts.map +1 -0
  145. package/dist/src/plugin/debug.js +382 -0
  146. package/dist/src/plugin/debug.js.map +1 -0
  147. package/dist/src/plugin/errors.d.ts +28 -0
  148. package/dist/src/plugin/errors.d.ts.map +1 -0
  149. package/dist/src/plugin/errors.js +42 -0
  150. package/dist/src/plugin/errors.js.map +1 -0
  151. package/dist/src/plugin/fingerprint.d.ts +70 -0
  152. package/dist/src/plugin/fingerprint.d.ts.map +1 -0
  153. package/dist/src/plugin/fingerprint.js +138 -0
  154. package/dist/src/plugin/fingerprint.js.map +1 -0
  155. package/dist/src/plugin/image-saver.d.ts +25 -0
  156. package/dist/src/plugin/image-saver.d.ts.map +1 -0
  157. package/dist/src/plugin/image-saver.js +86 -0
  158. package/dist/src/plugin/image-saver.js.map +1 -0
  159. package/dist/src/plugin/logger.d.ts +36 -0
  160. package/dist/src/plugin/logger.d.ts.map +1 -0
  161. package/dist/src/plugin/logger.js +71 -0
  162. package/dist/src/plugin/logger.js.map +1 -0
  163. package/dist/src/plugin/logging-utils.d.ts +23 -0
  164. package/dist/src/plugin/logging-utils.d.ts.map +1 -0
  165. package/dist/src/plugin/logging-utils.js +92 -0
  166. package/dist/src/plugin/logging-utils.js.map +1 -0
  167. package/dist/src/plugin/model-discovery.d.ts +16 -0
  168. package/dist/src/plugin/model-discovery.d.ts.map +1 -0
  169. package/dist/src/plugin/model-discovery.js +50 -0
  170. package/dist/src/plugin/model-discovery.js.map +1 -0
  171. package/dist/src/plugin/model-registry.d.ts +92 -0
  172. package/dist/src/plugin/model-registry.d.ts.map +1 -0
  173. package/dist/src/plugin/model-registry.js +248 -0
  174. package/dist/src/plugin/model-registry.js.map +1 -0
  175. package/dist/src/plugin/project.d.ts +33 -0
  176. package/dist/src/plugin/project.d.ts.map +1 -0
  177. package/dist/src/plugin/project.js +234 -0
  178. package/dist/src/plugin/project.js.map +1 -0
  179. package/dist/src/plugin/quota.d.ts +58 -0
  180. package/dist/src/plugin/quota.d.ts.map +1 -0
  181. package/dist/src/plugin/quota.js +296 -0
  182. package/dist/src/plugin/quota.js.map +1 -0
  183. package/dist/src/plugin/recovery/constants.d.ts +22 -0
  184. package/dist/src/plugin/recovery/constants.d.ts.map +1 -0
  185. package/dist/src/plugin/recovery/constants.js +43 -0
  186. package/dist/src/plugin/recovery/constants.js.map +1 -0
  187. package/dist/src/plugin/recovery/index.d.ts +12 -0
  188. package/dist/src/plugin/recovery/index.d.ts.map +1 -0
  189. package/dist/src/plugin/recovery/index.js +12 -0
  190. package/dist/src/plugin/recovery/index.js.map +1 -0
  191. package/dist/src/plugin/recovery/storage.d.ts +24 -0
  192. package/dist/src/plugin/recovery/storage.d.ts.map +1 -0
  193. package/dist/src/plugin/recovery/storage.js +354 -0
  194. package/dist/src/plugin/recovery/storage.js.map +1 -0
  195. package/dist/src/plugin/recovery/types.d.ts +116 -0
  196. package/dist/src/plugin/recovery/types.d.ts.map +1 -0
  197. package/dist/src/plugin/recovery/types.js +6 -0
  198. package/dist/src/plugin/recovery/types.js.map +1 -0
  199. package/dist/src/plugin/recovery.d.ts +61 -0
  200. package/dist/src/plugin/recovery.d.ts.map +1 -0
  201. package/dist/src/plugin/recovery.js +381 -0
  202. package/dist/src/plugin/recovery.js.map +1 -0
  203. package/dist/src/plugin/refresh-queue.d.ts +100 -0
  204. package/dist/src/plugin/refresh-queue.d.ts.map +1 -0
  205. package/dist/src/plugin/refresh-queue.js +247 -0
  206. package/dist/src/plugin/refresh-queue.js.map +1 -0
  207. package/dist/src/plugin/request-helpers.d.ts +282 -0
  208. package/dist/src/plugin/request-helpers.d.ts.map +1 -0
  209. package/dist/src/plugin/request-helpers.js +2343 -0
  210. package/dist/src/plugin/request-helpers.js.map +1 -0
  211. package/dist/src/plugin/request.d.ts +95 -0
  212. package/dist/src/plugin/request.d.ts.map +1 -0
  213. package/dist/src/plugin/request.js +1500 -0
  214. package/dist/src/plugin/request.js.map +1 -0
  215. package/dist/src/plugin/rotation.d.ts +169 -0
  216. package/dist/src/plugin/rotation.d.ts.map +1 -0
  217. package/dist/src/plugin/rotation.js +328 -0
  218. package/dist/src/plugin/rotation.js.map +1 -0
  219. package/dist/src/plugin/search.d.ts +32 -0
  220. package/dist/src/plugin/search.d.ts.map +1 -0
  221. package/dist/src/plugin/search.js +195 -0
  222. package/dist/src/plugin/search.js.map +1 -0
  223. package/dist/src/plugin/server.d.ts +23 -0
  224. package/dist/src/plugin/server.d.ts.map +1 -0
  225. package/dist/src/plugin/server.js +324 -0
  226. package/dist/src/plugin/server.js.map +1 -0
  227. package/dist/src/plugin/storage.d.ts +155 -0
  228. package/dist/src/plugin/storage.d.ts.map +1 -0
  229. package/dist/src/plugin/storage.js +650 -0
  230. package/dist/src/plugin/storage.js.map +1 -0
  231. package/dist/src/plugin/stores/signature-store.d.ts +5 -0
  232. package/dist/src/plugin/stores/signature-store.d.ts.map +1 -0
  233. package/dist/src/plugin/stores/signature-store.js +25 -0
  234. package/dist/src/plugin/stores/signature-store.js.map +1 -0
  235. package/dist/src/plugin/thinking-recovery.d.ts +90 -0
  236. package/dist/src/plugin/thinking-recovery.d.ts.map +1 -0
  237. package/dist/src/plugin/thinking-recovery.js +316 -0
  238. package/dist/src/plugin/thinking-recovery.js.map +1 -0
  239. package/dist/src/plugin/token.d.ts +19 -0
  240. package/dist/src/plugin/token.d.ts.map +1 -0
  241. package/dist/src/plugin/token.js +128 -0
  242. package/dist/src/plugin/token.js.map +1 -0
  243. package/dist/src/plugin/transform/claude.d.ts +80 -0
  244. package/dist/src/plugin/transform/claude.d.ts.map +1 -0
  245. package/dist/src/plugin/transform/claude.js +265 -0
  246. package/dist/src/plugin/transform/claude.js.map +1 -0
  247. package/dist/src/plugin/transform/cross-model-sanitizer.d.ts +35 -0
  248. package/dist/src/plugin/transform/cross-model-sanitizer.d.ts.map +1 -0
  249. package/dist/src/plugin/transform/cross-model-sanitizer.js +225 -0
  250. package/dist/src/plugin/transform/cross-model-sanitizer.js.map +1 -0
  251. package/dist/src/plugin/transform/gemini.d.ts +100 -0
  252. package/dist/src/plugin/transform/gemini.d.ts.map +1 -0
  253. package/dist/src/plugin/transform/gemini.js +446 -0
  254. package/dist/src/plugin/transform/gemini.js.map +1 -0
  255. package/dist/src/plugin/transform/index.d.ts +15 -0
  256. package/dist/src/plugin/transform/index.d.ts.map +1 -0
  257. package/dist/src/plugin/transform/index.js +14 -0
  258. package/dist/src/plugin/transform/index.js.map +1 -0
  259. package/dist/src/plugin/transform/model-resolver.d.ts +99 -0
  260. package/dist/src/plugin/transform/model-resolver.d.ts.map +1 -0
  261. package/dist/src/plugin/transform/model-resolver.js +340 -0
  262. package/dist/src/plugin/transform/model-resolver.js.map +1 -0
  263. package/dist/src/plugin/transform/types.d.ts +111 -0
  264. package/dist/src/plugin/transform/types.d.ts.map +1 -0
  265. package/dist/src/plugin/transform/types.js +1 -0
  266. package/dist/src/plugin/transform/types.js.map +1 -0
  267. package/dist/src/plugin/types.d.ts +97 -0
  268. package/dist/src/plugin/types.d.ts.map +1 -0
  269. package/dist/src/plugin/types.js +1 -0
  270. package/dist/src/plugin/types.js.map +1 -0
  271. package/dist/src/plugin/ui/ansi.d.ts +32 -0
  272. package/dist/src/plugin/ui/ansi.d.ts.map +1 -0
  273. package/dist/src/plugin/ui/ansi.js +52 -0
  274. package/dist/src/plugin/ui/ansi.js.map +1 -0
  275. package/dist/src/plugin/ui/auth-menu.d.ts +33 -0
  276. package/dist/src/plugin/ui/auth-menu.d.ts.map +1 -0
  277. package/dist/src/plugin/ui/auth-menu.js +110 -0
  278. package/dist/src/plugin/ui/auth-menu.js.map +1 -0
  279. package/dist/src/plugin/ui/confirm.d.ts +2 -0
  280. package/dist/src/plugin/ui/confirm.d.ts.map +1 -0
  281. package/dist/src/plugin/ui/confirm.js +15 -0
  282. package/dist/src/plugin/ui/confirm.js.map +1 -0
  283. package/dist/src/plugin/ui/select.d.ts +23 -0
  284. package/dist/src/plugin/ui/select.d.ts.map +1 -0
  285. package/dist/src/plugin/ui/select.js +254 -0
  286. package/dist/src/plugin/ui/select.js.map +1 -0
  287. package/dist/src/plugin/version.d.ts +19 -0
  288. package/dist/src/plugin/version.d.ts.map +1 -0
  289. package/dist/src/plugin/version.js +80 -0
  290. package/dist/src/plugin/version.js.map +1 -0
  291. package/dist/src/plugin.d.ts +45 -0
  292. package/dist/src/plugin.d.ts.map +1 -0
  293. package/dist/src/plugin.js +2817 -0
  294. package/dist/src/plugin.js.map +1 -0
  295. package/dist/tui.js +420 -0
  296. package/package.json +98 -5
@@ -0,0 +1,71 @@
1
+ /** "6d 23h", "4h 48m", "12m", "now"; empty when Antigravity gave no reset time. */
2
+ export function formatReset(resetAt, now) {
3
+ if (resetAt === null)
4
+ return "";
5
+ const minutes = Math.ceil((resetAt - now) / 60_000);
6
+ if (minutes <= 0)
7
+ return "now";
8
+ const days = Math.floor(minutes / 1440);
9
+ const hours = Math.floor((minutes % 1440) / 60);
10
+ const rest = minutes % 60;
11
+ if (days > 0)
12
+ return `${days}d ${String(hours).padStart(2, "0")}h`;
13
+ return hours > 0 ? `${hours}h ${String(rest).padStart(2, "0")}m` : `${rest}m`;
14
+ }
15
+ /** The windows to show for a group: "5h" first, then "wk" (weekly); missing ones are skipped. */
16
+ export function windowsOf(limit) {
17
+ const entries = [];
18
+ if (limit.fiveHour)
19
+ entries.push({ label: "5h", window: limit.fiveHour });
20
+ if (limit.weekly)
21
+ entries.push({ label: "wk", window: limit.weekly });
22
+ return entries;
23
+ }
24
+ export function formatPercent(window) {
25
+ if (window.remainingPercent === null)
26
+ return "?";
27
+ return `${Math.floor(window.remainingPercent)}%`;
28
+ }
29
+ export function windowLevel(window) {
30
+ if (window.remainingPercent === null)
31
+ return "unknown";
32
+ if (window.remainingPercent <= 10)
33
+ return "critical";
34
+ if (window.remainingPercent <= 30)
35
+ return "low";
36
+ return "ok";
37
+ }
38
+ /** The worst level among all of an account's windows, for its status dot. */
39
+ export function accountLevel(account) {
40
+ if (account.error || !account.enabled)
41
+ return "unknown";
42
+ const levels = account.limits
43
+ .flatMap((limit) => [limit.fiveHour, limit.weekly])
44
+ .filter((window) => window !== null)
45
+ .map(windowLevel);
46
+ if (levels.includes("critical"))
47
+ return "critical";
48
+ if (levels.includes("low"))
49
+ return "low";
50
+ if (levels.includes("ok"))
51
+ return "ok";
52
+ return "unknown";
53
+ }
54
+ /**
55
+ * The account serving the selected model's group first, then other accounts in use, then the
56
+ * remaining enabled ones, then disabled ones; stable otherwise.
57
+ */
58
+ export function sortAccounts(accounts, currentGroup) {
59
+ const rank = (account) => {
60
+ if (!account.enabled)
61
+ return 3;
62
+ if (currentGroup !== undefined && account.inUse.includes(currentGroup))
63
+ return 0;
64
+ return account.inUse.length > 0 ? 1 : 2;
65
+ };
66
+ return accounts
67
+ .map((account, index) => ({ account, index }))
68
+ .sort((a, b) => rank(a.account) - rank(b.account) || a.index - b.index)
69
+ .map(({ account }) => account);
70
+ }
71
+ //# sourceMappingURL=quota-format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quota-format.js","sourceRoot":"","sources":["../../../src/opencode-v2/quota-format.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { QuotaAccount, QuotaSnapshot } from "../../rpc";
2
+ import { checkAccountsQuota, type AccountQuotaResult } from "../plugin/quota";
3
+ import type { PluginClient } from "../plugin/types";
4
+ type FetchQuota = typeof checkAccountsQuota;
5
+ /** "Gemini Models" → "Gemini", "Claude and GPT models" → "Claude & GPT". */
6
+ export declare function shortGroupName(displayName: string | undefined): string;
7
+ export declare function toQuotaAccount(result: AccountQuotaResult, inUse: string[]): QuotaAccount;
8
+ /**
9
+ * Builds the per-account quota snapshot the TUI sidebar shows. Results are cached for a minute
10
+ * and concurrent callers share one fetch.
11
+ */
12
+ export declare function createQuotaReporter(client: PluginClient, providerId: string, fetchQuota?: FetchQuota): {
13
+ snapshot(refresh?: boolean): Promise<QuotaSnapshot>;
14
+ /** Drops the cached snapshot after the pool changed, so the next read reflects it. */
15
+ invalidate(): void;
16
+ };
17
+ export {};
18
+ //# sourceMappingURL=quota.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quota.d.ts","sourceRoot":"","sources":["../../../src/opencode-v2/quota.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAc,aAAa,EAAe,MAAM,WAAW,CAAC;AAEtF,OAAO,EACL,kBAAkB,EAClB,KAAK,kBAAkB,EAGxB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAOpD,KAAK,UAAU,GAAG,OAAO,kBAAkB,CAAC;AAW5C,4EAA4E;AAC5E,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAGtE;AAwCD,wBAAgB,cAAc,CAAC,MAAM,EAAE,kBAAkB,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,YAAY,CAkBxF;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,GAAE,UAA+B;iCA2B1F,OAAO,CAAC,aAAa,CAAC;IAcjD,sFAAsF;kBACxE,IAAI;EAIrB"}
@@ -0,0 +1,118 @@
1
+ import { createLogger } from "../plugin/logger";
2
+ import { checkAccountsQuota, } from "../plugin/quota";
3
+ import { loadAccounts } from "../plugin/storage";
4
+ const log = createLogger("opencode-v2.quota");
5
+ /** The shortest quota window is 5 hours; asking more than once a minute adds nothing. */
6
+ const QUOTA_CACHE_MS = 60_000;
7
+ function toPercent(fraction) {
8
+ return typeof fraction === "number" ? Math.round(fraction * 1000) / 10 : null;
9
+ }
10
+ function toTime(resetTime) {
11
+ const value = resetTime ? Date.parse(resetTime) : Number.NaN;
12
+ return Number.isFinite(value) ? value : null;
13
+ }
14
+ /** "Gemini Models" → "Gemini", "Claude and GPT models" → "Claude & GPT". */
15
+ export function shortGroupName(displayName) {
16
+ const name = (displayName ?? "Models").replace(/\s+models$/i, "").replace(/\s+and\s+/i, " & ").trim();
17
+ return name || "Models";
18
+ }
19
+ function summaryWindow(group, window) {
20
+ const bucket = group.buckets?.find((entry) => entry.window === window || entry.bucketId?.endsWith(window === "5h" ? "-5h" : "-weekly"));
21
+ if (!bucket)
22
+ return null;
23
+ return { remainingPercent: toPercent(bucket.remainingFraction), resetAt: toTime(bucket.resetTime) };
24
+ }
25
+ /** Limits from `retrieveUserQuotaSummary`: per model group, the 5-hour and the weekly window. */
26
+ function summaryLimits(groups) {
27
+ return groups.map((group) => ({
28
+ name: shortGroupName(group.displayName),
29
+ fiveHour: summaryWindow(group, "5h"),
30
+ weekly: summaryWindow(group, "weekly"),
31
+ }));
32
+ }
33
+ /**
34
+ * Fallback without the summary: per-model 5-hour quota from `fetchAvailableModels`. Gemini Pro
35
+ * and Flash draw on one bucket, so report the lower remaining and earlier reset.
36
+ */
37
+ function mergeGroups(name, groups) {
38
+ const present = groups.filter((group) => group !== undefined);
39
+ if (present.length === 0)
40
+ return undefined;
41
+ const remaining = present
42
+ .map((group) => group.remainingFraction)
43
+ .filter((value) => typeof value === "number");
44
+ const resets = present.map((group) => toTime(group.resetTime)).filter((value) => value !== null);
45
+ return {
46
+ name,
47
+ fiveHour: {
48
+ remainingPercent: remaining.length > 0 ? toPercent(Math.min(...remaining)) : null,
49
+ resetAt: resets.length > 0 ? Math.min(...resets) : null,
50
+ },
51
+ weekly: null,
52
+ };
53
+ }
54
+ export function toQuotaAccount(result, inUse) {
55
+ const groups = result.quota?.groups ?? {};
56
+ const summaryGroups = result.quotaSummary?.groups ?? [];
57
+ const limits = summaryGroups.length > 0
58
+ ? summaryLimits(summaryGroups)
59
+ : [
60
+ mergeGroups("Gemini", [groups["gemini-pro"], groups["gemini-flash"]]),
61
+ mergeGroups("Claude & GPT", [groups.claude]),
62
+ ].filter((limit) => limit !== undefined);
63
+ return {
64
+ index: result.index,
65
+ email: result.email ?? `Account ${result.index + 1}`,
66
+ enabled: !result.disabled,
67
+ inUse,
68
+ limits,
69
+ ...(result.error || result.quota?.error ? { error: result.error ?? result.quota?.error } : {}),
70
+ };
71
+ }
72
+ /**
73
+ * Builds the per-account quota snapshot the TUI sidebar shows. Results are cached for a minute
74
+ * and concurrent callers share one fetch.
75
+ */
76
+ export function createQuotaReporter(client, providerId, fetchQuota = checkAccountsQuota) {
77
+ let cached;
78
+ let pending;
79
+ const build = async () => {
80
+ const storage = await loadAccounts();
81
+ const accounts = storage?.accounts ?? [];
82
+ const results = await fetchQuota(accounts, client, providerId);
83
+ const activeGemini = storage?.activeIndexByFamily?.gemini ?? storage?.activeIndex ?? 0;
84
+ const activeClaude = storage?.activeIndexByFamily?.claude ?? storage?.activeIndex ?? 0;
85
+ const snapshot = {
86
+ fetchedAt: Date.now(),
87
+ accounts: results.map((result) => {
88
+ const inUse = result.disabled
89
+ ? []
90
+ : [result.index === activeGemini ? "Gemini" : undefined, result.index === activeClaude ? "Claude" : undefined].filter((name) => name !== undefined);
91
+ return toQuotaAccount(result, inUse);
92
+ }),
93
+ };
94
+ cached = snapshot;
95
+ return snapshot;
96
+ };
97
+ return {
98
+ snapshot(refresh = false) {
99
+ if (!refresh && cached && Date.now() - cached.fetchedAt < QUOTA_CACHE_MS) {
100
+ return Promise.resolve(cached);
101
+ }
102
+ pending ??= build()
103
+ .catch((error) => {
104
+ log.warn("quota check failed", { error: String(error) });
105
+ throw error;
106
+ })
107
+ .finally(() => {
108
+ pending = undefined;
109
+ });
110
+ return pending;
111
+ },
112
+ /** Drops the cached snapshot after the pool changed, so the next read reflects it. */
113
+ invalidate() {
114
+ cached = undefined;
115
+ },
116
+ };
117
+ }
118
+ //# sourceMappingURL=quota.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quota.js","sourceRoot":"","sources":["../../../src/opencode-v2/quota.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ /** What the plugin's browser or paste sign-in returns (the shape opencode's OAuth methods use). */
2
+ export type SignInAuthorization<Result> = {
3
+ mode: "auto";
4
+ url: string;
5
+ instructions: string;
6
+ callback: Promise<Result>;
7
+ /** Finishes with a pasted redirect URL when the browser could not reach the callback page. */
8
+ paste?: (code: string) => Promise<Result>;
9
+ } | {
10
+ mode: "code";
11
+ url: string;
12
+ instructions: string;
13
+ callback: (code: string) => Promise<Result>;
14
+ };
15
+ export type SignInStatus = {
16
+ status: "pending";
17
+ } | {
18
+ status: "complete";
19
+ email?: string;
20
+ } | {
21
+ status: "failed";
22
+ message: string;
23
+ } | {
24
+ status: "expired";
25
+ };
26
+ export interface SignInStart {
27
+ attemptID: string;
28
+ mode: "auto" | "code";
29
+ url: string;
30
+ instructions: string;
31
+ }
32
+ /**
33
+ * Sign-ins the plugin runs itself (re-authenticate / add account from the TUI), outside opencode's
34
+ * integration dialog: they update the plugin's account pool without creating another opencode
35
+ * login. The TUI starts an attempt, then polls it (browser) or completes it with a pasted code.
36
+ */
37
+ export declare function createSignInAttempts<Result>(options: {
38
+ start: (loginHint?: string) => Promise<SignInAuthorization<Result>>;
39
+ emailOf: (result: Result) => string | undefined;
40
+ onComplete?: () => void;
41
+ onCancel?: () => void | Promise<void>;
42
+ now?: () => number;
43
+ }): {
44
+ start(loginHint?: string): Promise<SignInStart>;
45
+ status(attemptID: string): SignInStatus;
46
+ /** Finishes a sign-in with the pasted redirect URL or code (paste mode, or browser fallback). */
47
+ complete(attemptID: string, code: string): Promise<{
48
+ email?: string;
49
+ }>;
50
+ cancel(attemptID: string): Promise<void>;
51
+ };
52
+ //# sourceMappingURL=sign-in-attempts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sign-in-attempts.d.ts","sourceRoot":"","sources":["../../../src/opencode-v2/sign-in-attempts.ts"],"names":[],"mappings":"AAEA,mGAAmG;AACnG,MAAM,MAAM,mBAAmB,CAAC,MAAM,IAClC;IACE,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IAC1B,8FAA8F;IAC9F,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CAC3C,GACD;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;CAAE,CAAC;AAErG,MAAM,MAAM,YAAY,GACpB;IAAE,MAAM,EAAE,SAAS,CAAA;CAAE,GACrB;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GACtC;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACrC;IAAE,MAAM,EAAE,SAAS,CAAA;CAAE,CAAC;AAE1B,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;CACtB;AAeD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,OAAO,EAAE;IACpD,KAAK,EAAE,CAAC,SAAS,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,CAAC;IACpE,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IAChD,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;sBAiB2B,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;sBAqBnC,MAAM,GAAG,YAAY;IAOvC,iGAAiG;wBACvE,MAAM,QAAQ,MAAM,GAAG,OAAO,CAAC;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;sBAmBpD,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;EAMjD"}
@@ -0,0 +1,81 @@
1
+ import { randomUUID } from "node:crypto";
2
+ /** Matches opencode's own limit for an unfinished sign-in. */
3
+ const ATTEMPT_TTL_MS = 10 * 60 * 1000;
4
+ function message(error) {
5
+ return error instanceof Error ? error.message : String(error);
6
+ }
7
+ /**
8
+ * Sign-ins the plugin runs itself (re-authenticate / add account from the TUI), outside opencode's
9
+ * integration dialog: they update the plugin's account pool without creating another opencode
10
+ * login. The TUI starts an attempt, then polls it (browser) or completes it with a pasted code.
11
+ */
12
+ export function createSignInAttempts(options) {
13
+ const now = options.now ?? Date.now;
14
+ const attempts = new Map();
15
+ const prune = () => {
16
+ for (const [id, attempt] of attempts) {
17
+ if (now() > attempt.expiresAt + ATTEMPT_TTL_MS)
18
+ attempts.delete(id);
19
+ }
20
+ };
21
+ const settle = (attempt, result) => {
22
+ attempt.status = { status: "complete", email: options.emailOf(result) };
23
+ options.onComplete?.();
24
+ return attempt.status;
25
+ };
26
+ return {
27
+ async start(loginHint) {
28
+ prune();
29
+ const authorization = await options.start(loginHint);
30
+ const attemptID = randomUUID();
31
+ const attempt = { authorization, status: { status: "pending" }, expiresAt: now() + ATTEMPT_TTL_MS };
32
+ attempts.set(attemptID, attempt);
33
+ if (authorization.mode === "auto") {
34
+ // Only a pending attempt changes: a pasted URL may have finished it first.
35
+ const pending = () => attempts.get(attemptID) === attempt && attempt.status.status === "pending";
36
+ authorization.callback.then((result) => {
37
+ if (pending())
38
+ settle(attempt, result);
39
+ }, (error) => {
40
+ if (pending())
41
+ attempt.status = { status: "failed", message: message(error) };
42
+ });
43
+ }
44
+ return { attemptID, mode: authorization.mode, url: authorization.url, instructions: authorization.instructions };
45
+ },
46
+ status(attemptID) {
47
+ const attempt = attempts.get(attemptID);
48
+ if (!attempt)
49
+ return { status: "expired" };
50
+ if (attempt.status.status === "pending" && now() > attempt.expiresAt)
51
+ attempt.status = { status: "expired" };
52
+ return attempt.status;
53
+ },
54
+ /** Finishes a sign-in with the pasted redirect URL or code (paste mode, or browser fallback). */
55
+ async complete(attemptID, code) {
56
+ const attempt = attempts.get(attemptID);
57
+ const finish = attempt?.authorization.mode === "code" ? attempt.authorization.callback : attempt?.authorization.paste;
58
+ if (!attempt || !finish || now() > attempt.expiresAt) {
59
+ throw new Error("This sign-in has expired. Start it again.");
60
+ }
61
+ if (attempt.status.status === "complete") {
62
+ return attempt.status.email ? { email: attempt.status.email } : {};
63
+ }
64
+ try {
65
+ const status = settle(attempt, await finish(code));
66
+ return status.status === "complete" && status.email ? { email: status.email } : {};
67
+ }
68
+ catch (error) {
69
+ attempt.status = { status: "failed", message: message(error) };
70
+ throw error;
71
+ }
72
+ },
73
+ async cancel(attemptID) {
74
+ const attempt = attempts.get(attemptID);
75
+ attempts.delete(attemptID);
76
+ if (attempt?.authorization.mode === "auto" && attempt.status.status === "pending")
77
+ await options.onCancel?.();
78
+ },
79
+ };
80
+ }
81
+ //# sourceMappingURL=sign-in-attempts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sign-in-attempts.js","sourceRoot":"","sources":["../../../src/opencode-v2/sign-in-attempts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,179 @@
1
+ import { type AccountStorageV4, type AccountMetadataV3, type RateLimitStateV3, type ModelFamily, type HeaderStyle, type CooldownReason } from "./storage";
2
+ import type { OAuthAuthDetails, RefreshParts } from "./types";
3
+ import type { AccountSelectionStrategy } from "./config/schema";
4
+ import { type Fingerprint, type FingerprintVersion } from "./fingerprint";
5
+ import type { QuotaGroup, QuotaGroupSummary } from "./quota";
6
+ export type { ModelFamily, HeaderStyle, CooldownReason } from "./storage";
7
+ export type { AccountSelectionStrategy } from "./config/schema";
8
+ export type RateLimitReason = "QUOTA_EXHAUSTED" | "RATE_LIMIT_EXCEEDED" | "MODEL_CAPACITY_EXHAUSTED" | "SERVER_ERROR" | "UNKNOWN";
9
+ export interface RateLimitBackoffResult {
10
+ backoffMs: number;
11
+ reason: RateLimitReason;
12
+ }
13
+ export declare function parseRateLimitReason(reason: string | undefined, message: string | undefined, status?: number): RateLimitReason;
14
+ export declare function calculateBackoffMs(reason: RateLimitReason, consecutiveFailures: number, retryAfterMs?: number | null): number;
15
+ export type BaseQuotaKey = "claude" | "gemini-antigravity" | "gemini-cli";
16
+ export type QuotaKey = BaseQuotaKey | `${BaseQuotaKey}:${string}`;
17
+ export interface ManagedAccount {
18
+ index: number;
19
+ email?: string;
20
+ addedAt: number;
21
+ lastUsed: number;
22
+ parts: RefreshParts;
23
+ access?: string;
24
+ expires?: number;
25
+ enabled: boolean;
26
+ rateLimitResetTimes: RateLimitStateV3;
27
+ lastSwitchReason?: "rate-limit" | "initial" | "rotation";
28
+ coolingDownUntil?: number;
29
+ cooldownReason?: CooldownReason;
30
+ touchedForQuota: Record<string, number>;
31
+ consecutiveFailures?: number;
32
+ /** Timestamp of last failure for TTL-based reset of consecutiveFailures */
33
+ lastFailureTime?: number;
34
+ /** Per-account device fingerprint for rate limit mitigation */
35
+ fingerprint?: import("./fingerprint").Fingerprint;
36
+ /** History of previous fingerprints for this account */
37
+ fingerprintHistory?: FingerprintVersion[];
38
+ /** Cached quota data from last checkAccountsQuota() call */
39
+ cachedQuota?: Partial<Record<QuotaGroup, QuotaGroupSummary>>;
40
+ cachedQuotaUpdatedAt?: number;
41
+ verificationRequired?: boolean;
42
+ verificationRequiredAt?: number;
43
+ verificationRequiredReason?: string;
44
+ verificationUrl?: string;
45
+ }
46
+ /**
47
+ * Resolve the quota group for soft quota checks.
48
+ *
49
+ * When a model string is available, we can precisely determine the quota group.
50
+ * When model is null/undefined, we fall back based on family:
51
+ * - Claude → "claude" quota group
52
+ * - Gemini → "gemini-pro" (conservative fallback; may misclassify flash models)
53
+ *
54
+ * @param family - The model family ("claude" | "gemini")
55
+ * @param model - Optional model string for precise resolution
56
+ * @returns The QuotaGroup to use for soft quota checks
57
+ */
58
+ export declare function resolveQuotaGroup(family: ModelFamily, model?: string | null): QuotaGroup;
59
+ export declare function computeSoftQuotaCacheTtlMs(ttlConfig: "auto" | number, refreshIntervalMinutes: number): number;
60
+ /**
61
+ * In-memory multi-account manager with sticky account selection.
62
+ *
63
+ * Uses the same account until it hits a rate limit (429), then switches.
64
+ * Rate limits are tracked per-model-family (claude/gemini) so an account
65
+ * rate-limited for Claude can still be used for Gemini.
66
+ *
67
+ * Source of truth for the pool is `antigravity-accounts.json`.
68
+ */
69
+ export declare class AccountManager {
70
+ private accounts;
71
+ private cursor;
72
+ private currentAccountIndexByFamily;
73
+ private sessionOffsetApplied;
74
+ private lastToastAccountIndex;
75
+ private lastToastTime;
76
+ private savePending;
77
+ private saveTimeout;
78
+ private savePromiseResolvers;
79
+ static loadFromDisk(authFallback?: OAuthAuthDetails): Promise<AccountManager>;
80
+ constructor(authFallback?: OAuthAuthDetails, stored?: AccountStorageV4 | null);
81
+ getAccountCount(): number;
82
+ getTotalAccountCount(): number;
83
+ getEnabledAccounts(): ManagedAccount[];
84
+ getAccountsSnapshot(): ManagedAccount[];
85
+ getCurrentAccountForFamily(family: ModelFamily): ManagedAccount | null;
86
+ markSwitched(account: ManagedAccount, reason: "rate-limit" | "initial" | "rotation", family: ModelFamily): void;
87
+ /**
88
+ * Check if we should show an account switch toast.
89
+ * Debounces repeated toasts for the same account.
90
+ */
91
+ shouldShowAccountToast(accountIndex: number, debounceMs?: number): boolean;
92
+ markToastShown(accountIndex: number): void;
93
+ getCurrentOrNextForFamily(family: ModelFamily, model?: string | null, strategy?: AccountSelectionStrategy, headerStyle?: HeaderStyle, pidOffsetEnabled?: boolean, softQuotaThresholdPercent?: number, softQuotaCacheTtlMs?: number, allowQuotaFallback?: boolean): ManagedAccount | null;
94
+ getNextForFamily(family: ModelFamily, model?: string | null, headerStyle?: HeaderStyle, softQuotaThresholdPercent?: number, softQuotaCacheTtlMs?: number): ManagedAccount | null;
95
+ markRateLimited(account: ManagedAccount, retryAfterMs: number, family: ModelFamily, headerStyle?: HeaderStyle, model?: string | null): void;
96
+ /**
97
+ * Mark an account as used after a successful API request.
98
+ * This updates the lastUsed timestamp for freshness calculations.
99
+ * Should be called AFTER request completion, not during account selection.
100
+ */
101
+ markAccountUsed(accountIndex: number): void;
102
+ markRateLimitedWithReason(account: ManagedAccount, family: ModelFamily, headerStyle: HeaderStyle, model: string | null | undefined, reason: RateLimitReason, retryAfterMs?: number | null, failureTtlMs?: number): number;
103
+ markRequestSuccess(account: ManagedAccount): void;
104
+ clearAllRateLimitsForFamily(family: ModelFamily, model?: string | null): void;
105
+ shouldTryOptimisticReset(family: ModelFamily, model?: string | null): boolean;
106
+ markAccountCoolingDown(account: ManagedAccount, cooldownMs: number, reason: CooldownReason): void;
107
+ isAccountCoolingDown(account: ManagedAccount): boolean;
108
+ clearAccountCooldown(account: ManagedAccount): void;
109
+ getAccountCooldownReason(account: ManagedAccount): CooldownReason | undefined;
110
+ markTouchedForQuota(account: ManagedAccount, quotaKey: string): void;
111
+ isFreshForQuota(account: ManagedAccount, quotaKey: string): boolean;
112
+ getFreshAccountsForQuota(quotaKey: string, family: ModelFamily, model?: string | null): ManagedAccount[];
113
+ isRateLimitedForHeaderStyle(account: ManagedAccount, family: ModelFamily, headerStyle: HeaderStyle, model?: string | null): boolean;
114
+ getAvailableHeaderStyle(account: ManagedAccount, family: ModelFamily, model?: string | null): HeaderStyle | null;
115
+ /**
116
+ * Check if any OTHER account has antigravity quota available for the given family/model.
117
+ *
118
+ * Used to determine whether to switch accounts vs fall back to gemini-cli:
119
+ * - If true: Switch to another account (preserve antigravity priority)
120
+ * - If false: All accounts exhausted antigravity, safe to fall back to gemini-cli
121
+ *
122
+ * @param currentAccountIndex - Index of the current account (will be excluded from check)
123
+ * @param family - Model family ("gemini" or "claude")
124
+ * @param model - Optional model name for model-specific rate limits
125
+ * @returns true if any other enabled, non-cooling-down account has antigravity available
126
+ */
127
+ hasOtherAccountWithAntigravityAvailable(currentAccountIndex: number, family: ModelFamily, model?: string | null): boolean;
128
+ setAccountEnabled(accountIndex: number, enabled: boolean): boolean;
129
+ markAccountVerificationRequired(accountIndex: number, reason?: string, verifyUrl?: string): boolean;
130
+ clearAccountVerificationRequired(accountIndex: number, enableAccount?: boolean): boolean;
131
+ removeAccountByIndex(accountIndex: number): boolean;
132
+ removeAccount(account: ManagedAccount): boolean;
133
+ updateFromAuth(account: ManagedAccount, auth: OAuthAuthDetails): void;
134
+ toAuthDetails(account: ManagedAccount): OAuthAuthDetails;
135
+ getMinWaitTimeForFamily(family: ModelFamily, model?: string | null, headerStyle?: HeaderStyle, strict?: boolean): number;
136
+ getAccounts(): ManagedAccount[];
137
+ /**
138
+ * Writes the pool to disk. By default the file is merged with what is on disk; pass
139
+ * `replace` after removing accounts, or the merge would bring them back.
140
+ */
141
+ saveToDisk(options?: {
142
+ replace?: boolean;
143
+ }): Promise<void>;
144
+ requestSaveToDisk(): void;
145
+ flushSaveToDisk(): Promise<void>;
146
+ private executeSave;
147
+ /**
148
+ * Regenerate fingerprint for an account, saving the old one to history.
149
+ * @param accountIndex - Index of the account to regenerate fingerprint for
150
+ * @returns The new fingerprint, or null if account not found
151
+ */
152
+ regenerateAccountFingerprint(accountIndex: number): Fingerprint | null;
153
+ /**
154
+ * Restore a fingerprint from history for an account.
155
+ * @param accountIndex - Index of the account
156
+ * @param historyIndex - Index in the fingerprint history to restore from (0 = most recent)
157
+ * @returns The restored fingerprint, or null if account/history not found
158
+ */
159
+ restoreAccountFingerprint(accountIndex: number, historyIndex: number): Fingerprint | null;
160
+ /**
161
+ * Get fingerprint history for an account.
162
+ * @param accountIndex - Index of the account
163
+ * @returns Array of fingerprint versions, or empty array if not found
164
+ */
165
+ getAccountFingerprintHistory(accountIndex: number): FingerprintVersion[];
166
+ updateQuotaCache(accountIndex: number, quotaGroups: Partial<Record<QuotaGroup, QuotaGroupSummary>>): void;
167
+ isAccountOverSoftQuota(account: ManagedAccount, family: ModelFamily, thresholdPercent: number, cacheTtlMs: number, model?: string | null): boolean;
168
+ getAccountsForQuotaCheck(): AccountMetadataV3[];
169
+ getOldestQuotaCacheAge(): number | null;
170
+ areAllAccountsOverSoftQuota(family: ModelFamily, thresholdPercent: number, cacheTtlMs: number, model?: string | null): boolean;
171
+ /**
172
+ * Get minimum wait time until any account's soft quota resets.
173
+ * Returns 0 if any account is available (not over threshold).
174
+ * Returns the minimum resetTime across all over-threshold accounts.
175
+ * Returns null if no resetTime data is available.
176
+ */
177
+ getMinWaitTimeForSoftQuota(family: ModelFamily, thresholdPercent: number, cacheTtlMs: number, model?: string | null): number | null;
178
+ }
179
+ //# sourceMappingURL=accounts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accounts.d.ts","sourceRoot":"","sources":["../../../src/plugin/accounts.ts"],"names":[],"mappings":"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"}