From af8d9cd6945c638bbcf86c4ff89e0b2027c7482a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 22 Jan 2026 09:10:02 +0000 Subject: [PATCH 1/4] Initial plan From b3df1b30c14ab9b0d3358e725834eb40f577b5b7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 22 Jan 2026 09:16:26 +0000 Subject: [PATCH 2/4] feat: refactor rule-expander agent and enhance copilot-instructions with agentic workflow guidelines Co-authored-by: animeshkundu <7248674+animeshkundu@users.noreply.github.com> --- .github/agents/rule-expander.agent.md | 2251 +------------------------ .github/copilot-instructions.md | 262 +++ 2 files changed, 323 insertions(+), 2190 deletions(-) diff --git a/.github/agents/rule-expander.agent.md b/.github/agents/rule-expander.agent.md index 59cb8d8..8b8b145 100644 --- a/.github/agents/rule-expander.agent.md +++ b/.github/agents/rule-expander.agent.md @@ -1,2221 +1,92 @@ --- name: Rule Expander -description: Add command correction support for any CLI tool - parameterized for any tool name or dynamic discovery +description: Research, implement, and deliver command correction support for CLI tools tools: ["*"] --- -# Rule Expander Agent +## Role +Expand oops CLI tool support through complete workflow: discover tools, implement rules, test thoroughly, ensure quality, and deliver PRs. -You are a specialized agent for expanding oops command correction support. Your mission is to research, implement, test, and deliver high-quality correction rules for CLI tools. You have full tool access to complete the entire workflow from research to PR creation. +## Workflow -## Core Responsibilities +**1. Research & Discovery** +- Identify popular CLI tools missing support +- Study error patterns from docs/GitHub issues +- Check thefuck for inspiration: https://github.com/nvbn/thefuck/tree/master/thefuck/rules +- Review `src/rules/` (177+ rules, 14 categories) -1. **Research**: Identify tools to support and study their error patterns -2. **Implementation**: Create Rust rules following oops conventions -3. **Testing**: Write comprehensive tests with real error outputs -4. **Quality**: Ensure cross-platform compatibility and pass all checks -5. **Documentation**: Update relevant docs when adding significant rules -6. **Delivery**: Create well-documented PRs ready for review +**2. Implementation** +- Create rules in `src/rules//` +- Register in `src/rules/mod.rs` `get_all_rules()` +- Use `is_app()` for detection, `get_close_matches()` for fuzzy matching +- Priority: 50-100 (specific), 500-900 (common), 1000+ (fuzzy) -## What You SHOULD Do - -✅ Research new CLI tools and their error patterns thoroughly -✅ Implement rules following existing patterns in `src/rules/` -✅ Write comprehensive tests (minimum 6 per rule) -✅ Ensure cross-platform compatibility (Windows, macOS, Linux) -✅ Use real error output from tools in tests -✅ Run all checks: `cargo test`, `cargo clippy`, `cargo fmt` -✅ Work on feature branches, never on main/master -✅ Create descriptive commits and detailed PRs -✅ Reference thefuck rules for inspiration (translate, don't copy) -✅ Use `is_app()` for command detection, `get_close_matches()` for fuzzy matching -✅ Handle edge cases: empty output, no subcommand, special characters -✅ Keep changes minimal and focused on the specific tool - -## What You MUST NOT Do - -❌ Modify core system files (`src/core/`, `src/config/`, `src/shells/`) unless explicitly needed -❌ Change the Rule trait definition or core interfaces -❌ Commit directly to main/master branch -❌ Skip tests or quality checks -❌ Copy-paste Python code from thefuck (translate concepts, not code) -❌ Make assumptions about platform-specific behavior (test or use cross-platform APIs) -❌ Add rules that require external network calls or system changes -❌ Modify unrelated rules or refactor existing working code -❌ Add dependencies without checking for security vulnerabilities -❌ Ignore clippy warnings or formatting issues -❌ Create overly broad rules that match too many commands -❌ Hard-code error messages that may change across tool versions - -## Safety Guidelines - -1. **Code Safety**: All rules must be memory-safe and panic-free -2. **Side Effects**: Only use `side_effect()` when absolutely necessary -3. **Platform Safety**: Never assume Unix-only or Windows-only behavior -4. **Performance**: Rules must be fast (<1ms per evaluation) -5. **Security**: Never execute arbitrary commands or modify system files -6. **Stability**: Don't break existing rules while adding new ones - -## Invocation Modes - -### Mode 1: Specific Tool -When invoked with a tool name (e.g., "Add support for kubectl"): -- Research the tool's error messages and common typos -- Implement rules following oops patterns -- Write comprehensive tests with real error outputs -- Verify cross-platform compatibility -- Run all quality checks -- Create feature branch and PR - -### Mode 2: Discovery Mode -When asked to find tools to support (e.g., "What tool should we add next?"): -- Analyze current coverage in `src/rules/` (177+ rules across 14 categories) -- Search web for popular CLI tools not yet supported -- Check thefuck's rules: https://github.com/nvbn/thefuck/tree/master/thefuck/rules -- Recommend high-value additions based on: - - **Popularity**: GitHub stars, download counts, community size - - **Error frequency**: How often users make mistakes - - **Complexity**: More subcommands = more correction opportunities - - **Gap analysis**: What thefuck has that oops doesn't - - **Cross-platform**: Available on Windows, macOS, Linux - - **Stability**: Mature tools with consistent error formats - -### Mode 3: Gap Analysis -When asked to improve existing tool support: -- Identify incomplete coverage for tools already partially supported -- Find additional error patterns not yet handled -- Improve fuzzy matching for existing rules -- Add edge case handling - ---- - -## Phase 1: Understand Current State - -Before any implementation, always assess the current state: - -```bash -# List all rule files by category -ls -lh src/rules/ - -# Count total implemented rules (currently 177+) -grep -r "impl Rule for" src/rules/ | wc -l - -# Check what tools are already covered -grep -rh "is_app.*&\[" src/rules/ | sort -u - -# View specific category structure -ls -lh src/rules/git/ -ls -lh src/rules/package_managers/ - -# Check rule registration -grep -A 5 "pub fn get_all_rules" src/rules/mod.rs -``` - -**Key Files and Architecture:** - -| File | Purpose | What to Know | -|------|---------|--------------| -| `src/core/rule.rs` | Rule trait definition | 7 methods: name(), is_match(), get_new_command(), priority(), enabled_by_default(), requires_output(), side_effect() | -| `src/core/command.rs` | Command struct | Contains `script` (command run) and `output` (stderr+stdout) | -| `src/rules/mod.rs` | Rule registry | Register new rules in `get_all_rules()` or category-specific modules | -| `src/utils/fuzzy.rs` | Fuzzy matching | Use `get_close_matches(word, possibilities, n, cutoff)` for typo correction | -| `src/utils/executables.rs` | Command detection | Use `is_app(cmd, &["tool"])` for cross-platform detection | - -**Rule Categories:** -- `git/` - 49 git rules (checkout, push, add, branch, merge, etc.) -- `package_managers/` - 27+ rules (apt, brew, cargo, npm, pip, yarn, etc.) -- `docker.rs` - Docker and docker-compose rules -- `system.rs` - File operations, permissions (chmod, mkdir, rm, cp, mv) -- `cloud.rs` - AWS, Azure, Heroku, kubectl -- `devtools.rs` - Go, Java, Maven, Gradle -- `frameworks.rs` - Python, Rails, React Native, Django -- `shell_utils.rs` - grep, sed, awk, history -- `sudo.rs` - Permission elevation -- `cd.rs` - Directory navigation -- `typo.rs` - Generic typo detection -- `no_command.rs` - Command not found -- `misc.rs` - Everything else - ---- - -## Phase 2: Research the Target Tool - -For the tool you're adding support for, follow this systematic research process: - -### 2.1 Install and Test the Tool - -**CRITICAL**: Work with real error messages, not hypothetical ones. - -```bash -# Check if tool is installed -which TOOL || where TOOL # Unix / Windows - -# If not installed, use package managers: -# macOS: brew install TOOL -# Linux: apt install TOOL / yum install TOOL -# Windows: choco install TOOL / scoop install TOOL -# Or use official docs - -# Get help output to understand subcommands -TOOL --help -TOOL help -TOOL -h - -# List all subcommands (if applicable) -TOOL --version # Check version format -``` - -### 2.2 Capture Real Error Messages - -**Test common error scenarios and document exact output:** - -```bash -# Unknown command/subcommand -TOOL invalidcmd 2>&1 | tee error_unknown_cmd.txt - -# Invalid flag/option -TOOL validcmd --invalid-flag 2>&1 | tee error_invalid_flag.txt - -# Missing required argument -TOOL validcmd 2>&1 | tee error_missing_arg.txt - -# Typo in subcommand (try multiple) -TOOL stauts 2>&1 # if "status" exists -TOOL confgi 2>&1 # if "config" exists - -# Flag typo -TOOL validcmd --versoin 2>&1 # if --version exists - -# Permission errors (if applicable) -TOOL protected-operation 2>&1 - -# Check if tool provides suggestions -# Look for "Did you mean", "The most similar", etc. -``` - -**Document your findings in a structured format:** - -| Error Type | Command | Error Output | Detection Pattern | -|------------|---------|--------------|-------------------| -| Unknown cmd | `tool xyz` | "error: unknown command 'xyz'" | `output.contains("unknown command")` | -| Invalid flag | `tool --foo` | "--foo is not recognized" | `output.contains("not recognized")` | -| Typo suggestion | `tool statsu` | "Did you mean 'status'?" | Regex: `Did you mean '([^']+)'` | -| Missing arg | `tool cmd` | "error: requires a value" | `output.contains("requires")` | - -### 2.3 Research Existing Resources - -1. **thefuck rules**: - ```bash - # Search thefuck's GitHub for the tool - # URL: https://github.com/nvbn/thefuck/tree/master/thefuck/rules - # Look for: {tool}.py, {tool}_*.py - ``` - -2. **Tool's GitHub repository**: - - Search issues for: "typo", "did you mean", "unknown command", "misspelled" - - Check discussions and common questions - - Review CHANGELOG for error message format changes - -3. **Official documentation**: - - Troubleshooting sections - - Common errors documentation - - FAQ pages - -4. **Community resources**: - - Stack Overflow: Search "[tool-name] typo" or "[tool-name] command not found" - - Reddit: r/programming, tool-specific subreddits - - Tool's Discord/Slack if available - -### 2.4 Identify Patterns and Corrections - -Based on your research, identify: - -1. **Error Detection Patterns**: How to recognize each error type -2. **Correction Strategies**: How to fix each error -3. **Fuzzy Matching Needs**: Whether to use `get_close_matches()` -4. **Priority Order**: Which rules should run first -5. **Edge Cases**: Empty args, special chars, nested subcommands - -**Example Analysis for kubectl:** -``` -Errors found: -1. Unknown command: "error: unknown command \"xyz\"" - → Use fuzzy matching against kubectl subcommands -2. Invalid flag: "Error: unknown flag: --xyz" - → Extract flag, fuzzy match against valid flags -3. Resource typo: "error: the server doesn't have a resource type \"pod\"" - → Suggest "pods" (plural form) -4. Missing context: "error: no context exists with the name: \"xyz\"" - → List available contexts from kubectl config -``` - ---- - -## Phase 3: Create Feature Branch - -**MANDATORY: Never work on main/master directly.** +**3. Testing (Min 6 tests/rule)** +- Positive matches (2+), Negative matches (2+), Corrections (1+), Edge cases (1+) +- Use real tool error output +**4. Quality** ```bash -# Verify current branch -git branch --show-current - -# Ensure on main and up-to-date -git checkout main -git pull origin main - -# Create descriptive feature branch -git checkout -b feature/add-TOOL-rules - -# Or for specific error types: -# git checkout -b feature/kubectl-unknown-command -# git checkout -b feature/terraform-typo-correction - -# Verify you're on the new branch -git branch --show-current # Should show feature/add-TOOL-rules - -# Check for uncommitted changes before starting -git status +cargo test && cargo clippy -- -D warnings && cargo fmt --check ``` -**Branch Naming Convention:** -- `feature/add-TOOL-rules` - Adding new tool support -- `feature/TOOL-error-type` - Adding specific error handling -- `fix/TOOL-rule-name` - Fixing existing rule bugs -- `enhance/TOOL-support` - Improving existing tool rules - ---- - -## Phase 4: Implement the Rule - -### 4.1 Choose File Location +**5. Delivery** +- Feature branch: `feature/add--support` +- Commit: `feat(rules): add support for ` +- PR: Summary, rules added, test coverage, examples -**Follow existing categorization strictly:** +## Key Guidelines -| Tool Category | File Path | Examples | -|---------------|-----------|----------| -| Package manager | `src/rules/package_managers/TOOL.rs` | apt, brew, cargo, npm, pip, yarn, gem, composer | -| Cloud/Infrastructure | `src/rules/cloud.rs` | aws, kubectl, terraform, ansible, helm | -| Container/Virtualization | `src/rules/docker.rs` | docker, docker-compose, podman | -| Development tool | `src/rules/devtools.rs` | go, javac, maven, gradle, make, cmake | -| Framework CLI | `src/rules/frameworks.rs` | rails, django, create-react-app, vue-cli | -| System utility | `src/rules/system.rs` | chmod, chown, mkdir, rm, cp, mv, ln | -| Shell utility | `src/rules/shell_utils.rs` | grep, sed, awk, find, xargs | -| Version control | `src/rules/git/*.rs` (git only) | For git, create new file in git/ subdirectory | -| Other popular CLI | `src/rules/misc.rs` | Any tool not fitting above categories | - -**Decision Tree:** -1. Is it a package manager? → `package_managers/` -2. Is it for cloud/K8s/infra? → `cloud.rs` -3. Is it Docker-related? → `docker.rs` -4. Is it a dev build tool? → `devtools.rs` -5. Is it a framework CLI? → `frameworks.rs` -6. Is it for file/permission ops? → `system.rs` -7. Is it a text/file search tool? → `shell_utils.rs` -8. Is it git? → `git/` (separate file per error type) -9. Otherwise → `misc.rs` - -### 4.2 Standard Rule Pattern +**DO:** +✅ Use real error output in tests +✅ Ensure cross-platform compatibility +✅ Handle edge cases (empty output, special chars) +✅ Keep changes focused +✅ Reference thefuck for ideas (translate, don't copy) -**Use this template as your starting point:** +**DON'T:** +❌ Modify core (`src/core/`, `src/config/`, `src/shells/`) +❌ Change Rule trait +❌ Commit to main/master +❌ Skip tests/quality checks +❌ Copy Python code +❌ Add rules requiring network/system changes +❌ Create overly broad matches +## Rule Pattern ```rust use crate::core::{is_app, Command, Rule}; -use crate::utils::get_close_matches; - -/// Rule that fixes TOOL [specific error type] errors. -/// -/// Matches when TOOL reports [describe the error condition] and suggests -/// corrections using [describe strategy: fuzzy matching, regex extraction, etc.]. -/// -/// # Examples -/// -/// ```ignore -/// $ TOOL badcmd -/// error: unknown command 'badcmd' -/// -/// $ oops -/// TOOL goodcmd [enter/↑/↓/ctrl+c] -/// ``` -#[derive(Debug, Clone, Copy, Default)] -pub struct ToolErrorType; - -impl ToolErrorType { - /// Creates a new instance of this rule. - pub fn new() -> Self { - Self - } - - /// Known valid [commands/flags/resources] for TOOL. - /// - /// Gathered from `TOOL --help` output on version X.Y.Z. - /// Update periodically as tool evolves. - const VALID_ITEMS: &'static [&'static str] = &[ - // Populate from: TOOL --help | grep "Commands:" -A 50 - "command1", - "command2", - // ... more items - ]; -} - -impl Rule for ToolErrorType { - fn name(&self) -> &str { - "tool_error_type" // Use snake_case, descriptive name - } - fn priority(&self) -> i32 { - 1000 // Default priority. Lower = runs first. - // Use 900-999 for high-priority rules - // Use 1001+ for fallback rules - } +#[derive(Debug, Clone, Default)] +pub struct MyRule; +impl Rule for MyRule { + fn name(&self) -> &str { "my_rule" } + fn priority(&self) -> i32 { 1000 } fn is_match(&self, cmd: &Command) -> bool { - // Step 1: Verify it's the right tool (CRITICAL for correctness) - if !is_app(cmd, &["tool", "tool.exe"]) { // Include .exe for Windows - return false; - } - - // Step 2: Check for specific error pattern - // Use case-insensitive matching for robustness - let output_lower = cmd.output.to_lowercase(); - - // Match multiple patterns if tool has variations - output_lower.contains("error: unknown command") - || output_lower.contains("is not a tool command") - || output_lower.contains("command not recognized") - - // Avoid overly broad patterns: - // BAD: output.contains("error") // Too generic! - // GOOD: output.contains("unknown command") + is_app(cmd, &["tool"]) && cmd.output.contains("error") } - fn get_new_command(&self, cmd: &Command) -> Vec { - // Parse command to extract the typo - let parts = cmd.script_parts(); - if parts.len() < 2 { - // No subcommand provided, can't correct - return vec![]; - } - - let typo = &parts[1]; // Usually subcommand is second part - - // Strategy 1: Use fuzzy matching (most common) - get_close_matches(typo, Self::VALID_ITEMS, 3, 0.6) - .into_iter() - .map(|suggestion| cmd.script.replace(typo, &suggestion)) - .collect() - - // Strategy 2: Extract suggestion from output (if tool provides it) - // use regex::Regex; - // let re = Regex::new(r"Did you mean '([^']+)'").unwrap(); - // if let Some(caps) = re.captures(&cmd.output) { - // let suggestion = caps.get(1).unwrap().as_str(); - // return vec![cmd.script.replace(typo, suggestion)]; - // } - // vec![] - - // Strategy 3: Simple string replacement - // vec![cmd.script.replace("wrong", "right")] - } - - // Optional: Override if rule doesn't need output - // fn requires_output(&self) -> bool { - // false // Set to false if matching on script alone - // } - - // Optional: Implement if post-correction action needed - // fn side_effect(&self, _old_cmd: &Command, _new_script: &str) -> anyhow::Result<()> { - // // Example: Update config file, add alias, etc. - // // Only use when absolutely necessary! - // Ok(()) - // } -} -``` - -### 4.3 Cross-Platform Compatibility (CRITICAL) - -**All rules MUST work on Windows, macOS, and Linux.** Follow these requirements: - -#### Command Detection -```rust -// ✅ GOOD: Cross-platform command detection -fn is_match(&self, cmd: &Command) -> bool { - is_app(cmd, &["tool", "tool.exe"]) // Handles both Unix and Windows - && cmd.output.contains("error") -} - -// ❌ BAD: Unix-only assumption -fn is_match(&self, cmd: &Command) -> bool { - cmd.script.starts_with("./tool") // Breaks on Windows! -} -``` - -#### Line Ending Handling -```rust -// ✅ GOOD: Handle both \n and \r\n -let lines: Vec<&str> = cmd.output.lines().collect(); // .lines() handles both - -for line in cmd.output.lines() { - // Process each line -} - -// ❌ BAD: Only handles Unix line endings -let lines: Vec<&str> = cmd.output.split('\n').collect(); // Misses \r on Windows -``` - -#### Path Separators -```rust -// ✅ GOOD: Use std::path or handle both separators -use std::path::MAIN_SEPARATOR; - -if path.contains('/') || path.contains('\\') { - // Handle path -} - -// ❌ BAD: Hardcode Unix separator -if path.contains('/') { // Breaks on Windows paths - // Handle path -} -``` - -#### Case Sensitivity -```rust -// ✅ GOOD: Case-insensitive where appropriate -let output_lower = cmd.output.to_lowercase(); -if output_lower.contains("error") { - // Match -} - -// Windows filenames are case-insensitive -let filename_lower = filename.to_lowercase(); - -// ⚠️ CONTEXT-DEPENDENT: Unix filenames are case-sensitive -// Be careful when matching filenames from output -``` - -#### Platform-Specific Commands -```rust -// ✅ GOOD: Check if command exists before suggesting -use crate::utils::which; - -fn get_new_command(&self, cmd: &Command) -> Vec { - let suggestions = vec!["vim", "nano", "notepad"]; - suggestions.into_iter() - .filter(|&cmd| which(cmd).is_some()) // Only suggest if available - .map(|editor| format!("{} file.txt", editor)) - .collect() -} - -// ❌ BAD: Suggest Unix-only commands on Windows -fn get_new_command(&self, cmd: &Command) -> Vec { - vec!["vim file.txt".to_string()] // Breaks if vim not on Windows -} -``` - -#### Shell Differences -```rust -// ✅ GOOD: Don't assume bash-specific syntax -// Rules should work with bash, zsh, fish, powershell, tcsh - -// ❌ BAD: Use bash-specific features -// vec!["command ${VAR}".to_string()] // ${} may not work in all shells -``` - -### 4.4 Register the Rule - -After creating your rule, register it in the appropriate module: - -**Option A: Add to category file's pub functions (preferred)** -```rust -// In src/rules/cloud.rs (if adding to existing category file) -pub fn all_cloud_rules() -> Vec> { - vec![ - // ... existing rules - Box::new(ToolErrorType::new()), - ] -} -``` - -**Option B: Add to main registry** -```rust -// In src/rules/mod.rs -pub fn get_all_rules() -> Vec> { - let mut rules = Vec::new(); - - // ... existing categories - - // Add your rule - rules.push(Box::new(tool::ToolErrorType::new())); - - rules -} - -// Don't forget to add module declaration at top of file: -pub mod tool; -``` - -**Option C: Create new module for complex tools** -```rust -// In src/rules/mod.rs -pub mod tool; // Add module declaration - -// Create src/rules/tool.rs or src/rules/tool/mod.rs -// Implement multiple rules, then export in mod.rs: -pub fn all_tool_rules() -> Vec> { - vec![ - Box::new(ToolUnknownCommand::new()), - Box::new(ToolInvalidFlag::new()), - Box::new(ToolMissingArg::new()), - ] -} -``` - -### 4.5 Common Patterns and Utilities - -#### Using Regex for Extraction -```rust -use regex::Regex; - -fn get_new_command(&self, cmd: &Command) -> Vec { - let re = Regex::new(r"error: unknown command '([^']+)'").unwrap(); - - if let Some(caps) = re.captures(&cmd.output) { - let wrong_cmd = caps.get(1).map(|m| m.as_str()).unwrap_or(""); - // Use wrong_cmd for fuzzy matching or replacement - } - - vec![] -} -``` - -#### Replace Argument Helper -```rust -use crate::utils::replace_argument; - -fn get_new_command(&self, cmd: &Command) -> Vec { - let matches = get_close_matches("typo", &["correct"], 3, 0.6); - matches.into_iter() - .map(|m| replace_argument(&cmd.script, "typo", &m)) - .collect() -} -``` - -#### Multiple Error Patterns -```rust -fn is_match(&self, cmd: &Command) -> bool { - if !is_app(cmd, &["tool"]) { - return false; - } - - let output = &cmd.output; - - // Match any of several error patterns - ["unknown command", "not recognized", "invalid subcommand"] - .iter() - .any(|pattern| output.to_lowercase().contains(pattern)) -} -``` - ---- - -## Phase 5: Write Comprehensive Tests - -**MANDATORY: Every rule requires minimum 6 test categories. Use REAL error output from the tool.** - -### 5.1 Test Structure Template - -```rust -#[cfg(test)] -mod tests { - use super::*; - use crate::core::Command; - - // Test 1: Verify rule name is correct - #[test] - fn test_tool_error_type_name() { - let rule = ToolErrorType::new(); - assert_eq!(rule.name(), "tool_error_type"); - } - - // Test 2: Positive match - rule SHOULD trigger - // CRITICAL: Use ACTUAL error output from running the tool - #[test] - fn test_tool_error_type_matches() { - let rule = ToolErrorType::new(); - - // Real error output captured from: tool badcmd - let cmd = Command::new( - "tool badcmd", - "error: unknown command 'badcmd'\n\n\ - See 'tool --help' for available commands.\n" - ); - - assert!(rule.is_match(&cmd)); - } - - // Test 3: Positive match with variations - #[test] - fn test_tool_error_type_matches_alternative_format() { - let rule = ToolErrorType::new(); - - // Some tools have multiple error formats - let cmd = Command::new( - "tool xyz", - "Error: 'xyz' is not a tool command. Did you mean 'xy'?\n" - ); - - assert!(rule.is_match(&cmd)); - } - - // Test 4: Negative match - wrong tool - #[test] - fn test_tool_error_type_not_matches_different_tool() { - let rule = ToolErrorType::new(); - - // Similar error but from different tool - let cmd = Command::new( - "othertool badcmd", - "error: unknown command 'badcmd'\n" - ); - - assert!(!rule.is_match(&cmd), "Should not match different tool"); - } - - // Test 5: Negative match - success output - #[test] - fn test_tool_error_type_not_matches_success() { - let rule = ToolErrorType::new(); - - // Successful command execution - let cmd = Command::new( - "tool status", - "Status: OK\nEverything is working correctly.\n" - ); - - assert!(!rule.is_match(&cmd), "Should not match successful commands"); - } - - // Test 6: Negative match - different error - #[test] - fn test_tool_error_type_not_matches_different_error() { - let rule = ToolErrorType::new(); - - // Different error type from same tool - let cmd = Command::new( - "tool cmd --invalid-flag", - "error: unknown flag --invalid-flag\n" - ); - - assert!(!rule.is_match(&cmd), "Should not match different error types"); - } - - // Test 7: Correction generation - single match - #[test] - fn test_tool_error_type_generates_correction() { - let rule = ToolErrorType::new(); - - // Typo: "statsu" should suggest "status" - let cmd = Command::new( - "tool statsu", - "error: unknown command 'statsu'\n" - ); - - let fixes = rule.get_new_command(&cmd); - - assert!(!fixes.is_empty(), "Should generate at least one correction"); - assert!( - fixes.iter().any(|f| f.contains("status")), - "Should suggest 'status', got: {:?}", fixes - ); - } - - // Test 8: Correction generation - multiple matches - #[test] - fn test_tool_error_type_multiple_corrections() { - let rule = ToolErrorType::new(); - - // Ambiguous typo that could match multiple commands - let cmd = Command::new( - "tool chec", - "error: unknown command 'chec'\n" - ); - - let fixes = rule.get_new_command(&cmd); - - // If tool has both "check" and "checkout" commands - assert!(fixes.len() >= 1, "Should generate corrections"); - // Verify corrections maintain the rest of the command - for fix in &fixes { - assert!(fix.starts_with("tool "), "Should preserve tool prefix"); - } - } - - // Test 9: Edge case - no subcommand - #[test] - fn test_tool_error_type_no_subcommand() { - let rule = ToolErrorType::new(); - - let cmd = Command::new( - "tool", - "error: no command specified\n" - ); - - let fixes = rule.get_new_command(&cmd); - - // Should handle gracefully without panicking - // Depending on rule logic, might return empty or help suggestion - assert!(fixes.is_empty() || !fixes.is_empty()); // No panic = success - } - - // Test 10: Edge case - empty output - #[test] - fn test_tool_error_type_empty_output() { - let rule = ToolErrorType::new(); - - let cmd = Command::new("tool cmd", ""); - - assert!(!rule.is_match(&cmd), "Should not match empty output"); - } - - // Test 11: Edge case - special characters in command - #[test] - fn test_tool_error_type_special_chars() { - let rule = ToolErrorType::new(); - - let cmd = Command::new( - "tool cmd --flag='value with spaces'", - "error: unknown command 'cmd'\n" - ); - - let fixes = rule.get_new_command(&cmd); - - // Should preserve special chars and quoting - if !fixes.is_empty() { - assert!(fixes[0].contains("--flag='value with spaces'")); - } - } - - // Test 12: Edge case - command with pipe or redirect - #[test] - fn test_tool_error_type_preserves_pipes() { - let rule = ToolErrorType::new(); - - let cmd = Command::new( - "tool badcmd | grep foo", - "error: unknown command 'badcmd'\n" - ); - - let fixes = rule.get_new_command(&cmd); - - // Should preserve the pipe - if !fixes.is_empty() { - assert!(fixes[0].contains("| grep foo")); - } - } - - // Test 13: Cross-platform - Windows .exe - #[test] - fn test_tool_error_type_matches_windows_exe() { - let rule = ToolErrorType::new(); - - // Simulate Windows command with .exe - let cmd = Command::new( - "tool.exe badcmd", - "error: unknown command 'badcmd'\n" - ); - - assert!(rule.is_match(&cmd), "Should match .exe on Windows"); - } - - // Test 14: Cross-platform - case insensitivity - #[test] - fn test_tool_error_type_case_insensitive() { - let rule = ToolErrorType::new(); - - // Error messages might vary in casing - let cmd = Command::new( - "tool badcmd", - "ERROR: UNKNOWN COMMAND 'badcmd'\n" // All caps - ); - - // Should still match if using case-insensitive detection - assert!(rule.is_match(&cmd)); - } - - // Test 15: Priority (if custom) - #[test] - fn test_tool_error_type_priority() { - let rule = ToolErrorType::new(); - - // Verify priority is set correctly - assert_eq!(rule.priority(), 1000); // Or your custom value - } - - // Test 16: Enabled by default - #[test] - fn test_tool_error_type_enabled_by_default() { - let rule = ToolErrorType::new(); - - assert!(rule.enabled_by_default()); - } - - // Test 17: Requires output - #[test] - fn test_tool_error_type_requires_output() { - let rule = ToolErrorType::new(); - - assert!(rule.requires_output()); // Or false if your rule doesn't need it + vec![format!("fixed {}", cmd.script)] } } ``` -### 5.2 Testing Best Practices - -**DO:** -✅ Use real error messages from actually running the tool -✅ Test both positive and negative cases -✅ Test edge cases: empty input, no args, special chars -✅ Test Windows compatibility (`.exe` suffix) -✅ Test case variations in error messages -✅ Add descriptive failure messages: `assert!(condition, "Expected X, got Y")` -✅ Test that corrections preserve command structure -✅ Test all public methods: priority(), enabled_by_default(), requires_output() - -**DON'T:** -❌ Use hypothetical error messages you made up -❌ Only test the happy path -❌ Skip edge cases -❌ Write tests that can't fail -❌ Use `assert!(true)` or similar meaningless assertions -❌ Forget to test cross-platform scenarios - -### 5.3 How to Get Real Error Output for Tests - -```bash -# Capture error to a file for copy-paste into tests -tool badcommand 2>&1 | tee error_output.txt - -# Test multiple scenarios -tool badcmd 2>&1 > test_unknown_cmd.txt -tool --badflg 2>&1 > test_invalid_flag.txt -tool cmd arg1 arg2 2>&1 > test_missing_arg.txt - -# Include version info in test comments -tool --version # e.g., "tool version 2.15.0" -# Add to test: "Tested with tool v2.15.0" -``` - -### 5.4 Running Tests - -```bash -# Run all tests -cargo test - -# Run only your new rule's tests -cargo test tool_error_type - -# Run with output shown (helpful for debugging) -cargo test tool_error_type -- --nocapture - -# Run specific test -cargo test test_tool_error_type_matches - -# Run tests and show which ones pass/fail -cargo test -- --test-threads=1 -``` - ---- - -## Phase 6: Run All Quality Checks - -**MANDATORY: All checks must pass before proceeding to PR.** - -### 6.1 Test Execution - -```bash -# Run all tests (MUST pass 100%) -cargo test - -# Run with verbose output to see details -cargo test -- --nocapture - -# Run only your new rule tests -cargo test tool_error_type - -# Check test coverage (if available) -# cargo tarpaulin --out Html -``` - -**Expected output:** -``` -running 17 tests -test tests::test_tool_error_type_name ... ok -test tests::test_tool_error_type_matches ... ok -test tests::test_tool_error_type_not_matches_different_tool ... ok -... -test result: ok. 17 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out -``` - -### 6.2 Linting (Clippy) - -```bash -# Run clippy with warnings treated as errors (MUST pass) -cargo clippy -- -D warnings - -# Run on all targets -cargo clippy --all-targets -- -D warnings - -# Fix auto-fixable issues -cargo clippy --fix -``` - -**Common clippy warnings to fix:** -- Unused imports -- Unused variables (prefix with `_` if intentional) -- Needless borrows -- Redundant clones -- Missing documentation on public items - -### 6.3 Code Formatting - -```bash -# Check if code is formatted correctly -cargo fmt --check - -# Format code automatically -cargo fmt - -# Format specific file -cargo fmt -- src/rules/tool.rs -``` - -### 6.4 Build Verification - -```bash -# Debug build (fast, for development) -cargo build - -# Release build (optimized, final check) -cargo build --release - -# Check without building (fast syntax check) -cargo check -``` - -### 6.5 Integration Check - -```bash -# Verify binary works -./target/release/oops --version - -# Test alias generation for all shells -TF_SHELL=bash ./target/release/oops --alias | head -5 -TF_SHELL=zsh ./target/release/oops --alias | head -5 -TF_SHELL=fish ./target/release/oops --alias | head -5 -TF_SHELL=powershell ./target/release/oops --alias | head -5 -TF_SHELL=tcsh ./target/release/oops --alias | head -5 - -# Simulate the tool's error (optional, if tool installed) -# export PREVIOUS_COMMAND="tool badcmd" -# export PREVIOUS_OUTPUT="error: unknown command 'badcmd'" -# ./target/release/oops -``` - -### 6.6 Quality Checklist - -Before proceeding, verify all items: - -- [ ] `cargo test` passes with 0 failures -- [ ] `cargo clippy -- -D warnings` passes with 0 warnings -- [ ] `cargo fmt --check` passes -- [ ] `cargo build --release` succeeds -- [ ] All 5 shells generate alias successfully -- [ ] Rule has minimum 6 tests (ideally 10-17) -- [ ] Tests use real error output from the tool -- [ ] Cross-platform: handles `.exe`, case sensitivity, line endings -- [ ] No unwrap() calls that could panic (use `?` or `unwrap_or`) -- [ ] Documentation comments on public items -- [ ] Rule registered in module system - ---- - -## Phase 7: Update Documentation (If Significant) - -**Only update docs for significant additions or new tool categories.** - -### 7.1 When to Update Docs - -**Update docs if:** -- Adding a popular, well-known tool (kubectl, terraform, docker, etc.) -- Adding a new tool category -- Adding 3+ rules for a single tool -- Adding first rule for a package manager or cloud platform - -**Skip docs update if:** -- Adding minor tools to misc.rs -- Adding single rule to existing category -- Improving existing rules -- Bug fixes - -### 7.2 Files to Update - -**README.md** (if major tool): -```markdown -## Supported Tools - -### Cloud & Infrastructure -- AWS CLI - credential errors, region issues, profile selection -- kubectl - resource typos, context errors, namespace issues ← Add here -- terraform - init required, workspace errors -``` - -**CLAUDE.md** (if new category): -```markdown -## Rule Categories - -Rules are organized by category: -- `git/` - Git operations (push, checkout, add, branch, etc.) -- `package_managers/` - apt, brew, cargo, npm, pip, etc. -- `kubernetes/` - kubectl, helm, k9s ← Add new category -- `cloud.rs` - AWS, Azure, Heroku -``` - -**CHANGELOG.md** (always update): -```markdown -## [Unreleased] - -### Added -- Add kubectl unknown command correction -- Add kubectl resource type typo correction -- Add kubectl context not found handling -``` - -### 7.3 Updating README Example - -```markdown - - -### Package Managers (27 rules) -- apt, brew, cargo, npm, pip, yarn, gem, composer, bundle - -### Cloud & Infrastructure (X rules) ← Update count -- AWS CLI, kubectl, terraform, ansible, helm ← Add tool -``` - -### 7.4 Documentation Standards - -- Keep descriptions concise (1 line per tool) -- List in alphabetical order within categories -- Update rule counts accurately -- Include real-world examples if adding to README -- Link to tool's official site if adding major tool section - ---- - -## Phase 8: Commit with Descriptive Message - -**Use conventional commit format with detailed description.** - -### 8.1 Stage Your Changes - -```bash -# Check what changed -git status - -# Review changes before staging -git diff src/rules/ - -# Stage only rule-related files -git add src/rules/tool.rs -git add src/rules/mod.rs # If you modified registry - -# Or stage all changes if appropriate -git add src/rules/ docs/ - -# Verify staged changes -git diff --staged -``` - -### 8.2 Write Commit Message - -**Format: `type(scope): subject`** - -```bash -git commit -m "feat(rules): add TOOL command corrections - -- Add ToolUnknownCommand rule for unknown subcommand errors -- Add ToolInvalidFlag rule for invalid flag/option errors -- Add ToolResourceTypo rule for resource name typos -- Add 17 comprehensive unit tests covering all scenarios -- Tested with TOOL version X.Y.Z -- Cross-platform: handles Windows .exe, case-insensitive matching - -Fixes common errors like: - $ TOOL statsu → TOOL status - $ TOOL --versoin → TOOL --version - $ TOOL pod → TOOL pods - -Closes #123" # If there's an issue - -# Alternative commit types: -# feat(rules): add new rules -# fix(rules): fix existing rule bugs -# test(rules): add missing tests -# docs: update documentation -# refactor(rules): restructure rule code -``` - -### 8.3 Commit Message Best Practices - -**DO:** -✅ Start with conventional commit type (feat, fix, docs, test, refactor) -✅ Add scope in parentheses: (rules), (git), (cloud) -✅ Use imperative mood: "add" not "added" or "adds" -✅ List all rules added with clear names -✅ Include test count -✅ Mention TOOL version tested against -✅ Provide before/after examples -✅ Reference issues with "Closes #123" or "Fixes #456" -✅ Add co-author if AI-assisted: `Co-Authored-By: Claude Opus 4.5 ` - -**DON'T:** -❌ Write vague messages: "updated stuff" or "fixes" -❌ Forget to mention cross-platform testing -❌ Omit test coverage info -❌ Use past tense: "added rules" -❌ Make giant commits with unrelated changes - -### 8.4 Verify Commit - -```bash -# View commit before pushing -git show HEAD - -# Check commit message format -git log -1 --pretty=format:"%s%n%b" - -# Amend if needed (before pushing) -git commit --amend -``` - -### 8.5 Push to Feature Branch - -```bash -# Push feature branch to remote -git push -u origin feature/add-TOOL-rules - -# If branch already pushed, just: -git push - -# Verify branch on GitHub -gh repo view --web # Opens repo in browser -``` - ---- - -## Phase 9: Create Pull Request - -**Create a comprehensive, well-documented PR ready for review.** - -### 9.1 PR Creation via GitHub CLI - -```bash -# Create PR with detailed description -gh pr create \ - --title "feat(rules): add TOOL command corrections" \ - --body "$(cat <<'EOF' -## Summary - -Adds command correction support for TOOL, fixing common typos and command errors. -Addresses issue #XXX (if applicable). - -## Rules Added - -- **`tool_unknown_command`** - Fixes unknown subcommand errors using fuzzy matching -- **`tool_invalid_flag`** - Corrects invalid flag/option typos -- **`tool_resource_typo`** - Handles resource name misspellings (if applicable) - -## Test Coverage - -- 17 comprehensive unit tests added -- All tests use real error output from TOOL v2.15.0 -- Tests cover: positive/negative matching, edge cases, cross-platform scenarios -- Test coverage: match detection, correction generation, Windows .exe handling - -## Quality Checklist - -- [x] `cargo test` passes (0 failures, 0 warnings) -- [x] `cargo clippy -- -D warnings` passes -- [x] `cargo fmt --check` passes -- [x] Release build succeeds -- [x] All 5 shell integrations generate aliases successfully -- [x] Cross-platform tested (Windows .exe, case sensitivity, line endings) -- [x] Uses `is_app()` for command detection -- [x] Uses `get_close_matches()` for fuzzy matching -- [x] No unwrap() calls that could panic -- [x] Documentation updated (if significant tool) - -## Example Corrections - -### Unknown Command -\`\`\`bash -$ TOOL statsu -error: unknown command 'statsu' - -$ oops -TOOL status [enter/↑/↓/ctrl+c] -\`\`\` - -### Invalid Flag -\`\`\`bash -$ TOOL status --verbos -error: unknown flag: --verbos - -$ oops -TOOL status --verbose [enter/↑/↓/ctrl+c] -\`\`\` - -### Resource Typo (if applicable) -\`\`\`bash -$ kubectl get pod -error: the server doesn't have a resource type "pod" - -$ oops -kubectl get pods [enter/↑/↓/ctrl+c] -\`\`\` - -## Cross-Platform Compatibility - -- [x] Uses `is_app(cmd, &["tool", "tool.exe"])` for Windows support -- [x] Case-insensitive error matching via `.to_lowercase()` -- [x] Line ending agnostic (uses `.lines()` instead of `.split('\n')`) -- [x] No Unix-specific path assumptions -- [x] No bash-specific syntax in corrections - -## Tool Version Tested - -- **TOOL version**: 2.15.0 -- **Platform**: macOS 13.4, Ubuntu 22.04, Windows 11 -- **Error messages verified**: All test cases use actual error output - -## Performance - -- Rule evaluation: <1ms per command -- No external dependencies added -- No network calls or file I/O - -## Breaking Changes - -None. This is purely additive. - -## Related Issues - -Closes #XXX (if applicable) -Ref #YYY (if related) - ---- - -**Note**: Generated with AI assistance from Claude Opus 4.5. -Please review for correctness and suggest improvements. -EOF -)" \ - --assignee @me \ - --label "enhancement,rules" - -# Or use interactive mode -gh pr create -``` - -### 9.2 PR Title Guidelines - -**Format**: `type(scope): concise description` - -**Examples:** -- ✅ `feat(rules): add kubectl command corrections` -- ✅ `feat(cloud): add terraform unknown command rule` -- ✅ `fix(git): improve branch typo detection` -- ❌ `Added some kubectl stuff` -- ❌ `Update rules` - -### 9.3 PR Description Template - -If not using CLI, create PR with this template: - -```markdown -## Summary -[1-2 sentence description of what this PR adds] - -## Rules Added -- `rule_name_1` - [description] -- `rule_name_2` - [description] - -## Test Coverage -- X unit tests added -- Tests use real error output from TOOL vX.Y.Z -- [Coverage details] - -## Quality Checklist -- [ ] `cargo test` passes -- [ ] `cargo clippy` passes -- [ ] `cargo fmt --check` passes -- [ ] Cross-platform compatible -- [ ] Documentation updated (if needed) - -## Example Corrections -[Show before/after examples] - -## Cross-Platform Compatibility -[Explain Windows/macOS/Linux considerations] - -## Related Issues -Closes #XXX -``` - -### 9.4 After PR Creation - -```bash -# View PR in browser -gh pr view --web - -# Check CI status -gh pr checks - -# If CI fails, fix and push updates -git add . -git commit -m "fix: address CI failures" -git push - -# Request review from maintainers -gh pr ready # Mark as ready for review -``` - -### 9.5 Responding to Review Comments - -```bash -# Make requested changes -# Edit files as needed - -# Commit with descriptive message -git add src/rules/tool.rs -git commit -m "refactor: address PR review feedback - -- Use more specific error matching -- Add test for Windows path scenario -- Fix clippy warning about unused import" - -# Push update -git push - -# Respond to comments on GitHub -gh pr comment --body "Updated as requested. PTAL." -``` - ---- - -## Discovery Mode: Finding High-Value Tools - -When asked to recommend tools to support, follow this systematic research process: - -### Step 1: Analyze Current Coverage - -```bash -# What tools are already covered? -grep -rh "is_app.*&\[" src/rules/ | sed 's/.*&\[//;s/\].*//' | tr ',' '\n' | tr -d '"' | sort -u - -# What categories exist? -ls -1 src/rules/ - -# Count rules per category -echo "Git rules:" && ls -1 src/rules/git/*.rs 2>/dev/null | wc -l -echo "Package manager rules:" && ls -1 src/rules/package_managers/*.rs 2>/dev/null | wc -l -echo "Total rules:" && grep -r "impl Rule for" src/rules/ | wc -l - -# Check if a specific tool is already covered -grep -r "is_app.*kubectl" src/rules/ -``` - -### Step 2: Research Popular CLI Tools Not Yet Covered - -**Search strategies:** - -1. **Web search queries:** - - "most popular command line tools 2024" - - "essential CLI tools for developers" - - "best terminal applications GitHub stars" - - "command line tools every developer should know" - -2. **GitHub exploration:** - - Search: `topic:cli language:Rust stars:>1000` - - Search: `topic:command-line stars:>5000` - - Browse: https://github.com/topics/cli - - Browse: https://github.com/topics/command-line-tool - -3. **Check thefuck's coverage:** - - URL: https://github.com/nvbn/thefuck/tree/master/thefuck/rules - - Compare each rule file against oops coverage - - Identify rules thefuck has but oops doesn't - -4. **Community resources:** - - Hacker News: "CLI tools" searches - - Reddit: r/commandline, r/programming - - Dev.to: CLI tool articles - - Awesome lists: awesome-cli, awesome-shell - -### Step 3: Evaluate Candidate Tools - -For each candidate, research and document: - -#### 3.1 Popularity Metrics -```bash -# GitHub stars (if open source) -gh repo view OWNER/REPO --json stargazersCount - -# Package downloads (if applicable) -# npm: https://npmjs.com/package/TOOL -# PyPI: https://pypython.org/project/TOOL -# cargo: https://crates.io/crates/TOOL -# brew: brew info TOOL -``` - -#### 3.2 Error Frequency Analysis -- Search Stack Overflow: `[tool-name] error typo` -- Count questions: More questions = more errors users encounter -- Check GitHub issues: Search for "typo", "unknown command", "did you mean" -- Estimate error-proneness: More subcommands = more typos - -#### 3.3 Complexity Assessment -```bash -# Install tool and analyze -TOOL --help | grep -i commands -A 50 # Count subcommands -TOOL --help | grep -i "^\s*[a-z]" | wc -l # Count options -TOOL help # Some tools use different help format - -# Assess complexity: -# - 0-5 subcommands: Low value (unless very popular) -# - 6-20 subcommands: Medium value -# - 20+ subcommands: High value (more error opportunities) -``` - -#### 3.4 Cross-Platform Check -- Is it available on Windows? (check: `choco search TOOL`, `scoop search TOOL`) -- Is it available on macOS? (check: `brew search TOOL`) -- Is it available on Linux? (check: `apt search TOOL`, `yum search TOOL`) -- Tools available on all 3 platforms = higher priority - -#### 3.5 Error Pattern Investigation -```bash -# Install and test error scenarios -TOOL --help # Understand structure -TOOL invalid-command 2>&1 # See error format -TOOL cmd --invalid-flag 2>&1 # Test flag errors - -# Document findings: -# - Does it provide "did you mean" suggestions? -# - Are error messages consistent and parseable? -# - Are there multiple error types to handle? -``` - -### Step 4: Score and Rank Candidates - -Create scoring matrix: - -| Tool | Stars | Downloads | Subcommands | Platforms | thefuck? | Score | Priority | -|------|-------|-----------|-------------|-----------|----------|-------|----------| -| kubectl | 109k | High | 30+ | 3/3 | ✅ | 95 | High | -| terraform | 42k | High | 15+ | 3/3 | ✅ | 90 | High | -| ansible | 62k | High | 20+ | 3/3 | ❌ | 85 | High | -| httpie | 33k | Medium | 8 | 3/3 | ✅ | 70 | Medium | -| jq | 30k | High | 0* | 3/3 | ❌ | 50 | Low | - -*jq has no subcommands, mainly filters - lower correction value - -**Scoring formula:** -``` -Score = (stars/1000) * 0.2 - + (subcommands) * 2 - + (platforms/3) * 20 - + (thefuck_exists ? 10 : 0) - + (downloads_high ? 15 : 0) -``` - -### Step 5: Present Recommendation - -**Format your recommendation as:** - -```markdown -## Recommended Tools to Add - -### High Priority - -#### 1. kubectl (Kubernetes CLI) -- **Popularity**: 109k GitHub stars, millions of downloads -- **Complexity**: 30+ subcommands (get, apply, delete, describe, logs, etc.) -- **Error Frequency**: 5,200+ Stack Overflow questions with "kubectl error" -- **Platforms**: ✅ Windows, ✅ macOS, ✅ Linux -- **thefuck support**: Yes (reference: thefuck/rules/kubectl.py) -- **Error patterns found**: - - Unknown command: "error: unknown command \"xyz\"" - - Resource typo: "error: the server doesn't have a resource type \"pod\"" - - Context not found: "error: no context exists with the name: \"xyz\"" - - Invalid flag: "Error: unknown flag: --xyz" -- **Estimated implementation**: 3-4 rules, ~15-20 tests -- **Value**: Very High - Used daily by DevOps/SRE professionals - -#### 2. terraform (Infrastructure as Code) -[Similar format] - -### Medium Priority - -#### 3. ansible (Configuration Management) -[Similar format] - -### Low Priority - -#### 4. httpie (HTTP client) -[Similar format] - -## Recommendation - -Start with **kubectl** for these reasons: -1. Extremely popular in cloud-native development -2. Complex with many error-prone subcommands -3. Clear, parseable error messages -4. thefuck already has rules we can reference -5. High impact: widely used in CI/CD pipelines - -## Implementation Roadmap - -1. Phase 1: kubectl unknown command + resource typo (Week 1) -2. Phase 2: kubectl context errors + flag typos (Week 2) -3. Phase 3: terraform if time permits (Week 3) -``` - -### Step 6: Gap Analysis for Existing Tools - -If asked to improve existing support: - -```bash -# Find partially supported tools -grep -rh "is_app.*docker" src/rules/ # What docker rules exist? -docker --help # What docker commands exist? - -# Identify gaps: -# - Which subcommands aren't covered? -# - Which error types aren't handled? -# - Are there new features in recent versions? - -# Compare with thefuck -# Check: https://github.com/nvbn/thefuck/blob/master/thefuck/rules/docker.py -# What does thefuck handle that oops doesn't? -``` - -**Gap report format:** -```markdown -## Gap Analysis: Docker - -### Current Coverage (in oops) -- docker_not_command: Unknown command errors ✅ -- docker_permission_denied: Permission errors ✅ - -### Missing Coverage -- Container name typos when using logs/exec/stop -- Volume mount path errors -- Network not found errors -- Image tag typos -- Port binding syntax errors - -### Recommendation -Add 3 more rules to improve docker support: -1. docker_container_typo: Fuzzy match container names -2. docker_image_tag_typo: Suggest correct tags -3. docker_network_not_found: List available networks -``` - ---- - -## Pre-PR Quality Checklist - -**Complete this checklist before creating your PR:** - -### Code Quality -- [ ] Rule follows existing patterns in `src/rules/` -- [ ] Uses `is_app(cmd, &["tool", "tool.exe"])` for command detection -- [ ] Uses `get_close_matches()` for fuzzy matching (when applicable) -- [ ] No `unwrap()` calls that could panic (use `?`, `unwrap_or`, or `match`) -- [ ] No `panic!()` or `unreachable!()` in production code -- [ ] Handles empty/None cases gracefully -- [ ] Error messages are descriptive and helpful - -### Testing -- [ ] Minimum 6 tests per rule (ideally 10-17) -- [ ] Tests use REAL error output captured from actual tool -- [ ] Positive match tests (rule should trigger) -- [ ] Negative match tests (wrong tool, success output, different error) -- [ ] Correction generation tests (verify expected fixes) -- [ ] Edge case tests (no args, empty output, special chars) -- [ ] Cross-platform tests (Windows .exe, case sensitivity) -- [ ] All test names are descriptive: `test_tool_error_matches` not `test1` - -### Cross-Platform -- [ ] Handles Windows: `is_app(cmd, &["tool", "tool.exe"])` -- [ ] Case-insensitive matching: `output.to_lowercase().contains(...)` -- [ ] Line ending agnostic: use `.lines()` not `.split('\n')` -- [ ] No hardcoded Unix paths: no assumptions about `/` vs `\` -- [ ] No bash-specific syntax in generated corrections -- [ ] No platform-specific commands without checking availability - -### Quality Checks -- [ ] `cargo test` passes (0 failures) -- [ ] `cargo clippy -- -D warnings` passes (0 warnings) -- [ ] `cargo fmt --check` passes -- [ ] `cargo build --release` succeeds -- [ ] All 5 shells generate alias: bash, zsh, fish, powershell, tcsh - -### Registration & Documentation -- [ ] Rule registered in `src/rules/mod.rs` or category module -- [ ] Module declared if new file created -- [ ] Documentation updated (README, CLAUDE.md) if significant tool -- [ ] CHANGELOG.md updated with entry in [Unreleased] section - -### Git & PR -- [ ] Working on feature branch, not main/master -- [ ] Commits follow conventional commit format -- [ ] Commit messages are descriptive with examples -- [ ] PR title follows format: `type(scope): description` -- [ ] PR description is comprehensive with examples -- [ ] No unrelated changes or refactoring -- [ ] Git history is clean (squash if needed) - -### Performance & Safety -- [ ] Rule evaluation is fast (<1ms) -- [ ] No network calls or external I/O -- [ ] No file system modifications in `is_match()` or `get_new_command()` -- [ ] `side_effect()` only used when absolutely necessary -- [ ] No added dependencies (or if added, justified and vulnerability-checked) - ---- - -## Common Mistakes to Avoid - -### 1. Using Fake Error Messages -❌ **BAD**: Making up error messages -```rust -let cmd = Command::new("tool xyz", "error: bad command"); // Hypothetical! -``` - -✅ **GOOD**: Using real error output -```rust -// Captured from: tool xyz -let cmd = Command::new("tool xyz", "tool: 'xyz' is not a tool command. See 'tool --help'."); -``` - -### 2. Overly Broad Pattern Matching -❌ **BAD**: Matching too generically -```rust -fn is_match(&self, cmd: &Command) -> bool { - cmd.output.contains("error") // TOO BROAD! Matches everything -} -``` - -✅ **GOOD**: Specific pattern matching -```rust -fn is_match(&self, cmd: &Command) -> bool { - is_app(cmd, &["tool"]) - && cmd.output.contains("is not a tool command") -} -``` - -### 3. Platform-Specific Assumptions -❌ **BAD**: Unix-only code -```rust -fn is_match(&self, cmd: &Command) -> bool { - cmd.script.starts_with("./tool") // Breaks on Windows! -} -``` - -✅ **GOOD**: Cross-platform code -```rust -fn is_match(&self, cmd: &Command) -> bool { - is_app(cmd, &["tool", "tool.exe"]) // Works everywhere -} -``` - -### 4. Hardcoding Version-Specific Error Messages -❌ **BAD**: Hardcoding exact error text -```rust -fn is_match(&self, cmd: &Command) -> bool { - cmd.output == "Error: unknown command 'xyz' in tool v2.1.0" // Breaks on v2.2.0! -} -``` - -✅ **GOOD**: Flexible pattern matching -```rust -fn is_match(&self, cmd: &Command) -> bool { - cmd.output.to_lowercase().contains("unknown command") // Version-agnostic -} -``` - -### 5. Panicking Code -❌ **BAD**: Using unwrap() that can panic -```rust -fn get_new_command(&self, cmd: &Command) -> Vec { - let parts = cmd.script.split_whitespace().collect::>(); - let typo = parts[1]; // PANICS if no args! - vec![format!("tool {}", typo)] -} -``` - -✅ **GOOD**: Safe handling -```rust -fn get_new_command(&self, cmd: &Command) -> Vec { - let parts = cmd.script_parts(); - if parts.len() < 2 { - return vec![]; // Graceful handling - } - let typo = &parts[1]; - vec![format!("tool {}", typo)] -} -``` - -### 6. Ignoring Edge Cases -❌ **BAD**: Not testing edge cases -```rust -#[test] -fn test_tool_works() { - let cmd = Command::new("tool bad", "error: unknown"); - assert!(rule.is_match(&cmd)); - // Only happy path tested! -} -``` - -✅ **GOOD**: Comprehensive edge case testing -```rust -#[test] -fn test_tool_empty_output() { - let cmd = Command::new("tool bad", ""); - assert!(!rule.is_match(&cmd)); -} - -#[test] -fn test_tool_no_subcommand() { - let cmd = Command::new("tool", "usage: tool "); - let fixes = rule.get_new_command(&cmd); - assert!(fixes.is_empty()); // No panic! -} -``` - -### 7. Modifying Unrelated Code -❌ **BAD**: Refactoring while adding features -```rust -// In your PR: -// - Modified 3 files for new rule -// - Refactored 10 other files "to clean up code" -// - Changed formatting in 20 files -// - Updated dependency versions -``` - -✅ **GOOD**: Focused changes -```rust -// In your PR: -// - Added 1 new rule file -// - Updated rule registry -// - Updated CHANGELOG -// That's it! -``` - -### 8. Skipping Tests or Quality Checks -❌ **BAD**: Pushing without running checks -```bash -git add . -git commit -m "added stuff" -git push # Didn't run cargo test! -``` - -✅ **GOOD**: Always run checks first -```bash -cargo test && \ -cargo clippy -- -D warnings && \ -cargo fmt --check && \ -cargo build --release && \ -git add . && \ -git commit -m "feat(rules): add tool command corrections" && \ -git push -``` - -### 9. Copying Python Code Directly -❌ **BAD**: Copy-pasting from thefuck -```python -# From thefuck's rules/kubectl.py -def match(command): - return 'kubectl' in command.script and 'error' in command.output -``` -```rust -// Direct translation - misses Rust idioms! -fn is_match(&self, cmd: &Command) -> bool { - cmd.script.contains("kubectl") && cmd.output.contains("error") -} -``` - -✅ **GOOD**: Translating concepts properly -```rust -fn is_match(&self, cmd: &Command) -> bool { - is_app(cmd, &["kubectl"]) // Use oops helper - && cmd.output.to_lowercase().contains("unknown command") // Specific -} -``` - -### 10. Creating Overly Complex Rules -❌ **BAD**: One rule doing too much -```rust -// ToolMegaRule handles: -// - Unknown commands -// - Invalid flags -// - Missing arguments -// - Permission errors -// - Configuration issues -// All in one giant is_match() function -``` - -✅ **GOOD**: Separate concerns -```rust -// ToolUnknownCommand - handles one thing well -// ToolInvalidFlag - handles another thing well -// ToolMissingArg - handles yet another thing well -// Each rule is focused and testable -``` - ---- - -## Troubleshooting Guide - -### Issue: Tests Failing - -**Symptom**: `cargo test` shows failures - -**Solutions**: -```bash -# Run tests with output to see details -cargo test -- --nocapture - -# Run specific failing test -cargo test test_tool_matches -- --nocapture - -# Check if error output format changed -# Re-run the actual tool and update test - -# Common fixes: -# - Update expected error message -# - Fix typo in test -# - Adjust fuzzy matching threshold -# - Handle edge case properly -``` - -### Issue: Clippy Warnings - -**Symptom**: `cargo clippy` shows warnings - -**Solutions**: -```bash -# See all warnings -cargo clippy -- -D warnings - -# Auto-fix some issues -cargo clippy --fix - -# Common warnings: -# - Unused import: Remove the import -# - Unused variable: Prefix with underscore: _var -# - Needless borrow: Remove & if not needed -# - Missing docs: Add /// comments -``` - -### Issue: Rule Not Triggering - -**Symptom**: Rule doesn't match when it should - -**Debug steps**: -```rust -// Add debug logging temporarily -fn is_match(&self, cmd: &Command) -> bool { - eprintln!("Checking rule for: {:?}", cmd.script); - eprintln!("Output: {:?}", cmd.output); - - let app_match = is_app(cmd, &["tool"]); - eprintln!("App match: {}", app_match); - - let error_match = cmd.output.contains("error"); - eprintln!("Error match: {}", error_match); - - app_match && error_match -} - -// Run test with output -// cargo test test_rule -- --nocapture -``` - -**Common causes**: -- Tool name mismatch (check `is_app` parameter) -- Case sensitivity (use `.to_lowercase()`) -- Error message changed (update pattern) -- Rule not registered (check `mod.rs`) -- Higher priority rule matched first (check priority values) - -### Issue: Fuzzy Matching Not Working - -**Symptom**: `get_close_matches` returns empty - -**Solutions**: -```rust -// Lower the cutoff threshold -get_close_matches(typo, possibilities, 3, 0.5) // Was 0.6 - -// Add more possibilities -const COMMANDS: &[&'static str] = &[ - "status", "config", "info", // Add more! -]; - -// Debug fuzzy matching -use crate::utils::get_close_matches; -let matches = get_close_matches("statsu", &["status".to_string()], 3, 0.6); -eprintln!("Fuzzy matches: {:?}", matches); -``` - -### Issue: Cross-Platform Test Failures - -**Symptom**: Tests pass locally but fail on Windows CI - -**Solutions**: -```rust -// Ensure .exe handling -fn is_match(&self, cmd: &Command) -> bool { - is_app(cmd, &["tool", "tool.exe"]) // Add .exe! -} - -// Handle line endings -let lines: Vec<&str> = cmd.output.lines().collect(); // Not .split('\n')! - -// Case insensitive -let output_lower = cmd.output.to_lowercase(); -``` - -### Issue: Rule Registered But Not Running - -**Symptom**: Rule exists but never gets invoked - -**Check**: -```bash -# Is rule in get_all_rules()? -grep -r "ToolErrorType::new" src/rules/ - -# Is module declared? -grep "pub mod tool" src/rules/mod.rs - -# Is rule enabled by default? -# Check enabled_by_default() returns true - -# Does rule require output? -# If requires_output() returns true, rule won't run if output is empty -``` - -### Issue: Compilation Errors - -**Symptom**: `cargo build` fails - -**Common errors & fixes**: -```rust -// Error: cannot find value `Command` -use crate::core::Command; // Add import - -// Error: cannot find function `is_app` -use crate::core::is_app; // Add import - -// Error: method `to_lowercase` not found -// You're using String, it should be str -let output_lower = cmd.output.to_lowercase(); // Works on String - -// Error: cannot move out of borrowed content -// Use & reference instead -let typo = &parts[1]; // Not parts[1] -``` - -### Issue: PR CI Failing - -**Symptom**: PR checks fail on GitHub - -**Solutions**: -```bash -# Reproduce CI environment locally -cargo test --all-targets --all-features -cargo clippy --all-targets --all-features -- -D warnings -cargo fmt --all -- --check - -# Check specific failing job -gh pr checks -gh run view - -# Common CI failures: -# - Forgot to run cargo fmt -# - Clippy warning on different Rust version -# - Test depends on local environment -# - Cross-platform issue (Windows/macOS) -``` - ---- - -## Advanced Topics - -### When to Use side_effect() - -**Use `side_effect()` ONLY when:** -- Need to update config files after correction -- Need to add shell alias/function -- Need to mark something as resolved (e.g., git merge conflict) - -**Example**: -```rust -fn side_effect(&self, old_cmd: &Command, new_script: &str) -> Result<()> { - // Example: Update git config after fixing user email - if new_script.contains("git config user.email") { - // Update shell history or config - } - Ok(()) -} -``` - -**Don't use for:** -- Logging (use debug! macro instead) -- Validation (do in is_match()) -- Correction generation (do in get_new_command()) - -### Custom Priority Ordering - -**Priority ranges:** -- 1-500: Critical/high priority (sudo, cd fixes) -- 501-999: High priority (specific git errors, tool-specific) -- 1000: Default (most rules) -- 1001-1500: Low priority (fallback rules, generic typo) -- 1501+: Very low priority (experimental, broad matches) - -**Example**: -```rust -fn priority(&self) -> i32 { - 900 // Higher priority than default (runs earlier) -} -``` - -### Multi-Rule Strategy - -For complex tools, create multiple focused rules: - -```rust -// Good approach: -ToolUnknownCommand // priority: 1000 -ToolInvalidFlag // priority: 1000 -ToolMissingArg // priority: 1001 (lower, more generic) -ToolGenericTypo // priority: 1100 (fallback) - -// Each rule handles one specific error type -// Rules run in priority order -// First match wins (by default) -``` - ---- - -## Resources and References - -### Official oops Documentation -- README.md - Project overview and installation -- CONTRIBUTING.md - Contribution guidelines -- CLAUDE.md - Architecture and conventions -- CHANGELOG.md - Version history - -### Key Source Files -- `src/core/rule.rs` - Rule trait definition and documentation -- `src/core/command.rs` - Command struct -- `src/utils/fuzzy.rs` - Fuzzy matching implementation -- `src/rules/git/not_command.rs` - Example of well-tested rule - -### External Resources -- thefuck rules: https://github.com/nvbn/thefuck/tree/master/thefuck/rules -- Rust book: https://doc.rust-lang.org/book/ -- Rust by Example: https://doc.rust-lang.org/rust-by-example/ -- Conventional Commits: https://www.conventionalcommits.org/ - -### Tools -- `cargo-watch` - Auto-run tests on file change -- `cargo-expand` - Debug macro expansions -- `cargo-outdated` - Check for outdated dependencies - ---- - -## Quick Reference Card - -### Rule Implementation Checklist -1. ✅ Research tool errors (real error messages!) -2. ✅ Create feature branch -3. ✅ Implement rule with `is_app()` and fuzzy matching -4. ✅ Write 6-17 comprehensive tests -5. ✅ Register rule in module system -6. ✅ Run all quality checks (test, clippy, fmt, build) -7. ✅ Update docs if significant -8. ✅ Commit with conventional format -9. ✅ Create detailed PR -10. ✅ Respond to review feedback - -### Essential Commands -```bash -# Development -cargo test # Run all tests -cargo test tool_ # Run specific tests -cargo clippy -- -D warnings # Lint -cargo fmt # Format code -cargo build --release # Build optimized - -# Git workflow -git checkout -b feature/add-TOOL-rules -git add src/rules/ -git commit -m "feat(rules): add TOOL corrections" -git push -u origin feature/add-TOOL-rules - -# PR creation -gh pr create --title "feat(rules): add TOOL corrections" -gh pr checks # Check CI status -gh pr view --web # Open in browser -``` - -### Key Patterns -```rust -// Command detection -is_app(cmd, &["tool", "tool.exe"]) - -// Fuzzy matching -get_close_matches(typo, &possibilities, 3, 0.6) - -// Safe argument access -let parts = cmd.script_parts(); -if parts.len() < 2 { return vec![]; } -let arg = &parts[1]; - -// Case-insensitive matching -cmd.output.to_lowercase().contains("error") -``` - ---- - -## Conclusion +## Discovery Criteria +- **Popularity**: GitHub stars, downloads +- **Error frequency**: Common mistakes +- **Complexity**: More subcommands +- **Gap**: What thefuck has that oops doesn't +- **Cross-platform**: All major OSes +- **Stability**: Consistent error formats -You are now equipped to: -- ✅ Research and identify high-value CLI tools to support -- ✅ Implement robust, cross-platform correction rules -- ✅ Write comprehensive tests with real error outputs -- ✅ Follow oops coding conventions and quality standards -- ✅ Create well-documented PRs ready for review +## Safety +- Rules <1ms evaluation +- Memory-safe, panic-free +- No arbitrary execution +- Minimal `side_effect()` -**Remember**: -- Start with research, not code -- Use real error messages in tests -- Think cross-platform from the start -- Keep changes focused and minimal -- Test thoroughly before PR -- Document clearly with examples +## Categories +git, package_managers (apt/brew/cargo/npm/pip/yarn), docker, system (ls/cp/mv), cloud (aws/azure), devtools (go/java/maven), frameworks, shell_utils (grep/sed/find), misc -**Good luck adding amazing corrections to oops!** 🚀 +See `rule-creator` agent for detailed implementation patterns. diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 32f4ec0..f5c1dbe 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -170,3 +170,265 @@ Rules are organized by category in `src/rules/`: - `frameworks.rs` - Python, Rails, React Native - `shell_utils.rs` - grep, sed, history - `misc.rs` - Other utilities + +## Agentic Workflow Guidelines + +### Working with AI Agents + +When working with GitHub Copilot agents on tasks: + +1. **Clear Task Scoping** + - Define clear, focused issues with specific acceptance criteria + - Include file hints and impacted areas + - Specify what "done" means (tests pass, docs updated, etc.) + - Avoid multi-topic or overly broad tasks + +2. **Acceptance Criteria Template** + ```markdown + ## Acceptance Criteria + - Implementation passes all affected tests + - Code follows project style and conventions + - Changes are minimal and focused + - No modifications to unrelated files + - Documentation updated if needed + - Security checks pass (cargo clippy, no vulnerabilities) + ``` + +3. **Incremental Work Pattern** + - Plan first, then implement in small steps + - Verify each step before moving to the next + - Commit frequently with descriptive messages + - Request reviews at logical checkpoints + +4. **Agent Boundaries** + - Agents should NOT modify core system files without explicit need + - Agents should NOT skip quality checks (tests, clippy, fmt) + - Agents should NOT commit directly to main/master + - Agents MUST verify changes don't break existing functionality + +### Task Suitability for AI Agents + +**Well-suited tasks:** +- Bug fixes with clear reproduction steps +- Adding new rules following established patterns +- Writing tests for existing functionality +- Documentation updates and improvements +- Refactoring within well-defined boundaries +- Code style and formatting fixes + +**Less suitable tasks:** +- Large architectural changes +- Core trait modifications +- Complex cross-cutting changes +- Security-critical modifications requiring deep context +- Changes requiring significant domain expertise + +### Review and Iteration + +- Treat agent output as a starting point, not final solution +- Always review generated code for: + - Correctness and edge cases + - Performance implications + - Security considerations + - Test coverage + - Code style consistency +- Provide specific feedback and iterate +- Run all quality checks before merging + +## Security Guidelines + +1. **Dependency Management** + - Always check dependencies for vulnerabilities before adding + - Use `cargo audit` to scan for known security issues + - Prefer well-maintained, popular crates + - Document security decisions + +2. **Code Safety** + - All code must be memory-safe (Rust guarantees this mostly) + - Avoid `unsafe` blocks unless absolutely necessary + - Never execute arbitrary commands without validation + - Don't modify system files or environment + - Handle errors explicitly, never unwrap() in production code paths + +3. **Rule Safety** + - Rules must not have side effects by default + - Use `side_effect()` sparingly and document why + - Never make network calls from rules + - Keep rule evaluation fast (<1ms) to avoid DoS + - Validate all inputs before using in commands + +4. **Testing for Security** + - Test edge cases: empty input, special characters, very long input + - Test for injection vulnerabilities in command generation + - Verify rules don't match unintended commands + - Test cross-platform behavior + +## Code Quality Standards + +### Rust-Specific + +1. **Error Handling** + - Use `Result` for fallible operations with `anyhow::Result` + - Use `?` operator for propagating errors + - Provide context with `.context()` when errors occur + - Never use `.unwrap()` or `.expect()` in library code + +2. **Type Safety** + - Prefer owned `String` in structs, `&str` in function parameters + - Use `#[derive(Debug, Clone)]` on public structs + - Implement traits explicitly when logic is non-trivial + - Use type aliases for complex types to improve readability + +3. **Documentation** + - Document all public APIs with `///` doc comments + - Include examples in doc comments for complex functions + - Explain the "why" not just the "what" + - Keep docs in sync with code + +4. **Performance** + - Prefer iterator chains over explicit loops where readable + - Use `Cow` for conditional cloning + - Cache expensive operations (already done for `which` lookups) + - Profile before optimizing + +### Testing Philosophy + +1. **Test Coverage** + - Every rule needs minimum 6 tests: + - 2+ positive matches (different error patterns) + - 2+ negative matches (shouldn't trigger) + - 1+ correction verification + - 1+ edge case (empty output, special chars) + - Use real error output from actual tools + - Test cross-platform behavior when relevant + +2. **Test Structure** + ```rust + #[cfg(test)] + mod tests { + use super::*; + use crate::core::Command; + + #[test] + fn test_matches_when_error_occurs() { + let cmd = Command::new("tool cmd", "error: something"); + let rule = MyRule::default(); + assert!(rule.is_match(&cmd)); + } + + #[test] + fn test_no_match_when_success() { + let cmd = Command::new("tool cmd", "success"); + let rule = MyRule::default(); + assert!(!rule.is_match(&cmd)); + } + + #[test] + fn test_generates_correct_fix() { + let cmd = Command::new("tool cmd", "error: typo"); + let rule = MyRule::default(); + let fixes = rule.get_new_command(&cmd); + assert!(fixes.contains(&"tool command".to_string())); + } + } + ``` + +3. **Test Data** + - Use realistic error messages from actual tool runs + - Test with different versions' error formats when known + - Include unicode, spaces, and special characters + - Test boundary conditions (empty, very long, null-like) + +## Project Memory & Context + +### Architecture Principles + +1. **Rule System** + - Rules are independent, stateless, and thread-safe + - Rules are evaluated lazily for performance + - Multiple rules can match; user selects from corrections + - Priority determines order (lower = higher priority) + +2. **Shell Integration** + - Each shell implements the `Shell` trait + - Shell-specific syntax (alias, history, chaining) isolated + - Environment variables for backward compatibility with thefuck + +3. **Performance First** + - Target: <50ms cold start + - Rules evaluate in microseconds + - Lazy evaluation of rules + - Efficient fuzzy matching with `strsim` + +### Common Patterns + +1. **Command Detection** + ```rust + use crate::utils::is_app; + + // Check if command uses specific tool + is_app(cmd, &["git", "g"]) // Handles aliases too + ``` + +2. **Fuzzy Matching** + ```rust + use crate::utils::get_close_matches; + + // Find similar commands + let suggestions = get_close_matches("psh", &["push", "pull"], 3); + ``` + +3. **Output Parsing** + ```rust + // Check for specific error patterns + if cmd.output.contains("not a git command") { + // Extract typo, suggest fix + } + ``` + +### Commit Message Guidelines + +Follow conventional commit format: +- `feat(rules): add support for kubectl` +- `fix(git): handle branch names with spaces` +- `test(npm): add edge cases for package.json errors` +- `docs(readme): update installation instructions` +- `refactor(core): simplify rule matching logic` +- `perf(fuzzy): optimize string comparison` +- `chore(deps): update dependencies` + +### PR Best Practices + +1. **Title**: Clear, concise, follows commit convention +2. **Description**: + - What problem does this solve? + - What changes were made? + - How was it tested? + - Any breaking changes or migration needed? +3. **Scope**: Keep PRs focused (single rule, single fix) +4. **Tests**: Include test output showing coverage +5. **Examples**: Show before/after for rule corrections + +## File Organization + +``` +src/ +├── main.rs # CLI entry point - minimal, just dispatch +├── lib.rs # Public library interface +├── cli.rs # clap-based argument parsing +├── config/ # Configuration loading (env, file, defaults) +├── core/ # Core types and rule engine (DO NOT MODIFY lightly) +│ ├── command.rs # Command struct +│ ├── rule.rs # Rule trait definition +│ ├── corrected.rs # CorrectedCommand with side effects +│ └── corrector.rs # Rule matching and filtering engine +├── rules/ # All correction rules (ADD NEW RULES HERE) +│ ├── mod.rs # Rule registry +│ └── / # Rules grouped by tool category +├── shells/ # Shell-specific integrations +├── output/ # Command execution and output capture +├── ui/ # Terminal UI and user interaction +└── utils/ # Shared utilities (caching, fuzzy matching) +``` + +**Key principle**: New rules go in `src/rules//` and are registered in `src/rules/mod.rs`. Core files should rarely need changes. From 52ece3ae42f795d24bfa488da3ec852231ea7891 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 22 Jan 2026 09:26:52 +0000 Subject: [PATCH 3/4] fix: correct rule pattern example and priority guidance in rule-expander agent Co-authored-by: animeshkundu <7248674+animeshkundu@users.noreply.github.com> --- .github/agents/rule-expander.agent.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/agents/rule-expander.agent.md b/.github/agents/rule-expander.agent.md index 8b8b145..71ad780 100644 --- a/.github/agents/rule-expander.agent.md +++ b/.github/agents/rule-expander.agent.md @@ -19,7 +19,7 @@ Expand oops CLI tool support through complete workflow: discover tools, implemen - Create rules in `src/rules//` - Register in `src/rules/mod.rs` `get_all_rules()` - Use `is_app()` for detection, `get_close_matches()` for fuzzy matching -- Priority: 50-100 (specific), 500-900 (common), 1000+ (fuzzy) +- Priority: 50-100 (specific), 500-900 (high), 1000 (default), 2000+ (fuzzy/fallback) **3. Testing (Min 6 tests/rule)** - Positive matches (2+), Negative matches (2+), Corrections (1+), Edge cases (1+) @@ -71,6 +71,7 @@ impl Rule for MyRule { } } ``` +``` ## Discovery Criteria - **Popularity**: GitHub stars, downloads From 74814490989cf23ce34f5750f288536abcaf768b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 22 Jan 2026 09:27:26 +0000 Subject: [PATCH 4/4] fix: remove extra code fence in rule-expander agent Co-authored-by: animeshkundu <7248674+animeshkundu@users.noreply.github.com> --- .github/agents/rule-expander.agent.md | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/agents/rule-expander.agent.md b/.github/agents/rule-expander.agent.md index 71ad780..81be9a3 100644 --- a/.github/agents/rule-expander.agent.md +++ b/.github/agents/rule-expander.agent.md @@ -71,7 +71,6 @@ impl Rule for MyRule { } } ``` -``` ## Discovery Criteria - **Popularity**: GitHub stars, downloads