Skip to content

feat(fleet-view): add the narrow needs-you-first captain sidebar - #2

Merged
ecloin merged 1 commit into
mainfrom
fm/fleet-sidebar
Aug 11, 2026
Merged

feat(fleet-view): add the narrow needs-you-first captain sidebar#2
ecloin merged 1 commit into
mainfrom
fm/fleet-sidebar

Conversation

@ecloin

@ecloin ecloin commented Aug 11, 2026

Copy link
Copy Markdown
Owner

What this changes

bin/fm-fleet-view.sh renders one wide Markdown table set today, which reads well in a full-width terminal but not in the narrow split pane a captain keeps open beside a session.

This makes the captain sidebar the default rendering:

⚓ FLEET · 19:40 · 7 tasks · 3 need you
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
NEEDS YOU (3)
● PR #1905 pane-naming — checks green,
  awaiting merge word
  ↳ https://github.com/kunchenguid/firstmate/pull/1905
● 3412 contracts — decision: pick REST
  or gRPC for the sync endpoint
● 7002 local ready — ready to review on
  your local copy
  ↳ bin/fm-review-diff.sh 7002
IN FLIGHT (2)
◐ 3406 merge-strategy — working 1h
◐ 7003 dead worker — working 14m
WAITING (2)
○ 2909 review scout — report ready,
  decisions open
○ 7001 pause task — upstream release
  lands Thursday
DONE TODAY (1)
✓ 3410 re-verify
  • --watch [seconds] redraws on an interval (default 5s) and exits cleanly on interrupt.
  • --wide keeps the previous Markdown tables; --json is unchanged.
  • Entries that ask for something carry a copyable full PR URL or a runnable review command.
  • Wording is captain-facing throughout: no internal state, monitoring, or runtime vocabulary.

Read-only

The view still consumes bin/fm-fleet-snapshot.sh --json rather than reparsing fleet state, so it inherits the snapshot's read-only guarantee: no session lock, no queue drain, no monitoring, nothing sent to a worker, and no writes under state/ or data/.
That is what makes it safe to leave redrawing beside a live session, and tests/fm-fleet-view.test.sh pins it by comparing every file in a fixture home - including modification times - across a render.

Snapshot additions

Two additive fields, both documented in the script header:

  • paths.status_log.last_event_epoch / .age_seconds date the last status append, so a renderer can age a declared event without stat-ing state files itself.
  • actions.review carries the per-task review command, which bin/fm-review-diff.sh already owns.

Notes

  • Wrapping counts codepoints rather than bytes, because the section glyphs and the em dash are multibyte and a byte-counting wrap folds a 40-column pane several characters early. A test drives a long entry through a fixed-width render and fails if any line overruns.
  • A copyable URL or command is never folded, so a double-click still selects all of it.
  • A second mate earns a line only when it is actually holding something, since a persistent second mate idles by design.

Verification

  • bin/fm-lint.sh clean (ShellCheck 0.11.0).
  • bin/fm-doc-audience-check.sh clean; docs/fleet-view.md classified operator-current.
  • bin/fm-test-run.sh --changed - 32 selected scripts, all passing.
  • bin/fm-test-run.sh --family snapshot-bearings - 3/3 passing, including the existing bearings and snapshot coverage.
  • The new width and read-only tests were each confirmed to fail when the behavior they cover is removed, so neither passes vacuously.

The fleet view rendered one wide Markdown table set, which reads well in a
full-width terminal but not in the split pane a captain keeps open beside a
session. This makes the sidebar the default rendering: needs-you first, then
work under way, declared waits, and what landed today, in captain-facing
wording with a copyable PR URL or review command on the entries that ask for
something. The previous tables stay available under --wide, and --json is
unchanged.

Classification still consumes fm-fleet-snapshot.sh --json rather than reparsing
fleet state, so the view keeps the snapshot's read-only guarantee: no lock, no
queue drain, no monitoring, no writes under state/ or data/. A render is
therefore safe to leave looping under --watch beside a live session, which the
tests pin by comparing every file in a fixture home across a render.

The snapshot gains the two fields the sidebar needed and had no owner for: the
status log's append time and age, so a renderer can age a declared event
without stat-ing state files itself, and the per-task review command, which
fm-review-diff.sh already owns.

Wrapping counts codepoints instead of bytes, because the section glyphs and the
em dash are multibyte and a byte-counting wrap folds a 40-column pane early.
@ecloin
ecloin merged commit 6af31a6 into main Aug 11, 2026
11 of 13 checks passed
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