-
Notifications
You must be signed in to change notification settings - Fork 11
Description
Problem
tokf currently uses a capture-then-process architecture — Command::output() blocks until the command finishes, then the full output is handed to the filter pipeline. For long-running commands like cargo test, gradle test, or mvn test in large workspaces, this means the user sees nothing until the entire command completes, which can take minutes.
With the chunk processing engine introduced in #199, we now have per-module structural awareness (e.g., per-crate breakdown for cargo test). The natural next step is to emit per-chunk results incrementally as each module finishes, rather than buffering everything for a final summary.
Desired behavior
For a multi-module cargo test workspace, instead of waiting 2 minutes and then seeing:
✓ cargo test: 863 passed, 0 failed, 28 ignored (7 suites)
tokf_common: 21 passed (1 suites)
tokf_filter: 180 passed (1 suites)
tokf: 550 passed (1 suites)
tokf_server: 95 passed (1 suites)
cli_basic: 17 passed (3 suites)
The user would see results appear progressively as each module finishes:
tokf_common: 21 passed ✓
tokf_filter: 180 passed, 1 ignored ✓
tokf: 550 passed ✓
tokf_server: 95 passed, 27 ignored ✓
cli_basic: 17 passed ✓
✓ cargo test: 863 passed, 0 failed, 28 ignored (7 suites)
On failure, failure details would append after the summary line.
This is especially valuable for Gradle and Maven multi-module projects where builds routinely take several minutes, and module-level feedback during execution dramatically improves the experience.
Architecture impact
This is a significant structural change. The current batch pipeline should remain the default; streaming would be opt-in per filter.
Components that need changes
| Component | Change |
|---|---|
runner.rs |
New execute_streaming() using Command::spawn() + line-by-line reader |
CommandResult |
New streaming variant or callback/channel model |
filter/mod.rs |
New streaming pipeline path alongside existing batch pipeline |
chunk.rs |
Incremental chunk detection — emit results when a boundary is hit |
commands.rs |
New orchestration for streaming mode |
| Filter config | New opt-in field (e.g., stream_chunks = true) |
| History/tracking | Must still buffer full output for recording |
| Baseline comparison | Needs full output (post-execution) |
Key constraints
- Exit code unknown until end — branch selection (
on_successvson_failure) requires the exit code. The summary line must come last. - Phase B variant resolution — some filters need full output to pick the right variant. Streaming mode may need to skip Phase B or require the filter to be fully resolved pre-execution.
- Section collection —
failures:sections use enter/exit state machines over the full output. Failure details can't be shown incrementally since they appear at the end of the output. - Aggregation for the summary — needs all
test result:lines to compute totals, so the summary line is always last. - History and tracking — must buffer the full raw output anyway for SQLite recording, so streaming doesn't reduce peak memory.
Design direction
The streaming pipeline would likely be a parallel path alongside the batch pipeline:
- Batch pipeline (existing): capture → filter → render → print. Stays as-is for correctness and for filters that don't opt in.
- Streaming pipeline (new): spawn → read lines → detect chunk boundaries → process completed chunks → emit per-chunk output → on exit, run batch pipeline for summary/failure details.
The per-chunk output template would be a new field in [[chunk]] config (e.g., stream_output = " {crate_name}: {passed} passed ✓"). The batch on_success/on_failure templates still handle the final summary.
Explicit non-design-decision: Capture then process, not streaming
CLAUDE.md lists "Capture then process, not streaming" as a design decision. This issue proposes adding an opt-in streaming mode alongside the existing batch mode, not replacing it. The batch pipeline remains the default and the only mode for filters without [[chunk]] streaming config.
Use cases
cargo testin Rust workspaces (per-crate results)gradle test/gradle buildin multi-module Java/Kotlin projects (per-module results)mvn test/mvn packagein multi-module Maven projects (per-module results)- Any long-running command with repeating structural blocks in its output
Out of scope
- Full line-by-line streaming (too granular, most filter stages need context)
- Replacing the batch pipeline (it stays as the default)
- Interactive/TUI progress display (this is just printing lines to stdout as chunks complete)