geminimock 0.1.2 → 0.1.4

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 (36) hide show
  1. package/README.md +244 -10
  2. package/dist/auth/account-store.d.ts +36 -0
  3. package/dist/auth/account-store.js +366 -0
  4. package/dist/auth/account-store.js.map +1 -0
  5. package/dist/auth/credential-store.d.ts +2 -0
  6. package/dist/auth/credential-store.js +33 -1
  7. package/dist/auth/credential-store.js.map +1 -1
  8. package/dist/auth/oauth-flow.d.ts +0 -2
  9. package/dist/auth/oauth-flow.js +122 -15
  10. package/dist/auth/oauth-flow.js.map +1 -1
  11. package/dist/auth/oauth-service.d.ts +12 -3
  12. package/dist/auth/oauth-service.js +90 -29
  13. package/dist/auth/oauth-service.js.map +1 -1
  14. package/dist/cli.js +336 -14
  15. package/dist/cli.js.map +1 -1
  16. package/dist/commands/auth-login.d.ts +16 -0
  17. package/dist/commands/auth-login.js +114 -0
  18. package/dist/commands/auth-login.js.map +1 -0
  19. package/dist/commands/auth-logout.d.ts +19 -0
  20. package/dist/commands/auth-logout.js +178 -0
  21. package/dist/commands/auth-logout.js.map +1 -0
  22. package/dist/config/env.d.ts +1 -0
  23. package/dist/config/env.js +3 -1
  24. package/dist/config/env.js.map +1 -1
  25. package/dist/gemini/code-assist-client.d.ts +15 -1
  26. package/dist/gemini/code-assist-client.js +101 -37
  27. package/dist/gemini/code-assist-client.js.map +1 -1
  28. package/dist/gemini/errors.d.ts +8 -0
  29. package/dist/gemini/errors.js +29 -0
  30. package/dist/gemini/errors.js.map +1 -0
  31. package/dist/server/app.js +8 -3
  32. package/dist/server/app.js.map +1 -1
  33. package/dist/server/background-service.d.ts +46 -0
  34. package/dist/server/background-service.js +332 -0
  35. package/dist/server/background-service.js.map +1 -0
  36. package/package.json +14 -1
@@ -0,0 +1,366 @@
1
+ import { randomBytes } from "node:crypto";
2
+ import { mkdir, readFile, rm, writeFile } from "node:fs/promises";
3
+ import { dirname, join } from "node:path";
4
+ import { z } from "zod";
5
+ const credentialSchema = z.object({
6
+ access_token: z.string(),
7
+ refresh_token: z.string().optional(),
8
+ expiry_date: z.number().optional(),
9
+ token_type: z.string().optional(),
10
+ scope: z.string().optional()
11
+ });
12
+ const accountSchema = z.object({
13
+ id: z.string(),
14
+ email: z.string().optional(),
15
+ enabled: z.boolean().default(true),
16
+ created_at: z.number(),
17
+ updated_at: z.number(),
18
+ last_used_at: z.number().optional(),
19
+ cooldown_until: z.number().optional(),
20
+ last_error: z.string().optional(),
21
+ credentials: credentialSchema
22
+ });
23
+ const storageSchema = z.object({
24
+ version: z.literal(1),
25
+ active_account_id: z.string().optional(),
26
+ rotation_cursor: z.number().int().nonnegative().default(0),
27
+ accounts: z.array(accountSchema).default([])
28
+ });
29
+ function createEmptyStorage() {
30
+ return {
31
+ version: 1,
32
+ active_account_id: undefined,
33
+ rotation_cursor: 0,
34
+ accounts: []
35
+ };
36
+ }
37
+ async function readJson(path) {
38
+ try {
39
+ const raw = await readFile(path, "utf8");
40
+ return JSON.parse(raw);
41
+ }
42
+ catch {
43
+ return null;
44
+ }
45
+ }
46
+ function normalizeCredentials(credentials) {
47
+ return credentialSchema.parse({
48
+ access_token: credentials.access_token,
49
+ refresh_token: credentials.refresh_token ?? undefined,
50
+ expiry_date: credentials.expiry_date ?? undefined,
51
+ token_type: credentials.token_type ?? undefined,
52
+ scope: credentials.scope ?? undefined
53
+ });
54
+ }
55
+ function now() {
56
+ return Date.now();
57
+ }
58
+ function accountId() {
59
+ return randomBytes(8).toString("hex");
60
+ }
61
+ function isUsable(account, at) {
62
+ if (!account.enabled) {
63
+ return false;
64
+ }
65
+ const cooldownUntil = account.cooldown_until ?? 0;
66
+ return cooldownUntil <= at;
67
+ }
68
+ function ensureActiveAccount(storage) {
69
+ if (storage.accounts.length === 0) {
70
+ storage.active_account_id = undefined;
71
+ storage.rotation_cursor = 0;
72
+ return storage;
73
+ }
74
+ const active = storage.accounts.find((account) => account.id === storage.active_account_id);
75
+ if (active?.enabled) {
76
+ return storage;
77
+ }
78
+ const fallback = storage.accounts.find((account) => account.enabled) ?? storage.accounts[0];
79
+ storage.active_account_id = fallback?.id;
80
+ return storage;
81
+ }
82
+ export function createAccountStore(accountsPath, legacyOAuthPath, fallbackOAuthPath) {
83
+ const signedOutPath = join(dirname(accountsPath), ".signed_out");
84
+ const fallbackDir = fallbackOAuthPath ? dirname(fallbackOAuthPath) : undefined;
85
+ const fallbackAccountsPath = fallbackDir ? join(fallbackDir, "google_accounts.json") : undefined;
86
+ async function writeStorage(storage) {
87
+ const normalized = storageSchema.parse(storage);
88
+ await mkdir(dirname(accountsPath), { recursive: true });
89
+ await writeFile(accountsPath, JSON.stringify(normalized, null, 2), { mode: 0o600, encoding: "utf8" });
90
+ await rm(signedOutPath, { force: true });
91
+ }
92
+ async function readStorageFromFile() {
93
+ const raw = await readJson(accountsPath);
94
+ if (!raw) {
95
+ return null;
96
+ }
97
+ try {
98
+ const parsed = storageSchema.parse(raw);
99
+ return ensureActiveAccount(parsed);
100
+ }
101
+ catch {
102
+ return null;
103
+ }
104
+ }
105
+ async function signedOut() {
106
+ try {
107
+ await readFile(signedOutPath, "utf8");
108
+ return true;
109
+ }
110
+ catch {
111
+ return false;
112
+ }
113
+ }
114
+ async function migrateLegacySingleAccount() {
115
+ const storage = createEmptyStorage();
116
+ if (await signedOut()) {
117
+ return storage;
118
+ }
119
+ const legacy = legacyOAuthPath ? await readJson(legacyOAuthPath) : null;
120
+ const fallback = fallbackOAuthPath ? await readJson(fallbackOAuthPath) : null;
121
+ const candidate = legacy ?? fallback;
122
+ if (!candidate) {
123
+ return storage;
124
+ }
125
+ try {
126
+ const credentials = credentialSchema.parse(candidate);
127
+ const initial = {
128
+ id: accountId(),
129
+ enabled: true,
130
+ created_at: now(),
131
+ updated_at: now(),
132
+ last_used_at: undefined,
133
+ cooldown_until: undefined,
134
+ last_error: undefined,
135
+ email: undefined,
136
+ credentials
137
+ };
138
+ storage.accounts = [initial];
139
+ storage.active_account_id = initial.id;
140
+ storage.rotation_cursor = 0;
141
+ await writeStorage(storage);
142
+ return storage;
143
+ }
144
+ catch {
145
+ return storage;
146
+ }
147
+ }
148
+ async function loadStorage() {
149
+ const existing = await readStorageFromFile();
150
+ if (existing) {
151
+ return ensureActiveAccount(existing);
152
+ }
153
+ return migrateLegacySingleAccount();
154
+ }
155
+ function resolveAccount(accounts, idOrEmail) {
156
+ const key = idOrEmail.trim().toLowerCase();
157
+ return accounts.find((account) => account.id === idOrEmail || account.email?.toLowerCase() === key);
158
+ }
159
+ function upsertAccount(storage, credentials, email) {
160
+ const normalized = normalizeCredentials(credentials);
161
+ const emailKey = email?.trim().toLowerCase();
162
+ const refreshToken = normalized.refresh_token;
163
+ const existing = storage.accounts.find((account) => {
164
+ if (refreshToken && account.credentials.refresh_token === refreshToken) {
165
+ return true;
166
+ }
167
+ if (emailKey && account.email?.toLowerCase() === emailKey) {
168
+ return true;
169
+ }
170
+ return false;
171
+ });
172
+ if (existing) {
173
+ existing.credentials = normalizeCredentials({
174
+ ...normalized,
175
+ refresh_token: normalized.refresh_token ?? existing.credentials.refresh_token,
176
+ expiry_date: normalized.expiry_date ?? existing.credentials.expiry_date
177
+ });
178
+ existing.enabled = true;
179
+ existing.updated_at = now();
180
+ existing.cooldown_until = undefined;
181
+ existing.last_error = undefined;
182
+ if (email) {
183
+ existing.email = email;
184
+ }
185
+ storage.active_account_id = existing.id;
186
+ return existing;
187
+ }
188
+ const created = {
189
+ id: accountId(),
190
+ email: email,
191
+ enabled: true,
192
+ created_at: now(),
193
+ updated_at: now(),
194
+ last_used_at: undefined,
195
+ cooldown_until: undefined,
196
+ last_error: undefined,
197
+ credentials: normalized
198
+ };
199
+ storage.accounts.push(created);
200
+ storage.active_account_id = created.id;
201
+ return created;
202
+ }
203
+ return {
204
+ accountsPath,
205
+ async listAccounts() {
206
+ const storage = await loadStorage();
207
+ return storage.accounts.map((account) => ({ ...account }));
208
+ },
209
+ async getActiveAccount() {
210
+ const storage = await loadStorage();
211
+ const active = storage.accounts.find((account) => account.id === storage.active_account_id);
212
+ return active ? { ...active } : null;
213
+ },
214
+ async getAccountCount() {
215
+ const storage = await loadStorage();
216
+ return storage.accounts.filter((account) => account.enabled).length;
217
+ },
218
+ async addOrUpdateAccount(credentials, email) {
219
+ const storage = await loadStorage();
220
+ const account = upsertAccount(storage, credentials, email);
221
+ await writeStorage(storage);
222
+ return { ...account };
223
+ },
224
+ async setActiveAccount(idOrEmail) {
225
+ const storage = await loadStorage();
226
+ const account = resolveAccount(storage.accounts, idOrEmail);
227
+ if (!account) {
228
+ throw new Error(`Account not found: ${idOrEmail}`);
229
+ }
230
+ if (!account.enabled) {
231
+ throw new Error(`Account is disabled: ${idOrEmail}`);
232
+ }
233
+ storage.active_account_id = account.id;
234
+ account.updated_at = now();
235
+ await writeStorage(storage);
236
+ return { ...account };
237
+ },
238
+ async removeAccount(idOrEmail) {
239
+ const storage = await loadStorage();
240
+ const index = storage.accounts.findIndex((account) => {
241
+ const email = account.email?.toLowerCase();
242
+ const key = idOrEmail.trim().toLowerCase();
243
+ return account.id === idOrEmail || email === key;
244
+ });
245
+ if (index < 0) {
246
+ return false;
247
+ }
248
+ const removed = storage.accounts.splice(index, 1)[0];
249
+ if (removed?.id === storage.active_account_id) {
250
+ storage.active_account_id = storage.accounts.find((account) => account.enabled)?.id
251
+ ?? storage.accounts[0]?.id;
252
+ }
253
+ await writeStorage(storage);
254
+ return true;
255
+ },
256
+ async logoutActive() {
257
+ const storage = await loadStorage();
258
+ const index = storage.accounts.findIndex((account) => account.id === storage.active_account_id);
259
+ if (index < 0) {
260
+ return null;
261
+ }
262
+ const removed = storage.accounts.splice(index, 1)[0];
263
+ if (removed?.id === storage.active_account_id) {
264
+ storage.active_account_id = storage.accounts.find((account) => account.enabled)?.id
265
+ ?? storage.accounts[0]?.id;
266
+ }
267
+ if (storage.accounts.length === 0) {
268
+ storage.rotation_cursor = 0;
269
+ }
270
+ else if (storage.rotation_cursor >= storage.accounts.length) {
271
+ storage.rotation_cursor = 0;
272
+ }
273
+ await writeStorage(storage);
274
+ return removed ? { ...removed } : null;
275
+ },
276
+ async markActiveUsed() {
277
+ const storage = await loadStorage();
278
+ const active = storage.accounts.find((account) => account.id === storage.active_account_id);
279
+ if (!active) {
280
+ return;
281
+ }
282
+ active.last_used_at = now();
283
+ active.updated_at = now();
284
+ active.cooldown_until = undefined;
285
+ active.last_error = undefined;
286
+ await writeStorage(storage);
287
+ },
288
+ async updateActiveCredentials(credentials, email) {
289
+ const storage = await loadStorage();
290
+ let active = storage.accounts.find((account) => account.id === storage.active_account_id);
291
+ if (!active) {
292
+ active = upsertAccount(storage, credentials, email);
293
+ }
294
+ else {
295
+ const normalized = normalizeCredentials(credentials);
296
+ active.credentials = normalizeCredentials({
297
+ ...normalized,
298
+ refresh_token: normalized.refresh_token ?? active.credentials.refresh_token,
299
+ expiry_date: normalized.expiry_date ?? active.credentials.expiry_date
300
+ });
301
+ active.updated_at = now();
302
+ active.cooldown_until = undefined;
303
+ active.last_error = undefined;
304
+ if (email) {
305
+ active.email = email;
306
+ }
307
+ }
308
+ await writeStorage(storage);
309
+ return { ...active };
310
+ },
311
+ async rotateActiveAccount(reason, cooldownMs) {
312
+ const storage = await loadStorage();
313
+ if (storage.accounts.length < 2) {
314
+ return null;
315
+ }
316
+ const at = now();
317
+ const activeIndex = storage.accounts.findIndex((account) => account.id === storage.active_account_id);
318
+ const current = activeIndex >= 0 ? storage.accounts[activeIndex] : undefined;
319
+ if (!current) {
320
+ storage.active_account_id = storage.accounts.find((account) => isUsable(account, at))?.id
321
+ ?? storage.accounts[0]?.id;
322
+ await writeStorage(storage);
323
+ return storage.accounts.find((account) => account.id === storage.active_account_id) ?? null;
324
+ }
325
+ current.cooldown_until = at + Math.max(0, cooldownMs);
326
+ current.last_error = reason;
327
+ current.updated_at = at;
328
+ for (let step = 1; step <= storage.accounts.length; step += 1) {
329
+ const idx = (activeIndex + step) % storage.accounts.length;
330
+ const candidate = storage.accounts[idx];
331
+ if (!candidate) {
332
+ continue;
333
+ }
334
+ if (candidate.id === current.id) {
335
+ continue;
336
+ }
337
+ if (!isUsable(candidate, at)) {
338
+ continue;
339
+ }
340
+ storage.active_account_id = candidate.id;
341
+ storage.rotation_cursor = idx;
342
+ candidate.last_used_at = at;
343
+ candidate.updated_at = at;
344
+ await writeStorage(storage);
345
+ return { ...candidate };
346
+ }
347
+ await writeStorage(storage);
348
+ return null;
349
+ },
350
+ async clearAll() {
351
+ await rm(accountsPath, { force: true });
352
+ await mkdir(dirname(accountsPath), { recursive: true });
353
+ await writeFile(signedOutPath, `${Date.now()}`, { mode: 0o600, encoding: "utf8" });
354
+ if (legacyOAuthPath) {
355
+ await rm(legacyOAuthPath, { force: true });
356
+ }
357
+ if (fallbackOAuthPath) {
358
+ await rm(fallbackOAuthPath, { force: true });
359
+ }
360
+ if (fallbackAccountsPath) {
361
+ await rm(fallbackAccountsPath, { force: true });
362
+ }
363
+ }
364
+ };
365
+ }
366
+ //# sourceMappingURL=account-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"account-store.js","sourceRoot":"","sources":["../../src/auth/account-store.ts"],"names":[],"mappings":"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"}
@@ -12,6 +12,8 @@ export declare function createCredentialStore(path: string, fallbackPath?: strin
12
12
  load(): Promise<StoredCredentials | null>;
13
13
  save(credentials: StoredCredentials): Promise<void>;
14
14
  clear(): Promise<void>;
15
+ loadFallback(): Promise<StoredCredentials | null>;
16
+ clearFallback(): Promise<void>;
15
17
  };
16
18
  export type CredentialStore = ReturnType<typeof createCredentialStore>;
17
19
  export {};
@@ -1,5 +1,5 @@
1
1
  import { mkdir, readFile, rm, writeFile } from "node:fs/promises";
2
- import { dirname } from "node:path";
2
+ import { dirname, join } from "node:path";
3
3
  import { z } from "zod";
4
4
  const credentialSchema = z.object({
5
5
  access_token: z.string(),
@@ -18,7 +18,19 @@ async function readCredentialFile(path) {
18
18
  return null;
19
19
  }
20
20
  }
21
+ async function exists(path) {
22
+ try {
23
+ await readFile(path, "utf8");
24
+ return true;
25
+ }
26
+ catch {
27
+ return false;
28
+ }
29
+ }
21
30
  export function createCredentialStore(path, fallbackPath) {
31
+ const signedOutPath = `${dirname(path)}/.signed_out`;
32
+ const fallbackDir = fallbackPath ? dirname(fallbackPath) : undefined;
33
+ const fallbackAccountsPath = fallbackDir ? join(fallbackDir, "google_accounts.json") : undefined;
22
34
  return {
23
35
  path,
24
36
  async load() {
@@ -26,6 +38,9 @@ export function createCredentialStore(path, fallbackPath) {
26
38
  if (primary) {
27
39
  return primary;
28
40
  }
41
+ if (await exists(signedOutPath)) {
42
+ return null;
43
+ }
29
44
  if (!fallbackPath) {
30
45
  return null;
31
46
  }
@@ -35,9 +50,26 @@ export function createCredentialStore(path, fallbackPath) {
35
50
  const data = credentialSchema.parse(credentials);
36
51
  await mkdir(dirname(path), { recursive: true });
37
52
  await writeFile(path, JSON.stringify(data, null, 2), { mode: 0o600, encoding: "utf8" });
53
+ await rm(signedOutPath, { force: true });
38
54
  },
39
55
  async clear() {
40
56
  await rm(path, { force: true });
57
+ await mkdir(dirname(path), { recursive: true });
58
+ await writeFile(signedOutPath, `${Date.now()}`, { mode: 0o600, encoding: "utf8" });
59
+ },
60
+ async loadFallback() {
61
+ if (!fallbackPath) {
62
+ return null;
63
+ }
64
+ return readCredentialFile(fallbackPath);
65
+ },
66
+ async clearFallback() {
67
+ if (fallbackPath) {
68
+ await rm(fallbackPath, { force: true });
69
+ }
70
+ if (fallbackAccountsPath) {
71
+ await rm(fallbackAccountsPath, { force: true });
72
+ }
41
73
  }
42
74
  };
43
75
  }
@@ -1 +1 @@
1
- {"version":3,"file":"credential-store.js","sourceRoot":"","sources":["../../src/auth/credential-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChC,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE;IACxB,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACpC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAClC,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACjC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC7B,CAAC,CAAC;AAIH,KAAK,UAAU,kBAAkB,CAAC,IAAY;IAC5C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACzC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAY,CAAC;QAC1C,OAAO,gBAAgB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,IAAY,EAAE,YAAqB;IACvE,OAAO;QACL,IAAI;QACJ,KAAK,CAAC,IAAI;YACR,MAAM,OAAO,GAAG,MAAM,kBAAkB,CAAC,IAAI,CAAC,CAAC;YAC/C,IAAI,OAAO,EAAE,CAAC;gBACZ,OAAO,OAAO,CAAC;YACjB,CAAC;YACD,IAAI,CAAC,YAAY,EAAE,CAAC;gBAClB,OAAO,IAAI,CAAC;YACd,CAAC;YACD,OAAO,kBAAkB,CAAC,YAAY,CAAC,CAAC;QAC1C,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,WAA8B;YACvC,MAAM,IAAI,GAAG,gBAAgB,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;YACjD,MAAM,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAChD,MAAM,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;QAC1F,CAAC;QACD,KAAK,CAAC,KAAK;YACT,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAClC,CAAC;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"credential-store.js","sourceRoot":"","sources":["../../src/auth/credential-store.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,4 @@
1
1
  import { OAuth2Client, type Credentials } from "google-auth-library";
2
- export declare const GEMINI_CLI_OAUTH_CLIENT_ID: string;
3
- export declare const GEMINI_CLI_OAUTH_CLIENT_SECRET: string;
4
2
  export declare const GEMINI_CLI_OAUTH_REDIRECT_URI = "https://codeassist.google.com/authcode";
5
3
  export declare const GEMINI_CLI_OAUTH_SCOPE: readonly ["https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/userinfo.profile"];
6
4
  export type ManualOAuthRequest = {
@@ -1,29 +1,136 @@
1
+ import { execFileSync } from "node:child_process";
1
2
  import { randomBytes } from "node:crypto";
2
- import { CodeChallengeMethod, OAuth2Client } from "google-auth-library";
3
- export const GEMINI_CLI_OAUTH_CLIENT_ID = process.env.GEMINI_CLI_OAUTH_CLIENT_ID ?? "replace-with-google-oauth-client-id";
4
- export const GEMINI_CLI_OAUTH_CLIENT_SECRET = process.env.GEMINI_CLI_OAUTH_CLIENT_SECRET ?? "replace-with-google-oauth-client-secret";
3
+ import { existsSync, readFileSync, realpathSync } from "node:fs";
4
+ import path from "node:path";
5
+ import { OAuth2Client, CodeChallengeMethod } from "google-auth-library";
6
+ const GEMINI_OAUTH_SOURCE_RELATIVE_PATHS = [
7
+ "node_modules/@google/gemini-cli/node_modules/@google/gemini-cli-core/dist/src/code_assist/oauth2.js",
8
+ "lib/node_modules/@google/gemini-cli/node_modules/@google/gemini-cli-core/dist/src/code_assist/oauth2.js",
9
+ "@google/gemini-cli/node_modules/@google/gemini-cli-core/dist/src/code_assist/oauth2.js",
10
+ "@google/gemini-cli-core/dist/src/code_assist/oauth2.js"
11
+ ];
5
12
  export const GEMINI_CLI_OAUTH_REDIRECT_URI = "https://codeassist.google.com/authcode";
6
13
  export const GEMINI_CLI_OAUTH_SCOPE = [
7
14
  "https://www.googleapis.com/auth/cloud-platform",
8
15
  "https://www.googleapis.com/auth/userinfo.email",
9
16
  "https://www.googleapis.com/auth/userinfo.profile"
10
17
  ];
11
- function isPlaceholder(value) {
12
- return value.startsWith("replace-with-");
18
+ const GEMINI_CLI_OAUTH_PROMPT = "consent select_account";
19
+ let discoveredClientConfig;
20
+ function readConfigFromSourceFile(filePath) {
21
+ if (!existsSync(filePath)) {
22
+ return null;
23
+ }
24
+ let source = "";
25
+ try {
26
+ source = readFileSync(filePath, "utf8");
27
+ }
28
+ catch {
29
+ return null;
30
+ }
31
+ const idMatch = source.match(/const OAUTH_CLIENT_ID = ['"]([^'"]+)['"]/);
32
+ if (!idMatch?.[1]) {
33
+ return null;
34
+ }
35
+ const secretMatch = source.match(/const OAUTH_CLIENT_SECRET = ['"]([^'"]+)['"]/);
36
+ return {
37
+ clientId: idMatch[1],
38
+ clientSecret: secretMatch?.[1]
39
+ };
40
+ }
41
+ function findConfigInDirectory(baseDir) {
42
+ for (const relativePath of GEMINI_OAUTH_SOURCE_RELATIVE_PATHS) {
43
+ const config = readConfigFromSourceFile(path.join(baseDir, relativePath));
44
+ if (config) {
45
+ return config;
46
+ }
47
+ }
48
+ return null;
49
+ }
50
+ function discoverFromGeminiBinary() {
51
+ let binaryPath = process.env.GEMINI_CLI_BIN_PATH?.trim();
52
+ if (!binaryPath) {
53
+ try {
54
+ binaryPath = execFileSync("which", ["gemini"], { encoding: "utf8" }).trim();
55
+ }
56
+ catch {
57
+ return null;
58
+ }
59
+ }
60
+ if (!binaryPath) {
61
+ return null;
62
+ }
63
+ let resolved = binaryPath;
64
+ try {
65
+ resolved = realpathSync(binaryPath);
66
+ }
67
+ catch { }
68
+ let current = path.dirname(resolved);
69
+ for (let i = 0; i < 10; i += 1) {
70
+ const config = findConfigInDirectory(current);
71
+ if (config) {
72
+ return config;
73
+ }
74
+ const parent = path.dirname(current);
75
+ if (parent === current) {
76
+ break;
77
+ }
78
+ current = parent;
79
+ }
80
+ return null;
81
+ }
82
+ function discoverFromGlobalNpmRoot() {
83
+ try {
84
+ const root = execFileSync("npm", ["root", "-g"], { encoding: "utf8" }).trim();
85
+ if (!root) {
86
+ return null;
87
+ }
88
+ return findConfigInDirectory(root);
89
+ }
90
+ catch {
91
+ return null;
92
+ }
93
+ }
94
+ function discoverDefaultClientConfig() {
95
+ if (process.env.GEMINI_CLI_OAUTH_AUTO_DISCOVERY === "0") {
96
+ return null;
97
+ }
98
+ if (discoveredClientConfig !== undefined) {
99
+ return discoveredClientConfig;
100
+ }
101
+ const sourcePath = process.env.GEMINI_CLI_OAUTH_SOURCE_PATH?.trim();
102
+ if (sourcePath) {
103
+ discoveredClientConfig = readConfigFromSourceFile(sourcePath);
104
+ return discoveredClientConfig;
105
+ }
106
+ discoveredClientConfig = discoverFromGeminiBinary() ?? discoverFromGlobalNpmRoot() ?? null;
107
+ return discoveredClientConfig;
108
+ }
109
+ function resolveClientId() {
110
+ const envClientId = process.env.GEMINI_CLI_OAUTH_CLIENT_ID?.trim();
111
+ if (envClientId) {
112
+ return envClientId;
113
+ }
114
+ return discoverDefaultClientConfig()?.clientId;
115
+ }
116
+ function resolveClientSecret() {
117
+ const envClientSecret = process.env.GEMINI_CLI_OAUTH_CLIENT_SECRET?.trim();
118
+ if (envClientSecret) {
119
+ return envClientSecret;
120
+ }
121
+ return discoverDefaultClientConfig()?.clientSecret;
13
122
  }
14
123
  export function hasConfiguredOAuthClient() {
15
- return GEMINI_CLI_OAUTH_CLIENT_ID.length > 0
16
- && GEMINI_CLI_OAUTH_CLIENT_SECRET.length > 0
17
- && !isPlaceholder(GEMINI_CLI_OAUTH_CLIENT_ID)
18
- && !isPlaceholder(GEMINI_CLI_OAUTH_CLIENT_SECRET);
124
+ return Boolean(resolveClientId());
19
125
  }
20
126
  export function createOAuthClient() {
21
- if (!hasConfiguredOAuthClient()) {
22
- throw new Error("OAuth client is not configured. Set GEMINI_CLI_OAUTH_CLIENT_ID and GEMINI_CLI_OAUTH_CLIENT_SECRET.");
127
+ const clientId = resolveClientId();
128
+ if (!clientId) {
129
+ throw new Error("OAuth client is not configured. Set GEMINI_CLI_OAUTH_CLIENT_ID or install Gemini CLI.");
23
130
  }
24
131
  return new OAuth2Client({
25
- clientId: GEMINI_CLI_OAUTH_CLIENT_ID,
26
- clientSecret: GEMINI_CLI_OAUTH_CLIENT_SECRET
132
+ clientId,
133
+ clientSecret: resolveClientSecret()
27
134
  });
28
135
  }
29
136
  export async function buildManualOAuthRequest() {
@@ -33,7 +140,7 @@ export async function buildManualOAuthRequest() {
33
140
  const authUrl = client.generateAuthUrl({
34
141
  redirect_uri: GEMINI_CLI_OAUTH_REDIRECT_URI,
35
142
  access_type: "offline",
36
- prompt: "consent",
143
+ prompt: GEMINI_CLI_OAUTH_PROMPT,
37
144
  scope: [...GEMINI_CLI_OAUTH_SCOPE],
38
145
  code_challenge_method: CodeChallengeMethod.S256,
39
146
  code_challenge: verifier.codeChallenge,
@@ -53,7 +160,7 @@ export function buildWebOAuthRequest(port) {
53
160
  const authUrl = client.generateAuthUrl({
54
161
  redirect_uri: redirectUri,
55
162
  access_type: "offline",
56
- prompt: "consent",
163
+ prompt: GEMINI_CLI_OAUTH_PROMPT,
57
164
  scope: [...GEMINI_CLI_OAUTH_SCOPE],
58
165
  state
59
166
  });