Skip to content

Hook Support in Extensions #14449

@abhipatel12

Description

@abhipatel12

Description

Add support for defining hooks within Gemini CLI extensions. This will allow extensions to automatically react to CLI events (like PreToolUse, PostToolUse, SessionStart) and execute commands or scripts.

Motivation

Currently, hooks can only be defined in user or project-level settings.json. This limits the shareability and reusability of powerful automation workflows. By enabling extensions to bundle hooks, we allow developers to create extensions that can:

  • Enforce security policies (e.g., "prevent rm -rf").
  • Automate workflows (e.g., "run linter after WriteFile").
  • Integrate with external systems (e.g., "notify Slack on SessionEnd").

Proposed Implementation

We will adopt a file-based convention similar to how custom commands are currently handled in extensions (commands/*.toml).

  1. Convention: Extensions can include a hooks/hooks.json file.
  2. Structure: The JSON structure will match the existing hooks configuration in settings.json.
  3. Loading: The ExtensionManager will automatically discover and load this file when loading an extension.
  4. Variable Substitution: We will support ${extensionPath} in hook commands to allow referencing scripts bundled within the extension (e.g., ${extensionPath}/scripts/my-hook.sh).
  5. Registration: Extension hooks will be registered with ConfigSource.Extensions priority, ensuring they integrate correctly with user and project hooks.

Example Usage

An extension my-linter-extension could have the following structure:

my-linter-extension/
├── gemini-extension.json
├── hooks/
│   └── hooks.json
└── scripts/
    └── lint.sh

hooks/hooks.json:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "WriteFile",
        "hooks": [
          {
            "type": "command",
            "command": "${extensionPath}/scripts/lint.sh"
          }
        ]
      }
    ]
  }
}

Metadata

Metadata

Assignees

Labels

No fields configured for Feature.

Projects

Status

Closed

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions