Skip to content
Development
Hook

Hooks

What repobrain runs automatically, and when. A hook is a command Claude Code fires at a fixed moment, without you asking for it.

From plugin
repobrain
1.4k4 skills4 commands1 hook

Claude Code

> /plugin marketplace add study8677/repobrain
> /plugin install repobrain@repobrain

What fires, and when

SessionStart

Fires once when a session begins, and again after a context compaction. It is where a plugin sets up its environment, or restores state the compaction dropped.

  • python3 "${CLAUDE_PLUGIN_ROOT}/hooks/install_engine.py" || python "${CLAUDE_PLUGIN_ROOT}/hooks/install_engine.py"
Read hooks/hooks.json

Where it lives

  • hooks/install_engine.pyRunsGitHub
    Read the script
    #!/usr/bin/env python3
    """SessionStart hook: ensure the RepoBrain CLI and engine are on PATH.
    
    Single cross-platform installer for Claude Code's plugin SessionStart hook.
    Idempotent and silent on the happy path. All output goes to stderr (stdout
    on a hook is interpreted as injected context).
    
    Strategy:
      1. If all RepoBrain commands are on PATH at the bundled versions, exit 0.
      2. Ensure pipx exists:
           - macOS with Homebrew → `brew install pipx`
           - Otherwise → `python -m pip install --user pipx`
         Both paths require no sudo.
      3. `pipx ensurepath` and prepend the pipx bin dir to PATH for the current
         process so the next `pipx install` finds the freshly placed shim.
      4. `pipx install --force <plugin_root>/engine`, then inject the bundled CLI
         into the same environment with `--include-apps`.
      5. If pipx remains unavailable, fall back to `pip install --user --upgrade`.
      6. On total failure, print a clear manual-install message and exit 1.
    """
    from __future__ import annotations
    
    import os
    import re
    import shutil
    import subprocess
    import sys
    from pathlib import Path
    
    
    ENGINE_PACKAGE = "repobrain-engine"
    REQUIRED_COMMANDS = ("rb", "rb-ask", "rb-refresh", "rb-mcp")
    
    
    def log(msg: str) -> None:
        print(msg, file=sys.stderr, flush=True)
    
    
    def has(cmd: str) -> bool:
        return shutil.which(cmd) is not None
    
    
    def user_scripts_bin() -> Path | None:
        """Resolve site.USER_BASE bin/Scripts dir from the current Python."""
        try:
            import site
            base = Path(site.USER_BASE)
        except Exception:
            return None
        candidate = base / ("Scripts" if os.name == "nt" else "bin")
        return candidate if candidate.is_dir() else None
    
    
    def prepend_path(p: Path) -> None:
        if not p.is_dir():
            return
        cur = os.environ.get("PATH", "")
        parts = cur.split(os.pathsep)
        if str(p) in parts:
            return
        os.environ["PATH"] = str(p) + os.pathsep + cur
    
    
    def run(cmd: list[str]) -> int:
        try:
            return subprocess.run(cmd, stderr=sys.stderr, stdout=sys.stderr).returncode
        except FileNotFoundError:
            return 127
    
    
    def ensure_pipx() -> bool:
        """Install pipx if missing. Returns True if pipx is available afterwards."""
        if has("pipx"):
            return True
    
        # macOS with Homebrew: cleanest path, no sudo.
        if sys.platform == "darwin" and has("brew"):
            log("[repobrain] Installing pipx via Homebrew...")
            run(["brew", "install", "pipx"])
    
        # Cross-platform fallback: pip install --user pipx.
        if not has("pipx"):
            py = sys.executable or ("python" if has("python") else "python3")
            log(f"[repobrain] Installing pipx via pip --user ({py})...")
            run([py, "-m", "pip", "install", "--user", "--quiet", "pipx"])
            # User-base scripts/bin needs to be on PATH for `pipx` to be findable.
            ub = user_scripts_bin()
            if ub:
                prepend_path(ub)
    
        return has("pipx") or _has_pipx_module()
    
    
    def _has_pipx_module() -> bool:
        """Some installs put pipx on PATH only after `ensurepath`. Check for the
        module so we can invoke it via `python -m pipx` as a fallback."""
        try:
            subprocess.run(
                [sys.executable or "python", "-m", "pipx", "--version"],
                check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
            )
            return True
        except Exception:
            return False
    
    
    def pipx(args: list[str]) -> int:
        if has("pipx"):
            return run(["pipx", *args])
        return run([sys.executable or "python", "-m", "pipx", *args])
    
    
    def read_project_version(package_dir: Path) -> str | None:
        """Read a bundled package version from its ``pyproject.toml``."""
        try:
            text = (package_dir / "pyproject.toml").read_text(encoding="utf-8")
        except OSError:
            return None
        match = re.search(r'^version\s*=\s*"([^"]+)"', text, flags=re.MULTILINE)
        return match.group(1) if match else None
    
    
    def get_installed_engine_version() -> str | None:
        """Return the installed rb-mcp engine version, if it can be queried."""
        rb_mcp = shutil.which("rb-mcp")
        if rb_mcp is None:
            return None
        try:
            completed = subprocess.run(
                [rb_mcp, "--version"],
                check=False,
                capture_output=True,
                text=True,
                timeout=15,
            )
        except Exception:
            return None
        if completed.returncode != 0:
            return None
        output = (completed.stdout or completed.stderr).strip()
        match = re.search(r"(\d+\.\d+\.\d+(?:[-+][A-Za-z0-9.]+)?)", output)
        return match.group(1) if match else None
    
    
    def get_installed_cli_version() -> str | None:
        """Return the installed ``rb`` CLI version, if it can be queried."""
        rb = shutil.which("rb")
        if rb is None:
            return None
        try:
            completed = subprocess.run(
                [rb, "version"],
                check=False,
                capture_output=True,
                text=True,
                timeout=15,
            )
        except Exception:
            return None
        if completed.returncode != 0:
            return None
        output = (completed.stdout or completed.stderr).strip()
        match = re.search(r"(\d+\.\d+\.\d+(?:[-+][A-Za-z0-9.]+)?)", output)
        return match.group(1) if match else None
    
    
    def required_commands_available() -> bool:
        """Return whether every command promised by the plugin is on PATH."""
        return all(has(command) for command in REQUIRED_COMMANDS)
    
    
    def installation_is_current(
        installed_engine: str | None,
        expected_engine: str | None,
        installed_cli: str | None,
        expected_cli: str | None,
    ) -> bool:
        """Return whether versions and all public commands match the bundle."""
        return (
            installed_engine == expected_engine
            and installed_cli == expected_cli
            and None not in (installed_engine, expected_engine, installed_cli, expected_cli)
            and required_commands_available()
        )
    
    
    def installed_bundle_is_current(
        expected_engine: str | None,
        expected_cli: str | None
  • hooks/install_engine.shGitHub
    Read the script
    #!/usr/bin/env bash
    # Thin wrapper for manual invocation. The real install logic lives in
    # `install_engine.py` so it can be reused by the Windows .bat wrapper and
    # the cross-platform hook command in `hooks.json`.
    set -u
    DIR="$(cd "$(dirname "$0")" && pwd)"
    exec python3 "${DIR}/install_engine.py" 2>/dev/null \
      || exec python "${DIR}/install_engine.py"
    

Read the script before you install anything that runs on your machine. This is the one part of a plugin that acts without being asked.

@study8677
Ships withrepobrain

Cross-IDE repository knowledge engine for grounded codebase Q&A. Formerly known as Antigravity Workspace Template — same project, new name.

Stars on GitHub

Momentum

stars in total
1.4k
Star history of study8677/repobrain on GitHub, a chart by star-history.com

More plugins that ship hooks.

superpowers

superpowers

A development methodology for coding agents that makes the agent brainstorm before building, follow plans, run parallel work and finish branches in a disciplined way. You get fewer skipped steps and more consistent results from your coding assistant.

15 skills1 hook311k
@obra@obra
Install Plugin
ponytail

ponytail

A Claude Code plugin with skills for auditing a whole repo, reviewing a change, listing deferred shortcut comments, and showing measured savings and a quick command reference.

6 skills10 hooks188k
@dietrichgebert@dietrichgebert
Install Plugin
agent-skills

agent-skills

Walks a software change from a written spec through design, testing, code review, CI/CD, and release, applying the matching engineering skill at each stage. Useful for developers using Claude Code on full development workflows.

25 skills+3112k
@addyosmani@addyosmani
Install Plugin
planning-with-files

planning-with-files

Persistent file-based planning for AI coding agents on long-running, multi-step tasks. It keeps task_plan.md, findings.md and progress.md on disk, so work can resume after /clear or context compaction.

6 skills+228k
@othmanadi@othmanadi
Install Plugin
gsd-core

gsd-core

A spec-driven development workflow for Claude Code that guides a project through planning, phases, milestone audits and fixes. Includes skills to generate tests from UAT criteria and to audit completed work.

72 skills+311k
@open-gsd@open-gsd
Install Plugin
superpowers-zh

superpowers-zh

Chinese-language skill pack for Claude Code that adds workflow guidance for brainstorming, TDD, debugging, and code review, plus Chinese conventions for commits, documentation, and domestic Git platforms like Gitee and Coding.net.

21 skills1 hook8.5k
@jnmetacode@jnmetacode
Install Plugin
socraticode

socraticode

Gives Claude Code semantic search, dependency graph and architecture context over a codebase, so an AI assistant can explore and understand a project's code. Includes skills for indexing a project and managing its file watching.

2 skills+33.4k
@giancarloerra@giancarloerra
Install Plugin
cocoindex-code

cocoindex-code

A lightweight code search engine that uses AST-based semantic search with local embeddings and incremental indexing. It helps Claude Code users find code faster and more efficiently.

1 skill1 MCP+13k
@cocoindex-io@cocoindex-io
Install Plugin

Questions about the hooks in repobrain.

Which coding agents can use the hooks in repobrain?
The hooks in repobrain install in Claude Code and Cursor: each runs Claude Code hooks from .claude/settings.json, so copy the hooks there.