Skip to content
jayjongcheolparkPublic

About

Read-only terminal dashboard for firstmate fleets (local and remote homes)

Resources

Stars

2 stars

Watchers

0 watching

Forks

Latest commit

 

History

3 Commits

Folders and files

Repository files navigation

fleetdeck

A read-only terminal dashboard for firstmate fleets. It shows the fleet information that firstmate keeps as plain files in each home, for homes on this machine and on other machines over SSH.

fleetdeck: a tour of the homes, Work, a task detail, PRs, Context and Activity

The demo fleet is made-up data: a main home, a local second mate (web-mate) and a remote home on devbox. See Demo to record it again.

What it shows

For each home:

  • Homes: the configured homes and the second mates that their data/secondmates.md lists, local or remote. Each home shows its session lock (held, stale or free, from state/.lock and a ps check of the pid), its watcher beat, and away mode.
  • Work: the task records in state/<id>.meta, the current state of each task from its status log state/<id>.status, the open decisions and blockers, the captain holds, and the backlog in data/backlog.md (In flight, Queued, Done).
  • PRs: the PR of each task (the pr= key in its meta, else the first PR link in its status log) and of each in-flight backlog row. Press p to read the state, checks, mergeability, review decision and unresolved review threads of each PR with gh.
  • Context: the documents that are loaded into a firstmate session at start (data/projects.md, data/secondmates.md, data/captain.md, data/captain-shared.md, data/learnings.md and, in a second mate, data/charter.md), with sizes and the token estimate against config/startup-memory-budget. It also shows the files in config/, the projects, the second-mate routes and the other data/*.md documents.
  • Activity: the queue counts (wake queue, operational inbox, task inboxes, pending replies), the most recent status events across tasks, and the tail of state/fleet-ledger.jsonl.

Press Enter on any row to open a detail view: a task with all its meta keys and status events, a decision, a backlog row with its body, a PR, a file, or a ledger record.

Install

With the install script

Run this command on macOS or Linux:

curl -fsSL https://raw.githubusercontent.com/jayjongcheolpark/fleetdeck/main/install.sh | sh

The script downloads the release archive for your OS and CPU, checks it against the release's SHA256SUMS, and installs fleetdeck to ~/.local/bin. If that directory is not on your PATH, the script tells you the line to add to your shell profile.

  • To install to a different directory, set FLEETDECK_INSTALL_DIR: curl -fsSL … | FLEETDECK_INSTALL_DIR=/usr/local/bin sh.
  • To install a specific version, set FLEETDECK_VERSION, for example FLEETDECK_VERSION=0.2.0.

Update

To replace the installed binary with the latest release, run:

fleetdeck update

fleetdeck update reads the latest GitHub Release, downloads the archive for the target that the running binary was built for, and checks it against SHA256SUMS. It runs the new binary once with --version, then renames it over the running binary. If any step fails, the old binary stays in place. It needs no GitHub token.

To only check whether a newer release exists, run fleetdeck update --check.

fleetdeck update works for a binary from the install script or from a release archive. If you installed with cargo, update with cargo.

From a release archive

Each GitHub Release has a fleetdeck-<version>-<target>.tar.gz archive for these targets:

Target Platform
aarch64-apple-darwin macOS on Apple silicon
x86_64-apple-darwin macOS on Intel
x86_64-unknown-linux-gnu Linux x86_64
aarch64-unknown-linux-gnu Linux arm64

Each archive holds the fleetdeck binary, this README and the license.

  1. Set the version and the target:

    VERSION=0.2.0
    TARGET=aarch64-apple-darwin
  2. Download the archive and the SHA256SUMS file:

    BASE=https://github.com/jayjongcheolpark/fleetdeck/releases/download/v$VERSION
    curl -fLO "$BASE/fleetdeck-$VERSION-$TARGET.tar.gz"
    curl -fLO "$BASE/SHA256SUMS"
  3. Check the archive against SHA256SUMS. On macOS, use shasum -a 256 in place of sha256sum.

    sha256sum --check --ignore-missing SHA256SUMS
  4. Extract the archive and put the binary on your PATH:

    tar -xzf "fleetdeck-$VERSION-$TARGET.tar.gz"
    install -m 755 "fleetdeck-$VERSION-$TARGET/fleetdeck" ~/.local/bin/fleetdeck

If you download the archive with a browser, macOS can block the binary because it is not signed. To allow it, run xattr -d com.apple.quarantine ~/.local/bin/fleetdeck.

With cargo

You need a Rust toolchain (1.88 or later) to build from source.

cargo install --git https://github.com/jayjongcheolpark/fleetdeck --tag v0.2.0 fleetdeck

Omit --tag to build the latest main. From a clone of this repository, use cargo install --path crates/fleetdeck.

Configure

  1. Create ~/.config/fleetdeck/config.toml (or $XDG_CONFIG_HOME/fleetdeck/config.toml).
  2. Add one [[home]] entry for each main home. For a remote home, set host to an SSH alias from your ~/.ssh/config.
refresh_secs = 30   # read every home again after this many seconds
timeout_secs = 15   # give up on a machine after this many seconds

[[home]]
name = "main"
path = "/Users/me/Developer/firstmate"

[[home]]
name = "devbox"
host = "devbox"         # ssh alias; omit for a home on this machine
path = "~/firstmate"    # ~ expands on the remote host
# discover = false      # do not add second mates from data/secondmates.md

You do not need to list second mates. fleetdeck reads data/secondmates.md in each configured home and adds every route it finds: a local route on the same machine as its parent, and a host: route over SSH.

Without a config file, fleetdeck shows $FM_HOME, or the current directory when it is a firstmate home. You can also pass homes on the command line:

fleetdeck --home ~/Developer/firstmate --ssh devbox:~/firstmate

Use

Key Action
↑/↓, j/k Move in the focused pane
Tab, ←/→ Move between the home list and the content
1 2 3 4, [ ] Work, PRs, Context, Activity tabs
Enter Open the selected row in the detail view
Esc Close the detail view
r Read every home again now
p Read PR status with gh
? Help
q Quit

Other modes:

  • fleetdeck --json prints the collected snapshots as JSON.
  • fleetdeck --frame 160x45 --tab work --select 0 prints one rendered frame as text.

fleetdeck reads every home again after refresh_secs. When the terminal reports that it lost focus, fleetdeck stops the timed reads and shows paused in the status bar. When the terminal gets focus again, fleetdeck reads every home immediately and starts the timer again. r still reads every home while fleetdeck is paused. A terminal that does not report focus changes never pauses fleetdeck.

Screenshots

The Work tab shows the tasks, the open decisions and blockers, the captain holds and the backlog of the selected home:

The Work tab of the main home

Enter opens the selected row in a detail view:

The detail view of a task

p reads each PR with gh:

The PRs tab with checks, mergeability and review state

The read-only guarantee

fleetdeck never writes, moves or deletes anything in a home, and it never changes fleet state.

  • One read-only script does all home access. crates/fleetdeck-core/src/gather.sh is the complete set of commands that fleetdeck runs on a machine that holds a home. It only uses head, tail, ls, stat, wc, awk, tr, ps, date, hostname and uname, and its only redirections go to /dev/null. fleetdeck runs it with sh -s for a local home and with ssh <alias> sh -s for a remote home, so both paths are the same code.
  • No firstmate scripts. fleetdeck parses the files directly. It does not run fm-fleet-snapshot.sh or fm-bearings-snapshot.sh, because they refresh a cache under state/. It does not run fm-crew-state.sh either, because that script reads terminal panes and calls the forge.
  • No acknowledgements. Queues are counted, never drained: the wake queue, the operational inbox and the task inboxes stay exactly as they are. fleetdeck sends no keys to terminal panes and sends no signals to processes. Liveness comes from ps -p <pid> only.
  • Secrets are not read. Files in config/ whose names contain password, secret, token, credential, key or .bak, or end in .env, are shown by name and size only.
  • GitHub is read-only. The PR tab uses gh pr view --json … and one gh api graphql query for review threads. It never posts, edits, approves or merges.
  • Remote reads go straight to the files. SSH runs the gather script under the login shell of the remote account. fleetdeck does not use firstmate's fm-on.sh remote job channel, so it does not interrupt the parent's reply mirror.

The integration test tests/fake_home.rs builds a fake main home and second mate, collects them, and checks that every path, byte and modification time is unchanged.

Layout

  • crates/fleetdeck-core: the data collection library, with no terminal code. collect::collect_fleet returns one model::HomeSnapshot per home. Another front end can reuse it.
  • crates/fleetdeck: the ratatui terminal UI.

The parsers follow the producers in firstmate: bin/fm-classify-lib.sh for status lines and open decisions, the tasks-axi markdown grammar for the backlog, bin/fm-secondmate-registry-lib.sh for second-mate routes, bin/fm-project-mode.sh for projects, and docs/fleet-ledger.md for the ledger.

Limits

  • The task state comes from the status log, the same way fm-crew-state.sh falls back to it. fleetdeck does not look at terminal panes, so it cannot tell a working pane from an idle one beyond the busy-state file.
  • A status log larger than 1 MiB is read from its end only, so a decision that was opened before that point and never closed does not show in the Work tab. The home summary line still shows firstmate's own count from state/home-summary.json.
  • A remote route listed by a remote home (a second mate on a third machine) is skipped.
  • PR status supports github.com only.

Demo

The GIF and the screenshots come from demo/demo.tape, a vhs script. To record them again, install Docker and run:

demo/record.sh

The script builds fleetdeck and runs vhs in a container. demo/setup.sh builds the demo fleet from demo/homes. In the container, small stand-ins in demo/bin replace ssh, gh and hostname. The "remote" home is read through fleetdeck's real ssh transport, but from a local directory, and the PR data is made up, so the recording makes no network calls.

License

MIT

About

Read-only terminal dashboard for firstmate fleets (local and remote homes)

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages