Open source contribution · Rust · CLI · LLM Token Reduction
rtk-ai/ rtk
Zero-dependency Rust CLI proxy that reduces AI token consumption by 60% to 90% on common dev commands (git, cargo, npm, testing).
- 2 merged PRs
- 7 PRs under review
- 35 commits to the project
- +980 lines added
- 86.6k GitHub stars
The project
RTK is a high-performance CLI proxy written in Rust with zero runtime dependencies, designed to cut AI token consumption by 60% to 90% across standard developer commands.
It acts as a transparent proxy between developers or AI coding agents and commands like git, cargo, npm, pytest, and linters, compressing verbose output while preserving the essential context for LLMs.
How each PR was made
-
One problem per PR
Each PR fixes a single thing with the smallest possible change. That keeps reviews simple, lowers the risk of side effects and lets one change be reverted without taking others with it.
-
The problem becomes a test
Fixes come with automated tests that cover the case that used to fail, so the problem cannot come back unnoticed.
-
The project's own bar
Formatting, static analysis and the full test suite run in the project's continuous integration, and a change only lands after the maintainer's review.
-
Written for the reviewer
Each PR description explains the problem, the change and how it was tested, so the maintainer can decide with confidence.
Every PR, in business terms
Click a PR to see the problem, what was done and the value delivered. The link at the end of each one leads to the full technical discussion on GitHub.
-
#4771merged Nov 1, 2026 Monthly economics report sums usage across all project rows Monthly economics reports overwrote rows and retained only the last project; the PR proposes aggregating tokens and spend across all projects.
- The problem
- When reviewing monthly economics and AI model usage broken down by project, the analytics engine received multiple records belonging to the same calendar month. Instead of aggregating counters, the monthly merger continually overwrote the period entry with each subsequent project, leaving only the final project metrics in the finished report. This caused monthly summaries and total calculations to severely understate overall token consumption and real monetary spend.
- What was done
- The PR proposes extending period aggregation to monthly reports, summing input tokens, output tokens, cached tokens, and total costs across all project rows for each month. Automated integration tests verify that duplicate monthly rows are properly combined into consolidated metrics and cost calculations.
- Value delivered
- Delivers accurate financial visibility into total monthly AI spending and token efficiency for engineering teams and leaders.
-
#4802opened Oct 26, 2026Under review Pytest summary no longer turns a banner printed by the test into a failure An underscore line that a test printed in captured output was read as the next failure's header, adding a failure to the summary; now only a pytest separator ends a captured section.
- The problem
- rtk condenses pytest output to save tokens, and to do so it identifies failure blocks by underscore headers. A test that prints a decorative banner, a title between underscores, has that line reproduced in the failure's captured output section. The parser took the line for a new failure's header: the banner became its own entry in the summary, and the following captured lines, including error lines printed by the test, were attributed to it.
- What the PR proposes
- The parser now knows when it is inside a captured section and, in that state, only opens a new block on a separator pytest itself prints: a column-zero line, underscores on both sides with the right side equal to or one longer than the left, and at least 39 columns, the minimum terminal width pytest considers. A shorter banner stays in the capture. A regression test uses the reported output and expects a single failure with its error lines, and the existing tests for shortened headers and real separators remain valid.
- Expected value
- The summary handed to the agent reports the right number of failures and attributes each line to the right test, with no invented failures.
-
#4786opened Oct 24, 2026Under review Deny rules reach commands glued to zsh's disown operator A command written right after zsh's disown operator reached the deny scan with the exclamation mark stuck to it and slipped past the rules; the prefix is now dropped before analysis.
- The problem
- rtk applies permission rules to the commands an agent asks to run, including those embedded in a shell call. When stripping shell grammar residue before the scan, the routine only handled standalone words, on purpose: an exclamation mark glued to a word is history expansion, and a glued brace is brace expansion. In zsh, however, the disown operator ends in an exclamation mark, and whatever comes glued after it, a command or a brace group, is a real command with the sign stuck in front. In that form the deny rule did not recognize the command and let it through.
- What the PR proposes
- The stripping now drops a leading exclamation mark even when glued to the next word, since no legitimate command starts that way, and only then proceeds to the standalone-word handling. Regression tests cover the spaced form, the form glued to the command and the form glued to a brace group, plus controls with allowed commands and compound commands outside an embedded shell.
- Expected value
- Closes a gap through which a destructive command would escape the deny rules just because of how it was written.
-
#4784opened Oct 24, 2026Under review Tool help tests on Windows stop opening six browser tabs The suite that compares each tool's native help with its help through rtk called Git on Windows, where help opens in the browser; Git is now left out of that suite on that platform only.
- The problem
- rtk has a suite that checks whether each wrapped tool's help survives the proxy, running the help option natively and through rtk for several commands, including three Git commands. On Windows, Git ships configured to show help as HTML, so each call opens the documentation in the default browser instead of printing the page to the terminal. Running the tests on that platform opened six tabs on the developer's machine, and the comparison used whatever Git printed after launching the browser, not the help text.
- What the PR proposes
- Git joined the list of tools skipped only on Windows, alongside the Unix utilities the platform lacks, and remains exercised everywhere else. Two regression tests pin the behavior: one guarantees the exclusion on Windows and the other guarantees the presence on other platforms. Git's short-help test, which opens no browser, still runs on all of them.
- Expected value
- Anyone developing rtk on Windows runs the full suite without interruptions and with a result that measures what it claims to measure.
-
#4555merged Oct 20, 2026 RTK delegated tasks work on Windows and with a custom Claude folder When delegating work to a cheaper model, RTK always fetched the API key through sh, which Windows lacks, and ignored Claude Code's custom configuration folder; the PR proposes using each system's shell and honoring that folder.
- The problem
- RTK's task commands hand work such as summarizing or generating text to a cheaper model, without the files entering the agent's context. The API key can come from a configured command, but it always ran through sh, which is usually missing on Windows, against the project's own security rules. The command being analyzed also ran without handling Windows .cmd and .bat shims, and the lookup of Claude Code conversations ignored a custom configuration folder.
- What was done
- The PR proposes running the key command through each system's default shell, with a clear message when it cannot run, and launching the analyzed command through the same mechanism RTK already uses to resolve shims and escape arguments on Windows. The conversations folder now follows the CLAUDE_CONFIG_DIR setting. New tests cover the key read from the command's output, the failure with an error code, the empty output and the custom folder.
- Value delivered
- With the change, anyone using RTK on Windows or with Claude Code in a folder of their own can rely on task delegation, and the token savings it brings, without manual tweaks.
-
#4621opened Oct 16, 2026Under review Passing pytest tests no longer show up as failures in RTK With pytest set to show the output of passing tests, RTK's filter listed every passing test as a failure, along with its output; the PR proposes closing the failures section at the next section heading.
- The problem
- RTK summarizes pytest output for the agent, highlighting only the failures. The filter enters the failures section on the FAILURES heading and only leaves it at the final summary. With the -rP or -rA options and at least one failing test, pytest prints a PASSES section after the failures, with the output of the passing tests, and the filter, still in the failures section, marked each of them as [FAIL].
- What the PR proposes
- The PR proposes that any new top-level section heading close the failure in progress and take the filter out of the failures section, so PASSES, the warnings summary and the other sections are handled normally again. A new test builds output with failures followed by PASSES and the short summary, and checks that only the failing test is reported as a failure.
- Expected value
- With the change, the agent gets the real list of failures, with no passing tests mixed in, and does not waste time investigating problems that do not exist.
-
#4620opened Oct 16, 2026Under review .NET build warnings and errors arrive with the right file and line When reading the .NET binary build log, RTK skipped a field in warnings and errors issued by the C# compiler, and everything after it came out shifted; the PR proposes reading the fields in the exact order MSBuild writes them.
- The problem
- For .NET builds, RTK reads the MSBuild binary log and hands the agent a lean summary with the warnings and errors. Each event in that log carries optional fields in a fixed order, and the reader only knew some of them. When a warning came from the C# compiler, which records the sender name, that field was not read and the following reads were shifted: the warning code took the place of the file, and line and column came out wrong, as in CS0168(53,7) with no source file name.
- What the PR proposes
- The PR proposes declaring every field flag in MSBuild's format and reading each field present in the same order MSBuild writes it, including the thread identifier, help keyword, sender name and location data. A new test builds a log with a warning and an error issued by the compiler and checks the code, file, line, column and message of each.
- Expected value
- With the change, the agent gets .NET build warnings and errors from RTK that point to the right file and line, without having to rerun the build to find where the problem is.
-
#4619opened Oct 16, 2026Under review RTK's outdated-hook warning no longer vanishes unseen The internal command RTK runs before each agent command used up the daily outdated-hook warning on a discarded output and fired telemetry for nothing; the PR proposes excluding it from both routines, as rtk hook already is.
- The problem
- Shell hooks and plugin adapters call rtk rewrite before each command to swap it for RTK's token-saving version. That path was not excluded from two daily routines: the reminder about a missing or outdated hook and the telemetry ping. When the reminder was due, it was printed on an output the hook discards and still marked as shown, so the user never saw it; and the telemetry started a background task in a process that ends right away.
- What the PR proposes
- The PR proposes treating rtk rewrite like rtk hook, which was already left out of both routines because it also runs before each command. The reminder is then left for the next command the user actually sees, and telemetry is no longer fired on the hook path. The existing tests were extended to cover rtk rewrite in both exclusions.
- Expected value
- With the change, anyone with an outdated hook is properly warned again, and the command that runs before every agent action gets lighter.
-
#4535opened Oct 12, 2026Under review Stdout and stderr write errors propagated cleanly instead of aborting In release builds, I/O errors during stdout or stderr writes in rtk read caused panics and abrupt SIGABRT aborts; the PR proposes clean error propagation with exit code 1.
- The problem
- In rtk read, general output was printed using the print! macro. Any I/O error during writing (such as ENOSPC, EDQUOT, or EPIPE) triggered a panic in std::io::stdio. Because release builds configure panic = "abort", the process crashed immediately with SIGABRT (exit code 134), preventing caller tools and scripts from identifying the root cause. Furthermore, reporting the error to stderr via eprintln! caused a secondary crash if stderr was also redirected or unwritable.
- What the PR proposes
- The PR introduces a fallible write_output helper that writes to locked stdout via writer.write_all() and cleanly returns a Result<()>, replacing the panic-prone print! macro. Error reporting in main and Commands::Read now guards stderr writes with non-panicking writeln!, preventing secondary aborts. Unit tests cover error bubbling, and Linux integration tests against /dev/full verify clean exit code 1 without crashing.
- Expected value
- Eliminates catastrophic SIGABRT process crashes in the CLI when standard streams run out of space or disconnect, allowing CI pipelines, AI agents, and automated scripts to handle failures deterministically.
Figures updated on Nov 14, 2026.
The same care in your system
The habits behind these PRs carry over to backends that move money: reproduce the problem before fixing it, prove the fix with a test and keep sensitive data from leaking.