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.
- package/dist/constants.d.ts +9 -20
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +19 -36
- package/dist/constants.js.map +1 -1
- package/dist/index.d.ts +4 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -14
- package/dist/index.js.map +1 -1
- package/dist/oauth.d.ts +27 -0
- package/dist/oauth.d.ts.map +1 -0
- package/dist/oauth.js +170 -0
- package/dist/oauth.js.map +1 -0
- package/dist/plugin.d.ts +11 -28
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +111 -115
- package/dist/plugin.js.map +1 -1
- package/dist/types.d.ts +5 -44
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -2
- package/dist/types.js.map +1 -1
- package/package.json +24 -21
- package/dist/auth/account-manager.d.ts +0 -16
- package/dist/auth/account-manager.d.ts.map +0 -1
- package/dist/auth/account-manager.js +0 -66
- package/dist/auth/account-manager.js.map +0 -1
- package/dist/auth/oauth.d.ts +0 -27
- package/dist/auth/oauth.d.ts.map +0 -1
- package/dist/auth/oauth.js +0 -92
- package/dist/auth/oauth.js.map +0 -1
- package/dist/cli/setup.d.ts +0 -3
- package/dist/cli/setup.d.ts.map +0 -1
- package/dist/cli/setup.js +0 -272
- package/dist/cli/setup.js.map +0 -1
- package/dist/index-minimal.d.ts +0 -2
- package/dist/index-minimal.d.ts.map +0 -1
- package/dist/index-minimal.js +0 -7
- package/dist/index-minimal.js.map +0 -1
- package/dist/index-simple.d.ts +0 -5
- package/dist/index-simple.d.ts.map +0 -1
- package/dist/index-simple.js +0 -10
- package/dist/index-simple.js.map +0 -1
- package/dist/plugin-minimal.d.ts +0 -21
- package/dist/plugin-minimal.d.ts.map +0 -1
- package/dist/plugin-minimal.js +0 -31
- package/dist/plugin-minimal.js.map +0 -1
- package/dist/plugin-simple.d.ts +0 -28
- package/dist/plugin-simple.d.ts.map +0 -1
- package/dist/plugin-simple.js +0 -124
- package/dist/plugin-simple.js.map +0 -1
- package/dist/storage/storage.d.ts +0 -56
- package/dist/storage/storage.d.ts.map +0 -1
- package/dist/storage/storage.js +0 -144
- package/dist/storage/storage.js.map +0 -1
package/dist/constants.d.ts
CHANGED
|
@@ -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
|
-
*
|
|
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
|
|
38
|
+
export declare const GOOGLE_USERINFO_ENDPOINT = "https://www.googleapis.com/oauth2/v2/userinfo";
|
|
51
39
|
/**
|
|
52
|
-
*
|
|
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
|
|
43
|
+
export declare const PROVIDER_ID = "google";
|
|
55
44
|
//# sourceMappingURL=constants.d.ts.map
|
package/dist/constants.d.ts.map
CHANGED
|
@@ -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,
|
|
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
|
-
|
|
8
|
-
|
|
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
|
-
|
|
22
|
-
|
|
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
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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
|
-
|
|
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
|
-
|
|
32
|
+
export const OAUTH_CREDS_PATH = path.join(GEMINI_DIR, "oauth_creds.json");
|
|
39
33
|
/**
|
|
40
|
-
*
|
|
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
|
-
|
|
36
|
+
export const TOKEN_EXPIRY_BUFFER_MS = 5 * 60 * 1000;
|
|
55
37
|
/**
|
|
56
|
-
*
|
|
38
|
+
* Google token endpoint
|
|
57
39
|
*/
|
|
58
|
-
|
|
40
|
+
export const GOOGLE_TOKEN_ENDPOINT = "https://oauth2.googleapis.com/token";
|
|
59
41
|
/**
|
|
60
|
-
*
|
|
42
|
+
* Google userinfo endpoint
|
|
61
43
|
*/
|
|
62
|
-
|
|
44
|
+
export const GOOGLE_USERINFO_ENDPOINT = "https://www.googleapis.com/oauth2/v2/userinfo";
|
|
63
45
|
/**
|
|
64
|
-
*
|
|
46
|
+
* Provider ID for this plugin
|
|
47
|
+
* Use the built-in "google" provider so we hook into existing Google/Gemini support
|
|
65
48
|
*/
|
|
66
|
-
|
|
49
|
+
export const PROVIDER_ID = "google";
|
|
67
50
|
//# sourceMappingURL=constants.js.map
|
package/dist/constants.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"
|
|
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
|
|
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
|
-
|
|
17
|
-
export
|
|
10
|
+
export { GeminiCliOAuthPlugin } from "./plugin.js";
|
|
11
|
+
export { default } from "./plugin.js";
|
|
18
12
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA
|
|
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
|
|
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
|
-
|
|
21
|
-
|
|
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":"
|
|
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"}
|
package/dist/oauth.d.ts
ADDED
|
@@ -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 {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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
|
package/dist/plugin.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA
|
|
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"}
|