fleet-agents 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,143 +1,102 @@
1
1
  # fleet-agents
2
2
 
3
3
  Run many [Claude Code](https://claude.com/claude-code) agents in parallel — each in its own
4
- isolated **git worktree** with its own task — and orchestrate them from one place, including
5
- from *inside* a Claude session via a `/fleet` slash command.
4
+ git worktree — and drive them all from one Claude session with a `/fleet` slash command.
5
+ You describe the work in plain English; fleet picks the right approach and runs it.
6
6
 
7
- - **macOS / Linux / WSL** → agents run as panes in one **tmux** session you can attach/detach.
8
- - **Windows** → each agent opens in its own terminal window (no tmux needed).
9
-
10
- ## Concepts (the mental model)
11
-
12
- | Term | What it is |
13
- |------|-----------|
14
- | **session** | One tmux session — the container. Survives detach/reboot (state is saved). |
15
- | **manager** | The orchestrator Claude in pane 0 of a session. You type `/fleet …` into it. |
16
- | **worker** | An agent in its own pane + git **worktree** (isolated branch), working one task. |
17
- | **sub-worker** | A worker a worker spawned — fleet tracks the chain so you can resume/remove it as a unit. |
18
- | **skill** | A named prompt template prepended to a task (`research`, `review`, `fix`, or your own). |
19
- | **mode** | How a worker runs: **once** (one-shot), **loop** (recurring), **goal** (until a condition holds). |
7
+ - **macOS / Linux / WSL** → agents are panes in one tmux session you can attach/detach.
8
+ - **Windows** → each agent opens in its own terminal window.
20
9
 
21
10
  ## Install
22
11
 
23
12
  ```bash
24
- npm install -g git+https://github.com/sanil-23/fleet-agents.git # (or 'fleet-agents' once on npm)
25
- fleet install-claude # adds the /fleet slash command to ~/.claude/commands
26
- fleet doctor # check prerequisites
13
+ npm install -g fleet-agents
14
+ fleet install-claude # adds the /fleet command to Claude Code
27
15
  ```
28
16
 
29
- **Requires:** Node ≥ 16, `git`, the `claude` CLI on PATH. `tmux` on macOS/Linux (Windows uses
30
- separate windows). `fleet pr …` review commands also need `gh` + `jq`.
17
+ Needs Node ≥ 16, `git`, the `claude` CLI, and `tmux` (macOS/Linux). Run `fleet doctor` to check.
31
18
 
32
19
  ## Quickstart
33
20
 
21
+ **1. Start a manager** — a tmux session with an orchestrator Claude in it:
22
+
34
23
  ```bash
35
- cd ~/code/myapp # any git repo
36
- fleet manager # opens a manager Claude here, in a tmux session
37
- fleet attach # (in your terminal) hop into the session
24
+ fleet manager --name xyz # rooted in the current repo (or: fleet manager --name xyz ~/code/app)
25
+ fleet attach --name xyz # hop into the session
38
26
  ```
39
- Then, **inside the manager**, just describe work:
27
+
28
+ **2. Inside that Claude, just describe the work:**
29
+
40
30
  ```
41
31
  /fleet fix the CSV parser crash and add a test
42
- /fleet research why the dashboard query is slow
43
- /fleet food-llm: tune the context window; api: add retry to the upload call
32
+ /fleet why is the dashboard query slow?
33
+ /fleet keep watching the deploy and ping me when it's green
44
34
  ```
45
- Each becomes a worker in its own pane + worktree. Detach with `Ctrl-b d` (agents keep
46
- running); come back any time with `fleet attach`, or after a reboot with `fleet resume`.
47
35
 
48
- ## Using it from inside Claude`/fleet`
36
+ That's the whole loop. For each prompt, fleet spins up a **worker** its own pane, its own
37
+ git worktree (isolated branch) — and sets it going. Detach with `Ctrl-b d` (agents keep
38
+ running); come back with `fleet attach --name xyz`, or after a reboot `fleet resume xyz`.
49
39
 
50
- `/fleet <prompt>` runs a **dispatch decision**: the manager picks the repo, **selects a skill**
51
- (or none), **picks a mode** (once / loop / goal), and launches the worker — then tells you what
52
- it chose. You can also be explicit:
40
+ ## How `/fleet` decides skills & modes are auto-picked
53
41
 
54
- ```
55
- /fleet <prompt> # manager auto-picks skill + mode
56
- /fleet research <thing> # force the read-only research skill
57
- /fleet keep checking the deploy … # → loop mode (recurring)
58
- /fleet rm self # (inside a worker) remove me + my sub-workers
59
- /fleet ls /fleet status /fleet sessions
60
- ```
42
+ When you type `/fleet "<prompt>"`, the manager makes four choices for you, then launches one
43
+ worker:
61
44
 
62
- ## Command reference
45
+ 1. **Repo** — the current repo by default (or whichever you name).
46
+ 2. **Skill** — a prompt template that shapes *how* the agent works. It picks the best fit, or none:
63
47
 
64
- ### Sessions
65
- ```bash
66
- fleet manager [dir] [--name X] [--window] # open a manager (rooted at dir; default cwd)
67
- # --window: new window in the CURRENT tmux session
68
- fleet attach [--name X] # attach to a session
69
- fleet status [session] # one-glance: manager + worker tree, live/saved
70
- fleet sessions # list all sessions
71
- fleet resume [session] [--dry-run] # rebuild a session — manager + workers, conversations continued
72
- fleet kill [--name X] # stop a session's tmux (keeps worktrees + state → resumable)
73
- ```
74
- `--name` lets you run several independent managers (`billing`, `infra`, …) at once. Bare
75
- `fleet resume` picks the most recently-active manager.
48
+ | Skill | Auto-picked when your prompt is… |
49
+ |-------|----------------------------------|
50
+ | `research` | investigate / debug / "why" / "how does" / trace — **read-only**, produces findings, no code changes |
51
+ | `review` | "review these changes" CodeRabbit-style review with concrete fixes |
52
+ | `fix` | "review and fix" applies fixes, runs the repo's checks, commits |
53
+ | *(your own)* | matches a skill you registered (`fleet skill add …`) |
54
+ | *(none)* | a normal implement/fix task |
76
55
 
77
- ### Launch work
78
- ```bash
79
- fleet add <repo> <task> "<prompt>|<file.md>" [base] [--skill NAME] [--no-worktree]
80
- fleet research <repo> <task> "<issue|file.md>" [base] # = --skill research (read-only)
81
- ```
82
- `<repo>` can be a name (resolved under `PROJECTS_ROOT`), a path, or `.` for the current repo.
83
- The prompt can be inline text **or a `.md` file path** (its contents become the task).
84
- `--no-worktree` runs the worker in the repo itself (no branch) — handy for read-only research.
56
+ 3. **Mode** — *how it runs*:
85
57
 
86
- ### Skills
87
- ```bash
88
- fleet skill ls
89
- fleet skill add <name> <file.md> # register your own
90
- fleet skill show <name> fleet skill rm <name>
91
- ```
92
- Built-ins: **research** (investigate, read-only), **review** (CodeRabbit-style review),
93
- **fix** (review + apply + verify + commit). Apply any with `--skill <name>`.
58
+ | Mode | Auto-picked when… |
59
+ |------|-------------------|
60
+ | **once** | one-shot task (the default) |
61
+ | **loop** | recurring / monitoring "every 5 min", "keep checking", "babysit the PR", "until CI is green" |
62
+ | **goal** | drive to an end-state — "keep going until X is done"; runs until that condition holds |
94
63
 
95
- ### Clean up
96
- ```bash
97
- fleet rm <repo> <task> [--branch] [--dry-run] # remove a worker + every sub-worker it spawned
98
- fleet rm --self [--branch] # (inside a worker) remove itself + its chain
99
- fleet sessions rm <session> [--branch] [--dry-run] # remove a session + ALL its child sessions
100
- fleet prune [session] [--dry-run] # drop recorded tasks whose worktree is gone
101
- ```
102
- `kill` is reversible (keeps work for `resume`); `rm` / `sessions rm` are destructive — use
103
- `--dry-run` to preview, `--branch` to also delete branches.
64
+ 4. **Launch** — creates the worktree and starts the worker with that skill + mode.
104
65
 
105
- ### PR review (`git` + `gh` + `jq`; open a pane, `--here` for foreground)
106
- ```bash
107
- fleet pr sync <pr> # checkout PR as pr/<num>, merge base, wire push
108
- fleet pr review <pr> [extra] # CodeRabbit-style review agent
109
- fleet pr fix <pr> [extra] # review-and-fix agent (commit & push)
110
- fleet pr coverage <pr> [extra] # fix the coverage gate
111
- fleet pr merge <pr> [--squash|--merge|--rebase] [--dry-run] [--summary-llm <tool>]
66
+ The manager tells you what it chose. Want to force a choice? Just name it:
67
+
68
+ ```
69
+ /fleet research <thing> # force the read-only research skill
70
+ /fleet review the auth changes # force the review skill
112
71
  ```
113
- Run inside the target repo or pass `-C <repo-dir>`. `pr merge` defaults to `--squash` and
114
- summarizes the body with `gemini` (use `--summary-llm none|claude` if you don't have it).
115
- (The old top-level `fleet review/fix/…` still work but print a deprecation hint.)
116
72
 
117
- ### Setup / health
73
+ (See the built-in + your skills with `fleet skill ls`.)
74
+
75
+ ## Commands you'll actually use
76
+
118
77
  ```bash
119
- fleet install-claude # (re)install the /fleet command
120
- fleet doctor # check tmux/gh/jq/claude/caffeinate + whether /fleet is installed
121
- fleet help
78
+ fleet manager --name xyz [dir] # start/open a manager
79
+ fleet attach --name xyz # jump into it
80
+ fleet status [xyz] # what's running: manager + worker tree
81
+ fleet resume [xyz] # rebuild after a reboot (agents continue where they left off)
82
+ fleet kill --name xyz # stop the session (keeps the work; resumable)
122
83
  ```
123
84
 
124
- ## Configuration (env vars)
125
-
126
- | Var | Default | Purpose |
127
- |-----|---------|---------|
128
- | `FLEET_BACKEND` | auto (`tmux` if available, else `windows`) | Force the spawner backend |
129
- | `FLEET_MODE` | `pane` | `window` = a tmux window per worker instead of a tiled pane |
130
- | `PROJECTS_ROOT` | `~/Projects` | Where bare repo names resolve |
131
- | `WT_ROOT` | `$PROJECTS_ROOT/.worktrees` | Where worktrees are created |
132
- | `FLEET_SESSION` | `fleet` | Default session name |
133
- | `FLEET_STATE_DIR` | `~/.fleet` | Where per-session state is stored |
134
- | `FLEET_SKILLS_DIR` | `~/.fleet/skills` | Where your custom skills live |
135
- | `FLEET_CLAUDE_FLAGS` | `--dangerously-skip-permissions` | Flags for each launched `claude` (set `""` to restore prompts) |
136
- | `FLEET_NO_CAFFEINATE` | unset | macOS: `1` to skip the auto keep-awake while a session is alive |
137
-
138
- > **Safety:** the default flags let agents run unattended (no permission prompts). Each worker
139
- > is isolated in a throwaway worktree, but they share your real filesystem and credentials —
140
- > only fan out tasks you'd trust to run on their own.
85
+ From inside Claude you can also say `/fleet ls`, `/fleet status`, or `/fleet rm <repo> <task>`
86
+ (removes a worker and anything it spawned). `/fleet rm self` removes the current pane and its
87
+ chain from a worker, that worker + its sub-workers; **from the manager, the whole session**
88
+ (manager + all its workers).
89
+
90
+ Everything else manual `fleet add`, custom skills, the `fleet pr` review/fix/merge toolkit
91
+ is in **`fleet help`**.
92
+
93
+ ## Good to know
94
+
95
+ - Agents run with `--dangerously-skip-permissions` so they work unattended. Each is isolated
96
+ in a throwaway worktree, but they share your real filesystem and credentials only fan out
97
+ work you'd trust to run on its own. (Set `FLEET_CLAUDE_FLAGS=""` to restore prompts.)
98
+ - On macOS, fleet keeps the Mac awake while a session is alive so sleep doesn't kill agents.
99
+ - Run several managers at once with different `--name`s (one per project/effort).
141
100
 
142
101
  ## License
143
102
 
package/bin/fleet.js CHANGED
@@ -493,11 +493,13 @@ function sessionChildrenMap() {
493
493
  }
494
494
 
495
495
  function removeOneSession(name, delBranch) {
496
- if (BACKEND === 'tmux') { try { execFileSync('tmux', ['kill-session', '-t', name], { stdio: 'ignore' }); } catch {} }
496
+ // Clean up worktrees + state BEFORE killing the tmux session if a manager removes its own
497
+ // session, killing it terminates this process, so cleanup must already be done.
497
498
  const s = loadState(name);
498
499
  for (const t of s.tasks) removeWorktreeByPath(t.wt, t.task, delBranch);
499
500
  try { fs.unlinkSync(statePath(name)); } catch {}
500
- console.log(` removed session '${name}' — killed + ${s.tasks.length} worktree(s)${delBranch ? ' + branches' : ''}`);
501
+ console.log(` removed session '${name}' — ${s.tasks.length} worktree(s)${delBranch ? ' + branches' : ''}, session killed`);
502
+ if (BACKEND === 'tmux') { try { execFileSync('tmux', ['kill-session', '-t', name], { stdio: 'ignore' }); } catch {} }
501
503
  }
502
504
 
503
505
  // Remove a session by name AND every child/sub-child session it spawned.
@@ -746,15 +748,25 @@ function cmdRm(args) {
746
748
  if (self) {
747
749
  const id = process.env.FLEET_TASK;
748
750
  if (id && id.includes('/')) {
751
+ // Inside a worker → remove this worker + every sub-worker it spawned.
749
752
  reponame = id.slice(0, id.indexOf('/'));
750
753
  task = id.slice(id.indexOf('/') + 1);
754
+ } else if (process.env.FLEET_SESSION) {
755
+ // No worker identity → we're the manager (pane 0). "self" = the whole session it runs:
756
+ // the manager + every worker it generated (and any child sessions).
757
+ const sess = process.env.FLEET_SESSION;
758
+ console.log(`fleet: 'self' from the manager → removing session '${sess}' (manager + all its workers)`);
759
+ const pass = [sess];
760
+ if (delBranch) pass.push('--branch');
761
+ if (dry) pass.push('--dry-run');
762
+ cmdRemoveSession(pass);
763
+ return;
751
764
  } else if (process.env.TMUX_PANE) {
752
- // No task identity, but we can still self-destruct the current pane.
753
765
  try { tmux(['kill-pane', '-t', process.env.TMUX_PANE]); } catch {}
754
- console.log('fleet: closed current worker pane (no FLEET_TASK — chain not resolved)');
766
+ console.log('fleet: closed current pane (no FLEET_TASK/FLEET_SESSION — chain not resolved)');
755
767
  return;
756
768
  } else {
757
- die('--self requires being inside a fleet worker (FLEET_TASK / TMUX_PANE unset)');
769
+ die('--self requires being inside a fleet session');
758
770
  }
759
771
  } else {
760
772
  const pos = args.filter((a) => !a.startsWith('-'));
@@ -885,7 +897,8 @@ SKILLS (named prompt templates the worker is seeded with)
885
897
 
886
898
  CLEAN UP
887
899
  fleet rm <repo> <task> [--branch] [--dry-run] remove a worker + every sub-worker it spawned
888
- fleet rm --self [--branch] (inside a worker) remove itself + its chain
900
+ fleet rm --self [--branch] remove self + chain — worker: it + sub-workers;
901
+ manager: the whole session (manager + all workers)
889
902
  fleet sessions rm <session> [--branch] [--dry-run] remove a session + ALL child sessions
890
903
  fleet prune [session] [--dry-run] drop recorded tasks whose worktree is gone
891
904
 
package/commands/fleet.md CHANGED
@@ -16,9 +16,11 @@ User input: `$ARGUMENTS`
16
16
  - `rm`/`remove`/`done <repo> <task>` → `fleet rm <repo> <task> --branch`. This removes that
17
17
  worker **and every sub-worker it spawned** (the chain): closes their panes, removes their
18
18
  worktrees, deletes branches.
19
- - `rm self` / `remove self` / "remove this worker" / "remove me" (no repo/task) → run
20
- `fleet rm --self --branch`. From inside a worker this removes that worker + its sub-worker
21
- chain (it reads the pane's FLEET_TASK). Only valid inside a worker pane.
19
+ - `rm self` / `remove self` / "remove this worker" / "kill me and my workers" (no repo/task)
20
+ → run `fleet rm --self --branch`. Scope depends on where it runs:
21
+ - from a **worker** removes that worker + every sub-worker it spawned (its chain).
22
+ - from the **manager** → removes the WHOLE session: the manager + all its workers + their
23
+ worktrees. (So killing the manager takes the full chain down with it.)
22
24
  - `kill`/`teardown` → `fleet kill`.
23
25
  - `resume …` → `fleet resume …`.
24
26
  - Anything else → it's one or more **task launches**. For each, run the **Dispatch decision**.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fleet-agents",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Run multiple Claude Code agents in parallel, each in its own git worktree — tmux on macOS/Linux/WSL, separate terminal windows on Windows.",
5
5
  "bin": {
6
6
  "fleet": "bin/fleet.js"