SpecForge's Gemini CLI support is a committed bundle — dist/agents/gemini/ — that ports the same
spec-driven lifecycle to Google's Gemini CLI: the /specforge:* TOML commands, repo-wide
instructions, and a real pre-tool gate. It's generated from the same neutral step source as the
Claude Code plugin, so the workflow and artifacts (specforge/spec.md, plan.md, tasks.md,
state.md, …) are identical; only the hook transport differs.
| Path | Purpose |
|---|---|
.gemini/commands/specforge/<n>.toml |
15 command files, invoked as /specforge:<n> in Gemini CLI |
.gemini/settings.json |
A BeforeTool hook registering the gate shim |
GEMINI.md |
Repo-wide instructions telling Gemini the gate exists and not to route around it |
.specforge/gate/{gemini-gate.sh,decide.sh,common.sh} |
The gate: a Gemini-specific shim over the same transport-agnostic decision logic Claude Code, Copilot, Cursor, and Codex use |
.specforge/scripts/{new-feature.sh,ralph-loop.sh} |
Helper scripts the /specforge:* commands reference |
pre-commit |
An agent-independent git hook — the backstop described below |
install.sh |
Copies the above into your repo (see Install) |
install.sh needs the rest of the bundle sitting beside it — it copies .gemini/ and
.specforge/ from its own directory, and it detects your repo root by running
git rev-parse --show-toplevel from wherever you invoke it. That means it can't be safely
piped through curl | sh: it has to be run from inside your target repo, pointed at a real
copy of the bundle. Get the bundle, then run its installer from inside your project:
# From inside your project repo:
git clone --depth 1 https://github.com/pooyagolchian/specforge /tmp/specforge
/tmp/specforge/dist/agents/gemini/install.sh
# then in Gemini CLI: /specforge:initThis is safe to re-run. If GEMINI.md or a git pre-commit hook already exists and differs from
SpecForge's version, install.sh backs up the existing file (.bak) before installing rather
than silently overwriting it. If you already have a .gemini/settings.json with your own hooks,
model config, or telemetry settings, install.sh merges SpecForge's hooks.BeforeTool entry into
it (via python3) instead of clobbering the file — if python3 isn't available, it backs up your
existing file to .gemini/settings.json.bak and warns you to re-add anything of yours by hand.
| Command | Phase | What it does |
|---|---|---|
/specforge:init |
setup | Scaffold the specforge/ workspace + input templates |
/specforge:constitution |
inception | Set project principles (soft gates) |
/specforge:reverse-engineer |
inception | Seed specs from an existing codebase (brownfield) |
/specforge:specify |
inception | Write the spec (WHAT/WHY) → spec.md |
/specforge:clarify |
inception | Resolve unknowns via a questions-in-a-file flow |
/specforge:plan |
construction | Design the HOW → plan.md + companions |
/specforge:tasks |
construction | Break the plan into an ordered, traceable checklist |
/specforge:analyze |
construction | Cross-check spec ↔ plan ↔ tasks for gaps (read-only) |
/specforge:approve <stage> |
gate | Record human approval — specify + plan opens the gate |
/specforge:implement |
construction | Build it, under the gate |
/specforge:loop |
construction | Autonomously work the approved task list — gated Ralph loop |
/specforge:operate |
operations | Deploy plan, runbook, observability, rollback, handoff |
/specforge:quick |
escape hatch | Audited fast-track for a trivial change |
/specforge:status |
any | Show progress + gate state |
/specforge:resume |
any | Continue after a context reset |
SpecForge's differentiator is that approval is enforced, not advisory. Here's the honest picture for Gemini CLI:
| Tier | Mechanism | Status |
|---|---|---|
| Claude Code | Real-time PreToolUse hook — blocks the edit at the moment it's attempted |
Full (the flagship) |
| Gemini CLI | BeforeTool hook (.gemini/settings.json → gemini-gate.sh) |
Config, matcher, deny-response shape, and cwd field match Gemini's documented hooks schema — not yet tested against a live Gemini CLI install |
| Any agent, or a human editing directly | git pre-commit hook (installed by install.sh) |
Agent-independent backstop — fires at commit time regardless of which AI (or no AI) made the edit |
The pre-commit hook is the honest floor: even where the BeforeTool hook is misconfigured,
disabled, or not wired up, an unapproved code change staged for commit is still caught locally,
before it's committed. It reuses the same decide.sh decision logic as the Gemini hook, so its
verdict is always consistent. Note this is a local git hook, not a CI/PR check — the bundle
doesn't ship a CI workflow for your repo; if you want enforcement at PR time too, you can wire
decide.sh into your own CI job the same way pre-commit does.
Caveat: .gemini/settings.json registers a BeforeTool hook with matcher write_file|replace
and a command pointing at gemini-gate.sh, matching Gemini CLI's documented hooks schema. The
shim reads the hook's JSON payload on stdin, reads the project directory from cwd, and looks for
the edited file's path at tool_input.file_path (Gemini's documented field for both write_file
and replace), falling back to tool_input.path and tool_input.absolute_path in case of field-
naming drift. On a deny, it emits Gemini's documented {"decision":"deny","reason":"..."} shape.
None of this has been exercised against a live Gemini CLI install — it's built and tested
against Gemini's documented schema and a scripted stand-in for the hook contract (see
tests/gemini-gate.test.sh and tests/e2e-gemini.test.sh), not verified end-to-end with the real
CLI. The shim fails open on anything it can't parse — a missing script, an unrecognized field
name, or a crash all resolve to "allow," never to "incorrectly block a legitimate edit." That means
a schema mismatch downgrades this tier to "not enforced by this hook," always caught anyway by the
pre-commit backstop at commit time. Verify against your Gemini CLI version.
- How the gates work — the shared decision logic (
decide.sh) behind every tier - Installation guide — the Claude Code plugin path
- GitHub Copilot guide — another non-Claude adapter
- Cursor guide — another non-Claude adapter
- Codex guide — the other newest adapter
- Quickstart