Skip to content

feat(config): support multi-word entries in exclude_commands for subcommand-level exclusion#1396

Open
atgim wants to merge 1 commit intortk-ai:developfrom
atgim:feat/exclude-commands-multiword
Open

feat(config): support multi-word entries in exclude_commands for subcommand-level exclusion#1396
atgim wants to merge 1 commit intortk-ai:developfrom
atgim:feat/exclude-commands-multiword

Conversation

@atgim
Copy link
Copy Markdown

@atgim atgim commented Apr 19, 2026

Summary

Extends [hooks].exclude_commands matching from first-word-only equality to whitespace-aware token matching. Entries containing whitespace match the command's first N tokens (where N is the entry's token count), enabling subcommand-level exclusion without blocking the parent command.

[hooks]
exclude_commands = ["curl", "git diff", "kubectl describe"]
  • "curl" behaves exactly as before (excludes all curl invocations)
  • "git diff" now excludes git diff with any args, but not git status / git log
  • Word boundaries use whitespace, so "git diff" never matches git difference or git diffoo
  • Whitespace in both entry and command is normalized (handled by split_whitespace on both sides)

Motivation

First-word-only matching forces all-or-nothing exclusion: users cannot exclude git diff from rewriting while keeping git status filtered, because both start with git. This is particularly harmful for diff/patch-producing subcommands where silent output corruption (stripped context lines, removed headers, dropped blob hashes) leads LLM-based agents to misinterpret file state and produce wrong edits.

The existing RTK_DISABLED=1 env-var escape hatch requires the user to remember it on every invocation, which is not viable for agent-driven pipelines. A persistent, config-level knob at subcommand granularity is what was missing.

Related issues

This PR addresses a concrete slice of #1313: users who know which specific subcommands they need raw output for can now declare it in config instead of patching the binary or sprinkling RTK_DISABLED=1.

Behavior

Implementation is a small helper function called from the existing exclude check:

fn is_command_excluded(cmd: &str, entry: &str) -> bool {
    let entry_tokens: Vec<&str> = entry.split_whitespace().collect();
    if entry_tokens.is_empty() {
        return false;
    }
    let cmd_tokens = cmd.split_whitespace().take(entry_tokens.len());
    cmd_tokens.eq(entry_tokens.iter().copied())
}

The call site in rewrite_segment_inner changes from:

let base = cmd_part.split_whitespace().next().unwrap_or("");
if excluded.iter().any(|e| e == base) { return None; }

to:

if excluded.iter().any(|e| is_command_excluded(cmd_part, e)) { return None; }

Backward compatibility

  • All existing single-word entries behave exactly as before (single-token split_whitespace().eq() reduces to first-word equality)
  • No config schema changes; no migration needed
  • All existing tests pass unchanged

Test plan

  • test_rewrite_multi_word_excludes_git_diff — two-word entry blocks subcommand + args
  • test_rewrite_multi_word_allows_other_git_subcommands — other subcommands still filter
  • test_rewrite_multi_word_no_partial_word_matchgit diff entry does not match git diffoo / git difference
  • test_rewrite_multi_word_and_single_word_coexist — mixed entries work independently
  • test_is_command_excluded_whitespace_normalization — multi-space handled correctly
  • test_is_command_excluded_empty_entry_never_matches — empty/whitespace-only entries safe
  • cargo fmt --all && cargo clippy --all-targets && cargo test --all — all 1596 tests pass, no new clippy warnings introduced

🤖 Generated with Claude Code

@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Apr 19, 2026

CLA assistant check
All committers have signed the CLA.

@pszymkowiak pszymkowiak added effort-small Quelques heures, 1 fichier enhancement New feature or request filter-quality Filter produces incorrect/truncated signal labels Apr 19, 2026
@pszymkowiak
Copy link
Copy Markdown
Collaborator

[w] wshm · Automated triage by AI

📊 Automated PR Analysis

Type feature
🟢 Risk low

Summary

Extends the exclude_commands configuration to support multi-word entries, enabling subcommand-level exclusion (e.g., excluding git diff without blocking git status). The implementation adds a small helper function that performs whitespace-aware token matching against the command's first N tokens, with full backward compatibility for existing single-word entries.

Review Checklist

  • Tests present
  • Breaking change
  • Docs updated

Linked issues: #1282, #1313, #1392


Analyzed automatically by wshm · This is an automated analysis, not a human review.

@atgim atgim changed the base branch from master to develop April 19, 2026 08:35
@atgim atgim force-pushed the feat/exclude-commands-multiword branch from faa3bc1 to 5168852 Compare April 19, 2026 08:35
Extends exclude_commands matching from first-word-only equality to
whitespace-aware token matching. Entries containing whitespace match
the command's first N tokens (where N is the entry's token count),
enabling subcommand-level exclusion without blocking the parent command.

Example config:

  [hooks]
  exclude_commands = ["curl", "git diff", "kubectl describe"]

- "curl" behaves exactly as before (excludes all curl invocations)
- "git diff" excludes `git diff` with any args, but NOT `git status`
- Word boundaries use whitespace, so "git diff" never matches
  `git difference` or `git diffoo`
- Whitespace in both entry and command is normalized (handled by
  split_whitespace on both sides)

Rationale: first-word-only matching forces all-or-nothing exclusion,
making it impossible to exclude diff/patch-producing subcommands
(`git diff`, `git show -p`) while keeping `git status` / `git log`
filtered. Silent output corruption on these subcommands is particularly
harmful for LLM agents that read diffs to make edits, since stripped
context lines can lead to wrong interpretation of file state.

Backward compatible: existing single-word entries unchanged. All
existing tests pass. New tests cover multi-word exclusion, partial
word safety, whitespace normalization, and mixed entry coexistence.

Refs: rtk-ai#1282, rtk-ai#1313
@atgim atgim force-pushed the feat/exclude-commands-multiword branch from 5168852 to ac8ab08 Compare April 19, 2026 08:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effort-small Quelques heures, 1 fichier enhancement New feature or request filter-quality Filter produces incorrect/truncated signal

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants