Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ Managing several long-lived commands across terminal panes is pesky, especially

- Run each command in its own PTY and group tasks by state, working directory, or named group.
- Keep tasks running under a daemon across client disconnects.
- Save and reload task recipes: directories, commands, group assignments, display names, tags, and the flagship.
- Save and reload task recipes: directories, commands, group assignments, display names, tags, the flagship, and which tasks had finished.
- Rerun a completed task in place, keeping its identity, group, and name.
- Launch `claude`, `codex`, `grok`, and `omp` as managed agents and resume their conversations on rerun and reload.
- Recover the current task set from automatic snapshots.
Expand Down
6 changes: 3 additions & 3 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# fleetcom Documentation

The daemon supervises live processes; session files store repeatable launch recipes. Reconnecting returns you to the daemon's running tasks, while loading a session starts new processes from its recipe. Use this guide for storage paths, lifecycle details, and a complete first run.
Use the daemon to supervise live processes and session files to save repeatable launch recipes, including whether each task had finished. Reconnect to access the daemon's running tasks. Load a session to start new processes for its live entries and restore finished tasks as stopped rows. Use this guide for storage paths, lifecycle details, and a complete first run.

## Index

Expand Down Expand Up @@ -150,7 +150,7 @@ Press `w`, type a name, and press `Enter` to save the fleet as a [session](sessi
| `<runtime>/daemon.lock` | `0666 & ~umask` when new; otherwise unchanged | the owning daemon's PID, trustworthy only while its `flock` is held |
| `<runtime>/daemon.log` | `0666 & ~umask` when new; otherwise unchanged | stderr from the autostarted daemon |
| [session directory](#config-directory-sessions) | `0700` | saved recipes |
| `<sessions>/<name>.json` | `0600` | directories, commands, groups, display names, tags, the flagship |
| `<sessions>/<name>.json` | `0600` | directories, commands, groups, display names, tags, the flagship, stopped flags |
| `<sessions>/recovery/` | `0700` | [automatic snapshots](sessions.md#recovery) |
| `<sessions>/recovery/<snapshot>.json` | `0600` | one automatic session recipe |
| `<capture-root>/<pid>-<nonce>/` | `0700` | [agent hook, notifier, and extension-module assets plus per-run capture payloads](agent-resume.md#capture-state-and-isolation) |
Expand All @@ -165,7 +165,7 @@ The runtime directory is validated before its contents are used. The path must b

Full command lines are persisted in recipes, including any embedded secrets. A token passed as an argument is written to its session file and to every recovery snapshot that captures the task.

The client environment is not persisted. Each client's environment and working directory are sent during the connection handshake and retained in daemon memory. Use session and recovery files to preserve only directories, commands, group assignments, display names, tags, and the flagship.
The client environment is not persisted. Each client's environment and working directory are sent during the connection handshake and retained in daemon memory. Use session and recovery files to preserve only directories, commands, group assignments, display names, tags, the flagship, and whether each task had finished.

### Captured IDs

Expand Down
23 changes: 12 additions & 11 deletions docs/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ Choose the operating mode with launch arguments. Use keys to control the dashboa
| `Ctrl-]` | Attach to the flagship |
| `g` | Assign the selected task to a group (through the group picker) |
| `R` | Rename the selected task: a display name shown in place of the command |
| `r` | Rerun a finished task; resume the conversation for a managed agent |
| `X` | Kill a running task (`TERM`, then `KILL` after 2 s), or remove a finished one |
| `r` | Rerun a finished task or start a stopped one; resume the conversation for a managed agent |
| `X` | Kill a running task (`TERM`, then `KILL` after 2 s), or remove a finished or stopped one |
| `w` | Save the current tasks as a session |
| `o` | Load a saved session or a recovery snapshot (through the [session picker](#the-o-session-picker)) |
| `?` | Open the [controls overlay](#the--controls-overlay) |
Expand All @@ -53,6 +53,7 @@ Choose the operating mode with launch arguments. Use keys to control the dashboa
| `∙` | Idle: running, but quiet |
| `✓` | Completed, exit 0 |
| `✗` | Completed, non-zero exit |
| ` ` | Stopped: restored from a [session](sessions.md) and not yet started |
| `◆` | Tagged "in use" |
| `⚑` | The [flagship](#the-flagship) |

Expand Down Expand Up @@ -108,13 +109,13 @@ Press `Esc`, `Enter`, `q`, or `End`, or scroll to the bottom, to return to live

#### Destroying tasks

Press uppercase `X` to kill a running task or remove a finished one. On removal, remaining processes in the task's process group are also terminated: `TERM`, then `KILL` after two seconds. Lowercase `x` and `Ctrl-X` are unbound.
Press uppercase `X` to kill a running task or remove a finished or stopped one. On removal of a finished task, remaining processes in its process group are also terminated: `TERM`, then `KILL` after two seconds. A stopped task has no process group to sweep. Lowercase `x` and `Ctrl-X` are unbound.

#### Rerunning tasks

Press `r` to rerun a finished task. Running tasks cannot be rerun without first being killed and are left untouched.
Press `r` to rerun a finished task or start a stopped one: a task restored from a [session](sessions.md) that had finished when the file was written. Until you start a stopped task, there is no process or output to view in attach or peek. Kill a running task before rerunning it; pressing `r` while it is running has no effect.

On rerun, the replacement is started in the same directory with the requesting client's environment. For a literal task, the exact command text is run again. For a managed agent, the binary is resolved on the current `PATH`, and the captured conversation is resumed when an ID is known; see [agent session resume](agent-resume.md).
On rerun, start the replacement in the same directory with the requesting client's environment. For a literal task, run the exact command text again. For a managed agent, resolve the binary on the current `PATH` and resume the captured conversation when an ID is known; see [agent session resume](agent-resume.md). For a stopped managed agent, resume its stored session ID. Binary lookup is deferred until you press `r`, so you can load the session without the agent installed.

On rerun, the task's ID, `◆` tag, group, name, and spawn order are preserved; its clock and screen are reset. Under lifecycle sorting, the restarted task may be listed in another section. You can also rerun inside peek without closing the overlay.

Expand All @@ -128,25 +129,25 @@ Press uppercase `Q` to stop the daemon and terminate each task's process group:

#### Grouping and tagging

Press `s` to cycle through state, dir, and custom grouping. In the header strip `by state · dir · custom`, the active mode is bold and the rest dim.
Press `s` to cycle through state, dir, and custom grouping. In the header strip `by state · dir · custom`, the active mode is bold and the rest dim. To its left, read the counts as `N running · N idle · N done`, followed by ` · N stopped` only while at least one stopped task is listed.

- By state: In use / Running / Idle / Completed. After 10 s without output, a running task is grouped under Idle. Completed tasks are grouped in one section, with exit status marked `✓`/`✗`.
- By state: In use / Running / Idle / Completed. After 10 s without output, a running task is grouped under Idle. Completed tasks are grouped in one section, with exit status marked `✓`/`✗`. Stopped tasks are placed in Completed as well, with a blank glyph and a blank age cell: no process has run under the row, so there is no launch, output, or exit time to measure from.
- By dir: one section per working directory; the invocation directory first, then the remaining labels sorted without regard to case.
- By custom group: one section per group name, sorted without regard to case, with Unassigned last. Fresh spawns remain unassigned unless they inherit a group, and the Unassigned section exists only while it has a member.

Dashboard section labels and within-section directory tiebreaks use the same case-insensitive order. Names that differ only by case are sorted next to each other in a deterministic order. Group identity remains case-sensitive, so `API` and `api` stay separate sections.

Groups belong to task state: an assignment survives client detach and rerun (`r`), and switching grouping modes does not modify it. Press `g` to reassign the selected task through the [group picker](#the-g-group-picker).

Press `m` to toggle the "in use" tag, marked `◆`. In state mode, tagged tasks form the In use section at the top. In custom mode, tagged tasks are placed at the top of their existing groups rather than in a global section. Within a dir or custom section, tasks are sorted as tagged, live, then completed; each class is then sorted by directory and spawn order. Idle state does not affect row order in these modes, so quiet tasks are kept in place and marked `∙`. In state mode, quiet tasks are moved from Running to Idle.
Press `m` to toggle the "in use" tag, marked `◆`. In state mode, tagged tasks form the In use section at the top. In custom mode, tagged tasks are placed at the top of their existing groups rather than in a global section. Within a dir or custom section, tasks are sorted as tagged, live, then completed or stopped; each class is then sorted by directory and spawn order. Idle state does not affect row order in these modes, so quiet tasks are kept in place and marked `∙`. In state mode, quiet tasks are moved from Running to Idle.

Press `M` to select the next tagged task in dashboard order, wrapping after the last. With no tagged tasks, the selection is unchanged; with one, that task is selected.

In custom mode only, a new command is assigned the selected task's group, through both `n` and the `@` picker. The destination is shown in the spawn prompt 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. New tasks are unassigned in state and dir modes. In dir mode, `n` instead opens in the selected task's directory; the `@` picker is unaffected.

#### The flagship

Press `]` to mark the selected task as the flagship, shown as `⚑`; press it again to clear the mark. You can mark only one task at a time. Select another task and press `]` to move the mark. Finished tasks cannot be marked. Sorting is unchanged.
Press `]` to mark the selected task as the flagship, shown as `⚑`; press it again to clear the mark. You can mark only one task at a time. Select another task and press `]` to move the mark. Finished and stopped tasks cannot be marked. Sorting is unchanged.

Press `Ctrl-]` from the dashboard, peek, or an attached task to attach to the flagship, and again to go back:

Expand All @@ -155,7 +156,7 @@ Press `Ctrl-]` from the dashboard, peek, or an attached task to attach to the fl

After attaching to the flagship with `Enter`, press `Ctrl-]` to return to the dashboard.

You keep tags set with `m` after task completion, but lose the flagship mark on completion or removal. Save and load [sessions](sessions.md) to preserve and restore both marks. You can also recover both marks from automatic snapshots. When loading with a current flagship, you keep that mark.
You keep tags set with `m` after task completion, but lose the flagship mark on completion or removal. Save and load [sessions](sessions.md) to preserve and restore both marks. You can also recover both marks from automatic snapshots. When loading with a current flagship, you keep that mark. A stored flagship on a stopped entry is not restored.

#### Renaming

Expand Down Expand Up @@ -229,7 +230,7 @@ Bindings are arranged in two columns. At limited height, group headers are omitt

## Peek

Peek shows the selected task's live screen (the last screenful) in a centered box over the dashboard. Use `↑`/`↓` (or `k`/`j`) to switch tasks, `Enter` to attach, `r` to rerun a finished task, or `Space`, `Esc`, or `q` to close.
Use peek to view the selected task's live screen (the last screenful) in a centered box over the dashboard. Use `↑`/`↓` (or `k`/`j`) to switch tasks, `Enter` to attach, `r` to rerun a finished task or start a stopped one, or `Space`, `Esc`, or `q` to close.

Read the source of the row's dashboard preview in the footer's `preview:` segment: `floor` (the last non-blank row of the live screen), `marker` (a full-screen program with no usable title), `title` (the child's window title), or `anchor/<rule>` (a recognized agent status, tagged with the matcher that produced it). On the alternate screen, any current title is rendered; recognized title formats are normalized first. On the primary screen, only a retained title recognized by the task's agent adapter is rendered. Otherwise, `floor` is used. Most rules name a screen matcher, such as `claude:spinner` or `codex:approval-menu`. The `claude:registry-approval` and `claude:registry-waiting` rules instead come from Claude's on-disk session status.

Expand Down
Loading
Loading