Skip to content

fix(parser): redirect and heredoc combos; function redirects stop streaming - #2589

Merged
chaliy merged 2 commits into
mainfrom
claude/redirect-fixes
Oct 7, 2026
Merged

chaliy merged 2 commits into
mainfrom
claude/redirect-fixes

Conversation

@chaliy

@chaliy chaliy commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

Requested by Михайло · project thread

What changed

  • A function call with output redirects now suspends streaming output while its body runs, as compound commands already did. Before, f > out wrote to out and also printed to the caller (the CLI and exec_streaming).
  • &>> file is lexed and parsed as >> file 2>&1. It was a parse error.
  • Here documents:
    • The rest of the line after a heredoc now parses like any other command line. Several heredocs per line work (cat <<A <<B, the last is stdin), and so do words after one (cat <<A file).
    • Compound commands take more redirects after a heredoc (done <<A 3<<B >out).
    • N<<EOF targets fd N (new Token::HereDocFd) and does not feed stdin. It was a 3 word plus a stdin heredoc.
  • paste - - hands stdin lines to its - operands in turn, like GNU. With -s, the first one takes everything.

Why

These are roadmap step 1 fidelity gaps from the Debian-oracle shell cases redirect-stdout-stderr-combos and heredoc-multiple-same-line. Both cases now match bash. The function leak was the worst: any agent running log() {...}; log > file through the CLI or a streaming host saw the output twice.

Before / After

Script Before After (= bash)
f() { echo out; }; f > o.txt (CLI) prints out prints nothing
echo a &>> x.txt parse error appends
cat <<A <<B … body of A body of B
paste - - <<A 3<<B … 3: command not found a1 a2
printf '1\n2\n3\n' | paste - - 1 1 / 2 2 / 3 3 1 2 / 3

Proof: new spec redirect-heredoc-combos.test.sh (7 cases, bash-verified), new integration test redirected_function_output_is_not_streamed, and bash_comparison passes.

Risk

Low-medium. This is a parser change: the lexer now always re-injects the line break after a heredoc delimiter, and the simple-command loop keeps parsing after a heredoc instead of stopping. Full lib, integration and comparison suites pass.

Checklist

  • Failing tests first
  • cargo test -p bashkit --lib / --test integration / bash_comparison
  • clippy -D warnings, fmt, check-okf
  • knowledge: parser.md, log

https://claude.ai/code/session_019aFikmptPc91Fj4N2iDXQA


Generated by Claude Code

@chaliy chaliy self-assigned this Oct 7, 2026
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
bashkit 72b78b4 Commit Preview URL

Branch Preview URL
Oct 07 2026, 07:45 PM

chaliy added 2 commits October 7, 2026 19:44
…eaming

- redirected function calls no longer stream their output to the caller
- `&>> file` parses as `>> file 2>&1`
- several heredocs per line, `N<<EOF`, words/redirects after a heredoc
- `paste - -` shares stdin between `-` operands

Claude-Session: https://claude.ai/code/session_019aFikmptPc91Fj4N2iDXQA
The coverage build overflowed TM-DOS-044 depth-50 nested $( ). Move the
new arms into out-of-line helpers, share one heredoc parser between
simple and compound commands, and heap-allocate the nested $( ) parser.
Debug stack need for the test: 2.05 MB -> 2.01 MB (main 2.02 MB).

Claude-Session: https://claude.ai/code/session_019aFikmptPc91Fj4N2iDXQA
@chaliy
chaliy force-pushed the claude/redirect-fixes branch from 6a1fe8b to 72b78b4 Compare October 7, 2026 19:45
@chaliy
chaliy merged commit b35f205 into main Oct 7, 2026
44 checks passed
@chaliy
chaliy deleted the claude/redirect-fixes branch October 7, 2026 20:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant