Files
wrkflw/crates
bahdotsh bdf7dbffe1 fix(ui): close the remaining review debt on screens 4-8
A review pass over the screens-4-8 branch turned up three things
that survived the last round. Dealing with them in one commit.

It turns out the curl preview and the real dispatcher were
computing the workflow URL segment *differently*. The preview
stripped `.yml`/`.yaml` and url-encoded the full user input —
subdir and all. The dispatcher ran `Path::new(name).file_stem()`
(which drops the subdir) and then unconditionally re-appended
`.yml`, turning a `ci.yaml` workflow into a `ci.yaml.yml` URL
that has never worked.

So the preview was lying about what Enter would send, the
dispatcher had a latent `.yml.yml` bug for any input that already
carried the extension, and `.yaml` files silently became `.yml`
URLs on dispatch.

Consolidate both paths behind a single
`wrkflw_github::workflow_dispatch_path_segment` helper. Drops any
subdir prefix, preserves an existing `.yml`/`.yaml`, appends
`.yml` only when absent. The preview and the dispatcher now
produce byte-identical URL segments for the same input — and the
`.yaml.yml` footgun is gone as a side effect.

The second one: `a` (select-all) and `r` (queue+run) were gated
only on `!app.running`, not on the active tab. Pressing `a` on
the DAG or Trigger or Secrets tabs — outside edit mode — would
silently flip every workflow to `selected` behind the user's
back. Same story for `r` queuing an execution. Add the tab gate.
Please don't do that.

The third one: `trigger_in_flight` was cleared by a trailing
`store(false)` at the end of the spawned dispatch task. Fine on
normal return. A panic inside reqwest or either SDK would skip
right past it, strand the flag at `true`, and lock the Trigger
tab into a permanent "already in flight" state until the TUI
restarts. Wrap the flag in an `InFlightGuard` RAII so Drop is
what actually clears it. Normal return, early return, *and*
unwinding all land it back at `false`.

While at it: dropped the `DEBUG: Shift+R pressed` log spam that
was sprinkled through the reset handlers, deleted the now-dead
`strip_yaml_suffix` helper, and cleaned up a stray
`test_edge_cases.rs` debug script that had been sitting in the
repo root.

Eight new tests across the two crates cover the shared URL
helper, the preview/dispatcher identity, \`.yaml\` round-trip, and
the in-flight guard on both normal drop and \`catch_unwind\` panic
paths.

cargo fmt + clippy -D warnings + full workspace test suite clean.
2026-04-21 22:18:10 +05:30
..
2025-09-05 08:22:15 +05:30

Wrkflw Crates

This directory contains the Rust crates that make up the wrkflw workspace.

Crate Structure

Crate Purpose
wrkflw CLI binary and library entry point
executor Workflow execution engine (Docker, Podman, emulation)
parser Workflow file parsing and JSON Schema validation
evaluator Structural evaluation of workflow files
validators Validation rules for jobs, steps, triggers, matrix
runtime Container management and emulation runtime
ui Terminal user interface (ratatui-based)
models Shared data structures (ValidationResult, GitLab models)
matrix Matrix expansion (include, exclude, fail-fast)
secrets Secrets management with multiple providers and encryption
github GitHub API integration (list/trigger workflows)
gitlab GitLab API integration (trigger pipelines)
logging Thread-safe in-memory logging for TUI/CLI
utils Workflow file detection and fd redirection helpers

Building

# Build everything
cargo build

# Build a specific crate
cargo build -p wrkflw-executor

Testing

# Run all tests
cargo test

# Run tests for a specific crate
cargo test -p wrkflw-executor

Each crate has its own Cargo.toml with dependencies managed through workspace inheritance in the root Cargo.toml.