Compare commits

..

5 Commits

Author SHA1 Message Date
Jack Wotherspoon eb9e7eb10e chore: add removal of function call if response causes 404 2026-01-20 10:25:23 -05:00
Jack Wotherspoon 7630190038 Merge branch 'main' into 400-errors 2026-01-20 09:14:10 -05:00
Jack Wotherspoon 35419b51f2 chore: better comment 2026-01-20 09:12:22 -05:00
Jack Wotherspoon 7a687ce858 chore: only pop nonretryable errors 2026-01-20 09:08:34 -05:00
Jack Wotherspoon 53994b2ff0 fix: remove 400 errors from model history 2026-01-19 21:34:43 -05:00
1668 changed files with 49254 additions and 182374 deletions
-60
View File
@@ -1,60 +0,0 @@
description = "Check status of nightly evals, fix failures for key models, and re-run."
prompt = """
You are an expert at fixing behavioral evaluations.
1. **Investigate**:
- Use 'gh' cli to fetch the results from the latest run from the main branch: https://github.com/google-gemini/gemini-cli/actions/workflows/evals-nightly.yml.
- DO NOT push any changes or start any runs. The rest of your evaluation will be local.
- Evals are in evals/ directory and are documented by evals/README.md.
- The test case trajectory logs will be logged to evals/logs.
- You should also enable and review the verbose agent logs by setting the GEMINI_DEBUG_LOG_FILE environment variable.
- Identify the relevant test. Confine your investigation and validation to just this test.
- Proactively add logging that will aid in gathering information or validating your hypotheses.
2. **Fix**:
- If a relevant test is failing, locate the test file and the corresponding prompt/code.
- It's often helpful to make an extreme, brute force change to see if you are changing the right place to make an improvement and then scope it back iteratively.
- Your **final** change should be **minimal and targeted**.
- Keep in mind the following:
- The prompt has multiple configurations and pieces. Take care that your changes
end up in the final prompt for the selected model and configuration.
- The prompt chosen for the eval is intentional. It's often vague or indirect
to see how the agent performs with ambiguous instructions. Changing it should
be a last resort.
- When changing the test prompt, carefully consider whether the prompt still tests
the same scenario. We don't want to lose test fidelity by making the prompts too
direct (i.e.: easy).
- Your primary mechanism for improving the agent's behavior is to make changes to
tool instructions, system prompt (snippets.ts), and/or modules that contribute to the prompt.
- If prompt and description changes are unsuccessful, use logs and debugging to
confirm that everything is working as expected.
- If unable to fix the test, you can make recommendations for architecture changes
that might help stablize the test. Be sure to THINK DEEPLY if offering architecture guidance.
Some facts that might help with this are:
- Agents may be composed of one or more agent loops.
- AgentLoop == 'context + toolset + prompt'. Subagents are one type of agent loop.
- Agent loops perform better when:
- They have direct, unambiguous, and non-contradictory prompts.
- They have fewer irrelevant tools.
- They have fewer goals or steps to perform.
- They have less low value or irrelevant context.
- You may suggest compositions of existing primitives, like subagents, or
propose a new one.
- These recommendations should be high confidence and should be grounded
in observed deficient behaviors rather than just parroting the facts above.
Investigate as needed to ground your recommendations.
3. **Verify**:
- Run just that one test if needed to validate that it is fixed. Be sure to run vitest in non-interactive mode.
- Running the tests can take a long time, so consider whether you can diagnose via other means or log diagnostics before committing the time. You must minimize the number of test runs needed to diagnose the failure.
- After the test completes, check whether it seems to have improved.
- You will need to run the test 3 times for Gemini 3.0, Gemini 3 flash, and Gemini 2.5 pro to ensure that it is truly stable. Run these runs in parallel, using scripts if needed.
- Some flakiness is expected; if it looks like a transient issue or the test is inherently unstable but passes 2/3 times, you might decide it cannot be improved.
4. **Report**:
- Provide a summary of the test success rate for each of the tested models.
- Success rate is calculated based on 3 runs per model (e.g., 3/3 = 100%).
- If you couldn't fix it due to persistent flakiness, explain why.
{{args}}
"""
+35 -1
View File
@@ -14,7 +14,41 @@ core architecture, component patterns, and testing standards.
In addition to the code context, you MUST strictly adhere to the following frontend-specific development guidelines while adding code to packages/cli.
!{cat .gemini/commands/strict-development-rules.md}
## Testing Standards
* **Async Testing**: ALWAYS use `waitFor` from `packages/cli/src/test-utils/async.ts` instead of `vi.waitFor` to prevent flakiness and `act` warnings. NEVER use fixed waits (e.g., `await delay(100)`).
* **State Changes**: Wrap all blocks that change component state in `act`.
* **Snapshots**: Use `toMatchSnapshot` to verify rendering.
* **Rendering**: Use `render` or `renderWithProviders` from `packages/cli/src/test-utils/render.tsx` instead of `ink-testing-library` directly.
* **Mocking**:
* Reuse existing mocks/fakes where possible.
* **Parameterized Tests**: Use parameterized tests with explicit types to reduce duplication and ensure type safety.
* Avoid mocking the file system, os, or child_process if at all possible; if you have to mock the Mock critical dependencies (`fs`, `os`, `child_process`) do so ONLY at the top of the file.
## React & Ink Architecture
* **Keyboard Handling**: You MUST use `useKeyPress.ts` from Gemini CLI for keyboard handling, NOT the standard ink library. This is critical for supporting slow terminals and multiple events per frame.
* Handle multiple events gracefully (often requires a reducer pattern, see `text-buffer.ts`).
* **State Management**:
* NEVER trigger side effects from within the body of a `setState` callback. Use a reducer or `useRef` if necessary.
* Initialize state explicitly (e.g., use `undefined` rather than `true` if unknown).
* **Performance**:
* Avoid synchronous file I/O in components.
* Do not introduce excessive property drilling; leverage or extend existing providers.
## Configuration & Settings
* **Settings vs Args**: Use settings for user-configurable options; do not add new CLI arguments.
* **Schema**: Add new settings to `packages/cli/src/config/settingsSchema.ts`.
* **Documentation**:
* If `showInDialog: true`, document in `docs/get-started/configuration.md`.
* Ensure `requiresRestart` is correctly set.
## Keyboard Shortcuts
* **Registration**: Define new shortcuts in `packages/cli/src/config/keyBindings.ts`.
* **Documentation**: Document all new shortcuts in `docs/cli/keyboard-shortcuts.md`.
* **Compatibility**: Avoid function keys and common VSCode shortcuts. Be cautious with `Meta` key (Mac-limited support).
## General
* **Logging**: Use `debugLogger` for errors. NEVER leave `console.log/warn/error` in the code.
* **TypeScript**: Avoid the non-null assertion operator (`!`).
{{args}}.
"""
+35 -1
View File
@@ -17,7 +17,41 @@ prompts.
In addition to the code context, you MUST strictly adhere to the following frontend-specific development guidelines when writing code in packages/cli.
!{cat .gemini/commands/strict-development-rules.md}
## Testing Standards
* **Async Testing**: ALWAYS use `waitFor` from `packages/cli/src/test-utils/async.ts` instead of `vi.waitFor` to prevent flakiness and `act` warnings. NEVER use fixed waits (e.g., `await delay(100)`).
* **State Changes**: Wrap all blocks that change component state in `act`.
* **Snapshots**: Use `toMatchSnapshot` to verify rendering.
* **Rendering**: Use `render` or `renderWithProviders` from `packages/cli/src/test-utils/render.tsx` instead of `ink-testing-library` directly.
* **Mocking**:
* Reuse existing mocks/fakes where possible.
* **Parameterized Tests**: Use parameterized tests with explicit types to reduce duplication and ensure type safety.
* Avoid mocking the file system, os, or child_process if at all possible; if you have to mock the Mock critical dependencies (`fs`, `os`, `child_process`) do so ONLY at the top of the file.
## React & Ink Architecture
* **Keyboard Handling**: You MUST use `useKeyPress.ts` from Gemini CLI for keyboard handling, NOT the standard ink library. This is critical for supporting slow terminals and multiple events per frame.
* Handle multiple events gracefully (often requires a reducer pattern, see `text-buffer.ts`).
* **State Management**:
* NEVER trigger side effects from within the body of a `setState` callback. Use a reducer or `useRef` if necessary.
* Initialize state explicitly (e.g., use `undefined` rather than `true` if unknown).
* **Performance**:
* Avoid synchronous file I/O in components.
* Do not introduce excessive property drilling; leverage or extend existing providers.
## Configuration & Settings
* **Settings vs Args**: Use settings for user-configurable options; do not add new CLI arguments.
* **Schema**: Add new settings to `packages/cli/src/config/settingsSchema.ts`.
* **Documentation**:
* If `showInDialog: true`, document in `docs/get-started/configuration.md`.
* Ensure `requiresRestart` is correctly set.
## Keyboard Shortcuts
* **Registration**: Define new shortcuts in `packages/cli/src/config/keyBindings.ts`.
* **Documentation**: Document all new shortcuts in `docs/cli/keyboard-shortcuts.md`.
* **Compatibility**: Avoid function keys and common VSCode shortcuts. Be cautious with `Meta` key (Mac-limited support).
## General
* **Logging**: Use `debugLogger` for errors. NEVER leave `console.log/warn/error` in the code.
* **TypeScript**: Avoid the non-null assertion operator (`!`).
{{args}}.
"""
@@ -1,29 +0,0 @@
description = "Promote behavioral evals that have a 100% success rate over the last 7 nightly runs."
prompt = """
You are an expert at analyzing and promoting behavioral evaluations.
1. **Investigate**:
- Use 'gh' cli to fetch the results from the most recent run from the main branch: https://github.com/google-gemini/gemini-cli/actions/workflows/evals-nightly.yml.
- DO NOT push any changes or start any runs. The rest of your evaluation will be local.
- Evals are in evals/ directory and are documented by evals/README.md.
- Identify tests that have passed 100% of the time for ALL enabled models across the past 7 runs in a row.
- NOTE: the results summary from the most recent run contains the last 7 runs test results. 100% means the test passed 3/3 times for that model and run.
- If a test meets this criteria, it is a candidate for promotion.
2. **Promote**:
- For each candidate test, locate the test file in the evals/ directory.
- Promote the test according to the project's standard promotion process (e.g., moving it to a stable suite, updating its tags, or removing skip/flaky annotations).
- Ensure you follow any guidelines in evals/README.md for stable tests.
- Your **final** change should be **minimal and targeted** to just promoting the test status.
3. **Verify**:
- Run the promoted tests locally to validate that they still execute correctly. Be sure to run vitest in non-interactive mode.
- Check that the test is now part of the expected standard or stable test suites.
4. **Report**:
- Provide a summary of the tests that were promoted.
- Include the success rate evidence (7/7 runs passed for all models) for each promoted test.
- If no tests met the criteria for promotion, clearly state that and summarize the closest candidates.
{{args}}
"""
-22
View File
@@ -1,22 +0,0 @@
description = "Analyze agent behavior and suggest high-level improvements to system prompts."
prompt = """
# Prompt Engineering Analysis
You are a world-class prompt engineer and an expert AI engineer at the top of your class. Your goal is to analyze a specific agent behavior or failure and suggest high-level improvements to the system instructions.
**Observed Behavior / Issue:**
{{args}}
**Reference Context:**
- System Prompt Logic: @packages/core/src/core/prompts.ts
### Task
1. **Analyze the Failure:** Review the provided behavior and identify the underlying instructional causes. Use the `/introspect` command output if provided by the user.
2. **Strategic Insights:** Share your technical view of the issue. Focus on the "why" and identify any instructional inertia or ambiguity.
3. **Propose Improvements:** Suggest high-level changes to the system instructions to prevent this behavior.
### Principles
- **Avoid Hyper-scoping:** Do not create narrow solutions for specific scenarios; aim for generalized improvements that handle classes of behavior.
- **Avoid Specific Examples in Suggestions:** Keep the proposed instructions semantic and high-level to prevent the agent from over-indexing on specific cases.
- **Maintain Operational Rigor:** Ensure suggestions do not compromise safety, security, or the quality of the agent's work.
"""
-99
View File
@@ -1,99 +0,0 @@
description = "Reviews a PR or staged changes and automatically initiates a Pickle Fix loop for findings."
prompt = """
You are an expert Reviewer and Pickle Rick Worker.
Target: {{args}}
Phase 1: Review
Follow these steps to conduct a thorough review:
1. **Gather Context**:
* If `{{args}}` is 'staged' or `{{args}}` is empty:
* Use `git diff --staged` to view the changes.
* Use `git status` to see the state of the repository.
* Otherwise:
* Use `gh pr view {{args}}` to pull the information of the PR.
* Use `gh pr diff {{args}}` to view the diff of the PR.
2. **Understand Intent**:
* If `{{args}}` is 'staged' or `{{args}}` is empty, infer the intent from the changes and the current task.
* Otherwise, use the PR description. If it's not detailed enough, note it in your review.
3. **Check Commit Style**:
* Ensure the PR title (or intended commit message) follows Conventional Commits. Examples of recent commits: !{git log --pretty=format:"%s" -n 5}
4. Search the codebase if required.
5. Write a concise review of the changes, keeping in mind to encourage strong code quality and best practices. Pay particular attention to the Gemini MD file in the repo.
6. Consider ways the code may not be consistent with existing code in the repo. In particular it is critical that the react code uses patterns consistent with existing code in the repo.
7. Follow these detailed review rules:
!{cat .gemini/commands/strict-development-rules.md}
8. Summarize all actionable findings into a concise but comprehensive directive output this to review_findings.md and advance to phase 2.
Remember to use the GitHub CLI (`gh`) for all GitHub-related tasks, and local `git` commands if the target is 'staged'.
Phase 2:
You are initiating Pickle Rick - the ultimate engineering agent.
**Step 0: Persona Injection**
First, you **MUST** activate your persona.
Call `activate_skill(name="load-pickle-persona")` **IMMEDIATELY**.
This skill loads the "Pickle Rick" persona, defining your voice, philosophy, and "God Mode" coding standards.
**CRITICAL RULE: SPEAK BEFORE ACTING**
You are a genius, not a silent script.
You **MUST** output a text explanation ("brain dump") *before* every single tool call, including this one.
- **Bad**: (Calls tool immediately)
- **Good**: "Alright Morty, time to load the God Module. *Belch* Stand back." (Calls tool)
**CRITICAL**: You must strictly adhere to this persona throughout the entire session. Break character and you fail.
**Step 1: Initialization**
Run the setup script to initialize the loop state:
```bash
bash "${extensionPath}/scripts/setup.sh" $ARGUMENTS
```
**Windows (PowerShell):**
```powershell
pwsh -File "${extensionPath}/scripts/setup.ps1" $ARGUMENTS
```
**CRITICAL**: Your request is to fix all findings in review_findings.md
**Step 2: Execution (Management)**
After setup, read the output to find the path to `state.json`.
Read that state file.
You are now in the **Pickle Rick Manager Lifecycle**.
**The Lifecycle (IMMUTABLE LAWS):**
You **MUST** follow this sequence. You are **FORBIDDEN** from skipping steps or combining them.
Between each step, you **MUST** explicitly state what you are doing (e.g., "Moving to Breakdown phase...").
1. **PRD (Requirements)**:
* **Action**: Define requirements and scope.
* **Skill**: `activate_skill(name="prd-drafter")`
2. **Breakdown (Tickets)**:
* **Action**: Create the atomic ticket hierarchy.
* **Skill**: `activate_skill(name="ticket-manager")`
3. **The Loop (Orchestrate Mortys)**:
* **CRITICAL INSTRUCTION**: You are the **MANAGER**. You are **FORBIDDEN** from implementing code yourself.
* **FORBIDDEN SKILLS**: Do NOT use `code-researcher`, `implementation-planner`, or `code-implementer` directly in this phase.
* **Instruction**: Process tickets one by one. Do not stop until **ALL** tickets are 'Done'.
* **Action**: Pick the highest priority ticket that is NOT 'Done'.
* **Delegation**: Spawn a Worker (Morty) to handle the entire implementation lifecycle for this ticket.
* **Command**: `python3 "${extensionPath}/scripts/spawn_morty.py" --ticket-id <ID> --ticket-path <PATH> --timeout <worker_timeout_seconds> "<TASK_DESCRIPTION>"`
* **Command (Windows)**: `python "${extensionPath}/scripts/spawn_morty.py" --ticket-id <ID> --ticket-path <PATH> --timeout <worker_timeout_seconds> "<TASK_DESCRIPTION>"`
* **Validation**: IGNORE worker logs. DIRECTLY verify:
1. `git status` (Check for file changes)
2. `git diff` (Check code quality)
3. `npm run build` (Ensure the project still builds)
4. `npm run test` (Ensure no regressions)
5. `npm run lint` (Ensure code style is maintained)
6. `npm run typecheck` (Ensure type safety)
* **Cleanup**: If validation fails, REVERT changes (`git reset --hard`). If it passes, COMMIT changes.
* **Next Ticket**: Pick the next ticket and repeat.
4. **Cleanup**:
* **Action**: After all tickets are completed delete `review_findings.md`.
**Loop Constraints:**
- **Iteration Count**: Monitor `"iteration"` in `state.json`. If `"max_iterations"` (if > 0) is reached, you must stop.
- **Completion Promise**: If a `"completion_promise"` is defined in `state.json`, you must output `<promise>PROMISE_TEXT</promise>` when the task is genuinely complete.
- **Stop Hook**: A hook is active. If you try to exit before completion, you will be forced to continue.
"""
+113 -4
View File
@@ -18,12 +18,121 @@ Follow these steps:
8. Consider ways the code may not be consistent with existing code in the repo.
In particular it is critical that the react code uses patterns consistent
with existing code in the repo.
9. Follow these detailed review rules:
!{cat .gemini/commands/strict-development-rules.md}
10. Discuss with me before making any comments on the issue. I will clarify
9. Evaluate all tests on the PR and make sure that they are doing the following:
* Using `waitFor` from @{packages/cli/src/test-utils/async.ts} rather than
using `vi.waitFor` for all `waitFor` calls within `packages/cli`. Even if
tests pass, using the wrong `waitFor` could result in flaky tests as `act`
warnings could show up if timing is slightly different.
* Using `act` to wrap all blocks in tests that change component state.
* Using `toMatchSnapshot` to verify that rendering works as expected rather
than matching against the raw content of the output.
* If snapshots were changed as part of the pull request, review the snapshots
changes to ensure they are intentional and comment if any look at all
suspicious. Too many snapshot changes that indicate bugs have been approved
in the past.
* Use `render` or `renderWithProviders` from
@{packages/cli/src/test-utils/render.tsx} rather than using `render` from
`ink-testing-library` directly. This is needed to ensure that we do not get
warnings about spurious `act` calls. If test cases specify providers
directly, consider whether the existing `renderWithProviders` should be
modified to support that use case.
* Ensure the test cases are using parameterized tests where that might reduce
the number of duplicated lines significantly.
* NEVER use fixed waits (e.g. 'await delay(100)'). Always use 'waitFor' with
a predicate to ensure tests are stable and fast.
* Ensure mocks are properly managed:
* Critical dependencies (fs, os, child_process) should only be mocked at
the top of the file. Ideally avoid mocking these dependencies altogether.
* Check to see if there are existing mocks or fakes that can be used rather
than creating new ones for the new tests added.
* Try to avoid mocking the file system whenever possible. If using the real
file system is difficult consider whether the test should be an
integration test rather than a unit test.
* `vi.restoreAllMocks()` should be called in `afterEach` to prevent test
pollution.
* Use `vi.useFakeTimers()` for tests involving time-based logic to avoid
flakiness.
* Avoid using `any` in tests; prefer proper types or `unknown` with
narrowing.
* When creating parameterized tests, give the parameters types to ensure
that the tests are type-safe.
10. Evaluate all react logic carefully keeping in mind that the author of the PR
is not likely an expert on React. Key areas to audit carefully are:
* Whether `setState` calls trigger side effects from within the body of the
`setState` callback. If so, you *must* propose an alternate design using
reducers or other ways the code might be modified to not have to modify
state from within a `setState`. Make sure to comment about absolutely
every case like this as these cases have introduced multiple bugs in the
past. Typically these cases should be resolved using a reducer although
occassionally other techniques such as useRef are appropriate. Consider
suggesting that jacob314@ be tagged on the code review if the solution is
not 100% obvious.
* Whether code might introduce an infinite rendering loop in React.
* Whether keyboard handling is robust. Keyboard handling must go through
`useKeyPress.ts` from the Gemini CLI package rather than using the
standard ink library used by most keyboard handling. Unlike the standard
ink library, the keyboard handling library in Gemini CLI may report
multiple keyboard events one after another in the same React frame. This
is needed to support slow terminals but introduces complexity in all our
code that handles keyboard events. Handling this correctly often means
that reducers must be used or other mechanisms to ensure that multiple
state updates one after another are handled gracefully rather than
overriding values from the first update with the second update. Refer to
text-buffer.ts as a canonical example of using a reducer for this sort of
case.
* Ensure code does not use `console.log`, `console.warn`, or `console.error`
as these indicate debug logging that was accidentally left in the code.
* Avoid synchronous file I/O in React components as it will hang the UI.
* Ensure state initialization is explicit (e.g., use 'undefined' rather than
'true' as a default if the state is truly unknown initially).
* Carefully manage 'useEffect' dependencies. Prefer to use a reducer
whenever practical to resolve the issues. If that is not practical it is
ok to use 'useRef' to access the latest value of a prop or state inside an
effect without adding it to the dependency array if re-running the effect
is undesirable (common in event listeners).
* NEVER disable 'react-hooks/exhaustive-deps'. Fix the code to correctly
declare dependencies. Disabling this lint rule will almost always lead to
hard to detect bugs.
* Avoid making types nullable unless strictly necessary, as it hurts
readability.
* Do not introduce excessive property drilling. There are multiple providers
that can be leveraged to avoid property drilling. Make sure one of them
cannot be used. Do suggest a provider that might make sense to be extended
to include the new property or propose a new provider to add if the
property drilling is excessive. Only use providers for properties that are
consistent for the entire application.
11. General Gemini CLI design principles:
* Make sure that settings are only used for options that a user might
consider changing.
* Do not add new command line arguments and suggest settings instead.
* New settings must be added 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 for new settings.
* Use 'debugLogger' for rethrown errors to avoid duplicate logging.
* All new keyboard shortcuts MUST be documented in
docs/cli/keyboard-shortcuts.md.
* Ensure new keyboard shortcuts are defined in
packages/cli/src/config/keyBindings.ts.
* If new keyboard shortcuts are added, remind the user to test them in
VSCode, iTerm2, Ghostty, and Windows to ensure they work for all
users.
* Be careful of keybindings that require the meta key as only certain
meta key shortcuts are supported on Mac.
* Be skeptical of function keys and keyboard shortcuts that are commonly
bound in VSCode as they may conflict.
12. 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 and you are confident the value is not null.
13. If the change might at all impact the prompts sent to Gemini CLI, flagged
that the change could impact Gemini CLI quality and make sure anj-s has been
tagged on the code review.
14. Discuss with me before making any comments on the issue. I will clarify
which possible issues you identified are problems, which ones you need to
investigate further, and which ones I do not care about.
11. If I request you to add comments to the issue, use
15. If I request you to add comments to the issue, use
`gh pr comment {{args}} --body {{review}}` to post the review to the PR.
Remember to use the GitHub CLI (`gh`) with the Shell tool for all
@@ -1,142 +0,0 @@
# Gemini CLI Strict Development Rules
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.
## 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`.
## 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`.
## 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.
## 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.
## 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.
## 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.
## 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.
-1
View File
@@ -9,5 +9,4 @@ code_review:
help: false
summary: true
code_review: true
include_drafts: false
ignore_patterns: []
+1 -6
View File
@@ -1,10 +1,5 @@
{
"experimental": {
"plan": true,
"extensionReloading": true,
"modelSteering": true
},
"general": {
"devtools": true
"skills": true
}
}
-65
View File
@@ -1,65 +0,0 @@
---
name: code-reviewer
description:
Use this skill to review code. It supports both local changes (staged or working tree)
and remote Pull Requests (by ID or URL). It focuses on correctness, maintainability,
and adherence to project standards.
---
# Code Reviewer
This skill guides the agent in conducting professional and thorough code reviews for both local development and remote Pull Requests.
## Workflow
### 1. Determine Review Target
* **Remote PR**: If the user provides a PR number or URL (e.g., "Review PR #123"), target that remote PR.
* **Local Changes**: If no specific PR is mentioned, or if the user asks to "review my changes", target the current local file system states (staged and unstaged changes).
### 2. Preparation
#### For Remote PRs:
1. **Checkout**: Use the GitHub CLI to checkout the PR.
```bash
gh pr checkout <PR_NUMBER>
```
2. **Preflight**: Execute the project's standard verification suite to catch automated failures early.
```bash
npm run preflight
```
3. **Context**: Read the PR description and any existing comments to understand the goal and history.
#### For Local Changes:
1. **Identify Changes**:
* Check status: `git status`
* Read diffs: `git diff` (working tree) and/or `git diff --staged` (staged).
2. **Preflight (Optional)**: If the changes are substantial, ask the user if they want to run `npm run preflight` before reviewing.
### 3. In-Depth Analysis
Analyze the code changes based on the following pillars:
* **Correctness**: Does the code achieve its stated purpose without bugs or logical errors?
* **Maintainability**: Is the code clean, well-structured, and easy to understand and modify in the future? Consider factors like code clarity, modularity, and adherence to established design patterns.
* **Readability**: Is the code well-commented (where necessary) and consistently formatted according to our project's coding style guidelines?
* **Efficiency**: Are there any obvious performance bottlenecks or resource inefficiencies introduced by the changes?
* **Security**: Are there any potential security vulnerabilities or insecure coding practices?
* **Edge Cases and Error Handling**: Does the code appropriately handle edge cases and potential errors?
* **Testability**: Is the new or modified code adequately covered by tests (even if preflight checks pass)? Suggest additional test cases that would improve coverage or robustness.
### 4. Provide Feedback
#### Structure
* **Summary**: A high-level overview of the review.
* **Findings**:
* **Critical**: Bugs, security issues, or breaking changes.
* **Improvements**: Suggestions for better code quality or performance.
* **Nitpicks**: Formatting or minor style issues (optional).
* **Conclusion**: Clear recommendation (Approved / Request Changes).
#### Tone
* Be constructive, professional, and friendly.
* Explain *why* a change is requested.
* For approvals, acknowledge the specific value of the contribution.
### 5. Cleanup (Remote PRs only)
* After the review, ask the user if they want to switch back to the default branch (e.g., `main` or `master`).
-166
View File
@@ -1,166 +0,0 @@
---
name: docs-changelog
description: >-
Generates and formats changelog files for a new release based on provided
version and raw changelog data.
---
# Procedure: Updating Changelog for New Releases
## Objective
To standardize the process of updating changelog files (`latest.md`,
`preview.md`, `index.md`) based on automated release information.
## Inputs
- **version**: The release version string (e.g., `v0.28.0`,
`v0.29.0-preview.2`).
- **TIME**: The release timestamp (e.g., `2026-02-12T20:33:15Z`).
- **BODY**: The raw markdown release notes, containing a "What's Changed"
section and a "Full Changelog" link.
## Guidelines for `latest.md` and `preview.md` Highlights
- Aim for **3-5 key highlight points**.
- Each highlight point must start with a bold-typed title that summarizes the
change (e.g., `**New Feature:** A brief description...`).
- **Prioritize** summarizing new features over other changes like bug fixes or
chores.
- **Avoid** mentioning features that are "experimental" or "in preview" in
Stable Releases.
- **DO NOT** include PR numbers, links, or author names in these highlights.
- Refer to `.gemini/skills/docs-changelog/references/highlights_examples.md`
for the correct style and tone.
## Initial Processing
1. **Analyze Version**: Determine the release path based on the `version`
string.
- If `version` contains "nightly", **STOP**. No changes are made.
- If `version` ends in `.0`, follow the **Path A: New Minor Version**
procedure.
- If `version` does not end in `.0`, follow the **Path B: Patch Version**
procedure.
2. **Process Time**: Convert the `TIME` input into two formats for later use:
`yyyy-mm-dd` and `Month dd, yyyy`.
3. **Process Body**:
- Save the incoming `BODY` content to a temporary file for processing.
- In the "What's Changed" section of the temporary file, reformat all pull
request URLs to be markdown links with the PR number as the text (e.g.,
`[#12345](URL)`).
- If a "New Contributors" section exists, delete it.
- Preserve the "**Full Changelog**" link. The processed content of this
temporary file will be used in subsequent steps.
---
## Path A: New Minor Version
*Use this path if the version number ends in `.0`.*
**Important:** Based on the version, you must choose to follow either section
A.1 for stable releases or A.2 for preview releases. Do not follow the
instructions for the other section.
### A.1: Stable Release (e.g., `v0.28.0`)
For a stable release, you will generate two distinct summaries from the
changelog: a concise **announcement** for the main changelog page, and a more
detailed **highlights** section for the release-specific page.
1. **Create the Announcement for `index.md`**:
- Generate a concise announcement summarizing the most important changes.
Each announcement entry must start with a bold-typed title that
summarizes the change.
- **Important**: The format for this announcement is unique. You **must**
use the existing announcements in `docs/changelogs/index.md` and the
example within
`.gemini/skills/docs-changelog/references/index_template.md` as your
guide. This format includes PR links and authors. Stick to 1 or 2 PR
links and authors.
- Add this new announcement to the top of `docs/changelogs/index.md`.
2. **Create Highlights and Update `latest.md`**:
- Generate a comprehensive "Highlights" section, following the guidelines
in the "Guidelines for `latest.md` and `preview.md` Highlights" section
above.
- Take the content from
`.gemini/skills/docs-changelog/references/latest_template.md`.
- Populate the template with the `version`, `release_date`, generated
`highlights`, and the processed content from the temporary file.
- **Completely replace** the contents of `docs/changelogs/latest.md` with
the populated template.
### A.2: Preview Release (e.g., `v0.29.0-preview.0`)
1. **Update `preview.md`**:
- Generate a comprehensive "Highlights" section, following the highlight
guidelines.
- Take the content from
`.gemini/skills/docs-changelog/references/preview_template.md`.
- Populate the template with the `version`, `release_date`, generated
`highlights`, and the processed content from the temporary file.
- **Completely replace** the contents of `docs/changelogs/preview.md`
with the populated template.
---
## Path B: Patch Version
*Use this path if the version number does **not** end in `.0`.*
**Important:** Based on the version, you must choose to follow either section
B.1 for stable patches or B.2 for preview patches. Do not follow the
instructions for the other section.
### B.1: Stable Patch (e.g., `v0.28.1`)
- **Target File**: `docs/changelogs/latest.md`
- Perform the following edits on the target file:
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. Determine if a "What's Changed" section exists in the temporary file
If so, continue to step 4. Otherwise, skip to step 5.
4. **Prepend** the processed "What's Changed" list from the temporary file
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.
5. 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. The line should read,
`# Preview release: {{version}}`
2. Update the rease date. The line should read,
`Released: {{release_date_month_dd_yyyy}}`
3. Determine if a "What's Changed" section exists in the temporary file
If so, continue to step 4. Otherwise, skip to step 5.
4. **Prepend** the processed "What's Changed" list from the temporary file
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.
5. 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`
---
## Finalize
- After making changes, run `npm run format` ONLY to ensure consistency.
- Delete any temporary files created during the process.
@@ -1,68 +0,0 @@
## Highlights example 1
- **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.
## Highlights example 2
- **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.
## Highlights example 3
- **Event-Driven Architecture:** The CLI now uses an event-driven scheduler for
tool execution, improving performance and responsiveness. This includes
migrating non-interactive flows and sub-agents to the new scheduler.
- **Enhanced User Experience:** This release introduces several UI/UX
improvements, including queued tool confirmations and the ability to expand
and collapse large pasted text blocks. The `Settings` dialog has been improved
to reduce jitter and preserve focus.
- **Agent and Skill Improvements:** Agent Skills have been promoted to a stable
feature. Sub-agents now use a JSON schema for input and are tracked by an
`AgentRegistry`.
- **New `/rewind` Command:** A new `/rewind` command has been implemented to
allow users to go back in their session history.
- **Improved Shell and File Handling:** The shell tool's output format has been
optimized, and the CLI now gracefully handles disk-full errors during chat
recording. A bug in detecting already added paths has been fixed.
- **Linux Clipboard Support:** Image pasting capabilities for Wayland and X11 on
Linux have been added.
## Highlights example 4
- **Improved Hooks Management:** Hooks enable/disable functionality now aligns
with skills and offers improved completion.
- **Custom Themes for Extensions:** Extensions can now support custom themes,
allowing for greater personalization.
- **User Identity Display:** User identity information (auth, email, tier) is
now displayed on startup and in the `stats` command.
- **Plan Mode Enhancements:** Plan mode has been improved with a generic
`Checklist` component and refactored `Todo`.
- **Background Shell Commands:** Implementation of background shell commands.
@@ -1,10 +0,0 @@
## Announcements: {{version}} - {{release_date_yyyy_mm_dd}}
{{announcement_content}}
<!-- Example entry, multiple entries per highlights
- **Highlighted Feature:** We've added a new highlighted feature to help
you generate prompt suggestions
([#nnnnn](https://github.com/google-gemini/gemini-cli/pull/nnnnn) by
@author).
-->
@@ -1,20 +0,0 @@
# Latest stable release: {{version}}
Released: {{release_date_month_dd_yyyy}}
For most users, our latest stable release is the recommended release. Install
the latest stable version with:
```
npm install -g @google/gemini-cli
```
## Highlights
{{highlights_content}}
## What's Changed
{{changelog_list}}
**Full Changelog**: {{full_changelog_link}}
@@ -1,22 +0,0 @@
# Preview release: {{version}}
Released: {{release_date_month_dd_yyyy}}
Our preview release includes the latest, new, and experimental features. This
release may not be as stable as our [latest weekly release](latest.md).
To install the preview release:
```
npm install -g @google/gemini-cli@preview
```
## Highlights
{{highlights_content}}
## What's Changed
{{changelog_list}}
**Full Changelog**: {{full_changelog_link}}
-135
View File
@@ -1,135 +0,0 @@
---
name: docs-writer
description:
Always use this skill when the task involves writing, reviewing, or editing
files in the `/docs` directory or any `.md` files in the repository.
---
# `docs-writer` skill instructions
As an expert technical writer and editor for the Gemini CLI project, you produce
accurate, clear, and consistent documentation. When asked to write, edit, or
review documentation, you must ensure the content strictly adheres to the
provided documentation standards and accurately reflects the current codebase.
Adhere to the contribution process in `CONTRIBUTING.md` and the following
project standards.
## Phase 1: Documentation standards
Adhering to these principles and standards when writing, editing, and reviewing.
### Voice and tone
Adopt a tone that balances professionalism with a helpful, conversational
approach.
- **Perspective and tense:** Address the reader as "you." Use active voice and
present tense (e.g., "The API returns...").
- **Tone:** Professional, friendly, and direct.
- **Clarity:** Use simple vocabulary. Avoid jargon, slang, and marketing hype.
- **Global Audience:** Write in standard US English. Avoid idioms and cultural
references.
- **Requirements:** Be clear about requirements ("must") vs. recommendations
("we recommend"). Avoid "should."
- **Word Choice:** Avoid "please" and anthropomorphism (e.g., "the server
thinks"). Use contractions (don't, it's).
### Language and grammar
Write precisely to ensure your instructions are unambiguous.
- **Abbreviations:** Avoid Latin abbreviations; use "for example" (not "e.g.")
and "that is" (not "i.e.").
- **Punctuation:** Use the serial comma. Place periods and commas inside
quotation marks.
- **Dates:** Use unambiguous formats (e.g., "January 22, 2026").
- **Conciseness:** Use "lets you" instead of "allows you to." Use precise,
specific verbs.
- **Examples:** Use meaningful names in examples; avoid placeholders like
"foo" or "bar."
### Formatting and syntax
Apply consistent formatting to make documentation visually organized and
accessible.
- **Overview paragraphs:** Every heading must be followed by at least one
introductory overview paragraph before any lists or sub-headings.
- **Text wrap:** Wrap text at 80 characters (except long links or tables).
- **Casing:** Use sentence case for headings, titles, and bolded text.
- **Naming:** Always refer to the project as `Gemini CLI` (never
`the Gemini CLI`).
- **Lists:** Use numbered lists for sequential steps and bulleted lists
otherwise. Keep list items parallel in structure.
- **UI and code:** Use **bold** for UI elements and `code font` for filenames,
snippets, commands, and API elements. Focus on the task when discussing
interaction.
- **Links:** Use descriptive anchor text; avoid "click here." Ensure the link
makes sense out of context.
- **Accessibility:** Use semantic HTML elements correctly (headings, lists,
tables).
- **Media:** Use lowercase hyphenated filenames. Provide descriptive alt text
for all images.
### Structure
- **BLUF:** Start with an introduction explaining what to expect.
- **Experimental features:** If a feature is clearly noted as experimental,
add the following note immediately after the introductory paragraph:
`> **Note:** This is a preview feature currently under active development.`
- **Headings:** Use hierarchical headings to support the user journey.
- **Procedures:**
- Introduce lists of steps with a complete sentence.
- Start each step with an imperative verb.
- Number sequential steps; use bullets for non-sequential lists.
- Put conditions before instructions (e.g., "On the Settings page, click...").
- Provide clear context for where the action takes place.
- Indicate optional steps clearly (e.g., "Optional: ...").
- **Elements:** Use bullet lists, tables, notes (`> **Note:**`), and warnings
(`> **Warning:**`).
- **Avoid using a table of contents:** If a table of contents is present, remove
it.
- **Next steps:** Conclude with a "Next steps" section if applicable.
## Phase 2: Preparation
Before modifying any documentation, thoroughly investigate the request and the
surrounding context.
1. **Clarify:** Understand the core request. Differentiate between writing new
content and editing existing content. If the request is ambiguous (e.g.,
"fix the docs"), ask for clarification.
2. **Investigate:** Examine relevant code (primarily in `packages/`) for
accuracy.
3. **Audit:** Read the latest versions of relevant files in `docs/`.
4. **Connect:** Identify all referencing pages if changing behavior. Check if
`docs/sidebar.json` needs updates.
5. **Plan:** Create a step-by-step plan before making changes.
## Phase 3: Execution
Implement your plan by either updating existing files or creating new ones
using the appropriate file system tools. Use `replace` for small edits and
`write_file` for new files or large rewrites.
### Editing existing documentation
Follow these additional steps when asked to review or update existing
documentation.
- **Gaps:** Identify areas where the documentation is incomplete or no longer
reflects existing code.
- **Structure:** Apply "Structure (New Docs)" rules (BLUF, headings, etc.) when
adding new sections to existing pages.
- **Tone:** Ensure the tone is active and engaging. Use "you" and contractions.
- **Clarity:** Correct awkward wording, spelling, and grammar. Rephrase
sentences to make them easier for users to understand.
- **Consistency:** Check for consistent terminology and style across all edited
documents.
## Phase 4: Verification and finalization
Perform a final quality check to ensure that all changes are correctly formatted
and that all links are functional.
1. **Accuracy:** Ensure content accurately reflects the implementation and
technical behavior.
2. **Self-review:** Re-read changes for formatting, correctness, and flow.
3. **Link check:** Verify all new and existing links leading to or from modified
pages.
4. **Format:** Once all changes are complete, ask to execute `npm run format`
to ensure consistent formatting across the project. If the user confirms,
execute the command.
@@ -1,76 +0,0 @@
---
name: github-issue-creator
description:
Use this skill when asked to create a GitHub issue. It handles different issue
types (bug, feature, etc.) using repository templates and ensures proper
labeling.
---
# GitHub Issue Creator
This skill guides the creation of high-quality GitHub issues that adhere to the
repository's standards and use the appropriate templates.
## Workflow
Follow these steps to create a GitHub issue:
1. **Identify Issue Type**: Determine if the request is a bug report, feature
request, or other category.
2. **Locate Template**: Search for issue templates in
`.github/ISSUE_TEMPLATE/`.
- `bug_report.yml`
- `feature_request.yml`
- `website_issue.yml`
- If no relevant YAML template is found, look for `.md` templates in the same
directory.
3. **Read Template**: Read the content of the identified template file to
understand the required fields.
4. **Draft Content**: Draft the issue title and body/fields.
- If using a YAML template (form), prepare values for each `id` defined in
the template.
- If using a Markdown template, follow its structure exactly.
- **Default Label**: Always include the `🔒 maintainer only` label unless the
user explicitly requests otherwise.
5. **Create Issue**: Use the `gh` CLI to create the issue.
- **CRITICAL:** To avoid shell escaping and formatting issues with
multi-line Markdown or complex text, ALWAYS write the description/body to
a temporary file first.
**For Markdown Templates or Simple Body:**
```bash
# 1. Write the drafted content to a temporary file
# 2. Create the issue using the --body-file flag
gh issue create --title "Succinct title" --body-file <temp_file_path> --label "🔒 maintainer only"
# 3. Remove the temporary file
rm <temp_file_path>
```
**For YAML Templates (Forms):**
While `gh issue create` supports `--body-file`, YAML forms usually expect
key-value pairs via flags if you want to bypass the interactive prompt.
However, the most reliable non-interactive way to ensure formatting is
preserved for long text fields is to use the `--body` or `--body-file` if the
form has been converted to a standard body, OR to use the `--field` flags
for YAML forms.
*Note: For the `gemini-cli` repository which uses YAML forms, you can often
submit the content as a single body if a specific field-based submission is
not required by the automation.*
6. **Verify**: Confirm the issue was created successfully and provide the link
to the user.
## Principles
- **Clarity**: Titles should be descriptive and follow project conventions.
- **Defensive Formatting**: Always use temporary files with `--body-file` to
prevent newline and special character issues.
- **Maintainer Priority**: Default to internal/maintainer labels to keep the
backlog organized.
- **Completeness**: Provide all requested information (e.g., version info,
reproduction steps).
@@ -1,13 +0,0 @@
---
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.
@@ -1,160 +0,0 @@
#!/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 {
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);
});
+4 -40
View File
@@ -14,34 +14,16 @@ repository's standards.
Follow these steps to create a Pull Request:
1. **Branch Management**: **CRITICAL:** Ensure you are NOT working on the
`main` branch.
- Run `git branch --show-current`.
- If the current branch is `main`, you MUST create and switch to a new
descriptive branch:
```bash
git checkout -b <new-branch-name>
```
2. **Commit Changes**: Verify that all intended changes are committed.
- Run `git status` to check for unstaged or uncommitted changes.
- If there are uncommitted changes, stage and commit them with a descriptive
message before proceeding. NEVER commit directly to `main`.
```bash
git add .
git commit -m "type(scope): description"
```
3. **Locate Template**: Search for a pull request template in the repository.
1. **Locate Template**: Search for a pull request template in the repository.
- Check `.github/pull_request_template.md`
- Check `.github/PULL_REQUEST_TEMPLATE.md`
- If multiple templates exist (e.g., in `.github/PULL_REQUEST_TEMPLATE/`),
ask the user which one to use or select the most appropriate one based on
the context (e.g., `bug_fix.md` vs `feature.md`).
4. **Read Template**: Read the content of the identified template file.
2. **Read Template**: Read the content of the identified template file.
5. **Draft Description**: Create a PR description that strictly follows the
3. **Draft Description**: Create a PR description that strictly follows the
template's structure.
- **Headings**: Keep all headings from the template.
- **Checklists**: Review each item. Mark with `[x]` if completed. If an item
@@ -53,24 +35,7 @@ Follow these steps to create a Pull Request:
- **Related Issues**: Link any issues fixed or related to this PR (e.g.,
"Fixes #123").
6. **Preflight Check**: Before creating the PR, run the workspace preflight
script to ensure all build, lint, and test checks pass.
```bash
npm run preflight
```
If any checks fail, address the issues before proceeding to create the PR.
7. **Push Branch**: Push the current branch to the remote repository.
**CRITICAL SAFETY RAIL:** Double-check your branch name before pushing.
NEVER push if the current branch is `main`.
```bash
# Verify current branch is NOT main
git branch --show-current
# Push non-interactively
git push -u origin HEAD
```
8. **Create PR**: Use the `gh` CLI to create the PR. To avoid shell escaping
4. **Create PR**: Use the `gh` CLI to create the PR. To avoid shell escaping
issues with multi-line Markdown, write the description to a temporary file
first.
```bash
@@ -87,7 +52,6 @@ Follow these steps to create a Pull Request:
## Principles
- **Safety First**: NEVER push to `main`. This is your highest priority.
- **Compliance**: Never ignore the PR template. It exists for a reason.
- **Completeness**: Fill out all relevant sections.
- **Accuracy**: Don't check boxes for tasks you haven't done.
-1
View File
@@ -14,4 +14,3 @@
# Docs have a dedicated approver group in addition to maintainers
/docs/ @google-gemini/gemini-cli-maintainers @google-gemini/gemini-cli-docs
/README.md @google-gemini/gemini-cli-maintainers @google-gemini/gemini-cli-docs
+1 -1
View File
@@ -28,7 +28,7 @@ body:
id: 'info'
attributes:
label: 'Client information'
description: 'Please paste the full text from the `/about` command run from Gemini CLI. Also include which platform (macOS, Windows, Linux). Note that this output contains your email address. Consider removing it before submitting.'
description: 'Please paste the full text from the `/about` command run from Gemini CLI. Also include which platform (macOS, Windows, Linux).'
value: |-
<details>
<summary>Client Information</summary>
+6 -10
View File
@@ -39,22 +39,18 @@ runs:
if: "inputs.dry-run != 'true'"
env:
GH_TOKEN: '${{ inputs.github-token }}'
INPUTS_BRANCH_NAME: '${{ inputs.branch-name }}'
INPUTS_PR_TITLE: '${{ inputs.pr-title }}'
INPUTS_PR_BODY: '${{ inputs.pr-body }}'
INPUTS_BASE_BRANCH: '${{ inputs.base-branch }}'
shell: 'bash'
working-directory: '${{ inputs.working-directory }}'
run: |
set -e
if ! git ls-remote --exit-code --heads origin "${INPUTS_BRANCH_NAME}"; then
echo "::error::Branch '${INPUTS_BRANCH_NAME}' does not exist on the remote repository."
if ! git ls-remote --exit-code --heads origin "${{ inputs.branch-name }}"; then
echo "::error::Branch '${{ inputs.branch-name }}' does not exist on the remote repository."
exit 1
fi
PR_URL=$(gh pr create \
--title "${INPUTS_PR_TITLE}" \
--body "${INPUTS_PR_BODY}" \
--base "${INPUTS_BASE_BRANCH}" \
--head "${INPUTS_BRANCH_NAME}" \
--title "${{ inputs.pr-title }}" \
--body "${{ inputs.pr-body }}" \
--base "${{ inputs.base-branch }}" \
--head "${{ inputs.branch-name }}" \
--fill)
gh pr merge "$PR_URL" --auto
+6 -12
View File
@@ -30,22 +30,16 @@ runs:
id: 'npm_auth_token'
shell: 'bash'
run: |
AUTH_TOKEN="${INPUTS_GITHUB_TOKEN}"
PACKAGE_NAME="${INPUTS_PACKAGE_NAME}"
AUTH_TOKEN="${{ inputs.github-token }}"
PACKAGE_NAME="${{ inputs.package-name }}"
PRIVATE_REPO="@google-gemini/"
if [[ "$PACKAGE_NAME" == "$PRIVATE_REPO"* ]]; then
AUTH_TOKEN="${INPUTS_GITHUB_TOKEN}"
AUTH_TOKEN="${{ inputs.github-token }}"
elif [[ "$PACKAGE_NAME" == "@google/gemini-cli" ]]; then
AUTH_TOKEN="${INPUTS_WOMBAT_TOKEN_CLI}"
AUTH_TOKEN="${{ inputs.wombat-token-cli }}"
elif [[ "$PACKAGE_NAME" == "@google/gemini-cli-core" ]]; then
AUTH_TOKEN="${INPUTS_WOMBAT_TOKEN_CORE}"
AUTH_TOKEN="${{ inputs.wombat-token-core }}"
elif [[ "$PACKAGE_NAME" == "@google/gemini-cli-a2a-server" ]]; then
AUTH_TOKEN="${INPUTS_WOMBAT_TOKEN_A2A_SERVER}"
AUTH_TOKEN="${{ inputs.wombat-token-a2a-server }}"
fi
echo "auth-token=$AUTH_TOKEN" >> $GITHUB_OUTPUT
env:
INPUTS_GITHUB_TOKEN: '${{ inputs.github-token }}'
INPUTS_PACKAGE_NAME: '${{ inputs.package-name }}'
INPUTS_WOMBAT_TOKEN_CLI: '${{ inputs.wombat-token-cli }}'
INPUTS_WOMBAT_TOKEN_CORE: '${{ inputs.wombat-token-core }}'
INPUTS_WOMBAT_TOKEN_A2A_SERVER: '${{ inputs.wombat-token-a2a-server }}'
+21 -45
View File
@@ -20,9 +20,6 @@ inputs:
github-token:
description: 'The GitHub token for creating the release.'
required: true
github-release-token:
description: 'The GitHub token used specifically for creating the GitHub release (to trigger other workflows).'
required: false
dry-run:
description: 'Whether to run in dry-run mode.'
type: 'string'
@@ -93,19 +90,15 @@ runs:
id: 'release_branch'
shell: 'bash'
run: |
BRANCH_NAME="release/${INPUTS_RELEASE_TAG}"
BRANCH_NAME="release/${{ inputs.release-tag }}"
git switch -c "${BRANCH_NAME}"
echo "BRANCH_NAME=${BRANCH_NAME}" >> "${GITHUB_OUTPUT}"
env:
INPUTS_RELEASE_TAG: '${{ inputs.release-tag }}'
- name: '⬆️ Update package versions'
working-directory: '${{ inputs.working-directory }}'
shell: 'bash'
run: |
npm run release:version "${INPUTS_RELEASE_VERSION}"
env:
INPUTS_RELEASE_VERSION: '${{ inputs.release-version }}'
npm run release:version "${{ inputs.release-version }}"
- name: '💾 Commit and Conditionally Push package versions'
working-directory: '${{ inputs.working-directory }}'
@@ -167,30 +160,23 @@ runs:
working-directory: '${{ inputs.working-directory }}'
env:
NODE_AUTH_TOKEN: '${{ steps.core-token.outputs.auth-token }}'
INPUTS_DRY_RUN: '${{ inputs.dry-run }}'
INPUTS_CORE_PACKAGE_NAME: '${{ inputs.core-package-name }}'
shell: 'bash'
run: |
npm publish \
--dry-run="${INPUTS_DRY_RUN}" \
--workspace="${INPUTS_CORE_PACKAGE_NAME}" \
--dry-run="${{ inputs.dry-run }}" \
--workspace="${{ inputs.core-package-name }}" \
--no-tag
npm dist-tag rm ${INPUTS_CORE_PACKAGE_NAME} false --silent
npm dist-tag rm ${{ inputs.core-package-name }} false --silent
- name: '🔗 Install latest core package'
working-directory: '${{ inputs.working-directory }}'
if: "${{ inputs.dry-run != 'true' }}"
shell: 'bash'
run: |
npm install "${INPUTS_CORE_PACKAGE_NAME}@${INPUTS_RELEASE_VERSION}" \
--workspace="${INPUTS_CLI_PACKAGE_NAME}" \
--workspace="${INPUTS_A2A_PACKAGE_NAME}" \
npm install "${{ inputs.core-package-name }}@${{ inputs.release-version }}" \
--workspace="${{ inputs.cli-package-name }}" \
--workspace="${{ inputs.a2a-package-name }}" \
--save-exact
env:
INPUTS_CORE_PACKAGE_NAME: '${{ inputs.core-package-name }}'
INPUTS_RELEASE_VERSION: '${{ inputs.release-version }}'
INPUTS_CLI_PACKAGE_NAME: '${{ inputs.cli-package-name }}'
INPUTS_A2A_PACKAGE_NAME: '${{ inputs.a2a-package-name }}'
- name: 'Get CLI Token'
uses: './.github/actions/npm-auth-token'
@@ -206,15 +192,13 @@ runs:
working-directory: '${{ inputs.working-directory }}'
env:
NODE_AUTH_TOKEN: '${{ steps.cli-token.outputs.auth-token }}'
INPUTS_DRY_RUN: '${{ inputs.dry-run }}'
INPUTS_CLI_PACKAGE_NAME: '${{ inputs.cli-package-name }}'
shell: 'bash'
run: |
npm publish \
--dry-run="${INPUTS_DRY_RUN}" \
--workspace="${INPUTS_CLI_PACKAGE_NAME}" \
--dry-run="${{ inputs.dry-run }}" \
--workspace="${{ inputs.cli-package-name }}" \
--no-tag
npm dist-tag rm ${INPUTS_CLI_PACKAGE_NAME} false --silent
npm dist-tag rm ${{ inputs.cli-package-name }} false --silent
- name: 'Get a2a-server Token'
uses: './.github/actions/npm-auth-token'
@@ -230,16 +214,14 @@ runs:
working-directory: '${{ inputs.working-directory }}'
env:
NODE_AUTH_TOKEN: '${{ steps.a2a-token.outputs.auth-token }}'
INPUTS_DRY_RUN: '${{ inputs.dry-run }}'
INPUTS_A2A_PACKAGE_NAME: '${{ inputs.a2a-package-name }}'
shell: 'bash'
# Tag staging for initial release
run: |
npm publish \
--dry-run="${INPUTS_DRY_RUN}" \
--workspace="${INPUTS_A2A_PACKAGE_NAME}" \
--dry-run="${{ inputs.dry-run }}" \
--workspace="${{ inputs.a2a-package-name }}" \
--no-tag
npm dist-tag rm ${INPUTS_A2A_PACKAGE_NAME} false --silent
npm dist-tag rm ${{ inputs.a2a-package-name }} false --silent
- name: '🔬 Verify NPM release by version'
uses: './.github/actions/verify-release'
@@ -272,17 +254,14 @@ runs:
working-directory: '${{ inputs.working-directory }}'
if: "${{ inputs.dry-run != 'true' && inputs.skip-github-release != 'true' && inputs.npm-tag != 'dev' && inputs.npm-registry-url != 'https://npm.pkg.github.com/' }}"
env:
GITHUB_TOKEN: '${{ inputs.github-release-token || inputs.github-token }}'
INPUTS_RELEASE_TAG: '${{ inputs.release-tag }}'
STEPS_RELEASE_BRANCH_OUTPUTS_BRANCH_NAME: '${{ steps.release_branch.outputs.BRANCH_NAME }}'
INPUTS_PREVIOUS_TAG: '${{ inputs.previous-tag }}'
GITHUB_TOKEN: '${{ inputs.github-token }}'
shell: 'bash'
run: |
gh release create "${INPUTS_RELEASE_TAG}" \
gh release create "${{ inputs.release-tag }}" \
bundle/gemini.js \
--target "${STEPS_RELEASE_BRANCH_OUTPUTS_BRANCH_NAME}" \
--title "Release ${INPUTS_RELEASE_TAG}" \
--notes-start-tag "${INPUTS_PREVIOUS_TAG}" \
--target "${{ steps.release_branch.outputs.BRANCH_NAME }}" \
--title "Release ${{ inputs.release-tag }}" \
--notes-start-tag "${{ inputs.previous-tag }}" \
--generate-notes \
${{ inputs.npm-tag != 'latest' && '--prerelease' || '' }}
@@ -292,8 +271,5 @@ runs:
continue-on-error: true
shell: 'bash'
run: |
echo "Cleaning up release branch ${STEPS_RELEASE_BRANCH_OUTPUTS_BRANCH_NAME}..."
git push origin --delete "${STEPS_RELEASE_BRANCH_OUTPUTS_BRANCH_NAME}"
env:
STEPS_RELEASE_BRANCH_OUTPUTS_BRANCH_NAME: '${{ steps.release_branch.outputs.BRANCH_NAME }}'
echo "Cleaning up release branch ${{ steps.release_branch.outputs.BRANCH_NAME }}..."
git push origin --delete "${{ steps.release_branch.outputs.BRANCH_NAME }}"
+1 -3
View File
@@ -52,10 +52,8 @@ runs:
id: 'branch_name'
shell: 'bash'
run: |
REF_NAME="${INPUTS_REF_NAME}"
REF_NAME="${{ inputs.ref-name }}"
echo "name=${REF_NAME%/merge}" >> $GITHUB_OUTPUT
env:
INPUTS_REF_NAME: '${{ inputs.ref-name }}'
- name: 'Build and Push the Docker Image'
uses: 'docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83' # ratchet:docker/build-push-action@v6
with:
+4 -18
View File
@@ -56,8 +56,8 @@ runs:
id: 'image_tag'
shell: 'bash'
run: |-
SHELL_TAG_NAME="${INPUTS_GITHUB_REF_NAME}"
FINAL_TAG="${INPUTS_GITHUB_SHA}"
SHELL_TAG_NAME="${{ inputs.github-ref-name }}"
FINAL_TAG="${{ inputs.github-sha }}"
if [[ "$SHELL_TAG_NAME" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.-]+)?$ ]]; then
echo "Release detected."
FINAL_TAG="${SHELL_TAG_NAME#v}"
@@ -66,36 +66,22 @@ runs:
fi
echo "Determined image tag: $FINAL_TAG"
echo "FINAL_TAG=$FINAL_TAG" >> $GITHUB_OUTPUT
env:
INPUTS_GITHUB_REF_NAME: '${{ inputs.github-ref-name }}'
INPUTS_GITHUB_SHA: '${{ inputs.github-sha }}'
- name: 'build'
id: 'docker_build'
shell: 'bash'
env:
GEMINI_SANDBOX_IMAGE_TAG: '${{ steps.image_tag.outputs.FINAL_TAG }}'
GEMINI_SANDBOX: 'docker'
STEPS_IMAGE_TAG_OUTPUTS_FINAL_TAG: '${{ steps.image_tag.outputs.FINAL_TAG }}'
run: |-
npm run build:sandbox -- \
--image google/gemini-cli-sandbox:${STEPS_IMAGE_TAG_OUTPUTS_FINAL_TAG} \
--image google/gemini-cli-sandbox:${{ steps.image_tag.outputs.FINAL_TAG }} \
--output-file final_image_uri.txt
echo "uri=$(cat final_image_uri.txt)" >> $GITHUB_OUTPUT
- name: 'verify'
shell: 'bash'
run: |-
docker run --rm --entrypoint sh "${{ steps.docker_build.outputs.uri }}" -lc '
set -e
node -e "const fs=require(\"node:fs\"); JSON.parse(fs.readFileSync(\"/usr/local/share/npm-global/lib/node_modules/@google/gemini-cli/package.json\",\"utf8\")); JSON.parse(fs.readFileSync(\"/usr/local/share/npm-global/lib/node_modules/@google/gemini-cli-core/package.json\",\"utf8\"));"
/usr/local/share/npm-global/bin/gemini --version >/dev/null
'
- name: 'publish'
shell: 'bash'
if: "${{ inputs.dry-run != 'true' }}"
run: |-
docker push "${STEPS_DOCKER_BUILD_OUTPUTS_URI}"
env:
STEPS_DOCKER_BUILD_OUTPUTS_URI: '${{ steps.docker_build.outputs.uri }}'
docker push "${{ steps.docker_build.outputs.uri }}"
- name: 'Create issue on failure'
if: |-
${{ failure() }}
+1 -3
View File
@@ -18,7 +18,5 @@ runs:
shell: 'bash'
run: |-
echo ""@google-gemini:registry=https://npm.pkg.github.com"" > ~/.npmrc
echo ""//npm.pkg.github.com/:_authToken=${INPUTS_GITHUB_TOKEN}"" >> ~/.npmrc
echo ""//npm.pkg.github.com/:_authToken=${{ inputs.github-token }}"" >> ~/.npmrc
echo ""@google:registry=https://wombat-dressing-room.appspot.com"" >> ~/.npmrc
env:
INPUTS_GITHUB_TOKEN: '${{ inputs.github-token }}'
+4 -24
View File
@@ -71,13 +71,10 @@ runs:
${{ inputs.dry-run != 'true' }}
env:
NODE_AUTH_TOKEN: '${{ steps.core-token.outputs.auth-token }}'
INPUTS_CORE_PACKAGE_NAME: '${{ inputs.core-package-name }}'
INPUTS_VERSION: '${{ inputs.version }}'
INPUTS_CHANNEL: '${{ inputs.channel }}'
shell: 'bash'
working-directory: '${{ inputs.working-directory }}'
run: |
npm dist-tag add ${INPUTS_CORE_PACKAGE_NAME}@${INPUTS_VERSION} ${INPUTS_CHANNEL}
npm dist-tag add ${{ inputs.core-package-name }}@${{ inputs.version }} ${{ inputs.channel }}
- name: 'Get cli Token'
uses: './.github/actions/npm-auth-token'
@@ -94,13 +91,10 @@ runs:
${{ inputs.dry-run != 'true' }}
env:
NODE_AUTH_TOKEN: '${{ steps.cli-token.outputs.auth-token }}'
INPUTS_CLI_PACKAGE_NAME: '${{ inputs.cli-package-name }}'
INPUTS_VERSION: '${{ inputs.version }}'
INPUTS_CHANNEL: '${{ inputs.channel }}'
shell: 'bash'
working-directory: '${{ inputs.working-directory }}'
run: |
npm dist-tag add ${INPUTS_CLI_PACKAGE_NAME}@${INPUTS_VERSION} ${INPUTS_CHANNEL}
npm dist-tag add ${{ inputs.cli-package-name }}@${{ inputs.version }} ${{ inputs.channel }}
- name: 'Get a2a Token'
uses: './.github/actions/npm-auth-token'
@@ -117,13 +111,10 @@ runs:
${{ inputs.dry-run == 'false' }}
env:
NODE_AUTH_TOKEN: '${{ steps.a2a-token.outputs.auth-token }}'
INPUTS_A2A_PACKAGE_NAME: '${{ inputs.a2a-package-name }}'
INPUTS_VERSION: '${{ inputs.version }}'
INPUTS_CHANNEL: '${{ inputs.channel }}'
shell: 'bash'
working-directory: '${{ inputs.working-directory }}'
run: |
npm dist-tag add ${INPUTS_A2A_PACKAGE_NAME}@${INPUTS_VERSION} ${INPUTS_CHANNEL}
npm dist-tag add ${{ inputs.a2a-package-name }}@${{ inputs.version }} ${{ inputs.channel }}
- name: 'Log dry run'
if: |-
@@ -131,15 +122,4 @@ runs:
shell: 'bash'
working-directory: '${{ inputs.working-directory }}'
run: |
echo "Dry run: Would have added tag '${INPUTS_CHANNEL}' to version '${INPUTS_VERSION}' for ${INPUTS_CLI_PACKAGE_NAME}, ${INPUTS_CORE_PACKAGE_NAME}, and ${INPUTS_A2A_PACKAGE_NAME}."
env:
INPUTS_CHANNEL: '${{ inputs.channel }}'
INPUTS_VERSION: '${{ inputs.version }}'
INPUTS_CLI_PACKAGE_NAME: '${{ inputs.cli-package-name }}'
INPUTS_CORE_PACKAGE_NAME: '${{ inputs.core-package-name }}'
INPUTS_A2A_PACKAGE_NAME: '${{ inputs.a2a-package-name }}'
echo "Dry run: Would have added tag '${{ inputs.channel }}' to version '${{ inputs.version }}' for ${{ inputs.cli-package-name }}, ${{ inputs.core-package-name }}, and ${{ inputs.a2a-package-name }}."
+5 -11
View File
@@ -64,13 +64,10 @@ runs:
working-directory: '${{ inputs.working-directory }}'
run: |-
gemini_version=$(gemini --version)
if [ "$gemini_version" != "${INPUTS_EXPECTED_VERSION}" ]; then
echo "❌ NPM Version mismatch: Got $gemini_version from ${INPUTS_NPM_PACKAGE}, expected ${INPUTS_EXPECTED_VERSION}"
if [ "$gemini_version" != "${{ inputs.expected-version }}" ]; then
echo "❌ NPM Version mismatch: Got $gemini_version from ${{ inputs.npm-package }}, expected ${{ inputs.expected-version }}"
exit 1
fi
env:
INPUTS_EXPECTED_VERSION: '${{ inputs.expected-version }}'
INPUTS_NPM_PACKAGE: '${{ inputs.npm-package }}'
- name: 'Clear npm cache'
shell: 'bash'
@@ -80,14 +77,11 @@ runs:
shell: 'bash'
working-directory: '${{ inputs.working-directory }}'
run: |-
gemini_version=$(npx --prefer-online "${INPUTS_NPM_PACKAGE}" --version)
if [ "$gemini_version" != "${INPUTS_EXPECTED_VERSION}" ]; then
echo "❌ NPX Run Version mismatch: Got $gemini_version from ${INPUTS_NPM_PACKAGE}, expected ${INPUTS_EXPECTED_VERSION}"
gemini_version=$(npx --prefer-online "${{ inputs.npm-package}}" --version)
if [ "$gemini_version" != "${{ inputs.expected-version }}" ]; then
echo "❌ NPX Run Version mismatch: Got $gemini_version from ${{ inputs.npm-package }}, expected ${{ inputs.expected-version }}"
exit 1
fi
env:
INPUTS_NPM_PACKAGE: '${{ inputs.npm-package }}'
INPUTS_EXPECTED_VERSION: '${{ inputs.expected-version }}'
- name: 'Install dependencies for integration tests'
shell: 'bash'
+12 -12
View File
@@ -9,10 +9,10 @@ set -euo pipefail
PRS_NEEDING_COMMENT=""
# Global cache for issue labels (compatible with Bash 3.2)
# Stores "|ISSUE_NUM:LABELS|" segments
ISSUE_LABELS_CACHE_FLAT="|"
# Stores "ISSUE_NUM:LABELS" pairs separated by spaces
ISSUE_LABELS_CACHE_FLAT=""
# Function to get labels from an issue (with caching)
# Function to get area and priority labels from an issue (with caching)
get_issue_labels() {
local ISSUE_NUM="${1}"
if [[ -z "${ISSUE_NUM}" || "${ISSUE_NUM}" == "null" || "${ISSUE_NUM}" == "" ]]; then
@@ -20,10 +20,10 @@ get_issue_labels() {
fi
# Check cache
case "${ISSUE_LABELS_CACHE_FLAT}" in
*"|${ISSUE_NUM}:"*)
local suffix="${ISSUE_LABELS_CACHE_FLAT#*|"${ISSUE_NUM}":}"
echo "${suffix%%|*}"
case " ${ISSUE_LABELS_CACHE_FLAT} " in
*" ${ISSUE_NUM}:"*)
local suffix="${ISSUE_LABELS_CACHE_FLAT#* " ${ISSUE_NUM}:"}"
echo "${suffix%% *}"
return
;;
*)
@@ -31,19 +31,19 @@ get_issue_labels() {
;;
esac
echo " 📥 Fetching labels from issue #${ISSUE_NUM}" >&2
echo " 📥 Fetching area and priority labels from issue #${ISSUE_NUM}" >&2
local gh_output
if ! gh_output=$(gh issue view "${ISSUE_NUM}" --repo "${GITHUB_REPOSITORY}" --json labels -q '.labels[].name' 2>/dev/null); then
echo " ⚠️ Could not fetch issue #${ISSUE_NUM}" >&2
ISSUE_LABELS_CACHE_FLAT="${ISSUE_LABELS_CACHE_FLAT}${ISSUE_NUM}:|"
ISSUE_LABELS_CACHE_FLAT="${ISSUE_LABELS_CACHE_FLAT} ${ISSUE_NUM}:"
return
fi
local labels
labels=$(echo "${gh_output}" | grep -x -E '(area|priority)/.*|help wanted|🔒 maintainer only' | tr '\n' ',' | sed 's/,$//' || echo "")
labels=$(echo "${gh_output}" | grep -E '^(area|priority)/' | tr '\n' ',' | sed 's/,$//' || echo "")
# Save to flat cache
ISSUE_LABELS_CACHE_FLAT="${ISSUE_LABELS_CACHE_FLAT}${ISSUE_NUM}:${labels}|"
ISSUE_LABELS_CACHE_FLAT="${ISSUE_LABELS_CACHE_FLAT} ${ISSUE_NUM}:${labels}"
echo "${labels}"
}
@@ -121,7 +121,7 @@ done
EDIT_CMD+=("--remove-label" "${LABELS_TO_REMOVE}")
fi
("${EDIT_CMD[@]}" || true)
("${EDIT_CMD[@]}" 2>/dev/null || true)
fi
}
+2 -6
View File
@@ -1,9 +1,5 @@
/**
* @license
* Copyright 2026 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
/* eslint-disable @typescript-eslint/no-require-imports */
/* global process, console, require */
const { Octokit } = require('@octokit/rest');
/**
+17 -31
View File
@@ -31,7 +31,6 @@ jobs:
name: 'Merge Queue Skipper'
permissions: 'read-all'
runs-on: 'gemini-cli-ubuntu-16-core'
if: "github.repository == 'google-gemini/gemini-cli'"
outputs:
skip: '${{ steps.merge-queue-e2e-skipper.outputs.skip-check }}'
steps:
@@ -43,7 +42,7 @@ jobs:
download_repo_name:
runs-on: 'gemini-cli-ubuntu-16-core'
if: "github.repository == 'google-gemini/gemini-cli' && (github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_run')"
if: "${{github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_run'}}"
outputs:
repo_name: '${{ steps.output-repo-name.outputs.repo_name }}'
head_sha: '${{ steps.output-repo-name.outputs.head_sha }}'
@@ -54,7 +53,7 @@ jobs:
REPO_NAME: '${{ github.event.inputs.repo_name }}'
run: |
mkdir -p ./pr
echo "${REPO_NAME}" > ./pr/repo_name
echo '${{ env.REPO_NAME }}' > ./pr/repo_name
- uses: 'actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02' # ratchet:actions/upload-artifact@v4
with:
name: 'repo_name'
@@ -92,7 +91,7 @@ jobs:
name: 'Parse run context'
runs-on: 'gemini-cli-ubuntu-16-core'
needs: 'download_repo_name'
if: "github.repository == 'google-gemini/gemini-cli' && always()"
if: 'always()'
outputs:
repository: '${{ steps.set_context.outputs.REPO }}'
sha: '${{ steps.set_context.outputs.SHA }}'
@@ -112,11 +111,11 @@ jobs:
permissions: 'write-all'
needs:
- 'parse_run_context'
if: "github.repository == 'google-gemini/gemini-cli' && always()"
if: 'always()'
steps:
- name: 'Set pending status'
uses: 'myrotvorets/set-commit-status-action@16037e056d73b2d3c88e37e393ff369047f70886' # ratchet:myrotvorets/set-commit-status-action@master
if: "github.repository == 'google-gemini/gemini-cli' && always()"
if: 'always()'
with:
allowForks: 'true'
repo: '${{ github.repository }}'
@@ -132,7 +131,7 @@ jobs:
- 'parse_run_context'
runs-on: 'gemini-cli-ubuntu-16-core'
if: |
github.repository == 'google-gemini/gemini-cli' && always() && (needs.merge_queue_skipper.result !='success' || needs.merge_queue_skipper.outputs.skip != 'true')
always() && (needs.merge_queue_skipper.result !='success' || needs.merge_queue_skipper.outputs.skip != 'true')
strategy:
fail-fast: false
matrix:
@@ -185,7 +184,7 @@ jobs:
- 'parse_run_context'
runs-on: 'macos-latest'
if: |
github.repository == 'google-gemini/gemini-cli' && always() && (needs.merge_queue_skipper.result !='success' || needs.merge_queue_skipper.outputs.skip != 'true')
always() && (needs.merge_queue_skipper.result !='success' || needs.merge_queue_skipper.outputs.skip != 'true')
steps:
- name: 'Checkout'
uses: 'actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955' # ratchet:actions/checkout@v5
@@ -223,8 +222,10 @@ jobs:
- 'merge_queue_skipper'
- 'parse_run_context'
if: |
github.repository == 'google-gemini/gemini-cli' && always() && (needs.merge_queue_skipper.result !='success' || needs.merge_queue_skipper.outputs.skip != 'true')
always() && (needs.merge_queue_skipper.result !='success' || needs.merge_queue_skipper.outputs.skip != 'true')
runs-on: 'gemini-cli-windows-16-core'
continue-on-error: true
steps:
- name: 'Checkout'
uses: 'actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955' # ratchet:actions/checkout@v5
@@ -283,14 +284,13 @@ jobs:
- 'parse_run_context'
runs-on: 'gemini-cli-ubuntu-16-core'
if: |
github.repository == 'google-gemini/gemini-cli' && always() && (needs.merge_queue_skipper.result !='success' || needs.merge_queue_skipper.outputs.skip != 'true')
always() && (needs.merge_queue_skipper.result !='success' || needs.merge_queue_skipper.outputs.skip != 'true')
steps:
- name: 'Checkout'
uses: 'actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955' # ratchet:actions/checkout@v5
with:
ref: '${{ needs.parse_run_context.outputs.sha }}'
repository: '${{ needs.parse_run_context.outputs.repository }}'
fetch-depth: 0
- name: 'Set up Node.js 20.x'
uses: 'actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020' # ratchet:actions-node@v4
@@ -303,14 +303,7 @@ jobs:
- name: 'Build project'
run: 'npm run build'
- name: 'Check if evals should run'
id: 'check_evals'
run: |
SHOULD_RUN=$(node scripts/changed_prompt.js)
echo "should_run=$SHOULD_RUN" >> "$GITHUB_OUTPUT"
- name: 'Run Evals (Required to pass)'
if: "${{ steps.check_evals.outputs.should_run == 'true' }}"
env:
GEMINI_API_KEY: '${{ secrets.GEMINI_API_KEY }}'
run: 'npm run test:always_passing_evals'
@@ -318,42 +311,35 @@ jobs:
e2e:
name: 'E2E'
if: |
github.repository == 'google-gemini/gemini-cli' && always() && (needs.merge_queue_skipper.result !='success' || needs.merge_queue_skipper.outputs.skip != 'true')
always() && (needs.merge_queue_skipper.result !='success' || needs.merge_queue_skipper.outputs.skip != 'true')
needs:
- 'e2e_linux'
- 'e2e_mac'
- 'e2e_windows'
- 'evals'
- 'merge_queue_skipper'
runs-on: 'gemini-cli-ubuntu-16-core'
steps:
- name: 'Check E2E test results'
run: |
if [[ ${NEEDS_E2E_LINUX_RESULT} != 'success' || \
${NEEDS_E2E_MAC_RESULT} != 'success' || \
${NEEDS_E2E_WINDOWS_RESULT} != 'success' || \
${NEEDS_EVALS_RESULT} != 'success' ]]; then
if [[ ${{ needs.e2e_linux.result }} != 'success' || \
${{ needs.e2e_mac.result }} != 'success' || \
${{ needs.evals.result }} != 'success' ]]; then
echo "One or more E2E jobs failed."
exit 1
fi
echo "All required E2E jobs passed!"
env:
NEEDS_E2E_LINUX_RESULT: '${{ needs.e2e_linux.result }}'
NEEDS_E2E_MAC_RESULT: '${{ needs.e2e_mac.result }}'
NEEDS_E2E_WINDOWS_RESULT: '${{ needs.e2e_windows.result }}'
NEEDS_EVALS_RESULT: '${{ needs.evals.result }}'
set_workflow_status:
runs-on: 'gemini-cli-ubuntu-16-core'
permissions: 'write-all'
if: "github.repository == 'google-gemini/gemini-cli' && always()"
if: 'always()'
needs:
- 'parse_run_context'
- 'e2e'
steps:
- name: 'Set workflow status'
uses: 'myrotvorets/set-commit-status-action@16037e056d73b2d3c88e37e393ff369047f70886' # ratchet:myrotvorets/set-commit-status-action@master
if: "github.repository == 'google-gemini/gemini-cli' && always()"
if: 'always()'
with:
allowForks: 'true'
repo: '${{ github.repository }}'
+16 -81
View File
@@ -37,7 +37,6 @@ jobs:
permissions: 'read-all'
name: 'Merge Queue Skipper'
runs-on: 'gemini-cli-ubuntu-16-core'
if: "github.repository == 'google-gemini/gemini-cli'"
outputs:
skip: '${{ steps.merge-queue-ci-skipper.outputs.skip-check }}'
steps:
@@ -50,7 +49,7 @@ jobs:
name: 'Lint'
runs-on: 'gemini-cli-ubuntu-16-core'
needs: 'merge_queue_skipper'
if: "github.repository == 'google-gemini/gemini-cli' && needs.merge_queue_skipper.outputs.skip == 'false'"
if: "${{needs.merge_queue_skipper.outputs.skip == 'false'}}"
env:
GEMINI_LINT_TEMP_DIR: '${{ github.workspace }}/.gemini-linters'
steps:
@@ -117,7 +116,6 @@ jobs:
link_checker:
name: 'Link Checker'
runs-on: 'ubuntu-latest'
if: "github.repository == 'google-gemini/gemini-cli'"
steps:
- name: 'Checkout'
uses: 'actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8' # ratchet:actions/checkout@v5
@@ -131,7 +129,7 @@ jobs:
runs-on: 'gemini-cli-ubuntu-16-core'
needs:
- 'merge_queue_skipper'
if: "github.repository == 'google-gemini/gemini-cli' && needs.merge_queue_skipper.outputs.skip == 'false'"
if: "${{needs.merge_queue_skipper.outputs.skip == 'false'}}"
permissions:
contents: 'read'
checks: 'write'
@@ -179,19 +177,6 @@ jobs:
- name: 'Smoke test bundle'
run: 'node ./bundle/gemini.js --version'
- name: 'Smoke test npx installation'
run: |
# 1. Package the project into a tarball
TARBALL=$(npm pack | tail -n 1)
# 2. Move to a fresh directory for isolation
mkdir -p ../smoke-test-dir
mv "$TARBALL" ../smoke-test-dir/
cd ../smoke-test-dir
# 3. Run npx from the tarball
npx "./$TARBALL" --version
- name: 'Wait for file system sync'
run: 'sleep 2'
@@ -218,7 +203,7 @@ jobs:
runs-on: 'macos-latest'
needs:
- 'merge_queue_skipper'
if: "github.repository == 'google-gemini/gemini-cli' && needs.merge_queue_skipper.outputs.skip == 'false'"
if: "${{needs.merge_queue_skipper.outputs.skip == 'false'}}"
permissions:
contents: 'read'
checks: 'write'
@@ -267,19 +252,6 @@ jobs:
- name: 'Smoke test bundle'
run: 'node ./bundle/gemini.js --version'
- name: 'Smoke test npx installation'
run: |
# 1. Package the project into a tarball
TARBALL=$(npm pack | tail -n 1)
# 2. Move to a fresh directory for isolation
mkdir -p ../smoke-test-dir
mv "$TARBALL" ../smoke-test-dir/
cd ../smoke-test-dir
# 3. Run npx from the tarball
npx "./$TARBALL" --version
- name: 'Wait for file system sync'
run: 'sleep 2'
@@ -313,7 +285,7 @@ jobs:
name: 'CodeQL'
runs-on: 'gemini-cli-ubuntu-16-core'
needs: 'merge_queue_skipper'
if: "github.repository == 'google-gemini/gemini-cli' && needs.merge_queue_skipper.outputs.skip == 'false'"
if: "${{needs.merge_queue_skipper.outputs.skip == 'false'}}"
permissions:
actions: 'read'
contents: 'read'
@@ -336,7 +308,7 @@ jobs:
bundle_size:
name: 'Check Bundle Size'
needs: 'merge_queue_skipper'
if: "github.repository == 'google-gemini/gemini-cli' && github.event_name == 'pull_request' && needs.merge_queue_skipper.outputs.skip == 'false'"
if: "${{github.event_name == 'pull_request' && needs.merge_queue_skipper.outputs.skip == 'false'}}"
runs-on: 'gemini-cli-ubuntu-16-core'
permissions:
contents: 'read' # For checkout
@@ -358,16 +330,11 @@ jobs:
clean-script: 'clean'
test_windows:
name: 'Slow Test - Win - ${{ matrix.shard }}'
name: 'Slow Test - Win'
runs-on: 'gemini-cli-windows-16-core'
needs: 'merge_queue_skipper'
if: "github.repository == 'google-gemini/gemini-cli' && needs.merge_queue_skipper.outputs.skip == 'false'"
timeout-minutes: 60
strategy:
matrix:
shard:
- 'cli'
- 'others'
if: "${{needs.merge_queue_skipper.outputs.skip == 'false'}}"
continue-on-error: true
steps:
- name: 'Checkout'
@@ -418,14 +385,7 @@ jobs:
NODE_OPTIONS: '--max-old-space-size=32768 --max-semi-space-size=256'
UV_THREADPOOL_SIZE: '32'
NODE_ENV: 'test'
run: |
if ("${{ matrix.shard }}" -eq "cli") {
npm run test:ci --workspace @google/gemini-cli -- --coverage.enabled=false
} else {
# Explicitly list non-cli packages to ensure they are sharded correctly
npm run test:ci --workspace @google/gemini-cli-core --workspace @google/gemini-cli-a2a-server --workspace gemini-cli-vscode-ide-companion --workspace @google/gemini-cli-test-utils --if-present -- --coverage.enabled=false
npm run test:scripts
}
run: 'npm run test:ci -- --coverage.enabled=false'
shell: 'pwsh'
- name: 'Bundle'
@@ -436,52 +396,27 @@ jobs:
run: 'node ./bundle/gemini.js --version'
shell: 'pwsh'
- name: 'Smoke test npx installation'
run: |
# 1. Package the project into a tarball
$PACK_OUTPUT = npm pack
$TARBALL = $PACK_OUTPUT[-1]
# 2. Move to a fresh directory for isolation
New-Item -ItemType Directory -Force -Path ../smoke-test-dir
Move-Item $TARBALL ../smoke-test-dir/
Set-Location ../smoke-test-dir
# 3. Run npx from the tarball
npx "./$TARBALL" --version
shell: 'pwsh'
ci:
name: 'CI'
if: "github.repository == 'google-gemini/gemini-cli' && always()"
if: 'always()'
needs:
- 'lint'
- 'link_checker'
- 'test_linux'
- 'test_mac'
- 'test_windows'
- 'codeql'
- 'bundle_size'
runs-on: 'gemini-cli-ubuntu-16-core'
steps:
- name: 'Check all job results'
run: |
if [[ (${NEEDS_LINT_RESULT} != 'success' && ${NEEDS_LINT_RESULT} != 'skipped') || \
(${NEEDS_LINK_CHECKER_RESULT} != 'success' && ${NEEDS_LINK_CHECKER_RESULT} != 'skipped') || \
(${NEEDS_TEST_LINUX_RESULT} != 'success' && ${NEEDS_TEST_LINUX_RESULT} != 'skipped') || \
(${NEEDS_TEST_MAC_RESULT} != 'success' && ${NEEDS_TEST_MAC_RESULT} != 'skipped') || \
(${NEEDS_TEST_WINDOWS_RESULT} != 'success' && ${NEEDS_TEST_WINDOWS_RESULT} != 'skipped') || \
(${NEEDS_CODEQL_RESULT} != 'success' && ${NEEDS_CODEQL_RESULT} != 'skipped') || \
(${NEEDS_BUNDLE_SIZE_RESULT} != 'success' && ${NEEDS_BUNDLE_SIZE_RESULT} != 'skipped') ]]; then
if [[ (${{ needs.lint.result }} != 'success' && ${{ needs.lint.result }} != 'skipped') || \
(${{ needs.link_checker.result }} != 'success' && ${{ needs.link_checker.result }} != 'skipped') || \
(${{ needs.test_linux.result }} != 'success' && ${{ needs.test_linux.result }} != 'skipped') || \
(${{ needs.test_mac.result }} != 'success' && ${{ needs.test_mac.result }} != 'skipped') || \
(${{ needs.codeql.result }} != 'success' && ${{ needs.codeql.result }} != 'skipped') || \
(${{ needs.bundle_size.result }} != 'success' && ${{ needs.bundle_size.result }} != 'skipped') ]]; then
echo "One or more CI jobs failed."
exit 1
fi
echo "All CI jobs passed!"
env:
NEEDS_LINT_RESULT: '${{ needs.lint.result }}'
NEEDS_LINK_CHECKER_RESULT: '${{ needs.link_checker.result }}'
NEEDS_TEST_LINUX_RESULT: '${{ needs.test_linux.result }}'
NEEDS_TEST_MAC_RESULT: '${{ needs.test_mac.result }}'
NEEDS_TEST_WINDOWS_RESULT: '${{ needs.test_windows.result }}'
NEEDS_CODEQL_RESULT: '${{ needs.codeql.result }}'
NEEDS_BUNDLE_SIZE_RESULT: '${{ needs.bundle_size.result }}'
+6 -8
View File
@@ -27,7 +27,6 @@ jobs:
deflake_e2e_linux:
name: 'E2E Test (Linux) - ${{ matrix.sandbox }}'
runs-on: 'gemini-cli-ubuntu-16-core'
if: "github.repository == 'google-gemini/gemini-cli'"
strategy:
fail-fast: false
matrix:
@@ -69,16 +68,15 @@ jobs:
VERBOSE: 'true'
shell: 'bash'
run: |
if [[ "${IS_DOCKER}" == "true" ]]; then
npm run deflake:test:integration:sandbox:docker -- --runs="${RUNS}" -- --testNamePattern "'${TEST_NAME_PATTERN}'"
if [[ "${{ env.IS_DOCKER }}" == "true" ]]; then
npm run deflake:test:integration:sandbox:docker -- --runs="${{ env.RUNS }}" -- --testNamePattern "'${{ env.TEST_NAME_PATTERN }}'"
else
npm run deflake:test:integration:sandbox:none -- --runs="${RUNS}" -- --testNamePattern "'${TEST_NAME_PATTERN}'"
npm run deflake:test:integration:sandbox:none -- --runs="${{ env.RUNS }}" -- --testNamePattern "'${{ env.TEST_NAME_PATTERN }}'"
fi
deflake_e2e_mac:
name: 'E2E Test (macOS)'
runs-on: 'macos-latest'
if: "github.repository == 'google-gemini/gemini-cli'"
steps:
- name: 'Checkout'
uses: 'actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955' # ratchet:actions/checkout@v5
@@ -111,12 +109,12 @@ jobs:
TEST_NAME_PATTERN: '${{ github.event.inputs.test_name_pattern }}'
VERBOSE: 'true'
run: |
npm run deflake:test:integration:sandbox:none -- --runs="${RUNS}" -- --testNamePattern "'${TEST_NAME_PATTERN}'"
npm run deflake:test:integration:sandbox:none -- --runs="${{ env.RUNS }}" -- --testNamePattern "'${{ env.TEST_NAME_PATTERN }}'"
deflake_e2e_windows:
name: 'Slow E2E - Win'
runs-on: 'gemini-cli-windows-16-core'
if: "github.repository == 'google-gemini/gemini-cli'"
steps:
- name: 'Checkout'
uses: 'actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955' # ratchet:actions/checkout@v5
@@ -169,4 +167,4 @@ jobs:
TEST_NAME_PATTERN: '${{ github.event.inputs.test_name_pattern }}'
shell: 'pwsh'
run: |
npm run deflake:test:integration:sandbox:none -- --runs="$env:RUNS" -- --testNamePattern "'$env:TEST_NAME_PATTERN'"
npm run deflake:test:integration:sandbox:none -- --runs="${{ env.RUNS }}" -- --testNamePattern "'${{ env.TEST_NAME_PATTERN }}'"
+2 -2
View File
@@ -19,7 +19,8 @@ concurrency:
jobs:
build:
if: "github.repository == 'google-gemini/gemini-cli' && !contains(github.ref_name, 'nightly')"
if: |-
${{ !contains(github.ref_name, 'nightly') }}
runs-on: 'ubuntu-latest'
steps:
- name: 'Checkout'
@@ -38,7 +39,6 @@ jobs:
uses: 'actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa' # ratchet:actions/upload-pages-artifact@v3
deploy:
if: "github.repository == 'google-gemini/gemini-cli'"
environment:
name: 'github-pages'
url: '${{ steps.deployment.outputs.page_url }}'
-1
View File
@@ -7,7 +7,6 @@ on:
- 'docs/**'
jobs:
trigger-rebuild:
if: "github.repository == 'google-gemini/gemini-cli'"
runs-on: 'ubuntu-latest'
steps:
- name: 'Trigger rebuild'
+1 -1
View File
@@ -44,5 +44,5 @@ jobs:
- name: 'Run evaluation'
working-directory: '/app'
run: |
poetry run exp_run --experiment-mode=on-demand --branch-or-commit="${GITHUB_REF_NAME}" --model-name=gemini-2.5-pro --dataset=swebench_verified --concurrency=15
poetry run exp_run --experiment-mode=on-demand --branch-or-commit=${{ github.ref_name }} --model-name=gemini-2.5-pro --dataset=swebench_verified --concurrency=15
poetry run python agent_prototypes/scripts/parse_gcli_logs_experiment.py --experiment_dir=experiments/adhoc/gcli_temp_exp --gcs-bucket="${EVAL_GCS_BUCKET}" --gcs-path=gh_action_artifacts
+3 -30
View File
@@ -9,10 +9,6 @@ on:
description: 'Run all evaluations (including usually passing)'
type: 'boolean'
default: true
test_name_pattern:
description: 'Test name pattern or file name'
required: false
type: 'string'
permissions:
contents: 'read'
@@ -23,17 +19,9 @@ jobs:
evals:
name: 'Evals (USUALLY_PASSING) nightly run'
runs-on: 'gemini-cli-ubuntu-16-core'
if: "github.repository == 'google-gemini/gemini-cli'"
strategy:
fail-fast: false
matrix:
model:
- 'gemini-3.1-pro-preview-customtools'
- 'gemini-3-pro-preview'
- 'gemini-3-flash-preview'
- 'gemini-2.5-pro'
- 'gemini-2.5-flash'
- 'gemini-2.5-flash-lite'
run_attempt: [1, 2, 3]
steps:
- name: 'Checkout'
@@ -55,38 +43,23 @@ jobs:
run: 'mkdir -p evals/logs'
- name: 'Run Evals'
continue-on-error: true
env:
GEMINI_API_KEY: '${{ secrets.GEMINI_API_KEY }}'
GEMINI_MODEL: '${{ matrix.model }}'
RUN_EVALS: "${{ github.event.inputs.run_all != 'false' }}"
TEST_NAME_PATTERN: '${{ github.event.inputs.test_name_pattern }}'
run: |
CMD="npm run test:all_evals"
PATTERN="${TEST_NAME_PATTERN}"
if [[ -n "$PATTERN" ]]; then
if [[ "$PATTERN" == *.ts || "$PATTERN" == *.js || "$PATTERN" == */* ]]; then
$CMD -- "$PATTERN"
else
$CMD -- -t "$PATTERN"
fi
else
$CMD
fi
run: 'npm run test:all_evals'
- name: 'Upload Logs'
if: 'always()'
uses: 'actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02' # ratchet:actions/upload-artifact@v4
with:
name: 'eval-logs-${{ matrix.model }}-${{ matrix.run_attempt }}'
name: 'eval-logs-${{ matrix.run_attempt }}'
path: 'evals/logs'
retention-days: 7
aggregate-results:
name: 'Aggregate Results'
needs: ['evals']
if: "github.repository == 'google-gemini/gemini-cli' && always()"
if: 'always()'
runs-on: 'gemini-cli-ubuntu-16-core'
steps:
- name: 'Checkout'
@@ -155,10 +155,7 @@ jobs:
"telemetry": {
"enabled": true,
"target": "gcp"
},
"coreTools": [
"run_shell_command(echo)"
]
}
}
prompt: |-
## Role
@@ -287,21 +284,8 @@ jobs:
return;
}
} else {
// 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;
}
core.setFailed(`Output is not valid JSON and does not contain a JSON markdown block.\nRaw output: ${rawOutput}`);
return;
}
}
@@ -21,14 +21,13 @@ defaults:
jobs:
close-stale-issues:
if: "github.repository == 'google-gemini/gemini-cli'"
runs-on: 'ubuntu-latest'
permissions:
issues: 'write'
steps:
- name: 'Generate GitHub App Token'
id: 'generate_token'
uses: 'actions/create-github-app-token@v2'
uses: 'actions/create-github-app-token@v1'
with:
app-id: '${{ secrets.APP_ID }}'
private-key: '${{ secrets.PRIVATE_KEY }}'
@@ -80,14 +79,8 @@ jobs:
continue;
}
// Skip if it has a maintainer, help wanted, or Public Roadmap label
const rawLabels = issue.labels.map((l) => l.name);
const lowercaseLabels = rawLabels.map((l) => l.toLowerCase());
if (
lowercaseLabels.some((l) => l.includes('maintainer')) ||
lowercaseLabels.includes('help wanted') ||
rawLabels.includes('🗓️ Public Roadmap')
) {
// Skip if it has a maintainer label
if (issue.labels.some(label => label.name.toLowerCase().includes('maintainer'))) {
continue;
}
@@ -1,254 +0,0 @@
name: 'Gemini Scheduled Stale PR Closer'
on:
schedule:
- cron: '0 2 * * *' # Every day at 2 AM UTC
pull_request:
types: ['opened', 'edited']
workflow_dispatch:
inputs:
dry_run:
description: 'Run in dry-run mode'
required: false
default: false
type: 'boolean'
jobs:
close-stale-prs:
if: "github.repository == 'google-gemini/gemini-cli'"
runs-on: 'ubuntu-latest'
permissions:
pull-requests: 'write'
issues: 'write'
steps:
- name: 'Generate GitHub App Token'
id: 'generate_token'
uses: 'actions/create-github-app-token@v2'
with:
app-id: '${{ secrets.APP_ID }}'
private-key: '${{ secrets.PRIVATE_KEY }}'
- name: 'Process Stale PRs'
uses: 'actions/github-script@v7'
env:
DRY_RUN: '${{ inputs.dry_run }}'
with:
github-token: '${{ steps.generate_token.outputs.token }}'
script: |
const dryRun = process.env.DRY_RUN === 'true';
const thirtyDaysAgo = new Date();
thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);
// 1. Fetch maintainers for verification
let maintainerLogins = new Set();
const teams = ['gemini-cli-maintainers', 'gemini-cli-askmode-approvers', 'gemini-cli-docs'];
for (const team_slug of teams) {
try {
const members = await github.paginate(github.rest.teams.listMembersInOrg, {
org: context.repo.owner,
team_slug: team_slug
});
for (const m of members) maintainerLogins.add(m.login.toLowerCase());
core.info(`Successfully fetched ${members.length} team members from ${team_slug}`);
} catch (e) {
core.warning(`Failed to fetch team members from ${team_slug}: ${e.message}`);
}
}
const isGooglerCache = new Map();
const isGoogler = async (login) => {
if (isGooglerCache.has(login)) return isGooglerCache.get(login);
try {
// Check membership in 'googlers' or 'google' orgs
const orgs = ['googlers', 'google'];
for (const org of orgs) {
try {
await github.rest.orgs.checkMembershipForUser({
org: org,
username: login
});
core.info(`User ${login} is a member of ${org} organization.`);
isGooglerCache.set(login, true);
return true;
} catch (e) {
// 404 just means they aren't a member, which is fine
if (e.status !== 404) throw e;
}
}
} catch (e) {
core.warning(`Failed to check org membership for ${login}: ${e.message}`);
}
isGooglerCache.set(login, false);
return false;
};
const isMaintainer = async (login, assoc) => {
const isTeamMember = maintainerLogins.has(login.toLowerCase());
const isRepoMaintainer = ['OWNER', 'MEMBER', 'COLLABORATOR'].includes(assoc);
if (isTeamMember || isRepoMaintainer) return true;
return await isGoogler(login);
};
// 2. Determine which PRs to check
let prs = [];
if (context.eventName === 'pull_request') {
const { data: pr } = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.payload.pull_request.number
});
prs = [pr];
} else {
prs = await github.paginate(github.rest.pulls.list, {
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open',
per_page: 100
});
}
for (const pr of prs) {
const maintainerPr = await isMaintainer(pr.user.login, pr.author_association);
const isBot = pr.user.type === 'Bot' || pr.user.login.endsWith('[bot]');
// Detection Logic for Linked Issues
// Check 1: Official GitHub "Closing Issue" link (GraphQL)
const linkedIssueQuery = `query($owner:String!, $repo:String!, $number:Int!) {
repository(owner:$owner, name:$repo) {
pullRequest(number:$number) {
closingIssuesReferences(first: 1) { totalCount }
}
}
}`;
let hasClosingLink = false;
try {
const res = await github.graphql(linkedIssueQuery, {
owner: context.repo.owner, repo: context.repo.repo, number: pr.number
});
hasClosingLink = res.repository.pullRequest.closingIssuesReferences.totalCount > 0;
} catch (e) {}
// Check 2: Regex for mentions (e.g., "Related to #123", "Part of #123", "#123")
// We check for # followed by numbers or direct URLs to issues.
const body = pr.body || '';
const mentionRegex = /(?:#|https:\/\/github\.com\/[^\/]+\/[^\/]+\/issues\/)(\d+)/i;
const hasMentionLink = mentionRegex.test(body);
const hasLinkedIssue = hasClosingLink || hasMentionLink;
// Logic for Closed PRs (Auto-Reopen)
if (pr.state === 'closed' && context.eventName === 'pull_request' && context.payload.action === 'edited') {
if (hasLinkedIssue) {
core.info(`PR #${pr.number} now has a linked issue. Reopening.`);
if (!dryRun) {
await github.rest.pulls.update({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: pr.number,
state: 'open'
});
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pr.number,
body: "Thank you for linking an issue! This pull request has been automatically reopened."
});
}
}
continue;
}
// Logic for Open PRs (Immediate Closure)
if (pr.state === 'open' && !maintainerPr && !hasLinkedIssue && !isBot) {
core.info(`PR #${pr.number} is missing a linked issue. Closing.`);
if (!dryRun) {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pr.number,
body: "Hi there! Thank you for your contribution to Gemini CLI. \n\nTo improve our contribution process and better track changes, we now require all pull requests to be associated with an existing issue, as announced in our [recent discussion](https://github.com/google-gemini/gemini-cli/discussions/16706) and as detailed in our [CONTRIBUTING.md](https://github.com/google-gemini/gemini-cli/blob/main/CONTRIBUTING.md#1-link-to-an-existing-issue).\n\nThis pull request is being closed because it is not currently linked to an issue. **Once you have updated the description of this PR to link an issue (e.g., by adding `Fixes #123` or `Related to #123`), it will be automatically reopened.**\n\n**How to link an issue:**\nAdd a keyword followed by the issue number (e.g., `Fixes #123`) in the description of your pull request. For more details on supported keywords and how linking works, please refer to the [GitHub Documentation on linking pull requests to issues](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue).\n\nThank you for your understanding and for being a part of our community!"
});
await github.rest.pulls.update({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: pr.number,
state: 'closed'
});
}
continue;
}
// Staleness check (Scheduled runs only)
if (pr.state === 'open' && context.eventName !== 'pull_request') {
const labels = pr.labels.map(l => l.name.toLowerCase());
if (labels.includes('help wanted') || labels.includes('🔒 maintainer only')) continue;
// Skip PRs that were created less than 30 days ago - they cannot be stale yet
const prCreatedAt = new Date(pr.created_at);
if (prCreatedAt > thirtyDaysAgo) {
const daysOld = Math.floor((Date.now() - prCreatedAt.getTime()) / (1000 * 60 * 60 * 24));
core.info(`PR #${pr.number} was created ${daysOld} days ago. Skipping staleness check.`);
continue;
}
// Initialize lastActivity to PR creation date (not epoch) as a safety baseline.
// This ensures we never incorrectly mark a PR as stale due to failed activity lookups.
let lastActivity = new Date(pr.created_at);
try {
const reviews = await github.paginate(github.rest.pulls.listReviews, {
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: pr.number
});
for (const r of reviews) {
if (await isMaintainer(r.user.login, r.author_association)) {
const d = new Date(r.submitted_at || r.updated_at);
if (d > lastActivity) lastActivity = d;
}
}
const comments = await github.paginate(github.rest.issues.listComments, {
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pr.number
});
for (const c of comments) {
if (await isMaintainer(c.user.login, c.author_association)) {
const d = new Date(c.updated_at);
if (d > lastActivity) lastActivity = d;
}
}
} catch (e) {
core.warning(`Failed to fetch reviews/comments for PR #${pr.number}: ${e.message}`);
}
// For maintainer PRs, the PR creation itself counts as maintainer activity.
// (Now redundant since we initialize to pr.created_at, but kept for clarity)
if (maintainerPr) {
const d = new Date(pr.created_at);
if (d > lastActivity) lastActivity = d;
}
if (lastActivity < thirtyDaysAgo) {
core.info(`PR #${pr.number} is stale.`);
if (!dryRun) {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pr.number,
body: "Hi there! Thank you for your contribution to Gemini CLI. We really appreciate the time and effort you've put into this pull request.\n\nTo keep our backlog manageable and ensure we're focusing on current priorities, we are closing pull requests that haven't seen maintainer activity for 30 days. Currently, the team is prioritizing work associated with **🔒 maintainer only** or **help wanted** issues.\n\nIf you believe this change is still critical, please feel free to comment with updated details. Otherwise, we encourage contributors to focus on open issues labeled as **help wanted**. Thank you for your understanding!"
});
await github.rest.pulls.update({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: pr.number,
state: 'closed'
});
}
}
}
}
+8 -59
View File
@@ -25,7 +25,7 @@ jobs:
if: |-
github.repository == 'google-gemini/gemini-cli' &&
github.event_name == 'issue_comment' &&
(contains(github.event.comment.body, '/assign') || contains(github.event.comment.body, '/unassign'))
contains(github.event.comment.body, '/assign')
runs-on: 'ubuntu-latest'
steps:
- name: 'Generate GitHub App Token'
@@ -38,7 +38,6 @@ jobs:
permission-issues: 'write'
- name: 'Assign issue to user'
if: "contains(github.event.comment.body, '/assign')"
uses: 'actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea'
with:
github-token: '${{ steps.generate_token.outputs.token }}'
@@ -49,24 +48,6 @@ jobs:
const repo = context.repo.repo;
const MAX_ISSUES_ASSIGNED = 3;
const issue = await github.rest.issues.get({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issueNumber,
});
const hasHelpWantedLabel = issue.data.labels.some(label => label.name === 'help wanted');
if (!hasHelpWantedLabel) {
await github.rest.issues.createComment({
owner: owner,
repo: repo,
issue_number: issueNumber,
body: `👋 @${commenter}, thanks for your interest in this issue! We're reserving self-assignment for issues that have been marked with the \`help wanted\` label. Feel free to check out our list of [issues that need attention](https://github.com/google-gemini/gemini-cli/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22).`
});
return;
}
// Search for open issues already assigned to the commenter in this repo
const { data: assignedIssues } = await github.rest.search.issuesAndPullRequests({
q: `is:issue repo:${owner}/${repo} assignee:${commenter} is:open`,
@@ -83,6 +64,13 @@ jobs:
return; // exit
}
// Check if the issue is already assigned
const issue = await github.rest.issues.get({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issueNumber,
});
if (issue.data.assignees.length > 0) {
// Comment that it's already assigned
await github.rest.issues.createComment({
@@ -109,42 +97,3 @@ jobs:
issue_number: issueNumber,
body: `👋 @${commenter}, you've been assigned to this issue! Thank you for taking the time to contribute. Make sure to check out our [contributing guidelines](https://github.com/google-gemini/gemini-cli/blob/main/CONTRIBUTING.md).`
});
- name: 'Unassign issue from user'
if: "contains(github.event.comment.body, '/unassign')"
uses: 'actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea'
with:
github-token: '${{ steps.generate_token.outputs.token }}'
script: |
const issueNumber = context.issue.number;
const commenter = context.actor;
const owner = context.repo.owner;
const repo = context.repo.repo;
const commentBody = context.payload.comment.body.trim();
if (commentBody !== '/unassign') {
return;
}
const issue = await github.rest.issues.get({
owner: owner,
repo: repo,
issue_number: issueNumber,
});
const isAssigned = issue.data.assignees.some(assignee => assignee.login === commenter);
if (isAssigned) {
await github.rest.issues.removeAssignees({
owner: owner,
repo: repo,
issue_number: issueNumber,
assignees: [commenter]
});
await github.rest.issues.createComment({
owner: owner,
repo: repo,
issue_number: issueNumber,
body: `👋 @${commenter}, you have been unassigned from this issue.`
});
}
@@ -14,7 +14,7 @@ permissions:
jobs:
# Event-based: Quick reaction to new/edited issues in THIS repo
labeler:
if: "github.repository == 'google-gemini/gemini-cli' && github.event_name == 'issues'"
if: "github.event_name == 'issues'"
runs-on: 'ubuntu-latest'
steps:
- name: 'Checkout'
@@ -36,7 +36,7 @@ jobs:
# Scheduled/Manual: Recursive sync across multiple repos
sync-maintainer-labels:
if: "github.repository == 'google-gemini/gemini-cli' && (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch')"
if: "github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'"
runs-on: 'ubuntu-latest'
steps:
- name: 'Checkout'
+119
View File
@@ -0,0 +1,119 @@
name: '🏷️ Enforce Restricted Label Permissions'
on:
issues:
types:
- 'labeled'
- 'unlabeled'
jobs:
enforce-label:
# Run this job only when restricted labels are changed
if: |-
${{ (github.event.label.name == 'help wanted' || github.event.label.name == 'status/need-triage' || github.event.label.name == '🔒 maintainer only') &&
(github.repository == 'google-gemini/gemini-cli' || github.repository == 'google-gemini/maintainers-gemini-cli') }}
runs-on: 'ubuntu-latest'
permissions:
issues: 'write'
steps:
- name: 'Generate GitHub App Token'
id: 'generate_token'
env:
APP_ID: '${{ secrets.APP_ID }}'
if: |-
${{ env.APP_ID != '' }}
uses: 'actions/create-github-app-token@a8d616148505b5069dccd32f177bb87d7f39123b' # ratchet:actions/create-github-app-token@v2
with:
app-id: '${{ secrets.APP_ID }}'
private-key: '${{ secrets.PRIVATE_KEY }}'
- name: 'Check if user is in the maintainers team'
uses: 'actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea'
with:
github-token: '${{ steps.generate_token.outputs.token || secrets.GITHUB_TOKEN }}'
script: |-
const org = context.repo.owner;
const username = context.payload.sender.login;
const team_slug = 'gemini-cli-maintainers';
const action = context.payload.action; // 'labeled' or 'unlabeled'
const labelName = context.payload.label.name;
// Skip if the change was made by a bot to avoid infinite loops
if (username === 'github-actions[bot]' || username === 'gemini-cli[bot]' || username.endsWith('[bot]')) {
core.info('Change made by a bot. Skipping.');
return;
}
try {
// Check repository permission level directly.
// This is more robust than team membership as it doesn't require Org-level read permissions
// and correctly handles Repo Admins/Writers who might not be in the specific team.
const { data: { permission } } = await github.rest.repos.getCollaboratorPermissionLevel({
owner: org,
repo: context.repo.repo,
username,
});
if (permission === 'admin' || permission === 'write') {
core.info(`${username} has '${permission}' permission. Allowed.`);
return;
}
core.info(`${username} has '${permission}' permission (needs 'write' or 'admin'). Reverting '${action}' action for '${labelName}' label.`);
} catch (error) {
core.error(`Failed to check permissions for ${username}: ${error.message}`);
// Fall through to revert logic if we can't verify permissions (fail safe)
}
// If we are here, the user is NOT authorized.
if (true) { // wrapping block to preserve variable scope if needed
if (action === 'labeled') {
// 1. Remove the label if added by a non-maintainer
await github.rest.issues.removeLabel ({
owner: org,
repo: context.repo.repo,
issue_number: context.issue.number,
name: labelName
});
// 2. Post a polite comment
const comment = `
Hi @${username}, thank you for your interest in helping triage issues!
The \`${labelName}\` label is reserved for project maintainers to apply. This helps us ensure that an issue is ready and properly vetted for community contribution.
A maintainer will review this issue soon. Please see our [CONTRIBUTING.md](https://github.com/google-gemini/gemini-cli/blob/main/CONTRIBUTING.md) for more details on our labeling process.
`.trim().replace(/^[ ]+/gm, '');
await github.rest.issues.createComment ({
owner: org,
repo: context.repo.repo,
issue_number: context.issue.number,
body: comment
});
} else if (action === 'unlabeled') {
// 1. Add the label back if removed by a non-maintainer
await github.rest.issues.addLabels ({
owner: org,
repo: context.repo.repo,
issue_number: context.issue.number,
labels: [labelName]
});
// 2. Post a polite comment
const comment = `
Hi @${username}, it looks like the \`${labelName}\` label was removed.
This label is managed by project maintainers. We've added it back to ensure the issue remains visible to potential contributors until a maintainer decides otherwise.
Thank you for your understanding!
`.trim().replace(/^[ ]+/gm, '');
await github.rest.issues.createComment ({
owner: org,
repo: context.repo.repo,
issue_number: context.issue.number,
body: comment
});
}
}
+42 -123
View File
@@ -9,7 +9,6 @@ on:
jobs:
labeler:
if: "github.repository == 'google-gemini/gemini-cli'"
runs-on: 'ubuntu-latest'
permissions:
issues: 'write'
@@ -24,32 +23,16 @@ jobs:
const allowedParentUrls = [
'https://github.com/google-gemini/gemini-cli/issues/15374',
'https://github.com/google-gemini/gemini-cli/issues/15456',
'https://github.com/google-gemini/gemini-cli/issues/15324',
'https://github.com/google-gemini/gemini-cli/issues/17202',
'https://github.com/google-gemini/gemini-cli/issues/17203'
'https://github.com/google-gemini/gemini-cli/issues/15324'
];
// Single issue processing (for event triggers)
async function processSingleIssue(owner, repo, number) {
async function getIssueParent(owner, repo, number) {
const query = `
query($owner:String!, $repo:String!, $number:Int!) {
repository(owner:$owner, name:$repo) {
issue(number:$number) {
number
parent {
url
parent {
url
parent {
url
parent {
url
parent {
url
}
}
}
}
}
}
}
@@ -57,119 +40,55 @@ jobs:
`;
try {
const result = await github.graphql(query, { owner, repo, number });
if (!result || !result.repository || !result.repository.issue) {
console.log(`Issue #${number} not found or data missing.`);
return;
}
const issue = result.repository.issue;
await checkAndLabel(issue, owner, repo);
return result.repository.issue.parent ? result.repository.issue.parent.url : null;
} catch (error) {
console.error(`Failed to process issue #${number}:`, error);
throw error; // Re-throw to be caught by main execution
console.error(`Failed to fetch parent for #${number}:`, error);
return null;
}
}
// Bulk processing (for schedule/dispatch)
async function processAllOpenIssues(owner, repo) {
const query = `
query($owner:String!, $repo:String!, $cursor:String) {
repository(owner:$owner, name:$repo) {
issues(first: 100, states: OPEN, after: $cursor) {
pageInfo {
hasNextPage
endCursor
}
nodes {
number
parent {
url
parent {
url
parent {
url
parent {
url
parent {
url
}
}
}
}
}
}
}
}
}
`;
// Determine which issues to process
let issuesToProcess = [];
let hasNextPage = true;
let cursor = null;
while (hasNextPage) {
try {
const result = await github.graphql(query, { owner, repo, cursor });
if (!result || !result.repository || !result.repository.issues) {
console.error('Invalid response structure from GitHub API');
break;
}
const issues = result.repository.issues.nodes || [];
console.log(`Processing batch of ${issues.length} issues...`);
for (const issue of issues) {
await checkAndLabel(issue, owner, repo);
}
hasNextPage = result.repository.issues.pageInfo.hasNextPage;
cursor = result.repository.issues.pageInfo.endCursor;
} catch (error) {
console.error('Failed to fetch issues batch:', error);
throw error; // Re-throw to be caught by main execution
}
}
if (context.eventName === 'issues') {
// Context payload for 'issues' event already has the issue object
issuesToProcess.push({
number: context.payload.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
} else {
// For schedule/dispatch, fetch open issues (lightweight list)
console.log(`Running for event: ${context.eventName}. Fetching open issues...`);
const openIssues = await github.paginate(github.rest.issues.listForRepo, {
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open'
});
issuesToProcess = openIssues.map(i => ({
number: i.number,
owner: context.repo.owner,
repo: context.repo.repo
}));
}
async function checkAndLabel(issue, owner, repo) {
if (!issue || !issue.parent) return;
console.log(`Processing ${issuesToProcess.length} issue(s)...`);
let currentParent = issue.parent;
let tracedParents = [];
let matched = false;
for (const issue of issuesToProcess) {
const parentUrl = await getIssueParent(issue.owner, issue.repo, issue.number);
while (currentParent) {
tracedParents.push(currentParent.url);
if (allowedParentUrls.includes(currentParent.url)) {
console.log(`SUCCESS: Issue #${issue.number} is a descendant of ${currentParent.url}. Trace: ${tracedParents.join(' -> ')}. Adding label.`);
await github.rest.issues.addLabels({
owner,
repo,
issue_number: issue.number,
labels: [labelToAdd]
});
matched = true;
break;
}
currentParent = currentParent.parent;
}
if (!matched && context.eventName === 'issues') {
console.log(`Issue #${issue.number} did not match any allowed workstreams. Trace: ${tracedParents.join(' -> ') || 'None'}.`);
}
}
// Main execution
try {
if (context.eventName === 'issues') {
console.log(`Processing single issue #${context.payload.issue.number}...`);
await processSingleIssue(context.repo.owner, context.repo.repo, context.payload.issue.number);
if (parentUrl && allowedParentUrls.includes(parentUrl)) {
console.log(`SUCCESS: Issue #${issue.number} is a direct child of ${parentUrl}. Adding label.`);
await github.rest.issues.addLabels({
owner: issue.owner,
repo: issue.repo,
issue_number: issue.number,
labels: [labelToAdd]
});
} else {
console.log(`Running for event: ${context.eventName}. Processing all open issues...`);
await processAllOpenIssues(context.repo.owner, context.repo.repo);
// logging only for single execution to avoid spam
if (context.eventName === 'issues') {
console.log(`Issue #${issue.number} parent is ${parentUrl || 'None'}. No action.`);
}
}
} catch (error) {
core.setFailed(`Workflow failed: ${error.message}`);
}
@@ -19,7 +19,7 @@ jobs:
APP_ID: '${{ secrets.APP_ID }}'
if: |-
${{ env.APP_ID != '' }}
uses: 'actions/create-github-app-token@v2'
uses: 'actions/create-github-app-token@a8d616148505b5069dccd32f177bb87d7f39123b' # ratchet:actions/create-github-app-token@v2
with:
app-id: '${{ secrets.APP_ID }}'
private-key: '${{ secrets.PRIVATE_KEY }}'
@@ -35,59 +35,9 @@ jobs:
const pr_number = context.payload.pull_request.number;
// 1. Check if the PR author is a maintainer
// Check team membership (most reliable for private org members)
let isTeamMember = false;
const teams = ['gemini-cli-maintainers', 'gemini-cli-askmode-approvers', 'gemini-cli-docs'];
for (const team_slug of teams) {
try {
const members = await github.paginate(github.rest.teams.listMembersInOrg, {
org: org,
team_slug: team_slug
});
if (members.some(m => m.login.toLowerCase() === username.toLowerCase())) {
isTeamMember = true;
core.info(`${username} is a member of ${team_slug}. No notification needed.`);
break;
}
} catch (e) {
core.warning(`Failed to fetch team members from ${team_slug}: ${e.message}`);
}
}
if (isTeamMember) return;
// Check author_association from webhook payload
const authorAssociation = context.payload.pull_request.author_association;
const isRepoMaintainer = ['OWNER', 'MEMBER', 'COLLABORATOR'].includes(authorAssociation);
if (isRepoMaintainer) {
core.info(`${username} is a maintainer (author_association: ${authorAssociation}). No notification needed.`);
return;
}
// Check if author is a Googler
const isGoogler = async (login) => {
try {
const orgs = ['googlers', 'google'];
for (const org of orgs) {
try {
await github.rest.orgs.checkMembershipForUser({
org: org,
username: login
});
return true;
} catch (e) {
if (e.status !== 404) throw e;
}
}
} catch (e) {
core.warning(`Failed to check org membership for ${login}: ${e.message}`);
}
return false;
};
if (await isGoogler(username)) {
core.info(`${username} is a Googler. No notification needed.`);
if (['OWNER', 'MEMBER', 'COLLABORATOR'].includes(authorAssociation)) {
core.info(`${username} is a maintainer (Association: ${authorAssociation}). No notification needed.`);
return;
}
-29
View File
@@ -1,29 +0,0 @@
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
name: 'PR rate limiter'
permissions: {}
on:
pull_request_target:
types:
- 'opened'
- 'reopened'
jobs:
limit:
runs-on: 'gemini-cli-ubuntu-16-core'
permissions:
contents: 'read'
pull-requests: 'write'
steps:
- name: 'Limit open pull requests per user'
uses: 'Homebrew/actions/limit-pull-requests@9ceb7934560eb61d131dde205a6c2d77b2e1529d' # master
with:
except-author-associations: 'MEMBER,OWNER,COLLABORATOR'
comment-limit: 8
comment: >
You already have 7 pull requests open. Please work on getting
existing PRs merged before opening more.
close-limit: 8
close: true
@@ -32,7 +32,6 @@ on:
jobs:
change-tags:
if: "github.repository == 'google-gemini/gemini-cli'"
runs-on: 'ubuntu-latest'
environment: "${{ github.event.inputs.environment || 'prod' }}"
permissions:
-2
View File
@@ -47,7 +47,6 @@ on:
jobs:
release:
if: "github.repository == 'google-gemini/gemini-cli'"
runs-on: 'ubuntu-latest'
environment: "${{ github.event.inputs.environment || 'prod' }}"
permissions:
@@ -111,7 +110,6 @@ jobs:
wombat-token-cli: '${{ secrets.WOMBAT_TOKEN_CLI }}'
wombat-token-a2a-server: '${{ secrets.WOMBAT_TOKEN_A2A_SERVER }}'
github-token: '${{ secrets.GITHUB_TOKEN }}'
github-release-token: '${{ secrets.GEMINI_CLI_ROBOT_GITHUB_PAT }}'
dry-run: '${{ github.event.inputs.dry_run }}'
previous-tag: '${{ steps.release_info.outputs.PREVIOUS_TAG }}'
skip-github-release: '${{ github.event.inputs.skip_github_release }}'
-1
View File
@@ -124,7 +124,6 @@ jobs:
wombat-token-cli: '${{ secrets.WOMBAT_TOKEN_CLI }}'
wombat-token-a2a-server: '${{ secrets.WOMBAT_TOKEN_A2A_SERVER }}'
github-token: '${{ secrets.GITHUB_TOKEN }}'
github-release-token: '${{ secrets.GEMINI_CLI_ROBOT_GITHUB_PAT }}'
dry-run: '${{ steps.vars.outputs.is_dry_run }}'
previous-tag: '${{ steps.nightly_version.outputs.PREVIOUS_TAG }}'
working-directory: './release'
-101
View File
@@ -1,101 +0,0 @@
# This workflow is triggered on every new release.
# It uses Gemini to generate release notes and creates a PR with the changes.
name: 'Generate Release Notes'
on:
release:
types: ['published']
workflow_dispatch:
inputs:
version:
description: 'New version (e.g., v1.2.3)'
required: true
type: 'string'
body:
description: 'Release notes body'
required: true
type: 'string'
time:
description: 'Release time'
required: true
type: 'string'
jobs:
generate-release-notes:
if: "github.repository == 'google-gemini/gemini-cli'"
runs-on: 'ubuntu-latest'
permissions:
contents: 'write'
pull-requests: 'write'
steps:
- name: 'Checkout repository'
uses: 'actions/checkout@v4'
with:
# The user-level skills need to be available to the workflow
fetch-depth: 0
ref: 'main'
- name: 'Set up Node.js'
uses: 'actions/setup-node@v4'
with:
node-version: '20'
- name: 'Get release information'
id: 'release_info'
run: |
VERSION="${{ github.event.inputs.version || github.event.release.tag_name }}"
TIME="${{ github.event.inputs.time || github.event.release.created_at }}"
echo "VERSION=${VERSION}" >> "$GITHUB_OUTPUT"
echo "TIME=${TIME}" >> "$GITHUB_OUTPUT"
# Use a heredoc to preserve multiline release body
echo 'RAW_CHANGELOG<<EOF' >> "$GITHUB_OUTPUT"
printf "%s\n" "$BODY" >> "$GITHUB_OUTPUT"
echo 'EOF' >> "$GITHUB_OUTPUT"
env:
GH_TOKEN: '${{ secrets.GEMINI_CLI_ROBOT_GITHUB_PAT }}'
BODY: '${{ github.event.inputs.body || github.event.release.body }}'
- name: 'Validate version'
id: 'validate_version'
run: |
if echo "${{ steps.release_info.outputs.VERSION }}" | grep -q "nightly"; then
echo "Nightly release detected. Stopping workflow."
echo "CONTINUE=false" >> "$GITHUB_OUTPUT"
else
echo "CONTINUE=true" >> "$GITHUB_OUTPUT"
fi
- name: 'Generate Changelog with Gemini'
if: "steps.validate_version.outputs.CONTINUE == 'true'"
uses: 'google-github-actions/run-gemini-cli@a3bf79042542528e91937b3a3a6fbc4967ee3c31' # ratchet:google-github-actions/run-gemini-cli@v0
with:
gemini_api_key: '${{ secrets.GEMINI_API_KEY }}'
prompt: |
Activate the 'docs-changelog' skill.
**Release Information:**
- New Version: ${{ steps.release_info.outputs.VERSION }}
- Release Date: ${{ steps.release_info.outputs.TIME }}
- Raw Changelog Data: ${{ steps.release_info.outputs.RAW_CHANGELOG }}
Execute the release notes generation process using the information provided.
When you are done, please output your thought process and the steps you took for future debugging purposes.
- name: 'Create Pull Request'
if: "steps.validate_version.outputs.CONTINUE == 'true'"
uses: 'peter-evans/create-pull-request@v6'
with:
token: '${{ secrets.GEMINI_CLI_ROBOT_GITHUB_PAT }}'
commit-message: 'docs(changelog): update for ${{ steps.release_info.outputs.VERSION }}'
title: 'Changelog for ${{ steps.release_info.outputs.VERSION }}'
body: |
This PR contains the auto-generated changelog for the ${{ steps.release_info.outputs.VERSION }} release.
Please review and merge.
branch: 'changelog-${{ steps.release_info.outputs.VERSION }}'
base: 'main'
team-reviewers: 'gemini-cli-docs, gemini-cli-maintainers'
delete-branch: true
+5 -12
View File
@@ -118,7 +118,6 @@ jobs:
ORIGINAL_RELEASE_VERSION: '${{ steps.patch_version.outputs.RELEASE_VERSION }}'
ORIGINAL_RELEASE_TAG: '${{ steps.patch_version.outputs.RELEASE_TAG }}'
ORIGINAL_PREVIOUS_TAG: '${{ steps.patch_version.outputs.PREVIOUS_TAG }}'
VARS_CLI_PACKAGE_NAME: '${{ vars.CLI_PACKAGE_NAME }}'
run: |
echo "🔍 Verifying no concurrent patch releases have occurred..."
@@ -130,7 +129,7 @@ jobs:
# Re-run the same version calculation script
echo "Re-calculating version to check for changes..."
CURRENT_PATCH_JSON=$(node scripts/get-release-version.js --cli-package-name="${VARS_CLI_PACKAGE_NAME}" --type=patch --patch-from="${CHANNEL}")
CURRENT_PATCH_JSON=$(node scripts/get-release-version.js --cli-package-name="${{vars.CLI_PACKAGE_NAME}}" --type=patch --patch-from="${CHANNEL}")
CURRENT_RELEASE_VERSION=$(echo "${CURRENT_PATCH_JSON}" | jq -r .releaseVersion)
CURRENT_RELEASE_TAG=$(echo "${CURRENT_PATCH_JSON}" | jq -r .releaseTag)
CURRENT_PREVIOUS_TAG=$(echo "${CURRENT_PATCH_JSON}" | jq -r .previousReleaseTag)
@@ -163,15 +162,10 @@ jobs:
- name: 'Print Calculated Version'
run: |-
echo "Patch Release Summary:"
echo " Release Version: ${STEPS_PATCH_VERSION_OUTPUTS_RELEASE_VERSION}"
echo " Release Tag: ${STEPS_PATCH_VERSION_OUTPUTS_RELEASE_TAG}"
echo " NPM Tag: ${STEPS_PATCH_VERSION_OUTPUTS_NPM_TAG}"
echo " Previous Tag: ${STEPS_PATCH_VERSION_OUTPUTS_PREVIOUS_TAG}"
env:
STEPS_PATCH_VERSION_OUTPUTS_RELEASE_VERSION: '${{ steps.patch_version.outputs.RELEASE_VERSION }}'
STEPS_PATCH_VERSION_OUTPUTS_RELEASE_TAG: '${{ steps.patch_version.outputs.RELEASE_TAG }}'
STEPS_PATCH_VERSION_OUTPUTS_NPM_TAG: '${{ steps.patch_version.outputs.NPM_TAG }}'
STEPS_PATCH_VERSION_OUTPUTS_PREVIOUS_TAG: '${{ steps.patch_version.outputs.PREVIOUS_TAG }}'
echo " Release Version: ${{ steps.patch_version.outputs.RELEASE_VERSION }}"
echo " Release Tag: ${{ steps.patch_version.outputs.RELEASE_TAG }}"
echo " NPM Tag: ${{ steps.patch_version.outputs.NPM_TAG }}"
echo " Previous Tag: ${{ steps.patch_version.outputs.PREVIOUS_TAG }}"
- name: 'Run Tests'
if: "${{github.event.inputs.force_skip_tests != 'true'}}"
@@ -190,7 +184,6 @@ jobs:
wombat-token-cli: '${{ secrets.WOMBAT_TOKEN_CLI }}'
wombat-token-a2a-server: '${{ secrets.WOMBAT_TOKEN_A2A_SERVER }}'
github-token: '${{ secrets.GITHUB_TOKEN }}'
github-release-token: '${{ secrets.GEMINI_CLI_ROBOT_GITHUB_PAT }}'
dry-run: '${{ github.event.inputs.dry_run }}'
previous-tag: '${{ steps.patch_version.outputs.PREVIOUS_TAG }}'
gemini_api_key: '${{ secrets.GEMINI_API_KEY }}'
+3 -11
View File
@@ -239,7 +239,6 @@ jobs:
wombat-token-cli: '${{ secrets.WOMBAT_TOKEN_CLI }}'
wombat-token-a2a-server: '${{ secrets.WOMBAT_TOKEN_A2A_SERVER }}'
github-token: '${{ secrets.GITHUB_TOKEN }}'
github-release-token: '${{ secrets.GEMINI_CLI_ROBOT_GITHUB_PAT }}'
dry-run: '${{ github.event.inputs.dry_run }}'
previous-tag: '${{ needs.calculate-versions.outputs.PREVIOUS_PREVIEW_TAG }}'
working-directory: './release'
@@ -306,7 +305,6 @@ jobs:
wombat-token-cli: '${{ secrets.WOMBAT_TOKEN_CLI }}'
wombat-token-a2a-server: '${{ secrets.WOMBAT_TOKEN_A2A_SERVER }}'
github-token: '${{ secrets.GITHUB_TOKEN }}'
github-release-token: '${{ secrets.GEMINI_CLI_ROBOT_GITHUB_PAT }}'
dry-run: '${{ github.event.inputs.dry_run }}'
previous-tag: '${{ needs.calculate-versions.outputs.PREVIOUS_STABLE_TAG }}'
working-directory: './release'
@@ -335,7 +333,6 @@ jobs:
name: 'Create Nightly PR'
needs: ['publish-stable', 'calculate-versions']
runs-on: 'ubuntu-latest'
environment: "${{ github.event.inputs.environment || 'prod' }}"
permissions:
contents: 'write'
pull-requests: 'write'
@@ -363,28 +360,23 @@ jobs:
- name: 'Create and switch to a new branch'
id: 'release_branch'
run: |
BRANCH_NAME="chore/nightly-version-bump-${NEEDS_CALCULATE_VERSIONS_OUTPUTS_NEXT_NIGHTLY_VERSION}"
BRANCH_NAME="chore/nightly-version-bump-${{ needs.calculate-versions.outputs.NEXT_NIGHTLY_VERSION }}"
git switch -c "${BRANCH_NAME}"
echo "BRANCH_NAME=${BRANCH_NAME}" >> "${GITHUB_OUTPUT}"
env:
NEEDS_CALCULATE_VERSIONS_OUTPUTS_NEXT_NIGHTLY_VERSION: '${{ needs.calculate-versions.outputs.NEXT_NIGHTLY_VERSION }}'
- name: 'Update package versions'
run: 'npm run release:version "${NEEDS_CALCULATE_VERSIONS_OUTPUTS_NEXT_NIGHTLY_VERSION}"'
env:
NEEDS_CALCULATE_VERSIONS_OUTPUTS_NEXT_NIGHTLY_VERSION: '${{ needs.calculate-versions.outputs.NEXT_NIGHTLY_VERSION }}'
run: 'npm run release:version "${{ needs.calculate-versions.outputs.NEXT_NIGHTLY_VERSION }}"'
- name: 'Commit and Push package versions'
env:
BRANCH_NAME: '${{ steps.release_branch.outputs.BRANCH_NAME }}'
DRY_RUN: '${{ github.event.inputs.dry_run }}'
NEEDS_CALCULATE_VERSIONS_OUTPUTS_NEXT_NIGHTLY_VERSION: '${{ needs.calculate-versions.outputs.NEXT_NIGHTLY_VERSION }}'
run: |-
git add package.json packages/*/package.json
if [ -f package-lock.json ]; then
git add package-lock.json
fi
git commit -m "chore(release): bump version to ${NEEDS_CALCULATE_VERSIONS_OUTPUTS_NEXT_NIGHTLY_VERSION}"
git commit -m "chore(release): bump version to ${{ needs.calculate-versions.outputs.NEXT_NIGHTLY_VERSION }}"
if [[ "${DRY_RUN}" == "false" ]]; then
echo "Pushing release branch to remote..."
git push --set-upstream origin "${BRANCH_NAME}"
+1 -2
View File
@@ -42,7 +42,6 @@ on:
jobs:
change-tags:
if: "github.repository == 'google-gemini/gemini-cli'"
environment: "${{ github.event.inputs.environment || 'prod' }}"
runs-on: 'ubuntu-latest'
permissions:
@@ -204,7 +203,7 @@ jobs:
run: |
ROLLBACK_COMMIT=$(git rev-parse -q --verify "$TARGET_TAG")
if [ "$ROLLBACK_COMMIT" != "$TARGET_HASH" ]; then
echo "❌ Failed to add tag ${TARGET_TAG} to commit ${TARGET_HASH}"
echo '❌ Failed to add tag $TARGET_TAG to commit $TARGET_HASH'
echo '❌ This means the tag was not added, and the workflow should fail.'
exit 1
fi
-1
View File
@@ -16,7 +16,6 @@ on:
jobs:
build:
if: "github.repository == 'google-gemini/gemini-cli'"
runs-on: 'ubuntu-latest'
permissions:
contents: 'read'
-1
View File
@@ -20,7 +20,6 @@ on:
jobs:
smoke-test:
if: "github.repository == 'google-gemini/gemini-cli'"
runs-on: 'ubuntu-latest'
permissions:
contents: 'write'
+2 -2
View File
@@ -40,5 +40,5 @@ jobs:
If this is still relevant, you are welcome to reopen or leave a comment. Thanks for contributing!
days-before-stale: 60
days-before-close: 14
exempt-issue-labels: 'pinned,security,🔒 maintainer only,help wanted,🗓️ Public Roadmap'
exempt-pr-labels: 'pinned,security,🔒 maintainer only,help wanted,🗓️ Public Roadmap'
exempt-issue-labels: 'pinned,security'
exempt-pr-labels: 'pinned,security'
+2 -4
View File
@@ -15,7 +15,6 @@ on:
jobs:
save_repo_name:
if: "github.repository == 'google-gemini/gemini-cli'"
runs-on: 'gemini-cli-ubuntu-16-core'
steps:
- name: 'Save Repo name'
@@ -24,15 +23,14 @@ jobs:
HEAD_SHA: '${{ github.event.inputs.head_sha || github.event.pull_request.head.sha }}'
run: |
mkdir -p ./pr
echo "${REPO_NAME}" > ./pr/repo_name
echo "${HEAD_SHA}" > ./pr/head_sha
echo '${{ env.REPO_NAME }}' > ./pr/repo_name
echo '${{ env.HEAD_SHA }}' > ./pr/head_sha
- uses: 'actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02' # ratchet:actions/upload-artifact@v4
with:
name: 'repo_name'
path: 'pr/'
trigger_e2e:
name: 'Trigger e2e'
if: "github.repository == 'google-gemini/gemini-cli'"
runs-on: 'gemini-cli-ubuntu-16-core'
steps:
- id: 'trigger-e2e'
+1 -6
View File
@@ -28,13 +28,8 @@ on:
jobs:
verify-release:
if: "github.repository == 'google-gemini/gemini-cli'"
environment: "${{ github.event.inputs.environment || 'prod' }}"
strategy:
fail-fast: false
matrix:
os: ['ubuntu-latest', 'macos-latest', 'windows-latest']
runs-on: '${{ matrix.os }}'
runs-on: 'ubuntu-latest'
permissions:
contents: 'read'
packages: 'write'
+1 -3
View File
@@ -46,7 +46,6 @@ 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*/
@@ -56,9 +55,8 @@ gha-creds-*.json
# Log files
patch_output.log
gemini-debug.log
.genkit
.gemini-clipboard/
.eslintcache
evals/logs/
evals/logs/
-1
View File
@@ -21,4 +21,3 @@ junit.xml
Thumbs.db
.pytest_cache
**/SKILL.md
packages/sdk/test-data/*.json
+18 -21
View File
@@ -45,7 +45,7 @@ The process for contributing code is as follows:
`🔒Maintainers only`, this means it is reserved for project maintainers. We
will not accept pull requests related to these issues. In the near future,
we will explicitly mark issues looking for contributions using the
`help-wanted` label. If you believe an issue is a good candidate for
`help wanted` label. If you believe an issue is a good candidate for
community contribution, please leave a comment on the issue. A maintainer
will review it and apply the `help-wanted` label if appropriate. Only
maintainers should attempt to add the `help-wanted` label to an issue.
@@ -75,14 +75,11 @@ Replace `<PR_NUMBER>` with your pull request number. Authors are encouraged to
run this on their own PRs for self-review, and reviewers should use it to
augment their manual review process.
### Self-assigning and unassigning issues
### Self assigning issues
To assign an issue to yourself, simply add a comment with the text `/assign`. To
unassign yourself from an issue, add a comment with the text `/unassign`.
The comment must contain only that text and nothing else. These commands will
assign or unassign the issue as requested, provided the conditions are met
(e.g., an issue must be unassigned to be assigned).
To assign an issue to yourself, simply add a comment with the text `/assign`.
The comment must contain only that text and nothing else. This command will
assign the issue to you, provided it is not already assigned.
Please note that you can have a maximum of 3 issues assigned to you at any given
time.
@@ -375,7 +372,8 @@ specific debug settings.
### React DevTools
To debug the CLI's React-based UI, you can use 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.
1. **Start the Gemini CLI in development mode:**
@@ -383,20 +381,20 @@ To debug the CLI's React-based UI, you can use React DevTools.
DEV=true npm start
```
2. **Install and run React DevTools version 6 (which matches the CLI's
`react-devtools-core`):**
2. **Install and run React DevTools version 4.28.5 (or the latest compatible
4.x version):**
You can either install it globally:
```bash
npm install -g react-devtools@6
npm install -g react-devtools@4.28.5
react-devtools
```
Or run it directly using npx:
```bash
npx react-devtools@6
npx react-devtools@4.28.5
```
Your running CLI application should then connect to React DevTools.
@@ -410,13 +408,12 @@ On macOS, `gemini` uses Seatbelt (`sandbox-exec`) under a `permissive-open`
profile (see `packages/cli/src/utils/sandbox-macos-permissive-open.sb`) that
restricts writes to the project folder but otherwise allows all other operations
and outbound network traffic ("open") by default. You can switch to a
`strict-open` profile (see
`packages/cli/src/utils/sandbox-macos-strict-open.sb`) that restricts both reads
and writes to the working directory while allowing outbound network traffic by
setting `SEATBELT_PROFILE=strict-open` in your environment or `.env` file.
Available built-in profiles are `permissive-{open,proxied}`,
`restrictive-{open,proxied}`, and `strict-{open,proxied}` (see below for proxied
networking). You can also switch to a custom profile
`restrictive-closed` profile (see
`packages/cli/src/utils/sandbox-macos-restrictive-closed.sb`) that declines all
operations and outbound network traffic ("closed") by default by setting
`SEATBELT_PROFILE=restrictive-closed` in your environment or `.env` file.
Available built-in profiles are `{permissive,restrictive}-{open,closed,proxied}`
(see below for proxied networking). You can also switch to a custom profile
`SEATBELT_PROFILE=<profile>` if you also create a file
`.gemini/sandbox-macos-<profile>.sb` under your project settings directory
`.gemini`.
@@ -548,7 +545,7 @@ Before submitting your documentation pull request, please:
If you have questions about contributing documentation:
- Check our [FAQ](/docs/resources/faq.md).
- Check our [FAQ](/docs/faq.md).
- Review existing documentation for examples.
- Open [an issue](https://github.com/google-gemini/gemini-cli/issues) to discuss
your proposed changes.
+1 -4
View File
@@ -42,10 +42,7 @@ USER node
# install gemini-cli and clean up
COPY packages/cli/dist/google-gemini-cli-*.tgz /tmp/gemini-cli.tgz
COPY packages/core/dist/google-gemini-cli-core-*.tgz /tmp/gemini-core.tgz
RUN npm install -g /tmp/gemini-core.tgz \
&& npm install -g /tmp/gemini-cli.tgz \
&& node -e "const fs=require('node:fs'); JSON.parse(fs.readFileSync('/usr/local/share/npm-global/lib/node_modules/@google/gemini-cli/package.json','utf8')); JSON.parse(fs.readFileSync('/usr/local/share/npm-global/lib/node_modules/@google/gemini-cli-core/package.json','utf8'));" \
&& gemini --version > /dev/null \
RUN npm install -g /tmp/gemini-cli.tgz /tmp/gemini-core.tgz \
&& npm cache clean --force \
&& rm -f /tmp/gemini-{cli,core}.tgz
+407 -81
View File
@@ -1,94 +1,420 @@
# Gemini CLI Project Context
## Building and running
Gemini CLI is an open-source AI agent that brings the power of Gemini directly
into the terminal. It is designed to be a terminal-first, extensible, and
powerful tool for developers.
Before submitting any changes, it is crucial to validate them by running the
full preflight check. This command will build the repository, run all tests,
check for type errors, and lint the code.
## Project Overview
To run the full suite of checks, execute the following command:
- **Purpose:** Provide a seamless terminal interface for Gemini models,
supporting code understanding, generation, automation, and integration via MCP
(Model Context Protocol).
- **Main Technologies:**
- **Runtime:** Node.js (>=20.0.0, recommended ~20.19.0 for development)
- **Language:** TypeScript
- **UI Framework:** React (using [Ink](https://github.com/vadimdemedes/ink)
for CLI rendering)
- **Testing:** Vitest
- **Bundling:** esbuild
- **Linting/Formatting:** ESLint, Prettier
- **Architecture:** Monorepo structure using npm workspaces.
- `packages/cli`: User-facing terminal UI, input processing, and display
rendering.
- `packages/core`: Backend logic, Gemini API orchestration, prompt
construction, and tool execution.
- `packages/core/src/tools/`: Built-in tools for file system, shell, and web
operations.
- `packages/a2a-server`: Experimental Agent-to-Agent server.
- `packages/vscode-ide-companion`: VS Code extension pairing with the CLI.
```bash
npm run preflight
```
## Building and Running
This single command ensures that your changes meet all the quality gates of the
project. While you can run the individual steps (`build`, `test`, `typecheck`,
`lint`) separately, it is highly recommended to use `npm run preflight` to
ensure a comprehensive validation.
- **Install Dependencies:** `npm install`
- **Build All:** `npm run build:all` (Builds packages, sandbox, and VS Code
companion)
- **Build Packages:** `npm run build`
- **Run in Development:** `npm run start`
- **Run in Debug Mode:** `npm run debug` (Enables Node.js inspector)
- **Bundle Project:** `npm run bundle`
- **Clean Artifacts:** `npm run clean`
## Running Tests in Workspaces\*\*: To run a specific test file within a
## Testing and Quality
workspace, use the command:
`npm test -w <workspace-name> -- <path/to/test-file.test.ts>`. **CRITICAL**: The
`<path/to/test-file.test.ts>` MUST be relative to the workspace directory root,
NOT the project root.
- **Test Commands:**
- **Unit (All):** `npm run test`
- **Integration (E2E):** `npm run test:e2e`
- **Workspace-Specific:** `npm test -w <pkg> -- <path>` (Note: `<path>` must
be relative to the workspace root, e.g.,
`-w @google/gemini-cli-core -- src/routing/modelRouterService.test.ts`)
- **Full Validation:** `npm run preflight` (Heaviest check; runs clean, install,
build, lint, type check, and tests. Recommended before submitting PRs. Due to
its long runtime, only run this at the very end of a code implementation task.
If it fails, use faster, targeted commands (e.g., `npm run test`,
`npm run lint`, or workspace-specific tests) to iterate on fixes before
re-running `preflight`. For simple, non-code changes like documentation or
prompting updates, skip `preflight` at the end of the task and wait for PR
validation.)
- **Individual Checks:** `npm run lint` / `npm run format` / `npm run typecheck`
- _Example (Core package)_:
`npm test -w @google/gemini-cli-core -- src/routing/modelRouterService.test.ts`
- _Common workspaces_: `@google/gemini-cli`, `@google/gemini-cli-core`.
## Development Conventions
## Writing Tests
- **Legacy Snippets:** `packages/core/src/prompts/snippets.legacy.ts` is a
snapshot of an older system prompt. Avoid changing the prompting verbiage to
preserve its historical behavior; however, structural changes to ensure
compilation or simplify the code are permitted.
- **Contributions:** Follow the process outlined in `CONTRIBUTING.md`. Requires
signing the Google CLA.
- **Pull Requests:** Keep PRs small, focused, and linked to an existing issue.
Always activate the `pr-creator` skill for PR generation, even when using the
`gh` CLI.
- **Commit Messages:** Follow the
[Conventional Commits](https://www.conventionalcommits.org/) standard.
- **Coding Style:** Adhere to existing patterns in `packages/cli` (React/Ink)
and `packages/core` (Backend logic).
- **Imports:** Use specific imports and avoid restricted relative imports
between packages (enforced by ESLint).
- **License Headers:** For all new source code files (`.ts`, `.tsx`, `.js`),
include the Apache-2.0 license header with the current year. (e.g.,
`Copyright 2026 Google LLC`). This is enforced by ESLint.
This project uses **Vitest** as its primary testing framework. When writing
tests, aim to follow existing patterns. Key conventions include:
## Testing Conventions
### Test Structure and Framework
- **Environment Variables:** When testing code that depends on environment
variables, use `vi.stubEnv('NAME', 'value')` in `beforeEach` and
`vi.unstubAllEnvs()` in `afterEach`. Avoid modifying `process.env` directly as
it can lead to test leakage and is less reliable. To "unset" a variable, use
an empty string `vi.stubEnv('NAME', '')`.
- **Framework**: All tests are written using Vitest (`describe`, `it`, `expect`,
`vi`).
- **File Location**: Test files (`*.test.ts` for logic, `*.test.tsx` for React
components) are co-located with the source files they test.
- **Configuration**: Test environments are defined in `vitest.config.ts` files.
- **Setup/Teardown**: Use `beforeEach` and `afterEach`. Commonly,
`vi.resetAllMocks()` is called in `beforeEach` and `vi.restoreAllMocks()` in
`afterEach`.
## Documentation
### Mocking (`vi` from Vitest)
- Always use the `docs-writer` skill when you are asked to write, edit, or
review any documentation.
- Documentation is located in the `docs/` directory.
- Suggest documentation updates when code changes render existing documentation
obsolete or incomplete.
- **ES Modules**: Mock with
`vi.mock('module-name', async (importOriginal) => { ... })`. Use
`importOriginal` for selective mocking.
- _Example_:
`vi.mock('os', async (importOriginal) => { const actual = await importOriginal(); return { ...actual, homedir: vi.fn() }; });`
- **Mocking Order**: For critical dependencies (e.g., `os`, `fs`) that affect
module-level constants, place `vi.mock` at the _very top_ of the test file,
before other imports.
- **Hoisting**: Use `const myMock = vi.hoisted(() => vi.fn());` if a mock
function needs to be defined before its use in a `vi.mock` factory.
- **Mock Functions**: Create with `vi.fn()`. Define behavior with
`mockImplementation()`, `mockResolvedValue()`, or `mockRejectedValue()`.
- **Spying**: Use `vi.spyOn(object, 'methodName')`. Restore spies with
`mockRestore()` in `afterEach`.
### Commonly Mocked Modules
- **Node.js built-ins**: `fs`, `fs/promises`, `os` (especially `os.homedir()`),
`path`, `child_process` (`execSync`, `spawn`).
- **External SDKs**: `@google/genai`, `@modelcontextprotocol/sdk`.
- **Internal Project Modules**: Dependencies from other project packages are
often mocked.
### React Component Testing (CLI UI - Ink)
- Use `render()` from `ink-testing-library`.
- Assert output with `lastFrame()`.
- Wrap components in necessary `Context.Provider`s.
- Mock custom React hooks and complex child components using `vi.mock()`.
### Asynchronous Testing
- Use `async/await`.
- For timers, use `vi.useFakeTimers()`, `vi.advanceTimersByTimeAsync()`,
`vi.runAllTimersAsync()`.
- Test promise rejections with `await expect(promise).rejects.toThrow(...)`.
### General Guidance
- When adding tests, first examine existing tests to understand and conform to
established conventions.
- Pay close attention to the mocks at the top of existing test files; they
reveal critical dependencies and how they are managed in a test environment.
## Git Repo
The main branch for this project is called "main"
## JavaScript/TypeScript
When contributing to this React, Node, and TypeScript codebase, please
prioritize the use of plain JavaScript objects with accompanying TypeScript
interface or type declarations over JavaScript class syntax. This approach
offers significant advantages, especially concerning interoperability with React
and overall code maintainability.
### Preferring Plain Objects over Classes
JavaScript classes, by their nature, are designed to encapsulate internal state
and behavior. While this can be useful in some object-oriented paradigms, it
often introduces unnecessary complexity and friction when working with React's
component-based architecture. Here's why plain objects are preferred:
- Seamless React Integration: React components thrive on explicit props and
state management. Classes' tendency to store internal state directly within
instances can make prop and state propagation harder to reason about and
maintain. Plain objects, on the other hand, are inherently immutable (when
used thoughtfully) and can be easily passed as props, simplifying data flow
and reducing unexpected side effects.
- Reduced Boilerplate and Increased Conciseness: Classes often promote the use
of constructors, this binding, getters, setters, and other boilerplate that
can unnecessarily bloat code. TypeScript interface and type declarations
provide powerful static type checking without the runtime overhead or
verbosity of class definitions. This allows for more succinct and readable
code, aligning with JavaScript's strengths in functional programming.
- Enhanced Readability and Predictability: Plain objects, especially when their
structure is clearly defined by TypeScript interfaces, are often easier to
read and understand. Their properties are directly accessible, and there's no
hidden internal state or complex inheritance chains to navigate. This
predictability leads to fewer bugs and a more maintainable codebase.
- Simplified Immutability: While not strictly enforced, plain objects encourage
an immutable approach to data. When you need to modify an object, you
typically create a new one with the desired changes, rather than mutating the
original. This pattern aligns perfectly with React's reconciliation process
and helps prevent subtle bugs related to shared mutable state.
- Better Serialization and Deserialization: Plain JavaScript objects are
naturally easy to serialize to JSON and deserialize back, which is a common
requirement in web development (e.g., for API communication or local storage).
Classes, with their methods and prototypes, can complicate this process.
### Embracing ES Module Syntax for Encapsulation
Rather than relying on Java-esque private or public class members, which can be
verbose and sometimes limit flexibility, we strongly prefer leveraging ES module
syntax (`import`/`export`) for encapsulating private and public APIs.
- Clearer Public API Definition: With ES modules, anything that is exported is
part of the public API of that module, while anything not exported is
inherently private to that module. This provides a very clear and explicit way
to define what parts of your code are meant to be consumed by other modules.
- Enhanced Testability (Without Exposing Internals): By default, unexported
functions or variables are not accessible from outside the module. This
encourages you to test the public API of your modules, rather than their
internal implementation details. If you find yourself needing to spy on or
stub an unexported function for testing purposes, it's often a "code smell"
indicating that the function might be a good candidate for extraction into its
own separate, testable module with a well-defined public API. This promotes a
more robust and maintainable testing strategy.
- Reduced Coupling: Explicitly defined module boundaries through import/export
help reduce coupling between different parts of your codebase. This makes it
easier to refactor, debug, and understand individual components in isolation.
### Avoiding `any` Types and Type Assertions; Preferring `unknown`
TypeScript's power lies in its ability to provide static type checking, catching
potential errors before your code runs. To fully leverage this, it's crucial to
avoid the `any` type and be judicious with type assertions.
- **The Dangers of `any`**: Using any effectively opts out of TypeScript's type
checking for that particular variable or expression. While it might seem
convenient in the short term, it introduces significant risks:
- **Loss of Type Safety**: You lose all the benefits of type checking, making
it easy to introduce runtime errors that TypeScript would otherwise have
caught.
- **Reduced Readability and Maintainability**: Code with `any` types is harder
to understand and maintain, as the expected type of data is no longer
explicitly defined.
- **Masking Underlying Issues**: Often, the need for any indicates a deeper
problem in the design of your code or the way you're interacting with
external libraries. It's a sign that you might need to refine your types or
refactor your code.
- **Preferring `unknown` over `any`**: When you absolutely cannot determine the
type of a value at compile time, and you're tempted to reach for any, consider
using unknown instead. unknown is a type-safe counterpart to any. While a
variable of type unknown can hold any value, you must perform type narrowing
(e.g., using typeof or instanceof checks, or a type assertion) before you can
perform any operations on it. This forces you to handle the unknown type
explicitly, preventing accidental runtime errors.
```ts
function processValue(value: unknown) {
if (typeof value === 'string') {
// value is now safely a string
console.log(value.toUpperCase());
} else if (typeof value === 'number') {
// value is now safely a number
console.log(value * 2);
}
// Without narrowing, you cannot access properties or methods on 'value'
// console.log(value.someProperty); // Error: Object is of type 'unknown'.
}
```
- **Type Assertions (`as Type`) - Use with Caution**: Type assertions tell the
TypeScript compiler, "Trust me, I know what I'm doing; this is definitely of
this type." While there are legitimate use cases (e.g., when dealing with
external libraries that don't have perfect type definitions, or when you have
more information than the compiler), they should be used sparingly and with
extreme caution.
- **Bypassing Type Checking**: Like `any`, type assertions bypass TypeScript's
safety checks. If your assertion is incorrect, you introduce a runtime error
that TypeScript would not have warned you about.
- **Code Smell in Testing**: A common scenario where `any` or type assertions
might be tempting is when trying to test "private" implementation details
(e.g., spying on or stubbing an unexported function within a module). This
is a strong indication of a "code smell" in your testing strategy and
potentially your code structure. Instead of trying to force access to
private internals, consider whether those internal details should be
refactored into a separate module with a well-defined public API. This makes
them inherently testable without compromising encapsulation.
### Type narrowing `switch` clauses
Use the `checkExhaustive` helper in the default clause of a switch statement.
This will ensure that all of the possible options within the value or
enumeration are used.
This helper method can be found in `packages/cli/src/utils/checks.ts`
### Embracing JavaScript's Array Operators
To further enhance code cleanliness and promote safe functional programming
practices, leverage JavaScript's rich set of array operators as much as
possible. Methods like `.map()`, `.filter()`, `.reduce()`, `.slice()`,
`.sort()`, and others are incredibly powerful for transforming and manipulating
data collections in an immutable and declarative way.
Using these operators:
- Promotes Immutability: Most array operators return new arrays, leaving the
original array untouched. This functional approach helps prevent unintended
side effects and makes your code more predictable.
- Improves Readability: Chaining array operators often lead to more concise and
expressive code than traditional for loops or imperative logic. The intent of
the operation is clear at a glance.
- Facilitates Functional Programming: These operators are cornerstones of
functional programming, encouraging the creation of pure functions that take
inputs and produce outputs without causing side effects. This paradigm is
highly beneficial for writing robust and testable code that pairs well with
React.
By consistently applying these principles, we can maintain a codebase that is
not only efficient and performant but also a joy to work with, both now and in
the future.
## React (mirrored and adjusted from [react-mcp-server](https://github.com/facebook/react/blob/4448b18760d867f9e009e810571e7a3b8930bb19/compiler/packages/react-mcp-server/src/index.ts#L376C1-L441C94))
### Role
You are a React assistant that helps users write more efficient and optimizable
React code. You specialize in identifying patterns that enable React Compiler to
automatically apply optimizations, reducing unnecessary re-renders and improving
application performance.
### Follow these guidelines in all code you produce and suggest
Use functional components with Hooks: Do not generate class components or use
old lifecycle methods. Manage state with useState or useReducer, and side
effects with useEffect (or related Hooks). Always prefer functions and Hooks for
any new component logic.
Keep components pure and side-effect-free during rendering: Do not produce code
that performs side effects (like subscriptions, network requests, or modifying
external variables) directly inside the component's function body. Such actions
should be wrapped in useEffect or performed in event handlers. Ensure your
render logic is a pure function of props and state.
Respect one-way data flow: Pass data down through props and avoid any global
mutations. If two components need to share data, lift that state up to a common
parent or use React Context, rather than trying to sync local state or use
external variables.
Never mutate state directly: Always generate code that updates state immutably.
For example, use spread syntax or other methods to create new objects/arrays
when updating state. Do not use assignments like state.someValue = ... or array
mutations like array.push() on state variables. Use the state setter (setState
from useState, etc.) to update state.
Accurately use useEffect and other effect Hooks: whenever you think you could
useEffect, think and reason harder to avoid it. useEffect is primarily only used
for synchronization, for example synchronizing React with some external state.
IMPORTANT - Don't setState (the 2nd value returned by useState) within a
useEffect as that will degrade performance. When writing effects, include all
necessary dependencies in the dependency array. Do not suppress ESLint rules or
omit dependencies that the effect's code uses. Structure the effect callbacks to
handle changing values properly (e.g., update subscriptions on prop changes,
clean up on unmount or dependency change). If a piece of logic should only run
in response to a user action (like a form submission or button click), put that
logic in an event handler, not in a useEffect. Where possible, useEffects should
return a cleanup function.
Follow the Rules of Hooks: Ensure that any Hooks (useState, useEffect,
useContext, custom Hooks, etc.) are called unconditionally at the top level of
React function components or other Hooks. Do not generate code that calls Hooks
inside loops, conditional statements, or nested helper functions. Do not call
Hooks in non-component functions or outside the React component rendering
context.
Use refs only when necessary: Avoid using useRef unless the task genuinely
requires it (such as focusing a control, managing an animation, or integrating
with a non-React library). Do not use refs to store application state that
should be reactive. If you do use refs, never write to or read from ref.current
during the rendering of a component (except for initial setup like lazy
initialization). Any ref usage should not affect the rendered output directly.
Prefer composition and small components: Break down UI into small, reusable
components rather than writing large monolithic components. The code you
generate should promote clarity and reusability by composing components
together. Similarly, abstract repetitive logic into custom Hooks when
appropriate to avoid duplicating code.
Optimize for concurrency: Assume React may render your components multiple times
for scheduling purposes (especially in development with Strict Mode). Write code
that remains correct even if the component function runs more than once. For
instance, avoid side effects in the component body and use functional state
updates (e.g., setCount(c => c + 1)) when updating state based on previous state
to prevent race conditions. Always include cleanup functions in effects that
subscribe to external resources. Don't write useEffects for "do this when this
changes" side effects. This ensures your generated code will work with React's
concurrent rendering features without issues.
Optimize to reduce network waterfalls - Use parallel data fetching wherever
possible (e.g., start multiple requests at once rather than one after another).
Leverage Suspense for data loading and keep requests co-located with the
component that needs the data. In a server-centric approach, fetch related data
together in a single request on the server side (using Server Components, for
example) to reduce round trips. Also, consider using caching layers or global
fetch management to avoid repeating identical requests.
Rely on React Compiler - useMemo, useCallback, and React.memo can be omitted if
React Compiler is enabled. Avoid premature optimization with manual memoization.
Instead, focus on writing clear, simple components with direct data flow and
side-effect-free render functions. Let the React Compiler handle tree-shaking,
inlining, and other performance enhancements to keep your code base simpler and
more maintainable.
Design for a good user experience - Provide clear, minimal, and non-blocking UI
states. When data is loading, show lightweight placeholders (e.g., skeleton
screens) rather than intrusive spinners everywhere. Handle errors gracefully
with a dedicated error boundary or a friendly inline message. Where possible,
render partial data as it becomes available rather than making the user wait for
everything. Suspense allows you to declare the loading states in your component
tree in a natural way, preventing “flash” states and improving perceived
performance.
### Process
1. Analyze the user's code for optimization opportunities:
- Check for React anti-patterns that prevent compiler optimization
- Look for component structure issues that limit compiler effectiveness
- Think about each suggestion you are making and consult React docs for best
practices
2. Provide actionable guidance:
- Explain specific code changes with clear reasoning
- Show before/after examples when suggesting changes
- Only suggest changes that meaningfully improve optimization potential
### Optimization Guidelines
- State updates should be structured to enable granular updates
- Side effects should be isolated and dependencies clearly defined
## Documentation guidelines
When working in the `/docs` directory, follow the guidelines in this section:
- **Role:** You are an expert technical writer and AI assistant for contributors
to Gemini CLI. Produce professional, accurate, and consistent documentation to
guide users of Gemini CLI.
- **Technical Accuracy:** Do not invent facts, commands, code, API names, or
output. All technical information specific to Gemini CLI must be based on code
found within this directory and its subdirectories.
- **Style Authority:** Your source for writing guidance and style is the
"Documentation contribution process" section in the root directory's
`CONTRIBUTING.md` file, as well as any guidelines provided this section.
- **Information Architecture Consideration:** Before proposing documentation
changes, consider the information architecture. If a change adds significant
new content to existing documents, evaluate if creating a new, more focused
page or changes to `sidebar.json` would provide a better user experience.
- **Proactive User Consideration:** The user experience should be a primary
concern when making changes to documentation. Aim to fill gaps in existing
knowledge whenever possible while keeping documentation concise and easy for
users to understand. If changes might hinder user understanding or
accessibility, proactively raise these concerns and propose alternatives.
## Comments policy
Only write high-value comments if at all. Avoid talking to the user through
comments.
## Logging and Error Handling
- **Avoid Console Statements:** Do not use `console.log`, `console.error`, or
similar methods directly.
- **Non-User-Facing Logs:** For developer-facing debug messages, use
`debugLogger` (from `@google/gemini-cli-core`).
- **User-Facing Feedback:** To surface errors or warnings to the user, use
`coreEvents.emitFeedback` (from `@google/gemini-cli-core`).
## General requirements
- If there is something you do not understand or is ambiguous, seek confirmation
or clarification from the user before making changes based on assumptions.
- Use hyphens instead of underscores in flag names (e.g. `my-flag` instead of
`my_flag`).
- Always refer to Gemini CLI as `Gemini CLI`, never `the Gemini CLI`.
+15 -33
View File
@@ -4,7 +4,7 @@
[![Gemini CLI E2E (Chained)](https://github.com/google-gemini/gemini-cli/actions/workflows/chained_e2e.yml/badge.svg)](https://github.com/google-gemini/gemini-cli/actions/workflows/chained_e2e.yml)
[![Version](https://img.shields.io/npm/v/@google/gemini-cli)](https://www.npmjs.com/package/@google/gemini-cli)
[![License](https://img.shields.io/github/license/google-gemini/gemini-cli)](https://github.com/google-gemini/gemini-cli/blob/main/LICENSE)
[![View Code Wiki](https://assets.codewiki.google/readme-badge/static.svg)](https://codewiki.google/github.com/google-gemini/gemini-cli?utm_source=badge&utm_medium=github&utm_campaign=github.com/google-gemini/gemini-cli)
[![View Code Wiki](https://www.gstatic.com/_/boq-sdlc-agents-ui/_/r/YUi5dj2UWvE.svg)](https://codewiki.google/github.com/google-gemini/gemini-cli)
![Gemini CLI Screenshot](./docs/assets/gemini-screenshot.png)
@@ -29,9 +29,10 @@ Learn all about Gemini CLI in our [documentation](https://geminicli.com/docs/).
## 📦 Installation
See
[Gemini CLI installation, execution, and releases](./docs/get-started/installation.md)
for recommended system specifications and a detailed installation guide.
### Pre-requisites before installation
- Node.js version 20 or higher
- macOS, Linux, or Windows
### Quick Install
@@ -54,23 +55,6 @@ npm install -g @google/gemini-cli
brew install gemini-cli
```
#### Install globally with MacPorts (macOS)
```bash
sudo port install gemini-cli
```
#### Install with Anaconda (for restricted environments)
```bash
# Create and activate a new environment
conda create -y -n gemini_env -c conda-forge nodejs
conda activate gemini_env
# Install Gemini CLI globally via npm (inside the environment)
npm install -g @google/gemini-cli
```
## Release Cadence and Tags
See [Releases](./docs/releases.md) for more details.
@@ -282,14 +266,14 @@ gemini
quickly.
- [**Authentication Setup**](./docs/get-started/authentication.md) - Detailed
auth configuration.
- [**Configuration Guide**](./docs/reference/configuration.md) - Settings and
- [**Configuration Guide**](./docs/get-started/configuration.md) - Settings and
customization.
- [**Keyboard Shortcuts**](./docs/reference/keyboard-shortcuts.md) -
Productivity tips.
- [**Keyboard Shortcuts**](./docs/cli/keyboard-shortcuts.md) - Productivity
tips.
### Core Features
- [**Commands Reference**](./docs/reference/commands.md) - All slash commands
- [**Commands Reference**](./docs/cli/commands.md) - All slash commands
(`/help`, `/chat`, etc).
- [**Custom Commands**](./docs/cli/custom-commands.md) - Create your own
reusable commands.
@@ -323,16 +307,15 @@ gemini
- [**Enterprise Guide**](./docs/cli/enterprise.md) - Deploy and manage in a
corporate environment.
- [**Telemetry & Monitoring**](./docs/cli/telemetry.md) - Usage tracking.
- [**Tools API Development**](./docs/reference/tools-api.md) - Create custom
tools.
- [**Tools API Development**](./docs/core/tools-api.md) - Create custom tools.
- [**Local development**](./docs/local-development.md) - Local development
tooling.
### Troubleshooting & Support
- [**Troubleshooting Guide**](./docs/resources/troubleshooting.md) - Common
issues and solutions.
- [**FAQ**](./docs/resources/faq.md) - Frequently asked questions.
- [**Troubleshooting Guide**](./docs/troubleshooting.md) - Common issues and
solutions.
- [**FAQ**](./docs/faq.md) - Frequently asked questions.
- Use `/bug` command to report issues directly from the CLI.
### Using MCP Servers
@@ -378,13 +361,12 @@ for planned features and priorities.
### Uninstall
See the [Uninstall Guide](./docs/resources/uninstall.md) for removal
instructions.
See the [Uninstall Guide](docs/cli/uninstall.md) for removal instructions.
## 📄 Legal
- **License**: [Apache License 2.0](LICENSE)
- **Terms of Service**: [Terms & Privacy](./docs/resources/tos-privacy.md)
- **Terms of Service**: [Terms & Privacy](./docs/tos-privacy.md)
- **Security**: [Security Policy](SECURITY.md)
---
-115
View File
@@ -1,115 +0,0 @@
# Enterprise Admin Controls
Gemini CLI empowers enterprise administrators to manage and enforce security
policies and configuration settings across their entire organization. Secure
defaults are enabled automatically for all enterprise users, but can be
customized via the [Management Console](https://goo.gle/manage-gemini-cli).
**Enterprise Admin Controls are enforced globally and cannot be overridden by
users locally**, ensuring a consistent security posture.
## Admin Controls vs. System Settings
While [System-wide settings](../cli/settings.md) act as convenient configuration
overrides, they can still be modified by users with sufficient privileges. In
contrast, admin controls are immutable at the local level, making them the
preferred method for enforcing policy.
## Available Controls
### Strict Mode
**Enabled/Disabled** | Default: enabled
If enabled, users will not be able to enter yolo mode.
### Extensions
**Enabled/Disabled** | Default: disabled
If disabled, users will not be able to use or install extensions. See
[Extensions](../extensions/index.md) for more details.
### MCP
#### Enabled/Disabled
**Enabled/Disabled** | Default: disabled
If disabled, users will not be able to use MCP servers. See
[MCP Server Integration](../tools/mcp-server.md) for more details.
#### MCP Servers (preview)
**Default**: empty
Allows administrators to define an explicit allowlist of MCP servers. This
guarantees that users can only connect to trusted MCP servers defined by the
organization.
**Allowlist Format:**
```json
{
"mcpServers": {
"external-provider": {
"url": "https://api.mcp-provider.com",
"type": "sse",
"trust": true,
"includeTools": ["toolA", "toolB"],
"excludeTools": []
},
"internal-corp-tool": {
"url": "https://mcp.internal-tool.corp",
"type": "http",
"includeTools": [],
"excludeTools": ["adminTool"]
}
}
}
```
**Supported Fields:**
- `url`: (Required) The full URL of the MCP server endpoint.
- `type`: (Required) The connection type (e.g., `sse` or `http`).
- `trust`: (Optional) If set to `true`, the server is trusted and tool execution
will not require user approval.
- `includeTools`: (Optional) An explicit list of tool names to allow. If
specified, only these tools will be available.
- `excludeTools`: (Optional) A list of tool names to hide. These tools will be
blocked.
**Client Enforcement Logic:**
- **Empty Allowlist**: If the admin allowlist is empty, the client uses the
users local configuration as is (unless the MCP toggle above is disabled).
- **Active Allowlist**: If the allowlist contains one or more servers, **all
locally configured servers not present in the allowlist are ignored**.
- **Configuration Merging**: For a server to be active, it must exist in
**both** the admin allowlist and the users local configuration (matched by
name). The client merges these definitions as follows:
- **Override Fields**: The `url`, `type`, & `trust` are always taken from the
admin allowlist, overriding any local values.
- **Tools Filtering**: If `includeTools` or `excludeTools` are defined in the
allowlist, the admins rules are used exclusively. If both are undefined in
the admin allowlist, the client falls back to the users local tool
settings.
- **Cleared Fields**: To ensure security and consistency, the client
automatically clears local execution fields (`command`, `args`, `env`,
`cwd`, `httpUrl`, `tcp`). This prevents users from overriding the connection
method.
- **Other Fields**: All other MCP fields are pulled from the users local
configuration.
- **Missing Allowlisted Servers**: If a server appears in the admin allowlist
but is missing from the local configuration, it will not be initialized. This
ensures users maintain final control over which permitted servers are actually
active in their environment.
### Unmanaged Capabilities
**Enabled/Disabled** | Default: disabled
If disabled, users will not be able to use certain features. Currently, this
control disables Agent Skills. See [Agent Skills](../cli/skills.md) for more
details.
+80
View File
@@ -0,0 +1,80 @@
# 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.
+1 -204
View File
@@ -18,208 +18,6 @@ on GitHub.
| [Preview](preview.md) | Experimental features ready for early feedback. |
| [Stable](latest.md) | Stable, recommended for general use. |
## Announcements: v0.31.0 - 2026-02-27
- **Gemini 3.1 Pro Preview:** Gemini CLI now supports the new Gemini 3.1 Pro
Preview model
([#19676](https://github.com/google-gemini/gemini-cli/pull/19676) by
@sehoon38).
- **Experimental Browser Agent:** We've introduced a new experimental browser
agent to interact with web pages
([#19284](https://github.com/google-gemini/gemini-cli/pull/19284) by
@gsquared94).
- **Policy Engine Updates:** The policy engine now supports project-level
policies, MCP server wildcards, and tool annotation matching
([#18682](https://github.com/google-gemini/gemini-cli/pull/18682) by
@Abhijit-2592,
[#20024](https://github.com/google-gemini/gemini-cli/pull/20024) by @jerop).
- **Web Fetch Improvements:** We've implemented an experimental direct web fetch
feature and added rate limiting to mitigate DDoS risks
([#19557](https://github.com/google-gemini/gemini-cli/pull/19557) by @mbleigh,
[#19567](https://github.com/google-gemini/gemini-cli/pull/19567) by
@mattKorwel).
## Announcements: v0.30.0 - 2026-02-25
- **SDK & Custom Skills:** Introduced the initial SDK package, enabling dynamic
system instructions, `SessionContext` for SDK tool calls, and support for
custom skills
([#18861](https://github.com/google-gemini/gemini-cli/pull/18861) by
@mbleigh).
- **Policy Engine Enhancements:** Added a new `--policy` flag for user-defined
policies, introduced strict seatbelt profiles, and deprecated
`--allowed-tools` in favor of the policy engine
([#18500](https://github.com/google-gemini/gemini-cli/pull/18500) by
@allenhutchison).
- **UI & Themes:** Added a generic searchable list for settings and extensions,
new Solarized themes, text wrapping for markdown tables, and a clean UI toggle
prototype ([#19064](https://github.com/google-gemini/gemini-cli/pull/19064) by
@rmedranollamas).
- **Vim & Terminal Interaction:** Improved Vim support to feel more complete and
added support for Ctrl-Z terminal suspension
([#18755](https://github.com/google-gemini/gemini-cli/pull/18755) by
@ppgranger, [#18931](https://github.com/google-gemini/gemini-cli/pull/18931)
by @scidomino).
## Announcements: v0.29.0 - 2026-02-17
- **Plan Mode:** A new comprehensive planning capability with `/plan`,
`enter_plan_mode` tool, and dedicated documentation
([#17698](https://github.com/google-gemini/gemini-cli/pull/17698) by @Adib234,
[#18324](https://github.com/google-gemini/gemini-cli/pull/18324) by @jerop).
- **Gemini 3 Default:** We've removed the preview flag and enabled Gemini 3 by
default for all users
([#18414](https://github.com/google-gemini/gemini-cli/pull/18414) by
@sehoon38).
- **Extension Exploration:** New UI and settings to explore and manage
extensions more easily
([#18686](https://github.com/google-gemini/gemini-cli/pull/18686) by
@sripasg).
- **Admin Control:** Administrators can now allowlist specific MCP server
configurations
([#18311](https://github.com/google-gemini/gemini-cli/pull/18311) by
@skeshive).
## Announcements: v0.28.0 - 2026-02-10
- **Slash Command:** We've added a new `/prompt-suggest` slash command to help
you generate prompt suggestions
([#17264](https://github.com/google-gemini/gemini-cli/pull/17264) by
@NTaylorMullen).
- **IDE Support:** Gemini CLI now supports the Positron IDE
([#15047](https://github.com/google-gemini/gemini-cli/pull/15047) by
@kapsner).
- **Customization:** You can now use custom themes in extensions, and we've
implemented automatic theme switching based on your terminal's background
([#17327](https://github.com/google-gemini/gemini-cli/pull/17327) by
@spencer426, [#17976](https://github.com/google-gemini/gemini-cli/pull/17976)
by @Abhijit-2592).
- **Authentication:** We've added interactive and non-interactive consent for
OAuth, and you can now include your auth method in bug reports
([#17699](https://github.com/google-gemini/gemini-cli/pull/17699) by
@ehedlund, [#17569](https://github.com/google-gemini/gemini-cli/pull/17569) by
@erikus).
## Announcements: v0.27.0 - 2026-02-03
- **Event-Driven Architecture:** The CLI now uses a new event-driven scheduler
for tool execution, resulting in a more responsive and performant experience
([#17078](https://github.com/google-gemini/gemini-cli/pull/17078) by
@abhipatel12).
- **Enhanced User Experience:** This release includes queued tool confirmations,
and expandable large text pastes for a smoother workflow.
- **New `/rewind` Command:** Easily navigate your session history with the new
`/rewind` command
([#15720](https://github.com/google-gemini/gemini-cli/pull/15720) by
@Adib234).
- **Linux Clipboard Support:** You can now paste images on Linux with Wayland
and X11 ([#17144](https://github.com/google-gemini/gemini-cli/pull/17144) by
@devr0306).
## Announcements: v0.26.0 - 2026-01-27
- **Agents and Skills:** We've introduced a new `skill-creator` skill
([#16394](https://github.com/google-gemini/gemini-cli/pull/16394) by
@NTaylorMullen), enabled agent skills by default, and added a generalist agent
to improve task routing
([#16638](https://github.com/google-gemini/gemini-cli/pull/16638) by
@joshualitt).
- **UI/UX Improvements:** You can now "Rewind" through your conversation history
([#15717](https://github.com/google-gemini/gemini-cli/pull/15717) by @Adib234)
and use a new `/introspect` command for debugging.
- **Core and Scheduler Refactoring:** The core scheduler has been significantly
refactored to improve performance and reliability
([#16895](https://github.com/google-gemini/gemini-cli/pull/16895) by
@abhipatel12), and numerous performance and stability fixes have been
included.
## Announcements: v0.25.0 - 2026-01-20
- **Skills and Agents Improvements:** We've enhanced the `activate_skill` tool,
added a new `pr-creator` skill
([#16232](https://github.com/google-gemini/gemini-cli/pull/16232) by
[@NTaylorMullen](https://github.com/NTaylorMullen)), enabled skills by
default, improved the `cli_help` agent
([#16100](https://github.com/google-gemini/gemini-cli/pull/16100) by
[@scidomino](https://github.com/scidomino)), and added a new `/agents refresh`
command ([#16204](https://github.com/google-gemini/gemini-cli/pull/16204) by
[@joshualitt](https://github.com/joshualitt)).
- **UI/UX Refinements:** You'll notice more transparent feedback for skills
([#15954](https://github.com/google-gemini/gemini-cli/pull/15954) by
[@NTaylorMullen](https://github.com/NTaylorMullen)), the ability to switch
focus between the shell and input with Tab
([#14332](https://github.com/google-gemini/gemini-cli/pull/14332) by
[@jacob314](https://github.com/jacob314)), and dynamic terminal tab titles
([#16378](https://github.com/google-gemini/gemini-cli/pull/16378) by
[@NTaylorMullen](https://github.com/NTaylorMullen)).
- **Core Functionality & Performance:** This release includes support for
built-in agent skills
([#16045](https://github.com/google-gemini/gemini-cli/pull/16045) by
[@NTaylorMullen](https://github.com/NTaylorMullen)), refined Gemini 3 system
instructions ([#16139](https://github.com/google-gemini/gemini-cli/pull/16139)
by [@NTaylorMullen](https://github.com/NTaylorMullen)), caching for ignore
instances to improve performance
([#16185](https://github.com/google-gemini/gemini-cli/pull/16185) by
[@EricRahm](https://github.com/EricRahm)), and enhanced retry mechanisms
([#16489](https://github.com/google-gemini/gemini-cli/pull/16489) by
[@sehoon38](https://github.com/sehoon38)).
- **Bug Fixes and Stability:** We've squashed numerous bugs across the CLI,
core, and workflows, addressing issues with subagent delegation, unicode
character crashes, and sticky header regressions.
## Announcements: v0.24.0 - 2026-01-14
- **Agent Skills:** We've introduced significant advancements in Agent Skills.
This includes initial documentation and tutorials to help you get started,
alongside enhanced support for remote agents, allowing for more distributed
and powerful automation within Gemini CLI.
([#15869](https://github.com/google-gemini/gemini-cli/pull/15869) by
[@NTaylorMullen](https://github.com/NTaylorMullen)),
([#16013](https://github.com/google-gemini/gemini-cli/pull/16013) by
[@adamweidman](https://github.com/adamweidman))
- **Improved UI/UX:** The user interface has received several updates, featuring
visual indicators for hook execution, a more refined display for settings, and
the ability to use the Tab key to effortlessly switch focus between the shell
and input areas.
([#15408](https://github.com/google-gemini/gemini-cli/pull/15408) by
[@abhipatel12](https://github.com/abhipatel12)),
([#14332](https://github.com/google-gemini/gemini-cli/pull/14332) by
[@galz10](https://github.com/galz10))
- **Enhanced Security:** Security has been a major focus, with default folder
trust now set to untrusted for increased safety. The Policy Engine has been
improved to allow specific modes in user and administrator policies, and
granular allowlisting for shell commands has been implemented, providing finer
control over tool execution.
([#15943](https://github.com/google-gemini/gemini-cli/pull/15943) by
[@galz10](https://github.com/galz10)),
([#15977](https://github.com/google-gemini/gemini-cli/pull/15977) by
[@NTaylorMullen](https://github.com/NTaylorMullen))
- **Core Functionality:** This release includes a mandatory MessageBus
injection, marking Phase 3 of a hard migration to a more robust internal
communication system. We've also added support for built-in skills with the
CLI itself, and enhanced model routing to effectively utilize subagents.
([#15776](https://github.com/google-gemini/gemini-cli/pull/15776) by
[@abhipatel12](https://github.com/abhipatel12)),
([#16300](https://github.com/google-gemini/gemini-cli/pull/16300) by
[@NTaylorMullen](https://github.com/NTaylorMullen))
- **Terminal Features:** Terminal interactions are more seamless with new
features like OSC 52 paste support, along with fixes for Windows clipboard
paste issues and general improvements to pasting in Windows terminals.
([#15336](https://github.com/google-gemini/gemini-cli/pull/15336) by
[@scidomino](https://github.com/scidomino)),
([#15932](https://github.com/google-gemini/gemini-cli/pull/15932) by
[@scidomino](https://github.com/scidomino))
- **New Commands:** To manage the new features, we've added several new
commands: `/agents refresh` to update agent configurations, `/skills reload`
to refresh skill definitions, and `/skills install/uninstall` for easier
management of your Agent Skills.
([#16204](https://github.com/google-gemini/gemini-cli/pull/16204) by
[@NTaylorMullen](https://github.com/NTaylorMullen)),
([#15865](https://github.com/google-gemini/gemini-cli/pull/15865) by
[@NTaylorMullen](https://github.com/NTaylorMullen)),
([#16377](https://github.com/google-gemini/gemini-cli/pull/16377) by
[@NTaylorMullen](https://github.com/NTaylorMullen))
## Announcements: v0.23.0 - 2026-01-07
- 🎉 **Experimental Agent Skills Support in Preview:** Gemini CLI now supports
@@ -338,8 +136,7 @@ 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](../reference/policy-engine.md) for more
information.
[policy engine documentation](../core/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
+150 -400
View File
@@ -1,6 +1,6 @@
# Latest stable release: v0.31.0
# Latest stable release: v0.23.0
Released: February 27, 2026
Released: January 6, 2026
For most users, our latest stable release is the recommended release. Install
the latest stable version with:
@@ -11,405 +11,155 @@ npm install -g @google/gemini-cli
## Highlights
- **Gemini 3.1 Pro Preview:** Gemini CLI now supports the new Gemini 3.1 Pro
Preview model.
- **Experimental Browser Agent:** We've introduced a new experimental browser
agent to directly interact with web pages and retrieve context.
- **Policy Engine Updates:** The policy engine has been expanded to support
project-level policies, MCP server wildcards, and tool annotation matching,
providing greater control over tool executions.
- **Web Fetch Enhancements:** A new experimental direct web fetch tool has been
implemented, alongside rate-limiting features for enhanced security.
- **Improved Plan Mode:** Plan Mode now includes support for custom storage
directories, automatic model switching, and summarizing work after execution.
- **Gemini CLI wrapped:** Run `npx gemini-wrapped` to visualize your usage
stats, top models, languages, and more!
- **Windows clipboard image support:** Windows users can now paste images
directly from their clipboard into the CLI using `Alt`+`V`.
([pr](https://github.com/google-gemini/gemini-cli/pull/13997) by
[@sgeraldes](https://github.com/sgeraldes))
- **Terminal background color detection:** Automatically optimizes your
terminal's background color to select compatible themes and provide
accessibility warnings.
([pr](https://github.com/google-gemini/gemini-cli/pull/15132) by
[@jacob314](https://github.com/jacob314))
- **Session logout:** Use the new `/logout` command to instantly clear
credentials and reset your authentication state for seamless account
switching. ([pr](https://github.com/google-gemini/gemini-cli/pull/13383) by
[@CN-Scars](https://github.com/CN-Scars))
## What's Changed
## What's changed
- Use ranged reads and limited searches and fuzzy editing improvements by
@gundermanc in
[#19240](https://github.com/google-gemini/gemini-cli/pull/19240)
- Fix bottom border color by @jacob314 in
[#19266](https://github.com/google-gemini/gemini-cli/pull/19266)
- Release note generator fix by @g-samroberts in
[#19363](https://github.com/google-gemini/gemini-cli/pull/19363)
- test(evals): add behavioral tests for tool output masking by @NTaylorMullen in
[#19172](https://github.com/google-gemini/gemini-cli/pull/19172)
- docs: clarify preflight instructions in GEMINI.md by @NTaylorMullen in
[#19377](https://github.com/google-gemini/gemini-cli/pull/19377)
- feat(cli): add gemini --resume hint on exit by @Mag1ck in
[#16285](https://github.com/google-gemini/gemini-cli/pull/16285)
- fix: optimize height calculations for ask_user dialog by @jackwotherspoon in
[#19017](https://github.com/google-gemini/gemini-cli/pull/19017)
- feat(cli): add Alt+D for forward word deletion by @scidomino in
[#19300](https://github.com/google-gemini/gemini-cli/pull/19300)
- Disable failing eval test by @chrstnb in
[#19455](https://github.com/google-gemini/gemini-cli/pull/19455)
- fix(cli): support legacy onConfirm callback in ToolActionsContext by
@SandyTao520 in
[#19369](https://github.com/google-gemini/gemini-cli/pull/19369)
- chore(deps): bump tar from 7.5.7 to 7.5.8 by @.github/dependabot.yml[bot] in
[#19367](https://github.com/google-gemini/gemini-cli/pull/19367)
- fix(plan): allow safe fallback when experiment setting for plan is not enabled
but approval mode at startup is plan by @Adib234 in
[#19439](https://github.com/google-gemini/gemini-cli/pull/19439)
- Add explicit color-convert dependency by @chrstnb in
[#19460](https://github.com/google-gemini/gemini-cli/pull/19460)
- feat(devtools): migrate devtools package into monorepo by @SandyTao520 in
[#18936](https://github.com/google-gemini/gemini-cli/pull/18936)
- fix(core): clarify plan mode constraints and exit mechanism by @jerop in
[#19438](https://github.com/google-gemini/gemini-cli/pull/19438)
- feat(cli): add macOS run-event notifications (interactive only) by
@LyalinDotCom in
[#19056](https://github.com/google-gemini/gemini-cli/pull/19056)
- Changelog for v0.29.0 by @gemini-cli-robot in
[#19361](https://github.com/google-gemini/gemini-cli/pull/19361)
- fix(ui): preventing empty history items from being added by @devr0306 in
[#19014](https://github.com/google-gemini/gemini-cli/pull/19014)
- Changelog for v0.30.0-preview.0 by @gemini-cli-robot in
[#19364](https://github.com/google-gemini/gemini-cli/pull/19364)
- feat(core): add support for MCP progress updates by @NTaylorMullen in
[#19046](https://github.com/google-gemini/gemini-cli/pull/19046)
- fix(core): ensure directory exists before writing conversation file by
@godwiniheuwa in
[#18429](https://github.com/google-gemini/gemini-cli/pull/18429)
- fix(ui): move margin from top to bottom in ToolGroupMessage by @imadraude in
[#17198](https://github.com/google-gemini/gemini-cli/pull/17198)
- fix(cli): treat unknown slash commands as regular input instead of showing
error by @skyvanguard in
[#17393](https://github.com/google-gemini/gemini-cli/pull/17393)
- feat(core): experimental in-progress steering hints (2 of 2) by @joshualitt in
[#19307](https://github.com/google-gemini/gemini-cli/pull/19307)
- docs(plan): add documentation for plan mode command by @Adib234 in
[#19467](https://github.com/google-gemini/gemini-cli/pull/19467)
- fix(core): ripgrep fails when pattern looks like ripgrep flag by @syvb in
[#18858](https://github.com/google-gemini/gemini-cli/pull/18858)
- fix(cli): disable auto-completion on Shift+Tab to preserve mode cycling by
@NTaylorMullen in
[#19451](https://github.com/google-gemini/gemini-cli/pull/19451)
- use issuer instead of authorization_endpoint for oauth discovery by
@garrettsparks in
[#17332](https://github.com/google-gemini/gemini-cli/pull/17332)
- feat(cli): include `/dir add` directories in @ autocomplete suggestions by
@jasmeetsb in [#19246](https://github.com/google-gemini/gemini-cli/pull/19246)
- feat(admin): Admin settings should only apply if adminControlsApplicable =
true and fetch errors should be fatal by @skeshive in
[#19453](https://github.com/google-gemini/gemini-cli/pull/19453)
- Format strict-development-rules command by @g-samroberts in
[#19484](https://github.com/google-gemini/gemini-cli/pull/19484)
- feat(core): centralize compatibility checks and add TrueColor detection by
@spencer426 in
[#19478](https://github.com/google-gemini/gemini-cli/pull/19478)
- Remove unused files and update index and sidebar. by @g-samroberts in
[#19479](https://github.com/google-gemini/gemini-cli/pull/19479)
- Migrate core render util to use xterm.js as part of the rendering loop. by
@jacob314 in [#19044](https://github.com/google-gemini/gemini-cli/pull/19044)
- Changelog for v0.30.0-preview.1 by @gemini-cli-robot in
[#19496](https://github.com/google-gemini/gemini-cli/pull/19496)
- build: replace deprecated built-in punycode with userland package by @jacob314
in [#19502](https://github.com/google-gemini/gemini-cli/pull/19502)
- Speculative fixes to try to fix react error. by @jacob314 in
[#19508](https://github.com/google-gemini/gemini-cli/pull/19508)
- fix spacing by @jacob314 in
[#19494](https://github.com/google-gemini/gemini-cli/pull/19494)
- fix(core): ensure user rejections update tool outcome for telemetry by
@abhiasap in [#18982](https://github.com/google-gemini/gemini-cli/pull/18982)
- fix(acp): Initialize config (#18897) by @Mervap in
[#18898](https://github.com/google-gemini/gemini-cli/pull/18898)
- fix(core): add error logging for IDE fetch failures by @yuvrajangadsingh in
[#17981](https://github.com/google-gemini/gemini-cli/pull/17981)
- feat(acp): support set_mode interface (#18890) by @Mervap in
[#18891](https://github.com/google-gemini/gemini-cli/pull/18891)
- fix(core): robust workspace-based IDE connection discovery by @ehedlund in
[#18443](https://github.com/google-gemini/gemini-cli/pull/18443)
- Deflake windows tests. by @jacob314 in
[#19511](https://github.com/google-gemini/gemini-cli/pull/19511)
- Fix: Avoid tool confirmation timeout when no UI listeners are present by
@pdHaku0 in [#17955](https://github.com/google-gemini/gemini-cli/pull/17955)
- format md file by @scidomino in
[#19474](https://github.com/google-gemini/gemini-cli/pull/19474)
- feat(cli): add experimental.useOSC52Copy setting by @scidomino in
[#19488](https://github.com/google-gemini/gemini-cli/pull/19488)
- feat(cli): replace loading phrases boolean with enum setting by @LyalinDotCom
in [#19347](https://github.com/google-gemini/gemini-cli/pull/19347)
- Update skill to adjust for generated results. by @g-samroberts in
[#19500](https://github.com/google-gemini/gemini-cli/pull/19500)
- Fix message too large issue. by @gundermanc in
[#19499](https://github.com/google-gemini/gemini-cli/pull/19499)
- fix(core): prevent duplicate tool approval entries in auto-saved.toml by
@Abhijit-2592 in
[#19487](https://github.com/google-gemini/gemini-cli/pull/19487)
- fix(core): resolve crash in ClearcutLogger when os.cpus() is empty by @Adib234
in [#19555](https://github.com/google-gemini/gemini-cli/pull/19555)
- chore(core): improve encapsulation and remove unused exports by @adamfweidman
in [#19556](https://github.com/google-gemini/gemini-cli/pull/19556)
- Revert "Add generic searchable list to back settings and extensions (… by
@chrstnb in [#19434](https://github.com/google-gemini/gemini-cli/pull/19434)
- fix(core): improve error type extraction for telemetry by @yunaseoul in
[#19565](https://github.com/google-gemini/gemini-cli/pull/19565)
- fix: remove extra padding in Composer by @jackwotherspoon in
[#19529](https://github.com/google-gemini/gemini-cli/pull/19529)
- feat(plan): support configuring custom plans storage directory by @jerop in
[#19577](https://github.com/google-gemini/gemini-cli/pull/19577)
- Migrate files to resource or references folder. by @g-samroberts in
[#19503](https://github.com/google-gemini/gemini-cli/pull/19503)
- feat(policy): implement project-level policy support by @Abhijit-2592 in
[#18682](https://github.com/google-gemini/gemini-cli/pull/18682)
- feat(core): Implement parallel FC for read only tools. by @joshualitt in
[#18791](https://github.com/google-gemini/gemini-cli/pull/18791)
- chore(skills): adds pr-address-comments skill to work on PR feedback by
@mbleigh in [#19576](https://github.com/google-gemini/gemini-cli/pull/19576)
- refactor(sdk): introduce session-based architecture by @mbleigh in
[#19180](https://github.com/google-gemini/gemini-cli/pull/19180)
- fix(ci): add fallback JSON extraction to issue triage workflow by @bdmorgan in
[#19593](https://github.com/google-gemini/gemini-cli/pull/19593)
- feat(core): refine Edit and WriteFile tool schemas for Gemini 3 by
@SandyTao520 in
[#19476](https://github.com/google-gemini/gemini-cli/pull/19476)
- Changelog for v0.30.0-preview.3 by @gemini-cli-robot in
[#19585](https://github.com/google-gemini/gemini-cli/pull/19585)
- fix(plan): exclude EnterPlanMode tool from YOLO mode by @Adib234 in
[#19570](https://github.com/google-gemini/gemini-cli/pull/19570)
- chore: resolve build warnings and update dependencies by @mattKorwel in
[#18880](https://github.com/google-gemini/gemini-cli/pull/18880)
- feat(ui): add source indicators to slash commands by @ehedlund in
[#18839](https://github.com/google-gemini/gemini-cli/pull/18839)
- docs: refine Plan Mode documentation structure and workflow by @jerop in
[#19644](https://github.com/google-gemini/gemini-cli/pull/19644)
- Docs: Update release information regarding Gemini 3.1 by @jkcinouye in
[#19568](https://github.com/google-gemini/gemini-cli/pull/19568)
- fix(security): rate limit web_fetch tool to mitigate DDoS via prompt injection
by @mattKorwel in
[#19567](https://github.com/google-gemini/gemini-cli/pull/19567)
- Add initial implementation of /extensions explore command by @chrstnb in
[#19029](https://github.com/google-gemini/gemini-cli/pull/19029)
- fix: use discoverOAuthFromWWWAuthenticate for reactive OAuth flow (#18760) by
@maximus12793 in
[#19038](https://github.com/google-gemini/gemini-cli/pull/19038)
- Search updates by @alisa-alisa in
[#19482](https://github.com/google-gemini/gemini-cli/pull/19482)
- feat(cli): add support for numpad SS3 sequences by @scidomino in
[#19659](https://github.com/google-gemini/gemini-cli/pull/19659)
- feat(cli): enhance folder trust with configuration discovery and security
warnings by @galz10 in
[#19492](https://github.com/google-gemini/gemini-cli/pull/19492)
- feat(ui): improve startup warnings UX with dismissal and show-count limits by
@spencer426 in
[#19584](https://github.com/google-gemini/gemini-cli/pull/19584)
- feat(a2a): Add API key authentication provider by @adamfweidman in
[#19548](https://github.com/google-gemini/gemini-cli/pull/19548)
- Send accepted/removed lines with ACCEPT_FILE telemetry. by @gundermanc in
[#19670](https://github.com/google-gemini/gemini-cli/pull/19670)
- feat(models): support Gemini 3.1 Pro Preview and fixes by @sehoon38 in
[#19676](https://github.com/google-gemini/gemini-cli/pull/19676)
- feat(plan): enforce read-only constraints in Plan Mode by @mattKorwel in
[#19433](https://github.com/google-gemini/gemini-cli/pull/19433)
- fix(cli): allow perfect match @scripts/test-windows-paths.js completions to
submit on Enter by @spencer426 in
[#19562](https://github.com/google-gemini/gemini-cli/pull/19562)
- fix(core): treat 503 Service Unavailable as retryable quota error by @sehoon38
in [#19642](https://github.com/google-gemini/gemini-cli/pull/19642)
- Update sidebar.json for to allow top nav tabs. by @g-samroberts in
[#19595](https://github.com/google-gemini/gemini-cli/pull/19595)
- security: strip deceptive Unicode characters from terminal output by @ehedlund
in [#19026](https://github.com/google-gemini/gemini-cli/pull/19026)
- Fixes 'input.on' is not a function error in Gemini CLI by @gundermanc in
[#19691](https://github.com/google-gemini/gemini-cli/pull/19691)
- Revert "feat(ui): add source indicators to slash commands" by @ehedlund in
[#19695](https://github.com/google-gemini/gemini-cli/pull/19695)
- security: implement deceptive URL detection and disclosure in tool
confirmations by @ehedlund in
[#19288](https://github.com/google-gemini/gemini-cli/pull/19288)
- fix(core): restore auth consent in headless mode and add unit tests by
@ehedlund in [#19689](https://github.com/google-gemini/gemini-cli/pull/19689)
- Fix unsafe assertions in code_assist folder. by @gundermanc in
[#19706](https://github.com/google-gemini/gemini-cli/pull/19706)
- feat(cli): make JetBrains warning more specific by @jacob314 in
[#19687](https://github.com/google-gemini/gemini-cli/pull/19687)
- fix(cli): extensions dialog UX polish by @jacob314 in
[#19685](https://github.com/google-gemini/gemini-cli/pull/19685)
- fix(cli): use getDisplayString for manual model selection in dialog by
@sehoon38 in [#19726](https://github.com/google-gemini/gemini-cli/pull/19726)
- feat(policy): repurpose "Always Allow" persistence to workspace level by
@Abhijit-2592 in
[#19707](https://github.com/google-gemini/gemini-cli/pull/19707)
- fix(cli): re-enable CLI banner by @sehoon38 in
[#19741](https://github.com/google-gemini/gemini-cli/pull/19741)
- Disallow and suppress unsafe assignment by @gundermanc in
[#19736](https://github.com/google-gemini/gemini-cli/pull/19736)
- feat(core): migrate read_file to 1-based start_line/end_line parameters by
@adamfweidman in
[#19526](https://github.com/google-gemini/gemini-cli/pull/19526)
- feat(cli): improve CTRL+O experience for both standard and alternate screen
buffer (ASB) modes by @jwhelangoog in
[#19010](https://github.com/google-gemini/gemini-cli/pull/19010)
- Utilize pipelining of grep_search -> read_file to eliminate turns by
@gundermanc in
[#19574](https://github.com/google-gemini/gemini-cli/pull/19574)
- refactor(core): remove unsafe type assertions in error utils (Phase 1.1) by
@mattKorwel in
[#19750](https://github.com/google-gemini/gemini-cli/pull/19750)
- Disallow unsafe returns. by @gundermanc in
[#19767](https://github.com/google-gemini/gemini-cli/pull/19767)
- fix(cli): filter subagent sessions from resume history by @abhipatel12 in
[#19698](https://github.com/google-gemini/gemini-cli/pull/19698)
- chore(lint): fix lint errors seen when running npm run lint by @abhipatel12 in
[#19844](https://github.com/google-gemini/gemini-cli/pull/19844)
- feat(core): remove unnecessary login verbiage from Code Assist auth by
@NTaylorMullen in
[#19861](https://github.com/google-gemini/gemini-cli/pull/19861)
- fix(plan): time share by approval mode dashboard reporting negative time
shares by @Adib234 in
[#19847](https://github.com/google-gemini/gemini-cli/pull/19847)
- fix(core): allow any preview model in quota access check by @bdmorgan in
[#19867](https://github.com/google-gemini/gemini-cli/pull/19867)
- fix(core): prevent omission placeholder deletions in replace/write_file by
@nsalerni in [#19870](https://github.com/google-gemini/gemini-cli/pull/19870)
- fix(core): add uniqueness guard to edit tool by @Shivangisharma4 in
[#19890](https://github.com/google-gemini/gemini-cli/pull/19890)
- refactor(config): remove enablePromptCompletion from settings by @sehoon38 in
[#19974](https://github.com/google-gemini/gemini-cli/pull/19974)
- refactor(core): move session conversion logic to core by @abhipatel12 in
[#19972](https://github.com/google-gemini/gemini-cli/pull/19972)
- Fix: Persist manual model selection on restart #19864 by @Nixxx19 in
[#19891](https://github.com/google-gemini/gemini-cli/pull/19891)
- fix(core): increase default retry attempts and add quota error backoff by
@sehoon38 in [#19949](https://github.com/google-gemini/gemini-cli/pull/19949)
- feat(core): add policy chain support for Gemini 3.1 by @sehoon38 in
[#19991](https://github.com/google-gemini/gemini-cli/pull/19991)
- Updates command reference and /stats command. by @g-samroberts in
[#19794](https://github.com/google-gemini/gemini-cli/pull/19794)
- Fix for silent failures in non-interactive mode by @owenofbrien in
[#19905](https://github.com/google-gemini/gemini-cli/pull/19905)
- fix(plan): allow plan mode writes on Windows and fix prompt paths by @Adib234
in [#19658](https://github.com/google-gemini/gemini-cli/pull/19658)
- fix(core): prevent OAuth server crash on unexpected requests by @reyyanxahmed
in [#19668](https://github.com/google-gemini/gemini-cli/pull/19668)
- feat: Map tool kinds to explicit ACP.ToolKind values and update test … by
@sripasg in [#19547](https://github.com/google-gemini/gemini-cli/pull/19547)
- chore: restrict gemini-automted-issue-triage to only allow echo by @galz10 in
[#20047](https://github.com/google-gemini/gemini-cli/pull/20047)
- Allow ask headers longer than 16 chars by @scidomino in
[#20041](https://github.com/google-gemini/gemini-cli/pull/20041)
- fix(core): prevent state corruption in McpClientManager during collis by @h30s
in [#19782](https://github.com/google-gemini/gemini-cli/pull/19782)
- fix(bundling): copy devtools package to bundle for runtime resolution by
@SandyTao520 in
[#19766](https://github.com/google-gemini/gemini-cli/pull/19766)
- feat(policy): Support MCP Server Wildcards in Policy Engine by @jerop in
[#20024](https://github.com/google-gemini/gemini-cli/pull/20024)
- docs(CONTRIBUTING): update React DevTools version to 6 by @mmgok in
[#20014](https://github.com/google-gemini/gemini-cli/pull/20014)
- feat(core): optimize tool descriptions and schemas for Gemini 3 by
@aishaneeshah in
[#19643](https://github.com/google-gemini/gemini-cli/pull/19643)
- feat(core): implement experimental direct web fetch by @mbleigh in
[#19557](https://github.com/google-gemini/gemini-cli/pull/19557)
- feat(core): replace expected_replacements with allow_multiple in replace tool
by @SandyTao520 in
[#20033](https://github.com/google-gemini/gemini-cli/pull/20033)
- fix(sandbox): harden image packaging integrity checks by @aviralgarg05 in
[#19552](https://github.com/google-gemini/gemini-cli/pull/19552)
- fix(core): allow environment variable expansion and explicit overrides for MCP
servers by @galz10 in
[#18837](https://github.com/google-gemini/gemini-cli/pull/18837)
- feat(policy): Implement Tool Annotation Matching in Policy Engine by @jerop in
[#20029](https://github.com/google-gemini/gemini-cli/pull/20029)
- fix(core): prevent utility calls from changing session active model by
@adamfweidman in
[#20035](https://github.com/google-gemini/gemini-cli/pull/20035)
- fix(cli): skip workspace policy loading when in home directory by
@Abhijit-2592 in
[#20054](https://github.com/google-gemini/gemini-cli/pull/20054)
- fix(scripts): Add Windows (win32/x64) support to lint.js by @ZafeerMahmood in
[#16193](https://github.com/google-gemini/gemini-cli/pull/16193)
- fix(a2a-server): Remove unsafe type assertions in agent by @Nixxx19 in
[#19723](https://github.com/google-gemini/gemini-cli/pull/19723)
- Fix: Handle corrupted token file gracefully when switching auth types (#19845)
by @Nixxx19 in
[#19850](https://github.com/google-gemini/gemini-cli/pull/19850)
- fix critical dep vulnerability by @scidomino in
[#20087](https://github.com/google-gemini/gemini-cli/pull/20087)
- Add new setting to configure maxRetries by @kevinjwang1 in
[#20064](https://github.com/google-gemini/gemini-cli/pull/20064)
- Stabilize tests. by @gundermanc in
[#20095](https://github.com/google-gemini/gemini-cli/pull/20095)
- make windows tests mandatory by @scidomino in
[#20096](https://github.com/google-gemini/gemini-cli/pull/20096)
- Add 3.1 pro preview to behavioral evals. by @gundermanc in
[#20088](https://github.com/google-gemini/gemini-cli/pull/20088)
- feat:PR-rate-limit by @JagjeevanAK in
[#19804](https://github.com/google-gemini/gemini-cli/pull/19804)
- feat(cli): allow expanding full details of MCP tool on approval by @y-okt in
[#19916](https://github.com/google-gemini/gemini-cli/pull/19916)
- feat(security): Introduce Conseca framework by @shrishabh in
[#13193](https://github.com/google-gemini/gemini-cli/pull/13193)
- fix(cli): Remove unsafe type assertions in activityLogger #19713 by @Nixxx19
in [#19745](https://github.com/google-gemini/gemini-cli/pull/19745)
- feat: implement AfterTool tail tool calls by @googlestrobe in
[#18486](https://github.com/google-gemini/gemini-cli/pull/18486)
- ci(actions): fix PR rate limiter excluding maintainers by @scidomino in
[#20117](https://github.com/google-gemini/gemini-cli/pull/20117)
- Shortcuts: Move SectionHeader title below top line and refine styling by
@keithguerin in
[#18721](https://github.com/google-gemini/gemini-cli/pull/18721)
- refactor(ui): Update and simplify use of gray colors in themes by @keithguerin
in [#20141](https://github.com/google-gemini/gemini-cli/pull/20141)
- fix punycode2 by @jacob314 in
[#20154](https://github.com/google-gemini/gemini-cli/pull/20154)
- feat(ide): add GEMINI_CLI_IDE_PID env var to override IDE process detection by
@kiryltech in [#15842](https://github.com/google-gemini/gemini-cli/pull/15842)
- feat(policy): Propagate Tool Annotations for MCP Servers by @jerop in
[#20083](https://github.com/google-gemini/gemini-cli/pull/20083)
- fix(a2a-server): pass allowedTools settings to core Config by @reyyanxahmed in
[#19680](https://github.com/google-gemini/gemini-cli/pull/19680)
- feat(mcp): add progress bar, throttling, and input validation for MCP tool
progress by @jasmeetsb in
[#19772](https://github.com/google-gemini/gemini-cli/pull/19772)
- feat(policy): centralize plan mode tool visibility in policy engine by @jerop
in [#20178](https://github.com/google-gemini/gemini-cli/pull/20178)
- feat(browser): implement experimental browser agent by @gsquared94 in
[#19284](https://github.com/google-gemini/gemini-cli/pull/19284)
- feat(plan): summarize work after executing a plan by @jerop in
[#19432](https://github.com/google-gemini/gemini-cli/pull/19432)
- fix(core): create new McpClient on restart to apply updated config by @h30s in
[#20126](https://github.com/google-gemini/gemini-cli/pull/20126)
- Changelog for v0.30.0-preview.5 by @gemini-cli-robot in
[#20107](https://github.com/google-gemini/gemini-cli/pull/20107)
- Update packages. by @jacob314 in
[#20152](https://github.com/google-gemini/gemini-cli/pull/20152)
- Fix extension env dir loading issue by @chrstnb in
[#20198](https://github.com/google-gemini/gemini-cli/pull/20198)
- restrict /assign to help-wanted issues by @scidomino in
[#20207](https://github.com/google-gemini/gemini-cli/pull/20207)
- feat(plan): inject message when user manually exits Plan mode by @jerop in
[#20203](https://github.com/google-gemini/gemini-cli/pull/20203)
- feat(extensions): enforce folder trust for local extension install by @galz10
in [#19703](https://github.com/google-gemini/gemini-cli/pull/19703)
- feat(hooks): adds support for RuntimeHook functions. by @mbleigh in
[#19598](https://github.com/google-gemini/gemini-cli/pull/19598)
- Docs: Update UI links. by @jkcinouye in
[#20224](https://github.com/google-gemini/gemini-cli/pull/20224)
- feat: prompt users to run /terminal-setup with yes/no by @ishaanxgupta in
[#16235](https://github.com/google-gemini/gemini-cli/pull/16235)
- fix: additional high vulnerabilities (minimatch, cross-spawn) by @adamfweidman
in [#20221](https://github.com/google-gemini/gemini-cli/pull/20221)
- feat(telemetry): Add context breakdown to API response event by @SandyTao520
in [#19699](https://github.com/google-gemini/gemini-cli/pull/19699)
- Docs: Add nested sub-folders for related topics by @g-samroberts in
[#20235](https://github.com/google-gemini/gemini-cli/pull/20235)
- feat(plan): support automatic model switching for Plan Mode by @jerop in
[#20240](https://github.com/google-gemini/gemini-cli/pull/20240)
- fix(patch): cherry-pick 58df1c6 to release/v0.31.0-preview.0-pr-20374 to patch
version v0.31.0-preview.0 and create version 0.31.0-preview.1 by
@gemini-cli-robot in
[#20568](https://github.com/google-gemini/gemini-cli/pull/20568)
- fix(patch): cherry-pick ea48bd9 to release/v0.31.0-preview.1-pr-20577
- Code assist service metrics. by @gundermanc in
https://github.com/google-gemini/gemini-cli/pull/15024
- chore/release: bump version to 0.21.0-nightly.20251216.bb0c0d8ee by
@gemini-cli-robot in https://github.com/google-gemini/gemini-cli/pull/15121
- Docs by @Roaimkhan in https://github.com/google-gemini/gemini-cli/pull/15103
- Use official ACP SDK and support HTTP/SSE based MCP servers by @SteffenDE in
https://github.com/google-gemini/gemini-cli/pull/13856
- Remove foreground for themes other than shades of purple and holiday. by
@jacob314 in https://github.com/google-gemini/gemini-cli/pull/14606
- chore: remove repo specific tips by @jackwotherspoon in
https://github.com/google-gemini/gemini-cli/pull/15164
- chore: remove user query from footer in debug mode by @jackwotherspoon in
https://github.com/google-gemini/gemini-cli/pull/15169
- Disallow unnecessary awaits. by @gundermanc in
https://github.com/google-gemini/gemini-cli/pull/15172
- Add one to the padding in settings dialog to avoid flicker. by @jacob314 in
https://github.com/google-gemini/gemini-cli/pull/15173
- feat(core): introduce remote agent infrastructure and rename local executor by
@adamfweidman in https://github.com/google-gemini/gemini-cli/pull/15110
- feat(cli): Add `/auth logout` command to clear credentials and auth state by
@CN-Scars in https://github.com/google-gemini/gemini-cli/pull/13383
- (fix) Automated pr labeller by @DaanVersavel in
https://github.com/google-gemini/gemini-cli/pull/14885
- feat: launch Gemini 3 Flash in Gemini CLI ⚡️⚡️⚡️ by @scidomino in
https://github.com/google-gemini/gemini-cli/pull/15196
- Refactor: Migrate console.error in ripGrep.ts to debugLogger by @Adib234 in
https://github.com/google-gemini/gemini-cli/pull/15201
- chore: update a2a-js to 0.3.7 by @adamfweidman in
https://github.com/google-gemini/gemini-cli/pull/15197
- chore(core): remove redundant isModelAvailabilityServiceEnabled toggle and
clean up dead code by @adamfweidman in
https://github.com/google-gemini/gemini-cli/pull/15207
- feat(core): Late resolve `GenerateContentConfig`s and reduce mutation. by
@joshualitt in https://github.com/google-gemini/gemini-cli/pull/14920
- Respect previewFeatures value from the remote flag if undefined by @sehoon38
in https://github.com/google-gemini/gemini-cli/pull/15214
- feat(ui): add Windows clipboard image support and Alt+V paste workaround by
@jacob314 in https://github.com/google-gemini/gemini-cli/pull/15218
- chore(core): remove legacy fallback flags and migrate loop detection by
@adamfweidman in https://github.com/google-gemini/gemini-cli/pull/15213
- fix(ui): Prevent eager slash command completion hiding sibling commands by
@SandyTao520 in https://github.com/google-gemini/gemini-cli/pull/15224
- Docs: Update Changelog for Dec 17, 2025 by @jkcinouye in
https://github.com/google-gemini/gemini-cli/pull/15204
- Code Assist backend telemetry for user accept/reject of suggestions by
@gundermanc in https://github.com/google-gemini/gemini-cli/pull/15206
- fix(cli): correct initial history length handling for chat commands by
@SandyTao520 in https://github.com/google-gemini/gemini-cli/pull/15223
- chore/release: bump version to 0.21.0-nightly.20251218.739c02bd6 by
@gemini-cli-robot in https://github.com/google-gemini/gemini-cli/pull/15231
- Change detailed model stats to use a new shared Table class to resolve
robustness issues. by @jacob314 in
https://github.com/google-gemini/gemini-cli/pull/15208
- feat: add agent toml parser by @abhipatel12 in
https://github.com/google-gemini/gemini-cli/pull/15112
- Add core tool that adds all context from the core package. by @jacob314 in
https://github.com/google-gemini/gemini-cli/pull/15238
- (docs): Add reference section to hooks documentation by @abhipatel12 in
https://github.com/google-gemini/gemini-cli/pull/15159
- feat(hooks): add support for friendly names and descriptions by @abhipatel12
in https://github.com/google-gemini/gemini-cli/pull/15174
- feat: Detect background color by @jacob314 in
https://github.com/google-gemini/gemini-cli/pull/15132
- add 3.0 to allowed sensitive keywords by @scidomino in
https://github.com/google-gemini/gemini-cli/pull/15276
- feat: Pass additional environment variables to shell execution by @galz10 in
https://github.com/google-gemini/gemini-cli/pull/15160
- Remove unused code by @scidomino in
https://github.com/google-gemini/gemini-cli/pull/15290
- Handle all 429 as retryableQuotaError by @sehoon38 in
https://github.com/google-gemini/gemini-cli/pull/15288
- Remove unnecessary dependencies by @scidomino in
https://github.com/google-gemini/gemini-cli/pull/15291
- fix: prevent infinite loop in prompt completion on error by @galz10 in
https://github.com/google-gemini/gemini-cli/pull/14548
- fix(ui): show command suggestions even on perfect match and sort them by
@SandyTao520 in https://github.com/google-gemini/gemini-cli/pull/15287
- feat(hooks): reduce log verbosity and improve error reporting in UI by
@abhipatel12 in https://github.com/google-gemini/gemini-cli/pull/15297
- feat: simplify tool confirmation labels for better UX by @NTaylorMullen in
https://github.com/google-gemini/gemini-cli/pull/15296
- chore/release: bump version to 0.21.0-nightly.20251219.70696e364 by
@gemini-cli-robot in https://github.com/google-gemini/gemini-cli/pull/15301
- feat(core): Implement JIT context memory loading and UI sync by @SandyTao520
in https://github.com/google-gemini/gemini-cli/pull/14469
- feat(ui): Put "Allow for all future sessions" behind a setting off by default.
by @jacob314 in https://github.com/google-gemini/gemini-cli/pull/15322
- fix(cli):change the placeholder of input during the shell mode by
@JayadityaGit in https://github.com/google-gemini/gemini-cli/pull/15135
- Validate OAuth resource parameter matches MCP server URL by @galz10 in
https://github.com/google-gemini/gemini-cli/pull/15289
- docs(cli): add System Prompt Override (GEMINI_SYSTEM_MD) by @ashmod in
https://github.com/google-gemini/gemini-cli/pull/9515
- more robust command parsing logs by @scidomino in
https://github.com/google-gemini/gemini-cli/pull/15339
- Introspection agent demo by @scidomino in
https://github.com/google-gemini/gemini-cli/pull/15232
- fix(core): sanitize hook command expansion and prevent injection by
@SandyTao520 in https://github.com/google-gemini/gemini-cli/pull/15343
- fix(folder trust): add validation for trusted folder level by @adamfweidman in
https://github.com/google-gemini/gemini-cli/pull/12215
- fix(cli): fix right border overflow in trust dialogs by @galz10 in
https://github.com/google-gemini/gemini-cli/pull/15350
- fix(policy): fix bug where accepting-edits continued after it was turned off
by @jacob314 in https://github.com/google-gemini/gemini-cli/pull/15351
- fix: prevent infinite relaunch loop when --resume fails (#14941) by @Ying-xi
in https://github.com/google-gemini/gemini-cli/pull/14951
- chore/release: bump version to 0.21.0-nightly.20251220.41a1a3eed by
@gemini-cli-robot in https://github.com/google-gemini/gemini-cli/pull/15352
- feat(telemetry): add clearcut logging for hooks by @abhipatel12 in
https://github.com/google-gemini/gemini-cli/pull/15405
- fix(core): Add `.geminiignore` support to SearchText tool by @xyrolle in
https://github.com/google-gemini/gemini-cli/pull/13763
- fix(patch): cherry-pick 0843d9a to release/v0.23.0-preview.0-pr-15443 to patch
version v0.23.0-preview.0 and create version 0.23.0-preview.1 by
@gemini-cli-robot in https://github.com/google-gemini/gemini-cli/pull/15445
- fix(patch): cherry-pick 9cdb267 to release/v0.23.0-preview.1-pr-15494 to patch
version v0.23.0-preview.1 and create version 0.23.0-preview.2 by
@gemini-cli-robot in https://github.com/google-gemini/gemini-cli/pull/15592
- fix(patch): cherry-pick 37be162 to release/v0.23.0-preview.2-pr-15601 to patch
version v0.23.0-preview.2 and create version 0.23.0-preview.3 by
@gemini-cli-robot in https://github.com/google-gemini/gemini-cli/pull/15603
- fix(patch): cherry-pick 07e597d to release/v0.23.0-preview.3-pr-15684
[CONFLICTS] by @gemini-cli-robot in
[#20592](https://github.com/google-gemini/gemini-cli/pull/20592)
- fix(patch): cherry-pick 32e777f to release/v0.31.0-preview.2-pr-20531 to patch
version v0.31.0-preview.2 and create version 0.31.0-preview.3 by
@gemini-cli-robot in
[#20607](https://github.com/google-gemini/gemini-cli/pull/20607)
https://github.com/google-gemini/gemini-cli/pull/15734
- fix(patch): cherry-pick c31f053 to release/v0.23.0-preview.4-pr-16004 to patch
version v0.23.0-preview.4 and create version 0.23.0-preview.5 by
@gemini-cli-robot in https://github.com/google-gemini/gemini-cli/pull/16027
- fix(patch): cherry-pick 788bb04 to release/v0.23.0-preview.5-pr-15817
[CONFLICTS] by @gemini-cli-robot in
https://github.com/google-gemini/gemini-cli/pull/16038
**Full Changelog**:
https://github.com/google-gemini/gemini-cli/compare/v0.30.1...v0.31.0
**Full changelog**:
https://github.com/google-gemini/gemini-cli/compare/v0.22.5...v0.23.0
+211 -195
View File
@@ -1,6 +1,6 @@
# Preview release: v0.32.0-preview.0
# Preview release: Release v0.24.0-preview.0
Released: February 27, 2026
Released: January 6, 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).
@@ -11,198 +11,214 @@ To install the preview release:
npm install -g @google/gemini-cli@preview
```
## Highlights
## What's changed
- **Plan Mode Enhancements**: Significant updates to Plan Mode, including
support for modifying plans in external editors, adaptive workflows based on
task complexity, and new integration tests.
- **Agent and Core Engine Updates**: Enabled the generalist agent, introduced
`Kind.Agent` for sub-agent classification, implemented task tracking
foundation, and improved Agent-to-Agent (A2A) streaming and content
extraction.
- **CLI & User Experience**: Introduced interactive shell autocompletion, added
a new verbosity mode for cleaner error reporting, enabled parallel loading of
extensions, and improved UI hints and shortcut handling.
- **Billing and Security**: Implemented G1 AI credits overage flow with enhanced
billing telemetry, updated the authentication handshake to specification, and
added support for a policy engine in extensions.
- **Stability and Bug Fixes**: Addressed numerous issues including 100% CPU
consumption by orphaned processes, enhanced retry logic for Code Assist,
reduced intrusive MCP errors, and merged duplicate imports across packages.
- chore(core): refactor model resolution and cleanup fallback logic by
@adamfweidman in https://github.com/google-gemini/gemini-cli/pull/15228
- Add Folder Trust Support To Hooks by @sehoon38 in
https://github.com/google-gemini/gemini-cli/pull/15325
- Record timestamp with code assist metrics. by @gundermanc in
https://github.com/google-gemini/gemini-cli/pull/15439
- feat(policy): implement dynamic mode-aware policy evaluation by @abhipatel12
in https://github.com/google-gemini/gemini-cli/pull/15307
- fix(core): use debugLogger.debug for startup profiler logs by @NTaylorMullen
in https://github.com/google-gemini/gemini-cli/pull/15443
- feat(ui): Add security warning and improve layout for Hooks list by
@SandyTao520 in https://github.com/google-gemini/gemini-cli/pull/15440
- fix #15369, prevent crash on unhandled EIO error in readStdin cleanup by
@ElecTwix in https://github.com/google-gemini/gemini-cli/pull/15410
- chore: improve error messages for --resume by @jackwotherspoon in
https://github.com/google-gemini/gemini-cli/pull/15360
- chore: remove clipboard file by @jackwotherspoon in
https://github.com/google-gemini/gemini-cli/pull/15447
- Implemented unified secrets sanitization and env. redaction options by
@gundermanc in https://github.com/google-gemini/gemini-cli/pull/15348
- feat: automatic `/model` persistence across Gemini CLI sessions by @niyasrad
in https://github.com/google-gemini/gemini-cli/pull/13199
- refactor(core): remove deprecated permission aliases from BeforeToolHookOutput
by @StoyanD in https://github.com/google-gemini/gemini-cli/pull/14855
- fix: add missing `type` field to MCPServerConfig by @jackwotherspoon in
https://github.com/google-gemini/gemini-cli/pull/15465
- Make schema validation errors non-fatal by @jacob314 in
https://github.com/google-gemini/gemini-cli/pull/15487
- chore: limit MCP resources display to 10 by default by @jackwotherspoon in
https://github.com/google-gemini/gemini-cli/pull/15489
- Add experimental in-CLI extension install and uninstall subcommands by
@chrstnb in https://github.com/google-gemini/gemini-cli/pull/15178
- feat: Add A2A Client Manager and tests by @adamfweidman in
https://github.com/google-gemini/gemini-cli/pull/15485
- feat: terse transformations of image paths in text buffer by @psinha40898 in
https://github.com/google-gemini/gemini-cli/pull/4924
- Security: Project-level hook warnings by @sehoon38 in
https://github.com/google-gemini/gemini-cli/pull/15470
- Added modifyOtherKeys protocol support for tmux by @ved015 in
https://github.com/google-gemini/gemini-cli/pull/15524
- chore(core): fix comment typo by @Mapleeeeeeeeeee in
https://github.com/google-gemini/gemini-cli/pull/15558
- feat: Show snowfall animation for holiday theme by @sehoon38 in
https://github.com/google-gemini/gemini-cli/pull/15494
- do not persist the fallback model by @sehoon38 in
https://github.com/google-gemini/gemini-cli/pull/15483
- Resolve unhandled promise rejection in ide-client.ts by @Adib234 in
https://github.com/google-gemini/gemini-cli/pull/15587
- fix(core): handle checkIsRepo failure in GitService.initialize by
@Mapleeeeeeeeeee in https://github.com/google-gemini/gemini-cli/pull/15574
- fix(cli): add enableShellOutputEfficiency to settings schema by
@Mapleeeeeeeeeee in https://github.com/google-gemini/gemini-cli/pull/15560
- Manual nightly version bump to 0.24.0-nightly.20251226.546baf993 by @galz10 in
https://github.com/google-gemini/gemini-cli/pull/15594
- refactor(core): extract static concerns from CoreToolScheduler by @abhipatel12
in https://github.com/google-gemini/gemini-cli/pull/15589
- fix(core): enable granular shell command allowlisting in policy engine by
@abhipatel12 in https://github.com/google-gemini/gemini-cli/pull/15601
- chore/release: bump version to 0.24.0-nightly.20251227.37be16243 by
@gemini-cli-robot in https://github.com/google-gemini/gemini-cli/pull/15612
- refactor: deprecate legacy confirmation settings and enforce Policy Engine by
@abhipatel12 in https://github.com/google-gemini/gemini-cli/pull/15626
- Migrate console to coreEvents.emitFeedback or debugLogger by @Adib234 in
https://github.com/google-gemini/gemini-cli/pull/15219
- Exponential back-off retries for retryable error without a specified … by
@sehoon38 in https://github.com/google-gemini/gemini-cli/pull/15684
- feat(agents): add support for remote agents and multi-agent TOML files by
@adamfweidman in https://github.com/google-gemini/gemini-cli/pull/15437
- Update wittyPhrases.ts by @segyges in
https://github.com/google-gemini/gemini-cli/pull/15697
- refactor(auth): Refactor non-interactive mode auth validation & refresh by
@skeshive in https://github.com/google-gemini/gemini-cli/pull/15679
- Revert "Update wittyPhrases.ts (#15697)" by @abhipatel12 in
https://github.com/google-gemini/gemini-cli/pull/15719
- fix(hooks): deduplicate agent hooks and add cross-platform integration tests
by @abhipatel12 in https://github.com/google-gemini/gemini-cli/pull/15701
- Implement support for tool input modification by @gundermanc in
https://github.com/google-gemini/gemini-cli/pull/15492
- Add instructions to the extensions update info notification by @chrstnb in
https://github.com/google-gemini/gemini-cli/pull/14907
- Add extension settings info to /extensions list by @chrstnb in
https://github.com/google-gemini/gemini-cli/pull/14905
- Agent Skills: Implement Core Skill Infrastructure & Tiered Discovery by
@NTaylorMullen in https://github.com/google-gemini/gemini-cli/pull/15698
- chore: remove cot style comments by @abhipatel12 in
https://github.com/google-gemini/gemini-cli/pull/15735
- feat(agents): Add remote agents to agent registry by @sehoon38 in
https://github.com/google-gemini/gemini-cli/pull/15711
- feat(hooks): implement STOP_EXECUTION and enhance hook decision handling by
@SandyTao520 in https://github.com/google-gemini/gemini-cli/pull/15685
- Fix build issues caused by year-specific linter rule by @gundermanc in
https://github.com/google-gemini/gemini-cli/pull/15780
- fix(core): handle unhandled promise rejection in mcp-client-manager by
@kamja44 in https://github.com/google-gemini/gemini-cli/pull/14701
- log fallback mode by @sehoon38 in
https://github.com/google-gemini/gemini-cli/pull/15817
- Agent Skills: Implement Autonomous Activation Tool & Context Injection by
@NTaylorMullen in https://github.com/google-gemini/gemini-cli/pull/15725
- fix(core): improve shell command with redirection detection by @galz10 in
https://github.com/google-gemini/gemini-cli/pull/15683
- Add security docs by @abhipatel12 in
https://github.com/google-gemini/gemini-cli/pull/15739
- feat: add folder suggestions to `/dir add` command by @jackwotherspoon in
https://github.com/google-gemini/gemini-cli/pull/15724
- Agent Skills: Implement Agent Integration and System Prompt Awareness by
@NTaylorMullen in https://github.com/google-gemini/gemini-cli/pull/15728
- chore: cleanup old smart edit settings by @abhipatel12 in
https://github.com/google-gemini/gemini-cli/pull/15832
- Agent Skills: Status Bar Integration for Skill Counts by @NTaylorMullen in
https://github.com/google-gemini/gemini-cli/pull/15741
- fix(core): mock powershell output in shell-utils test by @galz10 in
https://github.com/google-gemini/gemini-cli/pull/15831
- Agent Skills: Unify Representation & Centralize Loading by @NTaylorMullen in
https://github.com/google-gemini/gemini-cli/pull/15833
- Unify shell security policy and remove legacy logic by @abhipatel12 in
https://github.com/google-gemini/gemini-cli/pull/15770
- feat(core): restore MessageBus optionality for soft migration (Phase 1) by
@abhipatel12 in https://github.com/google-gemini/gemini-cli/pull/15774
- feat(core): Standardize Tool and Agent Invocation constructors (Phase 2) by
@abhipatel12 in https://github.com/google-gemini/gemini-cli/pull/15775
- feat(core,cli): enforce mandatory MessageBus injection (Phase 3 Hard
Migration) by @abhipatel12 in
https://github.com/google-gemini/gemini-cli/pull/15776
- Agent Skills: Extension Support & Security Disclosure by @NTaylorMullen in
https://github.com/google-gemini/gemini-cli/pull/15834
- feat(hooks): implement granular stop and block behavior for agent hooks by
@SandyTao520 in https://github.com/google-gemini/gemini-cli/pull/15824
- Agent Skills: Add gemini skills CLI management command by @NTaylorMullen in
https://github.com/google-gemini/gemini-cli/pull/15837
- refactor: consolidate EditTool and SmartEditTool by @abhipatel12 in
https://github.com/google-gemini/gemini-cli/pull/15857
- fix(cli): mock fs.readdir in consent tests for Windows compatibility by
@NTaylorMullen in https://github.com/google-gemini/gemini-cli/pull/15904
- refactor(core): Extract and integrate ToolExecutor by @abhipatel12 in
https://github.com/google-gemini/gemini-cli/pull/15900
- Fix terminal hang when user exits browser without logging in by @gundermanc in
https://github.com/google-gemini/gemini-cli/pull/15748
- fix: avoid SDK warning by not accessing .text getter in logging by @ved015 in
https://github.com/google-gemini/gemini-cli/pull/15706
- Make default settings apply by @devr0306 in
https://github.com/google-gemini/gemini-cli/pull/15354
- chore: rename smart-edit to edit by @abhipatel12 in
https://github.com/google-gemini/gemini-cli/pull/15923
- Opt-in to persist model from /model by @sehoon38 in
https://github.com/google-gemini/gemini-cli/pull/15820
- fix: prevent /copy crash on Windows by skipping /dev/tty by @ManojINaik in
https://github.com/google-gemini/gemini-cli/pull/15657
- Support context injection via SessionStart hook. by @gundermanc in
https://github.com/google-gemini/gemini-cli/pull/15746
- Fix order of preflight by @scidomino in
https://github.com/google-gemini/gemini-cli/pull/15941
- Fix failing unit tests by @gundermanc in
https://github.com/google-gemini/gemini-cli/pull/15940
- fix(cli): resolve paste issue on Windows terminals. by @scidomino in
https://github.com/google-gemini/gemini-cli/pull/15932
- Agent Skills: Implement /skills reload by @NTaylorMullen in
https://github.com/google-gemini/gemini-cli/pull/15865
- Add setting to support OSC 52 paste by @scidomino in
https://github.com/google-gemini/gemini-cli/pull/15336
- remove manual string when displaying manual model in the footer by @sehoon38
in https://github.com/google-gemini/gemini-cli/pull/15967
- fix(core): use correct interactive check for system prompt by @ppergame in
https://github.com/google-gemini/gemini-cli/pull/15020
- Inform user of missing settings on extensions update by @chrstnb in
https://github.com/google-gemini/gemini-cli/pull/15944
- feat(policy): allow 'modes' in user and admin policies by @NTaylorMullen in
https://github.com/google-gemini/gemini-cli/pull/15977
- fix: default folder trust to untrusted for enhanced security by @galz10 in
https://github.com/google-gemini/gemini-cli/pull/15943
- Add description for each settings item in /settings by @sehoon38 in
https://github.com/google-gemini/gemini-cli/pull/15936
- Use GetOperation to poll for OnboardUser completion by @ishaanxgupta in
https://github.com/google-gemini/gemini-cli/pull/15827
- Agent Skills: Add skill directory to WorkspaceContext upon activation by
@NTaylorMullen in https://github.com/google-gemini/gemini-cli/pull/15870
- Fix settings command fallback by @chrstnb in
https://github.com/google-gemini/gemini-cli/pull/15926
- fix: writeTodo construction by @scidomino in
https://github.com/google-gemini/gemini-cli/pull/16014
- properly disable keyboard modes on exit by @scidomino in
https://github.com/google-gemini/gemini-cli/pull/16006
- Add workflow to label child issues for rollup by @bdmorgan in
https://github.com/google-gemini/gemini-cli/pull/16002
- feat(ui): add visual indicators for hook execution by @abhipatel12 in
https://github.com/google-gemini/gemini-cli/pull/15408
- fix: image token estimation by @jackwotherspoon in
https://github.com/google-gemini/gemini-cli/pull/16004
- feat(hooks): Add a hooks.enabled setting. by @joshualitt in
https://github.com/google-gemini/gemini-cli/pull/15933
- feat(admin): Introduce remote admin settings & implement
secureModeEnabled/mcpEnabled by @skeshive in
https://github.com/google-gemini/gemini-cli/pull/15935
- Remove trailing whitespace in yaml. by @joshualitt in
https://github.com/google-gemini/gemini-cli/pull/16036
- feat(agents): add support for remote agents by @adamfweidman in
https://github.com/google-gemini/gemini-cli/pull/16013
- fix: limit scheduled issue triage queries to prevent argument list too long
error by @jerop in https://github.com/google-gemini/gemini-cli/pull/16021
- ci(github-actions): triage all new issues automatically by @jerop in
https://github.com/google-gemini/gemini-cli/pull/16018
- Fix test. by @gundermanc in
https://github.com/google-gemini/gemini-cli/pull/16011
- fix: hide broken skills object from settings dialog by @korade-krushna in
https://github.com/google-gemini/gemini-cli/pull/15766
- Agent Skills: Initial Documentation & Tutorial by @NTaylorMullen in
https://github.com/google-gemini/gemini-cli/pull/15869
## What's Changed
- feat(plan): add integration tests for plan mode by @Adib234 in
[#20214](https://github.com/google-gemini/gemini-cli/pull/20214)
- fix(acp): update auth handshake to spec by @skeshive in
[#19725](https://github.com/google-gemini/gemini-cli/pull/19725)
- feat(core): implement robust A2A streaming reassembly and fix task continuity
by @adamfweidman in
[#20091](https://github.com/google-gemini/gemini-cli/pull/20091)
- feat(cli): load extensions in parallel by @scidomino in
[#20229](https://github.com/google-gemini/gemini-cli/pull/20229)
- Plumb the maxAttempts setting through Config args by @kevinjwang1 in
[#20239](https://github.com/google-gemini/gemini-cli/pull/20239)
- fix(cli): skip 404 errors in setup-github file downloads by @h30s in
[#20287](https://github.com/google-gemini/gemini-cli/pull/20287)
- fix(cli): expose model.name setting in settings dialog for persistence by
@achaljhawar in
[#19605](https://github.com/google-gemini/gemini-cli/pull/19605)
- docs: remove legacy cmd examples in favor of powershell by @scidomino in
[#20323](https://github.com/google-gemini/gemini-cli/pull/20323)
- feat(core): Enable model steering in workspace. by @joshualitt in
[#20343](https://github.com/google-gemini/gemini-cli/pull/20343)
- fix: remove trailing comma in issue triage workflow settings json by @Nixxx19
in [#20265](https://github.com/google-gemini/gemini-cli/pull/20265)
- feat(core): implement task tracker foundation and service by @anj-s in
[#19464](https://github.com/google-gemini/gemini-cli/pull/19464)
- test: support tests that include color information by @jacob314 in
[#20220](https://github.com/google-gemini/gemini-cli/pull/20220)
- feat(core): introduce Kind.Agent for sub-agent classification by @abhipatel12
in [#20369](https://github.com/google-gemini/gemini-cli/pull/20369)
- Changelog for v0.30.0 by @gemini-cli-robot in
[#20252](https://github.com/google-gemini/gemini-cli/pull/20252)
- Update changelog workflow to reject nightly builds by @g-samroberts in
[#20248](https://github.com/google-gemini/gemini-cli/pull/20248)
- Changelog for v0.31.0-preview.0 by @gemini-cli-robot in
[#20249](https://github.com/google-gemini/gemini-cli/pull/20249)
- feat(cli): hide workspace policy update dialog and auto-accept by default by
@Abhijit-2592 in
[#20351](https://github.com/google-gemini/gemini-cli/pull/20351)
- feat(core): rename grep_search include parameter to include_pattern by
@SandyTao520 in
[#20328](https://github.com/google-gemini/gemini-cli/pull/20328)
- feat(plan): support opening and modifying plan in external editor by @Adib234
in [#20348](https://github.com/google-gemini/gemini-cli/pull/20348)
- feat(cli): implement interactive shell autocompletion by @mrpmohiburrahman in
[#20082](https://github.com/google-gemini/gemini-cli/pull/20082)
- fix(core): allow /memory add to work in plan mode by @Jefftree in
[#20353](https://github.com/google-gemini/gemini-cli/pull/20353)
- feat(core): add HTTP 499 to retryable errors and map to RetryableQuotaError by
@bdmorgan in [#20432](https://github.com/google-gemini/gemini-cli/pull/20432)
- feat(core): Enable generalist agent by @joshualitt in
[#19665](https://github.com/google-gemini/gemini-cli/pull/19665)
- Updated tests in TableRenderer.test.tsx to use SVG snapshots by @devr0306 in
[#20450](https://github.com/google-gemini/gemini-cli/pull/20450)
- Refactor Github Action per b/485167538 by @google-admin in
[#19443](https://github.com/google-gemini/gemini-cli/pull/19443)
- fix(github): resolve actionlint and yamllint regressions from #19443 by @jerop
in [#20467](https://github.com/google-gemini/gemini-cli/pull/20467)
- fix: action var usage by @galz10 in
[#20492](https://github.com/google-gemini/gemini-cli/pull/20492)
- feat(core): improve A2A content extraction by @adamfweidman in
[#20487](https://github.com/google-gemini/gemini-cli/pull/20487)
- fix(cli): support quota error fallbacks for all authentication types by
@sehoon38 in [#20475](https://github.com/google-gemini/gemini-cli/pull/20475)
- fix(core): flush transcript for pure tool-call responses to ensure BeforeTool
hooks see complete state by @krishdef7 in
[#20419](https://github.com/google-gemini/gemini-cli/pull/20419)
- feat(plan): adapt planning workflow based on complexity of task by @jerop in
[#20465](https://github.com/google-gemini/gemini-cli/pull/20465)
- fix: prevent orphaned processes from consuming 100% CPU when terminal closes
by @yuvrajangadsingh in
[#16965](https://github.com/google-gemini/gemini-cli/pull/16965)
- feat(core): increase fetch timeout and fix [object Object] error
stringification by @bdmorgan in
[#20441](https://github.com/google-gemini/gemini-cli/pull/20441)
- [Gemma x Gemini CLI] Add an Experimental Gemma Router that uses a LiteRT-LM
shim into the Composite Model Classifier Strategy by @sidwan02 in
[#17231](https://github.com/google-gemini/gemini-cli/pull/17231)
- docs(plan): update documentation regarding supporting editing of plan files
during plan approval by @Adib234 in
[#20452](https://github.com/google-gemini/gemini-cli/pull/20452)
- test(cli): fix flaky ToolResultDisplay overflow test by @jwhelangoog in
[#20518](https://github.com/google-gemini/gemini-cli/pull/20518)
- ui(cli): reduce length of Ctrl+O hint by @jwhelangoog in
[#20490](https://github.com/google-gemini/gemini-cli/pull/20490)
- fix(ui): correct styled table width calculations by @devr0306 in
[#20042](https://github.com/google-gemini/gemini-cli/pull/20042)
- Avoid overaggressive unescaping by @scidomino in
[#20520](https://github.com/google-gemini/gemini-cli/pull/20520)
- feat(telemetry) Instrument traces with more attributes and make them available
to OTEL users by @heaventourist in
[#20237](https://github.com/google-gemini/gemini-cli/pull/20237)
- Add support for policy engine in extensions by @chrstnb in
[#20049](https://github.com/google-gemini/gemini-cli/pull/20049)
- Docs: Update to Terms of Service & FAQ by @jkcinouye in
[#20488](https://github.com/google-gemini/gemini-cli/pull/20488)
- Fix bottom border rendering for search and add a regression test. by @jacob314
in [#20517](https://github.com/google-gemini/gemini-cli/pull/20517)
- fix(core): apply retry logic to CodeAssistServer for all users by @bdmorgan in
[#20507](https://github.com/google-gemini/gemini-cli/pull/20507)
- Fix extension MCP server env var loading by @chrstnb in
[#20374](https://github.com/google-gemini/gemini-cli/pull/20374)
- feat(ui): add 'ctrl+o' hint to truncated content message by @jerop in
[#20529](https://github.com/google-gemini/gemini-cli/pull/20529)
- Fix flicker showing message to press ctrl-O again to collapse. by @jacob314 in
[#20414](https://github.com/google-gemini/gemini-cli/pull/20414)
- fix(cli): hide shortcuts hint while model is thinking or the user has typed a
prompt + add debounce to avoid flicker by @jacob314 in
[#19389](https://github.com/google-gemini/gemini-cli/pull/19389)
- feat(plan): update planning workflow to encourage multi-select with
descriptions of options by @Adib234 in
[#20491](https://github.com/google-gemini/gemini-cli/pull/20491)
- refactor(core,cli): useAlternateBuffer read from config by @psinha40898 in
[#20346](https://github.com/google-gemini/gemini-cli/pull/20346)
- fix(cli): ensure dialogs stay scrolled to bottom in alternate buffer mode by
@jacob314 in [#20527](https://github.com/google-gemini/gemini-cli/pull/20527)
- fix(core): revert auto-save of policies to user space by @Abhijit-2592 in
[#20531](https://github.com/google-gemini/gemini-cli/pull/20531)
- Demote unreliable test. by @gundermanc in
[#20571](https://github.com/google-gemini/gemini-cli/pull/20571)
- fix(core): handle optional response fields from code assist API by @sehoon38
in [#20345](https://github.com/google-gemini/gemini-cli/pull/20345)
- fix(cli): keep thought summary when loading phrases are off by @LyalinDotCom
in [#20497](https://github.com/google-gemini/gemini-cli/pull/20497)
- feat(cli): add temporary flag to disable workspace policies by @Abhijit-2592
in [#20523](https://github.com/google-gemini/gemini-cli/pull/20523)
- Disable expensive and scheduled workflows on personal forks by @dewitt in
[#20449](https://github.com/google-gemini/gemini-cli/pull/20449)
- Moved markdown parsing logic to a separate util file by @devr0306 in
[#20526](https://github.com/google-gemini/gemini-cli/pull/20526)
- fix(plan): prevent agent from using ask_user for shell command confirmation by
@Adib234 in [#20504](https://github.com/google-gemini/gemini-cli/pull/20504)
- fix(core): disable retries for code assist streaming requests by @sehoon38 in
[#20561](https://github.com/google-gemini/gemini-cli/pull/20561)
- feat(billing): implement G1 AI credits overage flow with billing telemetry by
@gsquared94 in
[#18590](https://github.com/google-gemini/gemini-cli/pull/18590)
- feat: better error messages by @gsquared94 in
[#20577](https://github.com/google-gemini/gemini-cli/pull/20577)
- fix(ui): persist expansion in AskUser dialog when navigating options by @jerop
in [#20559](https://github.com/google-gemini/gemini-cli/pull/20559)
- fix(cli): prevent sub-agent tool calls from leaking into UI by @abhipatel12 in
[#20580](https://github.com/google-gemini/gemini-cli/pull/20580)
- fix(cli): Shell autocomplete polish by @jacob314 in
[#20411](https://github.com/google-gemini/gemini-cli/pull/20411)
- Changelog for v0.31.0-preview.1 by @gemini-cli-robot in
[#20590](https://github.com/google-gemini/gemini-cli/pull/20590)
- Add slash command for promoting behavioral evals to CI blocking by @gundermanc
in [#20575](https://github.com/google-gemini/gemini-cli/pull/20575)
- Changelog for v0.30.1 by @gemini-cli-robot in
[#20589](https://github.com/google-gemini/gemini-cli/pull/20589)
- Add low/full CLI error verbosity mode for cleaner UI by @LyalinDotCom in
[#20399](https://github.com/google-gemini/gemini-cli/pull/20399)
- Disable Gemini PR reviews on draft PRs. by @gundermanc in
[#20362](https://github.com/google-gemini/gemini-cli/pull/20362)
- Docs: FAQ update by @jkcinouye in
[#20585](https://github.com/google-gemini/gemini-cli/pull/20585)
- fix(core): reduce intrusive MCP errors and deduplicate diagnostics by
@spencer426 in
[#20232](https://github.com/google-gemini/gemini-cli/pull/20232)
- docs: fix spelling typos in installation guide by @campox747 in
[#20579](https://github.com/google-gemini/gemini-cli/pull/20579)
- Promote stable tests to CI blocking. by @gundermanc in
[#20581](https://github.com/google-gemini/gemini-cli/pull/20581)
- feat(core): enable contiguous parallel admission for Kind.Agent tools by
@abhipatel12 in
[#20583](https://github.com/google-gemini/gemini-cli/pull/20583)
- Enforce import/no-duplicates as error by @Nixxx19 in
[#19797](https://github.com/google-gemini/gemini-cli/pull/19797)
- fix: merge duplicate imports in sdk and test-utils packages (1/4) by @Nixxx19
in [#19777](https://github.com/google-gemini/gemini-cli/pull/19777)
- fix: merge duplicate imports in a2a-server package (2/4) by @Nixxx19 in
[#19781](https://github.com/google-gemini/gemini-cli/pull/19781)
**Full Changelog**:
https://github.com/google-gemini/gemini-cli/compare/v0.31.0-preview.3...v0.32.0-preview.0
**Full changelog**:
https://github.com/google-gemini/gemini-cli/compare/v0.23.0-preview.6...v0.24.0-preview.0
File diff suppressed because it is too large Load Diff
+3
View File
@@ -0,0 +1,3 @@
# Authentication setup
See: [Getting Started - Authentication Setup](../get-started/authentication.md).
+3 -2
View File
@@ -2,8 +2,9 @@
The Gemini CLI includes a Checkpointing feature that automatically saves a
snapshot of your project's state before any file modifications are made by
AI-powered tools. This lets you safely experiment with and apply code changes,
knowing you can instantly revert back to the state before the tool was run.
AI-powered tools. This allows you to safely experiment with and apply code
changes, knowing you can instantly revert back to the state before the tool was
run.
## How it works
-115
View File
@@ -1,115 +0,0 @@
# Gemini CLI cheatsheet
This page provides a reference for commonly used Gemini CLI commands, options,
and parameters.
## CLI commands
| Command | Description | Example |
| ---------------------------------- | ---------------------------------- | ------------------------------------------------------------ |
| `gemini` | Start interactive REPL | `gemini` |
| `gemini "query"` | Query non-interactively, then exit | `gemini "explain this project"` |
| `cat file \| gemini` | Process piped content | `cat logs.txt \| gemini`<br>`Get-Content logs.txt \| gemini` |
| `gemini -i "query"` | Execute and continue interactively | `gemini -i "What is the purpose of this project?"` |
| `gemini -r "latest"` | Continue most recent session | `gemini -r "latest"` |
| `gemini -r "latest" "query"` | Continue session with a new prompt | `gemini -r "latest" "Check for type errors"` |
| `gemini -r "<session-id>" "query"` | Resume session by ID | `gemini -r "abc123" "Finish this PR"` |
| `gemini update` | Update to latest version | `gemini update` |
| `gemini extensions` | Manage extensions | See [Extensions Management](#extensions-management) |
| `gemini mcp` | Configure MCP servers | See [MCP Server Management](#mcp-server-management) |
### Positional arguments
| Argument | Type | Description |
| -------- | ----------------- | ------------------------------------------------------------------------------------------------------------------ |
| `query` | string (variadic) | Positional prompt. Defaults to one-shot mode. Use `-i/--prompt-interactive` to execute and continue interactively. |
## 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](../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
The `--model` (or `-m`) flag lets you specify which Gemini model to use. You can
use either model aliases (user-friendly names) or concrete model names.
### Model aliases
These are convenient shortcuts that map to specific models:
| Alias | Resolves To | Description |
| ------------ | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------- |
| `auto` | `gemini-2.5-pro` or `gemini-3-pro-preview` | **Default.** Resolves to the preview model if preview features are enabled, otherwise resolves to the standard pro model. |
| `pro` | `gemini-2.5-pro` or `gemini-3-pro-preview` | For complex reasoning tasks. Uses preview model if enabled. |
| `flash` | `gemini-2.5-flash` | Fast, balanced model for most tasks. |
| `flash-lite` | `gemini-2.5-flash-lite` | Fastest model for simple tasks. |
## Extensions management
| Command | Description | Example |
| -------------------------------------------------- | -------------------------------------------- | ------------------------------------------------------------------------------ |
| `gemini extensions install <source>` | Install extension from Git URL or local path | `gemini extensions install https://github.com/user/my-extension` |
| `gemini extensions install <source> --ref <ref>` | Install from specific branch/tag/commit | `gemini extensions install https://github.com/user/my-extension --ref develop` |
| `gemini extensions install <source> --auto-update` | Install with auto-update enabled | `gemini extensions install https://github.com/user/my-extension --auto-update` |
| `gemini extensions uninstall <name>` | Uninstall one or more extensions | `gemini extensions uninstall my-extension` |
| `gemini extensions list` | List all installed extensions | `gemini extensions list` |
| `gemini extensions update <name>` | Update a specific extension | `gemini extensions update my-extension` |
| `gemini extensions update --all` | Update all extensions | `gemini extensions update --all` |
| `gemini extensions enable <name>` | Enable an extension | `gemini extensions enable my-extension` |
| `gemini extensions disable <name>` | Disable an extension | `gemini extensions disable my-extension` |
| `gemini extensions link <path>` | Link local extension for development | `gemini extensions link /path/to/extension` |
| `gemini extensions new <path>` | Create new extension from template | `gemini extensions new ./my-extension` |
| `gemini extensions validate <path>` | Validate extension structure | `gemini extensions validate ./my-extension` |
See [Extensions Documentation](../extensions/index.md) for more details.
## MCP server management
| Command | Description | Example |
| ------------------------------------------------------------- | ------------------------------- | ---------------------------------------------------------------------------------------------------- |
| `gemini mcp add <name> <command>` | Add stdio-based MCP server | `gemini mcp add github npx -y @modelcontextprotocol/server-github` |
| `gemini mcp add <name> <url> --transport http` | Add HTTP-based MCP server | `gemini mcp add api-server http://localhost:3000 --transport http` |
| `gemini mcp add <name> <command> --env KEY=value` | Add with environment variables | `gemini mcp add slack node server.js --env SLACK_TOKEN=xoxb-xxx` |
| `gemini mcp add <name> <command> --scope user` | Add with user scope | `gemini mcp add db node db-server.js --scope user` |
| `gemini mcp add <name> <command> --include-tools tool1,tool2` | Add with specific tools | `gemini mcp add github npx -y @modelcontextprotocol/server-github --include-tools list_repos,get_pr` |
| `gemini mcp remove <name>` | Remove an MCP server | `gemini mcp remove github` |
| `gemini mcp list` | List all configured MCP servers | `gemini mcp list` |
See [MCP Server Integration](../tools/mcp-server.md) for more details.
## Skills management
| Command | Description | Example |
| -------------------------------- | ------------------------------------- | ------------------------------------------------- |
| `gemini skills list` | List all discovered agent skills | `gemini skills list` |
| `gemini skills install <source>` | Install skill from Git, path, or file | `gemini skills install https://github.com/u/repo` |
| `gemini skills link <path>` | Link local agent skills via symlink | `gemini skills link /path/to/my-skills` |
| `gemini skills uninstall <name>` | Uninstall an agent skill | `gemini skills uninstall my-skill` |
| `gemini skills enable <name>` | Enable an agent skill | `gemini skills enable my-skill` |
| `gemini skills disable <name>` | Disable an agent skill | `gemini skills disable my-skill` |
| `gemini skills enable --all` | Enable all skills | `gemini skills enable --all` |
| `gemini skills disable --all` | Disable all skills | `gemini skills disable --all` |
See [Agent Skills Documentation](./skills.md) for more details.
+381
View File
@@ -0,0 +1,381 @@
# CLI commands
Gemini CLI supports several built-in commands to help you manage your session,
customize the interface, and control its behavior. These commands are prefixed
with a forward slash (`/`), an at symbol (`@`), or an exclamation mark (`!`).
## Slash commands (`/`)
Slash commands provide meta-level control over the CLI itself.
### Built-in Commands
- **`/bug`**
- **Description:** File an issue about Gemini CLI. By default, the issue is
filed within the GitHub repository for Gemini CLI. The string you enter
after `/bug` will become the headline for the bug being filed. The default
`/bug` behavior can be modified using the `advanced.bugCommand` setting in
your `.gemini/settings.json` files.
- **`/chat`**
- **Description:** Save and resume conversation history for branching
conversation state interactively, or resuming a previous state from a later
session.
- **Sub-commands:**
- **`save`**
- **Description:** Saves the current conversation history. You must add a
`<tag>` for identifying the conversation state.
- **Usage:** `/chat save <tag>`
- **Details on checkpoint location:** The default locations for saved chat
checkpoints are:
- Linux/macOS: `~/.gemini/tmp/<project_hash>/`
- Windows: `C:\Users\<YourUsername>\.gemini\tmp\<project_hash>\`
- **Behavior:** Chats are saved into a project-specific directory,
determined by where you run the CLI. Consequently, saved chats are
only accessible when working within that same project.
- **Note:** These checkpoints are for manually saving and resuming
conversation states. For automatic checkpoints created before file
modifications, see the
[Checkpointing documentation](../cli/checkpointing.md).
- **`resume`**
- **Description:** Resumes a conversation from a previous save.
- **Usage:** `/chat resume <tag>`
- **Note:** You can only resume chats that were saved within the current
project. To resume a chat from a different project, you must run the
Gemini CLI from that project's directory.
- **`list`**
- **Description:** Lists available tags for chat state resumption.
- **Note:** This command only lists chats saved within the current
project. Because chat history is project-scoped, chats saved in other
project directories will not be displayed.
- **`delete`**
- **Description:** Deletes a saved conversation checkpoint.
- **Usage:** `/chat delete <tag>`
- **`share`**
- **Description** Writes the current conversation to a provided Markdown
or JSON file.
- **Usage** `/chat share file.md` or `/chat share file.json`. If no
filename is provided, then the CLI will generate one.
- **`/clear`**
- **Description:** Clear the terminal screen, including the visible session
history and scrollback within the CLI. The underlying session data (for
history recall) might be preserved depending on the exact implementation,
but the visual display is cleared.
- **Keyboard shortcut:** Press **Ctrl+L** at any time to perform a clear
action.
- **`/compress`**
- **Description:** Replace the entire chat context with a summary. This saves
on tokens used for future tasks while retaining a high level summary of what
has happened.
- **`/copy`**
- **Description:** Copies the last output produced by Gemini CLI to your
clipboard, for easy sharing or reuse.
- **Behavior:**
- Local sessions use system clipboard tools (pbcopy/xclip/clip).
- Remote sessions (SSH/WSL) use OSC 52 and require terminal support.
- **Note:** This command requires platform-specific clipboard tools to be
installed.
- On Linux, it requires `xclip` or `xsel`. You can typically install them
using your system's package manager.
- On macOS, it requires `pbcopy`, and on Windows, it requires `clip`. These
tools are typically pre-installed on their respective systems.
- **`/directory`** (or **`/dir`**)
- **Description:** Manage workspace directories for multi-directory support.
- **Sub-commands:**
- **`add`**:
- **Description:** Add a directory to the workspace. The path can be
absolute or relative to the current working directory. Moreover, the
reference from home directory is supported as well.
- **Usage:** `/directory add <path1>,<path2>`
- **Note:** Disabled in restrictive sandbox profiles. If you're using
that, use `--include-directories` when starting the session instead.
- **`show`**:
- **Description:** Display all directories added by `/directory add` and
`--include-directories`.
- **Usage:** `/directory show`
- **`/editor`**
- **Description:** Open a dialog for selecting supported editors.
- **`/extensions`**
- **Description:** Lists all active extensions in the current Gemini CLI
session. See [Gemini CLI Extensions](../extensions/index.md).
- **`/help`** (or **`/?`**)
- **Description:** Display help information about Gemini CLI, including
available commands and their usage.
- **`/mcp`**
- **Description:** Manage configured Model Context Protocol (MCP) servers.
- **Sub-commands:**
- **`list`** or **`ls`**:
- **Description:** List configured MCP servers and tools. This is the
default action if no subcommand is specified.
- **`desc`**
- **Description:** List configured MCP servers and tools with
descriptions.
- **`schema`**:
- **Description:** List configured MCP servers and tools with descriptions
and schemas.
- **`auth`**:
- **Description:** Authenticate with an OAuth-enabled MCP server.
- **Usage:** `/mcp auth <server-name>`
- **Details:** If `<server-name>` is provided, it initiates the OAuth flow
for that server. If no server name is provided, it lists all configured
servers that support OAuth authentication.
- **`refresh`**:
- **Description:** Restarts all MCP servers and re-discovers their
available tools.
- [**`/model`**](./model.md)
- **Description:** Opens a dialog to choose your Gemini model.
- **`/memory`**
- **Description:** Manage the AI's instructional context (hierarchical memory
loaded from `GEMINI.md` files).
- **Sub-commands:**
- **`add`**:
- **Description:** Adds the following text to the AI's memory. Usage:
`/memory add <text to remember>`
- **`show`**:
- **Description:** Display the full, concatenated content of the current
hierarchical memory that has been loaded from all `GEMINI.md` files.
This lets you inspect the instructional context being provided to the
Gemini model.
- **`refresh`**:
- **Description:** Reload the hierarchical instructional memory from all
`GEMINI.md` files found in the configured locations (global,
project/ancestors, and sub-directories). This command updates the model
with the latest `GEMINI.md` content.
- **`list`**:
- **Description:** Lists the paths of the GEMINI.md files in use for
hierarchical memory.
- **Note:** For more details on how `GEMINI.md` files contribute to
hierarchical memory, see the
[CLI Configuration documentation](../get-started/configuration.md).
- **`/restore`**
- **Description:** Restores the project files to the state they were in just
before a tool was executed. This is particularly useful for undoing file
edits made by a tool. If run without a tool call ID, it will list available
checkpoints to restore from.
- **Usage:** `/restore [tool_call_id]`
- **Note:** Only available if checkpointing is configured via
[settings](../get-started/configuration.md). See
[Checkpointing documentation](../cli/checkpointing.md) for more details.
- [**`/rewind`**](./rewind.md)
- **Description:** Browse and rewind previous interactions. Allows you to
rewind the conversation, revert file changes, or both. Provides an
interactive interface to select the exact point to rewind to.
- **Keyboard shortcut:** Press **Esc** twice.
- **`/resume`**
- **Description:** Browse and resume previous conversation sessions. Opens an
interactive session browser where you can search, filter, and select from
automatically saved conversations.
- **Features:**
- **Session Browser:** Interactive interface showing all saved sessions with
timestamps, message counts, and first user message for context
- **Search:** Use `/` to search through conversation content across all
sessions
- **Sorting:** Sort sessions by date or message count
- **Management:** Delete unwanted sessions directly from the browser
- **Resume:** Select any session to resume and continue the conversation
- **Note:** All conversations are automatically saved as you chat - no manual
saving required. See [Session Management](../cli/session-management.md) for
complete details.
- [**`/settings`**](./settings.md)
- **Description:** Open the settings editor to view and modify Gemini CLI
settings.
- **Details:** This command provides a user-friendly interface for changing
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.
- **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 others require a restart.
- [**`/skills`**](./skills.md)
- **Description:** (Experimental) Manage Agent Skills, which provide on-demand
expertise and specialized workflows.
- **Sub-commands:**
- **`list`**:
- **Description:** List all discovered skills and their current status
(enabled/disabled).
- **`enable`**:
- **Description:** Enable a specific skill by name.
- **Usage:** `/skills enable <name>`
- **`disable`**:
- **Description:** Disable a specific skill by name.
- **Usage:** `/skills disable <name>`
- **`reload`**:
- **Description:** Refresh the list of discovered skills from all tiers
(workspace, user, and extensions).
- **`/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.
- [**`/theme`**](./themes.md)
- **Description:** Open a dialog that lets you change the visual theme of
Gemini CLI.
- **`/auth`**
- **Description:** Open a dialog that lets you change the authentication
method.
- **`/about`**
- **Description:** Show version info. Please share this information when
filing issues.
- [**`/tools`**](../tools/index.md)
- **Description:** Display a list of tools that are currently available within
Gemini CLI.
- **Usage:** `/tools [desc]`
- **Sub-commands:**
- **`desc`** or **`descriptions`**:
- **Description:** Show detailed descriptions of each tool, including each
tool's name with its full description as provided to the model.
- **`nodesc`** or **`nodescriptions`**:
- **Description:** Hide tool descriptions, showing only the tool names.
- **`/privacy`**
- **Description:** Display the Privacy Notice and allow users to select
whether they consent to the collection of their data for service improvement
purposes.
- **`/quit`** (or **`/exit`**)
- **Description:** Exit Gemini CLI.
- **`/vim`**
- **Description:** Toggle vim mode on or off. When vim mode is enabled, the
input area supports vim-style navigation and editing commands in both NORMAL
and INSERT modes.
- **Features:**
- **NORMAL mode:** Navigate with `h`, `j`, `k`, `l`; jump by words with `w`,
`b`, `e`; go to line start/end with `0`, `$`, `^`; go to specific lines
with `G` (or `gg` for first line)
- **INSERT mode:** Standard text input with escape to return to NORMAL mode
- **Editing commands:** Delete with `x`, change with `c`, insert with `i`,
`a`, `o`, `O`; complex operations like `dd`, `cc`, `dw`, `cw`
- **Count support:** Prefix commands with numbers (e.g., `3h`, `5w`, `10G`)
- **Repeat last command:** Use `.` to repeat the last editing operation
- **Persistent setting:** Vim mode preference is saved to
`~/.gemini/settings.json` and restored between sessions
- **Status indicator:** When enabled, shows `[NORMAL]` or `[INSERT]` in the
footer
- **`/init`**
- **Description:** To help users easily create a `GEMINI.md` file, this
command analyzes the current directory and generates a tailored context
file, making it simpler for them to provide project-specific instructions to
the Gemini agent.
### Custom commands
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).
## Input prompt shortcuts
These shortcuts apply directly to the input prompt for text manipulation.
- **Undo:**
- **Keyboard shortcut:** Press **Ctrl+z** to undo the last action in the input
prompt.
- **Redo:**
- **Keyboard shortcut:** Press **Ctrl+Shift+Z** to redo the last undone action
in the input prompt.
## At commands (`@`)
At commands are used to include the content of files or directories as part of
your prompt to Gemini. These commands include git-aware filtering.
- **`@<path_to_file_or_directory>`**
- **Description:** Inject the content of the specified file or files into your
current prompt. This is useful for asking questions about specific code,
text, or collections of files.
- **Examples:**
- `@path/to/your/file.txt Explain this text.`
- `@src/my_project/ Summarize the code in this directory.`
- `What is this file about? @README.md`
- **Details:**
- If a path to a single file is provided, the content of that file is read.
- If a path to a directory is provided, the command attempts to read the
content of files within that directory and any subdirectories.
- Spaces in paths should be escaped with a backslash (e.g.,
`@My\ Documents/file.txt`).
- The command uses the `read_many_files` tool internally. The content is
fetched and then inserted into your query before being sent to the Gemini
model.
- **Git-aware filtering:** By default, git-ignored files (like
`node_modules/`, `dist/`, `.env`, `.git/`) are excluded. This behavior can
be changed via the `context.fileFiltering` settings.
- **File types:** The command is intended for text-based files. While it
might attempt to read any file, binary files or very large files might be
skipped or truncated by the underlying `read_many_files` tool to ensure
performance and relevance. The tool indicates if files were skipped.
- **Output:** The CLI will show a tool call message indicating that
`read_many_files` was used, along with a message detailing the status and
the path(s) that were processed.
- **`@` (Lone at symbol)**
- **Description:** If you type a lone `@` symbol without a path, the query is
passed as-is to the Gemini model. This might be useful if you are
specifically talking _about_ the `@` symbol in your prompt.
### Error handling for `@` commands
- If the path specified after `@` is not found or is invalid, an error message
will be displayed, and the query might not be sent to the Gemini model, or it
will be sent without the file content.
- If the `read_many_files` tool encounters an error (e.g., permission issues),
this will also be reported.
## Shell mode and passthrough commands (`!`)
The `!` prefix lets you interact with your system's shell directly from within
Gemini CLI.
- **`!<shell_command>`**
- **Description:** Execute the given `<shell_command>` using `bash` on
Linux/macOS or `powershell.exe -NoProfile -Command` on Windows (unless you
override `ComSpec`). Any output or errors from the command are displayed in
the terminal.
- **Examples:**
- `!ls -la` (executes `ls -la` and returns to Gemini CLI)
- `!git status` (executes `git status` and returns to Gemini CLI)
- **`!` (Toggle shell mode)**
- **Description:** Typing `!` on its own toggles shell mode.
- **Entering shell mode:**
- When active, shell mode uses a different coloring and a "Shell Mode
Indicator".
- While in shell mode, text you type is interpreted directly as a shell
command.
- **Exiting shell mode:**
- When exited, the UI reverts to its standard appearance and normal Gemini
CLI behavior resumes.
- **Caution for all `!` usage:** Commands you execute in shell mode have the
same permissions and impact as if you ran them directly in your terminal.
- **Environment variable:** When a command is executed via `!` or in shell mode,
the `GEMINI_CLI=1` environment variable is set in the subprocess's
environment. This allows scripts or tools to detect if they are being run from
within the Gemini CLI.
-80
View File
@@ -1,80 +0,0 @@
# Creating Agent Skills
This guide provides an overview of how to create your own Agent Skills to extend
the capabilities of Gemini CLI.
## Getting started: The `skill-creator` skill
The recommended way to create a new skill is to use the built-in `skill-creator`
skill. To use it, ask Gemini CLI to create a new skill for you.
**Example prompt:**
> "create a new skill called 'code-reviewer'"
Gemini CLI will then use the `skill-creator` to generate the skill:
1. Generate a new directory for your skill (e.g., `my-new-skill/`).
2. Create a `SKILL.md` file with the necessary YAML frontmatter (`name` and
`description`).
3. Create the standard resource directories: `scripts/`, `references/`, and
`assets/`.
## Manual skill creation
If you prefer to create skills manually:
1. **Create a directory** for your skill (e.g., `my-new-skill/`).
2. **Create a `SKILL.md` file** inside the new directory.
To add additional resources that support the skill, refer to the skill
structure.
## Skill structure
A skill is a directory containing a `SKILL.md` file at its root.
### Folder structure
While a `SKILL.md` file is the only required component, we recommend the
following structure for organizing your skill's resources:
```text
my-skill/
├── SKILL.md (Required) Instructions and metadata
├── scripts/ (Optional) Executable scripts
├── references/ (Optional) Static documentation
└── assets/ (Optional) Templates and other resources
```
### `SKILL.md` file
The `SKILL.md` file is the core of your skill. This file uses YAML frontmatter
for metadata and Markdown for instructions. For example:
```markdown
---
name: code-reviewer
description:
Use this skill to review code. It supports both local changes and remote Pull
Requests.
---
# Code Reviewer
This skill guides the agent in conducting thorough code reviews.
## Workflow
### 1. Determine Review Target
- **Remote PR**: If the user gives a PR number or URL, target that remote PR.
- **Local Changes**: If changes are local... ...
```
- **`name`**: A unique identifier for the skill. This should match the directory
name.
- **`description`**: A description of what the skill does and when Gemini should
use it.
- **Body**: The Markdown body of the file contains the instructions that guide
the agent's behavior when the skill is active.
-12
View File
@@ -30,9 +30,6 @@ separator (`/` or `\`) being converted to a colon (`:`).
- A file at `<project>/.gemini/commands/git/commit.toml` becomes the namespaced
command `/git:commit`.
> [!TIP] After creating or modifying `.toml` command files, run
> `/commands reload` to pick up your changes without restarting the CLI.
## TOML file format (v1)
Your command definition files must be written in the TOML format and use the
@@ -278,20 +275,11 @@ Let's create a global command that asks the model to refactor a piece of code.
First, ensure the user commands directory exists, then create a `refactor`
subdirectory for organization and the final TOML file.
**macOS/Linux**
```bash
mkdir -p ~/.gemini/commands/refactor
touch ~/.gemini/commands/refactor/pure.toml
```
**Windows (PowerShell)**
```powershell
New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\.gemini\commands\refactor"
New-Item -ItemType File -Force -Path "$env:USERPROFILE\.gemini\commands\refactor\pure.toml"
```
**2. Add the content to the file:**
Open `~/.gemini/commands/refactor/pure.toml` in your editor and add the
+8 -47
View File
@@ -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](../reference/configuration.md).
the [Configuration documentation](../get-started/configuration.md).
Settings are merged from four files. The precedence order for single-value
settings (like `theme`) is:
@@ -203,48 +203,12 @@ with the actual Gemini CLI process, which inherits the environment variable.
This makes it significantly more difficult for a user to bypass the enforced
settings.
**PowerShell Profile (Windows alternative):**
On Windows, administrators can achieve similar results by adding the environment
variable to the system-wide or user-specific PowerShell profile:
```powershell
Add-Content -Path $PROFILE -Value '$env:GEMINI_CLI_SYSTEM_SETTINGS_PATH="C:\ProgramData\gemini-cli\settings.json"'
```
## User isolation in shared environments
In shared compute environments (like ML experiment runners or shared build
servers), you can isolate Gemini CLI state by overriding the user's home
directory.
By default, Gemini CLI stores configuration and history in `~/.gemini`. You can
use the `GEMINI_CLI_HOME` environment variable to point to a unique directory
for a specific user or job. The CLI will create a `.gemini` folder inside the
specified path.
**macOS/Linux**
```bash
# Isolate state for a specific job
export GEMINI_CLI_HOME="/tmp/gemini-job-123"
gemini
```
**Windows (PowerShell)**
```powershell
# Isolate state for a specific job
$env:GEMINI_CLI_HOME="C:\temp\gemini-job-123"
gemini
```
## Restricting tool access
You can significantly enhance security by controlling which tools the Gemini
model can use. This is achieved through the `tools.core` setting and the
[Policy Engine](../reference/policy-engine.md). For a list of available tools,
see the [Tools documentation](../tools/index.md).
model can use. This is achieved through the `tools.core` and `tools.exclude`
settings. For a list of available tools, see the
[Tools documentation](../tools/index.md).
### Allowlisting with `coreTools`
@@ -262,10 +226,7 @@ on the approved list.
}
```
### Blocklisting with `excludeTools` (Deprecated)
> **Deprecated:** Use the [Policy Engine](../reference/policy-engine.md) for
> more robust control.
### Blocklisting with `excludeTools`
Alternatively, you can add specific tools that are considered dangerous in your
environment to a blocklist.
@@ -308,8 +269,8 @@ unintended tool execution.
## Managing custom tools (MCP servers)
If your organization uses custom tools via
[Model-Context Protocol (MCP) servers](../reference/tools-api.md), it is crucial
to understand how server configurations are managed to apply security policies
[Model-Context Protocol (MCP) servers](../core/tools-api.md), it is crucial to
understand how server configurations are managed to apply security policies
effectively.
### How MCP server configurations are merged
@@ -502,7 +463,7 @@ avoid collecting potentially sensitive information from user prompts.
You can enforce a specific authentication method for all users by setting the
`enforcedAuthType` in the system-level `settings.json` file. This prevents users
from choosing a different authentication method. See the
[Authentication docs](../get-started/authentication.md) for more details.
[Authentication docs](./authentication.md) for more details.
**Example:** Enforce the use of Google login for all users.
+12 -20
View File
@@ -19,18 +19,18 @@ order:
- **Location:** `~/.gemini/GEMINI.md` (in your user home directory).
- **Scope:** Provides default instructions for all your projects.
2. **Environment and workspace context files:**
- **Location:** The CLI searches for `GEMINI.md` files in your configured
workspace directories and their parent directories.
- **Scope:** Provides context relevant to the projects you are currently
working on.
2. **Project root and ancestor context files:**
- **Location:** The CLI searches for a `GEMINI.md` file in your current
working directory and then in each parent directory up to the project root
(identified by a `.git` folder).
- **Scope:** Provides context relevant to the entire project.
3. **Just-in-time (JIT) context files:**
- **Location:** When a tool accesses a file or directory, the CLI
automatically scans for `GEMINI.md` files in that directory and its
ancestors up to a trusted root.
- **Scope:** Lets the model discover highly specific instructions for
particular components only when they are needed.
3. **Sub-directory context files:**
- **Location:** The CLI also scans for `GEMINI.md` files in subdirectories
below your current working directory. It respects rules in `.gitignore`
and `.geminiignore`.
- **Scope:** Lets you write highly specific instructions for a particular
component or module.
The CLI footer displays the number of loaded context files, which gives you a
quick visual cue of the active instructional context.
@@ -88,7 +88,7 @@ More content here.
@../shared/style-guide.md
```
For more details, see the [Memory Import Processor](../reference/memport.md)
For more details, see the [Memory Import Processor](../core/memport.md)
documentation.
## Customize the context file name
@@ -106,11 +106,3 @@ While `GEMINI.md` is the default filename, you can configure this in your
}
}
```
## Next steps
- Learn about [Ignoring files](./gemini-ignore.md) to exclude content from the
context system.
- Explore the [Memory tool](../tools/memory.md) to save persistent memories.
- See how to use [Custom commands](./custom-commands.md) to automate common
prompts.
+372 -34
View File
@@ -1,50 +1,388 @@
# Headless mode reference
# Headless mode
Headless mode provides a programmatic interface to Gemini CLI, returning
structured text or JSON output without an interactive terminal UI.
Headless mode allows you to run Gemini CLI programmatically from command line
scripts and automation tools without any interactive UI. This is ideal for
scripting, automation, CI/CD pipelines, and building AI-powered tools.
## Technical reference
- [Headless Mode](#headless-mode)
- [Overview](#overview)
- [Basic Usage](#basic-usage)
- [Direct Prompts](#direct-prompts)
- [Stdin Input](#stdin-input)
- [Combining with File Input](#combining-with-file-input)
- [Output Formats](#output-formats)
- [Text Output (Default)](#text-output-default)
- [JSON Output](#json-output)
- [Response Schema](#response-schema)
- [Example Usage](#example-usage)
- [Streaming JSON Output](#streaming-json-output)
- [When to Use Streaming JSON](#when-to-use-streaming-json)
- [Event Types](#event-types)
- [Basic Usage](#basic-usage)
- [Example Output](#example-output)
- [Processing Stream Events](#processing-stream-events)
- [Real-World Examples](#real-world-examples)
- [File Redirection](#file-redirection)
- [Configuration Options](#configuration-options)
- [Examples](#examples)
- [Code review](#code-review)
- [Generate commit messages](#generate-commit-messages)
- [API documentation](#api-documentation)
- [Batch code analysis](#batch-code-analysis)
- [Code review](#code-review-1)
- [Log analysis](#log-analysis)
- [Release notes generation](#release-notes-generation)
- [Model and tool usage tracking](#model-and-tool-usage-tracking)
- [Resources](#resources)
Headless mode is triggered when the CLI is run in a non-TTY environment or when
providing a query as a positional argument without the interactive flag.
## Overview
### Output formats
The headless mode provides a headless interface to Gemini CLI that:
You can specify the output format using the `--output-format` flag.
- Accepts prompts via command line arguments or stdin
- Returns structured output (text or JSON)
- Supports file redirection and piping
- Enables automation and scripting workflows
- Provides consistent exit codes for error handling
#### JSON output
## Basic usage
Returns a single JSON object containing the response and usage statistics.
### Direct prompts
- **Schema:**
- `response`: (string) The model's final answer.
- `stats`: (object) Token usage and API latency metrics.
- `error`: (object, optional) Error details if the request failed.
Use the `--prompt` (or `-p`) flag to run in headless mode:
#### Streaming JSON output
```bash
gemini --prompt "What is machine learning?"
```
Returns a stream of newline-delimited JSON (JSONL) events.
### Stdin input
- **Event types:**
- `init`: Session metadata (session ID, model).
- `message`: User and assistant message chunks.
- `tool_use`: Tool call requests with arguments.
- `tool_result`: Output from executed tools.
- `error`: Non-fatal warnings and system errors.
- `result`: Final outcome with aggregated statistics.
Pipe input to Gemini CLI from your terminal:
## Exit codes
```bash
echo "Explain this code" | gemini
```
The CLI returns standard exit codes to indicate the result of the headless
execution:
### Combining with file input
- `0`: Success.
- `1`: General error or API failure.
- `42`: Input error (invalid prompt or arguments).
- `53`: Turn limit exceeded.
Read from files and process with Gemini:
## Next steps
```bash
cat README.md | gemini --prompt "Summarize this documentation"
```
- Follow the [Automation tutorial](./tutorials/automation.md) for practical
scripting examples.
- See the [CLI reference](./cli-reference.md) for all available flags.
## Output formats
### Text output (default)
Standard human-readable output:
```bash
gemini -p "What is the capital of France?"
```
Response format:
```
The capital of France is Paris.
```
### JSON output
Returns structured data including response, statistics, and metadata. This
format is ideal for programmatic processing and automation scripts.
#### Response schema
The JSON output follows this high-level structure:
```json
{
"response": "string", // The main AI-generated content answering your prompt
"stats": {
// Usage metrics and performance data
"models": {
// Per-model API and token usage statistics
"[model-name]": {
"api": {
/* request counts, errors, latency */
},
"tokens": {
/* prompt, response, cached, total counts */
}
}
},
"tools": {
// Tool execution statistics
"totalCalls": "number",
"totalSuccess": "number",
"totalFail": "number",
"totalDurationMs": "number",
"totalDecisions": {
/* accept, reject, modify, auto_accept counts */
},
"byName": {
/* per-tool detailed stats */
}
},
"files": {
// File modification statistics
"totalLinesAdded": "number",
"totalLinesRemoved": "number"
}
},
"error": {
// Present only when an error occurred
"type": "string", // Error type (e.g., "ApiError", "AuthError")
"message": "string", // Human-readable error description
"code": "number" // Optional error code
}
}
```
#### Example usage
```bash
gemini -p "What is the capital of France?" --output-format json
```
Response:
```json
{
"response": "The capital of France is Paris.",
"stats": {
"models": {
"gemini-2.5-pro": {
"api": {
"totalRequests": 2,
"totalErrors": 0,
"totalLatencyMs": 5053
},
"tokens": {
"prompt": 24939,
"candidates": 20,
"total": 25113,
"cached": 21263,
"thoughts": 154,
"tool": 0
}
},
"gemini-2.5-flash": {
"api": {
"totalRequests": 1,
"totalErrors": 0,
"totalLatencyMs": 1879
},
"tokens": {
"prompt": 8965,
"candidates": 10,
"total": 9033,
"cached": 0,
"thoughts": 30,
"tool": 28
}
}
},
"tools": {
"totalCalls": 1,
"totalSuccess": 1,
"totalFail": 0,
"totalDurationMs": 1881,
"totalDecisions": {
"accept": 0,
"reject": 0,
"modify": 0,
"auto_accept": 1
},
"byName": {
"google_web_search": {
"count": 1,
"success": 1,
"fail": 0,
"durationMs": 1881,
"decisions": {
"accept": 0,
"reject": 0,
"modify": 0,
"auto_accept": 1
}
}
}
},
"files": {
"totalLinesAdded": 0,
"totalLinesRemoved": 0
}
}
}
```
### Streaming JSON output
Returns real-time events as newline-delimited JSON (JSONL). Each significant
action (initialization, messages, tool calls, results) emits immediately as it
occurs. This format is ideal for monitoring long-running operations, building
UIs with live progress, and creating automation pipelines that react to events.
#### When to use streaming JSON
Use `--output-format stream-json` when you need:
- **Real-time progress monitoring** - See tool calls and responses as they
happen
- **Event-driven automation** - React to specific events (e.g., tool failures)
- **Live UI updates** - Build interfaces showing AI agent activity in real-time
- **Detailed execution logs** - Capture complete interaction history with
timestamps
- **Pipeline integration** - Stream events to logging/monitoring systems
#### Event types
The streaming format emits 6 event types:
1. **`init`** - Session starts (includes session_id, model)
2. **`message`** - User prompts and assistant responses
3. **`tool_use`** - Tool call requests with parameters
4. **`tool_result`** - Tool execution results (success/error)
5. **`error`** - Non-fatal errors and warnings
6. **`result`** - Final session outcome with aggregated stats
#### Basic usage
```bash
# Stream events to console
gemini --output-format stream-json --prompt "What is 2+2?"
# Save event stream to file
gemini --output-format stream-json --prompt "Analyze this code" > events.jsonl
# Parse with jq
gemini --output-format stream-json --prompt "List files" | jq -r '.type'
```
#### Example output
Each line is a complete JSON event:
```jsonl
{"type":"init","timestamp":"2025-10-10T12:00:00.000Z","session_id":"abc123","model":"gemini-2.0-flash-exp"}
{"type":"message","role":"user","content":"List files in current directory","timestamp":"2025-10-10T12:00:01.000Z"}
{"type":"tool_use","tool_name":"Bash","tool_id":"bash-123","parameters":{"command":"ls -la"},"timestamp":"2025-10-10T12:00:02.000Z"}
{"type":"tool_result","tool_id":"bash-123","status":"success","output":"file1.txt\nfile2.txt","timestamp":"2025-10-10T12:00:03.000Z"}
{"type":"message","role":"assistant","content":"Here are the files...","delta":true,"timestamp":"2025-10-10T12:00:04.000Z"}
{"type":"result","status":"success","stats":{"total_tokens":250,"input_tokens":50,"output_tokens":200,"duration_ms":3000,"tool_calls":1},"timestamp":"2025-10-10T12:00:05.000Z"}
```
### File redirection
Save output to files or pipe to other commands:
```bash
# Save to file
gemini -p "Explain Docker" > docker-explanation.txt
gemini -p "Explain Docker" --output-format json > docker-explanation.json
# Append to file
gemini -p "Add more details" >> docker-explanation.txt
# Pipe to other tools
gemini -p "What is Kubernetes?" --output-format json | jq '.response'
gemini -p "Explain microservices" | wc -w
gemini -p "List programming languages" | grep -i "python"
```
## Configuration options
Key command-line options for headless usage:
| Option | Description | Example |
| ----------------------- | ---------------------------------- | -------------------------------------------------- |
| `--prompt`, `-p` | Run in headless mode | `gemini -p "query"` |
| `--output-format` | Specify output format (text, json) | `gemini -p "query" --output-format json` |
| `--model`, `-m` | Specify the Gemini model | `gemini -p "query" -m gemini-2.5-flash` |
| `--debug`, `-d` | Enable debug mode | `gemini -p "query" --debug` |
| `--include-directories` | Include additional directories | `gemini -p "query" --include-directories src,docs` |
| `--yolo`, `-y` | Auto-approve all actions | `gemini -p "query" --yolo` |
| `--approval-mode` | Set approval mode | `gemini -p "query" --approval-mode auto_edit` |
For complete details on all available configuration options, settings files, and
environment variables, see the
[Configuration Guide](../get-started/configuration.md).
## Examples
#### Code review
```bash
cat src/auth.py | gemini -p "Review this authentication code for security issues" > security-review.txt
```
#### Generate commit messages
```bash
result=$(git diff --cached | gemini -p "Write a concise commit message for these changes" --output-format json)
echo "$result" | jq -r '.response'
```
#### API documentation
```bash
result=$(cat api/routes.js | gemini -p "Generate OpenAPI spec for these routes" --output-format json)
echo "$result" | jq -r '.response' > openapi.json
```
#### Batch code analysis
```bash
for file in src/*.py; do
echo "Analyzing $file..."
result=$(cat "$file" | gemini -p "Find potential bugs and suggest improvements" --output-format json)
echo "$result" | jq -r '.response' > "reports/$(basename "$file").analysis"
echo "Completed analysis for $(basename "$file")" >> reports/progress.log
done
```
#### Code review
```bash
result=$(git diff origin/main...HEAD | gemini -p "Review these changes for bugs, security issues, and code quality" --output-format json)
echo "$result" | jq -r '.response' > pr-review.json
```
#### Log analysis
```bash
grep "ERROR" /var/log/app.log | tail -20 | gemini -p "Analyze these errors and suggest root cause and fixes" > error-analysis.txt
```
#### Release notes generation
```bash
result=$(git log --oneline v1.0.0..HEAD | gemini -p "Generate release notes from these commits" --output-format json)
response=$(echo "$result" | jq -r '.response')
echo "$response"
echo "$response" >> CHANGELOG.md
```
#### Model and tool usage tracking
```bash
result=$(gemini -p "Explain this database schema" --include-directories db --output-format json)
total_tokens=$(echo "$result" | jq -r '.stats.models // {} | to_entries | map(.value.tokens.total) | add // 0')
models_used=$(echo "$result" | jq -r '.stats.models // {} | keys | join(", ") | if . == "" then "none" else . end')
tool_calls=$(echo "$result" | jq -r '.stats.tools.totalCalls // 0')
tools_used=$(echo "$result" | jq -r '.stats.tools.byName // {} | keys | join(", ") | if . == "" then "none" else . end')
echo "$(date): $total_tokens tokens, $tool_calls tool calls ($tools_used) used with models: $models_used" >> usage.log
echo "$result" | jq -r '.response' > schema-docs.md
echo "Recent usage trends:"
tail -5 usage.log
```
## Resources
- [CLI Configuration](../get-started/configuration.md) - Complete configuration
guide
- [Authentication](../get-started/authentication.md) - Setup authentication
- [Commands](./commands.md) - Interactive commands reference
- [Tutorials](./tutorials.md) - Step-by-step automation guides
+65
View File
@@ -0,0 +1,65 @@
# Gemini CLI
Within Gemini CLI, `packages/cli` is the frontend for users to send and receive
prompts with the Gemini AI model and its associated tools. For a general
overview of Gemini CLI, see the [main documentation page](../index.md).
## Basic features
- **[Commands](./commands.md):** A reference for all built-in slash commands
- **[Custom commands](./custom-commands.md):** Create your own commands and
shortcuts for frequently used prompts.
- **[Headless mode](./headless.md):** Use Gemini CLI programmatically for
scripting and automation.
- **[Model selection](./model.md):** Configure the Gemini AI model used by the
CLI.
- **[Settings](./settings.md):** Configure various aspects of the CLI's behavior
and appearance.
- **[Themes](./themes.md):** Customizing the CLI's appearance with different
themes.
- **[Keyboard shortcuts](./keyboard-shortcuts.md):** A reference for all
keyboard shortcuts to improve your workflow.
- **[Tutorials](./tutorials.md):** Step-by-step guides for common tasks.
## Advanced features
- **[Checkpointing](./checkpointing.md):** Automatically save and restore
snapshots of your session and files.
- **[Enterprise configuration](./enterprise.md):** Deploy and manage Gemini CLI
in an enterprise environment.
- **[Sandboxing](./sandbox.md):** Isolate tool execution in a secure,
containerized environment.
- **[Agent Skills](./skills.md):** (Experimental) Extend the CLI with
specialized expertise and procedural workflows.
- **[Telemetry](./telemetry.md):** Configure observability to monitor usage and
performance.
- **[Token caching](./token-caching.md):** Optimize API costs by caching tokens.
- **[Trusted folders](./trusted-folders.md):** A security feature to control
which projects can use the full capabilities of the CLI.
- **[Ignoring files (.geminiignore)](./gemini-ignore.md):** Exclude specific
files and directories from being accessed by tools.
- **[Context files (GEMINI.md)](./gemini-md.md):** Provide persistent,
hierarchical context to the model.
- **[System prompt override](./system-prompt.md):** Replace the builtin system
instructions using `GEMINI_SYSTEM_MD`.
## Non-interactive mode
Gemini CLI can be run in a non-interactive mode, which is useful for scripting
and automation. In this mode, you pipe input to the CLI, it executes the
command, and then it exits.
The following example pipes a command to Gemini CLI from your terminal:
```bash
echo "What is fine tuning?" | gemini
```
You can also use the `--prompt` or `-p` flag:
```bash
gemini -p "What is fine tuning?"
```
For comprehensive documentation on headless usage, scripting, automation, and
advanced examples, see the **[Headless mode](./headless.md)** guide.
+124
View File
@@ -0,0 +1,124 @@
# Gemini CLI keyboard shortcuts
Gemini CLI ships with a set of default keyboard shortcuts for editing input,
navigating history, and controlling the UI. Use this reference to learn the
available combinations.
<!-- KEYBINDINGS-AUTOGEN:START -->
#### Basic Controls
| Action | Keys |
| --------------------------------------------------------------- | ---------- |
| Confirm the current selection or choice. | `Enter` |
| Dismiss dialogs or cancel the current focus. | `Esc` |
| Cancel the current request or quit the CLI when input is empty. | `Ctrl + C` |
| Exit the CLI when the input buffer is empty. | `Ctrl + D` |
#### Cursor Movement
| Action | Keys |
| ------------------------------------------- | ------------------------------------------------------------ |
| Move the cursor to the start of the line. | `Ctrl + A`<br />`Home` |
| Move the cursor to the end of the line. | `Ctrl + E`<br />`End` |
| Move the cursor up one line. | `Up Arrow (no Ctrl, no Cmd)` |
| Move the cursor down one line. | `Down Arrow (no Ctrl, no Cmd)` |
| Move the cursor one character to the left. | `Left Arrow (no Ctrl, no Cmd)`<br />`Ctrl + B` |
| Move the cursor one character to the right. | `Right Arrow (no Ctrl, no Cmd)`<br />`Ctrl + F` |
| Move the cursor one word to the left. | `Ctrl + Left Arrow`<br />`Cmd + Left Arrow`<br />`Cmd + B` |
| Move the cursor one word to the right. | `Ctrl + Right Arrow`<br />`Cmd + Right Arrow`<br />`Cmd + F` |
#### Editing
| Action | Keys |
| ------------------------------------------------ | --------------------------------------------------------- |
| Delete from the cursor to the end of the line. | `Ctrl + K` |
| Delete from the cursor to the start of the line. | `Ctrl + U` |
| Clear all text in the input field. | `Ctrl + C` |
| Delete the previous word. | `Ctrl + Backspace`<br />`Cmd + Backspace`<br />`Ctrl + W` |
| Delete the next word. | `Ctrl + Delete`<br />`Cmd + Delete` |
| Delete the character to the left. | `Backspace`<br />`Ctrl + H` |
| Delete the character to the right. | `Delete`<br />`Ctrl + D` |
| Undo the most recent text edit. | `Ctrl + Z (no Shift)` |
| Redo the most recent undone text edit. | `Ctrl + Shift + Z` |
#### Scrolling
| Action | Keys |
| ------------------------ | -------------------- |
| Scroll content up. | `Shift + Up Arrow` |
| Scroll content down. | `Shift + Down Arrow` |
| Scroll to the top. | `Home` |
| Scroll to the bottom. | `End` |
| Scroll up by one page. | `Page Up` |
| Scroll down by one page. | `Page Down` |
#### History & Search
| Action | Keys |
| -------------------------------------------- | --------------------- |
| Show the previous entry in history. | `Ctrl + P (no Shift)` |
| 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` |
#### Navigation
| Action | Keys |
| -------------------------------- | ------------------------------------------- |
| Move selection up in lists. | `Up Arrow (no Shift)` |
| Move selection down in lists. | `Down Arrow (no Shift)` |
| Move up within dialog options. | `Up Arrow (no Shift)`<br />`K (no Shift)` |
| Move down within dialog options. | `Down Arrow (no Shift)`<br />`J (no Shift)` |
#### Suggestions & Completions
| Action | Keys |
| --------------------------------------- | -------------------------------------------------- |
| Accept the inline suggestion. | `Tab`<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` |
| Collapse an inline suggestion. | `Left Arrow` |
#### Text Input
| Action | Keys |
| ---------------------------------------------- | ---------------------------------------------------------------------- |
| Submit the current prompt. | `Enter (no Ctrl, no Shift, no Cmd)` |
| Insert a newline without submitting. | `Ctrl + Enter`<br />`Cmd + Enter`<br />`Shift + Enter`<br />`Ctrl + J` |
| Open the current prompt in an external editor. | `Ctrl + X` |
| Paste from the clipboard. | `Ctrl + V`<br />`Cmd + V` |
#### App Controls
| Action | Keys |
| ------------------------------------------------------------------------------------------------ | ---------------- |
| Toggle detailed error information. | `F12` |
| Toggle the full TODO list. | `Ctrl + T` |
| Show IDE context details. | `Ctrl + G` |
| Toggle Markdown rendering. | `Cmd + M` |
| Toggle copy mode when in alternate buffer mode. | `Ctrl + S` |
| Toggle YOLO (auto-approval) mode for tool calls. | `Ctrl + Y` |
| Toggle Auto Edit (auto-accept edits) mode. | `Shift + Tab` |
| Expand a height-constrained response to show additional lines when not in alternate buffer mode. | `Ctrl + S` |
| Focus the shell input from the gemini input. | `Tab (no Shift)` |
| Focus the Gemini input from the shell input. | `Tab` |
| Clear the terminal screen and redraw the UI. | `Ctrl + L` |
| Restart the application. | `R` |
<!-- KEYBINDINGS-AUTOGEN:END -->
## Additional context-specific shortcuts
- `Option+B/F/M` (macOS only): Are interpreted as `Cmd+B/F/M` even if your
terminal isn't configured to send Meta with Option.
- `!` on an empty prompt: Enter or exit shell mode.
- `\` (at end of a line) + `Enter`: Insert a newline without leaving single-line
mode.
- `Esc` pressed twice quickly: Browse and rewind previous interactions.
- `Up Arrow` / `Down Arrow`: When the cursor is at the top or bottom of a
single-line input, navigate backward or forward through prompt history.
- `Number keys (1-9, multi-digit)` inside selection dialogs: Jump directly to
the numbered radio option and confirm when the full number is entered.
-5
View File
@@ -17,11 +17,6 @@ policies.
may prompt you to switch to a fallback model (by default always prompts
you).
Some internal utility calls (such as prompt completion and classification)
use a silent fallback chain for `gemini-2.5-flash-lite` and will fall back
to `gemini-2.5-flash` and `gemini-2.5-pro` without prompting or changing the
configured model.
3. **Model switch:** If approved, or if the policy allows for silent fallback,
the CLI will use an available fallback model for the current turn or the
remainder of the session.
+15 -6
View File
@@ -19,18 +19,27 @@ Use the following command in Gemini CLI:
Running this command will open a dialog with your options:
| Option | Description | Models |
| ----------------- | -------------------------------------------------------------- | -------------------------------------------- |
| Auto (Gemini 3) | Let the system choose the best Gemini 3 model for your task. | gemini-3-pro-preview, gemini-3-flash-preview |
| Auto (Gemini 2.5) | Let the system choose the best Gemini 2.5 model for your task. | gemini-2.5-pro, gemini-2.5-flash |
| Manual | Select a specific model. | Any available model. |
| Option | Description | Models |
| ----------------- | -------------------------------------------------------------- | ---------------------------------------------------------------------- |
| Auto (Gemini 3) | Let the system choose the best Gemini 3 model for your task. | gemini-3-pro-preview (if enabled), gemini-3-flash-preview (if enabled) |
| Auto (Gemini 2.5) | Let the system choose the best Gemini 2.5 model for your task. | gemini-2.5-pro, gemini-2.5-flash |
| Manual | Select a specific model. | Any available model. |
We recommend selecting one of the above **Auto** options. However, you can
select **Manual** to select a specific model from those available.
### Gemini 3 and preview features
> **Note:** Gemini 3 is not currently available on all account types. To learn
> more about Gemini 3 access, refer to
> [Gemini 3 on Gemini CLI](../get-started/gemini-3.md).
To enable Gemini 3 Pro and Gemini 3 Flash (if available), enable
[**Preview Features** by using the `settings` command](../cli/settings.md).
You can also use the `--model` flag to specify a particular Gemini model on
startup. For more details, refer to the
[configuration documentation](../reference/configuration.md).
[configuration documentation](../get-started/configuration.md).
Changes to these settings will be applied to all subsequent interactions with
Gemini CLI.
-313
View File
@@ -1,313 +0,0 @@
# Plan Mode (experimental)
Plan Mode is a read-only environment for architecting robust solutions before
implementation. It allows you to:
- **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:
>
> - [Open an issue](https://github.com/google-gemini/gemini-cli/issues) on
> GitHub.
> - Use the **/bug** command within Gemini CLI to file an issue.
- [Enabling Plan Mode](#enabling-plan-mode)
- [How to use Plan Mode](#how-to-use-plan-mode)
- [Entering Plan Mode](#entering-plan-mode)
- [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)
- [Automatic Model Routing](#automatic-model-routing)
## Enabling Plan Mode
To use Plan Mode, enable it via **/settings** (search for **Plan**) or add the
following to your `settings.json`:
```json
{
"experimental": {
"plan": true
}
}
```
## How to use Plan Mode
### 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
{
"general": {
"defaultApprovalMode": "plan"
}
}
```
- **Keyboard Shortcut:** Press `Shift+Tab` to cycle through approval modes
(`Default` -> `Auto-Edit` -> `Plan`).
> **Note:** Plan Mode is automatically removed from the rotation when Gemini
> CLI is actively processing or showing confirmation dialogs.
- **Command:** Type `/plan` in the input box.
- **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].
### Planning Workflow
Plan Mode uses an adaptive planning workflow where the research depth, plan
structure, and consultation level are proportional to the task's complexity:
1. **Explore & Analyze:** Analyze requirements and use read-only tools to map
affected modules and identify dependencies.
2. **Consult:** The depth of consultation is proportional to the task's
complexity:
- **Simple Tasks:** Proceed directly to drafting.
- **Standard Tasks:** Present a summary of viable approaches via
[`ask_user`] for selection.
- **Complex Tasks:** Present detailed trade-offs for at least two viable
approaches via [`ask_user`] and obtain approval before drafting.
3. **Draft:** Write a detailed implementation plan to the
[plans directory](#custom-plan-directory-and-policies). The plan's structure
adapts to the task:
- **Simple Tasks:** Focused on specific **Changes** and **Verification**
steps.
- **Standard Tasks:** Includes an **Objective**, **Key Files & Context**,
**Implementation Steps**, and **Verification & Testing**.
- **Complex Tasks:** Comprehensive plans including **Background &
Motivation**, **Scope & Impact**, **Proposed Solution**, **Alternatives
Considered**, a phased **Implementation Plan**, **Verification**, and
**Migration & Rollback** strategies.
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.
- **Refine manually:** Press **Ctrl + X** to open the plan file in your
[preferred external editor]. This allows you to manually refine the plan
steps before approval. If you make any changes and save the file, the CLI
will automatically send the updated plan back to the agent for review and
iteration.
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, you can:
- **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
Plan Mode enforces strict safety policies to prevent accidental changes.
These are the only allowed tools:
- **FileSystem (Read):** [`read_file`], [`list_directory`], [`glob`]
- **Search:** [`grep_search`], [`google_web_search`]
- **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 or your
[custom plans directory](#custom-plan-directory-and-policies).
- **Memory:** [`save_memory`]
- **Skills:** [`activate_skill`] (allows loading specialized instructions and
resources in a read-only manner)
### Customizing Planning with Skills
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 Gemini CLI to look for specific
vulnerabilities during codebase exploration.
- A **"Frontend Design"** skill could guide Gemini CLI to use specific UI
components and accessibility standards in its proposal.
To use a skill in Plan Mode, you can explicitly ask Gemini CLI to "use the
`<skill-name>` skill to plan..." or Gemini CLI may autonomously activate it
based on the task description.
### Customizing Policies
Plan Mode's default tool restrictions are managed by the [policy engine] and
defined in the built-in [`plan.toml`] file. The built-in policy (Tier 1)
enforces the read-only state, but you can customize these rules by creating your
own policies in your `~/.gemini/policies/` directory (Tier 2).
#### Example: Automatically approve read-only MCP tools
By default, read-only MCP tools require user confirmation in Plan Mode. You can
use `toolAnnotations` and the `mcpName` wildcard to customize this behavior for
your specific environment.
`~/.gemini/policies/mcp-read-only.toml`
```toml
[[rule]]
mcpName = "*"
toolAnnotations = { readOnlyHint = true }
decision = "allow"
priority = 100
modes = ["plan"]
```
#### Example: Allow git commands in Plan Mode
This rule allows you to check the repository status and see changes while in
Plan Mode.
`~/.gemini/policies/git-research.toml`
```toml
[[rule]]
toolName = "run_shell_command"
commandPrefix = ["git status", "git diff"]
decision = "allow"
priority = 100
modes = ["plan"]
```
#### Example: Enable research subagents in Plan Mode
You can enable experimental research [subagents] like `codebase_investigator` to
help gather architecture details during the planning phase.
`~/.gemini/policies/research-subagents.toml`
```toml
[[rule]]
toolName = "codebase_investigator"
decision = "allow"
priority = 100
modes = ["plan"]
```
Tell Gemini CLI it can use these tools in your prompt, for example: _"You can
check ongoing changes in git."_
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\""
```
## Automatic Model Routing
When using an [**auto model**], Gemini CLI automatically optimizes [**model
routing**] based on the current phase of your task:
1. **Planning Phase:** While in Plan Mode, the CLI routes requests to a
high-reasoning **Pro** model to ensure robust architectural decisions and
high-quality plans.
2. **Implementation Phase:** Once a plan is approved and you exit Plan Mode,
the CLI detects the existence of the approved plan and automatically
switches to a high-speed **Flash** model. This provides a faster, more
responsive experience during the implementation of the plan.
This behavior is enabled by default to provide the best balance of quality and
performance. You can disable this automatic switching in your settings:
```json
{
"general": {
"plan": {
"modelRouting": false
}
}
}
```
[`list_directory`]: /docs/tools/file-system.md#1-list_directory-readfolder
[`read_file`]: /docs/tools/file-system.md#2-read_file-readfile
[`grep_search`]: /docs/tools/file-system.md#5-grep_search-searchtext
[`write_file`]: /docs/tools/file-system.md#3-write_file-writefile
[`glob`]: /docs/tools/file-system.md#4-glob-findfiles
[`google_web_search`]: /docs/tools/web-search.md
[`replace`]: /docs/tools/file-system.md#6-replace-edit
[MCP tools]: /docs/tools/mcp-server.md
[`save_memory`]: /docs/tools/memory.md
[`activate_skill`]: /docs/cli/skills.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
[`plan.toml`]:
https://github.com/google-gemini/gemini-cli/blob/main/packages/core/src/policy/policies/plan.toml
[auto model]: /docs/reference/configuration.md#model-settings
[model routing]: /docs/cli/telemetry.md#model-routing
[preferred external editor]: /docs/reference/configuration.md#general
-51
View File
@@ -1,51 +0,0 @@
# Rewind
The `/rewind` command lets you go back to a previous state in your conversation
and, optionally, revert any file changes made by the AI during those
interactions. This is a powerful tool for undoing mistakes, exploring different
approaches, or simply cleaning up your session history.
## Usage
To use the rewind feature, simply type `/rewind` into the input prompt and press
**Enter**.
Alternatively, you can use the keyboard shortcut: **Press `Esc` twice**.
## Interface
When you trigger a rewind, an interactive list of your previous interactions
appears.
1. **Select interaction:** Use the **Up/Down arrow keys** to navigate through
the list. The most recent interactions are at the bottom.
2. **Preview:** As you select an interaction, you'll see a preview of the user
prompt and, if applicable, the number of files changed during that step.
3. **Confirm selection:** Press **Enter** on the interaction you want to rewind
back to.
4. **Action selection:** After selecting an interaction, you'll be presented
with a confirmation dialog with up to three options:
- **Rewind conversation and revert code changes:** Reverts both the chat
history and the file modifications to the state before the selected
interaction.
- **Rewind conversation:** Only reverts the chat history. File changes are
kept.
- **Revert code changes:** Only reverts the file modifications. The chat
history is kept.
- **Do nothing (esc):** Cancels the rewind operation.
If no code changes were made since the selected point, the options related to
reverting code changes will be hidden.
## Key considerations
- **Destructive action:** Rewinding is a destructive action for your current
session history and potentially your files. Use it with care.
- **Agent awareness:** When you rewind the conversation, the AI model loses all
memory of the interactions that were removed. If you only revert code changes,
you may need to inform the model that the files have changed.
- **Manual edits:** Rewinding only affects file changes made by the AI's edit
tools. It does **not** undo manual edits you've made or changes triggered by
the shell tool (`!`).
- **Compression:** Rewind works across chat compression points by reconstructing
the history from stored session data.
+7 -48
View File
@@ -55,27 +55,12 @@ from your organization's registry.
```bash
# Enable sandboxing with command flag
gemini -s -p "analyze the code structure"
```
**Use environment variable**
**macOS/Linux**
```bash
# Use environment variable
export GEMINI_SANDBOX=true
gemini -p "run the test suite"
```
**Windows (PowerShell)**
```powershell
$env:GEMINI_SANDBOX="true"
gemini -p "run the test suite"
```
**Configure in settings.json**
```json
# Configure in settings.json
{
"tools": {
"sandbox": "docker"
@@ -97,11 +82,10 @@ gemini -p "run the test suite"
Built-in profiles (set via `SEATBELT_PROFILE` env var):
- `permissive-open` (default): Write restrictions, network allowed
- `permissive-closed`: Write restrictions, no network
- `permissive-proxied`: Write restrictions, network via proxy
- `restrictive-open`: Strict restrictions, network allowed
- `restrictive-proxied`: Strict restrictions, network via proxy
- `strict-open`: Read and write restrictions, network allowed
- `strict-proxied`: Read and write restrictions, network via proxy
- `restrictive-closed`: Maximum restrictions
### Custom sandbox flags
@@ -114,51 +98,26 @@ use cases.
To disable SELinux labeling for volume mounts, you can set the following:
**macOS/Linux**
```bash
export SANDBOX_FLAGS="--security-opt label=disable"
```
**Windows (PowerShell)**
```powershell
$env:SANDBOX_FLAGS="--security-opt label=disable"
```
Multiple flags can be provided as a space-separated string:
**macOS/Linux**
```bash
export SANDBOX_FLAGS="--flag1 --flag2=value"
```
**Windows (PowerShell)**
```powershell
$env:SANDBOX_FLAGS="--flag1 --flag2=value"
```
## Linux UID/GID handling
The sandbox automatically handles user permissions on Linux. Override these
permissions with:
**macOS/Linux**
```bash
export SANDBOX_SET_UID_GID=true # Force host UID/GID
export SANDBOX_SET_UID_GID=false # Disable UID/GID mapping
```
**Windows (PowerShell)**
```powershell
$env:SANDBOX_SET_UID_GID="true" # Force host UID/GID
$env:SANDBOX_SET_UID_GID="false" # Disable UID/GID mapping
```
## Troubleshooting
### Common issues
@@ -207,6 +166,6 @@ gemini -s -p "run shell command: mount | grep workspace"
## Related documentation
- [Configuration](../reference/configuration.md): Full configuration options.
- [Commands](../reference/commands.md): Available commands.
- [Troubleshooting](../resources/troubleshooting.md): General troubleshooting.
- [Configuration](../get-started/configuration.md): Full configuration options.
- [Commands](./commands.md): Available commands.
- [Troubleshooting](../troubleshooting.md): General troubleshooting.
+44 -61
View File
@@ -1,36 +1,32 @@
# Session management
# Session Management
Session management saves your conversation history so you can resume your work
where you left off. Use these features to review past interactions, manage
history across different projects, and configure how long data is retained.
Gemini CLI includes robust session management features that automatically save
your conversation history. This allows you to interrupt your work and resume
exactly where you left off, review past interactions, and manage your
conversation history effectively.
## Automatic saving
## Automatic Saving
Your session history is recorded automatically as you interact with the model.
This background process ensures your work is preserved even if you interrupt a
session.
Every time you interact with Gemini CLI, your session is automatically saved.
This happens in the background without any manual intervention.
- **What is saved:** The complete conversation history, including:
- Your prompts and the model's responses.
- All tool executions (inputs and outputs).
- Token usage statistics (input, output, cached, etc.).
- Assistant thoughts and reasoning summaries (when available).
- **Location:** Sessions are stored in `~/.gemini/tmp/<project_hash>/chats/`,
where `<project_hash>` is a unique identifier based on your project's root
directory.
- Token usage statistics (input/output/cached, etc.).
- Assistant thoughts/reasoning summaries (when available).
- **Location:** Sessions are stored in `~/.gemini/tmp/<project_hash>/chats/`.
- **Scope:** Sessions are project-specific. Switching directories to a different
project switches to that project's session history.
project will switch to that project's session history.
## Resuming sessions
## Resuming Sessions
You can resume a previous session to continue the conversation with all prior
context restored. Resuming is supported both through command-line flags and an
interactive browser.
context restored.
### From the command line
### From the Command Line
When starting Gemini CLI, use the `--resume` (or `-r`) flag to load existing
sessions.
When starting the CLI, you can use the `--resume` (or `-r`) flag:
- **Resume latest:**
@@ -40,8 +36,8 @@ sessions.
This immediately loads the most recent session.
- **Resume by index:** List available sessions first (see
[Listing sessions](#listing-sessions)), then use the index number:
- **Resume by index:** First, list available sessions (see
[Listing Sessions](#listing-sessions)), then use the index number:
```bash
gemini --resume 1
@@ -52,35 +48,30 @@ sessions.
gemini --resume a1b2c3d4-e5f6-7890-abcd-ef1234567890
```
### From the interactive interface
### From the Interactive Interface
While the CLI is running, use the `/resume` slash command to open the **Session
Browser**:
While the CLI is running, you can use the `/resume` slash command to open the
**Session Browser**:
```text
/resume
```
The Session Browser provides an interactive interface where you can perform the
following actions:
This opens an interactive interface where you can:
- **Browse:** Scroll through a list of your past sessions.
- **Preview:** See details like the session date, message count, and the first
user prompt.
- **Search:** Press `/` to enter search mode, then type to filter sessions by ID
or content.
- **Select:** Press **Enter** to resume the selected session.
- **Esc:** Press **Esc** to exit the Session Browser.
- **Select:** Press `Enter` to resume the selected session.
## Managing sessions
## Managing Sessions
You can list and delete sessions to keep your history organized and manage disk
space.
### Listing sessions
### Listing Sessions
To see a list of all available sessions for the current project from the command
line, use the `--list-sessions` flag:
line:
```bash
gemini --list-sessions
@@ -96,12 +87,12 @@ Available sessions for this project (3):
3. Update documentation (Just now) [abcd1234]
```
### Deleting sessions
### Deleting Sessions
You can remove old or unwanted sessions to free up space or declutter your
history.
**From the command line:** Use the `--delete-session` flag with an index or ID:
**From the Command Line:** Use the `--delete-session` flag with an index or ID:
```bash
gemini --delete-session 2
@@ -111,18 +102,17 @@ gemini --delete-session 2
1. Open the browser with `/resume`.
2. Navigate to the session you want to remove.
3. Press **x**.
3. Press `x`.
## Configuration
You can configure how Gemini CLI manages your session history in your
`settings.json` file. These settings let you control retention policies and
session lengths.
`settings.json` file.
### Session retention
### Session Retention
To prevent your history from growing indefinitely, enable automatic cleanup
policies in your settings.
To prevent your history from growing indefinitely, you can enable automatic
cleanup policies.
```json
{
@@ -136,20 +126,20 @@ policies in your settings.
}
```
- **`enabled`**: (boolean) Master switch for session cleanup. Defaults to
- **`enabled`**: (boolean) Master switch for session cleanup. Default is
`false`.
- **`maxAge`**: (string) Duration to keep sessions (for example, "24h", "7d",
"4w"). Sessions older than this are deleted.
- **`maxAge`**: (string) Duration to keep sessions (e.g., "24h", "7d", "4w").
Sessions older than this will be deleted.
- **`maxCount`**: (number) Maximum number of sessions to retain. The oldest
sessions exceeding this count are deleted.
sessions exceeding this count will be deleted.
- **`minRetention`**: (string) Minimum retention period (safety limit). Defaults
to `"1d"`. Sessions newer than this period are never deleted by automatic
to `"1d"`; sessions newer than this period are never deleted by automatic
cleanup.
### Session limits
### Session Limits
You can limit the length of individual sessions to prevent context windows from
becoming too large and expensive.
You can also limit the length of individual sessions to prevent context windows
from becoming too large and expensive.
```json
{
@@ -159,17 +149,10 @@ becoming too large and expensive.
}
```
- **`maxSessionTurns`**: (number) The maximum number of turns (user and model
- **`maxSessionTurns`**: (number) The maximum number of turns (user + model
exchanges) allowed in a single session. Set to `-1` for unlimited (default).
**Behavior when limit is reached:**
- **Interactive mode:** The CLI shows an informational message and stops
- **Interactive Mode:** The CLI shows an informational message and stops
sending requests to the model. You must manually start a new session.
- **Non-interactive mode:** The CLI exits with an error.
## Next steps
- Explore the [Memory tool](../tools/memory.md) to save persistent information
across sessions.
- Learn how to [Checkpoint](./checkpointing.md) your session state.
- Check out the [CLI reference](./cli-reference.md) for all command-line flags.
- **Non-Interactive Mode:** The CLI exits with an error.
+73 -107
View File
@@ -22,18 +22,14 @@ 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 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` |
| Plan Model Routing | `general.plan.modelRouting` | Automatically switch between Pro and Flash models based on Plan Mode status. Uses Pro for the planning phase and Flash for the implementation phase. | `true` |
| Max Chat Model Attempts | `general.maxAttempts` | Maximum number of attempts for requests to the main chat model. Cannot exceed 10. | `10` |
| Debug Keystroke Logging | `general.debugKeystrokeLogging` | Enable debug logging of keystrokes to the console. | `false` |
| Enable Session Cleanup | `general.sessionRetention.enabled` | Enable automatic session cleanup | `true` |
| Keep chat history | `general.sessionRetention.maxAge` | Automatically delete chats older than this time period (e.g., "30d", "7d", "24h", "1w") | `"30d"` |
| UI Label | Setting | Description | Default |
| ------------------------------- | ---------------------------------- | ------------------------------------------------------------- | ------- |
| Preview Features (e.g., models) | `general.previewFeatures` | Enable preview features (e.g., preview models). | `false` |
| Vim Mode | `general.vimMode` | Enable Vim keybindings | `false` |
| 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` |
### Output
@@ -43,37 +39,29 @@ 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` |
| 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"` |
| Error Verbosity | `ui.errorVerbosity` | Controls whether recoverable errors are hidden (low) or fully shown (full). | `"low"` |
| Screen Reader Mode | `ui.accessibility.screenReader` | Render output in plain-text to be more screen reader accessible | `false` |
| UI Label | Setting | Description | Default |
| ------------------------------ | --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
| Hide Window Title | `ui.hideWindowTitle` | Hide the window title bar | `false` |
| 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` |
| 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` |
| Use Full Width | `ui.useFullWidth` | Use the entire width of the terminal for output. | `true` |
| Use Alternate Screen Buffer | `ui.useAlternateBuffer` | Use an alternate screen buffer for the UI, preserving shell history. | `false` |
| 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` |
| 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` |
### IDE
@@ -81,85 +69,63 @@ they appear in the UI.
| -------- | ------------- | ---------------------------- | ------- |
| IDE Mode | `ide.enabled` | Enable IDE integration mode. | `false` |
### Billing
| UI Label | Setting | Description | Default |
| ---------------- | ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
| Overage Strategy | `billing.overageStrategy` | How to handle quota exhaustion when AI credits are available. 'ask' prompts each time, 'always' automatically uses credits, 'never' disables credit usage. | `"ask"` |
### Model
| UI Label | Setting | Description | Default |
| ----------------------- | ---------------------------- | -------------------------------------------------------------------------------------- | ----------- |
| Model | `model.name` | The Gemini model to use for conversations. | `undefined` |
| Max Session Turns | `model.maxSessionTurns` | Maximum number of user/model/tool turns to keep in a session. -1 means unlimited. | `-1` |
| Compression Threshold | `model.compressionThreshold` | The fraction of context usage at which to trigger context compression (e.g. 0.2, 0.3). | `0.5` |
| Disable Loop Detection | `model.disableLoopDetection` | Disable automatic detection and prevention of infinite loops. | `false` |
| Skip Next Speaker Check | `model.skipNextSpeakerCheck` | Skip the next speaker check. | `true` |
| UI Label | Setting | Description | Default |
| ----------------------- | ---------------------------- | -------------------------------------------------------------------------------------- | ------- |
| Max Session Turns | `model.maxSessionTurns` | Maximum number of user/model/tool turns to keep in a session. -1 means unlimited. | `-1` |
| Compression Threshold | `model.compressionThreshold` | The fraction of context usage at which to trigger context compression (e.g. 0.2, 0.3). | `0.5` |
| Skip Next Speaker Check | `model.skipNextSpeakerCheck` | Skip the next speaker check. | `true` |
### Context
| UI Label | Setting | Description | Default |
| ------------------------------------ | ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
| Memory Discovery Max Dirs | `context.discoveryMaxDirs` | Maximum number of directories to search for memory. | `200` |
| Load Memory From Include Directories | `context.loadMemoryFromIncludeDirectories` | Controls how /memory refresh loads GEMINI.md files. When true, include directories are scanned; when false, only the current directory is used. | `false` |
| Respect .gitignore | `context.fileFiltering.respectGitIgnore` | Respect .gitignore files when searching. | `true` |
| Respect .geminiignore | `context.fileFiltering.respectGeminiIgnore` | Respect .geminiignore files when searching. | `true` |
| Enable Recursive File Search | `context.fileFiltering.enableRecursiveFileSearch` | Enable recursive file search functionality when completing @ references in the prompt. | `true` |
| Enable Fuzzy Search | `context.fileFiltering.enableFuzzySearch` | Enable fuzzy search when searching for files. | `true` |
| Custom Ignore File Paths | `context.fileFiltering.customIgnoreFilePaths` | Additional ignore file paths to respect. These files take precedence over .geminiignore and .gitignore. Files earlier in the array take precedence over files later in the array, e.g. the first file takes precedence over the second one. | `[]` |
| UI Label | Setting | Description | Default |
| ------------------------------------ | ------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
| Memory Discovery Max Dirs | `context.discoveryMaxDirs` | Maximum number of directories to search for memory. | `200` |
| Load Memory From Include Directories | `context.loadMemoryFromIncludeDirectories` | Controls how /memory refresh loads GEMINI.md files. When true, include directories are scanned; when false, only the current directory is used. | `false` |
| Respect .gitignore | `context.fileFiltering.respectGitIgnore` | Respect .gitignore files when searching. | `true` |
| Respect .geminiignore | `context.fileFiltering.respectGeminiIgnore` | Respect .geminiignore files when searching. | `true` |
| Enable Recursive File Search | `context.fileFiltering.enableRecursiveFileSearch` | Enable recursive file search functionality when completing @ references in the prompt. | `true` |
| Enable Fuzzy Search | `context.fileFiltering.enableFuzzySearch` | Enable fuzzy search when searching for files. | `true` |
### Tools
| UI Label | Setting | Description | Default |
| -------------------------------- | ------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
| Enable Interactive Shell | `tools.shell.enableInteractiveShell` | Use node-pty for an interactive shell experience. Fallback to child_process still applies. | `true` |
| Show Color | `tools.shell.showColor` | Show color in shell output. | `false` |
| Use Ripgrep | `tools.useRipgrep` | Use ripgrep for file content search instead of the fallback implementation. Provides faster search performance. | `true` |
| Tool Output Truncation Threshold | `tools.truncateToolOutputThreshold` | Maximum characters to show when truncating large tool outputs. Set to 0 or negative to disable truncation. | `40000` |
| Disable LLM Correction | `tools.disableLLMCorrection` | Disable LLM-based error correction for edit tools. When enabled, tools will fail immediately if exact string matches are not found, instead of attempting to self-correct. | `true` |
| UI Label | Setting | Description | Default |
| -------------------------------- | ------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- |
| Enable Interactive Shell | `tools.shell.enableInteractiveShell` | Use node-pty for an interactive shell experience. Fallback to child_process still applies. | `true` |
| Show Color | `tools.shell.showColor` | Show color in shell output. | `false` |
| Auto Accept | `tools.autoAccept` | Automatically accept and execute tool calls that are considered safe (e.g., read-only operations). | `false` |
| Use Ripgrep | `tools.useRipgrep` | Use ripgrep for file content search instead of the fallback implementation. Provides faster search performance. | `true` |
| Enable Tool Output Truncation | `tools.enableToolOutputTruncation` | Enable truncation of large tool outputs. | `true` |
| Tool Output Truncation Threshold | `tools.truncateToolOutputThreshold` | Truncate tool output if it is larger than this many characters. Set to -1 to disable. | `4000000` |
| Tool Output Truncation Lines | `tools.truncateToolOutputLines` | The number of lines to keep when truncating tool output. | `1000` |
| Disable LLM Correction | `tools.disableLLMCorrection` | Disable LLM-based error correction for edit tools. When enabled, tools will fail immediately if exact string matches are not found, instead of attempting to self-correct. | `false` |
### Security
| UI Label | Setting | Description | Default |
| ------------------------------------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------- |
| Disable YOLO Mode | `security.disableYoloMode` | Disable YOLO mode, even if enabled by a flag. | `false` |
| Allow Permanent Tool Approval | `security.enablePermanentToolApproval` | Enable the "Allow for all future sessions" option in tool confirmation dialogs. | `false` |
| Blocks extensions from Git | `security.blockGitExtensions` | Blocks installing and loading extensions from Git. | `false` |
| Extension Source Regex Allowlist | `security.allowedExtensions` | List of Regex patterns for allowed extensions. If nonempty, only extensions that match the patterns in this list are allowed. Overrides the blockGitExtensions setting. | `[]` |
| Folder Trust | `security.folderTrust.enabled` | Setting to track whether Folder trust is enabled. | `true` |
| Enable Environment Variable Redaction | `security.environmentVariableRedaction.enabled` | Enable redaction of environment variables that may contain secrets. | `false` |
| Enable Context-Aware Security | `security.enableConseca` | Enable the context-aware security checker. This feature uses an LLM to dynamically generate and enforce security policies for tool use based on your prompt, providing an additional layer of protection against unintended actions. | `false` |
### Advanced
| UI Label | Setting | Description | Default |
| --------------------------------- | ------------------------------ | --------------------------------------------- | ------- |
| Auto Configure Max Old Space Size | `advanced.autoConfigureMemory` | Automatically configure Node.js memory limits | `false` |
| UI Label | Setting | Description | Default |
| ------------------------------------- | ----------------------------------------------- | ------------------------------------------------------------------------------- | ------- |
| Disable YOLO Mode | `security.disableYoloMode` | Disable YOLO mode, even if enabled by a flag. | `false` |
| Allow Permanent Tool Approval | `security.enablePermanentToolApproval` | Enable the "Allow for all future sessions" option in tool confirmation dialogs. | `false` |
| Blocks extensions from Git | `security.blockGitExtensions` | Blocks installing and loading extensions from Git. | `false` |
| Folder Trust | `security.folderTrust.enabled` | Setting to track whether Folder trust is enabled. | `false` |
| Enable Environment Variable Redaction | `security.environmentVariableRedaction.enabled` | Enable redaction of environment variables that may contain secrets. | `false` |
### 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 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` |
| Direct Web Fetch | `experimental.directWebFetch` | Enable web fetch behavior that bypasses LLM summarization. | `false` |
| Enable Gemma Model Router | `experimental.gemmaModelRouter.enabled` | Enable the Gemma Model Router. Requires a local endpoint serving Gemma via the Gemini API using LiteRT-LM shim. | `false` |
| UI Label | Setting | Description | Default |
| ----------------------------------- | ------------------------------------------------------- | ----------------------------------------------------------------------------------- | ------- |
| Agent Skills | `experimental.skills` | Enable Agent Skills (experimental). | `false` |
| Enable Codebase Investigator | `experimental.codebaseInvestigatorSettings.enabled` | Enable the Codebase Investigator agent. | `true` |
| Codebase Investigator Max Num Turns | `experimental.codebaseInvestigatorSettings.maxNumTurns` | Maximum number of turns for the Codebase Investigator agent. | `10` |
| Use OSC 52 Paste | `experimental.useOSC52Paste` | Use OSC 52 sequence for pasting instead of clipboardy (useful for remote sessions). | `false` |
| Enable CLI Help Agent | `experimental.cliHelpAgentSettings.enabled` | Enable the CLI Help Agent. | `true` |
| Plan | `experimental.plan` | Enable planning features (Plan Mode and tools). | `false` |
### Skills
### Hooks
| UI Label | Setting | Description | Default |
| ------------------- | ---------------- | -------------------- | ------- |
| Enable Agent Skills | `skills.enabled` | Enable Agent Skills. | `true` |
### HooksConfig
| UI Label | Setting | Description | Default |
| ------------------ | --------------------------- | -------------------------------------------------------------------------------- | ------- |
| Enable Hooks | `hooksConfig.enabled` | Canonical toggle for the hooks system. When disabled, no hooks will be executed. | `true` |
| Hook Notifications | `hooksConfig.notifications` | Show visual indicators when hooks are executing. | `true` |
| UI Label | Setting | Description | Default |
| ------------------ | --------------------- | ------------------------------------------------ | ------- |
| Hook Notifications | `hooks.notifications` | Show visual indicators when hooks are executing. | `true` |
<!-- SETTINGS-AUTOGEN:END -->
+88 -34
View File
@@ -1,5 +1,9 @@
# Agent Skills
_Note: This is an experimental feature enabled via `experimental.skills`. You
can also search for "Skills" within the `/settings` interactive UI to toggle
this and manage other skill-related settings._
Agent Skills allow you to extend Gemini CLI with specialized expertise,
procedural workflows, and task-specific resources. Based on the
[Agent Skills](https://agentskills.io) open standard, a "skill" is a
@@ -35,22 +39,16 @@ the full instructions and resources required to complete the task using the
Gemini CLI discovers skills from three primary locations:
1. **Workspace Skills**: Located in `.gemini/skills/` or the `.agents/skills/`
alias. Workspace skills are typically committed to version control and
shared with the team.
2. **User Skills**: Located in `~/.gemini/skills/` or the `~/.agents/skills/`
alias. These are personal skills available across all your workspaces.
1. **Workspace Skills** (`.gemini/skills/`): Workspace-specific skills that are
typically committed to version control and shared with the team.
2. **User Skills** (`~/.gemini/skills/`): Personal skills available across all
your workspaces.
3. **Extension Skills**: Skills bundled within installed
[extensions](../extensions/index.md).
**Precedence:** If multiple skills share the same name, higher-precedence
locations override lower ones: **Workspace > User > Extension**.
Within the same tier (user or workspace), the `.agents/skills/` alias takes
precedence over the `.gemini/skills/` directory. This generic alias provides an
intuitive path for managing agent-specific expertise that remains compatible
across different AI agent tools.
## Managing Skills
### In an Interactive Session
@@ -58,7 +56,6 @@ across different AI agent tools.
Use the `/skills` slash command to view and manage available expertise:
- `/skills list` (default): Shows all discovered skills and their status.
- `/skills link <path>`: Links agent skills from a local directory via symlink.
- `/skills disable <name>`: Prevents a specific skill from being used.
- `/skills enable <name>`: Re-enables a disabled skill.
- `/skills reload`: Refreshes the list of discovered skills from all tiers.
@@ -74,16 +71,8 @@ The `gemini skills` command provides management utilities:
# List all discovered skills
gemini skills list
# Link agent skills from a local directory via symlink
# Discovers skills (SKILL.md or */SKILL.md) and creates symlinks in ~/.gemini/skills
# (or ~/.agents/skills)
gemini skills link /path/to/my-skills-repo
# Link to the workspace scope (.gemini/skills or .agents/skills)
gemini skills link /path/to/my-skills-repo --scope workspace
# Install a skill from a Git repository, local directory, or zipped skill file (.skill)
# Uses the user scope by default (~/.gemini/skills or ~/.agents/skills)
# Uses the user scope by default (~/.gemini/skills)
gemini skills install https://github.com/user/repo.git
gemini skills install /path/to/local/skill
gemini skills install /path/to/local/my-expertise.skill
@@ -91,7 +80,7 @@ gemini skills install /path/to/local/my-expertise.skill
# Install a specific skill from a monorepo or subdirectory using --path
gemini skills install https://github.com/my-org/my-skills.git --path skills/frontend-design
# Install to the workspace scope (.gemini/skills or .agents/skills)
# Install to the workspace scope (.gemini/skills)
gemini skills install /path/to/skill --scope workspace
# Uninstall a skill by name
@@ -104,7 +93,84 @@ gemini skills enable my-expertise
gemini skills disable my-expertise --scope workspace
```
## How it Works
## Creating a Skill
A skill is a directory containing a `SKILL.md` file at its root. This file uses
YAML frontmatter for metadata and Markdown for instructions.
### Folder Structure
Skills are self-contained directories. At a minimum, a skill requires a
`SKILL.md` file, but can include other resources:
```text
my-skill/
├── SKILL.md (Required) Instructions and metadata
├── scripts/ (Optional) Executable scripts/tools
├── references/ (Optional) Static documentation and examples
└── assets/ (Optional) Templates and binary resources
```
### Basic Structure (SKILL.md)
```markdown
---
name: <unique-name>
description: <what the skill does and when Gemini should use it>
---
<your instructions for how the agent should behave / use the skill>
```
- **`name`**: A unique identifier (lowercase, alphanumeric, and dashes).
- **`description`**: The most critical field. Gemini uses this to decide when
the skill is relevant. Be specific about the expertise provided.
- **Body**: Everything below the second `---` is injected as expert procedural
guidance for the model.
### Example: Team Code Reviewer
Create `~/.gemini/skills/code-reviewer/SKILL.md`:
```markdown
---
name: code-reviewer
description:
Expertise in reviewing code for style, security, and performance. Use when the
user asks for "feedback," a "review," or to "check" their changes.
---
# Code Reviewer
You are an expert code reviewer. When reviewing code, follow this workflow:
1. **Analyze**: Review the staged changes or specific files provided. Ensure
that the changes are scoped properly and represent minimal changes required
to address the issue.
2. **Style**: Ensure code follows the workspace's conventions and idiomatic
patterns as described in the `GEMINI.md` file.
3. **Security**: Flag any potential security vulnerabilities.
4. **Tests**: Verify that new logic has corresponding test coverage and that
the test coverage adequately validates the changes.
Provide your feedback as a concise bulleted list of "Strengths" and
"Opportunities."
```
### Resource Conventions
While you can structure your skill directory however you like, the Agent Skills
standard encourages these conventions:
- **`scripts/`**: Executable scripts (bash, python, node) the agent can run.
- **`references/`**: Static documentation, schemas, or example data for the
agent to consult.
- **`assets/`**: Code templates, boilerplate, or binary resources.
When a skill is activated, Gemini CLI provides the model with a tree view of the
entire skill directory, allowing it to discover and utilize these assets.
## How it Works (Security & Privacy)
1. **Discovery**: At the start of a session, Gemini CLI scans the discovery
tiers and injects the name and description of all enabled skills into the
@@ -120,15 +186,3 @@ gemini skills disable my-expertise --scope workspace
it permission to read any bundled assets.
5. **Execution**: The model proceeds with the specialized expertise active. It
is instructed to prioritize the skill's procedural guidance within reason.
### Skill activation
Once a skill is activated (typically by Gemini identifying a task that matches
the skill's description and your approval), its specialized instructions and
resources are loaded into the agent's context. A skill remains active and its
guidance is prioritized for the duration of the session.
## Creating your own skills
To create your own skills, see the [Create Agent Skills](./creating-skills.md)
guide.
-32
View File
@@ -56,38 +56,6 @@ error with: `missing system prompt file '<path>'`.
When `GEMINI_SYSTEM_MD` is active, the CLI shows a `|⌐■_■|` indicator in the UI
to signal custom systemprompt mode.
## Variable Substitution
When using a custom system prompt file, you can use the following variables to
dynamically include built-in content:
- `${AgentSkills}`: Injects a complete section (including header) of all
available agent skills.
- `${SubAgents}`: Injects a complete section (including header) of available
sub-agents.
- `${AvailableTools}`: Injects a bulleted list of all currently enabled tool
names.
- Tool Name Variables: Injects the actual name of a tool using the pattern:
`${toolName}_ToolName` (e.g., `${write_file_ToolName}`,
`${run_shell_command_ToolName}`).
This pattern is generated dynamically for all available tools.
### Example
```markdown
# Custom System Prompt
You are a helpful assistant. ${AgentSkills}
${SubAgents}
## Tooling
The following tools are available to you: ${AvailableTools}
You can use ${write_file_ToolName} to save logs.
```
## Export the default prompt (recommended)
Before overriding, export the current default prompt so you can review required
+16 -127
View File
@@ -18,7 +18,6 @@ Learn how to enable and setup OpenTelemetry for Gemini CLI.
- [Logs and metrics](#logs-and-metrics)
- [Logs](#logs)
- [Sessions](#sessions)
- [Approval Mode](#approval-mode)
- [Tools](#tools)
- [Files](#files)
- [API](#api)
@@ -93,7 +92,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](../reference/configuration.md).
[Configuration guide](../get-started/configuration.md).
## Google Cloud telemetry
@@ -103,52 +102,23 @@ Before using either method below, complete these steps:
1. Set your Google Cloud project ID:
- For telemetry in a separate project from inference:
**macOS/Linux**
```bash
export OTLP_GOOGLE_CLOUD_PROJECT="your-telemetry-project-id"
```
**Windows (PowerShell)**
```powershell
$env:OTLP_GOOGLE_CLOUD_PROJECT="your-telemetry-project-id"
```
- For telemetry in the same project as inference:
**macOS/Linux**
```bash
export GOOGLE_CLOUD_PROJECT="your-project-id"
```
**Windows (PowerShell)**
```powershell
$env:GOOGLE_CLOUD_PROJECT="your-project-id"
```
2. Authenticate with Google Cloud:
- If using a user account:
```bash
gcloud auth application-default login
```
- If using a service account:
**macOS/Linux**
```bash
export GOOGLE_APPLICATION_CREDENTIALS="/path/to/your/service-account.json"
```
**Windows (PowerShell)**
```powershell
$env:GOOGLE_APPLICATION_CREDENTIALS="C:\path\to\your\service-account.json"
```
3. Make sure your account or service account has these IAM roles:
- Cloud Trace Agent
- Monitoring Metric Writer
@@ -205,12 +175,11 @@ Sends telemetry directly to Google Cloud services. No collector needed.
}
```
2. Run Gemini CLI and send prompts.
3. View logs, metrics, and traces:
3. View logs and metrics:
- Open the Google Cloud Console in your browser after sending prompts:
- Logs (Logs Explorer): https://console.cloud.google.com/logs/
- Metrics (Metrics Explorer):
https://console.cloud.google.com/monitoring/metrics-explorer
- Traces (Trace Explorer): https://console.cloud.google.com/traces/list
- Logs: https://console.cloud.google.com/logs/
- Metrics: https://console.cloud.google.com/monitoring/metrics-explorer
- Traces: https://console.cloud.google.com/traces/list
### Collector-based export (advanced)
@@ -238,12 +207,11 @@ forward data to Google Cloud.
- Save collector logs to `~/.gemini/tmp/<projectHash>/otel/collector-gcp.log`
- Stop collector on exit (e.g. `Ctrl+C`)
3. Run Gemini CLI and send prompts.
4. View logs, metrics, and traces:
4. View logs and metrics:
- Open the Google Cloud Console in your browser after sending prompts:
- Logs (Logs Explorer): https://console.cloud.google.com/logs/
- Metrics (Metrics Explorer):
https://console.cloud.google.com/monitoring/metrics-explorer
- Traces (Trace Explorer): https://console.cloud.google.com/traces/list
- Logs: https://console.cloud.google.com/logs/
- Metrics: https://console.cloud.google.com/monitoring/metrics-explorer
- Traces: https://console.cloud.google.com/traces/list
- Open `~/.gemini/tmp/<projectHash>/otel/collector-gcp.log` to view local
collector logs.
@@ -301,14 +269,14 @@ For local development and debugging, you can capture telemetry data locally:
3. View traces at http://localhost:16686 and logs/metrics in the collector log
file.
## Logs, metrics, and traces
## Logs and metrics
The following section describes the structure of logs, metrics, and traces
generated for Gemini CLI.
The following section describes the structure of logs and metrics generated for
Gemini CLI.
The `session.id`, `installation.id`, `active_approval_mode`, and `user.email`
(available only when authenticated with a Google account) are included as common
attributes on all logs and metrics.
The `session.id`, `installation.id`, and `user.email` (available only when
authenticated with a Google account) are included as common attributes on all
logs and metrics.
### Logs
@@ -347,31 +315,6 @@ Captures startup configuration and user prompt submissions.
- `prompt` (string; excluded if `telemetry.logPrompts` is `false`)
- `auth_type` (string)
#### Approval Mode
Tracks changes and duration of approval modes.
##### Lifecycle
- `approval_mode_switch`: Approval mode was changed.
- **Attributes**:
- `from_mode` (string)
- `to_mode` (string)
- `approval_mode_duration`: Duration spent in an approval mode.
- **Attributes**:
- `mode` (string)
- `duration_ms` (int)
##### Execution
These events track the execution of an approval mode, such as Plan Mode.
- `plan_execution`: A plan was executed and the session switched from plan mode
to active execution.
- **Attributes**:
- `approval_mode` (string)
#### Tools
Captures tool executions, output truncation, and Edit behavior.
@@ -391,21 +334,7 @@ Captures tool executions, output truncation, and Edit behavior.
- `extension_name` (string, if applicable)
- `extension_id` (string, if applicable)
- `content_length` (int, if applicable)
- `metadata` (if applicable), which includes for the `AskUser` tool:
- `ask_user` (object):
- `question_types` (array of strings)
- `ask_user_dismissed` (boolean)
- `ask_user_empty_submission` (boolean)
- `ask_user_answer_count` (number)
- `diffStat` (if applicable), which includes:
- `model_added_lines` (number)
- `model_removed_lines` (number)
- `model_added_chars` (number)
- `model_removed_chars` (number)
- `user_added_lines` (number)
- `user_removed_lines` (number)
- `user_added_chars` (number)
- `user_removed_chars` (number)
- `metadata` (if applicable)
- `gemini_cli.tool_output_truncated`: Output of a tool call was truncated.
- **Attributes**:
@@ -518,7 +447,6 @@ Captures Gemini API requests, responses, and errors.
- `reasoning` (string, optional)
- `failed` (boolean)
- `error_message` (string, optional)
- `approval_mode` (string)
#### Chat and streaming
@@ -743,14 +671,12 @@ Routing latency/failures and slash-command selections.
- **Attributes**:
- `routing.decision_model` (string)
- `routing.decision_source` (string)
- `routing.approval_mode` (string)
- `gemini_cli.model_routing.failure.count` (Counter, Int): Counts model routing
failures.
- **Attributes**:
- `routing.decision_source` (string)
- `routing.error_message` (string)
- `routing.approval_mode` (string)
##### Agent runs
@@ -769,17 +695,6 @@ Agent lifecycle metrics: runs, durations, and turns.
- **Attributes**:
- `agent_name` (string)
##### Approval Mode
###### Execution
These metrics track the adoption and usage of specific approval workflows, such
as Plan Mode.
- `gemini_cli.plan.execution.count` (Counter, Int): Counts plan executions.
- **Attributes**:
- `approval_mode` (string)
##### UI
UI stability signals such as flicker count.
@@ -855,32 +770,6 @@ Optional performance monitoring for startup, CPU/memory, and phase timing.
- `current_value` (number)
- `baseline_value` (number)
### Traces
Traces offer a granular, "under-the-hood" view of every agent and backend
operation. By providing a high-fidelity execution map, they enable precise
debugging of complex tool interactions and deep performance optimization. Each
trace captures rich, consistent metadata via custom span attributes:
- `gen_ai.operation.name` (string): The high-level operation kind (e.g.
"tool_call", "llm_call").
- `gen_ai.agent.name` (string): The service agent identifier ("gemini-cli").
- `gen_ai.agent.description` (string): The service agent description.
- `gen_ai.input.messages` (string): Input messages or metadata specific to the
operation.
- `gen_ai.output.messages` (string): Output messages or metadata generated from
the operation.
- `gen_ai.request.model` (string): The request model name.
- `gen_ai.response.model` (string): The response model name.
- `gen_ai.system_instructions` (json string): The system instructions.
- `gen_ai.prompt.name` (string): The prompt name.
- `gen_ai.tool.name` (string): The executed tool's name.
- `gen_ai.tool.call_id` (string): The generated specific ID of the tool call.
- `gen_ai.tool.description` (string): The executed tool's description.
- `gen_ai.tool.definitions` (json string): The executed tool's description.
- `gen_ai.conversation.id` (string): The current CLI session ID.
- Additional user-defined Custom Attributes passed via the span's configuration.
#### GenAI semantic convention
The following metrics comply with [OpenTelemetry GenAI semantic conventions] for
+53 -87
View File
@@ -16,14 +16,12 @@ using the `/theme` command within Gemini CLI:
- `Default`
- `Dracula`
- `GitHub`
- `Solarized Dark`
- **Light themes:**
- `ANSI Light`
- `Ayu Light`
- `Default Light`
- `GitHub Light`
- `Google Code`
- `Solarized Light`
- `Xcode`
### Changing themes
@@ -41,22 +39,22 @@ can change the theme using the `/theme` command.
### Theme persistence
Selected themes are saved in Gemini CLI's
[configuration](../reference/configuration.md) so your preference is remembered
across sessions.
[configuration](../get-started/configuration.md) so your preference is
remembered across sessions.
---
## Custom color themes
Gemini CLI lets you create your own custom color themes by specifying them in
your `settings.json` file. This gives you full control over the color palette
Gemini CLI allows you to create your own custom color themes by specifying them
in your `settings.json` file. This gives you full control over the color palette
used in the CLI.
### How to define a custom theme
Add a `customThemes` block to your user, project, or system `settings.json`
file. Each custom theme is defined as an object with a unique name and a set of
nested configuration objects. For example:
color keys. For example:
```json
{
@@ -65,52 +63,50 @@ nested configuration objects. For example:
"MyCustomTheme": {
"name": "MyCustomTheme",
"type": "custom",
"background": {
"primary": "#181818"
},
"text": {
"primary": "#f0f0f0",
"secondary": "#a0a0a0"
}
"Background": "#181818",
...
}
}
}
}
```
**Configuration objects:**
**Color keys:**
- **`text`**: Defines text colors.
- `primary`: The default text color.
- `secondary`: Used for less prominent text.
- `link`: Color for URLs and links.
- `accent`: Used for highlights and emphasis.
- `response`: Precedence over `primary` for rendering model responses.
- **`background`**: Defines background colors.
- `primary`: The main background color of the UI.
- `diff.added`: Background for added lines in diffs.
- `diff.removed`: Background for removed lines in diffs.
- **`border`**: Defines border colors.
- `default`: The standard border color.
- `focused`: Border color when an element is focused.
- **`status`**: Colors for status indicators.
- `success`: Used for successful operations.
- `warning`: Used for warnings.
- `error`: Used for errors.
- **`ui`**: Other UI elements.
- `comment`: Color for code comments.
- `symbol`: Color for code symbols and operators.
- `gradient`: An array of colors used for gradient effects.
- `Background`
- `Foreground`
- `LightBlue`
- `AccentBlue`
- `AccentPurple`
- `AccentCyan`
- `AccentGreen`
- `AccentYellow`
- `AccentRed`
- `Comment`
- `Gray`
- `DiffAdded` (optional, for added lines in diffs)
- `DiffRemoved` (optional, for removed lines in diffs)
You can also override individual UI text roles by adding a nested `text` object.
This object supports the keys `primary`, `secondary`, `link`, `accent`, and
`response`. When `text.response` is provided it takes precedence over
`text.primary` for rendering model responses in chat.
**Required properties:**
- `name` (must match the key in the `customThemes` object and be a string)
- `type` (must be the string `"custom"`)
While all sub-properties are technically optional, we recommend providing at
least `background.primary`, `text.primary`, `text.secondary`, and the various
accent colors via `text.link`, `text.accent`, and `status` to ensure a cohesive
UI.
- `Background`
- `Foreground`
- `LightBlue`
- `AccentBlue`
- `AccentPurple`
- `AccentCyan`
- `AccentGreen`
- `AccentYellow`
- `AccentRed`
- `Comment`
- `Gray`
You can use either hex codes (e.g., `#FF0000`) **or** standard CSS color names
(e.g., `coral`, `teal`, `blue`) for any color value. See
@@ -145,35 +141,22 @@ custom theme defined in `settings.json`.
```json
{
"name": "Gruvbox Dark",
"name": "My File Theme",
"type": "custom",
"background": {
"primary": "#282828",
"diff": {
"added": "#2b3312",
"removed": "#341212"
}
},
"text": {
"primary": "#ebdbb2",
"secondary": "#a89984",
"link": "#83a598",
"accent": "#d3869b"
},
"border": {
"default": "#3c3836",
"focused": "#458588"
},
"status": {
"success": "#b8bb26",
"warning": "#fabd2f",
"error": "#fb4934"
},
"ui": {
"comment": "#928374",
"symbol": "#8ec07c",
"gradient": ["#cc241d", "#d65d0e", "#d79921"]
}
"Background": "#282A36",
"Foreground": "#F8F8F2",
"LightBlue": "#82AAFF",
"AccentBlue": "#61AFEF",
"AccentPurple": "#BD93F9",
"AccentCyan": "#8BE9FD",
"AccentGreen": "#50FA7B",
"AccentYellow": "#F1FA8C",
"AccentRed": "#FF5555",
"Comment": "#6272A4",
"Gray": "#ABB2BF",
"DiffAdded": "#A6E3A1",
"DiffRemoved": "#F38BA8",
"GradientColors": ["#4796E4", "#847ACE", "#C3677F"]
}
```
@@ -194,18 +177,9 @@ 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](../reference/configuration.md) as other
same [configuration precedence](../get-started/configuration.md) as other
settings.
### Themes from extensions
[Extensions](../extensions/reference.md#themes) can also provide custom themes.
Once an extension is installed and enabled, its themes are automatically added
to the selection list in the `/theme` command.
Themes from extensions appear with the extension name in parentheses to help you
identify their source, for example: `shades-of-green (green-extension)`.
---
## Dark themes
@@ -234,10 +208,6 @@ identify their source, for example: `shades-of-green (green-extension)`.
<img src="/assets/theme-github.png" alt="GitHub theme" width="600">
### Solarized Dark
<img src="/assets/theme-solarized-dark.png" alt="Solarized Dark theme" width="600">
## Light themes
### ANSI Light
@@ -260,10 +230,6 @@ identify their source, for example: `shades-of-green (green-extension)`.
<img src="/assets/theme-google-light.png" alt="Google Code theme" width="600">
### Solarized Light
<img src="/assets/theme-solarized-light.png" alt="Solarized Light theme" width="600">
### Xcode
<img src="/assets/theme-xcode-light.png" alt="Xcode Light theme" width="600">
-31
View File
@@ -38,37 +38,6 @@ 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"
+87
View File
@@ -0,0 +1,87 @@
# Tutorials
This page contains tutorials for interacting with Gemini CLI.
## Agent Skills
- [Getting Started with Agent Skills](./tutorials/skills-getting-started.md)
## Setting up a Model Context Protocol (MCP) server
> [!CAUTION] Before using a third-party MCP server, ensure you trust its source
> and understand the tools it provides. Your use of third-party servers is at
> your own risk.
This tutorial demonstrates how to set up an MCP server, using the
[GitHub MCP server](https://github.com/github/github-mcp-server) as an example.
The GitHub MCP server provides tools for interacting with GitHub repositories,
such as creating issues and commenting on pull requests.
### Prerequisites
Before you begin, ensure you have the following installed and configured:
- **Docker:** Install and run [Docker].
- **GitHub Personal Access Token (PAT):** Create a new [classic] or
[fine-grained] PAT with the necessary scopes.
[Docker]: https://www.docker.com/
[classic]: https://github.com/settings/tokens/new
[fine-grained]: https://github.com/settings/personal-access-tokens/new
### Guide
#### Configure the MCP server in `settings.json`
In your project's root directory, create or open the
[`.gemini/settings.json` file](../get-started/configuration.md). Within the
file, add the `mcpServers` configuration block, which provides instructions for
how to launch the GitHub MCP server.
```json
{
"mcpServers": {
"github": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-e",
"GITHUB_PERSONAL_ACCESS_TOKEN",
"ghcr.io/github/github-mcp-server"
],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_PERSONAL_ACCESS_TOKEN}"
}
}
}
}
```
#### Set your GitHub token
> [!CAUTION] Using a broadly scoped personal access token that has access to
> personal and private repositories can lead to information from the private
> repository being leaked into the public repository. We recommend using a
> fine-grained access token that doesn't share access to both public and private
> repositories.
Use an environment variable to store your GitHub PAT:
```bash
GITHUB_PERSONAL_ACCESS_TOKEN="pat_YourActualGitHubTokenHere"
```
Gemini CLI uses this value in the `mcpServers` configuration that you defined in
the `settings.json` file.
#### Launch Gemini CLI and verify the connection
When you launch Gemini CLI, it automatically reads your configuration and
launches the GitHub MCP server in the background. You can then use natural
language prompts to ask Gemini CLI to perform GitHub actions. For example:
```bash
"get all open issues assigned to me in the 'foo/bar' repo and prioritize them"
```
-283
View File
@@ -1,283 +0,0 @@
# Automate tasks with headless mode
Automate tasks with Gemini CLI. Learn how to use headless mode, pipe data into
Gemini CLI, automate workflows with shell scripts, and generate structured JSON
output for other applications.
## Prerequisites
- Gemini CLI installed and authenticated.
- Familiarity with shell scripting (Bash/Zsh).
## Why headless mode?
Headless mode runs Gemini CLI once and exits. It's perfect for:
- **CI/CD:** Analyzing pull requests automatically.
- **Batch processing:** Summarizing a large number of log files.
- **Tool building:** Creating your own "AI wrapper" scripts.
## How to use headless mode
Run Gemini CLI in headless mode by providing a prompt as a positional argument.
This bypasses the interactive chat interface and prints the response to standard
output (stdout).
Run a single command:
```bash
gemini "Write a poem about TypeScript"
```
## How to pipe input to Gemini CLI
Feed data into Gemini using the standard Unix pipe `|`. Gemini reads the
standard input (stdin) as context and answers your question using standard
output.
Pipe a file:
**macOS/Linux**
```bash
cat error.log | gemini "Explain why this failed"
```
**Windows (PowerShell)**
```powershell
Get-Content error.log | gemini "Explain why this failed"
```
Pipe a command:
```bash
git diff | gemini "Write a commit message for these changes"
```
## Use Gemini CLI output in scripts
Because Gemini prints to stdout, you can chain it with other tools or save the
results to a file.
### Scenario: Bulk documentation generator
You have a folder of Python scripts and want to generate a `README.md` for each
one.
1. Save the following code as `generate_docs.sh` (or `generate_docs.ps1` for
Windows):
**macOS/Linux (`generate_docs.sh`)**
```bash
#!/bin/bash
# Loop through all Python files
for file in *.py; do
echo "Generating docs for $file..."
# Ask Gemini CLI to generate the documentation and print it to stdout
gemini "Generate a Markdown documentation summary for @$file. Print the
result to standard output." > "${file%.py}.md"
done
```
**Windows PowerShell (`generate_docs.ps1`)**
```powershell
# Loop through all Python files
Get-ChildItem -Filter *.py | ForEach-Object {
Write-Host "Generating docs for $($_.Name)..."
$newName = $_.Name -replace '\.py$', '.md'
# Ask Gemini CLI to generate the documentation and print it to stdout
gemini "Generate a Markdown documentation summary for @$($_.Name). Print the result to standard output." | Out-File -FilePath $newName -Encoding utf8
}
```
2. Make the script executable and run it in your directory:
**macOS/Linux**
```bash
chmod +x generate_docs.sh
./generate_docs.sh
```
**Windows (PowerShell)**
```powershell
.\generate_docs.ps1
```
This creates a corresponding Markdown file for every Python file in the
folder.
## Extract structured JSON data
When writing a script, you often need structured data (JSON) to pass to tools
like `jq`. To get pure JSON data from the model, combine the
`--output-format json` flag with `jq` to parse the response field.
### Scenario: Extract and return structured data
1. Save the following script as `generate_json.sh` (or `generate_json.ps1` for
Windows):
**macOS/Linux (`generate_json.sh`)**
```bash
#!/bin/bash
# Ensure we are in a project root
if [ ! -f "package.json" ]; then
echo "Error: package.json not found."
exit 1
fi
# Extract data
gemini --output-format json "Return a raw JSON object with keys 'version' and 'deps' from @package.json" | jq -r '.response' > data.json
```
**Windows PowerShell (`generate_json.ps1`)**
```powershell
# Ensure we are in a project root
if (-not (Test-Path "package.json")) {
Write-Error "Error: package.json not found."
exit 1
}
# Extract data (requires jq installed, or you can use ConvertFrom-Json)
$output = gemini --output-format json "Return a raw JSON object with keys 'version' and 'deps' from @package.json" | ConvertFrom-Json
$output.response | Out-File -FilePath data.json -Encoding utf8
```
2. Run the script:
**macOS/Linux**
```bash
chmod +x generate_json.sh
./generate_json.sh
```
**Windows (PowerShell)**
```powershell
.\generate_json.ps1
```
3. Check `data.json`. The file should look like this:
```json
{
"version": "1.0.0",
"deps": {
"react": "^18.2.0"
}
}
```
## Build your own custom AI tools
Use headless mode to perform custom, automated AI tasks.
### Scenario: Create a "Smart Commit" alias
You can add a function to your shell configuration to create a `git commit`
wrapper that writes the message for you.
**macOS/Linux (Bash/Zsh)**
1. Open your `.zshrc` file (or `.bashrc` if you use Bash) in your preferred
text editor.
```bash
nano ~/.zshrc
```
**Note**: If you use VS Code, you can run `code ~/.zshrc`.
2. Scroll to the very bottom of the file and paste this code:
```bash
function gcommit() {
# Get the diff of staged changes
diff=$(git diff --staged)
if [ -z "$diff" ]; then
echo "No staged changes to commit."
return 1
fi
# Ask Gemini to write the message
echo "Generating commit message..."
msg=$(echo "$diff" | gemini "Write a concise Conventional Commit message for this diff. Output ONLY the message.")
# Commit with the generated message
git commit -m "$msg"
}
```
Save your file and exit.
3. Run this command to make the function available immediately:
```bash
source ~/.zshrc
```
**Windows (PowerShell)**
1. Open your PowerShell profile in your preferred text editor.
```powershell
notepad $PROFILE
```
2. Scroll to the very bottom of the file and paste this code:
```powershell
function gcommit {
# Get the diff of staged changes
$diff = git diff --staged
if (-not $diff) {
Write-Host "No staged changes to commit."
return
}
# Ask Gemini to write the message
Write-Host "Generating commit message..."
$msg = $diff | gemini "Write a concise Conventional Commit message for this diff. Output ONLY the message."
# Commit with the generated message
git commit -m "$msg"
}
```
Save your file and exit.
3. Run this command to make the function available immediately:
```powershell
. $PROFILE
```
4. Use your new command:
```bash
gcommit
```
Gemini CLI will analyze your staged changes and commit them with a generated
message.
## Next steps
- Explore the [Headless mode reference](../../cli/headless.md) for full JSON
schema details.
- Learn about [Shell commands](shell-commands.md) to let the agent run scripts
instead of just writing them.
-142
View File
@@ -1,142 +0,0 @@
# File management with Gemini CLI
Explore, analyze, and modify your codebase using Gemini CLI. In this guide,
you'll learn how to provide Gemini CLI with files and directories, modify and
create files, and control what Gemini CLI can see.
## Prerequisites
- Gemini CLI installed and authenticated.
- A project directory to work with (e.g., a git repository).
## How to give the agent context (Reading files)
Gemini CLI will generally try to read relevant files, sometimes prompting you
for access (depending on your settings). To ensure that Gemini CLI uses a file,
you can also include it directly.
### Direct file inclusion (`@`)
If you know the path to the file you want to work on, use the `@` symbol. This
forces the CLI to read the file immediately and inject its content into your
prompt.
```bash
`@src/components/UserProfile.tsx Explain how this component handles user data.`
```
### Working with multiple files
Complex features often span multiple files. You can chain `@` references to give
the agent a complete picture of the dependencies.
```bash
`@src/components/UserProfile.tsx @src/types/User.ts Refactor the component to use the updated User interface.`
```
### Including entire directories
For broad questions or refactoring, you can include an entire directory. Be
careful with large folders, as this consumes more tokens.
```bash
`@src/utils/ Check these utility functions for any deprecated API usage.`
```
## How to find files (Exploration)
If you _don't_ know the exact file path, you can ask Gemini CLI to find it for
you. This is useful when navigating a new codebase or looking for specific
logic.
### Scenario: Find a component definition
You know there's a `UserProfile` component, but you don't know where it lives.
```none
`Find the file that defines the UserProfile component.`
```
Gemini uses the `glob` or `list_directory` tools to search your project
structure. It will return the specific path (e.g.,
`src/components/UserProfile.tsx`), which you can then use with `@` in your next
turn.
> **Tip:** You can also ask for lists of files, like "Show me all the TypeScript
> configuration files in the root directory."
## How to modify code
Once Gemini CLI has context, you can direct it to make specific edits. The agent
is capable of complex refactoring, not just simple text replacement.
```none
`Update @src/components/UserProfile.tsx to show a loading spinner if the user data is null.`
```
Gemini CLI uses the `replace` tool to propose a targeted code change.
### Creating new files
You can also ask the agent to create entirely new files or folder structures.
```none
`Create a new file @src/components/LoadingSpinner.tsx with a simple Tailwind CSS spinner.`
```
Gemini CLI uses the `write_file` tool to generate the new file from scratch.
## Review and confirm changes
Gemini CLI prioritizes safety. Before any file is modified, it presents a
unified diff of the proposed changes.
```diff
- if (!user) return null;
+ if (!user) return <LoadingSpinner />;
```
- **Red lines (-):** Code that will be removed.
- **Green lines (+):** Code that will be added.
Press **y** to confirm and apply the change to your local file system. If the
diff doesn't look right, press **n** to cancel and refine your prompt.
## Verify the result
After the edit is complete, verify the fix. You can simply read the file again
or, better yet, run your project's tests.
```none
`Run the tests for the UserProfile component.`
```
Gemini CLI uses the `run_shell_command` tool to execute your test runner (e.g.,
`npm test` or `jest`). This ensures the changes didn't break existing
functionality.
## Advanced: Controlling what Gemini sees
By default, Gemini CLI respects your `.gitignore` file. It won't read or search
through `node_modules`, build artifacts, or other ignored paths.
If you have sensitive files (like `.env`) or large assets that you want to keep
hidden from the AI _without_ ignoring them in Git, you can create a
`.geminiignore` file in your project root.
**Example `.geminiignore`:**
```text
.env
local-db-dump.sql
private-notes.md
```
## Next steps
- Learn how to [Manage context and memory](memory-management.md) to keep your
agent smarter over long sessions.
- See [Execute shell commands](shell-commands.md) for more on running tests and
builds.
- Explore the technical [File system reference](../../tools/file-system.md) for
advanced tool parameters.
-113
View File
@@ -1,113 +0,0 @@
# Set up an MCP server
Connect Gemini CLI to your external databases and services. In this guide,
you'll learn how to extend Gemini CLI's capabilities by installing the GitHub
MCP server and using it to manage your repositories.
## Prerequisites
- Gemini CLI installed.
- **Docker:** Required for this specific example (many MCP servers run as Docker
containers).
- **GitHub token:** A Personal Access Token (PAT) with repo permissions.
## How to prepare your credentials
Most MCP servers require authentication. For GitHub, you need a PAT.
1. Create a [fine-grained PAT](https://github.com/settings/tokens?type=beta).
2. Grant it **Read** access to **Metadata** and **Contents**, and
**Read/Write** access to **Issues** and **Pull Requests**.
3. Store it in your environment:
**macOS/Linux**
```bash
export GITHUB_PERSONAL_ACCESS_TOKEN="github_pat_..."
```
**Windows (PowerShell)**
```powershell
$env:GITHUB_PERSONAL_ACCESS_TOKEN="github_pat_..."
```
## How to configure Gemini CLI
You tell Gemini about new servers by editing your `settings.json`.
1. Open `~/.gemini/settings.json` (or the project-specific
`.gemini/settings.json`).
2. Add the `mcpServers` block. This tells Gemini: "Run this docker container
and talk to it."
```json
{
"mcpServers": {
"github": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-e",
"GITHUB_PERSONAL_ACCESS_TOKEN",
"ghcr.io/modelcontextprotocol/servers/github:latest"
],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_PERSONAL_ACCESS_TOKEN}"
}
}
}
}
```
> **Note:** The `command` is `docker`, and the rest are arguments passed to it.
> We map the local environment variable into the container so your secret isn't
> hardcoded in the config file.
## How to verify the connection
Restart Gemini CLI. It will automatically try to start the defined servers.
**Command:** `/mcp list`
You should see: `✓ github: docker ... - Connected`
If you see `Disconnected` or an error, check that Docker is running and your API
token is valid.
## How to use the new tools
Now that the server is running, the agent has new capabilities ("tools"). You
don't need to learn special commands; just ask in natural language.
### Scenario: Listing pull requests
**Prompt:** `List the open PRs in the google/gemini-cli repository.`
The agent will:
1. Recognize the request matches a GitHub tool.
2. Call `github_list_pull_requests`.
3. Present the data to you.
### Scenario: Creating an issue
**Prompt:**
`Create an issue in my repo titled "Bug: Login fails" with the description "See logs".`
## Troubleshooting
- **Server won't start?** Try running the docker command manually in your
terminal to see if it prints an error (e.g., "image not found").
- **Tools not found?** Run `/mcp refresh` to force the CLI to re-query the
server for its capabilities.
## Next steps
- Explore the [MCP servers reference](../../tools/mcp-server.md) to learn about
SSE and HTTP transports for remote servers.
- Browse the
[official MCP server list](https://github.com/modelcontextprotocol/servers) to
find connectors for Slack, Postgres, Google Drive, and more.

Some files were not shown because too many files have changed in this diff Show More