Gemini CLI's hook contract is Claude Code's with the nouns changed. Google even
ships gemini hooks migrate --from-claude. So the adapter works the
same way: the briefing goes in on session start, and the session is observed
turn by turn.
Careful
Gemini CLI 0.5 or later. The hook system arrived in that release. Earlier versions register nothing.
What Runi installs#
Session hooks and an MCP server entry in ~/.gemini/settings.json,
plus a relay-gemini wrapper.
How the briefing arrives#
On startup the CLI fires SessionStart, reads
hookSpecificOutput.additionalContext off the merged hook output,
and adds it to the conversation history as the first user turn.
That is a real delivery path, measured in the shipped bundle and not read off a
documentation page.
Gemini renames every event instead of reusing Claude's names, so Runi maps the
same six moments onto Gemini's own vocabulary. BeforeAgent is
where a prompt is captured; AfterAgent is the end of a turn.
Note
One rendering quirk. Gemini HTML-escapes the context a hook returns, so
anything angle-bracketed in a briefing arrives as an entity:
<task> instead of <task>. Prose,
names and file paths are unaffected and the meaning survives. It looks odd
only if you print the raw context.
What Runi will not register#
Gemini exposes BeforeModel and AfterModel, which
carry the raw model exchange. Runi does not register for either. The same
principle holds across every adapter: the model's private reasoning is a
scratchpad, not a team channel.
Verify it#
$ runi doctor
…
ok adapter:gemini ok, last seen 3 min ago
Then start gemini in a tracked repository and ask what it was
given at the start of the session. The packet arrives as the first user turn,
so it is right there in the history.
Known limits#
- Angle brackets in the briefing arrive HTML-escaped, as above.
- The briefing lands once, at session start. A teammate's note that arrives mid-session reaches the next session.
- Only repositories your workspace tracks are published.
- Gemini CLI 0.5 and later only.
Troubleshooting#
gemini --version, then whether ~/.gemini/settings.json holds a Runi hooks block, then whether the folder is tracked.
Update the CLI, reconnect from Settings → Agents, and start a new session. Settings are read at startup.
The HTML escaping above. It is cosmetic.
Nothing to do. The model reads it correctly. If it does confuse a session, ask it to call runi_brief instead, which returns the packet through the tool channel unescaped.