Compare commits

..

2 Commits

73 changed files with 989 additions and 1819 deletions
-65
View File
@@ -1,65 +0,0 @@
---
name: code-reviewer
description:
Use this skill to review code. It supports both local changes (staged or working tree)
and remote Pull Requests (by ID or URL). It focuses on correctness, maintainability,
and adherence to project standards.
---
# Code Reviewer
This skill guides the agent in conducting professional and thorough code reviews for both local development and remote Pull Requests.
## Workflow
### 1. Determine Review Target
* **Remote PR**: If the user provides a PR number or URL (e.g., "Review PR #123"), target that remote PR.
* **Local Changes**: If no specific PR is mentioned, or if the user asks to "review my changes", target the current local file system states (staged and unstaged changes).
### 2. Preparation
#### For Remote PRs:
1. **Checkout**: Use the GitHub CLI to checkout the PR.
```bash
gh pr checkout <PR_NUMBER>
```
2. **Preflight**: Execute the project's standard verification suite to catch automated failures early.
```bash
npm run preflight
```
3. **Context**: Read the PR description and any existing comments to understand the goal and history.
#### For Local Changes:
1. **Identify Changes**:
* Check status: `git status`
* Read diffs: `git diff` (working tree) and/or `git diff --staged` (staged).
2. **Preflight (Optional)**: If the changes are substantial, ask the user if they want to run `npm run preflight` before reviewing.
### 3. In-Depth Analysis
Analyze the code changes based on the following pillars:
* **Correctness**: Does the code achieve its stated purpose without bugs or logical errors?
* **Maintainability**: Is the code clean, well-structured, and easy to understand and modify in the future? Consider factors like code clarity, modularity, and adherence to established design patterns.
* **Readability**: Is the code well-commented (where necessary) and consistently formatted according to our project's coding style guidelines?
* **Efficiency**: Are there any obvious performance bottlenecks or resource inefficiencies introduced by the changes?
* **Security**: Are there any potential security vulnerabilities or insecure coding practices?
* **Edge Cases and Error Handling**: Does the code appropriately handle edge cases and potential errors?
* **Testability**: Is the new or modified code adequately covered by tests (even if preflight checks pass)? Suggest additional test cases that would improve coverage or robustness.
### 4. Provide Feedback
#### Structure
* **Summary**: A high-level overview of the review.
* **Findings**:
* **Critical**: Bugs, security issues, or breaking changes.
* **Improvements**: Suggestions for better code quality or performance.
* **Nitpicks**: Formatting or minor style issues (optional).
* **Conclusion**: Clear recommendation (Approved / Request Changes).
#### Tone
* Be constructive, professional, and friendly.
* Explain *why* a change is requested.
* For approvals, acknowledge the specific value of the contribution.
### 5. Cleanup (Remote PRs only)
* After the review, ask the user if they want to switch back to the default branch (e.g., `main` or `master`).
-3
View File
@@ -22,6 +22,3 @@ Makefile eol=lf
*.eot binary
*.ttf binary
*.otf binary
# Configure GitHub to treat Markdoc files as Markdown
*.mdoc linguist-language=Markdown
+3 -5
View File
@@ -175,7 +175,7 @@ runs:
--dry-run="${INPUTS_DRY_RUN}" \
--workspace="${INPUTS_CORE_PACKAGE_NAME}" \
--no-tag
npm dist-tag rm ${INPUTS_CORE_PACKAGE_NAME} false
npm dist-tag rm ${INPUTS_CORE_PACKAGE_NAME} false --silent
- name: '🔗 Install latest core package'
working-directory: '${{ inputs.working-directory }}'
@@ -221,9 +221,7 @@ runs:
--dry-run="${INPUTS_DRY_RUN}" \
--workspace="${INPUTS_CLI_PACKAGE_NAME}" \
--no-tag
if [[ "${INPUTS_DRY_RUN}" == "false" ]]; then
npm dist-tag rm ${INPUTS_CLI_PACKAGE_NAME} false
fi
npm dist-tag rm ${INPUTS_CLI_PACKAGE_NAME} false --silent
- name: 'Get a2a-server Token'
uses: './.github/actions/npm-auth-token'
@@ -248,7 +246,7 @@ runs:
--dry-run="${INPUTS_DRY_RUN}" \
--workspace="${INPUTS_A2A_PACKAGE_NAME}" \
--no-tag
npm dist-tag rm ${INPUTS_A2A_PACKAGE_NAME} false
npm dist-tag rm ${INPUTS_A2A_PACKAGE_NAME} false --silent
- name: '🔬 Verify NPM release by version'
uses: './.github/actions/verify-release'
+4 -4
View File
@@ -34,7 +34,7 @@ runs:
JSON_INPUTS: '${{ toJSON(inputs) }}'
run: 'echo "$JSON_INPUTS"'
- name: 'Checkout'
uses: 'actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5' # ratchet:actions/checkout@v4
uses: 'actions/checkout@v4'
with:
ref: '${{ inputs.github-sha }}'
fetch-depth: 0
@@ -45,11 +45,11 @@ runs:
shell: 'bash'
run: 'npm run build'
- name: 'Set up QEMU'
uses: 'docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130' # ratchet:docker/setup-qemu-action@v3
uses: 'docker/setup-qemu-action@v3'
- name: 'Set up Docker Buildx'
uses: 'docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f' # ratchet:docker/setup-buildx-action@v3
uses: 'docker/setup-buildx-action@v3'
- name: 'Log in to GitHub Container Registry'
uses: 'docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9' # ratchet:docker/login-action@v3
uses: 'docker/login-action@v3'
with:
registry: 'docker.io'
username: '${{ inputs.dockerhub-username }}'
+1 -1
View File
@@ -36,7 +36,7 @@ runs:
run: 'echo "$JSON_INPUTS"'
- name: 'setup node'
uses: 'actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020' # ratchet:actions/setup-node@v4
uses: 'actions/setup-node@v4'
with:
node-version: '20'
+2 -5
View File
@@ -67,7 +67,7 @@ jobs:
cache: 'npm'
- name: 'Cache Linters'
uses: 'actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830' # ratchet:actions/cache@v4
uses: 'actions/cache@v4'
with:
path: '${{ env.GEMINI_LINT_TEMP_DIR }}'
key: "${{ runner.os }}-${{ runner.arch }}-linters-${{ hashFiles('scripts/lint.js') }}"
@@ -76,7 +76,7 @@ jobs:
run: 'npm ci'
- name: 'Cache ESLint'
uses: 'actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830' # ratchet:actions/cache@v4
uses: 'actions/cache@v4'
with:
path: '.eslintcache'
key: "${{ runner.os }}-eslint-${{ hashFiles('package-lock.json', 'eslint.config.js') }}"
@@ -114,9 +114,6 @@ jobs:
- name: 'Run sensitive keyword linter'
run: 'node scripts/lint.js --sensitive-keywords'
- name: 'Run GitHub Actions pinning linter'
run: 'node scripts/lint.js --check-github-actions-pinning'
link_checker:
name: 'Link Checker'
runs-on: 'ubuntu-latest'
@@ -28,14 +28,14 @@ jobs:
steps:
- name: 'Generate GitHub App Token'
id: 'generate_token'
uses: 'actions/create-github-app-token@fee1f7d63c2ff003460e3d139729b119787bc349' # ratchet:actions/create-github-app-token@v2
uses: 'actions/create-github-app-token@v2'
with:
app-id: '${{ secrets.APP_ID }}'
private-key: '${{ secrets.PRIVATE_KEY }}'
permission-issues: 'write'
- name: 'Process Stale Issues'
uses: 'actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b' # ratchet:actions/github-script@v7
uses: 'actions/github-script@v7'
env:
DRY_RUN: '${{ inputs.dry_run }}'
with:
@@ -27,13 +27,13 @@ jobs:
APP_ID: '${{ secrets.APP_ID }}'
if: |-
${{ env.APP_ID != '' }}
uses: 'actions/create-github-app-token@fee1f7d63c2ff003460e3d139729b119787bc349' # ratchet:actions/create-github-app-token@v2
uses: 'actions/create-github-app-token@v2'
with:
app-id: '${{ secrets.APP_ID }}'
private-key: '${{ secrets.PRIVATE_KEY }}'
- name: 'Process Stale PRs'
uses: 'actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b' # ratchet:actions/github-script@v7
uses: 'actions/github-script@v7'
env:
DRY_RUN: '${{ inputs.dry_run }}'
with:
@@ -18,10 +18,10 @@ jobs:
runs-on: 'ubuntu-latest'
steps:
- name: 'Checkout'
uses: 'actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5' # ratchet:actions/checkout@v4
uses: 'actions/checkout@v4'
- name: 'Setup Node.js'
uses: 'actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020' # ratchet:actions/setup-node@v4
uses: 'actions/setup-node@v4'
with:
node-version: '20'
cache: 'npm'
@@ -40,10 +40,10 @@ jobs:
runs-on: 'ubuntu-latest'
steps:
- name: 'Checkout'
uses: 'actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5' # ratchet:actions/checkout@v4
uses: 'actions/checkout@v4'
- name: 'Setup Node.js'
uses: 'actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020' # ratchet:actions/setup-node@v4
uses: 'actions/setup-node@v4'
with:
node-version: '20'
cache: 'npm'
@@ -15,7 +15,7 @@ jobs:
issues: 'write'
steps:
- name: 'Check for Parent Workstream and Apply Label'
uses: 'actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b' # ratchet:actions/github-script@v7
uses: 'actions/github-script@v7'
with:
script: |
const labelToAdd = 'workstream-rollup';
@@ -19,7 +19,7 @@ jobs:
APP_ID: '${{ secrets.APP_ID }}'
if: |-
${{ env.APP_ID != '' }}
uses: 'actions/create-github-app-token@fee1f7d63c2ff003460e3d139729b119787bc349' # ratchet:actions/create-github-app-token@v2
uses: 'actions/create-github-app-token@v2'
with:
app-id: '${{ secrets.APP_ID }}'
private-key: '${{ secrets.PRIVATE_KEY }}'
+1 -1
View File
@@ -40,7 +40,7 @@ jobs:
issues: 'write'
steps:
- name: 'Checkout repository'
uses: 'actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5' # ratchet:actions/checkout@v4
uses: 'actions/checkout@v4'
with:
ref: '${{ github.ref }}'
fetch-depth: 0
+3 -3
View File
@@ -29,14 +29,14 @@ jobs:
pull-requests: 'write'
steps:
- name: 'Checkout repository'
uses: 'actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5' # ratchet:actions/checkout@v4
uses: 'actions/checkout@v4'
with:
# The user-level skills need to be available to the workflow
fetch-depth: 0
ref: 'main'
- name: 'Set up Node.js'
uses: 'actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020' # ratchet:actions/setup-node@v4
uses: 'actions/setup-node@v4'
with:
node-version: '20'
@@ -86,7 +86,7 @@ jobs:
- name: 'Create Pull Request'
if: "steps.validate_version.outputs.CONTINUE == 'true'"
uses: 'peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c' # ratchet:peter-evans/create-pull-request@v6
uses: 'peter-evans/create-pull-request@v6'
with:
token: '${{ secrets.GEMINI_CLI_ROBOT_GITHUB_PAT }}'
commit-message: 'docs(changelog): update for ${{ steps.release_info.outputs.VERSION }}'
+4 -4
View File
@@ -33,7 +33,7 @@ jobs:
steps:
- name: 'Checkout'
uses: 'actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5' # ratchet:actions/checkout@v4
uses: 'actions/checkout@v4'
- name: 'Optimize Windows Performance'
if: "matrix.os == 'windows-latest'"
@@ -46,7 +46,7 @@ jobs:
shell: 'powershell'
- name: 'Set up Node.js'
uses: 'actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020' # ratchet:actions/setup-node@v4
uses: 'actions/setup-node@v4'
with:
node-version-file: '.nvmrc'
architecture: '${{ matrix.arch }}'
@@ -63,7 +63,7 @@ jobs:
- name: 'Setup Windows SDK (Windows)'
if: "matrix.os == 'windows-latest'"
uses: 'microsoft/setup-msbuild@6fb02220983dee41ce7ae257b6f4d8f9bf5ed4ce' # ratchet:microsoft/setup-msbuild@v2
uses: 'microsoft/setup-msbuild@v2'
- name: 'Add Signtool to Path (Windows)'
if: "matrix.os == 'windows-latest'"
@@ -153,7 +153,7 @@ jobs:
npm run test:integration:sandbox:none -- --testTimeout=600000
- name: 'Upload Artifact'
uses: 'actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02' # ratchet:actions/upload-artifact@v4
uses: 'actions/upload-artifact@v4'
with:
name: 'gemini-cli-${{ matrix.platform_name }}'
path: 'dist/${{ matrix.platform_name }}/'
@@ -40,13 +40,13 @@ jobs:
steps:
- name: 'Generate GitHub App Token'
id: 'generate_token'
uses: 'actions/create-github-app-token@fee1f7d63c2ff003460e3d139729b119787bc349' # ratchet:actions/create-github-app-token@v2
uses: 'actions/create-github-app-token@v2'
with:
app-id: '${{ secrets.APP_ID }}'
private-key: '${{ secrets.PRIVATE_KEY }}'
- name: 'Unassign inactive assignees'
uses: 'actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b' # ratchet:actions/github-script@v7
uses: 'actions/github-script@v7'
env:
DRY_RUN: '${{ inputs.dry_run }}'
with:
+1 -1
View File
@@ -30,7 +30,7 @@ Learn all about Gemini CLI in our [documentation](https://geminicli.com/docs/).
## 📦 Installation
See
[Gemini CLI installation, execution, and releases](https://geminicli.com/docs/get-started/installation/)
[Gemini CLI installation, execution, and releases](./docs/get-started/installation.md)
for recommended system specifications and a detailed installation guide.
### Quick Install
-24
View File
@@ -18,30 +18,6 @@ on GitHub.
| [Preview](preview.md) | Experimental features ready for early feedback. |
| [Stable](latest.md) | Stable, recommended for general use. |
## Announcements: v0.35.0 - 2026-03-24
- **Customizable Keyboard Shortcuts:** Users can now customize their keyboard
shortcuts, including support for literal character keybindings and the
extended Kitty protocol
([#21945](https://github.com/google-gemini/gemini-cli/pull/21945),
[#21972](https://github.com/google-gemini/gemini-cli/pull/21972) by
@scidomino).
- **Vim Mode Improvements:** Added missing motions (X, ~, r, f/F/t/T) and
yank/paste support with the unnamed register
([#21932](https://github.com/google-gemini/gemini-cli/pull/21932),
[#22026](https://github.com/google-gemini/gemini-cli/pull/22026) by @aanari).
- **Tool Isolation and Sandboxing:** Introduced `SandboxManager` to isolate
process-spawning tools and added Linux bubblewrap/seccomp sandboxing support
([#21774](https://github.com/google-gemini/gemini-cli/pull/21774),
[#22231](https://github.com/google-gemini/gemini-cli/pull/22231) by @galz10,
[#22680](https://github.com/google-gemini/gemini-cli/pull/22680) by
@DavidAPierce).
- **JIT Context Discovery:** Implemented Just-In-Time context discovery for file
system tools to improve model performance and accuracy
([#22082](https://github.com/google-gemini/gemini-cli/pull/22082),
[#22736](https://github.com/google-gemini/gemini-cli/pull/22736) by
@SandyTao520).
## Announcements: v0.34.0 - 2026-03-17
- **Plan Mode Enabled by Default:** Plan Mode is now enabled by default to help
+462 -361
View File
@@ -1,6 +1,6 @@
# Latest stable release: v0.35.0
# Latest stable release: v0.34.0
Released: March 24, 2026
Released: March 17, 2026
For most users, our latest stable release is the recommended release. Install
the latest stable version with:
@@ -11,373 +11,474 @@ npm install -g @google/gemini-cli
## Highlights
- **Customizable Keyboard Shortcuts:** Significant improvements to input
flexibility with support for custom keybindings, literal character bindings,
and extended terminal protocol keys.
- **Vim Mode Enhancements:** Further refinement of the Vim modal editing
experience, adding common motions like \`X\`, \`~\`, \`r\`, and \`f/F/t/T\`,
along with yank and paste support.
- **Enhanced Security through Sandboxing:** Introduction of a unified
\`SandboxManager\` and integration of Linux-native sandboxing (bubblewrap and
seccomp) to isolate tool execution and improve system security.
- **JIT Context Discovery:** Improved performance and accuracy by enabling
Just-In-Time context loading for file system tools, ensuring the model has the
most relevant information without overwhelming the context.
- **Subagent & Performance Updates:** Subagents are now enabled by default,
supported by a model-driven parallel tool scheduler and code splitting for
faster startup and more efficient task execution.
- **Plan Mode Enabled by Default**: The comprehensive planning capability is now
enabled by default, allowing for better structured task management and
execution.
- **Enhanced Sandboxing Capabilities**: Added support for native gVisor (runsc)
sandboxing as well as experimental LXC container sandboxing to provide more
robust and isolated execution environments.
- **Improved Loop Detection & Recovery**: Implemented iterative loop detection
and model feedback mechanisms to prevent the CLI from getting stuck in
repetitive actions.
- **Customizable UI Elements**: You can now configure a custom footer using the
new `/footer` command, and enjoy standardized semantic focus colors for better
history visibility.
- **Extensive Subagent Updates**: Refinements across the tracker visualization
tools, background process logging, and broader fallback support for models in
tool execution scenarios.
## What's Changed
- feat(cli): customizable keyboard shortcuts by @scidomino in
[#21945](https://github.com/google-gemini/gemini-cli/pull/21945)
- feat(core): Thread `AgentLoopContext` through core. by @joshualitt in
[#21944](https://github.com/google-gemini/gemini-cli/pull/21944)
- chore(release): bump version to 0.35.0-nightly.20260311.657f19c1f by
- feat(cli): add chat resume footer on session quit by @lordshashank in
[#20667](https://github.com/google-gemini/gemini-cli/pull/20667)
- Support bold and other styles in svg snapshots by @jacob314 in
[#20937](https://github.com/google-gemini/gemini-cli/pull/20937)
- fix(core): increase A2A agent timeout to 30 minutes by @adamfweidman in
[#21028](https://github.com/google-gemini/gemini-cli/pull/21028)
- Cleanup old branches. by @jacob314 in
[#19354](https://github.com/google-gemini/gemini-cli/pull/19354)
- chore(release): bump version to 0.34.0-nightly.20260303.34f0c1538 by
@gemini-cli-robot in
[#21966](https://github.com/google-gemini/gemini-cli/pull/21966)
- refactor(a2a): remove legacy CoreToolScheduler by @adamfweidman in
[#21955](https://github.com/google-gemini/gemini-cli/pull/21955)
- feat(ui): add missing vim mode motions (X, ~, r, f/F/t/T, df/dt and friends)
by @aanari in [#21932](https://github.com/google-gemini/gemini-cli/pull/21932)
- Feat/retry fetch notifications by @aishaneeshah in
[#21813](https://github.com/google-gemini/gemini-cli/pull/21813)
- fix(core): remove OAuth check from handle fallback and clean up stray file by
@sehoon38 in [#21962](https://github.com/google-gemini/gemini-cli/pull/21962)
- feat(cli): support literal character keybindings and extended Kitty protocol
keys by @scidomino in
[#21972](https://github.com/google-gemini/gemini-cli/pull/21972)
- fix(ui): clamp cursor to last char after all NORMAL mode deletes by @aanari in
[#21973](https://github.com/google-gemini/gemini-cli/pull/21973)
- test(core): add missing tests for prompts/utils.ts by @krrishverma1805-web in
[#19941](https://github.com/google-gemini/gemini-cli/pull/19941)
- fix(cli): allow scrolling keys in copy mode (Ctrl+S selection mode) by
@nsalerni in [#19933](https://github.com/google-gemini/gemini-cli/pull/19933)
- docs(cli): add custom keybinding documentation by @scidomino in
[#21980](https://github.com/google-gemini/gemini-cli/pull/21980)
- docs: fix misleading YOLO mode description in defaultApprovalMode by
@Gyanranjan-Priyam in
[#21878](https://github.com/google-gemini/gemini-cli/pull/21878)
- fix: clean up /clear and /resume by @jackwotherspoon in
[#22007](https://github.com/google-gemini/gemini-cli/pull/22007)
- fix(core)#20941: reap orphaned descendant processes on PTY abort by @manavmax
in [#21124](https://github.com/google-gemini/gemini-cli/pull/21124)
- fix(core): update language detection to use LSP 3.18 identifiers by @yunaseoul
in [#21931](https://github.com/google-gemini/gemini-cli/pull/21931)
- feat(cli): support removing keybindings via '-' prefix by @scidomino in
[#22042](https://github.com/google-gemini/gemini-cli/pull/22042)
- feat(policy): add --admin-policy flag for supplemental admin policies by
@galz10 in [#20360](https://github.com/google-gemini/gemini-cli/pull/20360)
- merge duplicate imports packages/cli/src subtask1 by @Nixxx19 in
[#22040](https://github.com/google-gemini/gemini-cli/pull/22040)
- perf(core): parallelize user quota and experiments fetching in refreshAuth by
@sehoon38 in [#21648](https://github.com/google-gemini/gemini-cli/pull/21648)
- Changelog for v0.34.0-preview.0 by @gemini-cli-robot in
[#21965](https://github.com/google-gemini/gemini-cli/pull/21965)
- Changelog for v0.33.0 by @gemini-cli-robot in
[#21967](https://github.com/google-gemini/gemini-cli/pull/21967)
- fix(core): handle EISDIR in robustRealpath on Windows by @sehoon38 in
[#21984](https://github.com/google-gemini/gemini-cli/pull/21984)
- feat(core): include initiationMethod in conversation interaction telemetry by
@yunaseoul in [#22054](https://github.com/google-gemini/gemini-cli/pull/22054)
- feat(ui): add vim yank/paste (y/p/P) with unnamed register by @aanari in
[#22026](https://github.com/google-gemini/gemini-cli/pull/22026)
- fix(core): enable numerical routing for api key users by @sehoon38 in
[#21977](https://github.com/google-gemini/gemini-cli/pull/21977)
- feat(telemetry): implement retry attempt telemetry for network related retries
by @aishaneeshah in
[#22027](https://github.com/google-gemini/gemini-cli/pull/22027)
- fix(policy): remove unnecessary escapeRegex from pattern builders by
@spencer426 in
[#21921](https://github.com/google-gemini/gemini-cli/pull/21921)
- fix(core): preserve dynamic tool descriptions on session resume by @sehoon38
in [#18835](https://github.com/google-gemini/gemini-cli/pull/18835)
- chore: allow 'gemini-3.1' in sensitive keyword linter by @scidomino in
[#22065](https://github.com/google-gemini/gemini-cli/pull/22065)
- feat(core): support custom base URL via env vars by @junaiddshaukat in
[#21561](https://github.com/google-gemini/gemini-cli/pull/21561)
- merge duplicate imports packages/cli/src subtask2 by @Nixxx19 in
[#22051](https://github.com/google-gemini/gemini-cli/pull/22051)
- fix(core): silently retry API errors up to 3 times before halting session by
@spencer426 in
[#21989](https://github.com/google-gemini/gemini-cli/pull/21989)
- feat(core): simplify subagent success UI and improve early termination display
[#21034](https://github.com/google-gemini/gemini-cli/pull/21034)
- feat(ui): standardize semantic focus colors and enhance history visibility by
@keithguerin in
[#20745](https://github.com/google-gemini/gemini-cli/pull/20745)
- fix: merge duplicate imports in packages/core (3/4) by @Nixxx19 in
[#20928](https://github.com/google-gemini/gemini-cli/pull/20928)
- Add extra safety checks for proto pollution by @jacob314 in
[#20396](https://github.com/google-gemini/gemini-cli/pull/20396)
- feat(core): Add tracker CRUD tools & visualization by @anj-s in
[#19489](https://github.com/google-gemini/gemini-cli/pull/19489)
- Revert "fix(ui): persist expansion in AskUser dialog when navigating options"
by @jacob314 in
[#21042](https://github.com/google-gemini/gemini-cli/pull/21042)
- Changelog for v0.33.0-preview.0 by @gemini-cli-robot in
[#21030](https://github.com/google-gemini/gemini-cli/pull/21030)
- fix: model persistence for all scenarios by @sripasg in
[#21051](https://github.com/google-gemini/gemini-cli/pull/21051)
- chore/release: bump version to 0.34.0-nightly.20260304.28af4e127 by
@gemini-cli-robot in
[#21054](https://github.com/google-gemini/gemini-cli/pull/21054)
- Consistently guard restarts against concurrent auto updates by @scidomino in
[#21016](https://github.com/google-gemini/gemini-cli/pull/21016)
- Defensive coding to reduce the risk of Maximum update depth errors by
@jacob314 in [#20940](https://github.com/google-gemini/gemini-cli/pull/20940)
- fix(cli): Polish shell autocomplete rendering to be a little more shell native
feeling. by @jacob314 in
[#20931](https://github.com/google-gemini/gemini-cli/pull/20931)
- Docs: Update plan mode docs by @jkcinouye in
[#19682](https://github.com/google-gemini/gemini-cli/pull/19682)
- fix(mcp): Notifications/tools/list_changed support not working by @jacob314 in
[#21050](https://github.com/google-gemini/gemini-cli/pull/21050)
- fix(cli): register extension lifecycle events in DebugProfiler by
@fayerman-source in
[#20101](https://github.com/google-gemini/gemini-cli/pull/20101)
- chore(dev): update vscode settings for typescriptreact by @rohit-4321 in
[#19907](https://github.com/google-gemini/gemini-cli/pull/19907)
- fix(cli): enable multi-arch docker builds for sandbox by @ru-aish in
[#19821](https://github.com/google-gemini/gemini-cli/pull/19821)
- Changelog for v0.32.0 by @gemini-cli-robot in
[#21033](https://github.com/google-gemini/gemini-cli/pull/21033)
- Changelog for v0.33.0-preview.1 by @gemini-cli-robot in
[#21058](https://github.com/google-gemini/gemini-cli/pull/21058)
- feat(core): improve @scripts/copy_files.js autocomplete to prioritize
filenames by @sehoon38 in
[#21064](https://github.com/google-gemini/gemini-cli/pull/21064)
- feat(sandbox): add experimental LXC container sandbox support by @h30s in
[#20735](https://github.com/google-gemini/gemini-cli/pull/20735)
- feat(evals): add overall pass rate row to eval nightly summary table by
@gundermanc in
[#20905](https://github.com/google-gemini/gemini-cli/pull/20905)
- feat(telemetry): include language in telemetry and fix accepted lines
computation by @gundermanc in
[#21126](https://github.com/google-gemini/gemini-cli/pull/21126)
- Changelog for v0.32.1 by @gemini-cli-robot in
[#21055](https://github.com/google-gemini/gemini-cli/pull/21055)
- feat(core): add robustness tests, logging, and metrics for CodeAssistServer
SSE parsing by @yunaseoul in
[#21013](https://github.com/google-gemini/gemini-cli/pull/21013)
- feat: add issue assignee workflow by @kartikangiras in
[#21003](https://github.com/google-gemini/gemini-cli/pull/21003)
- fix: improve error message when OAuth succeeds but project ID is required by
@Nixxx19 in [#21070](https://github.com/google-gemini/gemini-cli/pull/21070)
- feat(loop-reduction): implement iterative loop detection and model feedback by
@aishaneeshah in
[#20763](https://github.com/google-gemini/gemini-cli/pull/20763)
- chore(github): require prompt approvers for agent prompt files by @gundermanc
in [#20896](https://github.com/google-gemini/gemini-cli/pull/20896)
- Docs: Create tools reference by @jkcinouye in
[#19470](https://github.com/google-gemini/gemini-cli/pull/19470)
- fix(core, a2a-server): prevent hang during OAuth in non-interactive sessions
by @spencer426 in
[#21045](https://github.com/google-gemini/gemini-cli/pull/21045)
- chore(cli): enable deprecated settings removal by default by @yashodipmore in
[#20682](https://github.com/google-gemini/gemini-cli/pull/20682)
- feat(core): Disable fast ack helper for hints. by @joshualitt in
[#21011](https://github.com/google-gemini/gemini-cli/pull/21011)
- fix(ui): suppress redundant failure note when tool error note is shown by
@NTaylorMullen in
[#21078](https://github.com/google-gemini/gemini-cli/pull/21078)
- docs: document planning workflows with Conductor example by @jerop in
[#21166](https://github.com/google-gemini/gemini-cli/pull/21166)
- feat(release): ship esbuild bundle in npm package by @genneth in
[#19171](https://github.com/google-gemini/gemini-cli/pull/19171)
- fix(extensions): preserve symlinks in extension source path while enforcing
folder trust by @galz10 in
[#20867](https://github.com/google-gemini/gemini-cli/pull/20867)
- fix(cli): defer tool exclusions to policy engine in non-interactive mode by
@EricRahm in [#20639](https://github.com/google-gemini/gemini-cli/pull/20639)
- fix(ui): removed double padding on rendered content by @devr0306 in
[#21029](https://github.com/google-gemini/gemini-cli/pull/21029)
- fix(core): truncate excessively long lines in grep search output by
@gundermanc in
[#21147](https://github.com/google-gemini/gemini-cli/pull/21147)
- feat: add custom footer configuration via `/footer` by @jackwotherspoon in
[#19001](https://github.com/google-gemini/gemini-cli/pull/19001)
- perf(core): fix OOM crash in long-running sessions by @WizardsForgeGames in
[#19608](https://github.com/google-gemini/gemini-cli/pull/19608)
- refactor(cli): categorize built-in themes into dark/ and light/ directories by
@JayadityaGit in
[#18634](https://github.com/google-gemini/gemini-cli/pull/18634)
- fix(core): explicitly allow codebase_investigator and cli_help in read-only
mode by @Adib234 in
[#21157](https://github.com/google-gemini/gemini-cli/pull/21157)
- test: add browser agent integration tests by @kunal-10-cloud in
[#21151](https://github.com/google-gemini/gemini-cli/pull/21151)
- fix(cli): fix enabling kitty codes on Windows Terminal by @scidomino in
[#21136](https://github.com/google-gemini/gemini-cli/pull/21136)
- refactor(core): extract shared OAuth flow primitives from MCPOAuthProvider by
@SandyTao520 in
[#20895](https://github.com/google-gemini/gemini-cli/pull/20895)
- fix(ui): add partial output to cancelled shell UI by @devr0306 in
[#21178](https://github.com/google-gemini/gemini-cli/pull/21178)
- fix(cli): replace hardcoded keybinding strings with dynamic formatters by
@scidomino in [#21159](https://github.com/google-gemini/gemini-cli/pull/21159)
- DOCS: Update quota and pricing page by @g-samroberts in
[#21194](https://github.com/google-gemini/gemini-cli/pull/21194)
- feat(telemetry): implement Clearcut logging for startup statistics by
@yunaseoul in [#21172](https://github.com/google-gemini/gemini-cli/pull/21172)
- feat(triage): add area/documentation to issue triage by @g-samroberts in
[#21222](https://github.com/google-gemini/gemini-cli/pull/21222)
- Fix so shell calls are formatted by @jacob314 in
[#21237](https://github.com/google-gemini/gemini-cli/pull/21237)
- feat(cli): add native gVisor (runsc) sandboxing support by @Zheyuan-Lin in
[#21062](https://github.com/google-gemini/gemini-cli/pull/21062)
- docs: use absolute paths for internal links in plan-mode.md by @jerop in
[#21299](https://github.com/google-gemini/gemini-cli/pull/21299)
- fix(core): prevent unhandled AbortError crash during stream loop detection by
@7hokerz in [#21123](https://github.com/google-gemini/gemini-cli/pull/21123)
- fix:reorder env var redaction checks to scan values first by @kartikangiras in
[#21059](https://github.com/google-gemini/gemini-cli/pull/21059)
- fix(acp): rename --experimental-acp to --acp & remove Zed-specific refrences
by @skeshive in
[#21171](https://github.com/google-gemini/gemini-cli/pull/21171)
- feat(core): fallback to 2.5 models with no access for toolcalls by @sehoon38
in [#21283](https://github.com/google-gemini/gemini-cli/pull/21283)
- test(core): improve testing for API request/response parsing by @sehoon38 in
[#21227](https://github.com/google-gemini/gemini-cli/pull/21227)
- docs(links): update docs-writer skill and fix broken link by @g-samroberts in
[#21314](https://github.com/google-gemini/gemini-cli/pull/21314)
- Fix code colorizer ansi escape bug. by @jacob314 in
[#21321](https://github.com/google-gemini/gemini-cli/pull/21321)
- remove wildcard behavior on keybindings by @scidomino in
[#21315](https://github.com/google-gemini/gemini-cli/pull/21315)
- feat(acp): Add support for AI Gateway auth by @skeshive in
[#21305](https://github.com/google-gemini/gemini-cli/pull/21305)
- fix(theme): improve theme color contrast for macOS Terminal.app by @clocky in
[#21175](https://github.com/google-gemini/gemini-cli/pull/21175)
- feat (core): Implement tracker related SI changes by @anj-s in
[#19964](https://github.com/google-gemini/gemini-cli/pull/19964)
- Changelog for v0.33.0-preview.2 by @gemini-cli-robot in
[#21333](https://github.com/google-gemini/gemini-cli/pull/21333)
- Changelog for v0.33.0-preview.3 by @gemini-cli-robot in
[#21347](https://github.com/google-gemini/gemini-cli/pull/21347)
- docs: format release times as HH:MM UTC by @pavan-sh in
[#20726](https://github.com/google-gemini/gemini-cli/pull/20726)
- fix(cli): implement --all flag for extensions uninstall by @sehoon38 in
[#21319](https://github.com/google-gemini/gemini-cli/pull/21319)
- docs: fix incorrect relative links to command reference by @kanywst in
[#20964](https://github.com/google-gemini/gemini-cli/pull/20964)
- documentiong ensures ripgrep by @Jatin24062005 in
[#21298](https://github.com/google-gemini/gemini-cli/pull/21298)
- fix(core): handle AbortError thrown during processTurn by @MumuTW in
[#21296](https://github.com/google-gemini/gemini-cli/pull/21296)
- docs(cli): clarify ! command output visibility in shell commands tutorial by
@MohammedADev in
[#21041](https://github.com/google-gemini/gemini-cli/pull/21041)
- fix: logic for task tracker strategy and remove tracker tools by @anj-s in
[#21355](https://github.com/google-gemini/gemini-cli/pull/21355)
- fix(partUtils): display media type and size for inline data parts by @Aboudjem
in [#21358](https://github.com/google-gemini/gemini-cli/pull/21358)
- Fix(accessibility): add screen reader support to RewindViewer by @Famous077 in
[#20750](https://github.com/google-gemini/gemini-cli/pull/20750)
- fix(hooks): propagate stopHookActive in AfterAgent retry path (#20426) by
@Aarchi-07 in [#20439](https://github.com/google-gemini/gemini-cli/pull/20439)
- fix(core): deduplicate GEMINI.md files by device/inode on case-insensitive
filesystems (#19904) by @Nixxx19 in
[#19915](https://github.com/google-gemini/gemini-cli/pull/19915)
- feat(core): add concurrency safety guidance for subagent delegation (#17753)
by @abhipatel12 in
[#21917](https://github.com/google-gemini/gemini-cli/pull/21917)
- merge duplicate imports packages/cli/src subtask3 by @Nixxx19 in
[#22056](https://github.com/google-gemini/gemini-cli/pull/22056)
- fix(hooks): fix BeforeAgent/AfterAgent inconsistencies (#18514) by @krishdef7
in [#21383](https://github.com/google-gemini/gemini-cli/pull/21383)
- feat(core): implement SandboxManager interface and config schema by @galz10 in
[#21774](https://github.com/google-gemini/gemini-cli/pull/21774)
- docs: document npm deprecation warnings as safe to ignore by @h30s in
[#20692](https://github.com/google-gemini/gemini-cli/pull/20692)
- fix: remove status/need-triage from maintainer-only issues by @SandyTao520 in
[#22044](https://github.com/google-gemini/gemini-cli/pull/22044)
- fix(core): propagate subagent context to policy engine by @NTaylorMullen in
[#22086](https://github.com/google-gemini/gemini-cli/pull/22086)
- fix(cli): resolve skill uninstall failure when skill name is updated by
@NTaylorMullen in
[#22085](https://github.com/google-gemini/gemini-cli/pull/22085)
- docs(plan): clarify interactive plan editing with Ctrl+X by @Adib234 in
[#22076](https://github.com/google-gemini/gemini-cli/pull/22076)
- fix(policy): ensure user policies are loaded when policyPaths is empty by
@NTaylorMullen in
[#22090](https://github.com/google-gemini/gemini-cli/pull/22090)
- Docs: Add documentation for model steering (experimental). by @jkcinouye in
[#21154](https://github.com/google-gemini/gemini-cli/pull/21154)
- Add issue for automated changelogs by @g-samroberts in
[#21912](https://github.com/google-gemini/gemini-cli/pull/21912)
- fix(core): secure argsPattern and revert WEB_FETCH_TOOL_NAME escalation by
[#21278](https://github.com/google-gemini/gemini-cli/pull/21278)
- feat(ui): dynamically generate all keybinding hints by @scidomino in
[#21346](https://github.com/google-gemini/gemini-cli/pull/21346)
- feat(core): implement unified KeychainService and migrate token storage by
@ehedlund in [#21344](https://github.com/google-gemini/gemini-cli/pull/21344)
- fix(cli): gracefully handle --resume when no sessions exist by @SandyTao520 in
[#21429](https://github.com/google-gemini/gemini-cli/pull/21429)
- fix(plan): keep approved plan during chat compression by @ruomengz in
[#21284](https://github.com/google-gemini/gemini-cli/pull/21284)
- feat(core): implement generic CacheService and optimize setupUser by @sehoon38
in [#21374](https://github.com/google-gemini/gemini-cli/pull/21374)
- Update quota and pricing documentation with subscription tiers by @srithreepo
in [#21351](https://github.com/google-gemini/gemini-cli/pull/21351)
- fix(core): append correct OTLP paths for HTTP exporters by
@sebastien-prudhomme in
[#16836](https://github.com/google-gemini/gemini-cli/pull/16836)
- Changelog for v0.33.0-preview.4 by @gemini-cli-robot in
[#21354](https://github.com/google-gemini/gemini-cli/pull/21354)
- feat(cli): implement dot-prefixing for slash command conflicts by @ehedlund in
[#20979](https://github.com/google-gemini/gemini-cli/pull/20979)
- refactor(core): standardize MCP tool naming to mcp\_ FQN format by
@abhipatel12 in
[#21425](https://github.com/google-gemini/gemini-cli/pull/21425)
- feat(cli): hide gemma settings from display and mark as experimental by
@abhipatel12 in
[#21471](https://github.com/google-gemini/gemini-cli/pull/21471)
- feat(skills): refine string-reviewer guidelines and description by @clocky in
[#20368](https://github.com/google-gemini/gemini-cli/pull/20368)
- fix(core): whitelist TERM and COLORTERM in environment sanitization by
@deadsmash07 in
[#20514](https://github.com/google-gemini/gemini-cli/pull/20514)
- fix(billing): fix overage strategy lifecycle and settings integration by
@gsquared94 in
[#21236](https://github.com/google-gemini/gemini-cli/pull/21236)
- fix: expand paste placeholders in TextInput on submit by @Jefftree in
[#19946](https://github.com/google-gemini/gemini-cli/pull/19946)
- fix(core): add in-memory cache to ChatRecordingService to prevent OOM by
@SandyTao520 in
[#21502](https://github.com/google-gemini/gemini-cli/pull/21502)
- feat(cli): overhaul thinking UI by @keithguerin in
[#18725](https://github.com/google-gemini/gemini-cli/pull/18725)
- fix(ui): unify Ctrl+O expansion hint experience across buffer modes by
@jwhelangoog in
[#21474](https://github.com/google-gemini/gemini-cli/pull/21474)
- fix(cli): correct shell height reporting by @jacob314 in
[#21492](https://github.com/google-gemini/gemini-cli/pull/21492)
- Make test suite pass when the GEMINI_SYSTEM_MD env variable or
GEMINI_WRITE_SYSTEM_MD variable happens to be set locally/ by @jacob314 in
[#21480](https://github.com/google-gemini/gemini-cli/pull/21480)
- Disallow underspecified types by @gundermanc in
[#21485](https://github.com/google-gemini/gemini-cli/pull/21485)
- refactor(cli): standardize on 'reload' verb for all components by @keithguerin
in [#20654](https://github.com/google-gemini/gemini-cli/pull/20654)
- feat(cli): Invert quota language to 'percent used' by @keithguerin in
[#20100](https://github.com/google-gemini/gemini-cli/pull/20100)
- Docs: Add documentation for notifications (experimental)(macOS) by @jkcinouye
in [#21163](https://github.com/google-gemini/gemini-cli/pull/21163)
- Code review comments as a pr by @jacob314 in
[#21209](https://github.com/google-gemini/gemini-cli/pull/21209)
- feat(cli): unify /chat and /resume command UX by @LyalinDotCom in
[#20256](https://github.com/google-gemini/gemini-cli/pull/20256)
- docs: fix typo 'allowslisted' -> 'allowlisted' in mcp-server.md by
@Gyanranjan-Priyam in
[#21665](https://github.com/google-gemini/gemini-cli/pull/21665)
- fix(core): display actual graph output in tracker_visualize tool by @anj-s in
[#21455](https://github.com/google-gemini/gemini-cli/pull/21455)
- fix(core): sanitize SSE-corrupted JSON and domain strings in error
classification by @gsquared94 in
[#21702](https://github.com/google-gemini/gemini-cli/pull/21702)
- Docs: Make documentation links relative by @diodesign in
[#21490](https://github.com/google-gemini/gemini-cli/pull/21490)
- feat(cli): expose /tools desc as explicit subcommand for discoverability by
@aworki in [#21241](https://github.com/google-gemini/gemini-cli/pull/21241)
- feat(cli): add /compact alias for /compress command by @jackwotherspoon in
[#21711](https://github.com/google-gemini/gemini-cli/pull/21711)
- feat(plan): enable Plan Mode by default by @jerop in
[#21713](https://github.com/google-gemini/gemini-cli/pull/21713)
- feat(core): Introduce `AgentLoopContext`. by @joshualitt in
[#21198](https://github.com/google-gemini/gemini-cli/pull/21198)
- fix(core): resolve symlinks for non-existent paths during validation by
@Adib234 in [#21487](https://github.com/google-gemini/gemini-cli/pull/21487)
- docs: document tool exclusion from memory via deny policy by @Abhijit-2592 in
[#21428](https://github.com/google-gemini/gemini-cli/pull/21428)
- perf(core): cache loadApiKey to reduce redundant keychain access by @sehoon38
in [#21520](https://github.com/google-gemini/gemini-cli/pull/21520)
- feat(cli): implement /upgrade command by @sehoon38 in
[#21511](https://github.com/google-gemini/gemini-cli/pull/21511)
- Feat/browser agent progress emission by @kunal-10-cloud in
[#21218](https://github.com/google-gemini/gemini-cli/pull/21218)
- fix(settings): display objects as JSON instead of [object Object] by
@Zheyuan-Lin in
[#21458](https://github.com/google-gemini/gemini-cli/pull/21458)
- Unmarshall update by @DavidAPierce in
[#21721](https://github.com/google-gemini/gemini-cli/pull/21721)
- Update mcp's list function to check for disablement. by @DavidAPierce in
[#21148](https://github.com/google-gemini/gemini-cli/pull/21148)
- robustness(core): static checks to validate history is immutable by @jacob314
in [#21228](https://github.com/google-gemini/gemini-cli/pull/21228)
- refactor(cli): better react patterns for BaseSettingsDialog by @psinha40898 in
[#21206](https://github.com/google-gemini/gemini-cli/pull/21206)
- feat(security): implement robust IP validation and safeFetch foundation by
@alisa-alisa in
[#21401](https://github.com/google-gemini/gemini-cli/pull/21401)
- feat(core): improve subagent result display by @joshualitt in
[#20378](https://github.com/google-gemini/gemini-cli/pull/20378)
- docs: fix broken markdown syntax and anchor links in /tools by @campox747 in
[#20902](https://github.com/google-gemini/gemini-cli/pull/20902)
- feat(policy): support subagent-specific policies in TOML by @akh64bit in
[#21431](https://github.com/google-gemini/gemini-cli/pull/21431)
- Add script to speed up reviewing PRs adding a worktree. by @jacob314 in
[#21748](https://github.com/google-gemini/gemini-cli/pull/21748)
- fix(core): prevent infinite recursion in symlink resolution by @Adib234 in
[#21750](https://github.com/google-gemini/gemini-cli/pull/21750)
- fix(docs): fix headless mode docs by @ame2en in
[#21287](https://github.com/google-gemini/gemini-cli/pull/21287)
- feat/redesign header compact by @jacob314 in
[#20922](https://github.com/google-gemini/gemini-cli/pull/20922)
- refactor: migrate to useKeyMatchers hook by @scidomino in
[#21753](https://github.com/google-gemini/gemini-cli/pull/21753)
- perf(cli): cache loadSettings to reduce redundant disk I/O at startup by
@sehoon38 in [#21521](https://github.com/google-gemini/gemini-cli/pull/21521)
- fix(core): resolve Windows line ending and path separation bugs across CLI by
@muhammadusman586 in
[#21068](https://github.com/google-gemini/gemini-cli/pull/21068)
- docs: fix heading formatting in commands.md and phrasing in tools-api.md by
@campox747 in [#20679](https://github.com/google-gemini/gemini-cli/pull/20679)
- refactor(ui): unify keybinding infrastructure and support string
initialization by @scidomino in
[#21776](https://github.com/google-gemini/gemini-cli/pull/21776)
- Add support for updating extension sources and names by @chrstnb in
[#21715](https://github.com/google-gemini/gemini-cli/pull/21715)
- fix(core): handle GUI editor non-zero exit codes gracefully by @reyyanxahmed
in [#20376](https://github.com/google-gemini/gemini-cli/pull/20376)
- fix(core): destroy PTY on kill() and exception to prevent fd leak by @nbardy
in [#21693](https://github.com/google-gemini/gemini-cli/pull/21693)
- fix(docs): update theme screenshots and add missing themes by @ashmod in
[#20689](https://github.com/google-gemini/gemini-cli/pull/20689)
- refactor(cli): rename 'return' key to 'enter' internally by @scidomino in
[#21796](https://github.com/google-gemini/gemini-cli/pull/21796)
- build(release): restrict npm bundling to non-stable tags by @sehoon38 in
[#21821](https://github.com/google-gemini/gemini-cli/pull/21821)
- fix(core): override toolRegistry property for sub-agent schedulers by
@gsquared94 in
[#21766](https://github.com/google-gemini/gemini-cli/pull/21766)
- fix(cli): make footer items equally spaced by @jacob314 in
[#21843](https://github.com/google-gemini/gemini-cli/pull/21843)
- docs: clarify global policy rules application in plan mode by @jerop in
[#21864](https://github.com/google-gemini/gemini-cli/pull/21864)
- fix(core): ensure correct flash model steering in plan mode implementation
phase by @jerop in
[#21871](https://github.com/google-gemini/gemini-cli/pull/21871)
- fix(core): update @a2a-js/sdk to 0.3.11 by @adamfweidman in
[#21875](https://github.com/google-gemini/gemini-cli/pull/21875)
- refactor(core): improve API response error logging when retry by @yunaseoul in
[#21784](https://github.com/google-gemini/gemini-cli/pull/21784)
- fix(ui): handle headless execution in credits and upgrade dialogs by
@gsquared94 in
[#21850](https://github.com/google-gemini/gemini-cli/pull/21850)
- fix(core): treat retryable errors with >5 min delay as terminal quota errors
by @gsquared94 in
[#21881](https://github.com/google-gemini/gemini-cli/pull/21881)
- feat(telemetry): add specific PR, issue, and custom tracking IDs for GitHub
Actions by @cocosheng-g in
[#21129](https://github.com/google-gemini/gemini-cli/pull/21129)
- feat(core): add OAuth2 Authorization Code auth provider for A2A agents by
@SandyTao520 in
[#21496](https://github.com/google-gemini/gemini-cli/pull/21496)
- feat(cli): give visibility to /tools list command in the TUI and follow the
subcommand pattern of other commands by @JayadityaGit in
[#21213](https://github.com/google-gemini/gemini-cli/pull/21213)
- Handle dirty worktrees better and warn about running scripts/review.sh on
untrusted code. by @jacob314 in
[#21791](https://github.com/google-gemini/gemini-cli/pull/21791)
- feat(policy): support auto-add to policy by default and scoped persistence by
@spencer426 in
[#22104](https://github.com/google-gemini/gemini-cli/pull/22104)
- feat(core): differentiate User-Agent for a2a-server and ACP clients by
@bdmorgan in [#22059](https://github.com/google-gemini/gemini-cli/pull/22059)
- refactor(core): extract ExecutionLifecycleService for tool backgrounding by
@adamfweidman in
[#21717](https://github.com/google-gemini/gemini-cli/pull/21717)
- feat: Display pending and confirming tool calls by @sripasg in
[#22106](https://github.com/google-gemini/gemini-cli/pull/22106)
- feat(browser): implement input blocker overlay during automation by
[#20361](https://github.com/google-gemini/gemini-cli/pull/20361)
- fix(core): handle AbortError when ESC cancels tool execution by @PrasannaPal21
in [#20863](https://github.com/google-gemini/gemini-cli/pull/20863)
- fix(release): Improve Patch Release Workflow Comments: Clearer Approval
Guidance by @jerop in
[#21894](https://github.com/google-gemini/gemini-cli/pull/21894)
- docs: clarify telemetry setup and comprehensive data map by @jerop in
[#21879](https://github.com/google-gemini/gemini-cli/pull/21879)
- feat(core): add per-model token usage to stream-json output by @yongruilin in
[#21839](https://github.com/google-gemini/gemini-cli/pull/21839)
- docs: remove experimental badge from plan mode in sidebar by @jerop in
[#21906](https://github.com/google-gemini/gemini-cli/pull/21906)
- fix(cli): prevent race condition in loop detection retry by @skyvanguard in
[#17916](https://github.com/google-gemini/gemini-cli/pull/17916)
- Add behavioral evals for tracker by @anj-s in
[#20069](https://github.com/google-gemini/gemini-cli/pull/20069)
- fix(auth): update terminology to 'sign in' and 'sign out' by @clocky in
[#20892](https://github.com/google-gemini/gemini-cli/pull/20892)
- docs(mcp): standardize mcp tool fqn documentation by @abhipatel12 in
[#21664](https://github.com/google-gemini/gemini-cli/pull/21664)
- fix(ui): prevent empty tool-group border stubs after filtering by @Aaxhirrr in
[#21852](https://github.com/google-gemini/gemini-cli/pull/21852)
- make command names consistent by @scidomino in
[#21907](https://github.com/google-gemini/gemini-cli/pull/21907)
- refactor: remove agent_card_requires_auth config flag by @adamfweidman in
[#21914](https://github.com/google-gemini/gemini-cli/pull/21914)
- feat(a2a): implement standardized normalization and streaming reassembly by
@alisa-alisa in
[#21402](https://github.com/google-gemini/gemini-cli/pull/21402)
- feat(cli): enable skill activation via slash commands by @NTaylorMullen in
[#21758](https://github.com/google-gemini/gemini-cli/pull/21758)
- docs(cli): mention per-model token usage in stream-json result event by
@yongruilin in
[#21908](https://github.com/google-gemini/gemini-cli/pull/21908)
- fix(plan): prevent plan truncation in approval dialog by supporting
unconstrained heights by @Adib234 in
[#21037](https://github.com/google-gemini/gemini-cli/pull/21037)
- feat(a2a): switch from callback-based to event-driven tool scheduler by
@cocosheng-g in
[#21467](https://github.com/google-gemini/gemini-cli/pull/21467)
- feat(voice): implement speech-friendly response formatter by @ayush31010 in
[#20989](https://github.com/google-gemini/gemini-cli/pull/20989)
- feat: add pulsating blue border automation overlay to browser agent by
@kunal-10-cloud in
[#21132](https://github.com/google-gemini/gemini-cli/pull/21132)
- fix: register themes on extension load not start by @jackwotherspoon in
[#22148](https://github.com/google-gemini/gemini-cli/pull/22148)
- feat(ui): Do not show Ultra users /upgrade hint (#22154) by @sehoon38 in
[#22156](https://github.com/google-gemini/gemini-cli/pull/22156)
- chore: remove unnecessary log for themes by @jackwotherspoon in
[#22165](https://github.com/google-gemini/gemini-cli/pull/22165)
- fix(core): resolve MCP tool FQN validation, schema export, and wildcards in
subagents by @abhipatel12 in
[#22069](https://github.com/google-gemini/gemini-cli/pull/22069)
- fix(cli): validate --model argument at startup by @JaisalJain in
[#21393](https://github.com/google-gemini/gemini-cli/pull/21393)
- fix(core): handle policy ALLOW for exit_plan_mode by @backnotprop in
[#21802](https://github.com/google-gemini/gemini-cli/pull/21802)
- feat(telemetry): add Clearcut instrumentation for AI credits billing events by
@gsquared94 in
[#22153](https://github.com/google-gemini/gemini-cli/pull/22153)
- feat(core): add google credentials provider for remote agents by @adamfweidman
in [#21024](https://github.com/google-gemini/gemini-cli/pull/21024)
- test(cli): add integration test for node deprecation warnings by @Nixxx19 in
[#20215](https://github.com/google-gemini/gemini-cli/pull/20215)
- feat(cli): allow safe tools to execute concurrently while agent is busy by
@spencer426 in
[#21988](https://github.com/google-gemini/gemini-cli/pull/21988)
- feat(core): implement model-driven parallel tool scheduler by @abhipatel12 in
[#21933](https://github.com/google-gemini/gemini-cli/pull/21933)
- update vulnerable deps by @scidomino in
[#22180](https://github.com/google-gemini/gemini-cli/pull/22180)
- fix(core): fix startup stats to use int values for timestamps and durations by
@yunaseoul in [#22201](https://github.com/google-gemini/gemini-cli/pull/22201)
- fix(core): prevent duplicate tool schemas for instantiated tools by
@abhipatel12 in
[#22204](https://github.com/google-gemini/gemini-cli/pull/22204)
- fix(core): add proxy routing support for remote A2A subagents by @adamfweidman
in [#22199](https://github.com/google-gemini/gemini-cli/pull/22199)
- fix(core/ide): add Antigravity CLI fallbacks by @apfine in
[#22030](https://github.com/google-gemini/gemini-cli/pull/22030)
- fix(browser): fix duplicate function declaration error in browser agent by
@gsquared94 in
[#22207](https://github.com/google-gemini/gemini-cli/pull/22207)
- feat(core): implement Stage 1 improvements for webfetch tool by @aishaneeshah
in [#21313](https://github.com/google-gemini/gemini-cli/pull/21313)
- Changelog for v0.34.0-preview.1 by @gemini-cli-robot in
[#22194](https://github.com/google-gemini/gemini-cli/pull/22194)
- perf(cli): enable code splitting and deferred UI loading by @sehoon38 in
[#22117](https://github.com/google-gemini/gemini-cli/pull/22117)
- fix: remove unused img.png from project root by @SandyTao520 in
[#22222](https://github.com/google-gemini/gemini-cli/pull/22222)
- docs(local model routing): add docs on how to use Gemma for local model
routing by @douglas-reid in
[#21365](https://github.com/google-gemini/gemini-cli/pull/21365)
- feat(a2a): enable native gRPC support and protocol routing by @alisa-alisa in
[#21403](https://github.com/google-gemini/gemini-cli/pull/21403)
- fix(cli): escape @ symbols on paste to prevent unintended file expansion by
@krishdef7 in [#21239](https://github.com/google-gemini/gemini-cli/pull/21239)
- feat(core): add trajectoryId to ConversationOffered telemetry by @yunaseoul in
[#22214](https://github.com/google-gemini/gemini-cli/pull/22214)
- docs: clarify that tools.core is an allowlist for ALL built-in tools by
@hobostay in [#18813](https://github.com/google-gemini/gemini-cli/pull/18813)
- docs(plan): document hooks with plan mode by @ruomengz in
[#22197](https://github.com/google-gemini/gemini-cli/pull/22197)
- Changelog for v0.33.1 by @gemini-cli-robot in
[#22235](https://github.com/google-gemini/gemini-cli/pull/22235)
- build(ci): fix false positive evals trigger on merge commits by @gundermanc in
[#22237](https://github.com/google-gemini/gemini-cli/pull/22237)
- fix(core): explicitly pass messageBus to policy engine for MCP tool saves by
@abhipatel12 in
[#22255](https://github.com/google-gemini/gemini-cli/pull/22255)
- feat(core): Fully migrate packages/core to AgentLoopContext. by @joshualitt in
[#22115](https://github.com/google-gemini/gemini-cli/pull/22115)
- feat(core): increase sub-agent turn and time limits by @bdmorgan in
[#22196](https://github.com/google-gemini/gemini-cli/pull/22196)
- feat(core): instrument file system tools for JIT context discovery by
@SandyTao520 in
[#22082](https://github.com/google-gemini/gemini-cli/pull/22082)
- refactor(ui): extract pure session browser utilities by @abhipatel12 in
[#22256](https://github.com/google-gemini/gemini-cli/pull/22256)
- fix(plan): Fix AskUser evals by @Adib234 in
[#22074](https://github.com/google-gemini/gemini-cli/pull/22074)
- fix(settings): prevent j/k navigation keys from intercepting edit buffer input
by @student-ankitpandit in
[#21865](https://github.com/google-gemini/gemini-cli/pull/21865)
- feat(skills): improve async-pr-review workflow and logging by @mattKorwel in
[#21790](https://github.com/google-gemini/gemini-cli/pull/21790)
- refactor(cli): consolidate getErrorMessage utility to core by @scidomino in
[#22190](https://github.com/google-gemini/gemini-cli/pull/22190)
- fix(core): show descriptive error messages when saving settings fails by
@afarber in [#18095](https://github.com/google-gemini/gemini-cli/pull/18095)
- docs(core): add authentication guide for remote subagents by @adamfweidman in
[#22178](https://github.com/google-gemini/gemini-cli/pull/22178)
- docs: overhaul subagents documentation and add /agents command by @abhipatel12
in [#22345](https://github.com/google-gemini/gemini-cli/pull/22345)
- refactor(ui): extract SessionBrowser static ui components by @abhipatel12 in
[#22348](https://github.com/google-gemini/gemini-cli/pull/22348)
- test: add Object.create context regression test and tool confirmation
integration test by @gsquared94 in
[#22356](https://github.com/google-gemini/gemini-cli/pull/22356)
- feat(tracker): return TodoList display for tracker tools by @anj-s in
[#22060](https://github.com/google-gemini/gemini-cli/pull/22060)
- feat(agent): add allowed domain restrictions for browser agent by
@cynthialong0-0 in
[#21775](https://github.com/google-gemini/gemini-cli/pull/21775)
- chore/release: bump version to 0.35.0-nightly.20260313.bb060d7a9 by
[#21173](https://github.com/google-gemini/gemini-cli/pull/21173)
- Add extensionRegistryURI setting to change where the registry is read from by
@kevinjwang1 in
[#20463](https://github.com/google-gemini/gemini-cli/pull/20463)
- fix: patch gaxios v7 Array.toString() stream corruption by @gsquared94 in
[#21884](https://github.com/google-gemini/gemini-cli/pull/21884)
- fix: prevent hangs in non-interactive mode and improve agent guidance by
@cocosheng-g in
[#20893](https://github.com/google-gemini/gemini-cli/pull/20893)
- Add ExtensionDetails dialog and support install by @chrstnb in
[#20845](https://github.com/google-gemini/gemini-cli/pull/20845)
- chore/release: bump version to 0.34.0-nightly.20260310.4653b126f by
@gemini-cli-robot in
[#22251](https://github.com/google-gemini/gemini-cli/pull/22251)
- Move keychain fallback to keychain service by @chrstnb in
[#22332](https://github.com/google-gemini/gemini-cli/pull/22332)
- feat(core): integrate SandboxManager to sandbox all process-spawning tools by
@galz10 in [#22231](https://github.com/google-gemini/gemini-cli/pull/22231)
- fix(cli): support CJK input and full Unicode scalar values in terminal
protocols by @scidomino in
[#22353](https://github.com/google-gemini/gemini-cli/pull/22353)
- Promote stable tests. by @gundermanc in
[#22253](https://github.com/google-gemini/gemini-cli/pull/22253)
- feat(tracker): add tracker policy by @anj-s in
[#22379](https://github.com/google-gemini/gemini-cli/pull/22379)
- feat(security): add disableAlwaysAllow setting to disable auto-approvals by
@galz10 in [#21941](https://github.com/google-gemini/gemini-cli/pull/21941)
- Revert "fix(cli): validate --model argument at startup" by @sehoon38 in
[#22378](https://github.com/google-gemini/gemini-cli/pull/22378)
- fix(mcp): handle equivalent root resource URLs in OAuth validation by @galz10
in [#20231](https://github.com/google-gemini/gemini-cli/pull/20231)
- fix(core): use session-specific temp directory for task tracker by @anj-s in
[#22382](https://github.com/google-gemini/gemini-cli/pull/22382)
- Fix issue where config was undefined. by @gundermanc in
[#22397](https://github.com/google-gemini/gemini-cli/pull/22397)
- fix(core): deduplicate project memory when JIT context is enabled by
@SandyTao520 in
[#22234](https://github.com/google-gemini/gemini-cli/pull/22234)
- feat(prompts): implement Topic-Action-Summary model for verbosity reduction by
@Abhijit-2592 in
[#21503](https://github.com/google-gemini/gemini-cli/pull/21503)
- fix(core): fix manual deletion of subagent histories by @abhipatel12 in
[#22407](https://github.com/google-gemini/gemini-cli/pull/22407)
- Add registry var by @kevinjwang1 in
[#22224](https://github.com/google-gemini/gemini-cli/pull/22224)
- Add ModelDefinitions to ModelConfigService by @kevinjwang1 in
[#22302](https://github.com/google-gemini/gemini-cli/pull/22302)
- fix(cli): improve command conflict handling for skills by @NTaylorMullen in
[#21942](https://github.com/google-gemini/gemini-cli/pull/21942)
- fix(core): merge user settings with extension-provided MCP servers by
@abhipatel12 in
[#22484](https://github.com/google-gemini/gemini-cli/pull/22484)
- fix(core): skip discovery for incomplete MCP configs and resolve merge race
condition by @abhipatel12 in
[#22494](https://github.com/google-gemini/gemini-cli/pull/22494)
- fix(automation): harden stale PR closer permissions and maintainer detection
by @bdmorgan in
[#22558](https://github.com/google-gemini/gemini-cli/pull/22558)
- fix(automation): evaluate staleness before checking protected labels by
@bdmorgan in [#22561](https://github.com/google-gemini/gemini-cli/pull/22561)
- feat(agent): replace the runtime npx for browser agent chrome devtool mcp with
pre-built bundle by @cynthialong0-0 in
[#22213](https://github.com/google-gemini/gemini-cli/pull/22213)
- perf: optimize TrackerService dependency checks by @anj-s in
[#22384](https://github.com/google-gemini/gemini-cli/pull/22384)
- docs(policy): remove trailing space from commandPrefix examples by @kawasin73
in [#22264](https://github.com/google-gemini/gemini-cli/pull/22264)
- fix(a2a-server): resolve unsafe assignment lint errors by @ehedlund in
[#22661](https://github.com/google-gemini/gemini-cli/pull/22661)
- fix: Adjust ToolGroupMessage filtering to hide Confirming and show Canceled
tool calls. by @sripasg in
[#22230](https://github.com/google-gemini/gemini-cli/pull/22230)
- Disallow Object.create() and reflect. by @gundermanc in
[#22408](https://github.com/google-gemini/gemini-cli/pull/22408)
- Guard pro model usage by @sehoon38 in
[#22665](https://github.com/google-gemini/gemini-cli/pull/22665)
- refactor(core): Creates AgentSession abstraction for consolidated agent
interface. by @mbleigh in
[#22270](https://github.com/google-gemini/gemini-cli/pull/22270)
- docs(changelog): remove internal commands from release notes by
@jackwotherspoon in
[#22529](https://github.com/google-gemini/gemini-cli/pull/22529)
- feat: enable subagents by @abhipatel12 in
[#22386](https://github.com/google-gemini/gemini-cli/pull/22386)
- feat(extensions): implement cryptographic integrity verification for extension
updates by @ehedlund in
[#21772](https://github.com/google-gemini/gemini-cli/pull/21772)
- feat(tracker): polish UI sorting and formatting by @anj-s in
[#22437](https://github.com/google-gemini/gemini-cli/pull/22437)
- Changelog for v0.34.0-preview.2 by @gemini-cli-robot in
[#22220](https://github.com/google-gemini/gemini-cli/pull/22220)
- fix(core): fix three JIT context bugs in read_file, read_many_files, and
memoryDiscovery by @SandyTao520 in
[#22679](https://github.com/google-gemini/gemini-cli/pull/22679)
- refactor(core): introduce InjectionService with source-aware injection and
backend-native background completions by @adamfweidman in
[#22544](https://github.com/google-gemini/gemini-cli/pull/22544)
- Linux sandbox bubblewrap by @DavidAPierce in
[#22680](https://github.com/google-gemini/gemini-cli/pull/22680)
- feat(core): increase thought signature retry resilience by @bdmorgan in
[#22202](https://github.com/google-gemini/gemini-cli/pull/22202)
- feat(core): implement Stage 2 security and consistency improvements for
web_fetch by @aishaneeshah in
[#22217](https://github.com/google-gemini/gemini-cli/pull/22217)
- refactor(core): replace positional execute params with ExecuteOptions bag by
@adamfweidman in
[#22674](https://github.com/google-gemini/gemini-cli/pull/22674)
- feat(config): enable JIT context loading by default by @SandyTao520 in
[#22736](https://github.com/google-gemini/gemini-cli/pull/22736)
- fix(config): ensure discoveryMaxDirs is passed to global config during
initialization by @kevin-ramdass in
[#22744](https://github.com/google-gemini/gemini-cli/pull/22744)
- fix(plan): allowlist get_internal_docs in Plan Mode by @Adib234 in
[#22668](https://github.com/google-gemini/gemini-cli/pull/22668)
- Changelog for v0.34.0-preview.3 by @gemini-cli-robot in
[#22393](https://github.com/google-gemini/gemini-cli/pull/22393)
- feat(core): add foundation for subagent tool isolation by @akh64bit in
[#22708](https://github.com/google-gemini/gemini-cli/pull/22708)
- fix(core): handle surrogate pairs in truncateString by @sehoon38 in
[#22754](https://github.com/google-gemini/gemini-cli/pull/22754)
- fix(cli): override j/k navigation in settings dialog to fix search input
conflict by @sehoon38 in
[#22800](https://github.com/google-gemini/gemini-cli/pull/22800)
- feat(plan): add 'All the above' option to multi-select AskUser questions by
@Adib234 in [#22365](https://github.com/google-gemini/gemini-cli/pull/22365)
- docs: distribute package-specific GEMINI.md context to each package by
@SandyTao520 in
[#22734](https://github.com/google-gemini/gemini-cli/pull/22734)
- fix(cli): clean up stale pasted placeholder metadata after word/line deletions
by @Jomak-x in
[#20375](https://github.com/google-gemini/gemini-cli/pull/20375)
- refactor(core): align JIT memory placement with tiered context model by
@SandyTao520 in
[#22766](https://github.com/google-gemini/gemini-cli/pull/22766)
- Linux sandbox seccomp by @DavidAPierce in
[#22815](https://github.com/google-gemini/gemini-cli/pull/22815)
- fix(patch): cherry-pick 4e5dfd0 to release/v0.35.0-preview.1-pr-23074 to patch
version v0.35.0-preview.1 and create version 0.35.0-preview.2 by
@gemini-cli-robot in
[#23134](https://github.com/google-gemini/gemini-cli/pull/23134)
- fix(patch): cherry-pick daf3691 to release/v0.35.0-preview.2-pr-23558 to patch
version v0.35.0-preview.2 and create version 0.35.0-preview.3 by
@gemini-cli-robot in
[#23565](https://github.com/google-gemini/gemini-cli/pull/23565)
- fix(patch): cherry-pick b2d6dc4 to release/v0.35.0-preview.4-pr-23546
[#21816](https://github.com/google-gemini/gemini-cli/pull/21816)
- Changelog for v0.33.0-preview.13 by @gemini-cli-robot in
[#21927](https://github.com/google-gemini/gemini-cli/pull/21927)
- fix(cli): stabilize prompt layout to prevent jumping when typing by
@NTaylorMullen in
[#21081](https://github.com/google-gemini/gemini-cli/pull/21081)
- fix: preserve prompt text when cancelling streaming by @Nixxx19 in
[#21103](https://github.com/google-gemini/gemini-cli/pull/21103)
- fix: robust UX for remote agent errors by @Shyam-Raghuwanshi in
[#20307](https://github.com/google-gemini/gemini-cli/pull/20307)
- feat: implement background process logging and cleanup by @galz10 in
[#21189](https://github.com/google-gemini/gemini-cli/pull/21189)
- Changelog for v0.33.0-preview.14 by @gemini-cli-robot in
[#21938](https://github.com/google-gemini/gemini-cli/pull/21938)
- fix(patch): cherry-pick 45faf4d to release/v0.34.0-preview.0-pr-22148
[CONFLICTS] by @gemini-cli-robot in
[#23585](https://github.com/google-gemini/gemini-cli/pull/23585)
[#22174](https://github.com/google-gemini/gemini-cli/pull/22174)
- fix(patch): cherry-pick 8432bce to release/v0.34.0-preview.1-pr-22069 to patch
version v0.34.0-preview.1 and create version 0.34.0-preview.2 by
@gemini-cli-robot in
[#22205](https://github.com/google-gemini/gemini-cli/pull/22205)
- fix(patch): cherry-pick 24adacd to release/v0.34.0-preview.2-pr-22332 to patch
version v0.34.0-preview.2 and create version 0.34.0-preview.3 by
@gemini-cli-robot in
[#22391](https://github.com/google-gemini/gemini-cli/pull/22391)
- fix(patch): cherry-pick 48130eb to release/v0.34.0-preview.3-pr-22665 to patch
version v0.34.0-preview.3 and create version 0.34.0-preview.4 by
@gemini-cli-robot in
[#22719](https://github.com/google-gemini/gemini-cli/pull/22719)
**Full Changelog**:
https://github.com/google-gemini/gemini-cli/compare/v0.34.0...v0.35.0
https://github.com/google-gemini/gemini-cli/compare/v0.33.2...v0.34.0
+363 -358
View File
@@ -1,6 +1,6 @@
# Preview release: v0.36.0-preview.3
# Preview release: v0.35.0-preview.5
Released: March 25, 2026
Released: March 23, 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,370 +13,375 @@ npm install -g @google/gemini-cli@preview
## Highlights
- **Subagent Architecture Enhancements:** Significant updates to subagents,
including local execution, tool isolation, multi-registry discovery, dynamic
tool filtering, and JIT context injection.
- **Enhanced Security & Sandboxing:** Implemented strict macOS sandboxing using
Seatbelt allowlist, native Windows sandboxing, and support for
"Write-Protected" governance files.
- **Agent Context & State Management:** Introduced task tracker protocol
integration, 'blocked' statuses for tasks/todos, and `AgentSession` for
improved state management and replay semantics.
- **Browser & ACP Capabilities:** Added privacy consent for the browser agent,
sensitive action controls, improved API token usage metadata, and gateway auth
support via ACP.
- **CLI & UX Improvements:** Implemented a refreshed Composer layout, expanded
terminal fallback warnings, dynamic model resolution, and Git worktree support
for isolated parallel sessions.
- **Subagents & Architecture Enhancements**: Enabled subagents and laid the
foundation for subagent tool isolation. Added proxy routing support for remote
A2A subagents and integrated `SandboxManager` to sandbox all process-spawning
tools.
- **CLI & UI Improvements**: Introduced customizable keyboard shortcuts and
support for literal character keybindings. Added missing vim mode motions and
CJK input support. Enabled code splitting and deferred UI loading for improved
performance.
- **Context & Tools Optimization**: JIT context loading is now enabled by
default with deduplication for project memory. Introduced a model-driven
parallel tool scheduler and allowed safe tools to execute concurrently.
- **Security & Extensions**: Implemented cryptographic integrity verification
for extension updates and added a `disableAlwaysAllow` setting to prevent
auto-approvals for enhanced security.
- **Plan Mode & Web Fetch Updates**: Added an 'All the above' option for
multi-select AskUser questions in Plan Mode. Rolled out Stage 1 and Stage 2
security and consistency improvements for the `web_fetch` tool.
## What's Changed
- fix(patch): cherry-pick 055ff92 to release/v0.36.0-preview.0-pr-23672 to patch
version v0.36.0-preview.0 and create version 0.36.0-preview.1 by
- fix(patch): cherry-pick b2d6dc4 to release/v0.35.0-preview.4-pr-23546
[CONFLICTS] by @gemini-cli-robot in
[#23585](https://github.com/google-gemini/gemini-cli/pull/23585)
- fix(patch): cherry-pick daf3691 to release/v0.35.0-preview.2-pr-23558 to patch
version v0.35.0-preview.2 and create version 0.35.0-preview.3 by
@gemini-cli-robot in
[#23723](https://github.com/google-gemini/gemini-cli/pull/23723)
- Changelog for v0.33.2 by @gemini-cli-robot in
[#22730](https://github.com/google-gemini/gemini-cli/pull/22730)
- feat(core): multi-registry architecture and tool filtering for subagents by
@akh64bit in [#22712](https://github.com/google-gemini/gemini-cli/pull/22712)
- Changelog for v0.34.0-preview.4 by @gemini-cli-robot in
[#22752](https://github.com/google-gemini/gemini-cli/pull/22752)
- fix(devtools): use theme-aware text colors for console warnings and errors by
@SandyTao520 in
[#22181](https://github.com/google-gemini/gemini-cli/pull/22181)
- Add support for dynamic model Resolution to ModelConfigService by @kevinjwang1
in [#22578](https://github.com/google-gemini/gemini-cli/pull/22578)
- chore(release): bump version to 0.36.0-nightly.20260317.2f90b4653 by
[#23565](https://github.com/google-gemini/gemini-cli/pull/23565)
- fix(patch): cherry-pick 4e5dfd0 to release/v0.35.0-preview.1-pr-23074 to patch
version v0.35.0-preview.1 and create version 0.35.0-preview.2 by
@gemini-cli-robot in
[#22858](https://github.com/google-gemini/gemini-cli/pull/22858)
- fix(cli): use active sessionId in useLogger and improve resume robustness by
@mattKorwel in
[#22606](https://github.com/google-gemini/gemini-cli/pull/22606)
- fix(cli): expand tilde in policy paths from settings.json by @abhipatel12 in
[#22772](https://github.com/google-gemini/gemini-cli/pull/22772)
- fix(core): add actionable warnings for terminal fallbacks (#14426) by
[#23134](https://github.com/google-gemini/gemini-cli/pull/23134)
- feat(cli): customizable keyboard shortcuts by @scidomino in
[#21945](https://github.com/google-gemini/gemini-cli/pull/21945)
- feat(core): Thread `AgentLoopContext` through core. by @joshualitt in
[#21944](https://github.com/google-gemini/gemini-cli/pull/21944)
- chore(release): bump version to 0.35.0-nightly.20260311.657f19c1f by
@gemini-cli-robot in
[#21966](https://github.com/google-gemini/gemini-cli/pull/21966)
- refactor(a2a): remove legacy CoreToolScheduler by @adamfweidman in
[#21955](https://github.com/google-gemini/gemini-cli/pull/21955)
- feat(ui): add missing vim mode motions (X, ~, r, f/F/t/T, df/dt and friends)
by @aanari in [#21932](https://github.com/google-gemini/gemini-cli/pull/21932)
- Feat/retry fetch notifications by @aishaneeshah in
[#21813](https://github.com/google-gemini/gemini-cli/pull/21813)
- fix(core): remove OAuth check from handleFallback and clean up stray file by
@sehoon38 in [#21962](https://github.com/google-gemini/gemini-cli/pull/21962)
- feat(cli): support literal character keybindings and extended Kitty protocol
keys by @scidomino in
[#21972](https://github.com/google-gemini/gemini-cli/pull/21972)
- fix(ui): clamp cursor to last char after all NORMAL mode deletes by @aanari in
[#21973](https://github.com/google-gemini/gemini-cli/pull/21973)
- test(core): add missing tests for prompts/utils.ts by @krrishverma1805-web in
[#19941](https://github.com/google-gemini/gemini-cli/pull/19941)
- fix(cli): allow scrolling keys in copy mode (Ctrl+S selection mode) by
@nsalerni in [#19933](https://github.com/google-gemini/gemini-cli/pull/19933)
- docs(cli): add custom keybinding documentation by @scidomino in
[#21980](https://github.com/google-gemini/gemini-cli/pull/21980)
- docs: fix misleading YOLO mode description in defaultApprovalMode by
@Gyanranjan-Priyam in
[#21878](https://github.com/google-gemini/gemini-cli/pull/21878)
- fix: clean up /clear and /resume by @jackwotherspoon in
[#22007](https://github.com/google-gemini/gemini-cli/pull/22007)
- fix(core)#20941: reap orphaned descendant processes on PTY abort by @manavmax
in [#21124](https://github.com/google-gemini/gemini-cli/pull/21124)
- fix(core): update language detection to use LSP 3.18 identifiers by @yunaseoul
in [#21931](https://github.com/google-gemini/gemini-cli/pull/21931)
- feat(cli): support removing keybindings via '-' prefix by @scidomino in
[#22042](https://github.com/google-gemini/gemini-cli/pull/22042)
- feat(policy): add --admin-policy flag for supplemental admin policies by
@galz10 in [#20360](https://github.com/google-gemini/gemini-cli/pull/20360)
- merge duplicate imports packages/cli/src subtask1 by @Nixxx19 in
[#22040](https://github.com/google-gemini/gemini-cli/pull/22040)
- perf(core): parallelize user quota and experiments fetching in refreshAuth by
@sehoon38 in [#21648](https://github.com/google-gemini/gemini-cli/pull/21648)
- Changelog for v0.34.0-preview.0 by @gemini-cli-robot in
[#21965](https://github.com/google-gemini/gemini-cli/pull/21965)
- Changelog for v0.33.0 by @gemini-cli-robot in
[#21967](https://github.com/google-gemini/gemini-cli/pull/21967)
- fix(core): handle EISDIR in robustRealpath on Windows by @sehoon38 in
[#21984](https://github.com/google-gemini/gemini-cli/pull/21984)
- feat(core): include initiationMethod in conversation interaction telemetry by
@yunaseoul in [#22054](https://github.com/google-gemini/gemini-cli/pull/22054)
- feat(ui): add vim yank/paste (y/p/P) with unnamed register by @aanari in
[#22026](https://github.com/google-gemini/gemini-cli/pull/22026)
- fix(core): enable numerical routing for api key users by @sehoon38 in
[#21977](https://github.com/google-gemini/gemini-cli/pull/21977)
- feat(telemetry): implement retry attempt telemetry for network related retries
by @aishaneeshah in
[#22027](https://github.com/google-gemini/gemini-cli/pull/22027)
- fix(policy): remove unnecessary escapeRegex from pattern builders by
@spencer426 in
[#22211](https://github.com/google-gemini/gemini-cli/pull/22211)
- feat(tracker): integrate task tracker protocol into core system prompt by
@anj-s in [#22442](https://github.com/google-gemini/gemini-cli/pull/22442)
- chore: add posttest build hooks and fix missing dependencies by @NTaylorMullen
in [#22865](https://github.com/google-gemini/gemini-cli/pull/22865)
- feat(a2a): add agent acknowledgment command and enhance registry discovery by
@alisa-alisa in
[#22389](https://github.com/google-gemini/gemini-cli/pull/22389)
- fix(cli): automatically add all VSCode workspace folders to Gemini context by
@sakshisemalti in
[#21380](https://github.com/google-gemini/gemini-cli/pull/21380)
- feat: add 'blocked' status to tasks and todos by @anj-s in
[#22735](https://github.com/google-gemini/gemini-cli/pull/22735)
- refactor(cli): remove extra newlines in ShellToolMessage.tsx by @NTaylorMullen
in [#22868](https://github.com/google-gemini/gemini-cli/pull/22868)
- fix(cli): lazily load settings in onModelChange to prevent stale closure data
loss by @KumarADITHYA123 in
[#20403](https://github.com/google-gemini/gemini-cli/pull/20403)
- feat(core): subagent local execution and tool isolation by @akh64bit in
[#22718](https://github.com/google-gemini/gemini-cli/pull/22718)
- fix(cli): resolve subagent grouping and UI state persistence by @abhipatel12
in [#22252](https://github.com/google-gemini/gemini-cli/pull/22252)
- refactor(ui): extract SessionBrowser search and navigation components by
@abhipatel12 in
[#22377](https://github.com/google-gemini/gemini-cli/pull/22377)
- fix: updates Docker image reference for GitHub MCP server by @jhhornn in
[#22938](https://github.com/google-gemini/gemini-cli/pull/22938)
- refactor(cli): group subagent trajectory deletion and use native filesystem
testing by @abhipatel12 in
[#22890](https://github.com/google-gemini/gemini-cli/pull/22890)
- refactor(cli): simplify keypress and mouse providers and update tests by
@scidomino in [#22853](https://github.com/google-gemini/gemini-cli/pull/22853)
- Changelog for v0.34.0 by @gemini-cli-robot in
[#22860](https://github.com/google-gemini/gemini-cli/pull/22860)
- test(cli): simplify createMockSettings calls by @scidomino in
[#22952](https://github.com/google-gemini/gemini-cli/pull/22952)
- feat(ui): format multi-line banner warnings with a bold title by @keithguerin
in [#22955](https://github.com/google-gemini/gemini-cli/pull/22955)
- Docs: Remove references to stale Gemini CLI file structure info by
@g-samroberts in
[#22976](https://github.com/google-gemini/gemini-cli/pull/22976)
- feat(ui): remove write todo list tool from UI tips by @aniruddhaadak80 in
[#22281](https://github.com/google-gemini/gemini-cli/pull/22281)
- Fix issue where subagent thoughts are appended. by @gundermanc in
[#22975](https://github.com/google-gemini/gemini-cli/pull/22975)
- Feat/browser privacy consent by @kunal-10-cloud in
[#21119](https://github.com/google-gemini/gemini-cli/pull/21119)
- fix(core): explicitly map execution context in LocalAgentExecutor by @akh64bit
in [#22949](https://github.com/google-gemini/gemini-cli/pull/22949)
- feat(plan): support plan mode in non-interactive mode by @ruomengz in
[#22670](https://github.com/google-gemini/gemini-cli/pull/22670)
- feat(core): implement strict macOS sandboxing using Seatbelt allowlist by
@ehedlund in [#22832](https://github.com/google-gemini/gemini-cli/pull/22832)
- docs: add additional notes by @abhipatel12 in
[#23008](https://github.com/google-gemini/gemini-cli/pull/23008)
- fix(cli): resolve duplicate footer on tool cancel via ESC (#21743) by
@ruomengz in [#21781](https://github.com/google-gemini/gemini-cli/pull/21781)
- Changelog for v0.35.0-preview.1 by @gemini-cli-robot in
[#23012](https://github.com/google-gemini/gemini-cli/pull/23012)
- fix(ui): fix flickering on small terminal heights by @devr0306 in
[#21416](https://github.com/google-gemini/gemini-cli/pull/21416)
- fix(acp): provide more meta in tool_call_update by @Mervap in
[#22663](https://github.com/google-gemini/gemini-cli/pull/22663)
- docs: add FAQ entry for checking Gemini CLI version by @surajsahani in
[#21271](https://github.com/google-gemini/gemini-cli/pull/21271)
- feat(core): resilient subagent tool rejection with contextual feedback by
@abhipatel12 in
[#22951](https://github.com/google-gemini/gemini-cli/pull/22951)
- fix(cli): correctly handle auto-update for standalone binaries by @bdmorgan in
[#23038](https://github.com/google-gemini/gemini-cli/pull/23038)
- feat(core): add content-utils by @adamfweidman in
[#22984](https://github.com/google-gemini/gemini-cli/pull/22984)
- fix: circumvent genai sdk requirement for api key when using gateway auth via
ACP by @sripasg in
[#23042](https://github.com/google-gemini/gemini-cli/pull/23042)
- fix(core): don't persist browser consent sentinel in non-interactive mode by
@jasonmatthewsuhari in
[#23073](https://github.com/google-gemini/gemini-cli/pull/23073)
- fix(core): narrow browser agent description to prevent stealing URL tasks from
web_fetch by @gsquared94 in
[#23086](https://github.com/google-gemini/gemini-cli/pull/23086)
- feat(cli): Partial threading of AgentLoopContext. by @joshualitt in
[#22978](https://github.com/google-gemini/gemini-cli/pull/22978)
- fix(browser-agent): enable "Allow all server tools" session policy by
@cynthialong0-0 in
[#22343](https://github.com/google-gemini/gemini-cli/pull/22343)
- refactor(cli): integrate real config loading into async test utils by
@scidomino in [#23040](https://github.com/google-gemini/gemini-cli/pull/23040)
- feat(core): inject memory and JIT context into subagents by @abhipatel12 in
[#23032](https://github.com/google-gemini/gemini-cli/pull/23032)
- Fix logging and virtual list. by @jacob314 in
[#23080](https://github.com/google-gemini/gemini-cli/pull/23080)
- feat(core): cap JIT context upward traversal at git root by @SandyTao520 in
[#23074](https://github.com/google-gemini/gemini-cli/pull/23074)
- Docs: Minor style updates from initial docs audit. by @g-samroberts in
[#22872](https://github.com/google-gemini/gemini-cli/pull/22872)
- feat(core): add experimental memory manager agent to replace save_memory tool
by @SandyTao520 in
[#22726](https://github.com/google-gemini/gemini-cli/pull/22726)
- Changelog for v0.35.0-preview.2 by @gemini-cli-robot in
[#23142](https://github.com/google-gemini/gemini-cli/pull/23142)
- Update website issue template for label and title by @g-samroberts in
[#23036](https://github.com/google-gemini/gemini-cli/pull/23036)
- fix: upgrade ACP SDK from 0.12 to 0.16.1 by @sripasg in
[#23132](https://github.com/google-gemini/gemini-cli/pull/23132)
- Update callouts to work on github. by @g-samroberts in
[#22245](https://github.com/google-gemini/gemini-cli/pull/22245)
- feat: ACP: Add token usage metadata to the `send` method's return value by
@sripasg in [#23148](https://github.com/google-gemini/gemini-cli/pull/23148)
- fix(plan): clarify that plan mode policies are combined with normal mode by
@ruomengz in [#23158](https://github.com/google-gemini/gemini-cli/pull/23158)
- Add ModelChain support to ModelConfigService and make ModelDialog dynamic by
@kevinjwang1 in
[#22914](https://github.com/google-gemini/gemini-cli/pull/22914)
- Ensure that copied extensions are writable in the user's local directory by
@kevinjwang1 in
[#23016](https://github.com/google-gemini/gemini-cli/pull/23016)
- feat(core): implement native Windows sandboxing by @mattKorwel in
[#21807](https://github.com/google-gemini/gemini-cli/pull/21807)
- feat(core): add support for admin-forced MCP server installations by
@gsquared94 in
[#23163](https://github.com/google-gemini/gemini-cli/pull/23163)
- chore(lint): ignore .gemini directory and recursive node_modules by
@mattKorwel in
[#23211](https://github.com/google-gemini/gemini-cli/pull/23211)
- feat(cli): conditionally exclude ask_user tool in ACP mode by @nmcnamara-eng
in [#23045](https://github.com/google-gemini/gemini-cli/pull/23045)
- feat(core): introduce AgentSession and rename stream events to agent events by
@mbleigh in [#23159](https://github.com/google-gemini/gemini-cli/pull/23159)
- feat(worktree): add Git worktree support for isolated parallel sessions by
@jerop in [#22973](https://github.com/google-gemini/gemini-cli/pull/22973)
- Add support for linking in the extension registry by @kevinjwang1 in
[#23153](https://github.com/google-gemini/gemini-cli/pull/23153)
- feat(extensions): add --skip-settings flag to install command by @Ratish1 in
[#17212](https://github.com/google-gemini/gemini-cli/pull/17212)
- feat(telemetry): track if session is running in a Git worktree by @jerop in
[#23265](https://github.com/google-gemini/gemini-cli/pull/23265)
- refactor(core): use absolute paths in GEMINI.md context markers by
@SandyTao520 in
[#23135](https://github.com/google-gemini/gemini-cli/pull/23135)
- fix(core): add sanitization to sub agent thoughts and centralize utilities by
@devr0306 in [#22828](https://github.com/google-gemini/gemini-cli/pull/22828)
- feat(core): refine User-Agent for VS Code traffic (unified format) by
@sehoon38 in [#23256](https://github.com/google-gemini/gemini-cli/pull/23256)
- Fix schema for ModelChains by @kevinjwang1 in
[#23284](https://github.com/google-gemini/gemini-cli/pull/23284)
- test(cli): refactor tests for async render utilities by @scidomino in
[#23252](https://github.com/google-gemini/gemini-cli/pull/23252)
- feat(core): add security prompt for browser agent by @cynthialong0-0 in
[#23241](https://github.com/google-gemini/gemini-cli/pull/23241)
- refactor(ide): replace dynamic undici import with static fetch import by
@cocosheng-g in
[#23268](https://github.com/google-gemini/gemini-cli/pull/23268)
- test(cli): address unresolved feedback from PR #23252 by @scidomino in
[#23303](https://github.com/google-gemini/gemini-cli/pull/23303)
- feat(browser): add sensitive action controls and read-only noise reduction by
@cynthialong0-0 in
[#22867](https://github.com/google-gemini/gemini-cli/pull/22867)
- Disabling failing test while investigating by @alisa-alisa in
[#23311](https://github.com/google-gemini/gemini-cli/pull/23311)
- fix broken extension link in hooks guide by @Indrapal-70 in
[#21728](https://github.com/google-gemini/gemini-cli/pull/21728)
- fix(core): fix agent description indentation by @abhipatel12 in
[#23315](https://github.com/google-gemini/gemini-cli/pull/23315)
- Wrap the text under TOML rule for easier readability in policy-engine.md… by
@CogitationOps in
[#23076](https://github.com/google-gemini/gemini-cli/pull/23076)
- fix(extensions): revert broken extension removal behavior by @ehedlund in
[#23317](https://github.com/google-gemini/gemini-cli/pull/23317)
- feat(core): set up onboarding telemetry by @yunaseoul in
[#23118](https://github.com/google-gemini/gemini-cli/pull/23118)
- Retry evals on API error. by @gundermanc in
[#23322](https://github.com/google-gemini/gemini-cli/pull/23322)
- fix(evals): remove tool restrictions and add compile-time guards by
@SandyTao520 in
[#23312](https://github.com/google-gemini/gemini-cli/pull/23312)
- fix(hooks): support 'ask' decision for BeforeTool hooks by @gundermanc in
[#21146](https://github.com/google-gemini/gemini-cli/pull/21146)
- feat(browser): add warning message for session mode 'existing' by
@cynthialong0-0 in
[#23288](https://github.com/google-gemini/gemini-cli/pull/23288)
- chore(lint): enforce zero warnings and cleanup syntax restrictions by
@alisa-alisa in
[#22902](https://github.com/google-gemini/gemini-cli/pull/22902)
- fix(cli): add Esc instruction to HooksDialog footer by @abhipatel12 in
[#23258](https://github.com/google-gemini/gemini-cli/pull/23258)
- Disallow and suppress misused spread operator. by @gundermanc in
[#23294](https://github.com/google-gemini/gemini-cli/pull/23294)
- fix(core): refine CliHelpAgent description for better delegation by
@abhipatel12 in
[#23310](https://github.com/google-gemini/gemini-cli/pull/23310)
- fix(core): enable global session and persistent approval for web_fetch by
[#21921](https://github.com/google-gemini/gemini-cli/pull/21921)
- fix(core): preserve dynamic tool descriptions on session resume by @sehoon38
in [#18835](https://github.com/google-gemini/gemini-cli/pull/18835)
- chore: allow 'gemini-3.1' in sensitive keyword linter by @scidomino in
[#22065](https://github.com/google-gemini/gemini-cli/pull/22065)
- feat(core): support custom base URL via env vars by @junaiddshaukat in
[#21561](https://github.com/google-gemini/gemini-cli/pull/21561)
- merge duplicate imports packages/cli/src subtask2 by @Nixxx19 in
[#22051](https://github.com/google-gemini/gemini-cli/pull/22051)
- fix(core): silently retry API errors up to 3 times before halting session by
@spencer426 in
[#21989](https://github.com/google-gemini/gemini-cli/pull/21989)
- feat(core): simplify subagent success UI and improve early termination display
by @abhipatel12 in
[#21917](https://github.com/google-gemini/gemini-cli/pull/21917)
- merge duplicate imports packages/cli/src subtask3 by @Nixxx19 in
[#22056](https://github.com/google-gemini/gemini-cli/pull/22056)
- fix(hooks): fix BeforeAgent/AfterAgent inconsistencies (#18514) by @krishdef7
in [#21383](https://github.com/google-gemini/gemini-cli/pull/21383)
- feat(core): implement SandboxManager interface and config schema by @galz10 in
[#21774](https://github.com/google-gemini/gemini-cli/pull/21774)
- docs: document npm deprecation warnings as safe to ignore by @h30s in
[#20692](https://github.com/google-gemini/gemini-cli/pull/20692)
- fix: remove status/need-triage from maintainer-only issues by @SandyTao520 in
[#22044](https://github.com/google-gemini/gemini-cli/pull/22044)
- fix(core): propagate subagent context to policy engine by @NTaylorMullen in
[#22086](https://github.com/google-gemini/gemini-cli/pull/22086)
- fix(cli): resolve skill uninstall failure when skill name is updated by
@NTaylorMullen in
[#23295](https://github.com/google-gemini/gemini-cli/pull/23295)
- fix(plan): add state transition override to prevent plan mode freeze by
@Adib234 in [#23020](https://github.com/google-gemini/gemini-cli/pull/23020)
- fix(cli): record skill activation tool calls in chat history by @NTaylorMullen
in [#23203](https://github.com/google-gemini/gemini-cli/pull/23203)
- fix(core): ensure subagent tool updates apply configuration overrides
immediately by @abhipatel12 in
[#23161](https://github.com/google-gemini/gemini-cli/pull/23161)
- fix(cli): resolve flicker at boundaries of list in BaseSelectionList by
@jackwotherspoon in
[#23298](https://github.com/google-gemini/gemini-cli/pull/23298)
- test(cli): force generic terminal in tests to fix snapshot failures by
@abhipatel12 in
[#23499](https://github.com/google-gemini/gemini-cli/pull/23499)
- Evals: PR Guidance adding workflow by @alisa-alisa in
[#23164](https://github.com/google-gemini/gemini-cli/pull/23164)
- feat(core): refactor SandboxManager to a stateless architecture and introduce
explicit Deny interface by @ehedlund in
[#23141](https://github.com/google-gemini/gemini-cli/pull/23141)
- feat(core): add event-translator and update agent types by @adamfweidman in
[#22985](https://github.com/google-gemini/gemini-cli/pull/22985)
- perf(cli): parallelize and background startup cleanup tasks by @sehoon38 in
[#23545](https://github.com/google-gemini/gemini-cli/pull/23545)
- fix: "allow always" for commands with paths by @scidomino in
[#23558](https://github.com/google-gemini/gemini-cli/pull/23558)
- fix(cli): prevent terminal escape sequences from leaking on exit by
@mattKorwel in
[#22682](https://github.com/google-gemini/gemini-cli/pull/22682)
- feat(cli): implement full "GEMINI CLI" logo for logged-out state by
@keithguerin in
[#22412](https://github.com/google-gemini/gemini-cli/pull/22412)
- fix(plan): reserve minimum height for selection list in AskUserDialog by
@ruomengz in [#23280](https://github.com/google-gemini/gemini-cli/pull/23280)
- fix(core): harden AgentSession replay semantics by @adamfweidman in
[#23548](https://github.com/google-gemini/gemini-cli/pull/23548)
- test(core): migrate hook tests to scheduler by @abhipatel12 in
[#23496](https://github.com/google-gemini/gemini-cli/pull/23496)
- chore(config): disable agents by default by @abhipatel12 in
[#23546](https://github.com/google-gemini/gemini-cli/pull/23546)
- fix(ui): make tool confirmations take up entire terminal height by @devr0306
in [#22366](https://github.com/google-gemini/gemini-cli/pull/22366)
- fix(core): prevent redundant remote agent loading on model switch by
[#22085](https://github.com/google-gemini/gemini-cli/pull/22085)
- docs(plan): clarify interactive plan editing with Ctrl+X by @Adib234 in
[#22076](https://github.com/google-gemini/gemini-cli/pull/22076)
- fix(policy): ensure user policies are loaded when policyPaths is empty by
@NTaylorMullen in
[#22090](https://github.com/google-gemini/gemini-cli/pull/22090)
- Docs: Add documentation for model steering (experimental). by @jkcinouye in
[#21154](https://github.com/google-gemini/gemini-cli/pull/21154)
- Add issue for automated changelogs by @g-samroberts in
[#21912](https://github.com/google-gemini/gemini-cli/pull/21912)
- fix(core): secure argsPattern and revert WEB_FETCH_TOOL_NAME escalation by
@spencer426 in
[#22104](https://github.com/google-gemini/gemini-cli/pull/22104)
- feat(core): differentiate User-Agent for a2a-server and ACP clients by
@bdmorgan in [#22059](https://github.com/google-gemini/gemini-cli/pull/22059)
- refactor(core): extract ExecutionLifecycleService for tool backgrounding by
@adamfweidman in
[#23576](https://github.com/google-gemini/gemini-cli/pull/23576)
- refactor(core): update production type imports from coreToolScheduler by
@abhipatel12 in
[#23498](https://github.com/google-gemini/gemini-cli/pull/23498)
- feat(cli): always prefix extension skills with colon separator by
@NTaylorMullen in
[#23566](https://github.com/google-gemini/gemini-cli/pull/23566)
- fix(core): properly support allowRedirect in policy engine by @scidomino in
[#23579](https://github.com/google-gemini/gemini-cli/pull/23579)
- fix(cli): prevent subcommand shadowing and skip auth for commands by
@mattKorwel in
[#23177](https://github.com/google-gemini/gemini-cli/pull/23177)
- fix(test): move flaky tests to non-blocking suite by @mattKorwel in
[#23259](https://github.com/google-gemini/gemini-cli/pull/23259)
- Changelog for v0.35.0-preview.3 by @gemini-cli-robot in
[#23574](https://github.com/google-gemini/gemini-cli/pull/23574)
- feat(skills): add behavioral-evals skill with fixing and promoting guides by
@abhipatel12 in
[#23349](https://github.com/google-gemini/gemini-cli/pull/23349)
- refactor(core): delete obsolete coreToolScheduler by @abhipatel12 in
[#23502](https://github.com/google-gemini/gemini-cli/pull/23502)
- Changelog for v0.35.0-preview.4 by @gemini-cli-robot in
[#23581](https://github.com/google-gemini/gemini-cli/pull/23581)
- feat(core): add LegacyAgentSession by @adamfweidman in
[#22986](https://github.com/google-gemini/gemini-cli/pull/22986)
- feat(test-utils): add TestMcpServerBuilder and support in TestRig by
@abhipatel12 in
[#23491](https://github.com/google-gemini/gemini-cli/pull/23491)
- fix(core)!: Force policy config to specify toolName by @kschaab in
[#23330](https://github.com/google-gemini/gemini-cli/pull/23330)
- eval(save_memory): add multi-turn interactive evals for memoryManager by
@SandyTao520 in
[#23572](https://github.com/google-gemini/gemini-cli/pull/23572)
- fix(telemetry): patch memory leak and enforce logPrompts privacy by
[#21717](https://github.com/google-gemini/gemini-cli/pull/21717)
- feat: Display pending and confirming tool calls by @sripasg in
[#22106](https://github.com/google-gemini/gemini-cli/pull/22106)
- feat(browser): implement input blocker overlay during automation by
@kunal-10-cloud in
[#21132](https://github.com/google-gemini/gemini-cli/pull/21132)
- fix: register themes on extension load not start by @jackwotherspoon in
[#22148](https://github.com/google-gemini/gemini-cli/pull/22148)
- feat(ui): Do not show Ultra users /upgrade hint (#22154) by @sehoon38 in
[#22156](https://github.com/google-gemini/gemini-cli/pull/22156)
- chore: remove unnecessary log for themes by @jackwotherspoon in
[#22165](https://github.com/google-gemini/gemini-cli/pull/22165)
- fix(core): resolve MCP tool FQN validation, schema export, and wildcards in
subagents by @abhipatel12 in
[#22069](https://github.com/google-gemini/gemini-cli/pull/22069)
- fix(cli): validate --model argument at startup by @JaisalJain in
[#21393](https://github.com/google-gemini/gemini-cli/pull/21393)
- fix(core): handle policy ALLOW for exit_plan_mode by @backnotprop in
[#21802](https://github.com/google-gemini/gemini-cli/pull/21802)
- feat(telemetry): add Clearcut instrumentation for AI credits billing events by
@gsquared94 in
[#22153](https://github.com/google-gemini/gemini-cli/pull/22153)
- feat(core): add google credentials provider for remote agents by @adamfweidman
in [#21024](https://github.com/google-gemini/gemini-cli/pull/21024)
- test(cli): add integration test for node deprecation warnings by @Nixxx19 in
[#20215](https://github.com/google-gemini/gemini-cli/pull/20215)
- feat(cli): allow safe tools to execute concurrently while agent is busy by
@spencer426 in
[#23281](https://github.com/google-gemini/gemini-cli/pull/23281)
- perf(cli): background IDE client to speed up initialization by @sehoon38 in
[#23603](https://github.com/google-gemini/gemini-cli/pull/23603)
- fix(cli): prevent Ctrl+D exit when input buffer is not empty by @wtanaka in
[#23306](https://github.com/google-gemini/gemini-cli/pull/23306)
- fix: ACP: separate conversational text from execute tool command title by
@sripasg in [#23179](https://github.com/google-gemini/gemini-cli/pull/23179)
- feat(evals): add behavioral evaluations for subagent routing by @Samee24 in
[#23272](https://github.com/google-gemini/gemini-cli/pull/23272)
- refactor(cli,core): foundational layout, identity management, and type safety
by @jwhelangoog in
[#23286](https://github.com/google-gemini/gemini-cli/pull/23286)
- fix(core): accurately reflect subagent tool failure in UI by @abhipatel12 in
[#23187](https://github.com/google-gemini/gemini-cli/pull/23187)
- Changelog for v0.35.0-preview.5 by @gemini-cli-robot in
[#23606](https://github.com/google-gemini/gemini-cli/pull/23606)
- feat(ui): implement refreshed UX for Composer layout by @jwhelangoog in
[#21212](https://github.com/google-gemini/gemini-cli/pull/21212)
- fix: API key input dialog user interaction when selected Gemini API Key by
@kartikangiras in
[#21057](https://github.com/google-gemini/gemini-cli/pull/21057)
- docs: update `/mcp refresh` to `/mcp reload` by @adamfweidman in
[#23631](https://github.com/google-gemini/gemini-cli/pull/23631)
- Implementation of sandbox "Write-Protected" Governance Files by @DavidAPierce
in [#23139](https://github.com/google-gemini/gemini-cli/pull/23139)
- feat(sandbox): dynamic macOS sandbox expansion and worktree support by @galz10
in [#23301](https://github.com/google-gemini/gemini-cli/pull/23301)
- fix(acp): Pass the cwd to `AcpFileSystemService` to avoid looping failures in
asking for perms to write plan md file by @sripasg in
[#23612](https://github.com/google-gemini/gemini-cli/pull/23612)
- fix(plan): sandbox path resolution in Plan Mode to prevent hallucinations by
@Adib234 in [#22737](https://github.com/google-gemini/gemini-cli/pull/22737)
- feat(ui): allow immediate user input during startup by @sehoon38 in
[#23661](https://github.com/google-gemini/gemini-cli/pull/23661)
- refactor(sandbox): reorganize Windows sandbox files by @galz10 in
[#23645](https://github.com/google-gemini/gemini-cli/pull/23645)
- fix(core): improve remote agent streaming UI and UX by @adamfweidman in
[#23633](https://github.com/google-gemini/gemini-cli/pull/23633)
- perf(cli): optimize --version startup time by @sehoon38 in
[#23671](https://github.com/google-gemini/gemini-cli/pull/23671)
- refactor(core): stop gemini CLI from producing unsafe casts by @gundermanc in
[#23611](https://github.com/google-gemini/gemini-cli/pull/23611)
- use enableAutoUpdate in test rig by @scidomino in
[#23681](https://github.com/google-gemini/gemini-cli/pull/23681)
- feat(core): change user-facing auth type from oauth2 to oauth by @adamfweidman
in [#23639](https://github.com/google-gemini/gemini-cli/pull/23639)
- chore(deps): fix npm audit vulnerabilities by @scidomino in
[#23679](https://github.com/google-gemini/gemini-cli/pull/23679)
- test(evals): fix overlapping act() deadlock in app-test-helper by @Adib234 in
[#23666](https://github.com/google-gemini/gemini-cli/pull/23666)
[#21988](https://github.com/google-gemini/gemini-cli/pull/21988)
- feat(core): implement model-driven parallel tool scheduler by @abhipatel12 in
[#21933](https://github.com/google-gemini/gemini-cli/pull/21933)
- update vulnerable deps by @scidomino in
[#22180](https://github.com/google-gemini/gemini-cli/pull/22180)
- fix(core): fix startup stats to use int values for timestamps and durations by
@yunaseoul in [#22201](https://github.com/google-gemini/gemini-cli/pull/22201)
- fix(core): prevent duplicate tool schemas for instantiated tools by
@abhipatel12 in
[#22204](https://github.com/google-gemini/gemini-cli/pull/22204)
- fix(core): add proxy routing support for remote A2A subagents by @adamfweidman
in [#22199](https://github.com/google-gemini/gemini-cli/pull/22199)
- fix(core/ide): add Antigravity CLI fallbacks by @apfine in
[#22030](https://github.com/google-gemini/gemini-cli/pull/22030)
- fix(browser): fix duplicate function declaration error in browser agent by
@gsquared94 in
[#22207](https://github.com/google-gemini/gemini-cli/pull/22207)
- feat(core): implement Stage 1 improvements for webfetch tool by @aishaneeshah
in [#21313](https://github.com/google-gemini/gemini-cli/pull/21313)
- Changelog for v0.34.0-preview.1 by @gemini-cli-robot in
[#22194](https://github.com/google-gemini/gemini-cli/pull/22194)
- perf(cli): enable code splitting and deferred UI loading by @sehoon38 in
[#22117](https://github.com/google-gemini/gemini-cli/pull/22117)
- fix: remove unused img.png from project root by @SandyTao520 in
[#22222](https://github.com/google-gemini/gemini-cli/pull/22222)
- docs(local model routing): add docs on how to use Gemma for local model
routing by @douglas-reid in
[#21365](https://github.com/google-gemini/gemini-cli/pull/21365)
- feat(a2a): enable native gRPC support and protocol routing by @alisa-alisa in
[#21403](https://github.com/google-gemini/gemini-cli/pull/21403)
- fix(cli): escape @ symbols on paste to prevent unintended file expansion by
@krishdef7 in [#21239](https://github.com/google-gemini/gemini-cli/pull/21239)
- feat(core): add trajectoryId to ConversationOffered telemetry by @yunaseoul in
[#22214](https://github.com/google-gemini/gemini-cli/pull/22214)
- docs: clarify that tools.core is an allowlist for ALL built-in tools by
@hobostay in [#18813](https://github.com/google-gemini/gemini-cli/pull/18813)
- docs(plan): document hooks with plan mode by @ruomengz in
[#22197](https://github.com/google-gemini/gemini-cli/pull/22197)
- Changelog for v0.33.1 by @gemini-cli-robot in
[#22235](https://github.com/google-gemini/gemini-cli/pull/22235)
- build(ci): fix false positive evals trigger on merge commits by @gundermanc in
[#22237](https://github.com/google-gemini/gemini-cli/pull/22237)
- fix(core): explicitly pass messageBus to policy engine for MCP tool saves by
@abhipatel12 in
[#22255](https://github.com/google-gemini/gemini-cli/pull/22255)
- feat(core): Fully migrate packages/core to AgentLoopContext. by @joshualitt in
[#22115](https://github.com/google-gemini/gemini-cli/pull/22115)
- feat(core): increase sub-agent turn and time limits by @bdmorgan in
[#22196](https://github.com/google-gemini/gemini-cli/pull/22196)
- feat(core): instrument file system tools for JIT context discovery by
@SandyTao520 in
[#22082](https://github.com/google-gemini/gemini-cli/pull/22082)
- refactor(ui): extract pure session browser utilities by @abhipatel12 in
[#22256](https://github.com/google-gemini/gemini-cli/pull/22256)
- fix(plan): Fix AskUser evals by @Adib234 in
[#22074](https://github.com/google-gemini/gemini-cli/pull/22074)
- fix(settings): prevent j/k navigation keys from intercepting edit buffer input
by @student-ankitpandit in
[#21865](https://github.com/google-gemini/gemini-cli/pull/21865)
- feat(skills): improve async-pr-review workflow and logging by @mattKorwel in
[#21790](https://github.com/google-gemini/gemini-cli/pull/21790)
- refactor(cli): consolidate getErrorMessage utility to core by @scidomino in
[#22190](https://github.com/google-gemini/gemini-cli/pull/22190)
- fix(core): show descriptive error messages when saving settings fails by
@afarber in [#18095](https://github.com/google-gemini/gemini-cli/pull/18095)
- docs(core): add authentication guide for remote subagents by @adamfweidman in
[#22178](https://github.com/google-gemini/gemini-cli/pull/22178)
- docs: overhaul subagents documentation and add /agents command by @abhipatel12
in [#22345](https://github.com/google-gemini/gemini-cli/pull/22345)
- refactor(ui): extract SessionBrowser static ui components by @abhipatel12 in
[#22348](https://github.com/google-gemini/gemini-cli/pull/22348)
- test: add Object.create context regression test and tool confirmation
integration test by @gsquared94 in
[#22356](https://github.com/google-gemini/gemini-cli/pull/22356)
- feat(tracker): return TodoList display for tracker tools by @anj-s in
[#22060](https://github.com/google-gemini/gemini-cli/pull/22060)
- feat(agent): add allowed domain restrictions for browser agent by
@cynthialong0-0 in
[#21775](https://github.com/google-gemini/gemini-cli/pull/21775)
- chore/release: bump version to 0.35.0-nightly.20260313.bb060d7a9 by
@gemini-cli-robot in
[#22251](https://github.com/google-gemini/gemini-cli/pull/22251)
- Move keychain fallback to keychain service by @chrstnb in
[#22332](https://github.com/google-gemini/gemini-cli/pull/22332)
- feat(core): integrate SandboxManager to sandbox all process-spawning tools by
@galz10 in [#22231](https://github.com/google-gemini/gemini-cli/pull/22231)
- fix(cli): support CJK input and full Unicode scalar values in terminal
protocols by @scidomino in
[#22353](https://github.com/google-gemini/gemini-cli/pull/22353)
- Promote stable tests. by @gundermanc in
[#22253](https://github.com/google-gemini/gemini-cli/pull/22253)
- feat(tracker): add tracker policy by @anj-s in
[#22379](https://github.com/google-gemini/gemini-cli/pull/22379)
- feat(security): add disableAlwaysAllow setting to disable auto-approvals by
@galz10 in [#21941](https://github.com/google-gemini/gemini-cli/pull/21941)
- Revert "fix(cli): validate --model argument at startup" by @sehoon38 in
[#22378](https://github.com/google-gemini/gemini-cli/pull/22378)
- fix(mcp): handle equivalent root resource URLs in OAuth validation by @galz10
in [#20231](https://github.com/google-gemini/gemini-cli/pull/20231)
- fix(core): use session-specific temp directory for task tracker by @anj-s in
[#22382](https://github.com/google-gemini/gemini-cli/pull/22382)
- Fix issue where config was undefined. by @gundermanc in
[#22397](https://github.com/google-gemini/gemini-cli/pull/22397)
- fix(core): deduplicate project memory when JIT context is enabled by
@SandyTao520 in
[#22234](https://github.com/google-gemini/gemini-cli/pull/22234)
- feat(prompts): implement Topic-Action-Summary model for verbosity reduction by
@Abhijit-2592 in
[#21503](https://github.com/google-gemini/gemini-cli/pull/21503)
- fix(core): fix manual deletion of subagent histories by @abhipatel12 in
[#22407](https://github.com/google-gemini/gemini-cli/pull/22407)
- Add registry var by @kevinjwang1 in
[#22224](https://github.com/google-gemini/gemini-cli/pull/22224)
- Add ModelDefinitions to ModelConfigService by @kevinjwang1 in
[#22302](https://github.com/google-gemini/gemini-cli/pull/22302)
- fix(cli): improve command conflict handling for skills by @NTaylorMullen in
[#21942](https://github.com/google-gemini/gemini-cli/pull/21942)
- fix(core): merge user settings with extension-provided MCP servers by
@abhipatel12 in
[#22484](https://github.com/google-gemini/gemini-cli/pull/22484)
- fix(core): skip discovery for incomplete MCP configs and resolve merge race
condition by @abhipatel12 in
[#22494](https://github.com/google-gemini/gemini-cli/pull/22494)
- fix(automation): harden stale PR closer permissions and maintainer detection
by @bdmorgan in
[#22558](https://github.com/google-gemini/gemini-cli/pull/22558)
- fix(automation): evaluate staleness before checking protected labels by
@bdmorgan in [#22561](https://github.com/google-gemini/gemini-cli/pull/22561)
- feat(agent): replace the runtime npx for browser agent chrome devtool mcp with
pre-built bundle by @cynthialong0-0 in
[#22213](https://github.com/google-gemini/gemini-cli/pull/22213)
- perf: optimize TrackerService dependency checks by @anj-s in
[#22384](https://github.com/google-gemini/gemini-cli/pull/22384)
- docs(policy): remove trailing space from commandPrefix examples by @kawasin73
in [#22264](https://github.com/google-gemini/gemini-cli/pull/22264)
- fix(a2a-server): resolve unsafe assignment lint errors by @ehedlund in
[#22661](https://github.com/google-gemini/gemini-cli/pull/22661)
- fix: Adjust ToolGroupMessage filtering to hide Confirming and show Canceled
tool calls. by @sripasg in
[#22230](https://github.com/google-gemini/gemini-cli/pull/22230)
- Disallow Object.create() and reflect. by @gundermanc in
[#22408](https://github.com/google-gemini/gemini-cli/pull/22408)
- Guard pro model usage by @sehoon38 in
[#22665](https://github.com/google-gemini/gemini-cli/pull/22665)
- refactor(core): Creates AgentSession abstraction for consolidated agent
interface. by @mbleigh in
[#22270](https://github.com/google-gemini/gemini-cli/pull/22270)
- docs(changelog): remove internal commands from release notes by
@jackwotherspoon in
[#22529](https://github.com/google-gemini/gemini-cli/pull/22529)
- feat: enable subagents by @abhipatel12 in
[#22386](https://github.com/google-gemini/gemini-cli/pull/22386)
- feat(extensions): implement cryptographic integrity verification for extension
updates by @ehedlund in
[#21772](https://github.com/google-gemini/gemini-cli/pull/21772)
- feat(tracker): polish UI sorting and formatting by @anj-s in
[#22437](https://github.com/google-gemini/gemini-cli/pull/22437)
- Changelog for v0.34.0-preview.2 by @gemini-cli-robot in
[#22220](https://github.com/google-gemini/gemini-cli/pull/22220)
- fix(core): fix three JIT context bugs in read_file, read_many_files, and
memoryDiscovery by @SandyTao520 in
[#22679](https://github.com/google-gemini/gemini-cli/pull/22679)
- refactor(core): introduce InjectionService with source-aware injection and
backend-native background completions by @adamfweidman in
[#22544](https://github.com/google-gemini/gemini-cli/pull/22544)
- Linux sandbox bubblewrap by @DavidAPierce in
[#22680](https://github.com/google-gemini/gemini-cli/pull/22680)
- feat(core): increase thought signature retry resilience by @bdmorgan in
[#22202](https://github.com/google-gemini/gemini-cli/pull/22202)
- feat(core): implement Stage 2 security and consistency improvements for
web_fetch by @aishaneeshah in
[#22217](https://github.com/google-gemini/gemini-cli/pull/22217)
- refactor(core): replace positional execute params with ExecuteOptions bag by
@adamfweidman in
[#22674](https://github.com/google-gemini/gemini-cli/pull/22674)
- feat(config): enable JIT context loading by default by @SandyTao520 in
[#22736](https://github.com/google-gemini/gemini-cli/pull/22736)
- fix(config): ensure discoveryMaxDirs is passed to global config during
initialization by @kevin-ramdass in
[#22744](https://github.com/google-gemini/gemini-cli/pull/22744)
- fix(plan): allowlist get_internal_docs in Plan Mode by @Adib234 in
[#22668](https://github.com/google-gemini/gemini-cli/pull/22668)
- Changelog for v0.34.0-preview.3 by @gemini-cli-robot in
[#22393](https://github.com/google-gemini/gemini-cli/pull/22393)
- feat(core): add foundation for subagent tool isolation by @akh64bit in
[#22708](https://github.com/google-gemini/gemini-cli/pull/22708)
- fix(core): handle surrogate pairs in truncateString by @sehoon38 in
[#22754](https://github.com/google-gemini/gemini-cli/pull/22754)
- fix(cli): override j/k navigation in settings dialog to fix search input
conflict by @sehoon38 in
[#22800](https://github.com/google-gemini/gemini-cli/pull/22800)
- feat(plan): add 'All the above' option to multi-select AskUser questions by
@Adib234 in [#22365](https://github.com/google-gemini/gemini-cli/pull/22365)
- docs: distribute package-specific GEMINI.md context to each package by
@SandyTao520 in
[#22734](https://github.com/google-gemini/gemini-cli/pull/22734)
- fix(cli): clean up stale pasted placeholder metadata after word/line deletions
by @Jomak-x in
[#20375](https://github.com/google-gemini/gemini-cli/pull/20375)
- refactor(core): align JIT memory placement with tiered context model by
@SandyTao520 in
[#22766](https://github.com/google-gemini/gemini-cli/pull/22766)
- Linux sandbox seccomp by @DavidAPierce in
[#22815](https://github.com/google-gemini/gemini-cli/pull/22815)
**Full Changelog**:
https://github.com/google-gemini/gemini-cli/compare/v0.35.0-preview.5...v0.36.0-preview.3
https://github.com/google-gemini/gemini-cli/compare/v0.34.0-preview.4...v0.35.0-preview.5
+1 -1
View File
@@ -24,7 +24,7 @@ Once Gemini CLI is installed, run Gemini CLI from your command line:
gemini
```
For more installation options, see [Gemini CLI Installation](./installation/).
For more installation options, see [Gemini CLI Installation](./installation.md).
## Authenticate
@@ -23,33 +23,34 @@ installation methods, and release types.
We recommend most users install Gemini CLI using one of the following
installation methods:
{% tabs %}
{% tabitem label="npm" %}
Install globally with npm:
- npm
- Homebrew
- MacPorts
- Anaconda
Note that Gemini CLI comes pre-installed on
[**Cloud Shell**](https://docs.cloud.google.com/shell/docs) and
[**Cloud Workstations**](https://cloud.google.com/workstations).
### Install globally with npm
```bash
npm install -g @google/gemini-cli
```
{% /tabitem %}
{% tabitem label="Homebrew" %}
Install globally with Homebrew (macOS/Linux):
### Install globally with Homebrew (macOS/Linux)
```bash
brew install gemini-cli
```
{% /tabitem %}
{% tabitem label="MacPorts" %}
Install globally with MacPorts (macOS):
### Install globally with MacPorts (macOS)
```bash
sudo port install gemini-cli
```
{% /tabitem %}
{% tabitem label="Anaconda" %}
Install with Anaconda (for restricted environments):
### Install with Anaconda (for restricted environments)
```bash
# Create and activate a new environment
@@ -59,12 +60,6 @@ conda activate gemini_env
# Install Gemini CLI globally via npm (inside the environment)
npm install -g @google/gemini-cli
```
{% /tabitem %}
{% /tabs %}
Note that Gemini CLI comes pre-installed on
[**Cloud Shell**](https://docs.cloud.google.com/shell/docs) and
[**Cloud Workstations**](https://cloud.google.com/workstations).
## Run Gemini CLI
@@ -107,7 +102,7 @@ the default way that the CLI executes tools that might have side effects.
to run the CLI.
```bash
# Run the published sandbox image
docker run --rm -it us-docker.pkg.dev/gemini-code-dev/gemini-cli/sandbox:latest
docker run --rm -it us-docker.pkg.dev/gemini-code-dev/gemini-cli/sandbox:0.1.1
```
- **Using the `--sandbox` flag:** If you have Gemini CLI installed locally
(using the standard installation described above), you can instruct it to run
-157
View File
@@ -1,157 +0,0 @@
# Gemini CLI installation, execution, and releases
This document provides an overview of Gemini CLI's system requirements,
installation methods, and release types.
## Recommended system specifications
- **Operating System:**
- macOS 15+
- Windows 11 24H2+
- Ubuntu 20.04+
- **Hardware:**
- "Casual" usage: 4GB+ RAM (short sessions, common tasks and edits)
- "Power" usage: 16GB+ RAM (long sessions, large codebases, deep context)
- **Runtime:** Node.js 20.0.0+
- **Shell:** Bash, Zsh, or PowerShell
- **Location:**
[Gemini Code Assist supported locations](https://developers.google.com/gemini-code-assist/resources/available-locations#americas)
- **Internet connection required**
## Install Gemini CLI
We recommend most users install Gemini CLI using one of the following
installation methods:
<Tabs>
<TabItem label="npm">
Install globally with npm:
```bash
npm install -g @google/gemini-cli
```
</TabItem>
<TabItem label="Homebrew">
Install globally with Homebrew (macOS/Linux):
```bash
brew install gemini-cli
```
</TabItem>
</Tabs>
Note that Gemini CLI comes pre-installed on
[**Cloud Shell**](https://docs.cloud.google.com/shell/docs) and
[**Cloud Workstations**](https://cloud.google.com/workstations).
## Run Gemini CLI
For most users, we recommend running Gemini CLI with the `gemini` command:
```bash
gemini
```
For a list of options and additional commands, see the
[CLI cheatsheet](../cli/cli-reference.md).
You can also run Gemini CLI using one of the following advanced methods:
- Run instantly with npx. You can run Gemini CLI without permanent installation.
- In a sandbox. This method offers increased security and isolation.
- From the source. This is recommended for contributors to the project.
### Run instantly with npx
```bash
# Using npx (no installation required)
npx @google/gemini-cli
```
You can also execute the CLI directly from the main branch on GitHub, which is
helpful for testing features still in development:
```bash
npx https://github.com/google-gemini/gemini-cli
```
### Run in a sandbox (Docker/Podman)
For security and isolation, Gemini CLI can be run inside a container. This is
the default way that the CLI executes tools that might have side effects.
- **Directly from the registry:** You can run the published sandbox image
directly. This is useful for environments where you only have Docker and want
to run the CLI.
```bash
# Run the published sandbox image
docker run --rm -it us-docker.pkg.dev/gemini-code-dev/gemini-cli/sandbox:latest
```
- **Using the `--sandbox` flag:** If you have Gemini CLI installed locally
(using the standard installation described above), you can instruct it to run
inside the sandbox container.
```bash
gemini --sandbox -y -p "your prompt here"
```
### Run from source (recommended for Gemini CLI contributors)
Contributors to the project will want to run the CLI directly from the source
code.
- **Development mode:** This method provides hot-reloading and is useful for
active development.
```bash
# From the root of the repository
npm run start
```
- **Production-like mode (linked package):** This method simulates a global
installation by linking your local package. It's useful for testing a local
build in a production workflow.
```bash
# Link the local cli package to your global node_modules
npm link packages/cli
# Now you can run your local version using the `gemini` command
gemini
```
## Releases
Gemini CLI has three release channels: nightly, preview, and stable. For most
users, we recommend the stable release, which is the default installation.
### Stable
New stable releases are published each week. The stable release is the promotion
of last week's `preview` release along with any bug fixes. The stable release
uses `latest` tag, but omitting the tag also installs the latest stable release
by default:
```bash
# Both commands install the latest stable release.
npm install -g @google/gemini-cli
npm install -g @google/gemini-cli@latest
```
### Preview
New preview releases will be published each week. These releases are not fully
vetted and may contain regressions or other outstanding issues. Try out the
preview release by using the `preview` tag:
```bash
npm install -g @google/gemini-cli@preview
```
### Nightly
Nightly releases are published every day. The nightly release includes all
changes from the main branch at time of release. It should be assumed there are
pending validations and issues. You can help test the latest changes by
installing with the `nightly` tag:
```bash
npm install -g @google/gemini-cli@nightly
```
+2 -2
View File
@@ -15,8 +15,8 @@ npm install -g @google/gemini-cli
Jump in to Gemini CLI.
- **[Quickstart](./get-started/index.md):** Your first session with Gemini CLI.
- **[Installation](./get-started/installation/):** How to install Gemini CLI on
your system.
- **[Installation](./get-started/installation.md):** How to install Gemini CLI
on your system.
- **[Authentication](./get-started/authentication.md):** Setup instructions for
personal and enterprise accounts.
- **[Examples](./get-started/examples.md):** Practical examples of Gemini CLI in
+1 -25
View File
@@ -646,11 +646,6 @@ their corresponding top-level category object in your `settings.json` file.
"model": "gemini-3-flash-preview"
}
},
"chat-compression-3.1-flash-lite": {
"modelConfig": {
"model": "gemini-3.1-flash-lite-preview"
}
},
"chat-compression-2.5-pro": {
"modelConfig": {
"model": "gemini-2.5-pro"
@@ -985,17 +980,6 @@ their corresponding top-level category object in your `settings.json` file.
"auto-gemini-2.5": {
"default": "gemini-2.5-pro"
},
"gemini-3.1-flash-lite-preview": {
"default": "gemini-3.1-flash-lite-preview",
"contexts": [
{
"condition": {
"useGemini3_1FlashLite": false
},
"target": "gemini-2.5-flash-lite"
}
]
},
"flash": {
"default": "gemini-3-flash-preview",
"contexts": [
@@ -1008,15 +992,7 @@ their corresponding top-level category object in your `settings.json` file.
]
},
"flash-lite": {
"default": "gemini-2.5-flash-lite",
"contexts": [
{
"condition": {
"useGemini3_1FlashLite": true
},
"target": "gemini-3.1-flash-lite-preview"
}
]
"default": "gemini-2.5-flash-lite"
}
}
```
+21 -5
View File
@@ -6,12 +6,19 @@
* SPDX-License-Identifier: Apache-2.0
*/
import { main } from './src/gemini.js';
import { FatalError, writeToStderr } from '@google/gemini-cli-core';
import { runExitCleanup } from './src/utils/cleanup.js';
// --- Fast Path for Version ---
// We check for version flags at the very top to avoid loading any heavy dependencies.
// process.env.CLI_VERSION is defined during the build process by esbuild.
if (process.argv.includes('--version') || process.argv.includes('-v')) {
console.log(process.env['CLI_VERSION'] || 'unknown');
process.exit(0);
}
// --- Global Entry Point ---
let writeToStderrFn: (message: string) => void = (msg) =>
process.stderr.write(msg);
// Suppress known race condition error in node-pty on Windows
// Tracking bug: https://github.com/microsoft/node-pty/issues/827
process.on('uncaughtException', (error) => {
@@ -28,13 +35,22 @@ process.on('uncaughtException', (error) => {
// For other errors, we rely on the default behavior, but since we attached a listener,
// we must manually replicate it.
if (error instanceof Error) {
writeToStderr(error.stack + '\n');
writeToStderrFn(error.stack + '\n');
} else {
writeToStderr(String(error) + '\n');
writeToStderrFn(String(error) + '\n');
}
process.exit(1);
});
const [{ main }, { FatalError, writeToStderr }, { runExitCleanup }] =
await Promise.all([
import('./src/gemini.js'),
import('@google/gemini-cli-core'),
import('./src/utils/cleanup.js'),
]);
writeToStderrFn = writeToStderr;
main().catch(async (error) => {
// Set a timeout to force exit if cleanup hangs
const cleanupTimeout = setTimeout(() => {
@@ -3024,7 +3024,6 @@ export const SETTINGS_SCHEMA_DEFINITIONS: Record<
type: 'object',
properties: {
useGemini3_1: { type: 'boolean' },
useGemini3_1FlashLite: { type: 'boolean' },
useCustomTools: { type: 'boolean' },
hasAccessToPreview: { type: 'boolean' },
requestedModels: {
@@ -61,7 +61,7 @@ import type { UIState } from '../contexts/UIStateContext.js';
import { isLowColorDepth } from '../utils/terminalUtils.js';
import { cpLen } from '../utils/textUtils.js';
import { defaultKeyMatchers, Command } from '../key/keyMatchers.js';
import { useKeypress, type Key } from '../hooks/useKeypress.js';
import type { Key } from '../hooks/useKeypress.js';
import {
appEvents,
AppEvent,
@@ -163,18 +163,6 @@ describe('InputPrompt', () => {
let mockBuffer: TextBuffer;
let mockCommandContext: CommandContext;
const GlobalEscapeHandler = ({ onEscape }: { onEscape: () => void }) => {
useKeypress(
(key) => {
if (key.name !== 'escape') return false;
onEscape();
return true;
},
{ isActive: true, priority: false },
);
return null;
};
const mockedUseShellHistory = vi.mocked(useShellHistory);
const mockedUseCommandCompletion = vi.mocked(useCommandCompletion);
const mockedUseInputHistory = vi.mocked(useInputHistory);
@@ -2782,54 +2770,6 @@ describe('InputPrompt', () => {
unmount();
});
it('should not propagate ESC to global cancellation handler when shell mode is active (responding)', async () => {
props.shellModeActive = true;
props.streamingState = StreamingState.Responding;
const onGlobalEscape = vi.fn();
const { stdin, unmount } = await renderWithProviders(
<>
<GlobalEscapeHandler onEscape={onGlobalEscape} />
<InputPrompt {...props} />
</>,
);
await act(async () => {
stdin.write('\x1B');
vi.advanceTimersByTime(100);
});
await waitFor(() => {
expect(props.setShellModeActive).toHaveBeenCalledWith(false);
});
expect(onGlobalEscape).not.toHaveBeenCalled();
unmount();
});
it('should allow ESC to reach global cancellation handler when responding and no overlay is active', async () => {
props.shellModeActive = false;
props.streamingState = StreamingState.Responding;
const onGlobalEscape = vi.fn();
const { stdin, unmount } = await renderWithProviders(
<>
<GlobalEscapeHandler onEscape={onGlobalEscape} />
<InputPrompt {...props} />
</>,
);
await act(async () => {
stdin.write('\x1B');
vi.advanceTimersByTime(100);
});
await waitFor(() => {
expect(onGlobalEscape).toHaveBeenCalledTimes(1);
});
expect(props.setShellModeActive).not.toHaveBeenCalled();
unmount();
});
it('should handle ESC when completion suggestions are showing', async () => {
mockedUseCommandCompletion.mockReturnValue({
...mockCommandCompletion,
@@ -686,9 +686,13 @@ export const InputPrompt: React.FC<InputPromptProps> = ({
return true;
}
const isGenerating =
streamingState === StreamingState.Responding ||
streamingState === StreamingState.WaitingForConfirmation;
if (
key.name === 'escape' &&
(streamingState === StreamingState.Responding ||
streamingState === StreamingState.WaitingForConfirmation)
) {
return false;
}
const isPlainTab =
key.name === 'tab' && !key.shift && !key.alt && !key.ctrl && !key.cmd;
@@ -873,12 +877,6 @@ export const InputPrompt: React.FC<InputPromptProps> = ({
return true;
}
// If we're generating and no local overlay consumed Escape, let it
// propagate to the global cancellation handler.
if (isGenerating) {
return false;
}
handleEscPress();
return true;
}
@@ -21,10 +21,7 @@ import {
type UIState,
} from '../contexts/UIStateContext.js';
import { type IndividualToolCallDisplay } from '../types.js';
import {
type ConfirmingToolState,
useConfirmingTool,
} from '../hooks/useConfirmingTool.js';
import { type ConfirmingToolState } from '../hooks/useConfirmingTool.js';
// Mock dependencies
const mockUseSettings = vi.fn().mockReturnValue({
@@ -551,11 +548,10 @@ describe('MainContent', () => {
config: makeFakeConfig({ useAlternateBuffer: false }),
});
await waitFor(() => {
expect(lastFrame()).toContain('codebase_investigator');
});
const output = lastFrame();
expect(lastFrame()).toMatchSnapshot();
expect(output).toContain('codebase_investigator');
expect(output).toMatchSnapshot();
unmount();
});
@@ -603,16 +599,13 @@ describe('MainContent', () => {
const { lastFrame, unmount } = await renderWithProviders(<MainContent />, {
uiState: uiState as Partial<UIState>,
});
await waitFor(() => {
const output = lastFrame();
// Verify Part 1 and Part 2 are rendered.
expect(output).toContain('Part 1');
expect(output).toContain('Part 2');
});
const output = lastFrame();
// Verify Part 1 and Part 2 are rendered.
expect(output).toContain('Part 1');
expect(output).toContain('Part 2');
// The snapshot will be the best way to verify there is no gap (empty line) between them.
expect(lastFrame()).toMatchSnapshot();
expect(output).toMatchSnapshot();
unmount();
});
@@ -657,6 +650,7 @@ describe('MainContent', () => {
};
// We need to mock useConfirmingTool to return our confirmingTool
const { useConfirmingTool } = await import('../hooks/useConfirmingTool.js');
vi.mocked(useConfirmingTool).mockReturnValue(
confirmingTool as unknown as ConfirmingToolState,
);
@@ -673,16 +667,15 @@ describe('MainContent', () => {
config: makeFakeConfig({ useAlternateBuffer: false }),
});
await waitFor(() => {
const output = lastFrame();
// The output should NOT contain 'Hidden content'
expect(output).not.toContain('Hidden content');
// The output should contain the confirmation header
expect(output).toContain('Ready to start implementation?');
});
const output = lastFrame();
// The output should NOT contain 'Hidden content'
expect(output).not.toContain('Hidden content');
// The output should contain the confirmation header
expect(output).toContain('Ready to start implementation?');
// Snapshot will reveal if there are extra blank lines
expect(lastFrame()).toMatchSnapshot();
expect(output).toMatchSnapshot();
unmount();
});
@@ -715,12 +708,9 @@ describe('MainContent', () => {
config: makeFakeConfig({ useAlternateBuffer: false }),
});
await waitFor(() => {
expect(lastFrame()).toContain('Apply plan');
});
const output = lastFrame();
// This snapshot will show no spurious line because the group is now correctly suppressed.
expect(lastFrame()).toMatchSnapshot();
expect(output).toMatchSnapshot();
unmount();
});
@@ -53,7 +53,6 @@ describe('<ModelDialog />', () => {
const mockOnClose = vi.fn();
const mockGetHasAccessToPreviewModel = vi.fn();
const mockGetGemini31LaunchedSync = vi.fn();
const mockGetGemini31FlashLiteLaunchedSync = vi.fn();
const mockGetProModelNoAccess = vi.fn();
const mockGetProModelNoAccessSync = vi.fn();
const mockGetUserTier = vi.fn();
@@ -64,7 +63,6 @@ describe('<ModelDialog />', () => {
getHasAccessToPreviewModel: () => boolean;
getIdeMode: () => boolean;
getGemini31LaunchedSync: () => boolean;
getGemini31FlashLiteLaunchedSync: () => boolean;
getProModelNoAccess: () => Promise<boolean>;
getProModelNoAccessSync: () => boolean;
getUserTier: () => UserTierId | undefined;
@@ -76,7 +74,6 @@ describe('<ModelDialog />', () => {
getHasAccessToPreviewModel: mockGetHasAccessToPreviewModel,
getIdeMode: () => false,
getGemini31LaunchedSync: mockGetGemini31LaunchedSync,
getGemini31FlashLiteLaunchedSync: mockGetGemini31FlashLiteLaunchedSync,
getProModelNoAccess: mockGetProModelNoAccess,
getProModelNoAccessSync: mockGetProModelNoAccessSync,
getUserTier: mockGetUserTier,
@@ -87,7 +84,6 @@ describe('<ModelDialog />', () => {
mockGetModel.mockReturnValue(DEFAULT_GEMINI_MODEL_AUTO);
mockGetHasAccessToPreviewModel.mockReturnValue(false);
mockGetGemini31LaunchedSync.mockReturnValue(false);
mockGetGemini31FlashLiteLaunchedSync.mockReturnValue(false);
mockGetProModelNoAccess.mockResolvedValue(false);
mockGetProModelNoAccessSync.mockReturnValue(false);
mockGetUserTier.mockReturnValue(UserTierId.STANDARD);
@@ -135,7 +131,6 @@ describe('<ModelDialog />', () => {
mockGetProModelNoAccessSync.mockReturnValue(true);
mockGetProModelNoAccess.mockResolvedValue(true);
mockGetHasAccessToPreviewModel.mockReturnValue(true);
mockGetGemini31FlashLiteLaunchedSync.mockReturnValue(true);
mockGetUserTier.mockReturnValue(UserTierId.FREE);
mockGetDisplayString.mockImplementation((val: string) => val);
@@ -468,7 +463,6 @@ describe('<ModelDialog />', () => {
mockGetProModelNoAccessSync.mockReturnValue(false);
mockGetProModelNoAccess.mockResolvedValue(false);
mockGetHasAccessToPreviewModel.mockReturnValue(true);
mockGetGemini31FlashLiteLaunchedSync.mockReturnValue(true);
mockGetUserTier.mockReturnValue(UserTierId.FREE);
const { lastFrame, stdin, waitUntilReady, unmount } =
await renderComponent();
+2 -11
View File
@@ -63,8 +63,6 @@ export function ModelDialog({ onClose }: ModelDialogProps): React.JSX.Element {
const shouldShowPreviewModels = config?.getHasAccessToPreviewModel();
const useGemini31 = config?.getGemini31LaunchedSync?.() ?? false;
const useGemini31FlashLite =
config?.getGemini31FlashLiteLaunchedSync?.() ?? false;
const selectedAuthType = settings.merged.security.auth.selectedType;
const useCustomToolModel =
useGemini31 && selectedAuthType === AuthType.USE_GEMINI;
@@ -88,7 +86,6 @@ export function ModelDialog({ onClose }: ModelDialogProps): React.JSX.Element {
PREVIEW_GEMINI_MODEL,
PREVIEW_GEMINI_3_1_MODEL,
PREVIEW_GEMINI_3_1_CUSTOM_TOOLS_MODEL,
PREVIEW_GEMINI_3_1_FLASH_LITE_MODEL,
PREVIEW_GEMINI_FLASH_MODEL,
];
if (manualModels.includes(preferredModel)) {
@@ -213,10 +210,7 @@ export function ModelDialog({ onClose }: ModelDialogProps): React.JSX.Element {
// Flag Guard: Versioned models only show if their flag is active.
if (id === PREVIEW_GEMINI_3_1_MODEL && !useGemini31) return false;
if (
id === PREVIEW_GEMINI_3_1_FLASH_LITE_MODEL &&
!useGemini31FlashLite
)
if (id === PREVIEW_GEMINI_3_1_FLASH_LITE_MODEL && !useGemini31)
return false;
return true;
@@ -224,13 +218,11 @@ export function ModelDialog({ onClose }: ModelDialogProps): React.JSX.Element {
.map(([id, m]) => {
const resolvedId = config.modelConfigService.resolveModelId(id, {
useGemini3_1: useGemini31,
useGemini3_1FlashLite: useGemini31FlashLite,
useCustomTools: useCustomToolModel,
});
// Title ID is the resolved ID without custom tools flag
const titleId = config.modelConfigService.resolveModelId(id, {
useGemini3_1: useGemini31,
useGemini3_1FlashLite: useGemini31FlashLite,
});
return {
value: resolvedId,
@@ -292,7 +284,7 @@ export function ModelDialog({ onClose }: ModelDialogProps): React.JSX.Element {
},
];
if (isFreeTier && useGemini31FlashLite) {
if (isFreeTier) {
previewOptions.push({
value: PREVIEW_GEMINI_3_1_FLASH_LITE_MODEL,
title: getDisplayString(PREVIEW_GEMINI_3_1_FLASH_LITE_MODEL),
@@ -312,7 +304,6 @@ export function ModelDialog({ onClose }: ModelDialogProps): React.JSX.Element {
}, [
shouldShowPreviewModels,
useGemini31,
useGemini31FlashLite,
useCustomToolModel,
hasAccessToProModel,
config,
@@ -92,7 +92,6 @@ const buildModelRows = (
config: Config,
quotas?: RetrieveUserQuotaResponse,
useGemini3_1 = false,
useGemini3_1FlashLite = false,
useCustomToolModel = false,
) => {
const getBaseModelName = (name: string) => name.replace('-001', '');
@@ -125,12 +124,7 @@ const buildModelRows = (
?.filter(
(b) =>
b.modelId &&
isActiveModel(
b.modelId,
useGemini3_1,
useGemini3_1FlashLite,
useCustomToolModel,
) &&
isActiveModel(b.modelId, useGemini3_1, useCustomToolModel) &&
!usedModelNames.has(getDisplayString(b.modelId, config)),
)
.map((bucket) => ({
@@ -158,7 +152,6 @@ const ModelUsageTable: React.FC<{
pooledLimit?: number;
pooledResetTime?: string;
useGemini3_1?: boolean;
useGemini3_1FlashLite?: boolean;
useCustomToolModel?: boolean;
}> = ({
models,
@@ -171,7 +164,6 @@ const ModelUsageTable: React.FC<{
pooledLimit,
pooledResetTime,
useGemini3_1,
useGemini3_1FlashLite,
useCustomToolModel,
}) => {
const { stdout } = useStdout();
@@ -181,7 +173,6 @@ const ModelUsageTable: React.FC<{
config,
quotas,
useGemini3_1,
useGemini3_1FlashLite,
useCustomToolModel,
);
@@ -550,8 +541,6 @@ export const StatsDisplay: React.FC<StatsDisplayProps> = ({
const settings = useSettings();
const config = useConfig();
const useGemini3_1 = config.getGemini31LaunchedSync?.() ?? false;
const useGemini3_1FlashLite =
config.getGemini31FlashLiteLaunchedSync?.() ?? false;
const useCustomToolModel =
useGemini3_1 &&
config.getContentGeneratorConfig().authType === AuthType.USE_GEMINI;
@@ -708,7 +697,6 @@ export const StatsDisplay: React.FC<StatsDisplayProps> = ({
pooledLimit={pooledLimit}
pooledResetTime={pooledResetTime}
useGemini3_1={useGemini3_1}
useGemini3_1FlashLite={useGemini3_1FlashLite}
useCustomToolModel={useCustomToolModel}
/>
{renderFooter()}
@@ -1,6 +1,6 @@
/**
* @license
* Copyright 2026 Google LLC
* Copyright 2025 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
@@ -8,7 +8,6 @@ import { render } from '../../../test-utils/render.js';
import { describe, it, expect } from 'vitest';
import { SkillsList } from './SkillsList.js';
import { type SkillDefinition } from '@google/gemini-cli-core';
import { SKILLS_DOCS_URL } from '../../constants.js';
describe('SkillsList Component', () => {
const mockSkills: SkillDefinition[] = [
@@ -75,8 +74,9 @@ describe('SkillsList Component', () => {
<SkillsList skills={[]} showDescriptions={true} />,
);
const output = lastFrame();
expect(output).toContain('No skills available.');
expect(output).toContain(`Learn how to add skills: ${SKILLS_DOCS_URL}`);
expect(output).toContain('No skills available');
unmount();
});
@@ -8,7 +8,6 @@ import type React from 'react';
import { Box, Text } from 'ink';
import { theme } from '../../semantic-colors.js';
import { type SkillDefinition } from '../../types.js';
import { SKILLS_DOCS_URL } from '../../constants.js';
interface SkillsListProps {
skills: readonly SkillDefinition[];
@@ -87,13 +86,7 @@ export const SkillsList: React.FC<SkillsListProps> = ({
)}
{skills.length === 0 && (
<Box flexDirection="column">
<Text color={theme.text.primary}>No skills available.</Text>
<Box flexDirection="row">
<Text color={theme.text.primary}>Learn how to add skills: </Text>
<Text color={theme.text.link}>{SKILLS_DOCS_URL}</Text>
</Box>
</Box>
<Text color={theme.text.primary}> No skills available</Text>
)}
</Box>
);
-4
View File
@@ -58,7 +58,3 @@ export const MIN_TERMINAL_WIDTH_FOR_FULL_LABEL = 100;
/** Default context usage fraction at which to trigger compression */
export const DEFAULT_COMPRESSION_THRESHOLD = 0.5;
/** Documentation URL for skills setup and configuration */
export const SKILLS_DOCS_URL =
'https://github.com/google-gemini/gemini-cli/blob/main/docs/cli/skills.md';
@@ -14,7 +14,6 @@ import {
useKeypressContext,
ESC_TIMEOUT,
FAST_RETURN_TIMEOUT,
KeypressPriority,
type Key,
} from './KeypressContext.js';
import { terminalCapabilityManager } from '../utils/terminalCapabilityManager.js';
@@ -260,48 +259,6 @@ describe('KeypressContext', () => {
);
});
it('should stop propagation when a higher priority handler returns true', async () => {
const higherPriorityHandler = vi.fn(() => true);
const lowerPriorityHandler = vi.fn();
const { result } = await renderHookWithProviders(() =>
useKeypressContext(),
);
act(() => {
result.current.subscribe(higherPriorityHandler, KeypressPriority.High);
result.current.subscribe(lowerPriorityHandler, KeypressPriority.Normal);
});
act(() => stdin.write('\x1b[27u'));
expect(higherPriorityHandler).toHaveBeenCalledWith(
expect.objectContaining({ name: 'escape' }),
);
expect(lowerPriorityHandler).not.toHaveBeenCalled();
});
it('should continue propagation when a higher priority handler does not consume the event', async () => {
const higherPriorityHandler = vi.fn(() => false);
const lowerPriorityHandler = vi.fn();
const { result } = await renderHookWithProviders(() =>
useKeypressContext(),
);
act(() => {
result.current.subscribe(higherPriorityHandler, KeypressPriority.High);
result.current.subscribe(lowerPriorityHandler, KeypressPriority.Normal);
});
act(() => stdin.write('\x1b[27u'));
expect(higherPriorityHandler).toHaveBeenCalledWith(
expect.objectContaining({ name: 'escape' }),
);
expect(lowerPriorityHandler).toHaveBeenCalledWith(
expect.objectContaining({ name: 'escape' }),
);
});
it('should handle double Escape', async () => {
const keyHandler = vi.fn();
const { result } = await renderHookWithProviders(() =>
@@ -28,7 +28,6 @@ describe('policyCatalog', () => {
const chain = getModelPolicyChain({
previewEnabled: true,
useGemini31: true,
useGemini31FlashLite: false,
});
expect(chain[0]?.model).toBe(PREVIEW_GEMINI_3_1_MODEL);
expect(chain).toHaveLength(2);
@@ -39,7 +38,6 @@ describe('policyCatalog', () => {
const chain = getModelPolicyChain({
previewEnabled: true,
useGemini31: true,
useGemini31FlashLite: false,
useCustomToolModel: true,
});
expect(chain[0]?.model).toBe(PREVIEW_GEMINI_3_1_CUSTOM_TOOLS_MODEL);
@@ -30,7 +30,6 @@ export interface ModelPolicyOptions {
previewEnabled: boolean;
userTier?: UserTierId;
useGemini31?: boolean;
useGemini31FlashLite?: boolean;
useCustomToolModel?: boolean;
}
@@ -86,7 +85,6 @@ export function getModelPolicyChain(
const previewModel = resolveModel(
PREVIEW_GEMINI_MODEL,
options.useGemini31,
options.useGemini31FlashLite,
options.useCustomToolModel,
);
return [
@@ -27,7 +27,6 @@ const createMockConfig = (overrides: Partial<Config> = {}): Config => {
getUserTier: () => undefined,
getModel: () => 'gemini-2.5-pro',
getGemini31LaunchedSync: () => false,
getGemini31FlashLiteLaunchedSync: () => false,
getUseCustomToolModelSync: () => {
const useGemini31 = config.getGemini31LaunchedSync();
const authType = config.getContentGeneratorConfig().authType;
@@ -204,7 +203,6 @@ describe('policyHelpers', () => {
getExperimentalDynamicModelConfiguration: () => dynamic,
getModel: () => model,
getGemini31LaunchedSync: () => useGemini31 ?? false,
getGemini31FlashLiteLaunchedSync: () => false,
getHasAccessToPreviewModel: () => hasAccess ?? true,
getContentGeneratorConfig: () => ({ authType }),
modelConfigService: new ModelConfigService(DEFAULT_MODEL_CONFIGS),
@@ -45,15 +45,12 @@ export function resolvePolicyChain(
let chain;
const useGemini31 = config.getGemini31LaunchedSync?.() ?? false;
const useGemini31FlashLite =
config.getGemini31FlashLiteLaunchedSync?.() ?? false;
const useCustomToolModel = config.getUseCustomToolModelSync?.() ?? false;
const hasAccessToPreview = config.getHasAccessToPreviewModel?.() ?? true;
const resolvedModel = resolveModel(
modelFromConfig,
useGemini31,
useGemini31FlashLite,
useCustomToolModel,
hasAccessToPreview,
config,
@@ -67,7 +64,6 @@ export function resolvePolicyChain(
if (config.getExperimentalDynamicModelConfiguration?.() === true) {
const context = {
useGemini3_1: useGemini31,
useGemini3_1FlashLite: useGemini31FlashLite,
useCustomTools: useCustomToolModel,
};
@@ -124,7 +120,6 @@ export function resolvePolicyChain(
previewEnabled,
userTier: config.getUserTier(),
useGemini31,
useGemini31FlashLite,
useCustomToolModel,
});
} else {
@@ -134,7 +129,6 @@ export function resolvePolicyChain(
previewEnabled: false,
userTier: config.getUserTier(),
useGemini31,
useGemini31FlashLite,
useCustomToolModel,
});
}
@@ -18,7 +18,6 @@ export const ExperimentFlags = {
MASKING_PROTECT_LATEST_TURN: 45758819,
GEMINI_3_1_PRO_LAUNCHED: 45760185,
PRO_MODEL_NO_ACCESS: 45768879,
GEMINI_3_1_FLASH_LITE_LAUNCHED: 45771641,
} as const;
export type ExperimentFlagName =
+1 -43
View File
@@ -1820,10 +1820,6 @@ export class Config implements McpContext, AgentLoopContext {
const primaryModel = resolveModel(
this.getModel(),
this.getGemini31LaunchedSync(),
this.getGemini31FlashLiteLaunchedSync(),
this.getUseCustomToolModelSync(),
this.getHasAccessToPreviewModel(),
this,
);
return this.modelQuotas.get(primaryModel)?.remaining;
}
@@ -1836,10 +1832,6 @@ export class Config implements McpContext, AgentLoopContext {
const primaryModel = resolveModel(
this.getModel(),
this.getGemini31LaunchedSync(),
this.getGemini31FlashLiteLaunchedSync(),
this.getUseCustomToolModelSync(),
this.getHasAccessToPreviewModel(),
this,
);
return this.modelQuotas.get(primaryModel)?.limit;
}
@@ -1852,10 +1844,6 @@ export class Config implements McpContext, AgentLoopContext {
const primaryModel = resolveModel(
this.getModel(),
this.getGemini31LaunchedSync(),
this.getGemini31FlashLiteLaunchedSync(),
this.getUseCustomToolModelSync(),
this.getHasAccessToPreviewModel(),
this,
);
return this.modelQuotas.get(primaryModel)?.resetTime;
}
@@ -2919,7 +2907,7 @@ export class Config implements McpContext, AgentLoopContext {
}
/**
* Returns whether Gemini 3.1 Pro has been launched.
* Returns whether Gemini 3.1 has been launched.
* This method is async and ensures that experiments are loaded before returning the result.
*/
async getGemini31Launched(): Promise<boolean> {
@@ -2927,15 +2915,6 @@ export class Config implements McpContext, AgentLoopContext {
return this.getGemini31LaunchedSync();
}
/**
* Returns whether Gemini 3.1 Flash Lite has been launched.
* This method is async and ensures that experiments are loaded before returning the result.
*/
async getGemini31FlashLiteLaunched(): Promise<boolean> {
await this.ensureExperimentsLoaded();
return this.getGemini31FlashLiteLaunchedSync();
}
/**
* Returns whether the custom tool model should be used.
*/
@@ -2977,27 +2956,6 @@ export class Config implements McpContext, AgentLoopContext {
);
}
/**
* Returns whether Gemini 3.1 Flash Lite has been launched.
*
* Note: This method should only be called after startup, once experiments have been loaded.
* If you need to call this during startup or from an async context, use
* getGemini31FlashLiteLaunched instead.
*/
getGemini31FlashLiteLaunchedSync(): boolean {
const authType = this.contentGeneratorConfig?.authType;
if (
authType === AuthType.USE_GEMINI ||
authType === AuthType.USE_VERTEX_AI
) {
return true;
}
return (
this.experiments?.flags[ExperimentFlags.GEMINI_3_1_FLASH_LITE_LAUNCHED]
?.boolValue ?? false
);
}
private async ensureExperimentsLoaded(): Promise<void> {
if (!this.experimentsPromise) {
return;
@@ -218,11 +218,6 @@ export const DEFAULT_MODEL_CONFIGS: ModelConfigServiceConfig = {
model: 'gemini-3-flash-preview',
},
},
'chat-compression-3.1-flash-lite': {
modelConfig: {
model: 'gemini-3.1-flash-lite-preview',
},
},
'chat-compression-2.5-pro': {
modelConfig: {
model: 'gemini-2.5-pro',
@@ -441,15 +436,6 @@ export const DEFAULT_MODEL_CONFIGS: ModelConfigServiceConfig = {
'auto-gemini-2.5': {
default: 'gemini-2.5-pro',
},
'gemini-3.1-flash-lite-preview': {
default: 'gemini-3.1-flash-lite-preview',
contexts: [
{
condition: { useGemini3_1FlashLite: false },
target: 'gemini-2.5-flash-lite',
},
],
},
flash: {
default: 'gemini-3-flash-preview',
contexts: [
@@ -461,12 +447,6 @@ export const DEFAULT_MODEL_CONFIGS: ModelConfigServiceConfig = {
},
'flash-lite': {
default: 'gemini-2.5-flash-lite',
contexts: [
{
condition: { useGemini3_1FlashLite: true },
target: 'gemini-3.1-flash-lite-preview',
},
],
},
},
classifierIdResolutions: {
+29 -94
View File
@@ -21,7 +21,6 @@ import {
supportsMultimodalFunctionResponse,
GEMINI_MODEL_ALIAS_PRO,
GEMINI_MODEL_ALIAS_FLASH,
GEMINI_MODEL_ALIAS_FLASH_LITE,
GEMINI_MODEL_ALIAS_AUTO,
PREVIEW_GEMINI_FLASH_MODEL,
PREVIEW_GEMINI_MODEL_AUTO,
@@ -62,26 +61,9 @@ describe('Dynamic Configuration Parity', () => {
];
const flagCombos = [
{
useGemini3_1: false,
useGemini3_1FlashLite: false,
useCustomToolModel: false,
},
{
useGemini3_1: true,
useGemini3_1FlashLite: false,
useCustomToolModel: false,
},
{
useGemini3_1: true,
useGemini3_1FlashLite: true,
useCustomToolModel: false,
},
{
useGemini3_1: true,
useGemini3_1FlashLite: true,
useCustomToolModel: true,
},
{ useGemini3_1: false, useCustomToolModel: false },
{ useGemini3_1: true, useCustomToolModel: false },
{ useGemini3_1: true, useCustomToolModel: true },
];
it('resolveModel should match legacy behavior when dynamicModelConfiguration flag enabled.', () => {
@@ -102,7 +84,6 @@ describe('Dynamic Configuration Parity', () => {
const legacy = resolveModel(
model,
flags.useGemini3_1,
flags.useGemini3_1FlashLite,
flags.useCustomToolModel,
hasAccess,
mockLegacyConfig,
@@ -110,7 +91,6 @@ describe('Dynamic Configuration Parity', () => {
const dynamic = resolveModel(
model,
flags.useGemini3_1,
flags.useGemini3_1FlashLite,
flags.useCustomToolModel,
hasAccess,
mockDynamicConfig,
@@ -149,7 +129,6 @@ describe('Dynamic Configuration Parity', () => {
anchor,
tier,
flags.useGemini3_1,
flags.useGemini3_1FlashLite,
flags.useCustomToolModel,
hasAccess,
mockLegacyConfig,
@@ -158,7 +137,6 @@ describe('Dynamic Configuration Parity', () => {
anchor,
tier,
flags.useGemini3_1,
flags.useGemini3_1FlashLite,
flags.useCustomToolModel,
hasAccess,
mockDynamicConfig,
@@ -391,7 +369,7 @@ describe('resolveModel', () => {
});
it('should return Gemini 3.1 Pro Custom Tools when auto-gemini-3 is requested, useGemini3_1 is true, and useCustomToolModel is true', () => {
const model = resolveModel(PREVIEW_GEMINI_MODEL_AUTO, true, false, true);
const model = resolveModel(PREVIEW_GEMINI_MODEL_AUTO, true, true);
expect(model).toBe(PREVIEW_GEMINI_3_1_CUSTOM_TOOLS_MODEL);
});
@@ -400,16 +378,6 @@ describe('resolveModel', () => {
expect(model).toBe(DEFAULT_GEMINI_MODEL);
});
it('should return the Default Flash-Lite model when flash-lite is requested', () => {
const model = resolveModel(GEMINI_MODEL_ALIAS_FLASH_LITE);
expect(model).toBe(DEFAULT_GEMINI_FLASH_LITE_MODEL);
});
it('should return the Preview Flash-Lite model when flash-lite is requested and useGemini3_1FlashLite is true', () => {
const model = resolveModel(GEMINI_MODEL_ALIAS_FLASH_LITE, false, true);
expect(model).toBe(PREVIEW_GEMINI_3_1_FLASH_LITE_MODEL);
});
it('should return the requested model as-is for explicit specific models', () => {
expect(resolveModel(DEFAULT_GEMINI_MODEL)).toBe(DEFAULT_GEMINI_MODEL);
expect(resolveModel(DEFAULT_GEMINI_FLASH_MODEL)).toBe(
@@ -429,45 +397,39 @@ describe('resolveModel', () => {
describe('hasAccessToPreview logic', () => {
it('should return default model when access to preview is false and preview model is requested', () => {
expect(
resolveModel(PREVIEW_GEMINI_MODEL, false, false, false, false),
).toBe(DEFAULT_GEMINI_MODEL);
expect(resolveModel(PREVIEW_GEMINI_MODEL, false, false, false)).toBe(
DEFAULT_GEMINI_MODEL,
);
});
it('should return default flash model when access to preview is false and preview flash model is requested', () => {
expect(
resolveModel(PREVIEW_GEMINI_FLASH_MODEL, false, false, false, false),
resolveModel(PREVIEW_GEMINI_FLASH_MODEL, false, false, false),
).toBe(DEFAULT_GEMINI_FLASH_MODEL);
});
it('should return default flash lite model when access to preview is false and preview flash lite model is requested', () => {
expect(
resolveModel(
PREVIEW_GEMINI_3_1_FLASH_LITE_MODEL,
false,
false,
false,
false,
),
resolveModel(PREVIEW_GEMINI_3_1_FLASH_LITE_MODEL, false, false, false),
).toBe(DEFAULT_GEMINI_FLASH_LITE_MODEL);
});
it('should return default model when access to preview is false and auto-gemini-3 is requested', () => {
expect(
resolveModel(PREVIEW_GEMINI_MODEL_AUTO, false, false, false, false),
).toBe(DEFAULT_GEMINI_MODEL);
expect(resolveModel(PREVIEW_GEMINI_MODEL_AUTO, false, false, false)).toBe(
DEFAULT_GEMINI_MODEL,
);
});
it('should return default model when access to preview is false and Gemini 3.1 is requested', () => {
expect(
resolveModel(PREVIEW_GEMINI_MODEL_AUTO, true, false, false, false),
).toBe(DEFAULT_GEMINI_MODEL);
expect(resolveModel(PREVIEW_GEMINI_MODEL_AUTO, true, false, false)).toBe(
DEFAULT_GEMINI_MODEL,
);
});
it('should still return default model when access to preview is false and auto-gemini-2.5 is requested', () => {
expect(
resolveModel(DEFAULT_GEMINI_MODEL_AUTO, false, false, false, false),
).toBe(DEFAULT_GEMINI_MODEL);
expect(resolveModel(DEFAULT_GEMINI_MODEL_AUTO, false, false, false)).toBe(
DEFAULT_GEMINI_MODEL,
);
});
});
});
@@ -559,7 +521,6 @@ describe('resolveClassifierModel', () => {
PREVIEW_GEMINI_MODEL_AUTO,
GEMINI_MODEL_ALIAS_PRO,
true,
false,
true,
),
).toBe(PREVIEW_GEMINI_3_1_CUSTOM_TOOLS_MODEL);
@@ -571,11 +532,7 @@ describe('isActiveModel', () => {
expect(isActiveModel(DEFAULT_GEMINI_MODEL)).toBe(true);
expect(isActiveModel(PREVIEW_GEMINI_MODEL)).toBe(true);
expect(isActiveModel(DEFAULT_GEMINI_FLASH_MODEL)).toBe(true);
});
it('should return false for Gemini 3.1 models when Gemini 3.1 is not launched', () => {
expect(isActiveModel(PREVIEW_GEMINI_3_1_MODEL)).toBe(false);
expect(isActiveModel(PREVIEW_GEMINI_3_1_FLASH_LITE_MODEL)).toBe(false);
expect(isActiveModel(PREVIEW_GEMINI_3_1_FLASH_LITE_MODEL)).toBe(true);
});
it('should return true for unknown models and aliases', () => {
@@ -589,53 +546,31 @@ describe('isActiveModel', () => {
it('should return true for other valid models when useGemini3_1 is true', () => {
expect(isActiveModel(DEFAULT_GEMINI_MODEL, true)).toBe(true);
});
it('should return true for PREVIEW_GEMINI_3_1_FLASH_LITE_MODEL only when useGemini3_1FlashLite is true', () => {
expect(
isActiveModel(PREVIEW_GEMINI_3_1_FLASH_LITE_MODEL, false, true),
).toBe(true);
expect(isActiveModel(PREVIEW_GEMINI_3_1_FLASH_LITE_MODEL, true, true)).toBe(
true,
);
expect(
isActiveModel(PREVIEW_GEMINI_3_1_FLASH_LITE_MODEL, true, false),
).toBe(false);
expect(isActiveModel(PREVIEW_GEMINI_3_1_FLASH_LITE_MODEL, true)).toBe(true);
});
it('should correctly filter Gemini 3.1 models based on useCustomToolModel when useGemini3_1 is true', () => {
// When custom tools are preferred, standard 3.1 should be inactive
expect(isActiveModel(PREVIEW_GEMINI_3_1_MODEL, true, false, true)).toBe(
false,
);
expect(isActiveModel(PREVIEW_GEMINI_3_1_MODEL, true, true)).toBe(false);
expect(
isActiveModel(PREVIEW_GEMINI_3_1_CUSTOM_TOOLS_MODEL, true, false, true),
isActiveModel(PREVIEW_GEMINI_3_1_CUSTOM_TOOLS_MODEL, true, true),
).toBe(true);
// When custom tools are NOT preferred, custom tools 3.1 should be inactive
expect(isActiveModel(PREVIEW_GEMINI_3_1_MODEL, true, false, false)).toBe(
true,
);
expect(isActiveModel(PREVIEW_GEMINI_3_1_MODEL, true, false)).toBe(true);
expect(
isActiveModel(PREVIEW_GEMINI_3_1_CUSTOM_TOOLS_MODEL, true, false, false),
isActiveModel(PREVIEW_GEMINI_3_1_CUSTOM_TOOLS_MODEL, true, false),
).toBe(false);
});
it('should return false for Gemini 3.1 models when useGemini3_1 and useGemini3_1FlashLite are false', () => {
expect(isActiveModel(PREVIEW_GEMINI_3_1_MODEL, false, false, true)).toBe(
false,
);
expect(isActiveModel(PREVIEW_GEMINI_3_1_MODEL, false, false, false)).toBe(
false,
);
it('should return false for both Gemini 3.1 models when useGemini3_1 is false', () => {
expect(isActiveModel(PREVIEW_GEMINI_3_1_MODEL, false, true)).toBe(false);
expect(isActiveModel(PREVIEW_GEMINI_3_1_MODEL, false, false)).toBe(false);
expect(
isActiveModel(PREVIEW_GEMINI_3_1_CUSTOM_TOOLS_MODEL, false, false, true),
isActiveModel(PREVIEW_GEMINI_3_1_CUSTOM_TOOLS_MODEL, false, true),
).toBe(false);
expect(
isActiveModel(PREVIEW_GEMINI_3_1_CUSTOM_TOOLS_MODEL, false, false, false),
).toBe(false);
expect(
isActiveModel(PREVIEW_GEMINI_3_1_FLASH_LITE_MODEL, false, false),
isActiveModel(PREVIEW_GEMINI_3_1_CUSTOM_TOOLS_MODEL, false, false),
).toBe(false);
});
});
+3 -23
View File
@@ -6,7 +6,6 @@
export interface ModelResolutionContext {
useGemini3_1?: boolean;
useGemini3_1FlashLite?: boolean;
useCustomTools?: boolean;
hasAccessToPreview?: boolean;
requestedModel?: string;
@@ -98,7 +97,6 @@ export const DEFAULT_THINKING_MODE = 8192;
export function resolveModel(
requestedModel: string,
useGemini3_1: boolean = false,
useGemini3_1FlashLite: boolean = false,
useCustomToolModel: boolean = false,
hasAccessToPreview: boolean = true,
config?: ModelCapabilityContext,
@@ -106,7 +104,6 @@ export function resolveModel(
if (config?.getExperimentalDynamicModelConfiguration?.() === true) {
const resolved = config.modelConfigService.resolveModelId(requestedModel, {
useGemini3_1,
useGemini3_1FlashLite,
useCustomTools: useCustomToolModel,
hasAccessToPreview,
});
@@ -149,9 +146,7 @@ export function resolveModel(
break;
}
case GEMINI_MODEL_ALIAS_FLASH_LITE: {
resolved = useGemini3_1FlashLite
? PREVIEW_GEMINI_3_1_FLASH_LITE_MODEL
: DEFAULT_GEMINI_FLASH_LITE_MODEL;
resolved = DEFAULT_GEMINI_FLASH_LITE_MODEL;
break;
}
default: {
@@ -165,8 +160,6 @@ export function resolveModel(
switch (resolved) {
case PREVIEW_GEMINI_FLASH_MODEL:
return DEFAULT_GEMINI_FLASH_MODEL;
case PREVIEW_GEMINI_3_1_FLASH_LITE_MODEL:
return DEFAULT_GEMINI_FLASH_LITE_MODEL;
case PREVIEW_GEMINI_MODEL:
case PREVIEW_GEMINI_3_1_MODEL:
case PREVIEW_GEMINI_3_1_CUSTOM_TOOLS_MODEL:
@@ -200,7 +193,6 @@ export function resolveClassifierModel(
requestedModel: string,
modelAlias: string,
useGemini3_1: boolean = false,
useGemini3_1FlashLite: boolean = false,
useCustomToolModel: boolean = false,
hasAccessToPreview: boolean = true,
config?: ModelCapabilityContext,
@@ -211,7 +203,6 @@ export function resolveClassifierModel(
requestedModel,
{
useGemini3_1,
useGemini3_1FlashLite,
useCustomTools: useCustomToolModel,
hasAccessToPreview,
},
@@ -233,12 +224,7 @@ export function resolveClassifierModel(
}
return resolveModel(GEMINI_MODEL_ALIAS_FLASH);
}
return resolveModel(
requestedModel,
useGemini3_1,
useGemini3_1FlashLite,
useCustomToolModel,
);
return resolveModel(requestedModel, useGemini3_1, useCustomToolModel);
}
export function getDisplayString(
@@ -263,8 +249,6 @@ export function getDisplayString(
return PREVIEW_GEMINI_FLASH_MODEL;
case PREVIEW_GEMINI_3_1_CUSTOM_TOOLS_MODEL:
return PREVIEW_GEMINI_3_1_MODEL;
case PREVIEW_GEMINI_3_1_FLASH_LITE_MODEL:
return PREVIEW_GEMINI_3_1_FLASH_LITE_MODEL;
default:
return model;
}
@@ -363,7 +347,7 @@ export function isCustomModel(
config?: ModelCapabilityContext,
): boolean {
if (config?.getExperimentalDynamicModelConfiguration?.() === true) {
const resolved = resolveModel(model, false, false, false, true, config);
const resolved = resolveModel(model, false, false, true, config);
return (
config.modelConfigService.getModelDefinition(resolved)?.tier ===
'custom' || !resolved.startsWith('gemini-')
@@ -436,15 +420,11 @@ export function supportsMultimodalFunctionResponse(
export function isActiveModel(
model: string,
useGemini3_1: boolean = false,
useGemini3_1FlashLite: boolean = false,
useCustomToolModel: boolean = false,
): boolean {
if (!VALID_GEMINI_MODELS.has(model)) {
return false;
}
if (model === PREVIEW_GEMINI_3_1_FLASH_LITE_MODEL) {
return useGemini3_1FlashLite;
}
if (useGemini3_1) {
if (model === PREVIEW_GEMINI_MODEL) {
return false;
-1
View File
@@ -575,7 +575,6 @@ export class GeminiClient {
return resolveModel(
this.config.getActiveModel(),
this.config.getGemini31LaunchedSync?.() ?? false,
this.config.getGemini31FlashLiteLaunchedSync?.() ?? false,
false,
this.config.getHasAccessToPreviewModel?.() ?? true,
this.config,
@@ -180,9 +180,6 @@ export async function createContentGenerator(
config.authType === AuthType.USE_GEMINI ||
config.authType === AuthType.USE_VERTEX_AI ||
((await gcConfig.getGemini31Launched?.()) ?? false),
config.authType === AuthType.USE_GEMINI ||
config.authType === AuthType.USE_VERTEX_AI ||
((await gcConfig.getGemini31FlashLiteLaunched?.()) ?? false),
false,
gcConfig.getHasAccessToPreviewModel?.() ?? true,
gcConfig,
-82
View File
@@ -19,11 +19,6 @@ import {
SYNTHETIC_THOUGHT_SIGNATURE,
type StreamEvent,
} from './geminiChat.js';
import {
type CompletedToolCall,
CoreToolCallStatus,
} from '../scheduler/types.js';
import { MockTool } from '../test-utils/mock-tool.js';
import type { Config } from '../config/config.js';
import { setSimulate429 } from '../utils/testUtils.js';
import { DEFAULT_THINKING_MODE } from '../config/models.js';
@@ -170,9 +165,6 @@ describe('GeminiChat', () => {
getToolRegistry: vi.fn().mockReturnValue({
getTool: vi.fn(),
}),
toolRegistry: {
getTool: vi.fn(),
},
getContentGenerator: vi.fn().mockReturnValue(mockContentGenerator),
getRetryFetchErrors: vi.fn().mockReturnValue(false),
getMaxAttempts: vi.fn().mockReturnValue(10),
@@ -2577,78 +2569,4 @@ describe('GeminiChat', () => {
});
});
});
describe('recordCompletedToolCalls', () => {
it('should use originalRequestName and originalRequestArgs if present', () => {
const completedCall: CompletedToolCall = {
status: CoreToolCallStatus.Success,
request: {
callId: 'call-1',
name: 'tail-tool',
args: { tail: 'args' },
originalRequestName: 'original-tool',
originalRequestArgs: { original: 'args' },
isClientInitiated: false,
prompt_id: 'p1',
},
response: {
callId: 'call-1',
responseParts: [{ text: 'response' }],
resultDisplay: undefined,
error: undefined,
errorType: undefined,
},
tool: new MockTool({ name: 'mock-tool' }),
invocation: new MockTool({ name: 'mock-tool' }).build({ key: 'value' }),
};
const spy = vi.spyOn(chat.getChatRecordingService(), 'recordToolCalls');
chat.recordCompletedToolCalls('test-model', [completedCall]);
expect(spy).toHaveBeenCalledWith('test-model', [
expect.objectContaining({
id: 'call-1',
name: 'original-tool',
args: { original: 'args' },
result: [{ text: 'response' }],
}),
]);
});
it('should fall back to request name and args if original are not present', () => {
const completedCall: CompletedToolCall = {
status: CoreToolCallStatus.Success,
request: {
callId: 'call-1',
name: 'tool-name',
args: { key: 'value' },
isClientInitiated: false,
prompt_id: 'p1',
},
response: {
callId: 'call-1',
responseParts: [{ text: 'response' }],
resultDisplay: undefined,
error: undefined,
errorType: undefined,
},
tool: new MockTool({ name: 'mock-tool' }),
invocation: new MockTool({ name: 'mock-tool' }).build({ key: 'value' }),
};
const spy = vi.spyOn(chat.getChatRecordingService(), 'recordToolCalls');
chat.recordCompletedToolCalls('test-model', [completedCall]);
expect(spy).toHaveBeenCalledWith('test-model', [
expect.objectContaining({
id: 'call-1',
name: 'tool-name',
args: { key: 'value' },
result: [{ text: 'response' }],
}),
]);
});
});
});
+4 -11
View File
@@ -524,18 +524,12 @@ export class GeminiChat {
const apiCall = async () => {
const useGemini3_1 =
(await this.context.config.getGemini31Launched?.()) ?? false;
const useGemini3_1FlashLite =
(await this.context.config.getGemini31FlashLiteLaunched?.()) ?? false;
const hasAccessToPreview =
this.context.config.getHasAccessToPreviewModel?.() ?? true;
// Default to the last used model (which respects arguments/availability selection)
let modelToUse = resolveModel(
lastModelToUse,
useGemini3_1,
useGemini3_1FlashLite,
false,
hasAccessToPreview,
this.context.config.getHasAccessToPreviewModel?.() ?? true,
this.context.config,
);
@@ -545,9 +539,8 @@ export class GeminiChat {
modelToUse = resolveModel(
this.context.config.getActiveModel(),
useGemini3_1,
useGemini3_1FlashLite,
false,
hasAccessToPreview,
this.context.config.getHasAccessToPreviewModel?.() ?? true,
this.context.config,
);
}
@@ -1032,8 +1025,8 @@ export class GeminiChat {
return {
id: call.request.callId,
name: call.request.originalRequestName ?? call.request.name,
args: call.request.originalRequestArgs ?? call.request.args,
name: call.request.name,
args: call.request.args,
result: call.response?.responseParts || null,
status: call.status,
timestamp: new Date().toISOString(),
@@ -62,7 +62,6 @@ export class PromptProvider {
const desiredModel = resolveModel(
context.config.getActiveModel(),
context.config.getGemini31LaunchedSync?.() ?? false,
context.config.getGemini31FlashLiteLaunchedSync?.() ?? false,
false,
context.config.getHasAccessToPreviewModel?.() ?? true,
context.config,
@@ -248,7 +247,6 @@ export class PromptProvider {
const desiredModel = resolveModel(
context.config.getActiveModel(),
context.config.getGemini31LaunchedSync?.() ?? false,
context.config.getGemini31FlashLiteLaunchedSync?.() ?? false,
false,
context.config.getHasAccessToPreviewModel?.() ?? true,
context.config,
@@ -59,7 +59,6 @@ describe('ClassifierStrategy', () => {
getModel: vi.fn().mockReturnValue(DEFAULT_GEMINI_MODEL_AUTO),
getNumericalRoutingEnabled: vi.fn().mockResolvedValue(false),
getGemini31Launched: vi.fn().mockResolvedValue(false),
getGemini31FlashLiteLaunched: vi.fn().mockResolvedValue(false),
getUseCustomToolModel: vi.fn().mockImplementation(async () => {
const launched = await mockConfig.getGemini31Launched();
const authType = mockConfig.getContentGeneratorConfig().authType;
@@ -171,17 +171,14 @@ export class ClassifierStrategy implements RoutingStrategy {
const reasoning = routerResponse.reasoning;
const latencyMs = Date.now() - startTime;
const [useGemini3_1, useGemini3_1FlashLite, useCustomToolModel] =
await Promise.all([
config.getGemini31Launched(),
config.getGemini31FlashLiteLaunched(),
config.getUseCustomToolModel(),
]);
const [useGemini3_1, useCustomToolModel] = await Promise.all([
config.getGemini31Launched(),
config.getUseCustomToolModel(),
]);
const selectedModel = resolveClassifierModel(
model,
routerResponse.model_choice,
useGemini3_1,
useGemini3_1FlashLite,
useCustomToolModel,
config.getHasAccessToPreviewModel?.() ?? true,
config,
@@ -26,7 +26,6 @@ export class DefaultStrategy implements TerminalStrategy {
const defaultModel = resolveModel(
config.getModel(),
config.getGemini31LaunchedSync?.() ?? false,
config.getGemini31FlashLiteLaunchedSync?.() ?? false,
false,
config.getHasAccessToPreviewModel?.() ?? true,
config,
@@ -28,7 +28,6 @@ export class FallbackStrategy implements RoutingStrategy {
const resolvedModel = resolveModel(
requestedModel,
config.getGemini31LaunchedSync?.() ?? false,
config.getGemini31FlashLiteLaunchedSync?.() ?? false,
false,
config.getHasAccessToPreviewModel?.() ?? true,
config,
@@ -59,7 +59,6 @@ describe('NumericalClassifierStrategy', () => {
getResolvedClassifierThreshold: vi.fn().mockResolvedValue(90),
getClassifierThreshold: vi.fn().mockResolvedValue(undefined),
getGemini31Launched: vi.fn().mockResolvedValue(false),
getGemini31FlashLiteLaunched: vi.fn().mockResolvedValue(false),
getUseCustomToolModel: vi.fn().mockImplementation(async () => {
const launched = await mockConfig.getGemini31Launched();
const authType = mockConfig.getContentGeneratorConfig().authType;
@@ -147,17 +147,14 @@ export class NumericalClassifierStrategy implements RoutingStrategy {
const { threshold, groupLabel, modelAlias } =
await this.getRoutingDecision(score, config);
const [useGemini3_1, useGemini3_1FlashLite, useCustomToolModel] =
await Promise.all([
config.getGemini31Launched(),
config.getGemini31FlashLiteLaunched(),
config.getUseCustomToolModel(),
]);
const [useGemini3_1, useCustomToolModel] = await Promise.all([
config.getGemini31Launched(),
config.getUseCustomToolModel(),
]);
const selectedModel = resolveClassifierModel(
model,
modelAlias,
useGemini3_1,
useGemini3_1FlashLite,
useCustomToolModel,
config.getHasAccessToPreviewModel?.() ?? true,
config,
@@ -38,7 +38,6 @@ export class OverrideStrategy implements RoutingStrategy {
model: resolveModel(
overrideModel,
config.getGemini31LaunchedSync?.() ?? false,
config.getGemini31FlashLiteLaunchedSync?.() ?? false,
false,
config.getHasAccessToPreviewModel?.() ?? true,
config,
@@ -669,30 +669,6 @@ describe('Scheduler (Orchestrator)', () => {
);
});
it('should use originalRequestName when generating an error response', async () => {
const error = new Error('Some error');
vi.mocked(checkPolicy).mockRejectedValue(error);
const tailReq = { ...req1, originalRequestName: 'original-tool-name' };
await scheduler.schedule(tailReq, signal);
expect(mockStateManager.updateStatus).toHaveBeenCalledWith(
'call-1',
CoreToolCallStatus.Error,
expect.objectContaining({
errorType: ToolErrorType.UNHANDLED_EXCEPTION,
responseParts: expect.arrayContaining([
expect.objectContaining({
functionResponse: expect.objectContaining({
name: 'original-tool-name',
response: { error: 'Some error' },
}),
}),
]),
}),
);
});
it('should handle errors from checkPolicy (e.g. non-interactive ASK_USER)', async () => {
const error = new Error('Not interactive');
vi.mocked(checkPolicy).mockRejectedValue(error);
@@ -1155,7 +1131,6 @@ describe('Scheduler (Orchestrator)', () => {
name: 'tool-b',
args: { key: 'value' },
originalRequestName: 'test-tool', // Preserves original name
originalRequestArgs: req1.args, // Preserves original args
}),
tool: mockToolB,
}),
+1 -3
View File
@@ -77,7 +77,7 @@ const createErrorResponse = (
{
functionResponse: {
id: request.callId,
name: request.originalRequestName ?? request.name,
name: request.name,
response: { error: error.message },
},
},
@@ -766,8 +766,6 @@ export class Scheduler {
name: tailRequest.name,
args: tailRequest.args,
originalRequestName,
originalRequestArgs:
result.request.originalRequestArgs ?? result.request.args,
isClientInitiated: result.request.isClientInitiated,
prompt_id: result.request.prompt_id,
schedulerId: this.schedulerId,
@@ -44,8 +44,6 @@ describe('SchedulerStateManager', () => {
const mockInvocation = {
shouldConfirmExecute: vi.fn(),
execute: vi.fn(),
getDescription: vi.fn(),
} as unknown as AnyToolInvocation;
const createValidatingCall = (
@@ -612,19 +610,6 @@ describe('SchedulerStateManager', () => {
expect(onUpdate).toHaveBeenCalledTimes(1);
});
it('should use originalRequestName when cancelling queued calls', () => {
const call = createValidatingCall('tail-1');
call.request.originalRequestName = 'original-tool';
stateManager.enqueue([call]);
stateManager.cancelAllQueued('Batch cancel');
const completed = stateManager.completedBatch[0] as CancelledToolCall;
expect(completed.response.responseParts[0]?.functionResponse?.name).toBe(
'original-tool',
);
});
it('should not notify if cancelAllQueued is called on an empty queue', () => {
vi.mocked(onUpdate).mockClear();
stateManager.cancelAllQueued('Batch cancel');
+1 -1
View File
@@ -517,7 +517,7 @@ export class SchedulerStateManager {
{
functionResponse: {
id: call.request.callId,
name: call.request.originalRequestName ?? call.request.name,
name: call.request.name,
response: { error: errorMessage },
},
},
@@ -332,53 +332,6 @@ describe('ToolExecutor', () => {
expect(result.status).toBe(CoreToolCallStatus.Cancelled);
});
it('should return cancelled result and use originalRequestName when signal is aborted', async () => {
const mockTool = new MockTool({
name: 'slowTool',
});
const invocation = mockTool.build({});
// Mock executeToolWithHooks to simulate slow execution
vi.mocked(coreToolHookTriggers.executeToolWithHooks).mockImplementation(
async () => {
await new Promise((r) => setTimeout(r, 100));
return { llmContent: 'Done', returnDisplay: 'Done' };
},
);
const scheduledCall: ScheduledToolCall = {
status: CoreToolCallStatus.Scheduled,
request: {
callId: 'call-4',
name: 'actualToolName',
originalRequestName: 'originalToolName',
args: {},
isClientInitiated: false,
prompt_id: 'prompt-4',
},
tool: mockTool,
invocation: invocation as unknown as AnyToolInvocation,
startTime: Date.now(),
};
const controller = new AbortController();
const promise = executor.execute({
call: scheduledCall,
signal: controller.signal,
onUpdateToolCall: vi.fn(),
});
controller.abort();
const result = await promise;
expect(result.status).toBe(CoreToolCallStatus.Cancelled);
if (result.status === CoreToolCallStatus.Cancelled) {
expect(result.response.responseParts[0]?.functionResponse?.name).toBe(
'originalToolName',
);
}
});
it('should truncate large shell output', async () => {
// 1. Setup Config for Truncation
vi.spyOn(config, 'getTruncateToolOutputThreshold').mockReturnValue(10);
+2 -2
View File
@@ -307,7 +307,7 @@ export class ToolExecutor {
outputFile = truncatedOutputFile;
responseParts = convertToFunctionResponse(
call.request.originalRequestName ?? call.request.name,
call.request.name,
call.request.callId,
output,
this.config.getActiveModel(),
@@ -325,7 +325,7 @@ export class ToolExecutor {
{
functionResponse: {
id: call.request.callId,
name: call.request.originalRequestName ?? call.request.name,
name: call.request.name,
response: { error: errorMessage },
},
},
+2 -4
View File
@@ -37,12 +37,10 @@ export interface ToolCallRequestInfo {
name: string;
args: Record<string, unknown>;
/**
* The original name and arguments of the tool requested by the model.
* This is used for tail calls to ensure the final response and log retains
* the original values.
* The original name of the tool requested by the model.
* This is used for tail calls to ensure the final response retains the original name.
*/
originalRequestName?: string;
originalRequestArgs?: Record<string, unknown>;
isClientInitiated: boolean;
prompt_id: string;
checkpoint?: string;
@@ -30,7 +30,6 @@ import {
PREVIEW_GEMINI_MODEL,
PREVIEW_GEMINI_FLASH_MODEL,
PREVIEW_GEMINI_3_1_MODEL,
PREVIEW_GEMINI_3_1_FLASH_LITE_MODEL,
} from '../config/models.js';
import { PreCompressTrigger } from '../hooks/types.js';
@@ -106,8 +105,6 @@ export function modelStringToModelConfigAlias(model: string): string {
return 'chat-compression-3-pro';
case PREVIEW_GEMINI_FLASH_MODEL:
return 'chat-compression-3-flash';
case PREVIEW_GEMINI_3_1_FLASH_LITE_MODEL:
return 'chat-compression-3.1-flash-lite';
case DEFAULT_GEMINI_MODEL:
return 'chat-compression-2.5-pro';
case DEFAULT_GEMINI_FLASH_MODEL:
@@ -90,7 +90,6 @@ export interface ModelResolution {
/** The actual state of the current session. */
export interface ResolutionContext {
useGemini3_1?: boolean;
useGemini3_1FlashLite?: boolean;
useCustomTools?: boolean;
hasAccessToPreview?: boolean;
requestedModel?: string;
@@ -99,7 +98,6 @@ export interface ResolutionContext {
/** The requirements defined in the registry. */
export interface ResolutionCondition {
useGemini3_1?: boolean;
useGemini3_1FlashLite?: boolean;
useCustomTools?: boolean;
hasAccessToPreview?: boolean;
/** Matches if the current model is in this list. */
@@ -167,8 +165,6 @@ export class ModelConfigService {
switch (key) {
case 'useGemini3_1':
return value === context.useGemini3_1;
case 'useGemini3_1FlashLite':
return value === context.useGemini3_1FlashLite;
case 'useCustomTools':
return value === context.useCustomTools;
case 'hasAccessToPreview':
@@ -237,10 +237,6 @@
"model": "gemini-3-flash-preview",
"generateContentConfig": {}
},
"chat-compression-3.1-flash-lite": {
"model": "gemini-3.1-flash-lite-preview",
"generateContentConfig": {}
},
"chat-compression-2.5-pro": {
"model": "gemini-2.5-pro",
"generateContentConfig": {}
@@ -237,10 +237,6 @@
"model": "gemini-3-flash-preview",
"generateContentConfig": {}
},
"chat-compression-3.1-flash-lite": {
"model": "gemini-3.1-flash-lite-preview",
"generateContentConfig": {}
},
"chat-compression-2.5-pro": {
"model": "gemini-2.5-pro",
"generateContentConfig": {}
-9
View File
@@ -354,13 +354,4 @@ describe('getErrorType', () => {
expect(getErrorType(null)).toBe('unknown');
expect(getErrorType(undefined)).toBe('unknown');
});
it('should strip leading underscores from error names', () => {
class _GaxiosError extends Error {}
expect(getErrorType(new _GaxiosError('test'))).toBe('GaxiosError');
const errorWithUnderscoreName = new Error('test');
errorWithUnderscoreName.name = '_CodeBuddyError';
expect(getErrorType(errorWithUnderscoreName)).toBe('CodeBuddyError');
});
});
+3 -6
View File
@@ -58,12 +58,9 @@ export function getErrorType(error: unknown): string {
if (!(error instanceof Error)) return 'unknown';
// Return constructor name if the generic 'Error' name is used (for custom errors)
const name =
error.name === 'Error' ? (error.constructor?.name ?? 'Error') : error.name;
// Strip leading underscore from error names. Bundlers like esbuild sometimes
// rename classes to avoid scope collisions.
return name.replace(/^_+/, '');
return error.name === 'Error'
? (error.constructor?.name ?? 'Error')
: error.name;
}
export class FatalError extends Error {
File diff suppressed because one or more lines are too long
-80
View File
@@ -394,82 +394,6 @@ export function runTSConfigLinter() {
}
}
export function runGithubActionsPinningLinter() {
console.log('\nRunning GitHub Actions pinning linter...');
let files = [];
try {
files = execSync(
"git ls-files '.github/workflows/*.yml' '.github/workflows/*.yaml' '.github/actions/**/*.yml' '.github/actions/**/*.yaml'",
)
.toString()
.trim()
.split('\n')
.filter(Boolean);
} catch (e) {
console.error('Error finding GitHub Actions workflow files:', e.message);
process.exit(1);
}
let violationsFound = false;
// Improved regex to capture action name and ref, handling optional quotes and comments.
const USES_PATTERN = /uses:\s*['"]?([^@\s'"]+)@([^#\s'"]+)['"]?/;
const SHA_PATTERN = /^[0-9a-f]{40}$/i;
for (const file of files) {
if (!existsSync(file) || lstatSync(file).isDirectory()) {
continue;
}
const content = readFileSync(file, 'utf-8');
const lines = content.split('\n');
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
const match = line.match(USES_PATTERN);
if (match) {
const action = match[1];
let ref = match[2];
// Clean up any trailing quotes that might have been captured
ref = ref.replace(/['"]$/, '');
// Skip local actions (starting with ./), docker actions, and explicit exclusions
if (
action.startsWith('./') ||
action.startsWith('docker://') ||
line.includes('# github-actions-pinning:ignore')
) {
continue;
}
if (!SHA_PATTERN.test(ref)) {
violationsFound = true;
const lineNum = i + 1;
console.error(
`::error file=${file},line=${lineNum}::Action "${action}" uses "${ref}" instead of a 40-character SHA.`,
);
}
}
}
}
if (violationsFound) {
console.error(`
GitHub Actions pinning violations found. Please use exact commit hashes.
To automatically fix these, you can use the "ratchet" tool (https://github.com/sethvargo/ratchet):
- Mac/Linux (Homebrew): brew install ratchet && ratchet pin .github/workflows/*.yml .github/actions/**/*.yml
- Other platforms: Download from GitHub releases and run "ratchet pin .github/workflows/*.yml .github/actions/**/*.yml"
If you must use a tag, you can ignore this check by adding a comment (discouraged):
uses: some-action@v1 # github-actions-pinning:ignore
`);
process.exit(1);
} else {
console.log('No GitHub Actions pinning violations found.');
}
}
function main() {
const args = process.argv.slice(2);
@@ -497,9 +421,6 @@ function main() {
if (args.includes('--tsconfig')) {
runTSConfigLinter();
}
if (args.includes('--check-github-actions-pinning')) {
runGithubActionsPinningLinter();
}
if (args.length === 0) {
setupLinters();
@@ -510,7 +431,6 @@ function main() {
runPrettier();
runSensitiveKeywordLinter();
runTSConfigLinter();
runGithubActionsPinningLinter();
console.log('\nAll linting checks passed!');
}
}