Repository navigation
Conversation
…output shape The pipe-left rewrite fed rtk's summarized formats into downstream programs: 'grep -n X f | wc -l' counted rtk grep's header and elision lines (measured 28 for 60 real matches), '$(ls -t | head -1)' captured a size-decorated name, and head's rtk-read mapping leaked '[N more lines]' markers to whatever parsed the file. find/fd already had this exact carve-out (rtk-ai#439) — generalize it to a PIPE_INCOMPATIBLE list covering the other shape-changing rewrites (grep, rg, ls, head, tail, cat). Segments without a pipe, and non-pipeline segments of the same compound command, keep their rewrites. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR updates the hook command rewriter to avoid rewriting the pipe-feeding segment when the rewritten command would change the output shape in a way that breaks downstream pipe consumers (e.g., grep -n … | wc -l, ls -t | head -1). It generalizes the existing find/fd carve-out into a shared PIPE_INCOMPATIBLE list and adds regression tests for several representative commands.
Changes:
- Introduces
PIPE_INCOMPATIBLEand anis_pipe_incompatible(seg)helper (with env-assignment prefix skipping) to decide when the pipe-left rewrite must be skipped. - Replaces the prior inline
find/fdspecial-case inrewrite_compoundwith the helper. - Adds unit tests covering pipe-skipped behavior for
grep,ls,head, env-prefixedgrep, plus a test ensuring post-pipeline&&segments still rewrite.
Adopt rtk-ai#2965: hooks - don't rewrite pipe-feeding segments whose filter changes shape
|
Thanks for this, and sorry it sat — the diagnosis in #2962 was right, and the It's since been fixed upstream of this branch, which is why the PR now conflicts. #3128 ( I ran all six of the tests added here against
The last row is develop being deliberately better than the Worth saying explicitly: the Recommending we close this one as superseded by #3128/#3343 — the analysis in #2962 is what drove that work. Thanks for filing both. |
Summary
find/fdalready skip the pipe-left rewrite because rtk's output shape breaksxargs(Trouble running xargs as second bash command. #439). The same reasoning applies to every filter that reshapes output — this generalizes the special case into aPIPE_INCOMPATIBLElist:find,fd,grep,rg,ls,head,tail,catgrep -n X f | wc -lcounted 28 for 60 real matches;$(ls -t | head -1)captured a decorated nameFixes #2962
Implementation notes
find/fdcheck inrewrite_compoundbecomes oneis_pipe_incompatible(seg)helper + a const list — net behavior change is which names are in the listVAR=valueassignments, matchingrewrite_segment's own env-prefix handling (LC_ALL=C grep … | sortis correctly recognized)grep … | wc -l && git statusstill rewritesgit statusTest plan
test_rewrite_grep_pipe_skipped— thewc -lmiscount case is not rewrittentest_rewrite_ls_pipe_skipped,test_rewrite_head_pipe_skipped— same for the other shape-changing filterstest_rewrite_grep_env_prefix_pipe_skipped— env prefix doesn't hide the commandtest_rewrite_grep_no_pipe_still_rewritten— no pipe, stillrtk grep(savings preserved)test_rewrite_pipe_skip_only_affects_pipeline_segment—&&segments after the pipeline still rewritetest_rewrite_find_pipe_skipped/test_rewrite_find_no_pipe_still_rewritten/test_rewrite_pipe_first_onlyunchanged and passingrtk hook claude:grep … | wc -landls -t | head -1now pass through;grep -rn TODO srcstill rewritescargo fmt --check && cargo clippy --all-targets && cargo test— 2441 passed, 0 failed, no new warnings