@google/gemini-cli 0.35.0-preview.1 → 0.35.0-preview.2

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 (31) hide show
  1. package/bundle/{chunk-RIKAIXXN.js → chunk-5OVDZKPV.js} +6 -6
  2. package/bundle/{chunk-FKGF3664.js → chunk-6AQAEYFC.js} +5315 -9974
  3. package/bundle/{chunk-OK6A2T3J.js → chunk-C2LINL7G.js} +14 -12
  4. package/bundle/{chunk-OVO7PV7Z.js → chunk-ELVZ5MKI.js} +4 -4
  5. package/bundle/{chunk-DHZSW3D5.js → chunk-HYF34ISK.js} +4 -4
  6. package/bundle/{chunk-FIQWQZVG.js → chunk-QO53VEHI.js} +15 -12
  7. package/bundle/{chunk-7JZWJYL2.js → chunk-SCIFYSWM.js} +4 -4
  8. package/bundle/{chunk-J7ZVHCWL.js → chunk-TYZCRVGB.js} +70 -58
  9. package/bundle/chunk-WTYAEXC3.js +325893 -0
  10. package/bundle/chunk-WXXNCSKU.js +92840 -0
  11. package/bundle/{core-OSNLJAKB.js → core-ZWMLWHG7.js} +2 -2
  12. package/bundle/{devtoolsService-UPY6AYM7.js → devtoolsService-DH7MKZL2.js} +3 -3
  13. package/bundle/{devtoolsService-YJFR2ZTU.js → devtoolsService-EVTQ32UO.js} +3 -3
  14. package/bundle/{devtoolsService-CH2PM4E2.js → devtoolsService-FPFZEEVK.js} +5 -4
  15. package/bundle/devtoolsService-XMVPJFZ7.js +855 -0
  16. package/bundle/{core-YBLRHI5E.js → dist-6LCHGUBD.js} +2 -2
  17. package/bundle/{dist-PQCTLJ67.js → dist-AWPSKKKO.js} +2 -2
  18. package/bundle/dist-WOQEPX5R.js +1781 -0
  19. package/bundle/gemini.js +7 -7
  20. package/bundle/{interactiveCli-SIJB4G3Q.js → interactiveCli-7H3T4KJF.js} +4 -4
  21. package/bundle/{interactiveCli-AKIKCHLF.js → interactiveCli-E3DWTWRM.js} +239 -222
  22. package/bundle/{interactiveCli-3JVKXF42.js → interactiveCli-N4QW3NCZ.js} +4 -4
  23. package/bundle/interactiveCli-Z4Y6XB7M.js +48702 -0
  24. package/bundle/{memoryDiscovery-2RH76CMO.js → memoryDiscovery-7LUUOJNM.js} +1 -1
  25. package/bundle/{memoryDiscovery-P6SEGMWA.js → memoryDiscovery-RRX6QF4Y.js} +1 -1
  26. package/bundle/node_modules/@google/gemini-cli-devtools/package.json +1 -1
  27. package/bundle/{oauth2-provider-G4RXUPFH.js → oauth2-provider-CPMX7ITW.js} +2 -2
  28. package/bundle/{oauth2-provider-ZZIJ6OXB.js → oauth2-provider-IU6STKL7.js} +2 -2
  29. package/bundle/{oauth2-provider-N6KBVMX3.js → oauth2-provider-LTBDSRHY.js} +39 -73
  30. package/bundle/oauth2-provider-ZWWMTBET.js +238 -0
  31. package/package.json +1 -1
@@ -10,7 +10,7 @@ import {
10
10
  loadServerHierarchicalMemory,
11
11
  readGeminiMdFiles,
12
12
  refreshServerHierarchicalMemory
13
- } from "./chunk-OK6A2T3J.js";
13
+ } from "./chunk-C2LINL7G.js";
14
14
  import "./chunk-664ZODQF.js";
15
15
  import "./chunk-34MYV7JD.js";
16
16
  export {
@@ -10,7 +10,7 @@ import {
10
10
  loadServerHierarchicalMemory,
11
11
  readGeminiMdFiles,
12
12
  refreshServerHierarchicalMemory
13
- } from "./chunk-FIQWQZVG.js";
13
+ } from "./chunk-QO53VEHI.js";
14
14
  import "./chunk-664ZODQF.js";
15
15
  import "./chunk-34MYV7JD.js";
16
16
  export {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@google/gemini-cli-devtools",
3
- "version": "0.35.0-preview.1",
3
+ "version": "0.35.0-preview.2",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",
@@ -11,7 +11,7 @@ import {
11
11
  openBrowserSecurely,
12
12
  refreshAccessToken,
13
13
  startCallbackServer
14
- } from "./chunk-OVO7PV7Z.js";
14
+ } from "./chunk-ELVZ5MKI.js";
15
15
  import "./chunk-37ZTTFQF.js";
16
16
  import {
17
17
  FatalCancellationError,
@@ -19,7 +19,7 @@ import {
19
19
  coreEvents,
20
20
  debugLogger,
21
21
  getErrorMessage
22
- } from "./chunk-FIQWQZVG.js";
22
+ } from "./chunk-QO53VEHI.js";
23
23
  import "./chunk-664ZODQF.js";
24
24
  import "./chunk-RJTRUG2J.js";
25
25
  import "./chunk-IUUIT4SU.js";
@@ -11,7 +11,7 @@ import {
11
11
  openBrowserSecurely,
12
12
  refreshAccessToken,
13
13
  startCallbackServer
14
- } from "./chunk-RIKAIXXN.js";
14
+ } from "./chunk-6AQAEYFC.js";
15
15
  import "./chunk-37ZTTFQF.js";
16
16
  import {
17
17
  FatalCancellationError,
@@ -19,7 +19,7 @@ import {
19
19
  coreEvents,
20
20
  debugLogger,
21
21
  getErrorMessage
22
- } from "./chunk-OK6A2T3J.js";
22
+ } from "./chunk-C2LINL7G.js";
23
23
  import "./chunk-664ZODQF.js";
24
24
  import "./chunk-RJTRUG2J.js";
25
25
  import "./chunk-IUUIT4SU.js";
@@ -11,7 +11,7 @@ import {
11
11
  openBrowserSecurely,
12
12
  refreshAccessToken,
13
13
  startCallbackServer
14
- } from "./chunk-FKGF3664.js";
14
+ } from "./chunk-5OVDZKPV.js";
15
15
  import "./chunk-37ZTTFQF.js";
16
16
  import {
17
17
  FatalCancellationError,
@@ -19,35 +19,35 @@ import {
19
19
  coreEvents,
20
20
  debugLogger,
21
21
  getErrorMessage
22
- } from "./chunk-FIQWQZVG.js";
22
+ } from "./chunk-C2LINL7G.js";
23
23
  import "./chunk-664ZODQF.js";
24
24
  import "./chunk-RJTRUG2J.js";
25
25
  import "./chunk-IUUIT4SU.js";
26
26
  import "./chunk-34MYV7JD.js";
27
27
 
28
- // packages/core/src/agents/auth-provider/oauth2-provider.ts
28
+ // packages/core/dist/src/agents/auth-provider/oauth2-provider.js
29
29
  var OAuth2AuthProvider = class extends BaseA2AAuthProvider {
30
+ config;
31
+ agentName;
32
+ agentCardUrl;
33
+ type = "oauth2";
34
+ tokenStorage;
35
+ cachedToken = null;
36
+ /** Resolved OAuth URLs — may come from config or agent card. */
37
+ authorizationUrl;
38
+ tokenUrl;
39
+ scopes;
30
40
  constructor(config, agentName, agentCard, agentCardUrl) {
31
41
  super();
32
42
  this.config = config;
33
43
  this.agentName = agentName;
34
44
  this.agentCardUrl = agentCardUrl;
35
- this.tokenStorage = new MCPOAuthTokenStorage(
36
- Storage.getA2AOAuthTokensPath(),
37
- "gemini-cli-a2a"
38
- );
45
+ this.tokenStorage = new MCPOAuthTokenStorage(Storage.getA2AOAuthTokensPath(), "gemini-cli-a2a");
39
46
  this.authorizationUrl = config.authorization_url;
40
47
  this.tokenUrl = config.token_url;
41
48
  this.scopes = config.scopes;
42
49
  this.mergeAgentCardDefaults(agentCard);
43
50
  }
44
- type = "oauth2";
45
- tokenStorage;
46
- cachedToken = null;
47
- /** Resolved OAuth URLs — may come from config or agent card. */
48
- authorizationUrl;
49
- tokenUrl;
50
- scopes;
51
51
  /**
52
52
  * Initialize the provider by loading any persisted token from storage.
53
53
  * Also discovers OAuth URLs from the agent card if not yet resolved.
@@ -59,9 +59,7 @@ var OAuth2AuthProvider = class extends BaseA2AAuthProvider {
59
59
  const credentials = await this.tokenStorage.getCredentials(this.agentName);
60
60
  if (credentials && !this.tokenStorage.isTokenExpired(credentials.token)) {
61
61
  this.cachedToken = credentials.token;
62
- debugLogger.debug(
63
- `[OAuth2AuthProvider] Loaded valid cached token for "${this.agentName}"`
64
- );
62
+ debugLogger.debug(`[OAuth2AuthProvider] Loaded valid cached token for "${this.agentName}"`);
65
63
  }
66
64
  }
67
65
  /**
@@ -74,25 +72,16 @@ var OAuth2AuthProvider = class extends BaseA2AAuthProvider {
74
72
  }
75
73
  if (this.cachedToken?.refreshToken && this.tokenUrl && this.config.client_id) {
76
74
  try {
77
- const refreshed = await refreshAccessToken(
78
- {
79
- clientId: this.config.client_id,
80
- clientSecret: this.config.client_secret,
81
- scopes: this.scopes
82
- },
83
- this.cachedToken.refreshToken,
84
- this.tokenUrl
85
- );
86
- this.cachedToken = this.toOAuthToken(
87
- refreshed,
88
- this.cachedToken.refreshToken
89
- );
75
+ const refreshed = await refreshAccessToken({
76
+ clientId: this.config.client_id,
77
+ clientSecret: this.config.client_secret,
78
+ scopes: this.scopes
79
+ }, this.cachedToken.refreshToken, this.tokenUrl);
80
+ this.cachedToken = this.toOAuthToken(refreshed, this.cachedToken.refreshToken);
90
81
  await this.persistToken();
91
82
  return { Authorization: `Bearer ${this.cachedToken.accessToken}` };
92
83
  } catch (error) {
93
- debugLogger.debug(
94
- `[OAuth2AuthProvider] Refresh failed, falling back to interactive flow: ${getErrorMessage(error)}`
95
- );
84
+ debugLogger.debug(`[OAuth2AuthProvider] Refresh failed, falling back to interactive flow: ${getErrorMessage(error)}`);
96
85
  await this.tokenStorage.deleteCredentials(this.agentName);
97
86
  }
98
87
  }
@@ -111,9 +100,7 @@ var OAuth2AuthProvider = class extends BaseA2AAuthProvider {
111
100
  return void 0;
112
101
  }
113
102
  this.authRetryCount++;
114
- debugLogger.debug(
115
- "[OAuth2AuthProvider] Auth failure, clearing token and re-authenticating"
116
- );
103
+ debugLogger.debug("[OAuth2AuthProvider] Auth failure, clearing token and re-authenticating");
117
104
  this.cachedToken = null;
118
105
  await this.tokenStorage.deleteCredentials(this.agentName);
119
106
  return this.headers();
@@ -126,7 +113,8 @@ var OAuth2AuthProvider = class extends BaseA2AAuthProvider {
126
113
  * `securitySchemes` when not already provided via user config.
127
114
  */
128
115
  mergeAgentCardDefaults(agentCard) {
129
- if (!agentCard?.securitySchemes) return;
116
+ if (!agentCard?.securitySchemes)
117
+ return;
130
118
  for (const scheme of Object.values(agentCard.securitySchemes)) {
131
119
  if (scheme.type === "oauth2" && scheme.flows.authorizationCode) {
132
120
  const flow = scheme.flows.authorizationCode;
@@ -142,18 +130,15 @@ var OAuth2AuthProvider = class extends BaseA2AAuthProvider {
142
130
  * (which normalizes proto-format cards) and extract OAuth2 URLs.
143
131
  */
144
132
  async fetchAgentCardDefaults() {
145
- if (!this.agentCardUrl) return;
133
+ if (!this.agentCardUrl)
134
+ return;
146
135
  try {
147
- debugLogger.debug(
148
- `[OAuth2AuthProvider] Fetching agent card from ${this.agentCardUrl}`
149
- );
136
+ debugLogger.debug(`[OAuth2AuthProvider] Fetching agent card from ${this.agentCardUrl}`);
150
137
  const resolver = new DefaultAgentCardResolver();
151
138
  const card = await resolver.resolve(this.agentCardUrl, "");
152
139
  this.mergeAgentCardDefaults(card);
153
140
  } catch (error) {
154
- debugLogger.warn(
155
- `[OAuth2AuthProvider] Could not fetch agent card for OAuth URL discovery: ${getErrorMessage(error)}`
156
- );
141
+ debugLogger.warn(`[OAuth2AuthProvider] Could not fetch agent card for OAuth URL discovery: ${getErrorMessage(error)}`);
157
142
  }
158
143
  }
159
144
  /**
@@ -161,14 +146,10 @@ var OAuth2AuthProvider = class extends BaseA2AAuthProvider {
161
146
  */
162
147
  async authenticateInteractively() {
163
148
  if (!this.config.client_id) {
164
- throw new Error(
165
- `OAuth2 authentication for agent "${this.agentName}" requires a client_id. Add client_id to the auth config in your agent definition.`
166
- );
149
+ throw new Error(`OAuth2 authentication for agent "${this.agentName}" requires a client_id. Add client_id to the auth config in your agent definition.`);
167
150
  }
168
151
  if (!this.authorizationUrl || !this.tokenUrl) {
169
- throw new Error(
170
- `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.`
171
- );
152
+ 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.`);
172
153
  }
173
154
  const flowConfig = {
174
155
  clientId: this.config.client_id,
@@ -187,36 +168,25 @@ var OAuth2AuthProvider = class extends BaseA2AAuthProvider {
187
168
  redirectPort,
188
169
  /* resource= */
189
170
  void 0
190
- // No MCP resource parameter for A2A.
191
- );
192
- const consent = await getConsentForOauth(
193
- `Authentication required for A2A agent: '${this.agentName}'.`
194
171
  );
172
+ const consent = await getConsentForOauth(`Authentication required for A2A agent: '${this.agentName}'.`);
195
173
  if (!consent) {
196
174
  throw new FatalCancellationError("Authentication cancelled by user.");
197
175
  }
198
- coreEvents.emitFeedback(
199
- "info",
200
- `\u2192 Opening your browser for OAuth sign-in...
176
+ coreEvents.emitFeedback("info", `\u2192 Opening your browser for OAuth sign-in...
201
177
 
202
178
  If the browser does not open, copy and paste this URL into your browser:
203
179
  ${authUrl}
204
180
 
205
181
  \u{1F4A1} TIP: Triple-click to select the entire URL, then copy and paste it into your browser.
206
- \u26A0\uFE0F Make sure to copy the COMPLETE URL - it may wrap across multiple lines.`
207
- );
182
+ \u26A0\uFE0F Make sure to copy the COMPLETE URL - it may wrap across multiple lines.`);
208
183
  try {
209
184
  await openBrowserSecurely(authUrl);
210
185
  } catch (error) {
211
- debugLogger.warn(
212
- "Failed to open browser automatically:",
213
- getErrorMessage(error)
214
- );
186
+ debugLogger.warn("Failed to open browser automatically:", getErrorMessage(error));
215
187
  }
216
188
  const { code } = await callbackServer.response;
217
- debugLogger.debug(
218
- "\u2713 Authorization code received, exchanging for tokens..."
219
- );
189
+ debugLogger.debug("\u2713 Authorization code received, exchanging for tokens...");
220
190
  const tokenResponse = await exchangeCodeForToken(
221
191
  flowConfig,
222
192
  code,
@@ -253,13 +223,9 @@ ${authUrl}
253
223
  * Persist the current cached token to disk.
254
224
  */
255
225
  async persistToken() {
256
- if (!this.cachedToken) return;
257
- await this.tokenStorage.saveToken(
258
- this.agentName,
259
- this.cachedToken,
260
- this.config.client_id,
261
- this.tokenUrl
262
- );
226
+ if (!this.cachedToken)
227
+ return;
228
+ await this.tokenStorage.saveToken(this.agentName, this.cachedToken, this.config.client_id, this.tokenUrl);
263
229
  }
264
230
  };
265
231
  export {
@@ -0,0 +1,238 @@
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
+ MCPOAuthTokenStorage,
6
+ buildAuthorizationUrl,
7
+ exchangeCodeForToken,
8
+ generatePKCEParams,
9
+ getConsentForOauth,
10
+ getPortFromUrl,
11
+ openBrowserSecurely,
12
+ refreshAccessToken,
13
+ startCallbackServer
14
+ } from "./chunk-WTYAEXC3.js";
15
+ import "./chunk-37ZTTFQF.js";
16
+ import {
17
+ FatalCancellationError,
18
+ Storage,
19
+ coreEvents,
20
+ debugLogger,
21
+ getErrorMessage
22
+ } from "./chunk-C2LINL7G.js";
23
+ import "./chunk-664ZODQF.js";
24
+ import "./chunk-RJTRUG2J.js";
25
+ import "./chunk-IUUIT4SU.js";
26
+ import "./chunk-34MYV7JD.js";
27
+
28
+ // packages/core/dist/src/agents/auth-provider/oauth2-provider.js
29
+ var OAuth2AuthProvider = class extends BaseA2AAuthProvider {
30
+ config;
31
+ agentName;
32
+ agentCardUrl;
33
+ type = "oauth2";
34
+ tokenStorage;
35
+ cachedToken = null;
36
+ /** Resolved OAuth URLs — may come from config or agent card. */
37
+ authorizationUrl;
38
+ tokenUrl;
39
+ scopes;
40
+ constructor(config, agentName, agentCard, agentCardUrl) {
41
+ super();
42
+ this.config = config;
43
+ this.agentName = agentName;
44
+ this.agentCardUrl = agentCardUrl;
45
+ this.tokenStorage = new MCPOAuthTokenStorage(Storage.getA2AOAuthTokensPath(), "gemini-cli-a2a");
46
+ this.authorizationUrl = config.authorization_url;
47
+ this.tokenUrl = config.token_url;
48
+ this.scopes = config.scopes;
49
+ this.mergeAgentCardDefaults(agentCard);
50
+ }
51
+ /**
52
+ * Initialize the provider by loading any persisted token from storage.
53
+ * Also discovers OAuth URLs from the agent card if not yet resolved.
54
+ */
55
+ async initialize() {
56
+ if ((!this.authorizationUrl || !this.tokenUrl) && this.agentCardUrl) {
57
+ await this.fetchAgentCardDefaults();
58
+ }
59
+ const credentials = await this.tokenStorage.getCredentials(this.agentName);
60
+ if (credentials && !this.tokenStorage.isTokenExpired(credentials.token)) {
61
+ this.cachedToken = credentials.token;
62
+ debugLogger.debug(`[OAuth2AuthProvider] Loaded valid cached token for "${this.agentName}"`);
63
+ }
64
+ }
65
+ /**
66
+ * Return an Authorization header with a valid Bearer token.
67
+ * Refreshes or triggers interactive auth as needed.
68
+ */
69
+ async headers() {
70
+ if (this.cachedToken && !this.tokenStorage.isTokenExpired(this.cachedToken)) {
71
+ return { Authorization: `Bearer ${this.cachedToken.accessToken}` };
72
+ }
73
+ if (this.cachedToken?.refreshToken && this.tokenUrl && this.config.client_id) {
74
+ try {
75
+ const refreshed = await refreshAccessToken({
76
+ clientId: this.config.client_id,
77
+ clientSecret: this.config.client_secret,
78
+ scopes: this.scopes
79
+ }, this.cachedToken.refreshToken, this.tokenUrl);
80
+ this.cachedToken = this.toOAuthToken(refreshed, this.cachedToken.refreshToken);
81
+ await this.persistToken();
82
+ return { Authorization: `Bearer ${this.cachedToken.accessToken}` };
83
+ } catch (error) {
84
+ debugLogger.debug(`[OAuth2AuthProvider] Refresh failed, falling back to interactive flow: ${getErrorMessage(error)}`);
85
+ await this.tokenStorage.deleteCredentials(this.agentName);
86
+ }
87
+ }
88
+ this.cachedToken = await this.authenticateInteractively();
89
+ return { Authorization: `Bearer ${this.cachedToken.accessToken}` };
90
+ }
91
+ /**
92
+ * On 401/403, clear the cached token and re-authenticate (up to MAX_AUTH_RETRIES).
93
+ */
94
+ async shouldRetryWithHeaders(_req, res) {
95
+ if (res.status !== 401 && res.status !== 403) {
96
+ this.authRetryCount = 0;
97
+ return void 0;
98
+ }
99
+ if (this.authRetryCount >= BaseA2AAuthProvider.MAX_AUTH_RETRIES) {
100
+ return void 0;
101
+ }
102
+ this.authRetryCount++;
103
+ debugLogger.debug("[OAuth2AuthProvider] Auth failure, clearing token and re-authenticating");
104
+ this.cachedToken = null;
105
+ await this.tokenStorage.deleteCredentials(this.agentName);
106
+ return this.headers();
107
+ }
108
+ // ---------------------------------------------------------------------------
109
+ // Private helpers
110
+ // ---------------------------------------------------------------------------
111
+ /**
112
+ * Merge authorization_url, token_url, and scopes from the agent card's
113
+ * `securitySchemes` when not already provided via user config.
114
+ */
115
+ mergeAgentCardDefaults(agentCard) {
116
+ if (!agentCard?.securitySchemes)
117
+ return;
118
+ for (const scheme of Object.values(agentCard.securitySchemes)) {
119
+ if (scheme.type === "oauth2" && scheme.flows.authorizationCode) {
120
+ const flow = scheme.flows.authorizationCode;
121
+ this.authorizationUrl ??= flow.authorizationUrl;
122
+ this.tokenUrl ??= flow.tokenUrl;
123
+ this.scopes ??= Object.keys(flow.scopes);
124
+ break;
125
+ }
126
+ }
127
+ }
128
+ /**
129
+ * Fetch the agent card from `agentCardUrl` using `DefaultAgentCardResolver`
130
+ * (which normalizes proto-format cards) and extract OAuth2 URLs.
131
+ */
132
+ async fetchAgentCardDefaults() {
133
+ if (!this.agentCardUrl)
134
+ return;
135
+ try {
136
+ debugLogger.debug(`[OAuth2AuthProvider] Fetching agent card from ${this.agentCardUrl}`);
137
+ const resolver = new DefaultAgentCardResolver();
138
+ const card = await resolver.resolve(this.agentCardUrl, "");
139
+ this.mergeAgentCardDefaults(card);
140
+ } catch (error) {
141
+ debugLogger.warn(`[OAuth2AuthProvider] Could not fetch agent card for OAuth URL discovery: ${getErrorMessage(error)}`);
142
+ }
143
+ }
144
+ /**
145
+ * Run a full OAuth 2.0 Authorization Code + PKCE flow through the browser.
146
+ */
147
+ async authenticateInteractively() {
148
+ if (!this.config.client_id) {
149
+ throw new Error(`OAuth2 authentication for agent "${this.agentName}" requires a client_id. Add client_id to the auth config in your agent definition.`);
150
+ }
151
+ if (!this.authorizationUrl || !this.tokenUrl) {
152
+ 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.`);
153
+ }
154
+ const flowConfig = {
155
+ clientId: this.config.client_id,
156
+ clientSecret: this.config.client_secret,
157
+ authorizationUrl: this.authorizationUrl,
158
+ tokenUrl: this.tokenUrl,
159
+ scopes: this.scopes
160
+ };
161
+ const pkceParams = generatePKCEParams();
162
+ const preferredPort = getPortFromUrl(flowConfig.redirectUri);
163
+ const callbackServer = startCallbackServer(pkceParams.state, preferredPort);
164
+ const redirectPort = await callbackServer.port;
165
+ const authUrl = buildAuthorizationUrl(
166
+ flowConfig,
167
+ pkceParams,
168
+ redirectPort,
169
+ /* resource= */
170
+ void 0
171
+ );
172
+ const consent = await getConsentForOauth(`Authentication required for A2A agent: '${this.agentName}'.`);
173
+ if (!consent) {
174
+ throw new FatalCancellationError("Authentication cancelled by user.");
175
+ }
176
+ coreEvents.emitFeedback("info", `\u2192 Opening your browser for OAuth sign-in...
177
+
178
+ If the browser does not open, copy and paste this URL into your browser:
179
+ ${authUrl}
180
+
181
+ \u{1F4A1} TIP: Triple-click to select the entire URL, then copy and paste it into your browser.
182
+ \u26A0\uFE0F Make sure to copy the COMPLETE URL - it may wrap across multiple lines.`);
183
+ try {
184
+ await openBrowserSecurely(authUrl);
185
+ } catch (error) {
186
+ debugLogger.warn("Failed to open browser automatically:", getErrorMessage(error));
187
+ }
188
+ const { code } = await callbackServer.response;
189
+ debugLogger.debug("\u2713 Authorization code received, exchanging for tokens...");
190
+ const tokenResponse = await exchangeCodeForToken(
191
+ flowConfig,
192
+ code,
193
+ pkceParams.codeVerifier,
194
+ redirectPort,
195
+ /* resource= */
196
+ void 0
197
+ );
198
+ if (!tokenResponse.access_token) {
199
+ throw new Error("No access token received from token endpoint");
200
+ }
201
+ const token = this.toOAuthToken(tokenResponse);
202
+ this.cachedToken = token;
203
+ await this.persistToken();
204
+ debugLogger.debug("\u2713 OAuth2 authentication successful! Token saved.");
205
+ return token;
206
+ }
207
+ /**
208
+ * Convert an `OAuthTokenResponse` into the internal `OAuthToken` format.
209
+ */
210
+ toOAuthToken(response, fallbackRefreshToken) {
211
+ const token = {
212
+ accessToken: response.access_token,
213
+ tokenType: response.token_type || "Bearer",
214
+ refreshToken: response.refresh_token || fallbackRefreshToken,
215
+ scope: response.scope
216
+ };
217
+ if (response.expires_in) {
218
+ token.expiresAt = Date.now() + response.expires_in * 1e3;
219
+ }
220
+ return token;
221
+ }
222
+ /**
223
+ * Persist the current cached token to disk.
224
+ */
225
+ async persistToken() {
226
+ if (!this.cachedToken)
227
+ return;
228
+ await this.tokenStorage.saveToken(this.agentName, this.cachedToken, this.config.client_id, this.tokenUrl);
229
+ }
230
+ };
231
+ export {
232
+ OAuth2AuthProvider
233
+ };
234
+ /**
235
+ * @license
236
+ * Copyright 2026 Google LLC
237
+ * SPDX-License-Identifier: Apache-2.0
238
+ */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@google/gemini-cli",
3
- "version": "0.35.0-preview.1",
3
+ "version": "0.35.0-preview.2",
4
4
  "description": "Gemini CLI",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {