mirror of
https://github.com/bahdotsh/wrkflw.git
synced 2026-07-09 20:09:35 +02:00
The execution tab used to stare back at you with a single progress bar while the executor did... whatever it was doing. You found out what happened when the whole workflow was over, and only then. Not great for a tool whose entire point is running workflows locally. The reason was structural. `execute_workflow` handed back one `Vec<JobResult>` at the very end, `StepStatus` only had terminal variants (Success/Failure/Skipped — no Running, no Pending), and the container runtimes read logs *after* the container exited via `wait_container` followed by `logs().collect()`. The TUI was doing the best it could with a request/response it couldn't observe. So: thread an optional event stream through the executor. New `ExecutionEvent` enum (`JobStarted`, `StepStarted`, `StepLogChunk`, `StepCompleted`, `JobCompleted`, plus `Execution*` bookends) emitted via an `EventSink` that bundles an unbounded sender with a per-run `JobId` allocator so matrix combinations get distinct ids. The TUI spawns a receiver, drains it each tick, and paints the detail view live — spinner on the running step, ✓/✖/⊘/○ everywhere else, per-step duration, and a bottom pane that tails the step's log buffer as bytes come off stdout/stderr. `f` re-engages auto-follow; any manual j/k pins you where you are. Log streaming required rewriting all four runtimes. Emulation, secure_emulation and podman move to `tokio::process::Command` with piped stdio drained via `AsyncBufReadExt::lines()` in parallel tasks. Docker is the fun one: `logs(follow: true)` now runs concurrently with `wait_container` under `tokio::join!`, instead of the old sequential wait-then-read. Chunks mirror into the sink *and* accumulate into the final `ContainerOutput` so both the live view and the post-mortem `StepResult.output` stay truthful. CLI path is unchanged — `ExecutionConfig.event_sink` defaults to `None` and the whole thing short-circuits. Reusable workflows and composite actions collapse to a single synthetic step in the event stream for v1; nested forwarding is a separate problem for another day. `StepStatus` gained `Pending` and `Running` variants with `#[non_exhaustive]` so we can add more without breaking callers again. Per-step log buffer is capped at 10k lines with a truncation marker; the Step Output pane pins to the bottom so newest-first is always visible without caring about scroll state. Two new integration tests assert event ordering (JobStarted before any of its StepStarted, StepCompleted before JobCompleted, pairs match by (job_id, step_idx)) and that \`StepLogChunk\` arrives *between* \`StepStarted\` and \`StepCompleted\`. The sink-absent path stays behaviorally identical. Please don't put back the "collect everything then show it" pattern when the executor grows new capabilities. The streaming seams are there now; use them.
wrkflw-runtime
Runtime abstractions for executing steps in containers or emulation.
- Container management primitives used by the executor
- Emulation mode helpers (run on host without containers)
Example
// This crate is primarily consumed by `wrkflw-executor`.
// Prefer using the executor API instead of calling runtime directly.