Skip to content

Support exclude_commands config for auto-rewrite hook #243

Closed

Description

@nwparker

Problem

The auto-rewrite hook (rtk-rewrite.sh) rewrites all supported commands unconditionally. There's no way to exclude specific commands from being rewritten without manually editing the hook script — which gets overwritten on the next rtk init -g.

Proposal

Add an exclude_commands option to config.toml that the hook script reads at runtime:

[hooks]
exclude_commands = ["playwright", "curl"]

The hook script would check this list before rewriting and skip excluded commands.

Alternative approaches

  • Environment variable: RTK_EXCLUDE="playwright,curl" — simpler but less discoverable
  • Per-command disable in config: [commands.playwright] enabled = false
  • Hook flag: rtk init -g --exclude playwright that generates the hook without those patterns

Any of these would work. The key requirement is that the exclusion survives rtk init -g re-runs.

Activity

  1. added 2 commits that reference this issue on Mar 5, 2026
  2. added a commit that references this issue on Mar 5, 2026
  3. added a commit that references this issue on Mar 5, 2026
  4. pszymkowiak commented on Mar 20, 2026

    @pszymkowiak
    Collaborator

    wshm · Automated triage by AI

    🔍 Automated Triage

    ✨ Category feature
    🟡 Priority medium
    🎯 Confidence 91%

    Summary

    Feature request: add exclude_commands config option so specific commands survive rtk init -g re-runs without manual hook edits

    📁 Relevant files
    • config.toml
    • rtk-rewrite.sh

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

  5. nhumrich commented on Mar 27, 2026

    @nhumrich

    This feature appears to already be in the docs (its in the readme), but doesn't appear to actually work/do anything.
    either that, or it doesn't support nested commands like ["git push"]

  6. added a commit that references this issue on May 14, 2026
  7. pszymkowiak commented on Jul 7, 2026

    @pszymkowiak
    Collaborator

    exclude_commands was implemented in #342 (2026-03-05), so this issue looks resolved at a glance — but testing it end-to-end reveals a real gap that undermines the exact example this issue gives.

    exclude_commands = ["playwright"] does not exclude npx playwright test — only a direct playwright ... invocation.

    Root cause: compile_exclude_patterns (registry.rs) turns every entry into an anchored regex ^{pattern}($|\s), and is_excluded runs it against the command before wrapper prefixes (npx, pnpm exec, yarn dlx, ...) are stripped. Since npx playwright test doesn't start with playwright, the pattern never matches.

    Verified live with the real config file + real Playwright:

    [hooks]
    exclude_commands = ["playwright"]
    $ rtk rewrite "npx playwright --version"
    rtk playwright --version   # <- still rewritten, exit 3 (should be passthrough, exit 1)
    

    And confirmed the practical impact isn't just cosmetic: rtk playwright --version actually runs through the dedicated playwright_cmd filter (it happened to fail all its parsing tiers for --version and fall back to raw output by luck) — for npx playwright test, the filter would successfully parse and transform the output, exactly what the user configured the exclusion to prevent.

    Since almost nobody installs Playwright as a global binary — npx playwright test is the standard invocation — the issue's own headline example doesn't work with the simple syntax it proposes.

    A workaround exists but isn't documented: writing an explicit anchored regex, e.g. exclude_commands = ["^(npx )?playwright"], verified working for both forms.

    Two ways to close the gap:

    1. Quick: document that npx/pnpm-exec/etc.-wrapped commands need an explicit regex pattern to match.
    2. Better: check exclusion against the wrapper-normalized command (same normalization classify_command already does for npx/pnpm exec/yarn dlx/etc.), so a plain ["playwright"] entry works regardless of how it's invoked — matching what most users configuring this would expect.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions