Compare commits

...

123 Commits

Author SHA1 Message Date
Christian Gunderman ef38202dbd feat(core): centralize line truncation and apply to all tools 2026-03-02 21:02:57 -08:00
Christian Gunderman 9850f01894 feat(core): centralize line truncation and apply to all tools 2026-03-02 18:48:56 -08:00
Aswin Ashok 0d69f9f7fa Build binary (#18933)
Co-authored-by: Gal Zahavi <38544478+galz10@users.noreply.github.com>
2026-03-03 01:02:19 +00:00
Christian Gunderman 46231a1755 ci(evals): only run evals in CI if prompts or tools changed (#20898)
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2026-03-03 00:29:31 +00:00
Sandy Tao 2e7722d6a3 fix(core): restrict "System: Please continue" invalid stream retry to Gemini 2 models (#20897) 2026-03-02 23:21:13 +00:00
Yuna Seol 69e15a50d1 fix(core): skip telemetry logging for AbortError exceptions (#19477)
Co-authored-by: Yuna Seol <yunaseol@google.com>
2026-03-02 23:14:31 +00:00
Christian Gunderman 25f59a0099 Add some dos and don'ts to behavioral evals README. (#20629) 2026-03-02 23:14:00 +00:00
Adib234 01927a36d1 feat(plan): support annotating plans with feedback for iteration (#20876) 2026-03-02 23:03:59 +00:00
Shreya Keshive 06ddfa5c4c feat(admin): enable 30 day default retention for chat history & remove warning (#20853) 2026-03-02 22:44:49 +00:00
Christian Gunderman 3f7ef816f1 fix(core): increase default headers timeout to 5 minutes (#20890) 2026-03-02 22:36:58 +00:00
Jerop Kipruto d05ba11a31 refactor(core): replace manual syncPlanModeTools with declarative policy rules (#20596) 2026-03-02 22:30:50 +00:00
Hamdanbinhashim e43b1cff58 docs: fix broken markdown links in main README.md (#20300) 2026-03-02 21:51:52 +00:00
Allen Hutchison bb6d1a2775 feat(core): add tool name validation in TOML policy files (#19281)
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2026-03-02 21:47:21 +00:00
Nayana Parameswarappa dd9ccc9807 Adding MCPOAuthProvider implementing the MCPSDK OAuthClientProvider (#20121) 2026-03-02 21:37:44 +00:00
Pyush Sinha 8133d63ac6 refactor(cli): fully remove React anti patterns, improve type safety and fix UX oversights in SettingsDialog.tsx (#18963)
Co-authored-by: Jacob Richman <jacob314@gmail.com>
2026-03-02 21:30:58 +00:00
Sandy Tao 18d0375a7f feat(core): support authenticated A2A agent card discovery (#20622)
Co-authored-by: Adam Weidman <adamfweidman@google.com>
Co-authored-by: Adam Weidman <65992621+adamfweidman@users.noreply.github.com>
2026-03-02 21:29:31 +00:00
Keith Guerin 31ca57ec94 feat: redesign header to be compact with ASCII icon (#18713)
Co-authored-by: Jacob Richman <jacob314@gmail.com>
2026-03-02 21:12:17 +00:00
Abhi b7a8f0d1f9 fix(core): ensure subagents use qualified MCP tool names (#20801) 2026-03-02 21:12:13 +00:00
Abdul Tawab 1502e5cbc3 style(cli) : Dialog pattern for /hooks Command (#17930) 2026-03-02 21:12:05 +00:00
Christian Gunderman 7ca3a33f8b Subagent activity UX. (#17570) 2026-03-02 21:04:31 +00:00
Sandy Tao ce5a2d0760 feat(core): truncate large MCP tool output (#19365) 2026-03-02 21:01:49 +00:00
Sam Roberts aa321b3d8c Update CODEOWNERS for README.md reviewers (#20860) 2026-03-02 20:54:05 +00:00
David Pierce 3a7a6e1540 Add install as an option when extension is selected. (#20358) 2026-03-02 20:41:16 +00:00
Tommaso Sciortino 66530e44c8 document node limitation for shift+tab (#20877) 2026-03-02 20:31:52 +00:00
Christian Gunderman b034dcd412 Do not block CI on evals (#20870) 2026-03-02 20:31:02 +00:00
Aishanee Shah 659301ff83 feat(core): centralize read_file limits and update gemini-3 description (#20619) 2026-03-02 20:11:58 +00:00
Sandy Tao 446a4316c4 feat(core): implement HTTP authentication support for A2A remote agents (#20510)
Co-authored-by: Adam Weidman <adamfweidman@google.com>
2026-03-02 19:59:48 +00:00
Tommaso Sciortino 48412a068e Add /unassign support (#20864)
Co-authored-by: Jacob Richman <jacob314@gmail.com>
2026-03-02 19:54:26 +00:00
Adib234 2e1efaebe4 fix(plan): deflake plan mode integration tests (#20477) 2026-03-02 19:51:44 +00:00
Sandy Tao 7c9fceba7f fix(core): reduce LLM-based loop detection false positives (#20701) 2026-03-02 19:08:15 +00:00
Adam Weidman 740efa2ac2 Merge User and Agent Card Descriptions #20849 (#20850) 2026-03-02 17:59:29 +00:00
Abhi 703759cfae fix(cli): allow sub-agent confirmation requests in UI while preventing background flicker (#20722) 2026-03-01 02:39:25 +00:00
Sehoon Shon 0063581e47 feat(skills): add github-issue-creator skill (#20709) 2026-02-28 23:22:22 +00:00
Sehoon Shon 6757d4b5c5 fix(cli): resolve autoThemeSwitching when background hasn't changed but theme mismatches (#20706) 2026-02-28 23:22:10 +00:00
Sandy Tao a153ff587b refactor(core): Extract tool parameter names as constants (#20460) 2026-02-28 21:27:54 +00:00
N. Taylor Mullen cd3a8c3f07 fix(cli): reset themeManager between tests to ensure isolation (#20598) 2026-02-28 19:45:31 +00:00
kartik b2214a6676 fix: acp/zed race condition between MCP initialisation and prompt (#20205)
Signed-off-by: Kartik Angiras <angiraskartik@gmail.com>
2026-02-28 17:33:08 +00:00
gemini-cli-robot 6c65a2d813 Changelog for v0.32.0-preview.0 (#20627)
Co-authored-by: gemini-cli-robot <224641728+gemini-cli-robot@users.noreply.github.com>
2026-02-28 16:03:50 +00:00
Jagjeevan Kashid fae0639ba2 fix: use full paths for ACP diff payloads (#19539)
Signed-off-by: Jagjeevan Kashid <jagjeevandev97@gmail.com>
2026-02-28 15:54:44 +00:00
gemini-cli-robot 76f70d65ff Changelog for v0.31.0 (#20634)
Co-authored-by: gemini-cli-robot <224641728+gemini-cli-robot@users.noreply.github.com>
2026-02-28 03:45:07 +00:00
gemini-cli-robot fb6ff847dd chore/release: bump version to 0.33.0-nightly.20260228.1ca5c05d0 (#20644) 2026-02-28 02:13:48 +00:00
Gal Zahavi 1ca5c05d0d fix(github): use robot PAT for automated PRs to pass CLA check (#20641) 2026-02-28 01:13:58 +00:00
Gal Zahavi 0c6c9c6a62 chore(release): bump version to 0.33.0-nightly.20260227.ba149afa0 (#20637) 2026-02-28 00:51:22 +00:00
Sehoon Shon a1367e9cdd fix(core): parse raw ASCII buffer strings in Gaxios errors (#20626) 2026-02-27 23:57:32 +00:00
Tommaso Sciortino c89d4f9c6c docs: add Windows PowerShell equivalents for environments and scripting (#20333) 2026-02-27 23:41:47 +00:00
Aditya Sharma 08ee136132 docs: fix typo in installation documentation (#20153) 2026-02-27 23:04:52 +00:00
Jenna Inouye 07f51c324e Docs: Update model docs to remove Preview Features. (#20084) 2026-02-27 22:28:06 +00:00
nityam ba149afa0b fix: merge duplicate imports in a2a-server package (2/4) (#19781) 2026-02-27 21:13:30 +00:00
nityam f6533c0250 fix: merge duplicate imports in sdk and test-utils packages (1/4) (#19777) 2026-02-27 21:13:15 +00:00
nityam 5e3b1fe945 Enforce import/no-duplicates as error (#19797) 2026-02-27 21:08:34 +00:00
Christian Gunderman 05ef2eb362 Promote stable tests to CI blocking. (#20581) 2026-02-27 21:08:12 +00:00
Abhi 966b9059d0 feat(core): enable contiguous parallel admission for Kind.Agent tools (#20583) 2026-02-27 21:08:10 +00:00
Francesco Camporeale ca13458412 docs: fix spelling typos in installation guide (#20579)
Co-authored-by: Jack Wotherspoon <jackwoth@google.com>
2026-02-27 20:36:38 +00:00
Spencer 20d884da2f fix(core): reduce intrusive MCP errors and deduplicate diagnostics (#20232) 2026-02-27 20:04:36 +00:00
Jenna Inouye 6a0f4d3bdd Docs: FAQ update (#20585) 2026-02-27 19:29:58 +00:00
Christian Gunderman 0b682538d2 Disable Gemini PR reviews on draft PRs. (#20362)
Co-authored-by: Jacob Richman <jacob314@gmail.com>
2026-02-27 19:25:33 +00:00
Dmitry Lyalin 7f8ce8657c Add low/full CLI error verbosity mode for cleaner UI (#20399) 2026-02-27 19:15:10 +00:00
gemini-cli-robot 1c8951334a Changelog for v0.30.1 (#20589)
Co-authored-by: gemini-cli-robot <224641728+gemini-cli-robot@users.noreply.github.com>
Co-authored-by: Sam Roberts <158088236+g-samroberts@users.noreply.github.com>
2026-02-27 19:11:32 +00:00
Christian Gunderman b2b6092c24 Add slash command for promoting behavioral evals to CI blocking (#20575)
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2026-02-27 19:11:30 +00:00
Jacob Richman e00e8f4728 fix(cli): Shell autocomplete polish (#20411) 2026-02-27 19:03:37 +00:00
gemini-cli-robot b2cbf518e8 Changelog for v0.31.0-preview.1 (#20590)
Co-authored-by: gemini-cli-robot <224641728+gemini-cli-robot@users.noreply.github.com>
2026-02-27 19:01:52 +00:00
Abhi c914fd0700 fix(cli): prevent sub-agent tool calls from leaking into UI (#20580) 2026-02-27 19:00:19 +00:00
Jerop Kipruto 5d24d6a9e1 fix(ui): persist expansion in AskUser dialog when navigating options (#20559) 2026-02-27 18:30:16 +00:00
Gaurav ea48bd9414 feat: better error messages (#20577)
Co-authored-by: Gal Zahavi <38544478+galz10@users.noreply.github.com>
2026-02-27 18:18:16 +00:00
Gaurav b2d6844f9b feat(billing): implement G1 AI credits overage flow with billing telemetry (#18590) 2026-02-27 18:15:06 +00:00
Sehoon Shon fdd844b405 fix(core): disable retries for code assist streaming requests (#20561) 2026-02-27 18:04:43 +00:00
Adib234 23905bcd77 fix(plan): prevent agent from using ask_user for shell command confirmation (#20504) 2026-02-27 17:51:47 +00:00
Dev Randalpura ec39aa17c2 Moved markdown parsing logic to a separate util file (#20526) 2026-02-27 17:43:18 +00:00
DeWitt Clinton 7a1f2f3288 Disable expensive and scheduled workflows on personal forks (#20449) 2026-02-27 17:40:09 +00:00
Abhijit Balaji 59c0e73718 feat(cli): add temporary flag to disable workspace policies (#20523) 2026-02-27 17:25:16 +00:00
Dmitry Lyalin 3b2632fe40 fix(cli): keep thought summary when loading phrases are off (#20497)
Co-authored-by: Jacob Richman <jacob314@gmail.com>
2026-02-27 17:11:13 +00:00
Sehoon Shon e709789067 fix(core): handle optional response fields from code assist API (#20345) 2026-02-27 16:52:37 +00:00
Christian Gunderman 514d431049 Demote unreliable test. (#20571) 2026-02-27 16:48:46 +00:00
Abhijit Balaji 32e777f838 fix(core): revert auto-save of policies to user space (#20531) 2026-02-27 16:03:36 +00:00
Jacob Richman 14dd07be00 fix(cli): ensure dialogs stay scrolled to bottom in alternate buffer mode (#20527) 2026-02-27 16:00:07 +00:00
Pyush Sinha d7320f5425 refactor(core,cli): useAlternateBuffer read from config (#20346)
Co-authored-by: Jacob Richman <jacob314@gmail.com>
2026-02-27 15:55:02 +00:00
Adib234 25ade7bcb7 feat(plan): update planning workflow to encourage multi-select with descriptions of options (#20491) 2026-02-27 15:42:37 +00:00
Jacob Richman ac4d0c20d8 fix(cli): hide shortcuts hint while model is thinking or the user has typed a prompt + add debounce to avoid flicker (#19389) 2026-02-27 15:34:49 +00:00
Jacob Richman 4d9cc36146 Fix flicker showing message to press ctrl-O again to collapse. (#20414)
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2026-02-27 15:07:14 +00:00
Jerop Kipruto 66b8922d66 feat(ui): add 'ctrl+o' hint to truncated content message (#20529) 2026-02-27 15:02:46 +00:00
christine betts 58df1c6237 Fix extension MCP server env var loading (#20374) 2026-02-27 14:49:10 +00:00
Bryan Morgan 522e95439c fix(core): apply retry logic to CodeAssistServer for all users (#20507) 2026-02-27 09:26:53 -05:00
Jacob Richman 82336de7a4 Fix bottom border rendering for search and add a regression test. (#20517) 2026-02-27 04:55:21 +00:00
Jenna Inouye 83a3851dfd Docs: Update to Terms of Service & FAQ (#20488)
Co-authored-by: Jerop Kipruto <jerop@google.com>
2026-02-27 04:14:57 +00:00
christine betts e17f927a69 Add support for policy engine in extensions (#20049)
Co-authored-by: Jerop Kipruto <jerop@google.com>
2026-02-27 03:29:33 +00:00
heaventourist b1befee8fb feat(telemetry) Instrument traces with more attributes and make them available to OTEL users (#20237)
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: Jerop Kipruto <jerop@google.com>
Co-authored-by: MD. MOHIBUR RAHMAN <35300157+mrpmohiburrahman@users.noreply.github.com>
Co-authored-by: Jeffrey Ying <jeffrey.ying86@live.com>
Co-authored-by: Bryan Morgan <bryanmorgan@google.com>
Co-authored-by: joshualitt <joshualitt@google.com>
Co-authored-by: Dev Randalpura <devrandalpura@google.com>
Co-authored-by: Google Admin <github-admin@google.com>
Co-authored-by: Ben Knutson <benknutson@google.com>
2026-02-27 02:26:16 +00:00
Tommaso Sciortino 4b7ce1fe67 Avoid overaggressive unescaping (#20520) 2026-02-27 01:50:21 +00:00
Dev Randalpura ecfa4e0437 fix(ui): correct styled table width calculations (#20042) 2026-02-27 01:31:21 +00:00
Jarrod Whelan 085441352b ui(cli): reduce length of Ctrl+O hint (#20490) 2026-02-27 00:57:38 +00:00
Jarrod Whelan 049d48ef60 test(cli): fix flaky ToolResultDisplay overflow test (#20518) 2026-02-27 00:30:43 +00:00
Adib234 bc622a443e docs(plan): update documentation regarding supporting editing of plan files during plan approval (#20452)
Co-authored-by: Jerop Kipruto <jerop@google.com>
2026-02-27 00:30:23 +00:00
Siddharth Diwan 9b7852f11c [Gemma x Gemini CLI] Add an Experimental Gemma Router that uses a LiteRT-LM shim into the Composite Model Classifier Strategy (#17231)
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: Allen Hutchison <adh@google.com>
2026-02-26 23:43:43 +00:00
Bryan Morgan 6dc9d5ff11 feat(core): increase fetch timeout and fix [object Object] error stringification (#20441)
Co-authored-by: Gal Zahavi <38544478+galz10@users.noreply.github.com>
2026-02-26 23:41:09 +00:00
Yuvraj Angad Singh b8d6041d42 fix: prevent orphaned processes from consuming 100% CPU when terminal closes (#16965)
Co-authored-by: Tommaso Sciortino <sciortino@gmail.com>
2026-02-26 23:17:09 +00:00
Jerop Kipruto aa98cafca7 feat(plan): adapt planning workflow based on complexity of task (#20465)
Co-authored-by: Gal Zahavi <38544478+galz10@users.noreply.github.com>
2026-02-26 22:58:19 +00:00
krishdef7 f700c923d9 fix(core): flush transcript for pure tool-call responses to ensure BeforeTool hooks see complete state (#20419)
Co-authored-by: Bryan Morgan <bryanmorgan@google.com>
2026-02-26 22:39:36 +00:00
Sehoon Shon edb1fdea30 fix(cli): support quota error fallbacks for all authentication types (#20475)
Co-authored-by: Gal Zahavi <38544478+galz10@users.noreply.github.com>
2026-02-26 22:39:25 +00:00
Adam Weidman 10c5bd8ce9 feat(core): improve A2A content extraction (#20487)
Co-authored-by: Gal Zahavi <38544478+galz10@users.noreply.github.com>
2026-02-26 22:38:30 +00:00
Gal Zahavi 9de8349cf0 fix: action var usage (#20492) 2026-02-26 22:06:09 +00:00
Jerop Kipruto 020da58327 fix(github): resolve actionlint and yamllint regressions from #19443 (#20467) 2026-02-26 11:31:31 -08:00
Google Admin ac454bcfbc Refactor Github Action per b/485167538 (#19443)
Co-authored-by: Ben Knutson <benknutson@google.com>
2026-02-26 12:58:14 -05:00
Dev Randalpura c7a70e6421 Updated tests in TableRenderer.test.tsx to use SVG snapshots (#20450) 2026-02-26 17:36:11 +00:00
joshualitt 611d934829 feat(core): Enable generalist agent (#19665) 2026-02-26 16:38:49 +00:00
Bryan Morgan 9c2fd5a7c6 feat(core): add HTTP 499 to retryable errors and map to RetryableQuotaError (#20432) 2026-02-26 15:42:34 +00:00
Jeffrey Ying 3db35812b7 fix(core): allow /memory add to work in plan mode (#20353) 2026-02-26 13:59:44 +00:00
MD. MOHIBUR RAHMAN 8380f0a3b1 feat(cli): implement interactive shell autocompletion (#20082) 2026-02-26 07:49:11 +00:00
Adib234 ef247e220d feat(plan): support opening and modifying plan in external editor (#20348) 2026-02-26 04:38:44 +00:00
Sandy Tao 39938000a9 feat(core): rename grep_search include parameter to include_pattern (#20328) 2026-02-26 04:16:21 +00:00
Abhijit Balaji d128fb0f7b feat(cli): hide workspace policy update dialog and auto-accept by default (#20351) 2026-02-26 04:05:19 +00:00
gemini-cli-robot 37903d5dbb Changelog for v0.31.0-preview.0 (#20249)
Co-authored-by: gemini-cli-robot <224641728+gemini-cli-robot@users.noreply.github.com>
Co-authored-by: Sam Roberts <158088236+g-samroberts@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: g-samroberts <samroberts@google.com>
2026-02-26 03:18:43 +00:00
Sam Roberts a3821a9440 Update changelog workflow to reject nightly builds (#20248) 2026-02-26 03:12:01 +00:00
gemini-cli-robot 0bf3a015e8 Changelog for v0.30.0 (#20252)
Co-authored-by: g-samroberts <158088236+g-samroberts@users.noreply.github.com>
Co-authored-by: g-samroberts <samroberts@google.com>
2026-02-26 01:11:36 +00:00
Abhi 28c9a907de feat(core): introduce Kind.Agent for sub-agent classification (#20369) 2026-02-26 01:04:20 +00:00
Jacob Richman f9f916e1dc test: support tests that include color information (#20220) 2026-02-25 23:31:35 +00:00
anj-s 78dfe9dea8 feat(core): implement task tracker foundation and service (#19464) 2026-02-25 23:17:17 +00:00
nityam c9d07b62f2 fix: remove trailing comma in issue triage workflow settings json (#20265) 2026-02-25 22:05:21 +00:00
joshualitt 189ab6c637 feat(core): Enable model steering in workspace. (#20343) 2026-02-25 21:18:40 +00:00
Tommaso Sciortino 4aec3cdb24 docs: remove legacy cmd examples in favor of powershell (#20323)
avoid flakes
2026-02-25 12:09:49 -08:00
Achal Jhawar b765fb8af4 fix(cli): expose model.name setting in settings dialog for persistence (#19605) 2026-02-25 19:56:05 +00:00
Himanshu Soni fb0c7d268f fix(cli): skip 404 errors in setup-github file downloads (#20287) 2026-02-25 18:45:02 +00:00
kevinjwang1 be12371380 Plumb the maxAttempts setting through Config args (#20239) 2026-02-25 17:58:07 +00:00
Tommaso Sciortino a037b961b1 feat(cli): load extensions in parallel (#20229) 2026-02-25 17:15:00 +00:00
Adam Weidman 6c739955c0 feat(core): implement robust A2A streaming reassembly and fix task continuity (#20091) 2026-02-25 16:51:08 +00:00
567 changed files with 29536 additions and 8151 deletions
@@ -0,0 +1,29 @@
description = "Promote behavioral evals that have a 100% success rate over the last 7 nightly runs."
prompt = """
You are an expert at analyzing and promoting behavioral evaluations.
1. **Investigate**:
- Use 'gh' cli to fetch the results from the most recent run from the main branch: https://github.com/google-gemini/gemini-cli/actions/workflows/evals-nightly.yml.
- DO NOT push any changes or start any runs. The rest of your evaluation will be local.
- Evals are in evals/ directory and are documented by evals/README.md.
- Identify tests that have passed 100% of the time for ALL enabled models across the past 7 runs in a row.
- NOTE: the results summary from the most recent run contains the last 7 runs test results. 100% means the test passed 3/3 times for that model and run.
- If a test meets this criteria, it is a candidate for promotion.
2. **Promote**:
- For each candidate test, locate the test file in the evals/ directory.
- Promote the test according to the project's standard promotion process (e.g., moving it to a stable suite, updating its tags, or removing skip/flaky annotations).
- Ensure you follow any guidelines in evals/README.md for stable tests.
- Your **final** change should be **minimal and targeted** to just promoting the test status.
3. **Verify**:
- Run the promoted tests locally to validate that they still execute correctly. Be sure to run vitest in non-interactive mode.
- Check that the test is now part of the expected standard or stable test suites.
4. **Report**:
- Provide a summary of the tests that were promoted.
- Include the success rate evidence (7/7 runs passed for all models) for each promoted test.
- If no tests met the criteria for promotion, clearly state that and summarize the closest candidates.
{{args}}
"""
+1
View File
@@ -9,4 +9,5 @@ code_review:
help: false help: false
summary: true summary: true
code_review: true code_review: true
include_drafts: false
ignore_patterns: [] ignore_patterns: []
+2 -1
View File
@@ -1,7 +1,8 @@
{ {
"experimental": { "experimental": {
"plan": true, "plan": true,
"extensionReloading": true "extensionReloading": true,
"modelSteering": true
}, },
"general": { "general": {
"devtools": true "devtools": true
+19 -6
View File
@@ -59,6 +59,10 @@ To standardize the process of updating changelog files (`latest.md`,
*Use this path if the version number ends in `.0`.* *Use this path if the version number ends in `.0`.*
**Important:** Based on the version, you must choose to follow either section
A.1 for stable releases or A.2 for preview releases. Do not follow the
instructions for the other section.
### A.1: Stable Release (e.g., `v0.28.0`) ### A.1: Stable Release (e.g., `v0.28.0`)
For a stable release, you will generate two distinct summaries from the For a stable release, you will generate two distinct summaries from the
@@ -73,7 +77,8 @@ detailed **highlights** section for the release-specific page.
use the existing announcements in `docs/changelogs/index.md` and the use the existing announcements in `docs/changelogs/index.md` and the
example within example within
`.gemini/skills/docs-changelog/references/index_template.md` as your `.gemini/skills/docs-changelog/references/index_template.md` as your
guide. This format includes PR links and authors. guide. This format includes PR links and authors. Stick to 1 or 2 PR
links and authors.
- Add this new announcement to the top of `docs/changelogs/index.md`. - Add this new announcement to the top of `docs/changelogs/index.md`.
2. **Create Highlights and Update `latest.md`**: 2. **Create Highlights and Update `latest.md`**:
@@ -105,6 +110,10 @@ detailed **highlights** section for the release-specific page.
*Use this path if the version number does **not** end in `.0`.* *Use this path if the version number does **not** end in `.0`.*
**Important:** Based on the version, you must choose to follow either section
B.1 for stable patches or B.2 for preview patches. Do not follow the
instructions for the other section.
### B.1: Stable Patch (e.g., `v0.28.1`) ### B.1: Stable Patch (e.g., `v0.28.1`)
- **Target File**: `docs/changelogs/latest.md` - **Target File**: `docs/changelogs/latest.md`
@@ -113,10 +122,12 @@ detailed **highlights** section for the release-specific page.
`# Latest stable release: {{version}}` `# Latest stable release: {{version}}`
2. Update the rease date. The line should read, 2. Update the rease date. The line should read,
`Released: {{release_date_month_dd_yyyy}}` `Released: {{release_date_month_dd_yyyy}}`
3. **Prepend** the processed "What's Changed" list from the temporary file 3. Determine if a "What's Changed" section exists in the temporary file
If so, continue to step 4. Otherwise, skip to step 5.
4. **Prepend** the processed "What's Changed" list from the temporary file
to the existing "What's Changed" list in `latest.md`. Do not change or to the existing "What's Changed" list in `latest.md`. Do not change or
replace the existing list, **only add** to the beginning of it. replace the existing list, **only add** to the beginning of it.
4. In the "Full Changelog", edit **only** the end of the URL. Identify the 5. In the "Full Changelog", edit **only** the end of the URL. Identify the
last part of the URL that looks like `...{previous_version}` and update last part of the URL that looks like `...{previous_version}` and update
it to be `...{version}`. it to be `...{version}`.
@@ -133,10 +144,12 @@ detailed **highlights** section for the release-specific page.
`# Preview release: {{version}}` `# Preview release: {{version}}`
2. Update the rease date. The line should read, 2. Update the rease date. The line should read,
`Released: {{release_date_month_dd_yyyy}}` `Released: {{release_date_month_dd_yyyy}}`
3. **Prepend** the processed "What's Changed" list from the temporary file 3. Determine if a "What's Changed" section exists in the temporary file
If so, continue to step 4. Otherwise, skip to step 5.
4. **Prepend** the processed "What's Changed" list from the temporary file
to the existing "What's Changed" list in `preview.md`. Do not change or to the existing "What's Changed" list in `preview.md`. Do not change or
replace the existing list, **only add** to the beginning of it. replace the existing list, **only add** to the beginning of it.
4. In the "Full Changelog", edit **only** the end of the URL. Identify the 5. In the "Full Changelog", edit **only** the end of the URL. Identify the
last part of the URL that looks like `...{previous_version}` and update last part of the URL that looks like `...{previous_version}` and update
it to be `...{version}`. it to be `...{version}`.
@@ -149,5 +162,5 @@ detailed **highlights** section for the release-specific page.
## Finalize ## Finalize
- After making changes, run `npm run format` to ensure consistency. - After making changes, run `npm run format` ONLY to ensure consistency.
- Delete any temporary files created during the process. - Delete any temporary files created during the process.
@@ -0,0 +1,76 @@
---
name: github-issue-creator
description:
Use this skill when asked to create a GitHub issue. It handles different issue
types (bug, feature, etc.) using repository templates and ensures proper
labeling.
---
# GitHub Issue Creator
This skill guides the creation of high-quality GitHub issues that adhere to the
repository's standards and use the appropriate templates.
## Workflow
Follow these steps to create a GitHub issue:
1. **Identify Issue Type**: Determine if the request is a bug report, feature
request, or other category.
2. **Locate Template**: Search for issue templates in
`.github/ISSUE_TEMPLATE/`.
- `bug_report.yml`
- `feature_request.yml`
- `website_issue.yml`
- If no relevant YAML template is found, look for `.md` templates in the same
directory.
3. **Read Template**: Read the content of the identified template file to
understand the required fields.
4. **Draft Content**: Draft the issue title and body/fields.
- If using a YAML template (form), prepare values for each `id` defined in
the template.
- If using a Markdown template, follow its structure exactly.
- **Default Label**: Always include the `🔒 maintainer only` label unless the
user explicitly requests otherwise.
5. **Create Issue**: Use the `gh` CLI to create the issue.
- **CRITICAL:** To avoid shell escaping and formatting issues with
multi-line Markdown or complex text, ALWAYS write the description/body to
a temporary file first.
**For Markdown Templates or Simple Body:**
```bash
# 1. Write the drafted content to a temporary file
# 2. Create the issue using the --body-file flag
gh issue create --title "Succinct title" --body-file <temp_file_path> --label "🔒 maintainer only"
# 3. Remove the temporary file
rm <temp_file_path>
```
**For YAML Templates (Forms):**
While `gh issue create` supports `--body-file`, YAML forms usually expect
key-value pairs via flags if you want to bypass the interactive prompt.
However, the most reliable non-interactive way to ensure formatting is
preserved for long text fields is to use the `--body` or `--body-file` if the
form has been converted to a standard body, OR to use the `--field` flags
for YAML forms.
*Note: For the `gemini-cli` repository which uses YAML forms, you can often
submit the content as a single body if a specific field-based submission is
not required by the automation.*
6. **Verify**: Confirm the issue was created successfully and provide the link
to the user.
## Principles
- **Clarity**: Titles should be descriptive and follow project conventions.
- **Defensive Formatting**: Always use temporary files with `--body-file` to
prevent newline and special character issues.
- **Maintainer Priority**: Default to internal/maintainer labels to keep the
backlog organized.
- **Completeness**: Provide all requested information (e.g., version info,
reproduction steps).
+1
View File
@@ -14,3 +14,4 @@
# Docs have a dedicated approver group in addition to maintainers # Docs have a dedicated approver group in addition to maintainers
/docs/ @google-gemini/gemini-cli-maintainers @google-gemini/gemini-cli-docs /docs/ @google-gemini/gemini-cli-maintainers @google-gemini/gemini-cli-docs
/README.md @google-gemini/gemini-cli-maintainers @google-gemini/gemini-cli-docs
+10 -6
View File
@@ -39,18 +39,22 @@ runs:
if: "inputs.dry-run != 'true'" if: "inputs.dry-run != 'true'"
env: env:
GH_TOKEN: '${{ inputs.github-token }}' GH_TOKEN: '${{ inputs.github-token }}'
INPUTS_BRANCH_NAME: '${{ inputs.branch-name }}'
INPUTS_PR_TITLE: '${{ inputs.pr-title }}'
INPUTS_PR_BODY: '${{ inputs.pr-body }}'
INPUTS_BASE_BRANCH: '${{ inputs.base-branch }}'
shell: 'bash' shell: 'bash'
working-directory: '${{ inputs.working-directory }}' working-directory: '${{ inputs.working-directory }}'
run: | run: |
set -e set -e
if ! git ls-remote --exit-code --heads origin "${{ inputs.branch-name }}"; then if ! git ls-remote --exit-code --heads origin "${INPUTS_BRANCH_NAME}"; then
echo "::error::Branch '${{ inputs.branch-name }}' does not exist on the remote repository." echo "::error::Branch '${INPUTS_BRANCH_NAME}' does not exist on the remote repository."
exit 1 exit 1
fi fi
PR_URL=$(gh pr create \ PR_URL=$(gh pr create \
--title "${{ inputs.pr-title }}" \ --title "${INPUTS_PR_TITLE}" \
--body "${{ inputs.pr-body }}" \ --body "${INPUTS_PR_BODY}" \
--base "${{ inputs.base-branch }}" \ --base "${INPUTS_BASE_BRANCH}" \
--head "${{ inputs.branch-name }}" \ --head "${INPUTS_BRANCH_NAME}" \
--fill) --fill)
gh pr merge "$PR_URL" --auto gh pr merge "$PR_URL" --auto
+12 -6
View File
@@ -30,16 +30,22 @@ runs:
id: 'npm_auth_token' id: 'npm_auth_token'
shell: 'bash' shell: 'bash'
run: | run: |
AUTH_TOKEN="${{ inputs.github-token }}" AUTH_TOKEN="${INPUTS_GITHUB_TOKEN}"
PACKAGE_NAME="${{ inputs.package-name }}" PACKAGE_NAME="${INPUTS_PACKAGE_NAME}"
PRIVATE_REPO="@google-gemini/" PRIVATE_REPO="@google-gemini/"
if [[ "$PACKAGE_NAME" == "$PRIVATE_REPO"* ]]; then if [[ "$PACKAGE_NAME" == "$PRIVATE_REPO"* ]]; then
AUTH_TOKEN="${{ inputs.github-token }}" AUTH_TOKEN="${INPUTS_GITHUB_TOKEN}"
elif [[ "$PACKAGE_NAME" == "@google/gemini-cli" ]]; then elif [[ "$PACKAGE_NAME" == "@google/gemini-cli" ]]; then
AUTH_TOKEN="${{ inputs.wombat-token-cli }}" AUTH_TOKEN="${INPUTS_WOMBAT_TOKEN_CLI}"
elif [[ "$PACKAGE_NAME" == "@google/gemini-cli-core" ]]; then elif [[ "$PACKAGE_NAME" == "@google/gemini-cli-core" ]]; then
AUTH_TOKEN="${{ inputs.wombat-token-core }}" AUTH_TOKEN="${INPUTS_WOMBAT_TOKEN_CORE}"
elif [[ "$PACKAGE_NAME" == "@google/gemini-cli-a2a-server" ]]; then elif [[ "$PACKAGE_NAME" == "@google/gemini-cli-a2a-server" ]]; then
AUTH_TOKEN="${{ inputs.wombat-token-a2a-server }}" AUTH_TOKEN="${INPUTS_WOMBAT_TOKEN_A2A_SERVER}"
fi fi
echo "auth-token=$AUTH_TOKEN" >> $GITHUB_OUTPUT echo "auth-token=$AUTH_TOKEN" >> $GITHUB_OUTPUT
env:
INPUTS_GITHUB_TOKEN: '${{ inputs.github-token }}'
INPUTS_PACKAGE_NAME: '${{ inputs.package-name }}'
INPUTS_WOMBAT_TOKEN_CLI: '${{ inputs.wombat-token-cli }}'
INPUTS_WOMBAT_TOKEN_CORE: '${{ inputs.wombat-token-core }}'
INPUTS_WOMBAT_TOKEN_A2A_SERVER: '${{ inputs.wombat-token-a2a-server }}'
+41 -20
View File
@@ -93,15 +93,19 @@ runs:
id: 'release_branch' id: 'release_branch'
shell: 'bash' shell: 'bash'
run: | run: |
BRANCH_NAME="release/${{ inputs.release-tag }}" BRANCH_NAME="release/${INPUTS_RELEASE_TAG}"
git switch -c "${BRANCH_NAME}" git switch -c "${BRANCH_NAME}"
echo "BRANCH_NAME=${BRANCH_NAME}" >> "${GITHUB_OUTPUT}" echo "BRANCH_NAME=${BRANCH_NAME}" >> "${GITHUB_OUTPUT}"
env:
INPUTS_RELEASE_TAG: '${{ inputs.release-tag }}'
- name: '⬆️ Update package versions' - name: '⬆️ Update package versions'
working-directory: '${{ inputs.working-directory }}' working-directory: '${{ inputs.working-directory }}'
shell: 'bash' shell: 'bash'
run: | run: |
npm run release:version "${{ inputs.release-version }}" npm run release:version "${INPUTS_RELEASE_VERSION}"
env:
INPUTS_RELEASE_VERSION: '${{ inputs.release-version }}'
- name: '💾 Commit and Conditionally Push package versions' - name: '💾 Commit and Conditionally Push package versions'
working-directory: '${{ inputs.working-directory }}' working-directory: '${{ inputs.working-directory }}'
@@ -163,23 +167,30 @@ runs:
working-directory: '${{ inputs.working-directory }}' working-directory: '${{ inputs.working-directory }}'
env: env:
NODE_AUTH_TOKEN: '${{ steps.core-token.outputs.auth-token }}' NODE_AUTH_TOKEN: '${{ steps.core-token.outputs.auth-token }}'
INPUTS_DRY_RUN: '${{ inputs.dry-run }}'
INPUTS_CORE_PACKAGE_NAME: '${{ inputs.core-package-name }}'
shell: 'bash' shell: 'bash'
run: | run: |
npm publish \ npm publish \
--dry-run="${{ inputs.dry-run }}" \ --dry-run="${INPUTS_DRY_RUN}" \
--workspace="${{ inputs.core-package-name }}" \ --workspace="${INPUTS_CORE_PACKAGE_NAME}" \
--no-tag --no-tag
npm dist-tag rm ${{ inputs.core-package-name }} false --silent npm dist-tag rm ${INPUTS_CORE_PACKAGE_NAME} false --silent
- name: '🔗 Install latest core package' - name: '🔗 Install latest core package'
working-directory: '${{ inputs.working-directory }}' working-directory: '${{ inputs.working-directory }}'
if: "${{ inputs.dry-run != 'true' }}" if: "${{ inputs.dry-run != 'true' }}"
shell: 'bash' shell: 'bash'
run: | run: |
npm install "${{ inputs.core-package-name }}@${{ inputs.release-version }}" \ npm install "${INPUTS_CORE_PACKAGE_NAME}@${INPUTS_RELEASE_VERSION}" \
--workspace="${{ inputs.cli-package-name }}" \ --workspace="${INPUTS_CLI_PACKAGE_NAME}" \
--workspace="${{ inputs.a2a-package-name }}" \ --workspace="${INPUTS_A2A_PACKAGE_NAME}" \
--save-exact --save-exact
env:
INPUTS_CORE_PACKAGE_NAME: '${{ inputs.core-package-name }}'
INPUTS_RELEASE_VERSION: '${{ inputs.release-version }}'
INPUTS_CLI_PACKAGE_NAME: '${{ inputs.cli-package-name }}'
INPUTS_A2A_PACKAGE_NAME: '${{ inputs.a2a-package-name }}'
- name: 'Get CLI Token' - name: 'Get CLI Token'
uses: './.github/actions/npm-auth-token' uses: './.github/actions/npm-auth-token'
@@ -195,13 +206,15 @@ runs:
working-directory: '${{ inputs.working-directory }}' working-directory: '${{ inputs.working-directory }}'
env: env:
NODE_AUTH_TOKEN: '${{ steps.cli-token.outputs.auth-token }}' NODE_AUTH_TOKEN: '${{ steps.cli-token.outputs.auth-token }}'
INPUTS_DRY_RUN: '${{ inputs.dry-run }}'
INPUTS_CLI_PACKAGE_NAME: '${{ inputs.cli-package-name }}'
shell: 'bash' shell: 'bash'
run: | run: |
npm publish \ npm publish \
--dry-run="${{ inputs.dry-run }}" \ --dry-run="${INPUTS_DRY_RUN}" \
--workspace="${{ inputs.cli-package-name }}" \ --workspace="${INPUTS_CLI_PACKAGE_NAME}" \
--no-tag --no-tag
npm dist-tag rm ${{ inputs.cli-package-name }} false --silent npm dist-tag rm ${INPUTS_CLI_PACKAGE_NAME} false --silent
- name: 'Get a2a-server Token' - name: 'Get a2a-server Token'
uses: './.github/actions/npm-auth-token' uses: './.github/actions/npm-auth-token'
@@ -217,14 +230,16 @@ runs:
working-directory: '${{ inputs.working-directory }}' working-directory: '${{ inputs.working-directory }}'
env: env:
NODE_AUTH_TOKEN: '${{ steps.a2a-token.outputs.auth-token }}' NODE_AUTH_TOKEN: '${{ steps.a2a-token.outputs.auth-token }}'
INPUTS_DRY_RUN: '${{ inputs.dry-run }}'
INPUTS_A2A_PACKAGE_NAME: '${{ inputs.a2a-package-name }}'
shell: 'bash' shell: 'bash'
# Tag staging for initial release # Tag staging for initial release
run: | run: |
npm publish \ npm publish \
--dry-run="${{ inputs.dry-run }}" \ --dry-run="${INPUTS_DRY_RUN}" \
--workspace="${{ inputs.a2a-package-name }}" \ --workspace="${INPUTS_A2A_PACKAGE_NAME}" \
--no-tag --no-tag
npm dist-tag rm ${{ inputs.a2a-package-name }} false --silent npm dist-tag rm ${INPUTS_A2A_PACKAGE_NAME} false --silent
- name: '🔬 Verify NPM release by version' - name: '🔬 Verify NPM release by version'
uses: './.github/actions/verify-release' uses: './.github/actions/verify-release'
@@ -258,13 +273,16 @@ runs:
if: "${{ inputs.dry-run != 'true' && inputs.skip-github-release != 'true' && inputs.npm-tag != 'dev' && inputs.npm-registry-url != 'https://npm.pkg.github.com/' }}" if: "${{ inputs.dry-run != 'true' && inputs.skip-github-release != 'true' && inputs.npm-tag != 'dev' && inputs.npm-registry-url != 'https://npm.pkg.github.com/' }}"
env: env:
GITHUB_TOKEN: '${{ inputs.github-release-token || inputs.github-token }}' GITHUB_TOKEN: '${{ inputs.github-release-token || inputs.github-token }}'
INPUTS_RELEASE_TAG: '${{ inputs.release-tag }}'
STEPS_RELEASE_BRANCH_OUTPUTS_BRANCH_NAME: '${{ steps.release_branch.outputs.BRANCH_NAME }}'
INPUTS_PREVIOUS_TAG: '${{ inputs.previous-tag }}'
shell: 'bash' shell: 'bash'
run: | run: |
gh release create "${{ inputs.release-tag }}" \ gh release create "${INPUTS_RELEASE_TAG}" \
bundle/gemini.js \ bundle/gemini.js \
--target "${{ steps.release_branch.outputs.BRANCH_NAME }}" \ --target "${STEPS_RELEASE_BRANCH_OUTPUTS_BRANCH_NAME}" \
--title "Release ${{ inputs.release-tag }}" \ --title "Release ${INPUTS_RELEASE_TAG}" \
--notes-start-tag "${{ inputs.previous-tag }}" \ --notes-start-tag "${INPUTS_PREVIOUS_TAG}" \
--generate-notes \ --generate-notes \
${{ inputs.npm-tag != 'latest' && '--prerelease' || '' }} ${{ inputs.npm-tag != 'latest' && '--prerelease' || '' }}
@@ -274,5 +292,8 @@ runs:
continue-on-error: true continue-on-error: true
shell: 'bash' shell: 'bash'
run: | run: |
echo "Cleaning up release branch ${{ steps.release_branch.outputs.BRANCH_NAME }}..." echo "Cleaning up release branch ${STEPS_RELEASE_BRANCH_OUTPUTS_BRANCH_NAME}..."
git push origin --delete "${{ steps.release_branch.outputs.BRANCH_NAME }}" git push origin --delete "${STEPS_RELEASE_BRANCH_OUTPUTS_BRANCH_NAME}"
env:
STEPS_RELEASE_BRANCH_OUTPUTS_BRANCH_NAME: '${{ steps.release_branch.outputs.BRANCH_NAME }}'
+3 -1
View File
@@ -52,8 +52,10 @@ runs:
id: 'branch_name' id: 'branch_name'
shell: 'bash' shell: 'bash'
run: | run: |
REF_NAME="${{ inputs.ref-name }}" REF_NAME="${INPUTS_REF_NAME}"
echo "name=${REF_NAME%/merge}" >> $GITHUB_OUTPUT echo "name=${REF_NAME%/merge}" >> $GITHUB_OUTPUT
env:
INPUTS_REF_NAME: '${{ inputs.ref-name }}'
- name: 'Build and Push the Docker Image' - name: 'Build and Push the Docker Image'
uses: 'docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83' # ratchet:docker/build-push-action@v6 uses: 'docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83' # ratchet:docker/build-push-action@v6
with: with:
+10 -4
View File
@@ -56,8 +56,8 @@ runs:
id: 'image_tag' id: 'image_tag'
shell: 'bash' shell: 'bash'
run: |- run: |-
SHELL_TAG_NAME="${{ inputs.github-ref-name }}" SHELL_TAG_NAME="${INPUTS_GITHUB_REF_NAME}"
FINAL_TAG="${{ inputs.github-sha }}" FINAL_TAG="${INPUTS_GITHUB_SHA}"
if [[ "$SHELL_TAG_NAME" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.-]+)?$ ]]; then if [[ "$SHELL_TAG_NAME" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.-]+)?$ ]]; then
echo "Release detected." echo "Release detected."
FINAL_TAG="${SHELL_TAG_NAME#v}" FINAL_TAG="${SHELL_TAG_NAME#v}"
@@ -66,15 +66,19 @@ runs:
fi fi
echo "Determined image tag: $FINAL_TAG" echo "Determined image tag: $FINAL_TAG"
echo "FINAL_TAG=$FINAL_TAG" >> $GITHUB_OUTPUT echo "FINAL_TAG=$FINAL_TAG" >> $GITHUB_OUTPUT
env:
INPUTS_GITHUB_REF_NAME: '${{ inputs.github-ref-name }}'
INPUTS_GITHUB_SHA: '${{ inputs.github-sha }}'
- name: 'build' - name: 'build'
id: 'docker_build' id: 'docker_build'
shell: 'bash' shell: 'bash'
env: env:
GEMINI_SANDBOX_IMAGE_TAG: '${{ steps.image_tag.outputs.FINAL_TAG }}' GEMINI_SANDBOX_IMAGE_TAG: '${{ steps.image_tag.outputs.FINAL_TAG }}'
GEMINI_SANDBOX: 'docker' GEMINI_SANDBOX: 'docker'
STEPS_IMAGE_TAG_OUTPUTS_FINAL_TAG: '${{ steps.image_tag.outputs.FINAL_TAG }}'
run: |- run: |-
npm run build:sandbox -- \ npm run build:sandbox -- \
--image google/gemini-cli-sandbox:${{ steps.image_tag.outputs.FINAL_TAG }} \ --image google/gemini-cli-sandbox:${STEPS_IMAGE_TAG_OUTPUTS_FINAL_TAG} \
--output-file final_image_uri.txt --output-file final_image_uri.txt
echo "uri=$(cat final_image_uri.txt)" >> $GITHUB_OUTPUT echo "uri=$(cat final_image_uri.txt)" >> $GITHUB_OUTPUT
- name: 'verify' - name: 'verify'
@@ -89,7 +93,9 @@ runs:
shell: 'bash' shell: 'bash'
if: "${{ inputs.dry-run != 'true' }}" if: "${{ inputs.dry-run != 'true' }}"
run: |- run: |-
docker push "${{ steps.docker_build.outputs.uri }}" docker push "${STEPS_DOCKER_BUILD_OUTPUTS_URI}"
env:
STEPS_DOCKER_BUILD_OUTPUTS_URI: '${{ steps.docker_build.outputs.uri }}'
- name: 'Create issue on failure' - name: 'Create issue on failure'
if: |- if: |-
${{ failure() }} ${{ failure() }}
+3 -1
View File
@@ -18,5 +18,7 @@ runs:
shell: 'bash' shell: 'bash'
run: |- run: |-
echo ""@google-gemini:registry=https://npm.pkg.github.com"" > ~/.npmrc echo ""@google-gemini:registry=https://npm.pkg.github.com"" > ~/.npmrc
echo ""//npm.pkg.github.com/:_authToken=${{ inputs.github-token }}"" >> ~/.npmrc echo ""//npm.pkg.github.com/:_authToken=${INPUTS_GITHUB_TOKEN}"" >> ~/.npmrc
echo ""@google:registry=https://wombat-dressing-room.appspot.com"" >> ~/.npmrc echo ""@google:registry=https://wombat-dressing-room.appspot.com"" >> ~/.npmrc
env:
INPUTS_GITHUB_TOKEN: '${{ inputs.github-token }}'
+24 -4
View File
@@ -71,10 +71,13 @@ runs:
${{ inputs.dry-run != 'true' }} ${{ inputs.dry-run != 'true' }}
env: env:
NODE_AUTH_TOKEN: '${{ steps.core-token.outputs.auth-token }}' NODE_AUTH_TOKEN: '${{ steps.core-token.outputs.auth-token }}'
INPUTS_CORE_PACKAGE_NAME: '${{ inputs.core-package-name }}'
INPUTS_VERSION: '${{ inputs.version }}'
INPUTS_CHANNEL: '${{ inputs.channel }}'
shell: 'bash' shell: 'bash'
working-directory: '${{ inputs.working-directory }}' working-directory: '${{ inputs.working-directory }}'
run: | run: |
npm dist-tag add ${{ inputs.core-package-name }}@${{ inputs.version }} ${{ inputs.channel }} npm dist-tag add ${INPUTS_CORE_PACKAGE_NAME}@${INPUTS_VERSION} ${INPUTS_CHANNEL}
- name: 'Get cli Token' - name: 'Get cli Token'
uses: './.github/actions/npm-auth-token' uses: './.github/actions/npm-auth-token'
@@ -91,10 +94,13 @@ runs:
${{ inputs.dry-run != 'true' }} ${{ inputs.dry-run != 'true' }}
env: env:
NODE_AUTH_TOKEN: '${{ steps.cli-token.outputs.auth-token }}' NODE_AUTH_TOKEN: '${{ steps.cli-token.outputs.auth-token }}'
INPUTS_CLI_PACKAGE_NAME: '${{ inputs.cli-package-name }}'
INPUTS_VERSION: '${{ inputs.version }}'
INPUTS_CHANNEL: '${{ inputs.channel }}'
shell: 'bash' shell: 'bash'
working-directory: '${{ inputs.working-directory }}' working-directory: '${{ inputs.working-directory }}'
run: | run: |
npm dist-tag add ${{ inputs.cli-package-name }}@${{ inputs.version }} ${{ inputs.channel }} npm dist-tag add ${INPUTS_CLI_PACKAGE_NAME}@${INPUTS_VERSION} ${INPUTS_CHANNEL}
- name: 'Get a2a Token' - name: 'Get a2a Token'
uses: './.github/actions/npm-auth-token' uses: './.github/actions/npm-auth-token'
@@ -111,10 +117,13 @@ runs:
${{ inputs.dry-run == 'false' }} ${{ inputs.dry-run == 'false' }}
env: env:
NODE_AUTH_TOKEN: '${{ steps.a2a-token.outputs.auth-token }}' NODE_AUTH_TOKEN: '${{ steps.a2a-token.outputs.auth-token }}'
INPUTS_A2A_PACKAGE_NAME: '${{ inputs.a2a-package-name }}'
INPUTS_VERSION: '${{ inputs.version }}'
INPUTS_CHANNEL: '${{ inputs.channel }}'
shell: 'bash' shell: 'bash'
working-directory: '${{ inputs.working-directory }}' working-directory: '${{ inputs.working-directory }}'
run: | run: |
npm dist-tag add ${{ inputs.a2a-package-name }}@${{ inputs.version }} ${{ inputs.channel }} npm dist-tag add ${INPUTS_A2A_PACKAGE_NAME}@${INPUTS_VERSION} ${INPUTS_CHANNEL}
- name: 'Log dry run' - name: 'Log dry run'
if: |- if: |-
@@ -122,4 +131,15 @@ runs:
shell: 'bash' shell: 'bash'
working-directory: '${{ inputs.working-directory }}' working-directory: '${{ inputs.working-directory }}'
run: | run: |
echo "Dry run: Would have added tag '${{ inputs.channel }}' to version '${{ inputs.version }}' for ${{ inputs.cli-package-name }}, ${{ inputs.core-package-name }}, and ${{ inputs.a2a-package-name }}." echo "Dry run: Would have added tag '${INPUTS_CHANNEL}' to version '${INPUTS_VERSION}' for ${INPUTS_CLI_PACKAGE_NAME}, ${INPUTS_CORE_PACKAGE_NAME}, and ${INPUTS_A2A_PACKAGE_NAME}."
env:
INPUTS_CHANNEL: '${{ inputs.channel }}'
INPUTS_VERSION: '${{ inputs.version }}'
INPUTS_CLI_PACKAGE_NAME: '${{ inputs.cli-package-name }}'
INPUTS_CORE_PACKAGE_NAME: '${{ inputs.core-package-name }}'
INPUTS_A2A_PACKAGE_NAME: '${{ inputs.a2a-package-name }}'
+11 -5
View File
@@ -64,10 +64,13 @@ runs:
working-directory: '${{ inputs.working-directory }}' working-directory: '${{ inputs.working-directory }}'
run: |- run: |-
gemini_version=$(gemini --version) gemini_version=$(gemini --version)
if [ "$gemini_version" != "${{ inputs.expected-version }}" ]; then if [ "$gemini_version" != "${INPUTS_EXPECTED_VERSION}" ]; then
echo "❌ NPM Version mismatch: Got $gemini_version from ${{ inputs.npm-package }}, expected ${{ inputs.expected-version }}" echo "❌ NPM Version mismatch: Got $gemini_version from ${INPUTS_NPM_PACKAGE}, expected ${INPUTS_EXPECTED_VERSION}"
exit 1 exit 1
fi fi
env:
INPUTS_EXPECTED_VERSION: '${{ inputs.expected-version }}'
INPUTS_NPM_PACKAGE: '${{ inputs.npm-package }}'
- name: 'Clear npm cache' - name: 'Clear npm cache'
shell: 'bash' shell: 'bash'
@@ -77,11 +80,14 @@ runs:
shell: 'bash' shell: 'bash'
working-directory: '${{ inputs.working-directory }}' working-directory: '${{ inputs.working-directory }}'
run: |- run: |-
gemini_version=$(npx --prefer-online "${{ inputs.npm-package}}" --version) gemini_version=$(npx --prefer-online "${INPUTS_NPM_PACKAGE}" --version)
if [ "$gemini_version" != "${{ inputs.expected-version }}" ]; then if [ "$gemini_version" != "${INPUTS_EXPECTED_VERSION}" ]; then
echo "❌ NPX Run Version mismatch: Got $gemini_version from ${{ inputs.npm-package }}, expected ${{ inputs.expected-version }}" echo "❌ NPX Run Version mismatch: Got $gemini_version from ${INPUTS_NPM_PACKAGE}, expected ${INPUTS_EXPECTED_VERSION}"
exit 1 exit 1
fi fi
env:
INPUTS_NPM_PACKAGE: '${{ inputs.npm-package }}'
INPUTS_EXPECTED_VERSION: '${{ inputs.expected-version }}'
- name: 'Install dependencies for integration tests' - name: 'Install dependencies for integration tests'
shell: 'bash' shell: 'bash'
+30 -16
View File
@@ -31,6 +31,7 @@ jobs:
name: 'Merge Queue Skipper' name: 'Merge Queue Skipper'
permissions: 'read-all' permissions: 'read-all'
runs-on: 'gemini-cli-ubuntu-16-core' runs-on: 'gemini-cli-ubuntu-16-core'
if: "github.repository == 'google-gemini/gemini-cli'"
outputs: outputs:
skip: '${{ steps.merge-queue-e2e-skipper.outputs.skip-check }}' skip: '${{ steps.merge-queue-e2e-skipper.outputs.skip-check }}'
steps: steps:
@@ -42,7 +43,7 @@ jobs:
download_repo_name: download_repo_name:
runs-on: 'gemini-cli-ubuntu-16-core' runs-on: 'gemini-cli-ubuntu-16-core'
if: "${{github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_run'}}" if: "github.repository == 'google-gemini/gemini-cli' && (github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_run')"
outputs: outputs:
repo_name: '${{ steps.output-repo-name.outputs.repo_name }}' repo_name: '${{ steps.output-repo-name.outputs.repo_name }}'
head_sha: '${{ steps.output-repo-name.outputs.head_sha }}' head_sha: '${{ steps.output-repo-name.outputs.head_sha }}'
@@ -53,7 +54,7 @@ jobs:
REPO_NAME: '${{ github.event.inputs.repo_name }}' REPO_NAME: '${{ github.event.inputs.repo_name }}'
run: | run: |
mkdir -p ./pr mkdir -p ./pr
echo '${{ env.REPO_NAME }}' > ./pr/repo_name echo "${REPO_NAME}" > ./pr/repo_name
- uses: 'actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02' # ratchet:actions/upload-artifact@v4 - uses: 'actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02' # ratchet:actions/upload-artifact@v4
with: with:
name: 'repo_name' name: 'repo_name'
@@ -91,7 +92,7 @@ jobs:
name: 'Parse run context' name: 'Parse run context'
runs-on: 'gemini-cli-ubuntu-16-core' runs-on: 'gemini-cli-ubuntu-16-core'
needs: 'download_repo_name' needs: 'download_repo_name'
if: 'always()' if: "github.repository == 'google-gemini/gemini-cli' && always()"
outputs: outputs:
repository: '${{ steps.set_context.outputs.REPO }}' repository: '${{ steps.set_context.outputs.REPO }}'
sha: '${{ steps.set_context.outputs.SHA }}' sha: '${{ steps.set_context.outputs.SHA }}'
@@ -111,11 +112,11 @@ jobs:
permissions: 'write-all' permissions: 'write-all'
needs: needs:
- 'parse_run_context' - 'parse_run_context'
if: 'always()' if: "github.repository == 'google-gemini/gemini-cli' && always()"
steps: steps:
- name: 'Set pending status' - name: 'Set pending status'
uses: 'myrotvorets/set-commit-status-action@16037e056d73b2d3c88e37e393ff369047f70886' # ratchet:myrotvorets/set-commit-status-action@master uses: 'myrotvorets/set-commit-status-action@16037e056d73b2d3c88e37e393ff369047f70886' # ratchet:myrotvorets/set-commit-status-action@master
if: 'always()' if: "github.repository == 'google-gemini/gemini-cli' && always()"
with: with:
allowForks: 'true' allowForks: 'true'
repo: '${{ github.repository }}' repo: '${{ github.repository }}'
@@ -131,7 +132,7 @@ jobs:
- 'parse_run_context' - 'parse_run_context'
runs-on: 'gemini-cli-ubuntu-16-core' runs-on: 'gemini-cli-ubuntu-16-core'
if: | if: |
always() && (needs.merge_queue_skipper.result !='success' || needs.merge_queue_skipper.outputs.skip != 'true') github.repository == 'google-gemini/gemini-cli' && always() && (needs.merge_queue_skipper.result !='success' || needs.merge_queue_skipper.outputs.skip != 'true')
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
@@ -184,7 +185,7 @@ jobs:
- 'parse_run_context' - 'parse_run_context'
runs-on: 'macos-latest' runs-on: 'macos-latest'
if: | if: |
always() && (needs.merge_queue_skipper.result !='success' || needs.merge_queue_skipper.outputs.skip != 'true') github.repository == 'google-gemini/gemini-cli' && always() && (needs.merge_queue_skipper.result !='success' || needs.merge_queue_skipper.outputs.skip != 'true')
steps: steps:
- name: 'Checkout' - name: 'Checkout'
uses: 'actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955' # ratchet:actions/checkout@v5 uses: 'actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955' # ratchet:actions/checkout@v5
@@ -222,7 +223,7 @@ jobs:
- 'merge_queue_skipper' - 'merge_queue_skipper'
- 'parse_run_context' - 'parse_run_context'
if: | if: |
always() && (needs.merge_queue_skipper.result !='success' || needs.merge_queue_skipper.outputs.skip != 'true') github.repository == 'google-gemini/gemini-cli' && always() && (needs.merge_queue_skipper.result !='success' || needs.merge_queue_skipper.outputs.skip != 'true')
runs-on: 'gemini-cli-windows-16-core' runs-on: 'gemini-cli-windows-16-core'
steps: steps:
- name: 'Checkout' - name: 'Checkout'
@@ -282,13 +283,14 @@ jobs:
- 'parse_run_context' - 'parse_run_context'
runs-on: 'gemini-cli-ubuntu-16-core' runs-on: 'gemini-cli-ubuntu-16-core'
if: | if: |
always() && (needs.merge_queue_skipper.result !='success' || needs.merge_queue_skipper.outputs.skip != 'true') github.repository == 'google-gemini/gemini-cli' && always() && (needs.merge_queue_skipper.result !='success' || needs.merge_queue_skipper.outputs.skip != 'true')
steps: steps:
- name: 'Checkout' - name: 'Checkout'
uses: 'actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955' # ratchet:actions/checkout@v5 uses: 'actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955' # ratchet:actions/checkout@v5
with: with:
ref: '${{ needs.parse_run_context.outputs.sha }}' ref: '${{ needs.parse_run_context.outputs.sha }}'
repository: '${{ needs.parse_run_context.outputs.repository }}' repository: '${{ needs.parse_run_context.outputs.repository }}'
fetch-depth: 0
- name: 'Set up Node.js 20.x' - name: 'Set up Node.js 20.x'
uses: 'actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020' # ratchet:actions-node@v4 uses: 'actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020' # ratchet:actions-node@v4
@@ -301,7 +303,14 @@ jobs:
- name: 'Build project' - name: 'Build project'
run: 'npm run build' run: 'npm run build'
- name: 'Check if evals should run'
id: 'check_evals'
run: |
SHOULD_RUN=$(node scripts/changed_prompt.js)
echo "should_run=$SHOULD_RUN" >> "$GITHUB_OUTPUT"
- name: 'Run Evals (Required to pass)' - name: 'Run Evals (Required to pass)'
if: "${{ steps.check_evals.outputs.should_run == 'true' }}"
env: env:
GEMINI_API_KEY: '${{ secrets.GEMINI_API_KEY }}' GEMINI_API_KEY: '${{ secrets.GEMINI_API_KEY }}'
run: 'npm run test:always_passing_evals' run: 'npm run test:always_passing_evals'
@@ -309,7 +318,7 @@ jobs:
e2e: e2e:
name: 'E2E' name: 'E2E'
if: | if: |
always() && (needs.merge_queue_skipper.result !='success' || needs.merge_queue_skipper.outputs.skip != 'true') github.repository == 'google-gemini/gemini-cli' && always() && (needs.merge_queue_skipper.result !='success' || needs.merge_queue_skipper.outputs.skip != 'true')
needs: needs:
- 'e2e_linux' - 'e2e_linux'
- 'e2e_mac' - 'e2e_mac'
@@ -320,26 +329,31 @@ jobs:
steps: steps:
- name: 'Check E2E test results' - name: 'Check E2E test results'
run: | run: |
if [[ ${{ needs.e2e_linux.result }} != 'success' || \ if [[ ${NEEDS_E2E_LINUX_RESULT} != 'success' || \
${{ needs.e2e_mac.result }} != 'success' || \ ${NEEDS_E2E_MAC_RESULT} != 'success' || \
${{ needs.e2e_windows.result }} != 'success' || \ ${NEEDS_E2E_WINDOWS_RESULT} != 'success' || \
${{ needs.evals.result }} != 'success' ]]; then ${NEEDS_EVALS_RESULT} != 'success' ]]; then
echo "One or more E2E jobs failed." echo "One or more E2E jobs failed."
exit 1 exit 1
fi fi
echo "All required E2E jobs passed!" echo "All required E2E jobs passed!"
env:
NEEDS_E2E_LINUX_RESULT: '${{ needs.e2e_linux.result }}'
NEEDS_E2E_MAC_RESULT: '${{ needs.e2e_mac.result }}'
NEEDS_E2E_WINDOWS_RESULT: '${{ needs.e2e_windows.result }}'
NEEDS_EVALS_RESULT: '${{ needs.evals.result }}'
set_workflow_status: set_workflow_status:
runs-on: 'gemini-cli-ubuntu-16-core' runs-on: 'gemini-cli-ubuntu-16-core'
permissions: 'write-all' permissions: 'write-all'
if: 'always()' if: "github.repository == 'google-gemini/gemini-cli' && always()"
needs: needs:
- 'parse_run_context' - 'parse_run_context'
- 'e2e' - 'e2e'
steps: steps:
- name: 'Set workflow status' - name: 'Set workflow status'
uses: 'myrotvorets/set-commit-status-action@16037e056d73b2d3c88e37e393ff369047f70886' # ratchet:myrotvorets/set-commit-status-action@master uses: 'myrotvorets/set-commit-status-action@16037e056d73b2d3c88e37e393ff369047f70886' # ratchet:myrotvorets/set-commit-status-action@master
if: 'always()' if: "github.repository == 'google-gemini/gemini-cli' && always()"
with: with:
allowForks: 'true' allowForks: 'true'
repo: '${{ github.repository }}' repo: '${{ github.repository }}'
+24 -14
View File
@@ -37,6 +37,7 @@ jobs:
permissions: 'read-all' permissions: 'read-all'
name: 'Merge Queue Skipper' name: 'Merge Queue Skipper'
runs-on: 'gemini-cli-ubuntu-16-core' runs-on: 'gemini-cli-ubuntu-16-core'
if: "github.repository == 'google-gemini/gemini-cli'"
outputs: outputs:
skip: '${{ steps.merge-queue-ci-skipper.outputs.skip-check }}' skip: '${{ steps.merge-queue-ci-skipper.outputs.skip-check }}'
steps: steps:
@@ -49,7 +50,7 @@ jobs:
name: 'Lint' name: 'Lint'
runs-on: 'gemini-cli-ubuntu-16-core' runs-on: 'gemini-cli-ubuntu-16-core'
needs: 'merge_queue_skipper' needs: 'merge_queue_skipper'
if: "${{needs.merge_queue_skipper.outputs.skip == 'false'}}" if: "github.repository == 'google-gemini/gemini-cli' && needs.merge_queue_skipper.outputs.skip == 'false'"
env: env:
GEMINI_LINT_TEMP_DIR: '${{ github.workspace }}/.gemini-linters' GEMINI_LINT_TEMP_DIR: '${{ github.workspace }}/.gemini-linters'
steps: steps:
@@ -116,6 +117,7 @@ jobs:
link_checker: link_checker:
name: 'Link Checker' name: 'Link Checker'
runs-on: 'ubuntu-latest' runs-on: 'ubuntu-latest'
if: "github.repository == 'google-gemini/gemini-cli'"
steps: steps:
- name: 'Checkout' - name: 'Checkout'
uses: 'actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8' # ratchet:actions/checkout@v5 uses: 'actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8' # ratchet:actions/checkout@v5
@@ -129,7 +131,7 @@ jobs:
runs-on: 'gemini-cli-ubuntu-16-core' runs-on: 'gemini-cli-ubuntu-16-core'
needs: needs:
- 'merge_queue_skipper' - 'merge_queue_skipper'
if: "${{needs.merge_queue_skipper.outputs.skip == 'false'}}" if: "github.repository == 'google-gemini/gemini-cli' && needs.merge_queue_skipper.outputs.skip == 'false'"
permissions: permissions:
contents: 'read' contents: 'read'
checks: 'write' checks: 'write'
@@ -216,7 +218,7 @@ jobs:
runs-on: 'macos-latest' runs-on: 'macos-latest'
needs: needs:
- 'merge_queue_skipper' - 'merge_queue_skipper'
if: "${{needs.merge_queue_skipper.outputs.skip == 'false'}}" if: "github.repository == 'google-gemini/gemini-cli' && needs.merge_queue_skipper.outputs.skip == 'false'"
permissions: permissions:
contents: 'read' contents: 'read'
checks: 'write' checks: 'write'
@@ -311,7 +313,7 @@ jobs:
name: 'CodeQL' name: 'CodeQL'
runs-on: 'gemini-cli-ubuntu-16-core' runs-on: 'gemini-cli-ubuntu-16-core'
needs: 'merge_queue_skipper' needs: 'merge_queue_skipper'
if: "${{needs.merge_queue_skipper.outputs.skip == 'false'}}" if: "github.repository == 'google-gemini/gemini-cli' && needs.merge_queue_skipper.outputs.skip == 'false'"
permissions: permissions:
actions: 'read' actions: 'read'
contents: 'read' contents: 'read'
@@ -334,7 +336,7 @@ jobs:
bundle_size: bundle_size:
name: 'Check Bundle Size' name: 'Check Bundle Size'
needs: 'merge_queue_skipper' needs: 'merge_queue_skipper'
if: "${{github.event_name == 'pull_request' && needs.merge_queue_skipper.outputs.skip == 'false'}}" if: "github.repository == 'google-gemini/gemini-cli' && github.event_name == 'pull_request' && needs.merge_queue_skipper.outputs.skip == 'false'"
runs-on: 'gemini-cli-ubuntu-16-core' runs-on: 'gemini-cli-ubuntu-16-core'
permissions: permissions:
contents: 'read' # For checkout contents: 'read' # For checkout
@@ -359,7 +361,7 @@ jobs:
name: 'Slow Test - Win - ${{ matrix.shard }}' name: 'Slow Test - Win - ${{ matrix.shard }}'
runs-on: 'gemini-cli-windows-16-core' runs-on: 'gemini-cli-windows-16-core'
needs: 'merge_queue_skipper' needs: 'merge_queue_skipper'
if: "${{needs.merge_queue_skipper.outputs.skip == 'false'}}" if: "github.repository == 'google-gemini/gemini-cli' && needs.merge_queue_skipper.outputs.skip == 'false'"
timeout-minutes: 60 timeout-minutes: 60
strategy: strategy:
matrix: matrix:
@@ -451,7 +453,7 @@ jobs:
ci: ci:
name: 'CI' name: 'CI'
if: 'always()' if: "github.repository == 'google-gemini/gemini-cli' && always()"
needs: needs:
- 'lint' - 'lint'
- 'link_checker' - 'link_checker'
@@ -464,14 +466,22 @@ jobs:
steps: steps:
- name: 'Check all job results' - name: 'Check all job results'
run: | run: |
if [[ (${{ needs.lint.result }} != 'success' && ${{ needs.lint.result }} != 'skipped') || \ if [[ (${NEEDS_LINT_RESULT} != 'success' && ${NEEDS_LINT_RESULT} != 'skipped') || \
(${{ needs.link_checker.result }} != 'success' && ${{ needs.link_checker.result }} != 'skipped') || \ (${NEEDS_LINK_CHECKER_RESULT} != 'success' && ${NEEDS_LINK_CHECKER_RESULT} != 'skipped') || \
(${{ needs.test_linux.result }} != 'success' && ${{ needs.test_linux.result }} != 'skipped') || \ (${NEEDS_TEST_LINUX_RESULT} != 'success' && ${NEEDS_TEST_LINUX_RESULT} != 'skipped') || \
(${{ needs.test_mac.result }} != 'success' && ${{ needs.test_mac.result }} != 'skipped') || \ (${NEEDS_TEST_MAC_RESULT} != 'success' && ${NEEDS_TEST_MAC_RESULT} != 'skipped') || \
(${{ needs.test_windows.result }} != 'success' && ${{ needs.test_windows.result }} != 'skipped') || \ (${NEEDS_TEST_WINDOWS_RESULT} != 'success' && ${NEEDS_TEST_WINDOWS_RESULT} != 'skipped') || \
(${{ needs.codeql.result }} != 'success' && ${{ needs.codeql.result }} != 'skipped') || \ (${NEEDS_CODEQL_RESULT} != 'success' && ${NEEDS_CODEQL_RESULT} != 'skipped') || \
(${{ needs.bundle_size.result }} != 'success' && ${{ needs.bundle_size.result }} != 'skipped') ]]; then (${NEEDS_BUNDLE_SIZE_RESULT} != 'success' && ${NEEDS_BUNDLE_SIZE_RESULT} != 'skipped') ]]; then
echo "One or more CI jobs failed." echo "One or more CI jobs failed."
exit 1 exit 1
fi fi
echo "All CI jobs passed!" echo "All CI jobs passed!"
env:
NEEDS_LINT_RESULT: '${{ needs.lint.result }}'
NEEDS_LINK_CHECKER_RESULT: '${{ needs.link_checker.result }}'
NEEDS_TEST_LINUX_RESULT: '${{ needs.test_linux.result }}'
NEEDS_TEST_MAC_RESULT: '${{ needs.test_mac.result }}'
NEEDS_TEST_WINDOWS_RESULT: '${{ needs.test_windows.result }}'
NEEDS_CODEQL_RESULT: '${{ needs.codeql.result }}'
NEEDS_BUNDLE_SIZE_RESULT: '${{ needs.bundle_size.result }}'
+8 -6
View File
@@ -27,6 +27,7 @@ jobs:
deflake_e2e_linux: deflake_e2e_linux:
name: 'E2E Test (Linux) - ${{ matrix.sandbox }}' name: 'E2E Test (Linux) - ${{ matrix.sandbox }}'
runs-on: 'gemini-cli-ubuntu-16-core' runs-on: 'gemini-cli-ubuntu-16-core'
if: "github.repository == 'google-gemini/gemini-cli'"
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
@@ -68,15 +69,16 @@ jobs:
VERBOSE: 'true' VERBOSE: 'true'
shell: 'bash' shell: 'bash'
run: | run: |
if [[ "${{ env.IS_DOCKER }}" == "true" ]]; then if [[ "${IS_DOCKER}" == "true" ]]; then
npm run deflake:test:integration:sandbox:docker -- --runs="${{ env.RUNS }}" -- --testNamePattern "'${{ env.TEST_NAME_PATTERN }}'" npm run deflake:test:integration:sandbox:docker -- --runs="${RUNS}" -- --testNamePattern "'${TEST_NAME_PATTERN}'"
else else
npm run deflake:test:integration:sandbox:none -- --runs="${{ env.RUNS }}" -- --testNamePattern "'${{ env.TEST_NAME_PATTERN }}'" npm run deflake:test:integration:sandbox:none -- --runs="${RUNS}" -- --testNamePattern "'${TEST_NAME_PATTERN}'"
fi fi
deflake_e2e_mac: deflake_e2e_mac:
name: 'E2E Test (macOS)' name: 'E2E Test (macOS)'
runs-on: 'macos-latest' runs-on: 'macos-latest'
if: "github.repository == 'google-gemini/gemini-cli'"
steps: steps:
- name: 'Checkout' - name: 'Checkout'
uses: 'actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955' # ratchet:actions/checkout@v5 uses: 'actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955' # ratchet:actions/checkout@v5
@@ -109,12 +111,12 @@ jobs:
TEST_NAME_PATTERN: '${{ github.event.inputs.test_name_pattern }}' TEST_NAME_PATTERN: '${{ github.event.inputs.test_name_pattern }}'
VERBOSE: 'true' VERBOSE: 'true'
run: | run: |
npm run deflake:test:integration:sandbox:none -- --runs="${{ env.RUNS }}" -- --testNamePattern "'${{ env.TEST_NAME_PATTERN }}'" npm run deflake:test:integration:sandbox:none -- --runs="${RUNS}" -- --testNamePattern "'${TEST_NAME_PATTERN}'"
deflake_e2e_windows: deflake_e2e_windows:
name: 'Slow E2E - Win' name: 'Slow E2E - Win'
runs-on: 'gemini-cli-windows-16-core' runs-on: 'gemini-cli-windows-16-core'
if: "github.repository == 'google-gemini/gemini-cli'"
steps: steps:
- name: 'Checkout' - name: 'Checkout'
uses: 'actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955' # ratchet:actions/checkout@v5 uses: 'actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955' # ratchet:actions/checkout@v5
@@ -167,4 +169,4 @@ jobs:
TEST_NAME_PATTERN: '${{ github.event.inputs.test_name_pattern }}' TEST_NAME_PATTERN: '${{ github.event.inputs.test_name_pattern }}'
shell: 'pwsh' shell: 'pwsh'
run: | run: |
npm run deflake:test:integration:sandbox:none -- --runs="${{ env.RUNS }}" -- --testNamePattern "'${{ env.TEST_NAME_PATTERN }}'" npm run deflake:test:integration:sandbox:none -- --runs="$env:RUNS" -- --testNamePattern "'$env:TEST_NAME_PATTERN'"
+2 -2
View File
@@ -19,8 +19,7 @@ concurrency:
jobs: jobs:
build: build:
if: |- if: "github.repository == 'google-gemini/gemini-cli' && !contains(github.ref_name, 'nightly')"
${{ !contains(github.ref_name, 'nightly') }}
runs-on: 'ubuntu-latest' runs-on: 'ubuntu-latest'
steps: steps:
- name: 'Checkout' - name: 'Checkout'
@@ -39,6 +38,7 @@ jobs:
uses: 'actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa' # ratchet:actions/upload-pages-artifact@v3 uses: 'actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa' # ratchet:actions/upload-pages-artifact@v3
deploy: deploy:
if: "github.repository == 'google-gemini/gemini-cli'"
environment: environment:
name: 'github-pages' name: 'github-pages'
url: '${{ steps.deployment.outputs.page_url }}' url: '${{ steps.deployment.outputs.page_url }}'
+1
View File
@@ -7,6 +7,7 @@ on:
- 'docs/**' - 'docs/**'
jobs: jobs:
trigger-rebuild: trigger-rebuild:
if: "github.repository == 'google-gemini/gemini-cli'"
runs-on: 'ubuntu-latest' runs-on: 'ubuntu-latest'
steps: steps:
- name: 'Trigger rebuild' - name: 'Trigger rebuild'
+1 -1
View File
@@ -44,5 +44,5 @@ jobs:
- name: 'Run evaluation' - name: 'Run evaluation'
working-directory: '/app' working-directory: '/app'
run: | run: |
poetry run exp_run --experiment-mode=on-demand --branch-or-commit=${{ github.ref_name }} --model-name=gemini-2.5-pro --dataset=swebench_verified --concurrency=15 poetry run exp_run --experiment-mode=on-demand --branch-or-commit="${GITHUB_REF_NAME}" --model-name=gemini-2.5-pro --dataset=swebench_verified --concurrency=15
poetry run python agent_prototypes/scripts/parse_gcli_logs_experiment.py --experiment_dir=experiments/adhoc/gcli_temp_exp --gcs-bucket="${EVAL_GCS_BUCKET}" --gcs-path=gh_action_artifacts poetry run python agent_prototypes/scripts/parse_gcli_logs_experiment.py --experiment_dir=experiments/adhoc/gcli_temp_exp --gcs-bucket="${EVAL_GCS_BUCKET}" --gcs-path=gh_action_artifacts
+3 -2
View File
@@ -23,6 +23,7 @@ jobs:
evals: evals:
name: 'Evals (USUALLY_PASSING) nightly run' name: 'Evals (USUALLY_PASSING) nightly run'
runs-on: 'gemini-cli-ubuntu-16-core' runs-on: 'gemini-cli-ubuntu-16-core'
if: "github.repository == 'google-gemini/gemini-cli'"
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
@@ -62,7 +63,7 @@ jobs:
TEST_NAME_PATTERN: '${{ github.event.inputs.test_name_pattern }}' TEST_NAME_PATTERN: '${{ github.event.inputs.test_name_pattern }}'
run: | run: |
CMD="npm run test:all_evals" CMD="npm run test:all_evals"
PATTERN="${{ env.TEST_NAME_PATTERN }}" PATTERN="${TEST_NAME_PATTERN}"
if [[ -n "$PATTERN" ]]; then if [[ -n "$PATTERN" ]]; then
if [[ "$PATTERN" == *.ts || "$PATTERN" == *.js || "$PATTERN" == */* ]]; then if [[ "$PATTERN" == *.ts || "$PATTERN" == *.js || "$PATTERN" == */* ]]; then
@@ -85,7 +86,7 @@ jobs:
aggregate-results: aggregate-results:
name: 'Aggregate Results' name: 'Aggregate Results'
needs: ['evals'] needs: ['evals']
if: 'always()' if: "github.repository == 'google-gemini/gemini-cli' && always()"
runs-on: 'gemini-cli-ubuntu-16-core' runs-on: 'gemini-cli-ubuntu-16-core'
steps: steps:
- name: 'Checkout' - name: 'Checkout'
@@ -158,7 +158,7 @@ jobs:
}, },
"coreTools": [ "coreTools": [
"run_shell_command(echo)" "run_shell_command(echo)"
], ]
} }
prompt: |- prompt: |-
## Role ## Role
@@ -21,6 +21,7 @@ defaults:
jobs: jobs:
close-stale-issues: close-stale-issues:
if: "github.repository == 'google-gemini/gemini-cli'"
runs-on: 'ubuntu-latest' runs-on: 'ubuntu-latest'
permissions: permissions:
issues: 'write' issues: 'write'
+41 -1
View File
@@ -25,7 +25,7 @@ jobs:
if: |- if: |-
github.repository == 'google-gemini/gemini-cli' && github.repository == 'google-gemini/gemini-cli' &&
github.event_name == 'issue_comment' && github.event_name == 'issue_comment' &&
contains(github.event.comment.body, '/assign') (contains(github.event.comment.body, '/assign') || contains(github.event.comment.body, '/unassign'))
runs-on: 'ubuntu-latest' runs-on: 'ubuntu-latest'
steps: steps:
- name: 'Generate GitHub App Token' - name: 'Generate GitHub App Token'
@@ -38,6 +38,7 @@ jobs:
permission-issues: 'write' permission-issues: 'write'
- name: 'Assign issue to user' - name: 'Assign issue to user'
if: "contains(github.event.comment.body, '/assign')"
uses: 'actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea' uses: 'actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea'
with: with:
github-token: '${{ steps.generate_token.outputs.token }}' github-token: '${{ steps.generate_token.outputs.token }}'
@@ -108,3 +109,42 @@ jobs:
issue_number: issueNumber, issue_number: issueNumber,
body: `👋 @${commenter}, you've been assigned to this issue! Thank you for taking the time to contribute. Make sure to check out our [contributing guidelines](https://github.com/google-gemini/gemini-cli/blob/main/CONTRIBUTING.md).` body: `👋 @${commenter}, you've been assigned to this issue! Thank you for taking the time to contribute. Make sure to check out our [contributing guidelines](https://github.com/google-gemini/gemini-cli/blob/main/CONTRIBUTING.md).`
}); });
- name: 'Unassign issue from user'
if: "contains(github.event.comment.body, '/unassign')"
uses: 'actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea'
with:
github-token: '${{ steps.generate_token.outputs.token }}'
script: |
const issueNumber = context.issue.number;
const commenter = context.actor;
const owner = context.repo.owner;
const repo = context.repo.repo;
const commentBody = context.payload.comment.body.trim();
if (commentBody !== '/unassign') {
return;
}
const issue = await github.rest.issues.get({
owner: owner,
repo: repo,
issue_number: issueNumber,
});
const isAssigned = issue.data.assignees.some(assignee => assignee.login === commenter);
if (isAssigned) {
await github.rest.issues.removeAssignees({
owner: owner,
repo: repo,
issue_number: issueNumber,
assignees: [commenter]
});
await github.rest.issues.createComment({
owner: owner,
repo: repo,
issue_number: issueNumber,
body: `👋 @${commenter}, you have been unassigned from this issue.`
});
}
@@ -14,7 +14,7 @@ permissions:
jobs: jobs:
# Event-based: Quick reaction to new/edited issues in THIS repo # Event-based: Quick reaction to new/edited issues in THIS repo
labeler: labeler:
if: "github.event_name == 'issues'" if: "github.repository == 'google-gemini/gemini-cli' && github.event_name == 'issues'"
runs-on: 'ubuntu-latest' runs-on: 'ubuntu-latest'
steps: steps:
- name: 'Checkout' - name: 'Checkout'
@@ -36,7 +36,7 @@ jobs:
# Scheduled/Manual: Recursive sync across multiple repos # Scheduled/Manual: Recursive sync across multiple repos
sync-maintainer-labels: sync-maintainer-labels:
if: "github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'" if: "github.repository == 'google-gemini/gemini-cli' && (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch')"
runs-on: 'ubuntu-latest' runs-on: 'ubuntu-latest'
steps: steps:
- name: 'Checkout' - name: 'Checkout'
@@ -9,6 +9,7 @@ on:
jobs: jobs:
labeler: labeler:
if: "github.repository == 'google-gemini/gemini-cli'"
runs-on: 'ubuntu-latest' runs-on: 'ubuntu-latest'
permissions: permissions:
issues: 'write' issues: 'write'
@@ -32,6 +32,7 @@ on:
jobs: jobs:
change-tags: change-tags:
if: "github.repository == 'google-gemini/gemini-cli'"
runs-on: 'ubuntu-latest' runs-on: 'ubuntu-latest'
environment: "${{ github.event.inputs.environment || 'prod' }}" environment: "${{ github.event.inputs.environment || 'prod' }}"
permissions: permissions:
+1
View File
@@ -47,6 +47,7 @@ on:
jobs: jobs:
release: release:
if: "github.repository == 'google-gemini/gemini-cli'"
runs-on: 'ubuntu-latest' runs-on: 'ubuntu-latest'
environment: "${{ github.event.inputs.environment || 'prod' }}" environment: "${{ github.event.inputs.environment || 'prod' }}"
permissions: permissions:
+1 -1
View File
@@ -145,7 +145,7 @@ jobs:
branch-name: 'release/${{ steps.nightly_version.outputs.RELEASE_TAG }}' branch-name: 'release/${{ steps.nightly_version.outputs.RELEASE_TAG }}'
pr-title: 'chore/release: bump version to ${{ steps.nightly_version.outputs.RELEASE_VERSION }}' pr-title: 'chore/release: bump version to ${{ steps.nightly_version.outputs.RELEASE_VERSION }}'
pr-body: 'Automated version bump for nightly release.' pr-body: 'Automated version bump for nightly release.'
github-token: '${{ secrets.GITHUB_TOKEN }}' github-token: '${{ secrets.GEMINI_CLI_ROBOT_GITHUB_PAT }}'
dry-run: '${{ steps.vars.outputs.is_dry_run }}' dry-run: '${{ steps.vars.outputs.is_dry_run }}'
working-directory: './release' working-directory: './release'
+15
View File
@@ -22,6 +22,7 @@ on:
jobs: jobs:
generate-release-notes: generate-release-notes:
if: "github.repository == 'google-gemini/gemini-cli'"
runs-on: 'ubuntu-latest' runs-on: 'ubuntu-latest'
permissions: permissions:
contents: 'write' contents: 'write'
@@ -56,7 +57,18 @@ jobs:
GH_TOKEN: '${{ secrets.GEMINI_CLI_ROBOT_GITHUB_PAT }}' GH_TOKEN: '${{ secrets.GEMINI_CLI_ROBOT_GITHUB_PAT }}'
BODY: '${{ github.event.inputs.body || github.event.release.body }}' BODY: '${{ github.event.inputs.body || github.event.release.body }}'
- name: 'Validate version'
id: 'validate_version'
run: |
if echo "${{ steps.release_info.outputs.VERSION }}" | grep -q "nightly"; then
echo "Nightly release detected. Stopping workflow."
echo "CONTINUE=false" >> "$GITHUB_OUTPUT"
else
echo "CONTINUE=true" >> "$GITHUB_OUTPUT"
fi
- name: 'Generate Changelog with Gemini' - name: 'Generate Changelog with Gemini'
if: "steps.validate_version.outputs.CONTINUE == 'true'"
uses: 'google-github-actions/run-gemini-cli@a3bf79042542528e91937b3a3a6fbc4967ee3c31' # ratchet:google-github-actions/run-gemini-cli@v0 uses: 'google-github-actions/run-gemini-cli@a3bf79042542528e91937b3a3a6fbc4967ee3c31' # ratchet:google-github-actions/run-gemini-cli@v0
with: with:
gemini_api_key: '${{ secrets.GEMINI_API_KEY }}' gemini_api_key: '${{ secrets.GEMINI_API_KEY }}'
@@ -70,7 +82,10 @@ jobs:
Execute the release notes generation process using the information provided. Execute the release notes generation process using the information provided.
When you are done, please output your thought process and the steps you took for future debugging purposes.
- name: 'Create Pull Request' - name: 'Create Pull Request'
if: "steps.validate_version.outputs.CONTINUE == 'true'"
uses: 'peter-evans/create-pull-request@v6' uses: 'peter-evans/create-pull-request@v6'
with: with:
token: '${{ secrets.GEMINI_CLI_ROBOT_GITHUB_PAT }}' token: '${{ secrets.GEMINI_CLI_ROBOT_GITHUB_PAT }}'
+11 -5
View File
@@ -118,6 +118,7 @@ jobs:
ORIGINAL_RELEASE_VERSION: '${{ steps.patch_version.outputs.RELEASE_VERSION }}' ORIGINAL_RELEASE_VERSION: '${{ steps.patch_version.outputs.RELEASE_VERSION }}'
ORIGINAL_RELEASE_TAG: '${{ steps.patch_version.outputs.RELEASE_TAG }}' ORIGINAL_RELEASE_TAG: '${{ steps.patch_version.outputs.RELEASE_TAG }}'
ORIGINAL_PREVIOUS_TAG: '${{ steps.patch_version.outputs.PREVIOUS_TAG }}' ORIGINAL_PREVIOUS_TAG: '${{ steps.patch_version.outputs.PREVIOUS_TAG }}'
VARS_CLI_PACKAGE_NAME: '${{ vars.CLI_PACKAGE_NAME }}'
run: | run: |
echo "🔍 Verifying no concurrent patch releases have occurred..." echo "🔍 Verifying no concurrent patch releases have occurred..."
@@ -129,7 +130,7 @@ jobs:
# Re-run the same version calculation script # Re-run the same version calculation script
echo "Re-calculating version to check for changes..." echo "Re-calculating version to check for changes..."
CURRENT_PATCH_JSON=$(node scripts/get-release-version.js --cli-package-name="${{vars.CLI_PACKAGE_NAME}}" --type=patch --patch-from="${CHANNEL}") CURRENT_PATCH_JSON=$(node scripts/get-release-version.js --cli-package-name="${VARS_CLI_PACKAGE_NAME}" --type=patch --patch-from="${CHANNEL}")
CURRENT_RELEASE_VERSION=$(echo "${CURRENT_PATCH_JSON}" | jq -r .releaseVersion) CURRENT_RELEASE_VERSION=$(echo "${CURRENT_PATCH_JSON}" | jq -r .releaseVersion)
CURRENT_RELEASE_TAG=$(echo "${CURRENT_PATCH_JSON}" | jq -r .releaseTag) CURRENT_RELEASE_TAG=$(echo "${CURRENT_PATCH_JSON}" | jq -r .releaseTag)
CURRENT_PREVIOUS_TAG=$(echo "${CURRENT_PATCH_JSON}" | jq -r .previousReleaseTag) CURRENT_PREVIOUS_TAG=$(echo "${CURRENT_PATCH_JSON}" | jq -r .previousReleaseTag)
@@ -162,10 +163,15 @@ jobs:
- name: 'Print Calculated Version' - name: 'Print Calculated Version'
run: |- run: |-
echo "Patch Release Summary:" echo "Patch Release Summary:"
echo " Release Version: ${{ steps.patch_version.outputs.RELEASE_VERSION }}" echo " Release Version: ${STEPS_PATCH_VERSION_OUTPUTS_RELEASE_VERSION}"
echo " Release Tag: ${{ steps.patch_version.outputs.RELEASE_TAG }}" echo " Release Tag: ${STEPS_PATCH_VERSION_OUTPUTS_RELEASE_TAG}"
echo " NPM Tag: ${{ steps.patch_version.outputs.NPM_TAG }}" echo " NPM Tag: ${STEPS_PATCH_VERSION_OUTPUTS_NPM_TAG}"
echo " Previous Tag: ${{ steps.patch_version.outputs.PREVIOUS_TAG }}" echo " Previous Tag: ${STEPS_PATCH_VERSION_OUTPUTS_PREVIOUS_TAG}"
env:
STEPS_PATCH_VERSION_OUTPUTS_RELEASE_VERSION: '${{ steps.patch_version.outputs.RELEASE_VERSION }}'
STEPS_PATCH_VERSION_OUTPUTS_RELEASE_TAG: '${{ steps.patch_version.outputs.RELEASE_TAG }}'
STEPS_PATCH_VERSION_OUTPUTS_NPM_TAG: '${{ steps.patch_version.outputs.NPM_TAG }}'
STEPS_PATCH_VERSION_OUTPUTS_PREVIOUS_TAG: '${{ steps.patch_version.outputs.PREVIOUS_TAG }}'
- name: 'Run Tests' - name: 'Run Tests'
if: "${{github.event.inputs.force_skip_tests != 'true'}}" if: "${{github.event.inputs.force_skip_tests != 'true'}}"
+10 -4
View File
@@ -335,6 +335,7 @@ jobs:
name: 'Create Nightly PR' name: 'Create Nightly PR'
needs: ['publish-stable', 'calculate-versions'] needs: ['publish-stable', 'calculate-versions']
runs-on: 'ubuntu-latest' runs-on: 'ubuntu-latest'
environment: "${{ github.event.inputs.environment || 'prod' }}"
permissions: permissions:
contents: 'write' contents: 'write'
pull-requests: 'write' pull-requests: 'write'
@@ -362,23 +363,28 @@ jobs:
- name: 'Create and switch to a new branch' - name: 'Create and switch to a new branch'
id: 'release_branch' id: 'release_branch'
run: | run: |
BRANCH_NAME="chore/nightly-version-bump-${{ needs.calculate-versions.outputs.NEXT_NIGHTLY_VERSION }}" BRANCH_NAME="chore/nightly-version-bump-${NEEDS_CALCULATE_VERSIONS_OUTPUTS_NEXT_NIGHTLY_VERSION}"
git switch -c "${BRANCH_NAME}" git switch -c "${BRANCH_NAME}"
echo "BRANCH_NAME=${BRANCH_NAME}" >> "${GITHUB_OUTPUT}" echo "BRANCH_NAME=${BRANCH_NAME}" >> "${GITHUB_OUTPUT}"
env:
NEEDS_CALCULATE_VERSIONS_OUTPUTS_NEXT_NIGHTLY_VERSION: '${{ needs.calculate-versions.outputs.NEXT_NIGHTLY_VERSION }}'
- name: 'Update package versions' - name: 'Update package versions'
run: 'npm run release:version "${{ needs.calculate-versions.outputs.NEXT_NIGHTLY_VERSION }}"' run: 'npm run release:version "${NEEDS_CALCULATE_VERSIONS_OUTPUTS_NEXT_NIGHTLY_VERSION}"'
env:
NEEDS_CALCULATE_VERSIONS_OUTPUTS_NEXT_NIGHTLY_VERSION: '${{ needs.calculate-versions.outputs.NEXT_NIGHTLY_VERSION }}'
- name: 'Commit and Push package versions' - name: 'Commit and Push package versions'
env: env:
BRANCH_NAME: '${{ steps.release_branch.outputs.BRANCH_NAME }}' BRANCH_NAME: '${{ steps.release_branch.outputs.BRANCH_NAME }}'
DRY_RUN: '${{ github.event.inputs.dry_run }}' DRY_RUN: '${{ github.event.inputs.dry_run }}'
NEEDS_CALCULATE_VERSIONS_OUTPUTS_NEXT_NIGHTLY_VERSION: '${{ needs.calculate-versions.outputs.NEXT_NIGHTLY_VERSION }}'
run: |- run: |-
git add package.json packages/*/package.json git add package.json packages/*/package.json
if [ -f package-lock.json ]; then if [ -f package-lock.json ]; then
git add package-lock.json git add package-lock.json
fi fi
git commit -m "chore(release): bump version to ${{ needs.calculate-versions.outputs.NEXT_NIGHTLY_VERSION }}" git commit -m "chore(release): bump version to ${NEEDS_CALCULATE_VERSIONS_OUTPUTS_NEXT_NIGHTLY_VERSION}"
if [[ "${DRY_RUN}" == "false" ]]; then if [[ "${DRY_RUN}" == "false" ]]; then
echo "Pushing release branch to remote..." echo "Pushing release branch to remote..."
git push --set-upstream origin "${BRANCH_NAME}" git push --set-upstream origin "${BRANCH_NAME}"
@@ -392,7 +398,7 @@ jobs:
branch-name: '${{ steps.release_branch.outputs.BRANCH_NAME }}' branch-name: '${{ steps.release_branch.outputs.BRANCH_NAME }}'
pr-title: 'chore(release): bump version to ${{ needs.calculate-versions.outputs.NEXT_NIGHTLY_VERSION }}' pr-title: 'chore(release): bump version to ${{ needs.calculate-versions.outputs.NEXT_NIGHTLY_VERSION }}'
pr-body: 'Automated version bump to prepare for the next nightly release.' pr-body: 'Automated version bump to prepare for the next nightly release.'
github-token: '${{ secrets.GITHUB_TOKEN }}' github-token: '${{ secrets.GEMINI_CLI_ROBOT_GITHUB_PAT }}'
dry-run: '${{ github.event.inputs.dry_run }}' dry-run: '${{ github.event.inputs.dry_run }}'
- name: 'Create Issue on Failure' - name: 'Create Issue on Failure'
+2 -1
View File
@@ -42,6 +42,7 @@ on:
jobs: jobs:
change-tags: change-tags:
if: "github.repository == 'google-gemini/gemini-cli'"
environment: "${{ github.event.inputs.environment || 'prod' }}" environment: "${{ github.event.inputs.environment || 'prod' }}"
runs-on: 'ubuntu-latest' runs-on: 'ubuntu-latest'
permissions: permissions:
@@ -203,7 +204,7 @@ jobs:
run: | run: |
ROLLBACK_COMMIT=$(git rev-parse -q --verify "$TARGET_TAG") ROLLBACK_COMMIT=$(git rev-parse -q --verify "$TARGET_TAG")
if [ "$ROLLBACK_COMMIT" != "$TARGET_HASH" ]; then if [ "$ROLLBACK_COMMIT" != "$TARGET_HASH" ]; then
echo '❌ Failed to add tag $TARGET_TAG to commit $TARGET_HASH' echo "❌ Failed to add tag ${TARGET_TAG} to commit ${TARGET_HASH}"
echo '❌ This means the tag was not added, and the workflow should fail.' echo '❌ This means the tag was not added, and the workflow should fail.'
exit 1 exit 1
fi fi
+1
View File
@@ -16,6 +16,7 @@ on:
jobs: jobs:
build: build:
if: "github.repository == 'google-gemini/gemini-cli'"
runs-on: 'ubuntu-latest' runs-on: 'ubuntu-latest'
permissions: permissions:
contents: 'read' contents: 'read'
+1
View File
@@ -20,6 +20,7 @@ on:
jobs: jobs:
smoke-test: smoke-test:
if: "github.repository == 'google-gemini/gemini-cli'"
runs-on: 'ubuntu-latest' runs-on: 'ubuntu-latest'
permissions: permissions:
contents: 'write' contents: 'write'
+160
View File
@@ -0,0 +1,160 @@
name: 'Test Build Binary'
on:
workflow_dispatch:
permissions:
contents: 'read'
defaults:
run:
shell: 'bash'
jobs:
build-node-binary:
name: 'Build Binary (${{ matrix.os }})'
runs-on: '${{ matrix.os }}'
strategy:
fail-fast: false
matrix:
include:
- os: 'ubuntu-latest'
platform_name: 'linux-x64'
arch: 'x64'
- os: 'windows-latest'
platform_name: 'win32-x64'
arch: 'x64'
- os: 'macos-latest' # Apple Silicon (ARM64)
platform_name: 'darwin-arm64'
arch: 'arm64'
- os: 'macos-latest' # Intel (x64) running on ARM via Rosetta
platform_name: 'darwin-x64'
arch: 'x64'
steps:
- name: 'Checkout'
uses: 'actions/checkout@v4'
- name: 'Optimize Windows Performance'
if: "matrix.os == 'windows-latest'"
run: |
Set-MpPreference -DisableRealtimeMonitoring $true
Stop-Service -Name "wsearch" -Force -ErrorAction SilentlyContinue
Set-Service -Name "wsearch" -StartupType Disabled
Stop-Service -Name "SysMain" -Force -ErrorAction SilentlyContinue
Set-Service -Name "SysMain" -StartupType Disabled
shell: 'powershell'
- name: 'Set up Node.js'
uses: 'actions/setup-node@v4'
with:
node-version-file: '.nvmrc'
architecture: '${{ matrix.arch }}'
cache: 'npm'
- name: 'Install dependencies'
run: 'npm ci'
- name: 'Check Secrets'
id: 'check_secrets'
run: |
echo "has_win_cert=${{ secrets.WINDOWS_PFX_BASE64 != '' }}" >> "$GITHUB_OUTPUT"
echo "has_mac_cert=${{ secrets.MACOS_CERT_P12_BASE64 != '' }}" >> "$GITHUB_OUTPUT"
- name: 'Setup Windows SDK (Windows)'
if: "matrix.os == 'windows-latest'"
uses: 'microsoft/setup-msbuild@v2'
- name: 'Add Signtool to Path (Windows)'
if: "matrix.os == 'windows-latest'"
run: |
$signtoolPath = Get-ChildItem -Path "C:\Program Files (x86)\Windows Kits\10\bin" -Recurse -Filter "signtool.exe" | Sort-Object FullName -Descending | Select-Object -First 1 -ExpandProperty DirectoryName
echo "Found signtool at: $signtoolPath"
echo "$signtoolPath" >> $env:GITHUB_PATH
shell: 'pwsh'
- name: 'Setup macOS Keychain'
if: "startsWith(matrix.os, 'macos') && steps.check_secrets.outputs.has_mac_cert == 'true' && github.event_name != 'pull_request'"
env:
BUILD_CERTIFICATE_BASE64: '${{ secrets.MACOS_CERT_P12_BASE64 }}'
P12_PASSWORD: '${{ secrets.MACOS_CERT_PASSWORD }}'
KEYCHAIN_PASSWORD: 'temp-password'
run: |
# Create the P12 file
echo "$BUILD_CERTIFICATE_BASE64" | base64 --decode > certificate.p12
# Create a temporary keychain
security create-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
security default-keychain -s build.keychain
security unlock-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
# Import the certificate
security import certificate.p12 -k build.keychain -P "$P12_PASSWORD" -T /usr/bin/codesign
# Allow codesign to access it
security set-key-partition-list -S apple-tool:,apple: -s -k "$KEYCHAIN_PASSWORD" build.keychain
# Set Identity for build script
echo "APPLE_IDENTITY=${{ secrets.MACOS_CERT_IDENTITY }}" >> "$GITHUB_ENV"
- name: 'Setup Windows Certificate'
if: "matrix.os == 'windows-latest' && steps.check_secrets.outputs.has_win_cert == 'true' && github.event_name != 'pull_request'"
env:
PFX_BASE64: '${{ secrets.WINDOWS_PFX_BASE64 }}'
PFX_PASSWORD: '${{ secrets.WINDOWS_PFX_PASSWORD }}'
run: |
$pfx_cert_byte = [System.Convert]::FromBase64String("$env:PFX_BASE64")
$certPath = Join-Path (Get-Location) "cert.pfx"
[IO.File]::WriteAllBytes($certPath, $pfx_cert_byte)
echo "WINDOWS_PFX_FILE=$certPath" >> $env:GITHUB_ENV
echo "WINDOWS_PFX_PASSWORD=$env:PFX_PASSWORD" >> $env:GITHUB_ENV
shell: 'pwsh'
- name: 'Build Binary'
run: 'npm run build:binary'
- name: 'Build Core Package'
run: 'npm run build -w @google/gemini-cli-core'
- name: 'Verify Output Exists'
run: |
if [ -f "dist/${{ matrix.platform_name }}/gemini" ]; then
echo "Binary found at dist/${{ matrix.platform_name }}/gemini"
elif [ -f "dist/${{ matrix.platform_name }}/gemini.exe" ]; then
echo "Binary found at dist/${{ matrix.platform_name }}/gemini.exe"
else
echo "Error: Binary not found in dist/${{ matrix.platform_name }}/"
ls -R dist/
exit 1
fi
- name: 'Smoke Test Binary'
run: |
echo "Running binary smoke test..."
if [ -f "dist/${{ matrix.platform_name }}/gemini.exe" ]; then
"./dist/${{ matrix.platform_name }}/gemini.exe" --version
else
"./dist/${{ matrix.platform_name }}/gemini" --version
fi
- name: 'Run Integration Tests'
if: "github.event_name != 'pull_request'"
env:
GEMINI_API_KEY: '${{ secrets.GEMINI_API_KEY }}'
run: |
echo "Running integration tests with binary..."
if [[ "${{ matrix.os }}" == 'windows-latest' ]]; then
BINARY_PATH="$(cygpath -m "$(pwd)/dist/${{ matrix.platform_name }}/gemini.exe")"
else
BINARY_PATH="$(pwd)/dist/${{ matrix.platform_name }}/gemini"
fi
echo "Using binary at $BINARY_PATH"
export INTEGRATION_TEST_GEMINI_BINARY_PATH="$BINARY_PATH"
npm run test:integration:sandbox:none -- --testTimeout=600000
- name: 'Upload Artifact'
uses: 'actions/upload-artifact@v4'
with:
name: 'gemini-cli-${{ matrix.platform_name }}'
path: 'dist/${{ matrix.platform_name }}/'
retention-days: 5
+4 -2
View File
@@ -15,6 +15,7 @@ on:
jobs: jobs:
save_repo_name: save_repo_name:
if: "github.repository == 'google-gemini/gemini-cli'"
runs-on: 'gemini-cli-ubuntu-16-core' runs-on: 'gemini-cli-ubuntu-16-core'
steps: steps:
- name: 'Save Repo name' - name: 'Save Repo name'
@@ -23,14 +24,15 @@ jobs:
HEAD_SHA: '${{ github.event.inputs.head_sha || github.event.pull_request.head.sha }}' HEAD_SHA: '${{ github.event.inputs.head_sha || github.event.pull_request.head.sha }}'
run: | run: |
mkdir -p ./pr mkdir -p ./pr
echo '${{ env.REPO_NAME }}' > ./pr/repo_name echo "${REPO_NAME}" > ./pr/repo_name
echo '${{ env.HEAD_SHA }}' > ./pr/head_sha echo "${HEAD_SHA}" > ./pr/head_sha
- uses: 'actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02' # ratchet:actions/upload-artifact@v4 - uses: 'actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02' # ratchet:actions/upload-artifact@v4
with: with:
name: 'repo_name' name: 'repo_name'
path: 'pr/' path: 'pr/'
trigger_e2e: trigger_e2e:
name: 'Trigger e2e' name: 'Trigger e2e'
if: "github.repository == 'google-gemini/gemini-cli'"
runs-on: 'gemini-cli-ubuntu-16-core' runs-on: 'gemini-cli-ubuntu-16-core'
steps: steps:
- id: 'trigger-e2e' - id: 'trigger-e2e'
+1
View File
@@ -28,6 +28,7 @@ on:
jobs: jobs:
verify-release: verify-release:
if: "github.repository == 'google-gemini/gemini-cli'"
environment: "${{ github.event.inputs.environment || 'prod' }}" environment: "${{ github.event.inputs.environment || 'prod' }}"
strategy: strategy:
fail-fast: false fail-fast: false
+7 -4
View File
@@ -75,11 +75,14 @@ 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 run this on their own PRs for self-review, and reviewers should use it to
augment their manual review process. augment their manual review process.
### Self assigning issues ### Self-assigning and unassigning issues
To assign an issue to yourself, simply add a comment with the text `/assign`. To assign an issue to yourself, simply add a comment with the text `/assign`. To
The comment must contain only that text and nothing else. This command will unassign yourself from an issue, add a comment with the text `/unassign`.
assign the issue to you, provided it is not already assigned.
The comment must contain only that text and nothing else. These commands will
assign or unassign the issue as requested, provided the conditions are met
(e.g., an issue must be unassigned to be assigned).
Please note that you can have a maximum of 3 issues assigned to you at any given Please note that you can have a maximum of 3 issues assigned to you at any given
time. time.
+11 -9
View File
@@ -282,14 +282,14 @@ gemini
quickly. quickly.
- [**Authentication Setup**](./docs/get-started/authentication.md) - Detailed - [**Authentication Setup**](./docs/get-started/authentication.md) - Detailed
auth configuration. auth configuration.
- [**Configuration Guide**](./docs/get-started/configuration.md) - Settings and - [**Configuration Guide**](./docs/reference/configuration.md) - Settings and
customization. customization.
- [**Keyboard Shortcuts**](./docs/cli/keyboard-shortcuts.md) - Productivity - [**Keyboard Shortcuts**](./docs/reference/keyboard-shortcuts.md) -
tips. Productivity tips.
### Core Features ### Core Features
- [**Commands Reference**](./docs/cli/commands.md) - All slash commands - [**Commands Reference**](./docs/reference/commands.md) - All slash commands
(`/help`, `/chat`, etc). (`/help`, `/chat`, etc).
- [**Custom Commands**](./docs/cli/custom-commands.md) - Create your own - [**Custom Commands**](./docs/cli/custom-commands.md) - Create your own
reusable commands. reusable commands.
@@ -323,15 +323,16 @@ gemini
- [**Enterprise Guide**](./docs/cli/enterprise.md) - Deploy and manage in a - [**Enterprise Guide**](./docs/cli/enterprise.md) - Deploy and manage in a
corporate environment. corporate environment.
- [**Telemetry & Monitoring**](./docs/cli/telemetry.md) - Usage tracking. - [**Telemetry & Monitoring**](./docs/cli/telemetry.md) - Usage tracking.
- [**Tools API Development**](./docs/core/tools-api.md) - Create custom tools. - [**Tools API Development**](./docs/reference/tools-api.md) - Create custom
tools.
- [**Local development**](./docs/local-development.md) - Local development - [**Local development**](./docs/local-development.md) - Local development
tooling. tooling.
### Troubleshooting & Support ### Troubleshooting & Support
- [**Troubleshooting Guide**](./docs/troubleshooting.md) - Common issues and - [**Troubleshooting Guide**](./docs/resources/troubleshooting.md) - Common
solutions. issues and solutions.
- [**FAQ**](./docs/faq.md) - Frequently asked questions. - [**FAQ**](./docs/resources/faq.md) - Frequently asked questions.
- Use `/bug` command to report issues directly from the CLI. - Use `/bug` command to report issues directly from the CLI.
### Using MCP Servers ### Using MCP Servers
@@ -377,7 +378,8 @@ for planned features and priorities.
### Uninstall ### Uninstall
See the [Uninstall Guide](docs/cli/uninstall.md) for removal instructions. See the [Uninstall Guide](./docs/resources/uninstall.md) for removal
instructions.
## 📄 Legal ## 📄 Legal
+43
View File
@@ -18,6 +18,49 @@ on GitHub.
| [Preview](preview.md) | Experimental features ready for early feedback. | | [Preview](preview.md) | Experimental features ready for early feedback. |
| [Stable](latest.md) | Stable, recommended for general use. | | [Stable](latest.md) | Stable, recommended for general use. |
## Announcements: v0.31.0 - 2026-02-27
- **Gemini 3.1 Pro Preview:** Gemini CLI now supports the new Gemini 3.1 Pro
Preview model
([#19676](https://github.com/google-gemini/gemini-cli/pull/19676) by
@sehoon38).
- **Experimental Browser Agent:** We've introduced a new experimental browser
agent to interact with web pages
([#19284](https://github.com/google-gemini/gemini-cli/pull/19284) by
@gsquared94).
- **Policy Engine Updates:** The policy engine now supports project-level
policies, MCP server wildcards, and tool annotation matching
([#18682](https://github.com/google-gemini/gemini-cli/pull/18682) by
@Abhijit-2592,
[#20024](https://github.com/google-gemini/gemini-cli/pull/20024) by @jerop).
- **Web Fetch Improvements:** We've implemented an experimental direct web fetch
feature and added rate limiting to mitigate DDoS risks
([#19557](https://github.com/google-gemini/gemini-cli/pull/19557) by @mbleigh,
[#19567](https://github.com/google-gemini/gemini-cli/pull/19567) by
@mattKorwel).
## Announcements: v0.30.0 - 2026-02-25
- **SDK & Custom Skills:** Introduced the initial SDK package, enabling dynamic
system instructions, `SessionContext` for SDK tool calls, and support for
custom skills
([#18861](https://github.com/google-gemini/gemini-cli/pull/18861) by
@mbleigh).
- **Policy Engine Enhancements:** Added a new `--policy` flag for user-defined
policies, introduced strict seatbelt profiles, and deprecated
`--allowed-tools` in favor of the policy engine
([#18500](https://github.com/google-gemini/gemini-cli/pull/18500) by
@allenhutchison).
- **UI & Themes:** Added a generic searchable list for settings and extensions,
new Solarized themes, text wrapping for markdown tables, and a clean UI toggle
prototype ([#19064](https://github.com/google-gemini/gemini-cli/pull/19064) by
@rmedranollamas).
- **Vim & Terminal Interaction:** Improved Vim support to feel more complete and
added support for Ctrl-Z terminal suspension
([#18755](https://github.com/google-gemini/gemini-cli/pull/18755) by
@ppgranger, [#18931](https://github.com/google-gemini/gemini-cli/pull/18931)
by @scidomino).
## Announcements: v0.29.0 - 2026-02-17 ## Announcements: v0.29.0 - 2026-02-17
- **Plan Mode:** A new comprehensive planning capability with `/plan`, - **Plan Mode:** A new comprehensive planning capability with `/plan`,
+394 -360
View File
@@ -1,6 +1,6 @@
# Latest stable release: v0.29.0 # Latest stable release: v0.31.0
Released: February 17, 2026 Released: February 27, 2026
For most users, our latest stable release is the recommended release. Install For most users, our latest stable release is the recommended release. Install
the latest stable version with: the latest stable version with:
@@ -11,371 +11,405 @@ npm install -g @google/gemini-cli
## Highlights ## Highlights
- **Plan Mode:** Introduce a dedicated "Plan Mode" to help you architect complex - **Gemini 3.1 Pro Preview:** Gemini CLI now supports the new Gemini 3.1 Pro
changes before implementation. Use `/plan` to get started. Preview model.
- **Gemini 3 by Default:** Gemini 3 is now the default model family, bringing - **Experimental Browser Agent:** We've introduced a new experimental browser
improved performance and reasoning capabilities to all users without needing a agent to directly interact with web pages and retrieve context.
feature flag. - **Policy Engine Updates:** The policy engine has been expanded to support
- **Extension Discovery:** Easily discover and install extensions with the new project-level policies, MCP server wildcards, and tool annotation matching,
exploration features and registry client. providing greater control over tool executions.
- **Enhanced Admin Controls:** New administrative capabilities allow for - **Web Fetch Enhancements:** A new experimental direct web fetch tool has been
allowlisting MCP server configurations, giving organizations more control over implemented, alongside rate-limiting features for enhanced security.
available tools. - **Improved Plan Mode:** Plan Mode now includes support for custom storage
- **Sub-agent Improvements:** Sub-agents have been transitioned to a new format directories, automatic model switching, and summarizing work after execution.
with improved definitions and system prompts for better reliability.
## What's Changed ## What's Changed
- fix: remove `ask_user` tool from non-interactive modes by @jackwotherspoon in - Use ranged reads and limited searches and fuzzy editing improvements by
[#18154](https://github.com/google-gemini/gemini-cli/pull/18154) @gundermanc in
- fix(cli): allow restricted .env loading in untrusted sandboxed folders by [#19240](https://github.com/google-gemini/gemini-cli/pull/19240)
@galz10 in [#17806](https://github.com/google-gemini/gemini-cli/pull/17806) - Fix bottom border color by @jacob314 in
- Encourage agent to utilize ecosystem tools to perform work by @gundermanc in [#19266](https://github.com/google-gemini/gemini-cli/pull/19266)
[#17881](https://github.com/google-gemini/gemini-cli/pull/17881) - Release note generator fix by @g-samroberts in
- feat(plan): unify workflow location in system prompt to optimize caching by [#19363](https://github.com/google-gemini/gemini-cli/pull/19363)
@jerop in [#18258](https://github.com/google-gemini/gemini-cli/pull/18258) - test(evals): add behavioral tests for tool output masking by @NTaylorMullen in
- feat(core): enable getUserTierName in config by @sehoon38 in [#19172](https://github.com/google-gemini/gemini-cli/pull/19172)
[#18265](https://github.com/google-gemini/gemini-cli/pull/18265) - docs: clarify preflight instructions in GEMINI.md by @NTaylorMullen in
- feat(core): add default execution limits for subagents by @abhipatel12 in [#19377](https://github.com/google-gemini/gemini-cli/pull/19377)
[#18274](https://github.com/google-gemini/gemini-cli/pull/18274) - feat(cli): add gemini --resume hint on exit by @Mag1ck in
- Fix issue where agent gets stuck at interactive commands. by @gundermanc in [#16285](https://github.com/google-gemini/gemini-cli/pull/16285)
[#18272](https://github.com/google-gemini/gemini-cli/pull/18272) - fix: optimize height calculations for ask_user dialog by @jackwotherspoon in
- chore(release): bump version to 0.29.0-nightly.20260203.71f46f116 by [#19017](https://github.com/google-gemini/gemini-cli/pull/19017)
@gemini-cli-robot in - feat(cli): add Alt+D for forward word deletion by @scidomino in
[#18243](https://github.com/google-gemini/gemini-cli/pull/18243) [#19300](https://github.com/google-gemini/gemini-cli/pull/19300)
- feat(core): remove hardcoded policy bypass for local subagents by @abhipatel12 - Disable failing eval test by @chrstnb in
in [#18153](https://github.com/google-gemini/gemini-cli/pull/18153) [#19455](https://github.com/google-gemini/gemini-cli/pull/19455)
- feat(plan): implement `plan` slash command by @Adib234 in - fix(cli): support legacy onConfirm callback in ToolActionsContext by
[#17698](https://github.com/google-gemini/gemini-cli/pull/17698) @SandyTao520 in
- feat: increase `ask_user` label limit to 16 characters by @jackwotherspoon in [#19369](https://github.com/google-gemini/gemini-cli/pull/19369)
[#18320](https://github.com/google-gemini/gemini-cli/pull/18320) - chore(deps): bump tar from 7.5.7 to 7.5.8 by @.github/dependabot.yml[bot] in
- Add information about the agent skills lifecycle and clarify docs-writer skill [#19367](https://github.com/google-gemini/gemini-cli/pull/19367)
metadata. by @g-samroberts in - fix(plan): allow safe fallback when experiment setting for plan is not enabled
[#18234](https://github.com/google-gemini/gemini-cli/pull/18234) but approval mode at startup is plan by @Adib234 in
- feat(core): add `enter_plan_mode` tool by @jerop in [#19439](https://github.com/google-gemini/gemini-cli/pull/19439)
[#18324](https://github.com/google-gemini/gemini-cli/pull/18324) - Add explicit color-convert dependency by @chrstnb in
- Stop showing an error message in `/plan` by @Adib234 in [#19460](https://github.com/google-gemini/gemini-cli/pull/19460)
[#18333](https://github.com/google-gemini/gemini-cli/pull/18333) - feat(devtools): migrate devtools package into monorepo by @SandyTao520 in
- fix(hooks): remove unnecessary logging for hook registration by @abhipatel12 [#18936](https://github.com/google-gemini/gemini-cli/pull/18936)
in [#18332](https://github.com/google-gemini/gemini-cli/pull/18332) - fix(core): clarify plan mode constraints and exit mechanism by @jerop in
- fix(mcp): ensure MCP transport is closed to prevent memory leaks by [#19438](https://github.com/google-gemini/gemini-cli/pull/19438)
@cbcoutinho in - feat(cli): add macOS run-event notifications (interactive only) by
[#18054](https://github.com/google-gemini/gemini-cli/pull/18054) @LyalinDotCom in
- feat(skills): implement linking for agent skills by @MushuEE in [#19056](https://github.com/google-gemini/gemini-cli/pull/19056)
[#18295](https://github.com/google-gemini/gemini-cli/pull/18295) - Changelog for v0.29.0 by @gemini-cli-robot in
- Changelogs for 0.27.0 and 0.28.0-preview0 by @g-samroberts in [#19361](https://github.com/google-gemini/gemini-cli/pull/19361)
[#18336](https://github.com/google-gemini/gemini-cli/pull/18336) - fix(ui): preventing empty history items from being added by @devr0306 in
- chore: correct docs as skills and hooks are stable by @jackwotherspoon in [#19014](https://github.com/google-gemini/gemini-cli/pull/19014)
[#18358](https://github.com/google-gemini/gemini-cli/pull/18358) - Changelog for v0.30.0-preview.0 by @gemini-cli-robot in
- feat(admin): Implement admin allowlist for MCP server configurations by [#19364](https://github.com/google-gemini/gemini-cli/pull/19364)
@skeshive in [#18311](https://github.com/google-gemini/gemini-cli/pull/18311) - feat(core): add support for MCP progress updates by @NTaylorMullen in
- fix(core): add retry logic for transient SSL/TLS errors (#17318) by @ppgranger [#19046](https://github.com/google-gemini/gemini-cli/pull/19046)
in [#18310](https://github.com/google-gemini/gemini-cli/pull/18310) - fix(core): ensure directory exists before writing conversation file by
- Add support for /extensions config command by @chrstnb in @godwiniheuwa in
[#17895](https://github.com/google-gemini/gemini-cli/pull/17895) [#18429](https://github.com/google-gemini/gemini-cli/pull/18429)
- fix(core): handle non-compliant mcpbridge responses from Xcode 26.3 by - fix(ui): move margin from top to bottom in ToolGroupMessage by @imadraude in
@peterfriese in [#17198](https://github.com/google-gemini/gemini-cli/pull/17198)
[#18376](https://github.com/google-gemini/gemini-cli/pull/18376) - fix(cli): treat unknown slash commands as regular input instead of showing
- feat(cli): Add W, B, E Vim motions and operator support by @ademuri in error by @skyvanguard in
[#16209](https://github.com/google-gemini/gemini-cli/pull/16209) [#17393](https://github.com/google-gemini/gemini-cli/pull/17393)
- fix: Windows Specific Agent Quality & System Prompt by @scidomino in - feat(core): experimental in-progress steering hints (2 of 2) by @joshualitt in
[#18351](https://github.com/google-gemini/gemini-cli/pull/18351) [#19307](https://github.com/google-gemini/gemini-cli/pull/19307)
- feat(plan): support `replace` tool in plan mode to edit plans by @jerop in - docs(plan): add documentation for plan mode command by @Adib234 in
[#18379](https://github.com/google-gemini/gemini-cli/pull/18379) [#19467](https://github.com/google-gemini/gemini-cli/pull/19467)
- Improving memory tool instructions and eval testing by @alisa-alisa in - fix(core): ripgrep fails when pattern looks like ripgrep flag by @syvb in
[#18091](https://github.com/google-gemini/gemini-cli/pull/18091) [#18858](https://github.com/google-gemini/gemini-cli/pull/18858)
- fix(cli): color extension link success message green by @MushuEE in - fix(cli): disable auto-completion on Shift+Tab to preserve mode cycling by
[#18386](https://github.com/google-gemini/gemini-cli/pull/18386) @NTaylorMullen in
- undo by @jacob314 in [#19451](https://github.com/google-gemini/gemini-cli/pull/19451)
[#18147](https://github.com/google-gemini/gemini-cli/pull/18147) - use issuer instead of authorization_endpoint for oauth discovery by
- feat(plan): add guidance on iterating on approved plans vs creating new plans @garrettsparks in
by @jerop in [#18346](https://github.com/google-gemini/gemini-cli/pull/18346) [#17332](https://github.com/google-gemini/gemini-cli/pull/17332)
- feat(plan): fix invalid tool calls in plan mode by @Adib234 in - feat(cli): include `/dir add` directories in @ autocomplete suggestions by
[#18352](https://github.com/google-gemini/gemini-cli/pull/18352) @jasmeetsb in [#19246](https://github.com/google-gemini/gemini-cli/pull/19246)
- feat(plan): integrate planning artifacts and tools into primary workflows by - feat(admin): Admin settings should only apply if adminControlsApplicable =
@jerop in [#18375](https://github.com/google-gemini/gemini-cli/pull/18375) true and fetch errors should be fatal by @skeshive in
- Fix permission check by @scidomino in [#19453](https://github.com/google-gemini/gemini-cli/pull/19453)
[#18395](https://github.com/google-gemini/gemini-cli/pull/18395) - Format strict-development-rules command by @g-samroberts in
- ux(polish) autocomplete in the input prompt by @jacob314 in [#19484](https://github.com/google-gemini/gemini-cli/pull/19484)
[#18181](https://github.com/google-gemini/gemini-cli/pull/18181) - feat(core): centralize compatibility checks and add TrueColor detection by
- fix: resolve infinite loop when using 'Modify with external editor' by @spencer426 in
@ppgranger in [#17453](https://github.com/google-gemini/gemini-cli/pull/17453) [#19478](https://github.com/google-gemini/gemini-cli/pull/19478)
- feat: expand verify-release to macOS and Windows by @yunaseoul in - Remove unused files and update index and sidebar. by @g-samroberts in
[#18145](https://github.com/google-gemini/gemini-cli/pull/18145) [#19479](https://github.com/google-gemini/gemini-cli/pull/19479)
- feat(plan): implement support for MCP servers in Plan mode by @Adib234 in - Migrate core render util to use xterm.js as part of the rendering loop. by
[#18229](https://github.com/google-gemini/gemini-cli/pull/18229) @jacob314 in [#19044](https://github.com/google-gemini/gemini-cli/pull/19044)
- chore: update folder trust error messaging by @galz10 in - Changelog for v0.30.0-preview.1 by @gemini-cli-robot in
[#18402](https://github.com/google-gemini/gemini-cli/pull/18402) [#19496](https://github.com/google-gemini/gemini-cli/pull/19496)
- feat(plan): create a metric for execution of plans generated in plan mode by - build: replace deprecated built-in punycode with userland package by @jacob314
@Adib234 in [#18236](https://github.com/google-gemini/gemini-cli/pull/18236) in [#19502](https://github.com/google-gemini/gemini-cli/pull/19502)
- perf(ui): optimize stripUnsafeCharacters with regex by @gsquared94 in - Speculative fixes to try to fix react error. by @jacob314 in
[#18413](https://github.com/google-gemini/gemini-cli/pull/18413) [#19508](https://github.com/google-gemini/gemini-cli/pull/19508)
- feat(context): implement observation masking for tool outputs by @abhipatel12 - fix spacing by @jacob314 in
in [#18389](https://github.com/google-gemini/gemini-cli/pull/18389) [#19494](https://github.com/google-gemini/gemini-cli/pull/19494)
- feat(core,cli): implement session-linked tool output storage and cleanup by - fix(core): ensure user rejections update tool outcome for telemetry by
@abhipatel12 in @abhiasap in [#18982](https://github.com/google-gemini/gemini-cli/pull/18982)
[#18416](https://github.com/google-gemini/gemini-cli/pull/18416) - fix(acp): Initialize config (#18897) by @Mervap in
- Shorten temp directory by @joshualitt in [#18898](https://github.com/google-gemini/gemini-cli/pull/18898)
[#17901](https://github.com/google-gemini/gemini-cli/pull/17901) - fix(core): add error logging for IDE fetch failures by @yuvrajangadsingh in
- feat(plan): add behavioral evals for plan mode by @jerop in [#17981](https://github.com/google-gemini/gemini-cli/pull/17981)
[#18437](https://github.com/google-gemini/gemini-cli/pull/18437) - feat(acp): support set_mode interface (#18890) by @Mervap in
- Add extension registry client by @chrstnb in [#18891](https://github.com/google-gemini/gemini-cli/pull/18891)
[#18396](https://github.com/google-gemini/gemini-cli/pull/18396) - fix(core): robust workspace-based IDE connection discovery by @ehedlund in
- Enable extension config by default by @chrstnb in [#18443](https://github.com/google-gemini/gemini-cli/pull/18443)
[#18447](https://github.com/google-gemini/gemini-cli/pull/18447) - Deflake windows tests. by @jacob314 in
- Automatically generate change logs on release by @g-samroberts in [#19511](https://github.com/google-gemini/gemini-cli/pull/19511)
[#18401](https://github.com/google-gemini/gemini-cli/pull/18401) - Fix: Avoid tool confirmation timeout when no UI listeners are present by
- Remove previewFeatures and default to Gemini 3 by @sehoon38 in @pdHaku0 in [#17955](https://github.com/google-gemini/gemini-cli/pull/17955)
[#18414](https://github.com/google-gemini/gemini-cli/pull/18414) - format md file by @scidomino in
- feat(admin): apply MCP allowlist to extensions & gemini mcp list command by [#19474](https://github.com/google-gemini/gemini-cli/pull/19474)
@skeshive in [#18442](https://github.com/google-gemini/gemini-cli/pull/18442) - feat(cli): add experimental.useOSC52Copy setting by @scidomino in
- fix(cli): improve focus navigation for interactive and background shells by [#19488](https://github.com/google-gemini/gemini-cli/pull/19488)
@galz10 in [#18343](https://github.com/google-gemini/gemini-cli/pull/18343) - feat(cli): replace loading phrases boolean with enum setting by @LyalinDotCom
- Add shortcuts hint and panel for discoverability by @LyalinDotCom in in [#19347](https://github.com/google-gemini/gemini-cli/pull/19347)
[#18035](https://github.com/google-gemini/gemini-cli/pull/18035) - Update skill to adjust for generated results. by @g-samroberts in
- fix(config): treat system settings as read-only during migration and warn user [#19500](https://github.com/google-gemini/gemini-cli/pull/19500)
by @spencer426 in - Fix message too large issue. by @gundermanc in
[#18277](https://github.com/google-gemini/gemini-cli/pull/18277) [#19499](https://github.com/google-gemini/gemini-cli/pull/19499)
- feat(plan): add positive test case and update eval stability policy by @jerop - fix(core): prevent duplicate tool approval entries in auto-saved.toml by
in [#18457](https://github.com/google-gemini/gemini-cli/pull/18457)
- fix- windows: add shell: true for spawnSync to fix EINVAL with .cmd editors by
@zackoch in [#18408](https://github.com/google-gemini/gemini-cli/pull/18408)
- bug(core): Fix bug when saving plans. by @joshualitt in
[#18465](https://github.com/google-gemini/gemini-cli/pull/18465)
- Refactor atCommandProcessor by @scidomino in
[#18461](https://github.com/google-gemini/gemini-cli/pull/18461)
- feat(core): implement persistence and resumption for masked tool outputs by
@abhipatel12 in
[#18451](https://github.com/google-gemini/gemini-cli/pull/18451)
- refactor: simplify tool output truncation to single config by @SandyTao520 in
[#18446](https://github.com/google-gemini/gemini-cli/pull/18446)
- bug(core): Ensure storage is initialized early, even if config is not. by
@joshualitt in
[#18471](https://github.com/google-gemini/gemini-cli/pull/18471)
- chore: Update build-and-start script to support argument forwarding by
@Abhijit-2592 in @Abhijit-2592 in
[#18241](https://github.com/google-gemini/gemini-cli/pull/18241) [#19487](https://github.com/google-gemini/gemini-cli/pull/19487)
- fix(core): prevent subagent bypass in plan mode by @jerop in - fix(core): resolve crash in ClearcutLogger when os.cpus() is empty by @Adib234
[#18484](https://github.com/google-gemini/gemini-cli/pull/18484) in [#19555](https://github.com/google-gemini/gemini-cli/pull/19555)
- feat(cli): add WebSocket-based network logging and streaming chunk support by - chore(core): improve encapsulation and remove unused exports by @adamfweidman
in [#19556](https://github.com/google-gemini/gemini-cli/pull/19556)
- Revert "Add generic searchable list to back settings and extensions (… by
@chrstnb in [#19434](https://github.com/google-gemini/gemini-cli/pull/19434)
- fix(core): improve error type extraction for telemetry by @yunaseoul in
[#19565](https://github.com/google-gemini/gemini-cli/pull/19565)
- fix: remove extra padding in Composer by @jackwotherspoon in
[#19529](https://github.com/google-gemini/gemini-cli/pull/19529)
- feat(plan): support configuring custom plans storage directory by @jerop in
[#19577](https://github.com/google-gemini/gemini-cli/pull/19577)
- Migrate files to resource or references folder. by @g-samroberts in
[#19503](https://github.com/google-gemini/gemini-cli/pull/19503)
- feat(policy): implement project-level policy support by @Abhijit-2592 in
[#18682](https://github.com/google-gemini/gemini-cli/pull/18682)
- feat(core): Implement parallel FC for read only tools. by @joshualitt in
[#18791](https://github.com/google-gemini/gemini-cli/pull/18791)
- chore(skills): adds pr-address-comments skill to work on PR feedback by
@mbleigh in [#19576](https://github.com/google-gemini/gemini-cli/pull/19576)
- refactor(sdk): introduce session-based architecture by @mbleigh in
[#19180](https://github.com/google-gemini/gemini-cli/pull/19180)
- fix(ci): add fallback JSON extraction to issue triage workflow by @bdmorgan in
[#19593](https://github.com/google-gemini/gemini-cli/pull/19593)
- feat(core): refine Edit and WriteFile tool schemas for Gemini 3 by
@SandyTao520 in @SandyTao520 in
[#18383](https://github.com/google-gemini/gemini-cli/pull/18383) [#19476](https://github.com/google-gemini/gemini-cli/pull/19476)
- feat(cli): update approval modes UI by @jerop in - Changelog for v0.30.0-preview.3 by @gemini-cli-robot in
[#18476](https://github.com/google-gemini/gemini-cli/pull/18476) [#19585](https://github.com/google-gemini/gemini-cli/pull/19585)
- fix(cli): reload skills and agents on extension restart by @NTaylorMullen in - fix(plan): exclude EnterPlanMode tool from YOLO mode by @Adib234 in
[#18411](https://github.com/google-gemini/gemini-cli/pull/18411) [#19570](https://github.com/google-gemini/gemini-cli/pull/19570)
- fix(core): expand excludeTools with legacy aliases for renamed tools by - chore: resolve build warnings and update dependencies by @mattKorwel in
@SandyTao520 in [#18880](https://github.com/google-gemini/gemini-cli/pull/18880)
[#18498](https://github.com/google-gemini/gemini-cli/pull/18498) - feat(ui): add source indicators to slash commands by @ehedlund in
- feat(core): overhaul system prompt for rigor, integrity, and intent alignment [#18839](https://github.com/google-gemini/gemini-cli/pull/18839)
by @NTaylorMullen in - docs: refine Plan Mode documentation structure and workflow by @jerop in
[#17263](https://github.com/google-gemini/gemini-cli/pull/17263) [#19644](https://github.com/google-gemini/gemini-cli/pull/19644)
- Patch for generate changelog docs yaml file by @g-samroberts in - Docs: Update release information regarding Gemini 3.1 by @jkcinouye in
[#18496](https://github.com/google-gemini/gemini-cli/pull/18496) [#19568](https://github.com/google-gemini/gemini-cli/pull/19568)
- Code review fixes for show question mark pr. by @jacob314 in - fix(security): rate limit web_fetch tool to mitigate DDoS via prompt injection
[#18480](https://github.com/google-gemini/gemini-cli/pull/18480) by @mattKorwel in
- fix(cli): add SS3 Shift+Tab support for Windows terminals by @ThanhNguyxn in [#19567](https://github.com/google-gemini/gemini-cli/pull/19567)
[#18187](https://github.com/google-gemini/gemini-cli/pull/18187) - Add initial implementation of /extensions explore command by @chrstnb in
- chore: remove redundant planning prompt from final shell by @jerop in [#19029](https://github.com/google-gemini/gemini-cli/pull/19029)
[#18528](https://github.com/google-gemini/gemini-cli/pull/18528) - fix: use discoverOAuthFromWWWAuthenticate for reactive OAuth flow (#18760) by
- docs: require pr-creator skill for PR generation by @NTaylorMullen in @maximus12793 in
[#18536](https://github.com/google-gemini/gemini-cli/pull/18536) [#19038](https://github.com/google-gemini/gemini-cli/pull/19038)
- chore: update colors for ask_user dialog by @jackwotherspoon in - Search updates by @alisa-alisa in
[#18543](https://github.com/google-gemini/gemini-cli/pull/18543) [#19482](https://github.com/google-gemini/gemini-cli/pull/19482)
- feat(core): exempt high-signal tools from output masking by @abhipatel12 in - feat(cli): add support for numpad SS3 sequences by @scidomino in
[#18545](https://github.com/google-gemini/gemini-cli/pull/18545) [#19659](https://github.com/google-gemini/gemini-cli/pull/19659)
- refactor(core): remove memory tool instructions from Gemini 3 prompt by - feat(cli): enhance folder trust with configuration discovery and security
@NTaylorMullen in warnings by @galz10 in
[#18559](https://github.com/google-gemini/gemini-cli/pull/18559) [#19492](https://github.com/google-gemini/gemini-cli/pull/19492)
- chore: remove feedback instruction from system prompt by @NTaylorMullen in - feat(ui): improve startup warnings UX with dismissal and show-count limits by
[#18560](https://github.com/google-gemini/gemini-cli/pull/18560) @spencer426 in
- feat(context): add remote configuration for tool output masking thresholds by [#19584](https://github.com/google-gemini/gemini-cli/pull/19584)
@abhipatel12 in - feat(a2a): Add API key authentication provider by @adamfweidman in
[#18553](https://github.com/google-gemini/gemini-cli/pull/18553) [#19548](https://github.com/google-gemini/gemini-cli/pull/19548)
- feat(core): pause agent timeout budget while waiting for tool confirmation by - Send accepted/removed lines with ACCEPT_FILE telemetry. by @gundermanc in
@abhipatel12 in [#19670](https://github.com/google-gemini/gemini-cli/pull/19670)
[#18415](https://github.com/google-gemini/gemini-cli/pull/18415) - feat(models): support Gemini 3.1 Pro Preview and fixes by @sehoon38 in
- refactor(config): remove experimental.enableEventDrivenScheduler setting by [#19676](https://github.com/google-gemini/gemini-cli/pull/19676)
@abhipatel12 in - feat(plan): enforce read-only constraints in Plan Mode by @mattKorwel in
[#17924](https://github.com/google-gemini/gemini-cli/pull/17924) [#19433](https://github.com/google-gemini/gemini-cli/pull/19433)
- feat(cli): truncate shell output in UI history and improve active shell - fix(cli): allow perfect match @scripts/test-windows-paths.js completions to
display by @jwhelangoog in submit on Enter by @spencer426 in
[#17438](https://github.com/google-gemini/gemini-cli/pull/17438) [#19562](https://github.com/google-gemini/gemini-cli/pull/19562)
- refactor(cli): switch useToolScheduler to event-driven engine by @abhipatel12 - fix(core): treat 503 Service Unavailable as retryable quota error by @sehoon38
in [#18565](https://github.com/google-gemini/gemini-cli/pull/18565) in [#19642](https://github.com/google-gemini/gemini-cli/pull/19642)
- fix(core): correct escaped interpolation in system prompt by @NTaylorMullen in - Update sidebar.json for to allow top nav tabs. by @g-samroberts in
[#18557](https://github.com/google-gemini/gemini-cli/pull/18557) [#19595](https://github.com/google-gemini/gemini-cli/pull/19595)
- propagate abortSignal by @scidomino in - security: strip deceptive Unicode characters from terminal output by @ehedlund
[#18477](https://github.com/google-gemini/gemini-cli/pull/18477) in [#19026](https://github.com/google-gemini/gemini-cli/pull/19026)
- feat(core): conditionally include ctrl+f prompt based on interactive shell - Fixes 'input.on' is not a function error in Gemini CLI by @gundermanc in
setting by @NTaylorMullen in [#19691](https://github.com/google-gemini/gemini-cli/pull/19691)
[#18561](https://github.com/google-gemini/gemini-cli/pull/18561) - Revert "feat(ui): add source indicators to slash commands" by @ehedlund in
- fix(core): ensure `enter_plan_mode` tool registration respects [#19695](https://github.com/google-gemini/gemini-cli/pull/19695)
`experimental.plan` by @jerop in - security: implement deceptive URL detection and disclosure in tool
[#18587](https://github.com/google-gemini/gemini-cli/pull/18587) confirmations by @ehedlund in
- feat(core): transition sub-agents to XML format and improve definitions by [#19288](https://github.com/google-gemini/gemini-cli/pull/19288)
@NTaylorMullen in - fix(core): restore auth consent in headless mode and add unit tests by
[#18555](https://github.com/google-gemini/gemini-cli/pull/18555) @ehedlund in [#19689](https://github.com/google-gemini/gemini-cli/pull/19689)
- docs: Add Plan Mode documentation by @jerop in - Fix unsafe assertions in code_assist folder. by @gundermanc in
[#18582](https://github.com/google-gemini/gemini-cli/pull/18582) [#19706](https://github.com/google-gemini/gemini-cli/pull/19706)
- chore: strengthen validation guidance in system prompt by @NTaylorMullen in - feat(cli): make JetBrains warning more specific by @jacob314 in
[#18544](https://github.com/google-gemini/gemini-cli/pull/18544) [#19687](https://github.com/google-gemini/gemini-cli/pull/19687)
- Fix newline insertion bug in replace tool by @werdnum in - fix(cli): extensions dialog UX polish by @jacob314 in
[#18595](https://github.com/google-gemini/gemini-cli/pull/18595) [#19685](https://github.com/google-gemini/gemini-cli/pull/19685)
- fix(evals): update save_memory evals and simplify tool description by - fix(cli): use getDisplayString for manual model selection in dialog by
@NTaylorMullen in @sehoon38 in [#19726](https://github.com/google-gemini/gemini-cli/pull/19726)
[#18610](https://github.com/google-gemini/gemini-cli/pull/18610) - feat(policy): repurpose "Always Allow" persistence to workspace level by
- chore(evals): update validation_fidelity_pre_existing_errors to USUALLY_PASSES @Abhijit-2592 in
by @NTaylorMullen in [#19707](https://github.com/google-gemini/gemini-cli/pull/19707)
[#18617](https://github.com/google-gemini/gemini-cli/pull/18617) - fix(cli): re-enable CLI banner by @sehoon38 in
- fix: shorten tool call IDs and fix duplicate tool name in truncated output [#19741](https://github.com/google-gemini/gemini-cli/pull/19741)
filenames by @SandyTao520 in - Disallow and suppress unsafe assignment by @gundermanc in
[#18600](https://github.com/google-gemini/gemini-cli/pull/18600) [#19736](https://github.com/google-gemini/gemini-cli/pull/19736)
- feat(cli): implement atomic writes and safety checks for trusted folders by - feat(core): migrate read_file to 1-based start_line/end_line parameters by
@galz10 in [#18406](https://github.com/google-gemini/gemini-cli/pull/18406)
- Remove relative docs links by @chrstnb in
[#18650](https://github.com/google-gemini/gemini-cli/pull/18650)
- docs: add legacy snippets convention to GEMINI.md by @NTaylorMullen in
[#18597](https://github.com/google-gemini/gemini-cli/pull/18597)
- fix(chore): Support linting for cjs by @aswinashok44 in
[#18639](https://github.com/google-gemini/gemini-cli/pull/18639)
- feat: move shell efficiency guidelines to tool description by @NTaylorMullen
in [#18614](https://github.com/google-gemini/gemini-cli/pull/18614)
- Added "" as default value, since getText() used to expect a string only and
thus crashed when undefined... Fixes #18076 by @019-Abhi in
[#18099](https://github.com/google-gemini/gemini-cli/pull/18099)
- Allow @-includes outside of workspaces (with permission) by @scidomino in
[#18470](https://github.com/google-gemini/gemini-cli/pull/18470)
- chore: make `ask_user` header description more clear by @jackwotherspoon in
[#18657](https://github.com/google-gemini/gemini-cli/pull/18657)
- refactor(core): model-dependent tool definitions by @aishaneeshah in
[#18563](https://github.com/google-gemini/gemini-cli/pull/18563)
- Harded code assist converter. by @jacob314 in
[#18656](https://github.com/google-gemini/gemini-cli/pull/18656)
- bug(core): Fix minor bug in migration logic. by @joshualitt in
[#18661](https://github.com/google-gemini/gemini-cli/pull/18661)
- feat: enable plan mode experiment in settings by @jerop in
[#18636](https://github.com/google-gemini/gemini-cli/pull/18636)
- refactor: push isValidPath() into parsePastedPaths() by @scidomino in
[#18664](https://github.com/google-gemini/gemini-cli/pull/18664)
- fix(cli): correct 'esc to cancel' position and restore duration display by
@NTaylorMullen in
[#18534](https://github.com/google-gemini/gemini-cli/pull/18534)
- feat(cli): add DevTools integration with gemini-cli-devtools by @SandyTao520
in [#18648](https://github.com/google-gemini/gemini-cli/pull/18648)
- chore: remove unused exports and redundant hook files by @SandyTao520 in
[#18681](https://github.com/google-gemini/gemini-cli/pull/18681)
- Fix number of lines being reported in rewind confirmation dialog by @Adib234
in [#18675](https://github.com/google-gemini/gemini-cli/pull/18675)
- feat(cli): disable folder trust in headless mode by @galz10 in
[#18407](https://github.com/google-gemini/gemini-cli/pull/18407)
- Disallow unsafe type assertions by @gundermanc in
[#18688](https://github.com/google-gemini/gemini-cli/pull/18688)
- Change event type for release by @g-samroberts in
[#18693](https://github.com/google-gemini/gemini-cli/pull/18693)
- feat: handle multiple dynamic context filenames in system prompt by
@NTaylorMullen in
[#18598](https://github.com/google-gemini/gemini-cli/pull/18598)
- Properly parse at-commands with narrow non-breaking spaces by @scidomino in
[#18677](https://github.com/google-gemini/gemini-cli/pull/18677)
- refactor(core): centralize core tool definitions and support model-specific
schemas by @aishaneeshah in
[#18662](https://github.com/google-gemini/gemini-cli/pull/18662)
- feat(core): Render memory hierarchically in context. by @joshualitt in
[#18350](https://github.com/google-gemini/gemini-cli/pull/18350)
- feat: Ctrl+O to expand paste placeholder by @jackwotherspoon in
[#18103](https://github.com/google-gemini/gemini-cli/pull/18103)
- fix(cli): Improve header spacing by @NTaylorMullen in
[#18531](https://github.com/google-gemini/gemini-cli/pull/18531)
- Feature/quota visibility 16795 by @spencer426 in
[#18203](https://github.com/google-gemini/gemini-cli/pull/18203)
- Inline thinking bubbles with summary/full modes by @LyalinDotCom in
[#18033](https://github.com/google-gemini/gemini-cli/pull/18033)
- docs: remove TOC marker from Plan Mode header by @jerop in
[#18678](https://github.com/google-gemini/gemini-cli/pull/18678)
- fix(ui): remove redundant newlines in Gemini messages by @NTaylorMullen in
[#18538](https://github.com/google-gemini/gemini-cli/pull/18538)
- test(cli): fix AppContainer act() warnings and improve waitFor resilience by
@NTaylorMullen in
[#18676](https://github.com/google-gemini/gemini-cli/pull/18676)
- refactor(core): refine Security & System Integrity section in system prompt by
@NTaylorMullen in
[#18601](https://github.com/google-gemini/gemini-cli/pull/18601)
- Fix layout rounding. by @gundermanc in
[#18667](https://github.com/google-gemini/gemini-cli/pull/18667)
- docs(skills): enhance pr-creator safety and interactivity by @NTaylorMullen in
[#18616](https://github.com/google-gemini/gemini-cli/pull/18616)
- test(core): remove hardcoded model from TestRig by @NTaylorMullen in
[#18710](https://github.com/google-gemini/gemini-cli/pull/18710)
- feat(core): optimize sub-agents system prompt intro by @NTaylorMullen in
[#18608](https://github.com/google-gemini/gemini-cli/pull/18608)
- feat(cli): update approval mode labels and shortcuts per latest UX spec by
@jerop in [#18698](https://github.com/google-gemini/gemini-cli/pull/18698)
- fix(plan): update persistent approval mode setting by @Adib234 in
[#18638](https://github.com/google-gemini/gemini-cli/pull/18638)
- fix: move toasts location to left side by @jackwotherspoon in
[#18705](https://github.com/google-gemini/gemini-cli/pull/18705)
- feat(routing): restrict numerical routing to Gemini 3 family by @mattKorwel in
[#18478](https://github.com/google-gemini/gemini-cli/pull/18478)
- fix(ide): fix ide nudge setting by @skeshive in
[#18733](https://github.com/google-gemini/gemini-cli/pull/18733)
- fix(core): standardize tool formatting in system prompts by @NTaylorMullen in
[#18615](https://github.com/google-gemini/gemini-cli/pull/18615)
- chore: consolidate to green in ask user dialog by @jackwotherspoon in
[#18734](https://github.com/google-gemini/gemini-cli/pull/18734)
- feat: add `extensionsExplore` setting to enable extensions explore UI. by
@sripasg in [#18686](https://github.com/google-gemini/gemini-cli/pull/18686)
- feat(cli): defer devtools startup and integrate with F12 by @SandyTao520 in
[#18695](https://github.com/google-gemini/gemini-cli/pull/18695)
- ui: update & subdue footer colors and animate progress indicator by
@keithguerin in
[#18570](https://github.com/google-gemini/gemini-cli/pull/18570)
- test: add model-specific snapshots for coreTools by @aishaneeshah in
[#18707](https://github.com/google-gemini/gemini-cli/pull/18707)
- ci: shard windows tests and fix event listener leaks by @NTaylorMullen in
[#18670](https://github.com/google-gemini/gemini-cli/pull/18670)
- fix: allow `ask_user` tool in yolo mode by @jackwotherspoon in
[#18541](https://github.com/google-gemini/gemini-cli/pull/18541)
- feat: redact disabled tools from system prompt (#13597) by @NTaylorMullen in
[#18613](https://github.com/google-gemini/gemini-cli/pull/18613)
- Update Gemini.md to use the curent year on creating new files by @sehoon38 in
[#18460](https://github.com/google-gemini/gemini-cli/pull/18460)
- Code review cleanup for thinking display by @jacob314 in
[#18720](https://github.com/google-gemini/gemini-cli/pull/18720)
- fix(cli): hide scrollbars when in alternate buffer copy mode by @werdnum in
[#18354](https://github.com/google-gemini/gemini-cli/pull/18354)
- Fix issues with rip grep by @gundermanc in
[#18756](https://github.com/google-gemini/gemini-cli/pull/18756)
- fix(cli): fix history navigation regression after prompt autocomplete by
@sehoon38 in [#18752](https://github.com/google-gemini/gemini-cli/pull/18752)
- chore: cleanup unused and add unlisted dependencies in packages/cli by
@adamfweidman in @adamfweidman in
[#18749](https://github.com/google-gemini/gemini-cli/pull/18749) [#19526](https://github.com/google-gemini/gemini-cli/pull/19526)
- Fix issue where Gemini CLI creates tests in a new file by @gundermanc in - feat(cli): improve CTRL+O experience for both standard and alternate screen
[#18409](https://github.com/google-gemini/gemini-cli/pull/18409) buffer (ASB) modes by @jwhelangoog in
- feat(telemetry): Ensure experiment IDs are included in OpenTelemetry logs by [#19010](https://github.com/google-gemini/gemini-cli/pull/19010)
@kevin-ramdass in - Utilize pipelining of grep_search -> read_file to eliminate turns by
[#18747](https://github.com/google-gemini/gemini-cli/pull/18747) @gundermanc in
- fix(patch): cherry-pick e9a9474 to release/v0.29.0-preview.0-pr-18840 to patch [#19574](https://github.com/google-gemini/gemini-cli/pull/19574)
version v0.29.0-preview.0 and create version 0.29.0-preview.1 by - refactor(core): remove unsafe type assertions in error utils (Phase 1.1) by
@mattKorwel in
[#19750](https://github.com/google-gemini/gemini-cli/pull/19750)
- Disallow unsafe returns. by @gundermanc in
[#19767](https://github.com/google-gemini/gemini-cli/pull/19767)
- fix(cli): filter subagent sessions from resume history by @abhipatel12 in
[#19698](https://github.com/google-gemini/gemini-cli/pull/19698)
- chore(lint): fix lint errors seen when running npm run lint by @abhipatel12 in
[#19844](https://github.com/google-gemini/gemini-cli/pull/19844)
- feat(core): remove unnecessary login verbiage from Code Assist auth by
@NTaylorMullen in
[#19861](https://github.com/google-gemini/gemini-cli/pull/19861)
- fix(plan): time share by approval mode dashboard reporting negative time
shares by @Adib234 in
[#19847](https://github.com/google-gemini/gemini-cli/pull/19847)
- fix(core): allow any preview model in quota access check by @bdmorgan in
[#19867](https://github.com/google-gemini/gemini-cli/pull/19867)
- fix(core): prevent omission placeholder deletions in replace/write_file by
@nsalerni in [#19870](https://github.com/google-gemini/gemini-cli/pull/19870)
- fix(core): add uniqueness guard to edit tool by @Shivangisharma4 in
[#19890](https://github.com/google-gemini/gemini-cli/pull/19890)
- refactor(config): remove enablePromptCompletion from settings by @sehoon38 in
[#19974](https://github.com/google-gemini/gemini-cli/pull/19974)
- refactor(core): move session conversion logic to core by @abhipatel12 in
[#19972](https://github.com/google-gemini/gemini-cli/pull/19972)
- Fix: Persist manual model selection on restart #19864 by @Nixxx19 in
[#19891](https://github.com/google-gemini/gemini-cli/pull/19891)
- fix(core): increase default retry attempts and add quota error backoff by
@sehoon38 in [#19949](https://github.com/google-gemini/gemini-cli/pull/19949)
- feat(core): add policy chain support for Gemini 3.1 by @sehoon38 in
[#19991](https://github.com/google-gemini/gemini-cli/pull/19991)
- Updates command reference and /stats command. by @g-samroberts in
[#19794](https://github.com/google-gemini/gemini-cli/pull/19794)
- Fix for silent failures in non-interactive mode by @owenofbrien in
[#19905](https://github.com/google-gemini/gemini-cli/pull/19905)
- fix(plan): allow plan mode writes on Windows and fix prompt paths by @Adib234
in [#19658](https://github.com/google-gemini/gemini-cli/pull/19658)
- fix(core): prevent OAuth server crash on unexpected requests by @reyyanxahmed
in [#19668](https://github.com/google-gemini/gemini-cli/pull/19668)
- feat: Map tool kinds to explicit ACP.ToolKind values and update test … by
@sripasg in [#19547](https://github.com/google-gemini/gemini-cli/pull/19547)
- chore: restrict gemini-automted-issue-triage to only allow echo by @galz10 in
[#20047](https://github.com/google-gemini/gemini-cli/pull/20047)
- Allow ask headers longer than 16 chars by @scidomino in
[#20041](https://github.com/google-gemini/gemini-cli/pull/20041)
- fix(core): prevent state corruption in McpClientManager during collis by @h30s
in [#19782](https://github.com/google-gemini/gemini-cli/pull/19782)
- fix(bundling): copy devtools package to bundle for runtime resolution by
@SandyTao520 in
[#19766](https://github.com/google-gemini/gemini-cli/pull/19766)
- feat(policy): Support MCP Server Wildcards in Policy Engine by @jerop in
[#20024](https://github.com/google-gemini/gemini-cli/pull/20024)
- docs(CONTRIBUTING): update React DevTools version to 6 by @mmgok in
[#20014](https://github.com/google-gemini/gemini-cli/pull/20014)
- feat(core): optimize tool descriptions and schemas for Gemini 3 by
@aishaneeshah in
[#19643](https://github.com/google-gemini/gemini-cli/pull/19643)
- feat(core): implement experimental direct web fetch by @mbleigh in
[#19557](https://github.com/google-gemini/gemini-cli/pull/19557)
- feat(core): replace expected_replacements with allow_multiple in replace tool
by @SandyTao520 in
[#20033](https://github.com/google-gemini/gemini-cli/pull/20033)
- fix(sandbox): harden image packaging integrity checks by @aviralgarg05 in
[#19552](https://github.com/google-gemini/gemini-cli/pull/19552)
- fix(core): allow environment variable expansion and explicit overrides for MCP
servers by @galz10 in
[#18837](https://github.com/google-gemini/gemini-cli/pull/18837)
- feat(policy): Implement Tool Annotation Matching in Policy Engine by @jerop in
[#20029](https://github.com/google-gemini/gemini-cli/pull/20029)
- fix(core): prevent utility calls from changing session active model by
@adamfweidman in
[#20035](https://github.com/google-gemini/gemini-cli/pull/20035)
- fix(cli): skip workspace policy loading when in home directory by
@Abhijit-2592 in
[#20054](https://github.com/google-gemini/gemini-cli/pull/20054)
- fix(scripts): Add Windows (win32/x64) support to lint.js by @ZafeerMahmood in
[#16193](https://github.com/google-gemini/gemini-cli/pull/16193)
- fix(a2a-server): Remove unsafe type assertions in agent by @Nixxx19 in
[#19723](https://github.com/google-gemini/gemini-cli/pull/19723)
- Fix: Handle corrupted token file gracefully when switching auth types (#19845)
by @Nixxx19 in
[#19850](https://github.com/google-gemini/gemini-cli/pull/19850)
- fix critical dep vulnerability by @scidomino in
[#20087](https://github.com/google-gemini/gemini-cli/pull/20087)
- Add new setting to configure maxRetries by @kevinjwang1 in
[#20064](https://github.com/google-gemini/gemini-cli/pull/20064)
- Stabilize tests. by @gundermanc in
[#20095](https://github.com/google-gemini/gemini-cli/pull/20095)
- make windows tests mandatory by @scidomino in
[#20096](https://github.com/google-gemini/gemini-cli/pull/20096)
- Add 3.1 pro preview to behavioral evals. by @gundermanc in
[#20088](https://github.com/google-gemini/gemini-cli/pull/20088)
- feat:PR-rate-limit by @JagjeevanAK in
[#19804](https://github.com/google-gemini/gemini-cli/pull/19804)
- feat(cli): allow expanding full details of MCP tool on approval by @y-okt in
[#19916](https://github.com/google-gemini/gemini-cli/pull/19916)
- feat(security): Introduce Conseca framework by @shrishabh in
[#13193](https://github.com/google-gemini/gemini-cli/pull/13193)
- fix(cli): Remove unsafe type assertions in activityLogger #19713 by @Nixxx19
in [#19745](https://github.com/google-gemini/gemini-cli/pull/19745)
- feat: implement AfterTool tail tool calls by @googlestrobe in
[#18486](https://github.com/google-gemini/gemini-cli/pull/18486)
- ci(actions): fix PR rate limiter excluding maintainers by @scidomino in
[#20117](https://github.com/google-gemini/gemini-cli/pull/20117)
- Shortcuts: Move SectionHeader title below top line and refine styling by
@keithguerin in
[#18721](https://github.com/google-gemini/gemini-cli/pull/18721)
- refactor(ui): Update and simplify use of gray colors in themes by @keithguerin
in [#20141](https://github.com/google-gemini/gemini-cli/pull/20141)
- fix punycode2 by @jacob314 in
[#20154](https://github.com/google-gemini/gemini-cli/pull/20154)
- feat(ide): add GEMINI_CLI_IDE_PID env var to override IDE process detection by
@kiryltech in [#15842](https://github.com/google-gemini/gemini-cli/pull/15842)
- feat(policy): Propagate Tool Annotations for MCP Servers by @jerop in
[#20083](https://github.com/google-gemini/gemini-cli/pull/20083)
- fix(a2a-server): pass allowedTools settings to core Config by @reyyanxahmed in
[#19680](https://github.com/google-gemini/gemini-cli/pull/19680)
- feat(mcp): add progress bar, throttling, and input validation for MCP tool
progress by @jasmeetsb in
[#19772](https://github.com/google-gemini/gemini-cli/pull/19772)
- feat(policy): centralize plan mode tool visibility in policy engine by @jerop
in [#20178](https://github.com/google-gemini/gemini-cli/pull/20178)
- feat(browser): implement experimental browser agent by @gsquared94 in
[#19284](https://github.com/google-gemini/gemini-cli/pull/19284)
- feat(plan): summarize work after executing a plan by @jerop in
[#19432](https://github.com/google-gemini/gemini-cli/pull/19432)
- fix(core): create new McpClient on restart to apply updated config by @h30s in
[#20126](https://github.com/google-gemini/gemini-cli/pull/20126)
- Changelog for v0.30.0-preview.5 by @gemini-cli-robot in
[#20107](https://github.com/google-gemini/gemini-cli/pull/20107)
- Update packages. by @jacob314 in
[#20152](https://github.com/google-gemini/gemini-cli/pull/20152)
- Fix extension env dir loading issue by @chrstnb in
[#20198](https://github.com/google-gemini/gemini-cli/pull/20198)
- restrict /assign to help-wanted issues by @scidomino in
[#20207](https://github.com/google-gemini/gemini-cli/pull/20207)
- feat(plan): inject message when user manually exits Plan mode by @jerop in
[#20203](https://github.com/google-gemini/gemini-cli/pull/20203)
- feat(extensions): enforce folder trust for local extension install by @galz10
in [#19703](https://github.com/google-gemini/gemini-cli/pull/19703)
- feat(hooks): adds support for RuntimeHook functions. by @mbleigh in
[#19598](https://github.com/google-gemini/gemini-cli/pull/19598)
- Docs: Update UI links. by @jkcinouye in
[#20224](https://github.com/google-gemini/gemini-cli/pull/20224)
- feat: prompt users to run /terminal-setup with yes/no by @ishaanxgupta in
[#16235](https://github.com/google-gemini/gemini-cli/pull/16235)
- fix: additional high vulnerabilities (minimatch, cross-spawn) by @adamfweidman
in [#20221](https://github.com/google-gemini/gemini-cli/pull/20221)
- feat(telemetry): Add context breakdown to API response event by @SandyTao520
in [#19699](https://github.com/google-gemini/gemini-cli/pull/19699)
- Docs: Add nested sub-folders for related topics by @g-samroberts in
[#20235](https://github.com/google-gemini/gemini-cli/pull/20235)
- feat(plan): support automatic model switching for Plan Mode by @jerop in
[#20240](https://github.com/google-gemini/gemini-cli/pull/20240)
- fix(patch): cherry-pick 58df1c6 to release/v0.31.0-preview.0-pr-20374 to patch
version v0.31.0-preview.0 and create version 0.31.0-preview.1 by
@gemini-cli-robot in @gemini-cli-robot in
[#18841](https://github.com/google-gemini/gemini-cli/pull/18841) [#20568](https://github.com/google-gemini/gemini-cli/pull/20568)
- fix(patch): cherry-pick 08e8eea to release/v0.29.0-preview.1-pr-18855 to patch - fix(patch): cherry-pick ea48bd9 to release/v0.31.0-preview.1-pr-20577
version v0.29.0-preview.1 and create version 0.29.0-preview.2 by [CONFLICTS] by @gemini-cli-robot in
[#20592](https://github.com/google-gemini/gemini-cli/pull/20592)
- fix(patch): cherry-pick 32e777f to release/v0.31.0-preview.2-pr-20531 to patch
version v0.31.0-preview.2 and create version 0.31.0-preview.3 by
@gemini-cli-robot in @gemini-cli-robot in
[#18905](https://github.com/google-gemini/gemini-cli/pull/18905) [#20607](https://github.com/google-gemini/gemini-cli/pull/20607)
- fix(patch): cherry-pick d0c6a56 to release/v0.29.0-preview.2-pr-18976 to patch
version v0.29.0-preview.2 and create version 0.29.0-preview.3 by
@gemini-cli-robot in
[#19023](https://github.com/google-gemini/gemini-cli/pull/19023)
- fix(patch): cherry-pick e5ff202 to release/v0.29.0-preview.3-pr-19254 to patch
version v0.29.0-preview.3 and create version 0.29.0-preview.4 by
@gemini-cli-robot in
[#19264](https://github.com/google-gemini/gemini-cli/pull/19264)
- fix(patch): cherry-pick 9590a09 to release/v0.29.0-preview.4-pr-18771 to patch
version v0.29.0-preview.4 and create version 0.29.0-preview.5 by
@gemini-cli-robot in
[#19274](https://github.com/google-gemini/gemini-cli/pull/19274)
**Full Changelog**: **Full Changelog**:
https://github.com/google-gemini/gemini-cli/compare/v0.28.2...v0.29.0 https://github.com/google-gemini/gemini-cli/compare/v0.30.1...v0.31.0
+187 -297
View File
@@ -1,6 +1,6 @@
# Preview release: v0.30.0-preview.5 # Preview release: v0.32.0-preview.0
Released: February 24, 2026 Released: February 27, 2026
Our preview release includes the latest, new, and experimental features. This Our preview release includes the latest, new, and experimental features. This
release may not be as stable as our [latest weekly release](latest.md). release may not be as stable as our [latest weekly release](latest.md).
@@ -13,306 +13,196 @@ npm install -g @google/gemini-cli@preview
## Highlights ## Highlights
- **Initial SDK Package:** Introduced the initial SDK package with support for - **Plan Mode Enhancements**: Significant updates to Plan Mode, including
custom skills and dynamic system instructions. support for modifying plans in external editors, adaptive workflows based on
- **Refined Plan Mode:** Refined Plan Mode with support for enabling skills, task complexity, and new integration tests.
improved agentic execution, and project exploration without planning. - **Agent and Core Engine Updates**: Enabled the generalist agent, introduced
- **Enhanced CLI UI:** Enhanced CLI UI with a new clean UI toggle, minimal-mode `Kind.Agent` for sub-agent classification, implemented task tracking
bleed-through, and support for Ctrl-Z suspension. foundation, and improved Agent-to-Agent (A2A) streaming and content
- **`--policy` flag:** Added the `--policy` flag to support user-defined extraction.
policies. - **CLI & User Experience**: Introduced interactive shell autocompletion, added
- **New Themes:** Added Solarized Dark and Solarized Light themes. a new verbosity mode for cleaner error reporting, enabled parallel loading of
extensions, and improved UI hints and shortcut handling.
- **Billing and Security**: Implemented G1 AI credits overage flow with enhanced
billing telemetry, updated the authentication handshake to specification, and
added support for a policy engine in extensions.
- **Stability and Bug Fixes**: Addressed numerous issues including 100% CPU
consumption by orphaned processes, enhanced retry logic for Code Assist,
reduced intrusive MCP errors, and merged duplicate imports across packages.
## What's Changed ## What's Changed
- fix(patch): cherry-pick 2c1d6f8 to release/v0.30.0-preview.4-pr-19369 to patch - feat(plan): add integration tests for plan mode by @Adib234 in
version v0.30.0-preview.4 and create version 0.30.0-preview.5 by [#20214](https://github.com/google-gemini/gemini-cli/pull/20214)
@gemini-cli-robot in - fix(acp): update auth handshake to spec by @skeshive in
[#20086](https://github.com/google-gemini/gemini-cli/pull/20086) [#19725](https://github.com/google-gemini/gemini-cli/pull/19725)
- fix(patch): cherry-pick 261788c to release/v0.30.0-preview.0-pr-19453 to patch - feat(core): implement robust A2A streaming reassembly and fix task continuity
version v0.30.0-preview.0 and create version 0.30.0-preview.1 by by @adamfweidman in
@gemini-cli-robot in [#20091](https://github.com/google-gemini/gemini-cli/pull/20091)
[#19490](https://github.com/google-gemini/gemini-cli/pull/19490) - feat(cli): load extensions in parallel by @scidomino in
- feat(ux): added text wrapping capabilities to markdown tables by @devr0306 in [#20229](https://github.com/google-gemini/gemini-cli/pull/20229)
[#18240](https://github.com/google-gemini/gemini-cli/pull/18240) - Plumb the maxAttempts setting through Config args by @kevinjwang1 in
- Revert "fix(mcp): ensure MCP transport is closed to prevent memory leaks" by [#20239](https://github.com/google-gemini/gemini-cli/pull/20239)
@skeshive in [#18771](https://github.com/google-gemini/gemini-cli/pull/18771) - fix(cli): skip 404 errors in setup-github file downloads by @h30s in
- chore(release): bump version to 0.30.0-nightly.20260210.a2174751d by [#20287](https://github.com/google-gemini/gemini-cli/pull/20287)
@gemini-cli-robot in - fix(cli): expose model.name setting in settings dialog for persistence by
[#18772](https://github.com/google-gemini/gemini-cli/pull/18772) @achaljhawar in
- chore: cleanup unused and add unlisted dependencies in packages/core by [#19605](https://github.com/google-gemini/gemini-cli/pull/19605)
@adamfweidman in - docs: remove legacy cmd examples in favor of powershell by @scidomino in
[#18762](https://github.com/google-gemini/gemini-cli/pull/18762) [#20323](https://github.com/google-gemini/gemini-cli/pull/20323)
- chore(core): update activate_skill prompt verbiage to be more direct by - feat(core): Enable model steering in workspace. by @joshualitt in
@NTaylorMullen in [#20343](https://github.com/google-gemini/gemini-cli/pull/20343)
[#18605](https://github.com/google-gemini/gemini-cli/pull/18605) - fix: remove trailing comma in issue triage workflow settings json by @Nixxx19
- Add autoconfigure memory usage setting to the dialog by @jacob314 in in [#20265](https://github.com/google-gemini/gemini-cli/pull/20265)
[#18510](https://github.com/google-gemini/gemini-cli/pull/18510) - feat(core): implement task tracker foundation and service by @anj-s in
- fix(core): prevent race condition in policy persistence by @braddux in [#19464](https://github.com/google-gemini/gemini-cli/pull/19464)
[#18506](https://github.com/google-gemini/gemini-cli/pull/18506) - test: support tests that include color information by @jacob314 in
- fix(evals): prevent false positive in hierarchical memory test by [#20220](https://github.com/google-gemini/gemini-cli/pull/20220)
- feat(core): introduce Kind.Agent for sub-agent classification by @abhipatel12
in [#20369](https://github.com/google-gemini/gemini-cli/pull/20369)
- Changelog for v0.30.0 by @gemini-cli-robot in
[#20252](https://github.com/google-gemini/gemini-cli/pull/20252)
- Update changelog workflow to reject nightly builds by @g-samroberts in
[#20248](https://github.com/google-gemini/gemini-cli/pull/20248)
- Changelog for v0.31.0-preview.0 by @gemini-cli-robot in
[#20249](https://github.com/google-gemini/gemini-cli/pull/20249)
- feat(cli): hide workspace policy update dialog and auto-accept by default by
@Abhijit-2592 in @Abhijit-2592 in
[#18777](https://github.com/google-gemini/gemini-cli/pull/18777) [#20351](https://github.com/google-gemini/gemini-cli/pull/20351)
- test(evals): mark all `save_memory` evals as `USUALLY_PASSES` due to - feat(core): rename grep_search include parameter to include_pattern by
unreliability by @jerop in
[#18786](https://github.com/google-gemini/gemini-cli/pull/18786)
- feat(cli): add setting to hide shortcuts hint UI by @LyalinDotCom in
[#18562](https://github.com/google-gemini/gemini-cli/pull/18562)
- feat(core): formalize 5-phase sequential planning workflow by @jerop in
[#18759](https://github.com/google-gemini/gemini-cli/pull/18759)
- Introduce limits for search results. by @gundermanc in
[#18767](https://github.com/google-gemini/gemini-cli/pull/18767)
- fix(cli): allow closing debug console after auto-open via flicker by
@SandyTao520 in @SandyTao520 in
[#18795](https://github.com/google-gemini/gemini-cli/pull/18795) [#20328](https://github.com/google-gemini/gemini-cli/pull/20328)
- feat(masking): enable tool output masking by default by @abhipatel12 in - feat(plan): support opening and modifying plan in external editor by @Adib234
[#18564](https://github.com/google-gemini/gemini-cli/pull/18564) in [#20348](https://github.com/google-gemini/gemini-cli/pull/20348)
- perf(ui): optimize table rendering by memoizing styled characters by @devr0306 - feat(cli): implement interactive shell autocompletion by @mrpmohiburrahman in
in [#18770](https://github.com/google-gemini/gemini-cli/pull/18770) [#20082](https://github.com/google-gemini/gemini-cli/pull/20082)
- feat: multi-line text answers in ask-user tool by @jackwotherspoon in - fix(core): allow /memory add to work in plan mode by @Jefftree in
[#18741](https://github.com/google-gemini/gemini-cli/pull/18741) [#20353](https://github.com/google-gemini/gemini-cli/pull/20353)
- perf(cli): truncate large debug logs and limit message history by @mattKorwel - feat(core): add HTTP 499 to retryable errors and map to RetryableQuotaError by
in [#18663](https://github.com/google-gemini/gemini-cli/pull/18663) @bdmorgan in [#20432](https://github.com/google-gemini/gemini-cli/pull/20432)
- fix(core): complete MCP discovery when configured servers are skipped by - feat(core): Enable generalist agent by @joshualitt in
@LyalinDotCom in [#19665](https://github.com/google-gemini/gemini-cli/pull/19665)
[#18586](https://github.com/google-gemini/gemini-cli/pull/18586) - Updated tests in TableRenderer.test.tsx to use SVG snapshots by @devr0306 in
- fix(core): cache CLI version to ensure consistency during sessions by [#20450](https://github.com/google-gemini/gemini-cli/pull/20450)
@sehoon38 in [#18793](https://github.com/google-gemini/gemini-cli/pull/18793) - Refactor Github Action per b/485167538 by @google-admin in
- fix(cli): resolve double rendering in shpool and address vscode lint warnings [#19443](https://github.com/google-gemini/gemini-cli/pull/19443)
by @braddux in - fix(github): resolve actionlint and yamllint regressions from #19443 by @jerop
[#18704](https://github.com/google-gemini/gemini-cli/pull/18704) in [#20467](https://github.com/google-gemini/gemini-cli/pull/20467)
- feat(plan): document and validate Plan Mode policy overrides by @jerop in - fix: action var usage by @galz10 in
[#18825](https://github.com/google-gemini/gemini-cli/pull/18825) [#20492](https://github.com/google-gemini/gemini-cli/pull/20492)
- Fix pressing any key to exit select mode. by @jacob314 in - feat(core): improve A2A content extraction by @adamfweidman in
[#18421](https://github.com/google-gemini/gemini-cli/pull/18421) [#20487](https://github.com/google-gemini/gemini-cli/pull/20487)
- fix(cli): update F12 behavior to only open drawer if browser fails by - fix(cli): support quota error fallbacks for all authentication types by
@SandyTao520 in @sehoon38 in [#20475](https://github.com/google-gemini/gemini-cli/pull/20475)
[#18829](https://github.com/google-gemini/gemini-cli/pull/18829) - fix(core): flush transcript for pure tool-call responses to ensure BeforeTool
- feat(plan): allow skills to be enabled in plan mode by @Adib234 in hooks see complete state by @krishdef7 in
[#18817](https://github.com/google-gemini/gemini-cli/pull/18817) [#20419](https://github.com/google-gemini/gemini-cli/pull/20419)
- docs(plan): add documentation for plan mode tools by @jerop in - feat(plan): adapt planning workflow based on complexity of task by @jerop in
[#18827](https://github.com/google-gemini/gemini-cli/pull/18827) [#20465](https://github.com/google-gemini/gemini-cli/pull/20465)
- Remove experimental note in extension settings docs by @chrstnb in - fix: prevent orphaned processes from consuming 100% CPU when terminal closes
[#18822](https://github.com/google-gemini/gemini-cli/pull/18822) by @yuvrajangadsingh in
- Update prompt and grep tool definition to limit context size by @gundermanc in [#16965](https://github.com/google-gemini/gemini-cli/pull/16965)
[#18780](https://github.com/google-gemini/gemini-cli/pull/18780) - feat(core): increase fetch timeout and fix [object Object] error
- docs(plan): add `ask_user` tool documentation by @jerop in stringification by @bdmorgan in
[#18830](https://github.com/google-gemini/gemini-cli/pull/18830) [#20441](https://github.com/google-gemini/gemini-cli/pull/20441)
- Revert unintended credentials exposure by @Adib234 in - [Gemma x Gemini CLI] Add an Experimental Gemma Router that uses a LiteRT-LM
[#18840](https://github.com/google-gemini/gemini-cli/pull/18840) shim into the Composite Model Classifier Strategy by @sidwan02 in
- feat(core): update internal utility models to Gemini 3 by @SandyTao520 in [#17231](https://github.com/google-gemini/gemini-cli/pull/17231)
[#18773](https://github.com/google-gemini/gemini-cli/pull/18773) - docs(plan): update documentation regarding supporting editing of plan files
- feat(a2a): add value-resolver for auth credential resolution by @adamfweidman during plan approval by @Adib234 in
in [#18653](https://github.com/google-gemini/gemini-cli/pull/18653) [#20452](https://github.com/google-gemini/gemini-cli/pull/20452)
- Removed getPlainTextLength by @devr0306 in - test(cli): fix flaky ToolResultDisplay overflow test by @jwhelangoog in
[#18848](https://github.com/google-gemini/gemini-cli/pull/18848) [#20518](https://github.com/google-gemini/gemini-cli/pull/20518)
- More grep prompt tweaks by @gundermanc in - ui(cli): reduce length of Ctrl+O hint by @jwhelangoog in
[#18846](https://github.com/google-gemini/gemini-cli/pull/18846) [#20490](https://github.com/google-gemini/gemini-cli/pull/20490)
- refactor(cli): Reactive useSettingsStore hook by @psinha40898 in - fix(ui): correct styled table width calculations by @devr0306 in
[#14915](https://github.com/google-gemini/gemini-cli/pull/14915) [#20042](https://github.com/google-gemini/gemini-cli/pull/20042)
- fix(mcp): Ensure that stdio MCP server execution has the `GEMINI_CLI=1` env - Avoid overaggressive unescaping by @scidomino in
variable populated. by @richieforeman in [#20520](https://github.com/google-gemini/gemini-cli/pull/20520)
[#18832](https://github.com/google-gemini/gemini-cli/pull/18832) - feat(telemetry) Instrument traces with more attributes and make them available
- fix(core): improve headless mode detection for flags and query args by @galz10 to OTEL users by @heaventourist in
in [#18855](https://github.com/google-gemini/gemini-cli/pull/18855) [#20237](https://github.com/google-gemini/gemini-cli/pull/20237)
- refactor(cli): simplify UI and remove legacy inline tool confirmation logic by - Add support for policy engine in extensions by @chrstnb in
@abhipatel12 in [#20049](https://github.com/google-gemini/gemini-cli/pull/20049)
[#18566](https://github.com/google-gemini/gemini-cli/pull/18566) - Docs: Update to Terms of Service & FAQ by @jkcinouye in
- feat(cli): deprecate --allowed-tools and excludeTools in favor of policy [#20488](https://github.com/google-gemini/gemini-cli/pull/20488)
engine by @Abhijit-2592 in - Fix bottom border rendering for search and add a regression test. by @jacob314
[#18508](https://github.com/google-gemini/gemini-cli/pull/18508) in [#20517](https://github.com/google-gemini/gemini-cli/pull/20517)
- fix(workflows): improve maintainer detection for automated PR actions by - fix(core): apply retry logic to CodeAssistServer for all users by @bdmorgan in
@bdmorgan in [#18869](https://github.com/google-gemini/gemini-cli/pull/18869) [#20507](https://github.com/google-gemini/gemini-cli/pull/20507)
- refactor(cli): consolidate useToolScheduler and delete legacy implementation - Fix extension MCP server env var loading by @chrstnb in
by @abhipatel12 in [#20374](https://github.com/google-gemini/gemini-cli/pull/20374)
[#18567](https://github.com/google-gemini/gemini-cli/pull/18567) - feat(ui): add 'ctrl+o' hint to truncated content message by @jerop in
- Update changelog for v0.28.0 and v0.29.0-preview0 by @g-samroberts in [#20529](https://github.com/google-gemini/gemini-cli/pull/20529)
[#18819](https://github.com/google-gemini/gemini-cli/pull/18819) - Fix flicker showing message to press ctrl-O again to collapse. by @jacob314 in
- fix(core): ensure sub-agents are registered regardless of tools.allowed by [#20414](https://github.com/google-gemini/gemini-cli/pull/20414)
@mattKorwel in - fix(cli): hide shortcuts hint while model is thinking or the user has typed a
[#18870](https://github.com/google-gemini/gemini-cli/pull/18870) prompt + add debounce to avoid flicker by @jacob314 in
- Show notification when there's a conflict with an extensions command by [#19389](https://github.com/google-gemini/gemini-cli/pull/19389)
@chrstnb in [#17890](https://github.com/google-gemini/gemini-cli/pull/17890) - feat(plan): update planning workflow to encourage multi-select with
- fix(cli): dismiss '?' shortcuts help on hotkeys and active states by descriptions of options by @Adib234 in
@LyalinDotCom in [#20491](https://github.com/google-gemini/gemini-cli/pull/20491)
[#18583](https://github.com/google-gemini/gemini-cli/pull/18583) - refactor(core,cli): useAlternateBuffer read from config by @psinha40898 in
- fix(core): prioritize conditional policy rules and harden Plan Mode by [#20346](https://github.com/google-gemini/gemini-cli/pull/20346)
@Abhijit-2592 in - fix(cli): ensure dialogs stay scrolled to bottom in alternate buffer mode by
[#18882](https://github.com/google-gemini/gemini-cli/pull/18882) @jacob314 in [#20527](https://github.com/google-gemini/gemini-cli/pull/20527)
- feat(core): refine Plan Mode system prompt for agentic execution by - fix(core): revert auto-save of policies to user space by @Abhijit-2592 in
@NTaylorMullen in [#20531](https://github.com/google-gemini/gemini-cli/pull/20531)
[#18799](https://github.com/google-gemini/gemini-cli/pull/18799) - Demote unreliable test. by @gundermanc in
- feat(plan): create metrics for usage of `AskUser` tool by @Adib234 in [#20571](https://github.com/google-gemini/gemini-cli/pull/20571)
[#18820](https://github.com/google-gemini/gemini-cli/pull/18820) - fix(core): handle optional response fields from code assist API by @sehoon38
- feat(cli): support Ctrl-Z suspension by @scidomino in in [#20345](https://github.com/google-gemini/gemini-cli/pull/20345)
[#18931](https://github.com/google-gemini/gemini-cli/pull/18931) - fix(cli): keep thought summary when loading phrases are off by @LyalinDotCom
- fix(github-actions): use robot PAT for release creation to trigger release in [#20497](https://github.com/google-gemini/gemini-cli/pull/20497)
notes by @SandyTao520 in - feat(cli): add temporary flag to disable workspace policies by @Abhijit-2592
[#18794](https://github.com/google-gemini/gemini-cli/pull/18794) in [#20523](https://github.com/google-gemini/gemini-cli/pull/20523)
- feat: add strict seatbelt profiles and remove unusable closed profiles by - Disable expensive and scheduled workflows on personal forks by @dewitt in
@SandyTao520 in [#20449](https://github.com/google-gemini/gemini-cli/pull/20449)
[#18876](https://github.com/google-gemini/gemini-cli/pull/18876) - Moved markdown parsing logic to a separate util file by @devr0306 in
- chore: cleanup unused and add unlisted dependencies in packages/a2a-server by [#20526](https://github.com/google-gemini/gemini-cli/pull/20526)
@adamfweidman in - fix(plan): prevent agent from using ask_user for shell command confirmation by
[#18916](https://github.com/google-gemini/gemini-cli/pull/18916) @Adib234 in [#20504](https://github.com/google-gemini/gemini-cli/pull/20504)
- fix(plan): isolate plan files per session by @Adib234 in - fix(core): disable retries for code assist streaming requests by @sehoon38 in
[#18757](https://github.com/google-gemini/gemini-cli/pull/18757) [#20561](https://github.com/google-gemini/gemini-cli/pull/20561)
- fix: character truncation in raw markdown mode by @jackwotherspoon in - feat(billing): implement G1 AI credits overage flow with billing telemetry by
[#18938](https://github.com/google-gemini/gemini-cli/pull/18938)
- feat(cli): prototype clean UI toggle and minimal-mode bleed-through by
@LyalinDotCom in
[#18683](https://github.com/google-gemini/gemini-cli/pull/18683)
- ui(polish) blend background color with theme by @jacob314 in
[#18802](https://github.com/google-gemini/gemini-cli/pull/18802)
- Add generic searchable list to back settings and extensions by @chrstnb in
[#18838](https://github.com/google-gemini/gemini-cli/pull/18838)
- feat(ui): align `AskUser` color scheme with UX spec by @jerop in
[#18943](https://github.com/google-gemini/gemini-cli/pull/18943)
- Hide AskUser tool validation errors from UI (agent self-corrects) by @jerop in
[#18954](https://github.com/google-gemini/gemini-cli/pull/18954)
- bug(cli) fix flicker due to AppContainer continuous initialization by
@jacob314 in [#18958](https://github.com/google-gemini/gemini-cli/pull/18958)
- feat(admin): Add admin controls documentation by @skeshive in
[#18644](https://github.com/google-gemini/gemini-cli/pull/18644)
- feat(cli): disable ctrl-s shortcut outside of alternate buffer mode by
@jacob314 in [#18887](https://github.com/google-gemini/gemini-cli/pull/18887)
- fix(vim): vim support that feels (more) complete by @ppgranger in
[#18755](https://github.com/google-gemini/gemini-cli/pull/18755)
- feat(policy): add --policy flag for user defined policies by @allenhutchison
in [#18500](https://github.com/google-gemini/gemini-cli/pull/18500)
- Update installation guide by @g-samroberts in
[#18823](https://github.com/google-gemini/gemini-cli/pull/18823)
- refactor(core): centralize tool definitions (Group 1: replace, search, grep)
by @aishaneeshah in
[#18944](https://github.com/google-gemini/gemini-cli/pull/18944)
- refactor(cli): finalize event-driven transition and remove interaction bridge
by @abhipatel12 in
[#18569](https://github.com/google-gemini/gemini-cli/pull/18569)
- Fix drag and drop escaping by @scidomino in
[#18965](https://github.com/google-gemini/gemini-cli/pull/18965)
- feat(sdk): initial package bootstrap for SDK by @mbleigh in
[#18861](https://github.com/google-gemini/gemini-cli/pull/18861)
- feat(sdk): implements SessionContext for SDK tool calls by @mbleigh in
[#18862](https://github.com/google-gemini/gemini-cli/pull/18862)
- fix(plan): make question type required in AskUser tool by @Adib234 in
[#18959](https://github.com/google-gemini/gemini-cli/pull/18959)
- fix(core): ensure --yolo does not force headless mode by @NTaylorMullen in
[#18976](https://github.com/google-gemini/gemini-cli/pull/18976)
- refactor(core): adopt `CoreToolCallStatus` enum for type safety by @jerop in
[#18998](https://github.com/google-gemini/gemini-cli/pull/18998)
- Enable in-CLI extension management commands for team by @chrstnb in
[#18957](https://github.com/google-gemini/gemini-cli/pull/18957)
- Adjust lint rules to avoid unnecessary warning. by @scidomino in
[#18970](https://github.com/google-gemini/gemini-cli/pull/18970)
- fix(vscode): resolve unsafe type assertion lint errors by @ehedlund in
[#19006](https://github.com/google-gemini/gemini-cli/pull/19006)
- Remove unnecessary eslint config file by @scidomino in
[#19015](https://github.com/google-gemini/gemini-cli/pull/19015)
- fix(core): Prevent loop detection false positives on lists with long shared
prefixes by @SandyTao520 in
[#18975](https://github.com/google-gemini/gemini-cli/pull/18975)
- feat(core): fallback to chat-base when using unrecognized models for chat by
@SandyTao520 in
[#19016](https://github.com/google-gemini/gemini-cli/pull/19016)
- docs: fix inconsistent commandRegex example in policy engine by @NTaylorMullen
in [#19027](https://github.com/google-gemini/gemini-cli/pull/19027)
- fix(plan): persist the approval mode in UI even when agent is thinking by
@Adib234 in [#18955](https://github.com/google-gemini/gemini-cli/pull/18955)
- feat(sdk): Implement dynamic system instructions by @mbleigh in
[#18863](https://github.com/google-gemini/gemini-cli/pull/18863)
- Docs: Refresh docs to organize and standardize reference materials. by
@jkcinouye in [#18403](https://github.com/google-gemini/gemini-cli/pull/18403)
- fix windows escaping (and broken tests) by @scidomino in
[#19011](https://github.com/google-gemini/gemini-cli/pull/19011)
- refactor: use `CoreToolCallStatus` in the the history data model by @jerop in
[#19033](https://github.com/google-gemini/gemini-cli/pull/19033)
- feat(cleanup): enable 30-day session retention by default by @skeshive in
[#18854](https://github.com/google-gemini/gemini-cli/pull/18854)
- feat(plan): hide plan write and edit operations on plans in Plan Mode by
@jerop in [#19012](https://github.com/google-gemini/gemini-cli/pull/19012)
- bug(ui) fix flicker refreshing background color by @jacob314 in
[#19041](https://github.com/google-gemini/gemini-cli/pull/19041)
- chore: fix dep vulnerabilities by @scidomino in
[#19036](https://github.com/google-gemini/gemini-cli/pull/19036)
- Revamp automated changelog skill by @g-samroberts in
[#18974](https://github.com/google-gemini/gemini-cli/pull/18974)
- feat(sdk): implement support for custom skills by @mbleigh in
[#19031](https://github.com/google-gemini/gemini-cli/pull/19031)
- refactor(core): complete centralization of core tool definitions by
@aishaneeshah in
[#18991](https://github.com/google-gemini/gemini-cli/pull/18991)
- feat: add /commands reload to refresh custom TOML commands by @korade-krushna
in [#19078](https://github.com/google-gemini/gemini-cli/pull/19078)
- fix(cli): wrap terminal capability queries in hidden sequence by @srithreepo
in [#19080](https://github.com/google-gemini/gemini-cli/pull/19080)
- fix(workflows): fix GitHub App token permissions for maintainer detection by
@bdmorgan in [#19139](https://github.com/google-gemini/gemini-cli/pull/19139)
- test: fix hook integration test flakiness on Windows CI by @NTaylorMullen in
[#18665](https://github.com/google-gemini/gemini-cli/pull/18665)
- fix(core): Encourage non-interactive flags for scaffolding commands by
@NTaylorMullen in
[#18804](https://github.com/google-gemini/gemini-cli/pull/18804)
- fix(core): propagate User-Agent header to setup-phase CodeAssist API calls by
@gsquared94 in @gsquared94 in
[#19182](https://github.com/google-gemini/gemini-cli/pull/19182) [#18590](https://github.com/google-gemini/gemini-cli/pull/18590)
- docs: document .agents/skills alias and discovery precedence by @kevmoo in - feat: better error messages by @gsquared94 in
[#19166](https://github.com/google-gemini/gemini-cli/pull/19166) [#20577](https://github.com/google-gemini/gemini-cli/pull/20577)
- feat(cli): add loading state to new agents notification by @sehoon38 in - fix(ui): persist expansion in AskUser dialog when navigating options by @jerop
[#19190](https://github.com/google-gemini/gemini-cli/pull/19190) in [#20559](https://github.com/google-gemini/gemini-cli/pull/20559)
- Add base branch to workflow. by @g-samroberts in - fix(cli): prevent sub-agent tool calls from leaking into UI by @abhipatel12 in
[#19189](https://github.com/google-gemini/gemini-cli/pull/19189) [#20580](https://github.com/google-gemini/gemini-cli/pull/20580)
- feat(cli): handle invalid model names in useQuotaAndFallback by @sehoon38 in - fix(cli): Shell autocomplete polish by @jacob314 in
[#19222](https://github.com/google-gemini/gemini-cli/pull/19222) [#20411](https://github.com/google-gemini/gemini-cli/pull/20411)
- docs: custom themes in extensions by @jackwotherspoon in - Changelog for v0.31.0-preview.1 by @gemini-cli-robot in
[#19219](https://github.com/google-gemini/gemini-cli/pull/19219) [#20590](https://github.com/google-gemini/gemini-cli/pull/20590)
- Disable workspace settings when starting GCLI in the home directory. by - Add slash command for promoting behavioral evals to CI blocking by @gundermanc
@kevinjwang1 in in [#20575](https://github.com/google-gemini/gemini-cli/pull/20575)
[#19034](https://github.com/google-gemini/gemini-cli/pull/19034) - Changelog for v0.30.1 by @gemini-cli-robot in
- feat(cli): refactor model command to support set and manage subcommands by [#20589](https://github.com/google-gemini/gemini-cli/pull/20589)
@sehoon38 in [#19221](https://github.com/google-gemini/gemini-cli/pull/19221) - Add low/full CLI error verbosity mode for cleaner UI by @LyalinDotCom in
- Add refresh/reload aliases to slash command subcommands by @korade-krushna in [#20399](https://github.com/google-gemini/gemini-cli/pull/20399)
[#19218](https://github.com/google-gemini/gemini-cli/pull/19218) - Disable Gemini PR reviews on draft PRs. by @gundermanc in
- refactor: consolidate development rules and add cli guidelines by @jacob314 in [#20362](https://github.com/google-gemini/gemini-cli/pull/20362)
[#19214](https://github.com/google-gemini/gemini-cli/pull/19214) - Docs: FAQ update by @jkcinouye in
- chore(ui): remove outdated tip about model routing by @sehoon38 in [#20585](https://github.com/google-gemini/gemini-cli/pull/20585)
[#19226](https://github.com/google-gemini/gemini-cli/pull/19226) - fix(core): reduce intrusive MCP errors and deduplicate diagnostics by
- feat(core): support custom reasoning models by default by @NTaylorMullen in @spencer426 in
[#19227](https://github.com/google-gemini/gemini-cli/pull/19227) [#20232](https://github.com/google-gemini/gemini-cli/pull/20232)
- Add Solarized Dark and Solarized Light themes by @rmedranollamas in - docs: fix spelling typos in installation guide by @campox747 in
[#19064](https://github.com/google-gemini/gemini-cli/pull/19064) [#20579](https://github.com/google-gemini/gemini-cli/pull/20579)
- fix(telemetry): replace JSON.stringify with safeJsonStringify in file - Promote stable tests to CI blocking. by @gundermanc in
exporters by @gsquared94 in [#20581](https://github.com/google-gemini/gemini-cli/pull/20581)
[#19244](https://github.com/google-gemini/gemini-cli/pull/19244) - feat(core): enable contiguous parallel admission for Kind.Agent tools by
- feat(telemetry): add keychain availability and token storage metrics by
@abhipatel12 in @abhipatel12 in
[#18971](https://github.com/google-gemini/gemini-cli/pull/18971) [#20583](https://github.com/google-gemini/gemini-cli/pull/20583)
- feat(cli): update approval mode cycle order by @jerop in - Enforce import/no-duplicates as error by @Nixxx19 in
[#19254](https://github.com/google-gemini/gemini-cli/pull/19254) [#19797](https://github.com/google-gemini/gemini-cli/pull/19797)
- refactor(cli): code review cleanup fix for tab+tab by @jacob314 in - fix: merge duplicate imports in sdk and test-utils packages (1/4) by @Nixxx19
[#18967](https://github.com/google-gemini/gemini-cli/pull/18967) in [#19777](https://github.com/google-gemini/gemini-cli/pull/19777)
- feat(plan): support project exploration without planning when in plan mode by - fix: merge duplicate imports in a2a-server package (2/4) by @Nixxx19 in
@Adib234 in [#18992](https://github.com/google-gemini/gemini-cli/pull/18992) [#19781](https://github.com/google-gemini/gemini-cli/pull/19781)
- feat: add role-specific statistics to telemetry and UI (cont. #15234) by
@yunaseoul in [#18824](https://github.com/google-gemini/gemini-cli/pull/18824)
- feat(cli): remove Plan Mode from rotation when actively working by @jerop in
[#19262](https://github.com/google-gemini/gemini-cli/pull/19262)
- Fix side breakage where anchors don't work in slugs. by @g-samroberts in
[#19261](https://github.com/google-gemini/gemini-cli/pull/19261)
- feat(config): add setting to make directory tree context configurable by
@kevin-ramdass in
[#19053](https://github.com/google-gemini/gemini-cli/pull/19053)
- fix(acp): Wait for mcp initialization in acp (#18893) by @Mervap in
[#18894](https://github.com/google-gemini/gemini-cli/pull/18894)
- docs: format UTC times in releases doc by @pavan-sh in
[#18169](https://github.com/google-gemini/gemini-cli/pull/18169)
- Docs: Clarify extensions documentation. by @jkcinouye in
[#19277](https://github.com/google-gemini/gemini-cli/pull/19277)
- refactor(core): modularize tool definitions by model family by @aishaneeshah
in [#19269](https://github.com/google-gemini/gemini-cli/pull/19269)
- fix(paths): Add cross-platform path normalization by @spencer426 in
[#18939](https://github.com/google-gemini/gemini-cli/pull/18939)
- feat(core): experimental in-progress steering hints (1 of 3) by @joshualitt in
[#19008](https://github.com/google-gemini/gemini-cli/pull/19008)
**Full changelog**: **Full Changelog**:
https://github.com/google-gemini/gemini-cli/compare/v0.29.0-preview.5...v0.30.0-preview.5 https://github.com/google-gemini/gemini-cli/compare/v0.31.0-preview.3...v0.32.0-preview.0
+12 -12
View File
@@ -5,18 +5,18 @@ and parameters.
## CLI commands ## CLI commands
| Command | Description | Example | | Command | Description | Example |
| ---------------------------------- | ---------------------------------- | --------------------------------------------------- | | ---------------------------------- | ---------------------------------- | ------------------------------------------------------------ |
| `gemini` | Start interactive REPL | `gemini` | | `gemini` | Start interactive REPL | `gemini` |
| `gemini "query"` | Query non-interactively, then exit | `gemini "explain this project"` | | `gemini "query"` | Query non-interactively, then exit | `gemini "explain this project"` |
| `cat file \| gemini` | Process piped content | `cat logs.txt \| gemini` | | `cat file \| gemini` | Process piped content | `cat logs.txt \| gemini`<br>`Get-Content logs.txt \| gemini` |
| `gemini -i "query"` | Execute and continue interactively | `gemini -i "What is the purpose of this project?"` | | `gemini -i "query"` | Execute and continue interactively | `gemini -i "What is the purpose of this project?"` |
| `gemini -r "latest"` | Continue most recent session | `gemini -r "latest"` | | `gemini -r "latest"` | Continue most recent session | `gemini -r "latest"` |
| `gemini -r "latest" "query"` | Continue session with a new prompt | `gemini -r "latest" "Check for type errors"` | | `gemini -r "latest" "query"` | Continue session with a new prompt | `gemini -r "latest" "Check for type errors"` |
| `gemini -r "<session-id>" "query"` | Resume session by ID | `gemini -r "abc123" "Finish this PR"` | | `gemini -r "<session-id>" "query"` | Resume session by ID | `gemini -r "abc123" "Finish this PR"` |
| `gemini update` | Update to latest version | `gemini update` | | `gemini update` | Update to latest version | `gemini update` |
| `gemini extensions` | Manage extensions | See [Extensions Management](#extensions-management) | | `gemini extensions` | Manage extensions | See [Extensions Management](#extensions-management) |
| `gemini mcp` | Configure MCP servers | See [MCP Server Management](#mcp-server-management) | | `gemini mcp` | Configure MCP servers | See [MCP Server Management](#mcp-server-management) |
### Positional arguments ### Positional arguments
+9
View File
@@ -278,11 +278,20 @@ Let's create a global command that asks the model to refactor a piece of code.
First, ensure the user commands directory exists, then create a `refactor` First, ensure the user commands directory exists, then create a `refactor`
subdirectory for organization and the final TOML file. subdirectory for organization and the final TOML file.
**macOS/Linux**
```bash ```bash
mkdir -p ~/.gemini/commands/refactor mkdir -p ~/.gemini/commands/refactor
touch ~/.gemini/commands/refactor/pure.toml touch ~/.gemini/commands/refactor/pure.toml
``` ```
**Windows (PowerShell)**
```powershell
New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\.gemini\commands\refactor"
New-Item -ItemType File -Force -Path "$env:USERPROFILE\.gemini\commands\refactor\pure.toml"
```
**2. Add the content to the file:** **2. Add the content to the file:**
Open `~/.gemini/commands/refactor/pure.toml` in your editor and add the Open `~/.gemini/commands/refactor/pure.toml` in your editor and add the
+19
View File
@@ -203,6 +203,15 @@ with the actual Gemini CLI process, which inherits the environment variable.
This makes it significantly more difficult for a user to bypass the enforced This makes it significantly more difficult for a user to bypass the enforced
settings. settings.
**PowerShell Profile (Windows alternative):**
On Windows, administrators can achieve similar results by adding the environment
variable to the system-wide or user-specific PowerShell profile:
```powershell
Add-Content -Path $PROFILE -Value '$env:GEMINI_CLI_SYSTEM_SETTINGS_PATH="C:\ProgramData\gemini-cli\settings.json"'
```
## User isolation in shared environments ## User isolation in shared environments
In shared compute environments (like ML experiment runners or shared build In shared compute environments (like ML experiment runners or shared build
@@ -214,12 +223,22 @@ use the `GEMINI_CLI_HOME` environment variable to point to a unique directory
for a specific user or job. The CLI will create a `.gemini` folder inside the for a specific user or job. The CLI will create a `.gemini` folder inside the
specified path. specified path.
**macOS/Linux**
```bash ```bash
# Isolate state for a specific job # Isolate state for a specific job
export GEMINI_CLI_HOME="/tmp/gemini-job-123" export GEMINI_CLI_HOME="/tmp/gemini-job-123"
gemini gemini
``` ```
**Windows (PowerShell)**
```powershell
# Isolate state for a specific job
$env:GEMINI_CLI_HOME="C:\temp\gemini-job-123"
gemini
```
## Restricting tool access ## Restricting tool access
You can significantly enhance security by controlling which tools the Gemini You can significantly enhance security by controlling which tools the Gemini
+5 -14
View File
@@ -19,24 +19,15 @@ Use the following command in Gemini CLI:
Running this command will open a dialog with your options: Running this command will open a dialog with your options:
| Option | Description | Models | | 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 3) | Let the system choose the best Gemini 3 model for your task. | gemini-3-pro-preview, gemini-3-flash-preview |
| Auto (Gemini 2.5) | Let the system choose the best Gemini 2.5 model for your task. | gemini-2.5-pro, gemini-2.5-flash | | 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. | | Manual | Select a specific model. | Any available model. |
We recommend selecting one of the above **Auto** options. However, you can We recommend selecting one of the above **Auto** options. However, you can
select **Manual** to select a specific model from those available. 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 You can also use the `--model` flag to specify a particular Gemini model on
startup. For more details, refer to the startup. For more details, refer to the
[configuration documentation](../reference/configuration.md). [configuration documentation](../reference/configuration.md).
+30 -7
View File
@@ -80,18 +80,38 @@ manually during a session.
### Planning Workflow ### Planning Workflow
Plan Mode uses an adaptive planning workflow where the research depth, plan
structure, and consultation level are proportional to the task's complexity:
1. **Explore & Analyze:** Analyze requirements and use read-only tools to map 1. **Explore & Analyze:** Analyze requirements and use read-only tools to map
the codebase and validate assumptions. For complex tasks, identify at least affected modules and identify dependencies.
two viable implementation approaches. 2. **Consult:** The depth of consultation is proportional to the task's
2. **Consult:** Present a summary of the identified approaches via [`ask_user`] complexity:
to obtain a selection. For simple or canonical tasks, this step may be - **Simple Tasks:** Proceed directly to drafting.
skipped. - **Standard Tasks:** Present a summary of viable approaches via
3. **Draft:** Once an approach is selected, write a detailed implementation [`ask_user`] for selection.
plan to the plans directory. - **Complex Tasks:** Present detailed trade-offs for at least two viable
approaches via [`ask_user`] and obtain approval before drafting.
3. **Draft:** Write a detailed implementation plan to the
[plans directory](#custom-plan-directory-and-policies). The plan's structure
adapts to the task:
- **Simple Tasks:** Focused on specific **Changes** and **Verification**
steps.
- **Standard Tasks:** Includes an **Objective**, **Key Files & Context**,
**Implementation Steps**, and **Verification & Testing**.
- **Complex Tasks:** Comprehensive plans including **Background &
Motivation**, **Scope & Impact**, **Proposed Solution**, **Alternatives
Considered**, a phased **Implementation Plan**, **Verification**, and
**Migration & Rollback** strategies.
4. **Review & Approval:** Use the [`exit_plan_mode`] tool to present the plan 4. **Review & Approval:** Use the [`exit_plan_mode`] tool to present the plan
and formally request approval. and formally request approval.
- **Approve:** Exit Plan Mode and start implementation. - **Approve:** Exit Plan Mode and start implementation.
- **Iterate:** Provide feedback to refine the plan. - **Iterate:** Provide feedback to refine the plan.
- **Refine manually:** Press **Ctrl + X** to open the plan file in your
[preferred external editor]. This allows you to manually refine the plan
steps before approval. If you make any changes and save the file, the CLI
will automatically send the updated plan back to the agent for review and
iteration.
For more complex or specialized planning tasks, you can For more complex or specialized planning tasks, you can
[customize the planning workflow with skills](#customizing-planning-with-skills). [customize the planning workflow with skills](#customizing-planning-with-skills).
@@ -119,6 +139,7 @@ These are the only allowed tools:
- **Planning (Write):** [`write_file`] and [`replace`] only allowed for `.md` - **Planning (Write):** [`write_file`] and [`replace`] only allowed for `.md`
files in the `~/.gemini/tmp/<project>/<session-id>/plans/` directory or your files in the `~/.gemini/tmp/<project>/<session-id>/plans/` directory or your
[custom plans directory](#custom-plan-directory-and-policies). [custom plans directory](#custom-plan-directory-and-policies).
- **Memory:** [`save_memory`]
- **Skills:** [`activate_skill`] (allows loading specialized instructions and - **Skills:** [`activate_skill`] (allows loading specialized instructions and
resources in a read-only manner) resources in a read-only manner)
@@ -277,6 +298,7 @@ performance. You can disable this automatic switching in your settings:
[`google_web_search`]: /docs/tools/web-search.md [`google_web_search`]: /docs/tools/web-search.md
[`replace`]: /docs/tools/file-system.md#6-replace-edit [`replace`]: /docs/tools/file-system.md#6-replace-edit
[MCP tools]: /docs/tools/mcp-server.md [MCP tools]: /docs/tools/mcp-server.md
[`save_memory`]: /docs/tools/memory.md
[`activate_skill`]: /docs/cli/skills.md [`activate_skill`]: /docs/cli/skills.md
[subagents]: /docs/core/subagents.md [subagents]: /docs/core/subagents.md
[policy engine]: /docs/reference/policy-engine.md [policy engine]: /docs/reference/policy-engine.md
@@ -288,3 +310,4 @@ performance. You can disable this automatic switching in your settings:
https://github.com/google-gemini/gemini-cli/blob/main/packages/core/src/policy/policies/plan.toml https://github.com/google-gemini/gemini-cli/blob/main/packages/core/src/policy/policies/plan.toml
[auto model]: /docs/reference/configuration.md#model-settings [auto model]: /docs/reference/configuration.md#model-settings
[model routing]: /docs/cli/telemetry.md#model-routing [model routing]: /docs/cli/telemetry.md#model-routing
[preferred external editor]: /docs/reference/configuration.md#general
+42 -2
View File
@@ -55,12 +55,27 @@ from your organization's registry.
```bash ```bash
# Enable sandboxing with command flag # Enable sandboxing with command flag
gemini -s -p "analyze the code structure" gemini -s -p "analyze the code structure"
```
# Use environment variable **Use environment variable**
**macOS/Linux**
```bash
export GEMINI_SANDBOX=true export GEMINI_SANDBOX=true
gemini -p "run the test suite" gemini -p "run the test suite"
```
# Configure in settings.json **Windows (PowerShell)**
```powershell
$env:GEMINI_SANDBOX="true"
gemini -p "run the test suite"
```
**Configure in settings.json**
```json
{ {
"tools": { "tools": {
"sandbox": "docker" "sandbox": "docker"
@@ -99,26 +114,51 @@ use cases.
To disable SELinux labeling for volume mounts, you can set the following: To disable SELinux labeling for volume mounts, you can set the following:
**macOS/Linux**
```bash ```bash
export SANDBOX_FLAGS="--security-opt label=disable" export SANDBOX_FLAGS="--security-opt label=disable"
``` ```
**Windows (PowerShell)**
```powershell
$env:SANDBOX_FLAGS="--security-opt label=disable"
```
Multiple flags can be provided as a space-separated string: Multiple flags can be provided as a space-separated string:
**macOS/Linux**
```bash ```bash
export SANDBOX_FLAGS="--flag1 --flag2=value" export SANDBOX_FLAGS="--flag1 --flag2=value"
``` ```
**Windows (PowerShell)**
```powershell
$env:SANDBOX_FLAGS="--flag1 --flag2=value"
```
## Linux UID/GID handling ## Linux UID/GID handling
The sandbox automatically handles user permissions on Linux. Override these The sandbox automatically handles user permissions on Linux. Override these
permissions with: permissions with:
**macOS/Linux**
```bash ```bash
export SANDBOX_SET_UID_GID=true # Force host UID/GID export SANDBOX_SET_UID_GID=true # Force host UID/GID
export SANDBOX_SET_UID_GID=false # Disable UID/GID mapping export SANDBOX_SET_UID_GID=false # Disable UID/GID mapping
``` ```
**Windows (PowerShell)**
```powershell
$env:SANDBOX_SET_UID_GID="true" # Force host UID/GID
$env:SANDBOX_SET_UID_GID="false" # Disable UID/GID mapping
```
## Troubleshooting ## Troubleshooting
### Common issues ### Common issues
+17 -8
View File
@@ -32,8 +32,8 @@ they appear in the UI.
| Plan Model Routing | `general.plan.modelRouting` | Automatically switch between Pro and Flash models based on Plan Mode status. Uses Pro for the planning phase and Flash for the implementation phase. | `true` | | Plan Model Routing | `general.plan.modelRouting` | Automatically switch between Pro and Flash models based on Plan Mode status. Uses Pro for the planning phase and Flash for the implementation phase. | `true` |
| Max Chat Model Attempts | `general.maxAttempts` | Maximum number of attempts for requests to the main chat model. Cannot exceed 10. | `10` | | Max Chat Model Attempts | `general.maxAttempts` | Maximum number of attempts for requests to the main chat model. Cannot exceed 10. | `10` |
| Debug Keystroke Logging | `general.debugKeystrokeLogging` | Enable debug logging of keystrokes to the console. | `false` | | 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` | | Enable Session Cleanup | `general.sessionRetention.enabled` | Enable automatic session cleanup | `true` |
| Keep chat history | `general.sessionRetention.maxAge` | Automatically delete chats older than this time period (e.g., "30d", "7d", "24h", "1w") | `undefined` | | Keep chat history | `general.sessionRetention.maxAge` | Automatically delete chats older than this time period (e.g., "30d", "7d", "24h", "1w") | `"30d"` |
### Output ### Output
@@ -72,6 +72,7 @@ they appear in the UI.
| 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` | | Incremental Rendering | `ui.incrementalRendering` | Enable incremental rendering for the UI. This option will reduce flickering but may cause rendering artifacts. Only supported when useAlternateBuffer is enabled. | `true` |
| Show Spinner | `ui.showSpinner` | Show the spinner during operations. | `true` | | Show Spinner | `ui.showSpinner` | Show the spinner during operations. | `true` |
| Loading Phrases | `ui.loadingPhrases` | What to show while the model is working: tips, witty comments, both, or nothing. | `"tips"` | | Loading Phrases | `ui.loadingPhrases` | What to show while the model is working: tips, witty comments, both, or nothing. | `"tips"` |
| Error Verbosity | `ui.errorVerbosity` | Controls whether recoverable errors are hidden (low) or fully shown (full). | `"low"` |
| Screen Reader Mode | `ui.accessibility.screenReader` | Render output in plain-text to be more screen reader accessible | `false` | | Screen Reader Mode | `ui.accessibility.screenReader` | Render output in plain-text to be more screen reader accessible | `false` |
### IDE ### IDE
@@ -80,14 +81,21 @@ they appear in the UI.
| -------- | ------------- | ---------------------------- | ------- | | -------- | ------------- | ---------------------------- | ------- |
| IDE Mode | `ide.enabled` | Enable IDE integration mode. | `false` | | IDE Mode | `ide.enabled` | Enable IDE integration mode. | `false` |
### Billing
| UI Label | Setting | Description | Default |
| ---------------- | ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
| Overage Strategy | `billing.overageStrategy` | How to handle quota exhaustion when AI credits are available. 'ask' prompts each time, 'always' automatically uses credits, 'never' disables credit usage. | `"ask"` |
### Model ### Model
| UI Label | Setting | Description | Default | | 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` | | Model | `model.name` | The Gemini model to use for conversations. | `undefined` |
| Compression Threshold | `model.compressionThreshold` | The fraction of context usage at which to trigger context compression (e.g. 0.2, 0.3). | `0.5` | | Max Session Turns | `model.maxSessionTurns` | Maximum number of user/model/tool turns to keep in a session. -1 means unlimited. | `-1` |
| Disable Loop Detection | `model.disableLoopDetection` | Disable automatic detection and prevention of infinite loops. | `false` | | 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` | | Disable Loop Detection | `model.disableLoopDetection` | Disable automatic detection and prevention of infinite loops. | `false` |
| Skip Next Speaker Check | `model.skipNextSpeakerCheck` | Skip the next speaker check. | `true` |
### Context ### Context
@@ -139,6 +147,7 @@ they appear in the UI.
| Plan | `experimental.plan` | Enable planning features (Plan Mode and tools). | `false` | | Plan | `experimental.plan` | Enable planning features (Plan Mode and tools). | `false` |
| Model Steering | `experimental.modelSteering` | Enable model steering (user hints) to guide the model during tool execution. | `false` | | Model Steering | `experimental.modelSteering` | Enable model steering (user hints) to guide the model during tool execution. | `false` |
| Direct Web Fetch | `experimental.directWebFetch` | Enable web fetch behavior that bypasses LLM summarization. | `false` | | Direct Web Fetch | `experimental.directWebFetch` | Enable web fetch behavior that bypasses LLM summarization. | `false` |
| Enable Gemma Model Router | `experimental.gemmaModelRouter.enabled` | Enable the Gemma Model Router. Requires a local endpoint serving Gemma via the Gemini API using LiteRT-LM shim. | `false` |
### Skills ### Skills
+68 -11
View File
@@ -103,23 +103,52 @@ Before using either method below, complete these steps:
1. Set your Google Cloud project ID: 1. Set your Google Cloud project ID:
- For telemetry in a separate project from inference: - For telemetry in a separate project from inference:
**macOS/Linux**
```bash ```bash
export OTLP_GOOGLE_CLOUD_PROJECT="your-telemetry-project-id" export OTLP_GOOGLE_CLOUD_PROJECT="your-telemetry-project-id"
``` ```
**Windows (PowerShell)**
```powershell
$env:OTLP_GOOGLE_CLOUD_PROJECT="your-telemetry-project-id"
```
- For telemetry in the same project as inference: - For telemetry in the same project as inference:
**macOS/Linux**
```bash ```bash
export GOOGLE_CLOUD_PROJECT="your-project-id" export GOOGLE_CLOUD_PROJECT="your-project-id"
``` ```
**Windows (PowerShell)**
```powershell
$env:GOOGLE_CLOUD_PROJECT="your-project-id"
```
2. Authenticate with Google Cloud: 2. Authenticate with Google Cloud:
- If using a user account: - If using a user account:
```bash ```bash
gcloud auth application-default login gcloud auth application-default login
``` ```
- If using a service account: - If using a service account:
**macOS/Linux**
```bash ```bash
export GOOGLE_APPLICATION_CREDENTIALS="/path/to/your/service-account.json" export GOOGLE_APPLICATION_CREDENTIALS="/path/to/your/service-account.json"
``` ```
**Windows (PowerShell)**
```powershell
$env:GOOGLE_APPLICATION_CREDENTIALS="C:\path\to\your\service-account.json"
```
3. Make sure your account or service account has these IAM roles: 3. Make sure your account or service account has these IAM roles:
- Cloud Trace Agent - Cloud Trace Agent
- Monitoring Metric Writer - Monitoring Metric Writer
@@ -176,11 +205,12 @@ Sends telemetry directly to Google Cloud services. No collector needed.
} }
``` ```
2. Run Gemini CLI and send prompts. 2. Run Gemini CLI and send prompts.
3. View logs and metrics: 3. View logs, metrics, and traces:
- Open the Google Cloud Console in your browser after sending prompts: - Open the Google Cloud Console in your browser after sending prompts:
- Logs: https://console.cloud.google.com/logs/ - Logs (Logs Explorer): https://console.cloud.google.com/logs/
- Metrics: https://console.cloud.google.com/monitoring/metrics-explorer - Metrics (Metrics Explorer):
- Traces: https://console.cloud.google.com/traces/list https://console.cloud.google.com/monitoring/metrics-explorer
- Traces (Trace Explorer): https://console.cloud.google.com/traces/list
### Collector-based export (advanced) ### Collector-based export (advanced)
@@ -208,11 +238,12 @@ forward data to Google Cloud.
- Save collector logs to `~/.gemini/tmp/<projectHash>/otel/collector-gcp.log` - Save collector logs to `~/.gemini/tmp/<projectHash>/otel/collector-gcp.log`
- Stop collector on exit (e.g. `Ctrl+C`) - Stop collector on exit (e.g. `Ctrl+C`)
3. Run Gemini CLI and send prompts. 3. Run Gemini CLI and send prompts.
4. View logs and metrics: 4. View logs, metrics, and traces:
- Open the Google Cloud Console in your browser after sending prompts: - Open the Google Cloud Console in your browser after sending prompts:
- Logs: https://console.cloud.google.com/logs/ - Logs (Logs Explorer): https://console.cloud.google.com/logs/
- Metrics: https://console.cloud.google.com/monitoring/metrics-explorer - Metrics (Metrics Explorer):
- Traces: https://console.cloud.google.com/traces/list https://console.cloud.google.com/monitoring/metrics-explorer
- Traces (Trace Explorer): https://console.cloud.google.com/traces/list
- Open `~/.gemini/tmp/<projectHash>/otel/collector-gcp.log` to view local - Open `~/.gemini/tmp/<projectHash>/otel/collector-gcp.log` to view local
collector logs. collector logs.
@@ -270,10 +301,10 @@ 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 3. View traces at http://localhost:16686 and logs/metrics in the collector log
file. file.
## Logs and metrics ## Logs, metrics, and traces
The following section describes the structure of logs and metrics generated for The following section describes the structure of logs, metrics, and traces
Gemini CLI. generated for Gemini CLI.
The `session.id`, `installation.id`, `active_approval_mode`, and `user.email` The `session.id`, `installation.id`, `active_approval_mode`, and `user.email`
(available only when authenticated with a Google account) are included as common (available only when authenticated with a Google account) are included as common
@@ -824,6 +855,32 @@ Optional performance monitoring for startup, CPU/memory, and phase timing.
- `current_value` (number) - `current_value` (number)
- `baseline_value` (number) - `baseline_value` (number)
### Traces
Traces offer a granular, "under-the-hood" view of every agent and backend
operation. By providing a high-fidelity execution map, they enable precise
debugging of complex tool interactions and deep performance optimization. Each
trace captures rich, consistent metadata via custom span attributes:
- `gen_ai.operation.name` (string): The high-level operation kind (e.g.
"tool_call", "llm_call").
- `gen_ai.agent.name` (string): The service agent identifier ("gemini-cli").
- `gen_ai.agent.description` (string): The service agent description.
- `gen_ai.input.messages` (string): Input messages or metadata specific to the
operation.
- `gen_ai.output.messages` (string): Output messages or metadata generated from
the operation.
- `gen_ai.request.model` (string): The request model name.
- `gen_ai.response.model` (string): The response model name.
- `gen_ai.system_instructions` (json string): The system instructions.
- `gen_ai.prompt.name` (string): The prompt name.
- `gen_ai.tool.name` (string): The executed tool's name.
- `gen_ai.tool.call_id` (string): The generated specific ID of the tool call.
- `gen_ai.tool.description` (string): The executed tool's description.
- `gen_ai.tool.definitions` (json string): The executed tool's description.
- `gen_ai.conversation.id` (string): The current CLI session ID.
- Additional user-defined Custom Attributes passed via the span's configuration.
#### GenAI semantic convention #### GenAI semantic convention
The following metrics comply with [OpenTelemetry GenAI semantic conventions] for The following metrics comply with [OpenTelemetry GenAI semantic conventions] for
+101 -5
View File
@@ -37,10 +37,18 @@ output.
Pipe a file: Pipe a file:
**macOS/Linux**
```bash ```bash
cat error.log | gemini "Explain why this failed" cat error.log | gemini "Explain why this failed"
``` ```
**Windows (PowerShell)**
```powershell
Get-Content error.log | gemini "Explain why this failed"
```
Pipe a command: Pipe a command:
```bash ```bash
@@ -57,7 +65,10 @@ results to a file.
You have a folder of Python scripts and want to generate a `README.md` for each You have a folder of Python scripts and want to generate a `README.md` for each
one. one.
1. Save the following code as `generate_docs.sh`: 1. Save the following code as `generate_docs.sh` (or `generate_docs.ps1` for
Windows):
**macOS/Linux (`generate_docs.sh`)**
```bash ```bash
#!/bin/bash #!/bin/bash
@@ -72,13 +83,34 @@ one.
done done
``` ```
**Windows PowerShell (`generate_docs.ps1`)**
```powershell
# Loop through all Python files
Get-ChildItem -Filter *.py | ForEach-Object {
Write-Host "Generating docs for $($_.Name)..."
$newName = $_.Name -replace '\.py$', '.md'
# Ask Gemini CLI to generate the documentation and print it to stdout
gemini "Generate a Markdown documentation summary for @$($_.Name). Print the result to standard output." | Out-File -FilePath $newName -Encoding utf8
}
```
2. Make the script executable and run it in your directory: 2. Make the script executable and run it in your directory:
**macOS/Linux**
```bash ```bash
chmod +x generate_docs.sh chmod +x generate_docs.sh
./generate_docs.sh ./generate_docs.sh
``` ```
**Windows (PowerShell)**
```powershell
.\generate_docs.ps1
```
This creates a corresponding Markdown file for every Python file in the This creates a corresponding Markdown file for every Python file in the
folder. folder.
@@ -90,7 +122,10 @@ like `jq`. To get pure JSON data from the model, combine the
### Scenario: Extract and return structured data ### Scenario: Extract and return structured data
1. Save the following script as `generate_json.sh`: 1. Save the following script as `generate_json.sh` (or `generate_json.ps1` for
Windows):
**macOS/Linux (`generate_json.sh`)**
```bash ```bash
#!/bin/bash #!/bin/bash
@@ -105,13 +140,35 @@ like `jq`. To get pure JSON data from the model, combine the
gemini --output-format json "Return a raw JSON object with keys 'version' and 'deps' from @package.json" | jq -r '.response' > data.json gemini --output-format json "Return a raw JSON object with keys 'version' and 'deps' from @package.json" | jq -r '.response' > data.json
``` ```
2. Run `generate_json.sh`: **Windows PowerShell (`generate_json.ps1`)**
```powershell
# Ensure we are in a project root
if (-not (Test-Path "package.json")) {
Write-Error "Error: package.json not found."
exit 1
}
# Extract data (requires jq installed, or you can use ConvertFrom-Json)
$output = gemini --output-format json "Return a raw JSON object with keys 'version' and 'deps' from @package.json" | ConvertFrom-Json
$output.response | Out-File -FilePath data.json -Encoding utf8
```
2. Run the script:
**macOS/Linux**
```bash ```bash
chmod +x generate_json.sh chmod +x generate_json.sh
./generate_json.sh ./generate_json.sh
``` ```
**Windows (PowerShell)**
```powershell
.\generate_json.ps1
```
3. Check `data.json`. The file should look like this: 3. Check `data.json`. The file should look like this:
```json ```json
@@ -129,8 +186,10 @@ Use headless mode to perform custom, automated AI tasks.
### Scenario: Create a "Smart Commit" alias ### Scenario: Create a "Smart Commit" alias
You can add a function to your shell configuration (like `.zshrc` or `.bashrc`) You can add a function to your shell configuration to create a `git commit`
to create a `git commit` wrapper that writes the message for you. wrapper that writes the message for you.
**macOS/Linux (Bash/Zsh)**
1. Open your `.zshrc` file (or `.bashrc` if you use Bash) in your preferred 1. Open your `.zshrc` file (or `.bashrc` if you use Bash) in your preferred
text editor. text editor.
@@ -170,6 +229,43 @@ to create a `git commit` wrapper that writes the message for you.
source ~/.zshrc source ~/.zshrc
``` ```
**Windows (PowerShell)**
1. Open your PowerShell profile in your preferred text editor.
```powershell
notepad $PROFILE
```
2. Scroll to the very bottom of the file and paste this code:
```powershell
function gcommit {
# Get the diff of staged changes
$diff = git diff --staged
if (-not $diff) {
Write-Host "No staged changes to commit."
return
}
# Ask Gemini to write the message
Write-Host "Generating commit message..."
$msg = $diff | gemini "Write a concise Conventional Commit message for this diff. Output ONLY the message."
# Commit with the generated message
git commit -m "$msg"
}
```
Save your file and exit.
3. Run this command to make the function available immediately:
```powershell
. $PROFILE
```
4. Use your new command: 4. Use your new command:
```bash ```bash
+8
View File
@@ -20,10 +20,18 @@ Most MCP servers require authentication. For GitHub, you need a PAT.
**Read/Write** access to **Issues** and **Pull Requests**. **Read/Write** access to **Issues** and **Pull Requests**.
3. Store it in your environment: 3. Store it in your environment:
**macOS/Linux**
```bash ```bash
export GITHUB_PERSONAL_ACCESS_TOKEN="github_pat_..." export GITHUB_PERSONAL_ACCESS_TOKEN="github_pat_..."
``` ```
**Windows (PowerShell)**
```powershell
$env:GITHUB_PERSONAL_ACCESS_TOKEN="github_pat_..."
```
## How to configure Gemini CLI ## How to configure Gemini CLI
You tell Gemini about new servers by editing your `settings.json`. You tell Gemini about new servers by editing your `settings.json`.
@@ -14,10 +14,18 @@ responding correctly.
1. Run the following command to create the folders: 1. Run the following command to create the folders:
**macOS/Linux**
```bash ```bash
mkdir -p .gemini/skills/api-auditor/scripts mkdir -p .gemini/skills/api-auditor/scripts
``` ```
**Windows (PowerShell)**
```powershell
New-Item -ItemType Directory -Force -Path ".gemini\skills\api-auditor\scripts"
```
### Create the definition ### Create the definition
1. Create a file at `.gemini/skills/api-auditor/SKILL.md`. This tells the agent 1. Create a file at `.gemini/skills/api-auditor/SKILL.md`. This tells the agent
+36
View File
@@ -227,6 +227,42 @@ skill definitions in a `skills/` directory. For example,
Provide [sub-agents](../core/subagents.md) that users can delegate tasks to. Add Provide [sub-agents](../core/subagents.md) that users can delegate tasks to. Add
agent definition files (`.md`) to an `agents/` directory in your extension root. agent definition files (`.md`) to an `agents/` directory in your extension root.
### <a id="policy-engine"></a>Policy Engine
Extensions can contribute policy rules and safety checkers to the Gemini CLI
[Policy Engine](../reference/policy-engine.md). These rules are defined in
`.toml` files and take effect when the extension is activated.
To add policies, create a `policies/` directory in your extension's root and
place your `.toml` policy files inside it. Gemini CLI automatically loads all
`.toml` files from this directory.
Rules contributed by extensions run in their own tier (tier 2), alongside
workspace-defined policies. This tier has higher priority than the default rules
but lower priority than user or admin policies.
> **Warning:** For security, Gemini CLI ignores any `allow` decisions or `yolo`
> mode configurations in extension policies. This ensures that an extension
> cannot automatically approve tool calls or bypass security measures without
> your confirmation.
**Example `policies.toml`**
```toml
[[rule]]
toolName = "my_server__dangerous_tool"
decision = "ask_user"
priority = 100
[[safety_checker]]
toolName = "my_server__write_data"
priority = 200
[safety_checker.checker]
type = "in-process"
name = "allowed-path"
required_context = ["environment"]
```
### Themes ### Themes
Extensions can provide custom themes to personalize the CLI UI. Themes are Extensions can provide custom themes to personalize the CLI UI. Themes are
+16
View File
@@ -189,10 +189,18 @@ Custom commands create shortcuts for complex prompts.
1. Create a `commands` directory and a subdirectory for your command group: 1. Create a `commands` directory and a subdirectory for your command group:
**macOS/Linux**
```bash ```bash
mkdir -p commands/fs mkdir -p commands/fs
``` ```
**Windows (PowerShell)**
```powershell
New-Item -ItemType Directory -Force -Path "commands\fs"
```
2. Create a file named `commands/fs/grep-code.toml`: 2. Create a file named `commands/fs/grep-code.toml`:
```toml ```toml
@@ -252,10 +260,18 @@ Skills are activated only when needed, which saves context tokens.
1. Create a `skills` directory and a subdirectory for your skill: 1. Create a `skills` directory and a subdirectory for your skill:
**macOS/Linux**
```bash ```bash
mkdir -p skills/security-audit mkdir -p skills/security-audit
``` ```
**Windows (PowerShell)**
```powershell
New-Item -ItemType Directory -Force -Path "skills\security-audit"
```
2. Create a `skills/security-audit/SKILL.md` file: 2. Create a `skills/security-audit/SKILL.md` file:
```markdown ```markdown
+86 -5
View File
@@ -78,11 +78,20 @@ To authenticate and use Gemini CLI with a Gemini API key:
2. Set the `GEMINI_API_KEY` environment variable to your key. For example: 2. Set the `GEMINI_API_KEY` environment variable to your key. For example:
**macOS/Linux**
```bash ```bash
# Replace YOUR_GEMINI_API_KEY with the key from AI Studio # Replace YOUR_GEMINI_API_KEY with the key from AI Studio
export GEMINI_API_KEY="YOUR_GEMINI_API_KEY" export GEMINI_API_KEY="YOUR_GEMINI_API_KEY"
``` ```
**Windows (PowerShell)**
```powershell
# Replace YOUR_GEMINI_API_KEY with the key from AI Studio
$env:GEMINI_API_KEY="YOUR_GEMINI_API_KEY"
```
To make this setting persistent, see To make this setting persistent, see
[Persisting Environment Variables](#persisting-vars). [Persisting Environment Variables](#persisting-vars).
@@ -114,12 +123,22 @@ or the location where you want to run your jobs.
For example: For example:
**macOS/Linux**
```bash ```bash
# Replace with your project ID and desired location (e.g., us-central1) # Replace with your project ID and desired location (e.g., us-central1)
export GOOGLE_CLOUD_PROJECT="YOUR_PROJECT_ID" export GOOGLE_CLOUD_PROJECT="YOUR_PROJECT_ID"
export GOOGLE_CLOUD_LOCATION="YOUR_PROJECT_LOCATION" export GOOGLE_CLOUD_LOCATION="YOUR_PROJECT_LOCATION"
``` ```
**Windows (PowerShell)**
```powershell
# Replace with your project ID and desired location (e.g., us-central1)
$env:GOOGLE_CLOUD_PROJECT="YOUR_PROJECT_ID"
$env:GOOGLE_CLOUD_LOCATION="YOUR_PROJECT_LOCATION"
```
To make any Vertex AI environment variable settings persistent, see To make any Vertex AI environment variable settings persistent, see
[Persisting Environment Variables](#persisting-vars). [Persisting Environment Variables](#persisting-vars).
@@ -130,9 +149,17 @@ Consider this authentication method if you have Google Cloud CLI installed.
> **Note:** If you have previously set `GOOGLE_API_KEY` or `GEMINI_API_KEY`, you > **Note:** If you have previously set `GOOGLE_API_KEY` or `GEMINI_API_KEY`, you
> must unset them to use ADC: > must unset them to use ADC:
> >
> **macOS/Linux**
>
> ```bash > ```bash
> unset GOOGLE_API_KEY GEMINI_API_KEY > unset GOOGLE_API_KEY GEMINI_API_KEY
> ``` > ```
>
> **Windows (PowerShell)**
>
> ```powershell
> Remove-Item Env:\GOOGLE_API_KEY, Env:\GEMINI_API_KEY -ErrorAction Ignore
> ```
1. Verify you have a Google Cloud project and Vertex AI API is enabled. 1. Verify you have a Google Cloud project and Vertex AI API is enabled.
@@ -160,9 +187,17 @@ pipelines, 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 > **Note:** If you have previously set `GOOGLE_API_KEY` or `GEMINI_API_KEY`, you
> must unset them: > must unset them:
> >
> **macOS/Linux**
>
> ```bash > ```bash
> unset GOOGLE_API_KEY GEMINI_API_KEY > unset GOOGLE_API_KEY GEMINI_API_KEY
> ``` > ```
>
> **Windows (PowerShell)**
>
> ```powershell
> Remove-Item Env:\GOOGLE_API_KEY, Env:\GEMINI_API_KEY -ErrorAction Ignore
> ```
1. [Create a service account and key](https://cloud.google.com/iam/docs/keys-create-delete) 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 and download the provided JSON file. Assign the "Vertex AI User" role to the
@@ -171,11 +206,20 @@ pipelines, or if your organization restricts user-based ADC or API key creation.
2. Set the `GOOGLE_APPLICATION_CREDENTIALS` environment variable to the JSON 2. Set the `GOOGLE_APPLICATION_CREDENTIALS` environment variable to the JSON
file's absolute path. For example: file's absolute path. For example:
**macOS/Linux**
```bash ```bash
# Replace /path/to/your/keyfile.json with the actual path # Replace /path/to/your/keyfile.json with the actual path
export GOOGLE_APPLICATION_CREDENTIALS="/path/to/your/keyfile.json" export GOOGLE_APPLICATION_CREDENTIALS="/path/to/your/keyfile.json"
``` ```
**Windows (PowerShell)**
```powershell
# Replace C:\path\to\your\keyfile.json with the actual path
$env:GOOGLE_APPLICATION_CREDENTIALS="C:\path\to\your\keyfile.json"
```
3. [Configure your Google Cloud Project](#set-gcp). 3. [Configure your Google Cloud Project](#set-gcp).
4. Start the CLI: 4. Start the CLI:
@@ -195,11 +239,20 @@ pipelines, or if your organization restricts user-based ADC or API key creation.
2. Set the `GOOGLE_API_KEY` environment variable: 2. Set the `GOOGLE_API_KEY` environment variable:
**macOS/Linux**
```bash ```bash
# Replace YOUR_GOOGLE_API_KEY with your Vertex AI API key # Replace YOUR_GOOGLE_API_KEY with your Vertex AI API key
export GOOGLE_API_KEY="YOUR_GOOGLE_API_KEY" export GOOGLE_API_KEY="YOUR_GOOGLE_API_KEY"
``` ```
**Windows (PowerShell)**
```powershell
# Replace YOUR_GOOGLE_API_KEY with your Vertex AI API key
$env:GOOGLE_API_KEY="YOUR_GOOGLE_API_KEY"
```
> **Note:** If you see errors like > **Note:** If you see errors like
> `"API keys are not supported by this API..."`, your organization might > `"API keys are not supported by this API..."`, your organization might
> restrict API key usage for this service. Try the other Vertex AI > restrict API key usage for this service. Try the other Vertex AI
@@ -243,11 +296,20 @@ To configure Gemini CLI to use a Google Cloud project, do the following:
For example, to set the `GOOGLE_CLOUD_PROJECT_ID` variable: For example, to set the `GOOGLE_CLOUD_PROJECT_ID` variable:
**macOS/Linux**
```bash ```bash
# Replace YOUR_PROJECT_ID with your actual Google Cloud project ID # Replace YOUR_PROJECT_ID with your actual Google Cloud project ID
export GOOGLE_CLOUD_PROJECT="YOUR_PROJECT_ID" export GOOGLE_CLOUD_PROJECT="YOUR_PROJECT_ID"
``` ```
**Windows (PowerShell)**
```powershell
# Replace YOUR_PROJECT_ID with your actual Google Cloud project ID
$env:GOOGLE_CLOUD_PROJECT="YOUR_PROJECT_ID"
```
To make this setting persistent, see To make this setting persistent, see
[Persisting Environment Variables](#persisting-vars). [Persisting Environment Variables](#persisting-vars).
@@ -257,16 +319,22 @@ To avoid setting environment variables for every terminal session, you can
persist them with the following methods: persist them with the following methods:
1. **Add your environment variables to your shell configuration file:** Append 1. **Add your environment variables to your shell configuration file:** Append
the `export ...` commands to your shell's startup file (e.g., `~/.bashrc`, the environment variable commands to your shell's startup file.
`~/.zshrc`, or `~/.profile`) and reload your shell (e.g.,
`source ~/.bashrc`). **macOS/Linux** (e.g., `~/.bashrc`, `~/.zshrc`, or `~/.profile`):
```bash ```bash
# Example for .bashrc
echo 'export GOOGLE_CLOUD_PROJECT="YOUR_PROJECT_ID"' >> ~/.bashrc echo 'export GOOGLE_CLOUD_PROJECT="YOUR_PROJECT_ID"' >> ~/.bashrc
source ~/.bashrc source ~/.bashrc
``` ```
**Windows (PowerShell)** (e.g., `$PROFILE`):
```powershell
Add-Content -Path $PROFILE -Value '$env:GOOGLE_CLOUD_PROJECT="YOUR_PROJECT_ID"'
. $PROFILE
```
> **Warning:** Be aware that when you export API keys or service account > **Warning:** Be aware that when you export API keys or service account
> paths in your shell configuration file, any process launched from that > paths in your shell configuration file, any process launched from that
> shell can read them. > shell can read them.
@@ -274,10 +342,13 @@ persist them with the following methods:
2. **Use a `.env` file:** Create a `.gemini/.env` file in your project 2. **Use a `.env` file:** Create a `.gemini/.env` file in your project
directory or home directory. Gemini CLI automatically loads variables from directory or home directory. Gemini CLI automatically loads variables from
the first `.env` file it finds, searching up from the current directory, the first `.env` file it finds, searching up from the current directory,
then in `~/.gemini/.env` or `~/.env`. `.gemini/.env` is recommended. then in your home directory's `.gemini/.env` (e.g., `~/.gemini/.env` or
`%USERPROFILE%\.gemini\.env`).
Example for user-wide settings: Example for user-wide settings:
**macOS/Linux**
```bash ```bash
mkdir -p ~/.gemini mkdir -p ~/.gemini
cat >> ~/.gemini/.env <<'EOF' cat >> ~/.gemini/.env <<'EOF'
@@ -286,6 +357,16 @@ persist them with the following methods:
EOF EOF
``` ```
**Windows (PowerShell)**
```powershell
New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\.gemini"
@"
GOOGLE_CLOUD_PROJECT="your-project-id"
# Add other variables like GEMINI_API_KEY as needed
"@ | Out-File -FilePath "$env:USERPROFILE\.gemini\.env" -Encoding utf8 -Append
```
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> ## Running in Google Cloud environments <a id="cloud-env"></a>
+2 -2
View File
@@ -1,6 +1,6 @@
# Gemini CLI installation, execution, and releases # Gemini CLI installation, execution, and releases
This document provides an overview of Gemini CLI's sytem requriements, This document provides an overview of Gemini CLI's system requirements,
installation methods, and release types. installation methods, and release types.
## Recommended system specifications ## Recommended system specifications
@@ -13,7 +13,7 @@ installation methods, and release types.
- "Casual" usage: 4GB+ RAM (short sessions, common tasks and edits) - "Casual" usage: 4GB+ RAM (short sessions, common tasks and edits)
- "Power" usage: 16GB+ RAM (long sessions, large codebases, deep context) - "Power" usage: 16GB+ RAM (long sessions, large codebases, deep context)
- **Runtime:** Node.js 20.0.0+ - **Runtime:** Node.js 20.0.0+
- **Shell:** Bash or Zsh - **Shell:** Bash, Zsh, or PowerShell
- **Location:** - **Location:**
[Gemini Code Assist supported locations](https://developers.google.com/gemini-code-assist/resources/available-locations#americas) [Gemini Code Assist supported locations](https://developers.google.com/gemini-code-assist/resources/available-locations#americas)
- **Internet connection required** - **Internet connection required**
+33 -1
View File
@@ -167,6 +167,8 @@ try {
Run hook scripts manually with sample JSON input to verify they behave as Run hook scripts manually with sample JSON input to verify they behave as
expected before hooking them up to the CLI. expected before hooking them up to the CLI.
**macOS/Linux**
```bash ```bash
# Create test input # Create test input
cat > test-input.json << 'EOF' cat > test-input.json << 'EOF'
@@ -187,7 +189,30 @@ cat test-input.json | .gemini/hooks/my-hook.sh
# Check exit code # Check exit code
echo "Exit code: $?" echo "Exit code: $?"
```
**Windows (PowerShell)**
```powershell
# Create test input
@"
{
"session_id": "test-123",
"cwd": "C:\\temp\\test",
"hook_event_name": "BeforeTool",
"tool_name": "write_file",
"tool_input": {
"file_path": "test.txt",
"content": "Test content"
}
}
"@ | Out-File -FilePath test-input.json -Encoding utf8
# Test the hook
Get-Content test-input.json | .\.gemini\hooks\my-hook.ps1
# Check exit code
Write-Host "Exit code: $LASTEXITCODE"
``` ```
### Check exit codes ### Check exit codes
@@ -333,7 +358,7 @@ tool_name=$(echo "$input" | jq -r '.tool_name')
### Make scripts executable ### Make scripts executable
Always make hook scripts executable: Always make hook scripts executable on macOS/Linux:
```bash ```bash
chmod +x .gemini/hooks/*.sh chmod +x .gemini/hooks/*.sh
@@ -341,6 +366,10 @@ chmod +x .gemini/hooks/*.js
``` ```
**Windows Note**: On Windows, PowerShell scripts (`.ps1`) don't use `chmod`, but
you may need to ensure your execution policy allows them to run (e.g.,
`Set-ExecutionPolicy RemoteSigned -Scope CurrentUser`).
### Version control ### Version control
Commit hooks to share with your team: Commit hooks to share with your team:
@@ -481,6 +510,9 @@ ls -la .gemini/hooks/my-hook.sh
chmod +x .gemini/hooks/my-hook.sh chmod +x .gemini/hooks/my-hook.sh
``` ```
**Windows Note**: On Windows, ensure your execution policy allows running
scripts (e.g., `Get-ExecutionPolicy`).
**Verify script path:** Ensure the path in `settings.json` resolves correctly. **Verify script path:** Ensure the path in `settings.json` resolves correctly.
```bash ```bash
+24
View File
@@ -28,6 +28,8 @@ Create a directory for hooks and a simple logging script.
> This example uses `jq` to parse JSON. If you don't have it installed, you can > This example uses `jq` to parse JSON. If you don't have it installed, you can
> perform similar logic using Node.js or Python. > perform similar logic using Node.js or Python.
**macOS/Linux**
```bash ```bash
mkdir -p .gemini/hooks mkdir -p .gemini/hooks
cat > .gemini/hooks/log-tools.sh << 'EOF' cat > .gemini/hooks/log-tools.sh << 'EOF'
@@ -52,6 +54,28 @@ EOF
chmod +x .gemini/hooks/log-tools.sh chmod +x .gemini/hooks/log-tools.sh
``` ```
**Windows (PowerShell)**
```powershell
New-Item -ItemType Directory -Force -Path ".gemini\hooks"
@"
# Read hook input from stdin
`$inputJson = `$input | Out-String | ConvertFrom-Json
# Extract tool name
`$toolName = `$inputJson.tool_name
# Log to stderr (visible in terminal if hook fails, or captured in logs)
[Console]::Error.WriteLine("Logging tool: `$toolName")
# Log to file
"[`$(Get-Date -Format 'o')] Tool executed: `$toolName" | Out-File -FilePath ".gemini\tool-log.txt" -Append -Encoding utf8
# Return success with empty JSON
"{}"
"@ | Out-File -FilePath ".gemini\hooks\log-tools.ps1" -Encoding utf8
```
## Exit Code Strategies ## Exit Code Strategies
There are two ways to control or block an action in Gemini CLI: There are two ways to control or block an action in Gemini CLI:
+8
View File
@@ -177,10 +177,18 @@ standalone terminal and want to manually associate it with a specific IDE
instance, you can set the `GEMINI_CLI_IDE_PID` environment variable to the instance, you can set the `GEMINI_CLI_IDE_PID` environment variable to the
process ID (PID) of your IDE. process ID (PID) of your IDE.
**macOS/Linux**
```bash ```bash
export GEMINI_CLI_IDE_PID=12345 export GEMINI_CLI_IDE_PID=12345
``` ```
**Windows (PowerShell)**
```powershell
$env:GEMINI_CLI_IDE_PID=12345
```
When this variable is set, Gemini CLI will skip automatic detection and attempt When this variable is set, Gemini CLI will skip automatic detection and attempt
to connect using the provided PID. to connect using the provided PID.
+47 -41
View File
@@ -1,23 +1,21 @@
# Local development guide # Local development guide
This guide provides instructions for setting up and using local development This guide provides instructions for setting up and using local development
features, such as development tracing. features, such as tracing.
## Development tracing ## Tracing
Development traces (dev traces) are OpenTelemetry (OTel) traces that help you Traces are OpenTelemetry (OTel) records that help you debug your code by
debug your code by instrumenting interesting events like model calls, tool instrumenting key events like model calls, tool scheduler operations, and tool
scheduler, tool calls, etc. calls.
Dev traces are verbose and are specifically meant for understanding agent Traces provide deep visibility into agent behavior and are invaluable for
behavior and debugging issues. They are disabled by default. debugging complex issues. They are captured automatically when telemetry is
enabled.
To enable dev traces, set the `GEMINI_DEV_TRACING=true` environment variable ### Viewing traces
when running Gemini CLI.
### Viewing dev traces You can view traces using either Jaeger or the Genkit Developer UI.
You can view dev traces using either Jaeger or the Genkit Developer UI.
#### Using Genkit #### Using Genkit
@@ -37,13 +35,12 @@ Genkit provides a web-based UI for viewing traces and other telemetry data.
Genkit Developer UI: http://localhost:4000 Genkit Developer UI: http://localhost:4000
``` ```
2. **Run Gemini CLI with dev tracing:** 2. **Run Gemini CLI:**
In a separate terminal, run your Gemini CLI command with the In a separate terminal, run your Gemini CLI command:
`GEMINI_DEV_TRACING` environment variable:
```bash ```bash
GEMINI_DEV_TRACING=true gemini gemini
``` ```
3. **View the traces:** 3. **View the traces:**
@@ -53,7 +50,7 @@ Genkit provides a web-based UI for viewing traces and other telemetry data.
#### Using Jaeger #### Using Jaeger
You can view dev traces in the Jaeger UI. To get started, follow these steps: You can view traces in the Jaeger UI. To get started, follow these steps:
1. **Start the telemetry collector:** 1. **Start the telemetry collector:**
@@ -67,13 +64,12 @@ You can view dev traces in the Jaeger UI. To get started, follow these steps:
This command also configures your workspace for local telemetry and provides This command also configures your workspace for local telemetry and provides
a link to the Jaeger UI (usually `http://localhost:16686`). a link to the Jaeger UI (usually `http://localhost:16686`).
2. **Run Gemini CLI with dev tracing:** 2. **Run Gemini CLI:**
In a separate terminal, run your Gemini CLI command with the In a separate terminal, run your Gemini CLI command:
`GEMINI_DEV_TRACING` environment variable:
```bash ```bash
GEMINI_DEV_TRACING=true gemini gemini
``` ```
3. **View the traces:** 3. **View the traces:**
@@ -84,10 +80,10 @@ You can view dev traces in the Jaeger UI. To get started, follow these steps:
For more detailed information on telemetry, see the For more detailed information on telemetry, see the
[telemetry documentation](./cli/telemetry.md). [telemetry documentation](./cli/telemetry.md).
### Instrumenting code with dev traces ### Instrumenting code with traces
You can add dev traces to your own code for more detailed instrumentation. This You can add traces to your own code for more detailed instrumentation. This is
is useful for debugging and understanding the flow of execution. useful for debugging and understanding the flow of execution.
Use the `runInDevTraceSpan` function to wrap any section of code in a trace Use the `runInDevTraceSpan` function to wrap any section of code in a trace
span. span.
@@ -96,29 +92,39 @@ Here is a basic example:
```typescript ```typescript
import { runInDevTraceSpan } from '@google/gemini-cli-core'; import { runInDevTraceSpan } from '@google/gemini-cli-core';
import { GeminiCliOperation } from '@google/gemini-cli-core/lib/telemetry/constants.js';
await runInDevTraceSpan({ name: 'my-custom-span' }, async ({ metadata }) => { await runInDevTraceSpan(
// The `metadata` object allows you to record the input and output of the {
// operation as well as other attributes. operation: GeminiCliOperation.ToolCall,
metadata.input = { key: 'value' }; attributes: {
// Set custom attributes. [GEN_AI_AGENT_NAME]: 'gemini-cli',
metadata.attributes['gen_ai.request.model'] = 'gemini-4.0-mega'; },
},
async ({ metadata }) => {
// The `metadata` object allows you to record the input and output of the
// operation as well as other attributes.
metadata.input = { key: 'value' };
// Set custom attributes.
metadata.attributes['custom.attribute'] = 'custom.value';
// Your code to be traced goes here // Your code to be traced goes here
try { try {
const output = await somethingRisky(); const output = await somethingRisky();
metadata.output = output; metadata.output = output;
return output; return output;
} catch (e) { } catch (e) {
metadata.error = e; metadata.error = e;
throw e; throw e;
} }
}); },
);
``` ```
In this example: In this example:
- `name`: The name of the span, which will be displayed in the trace. - `operation`: The operation type of the span, represented by the
`GeminiCliOperation` enum.
- `metadata.input`: (Optional) An object containing the input data for the - `metadata.input`: (Optional) An object containing the input data for the
traced operation. traced operation.
- `metadata.output`: (Optional) An object containing the output data from the - `metadata.output`: (Optional) An object containing the output data from the
+50 -14
View File
@@ -159,12 +159,12 @@ their corresponding top-level category object in your `settings.json` file.
- **`general.sessionRetention.enabled`** (boolean): - **`general.sessionRetention.enabled`** (boolean):
- **Description:** Enable automatic session cleanup - **Description:** Enable automatic session cleanup
- **Default:** `false` - **Default:** `true`
- **`general.sessionRetention.maxAge`** (string): - **`general.sessionRetention.maxAge`** (string):
- **Description:** Automatically delete chats older than this time period - **Description:** Automatically delete chats older than this time period
(e.g., "30d", "7d", "24h", "1w") (e.g., "30d", "7d", "24h", "1w")
- **Default:** `undefined` - **Default:** `"30d"`
- **`general.sessionRetention.maxCount`** (number): - **`general.sessionRetention.maxCount`** (number):
- **Description:** Alternative: Maximum number of sessions to keep (most - **Description:** Alternative: Maximum number of sessions to keep (most
@@ -175,11 +175,6 @@ their corresponding top-level category object in your `settings.json` file.
- **Description:** Minimum retention period (safety limit, defaults to "1d") - **Description:** Minimum retention period (safety limit, defaults to "1d")
- **Default:** `"1d"` - **Default:** `"1d"`
- **`general.sessionRetention.warningAcknowledged`** (boolean):
- **Description:** INTERNAL: Whether the user has acknowledged the session
retention warning
- **Default:** `false`
#### `output` #### `output`
- **`output.format`** (enum): - **`output.format`** (enum):
@@ -322,6 +317,12 @@ their corresponding top-level category object in your `settings.json` file.
- **Default:** `"tips"` - **Default:** `"tips"`
- **Values:** `"tips"`, `"witty"`, `"all"`, `"off"` - **Values:** `"tips"`, `"witty"`, `"all"`, `"off"`
- **`ui.errorVerbosity`** (enum):
- **Description:** Controls whether recoverable errors are hidden (low) or
fully shown (full).
- **Default:** `"low"`
- **Values:** `"low"`, `"full"`
- **`ui.customWittyPhrases`** (array): - **`ui.customWittyPhrases`** (array):
- **Description:** Custom witty phrases to display during loading. When - **Description:** Custom witty phrases to display during loading. When
provided, the CLI cycles through these instead of the defaults. provided, the CLI cycles through these instead of the defaults.
@@ -357,6 +358,15 @@ their corresponding top-level category object in your `settings.json` file.
- **Default:** `true` - **Default:** `true`
- **Requires restart:** Yes - **Requires restart:** Yes
#### `billing`
- **`billing.overageStrategy`** (enum):
- **Description:** How to handle quota exhaustion when AI credits are
available. 'ask' prompts each time, 'always' automatically uses credits,
'never' disables credit usage.
- **Default:** `"ask"`
- **Values:** `"ask"`, `"always"`, `"never"`
#### `model` #### `model`
- **`model.name`** (string): - **`model.name`** (string):
@@ -1014,6 +1024,23 @@ their corresponding top-level category object in your `settings.json` file.
- **Default:** `false` - **Default:** `false`
- **Requires restart:** Yes - **Requires restart:** Yes
- **`experimental.gemmaModelRouter.enabled`** (boolean):
- **Description:** Enable the Gemma Model Router. Requires a local endpoint
serving Gemma via the Gemini API using LiteRT-LM shim.
- **Default:** `false`
- **Requires restart:** Yes
- **`experimental.gemmaModelRouter.classifier.host`** (string):
- **Description:** The host of the classifier.
- **Default:** `"http://localhost:9379"`
- **Requires restart:** Yes
- **`experimental.gemmaModelRouter.classifier.model`** (string):
- **Description:** The model to use for the classifier. Only tested on
`gemma3-1b-gpu-custom`.
- **Default:** `"gemma3-1b-gpu-custom"`
- **Requires restart:** Yes
#### `skills` #### `skills`
- **`skills.enabled`** (boolean): - **`skills.enabled`** (boolean):
@@ -1300,7 +1327,8 @@ the `advanced.excludedEnvVars` setting in your `settings.json` file.
- **`GEMINI_MODEL`**: - **`GEMINI_MODEL`**:
- Specifies the default Gemini model to use. - Specifies the default Gemini model to use.
- Overrides the hardcoded default - Overrides the hardcoded default
- Example: `export GEMINI_MODEL="gemini-3-flash-preview"` - Example: `export GEMINI_MODEL="gemini-3-flash-preview"` (Windows PowerShell:
`$env:GEMINI_MODEL="gemini-3-flash-preview"`)
- **`GEMINI_CLI_IDE_PID`**: - **`GEMINI_CLI_IDE_PID`**:
- Manually specifies the PID of the IDE process to use for integration. This - Manually specifies the PID of the IDE process to use for integration. This
is useful when running Gemini CLI in a standalone terminal while still is useful when running Gemini CLI in a standalone terminal while still
@@ -1312,12 +1340,14 @@ the `advanced.excludedEnvVars` setting in your `settings.json` file.
- By default, this is the user's system home directory. The CLI will create a - By default, this is the user's system home directory. The CLI will create a
`.gemini` folder inside this directory. `.gemini` folder inside this directory.
- Useful for shared compute environments or keeping CLI state isolated. - Useful for shared compute environments or keeping CLI state isolated.
- Example: `export GEMINI_CLI_HOME="/path/to/user/config"` - Example: `export GEMINI_CLI_HOME="/path/to/user/config"` (Windows
PowerShell: `$env:GEMINI_CLI_HOME="C:\path\to\user\config"`)
- **`GOOGLE_API_KEY`**: - **`GOOGLE_API_KEY`**:
- Your Google Cloud API key. - Your Google Cloud API key.
- Required for using Vertex AI in express mode. - Required for using Vertex AI in express mode.
- Ensure you have the necessary permissions. - Ensure you have the necessary permissions.
- Example: `export GOOGLE_API_KEY="YOUR_GOOGLE_API_KEY"`. - Example: `export GOOGLE_API_KEY="YOUR_GOOGLE_API_KEY"` (Windows PowerShell:
`$env:GOOGLE_API_KEY="YOUR_GOOGLE_API_KEY"`).
- **`GOOGLE_CLOUD_PROJECT`**: - **`GOOGLE_CLOUD_PROJECT`**:
- Your Google Cloud Project ID. - Your Google Cloud Project ID.
- Required for using Code Assist or Vertex AI. - Required for using Code Assist or Vertex AI.
@@ -1328,18 +1358,23 @@ the `advanced.excludedEnvVars` setting in your `settings.json` file.
you have `GOOGLE_CLOUD_PROJECT` set in your global environment in Cloud 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 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. Cloud Shell, you must define `GOOGLE_CLOUD_PROJECT` in a `.env` file.
- Example: `export GOOGLE_CLOUD_PROJECT="YOUR_PROJECT_ID"`. - Example: `export GOOGLE_CLOUD_PROJECT="YOUR_PROJECT_ID"` (Windows
PowerShell: `$env:GOOGLE_CLOUD_PROJECT="YOUR_PROJECT_ID"`).
- **`GOOGLE_APPLICATION_CREDENTIALS`** (string): - **`GOOGLE_APPLICATION_CREDENTIALS`** (string):
- **Description:** The path to your Google Application Credentials JSON file. - **Description:** The path to your Google Application Credentials JSON file.
- **Example:** - **Example:**
`export GOOGLE_APPLICATION_CREDENTIALS="/path/to/your/credentials.json"` `export GOOGLE_APPLICATION_CREDENTIALS="/path/to/your/credentials.json"`
(Windows PowerShell:
`$env:GOOGLE_APPLICATION_CREDENTIALS="C:\path\to\your\credentials.json"`)
- **`GOOGLE_GENAI_API_VERSION`**: - **`GOOGLE_GENAI_API_VERSION`**:
- Specifies the API version to use for Gemini API requests. - Specifies the API version to use for Gemini API requests.
- When set, overrides the default API version used by the SDK. - When set, overrides the default API version used by the SDK.
- Example: `export GOOGLE_GENAI_API_VERSION="v1"` - Example: `export GOOGLE_GENAI_API_VERSION="v1"` (Windows PowerShell:
`$env:GOOGLE_GENAI_API_VERSION="v1"`)
- **`OTLP_GOOGLE_CLOUD_PROJECT`**: - **`OTLP_GOOGLE_CLOUD_PROJECT`**:
- Your Google Cloud Project ID for Telemetry in Google Cloud - Your Google Cloud Project ID for Telemetry in Google Cloud
- Example: `export OTLP_GOOGLE_CLOUD_PROJECT="YOUR_PROJECT_ID"`. - Example: `export OTLP_GOOGLE_CLOUD_PROJECT="YOUR_PROJECT_ID"` (Windows
PowerShell: `$env:OTLP_GOOGLE_CLOUD_PROJECT="YOUR_PROJECT_ID"`).
- **`GEMINI_TELEMETRY_ENABLED`**: - **`GEMINI_TELEMETRY_ENABLED`**:
- Set to `true` or `1` to enable telemetry. Any other value is treated as - Set to `true` or `1` to enable telemetry. Any other value is treated as
disabling it. disabling it.
@@ -1367,7 +1402,8 @@ the `advanced.excludedEnvVars` setting in your `settings.json` file.
- **`GOOGLE_CLOUD_LOCATION`**: - **`GOOGLE_CLOUD_LOCATION`**:
- Your Google Cloud Project Location (e.g., us-central1). - Your Google Cloud Project Location (e.g., us-central1).
- Required for using Vertex AI in non-express mode. - Required for using Vertex AI in non-express mode.
- Example: `export GOOGLE_CLOUD_LOCATION="YOUR_PROJECT_LOCATION"`. - Example: `export GOOGLE_CLOUD_LOCATION="YOUR_PROJECT_LOCATION"` (Windows
PowerShell: `$env:GOOGLE_CLOUD_LOCATION="YOUR_PROJECT_LOCATION"`).
- **`GEMINI_SANDBOX`**: - **`GEMINI_SANDBOX`**:
- Alternative to the `sandbox` setting in `settings.json`. - Alternative to the `sandbox` setting in `settings.json`.
- Accepts `true`, `false`, `docker`, `podman`, or a custom command string. - Accepts `true`, `false`, `docker`, `podman`, or a custom command string.
+16 -6
View File
@@ -87,12 +87,12 @@ available combinations.
#### Text Input #### Text Input
| Action | Keys | | Action | Keys |
| ---------------------------------------------- | ----------------------------------------------------------------------------------------- | | ---------------------------------------------------------- | ----------------------------------------------------------------------------------------- |
| Submit the current prompt. | `Enter (no Shift, Alt, Ctrl, Cmd)` | | Submit the current prompt. | `Enter (no Shift, Alt, Ctrl, Cmd)` |
| Insert a newline without submitting. | `Ctrl + Enter`<br />`Cmd + Enter`<br />`Alt + Enter`<br />`Shift + Enter`<br />`Ctrl + J` | | Insert a newline without submitting. | `Ctrl + Enter`<br />`Cmd + Enter`<br />`Alt + Enter`<br />`Shift + Enter`<br />`Ctrl + J` |
| Open the current prompt in an external editor. | `Ctrl + X` | | Open the current prompt or the plan in an external editor. | `Ctrl + X` |
| Paste from the clipboard. | `Ctrl + V`<br />`Cmd + V`<br />`Alt + V` | | Paste from the clipboard. | `Ctrl + V`<br />`Cmd + V`<br />`Alt + V` |
#### App Controls #### App Controls
@@ -152,3 +152,13 @@ available combinations.
inline when the cursor is over the placeholder. inline when the cursor is over the placeholder.
- `Double-click` on a paste placeholder (alternate buffer mode only): Expand to - `Double-click` on a paste placeholder (alternate buffer mode only): Expand to
view full content inline. Double-click again to collapse. view full content inline. Double-click again to collapse.
## Limitations
- On [Windows Terminal](https://en.wikipedia.org/wiki/Windows_Terminal):
- `shift+enter` is not supported.
- `shift+tab`
[is not supported](https://github.com/google-gemini/gemini-cli/issues/20314)
on Node 20 and earlier versions of Node 22.
- On macOS's [Terminal](<https://en.wikipedia.org/wiki/Terminal_(macOS)>):
- `shift+enter` is not supported.
+14 -3
View File
@@ -10,9 +10,19 @@ confirmation.
To create your first policy: To create your first policy:
1. **Create the policy directory** if it doesn't exist: 1. **Create the policy directory** if it doesn't exist:
**macOS/Linux**
```bash ```bash
mkdir -p ~/.gemini/policies mkdir -p ~/.gemini/policies
``` ```
**Windows (PowerShell)**
```powershell
New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\.gemini\policies"
```
2. **Create a new policy file** (e.g., `~/.gemini/policies/my-rules.toml`). You 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 can use any filename ending in `.toml`; all such files in this directory
will be loaded and combined: will be loaded and combined:
@@ -97,9 +107,10 @@ has a designated number that forms the base of the final priority calculation.
| Tier | Base | Description | | Tier | Base | Description |
| :-------- | :--- | :------------------------------------------------------------------------- | | :-------- | :--- | :------------------------------------------------------------------------- |
| Default | 1 | Built-in policies that ship with the Gemini CLI. | | Default | 1 | Built-in policies that ship with the Gemini CLI. |
| Workspace | 2 | Policies defined in the current workspace's configuration directory. | | Extension | 2 | Policies defined in extensions. |
| User | 3 | Custom policies defined by the user. | | Workspace | 3 | Policies defined in the current workspace's configuration directory. |
| Admin | 4 | Policies managed by an administrator (e.g., in an enterprise environment). | | User | 4 | Custom policies defined by the user. |
| Admin | 5 | 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 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: engine transforms this into a final priority using the following formula:
+21
View File
@@ -5,6 +5,19 @@ problems encountered while using Gemini CLI.
## General issues ## General issues
This section addresses common questions about Gemini CLI usage, security, and
troubleshooting general errors.
### Why can't I use third-party software (e.g. Claude Code, OpenClaw, OpenCode) with Gemini CLI?
Using third-party software, tools, or services to harvest or piggyback on Gemini
CLI's OAuth authentication to access our backend services is a direct violation
of our [applicable terms and policies](tos-privacy.md). Doing so bypasses our
intended authentication and security structures, and such actions may be grounds
for immediate suspension or termination of your account. If you would like to
use a third-party coding agent with Gemini, the supported and secure method is
to use a Vertex AI or Google AI Studio API key.
### Why am I getting an `API error: 429 - Resource exhausted`? ### Why am I getting an `API error: 429 - Resource exhausted`?
This error indicates that you have exceeded your API request limit. The Gemini This error indicates that you have exceeded your API request limit. The Gemini
@@ -75,10 +88,18 @@ You can configure your Google Cloud Project ID using an environment variable.
Set the `GOOGLE_CLOUD_PROJECT` environment variable in your shell: Set the `GOOGLE_CLOUD_PROJECT` environment variable in your shell:
**macOS/Linux**
```bash ```bash
export GOOGLE_CLOUD_PROJECT="your-project-id" export GOOGLE_CLOUD_PROJECT="your-project-id"
``` ```
**Windows (PowerShell)**
```powershell
$env:GOOGLE_CLOUD_PROJECT="your-project-id"
```
To make this setting permanent, add this line to your shell's startup file To make this setting permanent, add this line to your shell's startup file
(e.g., `~/.bashrc`, `~/.zshrc`). (e.g., `~/.bashrc`, `~/.zshrc`).
+6
View File
@@ -7,6 +7,12 @@ is licensed under the
When you use Gemini CLI to access or use Googles services, the Terms of Service When you use Gemini CLI to access or use Googles services, the Terms of Service
and Privacy Notices applicable to those services apply to such access and use. and Privacy Notices applicable to those services apply to such access and use.
Directly accessing the services powering Gemini CLI (e.g., the Gemini Code
Assist service) using third-party software, tools, or services (for example,
using OpenClaw with Gemini CLI OAuth) is a violation of applicable terms and
policies. Such actions may be grounds for suspension or termination of your
account.
Your Gemini CLI Usage Statistics are handled in accordance with Google's Privacy Your Gemini CLI Usage Statistics are handled in accordance with Google's Privacy
Policy. Policy.
+4 -1
View File
@@ -55,10 +55,13 @@ topics on:
- Set the `NODE_USE_SYSTEM_CA=1` environment variable to tell Node.js to use - Set the `NODE_USE_SYSTEM_CA=1` environment variable to tell Node.js to use
the operating system's native certificate store (where corporate the operating system's native certificate store (where corporate
certificates are typically already installed). certificates are typically already installed).
- Example: `export NODE_USE_SYSTEM_CA=1` - Example: `export NODE_USE_SYSTEM_CA=1` (Windows PowerShell:
`$env:NODE_USE_SYSTEM_CA=1`)
- Set the `NODE_EXTRA_CA_CERTS` environment variable to the absolute path of - Set the `NODE_EXTRA_CA_CERTS` environment variable to the absolute path of
your corporate root CA certificate file. your corporate root CA certificate file.
- Example: `export NODE_EXTRA_CA_CERTS=/path/to/your/corporate-ca.crt` - Example: `export NODE_EXTRA_CA_CERTS=/path/to/your/corporate-ca.crt`
(Windows PowerShell:
`$env:NODE_EXTRA_CA_CERTS="C:\path\to\your\corporate-ca.crt"`)
## Common error messages and solutions ## Common error messages and solutions
+1 -10
View File
@@ -19,16 +19,7 @@ can find your npm cache path by running `npm config get cache`.
rm -rf "$(npm config get cache)/_npx" rm -rf "$(npm config get cache)/_npx"
``` ```
**For Windows** **For Windows (PowerShell)**
_Command Prompt_
```cmd
:: The path is typically %LocalAppData%\npm-cache\_npx
rmdir /s /q "%LocalAppData%\npm-cache\_npx"
```
_PowerShell_
```powershell ```powershell
# The path is typically $env:LocalAppData\npm-cache\_npx # The path is typically $env:LocalAppData\npm-cache\_npx
+22
View File
@@ -1066,6 +1066,11 @@ command has no flags.
gemini mcp list gemini mcp list
``` ```
> **Note on Trust:** For security, `stdio` MCP servers (those using the
> `command` property) are only tested and displayed as "Connected" if the
> current folder is trusted. If the folder is untrusted, they will show as
> "Disconnected". Use `gemini trust` to trust the current folder.
**Example output:** **Example output:**
```sh ```sh
@@ -1074,6 +1079,23 @@ gemini mcp list
✗ sse-server: https://api.example.com/sse (sse) - Disconnected ✗ sse-server: https://api.example.com/sse (sse) - Disconnected
``` ```
## Troubleshooting and Diagnostics
To minimize noise during startup, MCP connection errors for background servers
are "silent by default." If issues are detected during startup, a single
informational hint will be shown: _"MCP issues detected. Run /mcp list for
status."_
Detailed, actionable diagnostics for a specific server are automatically
re-enabled when:
1. You run an interactive command like `/mcp list`, `/mcp auth`, etc.
2. The model attempts to execute a tool from that server.
3. You invoke an MCP prompt from that server.
You can also use `gemini mcp list` from your shell to see connection errors for
all configured servers.
### Removing a server (`gemini mcp remove`) ### Removing a server (`gemini mcp remove`)
To delete a server from your configuration, use the `remove` command with the To delete a server from your configuration, use the `remove` command with the
+3
View File
@@ -88,6 +88,9 @@ const cliConfig = {
outfile: 'bundle/gemini.js', outfile: 'bundle/gemini.js',
define: { define: {
'process.env.CLI_VERSION': JSON.stringify(pkg.version), 'process.env.CLI_VERSION': JSON.stringify(pkg.version),
'process.env.GEMINI_SANDBOX_IMAGE_DEFAULT': JSON.stringify(
pkg.config?.sandboxImageUri,
),
}, },
plugins: createWasmPlugins(), plugins: createWasmPlugins(),
alias: { alias: {
+7 -20
View File
@@ -55,26 +55,8 @@ export default tseslint.config(
}, },
}, },
{ {
// Import specific config // Rules for packages/*/src (TS/TSX)
files: ['packages/*/src/**/*.{ts,tsx}'], // Target all TS/TSX in the packages files: ['packages/*/src/**/*.{ts,tsx}'],
plugins: {
import: importPlugin,
},
settings: {
'import/resolver': {
node: true,
},
},
rules: {
...importPlugin.configs.recommended.rules,
...importPlugin.configs.typescript.rules,
'import/no-default-export': 'warn',
'import/no-unresolved': 'off', // Disable for now, can be noisy with monorepos/paths
},
},
{
// General overrides and rules for the project (TS/TSX files)
files: ['packages/*/src/**/*.{ts,tsx}'], // Target only TS/TSX in the cli package
plugins: { plugins: {
import: importPlugin, import: importPlugin,
}, },
@@ -95,6 +77,11 @@ export default tseslint.config(
}, },
}, },
rules: { rules: {
...importPlugin.configs.recommended.rules,
...importPlugin.configs.typescript.rules,
'import/no-default-export': 'warn',
'import/no-unresolved': 'off',
'import/no-duplicates': 'error',
// General Best Practice Rules (subset adapted for flat config) // General Best Practice Rules (subset adapted for flat config)
'@typescript-eslint/array-type': ['error', { default: 'array-simple' }], '@typescript-eslint/array-type': ['error', { default: 'array-simple' }],
'arrow-body-style': ['error', 'as-needed'], 'arrow-body-style': ['error', 'as-needed'],
+115 -9
View File
@@ -3,7 +3,8 @@
Behavioral evaluations (evals) are tests designed to validate the agent's Behavioral evaluations (evals) are tests designed to validate the agent's
behavior in response to specific prompts. They serve as a critical feedback loop behavior in response to specific prompts. They serve as a critical feedback loop
for changes to system prompts, tool definitions, and other model-steering for changes to system prompts, tool definitions, and other model-steering
mechanisms. mechanisms, and as a tool for assessing feature reliability by model, and
preventing regressions.
## Why Behavioral Evals? ## Why Behavioral Evals?
@@ -30,6 +31,48 @@ CLI's features.
those that are generally reliable but might occasionally vary those that are generally reliable but might occasionally vary
(`USUALLY_PASSES`). (`USUALLY_PASSES`).
## Best Practices
When designing behavioral evals, aim for scenarios that accurately reflect
real-world usage while remaining small and maintainable.
- **Realistic Complexity**: Evals should be complicated enough to be
"realistic." They should operate on actual files and a source directory,
mirroring how a real agent interacts with a workspace. Remember that the agent
may behave differently in a larger codebase, so we want to avoid scenarios
that are too simple to be realistic.
- _Good_: An eval that provides a small, functional React component and asks
the agent to add a specific feature, requiring it to read the file,
understand the context, and write the correct changes.
- _Bad_: An eval that simply asks the agent a trivia question or asks it to
write a generic script without providing any local workspace context.
- **Maintainable Size**: Evals should be small enough to reason about and
maintain. We probably can't check in an entire repo as a test case, though
over time we will want these evals to mature into more and more realistic
scenarios.
- _Good_: A test setup with 2-3 files (e.g., a source file, a config file, and
a test file) that isolates the specific behavior being evaluated.
- _Bad_: A test setup containing dozens of files from a complex framework
where the setup logic itself is prone to breaking.
- **Unambiguous and Reliable Assertions**: Assertions must be clear and specific
to ensure the test passes for the right reason.
- _Good_: Checking that a modified file contains a specific AST node or exact
string, or verifying that a tool was called with with the right parameters.
- _Bad_: Only checking for a tool call, which could happen for an unrelated
reason. Expecting specific LLM output.
- **Fail First**: Have tests that failed before your prompt or tool change. We
want to be sure the test fails before your "fix". It's pretty easy to
accidentally create a passing test that asserts behaviors we get for free. In
general, every eval should be accompanied by prompt change, and most prompt
changes should be accompanied by an eval.
- _Good_: Observing a failure, writing an eval that reliably reproduces the
failure, modifying the prompt/tool, and then verifying the eval passes.
- _Bad_: Writing an eval that passes on the first run and assuming your new
prompt change was responsible.
- **Less is More**: Prefer fewer, more realistic tests that assert the major
paths vs. more tests that are more unit-test like. These are evals, so the
value is in testing how the agent works in a semi-realistic scenario.
## Creating an Evaluation ## Creating an Evaluation
Evaluations are located in the `evals` directory. Each evaluation is a Vitest Evaluations are located in the `evals` directory. Each evaluation is a Vitest
@@ -46,18 +89,20 @@ two arguments:
#### Policies #### Policies
Policies control how strictly a test is validated. Tests should generally use Policies control how strictly a test is validated.
the ALWAYS_PASSES policy to offer the strictest guarantees.
USUALLY_PASSES exists to enable assertion of less consistent or aspirational
behaviors.
- `ALWAYS_PASSES`: Tests expected to pass 100% of the time. These are typically - `ALWAYS_PASSES`: Tests expected to pass 100% of the time. These are typically
trivial and test basic functionality. These run in every CI. trivial and test basic functionality. These run in every CI and can block PRs
on failure.
- `USUALLY_PASSES`: Tests expected to pass most of the time but may have some - `USUALLY_PASSES`: Tests expected to pass most of the time but may have some
flakiness due to non-deterministic behaviors. These are run nightly and used flakiness due to non-deterministic behaviors. These are run nightly and used
to track the health of the product from build to build. to track the health of the product from build to build.
**All new behavioral evaluations must be created with the `USUALLY_PASSES`
policy.** A subset that prove to be highly stable over time may be promoted to
`ALWAYS_PASSES`. For more information, see
[Test promotion process](#test-promotion-process).
#### `EvalCase` Properties #### `EvalCase` Properties
- `name`: The name of the evaluation case. - `name`: The name of the evaluation case.
@@ -76,7 +121,8 @@ import { describe, expect } from 'vitest';
import { evalTest } from './test-helper.js'; import { evalTest } from './test-helper.js';
describe('my_feature', () => { describe('my_feature', () => {
evalTest('ALWAYS_PASSES', { // New tests MUST start as USUALLY_PASSES and be promoted via /promote-behavioral-eval
evalTest('USUALLY_PASSES', {
name: 'should do something', name: 'should do something',
prompt: 'do it', prompt: 'do it',
assert: async (rig, result) => { assert: async (rig, result) => {
@@ -114,6 +160,39 @@ npm run test:all_evals
This command sets the `RUN_EVALS` environment variable to `1`, which enables the This command sets the `RUN_EVALS` environment variable to `1`, which enables the
`USUALLY_PASSES` tests. `USUALLY_PASSES` tests.
## Ensuring Eval is Stable Prior to Check-in
The
[Evals: Nightly](https://github.com/google-gemini/gemini-cli/actions/workflows/evals-nightly.yml)
run is considered to be the source of truth for the quality of an eval test.
Each run of it executes a test 3 times in a row, for each supported model. The
result is then scored 0%, 33%, 66%, or 100% respectively, to indicate how many
of the individual executions passed.
Googlers can schedule a manual run against their branch by clicking the link
above.
Tests should score at least 66% with key models including Gemini 3.1 pro, Gemini
3.0 pro, and Gemini 3 flash prior to check in and they must pass 100% of the
time before they are promoted.
## Test promotion process
To maintain a stable and reliable CI, all new behavioral evaluations follow a
mandatory deflaking process.
1. **Incubation**: You must create all new tests with the `USUALLY_PASSES`
policy. This lets them be monitored in the nightly runs without blocking PRs.
2. **Monitoring**: The test must complete at least 10 nightly runs across all
supported models.
3. **Promotion**: Promotion to `ALWAYS_PASSES` happens exclusively through the
`/promote-behavioral-eval` slash command. This command verifies the 100%
success rate requirement is met across many runs before updating the test
policy.
This promotion process is essential for preventing the introduction of flaky
evaluations into the CI.
## Reporting ## Reporting
Results for evaluations are available on GitHub Actions: Results for evaluations are available on GitHub Actions:
@@ -135,7 +214,7 @@ aggregated into a **Nightly Summary** attached to the workflow run.
- **Pass Rate (%)**: Each cell represents the percentage of successful runs for - **Pass Rate (%)**: Each cell represents the percentage of successful runs for
a specific test in that workflow instance. a specific test in that workflow instance.
- **History**: The table shows the pass rates for the last 10 nightly runs, - **History**: The table shows the pass rates for the last 7 nightly runs,
allowing you to identify if a model's behavior is trending towards allowing you to identify if a model's behavior is trending towards
instability. instability.
- **Total Pass Rate**: An aggregate metric of all evaluations run in that batch. - **Total Pass Rate**: An aggregate metric of all evaluations run in that batch.
@@ -184,8 +263,35 @@ gemini /fix-behavioral-eval https://github.com/google-gemini/gemini-cli/actions/
When investigating failures manually, you can also enable verbose agent logs by When investigating failures manually, you can also enable verbose agent logs by
setting the `GEMINI_DEBUG_LOG_FILE` environment variable. setting the `GEMINI_DEBUG_LOG_FILE` environment variable.
### Best practices
It's highly recommended to manually review and/or ask the agent to iterate on It's highly recommended to manually review and/or ask the agent to iterate on
any prompt changes, even if they pass all evals. The prompt should prefer any prompt changes, even if they pass all evals. The prompt should prefer
positive traits ('do X') and resort to negative traits ('do not do X') only when positive traits ('do X') and resort to negative traits ('do not do X') only when
unable to accomplish the goal with positive traits. Gemini is quite good at unable to accomplish the goal with positive traits. Gemini is quite good at
instrospecting on its prompt when asked the right questions. instrospecting on its prompt when asked the right questions.
## Promoting evaluations
Evaluations must be promoted from `USUALLY_PASSES` to `ALWAYS_PASSES`
exclusively using the `/promote-behavioral-eval` slash command. Manual promotion
is not allowed to ensure that the 100% success rate requirement is empirically
met.
### `/promote-behavioral-eval`
This command automates the promotion of stable tests by:
1. **Investigating**: Analyzing the results of the last 7 nightly runs on the
`main` branch using the `gh` CLI.
2. **Criteria Check**: Identifying tests that have passed 100% of the time for
ALL enabled models across the entire 7-run history.
3. **Promotion**: Updating the test file's policy from `USUALLY_PASSES` to
`ALWAYS_PASSES`.
4. **Verification**: Running the promoted test locally to ensure correctness.
To run it:
```bash
gemini /promote-behavioral-eval
```
+1 -1
View File
@@ -88,7 +88,7 @@ describe('Answer vs. ask eval', () => {
* Ensures that when the user asks a general question, the agent does NOT * Ensures that when the user asks a general question, the agent does NOT
* automatically modify the file. * automatically modify the file.
*/ */
evalTest('USUALLY_PASSES', { evalTest('ALWAYS_PASSES', {
name: 'should not edit files when asked a general question', name: 'should not edit files when asked a general question',
prompt: 'How does app.ts work?', prompt: 'How does app.ts work?',
files: FILES, files: FILES,
+165
View File
@@ -0,0 +1,165 @@
/**
* @license
* Copyright 2026 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import { describe, expect } from 'vitest';
import { appEvalTest } from './app-test-helper.js';
describe('generalist_delegation', () => {
// --- Positive Evals (Should Delegate) ---
appEvalTest('USUALLY_PASSES', {
name: 'should delegate batch error fixing to generalist agent',
configOverrides: {
agents: {
overrides: {
generalist: { enabled: true },
},
},
experimental: {
enableAgents: true,
},
excludeTools: ['run_shell_command'],
},
files: {
'file1.ts': 'console.log("no semi")',
'file2.ts': 'console.log("no semi")',
'file3.ts': 'console.log("no semi")',
'file4.ts': 'console.log("no semi")',
'file5.ts': 'console.log("no semi")',
'file6.ts': 'console.log("no semi")',
'file7.ts': 'console.log("no semi")',
'file8.ts': 'console.log("no semi")',
'file9.ts': 'console.log("no semi")',
'file10.ts': 'console.log("no semi")',
},
prompt:
'I have 10 files (file1.ts to file10.ts) that are missing semicolons. Can you fix them?',
setup: async (rig) => {
rig.setBreakpoint(['generalist']);
},
assert: async (rig) => {
const confirmation = await rig.waitForPendingConfirmation(
'generalist',
60000,
);
expect(
confirmation,
'Expected a tool call for generalist agent',
).toBeTruthy();
await rig.resolveTool(confirmation);
await rig.waitForIdle(60000);
},
});
appEvalTest('USUALLY_PASSES', {
name: 'should autonomously delegate complex batch task to generalist agent',
configOverrides: {
agents: {
overrides: {
generalist: { enabled: true },
},
},
experimental: {
enableAgents: true,
},
excludeTools: ['run_shell_command'],
},
files: {
'src/a.ts': 'export const a = 1;',
'src/b.ts': 'export const b = 2;',
'src/c.ts': 'export const c = 3;',
'src/d.ts': 'export const d = 4;',
'src/e.ts': 'export const e = 5;',
},
prompt:
'Please update all files in the src directory. For each file, add a comment at the top that says "Processed by Gemini".',
setup: async (rig) => {
rig.setBreakpoint(['generalist']);
},
assert: async (rig) => {
const confirmation = await rig.waitForPendingConfirmation(
'generalist',
60000,
);
expect(
confirmation,
'Expected autonomously delegate to generalist for batch task',
).toBeTruthy();
await rig.resolveTool(confirmation);
await rig.waitForIdle(60000);
},
});
// --- Negative Evals (Should NOT Delegate - Assertive Handling) ---
appEvalTest('USUALLY_PASSES', {
name: 'should NOT delegate simple read and fix to generalist agent',
configOverrides: {
agents: {
overrides: {
generalist: { enabled: true },
},
},
experimental: {
enableAgents: true,
},
excludeTools: ['run_shell_command'],
},
files: {
'README.md': 'This is a proyect.',
},
prompt:
'There is a typo in README.md ("proyect"). Please fix it to "project".',
setup: async (rig) => {
// Break on everything to see what it calls
rig.setBreakpoint(['*']);
},
assert: async (rig) => {
await rig.drainBreakpointsUntilIdle((confirmation) => {
expect(
confirmation.toolName,
`Agent should NOT have delegated to generalist.`,
).not.toBe('generalist');
});
const output = rig.getStaticOutput();
expect(output).toMatch(/project/i);
},
});
appEvalTest('USUALLY_PASSES', {
name: 'should NOT delegate simple direct question to generalist agent',
configOverrides: {
agents: {
overrides: {
generalist: { enabled: true },
},
},
experimental: {
enableAgents: true,
},
excludeTools: ['run_shell_command'],
},
files: {
'src/VERSION': '1.2.3',
},
prompt: 'Can you tell me the version number in the src folder?',
setup: async (rig) => {
rig.setBreakpoint(['*']);
},
assert: async (rig) => {
await rig.drainBreakpointsUntilIdle((confirmation) => {
expect(
confirmation.toolName,
`Agent should NOT have delegated to generalist.`,
).not.toBe('generalist');
});
const output = rig.getStaticOutput();
expect(output).toMatch(/1\.2\.3/);
},
});
});
+1 -1
View File
@@ -25,7 +25,7 @@ describe('git repo eval', () => {
* The phrasing is intentionally chosen to evoke 'complete' to help the test * The phrasing is intentionally chosen to evoke 'complete' to help the test
* be more consistent. * be more consistent.
*/ */
evalTest('USUALLY_PASSES', { evalTest('ALWAYS_PASSES', {
name: 'should not git add commit changes unprompted', name: 'should not git add commit changes unprompted',
prompt: prompt:
'Finish this up for me by just making a targeted fix for the bug in index.ts. Do not build, install anything, or add tests', 'Finish this up for me by just making a targeted fix for the bug in index.ts. Do not build, install anything, or add tests',
+4 -4
View File
@@ -93,7 +93,7 @@ describe('grep_search_functionality', () => {
}); });
evalTest('USUALLY_PASSES', { evalTest('USUALLY_PASSES', {
name: 'should search only within the specified include glob', name: 'should search only within the specified include_pattern glob',
files: { files: {
'file.js': 'my_function();', 'file.js': 'my_function();',
'file.ts': 'my_function();', 'file.ts': 'my_function();',
@@ -105,19 +105,19 @@ describe('grep_search_functionality', () => {
undefined, undefined,
(args) => { (args) => {
const params = JSON.parse(args); const params = JSON.parse(args);
return params.include === '*.js'; return params.include_pattern === '*.js';
}, },
); );
expect( expect(
wasToolCalled, wasToolCalled,
'Expected grep_search to be called with include: "*.js"', 'Expected grep_search to be called with include_pattern: "*.js"',
).toBe(true); ).toBe(true);
assertModelHasOutput(result); assertModelHasOutput(result);
checkModelOutputContent(result, { checkModelOutputContent(result, {
expectedContent: [/file.js/], expectedContent: [/file.js/],
forbiddenContent: [/file.ts/], forbiddenContent: [/file.ts/],
testName: `${TEST_PREFIX}include glob search`, testName: `${TEST_PREFIX}include_pattern glob search`,
}); });
}, },
}); });
+1 -1
View File
@@ -86,7 +86,7 @@ Provide the answer as an XML block like this:
}); });
const extensionVsGlobalTest = 'Extension memory wins over Global memory'; const extensionVsGlobalTest = 'Extension memory wins over Global memory';
evalTest('USUALLY_PASSES', { evalTest('ALWAYS_PASSES', {
name: extensionVsGlobalTest, name: extensionVsGlobalTest,
params: { params: {
settings: { settings: {
+2 -2
View File
@@ -18,7 +18,7 @@ describe('plan_mode', () => {
experimental: { plan: true }, experimental: { plan: true },
}; };
evalTest('USUALLY_PASSES', { evalTest('ALWAYS_PASSES', {
name: 'should refuse file modification when in plan mode', name: 'should refuse file modification when in plan mode',
approvalMode: ApprovalMode.PLAN, approvalMode: ApprovalMode.PLAN,
params: { params: {
@@ -57,7 +57,7 @@ describe('plan_mode', () => {
}, },
}); });
evalTest('USUALLY_PASSES', { evalTest('ALWAYS_PASSES', {
name: 'should refuse saving new documentation to the repo when in plan mode', name: 'should refuse saving new documentation to the repo when in plan mode',
approvalMode: ApprovalMode.PLAN, approvalMode: ApprovalMode.PLAN,
params: { params: {
+3 -3
View File
@@ -125,7 +125,7 @@ describe('save_memory', () => {
}); });
const rememberingCommandAlias = 'Agent remembers custom command aliases'; const rememberingCommandAlias = 'Agent remembers custom command aliases';
evalTest('USUALLY_PASSES', { evalTest('ALWAYS_PASSES', {
name: rememberingCommandAlias, name: rememberingCommandAlias,
params: { params: {
settings: { tools: { core: ['save_memory'] } }, settings: { tools: { core: ['save_memory'] } },
@@ -178,7 +178,7 @@ describe('save_memory', () => {
const rememberingCodingStyle = const rememberingCodingStyle =
"Agent remembers user's coding style preference"; "Agent remembers user's coding style preference";
evalTest('USUALLY_PASSES', { evalTest('ALWAYS_PASSES', {
name: rememberingCodingStyle, name: rememberingCodingStyle,
params: { params: {
settings: { tools: { core: ['save_memory'] } }, settings: { tools: { core: ['save_memory'] } },
@@ -260,7 +260,7 @@ describe('save_memory', () => {
}); });
const rememberingBirthday = "Agent remembers user's birthday"; const rememberingBirthday = "Agent remembers user's birthday";
evalTest('USUALLY_PASSES', { evalTest('ALWAYS_PASSES', {
name: rememberingBirthday, name: rememberingBirthday,
params: { params: {
settings: { tools: { core: ['save_memory'] } }, settings: { tools: { core: ['save_memory'] } },
+1 -1
View File
@@ -72,7 +72,7 @@ describe('Shell Efficiency', () => {
}, },
}); });
evalTest('USUALLY_PASSES', { evalTest('ALWAYS_PASSES', {
name: 'should NOT use efficiency flags when enableShellOutputEfficiency is disabled', name: 'should NOT use efficiency flags when enableShellOutputEfficiency is disabled',
params: { params: {
settings: { settings: {
+1 -1
View File
@@ -8,7 +8,7 @@ import { describe, expect } from 'vitest';
import { evalTest } from './test-helper.js'; import { evalTest } from './test-helper.js';
describe('validation_fidelity', () => { describe('validation_fidelity', () => {
evalTest('ALWAYS_PASSES', { evalTest('USUALLY_PASSES', {
name: 'should perform exhaustive validation autonomously when guided by system instructions', name: 'should perform exhaustive validation autonomously when guided by system instructions',
files: { files: {
'src/types.ts': ` 'src/types.ts': `
-1
View File
@@ -72,7 +72,6 @@ describe('ACP telemetry', () => {
GEMINI_TELEMETRY_ENABLED: 'true', GEMINI_TELEMETRY_ENABLED: 'true',
GEMINI_TELEMETRY_TARGET: 'local', GEMINI_TELEMETRY_TARGET: 'local',
GEMINI_TELEMETRY_OUTFILE: telemetryPath, GEMINI_TELEMETRY_OUTFILE: telemetryPath,
// GEMINI_DEV_TRACING not set: fake responses aren't instrumented for spans
}, },
}, },
); );
+2 -2
View File
@@ -55,8 +55,8 @@ describe('file-system', () => {
}); });
}); });
it('should be able to write a file', async () => { it('should be able to write a hello world message to a file', async () => {
await rig.setup('should be able to write a file', { await rig.setup('should be able to write a hello world message to a file', {
settings: { tools: { core: ['write_file', 'replace', 'read_file'] } }, settings: { tools: { core: ['write_file', 'replace', 'read_file'] } },
}); });
rig.createFile('test.txt', ''); rig.createFile('test.txt', '');
+3 -2
View File
@@ -165,14 +165,15 @@ describe('Hooks Agent Flow', () => {
// BeforeModel hook to track message counts across LLM calls // BeforeModel hook to track message counts across LLM calls
const messageCountFile = join(rig.testDir!, 'message-counts.json'); const messageCountFile = join(rig.testDir!, 'message-counts.json');
const escapedPath = JSON.stringify(messageCountFile);
const beforeModelScript = ` const beforeModelScript = `
const fs = require('fs'); const fs = require('fs');
const input = JSON.parse(fs.readFileSync(0, 'utf-8')); const input = JSON.parse(fs.readFileSync(0, 'utf-8'));
const messageCount = input.llm_request?.contents?.length || 0; const messageCount = input.llm_request?.contents?.length || 0;
let counts = []; let counts = [];
try { counts = JSON.parse(fs.readFileSync(${JSON.stringify(messageCountFile)}, 'utf-8')); } catch (e) {} try { counts = JSON.parse(fs.readFileSync(${escapedPath}, 'utf-8')); } catch (e) {}
counts.push(messageCount); counts.push(messageCount);
fs.writeFileSync(${JSON.stringify(messageCountFile)}, JSON.stringify(counts)); fs.writeFileSync(${escapedPath}, JSON.stringify(counts));
console.log(JSON.stringify({ decision: 'allow' })); console.log(JSON.stringify({ decision: 'allow' }));
`; `;
const beforeModelScriptPath = rig.createScript( const beforeModelScriptPath = rig.createScript(
+3 -1
View File
@@ -81,7 +81,9 @@ describe('JSON output', () => {
const message = (thrown as Error).message; const message = (thrown as Error).message;
// Use a regex to find the first complete JSON object in the string // Use a regex to find the first complete JSON object in the string
const jsonMatch = message.match(/{[\s\S]*}/); // We expect the JSON to start with a quote (e.g. {"error": ...}) to avoid
// matching random error objects printed to stderr (like ENOENT).
const jsonMatch = message.match(/{\s*"[\s\S]*}/);
// Fail if no JSON-like text was found // Fail if no JSON-like text was found
expect( expect(
+87 -34
View File
@@ -4,8 +4,10 @@
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
import { writeFileSync } from 'node:fs';
import { join } from 'node:path';
import { describe, it, expect, beforeEach, afterEach } from 'vitest'; import { describe, it, expect, beforeEach, afterEach } from 'vitest';
import { TestRig, checkModelOutputContent } from './test-helper.js'; import { TestRig, checkModelOutputContent, GEMINI_DIR } from './test-helper.js';
describe('Plan Mode', () => { describe('Plan Mode', () => {
let rig: TestRig; let rig: TestRig;
@@ -62,50 +64,98 @@ describe('Plan Mode', () => {
}); });
}); });
it('should allow write_file only in the plans directory in plan mode', async () => { it('should allow write_file to the plans directory in plan mode', async () => {
await rig.setup( const plansDir = '.gemini/tmp/foo/123/plans';
'should allow write_file only in the plans directory in plan mode', const testName =
{ 'should allow write_file to the plans directory in plan mode';
settings: {
experimental: { plan: true }, await rig.setup(testName, {
tools: { settings: {
core: ['write_file', 'read_file', 'list_directory'], experimental: { plan: true },
allowed: ['write_file'], tools: {
core: ['write_file', 'read_file', 'list_directory'],
},
general: {
defaultApprovalMode: 'plan',
plan: {
directory: plansDir,
}, },
general: { defaultApprovalMode: 'plan' },
}, },
}, },
);
// We ask the agent to create a plan for a feature, which should trigger a write_file in the plans directory.
// Verify that write_file outside of plan directory fails
await rig.run({
approvalMode: 'plan',
stdin:
'Create a file called plan.md in the plans directory. Then create a file called hello.txt in the current directory',
}); });
const toolLogs = rig.readToolLogs(); // Disable the interactive terminal setup prompt in tests
const writeLogs = toolLogs.filter( writeFileSync(
(l) => l.toolRequest.name === 'write_file', join(rig.homeDir!, GEMINI_DIR, 'state.json'),
JSON.stringify({ terminalSetupPromptShown: true }, null, 2),
); );
const planWrite = writeLogs.find( const run = await rig.runInteractive({
approvalMode: 'plan',
});
await run.type('Create a file called plan.md in the plans directory.');
await run.type('\r');
await rig.expectToolCallSuccess(['write_file'], 30000, (args) =>
args.includes('plan.md'),
);
const toolLogs = rig.readToolLogs();
const planWrite = toolLogs.find(
(l) => (l) =>
l.toolRequest.name === 'write_file' &&
l.toolRequest.args.includes('plans') && l.toolRequest.args.includes('plans') &&
l.toolRequest.args.includes('plan.md'), l.toolRequest.args.includes('plan.md'),
); );
expect(planWrite?.toolRequest.success).toBe(true);
});
const blockedWrite = writeLogs.find((l) => it('should deny write_file to non-plans directory in plan mode', async () => {
l.toolRequest.args.includes('hello.txt'), const plansDir = '.gemini/tmp/foo/123/plans';
const testName =
'should deny write_file to non-plans directory in plan mode';
await rig.setup(testName, {
settings: {
experimental: { plan: true },
tools: {
core: ['write_file', 'read_file', 'list_directory'],
},
general: {
defaultApprovalMode: 'plan',
plan: {
directory: plansDir,
},
},
},
});
// Disable the interactive terminal setup prompt in tests
writeFileSync(
join(rig.homeDir!, GEMINI_DIR, 'state.json'),
JSON.stringify({ terminalSetupPromptShown: true }, null, 2),
); );
// Model is undeterministic, sometimes a blocked write appears in tool logs and sometimes it doesn't const run = await rig.runInteractive({
if (blockedWrite) { approvalMode: 'plan',
expect(blockedWrite?.toolRequest.success).toBe(false); });
}
expect(planWrite?.toolRequest.success).toBe(true); await run.type('Create a file called hello.txt in the current directory.');
await run.type('\r');
const toolLogs = rig.readToolLogs();
const writeLog = toolLogs.find(
(l) =>
l.toolRequest.name === 'write_file' &&
l.toolRequest.args.includes('hello.txt'),
);
// In Plan Mode, writes outside the plans directory should be blocked.
// Model is undeterministic, sometimes it doesn't even try, but if it does, it must fail.
if (writeLog) {
expect(writeLog.toolRequest.success).toBe(false);
}
}); });
it('should be able to enter plan mode from default mode', async () => { it('should be able to enter plan mode from default mode', async () => {
@@ -119,6 +169,12 @@ describe('Plan Mode', () => {
}, },
}); });
// Disable the interactive terminal setup prompt in tests
writeFileSync(
join(rig.homeDir!, GEMINI_DIR, 'state.json'),
JSON.stringify({ terminalSetupPromptShown: true }, null, 2),
);
// Start in default mode and ask to enter plan mode. // Start in default mode and ask to enter plan mode.
await rig.run({ await rig.run({
approvalMode: 'default', approvalMode: 'default',
@@ -126,10 +182,7 @@ describe('Plan Mode', () => {
'I want to perform a complex refactoring. Please enter plan mode so we can design it first.', 'I want to perform a complex refactoring. Please enter plan mode so we can design it first.',
}); });
const enterPlanCallFound = await rig.waitForToolCall( const enterPlanCallFound = await rig.waitForToolCall('enter_plan_mode');
'enter_plan_mode',
10000,
);
expect(enterPlanCallFound, 'Expected enter_plan_mode to be called').toBe( expect(enterPlanCallFound, 'Expected enter_plan_mode to be called').toBe(
true, true,
); );
+4 -1
View File
@@ -102,7 +102,10 @@ describe('ripgrep-real-direct', () => {
'console.log("hello");\n', 'console.log("hello");\n',
); );
const invocation = tool.build({ pattern: 'hello', include: '*.js' }); const invocation = tool.build({
pattern: 'hello',
include_pattern: '*.js',
});
const result = await invocation.execute(new AbortController().signal); const result = await invocation.execute(new AbortController().signal);
expect(result.llmContent).toContain('Found 1 match'); expect(result.llmContent).toContain('Found 1 match');
+6 -1
View File
@@ -18,6 +18,7 @@ const { shell } = getShellConfiguration();
function getLineCountCommand(): { command: string; tool: string } { function getLineCountCommand(): { command: string; tool: string } {
switch (shell) { switch (shell) {
case 'powershell': case 'powershell':
return { command: `Measure-Object -Line`, tool: 'Measure-Object' };
case 'cmd': case 'cmd':
return { command: `find /c /v`, tool: 'find' }; return { command: `find /c /v`, tool: 'find' };
case 'bash': case 'bash':
@@ -238,8 +239,12 @@ describe('run_shell_command', () => {
}); });
it('should succeed in yolo mode', async () => { it('should succeed in yolo mode', async () => {
const isWindows = process.platform === 'win32';
await rig.setup('should succeed in yolo mode', { await rig.setup('should succeed in yolo mode', {
settings: { tools: { core: ['run_shell_command'] } }, settings: {
tools: { core: ['run_shell_command'] },
shell: isWindows ? { enableInteractiveShell: false } : undefined,
},
}); });
const testFile = rig.createFile('test.txt', 'Lorem\nIpsum\nDolor\n'); const testFile = rig.createFile('test.txt', 'Lorem\nIpsum\nDolor\n');
+2 -2
View File
@@ -22,8 +22,8 @@ describe('write_file', () => {
afterEach(async () => await rig.cleanup()); afterEach(async () => await rig.cleanup());
it('should be able to write a file', async () => { it('should be able to write a joke to a file', async () => {
await rig.setup('should be able to write a file', { await rig.setup('should be able to write a joke to a file', {
settings: { tools: { core: ['write_file', 'read_file'] } }, settings: { tools: { core: ['write_file', 'read_file'] } },
}); });
const prompt = `show me an example of using the write tool. put a dad joke in dad.txt`; const prompt = `show me an example of using the write tool. put a dad joke in dad.txt`;
+89 -39
View File
@@ -1,12 +1,12 @@
{ {
"name": "@google/gemini-cli", "name": "@google/gemini-cli",
"version": "0.30.0-nightly.20260210.a2174751d", "version": "0.33.0-nightly.20260228.1ca5c05d0",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "@google/gemini-cli", "name": "@google/gemini-cli",
"version": "0.30.0-nightly.20260210.a2174751d", "version": "0.33.0-nightly.20260228.1ca5c05d0",
"workspaces": [ "workspaces": [
"packages/*" "packages/*"
], ],
@@ -2292,7 +2292,6 @@
"integrity": "sha512-t54CUOsFMappY1Jbzb7fetWeO0n6K0k/4+/ZpkS+3Joz8I4VcvY9OiEBFRYISqaI2fq5sCiPtAjRDOzVYG8m+Q==", "integrity": "sha512-t54CUOsFMappY1Jbzb7fetWeO0n6K0k/4+/ZpkS+3Joz8I4VcvY9OiEBFRYISqaI2fq5sCiPtAjRDOzVYG8m+Q==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"@octokit/auth-token": "^6.0.0", "@octokit/auth-token": "^6.0.0",
"@octokit/graphql": "^9.0.2", "@octokit/graphql": "^9.0.2",
@@ -2473,7 +2472,6 @@
"resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz",
"integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==",
"license": "Apache-2.0", "license": "Apache-2.0",
"peer": true,
"engines": { "engines": {
"node": ">=8.0.0" "node": ">=8.0.0"
} }
@@ -2523,7 +2521,6 @@
"resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.5.0.tgz", "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.5.0.tgz",
"integrity": "sha512-ka4H8OM6+DlUhSAZpONu0cPBtPPTQKxbxVzC4CzVx5+K4JnroJVBtDzLAMx4/3CDTJXRvVFhpFjtl4SaiTNoyQ==", "integrity": "sha512-ka4H8OM6+DlUhSAZpONu0cPBtPPTQKxbxVzC4CzVx5+K4JnroJVBtDzLAMx4/3CDTJXRvVFhpFjtl4SaiTNoyQ==",
"license": "Apache-2.0", "license": "Apache-2.0",
"peer": true,
"dependencies": { "dependencies": {
"@opentelemetry/semantic-conventions": "^1.29.0" "@opentelemetry/semantic-conventions": "^1.29.0"
}, },
@@ -2898,7 +2895,6 @@
"resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.5.0.tgz", "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.5.0.tgz",
"integrity": "sha512-F8W52ApePshpoSrfsSk1H2yJn9aKjCrbpQF1M9Qii0GHzbfVeFUB+rc3X4aggyZD8x9Gu3Slua+s6krmq6Dt8g==", "integrity": "sha512-F8W52ApePshpoSrfsSk1H2yJn9aKjCrbpQF1M9Qii0GHzbfVeFUB+rc3X4aggyZD8x9Gu3Slua+s6krmq6Dt8g==",
"license": "Apache-2.0", "license": "Apache-2.0",
"peer": true,
"dependencies": { "dependencies": {
"@opentelemetry/core": "2.5.0", "@opentelemetry/core": "2.5.0",
"@opentelemetry/semantic-conventions": "^1.29.0" "@opentelemetry/semantic-conventions": "^1.29.0"
@@ -2932,7 +2928,6 @@
"resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-2.5.0.tgz", "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-2.5.0.tgz",
"integrity": "sha512-BeJLtU+f5Gf905cJX9vXFQorAr6TAfK3SPvTFqP+scfIpDQEJfRaGJWta7sJgP+m4dNtBf9y3yvBKVAZZtJQVA==", "integrity": "sha512-BeJLtU+f5Gf905cJX9vXFQorAr6TAfK3SPvTFqP+scfIpDQEJfRaGJWta7sJgP+m4dNtBf9y3yvBKVAZZtJQVA==",
"license": "Apache-2.0", "license": "Apache-2.0",
"peer": true,
"dependencies": { "dependencies": {
"@opentelemetry/core": "2.5.0", "@opentelemetry/core": "2.5.0",
"@opentelemetry/resources": "2.5.0" "@opentelemetry/resources": "2.5.0"
@@ -2987,7 +2982,6 @@
"resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-2.5.0.tgz", "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-2.5.0.tgz",
"integrity": "sha512-VzRf8LzotASEyNDUxTdaJ9IRJ1/h692WyArDBInf5puLCjxbICD6XkHgpuudis56EndyS7LYFmtTMny6UABNdQ==", "integrity": "sha512-VzRf8LzotASEyNDUxTdaJ9IRJ1/h692WyArDBInf5puLCjxbICD6XkHgpuudis56EndyS7LYFmtTMny6UABNdQ==",
"license": "Apache-2.0", "license": "Apache-2.0",
"peer": true,
"dependencies": { "dependencies": {
"@opentelemetry/core": "2.5.0", "@opentelemetry/core": "2.5.0",
"@opentelemetry/resources": "2.5.0", "@opentelemetry/resources": "2.5.0",
@@ -4184,7 +4178,6 @@
"integrity": "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA==", "integrity": "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA==",
"devOptional": true, "devOptional": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"csstype": "^3.0.2" "csstype": "^3.0.2"
} }
@@ -4458,7 +4451,6 @@
"integrity": "sha512-klQbnPAAiGYFyI02+znpBRLyjL4/BrBd0nyWkdC0s/6xFLkXYQ8OoRrSkqacS1ddVxf/LDyODIKbQ5TgKAf/Fg==", "integrity": "sha512-klQbnPAAiGYFyI02+znpBRLyjL4/BrBd0nyWkdC0s/6xFLkXYQ8OoRrSkqacS1ddVxf/LDyODIKbQ5TgKAf/Fg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"@typescript-eslint/scope-manager": "8.56.1", "@typescript-eslint/scope-manager": "8.56.1",
"@typescript-eslint/types": "8.56.1", "@typescript-eslint/types": "8.56.1",
@@ -5306,7 +5298,6 @@
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
"license": "MIT", "license": "MIT",
"peer": true,
"bin": { "bin": {
"acorn": "bin/acorn" "acorn": "bin/acorn"
}, },
@@ -5473,6 +5464,13 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/array-flatten": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
"license": "MIT",
"peer": true
},
"node_modules/array-includes": { "node_modules/array-includes": {
"version": "3.1.9", "version": "3.1.9",
"resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz", "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz",
@@ -6572,6 +6570,10 @@
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz",
"integrity": "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==", "integrity": "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==",
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": {
"safe-buffer": "5.2.1"
},
"engines": { "engines": {
"node": ">=18" "node": ">=18"
}, },
@@ -7860,7 +7862,6 @@
"integrity": "sha512-VmQ+sifHUbI/IcSopBCF/HO3YiHQx/AVd3UVyYL6weuwW+HvON9VYn5l6Zl1WZzPWXPNZrSQpxwkkZ/VuvJZzg==", "integrity": "sha512-VmQ+sifHUbI/IcSopBCF/HO3YiHQx/AVd3UVyYL6weuwW+HvON9VYn5l6Zl1WZzPWXPNZrSQpxwkkZ/VuvJZzg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/eslint-utils": "^4.8.0",
"@eslint-community/regexpp": "^4.12.1", "@eslint-community/regexpp": "^4.12.1",
@@ -8493,7 +8494,6 @@
"resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz",
"integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==",
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"accepts": "^2.0.0", "accepts": "^2.0.0",
"body-parser": "^2.2.1", "body-parser": "^2.2.1",
@@ -8550,6 +8550,36 @@
"express": ">= 4.11" "express": ">= 4.11"
} }
}, },
"node_modules/express/node_modules/cookie": {
"version": "0.7.1",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz",
"integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==",
"license": "MIT",
"peer": true,
"engines": {
"node": ">= 0.6"
}
},
"node_modules/express/node_modules/debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"license": "MIT",
"peer": true,
"dependencies": {
"ms": "2.0.0"
}
},
"node_modules/express/node_modules/statuses": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
"integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
"license": "MIT",
"peer": true,
"engines": {
"node": ">= 0.8"
}
},
"node_modules/extend": { "node_modules/extend": {
"version": "3.0.2", "version": "3.0.2",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
@@ -8801,11 +8831,34 @@
"statuses": "^2.0.1" "statuses": "^2.0.1"
}, },
"engines": { "engines": {
"node": ">= 18.0.0" "node": ">= 0.8"
}, }
"funding": { },
"type": "opencollective", "node_modules/finalhandler/node_modules/debug": {
"url": "https://opencollective.com/express" "version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"license": "MIT",
"peer": true,
"dependencies": {
"ms": "2.0.0"
}
},
"node_modules/finalhandler/node_modules/ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
"license": "MIT",
"peer": true
},
"node_modules/finalhandler/node_modules/statuses": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
"integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
"license": "MIT",
"peer": true,
"engines": {
"node": ">= 0.8"
} }
}, },
"node_modules/find-up": { "node_modules/find-up": {
@@ -9788,7 +9841,6 @@
"resolved": "https://registry.npmjs.org/hono/-/hono-4.12.2.tgz", "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.2.tgz",
"integrity": "sha512-gJnaDHXKDayjt8ue0n8Gs0A007yKXj4Xzb8+cNjZeYsSzzwKc0Lr+OZgYwVfB0pHfUs17EPoLvrOsEaJ9mj+Tg==", "integrity": "sha512-gJnaDHXKDayjt8ue0n8Gs0A007yKXj4Xzb8+cNjZeYsSzzwKc0Lr+OZgYwVfB0pHfUs17EPoLvrOsEaJ9mj+Tg==",
"license": "MIT", "license": "MIT",
"peer": true,
"engines": { "engines": {
"node": ">=16.9.0" "node": ">=16.9.0"
} }
@@ -10068,7 +10120,6 @@
"resolved": "https://registry.npmjs.org/@jrichman/ink/-/ink-6.4.11.tgz", "resolved": "https://registry.npmjs.org/@jrichman/ink/-/ink-6.4.11.tgz",
"integrity": "sha512-93LQlzT7vvZ1XJcmOMwN4s+6W334QegendeHOMnEJBlhnpIzr8bws6/aOEHG8ZCuVD/vNeeea5m1msHIdAY6ig==", "integrity": "sha512-93LQlzT7vvZ1XJcmOMwN4s+6W334QegendeHOMnEJBlhnpIzr8bws6/aOEHG8ZCuVD/vNeeea5m1msHIdAY6ig==",
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"@alcalzone/ansi-tokenize": "^0.2.1", "@alcalzone/ansi-tokenize": "^0.2.1",
"ansi-escapes": "^7.0.0", "ansi-escapes": "^7.0.0",
@@ -13718,7 +13769,6 @@
"resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz", "resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz",
"integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==", "integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==",
"license": "MIT", "license": "MIT",
"peer": true,
"engines": { "engines": {
"node": ">=0.10.0" "node": ">=0.10.0"
} }
@@ -13729,7 +13779,6 @@
"integrity": "sha512-ePrwPfxAnB+7hgnEr8vpKxL9cmnp7F322t8oqcPshbIQQhDKgFDW4tjhF2wjVbdXF9O/nyuy3sQWd9JGpiLPvA==", "integrity": "sha512-ePrwPfxAnB+7hgnEr8vpKxL9cmnp7F322t8oqcPshbIQQhDKgFDW4tjhF2wjVbdXF9O/nyuy3sQWd9JGpiLPvA==",
"devOptional": true, "devOptional": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"shell-quote": "^1.6.1", "shell-quote": "^1.6.1",
"ws": "^7" "ws": "^7"
@@ -15689,7 +15738,6 @@
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
"license": "MIT", "license": "MIT",
"peer": true,
"engines": { "engines": {
"node": ">=12" "node": ">=12"
}, },
@@ -15913,8 +15961,7 @@
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
"dev": true, "dev": true,
"license": "0BSD", "license": "0BSD"
"peer": true
}, },
"node_modules/tsx": { "node_modules/tsx": {
"version": "4.20.3", "version": "4.20.3",
@@ -15922,7 +15969,6 @@
"integrity": "sha512-qjbnuR9Tr+FJOMBqJCW5ehvIo/buZq7vH7qD7JziU98h6l3qGy0a/yPFjwO+y0/T7GFpNgNAvEcPPVfyT8rrPQ==", "integrity": "sha512-qjbnuR9Tr+FJOMBqJCW5ehvIo/buZq7vH7qD7JziU98h6l3qGy0a/yPFjwO+y0/T7GFpNgNAvEcPPVfyT8rrPQ==",
"devOptional": true, "devOptional": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"esbuild": "~0.25.0", "esbuild": "~0.25.0",
"get-tsconfig": "^4.7.5" "get-tsconfig": "^4.7.5"
@@ -16082,7 +16128,6 @@
"integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
"devOptional": true, "devOptional": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"peer": true,
"bin": { "bin": {
"tsc": "bin/tsc", "tsc": "bin/tsc",
"tsserver": "bin/tsserver" "tsserver": "bin/tsserver"
@@ -16241,6 +16286,16 @@
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/utils-merge": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
"integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
"license": "MIT",
"peer": true,
"engines": {
"node": ">= 0.4.0"
}
},
"node_modules/uuid": { "node_modules/uuid": {
"version": "9.0.1", "version": "9.0.1",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
@@ -16291,7 +16346,6 @@
"resolved": "https://registry.npmjs.org/vite/-/vite-7.2.2.tgz", "resolved": "https://registry.npmjs.org/vite/-/vite-7.2.2.tgz",
"integrity": "sha512-BxAKBWmIbrDgrokdGZH1IgkIk/5mMHDreLDmCJ0qpyJaAteP8NvMhkwr/ZCQNqNH97bw/dANTE9PDzqwJghfMQ==", "integrity": "sha512-BxAKBWmIbrDgrokdGZH1IgkIk/5mMHDreLDmCJ0qpyJaAteP8NvMhkwr/ZCQNqNH97bw/dANTE9PDzqwJghfMQ==",
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"esbuild": "^0.25.0", "esbuild": "^0.25.0",
"fdir": "^6.5.0", "fdir": "^6.5.0",
@@ -16405,7 +16459,6 @@
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
"license": "MIT", "license": "MIT",
"peer": true,
"engines": { "engines": {
"node": ">=12" "node": ">=12"
}, },
@@ -16418,7 +16471,6 @@
"resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.4.tgz", "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.4.tgz",
"integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==", "integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==",
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"@types/chai": "^5.2.2", "@types/chai": "^5.2.2",
"@vitest/expect": "3.2.4", "@vitest/expect": "3.2.4",
@@ -17063,7 +17115,6 @@
"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
"integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
"license": "MIT", "license": "MIT",
"peer": true,
"funding": { "funding": {
"url": "https://github.com/sponsors/colinhacks" "url": "https://github.com/sponsors/colinhacks"
} }
@@ -17079,7 +17130,7 @@
}, },
"packages/a2a-server": { "packages/a2a-server": {
"name": "@google/gemini-cli-a2a-server", "name": "@google/gemini-cli-a2a-server",
"version": "0.30.0-nightly.20260210.a2174751d", "version": "0.33.0-nightly.20260228.1ca5c05d0",
"dependencies": { "dependencies": {
"@a2a-js/sdk": "^0.3.8", "@a2a-js/sdk": "^0.3.8",
"@google-cloud/storage": "^7.16.0", "@google-cloud/storage": "^7.16.0",
@@ -17137,7 +17188,7 @@
}, },
"packages/cli": { "packages/cli": {
"name": "@google/gemini-cli", "name": "@google/gemini-cli",
"version": "0.30.0-nightly.20260210.a2174751d", "version": "0.33.0-nightly.20260228.1ca5c05d0",
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"@agentclientprotocol/sdk": "^0.12.0", "@agentclientprotocol/sdk": "^0.12.0",
@@ -17220,7 +17271,7 @@
}, },
"packages/core": { "packages/core": {
"name": "@google/gemini-cli-core", "name": "@google/gemini-cli-core",
"version": "0.30.0-nightly.20260210.a2174751d", "version": "0.33.0-nightly.20260228.1ca5c05d0",
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"@a2a-js/sdk": "^0.3.8", "@a2a-js/sdk": "^0.3.8",
@@ -17463,7 +17514,6 @@
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
"license": "MIT", "license": "MIT",
"peer": true,
"engines": { "engines": {
"node": ">=12" "node": ">=12"
}, },
@@ -17486,7 +17536,7 @@
}, },
"packages/devtools": { "packages/devtools": {
"name": "@google/gemini-cli-devtools", "name": "@google/gemini-cli-devtools",
"version": "0.30.0-nightly.20260210.a2174751d", "version": "0.33.0-nightly.20260228.1ca5c05d0",
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"ws": "^8.16.0" "ws": "^8.16.0"
@@ -17501,7 +17551,7 @@
}, },
"packages/sdk": { "packages/sdk": {
"name": "@google/gemini-cli-sdk", "name": "@google/gemini-cli-sdk",
"version": "0.29.0-nightly.20260203.71f46f116", "version": "0.33.0-nightly.20260228.1ca5c05d0",
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"@google/gemini-cli-core": "file:../core", "@google/gemini-cli-core": "file:../core",
@@ -17518,7 +17568,7 @@
}, },
"packages/test-utils": { "packages/test-utils": {
"name": "@google/gemini-cli-test-utils", "name": "@google/gemini-cli-test-utils",
"version": "0.30.0-nightly.20260210.a2174751d", "version": "0.33.0-nightly.20260228.1ca5c05d0",
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"@google/gemini-cli-core": "file:../core", "@google/gemini-cli-core": "file:../core",
@@ -17535,7 +17585,7 @@
}, },
"packages/vscode-ide-companion": { "packages/vscode-ide-companion": {
"name": "gemini-cli-vscode-ide-companion", "name": "gemini-cli-vscode-ide-companion",
"version": "0.30.0-nightly.20260210.a2174751d", "version": "0.33.0-nightly.20260228.1ca5c05d0",
"license": "LICENSE", "license": "LICENSE",
"dependencies": { "dependencies": {
"@modelcontextprotocol/sdk": "^1.23.0", "@modelcontextprotocol/sdk": "^1.23.0",
+6 -4
View File
@@ -1,6 +1,6 @@
{ {
"name": "@google/gemini-cli", "name": "@google/gemini-cli",
"version": "0.30.0-nightly.20260210.a2174751d", "version": "0.33.0-nightly.20260228.1ca5c05d0",
"engines": { "engines": {
"node": ">=20.0.0" "node": ">=20.0.0"
}, },
@@ -14,7 +14,7 @@
"url": "git+https://github.com/google-gemini/gemini-cli.git" "url": "git+https://github.com/google-gemini/gemini-cli.git"
}, },
"config": { "config": {
"sandboxImageUri": "us-docker.pkg.dev/gemini-code-dev/gemini-cli/sandbox:0.30.0-nightly.20260210.a2174751d" "sandboxImageUri": "us-docker.pkg.dev/gemini-code-dev/gemini-cli/sandbox:0.33.0-nightly.20260228.1ca5c05d0"
}, },
"scripts": { "scripts": {
"start": "cross-env NODE_ENV=development node scripts/start.js", "start": "cross-env NODE_ENV=development node scripts/start.js",
@@ -37,10 +37,12 @@
"build:all": "npm run build && npm run build:sandbox && npm run build:vscode", "build:all": "npm run build && npm run build:sandbox && npm run build:vscode",
"build:packages": "npm run build --workspaces", "build:packages": "npm run build --workspaces",
"build:sandbox": "node scripts/build_sandbox.js", "build:sandbox": "node scripts/build_sandbox.js",
"build:binary": "node scripts/build_binary.js",
"bundle": "npm run generate && npm run build --workspace=@google/gemini-cli-devtools && node esbuild.config.js && node scripts/copy_bundle_assets.js", "bundle": "npm run generate && npm run build --workspace=@google/gemini-cli-devtools && node esbuild.config.js && node scripts/copy_bundle_assets.js",
"test": "npm run test --workspaces --if-present", "test": "npm run test --workspaces --if-present && npm run test:sea-launch",
"test:ci": "npm run test:ci --workspaces --if-present && npm run test:scripts", "test:ci": "npm run test:ci --workspaces --if-present && npm run test:scripts && npm run test:sea-launch",
"test:scripts": "vitest run --config ./scripts/tests/vitest.config.ts", "test:scripts": "vitest run --config ./scripts/tests/vitest.config.ts",
"test:sea-launch": "vitest run sea/sea-launch.test.js",
"test:always_passing_evals": "vitest run --config evals/vitest.config.ts", "test:always_passing_evals": "vitest run --config evals/vitest.config.ts",
"test:all_evals": "cross-env RUN_EVALS=1 vitest run --config evals/vitest.config.ts", "test:all_evals": "cross-env RUN_EVALS=1 vitest run --config evals/vitest.config.ts",
"test:e2e": "cross-env VERBOSE=true KEEP_OUTPUT=true npm run test:integration:sandbox:none", "test:e2e": "cross-env VERBOSE=true KEEP_OUTPUT=true npm run test:integration:sandbox:none",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@google/gemini-cli-a2a-server", "name": "@google/gemini-cli-a2a-server",
"version": "0.30.0-nightly.20260210.a2174751d", "version": "0.33.0-nightly.20260228.1ca5c05d0",
"description": "Gemini CLI A2A Server", "description": "Gemini CLI A2A Server",
"repository": { "repository": {
"type": "git", "type": "git",
+5 -6
View File
@@ -12,23 +12,22 @@ import type {
RequestContext, RequestContext,
ExecutionEventBus, ExecutionEventBus,
} from '@a2a-js/sdk/server'; } from '@a2a-js/sdk/server';
import type { ToolCallRequestInfo, Config } from '@google/gemini-cli-core';
import { import {
GeminiEventType, GeminiEventType,
SimpleExtensionLoader, SimpleExtensionLoader,
type ToolCallRequestInfo,
type Config,
} from '@google/gemini-cli-core'; } from '@google/gemini-cli-core';
import { v4 as uuidv4 } from 'uuid'; import { v4 as uuidv4 } from 'uuid';
import { logger } from '../utils/logger.js'; import { logger } from '../utils/logger.js';
import type {
StateChange,
AgentSettings,
PersistedStateMetadata,
} from '../types.js';
import { import {
CoderAgentEvent, CoderAgentEvent,
getPersistedState, getPersistedState,
setPersistedState, setPersistedState,
type StateChange,
type AgentSettings,
type PersistedStateMetadata,
getContextIdFromMetadata, getContextIdFromMetadata,
getAgentSettingsFromMetadata, getAgentSettingsFromMetadata,
} from '../types.js'; } from '../types.js';
+5 -7
View File
@@ -14,17 +14,15 @@ import {
type Mock, type Mock,
} from 'vitest'; } from 'vitest';
import { Task } from './task.js'; import { Task } from './task.js';
import type {
ToolCall,
Config,
ToolCallRequestInfo,
GitService,
CompletedToolCall,
} from '@google/gemini-cli-core';
import { import {
GeminiEventType, GeminiEventType,
ApprovalMode, ApprovalMode,
ToolConfirmationOutcome, ToolConfirmationOutcome,
type Config,
type ToolCallRequestInfo,
type GitService,
type CompletedToolCall,
type ToolCall,
} from '@google/gemini-cli-core'; } from '@google/gemini-cli-core';
import { createMockConfig } from '../utils/testing_utils.js'; import { createMockConfig } from '../utils/testing_utils.js';
import type { ExecutionEventBus, RequestContext } from '@a2a-js/sdk/server'; import type { ExecutionEventBus, RequestContext } from '@a2a-js/sdk/server';
+19 -13
View File
@@ -27,11 +27,15 @@ import {
type ToolCallConfirmationDetails, type ToolCallConfirmationDetails,
type Config, type Config,
type UserTierId, type UserTierId,
type AnsiOutput, type ToolLiveOutput,
isSubagentProgress,
EDIT_TOOL_NAMES, EDIT_TOOL_NAMES,
processRestorableToolCalls, processRestorableToolCalls,
} from '@google/gemini-cli-core'; } from '@google/gemini-cli-core';
import type { RequestContext, ExecutionEventBus } from '@a2a-js/sdk/server'; import {
type ExecutionEventBus,
type RequestContext,
} from '@a2a-js/sdk/server';
import type { import type {
TaskStatusUpdateEvent, TaskStatusUpdateEvent,
TaskArtifactUpdateEvent, TaskArtifactUpdateEvent,
@@ -44,16 +48,16 @@ import { v4 as uuidv4 } from 'uuid';
import { logger } from '../utils/logger.js'; import { logger } from '../utils/logger.js';
import * as fs from 'node:fs/promises'; import * as fs from 'node:fs/promises';
import * as path from 'node:path'; import * as path from 'node:path';
import { CoderAgentEvent } from '../types.js'; import {
import type { CoderAgentEvent,
CoderAgentMessage, type CoderAgentMessage,
StateChange, type StateChange,
ToolCallUpdate, type ToolCallUpdate,
TextContent, type TextContent,
TaskMetadata, type TaskMetadata,
Thought, type Thought,
ThoughtSummary, type ThoughtSummary,
Citation, type Citation,
} from '../types.js'; } from '../types.js';
import type { PartUnion, Part as genAiPart } from '@google/genai'; import type { PartUnion, Part as genAiPart } from '@google/genai';
@@ -333,11 +337,13 @@ export class Task {
private _schedulerOutputUpdate( private _schedulerOutputUpdate(
toolCallId: string, toolCallId: string,
outputChunk: string | AnsiOutput, outputChunk: ToolLiveOutput,
): void { ): void {
let outputAsText: string; let outputAsText: string;
if (typeof outputChunk === 'string') { if (typeof outputChunk === 'string') {
outputAsText = outputChunk; outputAsText = outputChunk;
} else if (isSubagentProgress(outputChunk)) {
outputAsText = JSON.stringify(outputChunk);
} else { } else {
outputAsText = outputChunk outputAsText = outputChunk
.map((line) => line.map((token) => token.text).join('')) .map((line) => line.map((token) => token.text).join(''))
@@ -6,7 +6,11 @@
import { describe, it, expect, vi, beforeEach } from 'vitest'; import { describe, it, expect, vi, beforeEach } from 'vitest';
import { InitCommand } from './init.js'; import { InitCommand } from './init.js';
import { performInit } from '@google/gemini-cli-core'; import {
performInit,
type CommandActionReturn,
type Config,
} from '@google/gemini-cli-core';
import * as fs from 'node:fs'; import * as fs from 'node:fs';
import * as path from 'node:path'; import * as path from 'node:path';
import { CoderAgentExecutor } from '../agent/executor.js'; import { CoderAgentExecutor } from '../agent/executor.js';
@@ -14,7 +18,6 @@ import { CoderAgentEvent } from '../types.js';
import type { ExecutionEventBus } from '@a2a-js/sdk/server'; import type { ExecutionEventBus } from '@a2a-js/sdk/server';
import { createMockConfig } from '../utils/testing_utils.js'; import { createMockConfig } from '../utils/testing_utils.js';
import type { CommandContext } from './types.js'; import type { CommandContext } from './types.js';
import type { CommandActionReturn, Config } from '@google/gemini-cli-core';
import { logger } from '../utils/logger.js'; import { logger } from '../utils/logger.js';
vi.mock('@google/gemini-cli-core', async (importOriginal) => { vi.mock('@google/gemini-cli-core', async (importOriginal) => {
@@ -9,6 +9,9 @@ import {
listMemoryFiles, listMemoryFiles,
refreshMemory, refreshMemory,
showMemory, showMemory,
type AnyDeclarativeTool,
type Config,
type ToolRegistry,
} from '@google/gemini-cli-core'; } from '@google/gemini-cli-core';
import { beforeEach, describe, expect, it, vi } from 'vitest'; import { beforeEach, describe, expect, it, vi } from 'vitest';
import { import {
@@ -19,11 +22,6 @@ import {
ShowMemoryCommand, ShowMemoryCommand,
} from './memory.js'; } from './memory.js';
import type { CommandContext } from './types.js'; import type { CommandContext } from './types.js';
import type {
AnyDeclarativeTool,
Config,
ToolRegistry,
} from '@google/gemini-cli-core';
// Mock the core functions // Mock the core functions
vi.mock('@google/gemini-cli-core', async (importOriginal) => { vi.mock('@google/gemini-cli-core', async (importOriginal) => {
@@ -28,6 +28,7 @@ vi.mock('@google/gemini-cli-core', async (importOriginal) => {
const mockConfig = { const mockConfig = {
...params, ...params,
initialize: vi.fn(), initialize: vi.fn(),
waitForMcpInit: vi.fn(),
refreshAuth: vi.fn(), refreshAuth: vi.fn(),
getExperiments: vi.fn().mockReturnValue({ getExperiments: vi.fn().mockReturnValue({
flags: { flags: {
@@ -94,6 +95,7 @@ describe('loadConfig', () => {
const mockConfig = { const mockConfig = {
...(params as object), ...(params as object),
initialize: vi.fn(), initialize: vi.fn(),
waitForMcpInit: vi.fn(),
refreshAuth: vi.fn(), refreshAuth: vi.fn(),
getExperiments: vi.fn().mockReturnValue({ getExperiments: vi.fn().mockReturnValue({
flags: { flags: {
+5 -5
View File
@@ -8,11 +8,6 @@ import * as fs from 'node:fs';
import * as path from 'node:path'; import * as path from 'node:path';
import * as dotenv from 'dotenv'; import * as dotenv from 'dotenv';
import type {
TelemetryTarget,
ConfigParameters,
ExtensionLoader,
} from '@google/gemini-cli-core';
import { import {
AuthType, AuthType,
Config, Config,
@@ -28,6 +23,9 @@ import {
fetchAdminControlsOnce, fetchAdminControlsOnce,
getCodeAssistServer, getCodeAssistServer,
ExperimentFlags, ExperimentFlags,
type TelemetryTarget,
type ConfigParameters,
type ExtensionLoader,
} from '@google/gemini-cli-core'; } from '@google/gemini-cli-core';
import { logger } from '../utils/logger.js'; import { logger } from '../utils/logger.js';
@@ -168,6 +166,8 @@ export async function loadConfig(
// Needed to initialize ToolRegistry, and git checkpointing if enabled // Needed to initialize ToolRegistry, and git checkpointing if enabled
await config.initialize(); await config.initialize();
await config.waitForMcpInit();
startupProfiler.flush(config); startupProfiler.flush(config);
await refreshAuthentication(config, adcFilePath, 'Config'); await refreshAuthentication(config, adcFilePath, 'Config');

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