Skip to content
Closed
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 '^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 '^(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 '^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 Policy

**Search priority (mandatory): 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 (grepai-style)
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 policy: `rgai > rg > grep` (use `rtk rgai` first)
- [ ] Use `rtk` for ALL git/pnpm/test/vitest commands
- [ ] Check savings: `rtk gain`

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

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

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Source: internal migration benchmark artifacts (private repository)" — this benchmark is not reproducible or verifiable by contributors. Either publish the benchmark script/dataset or move this table to internal docs.

### Migration Search Benchmark Snapshot (February 14, 2026)

Source: internal migration benchmark artifacts (private repository)

| Scenario | Agent | Est. tokens | Unique files | Files / 1K tokens |
|---|---|---:|---:|---:|
| token_opt | grep | 14106 | 94 | 6.66 |
| token_opt | rg | 14008 | 102 | 7.28 |
| token_opt | rgai | 3428 | 58 | 16.92 |
| quality_norm | grep | 14106 | 94 | 6.66 |
| quality_norm | rg | 14065 | 103 | 7.32 |
| quality_norm | rgai | 7349 | 103 | 14.02 |

Methodology and raw artifacts are private and not publicly linked.

## Search Priority Policy

**Search priority (mandatory): 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 +154,9 @@ 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 (grepai-style)
rtk grep "pattern" . # Exact/regex search (internal rg -> grep fallback)
rtk rgai auth token --path src # Unquoted multi-word query + explicit path
```

### Git
Expand Down Expand Up @@ -400,6 +426,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.

**Predictable 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 +522,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 Expand Up @@ -531,6 +566,7 @@ If you prefer Claude Code to **suggest** rtk usage rather than automatically rew
- You're learning rtk patterns and want visibility into the rewrite logic
- You prefer Claude Code to make explicit decisions rather than transparent rewrites
- You want to preserve exact command execution for debugging
- You suspect `strangeness tax` in a specific workflow and want explicit command choice

#### Suggest Hook Setup

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 Policy

**Search priority (mandatory): 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
17 changes: 17 additions & 0 deletions hooks/rtk-awareness.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,22 @@ 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"`

## Search Priority Policy

**Search priority (mandatory): rgai > rg > grep.**

- Use `rtk rgai` first for semantic/intention-based discovery.
- Use `rtk grep` for exact/regex matching.
- `rtk grep` internally uses `rg -> grep` backend fallback.

## 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 '^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 '^(grepai|rgai)[[:space:]]+search([[:space:]]|$)'; then
REWRITTEN="${ENV_PREFIX}$(echo "$CMD_BODY" | sed -E 's/^(grepai|rgai)[[:space:]]+search[[:space:]]+/rtk rgai /')"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This rewrite rule sends grepai search X to rtk rgai X, but rtk rgai is not a valid subcommand. The hook will silently transform a working command (grepai search) into a broken one (rtk rgai).

This rule should land together with the rtk rgai implementation.

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 '^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" \
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These three tests changed from expecting no rewrite (empty string) to expecting rewrites (rtk find, rtk tree, rtk wget). This is a behavior change unrelated to the rgai search policy — should be in a separate PR.

"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