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
3 changes: 3 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ Use [conventional commits](https://www.conventionalcommits.org/). Version is aut
## Package Structure
```text
cmd/fleet/main.go # CLI entry point
cmd/fleet/worktree.go # `fleet worktree <branch>` — worktree + session from the shell
internal/tmux/tmux.go # Tmux abstraction (create, kill, capture)
internal/tmux/pty.go # PTY-based attach with Ctrl+Q detach
internal/session/session.go # Session model, status detection, claude --resume
Expand Down Expand Up @@ -86,6 +87,8 @@ chrome-extension/ # Chrome MV3 extension (service worker, manifes
- Tmux session prefix: `fleet_` (agent sessions); drawer shells use a distinct `fleetsh_` prefix — intentionally not a prefix of `fleet_`, so shells never leak into agent-session enumeration (`tmux.ListSessions`)
- Session ID format: `<8hex>-<unix_timestamp>`
- SQLite DB: `~/.config/fleet/state.db`
- `fleet worktree <branch>` (alias `wt`, `cmd/fleet/worktree.go`): the TUI's `w` key as a CLI command — create the worktree, copy `.claude/settings.local.json` + `copy_files` entries, start a session. Flags: `--base` (defaults to `git.GetDefaultBranch`), `--path` (defaults to cwd), `--agent` (defaults to `default_agent`; **validated explicitly** — `agent.Parse` falls back to Claude for anything unrecognized, so a typo would silently launch the wrong agent), `--no-session` (print only the worktree path, so `cd "$(fleet worktree foo --no-session)"` composes; conflicts with `--agent`). Flags parse on **either side** of the branch (a loop peeling one positional per `fs.Parse` — a single Parse stops at the first positional and would reject `fleet worktree foo --no-session`). It resolves to the **main** worktree (`git.GetMainWorktreePath`) before creating, so running it from inside `repo-foo` yields `repo-bar`, not `repo-foo-bar` — same as pressing `w` on an origin header. It calls `debuglog.Init()` first: `debuglog.Logger`'s fallback writes to **stderr**, and the provider/`Session.Start` log at Info, so without it the command spews slog lines over the user's terminal (`fleet add` still does).
- External-session adoption: the TUI reads sessions from SQLite exactly **once**, at startup (`loadSessions`), so a session created by another fleet process would be invisible until restart. `maybeAdoptExternalSessions` (heavy worker pass, self-throttled to `adoptSweepInterval`=5s) diffs the table against the cycle's snapshot via the pure `unknownSessions` and sends `adoptSessionsMsg`; `handleAdoptSessions` re-checks `sessionByID` (the snapshot is taken at cycle start, so the Update goroutine is the only authoritative dedupe point) then mirrors `handleSessionCreateResult` minus `SaveSession`/analytics. **Adoption only** — rows deleted elsewhere are never dropped. Unlike a session the user just created, an adopted row arrives on a timer, so the cursor must not move: it's captured with `targetForCursor()` and restored by identity via `target.find` after the rebuild. No resurrection risk — `deferDelete` deletes the SQLite row immediately, ahead of the 5s undo window.
- Sessions grouped by git repo root in sidebar with tree lines (├─/└─)
- Status: Running, Waiting, Finished, Idle, Error, Starting, Suspended
- Status icons: ● (running/finished), ◐ (waiting), ○ (idle/starting), ✕ (error), · dim (suspended — same dot as idle; dim style + "suspended" label distinguish it)
Expand Down
5 changes: 5 additions & 0 deletions changelog/unreleased/adopt-external-sessions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
type: improved
---

**No restart needed.** A session created from another terminal — `fleet worktree`, `fleet add` — now shows up in a running fleet within ~5 seconds, instead of waiting until the next launch.
5 changes: 5 additions & 0 deletions changelog/unreleased/worktree-from-cli.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
type: added
---

**Worktrees from your shell.** `fleet worktree <branch>` creates the worktree and starts a session in it without opening the TUI — `--base`, `--path` and `--agent` to steer it, `--no-session` to print just the path for `cd "$(fleet worktree foo --no-session)"`.
4 changes: 4 additions & 0 deletions cmd/fleet/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ func main() {
os.Exit(1)
}
runRemove(args[1])
case "worktree", "wt":
runWorktree(args[1:])
case "hook-handler":
handleHookHandler()
case "chrome-host":
Expand Down Expand Up @@ -348,6 +350,8 @@ Usage:
fleet add <path> Add a new session
fleet list List all sessions
fleet remove <id> Remove a session
fleet worktree <branch> Create a git worktree and start a session in it
(--base, --path, --agent, --no-session)
fleet hooks <install|uninstall|status> Manage Claude Code hooks
fleet update Update to latest version
fleet version Show version
Expand Down
Loading
Loading