RTK (Rust Token Killer)

repository·develop·Indexed 10 days ago

https://github.com/rtk-ai/rtk

A high-performance CLI proxy designed to minimize LLM token consumption by intercepting shell commands and compressing their output by up to 90%. Version 0.42.4 includes integrations and hooks for AI agents and IDEs including Claude Code, GitHub Copilot, Cursor, Hermes, Cline, Roo Code, Google Antigravity, Kilo Code, and OpenCode.

Tokens
67.1K
Snippets
214
Records
328
Agent score
95%

What's inside RTK

  1. Overview of JVM ecosystem filters

    develop

    RTK provides specialized filters for JVM-based build tools to optimize output for AI agents by stripping boilerplate and focusing on actionable errors.

    ModuleTool(s)Modes
    gradlew_cmd.rs./gradlew, gradlew.bat, gradleBuild, Test, ConnectedTest, Lint, Dependencies (Streaming line filter)
    mvn_cmd.rsmvn, ./mvnw, mvnw.cmdTest, Compile, Package, Passthrough (Buffered single-pass filter)
  2. What is RTK (Rust Token Killer)

    develop

    RTK is a CLI proxy designed to sit between an AI assistant and development tools. It intercepts command output (via a PreToolUse hook) and filters out noise such as boilerplate, progress bars, and irrelevant data before it reaches the LLM.

    Key Benefit: It can reduce the bash output bytes reaching the LLM by up to 90% for common development commands, leading to more efficient context usage without requiring changes to your existing workflow.

  3. Understand the Discover module's core functions

    develop

    The Discover module provides two primary capabilities for managing LLM command execution:

    1. Command Rewriting: This is the active path used by LLM agent hooks. When an LLM executes a command (e.g., git status), the module intercepts it and decides whether to rewrite it to an RTK-optimized version (e.g., rtk git status) or pass it through unchanged. This happens for every command the LLM runs.

    2. History Analysis: Using the rtk discover command, the module scans past LLM session files (currently supporting Claude Code JSONL formats) to identify commands that could have been rewritten. This helps estimate potential token savings and command adoption rates.

  4. JavaScript, TypeScript, and Node.js command specifics

    develop

    When working with JavaScript, TypeScript, or Node.js projects within the RTK ecosystem, the following internal behaviors and tools are utilized:

    • Package Manager Execution: The system uses utils::package_manager_exec() to automatically detect whether to use pnpm, yarn, or npm. Developers should rely on this utility rather than hardcoding a specific package manager for JS modules.
    • Testing with Vitest: The vitest_cmd.rs command utilizes the parser/ module to provide structured output parsing for test results.
    • Testing with Playwright: The playwright_cmd.rs command utilizes the parser/ module to extract test results.
  5. Overview of the RTK Tracking System

    develop

    RTK's tracking system records command executions to provide analytics on how much bash output is reduced by RTK's filtering. It measures savings based on bash output bytes converted to estimated tokens (using a bytes / 4 ratio).

    Key Features:

    • Storage: Uses a SQLite database to store command history.
    • Retention: Automatically deletes records older than 90 days to manage database size.
    • Metrics: Tracks estimated input/output tokens, bash output reduction percentage (savings_pct), and execution time.
    • Aggregation: Provides APIs for daily, weekly, and monthly statistics and supports JSON/CSV exports.
  6. Understand CI status and trace output in RTK

    develop

    RTK provides specialized handling for CI-related commands to ensure compatibility and readability:

    • ci status: Since glab does not support -F json for this subcommand, RTK uses text-keyword parsing. If the system is in a non-English locale and no English status keyword is recognized, the raw verbatim output is returned.
    • ci trace: This command uses ANSI-stripping and GitLab section-marker filtering. It removes boilerplate from the runner, git, and artifacts to provide a clean text-only filter.
    • Pipeline/Merge Status Indicators: To maintain consistency with gh_cmd.rs and avoid rendering issues, RTK uses the following text tags: [ok], [fail], [cancel], [run], [pend], [skip], and [conflict].
  7. How Mistral Vibe Hooks work

    develop

    The Mistral Vibe hook is implemented as a subcommand of the RTK Rust binary (rtk hook vibe). It operates by intercepting Vibe's stdin JSON payload and performing transparent command rewrites.

    Hook Configuration

    The hook is declared in ~/.vibe/hooks.toml with the following requirements:

    • match = "bash"
    • strict = false

    Data Flow

    1. Input: The hook reads a JSON payload from stdin containing tool_name, tool_input.command, hook_event_name, and session_id.
    2. Processing: The rtk hook vibe binary processes the command.
    3. Output: The hook returns hook_specific_output.tool_input.command to perform the rewrite and a system_message to provide visibility in the UI.

    Error Handling and Passthrough

    • Passthrough: If the tool is not bash, the command is empty, the JSON is malformed, or the command is unknown to RTK, the hook exits with code 0 and empty stdout (allowing the original command to proceed).
    • Permission Denied: If RTK denies a command, the hook returns: {"decision":"deny","reason":"..."}.

    Fallback Mechanism

    By default, a system prompt is installed at ~/.vibe/prompts/rtk.md to act as a fallback. You can skip this prompt installation by using the --hook-only flag during setup.

  8. Use the Tee system to recover raw command output

    develop

    The Tee system automatically saves the full, unoptimized raw output of a command when it fails (exit code != 0). This allows an LLM to inspect the detailed error without re-executing the command.

    How it works:

    1. A command fails.
    2. RTK saves the raw output to ~/.local/share/rtk/tee/.
    3. The filtered output shown to the LLM includes a pointer to the log file.
    4. The LLM can then read that file to see the full error details.

    Example Output:

    FAILED: 2/15 tests
    [full output: ~/.local/share/rtk/tee/1707753600_cargo_test.log]

    Tee Configuration Options:

    • tee.enabled: (bool) Enable/disable the system.
    • tee.mode: (string) "failures" (default), "always", or "never".
    • tee.max_files: (int) Number of files to rotate (default: 20).
    • Note: Outputs shorter than 500 bytes or longer than 1 MB are not saved/are truncated.
  9. How command rewriting works

    develop

    RTK uses a sophisticated pipeline to ensure shell commands are rewritten safely without breaking syntax:

    1. Tokenization

    A lexer (lexer.rs) converts raw strings into typed tokens. This prevents errors caused by naive string splitting, such as breaking on quoted content like git commit -m "fix && update".

    2. Compound Splitting

    The engine splits commands on operators (&&, ||, ;) and pipes (|, |&).

    • Safety Rule: For standard pipelines, only the final stage marked pipeline_final_safe is rewritten.
    • Exclusions: Stderr pipelines (|&) and pipelines containing opaque shell groups remain raw to prevent corruption.

    3. Per-segment Rewriting

    Each command segment undergoes these steps:

    • Strip Redirects: Trailing redirects like 2>&1 or >/dev/null are stripped and re-appended after the rewrite.
    • Short-circuit Special Cases: Specific patterns like head -20 file are converted to rtk read file --max-lines 20 rather than using generic prefix replacement.
    • Classification: The command is normalized (stripping sudo, environment variables, and absolute paths) and matched against 60+ regex patterns.
    • Application: The matching prefix is replaced with rtk <cmd>, and the original environment prefixes and redirects are re-applied.

    4. Rewrite Guards (When rewriting is skipped)

    Rewriting is automatically skipped if:

    • RTK_DISABLED=1 is present in the environment prefix.
    • The command is gh with structured output flags (--json, --jq, --template).
    • The command is cat with flags other than -n.
    • The command involves write operations (e.g., cat or head with > or >>).
    • The command is explicitly listed in the hooks.exclude_commands configuration.
  10. How RTK handles PHP commands

    develop

    RTK provides specialized wrappers for common PHP CLI tools to improve developer experience by cleaning up noise and focusing on actionable errors.

    Key behaviors include:

    • Syntax Checks: php -l syntax checks are summarized via php_cmd.rs.
    • Laravel Artisan: php artisan* commands are routed to specialized helpers. artisan_cmd.rs cleans the output and applies runner-aware filtering specifically for php artisan test.
    • Testing Frameworks:
      • phpunit_cmd.rs strips progress and header noise, preserving only failure details and the final summary.
      • pest_cmd.rs and paratest_cmd.rs suppress compact progress to provide test-focused output.
      • test_output.rs provides the shared filtering logic used by PHPUnit, Pest, and ParaTest.
    • Static Analysis & Linting:
      • phpstan_cmd.rs injects JSON output by default and emits compact file/line error summaries.
      • ecs_cmd.rs (EasyCodingStandard) condenses output while preserving file paths and error lines.

    Tool Resolution Strategy: RTK uses a specific resolution order for all PHP tools: it first attempts to resolve binaries from the local vendor/bin/* directory, falling back to global binaries if no local version is found.

  11. Automatic Bundler detection in Ruby commands

    develop
    When running Ruby commands through RTK, the system automatically detects if a Gemfile is present in the current directory. If detected, RTK uses ruby_exec() to automatically prepend bundle exec to the command, ensuring the correct environment and gem versions are used.
  12. Understand the RTK permission model and exit codes

    develop

    RTK follows a least-privilege permission precedence: Deny > Ask > Allow (explicit) > Default (ask). It extracts Bash(...) rules from Claude Code settings.json files (project, global, and .local variants) to determine if a command should be rewritten.

    Permission Verdicts and Behavior

    VerdictTriggerrewrite_cmd exit codeHook behavior
    Denypermissions.deny rule matched2Passthrough — the host tool handles the denial.
    Askpermissions.ask rule matched3Rewrite + let the host tool prompt the user.
    Allowpermissions.allow rule matched0Rewrite + auto-allow.
    DefaultNo rule matched3Rewrite + let the host tool prompt the user.

    Per-tool Support Details

    ToolAsk SupportBehavior on Default
    Claude CodeYespermissionDecision: "ask" (user prompted)
    Copilot VS CodeYespermissionDecision: "ask" (user prompted)
    CursorReadypermission: "ask" (users prompted when Cursor enforces it)
    Gemini CLINoallow (limitation: Gemini lacks an 'ask' mode)
    Copilot CLINodeny-with-suggestion
    CodexNo (no-op)allow (fails open)
    Mistral VibeNoPassthrough (Vibe's own approval prompt fires on the rewritten command)