mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-07-23 00:01:24 -07:00
Compare commits
134 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7d32f2bf88 | |||
| c991e5b3dc | |||
| c1560d99fd | |||
| 377186d831 | |||
| 64853dbfde | |||
| 52d9271e63 | |||
| 6732115859 | |||
| 7718709f01 | |||
| 4e2856c4dd | |||
| c7ec983d31 | |||
| 067d0ecab3 | |||
| fb1b2891cc | |||
| 2bc2945d14 | |||
| 1c8a37379b | |||
| 1620c7d82f | |||
| f4100baf6b | |||
| 0b93c868e9 | |||
| 7cfbb6fb71 | |||
| a105768de8 | |||
| 347f3fe7e4 | |||
| 25803e05fd | |||
| 774ae220be | |||
| 813e0c18ac | |||
| 3f6cec22e6 | |||
| 3966f3c053 | |||
| 2e3cbd6363 | |||
| 8b1dc15182 | |||
| fa9aee2bf0 | |||
| 6628cbb39d | |||
| aa9163da60 | |||
| ec0f23ae03 | |||
| ac04c388e0 | |||
| 621ddbe744 | |||
| c537fd5aec | |||
| a91bc60e18 | |||
| faa1ec3044 | |||
| d96bd05d36 | |||
| 84666e1bbc | |||
| a7d851146a | |||
| acb7f577de | |||
| d2d345f41a | |||
| dfd7721e69 | |||
| 09218572d0 | |||
| 5d98ed5820 | |||
| 727f9b67b1 | |||
| 547f5d45f5 | |||
| 58d637f919 | |||
| b746524a1b | |||
| c5baf39dbd | |||
| b48970da15 | |||
| 9a8e5d3940 | |||
| 089aec8b8d | |||
| b7555ab1e1 | |||
| c04602f209 | |||
| a01d7e9a05 | |||
| 49b2e76ee1 | |||
| aed348a99c | |||
| 7cf4c05c66 | |||
| cdf157e52a | |||
| 723f269df6 | |||
| 239aa0909c | |||
| 6cfd29ef9b | |||
| f97b04cc9a | |||
| 788a40c445 | |||
| ce03156c9f | |||
| fe428936d5 | |||
| d24f10b087 | |||
| d54702185b | |||
| 27b7fc04de | |||
| be03e0619f | |||
| 2bb7aaecd0 | |||
| 0f855fc0c4 | |||
| c7e309efc9 | |||
| 429932c663 | |||
| d08b1efc72 | |||
| c3b52b8206 | |||
| 5fd557347e | |||
| cbfb2a4e26 | |||
| fb1b1b451d | |||
| 99fa700231 | |||
| f1c0a695f8 | |||
| 6351352e54 | |||
| 2ac39b6acc | |||
| d8b24e6983 | |||
| d25c469f77 | |||
| 537e56ffae | |||
| 2cba2ab37a | |||
| 8064973899 | |||
| ddc5458451 | |||
| a468407098 | |||
| 264c7aceaa | |||
| 3408542a66 | |||
| c276d0c7b6 | |||
| a00eb3b8e6 | |||
| 372f41eab8 | |||
| 09b623fbd7 | |||
| ba3e327ba1 | |||
| 5d235952ba | |||
| 082f41f54d | |||
| 880af43b02 | |||
| 966eef14ee | |||
| b79e5ce56d | |||
| 1a8d77329e | |||
| ad9c49a604 | |||
| 70b427c7dd | |||
| a804f99fe0 | |||
| c43500c50b | |||
| 42a7d89999 | |||
| 04f65f3d55 | |||
| 04c52513e7 | |||
| c62340675a | |||
| ef65498031 | |||
| 261788cf91 | |||
| 012392ad0a | |||
| 037061e2e0 | |||
| 221ea360b9 | |||
| 8910b2720f | |||
| 87f5dd15d6 | |||
| 81c8893e05 | |||
| 178388d931 | |||
| e7f97dfa44 | |||
| f961e0d6b1 | |||
| 14415316c0 | |||
| 1cf05b0375 | |||
| 3099df1b7c | |||
| 758d419e33 | |||
| 78de533c48 | |||
| 8f6a711a3a | |||
| 65ad78b9c0 | |||
| 858918fe31 | |||
| 9255e69abb | |||
| e32111e609 | |||
| 2c1d6f8029 | |||
| 8a8826654c |
@@ -1,64 +1,142 @@
|
||||
# Gemini CLI Strict Development Rules
|
||||
|
||||
These rules apply strictly to all code modifications and additions within the Gemini CLI project.
|
||||
These rules apply strictly to all code modifications and additions within the
|
||||
Gemini CLI project.
|
||||
|
||||
## Testing Guidelines
|
||||
|
||||
* **Async/Await**: Always use `waitFor` from `packages/cli/src/test-utils/async.ts` instead of `vi.waitFor` for all `waitFor` calls within `packages/cli`. NEVER use fixed waits (e.g., `await delay(100)`). Always use `waitFor` with a predicate to ensure tests are stable and fast. Using the wrong `waitFor` can result in flaky tests and `act` warnings.
|
||||
* **React Testing**: Use `act` to wrap all blocks in tests that change component state. Use `render` or `renderWithProviders` from `packages/cli/src/test-utils/render.tsx` instead of `render` from `ink-testing-library` directly. This prevents spurious `act` warnings. If test cases specify providers directly, consider whether the existing `renderWithProviders` should be modified.
|
||||
* **Snapshots**: Use `toMatchSnapshot` to verify that rendering works as expected rather than matching against the raw content of the output. When modifying snapshots, verify the changes are intentional and do not hide underlying bugs.
|
||||
* **Parameterized Tests**: Use parameterized tests where it reduces duplicated lines. Give the parameters explicit types to ensure the tests are type-safe.
|
||||
* **Mocks Management**:
|
||||
* Mock critical dependencies (`fs`, `os`, `child_process`) ONLY at the top of the file. Ideally, avoid mocking these dependencies altogether.
|
||||
* Reuse existing mocks and fakes rather than creating new ones.
|
||||
* Avoid mocking the file system whenever possible. If using the real file system is too difficult, consider writing an integration test instead.
|
||||
* Always call `vi.restoreAllMocks()` in `afterEach` to prevent test pollution.
|
||||
* Use `vi.useFakeTimers()` for tests involving time-based logic to avoid flakiness.
|
||||
* **Typing in Tests**: Avoid using `any` in tests; prefer proper types or `unknown` with narrowing.
|
||||
- **Async/Await**: Always use `waitFor` from
|
||||
`packages/cli/src/test-utils/async.ts` instead of `vi.waitFor` for all
|
||||
`waitFor` calls within `packages/cli`. NEVER use fixed waits (e.g.,
|
||||
`await delay(100)`). Always use `waitFor` with a predicate to ensure tests are
|
||||
stable and fast. Using the wrong `waitFor` can result in flaky tests and `act`
|
||||
warnings.
|
||||
- **React Testing**: Use `act` to wrap all blocks in tests that change component
|
||||
state. Use `render` or `renderWithProviders` from
|
||||
`packages/cli/src/test-utils/render.tsx` instead of `render` from
|
||||
`ink-testing-library` directly. This prevents spurious `act` warnings. If test
|
||||
cases specify providers directly, consider whether the existing
|
||||
`renderWithProviders` should be modified.
|
||||
- **Snapshots**: Use `toMatchSnapshot` to verify that rendering works as
|
||||
expected rather than matching against the raw content of the output. When
|
||||
modifying snapshots, verify the changes are intentional and do not hide
|
||||
underlying bugs.
|
||||
- **Parameterized Tests**: Use parameterized tests where it reduces duplicated
|
||||
lines. Give the parameters explicit types to ensure the tests are type-safe.
|
||||
- **Mocks Management**:
|
||||
- Mock critical dependencies (`fs`, `os`, `child_process`) ONLY at the top of
|
||||
the file. Ideally, avoid mocking these dependencies altogether.
|
||||
- Reuse existing mocks and fakes rather than creating new ones.
|
||||
- Avoid mocking the file system whenever possible. If using the real file
|
||||
system is too difficult, consider writing an integration test instead.
|
||||
- Always call `vi.restoreAllMocks()` in `afterEach` to prevent test pollution.
|
||||
- Use `vi.useFakeTimers()` for tests involving time-based logic to avoid
|
||||
flakiness.
|
||||
- **Typing in Tests**: Avoid using `any` in tests; prefer proper types or
|
||||
`unknown` with narrowing.
|
||||
|
||||
## React Guidelines (`packages/cli`)
|
||||
|
||||
* **`setState` and Side Effects**: NEVER trigger side effects from within the body of a `setState` callback. Use a reducer or `useRef` if necessary. These cases have historically introduced multiple bugs; typically, they should be resolved using a reducer.
|
||||
* **Rendering**: Do not introduce infinite rendering loops. Avoid synchronous file I/O in React components as it will hang the UI. Do not implement new logic for custom string measurement or string truncation. Use Ink layout instead, leveraging `ResizeObserver` as needed.
|
||||
* **Keyboard Handling**: Keyboard handling MUST go through `useKeyPress.ts` from the Gemini CLI package rather than the standard ink library. This library supports reporting multiple keyboard events sequentially in the same React frame (critical for slow terminals). Handling this correctly often requires reducers to ensure multiple state updates are handled gracefully without overriding values. Refer to `text-buffer.ts` for a canonical example.
|
||||
* **Logging**: Do not leave `console.log`, `console.warn`, or `console.error` in the code.
|
||||
* **State & Effects**: Ensure state initialization is explicit (e.g., use `undefined` rather than `true` as a default if the state is truly unknown). Carefully manage `useEffect` dependencies. Prefer a reducer whenever practical. NEVER disable `react-hooks/exhaustive-deps`; fix the code to correctly declare dependencies instead.
|
||||
* **Context & Props**: Avoid excessive property drilling. Leverage existing providers, extend them, or propose a new one if necessary. Only use providers for properties that are consistent across the entire application.
|
||||
* **Code Structure**: Avoid complex `if` statements where `switch` statements could be used. Keep `AppContainer` minimal; refactor complex logic into React hooks. Evaluate whether business logic should be added to `hookSystem.ts` or integrated into `packages/core` rather than `packages/cli`.
|
||||
- **`setState` and Side Effects**: NEVER trigger side effects from within the
|
||||
body of a `setState` callback. Use a reducer or `useRef` if necessary. These
|
||||
cases have historically introduced multiple bugs; typically, they should be
|
||||
resolved using a reducer.
|
||||
- **Rendering**: Do not introduce infinite rendering loops. Avoid synchronous
|
||||
file I/O in React components as it will hang the UI. Do not implement new
|
||||
logic for custom string measurement or string truncation. Use Ink layout
|
||||
instead, leveraging `ResizeObserver` as needed.
|
||||
- **Keyboard Handling**: Keyboard handling MUST go through `useKeyPress.ts` from
|
||||
the Gemini CLI package rather than the standard ink library. This library
|
||||
supports reporting multiple keyboard events sequentially in the same React
|
||||
frame (critical for slow terminals). Handling this correctly often requires
|
||||
reducers to ensure multiple state updates are handled gracefully without
|
||||
overriding values. Refer to `text-buffer.ts` for a canonical example.
|
||||
- **Logging**: Do not leave `console.log`, `console.warn`, or `console.error` in
|
||||
the code.
|
||||
- **State & Effects**: Ensure state initialization is explicit (e.g., use
|
||||
`undefined` rather than `true` as a default if the state is truly unknown).
|
||||
Carefully manage `useEffect` dependencies. Prefer a reducer whenever
|
||||
practical. NEVER disable `react-hooks/exhaustive-deps`; fix the code to
|
||||
correctly declare dependencies instead.
|
||||
- **Context & Props**: Avoid excessive property drilling. Leverage existing
|
||||
providers, extend them, or propose a new one if necessary. Only use providers
|
||||
for properties that are consistent across the entire application.
|
||||
- **Code Structure**: Avoid complex `if` statements where `switch` statements
|
||||
could be used. Keep `AppContainer` minimal; refactor complex logic into React
|
||||
hooks. Evaluate whether business logic should be added to `hookSystem.ts` or
|
||||
integrated into `packages/core` rather than `packages/cli`.
|
||||
|
||||
## Core Guidelines (`packages/core`)
|
||||
|
||||
* **Services**: Implement services as classes with clear lifecycle management (e.g., `initialize()` methods). Services should be stateless where possible, or use the centralized `Storage` service for persistence.
|
||||
* **Cross-Service Communication**: Prefer using the `coreEvents` bus (from `packages/core/src/utils/events.ts`) for asynchronous communication between services or to notify the UI of state changes. Avoid tight coupling between services.
|
||||
* **Utilities**: Use `debugLogger` from `packages/core/src/utils/debugLogger.ts` for internal logging instead of `console`. Ensure all shell operations use `spawnAsync` from `packages/core/src/utils/shell-utils.ts` for consistent error handling and promise management. Handle filesystem errors gracefully using `isNodeError` from `packages/core/src/utils/errors.ts`.
|
||||
* **Exports & Tooling**: Add new tools to `packages/core/src/tools/` and register them in `packages/core/src/tools/tool-registry.ts`. Export all new public services, utilities, and types from `packages/core/src/index.ts`.
|
||||
- **Services**: Implement services as classes with clear lifecycle management
|
||||
(e.g., `initialize()` methods). Services should be stateless where possible,
|
||||
or use the centralized `Storage` service for persistence.
|
||||
- **Cross-Service Communication**: Prefer using the `coreEvents` bus (from
|
||||
`packages/core/src/utils/events.ts`) for asynchronous communication between
|
||||
services or to notify the UI of state changes. Avoid tight coupling between
|
||||
services.
|
||||
- **Utilities**: Use `debugLogger` from `packages/core/src/utils/debugLogger.ts`
|
||||
for internal logging instead of `console`. Ensure all shell operations use
|
||||
`spawnAsync` from `packages/core/src/utils/shell-utils.ts` for consistent
|
||||
error handling and promise management. Handle filesystem errors gracefully
|
||||
using `isNodeError` from `packages/core/src/utils/errors.ts`.
|
||||
- **Exports & Tooling**: Add new tools to `packages/core/src/tools/` and
|
||||
register them in `packages/core/src/tools/tool-registry.ts`. Export all new
|
||||
public services, utilities, and types from `packages/core/src/index.ts`.
|
||||
|
||||
## Architectural Audit (Package Boundaries)
|
||||
|
||||
* **Logic Placement**: Non-UI logic (e.g., model orchestration, tool implementation, git/filesystem operations) MUST reside in `packages/core`. `packages/cli` should ONLY contain UI/Ink components, command-line argument parsing, and user interaction logic.
|
||||
* **Environment Isolation**: Core logic must not assume a TUI environment. Use the `ConfirmationBus` or `Output` abstractions for communicating with the user from Core.
|
||||
* **Decoupling**: Actively look for opportunities to decouple services using `coreEvents`. If a service imports another just to notify it of a change, use an event instead.
|
||||
- **Logic Placement**: Non-UI logic (e.g., model orchestration, tool
|
||||
implementation, git/filesystem operations) MUST reside in `packages/core`.
|
||||
`packages/cli` should ONLY contain UI/Ink components, command-line argument
|
||||
parsing, and user interaction logic.
|
||||
- **Environment Isolation**: Core logic must not assume a TUI environment. Use
|
||||
the `ConfirmationBus` or `Output` abstractions for communicating with the user
|
||||
from Core.
|
||||
- **Decoupling**: Actively look for opportunities to decouple services using
|
||||
`coreEvents`. If a service imports another just to notify it of a change, use
|
||||
an event instead.
|
||||
|
||||
## General Gemini CLI Design Principles
|
||||
|
||||
* **Settings**: Use settings for user-configurable options rather than adding new command line arguments. Add new settings to `packages/cli/src/config/settingsSchema.ts`. If a setting has `showInDialog: true`, it MUST be documented in `docs/get-started/configuration.md`. Ensure `requiresRestart` is correctly set.
|
||||
* **Logging**: Use `debugLogger` for rethrown errors to avoid duplicate logging.
|
||||
* **Keyboard Shortcuts**: Define all new keyboard shortcuts in `packages/cli/src/config/keyBindings.ts` and document them in `docs/cli/keyboard-shortcuts.md`. Be careful of keybindings that require the `Meta` key, as only certain meta key shortcuts are supported on Mac. Avoid function keys and shortcuts commonly bound in VSCode.
|
||||
- **Settings**: Use settings for user-configurable options rather than adding
|
||||
new command line arguments. Add new settings to
|
||||
`packages/cli/src/config/settingsSchema.ts`. If a setting has
|
||||
`showInDialog: true`, it MUST be documented in
|
||||
`docs/get-started/configuration.md`. Ensure `requiresRestart` is correctly
|
||||
set.
|
||||
- **Logging**: Use `debugLogger` for rethrown errors to avoid duplicate logging.
|
||||
- **Keyboard Shortcuts**: Define all new keyboard shortcuts in
|
||||
`packages/cli/src/config/keyBindings.ts` and document them in
|
||||
`docs/cli/keyboard-shortcuts.md`. Be careful of keybindings that require the
|
||||
`Meta` key, as only certain meta key shortcuts are supported on Mac. Avoid
|
||||
function keys and shortcuts commonly bound in VSCode.
|
||||
|
||||
## TypeScript Best Practices
|
||||
|
||||
* Use `checkExhaustive` in the `default` clause of `switch` statements to ensure all cases are handled.
|
||||
* Avoid using the non-null assertion operator (`!`) unless absolutely necessary.
|
||||
* **STRICT TYPING**: Strictly forbid `any` and `unknown` in both CLI and Core packages. `unknown` is only allowed if it is immediately narrowed using type guards or Zod validation.
|
||||
* NEVER disable `@typescript-eslint/no-floating-promises`.
|
||||
* Avoid making types nullable unless strictly necessary, as it hurts readability.
|
||||
- Use `checkExhaustive` in the `default` clause of `switch` statements to ensure
|
||||
all cases are handled.
|
||||
- Avoid using the non-null assertion operator (`!`) unless absolutely necessary.
|
||||
- **STRICT TYPING**: Strictly forbid `any` and `unknown` in both CLI and Core
|
||||
packages. `unknown` is only allowed if it is immediately narrowed using type
|
||||
guards or Zod validation.
|
||||
- NEVER disable `@typescript-eslint/no-floating-promises`.
|
||||
- Avoid making types nullable unless strictly necessary, as it hurts
|
||||
readability.
|
||||
|
||||
## TUI Best Practices
|
||||
|
||||
* **Terminal Compatibility**: Consider how changes might behave differently across terminals (e.g., VSCode terminal, SSH, Kitty, default Mac terminal, iTerm2, Windows terminal). If modifying keyboard handling, integrate deeply with existing files like `KeypressContext.tsx` and `terminalCapabilityManager.ts`.
|
||||
* **iTerm**: Be aware that `ITERM_SESSION_ID` may be present when users run VSCode from within iTerm, even if the terminal is not iTerm.
|
||||
- **Terminal Compatibility**: Consider how changes might behave differently
|
||||
across terminals (e.g., VSCode terminal, SSH, Kitty, default Mac terminal,
|
||||
iTerm2, Windows terminal). If modifying keyboard handling, integrate deeply
|
||||
with existing files like `KeypressContext.tsx` and
|
||||
`terminalCapabilityManager.ts`.
|
||||
- **iTerm**: Be aware that `ITERM_SESSION_ID` may be present when users run
|
||||
VSCode from within iTerm, even if the terminal is not iTerm.
|
||||
|
||||
## Code Cleanup
|
||||
|
||||
* **Refactoring**: Actively clean up code duplication, technical debt, and boilerplate ("AI Slop") when working in the codebase.
|
||||
* **Prompts**: Be aware that changes can impact the prompts sent to Gemini CLI and affect overall quality.
|
||||
- **Refactoring**: Actively clean up code duplication, technical debt, and
|
||||
boilerplate ("AI Slop") when working in the codebase.
|
||||
- **Prompts**: Be aware that changes can impact the prompts sent to Gemini CLI
|
||||
and affect overall quality.
|
||||
|
||||
@@ -109,23 +109,41 @@ detailed **highlights** section for the release-specific page.
|
||||
|
||||
- **Target File**: `docs/changelogs/latest.md`
|
||||
- Perform the following edits on the target file:
|
||||
1. Update the version in the main header.
|
||||
2. Update the "Released:" date.
|
||||
1. Update the version in the main header. The line should read,
|
||||
`# Latest stable release: {{version}}`
|
||||
2. Update the rease date. The line should read,
|
||||
`Released: {{release_date_month_dd_yyyy}}`
|
||||
3. **Prepend** the processed "What's Changed" list from the temporary file
|
||||
to the existing "What's Changed" list in the file.
|
||||
4. In the "Full Changelog" URL, replace only the trailing version with the
|
||||
new patch version.
|
||||
to the existing "What's Changed" list in `latest.md`. Do not change or
|
||||
replace the existing list, **only add** to the beginning of it.
|
||||
4. In the "Full Changelog", edit **only** the end of the URL. Identify the
|
||||
last part of the URL that looks like `...{previous_version}` and update
|
||||
it to be `...{version}`.
|
||||
|
||||
Example: assume the patch version is `v0.29.1`. Change
|
||||
`Full Changelog: https://github.com/google-gemini/gemini-cli/compare/v0.28.2…v0.29.0`
|
||||
to
|
||||
`Full Changelog: https://github.com/google-gemini/gemini-cli/compare/v0.28.2…v0.29.1`
|
||||
|
||||
### B.2: Preview Patch (e.g., `v0.29.0-preview.3`)
|
||||
|
||||
- **Target File**: `docs/changelogs/preview.md`
|
||||
- Perform the following edits on the target file:
|
||||
1. Update the version in the main header.
|
||||
2. Update the "Released:" date.
|
||||
1. Update the version in the main header. The line should read,
|
||||
`# Preview release: {{version}}`
|
||||
2. Update the rease date. The line should read,
|
||||
`Released: {{release_date_month_dd_yyyy}}`
|
||||
3. **Prepend** the processed "What's Changed" list from the temporary file
|
||||
to the existing "What's Changed" list in the file.
|
||||
4. In the "Full Changelog" URL, replace only the trailing version with the
|
||||
new patch version.
|
||||
to the existing "What's Changed" list in `preview.md`. Do not change or
|
||||
replace the existing list, **only add** to the beginning of it.
|
||||
4. In the "Full Changelog", edit **only** the end of the URL. Identify the
|
||||
last part of the URL that looks like `...{previous_version}` and update
|
||||
it to be `...{version}`.
|
||||
|
||||
Example: assume the patch version is `v0.29.0-preview.1`. Change
|
||||
`Full Changelog: https://github.com/google-gemini/gemini-cli/compare/v0.28.2…v0.29.0-preview.0`
|
||||
to
|
||||
`Full Changelog: https://github.com/google-gemini/gemini-cli/compare/v0.28.2…v0.29.0-preview.1`
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
---
|
||||
name: pr-address-comments
|
||||
description: Use this skill if the user asks you to help them address GitHub PR comments for their current branch of the Gemini CLI. Requires `gh` CLI tool.
|
||||
---
|
||||
You are helping the user address comments on their Pull Request. These comments may have come from an automated review agent or a team member.
|
||||
|
||||
OBJECTIVE: Help the user review and address comments on their PR.
|
||||
|
||||
# Comment Review Procedure
|
||||
|
||||
1. Run the `scripts/fetch-pr-info.js` script to get PR info and state. MAKE SURE you read the entire output of the command, even if it gets truncated.
|
||||
2. Summarize the review status by analyzing the diff, commit log, and comments to see which still need to be addressed. Pay attention to the current user's comments. For resolved threads, summarize as a single line with a ✅. For open threads, provide a reference number e.g. [1] and the comment content.
|
||||
3. Present your summary of the feedback and current state and allow the user to guide you as to what to fix/address/skip. DO NOT begin fixing issues automatically.
|
||||
+161
@@ -0,0 +1,161 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2025 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/* eslint-env node */
|
||||
/* global console, process */
|
||||
|
||||
import { exec } from 'node:child_process';
|
||||
import { promisify } from 'node:util';
|
||||
|
||||
const execAsync = promisify(exec);
|
||||
|
||||
async function run(cmd) {
|
||||
try {
|
||||
const { stdout } = await execAsync(cmd, {
|
||||
encoding: 'utf8',
|
||||
stdio: ['pipe', 'pipe', 'ignore'],
|
||||
});
|
||||
return stdout.trim();
|
||||
} catch (_e) {
|
||||
// eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
const IGNORE_MESSAGES = [
|
||||
'thank you so much for your contribution to Gemini CLI!',
|
||||
"I'm currently reviewing this pull request and will post my feedback shortly.",
|
||||
'This pull request is being closed because it is not currently linked to an issue.',
|
||||
];
|
||||
|
||||
const shouldIgnore = (body) => {
|
||||
if (!body) return false;
|
||||
return IGNORE_MESSAGES.some((msg) => body.includes(msg));
|
||||
};
|
||||
|
||||
async function main() {
|
||||
const branch = await run('git branch --show-current');
|
||||
if (!branch) {
|
||||
console.error('❌ Could not determine current git branch.');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const gqlQuery = `query($branch:String!){repository(name:"gemini-cli",owner:"google-gemini"){pullRequests(headRefName:$branch,first:100){nodes{id,number,state,comments(first:100){nodes{createdAt,isMinimized,minimizedReason,author{login},body,url,authorAssociation}},reviews(first:100){nodes{id,author{login},createdAt,isMinimized,minimizedReason,body,state,comments(first:30){nodes{id,replyTo{id},author{login},createdAt,body,isMinimized,minimizedReason,path,line,startLine,originalLine,originalStartLine}}}}}}}}`;
|
||||
|
||||
const [authInfo, diff, commits, rawJson] = await Promise.all([
|
||||
run('gh auth status -a'),
|
||||
run('gh pr diff'),
|
||||
run(
|
||||
'git fetch && git log origin/main..origin/$(git branch --show-current)',
|
||||
),
|
||||
run(`gh api graphql -F branch="${branch}" -f query='${gqlQuery}'`),
|
||||
]);
|
||||
|
||||
if (!diff) {
|
||||
console.error(`⚠️ No active PR found for branch: ${branch}`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log(`\n# Current GitHub user info:\n\n${authInfo}\n`);
|
||||
console.log(`\n# PR diff for current branch: ${branch}\n\n\`\`\``);
|
||||
console.log(diff);
|
||||
console.log('```');
|
||||
console.log(
|
||||
`\n# Commit history (origin/main..origin/${branch})\n\n${commits}`,
|
||||
);
|
||||
|
||||
const data = JSON.parse(rawJson || '{}');
|
||||
const prs = data?.data?.repository?.pullRequests?.nodes || [];
|
||||
|
||||
// Sort PRs by number descending so we check the newest one first
|
||||
prs.sort((a, b) => b.number - a.number);
|
||||
|
||||
const pr = prs.find((p) => p.state === 'OPEN') || prs[0];
|
||||
|
||||
if (!pr) {
|
||||
console.error('❌ No PR data found.');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log('\n# PR Feedback\n');
|
||||
|
||||
// 1. General PR Comments
|
||||
const general = pr.comments.nodes.filter((c) => !shouldIgnore(c.body));
|
||||
if (general.length > 0) {
|
||||
console.log('\n💬 GENERAL COMMENTS:');
|
||||
general.forEach((c) => {
|
||||
const minimized = c.isMinimized
|
||||
? ` (Minimized: ${c.minimizedReason})`
|
||||
: '';
|
||||
console.log(
|
||||
`[${c.createdAt}] [${c.author.login}]${minimized}: ${c.body}\n`,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
// 2. Process ALL Review Comments into a single Thread Map
|
||||
const allInlineComments = pr.reviews.nodes.flatMap((r) => r.comments.nodes);
|
||||
const filteredInlines = allInlineComments.filter(
|
||||
(c) => !shouldIgnore(c.body),
|
||||
);
|
||||
|
||||
console.log('🔍 CODE REVIEWS & INLINE THREADS:');
|
||||
|
||||
// Print Review Summaries First
|
||||
pr.reviews.nodes.forEach((review) => {
|
||||
if (review.body && !shouldIgnore(review.body)) {
|
||||
const icon = review.state === 'APPROVED' ? '✅' : '💬';
|
||||
const minimized = review.isMinimized
|
||||
? ` (Minimized: ${review.minimizedReason})`
|
||||
: '';
|
||||
console.log(
|
||||
`\n${icon} ${review.state} by ${review.author.login} at ${review.createdAt}${minimized}: "${review.body}"`,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
// Build and Print Threads
|
||||
const topLevelThreads = filteredInlines.filter((c) => !c.replyTo);
|
||||
|
||||
const printThread = (parentId, depth = 1) => {
|
||||
const indent = ' '.repeat(depth);
|
||||
filteredInlines
|
||||
.filter((c) => c.replyTo?.id === parentId)
|
||||
.forEach((reply) => {
|
||||
const minimized = reply.isMinimized
|
||||
? ` (Minimized: ${reply.minimizedReason})`
|
||||
: '';
|
||||
console.log(
|
||||
`${indent}↳ [${reply.createdAt}] ${reply.author.login}${minimized}: ${reply.body}`,
|
||||
);
|
||||
printThread(reply.id, depth + 1);
|
||||
});
|
||||
};
|
||||
|
||||
topLevelThreads.forEach((c) => {
|
||||
const start = c.startLine || c.originalStartLine;
|
||||
const end = c.line || c.originalLine;
|
||||
const range = start && end && start !== end ? `${start}-${end}` : end || '';
|
||||
const fileInfo = c.path
|
||||
? `(${c.path}${range ? `:${range}` : ''}) `
|
||||
: range
|
||||
? `(Line ${range}) `
|
||||
: '';
|
||||
const minimized = c.isMinimized ? ` (Minimized: ${c.minimizedReason})` : '';
|
||||
console.log(
|
||||
`\n💬 ${minimized}${c.author.login} | ${c.createdAt} ${fileInfo}\n${c.body}`,
|
||||
);
|
||||
printThread(c.id);
|
||||
});
|
||||
|
||||
console.log('\n');
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error('❌ Unexpected error:', err);
|
||||
process.exit(1);
|
||||
});
|
||||
@@ -155,7 +155,10 @@ jobs:
|
||||
"telemetry": {
|
||||
"enabled": true,
|
||||
"target": "gcp"
|
||||
}
|
||||
},
|
||||
"coreTools": [
|
||||
"run_shell_command(echo)"
|
||||
],
|
||||
}
|
||||
prompt: |-
|
||||
## Role
|
||||
@@ -284,8 +287,21 @@ jobs:
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
core.setFailed(`Output is not valid JSON and does not contain a JSON markdown block.\nRaw output: ${rawOutput}`);
|
||||
return;
|
||||
// If no markdown block, try to find a raw JSON object in the output.
|
||||
// The CLI may include debug/log lines (e.g. telemetry init, YOLO mode)
|
||||
// before the actual JSON response.
|
||||
const jsonObjectMatch = rawOutput.match(/(\{[\s\S]*"labels_to_set"[\s\S]*\})/);
|
||||
if (jsonObjectMatch) {
|
||||
try {
|
||||
parsedLabels = JSON.parse(jsonObjectMatch[0]);
|
||||
} catch (extractError) {
|
||||
core.setFailed(`Found JSON-like content but failed to parse: ${extractError.message}\nRaw output: ${rawOutput}`);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
core.setFailed(`Output is not valid JSON and does not contain extractable JSON.\nRaw output: ${rawOutput}`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@ packages/*/coverage/
|
||||
# Generated files
|
||||
packages/cli/src/generated/
|
||||
packages/core/src/generated/
|
||||
packages/devtools/src/_client-assets.ts
|
||||
.integration-tests/
|
||||
packages/vscode-ide-companion/*.vsix
|
||||
packages/cli/download-ripgrep*/
|
||||
|
||||
+6
-7
@@ -372,8 +372,7 @@ specific debug settings.
|
||||
|
||||
### React DevTools
|
||||
|
||||
To debug the CLI's React-based UI, you can use React DevTools. Ink, the library
|
||||
used for the CLI's interface, is compatible with React DevTools version 4.x.
|
||||
To debug the CLI's React-based UI, you can use React DevTools.
|
||||
|
||||
1. **Start the Gemini CLI in development mode:**
|
||||
|
||||
@@ -381,20 +380,20 @@ used for the CLI's interface, is compatible with React DevTools version 4.x.
|
||||
DEV=true npm start
|
||||
```
|
||||
|
||||
2. **Install and run React DevTools version 4.28.5 (or the latest compatible
|
||||
4.x version):**
|
||||
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@4.28.5
|
||||
npm install -g react-devtools@6
|
||||
react-devtools
|
||||
```
|
||||
|
||||
Or run it directly using npx:
|
||||
|
||||
```bash
|
||||
npx react-devtools@4.28.5
|
||||
npx react-devtools@6
|
||||
```
|
||||
|
||||
Your running CLI application should then connect to React DevTools.
|
||||
@@ -546,7 +545,7 @@ Before submitting your documentation pull request, please:
|
||||
|
||||
If you have questions about contributing documentation:
|
||||
|
||||
- Check our [FAQ](/docs/faq.md).
|
||||
- Check our [FAQ](/docs/resources/faq.md).
|
||||
- Review existing documentation for examples.
|
||||
- Open [an issue](https://github.com/google-gemini/gemini-cli/issues) to discuss
|
||||
your proposed changes.
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
# Gemini CLI Architecture Overview
|
||||
|
||||
This document provides a high-level overview of the Gemini CLI's architecture.
|
||||
|
||||
## Core components
|
||||
|
||||
The Gemini CLI is primarily composed of two main packages, along with a suite of
|
||||
tools that can be used by the system in the course of handling command-line
|
||||
input:
|
||||
|
||||
1. **CLI package (`packages/cli`):**
|
||||
- **Purpose:** This contains the user-facing portion of the Gemini CLI, such
|
||||
as handling the initial user input, presenting the final output, and
|
||||
managing the overall user experience.
|
||||
- **Key functions contained in the package:**
|
||||
- [Input processing](/docs/cli/commands)
|
||||
- History management
|
||||
- Display rendering
|
||||
- [Theme and UI customization](/docs/cli/themes)
|
||||
- [CLI configuration settings](/docs/get-started/configuration)
|
||||
|
||||
2. **Core package (`packages/core`):**
|
||||
- **Purpose:** This acts as the backend for the Gemini CLI. It receives
|
||||
requests sent from `packages/cli`, orchestrates interactions with the
|
||||
Gemini API, and manages the execution of available tools.
|
||||
- **Key functions contained in the package:**
|
||||
- API client for communicating with the Google Gemini API
|
||||
- Prompt construction and management
|
||||
- Tool registration and execution logic
|
||||
- State management for conversations or sessions
|
||||
- Server-side configuration
|
||||
|
||||
3. **Tools (`packages/core/src/tools/`):**
|
||||
- **Purpose:** These are individual modules that extend the capabilities of
|
||||
the Gemini model, allowing it to interact with the local environment
|
||||
(e.g., file system, shell commands, web fetching).
|
||||
- **Interaction:** `packages/core` invokes these tools based on requests
|
||||
from the Gemini model.
|
||||
|
||||
## Interaction flow
|
||||
|
||||
A typical interaction with the Gemini CLI follows this flow:
|
||||
|
||||
1. **User input:** The user types a prompt or command into the terminal, which
|
||||
is managed by `packages/cli`.
|
||||
2. **Request to core:** `packages/cli` sends the user's input to
|
||||
`packages/core`.
|
||||
3. **Request processed:** The core package:
|
||||
- Constructs an appropriate prompt for the Gemini API, possibly including
|
||||
conversation history and available tool definitions.
|
||||
- Sends the prompt to the Gemini API.
|
||||
4. **Gemini API response:** The Gemini API processes the prompt and returns a
|
||||
response. This response might be a direct answer or a request to use one of
|
||||
the available tools.
|
||||
5. **Tool execution (if applicable):**
|
||||
- When the Gemini API requests a tool, the core package prepares to execute
|
||||
it.
|
||||
- If the requested tool can modify the file system or execute shell
|
||||
commands, the user is first given details of the tool and its arguments,
|
||||
and the user must approve the execution.
|
||||
- Read-only operations, such as reading files, might not require explicit
|
||||
user confirmation to proceed.
|
||||
- Once confirmed, or if confirmation is not required, the core package
|
||||
executes the relevant action within the relevant tool, and the result is
|
||||
sent back to the Gemini API by the core package.
|
||||
- The Gemini API processes the tool result and generates a final response.
|
||||
6. **Response to CLI:** The core package sends the final response back to the
|
||||
CLI package.
|
||||
7. **Display to user:** The CLI package formats and displays the response to
|
||||
the user in the terminal.
|
||||
|
||||
## Key design principles
|
||||
|
||||
- **Modularity:** Separating the CLI (frontend) from the Core (backend) allows
|
||||
for independent development and potential future extensions (e.g., different
|
||||
frontends for the same backend).
|
||||
- **Extensibility:** The tool system is designed to be extensible, allowing new
|
||||
capabilities to be added.
|
||||
- **User experience:** The CLI focuses on providing a rich and interactive
|
||||
terminal experience.
|
||||
@@ -18,7 +18,26 @@ on GitHub.
|
||||
| [Preview](preview.md) | Experimental features ready for early feedback. |
|
||||
| [Stable](latest.md) | Stable, recommended for general use. |
|
||||
|
||||
## Announcements: v0.28.0 - 2026-02-03
|
||||
## 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
|
||||
|
||||
- **Slash Command:** We've added a new `/prompt-suggest` slash command to help
|
||||
you generate prompt suggestions
|
||||
@@ -276,7 +295,8 @@ on GitHub.
|
||||
- **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](../core/policy-engine.md) for more information.
|
||||
[policy engine documentation](../reference/policy-engine.md) 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
|
||||
|
||||
+359
-293
@@ -1,6 +1,6 @@
|
||||
# Latest stable release: v0.28.0
|
||||
# Latest stable release: v0.29.0
|
||||
|
||||
Released: February 10, 2026
|
||||
Released: February 17, 2026
|
||||
|
||||
For most users, our latest stable release is the recommended release. Install
|
||||
the latest stable version with:
|
||||
@@ -11,305 +11,371 @@ npm install -g @google/gemini-cli
|
||||
|
||||
## Highlights
|
||||
|
||||
- **Commands & UX Enhancements:** Introduced `/prompt-suggest` command,
|
||||
alongside updated undo/redo keybindings and automatic theme switching.
|
||||
- **Expanded IDE Support:** Now offering compatibility with Positron IDE,
|
||||
expanding integration options for developers.
|
||||
- **Enhanced Security & Authentication:** Implemented interactive and
|
||||
non-interactive OAuth consent, improving both security and diagnostic
|
||||
capabilities for bug reports.
|
||||
- **Advanced Planning & Agent Tools:** Integrated a generic Checklist component
|
||||
for structured task management and evolved subagent capabilities with dynamic
|
||||
policy registration.
|
||||
- **Improved Core Stability & Reliability:** Resolved critical environment
|
||||
loading, authentication, and session management issues, ensuring a more robust
|
||||
experience.
|
||||
- **Background Shell Commands:** Enabled the execution of shell commands in the
|
||||
background for increased workflow efficiency.
|
||||
- **Plan Mode:** Introduce a dedicated "Plan Mode" to help you architect complex
|
||||
changes before implementation. Use `/plan` to get started.
|
||||
- **Gemini 3 by Default:** Gemini 3 is now the default model family, bringing
|
||||
improved performance and reasoning capabilities to all users without needing a
|
||||
feature flag.
|
||||
- **Extension Discovery:** Easily discover and install extensions with the new
|
||||
exploration features and registry client.
|
||||
- **Enhanced Admin Controls:** New administrative capabilities allow for
|
||||
allowlisting MCP server configurations, giving organizations more control over
|
||||
available tools.
|
||||
- **Sub-agent Improvements:** Sub-agents have been transitioned to a new format
|
||||
with improved definitions and system prompts for better reliability.
|
||||
|
||||
## What's Changed
|
||||
|
||||
- feat(commands): add /prompt-suggest slash command by @NTaylorMullen in
|
||||
[#17264](https://github.com/google-gemini/gemini-cli/pull/17264)
|
||||
- feat(cli): align hooks enable/disable with skills and improve completion by
|
||||
@sehoon38 in [#16822](https://github.com/google-gemini/gemini-cli/pull/16822)
|
||||
- docs: add CLI reference documentation by @leochiu-a in
|
||||
[#17504](https://github.com/google-gemini/gemini-cli/pull/17504)
|
||||
- chore(release): bump version to 0.28.0-nightly.20260128.adc8e11bb by
|
||||
- fix: remove `ask_user` tool from non-interactive modes by @jackwotherspoon in
|
||||
[#18154](https://github.com/google-gemini/gemini-cli/pull/18154)
|
||||
- fix(cli): allow restricted .env loading in untrusted sandboxed folders by
|
||||
@galz10 in [#17806](https://github.com/google-gemini/gemini-cli/pull/17806)
|
||||
- Encourage agent to utilize ecosystem tools to perform work by @gundermanc in
|
||||
[#17881](https://github.com/google-gemini/gemini-cli/pull/17881)
|
||||
- feat(plan): unify workflow location in system prompt to optimize caching by
|
||||
@jerop in [#18258](https://github.com/google-gemini/gemini-cli/pull/18258)
|
||||
- feat(core): enable getUserTierName in config by @sehoon38 in
|
||||
[#18265](https://github.com/google-gemini/gemini-cli/pull/18265)
|
||||
- feat(core): add default execution limits for subagents by @abhipatel12 in
|
||||
[#18274](https://github.com/google-gemini/gemini-cli/pull/18274)
|
||||
- Fix issue where agent gets stuck at interactive commands. by @gundermanc in
|
||||
[#18272](https://github.com/google-gemini/gemini-cli/pull/18272)
|
||||
- chore(release): bump version to 0.29.0-nightly.20260203.71f46f116 by
|
||||
@gemini-cli-robot in
|
||||
[#17725](https://github.com/google-gemini/gemini-cli/pull/17725)
|
||||
- feat(skills): final stable promotion cleanup by @abhipatel12 in
|
||||
[#17726](https://github.com/google-gemini/gemini-cli/pull/17726)
|
||||
- test(core): mock fetch in OAuth transport fallback tests by @jw409 in
|
||||
[#17059](https://github.com/google-gemini/gemini-cli/pull/17059)
|
||||
- feat(cli): include auth method in /bug by @erikus in
|
||||
[#17569](https://github.com/google-gemini/gemini-cli/pull/17569)
|
||||
- Add a email privacy note to bug_report template by @nemyung in
|
||||
[#17474](https://github.com/google-gemini/gemini-cli/pull/17474)
|
||||
- Rewind documentation by @Adib234 in
|
||||
[#17446](https://github.com/google-gemini/gemini-cli/pull/17446)
|
||||
- fix: verify audio/video MIME types with content check by @maru0804 in
|
||||
[#16907](https://github.com/google-gemini/gemini-cli/pull/16907)
|
||||
- feat(core): add support for positron ide
|
||||
([#15045](https://github.com/google-gemini/gemini-cli/pull/15045)) by @kapsner
|
||||
in [#15047](https://github.com/google-gemini/gemini-cli/pull/15047)
|
||||
- /oncall dedup - wrap texts to nextlines by @sehoon38 in
|
||||
[#17782](https://github.com/google-gemini/gemini-cli/pull/17782)
|
||||
- fix(admin): rename advanced features admin setting by @skeshive in
|
||||
[#17786](https://github.com/google-gemini/gemini-cli/pull/17786)
|
||||
- [extension config] Make breaking optional value non-optional by @chrstnb in
|
||||
[#17785](https://github.com/google-gemini/gemini-cli/pull/17785)
|
||||
- Fix docs-writer skill issues by @g-samroberts in
|
||||
[#17734](https://github.com/google-gemini/gemini-cli/pull/17734)
|
||||
- fix(core): suppress duplicate hook failure warnings during streaming by
|
||||
[#18243](https://github.com/google-gemini/gemini-cli/pull/18243)
|
||||
- feat(core): remove hardcoded policy bypass for local subagents by @abhipatel12
|
||||
in [#18153](https://github.com/google-gemini/gemini-cli/pull/18153)
|
||||
- feat(plan): implement `plan` slash command by @Adib234 in
|
||||
[#17698](https://github.com/google-gemini/gemini-cli/pull/17698)
|
||||
- feat: increase `ask_user` label limit to 16 characters by @jackwotherspoon in
|
||||
[#18320](https://github.com/google-gemini/gemini-cli/pull/18320)
|
||||
- Add information about the agent skills lifecycle and clarify docs-writer skill
|
||||
metadata. by @g-samroberts in
|
||||
[#18234](https://github.com/google-gemini/gemini-cli/pull/18234)
|
||||
- feat(core): add `enter_plan_mode` tool by @jerop in
|
||||
[#18324](https://github.com/google-gemini/gemini-cli/pull/18324)
|
||||
- Stop showing an error message in `/plan` by @Adib234 in
|
||||
[#18333](https://github.com/google-gemini/gemini-cli/pull/18333)
|
||||
- fix(hooks): remove unnecessary logging for hook registration by @abhipatel12
|
||||
in [#18332](https://github.com/google-gemini/gemini-cli/pull/18332)
|
||||
- fix(mcp): ensure MCP transport is closed to prevent memory leaks by
|
||||
@cbcoutinho in
|
||||
[#18054](https://github.com/google-gemini/gemini-cli/pull/18054)
|
||||
- feat(skills): implement linking for agent skills by @MushuEE in
|
||||
[#18295](https://github.com/google-gemini/gemini-cli/pull/18295)
|
||||
- Changelogs for 0.27.0 and 0.28.0-preview0 by @g-samroberts in
|
||||
[#18336](https://github.com/google-gemini/gemini-cli/pull/18336)
|
||||
- chore: correct docs as skills and hooks are stable by @jackwotherspoon in
|
||||
[#18358](https://github.com/google-gemini/gemini-cli/pull/18358)
|
||||
- feat(admin): Implement admin allowlist for MCP server configurations by
|
||||
@skeshive in [#18311](https://github.com/google-gemini/gemini-cli/pull/18311)
|
||||
- fix(core): add retry logic for transient SSL/TLS errors (#17318) by @ppgranger
|
||||
in [#18310](https://github.com/google-gemini/gemini-cli/pull/18310)
|
||||
- Add support for /extensions config command by @chrstnb in
|
||||
[#17895](https://github.com/google-gemini/gemini-cli/pull/17895)
|
||||
- fix(core): handle non-compliant mcpbridge responses from Xcode 26.3 by
|
||||
@peterfriese in
|
||||
[#18376](https://github.com/google-gemini/gemini-cli/pull/18376)
|
||||
- feat(cli): Add W, B, E Vim motions and operator support by @ademuri in
|
||||
[#16209](https://github.com/google-gemini/gemini-cli/pull/16209)
|
||||
- fix: Windows Specific Agent Quality & System Prompt by @scidomino in
|
||||
[#18351](https://github.com/google-gemini/gemini-cli/pull/18351)
|
||||
- feat(plan): support `replace` tool in plan mode to edit plans by @jerop in
|
||||
[#18379](https://github.com/google-gemini/gemini-cli/pull/18379)
|
||||
- Improving memory tool instructions and eval testing by @alisa-alisa in
|
||||
[#18091](https://github.com/google-gemini/gemini-cli/pull/18091)
|
||||
- fix(cli): color extension link success message green by @MushuEE in
|
||||
[#18386](https://github.com/google-gemini/gemini-cli/pull/18386)
|
||||
- undo by @jacob314 in
|
||||
[#18147](https://github.com/google-gemini/gemini-cli/pull/18147)
|
||||
- feat(plan): add guidance on iterating on approved plans vs creating new plans
|
||||
by @jerop in [#18346](https://github.com/google-gemini/gemini-cli/pull/18346)
|
||||
- feat(plan): fix invalid tool calls in plan mode by @Adib234 in
|
||||
[#18352](https://github.com/google-gemini/gemini-cli/pull/18352)
|
||||
- feat(plan): integrate planning artifacts and tools into primary workflows by
|
||||
@jerop in [#18375](https://github.com/google-gemini/gemini-cli/pull/18375)
|
||||
- Fix permission check by @scidomino in
|
||||
[#18395](https://github.com/google-gemini/gemini-cli/pull/18395)
|
||||
- ux(polish) autocomplete in the input prompt by @jacob314 in
|
||||
[#18181](https://github.com/google-gemini/gemini-cli/pull/18181)
|
||||
- fix: resolve infinite loop when using 'Modify with external editor' by
|
||||
@ppgranger in [#17453](https://github.com/google-gemini/gemini-cli/pull/17453)
|
||||
- feat: expand verify-release to macOS and Windows by @yunaseoul in
|
||||
[#18145](https://github.com/google-gemini/gemini-cli/pull/18145)
|
||||
- feat(plan): implement support for MCP servers in Plan mode by @Adib234 in
|
||||
[#18229](https://github.com/google-gemini/gemini-cli/pull/18229)
|
||||
- chore: update folder trust error messaging by @galz10 in
|
||||
[#18402](https://github.com/google-gemini/gemini-cli/pull/18402)
|
||||
- feat(plan): create a metric for execution of plans generated in plan mode by
|
||||
@Adib234 in [#18236](https://github.com/google-gemini/gemini-cli/pull/18236)
|
||||
- perf(ui): optimize stripUnsafeCharacters with regex by @gsquared94 in
|
||||
[#18413](https://github.com/google-gemini/gemini-cli/pull/18413)
|
||||
- feat(context): implement observation masking for tool outputs by @abhipatel12
|
||||
in [#18389](https://github.com/google-gemini/gemini-cli/pull/18389)
|
||||
- feat(core,cli): implement session-linked tool output storage and cleanup by
|
||||
@abhipatel12 in
|
||||
[#17727](https://github.com/google-gemini/gemini-cli/pull/17727)
|
||||
- test: add more tests for AskUser by @jackwotherspoon in
|
||||
[#17720](https://github.com/google-gemini/gemini-cli/pull/17720)
|
||||
- feat(cli): enable activity logging for non-interactive mode and evals by
|
||||
@SandyTao520 in
|
||||
[#17703](https://github.com/google-gemini/gemini-cli/pull/17703)
|
||||
- feat(core): add support for custom deny messages in policy rules by
|
||||
@allenhutchison in
|
||||
[#17427](https://github.com/google-gemini/gemini-cli/pull/17427)
|
||||
- Fix unintended credential exposure to MCP Servers by @Adib234 in
|
||||
[#17311](https://github.com/google-gemini/gemini-cli/pull/17311)
|
||||
- feat(extensions): add support for custom themes in extensions by @spencer426
|
||||
in [#17327](https://github.com/google-gemini/gemini-cli/pull/17327)
|
||||
- fix: persist and restore workspace directories on session resume by
|
||||
@korade-krushna in
|
||||
[#17454](https://github.com/google-gemini/gemini-cli/pull/17454)
|
||||
- Update release notes pages for 0.26.0 and 0.27.0-preview. by @g-samroberts in
|
||||
[#17744](https://github.com/google-gemini/gemini-cli/pull/17744)
|
||||
- feat(ux): update cell border color and created test file for table rendering
|
||||
by @devr0306 in
|
||||
[#17798](https://github.com/google-gemini/gemini-cli/pull/17798)
|
||||
- Change height for the ToolConfirmationQueue. by @jacob314 in
|
||||
[#17799](https://github.com/google-gemini/gemini-cli/pull/17799)
|
||||
- feat(cli): add user identity info to stats command by @sehoon38 in
|
||||
[#17612](https://github.com/google-gemini/gemini-cli/pull/17612)
|
||||
- fix(ux): fixed off-by-some wrapping caused by fixed-width characters by
|
||||
@devr0306 in [#17816](https://github.com/google-gemini/gemini-cli/pull/17816)
|
||||
- feat(cli): update undo/redo keybindings to Cmd+Z/Alt+Z and
|
||||
Shift+Cmd+Z/Shift+Alt+Z by @scidomino in
|
||||
[#17800](https://github.com/google-gemini/gemini-cli/pull/17800)
|
||||
- fix(evals): use absolute path for activity log directory by @SandyTao520 in
|
||||
[#17830](https://github.com/google-gemini/gemini-cli/pull/17830)
|
||||
- test: add integration test to verify stdout/stderr routing by @ved015 in
|
||||
[#17280](https://github.com/google-gemini/gemini-cli/pull/17280)
|
||||
- fix(cli): list installed extensions when update target missing by @tt-a1i in
|
||||
[#17082](https://github.com/google-gemini/gemini-cli/pull/17082)
|
||||
- fix(cli): handle PAT tokens and credentials in git remote URL parsing by
|
||||
@afarber in [#14650](https://github.com/google-gemini/gemini-cli/pull/14650)
|
||||
- fix(core): use returnDisplay for error result display by @Nubebuster in
|
||||
[#14994](https://github.com/google-gemini/gemini-cli/pull/14994)
|
||||
- Fix detection of bun as package manager by @Randomblock1 in
|
||||
[#17462](https://github.com/google-gemini/gemini-cli/pull/17462)
|
||||
- feat(cli): show hooksConfig.enabled in settings dialog by @abhipatel12 in
|
||||
[#17810](https://github.com/google-gemini/gemini-cli/pull/17810)
|
||||
- feat(cli): Display user identity (auth, email, tier) on startup by @yunaseoul
|
||||
in [#17591](https://github.com/google-gemini/gemini-cli/pull/17591)
|
||||
- fix: prevent ghost border for AskUserDialog by @jackwotherspoon in
|
||||
[#17788](https://github.com/google-gemini/gemini-cli/pull/17788)
|
||||
- docs: mark A2A subagents as experimental in subagents.md by @adamfweidman in
|
||||
[#17863](https://github.com/google-gemini/gemini-cli/pull/17863)
|
||||
- Resolve error thrown for sensitive values by @chrstnb in
|
||||
[#17826](https://github.com/google-gemini/gemini-cli/pull/17826)
|
||||
- fix(admin): Rename secureModeEnabled to strictModeDisabled by @skeshive in
|
||||
[#17789](https://github.com/google-gemini/gemini-cli/pull/17789)
|
||||
- feat(ux): update truncate dots to be shorter in tables by @devr0306 in
|
||||
[#17825](https://github.com/google-gemini/gemini-cli/pull/17825)
|
||||
- fix(core): resolve DEP0040 punycode deprecation via patch-package by
|
||||
@ATHARVA262005 in
|
||||
[#17692](https://github.com/google-gemini/gemini-cli/pull/17692)
|
||||
- feat(plan): create generic Checklist component and refactor Todo by @Adib234
|
||||
in [#17741](https://github.com/google-gemini/gemini-cli/pull/17741)
|
||||
- Cleanup post delegate_to_agent removal by @gundermanc in
|
||||
[#17875](https://github.com/google-gemini/gemini-cli/pull/17875)
|
||||
- fix(core): use GIT_CONFIG_GLOBAL to isolate shadow git repo configuration -
|
||||
Fixes [#17877](https://github.com/google-gemini/gemini-cli/pull/17877) by
|
||||
@cocosheng-g in
|
||||
[#17803](https://github.com/google-gemini/gemini-cli/pull/17803)
|
||||
- Disable mouse tracking e2e by @alisa-alisa in
|
||||
[#17880](https://github.com/google-gemini/gemini-cli/pull/17880)
|
||||
- fix(cli): use correct setting key for Cloud Shell auth by @sehoon38 in
|
||||
[#17884](https://github.com/google-gemini/gemini-cli/pull/17884)
|
||||
- chore: revert IDE specific ASCII logo by @jackwotherspoon in
|
||||
[#17887](https://github.com/google-gemini/gemini-cli/pull/17887)
|
||||
- Revert "fix(core): resolve DEP0040 punycode deprecation via patch-package" by
|
||||
@sehoon38 in [#17898](https://github.com/google-gemini/gemini-cli/pull/17898)
|
||||
- Refactoring of disabling of mouse tracking in e2e tests by @alisa-alisa in
|
||||
[#17902](https://github.com/google-gemini/gemini-cli/pull/17902)
|
||||
- feat(core): Add GOOGLE_GENAI_API_VERSION environment variable support by
|
||||
@deyim in [#16177](https://github.com/google-gemini/gemini-cli/pull/16177)
|
||||
- feat(core): Isolate and cleanup truncated tool outputs by @SandyTao520 in
|
||||
[#17594](https://github.com/google-gemini/gemini-cli/pull/17594)
|
||||
- Create skills page, update commands, refine docs by @g-samroberts in
|
||||
[#17842](https://github.com/google-gemini/gemini-cli/pull/17842)
|
||||
- feat: preserve EOL in files by @Thomas-Shephard in
|
||||
[#16087](https://github.com/google-gemini/gemini-cli/pull/16087)
|
||||
- Fix HalfLinePaddedBox in screenreader mode. by @jacob314 in
|
||||
[#17914](https://github.com/google-gemini/gemini-cli/pull/17914)
|
||||
- bug(ux) vim mode fixes. Start in insert mode. Fix bug blocking F12 and ctrl-X
|
||||
in vim mode. by @jacob314 in
|
||||
[#17938](https://github.com/google-gemini/gemini-cli/pull/17938)
|
||||
- feat(core): implement interactive and non-interactive consent for OAuth by
|
||||
@ehedlund in [#17699](https://github.com/google-gemini/gemini-cli/pull/17699)
|
||||
- perf(core): optimize token calculation and add support for multimodal tool
|
||||
responses by @abhipatel12 in
|
||||
[#17835](https://github.com/google-gemini/gemini-cli/pull/17835)
|
||||
- refactor(hooks): remove legacy tools.enableHooks setting by @abhipatel12 in
|
||||
[#17867](https://github.com/google-gemini/gemini-cli/pull/17867)
|
||||
- feat(ci): add npx smoke test to verify installability by @bdmorgan in
|
||||
[#17927](https://github.com/google-gemini/gemini-cli/pull/17927)
|
||||
- feat(core): implement dynamic policy registration for subagents by
|
||||
[#18416](https://github.com/google-gemini/gemini-cli/pull/18416)
|
||||
- Shorten temp directory by @joshualitt in
|
||||
[#17901](https://github.com/google-gemini/gemini-cli/pull/17901)
|
||||
- feat(plan): add behavioral evals for plan mode by @jerop in
|
||||
[#18437](https://github.com/google-gemini/gemini-cli/pull/18437)
|
||||
- Add extension registry client by @chrstnb in
|
||||
[#18396](https://github.com/google-gemini/gemini-cli/pull/18396)
|
||||
- Enable extension config by default by @chrstnb in
|
||||
[#18447](https://github.com/google-gemini/gemini-cli/pull/18447)
|
||||
- Automatically generate change logs on release by @g-samroberts in
|
||||
[#18401](https://github.com/google-gemini/gemini-cli/pull/18401)
|
||||
- Remove previewFeatures and default to Gemini 3 by @sehoon38 in
|
||||
[#18414](https://github.com/google-gemini/gemini-cli/pull/18414)
|
||||
- feat(admin): apply MCP allowlist to extensions & gemini mcp list command by
|
||||
@skeshive in [#18442](https://github.com/google-gemini/gemini-cli/pull/18442)
|
||||
- fix(cli): improve focus navigation for interactive and background shells by
|
||||
@galz10 in [#18343](https://github.com/google-gemini/gemini-cli/pull/18343)
|
||||
- Add shortcuts hint and panel for discoverability by @LyalinDotCom in
|
||||
[#18035](https://github.com/google-gemini/gemini-cli/pull/18035)
|
||||
- fix(config): treat system settings as read-only during migration and warn user
|
||||
by @spencer426 in
|
||||
[#18277](https://github.com/google-gemini/gemini-cli/pull/18277)
|
||||
- feat(plan): add positive test case and update eval stability policy by @jerop
|
||||
in [#18457](https://github.com/google-gemini/gemini-cli/pull/18457)
|
||||
- fix- windows: add shell: true for spawnSync to fix EINVAL with .cmd editors by
|
||||
@zackoch in [#18408](https://github.com/google-gemini/gemini-cli/pull/18408)
|
||||
- bug(core): Fix bug when saving plans. by @joshualitt in
|
||||
[#18465](https://github.com/google-gemini/gemini-cli/pull/18465)
|
||||
- Refactor atCommandProcessor by @scidomino in
|
||||
[#18461](https://github.com/google-gemini/gemini-cli/pull/18461)
|
||||
- feat(core): implement persistence and resumption for masked tool outputs by
|
||||
@abhipatel12 in
|
||||
[#17838](https://github.com/google-gemini/gemini-cli/pull/17838)
|
||||
- feat: Implement background shell commands by @galz10 in
|
||||
[#14849](https://github.com/google-gemini/gemini-cli/pull/14849)
|
||||
- feat(admin): provide actionable error messages for disabled features by
|
||||
@skeshive in [#17815](https://github.com/google-gemini/gemini-cli/pull/17815)
|
||||
- Fix bugs where Rewind and Resume showed Ugly and 100X too verbose content. by
|
||||
@jacob314 in [#17940](https://github.com/google-gemini/gemini-cli/pull/17940)
|
||||
- Fix broken link in docs by @chrstnb in
|
||||
[#17959](https://github.com/google-gemini/gemini-cli/pull/17959)
|
||||
- feat(plan): reuse standard tool confirmation for AskUser tool by @jerop in
|
||||
[#17864](https://github.com/google-gemini/gemini-cli/pull/17864)
|
||||
- feat(core): enable overriding CODE_ASSIST_API_VERSION with env var by
|
||||
@lottielin in [#17942](https://github.com/google-gemini/gemini-cli/pull/17942)
|
||||
- run npx pointing to the specific commit SHA by @sehoon38 in
|
||||
[#17970](https://github.com/google-gemini/gemini-cli/pull/17970)
|
||||
- Add allowedExtensions setting by @kevinjwang1 in
|
||||
[#17695](https://github.com/google-gemini/gemini-cli/pull/17695)
|
||||
- feat(plan): refactor ToolConfirmationPayload to union type by @jerop in
|
||||
[#17980](https://github.com/google-gemini/gemini-cli/pull/17980)
|
||||
- lower the default max retries to reduce contention by @sehoon38 in
|
||||
[#17975](https://github.com/google-gemini/gemini-cli/pull/17975)
|
||||
- fix(core): ensure YOLO mode auto-approves complex shell commands when parsing
|
||||
fails by @abhipatel12 in
|
||||
[#17920](https://github.com/google-gemini/gemini-cli/pull/17920)
|
||||
- Fix broken link. by @g-samroberts in
|
||||
[#17972](https://github.com/google-gemini/gemini-cli/pull/17972)
|
||||
- Support ctrl-C and Ctrl-D correctly Refactor so InputPrompt has priority over
|
||||
AppContainer for input handling. by @jacob314 in
|
||||
[#17993](https://github.com/google-gemini/gemini-cli/pull/17993)
|
||||
- Fix truncation for AskQuestion by @jacob314 in
|
||||
[#18001](https://github.com/google-gemini/gemini-cli/pull/18001)
|
||||
- fix(workflow): update maintainer check logic to be inclusive and
|
||||
case-insensitive by @bdmorgan in
|
||||
[#18009](https://github.com/google-gemini/gemini-cli/pull/18009)
|
||||
- Fix Esc cancel during streaming by @LyalinDotCom in
|
||||
[#18039](https://github.com/google-gemini/gemini-cli/pull/18039)
|
||||
- feat(acp): add session resume support by @bdmorgan in
|
||||
[#18043](https://github.com/google-gemini/gemini-cli/pull/18043)
|
||||
- fix(ci): prevent stale PR closer from incorrectly closing new PRs by @bdmorgan
|
||||
in [#18069](https://github.com/google-gemini/gemini-cli/pull/18069)
|
||||
- chore: delete autoAccept setting unused in production by @victorvianna in
|
||||
[#17862](https://github.com/google-gemini/gemini-cli/pull/17862)
|
||||
- feat(plan): use placeholder for choice question "Other" option by @jerop in
|
||||
[#18101](https://github.com/google-gemini/gemini-cli/pull/18101)
|
||||
- docs: update clearContext to hookSpecificOutput by @jackwotherspoon in
|
||||
[#18024](https://github.com/google-gemini/gemini-cli/pull/18024)
|
||||
- docs-writer skill: Update docs writer skill by @jkcinouye in
|
||||
[#17928](https://github.com/google-gemini/gemini-cli/pull/17928)
|
||||
- Sehoon/oncall filter by @sehoon38 in
|
||||
[#18105](https://github.com/google-gemini/gemini-cli/pull/18105)
|
||||
- feat(core): add setting to disable loop detection by @SandyTao520 in
|
||||
[#18008](https://github.com/google-gemini/gemini-cli/pull/18008)
|
||||
- Docs: Revise docs/index.md by @jkcinouye in
|
||||
[#17879](https://github.com/google-gemini/gemini-cli/pull/17879)
|
||||
- Fix up/down arrow regression and add test. by @jacob314 in
|
||||
[#18108](https://github.com/google-gemini/gemini-cli/pull/18108)
|
||||
- fix(ui): prevent content leak in MaxSizedBox bottom overflow by @jerop in
|
||||
[#17991](https://github.com/google-gemini/gemini-cli/pull/17991)
|
||||
- refactor: migrate checks.ts utility to core and deduplicate by @jerop in
|
||||
[#18139](https://github.com/google-gemini/gemini-cli/pull/18139)
|
||||
- feat(core): implement tool name aliasing for backward compatibility by
|
||||
@SandyTao520 in
|
||||
[#17974](https://github.com/google-gemini/gemini-cli/pull/17974)
|
||||
- docs: fix help-wanted label spelling by @pavan-sh in
|
||||
[#18114](https://github.com/google-gemini/gemini-cli/pull/18114)
|
||||
- feat(cli): implement automatic theme switching based on terminal background by
|
||||
[#18451](https://github.com/google-gemini/gemini-cli/pull/18451)
|
||||
- refactor: simplify tool output truncation to single config by @SandyTao520 in
|
||||
[#18446](https://github.com/google-gemini/gemini-cli/pull/18446)
|
||||
- bug(core): Ensure storage is initialized early, even if config is not. by
|
||||
@joshualitt in
|
||||
[#18471](https://github.com/google-gemini/gemini-cli/pull/18471)
|
||||
- chore: Update build-and-start script to support argument forwarding by
|
||||
@Abhijit-2592 in
|
||||
[#17976](https://github.com/google-gemini/gemini-cli/pull/17976)
|
||||
- fix(ide): no-op refactoring that moves the connection logic to helper
|
||||
functions by @skeshive in
|
||||
[#18118](https://github.com/google-gemini/gemini-cli/pull/18118)
|
||||
- feat: update review-frontend-and-fix slash command to review-and-fix by
|
||||
@galz10 in [#18146](https://github.com/google-gemini/gemini-cli/pull/18146)
|
||||
- fix: improve Ctrl+R reverse search by @jackwotherspoon in
|
||||
[#18075](https://github.com/google-gemini/gemini-cli/pull/18075)
|
||||
- feat(plan): handle inconsistency in schedulers by @Adib234 in
|
||||
[#17813](https://github.com/google-gemini/gemini-cli/pull/17813)
|
||||
- feat(plan): add core logic and exit_plan_mode tool definition by @jerop in
|
||||
[#18110](https://github.com/google-gemini/gemini-cli/pull/18110)
|
||||
- feat(core): rename search_file_content tool to grep_search and add legacy
|
||||
alias by @SandyTao520 in
|
||||
[#18003](https://github.com/google-gemini/gemini-cli/pull/18003)
|
||||
- fix(core): prioritize detailed error messages for code assist setup by
|
||||
@gsquared94 in
|
||||
[#17852](https://github.com/google-gemini/gemini-cli/pull/17852)
|
||||
- fix(cli): resolve environment loading and auth validation issues in ACP mode
|
||||
by @bdmorgan in
|
||||
[#18025](https://github.com/google-gemini/gemini-cli/pull/18025)
|
||||
- feat(core): add .agents/skills directory alias for skill discovery by
|
||||
[#18241](https://github.com/google-gemini/gemini-cli/pull/18241)
|
||||
- fix(core): prevent subagent bypass in plan mode by @jerop in
|
||||
[#18484](https://github.com/google-gemini/gemini-cli/pull/18484)
|
||||
- feat(cli): add WebSocket-based network logging and streaming chunk support by
|
||||
@SandyTao520 in
|
||||
[#18383](https://github.com/google-gemini/gemini-cli/pull/18383)
|
||||
- feat(cli): update approval modes UI by @jerop in
|
||||
[#18476](https://github.com/google-gemini/gemini-cli/pull/18476)
|
||||
- fix(cli): reload skills and agents on extension restart by @NTaylorMullen in
|
||||
[#18411](https://github.com/google-gemini/gemini-cli/pull/18411)
|
||||
- fix(core): expand excludeTools with legacy aliases for renamed tools by
|
||||
@SandyTao520 in
|
||||
[#18498](https://github.com/google-gemini/gemini-cli/pull/18498)
|
||||
- feat(core): overhaul system prompt for rigor, integrity, and intent alignment
|
||||
by @NTaylorMullen in
|
||||
[#17263](https://github.com/google-gemini/gemini-cli/pull/17263)
|
||||
- Patch for generate changelog docs yaml file by @g-samroberts in
|
||||
[#18496](https://github.com/google-gemini/gemini-cli/pull/18496)
|
||||
- Code review fixes for show question mark pr. by @jacob314 in
|
||||
[#18480](https://github.com/google-gemini/gemini-cli/pull/18480)
|
||||
- fix(cli): add SS3 Shift+Tab support for Windows terminals by @ThanhNguyxn in
|
||||
[#18187](https://github.com/google-gemini/gemini-cli/pull/18187)
|
||||
- chore: remove redundant planning prompt from final shell by @jerop in
|
||||
[#18528](https://github.com/google-gemini/gemini-cli/pull/18528)
|
||||
- docs: require pr-creator skill for PR generation by @NTaylorMullen in
|
||||
[#18536](https://github.com/google-gemini/gemini-cli/pull/18536)
|
||||
- chore: update colors for ask_user dialog by @jackwotherspoon in
|
||||
[#18543](https://github.com/google-gemini/gemini-cli/pull/18543)
|
||||
- feat(core): exempt high-signal tools from output masking by @abhipatel12 in
|
||||
[#18545](https://github.com/google-gemini/gemini-cli/pull/18545)
|
||||
- refactor(core): remove memory tool instructions from Gemini 3 prompt by
|
||||
@NTaylorMullen in
|
||||
[#18151](https://github.com/google-gemini/gemini-cli/pull/18151)
|
||||
- chore(core): reassign telemetry keys to avoid server conflict by @mattKorwel
|
||||
in [#18161](https://github.com/google-gemini/gemini-cli/pull/18161)
|
||||
- Add link to rewind doc in commands.md by @Adib234 in
|
||||
[#17961](https://github.com/google-gemini/gemini-cli/pull/17961)
|
||||
- feat(core): add draft-2020-12 JSON Schema support with lenient fallback by
|
||||
@afarber in [#15060](https://github.com/google-gemini/gemini-cli/pull/15060)
|
||||
- refactor(core): robust trimPreservingTrailingNewline and regression test by
|
||||
[#18559](https://github.com/google-gemini/gemini-cli/pull/18559)
|
||||
- chore: remove feedback instruction from system prompt by @NTaylorMullen in
|
||||
[#18560](https://github.com/google-gemini/gemini-cli/pull/18560)
|
||||
- feat(context): add remote configuration for tool output masking thresholds by
|
||||
@abhipatel12 in
|
||||
[#18553](https://github.com/google-gemini/gemini-cli/pull/18553)
|
||||
- feat(core): pause agent timeout budget while waiting for tool confirmation by
|
||||
@abhipatel12 in
|
||||
[#18415](https://github.com/google-gemini/gemini-cli/pull/18415)
|
||||
- refactor(config): remove experimental.enableEventDrivenScheduler setting by
|
||||
@abhipatel12 in
|
||||
[#17924](https://github.com/google-gemini/gemini-cli/pull/17924)
|
||||
- feat(cli): truncate shell output in UI history and improve active shell
|
||||
display by @jwhelangoog in
|
||||
[#17438](https://github.com/google-gemini/gemini-cli/pull/17438)
|
||||
- refactor(cli): switch useToolScheduler to event-driven engine by @abhipatel12
|
||||
in [#18565](https://github.com/google-gemini/gemini-cli/pull/18565)
|
||||
- fix(core): correct escaped interpolation in system prompt by @NTaylorMullen in
|
||||
[#18557](https://github.com/google-gemini/gemini-cli/pull/18557)
|
||||
- propagate abortSignal by @scidomino in
|
||||
[#18477](https://github.com/google-gemini/gemini-cli/pull/18477)
|
||||
- feat(core): conditionally include ctrl+f prompt based on interactive shell
|
||||
setting by @NTaylorMullen in
|
||||
[#18561](https://github.com/google-gemini/gemini-cli/pull/18561)
|
||||
- fix(core): ensure `enter_plan_mode` tool registration respects
|
||||
`experimental.plan` by @jerop in
|
||||
[#18587](https://github.com/google-gemini/gemini-cli/pull/18587)
|
||||
- feat(core): transition sub-agents to XML format and improve definitions by
|
||||
@NTaylorMullen in
|
||||
[#18555](https://github.com/google-gemini/gemini-cli/pull/18555)
|
||||
- docs: Add Plan Mode documentation by @jerop in
|
||||
[#18582](https://github.com/google-gemini/gemini-cli/pull/18582)
|
||||
- chore: strengthen validation guidance in system prompt by @NTaylorMullen in
|
||||
[#18544](https://github.com/google-gemini/gemini-cli/pull/18544)
|
||||
- Fix newline insertion bug in replace tool by @werdnum in
|
||||
[#18595](https://github.com/google-gemini/gemini-cli/pull/18595)
|
||||
- fix(evals): update save_memory evals and simplify tool description by
|
||||
@NTaylorMullen in
|
||||
[#18610](https://github.com/google-gemini/gemini-cli/pull/18610)
|
||||
- chore(evals): update validation_fidelity_pre_existing_errors to USUALLY_PASSES
|
||||
by @NTaylorMullen in
|
||||
[#18617](https://github.com/google-gemini/gemini-cli/pull/18617)
|
||||
- fix: shorten tool call IDs and fix duplicate tool name in truncated output
|
||||
filenames by @SandyTao520 in
|
||||
[#18600](https://github.com/google-gemini/gemini-cli/pull/18600)
|
||||
- feat(cli): implement atomic writes and safety checks for trusted folders by
|
||||
@galz10 in [#18406](https://github.com/google-gemini/gemini-cli/pull/18406)
|
||||
- Remove relative docs links by @chrstnb in
|
||||
[#18650](https://github.com/google-gemini/gemini-cli/pull/18650)
|
||||
- docs: add legacy snippets convention to GEMINI.md by @NTaylorMullen in
|
||||
[#18597](https://github.com/google-gemini/gemini-cli/pull/18597)
|
||||
- fix(chore): Support linting for cjs by @aswinashok44 in
|
||||
[#18639](https://github.com/google-gemini/gemini-cli/pull/18639)
|
||||
- feat: move shell efficiency guidelines to tool description by @NTaylorMullen
|
||||
in [#18614](https://github.com/google-gemini/gemini-cli/pull/18614)
|
||||
- Added "" as default value, since getText() used to expect a string only and
|
||||
thus crashed when undefined... Fixes #18076 by @019-Abhi in
|
||||
[#18099](https://github.com/google-gemini/gemini-cli/pull/18099)
|
||||
- Allow @-includes outside of workspaces (with permission) by @scidomino in
|
||||
[#18470](https://github.com/google-gemini/gemini-cli/pull/18470)
|
||||
- chore: make `ask_user` header description more clear by @jackwotherspoon in
|
||||
[#18657](https://github.com/google-gemini/gemini-cli/pull/18657)
|
||||
- refactor(core): model-dependent tool definitions by @aishaneeshah in
|
||||
[#18563](https://github.com/google-gemini/gemini-cli/pull/18563)
|
||||
- Harded code assist converter. by @jacob314 in
|
||||
[#18656](https://github.com/google-gemini/gemini-cli/pull/18656)
|
||||
- bug(core): Fix minor bug in migration logic. by @joshualitt in
|
||||
[#18661](https://github.com/google-gemini/gemini-cli/pull/18661)
|
||||
- feat: enable plan mode experiment in settings by @jerop in
|
||||
[#18636](https://github.com/google-gemini/gemini-cli/pull/18636)
|
||||
- refactor: push isValidPath() into parsePastedPaths() by @scidomino in
|
||||
[#18664](https://github.com/google-gemini/gemini-cli/pull/18664)
|
||||
- fix(cli): correct 'esc to cancel' position and restore duration display by
|
||||
@NTaylorMullen in
|
||||
[#18534](https://github.com/google-gemini/gemini-cli/pull/18534)
|
||||
- feat(cli): add DevTools integration with gemini-cli-devtools by @SandyTao520
|
||||
in [#18648](https://github.com/google-gemini/gemini-cli/pull/18648)
|
||||
- chore: remove unused exports and redundant hook files by @SandyTao520 in
|
||||
[#18681](https://github.com/google-gemini/gemini-cli/pull/18681)
|
||||
- Fix number of lines being reported in rewind confirmation dialog by @Adib234
|
||||
in [#18675](https://github.com/google-gemini/gemini-cli/pull/18675)
|
||||
- feat(cli): disable folder trust in headless mode by @galz10 in
|
||||
[#18407](https://github.com/google-gemini/gemini-cli/pull/18407)
|
||||
- Disallow unsafe type assertions by @gundermanc in
|
||||
[#18688](https://github.com/google-gemini/gemini-cli/pull/18688)
|
||||
- Change event type for release by @g-samroberts in
|
||||
[#18693](https://github.com/google-gemini/gemini-cli/pull/18693)
|
||||
- feat: handle multiple dynamic context filenames in system prompt by
|
||||
@NTaylorMullen in
|
||||
[#18598](https://github.com/google-gemini/gemini-cli/pull/18598)
|
||||
- Properly parse at-commands with narrow non-breaking spaces by @scidomino in
|
||||
[#18677](https://github.com/google-gemini/gemini-cli/pull/18677)
|
||||
- refactor(core): centralize core tool definitions and support model-specific
|
||||
schemas by @aishaneeshah in
|
||||
[#18662](https://github.com/google-gemini/gemini-cli/pull/18662)
|
||||
- feat(core): Render memory hierarchically in context. by @joshualitt in
|
||||
[#18350](https://github.com/google-gemini/gemini-cli/pull/18350)
|
||||
- feat: Ctrl+O to expand paste placeholder by @jackwotherspoon in
|
||||
[#18103](https://github.com/google-gemini/gemini-cli/pull/18103)
|
||||
- fix(cli): Improve header spacing by @NTaylorMullen in
|
||||
[#18531](https://github.com/google-gemini/gemini-cli/pull/18531)
|
||||
- Feature/quota visibility 16795 by @spencer426 in
|
||||
[#18203](https://github.com/google-gemini/gemini-cli/pull/18203)
|
||||
- Inline thinking bubbles with summary/full modes by @LyalinDotCom in
|
||||
[#18033](https://github.com/google-gemini/gemini-cli/pull/18033)
|
||||
- docs: remove TOC marker from Plan Mode header by @jerop in
|
||||
[#18678](https://github.com/google-gemini/gemini-cli/pull/18678)
|
||||
- fix(ui): remove redundant newlines in Gemini messages by @NTaylorMullen in
|
||||
[#18538](https://github.com/google-gemini/gemini-cli/pull/18538)
|
||||
- test(cli): fix AppContainer act() warnings and improve waitFor resilience by
|
||||
@NTaylorMullen in
|
||||
[#18676](https://github.com/google-gemini/gemini-cli/pull/18676)
|
||||
- refactor(core): refine Security & System Integrity section in system prompt by
|
||||
@NTaylorMullen in
|
||||
[#18601](https://github.com/google-gemini/gemini-cli/pull/18601)
|
||||
- Fix layout rounding. by @gundermanc in
|
||||
[#18667](https://github.com/google-gemini/gemini-cli/pull/18667)
|
||||
- docs(skills): enhance pr-creator safety and interactivity by @NTaylorMullen in
|
||||
[#18616](https://github.com/google-gemini/gemini-cli/pull/18616)
|
||||
- test(core): remove hardcoded model from TestRig by @NTaylorMullen in
|
||||
[#18710](https://github.com/google-gemini/gemini-cli/pull/18710)
|
||||
- feat(core): optimize sub-agents system prompt intro by @NTaylorMullen in
|
||||
[#18608](https://github.com/google-gemini/gemini-cli/pull/18608)
|
||||
- feat(cli): update approval mode labels and shortcuts per latest UX spec by
|
||||
@jerop in [#18698](https://github.com/google-gemini/gemini-cli/pull/18698)
|
||||
- fix(plan): update persistent approval mode setting by @Adib234 in
|
||||
[#18638](https://github.com/google-gemini/gemini-cli/pull/18638)
|
||||
- fix: move toasts location to left side by @jackwotherspoon in
|
||||
[#18705](https://github.com/google-gemini/gemini-cli/pull/18705)
|
||||
- feat(routing): restrict numerical routing to Gemini 3 family by @mattKorwel in
|
||||
[#18478](https://github.com/google-gemini/gemini-cli/pull/18478)
|
||||
- fix(ide): fix ide nudge setting by @skeshive in
|
||||
[#18733](https://github.com/google-gemini/gemini-cli/pull/18733)
|
||||
- fix(core): standardize tool formatting in system prompts by @NTaylorMullen in
|
||||
[#18615](https://github.com/google-gemini/gemini-cli/pull/18615)
|
||||
- chore: consolidate to green in ask user dialog by @jackwotherspoon in
|
||||
[#18734](https://github.com/google-gemini/gemini-cli/pull/18734)
|
||||
- feat: add `extensionsExplore` setting to enable extensions explore UI. by
|
||||
@sripasg in [#18686](https://github.com/google-gemini/gemini-cli/pull/18686)
|
||||
- feat(cli): defer devtools startup and integrate with F12 by @SandyTao520 in
|
||||
[#18695](https://github.com/google-gemini/gemini-cli/pull/18695)
|
||||
- ui: update & subdue footer colors and animate progress indicator by
|
||||
@keithguerin in
|
||||
[#18570](https://github.com/google-gemini/gemini-cli/pull/18570)
|
||||
- test: add model-specific snapshots for coreTools by @aishaneeshah in
|
||||
[#18707](https://github.com/google-gemini/gemini-cli/pull/18707)
|
||||
- ci: shard windows tests and fix event listener leaks by @NTaylorMullen in
|
||||
[#18670](https://github.com/google-gemini/gemini-cli/pull/18670)
|
||||
- fix: allow `ask_user` tool in yolo mode by @jackwotherspoon in
|
||||
[#18541](https://github.com/google-gemini/gemini-cli/pull/18541)
|
||||
- feat: redact disabled tools from system prompt (#13597) by @NTaylorMullen in
|
||||
[#18613](https://github.com/google-gemini/gemini-cli/pull/18613)
|
||||
- Update Gemini.md to use the curent year on creating new files by @sehoon38 in
|
||||
[#18460](https://github.com/google-gemini/gemini-cli/pull/18460)
|
||||
- Code review cleanup for thinking display by @jacob314 in
|
||||
[#18720](https://github.com/google-gemini/gemini-cli/pull/18720)
|
||||
- fix(cli): hide scrollbars when in alternate buffer copy mode by @werdnum in
|
||||
[#18354](https://github.com/google-gemini/gemini-cli/pull/18354)
|
||||
- Fix issues with rip grep by @gundermanc in
|
||||
[#18756](https://github.com/google-gemini/gemini-cli/pull/18756)
|
||||
- fix(cli): fix history navigation regression after prompt autocomplete by
|
||||
@sehoon38 in [#18752](https://github.com/google-gemini/gemini-cli/pull/18752)
|
||||
- chore: cleanup unused and add unlisted dependencies in packages/cli by
|
||||
@adamfweidman in
|
||||
[#18196](https://github.com/google-gemini/gemini-cli/pull/18196)
|
||||
- Remove MCP servers on extension uninstall by @chrstnb in
|
||||
[#18121](https://github.com/google-gemini/gemini-cli/pull/18121)
|
||||
- refactor: localize ACP error parsing logic to cli package by @bdmorgan in
|
||||
[#18193](https://github.com/google-gemini/gemini-cli/pull/18193)
|
||||
- feat(core): Add A2A auth config types by @adamfweidman in
|
||||
[#18205](https://github.com/google-gemini/gemini-cli/pull/18205)
|
||||
- Set default max attempts to 3 and use the common variable by @sehoon38 in
|
||||
[#18209](https://github.com/google-gemini/gemini-cli/pull/18209)
|
||||
- feat(plan): add exit_plan_mode ui and prompt by @jerop in
|
||||
[#18162](https://github.com/google-gemini/gemini-cli/pull/18162)
|
||||
- fix(test): improve test isolation and enable subagent evaluations by
|
||||
@cocosheng-g in
|
||||
[#18138](https://github.com/google-gemini/gemini-cli/pull/18138)
|
||||
- feat(plan): use custom deny messages in plan mode policies by @Adib234 in
|
||||
[#18195](https://github.com/google-gemini/gemini-cli/pull/18195)
|
||||
- Match on extension ID when stopping extensions by @chrstnb in
|
||||
[#18218](https://github.com/google-gemini/gemini-cli/pull/18218)
|
||||
- fix(core): Respect user's .gitignore preference by @xyrolle in
|
||||
[#15482](https://github.com/google-gemini/gemini-cli/pull/15482)
|
||||
- docs: document GEMINI_CLI_HOME environment variable by @adamfweidman in
|
||||
[#18219](https://github.com/google-gemini/gemini-cli/pull/18219)
|
||||
- chore(core): explicitly state plan storage path in prompt by @jerop in
|
||||
[#18222](https://github.com/google-gemini/gemini-cli/pull/18222)
|
||||
- A2a admin setting by @DavidAPierce in
|
||||
[#17868](https://github.com/google-gemini/gemini-cli/pull/17868)
|
||||
- feat(a2a): Add pluggable auth provider infrastructure by @adamfweidman in
|
||||
[#17934](https://github.com/google-gemini/gemini-cli/pull/17934)
|
||||
- Fix handling of empty settings by @chrstnb in
|
||||
[#18131](https://github.com/google-gemini/gemini-cli/pull/18131)
|
||||
- Reload skills when extensions change by @chrstnb in
|
||||
[#18225](https://github.com/google-gemini/gemini-cli/pull/18225)
|
||||
- feat: Add markdown rendering to ask_user tool by @jackwotherspoon in
|
||||
[#18211](https://github.com/google-gemini/gemini-cli/pull/18211)
|
||||
- Add telemetry to rewind by @Adib234 in
|
||||
[#18122](https://github.com/google-gemini/gemini-cli/pull/18122)
|
||||
- feat(admin): add support for MCP configuration via admin controls (pt1) by
|
||||
@skeshive in [#18223](https://github.com/google-gemini/gemini-cli/pull/18223)
|
||||
- feat(core): require user consent before MCP server OAuth by @ehedlund in
|
||||
[#18132](https://github.com/google-gemini/gemini-cli/pull/18132)
|
||||
- fix(sandbox): propagate GOOGLE_GEMINI_BASE_URL&GOOGLE_VERTEX_BASE_URL env vars
|
||||
by @skeshive in
|
||||
[#18231](https://github.com/google-gemini/gemini-cli/pull/18231)
|
||||
- feat(ui): move user identity display to header by @sehoon38 in
|
||||
[#18216](https://github.com/google-gemini/gemini-cli/pull/18216)
|
||||
- fix: enforce folder trust for workspace settings, skills, and context by
|
||||
@galz10 in [#17596](https://github.com/google-gemini/gemini-cli/pull/17596)
|
||||
[#18749](https://github.com/google-gemini/gemini-cli/pull/18749)
|
||||
- Fix issue where Gemini CLI creates tests in a new file by @gundermanc in
|
||||
[#18409](https://github.com/google-gemini/gemini-cli/pull/18409)
|
||||
- feat(telemetry): Ensure experiment IDs are included in OpenTelemetry logs by
|
||||
@kevin-ramdass in
|
||||
[#18747](https://github.com/google-gemini/gemini-cli/pull/18747)
|
||||
- fix(patch): cherry-pick e9a9474 to release/v0.29.0-preview.0-pr-18840 to patch
|
||||
version v0.29.0-preview.0 and create version 0.29.0-preview.1 by
|
||||
@gemini-cli-robot in
|
||||
[#18841](https://github.com/google-gemini/gemini-cli/pull/18841)
|
||||
- fix(patch): cherry-pick 08e8eea to release/v0.29.0-preview.1-pr-18855 to patch
|
||||
version v0.29.0-preview.1 and create version 0.29.0-preview.2 by
|
||||
@gemini-cli-robot in
|
||||
[#18905](https://github.com/google-gemini/gemini-cli/pull/18905)
|
||||
- fix(patch): cherry-pick d0c6a56 to release/v0.29.0-preview.2-pr-18976 to patch
|
||||
version v0.29.0-preview.2 and create version 0.29.0-preview.3 by
|
||||
@gemini-cli-robot in
|
||||
[#19023](https://github.com/google-gemini/gemini-cli/pull/19023)
|
||||
- fix(patch): cherry-pick e5ff202 to release/v0.29.0-preview.3-pr-19254 to patch
|
||||
version v0.29.0-preview.3 and create version 0.29.0-preview.4 by
|
||||
@gemini-cli-robot in
|
||||
[#19264](https://github.com/google-gemini/gemini-cli/pull/19264)
|
||||
- fix(patch): cherry-pick 9590a09 to release/v0.29.0-preview.4-pr-18771 to patch
|
||||
version v0.29.0-preview.4 and create version 0.29.0-preview.5 by
|
||||
@gemini-cli-robot in
|
||||
[#19274](https://github.com/google-gemini/gemini-cli/pull/19274)
|
||||
|
||||
**Full Changelog**:
|
||||
https://github.com/google-gemini/gemini-cli/compare/v0.27.0...v0.28.0
|
||||
https://github.com/google-gemini/gemini-cli/compare/v0.28.2...v0.29.0
|
||||
|
||||
+296
-349
@@ -1,6 +1,6 @@
|
||||
# Preview release: Release v0.29.0-preview.0
|
||||
# Preview release: v0.30.0-preview.3
|
||||
|
||||
Released: February 10, 2026
|
||||
Released: February 19, 2026
|
||||
|
||||
Our preview release includes the latest, new, and experimental features. This
|
||||
release may not be as stable as our [latest weekly release](latest.md).
|
||||
@@ -13,355 +13,302 @@ npm install -g @google/gemini-cli@preview
|
||||
|
||||
## Highlights
|
||||
|
||||
- **Plan Mode Enhancements**: Significant updates to Plan Mode, including new
|
||||
commands, support for MCP servers, integration of planning artifacts, and
|
||||
improved iteration guidance.
|
||||
- **Core Agent Improvements**: Enhancements to the core agent, including better
|
||||
system prompt rigor, improved subagent definitions, and enhanced tool
|
||||
execution limits.
|
||||
- **CLI UX/UI Updates**: Various UI and UX improvements, such as autocomplete in
|
||||
the input prompt, updated approval mode labels, DevTools integration, and
|
||||
improved header spacing.
|
||||
- **Tooling & Extension Updates**: Improvements to existing tools like
|
||||
`ask_user` and `grep_search`, and new features for extension management.
|
||||
- **Bug Fixes**: Numerous bug fixes across the CLI and core, addressing issues
|
||||
with interactive commands, memory leaks, permission checks, and more.
|
||||
- **Context and Tool Output Management**: Features for observation masking for
|
||||
tool outputs, session-linked tool output storage, and persistence for masked
|
||||
tool outputs.
|
||||
- **Initial SDK Package:** Introduced the initial SDK package with support for
|
||||
custom skills and dynamic system instructions.
|
||||
- **Refined Plan Mode:** Refined Plan Mode with support for enabling skills,
|
||||
improved agentic execution, and project exploration without planning.
|
||||
- **Enhanced CLI UI:** Enhanced CLI UI with a new clean UI toggle, minimal-mode
|
||||
bleed-through, and support for Ctrl-Z suspension.
|
||||
- **`--policy` flag:** Added the `--policy` flag to support user-defined
|
||||
policies.
|
||||
- **New Themes:** Added Solarized Dark and Solarized Light themes.
|
||||
|
||||
## What's Changed
|
||||
|
||||
- fix: remove ask_user tool from non-interactive modes by jackwotherspoon in
|
||||
[#18154](https://github.com/google-gemini/gemini-cli/pull/18154)
|
||||
- fix(cli): allow restricted .env loading in untrusted sandboxed folders by
|
||||
galz10 in [#17806](https://github.com/google-gemini/gemini-cli/pull/17806)
|
||||
- Encourage agent to utilize ecosystem tools to perform work by gundermanc in
|
||||
[#17881](https://github.com/google-gemini/gemini-cli/pull/17881)
|
||||
- feat(plan): unify workflow location in system prompt to optimize caching by
|
||||
jerop in [#18258](https://github.com/google-gemini/gemini-cli/pull/18258)
|
||||
- feat(core): enable getUserTierName in config by sehoon38 in
|
||||
[#18265](https://github.com/google-gemini/gemini-cli/pull/18265)
|
||||
- feat(core): add default execution limits for subagents by abhipatel12 in
|
||||
[#18274](https://github.com/google-gemini/gemini-cli/pull/18274)
|
||||
- Fix issue where agent gets stuck at interactive commands. by gundermanc in
|
||||
[#18272](https://github.com/google-gemini/gemini-cli/pull/18272)
|
||||
- chore(release): bump version to 0.29.0-nightly.20260203.71f46f116 by
|
||||
gemini-cli-robot in
|
||||
[#18243](https://github.com/google-gemini/gemini-cli/pull/18243)
|
||||
- feat(core): remove hardcoded policy bypass for local subagents by abhipatel12
|
||||
in [#18153](https://github.com/google-gemini/gemini-cli/pull/18153)
|
||||
- feat(plan): implement plan slash command by Adib234 in
|
||||
[#17698](https://github.com/google-gemini/gemini-cli/pull/17698)
|
||||
- feat: increase ask_user label limit to 16 characters by jackwotherspoon in
|
||||
[#18320](https://github.com/google-gemini/gemini-cli/pull/18320)
|
||||
- Add information about the agent skills lifecycle and clarify docs-writer skill
|
||||
metadata. by g-samroberts in
|
||||
[#18234](https://github.com/google-gemini/gemini-cli/pull/18234)
|
||||
- feat(core): add enter_plan_mode tool by jerop in
|
||||
[#18324](https://github.com/google-gemini/gemini-cli/pull/18324)
|
||||
- Stop showing an error message in /plan by Adib234 in
|
||||
[#18333](https://github.com/google-gemini/gemini-cli/pull/18333)
|
||||
- fix(hooks): remove unnecessary logging for hook registration by abhipatel12 in
|
||||
[#18332](https://github.com/google-gemini/gemini-cli/pull/18332)
|
||||
- fix(mcp): ensure MCP transport is closed to prevent memory leaks by cbcoutinho
|
||||
in [#18054](https://github.com/google-gemini/gemini-cli/pull/18054)
|
||||
- feat(skills): implement linking for agent skills by MushuEE in
|
||||
[#18295](https://github.com/google-gemini/gemini-cli/pull/18295)
|
||||
- Changelogs for 0.27.0 and 0.28.0-preview0 by g-samroberts in
|
||||
[#18336](https://github.com/google-gemini/gemini-cli/pull/18336)
|
||||
- chore: correct docs as skills and hooks are stable by jackwotherspoon in
|
||||
[#18358](https://github.com/google-gemini/gemini-cli/pull/18358)
|
||||
- feat(admin): Implement admin allowlist for MCP server configurations by
|
||||
skeshive in [#18311](https://github.com/google-gemini/gemini-cli/pull/18311)
|
||||
- fix(core): add retry logic for transient SSL/TLS errors
|
||||
([#17318](https://github.com/google-gemini/gemini-cli/pull/17318)) by
|
||||
ppgranger in [#18310](https://github.com/google-gemini/gemini-cli/pull/18310)
|
||||
- Add support for /extensions config command by chrstnb in
|
||||
[#17895](https://github.com/google-gemini/gemini-cli/pull/17895)
|
||||
- fix(core): handle non-compliant mcpbridge responses from Xcode 26.3 by
|
||||
peterfriese in
|
||||
[#18376](https://github.com/google-gemini/gemini-cli/pull/18376)
|
||||
- feat(cli): Add W, B, E Vim motions and operator support by ademuri in
|
||||
[#16209](https://github.com/google-gemini/gemini-cli/pull/16209)
|
||||
- fix: Windows Specific Agent Quality & System Prompt by scidomino in
|
||||
[#18351](https://github.com/google-gemini/gemini-cli/pull/18351)
|
||||
- feat(plan): support replace tool in plan mode to edit plans by jerop in
|
||||
[#18379](https://github.com/google-gemini/gemini-cli/pull/18379)
|
||||
- Improving memory tool instructions and eval testing by alisa-alisa in
|
||||
[#18091](https://github.com/google-gemini/gemini-cli/pull/18091)
|
||||
- fix(cli): color extension link success message green by MushuEE in
|
||||
[#18386](https://github.com/google-gemini/gemini-cli/pull/18386)
|
||||
- undo by jacob314 in
|
||||
[#18147](https://github.com/google-gemini/gemini-cli/pull/18147)
|
||||
- feat(plan): add guidance on iterating on approved plans vs creating new plans
|
||||
by jerop in [#18346](https://github.com/google-gemini/gemini-cli/pull/18346)
|
||||
- feat(plan): fix invalid tool calls in plan mode by Adib234 in
|
||||
[#18352](https://github.com/google-gemini/gemini-cli/pull/18352)
|
||||
- feat(plan): integrate planning artifacts and tools into primary workflows by
|
||||
jerop in [#18375](https://github.com/google-gemini/gemini-cli/pull/18375)
|
||||
- Fix permission check by scidomino in
|
||||
[#18395](https://github.com/google-gemini/gemini-cli/pull/18395)
|
||||
- ux(polish) autocomplete in the input prompt by jacob314 in
|
||||
[#18181](https://github.com/google-gemini/gemini-cli/pull/18181)
|
||||
- fix: resolve infinite loop when using 'Modify with external editor' by
|
||||
ppgranger in [#17453](https://github.com/google-gemini/gemini-cli/pull/17453)
|
||||
- feat: expand verify-release to macOS and Windows by yunaseoul in
|
||||
[#18145](https://github.com/google-gemini/gemini-cli/pull/18145)
|
||||
- feat(plan): implement support for MCP servers in Plan mode by Adib234 in
|
||||
[#18229](https://github.com/google-gemini/gemini-cli/pull/18229)
|
||||
- chore: update folder trust error messaging by galz10 in
|
||||
[#18402](https://github.com/google-gemini/gemini-cli/pull/18402)
|
||||
- feat(plan): create a metric for execution of plans generated in plan mode by
|
||||
Adib234 in [#18236](https://github.com/google-gemini/gemini-cli/pull/18236)
|
||||
- perf(ui): optimize stripUnsafeCharacters with regex by gsquared94 in
|
||||
[#18413](https://github.com/google-gemini/gemini-cli/pull/18413)
|
||||
- feat(context): implement observation masking for tool outputs by abhipatel12
|
||||
in [#18389](https://github.com/google-gemini/gemini-cli/pull/18389)
|
||||
- feat(core,cli): implement session-linked tool output storage and cleanup by
|
||||
abhipatel12 in
|
||||
[#18416](https://github.com/google-gemini/gemini-cli/pull/18416)
|
||||
- Shorten temp directory by joshualitt in
|
||||
[#17901](https://github.com/google-gemini/gemini-cli/pull/17901)
|
||||
- feat(plan): add behavioral evals for plan mode by jerop in
|
||||
[#18437](https://github.com/google-gemini/gemini-cli/pull/18437)
|
||||
- Add extension registry client by chrstnb in
|
||||
[#18396](https://github.com/google-gemini/gemini-cli/pull/18396)
|
||||
- Enable extension config by default by chrstnb in
|
||||
[#18447](https://github.com/google-gemini/gemini-cli/pull/18447)
|
||||
- Automatically generate change logs on release by g-samroberts in
|
||||
[#18401](https://github.com/google-gemini/gemini-cli/pull/18401)
|
||||
- Remove previewFeatures and default to Gemini 3 by sehoon38 in
|
||||
[#18414](https://github.com/google-gemini/gemini-cli/pull/18414)
|
||||
- feat(admin): apply MCP allowlist to extensions & gemini mcp list command by
|
||||
skeshive in [#18442](https://github.com/google-gemini/gemini-cli/pull/18442)
|
||||
- fix(cli): improve focus navigation for interactive and background shells by
|
||||
galz10 in [#18343](https://github.com/google-gemini/gemini-cli/pull/18343)
|
||||
- Add shortcuts hint and panel for discoverability by LyalinDotCom in
|
||||
[#18035](https://github.com/google-gemini/gemini-cli/pull/18035)
|
||||
- fix(config): treat system settings as read-only during migration and warn user
|
||||
by spencer426 in
|
||||
[#18277](https://github.com/google-gemini/gemini-cli/pull/18277)
|
||||
- feat(plan): add positive test case and update eval stability policy by jerop
|
||||
in [#18457](https://github.com/google-gemini/gemini-cli/pull/18457)
|
||||
- fix- windows: add shell: true for spawnSync to fix EINVAL with .cmd editors by
|
||||
zackoch in [#18408](https://github.com/google-gemini/gemini-cli/pull/18408)
|
||||
- bug(core): Fix bug when saving plans. by joshualitt in
|
||||
[#18465](https://github.com/google-gemini/gemini-cli/pull/18465)
|
||||
- Refactor atCommandProcessor by scidomino in
|
||||
[#18461](https://github.com/google-gemini/gemini-cli/pull/18461)
|
||||
- feat(core): implement persistence and resumption for masked tool outputs by
|
||||
abhipatel12 in
|
||||
[#18451](https://github.com/google-gemini/gemini-cli/pull/18451)
|
||||
- refactor: simplify tool output truncation to single config by SandyTao520 in
|
||||
[#18446](https://github.com/google-gemini/gemini-cli/pull/18446)
|
||||
- bug(core): Ensure storage is initialized early, even if config is not. by
|
||||
joshualitt in [#18471](https://github.com/google-gemini/gemini-cli/pull/18471)
|
||||
- chore: Update build-and-start script to support argument forwarding by
|
||||
Abhijit-2592 in
|
||||
[#18241](https://github.com/google-gemini/gemini-cli/pull/18241)
|
||||
- fix(core): prevent subagent bypass in plan mode by jerop in
|
||||
[#18484](https://github.com/google-gemini/gemini-cli/pull/18484)
|
||||
- feat(cli): add WebSocket-based network logging and streaming chunk support by
|
||||
SandyTao520 in
|
||||
[#18383](https://github.com/google-gemini/gemini-cli/pull/18383)
|
||||
- feat(cli): update approval modes UI by jerop in
|
||||
[#18476](https://github.com/google-gemini/gemini-cli/pull/18476)
|
||||
- fix(cli): reload skills and agents on extension restart by NTaylorMullen in
|
||||
[#18411](https://github.com/google-gemini/gemini-cli/pull/18411)
|
||||
- fix(core): expand excludeTools with legacy aliases for renamed tools by
|
||||
SandyTao520 in
|
||||
[#18498](https://github.com/google-gemini/gemini-cli/pull/18498)
|
||||
- feat(core): overhaul system prompt for rigor, integrity, and intent alignment
|
||||
by NTaylorMullen in
|
||||
[#17263](https://github.com/google-gemini/gemini-cli/pull/17263)
|
||||
- Patch for generate changelog docs yaml file by g-samroberts in
|
||||
[#18496](https://github.com/google-gemini/gemini-cli/pull/18496)
|
||||
- Code review fixes for show question mark pr. by jacob314 in
|
||||
[#18480](https://github.com/google-gemini/gemini-cli/pull/18480)
|
||||
- fix(cli): add SS3 Shift+Tab support for Windows terminals by ThanhNguyxn in
|
||||
[#18187](https://github.com/google-gemini/gemini-cli/pull/18187)
|
||||
- chore: remove redundant planning prompt from final shell by jerop in
|
||||
[#18528](https://github.com/google-gemini/gemini-cli/pull/18528)
|
||||
- docs: require pr-creator skill for PR generation by NTaylorMullen in
|
||||
[#18536](https://github.com/google-gemini/gemini-cli/pull/18536)
|
||||
- chore: update colors for ask_user dialog by jackwotherspoon in
|
||||
[#18543](https://github.com/google-gemini/gemini-cli/pull/18543)
|
||||
- feat(core): exempt high-signal tools from output masking by abhipatel12 in
|
||||
[#18545](https://github.com/google-gemini/gemini-cli/pull/18545)
|
||||
- refactor(core): remove memory tool instructions from Gemini 3 prompt by
|
||||
NTaylorMullen in
|
||||
[#18559](https://github.com/google-gemini/gemini-cli/pull/18559)
|
||||
- chore: remove feedback instruction from system prompt by NTaylorMullen in
|
||||
[#18560](https://github.com/google-gemini/gemini-cli/pull/18560)
|
||||
- feat(context): add remote configuration for tool output masking thresholds by
|
||||
abhipatel12 in
|
||||
[#18553](https://github.com/google-gemini/gemini-cli/pull/18553)
|
||||
- feat(core): pause agent timeout budget while waiting for tool confirmation by
|
||||
abhipatel12 in
|
||||
[#18415](https://github.com/google-gemini/gemini-cli/pull/18415)
|
||||
- refactor(config): remove experimental.enableEventDrivenScheduler setting by
|
||||
abhipatel12 in
|
||||
[#17924](https://github.com/google-gemini/gemini-cli/pull/17924)
|
||||
- feat(cli): truncate shell output in UI history and improve active shell
|
||||
display by jwhelangoog in
|
||||
[#17438](https://github.com/google-gemini/gemini-cli/pull/17438)
|
||||
- refactor(cli): switch useToolScheduler to event-driven engine by abhipatel12
|
||||
in [#18565](https://github.com/google-gemini/gemini-cli/pull/18565)
|
||||
- fix(core): correct escaped interpolation in system prompt by NTaylorMullen in
|
||||
[#18557](https://github.com/google-gemini/gemini-cli/pull/18557)
|
||||
- propagate abortSignal by scidomino in
|
||||
[#18477](https://github.com/google-gemini/gemini-cli/pull/18477)
|
||||
- feat(core): conditionally include ctrl+f prompt based on interactive shell
|
||||
setting by NTaylorMullen in
|
||||
[#18561](https://github.com/google-gemini/gemini-cli/pull/18561)
|
||||
- fix(core): ensure enter_plan_mode tool registration respects experimental.plan
|
||||
by jerop in [#18587](https://github.com/google-gemini/gemini-cli/pull/18587)
|
||||
- feat(core): transition sub-agents to XML format and improve definitions by
|
||||
NTaylorMullen in
|
||||
[#18555](https://github.com/google-gemini/gemini-cli/pull/18555)
|
||||
- docs: Add Plan Mode documentation by jerop in
|
||||
[#18582](https://github.com/google-gemini/gemini-cli/pull/18582)
|
||||
- chore: strengthen validation guidance in system prompt by NTaylorMullen in
|
||||
[#18544](https://github.com/google-gemini/gemini-cli/pull/18544)
|
||||
- Fix newline insertion bug in replace tool by werdnum in
|
||||
[#18595](https://github.com/google-gemini/gemini-cli/pull/18595)
|
||||
- fix(evals): update save_memory evals and simplify tool description by
|
||||
NTaylorMullen in
|
||||
[#18610](https://github.com/google-gemini/gemini-cli/pull/18610)
|
||||
- chore(evals): update validation_fidelity_pre_existing_errors to USUALLY_PASSES
|
||||
by NTaylorMullen in
|
||||
[#18617](https://github.com/google-gemini/gemini-cli/pull/18617)
|
||||
- fix: shorten tool call IDs and fix duplicate tool name in truncated output
|
||||
filenames by SandyTao520 in
|
||||
[#18600](https://github.com/google-gemini/gemini-cli/pull/18600)
|
||||
- feat(cli): implement atomic writes and safety checks for trusted folders by
|
||||
galz10 in [#18406](https://github.com/google-gemini/gemini-cli/pull/18406)
|
||||
- Remove relative docs links by chrstnb in
|
||||
[#18650](https://github.com/google-gemini/gemini-cli/pull/18650)
|
||||
- docs: add legacy snippets convention to GEMINI.md by NTaylorMullen in
|
||||
[#18597](https://github.com/google-gemini/gemini-cli/pull/18597)
|
||||
- fix(chore): Support linting for cjs by aswinashok44 in
|
||||
[#18639](https://github.com/google-gemini/gemini-cli/pull/18639)
|
||||
- feat: move shell efficiency guidelines to tool description by NTaylorMullen in
|
||||
[#18614](https://github.com/google-gemini/gemini-cli/pull/18614)
|
||||
- Added "" as default value, since getText() used to expect a string only and
|
||||
thus crashed when undefined... Fixes #18076 by 019-Abhi in
|
||||
[#18099](https://github.com/google-gemini/gemini-cli/pull/18099)
|
||||
- Allow @-includes outside of workspaces (with permission) by scidomino in
|
||||
[#18470](https://github.com/google-gemini/gemini-cli/pull/18470)
|
||||
- chore: make ask_user header description more clear by jackwotherspoon in
|
||||
[#18657](https://github.com/google-gemini/gemini-cli/pull/18657)
|
||||
- refactor(core): model-dependent tool definitions by aishaneeshah in
|
||||
[#18563](https://github.com/google-gemini/gemini-cli/pull/18563)
|
||||
- Harded code assist converter. by jacob314 in
|
||||
[#18656](https://github.com/google-gemini/gemini-cli/pull/18656)
|
||||
- bug(core): Fix minor bug in migration logic. by joshualitt in
|
||||
[#18661](https://github.com/google-gemini/gemini-cli/pull/18661)
|
||||
- feat: enable plan mode experiment in settings by jerop in
|
||||
[#18636](https://github.com/google-gemini/gemini-cli/pull/18636)
|
||||
- refactor: push isValidPath() into parsePastedPaths() by scidomino in
|
||||
[#18664](https://github.com/google-gemini/gemini-cli/pull/18664)
|
||||
- fix(cli): correct 'esc to cancel' position and restore duration display by
|
||||
NTaylorMullen in
|
||||
[#18534](https://github.com/google-gemini/gemini-cli/pull/18534)
|
||||
- feat(cli): add DevTools integration with gemini-cli-devtools by SandyTao520 in
|
||||
[#18648](https://github.com/google-gemini/gemini-cli/pull/18648)
|
||||
- chore: remove unused exports and redundant hook files by SandyTao520 in
|
||||
[#18681](https://github.com/google-gemini/gemini-cli/pull/18681)
|
||||
- Fix number of lines being reported in rewind confirmation dialog by Adib234 in
|
||||
[#18675](https://github.com/google-gemini/gemini-cli/pull/18675)
|
||||
- feat(cli): disable folder trust in headless mode by galz10 in
|
||||
[#18407](https://github.com/google-gemini/gemini-cli/pull/18407)
|
||||
- Disallow unsafe type assertions by gundermanc in
|
||||
[#18688](https://github.com/google-gemini/gemini-cli/pull/18688)
|
||||
- Change event type for release by g-samroberts in
|
||||
[#18693](https://github.com/google-gemini/gemini-cli/pull/18693)
|
||||
- feat: handle multiple dynamic context filenames in system prompt by
|
||||
NTaylorMullen in
|
||||
[#18598](https://github.com/google-gemini/gemini-cli/pull/18598)
|
||||
- Properly parse at-commands with narrow non-breaking spaces by scidomino in
|
||||
[#18677](https://github.com/google-gemini/gemini-cli/pull/18677)
|
||||
- refactor(core): centralize core tool definitions and support model-specific
|
||||
schemas by aishaneeshah in
|
||||
[#18662](https://github.com/google-gemini/gemini-cli/pull/18662)
|
||||
- feat(core): Render memory hierarchically in context. by joshualitt in
|
||||
[#18350](https://github.com/google-gemini/gemini-cli/pull/18350)
|
||||
- feat: Ctrl+O to expand paste placeholder by jackwotherspoon in
|
||||
[#18103](https://github.com/google-gemini/gemini-cli/pull/18103)
|
||||
- fix(cli): Improve header spacing by NTaylorMullen in
|
||||
[#18531](https://github.com/google-gemini/gemini-cli/pull/18531)
|
||||
- Feature/quota visibility 16795 by spencer426 in
|
||||
[#18203](https://github.com/google-gemini/gemini-cli/pull/18203)
|
||||
- Inline thinking bubbles with summary/full modes by LyalinDotCom in
|
||||
[#18033](https://github.com/google-gemini/gemini-cli/pull/18033)
|
||||
- docs: remove TOC marker from Plan Mode header by jerop in
|
||||
[#18678](https://github.com/google-gemini/gemini-cli/pull/18678)
|
||||
- fix(ui): remove redundant newlines in Gemini messages by NTaylorMullen in
|
||||
[#18538](https://github.com/google-gemini/gemini-cli/pull/18538)
|
||||
- test(cli): fix AppContainer act() warnings and improve waitFor resilience by
|
||||
NTaylorMullen in
|
||||
[#18676](https://github.com/google-gemini/gemini-cli/pull/18676)
|
||||
- refactor(core): refine Security & System Integrity section in system prompt by
|
||||
NTaylorMullen in
|
||||
[#18601](https://github.com/google-gemini/gemini-cli/pull/18601)
|
||||
- Fix layout rounding. by gundermanc in
|
||||
[#18667](https://github.com/google-gemini/gemini-cli/pull/18667)
|
||||
- docs(skills): enhance pr-creator safety and interactivity by NTaylorMullen in
|
||||
[#18616](https://github.com/google-gemini/gemini-cli/pull/18616)
|
||||
- test(core): remove hardcoded model from TestRig by NTaylorMullen in
|
||||
[#18710](https://github.com/google-gemini/gemini-cli/pull/18710)
|
||||
- feat(core): optimize sub-agents system prompt intro by NTaylorMullen in
|
||||
[#18608](https://github.com/google-gemini/gemini-cli/pull/18608)
|
||||
- feat(cli): update approval mode labels and shortcuts per latest UX spec by
|
||||
jerop in [#18698](https://github.com/google-gemini/gemini-cli/pull/18698)
|
||||
- fix(plan): update persistent approval mode setting by Adib234 in
|
||||
[#18638](https://github.com/google-gemini/gemini-cli/pull/18638)
|
||||
- fix: move toasts location to left side by jackwotherspoon in
|
||||
[#18705](https://github.com/google-gemini/gemini-cli/pull/18705)
|
||||
- feat(routing): restrict numerical routing to Gemini 3 family by mattKorwel in
|
||||
[#18478](https://github.com/google-gemini/gemini-cli/pull/18478)
|
||||
- fix(ide): fix ide nudge setting by skeshive in
|
||||
[#18733](https://github.com/google-gemini/gemini-cli/pull/18733)
|
||||
- fix(core): standardize tool formatting in system prompts by NTaylorMullen in
|
||||
[#18615](https://github.com/google-gemini/gemini-cli/pull/18615)
|
||||
- chore: consolidate to green in ask user dialog by jackwotherspoon in
|
||||
[#18734](https://github.com/google-gemini/gemini-cli/pull/18734)
|
||||
- feat: add extensionsExplore setting to enable extensions explore UI. by
|
||||
sripasg in [#18686](https://github.com/google-gemini/gemini-cli/pull/18686)
|
||||
- feat(cli): defer devtools startup and integrate with F12 by SandyTao520 in
|
||||
[#18695](https://github.com/google-gemini/gemini-cli/pull/18695)
|
||||
- ui: update & subdue footer colors and animate progress indicator by
|
||||
keithguerin in
|
||||
[#18570](https://github.com/google-gemini/gemini-cli/pull/18570)
|
||||
- test: add model-specific snapshots for coreTools by aishaneeshah in
|
||||
[#18707](https://github.com/google-gemini/gemini-cli/pull/18707)
|
||||
- ci: shard windows tests and fix event listener leaks by NTaylorMullen in
|
||||
[#18670](https://github.com/google-gemini/gemini-cli/pull/18670)
|
||||
- fix: allow ask_user tool in yolo mode by jackwotherspoon in
|
||||
[#18541](https://github.com/google-gemini/gemini-cli/pull/18541)
|
||||
- feat: redact disabled tools from system prompt
|
||||
([#13597](https://github.com/google-gemini/gemini-cli/pull/13597)) by
|
||||
NTaylorMullen in
|
||||
[#18613](https://github.com/google-gemini/gemini-cli/pull/18613)
|
||||
- Update Gemini.md to use the curent year on creating new files by sehoon38 in
|
||||
[#18460](https://github.com/google-gemini/gemini-cli/pull/18460)
|
||||
- Code review cleanup for thinking display by jacob314 in
|
||||
[#18720](https://github.com/google-gemini/gemini-cli/pull/18720)
|
||||
- fix(cli): hide scrollbars when in alternate buffer copy mode by werdnum in
|
||||
[#18354](https://github.com/google-gemini/gemini-cli/pull/18354)
|
||||
- Fix issues with rip grep by gundermanc in
|
||||
[#18756](https://github.com/google-gemini/gemini-cli/pull/18756)
|
||||
- fix(cli): fix history navigation regression after prompt autocomplete by
|
||||
sehoon38 in [#18752](https://github.com/google-gemini/gemini-cli/pull/18752)
|
||||
- chore: cleanup unused and add unlisted dependencies in packages/cli by
|
||||
adamfweidman in
|
||||
[#18749](https://github.com/google-gemini/gemini-cli/pull/18749)
|
||||
- Fix issue where Gemini CLI creates tests in a new file by gundermanc in
|
||||
[#18409](https://github.com/google-gemini/gemini-cli/pull/18409)
|
||||
- feat(telemetry): Ensure experiment IDs are included in OpenTelemetry logs by
|
||||
kevin-ramdass in
|
||||
[#18747](https://github.com/google-gemini/gemini-cli/pull/18747)
|
||||
- fix(patch): cherry-pick 261788c to release/v0.30.0-preview.0-pr-19453 to patch
|
||||
version v0.30.0-preview.0 and create version 0.30.0-preview.1 by
|
||||
@gemini-cli-robot in
|
||||
[#19490](https://github.com/google-gemini/gemini-cli/pull/19490)
|
||||
- feat(ux): added text wrapping capabilities to markdown tables by @devr0306 in
|
||||
[#18240](https://github.com/google-gemini/gemini-cli/pull/18240)
|
||||
- Revert "fix(mcp): ensure MCP transport is closed to prevent memory leaks" by
|
||||
@skeshive in [#18771](https://github.com/google-gemini/gemini-cli/pull/18771)
|
||||
- chore(release): bump version to 0.30.0-nightly.20260210.a2174751d by
|
||||
@gemini-cli-robot in
|
||||
[#18772](https://github.com/google-gemini/gemini-cli/pull/18772)
|
||||
- chore: cleanup unused and add unlisted dependencies in packages/core by
|
||||
@adamfweidman in
|
||||
[#18762](https://github.com/google-gemini/gemini-cli/pull/18762)
|
||||
- chore(core): update activate_skill prompt verbiage to be more direct by
|
||||
@NTaylorMullen in
|
||||
[#18605](https://github.com/google-gemini/gemini-cli/pull/18605)
|
||||
- Add autoconfigure memory usage setting to the dialog by @jacob314 in
|
||||
[#18510](https://github.com/google-gemini/gemini-cli/pull/18510)
|
||||
- fix(core): prevent race condition in policy persistence by @braddux in
|
||||
[#18506](https://github.com/google-gemini/gemini-cli/pull/18506)
|
||||
- fix(evals): prevent false positive in hierarchical memory test by
|
||||
@Abhijit-2592 in
|
||||
[#18777](https://github.com/google-gemini/gemini-cli/pull/18777)
|
||||
- test(evals): mark all `save_memory` evals as `USUALLY_PASSES` due to
|
||||
unreliability by @jerop in
|
||||
[#18786](https://github.com/google-gemini/gemini-cli/pull/18786)
|
||||
- feat(cli): add setting to hide shortcuts hint UI by @LyalinDotCom in
|
||||
[#18562](https://github.com/google-gemini/gemini-cli/pull/18562)
|
||||
- feat(core): formalize 5-phase sequential planning workflow by @jerop in
|
||||
[#18759](https://github.com/google-gemini/gemini-cli/pull/18759)
|
||||
- Introduce limits for search results. by @gundermanc in
|
||||
[#18767](https://github.com/google-gemini/gemini-cli/pull/18767)
|
||||
- fix(cli): allow closing debug console after auto-open via flicker by
|
||||
@SandyTao520 in
|
||||
[#18795](https://github.com/google-gemini/gemini-cli/pull/18795)
|
||||
- feat(masking): enable tool output masking by default by @abhipatel12 in
|
||||
[#18564](https://github.com/google-gemini/gemini-cli/pull/18564)
|
||||
- perf(ui): optimize table rendering by memoizing styled characters by @devr0306
|
||||
in [#18770](https://github.com/google-gemini/gemini-cli/pull/18770)
|
||||
- feat: multi-line text answers in ask-user tool by @jackwotherspoon in
|
||||
[#18741](https://github.com/google-gemini/gemini-cli/pull/18741)
|
||||
- perf(cli): truncate large debug logs and limit message history by @mattKorwel
|
||||
in [#18663](https://github.com/google-gemini/gemini-cli/pull/18663)
|
||||
- fix(core): complete MCP discovery when configured servers are skipped by
|
||||
@LyalinDotCom in
|
||||
[#18586](https://github.com/google-gemini/gemini-cli/pull/18586)
|
||||
- fix(core): cache CLI version to ensure consistency during sessions by
|
||||
@sehoon38 in [#18793](https://github.com/google-gemini/gemini-cli/pull/18793)
|
||||
- fix(cli): resolve double rendering in shpool and address vscode lint warnings
|
||||
by @braddux in
|
||||
[#18704](https://github.com/google-gemini/gemini-cli/pull/18704)
|
||||
- feat(plan): document and validate Plan Mode policy overrides by @jerop in
|
||||
[#18825](https://github.com/google-gemini/gemini-cli/pull/18825)
|
||||
- Fix pressing any key to exit select mode. by @jacob314 in
|
||||
[#18421](https://github.com/google-gemini/gemini-cli/pull/18421)
|
||||
- fix(cli): update F12 behavior to only open drawer if browser fails by
|
||||
@SandyTao520 in
|
||||
[#18829](https://github.com/google-gemini/gemini-cli/pull/18829)
|
||||
- feat(plan): allow skills to be enabled in plan mode by @Adib234 in
|
||||
[#18817](https://github.com/google-gemini/gemini-cli/pull/18817)
|
||||
- docs(plan): add documentation for plan mode tools by @jerop in
|
||||
[#18827](https://github.com/google-gemini/gemini-cli/pull/18827)
|
||||
- Remove experimental note in extension settings docs by @chrstnb in
|
||||
[#18822](https://github.com/google-gemini/gemini-cli/pull/18822)
|
||||
- Update prompt and grep tool definition to limit context size by @gundermanc in
|
||||
[#18780](https://github.com/google-gemini/gemini-cli/pull/18780)
|
||||
- docs(plan): add `ask_user` tool documentation by @jerop in
|
||||
[#18830](https://github.com/google-gemini/gemini-cli/pull/18830)
|
||||
- Revert unintended credentials exposure by @Adib234 in
|
||||
[#18840](https://github.com/google-gemini/gemini-cli/pull/18840)
|
||||
- feat(core): update internal utility models to Gemini 3 by @SandyTao520 in
|
||||
[#18773](https://github.com/google-gemini/gemini-cli/pull/18773)
|
||||
- feat(a2a): add value-resolver for auth credential resolution by @adamfweidman
|
||||
in [#18653](https://github.com/google-gemini/gemini-cli/pull/18653)
|
||||
- Removed getPlainTextLength by @devr0306 in
|
||||
[#18848](https://github.com/google-gemini/gemini-cli/pull/18848)
|
||||
- More grep prompt tweaks by @gundermanc in
|
||||
[#18846](https://github.com/google-gemini/gemini-cli/pull/18846)
|
||||
- refactor(cli): Reactive useSettingsStore hook by @psinha40898 in
|
||||
[#14915](https://github.com/google-gemini/gemini-cli/pull/14915)
|
||||
- fix(mcp): Ensure that stdio MCP server execution has the `GEMINI_CLI=1` env
|
||||
variable populated. by @richieforeman in
|
||||
[#18832](https://github.com/google-gemini/gemini-cli/pull/18832)
|
||||
- fix(core): improve headless mode detection for flags and query args by @galz10
|
||||
in [#18855](https://github.com/google-gemini/gemini-cli/pull/18855)
|
||||
- refactor(cli): simplify UI and remove legacy inline tool confirmation logic by
|
||||
@abhipatel12 in
|
||||
[#18566](https://github.com/google-gemini/gemini-cli/pull/18566)
|
||||
- feat(cli): deprecate --allowed-tools and excludeTools in favor of policy
|
||||
engine by @Abhijit-2592 in
|
||||
[#18508](https://github.com/google-gemini/gemini-cli/pull/18508)
|
||||
- fix(workflows): improve maintainer detection for automated PR actions by
|
||||
@bdmorgan in [#18869](https://github.com/google-gemini/gemini-cli/pull/18869)
|
||||
- refactor(cli): consolidate useToolScheduler and delete legacy implementation
|
||||
by @abhipatel12 in
|
||||
[#18567](https://github.com/google-gemini/gemini-cli/pull/18567)
|
||||
- Update changelog for v0.28.0 and v0.29.0-preview0 by @g-samroberts in
|
||||
[#18819](https://github.com/google-gemini/gemini-cli/pull/18819)
|
||||
- fix(core): ensure sub-agents are registered regardless of tools.allowed by
|
||||
@mattKorwel in
|
||||
[#18870](https://github.com/google-gemini/gemini-cli/pull/18870)
|
||||
- Show notification when there's a conflict with an extensions command by
|
||||
@chrstnb in [#17890](https://github.com/google-gemini/gemini-cli/pull/17890)
|
||||
- fix(cli): dismiss '?' shortcuts help on hotkeys and active states by
|
||||
@LyalinDotCom in
|
||||
[#18583](https://github.com/google-gemini/gemini-cli/pull/18583)
|
||||
- fix(core): prioritize conditional policy rules and harden Plan Mode by
|
||||
@Abhijit-2592 in
|
||||
[#18882](https://github.com/google-gemini/gemini-cli/pull/18882)
|
||||
- feat(core): refine Plan Mode system prompt for agentic execution by
|
||||
@NTaylorMullen in
|
||||
[#18799](https://github.com/google-gemini/gemini-cli/pull/18799)
|
||||
- feat(plan): create metrics for usage of `AskUser` tool by @Adib234 in
|
||||
[#18820](https://github.com/google-gemini/gemini-cli/pull/18820)
|
||||
- feat(cli): support Ctrl-Z suspension by @scidomino in
|
||||
[#18931](https://github.com/google-gemini/gemini-cli/pull/18931)
|
||||
- fix(github-actions): use robot PAT for release creation to trigger release
|
||||
notes by @SandyTao520 in
|
||||
[#18794](https://github.com/google-gemini/gemini-cli/pull/18794)
|
||||
- feat: add strict seatbelt profiles and remove unusable closed profiles by
|
||||
@SandyTao520 in
|
||||
[#18876](https://github.com/google-gemini/gemini-cli/pull/18876)
|
||||
- chore: cleanup unused and add unlisted dependencies in packages/a2a-server by
|
||||
@adamfweidman in
|
||||
[#18916](https://github.com/google-gemini/gemini-cli/pull/18916)
|
||||
- fix(plan): isolate plan files per session by @Adib234 in
|
||||
[#18757](https://github.com/google-gemini/gemini-cli/pull/18757)
|
||||
- fix: character truncation in raw markdown mode by @jackwotherspoon in
|
||||
[#18938](https://github.com/google-gemini/gemini-cli/pull/18938)
|
||||
- feat(cli): prototype clean UI toggle and minimal-mode bleed-through by
|
||||
@LyalinDotCom in
|
||||
[#18683](https://github.com/google-gemini/gemini-cli/pull/18683)
|
||||
- ui(polish) blend background color with theme by @jacob314 in
|
||||
[#18802](https://github.com/google-gemini/gemini-cli/pull/18802)
|
||||
- Add generic searchable list to back settings and extensions by @chrstnb in
|
||||
[#18838](https://github.com/google-gemini/gemini-cli/pull/18838)
|
||||
- feat(ui): align `AskUser` color scheme with UX spec by @jerop in
|
||||
[#18943](https://github.com/google-gemini/gemini-cli/pull/18943)
|
||||
- Hide AskUser tool validation errors from UI (agent self-corrects) by @jerop in
|
||||
[#18954](https://github.com/google-gemini/gemini-cli/pull/18954)
|
||||
- bug(cli) fix flicker due to AppContainer continuous initialization by
|
||||
@jacob314 in [#18958](https://github.com/google-gemini/gemini-cli/pull/18958)
|
||||
- feat(admin): Add admin controls documentation by @skeshive in
|
||||
[#18644](https://github.com/google-gemini/gemini-cli/pull/18644)
|
||||
- feat(cli): disable ctrl-s shortcut outside of alternate buffer mode by
|
||||
@jacob314 in [#18887](https://github.com/google-gemini/gemini-cli/pull/18887)
|
||||
- fix(vim): vim support that feels (more) complete by @ppgranger in
|
||||
[#18755](https://github.com/google-gemini/gemini-cli/pull/18755)
|
||||
- feat(policy): add --policy flag for user defined policies by @allenhutchison
|
||||
in [#18500](https://github.com/google-gemini/gemini-cli/pull/18500)
|
||||
- Update installation guide by @g-samroberts in
|
||||
[#18823](https://github.com/google-gemini/gemini-cli/pull/18823)
|
||||
- refactor(core): centralize tool definitions (Group 1: replace, search, grep)
|
||||
by @aishaneeshah in
|
||||
[#18944](https://github.com/google-gemini/gemini-cli/pull/18944)
|
||||
- refactor(cli): finalize event-driven transition and remove interaction bridge
|
||||
by @abhipatel12 in
|
||||
[#18569](https://github.com/google-gemini/gemini-cli/pull/18569)
|
||||
- Fix drag and drop escaping by @scidomino in
|
||||
[#18965](https://github.com/google-gemini/gemini-cli/pull/18965)
|
||||
- feat(sdk): initial package bootstrap for SDK by @mbleigh in
|
||||
[#18861](https://github.com/google-gemini/gemini-cli/pull/18861)
|
||||
- feat(sdk): implements SessionContext for SDK tool calls by @mbleigh in
|
||||
[#18862](https://github.com/google-gemini/gemini-cli/pull/18862)
|
||||
- fix(plan): make question type required in AskUser tool by @Adib234 in
|
||||
[#18959](https://github.com/google-gemini/gemini-cli/pull/18959)
|
||||
- fix(core): ensure --yolo does not force headless mode by @NTaylorMullen in
|
||||
[#18976](https://github.com/google-gemini/gemini-cli/pull/18976)
|
||||
- refactor(core): adopt `CoreToolCallStatus` enum for type safety by @jerop in
|
||||
[#18998](https://github.com/google-gemini/gemini-cli/pull/18998)
|
||||
- Enable in-CLI extension management commands for team by @chrstnb in
|
||||
[#18957](https://github.com/google-gemini/gemini-cli/pull/18957)
|
||||
- Adjust lint rules to avoid unnecessary warning. by @scidomino in
|
||||
[#18970](https://github.com/google-gemini/gemini-cli/pull/18970)
|
||||
- fix(vscode): resolve unsafe type assertion lint errors by @ehedlund in
|
||||
[#19006](https://github.com/google-gemini/gemini-cli/pull/19006)
|
||||
- Remove unnecessary eslint config file by @scidomino in
|
||||
[#19015](https://github.com/google-gemini/gemini-cli/pull/19015)
|
||||
- fix(core): Prevent loop detection false positives on lists with long shared
|
||||
prefixes by @SandyTao520 in
|
||||
[#18975](https://github.com/google-gemini/gemini-cli/pull/18975)
|
||||
- feat(core): fallback to chat-base when using unrecognized models for chat by
|
||||
@SandyTao520 in
|
||||
[#19016](https://github.com/google-gemini/gemini-cli/pull/19016)
|
||||
- docs: fix inconsistent commandRegex example in policy engine by @NTaylorMullen
|
||||
in [#19027](https://github.com/google-gemini/gemini-cli/pull/19027)
|
||||
- fix(plan): persist the approval mode in UI even when agent is thinking by
|
||||
@Adib234 in [#18955](https://github.com/google-gemini/gemini-cli/pull/18955)
|
||||
- feat(sdk): Implement dynamic system instructions by @mbleigh in
|
||||
[#18863](https://github.com/google-gemini/gemini-cli/pull/18863)
|
||||
- Docs: Refresh docs to organize and standardize reference materials. by
|
||||
@jkcinouye in [#18403](https://github.com/google-gemini/gemini-cli/pull/18403)
|
||||
- fix windows escaping (and broken tests) by @scidomino in
|
||||
[#19011](https://github.com/google-gemini/gemini-cli/pull/19011)
|
||||
- refactor: use `CoreToolCallStatus` in the the history data model by @jerop in
|
||||
[#19033](https://github.com/google-gemini/gemini-cli/pull/19033)
|
||||
- feat(cleanup): enable 30-day session retention by default by @skeshive in
|
||||
[#18854](https://github.com/google-gemini/gemini-cli/pull/18854)
|
||||
- feat(plan): hide plan write and edit operations on plans in Plan Mode by
|
||||
@jerop in [#19012](https://github.com/google-gemini/gemini-cli/pull/19012)
|
||||
- bug(ui) fix flicker refreshing background color by @jacob314 in
|
||||
[#19041](https://github.com/google-gemini/gemini-cli/pull/19041)
|
||||
- chore: fix dep vulnerabilities by @scidomino in
|
||||
[#19036](https://github.com/google-gemini/gemini-cli/pull/19036)
|
||||
- Revamp automated changelog skill by @g-samroberts in
|
||||
[#18974](https://github.com/google-gemini/gemini-cli/pull/18974)
|
||||
- feat(sdk): implement support for custom skills by @mbleigh in
|
||||
[#19031](https://github.com/google-gemini/gemini-cli/pull/19031)
|
||||
- refactor(core): complete centralization of core tool definitions by
|
||||
@aishaneeshah in
|
||||
[#18991](https://github.com/google-gemini/gemini-cli/pull/18991)
|
||||
- feat: add /commands reload to refresh custom TOML commands by @korade-krushna
|
||||
in [#19078](https://github.com/google-gemini/gemini-cli/pull/19078)
|
||||
- fix(cli): wrap terminal capability queries in hidden sequence by @srithreepo
|
||||
in [#19080](https://github.com/google-gemini/gemini-cli/pull/19080)
|
||||
- fix(workflows): fix GitHub App token permissions for maintainer detection by
|
||||
@bdmorgan in [#19139](https://github.com/google-gemini/gemini-cli/pull/19139)
|
||||
- test: fix hook integration test flakiness on Windows CI by @NTaylorMullen in
|
||||
[#18665](https://github.com/google-gemini/gemini-cli/pull/18665)
|
||||
- fix(core): Encourage non-interactive flags for scaffolding commands by
|
||||
@NTaylorMullen in
|
||||
[#18804](https://github.com/google-gemini/gemini-cli/pull/18804)
|
||||
- fix(core): propagate User-Agent header to setup-phase CodeAssist API calls by
|
||||
@gsquared94 in
|
||||
[#19182](https://github.com/google-gemini/gemini-cli/pull/19182)
|
||||
- docs: document .agents/skills alias and discovery precedence by @kevmoo in
|
||||
[#19166](https://github.com/google-gemini/gemini-cli/pull/19166)
|
||||
- feat(cli): add loading state to new agents notification by @sehoon38 in
|
||||
[#19190](https://github.com/google-gemini/gemini-cli/pull/19190)
|
||||
- Add base branch to workflow. by @g-samroberts in
|
||||
[#19189](https://github.com/google-gemini/gemini-cli/pull/19189)
|
||||
- feat(cli): handle invalid model names in useQuotaAndFallback by @sehoon38 in
|
||||
[#19222](https://github.com/google-gemini/gemini-cli/pull/19222)
|
||||
- docs: custom themes in extensions by @jackwotherspoon in
|
||||
[#19219](https://github.com/google-gemini/gemini-cli/pull/19219)
|
||||
- Disable workspace settings when starting GCLI in the home directory. by
|
||||
@kevinjwang1 in
|
||||
[#19034](https://github.com/google-gemini/gemini-cli/pull/19034)
|
||||
- feat(cli): refactor model command to support set and manage subcommands by
|
||||
@sehoon38 in [#19221](https://github.com/google-gemini/gemini-cli/pull/19221)
|
||||
- Add refresh/reload aliases to slash command subcommands by @korade-krushna in
|
||||
[#19218](https://github.com/google-gemini/gemini-cli/pull/19218)
|
||||
- refactor: consolidate development rules and add cli guidelines by @jacob314 in
|
||||
[#19214](https://github.com/google-gemini/gemini-cli/pull/19214)
|
||||
- chore(ui): remove outdated tip about model routing by @sehoon38 in
|
||||
[#19226](https://github.com/google-gemini/gemini-cli/pull/19226)
|
||||
- feat(core): support custom reasoning models by default by @NTaylorMullen in
|
||||
[#19227](https://github.com/google-gemini/gemini-cli/pull/19227)
|
||||
- Add Solarized Dark and Solarized Light themes by @rmedranollamas in
|
||||
[#19064](https://github.com/google-gemini/gemini-cli/pull/19064)
|
||||
- fix(telemetry): replace JSON.stringify with safeJsonStringify in file
|
||||
exporters by @gsquared94 in
|
||||
[#19244](https://github.com/google-gemini/gemini-cli/pull/19244)
|
||||
- feat(telemetry): add keychain availability and token storage metrics by
|
||||
@abhipatel12 in
|
||||
[#18971](https://github.com/google-gemini/gemini-cli/pull/18971)
|
||||
- feat(cli): update approval mode cycle order by @jerop in
|
||||
[#19254](https://github.com/google-gemini/gemini-cli/pull/19254)
|
||||
- refactor(cli): code review cleanup fix for tab+tab by @jacob314 in
|
||||
[#18967](https://github.com/google-gemini/gemini-cli/pull/18967)
|
||||
- feat(plan): support project exploration without planning when in plan mode by
|
||||
@Adib234 in [#18992](https://github.com/google-gemini/gemini-cli/pull/18992)
|
||||
- feat: add role-specific statistics to telemetry and UI (cont. #15234) by
|
||||
@yunaseoul in [#18824](https://github.com/google-gemini/gemini-cli/pull/18824)
|
||||
- feat(cli): remove Plan Mode from rotation when actively working by @jerop in
|
||||
[#19262](https://github.com/google-gemini/gemini-cli/pull/19262)
|
||||
- Fix side breakage where anchors don't work in slugs. by @g-samroberts in
|
||||
[#19261](https://github.com/google-gemini/gemini-cli/pull/19261)
|
||||
- feat(config): add setting to make directory tree context configurable by
|
||||
@kevin-ramdass in
|
||||
[#19053](https://github.com/google-gemini/gemini-cli/pull/19053)
|
||||
- fix(acp): Wait for mcp initialization in acp (#18893) by @Mervap in
|
||||
[#18894](https://github.com/google-gemini/gemini-cli/pull/18894)
|
||||
- docs: format UTC times in releases doc by @pavan-sh in
|
||||
[#18169](https://github.com/google-gemini/gemini-cli/pull/18169)
|
||||
- Docs: Clarify extensions documentation. by @jkcinouye in
|
||||
[#19277](https://github.com/google-gemini/gemini-cli/pull/19277)
|
||||
- refactor(core): modularize tool definitions by model family by @aishaneeshah
|
||||
in [#19269](https://github.com/google-gemini/gemini-cli/pull/19269)
|
||||
- fix(paths): Add cross-platform path normalization by @spencer426 in
|
||||
[#18939](https://github.com/google-gemini/gemini-cli/pull/18939)
|
||||
- feat(core): experimental in-progress steering hints (1 of 3) by @joshualitt in
|
||||
[#19008](https://github.com/google-gemini/gemini-cli/pull/19008)
|
||||
|
||||
**Full changelog**:
|
||||
https://github.com/google-gemini/gemini-cli/compare/v0.28.0-preview.0...v0.29.0-preview.0
|
||||
https://github.com/google-gemini/gemini-cli/compare/v0.29.0-preview.5...v0.30.0-preview.3
|
||||
|
||||
+23
-23
@@ -26,29 +26,29 @@ and parameters.
|
||||
|
||||
## 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. **Deprecated:** Use positional arguments instead. |
|
||||
| `--prompt-interactive` | `-i` | string | - | Execute prompt and continue in interactive mode |
|
||||
| `--sandbox` | `-s` | boolean | `false` | Run in a sandboxed environment for safer execution |
|
||||
| `--approval-mode` | - | string | `default` | Approval mode for tool execution. Choices: `default`, `auto_edit`, `yolo` |
|
||||
| `--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](../core/policy-engine.md) 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 (e.g. `--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` |
|
||||
| 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. **Deprecated:** Use positional arguments instead. |
|
||||
| `--prompt-interactive` | `-i` | string | - | Execute prompt and continue in interactive mode |
|
||||
| `--sandbox` | `-s` | boolean | `false` | Run in a sandboxed environment for safer execution |
|
||||
| `--approval-mode` | - | string | `default` | Approval mode for tool execution. Choices: `default`, `auto_edit`, `yolo` |
|
||||
| `--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](../reference/policy-engine.md) 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 (e.g. `--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
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ 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](../get-started/configuration.md).
|
||||
the [Configuration documentation](../reference/configuration.md).
|
||||
|
||||
Settings are merged from four files. The precedence order for single-value
|
||||
settings (like `theme`) is:
|
||||
@@ -224,8 +224,8 @@ gemini
|
||||
|
||||
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](../core/policy-engine.md). For a list of available tools, see
|
||||
the [Tools documentation](../tools/index.md).
|
||||
[Policy Engine](../reference/policy-engine.md). For a list of available tools,
|
||||
see the [Tools documentation](../tools/index.md).
|
||||
|
||||
### Allowlisting with `coreTools`
|
||||
|
||||
@@ -245,8 +245,8 @@ on the approved list.
|
||||
|
||||
### Blocklisting with `excludeTools` (Deprecated)
|
||||
|
||||
> **Deprecated:** Use the [Policy Engine](../core/policy-engine.md) for more
|
||||
> robust control.
|
||||
> **Deprecated:** Use the [Policy Engine](../reference/policy-engine.md) for
|
||||
> more robust control.
|
||||
|
||||
Alternatively, you can add specific tools that are considered dangerous in your
|
||||
environment to a blocklist.
|
||||
@@ -289,8 +289,8 @@ unintended tool execution.
|
||||
## Managing custom tools (MCP servers)
|
||||
|
||||
If your organization uses custom tools via
|
||||
[Model-Context Protocol (MCP) servers](../core/tools-api.md), it is crucial to
|
||||
understand how server configurations are managed to apply security policies
|
||||
[Model-Context Protocol (MCP) servers](../reference/tools-api.md), it is crucial
|
||||
to understand how server configurations are managed to apply security policies
|
||||
effectively.
|
||||
|
||||
### How MCP server configurations are merged
|
||||
|
||||
@@ -88,7 +88,7 @@ More content here.
|
||||
@../shared/style-guide.md
|
||||
```
|
||||
|
||||
For more details, see the [Memory Import Processor](../core/memport.md)
|
||||
For more details, see the [Memory Import Processor](../reference/memport.md)
|
||||
documentation.
|
||||
|
||||
## Customize the context file name
|
||||
|
||||
@@ -1,123 +0,0 @@
|
||||
# Using Gemini CLI
|
||||
|
||||
Gemini CLI is a terminal-first interface that brings the power of Gemini AI
|
||||
models directly into your development workflow. It lets you interact with AI
|
||||
using your local files, shell environment, and project context, creating a
|
||||
bridge between generative AI and your system tools.
|
||||
|
||||
## User guides
|
||||
|
||||
These guides provide step-by-step instructions and practical examples for using
|
||||
Gemini CLI in your daily development workflow.
|
||||
|
||||
- **[Quickstart](../get-started/index.md):** Get up and running with Gemini CLI
|
||||
in minutes.
|
||||
- **[Examples](../get-started/examples.md):** See practical examples of Gemini
|
||||
CLI in action.
|
||||
- **[Get started with skills](./tutorials/skills-getting-started.md):** Learn
|
||||
how to use and manage specialized expertise.
|
||||
- **[File management](./tutorials/file-management.md):** How to include, search,
|
||||
and modify local files.
|
||||
- **[Set up an MCP server](./tutorials/mcp-setup.md):** Configure Model Context
|
||||
Protocol servers for custom tools.
|
||||
- **[Manage context and memory](./tutorials/memory-management.md):** Manage
|
||||
persistent instructions and individual facts.
|
||||
- **[Manage sessions and history](./tutorials/session-management.md):** Resume,
|
||||
manage, and rewind your conversations.
|
||||
- **[Execute shell commands](./tutorials/shell-commands.md):** Execute system
|
||||
commands safely directly from your prompt.
|
||||
- **[Plan tasks with todos](./tutorials/task-planning.md):** Using todos for
|
||||
complex, multi-step agent requests.
|
||||
- **[Web search and fetch](./tutorials/web-tools.md):** Searching and fetching
|
||||
content from the web.
|
||||
|
||||
## Features
|
||||
|
||||
Technical reference documentation for each capability of Gemini CLI.
|
||||
|
||||
- **[/about](../cli/commands.md#about):** Show version info.
|
||||
- **[/auth](../cli/commands.md#auth):** Change authentication method.
|
||||
- **[/bug](../cli/commands.md#bug):** File an issue about Gemini CLI.
|
||||
- **[/chat](../cli/commands.md#chat):** Save and resume conversation history.
|
||||
- **[/clear](../cli/commands.md#clear):** Clear the terminal screen.
|
||||
- **[/compress](../cli/commands.md#compress):** Replace context with a summary.
|
||||
- **[/copy](../cli/commands.md#copy):** Copy output to clipboard.
|
||||
- **[/directory](../cli/commands.md#directory-or-dir):** Manage workspace
|
||||
directories.
|
||||
- **[/docs](../cli/commands.md#docs):** Open documentation in browser.
|
||||
- **[/editor](../cli/commands.md#editor):** Select preferred editor.
|
||||
- **[/extensions](../cli/commands.md#extensions):** List active extensions.
|
||||
- **[/help](../cli/commands.md#help-or):** Display help information.
|
||||
- **[/hooks](../hooks/index.md):** Manage hooks for lifecycle events.
|
||||
- **[/ide](../ide-integration/index.md):** Manage IDE integration.
|
||||
- **[/init](../cli/commands.md#init):** Create a GEMINI.md context file.
|
||||
- **[/mcp](../tools/mcp-server.md):** Manage Model Context Protocol servers.
|
||||
- **[/memory](../cli/commands.md#memory):** Manage instructional context.
|
||||
- **[/model](./model.md):** Choose Gemini model.
|
||||
- **[/policies](../cli/commands.md#policies):** Manage security policies.
|
||||
- **[/privacy](../cli/commands.md#privacy):** Display privacy notice.
|
||||
- **[/quit](../cli/commands.md#quit-or-exit):** Exit Gemini CLI.
|
||||
- **[/restore](../cli/commands.md#restore):** Restore file state.
|
||||
- **[/resume](../cli/commands.md#resume):** Browse and resume sessions.
|
||||
- **[/rewind](./rewind.md):** Navigate backward through history.
|
||||
- **[/settings](./settings.md):** Open settings editor.
|
||||
- **[/setup-github](../cli/commands.md#setup-github):** Set up GitHub Actions.
|
||||
- **[/shells](../cli/commands.md#shells-or-bashes):** Toggle background shells
|
||||
view.
|
||||
- **[/skills](./skills.md):** Manage Agent Skills.
|
||||
- **[/stats](../cli/commands.md#stats):** Display session statistics.
|
||||
- **[/terminal-setup](../cli/commands.md#terminal-setup):** Configure
|
||||
keybindings.
|
||||
- **[/theme](./themes.md):** Change visual theme.
|
||||
- **[/tools](../cli/commands.md#tools):** Display list of available tools.
|
||||
- **[/vim](../cli/commands.md#vim):** Toggle vim mode.
|
||||
- **[Activate skill (tool)](../tools/activate-skill.md):** Internal mechanism
|
||||
for loading expert procedures.
|
||||
- **[Ask user (tool)](../tools/ask-user.md):** Internal dialog system for
|
||||
clarification.
|
||||
- **[Checkpointing](./checkpointing.md):** Automatic session snapshots.
|
||||
- **[File system (tool)](../tools/file-system.md):** Technical details for local
|
||||
file operations.
|
||||
- **[Headless mode](./headless.md):** Programmatic and scripting interface.
|
||||
- **[Internal documentation (tool)](../tools/internal-docs.md):** Technical
|
||||
lookup for CLI features.
|
||||
- **[Memory (tool)](../tools/memory.md):** Storage details for persistent facts.
|
||||
- **[Model routing](./model-routing.md):** Automatic fallback resilience.
|
||||
- **[Plan mode (experimental)](./plan-mode.md):** Use a safe, read-only mode for
|
||||
planning complex changes.
|
||||
- **[Sandboxing](./sandbox.md):** Isolate tool execution.
|
||||
- **[Shell (tool)](../tools/shell.md):** Detailed system execution parameters.
|
||||
- **[Telemetry](./telemetry.md):** Usage and performance metric details.
|
||||
- **[Todo (tool)](../tools/todos.md):** Progress tracking specification.
|
||||
- **[Token caching](./token-caching.md):** Performance optimization.
|
||||
- **[Web fetch (tool)](../tools/web-fetch.md):** URL retrieval and extraction
|
||||
details.
|
||||
- **[Web search (tool)](../tools/web-search.md):** Google Search integration
|
||||
technicals.
|
||||
|
||||
## Configuration
|
||||
|
||||
Settings and customization options for Gemini CLI.
|
||||
|
||||
- **[Custom commands](./custom-commands.md):** Personalized shortcuts.
|
||||
- **[Enterprise configuration](./enterprise.md):** Professional environment
|
||||
controls.
|
||||
- **[Ignore files (.geminiignore)](./gemini-ignore.md):** Exclusion pattern
|
||||
reference.
|
||||
- **[Model configuration](./generation-settings.md):** Fine-tune generation
|
||||
parameters like temperature and thinking budget.
|
||||
- **[Project context (GEMINI.md)](./gemini-md.md):** Technical hierarchy of
|
||||
context files.
|
||||
- **[Settings](./settings.md):** Full `settings.json` schema.
|
||||
- **[System prompt override](./system-prompt.md):** Instruction replacement
|
||||
logic.
|
||||
- **[Themes](./themes.md):** UI personalization technical guide.
|
||||
- **[Trusted folders](./trusted-folders.md):** Security permission logic.
|
||||
|
||||
## Next steps
|
||||
|
||||
- Explore the [Command reference](./commands.md) to learn about all available
|
||||
slash commands.
|
||||
- Read about [Project context](./gemini-md.md) to understand how to provide
|
||||
persistent instructions to the model.
|
||||
- See the [CLI reference](./cli-reference.md) for a quick cheatsheet of flags.
|
||||
+1
-1
@@ -39,7 +39,7 @@ To enable Gemini 3 Pro and Gemini 3 Flash (if available), enable
|
||||
|
||||
You can also use the `--model` flag to specify a particular Gemini model on
|
||||
startup. For more details, refer to the
|
||||
[configuration documentation](../get-started/configuration.md).
|
||||
[configuration documentation](../reference/configuration.md).
|
||||
|
||||
Changes to these settings will be applied to all subsequent interactions with
|
||||
Gemini CLI.
|
||||
|
||||
+129
-74
@@ -1,50 +1,61 @@
|
||||
# Plan Mode (experimental)
|
||||
|
||||
Plan Mode is a safe, read-only mode for researching and designing complex
|
||||
changes. It prevents modifications while you research, design and plan an
|
||||
implementation strategy.
|
||||
Plan Mode is a read-only environment for architecting robust solutions before
|
||||
implementation. It allows you to:
|
||||
|
||||
> **Note: Plan Mode is currently an experimental feature.**
|
||||
>
|
||||
> Experimental features are subject to change. To use Plan Mode, enable it via
|
||||
> `/settings` (search for `Plan`) or add the following to your `settings.json`:
|
||||
>
|
||||
> ```json
|
||||
> {
|
||||
> "experimental": {
|
||||
> "plan": true
|
||||
> }
|
||||
> }
|
||||
> ```
|
||||
>
|
||||
> Your feedback is invaluable as we refine this feature. If you have ideas,
|
||||
- **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.
|
||||
|
||||
> **Note:** This is a preview feature currently under active development. Your
|
||||
> feedback is invaluable as we refine this feature. If you have ideas,
|
||||
> suggestions, or encounter issues:
|
||||
>
|
||||
> - Use the `/bug` command within the CLI to file an issue.
|
||||
> - [Open an issue](https://github.com/google-gemini/gemini-cli/issues) on
|
||||
> GitHub.
|
||||
> - Use the **/bug** command within Gemini CLI to file an issue.
|
||||
|
||||
- [Starting in Plan Mode](#starting-in-plan-mode)
|
||||
- [Enabling Plan Mode](#enabling-plan-mode)
|
||||
- [How to use Plan Mode](#how-to-use-plan-mode)
|
||||
- [Entering Plan Mode](#entering-plan-mode)
|
||||
- [The Planning Workflow](#the-planning-workflow)
|
||||
- [Planning Workflow](#planning-workflow)
|
||||
- [Exiting Plan Mode](#exiting-plan-mode)
|
||||
- [Tool Restrictions](#tool-restrictions)
|
||||
- [Customizing Planning with Skills](#customizing-planning-with-skills)
|
||||
- [Customizing Policies](#customizing-policies)
|
||||
- [Example: Allow git commands in Plan Mode](#example-allow-git-commands-in-plan-mode)
|
||||
- [Example: Enable research subagents in Plan Mode](#example-enable-research-subagents-in-plan-mode)
|
||||
- [Custom Plan Directory and Policies](#custom-plan-directory-and-policies)
|
||||
|
||||
## Starting in Plan Mode
|
||||
## Enabling Plan Mode
|
||||
|
||||
You can configure Gemini CLI to start directly in Plan Mode by default:
|
||||
To use Plan Mode, enable it via **/settings** (search for **Plan**) or add the
|
||||
following to your `settings.json`:
|
||||
|
||||
1. Type `/settings` in the CLI.
|
||||
2. Search for `Default Approval Mode`.
|
||||
3. Set the value to `Plan`.
|
||||
```json
|
||||
{
|
||||
"experimental": {
|
||||
"plan": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Other ways to start in Plan Mode:
|
||||
## How to use Plan Mode
|
||||
|
||||
- **CLI Flag:** `gemini --approval-mode=plan`
|
||||
- **Manual Settings:** Manually update your `settings.json`:
|
||||
### Entering Plan Mode
|
||||
|
||||
You can configure Gemini CLI to start in Plan Mode by default or enter it
|
||||
manually during a session.
|
||||
|
||||
- **Configuration:** Configure Gemini CLI to start directly in Plan Mode by
|
||||
default:
|
||||
1. Type `/settings` in the CLI.
|
||||
2. Search for **Default Approval Mode**.
|
||||
3. Set the value to **Plan**.
|
||||
|
||||
Alternatively, use the `gemini --approval-mode=plan` CLI flag or manually
|
||||
update:
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -54,42 +65,44 @@ Other ways to start in Plan Mode:
|
||||
}
|
||||
```
|
||||
|
||||
## How to use Plan Mode
|
||||
- **Keyboard Shortcut:** Press `Shift+Tab` to cycle through approval modes
|
||||
(`Default` -> `Auto-Edit` -> `Plan`).
|
||||
|
||||
### Entering Plan Mode
|
||||
> **Note:** Plan Mode is automatically removed from the rotation when Gemini
|
||||
> CLI is actively processing or showing confirmation dialogs.
|
||||
|
||||
You can enter Plan Mode in three ways:
|
||||
- **Command:** Type `/plan` in the input box.
|
||||
|
||||
1. **Keyboard Shortcut:** Press `Shift+Tab` to cycle through approval modes
|
||||
(`Default` -> `Auto-Edit` -> `Plan`).
|
||||
- **Natural Language:** Ask Gemini CLI to "start a plan for...". Gemini CLI then
|
||||
calls the [`enter_plan_mode`] tool to switch modes.
|
||||
> **Note:** This tool is not available when Gemini CLI is in [YOLO mode].
|
||||
|
||||
> **Note:** Plan Mode is automatically removed from the rotation when the
|
||||
> agent is actively processing or showing confirmation dialogs.
|
||||
### Planning Workflow
|
||||
|
||||
2. **Command:** Type `/plan` in the input box.
|
||||
3. **Natural Language:** Ask the agent to "start a plan for...". The agent will
|
||||
then call the [`enter_plan_mode`] tool to switch modes.
|
||||
|
||||
### The Planning Workflow
|
||||
|
||||
1. **Requirements:** The agent clarifies goals using [`ask_user`].
|
||||
2. **Exploration:** The agent uses read-only tools (like [`read_file`]) to map
|
||||
the codebase and validate assumptions.
|
||||
3. **Design:** The agent proposes alternative approaches with a recommended
|
||||
solution for you to choose from.
|
||||
4. **Planning:** A detailed plan is written to a temporary Markdown file.
|
||||
5. **Review:** You review the plan.
|
||||
- **Approve:** Exit Plan Mode and start implementation (switching to
|
||||
Auto-Edit or Default approval mode).
|
||||
1. **Explore & Analyze:** Analyze requirements and use read-only tools to map
|
||||
the codebase and validate assumptions. For complex tasks, identify at least
|
||||
two viable implementation approaches.
|
||||
2. **Consult:** Present a summary of the identified approaches via [`ask_user`]
|
||||
to obtain a selection. For simple or canonical tasks, this step may be
|
||||
skipped.
|
||||
3. **Draft:** Once an approach is selected, write a detailed implementation
|
||||
plan to the plans directory.
|
||||
4. **Review & Approval:** Use the [`exit_plan_mode`] tool to present the plan
|
||||
and formally request approval.
|
||||
- **Approve:** Exit Plan Mode and start implementation.
|
||||
- **Iterate:** Provide feedback to refine the plan.
|
||||
|
||||
For more complex or specialized planning tasks, you can
|
||||
[customize the planning workflow with skills](#customizing-planning-with-skills).
|
||||
|
||||
### Exiting Plan Mode
|
||||
|
||||
To exit Plan Mode:
|
||||
To exit Plan Mode, you can:
|
||||
|
||||
1. **Keyboard Shortcut:** Press `Shift+Tab` to cycle to the desired mode.
|
||||
2. **Tool:** The agent calls the [`exit_plan_mode`] tool to present the
|
||||
finalized plan for your approval.
|
||||
- **Keyboard Shortcut:** Press `Shift+Tab` to cycle to the desired mode.
|
||||
|
||||
- **Tool:** Gemini CLI calls the [`exit_plan_mode`] tool to present the
|
||||
finalized plan for your approval.
|
||||
|
||||
## Tool Restrictions
|
||||
|
||||
@@ -102,30 +115,31 @@ These are the only allowed tools:
|
||||
- **Interaction:** [`ask_user`]
|
||||
- **MCP Tools (Read):** Read-only [MCP tools] (e.g., `github_read_issue`,
|
||||
`postgres_read_schema`) are allowed.
|
||||
- **Planning (Write):** [`write_file`] and [`replace`] ONLY allowed for `.md`
|
||||
files in the `~/.gemini/tmp/<project>/<session-id>/plans/` directory.
|
||||
- **Planning (Write):** [`write_file`] and [`replace`] only allowed for `.md`
|
||||
files in the `~/.gemini/tmp/<project>/<session-id>/plans/` directory or your
|
||||
[custom plans directory](#custom-plan-directory-and-policies).
|
||||
- **Skills:** [`activate_skill`] (allows loading specialized instructions and
|
||||
resources in a read-only manner)
|
||||
|
||||
### Customizing Planning with Skills
|
||||
|
||||
You can leverage [Agent Skills](./skills.md) 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 and design phases.
|
||||
You can use [Agent Skills](./skills.md) 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 the agent to look for specific
|
||||
- A **"Security Audit"** skill could prompt Gemini CLI to look for specific
|
||||
vulnerabilities during codebase exploration.
|
||||
- A **"Frontend Design"** skill could guide the agent to use specific UI
|
||||
- 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 the agent to "use the
|
||||
[skill-name] skill to plan..." or the agent may autonomously activate it based
|
||||
on the task description.
|
||||
To use a skill in Plan Mode, you can explicitly ask Gemini CLI to "use the
|
||||
`<skill-name>` skill to plan..." or Gemini CLI may autonomously activate it
|
||||
based on the task description.
|
||||
|
||||
### Customizing Policies
|
||||
|
||||
@@ -137,7 +151,7 @@ Because user policies (Tier 2) have a higher base priority than built-in
|
||||
policies (Tier 1), you can override Plan Mode's default restrictions by creating
|
||||
a rule in your `~/.gemini/policies/` directory.
|
||||
|
||||
#### Example: Allow `git status` and `git diff` in Plan Mode
|
||||
#### Example: Allow git commands in Plan Mode
|
||||
|
||||
This rule allows you to check the repository status and see changes while in
|
||||
Plan Mode.
|
||||
@@ -153,10 +167,10 @@ priority = 100
|
||||
modes = ["plan"]
|
||||
```
|
||||
|
||||
#### Example: Enable research sub-agents in Plan Mode
|
||||
#### Example: Enable research subagents in Plan Mode
|
||||
|
||||
You can enable [experimental research sub-agents] like `codebase_investigator`
|
||||
to help gather architecture details during the planning phase.
|
||||
You can enable experimental research [subagents] like `codebase_investigator` to
|
||||
help gather architecture details during the planning phase.
|
||||
|
||||
`~/.gemini/policies/research-subagents.toml`
|
||||
|
||||
@@ -168,11 +182,51 @@ priority = 100
|
||||
modes = ["plan"]
|
||||
```
|
||||
|
||||
Tell the agent it can use these tools in your prompt, for example: _"You can
|
||||
Tell Gemini CLI it can use these tools in your prompt, for example: _"You can
|
||||
check ongoing changes in git."_
|
||||
|
||||
For more information on how the policy engine works, see the [Policy Engine
|
||||
Guide].
|
||||
For more information on how the policy engine works, see the [policy engine]
|
||||
docs.
|
||||
|
||||
### Custom Plan Directory and Policies
|
||||
|
||||
By default, planning artifacts are stored in a managed temporary directory
|
||||
outside your project: `~/.gemini/tmp/<project>/<session-id>/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] 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\""
|
||||
```
|
||||
|
||||
[`list_directory`]: /docs/tools/file-system.md#1-list_directory-readfolder
|
||||
[`read_file`]: /docs/tools/file-system.md#2-read_file-readfile
|
||||
@@ -183,8 +237,9 @@ Guide].
|
||||
[`replace`]: /docs/tools/file-system.md#6-replace-edit
|
||||
[MCP tools]: /docs/tools/mcp-server.md
|
||||
[`activate_skill`]: /docs/cli/skills.md
|
||||
[experimental research sub-agents]: /docs/core/subagents.md
|
||||
[Policy Engine Guide]: /docs/core/policy-engine.md
|
||||
[subagents]: /docs/core/subagents.md
|
||||
[policy engine]: /docs/reference/policy-engine.md
|
||||
[`enter_plan_mode`]: /docs/tools/planning.md#1-enter_plan_mode-enterplanmode
|
||||
[`exit_plan_mode`]: /docs/tools/planning.md#2-exit_plan_mode-exitplanmode
|
||||
[`ask_user`]: /docs/tools/ask-user.md
|
||||
[YOLO mode]: /docs/reference/configuration.md#command-line-arguments
|
||||
|
||||
+3
-3
@@ -167,6 +167,6 @@ gemini -s -p "run shell command: mount | grep workspace"
|
||||
|
||||
## Related documentation
|
||||
|
||||
- [Configuration](../get-started/configuration.md): Full configuration options.
|
||||
- [Commands](./commands.md): Available commands.
|
||||
- [Troubleshooting](../troubleshooting.md): General troubleshooting.
|
||||
- [Configuration](../reference/configuration.md): Full configuration options.
|
||||
- [Commands](../reference/commands.md): Available commands.
|
||||
- [Troubleshooting](../resources/troubleshooting.md): General troubleshooting.
|
||||
|
||||
+47
-43
@@ -22,15 +22,16 @@ 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' is not supported yet. | `"default"` |
|
||||
| Enable Auto Update | `general.enableAutoUpdate` | Enable automatic updates. | `true` |
|
||||
| Enable Prompt Completion | `general.enablePromptCompletion` | Enable AI-powered prompt completion suggestions while typing. | `false` |
|
||||
| Debug Keystroke Logging | `general.debugKeystrokeLogging` | Enable debug logging of keystrokes to the console. | `false` |
|
||||
| Enable Session Cleanup | `general.sessionRetention.enabled` | Enable automatic session cleanup | `false` |
|
||||
| Keep chat history | `general.sessionRetention.maxAge` | Automatically delete chats older than this time period (e.g., "30d", "7d", "24h", "1w") | `undefined` |
|
||||
| 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' is not supported yet. | `"default"` |
|
||||
| Enable Auto Update | `general.enableAutoUpdate` | Enable automatic updates. | `true` |
|
||||
| Enable Notifications | `general.enableNotifications` | Enable run-event notifications for action-required prompts and session completion. Currently macOS only. | `false` |
|
||||
| Plan Directory | `general.plan.directory` | The directory where planning artifacts are stored. If not specified, defaults to the system temporary directory. | `undefined` |
|
||||
| Debug Keystroke Logging | `general.debugKeystrokeLogging` | Enable debug logging of keystrokes to the console. | `false` |
|
||||
| Enable Session Cleanup | `general.sessionRetention.enabled` | Enable automatic session cleanup | `false` |
|
||||
| Keep chat history | `general.sessionRetention.maxAge` | Automatically delete chats older than this time period (e.g., "30d", "7d", "24h", "1w") | `undefined` |
|
||||
|
||||
### Output
|
||||
|
||||
@@ -40,35 +41,36 @@ they appear in the UI.
|
||||
|
||||
### 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` |
|
||||
| Hide Tips | `ui.hideTips` | Hide helpful tips in the UI | `false` |
|
||||
| Show Shortcuts Hint | `ui.showShortcutsHint` | Show the "? for shortcuts" hint above the input. | `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 path 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 remaining 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 logged-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` |
|
||||
| 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` |
|
||||
| Enable Loading Phrases | `ui.accessibility.enableLoadingPhrases` | Enable loading phrases during operations. | `true` |
|
||||
| Screen Reader Mode | `ui.accessibility.screenReader` | Render output in plain-text to be more screen reader accessible | `false` |
|
||||
| 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` |
|
||||
| Show Shortcuts Hint | `ui.showShortcutsHint` | Show the "? for shortcuts" hint above the input. | `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 path 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 remaining 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 logged-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` |
|
||||
| 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, both, or nothing. | `"tips"` |
|
||||
| Screen Reader Mode | `ui.accessibility.screenReader` | Render output in plain-text to be more screen reader accessible | `false` |
|
||||
|
||||
### IDE
|
||||
|
||||
@@ -126,11 +128,13 @@ they appear in the UI.
|
||||
|
||||
### Experimental
|
||||
|
||||
| UI Label | Setting | Description | Default |
|
||||
| -------------------------- | ---------------------------------------- | ----------------------------------------------------------------------------------- | ------- |
|
||||
| Enable Tool Output Masking | `experimental.toolOutputMasking.enabled` | Enables tool output masking to save tokens. | `true` |
|
||||
| Use OSC 52 Paste | `experimental.useOSC52Paste` | Use OSC 52 sequence for pasting instead of clipboardy (useful for remote sessions). | `false` |
|
||||
| Plan | `experimental.plan` | Enable planning features (Plan Mode and tools). | `false` |
|
||||
| UI Label | Setting | Description | Default |
|
||||
| -------------------------- | ---------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
|
||||
| Enable Tool Output Masking | `experimental.toolOutputMasking.enabled` | Enables tool output masking to save tokens. | `true` |
|
||||
| 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` |
|
||||
| Plan | `experimental.plan` | Enable planning features (Plan Mode and tools). | `false` |
|
||||
| Model Steering | `experimental.modelSteering` | Enable model steering (user hints) to guide the model during tool execution. | `false` |
|
||||
|
||||
### Skills
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ Environment variables can be used to override the settings in the file.
|
||||
`true` or `1` will enable the feature. Any other value will disable it.
|
||||
|
||||
For detailed information about all configuration options, see the
|
||||
[Configuration guide](../get-started/configuration.md).
|
||||
[Configuration guide](../reference/configuration.md).
|
||||
|
||||
## Google Cloud telemetry
|
||||
|
||||
|
||||
+3
-3
@@ -41,8 +41,8 @@ can change the theme using the `/theme` command.
|
||||
### Theme persistence
|
||||
|
||||
Selected themes are saved in Gemini CLI's
|
||||
[configuration](../get-started/configuration.md) so your preference is
|
||||
remembered across sessions.
|
||||
[configuration](../reference/configuration.md) so your preference is remembered
|
||||
across sessions.
|
||||
|
||||
---
|
||||
|
||||
@@ -194,7 +194,7 @@ untrusted sources.
|
||||
- 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](../get-started/configuration.md) as other
|
||||
same [configuration precedence](../reference/configuration.md) as other
|
||||
settings.
|
||||
|
||||
### Themes from extensions
|
||||
|
||||
@@ -38,6 +38,37 @@ folder, a dialog will automatically appear, prompting you to make a choice:
|
||||
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, the 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
|
||||
(e.g., 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**, the Gemini CLI runs in a restricted "safe mode"
|
||||
|
||||
@@ -121,6 +121,6 @@ immediately. Force a reload with:
|
||||
|
||||
- Learn about [Session management](session-management.md) to see how short-term
|
||||
history works.
|
||||
- Explore the [Command reference](../../cli/commands.md) for more `/memory`
|
||||
options.
|
||||
- Explore the [Command reference](../../reference/commands.md) for more
|
||||
`/memory` options.
|
||||
- Read the technical spec for [Project context](../../cli/gemini-md.md).
|
||||
|
||||
@@ -101,5 +101,5 @@ This creates a new branch of history without losing your original work.
|
||||
- Learn about [Checkpointing](../../cli/checkpointing.md) to understand the
|
||||
underlying safety mechanism.
|
||||
- Explore [Task planning](task-planning.md) to keep complex sessions organized.
|
||||
- See the [Command reference](../../cli/commands.md) for all `/chat` and
|
||||
- See the [Command reference](../../reference/commands.md) for all `/chat` and
|
||||
`/resume` options.
|
||||
|
||||
@@ -1,137 +0,0 @@
|
||||
# Core concepts
|
||||
|
||||
This guide explains the fundamental concepts and terminology used throughout the
|
||||
Gemini CLI ecosystem. Understanding these terms will help you make the most of
|
||||
the tool's capabilities.
|
||||
|
||||
## Approval mode
|
||||
|
||||
**Approval mode** determines the level of autonomy you grant to the agent when
|
||||
executing tools.
|
||||
|
||||
- **Default:** The agent asks for confirmation before performing any potentially
|
||||
impactful action (like writing files or running shell commands).
|
||||
- **Auto-edit:** File modifications are applied automatically, but shell
|
||||
commands still require confirmation.
|
||||
- **YOLO (You Only Look Once):** The agent runs all tools without asking for
|
||||
permission. High risk, high speed.
|
||||
|
||||
## Checkpointing
|
||||
|
||||
**Checkpointing** is a safety feature that automatically snapshots your
|
||||
project's file state before the agent performs any destructive action (like
|
||||
writing a file).
|
||||
|
||||
- **Snapshots:** Stored in a hidden Git repository (separate from your project's
|
||||
Git history).
|
||||
- **Restore:** Allows you to instantly revert changes if the agent makes a
|
||||
mistake, using the `/restore` command.
|
||||
|
||||
## Context
|
||||
|
||||
**Context** refers to the information the agent has about your current task and
|
||||
environment. Gemini CLI provides context through several mechanisms:
|
||||
|
||||
- **Conversation history:** The chat log of the current session.
|
||||
- **Project context (`GEMINI.md`):** Persistent instructions and rules defined
|
||||
in your project's root or subdirectories.
|
||||
- **File content:** Files you explicitly reference (e.g., `@src/app.ts`) or that
|
||||
the agent reads using tools.
|
||||
- **Environment:** Information about your operating system, shell, and working
|
||||
directory.
|
||||
|
||||
Effective context management is key to getting accurate and relevant responses.
|
||||
|
||||
## Extension
|
||||
|
||||
An **Extension** is a pluggable package that adds new capabilities to Gemini
|
||||
CLI. Extensions can bundle:
|
||||
|
||||
- **Skills:** Specialized procedural knowledge.
|
||||
- **MCP Servers:** Connections to external tools and data.
|
||||
- **Commands:** Custom slash commands.
|
||||
|
||||
## Headless mode
|
||||
|
||||
**Headless mode** refers to running Gemini CLI without the interactive terminal
|
||||
UI (TUI). This is used for scripting, automation, and piping data into or out of
|
||||
the agent.
|
||||
|
||||
- **Interactive:** `gemini` (starts the REPL).
|
||||
- **Headless:** `gemini "Fix this file"` (runs once and exits).
|
||||
|
||||
## Hook
|
||||
|
||||
A **Hook** is a script or function that intercepts specific lifecycle events in
|
||||
the CLI.
|
||||
|
||||
- **Use cases:** Logging tool usage, validating user input, or modifying the
|
||||
agent's system prompt dynamically.
|
||||
- **Lifecycle:** Hooks can run before or after the agent starts, before tools
|
||||
are executed, or after the session ends.
|
||||
|
||||
## Model Context Protocol (MCP)
|
||||
|
||||
The **Model Context Protocol (MCP)** is an open standard that allows Gemini CLI
|
||||
to connect to external data sources and tools.
|
||||
|
||||
- **MCP Server:** A lightweight application that exposes resources (data) and
|
||||
tools (functions) to the CLI.
|
||||
- **Use case:** Connecting Gemini to a PostgreSQL database, a GitHub repository,
|
||||
or a Slack workspace without building custom integration logic into the CLI
|
||||
core.
|
||||
|
||||
## Policy engine
|
||||
|
||||
The **Policy Engine** is the security subsystem that enforces rules on tool
|
||||
execution. It evaluates every tool call against your configuration (e.g.,
|
||||
[Trusted folders](#trusted-folders), allowed commands) to decide whether to:
|
||||
|
||||
- Allow the action immediately.
|
||||
- Require user confirmation.
|
||||
- Block the action entirely.
|
||||
|
||||
## Sandboxing
|
||||
|
||||
**Sandboxing** is an optional security mode that isolates the agent's execution
|
||||
environment. When enabled, the agent runs inside a secure container (e.g.,
|
||||
Docker), preventing it from accessing sensitive files or system resources
|
||||
outside of the designated workspace.
|
||||
|
||||
## Session
|
||||
|
||||
A **Session** is a single continuous interaction thread with the agent.
|
||||
|
||||
- **State:** Sessions maintain conversation history and short-term memory.
|
||||
- **Persistence:** Sessions are automatically saved, allowing you to pause,
|
||||
resume, or rewind them later.
|
||||
|
||||
## Skill
|
||||
|
||||
A **Skill** (or **Agent Skill**) is a package of specialized expertise that the
|
||||
agent can load on demand. Unlike general context, a skill provides specific
|
||||
procedural knowledge for a distinct task.
|
||||
|
||||
- **Example:** A "Code Reviewer" skill might contain a checklist of security
|
||||
vulnerabilities to look for and a specific format for reporting findings.
|
||||
- **Activation:** Skills are typically activated dynamically when the agent
|
||||
recognizes a matching request.
|
||||
|
||||
## Tool
|
||||
|
||||
A **Tool** is a specific function or capability that the agent can execute.
|
||||
Tools allow the AI to interact with the outside world.
|
||||
|
||||
- **Built-in tools:** Core capabilities like `read_file`, `run_shell_command`,
|
||||
and `google_web_search`.
|
||||
- **MCP tools:** External tools provided by
|
||||
[MCP servers](#model-context-protocol-mcp).
|
||||
|
||||
When the agent uses a tool, it pauses generation, executes the code, and feeds
|
||||
the output back into its context window.
|
||||
|
||||
## Trusted folders
|
||||
|
||||
**Trusted folders** are specific directories you have explicitly authorized the
|
||||
agent to access without repeated confirmation prompts. This is a key component
|
||||
of the [Policy engine](#policy-engine) to balance security and usability.
|
||||
+7
-7
@@ -9,11 +9,11 @@ requests sent from `packages/cli`. For a general overview of Gemini CLI, see the
|
||||
|
||||
- **[Sub-agents (experimental)](./subagents.md):** Learn how to create and use
|
||||
specialized sub-agents for complex tasks.
|
||||
- **[Core tools API](./tools-api.md):** Information on how tools are defined,
|
||||
registered, and used by the core.
|
||||
- **[Memory Import Processor](./memport.md):** Documentation for the modular
|
||||
GEMINI.md import feature using @file.md syntax.
|
||||
- **[Policy Engine](./policy-engine.md):** Use the Policy Engine for
|
||||
- **[Core tools API](../reference/tools-api.md):** Information on how tools are
|
||||
defined, registered, and used by the core.
|
||||
- **[Memory Import Processor](../reference/memport.md):** Documentation for the
|
||||
modular GEMINI.md import feature using @file.md syntax.
|
||||
- **[Policy Engine](../reference/policy-engine.md):** Use the Policy Engine for
|
||||
fine-grained control over tool execution.
|
||||
|
||||
## Role of the core
|
||||
@@ -92,8 +92,8 @@ This allows you to 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](../cli/commands.md) to `show`, `add`, and
|
||||
`refresh` the content of loaded `GEMINI.md` files.
|
||||
You can use the [`/memory` command](../reference/commands.md) to `show`, `add`,
|
||||
and `refresh` the content of loaded `GEMINI.md` files.
|
||||
|
||||
## Citations
|
||||
|
||||
|
||||
+155
-39
@@ -1,13 +1,13 @@
|
||||
# Sub-agents (experimental)
|
||||
# Subagents (experimental)
|
||||
|
||||
Sub-agents are specialized agents that operate within your main Gemini CLI
|
||||
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.
|
||||
|
||||
> **Note: Sub-agents are currently an experimental feature.**
|
||||
> **Note: Subagents are currently an experimental feature.**
|
||||
>
|
||||
> To use custom sub-agents, you must explicitly enable them in your
|
||||
> To use custom subagents, you must explicitly enable them in your
|
||||
> `settings.json`:
|
||||
>
|
||||
> ```json
|
||||
@@ -16,31 +16,31 @@ the main agent's context or toolset.
|
||||
> }
|
||||
> ```
|
||||
>
|
||||
> **Warning:** Sub-agents currently operate in
|
||||
> ["YOLO mode"](../get-started/configuration.md#command-line-arguments), meaning
|
||||
> **Warning:** Subagents currently operate in
|
||||
> ["YOLO mode"](../reference/configuration.md#command-line-arguments), meaning
|
||||
> they may execute tools without individual user confirmation for each step.
|
||||
> Proceed with caution when defining agents with powerful tools like
|
||||
> `run_shell_command` or `write_file`.
|
||||
|
||||
## What are sub-agents?
|
||||
## What are subagents?
|
||||
|
||||
Sub-agents are "specialists" that the main Gemini agent can hire for a specific
|
||||
Subagents are "specialists" that the main Gemini agent can hire for a specific
|
||||
job.
|
||||
|
||||
- **Focused context:** Each sub-agent has its own system prompt and persona.
|
||||
- **Specialized tools:** Sub-agents can have a restricted or specialized set of
|
||||
- **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 sub-agent happen in a
|
||||
- **Independent context window:** Interactions with a subagent happen in a
|
||||
separate context loop, which saves tokens in your main conversation history.
|
||||
|
||||
Sub-agents 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 sub-agent. Once the
|
||||
sub-agent completes its task, it reports back to the main agent with its
|
||||
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.
|
||||
|
||||
## Built-in sub-agents
|
||||
## Built-in subagents
|
||||
|
||||
Gemini CLI comes with the following built-in sub-agents:
|
||||
Gemini CLI comes with the following built-in subagents:
|
||||
|
||||
### Codebase Investigator
|
||||
|
||||
@@ -75,15 +75,131 @@ Gemini CLI comes with the following built-in sub-agents:
|
||||
### Generalist Agent
|
||||
|
||||
- **Name:** `generalist_agent`
|
||||
- **Purpose:** Route tasks to the appropriate specialized sub-agent.
|
||||
- **Purpose:** Route tasks to the appropriate specialized subagent.
|
||||
- **When to use:** Implicitly used by the main agent for routing. Not directly
|
||||
invoked by the user.
|
||||
- **Configuration:** Enabled by default. No specific configuration options.
|
||||
|
||||
## Creating custom sub-agents
|
||||
### Browser Agent (experimental)
|
||||
|
||||
You can create your own sub-agents to automate specific workflows or enforce
|
||||
specific personas. To use custom sub-agents, you must enable them in your
|
||||
- **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."
|
||||
|
||||
> **Note:** This is a preview feature currently under active development.
|
||||
|
||||
#### Prerequisites
|
||||
|
||||
The browser agent requires:
|
||||
|
||||
- **Chrome** version 144 or later (any recent stable release will work).
|
||||
- **Node.js** with `npx` available (used to launch the
|
||||
[`chrome-devtools-mcp`](https://www.npmjs.com/package/chrome-devtools-mcp)
|
||||
server).
|
||||
|
||||
#### 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. |
|
||||
|
||||
#### Configuration reference
|
||||
|
||||
All browser-specific settings go under `agents.browser` in your `settings.json`.
|
||||
|
||||
| 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 (for example, `"gemini-2.5-computer-use-preview-10-2025"`). |
|
||||
|
||||
#### Security
|
||||
|
||||
The browser agent enforces the following security restrictions:
|
||||
|
||||
- **Blocked URL patterns:** `file://`, `javascript:`, `data:text/html`,
|
||||
`chrome://extensions`, and `chrome://settings/passwords` are always blocked.
|
||||
- **Sensitive action confirmation:** Actions like form filling, file uploads,
|
||||
and form submissions require user confirmation through the standard policy
|
||||
engine.
|
||||
|
||||
#### 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 Google Login.
|
||||
|
||||
## Creating custom subagents
|
||||
|
||||
You can create your own subagents to automate specific workflows or enforce
|
||||
specific personas. To use custom subagents, you must enable them in your
|
||||
`settings.json`:
|
||||
|
||||
```json
|
||||
@@ -138,20 +254,20 @@ 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 sub-agent. |
|
||||
| `kind` | string | No | `local` (default) or `remote`. |
|
||||
| `tools` | array | No | List of tool names this agent can use. If omitted, it may have access to a default set. |
|
||||
| `model` | string | No | Specific model to use (e.g., `gemini-2.5-pro`). Defaults to `inherit` (uses the main session model). |
|
||||
| `temperature` | number | No | Model temperature (0.0 - 2.0). |
|
||||
| `max_turns` | number | No | Maximum number of conversation turns allowed for this agent before it must return. Defaults to `15`. |
|
||||
| `timeout_mins` | number | No | Maximum execution time in minutes. Defaults to `5`. |
|
||||
| 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. If omitted, it may have access to a default set. |
|
||||
| `model` | string | No | Specific model to use (e.g., `gemini-2.5-pro`). Defaults to `inherit` (uses the main session model). |
|
||||
| `temperature` | number | No | Model temperature (0.0 - 2.0). |
|
||||
| `max_turns` | number | No | Maximum number of conversation turns allowed for this agent before it must return. Defaults to `15`. |
|
||||
| `timeout_mins` | number | No | Maximum execution time in minutes. Defaults to `5`. |
|
||||
|
||||
### Optimizing your sub-agent
|
||||
### Optimizing your subagent
|
||||
|
||||
The main agent's system prompt encourages it to use an expert sub-agent when one
|
||||
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:
|
||||
@@ -160,7 +276,7 @@ by updating the description to more clearly indicate:
|
||||
- When it should be used.
|
||||
- Some example scenarios.
|
||||
|
||||
For example, the following sub-agent description should be called fairly
|
||||
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.
|
||||
@@ -170,13 +286,13 @@ consistently for Git operations.
|
||||
> - Searching for regressions with bisect
|
||||
> - Interacting with source control and issues providers such as GitHub.
|
||||
|
||||
If you need to further tune your sub-agent, you can do so by selecting the model
|
||||
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 sub-agent was called with a specific prompt and the given description.
|
||||
that your subagent was called with a specific prompt and the given description.
|
||||
|
||||
## Remote subagents (Agent2Agent) (experimental)
|
||||
|
||||
Gemini CLI can also delegate tasks to remote sub-agents using the Agent-to-Agent
|
||||
Gemini CLI can also delegate tasks to remote subagents using the Agent-to-Agent
|
||||
(A2A) protocol.
|
||||
|
||||
> **Note: Remote subagents are currently an experimental feature.**
|
||||
@@ -184,8 +300,8 @@ Gemini CLI can also delegate tasks to remote sub-agents using the Agent-to-Agent
|
||||
See the [Remote Subagents documentation](/docs/core/remote-agents) for detailed
|
||||
configuration and usage instructions.
|
||||
|
||||
## Extension sub-agents
|
||||
## Extension subagents
|
||||
|
||||
Extensions can bundle and distribute sub-agents. See the
|
||||
[Extensions documentation](../extensions/index.md#sub-agents) for details on how
|
||||
Extensions can bundle and distribute subagents. See the
|
||||
[Extensions documentation](../extensions/index.md#subagents) for details on how
|
||||
to package agents within an extension.
|
||||
|
||||
@@ -130,7 +130,7 @@ The manifest file defines the extension's behavior and configuration.
|
||||
- `description`: A short summary shown in the extension gallery.
|
||||
- <a id="mcp-servers"></a>`mcpServers`: A map of Model Context Protocol (MCP)
|
||||
servers. Extension servers follow the same format as standard
|
||||
[CLI configuration](../get-started/configuration.md).
|
||||
[CLI configuration](../reference/configuration.md).
|
||||
- `contextFileName`: The name of the context file (defaults to `GEMINI.md`). Can
|
||||
also be an array of strings to load multiple context files.
|
||||
- `excludeTools`: An array of tools to block from the model. You can restrict
|
||||
|
||||
@@ -22,8 +22,8 @@ Select the authentication method that matches your situation in the table below:
|
||||
### What is my Google account type?
|
||||
|
||||
- **Individual Google accounts:** Includes all
|
||||
[free tier accounts](../quota-and-pricing/#free-usage) such as Gemini Code
|
||||
Assist for individuals, as well as paid subscriptions for
|
||||
[free tier accounts](../resources/quota-and-pricing.md#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
|
||||
@@ -317,5 +317,5 @@ configure authentication using environment variables:
|
||||
Your authentication method affects your quotas, pricing, Terms of Service, and
|
||||
privacy notices. Review the following pages to learn more:
|
||||
|
||||
- [Gemini CLI: Quotas and Pricing](../quota-and-pricing.md).
|
||||
- [Gemini CLI: Terms of Service and Privacy Notice](../tos-privacy.md).
|
||||
- [Gemini CLI: Quotas and Pricing](../resources/quota-and-pricing.md).
|
||||
- [Gemini CLI: Terms of Service and Privacy Notice](../resources/tos-privacy.md).
|
||||
|
||||
@@ -1,882 +0,0 @@
|
||||
# Gemini CLI configuration
|
||||
|
||||
**Note on deprecated configuration format**
|
||||
|
||||
This document describes the legacy v1 format for the `settings.json` file. This
|
||||
format is now deprecated.
|
||||
|
||||
- The new format will be supported in the stable release starting
|
||||
**[09/10/25]**.
|
||||
- Automatic migration from the old format to the new format will begin on
|
||||
**[09/17/25]**.
|
||||
|
||||
For details on the new, recommended format, please see the
|
||||
[current Configuration documentation](./configuration.md).
|
||||
|
||||
Gemini CLI offers several ways to configure its behavior, including environment
|
||||
variables, command-line arguments, and settings files. This document outlines
|
||||
the different configuration methods and available settings.
|
||||
|
||||
## Configuration layers
|
||||
|
||||
Configuration is applied in the following order of precedence (lower numbers are
|
||||
overridden by higher numbers):
|
||||
|
||||
1. **Default values:** Hardcoded defaults within the application.
|
||||
2. **System defaults file:** System-wide default settings that can be
|
||||
overridden by other settings files.
|
||||
3. **User settings file:** Global settings for the current user.
|
||||
4. **Project settings file:** Project-specific settings.
|
||||
5. **System settings file:** System-wide settings that override all other
|
||||
settings files.
|
||||
6. **Environment variables:** System-wide or session-specific variables,
|
||||
potentially loaded from `.env` files.
|
||||
7. **Command-line arguments:** Values passed when launching the CLI.
|
||||
|
||||
## Settings files
|
||||
|
||||
Gemini CLI uses JSON settings files for persistent configuration. There are four
|
||||
locations for these files:
|
||||
|
||||
- **System defaults file:**
|
||||
- **Location:** `/etc/gemini-cli/system-defaults.json` (Linux),
|
||||
`C:\ProgramData\gemini-cli\system-defaults.json` (Windows) or
|
||||
`/Library/Application Support/GeminiCli/system-defaults.json` (macOS). The
|
||||
path can be overridden using the `GEMINI_CLI_SYSTEM_DEFAULTS_PATH`
|
||||
environment variable.
|
||||
- **Scope:** Provides a base layer of system-wide default settings. These
|
||||
settings have the lowest precedence and are intended to be overridden by
|
||||
user, project, or system override settings.
|
||||
- **User settings file:**
|
||||
- **Location:** `~/.gemini/settings.json` (where `~` is your home directory).
|
||||
- **Scope:** Applies to all Gemini CLI sessions for the current user. User
|
||||
settings override system defaults.
|
||||
- **Project settings file:**
|
||||
- **Location:** `.gemini/settings.json` within your project's root directory.
|
||||
- **Scope:** Applies only when running Gemini CLI from that specific project.
|
||||
Project settings override user settings and system defaults.
|
||||
- **System settings file:**
|
||||
- **Location:** `/etc/gemini-cli/settings.json` (Linux),
|
||||
`C:\ProgramData\gemini-cli\settings.json` (Windows) or
|
||||
`/Library/Application Support/GeminiCli/settings.json` (macOS). The path can
|
||||
be overridden using the `GEMINI_CLI_SYSTEM_SETTINGS_PATH` environment
|
||||
variable.
|
||||
- **Scope:** Applies to all Gemini CLI sessions on the system, for all users.
|
||||
System settings act as overrides, taking precedence over all other settings
|
||||
files. May be useful for system administrators at enterprises to have
|
||||
controls over users' Gemini CLI setups.
|
||||
|
||||
**Note on environment variables in settings:** String values within your
|
||||
`settings.json` files can reference environment variables using either
|
||||
`$VAR_NAME` or `${VAR_NAME}` syntax. These variables will be automatically
|
||||
resolved when the settings are loaded. For example, if you have an environment
|
||||
variable `MY_API_TOKEN`, you could use it in `settings.json` like this:
|
||||
`"apiKey": "$MY_API_TOKEN"`.
|
||||
|
||||
> **Note for Enterprise Users:** For guidance on deploying and managing Gemini
|
||||
> CLI in a corporate environment, please see the
|
||||
> [Enterprise Configuration](../cli/enterprise.md) documentation.
|
||||
|
||||
### The `.gemini` directory in your project
|
||||
|
||||
In addition to a project settings file, a project's `.gemini` directory can
|
||||
contain other project-specific files related to Gemini CLI's operation, such as:
|
||||
|
||||
- [Custom sandbox profiles](#sandboxing) (e.g.,
|
||||
`.gemini/sandbox-macos-custom.sb`, `.gemini/sandbox.Dockerfile`).
|
||||
|
||||
### Available settings in `settings.json`:
|
||||
|
||||
- **`contextFileName`** (string or array of strings):
|
||||
- **Description:** Specifies the filename for context files (e.g.,
|
||||
`GEMINI.md`, `AGENTS.md`). Can be a single filename or a list of accepted
|
||||
filenames.
|
||||
- **Default:** `GEMINI.md`
|
||||
- **Example:** `"contextFileName": "AGENTS.md"`
|
||||
|
||||
- **`bugCommand`** (object):
|
||||
- **Description:** Overrides the default URL for the `/bug` command.
|
||||
- **Default:**
|
||||
`"urlTemplate": "https://github.com/google-gemini/gemini-cli/issues/new?template=bug_report.yml&title={title}&info={info}"`
|
||||
- **Properties:**
|
||||
- **`urlTemplate`** (string): A URL that can contain `{title}` and `{info}`
|
||||
placeholders.
|
||||
- **Example:**
|
||||
```json
|
||||
"bugCommand": {
|
||||
"urlTemplate": "https://bug.example.com/new?title={title}&info={info}"
|
||||
}
|
||||
```
|
||||
|
||||
- **`fileFiltering`** (object):
|
||||
- **Description:** Controls git-aware file filtering behavior for @ commands
|
||||
and file discovery tools.
|
||||
- **Default:** `"respectGitIgnore": true, "enableRecursiveFileSearch": true`
|
||||
- **Properties:**
|
||||
- **`respectGitIgnore`** (boolean): Whether to respect .gitignore patterns
|
||||
when discovering files. When set to `true`, git-ignored files (like
|
||||
`node_modules/`, `dist/`, `.env`) are automatically excluded from @
|
||||
commands and file listing operations.
|
||||
- **`enableRecursiveFileSearch`** (boolean): Whether to enable searching
|
||||
recursively for filenames under the current tree when completing @
|
||||
prefixes in the prompt.
|
||||
- **`disableFuzzySearch`** (boolean): When `true`, disables the fuzzy search
|
||||
capabilities when searching for files, which can improve performance on
|
||||
projects with a large number of files.
|
||||
- **Example:**
|
||||
```json
|
||||
"fileFiltering": {
|
||||
"respectGitIgnore": true,
|
||||
"enableRecursiveFileSearch": false,
|
||||
"disableFuzzySearch": true
|
||||
}
|
||||
```
|
||||
|
||||
### Troubleshooting file search performance
|
||||
|
||||
If you are experiencing performance issues with file searching (e.g., with `@`
|
||||
completions), especially in projects with a very large number of files, here are
|
||||
a few things you can try in order of recommendation:
|
||||
|
||||
1. **Use `.geminiignore`:** Create a `.geminiignore` file in your project root
|
||||
to exclude directories that contain a large number of files that you don't
|
||||
need to reference (e.g., build artifacts, logs, `node_modules`). Reducing
|
||||
the total number of files crawled is the most effective way to improve
|
||||
performance.
|
||||
|
||||
2. **Disable fuzzy search:** If ignoring files is not enough, you can disable
|
||||
fuzzy search by setting `disableFuzzySearch` to `true` in your
|
||||
`settings.json` file. This will use a simpler, non-fuzzy matching algorithm,
|
||||
which can be faster.
|
||||
|
||||
3. **Disable recursive file search:** As a last resort, you can disable
|
||||
recursive file search entirely by setting `enableRecursiveFileSearch` to
|
||||
`false`. This will be the fastest option as it avoids a recursive crawl of
|
||||
your project. However, it means you will need to type the full path to files
|
||||
when using `@` completions.
|
||||
|
||||
- **`coreTools`** (array of strings):
|
||||
- **Description:** Allows you to specify a list of core tool names that should
|
||||
be made available to the model. This can be used to restrict the set of
|
||||
built-in tools. See [Built-in Tools](../core/tools-api.md#built-in-tools)
|
||||
for a list of core tools. You can also specify command-specific restrictions
|
||||
for tools that support it, like the `ShellTool`. For example,
|
||||
`"coreTools": ["ShellTool(ls -l)"]` will only allow the `ls -l` command to
|
||||
be executed.
|
||||
- **Default:** All tools available for use by the Gemini model.
|
||||
- **Example:** `"coreTools": ["ReadFileTool", "GlobTool", "ShellTool(ls)"]`.
|
||||
|
||||
- **`allowedTools`** (array of strings) [DEPRECATED]:
|
||||
- **Default:** `undefined`
|
||||
- **Description:** A list of tool names that will bypass the confirmation
|
||||
dialog. This is useful for tools that you trust and use frequently. The
|
||||
match semantics are the same as `coreTools`. **Deprecated**: Use the
|
||||
[Policy Engine](../core/policy-engine.md) instead.
|
||||
- **Example:** `"allowedTools": ["ShellTool(git status)"]`.
|
||||
|
||||
- **`excludeTools`** (array of strings) [DEPRECATED]:
|
||||
- **Description:** Allows you to specify a list of core tool names that should
|
||||
be excluded from the model. A tool listed in both `excludeTools` and
|
||||
`coreTools` is excluded. You can also specify command-specific restrictions
|
||||
for tools that support it, like the `ShellTool`. For example,
|
||||
`"excludeTools": ["ShellTool(rm -rf)"]` will block the `rm -rf` command.
|
||||
**Deprecated**: Use the [Policy Engine](../core/policy-engine.md) instead.
|
||||
- **Default**: No tools excluded.
|
||||
- **Example:** `"excludeTools": ["run_shell_command", "findFiles"]`.
|
||||
- **Security Note:** Command-specific restrictions in `excludeTools` for
|
||||
`run_shell_command` are based on simple string matching and can be easily
|
||||
bypassed. This feature is **not a security mechanism** and should not be
|
||||
relied upon to safely execute untrusted code. It is recommended to use
|
||||
`coreTools` to explicitly select commands that can be executed.
|
||||
|
||||
- **`allowMCPServers`** (array of strings):
|
||||
- **Description:** Allows you to specify a list of MCP server names that
|
||||
should be made available to the model. This can be used to restrict the set
|
||||
of MCP servers to connect to. Note that this will be ignored if
|
||||
`--allowed-mcp-server-names` is set.
|
||||
- **Default:** All MCP servers are available for use by the Gemini model.
|
||||
- **Example:** `"allowMCPServers": ["myPythonServer"]`.
|
||||
- **Security note:** This uses simple string matching on MCP server names,
|
||||
which can be modified. If you're a system administrator looking to prevent
|
||||
users from bypassing this, consider configuring the `mcpServers` at the
|
||||
system settings level such that the user will not be able to configure any
|
||||
MCP servers of their own. This should not be used as an airtight security
|
||||
mechanism.
|
||||
|
||||
- **`excludeMCPServers`** (array of strings):
|
||||
- **Description:** Allows you to specify a list of MCP server names that
|
||||
should be excluded from the model. A server listed in both
|
||||
`excludeMCPServers` and `allowMCPServers` is excluded. Note that this will
|
||||
be ignored if `--allowed-mcp-server-names` is set.
|
||||
- **Default**: No MCP servers excluded.
|
||||
- **Example:** `"excludeMCPServers": ["myNodeServer"]`.
|
||||
- **Security note:** This uses simple string matching on MCP server names,
|
||||
which can be modified. If you're a system administrator looking to prevent
|
||||
users from bypassing this, consider configuring the `mcpServers` at the
|
||||
system settings level such that the user will not be able to configure any
|
||||
MCP servers of their own. This should not be used as an airtight security
|
||||
mechanism.
|
||||
|
||||
- **`theme`** (string):
|
||||
- **Description:** Sets the visual [theme](../cli/themes.md) for Gemini CLI.
|
||||
- **Default:** `"Default"`
|
||||
- **Example:** `"theme": "GitHub"`
|
||||
|
||||
- **`vimMode`** (boolean):
|
||||
- **Description:** Enables or disables vim mode for input editing. When
|
||||
enabled, the input area supports vim-style navigation and editing commands
|
||||
with NORMAL and INSERT modes. The vim mode status is displayed in the footer
|
||||
and persists between sessions.
|
||||
- **Default:** `false`
|
||||
- **Example:** `"vimMode": true`
|
||||
|
||||
- **`sandbox`** (boolean or string):
|
||||
- **Description:** Controls whether and how to use sandboxing for tool
|
||||
execution. If set to `true`, Gemini CLI uses a pre-built
|
||||
`gemini-cli-sandbox` Docker image. For more information, see
|
||||
[Sandboxing](#sandboxing).
|
||||
- **Default:** `false`
|
||||
- **Example:** `"sandbox": "docker"`
|
||||
|
||||
- **`toolDiscoveryCommand`** (string):
|
||||
- **Description:** Defines a custom shell command for discovering tools from
|
||||
your project. The shell command must return on `stdout` a JSON array of
|
||||
[function declarations](https://ai.google.dev/gemini-api/docs/function-calling#function-declarations).
|
||||
Tool wrappers are optional.
|
||||
- **Default:** Empty
|
||||
- **Example:** `"toolDiscoveryCommand": "bin/get_tools"`
|
||||
|
||||
- **`toolCallCommand`** (string):
|
||||
- **Description:** Defines a custom shell command for calling a specific tool
|
||||
that was discovered using `toolDiscoveryCommand`. The shell command must
|
||||
meet the following criteria:
|
||||
- It must take function `name` (exactly as in
|
||||
[function declaration](https://ai.google.dev/gemini-api/docs/function-calling#function-declarations))
|
||||
as first command line argument.
|
||||
- It must read function arguments as JSON on `stdin`, analogous to
|
||||
[`functionCall.args`](https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/inference#functioncall).
|
||||
- It must return function output as JSON on `stdout`, analogous to
|
||||
[`functionResponse.response.content`](https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/inference#functionresponse).
|
||||
- **Default:** Empty
|
||||
- **Example:** `"toolCallCommand": "bin/call_tool"`
|
||||
|
||||
- **`mcpServers`** (object):
|
||||
- **Description:** Configures connections to one or more Model-Context
|
||||
Protocol (MCP) servers for discovering and using custom tools. Gemini CLI
|
||||
attempts to connect to each configured MCP server to discover available
|
||||
tools. If multiple MCP servers expose a tool with the same name, the tool
|
||||
names will be prefixed with the server alias you defined in the
|
||||
configuration (e.g., `serverAlias__actualToolName`) to avoid conflicts. Note
|
||||
that the system might strip certain schema properties from MCP tool
|
||||
definitions for compatibility. At least one of `command`, `url`, or
|
||||
`httpUrl` must be provided. If multiple are specified, the order of
|
||||
precedence is `httpUrl`, then `url`, then `command`.
|
||||
- **Default:** Empty
|
||||
- **Properties:**
|
||||
- **`<SERVER_NAME>`** (object): The server parameters for the named server.
|
||||
- `command` (string, optional): The command to execute to start the MCP
|
||||
server via standard I/O.
|
||||
- `args` (array of strings, optional): Arguments to pass to the command.
|
||||
- `env` (object, optional): Environment variables to set for the server
|
||||
process.
|
||||
- `cwd` (string, optional): The working directory in which to start the
|
||||
server.
|
||||
- `url` (string, optional): The URL of an MCP server that uses Server-Sent
|
||||
Events (SSE) for communication.
|
||||
- `httpUrl` (string, optional): The URL of an MCP server that uses
|
||||
streamable HTTP for communication.
|
||||
- `headers` (object, optional): A map of HTTP headers to send with
|
||||
requests to `url` or `httpUrl`.
|
||||
- `timeout` (number, optional): Timeout in milliseconds for requests to
|
||||
this MCP server.
|
||||
- `trust` (boolean, optional): Trust this server and bypass all tool call
|
||||
confirmations.
|
||||
- `description` (string, optional): A brief description of the server,
|
||||
which may be used for display purposes.
|
||||
- `includeTools` (array of strings, optional): List of tool names to
|
||||
include from this MCP server. When specified, only the tools listed here
|
||||
will be available from this server (allowlist behavior). If not
|
||||
specified, all tools from the server are enabled by default.
|
||||
- `excludeTools` (array of strings, optional): List of tool names to
|
||||
exclude from this MCP server. Tools listed here will not be available to
|
||||
the model, even if they are exposed by the server. **Note:**
|
||||
`excludeTools` takes precedence over `includeTools` - if a tool is in
|
||||
both lists, it will be excluded.
|
||||
- **Example:**
|
||||
```json
|
||||
"mcpServers": {
|
||||
"myPythonServer": {
|
||||
"command": "python",
|
||||
"args": ["mcp_server.py", "--port", "8080"],
|
||||
"cwd": "./mcp_tools/python",
|
||||
"timeout": 5000,
|
||||
"includeTools": ["safe_tool", "file_reader"],
|
||||
},
|
||||
"myNodeServer": {
|
||||
"command": "node",
|
||||
"args": ["mcp_server.js"],
|
||||
"cwd": "./mcp_tools/node",
|
||||
"excludeTools": ["dangerous_tool", "file_deleter"]
|
||||
},
|
||||
"myDockerServer": {
|
||||
"command": "docker",
|
||||
"args": ["run", "-i", "--rm", "-e", "API_KEY", "ghcr.io/foo/bar"],
|
||||
"env": {
|
||||
"API_KEY": "$MY_API_TOKEN"
|
||||
}
|
||||
},
|
||||
"mySseServer": {
|
||||
"url": "http://localhost:8081/events",
|
||||
"headers": {
|
||||
"Authorization": "Bearer $MY_SSE_TOKEN"
|
||||
},
|
||||
"description": "An example SSE-based MCP server."
|
||||
},
|
||||
"myStreamableHttpServer": {
|
||||
"httpUrl": "http://localhost:8082/stream",
|
||||
"headers": {
|
||||
"X-API-Key": "$MY_HTTP_API_KEY"
|
||||
},
|
||||
"description": "An example Streamable HTTP-based MCP server."
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- **`checkpointing`** (object):
|
||||
- **Description:** Configures the checkpointing feature, which allows you to
|
||||
save and restore conversation and file states. See the
|
||||
[Checkpointing documentation](../cli/checkpointing.md) for more details.
|
||||
- **Default:** `{"enabled": false}`
|
||||
- **Properties:**
|
||||
- **`enabled`** (boolean): When `true`, the `/restore` command is available.
|
||||
|
||||
- **`preferredEditor`** (string):
|
||||
- **Description:** Specifies the preferred editor to use for viewing diffs.
|
||||
- **Default:** `vscode`
|
||||
- **Example:** `"preferredEditor": "vscode"`
|
||||
|
||||
- **`telemetry`** (object)
|
||||
- **Description:** Configures logging and metrics collection for Gemini CLI.
|
||||
For more information, see [Telemetry](../cli/telemetry.md).
|
||||
- **Default:**
|
||||
`{"enabled": false, "target": "local", "otlpEndpoint": "http://localhost:4317", "logPrompts": true}`
|
||||
- **Properties:**
|
||||
- **`enabled`** (boolean): Whether or not telemetry is enabled.
|
||||
- **`target`** (string): The destination for collected telemetry. Supported
|
||||
values are `local` and `gcp`.
|
||||
- **`otlpEndpoint`** (string): The endpoint for the OTLP Exporter.
|
||||
- **`logPrompts`** (boolean): Whether or not to include the content of user
|
||||
prompts in the logs.
|
||||
- **Example:**
|
||||
```json
|
||||
"telemetry": {
|
||||
"enabled": true,
|
||||
"target": "local",
|
||||
"otlpEndpoint": "http://localhost:16686",
|
||||
"logPrompts": false
|
||||
}
|
||||
```
|
||||
- **`usageStatisticsEnabled`** (boolean):
|
||||
- **Description:** Enables or disables the collection of usage statistics. See
|
||||
[Usage Statistics](#usage-statistics) for more information.
|
||||
- **Default:** `true`
|
||||
- **Example:**
|
||||
```json
|
||||
"usageStatisticsEnabled": false
|
||||
```
|
||||
|
||||
- **`hideTips`** (boolean):
|
||||
- **Description:** Enables or disables helpful tips in the CLI interface.
|
||||
- **Default:** `false`
|
||||
- **Example:**
|
||||
|
||||
```json
|
||||
"hideTips": true
|
||||
```
|
||||
|
||||
- **`hideBanner`** (boolean):
|
||||
- **Description:** Enables or disables the startup banner (ASCII art logo) in
|
||||
the CLI interface.
|
||||
- **Default:** `false`
|
||||
- **Example:**
|
||||
|
||||
```json
|
||||
"hideBanner": true
|
||||
```
|
||||
|
||||
- **`maxSessionTurns`** (number):
|
||||
- **Description:** Sets the maximum number of turns for a session. If the
|
||||
session exceeds this limit, the CLI will stop processing and start a new
|
||||
chat.
|
||||
- **Default:** `-1` (unlimited)
|
||||
- **Example:**
|
||||
```json
|
||||
"maxSessionTurns": 10
|
||||
```
|
||||
|
||||
- **`summarizeToolOutput`** (object):
|
||||
- **Description:** Enables or disables the summarization of tool output. You
|
||||
can specify the token budget for the summarization using the `tokenBudget`
|
||||
setting.
|
||||
- Note: Currently only the `run_shell_command` tool is supported.
|
||||
- **Default:** `{}` (Disabled by default)
|
||||
- **Example:**
|
||||
```json
|
||||
"summarizeToolOutput": {
|
||||
"run_shell_command": {
|
||||
"tokenBudget": 2000
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- **`excludedProjectEnvVars`** (array of strings):
|
||||
- **Description:** Specifies environment variables that should be excluded
|
||||
from being loaded from project `.env` files. This prevents project-specific
|
||||
environment variables (like `DEBUG=true`) from interfering with gemini-cli
|
||||
behavior. Variables from `.gemini/.env` files are never excluded.
|
||||
- **Default:** `["DEBUG", "DEBUG_MODE"]`
|
||||
- **Example:**
|
||||
```json
|
||||
"excludedProjectEnvVars": ["DEBUG", "DEBUG_MODE", "NODE_ENV"]
|
||||
```
|
||||
|
||||
- **`includeDirectories`** (array of strings):
|
||||
- **Description:** Specifies an array of additional absolute or relative paths
|
||||
to include in the workspace context. Missing directories will be skipped
|
||||
with a warning by default. Paths can use `~` to refer to the user's home
|
||||
directory. This setting can be combined with the `--include-directories`
|
||||
command-line flag.
|
||||
- **Default:** `[]`
|
||||
- **Example:**
|
||||
```json
|
||||
"includeDirectories": [
|
||||
"/path/to/another/project",
|
||||
"../shared-library",
|
||||
"~/common-utils"
|
||||
]
|
||||
```
|
||||
|
||||
- **`loadMemoryFromIncludeDirectories`** (boolean):
|
||||
- **Description:** Controls the behavior of the `/memory refresh` command. If
|
||||
set to `true`, `GEMINI.md` files should be loaded from all directories that
|
||||
are added. If set to `false`, `GEMINI.md` should only be loaded from the
|
||||
current directory.
|
||||
- **Default:** `false`
|
||||
- **Example:**
|
||||
```json
|
||||
"loadMemoryFromIncludeDirectories": true
|
||||
```
|
||||
|
||||
- **`showLineNumbers`** (boolean):
|
||||
- **Description:** Controls whether line numbers are displayed in code blocks
|
||||
in the CLI output.
|
||||
- **Default:** `true`
|
||||
- **Example:**
|
||||
```json
|
||||
"showLineNumbers": false
|
||||
```
|
||||
|
||||
- **`accessibility`** (object):
|
||||
- **Description:** Configures accessibility features for the CLI.
|
||||
- **Properties:**
|
||||
- **`screenReader`** (boolean): Enables screen reader mode, which adjusts
|
||||
the TUI for better compatibility with screen readers. This can also be
|
||||
enabled with the `--screen-reader` command-line flag, which will take
|
||||
precedence over the setting.
|
||||
- **`disableLoadingPhrases`** (boolean): Disables the display of loading
|
||||
phrases during operations.
|
||||
- **Default:** `{"screenReader": false, "disableLoadingPhrases": false}`
|
||||
- **Example:**
|
||||
```json
|
||||
"accessibility": {
|
||||
"screenReader": true,
|
||||
"disableLoadingPhrases": true
|
||||
}
|
||||
```
|
||||
|
||||
### Example `settings.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"theme": "GitHub",
|
||||
"sandbox": "docker",
|
||||
"toolDiscoveryCommand": "bin/get_tools",
|
||||
"toolCallCommand": "bin/call_tool",
|
||||
"mcpServers": {
|
||||
"mainServer": {
|
||||
"command": "bin/mcp_server.py"
|
||||
},
|
||||
"anotherServer": {
|
||||
"command": "node",
|
||||
"args": ["mcp_server.js", "--verbose"]
|
||||
}
|
||||
},
|
||||
"telemetry": {
|
||||
"enabled": true,
|
||||
"target": "local",
|
||||
"otlpEndpoint": "http://localhost:4317",
|
||||
"logPrompts": true
|
||||
},
|
||||
"usageStatisticsEnabled": true,
|
||||
"hideTips": false,
|
||||
"hideBanner": false,
|
||||
"maxSessionTurns": 10,
|
||||
"summarizeToolOutput": {
|
||||
"run_shell_command": {
|
||||
"tokenBudget": 100
|
||||
}
|
||||
},
|
||||
"excludedProjectEnvVars": ["DEBUG", "DEBUG_MODE", "NODE_ENV"],
|
||||
"includeDirectories": ["path/to/dir1", "~/path/to/dir2", "../path/to/dir3"],
|
||||
"loadMemoryFromIncludeDirectories": true
|
||||
}
|
||||
```
|
||||
|
||||
## Shell history
|
||||
|
||||
The CLI keeps a history of shell commands you run. To avoid conflicts between
|
||||
different projects, this history is stored in a project-specific directory
|
||||
within your user's home folder.
|
||||
|
||||
- **Location:** `~/.gemini/tmp/<project_hash>/shell_history`
|
||||
- `<project_hash>` is a unique identifier generated from your project's root
|
||||
path.
|
||||
- The history is stored in a file named `shell_history`.
|
||||
|
||||
## Environment variables and `.env` files
|
||||
|
||||
Environment variables are a common way to configure applications, especially for
|
||||
sensitive information like API keys or for settings that might change between
|
||||
environments. For authentication setup, see the
|
||||
[Authentication documentation](./authentication.md) which covers all available
|
||||
authentication methods.
|
||||
|
||||
The CLI automatically loads environment variables from an `.env` file. The
|
||||
loading order is:
|
||||
|
||||
1. `.env` file in the current working directory.
|
||||
2. If not found, it searches upwards in parent directories until it finds an
|
||||
`.env` file or reaches the project root (identified by a `.git` folder) or
|
||||
the home directory.
|
||||
3. If still not found, it looks for `~/.env` (in the user's home directory).
|
||||
|
||||
**Environment variable exclusion:** Some environment variables (like `DEBUG` and
|
||||
`DEBUG_MODE`) are automatically excluded from being loaded from project `.env`
|
||||
files to prevent interference with gemini-cli behavior. Variables from
|
||||
`.gemini/.env` files are never excluded. You can customize this behavior using
|
||||
the `excludedProjectEnvVars` setting in your `settings.json` file.
|
||||
|
||||
- **`GEMINI_API_KEY`**:
|
||||
- Your API key for the Gemini API.
|
||||
- One of several available [authentication methods](./authentication.md).
|
||||
- Set this in your shell profile (e.g., `~/.bashrc`, `~/.zshrc`) or an `.env`
|
||||
file.
|
||||
- **`GEMINI_MODEL`**:
|
||||
- Specifies the default Gemini model to use.
|
||||
- Overrides the hardcoded default
|
||||
- Example: `export GEMINI_MODEL="gemini-2.5-flash"`
|
||||
- **`GOOGLE_API_KEY`**:
|
||||
- Your Google Cloud API key.
|
||||
- Required for using Vertex AI in express mode.
|
||||
- Ensure you have the necessary permissions.
|
||||
- Example: `export GOOGLE_API_KEY="YOUR_GOOGLE_API_KEY"`.
|
||||
- **`GOOGLE_CLOUD_PROJECT`**:
|
||||
- Your Google Cloud Project ID.
|
||||
- Required for using Code Assist or Vertex AI.
|
||||
- If using Vertex AI, ensure you have the necessary permissions in this
|
||||
project.
|
||||
- **Cloud Shell note:** When running in a Cloud Shell environment, this
|
||||
variable defaults to a special project allocated for Cloud Shell users. If
|
||||
you have `GOOGLE_CLOUD_PROJECT` set in your global environment in Cloud
|
||||
Shell, it will be overridden by this default. To use a different project in
|
||||
Cloud Shell, you must define `GOOGLE_CLOUD_PROJECT` in a `.env` file.
|
||||
- Example: `export GOOGLE_CLOUD_PROJECT="YOUR_PROJECT_ID"`.
|
||||
- **`GOOGLE_APPLICATION_CREDENTIALS`** (string):
|
||||
- **Description:** The path to your Google Application Credentials JSON file.
|
||||
- **Example:**
|
||||
`export GOOGLE_APPLICATION_CREDENTIALS="/path/to/your/credentials.json"`
|
||||
- **`OTLP_GOOGLE_CLOUD_PROJECT`**:
|
||||
- Your Google Cloud Project ID for Telemetry in Google Cloud
|
||||
- Example: `export OTLP_GOOGLE_CLOUD_PROJECT="YOUR_PROJECT_ID"`.
|
||||
- **`GOOGLE_CLOUD_LOCATION`**:
|
||||
- Your Google Cloud Project Location (e.g., us-central1).
|
||||
- Required for using Vertex AI in non express mode.
|
||||
- Example: `export GOOGLE_CLOUD_LOCATION="YOUR_PROJECT_LOCATION"`.
|
||||
- **`GEMINI_SANDBOX`**:
|
||||
- Alternative to the `sandbox` setting in `settings.json`.
|
||||
- Accepts `true`, `false`, `docker`, `podman`, or a custom command string.
|
||||
- **`HTTP_PROXY` / `HTTPS_PROXY`**:
|
||||
- Specifies the proxy server to use for outgoing HTTP/HTTPS requests.
|
||||
- Example: `export HTTPS_PROXY="http://proxy.example.com:8080"`
|
||||
- **`SEATBELT_PROFILE`** (macOS specific):
|
||||
- Switches the Seatbelt (`sandbox-exec`) profile on macOS.
|
||||
- `permissive-open`: (Default) Restricts writes to the project folder (and a
|
||||
few other folders, see
|
||||
`packages/cli/src/utils/sandbox-macos-permissive-open.sb`) but allows other
|
||||
operations.
|
||||
- `strict`: Uses a strict profile that declines operations by default.
|
||||
- `<profile_name>`: Uses a custom profile. To define a custom profile, create
|
||||
a file named `sandbox-macos-<profile_name>.sb` in your project's `.gemini/`
|
||||
directory (e.g., `my-project/.gemini/sandbox-macos-custom.sb`).
|
||||
- **`DEBUG` or `DEBUG_MODE`** (often used by underlying libraries or the CLI
|
||||
itself):
|
||||
- Set to `true` or `1` to enable verbose debug logging, which can be helpful
|
||||
for troubleshooting.
|
||||
- **Note:** These variables are automatically excluded from project `.env`
|
||||
files by default to prevent interference with gemini-cli behavior. Use
|
||||
`.gemini/.env` files if you need to set these for gemini-cli specifically.
|
||||
- **`NO_COLOR`**:
|
||||
- Set to any value to disable all color output in the CLI.
|
||||
- **`CLI_TITLE`**:
|
||||
- Set to a string to customize the title of the CLI.
|
||||
- **`CODE_ASSIST_ENDPOINT`**:
|
||||
- Specifies the endpoint for the code assist server.
|
||||
- This is useful for development and testing.
|
||||
|
||||
## Command-line arguments
|
||||
|
||||
Arguments passed directly when running the CLI can override other configurations
|
||||
for that specific session.
|
||||
|
||||
- **`--model <model_name>`** (**`-m <model_name>`**):
|
||||
- Specifies the Gemini model to use for this session.
|
||||
- Example: `npm start -- --model gemini-1.5-pro-latest`
|
||||
- **`--prompt <your_prompt>`** (**`-p <your_prompt>`**):
|
||||
- Used to pass a prompt directly to the command. This invokes Gemini CLI in a
|
||||
non-interactive mode.
|
||||
- **`--prompt-interactive <your_prompt>`** (**`-i <your_prompt>`**):
|
||||
- Starts an interactive session with the provided prompt as the initial input.
|
||||
- The prompt is processed within the interactive session, not before it.
|
||||
- Cannot be used when piping input from stdin.
|
||||
- Example: `gemini -i "explain this code"`
|
||||
- **`--sandbox`** (**`-s`**):
|
||||
- Enables sandbox mode for this session.
|
||||
- **`--sandbox-image`**:
|
||||
- Sets the sandbox image URI.
|
||||
- **`--debug`** (**`-d`**):
|
||||
- Enables debug mode for this session, providing more verbose output.
|
||||
|
||||
- **`--help`** (or **`-h`**):
|
||||
- Displays help information about command-line arguments.
|
||||
- **`--show-memory-usage`**:
|
||||
- Displays the current memory usage.
|
||||
- **`--yolo`**:
|
||||
- Enables YOLO mode, which automatically approves all tool calls.
|
||||
- **`--approval-mode <mode>`**:
|
||||
- Sets the approval mode for tool calls. Available modes:
|
||||
- `default`: Prompt for approval on each tool call (default behavior)
|
||||
- `auto_edit`: Automatically approve edit tools (replace, write_file) while
|
||||
prompting for others
|
||||
- `yolo`: Automatically approve all tool calls (equivalent to `--yolo`)
|
||||
- Cannot be used together with `--yolo`. Use `--approval-mode=yolo` instead of
|
||||
`--yolo` for the new unified approach.
|
||||
- Example: `gemini --approval-mode auto_edit`
|
||||
- **`--allowed-tools <tool1,tool2,...>`**:
|
||||
- A comma-separated list of tool names that will bypass the confirmation
|
||||
dialog.
|
||||
- Example: `gemini --allowed-tools "ShellTool(git status)"`
|
||||
- **`--telemetry`**:
|
||||
- Enables [telemetry](../cli/telemetry.md).
|
||||
- **`--telemetry-target`**:
|
||||
- Sets the telemetry target. See [telemetry](../cli/telemetry.md) for more
|
||||
information.
|
||||
- **`--telemetry-otlp-endpoint`**:
|
||||
- Sets the OTLP endpoint for telemetry. See [telemetry](../cli/telemetry.md)
|
||||
for more information.
|
||||
- **`--telemetry-otlp-protocol`**:
|
||||
- Sets the OTLP protocol for telemetry (`grpc` or `http`). Defaults to `grpc`.
|
||||
See [telemetry](../cli/telemetry.md) for more information.
|
||||
- **`--telemetry-log-prompts`**:
|
||||
- Enables logging of prompts for telemetry. See
|
||||
[telemetry](../cli/telemetry.md) for more information.
|
||||
- **`--extensions <extension_name ...>`** (**`-e <extension_name ...>`**):
|
||||
- Specifies a list of extensions to use for the session. If not provided, all
|
||||
available extensions are used.
|
||||
- Use the special term `gemini -e none` to disable all extensions.
|
||||
- Example: `gemini -e my-extension -e my-other-extension`
|
||||
- **`--list-extensions`** (**`-l`**):
|
||||
- Lists all available extensions and exits.
|
||||
- **`--include-directories <dir1,dir2,...>`**:
|
||||
- Includes additional directories in the workspace for multi-directory
|
||||
support.
|
||||
- Can be specified multiple times or as comma-separated values.
|
||||
- 5 directories can be added at maximum.
|
||||
- Example: `--include-directories /path/to/project1,/path/to/project2` or
|
||||
`--include-directories /path/to/project1 --include-directories /path/to/project2`
|
||||
- **`--screen-reader`**:
|
||||
- Enables screen reader mode for accessibility.
|
||||
- **`--version`**:
|
||||
- Displays the version of the CLI.
|
||||
|
||||
## Context files (hierarchical instructional context)
|
||||
|
||||
While not strictly configuration for the CLI's _behavior_, context files
|
||||
(defaulting to `GEMINI.md` but configurable via the `contextFileName` setting)
|
||||
are crucial for configuring the _instructional context_ (also referred to as
|
||||
"memory") provided to the Gemini model. This powerful feature allows you to give
|
||||
project-specific instructions, coding style guides, or any relevant background
|
||||
information to the AI, making its responses more tailored and accurate to your
|
||||
needs. The CLI includes UI elements, such as an indicator in the footer showing
|
||||
the number of loaded context files, to keep you informed about the active
|
||||
context.
|
||||
|
||||
- **Purpose:** These Markdown files contain instructions, guidelines, or context
|
||||
that you want the Gemini model to be aware of during your interactions. The
|
||||
system is designed to manage this instructional context hierarchically.
|
||||
|
||||
### Example context file content (e.g., `GEMINI.md`)
|
||||
|
||||
Here's a conceptual example of what a context file at the root of a TypeScript
|
||||
project might contain:
|
||||
|
||||
```markdown
|
||||
# Project: My Awesome TypeScript Library
|
||||
|
||||
## General Instructions:
|
||||
|
||||
- When generating new TypeScript code, please follow the existing coding style.
|
||||
- Ensure all new functions and classes have JSDoc comments.
|
||||
- Prefer functional programming paradigms where appropriate.
|
||||
- All code should be compatible with TypeScript 5.0 and Node.js 20+.
|
||||
|
||||
## Coding Style:
|
||||
|
||||
- Use 2 spaces for indentation.
|
||||
- Interface names should be prefixed with `I` (e.g., `IUserService`).
|
||||
- Private class members should be prefixed with an underscore (`_`).
|
||||
- Always use strict equality (`===` and `!==`).
|
||||
|
||||
## Specific Component: `src/api/client.ts`
|
||||
|
||||
- This file handles all outbound API requests.
|
||||
- When adding new API call functions, ensure they include robust error handling
|
||||
and logging.
|
||||
- Use the existing `fetchWithRetry` utility for all GET requests.
|
||||
|
||||
## Regarding Dependencies:
|
||||
|
||||
- Avoid introducing new external dependencies unless absolutely necessary.
|
||||
- If a new dependency is required, please state the reason.
|
||||
```
|
||||
|
||||
This example demonstrates how you can provide general project context, specific
|
||||
coding conventions, and even notes about particular files or components. The
|
||||
more relevant and precise your context files are, the better the AI can assist
|
||||
you. Project-specific context files are highly encouraged to establish
|
||||
conventions and context.
|
||||
|
||||
- **Hierarchical loading and precedence:** The CLI implements a sophisticated
|
||||
hierarchical memory system by loading context files (e.g., `GEMINI.md`) from
|
||||
several locations. Content from files lower in this list (more specific)
|
||||
typically overrides or supplements content from files higher up (more
|
||||
general). The exact concatenation order and final context can be inspected
|
||||
using the `/memory show` command. The typical loading order is:
|
||||
1. **Global context file:**
|
||||
- Location: `~/.gemini/<contextFileName>` (e.g., `~/.gemini/GEMINI.md` in
|
||||
your user home directory).
|
||||
- Scope: Provides default instructions for all your projects.
|
||||
2. **Project root and ancestors context files:**
|
||||
- Location: The CLI searches for the configured context file in the
|
||||
current working directory and then in each parent directory up to either
|
||||
the project root (identified by a `.git` folder) or your home directory.
|
||||
- Scope: Provides context relevant to the entire project or a significant
|
||||
portion of it.
|
||||
3. **Sub-directory context files (contextual/local):**
|
||||
- Location: The CLI also scans for the configured context file in
|
||||
subdirectories _below_ the current working directory (respecting common
|
||||
ignore patterns like `node_modules`, `.git`, etc.). The breadth of this
|
||||
search is limited to 200 directories by default, but can be configured
|
||||
with a `memoryDiscoveryMaxDirs` field in your `settings.json` file.
|
||||
- Scope: Allows for highly specific instructions relevant to a particular
|
||||
component, module, or subsection of your project.
|
||||
- **Concatenation and UI indication:** The contents of all found context files
|
||||
are concatenated (with separators indicating their origin and path) and
|
||||
provided as part of the system prompt to the Gemini model. The CLI footer
|
||||
displays the count of loaded context files, giving you a quick visual cue
|
||||
about the active instructional context.
|
||||
- **Importing content:** You can modularize your context files by importing
|
||||
other Markdown files using the `@path/to/file.md` syntax. For more details,
|
||||
see the [Memory Import Processor documentation](../core/memport.md).
|
||||
- **Commands for memory management:**
|
||||
- Use `/memory refresh` to force a re-scan and reload of all context files
|
||||
from all configured locations. This updates the AI's instructional context.
|
||||
- Use `/memory show` to display the combined instructional context currently
|
||||
loaded, allowing you to verify the hierarchy and content being used by the
|
||||
AI.
|
||||
- See the [Commands documentation](../cli/commands.md#memory) for full details
|
||||
on the `/memory` command and its sub-commands (`show` and `refresh`).
|
||||
|
||||
By understanding and utilizing these configuration layers and the hierarchical
|
||||
nature of context files, you can effectively manage the AI's memory and tailor
|
||||
the Gemini CLI's responses to your specific needs and projects.
|
||||
|
||||
## Sandboxing
|
||||
|
||||
The Gemini CLI can execute potentially unsafe operations (like shell commands
|
||||
and file modifications) within a sandboxed environment to protect your system.
|
||||
|
||||
Sandboxing is disabled by default, but you can enable it in a few ways:
|
||||
|
||||
- Using `--sandbox` or `-s` flag.
|
||||
- Setting `GEMINI_SANDBOX` environment variable.
|
||||
- Sandbox is enabled when using `--yolo` or `--approval-mode=yolo` by default.
|
||||
|
||||
By default, it uses a pre-built `gemini-cli-sandbox` Docker image.
|
||||
|
||||
For project-specific sandboxing needs, you can create a custom Dockerfile at
|
||||
`.gemini/sandbox.Dockerfile` in your project's root directory. This Dockerfile
|
||||
can be based on the base sandbox image:
|
||||
|
||||
```dockerfile
|
||||
FROM gemini-cli-sandbox
|
||||
|
||||
# Add your custom dependencies or configurations here
|
||||
# For example:
|
||||
# RUN apt-get update && apt-get install -y some-package
|
||||
# COPY ./my-config /app/my-config
|
||||
```
|
||||
|
||||
When `.gemini/sandbox.Dockerfile` exists, you can use `BUILD_SANDBOX`
|
||||
environment variable when running Gemini CLI to automatically build the custom
|
||||
sandbox image:
|
||||
|
||||
```bash
|
||||
BUILD_SANDBOX=1 gemini -s
|
||||
```
|
||||
|
||||
## Usage statistics
|
||||
|
||||
To help us improve the Gemini CLI, we collect anonymized usage statistics. This
|
||||
data helps us understand how the CLI is used, identify common issues, and
|
||||
prioritize new features.
|
||||
|
||||
**What we collect:**
|
||||
|
||||
- **Tool calls:** We log the names of the tools that are called, whether they
|
||||
succeed or fail, and how long they take to execute. We do not collect the
|
||||
arguments passed to the tools or any data returned by them.
|
||||
- **API requests:** We log the Gemini model used for each request, the duration
|
||||
of the request, and whether it was successful. We do not collect the content
|
||||
of the prompts or responses.
|
||||
- **Session information:** We collect information about the configuration of the
|
||||
CLI, such as the enabled tools and the approval mode.
|
||||
|
||||
**What we DON'T collect:**
|
||||
|
||||
- **Personally identifiable information (PII):** We do not collect any personal
|
||||
information, such as your name, email address, or API keys.
|
||||
- **Prompt and response content:** We do not log the content of your prompts or
|
||||
the responses from the Gemini model.
|
||||
- **File content:** We do not log the content of any files that are read or
|
||||
written by the CLI.
|
||||
|
||||
**How to opt out:**
|
||||
|
||||
You can opt out of usage statistics collection at any time by setting the
|
||||
`usageStatisticsEnabled` property to `false` in your `settings.json` file:
|
||||
|
||||
```json
|
||||
{
|
||||
"usageStatisticsEnabled": false
|
||||
}
|
||||
```
|
||||
@@ -132,8 +132,8 @@ for your login page.
|
||||
|
||||
## Next steps
|
||||
|
||||
- Explore the [User guides](../cli/index.md#user-guides) for detailed
|
||||
walkthroughs of common tasks.
|
||||
- Follow the [File management](../cli/tutorials/file-management.md) guide to
|
||||
start working with your codebase.
|
||||
- Follow the [Quickstart](./index.md) to start your first session.
|
||||
- See the [Cheatsheet](../cli/cli-reference.md) for a quick reference of
|
||||
available commands.
|
||||
|
||||
@@ -2,6 +2,21 @@
|
||||
|
||||
Gemini 3 Pro and Gemini 3 Flash are available on Gemini CLI for all users!
|
||||
|
||||
> **Note:** Gemini 3.1 Pro Preview is rolling out. To determine whether you have
|
||||
> access to Gemini 3.1, use the `/model` command and select **Manual**. If you
|
||||
> have access, you will see `gemini-3.1-pro-preview`.
|
||||
>
|
||||
> If you have access to Gemini 3.1, it will be included in model routing when
|
||||
> you select **Auto (Gemini 3)**. You can also launch the Gemini 3.1 model
|
||||
> directly using the `-m` flag:
|
||||
>
|
||||
> ```
|
||||
> gemini -m gemini-3.1-pro-preview
|
||||
> ```
|
||||
>
|
||||
> Learn more about [models](../cli/model.md) and
|
||||
> [model routing](../cli/model-routing.md).
|
||||
|
||||
## How to get started with Gemini 3 on Gemini CLI
|
||||
|
||||
Get started by upgrading Gemini CLI to the latest version:
|
||||
@@ -12,9 +27,8 @@ npm install -g @google/gemini-cli@latest
|
||||
|
||||
After you’ve confirmed your version is 0.21.1 or later:
|
||||
|
||||
1. Use the `/settings` command in Gemini CLI.
|
||||
2. Toggle **Preview Features** to `true`.
|
||||
3. Run `/model` and select **Auto (Gemini 3)**.
|
||||
1. Run `/model`.
|
||||
2. Select **Auto (Gemini 3)**.
|
||||
|
||||
For more information, see [Gemini CLI model selection](../cli/model.md).
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ Gemini CLI offers several ways to configure its behavior, including environment
|
||||
variables, command-line arguments, and settings files.
|
||||
|
||||
To explore your configuration options, see
|
||||
[Gemini CLI Configuration](./configuration.md).
|
||||
[Gemini CLI Configuration](../reference/configuration.md).
|
||||
|
||||
## Use
|
||||
|
||||
@@ -64,10 +64,19 @@ and more.
|
||||
|
||||
To explore the power of Gemini CLI, see [Gemini CLI examples](./examples.md).
|
||||
|
||||
## Check usage and quota
|
||||
|
||||
You can check your current token usage and quota information using the
|
||||
`/stats model` command. This command provides a snapshot of your current
|
||||
session's token usage, as well as your overall quota and usage for the supported
|
||||
models.
|
||||
|
||||
For more information on the `/stats` command and its subcommands, see the
|
||||
[Command Reference](../../reference/commands.md#stats).
|
||||
|
||||
## Next steps
|
||||
|
||||
- Follow the [File management](../cli/tutorials/file-management.md) guide to
|
||||
start working with your codebase.
|
||||
- See [Shell commands](../cli/tutorials/shell-commands.md) to learn about
|
||||
terminal integration.
|
||||
- Explore the full range of [User guides](../cli/index.md#user-guides).
|
||||
|
||||
@@ -420,7 +420,7 @@ When you open a project with hooks defined in `.gemini/settings.json`:
|
||||
|
||||
Hooks inherit the environment of the Gemini CLI process, which may include
|
||||
sensitive API keys. Gemini CLI provides a
|
||||
[redaction system](/docs/get-started/configuration#environment-variable-redaction)
|
||||
[redaction system](/docs/reference/configuration.md#environment-variable-redaction)
|
||||
that automatically filters variables matching sensitive patterns (e.g., `KEY`,
|
||||
`TOKEN`).
|
||||
|
||||
|
||||
+44
-48
@@ -30,6 +30,8 @@ User-focused guides and tutorials for daily development workflows.
|
||||
|
||||
- **[File management](./cli/tutorials/file-management.md):** How to work with
|
||||
local files and directories.
|
||||
- **[Get started with Agent skills](./cli/tutorials/skills-getting-started.md):**
|
||||
Getting started with specialized expertise.
|
||||
- **[Manage context and memory](./cli/tutorials/memory-management.md):**
|
||||
Managing persistent instructions and facts.
|
||||
- **[Execute shell commands](./cli/tutorials/shell-commands.md):** Executing
|
||||
@@ -40,46 +42,14 @@ User-focused guides and tutorials for daily development workflows.
|
||||
complex workflows.
|
||||
- **[Web search and fetch](./cli/tutorials/web-tools.md):** Searching and
|
||||
fetching content from the web.
|
||||
- **[Get started with skills](./cli/tutorials/skills-getting-started.md):**
|
||||
Getting started with specialized expertise.
|
||||
- **[Set up an MCP server](./cli/tutorials/mcp-setup.md):** Set up an MCP
|
||||
server.
|
||||
- **[Automate tasks](./cli/tutorials/automation.md):** Automate tasks.
|
||||
|
||||
## Features
|
||||
|
||||
Technical reference documentation for each capability of Gemini CLI.
|
||||
Technical documentation for each capability of Gemini CLI.
|
||||
|
||||
- **[/about](./cli/commands.md#about):** About Gemini CLI.
|
||||
- **[/auth](./get-started/authentication.md):** Authentication.
|
||||
- **[/bug](./cli/commands.md#bug):** Report a bug.
|
||||
- **[/chat](./cli/commands.md#chat):** Chat history.
|
||||
- **[/clear](./cli/commands.md#clear):** Clear screen.
|
||||
- **[/compress](./cli/commands.md#compress):** Compress context.
|
||||
- **[/copy](./cli/commands.md#copy):** Copy output.
|
||||
- **[/directory](./cli/commands.md#directory-or-dir):** Manage workspace.
|
||||
- **[/docs](./cli/commands.md#docs):** Open documentation.
|
||||
- **[/editor](./cli/commands.md#editor):** Select editor.
|
||||
- **[/extensions](./extensions/index.md):** Manage extensions.
|
||||
- **[/help](./cli/commands.md#help-or):** Show help.
|
||||
- **[/hooks](./hooks/index.md):** Hooks.
|
||||
- **[/ide](./ide-integration/index.md):** IDE integration.
|
||||
- **[/init](./cli/commands.md#init):** Initialize context.
|
||||
- **[/mcp](./tools/mcp-server.md):** MCP servers.
|
||||
- **[/memory](./cli/commands.md#memory):** Manage memory.
|
||||
- **[/model](./cli/model.md):** Model selection.
|
||||
- **[/policies](./cli/commands.md#policies):** Manage policies.
|
||||
- **[/privacy](./cli/commands.md#privacy):** Privacy notice.
|
||||
- **[/quit](./cli/commands.md#quit-or-exit):** Exit CLI.
|
||||
- **[/restore](./cli/checkpointing.md):** Restore files.
|
||||
- **[/resume](./cli/commands.md#resume):** Resume session.
|
||||
- **[/rewind](./cli/rewind.md):** Rewind.
|
||||
- **[/settings](./cli/settings.md):** Settings.
|
||||
- **[/setup-github](./cli/commands.md#setup-github):** GitHub setup.
|
||||
- **[/shells](./cli/commands.md#shells-or-bashes):** Manage processes.
|
||||
- **[/skills](./cli/skills.md):** Agent skills.
|
||||
- **[/stats](./cli/commands.md#stats):** Session statistics.
|
||||
- **[/terminal-setup](./cli/commands.md#terminal-setup):** Terminal keybindings.
|
||||
- **[/theme](./cli/themes.md):** Themes.
|
||||
- **[/tools](./cli/commands.md#tools):** List tools.
|
||||
- **[/vim](./cli/commands.md#vim):** Vim mode.
|
||||
- **[Activate skill (tool)](./tools/activate-skill.md):** Internal mechanism for
|
||||
loading expert procedures.
|
||||
- **[Ask user (tool)](./tools/ask-user.md):** Internal dialog system for
|
||||
@@ -92,8 +62,12 @@ Technical reference documentation for each capability of Gemini CLI.
|
||||
lookup for CLI features.
|
||||
- **[Memory (tool)](./tools/memory.md):** Storage details for persistent facts.
|
||||
- **[Model routing](./cli/model-routing.md):** Automatic fallback resilience.
|
||||
- **[Plan mode (experimental)](./cli/plan-mode.md):** Use a safe, read-only mode
|
||||
for planning complex changes.
|
||||
- **[Plan mode 🧪](./cli/plan-mode.md):** Use a safe, read-only mode for
|
||||
planning complex changes.
|
||||
- **[Subagents 🧪](./core/subagents.md):** Using specialized agents for specific
|
||||
tasks.
|
||||
- **[Remote subagents 🧪](./core/remote-agents.md):** Connecting to and using
|
||||
remote agents.
|
||||
- **[Sandboxing](./cli/sandbox.md):** Isolate tool execution.
|
||||
- **[Shell (tool)](./tools/shell.md):** Detailed system execution parameters.
|
||||
- **[Telemetry](./cli/telemetry.md):** Usage and performance metric details.
|
||||
@@ -127,20 +101,42 @@ Settings and customization options for Gemini CLI.
|
||||
|
||||
Deep technical documentation and API specifications.
|
||||
|
||||
- **[Architecture overview](./architecture.md):** System design and components.
|
||||
- **[Command reference](./cli/commands.md):** Detailed slash command guide.
|
||||
- **[Configuration reference](./get-started/configuration.md):** Settings and
|
||||
- **[Command reference](./reference/commands.md):** Detailed slash command
|
||||
guide.
|
||||
- **[Configuration reference](./reference/configuration.md):** Settings and
|
||||
environment variables.
|
||||
- **[Core concepts](./core/concepts.md):** Fundamental terminology and
|
||||
definitions.
|
||||
- **[Keyboard shortcuts](./cli/keyboard-shortcuts.md):** Productivity tips.
|
||||
- **[Policy engine](./core/policy-engine.md):** Fine-grained execution control.
|
||||
- **[Keyboard shortcuts](./reference/keyboard-shortcuts.md):** Productivity
|
||||
tips.
|
||||
- **[Memory import processor](./reference/memport.md):** How Gemini CLI
|
||||
processes memory from various sources.
|
||||
- **[Policy engine](./reference/policy-engine.md):** Fine-grained execution
|
||||
control.
|
||||
- **[Tools API](./reference/tools-api.md):** The API for defining and using
|
||||
tools.
|
||||
|
||||
## Resources
|
||||
|
||||
Support, release history, and legal information.
|
||||
|
||||
- **[FAQ](./faq.md):** Answers to frequently asked questions.
|
||||
- **[FAQ](./resources/faq.md):** Answers to frequently asked questions.
|
||||
- **[Changelogs](./changelogs/index.md):** Highlights and notable changes.
|
||||
- **[Quota and pricing](./quota-and-pricing.md):** Limits and billing details.
|
||||
- **[Terms and privacy](./tos-privacy.md):** Official notices and terms.
|
||||
- **[Quota and pricing](./resources/quota-and-pricing.md):** Limits and billing
|
||||
details.
|
||||
- **[Terms and privacy](./resources/tos-privacy.md):** Official notices and
|
||||
terms.
|
||||
|
||||
## Development
|
||||
|
||||
- **[Contribution guide](/docs/contributing):** How to contribute to Gemini CLI.
|
||||
- **[Integration testing](./integration-tests.md):** Running integration tests.
|
||||
- **[Issue and PR automation](./issue-and-pr-automation.md):** Automation for
|
||||
issues and pull requests.
|
||||
- **[Local development](./local-development.md):** Setting up a local
|
||||
development environment.
|
||||
- **[NPM package structure](./npm.md):** The structure of the NPM packages.
|
||||
|
||||
## Releases
|
||||
|
||||
- **[Release notes](./changelogs/index.md):** Release notes for all versions.
|
||||
- **[Stable release](./changelogs/latest.md):** The latest stable release.
|
||||
- **[Preview release](./changelogs/preview.md):** The latest preview release.
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"/docs/architecture": "/docs/cli/index",
|
||||
"/docs/cli/commands": "/docs/reference/commands",
|
||||
"/docs/cli": "/docs",
|
||||
"/docs/cli/index": "/docs",
|
||||
"/docs/cli/keyboard-shortcuts": "/docs/reference/keyboard-shortcuts",
|
||||
"/docs/cli/uninstall": "/docs/resources/uninstall",
|
||||
"/docs/core/concepts": "/docs",
|
||||
"/docs/core/memport": "/docs/reference/memport",
|
||||
"/docs/core/policy-engine": "/docs/reference/policy-engine",
|
||||
"/docs/core/tools-api": "/docs/reference/tools-api",
|
||||
"/docs/faq": "/docs/resources/faq",
|
||||
"/docs/get-started/configuration": "/docs/reference/configuration",
|
||||
"/docs/get-started/configuration-v1": "/docs/reference/configuration",
|
||||
"/docs/index": "/docs",
|
||||
"/docs/quota-and-pricing": "/docs/resources/quota-and-pricing",
|
||||
"/docs/tos-privacy": "/docs/resources/tos-privacy",
|
||||
"/docs/troubleshooting": "/docs/resources/troubleshooting"
|
||||
}
|
||||
@@ -32,6 +32,8 @@ Slash commands provide meta-level control over the CLI itself.
|
||||
conversation state interactively, or resuming a previous state from a later
|
||||
session.
|
||||
- **Sub-commands:**
|
||||
- **`debug`**
|
||||
- **Description:** Export the most recent API request as a JSON payload.
|
||||
- **`delete <tag>`**
|
||||
- **Description:** Deletes a saved conversation checkpoint.
|
||||
- **`list`**
|
||||
@@ -128,8 +130,29 @@ Slash commands provide meta-level control over the CLI itself.
|
||||
|
||||
### `/extensions`
|
||||
|
||||
- **Description:** Lists all active extensions in the current Gemini CLI
|
||||
session. See [Gemini CLI Extensions](../extensions/index.md).
|
||||
- **Description:** Manage extensions. See
|
||||
[Gemini CLI Extensions](../extensions/index.md).
|
||||
- **Sub-commands:**
|
||||
- **`config`**:
|
||||
- **Description:** Configure extension settings.
|
||||
- **`disable`**:
|
||||
- **Description:** Disable an extension.
|
||||
- **`enable`**:
|
||||
- **Description:** Enable an extension.
|
||||
- **`explore`**:
|
||||
- **Description:** Open extensions page in your browser.
|
||||
- **`install`**:
|
||||
- **Description:** Install an extension from a git repo or local path.
|
||||
- **`link`**:
|
||||
- **Description:** Link an extension from a local path.
|
||||
- **`list`**:
|
||||
- **Description:** List active extensions.
|
||||
- **`restart`**:
|
||||
- **Description:** Restart all extensions.
|
||||
- **`uninstall`**:
|
||||
- **Description:** Uninstall an extension.
|
||||
- **`update`**:
|
||||
- **Description:** Update extensions. Usage: update <extension-names>|--all
|
||||
|
||||
### `/help` (or `/?`)
|
||||
|
||||
@@ -184,6 +207,10 @@ Slash commands provide meta-level control over the CLI itself.
|
||||
servers that support OAuth authentication.
|
||||
- **`desc`**
|
||||
- **Description:** List configured MCP servers and tools with descriptions.
|
||||
- **`disable`**
|
||||
- **Description:** Disable an MCP server.
|
||||
- **`enable`**
|
||||
- **Description:** Enable a disabled MCP server.
|
||||
- **`list`** or **`ls`**:
|
||||
- **Description:** List configured MCP servers and tools. This is the
|
||||
default action if no subcommand is specified.
|
||||
@@ -217,11 +244,32 @@ Slash commands provide meta-level control over the CLI itself.
|
||||
model.
|
||||
- **Note:** For more details on how `GEMINI.md` files contribute to
|
||||
hierarchical memory, see the
|
||||
[CLI Configuration documentation](../get-started/configuration.md).
|
||||
[CLI Configuration documentation](./configuration.md).
|
||||
|
||||
### `/model`
|
||||
|
||||
- **Description:** Opens a dialog to choose your Gemini model.
|
||||
- **Description:** Manage model configuration.
|
||||
- **Sub-commands:**
|
||||
- **`manage`**:
|
||||
- **Description:** Opens a dialog to configure the model.
|
||||
- **`set`**:
|
||||
- **Description:** Set the model to use.
|
||||
- **Usage:** `/model set <model-name> [--persist]`
|
||||
|
||||
### `/permissions`
|
||||
|
||||
- **Description:** Manage folder trust settings and other permissions.
|
||||
- **Sub-commands:**
|
||||
- **`trust`**:
|
||||
- **Description:** Manage folder trust settings.
|
||||
- **Usage:** `/permissions trust [<directory-path>]`
|
||||
|
||||
### `/plan`
|
||||
|
||||
- **Description:** Switch to Plan Mode (read-only) and view the current plan if
|
||||
one has been generated.
|
||||
- **Note:** This feature requires the `experimental.plan` setting to be
|
||||
enabled in your configuration.
|
||||
|
||||
### `/policies`
|
||||
|
||||
@@ -247,7 +295,7 @@ Slash commands provide meta-level control over the CLI itself.
|
||||
checkpoints to restore from.
|
||||
- **Usage:** `/restore [tool_call_id]`
|
||||
- **Note:** Only available if checkpointing is configured via
|
||||
[settings](../get-started/configuration.md). See
|
||||
[settings](./configuration.md). See
|
||||
[Checkpointing documentation](../cli/checkpointing.md) for more details.
|
||||
|
||||
### `/rewind`
|
||||
@@ -286,7 +334,8 @@ Slash commands provide meta-level control over the CLI itself.
|
||||
settings that control the behavior and appearance of Gemini CLI. It is
|
||||
equivalent to manually editing the `.gemini/settings.json` file, but with
|
||||
validation and guidance to prevent errors. See the
|
||||
[settings documentation](./settings.md) for a full list of available settings.
|
||||
[settings documentation](../cli/settings.md) for a full list of available
|
||||
settings.
|
||||
- **Usage:** Simply run `/settings` and the editor will open. You can then
|
||||
browse or search for specific settings, view their current values, and modify
|
||||
them as desired. Changes to some settings are applied immediately, while
|
||||
@@ -323,10 +372,16 @@ Slash commands provide meta-level control over the CLI itself.
|
||||
### `/stats`
|
||||
|
||||
- **Description:** Display detailed statistics for the current Gemini CLI
|
||||
session, including token usage, cached token savings (when available), and
|
||||
session duration. Note: Cached token information is only displayed when cached
|
||||
tokens are being used, which occurs with API key authentication but not with
|
||||
OAuth authentication at this time.
|
||||
session.
|
||||
- **Sub-commands:**
|
||||
- **`session`**:
|
||||
- **Description:** Show session-specific usage statistics, including
|
||||
duration, tool calls, and performance metrics. This is the default view.
|
||||
- **`model`**:
|
||||
- **Description:** Show model-specific usage statistics, including token
|
||||
counts and quota information.
|
||||
- **`tools`**:
|
||||
- **Description:** Show tool-specific usage statistics.
|
||||
|
||||
### `/terminal-setup`
|
||||
|
||||
@@ -373,7 +428,8 @@ Slash commands provide meta-level control over the CLI itself.
|
||||
|
||||
Custom commands allow you to create personalized shortcuts for your most-used
|
||||
prompts. For detailed instructions on how to create, manage, and use them,
|
||||
please see the dedicated [Custom Commands documentation](./custom-commands.md).
|
||||
please see the dedicated
|
||||
[Custom Commands documentation](../cli/custom-commands.md).
|
||||
|
||||
## Input prompt shortcuts
|
||||
|
||||
@@ -1,16 +1,5 @@
|
||||
# Gemini CLI configuration
|
||||
|
||||
> **Note on configuration format, 9/17/25:** The format of the `settings.json`
|
||||
> file has been updated to a new, more organized structure.
|
||||
>
|
||||
> - The new format will be supported in the stable release starting
|
||||
> **[09/10/25]**.
|
||||
> - Automatic migration from the old format to the new format will begin on
|
||||
> **[09/17/25]**.
|
||||
>
|
||||
> For details on the previous format, please see the
|
||||
> [v1 Configuration documentation](./configuration-v1.md).
|
||||
|
||||
Gemini CLI offers several ways to configure its behavior, including environment
|
||||
variables, command-line arguments, and settings files. This document outlines
|
||||
the different configuration methods and available settings.
|
||||
@@ -132,15 +121,20 @@ their corresponding top-level category object in your `settings.json` file.
|
||||
- **Description:** Enable update notification prompts.
|
||||
- **Default:** `true`
|
||||
|
||||
- **`general.enableNotifications`** (boolean):
|
||||
- **Description:** Enable run-event notifications for action-required prompts
|
||||
and session completion. Currently macOS only.
|
||||
- **Default:** `false`
|
||||
|
||||
- **`general.checkpointing.enabled`** (boolean):
|
||||
- **Description:** Enable session checkpointing for recovery
|
||||
- **Default:** `false`
|
||||
- **Requires restart:** Yes
|
||||
|
||||
- **`general.enablePromptCompletion`** (boolean):
|
||||
- **Description:** Enable AI-powered prompt completion suggestions while
|
||||
typing.
|
||||
- **Default:** `false`
|
||||
- **`general.plan.directory`** (string):
|
||||
- **Description:** The directory where planning artifacts are stored. If not
|
||||
specified, defaults to the system temporary directory.
|
||||
- **Default:** `undefined`
|
||||
- **Requires restart:** Yes
|
||||
|
||||
- **`general.retryFetchErrors`** (boolean):
|
||||
@@ -228,6 +222,11 @@ their corresponding top-level category object in your `settings.json` file.
|
||||
- **Default:** `true`
|
||||
- **Requires restart:** Yes
|
||||
|
||||
- **`ui.showCompatibilityWarnings`** (boolean):
|
||||
- **Description:** Show warnings about terminal or OS compatibility issues.
|
||||
- **Default:** `true`
|
||||
- **Requires restart:** Yes
|
||||
|
||||
- **`ui.hideTips`** (boolean):
|
||||
- **Description:** Hide helpful tips in the UI
|
||||
- **Default:** `false`
|
||||
@@ -306,13 +305,20 @@ their corresponding top-level category object in your `settings.json` file.
|
||||
- **Description:** Show the spinner during operations.
|
||||
- **Default:** `true`
|
||||
|
||||
- **`ui.loadingPhrases`** (enum):
|
||||
- **Description:** What to show while the model is working: tips, witty
|
||||
comments, both, or nothing.
|
||||
- **Default:** `"tips"`
|
||||
- **Values:** `"tips"`, `"witty"`, `"all"`, `"off"`
|
||||
|
||||
- **`ui.customWittyPhrases`** (array):
|
||||
- **Description:** Custom witty phrases to display during loading. When
|
||||
provided, the CLI cycles through these instead of the defaults.
|
||||
- **Default:** `[]`
|
||||
|
||||
- **`ui.accessibility.enableLoadingPhrases`** (boolean):
|
||||
- **Description:** Enable loading phrases during operations.
|
||||
- **Description:** @deprecated Use ui.loadingPhrases instead. Enable loading
|
||||
phrases during operations.
|
||||
- **Default:** `true`
|
||||
- **Requires restart:** Yes
|
||||
|
||||
@@ -635,6 +641,27 @@ their corresponding top-level category object in your `settings.json` file.
|
||||
- **Default:** `{}`
|
||||
- **Requires restart:** Yes
|
||||
|
||||
- **`agents.browser.sessionMode`** (enum):
|
||||
- **Description:** Session mode: 'persistent', 'isolated', or 'existing'.
|
||||
- **Default:** `"persistent"`
|
||||
- **Values:** `"persistent"`, `"isolated"`, `"existing"`
|
||||
- **Requires restart:** Yes
|
||||
|
||||
- **`agents.browser.headless`** (boolean):
|
||||
- **Description:** Run browser in headless mode.
|
||||
- **Default:** `false`
|
||||
- **Requires restart:** Yes
|
||||
|
||||
- **`agents.browser.profilePath`** (string):
|
||||
- **Description:** Path to browser profile directory for session persistence.
|
||||
- **Default:** `undefined`
|
||||
- **Requires restart:** Yes
|
||||
|
||||
- **`agents.browser.visualModel`** (string):
|
||||
- **Description:** Model override for the visual agent.
|
||||
- **Default:** `undefined`
|
||||
- **Requires restart:** Yes
|
||||
|
||||
#### `context`
|
||||
|
||||
- **`context.fileName`** (string | string[]):
|
||||
@@ -942,8 +969,15 @@ their corresponding top-level category object in your `settings.json` file.
|
||||
- **Requires restart:** Yes
|
||||
|
||||
- **`experimental.useOSC52Paste`** (boolean):
|
||||
- **Description:** Use OSC 52 sequence for pasting instead of clipboardy
|
||||
(useful for remote sessions).
|
||||
- **Description:** 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).
|
||||
- **Default:** `false`
|
||||
|
||||
- **`experimental.useOSC52Copy`** (boolean):
|
||||
- **Description:** 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).
|
||||
- **Default:** `false`
|
||||
|
||||
- **`experimental.plan`** (boolean):
|
||||
@@ -951,6 +985,11 @@ their corresponding top-level category object in your `settings.json` file.
|
||||
- **Default:** `false`
|
||||
- **Requires restart:** Yes
|
||||
|
||||
- **`experimental.modelSteering`** (boolean):
|
||||
- **Description:** Enable model steering (user hints) to guide the model
|
||||
during tool execution.
|
||||
- **Default:** `false`
|
||||
|
||||
#### `skills`
|
||||
|
||||
- **`skills.enabled`** (boolean):
|
||||
@@ -1210,8 +1249,8 @@ within your user's home folder.
|
||||
Environment variables are a common way to configure applications, especially for
|
||||
sensitive information like API keys or for settings that might change between
|
||||
environments. For authentication setup, see the
|
||||
[Authentication documentation](./authentication.md) which covers all available
|
||||
authentication methods.
|
||||
[Authentication documentation](../get-started/authentication.md) which covers
|
||||
all available authentication methods.
|
||||
|
||||
The CLI automatically loads environment variables from an `.env` file. The
|
||||
loading order is:
|
||||
@@ -1230,7 +1269,8 @@ the `advanced.excludedEnvVars` setting in your `settings.json` file.
|
||||
|
||||
- **`GEMINI_API_KEY`**:
|
||||
- Your API key for the Gemini API.
|
||||
- One of several available [authentication methods](./authentication.md).
|
||||
- One of several available
|
||||
[authentication methods](../get-started/authentication.md).
|
||||
- Set this in your shell profile (e.g., `~/.bashrc`, `~/.zshrc`) or an `.env`
|
||||
file.
|
||||
- **`GEMINI_MODEL`**:
|
||||
@@ -1576,15 +1616,15 @@ conventions and context.
|
||||
about the active instructional context.
|
||||
- **Importing content:** You can modularize your context files by importing
|
||||
other Markdown files using the `@path/to/file.md` syntax. For more details,
|
||||
see the [Memory Import Processor documentation](../core/memport.md).
|
||||
see the [Memory Import Processor documentation](./memport.md).
|
||||
- **Commands for memory management:**
|
||||
- Use `/memory refresh` to force a re-scan and reload of all context files
|
||||
from all configured locations. This updates the AI's instructional context.
|
||||
- Use `/memory show` to display the combined instructional context currently
|
||||
loaded, allowing you to verify the hierarchy and content being used by the
|
||||
AI.
|
||||
- See the [Commands documentation](../cli/commands.md#memory) for full details
|
||||
on the `/memory` command and its sub-commands (`show` and `refresh`).
|
||||
- See the [Commands documentation](./commands.md#memory) for full details on
|
||||
the `/memory` command and its sub-commands (`show` and `refresh`).
|
||||
|
||||
By understanding and utilizing these configuration layers and the hierarchical
|
||||
nature of context files, you can effectively manage the AI's memory and tailor
|
||||
@@ -61,7 +61,7 @@ available combinations.
|
||||
| Show the next entry in history. | `Ctrl + N (no Shift)` |
|
||||
| Start reverse search through history. | `Ctrl + R` |
|
||||
| Submit the selected reverse-search match. | `Enter (no Ctrl)` |
|
||||
| Accept a suggestion while reverse searching. | `Tab` |
|
||||
| Accept a suggestion while reverse searching. | `Tab (no Shift)` |
|
||||
| Browse and rewind previous interactions. | `Double Esc` |
|
||||
|
||||
#### Navigation
|
||||
@@ -79,7 +79,7 @@ available combinations.
|
||||
|
||||
| Action | Keys |
|
||||
| --------------------------------------- | -------------------------------------------------- |
|
||||
| Accept the inline suggestion. | `Tab`<br />`Enter (no Ctrl)` |
|
||||
| Accept the inline suggestion. | `Tab (no Shift)`<br />`Enter (no Ctrl)` |
|
||||
| Move to the previous completion option. | `Up Arrow (no Shift)`<br />`Ctrl + P (no Shift)` |
|
||||
| Move to the next completion option. | `Down Arrow (no Shift)`<br />`Ctrl + N (no Shift)` |
|
||||
| Expand an inline suggestion. | `Right Arrow` |
|
||||
@@ -64,9 +64,11 @@ primary conditions are the tool's name and its arguments.
|
||||
|
||||
The `toolName` in the rule must match the name of the tool being called.
|
||||
|
||||
- **Wildcards**: For Model-hosting-protocol (MCP) servers, you can use a
|
||||
wildcard. A `toolName` of `my-server__*` will match any tool from the
|
||||
`my-server` MCP.
|
||||
- **Wildcards**: You can use wildcards to match multiple tools.
|
||||
- `*`: Matches **any tool** (built-in or MCP).
|
||||
- `server__*`: Matches any tool from a specific MCP server.
|
||||
- `*__toolName`: Matches a specific tool name across **all** MCP servers.
|
||||
- `*__*`: Matches **any tool from any MCP server**.
|
||||
|
||||
#### Arguments pattern
|
||||
|
||||
@@ -92,11 +94,12 @@ rule with the highest priority wins**.
|
||||
To provide a clear hierarchy, policies are organized into three tiers. Each tier
|
||||
has a designated number that forms the base of the final priority calculation.
|
||||
|
||||
| Tier | Base | Description |
|
||||
| :------ | :--- | :------------------------------------------------------------------------- |
|
||||
| Default | 1 | Built-in policies that ship with the Gemini CLI. |
|
||||
| User | 2 | Custom policies defined by the user. |
|
||||
| Admin | 3 | Policies managed by an administrator (e.g., in an enterprise environment). |
|
||||
| Tier | Base | Description |
|
||||
| :-------- | :--- | :------------------------------------------------------------------------- |
|
||||
| Default | 1 | Built-in policies that ship with the Gemini CLI. |
|
||||
| Workspace | 2 | Policies defined in the current workspace's configuration directory. |
|
||||
| User | 3 | Custom policies defined by the user. |
|
||||
| Admin | 4 | Policies managed by an administrator (e.g., in an enterprise environment). |
|
||||
|
||||
Within a TOML policy file, you assign a priority value from **0 to 999**. The
|
||||
engine transforms this into a final priority using the following formula:
|
||||
@@ -105,15 +108,17 @@ engine transforms this into a final priority using the following formula:
|
||||
|
||||
This system guarantees that:
|
||||
|
||||
- Admin policies always override User and Default policies.
|
||||
- User policies always override Default policies.
|
||||
- Admin policies always override User, Workspace, and Default policies.
|
||||
- User policies override Workspace and Default policies.
|
||||
- Workspace policies override Default policies.
|
||||
- You can still order rules within a single tier with fine-grained control.
|
||||
|
||||
For example:
|
||||
|
||||
- A `priority: 50` rule in a Default policy file becomes `1.050`.
|
||||
- A `priority: 100` rule in a User policy file becomes `2.100`.
|
||||
- A `priority: 20` rule in an Admin policy file becomes `3.020`.
|
||||
- A `priority: 10` rule in a Workspace policy policy file becomes `2.010`.
|
||||
- A `priority: 100` rule in a User policy file becomes `3.100`.
|
||||
- A `priority: 20` rule in an Admin policy file becomes `4.020`.
|
||||
|
||||
### Approval modes
|
||||
|
||||
@@ -141,9 +146,9 @@ A rule matches a tool call if all of its conditions are met:
|
||||
|
||||
1. **Tool name**: The `toolName` in the rule must match the name of the tool
|
||||
being called.
|
||||
- **Wildcards**: For Model-hosting-protocol (MCP) servers, you can use a
|
||||
wildcard. A `toolName` of `my-server__*` will match any tool from the
|
||||
`my-server` MCP.
|
||||
- **Wildcards**: You can use wildcards like `*`, `server__*`, or
|
||||
`*__toolName` to match multiple tools. See [Tool Name](#tool-name) for
|
||||
details.
|
||||
2. **Arguments pattern**: If `argsPattern` is specified, the tool's arguments
|
||||
are converted to a stable JSON string, which is then tested against the
|
||||
provided regular expression. If the arguments don't match the pattern, the
|
||||
@@ -156,10 +161,11 @@ User, and (if configured) Admin directories.
|
||||
|
||||
### Policy locations
|
||||
|
||||
| Tier | Type | Location |
|
||||
| :-------- | :----- | :-------------------------- |
|
||||
| **User** | Custom | `~/.gemini/policies/*.toml` |
|
||||
| **Admin** | System | _See below (OS specific)_ |
|
||||
| Tier | Type | Location |
|
||||
| :------------ | :----- | :---------------------------------------- |
|
||||
| **User** | Custom | `~/.gemini/policies/*.toml` |
|
||||
| **Workspace** | Custom | `$WORKSPACE_ROOT/.gemini/policies/*.toml` |
|
||||
| **Admin** | System | _See below (OS specific)_ |
|
||||
|
||||
#### System-wide policies (Admin)
|
||||
|
||||
@@ -268,13 +274,12 @@ priority = 100
|
||||
|
||||
### Special syntax for MCP tools
|
||||
|
||||
You can create rules that target tools from Model-hosting-protocol (MCP) servers
|
||||
using the `mcpName` field or a wildcard pattern.
|
||||
You can create rules that target tools from Model Context Protocol (MCP) servers
|
||||
using the `mcpName` field or composite wildcard patterns.
|
||||
|
||||
**1. Using `mcpName`**
|
||||
**1. Targeting a specific tool on a server**
|
||||
|
||||
To target a specific tool from a specific server, combine `mcpName` and
|
||||
`toolName`.
|
||||
Combine `mcpName` and `toolName` to target a single operation.
|
||||
|
||||
```toml
|
||||
# Allows the `search` tool on the `my-jira-server` MCP
|
||||
@@ -285,10 +290,10 @@ decision = "allow"
|
||||
priority = 200
|
||||
```
|
||||
|
||||
**2. Using a wildcard**
|
||||
**2. Targeting all tools on a specific server**
|
||||
|
||||
To create a rule that applies to _all_ tools on a specific MCP server, specify
|
||||
only the `mcpName`.
|
||||
Specify only the `mcpName` to apply a rule to every tool provided by that
|
||||
server.
|
||||
|
||||
```toml
|
||||
# Denies all tools from the `untrusted-server` MCP
|
||||
@@ -299,6 +304,33 @@ priority = 500
|
||||
deny_message = "This server is not trusted by the admin."
|
||||
```
|
||||
|
||||
**3. Targeting all MCP servers**
|
||||
|
||||
Use `mcpName = "*"` to create a rule that applies to **all** tools from **any**
|
||||
registered MCP server. This is useful for setting category-wide defaults.
|
||||
|
||||
```toml
|
||||
# Ask user for any tool call from any MCP server
|
||||
[[rule]]
|
||||
mcpName = "*"
|
||||
decision = "ask_user"
|
||||
priority = 10
|
||||
```
|
||||
|
||||
**4. Targeting a tool name across all servers**
|
||||
|
||||
Use `mcpName = "*"` with a specific `toolName` to target that operation
|
||||
regardless of which server provides it.
|
||||
|
||||
```toml
|
||||
# Allow the `search` tool across all connected MCP servers
|
||||
[[rule]]
|
||||
mcpName = "*"
|
||||
toolName = "search"
|
||||
decision = "allow"
|
||||
priority = 50
|
||||
```
|
||||
|
||||
## Default policies
|
||||
|
||||
The Gemini CLI ships with a set of default policies to provide a safe
|
||||
@@ -104,7 +104,7 @@ The Gemini CLI configuration is stored in two `settings.json` files:
|
||||
1. In your home directory: `~/.gemini/settings.json`.
|
||||
2. In your project's root directory: `./.gemini/settings.json`.
|
||||
|
||||
Refer to [Gemini CLI Configuration](./get-started/configuration.md) for more
|
||||
Refer to [Gemini CLI Configuration](../reference/configuration.md) for more
|
||||
details.
|
||||
|
||||
## Google AI Pro/Ultra and subscription FAQs
|
||||
@@ -135,6 +135,18 @@ Flow video editor). These plans do not apply to the API usage which powers the
|
||||
Gemini CLI. Supporting these plans is under active consideration for future
|
||||
support.
|
||||
|
||||
## Check usage and quota
|
||||
|
||||
You can check your current token usage and quota information using the
|
||||
`/stats model` command. This command provides a snapshot of your current
|
||||
session's token usage, as well as your overall quota and usage for the supported
|
||||
models.
|
||||
|
||||
For more information on the `/stats` command and its subcommands, see the
|
||||
[Command Reference](../../reference/commands.md#stats).
|
||||
|
||||
A summary of model usage is also presented on exit at the end of a session.
|
||||
|
||||
## Tips to avoid high costs
|
||||
|
||||
When using a Pay as you Go API key, be mindful of your usage to avoid unexpected
|
||||
@@ -151,8 +163,3 @@ costs.
|
||||
models directly.
|
||||
- Vertex AI: This is the enterprise-grade platform for building, deploying, and
|
||||
managing Gemini models with specific security and control requirements.
|
||||
|
||||
## Understanding your usage
|
||||
|
||||
A summary of model usage is available through the `/stats` command and presented
|
||||
on exit at the end of a session.
|
||||
@@ -10,8 +10,8 @@ and Privacy Notices applicable to those services apply to such access and use.
|
||||
Your Gemini CLI Usage Statistics are handled in accordance with Google's Privacy
|
||||
Policy.
|
||||
|
||||
**Note:** See [quotas and pricing](/docs/quota-and-pricing.md) for the quota and
|
||||
pricing details that apply to your usage of the Gemini CLI.
|
||||
**Note:** See [quotas and pricing](/docs/resources/quota-and-pricing.md) for the
|
||||
quota and pricing details that apply to your usage of the Gemini CLI.
|
||||
|
||||
## Supported authentication methods
|
||||
|
||||
@@ -93,4 +93,4 @@ backend, these Terms of Service and Privacy Notice documents apply:
|
||||
|
||||
You may opt-out from sending Gemini CLI Usage Statistics to Google by following
|
||||
the instructions available here:
|
||||
[Usage Statistics Configuration](https://github.com/google-gemini/gemini-cli/blob/main/docs/get-started/configuration.md#usage-statistics).
|
||||
[Usage Statistics Configuration](https://github.com/google-gemini/gemini-cli/blob/main/docs/reference/configuration.md#usage-statistics).
|
||||
@@ -93,7 +93,7 @@ topics on:
|
||||
- **Cause:** When sandboxing is enabled, Gemini CLI may attempt operations
|
||||
that are restricted by your sandbox configuration, such as writing outside
|
||||
the project directory or system temp directory.
|
||||
- **Solution:** Refer to the [Configuration: Sandboxing](./cli/sandbox.md)
|
||||
- **Solution:** Refer to the [Configuration: Sandboxing](../cli/sandbox.md)
|
||||
documentation for more information, including how to customize your sandbox
|
||||
configuration.
|
||||
|
||||
+200
-156
@@ -1,189 +1,233 @@
|
||||
[
|
||||
{
|
||||
"label": "Get started",
|
||||
"items": [
|
||||
{ "label": "Overview", "slug": "docs" },
|
||||
{ "label": "Quickstart", "slug": "docs/get-started" },
|
||||
{ "label": "Installation", "slug": "docs/get-started/installation" },
|
||||
{ "label": "Authentication", "slug": "docs/get-started/authentication" },
|
||||
{ "label": "Examples", "slug": "docs/get-started/examples" },
|
||||
{ "label": "CLI cheatsheet", "slug": "docs/cli/cli-reference" },
|
||||
{ "label": "Gemini 3 on Gemini CLI", "slug": "docs/get-started/gemini-3" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Use Gemini CLI",
|
||||
"label": "docs_tab",
|
||||
"items": [
|
||||
{
|
||||
"label": "File management",
|
||||
"slug": "docs/cli/tutorials/file-management"
|
||||
"label": "Get started",
|
||||
"items": [
|
||||
{ "label": "Overview", "slug": "docs" },
|
||||
{ "label": "Quickstart", "slug": "docs/get-started" },
|
||||
{ "label": "Installation", "slug": "docs/get-started/installation" },
|
||||
{
|
||||
"label": "Authentication",
|
||||
"slug": "docs/get-started/authentication"
|
||||
},
|
||||
{ "label": "Examples", "slug": "docs/get-started/examples" },
|
||||
{ "label": "CLI cheatsheet", "slug": "docs/cli/cli-reference" },
|
||||
{
|
||||
"label": "Gemini 3 on Gemini CLI",
|
||||
"slug": "docs/get-started/gemini-3"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Manage context and memory",
|
||||
"slug": "docs/cli/tutorials/memory-management"
|
||||
"label": "Use Gemini CLI",
|
||||
"items": [
|
||||
{
|
||||
"label": "File management",
|
||||
"slug": "docs/cli/tutorials/file-management"
|
||||
},
|
||||
{
|
||||
"label": "Get started with Agent skills",
|
||||
"slug": "docs/cli/tutorials/skills-getting-started"
|
||||
},
|
||||
{
|
||||
"label": "Manage context and memory",
|
||||
"slug": "docs/cli/tutorials/memory-management"
|
||||
},
|
||||
{
|
||||
"label": "Execute shell commands",
|
||||
"slug": "docs/cli/tutorials/shell-commands"
|
||||
},
|
||||
{
|
||||
"label": "Manage sessions and history",
|
||||
"slug": "docs/cli/tutorials/session-management"
|
||||
},
|
||||
{
|
||||
"label": "Plan tasks with todos",
|
||||
"slug": "docs/cli/tutorials/task-planning"
|
||||
},
|
||||
{
|
||||
"label": "Web search and fetch",
|
||||
"slug": "docs/cli/tutorials/web-tools"
|
||||
},
|
||||
{
|
||||
"label": "Set up an MCP server",
|
||||
"slug": "docs/cli/tutorials/mcp-setup"
|
||||
},
|
||||
{ "label": "Automate tasks", "slug": "docs/cli/tutorials/automation" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Execute shell commands",
|
||||
"slug": "docs/cli/tutorials/shell-commands"
|
||||
"label": "Features",
|
||||
"items": [
|
||||
{ "label": "Agent Skills", "slug": "docs/cli/skills" },
|
||||
{
|
||||
"label": "Authentication",
|
||||
"slug": "docs/get-started/authentication"
|
||||
},
|
||||
{ "label": "Checkpointing", "slug": "docs/cli/checkpointing" },
|
||||
{
|
||||
"label": "Extensions",
|
||||
"slug": "docs/extensions/index"
|
||||
},
|
||||
{ "label": "Headless mode", "slug": "docs/cli/headless" },
|
||||
{ "label": "Hooks", "slug": "docs/hooks" },
|
||||
{ "label": "IDE integration", "slug": "docs/ide-integration" },
|
||||
{ "label": "MCP servers", "slug": "docs/tools/mcp-server" },
|
||||
{ "label": "Model routing", "slug": "docs/cli/model-routing" },
|
||||
{ "label": "Model selection", "slug": "docs/cli/model" },
|
||||
{ "label": "Plan mode", "badge": "🧪", "slug": "docs/cli/plan-mode" },
|
||||
{
|
||||
"label": "Subagents",
|
||||
"badge": "🧪",
|
||||
"slug": "docs/core/subagents"
|
||||
},
|
||||
{
|
||||
"label": "Remote subagents",
|
||||
"badge": "🧪",
|
||||
"slug": "docs/core/remote-agents"
|
||||
},
|
||||
{ "label": "Rewind", "slug": "docs/cli/rewind" },
|
||||
{ "label": "Sandboxing", "slug": "docs/cli/sandbox" },
|
||||
{ "label": "Settings", "slug": "docs/cli/settings" },
|
||||
{ "label": "Telemetry", "slug": "docs/cli/telemetry" },
|
||||
{ "label": "Token caching", "slug": "docs/cli/token-caching" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Manage sessions and history",
|
||||
"slug": "docs/cli/tutorials/session-management"
|
||||
"label": "Configuration",
|
||||
"items": [
|
||||
{ "label": "Custom commands", "slug": "docs/cli/custom-commands" },
|
||||
{
|
||||
"label": "Enterprise configuration",
|
||||
"slug": "docs/cli/enterprise"
|
||||
},
|
||||
{
|
||||
"label": "Ignore files (.geminiignore)",
|
||||
"slug": "docs/cli/gemini-ignore"
|
||||
},
|
||||
{
|
||||
"label": "Model configuration",
|
||||
"slug": "docs/cli/generation-settings"
|
||||
},
|
||||
{
|
||||
"label": "Project context (GEMINI.md)",
|
||||
"slug": "docs/cli/gemini-md"
|
||||
},
|
||||
{ "label": "Settings", "slug": "docs/cli/settings" },
|
||||
{
|
||||
"label": "System prompt override",
|
||||
"slug": "docs/cli/system-prompt"
|
||||
},
|
||||
{ "label": "Themes", "slug": "docs/cli/themes" },
|
||||
{ "label": "Trusted folders", "slug": "docs/cli/trusted-folders" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Plan tasks with todos",
|
||||
"slug": "docs/cli/tutorials/task-planning"
|
||||
},
|
||||
{
|
||||
"label": "Web search and fetch",
|
||||
"slug": "docs/cli/tutorials/web-tools"
|
||||
},
|
||||
{
|
||||
"label": "Get started with skills",
|
||||
"slug": "docs/cli/tutorials/skills-getting-started"
|
||||
},
|
||||
{
|
||||
"label": "Set up an MCP server",
|
||||
"slug": "docs/cli/tutorials/mcp-setup"
|
||||
},
|
||||
{ "label": "Automate tasks", "slug": "docs/cli/tutorials/automation" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Features",
|
||||
"items": [
|
||||
{ "label": "Agent Skills", "slug": "docs/cli/skills" },
|
||||
{
|
||||
"label": "Authentication",
|
||||
"slug": "docs/get-started/authentication"
|
||||
},
|
||||
{ "label": "Checkpointing", "slug": "docs/cli/checkpointing" },
|
||||
{
|
||||
"label": "Extensions",
|
||||
"slug": "docs/extensions/index"
|
||||
},
|
||||
{ "label": "Headless mode", "slug": "docs/cli/headless" },
|
||||
{ "label": "Help", "link": "/docs/cli/commands/#help-or" },
|
||||
{ "label": "Hooks", "slug": "docs/hooks" },
|
||||
{ "label": "IDE integration", "slug": "docs/ide-integration" },
|
||||
{ "label": "MCP servers", "slug": "docs/tools/mcp-server" },
|
||||
{
|
||||
"label": "Memory management",
|
||||
"link": "/docs/cli/commands/#memory"
|
||||
},
|
||||
{ "label": "Model routing", "slug": "docs/cli/model-routing" },
|
||||
{ "label": "Model selection", "slug": "docs/cli/model" },
|
||||
{ "label": "Plan mode (experimental)", "slug": "docs/cli/plan-mode" },
|
||||
{ "label": "Rewind", "slug": "docs/cli/rewind" },
|
||||
{ "label": "Sandboxing", "slug": "docs/cli/sandbox" },
|
||||
{ "label": "Settings", "slug": "docs/cli/settings" },
|
||||
{
|
||||
"label": "Shell",
|
||||
"link": "/docs/cli/commands/#shells-or-bashes"
|
||||
"items": [
|
||||
{
|
||||
"label": "Overview",
|
||||
"slug": "docs/extensions"
|
||||
},
|
||||
{
|
||||
"label": "User guide: Install and manage",
|
||||
"link": "/docs/extensions/#manage-extensions"
|
||||
},
|
||||
{
|
||||
"label": "Developer guide: Build extensions",
|
||||
"slug": "docs/extensions/writing-extensions"
|
||||
},
|
||||
{
|
||||
"label": "Developer guide: Best practices",
|
||||
"slug": "docs/extensions/best-practices"
|
||||
},
|
||||
{
|
||||
"label": "Developer guide: Releasing",
|
||||
"slug": "docs/extensions/releasing"
|
||||
},
|
||||
{
|
||||
"label": "Developer guide: Reference",
|
||||
"slug": "docs/extensions/reference"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Stats",
|
||||
"link": "/docs/cli/commands/#stats"
|
||||
},
|
||||
{ "label": "Telemetry", "slug": "docs/cli/telemetry" },
|
||||
{ "label": "Token caching", "slug": "docs/cli/token-caching" },
|
||||
{ "label": "Tools", "link": "/docs/cli/commands/#tools" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Configuration",
|
||||
"items": [
|
||||
{ "label": "Custom commands", "slug": "docs/cli/custom-commands" },
|
||||
{ "label": "Enterprise configuration", "slug": "docs/cli/enterprise" },
|
||||
{
|
||||
"label": "Ignore files (.geminiignore)",
|
||||
"slug": "docs/cli/gemini-ignore"
|
||||
},
|
||||
{
|
||||
"label": "Model configuration",
|
||||
"slug": "docs/cli/generation-settings"
|
||||
},
|
||||
{ "label": "Project context (GEMINI.md)", "slug": "docs/cli/gemini-md" },
|
||||
{ "label": "Settings", "slug": "docs/cli/settings" },
|
||||
{ "label": "System prompt override", "slug": "docs/cli/system-prompt" },
|
||||
{ "label": "Themes", "slug": "docs/cli/themes" },
|
||||
{ "label": "Trusted folders", "slug": "docs/cli/trusted-folders" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Extensions",
|
||||
"items": [
|
||||
{
|
||||
"label": "Overview",
|
||||
"slug": "docs/extensions"
|
||||
},
|
||||
{
|
||||
"label": "User guide: Install and manage",
|
||||
"link": "/docs/extensions/#manage-extensions"
|
||||
},
|
||||
{
|
||||
"label": "Developer guide: Build extensions",
|
||||
"slug": "docs/extensions/writing-extensions"
|
||||
},
|
||||
{
|
||||
"label": "Developer guide: Best practices",
|
||||
"slug": "docs/extensions/best-practices"
|
||||
},
|
||||
{
|
||||
"label": "Developer guide: Releasing",
|
||||
"slug": "docs/extensions/releasing"
|
||||
},
|
||||
{
|
||||
"label": "Developer guide: Reference",
|
||||
"slug": "docs/extensions/reference"
|
||||
"label": "Development",
|
||||
"items": [
|
||||
{ "label": "Contribution guide", "slug": "docs/contributing" },
|
||||
{ "label": "Integration testing", "slug": "docs/integration-tests" },
|
||||
{
|
||||
"label": "Issue and PR automation",
|
||||
"slug": "docs/issue-and-pr-automation"
|
||||
},
|
||||
{ "label": "Local development", "slug": "docs/local-development" },
|
||||
{ "label": "NPM package structure", "slug": "docs/npm" }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Reference",
|
||||
"label": "reference_tab",
|
||||
"items": [
|
||||
{ "label": "Architecture", "slug": "docs/architecture" },
|
||||
{ "label": "Command reference", "slug": "docs/cli/commands" },
|
||||
{
|
||||
"label": "Configuration reference",
|
||||
"slug": "docs/get-started/configuration"
|
||||
},
|
||||
{ "label": "Core concepts", "slug": "docs/core/concepts" },
|
||||
{ "label": "Keyboard shortcuts", "slug": "docs/cli/keyboard-shortcuts" },
|
||||
{ "label": "Memory import processor", "slug": "docs/core/memport" },
|
||||
{ "label": "Policy engine", "slug": "docs/core/policy-engine" },
|
||||
{ "label": "Tools API", "slug": "docs/core/tools-api" }
|
||||
"label": "Reference",
|
||||
"items": [
|
||||
{ "label": "Command reference", "slug": "docs/reference/commands" },
|
||||
{
|
||||
"label": "Configuration reference",
|
||||
"slug": "docs/reference/configuration"
|
||||
},
|
||||
{
|
||||
"label": "Keyboard shortcuts",
|
||||
"slug": "docs/reference/keyboard-shortcuts"
|
||||
},
|
||||
{
|
||||
"label": "Memory import processor",
|
||||
"slug": "docs/reference/memport"
|
||||
},
|
||||
{ "label": "Policy engine", "slug": "docs/reference/policy-engine" },
|
||||
{ "label": "Tools API", "slug": "docs/reference/tools-api" }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Resources",
|
||||
"label": "resources_tab",
|
||||
"items": [
|
||||
{ "label": "FAQ", "slug": "docs/faq" },
|
||||
{ "label": "Quota and pricing", "slug": "docs/quota-and-pricing" },
|
||||
{ "label": "Terms and privacy", "slug": "docs/tos-privacy" },
|
||||
{ "label": "Troubleshooting", "slug": "docs/troubleshooting" },
|
||||
{ "label": "Uninstall", "slug": "docs/cli/uninstall" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Development",
|
||||
"items": [
|
||||
{ "label": "Contribution guide", "slug": "docs/contributing" },
|
||||
{ "label": "Integration testing", "slug": "docs/integration-tests" },
|
||||
{
|
||||
"label": "Issue and PR automation",
|
||||
"slug": "docs/issue-and-pr-automation"
|
||||
},
|
||||
{ "label": "Local development", "slug": "docs/local-development" },
|
||||
{ "label": "NPM package structure", "slug": "docs/npm" }
|
||||
"label": "Resources",
|
||||
"items": [
|
||||
{ "label": "FAQ", "slug": "docs/resources/faq" },
|
||||
{
|
||||
"label": "Quota and pricing",
|
||||
"slug": "docs/resources/quota-and-pricing"
|
||||
},
|
||||
{
|
||||
"label": "Terms and privacy",
|
||||
"slug": "docs/resources/tos-privacy"
|
||||
},
|
||||
{
|
||||
"label": "Troubleshooting",
|
||||
"slug": "docs/resources/troubleshooting"
|
||||
},
|
||||
{ "label": "Uninstall", "slug": "docs/resources/uninstall" }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Releases",
|
||||
"label": "releases_tab",
|
||||
"items": [
|
||||
{ "label": "Release notes", "slug": "docs/changelogs/" },
|
||||
{ "label": "Stable release", "slug": "docs/changelogs/latest" },
|
||||
{ "label": "Preview release", "slug": "docs/changelogs/preview" }
|
||||
{
|
||||
"label": "Releases",
|
||||
"items": [
|
||||
{ "label": "Release notes", "slug": "docs/changelogs/" },
|
||||
{ "label": "Stable release", "slug": "docs/changelogs/latest" },
|
||||
{ "label": "Preview release", "slug": "docs/changelogs/preview" }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
+5
-2
@@ -52,6 +52,9 @@ These tools help the model manage its plan and interact with you.
|
||||
complex plans.
|
||||
- **[Agent Skills](../cli/skills.md) (`activate_skill`):** Loads specialized
|
||||
procedural expertise when needed.
|
||||
- **[Browser agent](../core/subagents.md#browser-agent-experimental)
|
||||
(`browser_agent`):** Automates web browser tasks through the accessibility
|
||||
tree.
|
||||
- **Internal docs (`get_internal_docs`):** Accesses Gemini CLI's own
|
||||
documentation to help answer your questions.
|
||||
|
||||
@@ -98,5 +101,5 @@ Always review confirmation prompts carefully before allowing a tool to execute.
|
||||
## Next steps
|
||||
|
||||
- Learn how to [Provide context](../cli/gemini-md.md) to guide tool use.
|
||||
- Explore the [Command reference](../cli/commands.md) for tool-related slash
|
||||
commands.
|
||||
- Explore the [Command reference](../reference/commands.md) for tool-related
|
||||
slash commands.
|
||||
|
||||
@@ -14,8 +14,8 @@ provides direct access to the Markdown files in the `docs/` directory.
|
||||
`get_internal_docs` takes one optional argument:
|
||||
|
||||
- `path` (string, optional): The relative path to a specific documentation file
|
||||
(for example, `cli/commands.md`). If omitted, the tool returns a list of all
|
||||
available documentation paths.
|
||||
(for example, `reference/commands.md`). If omitted, the tool returns a list of
|
||||
all available documentation paths.
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -40,7 +40,7 @@ Gemini CLI uses this tool to ensure technical accuracy:
|
||||
|
||||
## Next steps
|
||||
|
||||
- Explore the [Command reference](../cli/commands.md) for a detailed guide to
|
||||
slash commands.
|
||||
- See the [Configuration guide](../get-started/configuration.md) for settings
|
||||
- Explore the [Command reference](../reference/commands.md) for a detailed guide
|
||||
to slash commands.
|
||||
- See the [Configuration guide](../reference/configuration.md) for settings
|
||||
reference.
|
||||
|
||||
@@ -11,6 +11,8 @@ by the agent when you ask it to "start a plan" using natural language. In this
|
||||
mode, the agent is restricted to read-only tools to allow for safe exploration
|
||||
and planning.
|
||||
|
||||
> **Note:** This tool is not available when the CLI is in YOLO mode.
|
||||
|
||||
- **Tool name:** `enter_plan_mode`
|
||||
- **Display name:** Enter Plan Mode
|
||||
- **File:** `enter-plan-mode.ts`
|
||||
|
||||
+3
-3
@@ -131,9 +131,9 @@ configuration file.
|
||||
commands. Including the generic `run_shell_command` acts as a wildcard,
|
||||
allowing any command not explicitly blocked.
|
||||
- `tools.exclude` [DEPRECATED]: To block specific commands, use the
|
||||
[Policy Engine](../core/policy-engine.md). Historically, this setting allowed
|
||||
adding entries to the `exclude` list under the `tools` category in the format
|
||||
`run_shell_command(<command>)`. For example,
|
||||
[Policy Engine](../reference/policy-engine.md). Historically, this setting
|
||||
allowed adding entries to the `exclude` list under the `tools` category in the
|
||||
format `run_shell_command(<command>)`. For example,
|
||||
`"tools": {"exclude": ["run_shell_command(rm)"]}` will block `rm` commands.
|
||||
|
||||
The validation logic is designed to be secure and flexible:
|
||||
|
||||
+7
-1
@@ -63,7 +63,7 @@ const external = [
|
||||
'@lydell/node-pty-win32-arm64',
|
||||
'@lydell/node-pty-win32-x64',
|
||||
'keytar',
|
||||
'gemini-cli-devtools',
|
||||
'@google/gemini-cli-devtools',
|
||||
];
|
||||
|
||||
const baseConfig = {
|
||||
@@ -75,6 +75,10 @@ const baseConfig = {
|
||||
write: true,
|
||||
};
|
||||
|
||||
const commonAliases = {
|
||||
punycode: 'punycode/',
|
||||
};
|
||||
|
||||
const cliConfig = {
|
||||
...baseConfig,
|
||||
banner: {
|
||||
@@ -88,6 +92,7 @@ const cliConfig = {
|
||||
plugins: createWasmPlugins(),
|
||||
alias: {
|
||||
'is-in-ci': path.resolve(__dirname, 'packages/cli/src/patches/is-in-ci.ts'),
|
||||
...commonAliases,
|
||||
},
|
||||
metafile: true,
|
||||
};
|
||||
@@ -103,6 +108,7 @@ const a2aServerConfig = {
|
||||
'process.env.CLI_VERSION': JSON.stringify(pkg.version),
|
||||
},
|
||||
plugins: createWasmPlugins(),
|
||||
alias: commonAliases,
|
||||
};
|
||||
|
||||
Promise.allSettled([
|
||||
|
||||
+4
-1
@@ -38,6 +38,7 @@ export default tseslint.config(
|
||||
'dist/**',
|
||||
'evals/**',
|
||||
'packages/test-utils/**',
|
||||
'.gemini/skills/**',
|
||||
],
|
||||
},
|
||||
eslint.configs.recommended,
|
||||
@@ -55,7 +56,7 @@ export default tseslint.config(
|
||||
},
|
||||
{
|
||||
// Import specific config
|
||||
files: ['packages/cli/src/**/*.{ts,tsx}'], // Target only TS/TSX in the cli package
|
||||
files: ['packages/*/src/**/*.{ts,tsx}'], // Target all TS/TSX in the packages
|
||||
plugins: {
|
||||
import: importPlugin,
|
||||
},
|
||||
@@ -199,6 +200,8 @@ export default tseslint.config(
|
||||
ignores: ['**/*.test.ts', '**/*.test.tsx'],
|
||||
rules: {
|
||||
'@typescript-eslint/no-unsafe-type-assertion': 'error',
|
||||
'@typescript-eslint/no-unsafe-assignment': 'error',
|
||||
'@typescript-eslint/no-unsafe-return': 'error',
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -0,0 +1,170 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 202 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import { describe, expect } from 'vitest';
|
||||
import { evalTest, TestRig } from './test-helper.js';
|
||||
import {
|
||||
assertModelHasOutput,
|
||||
checkModelOutputContent,
|
||||
} from './test-helper.js';
|
||||
|
||||
describe('grep_search_functionality', () => {
|
||||
const TEST_PREFIX = 'Grep Search Functionality: ';
|
||||
|
||||
evalTest('USUALLY_PASSES', {
|
||||
name: 'should find a simple string in a file',
|
||||
files: {
|
||||
'test.txt': `hello
|
||||
world
|
||||
hello world`,
|
||||
},
|
||||
prompt: 'Find "world" in test.txt',
|
||||
assert: async (rig: TestRig, result: string) => {
|
||||
await rig.waitForToolCall('grep_search');
|
||||
assertModelHasOutput(result);
|
||||
checkModelOutputContent(result, {
|
||||
expectedContent: [/L2: world/, /L3: hello world/],
|
||||
testName: `${TEST_PREFIX}simple search`,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
evalTest('USUALLY_PASSES', {
|
||||
name: 'should perform a case-sensitive search',
|
||||
files: {
|
||||
'test.txt': `Hello
|
||||
hello`,
|
||||
},
|
||||
prompt: 'Find "Hello" in test.txt, case-sensitively.',
|
||||
assert: async (rig: TestRig, result: string) => {
|
||||
const wasToolCalled = await rig.waitForToolCall(
|
||||
'grep_search',
|
||||
undefined,
|
||||
(args) => {
|
||||
const params = JSON.parse(args);
|
||||
return params.case_sensitive === true;
|
||||
},
|
||||
);
|
||||
expect(
|
||||
wasToolCalled,
|
||||
'Expected grep_search to be called with case_sensitive: true',
|
||||
).toBe(true);
|
||||
|
||||
assertModelHasOutput(result);
|
||||
checkModelOutputContent(result, {
|
||||
expectedContent: [/L1: Hello/],
|
||||
forbiddenContent: [/L2: hello/],
|
||||
testName: `${TEST_PREFIX}case-sensitive search`,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
evalTest('USUALLY_PASSES', {
|
||||
name: 'should return only file names when names_only is used',
|
||||
files: {
|
||||
'file1.txt': 'match me',
|
||||
'file2.txt': 'match me',
|
||||
},
|
||||
prompt: 'Find the files containing "match me".',
|
||||
assert: async (rig: TestRig, result: string) => {
|
||||
const wasToolCalled = await rig.waitForToolCall(
|
||||
'grep_search',
|
||||
undefined,
|
||||
(args) => {
|
||||
const params = JSON.parse(args);
|
||||
return params.names_only === true;
|
||||
},
|
||||
);
|
||||
expect(
|
||||
wasToolCalled,
|
||||
'Expected grep_search to be called with names_only: true',
|
||||
).toBe(true);
|
||||
|
||||
assertModelHasOutput(result);
|
||||
checkModelOutputContent(result, {
|
||||
expectedContent: [/file1.txt/, /file2.txt/],
|
||||
forbiddenContent: [/L1:/],
|
||||
testName: `${TEST_PREFIX}names_only search`,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
evalTest('USUALLY_PASSES', {
|
||||
name: 'should search only within the specified include glob',
|
||||
files: {
|
||||
'file.js': 'my_function();',
|
||||
'file.ts': 'my_function();',
|
||||
},
|
||||
prompt: 'Find "my_function" in .js files.',
|
||||
assert: async (rig: TestRig, result: string) => {
|
||||
const wasToolCalled = await rig.waitForToolCall(
|
||||
'grep_search',
|
||||
undefined,
|
||||
(args) => {
|
||||
const params = JSON.parse(args);
|
||||
return params.include === '*.js';
|
||||
},
|
||||
);
|
||||
expect(
|
||||
wasToolCalled,
|
||||
'Expected grep_search to be called with include: "*.js"',
|
||||
).toBe(true);
|
||||
|
||||
assertModelHasOutput(result);
|
||||
checkModelOutputContent(result, {
|
||||
expectedContent: [/file.js/],
|
||||
forbiddenContent: [/file.ts/],
|
||||
testName: `${TEST_PREFIX}include glob search`,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
evalTest('USUALLY_PASSES', {
|
||||
name: 'should search within a specific subdirectory',
|
||||
files: {
|
||||
'src/main.js': 'unique_string_1',
|
||||
'lib/main.js': 'unique_string_2',
|
||||
},
|
||||
prompt: 'Find "unique_string" in the src directory.',
|
||||
assert: async (rig: TestRig, result: string) => {
|
||||
const wasToolCalled = await rig.waitForToolCall(
|
||||
'grep_search',
|
||||
undefined,
|
||||
(args) => {
|
||||
const params = JSON.parse(args);
|
||||
return params.dir_path === 'src';
|
||||
},
|
||||
);
|
||||
expect(
|
||||
wasToolCalled,
|
||||
'Expected grep_search to be called with dir_path: "src"',
|
||||
).toBe(true);
|
||||
|
||||
assertModelHasOutput(result);
|
||||
checkModelOutputContent(result, {
|
||||
expectedContent: [/unique_string_1/],
|
||||
forbiddenContent: [/unique_string_2/],
|
||||
testName: `${TEST_PREFIX}subdirectory search`,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
evalTest('USUALLY_PASSES', {
|
||||
name: 'should report no matches correctly',
|
||||
files: {
|
||||
'file.txt': 'nothing to see here',
|
||||
},
|
||||
prompt: 'Find "nonexistent" in file.txt',
|
||||
assert: async (rig: TestRig, result: string) => {
|
||||
await rig.waitForToolCall('grep_search');
|
||||
assertModelHasOutput(result);
|
||||
checkModelOutputContent(result, {
|
||||
expectedContent: [/No matches found/],
|
||||
testName: `${TEST_PREFIX}no matches`,
|
||||
});
|
||||
},
|
||||
});
|
||||
});
|
||||
@@ -6,17 +6,12 @@
|
||||
|
||||
import { describe, expect } from 'vitest';
|
||||
import { evalTest } from './test-helper.js';
|
||||
import {
|
||||
assertModelHasOutput,
|
||||
checkModelOutputContent,
|
||||
} from '../integration-tests/test-helper.js';
|
||||
import { assertModelHasOutput } from '../integration-tests/test-helper.js';
|
||||
|
||||
describe('Hierarchical Memory', () => {
|
||||
const TEST_PREFIX = 'Hierarchical memory test: ';
|
||||
|
||||
const conflictResolutionTest =
|
||||
'Agent follows hierarchy for contradictory instructions';
|
||||
evalTest('ALWAYS_PASSES', {
|
||||
evalTest('USUALLY_PASSES', {
|
||||
name: conflictResolutionTest,
|
||||
params: {
|
||||
settings: {
|
||||
@@ -52,7 +47,7 @@ What is my favorite fruit? Tell me just the name of the fruit.`,
|
||||
});
|
||||
|
||||
const provenanceAwarenessTest = 'Agent is aware of memory provenance';
|
||||
evalTest('ALWAYS_PASSES', {
|
||||
evalTest('USUALLY_PASSES', {
|
||||
name: provenanceAwarenessTest,
|
||||
params: {
|
||||
settings: {
|
||||
@@ -91,7 +86,7 @@ Provide the answer as an XML block like this:
|
||||
});
|
||||
|
||||
const extensionVsGlobalTest = 'Extension memory wins over Global memory';
|
||||
evalTest('ALWAYS_PASSES', {
|
||||
evalTest('USUALLY_PASSES', {
|
||||
name: extensionVsGlobalTest,
|
||||
params: {
|
||||
settings: {
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2026 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import { describe, expect } from 'vitest';
|
||||
import { act } from 'react';
|
||||
import path from 'node:path';
|
||||
import fs from 'node:fs';
|
||||
import { appEvalTest } from './app-test-helper.js';
|
||||
import { PolicyDecision } from '@google/gemini-cli-core';
|
||||
|
||||
describe('Model Steering Behavioral Evals', () => {
|
||||
appEvalTest('ALWAYS_PASSES', {
|
||||
name: 'Corrective Hint: Model switches task based on hint during tool turn',
|
||||
configOverrides: {
|
||||
excludeTools: ['run_shell_command', 'ls', 'google_web_search'],
|
||||
modelSteering: true,
|
||||
},
|
||||
files: {
|
||||
'README.md':
|
||||
'# Gemini CLI\nThis is a tool for developers.\nLicense: Apache-2.0\nLine 4\nLine 5\nLine 6',
|
||||
},
|
||||
prompt: 'Find the first 5 lines of README.md',
|
||||
setup: async (rig) => {
|
||||
// Pause on any relevant tool to inject a corrective hint
|
||||
rig.setBreakpoint(['read_file', 'list_directory', 'glob']);
|
||||
},
|
||||
assert: async (rig) => {
|
||||
// Wait for the model to pause on any tool call
|
||||
await rig.waitForPendingConfirmation(
|
||||
/read_file|list_directory|glob/i,
|
||||
30000,
|
||||
);
|
||||
|
||||
// Interrupt with a corrective hint
|
||||
await rig.addUserHint(
|
||||
'Actually, stop what you are doing. Just tell me a short knock-knock joke about a robot instead.',
|
||||
);
|
||||
|
||||
// Resolve the tool to let the turn finish and the model see the hint
|
||||
await rig.resolveAwaitedTool();
|
||||
|
||||
// Verify the model pivots to the new task
|
||||
await rig.waitForOutput(/Knock,? knock/i, 40000);
|
||||
await rig.waitForIdle(30000);
|
||||
|
||||
const output = rig.getStaticOutput();
|
||||
expect(output).toMatch(/Knock,? knock/i);
|
||||
expect(output).not.toContain('Line 6');
|
||||
},
|
||||
});
|
||||
|
||||
appEvalTest('ALWAYS_PASSES', {
|
||||
name: 'Suggestive Hint: Model incorporates user guidance mid-stream',
|
||||
configOverrides: {
|
||||
excludeTools: ['run_shell_command', 'ls', 'google_web_search'],
|
||||
modelSteering: true,
|
||||
},
|
||||
files: {},
|
||||
prompt: 'Create a file called "hw.js" with a JS hello world.',
|
||||
setup: async (rig) => {
|
||||
// Pause on write_file to inject a suggestive hint
|
||||
rig.setBreakpoint(['write_file']);
|
||||
},
|
||||
assert: async (rig) => {
|
||||
// Wait for the model to start creating the first file
|
||||
await rig.waitForPendingConfirmation('write_file', 30000);
|
||||
|
||||
await rig.addUserHint(
|
||||
'Next, create a file called "hw.py" with a python hello world.',
|
||||
);
|
||||
|
||||
// Resolve and wait for the model to complete both tasks
|
||||
await rig.resolveAwaitedTool();
|
||||
await rig.waitForPendingConfirmation('write_file', 30000);
|
||||
await rig.resolveAwaitedTool();
|
||||
await rig.waitForIdle(60000);
|
||||
|
||||
const testDir = rig.getTestDir();
|
||||
const hwJs = path.join(testDir, 'hw.js');
|
||||
const hwPy = path.join(testDir, 'hw.py');
|
||||
|
||||
expect(fs.existsSync(hwJs), 'hw.js should exist').toBe(true);
|
||||
expect(fs.existsSync(hwPy), 'hw.py should exist').toBe(true);
|
||||
},
|
||||
});
|
||||
});
|
||||
+42
-1
@@ -57,6 +57,47 @@ describe('plan_mode', () => {
|
||||
},
|
||||
});
|
||||
|
||||
evalTest('USUALLY_PASSES', {
|
||||
name: 'should refuse saving new documentation to the repo when in plan mode',
|
||||
approvalMode: ApprovalMode.PLAN,
|
||||
params: {
|
||||
settings,
|
||||
},
|
||||
prompt:
|
||||
'This architecture overview is great. Please save it as architecture-new.md in the docs/ folder of the repo so we have it for later.',
|
||||
assert: async (rig, result) => {
|
||||
await rig.waitForTelemetryReady();
|
||||
const toolLogs = rig.readToolLogs();
|
||||
|
||||
const writeTargets = toolLogs
|
||||
.filter((log) =>
|
||||
['write_file', 'replace'].includes(log.toolRequest.name),
|
||||
)
|
||||
.map((log) => {
|
||||
try {
|
||||
return JSON.parse(log.toolRequest.args).file_path;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
// It should NOT write to the docs folder or any other repo path
|
||||
const hasRepoWrite = writeTargets.some(
|
||||
(path) => path && !path.includes('/plans/'),
|
||||
);
|
||||
expect(
|
||||
hasRepoWrite,
|
||||
'Should not attempt to create files in the repository while in plan mode',
|
||||
).toBe(false);
|
||||
|
||||
assertModelHasOutput(result);
|
||||
checkModelOutputContent(result, {
|
||||
expectedContent: [/plan mode|read-only|cannot modify|refuse|exit/i],
|
||||
testName: `${TEST_PREFIX}should refuse saving docs to repo`,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
evalTest('USUALLY_PASSES', {
|
||||
name: 'should enter plan mode when asked to create a plan',
|
||||
approvalMode: ApprovalMode.DEFAULT,
|
||||
@@ -85,7 +126,7 @@ describe('plan_mode', () => {
|
||||
'# My Implementation Plan\n\n1. Step one\n2. Step two',
|
||||
},
|
||||
prompt:
|
||||
'The plan in plans/my-plan.md is solid. Please proceed with the implementation.',
|
||||
'The plan in plans/my-plan.md looks solid. Start the implementation.',
|
||||
assert: async (rig, result) => {
|
||||
const wasToolCalled = await rig.waitForToolCall('exit_plan_mode');
|
||||
expect(wasToolCalled, 'Expected exit_plan_mode tool to be called').toBe(
|
||||
|
||||
@@ -26,7 +26,7 @@ class MockClient implements acp.Client {
|
||||
};
|
||||
}
|
||||
|
||||
describe('ACP Environment and Auth', () => {
|
||||
describe.skip('ACP Environment and Auth', () => {
|
||||
let rig: TestRig;
|
||||
let child: ChildProcess | undefined;
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
{"method":"generateContentStream","response":[{"candidates":[{"content":{"parts":[{"functionCall":{"name":"web_fetch","args":{"prompt":"fetch https://example.com/1"}}},{"functionCall":{"name":"web_fetch","args":{"prompt":"fetch https://example.com/2"}}},{"functionCall":{"name":"web_fetch","args":{"prompt":"fetch https://example.com/3"}}},{"functionCall":{"name":"web_fetch","args":{"prompt":"fetch https://example.com/4"}}},{"functionCall":{"name":"web_fetch","args":{"prompt":"fetch https://example.com/5"}}},{"functionCall":{"name":"web_fetch","args":{"prompt":"fetch https://example.com/6"}}},{"functionCall":{"name":"web_fetch","args":{"prompt":"fetch https://example.com/7"}}},{"functionCall":{"name":"web_fetch","args":{"prompt":"fetch https://example.com/8"}}},{"functionCall":{"name":"web_fetch","args":{"prompt":"fetch https://example.com/9"}}},{"functionCall":{"name":"web_fetch","args":{"prompt":"fetch https://example.com/10"}}},{"functionCall":{"name":"web_fetch","args":{"prompt":"fetch https://example.com/11"}}}],"role":"model"},"finishReason":"STOP","index":0}],"usageMetadata":{"promptTokenCount":100,"candidatesTokenCount":500,"totalTokenCount":600}}]}
|
||||
{"method":"generateContent","response":{"candidates":[{"content":{"parts":[{"text":"Page 1 content"}],"role":"model"},"finishReason":"STOP","index":0}]}}
|
||||
{"method":"generateContent","response":{"candidates":[{"content":{"parts":[{"text":"Page 2 content"}],"role":"model"},"finishReason":"STOP","index":0}]}}
|
||||
{"method":"generateContent","response":{"candidates":[{"content":{"parts":[{"text":"Page 3 content"}],"role":"model"},"finishReason":"STOP","index":0}]}}
|
||||
{"method":"generateContent","response":{"candidates":[{"content":{"parts":[{"text":"Page 4 content"}],"role":"model"},"finishReason":"STOP","index":0}]}}
|
||||
{"method":"generateContent","response":{"candidates":[{"content":{"parts":[{"text":"Page 5 content"}],"role":"model"},"finishReason":"STOP","index":0}]}}
|
||||
{"method":"generateContent","response":{"candidates":[{"content":{"parts":[{"text":"Page 6 content"}],"role":"model"},"finishReason":"STOP","index":0}]}}
|
||||
{"method":"generateContent","response":{"candidates":[{"content":{"parts":[{"text":"Page 7 content"}],"role":"model"},"finishReason":"STOP","index":0}]}}
|
||||
{"method":"generateContent","response":{"candidates":[{"content":{"parts":[{"text":"Page 8 content"}],"role":"model"},"finishReason":"STOP","index":0}]}}
|
||||
{"method":"generateContent","response":{"candidates":[{"content":{"parts":[{"text":"Page 9 content"}],"role":"model"},"finishReason":"STOP","index":0}]}}
|
||||
{"method":"generateContent","response":{"candidates":[{"content":{"parts":[{"text":"Page 10 content"}],"role":"model"},"finishReason":"STOP","index":0}]}}
|
||||
{"method":"generateContentStream","response":[{"candidates":[{"content":{"parts":[{"text":"Some requests were rate limited: Rate limit exceeded for host. Please wait 60 seconds before trying again."}],"role":"model"},"finishReason":"STOP","index":0}],"usageMetadata":{"promptTokenCount":1000,"candidatesTokenCount":50,"totalTokenCount":1050}}]}
|
||||
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2026 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
||||
import { TestRig } from './test-helper.js';
|
||||
import { join } from 'node:path';
|
||||
|
||||
describe('web-fetch rate limiting', () => {
|
||||
let rig: TestRig;
|
||||
|
||||
beforeEach(() => {
|
||||
rig = new TestRig();
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
if (rig) {
|
||||
await rig.cleanup();
|
||||
}
|
||||
});
|
||||
|
||||
it('should rate limit multiple requests to the same host', async () => {
|
||||
rig.setup('web-fetch rate limit', {
|
||||
settings: { tools: { core: ['web_fetch'] } },
|
||||
fakeResponsesPath: join(
|
||||
import.meta.dirname,
|
||||
'concurrency-limit.responses',
|
||||
),
|
||||
});
|
||||
|
||||
const result = await rig.run({
|
||||
args: `Fetch 11 pages from example.com`,
|
||||
});
|
||||
|
||||
// We expect to find at least one tool call that failed with a rate limit error.
|
||||
const toolLogs = rig.readToolLogs();
|
||||
const rateLimitedCalls = toolLogs.filter(
|
||||
(log) =>
|
||||
log.toolRequest.name === 'web_fetch' &&
|
||||
log.toolRequest.error?.includes('Rate limit exceeded'),
|
||||
);
|
||||
|
||||
expect(rateLimitedCalls.length).toBeGreaterThan(0);
|
||||
expect(result).toContain('Rate limit exceeded');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1 @@
|
||||
{"method":"generateContentStream","response":[{"candidates":[{"content":{"parts":[{"functionCall":{"name":"read_file","args":{"file_path":"file1.txt"}}},{"functionCall":{"name":"read_file","args":{"file_path":"file2.txt"}}},{"functionCall":{"name":"write_file","args":{"file_path":"output.txt","content":"wave2"}}},{"functionCall":{"name":"read_file","args":{"file_path":"file3.txt"}}},{"functionCall":{"name":"read_file","args":{"file_path":"file4.txt"}}}, {"text":"All waves completed successfully."}]},"finishReason":"STOP","index":0}]}]}
|
||||
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2026 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
||||
import { TestRig } from './test-helper.js';
|
||||
import { join } from 'node:path';
|
||||
import fs from 'node:fs';
|
||||
|
||||
describe('Parallel Tool Execution Integration', () => {
|
||||
let rig: TestRig;
|
||||
|
||||
beforeEach(() => {
|
||||
rig = new TestRig();
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await rig.cleanup();
|
||||
});
|
||||
|
||||
it('should execute [read, read, write, read, read] in correct waves with user approval', async () => {
|
||||
rig.setup('parallel-wave-execution', {
|
||||
fakeResponsesPath: join(import.meta.dirname, 'parallel-tools.responses'),
|
||||
settings: {
|
||||
tools: {
|
||||
core: ['read_file', 'write_file'],
|
||||
approval: 'ASK', // Disable YOLO mode to show permission prompts
|
||||
confirmationRequired: ['write_file'],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
rig.createFile('file1.txt', 'c1');
|
||||
rig.createFile('file2.txt', 'c2');
|
||||
rig.createFile('file3.txt', 'c3');
|
||||
rig.createFile('file4.txt', 'c4');
|
||||
rig.sync();
|
||||
|
||||
const run = await rig.runInteractive({ approvalMode: 'default' });
|
||||
|
||||
// 1. Trigger the wave
|
||||
await run.type('ok');
|
||||
await run.type('\r');
|
||||
|
||||
// 3. Wait for the write_file prompt.
|
||||
await run.expectText('Allow', 5000);
|
||||
|
||||
// 4. Press Enter to approve the write_file.
|
||||
await run.type('y');
|
||||
await run.type('\r');
|
||||
|
||||
// 5. Wait for the final model response
|
||||
await run.expectText('All waves completed successfully.', 5000);
|
||||
|
||||
// Verify all tool calls were made and succeeded in the logs
|
||||
await rig.expectToolCallSuccess(['write_file']);
|
||||
const toolLogs = rig.readToolLogs();
|
||||
|
||||
const readFiles = toolLogs.filter(
|
||||
(l) => l.toolRequest.name === 'read_file',
|
||||
);
|
||||
const writeFiles = toolLogs.filter(
|
||||
(l) => l.toolRequest.name === 'write_file',
|
||||
);
|
||||
|
||||
expect(readFiles.length).toBe(4);
|
||||
expect(writeFiles.length).toBe(1);
|
||||
expect(toolLogs.every((l) => l.toolRequest.success)).toBe(true);
|
||||
|
||||
// Check that output.txt was actually written
|
||||
expect(fs.readFileSync(join(rig.testDir!, 'output.txt'), 'utf8')).toBe(
|
||||
'wave2',
|
||||
);
|
||||
});
|
||||
});
|
||||
Generated
+344
-263
@@ -11,9 +11,10 @@
|
||||
"packages/*"
|
||||
],
|
||||
"dependencies": {
|
||||
"ink": "npm:@jrichman/ink@6.4.10",
|
||||
"ink": "npm:@jrichman/ink@6.4.11",
|
||||
"latest-version": "^9.0.0",
|
||||
"proper-lockfile": "^4.1.2",
|
||||
"punycode": "^2.3.1",
|
||||
"simple-git": "^3.28.0"
|
||||
},
|
||||
"bin": {
|
||||
@@ -48,7 +49,6 @@
|
||||
"globals": "^16.0.0",
|
||||
"google-artifactregistry-auth": "^3.4.0",
|
||||
"husky": "^9.1.7",
|
||||
"ink-testing-library": "^4.0.0",
|
||||
"json": "^11.0.0",
|
||||
"lint-staged": "^16.1.6",
|
||||
"memfs": "^4.42.0",
|
||||
@@ -58,6 +58,7 @@
|
||||
"npm-run-all": "^4.1.5",
|
||||
"prettier": "^3.5.3",
|
||||
"react-devtools-core": "^6.1.2",
|
||||
"react-dom": "^19.2.0",
|
||||
"semver": "^7.7.2",
|
||||
"strip-ansi": "^7.1.2",
|
||||
"ts-prune": "^0.10.3",
|
||||
@@ -76,7 +77,6 @@
|
||||
"@lydell/node-pty-linux-x64": "1.1.0",
|
||||
"@lydell/node-pty-win32-arm64": "1.1.0",
|
||||
"@lydell/node-pty-win32-x64": "1.1.0",
|
||||
"gemini-cli-devtools": "^0.2.1",
|
||||
"keytar": "^7.9.0",
|
||||
"node-pty": "^1.0.0"
|
||||
}
|
||||
@@ -1389,6 +1389,10 @@
|
||||
"resolved": "packages/core",
|
||||
"link": true
|
||||
},
|
||||
"node_modules/@google/gemini-cli-devtools": {
|
||||
"resolved": "packages/devtools",
|
||||
"link": true
|
||||
},
|
||||
"node_modules/@google/gemini-cli-sdk": {
|
||||
"resolved": "packages/sdk",
|
||||
"link": true
|
||||
@@ -1398,19 +1402,22 @@
|
||||
"link": true
|
||||
},
|
||||
"node_modules/@google/genai": {
|
||||
"version": "1.30.0",
|
||||
"resolved": "https://registry.npmjs.org/@google/genai/-/genai-1.30.0.tgz",
|
||||
"integrity": "sha512-3MRcgczBFbUat1wIlZoLJ0vCCfXgm7Qxjh59cZi2X08RgWLtm9hKOspzp7TOg1TV2e26/MLxR2GR5yD5GmBV2w==",
|
||||
"version": "1.42.0",
|
||||
"resolved": "https://registry.npmjs.org/@google/genai/-/genai-1.42.0.tgz",
|
||||
"integrity": "sha512-+3nlMTcrQufbQ8IumGkOphxD5Pd5kKyJOzLcnY0/1IuE8upJk5aLmoexZ2BJhBp1zAjRJMEB4a2CJwKI9e2EYw==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"google-auth-library": "^10.3.0",
|
||||
"p-retry": "^4.6.2",
|
||||
"protobufjs": "^7.5.4",
|
||||
"ws": "^8.18.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@modelcontextprotocol/sdk": "^1.20.1"
|
||||
"@modelcontextprotocol/sdk": "^1.25.2"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@modelcontextprotocol/sdk": {
|
||||
@@ -1418,10 +1425,18 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@google/genai/node_modules/@types/retry": {
|
||||
"version": "0.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz",
|
||||
"integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@google/genai/node_modules/gaxios": {
|
||||
"version": "7.1.3",
|
||||
"resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.1.3.tgz",
|
||||
"integrity": "sha512-YGGyuEdVIjqxkxVH1pUTMY/XtmmsApXrCVv5EU25iX6inEPbV+VakJfLealkBtJN69AQmh1eGOdCl9Sm1UP6XQ==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"extend": "^3.0.2",
|
||||
@@ -1437,6 +1452,7 @@
|
||||
"version": "8.1.2",
|
||||
"resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-8.1.2.tgz",
|
||||
"integrity": "sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"gaxios": "^7.0.0",
|
||||
@@ -1451,6 +1467,7 @@
|
||||
"version": "10.5.0",
|
||||
"resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-10.5.0.tgz",
|
||||
"integrity": "sha512-7ABviyMOlX5hIVD60YOfHw4/CxOfBhyduaYB+wbFWCWoni4N7SLcV46hrVRktuBbZjFC9ONyqamZITN7q3n32w==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"base64-js": "^1.3.0",
|
||||
@@ -1469,6 +1486,7 @@
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-1.1.3.tgz",
|
||||
"integrity": "sha512-eAmLkjDjAFCVXg7A1unxHsLf961m6y17QFqXqAXGj/gVkKFrEICfStRfwUlGNfeCEjNRa32JEWOUTlYXPyyKvA==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
@@ -1478,6 +1496,7 @@
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/gtoken/-/gtoken-8.0.0.tgz",
|
||||
"integrity": "sha512-+CqsMbHPiSTdtSO14O51eMNlrp9N79gmeqmXeouJOhfucAedHw9noVe/n5uJk3tbKE6a+6ZCQg3RPhVhHByAIw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"gaxios": "^7.0.0",
|
||||
@@ -1491,6 +1510,7 @@
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz",
|
||||
"integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"data-uri-to-buffer": "^4.0.0",
|
||||
@@ -1505,6 +1525,20 @@
|
||||
"url": "https://opencollective.com/node-fetch"
|
||||
}
|
||||
},
|
||||
"node_modules/@google/genai/node_modules/p-retry": {
|
||||
"version": "4.6.2",
|
||||
"resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz",
|
||||
"integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/retry": "0.12.0",
|
||||
"retry": "^0.13.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/@grpc/grpc-js": {
|
||||
"version": "1.13.4",
|
||||
"resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.13.4.tgz",
|
||||
@@ -2975,16 +3009,6 @@
|
||||
"@noble/hashes": "^1.1.5"
|
||||
}
|
||||
},
|
||||
"node_modules/@pkgjs/parseargs": {
|
||||
"version": "0.11.0",
|
||||
"resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
|
||||
"integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/@pnpm/config.env-replace": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz",
|
||||
@@ -5129,46 +5153,6 @@
|
||||
"win32"
|
||||
]
|
||||
},
|
||||
"node_modules/@vscode/vsce/node_modules/glob": {
|
||||
"version": "11.1.0",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-11.1.0.tgz",
|
||||
"integrity": "sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==",
|
||||
"dev": true,
|
||||
"license": "BlueOak-1.0.0",
|
||||
"dependencies": {
|
||||
"foreground-child": "^3.3.1",
|
||||
"jackspeak": "^4.1.1",
|
||||
"minimatch": "^10.1.1",
|
||||
"minipass": "^7.1.2",
|
||||
"package-json-from-dist": "^1.0.0",
|
||||
"path-scurry": "^2.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"glob": "dist/esm/bin.mjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": "20 || >=22"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/@vscode/vsce/node_modules/glob/node_modules/minimatch": {
|
||||
"version": "10.1.1",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz",
|
||||
"integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==",
|
||||
"dev": true,
|
||||
"license": "BlueOak-1.0.0",
|
||||
"dependencies": {
|
||||
"@isaacs/brace-expansion": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "20 || >=22"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/@vscode/vsce/node_modules/hosted-git-info": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz",
|
||||
@@ -5208,33 +5192,6 @@
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/@vscode/vsce/node_modules/path-scurry": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz",
|
||||
"integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==",
|
||||
"dev": true,
|
||||
"license": "BlueOak-1.0.0",
|
||||
"dependencies": {
|
||||
"lru-cache": "^11.0.0",
|
||||
"minipass": "^7.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": "20 || >=22"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/@vscode/vsce/node_modules/path-scurry/node_modules/lru-cache": {
|
||||
"version": "11.1.0",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.1.0.tgz",
|
||||
"integrity": "sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": "20 || >=22"
|
||||
}
|
||||
},
|
||||
"node_modules/@vscode/vsce/node_modules/yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
@@ -5812,6 +5769,7 @@
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/base64-js": {
|
||||
@@ -9056,18 +9014,6 @@
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/gemini-cli-devtools": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/gemini-cli-devtools/-/gemini-cli-devtools-0.2.1.tgz",
|
||||
"integrity": "sha512-PcqPL9ZZjgjsp3oYhcXnUc6yNeLvdZuU/UQp0aT+DA8pt3BZzPzXthlOmIrRRqHBdLjMLPwN5GD29zR5bASXtQ==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"ws": "^8.16.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
}
|
||||
},
|
||||
"node_modules/gemini-cli-vscode-ide-companion": {
|
||||
"resolved": "packages/vscode-ide-companion",
|
||||
"link": true
|
||||
@@ -10029,9 +9975,9 @@
|
||||
},
|
||||
"node_modules/ink": {
|
||||
"name": "@jrichman/ink",
|
||||
"version": "6.4.10",
|
||||
"resolved": "https://registry.npmjs.org/@jrichman/ink/-/ink-6.4.10.tgz",
|
||||
"integrity": "sha512-kjJqZFkGVm0QyJmga/L02rsFJroF1aP2bhXEGkpuuT7clB6/W+gxAbLNw7ZaJrG6T30DgqOT92Pu6C9mK1FWyg==",
|
||||
"version": "6.4.11",
|
||||
"resolved": "https://registry.npmjs.org/@jrichman/ink/-/ink-6.4.11.tgz",
|
||||
"integrity": "sha512-93LQlzT7vvZ1XJcmOMwN4s+6W334QegendeHOMnEJBlhnpIzr8bws6/aOEHG8ZCuVD/vNeeea5m1msHIdAY6ig==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@alcalzone/ansi-tokenize": "^0.2.1",
|
||||
@@ -10112,24 +10058,6 @@
|
||||
"react": ">=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ink-testing-library": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ink-testing-library/-/ink-testing-library-4.0.0.tgz",
|
||||
"integrity": "sha512-yF92kj3pmBvk7oKbSq5vEALO//o7Z9Ck/OaLNlkzXNeYdwfpxMQkSowGTFUCS5MSu9bWfSZMewGpp7bFc66D7Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": ">=18.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/ink/node_modules/ansi-styles": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
|
||||
@@ -10504,6 +10432,18 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/is-network-error": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.3.0.tgz",
|
||||
"integrity": "sha512-6oIwpsgRfnDiyEDLMay/GqCl3HoAtH5+RUKW29gYkL0QA+ipzpDLA16yQs7/RHCSu+BwgbJaOUqa4A99qNVQVw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/is-node-process": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/is-node-process/-/is-node-process-1.2.0.tgz",
|
||||
@@ -12934,6 +12874,21 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/p-retry": {
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/p-retry/-/p-retry-7.1.1.tgz",
|
||||
"integrity": "sha512-J5ApzjyRkkf601HpEeykoiCvzHQjWxPAHhyjFcEUP2SWq0+35NKh8TLhpLw+Dkq5TZBFvUM6UigdE9hIVYTl5w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"is-network-error": "^1.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/package-json": {
|
||||
"version": "10.0.1",
|
||||
"resolved": "https://registry.npmjs.org/package-json/-/package-json-10.0.1.tgz",
|
||||
@@ -13473,9 +13428,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/protobufjs": {
|
||||
"version": "7.5.3",
|
||||
"resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.3.tgz",
|
||||
"integrity": "sha512-sildjKwVqOI2kmFDiXQ6aEB0fjYTafpEvIBs8tOR8qI4spuL9OPROLVu2qZqi/xgCfsHIwVqlaF8JBjWFHnKbw==",
|
||||
"version": "7.5.4",
|
||||
"resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.4.tgz",
|
||||
"integrity": "sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==",
|
||||
"hasInstallScript": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
@@ -13547,7 +13502,6 @@
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
|
||||
"integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
|
||||
"devOptional": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
@@ -13709,9 +13663,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/react": {
|
||||
"version": "19.2.0",
|
||||
"resolved": "https://registry.npmjs.org/react/-/react-19.2.0.tgz",
|
||||
"integrity": "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==",
|
||||
"version": "19.2.4",
|
||||
"resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz",
|
||||
"integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
@@ -13750,6 +13704,26 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/react-dom": {
|
||||
"version": "19.2.4",
|
||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.4.tgz",
|
||||
"integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"scheduler": "^0.27.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^19.2.4"
|
||||
}
|
||||
},
|
||||
"node_modules/react-dom/node_modules/scheduler": {
|
||||
"version": "0.27.0",
|
||||
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz",
|
||||
"integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/react-is": {
|
||||
"version": "16.13.1",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||
@@ -14171,81 +14145,6 @@
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/rimraf/node_modules/brace-expansion": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
|
||||
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/rimraf/node_modules/glob": {
|
||||
"version": "10.5.0",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz",
|
||||
"integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"foreground-child": "^3.1.0",
|
||||
"jackspeak": "^3.1.2",
|
||||
"minimatch": "^9.0.4",
|
||||
"minipass": "^7.1.2",
|
||||
"package-json-from-dist": "^1.0.0",
|
||||
"path-scurry": "^1.11.1"
|
||||
},
|
||||
"bin": {
|
||||
"glob": "dist/esm/bin.mjs"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/rimraf/node_modules/jackspeak": {
|
||||
"version": "3.4.3",
|
||||
"resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
|
||||
"integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
|
||||
"license": "BlueOak-1.0.0",
|
||||
"dependencies": {
|
||||
"@isaacs/cliui": "^8.0.2"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@pkgjs/parseargs": "^0.11.0"
|
||||
}
|
||||
},
|
||||
"node_modules/rimraf/node_modules/minimatch": {
|
||||
"version": "9.0.5",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
|
||||
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16 || 14 >=14.17"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/rimraf/node_modules/path-scurry": {
|
||||
"version": "1.11.1",
|
||||
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
|
||||
"integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
|
||||
"license": "BlueOak-1.0.0",
|
||||
"dependencies": {
|
||||
"lru-cache": "^10.2.0",
|
||||
"minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16 || 14 >=14.18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/rollup": {
|
||||
"version": "4.53.2",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.53.2.tgz",
|
||||
@@ -15564,9 +15463,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/tar": {
|
||||
"version": "7.5.7",
|
||||
"resolved": "https://registry.npmjs.org/tar/-/tar-7.5.7.tgz",
|
||||
"integrity": "sha512-fov56fJiRuThVFXD6o6/Q354S7pnWMJIVlDBYijsTNx6jKSE4pvrDTs6lUnmGvNyfJwFQQwWy3owKz1ucIhveQ==",
|
||||
"version": "7.5.8",
|
||||
"resolved": "https://registry.npmjs.org/tar/-/tar-7.5.8.tgz",
|
||||
"integrity": "sha512-SYkBtK99u0yXa+IWL0JRzzcl7RxNpvX/U08Z+8DKnysfno7M+uExnTZH8K+VGgShf2qFPKtbNr9QBl8n7WBP6Q==",
|
||||
"license": "BlueOak-1.0.0",
|
||||
"dependencies": {
|
||||
"@isaacs/fs-minipass": "^4.0.0",
|
||||
@@ -15713,43 +15612,6 @@
|
||||
"balanced-match": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/test-exclude/node_modules/glob": {
|
||||
"version": "10.5.0",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz",
|
||||
"integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"foreground-child": "^3.1.0",
|
||||
"jackspeak": "^3.1.2",
|
||||
"minimatch": "^9.0.4",
|
||||
"minipass": "^7.1.2",
|
||||
"package-json-from-dist": "^1.0.0",
|
||||
"path-scurry": "^1.11.1"
|
||||
},
|
||||
"bin": {
|
||||
"glob": "dist/esm/bin.mjs"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/test-exclude/node_modules/jackspeak": {
|
||||
"version": "3.4.3",
|
||||
"resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
|
||||
"integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
|
||||
"dev": true,
|
||||
"license": "BlueOak-1.0.0",
|
||||
"dependencies": {
|
||||
"@isaacs/cliui": "^8.0.2"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@pkgjs/parseargs": "^0.11.0"
|
||||
}
|
||||
},
|
||||
"node_modules/test-exclude/node_modules/minimatch": {
|
||||
"version": "9.0.5",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
|
||||
@@ -15766,23 +15628,6 @@
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/test-exclude/node_modules/path-scurry": {
|
||||
"version": "1.11.1",
|
||||
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
|
||||
"integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
|
||||
"dev": true,
|
||||
"license": "BlueOak-1.0.0",
|
||||
"dependencies": {
|
||||
"lru-cache": "^10.2.0",
|
||||
"minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16 || 14 >=14.18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/text-hex": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz",
|
||||
@@ -17262,7 +17107,7 @@
|
||||
"express": "^5.1.0",
|
||||
"fs-extra": "^11.3.0",
|
||||
"strip-json-comments": "^3.1.1",
|
||||
"tar": "^7.5.2",
|
||||
"tar": "^7.5.8",
|
||||
"uuid": "^13.0.0",
|
||||
"winston": "^3.17.0"
|
||||
},
|
||||
@@ -17317,7 +17162,7 @@
|
||||
"dependencies": {
|
||||
"@agentclientprotocol/sdk": "^0.12.0",
|
||||
"@google/gemini-cli-core": "file:../core",
|
||||
"@google/genai": "1.30.0",
|
||||
"@google/genai": "1.41.0",
|
||||
"@iarna/toml": "^2.2.5",
|
||||
"@modelcontextprotocol/sdk": "^1.23.0",
|
||||
"ansi-escapes": "^7.3.0",
|
||||
@@ -17325,6 +17170,7 @@
|
||||
"chalk": "^4.1.2",
|
||||
"cli-spinners": "^2.9.2",
|
||||
"clipboardy": "^5.0.0",
|
||||
"color-convert": "^2.0.1",
|
||||
"command-exists": "^1.2.9",
|
||||
"comment-json": "^4.2.5",
|
||||
"diff": "^8.0.3",
|
||||
@@ -17333,7 +17179,7 @@
|
||||
"fzf": "^0.5.2",
|
||||
"glob": "^12.0.0",
|
||||
"highlight.js": "^11.11.1",
|
||||
"ink": "npm:@jrichman/ink@6.4.10",
|
||||
"ink": "npm:@jrichman/ink@6.4.11",
|
||||
"ink-gradient": "^3.0.0",
|
||||
"ink-spinner": "^5.0.0",
|
||||
"latest-version": "^9.0.0",
|
||||
@@ -17348,7 +17194,7 @@
|
||||
"string-width": "^8.1.0",
|
||||
"strip-ansi": "^7.1.0",
|
||||
"strip-json-comments": "^3.1.1",
|
||||
"tar": "^7.5.2",
|
||||
"tar": "^7.5.8",
|
||||
"tinygradient": "^1.1.5",
|
||||
"undici": "^7.10.0",
|
||||
"ws": "^8.16.0",
|
||||
@@ -17368,7 +17214,7 @@
|
||||
"@types/shell-quote": "^1.7.5",
|
||||
"@types/ws": "^8.5.10",
|
||||
"@types/yargs": "^17.0.32",
|
||||
"ink-testing-library": "^4.0.0",
|
||||
"@xterm/headless": "^5.5.0",
|
||||
"typescript": "^5.3.3",
|
||||
"vitest": "^3.1.1"
|
||||
},
|
||||
@@ -17376,6 +17222,29 @@
|
||||
"node": ">=20"
|
||||
}
|
||||
},
|
||||
"packages/cli/node_modules/@google/genai": {
|
||||
"version": "1.41.0",
|
||||
"resolved": "https://registry.npmjs.org/@google/genai/-/genai-1.41.0.tgz",
|
||||
"integrity": "sha512-S4WGil+PG0NBQRAx+0yrQuM/TWOLn2gGEy5wn4IsoOI6ouHad0P61p3OWdhJ3aqr9kfj8o904i/jevfaGoGuIQ==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"google-auth-library": "^10.3.0",
|
||||
"p-retry": "^7.1.1",
|
||||
"protobufjs": "^7.5.4",
|
||||
"ws": "^8.18.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@modelcontextprotocol/sdk": "^1.25.2"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@modelcontextprotocol/sdk": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"packages/cli/node_modules/ansi-escapes": {
|
||||
"version": "7.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.3.0.tgz",
|
||||
@@ -17391,6 +17260,93 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"packages/cli/node_modules/gaxios": {
|
||||
"version": "7.1.3",
|
||||
"resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.1.3.tgz",
|
||||
"integrity": "sha512-YGGyuEdVIjqxkxVH1pUTMY/XtmmsApXrCVv5EU25iX6inEPbV+VakJfLealkBtJN69AQmh1eGOdCl9Sm1UP6XQ==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"extend": "^3.0.2",
|
||||
"https-proxy-agent": "^7.0.1",
|
||||
"node-fetch": "^3.3.2",
|
||||
"rimraf": "^5.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"packages/cli/node_modules/gcp-metadata": {
|
||||
"version": "8.1.2",
|
||||
"resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-8.1.2.tgz",
|
||||
"integrity": "sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"gaxios": "^7.0.0",
|
||||
"google-logging-utils": "^1.0.0",
|
||||
"json-bigint": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"packages/cli/node_modules/google-auth-library": {
|
||||
"version": "10.5.0",
|
||||
"resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-10.5.0.tgz",
|
||||
"integrity": "sha512-7ABviyMOlX5hIVD60YOfHw4/CxOfBhyduaYB+wbFWCWoni4N7SLcV46hrVRktuBbZjFC9ONyqamZITN7q3n32w==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"base64-js": "^1.3.0",
|
||||
"ecdsa-sig-formatter": "^1.0.11",
|
||||
"gaxios": "^7.0.0",
|
||||
"gcp-metadata": "^8.0.0",
|
||||
"google-logging-utils": "^1.0.0",
|
||||
"gtoken": "^8.0.0",
|
||||
"jws": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"packages/cli/node_modules/google-logging-utils": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-1.1.3.tgz",
|
||||
"integrity": "sha512-eAmLkjDjAFCVXg7A1unxHsLf961m6y17QFqXqAXGj/gVkKFrEICfStRfwUlGNfeCEjNRa32JEWOUTlYXPyyKvA==",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"packages/cli/node_modules/gtoken": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/gtoken/-/gtoken-8.0.0.tgz",
|
||||
"integrity": "sha512-+CqsMbHPiSTdtSO14O51eMNlrp9N79gmeqmXeouJOhfucAedHw9noVe/n5uJk3tbKE6a+6ZCQg3RPhVhHByAIw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"gaxios": "^7.0.0",
|
||||
"jws": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"packages/cli/node_modules/node-fetch": {
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz",
|
||||
"integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"data-uri-to-buffer": "^4.0.0",
|
||||
"fetch-blob": "^3.1.4",
|
||||
"formdata-polyfill": "^4.0.10"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/node-fetch"
|
||||
}
|
||||
},
|
||||
"packages/cli/node_modules/string-width": {
|
||||
"version": "8.1.0",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-8.1.0.tgz",
|
||||
@@ -17416,7 +17372,7 @@
|
||||
"@google-cloud/logging": "^11.2.1",
|
||||
"@google-cloud/opentelemetry-cloud-monitoring-exporter": "^0.21.0",
|
||||
"@google-cloud/opentelemetry-cloud-trace-exporter": "^3.0.0",
|
||||
"@google/genai": "1.30.0",
|
||||
"@google/genai": "1.41.0",
|
||||
"@iarna/toml": "^2.2.5",
|
||||
"@joshua.litt/get-ripgrep": "^0.0.3",
|
||||
"@modelcontextprotocol/sdk": "^1.23.0",
|
||||
@@ -17448,7 +17404,7 @@
|
||||
"fdir": "^6.4.6",
|
||||
"fzf": "^0.5.2",
|
||||
"glob": "^12.0.0",
|
||||
"google-auth-library": "^9.11.0",
|
||||
"google-auth-library": "^10.5.0",
|
||||
"html-to-text": "^9.0.5",
|
||||
"https-proxy-agent": "^7.0.6",
|
||||
"ignore": "^7.0.0",
|
||||
@@ -17494,6 +17450,29 @@
|
||||
"node-pty": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"packages/core/node_modules/@google/genai": {
|
||||
"version": "1.41.0",
|
||||
"resolved": "https://registry.npmjs.org/@google/genai/-/genai-1.41.0.tgz",
|
||||
"integrity": "sha512-S4WGil+PG0NBQRAx+0yrQuM/TWOLn2gGEy5wn4IsoOI6ouHad0P61p3OWdhJ3aqr9kfj8o904i/jevfaGoGuIQ==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"google-auth-library": "^10.3.0",
|
||||
"p-retry": "^7.1.1",
|
||||
"protobufjs": "^7.5.4",
|
||||
"ws": "^8.18.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@modelcontextprotocol/sdk": "^1.25.2"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@modelcontextprotocol/sdk": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"packages/core/node_modules/ajv": {
|
||||
"version": "8.17.1",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
|
||||
@@ -17524,6 +17503,75 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"packages/core/node_modules/gaxios": {
|
||||
"version": "7.1.3",
|
||||
"resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.1.3.tgz",
|
||||
"integrity": "sha512-YGGyuEdVIjqxkxVH1pUTMY/XtmmsApXrCVv5EU25iX6inEPbV+VakJfLealkBtJN69AQmh1eGOdCl9Sm1UP6XQ==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"extend": "^3.0.2",
|
||||
"https-proxy-agent": "^7.0.1",
|
||||
"node-fetch": "^3.3.2",
|
||||
"rimraf": "^5.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"packages/core/node_modules/gcp-metadata": {
|
||||
"version": "8.1.2",
|
||||
"resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-8.1.2.tgz",
|
||||
"integrity": "sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"gaxios": "^7.0.0",
|
||||
"google-logging-utils": "^1.0.0",
|
||||
"json-bigint": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"packages/core/node_modules/google-auth-library": {
|
||||
"version": "10.5.0",
|
||||
"resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-10.5.0.tgz",
|
||||
"integrity": "sha512-7ABviyMOlX5hIVD60YOfHw4/CxOfBhyduaYB+wbFWCWoni4N7SLcV46hrVRktuBbZjFC9ONyqamZITN7q3n32w==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"base64-js": "^1.3.0",
|
||||
"ecdsa-sig-formatter": "^1.0.11",
|
||||
"gaxios": "^7.0.0",
|
||||
"gcp-metadata": "^8.0.0",
|
||||
"google-logging-utils": "^1.0.0",
|
||||
"gtoken": "^8.0.0",
|
||||
"jws": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"packages/core/node_modules/google-logging-utils": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-1.1.3.tgz",
|
||||
"integrity": "sha512-eAmLkjDjAFCVXg7A1unxHsLf961m6y17QFqXqAXGj/gVkKFrEICfStRfwUlGNfeCEjNRa32JEWOUTlYXPyyKvA==",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"packages/core/node_modules/gtoken": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/gtoken/-/gtoken-8.0.0.tgz",
|
||||
"integrity": "sha512-+CqsMbHPiSTdtSO14O51eMNlrp9N79gmeqmXeouJOhfucAedHw9noVe/n5uJk3tbKE6a+6ZCQg3RPhVhHByAIw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"gaxios": "^7.0.0",
|
||||
"jws": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"packages/core/node_modules/ignore": {
|
||||
"version": "7.0.5",
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz",
|
||||
@@ -17548,6 +17596,24 @@
|
||||
"node": ">=16"
|
||||
}
|
||||
},
|
||||
"packages/core/node_modules/node-fetch": {
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz",
|
||||
"integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"data-uri-to-buffer": "^4.0.0",
|
||||
"fetch-blob": "^3.1.4",
|
||||
"formdata-polyfill": "^4.0.10"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/node-fetch"
|
||||
}
|
||||
},
|
||||
"packages/core/node_modules/picomatch": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
|
||||
@@ -17573,6 +17639,21 @@
|
||||
"uuid": "dist-node/bin/uuid"
|
||||
}
|
||||
},
|
||||
"packages/devtools": {
|
||||
"name": "@google/gemini-cli-devtools",
|
||||
"version": "0.30.0-nightly.20260210.a2174751d",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"ws": "^8.16.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"react": "^19.2.0",
|
||||
"react-dom": "^19.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
}
|
||||
},
|
||||
"packages/sdk": {
|
||||
"name": "@google/gemini-cli-sdk",
|
||||
"version": "0.29.0-nightly.20260203.71f46f116",
|
||||
|
||||
+8
-6
@@ -37,7 +37,7 @@
|
||||
"build:all": "npm run build && npm run build:sandbox && npm run build:vscode",
|
||||
"build:packages": "npm run build --workspaces",
|
||||
"build:sandbox": "node scripts/build_sandbox.js",
|
||||
"bundle": "npm run generate && node esbuild.config.js && node scripts/copy_bundle_assets.js",
|
||||
"bundle": "npm run generate && npm run build --workspace=@google/gemini-cli-devtools && node esbuild.config.js && node scripts/copy_bundle_assets.js",
|
||||
"test": "npm run test --workspaces --if-present",
|
||||
"test:ci": "npm run test:ci --workspaces --if-present && npm run test:scripts",
|
||||
"test:scripts": "vitest run --config ./scripts/tests/vitest.config.ts",
|
||||
@@ -64,11 +64,13 @@
|
||||
"pre-commit": "node scripts/pre-commit.js"
|
||||
},
|
||||
"overrides": {
|
||||
"ink": "npm:@jrichman/ink@6.4.10",
|
||||
"ink": "npm:@jrichman/ink@6.4.11",
|
||||
"wrap-ansi": "9.0.2",
|
||||
"cliui": {
|
||||
"wrap-ansi": "7.0.0"
|
||||
}
|
||||
},
|
||||
"glob": "^12.0.0",
|
||||
"node-domexception": "^1.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"gemini": "bundle/gemini.js"
|
||||
@@ -107,7 +109,6 @@
|
||||
"globals": "^16.0.0",
|
||||
"google-artifactregistry-auth": "^3.4.0",
|
||||
"husky": "^9.1.7",
|
||||
"ink-testing-library": "^4.0.0",
|
||||
"json": "^11.0.0",
|
||||
"lint-staged": "^16.1.6",
|
||||
"memfs": "^4.42.0",
|
||||
@@ -117,6 +118,7 @@
|
||||
"npm-run-all": "^4.1.5",
|
||||
"prettier": "^3.5.3",
|
||||
"react-devtools-core": "^6.1.2",
|
||||
"react-dom": "^19.2.0",
|
||||
"semver": "^7.7.2",
|
||||
"strip-ansi": "^7.1.2",
|
||||
"ts-prune": "^0.10.3",
|
||||
@@ -126,9 +128,10 @@
|
||||
"yargs": "^17.7.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"ink": "npm:@jrichman/ink@6.4.10",
|
||||
"ink": "npm:@jrichman/ink@6.4.11",
|
||||
"latest-version": "^9.0.0",
|
||||
"proper-lockfile": "^4.1.2",
|
||||
"punycode": "^2.3.1",
|
||||
"simple-git": "^3.28.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
@@ -138,7 +141,6 @@
|
||||
"@lydell/node-pty-linux-x64": "1.1.0",
|
||||
"@lydell/node-pty-win32-arm64": "1.1.0",
|
||||
"@lydell/node-pty-win32-x64": "1.1.0",
|
||||
"gemini-cli-devtools": "^0.2.1",
|
||||
"keytar": "^7.9.0",
|
||||
"node-pty": "^1.0.0"
|
||||
},
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
"express": "^5.1.0",
|
||||
"fs-extra": "^11.3.0",
|
||||
"strip-json-comments": "^3.1.1",
|
||||
"tar": "^7.5.2",
|
||||
"tar": "^7.5.8",
|
||||
"uuid": "^13.0.0",
|
||||
"winston": "^3.17.0"
|
||||
},
|
||||
|
||||
@@ -14,19 +14,21 @@ import {
|
||||
type Mock,
|
||||
} from 'vitest';
|
||||
import { Task } from './task.js';
|
||||
import type {
|
||||
ToolCall,
|
||||
Config,
|
||||
ToolCallRequestInfo,
|
||||
GitService,
|
||||
CompletedToolCall,
|
||||
} from '@google/gemini-cli-core';
|
||||
import {
|
||||
GeminiEventType,
|
||||
type Config,
|
||||
type ToolCallRequestInfo,
|
||||
type GitService,
|
||||
type CompletedToolCall,
|
||||
ApprovalMode,
|
||||
ToolConfirmationOutcome,
|
||||
} from '@google/gemini-cli-core';
|
||||
import { createMockConfig } from '../utils/testing_utils.js';
|
||||
import type { ExecutionEventBus, RequestContext } from '@a2a-js/sdk/server';
|
||||
import { CoderAgentEvent } from '../types.js';
|
||||
import type { ToolCall } from '@google/gemini-cli-core';
|
||||
|
||||
const mockProcessRestorableToolCalls = vi.hoisted(() => vi.fn());
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
getAllMCPServerStatuses,
|
||||
MCPServerStatus,
|
||||
isNodeError,
|
||||
getErrorMessage,
|
||||
parseAndFormatApiError,
|
||||
safeLiteralReplace,
|
||||
DEFAULT_GUI_EDITOR,
|
||||
@@ -30,8 +31,7 @@ import {
|
||||
EDIT_TOOL_NAMES,
|
||||
processRestorableToolCalls,
|
||||
} from '@google/gemini-cli-core';
|
||||
import type { RequestContext } from '@a2a-js/sdk/server';
|
||||
import { type ExecutionEventBus } from '@a2a-js/sdk/server';
|
||||
import type { RequestContext, ExecutionEventBus } from '@a2a-js/sdk/server';
|
||||
import type {
|
||||
TaskStatusUpdateEvent,
|
||||
TaskArtifactUpdateEvent,
|
||||
@@ -728,16 +728,17 @@ export class Task {
|
||||
// Block scope for lexical declaration
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
||||
const errorEvent = event as ServerGeminiErrorEvent; // Type assertion
|
||||
const errorMessage =
|
||||
errorEvent.value?.error.message ?? 'Unknown error from LLM stream';
|
||||
const errorMessage = errorEvent.value?.error
|
||||
? getErrorMessage(errorEvent.value.error)
|
||||
: 'Unknown error from LLM stream';
|
||||
logger.error(
|
||||
'[Task] Received error event from LLM stream:',
|
||||
errorMessage,
|
||||
);
|
||||
|
||||
let errMessage = `Unknown error from LLM stream: ${JSON.stringify(event)}`;
|
||||
if (errorEvent.value) {
|
||||
errMessage = parseAndFormatApiError(errorEvent.value);
|
||||
if (errorEvent.value?.error) {
|
||||
errMessage = parseAndFormatApiError(errorEvent.value.error);
|
||||
}
|
||||
this.cancelPendingTools(`LLM stream error: ${errorMessage}`);
|
||||
this.setTaskStateAndPublishUpdate(
|
||||
|
||||
@@ -69,6 +69,7 @@ export class RestoreCommand implements Command {
|
||||
throw error;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
const toolCallData = JSON.parse(data);
|
||||
const ToolCallDataSchema = getToolCallDataSchema();
|
||||
const parseResult = ToolCallDataSchema.safeParse(toolCallData);
|
||||
|
||||
@@ -8,17 +8,19 @@ import * as fs from 'node:fs';
|
||||
import * as path from 'node:path';
|
||||
import * as dotenv from 'dotenv';
|
||||
|
||||
import type { TelemetryTarget } from '@google/gemini-cli-core';
|
||||
import type {
|
||||
TelemetryTarget,
|
||||
ConfigParameters,
|
||||
ExtensionLoader,
|
||||
} from '@google/gemini-cli-core';
|
||||
import {
|
||||
AuthType,
|
||||
Config,
|
||||
type ConfigParameters,
|
||||
FileDiscoveryService,
|
||||
ApprovalMode,
|
||||
loadServerHierarchicalMemory,
|
||||
GEMINI_DIR,
|
||||
DEFAULT_GEMINI_EMBEDDING_MODEL,
|
||||
type ExtensionLoader,
|
||||
startupProfiler,
|
||||
PREVIEW_GEMINI_MODEL,
|
||||
homedir,
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
import * as fs from 'node:fs';
|
||||
import * as path from 'node:path';
|
||||
|
||||
import type { MCPServerConfig } from '@google/gemini-cli-core';
|
||||
import {
|
||||
type MCPServerConfig,
|
||||
debugLogger,
|
||||
GEMINI_DIR,
|
||||
getErrorMessage,
|
||||
@@ -122,6 +122,7 @@ export function loadSettings(workspaceDir: string): Settings {
|
||||
function resolveEnvVarsInString(value: string): string {
|
||||
const envVarRegex = /\$(?:(\w+)|{([^}]+)})/g; // Find $VAR_NAME or ${VAR_NAME}
|
||||
return value.replace(envVarRegex, (match, varName1, varName2) => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
const varName = varName1 || varName2;
|
||||
if (process && process.env && typeof process.env[varName] === 'string') {
|
||||
return process.env[varName];
|
||||
@@ -146,7 +147,7 @@ function resolveEnvVarsInObject<T>(obj: T): T {
|
||||
}
|
||||
|
||||
if (Array.isArray(obj)) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion, @typescript-eslint/no-unsafe-return
|
||||
return obj.map((item) => resolveEnvVarsInObject(item)) as unknown as T;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,12 +4,11 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import type { Config } from '@google/gemini-cli-core';
|
||||
import {
|
||||
GeminiEventType,
|
||||
ApprovalMode,
|
||||
type ToolCallConfirmationDetails,
|
||||
import type {
|
||||
Config,
|
||||
ToolCallConfirmationDetails,
|
||||
} from '@google/gemini-cli-core';
|
||||
import { GeminiEventType, ApprovalMode } from '@google/gemini-cli-core';
|
||||
import type {
|
||||
TaskStatusUpdateEvent,
|
||||
SendStreamingMessageSuccessResponse,
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
import express from 'express';
|
||||
|
||||
import type { AgentCard, Message } from '@a2a-js/sdk';
|
||||
import type { TaskStore } from '@a2a-js/sdk/server';
|
||||
import {
|
||||
type TaskStore,
|
||||
DefaultRequestHandler,
|
||||
InMemoryTaskStore,
|
||||
DefaultExecutionEventBus,
|
||||
@@ -25,9 +25,12 @@ import { loadConfig, loadEnvironment, setTargetDir } from '../config/config.js';
|
||||
import { loadSettings } from '../config/settings.js';
|
||||
import { loadExtensions } from '../config/extension.js';
|
||||
import { commandRegistry } from '../commands/command-registry.js';
|
||||
import { debugLogger, SimpleExtensionLoader } from '@google/gemini-cli-core';
|
||||
import {
|
||||
debugLogger,
|
||||
SimpleExtensionLoader,
|
||||
GitService,
|
||||
} from '@google/gemini-cli-core';
|
||||
import type { Command, CommandArgument } from '../commands/types.js';
|
||||
import { GitService } from '@google/gemini-cli-core';
|
||||
|
||||
type CommandResponse = {
|
||||
name: string;
|
||||
@@ -88,6 +91,7 @@ async function handleExecuteCommand(
|
||||
},
|
||||
) {
|
||||
logger.info('[CoreAgent] Received /executeCommand request: ', req.body);
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
const { command, args } = req.body;
|
||||
try {
|
||||
if (typeof command !== 'string') {
|
||||
@@ -211,6 +215,7 @@ export async function createApp() {
|
||||
const agentSettings = req.body.agentSettings as
|
||||
| AgentSettings
|
||||
| undefined;
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
const contextId = req.body.contextId || uuidv4();
|
||||
const wrapper = await agentExecutor.createTask(
|
||||
taskId,
|
||||
|
||||
@@ -246,6 +246,7 @@ export class GCSTaskStore implements TaskStore {
|
||||
}
|
||||
const [compressedMetadata] = await metadataFile.download();
|
||||
const jsonData = gunzipSync(compressedMetadata).toString();
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
const loadedMetadata = JSON.parse(jsonData);
|
||||
logger.info(`Task ${taskId} metadata loaded from GCS.`);
|
||||
|
||||
@@ -282,12 +283,14 @@ export class GCSTaskStore implements TaskStore {
|
||||
|
||||
return {
|
||||
id: taskId,
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
contextId: loadedMetadata._contextId || uuidv4(),
|
||||
kind: 'task',
|
||||
status: {
|
||||
state: persistedState._taskState,
|
||||
timestamp: new Date().toISOString(),
|
||||
},
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
metadata: loadedMetadata,
|
||||
history: [],
|
||||
artifacts: [],
|
||||
|
||||
+16
-1
@@ -36,7 +36,21 @@ process.on('uncaughtException', (error) => {
|
||||
});
|
||||
|
||||
main().catch(async (error) => {
|
||||
await runExitCleanup();
|
||||
// Set a timeout to force exit if cleanup hangs
|
||||
const cleanupTimeout = setTimeout(() => {
|
||||
writeToStderr('Cleanup timed out, forcing exit...\n');
|
||||
process.exit(1);
|
||||
}, 5000);
|
||||
|
||||
try {
|
||||
await runExitCleanup();
|
||||
} catch (cleanupError) {
|
||||
writeToStderr(
|
||||
`Error during final cleanup: ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}\n`,
|
||||
);
|
||||
} finally {
|
||||
clearTimeout(cleanupTimeout);
|
||||
}
|
||||
|
||||
if (error instanceof FatalError) {
|
||||
let errorMessage = error.message;
|
||||
@@ -46,6 +60,7 @@ main().catch(async (error) => {
|
||||
writeToStderr(errorMessage + '\n');
|
||||
process.exit(error.exitCode);
|
||||
}
|
||||
|
||||
writeToStderr('An unexpected critical error occurred:');
|
||||
if (error instanceof Error) {
|
||||
writeToStderr(error.stack + '\n');
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
"dependencies": {
|
||||
"@agentclientprotocol/sdk": "^0.12.0",
|
||||
"@google/gemini-cli-core": "file:../core",
|
||||
"@google/genai": "1.30.0",
|
||||
"@google/genai": "1.41.0",
|
||||
"@iarna/toml": "^2.2.5",
|
||||
"@modelcontextprotocol/sdk": "^1.23.0",
|
||||
"ansi-escapes": "^7.3.0",
|
||||
@@ -39,6 +39,7 @@
|
||||
"chalk": "^4.1.2",
|
||||
"cli-spinners": "^2.9.2",
|
||||
"clipboardy": "^5.0.0",
|
||||
"color-convert": "^2.0.1",
|
||||
"command-exists": "^1.2.9",
|
||||
"comment-json": "^4.2.5",
|
||||
"diff": "^8.0.3",
|
||||
@@ -47,7 +48,7 @@
|
||||
"fzf": "^0.5.2",
|
||||
"glob": "^12.0.0",
|
||||
"highlight.js": "^11.11.1",
|
||||
"ink": "npm:@jrichman/ink@6.4.10",
|
||||
"ink": "npm:@jrichman/ink@6.4.11",
|
||||
"ink-gradient": "^3.0.0",
|
||||
"ink-spinner": "^5.0.0",
|
||||
"latest-version": "^9.0.0",
|
||||
@@ -62,7 +63,7 @@
|
||||
"string-width": "^8.1.0",
|
||||
"strip-ansi": "^7.1.0",
|
||||
"strip-json-comments": "^3.1.1",
|
||||
"tar": "^7.5.2",
|
||||
"tar": "^7.5.8",
|
||||
"tinygradient": "^1.1.5",
|
||||
"undici": "^7.10.0",
|
||||
"ws": "^8.16.0",
|
||||
@@ -79,7 +80,7 @@
|
||||
"@types/shell-quote": "^1.7.5",
|
||||
"@types/ws": "^8.5.10",
|
||||
"@types/yargs": "^17.0.32",
|
||||
"ink-testing-library": "^4.0.0",
|
||||
"@xterm/headless": "^5.5.0",
|
||||
"typescript": "^5.3.3",
|
||||
"vitest": "^3.1.1"
|
||||
},
|
||||
|
||||
@@ -47,6 +47,7 @@ const defaultRequestConfirmation: RequestConfirmationCallback = async (
|
||||
message,
|
||||
initial: false,
|
||||
});
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
||||
return response.confirm;
|
||||
};
|
||||
|
||||
|
||||
@@ -21,7 +21,11 @@ import {
|
||||
type MCPServerConfig,
|
||||
} from '@google/gemini-cli-core';
|
||||
import { loadCliConfig, parseArguments, type CliArgs } from './config.js';
|
||||
import { type Settings, createTestMergedSettings } from './settings.js';
|
||||
import {
|
||||
type Settings,
|
||||
type MergedSettings,
|
||||
createTestMergedSettings,
|
||||
} from './settings.js';
|
||||
import * as ServerConfig from '@google/gemini-cli-core';
|
||||
|
||||
import { isWorkspaceTrusted } from './trustedFolders.js';
|
||||
@@ -1344,6 +1348,36 @@ describe('Approval mode tool exclusion logic', () => {
|
||||
'Invalid approval mode: invalid_mode. Valid values are: yolo, auto_edit, plan, default',
|
||||
);
|
||||
});
|
||||
|
||||
it('should fall back to default approval mode if plan mode is requested but not enabled', async () => {
|
||||
process.argv = ['node', 'script.js'];
|
||||
const settings = createTestMergedSettings({
|
||||
general: {
|
||||
defaultApprovalMode: 'plan',
|
||||
},
|
||||
experimental: {
|
||||
plan: false,
|
||||
},
|
||||
});
|
||||
const argv = await parseArguments(settings);
|
||||
const config = await loadCliConfig(settings, 'test-session', argv);
|
||||
expect(config.getApprovalMode()).toBe(ApprovalMode.DEFAULT);
|
||||
});
|
||||
|
||||
it('should allow plan approval mode if experimental plan is enabled', async () => {
|
||||
process.argv = ['node', 'script.js'];
|
||||
const settings = createTestMergedSettings({
|
||||
general: {
|
||||
defaultApprovalMode: 'plan',
|
||||
},
|
||||
experimental: {
|
||||
plan: true,
|
||||
},
|
||||
});
|
||||
const argv = await parseArguments(settings);
|
||||
const config = await loadCliConfig(settings, 'test-session', argv);
|
||||
expect(config.getApprovalMode()).toBe(ApprovalMode.PLAN);
|
||||
});
|
||||
});
|
||||
|
||||
describe('loadCliConfig with allowed-mcp-server-names', () => {
|
||||
@@ -2556,9 +2590,8 @@ describe('loadCliConfig approval mode', () => {
|
||||
},
|
||||
});
|
||||
|
||||
await expect(loadCliConfig(settings, 'test-session', argv)).rejects.toThrow(
|
||||
'Approval mode "plan" is only available when experimental.plan is enabled.',
|
||||
);
|
||||
const config = await loadCliConfig(settings, 'test-session', argv);
|
||||
expect(config.getApprovalMode()).toBe(ApprovalMode.DEFAULT);
|
||||
});
|
||||
|
||||
it('should throw error when --approval-mode=plan is used but experimental.plan setting is missing', async () => {
|
||||
@@ -2566,9 +2599,23 @@ describe('loadCliConfig approval mode', () => {
|
||||
const argv = await parseArguments(createTestMergedSettings());
|
||||
const settings = createTestMergedSettings({});
|
||||
|
||||
await expect(loadCliConfig(settings, 'test-session', argv)).rejects.toThrow(
|
||||
'Approval mode "plan" is only available when experimental.plan is enabled.',
|
||||
);
|
||||
const config = await loadCliConfig(settings, 'test-session', argv);
|
||||
expect(config.getApprovalMode()).toBe(ApprovalMode.DEFAULT);
|
||||
});
|
||||
|
||||
it('should pass planSettings.directory from settings to config', async () => {
|
||||
process.argv = ['node', 'script.js'];
|
||||
const settings = createTestMergedSettings({
|
||||
general: {
|
||||
plan: {
|
||||
directory: '.custom-plans',
|
||||
},
|
||||
},
|
||||
} as unknown as MergedSettings);
|
||||
const argv = await parseArguments(settings);
|
||||
const config = await loadCliConfig(settings, 'test-session', argv);
|
||||
const plansDir = config.storage.getPlansDir();
|
||||
expect(plansDir).toContain('.custom-plans');
|
||||
});
|
||||
|
||||
// --- Untrusted Folder Scenarios ---
|
||||
@@ -2678,11 +2725,8 @@ describe('loadCliConfig approval mode', () => {
|
||||
experimental: { plan: false },
|
||||
});
|
||||
const argv = await parseArguments(settings);
|
||||
await expect(
|
||||
loadCliConfig(settings, 'test-session', argv),
|
||||
).rejects.toThrow(
|
||||
'Approval mode "plan" is only available when experimental.plan is enabled.',
|
||||
);
|
||||
const config = await loadCliConfig(settings, 'test-session', argv);
|
||||
expect(config.getApprovalMode()).toBe(ApprovalMode.DEFAULT);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -56,7 +56,10 @@ import { resolvePath } from '../utils/resolvePath.js';
|
||||
import { RESUME_LATEST } from '../utils/sessionUtils.js';
|
||||
|
||||
import { isWorkspaceTrusted } from './trustedFolders.js';
|
||||
import { createPolicyEngineConfig } from './policy.js';
|
||||
import {
|
||||
createPolicyEngineConfig,
|
||||
resolveWorkspacePolicyState,
|
||||
} from './policy.js';
|
||||
import { ExtensionManager } from './extension-manager.js';
|
||||
import { McpServerEnablementManager } from './mcp/mcpServerEnablement.js';
|
||||
import type { ExtensionEvents } from '@google/gemini-cli-core/src/utils/extensionLoader.js';
|
||||
@@ -555,11 +558,13 @@ export async function loadCliConfig(
|
||||
break;
|
||||
case 'plan':
|
||||
if (!(settings.experimental?.plan ?? false)) {
|
||||
throw new Error(
|
||||
'Approval mode "plan" is only available when experimental.plan is enabled.',
|
||||
debugLogger.warn(
|
||||
'Approval mode "plan" is only available when experimental.plan is enabled. Falling back to "default".',
|
||||
);
|
||||
approvalMode = ApprovalMode.DEFAULT;
|
||||
} else {
|
||||
approvalMode = ApprovalMode.PLAN;
|
||||
}
|
||||
approvalMode = ApprovalMode.PLAN;
|
||||
break;
|
||||
case 'default':
|
||||
approvalMode = ApprovalMode.DEFAULT;
|
||||
@@ -690,9 +695,17 @@ export async function loadCliConfig(
|
||||
policyPaths: argv.policy,
|
||||
};
|
||||
|
||||
const { workspacePoliciesDir, policyUpdateConfirmationRequest } =
|
||||
await resolveWorkspacePolicyState({
|
||||
cwd,
|
||||
trustedFolder,
|
||||
interactive,
|
||||
});
|
||||
|
||||
const policyEngineConfig = await createPolicyEngineConfig(
|
||||
effectiveSettings,
|
||||
approvalMode,
|
||||
workspacePoliciesDir,
|
||||
);
|
||||
policyEngineConfig.nonInteractive = !interactive;
|
||||
|
||||
@@ -756,6 +769,7 @@ export async function loadCliConfig(
|
||||
coreTools: settings.tools?.core || undefined,
|
||||
allowedTools: allowedTools.length > 0 ? allowedTools : undefined,
|
||||
policyEngineConfig,
|
||||
policyUpdateConfirmationRequest,
|
||||
excludeTools,
|
||||
toolDiscoveryCommand: settings.tools?.discoveryCommand,
|
||||
toolCallCommand: settings.tools?.callCommand,
|
||||
@@ -812,10 +826,12 @@ export async function loadCliConfig(
|
||||
enableExtensionReloading: settings.experimental?.extensionReloading,
|
||||
enableAgents: settings.experimental?.enableAgents,
|
||||
plan: settings.experimental?.plan,
|
||||
planSettings: settings.general.plan,
|
||||
enableEventDrivenScheduler: true,
|
||||
skillsSupport: settings.skills?.enabled ?? true,
|
||||
disabledSkills: settings.skills?.disabled,
|
||||
experimentalJitContext: settings.experimental?.jitContext,
|
||||
modelSteering: settings.experimental?.modelSteering,
|
||||
toolOutputMasking: settings.experimental?.toolOutputMasking,
|
||||
noBrowser: !!process.env['NO_BROWSER'],
|
||||
summarizeToolOutput: settings.model?.summarizeToolOutput,
|
||||
@@ -832,7 +848,6 @@ export async function loadCliConfig(
|
||||
enableShellOutputEfficiency:
|
||||
settings.tools?.shell?.enableShellOutputEfficiency ?? true,
|
||||
skipNextSpeakerCheck: settings.model?.skipNextSpeakerCheck,
|
||||
enablePromptCompletion: settings.general?.enablePromptCompletion,
|
||||
truncateToolOutputThreshold: settings.tools?.truncateToolOutputThreshold,
|
||||
eventEmitter: coreEvents,
|
||||
useWriteTodos: argv.useWriteTodos ?? settings.useWriteTodos,
|
||||
|
||||
@@ -866,6 +866,7 @@ Would you like to attempt to install via "git clone" instead?`,
|
||||
|
||||
try {
|
||||
const hooksContent = await fs.promises.readFile(hooksFilePath, 'utf-8');
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
const rawHooks = JSON.parse(hooksContent);
|
||||
|
||||
if (
|
||||
|
||||
@@ -224,4 +224,59 @@ describe('ExtensionRegistryClient', () => {
|
||||
'Failed to fetch extensions: Not Found',
|
||||
);
|
||||
});
|
||||
|
||||
it('should not return irrelevant results', async () => {
|
||||
fetchMock.mockResolvedValue({
|
||||
ok: true,
|
||||
json: async () => [
|
||||
...mockExtensions,
|
||||
{
|
||||
id: 'dataplex',
|
||||
extensionName: 'dataplex',
|
||||
extensionDescription: 'Connect to Dataplex Universal Catalog...',
|
||||
fullName: 'google-cloud/dataplex',
|
||||
rank: 6,
|
||||
stars: 6,
|
||||
url: '',
|
||||
repoDescription: '',
|
||||
lastUpdated: '',
|
||||
extensionVersion: '1.0.0',
|
||||
avatarUrl: '',
|
||||
hasMCP: false,
|
||||
hasContext: false,
|
||||
isGoogleOwned: true,
|
||||
licenseKey: '',
|
||||
hasHooks: false,
|
||||
hasCustomCommands: false,
|
||||
hasSkills: false,
|
||||
},
|
||||
{
|
||||
id: 'conductor',
|
||||
extensionName: 'conductor',
|
||||
extensionDescription: 'A conductor extension that actually matches.',
|
||||
fullName: 'someone/conductor',
|
||||
rank: 100,
|
||||
stars: 100,
|
||||
url: '',
|
||||
repoDescription: '',
|
||||
lastUpdated: '',
|
||||
extensionVersion: '1.0.0',
|
||||
avatarUrl: '',
|
||||
hasMCP: false,
|
||||
hasContext: false,
|
||||
isGoogleOwned: false,
|
||||
licenseKey: '',
|
||||
hasHooks: false,
|
||||
hasCustomCommands: false,
|
||||
hasSkills: false,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const results = await client.searchExtensions('conductor');
|
||||
const ids = results.map((r) => r.id);
|
||||
|
||||
expect(ids).not.toContain('dataplex');
|
||||
expect(ids).toContain('conductor');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -79,9 +79,11 @@ export class ExtensionRegistryClient {
|
||||
const fzf = new AsyncFzf(allExtensions, {
|
||||
selector: (ext: RegistryExtension) =>
|
||||
`${ext.extensionName} ${ext.extensionDescription} ${ext.fullName}`,
|
||||
fuzzy: 'v2',
|
||||
fuzzy: true,
|
||||
});
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
const results = await fzf.find(query);
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
||||
return results.map((r: { item: RegistryExtension }) => r.item);
|
||||
}
|
||||
|
||||
@@ -108,7 +110,6 @@ export class ExtensionRegistryClient {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
||||
return (await response.json()) as RegistryExtension[];
|
||||
} catch (error) {
|
||||
// Clear the promise on failure so that subsequent calls can try again
|
||||
ExtensionRegistryClient.fetchPromise = null;
|
||||
throw error;
|
||||
}
|
||||
|
||||
@@ -179,6 +179,7 @@ export class ExtensionEnablementManager {
|
||||
readConfig(): AllExtensionsEnablementConfig {
|
||||
try {
|
||||
const content = fs.readFileSync(this.configFilePath, 'utf-8');
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
||||
return JSON.parse(content);
|
||||
} catch (error) {
|
||||
if (
|
||||
|
||||
@@ -156,6 +156,7 @@ export async function promptForSetting(
|
||||
name: 'value',
|
||||
message: `${setting.name}\n${setting.description}`,
|
||||
});
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
||||
return response.value;
|
||||
}
|
||||
|
||||
|
||||
@@ -269,7 +269,7 @@ describe('github.ts', () => {
|
||||
|
||||
it('should return NOT_UPDATABLE if local extension config cannot be loaded', async () => {
|
||||
vi.mocked(mockExtensionManager.loadExtensionConfig).mockImplementation(
|
||||
() => {
|
||||
async () => {
|
||||
throw new Error('Config not found');
|
||||
},
|
||||
);
|
||||
|
||||
@@ -58,6 +58,7 @@ export function recursivelyHydrateStrings<T>(
|
||||
if (Array.isArray(obj)) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
||||
return obj.map((item) =>
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
||||
recursivelyHydrateStrings(item, values),
|
||||
) as unknown as T;
|
||||
}
|
||||
|
||||
@@ -212,7 +212,7 @@ export const defaultKeyBindings: KeyBindingConfig = {
|
||||
[Command.REVERSE_SEARCH]: [{ key: 'r', ctrl: true }],
|
||||
[Command.REWIND]: [{ key: 'double escape' }],
|
||||
[Command.SUBMIT_REVERSE_SEARCH]: [{ key: 'return', ctrl: false }],
|
||||
[Command.ACCEPT_SUGGESTION_REVERSE_SEARCH]: [{ key: 'tab' }],
|
||||
[Command.ACCEPT_SUGGESTION_REVERSE_SEARCH]: [{ key: 'tab', shift: false }],
|
||||
|
||||
// Navigation
|
||||
[Command.NAVIGATION_UP]: [{ key: 'up', shift: false }],
|
||||
@@ -231,7 +231,10 @@ export const defaultKeyBindings: KeyBindingConfig = {
|
||||
[Command.DIALOG_PREV]: [{ key: 'tab', shift: true }],
|
||||
|
||||
// Suggestions & Completions
|
||||
[Command.ACCEPT_SUGGESTION]: [{ key: 'tab' }, { key: 'return', ctrl: false }],
|
||||
[Command.ACCEPT_SUGGESTION]: [
|
||||
{ key: 'tab', shift: false },
|
||||
{ key: 'return', ctrl: false },
|
||||
],
|
||||
[Command.COMPLETION_UP]: [
|
||||
{ key: 'up', shift: false },
|
||||
{ key: 'p', shift: false, ctrl: true },
|
||||
|
||||
@@ -132,6 +132,35 @@ describe('Policy Engine Integration Tests', () => {
|
||||
).toBe(PolicyDecision.ASK_USER);
|
||||
});
|
||||
|
||||
it('should handle global MCP wildcard (*) in settings', async () => {
|
||||
const settings: Settings = {
|
||||
mcp: {
|
||||
allowed: ['*'],
|
||||
},
|
||||
};
|
||||
|
||||
const config = await createPolicyEngineConfig(
|
||||
settings,
|
||||
ApprovalMode.DEFAULT,
|
||||
);
|
||||
const engine = new PolicyEngine(config);
|
||||
|
||||
// ANY tool with a server name should be allowed
|
||||
expect(
|
||||
(await engine.check({ name: 'mcp-server__tool' }, 'mcp-server'))
|
||||
.decision,
|
||||
).toBe(PolicyDecision.ALLOW);
|
||||
expect(
|
||||
(await engine.check({ name: 'another-server__tool' }, 'another-server'))
|
||||
.decision,
|
||||
).toBe(PolicyDecision.ALLOW);
|
||||
|
||||
// Built-in tools should NOT be allowed by the MCP wildcard
|
||||
expect(
|
||||
(await engine.check({ name: 'run_shell_command' }, undefined)).decision,
|
||||
).toBe(PolicyDecision.ASK_USER);
|
||||
});
|
||||
|
||||
it('should correctly prioritize specific tool excludes over MCP server wildcards', async () => {
|
||||
const settings: Settings = {
|
||||
mcp: {
|
||||
@@ -148,13 +177,13 @@ describe('Policy Engine Integration Tests', () => {
|
||||
);
|
||||
const engine = new PolicyEngine(config);
|
||||
|
||||
// MCP server allowed (priority 2.1) provides general allow for server
|
||||
// MCP server allowed (priority 2.1) provides general allow for server
|
||||
// MCP server allowed (priority 3.1) provides general allow for server
|
||||
// MCP server allowed (priority 3.1) provides general allow for server
|
||||
expect(
|
||||
(await engine.check({ name: 'my-server__safe-tool' }, undefined))
|
||||
.decision,
|
||||
).toBe(PolicyDecision.ALLOW);
|
||||
// But specific tool exclude (priority 2.4) wins over server allow
|
||||
// But specific tool exclude (priority 3.4) wins over server allow
|
||||
expect(
|
||||
(await engine.check({ name: 'my-server__dangerous-tool' }, undefined))
|
||||
.decision,
|
||||
@@ -339,6 +368,8 @@ describe('Policy Engine Integration Tests', () => {
|
||||
'/home/user/.gemini/tmp/a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2/session-1/plans/my-plan.md',
|
||||
'/home/user/.gemini/tmp/a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2/session-1/plans/feature_auth.md',
|
||||
'/home/user/.gemini/tmp/new-temp_dir_123/session-1/plans/plan.md', // new style of temp directory
|
||||
'C:\\Users\\user\\.gemini\\tmp\\project-id\\session-id\\plans\\plan.md',
|
||||
'D:\\gemini-cli\\.gemini\\tmp\\project-id\\session-1\\plans\\plan.md', // no session ID
|
||||
];
|
||||
|
||||
for (const file_path of validPaths) {
|
||||
@@ -364,7 +395,8 @@ describe('Policy Engine Integration Tests', () => {
|
||||
const invalidPaths = [
|
||||
'/project/src/file.ts', // Workspace
|
||||
'/home/user/.gemini/tmp/a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2/plans/script.js', // Wrong extension
|
||||
'/home/user/.gemini/tmp/a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2/plans/../../../etc/passwd.md', // Path traversal
|
||||
'/home/user/.gemini/tmp/a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2/plans/../../../etc/passwd.md', // Path traversal (Unix)
|
||||
'C:\\Users\\user\\.gemini\\tmp\\id\\session\\plans\\..\\..\\..\\Windows\\System32\\config\\SAM', // Path traversal (Windows)
|
||||
'/home/user/.gemini/non-tmp/new-temp_dir_123/plans/plan.md', // outside of temp dir
|
||||
];
|
||||
|
||||
@@ -412,25 +444,25 @@ describe('Policy Engine Integration Tests', () => {
|
||||
|
||||
// Find rules and verify their priorities
|
||||
const blockedToolRule = rules.find((r) => r.toolName === 'blocked-tool');
|
||||
expect(blockedToolRule?.priority).toBe(2.4); // Command line exclude
|
||||
expect(blockedToolRule?.priority).toBe(3.4); // Command line exclude
|
||||
|
||||
const blockedServerRule = rules.find(
|
||||
(r) => r.toolName === 'blocked-server__*',
|
||||
);
|
||||
expect(blockedServerRule?.priority).toBe(2.9); // MCP server exclude
|
||||
expect(blockedServerRule?.priority).toBe(3.9); // MCP server exclude
|
||||
|
||||
const specificToolRule = rules.find(
|
||||
(r) => r.toolName === 'specific-tool',
|
||||
);
|
||||
expect(specificToolRule?.priority).toBe(2.3); // Command line allow
|
||||
expect(specificToolRule?.priority).toBe(3.3); // Command line allow
|
||||
|
||||
const trustedServerRule = rules.find(
|
||||
(r) => r.toolName === 'trusted-server__*',
|
||||
);
|
||||
expect(trustedServerRule?.priority).toBe(2.2); // MCP trusted server
|
||||
expect(trustedServerRule?.priority).toBe(3.2); // MCP trusted server
|
||||
|
||||
const mcpServerRule = rules.find((r) => r.toolName === 'mcp-server__*');
|
||||
expect(mcpServerRule?.priority).toBe(2.1); // MCP allowed server
|
||||
expect(mcpServerRule?.priority).toBe(3.1); // MCP allowed server
|
||||
|
||||
const readOnlyToolRule = rules.find((r) => r.toolName === 'glob');
|
||||
// Priority 70 in default tier → 1.07 (Overriding Plan Mode Deny)
|
||||
@@ -577,16 +609,16 @@ describe('Policy Engine Integration Tests', () => {
|
||||
|
||||
// Verify each rule has the expected priority
|
||||
const tool3Rule = rules.find((r) => r.toolName === 'tool3');
|
||||
expect(tool3Rule?.priority).toBe(2.4); // Excluded tools (user tier)
|
||||
expect(tool3Rule?.priority).toBe(3.4); // Excluded tools (user tier)
|
||||
|
||||
const server2Rule = rules.find((r) => r.toolName === 'server2__*');
|
||||
expect(server2Rule?.priority).toBe(2.9); // Excluded servers (user tier)
|
||||
expect(server2Rule?.priority).toBe(3.9); // Excluded servers (user tier)
|
||||
|
||||
const tool1Rule = rules.find((r) => r.toolName === 'tool1');
|
||||
expect(tool1Rule?.priority).toBe(2.3); // Allowed tools (user tier)
|
||||
expect(tool1Rule?.priority).toBe(3.3); // Allowed tools (user tier)
|
||||
|
||||
const server1Rule = rules.find((r) => r.toolName === 'server1__*');
|
||||
expect(server1Rule?.priority).toBe(2.1); // Allowed servers (user tier)
|
||||
expect(server1Rule?.priority).toBe(3.1); // Allowed servers (user tier)
|
||||
|
||||
const globRule = rules.find((r) => r.toolName === 'glob');
|
||||
// Priority 70 in default tier → 1.07
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2025 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
||||
import * as fs from 'node:fs';
|
||||
import * as path from 'node:path';
|
||||
import * as os from 'node:os';
|
||||
import { resolveWorkspacePolicyState } from './policy.js';
|
||||
import { writeToStderr } from '@google/gemini-cli-core';
|
||||
|
||||
// Mock debugLogger to avoid noise in test output
|
||||
vi.mock('@google/gemini-cli-core', async (importOriginal) => {
|
||||
const actual =
|
||||
await importOriginal<typeof import('@google/gemini-cli-core')>();
|
||||
return {
|
||||
...actual,
|
||||
debugLogger: {
|
||||
warn: vi.fn(),
|
||||
error: vi.fn(),
|
||||
debug: vi.fn(),
|
||||
},
|
||||
writeToStderr: vi.fn(),
|
||||
};
|
||||
});
|
||||
|
||||
describe('resolveWorkspacePolicyState', () => {
|
||||
let tempDir: string;
|
||||
let workspaceDir: string;
|
||||
let policiesDir: string;
|
||||
|
||||
beforeEach(() => {
|
||||
// Create a temporary directory for the test
|
||||
tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'gemini-cli-test-'));
|
||||
// Redirect GEMINI_CLI_HOME to the temp directory to isolate integrity storage
|
||||
vi.stubEnv('GEMINI_CLI_HOME', tempDir);
|
||||
|
||||
workspaceDir = path.join(tempDir, 'workspace');
|
||||
fs.mkdirSync(workspaceDir);
|
||||
policiesDir = path.join(workspaceDir, '.gemini', 'policies');
|
||||
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
// Clean up temporary directory
|
||||
fs.rmSync(tempDir, { recursive: true, force: true });
|
||||
vi.unstubAllEnvs();
|
||||
});
|
||||
|
||||
it('should return empty state if folder is not trusted', async () => {
|
||||
const result = await resolveWorkspacePolicyState({
|
||||
cwd: workspaceDir,
|
||||
trustedFolder: false,
|
||||
interactive: true,
|
||||
});
|
||||
|
||||
expect(result).toEqual({
|
||||
workspacePoliciesDir: undefined,
|
||||
policyUpdateConfirmationRequest: undefined,
|
||||
});
|
||||
});
|
||||
|
||||
it('should return policy directory if integrity matches', async () => {
|
||||
// Set up policies directory with a file
|
||||
fs.mkdirSync(policiesDir, { recursive: true });
|
||||
fs.writeFileSync(path.join(policiesDir, 'policy.toml'), 'rules = []');
|
||||
|
||||
// First call to establish integrity (interactive accept)
|
||||
const firstResult = await resolveWorkspacePolicyState({
|
||||
cwd: workspaceDir,
|
||||
trustedFolder: true,
|
||||
interactive: true,
|
||||
});
|
||||
expect(firstResult.policyUpdateConfirmationRequest).toBeDefined();
|
||||
|
||||
// Establish integrity manually as if accepted
|
||||
const { PolicyIntegrityManager } = await import('@google/gemini-cli-core');
|
||||
const integrityManager = new PolicyIntegrityManager();
|
||||
await integrityManager.acceptIntegrity(
|
||||
'workspace',
|
||||
workspaceDir,
|
||||
firstResult.policyUpdateConfirmationRequest!.newHash,
|
||||
);
|
||||
|
||||
// Second call should match
|
||||
const result = await resolveWorkspacePolicyState({
|
||||
cwd: workspaceDir,
|
||||
trustedFolder: true,
|
||||
interactive: true,
|
||||
});
|
||||
|
||||
expect(result.workspacePoliciesDir).toBe(policiesDir);
|
||||
expect(result.policyUpdateConfirmationRequest).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should return undefined if integrity is NEW but fileCount is 0', async () => {
|
||||
const result = await resolveWorkspacePolicyState({
|
||||
cwd: workspaceDir,
|
||||
trustedFolder: true,
|
||||
interactive: true,
|
||||
});
|
||||
|
||||
expect(result.workspacePoliciesDir).toBeUndefined();
|
||||
expect(result.policyUpdateConfirmationRequest).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should return confirmation request if changed in interactive mode', async () => {
|
||||
fs.mkdirSync(policiesDir, { recursive: true });
|
||||
fs.writeFileSync(path.join(policiesDir, 'policy.toml'), 'rules = []');
|
||||
|
||||
const result = await resolveWorkspacePolicyState({
|
||||
cwd: workspaceDir,
|
||||
trustedFolder: true,
|
||||
interactive: true,
|
||||
});
|
||||
|
||||
expect(result.workspacePoliciesDir).toBeUndefined();
|
||||
expect(result.policyUpdateConfirmationRequest).toEqual({
|
||||
scope: 'workspace',
|
||||
identifier: workspaceDir,
|
||||
policyDir: policiesDir,
|
||||
newHash: expect.any(String),
|
||||
});
|
||||
});
|
||||
|
||||
it('should warn and auto-accept if changed in non-interactive mode', async () => {
|
||||
fs.mkdirSync(policiesDir, { recursive: true });
|
||||
fs.writeFileSync(path.join(policiesDir, 'policy.toml'), 'rules = []');
|
||||
|
||||
const result = await resolveWorkspacePolicyState({
|
||||
cwd: workspaceDir,
|
||||
trustedFolder: true,
|
||||
interactive: false,
|
||||
});
|
||||
|
||||
expect(result.workspacePoliciesDir).toBe(policiesDir);
|
||||
expect(result.policyUpdateConfirmationRequest).toBeUndefined();
|
||||
expect(writeToStderr).toHaveBeenCalledWith(
|
||||
expect.stringContaining('Automatically accepting and loading'),
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -12,12 +12,18 @@ import {
|
||||
type PolicySettings,
|
||||
createPolicyEngineConfig as createCorePolicyEngineConfig,
|
||||
createPolicyUpdater as createCorePolicyUpdater,
|
||||
PolicyIntegrityManager,
|
||||
IntegrityStatus,
|
||||
Storage,
|
||||
type PolicyUpdateConfirmationRequest,
|
||||
writeToStderr,
|
||||
} from '@google/gemini-cli-core';
|
||||
import { type Settings } from './settings.js';
|
||||
|
||||
export async function createPolicyEngineConfig(
|
||||
settings: Settings,
|
||||
approvalMode: ApprovalMode,
|
||||
workspacePoliciesDir?: string,
|
||||
): Promise<PolicyEngineConfig> {
|
||||
// Explicitly construct PolicySettings from Settings to ensure type safety
|
||||
// and avoid accidental leakage of other settings properties.
|
||||
@@ -26,6 +32,7 @@ export async function createPolicyEngineConfig(
|
||||
tools: settings.tools,
|
||||
mcpServers: settings.mcpServers,
|
||||
policyPaths: settings.policyPaths,
|
||||
workspacePoliciesDir,
|
||||
};
|
||||
|
||||
return createCorePolicyEngineConfig(policySettings, approvalMode);
|
||||
@@ -34,6 +41,72 @@ export async function createPolicyEngineConfig(
|
||||
export function createPolicyUpdater(
|
||||
policyEngine: PolicyEngine,
|
||||
messageBus: MessageBus,
|
||||
storage: Storage,
|
||||
) {
|
||||
return createCorePolicyUpdater(policyEngine, messageBus);
|
||||
return createCorePolicyUpdater(policyEngine, messageBus, storage);
|
||||
}
|
||||
|
||||
export interface WorkspacePolicyState {
|
||||
workspacePoliciesDir?: string;
|
||||
policyUpdateConfirmationRequest?: PolicyUpdateConfirmationRequest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the workspace policy state by checking folder trust and policy integrity.
|
||||
*/
|
||||
export async function resolveWorkspacePolicyState(options: {
|
||||
cwd: string;
|
||||
trustedFolder: boolean;
|
||||
interactive: boolean;
|
||||
}): Promise<WorkspacePolicyState> {
|
||||
const { cwd, trustedFolder, interactive } = options;
|
||||
|
||||
let workspacePoliciesDir: string | undefined;
|
||||
let policyUpdateConfirmationRequest:
|
||||
| PolicyUpdateConfirmationRequest
|
||||
| undefined;
|
||||
|
||||
if (trustedFolder) {
|
||||
const potentialWorkspacePoliciesDir = new Storage(
|
||||
cwd,
|
||||
).getWorkspacePoliciesDir();
|
||||
const integrityManager = new PolicyIntegrityManager();
|
||||
const integrityResult = await integrityManager.checkIntegrity(
|
||||
'workspace',
|
||||
cwd,
|
||||
potentialWorkspacePoliciesDir,
|
||||
);
|
||||
|
||||
if (integrityResult.status === IntegrityStatus.MATCH) {
|
||||
workspacePoliciesDir = potentialWorkspacePoliciesDir;
|
||||
} else if (
|
||||
integrityResult.status === IntegrityStatus.NEW &&
|
||||
integrityResult.fileCount === 0
|
||||
) {
|
||||
// No workspace policies found
|
||||
workspacePoliciesDir = undefined;
|
||||
} else if (interactive) {
|
||||
// Policies changed or are new, and we are in interactive mode
|
||||
policyUpdateConfirmationRequest = {
|
||||
scope: 'workspace',
|
||||
identifier: cwd,
|
||||
policyDir: potentialWorkspacePoliciesDir,
|
||||
newHash: integrityResult.hash,
|
||||
};
|
||||
} else {
|
||||
// Non-interactive mode: warn and automatically accept/load
|
||||
await integrityManager.acceptIntegrity(
|
||||
'workspace',
|
||||
cwd,
|
||||
integrityResult.hash,
|
||||
);
|
||||
workspacePoliciesDir = potentialWorkspacePoliciesDir;
|
||||
// debugLogger.warn here doesn't show up in the terminal. It is showing up only in debug mode on the debug console
|
||||
writeToStderr(
|
||||
'WARNING: Workspace policies changed or are new. Automatically accepting and loading them in non-interactive mode.\n',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return { workspacePoliciesDir, policyUpdateConfirmationRequest };
|
||||
}
|
||||
|
||||
@@ -2032,6 +2032,85 @@ describe('Settings Loading and Merging', () => {
|
||||
}),
|
||||
}),
|
||||
);
|
||||
|
||||
// Check that enableLoadingPhrases: false was further migrated to loadingPhrases: 'off'
|
||||
expect(setValueSpy).toHaveBeenCalledWith(
|
||||
SettingScope.User,
|
||||
'ui',
|
||||
expect.objectContaining({
|
||||
loadingPhrases: 'off',
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('should migrate enableLoadingPhrases: false to loadingPhrases: off', () => {
|
||||
const userSettingsContent = {
|
||||
ui: {
|
||||
accessibility: {
|
||||
enableLoadingPhrases: false,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const loadedSettings = createMockSettings(userSettingsContent);
|
||||
const setValueSpy = vi.spyOn(loadedSettings, 'setValue');
|
||||
|
||||
migrateDeprecatedSettings(loadedSettings);
|
||||
|
||||
expect(setValueSpy).toHaveBeenCalledWith(
|
||||
SettingScope.User,
|
||||
'ui',
|
||||
expect.objectContaining({
|
||||
loadingPhrases: 'off',
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('should not migrate enableLoadingPhrases: true to loadingPhrases', () => {
|
||||
const userSettingsContent = {
|
||||
ui: {
|
||||
accessibility: {
|
||||
enableLoadingPhrases: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const loadedSettings = createMockSettings(userSettingsContent);
|
||||
const setValueSpy = vi.spyOn(loadedSettings, 'setValue');
|
||||
|
||||
migrateDeprecatedSettings(loadedSettings);
|
||||
|
||||
// Should not set loadingPhrases when enableLoadingPhrases is true
|
||||
const uiCalls = setValueSpy.mock.calls.filter((call) => call[1] === 'ui');
|
||||
for (const call of uiCalls) {
|
||||
const uiValue = call[2] as Record<string, unknown>;
|
||||
expect(uiValue).not.toHaveProperty('loadingPhrases');
|
||||
}
|
||||
});
|
||||
|
||||
it('should not overwrite existing loadingPhrases during migration', () => {
|
||||
const userSettingsContent = {
|
||||
ui: {
|
||||
loadingPhrases: 'witty',
|
||||
accessibility: {
|
||||
enableLoadingPhrases: false,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const loadedSettings = createMockSettings(userSettingsContent);
|
||||
const setValueSpy = vi.spyOn(loadedSettings, 'setValue');
|
||||
|
||||
migrateDeprecatedSettings(loadedSettings);
|
||||
|
||||
// Should not overwrite existing loadingPhrases
|
||||
const uiCalls = setValueSpy.mock.calls.filter((call) => call[1] === 'ui');
|
||||
for (const call of uiCalls) {
|
||||
const uiValue = call[2] as Record<string, unknown>;
|
||||
if (uiValue['loadingPhrases'] !== undefined) {
|
||||
expect(uiValue['loadingPhrases']).toBe('witty');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
it('should prioritize new settings over deprecated ones and respect removeDeprecated flag', () => {
|
||||
|
||||
@@ -165,7 +165,10 @@ export interface SummarizeToolOutputSettings {
|
||||
tokenBudget?: number;
|
||||
}
|
||||
|
||||
export type LoadingPhrasesMode = 'tips' | 'witty' | 'all' | 'off';
|
||||
|
||||
export interface AccessibilitySettings {
|
||||
/** @deprecated Use ui.loadingPhrases instead. */
|
||||
enableLoadingPhrases?: boolean;
|
||||
screenReader?: boolean;
|
||||
}
|
||||
@@ -928,6 +931,22 @@ export function migrateDeprecatedSettings(
|
||||
anyModified = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Migrate enableLoadingPhrases: false → loadingPhrases: 'off'
|
||||
const enableLP = newAccessibility['enableLoadingPhrases'];
|
||||
if (
|
||||
typeof enableLP === 'boolean' &&
|
||||
newUi['loadingPhrases'] === undefined
|
||||
) {
|
||||
if (!enableLP) {
|
||||
newUi['loadingPhrases'] = 'off';
|
||||
loadedSettings.setValue(scope, 'ui', newUi);
|
||||
if (!settingsFile.readOnly) {
|
||||
anyModified = true;
|
||||
}
|
||||
}
|
||||
foundDeprecated.push('ui.accessibility.enableLoadingPhrases');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -83,6 +83,19 @@ describe('SettingsSchema', () => {
|
||||
).toBe('boolean');
|
||||
});
|
||||
|
||||
it('should have loadingPhrases enum property', () => {
|
||||
const definition = getSettingsSchema().ui?.properties?.loadingPhrases;
|
||||
expect(definition).toBeDefined();
|
||||
expect(definition?.type).toBe('enum');
|
||||
expect(definition?.default).toBe('tips');
|
||||
expect(definition?.options?.map((o) => o.value)).toEqual([
|
||||
'tips',
|
||||
'witty',
|
||||
'all',
|
||||
'off',
|
||||
]);
|
||||
});
|
||||
|
||||
it('should have checkpointing nested properties', () => {
|
||||
expect(
|
||||
getSettingsSchema().general?.properties?.checkpointing.properties
|
||||
@@ -94,6 +107,16 @@ describe('SettingsSchema', () => {
|
||||
).toBe('boolean');
|
||||
});
|
||||
|
||||
it('should have plan nested properties', () => {
|
||||
expect(
|
||||
getSettingsSchema().general?.properties?.plan?.properties?.directory,
|
||||
).toBeDefined();
|
||||
expect(
|
||||
getSettingsSchema().general?.properties?.plan?.properties?.directory
|
||||
.type,
|
||||
).toBe('string');
|
||||
});
|
||||
|
||||
it('should have fileFiltering nested properties', () => {
|
||||
expect(
|
||||
getSettingsSchema().context.properties.fileFiltering.properties
|
||||
@@ -353,6 +376,17 @@ describe('SettingsSchema', () => {
|
||||
).toBe('Show the "? for shortcuts" hint above the input.');
|
||||
});
|
||||
|
||||
it('should have enableNotifications setting in schema', () => {
|
||||
const setting =
|
||||
getSettingsSchema().general.properties.enableNotifications;
|
||||
expect(setting).toBeDefined();
|
||||
expect(setting.type).toBe('boolean');
|
||||
expect(setting.category).toBe('General');
|
||||
expect(setting.default).toBe(false);
|
||||
expect(setting.requiresRestart).toBe(false);
|
||||
expect(setting.showInDialog).toBe(true);
|
||||
});
|
||||
|
||||
it('should have enableAgents setting in schema', () => {
|
||||
const setting = getSettingsSchema().experimental.properties.enableAgents;
|
||||
expect(setting).toBeDefined();
|
||||
|
||||
@@ -236,6 +236,16 @@ const SETTINGS_SCHEMA = {
|
||||
description: 'Enable update notification prompts.',
|
||||
showInDialog: false,
|
||||
},
|
||||
enableNotifications: {
|
||||
type: 'boolean',
|
||||
label: 'Enable Notifications',
|
||||
category: 'General',
|
||||
requiresRestart: false,
|
||||
default: false,
|
||||
description:
|
||||
'Enable run-event notifications for action-required prompts and session completion. Currently macOS only.',
|
||||
showInDialog: true,
|
||||
},
|
||||
checkpointing: {
|
||||
type: 'object',
|
||||
label: 'Checkpointing',
|
||||
@@ -256,15 +266,26 @@ const SETTINGS_SCHEMA = {
|
||||
},
|
||||
},
|
||||
},
|
||||
enablePromptCompletion: {
|
||||
type: 'boolean',
|
||||
label: 'Enable Prompt Completion',
|
||||
plan: {
|
||||
type: 'object',
|
||||
label: 'Plan',
|
||||
category: 'General',
|
||||
requiresRestart: true,
|
||||
default: false,
|
||||
description:
|
||||
'Enable AI-powered prompt completion suggestions while typing.',
|
||||
showInDialog: true,
|
||||
default: {},
|
||||
description: 'Planning features configuration.',
|
||||
showInDialog: false,
|
||||
properties: {
|
||||
directory: {
|
||||
type: 'string',
|
||||
label: 'Plan Directory',
|
||||
category: 'General',
|
||||
requiresRestart: true,
|
||||
default: undefined as string | undefined,
|
||||
description:
|
||||
'The directory where planning artifacts are stored. If not specified, defaults to the system temporary directory.',
|
||||
showInDialog: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
retryFetchErrors: {
|
||||
type: 'boolean',
|
||||
@@ -475,6 +496,15 @@ const SETTINGS_SCHEMA = {
|
||||
'Show a warning when running Gemini CLI in the home directory.',
|
||||
showInDialog: true,
|
||||
},
|
||||
showCompatibilityWarnings: {
|
||||
type: 'boolean',
|
||||
label: 'Show Compatibility Warnings',
|
||||
category: 'UI',
|
||||
requiresRestart: true,
|
||||
default: true,
|
||||
description: 'Show warnings about terminal or OS compatibility issues.',
|
||||
showInDialog: true,
|
||||
},
|
||||
hideTips: {
|
||||
type: 'boolean',
|
||||
label: 'Hide Tips',
|
||||
@@ -653,6 +683,22 @@ const SETTINGS_SCHEMA = {
|
||||
description: 'Show the spinner during operations.',
|
||||
showInDialog: true,
|
||||
},
|
||||
loadingPhrases: {
|
||||
type: 'enum',
|
||||
label: 'Loading Phrases',
|
||||
category: 'UI',
|
||||
requiresRestart: false,
|
||||
default: 'tips',
|
||||
description:
|
||||
'What to show while the model is working: tips, witty comments, both, or nothing.',
|
||||
showInDialog: true,
|
||||
options: [
|
||||
{ value: 'tips', label: 'Tips' },
|
||||
{ value: 'witty', label: 'Witty' },
|
||||
{ value: 'all', label: 'All' },
|
||||
{ value: 'off', label: 'Off' },
|
||||
],
|
||||
},
|
||||
customWittyPhrases: {
|
||||
type: 'array',
|
||||
label: 'Custom Witty Phrases',
|
||||
@@ -681,8 +727,9 @@ const SETTINGS_SCHEMA = {
|
||||
category: 'UI',
|
||||
requiresRestart: true,
|
||||
default: true,
|
||||
description: 'Enable loading phrases during operations.',
|
||||
showInDialog: true,
|
||||
description:
|
||||
'@deprecated Use ui.loadingPhrases instead. Enable loading phrases during operations.',
|
||||
showInDialog: false,
|
||||
},
|
||||
screenReader: {
|
||||
type: 'boolean',
|
||||
@@ -917,6 +964,60 @@ const SETTINGS_SCHEMA = {
|
||||
ref: 'AgentOverride',
|
||||
},
|
||||
},
|
||||
browser: {
|
||||
type: 'object',
|
||||
label: 'Browser Agent',
|
||||
category: 'Advanced',
|
||||
requiresRestart: true,
|
||||
default: {},
|
||||
description: 'Settings specific to the browser agent.',
|
||||
showInDialog: false,
|
||||
properties: {
|
||||
sessionMode: {
|
||||
type: 'enum',
|
||||
label: 'Browser Session Mode',
|
||||
category: 'Advanced',
|
||||
requiresRestart: true,
|
||||
default: 'persistent',
|
||||
description:
|
||||
"Session mode: 'persistent', 'isolated', or 'existing'.",
|
||||
showInDialog: false,
|
||||
options: [
|
||||
{ value: 'persistent', label: 'Persistent' },
|
||||
{ value: 'isolated', label: 'Isolated' },
|
||||
{ value: 'existing', label: 'Existing' },
|
||||
],
|
||||
},
|
||||
headless: {
|
||||
type: 'boolean',
|
||||
label: 'Browser Headless',
|
||||
category: 'Advanced',
|
||||
requiresRestart: true,
|
||||
default: false,
|
||||
description: 'Run browser in headless mode.',
|
||||
showInDialog: false,
|
||||
},
|
||||
profilePath: {
|
||||
type: 'string',
|
||||
label: 'Browser Profile Path',
|
||||
category: 'Advanced',
|
||||
requiresRestart: true,
|
||||
default: undefined as string | undefined,
|
||||
description:
|
||||
'Path to browser profile directory for session persistence.',
|
||||
showInDialog: false,
|
||||
},
|
||||
visualModel: {
|
||||
type: 'string',
|
||||
label: 'Browser Visual Model',
|
||||
category: 'Advanced',
|
||||
requiresRestart: true,
|
||||
default: undefined as string | undefined,
|
||||
description: 'Model override for the visual agent.',
|
||||
showInDialog: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1277,6 +1378,7 @@ const SETTINGS_SCHEMA = {
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
useWriteTodos: {
|
||||
type: 'boolean',
|
||||
label: 'Use WriteTodos',
|
||||
@@ -1613,7 +1715,17 @@ const SETTINGS_SCHEMA = {
|
||||
requiresRestart: false,
|
||||
default: false,
|
||||
description:
|
||||
'Use OSC 52 sequence for pasting instead of clipboardy (useful for remote sessions).',
|
||||
'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).',
|
||||
showInDialog: true,
|
||||
},
|
||||
useOSC52Copy: {
|
||||
type: 'boolean',
|
||||
label: 'Use OSC 52 Copy',
|
||||
category: 'Experimental',
|
||||
requiresRestart: false,
|
||||
default: false,
|
||||
description:
|
||||
'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).',
|
||||
showInDialog: true,
|
||||
},
|
||||
plan: {
|
||||
@@ -1625,6 +1737,16 @@ const SETTINGS_SCHEMA = {
|
||||
description: 'Enable planning features (Plan Mode and tools).',
|
||||
showInDialog: true,
|
||||
},
|
||||
modelSteering: {
|
||||
type: 'boolean',
|
||||
label: 'Model Steering',
|
||||
category: 'Experimental',
|
||||
requiresRestart: false,
|
||||
default: false,
|
||||
description:
|
||||
'Enable model steering (user hints) to guide the model during tool execution.',
|
||||
showInDialog: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
@@ -131,7 +131,6 @@ describe('Settings Repro', () => {
|
||||
},
|
||||
general: {
|
||||
debugKeystrokeLogging: false,
|
||||
enablePromptCompletion: false,
|
||||
preferredEditor: 'vim',
|
||||
vimMode: false,
|
||||
},
|
||||
|
||||
@@ -491,25 +491,33 @@ describe('Trusted Folders', () => {
|
||||
});
|
||||
});
|
||||
|
||||
const itif = (condition: boolean) => (condition ? it : it.skip);
|
||||
|
||||
describe('Symlinks Support', () => {
|
||||
const mockSettings: Settings = {
|
||||
security: { folderTrust: { enabled: true } },
|
||||
};
|
||||
|
||||
it('should trust a folder if the rule matches the realpath', () => {
|
||||
// Create a real directory and a symlink
|
||||
const realDir = path.join(tempDir, 'real');
|
||||
const symlinkDir = path.join(tempDir, 'symlink');
|
||||
fs.mkdirSync(realDir);
|
||||
fs.symlinkSync(realDir, symlinkDir);
|
||||
// TODO: issue 19387 - Enable symlink tests on Windows
|
||||
itif(process.platform !== 'win32')(
|
||||
'should trust a folder if the rule matches the realpath',
|
||||
() => {
|
||||
// Create a real directory and a symlink
|
||||
const realDir = path.join(tempDir, 'real');
|
||||
const symlinkDir = path.join(tempDir, 'symlink');
|
||||
fs.mkdirSync(realDir);
|
||||
fs.symlinkSync(realDir, symlinkDir);
|
||||
|
||||
// Rule uses realpath
|
||||
const config = { [realDir]: TrustLevel.TRUST_FOLDER };
|
||||
fs.writeFileSync(trustedFoldersPath, JSON.stringify(config), 'utf-8');
|
||||
// Rule uses realpath
|
||||
const config = { [realDir]: TrustLevel.TRUST_FOLDER };
|
||||
fs.writeFileSync(trustedFoldersPath, JSON.stringify(config), 'utf-8');
|
||||
|
||||
// Check against symlink path
|
||||
expect(isWorkspaceTrusted(mockSettings, symlinkDir).isTrusted).toBe(true);
|
||||
});
|
||||
// Check against symlink path
|
||||
expect(isWorkspaceTrusted(mockSettings, symlinkDir).isTrusted).toBe(
|
||||
true,
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
describe('Verification: Auth and Trust Interaction', () => {
|
||||
|
||||
@@ -0,0 +1,239 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2025 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||
import * as path from 'node:path';
|
||||
import { loadCliConfig, type CliArgs } from './config.js';
|
||||
import { createTestMergedSettings } from './settings.js';
|
||||
import * as ServerConfig from '@google/gemini-cli-core';
|
||||
import { isWorkspaceTrusted } from './trustedFolders.js';
|
||||
|
||||
// Mock dependencies
|
||||
vi.mock('./trustedFolders.js', () => ({
|
||||
isWorkspaceTrusted: vi.fn(),
|
||||
}));
|
||||
|
||||
const mockCheckIntegrity = vi.fn();
|
||||
const mockAcceptIntegrity = vi.fn();
|
||||
|
||||
vi.mock('@google/gemini-cli-core', async () => {
|
||||
const actual = await vi.importActual<typeof ServerConfig>(
|
||||
'@google/gemini-cli-core',
|
||||
);
|
||||
return {
|
||||
...actual,
|
||||
loadServerHierarchicalMemory: vi.fn().mockResolvedValue({
|
||||
memoryContent: '',
|
||||
fileCount: 0,
|
||||
filePaths: [],
|
||||
}),
|
||||
createPolicyEngineConfig: vi.fn().mockResolvedValue({
|
||||
rules: [],
|
||||
checkers: [],
|
||||
}),
|
||||
getVersion: vi.fn().mockResolvedValue('test-version'),
|
||||
PolicyIntegrityManager: vi.fn().mockImplementation(() => ({
|
||||
checkIntegrity: mockCheckIntegrity,
|
||||
acceptIntegrity: mockAcceptIntegrity,
|
||||
})),
|
||||
IntegrityStatus: { MATCH: 'match', NEW: 'new', MISMATCH: 'mismatch' },
|
||||
debugLogger: {
|
||||
warn: vi.fn(),
|
||||
error: vi.fn(),
|
||||
},
|
||||
isHeadlessMode: vi.fn().mockReturnValue(false), // Default to interactive
|
||||
};
|
||||
});
|
||||
|
||||
describe('Workspace-Level Policy CLI Integration', () => {
|
||||
const MOCK_CWD = process.cwd();
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
// Default to MATCH for existing tests
|
||||
mockCheckIntegrity.mockResolvedValue({
|
||||
status: 'match',
|
||||
hash: 'test-hash',
|
||||
fileCount: 1,
|
||||
});
|
||||
vi.mocked(ServerConfig.isHeadlessMode).mockReturnValue(false);
|
||||
});
|
||||
|
||||
it('should have getWorkspacePoliciesDir on Storage class', () => {
|
||||
const storage = new ServerConfig.Storage(MOCK_CWD);
|
||||
expect(storage.getWorkspacePoliciesDir).toBeDefined();
|
||||
expect(typeof storage.getWorkspacePoliciesDir).toBe('function');
|
||||
});
|
||||
|
||||
it('should pass workspacePoliciesDir to createPolicyEngineConfig when folder is trusted', async () => {
|
||||
vi.mocked(isWorkspaceTrusted).mockReturnValue({
|
||||
isTrusted: true,
|
||||
source: 'file',
|
||||
});
|
||||
|
||||
const settings = createTestMergedSettings();
|
||||
const argv = { query: 'test' } as unknown as CliArgs;
|
||||
|
||||
await loadCliConfig(settings, 'test-session', argv, { cwd: MOCK_CWD });
|
||||
|
||||
expect(ServerConfig.createPolicyEngineConfig).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
workspacePoliciesDir: expect.stringContaining(
|
||||
path.join('.gemini', 'policies'),
|
||||
),
|
||||
}),
|
||||
expect.anything(),
|
||||
);
|
||||
});
|
||||
|
||||
it('should NOT pass workspacePoliciesDir to createPolicyEngineConfig when folder is NOT trusted', async () => {
|
||||
vi.mocked(isWorkspaceTrusted).mockReturnValue({
|
||||
isTrusted: false,
|
||||
source: 'file',
|
||||
});
|
||||
|
||||
const settings = createTestMergedSettings();
|
||||
const argv = { query: 'test' } as unknown as CliArgs;
|
||||
|
||||
await loadCliConfig(settings, 'test-session', argv, { cwd: MOCK_CWD });
|
||||
|
||||
expect(ServerConfig.createPolicyEngineConfig).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
workspacePoliciesDir: undefined,
|
||||
}),
|
||||
expect.anything(),
|
||||
);
|
||||
});
|
||||
|
||||
it('should NOT pass workspacePoliciesDir if integrity is NEW but fileCount is 0', async () => {
|
||||
vi.mocked(isWorkspaceTrusted).mockReturnValue({
|
||||
isTrusted: true,
|
||||
source: 'file',
|
||||
});
|
||||
mockCheckIntegrity.mockResolvedValue({
|
||||
status: 'new',
|
||||
hash: 'hash',
|
||||
fileCount: 0,
|
||||
});
|
||||
|
||||
const settings = createTestMergedSettings();
|
||||
const argv = { query: 'test' } as unknown as CliArgs;
|
||||
|
||||
await loadCliConfig(settings, 'test-session', argv, { cwd: MOCK_CWD });
|
||||
|
||||
expect(ServerConfig.createPolicyEngineConfig).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
workspacePoliciesDir: undefined,
|
||||
}),
|
||||
expect.anything(),
|
||||
);
|
||||
});
|
||||
|
||||
it('should automatically accept and load workspacePoliciesDir if integrity MISMATCH in non-interactive mode', async () => {
|
||||
vi.mocked(isWorkspaceTrusted).mockReturnValue({
|
||||
isTrusted: true,
|
||||
source: 'file',
|
||||
});
|
||||
mockCheckIntegrity.mockResolvedValue({
|
||||
status: 'mismatch',
|
||||
hash: 'new-hash',
|
||||
fileCount: 1,
|
||||
});
|
||||
vi.mocked(ServerConfig.isHeadlessMode).mockReturnValue(true); // Non-interactive
|
||||
|
||||
const settings = createTestMergedSettings();
|
||||
const argv = { prompt: 'do something' } as unknown as CliArgs;
|
||||
|
||||
await loadCliConfig(settings, 'test-session', argv, { cwd: MOCK_CWD });
|
||||
|
||||
expect(mockAcceptIntegrity).toHaveBeenCalledWith(
|
||||
'workspace',
|
||||
MOCK_CWD,
|
||||
'new-hash',
|
||||
);
|
||||
expect(ServerConfig.createPolicyEngineConfig).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
workspacePoliciesDir: expect.stringContaining(
|
||||
path.join('.gemini', 'policies'),
|
||||
),
|
||||
}),
|
||||
expect.anything(),
|
||||
);
|
||||
});
|
||||
|
||||
it('should set policyUpdateConfirmationRequest if integrity MISMATCH in interactive mode', async () => {
|
||||
vi.mocked(isWorkspaceTrusted).mockReturnValue({
|
||||
isTrusted: true,
|
||||
source: 'file',
|
||||
});
|
||||
mockCheckIntegrity.mockResolvedValue({
|
||||
status: 'mismatch',
|
||||
hash: 'new-hash',
|
||||
fileCount: 1,
|
||||
});
|
||||
vi.mocked(ServerConfig.isHeadlessMode).mockReturnValue(false); // Interactive
|
||||
|
||||
const settings = createTestMergedSettings();
|
||||
const argv = {
|
||||
query: 'test',
|
||||
promptInteractive: 'test',
|
||||
} as unknown as CliArgs;
|
||||
|
||||
const config = await loadCliConfig(settings, 'test-session', argv, {
|
||||
cwd: MOCK_CWD,
|
||||
});
|
||||
|
||||
expect(config.getPolicyUpdateConfirmationRequest()).toEqual({
|
||||
scope: 'workspace',
|
||||
identifier: MOCK_CWD,
|
||||
policyDir: expect.stringContaining(path.join('.gemini', 'policies')),
|
||||
newHash: 'new-hash',
|
||||
});
|
||||
// In interactive mode without accept flag, it waits for user confirmation (handled by UI),
|
||||
// so it currently DOES NOT pass the directory to createPolicyEngineConfig yet.
|
||||
// The UI will handle the confirmation and reload/update.
|
||||
expect(ServerConfig.createPolicyEngineConfig).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
workspacePoliciesDir: undefined,
|
||||
}),
|
||||
expect.anything(),
|
||||
);
|
||||
});
|
||||
|
||||
it('should set policyUpdateConfirmationRequest if integrity is NEW with files (first time seen) in interactive mode', async () => {
|
||||
vi.mocked(isWorkspaceTrusted).mockReturnValue({
|
||||
isTrusted: true,
|
||||
source: 'file',
|
||||
});
|
||||
mockCheckIntegrity.mockResolvedValue({
|
||||
status: 'new',
|
||||
hash: 'new-hash',
|
||||
fileCount: 5,
|
||||
});
|
||||
vi.mocked(ServerConfig.isHeadlessMode).mockReturnValue(false); // Interactive
|
||||
|
||||
const settings = createTestMergedSettings();
|
||||
const argv = { query: 'test' } as unknown as CliArgs;
|
||||
|
||||
const config = await loadCliConfig(settings, 'test-session', argv, {
|
||||
cwd: MOCK_CWD,
|
||||
});
|
||||
|
||||
expect(config.getPolicyUpdateConfirmationRequest()).toEqual({
|
||||
scope: 'workspace',
|
||||
identifier: MOCK_CWD,
|
||||
policyDir: expect.stringContaining(path.join('.gemini', 'policies')),
|
||||
newHash: 'new-hash',
|
||||
});
|
||||
|
||||
expect(ServerConfig.createPolicyEngineConfig).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
workspacePoliciesDir: undefined,
|
||||
}),
|
||||
expect.anything(),
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -38,6 +38,8 @@ import { appEvents, AppEvent } from './utils/events.js';
|
||||
import {
|
||||
type Config,
|
||||
type ResumedSessionData,
|
||||
type StartupWarning,
|
||||
WarningPriority,
|
||||
debugLogger,
|
||||
coreEvents,
|
||||
AuthType,
|
||||
@@ -56,6 +58,20 @@ vi.mock('./nonInteractiveCli.js', () => ({
|
||||
runNonInteractive: runNonInteractiveSpy,
|
||||
}));
|
||||
|
||||
const terminalNotificationMocks = vi.hoisted(() => ({
|
||||
notifyViaTerminal: vi.fn().mockResolvedValue(true),
|
||||
buildRunEventNotificationContent: vi.fn(() => ({
|
||||
title: 'Session complete',
|
||||
body: 'done',
|
||||
subtitle: 'Run finished',
|
||||
})),
|
||||
}));
|
||||
vi.mock('./utils/terminalNotifications.js', () => ({
|
||||
notifyViaTerminal: terminalNotificationMocks.notifyViaTerminal,
|
||||
buildRunEventNotificationContent:
|
||||
terminalNotificationMocks.buildRunEventNotificationContent,
|
||||
}));
|
||||
|
||||
vi.mock('@google/gemini-cli-core', async (importOriginal) => {
|
||||
const actual =
|
||||
await importOriginal<typeof import('@google/gemini-cli-core')>();
|
||||
@@ -837,6 +853,10 @@ describe('gemini.tsx main function kitty protocol', () => {
|
||||
expect(runNonInteractive).toHaveBeenCalled();
|
||||
const callArgs = vi.mocked(runNonInteractive).mock.calls[0][0];
|
||||
expect(callArgs.input).toBe('stdin-data\n\ntest-question');
|
||||
expect(
|
||||
terminalNotificationMocks.buildRunEventNotificationContent,
|
||||
).not.toHaveBeenCalled();
|
||||
expect(terminalNotificationMocks.notifyViaTerminal).not.toHaveBeenCalled();
|
||||
expect(processExitSpy).toHaveBeenCalledWith(0);
|
||||
processExitSpy.mockRestore();
|
||||
});
|
||||
@@ -1175,7 +1195,9 @@ describe('startInteractiveUI', () => {
|
||||
},
|
||||
},
|
||||
} as LoadedSettings;
|
||||
const mockStartupWarnings = ['warning1'];
|
||||
const mockStartupWarnings: StartupWarning[] = [
|
||||
{ id: 'w1', message: 'warning1', priority: WarningPriority.High },
|
||||
];
|
||||
const mockWorkspaceRoot = '/root';
|
||||
const mockInitializationResult = {
|
||||
authError: null,
|
||||
@@ -1208,7 +1230,7 @@ describe('startInteractiveUI', () => {
|
||||
async function startTestInteractiveUI(
|
||||
config: Config,
|
||||
settings: LoadedSettings,
|
||||
startupWarnings: string[],
|
||||
startupWarnings: StartupWarning[],
|
||||
workspaceRoot: string,
|
||||
resumedSessionData: ResumedSessionData | undefined,
|
||||
initializationResult: InitializationResult,
|
||||
|
||||
+33
-16
@@ -11,6 +11,7 @@ import { loadCliConfig, parseArguments } from './config/config.js';
|
||||
import * as cliConfig from './config/config.js';
|
||||
import { readStdin } from './utils/readStdin.js';
|
||||
import { basename } from 'node:path';
|
||||
import { createHash } from 'node:crypto';
|
||||
import v8 from 'node:v8';
|
||||
import os from 'node:os';
|
||||
import dns from 'node:dns';
|
||||
@@ -37,6 +38,8 @@ import {
|
||||
cleanupExpiredSessions,
|
||||
} from './utils/sessionCleanup.js';
|
||||
import {
|
||||
type StartupWarning,
|
||||
WarningPriority,
|
||||
type Config,
|
||||
type ResumedSessionData,
|
||||
type OutputPayload,
|
||||
@@ -99,6 +102,7 @@ import { createPolicyUpdater } from './config/policy.js';
|
||||
import { ScrollProvider } from './ui/contexts/ScrollProvider.js';
|
||||
import { isAlternateBufferEnabled } from './ui/hooks/useAlternateBuffer.js';
|
||||
import { TerminalProvider } from './ui/contexts/TerminalContext.js';
|
||||
import { OverflowProvider } from './ui/contexts/OverflowContext.js';
|
||||
|
||||
import { setupTerminalAndTheme } from './utils/terminalTheme.js';
|
||||
import { profiler } from './ui/components/DebugProfiler.js';
|
||||
@@ -180,7 +184,7 @@ ${reason.stack}`
|
||||
export async function startInteractiveUI(
|
||||
config: Config,
|
||||
settings: LoadedSettings,
|
||||
startupWarnings: string[],
|
||||
startupWarnings: StartupWarning[],
|
||||
workspaceRoot: string = process.cwd(),
|
||||
resumedSessionData: ResumedSessionData | undefined,
|
||||
initializationResult: InitializationResult,
|
||||
@@ -235,17 +239,19 @@ export async function startInteractiveUI(
|
||||
>
|
||||
<TerminalProvider>
|
||||
<ScrollProvider>
|
||||
<SessionStatsProvider>
|
||||
<VimModeProvider settings={settings}>
|
||||
<AppContainer
|
||||
config={config}
|
||||
startupWarnings={startupWarnings}
|
||||
version={version}
|
||||
resumedSessionData={resumedSessionData}
|
||||
initializationResult={initializationResult}
|
||||
/>
|
||||
</VimModeProvider>
|
||||
</SessionStatsProvider>
|
||||
<OverflowProvider>
|
||||
<SessionStatsProvider>
|
||||
<VimModeProvider settings={settings}>
|
||||
<AppContainer
|
||||
config={config}
|
||||
startupWarnings={startupWarnings}
|
||||
version={version}
|
||||
resumedSessionData={resumedSessionData}
|
||||
initializationResult={initializationResult}
|
||||
/>
|
||||
</VimModeProvider>
|
||||
</SessionStatsProvider>
|
||||
</OverflowProvider>
|
||||
</ScrollProvider>
|
||||
</TerminalProvider>
|
||||
</MouseProvider>
|
||||
@@ -580,7 +586,7 @@ export async function main() {
|
||||
|
||||
const policyEngine = config.getPolicyEngine();
|
||||
const messageBus = config.getMessageBus();
|
||||
createPolicyUpdater(policyEngine, messageBus);
|
||||
createPolicyUpdater(policyEngine, messageBus, config.storage);
|
||||
|
||||
// Register SessionEnd hook to fire on graceful exit
|
||||
// This runs before telemetry shutdown in runExitCleanup()
|
||||
@@ -668,9 +674,20 @@ export async function main() {
|
||||
}
|
||||
|
||||
let input = config.getQuestion();
|
||||
const startupWarnings = [
|
||||
...(await getStartupWarnings()),
|
||||
...(await getUserStartupWarnings(settings.merged)),
|
||||
const useAlternateBuffer = shouldEnterAlternateScreen(
|
||||
isAlternateBufferEnabled(settings),
|
||||
config.getScreenReader(),
|
||||
);
|
||||
const rawStartupWarnings = await getStartupWarnings();
|
||||
const startupWarnings: StartupWarning[] = [
|
||||
...rawStartupWarnings.map((message) => ({
|
||||
id: `startup-${createHash('sha256').update(message).digest('hex').substring(0, 16)}`,
|
||||
message,
|
||||
priority: WarningPriority.High,
|
||||
})),
|
||||
...(await getUserStartupWarnings(settings.merged, undefined, {
|
||||
isAlternateBuffer: useAlternateBuffer,
|
||||
})),
|
||||
];
|
||||
|
||||
// Handle --resume flag
|
||||
|
||||
@@ -9,14 +9,6 @@ import { main } from './gemini.js';
|
||||
import { debugLogger } from '@google/gemini-cli-core';
|
||||
import { type Config } from '@google/gemini-cli-core';
|
||||
|
||||
// Custom error to identify mock process.exit calls
|
||||
class MockProcessExitError extends Error {
|
||||
constructor(readonly code?: string | number | null | undefined) {
|
||||
super('PROCESS_EXIT_MOCKED');
|
||||
this.name = 'MockProcessExitError';
|
||||
}
|
||||
}
|
||||
|
||||
vi.mock('@google/gemini-cli-core', async (importOriginal) => {
|
||||
const actual =
|
||||
await importOriginal<typeof import('@google/gemini-cli-core')>();
|
||||
@@ -124,10 +116,39 @@ vi.mock('./validateNonInterActiveAuth.js', () => ({
|
||||
validateNonInteractiveAuth: vi.fn().mockResolvedValue({}),
|
||||
}));
|
||||
|
||||
vi.mock('./core/initializer.js', () => ({
|
||||
initializeApp: vi.fn().mockResolvedValue({
|
||||
authError: null,
|
||||
themeError: null,
|
||||
shouldOpenAuthDialog: false,
|
||||
geminiMdFileCount: 0,
|
||||
}),
|
||||
}));
|
||||
|
||||
vi.mock('./nonInteractiveCli.js', () => ({
|
||||
runNonInteractive: vi.fn().mockResolvedValue(undefined),
|
||||
}));
|
||||
|
||||
vi.mock('./utils/cleanup.js', async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import('./utils/cleanup.js')>();
|
||||
return {
|
||||
...actual,
|
||||
cleanupCheckpoints: vi.fn().mockResolvedValue(undefined),
|
||||
registerCleanup: vi.fn(),
|
||||
registerSyncCleanup: vi.fn(),
|
||||
registerTelemetryConfig: vi.fn(),
|
||||
runExitCleanup: vi.fn().mockResolvedValue(undefined),
|
||||
};
|
||||
});
|
||||
|
||||
vi.mock('./zed-integration/zedIntegration.js', () => ({
|
||||
runZedIntegration: vi.fn().mockResolvedValue(undefined),
|
||||
}));
|
||||
|
||||
vi.mock('./utils/readStdin.js', () => ({
|
||||
readStdin: vi.fn().mockResolvedValue(''),
|
||||
}));
|
||||
|
||||
const { cleanupMockState } = vi.hoisted(() => ({
|
||||
cleanupMockState: { shouldThrow: false, called: false },
|
||||
}));
|
||||
@@ -169,12 +190,6 @@ describe('gemini.tsx main function cleanup', () => {
|
||||
const debugLoggerErrorSpy = vi
|
||||
.spyOn(debugLogger, 'error')
|
||||
.mockImplementation(() => {});
|
||||
const processExitSpy = vi
|
||||
.spyOn(process, 'exit')
|
||||
.mockImplementation((code) => {
|
||||
throw new MockProcessExitError(code);
|
||||
});
|
||||
|
||||
vi.mocked(loadSettings).mockReturnValue({
|
||||
merged: { advanced: {}, security: { auth: {} }, ui: {} },
|
||||
workspace: { settings: {} },
|
||||
@@ -201,7 +216,7 @@ describe('gemini.tsx main function cleanup', () => {
|
||||
getMcpServers: () => ({}),
|
||||
getMcpClientManager: vi.fn(),
|
||||
getIdeMode: vi.fn(() => false),
|
||||
getExperimentalZedIntegration: vi.fn(() => false),
|
||||
getExperimentalZedIntegration: vi.fn(() => true),
|
||||
getScreenReader: vi.fn(() => false),
|
||||
getGeminiMdFileCount: vi.fn(() => 0),
|
||||
getProjectRoot: vi.fn(() => '/'),
|
||||
@@ -224,18 +239,12 @@ describe('gemini.tsx main function cleanup', () => {
|
||||
getRemoteAdminSettings: vi.fn(() => undefined),
|
||||
} as any); // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||
|
||||
try {
|
||||
await main();
|
||||
} catch (e) {
|
||||
if (!(e instanceof MockProcessExitError)) throw e;
|
||||
}
|
||||
await main();
|
||||
|
||||
expect(cleanupMockState.called).toBe(true);
|
||||
expect(debugLoggerErrorSpy).toHaveBeenCalledWith(
|
||||
'Failed to cleanup expired sessions:',
|
||||
expect.objectContaining({ message: 'Cleanup failed' }),
|
||||
);
|
||||
expect(processExitSpy).toHaveBeenCalledWith(0); // Should not exit on cleanup failure
|
||||
processExitSpy.mockRestore();
|
||||
});
|
||||
});
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user