rtk-ai/rtk

bug(rewrite): hook rewrites left-hand side of piped commands, breaking downstream filters

Open

#1,560 opened on Apr 27, 2026

View on GitHub
 (4 comments) (0 reactions) (0 assignees)Rust (2,914 forks)batch import
P1-criticalarea:clibugeffort-smallfilter-qualitygood first issueneeds-reproductionpriority:high

Repository metrics

Stars
 (48,085 stars)
PR merge metrics
 (Avg merge 11d 1h) (45 merged PRs in 30d)

Description

Summary

rtk rewrite (and rtk hook claude) rewrites piped commands like ps aux | grep foo | grep -v grep into rtk ps aux | grep foo | grep -v grep. Since rtk ps aux compresses/reformats output, the downstream grep no longer matches — the pipe silently returns empty results.

Reproduction

$ rtk rewrite 'ps aux | grep python | grep -v grep'
rtk ps aux | grep python | grep -v grep    # exit 0 — rewrite applied

$ ps aux | grep python | grep -v grep      # returns matching processes
$ rtk ps aux | grep python | grep -v grep  # returns nothing

Also confirmed via hook:

$ echo '{"tool_input":{"command":"ps aux | grep python | grep -v grep"}}' | rtk hook claude
{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecisionReason":"RTK auto-rewrite","updatedInput":{"command":"rtk ps aux | grep python | grep -v grep"}}}

Expected behavior

rtk rewrite should detect pipes in the command string and either:

  1. Skip rewriting entirely for piped commands, or
  2. Only rewrite if downstream stages are rtk-compatible

Workaround

Wrapper script around rtk hook claude that skips piped commands:

#!/usr/bin/env bash
INPUT=$(cat)
CMD=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)

case "$CMD" in
  *"|"*) exit 0 ;;
esac

echo "$INPUT" | rtk hook claude

Wire in settings.json:

"command": "~/.claude/hooks/rtk-hook-wrapper.sh"

Environment

  • rtk 0.37.2 (also reproduced on 0.34.2)
  • Hook: rtk hook claude (v0.37.2 built-in)
  • OS: Linux x86_64

Contributor guide