CodeVetter
← All unpacks
CodeVetter · Repo Unpack evidence

google-gemini/gemini-cli

Scanned commit d5b3e3accb dated 2026-09-21 — last upstream commit. Generated by codevetter 1.12.0 on 2026-09-22.

github.com/google-gemini/gemini-cli ↗ · 2974 files · 25.0 MB

Gemini CLI Gemini CLI is an open-source AI agent that brings the power of Gemini directly into your terminal.

Deep analysis by swe-2 via the devin CLI on 2026-09-22 (runtime not recorded) — every claim below links to its cited source files.

Overview

Gemini CLI is Google's open-source terminal agent for the Gemini models: an npm-workspaces monorepo whose main artifact is the `gemini` binary (packages/cli on Ink/React for the TUI, packages/core for the agent loop, tools, policy engine, MCP client, and telemetry). It runs a two-process startup (a lightweight parent that respawns a heavy child with tuned V8 flags), supports interactive and non-interactive/headless modes, an ACP stdio bridge for editors, an A2A HTTP server, an SDK package, and a VS Code companion extension. Its distinctive features are a TOML-driven policy engine gating every tool call, a hook system that can intercept agent/model/tool lifecycle events, and git-checkpointing plus JSONL session recording for rewind/resume.

System map

The repo is an npm workspaces monorepo (Node >=20, ESM, TypeScript 5.8) with the runtime split between packages/cli (Ink/React TUI, arg parsing, settings, extensions, sandboxing, ACP) and packages/core (agentic loop, tool registry, scheduler, policy engine, hooks, MCP client, telemetry). Secondary packages are a2a-server (Express A2A endpoint), sdk (programmatic sessions), vscode-ide-companion (IDE bridge), devtools (Vite React activity viewer), and test-utils. The shipped binary is produced by esbuild into bundle/gemini.js via the root `bundle` script. Runtime state lives under ~/.gemini (or GEMINI_CLI_HOME) via the Storage class; external integrations include the Gemini API / Code Assist / Vertex AI backends, arbitrary MCP servers, IDE companions over a local server, and git for worktrees/checkpointing.

Feature catalog

User-facing surface is broad: a yargs-driven CLI with subcommands (mcp, extensions, skills, hooks, gemma) plus ~45 built-in slash commands, custom TOML commands, and MCP-prompt commands. The agent can call ~20 built-in tools (file IO, shell, grep/glob/ripgrep, web fetch/search, todos, plan mode, tracker tasks, skills, subagents incl. a browser agent). Auth supports Google OAuth, Gemini API key, Vertex AI, compute ADC, and gateway modes. Features include session resume/checkpointing/rewind, GEMINI.md hierarchical memory, hooks, policies, extensions, skills, ACP editor mode, A2A server, voice mode, IDE integration, worktrees, and multiple output formats (text/json/stream-json).

All 15 feature catalog claims →

Data flow

Input enters via argv/stdin, is merged with layered settings.json files (system → user → workspace, plus remote admin controls over IPC), then Config becomes the single state owner for the session. A prompt flows through slash-command and @-file processors into Part[] arrays, into GeminiClient.sendMessageStream → Turn → GeminiChat → ContentGenerator → the Gemini/Code Assist/Vertex HTTP stream. Streamed chunks become typed events; ToolCallRequest events are drained into the Scheduler which runs policy checks, user confirmation over the MessageBus, hooks, then the ToolExecutor; tool results are appended as functionResponse parts and recorded into chat history plus the JSONL session file, looping until a Finished/Stopped event. Output exits via coreEvents.Output/TextOutput/StreamJsonFormatter or the Ink UI.

Behavior traces

Traced three flows end-to-end. (1) Startup: parent spawn → settings → args → session resolution → partial config → auth → optional sandbox relaunch → full config init → interactive Ink UI or headless loop. (2) Headless agentic turn: input normalization → hooks → GeminiClient stream → Turn/GeminiChat → tool requests → Scheduler (policy→confirm→hooks→execute) → responses fed back until Finished. (3) Session persistence/resume: JSONL transcript written per message/tool call and rehydrated via SessionSelector or imported from file.

Testing signals

Testing is heavy and layered: Vitest 3.2 with colocated *.test.ts(x) unit tests across every package (a large share of scanned TS files are tests), an integration-tests/ workspace running the real built binary (optionally under docker/podman sandbox) with recorded .responses fixtures, evals/ behavioral evals gated behind RUN_EVALS with an llm-judge, plus perf-tests/ and memory-tests/ with baseline updating. CI (ci.yml) enforces lint (eslint+actionlint+shellcheck+yamllint+prettier+sensitive-keywords+action pinning), build, typecheck, per-workspace test:ci, bundle smoke (`node ./bundle/gemini.js --version`), generated-settings-doc freshness, and lockfile checks. Husky+lint-staged run prettier/eslint on commit.

Risk map

The riskiest surfaces are the ones that execute or fetch code: ShellTool + ShellExecutionService (model-generated commands on the host, mitigated by policy/confirmation/sandbox), the sandbox relaunch path itself (exec/spawn of docker, podman, sandbox-exec), extension installation (git clone / GitHub release downloads, consent-gated), the toolDiscoveryCommand (arbitrary configured command whose stdout is parsed into tools), custom-command shell injection (!{...} processors), and the a2a-server which ships hardcoded demo credentials. Config.ts is a 4200-line god object and the two-process relaunch + ConsolePatcher/stdio interception are fragile coupling hotspots. Credential storage (OAuth via keychain/file fallback, apiKeyCredentialStorage, MCP oauth-token-storage) is sensitive file IO outside the repo.

All 13 risk map claims →

Extension points

Almost every subsystem is a plug-in point: ICommandLoader implementations feed CommandService; ToolRegistry.registerTool plus the discovery-command and MCP paths add tools; AgentRegistry loads local .md/agent definitions and remote A2A agents; the policy engine loads TOML rule dirs per tier; hooks subscribe to named lifecycle events; extensions bundle all of the above via gemini-extension.json; skills are discovered by SkillManager and activated via ActivateSkillTool; ContentGenerator is a factory interface; and the policy engine, themes, and model-config service all accept externally supplied entries.

Contributor handoff

An agent editing this repo should treat packages/core and packages/cli as separate layers (core must not import cli), keep the Config god-object edits minimal, route all tool gating through the PolicyEngine/MessageBus rather than ad-hoc checks, and always run the colocated vitest file plus typecheck before considering a change done. Build is `npm run bundle` (esbuild → bundle/gemini.js); quick dev loop is `npm run start` / `npm start -- -p '...'` after build. Conventions: ESM with .js import specifiers for .ts files, Apache license header enforced by eslint, debugLogger instead of console.*, proper-lockfile/proper JSONL append for session files. Traps: two-process relaunch means env changes need GEMINI_CLI_NO_RELAUNCH=1 to debug the real process; posttest triggers a full build; Ink is a forked package via npm overrides.

All 13 contributor handoff claims →

Languages

LanguageFilesShare of source
TypeScript217393%
Markdown170docs/config
JavaScript723%
YAML71docs/config
JSON55docs/config
Python492%
TOML241%
Shell100%

Start reading here

Probable source entrypoint: packages/ — inferred from the directory tree and manifest, not the upstream docs.

Source roots

packages/ (2329 files)

Repository structure

Top-level pathFiles
packages/2329
integration-tests/120
tools/117
docs/101
scripts/83
.github/73
evals/47
.gemini/46

Docs found: CONTRIBUTING.mdREADME.mddocs/CONTRIBUTING.mddocs/admin/enterprise-controls.mddocs/behavioral-evals.mddocs/changelogs/index.mddocs/changelogs/latest.mddocs/changelogs/preview.mddocs/cli/acp-mode.mddocs/cli/auto-memory.md

Package

package.json — @google/gemini-cli v0.62.0-nightly.20260918.g9450ade79, 58 declared dependencies.

@agentclientprotocol/sdk@modelcontextprotocol/sdk@octokit/rest@types/express@types/marked@types/mime-types@types/minimatch@types/mock-fs@types/prompts@types/proper-lockfile@types/react@types/react-dom

CI & config entrypoints

Structural health signals

Average score 6.2/10 across 96 analyzed source files; 68 hotspots surfaced.

These are deterministic review leads — size, churn, and structural signals — not proof of a bug in this project.

Recent history