Compare commits

..

1 Commits

Author SHA1 Message Date
gemini-cli-robot b545258c4c chore(release): v0.45.0-preview.0 2026-05-27 18:59:36 +00:00
24 changed files with 257 additions and 318 deletions
+200 -44
View File
@@ -1,6 +1,6 @@
# Preview release: v0.45.0-preview.0
# Preview release: v0.44.0-preview.0
Released: May 27, 2026
Released: May 22, 2026
Our preview release includes the latest, new, and experimental features. This
release may not be as stable as our [latest weekly release](latest.md).
@@ -13,52 +13,208 @@ npm install -g @google/gemini-cli@preview
## Highlights
- **Context Simplification:** Completed major architectural work to simplify and
optimize how the agent manages and processes session context.
- **A2A Usage Metadata:** The Agent-to-Agent (A2A) interface now exposes
detailed usage metadata, providing better visibility into resource
consumption.
- **Improved Routing:** Updated default auto-routing logic and added bypasses
for certain routing classifiers to prevent orphaned function response errors.
- **Terminal Stability:** Fixed several issues affecting terminal environments,
including Termux relaunch loops and PTY resize errors.
- **Security & Fixes:** Strengthened MCP list security and addressed issues with
session resumption and PTY environment signals.
- **Simplified Modes:** Merged existing Auto modes into a single, unified Auto
mode for a more streamlined user experience.
- **Enhanced Agent Registration:** Improved agent registration logic to
prioritize project-specific agents using a first-wins strategy.
- **New Developer Skills:** Introduced `agent-tui` and `tui-tester` skills to
empower developers with better terminal UI testing and automation
capabilities.
- **Expanded Editor Support:** Added support for Sublime Text and Emacs Client,
providing more flexibility for external editing tasks.
- **Session Management:** Added new session invocation types
(`LocalSessionInvocation`, `RemoteSessionInvocation`) and improved context
recovery across sessions.
## What's Changed
- chore(release): bump version to 0.45.0-nightly.20260521.g854f811be by
- chore(release): bump version to 0.44.0-nightly.20260512.g022e8baef by
@gemini-cli-robot in
[#27362](https://github.com/google-gemini/gemini-cli/pull/27362)
- fix(cli): prevent Termux relaunch and resize remount loops by @saymanq in
[#27110](https://github.com/google-gemini/gemini-cli/pull/27110)
- Feat/a2a expose usage metadata by @jvargassanchez-dot in
[#27288](https://github.com/google-gemini/gemini-cli/pull/27288)
- feat(context): Complete simplification work. by @joshualitt in
[#27345](https://github.com/google-gemini/gemini-cli/pull/27345)
- fix(core): force update_topic tool to execute sequentially by
@jvargassanchez-dot in
[#27357](https://github.com/google-gemini/gemini-cli/pull/27357)
- Changelog for v0.44.0-preview.0 by @gemini-cli-robot in
[#27360](https://github.com/google-gemini/gemini-cli/pull/27360)
- Changelog for v0.43.0 by @gemini-cli-robot in
[#27361](https://github.com/google-gemini/gemini-cli/pull/27361)
- Revert "fix(core): prevent SIGHUP kills in PTY environments" by @bbiggs in
[#27401](https://github.com/google-gemini/gemini-cli/pull/27401)
- fix(cli): filter internal session context from history during resumption by
[#26957](https://github.com/google-gemini/gemini-cli/pull/26957)
- Changelog for v0.42.0 by @gemini-cli-robot in
[#26958](https://github.com/google-gemini/gemini-cli/pull/26958)
- Refactor: Eliminate `no-unsafe-return` suppressions via strict type validation
by @M-DEV-1 in
[#20668](https://github.com/google-gemini/gemini-cli/pull/20668)
- Changelog for v0.43.0-preview.0 by @gemini-cli-robot in
[#26959](https://github.com/google-gemini/gemini-cli/pull/26959)
- feat(core): change agent registration to first-wins and prioritize project by
@adamfweidman in
[#26953](https://github.com/google-gemini/gemini-cli/pull/26953)
- feat(cli): merge Auto modes into a single Auto mode by @DavidAPierce in
[#26714](https://github.com/google-gemini/gemini-cli/pull/26714)
- fix(core): preserve OAuth refresh tokens during rotation and retrieval by
@cocosheng-g in
[#26924](https://github.com/google-gemini/gemini-cli/pull/26924)
- fix(cli): allow keychain auth for --list-sessions and non-interactive mode by
@cocosheng-g in
[#26921](https://github.com/google-gemini/gemini-cli/pull/26921)
- fix(core): handle EISDIR on virtual drives in memory discovery by @cocosheng-g
in [#26985](https://github.com/google-gemini/gemini-cli/pull/26985)
- fix(cli): auto-approve shell redirections in AUTO_EDIT mode by @cocosheng-g in
[#27003](https://github.com/google-gemini/gemini-cli/pull/27003)
- ci: suppress bot comments during standard triage maintenance by @cocosheng-g
in [#27006](https://github.com/google-gemini/gemini-cli/pull/27006)
- fix(core): refresh MCP OAuth token usage after re-auth by @sahilkirad in
[#26312](https://github.com/google-gemini/gemini-cli/pull/26312)
- fix(ui): clamped table column widths by @devr0306 in
[#26991](https://github.com/google-gemini/gemini-cli/pull/26991)
- fix(core): isolate subagent thread context by @akh64bit in
[#26449](https://github.com/google-gemini/gemini-cli/pull/26449)
- chore: add execution permission to scripts/review.sh by @scidomino in
[#27009](https://github.com/google-gemini/gemini-cli/pull/27009)
- fix(core): made context files append instead of replace by @devr0306 in
[#26950](https://github.com/google-gemini/gemini-cli/pull/26950)
- fix: add system PATH fallback for ripgrep resolution (#26777) by @cocosheng-g
in [#26868](https://github.com/google-gemini/gemini-cli/pull/26868)
- chore: clean up launched memory features by @SandyTao520 in
[#26941](https://github.com/google-gemini/gemini-cli/pull/26941)
- fix(core): throttle shell text output and bound live UI buffer by
@emersonbusson in
[#26955](https://github.com/google-gemini/gemini-cli/pull/26955)
- fix(cli): don't crash when an @-mention captures a non-path blob by @ifitisit
in [#25980](https://github.com/google-gemini/gemini-cli/pull/25980)
- fix(core): ensure stable fallback for restricted preview models by @galz10 in
[#26999](https://github.com/google-gemini/gemini-cli/pull/26999)
- feat(core): expose RAG snippets to local log file for debugging by @spencer426
in [#27016](https://github.com/google-gemini/gemini-cli/pull/27016)
- fix(acp/auth): prevent conflicting credentials on enterprise gateways and
support optional API keys natively by @sripasg in
[#27021](https://github.com/google-gemini/gemini-cli/pull/27021)
- fix(core): respect NO_PROXY for network-based MCP servers by @cocosheng-g in
[#27012](https://github.com/google-gemini/gemini-cli/pull/27012)
- fix(cli): resolve permission denied in sandbox on NixOS and other distros by
@cocosheng-g in
[#27004](https://github.com/google-gemini/gemini-cli/pull/27004)
- fix(ui): preserve new line at the end of edit window by @devr0306 in
[#27057](https://github.com/google-gemini/gemini-cli/pull/27057)
- fix(core): ensure Vertex AI sets hasAccessToPreviewModels and remove
aggressive 404 fallback revocation by @galz10 in
[#27067](https://github.com/google-gemini/gemini-cli/pull/27067)
- fix(core): ensure stable admin settings comparison across IPC to prevent
restart loop by @DavidAPierce in
[#27066](https://github.com/google-gemini/gemini-cli/pull/27066)
- fix(deps): update vulnerable dependencies by @scidomino in
[#27062](https://github.com/google-gemini/gemini-cli/pull/27062)
- fix(core): resolve EISDIR errors during file processing (#21527) by @ProthamD
in [#27041](https://github.com/google-gemini/gemini-cli/pull/27041)
- docs(extensions): clarify env var sanitization policy for MCP and ext… by
@galz10 in [#22854](https://github.com/google-gemini/gemini-cli/pull/22854)
- fix(ui): add ENAMETOOLONG and ENOTDIR to exceptions for file parsing errors by
@devr0306 in [#27069](https://github.com/google-gemini/gemini-cli/pull/27069)
- fix(cli): explicitly clear entrypoint when spawning sandbox container by
@cocosheng-g in
[#27059](https://github.com/google-gemini/gemini-cli/pull/27059)
- docs: update sandbox image command by @sjhddh in
[#26774](https://github.com/google-gemini/gemini-cli/pull/26774)
- fix(core): externalize https-proxy-agent to fix proxy support by @sotokisehiro
in [#26361](https://github.com/google-gemini/gemini-cli/pull/26361)
- security: update dependencies to fix critical and high vulnerabilities by
@scidomino in [#27077](https://github.com/google-gemini/gemini-cli/pull/27077)
- Fix/web fetch ctrl c abort by @ProthamD in
[#24320](https://github.com/google-gemini/gemini-cli/pull/24320)
- fix(core): add aliases and thinking config for gemini-3.1 models by
@anishs1207 in
[#27007](https://github.com/google-gemini/gemini-cli/pull/27007)
- fix(core): use hasAccessToPreview for auto model resolution and fix
disappearing models by @DavidAPierce in
[#27112](https://github.com/google-gemini/gemini-cli/pull/27112)
- feat(core): add adk.agentSessionSubagentEnabled flag by @adamfweidman in
[#26947](https://github.com/google-gemini/gemini-cli/pull/26947)
- fix(core): enforce compile-time exhaustiveness in content-utils by
@adamfweidman in
[#27207](https://github.com/google-gemini/gemini-cli/pull/27207)
- feat(skills): add agent-tui and tui-tester skills by @adamfweidman in
[#27121](https://github.com/google-gemini/gemini-cli/pull/27121)
- fix(context): Fix snapshot recovery across sessions. by @joshualitt in
[#26939](https://github.com/google-gemini/gemini-cli/pull/26939)
- fix(core): add unit tests for stableStringify by @devr0306 in
[#27212](https://github.com/google-gemini/gemini-cli/pull/27212)
- fix(core): prefer pwsh.exe over Windows PowerShell 5.1 (#25859) by @kaluchi in
[#25900](https://github.com/google-gemini/gemini-cli/pull/25900)
- feat(core): add LocalSessionInvocation by @adamfweidman in
[#26665](https://github.com/google-gemini/gemini-cli/pull/26665)
- refactor: decouple auto model description and configuration from
releaseChannel by @danielweis in
[#27227](https://github.com/google-gemini/gemini-cli/pull/27227)
- fix(core): prevent isBinary false-positive on Windows PTY streams by
@TirthNaik-99 in
[#26565](https://github.com/google-gemini/gemini-cli/pull/26565)
- fix(cli): Prevent unmapped keys in Vim Normal mode from inserting text into
prompt Input. by @Rajeshpatel07 in
[#25139](https://github.com/google-gemini/gemini-cli/pull/25139)
- fix(a2a-server): Implement default policy loading for parity with CLI by
@kschaab in [#27073](https://github.com/google-gemini/gemini-cli/pull/27073)
- feat(core): add RemoteSessionInvocation by @adamfweidman in
[#26937](https://github.com/google-gemini/gemini-cli/pull/26937)
- fix: allow configured MCP servers in non-interactive mode by @cocosheng-g in
[#27215](https://github.com/google-gemini/gemini-cli/pull/27215)
- fix(core): add exception handling to migrateFromFileStorage by @devr0306 in
[#27229](https://github.com/google-gemini/gemini-cli/pull/27229)
- fix(cli): bundle ink worker-entry.js by @rmedranollamas in
[#27249](https://github.com/google-gemini/gemini-cli/pull/27249)
- feat(core): wire AgentSession invocations into agent-tool by @adamfweidman in
[#26948](https://github.com/google-gemini/gemini-cli/pull/26948)
- fix(core): prevent path traversal in custome command file injection by
@ompatel-aiml in
[#27234](https://github.com/google-gemini/gemini-cli/pull/27234)
- fix(core): respect NO_PROXY in global fetch dispatcher by @cocosheng-g in
[#27216](https://github.com/google-gemini/gemini-cli/pull/27216)
- fix(core): correctly handle nullable array types in MCP tools by @devr0306 in
[#27228](https://github.com/google-gemini/gemini-cli/pull/27228)
- fix(cli): preserve proxy-agent named exports in ESM bundle by @ashishch432 in
[#27145](https://github.com/google-gemini/gemini-cli/pull/27145)
- Proposal: deterministic encoding for child-process I/O by @kaluchi in
[#27247](https://github.com/google-gemini/gemini-cli/pull/27247)
- feat(cli): add Sublime Text and Emacs Client editors, improve error messages
and documentation by @alberti42 in
[#21090](https://github.com/google-gemini/gemini-cli/pull/21090)
- Changelog for v0.43.0-preview.1 by @gemini-cli-robot in
[#27297](https://github.com/google-gemini/gemini-cli/pull/27297)
- fix(devtools): bundle devtools package to avoid resolution errors by
@rmedranollamas in
[#27391](https://github.com/google-gemini/gemini-cli/pull/27391)
- Update default auto routing by @DavidAPierce in
[#27071](https://github.com/google-gemini/gemini-cli/pull/27071)
- fix(core): bypass routing classifiers to prevent orphaned function response
errors by @danielweis in
[#27389](https://github.com/google-gemini/gemini-cli/pull/27389)
- fix(core): suppress PTY resize EBADF errors by @scidomino in
[#27461](https://github.com/google-gemini/gemini-cli/pull/27461)
- fix(core): prevent blacklist bypass in mcp list by @ompatel-aiml in
[#27377](https://github.com/google-gemini/gemini-cli/pull/27377)
- fix(cli): ignore unmapped vim normal keys by @MukundaKatta in
[#27102](https://github.com/google-gemini/gemini-cli/pull/27102)
[#27250](https://github.com/google-gemini/gemini-cli/pull/27250)
- fix(cli): integrate PolicyEngine into ACP session to prevent deadlocks
(#23507) by @cocosheng-g in
[#27252](https://github.com/google-gemini/gemini-cli/pull/27252)
- fix: robust ripgrep path resolution and 1p hermetic execution support by
@cocosheng-g in
[#27253](https://github.com/google-gemini/gemini-cli/pull/27253)
- refactor: decouple stored session deletion from ChatRecordingService (#22920)
by @yuvrajangadsingh in
[#27039](https://github.com/google-gemini/gemini-cli/pull/27039)
- fix(core): improve Alpine shell compatibility by @dibyx in
[#26770](https://github.com/google-gemini/gemini-cli/pull/26770)
- fix(core): generalize MCP compliance fix for tool results by @cocosheng-g in
[#27045](https://github.com/google-gemini/gemini-cli/pull/27045)
- fix(scripts): scrub CI env vars in dev to keep interactive mode by @Hashaam101
in [#27159](https://github.com/google-gemini/gemini-cli/pull/27159)
- fix(core): Added date field for the GCal MCP by @devr0306 in
[#27251](https://github.com/google-gemini/gemini-cli/pull/27251)
- fix(core): centralize path validation to prevent crashes from malformed
prompts by @cocosheng-g in
[#27211](https://github.com/google-gemini/gemini-cli/pull/27211)
- fix(core): prevent SIGHUP kills in PTY environments (WSL2/Kitty/Alacritty) by
@ProthamD in [#27267](https://github.com/google-gemini/gemini-cli/pull/27267)
- fix(core): dynamic fallback routing for exhausted quota models by @cocosheng-g
in [#27315](https://github.com/google-gemini/gemini-cli/pull/27315)
- Auto detect pnpm global installation path for macOS and Windows by @tisonkun
in [#22748](https://github.com/google-gemini/gemini-cli/pull/22748)
- fix(windows): resolve interactive shell arrow-key navigation on Windows by
@KumarADITHYA123 in
[#23505](https://github.com/google-gemini/gemini-cli/pull/23505)
- ci: robust stale issue lifecycle and consolidated triage labels by
@cocosheng-g in
[#27015](https://github.com/google-gemini/gemini-cli/pull/27015)
- fix(context): Ensure last message is processed. by @joshualitt in
[#27232](https://github.com/google-gemini/gemini-cli/pull/27232)
- chore/release: bump version to 0.44.0-nightly.20260521.g57c42a5c4 by
@gemini-cli-robot in
[#27324](https://github.com/google-gemini/gemini-cli/pull/27324)
- fix(ui): added volta to auto update check by @devr0306 in
[#27353](https://github.com/google-gemini/gemini-cli/pull/27353)
- perf: optimize issue triage and lifecycle management by @cocosheng-g in
[#27346](https://github.com/google-gemini/gemini-cli/pull/27346)
**Full Changelog**:
https://github.com/google-gemini/gemini-cli/compare/v0.44.0-preview.0...v0.45.0-preview.0
https://github.com/google-gemini/gemini-cli/compare/v0.43.0-preview.1...v0.44.0-preview.0
+9 -9
View File
@@ -1,12 +1,12 @@
{
"name": "@google/gemini-cli",
"version": "0.45.0-nightly.20260521.g854f811be",
"version": "0.45.0-preview.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@google/gemini-cli",
"version": "0.45.0-nightly.20260521.g854f811be",
"version": "0.45.0-preview.0",
"workspaces": [
"packages/*"
],
@@ -18117,7 +18117,7 @@
},
"packages/a2a-server": {
"name": "@google/gemini-cli-a2a-server",
"version": "0.45.0-nightly.20260521.g854f811be",
"version": "0.45.0-preview.0",
"dependencies": {
"@a2a-js/sdk": "0.3.11",
"@google-cloud/storage": "^7.19.0",
@@ -18246,7 +18246,7 @@
},
"packages/cli": {
"name": "@google/gemini-cli",
"version": "0.45.0-nightly.20260521.g854f811be",
"version": "0.45.0-preview.0",
"license": "Apache-2.0",
"dependencies": {
"@agentclientprotocol/sdk": "^0.16.1",
@@ -18394,7 +18394,7 @@
},
"packages/core": {
"name": "@google/gemini-cli-core",
"version": "0.45.0-nightly.20260521.g854f811be",
"version": "0.45.0-preview.0",
"license": "Apache-2.0",
"dependencies": {
"@a2a-js/sdk": "0.3.11",
@@ -18674,7 +18674,7 @@
},
"packages/devtools": {
"name": "@google/gemini-cli-devtools",
"version": "0.45.0-nightly.20260521.g854f811be",
"version": "0.45.0-preview.0",
"license": "Apache-2.0",
"dependencies": {
"ws": "^8.16.0"
@@ -18689,7 +18689,7 @@
},
"packages/sdk": {
"name": "@google/gemini-cli-sdk",
"version": "0.45.0-nightly.20260521.g854f811be",
"version": "0.45.0-preview.0",
"license": "Apache-2.0",
"dependencies": {
"@google/gemini-cli-core": "file:../core",
@@ -18720,7 +18720,7 @@
},
"packages/test-utils": {
"name": "@google/gemini-cli-test-utils",
"version": "0.45.0-nightly.20260521.g854f811be",
"version": "0.45.0-preview.0",
"license": "Apache-2.0",
"dependencies": {
"@google/gemini-cli-core": "file:../core",
@@ -18752,7 +18752,7 @@
},
"packages/vscode-ide-companion": {
"name": "gemini-cli-vscode-ide-companion",
"version": "0.45.0-nightly.20260521.g854f811be",
"version": "0.45.0-preview.0",
"license": "LICENSE",
"dependencies": {
"@modelcontextprotocol/sdk": "^1.23.0",
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@google/gemini-cli",
"version": "0.45.0-nightly.20260521.g854f811be",
"version": "0.45.0-preview.0",
"engines": {
"node": ">=20.0.0"
},
@@ -14,7 +14,7 @@
"url": "git+https://github.com/google-gemini/gemini-cli.git"
},
"config": {
"sandboxImageUri": "us-docker.pkg.dev/gemini-code-dev/gemini-cli/sandbox:0.45.0-nightly.20260521.g854f811be"
"sandboxImageUri": "us-docker.pkg.dev/gemini-code-dev/gemini-cli/sandbox:0.45.0-preview.0"
},
"scripts": {
"start": "cross-env NODE_ENV=development node scripts/start.js",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@google/gemini-cli-a2a-server",
"version": "0.45.0-nightly.20260521.g854f811be",
"version": "0.45.0-preview.0",
"description": "Gemini CLI A2A Server",
"repository": {
"type": "git",
+2 -5
View File
@@ -21,12 +21,9 @@ import {
// Tracking bug: https://github.com/microsoft/node-pty/issues/827
process.on('uncaughtException', (error) => {
if (error instanceof Error) {
const message = error.message || '';
const isPtyResizeError =
message === 'Cannot resize a pty that has already exited';
const isEbadfError =
message.includes('EBADF') ||
(error as { code?: string }).code === 'EBADF';
error.message === 'Cannot resize a pty that has already exited';
const isEbadfError = error.message.includes('EBADF');
const isFromNodePty =
error.stack?.includes('node-pty') || error.stack?.includes('PtyResize');
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@google/gemini-cli",
"version": "0.45.0-nightly.20260521.g854f811be",
"version": "0.45.0-preview.0",
"description": "Gemini CLI",
"license": "Apache-2.0",
"repository": {
@@ -27,7 +27,7 @@
"dist"
],
"config": {
"sandboxImageUri": "us-docker.pkg.dev/gemini-code-dev/gemini-cli/sandbox:0.45.0-nightly.20260521.g854f811be"
"sandboxImageUri": "us-docker.pkg.dev/gemini-code-dev/gemini-cli/sandbox:0.45.0-preview.0"
},
"dependencies": {
"@agentclientprotocol/sdk": "^0.16.1",
+10 -115
View File
@@ -7,7 +7,6 @@
import { AuthType } from '@google/gemini-cli-core';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { validateAuthMethod } from './auth.js';
import fs from 'node:fs';
vi.mock('@google/gemini-cli-core', async (importOriginal) => {
const actual =
@@ -18,30 +17,11 @@ vi.mock('@google/gemini-cli-core', async (importOriginal) => {
};
});
const { mockSettings } = vi.hoisted(() => ({
mockSettings: {
merged: {
security: {
auth: {
byoidConfigPath: undefined as string | undefined,
},
},
experimental: {
byoid: false as boolean,
},
},
},
}));
vi.mock('./settings.js', () => ({
loadEnvironment: vi.fn(),
loadSettings: vi.fn(() => mockSettings),
}));
vi.mock('node:fs', () => ({
default: {
existsSync: vi.fn(),
},
loadSettings: vi.fn().mockReturnValue({
merged: vi.fn().mockReturnValue({}),
}),
}));
describe('validateAuthMethod', () => {
@@ -50,13 +30,10 @@ describe('validateAuthMethod', () => {
vi.stubEnv('GOOGLE_CLOUD_PROJECT', undefined);
vi.stubEnv('GOOGLE_CLOUD_LOCATION', undefined);
vi.stubEnv('GOOGLE_API_KEY', undefined);
mockSettings.merged.security.auth.byoidConfigPath = undefined;
mockSettings.merged.experimental.byoid = false;
});
afterEach(() => {
vi.unstubAllEnvs();
vi.clearAllMocks();
});
it.each([
@@ -115,99 +92,17 @@ describe('validateAuthMethod', () => {
'• GOOGLE_API_KEY environment variable (if using express mode).\n' +
'Update your environment and try again (no reload needed if using .env)!',
},
{
description:
'should return null for BYOID if experimental.byoid is true, and byoidConfigPath is set and exists',
authType: AuthType.BYOID,
envs: {},
byoidEnabled: true,
byoidConfigPath: '/path/to/config',
fsExists: true,
expected: null,
},
{
description:
'should return error for BYOID if experimental.byoid is false',
authType: AuthType.BYOID,
envs: {},
byoidEnabled: false,
expected:
'BYOID authentication is experimental and must be enabled via experimental.byoid in settings.',
},
{
description:
'should return error for BYOID if byoidConfigPath is not set',
authType: AuthType.BYOID,
envs: {},
byoidEnabled: true,
expected:
'When using BYOID, you must specify the security.auth.byoidConfigPath setting.\n' +
'Update your settings and try again!',
},
{
description:
'should return error for BYOID if byoidConfigPath does not exist',
authType: AuthType.BYOID,
envs: {},
byoidEnabled: true,
byoidConfigPath: '/non/existent/path',
fsExists: false,
expected: 'BYOID configuration file not found at: /non/existent/path',
},
{
description:
'should return null for BYOID if experimentalByoid argument is true, even if settings are false',
authType: AuthType.BYOID,
envs: {},
experimentalByoidArg: true,
byoidEnabled: false,
byoidConfigPath: '/path/to/config',
fsExists: true,
expected: null,
},
{
description:
'should return error for BYOID if experimentalByoid argument is false and settings are false',
authType: AuthType.BYOID,
envs: {},
experimentalByoidArg: false,
byoidEnabled: false,
expected:
'BYOID authentication is experimental and must be enabled via experimental.byoid in settings.',
},
{
description: 'should return an error message for an invalid auth method',
// eslint-disable-next-line @typescript-eslint/no-explicit-any
authType: 'invalid' as any,
authType: 'invalid-method' as any,
envs: {},
expected: 'Invalid auth method selected.',
},
])(
'$description',
async ({
authType,
envs,
expected,
byoidConfigPath,
fsExists,
byoidEnabled,
experimentalByoidArg,
}) => {
for (const [key, value] of Object.entries(envs)) {
vi.stubEnv(key, value as string);
}
if (byoidConfigPath !== undefined) {
mockSettings.merged.security.auth.byoidConfigPath = byoidConfigPath;
}
if (byoidEnabled !== undefined) {
mockSettings.merged.experimental.byoid = byoidEnabled;
}
if (fsExists !== undefined) {
vi.mocked(fs.existsSync).mockReturnValue(fsExists);
}
expect(await validateAuthMethod(authType, experimentalByoidArg)).toBe(
expected,
);
},
);
])('$description', async ({ authType, envs, expected }) => {
for (const [key, value] of Object.entries(envs)) {
vi.stubEnv(key, value as string);
}
expect(await validateAuthMethod(authType)).toBe(expected);
});
});
+1 -24
View File
@@ -6,14 +6,11 @@
import { AuthType, loadApiKey } from '@google/gemini-cli-core';
import { loadEnvironment, loadSettings } from './settings.js';
import fs from 'node:fs';
export async function validateAuthMethod(
authMethod: string,
experimentalByoid?: boolean,
): Promise<string | null> {
const settings = loadSettings();
loadEnvironment(settings.merged, process.cwd());
loadEnvironment(loadSettings().merged, process.cwd());
if (
authMethod === AuthType.LOGIN_WITH_GOOGLE ||
authMethod === AuthType.COMPUTE_ADC
@@ -48,25 +45,5 @@ export async function validateAuthMethod(
return null;
}
if (authMethod === AuthType.BYOID) {
const isByoidEnabled =
experimentalByoid || settings.merged.experimental?.byoid;
if (!isByoidEnabled) {
return 'BYOID authentication is experimental and must be enabled via experimental.byoid in settings.';
}
const configPath = settings.merged.security.auth.byoidConfigPath;
if (!configPath) {
return (
'When using BYOID, you must specify the security.auth.byoidConfigPath setting.\n' +
'Update your settings and try again!'
);
}
if (!fs.existsSync(configPath)) {
return `BYOID configuration file not found at: ${configPath}`;
}
return null;
}
return 'Invalid auth method selected.';
}
-7
View File
@@ -91,7 +91,6 @@ export interface CliArgs {
allowedTools: string[] | undefined;
acp?: boolean;
experimentalAcp?: boolean;
experimentalByoid?: boolean;
extensions: string[] | undefined;
listExtensions: boolean | undefined;
resume: string | typeof RESUME_LATEST | undefined;
@@ -369,10 +368,6 @@ export async function parseArguments(
description:
'Starts the agent in ACP mode (deprecated, use --acp instead)',
})
.option('experimental-byoid', {
type: 'boolean',
description: 'Enable experimental support for BYOID authentication',
})
.option('allowed-mcp-server-names', {
type: 'array',
string: true,
@@ -1060,7 +1055,6 @@ export async function loadCliConfig(
disabledSkills: settings.skills?.disabled,
experimentalAutoMemory: settings.experimental?.autoMemory,
experimentalGemma: settings.experimental?.gemma,
experimentalByoid: argv.experimentalByoid || settings.experimental?.byoid,
contextManagement,
modelSteering: settings.experimental?.modelSteering,
topicUpdateNarration:
@@ -1127,7 +1121,6 @@ export async function loadCliConfig(
};
},
enableConseca: settings.security?.enableConseca,
byoidConfigPath: settings.security?.auth?.byoidConfigPath,
});
}
@@ -131,7 +131,6 @@ export class ExtensionManager extends ExtensionLoader {
cwd: options.workspaceDir,
model: '',
debugMode: false,
byoidConfigPath: options.settings.security?.auth?.byoidConfigPath,
});
this.requestConsent = options.requestConsent;
this.requestSetting = options.requestSetting ?? undefined;
-20
View File
@@ -2002,16 +2002,6 @@ const SETTINGS_SCHEMA = {
description: 'Whether to use an external authentication flow.',
showInDialog: false,
},
byoidConfigPath: {
type: 'string',
label: 'BYOID Configuration Path',
category: 'Security',
requiresRestart: true,
default: undefined as string | undefined,
description:
'Path to the BYOID (Bring Your Own IDentifier) configuration file.',
showInDialog: true,
},
},
},
enableConseca: {
@@ -2477,16 +2467,6 @@ const SETTINGS_SCHEMA = {
description: 'Enable logic for context management.',
showInDialog: true,
},
byoid: {
type: 'boolean',
label: 'Enable BYOID Auth',
category: 'Experimental',
requiresRestart: true,
default: false,
description:
'Enable experimental support for BYOID (Bring Your Own IDentifier) authentication.',
showInDialog: true,
},
topicUpdateNarration: {
type: 'boolean',
label: 'Topic & Update Narration',
-1
View File
@@ -516,7 +516,6 @@ export async function main() {
) {
const err = await validateAuthMethod(
settings.merged.security.auth.selectedType,
partialConfig.isExperimentalByoidEnabled(),
);
if (err) {
throw new Error(err);
+1 -5
View File
@@ -912,10 +912,7 @@ Logging in with Google... Restarting Gemini CLI to continue.
const authMethod = settings.merged.security.auth.selectedType;
void (async () => {
try {
const error = await validateAuthMethod(
authMethod,
config.isExperimentalByoidEnabled(),
);
const error = await validateAuthMethod(authMethod);
if (
error &&
authMethod === settings.merged.security.auth.selectedType
@@ -934,7 +931,6 @@ Logging in with Google... Restarting Gemini CLI to continue.
settings.merged.security.auth.enforcedType,
settings.merged.security.auth.useExternal,
onAuthError,
config,
]);
const { isModelDialogOpen, openModelDialog, closeModelDialog } =
+1 -3
View File
@@ -21,7 +21,6 @@ import { validateAuthMethod } from '../../config/auth.js';
export async function validateAuthMethodWithSettings(
authType: AuthType,
settings: LoadedSettings,
config?: Config,
): Promise<string | null> {
const enforcedType = settings.merged.security.auth.enforcedType;
if (enforcedType && enforcedType !== authType) {
@@ -34,7 +33,7 @@ export async function validateAuthMethodWithSettings(
if (authType === AuthType.USE_GEMINI) {
return null;
}
return validateAuthMethod(authType, config?.isExperimentalByoidEnabled());
return validateAuthMethod(authType);
}
import type { AccountSuspensionInfo } from '../contexts/UIStateContext.js';
@@ -115,7 +114,6 @@ export const useAuthCommand = (
const error = await validateAuthMethodWithSettings(
authType,
settings,
config,
).catch((e: unknown) => getErrorMessage(e));
if (error) {
@@ -42,10 +42,7 @@ export async function validateNonInteractiveAuth(
const authType: AuthType = effectiveAuthType;
if (!useExternalAuth) {
const err = await validateAuthMethod(
String(authType),
nonInteractiveConfig.isExperimentalByoidEnabled(),
);
const err = await validateAuthMethod(String(authType));
if (err != null) {
throw new Error(err);
}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@google/gemini-cli-core",
"version": "0.45.0-nightly.20260521.g854f811be",
"version": "0.45.0-preview.0",
"description": "Gemini CLI Core",
"license": "Apache-2.0",
"repository": {
+1 -2
View File
@@ -19,8 +19,7 @@ export async function createCodeAssistContentGenerator(
): Promise<ContentGenerator> {
if (
authType === AuthType.LOGIN_WITH_GOOGLE ||
authType === AuthType.COMPUTE_ADC ||
authType === AuthType.BYOID
authType === AuthType.COMPUTE_ADC
) {
const authClient = await getOauthClient(authType, config);
const userData = await setupUser(authClient, config, httpOptions);
-18
View File
@@ -715,7 +715,6 @@ export interface ConfigParameters {
autoDistillation?: boolean;
experimentalAutoMemory?: boolean;
experimentalGemma?: boolean;
experimentalByoid?: boolean;
experimentalContextManagementConfig?: string;
experimentalAgentHistoryTruncation?: boolean;
experimentalAgentHistoryTruncationThreshold?: number;
@@ -745,7 +744,6 @@ export interface ConfigParameters {
};
vertexAiRouting?: VertexAiRoutingConfig;
logRagSnippets?: boolean;
byoidConfigPath?: string;
}
export class Config implements McpContext, AgentLoopContext {
@@ -958,7 +956,6 @@ export class Config implements McpContext, AgentLoopContext {
overageStrategy: OverageStrategy;
};
private readonly vertexAiRouting: VertexAiRoutingConfig | undefined;
private readonly byoidConfigPath: string | undefined;
private readonly enableAgents: boolean;
private agents: AgentSettings;
@@ -968,7 +965,6 @@ export class Config implements McpContext, AgentLoopContext {
private readonly adminSkillsEnabled: boolean;
private readonly experimentalAutoMemory: boolean;
private readonly experimentalGemma: boolean;
private readonly experimentalByoid: boolean;
private readonly experimentalContextManagementConfig?: string;
private readonly memoryBoundaryMarkers: readonly string[];
private readonly topicUpdateNarration: boolean;
@@ -1190,7 +1186,6 @@ export class Config implements McpContext, AgentLoopContext {
this.experimentalAutoMemory = params.experimentalAutoMemory ?? false;
this.experimentalGemma = params.experimentalGemma ?? true;
this.experimentalByoid = params.experimentalByoid ?? false;
this.experimentalContextManagementConfig =
params.experimentalContextManagementConfig;
this.memoryBoundaryMarkers = params.memoryBoundaryMarkers ?? ['.git'];
@@ -1603,7 +1598,6 @@ export class Config implements McpContext, AgentLoopContext {
baseUrl,
customHeaders,
this.vertexAiRouting,
this.byoidConfigPath,
);
this.contentGenerator = await createContentGenerator(
newContentGeneratorConfig,
@@ -2658,10 +2652,6 @@ export class Config implements McpContext, AgentLoopContext {
return this.modelSteering;
}
isExperimentalByoidEnabled(): boolean {
return this.experimentalByoid;
}
async getToolOutputMaskingConfig(): Promise<ToolOutputMaskingConfig> {
await this.ensureExperimentsLoaded();
@@ -4146,14 +4136,6 @@ export class Config implements McpContext, AgentLoopContext {
await this.mcpClientManager.stop();
}
}
isExperimentalByoidEnabled(): boolean {
return this.experimentalByoid;
}
getByoidConfigPath(): string | undefined {
return this.byoidConfigPath;
}
}
// Export model constants for use in CLI
export { DEFAULT_GEMINI_FLASH_MODEL };
+2 -16
View File
@@ -65,7 +65,6 @@ export enum AuthType {
LEGACY_CLOUD_SHELL = 'cloud-shell',
COMPUTE_ADC = 'compute-default-credentials',
GATEWAY = 'gateway',
BYOID = 'byoid',
}
/**
@@ -106,7 +105,6 @@ export type ContentGeneratorConfig = {
baseUrl?: string;
customHeaders?: Record<string, string>;
vertexAiRouting?: VertexAiRoutingConfig;
byoidConfigPath?: string;
};
export type VertexAiRequestType = 'dedicated' | 'shared';
@@ -136,7 +134,6 @@ export async function createContentGeneratorConfig(
baseUrl?: string,
customHeaders?: Record<string, string>,
vertexAiRouting?: VertexAiRoutingConfig,
byoidConfigPath?: string,
): Promise<ContentGeneratorConfig> {
const contentGeneratorConfig: ContentGeneratorConfig = {
authType,
@@ -144,7 +141,6 @@ export async function createContentGeneratorConfig(
baseUrl,
customHeaders,
vertexAiRouting,
byoidConfigPath,
};
// If we are using Google auth or we are in Cloud Shell, there is nothing else to validate for now.
@@ -152,8 +148,7 @@ export async function createContentGeneratorConfig(
// (WSL/SSH/Docker/CI) keytar can block indefinitely on its functional probe.
if (
authType === AuthType.LOGIN_WITH_GOOGLE ||
authType === AuthType.COMPUTE_ADC ||
authType === AuthType.BYOID
authType === AuthType.COMPUTE_ADC
) {
return contentGeneratorConfig;
}
@@ -282,17 +277,8 @@ export async function createContentGenerator(
}
if (
config.authType === AuthType.LOGIN_WITH_GOOGLE ||
config.authType === AuthType.COMPUTE_ADC ||
config.authType === AuthType.BYOID
config.authType === AuthType.COMPUTE_ADC
) {
if (
config.authType === AuthType.BYOID &&
!gcConfig.isExperimentalByoidEnabled()
) {
throw new Error(
'BYOID authentication is experimental and must be enabled via the experimentalByoid flag.',
);
}
const httpOptions = { headers: baseHeaders };
return new LoggingContentGenerator(
await createCodeAssistContentGenerator(
@@ -37,7 +37,6 @@ import {
} from './sandboxManager.js';
import type { SandboxConfig } from '../config/config.js';
import { killProcessGroup } from '../utils/process-utils.js';
import { isNodeError } from '../utils/errors.js';
import {
ExecutionLifecycleService,
type ExecutionHandle,
@@ -1508,45 +1507,31 @@ export class ShellExecutionService {
}
const activePty = this.activePtys.get(pid);
if (!activePty) {
return;
}
// Skip Windows: process.kill(pid, 0) is heavy and native errors are catchable there.
if (process.platform !== 'win32') {
if (activePty) {
try {
process.kill(pid, 0);
activePty.ptyProcess.resize(cols, rows);
activePty.headlessTerminal.resize(cols, rows);
} catch (e) {
// Bail only if the process is explicitly confirmed dead (ESRCH).
if (isNodeError(e) && e.code === 'ESRCH') {
return;
// Ignore errors if the pty has already exited, which can happen
// due to a race condition between the exit event and this call.
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
const err = e as { code?: string; message?: string };
const isEsrch = err.code === 'ESRCH';
const isEbadf = err.code === 'EBADF' || err.message?.includes('EBADF');
const isWindowsPtyError = err.message?.includes(
'Cannot resize a pty that has already exited',
);
if (isEsrch || isEbadf || isWindowsPtyError) {
// On Unix, we get an ESRCH or EBADF error.
// On Windows, we get a message-based error.
// In both cases, it's safe to ignore.
} else {
throw e;
}
}
}
try {
activePty.ptyProcess.resize(cols, rows);
activePty.headlessTerminal.resize(cols, rows);
} catch (e) {
// Ignore errors if the pty has already exited, which can happen
// due to a race condition between the exit event and this call.
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
const err = e as { code?: string; message?: string };
const isEsrch = err.code === 'ESRCH';
const isEbadf = err.code === 'EBADF' || err.message?.includes('EBADF');
const isWindowsPtyError = err.message?.includes(
'Cannot resize a pty that has already exited',
);
if (isEsrch || isEbadf || isWindowsPtyError) {
// On Unix, we get an ESRCH or EBADF error.
// On Windows, we get a message-based error.
// In both cases, it's safe to ignore.
} else {
throw e;
}
}
// Force emit the new state after resize
if (activePty) {
const endLine = activePty.headlessTerminal.buffer.active.length;
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@google/gemini-cli-devtools",
"version": "0.45.0-nightly.20260521.g854f811be",
"version": "0.45.0-preview.0",
"license": "Apache-2.0",
"type": "module",
"main": "dist/src/index.js",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@google/gemini-cli-sdk",
"version": "0.45.0-nightly.20260521.g854f811be",
"version": "0.45.0-preview.0",
"description": "Gemini CLI SDK",
"license": "Apache-2.0",
"repository": {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@google/gemini-cli-test-utils",
"version": "0.45.0-nightly.20260521.g854f811be",
"version": "0.45.0-preview.0",
"private": true,
"main": "src/index.ts",
"license": "Apache-2.0",
+1 -1
View File
@@ -2,7 +2,7 @@
"name": "gemini-cli-vscode-ide-companion",
"displayName": "Gemini CLI Companion",
"description": "Enable Gemini CLI with direct access to your IDE workspace.",
"version": "0.45.0-nightly.20260521.g854f811be",
"version": "0.45.0-preview.0",
"publisher": "google",
"icon": "assets/icon.png",
"repository": {