Gemini CLI: Agent Skills, hooks and extensions
Google’s Gemini CLI (google-gemini/gemini-cli) supports Agent Skills natively. A spec-compliant SKILL.md loads without changes. This page covers how Gemini discovers and activates Skills, its hook system, how extensions package both, and where it differs from the Agent Skills spec.
Source: Gemini CLI docs at release v0.61.0, commit bb52374 (tagged 2026-09-23), read 2026-09-29. Gemini CLI was not installed on the checking machine, so nothing on this page was run.
Skill discovery
Gemini CLI reads Skills from four tiers, lowest precedence first (docs/cli/skills.md):
- Built-in. Skills shipped with Gemini CLI.
- Extension.
skills/<name>/SKILL.mdinside an installed extension. - User.
~/.gemini/skills/or the~/.agents/skills/alias. - Workspace.
.gemini/skills/or the.agents/skills/alias.
.agents/skills/ wins over .gemini/skills/. The .agents/skills/ alias is the same path Codex and OpenCode read, so one checked-in Skill directory serves all three.
gemini skills install <git-url-or-path>, gemini skills list and the /skills slash command manage them.
Activation
The lifecycle fromdocs/cli/skills.md:
- Discovery. At session start, Gemini CLI puts the name and description of every enabled Skill into the system prompt.
- Activation. When the model matches a task to a description, it calls the
activate_skilltool with the Skill’s name. Only the model calls this tool; the user cannot (docs/tools/activate-skill.md). - Consent. The user sees a confirmation prompt naming the Skill and the directory it will gain access to.
- Injection. On approval, the
SKILL.mdbody and the Skill’s folder structure enter the conversation, and the Skill directory is added to the agent’s allowed file paths.
scripts/, references/ and assets/ are read on demand (docs/cli/creating-skills.md).
Differences from the Agent Skills spec
- Only
nameanddescriptionare read. The loader parses those two fields and ignores the rest (skillLoader.ts).license,compatibility,metadataand every Claude Code extension field (paths,disable-model-invocation,allowed-tools) have no effect. - Activation needs user consent. In an interactive session each activation asks the user first. A Skill that must load unattended needs that prompt accounted for.
- No listing budget is documented. The docs state that every enabled Skill’s name and description is injected; they give no cap.
docs/cli/skills-best-practices.md.
Hooks
Gemini CLI runs command hooks configured insettings.json at project (.gemini/settings.json), user, system and extension level (docs/hooks/index.md). The event names differ from Claude Code’s:
The context column comes from
docs/hooks/reference.md. Hooks return JSON on stdout; any other stdout text breaks parsing, and the CLI then allows the action and shows the text as a system message. Timeouts are in milliseconds (default 60,000).
Extensions
An extension is a directory under~/.gemini/extensions/<name>/ with a required gemini-extension.json manifest (docs/extensions/reference.md). It can bundle:
- a context file (
GEMINI.mdby default, named bycontextFileName), loaded every session; - custom commands in
commands/*.toml(commands/gcs/sync.tomlbecomes/gcs:sync); - Skills in
skills/<name>/SKILL.md; - hooks in
hooks/hooks.json(not in the manifest); - subagents in
agents/, MCP servers and themes.
Always-on context costs every session
GEMINI.md, including files it pulls in with @file.md imports (docs/cli/gemini-md.md), is always-on context, like CLAUDE.md or AGENTS.md. Put procedures in a Skill, where only the description is paid every session, and keep GEMINI.md for rules that apply to every turn. See Token economics for the arithmetic.
Sources
- Gemini CLI docs and source at
v0.61.0(bb52374), read 2026-09-29: Skills,activate_skill, creating Skills, hooks index and reference, extensions reference,GEMINI.md,skillLoader.ts.