Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions .claude/hooks/rtk-rewrite.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# RTK auto-rewrite hook for Claude Code PreToolUse:Bash
# Transparently rewrites raw commands to their rtk equivalents.
# Outputs JSON with updatedInput to modify the command before execution.
# Source of truth: hooks/rtk-rewrite.sh (keep .claude/hooks copy in sync)

# Guards: skip silently if dependencies missing
if ! command -v rtk &>/dev/null || ! command -v jq &>/dev/null; then
Expand Down Expand Up @@ -88,10 +89,20 @@ elif echo "$MATCH_CMD" | grep -qE '^cargo[[:space:]]+fmt([[:space:]]|$)'; then
REWRITTEN="${ENV_PREFIX}$(echo "$CMD_BODY" | sed 's/^cargo fmt/rtk cargo fmt/')"

# --- File operations ---
# Search priority (mandatory): rgai > rg > grep
# Tier 1: semantic intent search (grepai/rgai) -> rtk rgai
# Tier 2: exact search via ripgrep -> rtk grep (rtk grep runs rg -> grep fallback internally)
# Tier 3: exact search via grep -> rtk grep
elif echo "$MATCH_CMD" | grep -qE '^(grepai|rgai)[[:space:]]+search([[:space:]]|$)'; then
REWRITTEN="${ENV_PREFIX}$(echo "$CMD_BODY" | sed -E 's/^(grepai|rgai)[[:space:]]+search[[:space:]]+/rtk rgai /')"
elif echo "$MATCH_CMD" | grep -qE '^rgai[[:space:]]+'; then
REWRITTEN="${ENV_PREFIX}$(echo "$CMD_BODY" | sed -E 's/^rgai[[:space:]]+/rtk rgai /')"
elif echo "$MATCH_CMD" | grep -qE '^cat[[:space:]]+'; then
REWRITTEN="${ENV_PREFIX}$(echo "$CMD_BODY" | sed 's/^cat /rtk read /')"
elif echo "$MATCH_CMD" | grep -qE '^(rg|grep)[[:space:]]+'; then
REWRITTEN="${ENV_PREFIX}$(echo "$CMD_BODY" | sed -E 's/^(rg|grep) /rtk grep /')"
elif echo "$MATCH_CMD" | grep -qE '^rg[[:space:]]+'; then
REWRITTEN="${ENV_PREFIX}$(echo "$CMD_BODY" | sed -E 's/^rg /rtk grep /')"
elif echo "$MATCH_CMD" | grep -qE '^grep[[:space:]]+'; then
REWRITTEN="${ENV_PREFIX}$(echo "$CMD_BODY" | sed -E 's/^grep /rtk grep /')"
elif echo "$MATCH_CMD" | grep -qE '^ls([[:space:]]|$)'; then
REWRITTEN="${ENV_PREFIX}$(echo "$CMD_BODY" | sed 's/^ls/rtk ls/')"
elif echo "$MATCH_CMD" | grep -qE '^tree([[:space:]]|$)'; then
Expand Down
13 changes: 12 additions & 1 deletion INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,15 @@ rtk gain # MUST show token savings, not "command not found"

## Project Initialization

### Search Priority

**Search priority: rgai > rg > grep.**

- Use `rtk rgai` first for semantic/intention-based discovery.
- Use `rtk grep` for exact/regex matching.
- `rtk grep` internally follows `rg -> grep` backend fallback.
- For fully raw output, use `rtk proxy <cmd>`.

### Recommended: Global Hook-First Setup

**Best for: All projects, automatic RTK usage**
Expand Down Expand Up @@ -229,7 +238,8 @@ cp ~/.claude/settings.json.bak ~/.claude/settings.json
```bash
rtk ls . # Compact tree view
rtk read file.rs # Optimized reading
rtk grep "pattern" . # Grouped search results
rtk rgai "query" # Semantic code search
rtk grep "pattern" . # Exact/regex search (internal rg -> grep fallback)
```

### Git
Expand Down Expand Up @@ -332,6 +342,7 @@ Before each session:
- [ ] Verify RTK is installed: `rtk --version`
- [ ] If not installed → follow "Install from fork"
- [ ] If project not initialized → `rtk init`
- [ ] Search: use `rtk rgai` first, then `rtk grep` for exact/regex
- [ ] Use `rtk` for ALL git/pnpm/test/vitest commands
- [ ] Check savings: `rtk gain`

Expand Down
21 changes: 20 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,15 @@ With rtk: **~45,000 tokens** → **70% reduction**

> Estimates based on medium-sized TypeScript/Rust projects. Actual savings vary by project size.

## Search Priority

**Search priority: rgai > rg > grep.**

- Use `rtk rgai` first for semantic/intention-based discovery.
- Use `rtk grep` for exact/regex matching.
- `rtk grep` internally follows `rg -> grep` backend fallback.
- For fully raw output, use `rtk proxy <cmd>`.

## Installation

### ⚠️ Pre-Installation Check (REQUIRED)
Expand Down Expand Up @@ -130,7 +139,8 @@ rtk read file.rs # Smart file reading
rtk read file.rs -l aggressive # Signatures only (strips bodies)
rtk smart file.rs # 2-line heuristic code summary
rtk find "*.rs" . # Compact find results
rtk grep "pattern" . # Grouped search results
rtk rgai "auth token refresh" # Semantic code search
rtk grep "pattern" . # Exact/regex search (internal rg -> grep fallback)
```

### Git
Expand Down Expand Up @@ -400,6 +410,11 @@ The most effective way to use rtk is with the **auto-rewrite hook** for Claude C

**Result**: 100% rtk adoption across all conversations and subagents, zero token overhead in Claude's context.

**Search ladder**:
- `rtk rgai` for semantic discovery
- `rtk grep` for exact/regex follow-up (`rg -> grep` fallback)
- `rtk proxy ...` when you need fully raw behavior

### What Are Hooks?

**For Beginners**:
Expand Down Expand Up @@ -491,12 +506,16 @@ The hook is included in this repository at `.claude/hooks/rtk-rewrite.sh`. To us

### Commands Rewritten

Search rewrite order is strict and deterministic: `rgai > rg > grep`.

| Raw Command | Rewritten To |
|-------------|-------------|
| `git status/diff/log/add/commit/push/pull/branch/fetch/stash` | `rtk git ...` |
| `gh pr/issue/run` | `rtk gh ...` |
| `cargo test/build/clippy` | `rtk cargo ...` |
| `cat <file>` | `rtk read <file>` |
| `grepai/rgai search <query>` | `rtk rgai <query>` |
| `rgai <query>` | `rtk rgai <query>` |
| `rg/grep <pattern>` | `rtk grep <pattern>` |
| `ls` | `rtk ls` |
| `vitest/pnpm test` | `rtk vitest run` |
Expand Down
9 changes: 9 additions & 0 deletions docs/TROUBLESHOOTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,15 @@ Then add to `~/.claude/settings.json` (replace `~` with full path):

**Note**: Use absolute path in `settings.json`, not `~/.claude/...`

### Search Priority

**Search priority: rgai > rg > grep.**

- Use `rtk rgai` first for semantic/intention-based discovery.
- Use `rtk grep` for exact/regex matching.
- `rtk grep` internally follows `rg -> grep` backend fallback.
- If you need fully raw output for debugging, use `rtk proxy <cmd>`.

---

## Problem: "command not found: rtk" after installation
Expand Down
9 changes: 9 additions & 0 deletions hooks/rtk-awareness.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,14 @@ which rtk # Verify correct binary

All other commands are automatically rewritten by the Claude Code hook.
Example: `git status` → `rtk git status` (transparent, 0 tokens overhead)
Example: `grepai search "auth token refresh"` → `rtk rgai "auth token refresh"`

## Semantic Search

```bash
rtk rgai "auth token refresh" # Intent-aware code search
rtk rgai auth token refresh --compact # Unquoted multi-word query
rtk rgai "auth token refresh" --json # Machine-readable output
```

Refer to CLAUDE.md for full command reference.
15 changes: 13 additions & 2 deletions hooks/rtk-rewrite.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# RTK auto-rewrite hook for Claude Code PreToolUse:Bash
# Transparently rewrites raw commands to their rtk equivalents.
# Outputs JSON with updatedInput to modify the command before execution.
# Source of truth: hooks/rtk-rewrite.sh (keep .claude/hooks copy in sync)

# Guards: skip silently if dependencies missing
if ! command -v rtk &>/dev/null || ! command -v jq &>/dev/null; then
Expand Down Expand Up @@ -88,10 +89,20 @@ elif echo "$MATCH_CMD" | grep -qE '^cargo[[:space:]]+fmt([[:space:]]|$)'; then
REWRITTEN="${ENV_PREFIX}$(echo "$CMD_BODY" | sed 's/^cargo fmt/rtk cargo fmt/')"

# --- File operations ---
# Search priority (mandatory): rgai > rg > grep
# Tier 1: semantic intent search (grepai/rgai) -> rtk rgai
# Tier 2: exact search via ripgrep -> rtk grep (rtk grep runs rg -> grep fallback internally)
# Tier 3: exact search via grep -> rtk grep
elif echo "$MATCH_CMD" | grep -qE '^(grepai|rgai)[[:space:]]+search([[:space:]]|$)'; then
REWRITTEN="${ENV_PREFIX}$(echo "$CMD_BODY" | sed -E 's/^(grepai|rgai)[[:space:]]+search[[:space:]]+/rtk rgai /')"
elif echo "$MATCH_CMD" | grep -qE '^rgai[[:space:]]+'; then
REWRITTEN="${ENV_PREFIX}$(echo "$CMD_BODY" | sed -E 's/^rgai[[:space:]]+/rtk rgai /')"
elif echo "$MATCH_CMD" | grep -qE '^cat[[:space:]]+'; then
REWRITTEN="${ENV_PREFIX}$(echo "$CMD_BODY" | sed 's/^cat /rtk read /')"
elif echo "$MATCH_CMD" | grep -qE '^(rg|grep)[[:space:]]+'; then
REWRITTEN="${ENV_PREFIX}$(echo "$CMD_BODY" | sed -E 's/^(rg|grep) /rtk grep /')"
elif echo "$MATCH_CMD" | grep -qE '^rg[[:space:]]+'; then
REWRITTEN="${ENV_PREFIX}$(echo "$CMD_BODY" | sed -E 's/^rg /rtk grep /')"
elif echo "$MATCH_CMD" | grep -qE '^grep[[:space:]]+'; then
REWRITTEN="${ENV_PREFIX}$(echo "$CMD_BODY" | sed -E 's/^grep /rtk grep /')"
elif echo "$MATCH_CMD" | grep -qE '^ls([[:space:]]|$)'; then
REWRITTEN="${ENV_PREFIX}$(echo "$CMD_BODY" | sed 's/^ls/rtk ls/')"
elif echo "$MATCH_CMD" | grep -qE '^tree([[:space:]]|$)'; then
Expand Down
46 changes: 38 additions & 8 deletions hooks/test-rtk-rewrite.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
# Test suite for rtk-rewrite.sh
# Feeds mock JSON through the hook and verifies the rewritten commands.
#
# Usage: bash ~/.claude/hooks/test-rtk-rewrite.sh
# Usage: bash hooks/test-rtk-rewrite.sh
# Override hook path: HOOK=/path/to/rtk-rewrite.sh bash hooks/test-rtk-rewrite.sh

HOOK="$HOME/.claude/hooks/rtk-rewrite.sh"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
HOOK="${HOOK:-$SCRIPT_DIR/rtk-rewrite.sh}"
PASS=0
FAIL=0
TOTAL=0
Expand Down Expand Up @@ -109,6 +111,22 @@ test_rewrite "rg pattern src/" \
"rg pattern src/" \
"rtk grep pattern src/"

test_rewrite "grepai search query" \
"grepai search auth middleware" \
"rtk rgai auth middleware"

test_rewrite "grepai search with flags" \
"grepai search \"error handler\" --json --compact" \
"rtk rgai \"error handler\" --json --compact"

test_rewrite "rgai search query (priority over rg/grep)" \
"rgai search auth middleware --compact" \
"rtk rgai auth middleware --compact"

test_rewrite "plain rgai" \
"rgai auth middleware --json" \
"rtk rgai auth middleware --json"

test_rewrite "cargo test" \
"cargo test" \
"rtk cargo test"
Expand Down Expand Up @@ -149,6 +167,18 @@ test_rewrite "env + docker compose" \
"COMPOSE_PROJECT_NAME=test docker compose up -d" \
"COMPOSE_PROJECT_NAME=test rtk docker compose up -d"

test_rewrite "env + grepai search" \
"NODE_ENV=test grepai search token refresh --json" \
"NODE_ENV=test rtk rgai token refresh --json"

test_rewrite "env + rg exact search" \
"RG_IGNORE_DOT=1 rg token src/" \
"RG_IGNORE_DOT=1 rtk grep token src/"

test_rewrite "env + grep exact search" \
"LC_ALL=C grep -rn token src/" \
"LC_ALL=C rtk grep -rn token src/"

echo ""

# ---- SECTION 3: New patterns ----
Expand Down Expand Up @@ -193,17 +223,17 @@ test_rewrite "docker exec -it db psql" \
"docker exec -it db psql" \
"rtk docker exec -it db psql"

test_rewrite "find (NOT rewritten — different arg format)" \
test_rewrite "find with native args" \
"find . -name '*.ts'" \
""
"rtk find . -name '*.ts'"

test_rewrite "tree (NOT rewritten — different arg format)" \
test_rewrite "tree with path arg" \
"tree src/" \
""
"rtk tree src/"

test_rewrite "wget (NOT rewritten — different arg format)" \
test_rewrite "wget URL" \
"wget https://example.com/file" \
""
"rtk wget https://example.com/file"

test_rewrite "gh api repos/owner/repo" \
"gh api repos/owner/repo" \
Expand Down
Loading