Skip to main content

What Are Hooks?

Claude Code hooks are scripts that intercept tool execution at specific lifecycle points. RTK uses the PreToolUse hook to modify Bash commands before they reach the shell.
Hook lifecycle: Claude decides to run a command → PreToolUse hook intercepts → Hook rewrites command → Modified command executes → Claude receives output

PreToolUse Hook Workflow

The rewrite is transparent: Claude never knows the command was modified. It just sees optimized output.

Auto-Rewrite Hook Architecture

RTK’s hook script (rtk-rewrite.sh) is a Bash script that:
  1. Receives: JSON input from Claude Code with the original command
  2. Parses: Extracts the command string
  3. Matches: Pattern-matches against known RTK commands
  4. Rewrites: Transforms to rtk <cmd> equivalent
  5. Returns: JSON output with updatedInput field
If no match is found, the hook returns empty JSON (command passes through unchanged).

Hook Script Structure

Guards and Safety

The hook includes guard clauses to handle edge cases:
  • Dependency check: Exits silently if rtk or jq not found
  • Empty command: Skips if no command string
  • Already rewritten: Skips if command already starts with rtk
  • Heredocs: Skips commands with << (shell syntax incompatible with rewriting)
Guards must appear before set -euo pipefail. Otherwise, missing dependencies cause the hook to crash instead of failing gracefully.

How the Hook Works

1. Command Detection

The hook pattern-matches the first word of the command:

2. Environment Variable Preservation

Commands with environment variable prefixes are handled correctly:
The hook strips env vars for pattern matching, then re-adds them after rewriting.

3. Command Chaining

The hook only rewrites the first command in chains:
Each command in the chain is rewritten independently because Claude Code invokes the hook once per command.

4. Passthrough Commands

Commands without RTK support pass through unchanged:
RTK’s passthrough support means unhandled commands still work.

Commands Rewritten

The hook rewrites the following commands:

Version Control

Build & Test

JavaScript/TypeScript

Python

Containers

Network

Infrastructure

Commands already using rtk, heredocs (<<), and unrecognized commands pass through unchanged.

Installation

The hook installs automatically with:
This creates:
  • ~/.claude/hooks/rtk-rewrite.sh (executable, with guards)
  • Entry in ~/.claude/settings.json
See Claude Code Integration for full walkthrough.

Manual Installation

If automatic setup fails:
1

Create hook directory

2

Copy hook script

3

Edit settings.json

Add to ~/.claude/settings.json:
4

Restart Claude Code

Close and reopen Claude Code, then test:

Per-Project Installation

For project-specific hooks, create .claude/hooks/rtk-rewrite.sh in your project root and reference it in .claude/settings.json:

Hook Debugging

Enable Audit Logging

Track every hook invocation:
Logs are written to ~/.local/share/rtk/hook-audit.log:
Columns:
  1. Timestamp (UTC)
  2. Action (rewrite, skip:*)
  3. Original command
  4. Rewritten command (or - if skipped)

Custom Audit Directory

Verify Hook Execution

Check if the hook is being invoked:
Expected:

Verify Hook Permissions

Should show -rwxr-xr-x (executable). If not executable:

Test Hook Manually

Run the hook script directly:
Expected output:

Alternative: Suggest Hook

If you prefer Claude Code to suggest rtk usage rather than automatically rewriting, use the suggest hook pattern.

Auto-Rewrite vs Suggest

When to Use Suggest

  • You want to audit which commands Claude chooses to run
  • You’re learning rtk patterns and want visibility
  • You prefer explicit decisions over transparent rewrites
  • You want to preserve exact command execution for debugging

Suggest Hook Setup

1

Create suggest hook

2

Register in settings.json

3

Restart Claude Code

Test with any rtk-compatible command. Claude will receive a system reminder but execute the original command.
The suggest hook outputs systemMessage instead of updatedInput, informing Claude that an rtk alternative exists without modifying the command.

Troubleshooting

Hook Not Rewriting Commands

Symptom: Commands show raw output after hook installation. Checks:
  1. Verify hook is registered:
  2. Verify hook is executable:
  3. Check dependencies:
  4. Enable audit logging:
    Then run a command and check logs.

Hook Crashes

Symptom: Claude Code shows “Hook execution failed” error. Common causes:
  • set -euo pipefail runs before guards → Move guards to top of script
  • Missing jq dependency → Install: brew install jq / apt install jq
  • Invalid JSON output → Test hook manually with echo '{...}' | hook.sh

Hook Ignores Certain Commands

Symptom: Some commands rewrite, others don’t. Cause: Pattern doesn’t match command syntax. Example: npm run test vs npm test Check the hook script patterns at ~/.claude/hooks/rtk-rewrite.sh around line 130-140 for npm handling.

Next Steps

Configuration

Customize RTK behavior and settings

Claude Code Setup

Full installation walkthrough