opencode-gemini-cli-oauth 1.1.22 → 1.2.3

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 (53) hide show
  1. package/dist/constants.d.ts +9 -20
  2. package/dist/constants.d.ts.map +1 -1
  3. package/dist/constants.js +19 -36
  4. package/dist/constants.js.map +1 -1
  5. package/dist/index.d.ts +4 -10
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +4 -14
  8. package/dist/index.js.map +1 -1
  9. package/dist/oauth.d.ts +27 -0
  10. package/dist/oauth.d.ts.map +1 -0
  11. package/dist/oauth.js +170 -0
  12. package/dist/oauth.js.map +1 -0
  13. package/dist/plugin.d.ts +11 -28
  14. package/dist/plugin.d.ts.map +1 -1
  15. package/dist/plugin.js +111 -115
  16. package/dist/plugin.js.map +1 -1
  17. package/dist/types.d.ts +5 -44
  18. package/dist/types.d.ts.map +1 -1
  19. package/dist/types.js +1 -2
  20. package/dist/types.js.map +1 -1
  21. package/package.json +24 -21
  22. package/dist/auth/account-manager.d.ts +0 -16
  23. package/dist/auth/account-manager.d.ts.map +0 -1
  24. package/dist/auth/account-manager.js +0 -66
  25. package/dist/auth/account-manager.js.map +0 -1
  26. package/dist/auth/oauth.d.ts +0 -27
  27. package/dist/auth/oauth.d.ts.map +0 -1
  28. package/dist/auth/oauth.js +0 -92
  29. package/dist/auth/oauth.js.map +0 -1
  30. package/dist/cli/setup.d.ts +0 -3
  31. package/dist/cli/setup.d.ts.map +0 -1
  32. package/dist/cli/setup.js +0 -272
  33. package/dist/cli/setup.js.map +0 -1
  34. package/dist/index-minimal.d.ts +0 -2
  35. package/dist/index-minimal.d.ts.map +0 -1
  36. package/dist/index-minimal.js +0 -7
  37. package/dist/index-minimal.js.map +0 -1
  38. package/dist/index-simple.d.ts +0 -5
  39. package/dist/index-simple.d.ts.map +0 -1
  40. package/dist/index-simple.js +0 -10
  41. package/dist/index-simple.js.map +0 -1
  42. package/dist/plugin-minimal.d.ts +0 -21
  43. package/dist/plugin-minimal.d.ts.map +0 -1
  44. package/dist/plugin-minimal.js +0 -31
  45. package/dist/plugin-minimal.js.map +0 -1
  46. package/dist/plugin-simple.d.ts +0 -28
  47. package/dist/plugin-simple.d.ts.map +0 -1
  48. package/dist/plugin-simple.js +0 -124
  49. package/dist/plugin-simple.js.map +0 -1
  50. package/dist/storage/storage.d.ts +0 -56
  51. package/dist/storage/storage.d.ts.map +0 -1
  52. package/dist/storage/storage.js +0 -144
  53. package/dist/storage/storage.js.map +0 -1
@@ -24,32 +24,21 @@ export declare const GEMINI_DIR: string;
24
24
  * OAuth credentials file path (compatible with Gemini CLI)
25
25
  */
26
26
  export declare const OAUTH_CREDS_PATH: string;
27
- /**
28
- * Google accounts file path (for multi-account support)
29
- */
30
- export declare const GOOGLE_ACCOUNTS_PATH: string;
31
- /**
32
- * Plugin storage directory
33
- */
34
- export declare const PLUGIN_STORAGE_DIR: string;
35
- /**
36
- * Account pool storage file
37
- */
38
- export declare const ACCOUNT_POOL_PATH: string;
39
- /**
40
- * Generative Language API endpoint
41
- */
42
- export declare const GEMINI_API_BASE = "https://generativelanguage.googleapis.com";
43
27
  /**
44
28
  * Token expiry buffer (refresh 5 minutes before expiry)
45
29
  */
46
30
  export declare const TOKEN_EXPIRY_BUFFER_MS: number;
47
31
  /**
48
- * Rate limit retry delay (milliseconds)
32
+ * Google token endpoint
33
+ */
34
+ export declare const GOOGLE_TOKEN_ENDPOINT = "https://oauth2.googleapis.com/token";
35
+ /**
36
+ * Google userinfo endpoint
49
37
  */
50
- export declare const RATE_LIMIT_RETRY_DELAY_MS = 2000;
38
+ export declare const GOOGLE_USERINFO_ENDPOINT = "https://www.googleapis.com/oauth2/v2/userinfo";
51
39
  /**
52
- * Maximum retry attempts for token refresh
40
+ * Provider ID for this plugin
41
+ * Use the built-in "google" provider so we hook into existing Google/Gemini support
53
42
  */
54
- export declare const MAX_REFRESH_RETRIES = 3;
43
+ export declare const PROVIDER_ID = "google";
55
44
  //# sourceMappingURL=constants.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,6EAA6E,CAAC;AAC1G,eAAO,MAAM,mBAAmB,wCAAwC,CAAC;AAEzE;;GAEG;AACH,eAAO,MAAM,YAAY,UAIxB,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,UAAU,QAAqC,CAAC;AAE7D;;GAEG;AACH,eAAO,MAAM,gBAAgB,QAA4C,CAAC;AAE1E;;GAEG;AACH,eAAO,MAAM,oBAAoB,QAAgD,CAAC;AAElF;;GAEG;AACH,eAAO,MAAM,kBAAkB,QAA2C,CAAC;AAE3E;;GAEG;AACH,eAAO,MAAM,iBAAiB,QAAqD,CAAC;AAEpF;;GAEG;AACH,eAAO,MAAM,eAAe,8CAA8C,CAAC;AAE3E;;GAEG;AACH,eAAO,MAAM,sBAAsB,QAAgB,CAAC;AAEpD;;GAEG;AACH,eAAO,MAAM,yBAAyB,OAAO,CAAC;AAE9C;;GAEG;AACH,eAAO,MAAM,mBAAmB,IAAI,CAAC"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,6EAA6E,CAAC;AAC1G,eAAO,MAAM,mBAAmB,wCAAwC,CAAC;AAEzE;;GAEG;AACH,eAAO,MAAM,YAAY,UAIxB,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,UAAU,QAAqC,CAAC;AAE7D;;GAEG;AACH,eAAO,MAAM,gBAAgB,QAA4C,CAAC;AAE1E;;GAEG;AACH,eAAO,MAAM,sBAAsB,QAAgB,CAAC;AAEpD;;GAEG;AACH,eAAO,MAAM,qBAAqB,wCAAwC,CAAC;AAE3E;;GAEG;AACH,eAAO,MAAM,wBAAwB,kDAAkD,CAAC;AAExF;;;GAGG;AACH,eAAO,MAAM,WAAW,WAAW,CAAC"}
package/dist/constants.js CHANGED
@@ -1,16 +1,10 @@
1
- "use strict";
2
1
  /**
3
2
  * @license
4
3
  * Copyright 2025 Yusuf
5
4
  * SPDX-License-Identifier: MIT
6
5
  */
7
- var __importDefault = (this && this.__importDefault) || function (mod) {
8
- return (mod && mod.__esModule) ? mod : { "default": mod };
9
- };
10
- Object.defineProperty(exports, "__esModule", { value: true });
11
- exports.MAX_REFRESH_RETRIES = exports.RATE_LIMIT_RETRY_DELAY_MS = exports.TOKEN_EXPIRY_BUFFER_MS = exports.GEMINI_API_BASE = exports.ACCOUNT_POOL_PATH = exports.PLUGIN_STORAGE_DIR = exports.GOOGLE_ACCOUNTS_PATH = exports.OAUTH_CREDS_PATH = exports.GEMINI_DIR = exports.OAUTH_SCOPES = exports.OAUTH_CLIENT_SECRET = exports.OAUTH_CLIENT_ID = void 0;
12
- const node_os_1 = __importDefault(require("node:os"));
13
- const node_path_1 = __importDefault(require("node:path"));
6
+ import os from "node:os";
7
+ import path from "node:path";
14
8
  /**
15
9
  * OAuth2 Client credentials from Gemini CLI
16
10
  * Source: @google/gemini-cli-core/dist/src/code_assist/oauth2.js
@@ -18,50 +12,39 @@ const node_path_1 = __importDefault(require("node:path"));
18
12
  * These credentials are safe to embed as this is an "installed application"
19
13
  * per Google OAuth2 guidelines: https://developers.google.com/identity/protocols/oauth2#installed
20
14
  */
21
- exports.OAUTH_CLIENT_ID = '681255809395-oo8ft2oprdrnp9e3aqf6av3hmdib135j.apps.googleusercontent.com';
22
- exports.OAUTH_CLIENT_SECRET = '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';
15
+ export const OAUTH_CLIENT_ID = "681255809395-oo8ft2oprdrnp9e3aqf6av3hmdib135j.apps.googleusercontent.com";
16
+ export const OAUTH_CLIENT_SECRET = "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";
23
17
  /**
24
18
  * OAuth scopes required for Gemini API access
25
19
  */
26
- exports.OAUTH_SCOPES = [
27
- 'https://www.googleapis.com/auth/cloud-platform',
28
- 'https://www.googleapis.com/auth/userinfo.email',
29
- 'https://www.googleapis.com/auth/userinfo.profile',
20
+ export const OAUTH_SCOPES = [
21
+ "https://www.googleapis.com/auth/cloud-platform",
22
+ "https://www.googleapis.com/auth/userinfo.email",
23
+ "https://www.googleapis.com/auth/userinfo.profile",
30
24
  ];
31
25
  /**
32
26
  * Gemini CLI storage directory
33
27
  */
34
- exports.GEMINI_DIR = node_path_1.default.join(node_os_1.default.homedir(), '.gemini');
28
+ export const GEMINI_DIR = path.join(os.homedir(), ".gemini");
35
29
  /**
36
30
  * OAuth credentials file path (compatible with Gemini CLI)
37
31
  */
38
- exports.OAUTH_CREDS_PATH = node_path_1.default.join(exports.GEMINI_DIR, 'oauth_creds.json');
32
+ export const OAUTH_CREDS_PATH = path.join(GEMINI_DIR, "oauth_creds.json");
39
33
  /**
40
- * Google accounts file path (for multi-account support)
41
- */
42
- exports.GOOGLE_ACCOUNTS_PATH = node_path_1.default.join(exports.GEMINI_DIR, 'google_accounts.json');
43
- /**
44
- * Plugin storage directory
45
- */
46
- exports.PLUGIN_STORAGE_DIR = node_path_1.default.join(exports.GEMINI_DIR, 'opencode-plugin');
47
- /**
48
- * Account pool storage file
49
- */
50
- exports.ACCOUNT_POOL_PATH = node_path_1.default.join(exports.PLUGIN_STORAGE_DIR, 'account_pool.json');
51
- /**
52
- * Generative Language API endpoint
34
+ * Token expiry buffer (refresh 5 minutes before expiry)
53
35
  */
54
- exports.GEMINI_API_BASE = 'https://generativelanguage.googleapis.com';
36
+ export const TOKEN_EXPIRY_BUFFER_MS = 5 * 60 * 1000;
55
37
  /**
56
- * Token expiry buffer (refresh 5 minutes before expiry)
38
+ * Google token endpoint
57
39
  */
58
- exports.TOKEN_EXPIRY_BUFFER_MS = 5 * 60 * 1000;
40
+ export const GOOGLE_TOKEN_ENDPOINT = "https://oauth2.googleapis.com/token";
59
41
  /**
60
- * Rate limit retry delay (milliseconds)
42
+ * Google userinfo endpoint
61
43
  */
62
- exports.RATE_LIMIT_RETRY_DELAY_MS = 2000;
44
+ export const GOOGLE_USERINFO_ENDPOINT = "https://www.googleapis.com/oauth2/v2/userinfo";
63
45
  /**
64
- * Maximum retry attempts for token refresh
46
+ * Provider ID for this plugin
47
+ * Use the built-in "google" provider so we hook into existing Google/Gemini support
65
48
  */
66
- exports.MAX_REFRESH_RETRIES = 3;
49
+ export const PROVIDER_ID = "google";
67
50
  //# sourceMappingURL=constants.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;;;;AAEH,sDAAyB;AACzB,0DAA6B;AAE7B;;;;;;GAMG;AACU,QAAA,eAAe,GAAG,0EAA0E,CAAC;AAC7F,QAAA,mBAAmB,GAAG,qCAAqC,CAAC;AAEzE;;GAEG;AACU,QAAA,YAAY,GAAG;IAC1B,gDAAgD;IAChD,gDAAgD;IAChD,kDAAkD;CACnD,CAAC;AAEF;;GAEG;AACU,QAAA,UAAU,GAAG,mBAAI,CAAC,IAAI,CAAC,iBAAE,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;AAE7D;;GAEG;AACU,QAAA,gBAAgB,GAAG,mBAAI,CAAC,IAAI,CAAC,kBAAU,EAAE,kBAAkB,CAAC,CAAC;AAE1E;;GAEG;AACU,QAAA,oBAAoB,GAAG,mBAAI,CAAC,IAAI,CAAC,kBAAU,EAAE,sBAAsB,CAAC,CAAC;AAElF;;GAEG;AACU,QAAA,kBAAkB,GAAG,mBAAI,CAAC,IAAI,CAAC,kBAAU,EAAE,iBAAiB,CAAC,CAAC;AAE3E;;GAEG;AACU,QAAA,iBAAiB,GAAG,mBAAI,CAAC,IAAI,CAAC,0BAAkB,EAAE,mBAAmB,CAAC,CAAC;AAEpF;;GAEG;AACU,QAAA,eAAe,GAAG,2CAA2C,CAAC;AAE3E;;GAEG;AACU,QAAA,sBAAsB,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AAEpD;;GAEG;AACU,QAAA,yBAAyB,GAAG,IAAI,CAAC;AAE9C;;GAEG;AACU,QAAA,mBAAmB,GAAG,CAAC,CAAC"}
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,0EAA0E,CAAC;AAC1G,MAAM,CAAC,MAAM,mBAAmB,GAAG,qCAAqC,CAAC;AAEzE;;GAEG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,gDAAgD;IAChD,gDAAgD;IAChD,kDAAkD;CACnD,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;AAE7D;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,kBAAkB,CAAC,CAAC;AAE1E;;GAEG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AAEpD;;GAEG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,qCAAqC,CAAC;AAE3E;;GAEG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,+CAA+C,CAAC;AAExF;;;GAGG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,QAAQ,CAAC"}
package/dist/index.d.ts CHANGED
@@ -2,17 +2,11 @@
2
2
  * @license
3
3
  * Copyright 2025 Yusuf
4
4
  * SPDX-License-Identifier: MIT
5
- */
6
- /**
5
+ *
7
6
  * OpenCode Gemini CLI OAuth Plugin
8
7
  *
9
- * Main entry point for the plugin
10
- */
11
- /**
12
- * @license
13
- * Copyright 2025 Yusuf
14
- * SPDX-License-Identifier: MIT
8
+ * Main entry point - exports the plugin for OpenCode
15
9
  */
16
- import loadPlugin from './plugin';
17
- export = loadPlugin;
10
+ export { GeminiCliOAuthPlugin } from "./plugin.js";
11
+ export { default } from "./plugin.js";
18
12
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;GAIG;AAEH;;;;GAIG;AAEH,OAAO,UAAU,MAAM,UAAU,CAAC;AAGlC,SAAS,UAAU,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC"}
package/dist/index.js CHANGED
@@ -1,22 +1,12 @@
1
- "use strict";
2
1
  /**
3
2
  * @license
4
3
  * Copyright 2025 Yusuf
5
4
  * SPDX-License-Identifier: MIT
6
- */
7
- var __importDefault = (this && this.__importDefault) || function (mod) {
8
- return (mod && mod.__esModule) ? mod : { "default": mod };
9
- };
10
- /**
5
+ *
11
6
  * OpenCode Gemini CLI OAuth Plugin
12
7
  *
13
- * Main entry point for the plugin
14
- */
15
- /**
16
- * @license
17
- * Copyright 2025 Yusuf
18
- * SPDX-License-Identifier: MIT
8
+ * Main entry point - exports the plugin for OpenCode
19
9
  */
20
- const plugin_1 = __importDefault(require("./plugin"));
21
- module.exports = plugin_1.default;
10
+ export { GeminiCliOAuthPlugin } from "./plugin.js";
11
+ export { default } from "./plugin.js";
22
12
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;;AAEH;;;;GAIG;AAEH;;;;GAIG;AAEH,sDAAkC;AAGlC,iBAAS,gBAAU,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Yusuf
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ import type { UserInfo } from "./types.js";
7
+ /**
8
+ * Get a valid access token, refreshing if necessary
9
+ */
10
+ export declare function getAccessToken(): Promise<string>;
11
+ /**
12
+ * Verify credentials are valid
13
+ */
14
+ export declare function verifyCredentials(): Promise<boolean>;
15
+ /**
16
+ * Get user info from Google
17
+ */
18
+ export declare function getUserInfo(): Promise<UserInfo>;
19
+ /**
20
+ * Check if credentials exist
21
+ */
22
+ export declare function hasCredentials(): Promise<boolean>;
23
+ /**
24
+ * Clear cached credentials (force re-read from disk)
25
+ */
26
+ export declare function clearCache(): void;
27
+ //# sourceMappingURL=oauth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../src/oauth.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAYH,OAAO,KAAK,EAAwC,QAAQ,EAAE,MAAM,YAAY,CAAC;AAiGjF;;GAEG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,CAqCtD;AAED;;GAEG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,OAAO,CAAC,CAY1D;AAED;;GAEG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC,QAAQ,CAAC,CAkBrD;AAED;;GAEG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC,CAGvD;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,IAAI,CAIjC"}
package/dist/oauth.js ADDED
@@ -0,0 +1,170 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Yusuf
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ import { readFile, writeFile, mkdir } from "node:fs/promises";
7
+ import { OAUTH_CREDS_PATH, GEMINI_DIR, OAUTH_CLIENT_ID, OAUTH_CLIENT_SECRET, TOKEN_EXPIRY_BUFFER_MS, GOOGLE_TOKEN_ENDPOINT, GOOGLE_USERINFO_ENDPOINT, } from "./constants.js";
8
+ // In-memory cache for credentials and access token
9
+ let cachedCredentials = null;
10
+ let cachedAccessToken = null;
11
+ let cachedTokenExpiry = 0;
12
+ /**
13
+ * Read OAuth credentials from Gemini CLI storage
14
+ */
15
+ async function readOAuthCredentials() {
16
+ try {
17
+ const data = await readFile(OAUTH_CREDS_PATH, "utf-8");
18
+ cachedCredentials = JSON.parse(data);
19
+ return cachedCredentials;
20
+ }
21
+ catch (error) {
22
+ if (error.code === "ENOENT") {
23
+ return null;
24
+ }
25
+ throw error;
26
+ }
27
+ }
28
+ /**
29
+ * Write OAuth credentials to Gemini CLI storage
30
+ */
31
+ async function writeOAuthCredentials(credentials) {
32
+ await mkdir(GEMINI_DIR, { recursive: true });
33
+ await writeFile(OAUTH_CREDS_PATH, JSON.stringify(credentials, null, 2), {
34
+ mode: 0o600, // Secure file permissions
35
+ });
36
+ cachedCredentials = credentials;
37
+ }
38
+ /**
39
+ * Refresh access token using refresh token
40
+ */
41
+ async function refreshAccessToken(refreshToken) {
42
+ try {
43
+ const response = await fetch(GOOGLE_TOKEN_ENDPOINT, {
44
+ method: "POST",
45
+ headers: {
46
+ "Content-Type": "application/x-www-form-urlencoded",
47
+ },
48
+ body: new URLSearchParams({
49
+ grant_type: "refresh_token",
50
+ refresh_token: refreshToken,
51
+ client_id: OAUTH_CLIENT_ID,
52
+ client_secret: OAUTH_CLIENT_SECRET,
53
+ }),
54
+ });
55
+ if (!response.ok) {
56
+ const errorText = await response.text();
57
+ return {
58
+ success: false,
59
+ error: `Token refresh failed: ${response.status} - ${errorText}`,
60
+ };
61
+ }
62
+ const data = (await response.json());
63
+ const expiryDate = Date.now() + data.expires_in * 1000;
64
+ // Update cached credentials
65
+ if (cachedCredentials) {
66
+ const updatedCreds = {
67
+ ...cachedCredentials,
68
+ access_token: data.access_token,
69
+ expiry_date: expiryDate,
70
+ token_type: data.token_type || "Bearer",
71
+ };
72
+ await writeOAuthCredentials(updatedCreds);
73
+ }
74
+ // Update in-memory cache
75
+ cachedAccessToken = data.access_token;
76
+ cachedTokenExpiry = expiryDate;
77
+ return {
78
+ success: true,
79
+ accessToken: data.access_token,
80
+ expiryDate,
81
+ };
82
+ }
83
+ catch (error) {
84
+ return {
85
+ success: false,
86
+ error: error instanceof Error ? error.message : String(error),
87
+ };
88
+ }
89
+ }
90
+ /**
91
+ * Get a valid access token, refreshing if necessary
92
+ */
93
+ export async function getAccessToken() {
94
+ const now = Date.now();
95
+ // Check in-memory cache first
96
+ if (cachedAccessToken && cachedTokenExpiry - now > TOKEN_EXPIRY_BUFFER_MS) {
97
+ return cachedAccessToken;
98
+ }
99
+ // Read credentials from disk
100
+ const credentials = await readOAuthCredentials();
101
+ if (!credentials) {
102
+ throw new Error("No OAuth credentials found. Please authenticate using Gemini CLI: gemini auth login");
103
+ }
104
+ const expiryTime = credentials.expiry_date || 0;
105
+ const needsRefresh = expiryTime - now < TOKEN_EXPIRY_BUFFER_MS;
106
+ if (needsRefresh) {
107
+ const refreshResult = await refreshAccessToken(credentials.refresh_token);
108
+ if (!refreshResult.success) {
109
+ throw new Error(`Failed to refresh access token: ${refreshResult.error}. Please re-authenticate with: gemini auth login`);
110
+ }
111
+ return refreshResult.accessToken;
112
+ }
113
+ // Update in-memory cache
114
+ cachedAccessToken = credentials.access_token;
115
+ cachedTokenExpiry = expiryTime;
116
+ return credentials.access_token;
117
+ }
118
+ /**
119
+ * Verify credentials are valid
120
+ */
121
+ export async function verifyCredentials() {
122
+ try {
123
+ const token = await getAccessToken();
124
+ const response = await fetch(GOOGLE_USERINFO_ENDPOINT, {
125
+ headers: {
126
+ Authorization: `Bearer ${token}`,
127
+ },
128
+ });
129
+ return response.ok;
130
+ }
131
+ catch {
132
+ return false;
133
+ }
134
+ }
135
+ /**
136
+ * Get user info from Google
137
+ */
138
+ export async function getUserInfo() {
139
+ const token = await getAccessToken();
140
+ const response = await fetch(GOOGLE_USERINFO_ENDPOINT, {
141
+ headers: {
142
+ Authorization: `Bearer ${token}`,
143
+ },
144
+ });
145
+ if (!response.ok) {
146
+ throw new Error(`Failed to get user info: ${response.status}`);
147
+ }
148
+ const data = (await response.json());
149
+ return {
150
+ email: data.email || "unknown",
151
+ name: data.name,
152
+ picture: data.picture,
153
+ };
154
+ }
155
+ /**
156
+ * Check if credentials exist
157
+ */
158
+ export async function hasCredentials() {
159
+ const credentials = await readOAuthCredentials();
160
+ return credentials !== null && !!credentials.refresh_token;
161
+ }
162
+ /**
163
+ * Clear cached credentials (force re-read from disk)
164
+ */
165
+ export function clearCache() {
166
+ cachedCredentials = null;
167
+ cachedAccessToken = null;
168
+ cachedTokenExpiry = 0;
169
+ }
170
+ //# sourceMappingURL=oauth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth.js","sourceRoot":"","sources":["../src/oauth.ts"],"names":[],"mappings":"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"}
package/dist/plugin.d.ts CHANGED
@@ -2,33 +2,16 @@
2
2
  * @license
3
3
  * Copyright 2025 Yusuf
4
4
  * SPDX-License-Identifier: MIT
5
+ *
6
+ * OpenCode Gemini CLI OAuth Plugin
7
+ *
8
+ * This plugin intercepts requests to Google's Generative AI API
9
+ * and injects the OAuth token from the Gemini CLI.
5
10
  */
6
- import type { PluginContext } from './types';
7
- export default function loadPlugin(context: PluginContext): Promise<{
8
- auth: {
9
- provider: string;
10
- loader: (getAuth: any, provider: string) => Promise<{
11
- apiKey: string;
12
- fetch: (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
13
- }>;
14
- methods: {
15
- label: string;
16
- type: string;
17
- authorize: () => Promise<{
18
- url: string;
19
- instructions: string;
20
- method: string;
21
- callback: () => Promise<{
22
- type: string;
23
- email: string;
24
- error?: undefined;
25
- } | {
26
- type: string;
27
- error: string;
28
- email?: undefined;
29
- }>;
30
- }>;
31
- }[];
32
- };
33
- }>;
11
+ import type { Plugin } from "@opencode-ai/plugin";
12
+ /**
13
+ * Create the Gemini CLI OAuth plugin
14
+ */
15
+ export declare const GeminiCliOAuthPlugin: Plugin;
16
+ export default GeminiCliOAuthPlugin;
34
17
  //# sourceMappingURL=plugin.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAe7C,wBAA8B,UAAU,CAAC,OAAO,EAAE,aAAa;;;0BAiDjC,GAAG,YAAY,MAAM;;2BAvCV,WAAW,GAAG,GAAG,SAAS,WAAW,KAAG,OAAO,CAAC,QAAQ,CAAC;;;;;;;;;;;;;;;;;;;;;GAuEjG"}
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAsB,MAAM,qBAAqB,CAAC;AAUtE;;GAEG;AACH,eAAO,MAAM,oBAAoB,EAAE,MAuIlC,CAAC;AAEF,eAAe,oBAAoB,CAAC"}