Help us shape the future of Go! Take the 2026 Go Developer Survey

gemini

package
v0.16.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 7, 2026 License: MIT Imports: 17 Imported by: 0

Documentation

Overview

Package gemini implements the Gemini CLI adapter for agentsync.

Gemini CLI stores user-level configuration under ~/.gemini and project-level under <repo>/.gemini (per geminicli.com/docs). Its settings file is JSON (settings.json) and holds BOTH MCP servers (the `mcpServers` object — the same idea as Claude) and lifecycle hooks (the `hooks` object — the same nested matcher-group/hooks-array shape Claude uses), so the adapter has a single key-merge strategy (merge-jsonc-keys) and co-owns two sections of one file, exactly as Claude co-owns `hooks`/`lspServers` inside its settings.json.

The remaining components are files: memory → GEMINI.md (the hierarchical context file: `~/.gemini/GEMINI.md` at user scope, repo-root `GEMINI.md` at project scope), slash commands → `.gemini/commands/<name>.toml` (TOML with `description` + `prompt`), and subagents → `.gemini/agents/<name>.md` (markdown with YAML frontmatter). Gemini CLI has no Agent Skills concept (it uses extensions) and no LSP config, so both are skipped. See docs/capability-matrix.md for the per-component coverage and documented loss.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func IngestMCPSpec

func IngestMCPSpec(raw map[string]any) source.MCPServerSpec

IngestMCPSpec translates one Gemini-native MCP server table — the value under settings.json `mcpServers.<id>` — into the canonical MCPServerSpec. It is the inverse of geminiMCPSpec: `httpUrl` → http transport, `url` → sse transport, otherwise stdio. Native keys agentsync doesn't model are kept in Extra.

There is no `$`-escape to INVERT here: Gemini offers no escape syntax (see geminiVarExpansionRe), so geminiMCPSpec writes resolved values verbatim and this reads them verbatim — the value round-trips losslessly without any transform.

Types

type Adapter

type Adapter struct {
	// contains filtered or unexported fields
}

Adapter implements adapter.Adapter for Gemini CLI.

func New

func New(opts Options) *Adapter

New constructs a Gemini CLI adapter.

func (*Adapter) Apply

func (a *Adapter) Apply(ops []adapter.FileOp, w adapter.DestWriter) error

Apply routes every destination write through the supplied DestWriter rather than calling iox.AtomicWrite directly. This is the contract that keeps the foreign-collision backup guarantee honest — see the doc on adapter.DestWriter.

func (*Adapter) Detect

func (a *Adapter) Detect() (bool, error)

func (*Adapter) Ingest

func (a *Adapter) Ingest(scope adapter.Scope, project string) (source.Canonical, error)

Ingest reads Gemini CLI's native config files and returns a partial source.Canonical. It is the inverse of Render (modulo the documented projected loss — subagent tools/color, command argument-hint/allowed-tools — which Render drops with a reported Skip).

func (*Adapter) IngestMCPSpec added in v0.15.0

func (a *Adapter) IngestMCPSpec(raw map[string]any) source.MCPServerSpec

IngestMCPSpec satisfies adapter.MCPSpecIngester by delegating to the package translator Ingest uses, so the dialect has exactly one definition.

func (*Adapter) KeyMergeStrategy

func (a *Adapter) KeyMergeStrategy() string

KeyMergeStrategy is gemini's single key-merge strategy: JSON (settings.json). settings.json is gemini's ONLY key-merge destination — both `mcpServers` and `hooks` live there — so the single strategy the render pipeline uses for orphan-cleanup synthesis is correct for every key-merge path this adapter owns.

func (*Adapter) Name

func (a *Adapter) Name() string

func (*Adapter) NativeHookEvent added in v0.11.0

func (a *Adapter) NativeHookEvent(canonical string) (string, bool)

NativeHookEvent implements adapter.HookEventNamer: Gemini renames canonical hook events in settings.json (PreToolUse -> BeforeTool, …), so import's stale-hook retirement must disown gemini's "/hooks/<native>" state key under the NATIVE spelling — matching only the canonical name would leave the key owned with no canonical render, and the next apply's orphan cleanup would delete the event from the user's settings.json.

func (*Adapter) RefusedHookEvents added in v0.11.0

func (a *Adapter) RefusedHookEvents(scope adapter.Scope, project string) ([]string, error)

RefusedHookEvents implements adapter.HookIngestGuard — see the interface doc for the shared contract and ingestHooks for what gemini refuses. Gemini leg: settings.json is re-read as JSONC (jsonkeys.DecodeJSONC), exactly as Ingest parses it; refused events surface under their CANONICAL names (BeforeTool → PreToolUse), and Gemini-only events (BeforeModel, …) never appear — no canonical file exists to retire. Warnings are discarded here; Ingest already emitted them on the same shapes.

func (*Adapter) Render

func (a *Adapter) Render(r secrets.Resolved, scope adapter.Scope, project string) ([]adapter.FileOp, []adapter.Skip, error)

Render converts the resolved canonical into FileOps for Gemini CLI.

Render projects each plugin's COMPONENTS (MCP, memory, commands, subagents, hooks) to Gemini's native `.gemini/` paths. Gemini CLI has no native plugin enable-state concept agentsync models (it uses extensions), so there is no PluginIngester and nothing is ever written back — the same components-only-on- apply rule every adapter follows.

func (*Adapter) SetStderr

func (a *Adapter) SetStderr(w io.Writer)

SetStderr replaces the warning sink the adapter writes Ingest warnings to, so a CLI command can route adapter warnings through the same styled writer it uses for its own output. See claude.Adapter.SetStderr for the contract.

func (*Adapter) VersionRoots added in v0.7.5

func (a *Adapter) VersionRoots(scope adapter.Scope, project string) []string

VersionRoots implements adapter.VersionedDirs: the user-scope ~/.gemini config dir is the local-only git-backup root (issue #118). Returns nil at project scope.

type Options

type Options struct {
	TargetRoot string // honors AGENTSYNC_TARGET_ROOT (real "/Users/x" in production)
	// LookPath overrides exec.LookPath for testing. nil means use exec.LookPath.
	LookPath func(file string) (string, error)
	// Stderr receives Ingest warnings (lenient-YAML notices, dropped components).
	// nil means os.Stderr.
	Stderr io.Writer
}

Options configure the adapter at construction.

type Paths

type Paths struct {
	ConfigDir   string // ~/.gemini (or <proj>/.gemini)
	Settings    string // .gemini/settings.json (mcpServers + hooks; merge-jsonc-keys)
	Memory      string // ~/.gemini/GEMINI.md (user) or <proj>/GEMINI.md (project root)
	CommandsDir string // .gemini/commands (slash-command TOML)
	AgentsDir   string // .gemini/agents (subagent markdown)
}

Paths resolves the destination paths for a given (scope, project, target-root).

settings.json holds both `mcpServers` and `hooks` (the adapter's single key-merge file). Memory is the hierarchical GEMINI.md context file: `~/.gemini/GEMINI.md` at user scope, repo-root `GEMINI.md` at project scope.

func ResolvePaths

func ResolvePaths(targetRoot, project string, projectScope bool) Paths

ResolvePaths returns the Paths for the given target root and optional project. projectScope=true + non-empty project uses project-local .gemini/ dirs and the repo-root GEMINI.md.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL