@cortexkit/opencode-antigravity-auth 2.0.0 → 2.1.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 (77) hide show
  1. package/README.md +3 -8
  2. package/dist/cli.js +330 -83
  3. package/dist/cli.js.map +4 -4
  4. package/dist/index.js +17039 -15773
  5. package/dist/index.js.map +4 -4
  6. package/dist/src/plugin/account-command-oauth.d.ts +34 -0
  7. package/dist/src/plugin/account-command-oauth.d.ts.map +1 -0
  8. package/dist/src/plugin/account-command-oauth.js +156 -0
  9. package/dist/src/plugin/account-command-oauth.js.map +1 -0
  10. package/dist/src/plugin/auth-loader.d.ts +16 -1
  11. package/dist/src/plugin/auth-loader.d.ts.map +1 -1
  12. package/dist/src/plugin/auth-loader.js +113 -32
  13. package/dist/src/plugin/auth-loader.js.map +1 -1
  14. package/dist/src/plugin/background-quota-refresh.d.ts +146 -0
  15. package/dist/src/plugin/background-quota-refresh.d.ts.map +1 -0
  16. package/dist/src/plugin/background-quota-refresh.js +347 -0
  17. package/dist/src/plugin/background-quota-refresh.js.map +1 -0
  18. package/dist/src/plugin/command-data.d.ts +61 -8
  19. package/dist/src/plugin/command-data.d.ts.map +1 -1
  20. package/dist/src/plugin/command-data.js +231 -39
  21. package/dist/src/plugin/command-data.js.map +1 -1
  22. package/dist/src/plugin/commands.d.ts +12 -9
  23. package/dist/src/plugin/commands.d.ts.map +1 -1
  24. package/dist/src/plugin/commands.js +140 -33
  25. package/dist/src/plugin/commands.js.map +1 -1
  26. package/dist/src/plugin/config/schema.d.ts +2 -0
  27. package/dist/src/plugin/config/schema.d.ts.map +1 -1
  28. package/dist/src/plugin/config/schema.js +24 -0
  29. package/dist/src/plugin/config/schema.js.map +1 -1
  30. package/dist/src/plugin/debug.d.ts +7 -0
  31. package/dist/src/plugin/debug.d.ts.map +1 -1
  32. package/dist/src/plugin/debug.js +25 -0
  33. package/dist/src/plugin/debug.js.map +1 -1
  34. package/dist/src/plugin/fetch-interceptor.d.ts.map +1 -1
  35. package/dist/src/plugin/fetch-interceptor.js +13 -1
  36. package/dist/src/plugin/fetch-interceptor.js.map +1 -1
  37. package/dist/src/plugin/index.d.ts +7 -0
  38. package/dist/src/plugin/index.d.ts.map +1 -1
  39. package/dist/src/plugin/index.js +127 -24
  40. package/dist/src/plugin/index.js.map +1 -1
  41. package/dist/src/plugin/killswitch.d.ts.map +1 -1
  42. package/dist/src/plugin/killswitch.js +12 -9
  43. package/dist/src/plugin/killswitch.js.map +1 -1
  44. package/dist/src/plugin/oauth-methods.d.ts.map +1 -1
  45. package/dist/src/plugin/oauth-methods.js +2 -10
  46. package/dist/src/plugin/oauth-methods.js.map +1 -1
  47. package/dist/src/plugin/quota.d.ts +42 -1
  48. package/dist/src/plugin/quota.d.ts.map +1 -1
  49. package/dist/src/plugin/quota.js +185 -41
  50. package/dist/src/plugin/quota.js.map +1 -1
  51. package/dist/src/plugin/request.d.ts.map +1 -1
  52. package/dist/src/plugin/request.js +6 -2
  53. package/dist/src/plugin/request.js.map +1 -1
  54. package/dist/src/plugin/ui/auth-menu.d.ts.map +1 -1
  55. package/dist/src/plugin/ui/auth-menu.js +2 -4
  56. package/dist/src/plugin/ui/auth-menu.js.map +1 -1
  57. package/dist/src/plugin/ui/quota-status.d.ts.map +1 -1
  58. package/dist/src/plugin/ui/quota-status.js +3 -5
  59. package/dist/src/plugin/ui/quota-status.js.map +1 -1
  60. package/dist/src/sidebar-state.d.ts +126 -9
  61. package/dist/src/sidebar-state.d.ts.map +1 -1
  62. package/dist/src/sidebar-state.js +185 -25
  63. package/dist/src/sidebar-state.js.map +1 -1
  64. package/dist/src/tui/command-dialogs.js +101 -3
  65. package/dist/src/tui/command-dialogs.js.map +1 -1
  66. package/dist/src/tui.d.ts.map +1 -1
  67. package/dist/src/tui.js +55 -20
  68. package/dist/src/tui.js.map +1 -1
  69. package/package.json +6 -6
  70. package/src/plugin/command-data.ts +331 -51
  71. package/src/sidebar-state.ts +306 -32
  72. package/src/tui/command-dialogs.tsx +136 -3
  73. package/src/tui-compiled/plugin/command-data.ts +331 -51
  74. package/src/tui-compiled/sidebar-state.ts +306 -32
  75. package/src/tui-compiled/tui/command-dialogs.tsx +189 -69
  76. package/src/tui-compiled/tui.tsx +73 -30
  77. package/src/tui.tsx +82 -28
@@ -0,0 +1,34 @@
1
+ import type { AntigravityAuthorization, AntigravityTokenExchangeResult } from '../antigravity/oauth';
2
+ import type { CommandAccountRow } from './command-data';
3
+ type OAuthSuccess = Extract<AntigravityTokenExchangeResult, {
4
+ type: 'success';
5
+ }>;
6
+ export interface AccountCommandOAuthServiceOptions {
7
+ authorize: () => Promise<AntigravityAuthorization>;
8
+ exchange: (code: string, state: string) => Promise<AntigravityTokenExchangeResult>;
9
+ persist: (result: OAuthSuccess) => Promise<void>;
10
+ listAccounts: () => Promise<CommandAccountRow[]>;
11
+ /**
12
+ * Optional hook invoked AFTER persist completes successfully. The plugin
13
+ * uses it to refresh the live AccountManager so the new account is
14
+ * visible to routing immediately, without waiting for an auth reload.
15
+ * Failures are swallowed — the OAuth flow still reports success and the
16
+ * next periodic AccountManager reload picks up the new account.
17
+ */
18
+ onAfterPersist?: (result: OAuthSuccess) => Promise<void> | void;
19
+ now?: () => number;
20
+ }
21
+ export interface AccountCommandOAuthService {
22
+ start(sessionId: string): Promise<{
23
+ url: string;
24
+ accounts: CommandAccountRow[];
25
+ }>;
26
+ finish(sessionId: string, callbackInput: string, label?: string): Promise<{
27
+ text: string;
28
+ accounts: CommandAccountRow[];
29
+ }>;
30
+ dispose(): void;
31
+ }
32
+ export declare function createAccountCommandOAuthService(options: AccountCommandOAuthServiceOptions): AccountCommandOAuthService;
33
+ export {};
34
+ //# sourceMappingURL=account-command-oauth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"account-command-oauth.d.ts","sourceRoot":"","sources":["../../../src/plugin/account-command-oauth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,wBAAwB,EACxB,8BAA8B,EAC/B,MAAM,sBAAsB,CAAA;AAC7B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAGvD,KAAK,YAAY,GAAG,OAAO,CAAC,8BAA8B,EAAE;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC,CAAA;AAShF,MAAM,WAAW,iCAAiC;IAChD,SAAS,EAAE,MAAM,OAAO,CAAC,wBAAwB,CAAC,CAAA;IAClD,QAAQ,EAAE,CACR,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,KACV,OAAO,CAAC,8BAA8B,CAAC,CAAA;IAC5C,OAAO,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAChD,YAAY,EAAE,MAAM,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAA;IAChD;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IAC/D,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,0BAA0B;IACzC,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;QAChC,GAAG,EAAE,MAAM,CAAA;QACX,QAAQ,EAAE,iBAAiB,EAAE,CAAA;KAC9B,CAAC,CAAA;IACF,MAAM,CACJ,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,MAAM,EACrB,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC;QACT,IAAI,EAAE,MAAM,CAAA;QACZ,QAAQ,EAAE,iBAAiB,EAAE,CAAA;KAC9B,CAAC,CAAA;IACF,OAAO,IAAI,IAAI,CAAA;CAChB;AAKD,wBAAgB,gCAAgC,CAC9C,OAAO,EAAE,iCAAiC,GACzC,0BAA0B,CAgK5B"}
@@ -0,0 +1,156 @@
1
+ import { parseOAuthCallbackInput } from './oauth-methods';
2
+ const OAUTH_PENDING_TTL_MS = 10 * 60 * 1_000;
3
+ const OAUTH_PENDING_CAP = 50;
4
+ export function createAccountCommandOAuthService(options) {
5
+ const pendingBySession = new Map();
6
+ const now = options.now ?? (() => Date.now());
7
+ const cleanupExpired = () => {
8
+ const current = now();
9
+ for (const [sessionId, entry] of pendingBySession) {
10
+ if (current - entry.createdAt > OAUTH_PENDING_TTL_MS) {
11
+ pendingBySession.delete(sessionId);
12
+ }
13
+ }
14
+ };
15
+ const takePending = (sessionId) => {
16
+ cleanupExpired();
17
+ const entry = pendingBySession.get(sessionId);
18
+ if (!entry || now() - entry.createdAt > OAUTH_PENDING_TTL_MS) {
19
+ pendingBySession.delete(sessionId);
20
+ return undefined;
21
+ }
22
+ // Consume the entry atomically with the take. A second concurrent
23
+ // `add-oauth-finish` call must observe "no pending entry" even
24
+ // before the first call's exchange completes — the previous
25
+ // peek-then-finally pattern allowed two finish() calls to both
26
+ // exchange and persist the same auth code.
27
+ pendingBySession.delete(sessionId);
28
+ return entry;
29
+ };
30
+ // Wrap listAccounts so a lock-contention or I/O failure in the error
31
+ // branches below does not replace the real OAuth failure text with a
32
+ // generic apply-error message. Mirrors the stage-4 guarded pattern.
33
+ const safeListAccounts = async () => {
34
+ try {
35
+ return await options.listAccounts();
36
+ }
37
+ catch {
38
+ return [];
39
+ }
40
+ };
41
+ return {
42
+ async start(sessionId) {
43
+ const authorization = await options.authorize();
44
+ const url = new URL(authorization.url);
45
+ const state = url.searchParams.get('state');
46
+ const redirectUri = url.searchParams.get('redirect_uri');
47
+ if (!state || !redirectUri) {
48
+ throw new Error('OAuth authorization URL is missing required state');
49
+ }
50
+ cleanupExpired();
51
+ if (pendingBySession.size >= OAUTH_PENDING_CAP) {
52
+ const oldest = [...pendingBySession.entries()].reduce((previous, current) => current[1].createdAt < previous[1].createdAt ? current : previous);
53
+ pendingBySession.delete(oldest[0]);
54
+ }
55
+ pendingBySession.set(sessionId, {
56
+ state,
57
+ verifier: authorization.verifier,
58
+ redirectUri,
59
+ createdAt: now(),
60
+ });
61
+ return { url: authorization.url, accounts: await safeListAccounts() };
62
+ },
63
+ async finish(sessionId, callbackInput, label) {
64
+ const pending = takePending(sessionId);
65
+ if (!pending) {
66
+ return {
67
+ text: 'OAuth session expired. Please start again.',
68
+ accounts: await safeListAccounts(),
69
+ };
70
+ }
71
+ // Stage 1: parse the callback URL/code. Failures here mean the
72
+ // user pasted a malformed callback — exchange has not started.
73
+ let callback;
74
+ try {
75
+ callback = parseOAuthCallbackInput(callbackInput, pending.state);
76
+ }
77
+ catch {
78
+ return {
79
+ text: 'OAuth authentication failed: could not parse the callback. Please start a new OAuth flow.',
80
+ accounts: await safeListAccounts(),
81
+ };
82
+ }
83
+ if ('error' in callback) {
84
+ return {
85
+ text: `OAuth authentication failed: ${callback.error}. Please start a new OAuth flow.`,
86
+ accounts: await safeListAccounts(),
87
+ };
88
+ }
89
+ // Stage 2: exchange the auth code with Google. Failures here mean
90
+ // the network or token endpoint rejected the code — nothing has
91
+ // been persisted yet.
92
+ let result;
93
+ try {
94
+ result = await options.exchange(callback.code, callback.state);
95
+ }
96
+ catch {
97
+ return {
98
+ text: 'OAuth exchange failed due to a network error. Please start a new OAuth flow.',
99
+ accounts: await safeListAccounts(),
100
+ };
101
+ }
102
+ if (result.type === 'failed') {
103
+ return {
104
+ text: 'OAuth authentication failed. Please start a new OAuth flow and try again.',
105
+ accounts: await safeListAccounts(),
106
+ };
107
+ }
108
+ // Stage 3: persist the new account to disk. A failure here means
109
+ // the account is NOT stored — surface the stage so the operator
110
+ // can retry without thinking the previous error already landed it.
111
+ const persisted = {
112
+ ...result,
113
+ label: label || result.label,
114
+ };
115
+ try {
116
+ await options.persist(persisted);
117
+ }
118
+ catch {
119
+ return {
120
+ text: 'OAuth account could not be saved to disk. Please start a new OAuth flow.',
121
+ accounts: await safeListAccounts(),
122
+ };
123
+ }
124
+ // Refresh the live AccountManager so routing sees the new account
125
+ // immediately instead of waiting for the next auth reload. Errors
126
+ // here are non-fatal — the on-disk write already landed.
127
+ try {
128
+ await options.onAfterPersist?.(persisted);
129
+ }
130
+ catch {
131
+ // Best-effort refresh; swallow failures.
132
+ }
133
+ // Stage 4: re-list the account pool. If the post-persist read
134
+ // fails for any reason (lock contention, I/O) we still report the
135
+ // successful add — the dialog will refresh on its next open.
136
+ let accounts;
137
+ try {
138
+ accounts = await options.listAccounts();
139
+ }
140
+ catch {
141
+ return {
142
+ text: 'OAuth account added.',
143
+ accounts: [],
144
+ };
145
+ }
146
+ return {
147
+ text: 'OAuth account added.',
148
+ accounts,
149
+ };
150
+ },
151
+ dispose() {
152
+ pendingBySession.clear();
153
+ },
154
+ };
155
+ }
156
+ //# sourceMappingURL=account-command-oauth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"account-command-oauth.js","sourceRoot":"","sources":["../../../src/plugin/account-command-oauth.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAA;AA8CzD,MAAM,oBAAoB,GAAG,EAAE,GAAG,EAAE,GAAG,KAAK,CAAA;AAC5C,MAAM,iBAAiB,GAAG,EAAE,CAAA;AAE5B,MAAM,UAAU,gCAAgC,CAC9C,OAA0C;IAE1C,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAA6B,CAAA;IAC7D,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAA;IAE7C,MAAM,cAAc,GAAG,GAAS,EAAE;QAChC,MAAM,OAAO,GAAG,GAAG,EAAE,CAAA;QACrB,KAAK,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,IAAI,gBAAgB,EAAE,CAAC;YAClD,IAAI,OAAO,GAAG,KAAK,CAAC,SAAS,GAAG,oBAAoB,EAAE,CAAC;gBACrD,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;YACpC,CAAC;QACH,CAAC;IACH,CAAC,CAAA;IAED,MAAM,WAAW,GAAG,CAAC,SAAiB,EAAiC,EAAE;QACvE,cAAc,EAAE,CAAA;QAChB,MAAM,KAAK,GAAG,gBAAgB,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;QAC7C,IAAI,CAAC,KAAK,IAAI,GAAG,EAAE,GAAG,KAAK,CAAC,SAAS,GAAG,oBAAoB,EAAE,CAAC;YAC7D,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;YAClC,OAAO,SAAS,CAAA;QAClB,CAAC;QACD,kEAAkE;QAClE,+DAA+D;QAC/D,4DAA4D;QAC5D,+DAA+D;QAC/D,2CAA2C;QAC3C,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;QAClC,OAAO,KAAK,CAAA;IACd,CAAC,CAAA;IAED,qEAAqE;IACrE,qEAAqE;IACrE,oEAAoE;IACpE,MAAM,gBAAgB,GAAG,KAAK,IAAkC,EAAE;QAChE,IAAI,CAAC;YACH,OAAO,MAAM,OAAO,CAAC,YAAY,EAAE,CAAA;QACrC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,CAAA;QACX,CAAC;IACH,CAAC,CAAA;IAED,OAAO;QACL,KAAK,CAAC,KAAK,CAAC,SAAS;YACnB,MAAM,aAAa,GAAG,MAAM,OAAO,CAAC,SAAS,EAAE,CAAA;YAC/C,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,CAAA;YACtC,MAAM,KAAK,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;YAC3C,MAAM,WAAW,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;YACxD,IAAI,CAAC,KAAK,IAAI,CAAC,WAAW,EAAE,CAAC;gBAC3B,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAA;YACtE,CAAC;YAED,cAAc,EAAE,CAAA;YAChB,IAAI,gBAAgB,CAAC,IAAI,IAAI,iBAAiB,EAAE,CAAC;gBAC/C,MAAM,MAAM,GAAG,CAAC,GAAG,gBAAgB,CAAC,OAAO,EAAE,CAAC,CAAC,MAAM,CACnD,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,CACpB,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CACpE,CAAA;gBACD,gBAAgB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;YACpC,CAAC;YACD,gBAAgB,CAAC,GAAG,CAAC,SAAS,EAAE;gBAC9B,KAAK;gBACL,QAAQ,EAAE,aAAa,CAAC,QAAQ;gBAChC,WAAW;gBACX,SAAS,EAAE,GAAG,EAAE;aACjB,CAAC,CAAA;YACF,OAAO,EAAE,GAAG,EAAE,aAAa,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,gBAAgB,EAAE,EAAE,CAAA;QACvE,CAAC;QAED,KAAK,CAAC,MAAM,CAAC,SAAS,EAAE,aAAa,EAAE,KAAK;YAC1C,MAAM,OAAO,GAAG,WAAW,CAAC,SAAS,CAAC,CAAA;YACtC,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,OAAO;oBACL,IAAI,EAAE,4CAA4C;oBAClD,QAAQ,EAAE,MAAM,gBAAgB,EAAE;iBACnC,CAAA;YACH,CAAC;YAED,+DAA+D;YAC/D,+DAA+D;YAC/D,IAAI,QAAoD,CAAA;YACxD,IAAI,CAAC;gBACH,QAAQ,GAAG,uBAAuB,CAAC,aAAa,EAAE,OAAO,CAAC,KAAK,CAAC,CAAA;YAClE,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO;oBACL,IAAI,EAAE,2FAA2F;oBACjG,QAAQ,EAAE,MAAM,gBAAgB,EAAE;iBACnC,CAAA;YACH,CAAC;YACD,IAAI,OAAO,IAAI,QAAQ,EAAE,CAAC;gBACxB,OAAO;oBACL,IAAI,EAAE,gCAAgC,QAAQ,CAAC,KAAK,kCAAkC;oBACtF,QAAQ,EAAE,MAAM,gBAAgB,EAAE;iBACnC,CAAA;YACH,CAAC;YAED,kEAAkE;YAClE,gEAAgE;YAChE,sBAAsB;YACtB,IAAI,MAAoD,CAAA;YACxD,IAAI,CAAC;gBACH,MAAM,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAA;YAChE,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO;oBACL,IAAI,EAAE,8EAA8E;oBACpF,QAAQ,EAAE,MAAM,gBAAgB,EAAE;iBACnC,CAAA;YACH,CAAC;YACD,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC7B,OAAO;oBACL,IAAI,EAAE,2EAA2E;oBACjF,QAAQ,EAAE,MAAM,gBAAgB,EAAE;iBACnC,CAAA;YACH,CAAC;YAED,iEAAiE;YACjE,gEAAgE;YAChE,mEAAmE;YACnE,MAAM,SAAS,GAAiB;gBAC9B,GAAG,MAAM;gBACT,KAAK,EAAE,KAAK,IAAI,MAAM,CAAC,KAAK;aAC7B,CAAA;YACD,IAAI,CAAC;gBACH,MAAM,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;YAClC,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO;oBACL,IAAI,EAAE,0EAA0E;oBAChF,QAAQ,EAAE,MAAM,gBAAgB,EAAE;iBACnC,CAAA;YACH,CAAC;YAED,kEAAkE;YAClE,kEAAkE;YAClE,yDAAyD;YACzD,IAAI,CAAC;gBACH,MAAM,OAAO,CAAC,cAAc,EAAE,CAAC,SAAS,CAAC,CAAA;YAC3C,CAAC;YAAC,MAAM,CAAC;gBACP,yCAAyC;YAC3C,CAAC;YAED,8DAA8D;YAC9D,kEAAkE;YAClE,6DAA6D;YAC7D,IAAI,QAA6B,CAAA;YACjC,IAAI,CAAC;gBACH,QAAQ,GAAG,MAAM,OAAO,CAAC,YAAY,EAAE,CAAA;YACzC,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO;oBACL,IAAI,EAAE,sBAAsB;oBAC5B,QAAQ,EAAE,EAAE;iBACb,CAAA;YACH,CAAC;YACD,OAAO;gBACL,IAAI,EAAE,sBAAsB;gBAC5B,QAAQ;aACT,CAAA;QACH,CAAC;QAED,OAAO;YACL,gBAAgB,CAAC,KAAK,EAAE,CAAA;QAC1B,CAAC;KACF,CAAA;AACH,CAAC"}
@@ -13,6 +13,21 @@ export type CreateAuthFetch = (input: {
13
13
  accountManager: AccountManager;
14
14
  getAuth: GetAuth;
15
15
  }) => AuthFetchRuntime;
16
+ /**
17
+ * Loader returned by `createAuthLoader`. The function loads the
18
+ * account pool from disk and installs the runtime.
19
+ */
20
+ export type LoadAndInstallRuntime = (getAuth: GetAuth, provider: Provider) => Promise<LoaderResult | Record<string, unknown>>;
21
+ /**
22
+ * Reload the live AccountManager + fetch runtime without going through
23
+ * the full startup loader. Used by the OAuth add flow so the new account
24
+ * is visible to routing immediately after `persistAccountPool`.
25
+ */
26
+ export type ReloadAccountRuntime = (getAuth: GetAuth) => Promise<void>;
27
+ export interface AuthLoaderHandle {
28
+ load: LoadAndInstallRuntime;
29
+ reload: ReloadAccountRuntime;
30
+ }
16
31
  interface AuthLoaderDependencies {
17
32
  loadAccounts: typeof loadAccounts;
18
33
  clearAccounts: typeof clearAccounts;
@@ -30,6 +45,6 @@ interface CreateAuthLoaderOptions {
30
45
  onGetAuth?(getAuth: GetAuth): void;
31
46
  dependencies?: Partial<AuthLoaderDependencies>;
32
47
  }
33
- export declare function createAuthLoader({ client, providerId, config, lifecycle, createFetch, onGetAuth, dependencies, }: CreateAuthLoaderOptions): (getAuth: GetAuth, provider: Provider) => Promise<LoaderResult | Record<string, unknown>>;
48
+ export declare function createAuthLoader({ client, providerId, config, lifecycle, createFetch, onGetAuth, dependencies, }: CreateAuthLoaderOptions): LoadAndInstallRuntime & AuthLoaderHandle;
34
49
  export {};
35
50
  //# sourceMappingURL=auth-loader.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth-loader.d.ts","sourceRoot":"","sources":["../../../src/plugin/auth-loader.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAM3C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAA;AACjD,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AACxD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAElD,OAAO,EACL,2BAA2B,EAE5B,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAEL,aAAa,EACb,YAAY,EACb,MAAM,WAAW,CAAA;AAClB,OAAO,KAAK,EACV,OAAO,EACP,YAAY,EACZ,YAAY,EACZ,QAAQ,EAET,MAAM,SAAS,CAAA;AAIhB,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,YAAY,CAAC,OAAO,CAAC,CAAA;IAC5B,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;CAChC;AAED,MAAM,MAAM,eAAe,GAAG,CAAC,KAAK,EAAE;IACpC,cAAc,EAAE,cAAc,CAAA;IAC9B,OAAO,EAAE,OAAO,CAAA;CACjB,KAAK,gBAAgB,CAAA;AAEtB,UAAU,sBAAsB;IAC9B,YAAY,EAAE,OAAO,YAAY,CAAA;IACjC,aAAa,EAAE,OAAO,aAAa,CAAA;IACnC,kBAAkB,CAChB,IAAI,EAAE,UAAU,CAAC,OAAO,cAAc,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,GACtD,OAAO,CAAC,cAAc,CAAC,CAAA;IAC1B,kBAAkB,EAAE,OAAO,2BAA2B,CAAA;IACtD,cAAc,EAAE,OAAO,cAAc,CAAA;IACrC,cAAc,EAAE,OAAO,cAAc,CAAA;CACtC;AAED,UAAU,uBAAuB;IAC/B,MAAM,EAAE,YAAY,CAAA;IACpB,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,iBAAiB,CAAA;IACzB,SAAS,EAAE,eAAe,CAAA;IAC1B,WAAW,EAAE,eAAe,CAAA;IAC5B,SAAS,CAAC,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAA;IAClC,YAAY,CAAC,EAAE,OAAO,CAAC,sBAAsB,CAAC,CAAA;CAC/C;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,MAAM,EACN,UAAU,EACV,MAAM,EACN,SAAS,EACT,WAAW,EACX,SAAS,EACT,YAAY,GACb,EAAE,uBAAuB,IA0BtB,SAAS,OAAO,EAChB,UAAU,QAAQ,KACjB,OAAO,CAAC,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAgInD"}
1
+ {"version":3,"file":"auth-loader.d.ts","sourceRoot":"","sources":["../../../src/plugin/auth-loader.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAM3C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAA;AACjD,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AACxD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAElD,OAAO,EACL,2BAA2B,EAE5B,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAEL,aAAa,EACb,YAAY,EACb,MAAM,WAAW,CAAA;AAClB,OAAO,KAAK,EACV,OAAO,EACP,YAAY,EACZ,YAAY,EACZ,QAAQ,EAET,MAAM,SAAS,CAAA;AAgBhB,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,YAAY,CAAC,OAAO,CAAC,CAAA;IAC5B,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;CAChC;AAED,MAAM,MAAM,eAAe,GAAG,CAAC,KAAK,EAAE;IACpC,cAAc,EAAE,cAAc,CAAA;IAC9B,OAAO,EAAE,OAAO,CAAA;CACjB,KAAK,gBAAgB,CAAA;AAEtB;;;GAGG;AACH,MAAM,MAAM,qBAAqB,GAAG,CAClC,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,QAAQ,KACf,OAAO,CAAC,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;AAEpD;;;;GAIG;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;AAEtE,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,qBAAqB,CAAA;IAC3B,MAAM,EAAE,oBAAoB,CAAA;CAC7B;AAED,UAAU,sBAAsB;IAC9B,YAAY,EAAE,OAAO,YAAY,CAAA;IACjC,aAAa,EAAE,OAAO,aAAa,CAAA;IACnC,kBAAkB,CAChB,IAAI,EAAE,UAAU,CAAC,OAAO,cAAc,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,GACtD,OAAO,CAAC,cAAc,CAAC,CAAA;IAC1B,kBAAkB,EAAE,OAAO,2BAA2B,CAAA;IACtD,cAAc,EAAE,OAAO,cAAc,CAAA;IACrC,cAAc,EAAE,OAAO,cAAc,CAAA;CACtC;AAED,UAAU,uBAAuB;IAC/B,MAAM,EAAE,YAAY,CAAA;IACpB,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,iBAAiB,CAAA;IACzB,SAAS,EAAE,eAAe,CAAA;IAC1B,WAAW,EAAE,eAAe,CAAA;IAC5B,SAAS,CAAC,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAA;IAClC,YAAY,CAAC,EAAE,OAAO,CAAC,sBAAsB,CAAC,CAAA;CAC/C;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,MAAM,EACN,UAAU,EACV,MAAM,EACN,SAAS,EACT,WAAW,EACX,SAAS,EACT,YAAY,GACb,EAAE,uBAAuB,GAAG,qBAAqB,GAAG,gBAAgB,CA2OpE"}
@@ -1,4 +1,6 @@
1
- import { buildSidebarMachineStateFromAccounts, setSidebarMachineState, } from '../sidebar-state';
1
+ import { createHash } from 'node:crypto';
2
+ import { getHealthTracker } from '@cortexkit/antigravity-auth-core';
3
+ import { buildSidebarMachineStateFromAccounts, isAccountCurrent, setSidebarMachineState, toCapturedTier, } from '../sidebar-state';
2
4
  import { AccountManager } from './accounts';
3
5
  import { isOAuthAuth } from './auth';
4
6
  import { buildAuthFromStoredAccount, detectAuthStorageDrift, } from './auth-drift';
@@ -7,6 +9,17 @@ import { createLogger } from './logger';
7
9
  import { createProactiveRefreshQueue, } from './refresh-queue';
8
10
  import { AccountStorageUnreadableError, clearAccounts, loadAccounts, } from './storage';
9
11
  const log = createLogger('auth-loader');
12
+ /**
13
+ * Opaque identity derived from a refresh token. Mirrors the local
14
+ * helper in `account-manager.ts` and `command-data.ts` — the auth-loader
15
+ * stays independent because it ships in the plugin's import graph and
16
+ * can't reach into the core barrel for `quotaAccountIdentity`. The
17
+ * sidebar projection uses this hash to detect a stale quota snapshot
18
+ * captured for a different account after an index shift.
19
+ */
20
+ function refreshTokenIdentity(refreshToken) {
21
+ return createHash('sha256').update(refreshToken).digest('hex').slice(0, 16);
22
+ }
10
23
  export function createAuthLoader({ client, providerId, config, lifecycle, createFetch, onGetAuth, dependencies, }) {
11
24
  const deps = {
12
25
  loadAccounts: dependencies?.loadAccounts ?? loadAccounts,
@@ -18,6 +31,13 @@ export function createAuthLoader({ client, providerId, config, lifecycle, create
18
31
  getLogFilePath: dependencies?.getLogFilePath ?? getLogFilePath,
19
32
  };
20
33
  let fetchRuntime = null;
34
+ // Reload chain — `installRuntime` swaps the fetch runtime and
35
+ // (previously) discarded the previous runtime's dispose with `void`,
36
+ // so two overlapping reloads could interleave teardown. Serialize
37
+ // reloads through a single shared promise so each new install waits
38
+ // for the previous one to fully settle (including its dispose)
39
+ // before tearing down the runtime it depends on.
40
+ let reloadChain = Promise.resolve();
21
41
  lifecycle.register({
22
42
  async dispose() {
23
43
  const runtime = fetchRuntime;
@@ -25,7 +45,60 @@ export function createAuthLoader({ client, providerId, config, lifecycle, create
25
45
  await runtime?.dispose();
26
46
  },
27
47
  }, 'producer');
28
- return async (getAuth, provider) => {
48
+ // Reload hook: invoked after out-of-band storage mutations (e.g.
49
+ // OAuth add) so the live AccountManager + fetch interceptor see the
50
+ // newly-persisted account without waiting for a plugin restart. The
51
+ // handle returned below wires this through to the OAuth finish flow.
52
+ let reloadRuntime = async () => { };
53
+ const installRuntime = async (accountManager, getAuth) => {
54
+ if (accountManager.getAccountCount() > 0) {
55
+ accountManager.requestSaveToDisk();
56
+ }
57
+ let refreshQueue = null;
58
+ if (config.proactive_token_refresh &&
59
+ accountManager.getAccountCount() > 0) {
60
+ refreshQueue = deps.createRefreshQueue(client, providerId, {
61
+ enabled: config.proactive_token_refresh,
62
+ bufferSeconds: config.proactive_refresh_buffer_seconds,
63
+ checkIntervalSeconds: config.proactive_refresh_check_interval_seconds,
64
+ });
65
+ refreshQueue.setAccountManager(accountManager);
66
+ }
67
+ await lifecycle.replaceAccountRuntime(accountManager, refreshQueue);
68
+ refreshQueue?.start();
69
+ // Swap the fetch runtime FIRST so the host's captured fetch
70
+ // reference (a call-time delegating wrapper below) immediately
71
+ // routes through the new interceptor, then await the previous
72
+ // runtime's dispose. The swap-then-dispose order guarantees there
73
+ // is no fetch gap between the old and new runtimes.
74
+ const previousRuntime = fetchRuntime;
75
+ fetchRuntime = createFetch({ accountManager, getAuth });
76
+ await previousRuntime?.dispose();
77
+ // Push the freshly materialized account pool into the sidebar so the
78
+ // TUI's next poll renders the labels / health / cooldown it needs
79
+ // without waiting for the first fetch to complete.
80
+ await setSidebarMachineState(buildSidebarMachineStateFromAccounts(accountManager.getAccounts().map((entry) => {
81
+ const activeByFamily = accountManager.getActiveIndexByFamily();
82
+ return {
83
+ index: entry.index,
84
+ label: entry.label,
85
+ enabled: entry.enabled,
86
+ current: isAccountCurrent(entry.index, activeByFamily),
87
+ coolingDownUntil: entry.coolingDownUntil,
88
+ healthScore: getHealthTracker().getScore(entry.index),
89
+ cachedQuota: entry.cachedQuota,
90
+ // Stamp the sidebar snapshot so the projection can detect a
91
+ // stale cache that landed on the wrong account (the manager's
92
+ // `cachedQuotaAccountId` is keyed to whatever account actually
93
+ // produced the snapshot — the live refresh-token hash is the
94
+ // expected identity at this slot).
95
+ cachedQuotaAccountId: entry.cachedQuotaAccountId,
96
+ currentQuotaAccountId: refreshTokenIdentity(entry.parts.refreshToken),
97
+ tier: toCapturedTier(entry),
98
+ };
99
+ })));
100
+ };
101
+ async function runLoader(getAuth, provider) {
29
102
  onGetAuth?.(getAuth);
30
103
  let auth = await getAuth();
31
104
  if (!isOAuthAuth(auth)) {
@@ -89,35 +162,7 @@ export function createAuthLoader({ client, providerId, config, lifecycle, create
89
162
  return {};
90
163
  }
91
164
  const accountManager = await deps.loadAccountManager(auth);
92
- if (accountManager.getAccountCount() > 0) {
93
- accountManager.requestSaveToDisk();
94
- }
95
- let refreshQueue = null;
96
- if (config.proactive_token_refresh &&
97
- accountManager.getAccountCount() > 0) {
98
- refreshQueue = deps.createRefreshQueue(client, providerId, {
99
- enabled: config.proactive_token_refresh,
100
- bufferSeconds: config.proactive_refresh_buffer_seconds,
101
- checkIntervalSeconds: config.proactive_refresh_check_interval_seconds,
102
- });
103
- refreshQueue.setAccountManager(accountManager);
104
- }
105
- await lifecycle.replaceAccountRuntime(accountManager, refreshQueue);
106
- refreshQueue?.start();
107
- const previousRuntime = fetchRuntime;
108
- fetchRuntime = createFetch({ accountManager, getAuth });
109
- await previousRuntime?.dispose();
110
- // Push the freshly materialized account pool into the sidebar so the
111
- // TUI's next poll renders the labels / health / cooldown it needs
112
- // without waiting for the first fetch to complete.
113
- await setSidebarMachineState(buildSidebarMachineStateFromAccounts(accountManager.getAccounts().map((entry) => ({
114
- index: entry.index,
115
- label: entry.label,
116
- enabled: entry.enabled,
117
- current: false,
118
- coolingDownUntil: entry.coolingDownUntil,
119
- cachedQuota: entry.cachedQuota,
120
- }))));
165
+ await installRuntime(accountManager, getAuth);
121
166
  if (deps.isDebugEnabled()) {
122
167
  const logPath = deps.getLogFilePath();
123
168
  if (logPath) {
@@ -137,8 +182,44 @@ export function createAuthLoader({ client, providerId, config, lifecycle, create
137
182
  }
138
183
  return {
139
184
  apiKey: '',
140
- fetch: fetchRuntime.fetch,
185
+ // Return a stable delegating wrapper that reads `fetchRuntime`
186
+ // at CALL time. A direct `fetchRuntime!.fetch` reference would
187
+ // capture the current runtime; the host keeps that reference
188
+ // across `reload()` calls, so a captured fetch would still route
189
+ // through the OLD interceptor after an OAuth add. The wrapper
190
+ // matches the host's `LoaderResult.fetch` signature exactly
191
+ // (no `this` binding) so behavior is preserved.
192
+ fetch: (input, init) => fetchRuntime.fetch(input, init),
141
193
  };
194
+ }
195
+ reloadRuntime = async (getAuth) => {
196
+ const auth = await getAuth();
197
+ if (!isOAuthAuth(auth))
198
+ return;
199
+ const nextManager = await deps.loadAccountManager(auth);
200
+ await installRuntime(nextManager, getAuth);
142
201
  };
202
+ // Return a callable object: `plugin.auth.loader` is invoked with
203
+ // `(getAuth, provider)` (host contract), and `authLoader.reload(...)`
204
+ // rebuilds the runtime after out-of-band storage mutations (OAuth add).
205
+ // The callable closes over `runLoader` directly so the `this`-context
206
+ // binding stays unbound.
207
+ async function authLoaderCallable(getAuth, provider) {
208
+ return runLoader(getAuth, provider);
209
+ }
210
+ async function reload(getAuth) {
211
+ const next = reloadChain.then(() => reloadRuntime(getAuth));
212
+ reloadChain = next.catch(() => { });
213
+ return next;
214
+ }
215
+ // `load` mirrors the authLoaderCallable so the public handle
216
+ // (`AuthLoaderHandle.load`) exposes the same entry point the host
217
+ // invokes. Without this assignment, contract consumers read
218
+ // `.load` as undefined and the documented type would lie.
219
+ const authLoader = Object.assign(authLoaderCallable, {
220
+ reload,
221
+ load: authLoaderCallable,
222
+ });
223
+ return authLoader;
143
224
  }
144
225
  //# sourceMappingURL=auth-loader.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth-loader.js","sourceRoot":"","sources":["../../../src/plugin/auth-loader.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"auth-loader.js","sourceRoot":"","sources":["../../../src/plugin/auth-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAA;AACnE,OAAO,EACL,oCAAoC,EACpC,gBAAgB,EAChB,sBAAsB,EACtB,cAAc,GACf,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAA;AACpC,OAAO,EACL,0BAA0B,EAC1B,sBAAsB,GACvB,MAAM,cAAc,CAAA;AAErB,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAExD,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AACvC,OAAO,EACL,2BAA2B,GAE5B,MAAM,iBAAiB,CAAA;AACxB,OAAO,EACL,6BAA6B,EAC7B,aAAa,EACb,YAAY,GACb,MAAM,WAAW,CAAA;AASlB,MAAM,GAAG,GAAG,YAAY,CAAC,aAAa,CAAC,CAAA;AAEvC;;;;;;;GAOG;AACH,SAAS,oBAAoB,CAAC,YAAoB;IAChD,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;AAC7E,CAAC;AAsDD,MAAM,UAAU,gBAAgB,CAAC,EAC/B,MAAM,EACN,UAAU,EACV,MAAM,EACN,SAAS,EACT,WAAW,EACX,SAAS,EACT,YAAY,GACY;IACxB,MAAM,IAAI,GAA2B;QACnC,YAAY,EAAE,YAAY,EAAE,YAAY,IAAI,YAAY;QACxD,aAAa,EAAE,YAAY,EAAE,aAAa,IAAI,aAAa;QAC3D,kBAAkB,EAChB,YAAY,EAAE,kBAAkB;YAChC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,cAAc,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QAC/C,kBAAkB,EAChB,YAAY,EAAE,kBAAkB,IAAI,2BAA2B;QACjE,cAAc,EAAE,YAAY,EAAE,cAAc,IAAI,cAAc;QAC9D,cAAc,EAAE,YAAY,EAAE,cAAc,IAAI,cAAc;KAC/D,CAAA;IACD,IAAI,YAAY,GAA4B,IAAI,CAAA;IAChD,8DAA8D;IAC9D,qEAAqE;IACrE,kEAAkE;IAClE,oEAAoE;IACpE,+DAA+D;IAC/D,iDAAiD;IACjD,IAAI,WAAW,GAAkB,OAAO,CAAC,OAAO,EAAE,CAAA;IAElD,SAAS,CAAC,QAAQ,CAChB;QACE,KAAK,CAAC,OAAO;YACX,MAAM,OAAO,GAAG,YAAY,CAAA;YAC5B,YAAY,GAAG,IAAI,CAAA;YACnB,MAAM,OAAO,EAAE,OAAO,EAAE,CAAA;QAC1B,CAAC;KACF,EACD,UAAU,CACX,CAAA;IAED,iEAAiE;IACjE,oEAAoE;IACpE,oEAAoE;IACpE,qEAAqE;IACrE,IAAI,aAAa,GAAyB,KAAK,IAAI,EAAE,GAAE,CAAC,CAAA;IAExD,MAAM,cAAc,GAAG,KAAK,EAC1B,cAA8B,EAC9B,OAAgB,EACD,EAAE;QACjB,IAAI,cAAc,CAAC,eAAe,EAAE,GAAG,CAAC,EAAE,CAAC;YACzC,cAAc,CAAC,iBAAiB,EAAE,CAAA;QACpC,CAAC;QAED,IAAI,YAAY,GAAiC,IAAI,CAAA;QACrD,IACE,MAAM,CAAC,uBAAuB;YAC9B,cAAc,CAAC,eAAe,EAAE,GAAG,CAAC,EACpC,CAAC;YACD,YAAY,GAAG,IAAI,CAAC,kBAAkB,CAAC,MAAM,EAAE,UAAU,EAAE;gBACzD,OAAO,EAAE,MAAM,CAAC,uBAAuB;gBACvC,aAAa,EAAE,MAAM,CAAC,gCAAgC;gBACtD,oBAAoB,EAAE,MAAM,CAAC,wCAAwC;aACtE,CAAC,CAAA;YACF,YAAY,CAAC,iBAAiB,CAAC,cAAc,CAAC,CAAA;QAChD,CAAC;QAED,MAAM,SAAS,CAAC,qBAAqB,CAAC,cAAc,EAAE,YAAY,CAAC,CAAA;QACnE,YAAY,EAAE,KAAK,EAAE,CAAA;QAErB,4DAA4D;QAC5D,+DAA+D;QAC/D,8DAA8D;QAC9D,kEAAkE;QAClE,oDAAoD;QACpD,MAAM,eAAe,GAAG,YAAY,CAAA;QACpC,YAAY,GAAG,WAAW,CAAC,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC,CAAA;QACvD,MAAM,eAAe,EAAE,OAAO,EAAE,CAAA;QAEhC,qEAAqE;QACrE,kEAAkE;QAClE,mDAAmD;QACnD,MAAM,sBAAsB,CAC1B,oCAAoC,CAClC,cAAc,CAAC,WAAW,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;YACzC,MAAM,cAAc,GAAG,cAAc,CAAC,sBAAsB,EAAE,CAAA;YAC9D,OAAO;gBACL,KAAK,EAAE,KAAK,CAAC,KAAK;gBAClB,KAAK,EAAE,KAAK,CAAC,KAAK;gBAClB,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,OAAO,EAAE,gBAAgB,CAAC,KAAK,CAAC,KAAK,EAAE,cAAc,CAAC;gBACtD,gBAAgB,EAAE,KAAK,CAAC,gBAAgB;gBACxC,WAAW,EAAE,gBAAgB,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC;gBACrD,WAAW,EAAE,KAAK,CAAC,WAAW;gBAC9B,4DAA4D;gBAC5D,8DAA8D;gBAC9D,+DAA+D;gBAC/D,6DAA6D;gBAC7D,mCAAmC;gBACnC,oBAAoB,EAAE,KAAK,CAAC,oBAAoB;gBAChD,qBAAqB,EAAE,oBAAoB,CACzC,KAAK,CAAC,KAAK,CAAC,YAAY,CACzB;gBACD,IAAI,EAAE,cAAc,CAAC,KAAK,CAAC;aAC5B,CAAA;QACH,CAAC,CAAC,CACH,CACF,CAAA;IACH,CAAC,CAAA;IAED,KAAK,UAAU,SAAS,CACtB,OAAgB,EAChB,QAAkB;QAElB,SAAS,EAAE,CAAC,OAAO,CAAC,CAAA;QACpB,IAAI,IAAI,GAAG,MAAM,OAAO,EAAE,CAAA;QAE1B,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;YACvB,IAAI,cAAwD,CAAA;YAC5D,IAAI,CAAC;gBACH,cAAc,GAAG,MAAM,IAAI,CAAC,YAAY,EAAE,CAAA;YAC5C,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,4DAA4D;gBAC5D,uDAAuD;gBACvD,2DAA2D;gBAC3D,yDAAyD;gBACzD,6DAA6D;gBAC7D,IAAI,KAAK,YAAY,6BAA6B,EAAE,CAAC;oBACnD,GAAG,CAAC,KAAK,CAAC,kDAAkD,EAAE;wBAC5D,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI;wBACxB,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM;wBAC5B,UAAU,EAAE,KAAK,CAAC,OAAO,CAAC,UAAU;qBACrC,CAAC,CAAA;oBACF,IAAI,CAAC;wBACH,MAAM,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC;4BACzB,IAAI,EAAE;gCACJ,OAAO,EAAE,sBAAsB,KAAK,CAAC,OAAO,CAAC,IAAI,mBAAmB,KAAK,CAAC,OAAO,CAAC,MAAM,sEAAsE,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,4BAA4B,KAAK,CAAC,OAAO,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;gCACvP,OAAO,EAAE,OAAO;gCAChB,QAAQ,EAAE,MAAM;6BACjB;yBACF,CAAC,CAAA;oBACJ,CAAC;oBAAC,MAAM,CAAC,CAAA,CAAC;gBACZ,CAAC;gBACD,MAAM,KAAK,CAAA;YACb,CAAC;YACD,MAAM,KAAK,GAAG,sBAAsB,CAAC,IAAI,EAAE,cAAc,CAAC,CAAA;YAC1D,IAAI,KAAK,CAAC,MAAM,KAAK,YAAY,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;gBACnD,IAAI,GAAG,0BAA0B,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;gBAChD,IAAI,CAAC;oBACH,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;wBACpB,IAAI,EAAE,EAAE,EAAE,EAAE,UAAU,EAAE;wBACxB,IAAI,EAAE;4BACJ,IAAI,EAAE,OAAO;4BACb,OAAO,EAAE,IAAI,CAAC,OAAO;4BACrB,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,EAAE;4BACzB,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,CAAC;yBAC3B;qBACF,CAAC,CAAA;oBACF,GAAG,CAAC,IAAI,CAAC,sDAAsD,EAAE;wBAC/D,MAAM,EAAE,KAAK,CAAC,MAAM;wBACpB,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,KAAK;qBAC3B,CAAC,CAAA;gBACJ,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,GAAG,CAAC,IAAI,CACN,+DAA+D,EAC/D,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CACzB,CAAA;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAED,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;YACvB,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,aAAa,EAAE,CAAA;YAC5B,CAAC;YAAC,MAAM,CAAC,CAAA,CAAC;YACV,OAAO,EAAE,CAAA;QACX,CAAC;QAED,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAA;QAC1D,MAAM,cAAc,CAAC,cAAc,EAAE,OAAO,CAAC,CAAA;QAE7C,IAAI,IAAI,CAAC,cAAc,EAAE,EAAE,CAAC;YAC1B,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,EAAE,CAAA;YACrC,IAAI,OAAO,EAAE,CAAC;gBACZ,IAAI,CAAC;oBACH,MAAM,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC;wBACzB,IAAI,EAAE,EAAE,OAAO,EAAE,cAAc,OAAO,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE;qBAC5D,CAAC,CAAA;gBACJ,CAAC;gBAAC,MAAM,CAAC,CAAA,CAAC;YACZ,CAAC;QACH,CAAC;QAED,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;YACpB,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;gBACnD,IAAI,KAAK;oBAAG,KAAuB,CAAC,IAAI,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAA;YACpE,CAAC;QACH,CAAC;QAED,OAAO;YACL,MAAM,EAAE,EAAE;YACV,+DAA+D;YAC/D,+DAA+D;YAC/D,6DAA6D;YAC7D,iEAAiE;YACjE,8DAA8D;YAC9D,4DAA4D;YAC5D,gDAAgD;YAChD,KAAK,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,YAAa,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC;SACzD,CAAA;IACH,CAAC;IAED,aAAa,GAAG,KAAK,EAAE,OAAgB,EAAiB,EAAE;QACxD,MAAM,IAAI,GAAG,MAAM,OAAO,EAAE,CAAA;QAC5B,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;YAAE,OAAM;QAC9B,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAA;QACvD,MAAM,cAAc,CAAC,WAAW,EAAE,OAAO,CAAC,CAAA;IAC5C,CAAC,CAAA;IAED,iEAAiE;IACjE,sEAAsE;IACtE,wEAAwE;IACxE,sEAAsE;IACtE,yBAAyB;IACzB,KAAK,UAAU,kBAAkB,CAC/B,OAAgB,EAChB,QAAkB;QAElB,OAAO,SAAS,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;IACrC,CAAC;IACD,KAAK,UAAU,MAAM,CAAC,OAAgB;QACpC,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAA;QAC3D,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;QAClC,OAAO,IAAI,CAAA;IACb,CAAC;IACD,6DAA6D;IAC7D,kEAAkE;IAClE,4DAA4D;IAC5D,0DAA0D;IAC1D,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,kBAAkB,EAAE;QACnD,MAAM;QACN,IAAI,EAAE,kBAAkB;KACzB,CAAC,CAAA;IACF,OAAO,UAAsD,CAAA;AAC/D,CAAC"}
@@ -0,0 +1,146 @@
1
+ /**
2
+ * Background quota poller.
3
+ *
4
+ * Runs a jittered, `unref()`'d timer that periodically refreshes quota for
5
+ * all accounts and pushes ONE sidebar snapshot per tick. Three-layer
6
+ * cross-process dedup:
7
+ *
8
+ * 1. Freshness gate — the only hard correctness bound for quota snapshots.
9
+ * Reads `checkedAt` from the on-disk sidebar state; skips quota work when
10
+ * it is fresher than
11
+ * `max(intervalMs − 60_000, floor(intervalMs / 2))`. The /2 floor
12
+ * ensures the gate still fires at the 1-minute minimum interval.
13
+ *
14
+ * 2. Advisory fenced lock — an optimization that lets a single process do
15
+ * the network work when several wake up simultaneously. Held → skip.
16
+ *
17
+ * 3. Lock throws → FAIL CLOSED (skip this tick, add jitter to next). A
18
+ * fallback mutex is NOT used here. The correct reasoning is: the
19
+ * freshness gate (layer 1) already bounds how many refreshes can land;
20
+ * a secondary "claim marker" file is just a worse re-implementation of
21
+ * the fenced lock we just failed to acquire — it replicates the same
22
+ * ownership problem without the protocol guarantees, and any transient
23
+ * I/O error that made the lock throw will likely affect a claim file
24
+ * too. The previous poller attempt fell into this trap across three
25
+ * review rounds; this comment exists so a future reviewer stops
26
+ * re-litigating it.
27
+ */
28
+ import type { AccountMetadataV3, QuotaGroup, QuotaGroupSummary } from '@cortexkit/antigravity-auth-core';
29
+ import { acquireFencedFileLock } from '@cortexkit/antigravity-auth-core/file-lock';
30
+ import type { QuotaManager } from './quota';
31
+ /**
32
+ * The subset of AccountManager that the poller needs. Using a narrow
33
+ * interface keeps the module decoupled from the large concrete class and
34
+ * lets tests pass minimal stubs without satisfying 90+ methods.
35
+ */
36
+ export interface PollerAccountView {
37
+ getAccounts(): Array<{
38
+ index: number;
39
+ label?: string;
40
+ enabled?: boolean;
41
+ parts: {
42
+ refreshToken: string;
43
+ };
44
+ cachedQuota?: Partial<Record<QuotaGroup, QuotaGroupSummary>>;
45
+ cachedQuotaAccountId?: string;
46
+ coolingDownUntil?: number;
47
+ /** Captured plan tier ID (raw upstream string). */
48
+ capturedTierId?: string;
49
+ /** Captured paid-tier ID (raw upstream string). */
50
+ capturedPaidTierId?: string;
51
+ /** Epoch ms when capturedTierId was last recorded. */
52
+ capturedTierAt?: number;
53
+ /** Schema version of the most recent tier capture. */
54
+ capturedTierSchemaVersion?: number;
55
+ }>;
56
+ /** Must return the full AccountMetadataV3 shape so the quota manager
57
+ * can use token-refresh and project-context fields inside each fetch. */
58
+ getAccountsForQuotaCheck(): AccountMetadataV3[];
59
+ updateQuotaCache(accountIndex: number, quotaGroups: Partial<Record<QuotaGroup, QuotaGroupSummary>>, expectedRefreshToken?: string): void;
60
+ /**
61
+ * Apply a subset of quota-result fields (e.g. captured tier) onto the
62
+ * in-memory account record without touching the quota cache itself.
63
+ */
64
+ applyUpdatedAccount(accountIndex: number, patch: {
65
+ capturedTierId?: string;
66
+ capturedPaidTierId?: string;
67
+ capturedTierAt?: number;
68
+ capturedTierSchemaVersion?: number;
69
+ }, expectedRefreshToken?: string): void;
70
+ requestSaveToDisk(): void;
71
+ /**
72
+ * Returns the active account index per model family so the sidebar
73
+ * snapshot can stamp the `current` flag on the right account.
74
+ */
75
+ getActiveIndexByFamily(): {
76
+ claude: number;
77
+ gemini: number;
78
+ };
79
+ }
80
+ export interface BackgroundQuotaRefreshOptions {
81
+ intervalMs: number;
82
+ sidebarStateFile: string;
83
+ /**
84
+ * Supplier for the live account pool. Called inside each locked phase, so it
85
+ * observes any concurrent add/remove that completed while waiting for the
86
+ * lock.
87
+ */
88
+ getAccountManager: () => PollerAccountView | null;
89
+ quotaManager: QuotaManager;
90
+ /**
91
+ * Optional tier-refresh callback. When provided, the poller calls this
92
+ * once per tick for the account whose capturedTierAt is missing or older
93
+ * than TIER_STALENESS_TTL_MS. The callback handles its own token-refresh
94
+ * and must resolve to a tier object (or null on failure / nothing to
95
+ * report) -- failure must never reject, since tier is best-effort.
96
+ *
97
+ * Wired in index.ts through the same agyTransport seam the quota manager
98
+ * uses, so e2e tests can inject a mock alongside the mock quota fetch.
99
+ */
100
+ loadAccountTier?: (account: AccountMetadataV3) => Promise<{
101
+ id: string;
102
+ paidId?: string;
103
+ capturedAt: number;
104
+ } | null>;
105
+ /**
106
+ * Clock / randomness seam. Defaults to the system clock.
107
+ */
108
+ now?: () => number;
109
+ random?: () => number;
110
+ /** Lock acquisition seam used by deterministic concurrency tests. */
111
+ acquireLock?: typeof acquireFencedFileLock;
112
+ }
113
+ /**
114
+ * Per-loader-instance background quota poller.
115
+ *
116
+ * Must be created after the plugin has initialised (so `getAccountManager()`
117
+ * is populated) and disposed via the producer lifecycle phase.
118
+ */
119
+ export declare class BackgroundQuotaRefresh {
120
+ private readonly intervalMs;
121
+ private readonly sidebarStateFile;
122
+ private readonly getAccountManager;
123
+ private readonly quotaManager;
124
+ private readonly loadAccountTier?;
125
+ private readonly now;
126
+ private readonly random;
127
+ private readonly acquireLock;
128
+ private timer;
129
+ /** Resolves when the currently-running tick completes (or immediately if none). */
130
+ private inFlight;
131
+ private disposed;
132
+ constructor(options: BackgroundQuotaRefreshOptions);
133
+ /** Start the background timer. Idempotent: a second call is a no-op. */
134
+ start(): void;
135
+ /** Stop the timer and await any in-flight tick. */
136
+ dispose(): Promise<void>;
137
+ private jitteredStartDelay;
138
+ private jitteredInterval;
139
+ private scheduleNext;
140
+ private runTick;
141
+ private refresh;
142
+ private refreshQuota;
143
+ private refreshTierSlot;
144
+ private pushSnapshot;
145
+ }
146
+ //# sourceMappingURL=background-quota-refresh.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"background-quota-refresh.d.ts","sourceRoot":"","sources":["../../../src/plugin/background-quota-refresh.ts"],"names":[],"mappings":"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"}