Compare commits

..

16 Commits

Author SHA1 Message Date
gemini-cli-robot e5161610ff chore(release): v0.11.3 2025-10-31 20:24:24 +00:00
Gaurav Ghosh 44b3c97486 refactor: simplify daily quota error messages 2025-10-31 11:11:19 -07:00
Sandy Tao b1bbef433d fix(core): ensure loop detection respects session disable flag (#12347) 2025-10-31 10:31:04 -07:00
Tommaso Sciortino 8a72585992 Mark model.compressionThreshold as requiring a restart (#12378) 2025-10-31 10:31:03 -07:00
Abhi 73b3211ea7 Remove context percentage in footer by default (#12326) 2025-10-31 10:31:02 -07:00
Tommaso Sciortino ce40a6534f Make compression threshold editable in the UI. (#12317) 2025-10-31 10:30:34 -07:00
Tommaso Sciortino 5be5575df0 Change default compression threshold (#12306) 2025-10-31 09:32:34 -07:00
Sandy Tao 847c6e7fd0 refactor(core): extract ChatCompressionService from GeminiClient (#12001) 2025-10-31 09:21:04 -07:00
gemini-cli-robot f4f3727936 chore(release): v0.11.2 2025-10-31 02:33:21 +00:00
gemini-cli-robot f36dec6ad4 fix(patch): cherry-pick 643f2c0 to release/v0.11.1-pr-12300 to patch version v0.11.1 and create version 0.11.2 (#12335)
Co-authored-by: Victor May <mayvic@google.com>
2025-10-30 19:20:45 -07:00
gemini-cli-robot 5213d9f3f9 chore(release): v0.11.1 2025-10-30 23:11:54 +00:00
gemini-cli-robot d9f6cebe1f fix(patch): cherry-pick ee92db7 to release/v0.11.0-pr-11624 to patch version v0.11.0 and create version 0.11.1 (#12321)
Co-authored-by: Gaurav <39389231+gsquared94@users.noreply.github.com>
2025-10-30 15:55:48 -07:00
gemini-cli-robot 92f5355d81 chore(release): v0.11.0 2025-10-29 01:17:14 +00:00
gemini-cli-robot c9c2e79dde chore(release): v0.11.0-preview.1 2025-10-28 22:56:55 +00:00
gemini-cli-robot a3947a8de5 fix(patch): cherry-pick 601a639 to release/v0.11.0-preview.0-pr-11889 to patch version v0.11.0-preview.0 and create version 0.11.0-preview.1 (#12188)
Co-authored-by: Victor May <mayvic@google.com>
Co-authored-by: matt korwel <matt.korwel@gmail.com>
2025-10-28 15:44:17 -07:00
gemini-cli-robot 9cf8b40349 chore(release): v0.11.0-preview.0 2025-10-22 17:11:36 +00:00
1395 changed files with 47226 additions and 189861 deletions
-29
View File
@@ -1,29 +0,0 @@
description="Injects context of all relevant cli files"
prompt = """
The following output contains the complete
source code of packages/core.
**Pay extremely close attention to these files.** They define the project's
core architecture, component patterns, and testing standards.
The source code contains the content of absolutely every source code file in
packages/core.
You should very rarely need to read any other files from packages/core to resolve
prompts.
!{find packages/core \\( -path packages/cli/dist -o -path packages/core/dist -o -name node_modules \\) -prune -o -type f \\( -name "*.ts" -o -name "*.tsx" \\) ! -name "*.test.ts" ! -name "*.test.tsx" ! -name "*.d.ts" -exec echo "--- {} ---" \\; -exec cat {} \\;}
In addition to the code context, you MUST strictly adhere to the following frontend-specific development guidelines when writing code in packages/core.
## 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.
## General
* **Logging**: Use `debugLogger` for errors. NEVER leave `console.log/warn/error` in the code.
* **TypeScript**: Avoid the non-null assertion operator (`!`).
{{args}}.
"""
-54
View File
@@ -1,54 +0,0 @@
description="Injects context of all relevant cli files"
prompt = """
The source code contains the content of absolutely every source code file in
packages/cli and key files from packages/core. In addition to the source code, the following test files are
included as they are test files that conform to the project's testing standards:
`packages/cli/src/ui/components/InputPrompt.test.tsx` and `packages/cli/src/ui/App.test.tsx`.
You should very rarely need to read any other files from packages/cli to resolve
prompts.
!{find packages/cli -path packages/cli/dist -prune -o -type f \\( -name "*.ts" -o -name "*.tsx" \\) ! -name "*.test.ts" ! -name "*.test.tsx" ! -name "*.d.ts" -exec echo "--- {} ---" \\; -exec cat {} \\; && echo "--- packages/cli/src/ui/components/InputPrompt.test.tsx ---" && cat packages/cli/src/ui/components/InputPrompt.test.tsx && echo "--- packages/cli/src/ui/App.test.tsx ---" && cat packages/cli/src/ui/App.test.tsx && echo "--- packages/core/src/core/coreToolScheduler.ts ---" && cat packages/core/src/core/coreToolScheduler.ts && echo "--- packages/core/src/core/nonInteractiveToolExecutor.ts ---" && cat packages/core/src/core/nonInteractiveToolExecutor.ts && echo "--- packages/core/src/confirmation-bus/message-bus.ts ---" && cat packages/core/src/confirmation-bus/message-bus.ts && echo "--- packages/core/src/confirmation-bus/types.ts ---" && cat packages/core/src/confirmation-bus/types.ts && echo "--- packages/core/src/utils/events.ts ---" && cat packages/core/src/utils/events.ts && echo "--- packages/core/src/core/client.ts ---" && cat packages/core/src/core/client.ts && echo "--- packages/core/src/core/geminiChat.ts ---" && cat packages/core/src/core/geminiChat.ts && echo "--- packages/core/src/core/turn.ts ---" && cat packages/core/src/core/turn.ts && echo "--- packages/core/src/agents/executor.ts ---" && cat packages/core/src/agents/executor.ts && echo "--- packages/core/src/telemetry/types.ts ---" && cat packages/core/src/telemetry/types.ts && echo "--- packages/core/src/telemetry/loggers.ts ---" && cat packages/core/src/telemetry/loggers.ts && echo "--- packages/core/src/telemetry/uiTelemetry.ts ---" && cat packages/core/src/telemetry/uiTelemetry.ts}
**Pay extremely close attention to these files.** They define the project's
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.
## 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}}.
"""
-57
View File
@@ -1,57 +0,0 @@
description="Injects context of all relevant cli files"
prompt = """
The following output contains the complete
source code of the gemini cli library (`packages/cli`), and {packages/core} and representative test files
(`packages/cli/src/ui/components/InputPrompt.test.tsx` and `packages/cli/src/ui/App.test.tsx`) that best conform to the project's testing standards.
**Pay extremely close attention to these files.** They define the project's
core architecture, component patterns, and testing standards.
The source code contains the content of absolutely every source code file in
packages/cli and packages/core. In addition to the source code, the following test files are
included as they are test files that conform to the project's testing standards:
`packages/cli/src/ui/components/InputPrompt.test.tsx` and `packages/cli/src/ui/App.test.tsx`.
You should very rarely need to read any other files from packages/cli to resolve
prompts.
!{find packages/cli packages/core \\( -path packages/cli/dist -o -path packages/core/dist -o -name node_modules \\) -prune -o -type f \\( -name "*.ts" -o -name "*.tsx" \\) ! -name "*.test.ts" ! -name "*.test.tsx" ! -name "*.d.ts" -exec echo "--- {} ---" \\; -exec cat {} \\; && echo "--- packages/cli/src/ui/components/InputPrompt.test.tsx ---" && cat packages/cli/src/ui/components/InputPrompt.test.tsx && echo "--- packages/cli/src/ui/App.test.tsx ---" && cat packages/cli/src/ui/App.test.tsx}
In addition to the code context, you MUST strictly adhere to the following frontend-specific development guidelines when writing code in packages/cli.
## 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}}.
"""
-16
View File
@@ -1,16 +0,0 @@
description = "Analyze the influence of system instructions on a specific action."
prompt = """
# Introspection Task
Take a step back and analyze your own system instructions and internal logic.
The user is curious about the reasoning behind a specific action or decision you've made.
**Specific point of interest:** {{args}}
Please provide a detailed breakdown of:
1. Which parts of your system instructions (global, workspace-specific, or provided via GEMINI.md) influenced this behavior?
2. What was your internal thought process leading up to this action?
3. Are there any ambiguities or conflicting instructions that played a role?
Your goal is to provide transparency into your underlying logic so the user can potentially improve the instructions in the future.
"""
-140
View File
@@ -1,140 +0,0 @@
description="Reviews a pull request based on issue number."
prompt = """
Please provide a detailed pull request review on GitHub issue: {{args}}.
Follow these steps:
1. Use `gh pr view {{args}}` to pull the information of the PR.
2. Use `gh pr diff {{args}}` to view the diff of the PR.
3. Understand the intent of the PR using the PR description.
4. If PR description is not detailed enough to understand the intent of the PR,
make sure to note it in your review.
5. Make sure the PR title follows Conventional Commits, here are the last five
commits to the repo as examples: !{git log --pretty=format:"%s" -n 5}
6. Search the codebase if required.
7. Write a concise review of the PR, keeping in mind to encourage strong code
quality and best practices. Pay particular attention to the Gemini MD file
in the repo.
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. 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.
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
GitHub-related tasks.
"""
-5
View File
@@ -1,5 +0,0 @@
{
"experimental": {
"skills": true
}
}
-57
View File
@@ -1,57 +0,0 @@
---
name: pr-creator
description:
Use this skill when asked to create a pull request (PR). It ensures all PRs
follow the repository's established templates and standards.
---
# Pull Request Creator
This skill guides the creation of high-quality Pull Requests that adhere to the
repository's standards.
## Workflow
Follow these steps to create a Pull Request:
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`).
2. **Read Template**: Read the content of the identified template file.
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
is not applicable, leave it unchecked or mark as `[ ]` (depending on the
template's instructions) or remove it if the template allows flexibility
(but prefer keeping it unchecked for transparency).
- **Content**: Fill in the sections with clear, concise summaries of your
changes.
- **Related Issues**: Link any issues fixed or related to this PR (e.g.,
"Fixes #123").
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
# 1. Write the drafted description to a temporary file
# 2. Create the PR using the --body-file flag
gh pr create --title "type(scope): succinct description" --body-file <temp_file_path>
# 3. Remove the temporary file
rm <temp_file_path>
```
- **Title**: Ensure the title follows the
[Conventional Commits](https://www.conventionalcommits.org/) format if the
repository uses it (e.g., `feat(ui): add new button`,
`fix(core): resolve crash`).
## Principles
- **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.
-3
View File
@@ -11,6 +11,3 @@
/.github/workflows/ @google-gemini/gemini-cli-askmode-approvers
/packages/cli/package.json @google-gemini/gemini-cli-askmode-approvers
/packages/core/package.json @google-gemini/gemini-cli-askmode-approvers
# Docs have a dedicated approver group in addition to maintainers
/docs/ @google-gemini/gemini-cli-maintainers @google-gemini/gemini-cli-docs
+3
View File
@@ -1,5 +1,8 @@
name: 'Bug Report'
description: 'Report a bug to help us improve Gemini CLI'
labels:
- 'kind/bug'
- 'status/need-triage'
body:
- type: 'markdown'
attributes:
+1 -1
View File
@@ -1,8 +1,8 @@
name: 'Feature Request'
description: 'Suggest an idea for this project'
labels:
- 'kind/enhancement'
- 'status/need-triage'
type: 'Feature'
body:
- type: 'markdown'
attributes:
+2 -1
View File
@@ -1,7 +1,8 @@
name: 'Website issue'
description: 'Report an issue with the Gemini CLI Website and Gemini CLI Extensions Gallery'
labels:
- 'area/extensions'
- 'area/website'
- 'status/need-triage'
body:
- type: 'markdown'
attributes:
+1 -2
View File
@@ -262,8 +262,7 @@ runs:
--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' || '' }}
--generate-notes
- name: '🧹 Clean up release branch'
working-directory: '${{ inputs.working-directory }}'
+1 -1
View File
@@ -75,4 +75,4 @@ runs:
gh issue create \
--title "Docker build failed" \
--body "The docker build failed. See the full run for details: ${DETAILS_URL}" \
--label "release-failure"
--label "kind/bug,release-failure"
+1 -1
View File
@@ -93,4 +93,4 @@ runs:
gh issue create \
--title "Docker build failed" \
--body "The docker build failed. See the full run for details: ${DETAILS_URL}" \
--label "release-failure"
--label "kind/bug,release-failure"
+20 -18
View File
@@ -1,33 +1,35 @@
# See https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
version: 2
updates:
- package-ecosystem: 'npm'
directory: '/'
schedule:
interval: 'weekly'
day: 'monday'
open-pull-requests-limit: 10
interval: 'daily'
target-branch: 'main'
commit-message:
prefix: 'chore(deps)'
include: 'scope'
reviewers:
- 'joshualitt'
- 'google-gemini/gemini-cli-askmode-approvers'
groups:
npm-dependencies:
patterns:
- '*'
# Group all non-major updates together.
# This is to reduce the number of PRs that need to be reviewed.
# Major updates will still be created as separate PRs.
npm-minor-patch:
applies-to: 'version-updates'
update-types:
- 'minor'
- 'patch'
open-pull-requests-limit: 0
- package-ecosystem: 'github-actions'
directory: '/'
schedule:
interval: 'weekly'
day: 'monday'
open-pull-requests-limit: 10
interval: 'daily'
target-branch: 'main'
commit-message:
prefix: 'chore(deps)'
include: 'scope'
reviewers:
- 'joshualitt'
groups:
actions-dependencies:
patterns:
- '*'
update-types:
- 'minor'
- 'patch'
- 'google-gemini/gemini-cli-askmode-approvers'
open-pull-requests-limit: 0
+31 -32
View File
@@ -1,42 +1,41 @@
## Summary
## TLDR
<!-- Concisely describe what this PR changes and why. Focus on impact and
urgency. -->
<!-- Add a brief description of what this pull request changes and why and any important things for reviewers to look at -->
## Details
## Dive Deeper
<!-- Add any extra context and design decisions. Keep it brief but complete. -->
<!-- more thoughts and in-depth discussion here -->
## Related Issues
## Reviewer Test Plan
<!-- Use keywords to auto-close issues (Closes #123, Fixes #456). If this PR is
only related to an issue or is a partial fix, simply reference the issue number
without a keyword (Related to #123). -->
<!-- when a person reviews your code they should ideally be pulling and running that code. How would they validate your change works and if relevant what are some good classes of example prompts and ways they can exercise your changes -->
## How to Validate
## Testing Matrix
<!-- List exact steps for reviewers to validate the change. Include commands,
expected results, and edge cases. -->
<!-- Before submitting please validate your changes on as many of these options as possible -->
## Pre-Merge Checklist
| | 🍏 | 🪟 | 🐧 |
| -------- | --- | --- | --- |
| npm run | ❓ | ❓ | ❓ |
| npx | ❓ | ❓ | ❓ |
| Docker | ❓ | ❓ | ❓ |
| Podman | ❓ | - | - |
| Seatbelt | ❓ | - | - |
<!-- Check all that apply before requesting review or merging. -->
## Linked issues / bugs
- [ ] Updated relevant documentation and README (if needed)
- [ ] Added/updated tests (if needed)
- [ ] Noted breaking changes (if any)
- [ ] Validated on required platforms/methods:
- [ ] MacOS
- [ ] npm run
- [ ] npx
- [ ] Docker
- [ ] Podman
- [ ] Seatbelt
- [ ] Windows
- [ ] npm run
- [ ] npx
- [ ] Docker
- [ ] Linux
- [ ] npm run
- [ ] npx
- [ ] Docker
<!--
Link to any related issues or bugs.
**If this PR fully resolves the issue, use one of the following keywords to automatically close the issue when this PR is merged:**
- Closes #<issue_number>
- Fixes #<issue_number>
- Resolves #<issue_number>
*Example: `Resolves #123`*
**If this PR is only related to an issue or is a partial fix, simply reference the issue number without a keyword:**
*Example: `This PR makes progress on #456` or `Related to #789`*
-->
-138
View File
@@ -1,138 +0,0 @@
/* eslint-disable */
/* global require, console, process */
/**
* Script to backfill the 'status/need-triage' label to all open issues
* that are NOT currently labeled with '🔒 maintainer only' or 'help wanted'.
*/
const { execFileSync } = require('child_process');
const isDryRun = process.argv.includes('--dry-run');
const REPO = 'google-gemini/gemini-cli';
/**
* Executes a GitHub CLI command safely using an argument array to prevent command injection.
* @param {string[]} args
* @returns {string|null}
*/
function runGh(args) {
try {
// Using execFileSync with an array of arguments is safe as it doesn't use a shell.
// We set a large maxBuffer (10MB) to handle repositories with many issues.
return execFileSync('gh', args, {
encoding: 'utf8',
maxBuffer: 10 * 1024 * 1024,
stdio: ['ignore', 'pipe', 'pipe'],
}).trim();
} catch (error) {
const stderr = error.stderr ? ` Stderr: ${error.stderr.trim()}` : '';
console.error(
`❌ Error running gh ${args.join(' ')}: ${error.message}${stderr}`,
);
return null;
}
}
async function main() {
console.log('🔐 GitHub CLI security check...');
const authStatus = runGh(['auth', 'status']);
if (authStatus === null) {
console.error('❌ GitHub CLI (gh) is not installed or not authenticated.');
process.exit(1);
}
if (isDryRun) {
console.log('🧪 DRY RUN MODE ENABLED - No changes will be made.\n');
}
console.log(`🔍 Fetching and filtering open issues from ${REPO}...`);
// We use the /issues endpoint with pagination to bypass the 1000-result limit.
// The jq filter ensures we exclude PRs, maintainer-only, help-wanted, and existing status/need-triage.
const jqFilter =
'.[] | select(.pull_request == null) | select([.labels[].name] as $l | (any($l[]; . == "🔒 maintainer only") | not) and (any($l[]; . == "help wanted") | not) and (any($l[]; . == "status/need-triage") | not)) | {number: .number, title: .title}';
const output = runGh([
'api',
`repos/${REPO}/issues?state=open&per_page=100`,
'--paginate',
'--jq',
jqFilter,
]);
if (output === null) {
process.exit(1);
}
const issues = output
.split('\n')
.filter((line) => line.trim())
.map((line) => {
try {
return JSON.parse(line);
} catch (_e) {
console.error(`⚠️ Failed to parse line: ${line}`);
return null;
}
})
.filter(Boolean);
console.log(`✅ Found ${issues.length} issues matching criteria.`);
if (issues.length === 0) {
console.log('✨ No issues need backfilling.');
return;
}
let successCount = 0;
let failCount = 0;
if (isDryRun) {
for (const issue of issues) {
console.log(
`[DRY RUN] Would label issue #${issue.number}: ${issue.title}`,
);
}
successCount = issues.length;
} else {
console.log(`🏷️ Applying labels to ${issues.length} issues...`);
for (const issue of issues) {
const issueNumber = String(issue.number);
console.log(`🏷️ Labeling issue #${issueNumber}: ${issue.title}`);
const result = runGh([
'issue',
'edit',
issueNumber,
'--add-label',
'status/need-triage',
'--repo',
REPO,
]);
if (result !== null) {
successCount++;
} else {
failCount++;
}
}
}
console.log(`\n📊 Summary:`);
console.log(` - Success: ${successCount}`);
console.log(` - Failed: ${failCount}`);
if (failCount > 0) {
console.error(`\n❌ Backfill completed with ${failCount} errors.`);
process.exit(1);
} else {
console.log(`\n🎉 ${isDryRun ? 'Dry run' : 'Backfill'} complete!`);
}
}
main().catch((error) => {
console.error('❌ Unexpected error:', error);
process.exit(1);
});
@@ -1,190 +0,0 @@
/**
* @license
* Copyright 2026 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
/* eslint-disable */
/* global require, console, process */
/**
* Script to backfill a process change notification comment to all open PRs
* not created by members of the 'gemini-cli-maintainers' team.
*
* Skip PRs that are already associated with an issue.
*/
const { execFileSync } = require('child_process');
const isDryRun = process.argv.includes('--dry-run');
const REPO = 'google-gemini/gemini-cli';
const ORG = 'google-gemini';
const TEAM_SLUG = 'gemini-cli-maintainers';
const DISCUSSION_URL =
'https://github.com/google-gemini/gemini-cli/discussions/16706';
/**
* Executes a GitHub CLI command safely using an argument array.
*/
function runGh(args, options = {}) {
const { silent = false } = options;
try {
return execFileSync('gh', args, {
encoding: 'utf8',
maxBuffer: 10 * 1024 * 1024,
stdio: ['ignore', 'pipe', 'pipe'],
}).trim();
} catch (error) {
if (!silent) {
const stderr = error.stderr ? ` Stderr: ${error.stderr.trim()}` : '';
console.error(
`❌ Error running gh ${args.join(' ')}: ${error.message}${stderr}`,
);
}
return null;
}
}
/**
* Checks if a user is a member of the maintainers team.
*/
const membershipCache = new Map();
function isMaintainer(username) {
if (membershipCache.has(username)) return membershipCache.get(username);
// GitHub returns 404 if user is not a member.
// We use silent: true to avoid logging 404s as errors.
const result = runGh(
['api', `orgs/${ORG}/teams/${TEAM_SLUG}/memberships/${username}`],
{ silent: true },
);
const isMember = result !== null;
membershipCache.set(username, isMember);
return isMember;
}
async function main() {
console.log('🔐 GitHub CLI security check...');
if (runGh(['auth', 'status']) === null) {
console.error('❌ GitHub CLI (gh) is not authenticated.');
process.exit(1);
}
if (isDryRun) {
console.log('🧪 DRY RUN MODE ENABLED\n');
}
console.log(`📥 Fetching open PRs from ${REPO}...`);
// Fetch number, author, and closingIssuesReferences to check if linked to an issue
const prsJson = runGh([
'pr',
'list',
'--repo',
REPO,
'--state',
'open',
'--limit',
'1000',
'--json',
'number,author,closingIssuesReferences',
]);
if (prsJson === null) process.exit(1);
const prs = JSON.parse(prsJson);
console.log(`📊 Found ${prs.length} open PRs. Filtering...`);
let targetPrs = [];
for (const pr of prs) {
const author = pr.author.login;
const issueCount = pr.closingIssuesReferences
? pr.closingIssuesReferences.length
: 0;
if (issueCount > 0) {
// Skip if already linked to an issue
continue;
}
if (!isMaintainer(author)) {
targetPrs.push(pr);
}
}
console.log(
`✅ Found ${targetPrs.length} PRs from non-maintainers without associated issues.`,
);
const commentBody =
"\nHi @{AUTHOR}, thank you so much for your contribution to Gemini CLI! We really appreciate the time and effort you've put into this.\n\nWe're making some updates to our contribution process to improve how we track and review changes. Please take a moment to review our recent discussion post: [Improving Our Contribution Process & Introducing New Guidelines](${DISCUSSION_URL}).\n\nKey Update: Starting **January 26, 2026**, the Gemini CLI project will require all pull requests to be associated with an existing issue. Any pull requests not linked to an issue by that date will be automatically closed.\n\nThank you for your understanding and for being a part of our community!\n ".trim();
let successCount = 0;
let skipCount = 0;
let failCount = 0;
for (const pr of targetPrs) {
const prNumber = String(pr.number);
const author = pr.author.login;
// Check if we already commented (idempotency)
// We use silent: true here because view might fail if PR is deleted mid-run
const existingComments = runGh(
[
'pr',
'view',
prNumber,
'--repo',
REPO,
'--json',
'comments',
'--jq',
`.comments[].body | contains("${DISCUSSION_URL}")`,
],
{ silent: true },
);
if (existingComments && existingComments.includes('true')) {
console.log(
`⏭️ PR #${prNumber} already has the notification. Skipping.`,
);
skipCount++;
continue;
}
if (isDryRun) {
console.log(`[DRY RUN] Would notify @${author} on PR #${prNumber}`);
successCount++;
} else {
console.log(`💬 Notifying @${author} on PR #${prNumber}...`);
const personalizedComment = commentBody.replace('{AUTHOR}', author);
const result = runGh([
'pr',
'comment',
prNumber,
'--repo',
REPO,
'--body',
personalizedComment,
]);
if (result !== null) {
successCount++;
} else {
failCount++;
}
}
}
console.log(`\n📊 Summary:`);
console.log(` - Notified: ${successCount}`);
console.log(` - Skipped: ${skipCount}`);
console.log(` - Failed: ${failCount}`);
if (failCount > 0) process.exit(1);
}
main().catch((e) => {
console.error(e);
process.exit(1);
});
+100 -147
View File
@@ -1,180 +1,133 @@
#!/usr/bin/env bash
# @license
# Copyright 2026 Google LLC
# SPDX-License-Identifier: Apache-2.0
set -euo pipefail
# Initialize a comma-separated string to hold PR numbers that need a comment
PRS_NEEDING_COMMENT=""
# Global cache for issue labels (compatible with Bash 3.2)
# Stores "ISSUE_NUM:LABELS" pairs separated by spaces
ISSUE_LABELS_CACHE_FLAT=""
# 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
return
# Function to process a single PR
process_pr() {
if [[ -z "${GITHUB_REPOSITORY:-}" ]]; then
echo "‼️ Missing \$GITHUB_REPOSITORY - this must be run from GitHub Actions"
return 1
fi
# Check cache
case " ${ISSUE_LABELS_CACHE_FLAT} " in
*" ${ISSUE_NUM}:"*)
local suffix="${ISSUE_LABELS_CACHE_FLAT#* " ${ISSUE_NUM}:"}"
echo "${suffix%% *}"
return
;;
*)
# Cache miss, proceed to fetch
;;
esac
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}:"
return
if [[ -z "${GITHUB_OUTPUT:-}" ]]; then
echo "‼️ Missing \$GITHUB_OUTPUT - this must be run from GitHub Actions"
return 1
fi
local labels
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}"
echo "${labels}"
}
# Function to process a single PR with pre-fetched data
process_pr_optimized() {
local PR_NUMBER="${1}"
local IS_DRAFT="${2}"
local ISSUE_NUMBER="${3}"
local CURRENT_LABELS="${4}" # Comma-separated labels
local PR_NUMBER=$1
echo "🔄 Processing PR #${PR_NUMBER}"
local LABELS_TO_ADD=""
local LABELS_TO_REMOVE=""
if [[ -z "${ISSUE_NUMBER}" || "${ISSUE_NUMBER}" == "null" || "${ISSUE_NUMBER}" == "" ]]; then
if [[ "${IS_DRAFT}" == "true" ]]; then
echo " 📝 PR #${PR_NUMBER} is a draft and has no linked issue"
if [[ ",${CURRENT_LABELS}," == *",status/need-issue,"* ]]; then
echo " Removing status/need-issue label"
LABELS_TO_REMOVE="status/need-issue"
fi
else
echo " ⚠️ No linked issue found for PR #${PR_NUMBER}"
if [[ ",${CURRENT_LABELS}," != *",status/need-issue,"* ]]; then
echo " Adding status/need-issue label"
LABELS_TO_ADD="status/need-issue"
fi
if [[ -z "${PRS_NEEDING_COMMENT}" ]]; then
PRS_NEEDING_COMMENT="${PR_NUMBER}"
else
PRS_NEEDING_COMMENT="${PRS_NEEDING_COMMENT},${PR_NUMBER}"
fi
fi
else
echo " 🔗 Found linked issue #${ISSUE_NUMBER}"
if [[ ",${CURRENT_LABELS}," == *",status/need-issue,"* ]]; then
echo " Removing status/need-issue label"
LABELS_TO_REMOVE="status/need-issue"
fi
local ISSUE_LABELS
ISSUE_LABELS=$(get_issue_labels "${ISSUE_NUMBER}")
if [[ -n "${ISSUE_LABELS}" ]]; then
local IFS_OLD="${IFS}"
IFS=','
for label in ${ISSUE_LABELS}; do
if [[ -n "${label}" ]] && [[ ",${CURRENT_LABELS}," != *",${label},"* ]]; then
if [[ -z "${LABELS_TO_ADD}" ]]; then
LABELS_TO_ADD="${label}"
else
LABELS_TO_ADD="${LABELS_TO_ADD},${label}"
fi
fi
done
IFS="${IFS_OLD}"
fi
if [[ -z "${LABELS_TO_ADD}" && -z "${LABELS_TO_REMOVE}" ]]; then
echo " ✅ Labels already synchronized"
fi
# Get closing issue number with error handling
local ISSUE_NUMBER
if ! ISSUE_NUMBER=$(gh pr view "${PR_NUMBER}" --repo "${GITHUB_REPOSITORY}" --json closingIssuesReferences -q '.closingIssuesReferences.nodes[0].number' 2>/dev/null); then
echo " ⚠️ Could not fetch closing issue for PR #${PR_NUMBER}"
fi
if [[ -n "${LABELS_TO_ADD}" || -n "${LABELS_TO_REMOVE}" ]]; then
local EDIT_CMD=("gh" "pr" "edit" "${PR_NUMBER}" "--repo" "${GITHUB_REPOSITORY}")
if [[ -z "${ISSUE_NUMBER}" ]]; then
echo "⚠️ No linked issue found for PR #${PR_NUMBER}, adding status/need-issue label"
if ! gh pr edit "${PR_NUMBER}" --repo "${GITHUB_REPOSITORY}" --add-label "status/need-issue" 2>/dev/null; then
echo " ⚠️ Failed to add label (may already exist or have permission issues)"
fi
# Add PR number to the list
if [[ -z "${PRS_NEEDING_COMMENT}" ]]; then
PRS_NEEDING_COMMENT="${PR_NUMBER}"
else
PRS_NEEDING_COMMENT="${PRS_NEEDING_COMMENT},${PR_NUMBER}"
fi
echo "needs_comment=true" >> "${GITHUB_OUTPUT}"
else
echo "🔗 Found linked issue #${ISSUE_NUMBER}"
# Remove status/need-issue label if present
if ! gh pr edit "${PR_NUMBER}" --repo "${GITHUB_REPOSITORY}" --remove-label "status/need-issue" 2>/dev/null; then
echo " status/need-issue label not present or could not be removed"
fi
# Get issue labels
echo "📥 Fetching labels from issue #${ISSUE_NUMBER}"
local ISSUE_LABELS=""
if ! ISSUE_LABELS=$(gh issue view "${ISSUE_NUMBER}" --repo "${GITHUB_REPOSITORY}" --json labels -q '.labels[].name' 2>/dev/null | tr '\n' ',' | sed 's/,$//' || echo ""); then
echo " ⚠️ Could not fetch issue #${ISSUE_NUMBER} (may not exist or be in different repo)"
ISSUE_LABELS=""
fi
# Get PR labels
echo "📥 Fetching labels from PR #${PR_NUMBER}"
local PR_LABELS=""
if ! PR_LABELS=$(gh pr view "${PR_NUMBER}" --repo "${GITHUB_REPOSITORY}" --json labels -q '.labels[].name' 2>/dev/null | tr '\n' ',' | sed 's/,$//' || echo ""); then
echo " ⚠️ Could not fetch PR labels"
PR_LABELS=""
fi
echo " Issue labels: ${ISSUE_LABELS}"
echo " PR labels: ${PR_LABELS}"
# Convert comma-separated strings to arrays
local ISSUE_LABEL_ARRAY PR_LABEL_ARRAY
IFS=',' read -ra ISSUE_LABEL_ARRAY <<< "${ISSUE_LABELS}"
IFS=',' read -ra PR_LABEL_ARRAY <<< "${PR_LABELS}"
# Find labels to add (on issue but not on PR)
local LABELS_TO_ADD=""
for label in "${ISSUE_LABEL_ARRAY[@]}"; do
if [[ -n "${label}" ]] && [[ " ${PR_LABEL_ARRAY[*]} " != *" ${label} "* ]]; then
if [[ -z "${LABELS_TO_ADD}" ]]; then
LABELS_TO_ADD="${label}"
else
LABELS_TO_ADD="${LABELS_TO_ADD},${label}"
fi
fi
done
# Apply label changes
if [[ -n "${LABELS_TO_ADD}" ]]; then
echo " Syncing labels to add: ${LABELS_TO_ADD}"
EDIT_CMD+=("--add-label" "${LABELS_TO_ADD}")
echo " Adding labels: ${LABELS_TO_ADD}"
if ! gh pr edit "${PR_NUMBER}" --repo "${GITHUB_REPOSITORY}" --add-label "${LABELS_TO_ADD}" 2>/dev/null; then
echo " ⚠️ Failed to add some labels"
fi
fi
if [[ -n "${LABELS_TO_REMOVE}" ]]; then
echo " Syncing labels to remove: ${LABELS_TO_REMOVE}"
EDIT_CMD+=("--remove-label" "${LABELS_TO_REMOVE}")
if [[ -z "${LABELS_TO_ADD}" ]]; then
echo "✅ Labels already synchronized"
fi
("${EDIT_CMD[@]}" 2>/dev/null || true)
echo "needs_comment=false" >> "${GITHUB_OUTPUT}"
fi
}
if [[ -z "${GITHUB_REPOSITORY:-}" ]]; then
echo "‼️ Missing \$GITHUB_REPOSITORY - this must be run from GitHub Actions"
exit 1
fi
if [[ -z "${GITHUB_OUTPUT:-}" ]]; then
echo "‼️ Missing \$GITHUB_OUTPUT - this must be run from GitHub Actions"
exit 1
fi
JQ_EXTRACT_FIELDS='{
number: .number,
isDraft: .isDraft,
issue: (.closingIssuesReferences[0].number // (.body // "" | capture("(^|[^a-zA-Z0-9])#(?<num>[0-9]+)([^a-zA-Z0-9]|$)")? | .num) // "null"),
labels: [.labels[].name] | join(",")
}'
JQ_TSV_FORMAT='"\((.number | tostring))\t\(.isDraft)\t\((.issue // null) | tostring)\t\(.labels)"'
# If PR_NUMBER is set, process only that PR
if [[ -n "${PR_NUMBER:-}" ]]; then
echo "🔄 Processing single PR #${PR_NUMBER}"
PR_DATA=$(gh pr view "${PR_NUMBER}" --repo "${GITHUB_REPOSITORY}" --json number,closingIssuesReferences,isDraft,body,labels 2>/dev/null) || {
echo "❌ Failed to fetch data for PR #${PR_NUMBER}"
if ! process_pr "${PR_NUMBER}"; then
echo "❌ Failed to process PR #${PR_NUMBER}"
exit 1
}
line=$(echo "${PR_DATA}" | jq -r "${JQ_EXTRACT_FIELDS} | ${JQ_TSV_FORMAT}")
IFS=$'\t' read -r pr_num is_draft issue_num current_labels <<< "${line}"
process_pr_optimized "${pr_num}" "${is_draft}" "${issue_num}" "${current_labels}"
fi
else
# Otherwise, get all open PRs and process them
# The script logic will determine which ones need issue linking or label sync
echo "📥 Getting all open pull requests..."
PR_DATA_ALL=$(gh pr list --repo "${GITHUB_REPOSITORY}" --state open --limit 1000 --json number,closingIssuesReferences,isDraft,body,labels 2>/dev/null) || {
if ! PR_NUMBERS=$(gh pr list --repo "${GITHUB_REPOSITORY}" --state open --limit 1000 --json number -q '.[].number' 2>/dev/null); then
echo "❌ Failed to fetch PR list"
exit 1
}
fi
PR_COUNT=$(echo "${PR_DATA_ALL}" | jq '. | length')
echo "📊 Found ${PR_COUNT} open PRs to process"
if [[ -z "${PR_NUMBERS}" ]]; then
echo "✅ No open PRs found"
else
# Count the number of PRs
PR_COUNT=$(echo "${PR_NUMBERS}" | wc -w | tr -d ' ')
echo "📊 Found ${PR_COUNT} open PRs to process"
# Use a temporary file to avoid masking exit codes in process substitution
tmp_file=$(mktemp)
echo "${PR_DATA_ALL}" | jq -r ".[] | ${JQ_EXTRACT_FIELDS} | ${JQ_TSV_FORMAT}" > "${tmp_file}"
while read -r line; do
[[ -z "${line}" ]] && continue
IFS=$'\t' read -r pr_num is_draft issue_num current_labels <<< "${line}"
process_pr_optimized "${pr_num}" "${is_draft}" "${issue_num}" "${current_labels}"
done < "${tmp_file}"
rm -f "${tmp_file}"
for pr_number in ${PR_NUMBERS}; do
if ! process_pr "${pr_number}"; then
echo "⚠️ Failed to process PR #${pr_number}, continuing with next PR..."
continue
fi
done
fi
fi
# Ensure output is always set, even if empty
if [[ -z "${PRS_NEEDING_COMMENT}" ]]; then
echo "prs_needing_comment=[]" >> "${GITHUB_OUTPUT}"
else
-355
View File
@@ -1,355 +0,0 @@
/* eslint-disable @typescript-eslint/no-require-imports */
/* global process, console, require */
const { Octokit } = require('@octokit/rest');
/**
* Sync Maintainer Labels (Recursive with strict parent-child relationship detection)
* - Uses Native Sub-issues.
* - Uses Markdown Task Lists (- [ ] #123).
* - Filters for OPEN issues only.
* - Skips DUPLICATES.
* - Skips Pull Requests.
* - ONLY labels issues in the PUBLIC (gemini-cli) repo.
*/
const REPO_OWNER = 'google-gemini';
const PUBLIC_REPO = 'gemini-cli';
const PRIVATE_REPO = 'maintainers-gemini-cli';
const ALLOWED_REPOS = [PUBLIC_REPO, PRIVATE_REPO];
const ROOT_ISSUES = [
{ owner: REPO_OWNER, repo: PUBLIC_REPO, number: 15374 },
{ owner: REPO_OWNER, repo: PUBLIC_REPO, number: 15456 },
{ owner: REPO_OWNER, repo: PUBLIC_REPO, number: 15324 },
];
const TARGET_LABEL = '🔒 maintainer only';
const isDryRun =
process.argv.includes('--dry-run') || process.env.DRY_RUN === 'true';
const octokit = new Octokit({
auth: process.env.GITHUB_TOKEN,
});
/**
* Extracts child issue references from markdown Task Lists ONLY.
* e.g. - [ ] #123 or - [x] google-gemini/gemini-cli#123
*/
function extractTaskListLinks(text, contextOwner, contextRepo) {
if (!text) return [];
const childIssues = new Map();
const add = (owner, repo, number) => {
if (ALLOWED_REPOS.includes(repo)) {
const key = `${owner}/${repo}#${number}`;
childIssues.set(key, { owner, repo, number: parseInt(number, 10) });
}
};
// 1. Full URLs in task lists
const urlRegex =
/-\s+\[[ x]\].*https:\/\/github\.com\/([a-zA-Z0-9._-]+)\/([a-zA-Z0-9._-]+)\/issues\/(\d+)\b/g;
let match;
while ((match = urlRegex.exec(text)) !== null) {
add(match[1], match[2], match[3]);
}
// 2. Cross-repo refs in task lists: owner/repo#123
const crossRepoRegex =
/-\s+\[[ x]\].*([a-zA-Z0-9._-]+)\/([a-zA-Z0-9._-]+)#(\d+)\b/g;
while ((match = crossRepoRegex.exec(text)) !== null) {
add(match[1], match[2], match[3]);
}
// 3. Short refs in task lists: #123
const shortRefRegex = /-\s+\[[ x]\].*#(\d+)\b/g;
while ((match = shortRefRegex.exec(text)) !== null) {
add(contextOwner, contextRepo, match[1]);
}
return Array.from(childIssues.values());
}
/**
* Fetches issue data via GraphQL with full pagination for sub-issues, comments, and labels.
*/
async function fetchIssueData(owner, repo, number) {
const query = `
query($owner:String!, $repo:String!, $number:Int!) {
repository(owner:$owner, name:$repo) {
issue(number:$number) {
state
title
body
labels(first: 100) {
nodes { name }
pageInfo { hasNextPage endCursor }
}
subIssues(first: 100) {
nodes {
number
repository {
name
owner { login }
}
}
pageInfo { hasNextPage endCursor }
}
comments(first: 100) {
nodes {
body
}
}
}
}
}
`;
try {
const response = await octokit.graphql(query, { owner, repo, number });
const data = response.repository.issue;
if (!data) return null;
const issue = {
state: data.state,
title: data.title,
body: data.body || '',
labels: data.labels.nodes.map((n) => n.name),
subIssues: [...data.subIssues.nodes],
comments: data.comments.nodes.map((n) => n.body),
};
// Paginate subIssues if there are more than 100
if (data.subIssues.pageInfo.hasNextPage) {
const moreSubIssues = await paginateConnection(
owner,
repo,
number,
'subIssues',
'number repository { name owner { login } }',
data.subIssues.pageInfo.endCursor,
);
issue.subIssues.push(...moreSubIssues);
}
// Paginate labels if there are more than 100 (unlikely but for completeness)
if (data.labels.pageInfo.hasNextPage) {
const moreLabels = await paginateConnection(
owner,
repo,
number,
'labels',
'name',
data.labels.pageInfo.endCursor,
(n) => n.name,
);
issue.labels.push(...moreLabels);
}
// Note: Comments are handled via Task Lists in body + first 100 comments.
// If an issue has > 100 comments with task lists, we'd need to paginate those too.
// Given the 1,100+ issue discovery count, 100 comments is usually sufficient,
// but we can add it for absolute completeness.
// (Skipping for now to avoid excessive API churn unless clearly needed).
return issue;
} catch (error) {
if (error.errors && error.errors.some((e) => e.type === 'NOT_FOUND')) {
return null;
}
throw error;
}
}
/**
* Helper to paginate any GraphQL connection.
*/
async function paginateConnection(
owner,
repo,
number,
connectionName,
nodeFields,
initialCursor,
transformNode = (n) => n,
) {
let additionalNodes = [];
let hasNext = true;
let cursor = initialCursor;
while (hasNext) {
const query = `
query($owner:String!, $repo:String!, $number:Int!, $cursor:String) {
repository(owner:$owner, name:$repo) {
issue(number:$number) {
${connectionName}(first: 100, after: $cursor) {
nodes { ${nodeFields} }
pageInfo { hasNextPage endCursor }
}
}
}
}
`;
const response = await octokit.graphql(query, {
owner,
repo,
number,
cursor,
});
const connection = response.repository.issue[connectionName];
additionalNodes.push(...connection.nodes.map(transformNode));
hasNext = connection.pageInfo.hasNextPage;
cursor = connection.pageInfo.endCursor;
}
return additionalNodes;
}
/**
* Validates if an issue should be processed (Open, not a duplicate, not a PR)
*/
function shouldProcess(issueData) {
if (!issueData) return false;
if (issueData.state !== 'OPEN') return false;
const labels = issueData.labels.map((l) => l.toLowerCase());
if (labels.includes('duplicate') || labels.includes('kind/duplicate')) {
return false;
}
return true;
}
async function getAllDescendants(roots) {
const allDescendants = new Map();
const visited = new Set();
const queue = [...roots];
for (const root of roots) {
visited.add(`${root.owner}/${root.repo}#${root.number}`);
}
console.log(`Starting discovery from ${roots.length} roots...`);
while (queue.length > 0) {
const current = queue.shift();
const currentKey = `${current.owner}/${current.repo}#${current.number}`;
try {
const issueData = await fetchIssueData(
current.owner,
current.repo,
current.number,
);
if (!shouldProcess(issueData)) {
continue;
}
// ONLY add to labeling list if it's in the PUBLIC repository
if (current.repo === PUBLIC_REPO) {
// Don't label the roots themselves
if (
!ROOT_ISSUES.some(
(r) => r.number === current.number && r.repo === current.repo,
)
) {
allDescendants.set(currentKey, {
...current,
title: issueData.title,
labels: issueData.labels,
});
}
}
const children = new Map();
// 1. Process Native Sub-issues
if (issueData.subIssues) {
for (const node of issueData.subIssues) {
const childOwner = node.repository.owner.login;
const childRepo = node.repository.name;
const childNumber = node.number;
const key = `${childOwner}/${childRepo}#${childNumber}`;
children.set(key, {
owner: childOwner,
repo: childRepo,
number: childNumber,
});
}
}
// 2. Process Markdown Task Lists in Body and Comments
let combinedText = issueData.body || '';
if (issueData.comments) {
for (const commentBody of issueData.comments) {
combinedText += '\n' + (commentBody || '');
}
}
const taskListLinks = extractTaskListLinks(
combinedText,
current.owner,
current.repo,
);
for (const link of taskListLinks) {
const key = `${link.owner}/${link.repo}#${link.number}`;
children.set(key, link);
}
// Queue children (regardless of which repo they are in, for recursion)
for (const [key, child] of children) {
if (!visited.has(key)) {
visited.add(key);
queue.push(child);
}
}
} catch (error) {
console.error(`Error processing ${currentKey}: ${error.message}`);
}
}
return Array.from(allDescendants.values());
}
async function run() {
if (isDryRun) {
console.log('=== DRY RUN MODE: No labels will be applied ===');
}
const descendants = await getAllDescendants(ROOT_ISSUES);
console.log(
`\nFound ${descendants.length} total unique open descendant issues in ${PUBLIC_REPO}.`,
);
for (const issueInfo of descendants) {
const issueKey = `${issueInfo.owner}/${issueInfo.repo}#${issueInfo.number}`;
try {
// Data is already available from the discovery phase
const hasLabel = issueInfo.labels.some((l) => l === TARGET_LABEL);
if (!hasLabel) {
if (isDryRun) {
console.log(
`[DRY RUN] Would label ${issueKey}: "${issueInfo.title}"`,
);
} else {
console.log(`Labeling ${issueKey}: "${issueInfo.title}"...`);
await octokit.rest.issues.addLabels({
owner: issueInfo.owner,
repo: issueInfo.repo,
issue_number: issueInfo.number,
labels: [TARGET_LABEL],
});
}
}
} catch (error) {
console.error(`Error processing label for ${issueKey}: ${error.message}`);
}
}
}
run().catch((error) => {
console.error(error);
process.exit(1);
});
+15 -64
View File
@@ -43,15 +43,13 @@ jobs:
- id: 'merge-queue-ci-skipper'
uses: 'cariad-tech/merge-queue-ci-skipper@1032489e59437862c90a08a2c92809c903883772' # ratchet:cariad-tech/merge-queue-ci-skipper@main
with:
secret: '${{ secrets.GEMINI_CLI_ROBOT_GITHUB_PAT }}'
secret: '${{ secrets.GITHUB_TOKEN }}'
lint:
name: 'Lint'
runs-on: 'gemini-cli-ubuntu-16-core'
needs: 'merge_queue_skipper'
if: "${{needs.merge_queue_skipper.outputs.skip == 'false'}}"
env:
GEMINI_LINT_TEMP_DIR: '${{ github.workspace }}/.gemini-linters'
steps:
- name: 'Checkout'
uses: 'actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8' # ratchet:actions/checkout@v5
@@ -65,21 +63,9 @@ jobs:
node-version-file: '.nvmrc'
cache: 'npm'
- name: 'Cache Linters'
uses: 'actions/cache@v4'
with:
path: '${{ env.GEMINI_LINT_TEMP_DIR }}'
key: "${{ runner.os }}-${{ runner.arch }}-linters-${{ hashFiles('scripts/lint.js') }}"
- name: 'Install dependencies'
run: 'npm ci'
- name: 'Cache ESLint'
uses: 'actions/cache@v4'
with:
path: '.eslintcache'
key: "${{ runner.os }}-eslint-${{ hashFiles('package-lock.json', 'eslint.config.js') }}"
- name: 'Validate NOTICES.txt'
run: 'git diff --exit-code packages/vscode-ide-companion/NOTICES.txt'
@@ -104,30 +90,14 @@ jobs:
- name: 'Run Prettier'
run: 'node scripts/lint.js --prettier'
- name: 'Build docs prerequisites'
run: 'npm run predocs:settings'
- name: 'Verify settings docs'
run: 'npm run docs:settings -- --check'
- name: 'Run sensitive keyword linter'
run: 'node scripts/lint.js --sensitive-keywords'
link_checker:
name: 'Link Checker'
runs-on: 'ubuntu-latest'
steps:
- name: 'Checkout'
uses: 'actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8' # ratchet:actions/checkout@v5
- name: 'Link Checker'
uses: 'lycheeverse/lychee-action@885c65f3dc543b57c898c8099f4e08c8afd178a2' # ratchet: lycheeverse/lychee-action@v2.6.1
with:
args: '--verbose --accept 200,503 ./**/*.md'
fail: true
test_linux:
name: 'Test (Linux) - ${{ matrix.node-version }}, ${{ matrix.shard }}'
name: 'Test (Linux)'
runs-on: 'gemini-cli-ubuntu-16-core'
needs:
- 'lint'
- 'merge_queue_skipper'
if: "${{needs.merge_queue_skipper.outputs.skip == 'false'}}"
permissions:
@@ -140,9 +110,6 @@ jobs:
- '20.x'
- '22.x'
- '24.x'
shard:
- 'cli'
- 'others'
steps:
- name: 'Checkout'
uses: 'actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8' # ratchet:actions/checkout@v5
@@ -162,14 +129,7 @@ jobs:
- name: 'Run tests and generate reports'
env:
NO_COLOR: true
run: |
if [[ "${{ matrix.shard }}" == "cli" ]]; then
npm run test:ci --workspace @google/gemini-cli
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
npm run test:scripts
fi
run: 'npm run test:ci'
- name: 'Bundle'
run: 'npm run bundle'
@@ -185,7 +145,7 @@ jobs:
${{ always() && (github.event.pull_request.head.repo.full_name == github.repository) }}
uses: 'dorny/test-reporter@dc3a92680fcc15842eef52e8c4606ea7ce6bd3f3' # ratchet:dorny/test-reporter@v2
with:
name: 'Test Results (Node ${{ runner.os }}, ${{ matrix.node-version }}, ${{ matrix.shard }})'
name: 'Test Results (Node ${{ matrix.node-version }})'
path: 'packages/*/junit.xml'
reporter: 'java-junit'
fail-on-error: 'false'
@@ -195,13 +155,14 @@ jobs:
${{ always() && (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository) }}
uses: 'actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02' # ratchet:actions/upload-artifact@v4
with:
name: 'test-results-fork-${{ runner.os }}-${{ matrix.node-version }}-${{ matrix.shard }}'
name: 'test-results-fork-${{ matrix.node-version }}-${{ runner.os }}'
path: 'packages/*/junit.xml'
test_mac:
name: 'Test (Mac) - ${{ matrix.node-version }}, ${{ matrix.shard }}'
runs-on: 'macos-latest'
name: 'Test (Mac)'
runs-on: '${{ matrix.os }}'
needs:
- 'lint'
- 'merge_queue_skipper'
if: "${{needs.merge_queue_skipper.outputs.skip == 'false'}}"
permissions:
@@ -211,13 +172,12 @@ jobs:
continue-on-error: true
strategy:
matrix:
os:
- 'macos-latest'
node-version:
- '20.x'
- '22.x'
- '24.x'
shard:
- 'cli'
- 'others'
steps:
- name: 'Checkout'
uses: 'actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8' # ratchet:actions/checkout@v5
@@ -237,14 +197,7 @@ jobs:
- name: 'Run tests and generate reports'
env:
NO_COLOR: true
run: |
if [[ "${{ matrix.shard }}" == "cli" ]]; then
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
fi
run: 'npm run test:ci -- --coverage.enabled=false'
- name: 'Bundle'
run: 'npm run bundle'
@@ -260,7 +213,7 @@ jobs:
${{ always() && (github.event.pull_request.head.repo.full_name == github.repository) }}
uses: 'dorny/test-reporter@dc3a92680fcc15842eef52e8c4606ea7ce6bd3f3' # ratchet:dorny/test-reporter@v2
with:
name: 'Test Results (Node ${{ runner.os }}, ${{ matrix.node-version }}, ${{ matrix.shard }})'
name: 'Test Results (Node ${{ matrix.node-version }})'
path: 'packages/*/junit.xml'
reporter: 'java-junit'
fail-on-error: 'false'
@@ -270,7 +223,7 @@ jobs:
${{ always() && (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository) }}
uses: 'actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02' # ratchet:actions/upload-artifact@v4
with:
name: 'test-results-fork-${{ runner.os }}-${{ matrix.node-version }}-${{ matrix.shard }}'
name: 'test-results-fork-${{ matrix.node-version }}-${{ runner.os }}'
path: 'packages/*/junit.xml'
- name: 'Upload coverage reports'
@@ -278,7 +231,7 @@ jobs:
${{ always() }}
uses: 'actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02' # ratchet:actions/upload-artifact@v4
with:
name: 'coverage-reports-${{ runner.os }}-${{ matrix.node-version }}-${{ matrix.shard }}'
name: 'coverage-reports-${{ matrix.node-version }}-${{ matrix.os }}'
path: 'packages/*/coverage'
codeql:
@@ -401,7 +354,6 @@ jobs:
if: 'always()'
needs:
- 'lint'
- 'link_checker'
- 'test_linux'
- 'test_mac'
- 'codeql'
@@ -411,7 +363,6 @@ jobs:
- 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.codeql.result }} != 'success' && ${{ needs.codeql.result }} != 'skipped') || \
+4 -138
View File
@@ -24,147 +24,13 @@ concurrency:
${{ github.ref != 'refs/heads/main' && !startsWith(github.ref, 'refs/heads/release/') }}
jobs:
deflake_e2e_linux:
name: 'E2E Test (Linux) - ${{ matrix.sandbox }}'
deflake:
name: 'Deflake'
runs-on: 'gemini-cli-ubuntu-16-core'
strategy:
fail-fast: false
matrix:
sandbox:
- 'sandbox:none'
- 'sandbox:docker'
node-version:
- '20.x'
steps:
- name: 'Checkout'
uses: 'actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955' # ratchet:actions/checkout@v5
with:
ref: '${{ github.event.pull_request.head.sha }}'
repository: '${{ github.repository }}'
- name: 'Set up Node.js ${{ matrix.node-version }}'
uses: 'actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020' # ratchet:actions-node@v4
with:
node-version: '${{ matrix.node-version }}'
- name: 'Install dependencies'
run: 'npm ci'
- name: 'Build project'
run: 'npm run build'
- name: 'Set up Docker'
if: "matrix.sandbox == 'sandbox:docker'"
uses: 'docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435' # ratchet:docker/setup-buildx-action@v3
- name: 'Run E2E tests'
env:
GEMINI_API_KEY: '${{ secrets.GEMINI_API_KEY }}'
IS_DOCKER: "${{ matrix.sandbox == 'sandbox:docker' }}"
KEEP_OUTPUT: 'true'
RUNS: '${{ github.event.inputs.runs }}'
TEST_NAME_PATTERN: '${{ github.event.inputs.test_name_pattern }}'
VERBOSE: 'true'
- name: 'Deflake'
shell: 'bash'
run: |
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="${{ env.RUNS }}" -- --testNamePattern "'${{ env.TEST_NAME_PATTERN }}'"
fi
deflake_e2e_mac:
name: 'E2E Test (macOS)'
runs-on: 'macos-latest'
steps:
- name: 'Checkout'
uses: 'actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955' # ratchet:actions/checkout@v5
with:
ref: '${{ github.event.pull_request.head.sha }}'
repository: '${{ github.repository }}'
- name: 'Set up Node.js 20.x'
uses: 'actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020' # ratchet:actions-node@v4
with:
node-version: '20.x'
- name: 'Install dependencies'
run: 'npm ci'
- name: 'Build project'
run: 'npm run build'
- name: 'Fix rollup optional dependencies on macOS'
if: "runner.os == 'macOS'"
run: |
npm cache clean --force
- name: 'Run E2E tests (non-Windows)'
if: "runner.os != 'Windows'"
env:
GEMINI_API_KEY: '${{ secrets.GEMINI_API_KEY }}'
KEEP_OUTPUT: 'true'
RUNS: '${{ github.event.inputs.runs }}'
SANDBOX: 'sandbox:none'
TEST_NAME_PATTERN: '${{ github.event.inputs.test_name_pattern }}'
VERBOSE: 'true'
run: |
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'
steps:
- name: 'Checkout'
uses: 'actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955' # ratchet:actions/checkout@v5
with:
ref: '${{ github.event.pull_request.head.sha }}'
repository: '${{ github.repository }}'
- name: 'Set up Node.js 20.x'
uses: 'actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020' # ratchet:actions-node@v4
with:
node-version: '20.x'
cache: 'npm'
- name: 'Configure Windows Defender exclusions'
run: |
Add-MpPreference -ExclusionPath $env:GITHUB_WORKSPACE -Force
Add-MpPreference -ExclusionPath "$env:GITHUB_WORKSPACE\node_modules" -Force
Add-MpPreference -ExclusionPath "$env:GITHUB_WORKSPACE\packages" -Force
Add-MpPreference -ExclusionPath "$env:TEMP" -Force
shell: 'pwsh'
- name: 'Configure npm for Windows performance'
run: |
npm config set progress false
npm config set audit false
npm config set fund false
npm config set loglevel error
npm config set maxsockets 32
npm config set registry https://registry.npmjs.org/
shell: 'pwsh'
- name: 'Install dependencies'
run: 'npm ci'
shell: 'pwsh'
- name: 'Build project'
run: 'npm run build'
shell: 'pwsh'
- name: 'Run E2E tests'
env:
GEMINI_API_KEY: '${{ secrets.GEMINI_API_KEY }}'
KEEP_OUTPUT: 'true'
SANDBOX: 'sandbox:none'
VERBOSE: 'true'
NODE_OPTIONS: '--max-old-space-size=32768 --max-semi-space-size=256'
UV_THREADPOOL_SIZE: '32'
NODE_ENV: 'test'
RUNS: '${{ github.event.inputs.runs }}'
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 }}'"
ECHO 'DEFLAKE WORKFLOW'
+245
View File
@@ -0,0 +1,245 @@
name: 'Testing: E2E'
on:
push:
branches:
- 'main'
# This will run for PRs from the base repository, providing secrets.
pull_request:
branches:
- 'main'
- 'release/**'
# This will run for PRs from forks when a label is added.
pull_request_target:
types: ['labeled']
merge_group:
workflow_dispatch:
inputs:
branch_ref:
description: 'Branch to run on'
required: true
default: 'main'
type: 'string'
concurrency:
group: '${{ github.workflow }}-${{ github.head_ref || github.ref }}'
cancel-in-progress: |-
${{ github.ref != 'refs/heads/main' && !startsWith(github.ref, 'refs/heads/release/') }}
jobs:
merge_queue_skipper:
name: 'Merge Queue Skipper'
runs-on: 'gemini-cli-ubuntu-16-core'
outputs:
skip: '${{ steps.merge-queue-e2e-skipper.outputs.skip-check }}'
steps:
- id: 'merge-queue-e2e-skipper'
uses: 'cariad-tech/merge-queue-ci-skipper@1032489e59437862c90a08a2c92809c903883772' # ratchet:cariad-tech/merge-queue-ci-skipper@main
with:
secret: '${{ secrets.GITHUB_TOKEN }}'
e2e_linux:
name: 'E2E Test (Linux) - ${{ matrix.sandbox }}'
needs: 'merge_queue_skipper'
if: |
needs.merge_queue_skipper.outputs.skip == 'false' &&
(github.event_name == 'push' ||
github.event_name == 'merge_group' ||
github.event_name == 'workflow_dispatch' ||
(github.event.pull_request.head.repo.full_name == github.repository) ||
(github.event.label.name == 'maintainer:e2e:ok'))
runs-on: 'gemini-cli-ubuntu-16-core'
strategy:
fail-fast: false
matrix:
sandbox:
- 'sandbox:none'
- 'sandbox:docker'
node-version:
- '20.x'
steps:
- name: 'Checkout (fork)'
uses: 'actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955' # ratchet:actions/checkout@v5
if: "github.event_name == 'pull_request_target'"
with:
ref: '${{ github.event.pull_request.head.sha }}'
repository: '${{ github.event.pull_request.head.repo.full_name }}'
- name: 'Checkout (internal)'
uses: 'actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955' # ratchet:actions/checkout@v5
if: "github.event_name != 'pull_request_target'"
with:
ref: '${{ github.event.inputs.branch_ref || github.ref }}'
- name: 'Set up Node.js ${{ matrix.node-version }}'
uses: 'actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020' # ratchet:actions-node@v4
with:
node-version: '${{ matrix.node-version }}'
- name: 'Install dependencies'
run: 'npm ci'
- name: 'Build project'
run: 'npm run build'
- name: 'Set up Docker'
if: "matrix.sandbox == 'sandbox:docker'"
uses: 'docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435' # ratchet:docker/setup-buildx-action@v3
- name: 'Run E2E tests'
env:
GEMINI_API_KEY: '${{ secrets.GEMINI_API_KEY }}'
KEEP_OUTPUT: 'true'
VERBOSE: 'true'
shell: 'bash'
run: |
if [[ "${{ matrix.sandbox }}" == "sandbox:docker" ]]; then
npm run test:integration:sandbox:docker
else
npm run test:integration:sandbox:none
fi
e2e_mac:
name: 'E2E Test (macOS)'
needs: 'merge_queue_skipper'
if: |
needs.merge_queue_skipper.outputs.skip == 'false' &&
(github.event_name == 'push' ||
github.event_name == 'merge_group' ||
github.event_name == 'workflow_dispatch' ||
(github.event.pull_request.head.repo.full_name == github.repository) ||
(github.event.label.name == 'maintainer:e2e:ok'))
runs-on: 'macos-latest'
steps:
- name: 'Checkout (fork)'
uses: 'actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955' # ratchet:actions/checkout@v5
if: "github.event_name == 'pull_request_target'"
with:
ref: '${{ github.event.pull_request.head.sha }}'
repository: '${{ github.event.pull_request.head.repo.full_name }}'
- name: 'Checkout (internal)'
uses: 'actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955' # ratchet:actions/checkout@v5
if: "github.event_name != 'pull_request_target'"
with:
ref: '${{ github.event.inputs.branch_ref || github.ref }}'
- name: 'Set up Node.js 20.x'
uses: 'actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020' # ratchet:actions-node@v4
with:
node-version: '20.x'
- name: 'Install dependencies'
run: 'npm ci'
- name: 'Build project'
run: 'npm run build'
- name: 'Fix rollup optional dependencies on macOS'
if: "runner.os == 'macOS'"
run: |
npm cache clean --force
- name: 'Run E2E tests (non-Windows)'
if: "runner.os != 'Windows'"
env:
GEMINI_API_KEY: '${{ secrets.GEMINI_API_KEY }}'
KEEP_OUTPUT: 'true'
SANDBOX: 'sandbox:none'
VERBOSE: 'true'
run: 'npm run test:integration:sandbox:none'
e2e_windows:
name: 'Slow E2E - Win'
needs: 'merge_queue_skipper'
if: |
needs.merge_queue_skipper.outputs.skip == 'false' &&
(github.event_name == 'push' ||
github.event_name == 'merge_group' ||
github.event_name == 'workflow_dispatch' ||
(github.event.pull_request.head.repo.full_name == github.repository) ||
(github.event.label.name == 'maintainer:e2e:ok'))
runs-on: 'gemini-cli-windows-16-core'
continue-on-error: true
steps:
- name: 'Checkout (fork)'
uses: 'actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955' # ratchet:actions/checkout@v5
if: "github.event_name == 'pull_request_target'"
with:
ref: '${{ github.event.pull_request.head.sha }}'
repository: '${{ github.event.pull_request.head.repo.full_name }}'
- name: 'Checkout (internal)'
uses: 'actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955' # ratchet:actions/checkout@v5
if: "github.event_name != 'pull_request_target'"
with:
ref: '${{ github.event.inputs.branch_ref || github.ref }}'
- name: 'Set up Node.js 20.x'
uses: 'actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020' # ratchet:actions-node@v4
with:
node-version: '20.x'
cache: 'npm'
- name: 'Configure Windows Defender exclusions'
run: |
Add-MpPreference -ExclusionPath $env:GITHUB_WORKSPACE -Force
Add-MpPreference -ExclusionPath "$env:GITHUB_WORKSPACE\node_modules" -Force
Add-MpPreference -ExclusionPath "$env:GITHUB_WORKSPACE\packages" -Force
Add-MpPreference -ExclusionPath "$env:TEMP" -Force
shell: 'pwsh'
- name: 'Configure npm for Windows performance'
run: |
npm config set progress false
npm config set audit false
npm config set fund false
npm config set loglevel error
npm config set maxsockets 32
npm config set registry https://registry.npmjs.org/
shell: 'pwsh'
- name: 'Install dependencies'
run: 'npm ci'
shell: 'pwsh'
- name: 'Build project'
run: 'npm run build'
shell: 'pwsh'
- name: 'Run E2E tests'
env:
GEMINI_API_KEY: '${{ secrets.GEMINI_API_KEY }}'
KEEP_OUTPUT: 'true'
SANDBOX: 'sandbox:none'
VERBOSE: 'true'
NODE_OPTIONS: '--max-old-space-size=32768 --max-semi-space-size=256'
UV_THREADPOOL_SIZE: '32'
NODE_ENV: 'test'
shell: 'pwsh'
run: 'npm run test:integration:sandbox:none'
e2e:
name: 'E2E'
if: |
always() && (
github.event_name == 'push' ||
github.event_name == 'merge_group' ||
github.event_name == 'workflow_dispatch' ||
(github.event.pull_request.head.repo.full_name == github.repository) ||
(github.event.label.name == 'maintainer:e2e:ok')
)
needs:
- 'e2e_linux'
- 'e2e_mac'
runs-on: 'gemini-cli-ubuntu-16-core'
steps:
- name: 'Check E2E test results'
run: |
if [[ (${{ needs.e2e_linux.result }} != 'success' && ${{ needs.e2e_linux.result }} != 'skipped') || \
(${{ needs.e2e_mac.result }} != 'success' && ${{ needs.e2e_mac.result }} != 'skipped') ]]; then
echo "One or more E2E jobs failed."
exit 1
fi
echo "All required E2E jobs passed!"
-76
View File
@@ -1,76 +0,0 @@
name: 'Evals: Nightly'
on:
schedule:
- cron: '0 1 * * *' # Runs at 1 AM every day
workflow_dispatch:
inputs:
run_all:
description: 'Run all evaluations (including usually passing)'
type: 'boolean'
default: true
permissions:
contents: 'read'
checks: 'write'
actions: 'read'
jobs:
evals:
name: 'Evals (USUALLY_PASSING) nightly run'
runs-on: 'gemini-cli-ubuntu-16-core'
strategy:
fail-fast: false
matrix:
run_attempt: [1, 2, 3]
steps:
- name: 'Checkout'
uses: 'actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8' # ratchet:actions/checkout@v5
- name: 'Set up Node.js'
uses: 'actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020' # ratchet:actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'npm'
- name: 'Install dependencies'
run: 'npm ci'
- name: 'Build project'
run: 'npm run build'
- name: 'Create logs directory'
run: 'mkdir -p evals/logs'
- name: 'Run Evals'
env:
GEMINI_API_KEY: '${{ secrets.GEMINI_API_KEY }}'
RUN_EVALS: "${{ github.event.inputs.run_all != 'false' }}"
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.run_attempt }}'
path: 'evals/logs'
retention-days: 7
aggregate-results:
name: 'Aggregate Results'
needs: ['evals']
if: 'always()'
runs-on: 'gemini-cli-ubuntu-16-core'
steps:
- name: 'Checkout'
uses: 'actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8' # ratchet:actions/checkout@v5
- name: 'Download Logs'
uses: 'actions/download-artifact@cc203385981b70ca67e1cc392babf9cc229d5806' # ratchet:actions/download-artifact@v4
with:
path: 'artifacts'
- name: 'Generate Summary'
env:
GH_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
run: 'node scripts/aggregate_evals.js artifacts >> "$GITHUB_STEP_SUMMARY"'
@@ -101,6 +101,7 @@ jobs:
"FIRESTORE_DATABASE_ID": "(default)",
"GOOGLE_APPLICATION_CREDENTIALS": "${GOOGLE_APPLICATION_CREDENTIALS}"
},
"enabled": true,
"timeout": 600000
}
},
@@ -14,15 +14,9 @@ on:
description: 'issue number to triage'
required: true
type: 'number'
workflow_call:
inputs:
issue_number:
description: 'issue number to triage'
required: false
type: 'string'
concurrency:
group: '${{ github.workflow }}-${{ github.event.issue.number || github.event.inputs.issue_number || inputs.issue_number }}'
group: '${{ github.workflow }}-${{ github.event.issue.number || github.event.inputs.issue_number }}'
cancel-in-progress: true
defaults:
@@ -40,18 +34,18 @@ permissions:
jobs:
triage-issue:
if: |-
(github.repository == 'google-gemini/gemini-cli' || github.repository == 'google-gemini/maintainers-gemini-cli') &&
github.repository == 'google-gemini/gemini-cli' &&
(
github.event_name == 'workflow_dispatch' ||
(
(github.event_name == 'issues' || github.event_name == 'issue_comment') &&
contains(github.event.issue.labels.*.name, 'status/need-triage') &&
(github.event_name != 'issue_comment' || (
contains(github.event.comment.body, '@gemini-cli /triage') &&
(github.event.comment.author_association == 'OWNER' || github.event.comment.author_association == 'MEMBER' || github.event.comment.author_association == 'COLLABORATOR')
))
)
) &&
!contains(github.event.issue.labels.*.name, 'area/')
)
timeout-minutes: 5
runs-on: 'ubuntu-latest'
steps:
@@ -63,40 +57,30 @@ jobs:
with:
github-token: '${{ secrets.GITHUB_TOKEN }}'
script: |
const issueNumber = ${{ github.event.inputs.issue_number || inputs.issue_number }};
const { data: issue } = await github.rest.issues.get({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issueNumber,
issue_number: ${{ github.event.inputs.issue_number }},
});
core.setOutput('title', issue.title);
core.setOutput('body', issue.body);
core.setOutput('labels', issue.labels.map(label => label.name).join(','));
return issue;
- name: 'Manual Trigger Pre-flight Checks'
- name: 'Check for triage label on manual trigger'
if: |-
github.event_name == 'workflow_dispatch'
github.event_name == 'workflow_dispatch' && !contains(steps.get_issue_data.outputs.labels, 'status/need-triage')
env:
ISSUE_NUMBER_INPUT: '${{ github.event.inputs.issue_number || inputs.issue_number }}'
LABELS: '${{ steps.get_issue_data.outputs.labels }}'
ISSUE_NUMBER_INPUT: '${{ github.event.inputs.issue_number }}'
run: |
if echo "${LABELS}" | grep -q 'area/'; then
echo "Issue #${ISSUE_NUMBER_INPUT} already has 'area/' label. Stopping workflow."
exit 1
fi
echo "Manual triage checks passed."
echo "Issue #${ISSUE_NUMBER_INPUT} does not have the 'status/need-triage' label. Stopping workflow."
exit 1
- name: 'Checkout'
uses: 'actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8' # ratchet:actions/checkout@v5
- 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 }}'
@@ -107,23 +91,13 @@ jobs:
id: 'get_labels'
uses: 'actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea'
with:
github-token: '${{ steps.generate_token.outputs.token || secrets.GITHUB_TOKEN }}'
github-token: '${{ steps.generate_token.outputs.token }}'
script: |-
const { data: labels } = await github.rest.issues.listLabelsForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
});
const allowedLabels = [
'area/agent',
'area/enterprise',
'area/non-interactive',
'area/core',
'area/security',
'area/platform',
'area/extensions',
'area/unknown'
];
const labelNames = labels.map(label => label.name).filter(name => allowedLabels.includes(name));
const labelNames = labels.map(label => label.name);
core.setOutput('available_labels', labelNames.join(','));
core.info(`Found ${labelNames.length} labels: ${labelNames.join(', ')}`);
return labelNames;
@@ -138,7 +112,7 @@ jobs:
ISSUE_BODY: >-
${{ github.event_name == 'workflow_dispatch' && steps.get_issue_data.outputs.body || github.event.issue.body }}
ISSUE_NUMBER: >-
${{ github.event_name == 'workflow_dispatch' && (github.event.inputs.issue_number || inputs.issue_number) || github.event.issue.number }}
${{ github.event_name == 'workflow_dispatch' && github.event.inputs.issue_number || github.event.issue.number }}
REPOSITORY: '${{ github.repository }}'
AVAILABLE_LABELS: '${{ steps.get_labels.outputs.available_labels }}'
with:
@@ -152,6 +126,9 @@ jobs:
settings: |-
{
"maxSessionTurns": 25,
"coreTools": [
"run_shell_command(echo)"
],
"telemetry": {
"enabled": true,
"target": "gcp"
@@ -160,100 +137,128 @@ jobs:
prompt: |-
## Role
You are an issue triage assistant. Your role is to analyze a GitHub issue and determine the single most appropriate area/ label based on the definitions provided.
You are an issue triage assistant. Analyze the current GitHub issue
and identify the most appropriate existing labels by only using the provided data. Use the available
tools to gather information; do not ask for information to be
provided. Do not remove the following labels titled maintainer, help wanted or good first issue.
## Steps
1. Review the issue title and body: ${{ env.ISSUE_TITLE }} and ${{ env.ISSUE_BODY }}.
2. Review the available labels: ${{ env.AVAILABLE_LABELS }}.
3. Select exactly one area/ label that best matches the issue based on Reference 1: Area Definitions.
4. Fallback Logic:
- If you cannot confidently determine the correct area/ label from the definitions, you must use area/unknown.
5. Output your selected label in JSON format and nothing else. Example:
{"labels_to_set": ["area/core"]}
1. You are only able to use the echo command. Review the available labels in the environment variable: "${AVAILABLE_LABELS}".
2. Review the issue title and body provided in the environment variables: "${ISSUE_TITLE}" and "${ISSUE_BODY}".
3. Select the most relevant labels from the existing labels, focusing on kind/*, area/*, sub-area/* and priority/*. For area/* and kind/* limit yourself to only the single most applicable label in each case.
4. If the issue already has area/ label, dont try to change it. Similarly, if the issue already has a kind/ label don't change it. And if the issue already has a priority/ label do not change it for example:
If an issue has area/core and kind/bug you will only add a priority/ label.
Instead if an issue has no labels, you will could add one lable of each kind.
5. For each issue please check if CLI version is present, this is usually in the output of the /about command and will look like 0.1.5 for anything more than 6 versions older than the most recent should add the status/need-retesting label.
6. If you see that the issue doesn't look like it has sufficient information recommend the status/need-information label and leave a comment politely requesting the relevant information, eg.. if repro steps are missing request for repro steps. if version information is missing request for version information into the explanation section below.
7. Output the appropriate labels for this issue in JSON format with explanation, for example:
```
{"labels_to_set": ["kind/bug", "priority/p0"], "explanation": "This is a critical bug report affecting main functionality"}
```
8. If the issue cannot be classified using the available labels, output:
```
{"labels_to_set": [], "explanation": "Unable to classify this issue with available labels"}
```
9. Use Area definitions mentioned below to help you narrow down issues.
10. If you think an issue might be a Priority/P0 do not apply the priority/p0 label. Instead apply a status/manual-triage label and include a note in your explanation.
11. If you are uncertain and have not been able to apply one each of kind/, area/ and priority/ , apply the status/manual-triage label.
## Guidelines
- Your output must contain exactly one area/ label.
- Triage only the current issue based on its title and body.
- Output only valid JSON format.
- Do not include any explanation or additional text, just the JSON.
Reference 1: Area Definitions
area/agent
- Description: Issues related to the "brain" of the CLI. This includes the core agent logic, model quality, tool/function calling, and memory.
- Example Issues:
"I am not getting a reasonable or expected response."
"The model is not calling the tool I expected."
"The web search tool is not working as expected."
"Feature request for a new built-in tool (e.g., read file, write file)."
"The generated code is poor quality or incorrect."
"The model seems stuck in a loop."
"The response from the model is malformed (e.g., broken JSON, bad formatting)."
"Concerns about unnecessary token consumption."
"Issues with how memory or chat history is managed."
"Issues with sub-agents."
"Model is switching from one to another unexpectedly."
- Only use labels that already exist in the repository
- Do not add comments or modify the issue content
- Triage only the current issue
- Identify only one area/ label
- Identify only one kind/ label
- Identify all applicable sub-area/* and priority/* labels based on the issue content. It's ok to have multiple of these
- Once you categorize the issue if it needs information bump down the priority by 1 eg.. a p0 would become a p1 a p1 would become a p2. P2 and P3 can stay as is in this scenario
- Reference all shell variables as "${VAR}" (with quotes and braces)
- Output only valid JSON format
- Do not include any explanation or additional text, just the JSON
area/enterprise
- Description: Issues specific to enterprise-level features, including telemetry, policy, and licenses.
- Example Issues:
"Usage data is not appearing in our telemetry dashboard."
"A user is able to perform an action that should be blocked by an admin policy."
"Questions about billing, licensing tiers, or enterprise quotas."
area/non-interactive
- Description: Issues related to using the CLI in automated or non-interactive environments (headless mode).
- Example Issues:
"Problems using the CLI as an SDK in another surface."
"The CLI is behaving differently when run from a shell script vs. an interactive terminal."
"GitHub action is failing."
"I am having trouble running the CLI in headless mode"
area/core
- Description: Issues with the fundamental CLI app itself. This includes the user interface (UI/UX), installation, OS compatibility, and performance.
- Example Issues:
"I am seeing my screen flicker when using the CLI."
"The output in my terminal is malformed or unreadable."
"Theme changes are not taking effect."
"Keyboard inputs (e.g., arrow keys, Ctrl+C) are not being recognized."
"The CLI failed to install or update."
"An issue specific to running on Windows, macOS, or Linux."
"Problems with command parsing, flags, or argument handling."
"High CPU or memory usage by the CLI process."
"Issues related to multi-modality (e.g., handling image inputs)."
"Problems with the IDE integration connection or installation"
area/security
- Description: Issues related to user authentication, authorization, data security, and privacy.
- Example Issues:
"I am unable to sign in."
"The login flow is selecting the wrong authentication path"
"Problems with API key handling or credential storage."
"A report of a security vulnerability"
"Concerns about data sanitization or potential data leaks."
"Issues or requests related to privacy controls."
"Preventing unauthorized data access."
area/platform
- Description: Issues related to CI/CD, release management, testing, eval infrastructure, capacity, quota management, and sandbox environments.
- Example Issues:
"I am getting a 429 'Resource Exhausted' or 500-level server error."
"General slowness or high latency from the service."
"The build script is broken on the main branch."
"Tests are failing in the CI/CD pipeline."
"Issues with the release management or publishing process."
"User is running out of capacity."
"Problems specific to the sandbox or staging environments."
"Questions about quota limits or requests for increases."
area/extensions
- Description: Issues related to the extension ecosystem, including the marketplace and website.
- Example Issues:
"Bugs related to the extension marketplace website."
"Issues with a specific extension."
"Feature request for the extension ecosystem."
area/unknown
- Description: Issues that do not clearly fit into any other defined area/ category, or where information is too limited to make a determination. Use this when no other area is appropriate.
Categorization Guidelines:
P0: Critical / Blocker
- A P0 bug is a catastrophic failure that demands immediate attention.
- To be a P0 it means almost all users are running into this issue and it is blocking users from being able to use the product.
- You would see this in the form of many comments from different developers on the bug.
- It represents a complete showstopper for a significant portion of users or for the development process itself.
Impact:
- Blocks development or testing for the entire team.
- Major security vulnerability that could compromise user data or system integrity.
- Causes data loss or corruption with no workaround.
- Crashes the application or makes a core feature completely unusable for all or most users in a production environment. Will it cause severe quality degration? Is it preventing contributors from contributing to the repository or is it a release blocker?
Qualifier: Is the main function of the software broken?
Example: The gemini auth login command fails with an unrecoverable error, preventing any user from authenticating and using the rest of the CLI.
P1: High
- A P1 bug is a serious issue that significantly degrades the user experience or impacts a core feature.
- While not a complete blocker, it's a major problem that needs a fast resolution. Feature requests are almost never P1.
- Once again this would be affecting many users.
- You would see this in the form of comments from different developers on the bug.
Impact:
- A core feature is broken or behaving incorrectly for a large number of users or large number of use cases.
- Review the bug details and comments to try figure out if this issue affects a large set of use cases or if it's a narrow set of use cases.
- Severe performance degradation making the application frustratingly slow.
- No straightforward workaround exists, or the workaround is difficult and non-obvious.
Qualifier: Is a key feature unusable or giving very wrong results?
Example: Gemini CLI enters a loop when making read-many-files tool call. I am unable to break out of the loop and gemini doesn't follow instructions subsequently.
P2: Medium
- A P2 bug is a moderately impactful issue. It's a noticeable problem but doesn't prevent the use of the software's main functionality.
Impact:
- Affects a non-critical feature or a smaller, specific subset of users.
- An inconvenient but functional workaround is available and easy to execute.
- Noticeable UI/UX problems that don't break functionality but look unprofessional (e.g., elements are misaligned or overlapping).
Qualifier: Is it an annoying but non-blocking problem?
Example: An error message is unclear or contains a typo, causing user confusion but not halting their workflow.
P3: Low
- A P3 bug is a minor, low-impact issue that is trivial or cosmetic. It has little to no effect on the overall functionality of the application.
Impact:
- Minor cosmetic issues like color inconsistencies, typos in documentation, or slight alignment problems on a non-critical page.
- An edge-case bug that is very difficult to reproduce and affects a tiny fraction of users.
Qualifier: Is it a "nice-to-fix" issue?
Example: Spelling mistakes etc.
Things you should know:
- If users are talking about issues where the model gets downgraded from pro to flash then i want you to categorize that as a performance issue
- This product is designed to use different models eg.. using pro, downgrading to flash etc. when users report that they dont expect the model to change those would be categorized as feature requests.
Definition of Areas
area/ux:
- Issues concerning user-facing elements like command usability, interactive features, help docs, and perceived performance.
- I am seeing my screen flicker when using Gemini CLI
- I am seeing the output malformed
- Theme changes aren't taking effect
- My keyboard inputs arent' being recognzied
area/platform:
- Issues related to installation, packaging, OS compatibility (Windows, macOS, Linux), and the underlying CLI framework.
area/background: Issues related to long-running background tasks, daemons, and autonomous or proactive agent features.
area/models:
- i am not getting a response that is reasonable or expected. this can include things like
- I am calling a tool and the tool is not performing as expected.
- i am expecting a tool to be called and it is not getting called ,
- Including experience when using
- built-in tools (e.g., web search, code interpreter, read file, writefile, etc..),
- Function calling issues should be under this area
- i am getting responses from the model that are malformed.
- Issues concerning Gemini quality of response and inference,
- Issues talking about unnecessary token consumption.
- Issues talking about Model getting stuck in a loop be watchful as this could be the root cause for issues that otherwise seem like model performance issues.
- Memory compression
- unexpected responses,
- poor quality of generated code
area/tools:
- These are primarily issues related to Model Context Protocol
- These are issues that mention MCP support
- feature requests asking for support for new tools.
area/core: Issues with fundamental components like command parsing, configuration management, session state, and the main API client logic. Introducing multi-modality
area/contribution: Issues related to improving the developer contribution experience, such as CI/CD pipelines, build scripts, and test automation infrastructure.
area/authentication: Issues related to user identity, login flows, API key handling, credential storage, and access token management, unable to sign in selecting wrong authentication path etc..
area/security-privacy: Issues concerning vulnerability patching, dependency security, data sanitization, privacy controls, and preventing unauthorized data access.
area/extensibility: Issues related to the plugin system, extension APIs, or making the CLI's functionality available in other applications, github actions, ide support etc..
area/performance: Issues focused on model performance
- Issues with running out of capacity,
- 429 errors etc..
- could also pertain to latency,
- other general software performance like, memory usage, CPU consumption, and algorithmic efficiency.
- Switching models from one to the other unexpectedly.
- name: 'Apply Labels to Issue'
if: |-
@@ -264,47 +269,54 @@ jobs:
LABELS_OUTPUT: '${{ steps.gemini_issue_analysis.outputs.summary }}'
uses: 'actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea'
with:
github-token: '${{ steps.generate_token.outputs.token || secrets.GITHUB_TOKEN }}'
script: |
const rawOutput = process.env.LABELS_OUTPUT;
core.info(`Raw output from model: ${rawOutput}`);
github-token: '${{ steps.generate_token.outputs.token }}'
script: |-
// Strip code block markers if present
const rawLabels = process.env.LABELS_OUTPUT;
core.info(`Raw labels JSON: ${rawLabels}`);
let parsedLabels;
try {
// First, try to parse the raw output as JSON.
parsedLabels = JSON.parse(rawOutput);
} catch (jsonError) {
// If that fails, check for a markdown code block.
core.warning(`Direct JSON parsing failed: ${jsonError.message}. Trying to extract from a markdown block.`);
const jsonMatch = rawOutput.match(/```json\s*([\s\S]*?)\s*```/);
if (jsonMatch && jsonMatch[1]) {
try {
parsedLabels = JSON.parse(jsonMatch[1].trim());
} catch (markdownError) {
core.setFailed(`Failed to parse JSON even after extracting from markdown block: ${markdownError.message}\nRaw output: ${rawOutput}`);
return;
}
} else {
core.setFailed(`Output is not valid JSON and does not contain a JSON markdown block.\nRaw output: ${rawOutput}`);
return;
const jsonMatch = rawLabels.match(/```json\s*([\s\S]*?)\s*```/);
if (!jsonMatch || !jsonMatch[1]) {
throw new Error("Could not find a ```json ... ``` block in the output.");
}
}
const issueNumber = parseInt(process.env.ISSUE_NUMBER);
const labelsToAdd = parsedLabels.labels_to_set || [];
if (labelsToAdd.length !== 1) {
core.setFailed(`Expected exactly 1 label (area/), but got ${labelsToAdd.length}. Labels: ${labelsToAdd.join(', ')}`);
const jsonString = jsonMatch[1].trim();
parsedLabels = JSON.parse(jsonString);
core.info(`Parsed labels JSON: ${JSON.stringify(parsedLabels)}`);
} catch (err) {
core.setFailed(`Failed to parse labels JSON from Gemini output: ${err.message}\nRaw output: ${rawLabels}`);
return;
}
const issueNumber = parseInt(process.env.ISSUE_NUMBER);
const explanation = parsedLabels.explanation || '';
const labelsToSet = parsedLabels.labels_to_set || [];
labelsToSet.push('status/bot-triaged');
// Set labels based on triage result
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issueNumber,
labels: labelsToAdd
});
core.info(`Successfully added labels for #${issueNumber}: ${labelsToAdd.join(', ')}`);
if (labelsToSet.length > 0) {
await github.rest.issues.setLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issueNumber,
labels: labelsToSet
});
const explanationInfo = explanation ? ` - ${explanation}` : '';
core.info(`Successfully set labels for #${issueNumber}: ${labelsToSet.join(', ')}${explanationInfo}`);
} else {
// If no labels to set, leave the issue as is
const explanationInfo = explanation ? ` - ${explanation}` : '';
core.info(`No labels to set for #${issueNumber}, leaving as is${explanationInfo}`);
}
if (explanation) {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issueNumber,
body: explanation,
});
}
- name: 'Post Issue Analysis Failure Comment'
if: |-
@@ -314,7 +326,7 @@ jobs:
RUN_URL: '${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}'
uses: 'actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea'
with:
github-token: '${{ steps.generate_token.outputs.token || secrets.GITHUB_TOKEN }}'
github-token: '${{ steps.generate_token.outputs.token }}'
script: |-
github.rest.issues.createComment({
owner: context.repo.owner,
@@ -81,6 +81,7 @@ jobs:
"FIRESTORE_DATABASE_ID": "(default)",
"GOOGLE_APPLICATION_CREDENTIALS": "${GOOGLE_APPLICATION_CREDENTIALS}"
},
"enabled": true,
"timeout": 600000
}
},
@@ -1,16 +1,12 @@
name: '📋 Gemini Scheduled Issue Triage'
on:
issues:
types:
- 'opened'
- 'reopened'
schedule:
- cron: '0 * * * *' # Runs every hour
workflow_dispatch:
concurrency:
group: '${{ github.workflow }}-${{ github.event.number || github.run_id }}'
group: '${{ github.workflow }}'
cancel-in-progress: true
defaults:
@@ -39,21 +35,7 @@ jobs:
private-key: '${{ secrets.PRIVATE_KEY }}'
permission-issues: 'write'
- name: 'Get issue from event'
if: |-
${{ github.event_name == 'issues' }}
id: 'get_issue_from_event'
env:
ISSUE_EVENT: '${{ toJSON(github.event.issue) }}'
run: |
set -euo pipefail
ISSUE_JSON=$(echo "$ISSUE_EVENT" | jq -c '[{number: .number, title: .title, body: .body}]')
echo "issues_to_triage=${ISSUE_JSON}" >> "${GITHUB_OUTPUT}"
echo "✅ Found issue #${{ github.event.issue.number }} from event to triage! 🎯"
- name: 'Find untriaged issues'
if: |-
${{ github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' }}
id: 'find_issues'
env:
GITHUB_TOKEN: '${{ steps.generate_token.outputs.token }}'
@@ -61,26 +43,22 @@ jobs:
run: |-
set -euo pipefail
echo '🔍 Finding issues missing area labels...'
NO_AREA_ISSUES="$(gh issue list --repo "${GITHUB_REPOSITORY}" \
--search 'is:open is:issue -label:area/core -label:area/agent -label:area/enterprise -label:area/non-interactive -label:area/security -label:area/platform -label:area/extensions -label:area/unknown' --limit 100 --json number,title,body)"
echo '🔍 Finding issues without labels...'
NO_LABEL_ISSUES="$(gh issue list --repo "${GITHUB_REPOSITORY}" \
--search 'is:open is:issue no:label' --json number,title,body)"
echo '🔍 Finding issues missing kind labels...'
NO_KIND_ISSUES="$(gh issue list --repo "${GITHUB_REPOSITORY}" \
--search 'is:open is:issue -label:kind/bug -label:kind/enhancement -label:kind/customer-issue -label:kind/question' --limit 100 --json number,title,body)"
echo '🏷️ Finding issues missing priority labels...'
NO_PRIORITY_ISSUES="$(gh issue list --repo "${GITHUB_REPOSITORY}" \
--search 'is:open is:issue -label:priority/p0 -label:priority/p1 -label:priority/p2 -label:priority/p3 -label:priority/unknown' --limit 100 --json number,title,body)"
echo '🏷️ Finding issues that need triage...'
NEED_TRIAGE_ISSUES="$(gh issue list --repo "${GITHUB_REPOSITORY}" \
--search "is:open is:issue label:\"status/need-triage\"" --limit 1000 --json number,title,body)"
echo '🔄 Merging and deduplicating issues...'
ISSUES="$(echo "${NO_AREA_ISSUES}" "${NO_KIND_ISSUES}" "${NO_PRIORITY_ISSUES}" | jq -c -s 'add | unique_by(.number)')"
ISSUES="$(echo "${NO_LABEL_ISSUES}" "${NEED_TRIAGE_ISSUES}" | jq -c -s 'add | unique_by(.number)')"
echo '📝 Setting output for GitHub Actions...'
echo "issues_to_triage=${ISSUES}" >> "${GITHUB_OUTPUT}"
ISSUE_COUNT="$(echo "${ISSUES}" | jq 'length')"
echo "✅ Found ${ISSUE_COUNT} unique issues to triage! 🎯"
echo "✅ Found ${ISSUE_COUNT} issues to triage! 🎯"
- name: 'Get Repository Labels'
id: 'get_labels'
@@ -99,13 +77,12 @@ jobs:
- name: 'Run Gemini Issue Analysis'
if: |-
(steps.get_issue_from_event.outputs.issues_to_triage != '' && steps.get_issue_from_event.outputs.issues_to_triage != '[]') ||
(steps.find_issues.outputs.issues_to_triage != '' && steps.find_issues.outputs.issues_to_triage != '[]')
${{ steps.find_issues.outputs.issues_to_triage != '[]' }}
uses: 'google-github-actions/run-gemini-cli@a3bf79042542528e91937b3a3a6fbc4967ee3c31' # ratchet:google-github-actions/run-gemini-cli@v0
id: 'gemini_issue_analysis'
env:
GITHUB_TOKEN: '' # Do not pass any auth token here since this runs on untrusted inputs
ISSUES_TO_TRIAGE: '${{ steps.get_issue_from_event.outputs.issues_to_triage || steps.find_issues.outputs.issues_to_triage }}'
ISSUES_TO_TRIAGE: '${{ steps.find_issues.outputs.issues_to_triage }}'
REPOSITORY: '${{ github.repository }}'
AVAILABLE_LABELS: '${{ steps.get_labels.outputs.available_labels }}'
with:
@@ -139,32 +116,38 @@ jobs:
1. You are only able to use the echo command. Review the available labels in the environment variable: "${AVAILABLE_LABELS}".
2. Check environment variable for issues to triage: $ISSUES_TO_TRIAGE (JSON array of issues)
3. Review the issue title, body and any comments provided in the environment variables.
4. Identify the most relevant labels from the existing labels, specifically focusing on area/*, kind/* and priority/*.
5. Label Policy:
- If the issue already has a kind/ label, do not change it.
- If the issue already has a priority/ label, do not change it.
- If the issue already has an area/ label, do not change it.
- If any of these are missing, select exactly ONE appropriate label for the missing category.
4. Identify the most relevant labels from the existing labels, focusing on kind/*, area/*, sub-area/* and priority/*.
5. If the issue already has area/ label, dont try to change it. Similarly, if the issue already has a kind/ label don't change it. And if the issue already has a priority/ label do not change it for example:
If an issue has area/core and kind/bug you will only add a priority/ label.
Instead if an issue has no labels, you will could add one lable of each kind.
6. Identify other applicable labels based on the issue content, such as status/*, help wanted, good first issue, etc.
7. Give me a single short explanation about why you are selecting each label in the process.
8. Output a JSON array of objects, each containing the issue number
7. For area/* and kind/* limit yourself to only the single most applicable label in each case.
8. Give me a single short explanation about why you are selecting each label in the process.
9. Output a JSON array of objects, each containing the issue number
and the labels to add and remove, along with an explanation. For example:
```
[
{
"issue_number": 123,
"labels_to_add": ["area/core", "kind/bug", "priority/p2"],
"labels_to_add": ["kind/bug", "priority/p2"],
"labels_to_remove": ["status/need-triage"],
"explanation": "This issue is a UI bug that needs to be addressed with medium priority."
"explanation": "This issue is a bug that needs to be addressed with medium priority."
},
{
"issue_number": 456,
"labels_to_add": ["kind/enhancement"],
"labels_to_remove": [],
"explanation": "This issue is an enhancement request that could improve the user experience."
}
]
```
If an issue cannot be classified, do not include it in the output array.
9. For each issue please check if CLI version is present, this is usually in the output of the /about command and will look like 0.1.5
10. For each issue please check if CLI version is present, this is usually in the output of the /about command and will look like 0.1.5
- Anything more than 6 versions older than the most recent should add the status/need-retesting label
10. If you see that the issue doesn't look like it has sufficient information recommend the status/need-information label and leave a comment politely requesting the relevant information, eg.. if repro steps are missing request for repro steps. if version information is missing request for version information into the explanation section below.
11. If you think an issue might be a Priority/P0 do not apply the priority/p0 label. Instead apply a status/manual-triage label and include a note in your explanation.
12. If you are uncertain about a category, use the area/unknown, kind/question, or priority/unknown labels as appropriate. If you are extremely uncertain, apply the status/manual-triage label.
11. If you see that the issue doesn't look like it has sufficient information recommend the status/need-information label and leave a comment politely requesting the relevant information, eg.. if repro steps are missing request for repro steps. if version information is missing request for version information into the explanation section below.
- After identifying appropriate labels to an issue, add "status/need-triage" label to labels_to_remove in the output.
12. If you think an issue might be a Priority/P0 do not apply the priority/p0 label. Instead apply a status/manual-triage label and include a note in your explanation.
13. If you are uncertain and have not been able to apply one each of kind/, area/ and priority/ , apply the status/manual-triage label.
## Guidelines
@@ -174,46 +157,100 @@ jobs:
- Do not add comments or modify the issue content.
- Do not remove the following labels maintainer, help wanted or good first issue.
- Triage only the current issue.
- Identify only one area/ label.
- Identify only one area/ label
- Identify only one kind/ label (Do not apply kind/duplicate or kind/parent-issue)
- Identify only one priority/ label.
- Identify all applicable sub-area/* and priority/* labels based on the issue content. It's ok to have multiple of these.
- Once you categorize the issue if it needs information bump down the priority by 1 eg.. a p0 would become a p1 a p1 would become a p2. P2 and P3 can stay as is in this scenario.
Categorization Guidelines (Priority):
P0 - Urgent Blocking Issues:
- DO NOT APPLY THIS LABEL AUTOMATICALLY. Use status/manual-triage instead.
- Definition: Urgent, block a significant percentage of the user base, and prevent frequent use of the Gemini CLI.
- This includes core stability blockers (e.g., authentication failures, broken upgrades), critical crashes, and P0 security vulnerabilities.
- Impact: Blocks development or testing for the entire team; Major security vulnerability; Causes data loss or corruption with no workaround; Crashes the application or makes a core feature completely unusable for all or most users.
- Qualifier: Is the main function of the software broken?
P1 - High-Impact Issues:
- Definition: Affect a large number of users, blocking them from using parts of the Gemini CLI, or make the CLI frequently unusable even with workarounds available.
- Impact: A core feature is broken or behaving incorrectly for a large number of users or use cases; Severe performance degradation; No straightforward workaround exists.
- Qualifier: Is a key feature unusable or giving very wrong results?
P2 - Significant Issues:
- Definition: Affect some users significantly, such as preventing the use of certain features or authentication types.
- Can also be issues that many users complain about, causing annoyance or hindering daily use.
- Impact: Affects a non-critical feature or a smaller, specific subset of users; An inconvenient but functional workaround is available; Noticeable UI/UX problems that look unprofessional.
- Qualifier: Is it an annoying but non-blocking problem?
P3 - Low-Impact Issues:
- Definition: Typically usability issues that cause annoyance to a limited user base.
- Includes feature requests that could be addressed in the near future and may be suitable for community contributions.
- Impact: Minor cosmetic issues; An edge-case bug that is very difficult to reproduce and affects a tiny fraction of users.
- Qualifier: Is it a "nice-to-fix" issue?
Categorization Guidelines (Area):
area/agent: Core Agent, Tools, Memory, Sub-Agents, Hooks, Agent Quality
area/core: User Interface, OS Support, Core Functionality
area/enterprise: Telemetry, Policy, Quota / Licensing
area/extensions: Gemini CLI extensions capability
area/non-interactive: GitHub Actions, SDK, 3P Integrations, Shell Scripting, Command line automation
area/platform: Build infra, Release mgmt, Testing, Eval infra, Capacity, Quota mgmt
area/security: security related issues
Categorization Guidelines:
P0: Critical / Blocker
- A P0 bug is a catastrophic failure that demands immediate attention.
- To be a P0 it means almost all users are running into this issue and it is blocking users from being able to use the product.
- You would see this in the form of many comments from different developers on the bug.
- It represents a complete showstopper for a significant portion of users or for the development process itself.
Impact:
- Blocks development or testing for the entire team.
- Major security vulnerability that could compromise user data or system integrity.
- Causes data loss or corruption with no workaround.
- Crashes the application or makes a core feature completely unusable for all or most users in a production environment. Will it cause severe quality degration?
- Is it preventing contributors from contributing to the repository or is it a release blocker?
Qualifier: Is the main function of the software broken?
Example: The gemini auth login command fails with an unrecoverable error, preventing any user from authenticating and using the rest of the CLI.
P1: High
- A P1 bug is a serious issue that significantly degrades the user experience or impacts a core feature.
- While not a complete blocker, it's a major problem that needs a fast resolution. Feature requests are almost never P1.
- Once again this would be affecting many users.
- You would see this in the form of comments from different developers on the bug.
Impact:
- A core feature is broken or behaving incorrectly for a large number of users or large number of use cases.
- Review the bug details and comments to try figure out if this issue affects a large set of use cases or if it's a narrow set of use cases.
- Severe performance degradation making the application frustratingly slow.
- No straightforward workaround exists, or the workaround is difficult and non-obvious.
Qualifier: Is a key feature unusable or giving very wrong results?
Example: Gemini CLI enters a loop when making read-many-files tool call. I am unable to break out of the loop and gemini doesn't follow instructions subsequently.
P2: Medium
- A P2 bug is a moderately impactful issue. It's a noticeable problem but doesn't prevent the use of the software's main functionality.
Impact:
- Affects a non-critical feature or a smaller, specific subset of users.
- An inconvenient but functional workaround is available and easy to execute.
- Noticeable UI/UX problems that don't break functionality but look unprofessional (e.g., elements are misaligned or overlapping).
Qualifier: Is it an annoying but non-blocking problem?
Example: An error message is unclear or contains a typo, causing user confusion but not halting their workflow.
P3: Low
- A P3 bug is a minor, low-impact issue that is trivial or cosmetic. It has little to no effect on the overall functionality of the application.
Impact:
- Minor cosmetic issues like color inconsistencies, typos in documentation, or slight alignment problems on a non-critical page.
- An edge-case bug that is very difficult to reproduce and affects a tiny fraction of users.
Qualifier: Is it a "nice-to-fix" issue?
Example: Spelling mistakes etc.
Additional Context:
- If users are talking about issues where the model gets downgraded from pro to flash then i want you to categorize that as a performance issue.
- This product is designed to use different models eg.. using pro, downgrading to flash etc.
- When users report that they dont expect the model to change those would be categorized as feature requests.
- If users are talking about issues where the model gets downgraded from pro to flash then i want you to categorize that as a performance issue
- This product is designed to use different models eg.. using pro, downgrading to flash etc.
- When users report that they dont expect the model to change those would be categorized as feature requests.
Definition of Areas
area/ux:
- Issues concerning user-facing elements like command usability, interactive features, help docs, and perceived performance.
- I am seeing my screen flicker when using Gemini CLI
- I am seeing the output malformed
- Theme changes aren't taking effect
- My keyboard inputs arent' being recognzied
area/platform:
- Issues related to installation, packaging, OS compatibility (Windows, macOS, Linux), and the underlying CLI framework.
area/background: Issues related to long-running background tasks, daemons, and autonomous or proactive agent features.
area/models:
- i am not getting a response that is reasonable or expected. this can include things like
- I am calling a tool and the tool is not performing as expected.
- i am expecting a tool to be called and it is not getting called ,
- Including experience when using
- built-in tools (e.g., web search, code interpreter, read file, writefile, etc..),
- Function calling issues should be under this area
- i am getting responses from the model that are malformed.
- Issues concerning Gemini quality of response and inference,
- Issues talking about unnecessary token consumption.
- Issues talking about Model getting stuck in a loop be watchful as this could be the root cause for issues that otherwise seem like model performance issues.
- Memory compression
- unexpected responses,
- poor quality of generated code
area/tools:
- These are primarily issues related to Model Context Protocol
- These are issues that mention MCP support
- feature requests asking for support for new tools.
area/core:
- Issues with fundamental components like command parsing, configuration management, session state, and the main API client logic. Introducing multi-modality
area/contribution:
- Issues related to improving the developer contribution experience, such as CI/CD pipelines, build scripts, and test automation infrastructure.
area/authentication:
- Issues related to user identity, login flows, API key handling, credential storage, and access token management, unable to sign in selecting wrong authentication path etc..
area/security-privacy:
- Issues concerning vulnerability patching, dependency security, data sanitization, privacy controls, and preventing unauthorized data access.
area/extensibility:
- Issues related to the plugin system, extension APIs, or making the CLI's functionality available in other applications, github actions, ide support etc..
area/performance:
- Issues focused on model performance
- Issues with running out of capacity,
- 429 errors etc..
- could also pertain to latency,
- other general software performance like, memory usage, CPU consumption, and algorithmic efficiency.
- Switching models from one to the other unexpectedly.
- name: 'Apply Labels to Issues'
if: |-
@@ -263,6 +300,24 @@ jobs:
core.info(`Successfully added labels for #${issueNumber}: ${labelsToAdd.join(', ')}${explanation}`);
}
if (entry.labels_to_remove && entry.labels_to_remove.length > 0) {
for (const label of entry.labels_to_remove) {
try {
await github.rest.issues.removeLabel({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issueNumber,
name: label
});
} catch (error) {
if (error.status !== 404) {
throw error;
}
}
}
core.info(`Successfully removed labels for #${issueNumber}: ${entry.labels_to_remove.join(', ')}`);
}
if (entry.explanation) {
await github.rest.issues.createComment({
owner: context.repo.owner,
@@ -39,7 +39,3 @@ jobs:
GITHUB_REPOSITORY: '${{ github.repository }}'
run: |-
./.github/scripts/pr-triage.sh
# If prs_needing_comment is empty, set it to [] explicitly for downstream steps
if [[ -z "$(grep 'prs_needing_comment' "${GITHUB_OUTPUT}" | cut -d'=' -f2-)" ]]; then
echo "prs_needing_comment=[]" >> "${GITHUB_OUTPUT}"
fi
@@ -1,152 +0,0 @@
name: '🔒 Gemini Scheduled Stale Issue Closer'
on:
schedule:
- cron: '0 0 * * 0' # Every Sunday at midnight UTC
workflow_dispatch:
inputs:
dry_run:
description: 'Run in dry-run mode (no changes applied)'
required: false
default: false
type: 'boolean'
concurrency:
group: '${{ github.workflow }}'
cancel-in-progress: true
defaults:
run:
shell: 'bash'
jobs:
close-stale-issues:
runs-on: 'ubuntu-latest'
permissions:
issues: 'write'
steps:
- name: 'Generate GitHub App Token'
id: 'generate_token'
uses: 'actions/create-github-app-token@v1'
with:
app-id: '${{ secrets.APP_ID }}'
private-key: '${{ secrets.PRIVATE_KEY }}'
permission-issues: 'write'
- name: 'Process Stale Issues'
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';
if (dryRun) {
core.info('DRY RUN MODE ENABLED: No changes will be applied.');
}
const batchLabel = 'Stale';
const threeMonthsAgo = new Date();
threeMonthsAgo.setMonth(threeMonthsAgo.getMonth() - 3);
const tenDaysAgo = new Date();
tenDaysAgo.setDate(tenDaysAgo.getDate() - 10);
core.info(`Cutoff date for creation: ${threeMonthsAgo.toISOString()}`);
core.info(`Cutoff date for updates: ${tenDaysAgo.toISOString()}`);
const query = `repo:${context.repo.owner}/${context.repo.repo} is:issue is:open created:<${threeMonthsAgo.toISOString()}`;
core.info(`Searching with query: ${query}`);
const itemsToCheck = await github.paginate(github.rest.search.issuesAndPullRequests, {
q: query,
sort: 'created',
order: 'asc',
per_page: 100
});
core.info(`Found ${itemsToCheck.length} open issues to check.`);
let processedCount = 0;
for (const issue of itemsToCheck) {
const createdAt = new Date(issue.created_at);
const updatedAt = new Date(issue.updated_at);
const reactionCount = issue.reactions.total_count;
// Basic thresholds
if (reactionCount >= 5) {
continue;
}
// Skip if it has a maintainer label
if (issue.labels.some(label => label.name.toLowerCase().includes('maintainer'))) {
continue;
}
let isStale = updatedAt < tenDaysAgo;
// If apparently active, check if it's only bot activity
if (!isStale) {
try {
const comments = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
per_page: 100,
sort: 'created',
direction: 'desc'
});
const lastHumanComment = comments.data.find(comment => comment.user.type !== 'Bot');
if (lastHumanComment) {
isStale = new Date(lastHumanComment.created_at) < tenDaysAgo;
} else {
// No human comments. Check if creator is human.
if (issue.user.type !== 'Bot') {
isStale = createdAt < tenDaysAgo;
} else {
isStale = true; // Bot created, only bot comments
}
}
} catch (error) {
core.warning(`Failed to fetch comments for issue #${issue.number}: ${error.message}`);
continue;
}
}
if (isStale) {
processedCount++;
const message = `Closing stale issue #${issue.number}: "${issue.title}" (${issue.html_url})`;
core.info(message);
if (!dryRun) {
// Add label
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
labels: [batchLabel]
});
// Add comment
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
body: 'Hello! As part of our effort to keep our backlog manageable and focus on the most active issues, we are tidying up older reports.\n\nIt looks like this issue hasn\'t been active for a while, so we are closing it for now. However, if you are still experiencing this bug on the latest stable build, please feel free to comment on this issue or create a new one with updated details.\n\nThank you for your contribution!'
});
// Close issue
await github.rest.issues.update({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
state: 'closed',
state_reason: 'not_planned'
});
}
}
}
core.info(`\nTotal issues processed: ${processedCount}`);
@@ -1,46 +0,0 @@
name: '🏷️ Issue Opened Labeler'
on:
issues:
types:
- 'opened'
jobs:
label-issue:
runs-on: 'ubuntu-latest'
if: |-
${{ github.repository == 'google-gemini/gemini-cli' || github.repository == 'google-gemini/maintainers-gemini-cli' }}
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: 'Add need-triage label'
uses: 'actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea'
with:
github-token: '${{ steps.generate_token.outputs.token || secrets.GITHUB_TOKEN }}'
script: |-
const { data: issue } = await github.rest.issues.get({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
});
const hasLabel = issue.labels.some(l => l.name === 'status/need-triage');
if (!hasLabel) {
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
labels: ['status/need-triage']
});
} else {
core.info('Issue already has status/need-triage label. Skipping.');
}
@@ -1,57 +0,0 @@
name: 'Label Child Issues for Project Rollup'
on:
issues:
types: ['opened', 'edited', 'reopened']
schedule:
- cron: '0 * * * *' # Run every hour
workflow_dispatch:
permissions:
issues: 'write'
contents: 'read'
jobs:
# Event-based: Quick reaction to new/edited issues in THIS repo
labeler:
if: "github.event_name == 'issues'"
runs-on: 'ubuntu-latest'
steps:
- name: 'Checkout'
uses: 'actions/checkout@v4'
- name: 'Setup Node.js'
uses: 'actions/setup-node@v4'
with:
node-version: '20'
cache: 'npm'
- name: 'Install Dependencies'
run: 'npm ci'
- name: 'Run Multi-Repo Sync Script'
env:
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
run: 'node .github/scripts/sync-maintainer-labels.cjs'
# Scheduled/Manual: Recursive sync across multiple repos
sync-maintainer-labels:
if: "github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'"
runs-on: 'ubuntu-latest'
steps:
- name: 'Checkout'
uses: 'actions/checkout@v4'
- name: 'Setup Node.js'
uses: 'actions/setup-node@v4'
with:
node-version: '20'
cache: 'npm'
- name: 'Install Dependencies'
run: 'npm ci'
- name: 'Run Multi-Repo Sync Script'
env:
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
run: 'node .github/scripts/sync-maintainer-labels.cjs'
-119
View File
@@ -1,119 +0,0 @@
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
});
}
}
@@ -1,94 +0,0 @@
name: 'Label Workstream Rollup'
on:
issues:
types: ['opened', 'edited', 'reopened']
schedule:
- cron: '0 * * * *'
workflow_dispatch:
jobs:
labeler:
runs-on: 'ubuntu-latest'
permissions:
issues: 'write'
steps:
- name: 'Check for Parent Workstream and Apply Label'
uses: 'actions/github-script@v7'
with:
script: |
const labelToAdd = 'workstream-rollup';
// Allow-list of parent issue URLs
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'
];
async function getIssueParent(owner, repo, number) {
const query = `
query($owner:String!, $repo:String!, $number:Int!) {
repository(owner:$owner, name:$repo) {
issue(number:$number) {
parent {
url
}
}
}
}
`;
try {
const result = await github.graphql(query, { owner, repo, number });
return result.repository.issue.parent ? result.repository.issue.parent.url : null;
} catch (error) {
console.error(`Failed to fetch parent for #${number}:`, error);
return null;
}
}
// Determine which issues to process
let issuesToProcess = [];
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
}));
}
console.log(`Processing ${issuesToProcess.length} issue(s)...`);
for (const issue of issuesToProcess) {
const parentUrl = await getIssueParent(issue.owner, issue.repo, 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 {
// logging only for single execution to avoid spam
if (context.eventName === 'issues') {
console.log(`Issue #${issue.number} parent is ${parentUrl || 'None'}. No action.`);
}
}
}
-25
View File
@@ -1,25 +0,0 @@
name: 'Links'
on:
push:
branches: ['main']
pull_request:
branches: ['main']
repository_dispatch:
workflow_dispatch:
schedule:
- cron: '00 18 * * *'
jobs:
linkChecker:
if: |-
${{ github.repository == 'google-gemini/gemini-cli' }}
runs-on: 'ubuntu-latest'
steps:
- uses: 'actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8' # ratchet:actions/checkout@v5
- name: 'Link Checker'
id: 'lychee'
uses: 'lycheeverse/lychee-action@885c65f3dc543b57c898c8099f4e08c8afd178a2' # ratchet: lycheeverse/lychee-action@v2.6.1
with:
args: '--verbose --no-progress --accept 200,503 ./**/*.md'
@@ -1,83 +0,0 @@
name: '🏷️ PR Contribution Guidelines Notifier'
on:
pull_request:
types:
- 'opened'
jobs:
notify-process-change:
runs-on: 'ubuntu-latest'
if: |-
github.repository == 'google-gemini/gemini-cli' || github.repository == 'google-gemini/maintainers-gemini-cli'
permissions:
pull-requests: '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 membership and post comment'
uses: 'actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea'
with:
github-token: '${{ steps.generate_token.outputs.token || secrets.GITHUB_TOKEN }}'
script: |-
const org = context.repo.owner;
const repo = context.repo.repo;
const username = context.payload.pull_request.user.login;
const pr_number = context.payload.pull_request.number;
// 1. Check if the PR author is a maintainer
const authorAssociation = context.payload.pull_request.author_association;
if (['OWNER', 'MEMBER', 'COLLABORATOR'].includes(authorAssociation)) {
core.info(`${username} is a maintainer (Association: ${authorAssociation}). No notification needed.`);
return;
}
// 2. Check if the PR is already associated with an issue
const query = `
query($owner:String!, $repo:String!, $number:Int!) {
repository(owner:$owner, name:$repo) {
pullRequest(number:$number) {
closingIssuesReferences(first: 1) {
totalCount
}
}
}
}
`;
const variables = { owner: org, repo: repo, number: pr_number };
const result = await github.graphql(query, variables);
const issueCount = result.repository.pullRequest.closingIssuesReferences.totalCount;
if (issueCount > 0) {
core.info(`PR #${pr_number} is already associated with an issue. No notification needed.`);
return;
}
// 3. Post the notification comment
core.info(`${username} is not a maintainer and PR #${pr_number} has no linked issue. Posting notification.`);
const comment = `
Hi @${username}, thank you so much for your contribution to Gemini CLI! We really appreciate the time and effort you've put into this.
We're making some updates to our contribution process to improve how we track and review changes. Please take a moment to review our recent discussion post: [Improving Our Contribution Process & Introducing New Guidelines](https://github.com/google-gemini/gemini-cli/discussions/16706).
Key Update: Starting **January 26, 2026**, the Gemini CLI project will require all pull requests to be associated with an existing issue. Any pull requests not linked to an issue by that date will be automatically closed.
Thank you for your understanding and for being a part of our community!
`.trim().replace(/^[ ]+/gm, '');
await github.rest.issues.createComment({
owner: org,
repo: repo,
issue_number: pr_number,
body: comment
});
+1 -1
View File
@@ -132,4 +132,4 @@ jobs:
gh issue create \
--title 'Manual Release Failed for ${RELEASE_TAG} on $(date +'%Y-%m-%d')' \
--body 'The manual release workflow failed. See the full run for details: ${DETAILS_URL}' \
--label 'release-failure,priority/p0'
--label 'kind/bug,release-failure,priority/p0'
+2 -3
View File
@@ -2,7 +2,7 @@ name: 'Release: Nightly'
on:
schedule:
- cron: '0 0 * * *'
- cron: '0 20 * * *'
workflow_dispatch:
inputs:
dry_run:
@@ -31,7 +31,6 @@ on:
jobs:
release:
if: "github.repository == 'google-gemini/gemini-cli'"
environment: "${{ github.event.inputs.environment || 'prod' }}"
runs-on: 'ubuntu-latest'
permissions:
@@ -158,4 +157,4 @@ jobs:
gh issue create \
--title "Nightly Release Failed for ${RELEASE_TAG} on $(date +'%Y-%m-%d')" \
--body "The nightly-release workflow failed. See the full run for details: ${DETAILS_URL}" \
--label 'release-failure,priority/p0'
--label 'kind/bug,release-failure,priority/p0'
@@ -1,8 +1,5 @@
name: 'Release: Patch (1) Create PR'
run-name: >-
Release Patch (1) Create PR | S:${{ inputs.channel }} | C:${{ inputs.commit }} ${{ inputs.original_pr && format('| PR:#{0}', inputs.original_pr) || '' }}
on:
workflow_dispatch:
inputs:
@@ -99,12 +96,12 @@ jobs:
--channel="${PATCH_CHANNEL}" \
--pullRequestNumber="${ORIGINAL_PR}" \
--dry-run="${DRY_RUN}"
echo "EXIT_CODE=$?" >> "$GITHUB_OUTPUT"
} 2>&1 | tee >(
echo "LOG_CONTENT<<EOF" >> "$GITHUB_ENV"
cat >> "$GITHUB_ENV"
echo "EOF" >> "$GITHUB_ENV"
)
echo "EXIT_CODE=${PIPESTATUS[0]}" >> "$GITHUB_OUTPUT"
- name: 'Comment on Original PR'
if: 'always() && inputs.original_pr'
@@ -118,7 +115,6 @@ jobs:
GITHUB_RUN_ID: '${{ github.run_id }}'
LOG_CONTENT: '${{ env.LOG_CONTENT }}'
TARGET_REF: '${{ github.event.inputs.ref }}'
ENVIRONMENT: '${{ github.event.inputs.environment }}'
continue-on-error: true
run: |
git checkout "${TARGET_REF}"
@@ -1,10 +1,5 @@
name: 'Release: Patch (2) Trigger'
run-name: >-
Release Patch (2) Trigger |
${{ github.event.pull_request.number && format('PR #{0}', github.event.pull_request.number) || 'Manual' }} |
${{ github.event.pull_request.head.ref || github.event.inputs.ref }}
on:
pull_request:
types:
@@ -1,8 +1,5 @@
name: 'Release: Patch (3) Release'
run-name: >-
Release Patch (3) Release | T:${{ inputs.type }} | R:${{ inputs.release_ref }} ${{ inputs.original_pr && format('| PR:#{0}', inputs.original_pr) || '' }}
on:
workflow_dispatch:
inputs:
@@ -205,7 +202,7 @@ jobs:
gh issue create \
--title 'Patch Release Failed for ${RELEASE_TAG} on $(date +'%Y-%m-%d')' \
--body 'The patch-release workflow failed. See the full run for details: ${DETAILS_URL}' \
--label 'release-failure,priority/p0'
--label 'kind/bug,release-failure,priority/p0'
- name: 'Comment Success on Original PR'
if: '${{ success() && github.event.inputs.original_pr }}'
+5 -8
View File
@@ -92,9 +92,6 @@ jobs:
fi
NIGHTLY_COMMAND="node scripts/get-release-version.js --type=promote-nightly"
STABLE_JSON=$(${STABLE_COMMAND})
STABLE_VERSION=$(echo "${STABLE_JSON}" | jq -r .releaseVersion)
PREVIEW_COMMAND+=" --stable-base-version=${STABLE_VERSION}"
NIGHTLY_COMMAND+=" --stable-base-version=${STABLE_VERSION}"
PREVIEW_JSON=$(${PREVIEW_COMMAND})
NIGHTLY_JSON=$(${NIGHTLY_COMMAND})
echo "STABLE_JSON_COMMAND=${STABLE_COMMAND}"
@@ -103,14 +100,14 @@ jobs:
echo "STABLE_JSON: ${STABLE_JSON}"
echo "PREVIEW_JSON: ${PREVIEW_JSON}"
echo "NIGHTLY_JSON: ${NIGHTLY_JSON}"
echo "STABLE_VERSION=${STABLE_VERSION}" >> "${GITHUB_OUTPUT}"
echo "STABLE_VERSION=$(echo "${STABLE_JSON}" | jq -r .releaseVersion)" >> "${GITHUB_OUTPUT}"
# shellcheck disable=SC1083
echo "STABLE_SHA=$(git rev-parse "$(echo "${PREVIEW_JSON}" | jq -r .previousReleaseTag)"^{commit})" >> "${GITHUB_OUTPUT}"
echo "PREVIOUS_STABLE_TAG=$(echo "${STABLE_JSON}" | jq -r .previousReleaseTag)" >> "${GITHUB_OUTPUT}"
echo "PREVIEW_VERSION=$(echo "${PREVIEW_JSON}" | jq -r .releaseVersion)" >> "${GITHUB_OUTPUT}"
# shellcheck disable=SC1083
REF="${REF_INPUT}"
SHA=$(git ls-remote origin "$REF" | awk -v ref="$REF" '$2 == "refs/heads/"ref || $2 == "refs/tags/"ref || $2 == ref {print $1}' | head -n 1)
SHA=$(git ls-remote origin "$REF" | awk '{print $1}')
if [ -z "$SHA" ]; then
if [[ "$REF" =~ ^[0-9a-f]{7,40}$ ]]; then
SHA="$REF"
@@ -261,7 +258,7 @@ jobs:
gh issue create \
--title 'Promote Release Failed for ${RELEASE_TAG} on $(date +'%Y-%m-%d')' \
--body 'The promote-release workflow failed during preview publish. See the full run for details: ${DETAILS_URL}' \
--label 'release-failure,priority/p0'
--label 'kind/bug,release-failure,priority/p0'
publish-stable:
name: 'Publish stable'
@@ -327,7 +324,7 @@ jobs:
gh issue create \
--title 'Promote Release Failed for ${RELEASE_TAG} on $(date +'%Y-%m-%d')' \
--body 'The promote-release workflow failed during stable publish. See the full run for details: ${DETAILS_URL}' \
--label 'release-failure,priority/p0'
--label 'kind/bug,release-failure,priority/p0'
nightly-pr:
name: 'Create Nightly PR'
@@ -403,4 +400,4 @@ jobs:
gh issue create \
--title 'Promote Release Failed for ${RELEASE_TAG} on $(date +'%Y-%m-%d')' \
--body 'The promote-release workflow failed during nightly PR creation. See the full run for details: ${DETAILS_URL}' \
--label 'release-failure,priority/p0'
--label 'kind/bug,release-failure,priority/p0'
+1 -1
View File
@@ -46,4 +46,4 @@ jobs:
gh issue create \
--title 'Sandbox Release Failed on $(date +'%Y-%m-%d')' \
--body 'The sandbox-release workflow failed. See the full run for details: ${DETAILS_URL}' \
--label 'release-failure,priority/p0'
--label 'kind/bug,release-failure,priority/p0'
+1 -1
View File
@@ -47,4 +47,4 @@ jobs:
gh issue create \
--title 'Smoke test failed on ${REF} @ $(date +'%Y-%m-%d')' \
--body 'Smoke test build failed. See the full run for details: ${DETAILS_URL}' \
--label 'priority/p0'
--label 'kind/bug,priority/p0'
@@ -1,10 +1,6 @@
name: 'Testing: E2E (Chained)'
name: 'Test Chained E2E'
on:
push:
branches:
- 'main'
merge_group:
workflow_run:
workflows: ['Trigger E2E']
types: ['completed']
@@ -18,18 +14,13 @@ on:
required: true
concurrency:
group: '${{ github.workflow }}-${{ github.head_ref || github.event.workflow_run.head_branch || github.ref }}'
group: '${{ github.workflow }}-${{ github.head_ref || github.ref }}'
cancel-in-progress: |-
${{ github.event_name != 'push' && github.event_name != 'merge_group' }}
permissions:
contents: 'read'
statuses: 'write'
${{ github.ref != 'refs/heads/main' && !startsWith(github.ref, 'refs/heads/release/') }}
jobs:
merge_queue_skipper:
name: 'Merge Queue Skipper'
permissions: 'read-all'
runs-on: 'gemini-cli-ubuntu-16-core'
outputs:
skip: '${{ steps.merge-queue-e2e-skipper.outputs.skip-check }}'
@@ -37,18 +28,15 @@ jobs:
- id: 'merge-queue-e2e-skipper'
uses: 'cariad-tech/merge-queue-ci-skipper@1032489e59437862c90a08a2c92809c903883772' # ratchet:cariad-tech/merge-queue-ci-skipper@main
with:
secret: '${{ secrets.GEMINI_CLI_ROBOT_GITHUB_PAT }}'
continue-on-error: true
secret: '${{ secrets.GITHUB_TOKEN }}'
download_repo_name:
runs-on: 'gemini-cli-ubuntu-16-core'
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 }}'
steps:
- name: 'Mock Repo Artifact'
if: "${{ github.event_name == 'workflow_dispatch' }}"
if: "${{ github.event_name != 'workflow_run' }}"
env:
REPO_NAME: '${{ github.event.inputs.repo_name }}'
run: |
@@ -67,7 +55,7 @@ jobs:
name: 'repo_name'
run-id: '${{ env.RUN_ID }}'
path: '${{ runner.temp }}/artifacts'
- name: 'Output Repo Name and SHA'
- name: 'Output Repo Name'
id: 'output-repo-name'
uses: 'actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd' # ratchet:actions/github-script@v8
with:
@@ -76,62 +64,13 @@ jobs:
const fs = require('fs');
const path = require('path');
const temp = '${{ runner.temp }}/artifacts';
const repoPath = path.join(temp, 'repo_name');
if (fs.existsSync(repoPath)) {
const repo_name = String(fs.readFileSync(repoPath)).trim();
core.setOutput('repo_name', repo_name);
}
const shaPath = path.join(temp, 'head_sha');
if (fs.existsSync(shaPath)) {
const head_sha = String(fs.readFileSync(shaPath)).trim();
core.setOutput('head_sha', head_sha);
}
parse_run_context:
name: 'Parse run context'
runs-on: 'gemini-cli-ubuntu-16-core'
needs: 'download_repo_name'
if: 'always()'
outputs:
repository: '${{ steps.set_context.outputs.REPO }}'
sha: '${{ steps.set_context.outputs.SHA }}'
steps:
- id: 'set_context'
name: 'Set dynamic repository and SHA'
env:
REPO: '${{ needs.download_repo_name.outputs.repo_name || github.repository }}'
SHA: '${{ needs.download_repo_name.outputs.head_sha || github.event.inputs.head_sha || github.event.workflow_run.head_sha || github.sha }}'
shell: 'bash'
run: |
echo "REPO=$REPO" >> "$GITHUB_OUTPUT"
echo "SHA=$SHA" >> "$GITHUB_OUTPUT"
set_pending_status:
runs-on: 'gemini-cli-ubuntu-16-core'
permissions: 'write-all'
needs:
- 'parse_run_context'
if: 'always()'
steps:
- name: 'Set pending status'
uses: 'myrotvorets/set-commit-status-action@16037e056d73b2d3c88e37e393ff369047f70886' # ratchet:myrotvorets/set-commit-status-action@master
if: 'always()'
with:
allowForks: 'true'
repo: '${{ github.repository }}'
sha: '${{ needs.parse_run_context.outputs.sha }}'
token: '${{ secrets.GEMINI_CLI_ROBOT_GITHUB_PAT }}'
status: 'pending'
context: 'E2E (Chained)'
const repo_name = String(fs.readFileSync(path.join(temp, 'repo_name')));
core.setOutput('repo_name', repo_name);
e2e_linux:
name: 'E2E Test (Linux) - ${{ matrix.sandbox }}'
needs:
- 'merge_queue_skipper'
- 'parse_run_context'
needs: 'download_repo_name'
runs-on: 'gemini-cli-ubuntu-16-core'
if: |
always() && (needs.merge_queue_skipper.result !='success' || needs.merge_queue_skipper.outputs.skip != 'true')
strategy:
fail-fast: false
matrix:
@@ -145,8 +84,8 @@ jobs:
- 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 }}'
ref: '${{ github.event.inputs.head_sha || github.event.workflow_run.head_sha }}'
repository: '${{ needs.download_repo_name.outputs.repo_name }}'
- name: 'Set up Node.js ${{ matrix.node-version }}'
uses: 'actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020' # ratchet:actions-node@v4
@@ -160,7 +99,7 @@ jobs:
run: 'npm run build'
- name: 'Set up Docker'
if: "${{matrix.sandbox == 'sandbox:docker'}}"
if: "matrix.sandbox == 'sandbox:docker'"
uses: 'docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435' # ratchet:docker/setup-buildx-action@v3
- name: 'Run E2E tests'
@@ -168,7 +107,6 @@ jobs:
GEMINI_API_KEY: '${{ secrets.GEMINI_API_KEY }}'
KEEP_OUTPUT: 'true'
VERBOSE: 'true'
BUILD_SANDBOX_FLAGS: '--cache-from type=gha --cache-to type=gha,mode=max'
shell: 'bash'
run: |
if [[ "${{ matrix.sandbox }}" == "sandbox:docker" ]]; then
@@ -179,18 +117,14 @@ jobs:
e2e_mac:
name: 'E2E Test (macOS)'
needs:
- 'merge_queue_skipper'
- 'parse_run_context'
needs: 'download_repo_name'
runs-on: 'macos-latest'
if: |
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 }}'
ref: '${{ github.event.inputs.head_sha || github.event.workflow_run.head_sha }}'
repository: '${{ needs.download_repo_name.outputs.repo_name }}'
- name: 'Set up Node.js 20.x'
uses: 'actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020' # ratchet:actions-node@v4
@@ -204,11 +138,11 @@ jobs:
run: 'npm run build'
- name: 'Fix rollup optional dependencies on macOS'
if: "${{runner.os == 'macOS'}}"
if: "runner.os == 'macOS'"
run: |
npm cache clean --force
- name: 'Run E2E tests (non-Windows)'
if: "${{runner.os != 'Windows'}}"
if: "runner.os != 'Windows'"
env:
GEMINI_API_KEY: '${{ secrets.GEMINI_API_KEY }}'
KEEP_OUTPUT: 'true'
@@ -220,9 +154,9 @@ jobs:
name: 'Slow E2E - Win'
needs:
- 'merge_queue_skipper'
- 'parse_run_context'
- 'download_repo_name'
if: |
always() && (needs.merge_queue_skipper.result !='success' || needs.merge_queue_skipper.outputs.skip != 'true')
needs.merge_queue_skipper.outputs.skip == 'false'
runs-on: 'gemini-cli-windows-16-core'
continue-on-error: true
@@ -230,8 +164,8 @@ jobs:
- 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 }}'
ref: '${{ github.event.inputs.head_sha || github.event.workflow_run.head_sha }}'
repository: '${{ needs.download_repo_name.outputs.repo_name }}'
- name: 'Set up Node.js 20.x'
uses: 'actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020' # ratchet:actions-node@v4
@@ -277,73 +211,21 @@ jobs:
shell: 'pwsh'
run: 'npm run test:integration:sandbox:none'
evals:
name: 'Evals (ALWAYS_PASSING)'
needs:
- 'merge_queue_skipper'
- 'parse_run_context'
runs-on: 'gemini-cli-ubuntu-16-core'
if: |
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 }}'
- name: 'Set up Node.js 20.x'
uses: 'actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020' # ratchet:actions-node@v4
with:
node-version: '20.x'
- name: 'Install dependencies'
run: 'npm ci'
- name: 'Build project'
run: 'npm run build'
- name: 'Run Evals (Required to pass)'
env:
GEMINI_API_KEY: '${{ secrets.GEMINI_API_KEY }}'
run: 'npm run test:always_passing_evals'
e2e:
name: 'E2E'
if: |
always() && (needs.merge_queue_skipper.result !='success' || needs.merge_queue_skipper.outputs.skip != 'true')
always() && needs.merge_queue_skipper.outputs.skip == 'false'
needs:
- 'e2e_linux'
- 'e2e_mac'
- '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.evals.result }} != 'success' ]]; then
${{ needs.e2e_mac.result }} != 'success' ]]; then
echo "One or more E2E jobs failed."
exit 1
fi
echo "All required E2E jobs passed!"
set_workflow_status:
runs-on: 'gemini-cli-ubuntu-16-core'
permissions: 'write-all'
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: 'always()'
with:
allowForks: 'true'
repo: '${{ github.repository }}'
sha: '${{ needs.parse_run_context.outputs.sha }}'
token: '${{ secrets.GITHUB_TOKEN }}'
status: '${{ needs.e2e.result }}'
context: 'E2E (Chained)'
+6 -11
View File
@@ -3,15 +3,11 @@ name: 'Trigger E2E'
on:
workflow_dispatch:
inputs:
repo_name:
description: 'Repository name (e.g., owner/repo)'
required: false
branch_ref:
description: 'Branch to run on'
required: true
default: 'main'
type: 'string'
head_sha:
description: 'SHA of the commit to test'
required: false
type: 'string'
pull_request:
jobs:
save_repo_name:
@@ -19,12 +15,11 @@ jobs:
steps:
- name: 'Save Repo name'
env:
REPO_NAME: '${{ github.event.inputs.repo_name || github.event.pull_request.head.repo.full_name }}'
HEAD_SHA: '${{ github.event.inputs.head_sha || github.event.pull_request.head.sha }}'
# Replace with github.event.pull_request.base.repo.full_name when switched to listen on pull request events. This repo name does not contain the org which is needed for checkout.
REPO_NAME: '${{ github.event.repository.name }}'
run: |
mkdir -p ./pr
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'
+1 -7
View File
@@ -11,14 +11,13 @@
.gemini/*
!.gemini/config.yaml
!.gemini/commands/
!.gemini/skills/
!.gemini/settings.json
# Note: .gemini-clipboard/ is NOT in gitignore so Gemini can access pasted images
# Dependency directory
node_modules
bower_components
package-lock.json
# Editors
.idea
@@ -55,8 +54,3 @@ gha-creds-*.json
# Log files
patch_output.log
.genkit
.gemini-clipboard/
.eslintcache
evals/logs/
-6
View File
@@ -1,6 +0,0 @@
http://localhost:16686/
https://github.com/google-gemini/gemini-cli/issues/new/choose
https://github.com/google-gemini/maintainers-gemini-cli/blob/main/npm.md
https://github.com/settings/personal-access-tokens/new
https://github.com/settings/tokens/new
https://www.npmjs.com/package/@google/gemini-cli
-3
View File
@@ -17,7 +17,4 @@ eslint.config.js
**/generated
gha-creds-*.json
junit.xml
.gemini-linters/
Thumbs.db
.pytest_cache
**/SKILL.md
+39 -178
View File
@@ -1,18 +1,6 @@
# How to contribute
# How to Contribute
We would love to accept your patches and contributions to this project. This
document includes:
- **[Before you begin](#before-you-begin):** Essential steps to take before
becoming a Gemini CLI contributor.
- **[Code contribution process](#code-contribution-process):** How to contribute
code to Gemini CLI.
- **[Development setup and workflow](#development-setup-and-workflow):** How to
set up your development environment and workflow.
- **[Documentation contribution process](#documentation-contribution-process):**
How to contribute documentation to Gemini CLI.
We're looking forward to seeing your contributions!
We would love to accept your patches and contributions to this project.
## Before you begin
@@ -35,47 +23,19 @@ sign a new one.
This project follows
[Google's Open Source Community Guidelines](https://opensource.google/conduct/).
## Code contribution process
## Contribution Process
### Get started
The process for contributing code is as follows:
1. **Find an issue** that you want to work on. If an issue is tagged as
`🔒Maintainers only`, this means it is reserved for project maintainers. We
will not accept pull requests related to these issues. In the near future,
we will explicitly mark issues looking for contributions using the
`help wanted` label. If you believe an issue is a good candidate for
community contribution, please leave a comment on the issue. A maintainer
will review it and apply the `help-wanted` label if appropriate. Only
maintainers should attempt to add the `help-wanted` label to an issue.
2. **Fork the repository** and create a new branch.
3. **Make your changes** in the `packages/` directory.
4. **Ensure all checks pass** by running `npm run preflight`.
5. **Open a pull request** with your changes.
### Code reviews
### Code Reviews
All submissions, including submissions by project members, require review. We
use [GitHub pull requests](https://docs.github.com/articles/about-pull-requests)
for this purpose.
If your pull request involves changes to `packages/cli` (the frontend), we
recommend running our automated frontend review tool. **Note: This tool is
currently experimental.** It helps detect common React anti-patterns, testing
issues, and other frontend-specific best practices that are easy to miss.
### Self Assigning Issues
To run the review tool, enter the following command from within Gemini CLI:
```text
/review-frontend <PR_NUMBER>
```
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 issues
If you're looking for an issue to work on, check out our list of issues that are
labeled
["help wanted"](https://github.com/google-gemini/gemini-cli/issues?q=is%3Aissue+state%3Aopen+label%3A%22help+wanted%22).
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
@@ -84,12 +44,12 @@ 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.
### Pull request guidelines
### Pull Request Guidelines
To help us review and merge your PRs quickly, please follow these guidelines.
PRs that do not meet these standards may be closed.
#### 1. Link to an existing issue
#### 1. Link to an Existing Issue
All PRs should be linked to an existing issue in our tracker. This ensures that
every change has been discussed and is aligned with the project's goals before
@@ -99,13 +59,10 @@ any code is written.
- **For features:** The PR should be linked to the feature request or proposal
issue that has been approved by a maintainer.
If an issue for your change doesn't exist, we will automatically close your PR
along with a comment reminding you to associate the PR with an issue. The ideal
workflow starts with an issue that has been reviewed and approved by a
maintainer. Please **open the issue first** and wait for feedback before you
start coding.
If an issue for your change doesn't exist, please **open one first** and wait
for feedback before you start coding.
#### 2. Keep it small and focused
#### 2. Keep It Small and Focused
We favor small, atomic PRs that address a single issue or add a single,
self-contained feature.
@@ -117,40 +74,37 @@ self-contained feature.
Large changes should be broken down into a series of smaller, logical PRs that
can be reviewed and merged independently.
#### 3. Use draft PRs for work in progress
#### 3. Use Draft PRs for Work in Progress
If you'd like to get early feedback on your work, please use GitHub's **Draft
Pull Request** feature. This signals to the maintainers that the PR is not yet
ready for a formal review but is open for discussion and initial feedback.
#### 4. Ensure all checks pass
#### 4. Ensure All Checks Pass
Before submitting your PR, ensure that all automated checks are passing by
running `npm run preflight`. This command runs all tests, linting, and other
style checks.
#### 5. Update documentation
#### 5. Update Documentation
If your PR introduces a user-facing change (e.g., a new command, a modified
flag, or a change in behavior), you must also update the relevant documentation
in the `/docs` directory.
See more about writing documentation:
[Documentation contribution process](#documentation-contribution-process).
#### 6. Write clear commit messages and a good PR description
#### 6. Write Clear Commit Messages and a Good PR Description
Your PR should have a clear, descriptive title and a detailed description of the
changes. Follow the [Conventional Commits](https://www.conventionalcommits.org/)
standard for your commit messages.
- **Good PR title:** `feat(cli): Add --json flag to 'config get' command`
- **Bad PR title:** `Made some changes`
- **Good PR Title:** `feat(cli): Add --json flag to 'config get' command`
- **Bad PR Title:** `Made some changes`
In the PR description, explain the "why" behind your changes and link to the
relevant issue (e.g., `Fixes #123`).
### Forking
## Forking
If you are forking the repository you will be able to run the Build, Test and
Integration test workflows. However in order to make the integration tests run
@@ -164,12 +118,12 @@ Additionally you will need to click on the `Actions` tab and enable workflows
for your repository, you'll find it's the large blue button in the center of the
screen.
### Development setup and workflow
## Development Setup and Workflow
This section guides contributors on how to build, modify, and understand the
development setup of this project.
### Setting up the development environment
### Setting Up the Development Environment
**Prerequisites:**
@@ -181,7 +135,7 @@ development setup of this project.
version of Node.js `>=20` is acceptable.
2. **Git**
### Build process
### Build Process
To clone the repository:
@@ -206,7 +160,7 @@ This command typically compiles TypeScript to JavaScript, bundles assets, and
prepares the packages for execution. Refer to `scripts/build.js` and
`package.json` scripts for more details on what happens during the build.
### Enabling sandboxing
### Enabling Sandboxing
[Sandboxing](#sandboxing) is highly recommended and requires, at a minimum,
setting `GEMINI_SANDBOX=true` in your `~/.env` and ensuring a sandboxing
@@ -222,7 +176,7 @@ npm run build:all
To skip building the sandbox container, you can use `npm run build` instead.
### Running the CLI
### Running
To start the Gemini CLI from the source code (after building), run the following
command from the root directory:
@@ -236,11 +190,11 @@ utilize `npm link path/to/gemini-cli/packages/cli` (see:
[docs](https://docs.npmjs.com/cli/v9/commands/npm-link)) or
`alias gemini="node path/to/gemini-cli/packages/cli"` to run with `gemini`
### Running tests
### Running Tests
This project contains two types of tests: unit tests and integration tests.
#### Unit tests
#### Unit Tests
To execute the unit test suite for the project:
@@ -252,7 +206,7 @@ This will run tests located in the `packages/core` and `packages/cli`
directories. Ensure tests pass before submitting any changes. For a more
comprehensive check, it is recommended to run `npm run preflight`.
#### Integration tests
#### Integration Tests
The integration tests are designed to validate the end-to-end functionality of
the Gemini CLI. They are not run as part of the default `npm run test` command.
@@ -264,9 +218,9 @@ npm run test:e2e
```
For more detailed information on the integration testing framework, please see
the [Integration Tests documentation](/docs/integration-tests.md).
the [Integration Tests documentation](./docs/integration-tests.md).
### Linting and preflight checks
### Linting and Preflight Checks
To ensure code quality and formatting consistency, run the preflight check:
@@ -313,7 +267,7 @@ root directory:
npm run lint
```
### Coding conventions
### Coding Conventions
- Please adhere to the coding style, patterns, and conventions used throughout
the existing codebase.
@@ -325,24 +279,19 @@ npm run lint
- **Imports:** Pay special attention to import paths. The project uses ESLint to
enforce restrictions on relative imports between packages.
### Project structure
### Project Structure
- `packages/`: Contains the individual sub-packages of the project.
- `a2a-server`: A2A server implementation for the Gemini CLI. (Experimental)
- `cli/`: The command-line interface.
- `core/`: The core backend logic for the Gemini CLI.
- `test-utils` Utilities for creating and cleaning temporary file systems for
testing.
- `vscode-ide-companion/`: The Gemini CLI Companion extension pairs with
Gemini CLI.
- `docs/`: Contains all project documentation.
- `scripts/`: Utility scripts for building, testing, and development tasks.
For more detailed architecture, see `docs/architecture.md`.
### Debugging
## Debugging
#### VS Code
### VS Code:
0. Run the CLI to interactively debug in VS Code with `F5`
1. Start the CLI in debug mode from the root directory:
@@ -400,9 +349,9 @@ used for the CLI's interface, is compatible with React DevTools version 4.x.
Your running CLI application should then connect to React DevTools.
![](/docs/assets/connected_devtools.png)
### Sandboxing
## Sandboxing
#### macOS Seatbelt
### macOS Seatbelt
On macOS, `gemini` uses Seatbelt (`sandbox-exec`) under a `permissive-open`
profile (see `packages/cli/src/utils/sandbox-macos-permissive-open.sb`) that
@@ -418,7 +367,7 @@ Available built-in profiles are `{permissive,restrictive}-{open,closed,proxied}`
`.gemini/sandbox-macos-<profile>.sb` under your project settings directory
`.gemini`.
#### Container-based sandboxing (all platforms)
### Container-based Sandboxing (All Platforms)
For stronger container-based sandboxing on macOS or other platforms, you can set
`GEMINI_SANDBOX=true|docker|podman|<command>` in your environment or `.env`
@@ -441,7 +390,7 @@ for your projects by creating the files `.gemini/sandbox.Dockerfile` and/or
running `gemini` with `BUILD_SANDBOX=1` to trigger building of your custom
sandbox.
#### Proxied networking
#### Proxied Networking
All sandboxing methods, including macOS Seatbelt using `*-proxied` profiles,
support restricting outbound network traffic through a custom proxy server that
@@ -452,7 +401,7 @@ connections to `example.com:443` (e.g. `curl https://example.com`) and declines
all other requests. The proxy is started and stopped automatically alongside the
sandbox.
### Manual publish
## Manual Publish
We publish an artifact for each commit to our internal registry. But if you need
to manually cut a local build, then run the following commands:
@@ -464,91 +413,3 @@ npm run auth
npm run prerelease:dev
npm publish --workspaces
```
## Documentation contribution process
Our documentation must be kept up-to-date with our code contributions. We want
our documentation to be clear, concise, and helpful to our users. We value:
- **Clarity:** Use simple and direct language. Avoid jargon where possible.
- **Accuracy:** Ensure all information is correct and up-to-date.
- **Completeness:** Cover all aspects of a feature or topic.
- **Examples:** Provide practical examples to help users understand how to use
Gemini CLI.
### Getting started
The process for contributing to the documentation is similar to contributing
code.
1. **Fork the repository** and create a new branch.
2. **Make your changes** in the `/docs` directory.
3. **Preview your changes locally** in Markdown rendering.
4. **Lint and format your changes.** Our preflight check includes linting and
formatting for documentation files.
```bash
npm run preflight
```
5. **Open a pull request** with your changes.
### Documentation structure
Our documentation is organized using [sidebar.json](/docs/sidebar.json) as the
table of contents. When adding new documentation:
1. Create your markdown file **in the appropriate directory** under `/docs`.
2. Add an entry to `sidebar.json` in the relevant section.
3. Ensure all internal links use relative paths and point to existing files.
### Style guide
We follow the
[Google Developer Documentation Style Guide](https://developers.google.com/style).
Please refer to it for guidance on writing style, tone, and formatting.
#### Key style points
- Use sentence case for headings.
- Write in second person ("you") when addressing the reader.
- Use present tense.
- Keep paragraphs short and focused.
- Use code blocks with appropriate language tags for syntax highlighting.
- Include practical examples whenever possible.
### Linting and formatting
We use `prettier` to enforce a consistent style across our documentation. The
`npm run preflight` command will check for any linting issues.
You can also run the linter and formatter separately:
- `npm run lint` - Check for linting issues
- `npm run format` - Auto-format markdown files
- `npm run lint:fix` - Auto-fix linting issues where possible
Please make sure your contributions are free of linting errors before submitting
a pull request.
### Before you submit
Before submitting your documentation pull request, please:
1. Run `npm run preflight` to ensure all checks pass.
2. Review your changes for clarity and accuracy.
3. Check that all links work correctly.
4. Ensure any code examples are tested and functional.
5. Sign the
[Contributor License Agreement (CLA)](https://cla.developers.google.com/) if
you haven't already.
### Need help?
If you have questions about contributing documentation:
- Check our [FAQ](/docs/faq.md).
- Review existing documentation for examples.
- Open [an issue](https://github.com/google-gemini/gemini-cli/issues) to discuss
your proposed changes.
- Reach out to the maintainers.
We appreciate your contributions to making Gemini CLI documentation better!
+3 -49
View File
@@ -15,17 +15,6 @@ 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.
## Running Tests in Workspaces\*\*: To run a specific test file within a
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.
- _Example (Core package)_:
`npm test -w @google/gemini-cli-core -- src/routing/modelRouterService.test.ts`
- _Common workspaces_: `@google/gemini-cli`, `@google/gemini-cli-core`.
## Writing Tests
This project uses **Vitest** as its primary testing framework. When writing
@@ -374,47 +363,12 @@ performance.
- 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
## General style requirements
- **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`.
Use hyphens instead of underscores in flag names (e.g. `my-flag` instead of
`my_flag`).
+13 -17
View File
@@ -1,10 +1,9 @@
# Gemini CLI
[![Gemini CLI CI](https://github.com/google-gemini/gemini-cli/actions/workflows/ci.yml/badge.svg)](https://github.com/google-gemini/gemini-cli/actions/workflows/ci.yml)
[![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)
[![Gemini CLI E2E](https://github.com/google-gemini/gemini-cli/actions/workflows/e2e.yml/badge.svg)](https://github.com/google-gemini/gemini-cli/actions/workflows/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://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)
@@ -18,8 +17,7 @@ Learn all about Gemini CLI in our [documentation](https://geminicli.com/docs/).
- **🎯 Free tier**: 60 requests/min and 1,000 requests/day with personal Google
account.
- **🧠 Powerful Gemini 3 models**: Access to improved reasoning and 1M token
context window.
- **🧠 Powerful Gemini 2.5 Pro**: Access to 1M token context window.
- **🔧 Built-in tools**: Google Search grounding, file operations, shell
commands, web fetching.
- **🔌 Extensible**: MCP (Model Context Protocol) support for custom
@@ -29,18 +27,13 @@ Learn all about Gemini CLI in our [documentation](https://geminicli.com/docs/).
## 📦 Installation
### Pre-requisites before installation
- Node.js version 20 or higher
- macOS, Linux, or Windows
### Quick Install
#### Run instantly with npx
```bash
# Using npx (no installation required)
npx @google/gemini-cli
npx https://github.com/google-gemini/gemini-cli
```
#### Install globally with npm
@@ -55,6 +48,11 @@ npm install -g @google/gemini-cli
brew install gemini-cli
```
#### System Requirements
- Node.js version 20 or higher
- macOS, Linux, or Windows
## Release Cadence and Tags
See [Releases](./docs/releases.md) for more details.
@@ -81,9 +79,9 @@ npm install -g @google/gemini-cli@latest
### Nightly
- New releases will be published each day at UTC 0000. This will be all changes
from the main branch as represented at time of release. It should be assumed
there are pending validations and issues. Use `nightly` tag.
- New releases will be published each week at UTC 0000 each day, This will be
all changes from the main branch as represented at time of release. It should
be assumed there are pending validations and issues. Use `nightly` tag.
```bash
npm install -g @google/gemini-cli@nightly
@@ -141,7 +139,7 @@ for details)
**Benefits:**
- **Free tier**: 60 requests/min and 1,000 requests/day
- **Gemini 3 models** with 1M token context window
- **Gemini 2.5 Pro** with 1M token context window
- **No API key management** - just sign in with your Google account
- **Automatic updates** to latest models
@@ -165,7 +163,7 @@ gemini
**Benefits:**
- **Free tier**: 1000 requests/day with Gemini 3 (mix of flash and pro)
- **Free tier**: 100 requests/day with Gemini 2.5 Pro
- **Model selection**: Choose specific Gemini models
- **Usage-based billing**: Upgrade for higher limits when needed
@@ -308,8 +306,6 @@ gemini
corporate environment.
- [**Telemetry & Monitoring**](./docs/cli/telemetry.md) - Usage tracking.
- [**Tools API Development**](./docs/core/tools-api.md) - Create custom tools.
- [**Local development**](./docs/local-development.md) - Local development
tooling.
### Troubleshooting & Support
-1
View File
@@ -1 +0,0 @@
../CONTRIBUTING.md
+5 -5
View File
@@ -13,11 +13,11 @@ input:
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)
- [Input processing](/docs/cli/commands.md)
- History management
- Display rendering
- [Theme and UI customization](/docs/cli/themes)
- [CLI configuration settings](/docs/get-started/configuration)
- [Theme and UI customization](/docs/cli/themes.md)
- [CLI configuration settings](/docs/get-started/configuration.md)
2. **Core package (`packages/core`):**
- **Purpose:** This acts as the backend for the Gemini CLI. It receives
@@ -37,7 +37,7 @@ input:
- **Interaction:** `packages/core` invokes these tools based on requests
from the Gemini model.
## Interaction flow
## Interaction Flow
A typical interaction with the Gemini CLI follows this flow:
@@ -69,7 +69,7 @@ A typical interaction with the Gemini CLI follows this flow:
7. **Display to user:** The CLI package formats and displays the response to
the user in the terminal.
## Key design principles
## Key Design Principles
- **Modularity:** Separating the CLI (frontend) from the Core (backend) allows
for independent development and potential future extensions (e.g., different
Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 350 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

+9 -341
View File
@@ -1,341 +1,9 @@
# Gemini CLI release notes
# Gemini CLI Changelog
Gemini CLI has three major release channels: nightly, preview, and stable. For
most users, we recommend the stable release.
Wondering what's new in Gemini CLI? This document provides key highlights and
notable changes to Gemini CLI.
On this page, you can find information regarding the current releases and
announcements from each release.
For the full changelog, refer to
[Releases - google-gemini/gemini-cli](https://github.com/google-gemini/gemini-cli/releases)
on GitHub.
## Current releases
| Release channel | Notes |
| :-------------------- | :---------------------------------------------- |
| Nightly | Nightly release with the most recent changes. |
| [Preview](preview.md) | Experimental features ready for early feedback. |
| [Stable](latest.md) | Stable, recommended for general use. |
## Announcements: v0.23.0 - 2026-01-07
- 🎉 **Experimental Agent Skills Support in Preview:** Gemini CLI now supports
[Agent Skills](https://agentskills.io/home) in our preview builds. This is an
early preview where were looking for feedback!
- Install Preview: `npm install -g @google/gemini-cli@preview`
- Enable in `/settings`
- Docs:
[https://geminicli.com/docs/cli/skills/](https://geminicli.com/docs/cli/skills/)
- **Gemini CLI wrapped:** Run `npx gemini-wrapped` to visualize your usage
stats, top models, languages, and more!
- **Windows clipboard image support:** Windows users can now paste images
directly from their clipboard into the CLI using `Alt`+`V`.
([pr](https://github.com/google-gemini/gemini-cli/pull/13997) by
[@sgeraldes](https://github.com/sgeraldes))
- **Terminal background color detection:** Automatically optimizes your
terminal's background color to select compatible themes and provide
accessibility warnings.
([pr](https://github.com/google-gemini/gemini-cli/pull/15132) by
[@jacob314](https://github.com/jacob314))
- **Session logout:** Use the new `/logout` command to instantly clear
credentials and reset your authentication state for seamless account
switching. ([pr](https://github.com/google-gemini/gemini-cli/pull/13383) by
[@CN-Scars](https://github.com/CN-Scars))
## Announcements: v0.22.0 - 2025-12-22
- 🎉**Free Tier + Gemini 3:** Free tier users now all have access to Gemini 3
Pro & Flash. Enable in `/settings` by toggling "Preview Features" to `true`.
- 🎉**Gemini CLI + Colab:** Gemini CLI is now pre-installed. Can be used
headlessly in notebook cells or interactively in the built-in terminal
([pic](https://imgur.com/a/G0Tn7vi))
- 🎉**Gemini CLI Extensions:**
- **Conductor:** Planning++, Gemini works with you to build out a detailed
plan, pull in extra details as needed, ultimately to give the LLM guardrails
with artifacts. Measure twice, implement once!
`gemini extensions install https://github.com/gemini-cli-extensions/conductor`
Blog:
[https://developers.googleblog.com/conductor-introducing-context-driven-development-for-gemini-cli/](https://developers.googleblog.com/conductor-introducing-context-driven-development-for-gemini-cli/)
- **Endor Labs:** Perform code analysis, vulnerability scanning, and
dependency checks using natural language.
`gemini extensions install https://github.com/endorlabs/gemini-extension`
## Announcements: v0.21.0 - 2025-12-15
- **⚡️⚡️⚡️ Gemini 3 Flash + Gemini CLI:** Better, faster and cheaper than 2.5
Pro - and in some scenarios better than 3 Pro! For paid tiers + free tier
users who were on the wait list enable **Preview Features** in `/settings.`
- For more information:
[Gemini 3 Flash is now available in Gemini CLI](https://developers.googleblog.com/gemini-3-flash-is-now-available-in-gemini-cli/).
- 🎉 Gemini CLI Extensions:
- Rill: Utilize natural language to analyze Rill data, enabling the
exploration of metrics and trends without the need for manual queries.
`gemini extensions install https://github.com/rilldata/rill-gemini-extension`
- Browserbase: Interact with web pages, take screenshots, extract information,
and perform automated actions with atomic precision.
`gemini extensions install https://github.com/browserbase/mcp-server-browserbase`
- Quota Visibility: The `/stats` command now displays quota information for all
available models, including those not used in the current session. (@sehoon38)
- Fuzzy Setting Search: Users can now quickly find settings using fuzzy search
within the settings dialog. (@sehoon38)
- MCP Resource Support: Users can now discover, view, and search through
resources using the @ command. (@MrLesk)
- Auto-execute Simple Slash Commands: Simple slash commands are now executed
immediately on enter. (@jackwotherspoon)
## Announcements: v0.20.0 - 2025-12-01
- **Multi-file Drag & Drop:** Users can now drag and drop multiple files into
the terminal, and the CLI will automatically prefix each valid path with `@`.
([pr](https://github.com/google-gemini/gemini-cli/pull/14832) by
[@jackwotherspoon](https://github.com/jackwotherspoon))
- **Persistent "Always Allow" Policies:** Users can now save "Always Allow"
decisions for tool executions, with granular control over specific shell
commands and multi-cloud platform tools.
([pr](https://github.com/google-gemini/gemini-cli/pull/14737) by
[@allenhutchison](https://github.com/allenhutchison))
## Announcements: v0.19.0 - 2025-11-24
- 🎉 **New extensions:**
- **Eleven Labs:** Create, play, manage your audio play tracks with the Eleven
Labs Gemini CLI extension:
`gemini extensions install https://github.com/elevenlabs/elevenlabs-mcp`
- **Zed integration:** Users can now leverage Gemini 3 within the Zed
integration after enabling "Preview Features" in their CLIs `/settings`.
([pr](https://github.com/google-gemini/gemini-cli/pull/13398) by
[@benbrandt](https://github.com/benbrandt))
- **Interactive shell:**
- **Click-to-Focus:** When "Use Alternate Buffer" setting is enabled, users
can click within the embedded shell output to focus it for input.
([pr](https://github.com/google-gemini/gemini-cli/pull/13341) by
[@galz10](https://github.com/galz10))
- **Loading phrase:** Clearly indicates when the interactive shell is awaiting
user input. ([vid](https://imgur.com/a/kjK8bUK),
[pr](https://github.com/google-gemini/gemini-cli/pull/12535) by
[@jackwotherspoon](https://github.com/jackwotherspoon))
## Announcements: v0.18.0 - 2025-11-17
- 🎉 **New extensions:**
- **Google Workspace**: Integrate Gemini CLI with your Workspace data. Write
docs, build slides, chat with others or even get your calc on in sheets:
`gemini extensions install https://github.com/gemini-cli-extensions/workspace`
- Blog:
[https://allen.hutchison.org/2025/11/19/bringing-the-office-to-the-terminal/](https://allen.hutchison.org/2025/11/19/bringing-the-office-to-the-terminal/)
- **Redis:** Manage and search data in Redis with natural language:
`gemini extensions install https://github.com/redis/mcp-redis`
- **Anomalo:** Query your data warehouse table metadata and quality status
through commands and natural language:
`gemini extensions install https://github.com/datagravity-ai/anomalo-gemini-extension`
- **Experimental permission improvements:** We are now experimenting with a new
policy engine in Gemini CLI. This allows users and administrators to create
fine-grained policy for tool calls. Currently behind a flag. See
[policy engine documentation](../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
key, Google AI Pro or Google AI Ultra (for individuals, not businesses) and
Gemini Code Assist Enterprise users. Enable it via `/settings` and toggling on
**Preview Features**.
- **Updated UI rollback:** Weve temporarily rolled back our updated UI to give
it more time to bake. This means for a time you wont have embedded scrolling
or mouse support. You can re-enable with `/settings` -> **Use Alternate Screen
Buffer** -> `true`.
- **Model in history:** Users can now toggle in `/settings` to display model in
their chat history. ([gif](https://imgur.com/a/uEmNKnQ),
[pr](https://github.com/google-gemini/gemini-cli/pull/13034) by
[@scidomino](https://github.com/scidomino))
- **Multi-uninstall:** Users can now uninstall multiple extensions with a single
command. ([pic](https://imgur.com/a/9Dtq8u2),
[pr](https://github.com/google-gemini/gemini-cli/pull/13016) by
[@JayadityaGit](https://github.com/JayadityaGit))
## Announcements: v0.16.0 - 2025-11-10
- **Gemini 3 + Gemini CLI:** launch 🚀🚀🚀
- **Data Commons Gemini CLI Extension** - A new Data Commons Gemini CLI
extension that lets you query open-source statistical data from
datacommons.org. **To get started, you'll need a Data Commons API key and uv
installed**. These and other details to get you started with the extension can
be found at
[https://github.com/gemini-cli-extensions/datacommons](https://github.com/gemini-cli-extensions/datacommons).
## Announcements: v0.15.0 - 2025-11-03
- **🎉 Seamless scrollable UI and mouse support:** Weve given Gemini CLI a
major facelift to make your terminal experience smoother and much more
polished. You now get a flicker-free display with sticky headers that keep
important context visible and a stable input prompt that doesn't jump around.
We even added mouse support so you can click right where you need to type!
([gif](https://imgur.com/a/O6qc7bx),
[@jacob314](https://github.com/jacob314)).
- **Announcement:**
[https://developers.googleblog.com/en/making-the-terminal-beautiful-one-pixel-at-a-time/](https://developers.googleblog.com/en/making-the-terminal-beautiful-one-pixel-at-a-time/)
- **🎉 New partner extensions:**
- **Arize:** Seamlessly instrument AI applications with Arize AX and grant
direct access to Arize support:
`gemini extensions install https://github.com/Arize-ai/arize-tracing-assistant`
- **Chronosphere:** Retrieve logs, metrics, traces, events, and specific
entities:
`gemini extensions install https://github.com/chronosphereio/chronosphere-mcp`
- **Transmit:** Comprehensive context, validation, and automated fixes for
creating production-ready authentication and identity workflows:
`gemini extensions install https://github.com/TransmitSecurity/transmit-security-journey-builder`
- **Todo planning:** Complex questions now get broken down into todo lists that
the model can manage and check off. ([gif](https://imgur.com/a/EGDfNlZ),
[pr](https://github.com/google-gemini/gemini-cli/pull/12905) by
[@anj-s](https://github.com/anj-s))
- **Disable GitHub extensions:** Users can now prevent the installation and
loading of extensions from GitHub.
([pr](https://github.com/google-gemini/gemini-cli/pull/12838) by
[@kevinjwang1](https://github.com/kevinjwang1)).
- **Extensions restart:** Users can now explicitly restart extensions using the
`/extensions restart` command.
([pr](https://github.com/google-gemini/gemini-cli/pull/12739) by
[@jakemac53](https://github.com/jakemac53)).
- **Better Angular support:** Angular workflows should now be more seamless
([pr](https://github.com/google-gemini/gemini-cli/pull/10252) by
[@MarkTechson](https://github.com/MarkTechson)).
- **Validate command:** Users can now check that local extensions are formatted
correctly. ([pr](https://github.com/google-gemini/gemini-cli/pull/12186) by
[@kevinjwang1](https://github.com/kevinjwang1)).
## Announcements: v0.12.0 - 2025-10-27
![Codebase investigator subagent in Gemini CLI.](https://i.imgur.com/4J1njsx.png)
- **🎉 New partner extensions:**
- **🤗 Hugging Face extension:** Access the Hugging Face hub.
([gif](https://drive.google.com/file/d/1LEzIuSH6_igFXq96_tWev11svBNyPJEB/view?usp=sharing&resourcekey=0-LtPTzR1woh-rxGtfPzjjfg))
`gemini extensions install https://github.com/huggingface/hf-mcp-server`
- **Monday.com extension**: Analyze your sprints, update your task boards,
etc.
([gif](https://drive.google.com/file/d/1cO0g6kY1odiBIrZTaqu5ZakaGZaZgpQv/view?usp=sharing&resourcekey=0-xEr67SIjXmAXRe1PKy7Jlw))
`gemini extensions install https://github.com/mondaycom/mcp`
- **Data Commons extension:** Query public datasets or ground responses on
data from Data Commons
([gif](https://drive.google.com/file/d/1cuj-B-vmUkeJnoBXrO_Y1CuqphYc6p-O/view?usp=sharing&resourcekey=0-0adXCXDQEd91ZZW63HbW-Q)).
`gemini extensions install https://github.com/gemini-cli-extensions/datacommons`
- **Model selection:** Choose the Gemini model for your session with `/model`.
([pic](https://imgur.com/a/ABFcWWw),
[pr](https://github.com/google-gemini/gemini-cli/pull/8940) by
[@abhipatel12](https://github.com/abhipatel12)).
- **Model routing:** Gemini CLI will now intelligently pick the best model for
the task. Simple queries will be sent to Flash while complex analytical or
creative tasks will still use the power of Pro. This ensures your quota will
last for a longer period of time. You can always opt-out of this via `/model`.
([pr](https://github.com/google-gemini/gemini-cli/pull/9262) by
[@abhipatel12](https://github.com/abhipatel12)).
- Discussion:
[https://github.com/google-gemini/gemini-cli/discussions/12375](https://github.com/google-gemini/gemini-cli/discussions/12375)
- **Codebase investigator subagent:** We now have a new built-in subagent that
will explore your workspace and resolve relevant information to improve
overall performance.
([pr](https://github.com/google-gemini/gemini-cli/pull/9988) by
[@abhipatel12](https://github.com/abhipatel12),
[pr](https://github.com/google-gemini/gemini-cli/pull/10282) by
[@silviojr](https://github.com/silviojr)).
- Enable, disable, or limit turns in `/settings`, plus advanced configs in
`settings.json` ([pic](https://imgur.com/a/yJiggNO),
[pr](https://github.com/google-gemini/gemini-cli/pull/10844) by
[@silviojr](https://github.com/silviojr)).
- **Explore extensions with `/extension`:** Users can now open the extensions
page in their default browser directly from the CLI using the `/extension`
explore command. ([pr](https://github.com/google-gemini/gemini-cli/pull/11846)
by [@JayadityaGit](https://github.com/JayadityaGit)).
- **Configurable compression:** Users can modify the compression threshold in
`/settings`. The default has been made more proactive
([pr](https://github.com/google-gemini/gemini-cli/pull/12317) by
[@scidomino](https://github.com/scidomino)).
- **API key authentication:** Users can now securely enter and store their
Gemini API key via a new dialog, eliminating the need for environment
variables and repeated entry.
([pr](https://github.com/google-gemini/gemini-cli/pull/11760) by
[@galz10](https://github.com/galz10)).
- **Sequential approval:** Users can now approve multiple tool calls
sequentially during execution.
([pr](https://github.com/google-gemini/gemini-cli/pull/11593) by
[@joshualitt](https://github.com/joshualitt)).
## Announcements: v0.11.0 - 2025-10-20
![Gemini CLI and Jules](https://storage.googleapis.com/gweb-developer-goog-blog-assets/images/Jules_Extension_-_Blog_Header_O346JNt.original.png)
- 🎉 **Gemini CLI Jules Extension:** Use Gemini CLI to orchestrate Jules. Spawn
remote workers, delegate tedious tasks, or check in on running jobs!
- Install:
`gemini extensions install https://github.com/gemini-cli-extensions/jules`
- Announcement:
[https://developers.googleblog.com/en/introducing-the-jules-extension-for-gemini-cli/](https://developers.googleblog.com/en/introducing-the-jules-extension-for-gemini-cli/)
- **Stream JSON output:** Stream real-time JSONL events with
`--output-format stream-json` to monitor AI agent progress when run
headlessly. ([gif](https://imgur.com/a/0UCE81X),
[pr](https://github.com/google-gemini/gemini-cli/pull/10883) by
[@anj-s](https://github.com/anj-s))
- **Markdown toggle:** Users can now switch between rendered and raw markdown
display using `alt+m `or` ctrl+m`. ([gif](https://imgur.com/a/lDNdLqr),
[pr](https://github.com/google-gemini/gemini-cli/pull/10383) by
[@srivatsj](https://github.com/srivatsj))
- **Queued message editing:** Users can now quickly edit queued messages by
pressing the up arrow key when the input is empty.
([gif](https://imgur.com/a/ioRslLd),
[pr](https://github.com/google-gemini/gemini-cli/pull/10392) by
[@akhil29](https://github.com/akhil29))
- **JSON web fetch**: Non-HTML content like JSON APIs or raw source code are now
properly shown to the model (previously only supported HTML)
([gif](https://imgur.com/a/Q58U4qJ),
[pr](https://github.com/google-gemini/gemini-cli/pull/11284) by
[@abhipatel12](https://github.com/abhipatel12))
- **Non-interactive MCP commands:** Users can now run MCP slash commands in
non-interactive mode `gemini "/some-mcp-prompt"`.
([pr](https://github.com/google-gemini/gemini-cli/pull/10194) by
[@capachino](https://github.com/capachino))
- **Removal of deprecated flags:** Weve finally removed a number of deprecated
flags to cleanup Gemini CLIs invocation profile:
- `--all-files` / `-a` in favor of `@` from within Gemini CLI.
([pr](https://github.com/google-gemini/gemini-cli/pull/11228) by
[@allenhutchison](https://github.com/allenhutchison))
- `--telemetry-*` flags in favor of
[environment variables](https://github.com/google-gemini/gemini-cli/pull/11318)
([pr](https://github.com/google-gemini/gemini-cli/pull/11318) by
[@allenhutchison](https://github.com/allenhutchison))
## Announcements: v0.10.0 - 2025-10-13
- **Polish:** The team has been heads down bug fixing and investing heavily into
polishing existing flows, tools, and interactions.
- **Interactive Shell Tool calling:** Gemini CLI can now also execute
interactive tools if needed
([pr](https://github.com/google-gemini/gemini-cli/pull/11225) by
[@galz10](https://github.com/galz10)).
- **Alt+Key support:** Enables broader support for Alt+Key keyboard shortcuts
across different terminals.
([pr](https://github.com/google-gemini/gemini-cli/pull/10767) by
[@srivatsj](https://github.com/srivatsj)).
- **Telemetry Diff stats:** Track line changes made by the model and user during
file operations via OTEL.
([pr](https://github.com/google-gemini/gemini-cli/pull/10819) by
[@jerop](https://github.com/jerop)).
## Announcements: v0.9.0 - 2025-10-06
## v0.9.0 - Gemini CLI weekly update - 2025-10-06
- 🎉 **Interactive Shell:** Run interactive commands like `vim`, `rebase -i`, or
even `gemini` 😎 directly in Gemini CLI:
@@ -360,7 +28,7 @@ on GitHub.
([pr](https://github.com/google-gemini/gemini-cli/pull/10108) by
[@sgnagnarella](https://github.com/sgnagnarella))
## Announcements: v0.8.0 - 2025-09-29
## v0.8.0 - Gemini CLI weekly update - 2025-09-29
- 🎉 **Announcing Gemini CLI Extensions** 🎉
- Completely customize your Gemini CLI experience to fit your workflow.
@@ -399,7 +67,7 @@ on GitHub.
changes, smaller features, UI updates, reliability and bug fixes + general
polish made it in this week!
## Announcements: v0.7.0 - 2025-09-22
## v0.7.0 - Gemini CLI weekly update - 2025-09-22
- 🎉**Build your own Gemini CLI IDE plugin:** We've published a spec for
creating IDE plugins to enable rich context-aware experiences and native
@@ -437,7 +105,7 @@ on GitHub.
changes, smaller features, UI updates, reliability and bug fixes + general
polish made it in this week!
## Announcements: v0.6.0 - 2025-09-15
## v0.6.0 - Gemini CLI weekly update - 2025-09-15
- 🎉 **Higher limits for Google AI Pro and Ultra subscribers:** Were psyched to
finally announce that Google AI Pro and AI Ultra subscribers now get access to
@@ -518,7 +186,7 @@ on GitHub.
changes, smaller features, UI updates, reliability and bug fixes + general
polish made it in this week!
## Announcements: v0.5.0 - 2025-09-08
## v0.5.0 - Gemini CLI weekly update - 2025-09-08
- 🎉**FastMCP + Gemini CLI**🎉: Quickly install and manage your Gemini CLI MCP
servers with FastMCP ([video](https://imgur.com/a/m8QdCPh),
@@ -563,7 +231,7 @@ on GitHub.
changes, smaller features, UI updates, reliability and bug fixes + general
polish made it in this week!
## Announcements: v0.4.0 - 2025-09-01
## v0.4.0 - Gemini CLI weekly update - 2025-09-01
- 🎉**Gemini CLI CloudRun and Security Integrations**🎉: Automate app deployment
and security analysis with CloudRun and Security extension integrations. Once
-165
View File
@@ -1,165 +0,0 @@
# Latest stable release: v0.23.0
Released: January 6, 2026
For most users, our latest stable release is the recommended release. Install
the latest stable version with:
```
npm install -g @google/gemini-cli
```
## Highlights
- **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
- 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
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.22.5...v0.23.0
-224
View File
@@ -1,224 +0,0 @@
# Preview release: Release v0.24.0-preview.0
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).
To install the preview release:
```
npm install -g @google/gemini-cli@preview
```
## What's changed
- 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
**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
+1 -1
View File
@@ -1,3 +1,3 @@
# Authentication setup
# Authentication Setup
See: [Getting Started - Authentication Setup](../get-started/authentication.md).
+23 -13
View File
@@ -6,19 +6,19 @@ 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
## How It Works
When you approve a tool that modifies the file system (like `write_file` or
`replace`), the CLI automatically creates a "checkpoint." This checkpoint
includes:
1. **A Git snapshot:** A commit is made in a special, shadow Git repository
1. **A Git Snapshot:** A commit is made in a special, shadow Git repository
located in your home directory (`~/.gemini/history/<project_hash>`). This
snapshot captures the complete state of your project files at that moment.
It does **not** interfere with your own project's Git repository.
2. **Conversation history:** The entire conversation you've had with the agent
2. **Conversation History:** The entire conversation you've had with the agent
up to that point is saved.
3. **The tool call:** The specific tool call that was about to be executed is
3. **The Tool Call:** The specific tool call that was about to be executed is
also stored.
If you want to undo the change or simply go back, you can use the `/restore`
@@ -35,14 +35,24 @@ repository while the conversation history and tool calls are saved in a JSON
file in your project's temporary directory, typically located at
`~/.gemini/tmp/<project_hash>/checkpoints`.
## Enabling the feature
## Enabling the Feature
The Checkpointing feature is disabled by default. To enable it, you need to edit
your `settings.json` file.
The Checkpointing feature is disabled by default. To enable it, you can either
use a command-line flag or edit your `settings.json` file.
> **Note:** The `--checkpointing` command-line flag was removed in version
> 0.11.0. Checkpointing can now only be enabled through the `settings.json`
> configuration file.
### Using the Command-Line Flag
You can enable checkpointing for the current session by using the
`--checkpointing` flag when starting the Gemini CLI:
```bash
gemini --checkpointing
```
### Using the `settings.json` File
To enable checkpointing by default for all sessions, you need to edit your
`settings.json` file.
Add the following key to your `settings.json`:
@@ -56,12 +66,12 @@ Add the following key to your `settings.json`:
}
```
## Using the `/restore` command
## Using the `/restore` Command
Once enabled, checkpoints are created automatically. To manage them, you use the
`/restore` command.
### List available checkpoints
### List Available Checkpoints
To see a list of all saved checkpoints for the current project, simply run:
@@ -74,7 +84,7 @@ typically composed of a timestamp, the name of the file being modified, and the
name of the tool that was about to be run (e.g.,
`2025-06-22T10-00-00_000Z-my-file.txt-write_file`).
### Restore a specific checkpoint
### Restore a Specific Checkpoint
To restore your project to a specific checkpoint, use the checkpoint file from
the list:
+12 -66
View File
@@ -1,4 +1,4 @@
# CLI commands
# 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
@@ -26,13 +26,12 @@ Slash commands provide meta-level control over the CLI itself.
- **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
- **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.
- When you run `/chat list`, the CLI only scans these specific
directories to find available checkpoints.
- **Note:** These checkpoints are for manually saving and resuming
conversation states. For automatic checkpoints created before file
modifications, see the
@@ -40,14 +39,8 @@ Slash commands provide meta-level control over the CLI itself.
- **`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>`
@@ -73,9 +66,6 @@ Slash commands provide meta-level control over the CLI itself.
- **`/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
@@ -131,9 +121,6 @@ Slash commands provide meta-level control over the CLI itself.
- **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).
@@ -164,63 +151,22 @@ Slash commands provide meta-level control over the CLI itself.
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
- **Note:** Only available if the CLI is invoked with the `--checkpointing`
option or 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)
- **`/settings`**
- **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.
validation and guidance to prevent errors.
- **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
@@ -283,13 +229,13 @@ Slash commands provide meta-level control over the CLI itself.
file, making it simpler for them to provide project-specific instructions to
the Gemini agent.
### Custom commands
### 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
## Input Prompt Shortcuts
These shortcuts apply directly to the input prompt for text manipulation.
@@ -347,7 +293,7 @@ your prompt to Gemini. These commands include git-aware filtering.
- If the `read_many_files` tool encounters an error (e.g., permission issues),
this will also be reported.
## Shell mode and passthrough commands (`!`)
## Shell mode & passthrough commands (`!`)
The `!` prefix lets you interact with your system's shell directly from within
Gemini CLI.
@@ -375,7 +321,7 @@ Gemini CLI.
- **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,
- **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.
+770
View File
@@ -0,0 +1,770 @@
# Gemini CLI Configuration
Gemini CLI offers several ways to configure its behavior, including environment
variables, command-line arguments, and settings files. This document outlines
the different configuration methods and available settings.
## Configuration layers
Configuration is applied in the following order of precedence (lower numbers are
overridden by higher numbers):
1. **Default values:** Hardcoded defaults within the application.
2. **User settings file:** Global settings for the current user.
3. **Project settings file:** Project-specific settings.
4. **System settings file:** System-wide settings.
5. **Environment variables:** System-wide or session-specific variables,
potentially loaded from `.env` files.
6. **Command-line arguments:** Values passed when launching the CLI.
## Settings files
Gemini CLI uses `settings.json` files for persistent configuration. There are
three locations for these files:
- **User settings file:**
- **Location:** `~/.gemini/settings.json` (where `~` is your home directory).
- **Scope:** Applies to all Gemini CLI sessions for the current user.
- **Project settings file:**
- **Location:** `.gemini/settings.json` within your project's root directory.
- **Scope:** Applies only when running Gemini CLI from that specific project.
Project settings override user settings.
- **System settings file:**
- **Location:** `/etc/gemini-cli/settings.json` (Linux),
`C:\ProgramData\gemini-cli\settings.json` (Windows) or
`/Library/Application Support/GeminiCli/settings.json` (macOS). The path can
be overridden using the `GEMINI_CLI_SYSTEM_SETTINGS_PATH` environment
variable.
- **Scope:** Applies to all Gemini CLI sessions on the system, for all users.
System settings override user and project settings. May be useful for system
administrators at enterprises to have controls over users' Gemini CLI
setups.
**Note on environment variables in settings:** String values within your
`settings.json` files can reference environment variables using either
`$VAR_NAME` or `${VAR_NAME}` syntax. These variables will be automatically
resolved when the settings are loaded. For example, if you have an environment
variable `MY_API_TOKEN`, you could use it in `settings.json` like this:
`"apiKey": "$MY_API_TOKEN"`.
### The `.gemini` directory in your project
In addition to a project settings file, a project's `.gemini` directory can
contain other project-specific files related to Gemini CLI's operation, such as:
- [Custom sandbox profiles](#sandboxing) (e.g.,
`.gemini/sandbox-macos-custom.sb`, `.gemini/sandbox.Dockerfile`).
### Available settings in `settings.json`:
- **`contextFileName`** (string or array of strings):
- **Description:** Specifies the filename for context files (e.g.,
`GEMINI.md`, `AGENTS.md`). Can be a single filename or a list of accepted
filenames.
- **Default:** `GEMINI.md`
- **Example:** `"contextFileName": "AGENTS.md"`
- **`bugCommand`** (object):
- **Description:** Overrides the default URL for the `/bug` command.
- **Default:**
`"urlTemplate": "https://github.com/google-gemini/gemini-cli/issues/new?template=bug_report.yml&title={title}&info={info}"`
- **Properties:**
- **`urlTemplate`** (string): A URL that can contain `{title}` and `{info}`
placeholders.
- **Example:**
```json
"bugCommand": {
"urlTemplate": "https://bug.example.com/new?title={title}&info={info}"
}
```
- **`fileFiltering`** (object):
- **Description:** Controls git-aware file filtering behavior for @ commands
and file discovery tools.
- **Default:** `"respectGitIgnore": true, "enableRecursiveFileSearch": true`
- **Properties:**
- **`respectGitIgnore`** (boolean): Whether to respect .gitignore patterns
when discovering files. When set to `true`, git-ignored files (like
`node_modules/`, `dist/`, `.env`) are automatically excluded from @
commands and file listing operations.
- **`enableRecursiveFileSearch`** (boolean): Whether to enable searching
recursively for filenames under the current tree when completing @
prefixes in the prompt.
- **Example:**
```json
"fileFiltering": {
"respectGitIgnore": true,
"enableRecursiveFileSearch": false
}
```
- **`coreTools`** (array of strings):
- **Description:** Allows you to specify a list of core tool names that should
be made available to the model. This can be used to restrict the set of
built-in tools. See [Built-in Tools](../core/tools-api.md#built-in-tools)
for a list of core tools. You can also specify command-specific restrictions
for tools that support it, like the `ShellTool`. For example,
`"coreTools": ["ShellTool(ls -l)"]` will only allow the `ls -l` command to
be executed.
- **Default:** All tools available for use by the Gemini model.
- **Example:** `"coreTools": ["ReadFileTool", "GlobTool", "ShellTool(ls)"]`.
- **`excludeTools`** (array of strings):
- **Description:** Allows you to specify a list of core tool names that should
be excluded from the model. A tool listed in both `excludeTools` and
`coreTools` is excluded. You can also specify command-specific restrictions
for tools that support it, like the `ShellTool`. For example,
`"excludeTools": ["ShellTool(rm -rf)"]` will block the `rm -rf` command.
- **Default**: No tools excluded.
- **Example:** `"excludeTools": ["run_shell_command", "findFiles"]`.
- **Security Note:** Command-specific restrictions in `excludeTools` for
`run_shell_command` are based on simple string matching and can be easily
bypassed. This feature is **not a security mechanism** and should not be
relied upon to safely execute untrusted code. It is recommended to use
`coreTools` to explicitly select commands that can be executed.
- **`allowMCPServers`** (array of strings):
- **Description:** Allows you to specify a list of MCP server names that
should be made available to the model. This can be used to restrict the set
of MCP servers to connect to. Note that this will be ignored if
`--allowed-mcp-server-names` is set.
- **Default:** All MCP servers are available for use by the Gemini model.
- **Example:** `"allowMCPServers": ["myPythonServer"]`.
- **Security Note:** This uses simple string matching on MCP server names,
which can be modified. If you're a system administrator looking to prevent
users from bypassing this, consider configuring the `mcpServers` at the
system settings level such that the user will not be able to configure any
MCP servers of their own. This should not be used as an airtight security
mechanism.
- **`excludeMCPServers`** (array of strings):
- **Description:** Allows you to specify a list of MCP server names that
should be excluded from the model. A server listed in both
`excludeMCPServers` and `allowMCPServers` is excluded. Note that this will
be ignored if `--allowed-mcp-server-names` is set.
- **Default**: No MCP servers excluded.
- **Example:** `"excludeMCPServers": ["myNodeServer"]`.
- **Security Note:** This uses simple string matching on MCP server names,
which can be modified. If you're a system administrator looking to prevent
users from bypassing this, consider configuring the `mcpServers` at the
system settings level such that the user will not be able to configure any
MCP servers of their own. This should not be used as an airtight security
mechanism.
- **`autoAccept`** (boolean):
- **Description:** Controls whether the CLI automatically accepts and executes
tool calls that are considered safe (e.g., read-only operations) without
explicit user confirmation. If set to `true`, the CLI will bypass the
confirmation prompt for tools deemed safe.
- **Default:** `false`
- **Example:** `"autoAccept": true`
- **`theme`** (string):
- **Description:** Sets the visual [theme](./themes.md) for Gemini CLI.
- **Default:** `"Default"`
- **Example:** `"theme": "GitHub"`
- **`vimMode`** (boolean):
- **Description:** Enables or disables vim mode for input editing. When
enabled, the input area supports vim-style navigation and editing commands
with NORMAL and INSERT modes. The vim mode status is displayed in the footer
and persists between sessions.
- **Default:** `false`
- **Example:** `"vimMode": true`
- **`sandbox`** (boolean or string):
- **Description:** Controls whether and how to use sandboxing for tool
execution. If set to `true`, Gemini CLI uses a pre-built
`gemini-cli-sandbox` Docker image. For more information, see
[Sandboxing](#sandboxing).
- **Default:** `false`
- **Example:** `"sandbox": "docker"`
- **`toolDiscoveryCommand`** (string):
- **Description:** Defines a custom shell command for discovering tools from
your project. The shell command must return on `stdout` a JSON array of
[function declarations](https://ai.google.dev/gemini-api/docs/function-calling#function-declarations).
Tool wrappers are optional.
- **Default:** Empty
- **Example:** `"toolDiscoveryCommand": "bin/get_tools"`
- **`toolCallCommand`** (string):
- **Description:** Defines a custom shell command for calling a specific tool
that was discovered using `toolDiscoveryCommand`. The shell command must
meet the following criteria:
- It must take function `name` (exactly as in
[function declaration](https://ai.google.dev/gemini-api/docs/function-calling#function-declarations))
as first command line argument.
- It must read function arguments as JSON on `stdin`, analogous to
[`functionCall.args`](https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/inference#functioncall).
- It must return function output as JSON on `stdout`, analogous to
[`functionResponse.response.content`](https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/inference#functionresponse).
- **Default:** Empty
- **Example:** `"toolCallCommand": "bin/call_tool"`
- **`mcpServers`** (object):
- **Description:** Configures connections to one or more Model-Context
Protocol (MCP) servers for discovering and using custom tools. Gemini CLI
attempts to connect to each configured MCP server to discover available
tools. If multiple MCP servers expose a tool with the same name, the tool
names will be prefixed with the server alias you defined in the
configuration (e.g., `serverAlias__actualToolName`) to avoid conflicts. Note
that the system might strip certain schema properties from MCP tool
definitions for compatibility.
- **Default:** Empty
- **Properties:**
- **`<SERVER_NAME>`** (object): The server parameters for the named server.
- `command` (string, required): The command to execute to start the MCP
server.
- `args` (array of strings, optional): Arguments to pass to the command.
- `env` (object, optional): Environment variables to set for the server
process.
- `cwd` (string, optional): The working directory in which to start the
server.
- `timeout` (number, optional): Timeout in milliseconds for requests to
this MCP server.
- `trust` (boolean, optional): Trust this server and bypass all tool call
confirmations.
- `includeTools` (array of strings, optional): List of tool names to
include from this MCP server. When specified, only the tools listed here
will be available from this server (whitelist behavior). If not
specified, all tools from the server are enabled by default.
- `excludeTools` (array of strings, optional): List of tool names to
exclude from this MCP server. Tools listed here will not be available to
the model, even if they are exposed by the server. **Note:**
`excludeTools` takes precedence over `includeTools` - if a tool is in
both lists, it will be excluded.
- **Example:**
```json
"mcpServers": {
"myPythonServer": {
"command": "python",
"args": ["mcp_server.py", "--port", "8080"],
"cwd": "./mcp_tools/python",
"timeout": 5000,
"includeTools": ["safe_tool", "file_reader"],
},
"myNodeServer": {
"command": "node",
"args": ["mcp_server.js"],
"cwd": "./mcp_tools/node",
"excludeTools": ["dangerous_tool", "file_deleter"]
},
"myDockerServer": {
"command": "docker",
"args": ["run", "-i", "--rm", "-e", "API_KEY", "ghcr.io/foo/bar"],
"env": {
"API_KEY": "$MY_API_TOKEN"
}
}
}
```
- **`checkpointing`** (object):
- **Description:** Configures the checkpointing feature, which allows you to
save and restore conversation and file states. See the
[Checkpointing documentation](./checkpointing.md) for more details.
- **Default:** `{"enabled": false}`
- **Properties:**
- **`enabled`** (boolean): When `true`, the `/restore` command is available.
- **`preferredEditor`** (string):
- **Description:** Specifies the preferred editor to use for viewing diffs.
- **Default:** `vscode`
- **Example:** `"preferredEditor": "vscode"`
- **`telemetry`** (object)
- **Description:** Configures logging and metrics collection for Gemini CLI.
For more information, see [Telemetry](./telemetry.md).
- **Default:**
`{"enabled": false, "target": "local", "otlpEndpoint": "http://localhost:4317", "logPrompts": true}`
- **Properties:**
- **`enabled`** (boolean): Whether or not telemetry is enabled.
- **`target`** (string): The destination for collected telemetry. Supported
values are `local` and `gcp`.
- **`otlpEndpoint`** (string): The endpoint for the OTLP Exporter.
- **`logPrompts`** (boolean): Whether or not to include the content of user
prompts in the logs.
- **Example:**
```json
"telemetry": {
"enabled": true,
"target": "local",
"otlpEndpoint": "http://localhost:16686",
"logPrompts": false
}
```
- **`usageStatisticsEnabled`** (boolean):
- **Description:** Enables or disables the collection of usage statistics. See
[Usage Statistics](#usage-statistics) for more information.
- **Default:** `true`
- **Example:**
```json
"usageStatisticsEnabled": false
```
- **`hideTips`** (boolean):
- **Description:** Enables or disables helpful tips in the CLI interface.
- **Default:** `false`
- **Example:**
```json
"hideTips": true
```
- **`hideBanner`** (boolean):
- **Description:** Enables or disables the startup banner (ASCII art logo) in
the CLI interface.
- **Default:** `false`
- **Example:**
```json
"hideBanner": true
```
- **`maxSessionTurns`** (number):
- **Description:** Sets the maximum number of turns for a session. If the
session exceeds this limit, the CLI will stop processing and start a new
chat.
- **Default:** `-1` (unlimited)
- **Example:**
```json
"maxSessionTurns": 10
```
- **`summarizeToolOutput`** (object):
- **Description:** Enables or disables the summarization of tool output. You
can specify the token budget for the summarization using the `tokenBudget`
setting.
- Note: Currently only the `run_shell_command` tool is supported.
- **Default:** `{}` (Disabled by default)
- **Example:**
```json
"summarizeToolOutput": {
"run_shell_command": {
"tokenBudget": 2000
}
}
```
- **`excludedProjectEnvVars`** (array of strings):
- **Description:** Specifies environment variables that should be excluded
from being loaded from project `.env` files. This prevents project-specific
environment variables (like `DEBUG=true`) from interfering with gemini-cli
behavior. Variables from `.gemini/.env` files are never excluded.
- **Default:** `["DEBUG", "DEBUG_MODE"]`
- **Example:**
```json
"excludedProjectEnvVars": ["DEBUG", "DEBUG_MODE", "NODE_ENV"]
```
- **`includeDirectories`** (array of strings):
- **Description:** Specifies an array of additional absolute or relative paths
to include in the workspace context. This allows you to work with files
across multiple directories as if they were one. Paths can use `~` to refer
to the user's home directory. This setting can be combined with the
`--include-directories` command-line flag.
- **Default:** `[]`
- **Example:**
```json
"includeDirectories": [
"/path/to/another/project",
"../shared-library",
"~/common-utils"
]
```
- **`loadMemoryFromIncludeDirectories`** (boolean):
- **Description:** Controls the behavior of the `/memory refresh` command. If
set to `true`, `GEMINI.md` files should be loaded from all directories that
are added. If set to `false`, `GEMINI.md` should only be loaded from the
current directory.
- **Default:** `false`
- **Example:**
```json
"loadMemoryFromIncludeDirectories": true
```
### Example `settings.json`:
```json
{
"theme": "GitHub",
"sandbox": "docker",
"toolDiscoveryCommand": "bin/get_tools",
"toolCallCommand": "bin/call_tool",
"mcpServers": {
"mainServer": {
"command": "bin/mcp_server.py"
},
"anotherServer": {
"command": "node",
"args": ["mcp_server.js", "--verbose"]
}
},
"telemetry": {
"enabled": true,
"target": "local",
"otlpEndpoint": "http://localhost:4317",
"logPrompts": true
},
"usageStatisticsEnabled": true,
"hideTips": false,
"hideBanner": false,
"maxSessionTurns": 10,
"summarizeToolOutput": {
"run_shell_command": {
"tokenBudget": 100
}
},
"excludedProjectEnvVars": ["DEBUG", "DEBUG_MODE", "NODE_ENV"],
"includeDirectories": ["path/to/dir1", "~/path/to/dir2", "../path/to/dir3"],
"loadMemoryFromIncludeDirectories": true
}
```
## Shell History
The CLI keeps a history of shell commands you run. To avoid conflicts between
different projects, this history is stored in a project-specific directory
within your user's home folder.
- **Location:** `~/.gemini/tmp/<project_hash>/shell_history`
- `<project_hash>` is a unique identifier generated from your project's root
path.
- The history is stored in a file named `shell_history`.
## Environment Variables & `.env` Files
Environment variables are a common way to configure applications, especially for
sensitive information like API keys or for settings that might change between
environments.
The CLI automatically loads environment variables from an `.env` file. The
loading order is:
1. `.env` file in the current working directory.
2. If not found, it searches upwards in parent directories until it finds an
`.env` file or reaches the project root (identified by a `.git` folder) or
the home directory.
3. If still not found, it looks for `~/.env` (in the user's home directory).
**Environment Variable Exclusion:** Some environment variables (like `DEBUG` and
`DEBUG_MODE`) are automatically excluded from being loaded from project `.env`
files to prevent interference with gemini-cli behavior. Variables from
`.gemini/.env` files are never excluded. You can customize this behavior using
the `excludedProjectEnvVars` setting in your `settings.json` file.
- **`GEMINI_API_KEY`** (Required):
- Your API key for the Gemini API.
- **Crucial for operation.** The CLI will not function without it.
- Set this in your shell profile (e.g., `~/.bashrc`, `~/.zshrc`) or an `.env`
file.
- **`GEMINI_MODEL`**:
- Specifies the default Gemini model to use.
- Overrides the hardcoded default
- Example: `export GEMINI_MODEL="gemini-2.5-flash"`
- **`GOOGLE_API_KEY`**:
- Your Google Cloud API key.
- Required for using Vertex AI in express mode.
- Ensure you have the necessary permissions.
- Example: `export GOOGLE_API_KEY="YOUR_GOOGLE_API_KEY"`.
- **`GOOGLE_CLOUD_PROJECT`**:
- Your Google Cloud Project ID.
- Required for using Code Assist or Vertex AI.
- If using Vertex AI, ensure you have the necessary permissions in this
project.
- **Cloud Shell Note:** When running in a Cloud Shell environment, this
variable defaults to a special project allocated for Cloud Shell users. If
you have `GOOGLE_CLOUD_PROJECT` set in your global environment in Cloud
Shell, it will be overridden by this default. To use a different project in
Cloud Shell, you must define `GOOGLE_CLOUD_PROJECT` in a `.env` file.
- Example: `export GOOGLE_CLOUD_PROJECT="YOUR_PROJECT_ID"`.
- **`GOOGLE_APPLICATION_CREDENTIALS`** (string):
- **Description:** The path to your Google Application Credentials JSON file.
- **Example:**
`export GOOGLE_APPLICATION_CREDENTIALS="/path/to/your/credentials.json"`
- **`OTLP_GOOGLE_CLOUD_PROJECT`**:
- Your Google Cloud Project ID for Telemetry in Google Cloud
- Example: `export OTLP_GOOGLE_CLOUD_PROJECT="YOUR_PROJECT_ID"`.
- **`GOOGLE_CLOUD_LOCATION`**:
- Your Google Cloud Project Location (e.g., us-central1).
- Required for using Vertex AI in non express mode.
- Example: `export GOOGLE_CLOUD_LOCATION="YOUR_PROJECT_LOCATION"`.
- **`GEMINI_SANDBOX`**:
- Alternative to the `sandbox` setting in `settings.json`.
- Accepts `true`, `false`, `docker`, `podman`, or a custom command string.
- **`SEATBELT_PROFILE`** (macOS specific):
- Switches the Seatbelt (`sandbox-exec`) profile on macOS.
- `permissive-open`: (Default) Restricts writes to the project folder (and a
few other folders, see
`packages/cli/src/utils/sandbox-macos-permissive-open.sb`) but allows other
operations.
- `strict`: Uses a strict profile that declines operations by default.
- `<profile_name>`: Uses a custom profile. To define a custom profile, create
a file named `sandbox-macos-<profile_name>.sb` in your project's `.gemini/`
directory (e.g., `my-project/.gemini/sandbox-macos-custom.sb`).
- **`DEBUG` or `DEBUG_MODE`** (often used by underlying libraries or the CLI
itself):
- Set to `true` or `1` to enable verbose debug logging, which can be helpful
for troubleshooting.
- **Note:** These variables are automatically excluded from project `.env`
files by default to prevent interference with gemini-cli behavior. Use
`.gemini/.env` files if you need to set these for gemini-cli specifically.
- **`NO_COLOR`**:
- Set to any value to disable all color output in the CLI.
- **`CLI_TITLE`**:
- Set to a string to customize the title of the CLI.
- **`CODE_ASSIST_ENDPOINT`**:
- Specifies the endpoint for the code assist server.
- This is useful for development and testing.
- **`GEMINI_SYSTEM_MD`**:
- Overrides the base system prompt with the contents of a Markdown file.
- If set to `1` or `true`, it uses the file at `.gemini/system.md`.
- If set to a file path, it uses that file. The path can be absolute or
relative. `~` is supported for the home directory.
- The specified file must exist.
- **`GEMINI_WRITE_SYSTEM_MD`**:
- Writes the default system prompt to a file. This is useful for getting a
template to customize.
- If set to `1` or `true`, it writes to `.gemini/system.md`.
- If set to a file path, it writes to that path. The path can be absolute or
relative. `~` is supported for the home directory. **Note: This will
overwrite the file if it already exists.**
## Command-Line Arguments
Arguments passed directly when running the CLI can override other configurations
for that specific session.
- **`--model <model_name>`** (**`-m <model_name>`**):
- Specifies the Gemini model to use for this session.
- Example: `npm start -- --model gemini-1.5-pro-latest`
- **`--prompt <your_prompt>`** (**`-p <your_prompt>`**):
- Used to pass a prompt directly to the command. This invokes Gemini CLI in a
non-interactive mode.
- **`--prompt-interactive <your_prompt>`** (**`-i <your_prompt>`**):
- Starts an interactive session with the provided prompt as the initial input.
- The prompt is processed within the interactive session, not before it.
- Cannot be used when piping input from stdin.
- Example: `gemini -i "explain this code"`
- **`--sandbox`** (**`-s`**):
- Enables sandbox mode for this session.
- **`--sandbox-image`**:
- Sets the sandbox image URI.
- **`--debug`** (**`-d`**):
- Enables debug mode for this session, providing more verbose output.
- **`--all-files`** (**`-a`**):
- If set, recursively includes all files within the current directory as
context for the prompt.
- **`--help`** (or **`-h`**):
- Displays help information about command-line arguments.
- **`--show-memory-usage`**:
- Displays the current memory usage.
- **`--yolo`**:
- Enables YOLO mode, which automatically approves all tool calls.
- **`--telemetry`**:
- Enables [telemetry](../telemetry.md).
- **`--telemetry-target`**:
- Sets the telemetry target. See [telemetry](../telemetry.md) for more
information.
- **`--telemetry-otlp-endpoint`**:
- Sets the OTLP endpoint for telemetry. See [telemetry](../telemetry.md) for
more information.
- **`--telemetry-log-prompts`**:
- Enables logging of prompts for telemetry. See [telemetry](../telemetry.md)
for more information.
- **`--checkpointing`**:
- Enables [checkpointing](./checkpointing.md).
- **`--extensions <extension_name ...>`** (**`-e <extension_name ...>`**):
- Specifies a list of extensions to use for the session. If not provided, all
available extensions are used.
- Use the special term `gemini -e none` to disable all extensions.
- Example: `gemini -e my-extension -e my-other-extension`
- **`--list-extensions`** (**`-l`**):
- Lists all available extensions and exits.
- **`--proxy`**:
- Sets the proxy for the CLI.
- Example: `--proxy http://localhost:7890`.
- **`--include-directories <dir1,dir2,...>`**:
- Includes additional directories in the workspace for multi-directory
support.
- Can be specified multiple times or as comma-separated values.
- 5 directories can be added at maximum.
- Example: `--include-directories /path/to/project1,/path/to/project2` or
`--include-directories /path/to/project1 --include-directories /path/to/project2`
- **`--version`**:
- Displays the version of the CLI.
## Context Files (Hierarchical Instructional Context)
While not strictly configuration for the CLI's _behavior_, context files
(defaulting to `GEMINI.md` but configurable via the `contextFileName` setting)
are crucial for configuring the _instructional context_ (also referred to as
"memory") provided to the Gemini model. This powerful feature allows you to give
project-specific instructions, coding style guides, or any relevant background
information to the AI, making its responses more tailored and accurate to your
needs. The CLI includes UI elements, such as an indicator in the footer showing
the number of loaded context files, to keep you informed about the active
context.
- **Purpose:** These Markdown files contain instructions, guidelines, or context
that you want the Gemini model to be aware of during your interactions. The
system is designed to manage this instructional context hierarchically.
### Example Context File Content (e.g., `GEMINI.md`)
Here's a conceptual example of what a context file at the root of a TypeScript
project might contain:
```markdown
# Project: My Awesome TypeScript Library
## General Instructions:
- When generating new TypeScript code, please follow the existing coding style.
- Ensure all new functions and classes have JSDoc comments.
- Prefer functional programming paradigms where appropriate.
- All code should be compatible with TypeScript 5.0 and Node.js 20+.
## Coding Style:
- Use 2 spaces for indentation.
- Interface names should be prefixed with `I` (e.g., `IUserService`).
- Private class members should be prefixed with an underscore (`_`).
- Always use strict equality (`===` and `!==`).
## Specific Component: `src/api/client.ts`
- This file handles all outbound API requests.
- When adding new API call functions, ensure they include robust error handling
and logging.
- Use the existing `fetchWithRetry` utility for all GET requests.
## Regarding Dependencies:
- Avoid introducing new external dependencies unless absolutely necessary.
- If a new dependency is required, please state the reason.
```
This example demonstrates how you can provide general project context, specific
coding conventions, and even notes about particular files or components. The
more relevant and precise your context files are, the better the AI can assist
you. Project-specific context files are highly encouraged to establish
conventions and context.
- **Hierarchical Loading and Precedence:** The CLI implements a sophisticated
hierarchical memory system by loading context files (e.g., `GEMINI.md`) from
several locations. Content from files lower in this list (more specific)
typically overrides or supplements content from files higher up (more
general). The exact concatenation order and final context can be inspected
using the `/memory show` command. The typical loading order is:
1. **Global Context File:**
- Location: `~/.gemini/<contextFileName>` (e.g., `~/.gemini/GEMINI.md` in
your user home directory).
- Scope: Provides default instructions for all your projects.
2. **Project Root & Ancestors Context Files:**
- Location: The CLI searches for the configured context file in the
current working directory and then in each parent directory up to either
the project root (identified by a `.git` folder) or your home directory.
- Scope: Provides context relevant to the entire project or a significant
portion of it.
3. **Sub-directory Context Files (Contextual/Local):**
- Location: The CLI also scans for the configured context file in
subdirectories _below_ the current working directory (respecting common
ignore patterns like `node_modules`, `.git`, etc.). The breadth of this
search is limited to 200 directories by default, but can be configured
with a `memoryDiscoveryMaxDirs` field in your `settings.json` file.
- Scope: Allows for highly specific instructions relevant to a particular
component, module, or subsection of your project.
- **Concatenation & UI Indication:** The contents of all found context files are
concatenated (with separators indicating their origin and path) and provided
as part of the system prompt to the Gemini model. The CLI footer displays the
count of loaded context files, giving you a quick visual cue about the active
instructional context.
- **Importing Content:** You can modularize your context files by importing
other Markdown files using the `@path/to/file.md` syntax. For more details,
see the [Memory Import Processor documentation](../core/memport.md).
- **Commands for Memory Management:**
- Use `/memory refresh` to force a re-scan and reload of all context files
from all configured locations. This updates the AI's instructional context.
- Use `/memory show` to display the combined instructional context currently
loaded, allowing you to verify the hierarchy and content being used by the
AI.
- See the [Commands documentation](./commands.md#memory) for full details on
the `/memory` command and its sub-commands (`show` and `refresh`).
By understanding and utilizing these configuration layers and the hierarchical
nature of context files, you can effectively manage the AI's memory and tailor
the Gemini CLI's responses to your specific needs and projects.
## Sandboxing
The Gemini CLI can execute potentially unsafe operations (like shell commands
and file modifications) within a sandboxed environment to protect your system.
Sandboxing is disabled by default, but you can enable it in a few ways:
- Using `--sandbox` or `-s` flag.
- Setting `GEMINI_SANDBOX` environment variable.
- Sandbox is enabled in `--yolo` mode by default.
By default, it uses a pre-built `gemini-cli-sandbox` Docker image.
For project-specific sandboxing needs, you can create a custom Dockerfile at
`.gemini/sandbox.Dockerfile` in your project's root directory. This Dockerfile
can be based on the base sandbox image:
```dockerfile
FROM gemini-cli-sandbox
# Add your custom dependencies or configurations here
# For example:
# RUN apt-get update && apt-get install -y some-package
# COPY ./my-config /app/my-config
```
When `.gemini/sandbox.Dockerfile` exists, you can use `BUILD_SANDBOX`
environment variable when running Gemini CLI to automatically build the custom
sandbox image:
```bash
BUILD_SANDBOX=1 gemini -s
```
## Usage Statistics
To help us improve the Gemini CLI, we collect anonymized usage statistics. This
data helps us understand how the CLI is used, identify common issues, and
prioritize new features.
**What we collect:**
- **Tool Calls:** We log the names of the tools that are called, whether they
succeed or fail, and how long they take to execute. We do not collect the
arguments passed to the tools or any data returned by them.
- **API Requests:** We log the Gemini model used for each request, the duration
of the request, and whether it was successful. We do not collect the content
of the prompts or responses.
- **Session Information:** We collect information about the configuration of the
CLI, such as the enabled tools and the approval mode.
**What we DON'T collect:**
- **Personally Identifiable Information (PII):** We do not collect any personal
information, such as your name, email address, or API keys.
- **Prompt and Response Content:** We do not log the content of your prompts or
the responses from the Gemini model.
- **File Content:** We do not log the content of any files that are read or
written by the CLI.
**How to opt out:**
You can opt out of usage statistics collection at any time by setting the
`usageStatisticsEnabled` property to `false` in your `settings.json` file:
```json
{
"usageStatisticsEnabled": false
}
```
+17 -17
View File
@@ -1,4 +1,4 @@
# Custom commands
# Custom Commands
Custom commands let you save and reuse your favorite or most frequently used
prompts as personal shortcuts within Gemini CLI. You can create commands that
@@ -9,9 +9,9 @@ all your projects, streamlining your workflow and ensuring consistency.
Gemini CLI discovers commands from two locations, loaded in a specific order:
1. **User commands (global):** Located in `~/.gemini/commands/`. These commands
1. **User Commands (Global):** Located in `~/.gemini/commands/`. These commands
are available in any project you are working on.
2. **Project commands (local):** Located in
2. **Project Commands (Local):** Located in
`<your-project-root>/.gemini/commands/`. These commands are specific to the
current project and can be checked into version control to be shared with
your team.
@@ -30,7 +30,7 @@ separator (`/` or `\`) being converted to a colon (`:`).
- A file at `<project>/.gemini/commands/git/commit.toml` becomes the namespaced
command `/git:commit`.
## TOML file format (v1)
## TOML File Format (v1)
Your command definition files must be written in the TOML format and use the
`.toml` file extension.
@@ -50,7 +50,7 @@ Your command definition files must be written in the TOML format and use the
## Handling arguments
Custom commands support two powerful methods for handling arguments. The CLI
automatically chooses the correct method based on the content of your command's
automatically chooses the correct method based on the content of your command\'s
`prompt`.
### 1. Context-aware injection with `{{args}}`
@@ -60,7 +60,7 @@ replace that placeholder with the text the user typed after the command name.
The behavior of this injection depends on where it is used:
**A. Raw injection (outside shell commands)**
**A. Raw injection (outside Shell commands)**
When used in the main body of the prompt, the arguments are injected exactly as
the user typed them.
@@ -77,7 +77,7 @@ prompt = "Please provide a code fix for the issue described here: {{args}}."
The model receives:
`Please provide a code fix for the issue described here: "Button is misaligned".`
**B. Using arguments in shell commands (inside `!{...}` blocks)**
**B. Using arguments in Shell commands (inside `!{...}` blocks)**
When you use `{{args}}` inside a shell injection block (`!{...}`), the arguments
are automatically **shell-escaped** before replacement. This allows you to
@@ -96,13 +96,13 @@ Search Results:
"""
```
When you run `/grep-code It's complicated`:
When you run `/grep-code It\'s complicated`:
1. The CLI sees `{{args}}` used both outside and inside `!{...}`.
2. Outside: The first `{{args}}` is replaced raw with `It's complicated`.
2. Outside: The first `{{args}}` is replaced raw with `It\'s complicated`.
3. Inside: The second `{{args}}` is replaced with the escaped version (e.g., on
Linux: `"It\'s complicated"`).
4. The command executed is `grep -r "It's complicated" .`.
4. The command executed is `grep -r "It\'s complicated" .`.
5. The CLI prompts you to confirm this exact, secure command before execution.
6. The final prompt is sent.
@@ -129,13 +129,13 @@ format and behavior.
# In: <project>/.gemini/commands/changelog.toml
# Invoked via: /changelog 1.2.0 added "Support for default argument parsing."
description = "Adds a new entry to the project's CHANGELOG.md file."
description = "Adds a new entry to the project\'s CHANGELOG.md file."
prompt = """
# Task: Update Changelog
You are an expert maintainer of this software project. A user has invoked a command to add a new entry to the changelog.
**The user's raw command is appended below your instructions.**
**The user\'s raw command is appended below your instructions.**
Your task is to parse the `<version>`, `<change_type>`, and `<message>` from their input and use the `write_file` tool to correctly update the `CHANGELOG.md` file.
@@ -147,7 +147,7 @@ The command follows this format: `/changelog <version> <type> <message>`
1. Read the `CHANGELOG.md` file.
2. Find the section for the specified `<version>`.
3. Add the `<message>` under the correct `<type>` heading.
4. If the version or type section doesn't exist, create it.
4. If the version or type section doesn\'t exist, create it.
5. Adhere strictly to the "Keep a Changelog" format.
"""
```
@@ -156,7 +156,7 @@ When you run `/changelog 1.2.0 added "New feature"`, the final text sent to the
model will be the original prompt followed by two newlines and the command you
typed.
### 3. Executing shell commands with `!{...}`
### 3. Executing Shell commands with `!{...}`
You can make your commands dynamic by executing shell commands directly within
your `prompt` and injecting their output. This is ideal for gathering context
@@ -241,7 +241,7 @@ operate on specific files.
**Example (`review.toml`):**
This command injects the content of a _fixed_ best practices file
(`docs/best-practices.md`) and uses the user's arguments to provide context for
(`docs/best-practices.md`) and uses the user\'s arguments to provide context for
the review.
```toml
@@ -293,7 +293,7 @@ practice.
description = "Asks the model to refactor the current context into a pure function."
prompt = """
Please analyze the code I've provided in the current context.
Please analyze the code I\'ve provided in the current context.
Refactor it into a pure function.
Your response should include:
@@ -302,7 +302,7 @@ Your response should include:
"""
```
**3. Run the command:**
**3. Run the Command:**
That's it! You can now run your command in the CLI. First, you might add a file
to the context, and then invoke your command:
+25 -120
View File
@@ -1,11 +1,11 @@
# Gemini CLI for the enterprise
# Gemini CLI for the Enterprise
This document outlines configuration patterns and best practices for deploying
and managing Gemini CLI in an enterprise environment. By leveraging system-level
settings, administrators can enforce security policies, manage tool access, and
ensure a consistent experience for all users.
> **A note on security:** The patterns described in this document are intended
> **A Note on Security:** The patterns described in this document are intended
> to help administrators create a more controlled and secure environment for
> using Gemini CLI. However, they should not be considered a foolproof security
> boundary. A determined user with sufficient privileges on their local machine
@@ -14,7 +14,7 @@ ensure a consistent experience for all users.
> managed environment, not to defend against a malicious actor with local
> administrative rights.
## Centralized configuration: The system settings file
## Centralized Configuration: The System Settings File
The most powerful tools for enterprise administration are the system-wide
settings files. These files allow you to define a baseline configuration
@@ -33,11 +33,11 @@ settings (like `theme`) is:
This means the System Overrides file has the final say. For settings that are
arrays (`includeDirectories`) or objects (`mcpServers`), the values are merged.
**Example of merging and precedence:**
**Example of Merging and Precedence:**
Here is how settings from different levels are combined.
- **System defaults `system-defaults.json`:**
- **System Defaults `system-defaults.json`:**
```json
{
@@ -89,7 +89,7 @@ Here is how settings from different levels are combined.
}
```
- **System overrides `settings.json`:**
- **System Overrides `settings.json`:**
```json
{
"ui": {
@@ -108,7 +108,7 @@ Here is how settings from different levels are combined.
This results in the following merged configuration:
- **Final merged configuration:**
- **Final Merged Configuration:**
```json
{
"ui": {
@@ -159,51 +159,7 @@ This results in the following merged configuration:
By using the system settings file, you can enforce the security and
configuration patterns described below.
### Enforcing system settings with a wrapper script
While the `GEMINI_CLI_SYSTEM_SETTINGS_PATH` environment variable provides
flexibility, a user could potentially override it to point to a different
settings file, bypassing the centrally managed configuration. To mitigate this,
enterprises can deploy a wrapper script or alias that ensures the environment
variable is always set to the corporate-controlled path.
This approach ensures that no matter how the user calls the `gemini` command,
the enterprise settings are always loaded with the highest precedence.
**Example wrapper script:**
Administrators can create a script named `gemini` and place it in a directory
that appears earlier in the user's `PATH` than the actual Gemini CLI binary
(e.g., `/usr/local/bin/gemini`).
```bash
#!/bin/bash
# Enforce the path to the corporate system settings file.
# This ensures that the company's configuration is always applied.
export GEMINI_CLI_SYSTEM_SETTINGS_PATH="/etc/gemini-cli/settings.json"
# Find the original gemini executable.
# This is a simple example; a more robust solution might be needed
# depending on the installation method.
REAL_GEMINI_PATH=$(type -aP gemini | grep -v "^$(type -P gemini)$" | head -n 1)
if [ -z "$REAL_GEMINI_PATH" ]; then
echo "Error: The original 'gemini' executable was not found." >&2
exit 1
fi
# Pass all arguments to the real Gemini CLI executable.
exec "$REAL_GEMINI_PATH" "$@"
```
By deploying this script, the `GEMINI_CLI_SYSTEM_SETTINGS_PATH` is set within
the script's environment, and the `exec` command replaces the script process
with the actual Gemini CLI process, which inherits the environment variable.
This makes it significantly more difficult for a user to bypass the enforced
settings.
## Restricting tool access
## Restricting Tool Access
You can significantly enhance security by controlling which tools the Gemini
model can use. This is achieved through the `tools.core` and `tools.exclude`
@@ -241,39 +197,19 @@ environment to a blocklist.
}
```
**Security note:** Blocklisting with `excludeTools` is less secure than
**Security Note:** Blocklisting with `excludeTools` is less secure than
allowlisting with `coreTools`, as it relies on blocking known-bad commands, and
clever users may find ways to bypass simple string-based blocks. **Allowlisting
is the recommended approach.**
### Disabling YOLO mode
To ensure that users cannot bypass the confirmation prompt for tool execution,
you can disable YOLO mode at the policy level. This adds a critical layer of
safety, as it prevents the model from executing tools without explicit user
approval.
**Example:** Force all tool executions to require user confirmation.
```json
{
"security": {
"disableYoloMode": true
}
}
```
This setting is highly recommended in an enterprise environment to prevent
unintended tool execution.
## Managing custom tools (MCP servers)
## Managing Custom Tools (MCP Servers)
If your organization uses custom tools via
[Model-Context Protocol (MCP) servers](../core/tools-api.md), it is crucial to
understand how server configurations are managed to apply security policies
effectively.
### How MCP server configurations are merged
### How MCP Server Configurations are Merged
Gemini CLI loads `settings.json` files from three levels: System, Workspace, and
User. When it comes to the `mcpServers` object, these configurations are
@@ -290,12 +226,12 @@ This means a user **cannot** override the definition of a server that is already
defined in the system-level settings. However, they **can** add new servers with
unique names.
### Enforcing a catalog of tools
### Enforcing a Catalog of Tools
The security of your MCP tool ecosystem depends on a combination of defining the
canonical servers and adding their names to an allowlist.
### Restricting tools within an MCP server
### Restricting Tools Within an MCP Server
For even greater security, especially when dealing with third-party MCP servers,
you can restrict which specific tools from a server are exposed to the model.
@@ -324,7 +260,7 @@ third-party MCP server, even if the server offers other tools like
}
```
#### More secure pattern: Define and add to allowlist in system settings
#### More Secure Pattern: Define and Add to Allowlist in System Settings
To create a secure, centrally-managed catalog of tools, the system administrator
**must** do both of the following in the system-level `settings.json` file:
@@ -337,7 +273,7 @@ To create a secure, centrally-managed catalog of tools, the system administrator
any servers that are not on this list. If this setting is omitted, the CLI
will merge and allow any server defined by the user.
**Example system `settings.json`:**
**Example System `settings.json`:**
1. Add the _names_ of all approved servers to an allowlist. This will prevent
users from adding their own servers.
@@ -366,12 +302,12 @@ Any server a user defines will either be overridden by the system definition (if
it has the same name) or blocked because its name is not in the `mcp.allowed`
list.
### Less secure pattern: Omitting the allowlist
### Less Secure Pattern: Omitting the Allowlist
If the administrator defines the `mcpServers` object but fails to also specify
the `mcp.allowed` allowlist, users may add their own servers.
**Example system `settings.json`:**
**Example System `settings.json`:**
This configuration defines servers but does not enforce the allowlist. The
administrator has NOT included the "mcp.allowed" setting.
@@ -391,7 +327,7 @@ In this scenario, a user can add their own server in their local
results, the user's server will be added to the list of available tools and
allowed to run.
## Enforcing sandboxing for security
## Enforcing Sandboxing for Security
To mitigate the risk of potentially harmful operations, you can enforce the use
of sandboxing for all tool execution. The sandbox isolates tool execution in a
@@ -407,18 +343,19 @@ containerized environment.
}
```
You can also specify a custom, hardened Docker image for the sandbox by building
a custom `sandbox.Dockerfile` as described in the
You can also specify a custom, hardened Docker image for the sandbox using the
`--sandbox-image` command-line argument or by building a custom
`sandbox.Dockerfile` as described in the
[Sandboxing documentation](./sandbox.md).
## Controlling network access via proxy
## Controlling Network Access via Proxy
In corporate environments with strict network policies, you can configure Gemini
CLI to route all outbound traffic through a corporate proxy. This can be set via
an environment variable, but it can also be enforced for custom tools via the
`mcpServers` configuration.
**Example (for an MCP server):**
**Example (for an MCP Server):**
```json
{
@@ -435,7 +372,7 @@ an environment variable, but it can also be enforced for custom tools via the
}
```
## Telemetry and auditing
## Telemetry and Auditing
For auditing and monitoring purposes, you can configure Gemini CLI to send
telemetry data to a central location. This allows you to track tool usage and
@@ -478,39 +415,7 @@ prompted to switch to the enforced method. In non-interactive mode, the CLI will
exit with an error if the configured authentication method does not match the
enforced one.
### Restricting logins to corporate domains
For enterprises using Google Workspace, you can enforce that users only
authenticate with their corporate Google accounts. This is a network-level
control that is configured on a proxy server, not within Gemini CLI itself. It
works by intercepting authentication requests to Google and adding a special
HTTP header.
This policy prevents users from logging in with personal Gmail accounts or other
non-corporate Google accounts.
For detailed instructions, see the Google Workspace Admin Help article on
[blocking access to consumer accounts](https://support.google.com/a/answer/1668854?hl=en#zippy=%2Cstep-choose-a-web-proxy-server%2Cstep-configure-the-network-to-block-certain-accounts).
The general steps are as follows:
1. **Intercept Requests**: Configure your web proxy to intercept all requests
to `google.com`.
2. **Add HTTP Header**: For each intercepted request, add the
`X-GoogApps-Allowed-Domains` HTTP header.
3. **Specify Domains**: The value of the header should be a comma-separated
list of your approved Google Workspace domain names.
**Example header:**
```
X-GoogApps-Allowed-Domains: my-corporate-domain.com, secondary-domain.com
```
When this header is present, Google's authentication service will only allow
logins from accounts belonging to the specified domains.
## Putting it all together: example system `settings.json`
## Putting It All Together: Example System `settings.json`
Here is an example of a system `settings.json` file that combines several of the
patterns discussed above to create a secure, controlled environment for Gemini
+3 -3
View File
@@ -1,4 +1,4 @@
# Ignoring files
# Ignoring Files
This document provides an overview of the Gemini Ignore (`.geminiignore`)
feature of the Gemini CLI.
@@ -13,8 +13,8 @@ Git).
When you add a path to your `.geminiignore` file, tools that respect this file
will exclude matching files and directories from their operations. For example,
when you use the `@` command to share files, any paths in your `.geminiignore`
file will be automatically excluded.
when you use the [`read_many_files`](../tools/multi-file.md) command, any paths
in your `.geminiignore` file will be automatically excluded.
For the most part, `.geminiignore` follows the conventions of `.gitignore`
files:
+1 -1
View File
@@ -1,4 +1,4 @@
# Provide context with GEMINI.md files
# Provide Context with GEMINI.md Files
Context files, which use the default name `GEMINI.md`, are a powerful feature
for providing instructional context to the Gemini model. You can use these files
-210
View File
@@ -1,210 +0,0 @@
# Advanced Model Configuration
This guide details the Model Configuration system within the Gemini CLI.
Designed for researchers, AI quality engineers, and advanced users, this system
provides a rigorous framework for managing generative model hyperparameters and
behaviors.
> **Warning**: This is a power-user feature. Configuration values are passed
> directly to the model provider with minimal validation. Incorrect settings
> (e.g., incompatible parameter combinations) may result in runtime errors from
> the API.
## 1. System Overview
The Model Configuration system (`ModelConfigService`) enables deterministic
control over model generation. It decouples the requested model identifier
(e.g., a CLI flag or agent request) from the underlying API configuration. This
allows for:
- **Precise Hyperparameter Tuning**: Direct control over `temperature`, `topP`,
`thinkingBudget`, and other SDK-level parameters.
- **Environment-Specific Behavior**: Distinct configurations for different
operating contexts (e.g., testing vs. production).
- **Agent-Scoped Customization**: Applying specific settings only when a
particular agent is active.
The system operates on two core primitives: **Aliases** and **Overrides**.
## 2. Configuration Primitives
These settings are located under the `modelConfigs` key in your configuration
file.
### Aliases (`customAliases`)
Aliases are named, reusable configuration presets. Users should define their own
aliases (or override system defaults) in the `customAliases` map.
- **Inheritance**: An alias can `extends` another alias (including system
defaults like `chat-base`), inheriting its `modelConfig`. Child aliases can
overwrite or augment inherited settings.
- **Abstract Aliases**: An alias is not required to specify a concrete `model`
if it serves purely as a base for other aliases.
**Example Hierarchy**:
```json
"modelConfigs": {
"customAliases": {
"base": {
"modelConfig": {
"generateContentConfig": { "temperature": 0.0 }
}
},
"chat-base": {
"extends": "base",
"modelConfig": {
"generateContentConfig": { "temperature": 0.7 }
}
}
}
}
```
### Overrides (`overrides`)
Overrides are conditional rules that inject configuration based on the runtime
context. They are evaluated dynamically for each model request.
- **Match Criteria**: Overrides apply when the request context matches the
specified `match` properties.
- `model`: Matches the requested model name or alias.
- `overrideScope`: Matches the distinct scope of the request (typically the
agent name, e.g., `codebaseInvestigator`).
**Example Override**:
```json
"modelConfigs": {
"overrides": [
{
"match": {
"overrideScope": "codebaseInvestigator"
},
"modelConfig": {
"generateContentConfig": { "temperature": 0.1 }
}
}
]
}
```
## 3. Resolution Strategy
The `ModelConfigService` resolves the final configuration through a two-step
process:
### Step 1: Alias Resolution
The requested model string is looked up in the merged map of system `aliases`
and user `customAliases`.
1. If found, the system recursively resolves the `extends` chain.
2. Settings are merged from parent to child (child wins).
3. This results in a base `ResolvedModelConfig`.
4. If not found, the requested string is treated as the raw model name.
### Step 2: Override Application
The system evaluates the `overrides` list against the request context (`model`
and `overrideScope`).
1. **Filtering**: All matching overrides are identified.
2. **Sorting**: Matches are prioritized by **specificity** (the number of
matched keys in the `match` object).
- Specific matches (e.g., `model` + `overrideScope`) override broad matches
(e.g., `model` only).
- Tie-breaking: If specificity is equal, the order of definition in the
`overrides` array is preserved (last one wins).
3. **Merging**: The configurations from the sorted overrides are merged
sequentially onto the base configuration.
## 4. Configuration Reference
The configuration follows the `ModelConfigServiceConfig` interface.
### `ModelConfig` Object
Defines the actual parameters for the model.
| Property | Type | Description |
| :---------------------- | :------- | :----------------------------------------------------------------- |
| `model` | `string` | The identifier of the model to be called (e.g., `gemini-2.5-pro`). |
| `generateContentConfig` | `object` | The configuration object passed to the `@google/genai` SDK. |
### `GenerateContentConfig` (Common Parameters)
Directly maps to the SDK's `GenerateContentConfig`. Common parameters include:
- **`temperature`**: (`number`) Controls output randomness. Lower values (0.0)
are deterministic; higher values (>0.7) are creative.
- **`topP`**: (`number`) Nucleus sampling probability.
- **`maxOutputTokens`**: (`number`) Limit on generated response length.
- **`thinkingConfig`**: (`object`) Configuration for models with reasoning
capabilities (e.g., `thinkingBudget`, `includeThoughts`).
## 5. Practical Examples
### Defining a Deterministic Baseline
Create an alias for tasks requiring high precision, extending the standard chat
configuration but enforcing zero temperature.
```json
"modelConfigs": {
"customAliases": {
"precise-mode": {
"extends": "chat-base",
"modelConfig": {
"generateContentConfig": {
"temperature": 0.0,
"topP": 1.0
}
}
}
}
}
```
### Agent-Specific Parameter Injection
Enforce extended thinking budgets for a specific agent without altering the
global default, e.g. for the `codebaseInvestigator`.
```json
"modelConfigs": {
"overrides": [
{
"match": {
"overrideScope": "codebaseInvestigator"
},
"modelConfig": {
"generateContentConfig": {
"thinkingConfig": { "thinkingBudget": 4096 }
}
}
}
]
}
```
### Experimental Model Evaluation
Route traffic for a specific alias to a preview model for A/B testing, without
changing client code.
```json
"modelConfigs": {
"overrides": [
{
"match": {
"model": "gemini-2.5-pro"
},
"modelConfig": {
"model": "gemini-2.5-pro-experimental-001"
}
}
]
}
```
+17 -17
View File
@@ -1,4 +1,4 @@
# Headless mode
# Headless Mode
Headless mode allows you to run Gemini CLI programmatically from command line
scripts and automation tools without any interactive UI. This is ideal for
@@ -45,9 +45,9 @@ The headless mode provides a headless interface to Gemini CLI that:
- Enables automation and scripting workflows
- Provides consistent exit codes for error handling
## Basic usage
## Basic Usage
### Direct prompts
### Direct Prompts
Use the `--prompt` (or `-p`) flag to run in headless mode:
@@ -55,7 +55,7 @@ Use the `--prompt` (or `-p`) flag to run in headless mode:
gemini --prompt "What is machine learning?"
```
### Stdin input
### Stdin Input
Pipe input to Gemini CLI from your terminal:
@@ -63,7 +63,7 @@ Pipe input to Gemini CLI from your terminal:
echo "Explain this code" | gemini
```
### Combining with file input
### Combining with File Input
Read from files and process with Gemini:
@@ -71,9 +71,9 @@ Read from files and process with Gemini:
cat README.md | gemini --prompt "Summarize this documentation"
```
## Output formats
## Output Formats
### Text output (default)
### Text Output (Default)
Standard human-readable output:
@@ -87,12 +87,12 @@ Response format:
The capital of France is Paris.
```
### JSON output
### JSON Output
Returns structured data including response, statistics, and metadata. This
format is ideal for programmatic processing and automation scripts.
#### Response schema
#### Response Schema
The JSON output follows this high-level structure:
@@ -140,7 +140,7 @@ The JSON output follows this high-level structure:
}
```
#### Example usage
#### Example Usage
```bash
gemini -p "What is the capital of France?" --output-format json
@@ -218,14 +218,14 @@ Response:
}
```
### Streaming JSON output
### 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
#### When to Use Streaming JSON
Use `--output-format stream-json` when you need:
@@ -237,7 +237,7 @@ Use `--output-format stream-json` when you need:
timestamps
- **Pipeline integration** - Stream events to logging/monitoring systems
#### Event types
#### Event Types
The streaming format emits 6 event types:
@@ -248,7 +248,7 @@ The streaming format emits 6 event types:
5. **`error`** - Non-fatal errors and warnings
6. **`result`** - Final session outcome with aggregated stats
#### Basic usage
#### Basic Usage
```bash
# Stream events to console
@@ -261,7 +261,7 @@ gemini --output-format stream-json --prompt "Analyze this code" > events.jsonl
gemini --output-format stream-json --prompt "List files" | jq -r '.type'
```
#### Example output
#### Example Output
Each line is a complete JSON event:
@@ -274,7 +274,7 @@ Each line is a complete JSON event:
{"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
### File Redirection
Save output to files or pipe to other commands:
@@ -292,7 +292,7 @@ gemini -p "Explain microservices" | wc -w
gemini -p "List programming languages" | grep -i "python"
```
## Configuration options
## Configuration Options
Key command-line options for headless usage:
+11 -18
View File
@@ -7,17 +7,14 @@ 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
(e.g., `/help`, `/chat`, `/tools`).
- **[Custom Commands](./custom-commands.md):** Create your own commands and
shortcuts for frequently used prompts.
- **[Headless mode](./headless.md):** Use Gemini CLI programmatically for
- **[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](./keyboard-shortcuts.md):** A reference for all
keyboard shortcuts to improve your workflow.
- **[Tutorials](./tutorials.md):** Step-by-step guides for common tasks.
@@ -25,23 +22,19 @@ overview of Gemini CLI, see the [main documentation page](../index.md).
- **[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.
- **[Enterprise Configuration](./enterprise.md):** Deploying 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
- **[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
- **[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,
- **[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
@@ -62,4 +55,4 @@ gemini -p "What is fine tuning?"
```
For comprehensive documentation on headless usage, scripting, automation, and
advanced examples, see the **[Headless mode](./headless.md)** guide.
advanced examples, see the **[Headless Mode](./headless.md)** guide.
+57 -113
View File
@@ -1,124 +1,68 @@
# Gemini CLI keyboard shortcuts
# 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.
This document lists the available keyboard shortcuts in the Gemini CLI.
<!-- KEYBINDINGS-AUTOGEN:START -->
## General
#### Basic Controls
| Shortcut | Description |
| -------- | --------------------------------------------------------------------------------------------------------------------- |
| `Esc` | Close dialogs and suggestions. |
| `Ctrl+C` | Cancel the ongoing request and clear the input. Press twice to exit the application. |
| `Ctrl+D` | Exit the application if the input is empty. Press twice to confirm. |
| `Ctrl+L` | Clear the screen. |
| `Ctrl+O` | Toggle the display of the debug console. |
| `Ctrl+S` | Allows long responses to print fully, disabling truncation. Use your terminal's scrollback to view the entire output. |
| `Ctrl+Y` | Toggle auto-approval (YOLO mode) for all tool calls. |
| 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` |
## Input Prompt
#### Cursor Movement
| Shortcut | Description |
| -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `!` | Toggle shell mode when the input is empty. |
| `\` (at end of line) + `Enter` | Insert a newline. |
| `Down Arrow` | Navigate down through the input history. |
| `Enter` | Submit the current prompt. |
| `Meta+Delete` / `Ctrl+Delete` | Delete the word to the right of the cursor. |
| `Tab` | Autocomplete the current suggestion if one exists. |
| `Up Arrow` | Navigate up through the input history. |
| `Ctrl+A` / `Home` | Move the cursor to the beginning of the line. |
| `Ctrl+B` / `Left Arrow` | Move the cursor one character to the left. |
| `Ctrl+C` | Clear the input prompt |
| `Esc` (double press) | Clear the input prompt. |
| `Ctrl+D` / `Delete` | Delete the character to the right of the cursor. |
| `Ctrl+E` / `End` | Move the cursor to the end of the line. |
| `Ctrl+F` / `Right Arrow` | Move the cursor one character to the right. |
| `Ctrl+H` / `Backspace` | Delete the character to the left of the cursor. |
| `Ctrl+K` | Delete from the cursor to the end of the line. |
| `Ctrl+Left Arrow` / `Meta+Left Arrow` / `Meta+B` | Move the cursor one word to the left. |
| `Ctrl+N` | Navigate down through the input history. |
| `Ctrl+P` | Navigate up through the input history. |
| `Ctrl+Right Arrow` / `Meta+Right Arrow` / `Meta+F` | Move the cursor one word to the right. |
| `Ctrl+U` | Delete from the cursor to the beginning of the line. |
| `Ctrl+V` | Paste clipboard content. If the clipboard contains an image, it will be saved and a reference to it will be inserted in the prompt. |
| `Ctrl+W` / `Meta+Backspace` / `Ctrl+Backspace` | Delete the word to the left of the cursor. |
| `Ctrl+X` / `Meta+Enter` | Open the current input in an external editor. |
| 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` |
## Suggestions
#### Editing
| Shortcut | Description |
| --------------- | -------------------------------------- |
| `Down Arrow` | Navigate down through the suggestions. |
| `Tab` / `Enter` | Accept the selected suggestion. |
| `Up Arrow` | Navigate up through the suggestions. |
| 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` |
## Radio Button Select
#### Scrolling
| Shortcut | Description |
| ------------------ | ------------------------------------------------------------------------------------------------------------- |
| `Down Arrow` / `j` | Move selection down. |
| `Enter` | Confirm selection. |
| `Up Arrow` / `k` | Move selection up. |
| `1-9` | Select an item by its number. |
| (multi-digit) | For items with numbers greater than 9, press the digits in quick succession to select the corresponding item. |
| 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` |
## IDE Integration
#### 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.
| Shortcut | Description |
| -------- | --------------------------------- |
| `Ctrl+G` | See context CLI received from IDE |
-37
View File
@@ -1,37 +0,0 @@
# Model routing
Gemini CLI includes a model routing feature that automatically switches to a
fallback model in case of a model failure. This feature is enabled by default
and provides resilience when the primary model is unavailable.
## How it works
Model routing is managed by the `ModelAvailabilityService`, which monitors model
health and automatically routes requests to available models based on defined
policies.
1. **Model failure:** If the currently selected model fails (e.g., due to quota
or server errors), the CLI will initiate the fallback process.
2. **User consent:** Depending on the failure and the model's policy, the CLI
may prompt you to switch to a fallback model (by default always prompts
you).
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.
### Model selection precedence
The model used by Gemini CLI is determined by the following order of precedence:
1. **`--model` command-line flag:** A model specified with the `--model` flag
when launching the CLI will always be used.
2. **`GEMINI_MODEL` environment variable:** If the `--model` flag is not used,
the CLI will use the model specified in the `GEMINI_MODEL` environment
variable.
3. **`model.name` in `settings.json`:** If neither of the above are set, the
model specified in the `model.name` property of your `settings.json` file
will be used.
4. **Default model:** If none of the above are set, the default model will be
used. The default model is `auto`
-62
View File
@@ -1,62 +0,0 @@
# Gemini CLI model selection (`/model` command)
Select your Gemini CLI model. The `/model` command lets you configure the model
used by Gemini CLI, giving you more control over your results. Use **Pro**
models for complex tasks and reasoning, **Flash** models for high speed results,
or the (recommended) **Auto** setting to choose the best model for your tasks.
> **Note:** The `/model` command (and the `--model` flag) does not override the
> model used by sub-agents. Consequently, even when using the `/model` flag you
> may see other models used in your model usage reports.
## How to use the `/model` command
Use the following command in Gemini CLI:
```
/model
```
Running this command will open a dialog with your options:
| Option | Description | Models |
| ----------------- | -------------------------------------------------------------- | ---------------------------------------------------------------------- |
| Auto (Gemini 3) | Let the system choose the best Gemini 3 model for your task. | gemini-3-pro-preview (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](../get-started/configuration.md).
Changes to these settings will be applied to all subsequent interactions with
Gemini CLI.
## Best practices for model selection
- **Default to Auto.** For most users, the _Auto_ option model provides a
balance between speed and performance, automatically selecting the correct
model based on the complexity of the task. Example: Developing a web
application could include a mix of complex tasks (building architecture and
scaffolding the project) and simple tasks (generating CSS).
- **Switch to Pro if you aren't getting the results you want.** If you think you
need your model to be a little "smarter," you can manually select Pro. Pro
will provide you with the highest levels of reasoning and creativity. Example:
A complex or multi-stage debugging task.
- **Switch to Flash or Flash-Lite if you need faster results.** If you need a
simple response quickly, Flash or Flash-Lite is the best option. Example:
Converting a JSON object to a YAML string.
+2 -2
View File
@@ -11,7 +11,7 @@ Before using sandboxing, you need to install and set up the Gemini CLI:
npm install -g @google/gemini-cli
```
To verify the installation:
To verify the installation
```bash
gemini --version
@@ -87,7 +87,7 @@ Built-in profiles (set via `SEATBELT_PROFILE` env var):
- `restrictive-open`: Strict restrictions, network allowed
- `restrictive-closed`: Maximum restrictions
### Custom sandbox flags
### Custom Sandbox Flags
For container-based sandboxing, you can inject custom flags into the `docker` or
`podman` command using the `SANDBOX_FLAGS` environment variable. This is useful
-158
View File
@@ -1,158 +0,0 @@
# Session Management
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
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/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 will switch to that project's session history.
## Resuming Sessions
You can resume a previous session to continue the conversation with all prior
context restored.
### From the Command Line
When starting the CLI, you can use the `--resume` (or `-r`) flag:
- **Resume latest:**
```bash
gemini --resume
```
This immediately loads the most recent session.
- **Resume by index:** First, list available sessions (see
[Listing Sessions](#listing-sessions)), then use the index number:
```bash
gemini --resume 1
```
- **Resume by ID:** You can also provide the full session UUID:
```bash
gemini --resume a1b2c3d4-e5f6-7890-abcd-ef1234567890
```
### From the Interactive Interface
While the CLI is running, you can use the `/resume` slash command to open the
**Session Browser**:
```text
/resume
```
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.
## Managing Sessions
### Listing Sessions
To see a list of all available sessions for the current project from the command
line:
```bash
gemini --list-sessions
```
Output example:
```text
Available sessions for this project (3):
1. Fix bug in auth (2 days ago) [a1b2c3d4]
2. Refactor database schema (5 hours ago) [e5f67890]
3. Update documentation (Just now) [abcd1234]
```
### Deleting Sessions
You can remove old or unwanted sessions to free up space or declutter your
history.
**From the Command Line:** Use the `--delete-session` flag with an index or ID:
```bash
gemini --delete-session 2
```
**From the Session Browser:**
1. Open the browser with `/resume`.
2. Navigate to the session you want to remove.
3. Press `x`.
## Configuration
You can configure how Gemini CLI manages your session history in your
`settings.json` file.
### Session Retention
To prevent your history from growing indefinitely, you can enable automatic
cleanup policies.
```json
{
"general": {
"sessionRetention": {
"enabled": true,
"maxAge": "30d", // Keep sessions for 30 days
"maxCount": 50 // Keep the 50 most recent sessions
}
}
}
```
- **`enabled`**: (boolean) Master switch for session cleanup. Default is
`false`.
- **`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 will be deleted.
- **`minRetention`**: (string) Minimum retention period (safety limit). Defaults
to `"1d"`; sessions newer than this period are never deleted by automatic
cleanup.
### Session Limits
You can also limit the length of individual sessions to prevent context windows
from becoming too large and expensive.
```json
{
"model": {
"maxSessionTurns": 100
}
}
```
- **`maxSessionTurns`**: (number) The maximum number of turns (user + model
exchanges) allowed in a single session. Set to `-1` for unlimited (default).
**Behavior when limit is reached:**
- **Interactive Mode:** The CLI shows an informational message and stops
sending requests to the model. You must manually start a new session.
- **Non-Interactive Mode:** The CLI exits with an error.
-131
View File
@@ -1,131 +0,0 @@
# Gemini CLI settings (`/settings` command)
Control your Gemini CLI experience with the `/settings` command. The `/settings`
command opens a dialog to view and edit all your Gemini CLI settings, including
your UI experience, keybindings, and accessibility features.
Your Gemini CLI settings are stored in a `settings.json` file. In addition to
using the `/settings` command, you can also edit them in one of the following
locations:
- **User settings**: `~/.gemini/settings.json`
- **Workspace settings**: `your-project/.gemini/settings.json`
Note: Workspace settings override user settings.
## Settings reference
Here is a list of all the available settings, grouped by category and ordered as
they appear in the UI.
<!-- SETTINGS-AUTOGEN:START -->
### General
| 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
| UI Label | Setting | Description | Default |
| ------------- | --------------- | ------------------------------------------------------ | -------- |
| Output Format | `output.format` | The format of the CLI output. Can be `text` or `json`. | `"text"` |
### UI
| UI Label | Setting | Description | Default |
| ------------------------------ | --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
| 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
| UI Label | Setting | Description | Default |
| -------- | ------------- | ---------------------------- | ------- |
| IDE Mode | `ide.enabled` | Enable IDE integration mode. | `false` |
### Model
| 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` |
### 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` |
| 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` |
| 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 |
| ----------------------------------- | ------------------------------------------------------- | ----------------------------------------------------------------------------------- | ------- |
| 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` |
### Hooks
| UI Label | Setting | Description | Default |
| ------------------ | --------------------- | ------------------------------------------------ | ------- |
| Hook Notifications | `hooks.notifications` | Show visual indicators when hooks are executing. | `true` |
<!-- SETTINGS-AUTOGEN:END -->
-188
View File
@@ -1,188 +0,0 @@
# 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
self-contained directory that packages instructions and assets into a
discoverable capability.
## Overview
Unlike general context files ([`GEMINI.md`](./gemini-md.md)), which provide
persistent workspace-wide background, Skills represent **on-demand expertise**.
This allows Gemini to maintain a vast library of specialized capabilities—such
as security auditing, cloud deployments, or codebase migrations—without
cluttering the model's immediate context window.
Gemini autonomously decides when to employ a skill based on your request and the
skill's description. When a relevant skill is identified, the model "pulls in"
the full instructions and resources required to complete the task using the
`activate_skill` tool.
## Key Benefits
- **Shared Expertise:** Package complex workflows (like a specific team's PR
review process) into a folder that anyone can use.
- **Repeatable Workflows:** Ensure complex multi-step tasks are performed
consistently by providing a procedural framework.
- **Resource Bundling:** Include scripts, templates, or example data alongside
instructions so the agent has everything it needs.
- **Progressive Disclosure:** Only skill metadata (name and description) is
loaded initially. Detailed instructions and resources are only disclosed when
the model explicitly activates the skill, saving context tokens.
## Skill Discovery Tiers
Gemini CLI discovers skills from three primary locations:
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**.
## Managing Skills
### In an Interactive Session
Use the `/skills` slash command to view and manage available expertise:
- `/skills list` (default): Shows all discovered skills and their status.
- `/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.
_Note: `/skills disable` and `/skills enable` default to the `user` scope. Use
`--scope workspace` to manage workspace-specific settings._
### From the Terminal
The `gemini skills` command provides management utilities:
```bash
# List all discovered skills
gemini skills list
# Install a skill from a Git repository, local directory, or zipped skill file (.skill)
# 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
# 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)
gemini skills install /path/to/skill --scope workspace
# Uninstall a skill by name
gemini skills uninstall my-expertise --scope workspace
# Enable a skill (globally)
gemini skills enable my-expertise
# Disable a skill. Can use --scope to specify workspace or user (defaults to workspace)
gemini skills disable my-expertise --scope workspace
```
## 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
system prompt.
2. **Activation**: When Gemini identifies a task matching a skill's
description, it calls the `activate_skill` tool.
3. **Consent**: You will see a confirmation prompt in the UI detailing the
skill's name, purpose, and the directory path it will gain access to.
4. **Injection**: Upon your approval:
- The `SKILL.md` body and folder structure is added to the conversation
history.
- The skill's directory is added to the agent's allowed file paths, granting
it permission to read any bundled assets.
5. **Execution**: The model proceeds with the specialized expertise active. It
is instructed to prioritize the skill's procedural guidance within reason.
-93
View File
@@ -1,93 +0,0 @@
# System Prompt Override (GEMINI_SYSTEM_MD)
The core system instructions that guide Gemini CLI can be completely replaced
with your own Markdown file. This feature is controlled via the
`GEMINI_SYSTEM_MD` environment variable.
## Overview
The `GEMINI_SYSTEM_MD` variable instructs the CLI to use an external Markdown
file for its system prompt, completely overriding the built-in default. This is
a full replacement, not a merge. If you use a custom file, none of the original
core instructions will apply unless you include them yourself.
This feature is intended for advanced users who need to enforce strict,
project-specific behavior or create a customized persona.
> Tip: You can export the current default system prompt to a file first, review
> it, and then selectively modify or replace it (see
> [“Export the default prompt”](#export-the-default-prompt-recommended)).
## How to enable
You can set the environment variable temporarily in your shell, or persist it
via a `.gemini/.env` file. See
[Persisting Environment Variables](../get-started/authentication.md#persisting-environment-variables).
- Use the project default path (`.gemini/system.md`):
- `GEMINI_SYSTEM_MD=true` or `GEMINI_SYSTEM_MD=1`
- The CLI reads `./.gemini/system.md` (relative to your current project
directory).
- Use a custom file path:
- `GEMINI_SYSTEM_MD=/absolute/path/to/my-system.md`
- Relative paths are supported and resolved from the current working
directory.
- Tilde expansion is supported (e.g., `~/my-system.md`).
- Disable the override (use builtin prompt):
- `GEMINI_SYSTEM_MD=false` or `GEMINI_SYSTEM_MD=0` or unset the variable.
If the override is enabled but the target file does not exist, the CLI will
error with: `missing system prompt file '<path>'`.
## Quick examples
- Oneoff session using a project file:
- `GEMINI_SYSTEM_MD=1 gemini`
- Persist for a project using `.gemini/.env`:
- Create `.gemini/system.md`, then add to `.gemini/.env`:
- `GEMINI_SYSTEM_MD=1`
- Use a custom file under your home directory:
- `GEMINI_SYSTEM_MD=~/prompts/SYSTEM.md gemini`
## UI indicator
When `GEMINI_SYSTEM_MD` is active, the CLI shows a `|⌐■_■|` indicator in the UI
to signal custom systemprompt mode.
## Export the default prompt (recommended)
Before overriding, export the current default prompt so you can review required
safety and workflow rules.
- Write the builtin prompt to the project default path:
- `GEMINI_WRITE_SYSTEM_MD=1 gemini`
- Or write to a custom path:
- `GEMINI_WRITE_SYSTEM_MD=~/prompts/DEFAULT_SYSTEM.md gemini`
This creates the file and writes the current builtin system prompt to it.
## Best practices: SYSTEM.md vs GEMINI.md
- SYSTEM.md (firmware):
- Nonnegotiable operational rules: safety, tooluse protocols, approvals, and
mechanics that keep the CLI reliable.
- Stable across tasks and projects (or per project when needed).
- GEMINI.md (strategy):
- Persona, goals, methodologies, and project/domain context.
- Evolves per task; relies on SYSTEM.md for safe execution.
Keep SYSTEM.md minimal but complete for safety and tool operation. Keep
GEMINI.md focused on highlevel guidance and project specifics.
## Troubleshooting
- Error: `missing system prompt file '…'`
- Ensure the referenced path exists and is readable.
- For `GEMINI_SYSTEM_MD=1|true`, create `./.gemini/system.md` in your project.
- Override not taking effect
- Confirm the variable is loaded (use `.gemini/.env` or export in your shell).
- Paths are resolved from the current working directory; try an absolute path.
- Restore defaults
- Unset `GEMINI_SYSTEM_MD` or set it to `0`/`false`.
+144 -519
View File
@@ -3,70 +3,47 @@
Learn how to enable and setup OpenTelemetry for Gemini CLI.
- [Observability with OpenTelemetry](#observability-with-opentelemetry)
- [Key benefits](#key-benefits)
- [OpenTelemetry integration](#opentelemetry-integration)
- [Key Benefits](#key-benefits)
- [OpenTelemetry Integration](#opentelemetry-integration)
- [Configuration](#configuration)
- [Google Cloud telemetry](#google-cloud-telemetry)
- [Google Cloud Telemetry](#google-cloud-telemetry)
- [Prerequisites](#prerequisites)
- [Authenticating with CLI Credentials](#authenticating-with-cli-credentials)
- [Direct export (recommended)](#direct-export-recommended)
- [Collector-based export (advanced)](#collector-based-export-advanced)
- [Monitoring Dashboards](#monitoring-dashboards)
- [Local telemetry](#local-telemetry)
- [File-based output (recommended)](#file-based-output-recommended)
- [Collector-based export (advanced)](#collector-based-export-advanced-1)
- [Logs and metrics](#logs-and-metrics)
- [Direct Export (Recommended)](#direct-export-recommended)
- [Collector-Based Export (Advanced)](#collector-based-export-advanced)
- [Local Telemetry](#local-telemetry)
- [File-based Output (Recommended)](#file-based-output-recommended)
- [Collector-Based Export (Advanced)](#collector-based-export-advanced-1)
- [Logs and Metrics](#logs-and-metrics)
- [Logs](#logs)
- [Sessions](#sessions)
- [Tools](#tools)
- [Files](#files)
- [API](#api)
- [Model routing](#model-routing)
- [Chat and streaming](#chat-and-streaming)
- [Resilience](#resilience)
- [Extensions](#extensions)
- [Agent runs](#agent-runs)
- [IDE](#ide)
- [UI](#ui)
- [Metrics](#metrics)
- [Custom](#custom)
- [Sessions](#sessions-1)
- [Tools](#tools-1)
- [API](#api-1)
- [Token usage](#token-usage)
- [Files](#files-1)
- [Chat and streaming](#chat-and-streaming-1)
- [Model routing](#model-routing-1)
- [Agent runs](#agent-runs-1)
- [UI](#ui-1)
- [Performance](#performance)
- [GenAI semantic convention](#genai-semantic-convention)
- [GenAI Semantic Convention](#genai-semantic-convention)
## Key benefits
## Key Benefits
- **🔍 Usage analytics**: Understand interaction patterns and feature adoption
- **🔍 Usage Analytics**: Understand interaction patterns and feature adoption
across your team
- **⚡ Performance monitoring**: Track response times, token consumption, and
- **⚡ Performance Monitoring**: Track response times, token consumption, and
resource utilization
- **🐛 Real-time debugging**: Identify bottlenecks, failures, and error patterns
- **🐛 Real-time Debugging**: Identify bottlenecks, failures, and error patterns
as they occur
- **📊 Workflow optimization**: Make informed decisions to improve
- **📊 Workflow Optimization**: Make informed decisions to improve
configurations and processes
- **🏢 Enterprise governance**: Monitor usage across teams, track costs, ensure
- **🏢 Enterprise Governance**: Monitor usage across teams, track costs, ensure
compliance, and integrate with existing monitoring infrastructure
## OpenTelemetry integration
## OpenTelemetry Integration
Built on **[OpenTelemetry]** — the vendor-neutral, industry-standard
observability framework — Gemini CLI's observability system provides:
- **Universal compatibility**: Export to any OpenTelemetry backend (Google
- **Universal Compatibility**: Export to any OpenTelemetry backend (Google
Cloud, Jaeger, Prometheus, Datadog, etc.)
- **Standardized data**: Use consistent formats and collection methods across
- **Standardized Data**: Use consistent formats and collection methods across
your toolchain
- **Future-proof integration**: Connect with existing and future observability
- **Future-Proof Integration**: Connect with existing and future observability
infrastructure
- **No vendor lock-in**: Switch between backends without changing your
- **No Vendor Lock-in**: Switch between backends without changing your
instrumentation
[OpenTelemetry]: https://opentelemetry.io/
@@ -74,27 +51,26 @@ observability framework — Gemini CLI's observability system provides:
## Configuration
All telemetry behavior is controlled through your `.gemini/settings.json` file.
Environment variables can be used to override the settings in the file.
These settings can be overridden by environment variables or CLI flags.
| Setting | Environment Variable | Description | Values | Default |
| -------------- | -------------------------------- | --------------------------------------------------- | ----------------- | ----------------------- |
| `enabled` | `GEMINI_TELEMETRY_ENABLED` | Enable or disable telemetry | `true`/`false` | `false` |
| `target` | `GEMINI_TELEMETRY_TARGET` | Where to send telemetry data | `"gcp"`/`"local"` | `"local"` |
| `otlpEndpoint` | `GEMINI_TELEMETRY_OTLP_ENDPOINT` | OTLP collector endpoint | URL string | `http://localhost:4317` |
| `otlpProtocol` | `GEMINI_TELEMETRY_OTLP_PROTOCOL` | OTLP transport protocol | `"grpc"`/`"http"` | `"grpc"` |
| `outfile` | `GEMINI_TELEMETRY_OUTFILE` | Save telemetry to file (overrides `otlpEndpoint`) | file path | - |
| `logPrompts` | `GEMINI_TELEMETRY_LOG_PROMPTS` | Include prompts in telemetry logs | `true`/`false` | `true` |
| `useCollector` | `GEMINI_TELEMETRY_USE_COLLECTOR` | Use external OTLP collector (advanced) | `true`/`false` | `false` |
| `useCliAuth` | `GEMINI_TELEMETRY_USE_CLI_AUTH` | Use CLI credentials for telemetry (GCP target only) | `true`/`false` | `false` |
| Setting | Environment Variable | CLI Flag | Description | Values | Default |
| -------------- | -------------------------------- | -------------------------------------------------------- | ------------------------------------------------- | ----------------- | ----------------------- |
| `enabled` | `GEMINI_TELEMETRY_ENABLED` | `--telemetry` / `--no-telemetry` | Enable or disable telemetry | `true`/`false` | `false` |
| `target` | `GEMINI_TELEMETRY_TARGET` | `--telemetry-target <local\|gcp>` | Where to send telemetry data | `"gcp"`/`"local"` | `"local"` |
| `otlpEndpoint` | `GEMINI_TELEMETRY_OTLP_ENDPOINT` | `--telemetry-otlp-endpoint <URL>` | OTLP collector endpoint | URL string | `http://localhost:4317` |
| `otlpProtocol` | `GEMINI_TELEMETRY_OTLP_PROTOCOL` | `--telemetry-otlp-protocol <grpc\|http>` | OTLP transport protocol | `"grpc"`/`"http"` | `"grpc"` |
| `outfile` | `GEMINI_TELEMETRY_OUTFILE` | `--telemetry-outfile <path>` | Save telemetry to file (overrides `otlpEndpoint`) | file path | - |
| `logPrompts` | `GEMINI_TELEMETRY_LOG_PROMPTS` | `--telemetry-log-prompts` / `--no-telemetry-log-prompts` | Include prompts in telemetry logs | `true`/`false` | `true` |
| `useCollector` | `GEMINI_TELEMETRY_USE_COLLECTOR` | - | Use external OTLP collector (advanced) | `true`/`false` | `false` |
**Note on boolean environment variables:** For the boolean settings (`enabled`,
`logPrompts`, `useCollector`), setting the corresponding environment variable to
`true` or `1` will enable the feature. Any other value will disable it.
For detailed information about all configuration options, see the
[Configuration guide](../get-started/configuration.md).
[Configuration Guide](../get-started/configuration.md).
## Google Cloud telemetry
## Google Cloud Telemetry
### Prerequisites
@@ -133,35 +109,7 @@ Before using either method below, complete these steps:
--project="$OTLP_GOOGLE_CLOUD_PROJECT"
```
### Authenticating with CLI Credentials
By default, the telemetry collector for Google Cloud uses Application Default
Credentials (ADC). However, you can configure it to use the same OAuth
credentials that you use to log in to the Gemini CLI. This is useful in
environments where you don't have ADC set up.
To enable this, set the `useCliAuth` property in your `telemetry` settings to
`true`:
```json
{
"telemetry": {
"enabled": true,
"target": "gcp",
"useCliAuth": true
}
}
```
**Important:**
- This setting requires the use of **Direct Export** (in-process exporters).
- It **cannot** be used with `useCollector: true`. If you enable both, telemetry
will be disabled and an error will be logged.
- The CLI will automatically use your credentials to authenticate with Google
Cloud Trace, Metrics, and Logging APIs.
### Direct export (recommended)
### Direct Export (Recommended)
Sends telemetry directly to Google Cloud services. No collector needed.
@@ -181,7 +129,7 @@ Sends telemetry directly to Google Cloud services. No collector needed.
- Metrics: https://console.cloud.google.com/monitoring/metrics-explorer
- Traces: https://console.cloud.google.com/traces/list
### Collector-based export (advanced)
### Collector-Based Export (Advanced)
For custom processing, filtering, or routing, use an OpenTelemetry collector to
forward data to Google Cloud.
@@ -215,29 +163,11 @@ forward data to Google Cloud.
- Open `~/.gemini/tmp/<projectHash>/otel/collector-gcp.log` to view local
collector logs.
### Monitoring Dashboards
Gemini CLI provides a pre-configured
[Google Cloud Monitoring](https://cloud.google.com/monitoring) dashboard to
visualize your telemetry.
This dashboard can be found under **Google Cloud Monitoring Dashboard
Templates** as "**Gemini CLI Monitoring**".
![Gemini CLI Monitoring Dashboard Overview](/docs/assets/monitoring-dashboard-overview.png)
![Gemini CLI Monitoring Dashboard Metrics](/docs/assets/monitoring-dashboard-metrics.png)
![Gemini CLI Monitoring Dashboard Logs](/docs/assets/monitoring-dashboard-logs.png)
To learn more, check out this blog post:
[Instant insights: Gemini CLIs new pre-configured monitoring dashboards](https://cloud.google.com/blog/topics/developers-practitioners/instant-insights-gemini-clis-new-pre-configured-monitoring-dashboards/).
## Local telemetry
## Local Telemetry
For local development and debugging, you can capture telemetry data locally:
### File-based output (recommended)
### File-based Output (Recommended)
1. Enable telemetry in your `.gemini/settings.json`:
```json
@@ -253,7 +183,7 @@ For local development and debugging, you can capture telemetry data locally:
2. Run Gemini CLI and send prompts.
3. View logs and metrics in the specified file (e.g., `.gemini/telemetry.log`).
### Collector-based export (advanced)
### Collector-Based Export (Advanced)
1. Run the automation script:
```bash
@@ -269,25 +199,21 @@ 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 and metrics
## Logs and Metrics
The following section describes the structure of logs and metrics generated for
Gemini CLI.
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.
The `session.id`, `installation.id`, and `user.email` are included as common
attributes on all logs and metrics.
### Logs
Logs are timestamped records of specific events. The following events are logged
for Gemini CLI, grouped by category.
for Gemini CLI:
#### Sessions
Captures startup configuration and user prompt submissions.
- `gemini_cli.config`: Emitted once at startup with the CLI configuration.
- `gemini_cli.config`: This event occurs once at startup with the CLI's
configuration.
- **Attributes**:
- `model` (string)
- `embedding_model` (string)
@@ -296,47 +222,81 @@ Captures startup configuration and user prompt submissions.
- `approval_mode` (string)
- `api_key_enabled` (boolean)
- `vertex_ai_enabled` (boolean)
- `log_user_prompts_enabled` (boolean)
- `code_assist_enabled` (boolean)
- `log_prompts_enabled` (boolean)
- `file_filtering_respect_git_ignore` (boolean)
- `debug_mode` (boolean)
- `mcp_servers` (string)
- `mcp_servers_count` (int)
- `extensions` (string)
- `extension_ids` (string)
- `extension_count` (int)
- `mcp_tools` (string, if applicable)
- `mcp_tools_count` (int, if applicable)
- `output_format` ("text", "json", or "stream-json")
- `output_format` (string: "text", "json", or "stream-json")
- `gemini_cli.user_prompt`: Emitted when a user submits a prompt.
- `gemini_cli.user_prompt`: This event occurs when a user submits a prompt.
- **Attributes**:
- `prompt_length` (int)
- `prompt_id` (string)
- `prompt` (string; excluded if `telemetry.logPrompts` is `false`)
- `prompt` (string, this attribute is excluded if `log_prompts_enabled` is
configured to be `false`)
- `auth_type` (string)
#### Tools
Captures tool executions, output truncation, and Edit behavior.
- `gemini_cli.tool_call`: Emitted for each tool (function) call.
- `gemini_cli.tool_call`: This event occurs for each function call.
- **Attributes**:
- `function_name`
- `function_args`
- `duration_ms`
- `success` (boolean)
- `decision` ("accept", "reject", "auto_accept", or "modify", if applicable)
- `decision` (string: "accept", "reject", "auto_accept", or "modify", if
applicable)
- `error` (if applicable)
- `error_type` (if applicable)
- `prompt_id` (string)
- `tool_type` ("native" or "mcp")
- `mcp_server_name` (string, if applicable)
- `extension_name` (string, if applicable)
- `extension_id` (string, if applicable)
- `content_length` (int, if applicable)
- `metadata` (if applicable)
- `metadata` (if applicable, dictionary of string -> any)
- `gemini_cli.tool_output_truncated`: Output of a tool call was truncated.
- `gemini_cli.file_operation`: This event occurs for each file operation.
- **Attributes**:
- `tool_name` (string)
- `operation` (string: "create", "read", "update")
- `lines` (int, if applicable)
- `mimetype` (string, if applicable)
- `extension` (string, if applicable)
- `programming_language` (string, if applicable)
- `diff_stat` (json string, if applicable): A JSON string with the following
members:
- `ai_added_lines` (int)
- `ai_removed_lines` (int)
- `user_added_lines` (int)
- `user_removed_lines` (int)
- `gemini_cli.api_request`: This event occurs when making a request to Gemini
API.
- **Attributes**:
- `model`
- `request_text` (if applicable)
- `gemini_cli.api_error`: This event occurs if the API request fails.
- **Attributes**:
- `model`
- `error`
- `error_type`
- `status_code`
- `duration_ms`
- `auth_type`
- `gemini_cli.api_response`: This event occurs upon receiving a response from
Gemini API.
- **Attributes**:
- `model`
- `status_code`
- `duration_ms`
- `error` (optional)
- `input_token_count`
- `output_token_count`
- `cached_content_token_count`
- `thoughts_token_count`
- `tool_token_count`
- `response_text` (if applicable)
- `auth_type`
- `gemini_cli.tool_output_truncated`: This event occurs when the output of a
tool call is too large and gets truncated.
- **Attributes**:
- `tool_name` (string)
- `original_content_length` (int)
@@ -345,226 +305,32 @@ Captures tool executions, output truncation, and Edit behavior.
- `lines` (int)
- `prompt_id` (string)
- `gemini_cli.edit_strategy`: Edit strategy chosen.
- `gemini_cli.malformed_json_response`: This event occurs when a `generateJson`
response from Gemini API cannot be parsed as a json.
- **Attributes**:
- `strategy` (string)
- `model`
- `gemini_cli.edit_correction`: Edit correction result.
- `gemini_cli.flash_fallback`: This event occurs when Gemini CLI switches to
flash as fallback.
- **Attributes**:
- `correction` ("success" | "failure")
- `auth_type`
- `gen_ai.client.inference.operation.details`: This event provides detailed
information about the GenAI operation, aligned with [OpenTelemetry GenAI
semantic conventions for events].
- **Attributes**:
- `gen_ai.request.model` (string)
- `gen_ai.provider.name` (string)
- `gen_ai.operation.name` (string)
- `gen_ai.input.messages` (json string)
- `gen_ai.output.messages` (json string)
- `gen_ai.response.finish_reasons` (array of strings)
- `gen_ai.usage.input_tokens` (int)
- `gen_ai.usage.output_tokens` (int)
- `gen_ai.request.temperature` (float)
- `gen_ai.request.top_p` (float)
- `gen_ai.request.top_k` (int)
- `gen_ai.request.max_tokens` (int)
- `gen_ai.system_instructions` (json string)
- `server.address` (string)
- `server.port` (int)
#### Files
Tracks file operations performed by tools.
- `gemini_cli.file_operation`: Emitted for each file operation.
- **Attributes**:
- `tool_name` (string)
- `operation` ("create" | "read" | "update")
- `lines` (int, optional)
- `mimetype` (string, optional)
- `extension` (string, optional)
- `programming_language` (string, optional)
#### API
Captures Gemini API requests, responses, and errors.
- `gemini_cli.api_request`: Request sent to Gemini API.
- **Attributes**:
- `model` (string)
- `prompt_id` (string)
- `request_text` (string, optional)
- `gemini_cli.api_response`: Response received from Gemini API.
- **Attributes**:
- `model` (string)
- `status_code` (int|string)
- `duration_ms` (int)
- `input_token_count` (int)
- `output_token_count` (int)
- `cached_content_token_count` (int)
- `thoughts_token_count` (int)
- `tool_token_count` (int)
- `total_token_count` (int)
- `response_text` (string, optional)
- `prompt_id` (string)
- `auth_type` (string)
- `finish_reasons` (array of strings)
- `gemini_cli.api_error`: API request failed.
- **Attributes**:
- `model` (string)
- `error` (string)
- `error_type` (string)
- `status_code` (int|string)
- `duration_ms` (int)
- `prompt_id` (string)
- `auth_type` (string)
- `gemini_cli.malformed_json_response`: `generateJson` response could not be
parsed.
- **Attributes**:
- `model` (string)
#### Model routing
- `gemini_cli.slash_command`: A slash command was executed.
- `gemini_cli.slash_command`: This event occurs when a user executes a slash
command.
- **Attributes**:
- `command` (string)
- `subcommand` (string, optional)
- `status` ("success" | "error")
- `subcommand` (string, if applicable)
- `gemini_cli.slash_command.model`: Model was selected via slash command.
- **Attributes**:
- `model_name` (string)
- `gemini_cli.model_routing`: Model router made a decision.
- **Attributes**:
- `decision_model` (string)
- `decision_source` (string)
- `routing_latency_ms` (int)
- `reasoning` (string, optional)
- `failed` (boolean)
- `error_message` (string, optional)
#### Chat and streaming
- `gemini_cli.chat_compression`: Chat context was compressed.
- **Attributes**:
- `tokens_before` (int)
- `tokens_after` (int)
- `gemini_cli.chat.invalid_chunk`: Invalid chunk received from a stream.
- **Attributes**:
- `error.message` (string, optional)
- `gemini_cli.chat.content_retry`: Retry triggered due to a content error.
- **Attributes**:
- `attempt_number` (int)
- `error_type` (string)
- `retry_delay_ms` (int)
- `model` (string)
- `gemini_cli.chat.content_retry_failure`: All content retries failed.
- **Attributes**:
- `total_attempts` (int)
- `final_error_type` (string)
- `total_duration_ms` (int, optional)
- `model` (string)
- `gemini_cli.conversation_finished`: Conversation session ended.
- **Attributes**:
- `approvalMode` (string)
- `turnCount` (int)
- `gemini_cli.next_speaker_check`: Next speaker determination.
- **Attributes**:
- `prompt_id` (string)
- `finish_reason` (string)
- `result` (string)
#### Resilience
Records fallback mechanisms for models and network operations.
- `gemini_cli.flash_fallback`: Switched to a flash model as fallback.
- **Attributes**:
- `auth_type` (string)
- `gemini_cli.ripgrep_fallback`: Switched to grep as fallback for file search.
- **Attributes**:
- `error` (string, optional)
- `gemini_cli.web_fetch_fallback_attempt`: Attempted web-fetch fallback.
- **Attributes**:
- `reason` ("private_ip" | "primary_failed")
#### Extensions
Tracks extension lifecycle and settings changes.
- `gemini_cli.extension_install`: An extension was installed.
- `gemini_cli.extension_enable`: This event occurs when an extension is enabled
- `gemini_cli.extension_install`: This event occurs when an extension is
installed
- **Attributes**:
- `extension_name` (string)
- `extension_version` (string)
- `extension_source` (string)
- `status` (string)
- `gemini_cli.extension_uninstall`: An extension was uninstalled.
- **Attributes**:
- `extension_name` (string)
- `status` (string)
- `gemini_cli.extension_enable`: An extension was enabled.
- **Attributes**:
- `extension_name` (string)
- `setting_scope` (string)
- `gemini_cli.extension_disable`: An extension was disabled.
- **Attributes**:
- `extension_name` (string)
- `setting_scope` (string)
- `gemini_cli.extension_update`: An extension was updated.
- **Attributes**:
- `extension_name` (string)
- `extension_version` (string)
- `extension_previous_version` (string)
- `extension_source` (string)
- `status` (string)
#### Agent runs
- `gemini_cli.agent.start`: Agent run started.
- **Attributes**:
- `agent_id` (string)
- `agent_name` (string)
- `gemini_cli.agent.finish`: Agent run finished.
- **Attributes**:
- `agent_id` (string)
- `agent_name` (string)
- `duration_ms` (int)
- `turn_count` (int)
- `terminate_reason` (string)
#### IDE
Captures IDE connectivity and conversation lifecycle events.
- `gemini_cli.ide_connection`: IDE companion connection.
- **Attributes**:
- `connection_type` (string)
#### UI
Tracks terminal rendering issues and related signals.
- `kitty_sequence_overflow`: Terminal kitty control sequence overflow.
- **Attributes**:
- `sequence_length` (int)
- `truncated_sequence` (string)
- `gemini_cli.extension_uninstall`: This event occurs when an extension is
uninstalled
### Metrics
@@ -572,31 +338,27 @@ Metrics are numerical measurements of behavior over time.
#### Custom
##### Sessions
Counts CLI sessions at startup.
- `gemini_cli.session.count` (Counter, Int): Incremented once per CLI startup.
##### Tools
Measures tool usage and latency.
- `gemini_cli.tool.call.count` (Counter, Int): Counts tool calls.
- **Attributes**:
- `function_name`
- `success` (boolean)
- `decision` (string: "accept", "reject", "modify", or "auto_accept", if
applicable)
- `tool_type` (string: "mcp" or "native", if applicable)
- `decision` (string: "accept", "reject", or "modify", if applicable)
- `tool_type` (string: "mcp", or "native", if applicable)
- `model_added_lines` (Int, optional): Lines added by model in the proposed
changes, if applicable
- `model_removed_lines` (Int, optional): Lines removed by model in the
proposed changes, if applicable
- `user_added_lines` (Int, optional): Lines added by user edits after model
proposal, if applicable
- `user_removed_lines` (Int, optional): Lines removed by user edits after
model proposal, if applicable
- `gemini_cli.tool.call.latency` (Histogram, ms): Measures tool call latency.
- **Attributes**:
- `function_name`
##### API
Tracks API request volume and latency.
- `decision` (string: "accept", "reject", or "modify", if applicable)
- `gemini_cli.api.request.count` (Counter, Int): Counts all API requests.
- **Attributes**:
@@ -608,169 +370,34 @@ Tracks API request volume and latency.
latency.
- **Attributes**:
- `model`
- Note: Overlaps with `gen_ai.client.operation.duration` (GenAI conventions).
- **Note**: This metric overlaps with `gen_ai.client.operation.duration` below
that's compliant with GenAI Semantic Conventions.
##### Token usage
Tracks tokens used by model and type.
- `gemini_cli.token.usage` (Counter, Int): Counts tokens used.
- `gemini_cli.token.usage` (Counter, Int): Counts the number of tokens used.
- **Attributes**:
- `model`
- `type` ("input", "output", "thought", "cache", or "tool")
- Note: Overlaps with `gen_ai.client.token.usage` for `input`/`output`.
##### Files
Counts file operations with basic context.
- `type` (string: "input", "output", "thought", "cache", or "tool")
- **Note**: This metric overlaps with `gen_ai.client.token.usage` below for
`input`/`output` token types that's compliant with GenAI Semantic
Conventions.
- `gemini_cli.file.operation.count` (Counter, Int): Counts file operations.
- **Attributes**:
- `operation` ("create", "read", "update")
- `lines` (Int, optional)
- `mimetype` (string, optional)
- `extension` (string, optional)
- `programming_language` (string, optional)
- `gemini_cli.lines.changed` (Counter, Int): Number of lines changed (from file
diffs).
- **Attributes**:
- `function_name`
- `type` ("added" or "removed")
##### Chat and streaming
Resilience counters for compression, invalid chunks, and retries.
- `operation` (string: "create", "read", "update"): The type of file
operation.
- `lines` (Int, if applicable): Number of lines in the file.
- `mimetype` (string, if applicable): Mimetype of the file.
- `extension` (string, if applicable): File extension of the file.
- `programming_language` (string, if applicable): The programming language
of the file.
- `gemini_cli.chat_compression` (Counter, Int): Counts chat compression
operations.
operations
- **Attributes**:
- `tokens_before` (Int)
- `tokens_after` (Int)
- `tokens_before`: (Int): Number of tokens in context prior to compression
- `tokens_after`: (Int): Number of tokens in context after compression
- `gemini_cli.chat.invalid_chunk.count` (Counter, Int): Counts invalid chunks
from streams.
- `gemini_cli.chat.content_retry.count` (Counter, Int): Counts retries due to
content errors.
- `gemini_cli.chat.content_retry_failure.count` (Counter, Int): Counts requests
where all content retries failed.
##### Model routing
Routing latency/failures and slash-command selections.
- `gemini_cli.slash_command.model.call_count` (Counter, Int): Counts model
selections via slash command.
- **Attributes**:
- `slash_command.model.model_name` (string)
- `gemini_cli.model_routing.latency` (Histogram, ms): Model routing decision
latency.
- **Attributes**:
- `routing.decision_model` (string)
- `routing.decision_source` (string)
- `gemini_cli.model_routing.failure.count` (Counter, Int): Counts model routing
failures.
- **Attributes**:
- `routing.decision_source` (string)
- `routing.error_message` (string)
##### Agent runs
Agent lifecycle metrics: runs, durations, and turns.
- `gemini_cli.agent.run.count` (Counter, Int): Counts agent runs.
- **Attributes**:
- `agent_name` (string)
- `terminate_reason` (string)
- `gemini_cli.agent.duration` (Histogram, ms): Agent run durations.
- **Attributes**:
- `agent_name` (string)
- `gemini_cli.agent.turns` (Histogram, turns): Turns taken per agent run.
- **Attributes**:
- `agent_name` (string)
##### UI
UI stability signals such as flicker count.
- `gemini_cli.ui.flicker.count` (Counter, Int): Counts UI frames that flicker
(render taller than terminal).
##### Performance
Optional performance monitoring for startup, CPU/memory, and phase timing.
- `gemini_cli.startup.duration` (Histogram, ms): CLI startup time by phase.
- **Attributes**:
- `phase` (string)
- `details` (map, optional)
- `gemini_cli.memory.usage` (Histogram, bytes): Memory usage.
- **Attributes**:
- `memory_type` ("heap_used", "heap_total", "external", "rss")
- `component` (string, optional)
- `gemini_cli.cpu.usage` (Histogram, percent): CPU usage percentage.
- **Attributes**:
- `component` (string, optional)
- `gemini_cli.tool.queue.depth` (Histogram, count): Number of tools in the
execution queue.
- `gemini_cli.tool.execution.breakdown` (Histogram, ms): Tool time by phase.
- **Attributes**:
- `function_name` (string)
- `phase` ("validation", "preparation", "execution", "result_processing")
- `gemini_cli.api.request.breakdown` (Histogram, ms): API request time by phase.
- **Attributes**:
- `model` (string)
- `phase` ("request_preparation", "network_latency", "response_processing",
"token_processing")
- `gemini_cli.token.efficiency` (Histogram, ratio): Token efficiency metrics.
- **Attributes**:
- `model` (string)
- `metric` (string)
- `context` (string, optional)
- `gemini_cli.performance.score` (Histogram, score): Composite performance
score.
- **Attributes**:
- `category` (string)
- `baseline` (number, optional)
- `gemini_cli.performance.regression` (Counter, Int): Regression detection
events.
- **Attributes**:
- `metric` (string)
- `severity` ("low", "medium", "high")
- `current_value` (number)
- `baseline_value` (number)
- `gemini_cli.performance.regression.percentage_change` (Histogram, percent):
Percent change from baseline when regression detected.
- **Attributes**:
- `metric` (string)
- `severity` ("low", "medium", "high")
- `current_value` (number)
- `baseline_value` (number)
- `gemini_cli.performance.baseline.comparison` (Histogram, percent): Comparison
to baseline.
- **Attributes**:
- `metric` (string)
- `category` (string)
- `current_value` (number)
- `baseline_value` (number)
#### GenAI semantic convention
#### GenAI Semantic Convention
The following metrics comply with [OpenTelemetry GenAI semantic conventions] for
standardized observability across GenAI applications:
@@ -807,5 +434,3 @@ standardized observability across GenAI applications:
[OpenTelemetry GenAI semantic conventions]:
https://github.com/open-telemetry/semantic-conventions/blob/main/docs/gen-ai/gen-ai-metrics.md
[OpenTelemetry GenAI semantic conventions for events]:
https://github.com/open-telemetry/semantic-conventions/blob/8b4f210f43136e57c1f6f47292eb6d38e3bf30bb/docs/gen-ai/gen-ai-events.md
+16 -19
View File
@@ -4,19 +4,19 @@ Gemini CLI supports a variety of themes to customize its color scheme and
appearance. You can change the theme to suit your preferences via the `/theme`
command or `"theme":` configuration setting.
## Available themes
## Available Themes
Gemini CLI comes with a selection of pre-defined themes, which you can list
using the `/theme` command within Gemini CLI:
- **Dark themes:**
- **Dark Themes:**
- `ANSI`
- `Atom One`
- `Ayu`
- `Default`
- `Dracula`
- `GitHub`
- **Light themes:**
- **Light Themes:**
- `ANSI Light`
- `Ayu Light`
- `Default Light`
@@ -24,7 +24,7 @@ using the `/theme` command within Gemini CLI:
- `Google Code`
- `Xcode`
### Changing themes
### Changing Themes
1. Enter `/theme` into Gemini CLI.
2. A dialog or selection prompt appears, listing the available themes.
@@ -36,7 +36,7 @@ using the `/theme` command within Gemini CLI:
by a file path), you must remove the `"theme"` setting from the file before you
can change the theme using the `/theme` command.
### Theme persistence
### Theme Persistence
Selected themes are saved in Gemini CLI's
[configuration](../get-started/configuration.md) so your preference is
@@ -44,13 +44,13 @@ remembered across sessions.
---
## Custom color themes
## Custom Color Themes
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
### 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
@@ -86,13 +86,9 @@ color keys. For example:
- `Gray`
- `DiffAdded` (optional, for added lines in diffs)
- `DiffRemoved` (optional, for removed lines in diffs)
- `DiffModified` (optional, for modified 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:**
**Required Properties:**
- `name` (must match the key in the `customThemes` object and be a string)
- `type` (must be the string `"custom"`)
@@ -116,7 +112,7 @@ for a full list of supported names.
You can define multiple custom themes by adding more entries to the
`customThemes` object.
### Loading themes from a file
### Loading Themes from a File
In addition to defining custom themes in `settings.json`, you can also load a
theme directly from a JSON file by specifying the file path in your
@@ -156,21 +152,22 @@ custom theme defined in `settings.json`.
"Gray": "#ABB2BF",
"DiffAdded": "#A6E3A1",
"DiffRemoved": "#F38BA8",
"DiffModified": "#89B4FA",
"GradientColors": ["#4796E4", "#847ACE", "#C3677F"]
}
```
**Security note:** For your safety, Gemini CLI will only load theme files that
**Security Note:** For your safety, Gemini CLI will only load theme files that
are located within your home directory. If you attempt to load a theme from
outside your home directory, a warning will be displayed and the theme will not
be loaded. This is to prevent loading potentially malicious theme files from
untrusted sources.
### Example custom theme
### Example Custom Theme
<img src="../assets/theme-custom.png" alt="Custom theme example" width="600" />
### Using your custom theme
### Using Your Custom Theme
- Select your custom theme using the `/theme` command in Gemini CLI. Your custom
theme will appear in the theme selection dialog.
@@ -182,7 +179,7 @@ untrusted sources.
---
## Dark themes
## Dark Themes
### ANSI
@@ -208,7 +205,7 @@ untrusted sources.
<img src="/assets/theme-github.png" alt="GitHub theme" width="600">
## Light themes
## Light Themes
### ANSI Light
+1 -1
View File
@@ -1,4 +1,4 @@
# Token caching and cost optimization
# Token Caching and Cost Optimization
Gemini CLI automatically optimizes API costs through token caching when using
API key authentication (Gemini API key or Vertex AI). This feature reuses
+16 -16
View File
@@ -5,7 +5,7 @@ which projects can use the full capabilities of the Gemini CLI. It prevents
potentially malicious code from running by asking you to approve a folder before
the CLI loads any project-specific configurations from it.
## Enabling the feature
## Enabling the Feature
The Trusted Folders feature is **disabled by default**. To use it, you must
first enable it in your settings.
@@ -22,7 +22,7 @@ Add the following to your user `settings.json` file:
}
```
## How it works: The trust dialog
## How It Works: The Trust Dialog
Once the feature is enabled, the first time you run the Gemini CLI from a
folder, a dialog will automatically appear, prompting you to make a choice:
@@ -38,58 +38,58 @@ 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.
## Why trust matters: The impact of an untrusted workspace
## Why Trust Matters: The Impact of an Untrusted Workspace
When a folder is **untrusted**, the Gemini CLI runs in a restricted "safe mode"
to protect you. In this mode, the following features are disabled:
1. **Workspace settings are ignored**: The CLI will **not** load the
1. **Workspace Settings are Ignored**: The CLI will **not** load the
`.gemini/settings.json` file from the project. This prevents the loading of
custom tools and other potentially dangerous configurations.
2. **Environment variables are ignored**: The CLI will **not** load any `.env`
2. **Environment Variables are Ignored**: The CLI will **not** load any `.env`
files from the project.
3. **Extension management is restricted**: You **cannot install, update, or
3. **Extension Management is Restricted**: You **cannot install, update, or
uninstall** extensions.
4. **Tool auto-acceptance is disabled**: You will always be prompted before any
4. **Tool Auto-Acceptance is Disabled**: You will always be prompted before any
tool is run, even if you have auto-acceptance enabled globally.
5. **Automatic memory loading is disabled**: The CLI will not automatically
5. **Automatic Memory Loading is Disabled**: The CLI will not automatically
load files into context from directories specified in local settings.
6. **MCP servers do not connect**: The CLI will not attempt to connect to any
6. **MCP Servers Do Not Connect**: The CLI will not attempt to connect to any
[Model Context Protocol (MCP)](../tools/mcp-server.md) servers.
7. **Custom commands are not loaded**: The CLI will not load any custom
7. **Custom Commands are Not Loaded**: The CLI will not load any custom
commands from .toml files, including both project-specific and global user
commands.
Granting trust to a folder unlocks the full functionality of the Gemini CLI for
that workspace.
## Managing your trust settings
## Managing Your Trust Settings
If you need to change a decision or see all your settings, you have a couple of
options:
- **Change the current folder's trust**: Run the `/permissions` command from
- **Change the Current Folder's Trust**: Run the `/permissions` command from
within the CLI. This will bring up the same interactive dialog, allowing you
to change the trust level for the current folder.
- **View all trust rules**: To see a complete list of all your trusted and
- **View All Trust Rules**: To see a complete list of all your trusted and
untrusted folder rules, you can inspect the contents of the
`~/.gemini/trustedFolders.json` file in your home directory.
## The trust check process (advanced)
## The Trust Check Process (Advanced)
For advanced users, it's helpful to know the exact order of operations for how
trust is determined:
1. **IDE trust signal**: If you are using the
1. **IDE Trust Signal**: If you are using the
[IDE Integration](../ide-integration/index.md), the CLI first asks the IDE
if the workspace is trusted. The IDE's response takes highest priority.
2. **Local trust file**: If the IDE is not connected, the CLI checks the
2. **Local Trust File**: If the IDE is not connected, the CLI checks the
central `~/.gemini/trustedFolders.json` file.
+1 -5
View File
@@ -2,17 +2,13 @@
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
This tutorial demonstrates how to set up a 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.
@@ -1,124 +0,0 @@
# Getting Started with Agent Skills
Agent Skills allow you to extend Gemini CLI with specialized expertise. This
tutorial will guide you through creating your first skill, enabling it, and
using it in a session.
## 1. Enable Agent Skills
Agent Skills are currently an experimental feature and must be enabled in your
settings.
### Via the interactive UI
1. Start a Gemini CLI session by running `gemini`.
2. Type `/settings` to open the interactive settings dialog.
3. Search for "Skills".
4. Toggle **Agent Skills** to `true`.
5. Press `Esc` to save and exit. You may need to restart the CLI for the
changes to take effect.
### Via `settings.json`
Alternatively, you can manually edit your global settings file at
`~/.gemini/settings.json` (create it if it doesn't exist):
```json
{
"experimental": {
"skills": true
}
}
```
## 2. Create Your First Skill
A skill is a directory containing a `SKILL.md` file. Let's create an **API
Auditor** skill that helps you verify if local or remote endpoints are
responding correctly.
1. **Create the skill directory structure:**
```bash
mkdir -p .gemini/skills/api-auditor/scripts
```
2. **Create the `SKILL.md` file:** Create a file at
`.gemini/skills/api-auditor/SKILL.md` with the following content:
```markdown
---
name: api-auditor
description:
Expertise in auditing and testing API endpoints. Use when the user asks to
"check", "test", or "audit" a URL or API.
---
# API Auditor Instructions
You act as a QA engineer specialized in API reliability. When this skill is
active, you MUST:
1. **Audit**: Use the bundled `scripts/audit.js` utility to check the
status of the provided URL.
2. **Report**: Analyze the output (status codes, latency) and explain any
failures in plain English.
3. **Secure**: Remind the user if they are testing a sensitive endpoint
without an `https://` protocol.
```
3. **Create the bundled Node.js script:** Create a file at
`.gemini/skills/api-auditor/scripts/audit.js`. This script will be used by
the agent to perform the actual check:
```javascript
// .gemini/skills/api-auditor/scripts/audit.js
const url = process.argv[2];
if (!url) {
console.error('Usage: node audit.js <url>');
process.exit(1);
}
console.log(`Auditing ${url}...`);
fetch(url, { method: 'HEAD' })
.then((r) => console.log(`Result: Success (Status ${r.status})`))
.catch((e) => console.error(`Result: Failed (${e.message})`));
```
## 3. Verify the Skill is Discovered
Use the `/skills` slash command (or `gemini skills list` from your terminal) to
see if Gemini CLI has found your new skill.
In a Gemini CLI session:
```
/skills list
```
You should see `api-auditor` in the list of available skills.
## 4. Use the Skill in a Chat
Now, let's see the skill in action. Start a new session and ask a question about
an endpoint.
**User:** "Can you audit http://geminili.com"
Gemini will recognize the request matches the `api-auditor` description and will
ask for your permission to activate it.
**Model:** (After calling `activate_skill`) "I've activated the **api-auditor**
skill. I'll run the audit script now..."
Gemini will then use the `run_shell_command` tool to execute your bundled Node
script:
`node .gemini/skills/api-auditor/scripts/audit.js http://geminili.com`
## Next Steps
- Explore [Agent Skills Authoring Guide](../skills.md#creating-a-skill) to learn
about more advanced skill features.
- Learn how to share skills via [Extensions](../../extensions/index.md).
+1 -1
View File
@@ -35,7 +35,7 @@ _PowerShell_
Remove-Item -Path (Join-Path $env:LocalAppData "npm-cache\_npx") -Recurse -Force
```
## Method 2: Using npm (global install)
## Method 2: Using npm (Global Install)
If you installed the CLI globally (e.g., `npm install -g @google/gemini-cli`),
use the `npm uninstall` command with the `-g` flag to remove it.
+1 -3
View File
@@ -1,4 +1,4 @@
# Gemini CLI core
# Gemini CLI Core
Gemini CLI's core package (`packages/core`) is the backend portion of Gemini
CLI, handling communication with the Gemini API, managing tools, and processing
@@ -11,8 +11,6 @@ requests sent from `packages/cli`. For a general overview of Gemini CLI, see the
registered, and used by the core.
- **[Memory Import Processor](./memport.md):** Documentation for the modular
GEMINI.md import feature using @file.md syntax.
- **[Policy Engine](./policy-engine.md):** Use the Policy Engine for
fine-grained control over tool execution.
## Role of the core
+18 -20
View File
@@ -27,21 +27,21 @@ More content here.
@./shared/configuration.md
```
## Supported path formats
## Supported Path Formats
### Relative paths
### Relative Paths
- `@./file.md` - Import from the same directory
- `@../file.md` - Import from parent directory
- `@./components/file.md` - Import from subdirectory
### Absolute paths
### Absolute Paths
- `@/absolute/path/to/file.md` - Import using absolute path
## Examples
### Basic import
### Basic Import
```markdown
# My GEMINI.md
@@ -55,7 +55,7 @@ Welcome to my project!
@./features/overview.md
```
### Nested imports
### Nested Imports
The imported files can themselves contain imports, creating a nested structure:
@@ -73,9 +73,9 @@ The imported files can themselves contain imports, creating a nested structure:
@./shared/title.md
```
## Safety features
## Safety Features
### Circular import detection
### Circular Import Detection
The processor automatically detects and prevents circular imports:
@@ -83,45 +83,43 @@ The processor automatically detects and prevents circular imports:
# file-a.md
@./file-b.md
```
```markdown
# file-b.md
@./file-a.md <!-- This will be detected and prevented -->
```
### File access security
### File Access Security
The `validateImportPath` function ensures that imports are only allowed from
specified directories, preventing access to sensitive files outside the allowed
scope.
### Maximum import depth
### Maximum Import Depth
To prevent infinite recursion, there's a configurable maximum import depth
(default: 5 levels).
## Error handling
## Error Handling
### Missing files
### Missing Files
If a referenced file doesn't exist, the import will fail gracefully with an
error comment in the output.
### File access errors
### File Access Errors
Permission issues or other file system errors are handled gracefully with
appropriate error messages.
## Code region detection
## Code Region Detection
The import processor uses the `marked` library to detect code blocks and inline
code spans, ensuring that `@` imports inside these regions are properly ignored.
This provides robust handling of nested code blocks and complex Markdown
structures.
## Import tree structure
## Import Tree Structure
The processor returns an import tree that shows the hierarchy of imported files,
similar to Claude's `/memory` feature. This helps users debug problems with
@@ -145,7 +143,7 @@ Memory Files
The tree preserves the order that files were imported and shows the complete
import chain for debugging purposes.
## Comparison to Claude Code's `/memory` (`claude.md`) approach
## Comparison to Claude Code's `/memory` (`claude.md`) Approach
Claude Code's `/memory` feature (as seen in `claude.md`) produces a flat, linear
document by concatenating all included files, always marking file boundaries
@@ -156,7 +154,7 @@ for reconstructing the hierarchy if needed.
> [!NOTE] The import tree is mainly for clarity during development and has
> limited relevance to LLM consumption.
## API reference
## API Reference
### `processImports(content, basePath, debugMode?, importState?)`
@@ -227,7 +225,7 @@ directory if no `.git` is found)
## Troubleshooting
### Common issues
### Common Issues
1. **Import not working**: Check that the file exists and the path is correct
2. **Circular import warnings**: Review your import structure for circular
@@ -237,7 +235,7 @@ directory if no `.git` is found)
4. **Path resolution issues**: Use absolute paths if relative paths aren't
resolving correctly
### Debug mode
### Debug Mode
Enable debug mode to see detailed logging of the import process:
-268
View File
@@ -1,268 +0,0 @@
# Policy engine
The Gemini CLI includes a powerful policy engine that provides fine-grained
control over tool execution. It allows users and administrators to define rules
that determine whether a tool call should be allowed, denied, or require user
confirmation.
## Quick start
To create your first policy:
1. **Create the policy directory** if it doesn't exist:
```bash
mkdir -p ~/.gemini/policies
```
2. **Create a new policy file** (e.g., `~/.gemini/policies/my-rules.toml`). You
can use any filename ending in `.toml`; all such files in this directory
will be loaded and combined:
```toml
[[rule]]
toolName = "run_shell_command"
commandPrefix = "git status"
decision = "allow"
priority = 100
```
3. **Run a command** that triggers the policy (e.g., ask Gemini CLI to
`git status`). The tool will now execute automatically without prompting for
confirmation.
## Core concepts
The policy engine operates on a set of rules. Each rule is a combination of
conditions and a resulting decision. When a large language model wants to
execute a tool, the policy engine evaluates all rules to find the
highest-priority rule that matches the tool call.
A rule consists of the following main components:
- **Conditions**: Criteria that a tool call must meet for the rule to apply.
This can include the tool's name, the arguments provided to it, or the current
approval mode.
- **Decision**: The action to take if the rule matches (`allow`, `deny`, or
`ask_user`).
- **Priority**: A number that determines the rule's precedence. Higher numbers
win.
For example, this rule will ask for user confirmation before executing any `git`
command.
```toml
[[rule]]
toolName = "run_shell_command"
commandPrefix = "git "
decision = "ask_user"
priority = 100
```
### Conditions
Conditions are the criteria that a tool call must meet for a rule to apply. The
primary conditions are the tool's name and its arguments.
#### Tool Name
The `toolName` in the rule must match the name of the tool being called.
- **Wildcards**: For Model-hosting-protocol (MCP) servers, you can use a
wildcard. A `toolName` of `my-server__*` will match any tool from the
`my-server` MCP.
#### Arguments pattern
If `argsPattern` is specified, the tool's arguments are converted to a stable
JSON string, which is then tested against the provided regular expression. If
the arguments don't match the pattern, the rule does not apply.
### Decisions
There are three possible decisions a rule can enforce:
- `allow`: The tool call is executed automatically without user interaction.
- `deny`: The tool call is blocked and is not executed.
- `ask_user`: The user is prompted to approve or deny the tool call. (In
non-interactive mode, this is treated as `deny`.)
### Priority system and tiers
The policy engine uses a sophisticated priority system to resolve conflicts when
multiple rules match a single tool call. The core principle is simple: **the
rule with the highest priority wins**.
To provide a clear hierarchy, policies are organized into three tiers. Each tier
has a designated number that forms the base of the final priority calculation.
| Tier | Base | Description |
| :------ | :--- | :------------------------------------------------------------------------- |
| Default | 1 | Built-in policies that ship with the Gemini CLI. |
| User | 2 | Custom policies defined by the user. |
| Admin | 3 | Policies managed by an administrator (e.g., in an enterprise environment). |
Within a TOML policy file, you assign a priority value from **0 to 999**. The
engine transforms this into a final priority using the following formula:
`final_priority = tier_base + (toml_priority / 1000)`
This system guarantees that:
- Admin policies always override User and Default policies.
- User policies always override Default policies.
- You can still order rules within a single tier with fine-grained control.
For example:
- A `priority: 50` rule in a Default policy file becomes `1.050`.
- A `priority: 100` rule in a User policy file becomes `2.100`.
- A `priority: 20` rule in an Admin policy file becomes `3.020`.
### Approval modes
Approval modes allow the policy engine to apply different sets of rules based on
the CLI's operational mode. A rule can be associated with one or more modes
(e.g., `yolo`, `autoEdit`). The rule will only be active if the CLI is running
in one of its specified modes. If a rule has no modes specified, it is always
active.
## Rule matching
When a tool call is made, the engine checks it against all active rules,
starting from the highest priority. The first rule that matches determines the
outcome.
A rule matches a tool call if all of its conditions are met:
1. **Tool name**: The `toolName` in the rule must match the name of the tool
being called.
- **Wildcards**: For Model-hosting-protocol (MCP) servers, you can use a
wildcard. A `toolName` of `my-server__*` will match any tool from the
`my-server` MCP.
2. **Arguments pattern**: If `argsPattern` is specified, the tool's arguments
are converted to a stable JSON string, which is then tested against the
provided regular expression. If the arguments don't match the pattern, the
rule does not apply.
## Configuration
Policies are defined in `.toml` files. The CLI loads these files from Default,
User, and (if configured) Admin directories.
### TOML rule schema
Here is a breakdown of the fields available in a TOML policy rule:
```toml
[[rule]]
# A unique name for the tool, or an array of names.
toolName = "run_shell_command"
# (Optional) The name of an MCP server. Can be combined with toolName
# to form a composite name like "mcpName__toolName".
mcpName = "my-custom-server"
# (Optional) A regex to match against the tool's arguments.
argsPattern = '"command":"(git|npm)'
# (Optional) A string or array of strings that a shell command must start with.
# This is syntactic sugar for `toolName = "run_shell_command"` and an `argsPattern`.
commandPrefix = "git "
# (Optional) A regex to match against the entire shell command.
# This is also syntactic sugar for `toolName = "run_shell_command"`.
# Note: This pattern is tested against the JSON representation of the arguments (e.g., `{"command":"<your_command>"}`), so anchors like `^` or `$` will apply to the full JSON string, not just the command text.
# You cannot use commandPrefix and commandRegex in the same rule.
commandRegex = "^git (commit|push)"
# The decision to take. Must be "allow", "deny", or "ask_user".
decision = "ask_user"
# The priority of the rule, from 0 to 999.
priority = 10
# (Optional) An array of approval modes where this rule is active.
modes = ["autoEdit"]
```
### Using arrays (lists)
To apply the same rule to multiple tools or command prefixes, you can provide an
array of strings for the `toolName` and `commandPrefix` fields.
**Example:**
This single rule will apply to both the `write_file` and `replace` tools.
```toml
[[rule]]
toolName = ["write_file", "replace"]
decision = "ask_user"
priority = 10
```
### Special syntax for `run_shell_command`
To simplify writing policies for `run_shell_command`, you can use
`commandPrefix` or `commandRegex` instead of the more complex `argsPattern`.
- `commandPrefix`: Matches if the `command` argument starts with the given
string.
- `commandRegex`: Matches if the `command` argument matches the given regular
expression.
**Example:**
This rule will ask for user confirmation before executing any `git` command.
```toml
[[rule]]
toolName = "run_shell_command"
commandPrefix = "git "
decision = "ask_user"
priority = 100
```
### Special syntax for MCP tools
You can create rules that target tools from Model-hosting-protocol (MCP) servers
using the `mcpName` field or a wildcard pattern.
**1. Using `mcpName`**
To target a specific tool from a specific server, combine `mcpName` and
`toolName`.
```toml
# Allows the `search` tool on the `my-jira-server` MCP
[[rule]]
mcpName = "my-jira-server"
toolName = "search"
decision = "allow"
priority = 200
```
**2. Using a wildcard**
To create a rule that applies to _all_ tools on a specific MCP server, specify
only the `mcpName`.
```toml
# Denies all tools from the `untrusted-server` MCP
[[rule]]
mcpName = "untrusted-server"
decision = "deny"
priority = 500
```
## Default policies
The Gemini CLI ships with a set of default policies to provide a safe
out-of-the-box experience.
- **Read-only tools** (like `read_file`, `glob`) are generally **allowed**.
- **Agent delegation** (like `delegate_to_agent`) defaults to **`ask_user`** to
ensure remote agents can prompt for confirmation, but local sub-agent actions
are executed silently and checked individually.
- **Write tools** (like `write_file`, `run_shell_command`) default to
**`ask_user`**.
- In **`yolo`** mode, a high-priority rule allows all tools.
- In **`autoEdit`** mode, rules allow certain write operations to happen without
prompting.
+28 -27
View File
@@ -1,11 +1,11 @@
# Gemini CLI core: Tools API
# Gemini CLI Core: Tools API
The Gemini CLI core (`packages/core`) features a robust system for defining,
registering, and executing tools. These tools extend the capabilities of the
Gemini model, allowing it to interact with the local environment, fetch web
content, and perform various actions beyond simple text generation.
## Core concepts
## Core Concepts
- **Tool (`tools.ts`):** An interface and base class (`BaseTool`) that defines
the contract for all tools. Each tool must have:
@@ -32,37 +32,38 @@ content, and perform various actions beyond simple text generation.
- `returnDisplay`: A user-friendly string (often Markdown) or a special object
(like `FileDiff`) for display in the CLI.
- **Returning rich content:** Tools are not limited to returning simple text.
- **Returning Rich Content:** Tools are not limited to returning simple text.
The `llmContent` can be a `PartListUnion`, which is an array that can contain
a mix of `Part` objects (for images, audio, etc.) and `string`s. This allows a
single tool execution to return multiple pieces of rich content.
- **Tool registry (`tool-registry.ts`):** A class (`ToolRegistry`) responsible
- **Tool Registry (`tool-registry.ts`):** A class (`ToolRegistry`) responsible
for:
- **Registering tools:** Holding a collection of all available built-in tools
- **Registering Tools:** Holding a collection of all available built-in tools
(e.g., `ReadFileTool`, `ShellTool`).
- **Discovering tools:** It can also discover tools dynamically:
- **Command-based discovery:** If `tools.discoveryCommand` is configured in
- **Discovering Tools:** It can also discover tools dynamically:
- **Command-based Discovery:** If `tools.discoveryCommand` is configured in
settings, this command is executed. It's expected to output JSON
describing custom tools, which are then registered as `DiscoveredTool`
instances.
- **MCP-based discovery:** If `mcp.serverCommand` is configured, the
- **MCP-based Discovery:** If `mcp.serverCommand` is configured, the
registry can connect to a Model Context Protocol (MCP) server to list and
register tools (`DiscoveredMCPTool`).
- **Providing schemas:** Exposing the `FunctionDeclaration` schemas of all
- **Providing Schemas:** Exposing the `FunctionDeclaration` schemas of all
registered tools to the Gemini model, so it knows what tools are available
and how to use them.
- **Retrieving tools:** Allowing the core to get a specific tool by name for
- **Retrieving Tools:** Allowing the core to get a specific tool by name for
execution.
## Built-in tools
## Built-in Tools
The core comes with a suite of pre-defined tools, typically found in
`packages/core/src/tools/`. These include:
- **File system tools:**
- **File System Tools:**
- `LSTool` (`ls.ts`): Lists directory contents.
- `ReadFileTool` (`read-file.ts`): Reads the content of a single file.
- `ReadFileTool` (`read-file.ts`): Reads the content of a single file. It
takes an `absolute_path` parameter, which must be an absolute path.
- `WriteFileTool` (`write-file.ts`): Writes content to a file.
- `GrepTool` (`grep.ts`): Searches for patterns in files.
- `GlobTool` (`glob.ts`): Finds files matching glob patterns.
@@ -70,26 +71,26 @@ The core comes with a suite of pre-defined tools, typically found in
requiring confirmation).
- `ReadManyFilesTool` (`read-many-files.ts`): Reads and concatenates content
from multiple files or glob patterns (used by the `@` command in CLI).
- **Execution tools:**
- **Execution Tools:**
- `ShellTool` (`shell.ts`): Executes arbitrary shell commands (requires
careful sandboxing and user confirmation).
- **Web tools:**
- **Web Tools:**
- `WebFetchTool` (`web-fetch.ts`): Fetches content from a URL.
- `WebSearchTool` (`web-search.ts`): Performs a web search.
- **Memory tools:**
- **Memory Tools:**
- `MemoryTool` (`memoryTool.ts`): Interacts with the AI's memory.
Each of these tools extends `BaseTool` and implements the required methods for
its specific functionality.
## Tool execution flow
## Tool Execution Flow
1. **Model request:** The Gemini model, based on the user's prompt and the
1. **Model Request:** The Gemini model, based on the user's prompt and the
provided tool schemas, decides to use a tool and returns a `FunctionCall`
part in its response, specifying the tool name and arguments.
2. **Core receives request:** The core parses this `FunctionCall`.
3. **Tool retrieval:** It looks up the requested tool in the `ToolRegistry`.
4. **Parameter validation:** The tool's `validateToolParams()` method is
2. **Core Receives Request:** The core parses this `FunctionCall`.
3. **Tool Retrieval:** It looks up the requested tool in the `ToolRegistry`.
4. **Parameter Validation:** The tool's `validateToolParams()` method is
called.
5. **Confirmation (if needed):**
- The tool's `shouldConfirmExecute()` method is called.
@@ -99,27 +100,27 @@ its specific functionality.
6. **Execution:** If validated and confirmed (or if no confirmation is needed),
the core calls the tool's `execute()` method with the provided arguments and
an `AbortSignal` (for potential cancellation).
7. **Result processing:** The `ToolResult` from `execute()` is received by the
7. **Result Processing:** The `ToolResult` from `execute()` is received by the
core.
8. **Response to model:** The `llmContent` from the `ToolResult` is packaged as
8. **Response to Model:** The `llmContent` from the `ToolResult` is packaged as
a `FunctionResponse` and sent back to the Gemini model so it can continue
generating a user-facing response.
9. **Display to user:** The `returnDisplay` from the `ToolResult` is sent to
9. **Display to User:** The `returnDisplay` from the `ToolResult` is sent to
the CLI to show the user what the tool did.
## Extending with custom tools
## Extending with Custom Tools
While direct programmatic registration of new tools by users isn't explicitly
detailed as a primary workflow in the provided files for typical end-users, the
architecture supports extension through:
- **Command-based discovery:** Advanced users or project administrators can
- **Command-based Discovery:** Advanced users or project administrators can
define a `tools.discoveryCommand` in `settings.json`. This command, when run
by the Gemini CLI core, should output a JSON array of `FunctionDeclaration`
objects. The core will then make these available as `DiscoveredTool`
instances. The corresponding `tools.callCommand` would then be responsible for
actually executing these custom tools.
- **MCP server(s):** For more complex scenarios, one or more MCP servers can be
- **MCP Server(s):** For more complex scenarios, one or more MCP servers can be
set up and configured via the `mcpServers` setting in `settings.json`. The
Gemini CLI core can then discover and use tools exposed by these servers. As
mentioned, if you have multiple MCP servers, the tool names will be prefixed
+1 -1
View File
@@ -1,4 +1,4 @@
# Example proxy script
# Example Proxy Script
The following is an example of a proxy script that can be used with the
`GEMINI_SANDBOX_PROXY_COMMAND` environment variable. This script only allows
+9 -7
View File
@@ -1,4 +1,4 @@
# Extension releasing
# Extension Releasing
There are two primary ways of releasing extensions to users:
@@ -15,9 +15,11 @@ if you need to ship platform specific binary files.
This is the most flexible and simple option. All you need to do is create a
publicly accessible git repo (such as a public github repository) and then users
can install your extension using `gemini extensions install <your-repo-uri>`.
They can optionally depend on a specific ref (branch/tag/commit) using the
`--ref=<some-ref>` argument, this defaults to the default branch.
can install your extension using `gemini extensions install <your-repo-uri>`, or
for a GitHub repository they can use the simplified
`gemini extensions install <org>/<repo>` format. They can optionally depend on a
specific ref (branch/tag/commit) using the `--ref=<some-ref>` argument, this
defaults to the default branch.
Whenever commits are pushed to the ref that a user depends on, they will be
prompted to update the extension. Note that this also allows for easy rollbacks,
@@ -64,7 +66,7 @@ If you plan on doing cherry picks, you may want to avoid having your default
branch be the stable branch to avoid force-pushing to the default branch which
should generally be avoided.
## Releasing through GitHub releases
## Releasing through Github releases
Gemini CLI extensions can be distributed through
[GitHub Releases](https://docs.github.com/en/repositories/releasing-projects-on-github/about-releases).
@@ -105,9 +107,9 @@ To ensure Gemini CLI can automatically find the correct release asset for each
platform, you must follow this naming convention. The CLI will search for assets
in the following order:
1. **Platform and architecture-Specific:**
1. **Platform and Architecture-Specific:**
`{platform}.{arch}.{name}.{extension}`
2. **Platform-specific:** `{platform}.{name}.{extension}`
2. **Platform-Specific:** `{platform}.{name}.{extension}`
3. **Generic:** If only one asset is provided, it will be used as a generic
fallback.
+8 -45
View File
@@ -1,4 +1,4 @@
# Getting started with Gemini CLI extensions
# Getting Started with Gemini CLI Extensions
This guide will walk you through creating your first Gemini CLI extension.
You'll learn how to set up a new extension, add a custom tool via an MCP server,
@@ -10,7 +10,7 @@ file.
Before you start, make sure you have the Gemini CLI installed and a basic
understanding of Node.js and TypeScript.
## Step 1: Create a new extension
## Step 1: Create a New Extension
The easiest way to start is by using one of the built-in templates. We'll use
the `mcp-server` example as our foundation.
@@ -32,7 +32,7 @@ my-first-extension/
└── tsconfig.json
```
## Step 2: Understand the extension files
## Step 2: Understand the Extension Files
Let's look at the key files in your new extension.
@@ -124,7 +124,7 @@ These are standard configuration files for a TypeScript project. The
`package.json` file defines dependencies and a `build` script, and
`tsconfig.json` configures the TypeScript compiler.
## Step 3: Build and link your extension
## Step 3: Build and Link Your Extension
Before you can use the extension, you need to compile the TypeScript code and
link the extension to your Gemini CLI installation for local development.
@@ -158,7 +158,7 @@ link the extension to your Gemini CLI installation for local development.
Now, restart your Gemini CLI session. The new `fetch_posts` tool will be
available. You can test it by asking: "fetch posts".
## Step 4: Add a custom command
## Step 4: Add a Custom Command
Custom commands provide a way to create shortcuts for complex prompts. Let's add
a command that searches for a pattern in your code.
@@ -186,7 +186,7 @@ a command that searches for a pattern in your code.
After saving the file, restart the Gemini CLI. You can now run
`/fs:grep-code "some pattern"` to use your new command.
## Step 5: Add a custom `GEMINI.md`
## Step 5: Add a Custom `GEMINI.md`
You can provide persistent context to the model by adding a `GEMINI.md` file to
your extension. This is useful for giving the model instructions on how to
@@ -222,45 +222,9 @@ need this for extensions built to expose commands and prompts.
Restart the CLI again. The model will now have the context from your `GEMINI.md`
file in every session where the extension is active.
## (Optional) Step 6: Add an Agent Skill
## Step 6: Releasing Your Extension
_Note: This is an experimental feature enabled via `experimental.skills`._
[Agent Skills](../cli/skills.md) let you bundle specialized expertise and
procedural workflows. Unlike `GEMINI.md`, which provides persistent context,
skills are activated only when needed, saving context tokens.
1. Create a `skills` directory and a subdirectory for your skill:
```bash
mkdir -p skills/security-audit
```
2. Create a `skills/security-audit/SKILL.md` file:
```markdown
---
name: security-audit
description:
Expertise in auditing code for security vulnerabilities. Use when the user
asks to "check for security issues" or "audit" their changes.
---
# Security Auditor
You are an expert security researcher. When auditing code:
1. Look for common vulnerabilities (OWASP Top 10).
2. Check for hardcoded secrets or API keys.
3. Suggest remediation steps for any findings.
```
Skills bundled with your extension are automatically discovered and can be
activated by the model during a session when it identifies a relevant task.
## Step 7: Release your extension
Once you're happy with your extension, you can share it with others. The two
Once you are happy with your extension, you can share it with others. The two
primary ways of releasing extensions are via a Git repository or through GitHub
Releases. Using a public Git repository is the simplest method.
@@ -275,7 +239,6 @@ You've successfully created a Gemini CLI extension! You learned how to:
- Add custom tools with an MCP server.
- Create convenient custom commands.
- Provide persistent context to the model.
- Bundle specialized Agent Skills.
- Link your extension for local development.
From here, you can explore more advanced features and build powerful new
+36 -181
View File
@@ -1,11 +1,11 @@
# Gemini CLI extensions
# Gemini CLI Extensions
_This documentation is up-to-date with the v0.4.0 release._
Gemini CLI extensions package prompts, MCP servers, Agent Skills, and custom
commands into a familiar and user-friendly format. With extensions, you can
expand the capabilities of Gemini CLI and share those capabilities with others.
They're designed to be easily installable and shareable.
Gemini CLI extensions package prompts, MCP servers, and custom commands into a
familiar and user-friendly format. With extensions, you can expand the
capabilities of Gemini CLI and share those capabilities with others. They are
designed to be easily installable and shareable.
To see examples of extensions, you can browse a gallery of
[Gemini CLI extensions](https://geminicli.com/extensions/browse/).
@@ -42,23 +42,19 @@ installed on your machine. See
for help.
```
gemini extensions install <source> [--ref <ref>] [--auto-update] [--pre-release] [--consent]
gemini extensions install https://github.com/gemini-cli-extensions/security
```
- `<source>`: The github URL or local path of the extension to install.
- `--ref`: The git ref to install from.
- `--auto-update`: Enable auto-update for this extension.
- `--pre-release`: Enable pre-release versions for this extension.
- `--consent`: Acknowledge the security risks of installing an extension and
skip the confirmation prompt.
This will install the Gemini CLI Security extension, which offers support for a
`/security:analyze` command.
### Uninstalling an extension
To uninstall one or more extensions, run
`gemini extensions uninstall <name...>`:
To uninstall, run `gemini extensions uninstall extension-name`, so, in the case
of the install example:
```
gemini extensions uninstall gemini-cli-security gemini-cli-another-extension
gemini extensions uninstall gemini-cli-security
```
### Disabling an extension
@@ -66,31 +62,27 @@ gemini extensions uninstall gemini-cli-security gemini-cli-another-extension
Extensions are, by default, enabled across all workspaces. You can disable an
extension entirely or for specific workspace.
```
gemini extensions disable <name> [--scope <scope>]
```
- `<name>`: The name of the extension to disable.
- `--scope`: The scope to disable the extension in (`user` or `workspace`).
For example, `gemini extensions disable extension-name` will disable the
extension at the user level, so it will be disabled everywhere.
`gemini extensions disable extension-name --scope=workspace` will only disable
the extension in the current workspace.
### Enabling an extension
You can enable extensions using `gemini extensions enable <name>`. You can also
enable an extension for a specific workspace using
`gemini extensions enable <name> --scope=workspace` from within that workspace.
You can enable extensions using `gemini extensions enable extension-name`. You
can also enable an extension for a specific workspace using
`gemini extensions enable extension-name --scope=workspace` from within that
workspace.
```
gemini extensions enable <name> [--scope <scope>]
```
- `<name>`: The name of the extension to enable.
- `--scope`: The scope to enable the extension in (`user` or `workspace`).
This is useful if you have an extension disabled at the top-level and only
enabled in specific places.
### Updating an extension
For extensions installed from a local path or a git repository, you can
explicitly update to the latest version (as reflected in the
`gemini-extension.json` `version` field) with `gemini extensions update <name>`.
`gemini-extension.json` `version` field) with
`gemini extensions update extension-name`.
You can update all extensions with:
@@ -98,6 +90,10 @@ You can update all extensions with:
gemini extensions update --all
```
## Extension creation
We offer commands to make extension development easier.
### Create a boilerplate extension
We offer several example extensions `context`, `custom-commands`,
@@ -108,12 +104,9 @@ To copy one of these examples into a development directory using the type of
your choosing, run:
```
gemini extensions new <path> [template]
gemini extensions new path/to/directory custom-commands
```
- `<path>`: The path to create the extension in.
- `[template]`: The boilerplate template to use.
### Link a local extension
The `gemini extensions link` command will create a symbolic link from the
@@ -123,11 +116,9 @@ This is useful so you don't have to run `gemini extensions update` every time
you make changes you'd like to test.
```
gemini extensions link <path>
gemini extensions link path/to/directory
```
- `<path>`: The path of the extension to link.
## How it works
On startup, Gemini CLI looks for extensions in `<home>/.gemini/extensions`
@@ -163,11 +154,11 @@ The file has the following structure:
your extension in the CLI. Note that we expect this name to match the
extension directory name.
- `version`: The version of the extension.
- `mcpServers`: A map of MCP servers to settings. The key is the name of the
- `mcpServers`: A map of MCP servers to configure. The key is the name of the
server, and the value is the server configuration. These servers will be
loaded on startup just like MCP servers settings in a
loaded on startup just like MCP servers configured in a
[`settings.json` file](../get-started/configuration.md). If both an extension
and a `settings.json` file settings an MCP server with the same name, the
and a `settings.json` file configure an MCP server with the same name, the
server defined in the `settings.json` file takes precedence.
- Note that all MCP server configuration options are supported except for
`trust`.
@@ -186,58 +177,6 @@ When Gemini CLI starts, it loads all the extensions and merges their
configurations. If there are any conflicts, the workspace configuration takes
precedence.
### Settings
_Note: This is an experimental feature. We do not yet recommend extension
authors introduce settings as part of their core flows._
Extensions can define settings that the user will be prompted to provide upon
installation. This is useful for things like API keys, URLs, or other
configuration that the extension needs to function.
To define settings, add a `settings` array to your `gemini-extension.json` file.
Each object in the array should have the following properties:
- `name`: A user-friendly name for the setting.
- `description`: A description of the setting and what it's used for.
- `envVar`: The name of the environment variable that the setting will be stored
as.
- `sensitive`: Optional boolean. If true, obfuscates the input the user provides
and stores the secret in keychain storage. **Example**
```json
{
"name": "my-api-extension",
"version": "1.0.0",
"settings": [
{
"name": "API Key",
"description": "Your API key for the service.",
"envVar": "MY_API_KEY"
}
]
}
```
When a user installs this extension, they will be prompted to enter their API
key. The value will be saved to a `.env` file in the extension's directory
(e.g., `<home>/.gemini/extensions/my-api-extension/.env`).
You can view a list of an extension's settings by running:
```
gemini extensions list
```
and you can update a given setting using:
```
gemini extensions config <extension name> [setting name] [--scope <scope>]
```
- `--scope`: The scope to set the setting in (`user` or `workspace`). This is
optional and will default to `user`.
### Custom commands
Extensions can provide [custom commands](../cli/custom-commands.md) by placing
@@ -263,88 +202,6 @@ Would provide these commands:
- `/deploy` - Shows as `[gcp] Custom command from deploy.toml` in help
- `/gcs:sync` - Shows as `[gcp] Custom command from sync.toml` in help
### Agent Skills
_Note: This is an experimental feature enabled via `experimental.skills`._
Extensions can bundle [Agent Skills](../cli/skills.md) to provide on-demand
expertise and specialized workflows. To include skills in your extension, place
them in a `skills/` subdirectory within the extension directory. Each skill must
follow the [Agent Skills structure](../cli/skills.md#folder-structure),
including a `SKILL.md` file.
**Example**
An extension named `security-toolkit` with the following structure:
```
.gemini/extensions/security-toolkit/
├── gemini-extension.json
└── skills/
├── audit/
│ ├── SKILL.md
│ └── scripts/
│ └── scan.py
└── hardening/
└── SKILL.md
```
Upon installation, these skills will be discovered by Gemini CLI and can be
activated during a session when the model identifies a task matching their
descriptions.
Extension skills have the lowest precedence and will be overridden by user or
workspace skills of the same name. They can be viewed and managed (enabled or
disabled) using the [`/skills` command](../cli/skills.md#managing-skills).
### Hooks
Extensions can provide [hooks](../hooks/index.md) to intercept and customize
Gemini CLI behavior at specific lifecycle events. Hooks provided by an extension
must be defined in a `hooks/hooks.json` file within the extension directory.
> [!IMPORTANT] Hooks are not defined directly in `gemini-extension.json`. The
> CLI specifically looks for the `hooks/hooks.json` file.
#### Directory structure
```
.gemini/extensions/my-extension/
├── gemini-extension.json
└── hooks/
└── hooks.json
```
#### `hooks/hooks.json` format
The `hooks.json` file contains a `hooks` object where keys are
[event names](../hooks/reference.md#supported-events) and values are arrays of
[hook definitions](../hooks/reference.md#hook-definition).
```json
{
"hooks": {
"before_agent": [
{
"hooks": [
{
"type": "command",
"command": "node ${extensionPath}/scripts/setup.js",
"name": "Extension Setup"
}
]
}
]
}
}
```
#### Supported variables
Just like `gemini-extension.json`, the `hooks/hooks.json` file supports
[variable substitution](#variables). This is particularly useful for referencing
scripts within the extension directory using `${extensionPath}`.
### Conflict resolution
Extension commands have the lowest precedence. When a conflict occurs with user
@@ -360,12 +217,11 @@ For example, if both a user and the `gcp` extension define a `deploy` command:
- `/gcp.deploy` - Executes the extension's deploy command (marked with `[gcp]`
tag)
### Variables
## Variables
Gemini CLI extensions allow variable substitution in both
`gemini-extension.json` and `hooks/hooks.json`. This can be useful if e.g., you
need the current directory to run an MCP server or hook script using
`"cwd": "${extensionPath}${/}run.ts"`.
Gemini CLI extensions allow variable substitution in `gemini-extension.json`.
This can be useful if e.g., you need the current directory to run an MCP server
using `"cwd": "${extensionPath}${/}run.ts"`.
**Supported variables:**
@@ -374,4 +230,3 @@ need the current directory to run an MCP server or hook script using
| `${extensionPath}` | The fully-qualified path of the extension in the user's filesystem e.g., '/Users/username/.gemini/extensions/example-extension'. This will not unwrap symlinks. |
| `${workspacePath}` | The fully-qualified path of the current workspace. |
| `${/} or ${pathSeparator}` | The path separator (differs per OS). |
| `${process.execPath}` | The path to the Node.js binary executing the CLI. |
+1 -1
View File
@@ -1,4 +1,4 @@
# Frequently asked questions (FAQ)
# Frequently Asked Questions (FAQ)
This page provides answers to common questions and solutions to frequent
problems encountered while using Gemini CLI.
+147 -195
View File
@@ -1,198 +1,196 @@
# Gemini CLI authentication setup
# Gemini CLI Authentication Setup
To use Gemini CLI, you'll need to authenticate with Google. This guide helps you
quickly find the best way to sign in based on your account type and how you're
using the CLI.
Gemini CLI requires authentication using Google's services. Before using Gemini
CLI, configure **one** of the following authentication methods:
For most users, we recommend starting Gemini CLI and logging in with your
personal Google account.
- Interactive mode:
- Recommended: Login with Google
- Use Gemini API key
- Use Vertex AI
- Headless (non-interactive) mode
- Google Cloud Shell
## Choose your authentication method <a id="auth-methods"></a>
## Quick Check: Running in Google Cloud Shell?
Select the authentication method that matches your situation in the table below:
If you are running the Gemini CLI within a Google Cloud Shell environment,
authentication is typically automatic using your Cloud Shell credentials.
| User Type / Scenario | Recommended Authentication Method | Google Cloud Project Required |
| :--------------------------------------------------------------------- | :--------------------------------------------------------------- | :---------------------------------------------------------- |
| Individual Google accounts | [Login with Google](#login-google) | No, with exceptions |
| Organization users with a company, school, or Google Workspace account | [Login with Google](#login-google) | [Yes](#set-gcp) |
| AI Studio user with a Gemini API key | [Use Gemini API Key](#gemini-api) | No |
| Google Cloud Vertex AI user | [Vertex AI](#vertex-ai) | [Yes](#set-gcp) |
| [Headless mode](#headless) | [Use Gemini API Key](#gemini-api) or<br> [Vertex AI](#vertex-ai) | No (for Gemini API Key)<br> [Yes](#set-gcp) (for Vertex AI) |
## Authenticate in Interactive mode
### What is my Google account type?
When you run Gemini CLI through the command-line, Gemini CLI will provide the
following options:
- **Individual Google accounts:** Includes all
[free tier accounts](../quota-and-pricing/#free-usage) such as Gemini Code
Assist for individuals, as well as paid subscriptions for
[Google AI Pro and Ultra](https://gemini.google/subscriptions/).
```bash
> 1. Login with Google
> 2. Use Gemini API key
> 3. Vertex AI
```
- **Organization accounts:** Accounts using paid licenses through an
organization such as a company, school, or
[Google Workspace](https://workspace.google.com/). Includes
[Google AI Ultra for Business](https://support.google.com/a/answer/16345165)
subscriptions.
The following sections provide instructions for each of these authentication
options.
## (Recommended) Login with Google <a id="login-google"></a>
### Recommended: Login with Google
If you run Gemini CLI on your local machine, the simplest authentication method
is logging in with your Google account. This method requires a web browser on a
machine that can communicate with the terminal running Gemini CLI (e.g., your
local machine).
If you are running Gemini CLI on your local machine, the simplest method is
logging in with your Google account.
> **Important:** If you are a **Google AI Pro** or **Google AI Ultra**
> subscriber, use the Google account associated with your subscription.
> **Important:** Use this method if you are a **Google AI Pro** or **Google AI
> Ultra** subscriber.
To authenticate and use Gemini CLI:
1. Select **Login with Google**. Gemini CLI will open a login prompt using your
web browser.
1. Start the CLI:
If you are a **Google AI Pro** or **Google AI Ultra** subscriber, login with
the Google account associated with your subscription.
```bash
gemini
```
2. Follow the on-screen instructions. Your credentials will be cached locally
for future sessions.
2. Select **Login with Google**. Gemini CLI opens a login prompt using your web
browser. Follow the on-screen instructions. Your credentials will be cached
locally for future sessions.
> **Note:** This method requires a web browser on a machine that can
> communicate with the terminal running the CLI (e.g., your local machine).
> The browser will be redirected to a `localhost` URL that the CLI listens on
> during setup.
### Do I need to set my Google Cloud project?
#### (Optional) Set your Google Cloud Project
Most individual Google accounts (free and paid) don't require a Google Cloud
project for authentication. However, you'll need to set a Google Cloud project
when you meet at least one of the following conditions:
When you log in using a Google account, you may be prompted to select a
`GOOGLE_CLOUD_PROJECT`.
- You are using a company, school, or Google Workspace account.
- You are using a Gemini Code Assist license from the Google Developer Program.
- You are using a license from a Gemini Code Assist subscription.
This can be necessary if you are:
For instructions, see [Set your Google Cloud Project](#set-gcp).
- Using a Google Workspace account.
- Using a Gemini Code Assist license from the Google Developer Program.
- Using a license from a Gemini Code Assist subscription.
- Using the product outside the
[supported regions](https://developers.google.com/gemini-code-assist/resources/available-locations)
for free individual usage.
- A Google account holder under the age of 18.
## Use Gemini API key <a id="gemini-api"></a>
If you fall into one of these categories, you must:
1. Have a Google Cloud Project ID.
2. [Enable the Gemini for Cloud API](https://cloud.google.com/gemini/docs/discover/set-up-gemini#enable-api).
3. [Configure necessary IAM access permissions](https://cloud.google.com/gemini/docs/discover/set-up-gemini#grant-iam).
To set the project ID, you can export either the `GOOGLE_CLOUD_PROJECT` or
`GOOGLE_CLOUD_PROJECT_ID` environment variable. The CLI checks for
`GOOGLE_CLOUD_PROJECT` first, then falls back to `GOOGLE_CLOUD_PROJECT_ID` :
```bash
# Replace YOUR_PROJECT_ID with your actual Google Cloud Project ID
# Using the standard variable:
export GOOGLE_CLOUD_PROJECT="YOUR_PROJECT_ID"
# Or, using the fallback variable:
export GOOGLE_CLOUD_PROJECT_ID="YOUR_PROJECT_ID"
```
To make this setting persistent, see
[Persisting Environment Variables](#persisting-environment-variables).
### Use Gemini API Key
If you don't want to authenticate using your Google account, you can use an API
key from Google AI Studio.
To authenticate and use Gemini CLI with a Gemini API key:
1. Obtain your API key from
[Google AI Studio](https://aistudio.google.com/app/apikey).
2. Set the `GEMINI_API_KEY` environment variable:
1. Obtain your API key from
[Google AI Studio](https://aistudio.google.com/app/apikey).
```bash
# Replace YOUR_GEMINI_API_KEY with the key from AI Studio
export GEMINI_API_KEY="YOUR_GEMINI_API_KEY"
```
2. Set the `GEMINI_API_KEY` environment variable to your key. For example:
```bash
# Replace YOUR_GEMINI_API_KEY with the key from AI Studio
export GEMINI_API_KEY="YOUR_GEMINI_API_KEY"
```
To make this setting persistent, see
[Persisting Environment Variables](#persisting-vars).
3. Start the CLI:
```bash
gemini
```
4. Select **Use Gemini API key**.
To make this setting persistent, see
[Persisting Environment Variables](#persisting-environment-variables).
> **Warning:** Treat API keys, especially for services like Gemini, as sensitive
> credentials. Protect them to prevent unauthorized access and potential misuse
> of the service under your account.
## Use Vertex AI <a id="vertex-ai"></a>
### Use Vertex AI
To use Gemini CLI with Google Cloud's Vertex AI platform, choose from the
following authentication options:
If you intend to use Google Cloud's Vertex AI platform, you have several
authentication options:
- A. Application Default Credentials (ADC) using `gcloud`.
- B. Service account JSON key.
- C. Google Cloud API key.
- Application Default Credentials (ADC) and `gcloud`.
- A Service Account JSON key.
- A Google Cloud API key.
Regardless of your authentication method for Vertex AI, you'll need to set
`GOOGLE_CLOUD_PROJECT` to your Google Cloud project ID with the Vertex AI API
enabled, and `GOOGLE_CLOUD_LOCATION` to the location of your Vertex AI resources
or the location where you want to run your jobs.
#### First: Set required environment variables
For example:
Regardless of your method of authentication, you'll typically need to set the
following variables: `GOOGLE_CLOUD_PROJECT` (or `GOOGLE_CLOUD_PROJECT_ID`) and
`GOOGLE_CLOUD_LOCATION`.
To set these variables:
```bash
# Replace with your project ID and desired location (e.g., us-central1)
# You can use GOOGLE_CLOUD_PROJECT_ID as a fallback for GOOGLE_CLOUD_PROJECT
export GOOGLE_CLOUD_PROJECT="YOUR_PROJECT_ID"
export GOOGLE_CLOUD_LOCATION="YOUR_PROJECT_LOCATION"
```
To make any Vertex AI environment variable settings persistent, see
[Persisting Environment Variables](#persisting-vars).
#### A. Vertex AI - Application Default Credentials (ADC) using `gcloud`
#### A. Vertex AI - application default credentials (ADC) using `gcloud`
Consider this authentication method if you have Google Cloud CLI installed.
Consider this method of authentication if you have Google Cloud CLI installed.
> **Note:** If you have previously set `GOOGLE_API_KEY` or `GEMINI_API_KEY`, you
> must unset them to use ADC:
>
> ```bash
> unset GOOGLE_API_KEY GEMINI_API_KEY
> ```
1. Verify you have a Google Cloud project and Vertex AI API is enabled.
```bash
unset GOOGLE_API_KEY GEMINI_API_KEY
```
2. Log in to Google Cloud:
1. Ensure you have a Google Cloud project and Vertex AI API is enabled.
2. Log in to Google Cloud:
```bash
gcloud auth application-default login
```
```bash
gcloud auth application-default login
```
3. [Configure your Google Cloud Project](#set-gcp).
See
[Set up Application Default Credentials](https://cloud.google.com/docs/authentication/provide-credentials-adc)
for details.
4. Start the CLI:
3. Ensure `GOOGLE_CLOUD_PROJECT` (or `GOOGLE_CLOUD_PROJECT_ID`) and
`GOOGLE_CLOUD_LOCATION` are set.
```bash
gemini
```
#### B. Vertex AI - Service Account JSON key
5. Select **Vertex AI**.
#### B. Vertex AI - service account JSON key
Consider this method of authentication in non-interactive environments, CI/CD
pipelines, or if your organization restricts user-based ADC or API key creation.
Consider this method of authentication in non-interactive environments, CI/CD,
or if your organization restricts user-based ADC or API key creation.
> **Note:** If you have previously set `GOOGLE_API_KEY` or `GEMINI_API_KEY`, you
> must unset them:
>
> ```bash
> unset GOOGLE_API_KEY GEMINI_API_KEY
> ```
```bash
unset GOOGLE_API_KEY GEMINI_API_KEY
```
1. [Create a service account and key](https://cloud.google.com/iam/docs/keys-create-delete)
and download the provided JSON file. Assign the "Vertex AI User" role to the
service account.
2. Set the `GOOGLE_APPLICATION_CREDENTIALS` environment variable to the JSON
file's absolute path. For example:
file's absolute path:
```bash
# Replace /path/to/your/keyfile.json with the actual path
export GOOGLE_APPLICATION_CREDENTIALS="/path/to/your/keyfile.json"
```
3. [Configure your Google Cloud Project](#set-gcp).
3. Ensure `GOOGLE_CLOUD_PROJECT` (or `GOOGLE_CLOUD_PROJECT_ID`) and
`GOOGLE_CLOUD_LOCATION` are set.
4. Start the CLI:
```bash
gemini
```
5. Select **Vertex AI**.
> **Warning:** Protect your service account key file as it gives access to
> your resources.
> **Warning:** Protect your service account key file as it provides access to
> your resources.
#### C. Vertex AI - Google Cloud API key
1. Obtain a Google Cloud API key:
[Get an API Key](https://cloud.google.com/vertex-ai/generative-ai/docs/start/api-keys?usertype=newuser).
2. Set the `GOOGLE_API_KEY` environment variable:
```bash
@@ -202,59 +200,17 @@ pipelines, or if your organization restricts user-based ADC or API key creation.
> **Note:** If you see errors like
> `"API keys are not supported by this API..."`, your organization might
> restrict API key usage for this service. Try the other Vertex AI
> authentication methods instead.
> restrict API key usage for this service. Try the
> [Service Account JSON Key](#b-vertex-ai-service-account-json-key) or
> [ADC](#a-vertex-ai-application-default-credentials-adc-using-gcloud)
> methods instead.
3. [Configure your Google Cloud Project](#set-gcp).
To make any of these Vertex AI environment variable settings persistent, see
[Persisting Environment Variables](#persisting-environment-variables).
4. Start the CLI:
## Persisting Environment Variables
```bash
gemini
```
5. Select **Vertex AI**.
## Set your Google Cloud project <a id="set-gcp"></a>
> **Important:** Most individual Google accounts (free and paid) don't require a
> Google Cloud project for authentication.
When you sign in using your Google account, you may need to configure a Google
Cloud project for Gemini CLI to use. This applies when you meet at least one of
the following conditions:
- You are using a Company, School, or Google Workspace account.
- You are using a Gemini Code Assist license from the Google Developer Program.
- You are using a license from a Gemini Code Assist subscription.
To configure Gemini CLI to use a Google Cloud project, do the following:
1. [Find your Google Cloud Project ID](https://support.google.com/googleapi/answer/7014113).
2. [Enable the Gemini for Cloud API](https://cloud.google.com/gemini/docs/discover/set-up-gemini#enable-api).
3. [Configure necessary IAM access permissions](https://cloud.google.com/gemini/docs/discover/set-up-gemini#grant-iam).
4. Configure your environment variables. Set either the `GOOGLE_CLOUD_PROJECT`
or `GOOGLE_CLOUD_PROJECT_ID` variable to the project ID to use with Gemini
CLI. Gemini CLI checks for `GOOGLE_CLOUD_PROJECT` first, then falls back to
`GOOGLE_CLOUD_PROJECT_ID`.
For example, to set the `GOOGLE_CLOUD_PROJECT_ID` variable:
```bash
# Replace YOUR_PROJECT_ID with your actual Google Cloud project ID
export GOOGLE_CLOUD_PROJECT="YOUR_PROJECT_ID"
```
To make this setting persistent, see
[Persisting Environment Variables](#persisting-vars).
## Persisting environment variables <a id="persisting-vars"></a>
To avoid setting environment variables for every terminal session, you can
persist them with the following methods:
To avoid setting environment variables in every terminal session, you can:
1. **Add your environment variables to your shell configuration file:** Append
the `export ...` commands to your shell's startup file (e.g., `~/.bashrc`,
@@ -267,9 +223,9 @@ persist them with the following methods:
source ~/.bashrc
```
> **Warning:** Be aware that when you export API keys or service account
> paths in your shell configuration file, any process launched from that
> shell can read them.
> **Warning:** Be advised that when you export API keys or service account
> paths in your shell configuration file, any process executed from the
> shell can potentially read them.
2. **Use a `.env` file:** Create a `.gemini/.env` file in your project
directory or home directory. Gemini CLI automatically loads variables from
@@ -286,31 +242,27 @@ persist them with the following methods:
EOF
```
Variables are loaded from the first file found, not merged.
Variables are loaded from the first file found, not merged.
## Running in Google Cloud environments <a id="cloud-env"></a>
## Non-interactive mode / headless environments
When running Gemini CLI within certain Google Cloud environments, authentication
is automatic.
Non-interative mode / headless environments will use your existing
authentication method, if an existing authentication credential is cached.
In a Google Cloud Shell environment, Gemini CLI typically authenticates
automatically using your Cloud Shell credentials. In Compute Engine
environments, Gemini CLI automatically uses Application Default Credentials
(ADC) from the environment's metadata server.
If you have not already logged in with an authentication credential (such as a
Google account), you **must** configure authentication using environment
variables:
If automatic authentication fails, use one of the interactive methods described
on this page.
1. **Gemini API Key:** Set `GEMINI_API_KEY`.
2. **Vertex AI:**
- Set `GOOGLE_GENAI_USE_VERTEXAI=true`.
- **With Google Cloud API Key:** Set `GOOGLE_API_KEY`.
- **With ADC:** Ensure ADC is configured (e.g., via a service account with
`GOOGLE_APPLICATION_CREDENTIALS`) and set `GOOGLE_CLOUD_PROJECT` (or
`GOOGLE_CLOUD_PROJECT_ID`) and `GOOGLE_CLOUD_LOCATION`.
## Running in headless mode <a id="headless"></a>
[Headless mode](../cli/headless) will use your existing authentication method,
if an existing authentication credential is cached.
If you have not already logged in with an authentication credential, you must
configure authentication using environment variables:
- [Use Gemini API Key](#gemini-api)
- [Vertex AI](#vertex-ai)
The CLI will exit with an error in non-interactive mode if no suitable
environment variables are found.
## What's next?
+37 -35
View File
@@ -1,6 +1,6 @@
# Gemini CLI configuration
# Gemini CLI Configuration
**Note on deprecated configuration format**
**Note on Deprecated Configuration Format**
This document describes the legacy v1 format for the `settings.json` file. This
format is now deprecated.
@@ -132,7 +132,7 @@ contain other project-specific files related to Gemini CLI's operation, such as:
}
```
### Troubleshooting file search performance
### Troubleshooting File Search Performance
If you are experiencing performance issues with file searching (e.g., with `@`
completions), especially in projects with a very large number of files, here are
@@ -144,12 +144,12 @@ a few things you can try in order of recommendation:
the total number of files crawled is the most effective way to improve
performance.
2. **Disable fuzzy search:** If ignoring files is not enough, you can disable
2. **Disable Fuzzy Search:** If ignoring files is not enough, you can disable
fuzzy search by setting `disableFuzzySearch` to `true` in your
`settings.json` file. This will use a simpler, non-fuzzy matching algorithm,
which can be faster.
3. **Disable recursive file search:** As a last resort, you can disable
3. **Disable Recursive File Search:** As a last resort, you can disable
recursive file search entirely by setting `enableRecursiveFileSearch` to
`false`. This will be the fastest option as it avoids a recursive crawl of
your project. However, it means you will need to type the full path to files
@@ -194,7 +194,7 @@ a few things you can try in order of recommendation:
`--allowed-mcp-server-names` is set.
- **Default:** All MCP servers are available for use by the Gemini model.
- **Example:** `"allowMCPServers": ["myPythonServer"]`.
- **Security note:** This uses simple string matching on MCP server names,
- **Security Note:** This uses simple string matching on MCP server names,
which can be modified. If you're a system administrator looking to prevent
users from bypassing this, consider configuring the `mcpServers` at the
system settings level such that the user will not be able to configure any
@@ -208,7 +208,7 @@ a few things you can try in order of recommendation:
be ignored if `--allowed-mcp-server-names` is set.
- **Default**: No MCP servers excluded.
- **Example:** `"excludeMCPServers": ["myNodeServer"]`.
- **Security note:** This uses simple string matching on MCP server names,
- **Security Note:** This uses simple string matching on MCP server names,
which can be modified. If you're a system administrator looking to prevent
users from bypassing this, consider configuring the `mcpServers` at the
system settings level such that the user will not be able to configure any
@@ -538,7 +538,7 @@ a few things you can try in order of recommendation:
}
```
## Shell history
## Shell History
The CLI keeps a history of shell commands you run. To avoid conflicts between
different projects, this history is stored in a project-specific directory
@@ -549,7 +549,7 @@ within your user's home folder.
path.
- The history is stored in a file named `shell_history`.
## Environment variables and `.env` files
## Environment Variables & `.env` Files
Environment variables are a common way to configure applications, especially for
sensitive information like API keys or for settings that might change between
@@ -566,7 +566,7 @@ loading order is:
the home directory.
3. If still not found, it looks for `~/.env` (in the user's home directory).
**Environment variable exclusion:** Some environment variables (like `DEBUG` and
**Environment Variable Exclusion:** Some environment variables (like `DEBUG` and
`DEBUG_MODE`) are automatically excluded from being loaded from project `.env`
files to prevent interference with gemini-cli behavior. Variables from
`.gemini/.env` files are never excluded. You can customize this behavior using
@@ -591,7 +591,7 @@ the `excludedProjectEnvVars` setting in your `settings.json` file.
- Required for using Code Assist or Vertex AI.
- If using Vertex AI, ensure you have the necessary permissions in this
project.
- **Cloud Shell note:** When running in a Cloud Shell environment, this
- **Cloud Shell Note:** When running in a Cloud Shell environment, this
variable defaults to a special project allocated for Cloud Shell users. If
you have `GOOGLE_CLOUD_PROJECT` set in your global environment in Cloud
Shell, it will be overridden by this default. To use a different project in
@@ -611,9 +611,6 @@ the `excludedProjectEnvVars` setting in your `settings.json` file.
- **`GEMINI_SANDBOX`**:
- Alternative to the `sandbox` setting in `settings.json`.
- Accepts `true`, `false`, `docker`, `podman`, or a custom command string.
- **`HTTP_PROXY` / `HTTPS_PROXY`**:
- Specifies the proxy server to use for outgoing HTTP/HTTPS requests.
- Example: `export HTTPS_PROXY="http://proxy.example.com:8080"`
- **`SEATBELT_PROFILE`** (macOS specific):
- Switches the Seatbelt (`sandbox-exec`) profile on macOS.
- `permissive-open`: (Default) Restricts writes to the project folder (and a
@@ -639,7 +636,7 @@ the `excludedProjectEnvVars` setting in your `settings.json` file.
- Specifies the endpoint for the code assist server.
- This is useful for development and testing.
## Command-line arguments
## Command-Line Arguments
Arguments passed directly when running the CLI can override other configurations
for that specific session.
@@ -695,6 +692,8 @@ for that specific session.
- **`--telemetry-log-prompts`**:
- Enables logging of prompts for telemetry. See
[telemetry](../cli/telemetry.md) for more information.
- **`--checkpointing`**:
- Enables [checkpointing](../cli/checkpointing.md).
- **`--extensions <extension_name ...>`** (**`-e <extension_name ...>`**):
- Specifies a list of extensions to use for the session. If not provided, all
available extensions are used.
@@ -702,6 +701,9 @@ for that specific session.
- Example: `gemini -e my-extension -e my-other-extension`
- **`--list-extensions`** (**`-l`**):
- Lists all available extensions and exits.
- **`--proxy`**:
- Sets the proxy for the CLI.
- Example: `--proxy http://localhost:7890`.
- **`--include-directories <dir1,dir2,...>`**:
- Includes additional directories in the workspace for multi-directory
support.
@@ -714,7 +716,7 @@ for that specific session.
- **`--version`**:
- Displays the version of the CLI.
## Context files (hierarchical instructional context)
## Context Files (Hierarchical Instructional Context)
While not strictly configuration for the CLI's _behavior_, context files
(defaulting to `GEMINI.md` but configurable via the `contextFileName` setting)
@@ -730,7 +732,7 @@ context.
that you want the Gemini model to be aware of during your interactions. The
system is designed to manage this instructional context hierarchically.
### Example context file content (e.g., `GEMINI.md`)
### Example Context File Content (e.g., `GEMINI.md`)
Here's a conceptual example of what a context file at the root of a TypeScript
project might contain:
@@ -771,23 +773,23 @@ more relevant and precise your context files are, the better the AI can assist
you. Project-specific context files are highly encouraged to establish
conventions and context.
- **Hierarchical loading and precedence:** The CLI implements a sophisticated
- **Hierarchical Loading and Precedence:** The CLI implements a sophisticated
hierarchical memory system by loading context files (e.g., `GEMINI.md`) from
several locations. Content from files lower in this list (more specific)
typically overrides or supplements content from files higher up (more
general). The exact concatenation order and final context can be inspected
using the `/memory show` command. The typical loading order is:
1. **Global context file:**
1. **Global Context File:**
- Location: `~/.gemini/<contextFileName>` (e.g., `~/.gemini/GEMINI.md` in
your user home directory).
- Scope: Provides default instructions for all your projects.
2. **Project root and ancestors context files:**
2. **Project Root & Ancestors Context Files:**
- Location: The CLI searches for the configured context file in the
current working directory and then in each parent directory up to either
the project root (identified by a `.git` folder) or your home directory.
- Scope: Provides context relevant to the entire project or a significant
portion of it.
3. **Sub-directory context files (contextual/local):**
3. **Sub-directory Context Files (Contextual/Local):**
- Location: The CLI also scans for the configured context file in
subdirectories _below_ the current working directory (respecting common
ignore patterns like `node_modules`, `.git`, etc.). The breadth of this
@@ -795,15 +797,15 @@ conventions and context.
with a `memoryDiscoveryMaxDirs` field in your `settings.json` file.
- Scope: Allows for highly specific instructions relevant to a particular
component, module, or subsection of your project.
- **Concatenation and UI indication:** The contents of all found context files
are concatenated (with separators indicating their origin and path) and
provided as part of the system prompt to the Gemini model. The CLI footer
displays the count of loaded context files, giving you a quick visual cue
about the active instructional context.
- **Importing content:** You can modularize your context files by importing
- **Concatenation & UI Indication:** The contents of all found context files are
concatenated (with separators indicating their origin and path) and provided
as part of the system prompt to the Gemini model. The CLI footer displays the
count of loaded context files, giving you a quick visual cue about the active
instructional context.
- **Importing Content:** You can modularize your context files by importing
other Markdown files using the `@path/to/file.md` syntax. For more details,
see the [Memory Import Processor documentation](../core/memport.md).
- **Commands for memory management:**
- **Commands for Memory Management:**
- Use `/memory refresh` to force a re-scan and reload of all context files
from all configured locations. This updates the AI's instructional context.
- Use `/memory show` to display the combined instructional context currently
@@ -850,7 +852,7 @@ sandbox image:
BUILD_SANDBOX=1 gemini -s
```
## Usage statistics
## Usage Statistics
To help us improve the Gemini CLI, we collect anonymized usage statistics. This
data helps us understand how the CLI is used, identify common issues, and
@@ -858,22 +860,22 @@ prioritize new features.
**What we collect:**
- **Tool calls:** We log the names of the tools that are called, whether they
- **Tool Calls:** We log the names of the tools that are called, whether they
succeed or fail, and how long they take to execute. We do not collect the
arguments passed to the tools or any data returned by them.
- **API requests:** We log the Gemini model used for each request, the duration
- **API Requests:** We log the Gemini model used for each request, the duration
of the request, and whether it was successful. We do not collect the content
of the prompts or responses.
- **Session information:** We collect information about the configuration of the
- **Session Information:** We collect information about the configuration of the
CLI, such as the enabled tools and the approval mode.
**What we DON'T collect:**
- **Personally identifiable information (PII):** We do not collect any personal
- **Personally Identifiable Information (PII):** We do not collect any personal
information, such as your name, email address, or API keys.
- **Prompt and response content:** We do not log the content of your prompts or
- **Prompt and Response Content:** We do not log the content of your prompts or
the responses from the Gemini model.
- **File content:** We do not log the content of any files that are read or
- **File Content:** We do not log the content of any files that are read or
written by the CLI.
**How to opt out:**
File diff suppressed because it is too large Load Diff

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