
Gemini
- Updated April 15, 2026
- josephyaduvanshi/gemini-companion
gemini is a Claude Code skill in the AI & Agent Building category. Use Gemini CLI from Claude Code to delegate investigation, implementation, and review tasks.
Key points
- gemini
- AI & Agent Building
- AI-coding skill
Gemini by the numbers
- Data as of Jul 7, 2026 (Skillselion catalog sync)
/plugin marketplace add josephyaduvanshi/gemini-companion/plugin install gemini@gemini-companionAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Last updated | April 15, 2026 |
|---|---|
| Repository | josephyaduvanshi/gemini-companion ↗ |
What it does
Use Gemini CLI from Claude Code to delegate investigation, implementation, and review tasks.
README.md
gemini-companion
Delegate rescues and code reviews to Gemini CLI from inside Claude Code.
One CLI talking to another. No broker, no protocol dance, no magic.
If this saves you an afternoon, star the repo ⭐
/gemini:setup
/gemini:rescue investigate why the auth middleware drops cookies on logout
/gemini:review
That's the whole thing. You type a slash command, Claude hands the work over to Gemini CLI, and you get Gemini's answer back without Claude paraphrasing it.
Table of Contents
- What you get
- Why this exists
- Requirements
- Install
- Usage
- Typical flows
- Feature parity with codex-plugin-cc
- The --effort flag (how it actually works)
- Gemini integration
- State layout
- Skills that ship with the plugin
- Environment variables
- Development
- FAQ
- Attribution
- License
What you get
/gemini:review— a read-only code review. The plugin collects git status/diff/changed files locally, then runs Gemini in--approval-mode planso it physically cannot edit your workspace/gemini:adversarial-review— a steerable review with structured JSON findings/gemini:rescue— hand any task off to Gemini through a thin subagent/gemini:status,/gemini:result,/gemini:cancel— manage background jobs without leaving Claude/gemini:setup— health check the runtime and toggle the optional stop-time review gate
Everything is Gemini doing the work. This plugin just makes sure the output comes back to you clean, the state is persisted, and cancellation actually cancels.
Why this exists
I wanted codex-plugin-cc's workflow but pointed at Google's Gemini CLI.
There's an existing community Gemini plugin for Claude Code built on top of Gemini's experimental ACP (Agent Client Protocol) mode. I tried it, ran into bugs, and decided to go a different way.
Gemini CLI's --output-format stream-json turned out to be a clean, flat event stream: an init with session id + model, then message events (user / assistant, with a delta: true flag for partials), tool_use / tool_result events, and a final result envelope carrying stats and exit status. That made the port easy. It's also way easier to debug than ACP: every event is a newline of JSON, so I can tail -f and pipe through jq while things are misbehaving.
The tradeoff is that every task spawns a fresh gemini process instead of reusing a persistent one. Cold start is 0.5 to 2 seconds. That's invisible for rescue and review workflows and I am not going to over-engineer a broker to save a second per call.
Requirements
- Node.js 18.18 or later
- Gemini CLI 0.37+ installed globally (
npm install -g @google/gemini-cli) - An auth method, one of:
- OAuth (free tier) — run
geminionce interactively and complete the Google sign-in flow. Credentials land in~/.gemini/oauth_creds.json. GEMINI_API_KEY— a Gemini API key exported in your shell (or written to~/.gemini/settings.json).- Vertex AI — set
GOOGLE_APPLICATION_CREDENTIALSor rungcloud auth application-default login.
- OAuth (free tier) — run
- Claude Code (obviously)
/gemini:setup walks you through whatever's missing.
Install
Add the marketplace in Claude Code:
/plugin marketplace add josephyaduvanshi/gemini-companion
Install the plugin:
/plugin install gemini@gemini-companion
Reload plugins:
/reload-plugins
Then run:
/gemini:setup
If Gemini CLI isn't installed and npm is, /gemini:setup offers to install it for you. Otherwise, install it yourself:
npm install -g @google/gemini-cli
gemini # run once interactively to complete OAuth (or export GEMINI_API_KEY)
After install you should see:
- the
/gemini:*slash commands listed in your Claude Code session - the
gemini:gemini-rescuesubagent in/agents
A good first run is:
/gemini:review --background
/gemini:status
/gemini:result
Usage
/gemini:setup
Runs a health check. Reports node + npm + gemini versions, auth state, the default model, session runtime, and whether the stop-time review gate is on for this repo.
/gemini:setup
/gemini:setup --enable-review-gate # turn on the Stop hook
/gemini:setup --disable-review-gate # turn it back off
[!NOTE] If Gemini isn't installed and
npmis, setup offers to install it for you. If it's installed but not authenticated, setup tells you exactly which env var or auth command to run.
/gemini:rescue
The "hand something off to Gemini" command. Routes through the gemini:gemini-rescue subagent, which calls the companion once and gives you Gemini's answer verbatim — no rewriting, no follow-up.
Use it when you want Gemini to:
- investigate a bug
- try a fix
- take a faster pass with a smaller model (
flash) - continue a previous Gemini session
Examples:
/gemini:rescue investigate why the tests started failing
/gemini:rescue fix the failing test with the smallest safe patch
/gemini:rescue --resume apply the top fix from the last run
/gemini:rescue --model pro --effort high investigate the flaky integration test
/gemini:rescue --model flash fix the issue quickly
/gemini:rescue --background investigate the regression
You can also just ask Claude to hand it off in plain English:
Ask gemini to redesign the database connection to be more resilient.
Claude will pick up the cue and route through the subagent.
Flags at a glance:
--background— kick it off, return a job id--wait— run in the foreground (default)--model <alias>—pro,flash,flash-lite, or any model string your gemini install knows--effort <level>—none,minimal,low,medium,high,xhigh(details below)--resume/--fresh— continue the latest Gemini session for this repo, or start a new one--include-dirs <path>[,<path>...]— expand Gemini's write sandbox beyondcwd
[!WARNING] Writing outside the workspace needs
--include-dirs. Gemini CLI sandboxeswrite_fileto the workspacecwd, even in--approval-mode yolo. If you ask Gemini to write/tmp/foo.mdwhile running from/home/me/project, Gemini silently redirects the write to~/.gemini/tmp/<workspace>/foo.mdand the file never appears at the requested path. Pass--include-dirs <parent>to expand the sandbox. Example:/gemini:rescue --include-dirs /tmp,/Users/me/output draft a research doc at /tmp/research.mdThe
gemini-rescuesubagent also tries to detect outside-of-cwd paths in your request and add--include-dirsautomatically — but relying on that is not as reliable as being explicit.
[!NOTE] Rescues can take a while depending on the model and the task. If the job looks open-ended, prefer
--backgroundand check back with/gemini:status.
/gemini:review
Runs a code review on your current changes. Unlike qwen-companion (which delegates to qwen's built-in /review), Gemini CLI has no native /review command — so the plugin does the work locally. It detects git scope, runs git status / diff / log with runCommand (argv, no shell), reads changed files under a size budget, and passes the collected context to Gemini as a prompt. Gemini runs in --approval-mode plan (read-only, no shell, no writes), produces a Markdown review, and the plugin hands you the output.
This matters for trust: /gemini:review is read-only by enforcement, not by prompt wording. Gemini physically cannot edit your workspace during a review.
Use it when you want:
- a review of your current uncommitted changes
- a review of your branch compared to a base branch like
main
/gemini:review
/gemini:review --base main
/gemini:review --background
[!NOTE] This command is read-only. It does not take custom focus text. Use
/gemini:adversarial-reviewif you want to steer the review toward a specific risk area.
/gemini:adversarial-review
Runs a steerable review that challenges the implementation and design, not just the code details.
Same git context as /gemini:review, different prompt. This one loads the adversarial review template from plugins/gemini/prompts/adversarial-review.md, enforces the schema in plugins/gemini/schemas/review-output.schema.json, and parses Gemini's reply. Findings come back sorted by severity (critical → high → medium → low) with file:line ranges and concrete fix suggestions.
Use it when you want:
- a pre-ship review that questions the direction, not just the code
- pressure-testing around specific risks like auth, data loss, race conditions, rollback safety
- focus-directed review — anything you type after the flags is forwarded as focus instructions
/gemini:adversarial-review
/gemini:adversarial-review --base main challenge the caching and retry design
/gemini:adversarial-review --background look for race conditions around cache invalidation
[!WARNING] After an adversarial review, Claude will present findings and stop. It will not auto-fix anything. You have to pick which findings to act on and explicitly ask Claude to fix them. That's intentional.
/gemini:status
Shows running and recent Gemini jobs for this repository, scoped to the current Claude Code session.
/gemini:status # compact table of current + recent jobs
/gemini:status task-abc123 # full record for one job
/gemini:status task-abc123 --wait # block until the job finishes
/gemini:status --all # include jobs from other sessions
Use it to check background progress, see the latest completed job, or confirm whether a task is still running.
/gemini:result
Shows the stored final output for a finished job. Ends with a gemini --resume <session_id> footer you can paste into a terminal to keep the conversation going outside of Claude Code.
/gemini:result # latest finished job in this session
/gemini:result task-abc123 # a specific job
/gemini:cancel
Cancels an active Gemini job. Gracefully. It sends SIGINT first and waits 2 seconds — in practice this is the only signal that ever actually fires. If gemini is still alive, it gets SIGTERM, another 2 seconds, then SIGKILL.
/gemini:cancel # cancel the only active job in this session
/gemini:cancel task-abc123 # cancel a specific job
Signals target the whole process group because workers are spawned with detached: true, so kill(-pid) reaches every child. The job log records exactly which signal fired and whether the process exited gracefully.
Typical flows
Review before shipping
/gemini:review
Hand a problem to Gemini
/gemini:rescue investigate why the build is failing in CI
Start something long-running
/gemini:adversarial-review --background
/gemini:rescue --background investigate the flaky test
Then check in with:
/gemini:status
/gemini:result
Continue a Gemini session you started in a terminal
# Outside Claude Code:
gemini -p "Plan the cache invalidation refactor"
# Later, inside Claude Code:
/gemini:rescue --resume apply the plan you just made
The plugin scans ~/.gemini/tmp/<bucket>/chats/session-*.json and finds the most recent session for this repo, whether or not it was started through the plugin. Gemini auto-records every session, so there is nothing to flip on.
Feature parity with codex-plugin-cc
Everything from openai/codex-plugin-cc v1.0.3 is here. This table is the full map.
| Feature | codex-plugin-cc | gemini-companion |
|---|---|---|
/setup with review-gate toggle |
✅ | ✅ |
/rescue with --model, --effort, --resume, --fresh, --write, --background, --wait |
✅ | ✅ |
/review |
✅ via review/start JSON-RPC (structured) |
✅ via local git context collection + Gemini in --approval-mode plan (read-only by enforcement) |
/adversarial-review |
✅ with JSON schema | ✅ same schema, enforced via a temp settings + prompt addendum |
/status, /result, /cancel |
✅ | ✅ |
--effort none..xhigh |
GPT-5.4 reasoning budget | tool-call budget via maxSessionTurns (temp settings.json + GEMINI_CLI_SYSTEM_SETTINGS_PATH) plus a system-prompt directive |
| Model aliases | ✅ | ✅ — pro, flash, flash-lite (anything else passes through) |
--background worker |
✅ | ✅ detached subprocess, same job lifecycle |
--resume-last / --fresh |
✅ | ✅ via gemini --resume <id> (gemini auto-records every session) |
| Resume picks up out-of-plugin sessions | ✅ (shared thread store) | ✅ scans ~/.gemini/tmp/<bucket>/chats/session-*.json |
| Graceful cancel | ✅ turn/interrupt RPC |
✅ two-phase SIGINT, SIGTERM, SIGKILL with 2-second grace periods |
| Stop-time review gate | ✅ | ✅ |
| SessionStart / SessionEnd hook | ✅ | ✅ |
| Touched-files tracking | ✅ from protocol | ✅ from gemini tool_use events (write_file, replace, edit) |
scripts/bump-version.mjs |
✅ | ✅ |
| CI workflow | ✅ | ✅ .github/workflows/pull-request-ci.yml — test on Node 18/20/22 × Ubuntu/macOS |
| Shared app-server broker | ✅ | ❌ intentional. Gemini has no persistent server mode. Per-task spawn is fine for rescue/review workflows. I'll adopt if upstream gemini adds one. |
The --effort flag (how it actually works)
Gemini has no native reasoning-budget dial, so I built the next-best thing: --effort caps the actual tool-call budget via Gemini's maxSessionTurns setting and adds a reasoning-depth hint to the prompt.
Gemini has no --append-system-prompt flag and GEMINI_SYSTEM_MD is a full override of the built-in system prompt — so the adapter does two things per turn:
- Writes a one-shot
settings.jsonwith the appropriatemaxSessionTurnsand points Gemini at it throughGEMINI_CLI_SYSTEM_SETTINGS_PATH. - Prepends a short addendum (effort directive + optional output schema reminder) to the user prompt with a clear separator.
| Level | maxSessionTurns |
System-prompt addendum |
|---|---|---|
none |
1 | "Do not use reasoning. Reply directly without deliberation." |
minimal |
2 | "Use minimal reasoning. Be terse and decisive." |
low |
4 | "Think briefly before answering." |
medium |
(unbounded, default) | (none) |
high |
(unbounded) | "Think carefully and consider multiple angles before answering." |
xhigh |
(unbounded) | "Think very carefully. Consider edge cases, alternative approaches, and potential pitfalls." |
none through low are real hard caps. Gemini cannot sneak extra tool rounds past them. high and xhigh are hints — there's no way to force gemini to think more if it doesn't want to.
Gemini integration
The plugin uses the global gemini binary installed in your environment and picks up the same ~/.gemini/settings.json configuration you'd get from running gemini directly.
Common configurations
If you want to change the default model, edit ~/.gemini/settings.json:
{
"model": { "name": "gemini-2.5-pro" }
}
The plugin reads model.name (and the v0.37-era defaultModel alias) and surfaces it in /gemini:setup. Per-task --model overrides always win.
Moving the work over to Gemini
Every /gemini:result output ends with a footer like:
Gemini session ID: 8a205db3-affe-4e9f-b7d5-a5ade53473e6
Resume in Gemini: gemini --resume 8a205db3-affe-4e9f-b7d5-a5ade53473e6
Paste that into a terminal to keep working in Gemini directly, with full chat history intact.
State layout
The companion writes state under $CLAUDE_PLUGIN_DATA/state/<slug>-<hash>/ when running inside Claude Code, or under $TMPDIR/gemini-companion/<slug>-<hash>/ otherwise:
state.json config + jobs index
jobs/
task-<id>.json full job record: request, payload, rendered output
task-<id>.log timestamped progress log
Jobs are scoped to a Claude session via GEMINI_COMPANION_SESSION_ID, which the SessionStart hook exports. When a session ends, any queued or running jobs for that session are torn down. The state file is capped at 50 jobs per workspace — older ones are pruned automatically.
Skills that ship with the plugin
All three are marked user-invocable: false because they exist to guide Claude, not to be slash commands you type:
gemini-cli-runtime— the one-Bash-call contract the rescue subagent follows. Exists so Claude doesn't drift into reading files or drafting plans when the whole point is to delegate.gemini-result-handling— how to present Gemini's output. The important rule: after a review, stop. Don't auto-fix findings. Ask.gemini-prompting— a short guide to writing good Gemini prompts using XML block tags like<task>,<structured_output_contract>,<verification_loop>,<grounding_rules>, and<action_safety>.
Environment variables
| Variable | What it does |
|---|---|
CLAUDE_PLUGIN_DATA |
Parent directory for plugin state. Claude Code sets this automatically. |
GEMINI_COMPANION_SESSION_ID |
Exported by the SessionStart hook so jobs can be scoped per Claude session. |
GEMINI_BIN |
Override the gemini binary path. Used by the test fixture to point at a fake gemini. |
GEMINI_API_KEY |
Gemini API key auth (alternative to OAuth). Read by the gemini CLI directly. |
GEMINI_CLI_SYSTEM_SETTINGS_PATH |
Set by the companion on each turn to inject the per-run maxSessionTurns budget. Do not set manually. |
Development
git clone https://github.com/josephyaduvanshi/gemini-companion.git
cd gemini-companion
node --test tests/*.test.mjs
Tests run against either the library modules directly or the runtime via a fake gemini fixture (tests/fake-gemini-fixture.mjs). The fake gemini is a tiny Node script that prints a canned stream-json transcript, which lets runGeminiTurn() run in CI without the real CLI installed.
Useful dev commands
# bump all three manifests to a new version
node scripts/bump-version.mjs 1.0.1
# verify all three manifests agree with package.json
node scripts/bump-version.mjs --check
# run just one test file
node --test tests/runtime.test.mjs
CI
The CI workflow lives at .github/workflows/pull-request-ci.yml. It runs the test suite on Node 18, 20, and 22 across Ubuntu and macOS, syntax-checks every .mjs file, and validates the JSON manifests on every PR and push to main.
Repo layout
gemini-companion/
├── .claude-plugin/
│ └── marketplace.json ← Claude Code marketplace entry
├── plugins/
│ └── gemini/
│ ├── .claude-plugin/plugin.json
│ ├── agents/gemini-rescue.md
│ ├── commands/ ← slash command definitions
│ ├── hooks/hooks.json ← SessionStart/End + Stop gate
│ ├── prompts/ ← adversarial-review + stop-review-gate templates
│ ├── schemas/ ← review-output.schema.json
│ ├── scripts/
│ │ ├── gemini-companion.mjs ← subcommand router
│ │ ├── session-lifecycle-hook.mjs
│ │ ├── stop-review-gate-hook.mjs
│ │ └── lib/ ← state, render, git, gemini adapter…
│ └── skills/ ← gemini-cli-runtime, gemini-result-handling, gemini-prompting
├── scripts/bump-version.mjs
├── tests/ ← test suite
└── .github/workflows/
FAQ
Do I need a separate Gemini account for this plugin?
No. If you're already signed into Gemini CLI on this machine, the plugin picks up your existing auth automatically. The plugin uses your local Gemini CLI authentication, not its own.
Does the plugin use a separate Gemini runtime?
No. It delegates through your local Gemini CLI on the same machine. That means:
- same gemini install you'd use directly
- same local auth state
- same
~/.gemini/settings.jsonconfig - same repository checkout and environment
Will it use the same Gemini config I already have?
Yes. The plugin reads ~/.gemini/settings.json for the default model, auth type, and environment variables. Per-task --model overrides always win.
Can I still use gemini --resume directly in my terminal?
Yes. Gemini auto-records every session to ~/.gemini/tmp/<bucket>/chats/. Copy the session ID out of /gemini:result and paste it into gemini --resume <id> whenever you want.
Why not ACP mode like the other gemini plugin?
I tried it, I couldn't get it working reliably, and the stream-json path turned out to be easier to port and easier to debug. See Why this exists.
Why is there no shared broker like codex has?
Gemini CLI doesn't ship a persistent app-server subcommand. Stream-json input mode exists but the process exits after a single completed turn, so a real broker would need either a new gemini mode or a fragile ACP implementation. Neither seemed worth it for the 0.5–2s cold start cost I'd save per task. If upstream gemini adds a persistent server mode, I'll adopt it.
Can I use this with other gemini-compatible CLIs?
Anything that speaks Gemini CLI's --output-format stream-json protocol and respects --approval-mode, --resume, and the GEMINI_CLI_SYSTEM_SETTINGS_PATH env var should work. Point the GEMINI_BIN env var at it.
Attribution
This plugin is derived from openai/codex-plugin-cc, Copyright 2025 OpenAI, Apache-2.0. A lot of the state model, job tracking, rendering, command layout, skill design, and test harness are direct ports.
The CLI adapter in plugins/gemini/scripts/lib/gemini.mjs is mine. See NOTICE and LICENSE for the full terms.
License
Apache-2.0. See LICENSE.
Built by Joseph Yaduvanshi
If this saved you an afternoon, a ⭐ on the repo is the nicest thank-you.