Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
6c3df3a
feat(dashboard): cycle the selection through tagged tasks with M
ReagentX Jul 31, 2026
003f2b1
fix(pickdir): filter the recent directories instead of hiding them
ReagentX Jul 31, 2026
303ebb4
refactor(docs): clarify command descriptions and improve consistency …
ReagentX Jul 31, 2026
0952f18
feat(controls): add controls overlay for dashboard key references and…
ReagentX Jul 31, 2026
2c16589
docs: update installation instructions and enhance usage details in R…
ReagentX Jul 31, 2026
d24467b
docs: update usage section in README for clarity and consistency
ReagentX Jul 31, 2026
00f0403
docs: clarify usage instructions for starting the dashboard
ReagentX Jul 31, 2026
4146418
test(docs): generate the README dashboard frames from a fabricated fleet
ReagentX Jul 31, 2026
f74f399
fix(docs): park the capture cursor and correct the capture recipe
ReagentX Jul 31, 2026
c866cba
fix(docs): peek the first completed run so the selection frames the box
ReagentX Jul 31, 2026
96324b2
test(docs): show failure, a real age spread, and a clipped list
ReagentX Jul 31, 2026
f5743c3
test(docs): name the capture window in the frame itself
ReagentX Jul 31, 2026
bbbc3c4
test(docs): add custom-group and controls-overlay frames
ReagentX Jul 31, 2026
9707689
docs(img): give each frame its own capture line
ReagentX Jul 31, 2026
1f990fc
fix(docs): clarify instructions for capturing dashboard frames
ReagentX Jul 31, 2026
457e509
docs: add images for fleet and group views in documentation
ReagentX Jul 31, 2026
472c2eb
docs: update command descriptions and clarify overlay behavior
ReagentX Jul 31, 2026
f6843b8
refactor: improve documentation and clarity in app and ui modules
ReagentX Jul 31, 2026
071f9d7
docs: enhance README with custom groups section and clarify installat…
ReagentX Jul 31, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 22 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ Press `Enter` to take control of a task, then `Ctrl-\` to return to the dashboar

![`fleetcom` attach](docs/img/attach.png)

### Custom groups

Organize related tasks into named groups, even when they run in different directories.

![`fleetcom` custom-group view](docs/img/groups.png)

### Resume agent sessions

Start `claude`, `codex`, or `grok` normally. When you rerun the task or reload a saved session, `fleetcom` resumes the same conversation automatically.
Expand Down Expand Up @@ -53,48 +59,35 @@ For normal use, install the published crate from [crates.io](https://crates.io/c
cargo install fleetcom
```

### From source

From the project root:

- `cargo install --path .` to install `fleetcom` on `PATH`, or
- `cargo build --release` and run `target/release/fleetcom`.
[Source installation](docs/README.md#installation-from-source) covers builds from a repository clone.

## Usage

| Invocation | Behavior |
| -- | -- |
| `fleetcom` | Connect to the daemon, autostarting it when necessary, and open the dashboard |
| `fleetcom <session>` | Load a saved session, then open the dashboard |
| `fleetcom --foreground` | Run in-process without a daemon; tasks stop when the client quits |
| `fleetcom --scrollback <lines>` | Set per-task scrollback (default 2,000); read at supervisor start, so a running daemon keeps its value until `--kill` |
| `fleetcom --kill` | Stop the daemon and every task it owns |
| `fleetcom --help` / `--version` | Print usage or version information and exit |
Connect to the daemon, autostarting it when necessary, and open the dashboard by invoking:

The first ordinary invocation starts the daemon when necessary. `--daemon` is an internal mode.
```sh
fleetcom
```

The [invocation reference](docs/commands.md#invocation) covers sessions, foreground mode, scrollback, and daemon shutdown.

## Key Commands

### Dashboard

| Key | Command |
| -- | -- |
| ↑ ↓ / `k` `j` | move the selection |
| `Enter` | attach to the selected task |
| `Space` | peek at the selected task |
| `n` | new command in the invocation directory |
| `@` | new command in a directory you pick (with completion) |
| `q` | disconnect; leave the daemon and tasks running |
| `Q` | quit; kill the tasks and stop the daemon |
The dashboard shows two short key hints; `?` opens an expanded key reference:

```text
❯ n run · @ dir · / find · s sort
↑↓ select · enter attach · space peek · ? controls
```

### Attached

| Key | Command |
| -- | -- |
| `Ctrl-\` | background the task and return to the dashboard |
| anything else | forwarded to the task's PTY |
- `Ctrl-\` backgrounds the task and returns to the dashboard.
- Other supported input is forwarded to the task's PTY.

[`docs/commands.md`](docs/commands.md) covers every key and launch flag, including the routing mechanics.
[`docs/commands.md`](docs/commands.md#dashboard) covers every key and launch flag, including the routing mechanics.

## How it works

Expand Down
10 changes: 5 additions & 5 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,11 @@ Run `fleetcom`. The first invocation starts the daemon and opens an empty dashbo
```text
fleetcom 0 running · 0 idle · 0 done by state · dir · custom

❯ n run · @ dir · / find · s sort · w save · o load
↑↓ select · enter attach · space peek · m tag · g group · R rename · r rerun · X kill · q detach · Q quit
❯ n run · @ dir · / find · s sort
↑↓ select · enter attach · space peek · ? controls
```

Press `n`, enter a command, and press `Enter`. The command runs in its own PTY and appears under Running. Repeat the process for a second command:
The hint rows cover common dashboard actions; `?` opens an expanded key reference. Press `n`, enter a command, and press `Enter`. The command runs in its own PTY and appears under Running. Repeat the process for a second command:

```text
fleetcom 2 running · 0 idle · 0 done by state · dir · custom
Expand All @@ -75,8 +75,8 @@ Press `n`, enter a command, and press `Enter`. The command runs in its own PTY a
✻ cargo watch -x test test result: ok. 42 passed 9s
✻ npm run dev VITE v5.0 ready in 312 ms 4s

❯ n run · @ dir · / find · s sort · w save · o load
↑↓ select · enter attach · space peek · m tag · g group · R rename · r rerun · X kill · q detach · Q quit
❯ n run · @ dir · / find · s sort
↑↓ select · enter attach · space peek · ? controls
```

Each row is `glyph · tag · command · latest output · age`. The age counts from the task's last meaningful edge: launch while running, last output once idle, exit once completed. `Space` peeks: a read-only box of the selected task's live screen, without leaving the dashboard:
Expand Down
32 changes: 26 additions & 6 deletions docs/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,19 @@
| `/` | Jump the selection to a task by name, command, or group (opens the [find palette](#the--find-palette)) |
| `s` | Cycle grouping: by state / by directory / by custom group |
| `m` | Tag the selected task "in use" (toggles) |
| `M` | Select the next tagged task in dashboard order, wrapping at the end |
| `g` | Assign the selected task to a group (opens the group picker) |
| `R` | Rename the selected task: a display name shown in place of the command |
| `r` | Rerun a finished task; supported agent tasks use the captured resume command |
| `X` | Kill a running task (`TERM`, then `KILL` after 2 s), or remove a finished one |
| `w` | Save the current tasks as a session |
| `o` | Load a saved session or a recovery snapshot (opens the [session picker](#the-o-session-picker)) |
| `q` (or `Ctrl-C`) | Disconnect; leave the daemon and tasks running |
| `?` | Open the [controls overlay](#the--controls-overlay) |
| `q` (or `Ctrl-C`) | Disconnect from the daemon; under `--foreground`, quit and stop the tasks |
| `Q` | Quit; kill the tasks and stop the daemon |

![`fleetcom` controls overlay](img/controls.png)

### Status glyphs

| Glyph | Meaning |
Expand Down Expand Up @@ -128,6 +132,8 @@ Groups belong to task state: an assignment survives client detach and rerun (`r`

`m` toggles the "in use" tag and marks the task with `◆`. In state mode, tagged tasks form the In use section at the top. In custom mode, a tag moves the task to the top of its existing group rather than creating a global section. Within a dir or custom section, tasks sort as tagged, live, then completed; each class then sorts by directory and spawn order. Idle state does not affect row order in these modes, so a quiet task keeps its position and shows `∙`. State mode instead moves quiet tasks from Running to Idle.

`M` cycles the selection through tagged tasks in dashboard order. It wraps after the last tagged task. With no tagged tasks, the selection does not move; with one, the selection moves to that task and stays there.

In custom mode only, a new command inherits the selected task's group, through both `n` and the `@` picker. The spawn prompt shows the destination as `❯ dir ▸ group ▸ command`, each segment present only when it applies: the dir segment for a non-default directory, the group segment when a group will be inherited. State- and dir-mode spawns start unassigned.

#### Renaming
Expand All @@ -142,11 +148,15 @@ The daemon removes control characters, trims surrounding whitespace, and limits

`@` opens a bottom panel containing a path field and its matching directories. `Enter` depends on the selected row type:

- Current directory: run the command in that directory (`Enter`).
- Recent directories: ones you've launched in before; `Enter` runs there, `Tab`/`→` browses into them.
- Subdirectories of the current path: `Enter` or `Tab`/`→` descends into one.
- Resolved path: run the command in that directory (`Enter`). Row 0 is always this row, so the list is never empty.
- Current task directories: `Enter` runs there; `Tab`/`→` browses into them. These rows precede subdirectories.
- Subdirectories of the resolved path: `Enter` or `Tab`/`→` descends into one.

Typing filters both lists under different rules. A subdirectory matches the fragment as a case-insensitive prefix. A current task directory matches a case-insensitive substring of its final path component: `log` finds `~/Documents/Code/Rust/Logria`, while `crab` finds both `crabapple` and `crabstep`. Parent components do not participate, so `doc` does not match every directory under `~/Documents/`.

Typing filters the rows; `Backspace` deletes one character and the matches re-filter; `↑`/`↓` move the highlight; `Esc` cancels. Completion updates on each input, permitting navigation and launch without leaving the dashboard. `←`/`→` move the caret within the typed path (`→` descends only when the caret is at the end), and `Ctrl-A`/`Ctrl-E` (or `Home`/`End`) jump to either end; the same caret keys work in every `fleetcom` text field.
Once the field contains `/`, current task directory rows are omitted; the picker shows the resolved path and its matching subdirectories. Without `/`, a current task directory that is also a matching subdirectory appears once, with the current task row behavior.

`Backspace` deletes one character and the matches re-filter; `↑`/`↓` move the highlight; `Esc` cancels. Completion updates on each input, permitting navigation and launch without leaving the dashboard. `←`/`→` move the caret within the typed path (`→` descends only when the caret is at the end), and `Ctrl-A`/`Ctrl-E` (or `Home`/`End`) jump to either end; the same caret keys work in every `fleetcom` text field.

## The `/` find palette

Expand Down Expand Up @@ -178,6 +188,16 @@ The daemon normalizes every group name received from the picker or a [session](s

A recovery row reads `<age> ago · <tasks> task(s) · <label>`: the file's age, its command count, and its stored label (normally `autosaved <timestamp>`). `Enter` loads the highlighted snapshot; the status line confirms the load and suggests saving it. Press `w` to save the recovered fleet as a named session.

## The `?` controls overlay

The dashboard's two hint rows cover common actions: `↑↓ select · enter attach · space peek · ? controls` and `❯ n run · @ dir · / find · s sort`. `?` opens an expanded reference for dashboard actions and the attached-mode background chord.

The overlay groups bindings by purpose in a centered box. It does not scroll. `?`, `Esc`, or `q` returns to the dashboard. Other keys do nothing in the overlay; `Ctrl-C` still disconnects.

`?` is Shift-`/`. `fleetcom` accepts both event forms for this binding: `?`, or `/` with Shift. An unmodified `/` still opens the [find palette](#the--find-palette).

The box uses a two-column layout. When height is limited, group headers drop first; if the entries still do not fit, the overlay clips the tail and reports `+N more` on the bottom border. Narrow terminals clip each row to the box width.

## Peek

A centered box over the dashboard showing the selected task's live screen (the last screenful). `↑`/`↓` (or `k`/`j`) switch which task you're peeking at; `Enter` attaches to it; `r` reruns it if it has finished; `Space`, `Esc`, or `q` closes.
Expand All @@ -186,7 +206,7 @@ The footer's `preview:` segment names the source of the row's dashboard preview:

## Attached

The task owns the terminal, and its status bar reads `[attached] <command> Ctrl-\ background`, or `[attached] <name> · <command>` for a named task. `Ctrl-\` returns to the dashboard; every other key (control chords included) goes to the child.
The task owns the terminal, and its status bar reads `[attached] <command> Ctrl-\ background`, or `[attached] <name> · <command>` for a named task. `Ctrl-\` returns to the dashboard. Other supported input normally goes to the child; [scrollback](#scrollback) reserves its navigation keys.

## Connection loss

Expand Down
47 changes: 47 additions & 0 deletions docs/img/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# README screenshots

Each `.ansi` file is one dashboard frame written by the real renderer over a
fabricated fleet, so a terminal `cat`-ing it paints exactly what a live run
paints.

| Frame | Shows |
| -- | -- |
| `home.ansi` | grouped by directory, the list outgrowing its region |
| `quickpeek.ansi` | grouped by state, peek open over a finished run |
| `groups.ansi` | grouped by custom group: one section spans five directories, and one directory feeds two sections |
| `controls.ansi` | the `?` overlay over the dir-grouped dashboard |

All four render the same 21 tasks. `attach.png` is captured from a live session,
because it needs a live attach.

The fixture is `write_readme_screenshot_fixtures` in `src/app_tests.rs`. Edit the
fleet there (task names, previews, ages, tags, selection), then regenerate:

```sh
cargo test -- --ignored write_readme_screenshot_fixtures
```

Every duration in the fixture is constant. With the same `$HOME`, two runs write
identical bytes; section labels abbreviate that path to `~`.

## Capturing

```sh
clear; cat docs/img/home.ansi; read -rsk 1; printf '\033[?25h'
clear; cat docs/img/quickpeek.ansi; read -rsk 1; printf '\033[?25h'
clear; cat docs/img/groups.ansi; read -rsk 1; printf '\033[?25h'
clear; cat docs/img/controls.ansi; read -rsk 1; printf '\033[?25h'
```

`read` blocks until a keypress, so the screenshot is taken with nothing emitted
after the frame; the trailing `printf` restores the cursor, which the frame
hides. The flags are zsh's; bash spells the same thing `read -rs -n1`, and
`read -r` waits for Enter in both.

Each frame parks the cursor on the terminal's last row, outside centered
overlays. This matters for `render_peek`, which otherwise leaves the cursor
inside the peek box while `read` waits.

The terminal must be at least 107×30, the size the frames are painted at. `clear`
first: a frame only paints its own rows, so a taller window would show stale
scrollback beneath it.
Binary file modified docs/img/attach.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions docs/img/controls.ansi
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
]0;fleetcom[?2026h[?25l fleetcom 12 running · 2 idle · 7 done by state · dir · custom · 4/21   ~/Documents/Code/Rust/fleetcom  ✻ ◆Dashboard Refine ✻ Scope small fixes for dashboard and CLI 2m ✻ ◆Summary Refine Inferring… · thinking with high effort 5m ✻ Grok Language Grok 4.5 (xhigh) · Responding… 12m ✻ Codex Language gpt-5.6-sol high · fleetcom · feat/cs/interface-fixes · 387K used · 9.… 18m ✻ Codex Review gpt-5.6-sol high · fleetcom · feat/cs/interface-fixes · 221K used · 4.… 24m ✓ cargo test test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered… 12s ✗ cargo clippy error: could not compile `fleetcom` (lib test) due to 1 previous error 3m ~  ✻ claude agents 2 awaiting input · claude agents 1h ✻ Zellij Desktop ¦ Utility 2h ∙ python >>> 41m ✓ brew update && brew upgra… Already up-to-date. 13m ~/Documents/Code/Apple/turret  ✻ Game Infra Review Turret Game Codebase Organization and Ex… - grok 8m ✻ Missile Nerf gpt-5.6-sol high · turret · main · 129K used · 1.31M in · 10.1K out 33m ✻ EMP Nerf gpt-5.6-sol high · turret · main · 161K used · 1.64M in · 10.4K out 35m ~/Documents/Code/Rust/crabapple  ✓ cargo test all doctests ran in 0.39s; merged doctests compilation took 0.38s 17m ~/Documents/Code/Rust/crabstep  ✓ cargo test all doctests ran in 0.83s; merged doctests compilation took 0.81s 21m ~/Documents/Code/Rust/imessage-exporter  ✻ claude ✻ Review GitHub issue 780 6m ✓ cargo test all doctests ran in 1.99s; merged doctests compilation took 1.95s 19m ~/Documents/Code/Rust/Logria  ✻ cargo watch -x test [Running 'cargo test'] test result: ok. 223 passed; 0 failed 45s ❯ n run · @ dir · / find · s sort  ↑↓ select · enter attach · space peek · ? controls [?25l┌─ controls ────────────────────────────────────────────┐│ Navigate ││ ↑↓ / kj move selection / find a task ││ Tab ⇧Tab jump section M next tagged ││ Act ││ enter attach r rerun finished ││ space peek X kill or remove ││ Organize ││ m tag in use R rename ││ g assign group s cycle grouping ││ Create ││ n run here @ run in a dir ││ Session ││ w save session o load session ││ Leave ││ q detach Q quit and kill ││ Attached ││ Ctrl-\ background │└───────────────────────────────────────────────────────┘ ? esc close [?2026l
Binary file added docs/img/controls.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading