@google/gemini-cli 0.65.0-preview.0 → 0.66.0-nightly.20261017.ged96faedf
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/README.md +21 -56
- package/bundle/{chunk-NL7ZHGCH.js → chunk-464WBVYM.js} +1 -1
- package/bundle/{chunk-QJK54DSE.js → chunk-5VQUE3OF.js} +1 -1
- package/bundle/{chunk-VF5WQSOE.js → chunk-7ARQMEMX.js} +1 -1
- package/bundle/{chunk-2WVLIJA5.js → chunk-BUG4N6U5.js} +145 -77
- package/bundle/{chunk-F6AJM4WN.js → chunk-DPV3ZEOC.js} +3 -3
- package/bundle/{chunk-GSQEBEGC.js → chunk-ERBSM2HU.js} +3 -3
- package/bundle/{chunk-WTRK3NVX.js → chunk-GEUFOF2X.js} +106 -1500
- package/bundle/{chunk-V2R74WAG.js → chunk-H4U2CWBQ.js} +151 -81
- package/bundle/chunk-HDP6V6JI.js +1956 -0
- package/bundle/{chunk-RPHDSDL6.js → chunk-IDCWFZU3.js} +1 -1
- package/bundle/{chunk-SN7QZKXC.js → chunk-IGOTAEJY.js} +170 -1551
- package/bundle/chunk-J5QPCO3J.js +101859 -0
- package/bundle/{chunk-H2CZXS7F.js → chunk-JY3DYBJT.js} +1 -1
- package/bundle/{chunk-HLOOE7YN.js → chunk-LDGJJCVW.js} +9 -8
- package/bundle/chunk-MH4KAY5W.js +512 -0
- package/bundle/{chunk-LLE5Z636.js → chunk-NAPT3FAL.js} +106 -1500
- package/bundle/chunk-NOSWGXRT.js +1956 -0
- package/bundle/{chunk-43EXRO7A.js → chunk-NU74STQ5.js} +145 -77
- package/bundle/{chunk-K7NOVQ6G.js → chunk-QCWGLPCO.js} +376 -231
- package/bundle/{chunk-WGL5FJOS.js → chunk-QF3ALSJN.js} +3 -3
- package/bundle/{chunk-K4G5D5ZZ.js → chunk-R4KPURFC.js} +1 -1
- package/bundle/chunk-R6XDLHLP.js +1956 -0
- package/bundle/chunk-R7UPATQC.js +1956 -0
- package/bundle/chunk-RACMC24X.js +118 -0
- package/bundle/{chunk-4JGVVJGK.js → chunk-RE4V6I3G.js} +1 -1
- package/bundle/{chunk-S7BCRBI4.js → chunk-UTTFPWGQ.js} +1 -1
- package/bundle/chunk-VXYA6LA4.js +1571 -0
- package/bundle/chunk-XY2QSBID.js +17603 -0
- package/bundle/{chunk-K7AA35SP.js → chunk-YOI4DS3V.js} +365 -230
- package/bundle/chunk-YP27UYI4.js +154 -0
- package/bundle/{chunk-TP236FKO.js → chunk-YPLMNSM4.js} +8243 -15166
- package/bundle/chunk-ZFQ347ZN.js +402181 -0
- package/bundle/{cleanup-HPADDONA.js → cleanup-6FAZDCL3.js} +2 -2
- package/bundle/{cleanup-JOMSXKMP.js → cleanup-GNZLZG55.js} +2 -2
- package/bundle/{cleanup-LYRJHMMO.js → cleanup-RX3AC5ET.js} +2 -2
- package/bundle/cleanup-WAU2KYGS.js +32 -0
- package/bundle/{core-NCJTYARO.js → core-AGGXDQOT.js} +13 -1
- package/bundle/{devtoolsService-WP2OPVPB.js → devtoolsService-6XOCGTLC.js} +2 -2
- package/bundle/{devtoolsService-JFJBTZ4B.js → devtoolsService-FBTSVQ57.js} +4 -3
- package/bundle/{devtoolsService-HIZA3JGR.js → devtoolsService-UO6ZB72B.js} +2 -2
- package/bundle/devtoolsService-W5QGZ3SW.js +4359 -0
- package/bundle/{dist-GQKLLBDW.js → dist-2ELAEESC.js} +13 -1
- package/bundle/{core-IVQAI4S6.js → dist-2R7C2WHA.js} +13 -1
- package/bundle/dist-PALH7PJS.js +2280 -0
- package/bundle/docs/changelogs/index.md +22 -0
- package/bundle/docs/changelogs/latest.md +64 -54
- package/bundle/docs/changelogs/preview.md +91 -55
- package/bundle/docs/reference/configuration.md +8 -3
- package/bundle/docs/reference/keyboard-shortcuts.md +18 -4
- package/bundle/{gemini-5TUKZVGS.js → gemini-6MH55Y7F.js} +37 -18
- package/bundle/{gemini-7CHJYSHM.js → gemini-DOXUDJDY.js} +37 -18
- package/bundle/{gemini-546WMAHG.js → gemini-OHYXI52N.js} +237 -202
- package/bundle/gemini-OUEDCH4P.js +17970 -0
- package/bundle/gemini.js +14 -15
- package/bundle/{interactiveCli-E3PUPYMZ.js → interactiveCli-7LIKGDTJ.js} +1061 -989
- package/bundle/{interactiveCli-5XIAIY74.js → interactiveCli-EGQYN3KR.js} +1371 -1280
- package/bundle/{interactiveCli-L4PK7YY3.js → interactiveCli-TG7PGV4V.js} +1061 -989
- package/bundle/interactiveCli-YEXCUIFZ.js +35601 -0
- package/bundle/{liteRtServerManager-JCTYJBV5.js → liteRtServerManager-KAPXZ3EU.js} +4 -4
- package/bundle/{liteRtServerManager-JERG6KYC.js → liteRtServerManager-MSJIWMWP.js} +4 -4
- package/bundle/{liteRtServerManager-22ISMNN2.js → liteRtServerManager-PD2N3GLD.js} +4 -4
- package/bundle/liteRtServerManager-X5SCFYXM.js +65 -0
- package/bundle/{oauth2-provider-XRUER2XR.js → oauth2-provider-IUN6Z4IO.js} +1 -1
- package/bundle/{oauth2-provider-477UJQX6.js → oauth2-provider-MKJIQNWP.js} +41 -79
- package/bundle/{oauth2-provider-MKWWBW4K.js → oauth2-provider-RMF7U2UN.js} +1 -1
- package/bundle/oauth2-provider-ZM5GWCNX.js +273 -0
- package/bundle/{start-MVIPJNQ5.js → start-5GIUIER3.js} +6 -6
- package/bundle/{start-RZWSVT55.js → start-APIVGXZ3.js} +6 -6
- package/bundle/{start-AGMBPY3O.js → start-GJ4TH4KZ.js} +6 -6
- package/bundle/start-WDS52ZNE.js +18 -0
- package/package.json +1 -1
- package/bundle/chunk-4DCA4L53.js +0 -425
- package/bundle/chunk-BFIV7GTA.js +0 -425
- package/bundle/chunk-V72FRESD.js +0 -425
|
@@ -3,11 +3,11 @@ import {
|
|
|
3
3
|
DEFAULT_PORT,
|
|
4
4
|
getBinaryPath,
|
|
5
5
|
isServerRunning
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import "./chunk-
|
|
6
|
+
} from "./chunk-NU74STQ5.js";
|
|
7
|
+
import "./chunk-5VQUE3OF.js";
|
|
8
8
|
import {
|
|
9
9
|
debugLogger
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-QCWGLPCO.js";
|
|
11
11
|
import "./chunk-664ZODQF.js";
|
|
12
12
|
import "./chunk-IUUIT4SU.js";
|
|
13
13
|
import "./chunk-L6PII3GR.js";
|
|
@@ -41,7 +41,7 @@ var LiteRtServerManager = class {
|
|
|
41
41
|
`[LiteRtServerManager] Auto-starting LiteRT server on port ${port}...`
|
|
42
42
|
);
|
|
43
43
|
try {
|
|
44
|
-
const { startServer } = await import("./start-
|
|
44
|
+
const { startServer } = await import("./start-5GIUIER3.js");
|
|
45
45
|
const started = await startServer(binaryPath, port);
|
|
46
46
|
if (started) {
|
|
47
47
|
debugLogger.log(`[LiteRtServerManager] Server started on port ${port}`);
|
|
@@ -3,11 +3,11 @@ import {
|
|
|
3
3
|
DEFAULT_PORT,
|
|
4
4
|
getBinaryPath,
|
|
5
5
|
isServerRunning
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import "./chunk-
|
|
6
|
+
} from "./chunk-XY2QSBID.js";
|
|
7
|
+
import "./chunk-464WBVYM.js";
|
|
8
8
|
import {
|
|
9
9
|
debugLogger
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-ZFQ347ZN.js";
|
|
11
11
|
import "./chunk-664ZODQF.js";
|
|
12
12
|
import "./chunk-IUUIT4SU.js";
|
|
13
13
|
import "./chunk-L6PII3GR.js";
|
|
@@ -41,7 +41,7 @@ var LiteRtServerManager = class {
|
|
|
41
41
|
`[LiteRtServerManager] Auto-starting LiteRT server on port ${port}...`
|
|
42
42
|
);
|
|
43
43
|
try {
|
|
44
|
-
const { startServer } = await import("./start-
|
|
44
|
+
const { startServer } = await import("./start-APIVGXZ3.js");
|
|
45
45
|
const started = await startServer(binaryPath, port);
|
|
46
46
|
if (started) {
|
|
47
47
|
debugLogger.log(`[LiteRtServerManager] Server started on port ${port}`);
|
|
@@ -3,11 +3,11 @@ import {
|
|
|
3
3
|
DEFAULT_PORT,
|
|
4
4
|
getBinaryPath,
|
|
5
5
|
isServerRunning
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import "./chunk-
|
|
6
|
+
} from "./chunk-H4U2CWBQ.js";
|
|
7
|
+
import "./chunk-MH4KAY5W.js";
|
|
8
8
|
import {
|
|
9
9
|
debugLogger
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-YPLMNSM4.js";
|
|
11
11
|
import "./chunk-664ZODQF.js";
|
|
12
12
|
import "./chunk-IUUIT4SU.js";
|
|
13
13
|
import "./chunk-L6PII3GR.js";
|
|
@@ -41,7 +41,7 @@ var LiteRtServerManager = class {
|
|
|
41
41
|
`[LiteRtServerManager] Auto-starting LiteRT server on port ${port}...`
|
|
42
42
|
);
|
|
43
43
|
try {
|
|
44
|
-
const { startServer } = await import("./start-
|
|
44
|
+
const { startServer } = await import("./start-GJ4TH4KZ.js");
|
|
45
45
|
const started = await startServer(binaryPath, port);
|
|
46
46
|
if (started) {
|
|
47
47
|
debugLogger.log(`[LiteRtServerManager] Server started on port ${port}`);
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
const require = (await import('node:module')).createRequire(import.meta.url); const __chunk_filename = (await import('node:url')).fileURLToPath(import.meta.url); const __chunk_dirname = (await import('node:path')).dirname(__chunk_filename);
|
|
2
|
+
import {
|
|
3
|
+
DEFAULT_PORT,
|
|
4
|
+
getBinaryPath,
|
|
5
|
+
isServerRunning
|
|
6
|
+
} from "./chunk-BUG4N6U5.js";
|
|
7
|
+
import "./chunk-LDGJJCVW.js";
|
|
8
|
+
import {
|
|
9
|
+
debugLogger
|
|
10
|
+
} from "./chunk-YOI4DS3V.js";
|
|
11
|
+
import "./chunk-664ZODQF.js";
|
|
12
|
+
import "./chunk-IUUIT4SU.js";
|
|
13
|
+
import "./chunk-L6PII3GR.js";
|
|
14
|
+
import "./chunk-34MYV7JD.js";
|
|
15
|
+
|
|
16
|
+
// packages/cli/src/services/liteRtServerManager.ts
|
|
17
|
+
import fs from "node:fs";
|
|
18
|
+
var LiteRtServerManager = class {
|
|
19
|
+
static async ensureRunning(gemmaSettings) {
|
|
20
|
+
if (!gemmaSettings?.enabled) return;
|
|
21
|
+
if (gemmaSettings.autoStartServer === false) return;
|
|
22
|
+
const binaryPath = getBinaryPath();
|
|
23
|
+
if (!binaryPath || !fs.existsSync(binaryPath)) {
|
|
24
|
+
debugLogger.log(
|
|
25
|
+
'[LiteRtServerManager] Binary not installed, skipping auto-start. Run "gemini gemma setup".'
|
|
26
|
+
);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const port = parseInt(
|
|
30
|
+
gemmaSettings.classifier?.host?.match(/:(\d+)/)?.[1] ?? "",
|
|
31
|
+
10
|
|
32
|
+
) || DEFAULT_PORT;
|
|
33
|
+
const running = await isServerRunning(port);
|
|
34
|
+
if (running) {
|
|
35
|
+
debugLogger.log(
|
|
36
|
+
`[LiteRtServerManager] Server already running on port ${port}`
|
|
37
|
+
);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
debugLogger.log(
|
|
41
|
+
`[LiteRtServerManager] Auto-starting LiteRT server on port ${port}...`
|
|
42
|
+
);
|
|
43
|
+
try {
|
|
44
|
+
const { startServer } = await import("./start-WDS52ZNE.js");
|
|
45
|
+
const started = await startServer(binaryPath, port);
|
|
46
|
+
if (started) {
|
|
47
|
+
debugLogger.log(`[LiteRtServerManager] Server started on port ${port}`);
|
|
48
|
+
} else {
|
|
49
|
+
debugLogger.warn(
|
|
50
|
+
`[LiteRtServerManager] Server may not have started correctly on port ${port}`
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
} catch (error) {
|
|
54
|
+
debugLogger.warn("[LiteRtServerManager] Auto-start failed:", error);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
export {
|
|
59
|
+
LiteRtServerManager
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* @license
|
|
63
|
+
* Copyright 2026 Google LLC
|
|
64
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
65
|
+
*/
|
|
@@ -16,36 +16,36 @@ import {
|
|
|
16
16
|
openBrowserSecurely,
|
|
17
17
|
refreshAccessToken,
|
|
18
18
|
startCallbackServer
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-YOI4DS3V.js";
|
|
20
20
|
import "./chunk-664ZODQF.js";
|
|
21
21
|
import "./chunk-IUUIT4SU.js";
|
|
22
22
|
import "./chunk-L6PII3GR.js";
|
|
23
23
|
import "./chunk-34MYV7JD.js";
|
|
24
24
|
|
|
25
|
-
// packages/core/src/agents/auth-provider/oauth2-provider.
|
|
25
|
+
// packages/core/dist/src/agents/auth-provider/oauth2-provider.js
|
|
26
26
|
var OAuth2AuthProvider = class extends BaseA2AAuthProvider {
|
|
27
|
+
config;
|
|
28
|
+
agentName;
|
|
29
|
+
agentCardUrl;
|
|
30
|
+
type = "oauth2";
|
|
31
|
+
tokenStorage;
|
|
32
|
+
cachedToken = null;
|
|
33
|
+
pendingAuthPromise = null;
|
|
34
|
+
/** Resolved OAuth URLs — may come from config or agent card. */
|
|
35
|
+
authorizationUrl;
|
|
36
|
+
tokenUrl;
|
|
37
|
+
scopes;
|
|
27
38
|
constructor(config, agentName, agentCard, agentCardUrl) {
|
|
28
39
|
super();
|
|
29
40
|
this.config = config;
|
|
30
41
|
this.agentName = agentName;
|
|
31
42
|
this.agentCardUrl = agentCardUrl;
|
|
32
|
-
this.tokenStorage = new MCPOAuthTokenStorage(
|
|
33
|
-
Storage.getA2AOAuthTokensPath(),
|
|
34
|
-
"gemini-cli-a2a"
|
|
35
|
-
);
|
|
43
|
+
this.tokenStorage = new MCPOAuthTokenStorage(Storage.getA2AOAuthTokensPath(), "gemini-cli-a2a");
|
|
36
44
|
this.authorizationUrl = config.authorization_url;
|
|
37
45
|
this.tokenUrl = config.token_url;
|
|
38
46
|
this.scopes = config.scopes;
|
|
39
47
|
this.mergeAgentCardDefaults(agentCard);
|
|
40
48
|
}
|
|
41
|
-
type = "oauth2";
|
|
42
|
-
tokenStorage;
|
|
43
|
-
cachedToken = null;
|
|
44
|
-
pendingAuthPromise = null;
|
|
45
|
-
/** Resolved OAuth URLs — may come from config or agent card. */
|
|
46
|
-
authorizationUrl;
|
|
47
|
-
tokenUrl;
|
|
48
|
-
scopes;
|
|
49
49
|
/**
|
|
50
50
|
* Initialize the provider by loading any persisted token from storage.
|
|
51
51
|
* Also discovers OAuth URLs from the agent card if not yet resolved.
|
|
@@ -57,9 +57,7 @@ var OAuth2AuthProvider = class extends BaseA2AAuthProvider {
|
|
|
57
57
|
const credentials = await this.tokenStorage.getCredentials(this.agentName);
|
|
58
58
|
if (credentials && !this.tokenStorage.isTokenExpired(credentials.token)) {
|
|
59
59
|
this.cachedToken = credentials.token;
|
|
60
|
-
debugLogger.debug(
|
|
61
|
-
`[OAuth2AuthProvider] Loaded valid cached token for "${this.agentName}"`
|
|
62
|
-
);
|
|
60
|
+
debugLogger.debug(`[OAuth2AuthProvider] Loaded valid cached token for "${this.agentName}"`);
|
|
63
61
|
}
|
|
64
62
|
}
|
|
65
63
|
/**
|
|
@@ -86,25 +84,16 @@ var OAuth2AuthProvider = class extends BaseA2AAuthProvider {
|
|
|
86
84
|
async acquireToken() {
|
|
87
85
|
if (this.cachedToken?.refreshToken && this.tokenUrl && this.config.client_id) {
|
|
88
86
|
try {
|
|
89
|
-
const refreshed = await refreshAccessToken(
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
this.cachedToken.refreshToken,
|
|
96
|
-
this.tokenUrl
|
|
97
|
-
);
|
|
98
|
-
this.cachedToken = this.toOAuthToken(
|
|
99
|
-
refreshed,
|
|
100
|
-
this.cachedToken.refreshToken
|
|
101
|
-
);
|
|
87
|
+
const refreshed = await refreshAccessToken({
|
|
88
|
+
clientId: this.config.client_id,
|
|
89
|
+
clientSecret: this.config.client_secret,
|
|
90
|
+
scopes: this.scopes
|
|
91
|
+
}, this.cachedToken.refreshToken, this.tokenUrl);
|
|
92
|
+
this.cachedToken = this.toOAuthToken(refreshed, this.cachedToken.refreshToken);
|
|
102
93
|
await this.persistToken();
|
|
103
94
|
return this.cachedToken;
|
|
104
95
|
} catch (error) {
|
|
105
|
-
debugLogger.debug(
|
|
106
|
-
`[OAuth2AuthProvider] Refresh failed, falling back to interactive flow: ${getErrorMessage(error)}`
|
|
107
|
-
);
|
|
96
|
+
debugLogger.debug(`[OAuth2AuthProvider] Refresh failed, falling back to interactive flow: ${getErrorMessage(error)}`);
|
|
108
97
|
this.cachedToken = null;
|
|
109
98
|
await this.tokenStorage.deleteCredentials(this.agentName);
|
|
110
99
|
}
|
|
@@ -129,9 +118,7 @@ var OAuth2AuthProvider = class extends BaseA2AAuthProvider {
|
|
|
129
118
|
const reqHeaders = new Headers(req.headers);
|
|
130
119
|
const reqToken = reqHeaders.get("Authorization")?.split(" ")[1];
|
|
131
120
|
if (reqToken && (!this.cachedToken || reqToken !== this.cachedToken.accessToken)) {
|
|
132
|
-
debugLogger.debug(
|
|
133
|
-
"[OAuth2AuthProvider] Token already cleared or updated by another request, retrying with new token"
|
|
134
|
-
);
|
|
121
|
+
debugLogger.debug("[OAuth2AuthProvider] Token already cleared or updated by another request, retrying with new token");
|
|
135
122
|
const retryCount = this.authRetryCount;
|
|
136
123
|
const headers2 = await this.headers();
|
|
137
124
|
this.authRetryCount = Math.max(this.authRetryCount, retryCount);
|
|
@@ -142,9 +129,7 @@ var OAuth2AuthProvider = class extends BaseA2AAuthProvider {
|
|
|
142
129
|
}
|
|
143
130
|
const nextRetryCount = this.authRetryCount + 1;
|
|
144
131
|
this.authRetryCount = nextRetryCount;
|
|
145
|
-
debugLogger.debug(
|
|
146
|
-
"[OAuth2AuthProvider] Auth failure, clearing token and re-authenticating"
|
|
147
|
-
);
|
|
132
|
+
debugLogger.debug("[OAuth2AuthProvider] Auth failure, clearing token and re-authenticating");
|
|
148
133
|
this.cachedToken = null;
|
|
149
134
|
await this.tokenStorage.deleteCredentials(this.agentName);
|
|
150
135
|
const headers = await this.headers();
|
|
@@ -159,7 +144,8 @@ var OAuth2AuthProvider = class extends BaseA2AAuthProvider {
|
|
|
159
144
|
* `securitySchemes` when not already provided via user config.
|
|
160
145
|
*/
|
|
161
146
|
mergeAgentCardDefaults(agentCard) {
|
|
162
|
-
if (!agentCard?.securitySchemes)
|
|
147
|
+
if (!agentCard?.securitySchemes)
|
|
148
|
+
return;
|
|
163
149
|
for (const scheme of Object.values(agentCard.securitySchemes)) {
|
|
164
150
|
if (scheme.type === "oauth2" && scheme.flows.authorizationCode) {
|
|
165
151
|
const flow = scheme.flows.authorizationCode;
|
|
@@ -175,18 +161,15 @@ var OAuth2AuthProvider = class extends BaseA2AAuthProvider {
|
|
|
175
161
|
* (which normalizes proto-format cards) and extract OAuth2 URLs.
|
|
176
162
|
*/
|
|
177
163
|
async fetchAgentCardDefaults() {
|
|
178
|
-
if (!this.agentCardUrl)
|
|
164
|
+
if (!this.agentCardUrl)
|
|
165
|
+
return;
|
|
179
166
|
try {
|
|
180
|
-
debugLogger.debug(
|
|
181
|
-
`[OAuth2AuthProvider] Fetching agent card from ${this.agentCardUrl}`
|
|
182
|
-
);
|
|
167
|
+
debugLogger.debug(`[OAuth2AuthProvider] Fetching agent card from ${this.agentCardUrl}`);
|
|
183
168
|
const resolver = new DefaultAgentCardResolver();
|
|
184
169
|
const card = await resolver.resolve(this.agentCardUrl, "");
|
|
185
170
|
this.mergeAgentCardDefaults(card);
|
|
186
171
|
} catch (error) {
|
|
187
|
-
debugLogger.warn(
|
|
188
|
-
`[OAuth2AuthProvider] Could not fetch agent card for OAuth URL discovery: ${getErrorMessage(error)}`
|
|
189
|
-
);
|
|
172
|
+
debugLogger.warn(`[OAuth2AuthProvider] Could not fetch agent card for OAuth URL discovery: ${getErrorMessage(error)}`);
|
|
190
173
|
}
|
|
191
174
|
}
|
|
192
175
|
/**
|
|
@@ -194,14 +177,10 @@ var OAuth2AuthProvider = class extends BaseA2AAuthProvider {
|
|
|
194
177
|
*/
|
|
195
178
|
async authenticateInteractively() {
|
|
196
179
|
if (!this.config.client_id) {
|
|
197
|
-
throw new Error(
|
|
198
|
-
`OAuth2 authentication for agent "${this.agentName}" requires a client_id. Add client_id to the auth config in your agent definition.`
|
|
199
|
-
);
|
|
180
|
+
throw new Error(`OAuth2 authentication for agent "${this.agentName}" requires a client_id. Add client_id to the auth config in your agent definition.`);
|
|
200
181
|
}
|
|
201
182
|
if (!this.authorizationUrl || !this.tokenUrl) {
|
|
202
|
-
throw new Error(
|
|
203
|
-
`OAuth2 authentication for agent "${this.agentName}" requires authorization_url and token_url. Provide them in the auth config or ensure the agent card exposes an oauth2 security scheme.`
|
|
204
|
-
);
|
|
183
|
+
throw new Error(`OAuth2 authentication for agent "${this.agentName}" requires authorization_url and token_url. Provide them in the auth config or ensure the agent card exposes an oauth2 security scheme.`);
|
|
205
184
|
}
|
|
206
185
|
const flowConfig = {
|
|
207
186
|
clientId: this.config.client_id,
|
|
@@ -220,42 +199,29 @@ var OAuth2AuthProvider = class extends BaseA2AAuthProvider {
|
|
|
220
199
|
redirectPort,
|
|
221
200
|
/* resource= */
|
|
222
201
|
void 0
|
|
223
|
-
// No MCP resource parameter for A2A.
|
|
224
|
-
);
|
|
225
|
-
const consent = await getConsentForOauth(
|
|
226
|
-
`Authentication required for A2A agent: '${this.agentName}'.`
|
|
227
202
|
);
|
|
203
|
+
const consent = await getConsentForOauth(`Authentication required for A2A agent: '${this.agentName}'.`);
|
|
228
204
|
if (!consent) {
|
|
229
|
-
const cancelError = new FatalCancellationError(
|
|
230
|
-
"Authentication cancelled by user."
|
|
231
|
-
);
|
|
205
|
+
const cancelError = new FatalCancellationError("Authentication cancelled by user.");
|
|
232
206
|
callbackServer.response.catch(() => {
|
|
233
207
|
});
|
|
234
208
|
callbackServer.cancel?.(cancelError);
|
|
235
209
|
throw cancelError;
|
|
236
210
|
}
|
|
237
|
-
coreEvents.emitFeedback(
|
|
238
|
-
"info",
|
|
239
|
-
`\u2192 Opening your browser for OAuth sign-in...
|
|
211
|
+
coreEvents.emitFeedback("info", `\u2192 Opening your browser for OAuth sign-in...
|
|
240
212
|
|
|
241
213
|
If the browser does not open, copy and paste this URL into your browser:
|
|
242
214
|
${authUrl}
|
|
243
215
|
|
|
244
216
|
\u{1F4A1} TIP: Triple-click to select the entire URL, then copy and paste it into your browser.
|
|
245
|
-
\u26A0\uFE0F Make sure to copy the COMPLETE URL - it may wrap across multiple lines.`
|
|
246
|
-
);
|
|
217
|
+
\u26A0\uFE0F Make sure to copy the COMPLETE URL - it may wrap across multiple lines.`);
|
|
247
218
|
try {
|
|
248
219
|
await openBrowserSecurely(authUrl);
|
|
249
220
|
} catch (error) {
|
|
250
|
-
debugLogger.warn(
|
|
251
|
-
"Failed to open browser automatically:",
|
|
252
|
-
getErrorMessage(error)
|
|
253
|
-
);
|
|
221
|
+
debugLogger.warn("Failed to open browser automatically:", getErrorMessage(error));
|
|
254
222
|
}
|
|
255
223
|
const { code } = await callbackServer.response;
|
|
256
|
-
debugLogger.debug(
|
|
257
|
-
"\u2713 Authorization code received, exchanging for tokens..."
|
|
258
|
-
);
|
|
224
|
+
debugLogger.debug("\u2713 Authorization code received, exchanging for tokens...");
|
|
259
225
|
const tokenResponse = await exchangeCodeForToken(
|
|
260
226
|
flowConfig,
|
|
261
227
|
code,
|
|
@@ -292,13 +258,9 @@ ${authUrl}
|
|
|
292
258
|
* Persist the current cached token to disk.
|
|
293
259
|
*/
|
|
294
260
|
async persistToken() {
|
|
295
|
-
if (!this.cachedToken)
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
this.cachedToken,
|
|
299
|
-
this.config.client_id,
|
|
300
|
-
this.tokenUrl
|
|
301
|
-
);
|
|
261
|
+
if (!this.cachedToken)
|
|
262
|
+
return;
|
|
263
|
+
await this.tokenStorage.saveToken(this.agentName, this.cachedToken, this.config.client_id, this.tokenUrl);
|
|
302
264
|
}
|
|
303
265
|
};
|
|
304
266
|
export {
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
const require = (await import('node:module')).createRequire(import.meta.url); const __chunk_filename = (await import('node:url')).fileURLToPath(import.meta.url); const __chunk_dirname = (await import('node:path')).dirname(__chunk_filename);
|
|
2
|
+
import {
|
|
3
|
+
BaseA2AAuthProvider,
|
|
4
|
+
DefaultAgentCardResolver,
|
|
5
|
+
FatalCancellationError,
|
|
6
|
+
MCPOAuthTokenStorage,
|
|
7
|
+
Storage,
|
|
8
|
+
buildAuthorizationUrl,
|
|
9
|
+
coreEvents,
|
|
10
|
+
debugLogger,
|
|
11
|
+
exchangeCodeForToken,
|
|
12
|
+
generatePKCEParams,
|
|
13
|
+
getConsentForOauth,
|
|
14
|
+
getErrorMessage,
|
|
15
|
+
getPortFromUrl,
|
|
16
|
+
openBrowserSecurely,
|
|
17
|
+
refreshAccessToken,
|
|
18
|
+
startCallbackServer
|
|
19
|
+
} from "./chunk-ZFQ347ZN.js";
|
|
20
|
+
import "./chunk-664ZODQF.js";
|
|
21
|
+
import "./chunk-IUUIT4SU.js";
|
|
22
|
+
import "./chunk-L6PII3GR.js";
|
|
23
|
+
import "./chunk-34MYV7JD.js";
|
|
24
|
+
|
|
25
|
+
// packages/core/dist/src/agents/auth-provider/oauth2-provider.js
|
|
26
|
+
var OAuth2AuthProvider = class extends BaseA2AAuthProvider {
|
|
27
|
+
config;
|
|
28
|
+
agentName;
|
|
29
|
+
agentCardUrl;
|
|
30
|
+
type = "oauth2";
|
|
31
|
+
tokenStorage;
|
|
32
|
+
cachedToken = null;
|
|
33
|
+
pendingAuthPromise = null;
|
|
34
|
+
/** Resolved OAuth URLs — may come from config or agent card. */
|
|
35
|
+
authorizationUrl;
|
|
36
|
+
tokenUrl;
|
|
37
|
+
scopes;
|
|
38
|
+
constructor(config, agentName, agentCard, agentCardUrl) {
|
|
39
|
+
super();
|
|
40
|
+
this.config = config;
|
|
41
|
+
this.agentName = agentName;
|
|
42
|
+
this.agentCardUrl = agentCardUrl;
|
|
43
|
+
this.tokenStorage = new MCPOAuthTokenStorage(Storage.getA2AOAuthTokensPath(), "gemini-cli-a2a");
|
|
44
|
+
this.authorizationUrl = config.authorization_url;
|
|
45
|
+
this.tokenUrl = config.token_url;
|
|
46
|
+
this.scopes = config.scopes;
|
|
47
|
+
this.mergeAgentCardDefaults(agentCard);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Initialize the provider by loading any persisted token from storage.
|
|
51
|
+
* Also discovers OAuth URLs from the agent card if not yet resolved.
|
|
52
|
+
*/
|
|
53
|
+
async initialize() {
|
|
54
|
+
if ((!this.authorizationUrl || !this.tokenUrl) && this.agentCardUrl) {
|
|
55
|
+
await this.fetchAgentCardDefaults();
|
|
56
|
+
}
|
|
57
|
+
const credentials = await this.tokenStorage.getCredentials(this.agentName);
|
|
58
|
+
if (credentials && !this.tokenStorage.isTokenExpired(credentials.token)) {
|
|
59
|
+
this.cachedToken = credentials.token;
|
|
60
|
+
debugLogger.debug(`[OAuth2AuthProvider] Loaded valid cached token for "${this.agentName}"`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Return an Authorization header with a valid Bearer token.
|
|
65
|
+
* Refreshes or triggers interactive auth as needed, deduplicating concurrent requests.
|
|
66
|
+
*/
|
|
67
|
+
async headers() {
|
|
68
|
+
if (this.cachedToken && !this.tokenStorage.isTokenExpired(this.cachedToken)) {
|
|
69
|
+
this.authRetryCount = 0;
|
|
70
|
+
return { Authorization: `Bearer ${this.cachedToken.accessToken}` };
|
|
71
|
+
}
|
|
72
|
+
if (!this.pendingAuthPromise) {
|
|
73
|
+
this.pendingAuthPromise = this.acquireToken().finally(() => {
|
|
74
|
+
this.pendingAuthPromise = null;
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
const token = await this.pendingAuthPromise;
|
|
78
|
+
this.authRetryCount = 0;
|
|
79
|
+
return { Authorization: `Bearer ${token.accessToken}` };
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Refresh an expired token or run interactive browser-based authentication.
|
|
83
|
+
*/
|
|
84
|
+
async acquireToken() {
|
|
85
|
+
if (this.cachedToken?.refreshToken && this.tokenUrl && this.config.client_id) {
|
|
86
|
+
try {
|
|
87
|
+
const refreshed = await refreshAccessToken({
|
|
88
|
+
clientId: this.config.client_id,
|
|
89
|
+
clientSecret: this.config.client_secret,
|
|
90
|
+
scopes: this.scopes
|
|
91
|
+
}, this.cachedToken.refreshToken, this.tokenUrl);
|
|
92
|
+
this.cachedToken = this.toOAuthToken(refreshed, this.cachedToken.refreshToken);
|
|
93
|
+
await this.persistToken();
|
|
94
|
+
return this.cachedToken;
|
|
95
|
+
} catch (error) {
|
|
96
|
+
debugLogger.debug(`[OAuth2AuthProvider] Refresh failed, falling back to interactive flow: ${getErrorMessage(error)}`);
|
|
97
|
+
this.cachedToken = null;
|
|
98
|
+
await this.tokenStorage.deleteCredentials(this.agentName);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
this.cachedToken = await this.authenticateInteractively();
|
|
102
|
+
return this.cachedToken;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Return the maximum number of consecutive authentication retries allowed.
|
|
106
|
+
*/
|
|
107
|
+
getMaxAuthRetries() {
|
|
108
|
+
return BaseA2AAuthProvider.MAX_AUTH_RETRIES;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* On 401/403, clear the cached token and re-authenticate (up to MAX_AUTH_RETRIES).
|
|
112
|
+
*/
|
|
113
|
+
async shouldRetryWithHeaders(req, res) {
|
|
114
|
+
if (res.status !== 401 && res.status !== 403) {
|
|
115
|
+
this.authRetryCount = 0;
|
|
116
|
+
return void 0;
|
|
117
|
+
}
|
|
118
|
+
const reqHeaders = new Headers(req.headers);
|
|
119
|
+
const reqToken = reqHeaders.get("Authorization")?.split(" ")[1];
|
|
120
|
+
if (reqToken && (!this.cachedToken || reqToken !== this.cachedToken.accessToken)) {
|
|
121
|
+
debugLogger.debug("[OAuth2AuthProvider] Token already cleared or updated by another request, retrying with new token");
|
|
122
|
+
const retryCount = this.authRetryCount;
|
|
123
|
+
const headers2 = await this.headers();
|
|
124
|
+
this.authRetryCount = Math.max(this.authRetryCount, retryCount);
|
|
125
|
+
return headers2;
|
|
126
|
+
}
|
|
127
|
+
if (this.authRetryCount >= this.getMaxAuthRetries()) {
|
|
128
|
+
return void 0;
|
|
129
|
+
}
|
|
130
|
+
const nextRetryCount = this.authRetryCount + 1;
|
|
131
|
+
this.authRetryCount = nextRetryCount;
|
|
132
|
+
debugLogger.debug("[OAuth2AuthProvider] Auth failure, clearing token and re-authenticating");
|
|
133
|
+
this.cachedToken = null;
|
|
134
|
+
await this.tokenStorage.deleteCredentials(this.agentName);
|
|
135
|
+
const headers = await this.headers();
|
|
136
|
+
this.authRetryCount = nextRetryCount;
|
|
137
|
+
return headers;
|
|
138
|
+
}
|
|
139
|
+
// ---------------------------------------------------------------------------
|
|
140
|
+
// Private helpers
|
|
141
|
+
// ---------------------------------------------------------------------------
|
|
142
|
+
/**
|
|
143
|
+
* Merge authorization_url, token_url, and scopes from the agent card's
|
|
144
|
+
* `securitySchemes` when not already provided via user config.
|
|
145
|
+
*/
|
|
146
|
+
mergeAgentCardDefaults(agentCard) {
|
|
147
|
+
if (!agentCard?.securitySchemes)
|
|
148
|
+
return;
|
|
149
|
+
for (const scheme of Object.values(agentCard.securitySchemes)) {
|
|
150
|
+
if (scheme.type === "oauth2" && scheme.flows.authorizationCode) {
|
|
151
|
+
const flow = scheme.flows.authorizationCode;
|
|
152
|
+
this.authorizationUrl ??= flow.authorizationUrl;
|
|
153
|
+
this.tokenUrl ??= flow.tokenUrl;
|
|
154
|
+
this.scopes ??= Object.keys(flow.scopes);
|
|
155
|
+
break;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Fetch the agent card from `agentCardUrl` using `DefaultAgentCardResolver`
|
|
161
|
+
* (which normalizes proto-format cards) and extract OAuth2 URLs.
|
|
162
|
+
*/
|
|
163
|
+
async fetchAgentCardDefaults() {
|
|
164
|
+
if (!this.agentCardUrl)
|
|
165
|
+
return;
|
|
166
|
+
try {
|
|
167
|
+
debugLogger.debug(`[OAuth2AuthProvider] Fetching agent card from ${this.agentCardUrl}`);
|
|
168
|
+
const resolver = new DefaultAgentCardResolver();
|
|
169
|
+
const card = await resolver.resolve(this.agentCardUrl, "");
|
|
170
|
+
this.mergeAgentCardDefaults(card);
|
|
171
|
+
} catch (error) {
|
|
172
|
+
debugLogger.warn(`[OAuth2AuthProvider] Could not fetch agent card for OAuth URL discovery: ${getErrorMessage(error)}`);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Run a full OAuth 2.0 Authorization Code + PKCE flow through the browser.
|
|
177
|
+
*/
|
|
178
|
+
async authenticateInteractively() {
|
|
179
|
+
if (!this.config.client_id) {
|
|
180
|
+
throw new Error(`OAuth2 authentication for agent "${this.agentName}" requires a client_id. Add client_id to the auth config in your agent definition.`);
|
|
181
|
+
}
|
|
182
|
+
if (!this.authorizationUrl || !this.tokenUrl) {
|
|
183
|
+
throw new Error(`OAuth2 authentication for agent "${this.agentName}" requires authorization_url and token_url. Provide them in the auth config or ensure the agent card exposes an oauth2 security scheme.`);
|
|
184
|
+
}
|
|
185
|
+
const flowConfig = {
|
|
186
|
+
clientId: this.config.client_id,
|
|
187
|
+
clientSecret: this.config.client_secret,
|
|
188
|
+
authorizationUrl: this.authorizationUrl,
|
|
189
|
+
tokenUrl: this.tokenUrl,
|
|
190
|
+
scopes: this.scopes
|
|
191
|
+
};
|
|
192
|
+
const pkceParams = generatePKCEParams();
|
|
193
|
+
const preferredPort = getPortFromUrl(flowConfig.redirectUri);
|
|
194
|
+
const callbackServer = startCallbackServer(pkceParams.state, preferredPort);
|
|
195
|
+
const redirectPort = await callbackServer.port;
|
|
196
|
+
const authUrl = buildAuthorizationUrl(
|
|
197
|
+
flowConfig,
|
|
198
|
+
pkceParams,
|
|
199
|
+
redirectPort,
|
|
200
|
+
/* resource= */
|
|
201
|
+
void 0
|
|
202
|
+
);
|
|
203
|
+
const consent = await getConsentForOauth(`Authentication required for A2A agent: '${this.agentName}'.`);
|
|
204
|
+
if (!consent) {
|
|
205
|
+
const cancelError = new FatalCancellationError("Authentication cancelled by user.");
|
|
206
|
+
callbackServer.response.catch(() => {
|
|
207
|
+
});
|
|
208
|
+
callbackServer.cancel?.(cancelError);
|
|
209
|
+
throw cancelError;
|
|
210
|
+
}
|
|
211
|
+
coreEvents.emitFeedback("info", `\u2192 Opening your browser for OAuth sign-in...
|
|
212
|
+
|
|
213
|
+
If the browser does not open, copy and paste this URL into your browser:
|
|
214
|
+
${authUrl}
|
|
215
|
+
|
|
216
|
+
\u{1F4A1} TIP: Triple-click to select the entire URL, then copy and paste it into your browser.
|
|
217
|
+
\u26A0\uFE0F Make sure to copy the COMPLETE URL - it may wrap across multiple lines.`);
|
|
218
|
+
try {
|
|
219
|
+
await openBrowserSecurely(authUrl);
|
|
220
|
+
} catch (error) {
|
|
221
|
+
debugLogger.warn("Failed to open browser automatically:", getErrorMessage(error));
|
|
222
|
+
}
|
|
223
|
+
const { code } = await callbackServer.response;
|
|
224
|
+
debugLogger.debug("\u2713 Authorization code received, exchanging for tokens...");
|
|
225
|
+
const tokenResponse = await exchangeCodeForToken(
|
|
226
|
+
flowConfig,
|
|
227
|
+
code,
|
|
228
|
+
pkceParams.codeVerifier,
|
|
229
|
+
redirectPort,
|
|
230
|
+
/* resource= */
|
|
231
|
+
void 0
|
|
232
|
+
);
|
|
233
|
+
if (!tokenResponse.access_token) {
|
|
234
|
+
throw new Error("No access token received from token endpoint");
|
|
235
|
+
}
|
|
236
|
+
const token = this.toOAuthToken(tokenResponse);
|
|
237
|
+
this.cachedToken = token;
|
|
238
|
+
await this.persistToken();
|
|
239
|
+
debugLogger.debug("\u2713 OAuth2 authentication successful! Token saved.");
|
|
240
|
+
return token;
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Convert an `OAuthTokenResponse` into the internal `OAuthToken` format.
|
|
244
|
+
*/
|
|
245
|
+
toOAuthToken(response, fallbackRefreshToken) {
|
|
246
|
+
const token = {
|
|
247
|
+
accessToken: response.access_token,
|
|
248
|
+
tokenType: response.token_type || "Bearer",
|
|
249
|
+
refreshToken: response.refresh_token || fallbackRefreshToken,
|
|
250
|
+
scope: response.scope
|
|
251
|
+
};
|
|
252
|
+
if (response.expires_in) {
|
|
253
|
+
token.expiresAt = Date.now() + response.expires_in * 1e3;
|
|
254
|
+
}
|
|
255
|
+
return token;
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Persist the current cached token to disk.
|
|
259
|
+
*/
|
|
260
|
+
async persistToken() {
|
|
261
|
+
if (!this.cachedToken)
|
|
262
|
+
return;
|
|
263
|
+
await this.tokenStorage.saveToken(this.agentName, this.cachedToken, this.config.client_id, this.tokenUrl);
|
|
264
|
+
}
|
|
265
|
+
};
|
|
266
|
+
export {
|
|
267
|
+
OAuth2AuthProvider
|
|
268
|
+
};
|
|
269
|
+
/**
|
|
270
|
+
* @license
|
|
271
|
+
* Copyright 2026 Google LLC
|
|
272
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
273
|
+
*/
|
|
@@ -2,12 +2,12 @@ const require = (await import('node:module')).createRequire(import.meta.url); co
|
|
|
2
2
|
import {
|
|
3
3
|
startCommand,
|
|
4
4
|
startServer
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
7
|
-
import "./chunk-
|
|
8
|
-
import "./chunk-
|
|
9
|
-
import "./chunk-
|
|
10
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-RACMC24X.js";
|
|
6
|
+
import "./chunk-RE4V6I3G.js";
|
|
7
|
+
import "./chunk-NU74STQ5.js";
|
|
8
|
+
import "./chunk-5VQUE3OF.js";
|
|
9
|
+
import "./chunk-YP27UYI4.js";
|
|
10
|
+
import "./chunk-QCWGLPCO.js";
|
|
11
11
|
import "./chunk-664ZODQF.js";
|
|
12
12
|
import "./chunk-IUUIT4SU.js";
|
|
13
13
|
import "./chunk-L6PII3GR.js";
|