SIGN IN SIGN UP
rtk-ai / rtk UNCLAIMED

CLI proxy that reduces LLM token consumption by 60-90% on common dev commands. Single Rust binary, zero dependencies

0 0 0 Rust
feat: TOML Part 2 — user-global config, shadow warning, rtk init templates, 4 new built-in filters (#351) * docs: update module count to 58 (toml_filter + verify_cmd) * docs: bump version refs to 0.27.1, fix module count to 59 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat: TOML DSL PR 2 — user-global config, shadow warning, init templates, 4 new filters - toml_filter: add ~/.config/rtk/filters.toml (priority 2, between project and built-in) - toml_filter: shadow warning when match_command overlaps a Rust-handled command - init: rtk init generates .rtk/filters.toml template (local) and ~/.config/rtk/filters.toml (global) - builtin_filters: add pre-commit, helm, gcloud, ansible-playbook (46/46 inline tests) - README: add "Custom Filters" section with lookup table, primitives, examples, built-in list Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat(filters): add quarto-render, pnpm-build, trunk-build from rtk discover data (52/52 tests) * feat(filters): add docker-inspect, sops, docker-compose-ps built-in filters Resolves issues #279, #277, #276 as TOML-native filters (no Rust required). - docker-inspect: strip_ansi + truncate_lines_at=120 + max_lines=60 - sops: strip_ansi + strip_lines_matching blank lines + max_lines=40 - docker-compose-ps: strip_ansi + truncate_lines_at=120 + max_lines=40 6 inline tests added (2 per filter), all passing. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * refactor(filters): split monolithic builtin_filters.toml into 28 individual files Replace the 848-line src/builtin_filters.toml monolith with individual files under src/filters/<name>.toml (1 filter + tests per file). Files are concatenated alphabetically by build.rs at compile time into OUT_DIR/builtin_filters.toml, then embedded via a BUILTIN_TOML constant in toml_filter.rs. The build step validates TOML syntax and detects duplicate filter names across files. Benefits: - Zero merge conflicts when multiple PRs add filters (different files) - Clear PR diffs: "+1 file of 30 lines" vs "+30 lines in 850-line file" - Easy onboarding: copy any .toml, rename, edit 3 fields — done - Build-time TOML validation catches syntax errors before tests run Changes: - build.rs (new): concat + validate src/filters/*.toml - Cargo.toml: add [build-dependencies] toml = "0.8" - src/filters/*.toml (28 files): split from monolith - src/filters/README.md (new): contributor guide - src/toml_filter.rs: BUILTIN_TOML const + 5 include_str replacements - src/builtin_filters.toml: deleted Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * test(filters): add 5 new unit tests for multi-file architecture + wget filter Unit tests added (toml_filter.rs): - test_builtin_toml_has_schema_version: ensures build.rs injects schema_version - test_builtin_all_expected_filters_present: guards against accidental file deletion - test_builtin_filter_count: exact count check (fails if filter added/removed without update) - test_builtin_all_filters_have_inline_tests: prevents shipping filters with no tests - test_new_filter_discoverable_after_concat: simulates build.rs concat, verifies lookup New built-in filter: - src/filters/wget.toml: compact wget download output (strips connection/resolution noise, short-circuits on 'saved [' to 'ok (downloaded)', 2 inline tests) Test results: 661/661 unit tests, 60/60 inline TOML filter tests Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * docs: add filter-workflow.md with Mermaid diagrams Build pipeline + runtime lookup priority, both as Mermaid flowcharts. Shows the full path from src/filters/*.toml to binary to execution. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix: remove dead TOML filters — wget, git-checkout, git-merge, git-remote, cargo-run These filters were never reachable: Clap routes rtk git/cargo commands to their dedicated Rust modules before run_fallback is called. The TOML engine only fires for unknown commands. Shipping dead filters gives false confidence (inline tests pass, but filters never activate in production). Also fixes P1-1 from the PR #386 review: wget was in RUST_HANDLED_COMMANDS and the shadow warning fired at compile time but did not block the build. Removed: cargo-run.toml, git-checkout.toml, git-merge.toml, git-remote.toml, wget.toml Updated test guards: count 29→24, expected list -5 names, concat test 30→25. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix: remove 3 dead TOML filters + update guards (PR #351) docker-inspect, docker-compose-ps, and pnpm-build are handled by container.rs and pnpm_cmd.rs before run_fallback is reached — their TOML filters never fire. Remove the files to avoid false documentation. Update toml_filter.rs guards: expected list -3 names, count 24→21, concat test 25→22. Update CONTRIBUTING.md example count to match. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix: rebase on PR #349 — apply regex anchors, make on_empty, build.rs clippy, docs macOS path - Add (\\s|$) word-boundary anchors to 6 tofu/mix match_command regexes (tofu-plan, tofu-init, tofu-validate, tofu-fmt, mix-format, mix-compile) - Add on_empty = "make: ok" to make.toml + update existing empty-output test - Fix build.rs clippy: map_or(false, ...) → is_some_and(..) - Add macOS alt path note to filter-workflow.md Mermaid diagram Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 11:02:18 +01:00
use std::collections::HashSet;
use std::fs;
use std::path::Path;
fn main() {
#[cfg(windows)]
{
// Clap + the full command graph can exceed the default 1 MiB Windows
// main-thread stack during process startup. Reserve a larger stack for
// the CLI binary so `rtk.exe --version`, `--help`, and hook entry
// points start reliably without requiring ad-hoc RUSTFLAGS.
println!("cargo:rustc-link-arg=/STACK:8388608");
}
feat: TOML Part 2 — user-global config, shadow warning, rtk init templates, 4 new built-in filters (#351) * docs: update module count to 58 (toml_filter + verify_cmd) * docs: bump version refs to 0.27.1, fix module count to 59 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat: TOML DSL PR 2 — user-global config, shadow warning, init templates, 4 new filters - toml_filter: add ~/.config/rtk/filters.toml (priority 2, between project and built-in) - toml_filter: shadow warning when match_command overlaps a Rust-handled command - init: rtk init generates .rtk/filters.toml template (local) and ~/.config/rtk/filters.toml (global) - builtin_filters: add pre-commit, helm, gcloud, ansible-playbook (46/46 inline tests) - README: add "Custom Filters" section with lookup table, primitives, examples, built-in list Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat(filters): add quarto-render, pnpm-build, trunk-build from rtk discover data (52/52 tests) * feat(filters): add docker-inspect, sops, docker-compose-ps built-in filters Resolves issues #279, #277, #276 as TOML-native filters (no Rust required). - docker-inspect: strip_ansi + truncate_lines_at=120 + max_lines=60 - sops: strip_ansi + strip_lines_matching blank lines + max_lines=40 - docker-compose-ps: strip_ansi + truncate_lines_at=120 + max_lines=40 6 inline tests added (2 per filter), all passing. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * refactor(filters): split monolithic builtin_filters.toml into 28 individual files Replace the 848-line src/builtin_filters.toml monolith with individual files under src/filters/<name>.toml (1 filter + tests per file). Files are concatenated alphabetically by build.rs at compile time into OUT_DIR/builtin_filters.toml, then embedded via a BUILTIN_TOML constant in toml_filter.rs. The build step validates TOML syntax and detects duplicate filter names across files. Benefits: - Zero merge conflicts when multiple PRs add filters (different files) - Clear PR diffs: "+1 file of 30 lines" vs "+30 lines in 850-line file" - Easy onboarding: copy any .toml, rename, edit 3 fields — done - Build-time TOML validation catches syntax errors before tests run Changes: - build.rs (new): concat + validate src/filters/*.toml - Cargo.toml: add [build-dependencies] toml = "0.8" - src/filters/*.toml (28 files): split from monolith - src/filters/README.md (new): contributor guide - src/toml_filter.rs: BUILTIN_TOML const + 5 include_str replacements - src/builtin_filters.toml: deleted Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * test(filters): add 5 new unit tests for multi-file architecture + wget filter Unit tests added (toml_filter.rs): - test_builtin_toml_has_schema_version: ensures build.rs injects schema_version - test_builtin_all_expected_filters_present: guards against accidental file deletion - test_builtin_filter_count: exact count check (fails if filter added/removed without update) - test_builtin_all_filters_have_inline_tests: prevents shipping filters with no tests - test_new_filter_discoverable_after_concat: simulates build.rs concat, verifies lookup New built-in filter: - src/filters/wget.toml: compact wget download output (strips connection/resolution noise, short-circuits on 'saved [' to 'ok (downloaded)', 2 inline tests) Test results: 661/661 unit tests, 60/60 inline TOML filter tests Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * docs: add filter-workflow.md with Mermaid diagrams Build pipeline + runtime lookup priority, both as Mermaid flowcharts. Shows the full path from src/filters/*.toml to binary to execution. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix: remove dead TOML filters — wget, git-checkout, git-merge, git-remote, cargo-run These filters were never reachable: Clap routes rtk git/cargo commands to their dedicated Rust modules before run_fallback is called. The TOML engine only fires for unknown commands. Shipping dead filters gives false confidence (inline tests pass, but filters never activate in production). Also fixes P1-1 from the PR #386 review: wget was in RUST_HANDLED_COMMANDS and the shadow warning fired at compile time but did not block the build. Removed: cargo-run.toml, git-checkout.toml, git-merge.toml, git-remote.toml, wget.toml Updated test guards: count 29→24, expected list -5 names, concat test 30→25. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix: remove 3 dead TOML filters + update guards (PR #351) docker-inspect, docker-compose-ps, and pnpm-build are handled by container.rs and pnpm_cmd.rs before run_fallback is reached — their TOML filters never fire. Remove the files to avoid false documentation. Update toml_filter.rs guards: expected list -3 names, count 24→21, concat test 25→22. Update CONTRIBUTING.md example count to match. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix: rebase on PR #349 — apply regex anchors, make on_empty, build.rs clippy, docs macOS path - Add (\\s|$) word-boundary anchors to 6 tofu/mix match_command regexes (tofu-plan, tofu-init, tofu-validate, tofu-fmt, mix-format, mix-compile) - Add on_empty = "make: ok" to make.toml + update existing empty-output test - Fix build.rs clippy: map_or(false, ...) → is_some_and(..) - Add macOS alt path note to filter-workflow.md Mermaid diagram Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 11:02:18 +01:00
let filters_dir = Path::new("src/filters");
let out_dir = std::env::var("OUT_DIR").expect("OUT_DIR must be set by Cargo");
let dest = Path::new(&out_dir).join("builtin_filters.toml");
// Rebuild when any file in src/filters/ changes
println!("cargo:rerun-if-changed=src/filters");
let mut files: Vec<_> = fs::read_dir(filters_dir)
.expect("src/filters/ directory must exist")
.filter_map(|e| e.ok())
.filter(|e| e.path().extension().is_some_and(|ext| ext == "toml"))
.collect();
// Sort alphabetically for deterministic filter ordering
files.sort_by_key(|e| e.file_name());
let mut combined = String::from("schema_version = 1\n\n");
for entry in &files {
let content = fs::read_to_string(entry.path())
.unwrap_or_else(|e| panic!("Failed to read {:?}: {}", entry.path(), e));
combined.push_str(&format!(
"# --- {} ---\n",
entry.file_name().to_string_lossy()
));
combined.push_str(&content);
combined.push_str("\n\n");
}
// Validate: parse the combined TOML to catch errors at build time
let parsed: toml::Value = combined.parse().unwrap_or_else(|e| {
panic!(
"TOML validation failed for combined filters:\n{}\n\nCheck src/filters/*.toml files",
e
)
});
// Detect duplicate filter names across files
if let Some(filters) = parsed.get("filters").and_then(|f| f.as_table()) {
let mut seen: HashSet<String> = HashSet::new();
for key in filters.keys() {
if !seen.insert(key.clone()) {
panic!(
"Duplicate filter name '{}' found across src/filters/*.toml files",
key
);
}
}
}
fs::write(&dest, combined).expect("Failed to write combined builtin_filters.toml");
}