# Gemini CLI Documentation # [Automation and triage processes](http://geminicli.com/docs/issue-and-pr-automation.md) This document provides a detailed overview of the automated processes we use to manage and triage issues and pull requests. Our goal is to provide prompt feedback and ensure that contributions are reviewed and integrated efficiently. Understanding this automation will help you as a contributor know what to expect and how to best interact with our repository bots. ## Guiding principle: Issues and pull requests First and foremost, almost every Pull Request (PR) should be linked to a corresponding Issue. The issue describes the "what" and the "why" (the bug or feature), while the PR is the "how" (the implementation). This separation helps us track work, prioritize features, and maintain clear historical context. Our automation is built around this principle. > [!NOTE] > Issues tagged as "πŸ”’Maintainers only" are reserved for project > maintainers. We will not accept pull requests related to these issues. --- ## Detailed automation workflows Here is a breakdown of the specific automation workflows that run in our repository. ### 1. When you open an issue: `Automated Issue Triage` This is the first bot you will interact with when you create an issue. Its job is to perform an initial analysis and apply the correct labels. - **Workflow File**: `.github/workflows/gemini-automated-issue-triage.yml` - **When it runs**: Immediately after an issue is created or reopened. - **What it does**: - It uses a Gemini model to analyze the issue's title and body against a detailed set of guidelines. - **Applies one `area/*` label**: Categorizes the issue into a functional area of the project (for example, `area/ux`, `area/models`, `area/platform`). - **Applies one `kind/*` label**: Identifies the type of issue (for example, `kind/bug`, `kind/enhancement`, `kind/question`). - **Applies one `priority/*` label**: Assigns a priority from P0 (critical) to P3 (low) based on the described impact. - **May apply `status/need-information`**: If the issue lacks critical details (like logs or reproduction steps), it will be flagged for more information. - **May apply `status/need-retesting`**: If the issue references a CLI version that is more than six versions old, it will be flagged for retesting on a current version. - **What you should do**: - Fill out the issue template as completely as possible. The more detail you provide, the more accurate the triage will be. - If the `status/need-information` label is added, provide the requested details in a comment. ### 2. When you open a pull request: `Continuous Integration (CI)` This workflow ensures that all changes meet our quality standards before they can be merged. - **Workflow File**: `.github/workflows/ci.yml` - **When it runs**: On every push to a pull request. - **What it does**: - **Lint**: Checks that your code adheres to our project's formatting and style rules. - **Test**: Runs our full suite of automated tests across macOS, Windows, and Linux, and on multiple Node.js versions. This is the most time-consuming part of the CI process. - **Post Coverage Comment**: After all tests have successfully passed, a bot will post a comment on your PR. This comment provides a summary of how well your changes are covered by tests. - **What you should do**: - Ensure all CI checks pass. A green checkmark βœ… will appear next to your commit when everything is successful. - If a check fails (a red "X" ❌), click the "Details" link next to the failed check to view the logs, identify the problem, and push a fix. ### 3. Ongoing triage for pull requests: `PR Auditing and Label Sync` This workflow runs periodically to ensure all open PRs are correctly linked to issues and have consistent labels. - **Workflow File**: `.github/workflows/gemini-scheduled-pr-triage.yml` - **When it runs**: Every 15 minutes on all open pull requests. - **What it does**: - **Checks for a linked issue**: The bot scans your PR description for a keyword that links it to an issue (for example, `Fixes #123`, `Closes #456`). - **Adds `status/need-issue`**: If no linked issue is found, the bot will add the `status/need-issue` label to your PR. This is a clear signal that an issue needs to be created and linked. - **Synchronizes labels**: If an issue _is_ linked, the bot ensures the PR's labels perfectly match the issue's labels. It will add any missing labels and remove any that don't belong, and it will remove the `status/need-issue` label if it was present. - **What you should do**: - **Always link your PR to an issue.** This is the most important step. Add a line like `Resolves #` to your PR description. - This will ensure your PR is correctly categorized and moves through the review process smoothly. ### 4. Ongoing triage for issues: `Scheduled Issue Triage` This is a fallback workflow to ensure that no issue gets missed by the triage process. - **Workflow File**: `.github/workflows/gemini-scheduled-issue-triage.yml` - **When it runs**: Every hour on all open issues. - **What it does**: - It actively seeks out issues that either have no labels at all or still have the `status/need-triage` label. - It then triggers the same powerful Gemini-based analysis as the initial triage bot to apply the correct labels. - **What you should do**: - You typically don't need to do anything. This workflow is a safety net to ensure every issue is eventually categorized, even if the initial triage fails. ### 5. Automatic unassignment of inactive contributors: `Unassign Inactive Issue Assignees` To keep the list of open `help wanted` issues accessible to all contributors, this workflow automatically removes **external contributors** who have not opened a linked pull request within **7 days** of being assigned. Maintainers, org members, and repo collaborators with write access or above are always exempt and will never be auto-unassigned. - **Workflow File**: `.github/workflows/unassign-inactive-assignees.yml` - **When it runs**: Every day at 09:00 UTC, and can be triggered manually with an optional `dry_run` mode. - **What it does**: 1. Finds every open issue labeled `help wanted` that has at least one assignee. 2. Identifies privileged users (team members, repo collaborators with write+ access, maintainers) and skips them entirely. 3. For each remaining (external) assignee it reads the issue's timeline to determine: - The exact date they were assigned (using `assigned` timeline events). - Whether they have opened a PR that is already linked/cross-referenced to the issue. 4. Each cross-referenced PR is fetched to verify it is **ready for review**: open and non-draft, or already merged. Draft PRs do not count. 5. If an assignee has been assigned for **more than 7 days** and no qualifying PR is found, they are automatically unassigned and a comment is posted explaining the reason and how to re-claim the issue. 6. Assignees who have a non-draft, open or merged PR linked to the issue are **never** unassigned by this workflow. - **What you should do**: - **Open a real PR, not a draft**: Within 7 days of being assigned, open a PR that is ready for review and include `Fixes #` in the description. Draft PRs do not satisfy the requirement and will not prevent auto-unassignment. - **Re-assign if unassigned by mistake**: Comment `/assign` on the issue to assign yourself again. - **Unassign yourself** if you can no longer work on the issue by commenting `/unassign`, so other contributors can pick it up right away. ### 6. Automatically label PRs by size: `PR Size Labeler` To help maintainers estimate review effort and keep the PR history clean, this workflow automatically tags every pull request with a size label representing the total volume of line changes. - **Workflow File**: `.github/workflows/pr-size-labeler.yml` - **When it runs**: Immediately after a pull request is created, synchronized (new commits pushed), or reopened. It can also be triggered manually via `workflow_dispatch` with a PR number. - **What it does**: - **Calculates total changes**: Summarizes additions and deletions across all changed files in a single consolidated API request. - **Applies standard size labels**: - `size/XS`: < 10 lines changed - `size/S`: 10-49 lines changed - `size/M`: 50-249 lines changed - `size/L`: 250-999 lines changed - `size/XL`: >= 1000 lines changed - **Updates size tag atomically**: Adds the new correct size label and removes any obsolete size labels in one atomic step. - **Updates/Posts PR size info comment**: Instead of spamming a new comment on every commit push, it updates the existing size labeler status comment inline to keep the PR conversation timeline perfectly neat and clean. - **What you should do**: - You do not need to take any actions. The workflow runs automatically and updates the label and comment seamlessly as you push new updates. ### 7. Release automation This workflow handles the process of packaging and publishing new versions of Gemini CLI. - **Workflow File**: `.github/workflows/release-manual.yml` - **When it runs**: On a daily schedule for "nightly" releases, and manually for official patch/minor releases. - **What it does**: - Automatically builds the project, bumps the version numbers, and publishes the packages to npm. - Creates a corresponding release on GitHub with generated release notes. - **What you should do**: - As a contributor, you don't need to do anything for this process. You can be confident that once your PR is merged into the `main` branch, your changes will be included in the very next nightly release. We hope this detailed overview is helpful. If you have any questions about our automation or processes, don't hesitate to ask! # [Gemini CLI documentation](http://geminicli.com/docs.md) Gemini CLI brings the power of Gemini models directly into your terminal. Use it to understand code, automate tasks, and build workflows with your local project context. ## Install ```bash npm install -g @google/gemini-cli ``` ## Get started Jump in to Gemini CLI. - **[Quickstart](/docs/get-started):** Your first session with Gemini CLI. - **[Installation](/docs/get-started/installation):** How to install Gemini CLI on your system. - **[Authentication](/docs/get-started/authentication):** Setup instructions for personal and enterprise accounts. - **[CLI cheatsheet](/docs/cli/cli-reference):** A quick reference for common commands and options. - **[Gemini 3 on Gemini CLI](/docs/get-started/gemini-3):** Learn about Gemini 3 support in Gemini CLI. ## Use Gemini CLI User-focused guides and tutorials for daily development workflows. - **[File management](/docs/cli/tutorials/file-management):** How to work with local files and directories. - **[Get started with Agent skills](/docs/cli/tutorials/skills-getting-started):** Getting started with specialized expertise. - **[Manage context and memory](/docs/cli/tutorials/memory-management):** Managing persistent instructions and facts. - **[Execute shell commands](/docs/cli/tutorials/shell-commands):** Executing system commands safely. - **[Manage sessions and history](/docs/cli/tutorials/session-management):** Resuming, managing, and rewinding conversations. - **[Plan tasks with todos](/docs/cli/tutorials/task-planning):** Using todos for complex workflows. - **[Web search and fetch](/docs/cli/tutorials/web-tools):** Searching and fetching content from the web. - **[Set up an MCP server](/docs/cli/tutorials/mcp-setup):** Set up an MCP server. - **[Automate tasks](/docs/cli/tutorials/automation):** Automate tasks. ## Features Technical documentation for each capability of Gemini CLI. - **[Extensions](/docs/extensions):** Extend Gemini CLI with new tools and capabilities. - **[Agent Skills](/docs/cli/skills):** Use specialized agents for specific tasks. - **[Checkpointing](/docs/cli/checkpointing):** Automatic session snapshots. - **[Headless mode](/docs/cli/headless):** Programmatic and scripting interface. - **[Hooks](/docs/hooks):** Customize Gemini CLI behavior with scripts. - **[IDE integration](/docs/ide-integration):** Integrate Gemini CLI with your favorite IDE. - **[MCP servers](/docs/tools/mcp-server):** Connect to and use remote agents. - **[Model routing](/docs/cli/model-routing):** Automatic fallback resilience. - **[Model selection](/docs/cli/model):** Choose the best model for your needs. - **[Plan mode πŸ”¬](/docs/cli/plan-mode):** Use a safe, read-only mode for planning complex changes. - **[Subagents πŸ”¬](/docs/core/subagents):** Using specialized agents for specific tasks. - **[Remote subagents πŸ”¬](/docs/core/remote-agents):** Connecting to and using remote agents. - **[Rewind](/docs/cli/rewind):** Rewind and replay sessions. - **[Sandboxing](/docs/cli/sandbox):** Isolate tool execution. - **[Settings](/docs/cli/settings):** Full configuration reference. - **[Telemetry](/docs/cli/telemetry):** Usage and performance metric details. - **[Token caching](/docs/cli/token-caching):** Performance optimization. ## Configuration Settings and customization options for Gemini CLI. - **[Custom commands](/docs/cli/custom-commands):** Personalized shortcuts. - **[Enterprise configuration](/docs/cli/enterprise):** Professional environment controls. - **[Ignore files (.geminiignore)](/docs/cli/gemini-ignore):** Exclusion pattern reference. - **[Model configuration](/docs/cli/generation-settings):** Fine-tune generation parameters like temperature and thinking budget. - **[Project context (GEMINI.md)](/docs/cli/gemini-md):** Technical hierarchy of context files. - **[System prompt override](/docs/cli/system-prompt):** Instruction replacement logic. - **[Themes](/docs/cli/themes):** UI personalization technical guide. - **[Trusted folders](/docs/cli/trusted-folders):** Security permission logic. ## Reference Deep technical documentation and API specifications. - **[Command reference](/docs/reference/commands):** Detailed slash command guide. - **[Configuration reference](/docs/reference/configuration):** Settings and environment variables. - **[Keyboard shortcuts](/docs/reference/keyboard-shortcuts):** Productivity tips. - **[Memory import processor](/docs/reference/memport):** How Gemini CLI processes memory from various sources. - **[Policy engine](/docs/reference/policy-engine):** Fine-grained execution control. - **[Tools reference](/docs/reference/tools):** Information on how tools are defined, registered, and used. ## Resources Support, release history, and legal information. - **[FAQ](/docs/resources/faq):** Answers to frequently asked questions. - **[Quota and pricing](/docs/resources/quota-and-pricing):** Limits and billing details. - **[Terms and privacy](/docs/resources/tos-privacy):** Official notices and terms. - **[Troubleshooting](/docs/resources/troubleshooting):** Common issues and solutions. - **[Uninstall](/docs/resources/uninstall):** How to uninstall Gemini CLI. ## Development - **[Contribution guide](/docs/contributing):** How to contribute to Gemini CLI. - **[Integration testing](/docs/integration-tests):** Running integration tests. - **[Issue and PR automation](/docs/issue-and-pr-automation):** Automation for issues and pull requests. - **[Local development](/docs/local-development):** Setting up a local development environment. - **[NPM package structure](/docs/npm):** The structure of the NPM packages. ## Releases - **[Release notes](/docs/changelogs):** Release notes for all versions. - **[Stable release](/docs/changelogs/latest):** The latest stable release. - **[Preview release](/docs/changelogs/preview):** The latest preview release. # [Release confidence strategy](http://geminicli.com/docs/release-confidence.md) This document outlines the strategy for gaining confidence in every release of Gemini CLI. It serves as a checklist and quality gate for release manager to ensure we are shipping a high-quality product. ## The goal To answer the question, "Is this release _truly_ ready for our users?" with a high degree of confidence, based on a holistic evaluation of automated signals, manual verification, and data. ## Level 1: Automated gates (must pass) These are the baseline requirements. If any of these fail, the release is a no-go. ### 1. CI/CD health All workflows in `.github/workflows/ci.yml` must pass on the `main` branch (for nightly) or the release branch (for preview/stable). - **Platforms:** Tests must pass on **Linux and macOS**. - **Checks:** - **Linting:** No linting errors (ESLint, Prettier, etc.). - **Typechecking:** No TypeScript errors. - **Unit Tests:** All unit tests in `packages/core` and `packages/cli` must pass. - **Build:** The project must build and bundle successfully. ### 2. End-to-end (E2E) tests All workflows in `.github/workflows/chained_e2e.yml` must pass. - **Platforms:** **Linux, macOS and Windows**. - **Sandboxing:** Tests must pass with both `sandbox:none` and `sandbox:docker` on Linux. ### 3. Post-deployment smoke tests After a release is published to npm, the `smoke-test.yml` workflow runs. This must pass to confirm the package is installable and the binary is executable. - **Command:** `npx -y @google/gemini-cli@ --version` must return the correct version without error. - **Platform:** Currently runs on `ubuntu-latest`. ## Level 2: Manual verification and dogfooding Automated tests cannot catch everything, especially UX issues. ### 1. Dogfooding via `preview` tag The weekly release cadence promotes code from `main` -> `nightly` -> `preview` -> `stable`. - **Requirement:** The `preview` release must be used by maintainers for at least **one week** before being promoted to `stable`. - **Action:** Maintainers should install the preview version locally: ```bash npm install -g @google/gemini-cli@preview ``` - **Goal:** To catch regressions and UX issues in day-to-day usage before they reach the broad user base. ### 2. Critical user journey (CUJ) checklist Before promoting a `preview` release to `stable`, a release manager must manually run through this checklist. - **Setup:** - [ ] Uninstall any existing global version: `npm uninstall -g @google/gemini-cli` - [ ] Clear npx cache (optional but recommended): `npm cache clean --force` - [ ] Install the preview version: `npm install -g @google/gemini-cli@preview` - [ ] Verify version: `gemini --version` - **Authentication:** - [ ] In interactive mode run `/auth` and verify all sign in flows work: - [ ] Sign in with Google - [ ] API Key - [ ] Vertex AI - **Basic prompting:** - [ ] Run `gemini "Tell me a joke"` and verify a sensible response. - [ ] Run in interactive mode: `gemini`. Ask a follow-up question to test context. - **Piped input:** - [ ] Run `echo "Summarize this" | gemini` and verify it processes stdin. - **Context management:** - [ ] In interactive mode, use `@file` to add a local file to context. Ask a question about it. - **Settings:** - [ ] In interactive mode run `/settings` and make modifications - [ ] Validate that setting is changed - **Function calling:** - [ ] In interactive mode, ask gemini to "create a file named hello.md with the content 'hello world'" and verify the file is created correctly. If any of these CUJs fail, the release is a no-go until a patch is applied to the `preview` channel. ### 3. Pre-Launch bug bash (tier 1 and 2 launches) For high-impact releases, an organized bug bash is required to ensure a higher level of quality and to catch issues across a wider range of environments and use cases. **Definition of tiers:** - **Tier 1:** Industry-Moving News πŸš€ - **Tier 2:** Important News for Our Users πŸ“£ - **Tier 3:** Relevant, but Not Life-Changing πŸ’‘ - **Tier 4:** Bug Fixes βš’οΈ **Requirement:** A bug bash must be scheduled at least **72 hours in advance** of any Tier 1 or Tier 2 launch. **Rule of thumb:** A bug bash should be considered for any release that involves: - A blog post - Coordinated social media announcements - Media relations or press outreach - A "Turbo" launch event ## Level 3: Telemetry and data review ### Dashboard health - [ ] Go to `go/gemini-cli-dash`. - [ ] Navigate to the "Tool Call" tab. - [ ] Validate that there are no spikes in errors for the release you would like to promote. ### Model evaluation - [ ] Navigate to `go/gemini-cli-offline-evals-dash`. - [ ] Make sure that the release you want to promote's recurring run is within average eval runs. ## The "go/no-go" decision Before triggering the `Release: Promote` workflow to move `preview` to `stable`: 1. [ ] **Level 1:** CI and E2E workflows are green for the commit corresponding to the current `preview` tag. 2. [ ] **Level 2:** The `preview` version has been out for one week, and the CUJ checklist has been completed successfully by a release manager. No blocking issues have been reported. 3. [ ] **Level 3:** Dashboard Health and Model Evaluation checks have been completed and show no regressions. If all checks pass, proceed with the promotion. # [Package overview](http://geminicli.com/docs/npm.md) This monorepo contains two main packages: `@google/gemini-cli` and `@google/gemini-cli-core`. ## `@google/gemini-cli` This is the main package for Gemini CLI. It is responsible for the user interface, command parsing, and all other user-facing functionality. When this package is published, it is bundled into a single executable file. This bundle includes all of the package's dependencies, including `@google/gemini-cli-core`. This means that whether a user installs the package with `npm install -g @google/gemini-cli` or runs it directly with `npx @google/gemini-cli`, they are using this single, self-contained executable. ## `@google/gemini-cli-core` This package contains the core logic for interacting with the Gemini API. It is responsible for making API requests, handling authentication, and managing the local cache. This package is not bundled. When it is published, it is published as a standard Node.js package with its own dependencies. This allows it to be used as a standalone package in other projects, if needed. All transpiled js code in the `dist` folder is included in the package. ## NPM workspaces This project uses [NPM Workspaces](https://docs.npmjs.com/cli/v10/using-npm/workspaces) to manage the packages within this monorepo. This simplifies development by allowing us to manage dependencies and run scripts across multiple packages from the root of the project. ### How it works The root `package.json` file defines the workspaces for this project: ```json { "workspaces": ["packages/*"] } ``` This tells NPM that any folder inside the `packages` directory is a separate package that should be managed as part of the workspace. ### Benefits of workspaces - **Simplified dependency management**: Running `npm install` from the root of the project will install all dependencies for all packages in the workspace and link them together. This means you don't need to run `npm install` in each package's directory. - **Automatic linking**: Packages within the workspace can depend on each other. When you run `npm install`, NPM will automatically create symlinks between the packages. This means that when you make changes to one package, the changes are immediately available to other packages that depend on it. - **Simplified script execution**: You can run scripts in any package from the root of the project using the `--workspace` flag. For example, to run the `build` script in the `cli` package, you can run `npm run build --workspace @google/gemini-cli`. # [Enterprise Admin Controls](http://geminicli.com/docs/admin/enterprise-controls.md) Gemini CLI empowers enterprise administrators to manage and enforce security policies and configuration settings across their entire organization. Secure defaults are enabled automatically for all enterprise users, but can be customized via the [Management Console](https://goo.gle/manage-gemini-cli). **Enterprise Admin Controls are enforced globally and cannot be overridden by users locally**, ensuring a consistent security posture. ## Admin Controls vs. System Settings While [System-wide settings](/docs/cli/settings) act as convenient configuration overrides, they can still be modified by users with sufficient privileges. In contrast, admin controls are immutable at the local level, making them the preferred method for enforcing policy. ## Available Controls ### Strict Mode **Enabled/Disabled** | Default: enabled If enabled, users will not be able to enter yolo mode. ### Extensions **Enabled/Disabled** | Default: disabled If disabled, users will not be able to use or install extensions. See [Extensions](/docs/extensions) for more details. ### MCP #### Enabled/Disabled **Enabled/Disabled** | Default: disabled If disabled, users will not be able to use MCP servers. See [MCP Server Integration](/docs/tools/mcp-server) for more details. #### MCP Servers (preview) **Default**: empty Allows administrators to define an explicit allowlist of MCP servers. This guarantees that users can only connect to trusted MCP servers defined by the organization. **Allowlist Format:** ```json { "mcpServers": { "external-provider": { "url": "https://api.mcp-provider.com", "type": "sse", "trust": true, "includeTools": ["toolA", "toolB"], "excludeTools": [] }, "internal-corp-tool": { "url": "https://mcp.internal-tool.corp", "type": "http", "includeTools": [], "excludeTools": ["adminTool"] } } } ``` **Supported Fields:** - `url`: (Required) The full URL of the MCP server endpoint. - `type`: (Required) The connection type (for example, `sse` or `http`). - `trust`: (Optional) If set to `true`, the server is trusted and tool execution will not require user approval. - `includeTools`: (Optional) An explicit list of tool names to allow. If specified, only these tools will be available. - `excludeTools`: (Optional) A list of tool names to hide. These tools will be blocked. **Client Enforcement Logic:** - **Empty Allowlist**: If the admin allowlist is empty, the client uses the user’s local configuration as is (unless the MCP toggle above is disabled). - **Active Allowlist**: If the allowlist contains one or more servers, **all locally configured servers not present in the allowlist are ignored**. - **Configuration Merging**: For a server to be active, it must exist in **both** the admin allowlist and the user’s local configuration (matched by name). The client merges these definitions as follows: - **Override Fields**: The `url`, `type`, & `trust` are always taken from the admin allowlist, overriding any local values. - **Tools Filtering**: If `includeTools` or `excludeTools` are defined in the allowlist, the admin’s rules are used exclusively. If both are undefined in the admin allowlist, the client falls back to the user’s local tool settings. - **Cleared Fields**: To ensure security and consistency, the client automatically clears local execution fields (`command`, `args`, `env`, `cwd`, `httpUrl`, `tcp`). This prevents users from overriding the connection method. - **Other Fields**: All other MCP fields are pulled from the user’s local configuration. - **Missing Allowlisted Servers**: If a server appears in the admin allowlist but is missing from the local configuration, it will not be initialized. This ensures users maintain final control over which permitted servers are actually active in their environment. #### Required MCP Servers (preview) **Default**: empty Allows administrators to define MCP servers that are **always injected** into the user's environment. Unlike the allowlist (which filters user-configured servers), required servers are automatically added regardless of the user's local configuration. **Required Servers Format:** ```json { "requiredMcpServers": { "corp-compliance-tool": { "url": "https://mcp.corp/compliance", "type": "http", "trust": true, "description": "Corporate compliance tool" }, "internal-registry": { "url": "https://registry.corp/mcp", "type": "sse", "authProviderType": "google_credentials", "oauth": { "scopes": ["https://www.googleapis.com/auth/scope"] } } } } ``` **Supported Fields:** - `url`: (Required) The full URL of the MCP server endpoint. - `type`: (Required) The connection type (`sse` or `http`). - `trust`: (Optional) If set to `true`, tool execution will not require user approval. Defaults to `true` for required servers. - `description`: (Optional) Human-readable description of the server. - `authProviderType`: (Optional) Authentication provider (`dynamic_discovery`, `google_credentials`, or `service_account_impersonation`). - `oauth`: (Optional) OAuth configuration including `scopes`, `clientId`, and `clientSecret`. - `targetAudience`: (Optional) OAuth target audience for service-to-service auth. - `targetServiceAccount`: (Optional) Service account email to impersonate. - `headers`: (Optional) Additional HTTP headers to send with requests. - `includeTools` / `excludeTools`: (Optional) Tool filtering lists. - `timeout`: (Optional) Timeout in milliseconds for MCP requests. **Client Enforcement Logic:** - Required servers are injected **after** allowlist filtering, so they are always available even if the allowlist is active. - If a required server has the **same name** as a locally configured server, the admin configuration **completely overrides** the local one. - Required servers only support remote transports (`sse`, `http`). Local execution fields (`command`, `args`, `env`, `cwd`) are not supported. - Required servers can coexist with allowlisted servers β€” both features work independently. ### Unmanaged Capabilities **Enabled/Disabled** | Default: disabled If disabled, users will not be able to use certain features. Currently, this control disables Agent Skills. See [Agent Skills](/docs/cli/skills) for more details. # [Local development guide](http://geminicli.com/docs/local-development.md) This guide provides instructions for setting up and using local development features for Gemini CLI. ## Tracing Gemini CLI uses OpenTelemetry (OTel) to record traces that help you debug agent behavior. Traces instrument key events like model calls, tool scheduler operations, and tool calls. Traces provide deep visibility into agent behavior and help you debug complex issues. They are captured automatically when you enable telemetry. ### View traces You can view traces using Genkit Developer UI, Jaeger, or Google Cloud. #### Use Genkit Genkit provides a web-based UI for viewing traces and other telemetry data. 1. **Start the Genkit telemetry server:** Run the following command to start the Genkit server: ```bash npm run telemetry -- --target=genkit ``` The script will output the URL for the Genkit Developer UI. For example: `Genkit Developer UI: http://localhost:4000` 2. **Run Gemini CLI:** In a separate terminal, run your Gemini CLI command: ```bash gemini ``` 3. **View the traces:** Open the Genkit Developer UI URL in your browser and navigate to the **Traces** tab to view the traces. #### Use Jaeger You can view traces in the Jaeger UI for local development. 1. **Start the telemetry collector:** Run the following command in your terminal to download and start Jaeger and an OTel collector: ```bash npm run telemetry -- --target=local ``` This command configures your workspace for local telemetry and provides a link to the Jaeger UI (usually `http://localhost:16686`). - **Collector logs:** `~/.gemini/tmp//otel/collector.log` 2. **Run Gemini CLI:** In a separate terminal, run your Gemini CLI command: ```bash gemini ``` 3. **View the traces:** After running your command, open the Jaeger UI link in your browser to view the traces. #### Use Google Cloud You can use an OpenTelemetry collector to forward telemetry data to Google Cloud Trace for custom processing or routing. > [!WARNING] > Ensure you complete the > [Google Cloud telemetry prerequisites](/docs/cli/telemetry#prerequisites) > (Project ID, authentication, IAM roles, and APIs) before using this method. 1. **Configure `.gemini/settings.json`:** ```json { "telemetry": { "enabled": true, "target": "gcp", "useCollector": true } } ``` 2. **Start the telemetry collector:** Run the following command to start a local OTel collector that forwards to Google Cloud: ```bash npm run telemetry -- --target=gcp ``` The script outputs links to view traces, metrics, and logs in the Google Cloud Console. - **Collector logs:** `~/.gemini/tmp//otel/collector-gcp.log` 3. **Run Gemini CLI:** In a separate terminal, run your Gemini CLI command: ```bash gemini ``` 4. **View logs, metrics, and traces:** After sending prompts, view your data in the Google Cloud Console. See the [telemetry documentation](/docs/cli/telemetry#view-google-cloud-telemetry) for links to Logs, Metrics, and Trace explorers. For more detailed information on telemetry, see the [telemetry documentation](/docs/cli/telemetry). ### Instrument code with traces You can add traces to your own code for more detailed instrumentation. Adding traces helps you debug and understand the flow of execution. Use the `runInDevTraceSpan` function to wrap any section of code in a trace span. Here is a basic example: ```typescript import { runInDevTraceSpan } from '@google/gemini-cli-core'; import { GeminiCliOperation } from '@google/gemini-cli-core/lib/telemetry/constants.js'; await runInDevTraceSpan( { operation: GeminiCliOperation.ToolCall, attributes: { [GEN_AI_AGENT_NAME]: 'gemini-cli', }, }, async ({ metadata }) => { // metadata allows you to record the input and output of the // operation as well as other attributes. metadata.input = { key: 'value' }; // Set custom attributes. metadata.attributes['custom.attribute'] = 'custom.value'; // Your code to be traced goes here. try { const output = await somethingRisky(); metadata.output = output; return output; } catch (e) { metadata.error = e; throw e; } }, ); ``` In this example: - `operation`: The operation type of the span, represented by the `GeminiCliOperation` enum. - `metadata.input`: (Optional) An object containing the input data for the traced operation. - `metadata.output`: (Optional) An object containing the output data from the traced operation. - `metadata.attributes`: (Optional) A record of custom attributes to add to the span. - `metadata.error`: (Optional) An error object to record if the operation fails. # [Gemini CLI releases](http://geminicli.com/docs/releases.md) > [!IMPORTANT] > **Coordinate with the Release Manager:** The release manager is responsible for coordinating patches and releases. Please update them before performing any of the release actions described in this document. ## `dev` vs `prod` environment Our release flows support both `dev` and `prod` environments. The `dev` environment pushes to a private GitHub-hosted NPM repository, with the package names beginning with `@google-gemini/**` instead of `@google/**`. The `prod` environment pushes to the public global NPM registry via Wombat Dressing Room, which is Google's system for managing NPM packages in the `@google/**` namespace. The packages are all named `@google/**`. More information can be found about these systems in the [NPM Package Overview](/docs/npm) ### Package scopes | Package | `prod` (Wombat Dressing Room) | `dev` (GitHub Private NPM Repo) | | ---------- | ----------------------------- | ----------------------------------------- | | CLI | @google/gemini-cli | @google-gemini/gemini-cli | | Core | @google/gemini-cli-core | @google-gemini/gemini-cli-core A2A Server | | A2A Server | @google/gemini-cli-a2a-server | @google-gemini/gemini-cli-a2a-server | ## Release cadence and tags We will follow https://semver.org/ as closely as possible but will call out when or if we have to deviate from it. Our weekly releases will be minor version increments and any bug or hotfixes between releases will go out as patch versions on the most recent release. Each Tuesday ~20:00 UTC new Stable and Preview releases will be cut. The promotion flow is: - Code is committed to main and pushed each night to nightly - After no more than 1 week on main, code is promoted to the `preview` channel - After 1 week the most recent `preview` channel is promoted to `stable` channel - Patch fixes will be produced against both `preview` and `stable` as needed, with the final 'patch' version number incrementing each time. ### Preview These releases will not have been fully vetted and may contain regressions or other outstanding issues. Help us test and install with `preview` tag. ```bash npm install -g @google/gemini-cli@preview ``` ### Stable This will be the full promotion of last week's release + any bug fixes and validations. Use `latest` tag. ```bash npm install -g @google/gemini-cli@latest ``` ### Nightly - New releases will be published each day at UTC 00:00. This will be all changes from the main branch as represented at time of release. It should be assumed there are pending validations and issues. Use `nightly` tag. ```bash npm install -g @google/gemini-cli@nightly ``` ## Weekly release promotion Each Tuesday, the on-call engineer will trigger the "Promote Release" workflow. This single action automates the entire weekly release process: 1. **Promotes preview to stable:** The workflow identifies the latest `preview` release and promotes it to `stable`. This becomes the new `latest` version on npm. 2. **Promotes nightly to preview:** The latest `nightly` release is then promoted to become the new `preview` version. 3. **Prepares for next nightly:** A pull request is automatically created and merged to bump the version in `main` in preparation for the next nightly release. This process ensures a consistent and reliable release cadence with minimal manual intervention. ### Source of truth for versioning To ensure the highest reliability, the release promotion process uses the **NPM registry as the single source of truth** for determining the current version of each release channel (`stable`, `preview`, and `nightly`). 1. **Fetch from NPM:** The workflow begins by querying NPM's `dist-tags` (`latest`, `preview`, `nightly`) to get the exact version strings for the packages currently available to users. 2. **Cross-check for integrity:** For each version retrieved from NPM, the workflow performs a critical integrity check: - It verifies that a corresponding **git tag** exists in the repository. - It verifies that a corresponding **GitHub release** has been created. 3. **Halt on discrepancy:** If either the git tag or the GitHub Release is missing for a version listed on NPM, the workflow will immediately fail. This strict check prevents promotions from a broken or incomplete previous release and alerts the on-call engineer to a release state inconsistency that must be manually resolved. 4. **Calculate next version:** Only after these checks pass does the workflow proceed to calculate the next semantic version based on the trusted version numbers retrieved from NPM. This NPM-first approach, backed by integrity checks, makes the release process highly robust and prevents the kinds of versioning discrepancies that can arise from relying solely on git history or API outputs. ## Manual releases For situations requiring a release outside of the regular nightly and weekly promotion schedule, and NOT already covered by patching process, you can use the `Release: Manual` workflow. This workflow provides a direct way to publish a specific version from any branch, tag, or commit SHA. ### How to create a manual release 1. Navigate to the **Actions** tab of the repository. 2. Select the **Release: Manual** workflow from the list. 3. Click the **Run workflow** dropdown button. 4. Fill in the required inputs: - **Version**: The exact version to release (for example, `v0.6.1`). This must be a valid semantic version with a `v` prefix. - **Ref**: The branch, tag, or full commit SHA to release from. - **NPM Channel**: The npm channel to publish to. The options are `preview`, `nightly`, `latest` (for stable releases), and `dev`. The default is `dev`. - **Dry Run**: Leave as `true` to run all steps without publishing, or set to `false` to perform a live release. - **Force Skip Tests**: Set to `true` to skip the test suite. This is not recommended for production releases. - **Skip GitHub Release**: Set to `true` to skip creating a GitHub release and create an npm release only. - **Environment**: Select the appropriate environment. The `dev` environment is intended for testing. The `prod` environment is intended for production releases. `prod` is the default and will require authorization from a release administrator. 5. Click **Run workflow**. The workflow will then proceed to test (if not skipped), build, and publish the release. If the workflow fails during a non-dry run, it will automatically create a GitHub issue with the failure details. ## Rollback/rollforward In the event that a release has a critical regression, you can quickly roll back to a previous stable version or roll forward to a new patch by changing the npm `dist-tag`. The `Release: Change Tags` workflow provides a safe and controlled way to do this. This is the preferred method for both rollbacks and rollforwards, as it does not require a full release cycle. ### How to change a release tag 1. Navigate to the **Actions** tab of the repository. 2. Select the **Release: Change Tags** workflow from the list. 3. Click the **Run workflow** dropdown button. 4. Fill in the required inputs: - **Version**: The existing package version that you want to point the tag to (for example, `0.5.0-preview-2`). This version **must** already be published to the npm registry. - **Channel**: The npm `dist-tag` to apply (for example, `preview`, `stable`). - **Dry Run**: Leave as `true` to log the action without making changes, or set to `false` to perform the live tag change. - **Environment**: Select the appropriate environment. The `dev` environment is intended for testing. The `prod` environment is intended for production releases. `prod` is the default and will require authorization from a release administrator. 5. Click **Run workflow**. The workflow will then run `npm dist-tag add` for the appropriate `gemini-cli`, `gemini-cli-core` and `gemini-cli-a2a-server` packages, pointing the specified channel to the specified version. ## Patching If a critical bug that is already fixed on `main` needs to be patched on a `stable` or `preview` release, the process is now highly automated. ### How to patch #### 1. Create the patch pull request There are two ways to create a patch pull request: **Option A: From a GitHub comment (recommended)** After a pull request containing the fix has been merged, a maintainer can add a comment on that same PR with the following format: `/patch [channel]` - **channel** (optional): - _no channel_ - patches both stable and preview channels (default, recommended for most fixes) - `both` - patches both stable and preview channels (same as default) - `stable` - patches only the stable channel - `preview` - patches only the preview channel Examples: - `/patch` (patches both stable and preview - default) - `/patch both` (patches both stable and preview - explicit) - `/patch stable` (patches only stable) - `/patch preview` (patches only preview) The `Release: Patch from Comment` workflow will automatically find the merge commit SHA and trigger the `Release: Patch (1) Create PR` workflow. If the PR is not yet merged, it will post a comment indicating the failure. **Option B: Manually triggering the workflow** Navigate to the **Actions** tab and run the **Release: Patch (1) Create PR** workflow. - **Commit**: The full SHA of the commit on `main` that you want to cherry-pick. - **Channel**: The channel you want to patch (`stable` or `preview`). This workflow will automatically: 1. Find the latest release tag for the channel. 2. Create a release branch from that tag if one doesn't exist (for example, `release/v0.5.1-pr-12345`). 3. Create a new hotfix branch from the release branch. 4. Cherry-pick your specified commit into the hotfix branch. 5. Create a pull request from the hotfix branch back to the release branch. #### 2. Review and merge Review the automatically created pull request(s) to ensure the cherry-pick was successful and the changes are correct. Once approved, merge the pull request. > [!WARNING] > The `release/*` branches are protected by branch protection > rules. A pull request to one of these branches requires at least one review from > a code owner before it can be merged. This ensures that no unauthorized code is > released. #### 2.5. Adding multiple commits to a hotfix (advanced) If you need to include multiple fixes in a single patch release, you can add additional commits to the hotfix branch after the initial patch PR has been created: 1. **Start with the primary fix**: Use `/patch` (or `/patch both`) on the most important PR to create the initial hotfix branch and PR. 2. **Checkout the hotfix branch locally**: ```bash git fetch origin git checkout hotfix/v0.5.1/stable/cherry-pick-abc1234 # Use the actual branch name from the PR ``` 3. **Cherry-pick additional commits**: ```bash git cherry-pick git cherry-pick # Add as many commits as needed ``` 4. **Push the updated branch**: ```bash git push origin hotfix/v0.5.1/stable/cherry-pick-abc1234 ``` 5. **Test and review**: The existing patch PR will automatically update with your additional commits. Test thoroughly since you're now releasing multiple changes together. 6. **Update the PR description**: Consider updating the PR title and description to reflect that it includes multiple fixes. This approach lets you group related fixes into a single patch release while maintaining full control over what gets included and how conflicts are resolved. #### 3. Automatic release Upon merging the pull request, the `Release: Patch (2) Trigger` workflow is automatically triggered. It will then start the `Release: Patch (3) Release` workflow, which will: 1. Build and test the patched code. 2. Publish the new patch version to npm. 3. Create a new GitHub release with the patch notes. This fully automated process ensures that patches are created and released consistently and reliably. #### Troubleshooting: Older branch workflows **Issue**: If the patch trigger workflow fails with errors like "Resource not accessible by integration" or references to non-existent workflow files (for example, `patch-release.yml`), this indicates the hotfix branch contains an outdated version of the workflow files. **Root cause**: When a PR is merged, GitHub Actions runs the workflow definition from the **source branch** (the hotfix branch), not from the target branch (the release branch). If the hotfix branch was created from an older release branch that predates workflow improvements, it will use the old workflow logic. **Solutions**: **Option 1: Manual trigger (quick fix)** Manually trigger the updated workflow from the branch with the latest workflow code: ```bash # For a preview channel patch with tests skipped gh workflow run release-patch-2-trigger.yml --ref \ --field ref="hotfix/v0.6.0-preview.2/preview/cherry-pick-abc1234" \ --field workflow_ref= \ --field dry_run=false \ --field force_skip_tests=true # For a stable channel patch gh workflow run release-patch-2-trigger.yml --ref \ --field ref="hotfix/v0.5.1/stable/cherry-pick-abc1234" \ --field workflow_ref= \ --field dry_run=false \ --field force_skip_tests=false # Example using main branch (most common case) gh workflow run release-patch-2-trigger.yml --ref main \ --field ref="hotfix/v0.6.0-preview.2/preview/cherry-pick-abc1234" \ --field workflow_ref=main \ --field dry_run=false \ --field force_skip_tests=true ``` **Note**: Replace `` with the branch containing the latest workflow improvements (usually `main`, but could be a feature branch if testing updates). **Option 2: Update the hotfix branch** Merge the latest main branch into your hotfix branch to get the updated workflows: ```bash git checkout hotfix/v0.6.0-preview.2/preview/cherry-pick-abc1234 git merge main git push ``` Then close and reopen the PR to retrigger the workflow with the updated version. **Option 3: Direct release trigger** Skip the trigger workflow entirely and directly run the release workflow: ```bash # Replace channel and release_ref with appropriate values gh workflow run release-patch-3-release.yml --ref main \ --field type="preview" \ --field dry_run=false \ --field force_skip_tests=true \ --field release_ref="release/v0.6.0-preview.2" ``` ### Docker We also run a Google cloud build called [release-docker.yml](https://github.com/google-gemini/gemini-cli/blob/main/.gcp/release-docker.yml). Which publishes the sandbox docker to match your release. This will also be moved to GH and combined with the main release file once service account permissions are sorted out. ## Release validation After pushing a new release smoke testing should be performed to ensure that the packages are working as expected. This can be done by installing the packages locally and running a set of tests to ensure that they are functioning correctly. - `npx -y @google/gemini-cli@latest --version` to validate the push worked as expected if you were not doing a rc or dev tag - `npx -y @google/gemini-cli@ --version` to validate the tag pushed appropriately - _This is destructive locally_ `npm uninstall @google/gemini-cli && npm uninstall -g @google/gemini-cli && npm cache clean --force && npm install @google/gemini-cli@` - Smoke testing a basic run through of exercising a few llm commands and tools is recommended to ensure that the packages are working as expected. We'll codify this more in the future. ## Local testing and validation: Changes to the packaging and publishing process If you need to test the release process without actually publishing to NPM or creating a public GitHub release, you can trigger the workflow manually from the GitHub UI. 1. Go to the [Actions tab](https://github.com/google-gemini/gemini-cli/actions/workflows/release-manual.yml) of the repository. 2. Click on the "Run workflow" dropdown. 3. Leave the `dry_run` option checked (`true`). 4. Click the "Run workflow" button. This will run the entire release process but will skip the `npm publish` and `gh release create` steps. You can inspect the workflow logs to ensure everything is working as expected. It is crucial to test any changes to the packaging and publishing process locally before committing them. This ensures that the packages will be published correctly and that they will work as expected when installed by a user. To validate your changes, you can perform a dry run of the publishing process. This will simulate the publishing process without actually publishing the packages to the npm registry. ```bash npm_package_version=9.9.9 SANDBOX_IMAGE_REGISTRY="registry" SANDBOX_IMAGE_NAME="thename" npm run publish:npm --dry-run ``` This command will do the following: 1. Build all the packages. 2. Run all the prepublish scripts. 3. Create the package tarballs that would be published to npm. 4. Print a summary of the packages that would be published. You can then inspect the generated tarballs to ensure that they contain the correct files and that the `package.json` files have been updated correctly. The tarballs will be created in the root of each package's directory (for example, `packages/cli/google-gemini-cli-0.1.6.tgz`). By performing a dry run, you can be confident that your changes to the packaging process are correct and that the packages will be published successfully. ## Release deep dive The release process creates two distinct types of artifacts for different distribution channels: standard packages for the NPM registry and a single, self-contained executable for GitHub Releases. Here are the key stages: **Stage 1: Pre-release sanity checks and versioning** - **What happens:** Before any files are moved, the process ensures the project is in a good state. This involves running tests, linting, and type-checking (`npm run preflight`). The version number in the root `package.json` and `packages/cli/package.json` is updated to the new release version. **Stage 2: Building the source code for NPM** - **What happens:** The TypeScript source code in `packages/core/src` and `packages/cli/src` is compiled into standard JavaScript. - **File movement:** - `packages/core/src/**/*.ts` -> compiled to -> `packages/core/dist/` - `packages/cli/src/**/*.ts` -> compiled to -> `packages/cli/dist/` - **Why:** The TypeScript code written during development needs to be converted into plain JavaScript that can be run by Node.js. The `core` package is built first as the `cli` package depends on it. **Stage 3: Publishing standard packages to NPM** - **What happens:** The `npm publish` command is run for the `@google/gemini-cli-core` and `@google/gemini-cli` packages. - **Why:** This publishes them as standard Node.js packages. Users installing via `npm install -g @google/gemini-cli` will download these packages, and `npm` will handle installing the `@google/gemini-cli-core` dependency automatically. The code in these packages is not bundled into a single file. **Stage 4: Assembling and creating the GitHub release asset** This stage happens _after_ the NPM publish and creates the single-file executable that enables `npx` usage directly from the GitHub repository. 1. **The JavaScript bundle is created:** - **What happens:** The built JavaScript from both `packages/core/dist` and `packages/cli/dist`, along with all third-party JavaScript dependencies, are bundled by `esbuild` into a single, executable JavaScript file (for example, `gemini.js`). The `node-pty` library is excluded from this bundle as it contains native binaries. - **Why:** This creates a single, optimized file that contains all the necessary application code. It simplifies execution for users who want to run the CLI without a full `npm install`, as all dependencies (including the `core` package) are included directly. 2. **The `bundle` directory is assembled:** - **What happens:** A temporary `bundle` folder is created at the project root. The single `gemini.js` executable is placed inside it, along with other essential files. - **File movement:** - `gemini.js` (from esbuild) -> `bundle/gemini.js` - `README.md` -> `bundle/README.md` - `LICENSE` -> `bundle/LICENSE` - `packages/cli/src/utils/*.sb` (sandbox profiles) -> `bundle/` - **Why:** This creates a clean, self-contained directory with everything needed to run the CLI and understand its license and usage. 3. **The GitHub release is created:** - **What happens:** The contents of the `bundle` directory, including the `gemini.js` executable, are attached as assets to a new GitHub Release. - **Why:** This makes the single-file version of the CLI available for direct download and enables the `npx https://github.com/google-gemini/gemini-cli` command, which downloads and runs this specific bundled asset. **Summary of artifacts** - **NPM:** Publishes standard, un-bundled Node.js packages. The primary artifact is the code in `packages/cli/dist`, which depends on `@google/gemini-cli-core`. - **GitHub release:** Publishes a single, bundled `gemini.js` file that contains all dependencies, for easy execution via `npx`. This dual-artifact process ensures that both traditional `npm` users and those who prefer the convenience of `npx` have an optimized experience. ## Notifications Failing release workflows will automatically create an issue with the label `release-failure`. A notification will be posted to the maintainer's chat channel when issues with this type are created. ### Modifying chat notifications Notifications use [GitHub for Google Chat](https://workspace.google.com/marketplace/app/github_for_google_chat/536184076190). To modify the notifications, use `/github-settings` within the chat space. > [!WARNING] > The following instructions describe a fragile workaround that depends on the > internal structure of the chat application's UI. It is likely to break with > future updates. The list of available labels is not currently populated correctly. If you want to add a label that does not appear alphabetically in the first 30 labels in the repo, you must use your browser's developer tools to manually modify the UI: 1. Open your browser's developer tools (for example, Chrome DevTools). 2. In the `/github-settings` dialog, inspect the list of labels. 3. Locate one of the `
  • ` elements representing a label. 4. In the HTML, modify the `data-option-value` attribute of that `
  • ` element to the desired label name (for example, `release-failure`). 5. Click on your modified label in the UI to select it, then save your settings. # [Behavioral Evaluations & EDK Guide](http://geminicli.com/docs/behavioral-evals.md) This guide introduces the **Eval Development Kit (EDK)** and details how to write, validate, run, and report on **behavioral evaluations** in the Gemini CLI codebase. --- ## Overview Behavioral evaluations are automated tests designed to assert on the **behavior** of the Gemini CLI agent (e.g., verifying which tools are called, checking call ordering, or avoiding destructive commands) rather than checking the final prose output. Evaluating agent behavior is critical because: 1. Model responses are non-deterministic, making exact prose matching highly fragile. 2. We must ensure the model utilizes the most efficient tools (e.g., batching files via `read_many_files` instead of sequential `read_file` calls). 3. We must enforce safety boundaries (e.g., preventing execution of raw shell commands when safe alternatives exist). All behavioral evaluations are stored under the `evals/` directory. --- ## EDK Developer Commands The EDK provides CLI tools under `scripts/` to help contributors audit, check, and monitor evals. ### 1. `npm run eval:inventory` Scans all eval files under `evals/`, statically parses them, and provides a structured overview of what exists in the repository. - **Usage:** ```bash npm run eval:inventory ``` - **JSON Output:** For CI integration or inventory indexing, generate a machine-readable JSON report: ```bash npm run eval:inventory -- --json ``` - **Custom Root:** Run against another directory or repository: ```bash npm run eval:inventory -- --root /path/to/other/repo ``` --- ### 2. `npm run eval:validate` A lint-like checker that validates eval source files against standard structural guidelines and best practices. - **Usage:** ```bash npm run eval:validate ``` - **Custom Scopes:** Validate a specific file: ```bash npm run eval:validate -- evals/my-test.eval.ts ``` #### Validation Rules & Severities | Rule ID | Severity | Description | | :------------------- | :---------- | :--------------------------------------------------------------------------------------------------------------------- | | `file-naming` | **Error** | File must match `*.eval.ts` or `*.eval.tsx` naming conventions. | | `valid-policy` | **Error** | Policy must be one of `ALWAYS_PASSES`, `USUALLY_PASSES`, or `USUALLY_FAILS`. | | `suite-metadata` | **Error** | Both `suiteName` and `suiteType` must be present as static string literals. | | `prompt-presence` | **Error** | Every eval case must have a non-empty `prompt` string. | | `case-name-static` | **Error** | The case name must be a static string literal, not computed dynamically. | | `invalid-tool-refs` | **Error** | All tools referenced in assertions must match known built-in or legacy tools. | | `positive-assertion` | **Error** | Evaluation cases must assert on at least one tool call (e.g., check `waitForToolCall` has been invoked). | | `workspace-setup` | **Error** | Workspace behaviors (like file-system edits/reads) must set up a `files` object. | | `new-evals-policy` | **Warning** | New evals must not use `ALWAYS_PASSES` policy initially (they should be promoted after nightly data proves stability). | Warnings (`new-evals-policy`) will be logged with `⚠` and will **not** cause the CLI process to exit with status `1`. Errors (`βœ—`) will block CI builds and return exit status `1`. --- ### 3. `npm run eval:report` Aggregates local vitest `report.json` artifacts, maps them against inventory policies, and summarizes the pass rates per model. - **Usage:** ```bash npm run eval:report ``` By default, it scans `evals/logs/` recursively for `report.json` files. - **Specifying Directory:** ```bash npm run eval:report -- /path/to/logs ``` - **JSON Output:** ```bash npm run eval:report -- --json ``` --- ## Contributor Workflow When writing a new behavioral evaluation, adhere to this workflow to ensure high-quality, non-flaky test runs. ### Step-by-Step Guide 1. **Identify the Target Behavior**: Determine which tool calls need verification (e.g., `web_fetch` must be called). 2. **Author the Eval File**: Create your file under `evals/.eval.ts` naming it properly. 3. **Configure Workspace Files**: If the eval reads or edits files, define them inside the `files` metadata field. 4. **Assert Behavior, Not Prose**: Ensure the `assert` block checks tool interactions using `rig.waitForToolCall` or similar. Do not check final prose. 5. **Run Locally**: ```bash RUN_EVALS=true npx vitest run evals/my-test.eval.ts ``` 6. **Deflake**: Run your eval at least 3 times locally to verify it does not fail due to model variance. 7. **Run Validation**: Run `npm run eval:validate` to ensure no linting errors are present. ### Acceptance Criteria Checklist - [ ] **Naming**: File ends with `.eval.ts` or `.eval.tsx`. - [ ] **Policy**: New evals start as `USUALLY_PASSES`. - [ ] **Metadata**: Static `suiteName` and `suiteType` (e.g. `'behavioral'`) are specified. - [ ] **Assertions**: Uses `rig.waitForToolCall` or asserts tool arguments explicitly. - [ ] **Clean workspace**: Does not write to files outside `rig.testDir`. ### Common Anti-Patterns to Avoid - **Restricting core tools**: Never override `settings.tools.core` to limit tools. Evals must run against the default toolset. - **Checking model prose**: Avoid `expect(result).toContain('something')` since model wording is non-deterministic. - **Integration-only testing**: Evals that only write files without checking realistic model prompts are integration tests and belong under `integration-tests/`. --- ## CI & Dashboard Integration You can easily automate behavioral evaluations or compile dashboard data using EDK's JSON reporters. ### CI Validation Block Add a step in your PR checks or GitHub workflows to automatically lint new evals and block pull requests containing validation errors: ```yaml - name: Run Eval Validator run: npm run eval:validate ``` ### Publishing to a Dashboard To record nightly performance metrics across multiple models: 1. Configure your workflow to run evaluations with the JSON reporter: ```bash cross-env GEMINI_MODEL=gemini-2.5-pro npx vitest run --config evals/vitest.config.ts --reporter=json --outputFile="evals/logs/eval-logs-gemini-2.5-pro/report.json" ``` 2. Aggregate all test runs using the reporting tool: ```bash npm run eval:report -- evals/logs --json > aggregated_report.json ``` 3. Upload `aggregated_report.json` to your dashboard storage backend to visualize pass rates over time. # [How to contribute](http://geminicli.com/docs/contributing.md) We would love to accept your patches and contributions to this project. This document includes: - **[Before you begin](#before-you-begin):** Essential steps to take before becoming a Gemini CLI contributor. - **[Code contribution process](#code-contribution-process):** How to contribute code to Gemini CLI. - **[Development setup and workflow](#development-setup-and-workflow):** How to set up your development environment and workflow. - **[Documentation contribution process](#documentation-contribution-process):** How to contribute documentation to Gemini CLI. We're looking forward to seeing your contributions! ## Before you begin ### Sign our Contributor License Agreement Contributions to this project must be accompanied by a [Contributor License Agreement](https://cla.developers.google.com/about) (CLA). You (or your employer) retain the copyright to your contribution; this simply gives us permission to use and redistribute your contributions as part of the project. If you or your current employer have already signed the Google CLA (even if it was for a different project), you probably don't need to do it again. Visit to see your current agreements or to sign a new one. ### Review our Community Guidelines This project follows [Google's Open Source Community Guidelines](https://opensource.google/conduct/). ## Code contribution process ### Get started The process for contributing code is as follows: 1. **Find an issue** that you want to work on. If an issue is tagged as `πŸ”’Maintainers only`, this means it is reserved for project maintainers. We will not accept pull requests related to these issues. In the near future, we will explicitly mark issues looking for contributions using the `help-wanted` label. If you believe an issue is a good candidate for community contribution, please leave a comment on the issue. A maintainer will review it and apply the `help-wanted` label if appropriate. Only maintainers should attempt to add the `help-wanted` label to an issue. 2. **Fork the repository** and create a new branch. 3. **Make your changes** in the `packages/` directory. 4. **Ensure all checks pass** by running `npm run preflight`. 5. **Open a pull request** with your changes. ### Code reviews All submissions, including submissions by project members, require review. We use [GitHub pull requests](https://docs.github.com/articles/about-pull-requests) for this purpose. To assist with the review process, we provide an automated review tool that helps detect common anti-patterns, testing issues, and other best practices that are easy to miss. #### Using the automated review tool You can run the review tool in two ways: 1. **Using the helper script (Recommended):** We provide a script that automatically handles checking out the PR into a separate worktree, installing dependencies, building the project, and launching the review tool. ```bash ./scripts/review.sh [model] ``` **Warning:** If you run `scripts/review.sh`, you must have first verified that the code for the PR being reviewed is safe to run and does not contain data exfiltration attacks. **Authors are strongly encouraged to run this script on their own PRs** immediately after creation. This allows you to catch and fix simple issues locally before a maintainer performs a full review. **Note on Models:** By default, the script uses the latest Pro model (`gemini-3.1-pro-preview`). If you do not have enough Pro quota, you can run it with the latest Flash model instead: `./scripts/review.sh gemini-3-flash-preview`. 2. **Manually from within Gemini CLI:** If you already have the PR checked out and built, you can run the tool directly from the CLI prompt: ```text /review-frontend ``` Replace `` with your pull request number. Reviewers should use this tool to augment, not replace, their manual review process. ### Self-assigning and unassigning issues To assign an issue to yourself, simply add a comment with the text `/assign`. To unassign yourself from an issue, add a comment with the text `/unassign`. The comment must contain only that text and nothing else. These commands will assign or unassign the issue as requested, provided the conditions are met (e.g., an issue must be unassigned to be assigned). Please note that you can have a maximum of 3 issues assigned to you at any given time and that only [issues labeled "help wanted"](https://github.com/google-gemini/gemini-cli/issues?q=is%3Aissue%20state%3Aopen%20label%3A%22help%20wanted%22) may be self-assigned. ### Pull request guidelines To help us review and merge your PRs quickly, please follow these guidelines. PRs that do not meet these standards may be closed. #### 1. Link to an existing issue All PRs should be linked to an existing issue in our tracker. This ensures that every change has been discussed and is aligned with the project's goals before any code is written. - **For bug fixes:** The PR should be linked to the bug report issue. - **For features:** The PR should be linked to the feature request or proposal issue that has been approved by a maintainer. If an issue for your change doesn't exist, we will automatically close your PR along with a comment reminding you to associate the PR with an issue. The ideal workflow starts with an issue that has been reviewed and approved by a maintainer. Please **open the issue first** and wait for feedback before you start coding. #### 2. Keep it small and focused We favor small, atomic PRs that address a single issue or add a single, self-contained feature. - **Do:** Create a PR that fixes one specific bug or adds one specific feature. - **Don't:** Bundle multiple unrelated changes (e.g., a bug fix, a new feature, and a refactor) into a single PR. Large changes should be broken down into a series of smaller, logical PRs that can be reviewed and merged independently. #### 3. Use draft PRs for work in progress If you'd like to get early feedback on your work, please use GitHub's **Draft Pull Request** feature. This signals to the maintainers that the PR is not yet ready for a formal review but is open for discussion and initial feedback. #### 4. Ensure all checks pass Before submitting your PR, ensure that all automated checks are passing by running `npm run preflight`. This command runs all tests, linting, and other style checks. #### 5. Update documentation If your PR introduces a user-facing change (e.g., a new command, a modified flag, or a change in behavior), you must also update the relevant documentation in the `/docs` directory. See more about writing documentation: [Documentation contribution process](#documentation-contribution-process). #### 6. Write clear commit messages and a good PR description Your PR should have a clear, descriptive title and a detailed description of the changes. Follow the [Conventional Commits](https://www.conventionalcommits.org/) standard for your commit messages. - **Good PR title:** `feat(cli): Add --json flag to 'config get' command` - **Bad PR title:** `Made some changes` In the PR description, explain the "why" behind your changes and link to the relevant issue (e.g., `Fixes #123`). ### Forking If you are forking the repository you will be able to run the Build, Test and Integration test workflows. However in order to make the integration tests run you'll need to add a [GitHub Repository Secret](https://docs.github.com/en/actions/security-for-github-actions/security-guides/using-secrets-in-github-actions#creating-secrets-for-a-repository) with a value of `GEMINI_API_KEY` and set that to a valid API key that you have available. Your key and secret are private to your repo; no one without access can see your key and you cannot see any secrets related to this repo. Additionally you will need to click on the `Actions` tab and enable workflows for your repository, you'll find it's the large blue button in the center of the screen. ### Development setup and workflow This section guides contributors on how to build, modify, and understand the development setup of this project. ### Setting up the development environment **Prerequisites:** 1. **Node.js**: - **Development:** Please use Node.js `~20.19.0`. This specific version is required due to an upstream development dependency issue. You can use a tool like [nvm](https://github.com/nvm-sh/nvm) to manage Node.js versions. - **Production:** For running the CLI in a production environment, any version of Node.js `>=20` is acceptable. 2. **Git** ### Build process To clone the repository: ```bash git clone https://github.com/google-gemini/gemini-cli.git # Or your fork's URL cd gemini-cli ``` To install dependencies defined in `package.json` as well as root dependencies: ```bash npm install ``` To build the entire project (all packages): ```bash npm run build ``` This command typically compiles TypeScript to JavaScript, bundles assets, and prepares the packages for execution. Refer to `scripts/build.js` and `package.json` scripts for more details on what happens during the build. ### Enabling sandboxing [Sandboxing](#sandboxing) is highly recommended and requires, at a minimum, setting `GEMINI_SANDBOX=true` in your `~/.env` and ensuring a sandboxing provider (e.g. `macOS Seatbelt`, `docker`, or `podman`) is available. See [Sandboxing](#sandboxing) for details. To build both the `gemini` CLI utility and the sandbox container, run `build:all` from the root directory: ```bash npm run build:all ``` To skip building the sandbox container, you can use `npm run build` instead. ### Running the CLI To start the Gemini CLI from the source code (after building), run the following command from the root directory: ```bash npm start ``` If you'd like to run the source build outside of the gemini-cli folder, you can utilize `npm link path/to/gemini-cli/packages/cli` (see: [docs](https://docs.npmjs.com/cli/v9/commands/npm-link)) or `alias gemini="node path/to/gemini-cli/packages/cli"` to run with `gemini` ### Running tests This project contains two types of tests: unit tests and integration tests. #### Unit tests To execute the unit test suite for the project: ```bash npm run test ``` This will run tests located in the `packages/core` and `packages/cli` directories. Ensure tests pass before submitting any changes. For a more comprehensive check, it is recommended to run `npm run preflight`. #### Integration tests The integration tests are designed to validate the end-to-end functionality of the Gemini CLI. They are not run as part of the default `npm run test` command. To run the integration tests, use the following command: ```bash npm run test:e2e ``` For more detailed information on the integration testing framework, please see the [Integration Tests documentation](https://geminicli.com/docs/integration-tests). ### Linting and preflight checks To ensure code quality and formatting consistency, run the preflight check: ```bash npm run preflight ``` This command will run ESLint, Prettier, all tests, and other checks as defined in the project's `package.json`. _ProTip_ after cloning create a git precommit hook file to ensure your commits are always clean. ```bash echo " # Run npm build and check for errors if ! npm run preflight; then echo "npm build failed. Commit aborted." exit 1 fi " > .git/hooks/pre-commit && chmod +x .git/hooks/pre-commit ``` #### Formatting To separately format the code in this project, run the following command from the root directory: ```bash npm run format ``` This command uses Prettier to format the code according to the project's style guidelines. #### Linting To separately lint the code in this project, run the following command from the root directory: ```bash npm run lint ``` ### Coding conventions - Please adhere to the coding style, patterns, and conventions used throughout the existing codebase. - Consult [GEMINI.md](https://github.com/google-gemini/gemini-cli/blob/main/GEMINI.md) (typically found in the project root) for specific instructions related to AI-assisted development, including conventions for React, comments, and Git usage. - **Imports:** Pay special attention to import paths. The project uses ESLint to enforce restrictions on relative imports between packages. ### Debugging #### VS Code 0. Run the CLI to interactively debug in VS Code with `F5` 1. Start the CLI in debug mode from the root directory: ```bash npm run debug ``` This command runs `node --inspect-brk dist/gemini.js` within the `packages/cli` directory, pausing execution until a debugger attaches. You can then open `chrome://inspect` in your Chrome browser to connect to the debugger. 2. In VS Code, use the "Attach" launch configuration (found in `.vscode/launch.json`). Alternatively, you can use the "Launch Program" configuration in VS Code if you prefer to launch the currently open file directly, but 'F5' is generally recommended. To hit a breakpoint inside the sandbox container run: ```bash DEBUG=1 gemini ``` **Note:** If you have `DEBUG=true` in a project's `.env` file, it won't affect gemini-cli due to automatic exclusion. Use `.gemini/.env` files for gemini-cli specific debug settings. ### React DevTools To debug the CLI's React-based UI, you can use React DevTools. 1. **Start the Gemini CLI in development mode:** ```bash DEV=true npm start ``` 2. **Install and run React DevTools version 6 (which matches the CLI's `react-devtools-core`):** You can either install it globally: ```bash npm install -g react-devtools@6 react-devtools ``` Or run it directly using npx: ```bash npx react-devtools@6 ``` Your running CLI application should then connect to React DevTools. ![](/docs/assets/connected_devtools.png) ### Sandboxing #### macOS Seatbelt On macOS, `gemini` uses Seatbelt (`sandbox-exec`) under a `permissive-open` profile (see `packages/cli/src/utils/sandbox-macos-permissive-open.sb`) that denies operations by default, confining writes to the project folder while allowing broad file reads and outbound network traffic ("open") by default. You can switch to a `strict-open` profile (see `packages/cli/src/utils/sandbox-macos-strict-open.sb`) that restricts both reads and writes to the working directory while allowing outbound network traffic by setting `SEATBELT_PROFILE=strict-open` in your environment or `.env` file. Available built-in profiles are `permissive-{open,proxied}`, `restrictive-{open,proxied}`, and `strict-{open,proxied}` (see below for proxied networking). You can also switch to a custom profile `SEATBELT_PROFILE=` if you also create a file `.gemini/sandbox-macos-.sb` under your project settings directory `.gemini`. #### Container-based sandboxing (all platforms) For stronger container-based sandboxing on macOS or other platforms, you can set `GEMINI_SANDBOX=true|docker|podman|` in your environment or `.env` file. The specified command (or if `true` then either `docker` or `podman`) must be installed on the host machine. Once enabled, `npm run build:all` will build a minimal container ("sandbox") image and `npm start` will launch inside a fresh instance of that container. The first build can take 20-30s (mostly due to downloading of the base image) but after that both build and start overhead should be minimal. Default builds (`npm run build`) will not rebuild the sandbox. Container-based sandboxing mounts the project directory (and system temp directory) with read-write access and is started/stopped/removed automatically as you start/stop Gemini CLI. Files created within the sandbox should be automatically mapped to your user/group on host machine. You can easily specify additional mounts, ports, or environment variables by setting `SANDBOX_{MOUNTS,PORTS,ENV}` as needed. You can also fully customize the sandbox for your projects by creating the files `.gemini/sandbox.Dockerfile` and/or `.gemini/sandbox.bashrc` under your project settings directory (`.gemini`) and running `gemini` with `BUILD_SANDBOX=1` to trigger building of your custom sandbox. #### Proxied networking All sandboxing methods, including macOS Seatbelt using `*-proxied` profiles, support restricting outbound network traffic through a custom proxy server that can be specified as `GEMINI_SANDBOX_PROXY_COMMAND=`, where `` must start a proxy server that listens on `:::8877` for relevant requests. See `docs/examples/proxy-script.md` for a minimal proxy that only allows `HTTPS` connections to `example.com:443` (e.g. `curl https://example.com`) and declines all other requests. The proxy is started and stopped automatically alongside the sandbox. ### Manual publish We publish an artifact for each commit to our internal registry. But if you need to manually cut a local build, then run the following commands: ``` npm run clean npm install npm run auth npm run prerelease:dev npm publish --workspaces ``` ## Documentation contribution process Our documentation must be kept up-to-date with our code contributions. We want our documentation to be clear, concise, and helpful to our users. We value: - **Clarity:** Use simple and direct language. Avoid jargon where possible. - **Accuracy:** Ensure all information is correct and up-to-date. - **Completeness:** Cover all aspects of a feature or topic. - **Examples:** Provide practical examples to help users understand how to use Gemini CLI. ### Getting started The process for contributing to the documentation is similar to contributing code. 1. **Fork the repository** and create a new branch. 2. **Make your changes** in the `/docs` directory. 3. **Preview your changes locally** in Markdown rendering. 4. **Lint and format your changes.** Our preflight check includes linting and formatting for documentation files. ```bash npm run preflight ``` 5. **Open a pull request** with your changes. ### Documentation structure Our documentation is organized using [sidebar.json](https://github.com/google-gemini/gemini-cli/blob/main/docs/sidebar.json) as the table of contents. When adding new documentation: 1. Create your markdown file **in the appropriate directory** under `/docs`. 2. Add an entry to `sidebar.json` in the relevant section. 3. Ensure all internal links use relative paths and point to existing files. ### Style guide We follow the [Google Developer Documentation Style Guide](https://developers.google.com/style). Please refer to it for guidance on writing style, tone, and formatting. #### Key style points - Use sentence case for headings. - Write in second person ("you") when addressing the reader. - Use present tense. - Keep paragraphs short and focused. - Use code blocks with appropriate language tags for syntax highlighting. - Include practical examples whenever possible. ### Linting and formatting We use `prettier` to enforce a consistent style across our documentation. The `npm run preflight` command will check for any linting issues. You can also run the linter and formatter separately: - `npm run lint` - Check for linting issues - `npm run format` - Auto-format markdown files - `npm run lint:fix` - Auto-fix linting issues where possible Please make sure your contributions are free of linting errors before submitting a pull request. ### Before you submit Before submitting your documentation pull request, please: 1. Run `npm run preflight` to ensure all checks pass. 2. Review your changes for clarity and accuracy. 3. Check that all links work correctly. 4. Ensure any code examples are tested and functional. 5. Sign the [Contributor License Agreement (CLA)](https://cla.developers.google.com/) if you haven't already. ### Need help? If you have questions about contributing documentation: - Check our [FAQ](https://geminicli.com/docs/resources/faq). - Review existing documentation for examples. - Open [an issue](https://github.com/google-gemini/gemini-cli/issues) to discuss your proposed changes. - Reach out to the maintainers. We appreciate your contributions to making Gemini CLI documentation better! # [Integration tests](http://geminicli.com/docs/integration-tests.md) This document provides information about the integration testing framework used in this project. ## Overview The integration tests are designed to validate the end-to-end functionality of Gemini CLI. They execute the built binary in a controlled environment and verify that it behaves as expected when interacting with the file system. These tests are located in the `integration-tests` directory and are run using a custom test runner. ## Building the tests Prior to running any integration tests, you need to create a release bundle that you want to actually test: ```bash npm run bundle ``` You must re-run this command after making any changes to the CLI source code, but not after making changes to tests. ## Running the tests The integration tests are not run as part of the default `npm run test` command. They must be run explicitly using the `npm run test:integration:all` script. The integration tests can also be run using the following shortcut: ```bash npm run test:e2e ``` ## Running a specific set of tests To run a subset of test files, you can use `npm run ....` where <integration test command> is either `test:e2e` or `test:integration*` and `` is any of the `.test.js` files in the `integration-tests/` directory. For example, the following command runs `list_directory.test.js` and `write_file.test.js`: ```bash npm run test:e2e list_directory write_file ``` ### Running a single test by name To run a single test by its name, use the `--test-name-pattern` flag: ```bash npm run test:e2e -- --test-name-pattern "reads a file" ``` ### Regenerating model responses Some integration tests use faked out model responses, which may need to be regenerated from time to time as the implementations change. To regenerate these golden files, set the REGENERATE_MODEL_GOLDENS environment variable to "true" when running the tests, for example: **WARNING**: If running locally you should review these updated responses for any information about yourself or your system that gemini may have included in these responses. ```bash REGENERATE_MODEL_GOLDENS="true" npm run test:e2e ``` **WARNING**: Make sure you run **await rig.cleanup()** at the end of your test, else the golden files will not be updated. ### Deflaking a test Before adding a **new** integration test, you should test it at least 5 times with the deflake script or workflow to make sure that it is not flaky. ### Deflake script ```bash npm run deflake -- --runs=5 --command="npm run test:e2e -- -- --test-name-pattern ''" ``` #### Deflake workflow ```bash gh workflow run deflake.yml --ref -f test_name_pattern="" ``` ### Running all tests To run the entire suite of integration tests, use the following command: ```bash npm run test:integration:all ``` ### Sandbox matrix The `all` command will run tests for `no sandboxing`, `docker` and `podman`. Each individual type can be run using the following commands: ```bash npm run test:integration:sandbox:none ``` ```bash npm run test:integration:sandbox:docker ``` ```bash npm run test:integration:sandbox:podman ``` ## Memory regression tests Memory regression tests are designed to detect heap growth and leaks across key CLI scenarios. They are located in the `memory-tests` directory. These tests are distinct from standard integration tests because they measure memory usage and compare it against committed baselines. ### Running memory tests Memory tests are not run as part of the default `npm run test` or `npm run test:e2e` commands. They are run nightly in CI but can be run manually: ```bash npm run test:memory ``` ### Updating baselines If you intentionally change behavior that affects memory usage, you may need to update the baselines. Set the `UPDATE_MEMORY_BASELINES` environment variable to `true`: ```bash UPDATE_MEMORY_BASELINES=true npm run test:memory ``` This will run the tests, take median snapshots, and overwrite `memory-tests/baselines.json`. You should review the changes and commit the updated baseline file. ### How it works The harness (`MemoryTestHarness` in `packages/test-utils`): - Forces garbage collection multiple times to reduce noise. - Takes median snapshots to filter spikes. - Compares against baselines with a 10% tolerance. - Can analyze sustained leaks across 3 snapshots using `analyzeSnapshots()`. ## Performance regression tests Performance regression tests are designed to detect wall-clock time, CPU usage, and event loop delay regressions across key CLI scenarios. They are located in the `perf-tests` directory. These tests are distinct from standard integration tests because they measure performance metrics and compare it against committed baselines. ### Running performance tests Performance tests are not run as part of the default `npm run test` or `npm run test:e2e` commands. They are run nightly in CI but can be run manually: ```bash npm run test:perf ``` ### Updating baselines If you intentionally change behavior that affects performance, you may need to update the baselines. Set the `UPDATE_PERF_BASELINES` environment variable to `true`: ```bash UPDATE_PERF_BASELINES=true npm run test:perf ``` This will run the tests multiple times (with warmup), apply IQR outlier filtering, and overwrite `perf-tests/baselines.json`. You should review the changes and commit the updated baseline file. ### How it works The harness (`PerfTestHarness` in `packages/test-utils`): - Measures wall-clock time using `performance.now()`. - Measures CPU usage using `process.cpuUsage()`. - Monitors event loop delay using `perf_hooks.monitorEventLoopDelay()`. - Applies IQR (Interquartile Range) filtering to remove outlier samples. - Compares against baselines with a 15% tolerance. ## Diagnostics The integration test runner provides several options for diagnostics to help track down test failures. ### Keeping test output You can preserve the temporary files created during a test run for inspection. This is useful for debugging issues with file system operations. To keep the test output set the `KEEP_OUTPUT` environment variable to `true`. ```bash KEEP_OUTPUT=true npm run test:integration:sandbox:none ``` When output is kept, the test runner will print the path to the unique directory for the test run. ### Verbose output For more detailed debugging, set the `VERBOSE` environment variable to `true`. ```bash VERBOSE=true npm run test:integration:sandbox:none ``` When using `VERBOSE=true` and `KEEP_OUTPUT=true` in the same command, the output is streamed to the console and also saved to a log file within the test's temporary directory. The verbose output is formatted to clearly identify the source of the logs: ``` --- TEST: : --- ... output from the gemini command ... --- END TEST: : --- ``` ## Linting and formatting To ensure code quality and consistency, the integration test files are linted as part of the main build process. You can also manually run the linter and auto-fixer. ### Running the linter To check for linting errors, run the following command: ```bash npm run lint ``` You can include the `:fix` flag in the command to automatically fix any fixable linting errors: ```bash npm run lint:fix ``` ## Directory structure The integration tests create a unique directory for each test run inside the `.integration-tests` directory. Within this directory, a subdirectory is created for each test file, and within that, a subdirectory is created for each individual test case. This structure makes it easy to locate the artifacts for a specific test run, file, or case. ``` .integration-tests/ └── / └── .test.js/ └── / β”œβ”€β”€ output.log └── ...other test artifacts... ``` ## Continuous integration To ensure the integration tests are always run, a GitHub Actions workflow is defined in `.github/workflows/chained_e2e.yml`. This workflow automatically runs the integrations tests for pull requests against the `main` branch, or when a pull request is added to a merge queue. The workflow runs the tests in different sandboxing environments to ensure Gemini CLI is tested across each: - `sandbox:none`: Runs the tests without any sandboxing. - `sandbox:docker`: Runs the tests in a Docker container. - `sandbox:podman`: Runs the tests in a Podman container. # [Latest stable release: v0.64.0](http://geminicli.com/docs/changelogs/latest.md) Released: October 13, 2026 For most users, our latest stable release is the recommended release. Install the latest stable version with: ``` npm install -g @google/gemini-cli ``` ## Highlights - **Atomic File Operations & State Recovery:** Serialized file tool operations with atomic writes and introduced atomic CLI state persistence with automatic recovery from backup on corruption. - **Chat Recording Optimization:** Implemented append-only delta patching and bounded history windowing in ChatRecordingService to optimize memory and disk efficiency during long-running sessions. - **CLI Input & Reference Resolution:** Added support for resolving `@file:line` references, resolved CPU hangs and quote swallowing on `@` symbols within code blocks, and prevented ghost text wrap hangs. - **Terminal UI & Interaction Stability:** Ensured Ctrl+C emergency aborts reliably reach active cancellation handlers, made selection list confirmation with Enter and Spacebar dependable, preserved scroll positions, and fixed Windows ConPTY IME cursor forwarding. ## What's Changed - refactor(a2a-server): implement V1 to V2 settings migration logic by @jvargassanchez-dot in [#29450](https://github.com/google-gemini/gemini-cli/pull/29450) - fix(acp): bridge PromptResponse.usage and emit usage_update notifications (#29389) by @elberthc-byte in [#29549](https://github.com/google-gemini/gemini-cli/pull/29549) - Changelog for v0.63.0-preview.0 by @gemini-cli-robot in [#29565](https://github.com/google-gemini/gemini-cli/pull/29565) - fix(cli): propagate resolved folder trust state in headless mode (#29031) by @amelidev in [#29528](https://github.com/google-gemini/gemini-cli/pull/29528) - chore(release): bump version to 0.64.0-nightly.20260929.gd75234cae by @gemini-cli-robot in [#29567](https://github.com/google-gemini/gemini-cli/pull/29567) - fix(cli): prevent CPU hang and quote swallowing on @ within code (#29434) by @elberthc-byte in [#29557](https://github.com/google-gemini/gemini-cli/pull/29557) - fix(core): serialize file tool operations and make writes atomic (#29078) by @elberthc-byte in [#29499](https://github.com/google-gemini/gemini-cli/pull/29499) - fix(core): implement append-only delta patching and bounded history windowing in ChatRecordingService by @jvargassanchez-dot in [#29568](https://github.com/google-gemini/gemini-cli/pull/29568) - fix(cli): persist state atomically and recover from backup on corruption by @urielefrenvirtusa in [#29558](https://github.com/google-gemini/gemini-cli/pull/29558) - fix(cli): ensure Ctrl+C emergency abort reaches cancellation handler during active operations by @urielefrenvirtusa in [#29586](https://github.com/google-gemini/gemini-cli/pull/29586) - fix(cli): resolve @file:line references and prevent ghost text wrap hang by @jesussamuel-byte in [#29581](https://github.com/google-gemini/gemini-cli/pull/29581) - fix(ui): ensure Windows ConPTY forwards IME cursor position by @jesussamuel-byte in [#29560](https://github.com/google-gemini/gemini-cli/pull/29560) - fix(cli): retry directory removal on Windows locking errors during extension updates by @jesussamuel-byte in [#29540](https://github.com/google-gemini/gemini-cli/pull/29540) - fix(acp): resolve session by exact id and handle listener cleanup on session failure by @diegogodinezr in [#29580](https://github.com/google-gemini/gemini-cli/pull/29580) - fix(cli): preserve scroll position and partition pending height budget by @luisfelipe-alt in [#29520](https://github.com/google-gemini/gemini-cli/pull/29520) - fix(cli): ensure Enter and Spacebar reliably confirm selection list options by @ugorla-dev in [#29502](https://github.com/google-gemini/gemini-cli/pull/29502) - fix(patch): cherry-pick 2ce1a69 to release/v0.64.0-preview.0-pr-29672 to patch version v0.64.0-preview.0 and create version 0.64.0-preview.1 by @gemini-cli-robot in [#29696](https://github.com/google-gemini/gemini-cli/pull/29696) **Full Changelog**: https://github.com/google-gemini/gemini-cli/compare/v0.63.0...v0.64.0 # [Gemini CLI release notes](http://geminicli.com/docs/changelogs.md) Gemini CLI has three major release channels: nightly, preview, and stable. For most users, we recommend the stable release. On this page, you can find information regarding the current releases and announcements from each release. For the full changelog, refer to [Releases - google-gemini/gemini-cli](https://github.com/google-gemini/gemini-cli/releases) on GitHub. ## Current releases | Release channel | Notes | | :-------------------- | :---------------------------------------------- | | Nightly | Nightly release with the most recent changes. | | [Preview](/docs/changelogs/preview) | Experimental features ready for early feedback. | | [Stable](/docs/changelogs/latest) | Stable, recommended for general use. | ## Announcements: v0.64.0 - 2026-10-13 - **Atomic Operations & State Persistence:** Serialized file tool operations with atomic writes and introduced atomic CLI state persistence with automatic recovery from backup on corruption ([#29499](https://github.com/google-gemini/gemini-cli/pull/29499) by @elberthc-byte, [#29558](https://github.com/google-gemini/gemini-cli/pull/29558) by @urielefrenvirtusa). - **Chat Recording Optimization:** Implemented append-only delta patching and bounded history windowing in ChatRecordingService to optimize memory and disk efficiency during long-running sessions ([#29568](https://github.com/google-gemini/gemini-cli/pull/29568) by @jvargassanchez-dot). - **CLI Interaction & Input Robustness:** Resolved `@file:line` references, prevented CPU hangs on `@` in code blocks, and ensured Ctrl+C emergency aborts reliably reach cancellation handlers ([#29581](https://github.com/google-gemini/gemini-cli/pull/29581) by @jesussamuel-byte, [#29586](https://github.com/google-gemini/gemini-cli/pull/29586) by @urielefrenvirtusa). ## Announcements: v0.63.0 - 2026-10-06 - **Autonomous Plan Execution:** Enabled autonomous plan execution in non-interactive mode to support unattended agent workflows ([#29539](https://github.com/google-gemini/gemini-cli/pull/29539) by @urielefrenvirtusa). - **Core Stability and Memory Lifecycle:** Bounded tool output sizes and optimized memory management in long-running agent loops while preventing infinite authentication loops across headless and supervisor environments ([#29451](https://github.com/google-gemini/gemini-cli/pull/29451) by @diegogodinezr, [#29448](https://github.com/google-gemini/gemini-cli/pull/29448) by @villahernandez-coder). ## Announcements: v0.61.0 - 2026-09-23 - **Core Security Hardening:** Prevented indirect prompt injection vulnerabilities via build file modifications and untrusted flags, while hardening filesystem boundaries and isolating runtime state ([#29250](https://github.com/google-gemini/gemini-cli/pull/29250) by @villahernandez-coder, [#29214](https://github.com/google-gemini/gemini-cli/pull/29214) by @diegogodinezr). - **Agent Loop and Model Stability:** Ensured AgentLoopContext state preservation across spread operations and preserved explicit versioned Flash model IDs ([#29335](https://github.com/google-gemini/gemini-cli/pull/29335) by @diegogodinezr, [#29252](https://github.com/google-gemini/gemini-cli/pull/29252) by @SandyTao520). ## Announcements: v0.60.0 - 2026-09-15 - **Extension & Tool Safety Hardening:** Prompt for user consent on environment changes and sanitize runtime-altering environment variables, while enforcing envelope metadata provenance for untrusted tool outputs ([#28863](https://github.com/google-gemini/gemini-cli/pull/28863) by @amelidev, [#29215](https://github.com/google-gemini/gemini-cli/pull/29215) by @luisfelipe-alt). - **Sandbox Directory Isolation:** Isolated settings and temporary directories inside sandbox containers, including the macOS Seatbelt sandbox ([#29171](https://github.com/google-gemini/gemini-cli/pull/29171), [#29216](https://github.com/google-gemini/gemini-cli/pull/29216) by @jvargassanchez-dot). ## Announcements: v0.59.0 - 2026-09-08 - **MCP OAuth SSRF Mitigation:** Prevented Server-Side Request Forgery (SSRF) during Model Context Protocol (MCP) OAuth metadata discovery and authentication ([#29081](https://github.com/google-gemini/gemini-cli/pull/29081) by @josebalius). - **Fail-Closed Workspace Trust:** Enforced a secure, fail-closed workspace trust policy and filtered available `mcpServers` when operating in restricted mode ([#29099](https://github.com/google-gemini/gemini-cli/pull/29099) by @luisfelipe-alt). ## Announcements: v0.58.0 - 2026-09-01 - **Core Security & Path Handling:** Enforced consistent symlink evaluation in ignore path handling and declared top-level safety checkers in write policy configuration ([#28915](https://github.com/google-gemini/gemini-cli/pull/28915), [#28961](https://github.com/google-gemini/gemini-cli/pull/28961) by @luisfelipe-alt). - **macOS Seatbelt Sandbox:** Isolated Docker and container runtime sockets and binaries to restrict container runtime access in the macOS sandbox ([#28935](https://github.com/google-gemini/gemini-cli/pull/28935) by @josebalius). - **Session & Recovery Optimizations:** Optimized history rollback mechanics, retry nudge prompts, and resolved stale cancellation errors in the Agent-to-Agent server ([#28934](https://github.com/google-gemini/gemini-cli/pull/28934) by @DavidAPierce, [#28940](https://github.com/google-gemini/gemini-cli/pull/28940) by @amelidev). ## Announcements: v0.54.0 - 2026-08-06 - **PR Automation & Antigravity Agent:** Integrated the Antigravity agent runner with dual-locking Firestore concurrency controls to secure the PR generator ([#28434](https://github.com/google-gemini/gemini-cli/pull/28434), [#28432](https://github.com/google-gemini/gemini-cli/pull/28432) by @joneba-google). - **Caretaker Triaging & Security:** Enhanced caretaker triage to post comments prior to auto-closing issues and sanitized issue titles under untrusted context ([#28411](https://github.com/google-gemini/gemini-cli/pull/28411), [#28352](https://github.com/google-gemini/gemini-cli/pull/28352) by @chadd28). - **Security and Session Robustness:** Prevented cleartext credential leakage by enforcing HTTPS, rotated session IDs on model fallbacks, and skipped merged function-response turns in active loops ([#28517](https://github.com/google-gemini/gemini-cli/pull/28517) by @amelidev, [#28565](https://github.com/google-gemini/gemini-cli/pull/28565) by @adamfweidman). ## Announcements: v0.53.0 - 2026-07-28 - **Caretaker Triage Orchestration:** Implemented an LLM triage orchestrator and container build setup ([#28345](https://github.com/google-gemini/gemini-cli/pull/28345) by @chadd28). - **Eval Coverage Reporting:** Introduced a new command for generating evaluation coverage reports ([#28169](https://github.com/google-gemini/gemini-cli/pull/28169) by @ved015). - **Security & Loop Mitigations:** Enforced workspace trust and task isolation in the A2A server, aligned macOS Seatbelt profiles with the deny-default model, and mitigated infinite ReAct/prompt injection loops ([#28470](https://github.com/google-gemini/gemini-cli/pull/28470) by @luisfelipe-alt, [#28424](https://github.com/google-gemini/gemini-cli/pull/28424) by @ompatel-aiml). ## Announcements: v0.52.0 - 2026-07-22 - **Caretaker Triage & Egress Services:** Implemented the core triage worker foundational modules, main worker execution loops, and egress action publishers alongside the octokit GitHub Action handler for egress services ([#28163](https://github.com/google-gemini/gemini-cli/pull/28163), [#28306](https://github.com/google-gemini/gemini-cli/pull/28306) by @chadd28). - **Core Tool Enhancements:** Bypassed LLM correction for JSON and IPYNB files in `write_file` and `replace` tools, and simplified plan mode write policy to support relative paths ([#28223](https://github.com/google-gemini/gemini-cli/pull/28223) by @amelidev, [#28398](https://github.com/google-gemini/gemini-cli/pull/28398) by @DavidAPierce). - **Auth & Privacy Improvements:** Displayed clear error messages when user account has no Code Assist tier, and bumped `google-auth-library` to version 10.9.0 ([#28304](https://github.com/google-gemini/gemini-cli/pull/28304) by @ompatel-aiml, [#28385](https://github.com/google-gemini/gemini-cli/pull/28385) by @jerrylin3321). ## Announcements: v0.50.0 - 2026-07-08 - **Tool Registry Discovery:** Introduced tool registry discovery capabilities to automatically detect and register available tools ([#28113](https://github.com/google-gemini/gemini-cli/pull/28113) by @ved015). - **Release Verification & CI Stability:** Enhanced release verification by ignoring scripts during verification, preventing workspace binary shadowing, and safeguarding against bad NPM releases ([#28116](https://github.com/google-gemini/gemini-cli/pull/28116) by @rmedranollamas, [#28132](https://github.com/google-gemini/gemini-cli/pull/28132) by @galdawave). ## Announcements: v0.45.0 - 2026-06-03 - **Context Simplification:** Completed major architectural work to simplify the `ContextManager`, improving system robustness and performance ([#27345](https://github.com/google-gemini/gemini-cli/pull/27345) by @joshualitt). - **A2A Usage Metadata:** Exposed critical usage metadata in the Agent-to-Agent (A2A) protocol for better resource tracking ([#27288](https://github.com/google-gemini/gemini-cli/pull/27288) by @jvargassanchez-dot). - **Reliability Fixes:** Addressed Termux relaunch loops, PTY resize errors, and forced sequential execution for topic updates ([#27110](https://github.com/google-gemini/gemini-cli/pull/27110) by @saymanq, [#27357](https://github.com/google-gemini/gemini-cli/pull/27357) by @jvargassanchez-dot, [#27461](https://github.com/google-gemini/gemini-cli/pull/27461) by @scidomino). ## Announcements: v0.44.0 - 2026-05-27 - **Unified Auto Mode:** Streamlined the automation experience by merging specialized Auto modes into a single, unified mode ([#26714](https://github.com/google-gemini/gemini-cli/pull/26714) by @DavidAPierce). - **New Editor Integrations:** Added native support for Sublime Text and Emacs Client ([#21090](https://github.com/google-gemini/gemini-cli/pull/21090) by @alberti42). - **Enhanced TUI Testing:** Introduced `agent-tui` and `tui-tester` skills for programmatic testing and automation of terminal UI applications ([#27121](https://github.com/google-gemini/gemini-cli/pull/27121) by @adamfweidman). ## Announcements: v0.43.0 - 2026-05-22 - **Surgical Code Edits:** Steered Gemini models to prefer the `edit` tool for surgical modifications, improving speed and precision ([#26480](https://github.com/google-gemini/gemini-cli/pull/26480) by @aishaneeshah). - **Session Export and Import:** Added the ability to export sessions to files and import them via a new flag, facilitating session portability ([#26514](https://github.com/google-gemini/gemini-cli/pull/26514) by @cocosheng-g). - **Adaptive Token Estimation:** Introduced an adaptive token calculator for more accurate content size estimation, enhancing context management efficiency ([#26888](https://github.com/google-gemini/gemini-cli/pull/26888) by @joshualitt). ## Announcements: v0.42.0 - 2026-05-12 - **Auto Memory Inbox:** Introduced a new inbox flow for Auto Memory with a canonical-patch contract for seamless skill management ([#26338](https://github.com/google-gemini/gemini-cli/pull/26338) by @SandyTao520). - **Gemma 4 by Default:** Enabled Gemma 4 models by default via the Gemini API for all users ([#26307](https://github.com/google-gemini/gemini-cli/pull/26307) by @Abhijit-2592). - **Voice Mode Enhancements:** Added wave animations and privacy/compliance UX warnings for the Gemini Live backend ([#26284](https://github.com/google-gemini/gemini-cli/pull/26284) by @devr0306, [#26454](https://github.com/google-gemini/gemini-cli/pull/26454) by @cocosheng-g). ## Announcements: v0.41.0 - 2026-05-05 - **Real-time Voice Mode:** Implemented real-time voice mode with cloud and local backends ([#24174](https://github.com/google-gemini/gemini-cli/pull/24174) by @Abhijit-2592). - **Secure Environment Loading:** Enforced workspace trust and secured .env loading in headless mode ([#25814](https://github.com/google-gemini/gemini-cli/pull/25814) by @ehedlund). - **Advanced Shell Validation:** Enhanced shell command validation and added core tools allowlist for improved security ([#25720](https://github.com/google-gemini/gemini-cli/pull/25720) by @galz10). ## Announcements: v0.40.0 - 2026-04-28 - **Offline Search and Themes:** Bundled ripgrep for offline search support and added GitHub-style colorblind themes ([#25342](https://github.com/google-gemini/gemini-cli/pull/25342) by @scidomino, [#15504](https://github.com/google-gemini/gemini-cli/pull/15504) by @Z1xus). - **Advanced Resource and Memory Management:** Introduced MCP resource tools and transitioned to a prompt-driven, four-tier memory management system ([#25395](https://github.com/google-gemini/gemini-cli/pull/25395) by @ruomengz, [#25716](https://github.com/google-gemini/gemini-cli/pull/25716) by @SandyTao520). - **UX and Local Models:** Enabled topic update narrations by default and streamlined Gemma local model setup with `gemini gemma` ([#25586](https://github.com/google-gemini/gemini-cli/pull/25586) by @gundermanc, [#25498](https://github.com/google-gemini/gemini-cli/pull/25498) by @Samee24). ## Announcements: v0.39.0 - 2026-04-23 - **Skill Management:** Added a new `/memory` inbox command for reviewing and patching skills extracted during sessions ([#24544](https://github.com/google-gemini/gemini-cli/pull/24544) by @SandyTao520, [#25148](https://github.com/google-gemini/gemini-cli/pull/25148) by @SandyTao520). - **Improved Transparency:** Plan Mode now requires confirmation for skill activation and allows plan inspection ([#24946](https://github.com/google-gemini/gemini-cli/pull/24946), [#25058](https://github.com/google-gemini/gemini-cli/pull/25058) by @ruomengz). - **Architecture & Reliability:** Introduced a decoupled `ContextManager` architecture and resolved several critical memory leaks and PTY exhaustion issues ([#24752](https://github.com/google-gemini/gemini-cli/pull/24752) by @joshualitt, [#25079](https://github.com/google-gemini/gemini-cli/pull/25079) by @spencer426). ## Announcements: v0.38.0 - 2026-04-14 - **Chapters Narrative Flow:** Group agent interactions into "Chapters" based on intent and tool usage for better session structure ([#23150](https://github.com/google-gemini/gemini-cli/pull/23150) by @Abhijit-2592, [#24079](https://github.com/google-gemini/gemini-cli/pull/24079) by @gundermanc). - **Context Compression Service:** Advanced context management to efficiently distill conversation history ([#24483](https://github.com/google-gemini/gemini-cli/pull/24483) by @joshualitt). - **UI Flicker & UX Enhancements:** Solved rendering flicker with "Terminal Buffer" mode and introduced selective topic expansion ([#24512](https://github.com/google-gemini/gemini-cli/pull/24512) by @jacob314, [#24793](https://github.com/google-gemini/gemini-cli/pull/24793) by @Abhijit-2592). - **Persistent Policy Approvals:** Implemented context-aware persistent approvals for tool execution ([#23257](https://github.com/google-gemini/gemini-cli/pull/23257) by @jerop). ## Announcements: v0.37.0 - 2026-04-08 - **Dynamic Sandbox Expansion:** Implemented dynamic sandbox expansion and worktree support for Linux and Windows, improving developer workflows in isolated environments ([#23692](https://github.com/google-gemini/gemini-cli/pull/23692) by @galz10, [#23691](https://github.com/google-gemini/gemini-cli/pull/23691) by @scidomino). - **Chapters Narrative Flow:** Introduced tool-based topic grouping ("Chapters") to provide better session structure and narrative continuity ([#23150](https://github.com/google-gemini/gemini-cli/pull/23150) by @Abhijit-2592, [#24079](https://github.com/google-gemini/gemini-cli/pull/24079) by @gundermanc). - **Advanced Browser Capabilities:** Enhanced the browser agent with persistent sessions and dynamic tool discovery ([#21306](https://github.com/google-gemini/gemini-cli/pull/21306) by @kunal-10-cloud, [#23805](https://github.com/google-gemini/gemini-cli/pull/23805) by @cynthialong0-0). ## Announcements: v0.36.0 - 2026-04-01 - **Multi-Registry Architecture and Sandboxing:** Introduced a multi-registry architecture and implemented native macOS Seatbelt and Windows sandboxing for enhanced subagent security ([#22712](https://github.com/google-gemini/gemini-cli/pull/22712), [#22718](https://github.com/google-gemini/gemini-cli/pull/22718) by @akh64bit, [#22832](https://github.com/google-gemini/gemini-cli/pull/22832) by @ehedlund, [#21807](https://github.com/google-gemini/gemini-cli/pull/21807) by @mattKorwel). - **Refreshed Composer UX:** Implemented a refreshed user experience for the Composer layout and improved terminal interaction robustness ([#21212](https://github.com/google-gemini/gemini-cli/pull/21212), [#23286](https://github.com/google-gemini/gemini-cli/pull/23286) by @jwhelangoog). - **Git Worktree Support:** Added native support for Git worktrees, allowing for isolated parallel sessions ([#22973](https://github.com/google-gemini/gemini-cli/pull/22973), [#23265](https://github.com/google-gemini/gemini-cli/pull/23265) by @jerop). - **Subagent Context and Feedback:** Enhanced subagents with JIT context injection and resilient tool rejection with contextual feedback ([#23032](https://github.com/google-gemini/gemini-cli/pull/23032), [#22951](https://github.com/google-gemini/gemini-cli/pull/22951) by @abhipatel12). ## 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 you break down complex tasks and execute them systematically ([#21713](https://github.com/google-gemini/gemini-cli/pull/21713) by @jerop). - **Sandboxing Enhancements:** We've added native gVisor (runsc) and experimental LXC container sandboxing support for safer execution environments ([#21062](https://github.com/google-gemini/gemini-cli/pull/21062) by @Zheyuan-Lin, [#20735](https://github.com/google-gemini/gemini-cli/pull/20735) by @h30s). ## Announcements: v0.33.0 - 2026-03-11 - **Agent Architecture Enhancements:** Introduced HTTP authentication for A2A remote agents and authenticated A2A agent card discovery ([#20510](https://github.com/google-gemini/gemini-cli/pull/20510) by @SandyTao520, [#20622](https://github.com/google-gemini/gemini-cli/pull/20622) by @SandyTao520). - **Plan Mode Updates:** Expanded Plan Mode with built-in research subagents, annotation support for feedback, and a new `copy` subcommand ([#20972](https://github.com/google-gemini/gemini-cli/pull/20972) by @Adib234, [#20988](https://github.com/google-gemini/gemini-cli/pull/20988) by @ruomengz). - **CLI UX & Admin Controls:** Redesigned the header to be compact with an ASCII icon, inverted context window display to show usage, and enabled a 30-day default retention for chat history ([#18713](https://github.com/google-gemini/gemini-cli/pull/18713) by @keithguerin, [#20853](https://github.com/google-gemini/gemini-cli/pull/20853) by @skeshive). ## Announcements: v0.32.0 - 2026-03-03 - **Generalist Agent:** The generalist agent is now enabled to improve task delegation and routing ([#19665](https://github.com/google-gemini/gemini-cli/pull/19665) by @joshualitt). - **Model Steering in Workspace:** Added support for model steering directly in the workspace ([#20343](https://github.com/google-gemini/gemini-cli/pull/20343) by @joshualitt). - **Plan Mode Enhancements:** Users can now open and modify plans in an external editor, and the planning workflow has been adapted to handle complex tasks more effectively with multi-select options ([#20348](https://github.com/google-gemini/gemini-cli/pull/20348) by @Adib234, [#20465](https://github.com/google-gemini/gemini-cli/pull/20465) by @jerop). - **Interactive Shell Autocompletion:** Introduced interactive shell autocompletion for a more seamless experience ([#20082](https://github.com/google-gemini/gemini-cli/pull/20082) by @mrpmohiburrahman). - **Parallel Extension Loading:** Extensions are now loaded in parallel to improve startup times ([#20229](https://github.com/google-gemini/gemini-cli/pull/20229) by @scidomino). ## Announcements: v0.31.0 - 2026-02-27 - **Gemini 3.1 Pro Preview:** Gemini CLI now supports the new Gemini 3.1 Pro Preview model ([#19676](https://github.com/google-gemini/gemini-cli/pull/19676) by @sehoon38). - **Experimental Browser Agent:** We've introduced a new experimental browser agent to interact with web pages ([#19284](https://github.com/google-gemini/gemini-cli/pull/19284) by @gsquared94). - **Policy Engine Updates:** The policy engine now supports project-level policies, MCP server wildcards, and tool annotation matching ([#18682](https://github.com/google-gemini/gemini-cli/pull/18682) by @Abhijit-2592, [#20024](https://github.com/google-gemini/gemini-cli/pull/20024) by @jerop). - **Web Fetch Improvements:** We've implemented an experimental direct web fetch feature and added rate limiting to mitigate DDoS risks ([#19557](https://github.com/google-gemini/gemini-cli/pull/19557) by @mbleigh, [#19567](https://github.com/google-gemini/gemini-cli/pull/19567) by @mattKorwel). ## Announcements: v0.30.0 - 2026-02-25 - **SDK & Custom Skills:** Introduced the initial SDK package, enabling dynamic system instructions, `SessionContext` for SDK tool calls, and support for custom skills ([#18861](https://github.com/google-gemini/gemini-cli/pull/18861) by @mbleigh). - **Policy Engine Enhancements:** Added a new `--policy` flag for user-defined policies, introduced strict seatbelt profiles, and deprecated `--allowed-tools` in favor of the policy engine ([#18500](https://github.com/google-gemini/gemini-cli/pull/18500) by @allenhutchison). - **UI & Themes:** Added a generic searchable list for settings and extensions, new Solarized themes, text wrapping for markdown tables, and a clean UI toggle prototype ([#19064](https://github.com/google-gemini/gemini-cli/pull/19064) by @rmedranollamas). - **Vim & Terminal Interaction:** Improved Vim support to feel more complete and added support for Ctrl-Z terminal suspension ([#18755](https://github.com/google-gemini/gemini-cli/pull/18755) by @ppgranger, [#18931](https://github.com/google-gemini/gemini-cli/pull/18931) by @scidomino). ## Announcements: v0.29.0 - 2026-02-17 - **Plan Mode:** A new comprehensive planning capability with `/plan`, `enter_plan_mode` tool, and dedicated documentation ([#17698](https://github.com/google-gemini/gemini-cli/pull/17698) by @Adib234, [#18324](https://github.com/google-gemini/gemini-cli/pull/18324) by @jerop). - **Gemini 3 Default:** We've removed the preview flag and enabled Gemini 3 by default for all users ([#18414](https://github.com/google-gemini/gemini-cli/pull/18414) by @sehoon38). - **Extension Exploration:** New UI and settings to explore and manage extensions more easily ([#18686](https://github.com/google-gemini/gemini-cli/pull/18686) by @sripasg). - **Admin Control:** Administrators can now allowlist specific MCP server configurations ([#18311](https://github.com/google-gemini/gemini-cli/pull/18311) by @skeshive). ## Announcements: v0.28.0 - 2026-02-10 - **IDE Support:** Gemini CLI now supports the Positron IDE ([#15047](https://github.com/google-gemini/gemini-cli/pull/15047) by @kapsner). - **Customization:** You can now use custom themes in extensions, and we've implemented automatic theme switching based on your terminal's background ([#17327](https://github.com/google-gemini/gemini-cli/pull/17327) by @spencer426, [#17976](https://github.com/google-gemini/gemini-cli/pull/17976) by @Abhijit-2592). - **Authentication:** We've added interactive and non-interactive consent for OAuth, and you can now include your auth method in bug reports ([#17699](https://github.com/google-gemini/gemini-cli/pull/17699) by @ehedlund, [#17569](https://github.com/google-gemini/gemini-cli/pull/17569) by @erikus). ## Announcements: v0.27.0 - 2026-02-03 - **Event-Driven Architecture:** The CLI now uses a new event-driven scheduler for tool execution, resulting in a more responsive and performant experience ([#17078](https://github.com/google-gemini/gemini-cli/pull/17078) by @abhipatel12). - **Enhanced User Experience:** This release includes queued tool confirmations, and expandable large text pastes for a smoother workflow. - **New `/rewind` Command:** Easily navigate your session history with the new `/rewind` command ([#15720](https://github.com/google-gemini/gemini-cli/pull/15720) by @Adib234). - **Linux Clipboard Support:** You can now paste images on Linux with Wayland and X11 ([#17144](https://github.com/google-gemini/gemini-cli/pull/17144) by @devr0306). ## Announcements: v0.26.0 - 2026-01-27 - **Agents and Skills:** We've introduced a new `skill-creator` skill ([#16394](https://github.com/google-gemini/gemini-cli/pull/16394) by @NTaylorMullen), enabled agent skills by default, and added a generalist agent to improve task routing ([#16638](https://github.com/google-gemini/gemini-cli/pull/16638) by @joshualitt). - **UI/UX Improvements:** You can now "Rewind" through your conversation history ([#15717](https://github.com/google-gemini/gemini-cli/pull/15717) by @Adib234). - **Core and Scheduler Refactoring:** The core scheduler has been significantly refactored to improve performance and reliability ([#16895](https://github.com/google-gemini/gemini-cli/pull/16895) by @abhipatel12), and numerous performance and stability fixes have been included. ## Announcements: v0.25.0 - 2026-01-20 - **Skills and Agents Improvements:** We've enhanced the `activate_skill` tool, added a new `pr-creator` skill ([#16232](https://github.com/google-gemini/gemini-cli/pull/16232) by [@NTaylorMullen](https://github.com/NTaylorMullen)), enabled skills by default, improved the `cli_help` agent ([#16100](https://github.com/google-gemini/gemini-cli/pull/16100) by [@scidomino](https://github.com/scidomino)), and added a new `/agents refresh` command ([#16204](https://github.com/google-gemini/gemini-cli/pull/16204) by [@joshualitt](https://github.com/joshualitt)). - **UI/UX Refinements:** You'll notice more transparent feedback for skills ([#15954](https://github.com/google-gemini/gemini-cli/pull/15954) by [@NTaylorMullen](https://github.com/NTaylorMullen)), the ability to switch focus between the shell and input with Tab ([#14332](https://github.com/google-gemini/gemini-cli/pull/14332) by [@jacob314](https://github.com/jacob314)), and dynamic terminal tab titles ([#16378](https://github.com/google-gemini/gemini-cli/pull/16378) by [@NTaylorMullen](https://github.com/NTaylorMullen)). - **Core Functionality & Performance:** This release includes support for built-in agent skills ([#16045](https://github.com/google-gemini/gemini-cli/pull/16045) by [@NTaylorMullen](https://github.com/NTaylorMullen)), refined Gemini 3 system instructions ([#16139](https://github.com/google-gemini/gemini-cli/pull/16139) by [@NTaylorMullen](https://github.com/NTaylorMullen)), caching for ignore instances to improve performance ([#16185](https://github.com/google-gemini/gemini-cli/pull/16185) by [@EricRahm](https://github.com/EricRahm)), and enhanced retry mechanisms ([#16489](https://github.com/google-gemini/gemini-cli/pull/16489) by [@sehoon38](https://github.com/sehoon38)). - **Bug Fixes and Stability:** We've squashed numerous bugs across the CLI, core, and workflows, addressing issues with subagent delegation, unicode character crashes, and sticky header regressions. ## Announcements: v0.24.0 - 2026-01-14 - **Agent Skills:** We've introduced significant advancements in Agent Skills. This includes initial documentation and tutorials to help you get started, alongside enhanced support for remote agents, allowing for more distributed and powerful automation within Gemini CLI. ([#15869](https://github.com/google-gemini/gemini-cli/pull/15869) by [@NTaylorMullen](https://github.com/NTaylorMullen)), ([#16013](https://github.com/google-gemini/gemini-cli/pull/16013) by [@adamweidman](https://github.com/adamweidman)) - **Improved UI/UX:** The user interface has received several updates, featuring visual indicators for hook execution, a more refined display for settings, and the ability to use the Tab key to effortlessly switch focus between the shell and input areas. ([#15408](https://github.com/google-gemini/gemini-cli/pull/15408) by [@abhipatel12](https://github.com/abhipatel12)), ([#14332](https://github.com/google-gemini/gemini-cli/pull/14332) by [@galz10](https://github.com/galz10)) - **Enhanced Security:** Security has been a major focus, with default folder trust now set to untrusted for increased safety. The Policy Engine has been improved to allow specific modes in user and administrator policies, and granular allowlisting for shell commands has been implemented, providing finer control over tool execution. ([#15943](https://github.com/google-gemini/gemini-cli/pull/15943) by [@galz10](https://github.com/galz10)), ([#15977](https://github.com/google-gemini/gemini-cli/pull/15977) by [@NTaylorMullen](https://github.com/NTaylorMullen)) - **Core Functionality:** This release includes a mandatory MessageBus injection, marking Phase 3 of a hard migration to a more robust internal communication system. We've also added support for built-in skills with the CLI itself, and enhanced model routing to effectively utilize subagents. ([#15776](https://github.com/google-gemini/gemini-cli/pull/15776) by [@abhipatel12](https://github.com/abhipatel12)), ([#16300](https://github.com/google-gemini/gemini-cli/pull/16300) by [@NTaylorMullen](https://github.com/NTaylorMullen)) - **Terminal Features:** Terminal interactions are more seamless with new features like OSC 52 paste support, along with fixes for Windows clipboard paste issues and general improvements to pasting in Windows terminals. ([#15336](https://github.com/google-gemini/gemini-cli/pull/15336) by [@scidomino](https://github.com/scidomino)), ([#15932](https://github.com/google-gemini/gemini-cli/pull/15932) by [@scidomino](https://github.com/scidomino)) - **New Commands:** To manage the new features, we've added several new commands: `/agents refresh` to update agent configurations, `/skills reload` to refresh skill definitions, and `/skills install/uninstall` for easier management of your Agent Skills. ([#16204](https://github.com/google-gemini/gemini-cli/pull/16204) by [@NTaylorMullen](https://github.com/NTaylorMullen)), ([#15865](https://github.com/google-gemini/gemini-cli/pull/15865) by [@NTaylorMullen](https://github.com/NTaylorMullen)), ([#16377](https://github.com/google-gemini/gemini-cli/pull/16377) by [@NTaylorMullen](https://github.com/NTaylorMullen)) ## Announcements: v0.23.0 - 2026-01-07 - πŸŽ‰ **Experimental Agent Skills Support in Preview:** Gemini CLI now supports [Agent Skills](https://agentskills.io/home) in our preview builds. This is an early preview where we’re looking for feedback! - Install Preview: `npm install -g @google/gemini-cli@preview` - Enable in `/settings` - Docs: [https://geminicli.com/docs/cli/skills/](https://geminicli.com/docs/cli/skills/) - **Gemini CLI wrapped:** Run `npx gemini-wrapped` to visualize your usage stats, top models, languages, and more! - **Windows clipboard image support:** Windows users can now paste images directly from their clipboard into the CLI using `Alt`+`V`. ([pr](https://github.com/google-gemini/gemini-cli/pull/13997) by [@sgeraldes](https://github.com/sgeraldes)) - **Terminal background color detection:** Automatically optimizes your terminal's background color to select compatible themes and provide accessibility warnings. ([pr](https://github.com/google-gemini/gemini-cli/pull/15132) by [@jacob314](https://github.com/jacob314)) - **Session logout:** Use the new `/logout` command to instantly clear credentials and reset your authentication state for seamless account switching. ([pr](https://github.com/google-gemini/gemini-cli/pull/13383) by [@CN-Scars](https://github.com/CN-Scars)) ## Announcements: v0.22.0 - 2025-12-22 - πŸŽ‰**Free Tier + Gemini 3:** Free tier users now all have access to Gemini 3 Pro & Flash. Enable in `/settings` by toggling "Preview Features" to `true`. - πŸŽ‰**Gemini CLI + Colab:** Gemini CLI is now pre-installed. Can be used headlessly in notebook cells or interactively in the built-in terminal ([pic](https://imgur.com/a/G0Tn7vi)) - πŸŽ‰**Gemini CLI Extensions:** - **Conductor:** Planning++, Gemini works with you to build out a detailed plan, pull in extra details as needed, ultimately to give the LLM guardrails with artifacts. Measure twice, implement once! `gemini extensions install https://github.com/gemini-cli-extensions/conductor` Blog: [https://developers.googleblog.com/conductor-introducing-context-driven-development-for-gemini-cli/](https://developers.googleblog.com/conductor-introducing-context-driven-development-for-gemini-cli/) - **Endor Labs:** Perform code analysis, vulnerability scanning, and dependency checks using natural language. `gemini extensions install https://github.com/endorlabs/gemini-extension` ## Announcements: v0.21.0 - 2025-12-15 - **⚑️⚑️⚑️ Gemini 3 Flash + Gemini CLI:** Better, faster and cheaper than 2.5 Pro - and in some scenarios better than 3 Pro! For paid tiers + free tier users who were on the wait list enable **Preview Features** in `/settings.` - For more information: [Gemini 3 Flash is now available in Gemini CLI](https://developers.googleblog.com/gemini-3-flash-is-now-available-in-gemini-cli/). - πŸŽ‰ Gemini CLI Extensions: - Rill: Utilize natural language to analyze Rill data, enabling the exploration of metrics and trends without the need for manual queries. `gemini extensions install https://github.com/rilldata/rill-gemini-extension` - Browserbase: Interact with web pages, take screenshots, extract information, and perform automated actions with atomic precision. `gemini extensions install https://github.com/browserbase/mcp-server-browserbase` - Quota Visibility: The `/stats` command now displays quota information for all available models, including those not used in the current session. (@sehoon38) - Fuzzy Setting Search: Users can now quickly find settings using fuzzy search within the settings dialog. (@sehoon38) - MCP Resource Support: Users can now discover, view, and search through resources using the @ command. (@MrLesk) - Auto-execute Simple Slash Commands: Simple slash commands are now executed immediately on enter. (@jackwotherspoon) ## Announcements: v0.20.0 - 2025-12-01 - **Multi-file Drag & Drop:** Users can now drag and drop multiple files into the terminal, and the CLI will automatically prefix each valid path with `@`. ([pr](https://github.com/google-gemini/gemini-cli/pull/14832) by [@jackwotherspoon](https://github.com/jackwotherspoon)) - **Persistent "Always Allow" Policies:** Users can now save "Always Allow" decisions for tool executions, with granular control over specific shell commands and multi-cloud platform tools. ([pr](https://github.com/google-gemini/gemini-cli/pull/14737) by [@allenhutchison](https://github.com/allenhutchison)) ## Announcements: v0.19.0 - 2025-11-24 - πŸŽ‰ **New extensions:** - **Eleven Labs:** Create, play, manage your audio play tracks with the Eleven Labs Gemini CLI extension: `gemini extensions install https://github.com/elevenlabs/elevenlabs-mcp` - **Zed integration:** Users can now leverage Gemini 3 within the Zed integration after enabling "Preview Features" in their CLI’s `/settings`. ([pr](https://github.com/google-gemini/gemini-cli/pull/13398) by [@benbrandt](https://github.com/benbrandt)) - **Interactive shell:** - **Click-to-Focus:** When "Use Alternate Buffer" setting is enabled, users can click within the embedded shell output to focus it for input. ([pr](https://github.com/google-gemini/gemini-cli/pull/13341) by [@galz10](https://github.com/galz10)) - **Loading phrase:** Clearly indicates when the interactive shell is awaiting user input. ([vid](https://imgur.com/a/kjK8bUK), [pr](https://github.com/google-gemini/gemini-cli/pull/12535) by [@jackwotherspoon](https://github.com/jackwotherspoon)) ## Announcements: v0.18.0 - 2025-11-17 - πŸŽ‰ **New extensions:** - **Google Workspace**: Integrate Gemini CLI with your Workspace data. Write docs, build slides, chat with others or even get your calc on in sheets: `gemini extensions install https://github.com/gemini-cli-extensions/workspace` - Blog: [https://allen.hutchison.org/2025/11/19/bringing-the-office-to-the-terminal/](https://allen.hutchison.org/2025/11/19/bringing-the-office-to-the-terminal/) - **Redis:** Manage and search data in Redis with natural language: `gemini extensions install https://github.com/redis/mcp-redis` - **Anomalo:** Query your data warehouse table metadata and quality status through commands and natural language: `gemini extensions install https://github.com/datagravity-ai/anomalo-gemini-extension` - **Experimental permission improvements:** We are now experimenting with a new policy engine in Gemini CLI. This allows users and administrators to create fine-grained policy for tool calls. Currently behind a flag. See [policy engine documentation](/docs/reference/policy-engine) for more information. - Blog: [https://allen.hutchison.org/2025/11/26/the-guardrails-of-autonomy/](https://allen.hutchison.org/2025/11/26/the-guardrails-of-autonomy/) - **Gemini 3 support for paid:** Gemini 3 support has been rolled out to all API key, Google AI Pro or Google AI Ultra (for individuals, not businesses) and Gemini Code Assist Enterprise users. Enable it via `/settings` and toggling on **Preview Features**. - **Updated UI rollback:** We’ve temporarily rolled back our updated UI to give it more time to bake. This means for a time you won’t have embedded scrolling or mouse support. You can re-enable with `/settings` -> **Use Alternate Screen Buffer** -> `true`. - **Model in history:** Users can now toggle in `/settings` to display model in their chat history. ([gif](https://imgur.com/a/uEmNKnQ), [pr](https://github.com/google-gemini/gemini-cli/pull/13034) by [@scidomino](https://github.com/scidomino)) - **Multi-uninstall:** Users can now uninstall multiple extensions with a single command. ([pic](https://imgur.com/a/9Dtq8u2), [pr](https://github.com/google-gemini/gemini-cli/pull/13016) by [@JayadityaGit](https://github.com/JayadityaGit)) ## Announcements: v0.16.0 - 2025-11-10 - **Gemini 3 + Gemini CLI:** launch πŸš€πŸš€πŸš€ - **Data Commons Gemini CLI Extension** - A new Data Commons Gemini CLI extension that lets you query open-source statistical data from datacommons.org. **To get started, you'll need a Data Commons API key and uv installed**. These and other details to get you started with the extension can be found at [https://github.com/gemini-cli-extensions/datacommons](https://github.com/gemini-cli-extensions/datacommons). ## Announcements: v0.15.0 - 2025-11-03 - **πŸŽ‰ Seamless scrollable UI and mouse support:** We’ve given Gemini CLI a major facelift to make your terminal experience smoother and much more polished. You now get a flicker-free display with sticky headers that keep important context visible and a stable input prompt that doesn't jump around. We even added mouse support so you can click right where you need to type! ([gif](https://imgur.com/a/O6qc7bx), [@jacob314](https://github.com/jacob314)). - **Announcement:** [https://developers.googleblog.com/en/making-the-terminal-beautiful-one-pixel-at-a-time/](https://developers.googleblog.com/en/making-the-terminal-beautiful-one-pixel-at-a-time/) - **πŸŽ‰ New partner extensions:** - **Arize:** Seamlessly instrument AI applications with Arize AX and grant direct access to Arize support: `gemini extensions install https://github.com/Arize-ai/arize-tracing-assistant` - **Chronosphere:** Retrieve logs, metrics, traces, events, and specific entities: `gemini extensions install https://github.com/chronosphereio/chronosphere-mcp` - **Transmit:** Comprehensive context, validation, and automated fixes for creating production-ready authentication and identity workflows: `gemini extensions install https://github.com/TransmitSecurity/transmit-security-journey-builder` - **Todo planning:** Complex questions now get broken down into todo lists that the model can manage and check off. ([gif](https://imgur.com/a/EGDfNlZ), [pr](https://github.com/google-gemini/gemini-cli/pull/12905) by [@anj-s](https://github.com/anj-s)) - **Disable GitHub extensions:** Users can now prevent the installation and loading of extensions from GitHub. ([pr](https://github.com/google-gemini/gemini-cli/pull/12838) by [@kevinjwang1](https://github.com/kevinjwang1)). - **Extensions restart:** Users can now explicitly restart extensions using the `/extensions restart` command. ([pr](https://github.com/google-gemini/gemini-cli/pull/12739) by [@jakemac53](https://github.com/jakemac53)). - **Better Angular support:** Angular workflows should now be more seamless ([pr](https://github.com/google-gemini/gemini-cli/pull/10252) by [@MarkTechson](https://github.com/MarkTechson)). - **Validate command:** Users can now check that local extensions are formatted correctly. ([pr](https://github.com/google-gemini/gemini-cli/pull/12186) by [@kevinjwang1](https://github.com/kevinjwang1)). ## Announcements: v0.12.0 - 2025-10-27 ![Codebase investigator subagent in Gemini CLI.](https://i.imgur.com/4J1njsx.png) - **πŸŽ‰ New partner extensions:** - **πŸ€— Hugging Face extension:** Access the Hugging Face hub. ([gif](https://drive.google.com/file/d/1LEzIuSH6_igFXq96_tWev11svBNyPJEB/view?usp=sharing&resourcekey=0-LtPTzR1woh-rxGtfPzjjfg)) `gemini extensions install https://github.com/huggingface/hf-mcp-server` - **Monday.com extension**: Analyze your sprints, update your task boards, etc. ([gif](https://drive.google.com/file/d/1cO0g6kY1odiBIrZTaqu5ZakaGZaZgpQv/view?usp=sharing&resourcekey=0-xEr67SIjXmAXRe1PKy7Jlw)) `gemini extensions install https://github.com/mondaycom/mcp` - **Data Commons extension:** Query public datasets or ground responses on data from Data Commons ([gif](https://drive.google.com/file/d/1cuj-B-vmUkeJnoBXrO_Y1CuqphYc6p-O/view?usp=sharing&resourcekey=0-0adXCXDQEd91ZZW63HbW-Q)). `gemini extensions install https://github.com/gemini-cli-extensions/datacommons` - **Model selection:** Choose the Gemini model for your session with `/model`. ([pic](https://imgur.com/a/ABFcWWw), [pr](https://github.com/google-gemini/gemini-cli/pull/8940) by [@abhipatel12](https://github.com/abhipatel12)). - **Model routing:** Gemini CLI will now intelligently pick the best model for the task. Simple queries will be sent to Flash while complex analytical or creative tasks will still use the power of Pro. This ensures your quota will last for a longer period of time. You can always opt-out of this via `/model`. ([pr](https://github.com/google-gemini/gemini-cli/pull/9262) by [@abhipatel12](https://github.com/abhipatel12)). - Discussion: [https://github.com/google-gemini/gemini-cli/discussions/12375](https://github.com/google-gemini/gemini-cli/discussions/12375) - **Codebase investigator subagent:** We now have a new built-in subagent that will explore your workspace and resolve relevant information to improve overall performance. ([pr](https://github.com/google-gemini/gemini-cli/pull/9988) by [@abhipatel12](https://github.com/abhipatel12), [pr](https://github.com/google-gemini/gemini-cli/pull/10282) by [@silviojr](https://github.com/silviojr)). - Enable, disable, or limit turns in `/settings`, plus advanced configs in `settings.json` ([pic](https://imgur.com/a/yJiggNO), [pr](https://github.com/google-gemini/gemini-cli/pull/10844) by [@silviojr](https://github.com/silviojr)). - **Explore extensions with `/extension`:** Users can now open the extensions page in their default browser directly from the CLI using the `/extension` explore command. ([pr](https://github.com/google-gemini/gemini-cli/pull/11846) by [@JayadityaGit](https://github.com/JayadityaGit)). - **Configurable compression:** Users can modify the context compression threshold in `/settings` (decimal with percentage display). The default has been made more proactive ([pr](https://github.com/google-gemini/gemini-cli/pull/12317) by [@scidomino](https://github.com/scidomino)). - **API key authentication:** Users can now securely enter and store their Gemini API key via a new dialog, eliminating the need for environment variables and repeated entry. ([pr](https://github.com/google-gemini/gemini-cli/pull/11760) by [@galz10](https://github.com/galz10)). - **Sequential approval:** Users can now approve multiple tool calls sequentially during execution. ([pr](https://github.com/google-gemini/gemini-cli/pull/11593) by [@joshualitt](https://github.com/joshualitt)). ## Announcements: v0.11.0 - 2025-10-20 ![Gemini CLI and Jules](https://storage.googleapis.com/gweb-developer-goog-blog-assets/images/Jules_Extension_-_Blog_Header_O346JNt.original.png) - πŸŽ‰ **Gemini CLI Jules Extension:** Use Gemini CLI to orchestrate Jules. Spawn remote workers, delegate tedious tasks, or check in on running jobs! - Install: `gemini extensions install https://github.com/gemini-cli-extensions/jules` - Announcement: [https://developers.googleblog.com/en/introducing-the-jules-extension-for-gemini-cli/](https://developers.googleblog.com/en/introducing-the-jules-extension-for-gemini-cli/) - **Stream JSON output:** Stream real-time JSONL events with `--output-format stream-json` to monitor AI agent progress when run headlessly. ([gif](https://imgur.com/a/0UCE81X), [pr](https://github.com/google-gemini/gemini-cli/pull/10883) by [@anj-s](https://github.com/anj-s)) - **Markdown toggle:** Users can now switch between rendered and raw markdown display using `alt+m `or` ctrl+m`. ([gif](https://imgur.com/a/lDNdLqr), [pr](https://github.com/google-gemini/gemini-cli/pull/10383) by [@srivatsj](https://github.com/srivatsj)) - **Queued message editing:** Users can now quickly edit queued messages by pressing the up arrow key when the input is empty. ([gif](https://imgur.com/a/ioRslLd), [pr](https://github.com/google-gemini/gemini-cli/pull/10392) by [@akhil29](https://github.com/akhil29)) - **JSON web fetch**: Non-HTML content like JSON APIs or raw source code are now properly shown to the model (previously only supported HTML) ([gif](https://imgur.com/a/Q58U4qJ), [pr](https://github.com/google-gemini/gemini-cli/pull/11284) by [@abhipatel12](https://github.com/abhipatel12)) - **Non-interactive MCP commands:** Users can now run MCP slash commands in non-interactive mode `gemini "/some-mcp-prompt"`. ([pr](https://github.com/google-gemini/gemini-cli/pull/10194) by [@capachino](https://github.com/capachino)) - **Removal of deprecated flags:** We’ve finally removed a number of deprecated flags to cleanup Gemini CLI’s invocation profile: - `--all-files` / `-a` in favor of `@` from within Gemini CLI. ([pr](https://github.com/google-gemini/gemini-cli/pull/11228) by [@allenhutchison](https://github.com/allenhutchison)) - `--telemetry-*` flags in favor of [environment variables](https://github.com/google-gemini/gemini-cli/pull/11318) ([pr](https://github.com/google-gemini/gemini-cli/pull/11318) by [@allenhutchison](https://github.com/allenhutchison)) ## Announcements: v0.10.0 - 2025-10-13 - **Polish:** The team has been heads down bug fixing and investing heavily into polishing existing flows, tools, and interactions. - **Interactive Shell Tool calling:** Gemini CLI can now also execute interactive tools if needed ([pr](https://github.com/google-gemini/gemini-cli/pull/11225) by [@galz10](https://github.com/galz10)). - **Alt+Key support:** Enables broader support for Alt+Key keyboard shortcuts across different terminals. ([pr](https://github.com/google-gemini/gemini-cli/pull/10767) by [@srivatsj](https://github.com/srivatsj)). - **Telemetry Diff stats:** Track line changes made by the model and user during file operations via OTEL. ([pr](https://github.com/google-gemini/gemini-cli/pull/10819) by [@jerop](https://github.com/jerop)). ## Announcements: v0.9.0 - 2025-10-06 - πŸŽ‰ **Interactive Shell:** Run interactive commands like `vim`, `rebase -i`, or even `gemini` 😎 directly in Gemini CLI: - Blog: [https://developers.googleblog.com/en/say-hello-to-a-new-level-of-interactivity-in-gemini-cli/](https://developers.googleblog.com/en/say-hello-to-a-new-level-of-interactivity-in-gemini-cli/) - **Install pre-release extensions:** Install the latest `--pre-release` versions of extensions. Used for when an extension’s release hasn’t been marked as "latest". ([pr](https://github.com/google-gemini/gemini-cli/pull/10752) by [@jakemac53](https://github.com/jakemac53)) - **Simplified extension creation:** Create a new, empty extension. Templates are no longer required. ([pr](https://github.com/google-gemini/gemini-cli/pull/10629) by [@chrstnb](https://github.com/chrstnb)) - **OpenTelemetry GenAI metrics:** Aligns telemetry with industry-standard semantic conventions for improved interoperability. ([spec](https://opentelemetry.io/docs/concepts/semantic-conventions/), [pr](https://github.com/google-gemini/gemini-cli/pull/10343) by [@jerop](https://github.com/jerop)) - **List memory files:** Quickly find the location of your long-term memory files with `/memory list`. ([pr](https://github.com/google-gemini/gemini-cli/pull/10108) by [@sgnagnarella](https://github.com/sgnagnarella)) ## Announcements: v0.8.0 - 2025-09-29 - πŸŽ‰ **Announcing Gemini CLI Extensions** πŸŽ‰ - Completely customize your Gemini CLI experience to fit your workflow. - Build and share your own Gemini CLI extensions with the world. - Launching with a growing catalog of community, partner, and Google-built extensions. - Check extensions from [key launch partners](https://github.com/google-gemini/gemini-cli/discussions/10718). - Easy install: - `gemini extensions install ` - Easy management: - `gemini extensions install|uninstall|link` - `gemini extensions enable|disable` - `gemini extensions list|update|new` - Or use commands while running with `/extensions list|update`. - Everything you need to know: [Now open for building: Introducing Gemini CLI extensions](https://blog.google/technology/developers/gemini-cli-extensions/). - πŸŽ‰ **Our New Home Page & Better Documentation** πŸŽ‰ - Check out our new home page for better getting started material, reference documentation, extensions and more! - _Homepage:_ [https://geminicli.com](https://geminicli.com) - ‼️*NEW documentation:* [https://geminicli.com/docs](https://geminicli.com/docs) (Have any [suggestions](https://github.com/google-gemini/gemini-cli/discussions/8722)?) - _Extensions:_ [https://geminicli.com/extensions](https://geminicli.com/extensions) - **Non-Interactive Allowed Tools:** `--allowed-tools` will now also work in non-interactive mode. ([pr](https://github.com/google-gemini/gemini-cli/pull/9114) by [@mistergarrison](https://github.com/mistergarrison)) - **Terminal Title Status:** See the CLI's real-time status and thoughts directly in the terminal window's title by setting `showStatusInTitle: true`. ([pr](https://github.com/google-gemini/gemini-cli/pull/4386) by [@Fridayxiao](https://github.com/Fridayxiao)) - **Small features, polish, reliability & bug fixes:** A large amount of changes, smaller features, UI updates, reliability and bug fixes + general polish made it in this week! ## Announcements: v0.7.0 - 2025-09-22 - πŸŽ‰**Build your own Gemini CLI IDE plugin:** We've published a spec for creating IDE plugins to enable rich context-aware experiences and native in-editor diffing in your IDE of choice. ([pr](https://github.com/google-gemini/gemini-cli/pull/8479) by [@skeshive](https://github.com/skeshive)) - πŸŽ‰ **Gemini CLI extensions** - **Flutter:** An early version to help you create, build, test, and run Flutter apps with Gemini CLI ([extension](https://github.com/gemini-cli-extensions/flutter)) - **nanobanana:** Integrate nanobanana into Gemini CLI ([extension](https://github.com/gemini-cli-extensions/nanobanana)) - **Telemetry config via environment:** Manage telemetry settings using environment variables for a more flexible setup. ([docs](https://github.com/google-gemini/gemini-cli/blob/main/docs/cli/telemetry.md#configuration), [pr](https://github.com/google-gemini/gemini-cli/pull/9113) by [@jerop](https://github.com/jerop)) - **​​Experimental todos:** Track and display progress on complex tasks with a managed checklist. Off by default but can be enabled via `"useWriteTodos": true` ([pr](https://github.com/google-gemini/gemini-cli/pull/8761) by [@anj-s](https://github.com/anj-s)) - **Share chat support for tools:** Using `/chat share` will now also render function calls and responses in the final markdown file. ([pr](https://github.com/google-gemini/gemini-cli/pull/8693) by [@rramkumar1](https://github.com/rramkumar1)) - **Citations:** Now enabled for all users ([pr](https://github.com/google-gemini/gemini-cli/pull/8570) by [@scidomino](https://github.com/scidomino)) - **Custom commands in Headless Mode:** Run custom slash commands directly from the command line in non-interactive mode: `gemini "/joke Chuck Norris"` ([pr](https://github.com/google-gemini/gemini-cli/pull/8305) by [@capachino](https://github.com/capachino)) - **Small features, polish, reliability & bug fixes:** A large amount of changes, smaller features, UI updates, reliability and bug fixes + general polish made it in this week! ## Announcements: v0.6.0 - 2025-09-15 - πŸŽ‰ **Higher limits for Google AI Pro and Ultra subscribers:** We’re psyched to finally announce that Google AI Pro and AI Ultra subscribers now get access to significantly higher 2.5 quota limits for Gemini CLI! - **Announcement:** [https://blog.google/technology/developers/gemini-cli-code-assist-higher-limits/](https://blog.google/technology/developers/gemini-cli-code-assist-higher-limits/) - πŸŽ‰**Gemini CLI Databases and BigQuery Extensions:** Connect Gemini CLI to all of your cloud data with Gemini CLI. - Announcement and how to get started with each of the below extensions: [https://cloud.google.com/blog/products/databases/gemini-cli-extensions-for-google-data-cloud?e=48754805](https://cloud.google.com/blog/products/databases/gemini-cli-extensions-for-google-data-cloud?e=48754805) - **AlloyDB:** Interact, manage and observe AlloyDB for PostgreSQL databases ([manage](https://github.com/gemini-cli-extensions/alloydb#configuration), [observe](https://github.com/gemini-cli-extensions/alloydb-observability#configuration)) - **BigQuery:** Connect and query your BigQuery datasets or utilize a sub-agent for contextual insights ([query](https://github.com/gemini-cli-extensions/bigquery-data-analytics#configuration), [sub-agent](https://github.com/gemini-cli-extensions/bigquery-conversational-analytics)) - **Cloud SQL:** Interact, manage and observe Cloud SQL for PostgreSQL ([manage](https://github.com/gemini-cli-extensions/cloud-sql-postgresql#configuration),[ observe](https://github.com/gemini-cli-extensions/cloud-sql-postgresql-observability#configuration)), Cloud SQL for MySQL ([manage](https://github.com/gemini-cli-extensions/cloud-sql-mysql#configuration),[ observe](https://github.com/gemini-cli-extensions/cloud-sql-mysql-observability#configuration)) and Cloud SQL for SQL Server ([manage](https://github.com/gemini-cli-extensions/cloud-sql-sqlserver#configuration),[ observe](https://github.com/gemini-cli-extensions/cloud-sql-sqlserver-observability#configuration)) databases. - **Dataplex:** Discover, manage, and govern data and AI artifacts ([extension](https://github.com/gemini-cli-extensions/dataplex#configuration)) - **Firestore:** Interact with Firestore databases, collections and documents ([extension](https://github.com/gemini-cli-extensions/firestore-native#configuration)) - **Looker:** Query data, run Looks and create dashboards ([extension](https://github.com/gemini-cli-extensions/looker#configuration)) - **MySQL:** Interact with MySQL databases ([extension](https://github.com/gemini-cli-extensions/mysql#configuration)) - **Postgres:** Interact with PostgreSQL databases ([extension](https://github.com/gemini-cli-extensions/postgres#configuration)) - **Spanner:** Interact with Spanner databases ([extension](https://github.com/gemini-cli-extensions/spanner#configuration)) - **SQL Server:** Interact with SQL Server databases ([extension](https://github.com/gemini-cli-extensions/sql-server#configuration)) - **MCP Toolbox:** Configure and load custom tools for more than 30+ data sources ([extension](https://github.com/gemini-cli-extensions/mcp-toolbox#configuration)) - **JSON output mode:** Have Gemini CLI output JSON with `--output-format json` when invoked headlessly for easy parsing and post-processing. Includes response, stats and errors. ([pr](https://github.com/google-gemini/gemini-cli/pull/8119) by [@jerop](https://github.com/jerop)) - **Keybinding triggered approvals:** When you use shortcuts (`shift+y` or `shift+tab`) to activate YOLO/auto-edit modes any pending confirmation dialogs will now approve. ([pr](https://github.com/google-gemini/gemini-cli/pull/6665) by [@bulkypanda](https://github.com/bulkypanda)) - **Chat sharing:** Convert the current conversation to a Markdown or JSON file with _/chat share <file.md|file.json>_ ([pr](https://github.com/google-gemini/gemini-cli/pull/8139) by [@rramkumar1](https://github.com/rramkumar1)) - **Prompt search:** Search your prompt history using `ctrl+r`. ([pr](https://github.com/google-gemini/gemini-cli/pull/5539) by [@Aisha630](https://github.com/Aisha630)) - **Input undo/redo:** Recover accidentally deleted text in the input prompt using `ctrl+z` (undo) and `ctrl+shift+z` (redo). ([pr](https://github.com/google-gemini/gemini-cli/pull/4625) by [@masiafrest](https://github.com/masiafrest)) - **Loop detection confirmation:** When loops are detected you are now presented with a dialog to disable detection for the current session. ([pr](https://github.com/google-gemini/gemini-cli/pull/8231) by [@SandyTao520](https://github.com/SandyTao520)) - **Direct to Google Cloud Telemetry:** Directly send telemetry to Google Cloud for a simpler and more streamlined setup. ([pr](https://github.com/google-gemini/gemini-cli/pull/8541) by [@jerop](https://github.com/jerop)) - **Visual Mode Indicator Revamp:** β€˜shell’, 'accept edits' and 'yolo' modes now have colors to match their impact / usage. Input box now also updates. ([shell](https://imgur.com/a/DovpVF1), [accept-edits](https://imgur.com/a/33KDz3J), [yolo](https://imgur.com/a/tbFwIWp), [pr](https://github.com/google-gemini/gemini-cli/pull/8200) by [@miguelsolorio](https://github.com/miguelsolorio)) - **Small features, polish, reliability & bug fixes:** A large amount of changes, smaller features, UI updates, reliability and bug fixes + general polish made it in this week! ## Announcements: v0.5.0 - 2025-09-08 - πŸŽ‰**FastMCP + Gemini CLI**πŸŽ‰: Quickly install and manage your Gemini CLI MCP servers with FastMCP ([video](https://imgur.com/a/m8QdCPh), [pr](https://github.com/jlowin/fastmcp/pull/1709) by [@jackwotherspoon](https://github.com/jackwotherspoon)**)** - Getting started: [https://gofastmcp.com/integrations/gemini-cli](https://gofastmcp.com/integrations/gemini-cli) - **Positional Prompt for Non-Interactive:** Seamlessly invoke Gemini CLI headlessly via `gemini "Hello"`. Synonymous with passing `-p`. ([gif](https://imgur.com/a/hcBznpB), [pr](https://github.com/google-gemini/gemini-cli/pull/7668) by [@allenhutchison](https://github.com/allenhutchison)) - **Experimental Tool output truncation:** Enable truncating shell tool outputs and saving full output to a file by setting `"enableToolOutputTruncation": true `([pr](https://github.com/google-gemini/gemini-cli/pull/8039) by [@SandyTao520](https://github.com/SandyTao520)) - **Edit Tool improvements:** Gemini CLI’s ability to edit files should now be far more capable. ([pr](https://github.com/google-gemini/gemini-cli/pull/7679) by [@silviojr](https://github.com/silviojr)) - **Custom witty messages:** The feature you’ve all been waiting for… Personalized witty loading messages via `"ui": { "customWittyPhrases": ["YOLO"]}` in `settings.json`. ([pr](https://github.com/google-gemini/gemini-cli/pull/7641) by [@JayadityaGit](https://github.com/JayadityaGit)) - **Nested .gitignore File Handling:** Nested `.gitignore` files are now respected. ([pr](https://github.com/google-gemini/gemini-cli/pull/7645) by [@gsquared94](https://github.com/gsquared94)) - **Enforced authentication:** System administrators can now mandate a specific authentication method via `"enforcedAuthType": "oauth-personal|gemini-api-key|…"`in `settings.json`. ([pr](https://github.com/google-gemini/gemini-cli/pull/6564) by [@chrstnb](https://github.com/chrstnb)) - **A2A development-tool extension:** An RFC for an Agent2Agent ([A2A](https://a2a-protocol.org/latest/)) powered extension for developer tool use cases. ([feedback](https://github.com/google-gemini/gemini-cli/discussions/7822), [pr](https://github.com/google-gemini/gemini-cli/pull/7817) by [@skeshive](https://github.com/skeshive)) - **Hands on Codelab: **[https://codelabs.developers.google.com/gemini-cli-hands-on](https://codelabs.developers.google.com/gemini-cli-hands-on) - **Small features, polish, reliability & bug fixes:** A large amount of changes, smaller features, UI updates, reliability and bug fixes + general polish made it in this week! ## Announcements: v0.4.0 - 2025-09-01 - πŸŽ‰**Gemini CLI CloudRun and Security Integrations**πŸŽ‰: Automate app deployment and security analysis with CloudRun and Security extension integrations. Once installed deploy your app to the cloud with `/deploy` and find and fix security vulnerabilities with `/security:analyze`. - Announcement and how to get started: [https://cloud.google.com/blog/products/ai-machine-learning/automate-app-deployment-and-security-analysis-with-new-gemini-cli-extensions](https://cloud.google.com/blog/products/ai-machine-learning/automate-app-deployment-and-security-analysis-with-new-gemini-cli-extensions) - **Experimental** - **Edit Tool:** Give our new edit tool a try by setting `"useSmartEdit": true` in `settings.json`! ([feedback](https://github.com/google-gemini/gemini-cli/discussions/7758), [pr](https://github.com/google-gemini/gemini-cli/pull/6823) by [@silviojr](https://github.com/silviojr)) - **Model talking to itself fix:** We’ve removed a model workaround that would encourage Gemini CLI to continue conversations on your behalf. This may be disruptive and can be disabled via `"skipNextSpeakerCheck": false` in your `settings.json` ([feedback](https://github.com/google-gemini/gemini-cli/discussions/6666), [pr](https://github.com/google-gemini/gemini-cli/pull/7614) by [@SandyTao520](https://github.com/SandyTao520)) - **Prompt completion:** Get real-time AI suggestions to complete your prompts as you type. Enable it with `"general": { "enablePromptCompletion": true }` and share your feedback! ([gif](https://miro.medium.com/v2/resize:fit:2000/format:webp/1*hvegW7YXOg6N_beUWhTdxA.gif), [pr](https://github.com/google-gemini/gemini-cli/pull/4691) by [@3ks](https://github.com/3ks)) - **Footer visibility configuration:** Customize the CLI's footer look and feel in `settings.json` ([pr](https://github.com/google-gemini/gemini-cli/pull/7419) by [@miguelsolorio](https://github.com/miguelsolorio)) - `hideCWD`: hide current working directory. - `hideSandboxStatus`: hide sandbox status. - `hideModelInfo`: hide current model information. - `hideContextSummary`: hide request context summary. - **Citations:** For enterprise Code Assist licenses users will now see citations in their responses by default. Enable this yourself with `"showCitations": true` ([pr](https://github.com/google-gemini/gemini-cli/pull/7350) by [@scidomino](https://github.com/scidomino)) - **Pro Quota Dialog:** Handle daily Pro model usage limits with an interactive dialog that lets you immediately switch auth or fallback. ([pr](https://github.com/google-gemini/gemini-cli/pull/7094) by [@JayadityaGit](https://github.com/JayadityaGit)) - **Custom commands @:** Embed local file or directory content directly into your custom command prompts using `@{path}` syntax ([gif](https://miro.medium.com/v2/resize:fit:2000/format:webp/1*GosBAo2SjMfFffAnzT7ZMg.gif), [pr](https://github.com/google-gemini/gemini-cli/pull/6716) by [@abhipatel12](https://github.com/abhipatel12)) - **2.5 Flash Lite support:** You can now use the `gemini-2.5-flash-lite` model for Gemini CLI via `gemini -m …`. ([gif](https://miro.medium.com/v2/resize:fit:2000/format:webp/1*P4SKwnrsyBuULoHrFqsFKQ.gif), [pr](https://github.com/google-gemini/gemini-cli/pull/4652) by [@psinha40898](https://github.com/psinha40898)) - **CLI streamlining:** We have deprecated a number of command line arguments in favor of `settings.json`Β alternatives. We will remove these arguments in a future release. See the PR for the full list of deprecations. ([pr](https://github.com/google-gemini/gemini-cli/pull/7360) by [@allenhutchison](https://github.com/allenhutchison)) - **JSON session summary:** Track and save detailed CLI session statistics to a JSON file for performance analysis with `--session-summary ` ([pr](https://github.com/google-gemini/gemini-cli/pull/7347) by [@leehagoodjames](https://github.com/leehagoodjames)) - **Robust keyboard handling:** More reliable and consistent behavior for arrow keys, special keys (Home, End, etc.), and modifier combinations across various terminals. ([pr](https://github.com/google-gemini/gemini-cli/pull/7118) by [@deepankarsharma](https://github.com/deepankarsharma)) - **MCP loading indicator:** Provides visual feedback during CLI initialization when connecting to multiple servers. ([pr](https://github.com/google-gemini/gemini-cli/pull/6923) by [@swissspidy](https://github.com/swissspidy)) - **Small features, polish, reliability & bug fixes:** A large amount of changes, smaller features, UI updates, reliability and bug fixes + general polish made it in this week! # [Preview release: v0.65.0-preview.0](http://geminicli.com/docs/changelogs/preview.md) Released: October 13, 2026 Our preview release includes the latest, new, and experimental features. This release may not be as stable as our [latest weekly release](/docs/changelogs/latest). To install the preview release: ``` npm install -g @google/gemini-cli@preview ``` ## Highlights - **Custom Telemetry Headers**: Added support for configuring custom OTLP headers in telemetry settings, enabling authentication and header customization for OpenTelemetry collectors. - **File System Performance & Traversal**: Optimized ignore pattern filtering with subtree pruning to accelerate directory scanning, deferred recursive file reads for `@` references, and improved empty file handling across multi-byte encodings. - **Session Resilience & State Integrity**: Prevented session poisoning during rapid Ctrl+C interruptions, preserved resumed session history on quick exits, and eliminated duplicate tool response turns upon resuming sessions. - **Authentication & Workspace Security**: Enforced read-only workspace settings in untrusted directories, aligned OAuth callback parameter validation with RFC 9207 metadata, and resolved infinite authentication retry loops. - **Terminal UI & Interactive Stability**: Resolved interactive mode hangs on Enter keypresses, prevented unnecessary terminal clears and scroll resets when expanding output with Ctrl+O, and restored debounced static UI refreshes on terminal width changes. ## What's Changed - fix(cli): enforce read-only workspace settings in untrusted folders by @jvargassanchez-dot in [#29583](https://github.com/google-gemini/gemini-cli/pull/29583) - fix(core): avoid duplicate tool response turns when resuming sessions by @diegogodinezr in [#29618](https://github.com/google-gemini/gemini-cli/pull/29618) - fix(core): prevent deletion of resumed session history on quick exit (#29198) by @villahernandez-coder in [#29584](https://github.com/google-gemini/gemini-cli/pull/29584) - Changelog for v0.64.0-preview.0 by @gemini-cli-robot in [#29656](https://github.com/google-gemini/gemini-cli/pull/29656) - Changelog for v0.63.0 by @gemini-cli-robot in [#29659](https://github.com/google-gemini/gemini-cli/pull/29659) - fix(core): align OAuth callback iss parameter validation with RFC 9207 metadata by @luisfelipe-alt in [#29616](https://github.com/google-gemini/gemini-cli/pull/29616) - fix(cli): prevent unnecessary terminal clears and scroll resets when expanding with Ctrl+O by @jesussamuel-byte in [#29640](https://github.com/google-gemini/gemini-cli/pull/29640) - chore(release): bump version to 0.65.0-nightly.20261006.gfb972b2f8 by @gemini-cli-robot in [#29657](https://github.com/google-gemini/gemini-cli/pull/29657) - fix(ci): add missing loop in unassign-inactive-assignees workflow by @ugorla-dev in [#29609](https://github.com/google-gemini/gemini-cli/pull/29609) - fix(core): enforce terminal user turn invariant and normalize request contents by @luisfelipe-alt in [#29612](https://github.com/google-gemini/gemini-cli/pull/29612) - `feat(telemetry): support custom OTLP headers in telemetry configuration` by @jesussamuel-byte in [#29641](https://github.com/google-gemini/gemini-cli/pull/29641) - fix(auth): prevent infinite verification and OAuth retry loops by @villahernandez-coder in [#29655](https://github.com/google-gemini/gemini-cli/pull/29655) - fix(cli): handle JSON parse and response stream errors in fetchJson by @jesussamuel-byte in [#29658](https://github.com/google-gemini/gemini-cli/pull/29658) - fix(core): preserve line terminators in truncateString by @diegogodinezr in [#29673](https://github.com/google-gemini/gemini-cli/pull/29673) - fix(vscode-ide-companion): make IdeServer.stop() resolve while MCP sessions are open by @elberthc-byte in [#29674](https://github.com/google-gemini/gemini-cli/pull/29674) - fix(core): retain ask_user question text in the tool result display by @elberthc-byte in [#29677](https://github.com/google-gemini/gemini-cli/pull/29677) - fix(core): eliminate false positives on untrusted command flags and compound loops by @DavidAPierce in [#29672](https://github.com/google-gemini/gemini-cli/pull/29672) - fix(cli): clear cached credentials when re-selecting Google login by @urielefrenvirtusa in [#29643](https://github.com/google-gemini/gemini-cli/pull/29643) - fix(cli): resolve hang on Enter keypress in interactive mode (#23297) by @elberthc-byte in [#29476](https://github.com/google-gemini/gemini-cli/pull/29476) - perf(core): optimize ignore filtering and enable subtree pruning (#29077) by @amelidev in [#29582](https://github.com/google-gemini/gemini-cli/pull/29582) - fix(a2a-server): isolate tool rejection to active call in sequential batches by @jvargassanchez-dot in [#29683](https://github.com/google-gemini/gemini-cli/pull/29683) - fix(cli): skip eager recursive file reading for @ references by @jvargassanchez-dot in [#29617](https://github.com/google-gemini/gemini-cli/pull/29617) - fix(cli): keep loading other extensions when one fails the allowlist check by @jesussamuel-byte in [#29720](https://github.com/google-gemini/gemini-cli/pull/29720) - fix(cli): correct reverse search highlight index for expanding unicode characters by @diegogodinezr in [#29699](https://github.com/google-gemini/gemini-cli/pull/29699) - fix(core): treat whitespace-only UTF-16 and UTF-32 files as empty by @jesussamuel-byte in [#29722](https://github.com/google-gemini/gemini-cli/pull/29722) - fix(cli): restore debounced static UI refresh on terminal width changes by @jvargassanchez-dot in [#29644](https://github.com/google-gemini/gemini-cli/pull/29644) - fix(cli): prevent session poisoning on rapid Ctrl-C interruption by @villahernandez-coder in [#29728](https://github.com/google-gemini/gemini-cli/pull/29728) **Full Changelog**: https://github.com/google-gemini/gemini-cli/compare/v0.64.0-preview.1...v0.65.0-preview.0 # [ACP Mode](http://geminicli.com/docs/cli/acp-mode.md) ACP (Agent Client Protocol) mode is a special operational mode of Gemini CLI designed for programmatic control, primarily for IDE and other developer tool integrations. It uses a JSON-RPC protocol over stdio to communicate between Gemini CLI agent and a client. To start Gemini CLI in ACP mode, use the `--acp` flag: ```bash gemini --acp ``` ## Agent Client Protocol (ACP) ACP is an open protocol that standardizes how AI coding agents communicate with code editors and IDEs. It addresses the challenge of fragmented distribution, where agents traditionally needed custom integrations for each client. With ACP, developers can implement their agent once, and it becomes compatible with any ACP-compliant editor. For a comprehensive introduction to ACP, including its architecture and benefits, refer to the official [ACP Introduction](https://agentclientprotocol.com/get-started/introduction) documentation. ### Existing integrations using ACP The ACP Agent Registry simplifies the distribution and management of ACP-compatible agents across various IDEs. Gemini CLI is an ACP-compatible agent and can be found in this registry. For more general information about the registry, and how to use it with specific IDEs like JetBrains and Zed, refer to the [IDE Integration](/docs/ide-integration) documentation. You can also find more information on the official [ACP Agent Registry](https://agentclientprotocol.com/get-started/registry) page. ## Architecture and protocol basics ACP mode establishes a client-server relationship between your tool (the client) and Gemini CLI (the server). - **Communication:** The entire communication happens over standard input/output (stdio) using the JSON-RPC 2.0 protocol. - **Client's role:** The client is responsible for sending requests (for example, prompts) and handling responses and notifications from Gemini CLI. - **Gemini CLI's role:** In ACP mode, Gemini CLI listens for incoming JSON-RPC requests, processes them, and sends back responses. The core of the ACP implementation can be found in `packages/cli/src/acp/acpClient.ts`. ### Extending with MCP ACP can be used with the Model Context Protocol (MCP). This lets an ACP client (like an IDE) expose its own functionality as "tools" that the Gemini model can use. 1. The client implements an **MCP server** that advertises its tools. 2. During the ACP `initialize` handshake, the client provides the connection details for its MCP server. 3. Gemini CLI connects to the MCP server, discovers the available tools, and makes them available to the AI model. 4. When the model decides to use one of these tools, Gemini CLI sends a tool call request to the MCP server. This mechanism lets for a powerful, two-way integration where the agent can leverage the IDE's capabilities to perform tasks. The MCP client logic is in `packages/core/src/tools/mcp-client.ts`. ## Capabilities and supported methods The ACP protocol exposes a number of methods for ACP clients (for example IDEs) to control Gemini CLI. ### Core methods - `initialize`: Establishes the initial connection and lets the client to register its MCP server. - `authenticate`: Authenticates the user. - `newSession`: Starts a new chat session. - `loadSession`: Loads a previous session. - `prompt`: Sends a prompt to the agent. - `cancel`: Cancels an ongoing prompt. ### Session control - `setSessionMode`: Allows changing the approval level for tool calls (for example, to `auto-approve`). - `unstable_setSessionModel`: Changes the model for the current session. ### File system proxy ACP includes a proxied file system service. This means that when the agent needs to read or write files, it does so through the ACP client. This is a security feature that ensures the agent only has access to the files that the client (and by extension, the user) has explicitly allowed. ## Debugging and telemetry You can get insights into the ACP communication and the agent's behavior through debugging logs and telemetry. ### Debugging logs To enable general debugging logs, start Gemini CLI with the `--debug` flag: ```bash gemini --acp --debug ``` ### Telemetry For more detailed telemetry, you can use the following environment variables to capture telemetry data to a file: - `GEMINI_TELEMETRY_ENABLED=true` - `GEMINI_TELEMETRY_TARGET=local` - `GEMINI_TELEMETRY_OUTFILE=/path/to/your/log.json` This will write a JSON log file containing detailed information about all the events happening within the agent, including ACP requests and responses. The integration test `integration-tests/acp-telemetry.test.ts` provides a working example of how to set this up. # [Auto Memory](http://geminicli.com/docs/cli/auto-memory.md) Auto Memory is an experimental feature that mines your past Gemini CLI sessions in the background and proposes durable memory updates and reusable [Agent Skills](/docs/cli/skills). You review each candidate before it becomes available to future sessions: apply memory updates, promote skills, or discard anything you do not want. > [!NOTE] > This is an experimental feature currently under active development. ## Overview Every session you run with Gemini CLI is recorded locally as a transcript. Auto Memory scans those transcripts for durable facts, preferences, workflow constraints, and procedural patterns that recur across sessions. It can draft memory updates as unified diff `.patch` files and draft reusable procedures as `SKILL.md` files. All candidates are held in a project-local inbox until you approve or discard them. You'll use Auto Memory when you want to: - **Capture team workflows** that you find yourself walking the agent through more than once. - **Preserve durable project context** such as repeated verification commands, local constraints, or personal project notes. - **Codify hard-won fixes** for project-specific landmines so future sessions avoid them. - **Bootstrap a skills library** without writing every `SKILL.md` by hand. Auto Memory complements direct memory-file editing. The agent can still persist explicit user instructions by editing the appropriate Markdown memory file; Auto Memory infers candidates from past sessions, writes reviewable patches or skill drafts, and never applies them without your approval. ## Prerequisites - Gemini CLI installed and authenticated. - At least one idle project session with 10 or more user messages. Auto Memory ignores active, trivial, and sub-agent sessions. ## How to enable Auto Memory Auto Memory is off by default. Enable it in your settings file: 1. Open your global settings file at `~/.gemini/settings.json`. If you only want Auto Memory in one project, edit `.gemini/settings.json` in that project instead. 2. Add the experimental flag: ```json { "experimental": { "autoMemory": true } } ``` 3. Restart Gemini CLI. The flag requires a restart because the extraction service starts during session boot. ## How Auto Memory works Auto Memory runs as a background task on session startup. It does not block the UI, consume your interactive turns, or surface tool prompts. 1. **Eligibility scan.** The service indexes recent sessions from `~/.gemini/tmp//chats/`. Sessions are eligible only if they have been idle for at least three hours and contain at least 10 user messages. 2. **Lock acquisition.** A lock file in the project's memory directory coordinates across multiple CLI instances so extraction runs at most once at a time. A state file records processed session versions, and extraction is throttled so short back-to-back CLI launches do not repeatedly scan history. 3. **Candidate extraction.** A background extraction agent reviews the session index, reads any sessions that look like they contain durable memory or repeated procedural workflows, and drafts candidates. It defaults to creating no artifacts unless the evidence is strong, so many runs produce no inbox items. 4. **Safety boundaries.** Auto Memory writes candidates to a review inbox. It cannot directly edit active memory files, settings, credentials, or project `GEMINI.md` files. 5. **Patch validation.** Skill update patches are parsed and dry-run before they are surfaced. Memory patches are parsed, target-allowlisted, and applied atomically only when you approve them from the inbox. 6. **Notification.** When a run produces new candidates, Gemini CLI surfaces an inline message telling you how many items are waiting. ## How to review extracted items Use the `/memory inbox` slash command to open the inbox dialog at any time: **Command:** `/memory inbox` The dialog groups pending items into new skills, skill updates, and memory updates. From there you can: - **Read** the full `SKILL.md` body before deciding. - **Promote** a skill to your user (`~/.gemini/skills/`) or workspace (`.gemini/skills/`) directory. - **Discard** a skill you do not want. - **Apply** or reject a `.patch` proposal against an existing skill. - **Review** memory diffs before they touch active files. - **Apply** or dismiss private and global memory patches. Private patches target the project memory directory; global patches target only your personal `~/.gemini/GEMINI.md` file. Promoted skills become discoverable in the next session and follow the standard [skill discovery precedence](/docs/cli/skills#skill-discovery-tiers). Applied memory patches update the underlying memory files and reload memory for the current session. ## How to disable Auto Memory To turn off background extraction, set the flag back to `false` in your settings file and restart Gemini CLI: ```json { "experimental": { "autoMemory": false } } ``` Disabling the flag stops the background service immediately on the next session start. Existing inbox items remain on disk; you can either drain them with `/memory inbox` first or remove the project memory directory manually. ## Data and privacy - Auto Memory only reads session files that already exist locally on your machine. - Auto Memory uses model calls to analyze selected local transcript content during extraction. No candidates are applied automatically, but transcript excerpts may be sent to the configured model as part of those calls. - The extraction agent is instructed to redact secrets, tokens, and credentials it encounters and to never copy large tool outputs verbatim. - Drafted skills and memory patches live in your project's memory directory until you promote, apply, dismiss, or discard them. They are not automatically loaded into any session. ## Limitations - The extraction agent runs on a preview Gemini Flash model. Extraction quality depends on the model's ability to recognize durable patterns versus one-off incidents. - Auto Memory does not extract memory or skills from the current session. It only considers sessions that have been idle for three hours or more. - Project or workspace shared instructions in project `GEMINI.md` files are not auto-extractable. Auto Memory can propose private project memory, global personal memory, and skills. - Inbox items are stored per project. Skills extracted in one workspace are not visible from another until you promote them to the user-scope skills directory. ## Next steps - Learn how skills are discovered and activated in [Agent Skills](/docs/cli/skills). - Explore the [memory management tutorial](/docs/cli/tutorials/memory-management) for the complementary explicit-memory and `GEMINI.md` workflows. - Review the experimental settings catalog in [Settings](/docs/cli/settings#experimental). # [Checkpointing](http://geminicli.com/docs/cli/checkpointing.md) Gemini CLI includes a Checkpointing feature that automatically saves a snapshot of your project's state before any file modifications are made by AI-powered tools. This lets you safely experiment with and apply code changes, knowing you can instantly revert back to the state before the tool was run. ## How it works When you approve a tool that modifies the file system (like `write_file` or `replace`), the CLI automatically creates a "checkpoint." This checkpoint includes: 1. **A Git snapshot:** A commit is made in a special, shadow Git repository located in your home directory (`~/.gemini/history/`). This snapshot captures the complete state of your project files at that moment. It does **not** interfere with your own project's Git repository. 2. **Conversation history:** The entire conversation you've had with the agent up to that point is saved. 3. **The tool call:** The specific tool call that was about to be executed is also stored. If you want to undo the change or simply go back, you can use the `/restore` command. Restoring a checkpoint will: - Revert all files in your project to the state captured in the snapshot. - Restore the conversation history in the CLI. - Re-propose the original tool call, allowing you to run it again, modify it, or simply ignore it. All checkpoint data, including the Git snapshot and conversation history, is stored locally on your machine. The Git snapshot is stored in the shadow repository while the conversation history and tool calls are saved in a JSON file in your project's temporary directory, typically located at `~/.gemini/tmp//checkpoints`. ## Enabling the feature The Checkpointing feature is disabled by default. To enable it, you need to edit your `settings.json` file. > [!CAUTION] > The `--checkpointing` command-line flag was removed in version > 0.11.0. Checkpointing can now only be enabled through the `settings.json` > configuration file. Add the following key to your `settings.json`: ```json { "general": { "checkpointing": { "enabled": true } } } ``` ## Using the `/restore` command Once enabled, checkpoints are created automatically. To manage them, you use the `/restore` command. ### List available checkpoints To see a list of all saved checkpoints for the current project, simply run: ``` /restore ``` The CLI will display a list of available checkpoint files. These file names are typically composed of a timestamp, the name of the file being modified, and the name of the tool that was about to be run (for example, `2025-06-22T10-00-00_000Z-my-file.txt-write_file`). ### Restore a specific checkpoint To restore your project to a specific checkpoint, use the checkpoint file from the list: ``` /restore ``` For example: ``` /restore 2025-06-22T10-00-00_000Z-my-file.txt-write_file ``` After running the command, your files and conversation will be immediately restored to the state they were in when the checkpoint was created, and the original tool prompt will reappear. # [Creating Agent Skills](http://geminicli.com/docs/cli/creating-skills.md) Agent Skills let you extend Gemini CLI with specialized expertise, procedural workflows, and task-specific resources. This guide walks you through both automated and manual methods for creating and organizing your skills. ## Quickstart: Create a skill with a prompt The fastest way to create a new skill is to use the built-in `skill-creator`. This meta-skill guides you through designing, scaffolding, and validating your expertise. Simply ask Gemini CLI to create a skill for you: > "Create a new skill called 'code-reviewer' that analyzes local files for > common errors and style violations." Gemini will then: 1. Generate a new directory for your skill (for example, `my-new-skill/`). 2. Create a `SKILL.md` file with the necessary YAML frontmatter (`name` and `description`). 3. Create the standard resource directories: `scripts/`, `references/`, and `assets/`. Once created, you can find your new skill in `.gemini/skills/code-reviewer/`. ## Manual creation 1. **Create a directory** for your skill (for example, `my-new-skill/`). 2. **Create a `SKILL.md` file** inside the new directory. ### 1. Create the directory structure The first step is to create the necessary folders for your skill and its scripts. **macOS/Linux** ```bash mkdir -p .gemini/skills/code-reviewer/scripts ``` **Windows (PowerShell)** ```powershell New-Item -ItemType Directory -Force -Path ".gemini\skills\code-reviewer\scripts" ``` ### 2. Define the skill (`SKILL.md`) The `SKILL.md` file defines the skill's purpose and instructions for the agent. Create a file at `.gemini/skills/code-reviewer/SKILL.md`. ```markdown --- name: code-reviewer description: Expertise in reviewing code changes for correctness, security, and style. Use when the user asks to "review" their code or a PR. --- # Code Reviewer Instructions You act as a senior software engineer specialized in code quality. When this skill is active, you MUST: 1. **Analyze**: Review the provided code for logical errors, security vulnerabilities, and style violations. 2. **Review**: Use the bundled `scripts/review.js` utility to perform an automated check. 3. **Feedback**: Provide constructive feedback, clearly distinguishing between critical issues and minor improvements. ``` ### 3. Add the tool logic Skills can bundle resources like scripts to perform deterministic tasks. Create a file at `.gemini/skills/code-reviewer/scripts/review.js`. ```javascript // .gemini/skills/code-reviewer/scripts/review.js const file = process.argv[2]; if (!file) { console.error('Usage: node review.js '); process.exit(1); } console.log(`Reviewing ${file}...`); // Simple mock review logic setTimeout(() => { console.log(`Result: Success (No major issues found in ${file})`); }, 500); ``` ### 4. Test the skill Gemini CLI automatically discovers skills in the `.gemini/skills` directory. 1. Start a new session and ask a question that triggers the skill's description: "Can you review index.js" 2. Gemini identifies the request matches the `code-reviewer` description and asks for permission to activate it. 3. Once you approve, Gemini executes the bundled script: `node .gemini/skills/code-reviewer/scripts/review.js index.js` To determine whether your skill has been correctly loaded, run the command: ```bash /skills ``` ### 5. Optional: Share your skill You can share your skills in several ways depending on your target audience. - **Workspace skills**: Commit your skill to a `.gemini/skills/` directory in your project repository. - **Extensions**: Bundle your skill within a [Gemini CLI extension](/docs/extensions/writing-extensions). - **Git repositories**: Share the skill directory as a standalone Git repo and install it using `gemini skills install `. --- ## Core concepts Now that you've built your first skill, let's explore the core components and workflows for developing more complex expertise. ### Skill structure While a `SKILL.md` file is the only required component, we recommend the following structure for organizing your skill's resources. ```text my-skill/ β”œβ”€β”€ SKILL.md (Required) Instructions and metadata β”œβ”€β”€ scripts/ (Optional) Executable scripts β”œβ”€β”€ references/ (Optional) Static documentation └── assets/ (Optional) Templates and other resources ``` When a skill is activated, the model is granted access to this entire directory. You can instruct the model to use the tools and files found within these folders. ### Metadata and triggers The `SKILL.md` file uses YAML frontmatter for metadata. - **`name`**: A unique identifier for the skill. This should match the directory name. - **`description`**: **CRITICAL.** This is how Gemini decides when to use the skill. Be specific about the tasks it handles and the keywords that should trigger it. ### Discovery tiers Gemini CLI discovers skills from several locations, following a specific order of precedence (lowest to highest): 1. **Built-in Skills**: Included with Gemini CLI (pre-approved). 2. **Extension Skills**: Bundled within [extensions](/docs/extensions). 3. **User Skills**: `~/.gemini/skills/` or the `~/.agents/skills/` alias. 4. **Workspace Skills**: `.gemini/skills/` or the `.agents/skills/` alias. ### Discovery aliases You can use `.agents/skills` as an alternative to `.gemini/skills`. This alias is compatible with other AI agent tools following the [Agent Skills](https://agentskills.io) standard. ## Advanced development Once you've built a basic skill, you can use specialized scripts and workflows to streamline your development process. ### Creation scripts If you are developing a skill and want to use the same scripts the built-in tools use, you can find them in the core package. These scripts help automate the initialization, validation, and packaging of skills. - **Initialize**: `node scripts/init_skill.cjs --path ` - **Validate**: `node scripts/validate_skill.cjs ` - **Package**: `node scripts/package_skill.cjs ` (Creates a `.skill` zip file) ### Linking for local development If you are developing a skill in a separate directory, you can link it to your user skills directory for testing: ```bash gemini skills link . ``` ## Next steps - [Skill best practices](/docs/cli/skills-best-practices): Learn strategies for building reliable and effective skills. - [Agent Skills overview](/docs/cli/skills): Deep dive into discovery tiers and the skill lifecycle. - [Get started with Agent Skills](/docs/cli/tutorials/skills-getting-started): A quick walkthrough of triggering and using skills. # [Gemini CLI cheatsheet](http://geminicli.com/docs/cli/cli-reference.md) This page provides a reference for commonly used Gemini CLI commands, options, and parameters. ## CLI commands | Command | Description | Example | | ---------------------------------- | ---------------------------------- | ------------------------------------------------------------ | | `gemini` | Start interactive REPL | `gemini` | | `gemini -p "query"` | Query non-interactively | `gemini -p "summarize README.md"` | | gemini "query" | Query and continue interactively | gemini "explain this project" | | `cat file \| gemini` | Process piped content | `cat logs.txt \| gemini`
    `Get-Content logs.txt \| gemini` | | `gemini -i "query"` | Execute and continue interactively | `gemini -i "What is the purpose of this project?"` | | `gemini -r "latest"` | Continue most recent session | `gemini -r "latest"` | | `gemini -r "latest" "query"` | Continue session with a new prompt | `gemini -r "latest" "Check for type errors"` | | `gemini -r "" "query"` | Resume session by ID | `gemini -r "abc123" "Finish this PR"` | | `gemini update` | Update to latest version | `gemini update` | | `gemini extensions` | Manage extensions | See [Extensions Management](#extensions-management) | | `gemini mcp` | Configure MCP servers | See [MCP Server Management](#mcp-server-management) | ### Positional arguments | Argument | Type | Description | | -------- | ----------------- | ---------------------------------------------------------------------------------------------------------- | | `query` | string (variadic) | Positional prompt. Defaults to interactive mode in a TTY. Use `-p/--prompt` for non-interactive execution. | ## Interactive commands These commands are available within the interactive REPL. | Command | Description | | -------------------- | ----------------------------------------------- | | `/skills reload` | Reload discovered skills from disk | | `/agents reload` | Reload the agent registry | | `/commands list` | List available custom slash commands | | `/commands reload` | Reload custom slash commands | | `/memory reload` | Reload context files (for example, `GEMINI.md`) | | `/mcp reload` | Restart and reload MCP servers | | `/extensions reload` | Reload all active extensions | | `/help` | Show help for all commands | | `/quit` | Exit the interactive session | ## CLI Options | Option | Alias | Type | Default | Description | | -------------------------------- | ----- | ------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `--debug` | `-d` | boolean | `false` | Run in debug mode with verbose logging | | `--version` | `-v` | - | - | Show CLI version number and exit | | `--help` | `-h` | - | - | Show help information | | `--model` | `-m` | string | `auto` | Model to use. See [Model Selection](#model-selection) for available values. | | `--prompt` | `-p` | string | - | Prompt text. Appended to stdin input if provided. Forces non-interactive mode. | | `--prompt-interactive` | `-i` | string | - | Execute prompt and continue in interactive mode | | `--worktree` | `-w` | string | - | Start Gemini in a new git worktree. If no name is provided, one is generated automatically. Requires `experimental.worktrees: true` in settings. | | `--sandbox` | `-s` | boolean | `false` | Run in a sandboxed environment for safer execution | | `--skip-trust` | - | boolean | `false` | Trust the current workspace for this session, skipping the folder trust check. | | `--approval-mode` | - | string | `default` | Approval mode for tool execution. Choices: `default`, `auto_edit`, `yolo`, `plan` | | `--yolo` | `-y` | boolean | `false` | **Deprecated.** Auto-approve all actions. Use `--approval-mode=yolo` instead. | | `--experimental-acp` | - | boolean | - | Start in ACP (Agent Code Pilot) mode. **Experimental feature.** | | `--experimental-zed-integration` | - | boolean | - | Run in Zed editor integration mode. **Experimental feature.** | | `--allowed-mcp-server-names` | - | array | - | Allowed MCP server names (comma-separated or multiple flags) | | `--allowed-tools` | - | array | - | **Deprecated.** Use the [Policy Engine](/docs/reference/policy-engine) instead. Tools that are allowed to run without confirmation (comma-separated or multiple flags) | | `--extensions` | `-e` | array | - | List of extensions to use. If not provided, all extensions are enabled (comma-separated or multiple flags) | | `--list-extensions` | `-l` | boolean | - | List all available extensions and exit | | `--resume` | `-r` | string | - | Resume a previous session. Use `"latest"` for most recent or index number (for example `--resume 5`) | | `--list-sessions` | - | boolean | - | List available sessions for the current project and exit | | `--delete-session` | - | string | - | Delete a session by index number (use `--list-sessions` to see available sessions) | | `--include-directories` | - | array | - | Additional directories to include in the workspace (comma-separated or multiple flags) | | `--screen-reader` | - | boolean | - | Enable screen reader mode for accessibility | | `--output-format` | `-o` | string | `text` | The format of the CLI output. Choices: `text`, `json`, `stream-json` | ## Model selection The `--model` (or `-m`) flag lets you specify which Gemini model to use. You can use either model aliases (user-friendly names) or concrete model names. ### Model aliases These are convenient shortcuts that map to specific models: | Alias | Resolves To | Description | | ------------ | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------- | | `auto` | `gemini-2.5-pro` or `gemini-3-pro-preview` | **Default.** Resolves to the preview model if preview features are enabled, otherwise resolves to the standard pro model. | | `pro` | `gemini-2.5-pro` or `gemini-3-pro-preview` | For complex reasoning tasks. Uses preview model if enabled. | | `flash` | `gemini-2.5-flash` | Fast, balanced model for most tasks. | | `flash-lite` | `gemini-2.5-flash-lite` | Fastest model for simple tasks. | ## Extensions management | Command | Description | Example | | -------------------------------------------------- | -------------------------------------------- | ------------------------------------------------------------------------------ | | `gemini extensions install ` | Install extension from Git URL or local path | `gemini extensions install https://github.com/user/my-extension` | | `gemini extensions install --ref ` | Install from specific branch/tag/commit | `gemini extensions install https://github.com/user/my-extension --ref develop` | | `gemini extensions install --auto-update` | Install with auto-update enabled | `gemini extensions install https://github.com/user/my-extension --auto-update` | | `gemini extensions uninstall ` | Uninstall one or more extensions | `gemini extensions uninstall my-extension` | | `gemini extensions list` | List all installed extensions | `gemini extensions list` | | `gemini extensions update ` | Update a specific extension | `gemini extensions update my-extension` | | `gemini extensions update --all` | Update all extensions | `gemini extensions update --all` | | `gemini extensions enable ` | Enable an extension | `gemini extensions enable my-extension` | | `gemini extensions disable ` | Disable an extension | `gemini extensions disable my-extension` | | `gemini extensions link ` | Link local extension for development | `gemini extensions link /path/to/extension` | | `gemini extensions new ` | Create new extension from template | `gemini extensions new ./my-extension` | | `gemini extensions validate ` | Validate extension structure | `gemini extensions validate ./my-extension` | See [Extensions Documentation](/docs/extensions) for more details. ## MCP server management | Command | Description | Example | | ------------------------------------------------------------- | ------------------------------- | ---------------------------------------------------------------------------------------------------- | | `gemini mcp add ` | Add stdio-based MCP server | `gemini mcp add github npx -y @modelcontextprotocol/server-github` | | `gemini mcp add --transport http` | Add HTTP-based MCP server | `gemini mcp add api-server http://localhost:3000 --transport http` | | `gemini mcp add --env KEY=value` | Add with environment variables | `gemini mcp add slack node server.js --env SLACK_TOKEN=xoxb-xxx` | | `gemini mcp add --scope user` | Add with user scope | `gemini mcp add db node db-server.js --scope user` | | `gemini mcp add --include-tools tool1,tool2` | Add with specific tools | `gemini mcp add github npx -y @modelcontextprotocol/server-github --include-tools list_repos,get_pr` | | `gemini mcp remove ` | Remove an MCP server | `gemini mcp remove github` | | `gemini mcp list` | List all configured MCP servers | `gemini mcp list` | See [MCP Server Integration](/docs/tools/mcp-server) for more details. ## Skills management | Command | Description | Example | | -------------------------------- | ------------------------------------- | ------------------------------------------------- | | `gemini skills list` | List all discovered agent skills | `gemini skills list` | | `gemini skills install ` | Install skill from Git, path, or file | `gemini skills install https://github.com/u/repo` | | `gemini skills link ` | Link local agent skills via symlink | `gemini skills link /path/to/my-skills` | | `gemini skills uninstall ` | Uninstall an agent skill | `gemini skills uninstall my-skill` | | `gemini skills enable ` | Enable an agent skill | `gemini skills enable my-skill` | | `gemini skills disable ` | Disable an agent skill | `gemini skills disable my-skill` | | `gemini skills enable --all` | Enable all skills | `gemini skills enable --all` | | `gemini skills disable --all` | Disable all skills | `gemini skills disable --all` | See [Agent Skills Documentation](/docs/cli/skills) for more details. # [Gemini CLI for the enterprise](http://geminicli.com/docs/cli/enterprise.md) This document outlines configuration patterns and best practices for deploying and managing Gemini CLI in an enterprise environment. By leveraging system-level settings, administrators can enforce security policies, manage tool access, and ensure a consistent experience for all users. > [!WARNING] > The patterns described in this document are intended to help > administrators create a more controlled and secure environment for using > Gemini CLI. However, they should not be considered a foolproof security > boundary. A determined user with sufficient privileges on their local machine > may still be able to circumvent these configurations. These measures are > designed to prevent accidental misuse and enforce corporate policy in a > managed environment, not to defend against a malicious actor with local > administrative rights. ## Centralized configuration: The system settings file The most powerful tools for enterprise administration are the system-wide settings files. These files allow you to define a baseline configuration (`system-defaults.json`) and a set of overrides (`settings.json`) that apply to all users on a machine. For a complete overview of configuration options, see the [Configuration documentation](/docs/reference/configuration). Settings are merged from four files. The precedence order for single-value settings (like `theme`) is: 1. System Defaults (`system-defaults.json`) 2. User Settings (`~/.gemini/settings.json`) 3. Workspace Settings (`/.gemini/settings.json`) 4. System Overrides (`settings.json`) This means the System Overrides file has the final say. For settings that are arrays (`includeDirectories`) or objects (`mcpServers`), the values are merged. **Example of merging and precedence:** Here is how settings from different levels are combined. - **System defaults `system-defaults.json`:** ```json { "ui": { "theme": "default-corporate-theme" }, "context": { "includeDirectories": ["/etc/gemini-cli/common-context"] } } ``` - **User `settings.json` (`~/.gemini/settings.json`):** ```json { "ui": { "theme": "user-preferred-dark-theme" }, "mcpServers": { "corp-server": { "command": "/usr/local/bin/corp-server-dev" }, "user-tool": { "command": "npm start --prefix ~/tools/my-tool" } }, "context": { "includeDirectories": ["~/gemini-context"] } } ``` - **Workspace `settings.json` (`/.gemini/settings.json`):** ```json { "ui": { "theme": "project-specific-light-theme" }, "mcpServers": { "project-tool": { "command": "npm start" } }, "context": { "includeDirectories": ["./project-context"] } } ``` - **System overrides `settings.json`:** ```json { "ui": { "theme": "system-enforced-theme" }, "mcpServers": { "corp-server": { "command": "/usr/local/bin/corp-server-prod" } }, "context": { "includeDirectories": ["/etc/gemini-cli/global-context"] } } ``` This results in the following merged configuration: - **Final merged configuration:** ```json { "ui": { "theme": "system-enforced-theme" }, "mcpServers": { "corp-server": { "command": "/usr/local/bin/corp-server-prod" }, "user-tool": { "command": "npm start --prefix ~/tools/my-tool" }, "project-tool": { "command": "npm start" } }, "context": { "includeDirectories": [ "/etc/gemini-cli/common-context", "~/gemini-context", "./project-context", "/etc/gemini-cli/global-context" ] } } ``` **Why:** - **`theme`**: The value from the system overrides (`system-enforced-theme`) is used, as it has the highest precedence. - **`mcpServers`**: The objects are merged. The `corp-server` definition from the system overrides takes precedence over the user's definition. The unique `user-tool` and `project-tool` are included. - **`includeDirectories`**: The arrays are concatenated in the order of System Defaults, User, Workspace, and then System Overrides. - **Location**: - **Linux**: `/etc/gemini-cli/settings.json` - **Windows**: `C:\ProgramData\gemini-cli\settings.json` - **macOS**: `/Library/Application Support/GeminiCli/settings.json` - The path can be overridden using the `GEMINI_CLI_SYSTEM_SETTINGS_PATH` environment variable. - **Control**: This file should be managed by system administrators and protected with appropriate file permissions to prevent unauthorized modification by users. By using the system settings file, you can enforce the security and configuration patterns described below. ### Enforcing system settings with a wrapper script While the `GEMINI_CLI_SYSTEM_SETTINGS_PATH` environment variable provides flexibility, a user could potentially override it to point to a different settings file, bypassing the centrally managed configuration. To mitigate this, enterprises can deploy a wrapper script or alias that ensures the environment variable is always set to the corporate-controlled path. This approach ensures that no matter how the user calls the `gemini` command, the enterprise settings are always loaded with the highest precedence. **Example wrapper script:** Administrators can create a script named `gemini` and place it in a directory that appears earlier in the user's `PATH` than the actual Gemini CLI binary (for example, `/usr/local/bin/gemini`). ```bash #!/bin/bash # Enforce the path to the corporate system settings file. # This ensures that the company's configuration is always applied. export GEMINI_CLI_SYSTEM_SETTINGS_PATH="/etc/gemini-cli/settings.json" # Find the original gemini executable. # This is a simple example; a more robust solution might be needed # depending on the installation method. REAL_GEMINI_PATH=$(type -aP gemini | grep -v "^$(type -P gemini)$" | head -n 1) if [ -z "$REAL_GEMINI_PATH" ]; then echo "Error: The original 'gemini' executable was not found." >&2 exit 1 fi # Pass all arguments to the real Gemini CLI executable. exec "$REAL_GEMINI_PATH" "$@" ``` By deploying this script, the `GEMINI_CLI_SYSTEM_SETTINGS_PATH` is set within the script's environment, and the `exec` command replaces the script process with the actual Gemini CLI process, which inherits the environment variable. This makes it significantly more difficult for a user to bypass the enforced settings. **PowerShell Profile (Windows alternative):** On Windows, administrators can achieve similar results by adding the environment variable to the system-wide or user-specific PowerShell profile: ```powershell Add-Content -Path $PROFILE -Value '$env:GEMINI_CLI_SYSTEM_SETTINGS_PATH="C:\ProgramData\gemini-cli\settings.json"' ``` ## User isolation in shared environments In shared compute environments (like ML experiment runners or shared build servers), you can isolate Gemini CLI state by overriding the user's home directory. By default, Gemini CLI stores configuration and history in `~/.gemini`. You can use the `GEMINI_CLI_HOME` environment variable to point to a unique directory for a specific user or job. The CLI will create a `.gemini` folder inside the specified path. **macOS/Linux** ```bash # Isolate state for a specific job export GEMINI_CLI_HOME="/tmp/gemini-job-123" gemini ``` **Windows (PowerShell)** ```powershell # Isolate state for a specific job $env:GEMINI_CLI_HOME="C:\temp\gemini-job-123" gemini ``` ## Restricting tool access You can significantly enhance security by controlling which tools the Gemini model can use. This is achieved through the `tools.core` setting and the [Policy Engine](/docs/reference/policy-engine). For a list of available tools, see the [Tools reference](/docs/reference/tools). ### Allowlisting with `coreTools` The most secure approach is to explicitly add the tools and commands that users are permitted to execute to an allowlist. This prevents the use of any tool not on the approved list. **Example:** Allow only safe, read-only file operations and listing files. ```json { "tools": { "core": ["ReadFileTool", "GlobTool", "ShellTool(ls)"] } } ``` ### Blocklisting with `excludeTools` (Deprecated) > **Deprecated:** Use the [Policy Engine](/docs/reference/policy-engine) for > more robust control. Alternatively, you can add specific tools that are considered dangerous in your environment to a blocklist. **Example:** Prevent the use of the shell tool for removing files. ```json { "tools": { "exclude": ["ShellTool(rm -rf)"] } } ``` > [!WARNING] > Blocklisting with `excludeTools` is less secure than > allowlisting with `tools.core`, as it relies on blocking known-bad commands, > and clever users may find ways to bypass simple string-based blocks. > **Allowlisting is the recommended approach.** ### Disabling YOLO mode To ensure that users cannot bypass the confirmation prompt for tool execution, you can disable YOLO mode at the policy level. This adds a critical layer of safety, as it prevents the model from executing tools without explicit user approval. **Example:** Force all tool executions to require user confirmation. ```json { "security": { "disableYoloMode": true } } ``` This setting is highly recommended in an enterprise environment to prevent unintended tool execution. ## Managing custom tools (MCP servers) If your organization uses custom tools via [Model-Context Protocol (MCP) servers](/docs/tools/mcp-server), it is crucial to understand how server configurations are managed to apply security policies effectively. ### How MCP server configurations are merged Gemini CLI loads `settings.json` files from three levels: System, Workspace, and User. When it comes to the `mcpServers` object, these configurations are **merged**: 1. **Merging:** The lists of servers from all three levels are combined into a single list. 2. **Precedence:** If a server with the **same name** is defined at multiple levels (for example, a server named `corp-api` exists in both system and user settings), the definition from the highest-precedence level is used. The order of precedence is: **System > Workspace > User**. This means a user **cannot** override the definition of a server that is already defined in the system-level settings. However, they **can** add new servers with unique names. ### Enforcing a catalog of tools The security of your MCP tool ecosystem depends on a combination of defining the canonical servers and adding their names to an allowlist. ### Restricting tools within an MCP server For even greater security, especially when dealing with third-party MCP servers, you can restrict which specific tools from a server are exposed to the model. This is done using the `includeTools` and `excludeTools` properties within a server's definition. This lets you use a subset of tools from a server without allowing potentially dangerous ones. Following the principle of least privilege, it is highly recommended to use `includeTools` to create an allowlist of only the necessary tools. **Example:** Only allow the `code-search` and `get-ticket-details` tools from a third-party MCP server, even if the server offers other tools like `delete-ticket`. ```json { "mcp": { "allowed": ["third-party-analyzer"] }, "mcpServers": { "third-party-analyzer": { "command": "/usr/local/bin/start-3p-analyzer.sh", "includeTools": ["code-search", "get-ticket-details"] } } } ``` #### More secure pattern: Define and add to allowlist in system settings To create a secure, centrally-managed catalog of tools, the system administrator **must** do both of the following in the system-level `settings.json` file: 1. **Define the full configuration** for every approved server in the `mcpServers` object. This ensures that even if a user defines a server with the same name, the secure system-level definition will take precedence. 2. **Add the names** of those servers to an allowlist using the `mcp.allowed` setting. This is a critical security step that prevents users from running any servers that are not on this list. If this setting is omitted, the CLI will merge and allow any server defined by the user. **Example system `settings.json`:** 1. Add the _names_ of all approved servers to an allowlist. This will prevent users from adding their own servers. 2. Provide the canonical _definition_ for each server on the allowlist. ```json { "mcp": { "allowed": ["corp-data-api", "source-code-analyzer"] }, "mcpServers": { "corp-data-api": { "command": "/usr/local/bin/start-corp-api.sh", "timeout": 5000 }, "source-code-analyzer": { "command": "/usr/local/bin/start-analyzer.sh" } } } ``` This pattern is more secure because it uses both definition and an allowlist. Any server a user defines will either be overridden by the system definition (if it has the same name) or blocked because its name is not in the `mcp.allowed` list. ### Less secure pattern: Omitting the allowlist If the administrator defines the `mcpServers` object but fails to also specify the `mcp.allowed` allowlist, users may add their own servers. **Example system `settings.json`:** This configuration defines servers but does not enforce the allowlist. The administrator has NOT included the "mcp.allowed" setting. ```json { "mcpServers": { "corp-data-api": { "command": "/usr/local/bin/start-corp-api.sh" } } } ``` In this scenario, a user can add their own server in their local `settings.json`. Because there is no `mcp.allowed` list to filter the merged results, the user's server will be added to the list of available tools and allowed to run. ## Enforcing sandboxing for security To mitigate the risk of potentially harmful operations, you can enforce the use of sandboxing for all tool execution. The sandbox isolates tool execution in a containerized environment. **Example:** Force all tool execution to happen within a Docker sandbox. ```json { "tools": { "sandbox": "docker" } } ``` You can also specify a custom, hardened Docker image for the sandbox by building a custom `sandbox.Dockerfile` as described in the [Sandboxing documentation](/docs/cli/sandbox). ## Controlling network access via proxy In corporate environments with strict network policies, you can configure Gemini CLI to route all outbound traffic through a corporate proxy. This can be set via an environment variable, but it can also be enforced for custom tools via the `mcpServers` configuration. **Example (for an MCP server):** ```json { "mcpServers": { "proxied-server": { "command": "node", "args": ["mcp_server.js"], "env": { "HTTP_PROXY": "http://proxy.example.com:8080", "HTTPS_PROXY": "http://proxy.example.com:8080" } } } } ``` ## Telemetry and auditing For auditing and monitoring purposes, you can configure Gemini CLI to send telemetry data to a central location. This lets you track tool usage and other events. For more information, see the [telemetry documentation](/docs/cli/telemetry). **Example:** Enable telemetry and send it to a local OTLP collector. If `otlpEndpoint` is not specified, it defaults to `http://localhost:4317`. ```json { "telemetry": { "enabled": true, "target": "gcp", "logPrompts": false } } ``` > [!NOTE] > Ensure that `logPrompts` is set to `false` in an enterprise setting to > avoid collecting potentially sensitive information from user prompts. ## Authentication You can enforce a specific authentication method for all users by setting the `security.auth.enforcedType` in the system-level `settings.json` file. This prevents users from choosing a different authentication method. See the [Authentication docs](/docs/get-started/authentication) for more details. **Example:** Enforce the use of Google login for all users. ```json { "security": { "auth": { "enforcedType": "oauth-personal" } } } ``` If a user has a different authentication method configured, they will be prompted to switch to the enforced method. In non-interactive mode, the CLI will exit with an error if the configured authentication method does not match the enforced one. ### Restricting logins to corporate domains For enterprises using Google Workspace, you can enforce that users only authenticate with their corporate Google accounts. This is a network-level control that is configured on a proxy server, not within Gemini CLI itself. It works by intercepting authentication requests to Google and adding a special HTTP header. This policy prevents users from logging in with personal Gmail accounts or other non-corporate Google accounts. For detailed instructions, see the Google Workspace Admin Help article on [blocking access to consumer accounts](https://support.google.com/a/answer/1668854?hl=en#zippy=%2Cstep-choose-a-web-proxy-server%2Cstep-configure-the-network-to-block-certain-accounts). The general steps are as follows: 1. **Intercept Requests**: Configure your web proxy to intercept all requests to `google.com`. 2. **Add HTTP Header**: For each intercepted request, add the `X-GoogApps-Allowed-Domains` HTTP header. 3. **Specify Domains**: The value of the header should be a comma-separated list of your approved Google Workspace domain names. **Example header:** ``` X-GoogApps-Allowed-Domains: my-corporate-domain.com, secondary-domain.com ``` When this header is present, Google's authentication service will only allow logins from accounts belonging to the specified domains. ## Putting it all together: example system `settings.json` Here is an example of a system `settings.json` file that combines several of the patterns discussed above to create a secure, controlled environment for Gemini CLI. ```json { "tools": { "sandbox": "docker", "core": [ "ReadFileTool", "GlobTool", "ShellTool(ls)", "ShellTool(cat)", "ShellTool(grep)" ] }, "mcp": { "allowed": ["corp-tools"] }, "mcpServers": { "corp-tools": { "command": "/opt/gemini-tools/start.sh", "timeout": 5000 } }, "telemetry": { "enabled": true, "target": "gcp", "otlpEndpoint": "https://telemetry-prod.example.com:4317", "logPrompts": false }, "advanced": { "bugCommand": { "urlTemplate": "https://servicedesk.example.com/new-ticket?title={title}&details={info}" } }, "privacy": { "usageStatisticsEnabled": false } } ``` This configuration: - Forces all tool execution into a Docker sandbox. - Strictly uses an allowlist for a small set of safe shell commands and file tools. - Defines and allows a single corporate MCP server for custom tools. - Enables telemetry for auditing, without logging prompt content. - Redirects the `/bug` command to an internal ticketing system. - Disables general usage statistics collection. # [Custom commands](http://geminicli.com/docs/cli/custom-commands.md) Custom commands let you save and reuse your favorite or most frequently used prompts as personal shortcuts within Gemini CLI. You can create commands that are specific to a single project or commands that are available globally across all your projects, streamlining your workflow and ensuring consistency. ## File locations and precedence Gemini CLI discovers commands from two locations, loaded in a specific order: 1. **User commands (global):** Located in `~/.gemini/commands/`. These commands are available in any project you are working on. 2. **Project commands (local):** Located in `/.gemini/commands/`. These commands are specific to the current project and can be checked into version control to be shared with your team. If a command in the project directory has the same name as a command in the user directory, the **project command will always be used.** This allows projects to override global commands with project-specific versions. ## Naming and namespacing The name of a command is determined by its file path relative to its `commands` directory. Subdirectories are used to create namespaced commands, with the path separator (`/` or `\`) being converted to a colon (`:`). - A file at `~/.gemini/commands/test.toml` becomes the command `/test`. - A file at `/.gemini/commands/git/commit.toml` becomes the namespaced command `/git:commit`. > [!TIP] > After creating or modifying `.toml` command files, run > `/commands reload` to pick up your changes without restarting the CLI. > To see all available command files, run `/commands list`. ## TOML file format (v1) Your command definition files must be written in the TOML format and use the `.toml` file extension. ### Required fields - `prompt` (String): The prompt that will be sent to the Gemini model when the command is executed. This can be a single-line or multi-line string. ### Optional fields - `description` (String): A brief, one-line description of what the command does. This text will be displayed next to your command in the `/help` menu. **If you omit this field, a generic description will be generated from the filename.** ## Handling arguments Custom commands support two powerful methods for handling arguments. The CLI automatically chooses the correct method based on the content of your command's `prompt`. ### 1. Context-aware injection with `{{args}}` If your `prompt` contains the special placeholder `{{args}}`, the CLI will replace that placeholder with the text the user typed after the command name. The behavior of this injection depends on where it is used: **A. Raw injection (outside shell commands)** When used in the main body of the prompt, the arguments are injected exactly as the user typed them. **Example (`git/fix.toml`):** ```toml # Invoked via: /git:fix "Button is misaligned" description = "Generates a fix for a given issue." prompt = "Please provide a code fix for the issue described here: {{args}}." ``` The model receives: `Please provide a code fix for the issue described here: "Button is misaligned".` **B. Using arguments in shell commands (inside `!{...}` blocks)** When you use `{{args}}` inside a shell injection block (`!{...}`), the arguments are automatically **shell-escaped** before replacement. This lets you safely pass arguments to shell commands, ensuring the resulting command is syntactically correct and secure while preventing command injection vulnerabilities. **Example (`/grep-code.toml`):** ```toml prompt = """ Please summarize the findings for the pattern `{{args}}`. Search Results: !{grep -r {{args}} .} """ ``` When you run `/grep-code It's complicated`: 1. The CLI sees `{{args}}` used both outside and inside `!{...}`. 2. Outside: The first `{{args}}` is replaced raw with `It's complicated`. 3. Inside: The second `{{args}}` is replaced with the escaped version (for example, on Linux: `"It\'s complicated"`). 4. The command executed is `grep -r "It's complicated" .`. 5. The CLI prompts you to confirm this exact, secure command before execution. 6. The final prompt is sent. ### 2. Default argument handling If your `prompt` does **not** contain the special placeholder `{{args}}`, the CLI uses a default behavior for handling arguments. If you provide arguments to the command (for example, `/mycommand arg1`), the CLI will append the full command you typed to the end of the prompt, separated by two newlines. This allows the model to see both the original instructions and the specific arguments you just provided. If you do **not** provide any arguments (for example, `/mycommand`), the prompt is sent to the model exactly as it is, with nothing appended. **Example (`changelog.toml`):** This example shows how to create a robust command by defining a role for the model, explaining where to find the user's input, and specifying the expected format and behavior. ```toml # In: /.gemini/commands/changelog.toml # Invoked via: /changelog 1.2.0 added "Support for default argument parsing." description = "Adds a new entry to the project's CHANGELOG.md file." prompt = """ # Task: Update Changelog You are an expert maintainer of this software project. A user has invoked a command to add a new entry to the changelog. **The user's raw command is appended below your instructions.** Your task is to parse the ``, ``, and `` from their input and use the `write_file` tool to correctly update the `CHANGELOG.md` file. ## Expected Format The command follows this format: `/changelog ` - `` must be one of: "added", "changed", "fixed", "removed". ## Behavior 1. Read the `CHANGELOG.md` file. 2. Find the section for the specified ``. 3. Add the `` under the correct `` heading. 4. If the version or type section doesn't exist, create it. 5. Adhere strictly to the "Keep a Changelog" format. """ ``` When you run `/changelog 1.2.0 added "New feature"`, the final text sent to the model will be the original prompt followed by two newlines and the command you typed. ### 3. Executing shell commands with `!{...}` You can make your commands dynamic by executing shell commands directly within your `prompt` and injecting their output. This is ideal for gathering context from your local environment, like reading file content or checking the status of Git. When a custom command attempts to execute a shell command, Gemini CLI will now prompt you for confirmation before proceeding. This is a security measure to ensure that only intended commands can be run. **How it works:** 1. **Inject commands:** Use the `!{...}` syntax. 2. **Argument substitution:** If `{{args}}` is present inside the block, it is automatically shell-escaped (see [Context-Aware Injection](#1-context-aware-injection-with-args) above). 3. **Robust parsing:** The parser correctly handles complex shell commands that include nested braces, such as JSON payloads. The content inside `!{...}` must have balanced braces (`{` and `}`). If you need to execute a command containing unbalanced braces, consider wrapping it in an external script file and calling the script within the `!{...}` block. 4. **Security check and confirmation:** The CLI performs a security check on the final, resolved command (after arguments are escaped and substituted). A dialog will appear showing the exact command(s) to be executed. 5. **Execution and error reporting:** The command is executed. If the command fails, the output injected into the prompt will include the error messages (stderr) followed by a status line, for example, `[Shell command exited with code 1]`. This helps the model understand the context of the failure. **Example (`git/commit.toml`):** This command gets the staged git diff and uses it to ask the model to write a commit message. ````toml # In: /.gemini/commands/git/commit.toml # Invoked via: /git:commit description = "Generates a Git commit message based on staged changes." # The prompt uses !{...} to execute the command and inject its output. prompt = """ Please generate a Conventional Commit message based on the following git diff: ```diff !{git diff --staged} ``` """ ```` When you run `/git:commit`, the CLI first executes `git diff --staged`, then replaces `!{git diff --staged}` with the output of that command before sending the final, complete prompt to the model. ### 4. Injecting file content with `@{...}` You can directly embed the content of a file or a directory listing into your prompt using the `@{...}` syntax. This is useful for creating commands that operate on specific files. **How it works:** - **File injection**: `@{path/to/file.txt}` is replaced by the content of `file.txt`. - **Multimodal support**: If the path points to a supported image (for example, PNG, JPEG), PDF, audio, or video file, it will be correctly encoded and injected as multimodal input. Other binary files are handled gracefully and skipped. - **Directory listing**: `@{path/to/dir}` is traversed and each file present within the directory and all subdirectories is inserted into the prompt. This respects `.gitignore` and `.geminiignore` if enabled. - **Workspace-aware**: The command searches for the path in the current directory and any other workspace directories. Absolute paths are allowed if they are within the workspace. - **Processing order**: File content injection with `@{...}` is processed _before_ shell commands (`!{...}`) and argument substitution (`{{args}}`). - **Parsing**: The parser requires the content inside `@{...}` (the path) to have balanced braces (`{` and `}`). **Example (`review.toml`):** This command injects the content of a _fixed_ best practices file (`docs/best-practices.md`) and uses the user's arguments to provide context for the review. ```toml # In: /.gemini/commands/review.toml # Invoked via: /review FileCommandLoader.ts description = "Reviews the provided context using a best practice guide." prompt = """ You are an expert code reviewer. Your task is to review {{args}}. Use the following best practices when providing your review: @{docs/best-practices.md} """ ``` When you run `/review FileCommandLoader.ts`, the `@{docs/best-practices.md}` placeholder is replaced by the content of that file, and `{{args}}` is replaced by the text you provided, before the final prompt is sent to the model. --- ## Example: A "Pure Function" refactoring command Let's create a global command that asks the model to refactor a piece of code. **1. Create the file and directories:** First, ensure the user commands directory exists, then create a `refactor` subdirectory for organization and the final TOML file. **macOS/Linux** ```bash mkdir -p ~/.gemini/commands/refactor touch ~/.gemini/commands/refactor/pure.toml ``` **Windows (PowerShell)** ```powershell New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\.gemini\commands\refactor" New-Item -ItemType File -Force -Path "$env:USERPROFILE\.gemini\commands\refactor\pure.toml" ``` **2. Add the content to the file:** Open `~/.gemini/commands/refactor/pure.toml` in your editor and add the following content. We are including the optional `description` for best practice. ```toml # In: ~/.gemini/commands/refactor/pure.toml # This command will be invoked via: /refactor:pure description = "Asks the model to refactor the current context into a pure function." prompt = """ Please analyze the code I've provided in the current context. Refactor it into a pure function. Your response should include: 1. The refactored, pure function code block. 2. A brief explanation of the key changes you made and why they contribute to purity. """ ``` **3. Run the command:** That's it! You can now run your command in the CLI. First, you might add a file to the context, and then invoke your command: ``` > @my-messy-function.js > /refactor:pure ``` Gemini CLI will then execute the multi-line prompt defined in your TOML file. # [Ignoring files](http://geminicli.com/docs/cli/gemini-ignore.md) This document provides an overview of the Gemini Ignore (`.geminiignore`) feature of Gemini CLI. Gemini CLI includes the ability to automatically ignore files, similar to `.gitignore` (used by Git) and `.aiexclude` (used by Gemini Code Assist). Adding paths to your `.geminiignore` file will exclude them from tools that support this feature, although they will still be visible to other services (such as Git). ## How it works When you add a path to your `.geminiignore` file, tools that respect this file will exclude matching files and directories from their operations. For example, when you use the `@` command to share files, any paths in your `.geminiignore` file will be automatically excluded. For the most part, `.geminiignore` follows the conventions of `.gitignore` files: - Blank lines and lines starting with `#` are ignored. - Standard glob patterns are supported (such as `*`, `?`, and `[]`). - Putting a `/` at the end will only match directories. - Putting a `/` at the beginning anchors the path relative to the `.geminiignore` file. - `!` negates a pattern. You can update your `.geminiignore` file at any time. To apply the changes, you must restart your Gemini CLI session. ## How to use `.geminiignore` To enable `.geminiignore`: 1. Create a file named `.geminiignore` in the root of your project directory. To add a file or directory to `.geminiignore`: 1. Open your `.geminiignore` file. 2. Add the path or file you want to ignore, for example: `/archive/` or `apikeys.txt`. ### `.geminiignore` examples You can use `.geminiignore` to ignore directories and files: ``` # Exclude your /packages/ directory and all subdirectories /packages/ # Exclude your apikeys.txt file apikeys.txt ``` You can use wildcards in your `.geminiignore` file with `*`: ``` # Exclude all .md files *.md ``` Finally, you can exclude files and directories from exclusion with `!`: ``` # Exclude all .md files except README.md *.md !README.md ``` To remove paths from your `.geminiignore` file, delete the relevant lines. # [Provide context with GEMINI.md files](http://geminicli.com/docs/cli/gemini-md.md) Context files, which use the default name `GEMINI.md`, are a powerful feature for providing instructional context to the Gemini model. You can use these files to give project-specific instructions, define a persona, or provide coding style guides to make the AI's responses more accurate and tailored to your needs. Instead of repeating instructions in every prompt, you can define them once in a context file. ## Understand the context hierarchy The CLI uses a hierarchical system to source context. It loads various context files from several locations, concatenates the contents of all found files, and sends them to the model with every prompt. The CLI loads files in the following order: 1. **Global context file:** - **Location:** `~/.gemini/GEMINI.md` (in your user home directory). - **Scope:** Provides default instructions for all your projects. 2. **Environment and workspace context files:** - **Location:** The CLI searches for `GEMINI.md` files in your configured workspace directories and their parent directories. - **Scope:** Provides context relevant to the projects you are currently working on. 3. **Just-in-time (JIT) context files:** - **Location:** When a tool accesses a file or directory, the CLI automatically scans for `GEMINI.md` files in that directory and its ancestors up to a trusted root. - **Scope:** Lets the model discover highly specific instructions for particular components only when they are needed. The CLI footer displays the number of loaded context files, which gives you a quick visual cue of the active instructional context. ### Example `GEMINI.md` file Here is an example of what you can include in a `GEMINI.md` file at the root of a TypeScript project: ```markdown # Project: My TypeScript Library ## General Instructions - When you generate new TypeScript code, follow the existing coding style. - Ensure all new functions and classes have JSDoc comments. - Prefer functional programming paradigms where appropriate. ## Coding Style - Use 2 spaces for indentation. - Prefix interface names with `I` (for example, `IUserService`). - Always use strict equality (`===` and `!==`). ``` ## Manage context with the `/memory` command You can interact with the loaded context files by using the `/memory` command. - **`/memory show`**: Displays the full, concatenated content of the current hierarchical memory. This lets you inspect the exact instructional context being provided to the model. - **`/memory reload`**: Forces a re-scan and reload of all `GEMINI.md` files from all configured locations. ## Modularize context with imports You can break down large `GEMINI.md` files into smaller, more manageable components by importing content from other files using the `@file.md` syntax. This feature supports both relative and absolute paths. **Example `GEMINI.md` with imports:** ```markdown # Main GEMINI.md file This is the main content. @./components/instructions.md More content here. @../shared/style-guide.md ``` For more details, see the [Memory Import Processor](/docs/reference/memport) documentation. ## Customize the context file name While `GEMINI.md` is the default filename, you can configure this in your `settings.json` file. To specify a different name or a list of names, use the `context.fileName` property. **Example `settings.json`:** ```json { "context": { "fileName": ["AGENTS.md", "CONTEXT.md", "GEMINI.md"] } } ``` ## Next steps - Learn about [Ignoring files](/docs/cli/gemini-ignore) to exclude content from the context system. - Explore the [Memory tool](/docs/tools/memory) to save persistent memories. - See how to use [Custom commands](/docs/cli/custom-commands) to automate common prompts. # [Advanced Model Configuration](http://geminicli.com/docs/cli/generation-settings.md) This guide details the Model Configuration system within Gemini CLI. Designed for researchers, AI quality engineers, and advanced users, this system provides a rigorous framework for managing generative model hyperparameters and behaviors. > [!WARNING] > This is a power-user feature. Configuration values are passed > directly to the model provider with minimal validation. Incorrect settings > (for example, incompatible parameter combinations) may result in runtime > errors from the API. ## 1. System Overview The Model Configuration system (`ModelConfigService`) enables deterministic control over model generation. It decouples the requested model identifier (for example, a CLI flag or agent request) from the underlying API configuration. This allows for: - **Precise Hyperparameter Tuning**: Direct control over `temperature`, `topP`, `thinkingBudget`, and other SDK-level parameters. - **Environment-Specific Behavior**: Distinct configurations for different operating contexts (for example, testing vs. production). - **Agent-Scoped Customization**: Applying specific settings only when a particular agent is active. The system operates on two core primitives: **Aliases** and **Overrides**. ## 2. Configuration Primitives These settings are located under the `modelConfigs` key in your configuration file. ### Aliases (`customAliases`) Aliases are named, reusable configuration presets. Users should define their own aliases (or override system defaults) in the `customAliases` map. - **Inheritance**: An alias can `extends` another alias (including system defaults like `chat-base`), inheriting its `modelConfig`. Child aliases can overwrite or augment inherited settings. - **Abstract Aliases**: An alias is not required to specify a concrete `model` if it serves purely as a base for other aliases. **Example Hierarchy**: ```json "modelConfigs": { "customAliases": { "base": { "modelConfig": { "generateContentConfig": { "temperature": 0.0 } } }, "chat-base": { "extends": "base", "modelConfig": { "generateContentConfig": { "temperature": 0.7 } } } } } ``` ### Overrides (`overrides`) Overrides are conditional rules that inject configuration based on the runtime context. They are evaluated dynamically for each model request. - **Match Criteria**: Overrides apply when the request context matches the specified `match` properties. - `model`: Matches the requested model name or alias. - `overrideScope`: Matches the distinct scope of the request (typically the agent name, for example, `codebaseInvestigator`). **Example Override**: ```json "modelConfigs": { "overrides": [ { "match": { "overrideScope": "codebaseInvestigator" }, "modelConfig": { "generateContentConfig": { "temperature": 0.1 } } } ] } ``` ## 3. Resolution Strategy The `ModelConfigService` resolves the final configuration through a two-step process: ### Step 1: Alias Resolution The requested model string is looked up in the merged map of system `aliases` and user `customAliases`. 1. If found, the system recursively resolves the `extends` chain. 2. Settings are merged from parent to child (child wins). 3. This results in a base `ResolvedModelConfig`. 4. If not found, the requested string is treated as the raw model name. ### Step 2: Override Application The system evaluates the `overrides` list against the request context (`model` and `overrideScope`). 1. **Filtering**: All matching overrides are identified. 2. **Sorting**: Matches are prioritized by **specificity** (the number of matched keys in the `match` object). - Specific matches (for example, `model` + `overrideScope`) override broad matches (for example, `model` only). - Tie-breaking: If specificity is equal, the order of definition in the `overrides` array is preserved (last one wins). 3. **Merging**: The configurations from the sorted overrides are merged sequentially onto the base configuration. ## 4. Configuration Reference The configuration follows the `ModelConfigServiceConfig` interface. ### `ModelConfig` Object Defines the actual parameters for the model. | Property | Type | Description | | :---------------------- | :------- | :------------------------------------------------------------------------ | | `model` | `string` | The identifier of the model to be called (for example, `gemini-2.5-pro`). | | `generateContentConfig` | `object` | The configuration object passed to the `@google/genai` SDK. | ### `GenerateContentConfig` (Common Parameters) Directly maps to the SDK's `GenerateContentConfig`. Common parameters include: - **`temperature`**: (`number`) Controls output randomness. Lower values (0.0) are deterministic; higher values (>0.7) are creative. - **`topP`**: (`number`) Nucleus sampling probability. - **`maxOutputTokens`**: (`number`) Limit on generated response length. - **`thinkingConfig`**: (`object`) Configuration for models with reasoning capabilities (for example, `thinkingBudget`, `includeThoughts`). ## 5. Practical Examples ### Defining a Deterministic Baseline Create an alias for tasks requiring high precision, extending the standard chat configuration but enforcing zero temperature. ```json "modelConfigs": { "customAliases": { "precise-mode": { "extends": "chat-base", "modelConfig": { "generateContentConfig": { "temperature": 0.0, "topP": 1.0 } } } } } ``` ### Agent-Specific Parameter Injection Enforce extended thinking budgets for a specific agent without altering the global default, for example for the `codebaseInvestigator`. ```json "modelConfigs": { "overrides": [ { "match": { "overrideScope": "codebaseInvestigator" }, "modelConfig": { "generateContentConfig": { "thinkingConfig": { "thinkingBudget": 4096 } } } } ] } ``` ### Experimental Model Evaluation Route traffic for a specific alias to a preview model for A/B testing, without changing client code. ```json "modelConfigs": { "overrides": [ { "match": { "model": "gemini-2.5-pro" }, "modelConfig": { "model": "gemini-2.5-pro-experimental-001" } } ] } ``` # [Git Worktrees (experimental)](http://geminicli.com/docs/cli/git-worktrees.md) When working on multiple tasks at once, you can use Git worktrees to give each Gemini session its own copy of the codebase. Git worktrees create separate working directories that each have their own files and branch while sharing the same repository history. This prevents changes in one session from colliding with another. Learn more about [session management](/docs/cli/session-management). > [!NOTE] > This is an experimental feature currently under active development. Your > feedback is invaluable as we refine this feature. If you have ideas, > suggestions, or encounter issues: > > - [Open an issue](https://github.com/google-gemini/gemini-cli/issues/new?template=bug_report.yml) on GitHub. > - Use the **/bug** command within Gemini CLI to file an issue. Learn more in the official Git worktree [documentation](https://git-scm.com/docs/git-worktree). ## How to enable Git worktrees Git worktrees are an experimental feature. You must enable them in your settings using the `/settings` command or by manually editing your `settings.json` file. 1. Use the `/settings` command. 2. Search for and set **Enable Git Worktrees** to `true`. Alternatively, add the following to your `settings.json`: ```json { "experimental": { "worktrees": true } } ``` ## How to use Git worktrees Use the `--worktree` (`-w`) flag to create an isolated worktree and start Gemini CLI in it. - **Start with a specific name:** The value you pass becomes both the directory name (within `.gemini/worktrees/`) and the branch name. ```bash gemini --worktree feature-search ``` - **Start with a random name:** If you omit the name, Gemini generates a random one automatically (for example, `worktree-a1b2c3d4`). ```bash gemini --worktree ``` > [!NOTE] > Remember to initialize your development environment in each new > worktree according to your project's setup. Depending on your stack, this > might include running dependency installation (`npm install`, `yarn`), setting > up virtual environments, or following your project's standard build process. ## How to exit a Git worktree session When you exit a worktree session (using `/quit` or `Ctrl+C`), Gemini leaves the worktree intact so your work is not lost. This includes your uncommitted changes (modified files, staged changes, or untracked files) and any new commits you have made. Gemini prioritizes a fast and safe exit: it **does not automatically delete** your worktree or branch. You are responsible for cleaning up your worktrees manually once you are finished with them. When you exit, Gemini displays instructions on how to resume your work or how to manually remove the worktree if you no longer need it. ## Resuming work in a Git worktree To resume a session in a worktree, navigate to the worktree directory and start Gemini CLI with the `--resume` flag and the session ID: ```bash cd .gemini/worktrees/feature-search gemini --resume ``` ## Managing Git worktrees manually For more control over worktree location and branch configuration, or to clean up a preserved worktree, you can use Git directly: - **Clean up a preserved Git worktree:** ```bash git worktree remove .gemini/worktrees/feature-search --force git branch -D worktree-feature-search ``` - **Create a Git worktree manually:** ```bash git worktree add ../project-feature-search -b feature-search cd ../project-feature-search && gemini ``` [Open an issue]: https://github.com/google-gemini/gemini-cli/issues # [Headless mode reference](http://geminicli.com/docs/cli/headless.md) Headless mode provides a programmatic interface to Gemini CLI, returning structured text or JSON output without an interactive terminal UI. ## Technical reference Headless mode is triggered when the CLI is run in a non-TTY environment or when providing a query with the `-p` (or `--prompt`) flag. ### Output formats You can specify the output format using the `--output-format` flag. #### JSON output Returns a single JSON object containing the response and usage statistics. - **Schema:** - `response`: (string) The model's final answer. - `stats`: (object) Token usage and API latency metrics. - `error`: (object, optional) Error details if the request failed. #### Streaming JSON output Returns a stream of newline-delimited JSON (JSONL) events. - **Event types:** - `init`: Session metadata (session ID, model). - `message`: User and assistant message chunks. - `tool_use`: Tool call requests with arguments. - `tool_result`: Output from executed tools. - `error`: Non-fatal warnings and system errors. - `result`: Final outcome with aggregated statistics and per-model token usage breakdowns. ## Exit codes The CLI returns standard exit codes to indicate the result of the headless execution: - `0`: Success. - `1`: General error or API failure. - `42`: Input error (invalid prompt or arguments). - `53`: Turn limit exceeded. ## Next steps - Follow the [Automation tutorial](/docs/cli/tutorials/automation) for practical scripting examples. - See the [CLI reference](/docs/cli/cli-reference) for all available flags. # [Model steering (experimental)](http://geminicli.com/docs/cli/model-steering.md) Model steering lets you provide real-time guidance and feedback to Gemini CLI while it is actively executing a task. This lets you correct course, add missing context, or skip unnecessary steps without having to stop and restart the agent. > [!NOTE] > This is an experimental feature currently under active development and > may need to be enabled under `/settings`. Model steering is particularly useful during complex [Plan Mode](/docs/cli/plan-mode) workflows or long-running subagent executions where you want to ensure the agent stays on the right track. ## Enabling model steering Model steering is an experimental feature and is disabled by default. You can enable it using the `/settings` command or by updating your `settings.json` file. 1. Type `/settings` in Gemini CLI. 2. Search for **Model Steering**. 3. Set the value to **true**. Alternatively, add the following to your `settings.json`: ```json { "experimental": { "modelSteering": true } } ``` ## Using model steering When model steering is enabled, Gemini CLI treats any text you type while the agent is working as a steering hint. 1. Start a task (for example, "Refactor the database service"). 2. While the agent is working (the spinner is visible), type your feedback in the input box. 3. Press **Enter**. Gemini CLI acknowledges your hint with a brief message and injects it directly into the model's context for the very next turn. The model then re-evaluates its current plan and adjusts its actions accordingly. ### Common use cases You can use steering hints to guide the model in several ways: - **Correcting a path:** "Actually, the utilities are in `src/common/utils`." - **Skipping a step:** "Skip the unit tests for now and just focus on the implementation." - **Adding context:** "The `User` type is defined in `packages/core/types.ts`." - **Redirecting the effort:** "Stop searching the codebase and start drafting the plan now." - **Handling ambiguity:** "Use the existing `Logger` class instead of creating a new one." ## How it works When you submit a steering hint, Gemini CLI performs the following actions: 1. **Immediate acknowledgment:** It uses a small, fast model to generate a one-sentence acknowledgment so you know your hint was received. 2. **Context injection:** It prepends an internal instruction to your hint that tells the main agent to: - Re-evaluate the active plan. - Classify the update (for example, as a new task or extra context). - Apply minimal-diff changes to affected tasks. 3. **Real-time update:** The hint is delivered to the agent at the beginning of its next turn, ensuring the most immediate course correction possible. ## Next steps - Tackle complex tasks with [Plan Mode](/docs/cli/plan-mode). - Build custom [Agent Skills](/docs/cli/skills). # [Gemini CLI model selection (`/model` command)](http://geminicli.com/docs/cli/model.md) Select your Gemini CLI model. The `/model` command lets you configure the model used by Gemini CLI, giving you more control over your results. Use **Pro** models for complex tasks and reasoning, **Flash** models for high speed results, or the (recommended) **Auto** setting to choose the best model for your tasks. > [!NOTE] > The `/model` command (and the `--model` flag) does not override the > model used by sub-agents. Consequently, even when using the `/model` flag you > may see other models used in your model usage reports. ## How to use the `/model` command Use the following command in Gemini CLI: ``` /model ``` Running this command will open a dialog with your options: | Option | Description | Models | | ----------------- | -------------------------------------------------------------- | -------------------------------------------- | | Auto (Gemini 3) | Let the system choose the best Gemini 3 model for your task. | gemini-3-pro-preview, gemini-3-flash-preview | | Auto (Gemini 2.5) | Let the system choose the best Gemini 2.5 model for your task. | gemini-2.5-pro, gemini-2.5-flash | | Manual | Select a specific model. | Any available model. | We recommend selecting one of the above **Auto** options. However, you can select **Manual** to select a specific model from those available. You can also use the `--model` flag to specify a particular Gemini model on startup. For more details, refer to the [configuration documentation](/docs/reference/configuration). Changes to these settings will be applied to all subsequent interactions with Gemini CLI. ## Best practices for model selection - **Default to Auto.** For most users, the _Auto_ option model provides a balance between speed and performance, automatically selecting the correct model based on the complexity of the task. Example: Developing a web application could include a mix of complex tasks (building architecture and scaffolding the project) and simple tasks (generating CSS). - **Switch to Pro if you aren't getting the results you want.** If you think you need your model to be a little "smarter," you can manually select Pro. Pro will provide you with the highest levels of reasoning and creativity. Example: A complex or multi-stage debugging task. - **Switch to Flash or Flash-Lite if you need faster results.** If you need a simple response quickly, Flash or Flash-Lite is the best option. Example: Converting a JSON object to a YAML string. # [Model routing](http://geminicli.com/docs/cli/model-routing.md) Gemini CLI includes a model routing feature that automatically switches to a fallback model in case of a model failure. This feature is enabled by default and provides resilience when the primary model is unavailable. ## How it works Model routing is managed by the `ModelAvailabilityService`, which monitors model health and automatically routes requests to available models based on defined policies. 1. **Model failure:** If the currently selected model fails (for example, due to quota or server errors), the CLI will initiate the fallback process. 2. **User consent:** Depending on the failure and the model's policy, the CLI may prompt you to switch to a fallback model (by default always prompts you). Some internal utility calls (such as prompt completion and classification) use a silent fallback chain for `gemini-2.5-flash-lite` and will fall back to `gemini-2.5-flash` and `gemini-2.5-pro` without prompting or changing the configured model. 3. **Model switch:** If approved, or if the policy allows for silent fallback, the CLI will use an available fallback model for the current turn or the remainder of the session. ### Local Model Routing (Experimental) Gemini CLI supports using a local model for routing decisions. When configured, Gemini CLI will use a locally-running **Gemma** model to make routing decisions (instead of sending routing decisions to a hosted model). This feature can help reduce costs associated with hosted model usage while offering similar routing decision latency and quality. The easiest way to set this up is using the automated `gemini gemma setup` command. For more details on how to configure local model routing, see [`gemini gemma` β€” Local Model Routing Setup](/docs/core/gemma-setup). ### Model selection precedence The model used by Gemini CLI is determined by the following order of precedence: 1. **`--model` command-line flag:** A model specified with the `--model` flag when launching the CLI will always be used. 2. **`GEMINI_MODEL` environment variable:** If the `--model` flag is not used, the CLI will use the model specified in the `GEMINI_MODEL` environment variable. 3. **`model.name` in `settings.json`:** If neither of the above are set, the model specified in the `model.name` property of your `settings.json` file will be used. 4. **Local model (experimental):** If the Gemma local model router is enabled in your `settings.json` file, the CLI will use the local Gemma model (instead of Gemini models) to route the request to an appropriate model. 5. **Default model:** If none of the above are set, the default model will be used. The default model is `auto` # [Notifications (experimental)](http://geminicli.com/docs/cli/notifications.md) Gemini CLI can send system notifications to alert you when a session completes or when it needs your attention, such as when it's waiting for you to approve a tool call. > [!NOTE] > This is an experimental feature currently under active development and > may need to be enabled under `/settings`. Notifications are particularly useful when running long-running tasks or using [Plan Mode](/docs/cli/plan-mode), letting you switch to other windows while Gemini CLI works in the background. ## Requirements ### Terminal support The CLI uses the OSC 9 terminal escape sequence to trigger system notifications. This is supported by several modern terminal emulators including iTerm2, WezTerm, Ghostty, and Kitty. If your terminal does not support OSC 9 notifications, Gemini CLI falls back to a terminal bell (BEL) to get your attention. Most terminals respond to BEL with a taskbar flash or system alert sound. ## Enable notifications Notifications are disabled by default. You can enable them using the `/settings` command or by updating your `settings.json` file. 1. Open the settings dialog by typing `/settings` in an interactive session. 2. Navigate to the **General** category. 3. Toggle the **Enable Notifications** setting to **On**. Alternatively, add the following to your `settings.json`: ```json { "general": { "enableNotifications": true } } ``` ## Types of notifications Gemini CLI sends notifications for the following events: - **Action required:** Triggered when the model is waiting for user input or tool approval. This helps you know when the CLI has paused and needs you to intervene. - **Session complete:** Triggered when a session finishes successfully. This is useful for tracking the completion of automated tasks. ## Next steps - Start planning with [Plan Mode](/docs/cli/plan-mode). - Configure your experience with other [settings](/docs/cli/settings). # [Plan Mode](http://geminicli.com/docs/cli/plan-mode.md) Plan Mode is a read-only environment for architecting robust solutions before implementation. With Plan Mode, you can: - **Research:** Explore the project in a read-only state to prevent accidental changes. - **Design:** Understand problems, evaluate trade-offs, and choose a solution. - **Plan:** Align on an execution strategy before any code is modified. Plan Mode is enabled by default. You can manage this setting using the `/settings` command. ## How to enter Plan Mode Plan Mode integrates seamlessly into your workflow, letting you switch between planning and execution as needed. You can either configure Gemini CLI to start in Plan Mode by default or enter Plan Mode manually during a session. ### Launch in Plan Mode To start Gemini CLI directly in Plan Mode by default: 1. Use the `/settings` command. 2. Set **Default Approval Mode** to `Plan`. To launch Gemini CLI in Plan Mode once: 1. Use `gemini --approval-mode=plan` when launching Gemini CLI. ### Enter Plan Mode manually To start Plan Mode while using Gemini CLI: - **Keyboard shortcut:** Press `Shift+Tab` to cycle through approval modes (`Default` -> `Auto-Edit` -> `Plan`). Plan Mode is automatically removed from the rotation when Gemini CLI is actively processing or showing confirmation dialogs. - **Command:** Type `/plan [goal]` in the input box. The `[goal]` is optional; for example, `/plan implement authentication` will switch to Plan Mode and immediately submit the prompt to the model. - **Natural Language:** Ask Gemini CLI to "start a plan for...". Gemini CLI calls the [`enter_plan_mode`](/docs/tools/planning#1-enter_plan_mode-enterplanmode) tool to switch modes. This tool is not available when Gemini CLI is in [YOLO mode](/docs/reference/configuration#command-line-arguments). ## How to use Plan Mode Plan Mode lets you collaborate with Gemini CLI to design a solution before Gemini CLI takes action. 1. **Provide a goal:** Start by describing what you want to achieve. Gemini CLI will then enter Plan Mode (if it's not already) to research the task. 2. **Discuss and agree on strategy:** As Gemini CLI analyzes your codebase, it will discuss its findings and proposed strategy with you to ensure alignment. It may ask you questions or present different implementation options using [`ask_user`](/docs/tools/ask-user). **Gemini CLI will stop and wait for your confirmation** before drafting the formal plan. You should reach an informal agreement on the approach before proceeding. 3. **Review the plan:** Once you've agreed on the strategy, Gemini CLI creates a detailed implementation plan as a Markdown file in your plans directory. - **View:** You can open and read this file to understand the proposed changes. - **Edit:** Press `Ctrl+X` to open the plan directly in your configured external editor. 4. **Approve or iterate:** Gemini CLI will present the finalized plan for your formal approval. - **Approve:** If you're satisfied with the plan, approve it to start the implementation immediately: **Yes, automatically accept edits** or **Yes, manually accept edits**. - **Iterate:** If the plan needs adjustments, provide feedback in the input box or [edit the plan file directly](#collaborative-plan-editing). Gemini CLI will refine the strategy and update the plan. - **Cancel:** You can cancel your plan with `Esc`. For more complex or specialized planning tasks, you can [customize the planning workflow with skills](#custom-planning-with-skills). ### Collaborative plan editing You can collaborate with Gemini CLI by making direct changes or leaving comments in the implementation plan. This is often faster and more precise than describing complex changes in natural language. 1. **Open the plan:** Press `Ctrl+X` when Gemini CLI presents a plan for review. 2. **Edit or comment:** The plan opens in your configured external editor (for example, VS Code or Vim). You can: - **Modify steps:** Directly reorder, delete, or rewrite implementation steps. - **Leave comments:** Add inline questions or feedback (for example, "Wait, shouldn't we use the existing `Logger` class here?"). 3. **Save and close:** Save your changes and close the editor. 4. **Review and refine:** Gemini CLI automatically detects the changes, reviews your comments, and adjusts the implementation strategy. It then presents the refined plan for your final approval. ## How to exit Plan Mode You can exit Plan Mode at any time, whether you have finalized a plan or want to switch back to another mode. - **Approve a plan:** When Gemini CLI presents a finalized plan, approving it automatically exits Plan Mode and starts the implementation. - **Keyboard shortcut:** Press `Shift+Tab` to cycle to the desired mode. - **Natural language:** Ask Gemini CLI to "exit plan mode" or "stop planning." ## Tool Restrictions Plan Mode enforces strict safety policies to prevent accidental changes. These are the only allowed tools: - **FileSystem (Read):** [`read_file`](/docs/tools/file-system#2-read_file-readfile), [`list_directory`](/docs/tools/file-system#1-list_directory-readfolder), [`glob`](/docs/tools/file-system#4-glob-findfiles) - **Search:** [`grep_search`](/docs/tools/file-system#5-grep_search-searchtext), [`google_web_search`](/docs/tools/web-search), [`web_fetch`](/docs/tools/web-fetch) (requires explicit confirmation), [`get_internal_docs`](/docs/tools/internal-docs) - **Research Subagents:** [`codebase_investigator`](/docs/core/subagents#codebase-investigator), [`cli_help`](/docs/core/subagents#cli-help-agent) - **Interaction:** [`ask_user`](/docs/tools/ask-user) - **MCP tools (Read):** Read-only [MCP tools](/docs/tools/mcp-server) (for example, `github_read_issue`, `postgres_read_schema`) and core [MCP resource tools](/docs/tools/mcp-resources) (`list_mcp_resources`, `read_mcp_resource`) are allowed. - **Planning (Write):** [`write_file`](/docs/tools/file-system#3-write_file-writefile) and [`replace`](/docs/tools/file-system#6-replace-edit) only allowed for `.md` files in the `~/.gemini/tmp///plans/` directory or your [custom plans directory](#custom-plan-directory-and-policies). - **Skills:** [`activate_skill`](/docs/cli/skills) (allows loading specialized instructions and resources in a read-only manner) ## Customization and best practices Plan Mode is secure by default, but you can adapt it to fit your specific workflows. You can customize how Gemini CLI plans by using skills, adjusting safety policies, changing where plans are stored, or adding hooks. ### Custom planning with skills You can use [Agent Skills](/docs/cli/skills) to customize how Gemini CLI approaches planning for specific types of tasks. When a skill is activated during Plan Mode, its specialized instructions and procedural workflows will guide the research, design, and planning phases. For example: - A **"Database Migration"** skill could ensure the plan includes data safety checks and rollback strategies. - A **"Security Audit"** skill could prompt Gemini CLI to look for specific vulnerabilities during codebase exploration. - A **"Frontend Design"** skill could guide Gemini CLI to use specific UI components and accessibility standards in its proposal. To use a skill in Plan Mode, you can explicitly ask Gemini CLI to "use the `` skill to plan..." or Gemini CLI may autonomously activate it based on the task description. ### Custom policies Plan Mode's default tool restrictions are managed by the [policy engine](/docs/reference/policy-engine) and defined in the built-in [`plan.toml`] file. The built-in policy (Tier 1) enforces the read-only state, but you can customize these rules by creating your own policies in your `~/.gemini/policies/` directory (Tier 2). #### Global vs. mode-specific rules As described in the [policy engine documentation](/docs/reference/policy-engine#approval-modes), any rule that does not explicitly specify `modes` is considered "always active" and will apply to Plan Mode as well. To maintain the integrity of Plan Mode as a safe research environment, persistent tool approvals are context-aware. Approvals granted in modes like Default or Auto-Edit do not apply to Plan Mode, ensuring that tools trusted for implementation don't automatically execute while you're researching. However, approvals granted while in Plan Mode are treated as intentional choices for global trust and apply to all modes. If you want to manually restrict a rule to other modes but _not_ to Plan Mode, you must explicitly specify the target modes. For example, to allow `npm test` in default and Auto-Edit modes but not in Plan Mode: ```toml [[rule]] toolName = "run_shell_command" commandPrefix = "npm test" decision = "allow" priority = 100 # By omitting "plan", this rule will not be active in Plan Mode. modes = ["default", "autoEdit"] ``` #### Example: Automatically approve read-only MCP tools By default, read-only MCP tools require user confirmation in Plan Mode. You can use `toolAnnotations` and the `mcpName` wildcard to customize this behavior for your specific environment. `~/.gemini/policies/mcp-read-only.toml` ```toml [[rule]] toolName = "*" mcpName = "*" toolAnnotations = { readOnlyHint = true } decision = "allow" priority = 100 modes = ["plan"] ``` For more information on how the policy engine works, see the [policy engine](/docs/reference/policy-engine) docs. #### Example: Allow git commands in Plan Mode This rule lets you check the repository status and see changes while in Plan Mode. `~/.gemini/policies/git-research.toml` ```toml [[rule]] toolName = "run_shell_command" commandPrefix = ["git status", "git diff"] decision = "allow" priority = 100 modes = ["plan"] ``` #### Example: Enable custom subagents in Plan Mode Built-in research [subagents](/docs/core/subagents) like [`codebase_investigator`](/docs/core/subagents#codebase-investigator) and [`cli_help`](/docs/core/subagents#cli-help-agent) are enabled by default in Plan Mode. You can enable additional [custom subagents](/docs/core/subagents#creating-custom-subagents) by adding a rule to your policy. `~/.gemini/policies/research-subagents.toml` ```toml [[rule]] toolName = "my_custom_subagent" decision = "allow" priority = 100 modes = ["plan"] ``` Tell Gemini CLI it can use these tools in your prompt, for example: _"You can check ongoing changes in git."_ ### Custom plan directory and policies By default, planning artifacts are stored in a managed temporary directory outside your project: `~/.gemini/tmp///plans/`. You can configure a custom directory for plans in your `settings.json`. For example, to store plans in a `.gemini/plans` directory within your project: ```json { "general": { "plan": { "directory": ".gemini/plans" } } } ``` To maintain the safety of Plan Mode, user-configured paths for the plans directory are restricted to the project root. This ensures that custom planning locations defined within a project's workspace cannot be used to escape and overwrite sensitive files elsewhere. Any user-configured directory must reside within the project boundary. Using a custom directory requires updating your [policy engine](/docs/reference/policy-engine) configurations to allow `write_file` and `replace` in that specific location. For example, to allow writing to the `.gemini/plans` directory within your project, create a policy file at `~/.gemini/policies/plan-custom-directory.toml`: ```toml [[rule]] toolName = ["write_file", "replace"] decision = "allow" priority = 100 modes = ["plan"] # Adjust the pattern to match your custom directory. # This example matches any .md file in a .gemini/plans directory within the project. argsPattern = "\"file_path\":\"[^\"]+[\\\\/]+\\.gemini[\\\\/]+plans[\\\\/]+[\\w-]+\\.md\"" ``` ### Using hooks with Plan Mode You can use the [hook system](/docs/hooks/writing-hooks) to automate parts of the planning workflow or enforce additional checks when Gemini CLI transitions into or out of Plan Mode. Hooks such as `BeforeTool` or `AfterTool` can be configured to intercept the `enter_plan_mode` and `exit_plan_mode` tool calls. > [!WARNING] When hooks are triggered by **tool executions**, they do **not** > run when you manually toggle Plan Mode using the `/plan` command or the > `Shift+Tab` keyboard shortcut. If you need hooks to execute on mode changes, > ensure the transition is initiated by the agent (for example, by asking "start > a plan for..."). #### Example: Archive approved plans to GCS (`AfterTool`) If your organizational policy requires a record of all execution plans, you can use an `AfterTool` hook to securely copy the plan artifact to Google Cloud Storage whenever Gemini CLI exits Plan Mode to start the implementation. **`.gemini/hooks/archive-plan.sh`:** ```bash #!/usr/bin/env bash # Extract the plan filename from the tool input JSON plan_filename=$(jq -r '.tool_input.plan_filename // empty') # Construct the absolute path using the GEMINI_PLANS_DIR environment variable plan_path="$GEMINI_PLANS_DIR/$plan_filename" if [ -f "$plan_path" ]; then # Generate a unique filename using a timestamp filename="$(date +%s)_$(basename "$plan_path")" # Upload the plan to GCS in the background so it doesn't block the CLI gsutil cp "$plan_path" "gs://my-audit-bucket/gemini-plans/$filename" > /dev/null 2>&1 & fi # AfterTool hooks should generally allow the flow to continue echo '{"decision": "allow"}' ``` To register this `AfterTool` hook, add it to your `settings.json`: ```json { "hooks": { "AfterTool": [ { "matcher": "exit_plan_mode", "hooks": [ { "name": "archive-plan", "type": "command", "command": "~/.gemini/hooks/archive-plan.sh" } ] } ] } } ``` ## Commands - **`/plan copy`**: Copy the currently approved plan to your clipboard. ## Planning workflows Plan Mode provides building blocks for structured research and design. These are implemented as [extensions](/docs/extensions) using core planning tools like [`enter_plan_mode`](/docs/tools/planning#1-enter_plan_mode-enterplanmode), [`exit_plan_mode`](/docs/tools/planning#2-exit_plan_mode-exitplanmode), and [`ask_user`](/docs/tools/ask-user). ### Built-in planning workflow The built-in planner uses an adaptive workflow to analyze your project, consult you on trade-offs via [`ask_user`](/docs/tools/ask-user), and draft a plan for your approval. ### Custom planning workflows You can install or create specialized planners to suit your workflow. #### Conductor [Conductor] is designed for spec-driven development. It organizes work into "tracks" and stores persistent artifacts in your project's `conductor/` directory: - **Automate transitions:** Switches to read-only mode via [`enter_plan_mode`](/docs/tools/planning#1-enter_plan_mode-enterplanmode). - **Streamline decisions:** Uses [`ask_user`](/docs/tools/ask-user) for architectural choices. - **Maintain project context:** Stores artifacts in the project directory using [custom plan directory and policies](#custom-plan-directory-and-policies). - **Handoff execution:** Transitions to implementation via [`exit_plan_mode`](/docs/tools/planning#2-exit_plan_mode-exitplanmode). #### Build your own Since Plan Mode is built on modular building blocks, you can develop your own custom planning workflow as an [extensions](/docs/extensions). By leveraging core tools and [custom policies](#custom-policies), you can define how Gemini CLI researches and stores plans for your specific domain. To build a custom planning workflow, you can use: - **Tool usage:** Use core tools like [`enter_plan_mode`](/docs/tools/planning#1-enter_plan_mode-enterplanmode), [`ask_user`](/docs/tools/ask-user), and [`exit_plan_mode`](/docs/tools/planning#2-exit_plan_mode-exitplanmode) to manage the research and design process. - **Customization:** Set your own storage locations and policy rules using [custom plan directories](#custom-plan-directory-and-policies) and [custom policies](#custom-policies). > [!TIP] > Use [Conductor] as a reference when building your own custom > planning workflow. By using Plan Mode as its execution environment, your custom methodology can enforce read-only safety during the design phase while benefiting from high-reasoning model routing. ## Automatic Model Routing When using an [auto model](/docs/reference/configuration#model), Gemini CLI automatically optimizes [model routing](/docs/cli/telemetry#model-routing) based on the current phase of your task: 1. **Planning Phase:** While in Plan Mode, the CLI routes requests to a high-reasoning **Pro** model to ensure robust architectural decisions and high-quality plans. 2. **Implementation Phase:** Once a plan is approved and you exit Plan Mode, the CLI detects the existence of the approved plan and automatically switches to a high-speed **Flash** model. This provides a faster, more responsive experience during the implementation of the plan. If the high-reasoning model is unavailable or you don't have access to it, Gemini CLI automatically and silently falls back to a faster model to ensure your workflow isn't interrupted. This behavior is enabled by default to provide the best balance of quality and performance. You can disable this automatic switching in your settings: ```json { "general": { "plan": { "modelRouting": false } } } ``` ## Cleanup By default, Gemini CLI automatically cleans up old session data, including all associated plan files and task trackers. - **Default behavior:** Sessions (and their plans) are retained for **30 days**. - **Configuration:** You can customize this behavior via the `/settings` command (search for **Enable Session Cleanup** or **Keep chat history**) or in your `settings.json` file. See [session retention](/docs/cli/session-management#session-retention) for more details. Manual deletion also removes all associated artifacts: - **Command Line:** Use `gemini --delete-session `. - **Session Browser:** Press `/resume`, navigate to a session, and press `x`. If you use a [custom plans directory](#custom-plan-directory-and-policies), those files are not automatically deleted and must be managed manually. ## Non-interactive execution When running Gemini CLI in non-interactive environments (such as headless scripts or CI/CD pipelines), Plan Mode optimizes for automated workflows: - **Automatic transitions:** The policy engine automatically approves the `enter_plan_mode` and `exit_plan_mode` tools without prompting for user confirmation. - **Automated implementation:** When exiting Plan Mode to execute the plan, Gemini CLI automatically switches to [YOLO mode](/docs/reference/policy-engine#approval-modes) instead of the standard Default mode. This allows the CLI to execute the implementation steps automatically without hanging on interactive tool approvals. **Example:** ```bash gemini --approval-mode plan -p "Analyze telemetry and suggest improvements" ``` [`plan.toml`]: https://github.com/google-gemini/gemini-cli/blob/main/packages/core/src/policy/policies/plan.toml [Conductor]: https://github.com/gemini-cli-extensions/conductor [open an issue]: https://github.com/google-gemini/gemini-cli/issues # [Rewind](http://geminicli.com/docs/cli/rewind.md) The `/rewind` command lets you go back to a previous state in your conversation and, optionally, revert any file changes made by the AI during those interactions. This is a powerful tool for undoing mistakes, exploring different approaches, or simply cleaning up your session history. ## Usage To use the rewind feature, simply type `/rewind` into the input prompt and press **Enter**. Alternatively, you can use the keyboard shortcut: **Press `Esc` twice**. ## Interface When you trigger a rewind, an interactive list of your previous interactions appears. 1. **Select interaction:** Use the **Up/Down arrow keys** to navigate through the list. The most recent interactions are at the bottom. 2. **Preview:** As you select an interaction, you'll see a preview of the user prompt and, if applicable, the number of files changed during that step. 3. **Confirm selection:** Press **Enter** on the interaction you want to rewind back to. 4. **Action selection:** After selecting an interaction, you'll be presented with a confirmation dialog with up to three options: - **Rewind conversation and revert code changes:** Reverts both the chat history and the file modifications to the state before the selected interaction. - **Rewind conversation:** Only reverts the chat history. File changes are kept. - **Revert code changes:** Only reverts the file modifications. The chat history is kept. - **Do nothing (esc):** Cancels the rewind operation. If no code changes were made since the selected point, the options related to reverting code changes will be hidden. ## Key considerations - **Destructive action:** Rewinding is a destructive action for your current session history and potentially your files. Use it with care. - **Agent awareness:** When you rewind the conversation, the AI model loses all memory of the interactions that were removed. If you only revert code changes, you may need to inform the model that the files have changed. - **Manual edits:** Rewinding only affects file changes made by the AI's edit tools. It does **not** undo manual edits you've made or changes triggered by the shell tool (`!`). - **Compression:** Rewind works across chat compression points by reconstructing the history from stored session data. # [Sandboxing in Gemini CLI](http://geminicli.com/docs/cli/sandbox.md) This document provides a guide to sandboxing in Gemini CLI, including prerequisites, quickstart, and configuration. ## Prerequisites Before using sandboxing, you need to install and set up Gemini CLI: ```bash npm install -g @google/gemini-cli ``` To verify the installation: ```bash gemini --version ``` ## Overview of sandboxing Sandboxing isolates potentially dangerous operations (such as shell commands or file modifications) from your host system, providing a security barrier between AI operations and your environment. The benefits of sandboxing include: - **Security**: Prevent accidental system damage or data loss. - **Isolation**: Limit file system access to project directory. - **Consistency**: Ensure reproducible environments across different systems. - **Safety**: Reduce risk when working with untrusted code or experimental commands. ## Quickstart You can enable sandboxing using a command flag, environment variable, or configuration file. ### Using the command flag ```bash gemini -s -p "analyze the code structure" ``` ### Using an environment variable **macOS/Linux** ```bash export GEMINI_SANDBOX=true gemini -p "run the test suite" ``` **Windows (PowerShell)** ```powershell $env:GEMINI_SANDBOX="true" gemini -p "run the test suite" ``` ### Configuring via settings.json ```json { "tools": { "sandbox": "docker" } } ``` ## Configuration Enable sandboxing using one of the following methods (in order of precedence): 1. **Command flag**: `-s` or `--sandbox` 2. **Environment variable**: `GEMINI_SANDBOX=true|docker|podman|sandbox-exec|runsc|lxc` 3. **Settings file**: `"sandbox": true` in the `tools` object of your `settings.json` file (for example, `{"tools": {"sandbox": true}}`). ## Sandboxing methods Your ideal method of sandboxing may differ depending on your platform and your preferred container solution. ### 1. macOS Seatbelt (macOS only) Lightweight, built-in sandboxing using `sandbox-exec`. **Default profile**: `permissive-open` - denies operations by default; confines writes to the project directory while allowing broad file reads and network access. Built-in profiles (set via `SEATBELT_PROFILE` env var): - `permissive-open` (default): Write restrictions, network allowed - `permissive-proxied`: Write restrictions, network via proxy - `restrictive-open`: Strict restrictions, network allowed - `restrictive-proxied`: Strict restrictions, network via proxy - `strict-open`: Read and write restrictions, network allowed - `strict-proxied`: Read and write restrictions, network via proxy ### 2. Container-based (Docker/Podman) Cross-platform sandboxing with complete process isolation using container technology. By default, it uses the `ghcr.io/google/gemini-cli:latest` image. **Prerequisites:** - Docker or Podman must be installed and running on your system. **How it works (Workspace directory):** Inside the sandbox container, your current working directory is mounted at the **exact same absolute path** as it is on your host machine. For example, if you run the CLI from `/Users/you/project` on your host machine, the sandbox will mount your local project folder and operate within `/Users/you/project` inside the container. This allows the AI to seamlessly read and modify your project files while remaining isolated from the rest of your system. **Quick setup:** To enable Docker sandboxing, run Gemini CLI with the sandbox flag and specify Docker as the provider: ```bash # Using the environment variable (Recommended) export GEMINI_SANDBOX=docker gemini -p "build the project" # Or configure it permanently in your settings.json # {"tools": {"sandbox": "docker"}} ``` **Customizing the Sandbox Image:** If your project requires specific dependencies, you can specify a custom image name or have Gemini CLI build one for you automatically. You can use any Docker or Podman image as your sandbox, provided it has standard shell utilities (like `bash`) available. **Option A: Using an existing custom image (e.g., Artifact Registry)** To configure a custom image that is hosted on a registry (or built locally), update your `settings.json` to use an object for the sandbox configuration, or set the `GEMINI_SANDBOX_IMAGE` environment variable. _Example: Configuring via `settings.json`_ ```json { "tools": { "sandbox": { "command": "docker", "image": "us-central1-docker.pkg.dev/my-project/my-repo/my-custom-sandbox:latest" } } } ``` _Example: Configuring via environment variable_ ```bash export GEMINI_SANDBOX_IMAGE="us-central1-docker.pkg.dev/my-project/my-repo/my-custom-sandbox:latest" ``` **Option B: Building a local custom image automatically** If you prefer to define your environment as code, you can provide a Dockerfile and Gemini CLI will build the image automatically. 1. Create a `.gemini/sandbox.Dockerfile` in your project root. 2. Ensure you have the `gh` CLI installed and authenticated (if you are using the default `ghcr.io/google/gemini-cli` image as a base). 3. Run your command with the `BUILD_SANDBOX` environment variable set: ```bash BUILD_SANDBOX=1 GEMINI_SANDBOX=docker gemini -p "run my custom build" ``` ### 3. Windows Native Sandbox (Windows only) ... **Troubleshooting and Side Effects:** The Windows Native sandbox uses the `icacls` command to set a "Low Mandatory Level" on files and directories it needs to write to. - **Persistence**: These integrity level changes are persistent on the filesystem. Even after the sandbox session ends, files created or modified by the sandbox will retain their "Low" integrity level. - **Manual Reset**: If you need to reset the integrity level of a file or directory, you can use: ```powershell icacls "C:\path\to\dir" /setintegritylevel Medium ``` - **System Folders**: The sandbox manager automatically skips setting integrity levels on system folders (like `C:\Windows`) for safety. ### 4. gVisor / runsc (Linux only) Strongest isolation available: runs containers inside a user-space kernel via [gVisor](https://github.com/google/gvisor). gVisor intercepts all container system calls and handles them in a sandboxed kernel written in Go, providing a strong security barrier between AI operations and the host OS. **Prerequisites:** - Linux (gVisor supports Linux only) - Docker installed and running - gVisor/runsc runtime configured When you set `sandbox: "runsc"`, Gemini CLI runs `docker run --runtime=runsc ...` to execute containers with gVisor isolation. runsc is not auto-detected; you must specify it explicitly (e.g. `GEMINI_SANDBOX=runsc` or `sandbox: "runsc"`). To set up runsc: 1. Install the runsc binary. 2. Configure the Docker daemon to use the runsc runtime. 3. Verify the installation. ### 5. LXC/LXD (Linux only, experimental) Full-system container sandboxing using LXC/LXD. Unlike Docker/Podman, LXC containers run a complete Linux system with `systemd`, `snapd`, and other system services. This is ideal for tools that don't work in standard Docker containers, such as Snapcraft and Rockcraft. **Prerequisites**: - Linux only. - LXC/LXD must be installed (`snap install lxd` or `apt install lxd`). - A container must be created and running before starting Gemini CLI. Gemini does **not** create the container automatically. **Quick setup**: ```bash # Initialize LXD (first time only) lxd init --auto # Create and start an Ubuntu container lxc launch ubuntu:24.04 gemini-sandbox # Enable LXC sandboxing export GEMINI_SANDBOX=lxc gemini -p "build the project" ``` **Custom container name**: ```bash export GEMINI_SANDBOX=lxc export GEMINI_SANDBOX_IMAGE=my-snapcraft-container gemini -p "build the snap" ``` **Limitations**: - Linux only (LXC is not available on macOS or Windows). - The container must already exist and be running. - The workspace directory is bind-mounted into the container at the same absolute path β€” the path must be writable inside the container. - Used with tools like Snapcraft or Rockcraft that require a full system. ## Tool sandboxing Tool-level sandboxing provides granular isolation for individual tool executions (like `shell_exec` and `write_file`) instead of sandboxing the entire Gemini CLI process. This approach offers better integration with your local environment for non-tool tasks (like UI rendering and configuration loading) while still providing security for tool-driven operations. ### How to turn off tool sandboxing If you experience issues with tool sandboxing or prefer full-process isolation, you can disable it by setting `security.toolSandboxing` to `false` in your `settings.json` file. ```json { "security": { "toolSandboxing": false } } ``` > [!NOTE] > Changing the `security.toolSandboxing` setting requires a restart of Gemini > CLI to take effect. ## Sandbox expansion Sandbox expansion is a dynamic permission system that lets Gemini CLI request additional permissions for a command when needed. When a sandboxed command fails due to permission restrictions (like restricted file paths or network access), or when a command is proactively identified as requiring extra permissions (like `npm install`), Gemini CLI will present you with a "Sandbox Expansion Request." ### How sandbox expansion works 1. **Detection**: Gemini CLI detects a sandbox denial or proactively identifies a command that requires extra permissions. 2. **Request**: A modal dialog is shown, explaining which additional permissions (e.g., specific directories or network access) are required. 3. **Approval**: If you approve the expansion, the command is executed with the extended permissions for that specific run. This mechanism ensures you don't have to manually re-run commands with more permissive sandbox settings, while still maintaining control over what the AI can access. ### Including files outside the workspace By default, the sandbox only has access to the current project workspace. If you need the sandbox to have permission to operate on certain files or directories from the local file system outside of the project workspace, you can mount them using the `SANDBOX_MOUNTS` environment variable. Provide a comma-separated list of mount definitions in the format `from:to:opts`. If `to` is omitted, it defaults to the same path as `from`. If `opts` is omitted, it defaults to `ro` (read-only). Note that the `from` path must be an absolute path. **Example**: ```bash export SANDBOX_MOUNTS="/path/on/host:/path/in/container:rw,/another/path:ro" ``` ## Running inside a Docker container If you are running Gemini CLI itself from within an official or custom Docker container and want to enable sandboxing, you must share the host's Docker socket and ensure your workspace paths align. 1. **Mount the Docker socket**: Map `/var/run/docker.sock` so the CLI can spawn sibling sandbox containers via the host's Docker daemon. 2. **Align workspace paths**: The path to your workspace inside the container must exactly match the absolute path on the host. Because the sandbox container is spawned by the host's Docker daemon, it resolves volume mounts against the host file system. **Example**: ```bash docker run -it \ -v /var/run/docker.sock:/var/run/docker.sock \ -v /absolute/path/on/host/project:/absolute/path/on/host/project \ -w /absolute/path/on/host/project \ -e GEMINI_SANDBOX=docker \ ghcr.io/google/gemini-cli:latest ``` ## Advanced settings ### Custom sandbox flags For container-based sandboxing, you can inject custom flags into the `docker` or `podman` command using the `SANDBOX_FLAGS` environment variable. This is useful for advanced configurations, such as disabling security features for specific use cases. **Example (Podman)**: To disable SELinux labeling for volume mounts, you can set the following: **macOS/Linux** ```bash export SANDBOX_FLAGS="--security-opt label=disable" ``` **Windows (PowerShell)** ```powershell $env:SANDBOX_FLAGS="--security-opt label=disable" ``` Multiple flags can be provided as a space-separated string: **macOS/Linux** ```bash export SANDBOX_FLAGS="--flag1 --flag2=value" ``` **Windows (PowerShell)** ```powershell $env:SANDBOX_FLAGS="--flag1 --flag2=value" ``` ### Linux UID/GID handling The sandbox automatically handles user permissions on Linux. Override these permissions with: **macOS/Linux** ```bash export SANDBOX_SET_UID_GID=true # Force host UID/GID export SANDBOX_SET_UID_GID=false # Disable UID/GID mapping ``` **Windows (PowerShell)** ```powershell $env:SANDBOX_SET_UID_GID="true" # Force host UID/GID $env:SANDBOX_SET_UID_GID="false" # Disable UID/GID mapping ``` ## Troubleshooting ### Common issues **"Operation not permitted"** - Operation requires access outside sandbox. - Try more permissive profile or add mount points. **Missing commands** - Add to a custom Dockerfile. Automatic `BUILD_SANDBOX` builds are only available when running Gemini CLI from source; npm installs need a prebuilt image instead. - Install via `sandbox.bashrc`. **Network issues** - Check sandbox profile allows network. - Verify proxy configuration. ### Debug mode ```bash DEBUG=1 gemini -s -p "debug command" ``` > [!NOTE] > If you have `DEBUG=true` in a project's `.env` file, it won't affect > gemini-cli due to automatic exclusion. Use `.gemini/.env` files for > gemini-cli specific debug settings. ### Inspect sandbox ```bash # Check environment gemini -s -p "run shell command: env | grep SANDBOX" # List mounts gemini -s -p "run shell command: mount | grep workspace" ``` ## Security notes - Sandboxing reduces but doesn't eliminate all risks. - Use the most restrictive profile that allows your work. - Container overhead is minimal after first build. - GUI applications may not work in sandboxes. ## Related documentation - [Configuration](/docs/reference/configuration): Full configuration options. - [Commands](/docs/reference/commands): Available commands. - [Troubleshooting](/docs/resources/troubleshooting): General troubleshooting. # [Session management](http://geminicli.com/docs/cli/session-management.md) Session management saves your conversation history so you can resume your work where you left off. Use these features to review past interactions, manage history across different projects, and configure how long data is retained. ## Automatic saving Your session history is recorded automatically as you interact with the model. This background process ensures your work is preserved even if you interrupt a session. - **What is saved:** The complete conversation history, including: - Your prompts and the model's responses. - All tool executions (inputs and outputs). - Token usage statistics (input, output, cached, etc.). - Assistant thoughts and reasoning summaries (when available). - **Location:** Sessions are stored in `~/.gemini/tmp//chats/`, where `` is a unique identifier based on your project's root directory. - **Scope:** Sessions are project-specific. Switching directories to a different project switches to that project's session history. ## Resuming sessions You can resume a previous session to continue the conversation with all prior context restored. Resuming is supported both through command-line flags and an interactive browser. ### From the command line When starting Gemini CLI, use the `--resume` (or `-r`) flag to load existing sessions. - **Resume latest:** ```bash gemini --resume ``` This immediately loads the most recent session. - **Resume by index:** List available sessions first (see [Listing sessions](#listing-sessions)), then use the index number: ```bash gemini --resume 1 ``` - **Resume by ID:** You can also provide the full session UUID: ```bash gemini --resume a1b2c3d4-e5f6-7890-abcd-ef1234567890 ``` ### From the interactive interface While the CLI is running, use the `/resume` slash command to open the **Session Browser**: ```text /resume ``` When typing `/resume` (or `/chat`) in slash completion, commands are grouped under titled separators: - `-- auto --` (session browser) - `list` is selectable and opens the session browser - `-- checkpoints --` (manual tagged checkpoint commands) Unique prefixes such as `/resum` and `/cha` resolve to the same grouped menu. The Session Browser provides an interactive interface where you can perform the following actions: - **Browse:** Scroll through a list of your past sessions. - **Preview:** See details like the session date, message count, and the first user prompt. - **Search:** Press `/` to enter search mode, then type to filter sessions by ID or content. - **Select:** Press **Enter** to resume the selected session. - **Esc:** Press **Esc** to exit the Session Browser. ### Manual chat checkpoints For named branch points inside a session, use chat checkpoints: ```text /resume save decision-point /resume list /resume resume decision-point ``` Compatibility aliases: - `/chat ...` works for the same commands. - `/resume checkpoints ...` also remains supported during migration. ## Parallel sessions with Git worktrees When working on multiple tasks at once, you can use [Git worktrees](/docs/cli/git-worktrees) to give each Gemini session its own copy of the codebase. This prevents changes in one session from colliding with another. ## Managing sessions You can list and delete sessions to keep your history organized and manage disk space. ### Listing sessions To see a list of all available sessions for the current project from the command line, use the `--list-sessions` flag: ```bash gemini --list-sessions ``` Output example: ```text Available sessions for this project (3): 1. Fix bug in auth (2 days ago) [a1b2c3d4] 2. Refactor database schema (5 hours ago) [e5f67890] 3. Update documentation (Just now) [abcd1234] ``` ### Deleting sessions You can remove old or unwanted sessions to free up space or declutter your history. **From the command line:** Use the `--delete-session` flag with an index or ID: ```bash gemini --delete-session 2 ``` **From the Session Browser:** 1. Open the browser with `/resume`. 2. Navigate to the session you want to remove. 3. Press **x**. ## Configuration You can configure how Gemini CLI manages your session history in your `settings.json` file. These settings let you control retention policies and session lengths. ### Session retention By default, Gemini CLI automatically cleans up old session data to prevent your history from growing indefinitely. When a session is deleted, Gemini CLI also removes all associated data, including implementation plans, task trackers, tool outputs, and activity logs. The default policy is to **retain sessions for 30 days**. #### Configuration You can customize these policies using the `/settings` command or by manually editing your `settings.json` file: ```json { "general": { "sessionRetention": { "enabled": true, "maxAge": "30d", "maxCount": 50 } } } ``` - **`enabled`**: (boolean) Master switch for session cleanup. Defaults to `true`. - **`maxAge`**: (string) Duration to keep sessions (for example, "24h", "7d", "4w"). Sessions older than this are deleted. Defaults to `"30d"`. - **`maxCount`**: (number) Maximum number of sessions to retain. The oldest sessions exceeding this count are deleted. Defaults to undefined (unlimited). - **`minRetention`**: (string) Minimum retention period (safety limit). Defaults to `"1d"`. Sessions newer than this period are never deleted by automatic cleanup. ### Session limits You can limit the length of individual sessions to prevent context windows from becoming too large and expensive. ```json { "model": { "maxSessionTurns": 100 } } ``` - **`maxSessionTurns`**: (number) The maximum number of turns (user and model exchanges) allowed in a single session. Set to `-1` for unlimited (default). **Behavior when limit is reached:** - **Interactive mode:** The CLI shows an informational message and stops sending requests to the model. You must manually start a new session. - **Non-interactive mode:** The CLI exits with an error. ## Next steps - Explore the [Memory tool](/docs/tools/memory) to save persistent information across sessions. - Learn how to [Checkpoint](/docs/cli/checkpointing) your session state. - Check out the [CLI reference](/docs/cli/cli-reference) for all command-line flags. # [Gemini CLI settings (`/settings` command)](http://geminicli.com/docs/cli/settings.md) Control your Gemini CLI experience with the `/settings` command. The `/settings` command opens a dialog to view and edit all your Gemini CLI settings, including your UI experience, keybindings, and accessibility features. Your Gemini CLI settings are stored in a `settings.json` file. In addition to using the `/settings` command, you can also edit them in one of the following locations: - **User settings**: `~/.gemini/settings.json` - **Workspace settings**: `your-project/.gemini/settings.json` > [!IMPORTANT] > Workspace settings override user settings. ## Settings reference Here is a list of all the available settings, grouped by category and ordered as they appear in the UI. ### General | UI Label | Setting | Description | Default | | ----------------------------- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | | Vim Mode | `general.vimMode` | Enable Vim keybindings | `false` | | Default Approval Mode | `general.defaultApprovalMode` | The default approval mode for tool execution. 'default' prompts for approval, 'auto_edit' auto-approves edit tools, and 'plan' is read-only mode. YOLO mode (auto-approve all actions) can only be enabled via command line (--yolo or --approval-mode=yolo). | `"default"` | | Enable Auto Update | `general.enableAutoUpdate` | Enable automatic updates. | `true` | | Enable Terminal Notifications | `general.enableNotifications` | Enable terminal run-event notifications for action-required prompts and session completion. | `false` | | Terminal Notification Method | `general.notificationMethod` | How to send terminal notifications. | `"auto"` | | Enable Plan Mode | `general.plan.enabled` | Enable Plan Mode for read-only safety during planning. | `true` | | Plan Directory | `general.plan.directory` | The directory where planning artifacts are stored. If not specified, defaults to the system temporary directory. A custom directory requires a policy to allow write access in Plan Mode. | `undefined` | | Plan Model Routing | `general.plan.modelRouting` | Automatically switch between Pro and Flash models based on Plan Mode status. Uses Pro for the planning phase and Flash for the implementation phase. | `true` | | Retry Fetch Errors | `general.retryFetchErrors` | Retry on "exception TypeError: fetch failed sending request" errors. | `true` | | Max Chat Model Attempts | `general.maxAttempts` | Maximum number of attempts for requests to the main chat model. Cannot exceed 10. | `10` | | Debug Keystroke Logging | `general.debugKeystrokeLogging` | Enable debug logging of keystrokes to the console. | `false` | | Enable Session Cleanup | `general.sessionRetention.enabled` | Enable automatic session cleanup | `true` | | Keep chat history | `general.sessionRetention.maxAge` | Automatically delete chats older than this time period (e.g., "30d", "7d", "24h", "1w") | `"30d"` | | Topic & Update Narration | `general.topicUpdateNarration` | Enable the Topic & Update communication model for reduced chattiness and structured progress reporting. | `true` | | Log RAG Snippets | `general.logRagSnippets` | Log full Code Customization (RAG) retrieved snippets to a local file for debugging. | `false` | ### Output | UI Label | Setting | Description | Default | | ------------- | --------------- | ------------------------------------------------------ | -------- | | Output Format | `output.format` | The format of the CLI output. Can be `text` or `json`. | `"text"` | ### UI | UI Label | Setting | Description | Default | | ------------------------------------ | -------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | | Auto Theme Switching | `ui.autoThemeSwitching` | Automatically switch between default light and dark themes based on terminal background color. | `true` | | Terminal Background Polling Interval | `ui.terminalBackgroundPollingInterval` | Interval in seconds to poll the terminal background color. | `60` | | Hide Window Title | `ui.hideWindowTitle` | Hide the window title bar | `false` | | Inline Thinking | `ui.inlineThinkingMode` | Display model thinking inline: off or full. | `"off"` | | Show Thoughts in Title | `ui.showStatusInTitle` | Show Gemini CLI model thoughts in the terminal window title during the working phase | `false` | | Dynamic Window Title | `ui.dynamicWindowTitle` | Update the terminal window title with current status icons (Ready: β—‡, Action Required: βœ‹, Working: ✦) | `true` | | Show Home Directory Warning | `ui.showHomeDirectoryWarning` | Show a warning when running Gemini CLI in the home directory. | `true` | | Show Compatibility Warnings | `ui.showCompatibilityWarnings` | Show warnings about terminal or OS compatibility issues. | `true` | | Hide Tips | `ui.hideTips` | Hide helpful tips in the UI | `false` | | Escape Pasted @ Symbols | `ui.escapePastedAtSymbols` | When enabled, @ symbols in pasted text are escaped to prevent unintended @path expansion. | `false` | | Show Shortcuts Hint | `ui.showShortcutsHint` | Show the "? for shortcuts" hint above the input. | `true` | | Compact Tool Output | `ui.compactToolOutput` | Display tool outputs (like directory listings and file reads) in a compact, structured format. | `true` | | Hide Banner | `ui.hideBanner` | Hide the application banner | `false` | | Hide Context Summary | `ui.hideContextSummary` | Hide the context summary (GEMINI.md, MCP servers) above the input. | `false` | | Hide CWD | `ui.footer.hideCWD` | Hide the current working directory in the footer. | `false` | | Hide Sandbox Status | `ui.footer.hideSandboxStatus` | Hide the sandbox status indicator in the footer. | `false` | | Hide Model Info | `ui.footer.hideModelInfo` | Hide the model name and context usage in the footer. | `false` | | Hide Context Window Percentage | `ui.footer.hideContextPercentage` | Hides the context window usage percentage. | `true` | | Hide Footer | `ui.hideFooter` | Hide the footer from the UI | `false` | | Show Memory Usage | `ui.showMemoryUsage` | Display memory usage information in the UI | `false` | | Show Line Numbers | `ui.showLineNumbers` | Show line numbers in the chat. | `true` | | Show Citations | `ui.showCitations` | Show citations for generated text in the chat. | `false` | | Show Model Info In Chat | `ui.showModelInfoInChat` | Show the model name in the chat for each model turn. | `false` | | Show User Identity | `ui.showUserIdentity` | Show the signed-in user's identity (e.g. email) in the UI. | `true` | | Use Alternate Screen Buffer | `ui.useAlternateBuffer` | Use an alternate screen buffer for the UI, preserving shell history. | `false` | | Render Process | `ui.renderProcess` | Enable Ink render process for the UI. | `true` | | Terminal Buffer | `ui.terminalBuffer` | Use the new terminal buffer architecture for rendering. | `false` | | Use Background Color | `ui.useBackgroundColor` | Whether to use background colors in the UI. | `true` | | Incremental Rendering | `ui.incrementalRendering` | Enable incremental rendering for the UI. This option will reduce flickering but may cause rendering artifacts. Only supported when useAlternateBuffer is enabled. | `true` | | Show Spinner | `ui.showSpinner` | Show the spinner during operations. | `true` | | Loading Phrases | `ui.loadingPhrases` | What to show while the model is working: tips, witty comments, all, or off. | `"off"` | | Error Verbosity | `ui.errorVerbosity` | Controls whether recoverable errors are hidden (low) or fully shown (full). | `"low"` | | Screen Reader Mode | `ui.accessibility.screenReader` | Render output in plain-text to be more screen reader accessible | `false` | ### IDE | UI Label | Setting | Description | Default | | -------- | ------------- | ---------------------------- | ------- | | IDE Mode | `ide.enabled` | Enable IDE integration mode. | `false` | ### Billing | UI Label | Setting | Description | Default | | ---------------- | ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | | Overage Strategy | `billing.overageStrategy` | How to handle quota exhaustion when AI credits are available. 'ask' prompts each time, 'always' automatically uses credits, 'never' disables credit usage. | `"ask"` | ### Model | UI Label | Setting | Description | Default | | ----------------------------- | ---------------------------- | -------------------------------------------------------------------------------------- | ----------- | | Model | `model.name` | The Gemini model to use for conversations. | `undefined` | | Max Session Turns | `model.maxSessionTurns` | Maximum number of user/model/tool turns to keep in a session. -1 means unlimited. | `-1` | | Context Compression Threshold | `model.compressionThreshold` | The fraction of context usage at which to trigger context compression (e.g. 0.2, 0.3). | `0.5` | | Disable Loop Detection | `model.disableLoopDetection` | Disable automatic detection and prevention of infinite loops. | `false` | | Skip Next Speaker Check | `model.skipNextSpeakerCheck` | Skip the next speaker check. | `true` | ### Agents | UI Label | Setting | Description | Default | | ------------------------- | ---------------------------------------- | --------------------------------------------------------------------------------------------- | ------- | | Confirm Sensitive Actions | `agents.browser.confirmSensitiveActions` | Require manual confirmation for sensitive browser actions (e.g., fill_form, evaluate_script). | `false` | | Block File Uploads | `agents.browser.blockFileUploads` | Hard-block file upload requests from the browser agent. | `false` | ### Context | UI Label | Setting | Description | Default | | ------------------------------------ | ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | | Memory Discovery Max Dirs | `context.discoveryMaxDirs` | Maximum number of directories to search for memory. | `200` | | Load Memory From Include Directories | `context.loadMemoryFromIncludeDirectories` | Controls how /memory reload loads GEMINI.md files. When true, include directories are scanned; when false, only the current directory is used. | `false` | | Respect .gitignore | `context.fileFiltering.respectGitIgnore` | Respect .gitignore files when searching. | `true` | | Respect .geminiignore | `context.fileFiltering.respectGeminiIgnore` | Respect .geminiignore files when searching. | `true` | | Enable Recursive File Search | `context.fileFiltering.enableRecursiveFileSearch` | Enable recursive file search functionality when completing @ references in the prompt. | `true` | | Enable Fuzzy Search | `context.fileFiltering.enableFuzzySearch` | Enable fuzzy search when searching for files. | `true` | | Custom Ignore File Paths | `context.fileFiltering.customIgnoreFilePaths` | Additional ignore file paths to respect. These files take precedence over .geminiignore and .gitignore. Files earlier in the array take precedence over files later in the array, e.g. the first file takes precedence over the second one. | `[]` | ### Tools | UI Label | Setting | Description | Default | | -------------------------------- | ------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | | Sandbox Allowed Paths | `tools.sandboxAllowedPaths` | List of additional paths that the sandbox is allowed to access. | `[]` | | Sandbox Network Access | `tools.sandboxNetworkAccess` | Whether the sandbox is allowed to access the network. | `false` | | Enable Interactive Shell | `tools.shell.enableInteractiveShell` | Use node-pty for an interactive shell experience. Fallback to child_process still applies. | `true` | | Show Color | `tools.shell.showColor` | Show color in shell output. | `true` | | Use Ripgrep | `tools.useRipgrep` | Use ripgrep for file content search instead of the fallback implementation. Provides faster search performance. | `true` | | Tool Output Truncation Threshold | `tools.truncateToolOutputThreshold` | Maximum characters to show when truncating large tool outputs. Set to 0 or negative to disable truncation. | `40000` | | Disable LLM Correction | `tools.disableLLMCorrection` | Disable LLM-based error correction for edit tools. When enabled, tools will fail immediately if exact string matches are not found, instead of attempting to self-correct. | `true` | ### Security | UI Label | Setting | Description | Default | | ------------------------------------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------- | | Tool Sandboxing | `security.toolSandboxing` | Tool-level sandboxing. Isolates individual tools instead of the entire CLI process. | `false` | | Disable YOLO Mode | `security.disableYoloMode` | Disable YOLO mode, even if enabled by a flag. | `false` | | Disable Always Allow | `security.disableAlwaysAllow` | Disable "Always allow" options in tool confirmation dialogs. | `false` | | Allow Permanent Tool Approval | `security.enablePermanentToolApproval` | Enable the "Allow for all future sessions" option in tool confirmation dialogs. | `false` | | Auto-add to Policy by Default | `security.autoAddToPolicyByDefault` | When enabled, the "Allow for all future sessions" option becomes the default choice for low-risk tools in trusted workspaces. | `false` | | Blocks extensions from Git | `security.blockGitExtensions` | Blocks installing and loading extensions from Git. | `false` | | Extension Source Regex Allowlist | `security.allowedExtensions` | List of Regex patterns for allowed extensions. If nonempty, only extensions that match the patterns in this list are allowed. Overrides the blockGitExtensions setting. | `[]` | | Folder Trust | `security.folderTrust.enabled` | Setting to track whether Folder trust is enabled. | `true` | | Enable Environment Variable Redaction | `security.environmentVariableRedaction.enabled` | Enable redaction of environment variables that may contain secrets. | `false` | | Enable Context-Aware Security | `security.enableConseca` | Enable the context-aware security checker. This feature uses an LLM to dynamically generate and enforce security policies for tool use based on your prompt, providing an additional layer of protection against unintended actions. | `false` | ### Advanced | UI Label | Setting | Description | Default | | --------------------------------- | ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | | Auto Configure Max Old Space Size | `advanced.autoConfigureMemory` | Automatically configure Node.js memory limits. Note: Because memory is allocated during the initial process boot, this setting is only read from the global user settings file and ignores workspace-level overrides. | `true` | | Ignore Local .env | `advanced.ignoreLocalEnv` | Whether to ignore generic .env files in the project directory. | `false` | ### Experimental | UI Label | Setting | Description | Default | | ---------------------------------------------------- | ----------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | | Gemma Models | `experimental.gemma` | Enable access to Gemma 4 models via Gemini API. | `true` | | Voice Mode | `experimental.voiceMode` | Enable experimental voice dictation and commands (/voice, /voice model). | `false` | | Voice Activation Mode | `experimental.voice.activationMode` | How to trigger voice recording with the Space key. | `"push-to-talk"` | | Voice Transcription Backend | `experimental.voice.backend` | The backend to use for voice transcription. Note: When using the Gemini Live backend, voice recordings are sent to Google Cloud for transcription. | `"gemini-live"` | | Whisper Model | `experimental.voice.whisperModel` | The Whisper model to use for local transcription. | `"ggml-base.en.bin"` | | Voice Stop Grace Period (ms) | `experimental.voice.stopGracePeriodMs` | How long to wait for final transcription after stopping recording. | `4000` | | Enable Git Worktrees | `experimental.worktrees` | Enable automated Git worktree management for parallel work. | `false` | | Use OSC 52 Paste | `experimental.useOSC52Paste` | Use OSC 52 for pasting. This may be more robust than the default system when using remote terminal sessions (if your terminal is configured to allow it). | `false` | | Use OSC 52 Copy | `experimental.useOSC52Copy` | Use OSC 52 for copying. This may be more robust than the default system when using remote terminal sessions (if your terminal is configured to allow it). | `false` | | Model Steering | `experimental.modelSteering` | Enable model steering (user hints) to guide the model during tool execution. | `false` | | Direct Web Fetch | `experimental.directWebFetch` | Enable web fetch behavior that bypasses LLM summarization. | `false` | | Enable Gemma Model Router | `experimental.gemmaModelRouter.enabled` | Enable the Gemma Model Router (experimental). Requires a local endpoint serving Gemma via the Gemini API using LiteRT-LM shim. | `false` | | Auto-start LiteRT Server | `experimental.gemmaModelRouter.autoStartServer` | Automatically start the LiteRT-LM server when Gemini CLI starts and the Gemma router is enabled. | `false` | | Auto Memory | `experimental.autoMemory` | Automatically extract memory patches and skills from past sessions in the background. Every change is written as a unified diff `.patch` file under `/.inbox//` and held for review in /memory inbox; nothing is applied until you approve it. | `false` | | Use the generalist profile to manage agent contexts. | `experimental.generalistProfile` | Suitable for general coding and software development tasks. | `false` | | Enable Context Management | `experimental.contextManagement` | Enable logic for context management. | `false` | ### Skills | UI Label | Setting | Description | Default | | ------------------- | ---------------- | -------------------- | ------- | | Enable Agent Skills | `skills.enabled` | Enable Agent Skills. | `true` | ### HooksConfig | UI Label | Setting | Description | Default | | ------------------ | --------------------------- | -------------------------------------------------------------------------------- | ------- | | Enable Hooks | `hooksConfig.enabled` | Canonical toggle for the hooks system. When disabled, no hooks will be executed. | `true` | | Hook Notifications | `hooksConfig.notifications` | Show visual indicators when hooks are executing. | `true` | # [Agent Skill best practices](http://geminicli.com/docs/cli/skills-best-practices.md) Create high-quality, reliable Agent Skills by following these established design principles and patterns. ## Design for discovery The most important part of a skill is its `description`. This is the only information the model has before activation. - **Be specific**: Use keywords that are likely to appear in user prompts (for example, "audit," "security," "refactor," "migration"). - **Define the trigger**: Clearly state _when_ the skill should be used (for example, "Use this skill when the user asks to review a PR for performance regressions"). - **Avoid overlap**: Ensure your skill descriptions are distinct from one another and from the general capabilities of the model. ## Progressive disclosure The "context window" is a shared resource. Use a three-level loading system to manage context efficiently. 1. **Metadata (name + description)**: Always in context (~100 words). 2. **`SKILL.md` body**: Loaded only after the skill triggers (<5k words). 3. **Bundled resources**: Loaded only as needed by the model. **Best practice**: Keep the `SKILL.md` body focused on core procedural instructions. Move detailed reference material, schemas, and examples into separate files in a `references/` directory. ## Degrees of freedom Match the level of instruction specificity to the task's fragility. - **High freedom (text-based instructions)**: Use when multiple approaches are valid or decisions depend heavily on context. - **Medium freedom (pseudocode or scripts with parameters)**: Use when a preferred pattern exists but some variation is acceptable. - **Low freedom (specific scripts, few parameters)**: Use when operations are fragile and error-prone, or a specific sequence MUST be followed. ## Bundle resources effectively Leverage the skill's ability to include scripts and assets to extend the agent's capabilities. - **Use scripts for deterministic tasks**: If a task can be automated with a script (for example, running a linter, fetching data from an API), bundle it in the `scripts/` folder. - **Agentic ergonomics**: Ensure scripts output LLM-friendly stdout. Suppress verbose tracebacks and provide clear, concise success/failure messages. - **Provide templates**: Include common file headers or boilerplate code in the `assets/` folder to ensure the agent produces consistent output. ## Anatomy of a great skill A well-structured skill directory organizes its resources into specialized sub-folders. ```text my-skill/ β”œβ”€β”€ SKILL.md (Required) Core instructions and metadata β”œβ”€β”€ scripts/ (Optional) Executable logic (Node.js, Python, etc.) β”œβ”€β”€ references/ (Optional) Documentation to be loaded as needed └── assets/ (Optional) Templates and non-executable resources ``` ## Security and privacy Design your skills with security in mind to protect your workspace and data. - **Avoid hardcoded secrets**: Never include API keys or passwords in your skill's scripts or documentation. - **Review third-party skills**: Inspect the `SKILL.md` and scripts of any skill before installing it from an untrusted source. - **Limit scope**: Design skills to be as focused as possible to minimize the potential impact of errors. # [Agent Skills](http://geminicli.com/docs/cli/skills.md) Agent Skills let you extend Gemini CLI with specialized expertise, procedural workflows, and task-specific resources. Based on the [Agent Skills](https://agentskills.io) open standard, a "skill" is a self-contained directory that packages instructions and assets into a discoverable capability. Unlike general context files ([GEMINI.md](/docs/cli/gemini-md)), which provide persistent workspace-wide background, Skills represent **on-demand expertise**. This lets Gemini CLI maintain a vast library of specialized capabilitiesβ€”such as security auditing, cloud deployments, or codebase migrationsβ€”without cluttering the model's immediate context window. ## How it works The lifecycle of an Agent Skill involves discovery, activation, and conditional resource access. 1. **Discovery**: At the start of a session, Gemini CLI scans the discovery tiers and injects the name and description of all enabled skills into the system prompt. 2. **Activation**: When Gemini identifies a task matching a skill's description, it calls the `activate_skill` tool. 3. **Consent**: You will see a confirmation prompt in the UI detailing the skill's name, purpose, and the directory path it will gain access to. 4. **Injection**: Upon your approval: - The `SKILL.md` body and folder structure is added to the conversation history. - The skill's directory is added to the agent's allowed file paths, granting it permission to read any bundled assets. 5. **Execution**: The model proceeds with the specialized expertise active. It is instructed to prioritize the skill's procedural guidance within reason. ## Discovery tiers Gemini CLI discovers skills from several locations, following a specific order of precedence (lowest to highest): 1. **Built-in skills**: Standard skills included with Gemini CLI that provide foundational capabilities. 2. **Extension skills**: Skills bundled within installed [extensions](/docs/extensions). 3. **User skills**: Located in `~/.gemini/skills/` or the `~/.agents/skills/` alias. 4. **Workspace skills**: Located in `.gemini/skills/` or the `.agents/skills/` alias. Workspace skills are shared with your team via version control. ### Precedence and aliases If multiple skills share the same name, the version from the higher-precedence location is used. Within the same tier (user or workspace), the `.agents/skills/` alias takes precedence over the `.gemini/skills/` directory. The `.agents/skills/` alias provides an interoperable path for managing agent-specific expertise that remains compatible across different AI tools. ## Key benefits Agent Skills provide several advantages for managing specialized knowledge and complex workflows. - **Shared expertise**: Package complex workflows (like a specific team's PR review process) into a folder that anyone can use. - **Repeatable workflows**: Ensure complex multi-step tasks are performed consistently by providing a procedural framework. - **Resource bundling**: Include scripts, templates, or example data alongside instructions so the agent has everything it needs. - **Progressive disclosure**: Only skill metadata (name and description) is loaded initially. Detailed instructions and resources are only disclosed when the model explicitly activates the skill, saving context tokens. > [!NOTE] > `/skills disable` and `/skills enable` default to the `user` scope. Use > `--scope workspace` to manage workspace-specific settings. To see all available skills in your current session, use the `/skills list` command. ## Managing skills You can manage Agent Skills through interactive session commands or directly from your terminal. ### In an interactive session Use the `/skills` slash command to view and manage available expertise: - `/skills list [all] [nodesc]`: Shows discovered skills. Use `all` to include built-in skills and `nodesc` to hide descriptions. - `/skills link [--scope user|workspace]`: Links skills from a local directory. - `/skills disable `: Prevents a specific skill from being used. - `/skills enable `: Re-enables a disabled skill. - `/skills reload` (or `/skills refresh`): Refreshes the list of discovered skills from all tiers. ### From the terminal The `gemini skills` command provides management utilities: ```bash # List all discovered skills. Use --all to include built-in skills. gemini skills list --all # Install a skill from a Git repository or local directory. # Use --consent to skip the security confirmation prompt. gemini skills install https://github.com/user/repo.git --consent # Uninstall a skill. gemini skills uninstall my-skill --scope workspace ``` #### Command options The skill management commands support several global and command-specific options. - `--scope`: Either `user` (global, default) or `workspace` (local to the project). - `--path`: The sub-directory within a Git repository containing the skill. - `--consent`: Acknowledge security risks and skip the interactive confirmation during installation. For more details on CLI commands, see the [CLI reference](/docs/cli/cli-reference#skills-management). ## Next steps Explore these resources to refine your skills and understand the framework better. - [Get started with Agent Skills](/docs/cli/tutorials/skills-getting-started): A quick walkthrough of triggering and using skills. - [Creating Agent Skills](/docs/cli/creating-skills): Create your first skill and bundle custom logic. - [Using Agent Skills](/docs/cli/using-agent-skills): Learn how to leverage built-in and custom skills. - [Best practices](/docs/cli/skills-best-practices): Learn strategies for building effective skills. # [Observability with OpenTelemetry](http://geminicli.com/docs/cli/telemetry.md) Observability is the key to turning experimental AI into reliable software. Gemini CLI provides built-in support for OpenTelemetry, transforming every agent interaction into a rich stream of logs, metrics, and traces. This three-pillar approach gives you the high-fidelity visibility needed to understand agent behavior, optimize performance, and ensure reliability across your entire workflow. Whether you are debugging a complex tool interaction locally or monitoring enterprise-wide usage in the cloud, Gemini CLI's observability system provides the actionable intelligence needed to move from "black box" AI to predictable, high-performance systems. ## OpenTelemetry integration Gemini CLI integrates with **[OpenTelemetry]**, a vendor-neutral, industry-standard observability framework. The observability system provides: - Universal compatibility: Export to any OpenTelemetry backend (Google Cloud, Jaeger, Prometheus, Datadog, etc.). - Standardized data: Use consistent formats and collection methods across your toolchain. - Future-proof integration: Connect with existing and future observability infrastructure. - No vendor lock-in: Switch between backends without changing your instrumentation. [OpenTelemetry]: https://opentelemetry.io/ ## Configuration You control telemetry behavior through the `.gemini/settings.json` file. Environment variables can override these settings. | Setting | Environment Variable | Description | Values | Default | | -------------- | --------------------------------- | --------------------------------------------------- | ----------------- | ----------------------- | | `enabled` | `GEMINI_TELEMETRY_ENABLED` | Enable or disable telemetry | `true`/`false` | `false` | | `traces` | `GEMINI_TELEMETRY_TRACES_ENABLED` | Enable detailed attribute tracing | `true`/`false` | `false` | | `target` | `GEMINI_TELEMETRY_TARGET` | Where to send telemetry data | `"gcp"`/`"local"` | `"local"` | | `otlpEndpoint` | `GEMINI_TELEMETRY_OTLP_ENDPOINT` | OTLP collector endpoint | URL string | `http://localhost:4317` | | `otlpProtocol` | `GEMINI_TELEMETRY_OTLP_PROTOCOL` | OTLP transport protocol | `"grpc"`/`"http"` | `"grpc"` | | `otlpHeaders` | `GEMINI_TELEMETRY_OTLP_HEADERS` | Custom headers for OTLP exporter requests | JSON/`key=value` | - | | `outfile` | `GEMINI_TELEMETRY_OUTFILE` | Save telemetry to file (overrides `otlpEndpoint`) | file path | - | | `logPrompts` | `GEMINI_TELEMETRY_LOG_PROMPTS` | Include prompts in telemetry logs | `true`/`false` | `true` | | `useCollector` | `GEMINI_TELEMETRY_USE_COLLECTOR` | Use external OTLP collector (advanced) | `true`/`false` | `false` | | `useCliAuth` | `GEMINI_TELEMETRY_USE_CLI_AUTH` | Use CLI credentials for telemetry (GCP target only) | `true`/`false` | `false` | | - | `GEMINI_CLI_SURFACE` | Optional custom label for traffic reporting | string | - | **Note on boolean environment variables:** For boolean settings like `enabled`, setting the environment variable to `true` or `1` enables the feature. For detailed configuration information, see the [Configuration guide](/docs/reference/configuration). ## Google Cloud telemetry You can export telemetry data directly to Google Cloud Trace, Cloud Monitoring, and Cloud Logging. ### Prerequisites You must complete several setup steps before enabling Google Cloud telemetry. 1. Set your Google Cloud project ID: - To send telemetry to a separate project: **macOS/Linux** ```bash export OTLP_GOOGLE_CLOUD_PROJECT="your-telemetry-project-id" ``` **Windows (PowerShell)** ```powershell $env:OTLP_GOOGLE_CLOUD_PROJECT="your-telemetry-project-id" ``` - To send telemetry to the same project as inference: **macOS/Linux** ```bash export GOOGLE_CLOUD_PROJECT="your-project-id" ``` **Windows (PowerShell)** ```powershell $env:GOOGLE_CLOUD_PROJECT="your-project-id" ``` 2. Authenticate with Google Cloud using one of these methods: - **Method A: Application Default Credentials (ADC)**: Use this method for service accounts or standard `gcloud` authentication. - For user accounts: ```bash gcloud auth application-default login ``` - For service accounts: **macOS/Linux** ```bash export GOOGLE_APPLICATION_CREDENTIALS="/path/to/your/service-account.json" ``` **Windows (PowerShell)** ```powershell $env:GOOGLE_APPLICATION_CREDENTIALS="C:\path\to\your\service-account.json" ``` * **Method B: CLI Auth** (Direct export only): Simplest method for local users. Gemini CLI uses the same OAuth credentials you used for login. To enable this, set `useCliAuth: true` in your `.gemini/settings.json`: ```json { "telemetry": { "enabled": true, "target": "gcp", "useCliAuth": true } } ``` > [!NOTE] > This setting requires **Direct export** (in-process exporters) > and cannot be used when `useCollector` is `true`. If both are enabled, > telemetry will be disabled. 3. Ensure your account or service account has these IAM roles: - Cloud Trace Agent - Monitoring Metric Writer - Logs Writer 4. Enable the required Google Cloud APIs: ```bash gcloud services enable \ cloudtrace.googleapis.com \ monitoring.googleapis.com \ logging.googleapis.com \ --project="$OTLP_GOOGLE_CLOUD_PROJECT" ``` ### Direct export We recommend using direct export to send telemetry directly to Google Cloud services. 1. Enable telemetry in `.gemini/settings.json`: ```json { "telemetry": { "enabled": true, "target": "gcp" } } ``` 2. Run Gemini CLI and send prompts. 3. View logs, metrics, and traces in the Google Cloud Console. See [View Google Cloud telemetry](#view-google-cloud-telemetry) for details. ### View Google Cloud telemetry After you enable telemetry and run Gemini CLI, you can view your data in the Google Cloud Console. - **Logs:** [Logs Explorer](https://console.cloud.google.com/logs/) - **Metrics:** [Metrics Explorer](https://console.cloud.google.com/monitoring/metrics-explorer) - **Traces:** [Trace Explorer](https://console.cloud.google.com/traces/list) For detailed information on how to use these tools, see the following official Google Cloud documentation: - [View and analyze logs with Logs Explorer](https://cloud.google.com/logging/docs/view/logs-explorer-interface) - [Create charts with Metrics Explorer](https://cloud.google.com/monitoring/charts/metrics-explorer) - [Find and explore traces](https://cloud.google.com/trace/docs/finding-traces) #### Monitoring dashboards Gemini CLI provides a pre-configured [Google Cloud Monitoring](https://cloud.google.com/monitoring) dashboard to visualize your telemetry. Find this dashboard under **Google Cloud Monitoring Dashboard Templates** as "**Gemini CLI Monitoring**". ![Gemini CLI Monitoring Dashboard Overview](/docs/assets/monitoring-dashboard-overview.png) ![Gemini CLI Monitoring Dashboard Metrics](/docs/assets/monitoring-dashboard-metrics.png) ![Gemini CLI Monitoring Dashboard Logs](/docs/assets/monitoring-dashboard-logs.png) To learn more, see [Instant insights: Gemini CLI’s pre-configured monitoring dashboards](https://cloud.google.com/blog/topics/developers-practitioners/instant-insights-gemini-clis-new-pre-configured-monitoring-dashboards/). ## Local telemetry You can capture telemetry data locally for development and debugging. We recommend using file-based output for local development. 1. Enable telemetry in `.gemini/settings.json`: ```json { "telemetry": { "enabled": true, "target": "local", "outfile": ".gemini/telemetry.log" } } ``` 2. Run Gemini CLI and send prompts. 3. View logs and metrics in `.gemini/telemetry.log`. For advanced local telemetry setups (such as Jaeger or Genkit), see the [Local development guide](/docs/local-development#viewing-traces). ## Client identification Gemini CLI includes identifiers in its `User-Agent` header to help you differentiate and report on API traffic from different environments (for example, identifying calls from Gemini Code Assist versus a standard terminal). ### Automatic identification Most integrated environments are identified automatically without additional configuration. The identifier is included as a prefix to the `User-Agent` and as a "surface" tag in the parenthetical metadata. | Environment | User-Agent Prefix | Surface Tag | | :---------------------------------- | :--------------------------- | :---------- | | **Gemini Code Assist (Agent Mode)** | `GeminiCLI-a2a-server` | `vscode` | | **Zed (via ACP)** | `GeminiCLI-acp-zed` | `zed` | | **XCode (via ACP)** | `GeminiCLI-acp-xcode` | `xcode` | | **IntelliJ IDEA (via ACP)** | `GeminiCLI-acp-intellijidea` | `jetbrains` | | **Standard Terminal** | `GeminiCLI` | `terminal` | **Example User-Agent:** `GeminiCLI-a2a-server/0.34.0/gemini-pro (linux; x64; vscode)` ### Custom identification You can provide a custom identifier for your own scripts or automation by setting the `GEMINI_CLI_SURFACE` environment variable. This is useful for tracking specific internal tools or distribution channels in your GCP logs. **macOS/Linux** ```bash export GEMINI_CLI_SURFACE="my-custom-tool" ``` **Windows (PowerShell)** ```powershell $env:GEMINI_CLI_SURFACE="my-custom-tool" ``` When set, the value appears at the end of the `User-Agent` parenthetical: `GeminiCLI/0.34.0/gemini-pro (linux; x64; my-custom-tool)` ## Logs, metrics, and traces This section describes the structure of logs, metrics, and traces generated by Gemini CLI. Gemini CLI includes `session.id`, `installation.id`, `active_approval_mode`, and `user.email` (when authenticated) as common attributes on all data. ### Logs Logs provide timestamped records of specific events. Gemini CLI logs events across several categories. #### Sessions Session logs capture startup configuration and prompt submissions. ##### `gemini_cli.config` Emitted at startup with the CLI configuration.
    Attributes - `model` (string) - `embedding_model` (string) - `sandbox_enabled` (boolean) - `core_tools_enabled` (string) - `approval_mode` (string) - `api_key_enabled` (boolean) - `vertex_ai_enabled` (boolean) - `log_user_prompts_enabled` (boolean) - `file_filtering_respect_git_ignore` (boolean) - `debug_mode` (boolean) - `mcp_servers` (string) - `mcp_servers_count` (int) - `mcp_tools` (string) - `mcp_tools_count` (int) - `output_format` (string) - `extensions` (string) - `extension_ids` (string) - `extensions_count` (int) - `auth_type` (string) - `worktree_active` (boolean) - `github_workflow_name` (string, optional) - `github_repository_hash` (string, optional) - `github_event_name` (string, optional) - `github_pr_number` (string, optional) - `github_issue_number` (string, optional) - `github_custom_tracking_id` (string, optional)
    ##### `gemini_cli.user_prompt` Emitted when you submit a prompt.
    Attributes - `prompt_length` (int) - `prompt_id` (string) - `prompt` (string; excluded if `telemetry.logPrompts` is `false`) - `auth_type` (string)
    #### Approval mode These logs track changes to and usage of different approval modes. ##### Lifecycle ##### `approval_mode_switch` Logs when you change the approval mode.
    Attributes - `from_mode` (string) - `to_mode` (string)
    ##### `approval_mode_duration` Records time spent in an approval mode.
    Attributes - `mode` (string) - `duration_ms` (int)
    ##### Execution ##### `plan_execution` Logs when you execute a plan and switch from plan mode to active execution.
    Attributes - `approval_mode` (string)
    #### Tools Tool logs capture executions, truncation, and edit behavior. ##### `gemini_cli.tool_call` Emitted for each tool (function) call.
    Attributes - `function_name` (string) - `function_args` (string) - `duration_ms` (int) - `success` (boolean) - `decision` (string: "accept", "reject", "auto_accept", or "modify") - `error` (string, optional) - `error_type` (string, optional) - `prompt_id` (string) - `tool_type` (string: "native" or "mcp") - `mcp_server_name` (string, optional) - `extension_name` (string, optional) - `extension_id` (string, optional) - `content_length` (int, optional) - `start_time` (number, optional) - `end_time` (number, optional) - `metadata` (object, optional), which may include: - `model_added_lines` (number) - `model_removed_lines` (number) - `user_added_lines` (number) - `user_removed_lines` (number) - `ask_user` (object)
    ##### `gemini_cli.tool_output_truncated` Logs when tool output is truncated.
    Attributes - `tool_name` (string) - `original_content_length` (int) - `truncated_content_length` (int) - `threshold` (int) - `lines` (int) - `prompt_id` (string)
    ##### `gemini_cli.edit_strategy` Records the chosen edit strategy.
    Attributes - `strategy` (string)
    ##### `gemini_cli.edit_correction` Records the result of an edit correction.
    Attributes - `correction` (string: "success" or "failure")
    ##### `gen_ai.client.inference.operation.details` Provides detailed GenAI operation data aligned with OpenTelemetry conventions.
    Attributes - `gen_ai.request.model` (string) - `gen_ai.provider.name` (string) - `gen_ai.operation.name` (string) - `gen_ai.input.messages` (json string) - `gen_ai.output.messages` (json string) - `gen_ai.response.finish_reasons` (array of strings) - `gen_ai.usage.input_tokens` (int) - `gen_ai.usage.output_tokens` (int) - `gen_ai.request.temperature` (float) - `gen_ai.request.top_p` (float) - `gen_ai.request.top_k` (int) - `gen_ai.request.max_tokens` (int) - `gen_ai.system_instructions` (json string) - `server.address` (string) - `server.port` (int)
    #### Files File logs track operations performed by tools. ##### `gemini_cli.file_operation` Emitted for each file creation, read, or update.
    Attributes - `tool_name` (string) - `operation` (string: "create", "read", or "update") - `lines` (int, optional) - `mimetype` (string, optional) - `extension` (string, optional) - `programming_language` (string, optional)
    #### API API logs capture requests, responses, and errors from Gemini API. ##### `gemini_cli.api_request` Request sent to Gemini API.
    Attributes - `model` (string) - `prompt_id` (string) - `role` (string: "user", "model", or "system") - `request_text` (string, optional)
    ##### `gemini_cli.api_response` Response received from Gemini API.
    Attributes - `model` (string) - `status_code` (int or string) - `duration_ms` (int) - `input_token_count` (int) - `output_token_count` (int) - `cached_content_token_count` (int) - `thoughts_token_count` (int) - `tool_token_count` (int) - `total_token_count` (int) - `prompt_id` (string) - `auth_type` (string) - `finish_reasons` (array of strings) - `response_text` (string, optional)
    ##### `gemini_cli.api_error` Logs when an API request fails.
    Attributes - `error.message` (string) - `model_name` (string) - `duration` (int) - `prompt_id` (string) - `auth_type` (string) - `error_type` (string, optional) - `status_code` (int or string, optional) - `role` (string, optional)
    ##### `gemini_cli.malformed_json_response` Logs when a JSON response cannot be parsed.
    Attributes - `model` (string)
    #### Model routing These logs track how Gemini CLI selects and routes requests to models. ##### `gemini_cli.slash_command` Logs slash command execution.
    Attributes - `command` (string) - `subcommand` (string, optional) - `status` (string: "success" or "error")
    ##### `gemini_cli.slash_command.model` Logs model selection via slash command.
    Attributes - `model_name` (string)
    ##### `gemini_cli.model_routing` Records model router decisions and reasoning.
    Attributes - `decision_model` (string) - `decision_source` (string) - `routing_latency_ms` (int) - `reasoning` (string, optional) - `failed` (boolean) - `error_message` (string, optional) - `approval_mode` (string)
    #### Chat and streaming These logs track chat context compression and streaming chunk errors. ##### `gemini_cli.chat_compression` Logs chat context compression events.
    Attributes - `tokens_before` (int) - `tokens_after` (int)
    ##### `gemini_cli.chat.invalid_chunk` Logs invalid chunks received in a stream.
    Attributes - `error_message` (string, optional)
    ##### `gemini_cli.chat.content_retry` Logs retries due to content errors.
    Attributes - `attempt_number` (int) - `error_type` (string) - `retry_delay_ms` (int) - `model` (string)
    ##### `gemini_cli.chat.content_retry_failure` Logs when all content retries fail.
    Attributes - `total_attempts` (int) - `final_error_type` (string) - `total_duration_ms` (int, optional) - `model` (string)
    ##### `gemini_cli.conversation_finished` Logs when a conversation session ends.
    Attributes - `approvalMode` (string) - `turnCount` (int)
    #### Resilience Resilience logs record fallback mechanisms and recovery attempts. ##### `gemini_cli.flash_fallback` Logs switch to a flash model fallback.
    Attributes - `auth_type` (string)
    ##### `gemini_cli.ripgrep_fallback` Logs fallback to standard grep.
    Attributes - `error` (string, optional)
    ##### `gemini_cli.web_fetch_fallback_attempt` Logs web-fetch fallback attempts.
    Attributes - `reason` (string: "private_ip" or "primary_failed")
    ##### `gemini_cli.agent.recovery_attempt` Logs attempts to recover from agent errors.
    Attributes - `agent_name` (string) - `attempt_number` (int) - `success` (boolean) - `error_type` (string, optional)
    #### Extensions Extension logs track lifecycle events and settings changes. ##### `gemini_cli.extension_install` Logs when you install an extension.
    Attributes - `extension_name` (string) - `extension_version` (string) - `extension_source` (string) - `status` (string)
    ##### `gemini_cli.extension_uninstall` Logs when you uninstall an extension.
    Attributes - `extension_name` (string) - `status` (string)
    ##### `gemini_cli.extension_enable` Logs when you enable an extension.
    Attributes - `extension_name` (string) - `setting_scope` (string)
    ##### `gemini_cli.extension_disable` Logs when you disable an extension.
    Attributes - `extension_name` (string) - `setting_scope` (string)
    #### Agent runs Agent logs track the lifecycle of agent executions. ##### `gemini_cli.agent.start` Logs when an agent run begins.
    Attributes - `agent_id` (string) - `agent_name` (string)
    ##### `gemini_cli.agent.finish` Logs when an agent run completes.
    Attributes - `agent_id` (string) - `agent_name` (string) - `duration_ms` (int) - `turn_count` (int) - `terminate_reason` (string)
    #### IDE IDE logs capture connectivity events for the IDE companion. ##### `gemini_cli.ide_connection` Logs IDE companion connections.
    Attributes - `connection_type` (string)
    #### UI UI logs track terminal rendering issues. ##### `kitty_sequence_overflow` Logs terminal control sequence overflows.
    Attributes - `sequence_length` (int) - `truncated_sequence` (string)
    #### Miscellaneous ##### `gemini_cli.rewind` Logs when the conversation state is rewound.
    Attributes - `outcome` (string)
    ##### `gemini_cli.conseca.verdict` Logs security verdicts from ConSeca.
    Attributes - `verdict` (string) - `decision` (string: "accept", "reject", or "modify") - `reason` (string, optional) - `tool_name` (string, optional)
    ##### `gemini_cli.hook_call` Logs execution of lifecycle hooks.
    Attributes - `hook_name` (string) - `hook_type` (string) - `duration_ms` (int) - `success` (boolean)
    ##### `gemini_cli.tool_output_masking` Logs when tool output is masked for privacy.
    Attributes - `tokens_before` (int) - `tokens_after` (int) - `masked_count` (int) - `total_prunable_tokens` (int)
    ##### `gemini_cli.keychain.availability` Logs keychain availability checks.
    Attributes - `available` (boolean) ##### `gemini_cli.startup_stats` Logs detailed startup performance statistics.
    Attributes - `phases` (json array of startup phases) - `os_platform` (string) - `os_release` (string) - `is_docker` (boolean)
    ### Metrics Metrics provide numerical measurements of behavior over time. #### Custom metrics Gemini CLI exports several custom metrics. ##### Sessions ##### `gemini_cli.session.count` Incremented once per CLI startup. ##### Onboarding Tracks onboarding flow from authentication to the user - `gemini_cli.onboarding.start` (Counter, Int): Incremented when the authentication flow begins. - `gemini_cli.onboarding.success` (Counter, Int): Incremented when the user onboarding flow completes successfully.
    Attributes (Success) - `user_tier` (string) ##### Tools ##### `gemini_cli.tool.call.count` Counts tool calls.
    Attributes - `function_name` (string) - `success` (boolean) - `decision` (string: "accept", "reject", "modify", or "auto_accept") - `tool_type` (string: "mcp" or "native")
    ##### `gemini_cli.tool.call.latency` Measures tool call latency (in ms).
    Attributes - `function_name` (string)
    ##### API ##### `gemini_cli.api.request.count` Counts all API requests.
    Attributes - `model` (string) - `status_code` (int or string) - `error_type` (string, optional)
    ##### `gemini_cli.api.request.latency` Measures API request latency (in ms).
    Attributes - `model` (string)
    ##### Token usage ##### `gemini_cli.token.usage` Counts input, output, thought, cache, and tool tokens.
    Attributes - `model` (string) - `type` (string: "input", "output", "thought", "cache", or "tool")
    ##### Files ##### `gemini_cli.file.operation.count` Counts file operations.
    Attributes - `operation` (string: "create", "read", or "update") - `lines` (int, optional) - `mimetype` (string, optional) - `extension` (string, optional) - `programming_language` (string, optional)
    ##### `gemini_cli.lines.changed` Counts added or removed lines.
    Attributes - `function_name` (string, optional) - `type` (string: "added" or "removed")
    ##### Chat and streaming ##### `gemini_cli.chat_compression` Counts compression operations.
    Attributes - `tokens_before` (int) - `tokens_after` (int)
    ##### `gemini_cli.chat.invalid_chunk.count` Counts invalid stream chunks. ##### `gemini_cli.chat.content_retry.count` Counts content error retries. ##### `gemini_cli.chat.content_retry_failure.count` Counts requests where all retries failed. ##### Model routing ##### `gemini_cli.slash_command.model.call_count` Counts model selections.
    Attributes - `slash_command.model.model_name` (string)
    ##### `gemini_cli.model_routing.latency` Measures routing decision latency.
    Attributes - `routing.decision_model` (string) - `routing.decision_source` (string) - `routing.approval_mode` (string)
    ##### `gemini_cli.model_routing.failure.count` Counts routing failures.
    Attributes - `routing.decision_source` (string) - `routing.error_message` (string) - `routing.approval_mode` (string)
    ##### Agent runs ##### `gemini_cli.agent.run.count` Counts agent runs.
    Attributes - `agent_name` (string) - `terminate_reason` (string)
    ##### `gemini_cli.agent.duration` Measures agent run duration.
    Attributes - `agent_name` (string)
    ##### `gemini_cli.agent.turns` Counts turns per agent run.
    Attributes - `agent_name` (string)
    ##### Approval mode ##### `gemini_cli.plan.execution.count` Counts plan executions.
    Attributes - `approval_mode` (string)
    ##### UI ##### `gemini_cli.ui.flicker.count` Counts terminal flicker events. ##### Performance Gemini CLI provides detailed performance metrics for advanced monitoring. ##### `gemini_cli.startup.duration` Measures startup time by phase.
    Attributes - `phase` (string) - `details` (map, optional)
    ##### `gemini_cli.memory.usage` Measures heap and RSS memory.
    Attributes - `memory_type` (string: "heap_used", "heap_total", "external", "rss") - `component` (string, optional)
    ##### `gemini_cli.cpu.usage` Measures CPU usage percentage.
    Attributes - `component` (string, optional)
    ##### `gemini_cli.tool.queue.depth` Measures tool execution queue depth. ##### `gemini_cli.tool.execution.breakdown` Breaks down tool time by phase.
    Attributes - `function_name` (string) - `phase` (string: "validation", "preparation", "execution", "result_processing")
    #### GenAI semantic convention These metrics follow standard [OpenTelemetry GenAI semantic conventions]. - `gen_ai.client.token.usage`: Counts tokens used per operation. - `gen_ai.client.operation.duration`: Measures operation duration in seconds. [OpenTelemetry GenAI semantic conventions]: https://github.com/open-telemetry/semantic-conventions/blob/main/docs/gen-ai/gen-ai-metrics.md ### Traces Traces provide an "under-the-hood" view of agent and backend operations. Use traces to debug tool interactions and optimize performance. > [!NOTE] > Detailed trace attributes (like full prompts and tool outputs) are disabled by default > to minimize overhead. You must explicitly set `telemetry.traces` to `true` (or set > `GEMINI_TELEMETRY_TRACES_ENABLED=true`) to capture them. Every trace captures rich metadata via standard span attributes.
    Standard span attributes - `gen_ai.operation.name`: High-level operation (for example, `tool_call`, `llm_call`, `user_prompt`, `system_prompt`, `agent_call`, or `schedule_tool_calls`). - `gen_ai.agent.name`: Set to `gemini-cli`. - `gen_ai.agent.description`: The service agent description. - `gen_ai.input.messages`: Input data or metadata. - `gen_ai.output.messages`: Output data or results. - `gen_ai.request.model`: Request model name. - `gen_ai.response.model`: Response model name. - `gen_ai.prompt.name`: The prompt name. - `gen_ai.tool.name`: Executed tool name. - `gen_ai.tool.call_id`: Unique ID for the tool call. - `gen_ai.tool.description`: Tool description. - `gen_ai.tool.definitions`: Tool definitions in JSON format. - `gen_ai.usage.input_tokens`: Number of input tokens. - `gen_ai.usage.output_tokens`: Number of output tokens. - `gen_ai.system_instructions`: System instructions in JSON format. - `gen_ai.conversation.id`: The CLI session ID.
    For more details on semantic conventions for events, see the [OpenTelemetry documentation](https://github.com/open-telemetry/semantic-conventions/blob/8b4f210f43136e57c1f6f47292eb6d38e3bf30bb/docs/gen-ai/gen-ai-events.md). # [System Prompt Override (GEMINI_SYSTEM_MD)](http://geminicli.com/docs/cli/system-prompt.md) The core system instructions that guide Gemini CLI can be completely replaced with your own Markdown file. This feature is controlled via the `GEMINI_SYSTEM_MD` environment variable. ## Overview The `GEMINI_SYSTEM_MD` variable instructs the CLI to use an external Markdown file for its system prompt, completely overriding the built-in default. This is a full replacement, not a merge. If you use a custom file, none of the original core instructions will apply unless you include them yourself. This feature is intended for advanced users who need to enforce strict, project-specific behavior or create a customized persona. > [!TIP] > You can export the current default system prompt to a file first, review > it, and then selectively modify or replace it (see > [β€œExport the default prompt”](#export-the-default-prompt-recommended)). ## How to enable You can set the environment variable temporarily in your shell, or persist it via a `.gemini/.env` file. See [Persisting Environment Variables](/docs/get-started/authentication#persisting-environment-variables). - Use the project default path (`.gemini/system.md`): - `GEMINI_SYSTEM_MD=true` or `GEMINI_SYSTEM_MD=1` - The CLI reads `./.gemini/system.md` (relative to your current project directory). - Use a custom file path: - `GEMINI_SYSTEM_MD=/absolute/path/to/my-system.md` - Relative paths are supported and resolved from the current working directory. - Tilde expansion is supported (for example, `~/my-system.md`). - Disable the override (use built‑in prompt): - `GEMINI_SYSTEM_MD=false` or `GEMINI_SYSTEM_MD=0` or unset the variable. If the override is enabled but the target file does not exist, the CLI will error with: `missing system prompt file ''`. ## Quick examples - One‑off session using a project file: - `GEMINI_SYSTEM_MD=1 gemini` - Persist for a project using `.gemini/.env`: - Create `.gemini/system.md`, then add to `.gemini/.env`: - `GEMINI_SYSTEM_MD=1` - Use a custom file under your home directory: - `GEMINI_SYSTEM_MD=~/prompts/system.md gemini` ## UI indicator When `GEMINI_SYSTEM_MD` is active, the CLI shows a `|βŒβ– _β– |` indicator in the UI to signal custom system‑prompt mode. ## Variable Substitution When using a custom system prompt file, you can use the following variables to dynamically include built-in content: - `${AgentSkills}`: Injects a complete section (including header) of all available agent skills. - `${SubAgents}`: Injects a complete section (including header) of available sub-agents. - `${AvailableTools}`: Injects a bulleted list of all currently enabled tool names. - Tool Name Variables: Injects the actual name of a tool using the pattern: `${toolName}_ToolName` (for example, `${write_file_ToolName}`, `${run_shell_command_ToolName}`). This pattern is generated dynamically for all available tools. ### Example ```markdown # Custom System Prompt You are a helpful assistant. ${AgentSkills} ${SubAgents} ## Tooling The following tools are available to you: ${AvailableTools} You can use ${write_file_ToolName} to save logs. ``` ## Export the default prompt (recommended) Before overriding, export the current default prompt so you can review required safety and workflow rules. - Write the built‑in prompt to the project default path: - `GEMINI_WRITE_SYSTEM_MD=1 gemini` - Or write to a custom path: - `GEMINI_WRITE_SYSTEM_MD=~/prompts/DEFAULT_SYSTEM.md gemini` This creates the file and writes the current built‑in system prompt to it. ## Best practices: system.md vs GEMINI.md - system.md (firmware): - Non‑negotiable operational rules: safety, tool‑use protocols, approvals, and mechanics that keep the CLI reliable. - Stable across tasks and projects (or per project when needed). - GEMINI.md (strategy): - Persona, goals, methodologies, and project/domain context. - Evolves per task; relies on system.md for safe execution. Keep system.md minimal but complete for safety and tool operation. Keep GEMINI.md focused on high‑level guidance and project specifics. ## Troubleshooting - Error: `missing system prompt file '…'` - Ensure the referenced path exists and is readable. - For `GEMINI_SYSTEM_MD=1|true`, create `./.gemini/system.md` in your project. - Override not taking effect - Confirm the variable is loaded (use `.gemini/.env` or export in your shell). - Paths are resolved from the current working directory; try an absolute path. - Restore defaults - Unset `GEMINI_SYSTEM_MD` or set it to `0`/`false`. # [Themes](http://geminicli.com/docs/cli/themes.md) Gemini CLI supports a variety of themes to customize its color scheme and appearance. You can change the theme to suit your preferences via the `/theme` command or `"theme":` configuration setting. ## Available themes Gemini CLI comes with a selection of pre-defined themes, which you can list using the `/theme` command within Gemini CLI: - **Dark themes:** - `ANSI` - `Atom One` - `Ayu` - `Default` - `Dracula` - `GitHub` - `Holiday` - `Shades Of Purple` - `Solarized Dark` - `Tokyo Night` - **Light themes:** - `ANSI Light` - `Ayu Light` - `Default Light` - `GitHub Light` - `Google Code` - `Solarized Light` - `Xcode` ### Changing themes 1. Enter `/theme` into Gemini CLI. 2. A dialog or selection prompt appears, listing the available themes. 3. Using the arrow keys, select a theme. Some interfaces might offer a live preview or highlight as you select. 4. Confirm your selection to apply the theme. > [!NOTE] > If a theme is defined in your `settings.json` file (either by name or > by a file path), you must remove the `"theme"` setting from the file before > you can change the theme using the `/theme` command. ### Theme persistence Selected themes are saved in Gemini CLI's [configuration](/docs/reference/configuration) so your preference is remembered across sessions. --- ## Custom color themes Gemini CLI lets you create your own custom color themes by specifying them in your `settings.json` file. This gives you full control over the color palette used in the CLI. ### How to define a custom theme Add a `customThemes` block to your user, project, or system `settings.json` file. Each custom theme is defined as an object with a unique name and a set of nested configuration objects. For example: ```json { "ui": { "customThemes": { "MyCustomTheme": { "name": "MyCustomTheme", "type": "custom", "background": { "primary": "#181818" }, "text": { "primary": "#f0f0f0", "secondary": "#a0a0a0" } } } } } ``` **Configuration objects:** - **`text`**: Defines text colors. - `primary`: The default text color. - `secondary`: Used for less prominent text. - `link`: Color for URLs and links. - `accent`: Used for highlights and emphasis. - `response`: Precedence over `primary` for rendering model responses. - **`background`**: Defines background colors. - `primary`: The main background color of the UI. - `diff.added`: Background for added lines in diffs. - `diff.removed`: Background for removed lines in diffs. - **`border`**: Defines border colors. - `default`: The standard border color. - `focused`: Border color when an element is focused. - **`status`**: Colors for status indicators. - `success`: Used for successful operations. - `warning`: Used for warnings. - `error`: Used for errors. - **`ui`**: Other UI elements. - `comment`: Color for code comments. - `symbol`: Color for code symbols and operators. - `gradient`: An array of colors used for gradient effects. **Required properties:** - `name` (must match the key in the `customThemes` object and be a string) - `type` (must be the string `"custom"`) While all sub-properties are technically optional, we recommend providing at least `background.primary`, `text.primary`, `text.secondary`, and the various accent colors via `text.link`, `text.accent`, and `status` to ensure a cohesive UI. You can use either hex codes (for example, `#FF0000`) **or** standard CSS color names (for example, `coral`, `teal`, `blue`) for any color value. See [CSS color names](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#color_keywords) for a full list of supported names. You can define multiple custom themes by adding more entries to the `customThemes` object. ### Loading themes from a file In addition to defining custom themes in `settings.json`, you can also load a theme directly from a JSON file by specifying the file path in your `settings.json`. This is useful for sharing themes or keeping them separate from your main configuration. To load a theme from a file, set the `theme` property in your `settings.json` to the path of your theme file: ```json { "ui": { "theme": "/path/to/your/theme.json" } } ``` The theme file must be a valid JSON file that follows the same structure as a custom theme defined in `settings.json`. **Example `my-theme.json`:** ```json { "name": "Gruvbox Dark", "type": "custom", "background": { "primary": "#282828", "diff": { "added": "#2b3312", "removed": "#341212" } }, "text": { "primary": "#ebdbb2", "secondary": "#a89984", "link": "#83a598", "accent": "#d3869b" }, "border": { "default": "#3c3836", "focused": "#458588" }, "status": { "success": "#b8bb26", "warning": "#fabd2f", "error": "#fb4934" }, "ui": { "comment": "#928374", "symbol": "#8ec07c", "gradient": ["#cc241d", "#d65d0e", "#d79921"] } } ``` > [!WARNING] > For your safety, Gemini CLI will only load theme files that > are located within your home directory. If you attempt to load a theme from > outside your home directory, a warning will be displayed and the theme will > not be loaded. This is to prevent loading potentially malicious theme files > from untrusted sources. ### Example custom theme Custom theme example ### Using your custom theme - Select your custom theme using the `/theme` command in Gemini CLI. Your custom theme will appear in the theme selection dialog. - Or, set it as the default by adding `"theme": "MyCustomTheme"` to the `ui` object in your `settings.json`. - Custom themes can be set at the user, project, or system level, and follow the same [configuration precedence](/docs/reference/configuration) as other settings. ### Themes from extensions [Extensions](/docs/extensions/reference#themes) can also provide custom themes. Once an extension is installed and enabled, its themes are automatically added to the selection list in the `/theme` command. Themes from extensions appear with the extension name in parentheses to help you identify their source, for example: `shades-of-green (green-extension)`. --- ## Dark themes ### ANSI ANSI theme ### Atom One Atom One theme ### Ayu Ayu theme ### Default Default theme ### Dracula Dracula theme ### GitHub GitHub theme ### Holiday Holiday theme ### Shades Of Purple Shades Of Purple theme ### Solarized Dark Solarized Dark theme ### Tokyo Night Tokyo Night theme ## Light themes ### ANSI Light ANSI Light theme ### Ayu Light Ayu Light theme ### Default Light Default Light theme ### GitHub Light GitHub Light theme ### Google Code Google Code theme ### Solarized Light Solarized Light theme ### Xcode Xcode Light theme # [Trusted Folders](http://geminicli.com/docs/cli/trusted-folders.md) The Trusted Folders feature is a security setting that gives you control over which projects can use the full capabilities of Gemini CLI. It prevents potentially malicious code from running by asking you to approve a folder before the CLI loads any project-specific configurations from it. ## Enabling the feature The Trusted Folders feature is **disabled by default**. To use it, you must first enable it in your settings. Add the following to your user `settings.json` file: ```json { "security": { "folderTrust": { "enabled": true } } } ``` ## How it works: The trust dialog Once the feature is enabled, the first time you run Gemini CLI from a folder, a dialog will automatically appear, prompting you to make a choice: - **Trust folder**: Grants full trust to the current folder (for example, `my-project`). - **Trust parent folder**: Grants trust to the parent directory (for example, `safe-projects`), which automatically trusts all of its subdirectories as well. This is useful if you keep all your safe projects in one place. - **Don't trust**: Marks the folder as untrusted. The CLI will operate in a restricted "safe mode." Your choice is saved in a central file (`~/.gemini/trustedFolders.json`), so you will only be asked once per folder. ## Understanding folder contents: The discovery phase Before you make a choice, Gemini CLI performs a **discovery phase** to scan the folder for potential configurations. This information is displayed in the trust dialog to help you make an informed decision. The discovery UI lists the following categories of items found in the project: - **Commands**: Custom `.toml` command definitions that add new functionality. - **MCP Servers**: Configured Model Context Protocol servers that the CLI will attempt to connect to. - **Hooks**: System or custom hooks that can intercept and modify CLI behavior. - **Skills**: Local agent skills that provide specialized capabilities. - **Setting overrides**: Any project-specific configurations that override your global user settings. ### Security warnings and errors The trust dialog also highlights critical information that requires your attention: - **Security Warnings**: The CLI will explicitly flag potentially dangerous settings, such as auto-approving certain tools or disabling the security sandbox. - **Discovery Errors**: If the CLI encounters issues while scanning the folder (for example, a malformed `settings.json` file), these errors will be displayed prominently. By reviewing these details, you can ensure that you only grant trust to projects that you know are safe. ## Why trust matters: The impact of an untrusted workspace When a folder is **untrusted**, Gemini CLI runs in a restricted "safe mode" to protect you. In this mode, the following features are disabled: 1. **Workspace settings are ignored**: The CLI will **not** load the `.gemini/settings.json` file from the project. This prevents the loading of custom tools and other potentially dangerous configurations. 2. **Environment variables are ignored**: The CLI will **not** load any `.env` files from the project. 3. **Extension management is restricted**: You **cannot install, update, or uninstall** extensions. 4. **Tool auto-acceptance is disabled**: You will always be prompted before any tool is run, even if you have auto-acceptance enabled globally. 5. **Automatic memory loading is disabled**: The CLI will not automatically load files into context from directories specified in local settings. 6. **MCP servers do not connect**: The CLI will not attempt to connect to any [Model Context Protocol (MCP)](/docs/tools/mcp-server) servers. 7. **Custom commands are not loaded**: The CLI will not load any custom commands from .toml files, including both project-specific and global user commands. Granting trust to a folder unlocks the full functionality of Gemini CLI for that workspace. ## Headless and automated environments When running Gemini CLI in a headless environment (for example, a CI/CD pipeline) where interactive prompts are not possible, the trust dialog cannot be displayed. If the folder is untrusted and the Folder Trust feature is enabled, the CLI will throw a `FatalUntrustedWorkspaceError` and exit. To proceed in these environments, you can bypass the trust check using one of the following methods: - **Command-line flag:** Run the CLI with the `--skip-trust` flag. - **Environment variable:** Set the `GEMINI_CLI_TRUST_WORKSPACE=true` environment variable. These methods will trust the current workspace for the duration of the session without prompting. For detailed instructions on managing folder trust within CI/CD workflows, review the [Gemini CLI trust guidance for GitHub Actions](https://github.com/google-github-actions/run-gemini-cli/blob/main/docs/trust-guidance.md). ## Overriding the trust file location By default, trust settings are saved to `~/.gemini/trustedFolders.json`. If you need to store this file in a different location, you can set the `GEMINI_CLI_TRUSTED_FOLDERS_PATH` environment variable to the desired absolute file path. ## Managing your trust settings If you need to change a decision or see all your settings, you have a couple of options: - **Change the current folder's trust**: Run the `/permissions` command from within the CLI. This will bring up the same interactive dialog, allowing you to change the trust level for the current folder. - **View all trust rules**: To see a complete list of all your trusted and untrusted folder rules, you can inspect the contents of the `~/.gemini/trustedFolders.json` file in your home directory. ## The trust check process (advanced) For advanced users, it's helpful to know the exact order of operations for how trust is determined: 1. **IDE trust signal**: If you are using the [IDE Integration](/docs/ide-integration), the CLI first asks the IDE if the workspace is trusted. The IDE's response takes highest priority. 2. **Local trust file**: If the IDE is not connected, the CLI checks the central `~/.gemini/trustedFolders.json` file. # [Managing Agent Skills](http://geminicli.com/docs/cli/using-agent-skills.md) Agent Skills provide Gemini CLI with specialized expertise on demand. This guide covers advanced management techniques, including using slash commands, terminal utilities, and understanding discovery tiers. ## Discovery tiers Gemini CLI discovers skills from several locations, following a specific order of precedence (lowest to highest): 1. **Built-in Skills**: Included with Gemini CLI and always available. 2. **Extension Skills**: Bundled within [extensions](/docs/extensions). 3. **User Skills**: Located in `~/.gemini/skills/` or the `~/.agents/skills/` alias. These are available across all your projects. 4. **Workspace Skills**: Located in `.gemini/skills/` or the `.agents/skills/` alias within your current directory. These are project-specific. > **Tip:** If multiple skills share the same name, the version from the > higher-precedence location is used. ## In-session management Use the `/skills` slash command during an interactive session to manage your available expertise. - **List skills**: `/skills list` (shows discovered skills). - Use `/skills list all` to include internal built-in skills. - Use `/skills list nodesc` to hide descriptions. - **Reload skills**: `/skills reload` (or `/skills refresh`) to scan for new or modified skills without restarting the CLI. - **Toggle status**: - `/skills disable `: Prevents a skill from being triggered. - `/skills enable `: Re-enables a disabled skill. - **Link local skills**: `/skills link [--scope user|workspace]` to immediately use a skill you are developing. ## Terminal utilities The `gemini skills` command provides management utilities directly from your system shell. ### Install a skill To install a skill from a remote repository or a local `.skill` package: ```bash gemini skills install https://github.com/user/my-awesome-skill ``` By default, this installs to your **user profile**. Use `--scope workspace` to install it only for the current project. ### Link for development If you are developing a skill, use the `link` command to create a reference to your local directory: ```bash gemini skills link ./path/to/my-skill ``` ### Uninstall a skill To completely remove an installed or linked skill: ```bash gemini skills uninstall ``` ## Security and consent Agent Skills can execute scripts and access your files. To protect your environment: 1. **Installation consent**: When installing from a remote URL, you will be asked to confirm the source. 2. **Activation consent**: Every time a skill is triggered during a session, the agent must ask for permission to activate it and gain access to its resources. ## Next steps - [Get started with Agent Skills](/docs/cli/tutorials/skills-getting-started): A walkthrough for creating your first skill. - [Creating Agent Skills](/docs/cli/creating-skills): Detailed guide on bundling scripts and assets. - [Skill best practices](/docs/cli/skills-best-practices): Strategies for building reliable expertise. # [Token caching and cost optimization](http://geminicli.com/docs/cli/token-caching.md) Gemini CLI automatically optimizes API costs through token caching when using API key authentication (Gemini API key or Vertex AI). This feature reuses previous system instructions and context to reduce the number of tokens processed in subsequent requests. **Token caching is available for:** - API key users (Gemini API key) - Vertex AI users (with project and location setup) **Token caching is not available for:** - OAuth users (Google Personal/Enterprise accounts) - the Code Assist API does not support cached content creation at this time You can view your token usage and cached token savings using the `/stats` command. When cached tokens are available, they will be displayed in the stats output. # [Gemini CLI core](http://geminicli.com/docs/core.md) Gemini CLI's core package (`packages/core`) is the backend portion of Gemini CLI, handling communication with the Gemini API, managing tools, and processing requests sent from `packages/cli`. For a general overview of Gemini CLI, see the [main documentation page](/docs). ## Navigating this section - **[Sub-agents](/docs/core/subagents):** Learn how to create and use specialized sub-agents for complex tasks. - **[Core tools reference](/docs/reference/tools):** Information on how tools are defined, registered, and used by the core. - **[Memory Import Processor](/docs/reference/memport):** Documentation for the modular GEMINI.md import feature using @file.md syntax. - **[Policy Engine](/docs/reference/policy-engine):** Use the Policy Engine for fine-grained control over tool execution. - **[Local Model Routing (experimental)](/docs/core/gemma-setup):** Learn how to enable use of a local Gemma model for model routing decisions using the automated setup command. ## Role of the core While the `packages/cli` portion of Gemini CLI provides the user interface, `packages/core` is responsible for: - **Gemini API interaction:** Securely communicating with the Google Gemini API, sending user prompts, and receiving model responses. - **Prompt engineering:** Constructing effective prompts for the Gemini model, potentially incorporating conversation history, tool definitions, and instructional context from `GEMINI.md` files. - **Tool management & orchestration:** - Registering available tools (for example, file system tools, shell command execution). - Interpreting tool use requests from the Gemini model. - Executing the requested tools with the provided arguments. - Returning tool execution results to the Gemini model for further processing. - **Session and state management:** Keeping track of the conversation state, including history and any relevant context required for coherent interactions. - **Configuration:** Managing core-specific configurations, such as API key access, model selection, and tool settings. ## Security considerations The core plays a vital role in security: - **API key management:** It handles the `GEMINI_API_KEY` and ensures it's used securely when communicating with the Gemini API. - **Tool execution:** When tools interact with the local system (for example, `run_shell_command`), the core (and its underlying tool implementations) must do so with appropriate caution, often involving sandboxing mechanisms to prevent unintended modifications. ## Chat history compression To ensure that long conversations don't exceed the token limits of the Gemini model, the core includes a chat history compression feature. When a conversation approaches the token limit for the configured model, the core automatically compresses the conversation history before sending it to the model. This compression is designed to be lossless in terms of the information conveyed, but it reduces the overall number of tokens used. You can find the token limits for each model in the [Google AI documentation](https://ai.google.dev/gemini-api/docs/models). ## Model fallback Gemini CLI includes a model fallback mechanism to ensure that you can continue to use the CLI even if the default "pro" model is rate-limited. If you are using the default "pro" model and the CLI detects that you are being rate-limited, it automatically switches to the "flash" model for the current session. This lets you continue working without interruption. Internal utility calls that use `gemini-2.5-flash-lite` (for example, prompt completion and classification) silently fall back to `gemini-2.5-flash` and `gemini-2.5-pro` when quota is exhausted, without changing the configured model. ## File discovery service The file discovery service is responsible for finding files in the project that are relevant to the current context. It is used by the `@` command and other tools that need to access files. ## Memory discovery service The memory discovery service is responsible for finding and loading the `GEMINI.md` files that provide context to the model. It searches for these files in a hierarchical manner, starting from the current working directory and moving up to the project root and the user's home directory. It also searches in subdirectories. This lets you have global, project-level, and component-level context files, which are all combined to provide the model with the most relevant information. You can use the [`/memory` command](/docs/reference/commands) to `show`, `add`, and `refresh` the content of loaded `GEMINI.md` files. ## Citations When Gemini finds it is reciting text from a source it appends the citation to the output. It is enabled by default but can be disabled with the ui.showCitations setting. - When proposing an edit the citations display before giving the user the option to accept. - Citations are always shown at the end of the model’s turn. - We deduplicate citations and display them in alphabetical order. # [Manual Local Model Routing Setup (experimental)](http://geminicli.com/docs/core/local-model-routing.md) Gemini CLI supports using a local model for [routing decisions](/docs/cli/model-routing). When configured, Gemini CLI will use a locally-running **Gemma** model to make routing decisions (instead of sending routing decisions to a hosted model). > [!NOTE] > This is an experimental feature currently under active development. > [!IMPORTANT] > **Recommended:** We now provide a fully automated setup command. We recommend > using the [`gemini gemma` Setup Guide](/docs/core/gemma-setup) instead of following > these manual steps. This feature can help reduce costs associated with hosted model usage while offering similar routing decision latency and quality. ## Manual Setup Using a Gemma model for routing decisions requires that an implementation of a Gemma model be running locally on your machine, served behind an HTTP endpoint and accessed via the Gemini API. If you cannot use the `gemini gemma setup` command, follow these manual steps: ### Download the LiteRT-LM runtime The [LiteRT-LM](https://github.com/google-ai-edge/LiteRT-LM) runtime offers pre-built binaries for locally-serving models. Download the binary appropriate for your system. #### Windows 1. Download [lit.windows_x86_64.exe](https://github.com/google-ai-edge/LiteRT-LM/releases/download/v0.9.0-alpha03/lit.windows_x86_64.exe). 2. Using GPU on Windows requires the DirectXShaderCompiler. Download the [dxc zip from the latest release](https://github.com/microsoft/DirectXShaderCompiler/releases/download/v1.8.2505.1/dxc_2025_07_14.zip). Unzip the archive and from the architecture-appropriate `bin\` directory, and copy the `dxil.dll` and `dxcompiler.dll` into the same location as you saved `lit.windows_x86_64.exe`. 3. (Optional) Test starting the runtime: `.\lit.windows_x86_64.exe serve --verbose` #### Linux 1. Download [lit.linux_x86_64](https://github.com/google-ai-edge/LiteRT-LM/releases/download/v0.9.0-alpha03/lit.linux_x86_64). 2. Ensure the binary is executable: `chmod a+x lit.linux_x86_64` 3. (Optional) Test starting the runtime: `./lit.linux_x86_64 serve --verbose` #### MacOS 1. Download [lit-macos-arm64](https://github.com/google-ai-edge/LiteRT-LM/releases/download/v0.9.0-alpha03/lit.macos_arm64). 2. Ensure the binary is executable: `chmod a+x lit.macos_arm64` 3. (Optional) Test starting the runtime: `./lit.macos_arm64 serve --verbose` > **Note**: MacOS can be configured to only allows binaries from "App Store & > Known Developers". If you encounter an error message when attempting to run > the binary, you will need to allow the application. One option is to visit > `System Settings -> Privacy & Security`, scroll to `Security`, and click > `"Allow Anyway"` for `"lit.macos_arm64"`. Another option is to run > `xattr -d com.apple.quarantine lit.macos_arm64` from the commandline. ### Download the Gemma Model Before using Gemma, you will need to download the model (and agree to the Terms of Service). This can be done via the LiteRT-LM runtime. #### Windows ```bash $ .\lit.windows_x86_64.exe pull gemma3-1b-gpu-custom [Legal] The model you are about to download is governed by the Gemma Terms of Use and Prohibited Use Policy. Please review these terms and ensure you agree before continuing. Full Terms: https://ai.google.dev/gemma/terms Prohibited Use Policy: https://ai.google.dev/gemma/prohibited_use_policy Do you accept these terms? (Y/N): Y Terms accepted. Downloading model 'gemma3-1b-gpu-custom' ... Downloading... 968.6 MB Download complete. ``` #### Linux ```bash $ ./lit.linux_x86_64 pull gemma3-1b-gpu-custom [Legal] The model you are about to download is governed by the Gemma Terms of Use and Prohibited Use Policy. Please review these terms and ensure you agree before continuing. Full Terms: https://ai.google.dev/gemma/terms Prohibited Use Policy: https://ai.google.dev/gemma/prohibited_use_policy Do you accept these terms? (Y/N): Y Terms accepted. Downloading model 'gemma3-1b-gpu-custom' ... Downloading... 968.6 MB Download complete. ``` #### MacOS ```bash $ ./lit.lit.macos_arm64 pull gemma3-1b-gpu-custom [Legal] The model you are about to download is governed by the Gemma Terms of Use and Prohibited Use Policy. Review these terms and ensure you agree before continuing. Full Terms: https://ai.google.dev/gemma/terms Prohibited Use Policy: https://ai.google.dev/gemma/prohibited_use_policy Do you accept these terms? (Y/N): Y Terms accepted. Downloading model 'gemma3-1b-gpu-custom' ... Downloading... 968.6 MB Download complete. ``` ### Start LiteRT-LM Runtime Using the command appropriate to your system, start the LiteRT-LM runtime. Configure the port that you want to use for your Gemma model. For the purposes of this document, we will use port `9379`. Example command for MacOS: `./lit.macos_arm64 serve --port=9379 --verbose` ### (Optional) Verify Model Serving Send a quick prompt to the model via HTTP to validate successful model serving. This will cause the runtime to download the model and run it once. You should see a short joke in the server output as an indicator of success. #### Windows ``` # Run this in PowerShell to send a request to the server $uri = "http://localhost:9379/v1beta/models/gemma3-1b-gpu-custom:generateContent" $body = @{contents = @( @{ role = "user" parts = @( @{ text = "Tell me a joke." } ) })} | ConvertTo-Json -Depth 10 Invoke-RestMethod -Uri $uri -Method Post -Body $body -ContentType "application/json" ``` #### Linux/MacOS ```bash $ curl "http://localhost:9379/v1beta/models/gemma3-1b-gpu-custom:generateContent" \ -H 'Content-Type: application/json' \ -X POST \ -d '{"contents":[{"role":"user","parts":[{"text":"Tell me a joke."}]}]}' ``` ## Configuration To use a local Gemma model for routing, you must explicitly enable it in your `settings.json`: ```json { "experimental": { "gemmaModelRouter": { "enabled": true, "classifier": { "host": "http://localhost:9379", "model": "gemma3-1b-gpu-custom" } } } } ``` > Use the port you started your LiteRT-LM runtime on in the setup steps. ### Configuration schema | Field | Type | Required | Description | | :----------------- | :------ | :------- | :----------------------------------------------------------------------------------------- | | `enabled` | boolean | Yes | Must be `true` to enable the feature. | | `classifier` | object | Yes | The configuration for the local model endpoint. It includes the host and model specifiers. | | `classifier.host` | string | Yes | The URL to the local model server. Should be `http://localhost:`. | | `classifier.model` | string | Yes | The model name to use for decisions. Must be `"gemma3-1b-gpu-custom"`. | > **Note: You will need to restart after configuration changes for local model > routing to take effect.** # [Subagents](http://geminicli.com/docs/core/subagents.md) Subagents are specialized agents that operate within your main Gemini CLI session. They are designed to handle specific, complex tasksβ€”like deep codebase analysis, documentation lookup, or domain-specific reasoningβ€”without cluttering the main agent's context or toolset. ## What are subagents? Subagents are "specialists" that the main Gemini agent can hire for a specific job. - **Focused context:** Each subagent has its own system prompt and persona. - **Specialized tools:** Subagents can have a restricted or specialized set of tools. - **Independent context window:** Interactions with a subagent happen in a separate context loop, which saves tokens in your main conversation history. Subagents are exposed to the main agent as a tool of the same name. When the main agent calls the tool, it delegates the task to the subagent. Once the subagent completes its task, it reports back to the main agent with its findings. ## How to use subagents You can use subagents through automatic delegation or by explicitly forcing them in your prompt. ### Automatic delegation Gemini CLI's main agent is instructed to use specialized subagents when a task matches their expertise. For example, if you ask "How does the auth system work?", the main agent may decide to call the `codebase_investigator` subagent to perform the research. ### Forcing a subagent (@ syntax) You can explicitly direct a task to a specific subagent by using the `@` symbol followed by the subagent's name at the beginning of your prompt. This is useful when you want to bypass the main agent's decision-making and go straight to a specialist. **Example:** ```bash @codebase_investigator Map out the relationship between the AgentRegistry and the LocalAgentExecutor. ``` When you use the `@` syntax, the CLI injects a system note that nudges the primary model to use that specific subagent tool immediately. ## Built-in subagents Gemini CLI comes with the following built-in subagents: ### Codebase Investigator - **Name:** `codebase_investigator` - **Purpose:** Analyze the codebase, reverse engineer, and understand complex dependencies. - **When to use:** "How does the authentication system work?", "Map out the dependencies of the `AgentRegistry` class." - **Configuration:** Enabled by default. You can override its settings in `settings.json` under `agents.overrides`. Example (forcing a specific model and increasing turns): ```json { "agents": { "overrides": { "codebase_investigator": { "modelConfig": { "model": "gemini-3-flash-preview" }, "runConfig": { "maxTurns": 50 } } } } } ``` ### CLI Help Agent - **Name:** `cli_help` - **Purpose:** Get expert knowledge about Gemini CLI itself, its commands, configuration, and documentation. - **When to use:** "How do I configure a proxy?", "What does the `/rewind` command do?" - **Configuration:** Enabled by default. ### Generalist Agent - **Name:** `generalist` - **Purpose:** A general, all-purpose subagent that uses the inherited tool access and configurations from the main agent. Useful for executing broad, resource-heavy subtasks in an isolated conversation, optimizing your main agent's context by returning only the final result of that given task. - **When to use:** Use this agent when a task requires many steps, handles large volumes of information, or requires the same full capabilities as the main agent. It is ideal for: - **Multi-file modifications:** Applying refactors or fixing errors across several files at once. - **High-volume execution:** Running commands or tests that produce extensive terminal output. - **Action-oriented research:** Investigations where the agent needs to both search code and run commands or make edits to find a solution. By delegating these tasks, you prevent your main conversation from becoming cluttered or slow. You can invoke it explicitly using `@generalist`. - **Configuration:** Enabled by default. ### Browser Agent - **Name:** `browser_agent` - **Purpose:** Automate web browser tasks β€” navigating websites, filling forms, clicking buttons, and extracting information from web pages β€” using the accessibility tree. - **When to use:** "Go to example.com and fill out the contact form," "Extract the pricing table from this page," "Click the login button and enter my credentials." #### Prerequisites The browser agent requires: - **Chrome** version 144 or later (any recent stable release works). The underlying [`chrome-devtools-mcp`](https://www.npmjs.com/package/chrome-devtools-mcp) server is bundled with Gemini CLI and launched automatically β€” no separate installation is needed. #### Enabling the browser agent The browser agent is disabled by default. Enable it in your `settings.json`: ```json { "agents": { "overrides": { "browser_agent": { "enabled": true } } } } ``` #### Session modes The `sessionMode` setting controls how Chrome is launched and managed. Set it under `agents.browser`: ```json { "agents": { "overrides": { "browser_agent": { "enabled": true } }, "browser": { "sessionMode": "persistent" } } } ``` The available modes are: | Mode | Description | | :----------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `persistent` | **(Default)** Launches Chrome with a persistent profile stored at `~/.gemini/cli-browser-profile/`. Cookies, history, and settings are preserved between sessions. | | `isolated` | Launches Chrome with a temporary profile that is deleted after each session. Use this for clean-state automation. | | `existing` | Attaches to an already-running Chrome instance. You must enable remote debugging first by navigating to `chrome://inspect/#remote-debugging` in Chrome. No new browser process is launched. | #### First-run consent The first time the browser agent is invoked, Gemini CLI displays a consent dialog. You must accept before the browser session starts. This dialog only appears once. #### Configuration reference All browser-specific settings go under `agents.browser` in your `settings.json`. For full details, see the [`agents.browser` configuration reference](/docs/reference/configuration#agents). | Setting | Type | Default | Description | | :------------------------ | :--------- | :------------- | :------------------------------------------------------------------------------ | | `sessionMode` | `string` | `"persistent"` | How Chrome is managed: `"persistent"`, `"isolated"`, or `"existing"`. | | `headless` | `boolean` | `false` | Run Chrome in headless mode (no visible window). | | `profilePath` | `string` | β€” | Custom path to a browser profile directory. | | `visualModel` | `string` | β€” | Model override for the visual agent. | | `allowedDomains` | `string[]` | β€” | Restrict navigation to specific domains (for example, `["github.com"]`). | | `disableUserInput` | `boolean` | `true` | Disable user input on the browser window during automation (non-headless only). | | `maxActionsPerTask` | `number` | `100` | Maximum tool calls per task. The agent is terminated when the limit is reached. | | `confirmSensitiveActions` | `boolean` | `false` | Require manual confirmation for `upload_file` and `evaluate_script`. | | `blockFileUploads` | `boolean` | `false` | Hard-block all file upload requests from the agent. | #### Automation overlay and input blocking In non-headless mode, the browser agent injects a visual overlay into the browser window to indicate that automation is in progress. By default, user input (keyboard and mouse) is also blocked to prevent accidental interference. You can disable this by setting `disableUserInput` to `false`. #### Security The browser agent enforces several layers of security: - **Domain restrictions:** When `allowedDomains` is set, the agent can only navigate to the listed domains (and their subdomains when using `*.` prefix). Attempting to visit a disallowed domain throws a fatal error that immediately terminates the agent. The agent also attempts to detect and block the use of allowed domains as proxies (e.g., via query parameters or fragments) to access restricted content. - **Blocked URL patterns:** The underlying MCP server blocks dangerous URL schemes including `file://`, `javascript:`, `data:text/html`, `chrome://extensions`, and `chrome://settings/passwords`. - **Sensitive action confirmation:** Form filling (`fill`, `fill_form`) always requires user confirmation through the policy engine, regardless of approval mode. When `confirmSensitiveActions` is `true`, `upload_file` and `evaluate_script` also require confirmation. - **File upload blocking:** Set `blockFileUploads` to `true` to hard-block all file upload requests, preventing the agent from uploading any files. - **Action rate limiting:** The `maxActionsPerTask` setting (default: 100) limits the total number of tool calls per task to prevent runaway execution. #### Visual agent By default, the browser agent interacts with pages through the accessibility tree using element `uid` values. For tasks that require visual identification (for example, "click the yellow button" or "find the red error message"), you can enable the visual agent by setting a `visualModel`: ```json { "agents": { "overrides": { "browser_agent": { "enabled": true } }, "browser": { "visualModel": "gemini-2.5-computer-use-preview-10-2025" } } } ``` When enabled, the agent gains access to the `analyze_screenshot` tool, which captures a screenshot and sends it to the vision model for analysis. The model returns coordinates and element descriptions that the browser agent uses with the `click_at` tool for precise, coordinate-based interactions. > [!NOTE] > The visual agent requires API key or Vertex AI authentication. It is > not available when using "Sign in with Google". #### Sandbox support The browser agent adjusts its behavior automatically when running inside a sandbox. ##### macOS seatbelt (`sandbox-exec`) When the CLI runs under the macOS seatbelt sandbox, `persistent` and `isolated` session modes are forced to `isolated` with `headless` enabled. This avoids permission errors caused by seatbelt file-system restrictions on persistent browser profiles. If `sessionMode` is set to `existing`, no override is applied. ##### Container sandboxes (Docker / Podman) Chrome is not available inside the container, so the browser agent is **disabled** unless `sessionMode` is set to `"existing"`. When enabled with `existing` mode, the agent automatically connects to Chrome on the host via the resolved IP of `host.docker.internal:9222` instead of using local pipe discovery. Port `9222` is currently hardcoded and cannot be customized. To use the browser agent in a Docker sandbox: 1. Start Chrome on the host with remote debugging enabled: ```bash # Option A: Launch Chrome from the command line google-chrome --remote-debugging-port=9222 # Option B: Enable in Chrome settings # Navigate to chrome://inspect/#remote-debugging and enable ``` 2. Configure `sessionMode` and allowed domains in your project's `.gemini/settings.json`: ```json { "agents": { "overrides": { "browser_agent": { "enabled": true } }, "browser": { "sessionMode": "existing", "allowedDomains": ["example.com"] } } } ``` 3. Launch the CLI with port forwarding: ```bash GEMINI_SANDBOX=docker SANDBOX_PORTS=9222 gemini ``` ## Creating custom subagents You can create your own subagents to automate specific workflows or enforce specific personas. ### Agent definition files Custom agents are defined as Markdown files (`.md`) with YAML frontmatter. You can place them in: 1. **Project-level:** `.gemini/agents/*.md` (Shared with your team) 2. **User-level:** `~/.gemini/agents/*.md` (Personal agents) ### File format The file **MUST** start with YAML frontmatter enclosed in triple-dashes `---`. The body of the markdown file becomes the agent's **System Prompt**. **Example: `.gemini/agents/security-auditor.md`** ```markdown --- name: security-auditor description: Specialized in finding security vulnerabilities in code. kind: local tools: - read_file - grep_search model: gemini-3-flash-preview temperature: 0.2 max_turns: 10 --- You are a ruthless Security Auditor. Your job is to analyze code for potential vulnerabilities. Focus on: 1. SQL Injection 2. XSS (Cross-Site Scripting) 3. Hardcoded credentials 4. Unsafe file operations When you find a vulnerability, explain it clearly and suggest a fix. Do not fix it yourself; just report it. ``` ### Configuration schema | Field | Type | Required | Description | | :------------- | :----- | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `name` | string | Yes | Unique identifier (slug) used as the tool name for the agent. Only lowercase letters, numbers, hyphens, and underscores. | | `description` | string | Yes | Short description of what the agent does. This is visible to the main agent to help it decide when to call this subagent. | | `kind` | string | No | `local` (default) or `remote`. | | `tools` | array | No | List of tool names this agent can use. Supports wildcards: `*` (all tools), `mcp_*` (all MCP tools), `mcp_server_*` (all tools from a server). **If omitted, it inherits all tools from the parent session.** | | `mcpServers` | object | No | Configuration for inline Model Context Protocol (MCP) servers isolated to this specific agent. | | `model` | string | No | Specific model to use (for example, `gemini-3-preview`). Defaults to `inherit` (uses the main session model). | | `temperature` | number | No | Model temperature (0.0 - 2.0). Defaults to `1`. | | `max_turns` | number | No | Maximum number of conversation turns allowed for this agent before it must return. Defaults to `30`. | | `timeout_mins` | number | No | Maximum execution time in minutes. Defaults to `10`. | ### Tool wildcards When defining `tools` for a subagent, you can use wildcards to quickly grant access to groups of tools: - `*`: Grant access to all available built-in and discovered tools. - `mcp_*`: Grant access to all tools from all connected MCP servers. - `mcp_my-server_*`: Grant access to all tools from a specific MCP server named `my-server`. ### Isolation and recursion protection Each subagent runs in its own isolated context loop. This means: - **Independent history:** The subagent's conversation history does not bloat the main agent's context. - **Isolated tools:** The subagent only has access to the tools you explicitly grant it. - **Recursion protection:** To prevent infinite loops and excessive token usage, subagents **cannot** call other subagents. If a subagent is granted the `*` tool wildcard, it will still be unable to see or invoke other agents. ## Subagent tool isolation Subagent tool isolation moves Gemini CLI away from a single global tool registry. By providing isolated execution environments, you can ensure that subagents only interact with the parts of the system they are designed for. This prevents unintended side effects, improves reliability by avoiding state contamination, and enables fine-grained permission control. With this feature, you can: - **Specify tool access:** Define exactly which tools an agent can access using a `tools` list in the agent definition. - **Define inline MCP servers:** Configure Model Context Protocol (MCP) servers (which provide a standardized way to connect AI models to external tools and data sources) directly in the subagent's markdown frontmatter, isolating them to that specific agent. - **Maintain state isolation:** Ensure that subagents only interact with their own set of tools and servers, preventing side effects and state contamination. - **Apply subagent-specific policies:** Enforce granular rules in your [Policy Engine](/docs/reference/policy-engine) TOML configuration based on the executing subagent's name. ### Configuring isolated tools and servers You can configure tool isolation for a subagent by updating its markdown frontmatter. This lets you explicitly state which tools the subagent can use, rather than relying on the global registry. Add an `mcpServers` object to define inline MCP servers that are unique to the agent. **Example:** ```yaml --- name: my-isolated-agent tools: - grep_search - read_file mcpServers: my-custom-server: command: 'node' args: ['path/to/server.js'] --- ``` ### Subagent-specific policies You can enforce fine-grained control over subagents using the [Policy Engine's](/docs/reference/policy-engine) TOML configuration. This allows you to grant or restrict permissions specifically for an agent, without affecting the rest of your CLI session. To restrict a policy rule to a specific subagent, add the `subagent` property to the `[[rules]]` block in your `policy.toml` file. **Example:** ```toml [[rules]] name = "Allow pr-creator to push code" subagent = "pr-creator" description = "Permit pr-creator to push branches automatically." action = "allow" toolName = "run_shell_command" commandPrefix = "git push" ``` In this configuration, the policy rule only triggers if the executing subagent's name matches `pr-creator`. Rules without the `subagent` property apply universally to all agents. ## Managing subagents You can manage subagents interactively using the `/agents` command or persistently via `settings.json`. ### Interactive management (/agents) If you are in an interactive CLI session, you can use the `/agents` command to manage subagents without editing configuration files manually. This is the recommended way to quickly enable, disable, or re-configure agents on the fly. For a full list of sub-commands and usage, see the [`/agents` command reference](/docs/reference/commands#agents). ### Persistent configuration (settings.json) While the `/agents` command and agent definition files provide a starting point, you can use `settings.json` for global, persistent overrides. This is useful for enforcing specific models or execution limits across all sessions. #### `agents.overrides` Use this to enable or disable specific agents or override their run configurations. ```json { "agents": { "overrides": { "security-auditor": { "enabled": false, "runConfig": { "maxTurns": 20, "maxTimeMinutes": 10 } } } } } ``` #### `modelConfigs.overrides` You can target specific subagents with custom model settings (like system instruction prefixes or specific safety settings) using the `overrideScope` field. ```json { "modelConfigs": { "overrides": [ { "match": { "overrideScope": "security-auditor" }, "modelConfig": { "generateContentConfig": { "temperature": 0.1 } } } ] } } ``` #### Safety policies (TOML) You can restrict access to specific subagents using the CLI's **Policy Engine**. Subagents are treated as virtual tool names for policy matching purposes. To govern access to a subagent, create a `.toml` file in your policy directory (e.g., `~/.gemini/policies/`): ```toml [[rule]] toolName = "codebase_investigator" decision = "deny" deny_message = "Deep codebase analysis is restricted for this session." ``` For more information on setting up fine-grained safety guardrails, see the [Policy Engine reference](/docs/reference/policy-engine#special-syntax-for-subagents). ### Optimizing your subagent The main agent's system prompt encourages it to use an expert subagent when one is available. It decides whether an agent is a relevant expert based on the agent's description. You can improve the reliability with which an agent is used by updating the description to more clearly indicate: - Its area of expertise. - When it should be used. - Some example scenarios. For example, the following subagent description should be called fairly consistently for Git operations. > Git expert agent which should be used for all local and remote git operations. > For example: > > - Making commits > - Searching for regressions with bisect > - Interacting with source control and issues providers such as GitHub. If you need to further tune your subagent, you can do so by selecting the model to optimize for with `/model` and then asking the model why it does not think that your subagent was called with a specific prompt and the given description. ## Remote subagents (Agent2Agent) Gemini CLI can also delegate tasks to remote subagents using the Agent-to-Agent (A2A) protocol. See the [Remote Subagents documentation](/docs/core/remote-agents) for detailed configuration, authentication, and usage instructions. ## Extension subagents Extensions can bundle and distribute subagents. See the [Extensions documentation](/docs/extensions#subagents) for details on how to package agents within an extension. ## Disabling subagents Subagents are enabled by default. To disable them, set `enableAgents` to `false` in your `settings.json`: ```json { "experimental": { "enableAgents": false } } ``` # [Remote Subagents](http://geminicli.com/docs/core/remote-agents.md) Gemini CLI supports connecting to remote subagents using the Agent-to-Agent (A2A) protocol. This allows Gemini CLI to interact with other agents, expanding its capabilities by delegating tasks to remote services. Gemini CLI can connect to any compliant A2A agent. You can find samples of A2A agents in the following repositories: - [ADK Samples (Python)](https://github.com/google/adk-samples/tree/main/python) - [ADK Python Contributing Samples](https://github.com/google/adk-python/tree/main/contributing/samples) ## Proxy support Gemini CLI routes traffic to remote agents through an HTTP/HTTPS proxy if one is configured. It uses the `general.proxy` setting in your `settings.json` file or standard environment variables (`HTTP_PROXY`, `HTTPS_PROXY`). ```json { "general": { "proxy": "http://my-proxy:8080" } } ``` ## Defining remote subagents Remote subagents are defined as Markdown files (`.md`) with YAML frontmatter. You can place them in: 1. **Project-level:** `.gemini/agents/*.md` (Shared with your team) 2. **User-level:** `~/.gemini/agents/*.md` (Personal agents) ### Configuration schema | Field | Type | Required | Description | | :---------------- | :----- | :------- | :------------------------------------------------------------------------------------------------------------- | | `kind` | string | Yes | Must be `remote`. | | `name` | string | Yes | A unique name for the agent. Must be a valid slug (lowercase letters, numbers, hyphens, and underscores only). | | `agent_card_url` | string | Yes\* | The URL to the agent's A2A card endpoint. Required if `agent_card_json` is not provided. | | `agent_card_json` | string | Yes\* | The inline JSON string of the agent's A2A card. Required if `agent_card_url` is not provided. | | `auth` | object | No | Authentication configuration. See [Authentication](#authentication). | ### Single-subagent example ```markdown --- kind: remote name: my-remote-agent agent_card_url: https://example.com/agent-card --- ``` ### Multi-subagent example The loader explicitly supports multiple remote subagents defined in a single Markdown file. ```markdown --- - kind: remote name: remote-1 agent_card_url: https://example.com/1 - kind: remote name: remote-2 agent_card_url: https://example.com/2 --- ``` > [!NOTE] Mixed local and remote agents, or multiple local agents, are not > supported in a single file; the list format is currently remote-only. ### Inline Agent Card JSON
    View formatting options for JSON strings If you don't have an endpoint serving the agent card, you can provide the A2A card directly as a JSON string using `agent_card_json`. When providing a JSON string in YAML, you must properly format it as a string scalar. You can use single quotes, a block scalar, or double quotes (which require escaping internal double quotes). #### Using single quotes Single quotes allow you to embed unescaped double quotes inside the JSON string. This format is useful for shorter, single-line JSON strings. ```markdown --- kind: remote name: single-quotes-agent agent_card_json: '{ "protocolVersion": "0.3.0", "name": "Example Agent", "version": "1.0.0", "url": "dummy-url" }' --- ``` #### Using a block scalar The literal block scalar (`|`) preserves line breaks and is highly recommended for multiline JSON strings as it avoids quote escaping entirely. The following is a complete, valid Agent Card configuration using dummy values. ```markdown --- kind: remote name: block-scalar-agent agent_card_json: | { "protocolVersion": "0.3.0", "name": "Example Agent Name", "description": "An example agent description for documentation purposes.", "version": "1.0.0", "url": "dummy-url", "preferredTransport": "HTTP+JSON", "capabilities": { "streaming": true, "extendedAgentCard": false }, "defaultInputModes": [ "text/plain" ], "defaultOutputModes": [ "application/json" ], "skills": [ { "id": "ExampleSkill", "name": "Example Skill Assistant", "description": "A description of what this example skill does.", "tags": [ "example-tag" ], "examples": [ "Show me an example." ] } ] } --- ``` #### Using double quotes Double quotes are also supported, but any internal double quotes in your JSON must be escaped with a backslash. ```markdown --- kind: remote name: double-quotes-agent agent_card_json: '{ "protocolVersion": "0.3.0", "name": "Example Agent", "version": "1.0.0", "url": "dummy-url" }' --- ```
    ## Authentication Many remote agents require authentication. Gemini CLI supports several authentication methods aligned with the [A2A security specification](https://a2a-protocol.org/latest/specification/#451-securityscheme). Add an `auth` block to your agent's frontmatter to configure credentials. ### Supported auth types Gemini CLI supports the following authentication types: | Type | Description | | :------------------- | :--------------------------------------------------------------------------------------------- | | `apiKey` | Send a static API key as an HTTP header. | | `http` | HTTP authentication (Bearer token, Basic credentials, or any IANA-registered scheme). | | `google-credentials` | Google Application Default Credentials (ADC). Automatically selects access or identity tokens. | | `oauth` | OAuth 2.0 Authorization Code flow with PKCE. Opens a browser for interactive sign-in. | ### Dynamic values For `apiKey` and `http` auth types, secret values (`key`, `token`, `username`, `password`, `value`) support dynamic resolution: | Format | Description | Example | | :---------- | :-------------------------------------------------- | :------------------------- | | `$ENV_VAR` | Read from an environment variable. | `$MY_API_KEY` | | `!command` | Execute a shell command and use the trimmed output. | `!gcloud auth print-token` | | literal | Use the string as-is. | `sk-abc123` | | `$$` / `!!` | Escape prefix. `$$FOO` becomes the literal `$FOO`. | `$$NOT_AN_ENV_VAR` | > **Security tip:** Prefer `$ENV_VAR` or `!command` over embedding secrets > directly in agent files, especially for project-level agents checked into > version control. ### API key (`apiKey`) Sends an API key as an HTTP header on every request. | Field | Type | Required | Description | | :----- | :----- | :------- | :---------------------------------------------------- | | `type` | string | Yes | Must be `apiKey`. | | `key` | string | Yes | The API key value. Supports dynamic values. | | `name` | string | No | Header name to send the key in. Default: `X-API-Key`. | ```yaml --- kind: remote name: my-agent agent_card_url: https://example.com/agent-card auth: type: apiKey key: $MY_API_KEY --- ``` ### HTTP authentication (`http`) Supports Bearer tokens, Basic auth, and arbitrary IANA-registered HTTP authentication schemes. #### Bearer token Use the following fields to configure a Bearer token: | Field | Type | Required | Description | | :------- | :----- | :------- | :----------------------------------------- | | `type` | string | Yes | Must be `http`. | | `scheme` | string | Yes | Must be `Bearer`. | | `token` | string | Yes | The bearer token. Supports dynamic values. | ```yaml auth: type: http scheme: Bearer token: $MY_BEARER_TOKEN ``` #### Basic authentication Use the following fields to configure Basic authentication: | Field | Type | Required | Description | | :--------- | :----- | :------- | :------------------------------------- | | `type` | string | Yes | Must be `http`. | | `scheme` | string | Yes | Must be `Basic`. | | `username` | string | Yes | The username. Supports dynamic values. | | `password` | string | Yes | The password. Supports dynamic values. | ```yaml auth: type: http scheme: Basic username: $MY_USERNAME password: $MY_PASSWORD ``` #### Raw scheme For any other IANA-registered scheme (for example, Digest, HOBA), provide the raw authorization value. | Field | Type | Required | Description | | :------- | :----- | :------- | :---------------------------------------------------------------------------- | | `type` | string | Yes | Must be `http`. | | `scheme` | string | Yes | The scheme name (for example, `Digest`). | | `value` | string | Yes | Raw value sent as `Authorization: `. Supports dynamic values. | ```yaml auth: type: http scheme: Digest value: $MY_DIGEST_VALUE ``` ### Google Application Default Credentials (`google-credentials`) Uses [Google Application Default Credentials (ADC)](https://cloud.google.com/docs/authentication/application-default-credentials) to authenticate with Google Cloud services and Cloud Run endpoints. This is the recommended auth method for agents hosted on Google Cloud infrastructure. | Field | Type | Required | Description | | :------- | :------- | :------- | :-------------------------------------------------------------------------- | | `type` | string | Yes | Must be `google-credentials`. | | `scopes` | string[] | No | OAuth scopes. Defaults to `https://www.googleapis.com/auth/cloud-platform`. | ```yaml --- kind: remote name: my-gcp-agent agent_card_url: https://my-agent-xyz.run.app/.well-known/agent.json auth: type: google-credentials --- ``` #### How token selection works The provider automatically selects the correct token type based on the agent's host: | Host pattern | Token type | Use case | | :----------------- | :----------------- | :------------------------------------------ | | `*.googleapis.com` | **Access token** | Google APIs (Agent Engine, Vertex AI, etc.) | | `*.run.app` | **Identity token** | Cloud Run services | - **Access tokens** authorize API calls to Google services. They are scoped (default: `cloud-platform`) and fetched via `GoogleAuth.getClient()`. - **Identity tokens** prove the caller's identity to a service that validates the token's audience. The audience is set to the target host. These are fetched via `GoogleAuth.getIdTokenClient()`. Both token types are cached and automatically refreshed before expiry. #### Setup `google-credentials` relies on ADC, which means your environment must have credentials configured. Common setups: - **Local development:** Run `gcloud auth application-default login` to authenticate with your Google account. - **CI / Cloud environments:** Use a service account. Set the `GOOGLE_APPLICATION_CREDENTIALS` environment variable to the path of your service account key file, or use workload identity on GKE / Cloud Run. #### Allowed hosts For security, `google-credentials` only sends tokens to known Google-owned hosts: - `*.googleapis.com` - `*.run.app` Requests to any other host will be rejected with an error. If your agent is hosted on a different domain, use one of the other auth types (`apiKey`, `http`, or `oauth`). #### Examples The following examples demonstrate how to configure Google Application Default Credentials. **Cloud Run agent:** ```yaml --- kind: remote name: cloud-run-agent agent_card_url: https://my-agent-xyz.run.app/.well-known/agent.json auth: type: google-credentials --- ``` **Google API with custom scopes:** ```yaml --- kind: remote name: vertex-agent agent_card_url: https://us-central1-aiplatform.googleapis.com/.well-known/agent.json auth: type: google-credentials scopes: - https://www.googleapis.com/auth/cloud-platform - https://www.googleapis.com/auth/compute --- ``` ### OAuth 2.0 (`oauth`) Performs an interactive OAuth 2.0 Authorization Code flow with PKCE. On first use, Gemini CLI opens your browser for sign-in and persists the resulting tokens for subsequent requests. | Field | Type | Required | Description | | :------------------ | :------- | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------- | | `type` | string | Yes | Must be `oauth`. | | `client_id` | string | Yes\* | OAuth client ID. Required for interactive auth. | | `client_secret` | string | No\* | OAuth client secret. Required by most authorization servers (confidential clients). Can be omitted for public clients that don't require a secret. | | `scopes` | string[] | No | Requested scopes. Can also be discovered from the agent card. | | `authorization_url` | string | No | Authorization endpoint. Discovered from the agent card if omitted. | | `token_url` | string | No | Token endpoint. Discovered from the agent card if omitted. | ```yaml --- kind: remote name: oauth-agent agent_card_url: https://example.com/.well-known/agent.json auth: type: oauth client_id: my-client-id.apps.example.com --- ``` If the agent card advertises an `oauth2` security scheme with `authorizationCode` flow, the `authorization_url`, `token_url`, and `scopes` are automatically discovered. You only need to provide `client_id` (and `client_secret` if required). Tokens are persisted to disk and refreshed automatically when they expire. ### Auth validation When Gemini CLI loads a remote agent, it validates your auth configuration against the agent card's declared `securitySchemes`. If the agent requires authentication that you haven't configured, you'll see an error describing what's needed. `google-credentials` is treated as compatible with `http` Bearer security schemes, since it produces Bearer tokens. ### Auth retry behavior All auth providers automatically retry on `401` and `403` responses by re-fetching credentials (up to 2 retries). This handles cases like expired tokens or rotated credentials. For `apiKey` with `!command` values, the command is re-executed on retry to fetch a fresh key. ### Agent card fetching and auth When connecting to a remote agent, Gemini CLI first fetches the agent card **without** authentication. If the card endpoint returns a `401` or `403`, it retries the fetch **with** the configured auth headers. This lets agents have publicly accessible cards while protecting their task endpoints, or to protect both behind auth. ## Managing Subagents Users can manage subagents using the following commands within Gemini CLI: - `/agents list`: Displays all available local and remote subagents. - `/agents reload`: Reloads the agent registry. Use this after adding or modifying agent definition files. - `/agents enable `: Enables a specific subagent. - `/agents disable `: Disables a specific subagent. > [!TIP] > You can use the `@cli_help` agent within Gemini CLI for assistance > with configuring subagents. ## Disabling remote agents Remote subagents are enabled by default. To disable them, set `enableAgents` to `false` in your `settings.json`: ```json { "experimental": { "enableAgents": false } } ``` # [`gemini gemma` β€” Automated Local Model Routing Setup](http://geminicli.com/docs/core/gemma-setup.md) Local model routing uses a local Gemma 3 1B model running on your machine to classify and route user requests. It routes simple requests (like file reads) to Gemini Flash and complex requests (like architecture discussions) to Gemini Pro. > [!NOTE] > This is an experimental feature currently under active development. ## What is this? This feature saves cloud API costs by using local inference for task classification instead of a cloud-based classifier. It adds a few milliseconds of local latency but can significantly reduce the overall token usage for hosted models. ## Quick start ```bash # One command does everything: downloads runtime, pulls model, configures settings, starts server gemini gemma setup ``` You'll be prompted to accept the Gemma Terms of Use. The model is ~1 GB. After setup, **just use the CLI normally** β€” routing happens automatically on every request. ## Commands | Command | What it does | | --------------------- | -------------------------------------------------------------- | | `gemini gemma setup` | Full install (binary + model + settings + server start) | | `gemini gemma status` | Health check β€” shows what's installed and running | | `gemini gemma start` | Start the LiteRT server (auto-starts on CLI launch by default) | | `gemini gemma stop` | Stop the LiteRT server | | `gemini gemma logs` | Tail the server logs to see routing requests live | | `/gemma` | In-session status check (type it inside the CLI) | ## Verifying it works 1. Run `gemini gemma status` β€” all checks should show green 2. Open two terminals: - Terminal 1: `gemini gemma logs` (watch for incoming requests) - Terminal 2: use the CLI normally 3. You should see classification requests appear in the logs as you interact with the CLI 4. The `/gemma` slash command inside a session shows a quick status panel ## Setup flags ```bash gemini gemma setup --port 8080 # custom port gemini gemma setup --no-start # don't start server after install gemini gemma setup --force # re-download everything gemini gemma setup --skip-model # binary only, skip the 1GB model download ``` ## How it works under the hood - Local Gemma classifies each request as "simple" or "complex" (~100ms) - Simple β†’ Flash, Complex β†’ Pro - If the local server is down, the CLI silently falls back to the cloud classifier β€” no errors, no disruption ## Disabling Set `enabled: false` in settings or just run `gemini gemma stop` to turn off the server: ```json { "experimental": { "gemmaModelRouter": { "enabled": false } } } ``` ## Advanced setup If you are in an environment where the `gemini gemma setup` command cannot automatically download binaries (for example, behind a strict corporate firewall), you can perform the setup manually. For more information, see the [Manual Local Model Routing Setup guide](/docs/core/local-model-routing). # [Example proxy script](http://geminicli.com/docs/examples/proxy-script.md) The following is an example of a proxy script that can be used with the `GEMINI_SANDBOX_PROXY_COMMAND` environment variable. This script only allows `HTTPS` connections to `example.com:443` and declines all other requests. ```javascript #!/usr/bin/env node /** * @license * Copyright 2025 Google LLC * SPDX-License-Identifier: Apache-2.0 */ // Example proxy server that listens on :::8877 and only allows HTTPS connections to example.com. // Set `GEMINI_SANDBOX_PROXY_COMMAND=scripts/example-proxy.js` to run proxy alongside sandbox // Test via `curl https://example.com` inside sandbox (in shell mode or via shell tool) import http from 'node:http'; import net from 'node:net'; import { URL } from 'node:url'; import console from 'node:console'; const PROXY_PORT = 8877; const ALLOWED_DOMAINS = ['example.com', 'googleapis.com']; const ALLOWED_PORT = '443'; const server = http.createServer((req, res) => { // Deny all requests other than CONNECT for HTTPS console.log( `[PROXY] Denying non-CONNECT request for: ${req.method} ${req.url}`, ); res.writeHead(405, { 'Content-Type': 'text/plain' }); res.end('Method Not Allowed'); }); server.on('connect', (req, clientSocket, head) => { // req.url will be in the format "hostname:port" for a CONNECT request. const { port, hostname } = new URL(`http://${req.url}`); console.log(`[PROXY] Intercepted CONNECT request for: ${hostname}:${port}`); if ( ALLOWED_DOMAINS.some( (domain) => hostname == domain || hostname.endsWith(`.${domain}`), ) && port === ALLOWED_PORT ) { console.log(`[PROXY] Allowing connection to ${hostname}:${port}`); // Establish a TCP connection to the original destination. const serverSocket = net.connect(port, hostname, () => { clientSocket.write('HTTP/1.1 200 Connection Established\r\n\r\n'); // Create a tunnel by piping data between the client and the destination server. serverSocket.write(head); serverSocket.pipe(clientSocket); clientSocket.pipe(serverSocket); }); serverSocket.on('error', (err) => { console.error(`[PROXY] Error connecting to destination: ${err.message}`); clientSocket.end(`HTTP/1.1 502 Bad Gateway\r\n\r\n`); }); } else { console.log(`[PROXY] Denying connection to ${hostname}:${port}`); clientSocket.end('HTTP/1.1 403 Forbidden\r\n\r\n'); } clientSocket.on('error', (err) => { // This can happen if the client hangs up. console.error(`[PROXY] Client socket error: ${err.message}`); }); }); server.listen(PROXY_PORT, () => { const address = server.address(); console.log(`[PROXY] Proxy listening on ${address.address}:${address.port}`); console.log( `[PROXY] Allowing HTTPS connections to domains: ${ALLOWED_DOMAINS.join(', ')}`, ); }); ``` # [Gemini CLI extension best practices](http://geminicli.com/docs/extensions/best-practices.md) This guide covers best practices for developing, securing, and maintaining Gemini CLI extensions. ## Development Developing extensions for Gemini CLI is a lightweight, iterative process. Use these strategies to build robust and efficient extensions. ### Structure your extension While simple extensions may contain only a few files, we recommend a organized structure for complex projects. ```text my-extension/ β”œβ”€β”€ package.json β”œβ”€β”€ tsconfig.json β”œβ”€β”€ gemini-extension.json β”œβ”€β”€ src/ β”‚ β”œβ”€β”€ index.ts β”‚ └── tools/ └── dist/ ``` - **Use TypeScript:** We strongly recommend using TypeScript for type safety and improved developer experience. - **Separate source and build:** Keep your source code in `src/` and output build artifacts to `dist/`. - **Bundle dependencies:** If your extension has many dependencies, bundle them using a tool like `esbuild` to reduce installation time and avoid conflicts. ### Iterate with `link` Use the `gemini extensions link` command to develop locally without reinstalling your extension after every change. ```bash cd my-extension gemini extensions link . ``` Changes to your code are immediately available in the CLI after you rebuild the project and restart the session. ### Use `GEMINI.md` effectively Your `GEMINI.md` file provides essential context to the model. - **Focus on goals:** Explain the high-level purpose of the extension and how to interact with its tools. - **Be concise:** Avoid dumping exhaustive documentation into the file. Use clear, direct language. - **Provide examples:** Include brief examples of how the model should use specific tools or commands. ## Security Follow the principle of least privilege and rigorous input validation when building extensions. ### Minimal permissions Only request the permissions your MCP server needs to function. Avoid giving the model broad access (such as full shell access) if restricted tools are sufficient. If your extension uses powerful tools like `run_shell_command`, restrict them in your `gemini-extension.json` file: ```json { "name": "my-safe-extension", "excludeTools": ["run_shell_command(rm -rf *)"] } ``` This ensures the CLI blocks dangerous commands even if the model attempts to execute them. ### Validate inputs Your MCP server runs on the user's machine. Always validate tool inputs to prevent arbitrary code execution or unauthorized filesystem access. ```typescript // Example: Validating paths if (!path.resolve(inputPath).startsWith(path.resolve(allowedDir) + path.sep)) { throw new Error('Access denied'); } ``` ### Secure sensitive settings If your extension requires API keys or other secrets, use the `sensitive: true` option in your manifest. This ensures keys are stored in the system keychain and obfuscated in the CLI output. ```json "settings": [ { "name": "API Key", "envVar": "MY_API_KEY", "sensitive": true } ] ``` ## Release Follow standard versioning and release practices to ensure a smooth experience for your users. ### Semantic versioning Follow [Semantic Versioning (SemVer)](https://semver.org/) to communicate changes clearly. - **Major:** Breaking changes (for example, renaming tools or changing arguments). - **Minor:** New features (for example, adding new tools or commands). - **Patch:** Bug fixes and performance improvements. ### Release channels Use Git branches to manage release channels. This lets users choose between stability and the latest features. ```bash # Install the stable version (default branch) gemini extensions install github.com/user/repo # Install the development version gemini extensions install github.com/user/repo --ref dev ``` ### Clean artifacts When using GitHub Releases, ensure your archives only contain necessary files (such as `dist/`, `gemini-extension.json`, and `package.json`). Exclude `node_modules/` and `src/` to minimize download size. ## Test and verify Test your extension thoroughly before releasing it to users. - **Manual verification:** Use `gemini extensions link` to test your extension in a live CLI session. Verify that tools appear in the debug console (F12) and that custom commands resolve correctly. - **Automated testing:** If your extension includes an MCP server, write unit tests for your tool logic using a framework like Vitest or Jest. You can test MCP tools in isolation by mocking the transport layer. ## Troubleshooting Use these tips to diagnose and fix common extension issues. ### Extension not loading If your extension doesn't appear in `/extensions list`: - **Check the manifest:** Ensure `gemini-extension.json` is in the root directory and contains valid JSON. - **Verify the name:** The `name` field in the manifest must match the extension directory name exactly. - **Restart the CLI:** Extensions are loaded at the start of a session. Restart Gemini CLI after making changes to the manifest or linking a new extension. ### MCP server failures If your tools aren't working as expected: - **Check the logs:** View the CLI logs to see if the MCP server failed to start. - **Test the command:** Run the server's `command` and `args` directly in your terminal to ensure it starts correctly outside of Gemini CLI. - **Debug console:** In interactive mode, press **F12** to open the debug console and inspect tool calls and responses. ### Command conflicts If a custom command isn't responding: - **Check precedence:** Remember that user and project commands take precedence over extension commands. Use the prefixed name (for example, `/extension.command`) to verify the extension's version. - **Help command:** Run `/help` to see a list of all available commands and their sources. # [Gemini CLI extensions](http://geminicli.com/docs/extensions.md) Gemini CLI extensions package prompts, MCP servers, custom commands, themes, hooks, sub-agents, and agent skills into a familiar and user-friendly format. With extensions, you can expand the capabilities of Gemini CLI and share those capabilities with others. They are designed to be easily installable and shareable. To see what's possible, browse the [Gemini CLI extension gallery](https://geminicli.com/extensions/browse/). ## Choose your path Choose the guide that best fits your needs. ### I want to use extensions Learn how to discover, install, and manage extensions to enhance your Gemini CLI experience. - **[Manage extensions](#manage-extensions):** List and verify your installed extensions. - **[Install extensions](#installation):** Add new capabilities from GitHub or local paths. ### I want to build extensions Learn how to create, test, and share your own extensions with the community. - **[Build extensions](/docs/extensions/writing-extensions):** Create your first extension from a template. - **[Best practices](/docs/extensions/best-practices):** Learn how to build secure and reliable extensions. - **[Publish to the gallery](/docs/extensions/releasing):** Share your work with the world. ## Manage extensions Use the interactive `/extensions` command to verify your installed extensions and their status: ```bash /extensions list ``` You can also manage extensions from your terminal using the `gemini extensions` command group: ```bash gemini extensions list ``` ## Installation Install an extension by providing its GitHub repository URL. For example: ```bash gemini extensions install https://github.com/gemini-cli-extensions/workspace ``` For more advanced installation options, see the [Extension reference](/docs/extensions/reference#install-an-extension). # [Extension reference](http://geminicli.com/docs/extensions/reference.md) This guide covers the `gemini extensions` commands and the structure of the `gemini-extension.json` configuration file. ## Manage extensions Use the `gemini extensions` command group to manage your extensions from the terminal. Note that commands like `gemini extensions install` are not supported within the CLI's interactive mode. However, you can use the `/extensions list` command to view installed extensions. All management operations, including updates to slash commands, take effect only after you restart the CLI session. ### Install an extension Install an extension by providing its GitHub repository URL or a local file path. Gemini CLI creates a copy of the extension during installation. You must run `gemini extensions update` to pull changes from the source. To install from GitHub, you must have `git` installed on your machine. ```bash gemini extensions install [--ref ] [--auto-update] [--pre-release] [--consent] [--skip-settings] ``` - ``: The GitHub URL or local path of the extension. - `--ref`: The git ref (branch, tag, or commit) to install. - `--auto-update`: Enable automatic updates for this extension. - `--pre-release`: Enable installation of pre-release versions. - `--consent`: Acknowledge security risks and skip the confirmation prompt. - `--skip-settings`: Skip the configuration on install process. ### Uninstall an extension To uninstall one or more extensions, use the `uninstall` command: ```bash gemini extensions uninstall ``` ### Disable an extension Extensions are enabled globally by default. You can disable an extension entirely or for a specific workspace. ```bash gemini extensions disable [--scope ] ``` - ``: The name of the extension to disable. - `--scope`: The scope to disable the extension in (`user` or `workspace`). ### Enable an extension Re-enable a disabled extension using the `enable` command: ```bash gemini extensions enable [--scope ] ``` - ``: The name of the extension to enable. - `--scope`: The scope to enable the extension in (`user` or `workspace`). ### Update an extension Update an extension to the version specified in its `gemini-extension.json` file. ```bash gemini extensions update ``` To update all installed extensions at once: ```bash gemini extensions update --all ``` ### Create an extension from a template Create a new extension directory using a built-in template. ```bash gemini extensions new [template] ``` - ``: The directory to create. - `[template]`: The template to use (for example, `mcp-server`, `context`, `custom-commands`). ### Link a local extension Create a symbolic link between your development directory and Gemini CLI extensions directory. This lets you test changes immediately without reinstalling. ```bash gemini extensions link ``` ## Extension format Gemini CLI loads extensions from `/.gemini/extensions`. Each extension must have a `gemini-extension.json` file in its root directory. ### `gemini-extension.json` The manifest file defines the extension's behavior and configuration. ```json { "name": "my-extension", "version": "1.0.0", "description": "My awesome extension", "mcpServers": { "my-server": { "command": "node", "args": ["${extensionPath}/my-server.js"], "cwd": "${extensionPath}" } }, "contextFileName": "GEMINI.md", "excludeTools": ["run_shell_command"], "migratedTo": "https://github.com/new-owner/new-extension-repo", "plan": { "directory": ".gemini/plans" } } ``` - `name`: The name of the extension. This is used to uniquely identify the extension and for conflict resolution when extension commands have the same name as user or project commands. The name should be lowercase or numbers and use dashes instead of underscores or spaces. This is how users will refer to your extension in the CLI. Note that we expect this name to match the extension directory name. - `version`: The version of the extension. - `description`: A short description of the extension. This will be displayed on [geminicli.com/extensions](https://geminicli.com/extensions). - `migratedTo`: The URL of the new repository source for the extension. If this is set, the CLI will automatically check this new source for updates and migrate the extension's installation to the new source if an update is found. - `mcpServers`: A map of MCP servers to settings. The key is the name of the server, and the value is the server configuration. These servers will be loaded on startup just like MCP servers defined in a [`settings.json` file](/docs/reference/configuration). If both an extension and a `settings.json` file define an MCP server with the same name, the server defined in the `settings.json` file takes precedence. - Note that all MCP server configuration options are supported except for `trust`. - For portability, you should use `${extensionPath}` to refer to files within your extension directory. - Separate your executable and its arguments using `command` and `args` instead of putting them both in `command`. - `contextFileName`: The name of the file that contains the context for the extension. This will be used to load the context from the extension directory. If this property is not used but a `GEMINI.md` file is present in your extension directory, then that file will be loaded. - `excludeTools`: An array of tool names to exclude from the model. You can also specify command-specific restrictions for tools that support it, like the `run_shell_command` tool. For example, `"excludeTools": ["run_shell_command(rm -rf)"]` will block the `rm -rf` command. Note that this differs from the MCP server `excludeTools` functionality, which can be listed in the MCP server config. - `plan`: Planning features configuration. - `directory`: The directory where planning artifacts are stored. This serves as a fallback if the user hasn't specified a plan directory in their settings. If not specified by either the extension or the user, the default is `~/.gemini/tmp///plans/`. When Gemini CLI starts, it loads all the extensions and merges their configurations. If there are any conflicts, the workspace configuration takes precedence. ### Extension settings Extensions can define settings that users provide during installation, such as API keys or URLs. These values are stored in a `.env` file within the extension directory. To define settings, add a `settings` array to your manifest: ```json { "name": "my-api-extension", "version": "1.0.0", "settings": [ { "name": "API Key", "description": "Your API key for the service.", "envVar": "MY_API_KEY", "sensitive": true } ] } ``` - `name`: The setting's display name. - `description`: A clear explanation of the setting. - `envVar`: The environment variable name where the value is stored. - `sensitive`: If `true`, the value is stored in the system keychain and obfuscated in the UI. To update an extension's settings: ```bash gemini extensions config [setting] [--scope ] ``` #### Environment variable sanitization For security reasons, sensitive environment variables are filtered out and not passed to extensions or MCP servers by default. Extensions **will not** inherit the user's full shell environment variables. They will only have access to: 1. Standard safe variables (e.g., `HOME`, `PATH`, `TMPDIR`). 2. Variables explicitly declared and requested in the `gemini-extension.json` manifest via the `settings` array (using the `envVar` property). If your extension requires specific environment variables (like an API key, custom host, or config path), you **must** declare them in the `settings` array so the CLI can allowlist them for use within the extension. ### Custom commands Provide [custom commands](/docs/cli/custom-commands) by placing TOML files in a `commands/` subdirectory. Gemini CLI uses the directory structure to determine the command name. For an extension named `gcp`: - `commands/deploy.toml` becomes `/deploy` - `commands/gcs/sync.toml` becomes `/gcs:sync` (namespaced with a colon) ### Hooks Intercept and customize CLI behavior using [hooks](/docs/hooks). Define hooks in a `hooks/hooks.json` file within your extension directory. Note that hooks are not defined in the `gemini-extension.json` manifest. ### Agent skills Bundle [agent skills](/docs/cli/skills) to provide specialized workflows. Place skill definitions in a `skills/` directory. For example, `skills/security-audit/SKILL.md` exposes a `security-audit` skill. ### Sub-agents > [!NOTE] > Sub-agents are a preview feature currently under active development. Provide [sub-agents](/docs/core/subagents) that users can delegate tasks to. Add agent definition files (`.md`) to an `agents/` directory in your extension root. ### Policy Engine Extensions can contribute policy rules and safety checkers to Gemini CLI [Policy Engine](/docs/reference/policy-engine). These rules are defined in `.toml` files and take effect when the extension is activated. To add policies, create a `policies/` directory in your extension's root and place your `.toml` policy files inside it. Gemini CLI automatically loads all `.toml` files from this directory. Rules contributed by extensions run in their own tier (tier 2), alongside workspace-defined policies. This tier has higher priority than the default rules but lower priority than user or admin policies. > [!WARNING] > For security, Gemini CLI ignores any `allow` decisions or `yolo` > mode configurations in extension policies. This ensures that an extension > cannot automatically approve tool calls or bypass security measures without > your confirmation. **Example `policies.toml`** ```toml [[rule]] mcpName = "my_server" toolName = "dangerous_tool" decision = "ask_user" priority = 100 [[safety_checker]] mcpName = "my_server" toolName = "write_data" priority = 200 [safety_checker.checker] type = "in-process" name = "allowed-path" required_context = ["environment"] ``` ### Themes Extensions can provide custom themes to personalize the CLI UI. Themes are defined in the `themes` array in `gemini-extension.json`. **Example** ```json { "name": "my-green-extension", "version": "1.0.0", "themes": [ { "name": "shades-of-green", "type": "custom", "background": { "primary": "#1a362a" }, "text": { "primary": "#a6e3a1", "secondary": "#6e8e7a", "link": "#89e689" }, "status": { "success": "#76c076", "warning": "#d9e689", "error": "#b34e4e" }, "border": { "default": "#4a6c5a" }, "ui": { "comment": "#6e8e7a" } } ] } ``` Custom themes provided by extensions can be selected using the `/theme` command or by setting the `ui.theme` property in your `settings.json` file. Note that when referring to a theme from an extension, the extension name is appended to the theme name in parentheses, for example, `shades-of-green (my-green-extension)`. ### Conflict resolution Extension commands have the lowest precedence. If an extension command name conflicts with a user or project command, the extension command is prefixed with the extension name (for example, `/gcp.deploy`) using a dot separator. ## Variables Gemini CLI supports variable substitution in `gemini-extension.json` and `hooks/hooks.json`. | Variable | Description | | :----------------- | :---------------------------------------------- | | `${extensionPath}` | The absolute path to the extension's directory. | | `${workspacePath}` | The absolute path to the current workspace. | | `${/}` | The platform-specific path separator. | # [Build Gemini CLI extensions](http://geminicli.com/docs/extensions/writing-extensions.md) Gemini CLI extensions let you expand the capabilities of Gemini CLI by adding custom tools, commands, and context. This guide walks you through creating your first extension, from setting up a template to adding custom functionality and linking it for local development. ## Prerequisites Before you start, ensure you have Gemini CLI installed and a basic understanding of Node.js. ## Extension features Extensions offer several ways to customize Gemini CLI. Use this table to decide which features your extension needs. | Feature | What it is | When to use it | Invoked by | | :------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------ | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-------------------- | | **[MCP server](/docs/extensions/reference#mcp-servers)** | A standard way to expose new tools and data sources to the model. | Use this when you want the model to be able to _do_ new things, like fetching data from an internal API, querying a database, or controlling a local application. We also support MCP resources (which can replace custom commands) and system instructions (which can replace custom context) | Model | | **[Custom commands](/docs/cli/custom-commands)** | A shortcut (like `/my-cmd`) that executes a pre-defined prompt or shell command. | Use this for repetitive tasks or to save long, complex prompts that you use frequently. Great for automation. | User | | **[Context file (`GEMINI.md`)](/docs/extensions/reference#contextfilename)** | A markdown file containing instructions that are loaded into the model's context at the start of every session. | Use this to define the "personality" of your extension, set coding standards, or provide essential knowledge that the model should always have. | CLI provides to model | | **[Agent skills](/docs/cli/skills)** | A specialized set of instructions and workflows that the model activates only when needed. | Use this for complex, occasional tasks (like "create a PR" or "audit security") to avoid cluttering the main context window when the skill isn't being used. | Model | | **[Hooks](/docs/hooks)** | A way to intercept and customize the CLI's behavior at specific lifecycle events (for example, before/after a tool call). | Use this when you want to automate actions based on what the model is doing, like validating tool arguments, logging activity, or modifying the model's input/output. | CLI | | **[Custom themes](/docs/extensions/reference#themes)** | A set of color definitions to personalize the CLI UI. | Use this to provide a unique visual identity for your extension or to offer specialized high-contrast or thematic color schemes. | User (via /theme) | ## Step 1: Create a new extension The easiest way to start is by using a built-in template. We'll use the `mcp-server` example as our foundation. Run the following command to create a new directory called `my-first-extension` with the template files: ```bash gemini extensions new my-first-extension mcp-server ``` This creates a directory with the following structure: ``` my-first-extension/ β”œβ”€β”€ example.js β”œβ”€β”€ gemini-extension.json └── package.json ``` ## Step 2: Understand the extension files Your new extension contains several key files that define its behavior. ### `gemini-extension.json` The manifest file tells Gemini CLI how to load and use your extension. ```json { "name": "mcp-server-example", "version": "1.0.0", "mcpServers": { "nodeServer": { "command": "node", "args": ["${extensionPath}${/}example.js"], "cwd": "${extensionPath}" } } } ``` - `name`: The unique name for your extension. - `version`: The version of your extension. - `mcpServers`: Defines Model Context Protocol (MCP) servers to add new tools. - `command`, `args`, `cwd`: Specify how to start your server. The `${extensionPath}` variable is replaced with the absolute path to your extension's directory. ### `example.js` This file contains the source code for your MCP server. It uses the `@modelcontextprotocol/sdk` to define tools. ```javascript /** * @license * Copyright 2025 Google LLC * SPDX-License-Identifier: Apache-2.0 */ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; import { z } from 'zod'; const server = new McpServer({ name: 'prompt-server', version: '1.0.0', }); // Registers a new tool named 'fetch_posts' server.registerTool( 'fetch_posts', { description: 'Fetches a list of posts from a public API.', inputSchema: z.object({}).shape, }, async () => { const apiResponse = await fetch( 'https://jsonplaceholder.typicode.com/posts', ); const posts = await apiResponse.json(); const response = { posts: posts.slice(0, 5) }; return { content: [ { type: 'text', text: JSON.stringify(response), }, ], }; }, ); const transport = new StdioServerTransport(); await server.connect(transport); ``` ### `package.json` The standard configuration file for a Node.js project. It defines dependencies and scripts for your extension. ## Step 3: Add extension settings Some extensions need configuration, such as API keys or user preferences. Let's add a setting for an API key. 1. Open `gemini-extension.json`. 2. Add a `settings` array to the configuration: ```json { "name": "mcp-server-example", "version": "1.0.0", "settings": [ { "name": "API Key", "description": "The API key for the service.", "envVar": "MY_SERVICE_API_KEY", "sensitive": true } ], "mcpServers": { // ... } } ``` When a user installs this extension, Gemini CLI will prompt them to enter the "API Key". The value will be stored securely in the system keychain (because `sensitive` is true) and injected into the MCP server's process as the `MY_SERVICE_API_KEY` environment variable. > **Important (Environment Variable Sanitization):** For security reasons, > sensitive environment variables are filtered out and not passed to extensions > or MCP servers by default. Extensions will _only_ have access to environment > variables that are explicitly declared in the `settings` array using the > `envVar` property, plus a few standard safe variables. Do not expect host > environment variables to be available otherwise. ## Step 4: Link your extension Link your extension to your Gemini CLI installation for local development. 1. **Install dependencies:** ```bash cd my-first-extension npm install ``` 2. **Link the extension:** The `link` command creates a symbolic link from Gemini CLI extensions directory to your development directory. Changes you make are reflected immediately. ```bash gemini extensions link . ``` Restart your Gemini CLI session to use the new `fetch_posts` tool. Test it by asking: "fetch posts". ## Step 5: Add a custom command Custom commands create shortcuts for complex prompts. 1. Create a `commands` directory and a subdirectory for your command group: **macOS/Linux** ```bash mkdir -p commands/fs ``` **Windows (PowerShell)** ```powershell New-Item -ItemType Directory -Force -Path "commands\fs" ``` 2. Create a file named `commands/fs/grep-code.toml`: ```toml prompt = """ Please summarize the findings for the pattern `{{args}}`. Search Results: !{grep -r {{args}} .} """ ``` This command, `/fs:grep-code`, takes an argument, runs the `grep` shell command, and pipes the results into a prompt for summarization. After saving the file, restart Gemini CLI. Run `/fs:grep-code "some pattern"` to use your new command. ## Step 6: Add a custom `GEMINI.md` Provide persistent context to the model by adding a `GEMINI.md` file to your extension. This is useful for setting behavior or providing essential tool information. 1. Create a file named `GEMINI.md` in the root of your extension directory: ```markdown # My First Extension Instructions You are an expert developer assistant. When the user asks you to fetch posts, use the `fetch_posts` tool. Be concise in your responses. ``` 2. Update your `gemini-extension.json` to load this file: ```json { "name": "my-first-extension", "version": "1.0.0", "contextFileName": "GEMINI.md", "mcpServers": { "nodeServer": { "command": "node", "args": ["${extensionPath}${/}example.js"], "cwd": "${extensionPath}" } } } ``` Restart Gemini CLI. The model now has the context from your `GEMINI.md` file in every session where the extension is active. ## (Optional) Step 7: Add an Agent Skill [Agent Skills](/docs/cli/skills) bundle specialized expertise and workflows. Skills are activated only when needed, which saves context tokens. 1. Create a `skills` directory and a subdirectory for your skill: **macOS/Linux** ```bash mkdir -p skills/security-audit ``` **Windows (PowerShell)** ```powershell New-Item -ItemType Directory -Force -Path "skills\security-audit" ``` 2. Create a `skills/security-audit/SKILL.md` file: ```markdown --- name: security-audit description: Expertise in auditing code for security vulnerabilities. Use when the user asks to "check for security issues" or "audit" their changes. --- # Security Auditor You are an expert security researcher. When auditing code: 1. Look for common vulnerabilities (OWASP Top 10). 2. Check for hardcoded secrets or API keys. 3. Suggest remediation steps for any findings. ``` Gemini CLI automatically discovers skills bundled with your extension. The model activates them when it identifies a relevant task. ## Step 8: Release your extension When your extension is ready, share it with others via a Git repository or GitHub Releases. Refer to the [Extension Releasing Guide](/docs/extensions/releasing) for detailed instructions and learn how to list your extension in the gallery. ## Next steps - [Extension reference](/docs/extensions/reference): Deeply understand the extension format, commands, and configuration. - [Best practices](/docs/extensions/best-practices): Learn strategies for building great extensions. # [Release extensions](http://geminicli.com/docs/extensions/releasing.md) Release Gemini CLI extensions to your users through a Git repository or GitHub Releases. This guide explains how to share your work, list it in the gallery, and manage updates. Git repository releases are the simplest approach and offer the most flexibility for managing development branches. GitHub Releases are more efficient for initial installations because they ship as single archives rather than requiring a full `git clone`. Use GitHub Releases if you need to include platform-specific binary files. ## List your extension in the gallery The [Gemini CLI extension gallery](https://geminicli.com/extensions/browse/) automatically indexes public extensions to help users discover your work. You don't need to submit an issue or email us to list your extension. To have your extension automatically discovered and listed: 1. **Use a public repository:** Ensure your extension is hosted in a public GitHub repository. 2. **Add the GitHub topic:** Add the `gemini-cli-extension` topic to your repository's **About** section. Our crawler uses this topic to find new extensions. 3. **Place the manifest at the root:** Ensure your `gemini-extension.json` file is in the absolute root of the repository or the release archive. Our system crawls tagged repositories daily. Once you tag your repository, your extension will appear in the gallery if it passes validation. ## Release through a Git repository Releasing through Git is the most flexible option. Create a public Git repository and provide the URL to your users. They can then install your extension using `gemini extensions install `. Users can optionally depend on a specific branch, tag, or commit using the `--ref` argument. For example: ```bash gemini extensions install --ref=stable ``` Whenever you push commits to the referenced branch, the CLI prompts users to update their installation. The `HEAD` commit is always treated as the latest version. ### Manage release channels You can use branches or tags to manage different release channels, such as `stable`, `preview`, or `dev`. We recommend using your default branch as the stable release channel. This ensures that the default installation command always provides the most reliable version of your extension. You can then use a `dev` branch for active development and merge it into the default branch when you are ready for a release. ## Release through GitHub Releases Distributing extensions through [GitHub Releases](https://docs.github.com/en/repositories/releasing-projects-on-github/about-releases) provides a faster installation experience by avoiding a repository clone. Gemini CLI checks for updates by looking for the **Latest** release on GitHub. Users can also install specific versions using the `--ref` argument with a release tag. Use the `--pre-release` flag to install the latest version even if it isn't marked as **Latest**. ### Custom pre-built archives You can attach custom archives directly to your GitHub Release as assets. This is useful if your extension requires a build step or includes platform-specific binaries. Custom archives must be fully self-contained and follow the required [archive structure](#archive-structure). If your extension is platform-independent, provide a single generic asset. #### Platform-specific archives To let Gemini CLI find the correct asset for a user's platform, use the following naming convention: 1. **Platform and architecture-specific:** `{platform}.{arch}.{name}.{extension}` 2. **Platform-specific:** `{platform}.{name}.{extension}` 3. **Generic:** A single asset will be used as a fallback if no specific match is found. Use these values for the placeholders: - `{name}`: Your extension name. - `{platform}`: Use `darwin` (macOS), `linux`, or `win32` (Windows). - `{arch}`: Use `x64` or `arm64`. - `{extension}`: Use `.tar.gz` or `.zip`. **Examples:** - `darwin.arm64.my-tool.tar.gz` (specific to Apple Silicon Macs) - `darwin.my-tool.tar.gz` (fallback for all Macs, for example Intel) - `linux.x64.my-tool.tar.gz` - `win32.my-tool.zip` #### Archive structure Archives must be fully contained extensions. The `gemini-extension.json` file must be at the root of the archive. The rest of the layout should match a standard extension structure. #### Example GitHub Actions workflow Use this example workflow to build and release your extension for multiple platforms: ```yaml name: Release Extension on: push: tags: - 'v*' jobs: release: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Set up Node.js uses: actions/setup-node@v3 with: node-version: '20' - name: Install dependencies run: npm ci - name: Build extension run: npm run build - name: Create release assets run: | npm run package -- --platform=darwin --arch=arm64 npm run package -- --platform=linux --arch=x64 npm run package -- --platform=win32 --arch=x64 - name: Create GitHub Release uses: softprops/action-gh-release@v1 with: files: | release/darwin.arm64.my-tool.tar.gz release/linux.arm64.my-tool.tar.gz release/win32.arm64.my-tool.zip ``` ## Migrate an extension repository If you move your extension to a new repository or rename it, use the `migratedTo` property in `gemini-extension.json` to seamlessly transition your users. 1. **Create the new repository:** Set up your extension in its new location. 2. **Update the old repository:** In your original repository, update the `gemini-extension.json` file to include the `migratedTo` property pointing to the new repository URL, and increment the version number. ```json { "name": "my-extension", "version": "1.1.0", "migratedTo": "https://github.com/new-owner/new-extension-repo" } ``` 3. **Release the update:** Publish this new version in your old repository. When users check for updates, Gemini CLI detects the `migratedTo` field, verifies the new repository, and automatically updates their local installation to track the new source. All settings migrate automatically. ## How updates work Gemini CLI automatically checks for extension updates based on the installation method. Understanding these mechanisms helps you ensure your users always have the latest version. ### Sync manifest and tags For GitHub releases, always ensure the `version` in `gemini-extension.json` matches your GitHub release tag. While the CLI uses tags for update detection, it displays the manifest version in the UI. Keeping them in sync prevents confusion. ### Update mechanisms
    Technical update details The CLI uses different strategies depending on the installation type: - **GitHub releases:** The CLI queries the GitHub API for the latest release tag. It ignores the `version` field in the manifest for detection. - **Git clones:** The CLI runs `git ls-remote` to compare the latest remote commit hash with your local `HEAD`. - **Local extensions:** The CLI compares the `version` field in the source directory's manifest with the installed version. To verify an extension's installation type, inspect the `type` field in the metadata file at `~/.gemini/extensions//.gemini-extension-install.json`.
    > [!IMPORTANT] > The `migratedTo` flow requires at least one release on the new repository for > the CLI to recognize it as a valid update source. # [Gemini CLI authentication setup](http://geminicli.com/docs/get-started/authentication.md) import { Tabs, TabItem } from '@astrojs/starlight/components'; To use Gemini CLI, you'll need to authenticate with Google. This guide helps you quickly find the best way to sign in based on your account type and how you're using the CLI. > [!TIP] > Looking for a high-level comparison of all available subscriptions? > To compare features and find the right quota for your needs, see our > [Plans page](https://geminicli.com/plans/). For most users, we recommend starting Gemini CLI and logging in with your personal Google account. ## Choose your authentication method Select the authentication method that matches your situation in the table below: | User Type / Scenario | Recommended Authentication Method | Google Cloud Project Required | | :--------------------------------------------------------------------- | :--------------------------------------------------------------- | :---------------------------------------------------------- | | Individual Google accounts | [Sign in with Google](#login-google) | No, with exceptions | | Organization users with a company, school, or Google Workspace account | [Sign in with Google](#login-google) | [Yes](#set-gcp) | | AI Studio user with a Gemini API key | [Use Gemini API Key](#gemini-api) | No | | Google Cloud Vertex AI user | [Vertex AI](#vertex-ai) | [Yes](#set-gcp) | | [Headless mode](#headless) | [Use Gemini API Key](#gemini-api) or
    [Vertex AI](#vertex-ai) | No (for Gemini API Key)
    [Yes](#set-gcp) (for Vertex AI) | ### What is my Google account type? - **Individual Google accounts:** Includes all [free tier accounts](/docs/resources/quota-and-pricing#free-usage) such as Gemini Code Assist for individuals, as well as paid subscriptions for [Google AI Pro and Ultra](https://gemini.google/subscriptions/). - **Organization accounts:** Accounts using paid licenses through an organization such as a company, school, or [Google Workspace](https://workspace.google.com/). Includes [Google AI Ultra for Business](https://support.google.com/a/answer/16345165) subscriptions. ## (Recommended) Sign in with Google If you run Gemini CLI on your local machine, the simplest authentication method is logging in with your Google account. This method requires a web browser on a machine that can communicate with the terminal running Gemini CLI (for example, your local machine). If you are a **Google AI Pro** or **Google AI Ultra** subscriber, use the Google account associated with your subscription. To authenticate and use Gemini CLI: 1. Start the CLI: ```bash gemini ``` 2. Select **Sign in with Google**. Gemini CLI opens a sign in prompt using your web browser. Follow the on-screen instructions. Your credentials will be cached locally for future sessions. ### Do I need to set my Google Cloud project? Most individual Google accounts (free and paid) don't require a Google Cloud project for authentication. However, you'll need to set a Google Cloud project when you meet at least one of the following conditions: - You are using a company, school, or Google Workspace account. - You are using a Gemini Code Assist license from the Google Developer Program. - You are using a license from a Gemini Code Assist subscription. For instructions, see [Set your Google Cloud Project](#set-gcp). ## Use Gemini API key If you don't want to authenticate using your Google account, you can use an API key from Google AI Studio. To authenticate and use Gemini CLI with a Gemini API key: 1. Obtain your API key from [Google AI Studio](https://aistudio.google.com/app/apikey). 2. Set the `GEMINI_API_KEY` environment variable to your key. For example: ```bash # Replace YOUR_GEMINI_API_KEY with the key from AI Studio export GEMINI_API_KEY="YOUR_GEMINI_API_KEY" ``` ```powershell # Replace YOUR_GEMINI_API_KEY with the key from AI Studio $env:GEMINI_API_KEY="YOUR_GEMINI_API_KEY" ``` To make this setting persistent, see [Persisting Environment Variables](#persisting-vars). 3. Start the CLI: ```bash gemini ``` 4. Select **Use Gemini API key**. > [!WARNING] > Treat API keys, especially for services like Gemini, as sensitive > credentials. Protect them to prevent unauthorized access and potential misuse > of the service under your account. ## Use Vertex AI To use Gemini CLI with Google Cloud's Vertex AI platform, choose from the following authentication options: - A. Application Default Credentials (ADC) using `gcloud`. - B. Service account JSON key. - C. Google Cloud API key. Regardless of your authentication method for Vertex AI, you'll need to set `GOOGLE_CLOUD_PROJECT` to your Google Cloud project ID with the Vertex AI API enabled, and `GOOGLE_CLOUD_LOCATION` to the [location of your Vertex AI resources](https://cloud.google.com/vertex-ai/generative-ai/docs/learn/locations) or the location where you want to run your jobs. For example: ```bash # Replace with your project ID and desired location (for example, us-central1) export GOOGLE_CLOUD_PROJECT="YOUR_PROJECT_ID" export GOOGLE_CLOUD_LOCATION="YOUR_PROJECT_LOCATION" ``` ```powershell # Replace with your project ID and desired location (for example, us-central1) $env:GOOGLE_CLOUD_PROJECT="YOUR_PROJECT_ID" $env:GOOGLE_CLOUD_LOCATION="YOUR_PROJECT_LOCATION" ``` To make any Vertex AI environment variable settings persistent, see [Persisting Environment Variables](#persisting-vars). #### A. Vertex AI - application default credentials (ADC) using `gcloud` Consider this authentication method if you have Google Cloud CLI installed. If you have previously set `GOOGLE_API_KEY` or `GEMINI_API_KEY`, you must unset them to use ADC. ```bash unset GOOGLE_API_KEY GEMINI_API_KEY ``` ```powershell Remove-Item Env:\GOOGLE_API_KEY, Env:\GEMINI_API_KEY -ErrorAction Ignore ``` 1. Verify you have a Google Cloud project and Vertex AI API is enabled. 2. Log in to Google Cloud: ```bash gcloud auth application-default login ``` 3. [Configure your Google Cloud Project](#set-gcp). 4. Start the CLI: ```bash gemini ``` 5. Select **Vertex AI**. #### B. Vertex AI - service account JSON key Consider this method of authentication in non-interactive environments, CI/CD pipelines, or if your organization restricts user-based ADC or API key creation. If you have previously set `GOOGLE_API_KEY` or `GEMINI_API_KEY`, you must unset them: ```bash unset GOOGLE_API_KEY GEMINI_API_KEY ``` ```powershell Remove-Item Env:\GOOGLE_API_KEY, Env:\GEMINI_API_KEY -ErrorAction Ignore ``` 1. [Create a service account and key](https://cloud.google.com/iam/docs/keys-create-delete) and download the provided JSON file. Assign the "Vertex AI User" role to the service account. 2. Set the `GOOGLE_APPLICATION_CREDENTIALS` environment variable to the JSON file's absolute path. For example: ```bash # Replace /path/to/your/keyfile.json with the actual path export GOOGLE_APPLICATION_CREDENTIALS="/path/to/your/keyfile.json" ``` ```powershell # Replace C:\path\to\your\keyfile.json with the actual path $env:GOOGLE_APPLICATION_CREDENTIALS="C:\path\to\your\keyfile.json" ``` 3. [Configure your Google Cloud Project](#set-gcp). 4. Start the CLI: ```bash gemini ``` 5. Select **Vertex AI**. > [!WARNING] > Protect your service account key file as it gives access to > your resources. #### C. Vertex AI - Google Cloud API key 1. Obtain a Google Cloud API key: [Get an API Key](https://cloud.google.com/vertex-ai/generative-ai/docs/start/api-keys?usertype=newuser). 2. Set the `GOOGLE_API_KEY` environment variable: ```bash # Replace YOUR_GOOGLE_API_KEY with your Vertex AI API key export GOOGLE_API_KEY="YOUR_GOOGLE_API_KEY" ``` ```powershell # Replace YOUR_GOOGLE_API_KEY with your Vertex AI API key $env:GOOGLE_API_KEY="YOUR_GOOGLE_API_KEY" ``` If you see errors like `"API keys are not supported by this API..."`, your organization might restrict API key usage for this service. Try the other Vertex AI authentication methods instead. 3. [Configure your Google Cloud Project](#set-gcp). 4. Start the CLI: ```bash gemini ``` 5. Select **Vertex AI**. ## Set your Google Cloud project > [!IMPORTANT] > Most individual Google accounts (free and paid) don't require a > Google Cloud project for authentication. When you sign in using your Google account, you may need to configure a Google Cloud project for Gemini CLI to use. This applies when you meet at least one of the following conditions: - You are using a Company, School, or Google Workspace account. - You are using a Gemini Code Assist license from the Google Developer Program. - You are using a license from a Gemini Code Assist subscription. To configure Gemini CLI to use a Google Cloud pro