-
Notifications
You must be signed in to change notification settings - Fork 0
Hooks
Hooks are shell commands that Gemini CLI runs automatically in response to session lifecycle events. For rocketsmith, a SessionStart hook injects the dependency status into context so the agent knows whether Java, OpenRocket, and PrusaSlicer are installed before saying a word.
Claude Code: Claude Code does not use Gemini-style hooks. Dependency status is surfaced via
rocketsmith_setup, which the agent calls at session start. The hooks described on this page are Gemini CLI only.
hooks/
├── hooks.json ← declares the hook event and calls run-hook.cmd
├── run-hook.cmd ← cross-platform polyglot wrapper (Windows batch + Unix bash)
└── session-start ← actual hook logic, named after the event, no file extension
This structure follows the convention from obra/superpowers.
Declares which lifecycle events trigger which commands. Must live at hooks/hooks.json inside the extension directory — not inside gemini-extension.json (hooks is not a valid field there).
{
"hooks": {
"SessionStart": [
{
"matcher": "startup|clear|compact",
"hooks": [
{
"type": "command",
"command": "\"${extensionPath}/hooks/run-hook.cmd\" session-start",
"async": false
}
]
}
]
}
}${extensionPath} is substituted by Gemini CLI with the path to the installed extension directory.
A polyglot script that runs as both a Windows batch file and a Unix shell script. Its job is to find bash on whatever platform the user is on and delegate to the named hook script.
- On Unix: the batch block is skipped (
: << 'CMDBLOCK'hides it from bash); the Unix section at the bottom runs directly - On Windows:
cmd.exeexecutes the batch block, which searches for bash in Git for Windows locations and onPATH - If no bash is found on Windows, it exits silently — the session still works, just without the hook context
The script takes the hook name as its first argument (session-start) and passes any remaining args through.
The actual hook logic. Named after the event it handles, with no file extension (following the superpowers convention — file extensions on hook scripts interfere with some platform auto-detection).
What it does:
- Determines the extension root using
SCRIPT_DIR(dirname "$0") — more reliable than env var injection - Checks for Java (
javaon PATH), the OpenRocket JAR (standard platform paths +$OPENROCKET_JAR), and PrusaSlicer (prusa-slicer/PrusaSliceron PATH) directly via shell commands - Builds a status summary and lists any missing dependencies
- JSON-escapes the output (backslashes, quotes, newlines)
- Outputs
{"additionalContext": "..."}— the format Gemini CLI expects from hooks
Gemini CLI hooks must output valid JSON to stdout. Plain text output is ignored. The SDK-standard format is:
{"additionalContext": "text to inject into agent context"}Debugging output should go to stderr, not stdout, to avoid corrupting the JSON.
The injected text appears in the agent's context as:
# rocketsmith dependency status
java: installed (/path/to/jvm)
openrocket: installed (/path/to/openrocket.jar)
prusaslicer: installed (/path/to/prusa-slicer)
status: ready — all tools available
If any dependency is missing, status reads NOT READY — missing: <dep>. Call rocketsmith_setup(action='install') to install.
The previous approach required the agent to call rocketsmith_setup(action="check") as its first turn in every session. This had two problems:
- It cost a turn and added latency before the agent could do any useful work
- The agent could forget to do it
The SessionStart hook runs automatically before the agent's first turn, so the dependency status is already in context when the agent starts. rocketsmith_setup(action="install") is still a tool for when installation is needed — that requires user confirmation and can take a while.
To add a hook for a different lifecycle event (e.g. BeforeTool):
- Add an entry to
hooks/hooks.jsonunder the new event key - Create a corresponding script in
hooks/named after the event - Make the script executable:
chmod +x hooks/<name> - Ensure the script outputs
{"additionalContext": "..."}JSON to stdout
Available Gemini CLI hook events: SessionStart, SessionEnd, BeforeAgent, AfterAgent, BeforeModel, AfterModel, BeforeToolSelection, BeforeTool, AfterTool, PreCompress.