code-simplifier
Review RTK Rust code for idiomatic simplification. Detects over-engineering, unnecessary allocations, verbose patterns. Applies Rust idioms without changing…
Rust design patterns for RTK. Newtype, Builder, RAII, Trait Objects, State Machine. Applied to CLI filter modules. Use when designing new modules or refactoring existing ones.
$ npx -y skills add rtk-ai/rtk --skill design-patterns --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/design-patternsContext preview
The summary Claude sees to decide when to auto-load this skill.
Rust design patterns for RTK. Newtype, Builder, RAII, Trait Objects, State Machine. Applied to CLI filter modules. Use when designing new modules or refactoring existing ones.
name: design-patterns description: Rust design patterns for RTK. Newtype, Builder, RAII, Trait Objects, State Machine. Applied to CLI filter modules. Use when designing new modules or refactoring existing ones. triggers: - "design pattern" - "how to structure" - "best pattern for" - "refactor to pattern" allowed-tools: - Read - Grep - Glob effort: medium tags: [rust, design-patterns, architecture, newtype, builder, rtk]
Patterns that apply to RTK's filter module architecture. Focused on CLI tool patterns, not web/service patterns.
Use when: wrapping primitive types to prevent misuse (command names, paths, token counts).
// Without Newtype — easy to mix up
fn track(input_tokens: usize, output_tokens: usize) { ... }
track(output_tokens, input_tokens); // Silent bug!
// With Newtype — compile error on swap
pub struct InputTokens(pub usize);
pub struct OutputTokens(pub usize);
fn track(input: InputTokens, output: OutputTokens) { ... }
track(OutputTokens(100), InputTokens(400)); // Compile error ✅// Practical RTK example: command name validation
pub struct CommandName(String);
impl CommandName {
pub fn new(s: &str) -> Result<Self> {
if s.contains(';') || s.contains('|') || s.contains('`') {
anyhow::bail!("Invalid command name: shell metacharacters");
}
Ok(Self(s.to_string()))
}
pub fn as_str(&self) -> &str { &self.0 }
}Use when: a struct has 4+ optional fields, many with defaults.
#[derive(Default)]
pub struct FilterConfig {
max_lines: Option<usize>,
strip_ansi: bool,
show_warnings: bool,
truncate_at: Option<usize>,
}
impl FilterConfig {
pub fn new() -> Self { Self::default() }
pub fn max_lines(mut self, n: usize) -> Self { self.max_lines = Some(n); self }
pub fn strip_ansi(mut self, v: bool) -> Self { self.strip_ansi = v; self }
pub fn show_warnings(mut self, v: bool) -> Self { self.show_warnings = v; self }
}
// Usage — readable, no positional arg confusion
let config = FilterConfig::new()
.max_lines(50)
.strip_ansi(true)
.show_warnings(false);When NOT to use Builder: if the struct has 1-3 fields with obvious meaning. Over-engineering for simple cases.
Use when: parsing multi-section output (test results, build output) where context changes behavior.
// RTK example: pytest output parsing
#[derive(Debug, PartialEq)]
enum ParseState {
LookingForTests,
InTestOutput,
InFailureSummary,
Done,
}
fn parse_pytest(input: &str) -> String {
let mut state = ParseState::LookingForTests;
let mut failures = Vec::new();
for line in input.lines() {
match state {
ParseState::LookingForTests => {
if line.contains("FAILED") || line.contains("ERROR") {
state = ParseState::InFailureSummary;
failures.push(line);
}
}
ParseState::InFailureSummary => {
if line.starts_with("=====") { state = ParseState::Done; }
else { failures.push(line); }
}
ParseState::Done => break,
_ => {}
}
}
failures.join("\n")
}Use when: different command families need the same interface. Avoids massive match arms.
// Define a common interface for filters
pub trait OutputFilter {
fn filter(&self, input: &str) -> Result<String>;
fn command_name(&self) -> &str;
}
pub struct GitFilter;
pub struct CargoFilter;
impl OutputFilter for GitFilter {
fn filter(&self, input: &str) -> Result<String> { filter_git(input) }
fn command_name(&self) -> &str { "git" }
}
// RTK currently uses match-based dispatch in main.rs (simpler, no dynamic dispatch overhead)
// Trait objects are useful if filter registry becomes dynamic (e.g., TOML-loaded plugins)Note: RTK's current `match` dispatch in `main.rs` is intentional — static dispatch, zero overhead. Only move to trait objects if the match arm count exceeds ~20 commands.
Use when: managing resources that need cleanup (temp files, SQLite connections).
// RTK tee.rs — RAII for temp output files
pub struct TeeFile {
path: PathBuf,
}
impl TeeFile {
pub fn create(content: &str) -> Result<Self> {
let path = tee_path()?;
fs::write(&path, content)
.with_context(|| format!("Failed to write tee file: {}", path.display()))?;
Ok(Self { path })
}
pub fn path(&self) -> &Path { &self.path }
}
// No explicit cleanup needed — file persists intentionally (rotation handled separately)
// If cleanup were needed: impl Drop { fn drop(&mut self) { let _ = fs::remove_file(&self.path); } }Use when: a command has multiple filtering modes (e.g., compact vs. verbose).
pub enum FilterMode {
Compact, // Show only failures/errors
Summary, // Show counts + top errors
Full, // Pass through unchanged
}
pub fn apply_filter(input: &str, mode: FilterMode) -> String {
match mode {
FilterMode::Compact => filter_compact(input),
FilterMode::Summary => filter_summary(input),
FilterMode::Full => input.to_string(),
}
}Use when: you need to add methods to types you don't own (like `&str` for RTK-specific parsing).
pub trait RtkStrExt {
fn is_error_line(&self) -> bool;
fn is_warning_line(&self) -> bool;
fn token_count(&self) -> usize;
}
impl RtkStrExt for str {
fn is_error_line(&self) -> bool {
self.starts_with("error") || self.contains("[E")
}
fn is_warning_line(&self) -> bool {CLI proxy that reduces LLM token consumption by 60-90% on common dev commands. Single Rust binary, zero dependencies
Repo: rtk-ai/rtk
Review RTK Rust code for idiomatic simplification. Detects over-engineering, unnecessary allocations, verbose patterns. Applies Rust idioms without changing…
Issue triage: audit open issues, categorize, detect duplicates, cross-ref PRs, risk assessment, post comments. Args: "all" for deep analysis of all, issue…
CLI performance optimization - startup time, memory usage, token savings benchmarking
Batch review des PRs RTK par ordre de complexité croissante (XS → S → M → L). Pour chaque PR : vérifie l'état (conflits, CLA, reviews), lit le diff complet,…
PR triage: audit open PRs, deep review selected ones, draft and post review comments. Args: "all" to review all, PR numbers to focus (e.g. "42 57"), "en"/"fr"…
Generate a comprehensive repo recap (PRs, issues, releases) for sharing with team. Pass "en" or "fr" as argument for language (default fr).