83 lines
4.0 KiB
Markdown
83 lines
4.0 KiB
Markdown
# Maestro
|
|
|
|
A terminal-session orchestrator for one machine. One daemon per host owns every
|
|
interactive shell or agent (Claude Code, opencode, plain bash) running on it;
|
|
clients — CLI, TUI, browser — attach over a plain HTTP + WebSocket API. tmux for
|
|
persistence, WebSocket for transport.
|
|
|
|
## Architecture
|
|
|
|
```
|
|
maestro daemon tmux wrapper + session API on 127.0.0.1:7070
|
|
├── GET/POST /api/sessions list / spawn
|
|
├── DELETE /api/sessions/:id kill
|
|
├── GET /api/info hostname, version, home dir, spawn presets
|
|
├── GET /api/dirs directory listing (spawn autocomplete)
|
|
├── GET /api/recent-dirs spawn history
|
|
├── GET /api/gitroot enclosing repo of a path
|
|
├── WS /api/events Snapshot + session deltas
|
|
└── WS /api/attach/:id raw PTY bytes
|
|
|
|
maestro list/spawn/attach/kill CLI client
|
|
maestro tui ratatui client
|
|
maestro-web serves the SPA, reverse-proxies /api/* to the daemon
|
|
```
|
|
|
|
**No authentication layer, no registry, no peer-to-peer.** Whoever can reach the
|
|
daemon's bind address can drive every session on the host — same trust model as
|
|
tmux itself. The operator picks the perimeter: `127.0.0.1` for local-only, a
|
|
WireGuard/LAN address to share with their own devices, never a public IP.
|
|
|
|
Every config field has a default, so `~/.config/maestro/config.toml` is
|
|
optional.
|
|
|
|
## Where the work is
|
|
|
|
Linear project **Maestro** under team **Naps62**.
|
|
|
|
`.claude/linear.json` wires `/yolo` and `/work` to this project — they pick from
|
|
"available now" (status backlog/pending, not blocked).
|
|
|
|
## Repo layout
|
|
|
|
Cargo workspace. NAP-245 unified the per-binary crates behind a single
|
|
`crates/maestro/` umbrella that ships the `maestro` binary with feature gates
|
|
(`cli` / `daemon` / `tui`, default = all three).
|
|
|
|
```
|
|
crates/
|
|
├── maestro/ # umbrella binary `maestro` (cli + daemon + tui, feature-gated) (NAP-245)
|
|
├── maestro-protocol/ # shared wire types (NAP-211)
|
|
├── maestro-config/ # shared on-disk config schema (NAP-233)
|
|
├── maestro-cli/ # `maestro list/spawn/attach/kill` dispatch (NAP-216)
|
|
├── maestro-daemon/ # `maestro daemon` — tmux wrapper + HTTP/WS API (NAP-212, NAP-214)
|
|
├── maestro-web/ # standalone `maestro-web` browser UI (NAP-241, NAP-249)
|
|
├── maestro-tui/ # `maestro tui` — ratatui session manager (NAP-275 epic)
|
|
├── maestro-installer/ # `maestro-install` wizard: cargo install + systemd (NAP-225)
|
|
└── maestro-e2e/ # cross-process integration tests (NAP-217)
|
|
web/ # browser SPA (NAP-218)
|
|
flake.nix # Nix flake: packages, checks, dev shell, `nix run .#dev`
|
|
nix/ # Home Manager module (`services.maestro`)
|
|
```
|
|
|
|
See `docs/INSTALL.md` for end-user install instructions.
|
|
|
|
`docs/WORKTREES.md` is the contract for session worktrees — placement,
|
|
collisions, what blocks a kill, what `--force` retains, and what reclaim
|
|
touches. Read it before changing anything that creates or removes one.
|
|
|
|
`nix run .#dev` (or `just dev`) brings up the whole local stack under
|
|
process-compose: a debug daemon on 127.0.0.1:7071, then Vite on :5173 once the
|
|
daemon answers `/api/info`. The SPA proxies `/api/*` back to the daemon, so only
|
|
the UI is exposed on the network. The dev port is deliberately not the daemon's
|
|
own default 7070 (`devDaemonPort` in `flake.nix`), so the stack never fights a
|
|
real daemon on the same host.
|
|
|
|
## Conventions
|
|
|
|
- **TDD by default.** Failing test first, then minimal impl. Commit test + impl together.
|
|
- **Frequent commits.** One logical unit per commit; don't pile work up.
|
|
- **Conventional commits with `maestro` scope.** Example: `feat(maestro): add Hello message round-trip test`.
|
|
- **`cargo fmt` + `cargo clippy --all-targets -- -D warnings`** before every commit.
|
|
- **Integration tests use real `tmux` and `git`.** Don't mock them. Isolate via temp `$HOME` and `TMUX_TMPDIR`.
|