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
8 changes: 6 additions & 2 deletions .claude/skills/rtk-triage/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,13 @@ gh api "repos/{owner}/{repo}/collaborators" --jq '.[].login'

**PRs** :
```bash
gh pr list --state open --limit 60 \
# Fetcher toutes les PRs ouvertes — paginer si nécessaire (gh limite à 200 par appel)
gh pr list --state open --limit 200 \
--json number,title,author,createdAt,updatedAt,additions,deletions,changedFiles,isDraft,mergeable,reviewDecision,statusCheckRollup,body

# Si le repo a >200 PRs ouvertes, relancer avec --search pour paginer :
# gh pr list --state open --limit 200 --search "is:pr is:open sort:updated-desc" ...

# Pour chaque PR, récupérer les fichiers modifiés (nécessaire pour overlap detection)
# Prioriser les PRs candidates (même domaine, même auteur)
gh pr view {num} --json files --jq '[.files[].path] | join(",")'
Expand Down Expand Up @@ -232,6 +236,6 @@ Croisement issues × PRs. {N} PRs ouvertes, {N} issues ouvertes.

- Langue : argument `en`/`fr`. Défaut : `fr`. Les commentaires GitHub restent toujours en anglais.
- Ne jamais poster de commentaires GitHub sans validation utilisateur (AskUserQuestion).
- Si >150 issues ou >60 PRs : prévenir l'utilisateur, proposer de filtrer par label ou date.
- Si >200 issues ou >200 PRs : prévenir l'utilisateur et paginer (relancer avec `--search` ou `gh api` avec pagination).
- L'analyse croisée (Phase 3) est toujours exécutée — c'est la valeur ajoutée de ce skill.
- Le fichier claudedocs est sauvegardé automatiquement sauf si l'utilisateur dit "no save".
127 changes: 127 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
# Copilot Instructions for rtk

**rtk (Rust Token Killer)** is a CLI proxy that filters and compresses command outputs before they reach an LLM context, saving 60–90% of tokens. It wraps common tools (`git`, `cargo`, `grep`, `pnpm`, `go`, etc.) and outputs condensed summaries instead of raw output.

## Using rtk in this session

**Always prefix commands with `rtk` when running shell commands** — this is the entire point of the project and reduces token consumption for every operation you perform.

```bash
# Instead of: Use:
git status rtk git status
git log -10 rtk git log -10
cargo test rtk cargo test
cargo clippy --all-targets rtk cargo clippy --all-targets
grep -r "pattern" src/ rtk grep -r "pattern" src/
```

**rtk meta-commands** (always use these directly, no prefix needed):
```bash
rtk gain # Show token savings analytics for this session
rtk gain --history # Full command history with per-command savings
rtk discover # Scan session history for missed rtk opportunities
rtk proxy <cmd> # Run a command raw (no filtering) but still track it
```

**Verify rtk is installed before starting:**
```bash
rtk --version # Should print: rtk X.Y.Z
rtk gain # Should show a dashboard (not "command not found")
```

> ⚠️ **Name collision**: `rtk gain` failing means you have `reachingforthejack/rtk` (Rust Type Kit) installed instead of this project. Run `which rtk` and check the binary source.
## Build, Test & Lint

```bash
# Development build
cargo build

# Run all tests
cargo test

# Run a single test by name
cargo test test_filter_git_log

# Run all tests in a module
cargo test git::tests::

# Run tests with stdout
cargo test -- --nocapture

# Pre-commit gate (must all pass before any PR)
cargo fmt --all --check && cargo clippy --all-targets && cargo test

# Smoke tests (requires installed binary)
bash scripts/test-all.sh
```

PRs target the **`develop`** branch, not `main`. All commits require a DCO sign-off (`git commit -s`).

## Architecture

```
main.rs ← Clap Commands enum → specialized module (git.rs, *_cmd.rs, etc.)
execute subprocess
filter/compress output
tracking::TimedExecution → SQLite (~/.local/share/rtk/tracking.db)
```

Key modules:
- **`main.rs`** — Clap `Commands` enum routes every subcommand to its module. Each arm calls `tracking::TimedExecution::start()` before running, then `.track(...)` after.
- **`filter.rs`** — Language-aware filtering with `FilterLevel` (`none` / `minimal` / `aggressive`) and `Language` enum. Used by `read` and `smart` commands.
- **`tracking.rs`** — SQLite persistence for token savings, scoped per project path. Powers `rtk gain`.
- **`tee.rs`** — On filter failure, saves raw output to `~/.local/share/rtk/tee/` and prints a one-line hint so the LLM can re-read without re-running the command.
- **`utils.rs`** — Shared helpers: `truncate`, `strip_ansi`, `execute_command`, package-manager auto-detection (pnpm/yarn/npm/npx).

New commands follow this structure: one file `src/<cmd>_cmd.rs` with a `pub fn run(...)` entry point, registered in the `Commands` enum in `main.rs`.

## Key Conventions

### Error handling
- Use `anyhow::Result` throughout (this is a binary, not a library).
- Always attach context: `operation.context("description")?` — never bare `?` without context.
- No `unwrap()` in production code; `expect("reason")` is acceptable only in tests.
- Every filter must fall back to raw command execution on error — never break the user's workflow.

### Regex
- Compile once with `lazy_static!`, never inside a function body:
```rust
lazy_static! {
static ref RE: Regex = Regex::new(r"pattern").unwrap();
}
```

### Testing
- Unit tests live **inside the module file** in `#[cfg(test)] mod tests { ... }` — not in `tests/`.
- Fixtures are real captured command output in `tests/fixtures/<cmd>_raw.txt`, loaded with `include_str!("../tests/fixtures/...")`.
- Each test module defines its own local `fn count_tokens(text: &str) -> usize` (word-split approximation) — there is no shared utility for this.
- Token savings assertions use `assert!(savings >= 60.0, ...)`.
- Snapshot tests use `assert_snapshot!()` from the `insta` crate; review with `cargo insta review`.

### Adding a new command
1. Create `src/<cmd>_cmd.rs` with `pub fn run(...)`.
2. Add `mod <cmd>_cmd;` at the top of `main.rs`.
3. Add a variant to the `Commands` enum with `#[arg(trailing_var_arg = true, allow_hyphen_values = true)]` for pass-through flags.
4. Route the variant in the `match` block, wrapping execution with `tracking::TimedExecution`.
5. Write a fixture from real output, then unit tests in the module file.
6. Update `README.md` (command list + savings %) and `CHANGELOG.md`.

### Exit codes
Preserve the underlying command's exit code. Use `std::process::exit(code)` when the child process exits non-zero.

### Performance constraints
- Startup must stay under 10ms — no async runtime (no `tokio`/`async-std`).
- No blocking I/O at startup; config is loaded on-demand.
- Binary size target: <5 MB stripped.

### Branch naming
```
fix(scope): short-description
feat(scope): short-description
chore(scope): short-description
```
`scope` is the affected component (e.g. `git`, `filter`, `tracking`).
12 changes: 12 additions & 0 deletions .github/hooks/rtk-rewrite.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"hooks": {
"PreToolUse": [
{
"type": "command",
"command": "rtk hook",
"cwd": ".",
"timeout": 5
}
]
}
}
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "0.30.1"
".": "0.31.0"
}
6 changes: 3 additions & 3 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -293,12 +293,12 @@ SHARED utils.rs Helpers N/A ✓
tee.rs Full output recovery N/A ✓
```

**Total: 66 modules** (44 command modules + 22 infrastructure modules)
**Total: 67 modules** (45 command modules + 22 infrastructure modules)

### Module Count Breakdown

- **Command Modules**: 34 (directly exposed to users)
- **Infrastructure Modules**: 20 (utils, filter, tracking, tee, config, init, gain, toml_filter, verify_cmd, etc.)
- **Command Modules**: 45 (directly exposed to users)
- **Infrastructure Modules**: 22 (utils, filter, tracking, tee, config, init, gain, toml_filter, verify_cmd, trust, etc.)
- **Git Commands**: 7 operations (status, diff, log, add, commit, push, branch/checkout)
- **JS/TS Tooling**: 8 modules (modern frontend/fullstack development)
- **Python Tooling**: 3 modules (ruff, pytest, pip)
Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ All notable changes to rtk (Rust Token Killer) will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.31.0](https://github.com/rtk-ai/rtk/compare/v0.30.1...v0.31.0) (2026-03-19)


### Features

* 9-tool AI agent support + emoji removal ([#704](https://github.com/rtk-ai/rtk/issues/704)) ([737dada](https://github.com/rtk-ai/rtk/commit/737dada4a56c0d7a482cc438e7280340d634f75d))

## [0.30.1](https://github.com/rtk-ai/rtk/compare/v0.30.0...v0.30.1) (2026-03-18)


Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "rtk"
version = "0.30.1"
version = "0.31.0"
edition = "2021"
authors = ["Patrick Szymkowiak"]
description = "Rust Token Killer - High-performance CLI proxy to minimize LLM token consumption"
Expand Down
23 changes: 22 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ rtk gain # Should show token savings stats
# 1. Install hook for Claude Code (recommended)
rtk init --global
# Follow instructions to register in ~/.claude/settings.json
# Claude Code only by default (use --opencode for OpenCode)
# Claude Code only by default (use --opencode for OpenCode, --gemini for Gemini CLI)

# 2. Restart Claude Code, then test
git status # Automatically rewritten to rtk git status
Expand Down Expand Up @@ -287,6 +287,27 @@ rtk init --show # Verify installation

After install, **restart Claude Code**.

## Gemini CLI Support (Global)

RTK supports Gemini CLI via a native Rust hook processor. The hook intercepts `run_shell_command` tool calls and rewrites them to `rtk` equivalents using the same rewrite engine as Claude Code.

**Install Gemini hook:**
```bash
rtk init -g --gemini
```

**What it creates:**
- `~/.gemini/hooks/rtk-hook-gemini.sh` (thin wrapper calling `rtk hook gemini`)
- `~/.gemini/GEMINI.md` (RTK awareness instructions)
- Patches `~/.gemini/settings.json` with BeforeTool hook

**Uninstall:**
```bash
rtk init -g --gemini --uninstall
```

**Restart Required**: Restart Gemini CLI, then test with `git status` in a session.

## OpenCode Plugin (Global)

OpenCode supports plugins that can intercept tool execution. RTK provides a global plugin that mirrors the Claude auto-rewrite behavior by rewriting Bash tool commands to `rtk ...` before they execute. This plugin is **not** installed by default.
Expand Down
32 changes: 32 additions & 0 deletions hooks/cline-rtk-rules.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# RTK - Rust Token Killer (Cline)

**Usage**: Token-optimized CLI proxy for shell commands.

## Rule

Always prefix shell commands with `rtk` to minimize token consumption.

Examples:

```bash
rtk git status
rtk cargo test
rtk ls src/
rtk grep "pattern" src/
rtk find "*.rs" .
rtk docker ps
rtk gh pr list
```

## Meta Commands

```bash
rtk gain # Show token savings
rtk gain --history # Command history with savings
rtk discover # Find missed RTK opportunities
rtk proxy <cmd> # Run raw (no filtering, for debugging)
```

## Why

RTK filters and compresses command output before it reaches the LLM context, saving 60-90% tokens on common operations. Always use `rtk <cmd>` instead of raw commands.
60 changes: 60 additions & 0 deletions hooks/copilot-rtk-awareness.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# RTK — Copilot Integration (VS Code Copilot Chat + Copilot CLI)

**Usage**: Token-optimized CLI proxy (60-90% savings on dev operations)

## What's automatic

The `.github/copilot-instructions.md` file is loaded at session start by both Copilot CLI and VS Code Copilot Chat.
It instructs Copilot to prefix commands with `rtk` automatically.

The `.github/hooks/rtk-rewrite.json` hook adds a `PreToolUse` safety net via `rtk hook`
a cross-platform Rust binary that intercepts raw bash tool calls and rewrites them.
No shell scripts, no `jq` dependency, works on Windows natively.

## Meta commands (always use directly)

```bash
rtk gain # Token savings dashboard for this session
rtk gain --history # Per-command history with savings %
rtk discover # Scan session history for missed rtk opportunities
rtk proxy <cmd> # Run raw (no filtering) but still track it
```

## Installation verification

```bash
rtk --version # Should print: rtk X.Y.Z
rtk gain # Should show a dashboard (not "command not found")
which rtk # Verify correct binary path
```

> ⚠️ **Name collision**: If `rtk gain` fails, you may have `reachingforthejack/rtk`
> (Rust Type Kit) installed instead. Check `which rtk` and reinstall from rtk-ai/rtk.
## How the hook works

`rtk hook` reads `PreToolUse` JSON from stdin, detects the agent format, and responds appropriately:

**VS Code Copilot Chat** (supports `updatedInput` — transparent rewrite, no denial):
1. Agent runs `git status``rtk hook` intercepts via `PreToolUse`
2. `rtk hook` detects VS Code format (`tool_name`/`tool_input` keys)
3. Returns `hookSpecificOutput.updatedInput.command = "rtk git status"`
4. Agent runs the rewritten command silently — no denial, no retry

**GitHub Copilot CLI** (deny-with-suggestion — CLI ignores `updatedInput` today, see [issue #2013](https://github.com/github/copilot-cli/issues/2013)):
1. Agent runs `git status``rtk hook` intercepts via `PreToolUse`
2. `rtk hook` detects Copilot CLI format (`toolName`/`toolArgs` keys)
3. Returns `permissionDecision: deny` with reason: `"Token savings: use 'rtk git status' instead"`
4. Copilot reads the reason and re-runs `rtk git status`

When Copilot CLI adds `updatedInput` support, only `rtk hook` needs updating — no config changes.

## Integration comparison

| Tool | Mechanism | Hook output | File |
|-----------------------|-----------------------------------------|--------------------------|------------------------------------|
| Claude Code | `PreToolUse` hook with `updatedInput` | Transparent rewrite | `hooks/rtk-rewrite.sh` |
| VS Code Copilot Chat | `PreToolUse` hook with `updatedInput` | Transparent rewrite | `.github/hooks/rtk-rewrite.json` |
| GitHub Copilot CLI | `PreToolUse` deny-with-suggestion | Denial + retry | `.github/hooks/rtk-rewrite.json` |
| OpenCode | Plugin `tool.execute.before` | Transparent rewrite | `hooks/opencode-rtk.ts` |
| (any) | Custom instructions | Prompt-level guidance | `.github/copilot-instructions.md` |
Loading
Loading