Skip to main content

Hooks System

Hooks are lifecycle event handlers that execute at specific points in the platform’s lifecycle, allowing Superpowers to inject context, run setup scripts, or perform initialization tasks.

What Are Hooks?

Hooks are automatic scripts that run when certain events occur in your AI coding platform. They enable:
  • Context Injection: Adding information to the agent’s context at session start
  • Setup Tasks: Running initialization scripts before work begins
  • Environment Configuration: Setting up project-specific requirements
  • Custom Workflows: Triggering platform-specific automation
Hooks are transparent to users - they run automatically without user intervention.

Hook Configuration

Hooks are defined in hooks/hooks.json:

Configuration Anatomy

Different platforms support different hook events:
  • SessionStart: Runs when a new session begins (supported by Claude Code, Cursor)
  • SessionResume: Runs when resuming a saved session
  • ProjectOpen: Runs when opening a project
  • Custom events: Platform-specific hooks
Currently, Superpowers only implements SessionStart.
The matcher field filters when hooks run:
This regex matches session states:
  • startup: New session
  • resume: Resumed session
  • clear: Cleared session
  • compact: Compacted session
The hook runs if the session state matches any of these patterns.
Each hook has:
  • type: Command type (usually "command")
  • command: Shell command to execute
  • async: Whether to run asynchronously (false = blocking)
Environment variables available:
  • ${CLAUDE_PLUGIN_ROOT}: Path to plugin root directory
  • ${CURSOR_PLUGIN_ROOT}: Path to plugin root (Cursor)
  • Standard shell variables ($HOME, $USER, etc.)

SessionStart Hook

The SessionStart hook is the most important hook in Superpowers - it injects the using-superpowers skill content into every session.

Hook Script: hooks/session-start

What the Hook Does

1

Determine Plugin Root

Finds the plugin installation directory using SCRIPT_DIR:
2

Check for Legacy Configuration

Detects old installation paths and warns users:
3

Read using-superpowers Skill

Loads the core skill that teaches agents how to use skills:
4

Escape for JSON

Properly escapes content for JSON embedding (critical for special characters):
Performance note: Uses bash parameter substitution instead of character-by-character loops for 10-100x speedup.
5

Output JSON Context

Returns JSON with dual format for compatibility:
  • Cursor: Uses additional_context
  • Claude Code: Uses hookSpecificOutput.additionalContext

Cross-Platform Hook Wrapper

The hooks/run-hook.cmd script is a polyglot (runs on both Windows and Unix):

How the Polyglot Works

When cmd.exe runs the script:
  1. The : << 'CMDBLOCK' is ignored (: is a no-op in batch)
  2. Batch portion executes normally
  3. Searches for Git Bash in standard locations
  4. Falls back to bash on PATH
  5. If no bash found, exits silently (plugin still works without hooks)
When bash/sh runs the script:
  1. The : << 'CMDBLOCK' starts a heredoc that ignores the batch portion
  2. CMDBLOCK closes the heredoc
  3. Unix portion executes normally
  4. Directly calls bash with the hook script
Why extensionless filenames? Claude Code’s Windows auto-detection prepends bash to any command with .sh, which would double-invoke bash.

Creating Custom Hooks

Step 1: Define Hook in hooks.json

Step 2: Create Hook Script

Create hooks/my-custom-hook (no extension):

Step 3: Make Executable

Step 4: Test Locally

Hook Output Format

Hooks must output valid JSON to stdout:
  • additional_context: Text injected into agent context (Cursor format)
  • hookSpecificOutput.hookEventName: Name of triggering event
  • hookSpecificOutput.additionalContext: Text injected into agent context (Claude Code format)
  • Custom fields: Platform-specific extensions
Invalid JSON will cause hook failures. Use tools like jq to validate:

Platform Support

OpenCode alternative: Uses plugin system with experimental.chat.system.transform hook to inject context at session start. See Plugin System.

Debugging Hooks

Enable Verbose Logging

Add debugging to your hook script:

Check Platform Logs

  • Claude Code: Check debug logs via /debug logs
  • Cursor: Check console in developer tools
  • Manual test: Run hook directly: ./hooks/run-hook.cmd session-start

Common Issues

  • Verify hooks.json syntax with jq
  • Check file permissions: chmod +x hooks/session-start
  • Ensure matcher pattern matches session state
  • Verify plugin is properly installed
  • Test JSON with: ./hooks/run-hook.cmd session-start | jq .
  • Check for unescaped special characters
  • Verify all quotes are properly escaped
  • Ensure heredoc EOF is on its own line
  • Verify both additional_context AND hookSpecificOutput.additionalContext are set
  • Check platform-specific field requirements
  • Test with minimal content first
  • Review platform logs for errors

Best Practices

1

Keep Hooks Fast

Hooks block session start - keep execution under 1 second:
2

Handle Errors Gracefully

Don’t fail the entire session if hook fails:
3

Use Efficient String Escaping

Use bash parameter substitution instead of loops:
4

Test Cross-Platform

Test on both Windows and Unix:

Next Steps

Architecture

Understand overall system architecture

Plugin System

Learn how plugins integrate hooks

Creating Skills

Write custom skills that hooks can inject

Contributing

Contribute hook improvements