Skip to content

Hook: chained commands (cd dir && cmd) are never rewritten #112

Closed

Description

@Rmohid

Problem

Claude Code frequently emits chained commands like:

cd /Users/me/code/project && git status
cd /some/dir && python3 -m pytest tests/ -v
cd /foo && git add . && git commit -m "msg"

The hook script sets FIRST_CMD="$CMD" and then matches against patterns like ^git[[:space:]]+status. Since the full command starts with cd, none of the patterns match, and the hook silently passes through.

rtk discover shows this is the dominant source of missed savings -- 271 git status, 65 tail, 81 grep, 105 ls calls missed in 30 days of usage (~84K tokens saveable).

Fix

Extract the last command segment after && or ; for pattern matching, then reassemble the full command after rewriting:

CHAIN_PREFIX=""
FINAL_CMD="$CMD"

if [[ "$CMD" == *" && "* ]]; then
  CHAIN_PREFIX="${CMD% && *} && "
  FINAL_CMD="${CMD##* && }"
elif [[ "$CMD" == *" ; "* ]]; then
  CHAIN_PREFIX="${CMD% ; *} ; "
  FINAL_CMD="${CMD##* ; }"
fi

# ... match/rewrite against FINAL_CMD ...

# Reassemble
if [ -n "$CHAIN_PREFIX" ]; then
  REWRITTEN="${CHAIN_PREFIX}${REWRITTEN}"
fi

This uses bash parameter expansion (no regex issues with && in =~).

Environment

  • rtk 0.15.3
  • macOS (Tahoe)
  • Claude Code CLI

Activity

  1. ahundt commented on Feb 14, 2026

    @ahundt
    Contributor

    I have hooks that do this, it is actually harder than that to do correctly. You have to use an bash lexer to actually parse the commands and determine if a given chunk is actually a command or part of other commands and params. There are also edge cases like heredocs and comments and many more to get it right.

  2. added a commit that references this issue on Feb 15, 2026
    e39ab46
  3. ahundt commented on Feb 15, 2026

    @ahundt
    Contributor

    Hey @Rmohid I've implemented this request in #131 if you can give it a try let me know what you think!

  4. F0rty-Tw0 commented on Feb 16, 2026

    @F0rty-Tw0
    Contributor

    I had the same issue, and just updated my RTK hooks to catch that.

  5. added a commit that references this issue on Feb 16, 2026
    730f31c
  6. pszymkowiak commented on Feb 17, 2026

    @pszymkowiak
    Collaborator

    Tracked in PR #156 (Hook Engine + Chained Command Rewriting).

  7. Rmohid commented on Feb 18, 2026

    @Rmohid
    ContributorAuthor

    Verified fix: PR #156 adds Rust hook engine with lexer/chain parser. cd /tmp && git status correctly rewrites to cd /tmp && rtk git status. Build passes, 541 tests pass (336 in hook engine, 15 chain-specific). PR #150 also handles this case.

  8. added 3 commits that reference this issue on Feb 19, 2026
    41a7dfc
    ea40731
    3738a8b
  9. added 2 commits that reference this issue on Feb 23, 2026
    63312da
    7efe55d
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2-importantDevrait être fixé bientôtbugSomething isn't workingeffort-medium1-2 jours, quelques fichiers

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions