Repository navigation
task-monitor 4/6: ratatui front end (repo view + all-repos overview, real-time): the task-monitor binary in monitor/ - #282
Merged
Merged
Conversation
…real-time): the task-monitor binary in monitor/ A Rust + ratatui front end over `task-monitor-snapshot --json` (#276, epic #272). It renders the repo view (in flight / next / done) and the all-repos overview with each repo's attention light, its signals in words and its zellij session. - Real time: filesystem events under `$TASK_FORCE_HOME/radio` (not its log), `$TASK_FORCE_HOME/monitor` and each repo's worktree base (`.<slug>.info` only) trigger a debounced `--local` snapshot; a full snapshot runs every 45s (`--poll`). Both run off the UI thread with timeouts, and an older run never replaces a newer one. - Never blank: a failed or slow snapshot keeps the last good one up, marked stale, with the collector's reason in the footer. - Keys: arrows, enter (expand / enter repo), o, t, a, q. `t` stays in the monitor's zellij session and checks that the tab at the recorded id still bears the item's name (the #260 rule) before going to it. - No task-force logic in Rust: the snapshot gains `worktree_base` so the watcher does not re-derive task-work's path rule. Schema doc, example and a bats test cover it. 45 Rust tests (fixture rendering, keys, scheduler timing, watcher filter, collector failure/timeout, tab check). README section, workflow doc + steering templates, CHANGELOG. install.sh and CI stay with #277. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Owner
Author
Spec compliance (#276)Every scope bullet is delivered:
The PR body opens with Code-review findingsNo blockers. Two points are worth fixing in this PR; both are small.
Nits (non-blocking)
Verdictclean-with-nits. I would fix findings 1 and 2 in this PR, since they are small and in code the PR already owns. PM decides; neither blocks the merge. |
…real-time): CI builds, tests and lints the Rust crate The PM moved the CI Rust job from #277 into this PR, so #282 is verified before it merges. A `rust` job on ubuntu-latest and macos-latest runs from `monitor/` on stable: fmt --check, build --locked, test --locked, clippy -D warnings, with Swatinem/rust-cache. A `rust-msrv` job builds and tests on 1.88, the declared rust-version (ratatui 0.30's floor), and checked locally with `cargo +1.88 test`. CHANGELOG and README say so; neither job is a required check yet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…real-time): keep full results that land after a local run Review round 1 (PR #282): - `App::offer` dropped a full run's result whenever a local run that started later landed first. Heartbeats rewrite session files all the time, so that was the normal case and the forge data never reached the screen. A full result now replaces local data whatever their start times. When it does, its disk state is older than what it replaced, so offer returns `TakenNeedsLocal` and main schedules a local rerun. - `App::failed` marked a fresh screen stale over an older run's failure. It now takes the run's start and mode and applies the same rule as offer (`App::superseded`). A full run's failure still counts against local data, because the forge state on screen is what failed to refresh. - `to_key` gets a test: Ctrl-C is Quit, a bare c is a key, a release is ignored. 48 Rust tests. Breaking the full-run exception, the failure guard, the rerun signal and the Ctrl-C mapping each turned a test red. Also builds and tests on 1.88. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
martin-conur
added a commit
that referenced
this pull request
Oct 20, 2026
…k-monitor-queue in the task-monitor docs After rebasing onto #282: the README's snapshot and `task-monitor` sections and the `task-monitor` block in all seven workflow templates and this repo's workflow doc now say the Next section is the queue the PM writes with `task-monitor-queue`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
martin-conur
added a commit
that referenced
this pull request
Oct 20, 2026
…-monitor-queue (#281) * task-monitor 3/6: PM short-term queue (task-monitor next …): add task-monitor-queue New canonical root binary `bin/task-monitor-queue` (named by the PM: the user-facing `task-monitor` is the #276 front end). The PM writes the board's Next section with `set <ref>... [--note <ref>=<text>]`, `add`, `rm`, `clear`, or no subcommand to show it. Each write answers with one line, so the PM's board cost is one short call. It owns the queue file format that `task-monitor-snapshot` already reads: `$TASK_FORCE_HOME/monitor/<repo>/queue`, one ref per line with an optional tab-separated note. Refs are compared by their last path segment, so `267`, `#267` and an issue URL are one item. `task-work` uses that to drop the ref it dispatches, best effort, so a dispatched item never returns as next once it leaves In flight. Every PM prompt (four claude `commands/pm.md`, this repo's copy, three kiro `agents/pm.json`) gains one paragraph on when to call it. All seven installers link it; README, workflow templates, schema doc and CHANGELOG updated. New tests/task_monitor_queue.bats (21 tests under /bin/bash, mutation-checked) and a symlink test. Closes #275 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * task-monitor 3/6: PM short-term queue (task-monitor next …): address review round 1 - Every leading `#` of a ref is stripped, so `##5` is stored as `5` instead of `#5`, which the reader skipped as a comment. - `--` ends the options, so a ref starting with `-` can be passed. - A URL ref's query string and fragment are dropped from its key: a Notion page URL with and without `?pvs=4` is one item. - Documented that `--note` splits on the first `=`, so a ref containing `=` cannot take a note. - One comment naming the accepted race between a PM `set` and the task-work `rm`. Three new tests, each mutation-checked. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * task-monitor 3/6: PM short-term queue (task-monitor next …): name task-monitor-queue in the task-monitor docs After rebasing onto #282: the README's snapshot and `task-monitor` sections and the `task-monitor` block in all seven workflow templates and this repo's workflow doc now say the Next section is the queue the PM writes with `task-monitor-queue`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
martin-conur
added a commit
that referenced
this pull request
Oct 20, 2026
…k task-monitor from every loadout installer New `lib/monitor-install.sh` (`aw_install_monitor`), called from the drift-guarded install-shared-symlinks stanza of all seven loadout installers. With cargo on PATH it runs `cargo build --release` on monitor/ and links ~/.local/bin/task-monitor to the executable cargo's JSON output reports, so CARGO_TARGET_DIR is honoured; a binary built outside the checkout gets a TASK_MONITOR_SNAPSHOT hint. Without cargo it prints one skip line; a failed build warns. Neither fails the install. tests/install_symlinks.bats stubs cargo for every installer test and adds five #277 cases. README, the workflow doc, the seven steering templates and CHANGELOG updated. The CI Rust job moved to #282. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
martin-conur
added a commit
that referenced
this pull request
Oct 20, 2026
…k task-monitor from every loadout installer (#285) * task-monitor 5/6: install.sh cargo build + CI Rust job: build and link task-monitor from every loadout installer New `lib/monitor-install.sh` (`aw_install_monitor`), called from the drift-guarded install-shared-symlinks stanza of all seven loadout installers. With cargo on PATH it runs `cargo build --release` on monitor/ and links ~/.local/bin/task-monitor to the executable cargo's JSON output reports, so CARGO_TARGET_DIR is honoured; a binary built outside the checkout gets a TASK_MONITOR_SNAPSHOT hint. Without cargo it prints one skip line; a failed build warns. Neither fails the install. tests/install_symlinks.bats stubs cargo for every installer test and adds five #277 cases. README, the workflow doc, the seven steering templates and CHANGELOG updated. The CI Rust job moved to #282. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * task-monitor 5/6: install.sh cargo build + CI Rust job: build with --locked The installer's `cargo build` now passes `--locked`, as CI does, so a user install builds exactly the committed Cargo.lock instead of silently updating a stale one in the checkout. The retry hint says the same. The stub-cargo test pinning the build args is updated; dropping `--locked` turns it red. README, CHANGELOG and the helper's header comment follow. Review nit on PR #285. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This adds
task-monitor, a live terminal board built in Rust with ratatui. For the repo you're in it shows what is in flight, what is next and what has landed, and an overview shows which repo needs you and why. It refreshes from disk the moment radio or a worker changes something, asks GitHub every 45 seconds, and keeps the last good screen up, marked stale, when a refresh fails.Closes #276
What
monitor/: a new crate that builds thetask-monitorbinary. It readstask-monitor-snapshot --json --all [--local]and nothing else. Every field is optional, unknown fields are ignored, and a differentschemais refused.Screens: the repo view (in flight with status, PR, activity icon and age, reviewers; next, from the queue or the backlog, with notes; done with PR, SHA, age and a two-line summary) and the overview (attention light, signal text, in-flight count, zellij session). ⏎ expands an item in place, with a done item showing its full PR body, scrollable.
Refresh: filesystem events (notify) on
$TASK_FORCE_HOME/radio(excludinglog),$TASK_FORCE_HOME/monitorand each worktree base (.<slug>.infoonly) run a--localsnapshot. Events are debounced 400ms on the trailing edge and capped at 2s, and only one local run goes at a time, with a rerun if an event lands mid-run. The full run starts at launch and then 45s after the previous one finished (--poll 30-600). Timeouts are 20s for a local run and 180s for a full one, and a hung collector is killed. A result never replaces a newer run's.t: uses the sidecarTAB_ID, else the session's, or the PM's for queue/done items and overview rows. It refuses a tab in another zellij session by naming it. Otherwise it checks withlist-tabsthat the tab at that id still bears the item's name (theaw_tab_name_is_slugrule from task-done closes a stale TAB_ID without checking the tab is its own, killing an unrelated worker after a zellij restart #260) beforego-to-tab-by-id.Snapshot: one new field,
worktree_base, so the watcher doesn't re-derive task-work's path rule. It is in the schema doc and example, with a bats test.Docs: a README section, a
task-monitorparagraph in.claude/gh-workflow.mdand the seven steering templates, and a CHANGELOG entry.CI (the PM moved this here from task-monitor 5/6: install.sh cargo build + CI Rust job #277): a
rustjob on ubuntu-latest and macos-latest runs frommonitor/on stable:cargo fmt --check,cargo build --locked,cargo test --locked,cargo clippy --all-targets --locked -- -D warnings, withSwatinem/rust-cache(keyed onmonitor/Cargo.lock). Arust-msrvjob builds and tests on 1.88, therust-versioninCargo.tomland ratatui 0.30's floor. I checked that pin locally withcargo +1.88 test --locked(45/45).Branch protection:
mainrequires four checks by name:ShellCheck,Bats tests (ubuntu-latest),Bats tests (macos-latest)andLoadout drift check. The newRust (ubuntu-latest),Rust (macos-latest)andRust MSRV (1.88)checks are not required. Add them in the branch settings if they should gate merges. I did not change protection.install.shstays with #277, and the queue is read only through the snapshot (#275 ownstask-monitor-queue).Verification
cargo test: 45 pass,cargo clippy --all-targets: clean. I broke eight targets on purpose (tab-name rule, session check, run ordering, local-run coalescing, log filter, narrow fit, error reset, timeout kill), plus the symlink canonicalization, and each turned a test red.TASK_FORCE_HOME: it renders, a session-file write and a new sidecar each trigger a--localrun, aradio/logappend does not, andqexits 0.--allsnapshot from this machine (4 repos) on a TestBackend to check the layout../run_tests.sh: 1436/1436.tools/check-drift.sh: clean.shellcheck -x bin/task-monitor-snapshot: clean. CI runs the Rust tests as of the second commit.🤖 Generated with Claude Code