mirror of
https://github.com/rtk-ai/rtk.git
synced 2026-09-19 07:33:17 +08:00
7d76af84b9
* fix(cicd): Add security check on dev branch PR add security check cicd on dev branch PR Signed-off-by: aesoft <43991222+aeppling@users.noreply.github.com> * fix: enrich telemetry with install_method and token savings - Add install_method detection (homebrew/cargo/script/nix/other) - Add tokens_saved_24h and tokens_saved_total to payload - Add Tracker::total_tokens_saved() and Tracker::tokens_saved_24h() methods - Point telemetry to new dedicated rtk-telemetry service Signed-off-by: Patrick szymkowiak <patrick.szymkowiak@innovtech.eu> * fix: detect install method on Windows paths Add backslash variants for .cargo\bin and .local\bin detection Signed-off-by: Patrick szymkowiak <patrick.szymkowiak@innovtech.eu> * fix: enrich telemetry with install_method and token savings (#432) - Add install_method detection (homebrew/cargo/script/nix/other) - Add tokens_saved_24h and tokens_saved_total to payload - Add Tracker::total_tokens_saved() and Tracker::tokens_saved_24h() methods - Point telemetry to new dedicated rtk-telemetry service Signed-off-by: Patrick szymkowiak <patrick.szymkowiak@innovtech.eu> * fix: 4 critical bugs — git exit code, jq warning, npm run doubling, pnpm build filter (#458) * fix: propagate exit code 128 when rtk git status runs outside a repo (#435) Previously printed "Not a git repository" to stdout and returned exit 0. Now prints to stderr and exits with git's actual exit code (128). Signed-off-by: Patrick szymkowiak <patrick.szymkowiak@innovtech.eu> * fix: warn when jq is not installed instead of silent exit (#430) Hook now prints a warning to stderr before exiting cleanly, so users know the rewrite pipeline is not functioning. Signed-off-by: Patrick szymkowiak <patrick.szymkowiak@innovtech.eu> * fix: strip leading 'run' arg to prevent npm run run doubling (#438) When user types 'rtk npm run build', args contain ["run", "build"]. Since npm_cmd always prepends 'run', this caused 'npm run run build'. Now strips the leading 'run' from args if present. Signed-off-by: Patrick szymkowiak <patrick.szymkowiak@innovtech.eu> * fix: route pnpm build through generic passthrough instead of Next.js filter (#454) pnpm build was hardcoded to next_cmd::run which misparses Vite/other framework output as errors. Now uses generic passthrough. Signed-off-by: Patrick szymkowiak <patrick.szymkowiak@innovtech.eu> * docs: bump README version to 0.28.0 Signed-off-by: Patrick szymkowiak <patrick.szymkowiak@innovtech.eu> --------- Signed-off-by: Patrick szymkowiak <patrick.szymkowiak@innovtech.eu> * fix: warn when rtk binary is not in PATH instead of silent exit (#430) (#465) Applies the same fix as jq — all silent exits now warn on stderr. Signed-off-by: Patrick szymkowiak <patrick.szymkowiak@innovtech.eu> --------- Signed-off-by: aesoft <43991222+aeppling@users.noreply.github.com> Signed-off-by: Patrick szymkowiak <patrick.szymkowiak@innovtech.eu> Co-authored-by: aesoft <43991222+aeppling@users.noreply.github.com>
606 lines
23 KiB
Markdown
606 lines
23 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
## Project Overview
|
|
|
|
**rtk (Rust Token Killer)** is a high-performance CLI proxy that minimizes LLM token consumption by filtering and compressing command outputs. It achieves 60-90% token savings on common development operations through smart filtering, grouping, truncation, and deduplication.
|
|
|
|
This is a fork with critical fixes for git argument parsing and modern JavaScript stack support (pnpm, vitest, Next.js, TypeScript, Playwright, Prisma).
|
|
|
|
### ⚠️ Name Collision Warning
|
|
|
|
**Two different "rtk" projects exist:**
|
|
- ✅ **This project**: Rust Token Killer (rtk-ai/rtk)
|
|
- ❌ **reachingforthejack/rtk**: Rust Type Kit (DIFFERENT - generates Rust types)
|
|
|
|
**Verify correct installation:**
|
|
```bash
|
|
rtk --version # Should show "rtk 0.28.0" (or newer)
|
|
rtk gain # Should show token savings stats (NOT "command not found")
|
|
```
|
|
|
|
If `rtk gain` fails, you have the wrong package installed.
|
|
|
|
## Development Commands
|
|
|
|
> **Note**: If rtk is installed, prefer `rtk <cmd>` over raw commands for token-optimized output.
|
|
> All commands work with passthrough support even for subcommands rtk doesn't specifically handle.
|
|
|
|
### Build & Run
|
|
```bash
|
|
# Development build
|
|
cargo build # raw
|
|
rtk cargo build # preferred (token-optimized)
|
|
|
|
# Release build (optimized)
|
|
cargo build --release
|
|
rtk cargo build --release
|
|
|
|
# Run directly
|
|
cargo run -- <command>
|
|
|
|
# Install locally
|
|
cargo install --path .
|
|
```
|
|
|
|
### Testing
|
|
```bash
|
|
# Run all tests
|
|
cargo test # raw
|
|
rtk cargo test # preferred (token-optimized)
|
|
|
|
# Run specific test
|
|
cargo test <test_name>
|
|
rtk cargo test <test_name>
|
|
|
|
# Run tests with output
|
|
cargo test -- --nocapture
|
|
rtk cargo test -- --nocapture
|
|
|
|
# Run tests in specific module
|
|
cargo test <module_name>::
|
|
rtk cargo test <module_name>::
|
|
```
|
|
|
|
### Linting & Quality
|
|
```bash
|
|
# Check without building
|
|
cargo check # raw
|
|
rtk cargo check # preferred (token-optimized)
|
|
|
|
# Format code
|
|
cargo fmt # passthrough (0% savings, but works)
|
|
|
|
# Run clippy lints
|
|
cargo clippy # raw
|
|
rtk cargo clippy # preferred (token-optimized)
|
|
|
|
# Check all targets
|
|
cargo clippy --all-targets
|
|
rtk cargo clippy --all-targets
|
|
```
|
|
|
|
### Package Building
|
|
```bash
|
|
# Build DEB package (Linux)
|
|
cargo install cargo-deb
|
|
cargo deb
|
|
|
|
# Build RPM package (Fedora/RHEL)
|
|
cargo install cargo-generate-rpm
|
|
cargo build --release
|
|
cargo generate-rpm
|
|
```
|
|
|
|
## Architecture
|
|
|
|
### Core Design Pattern
|
|
|
|
rtk uses a **command proxy architecture** with specialized modules for each output type:
|
|
|
|
```
|
|
main.rs (CLI entry)
|
|
→ Clap command parsing
|
|
→ Route to specialized modules
|
|
→ tracking.rs (SQLite) records token savings
|
|
```
|
|
|
|
### Key Architectural Components
|
|
|
|
**1. Command Modules** (src/*_cmd.rs, src/git.rs, src/container.rs)
|
|
- Each module handles a specific command type (git, grep, etc.)
|
|
- Responsible for executing underlying commands and transforming output
|
|
- Implement token-optimized formatting strategies
|
|
|
|
**2. Core Filtering** (src/filter.rs)
|
|
- Language-aware code filtering (Rust, Python, JavaScript, etc.)
|
|
- Filter levels: `none`, `minimal`, `aggressive`
|
|
- Strips comments, whitespace, and function bodies (aggressive mode)
|
|
- Used by `read` and `smart` commands
|
|
|
|
**3. Token Tracking** (src/tracking.rs)
|
|
- SQLite-based persistent storage (~/.local/share/rtk/tracking.db)
|
|
- Records: original_cmd, rtk_cmd, input_tokens, output_tokens, savings_pct
|
|
- 90-day retention policy with automatic cleanup
|
|
- Powers the `rtk gain` analytics command
|
|
- **Configurable database path**: Via `RTK_DB_PATH` env var or `config.toml`
|
|
- Priority: env var > config file > default location
|
|
|
|
**4. Configuration System** (src/config.rs, src/init.rs)
|
|
- Manages CLAUDE.md initialization (global vs local)
|
|
- Reads ~/.config/rtk/config.toml for user preferences
|
|
- `rtk init` command bootstraps LLM integration
|
|
- **New**: `tracking.database_path` field for custom DB location
|
|
|
|
**5. Tee Output Recovery** (src/tee.rs)
|
|
- Saves raw unfiltered output to `~/.local/share/rtk/tee/` on command failure
|
|
- Prints one-line hint `[full output: ~/.local/share/rtk/tee/...]` so LLMs can read instead of re-run
|
|
- Configurable via `[tee]` section in config.toml or env vars (`RTK_TEE`, `RTK_TEE_DIR`)
|
|
- Default mode: failures only, skip outputs < 500 chars, 20 file rotation, 1MB cap
|
|
- Silent error handling: tee failure never affects command output or exit code
|
|
|
|
**6. Shared Utilities** (src/utils.rs)
|
|
- Common functions for command modules: truncate, strip_ansi, execute_command
|
|
- Package manager auto-detection (pnpm/yarn/npm/npx)
|
|
- Consistent error handling and output formatting
|
|
- Used by all modern JavaScript/TypeScript tooling commands
|
|
|
|
### Command Routing Flow
|
|
|
|
All commands follow this pattern:
|
|
```rust
|
|
main.rs:Commands enum
|
|
→ match statement routes to module
|
|
→ module::run() executes logic
|
|
→ tracking::track_command() records metrics
|
|
→ Result<()> propagates errors
|
|
```
|
|
|
|
### Proxy Mode
|
|
|
|
**Purpose**: Execute commands without filtering but track usage for metrics.
|
|
|
|
**Usage**: `rtk proxy <command> [args...]`
|
|
|
|
**Benefits**:
|
|
- **Bypass RTK filtering**: Workaround bugs or get full unfiltered output
|
|
- **Track usage metrics**: Measure which commands Claude uses most (visible in `rtk gain --history`)
|
|
- **Guaranteed compatibility**: Always works even if RTK doesn't implement the command
|
|
- **Prototyping**: Test new commands before implementing optimized filtering
|
|
|
|
**Examples**:
|
|
```bash
|
|
# Full git log output (no truncation)
|
|
rtk proxy git log --oneline -20
|
|
|
|
# Raw npm output (no filtering)
|
|
rtk proxy npm install express
|
|
|
|
# Any command works
|
|
rtk proxy curl https://api.example.com/data
|
|
|
|
# Tracking shows 0% savings (expected)
|
|
rtk gain --history | grep proxy
|
|
```
|
|
|
|
**Tracking**: All proxy commands appear in `rtk gain --history` with 0% savings (input = output) but preserve usage statistics.
|
|
|
|
### Critical Implementation Details
|
|
|
|
**Git Argument Handling** (src/git.rs)
|
|
- Uses `trailing_var_arg = true` + `allow_hyphen_values = true` to properly handle git flags
|
|
- Auto-detects `--merges` flag to avoid conflicting with `--no-merges` injection
|
|
- Propagates git exit codes for CI/CD reliability (PR #5 fix)
|
|
|
|
**Output Filtering Strategy**
|
|
- Compact mode: Show only summary/failures
|
|
- Full mode: Available with `-v` verbosity flags
|
|
- Test output: Show only failures (90% token reduction)
|
|
- Git operations: Ultra-compressed confirmations ("ok ✓")
|
|
|
|
**Language Detection** (src/filter.rs)
|
|
- File extension-based with fallback heuristics
|
|
- Supports Rust, Python, JS/TS, Java, Go, C/C++, etc.
|
|
- Tokenization rules vary by language (comments, strings, blocks)
|
|
|
|
### Module Responsibilities
|
|
|
|
| Module | Purpose | Token Strategy |
|
|
|--------|---------|----------------|
|
|
| git.rs | Git operations | Stat summaries + compact diffs |
|
|
| grep_cmd.rs | Code search | Group by file, truncate lines |
|
|
| ls.rs | Directory listing | Tree format, aggregate counts |
|
|
| read.rs | File reading | Filter-level based stripping |
|
|
| runner.rs | Command execution | Stderr only (err), failures only (test) |
|
|
| log_cmd.rs | Log parsing | Deduplication with counts |
|
|
| json_cmd.rs | JSON inspection | Structure without values |
|
|
| lint_cmd.rs | ESLint/Biome linting | Group by rule, file summary (84% reduction) |
|
|
| tsc_cmd.rs | TypeScript compiler | Group by file/error code (83% reduction) |
|
|
| next_cmd.rs | Next.js build/dev | Route metrics, bundle stats only (87% reduction) |
|
|
| prettier_cmd.rs | Format checking | Files needing changes only (70% reduction) |
|
|
| playwright_cmd.rs | E2E test results | Failures only, grouped by suite (94% reduction) |
|
|
| prisma_cmd.rs | Prisma CLI | Strip ASCII art and verbose output (88% reduction) |
|
|
| gh_cmd.rs | GitHub CLI | Compact PR/issue/run views (26-87% reduction) |
|
|
| vitest_cmd.rs | Vitest test runner | Failures only with ANSI stripping (99.5% reduction) |
|
|
| pnpm_cmd.rs | pnpm package manager | Compact dependency trees (70-90% reduction) |
|
|
| ruff_cmd.rs | Ruff linter/formatter | JSON for check, text for format (80%+ reduction) |
|
|
| pytest_cmd.rs | Pytest test runner | State machine text parser (90%+ reduction) |
|
|
| mypy_cmd.rs | Mypy type checker | Group by file/error code (80% reduction) |
|
|
| pip_cmd.rs | pip/uv package manager | JSON parsing, auto-detect uv (70-85% reduction) |
|
|
| go_cmd.rs | Go commands | NDJSON for test, text for build/vet (80-90% reduction) |
|
|
| golangci_cmd.rs | golangci-lint | JSON parsing, group by rule (85% reduction) |
|
|
| tee.rs | Full output recovery | Save raw output to file on failure, print hint for LLM re-read |
|
|
| utils.rs | Shared utilities | Package manager detection, common formatting |
|
|
| discover/ | Claude Code history analysis | Scan JSONL sessions, classify commands, report missed savings |
|
|
|
|
## Performance Constraints
|
|
|
|
RTK has **strict performance targets** to maintain zero-overhead CLI experience:
|
|
|
|
| Metric | Target | Verification Method |
|
|
|--------|--------|---------------------|
|
|
| **Startup time** | <10ms | `hyperfine 'rtk git status' 'git status'` |
|
|
| **Memory overhead** | <5MB resident | `/usr/bin/time -l rtk git status` (macOS) |
|
|
| **Token savings** | 60-90% | Verify in tests with `count_tokens()` assertions |
|
|
| **Binary size** | <5MB stripped | `ls -lh target/release/rtk` |
|
|
|
|
**Performance regressions are release blockers** - always benchmark before/after changes:
|
|
|
|
```bash
|
|
# Before changes
|
|
hyperfine 'rtk git log -10' --warmup 3 > /tmp/before.txt
|
|
|
|
# After changes
|
|
cargo build --release
|
|
hyperfine 'target/release/rtk git log -10' --warmup 3 > /tmp/after.txt
|
|
|
|
# Compare (should be <10ms)
|
|
diff /tmp/before.txt /tmp/after.txt
|
|
```
|
|
|
|
**Why <10ms matters**: Claude Code users expect CLI tools to be instant. Any perceptible delay (>10ms) breaks the developer flow. RTK achieves this through:
|
|
- **Zero async overhead**: Single-threaded, no tokio runtime
|
|
- **Lazy regex compilation**: Compile once with `lazy_static!`, reuse forever
|
|
- **Minimal allocations**: Borrow over clone, in-place filtering
|
|
- **No user config**: Zero file I/O on startup (config loaded on-demand)
|
|
|
|
## Error Handling
|
|
|
|
RTK follows Rust best practices for error handling:
|
|
|
|
**Rules**:
|
|
- **anyhow::Result** for CLI binary (RTK is an application, not a library)
|
|
- **ALWAYS** use `.context("description")` with `?` operator
|
|
- **NO unwrap()** in production code (tests only - use `expect("explanation")` if needed)
|
|
- **Graceful degradation**: If filter fails, fallback to raw command execution
|
|
|
|
**Example**:
|
|
|
|
```rust
|
|
use anyhow::{Context, Result};
|
|
|
|
pub fn filter_git_log(input: &str) -> Result<String> {
|
|
let lines: Vec<_> = input
|
|
.lines()
|
|
.filter(|line| !line.is_empty())
|
|
.collect();
|
|
|
|
// ✅ RIGHT: Context on error
|
|
let hash = extract_hash(lines[0])
|
|
.context("Failed to extract commit hash from git log")?;
|
|
|
|
// ❌ WRONG: No context
|
|
let hash = extract_hash(lines[0])?;
|
|
|
|
// ❌ WRONG: Panic in production
|
|
let hash = extract_hash(lines[0]).unwrap();
|
|
|
|
Ok(format!("Commit: {}", hash))
|
|
}
|
|
```
|
|
|
|
**Fallback pattern** (critical for all filters):
|
|
|
|
```rust
|
|
// ✅ RIGHT: Fallback to raw command if filter fails
|
|
pub fn execute_with_filter(cmd: &str, args: &[&str]) -> Result<()> {
|
|
match get_filter(cmd) {
|
|
Some(filter) => match filter.apply(cmd, args) {
|
|
Ok(output) => println!("{}", output),
|
|
Err(e) => {
|
|
eprintln!("Filter failed: {}, falling back to raw", e);
|
|
execute_raw(cmd, args)?;
|
|
}
|
|
},
|
|
None => execute_raw(cmd, args)?,
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
// ❌ WRONG: Panic if no filter
|
|
pub fn execute_with_filter(cmd: &str, args: &[&str]) -> Result<()> {
|
|
let filter = get_filter(cmd).expect("Filter must exist");
|
|
filter.apply(cmd, args)?;
|
|
Ok(())
|
|
}
|
|
```
|
|
|
|
## Common Pitfalls
|
|
|
|
**Don't add async dependencies** (kills startup time)
|
|
- RTK is single-threaded by design
|
|
- Adding tokio/async-std adds ~5-10ms startup overhead
|
|
- Use blocking I/O with fallback to raw command
|
|
|
|
**Don't recompile regex at runtime** (kills performance)
|
|
- ❌ WRONG: `let re = Regex::new(r"pattern").unwrap();` inside function
|
|
- ✅ RIGHT: `lazy_static! { static ref RE: Regex = Regex::new(r"pattern").unwrap(); }`
|
|
|
|
**Don't panic on filter failure** (breaks user workflow)
|
|
- Always fallback to raw command execution
|
|
- Log error to stderr, execute original command unchanged
|
|
|
|
**Don't assume command output format** (breaks across versions)
|
|
- Test with real fixtures from multiple versions
|
|
- Use flexible regex patterns that tolerate format changes
|
|
|
|
**Don't skip cross-platform testing** (macOS ≠ Linux ≠ Windows)
|
|
- Shell escaping differs: bash/zsh vs PowerShell
|
|
- Path separators differ: `/` vs `\`
|
|
- Line endings differ: LF vs CRLF
|
|
|
|
**Don't break pipe compatibility** (users expect Unix behavior)
|
|
- `rtk git status | grep modified` must work
|
|
- Preserve stdout/stderr separation
|
|
- Respect exit codes (0 = success, non-zero = failure)
|
|
|
|
## Fork-Specific Features
|
|
|
|
### PR #5: Git Argument Parsing Fix (CRITICAL)
|
|
- **Problem**: Git flags like `--oneline`, `--cached` were rejected
|
|
- **Solution**: Fixed Clap parsing with proper trailing_var_arg configuration
|
|
- **Impact**: All git commands now accept native git flags
|
|
|
|
### PR #6: pnpm Support
|
|
- **New Commands**: `rtk pnpm list`, `rtk pnpm outdated`, `rtk pnpm install`
|
|
- **Token Savings**: 70-90% reduction on package manager operations
|
|
- **Security**: Package name validation prevents command injection
|
|
|
|
### PR #9: Modern JavaScript/TypeScript Tooling (2026-01-29)
|
|
- **New Commands**: 6 commands for T3 Stack workflows
|
|
- `rtk lint`: ESLint/Biome with grouped rule violations (84% reduction)
|
|
- `rtk tsc`: TypeScript compiler errors grouped by file/code (83% reduction)
|
|
- `rtk next`: Next.js build with route/bundle metrics (87% reduction)
|
|
- `rtk prettier`: Format checker showing files needing changes (70% reduction)
|
|
- `rtk playwright`: E2E test results showing failures only (94% reduction)
|
|
- `rtk prisma`: Prisma CLI without ASCII art (88% reduction)
|
|
- **Shared Infrastructure**: utils.rs module for package manager auto-detection
|
|
- **Features**: Exit code preservation, error grouping, consistent formatting
|
|
- **Testing**: Validated on a production T3 Stack project
|
|
|
|
### Python & Go Support (2026-02-12)
|
|
- **Python Commands**: 3 commands for Python development workflows
|
|
- `rtk ruff check/format`: Ruff linter/formatter with JSON (check) and text (format) parsing (80%+ reduction)
|
|
- `rtk pytest`: Pytest test runner with state machine text parser (90%+ reduction)
|
|
- `rtk pip list/outdated/install`: pip package manager with auto-detect uv (70-85% reduction)
|
|
- **Go Commands**: 4 commands via sub-enum for Go ecosystem
|
|
- `rtk go test`: NDJSON line-by-line parser for interleaved events (90%+ reduction)
|
|
- `rtk go build`: Text filter showing errors only (80% reduction)
|
|
- `rtk go vet`: Text filter for issues (75% reduction)
|
|
- `rtk golangci-lint`: JSON parsing grouped by rule (85% reduction)
|
|
- **Architecture**: Standalone Python commands (mirror lint/prettier), Go sub-enum (mirror git/cargo)
|
|
- **Patterns**: JSON for structured output (ruff check, golangci-lint, pip), NDJSON streaming (go test), text state machine (pytest), text filters (go build/vet, ruff format)
|
|
|
|
## Testing Strategy
|
|
|
|
### TDD Workflow (mandatory)
|
|
All code follows Red-Green-Refactor. See `.claude/skills/rtk-tdd/` for the full workflow and Rust-idiomatic patterns. See `.claude/skills/rtk-tdd/references/testing-patterns.md` for RTK-specific patterns and untested module backlog.
|
|
|
|
### Test Architecture
|
|
- **Unit tests**: Embedded `#[cfg(test)] mod tests` in each module (105+ tests, 25+ files)
|
|
- **Smoke tests**: `scripts/test-all.sh` (69 assertions on all commands)
|
|
- **Dominant pattern**: raw string input -> filter function -> assert output contains/excludes
|
|
|
|
### Pre-commit gate
|
|
```bash
|
|
cargo fmt --all --check && rtk cargo clippy --all-targets && rtk cargo test
|
|
```
|
|
|
|
### Test commands
|
|
```bash
|
|
cargo test # All tests
|
|
cargo test filter::tests:: # Module-specific
|
|
cargo test -- --nocapture # With stdout
|
|
bash scripts/test-all.sh # Smoke tests (installed binary required)
|
|
```
|
|
|
|
## Dependencies
|
|
|
|
Core dependencies (see Cargo.toml):
|
|
- **clap**: CLI parsing with derive macros
|
|
- **anyhow**: Error handling
|
|
- **rusqlite**: SQLite for tracking database
|
|
- **regex**: Pattern matching for filtering
|
|
- **ignore**: gitignore-aware file traversal
|
|
- **colored**: Terminal output formatting
|
|
- **serde/serde_json**: Configuration and JSON parsing
|
|
|
|
## Build Optimizations
|
|
|
|
Release profile (Cargo.toml:31-36):
|
|
- `opt-level = 3`: Maximum optimization
|
|
- `lto = true`: Link-time optimization
|
|
- `codegen-units = 1`: Single codegen for better optimization
|
|
- `strip = true`: Remove debug symbols
|
|
- `panic = "abort"`: Smaller binary size
|
|
|
|
## CI/CD
|
|
|
|
GitHub Actions workflow (.github/workflows/release.yml):
|
|
- Multi-platform builds (macOS, Linux x86_64/ARM64, Windows)
|
|
- DEB/RPM package generation
|
|
- Automated releases on version tags (v*)
|
|
- Checksums for binary verification
|
|
|
|
## Build Verification (Mandatory)
|
|
|
|
**CRITICAL**: After ANY Rust file edits, ALWAYS run the full quality check pipeline before committing:
|
|
|
|
```bash
|
|
cargo fmt --all && cargo clippy --all-targets && cargo test --all
|
|
```
|
|
|
|
**Rules**:
|
|
- Never commit code that hasn't passed all 3 checks
|
|
- Fix ALL clippy warnings before moving on (zero tolerance)
|
|
- If build fails, fix it immediately before continuing to next task
|
|
- Pre-commit hook will auto-enforce this (see `.claude/hooks/bash/pre-commit-format.sh`)
|
|
|
|
**Why**: RTK is a production CLI tool used by developers in their workflows. Bugs break developer productivity. Quality gates prevent regressions and maintain user trust.
|
|
|
|
**Performance verification** (for filter changes):
|
|
|
|
```bash
|
|
# Benchmark before/after
|
|
hyperfine 'rtk git log -10' --warmup 3
|
|
cargo build --release
|
|
hyperfine 'target/release/rtk git log -10' --warmup 3
|
|
|
|
# Memory profiling
|
|
/usr/bin/time -l target/release/rtk git status # macOS
|
|
/usr/bin/time -v target/release/rtk git status # Linux
|
|
```
|
|
|
|
## Testing Policy
|
|
|
|
**Manual testing is REQUIRED** for filter changes and new commands:
|
|
|
|
- **For new filters**: Test with real command (`rtk <cmd>`), verify output matches expectations
|
|
- Example: `rtk git log -10` → inspect output, verify condensed correctly
|
|
- Example: `rtk cargo test` → verify only failures shown, not full output
|
|
|
|
- **For hook changes**: Test in real Claude Code session, verify command rewriting works
|
|
- Create test Claude Code session
|
|
- Type raw command (e.g., `git status`)
|
|
- Verify hook rewrites to `rtk git status`
|
|
|
|
- **For performance**: Run `hyperfine` comparison (before/after), verify <10ms startup
|
|
- Benchmark baseline: `hyperfine 'rtk git status' --warmup 3`
|
|
- Make changes, rebuild
|
|
- Benchmark again: `hyperfine 'target/release/rtk git status' --warmup 3`
|
|
- Compare results: startup time should be <10ms
|
|
|
|
- **For cross-platform**: Test on macOS + Linux (Docker) + Windows (CI), verify shell escaping
|
|
- macOS (zsh): Test locally
|
|
- Linux (bash): Use Docker `docker run --rm -v $(pwd):/rtk -w /rtk rust:latest cargo test`
|
|
- Windows (PowerShell): Trust CI/CD pipeline or test manually if available
|
|
|
|
**Anti-pattern**: Running only automated tests (`cargo test`, `cargo clippy`) without actually executing `rtk <cmd>` and inspecting output.
|
|
|
|
**Example**: If fixing the `git log` filter, run `rtk git log -10` and verify:
|
|
1. Output is condensed (shorter than raw `git log -10`)
|
|
2. Critical info preserved (commit hashes, messages)
|
|
3. Format is readable and consistent
|
|
4. Exit code matches git's exit code (0 for success)
|
|
|
|
## Working Directory Confirmation
|
|
|
|
**ALWAYS confirm working directory before starting any work**:
|
|
|
|
```bash
|
|
pwd # Verify you're in the rtk project root
|
|
git branch # Verify correct branch (main, feature/*, etc.)
|
|
```
|
|
|
|
**Never assume** which project to work in. Always verify before file operations.
|
|
|
|
## Avoiding Rabbit Holes
|
|
|
|
**Stay focused on the task**. Do not make excessive operations to verify external APIs, documentation, or edge cases unless explicitly asked.
|
|
|
|
**Rule**: If verification requires more than 3-4 exploratory commands, STOP and ask the user whether to continue or trust available info.
|
|
|
|
**Examples of rabbit holes to avoid**:
|
|
- Excessive regex pattern testing (trust snapshot tests, don't manually verify 20 edge cases)
|
|
- Deep diving into external command documentation (use fixtures, don't research git/cargo internals)
|
|
- Over-testing cross-platform behavior (test macOS + Linux, trust CI for Windows)
|
|
- Verifying API signatures across multiple crate versions (use docs.rs if needed, don't clone repos)
|
|
|
|
**When to stop and ask**:
|
|
- "Should I research X external API behavior?" → ASK if it requires >3 commands
|
|
- "Should I test Y edge case?" → ASK if not mentioned in requirements
|
|
- "Should I verify Z across N platforms?" → ASK if N > 2
|
|
|
|
## Plan Execution Protocol
|
|
|
|
When user provides a numbered plan (QW1-QW4, Phase 1-5, sprint tasks, etc.):
|
|
|
|
1. **Execute sequentially**: Follow plan order unless explicitly told otherwise
|
|
2. **Commit after each logical step**: One commit per completed phase/task
|
|
3. **Never skip or reorder**: If a step is blocked, report it and ask before proceeding
|
|
4. **Track progress**: Use task list (TaskCreate/TaskUpdate) for plans with 3+ steps
|
|
5. **Validate assumptions**: Before starting, verify all referenced file paths exist and working directory is correct
|
|
|
|
**Why**: Plan-driven execution produces better outcomes than ad-hoc implementation. Structured plans help maintain focus and prevent scope creep.
|
|
|
|
|
|
## Filter Development Checklist
|
|
|
|
When adding a new filter (e.g., `rtk newcmd`):
|
|
|
|
### Implementation
|
|
- [ ] Create filter module in `src/<cmd>_cmd.rs` (or extend existing)
|
|
- [ ] Add `lazy_static!` regex patterns for parsing (compile once, reuse)
|
|
- [ ] Implement fallback to raw command on error (graceful degradation)
|
|
- [ ] Preserve exit codes (`std::process::exit(code)` if non-zero)
|
|
|
|
### Testing
|
|
- [ ] Write snapshot test with real command output fixture (`tests/fixtures/<cmd>_raw.txt`)
|
|
- [ ] Verify token savings ≥60% with `count_tokens()` assertion
|
|
- [ ] Test cross-platform shell escaping (macOS, Linux, Windows)
|
|
- [ ] Write unit tests for edge cases (empty output, errors, unicode, ANSI codes)
|
|
|
|
### Integration
|
|
- [ ] Register filter in main.rs Commands enum
|
|
- [ ] Update README.md with new command support and token savings %
|
|
- [ ] Update CHANGELOG.md with feature description
|
|
|
|
### Quality Gates
|
|
- [ ] Run `cargo fmt --all && cargo clippy --all-targets && cargo test`
|
|
- [ ] Benchmark startup time with `hyperfine` (verify <10ms)
|
|
- [ ] Test manually: `rtk <cmd>` and inspect output for correctness
|
|
- [ ] Verify fallback: Break filter intentionally, confirm raw command executes
|
|
|
|
### Documentation
|
|
- [ ] Add command to this CLAUDE.md Module Responsibilities table
|
|
- [ ] Document token savings % (from tests)
|
|
- [ ] Add usage examples to README.md
|
|
|
|
**Example workflow** (adding `rtk newcmd`):
|
|
|
|
```bash
|
|
# 1. Create module
|
|
touch src/newcmd_cmd.rs
|
|
|
|
# 2. Write test first (TDD)
|
|
echo 'raw command output fixture' > tests/fixtures/newcmd_raw.txt
|
|
# Add test in src/newcmd_cmd.rs
|
|
|
|
# 3. Implement filter
|
|
# Add lazy_static regex, implement logic, add fallback
|
|
|
|
# 4. Quality checks
|
|
cargo fmt --all && cargo clippy --all-targets && cargo test
|
|
|
|
# 5. Benchmark
|
|
hyperfine 'rtk newcmd args'
|
|
|
|
# 6. Manual test
|
|
rtk newcmd args
|
|
# Inspect output, verify condensed
|
|
|
|
# 7. Document
|
|
# Update README.md, CHANGELOG.md, this file
|
|
```
|