Skip to content

feat: Gemini CLI client adapter (D4a)#120

Merged
m1ngshum merged 1 commit into
mainfrom
feat/gemini-cli-adapter
Jul 3, 2026
Merged

feat: Gemini CLI client adapter (D4a)#120
m1ngshum merged 1 commit into
mainfrom
feat/gemini-cli-adapter

Conversation

@m1ngshum

@m1ngshum m1ngshum commented Jul 3, 2026

Copy link
Copy Markdown
Member

What

Adds Gemini CLI (Google's terminal agent) as a 6th first-class client, targeting the user-global ~/.gemini/settings.json (top-level mcpServers map). This is Wave-1 item D4a from docs/ROADMAP-ADOPTION.md — the next developer-reach adapter after D1 (Claude Code, shipped v0.18.0).

It's a structural clone of the D1 pattern: a rootKey-only BaseAdapter subclass. The detector auto-enumerates CLIENT_IDS, so every client-iterating command — install, remove, list, audit, doctor, sync --check, up, guard, … — picks it up with no further wiring.

Changes

  • src/config/paths.tsgemini-cli added to the CLIENT_IDS tuple + getConfigPath case → ~/.gemini/settings.json (home-relative on all platforms, like claude-code/cursor/windsurf)
  • src/config/adapters/gemini-cli.ts — new GeminiCliAdapter (rootKey mcpServers)
  • factory.ts / index.ts — wire + export the adapter
  • completions.ts, doctor.ts, guard/cli.ts — the three hardcoded/label client lists (the exhaustiveness tripwire on Record<ClientId, string> surfaced the last two at typecheck)

Scope & caveats (honest)

  • User-global only. Per-project .gemini/settings.json is deliberately out of scope — same reasoning as D1's per-project deferral (nested shape doesn't fit the single-rootKey model).
  • URL transport: Gemini reads url as an SSE endpoint and httpUrl as HTTP; mcpm writes url. Same URL-transport caveat that already applies to every non-Cursor client.
  • Format confirmed against Google's gemini-cli docs (top-level mcpServers, ~/.gemini/settings.json).
  • Zero new deps.

Tests

  • New gemini-cli.test.ts: clientId, reads mcpServers, and the key invariant — a write preserves unrelated settings.json keys (theme, selectedAuthType, a server's extra trust field)
  • paths.test.ts: darwin/linux/win32 path resolution
  • doctor.test.ts: ALL_CLIENTS updated (the client-count invariant)
  • Full suite 1923/1923 green (FORCE_COLOR=0); typecheck + lint clean

End-to-end verification

Ran the built CLI in a throwaway HOME against a realistic ~/.gemini/settings.json:

  • doctor✓ Gemini CLI — config found, 1 server
  • disable existing --client gemini-cli → preserved theme / selectedAuthType / the server's trust field, added disabled: true, wrote .bak

Docs

CHANGELOG [Unreleased], README supported-clients table + diagram, CLAUDE.md (version line, architecture diagram, decisions log), ROADMAP-ADOPTION.md (D4a → ✅ SHIPPED).

Adds `gemini-cli` as a 6th first-class client targeting the user-global
`~/.gemini/settings.json` (top-level `mcpServers` map) — a rootKey-only
BaseAdapter subclass, a structural clone of the Claude Code adapter (D1).

The detector auto-enumerates CLIENT_IDS, so every client-iterating command
(install, remove, list, audit, doctor, sync --check, up, guard, …) picks it
up with no further wiring. Writes preserve unrelated settings.json keys
(theme, selectedAuthType, …) via the existing atomic read-modify-write + .bak.

Scope: user-global only; per-project .gemini/settings.json is out of scope
(same as D1). URL caveat: Gemini reads url=SSE / httpUrl=HTTP, mcpm writes url
— the existing non-Cursor URL-transport caveat. Zero new deps.

Verified end-to-end on the built CLI (doctor detects it; disable preserves
sibling keys) + unit tests for clientId, read, sibling-preservation, and paths.
Format confirmed against Google's gemini-cli docs.
@m1ngshum m1ngshum merged commit 2207bba into main Jul 3, 2026
8 checks passed
@m1ngshum m1ngshum deleted the feat/gemini-cli-adapter branch July 3, 2026 07:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant