Ships `maestro`, `maestro-web` and the SPA bundle as flake packages, plus a `services.maestro` Home Manager module that runs the daemon and the web UI as systemd user services. `maestro-web`'s build.rs now honours MAESTRO_WEB_DIST and hands the resolved bundle path to `include_dir!` through MAESTRO_WEB_BUNDLE_DIR. Without it the Nix build would have to run `pnpm install` mid-compile, which the sandbox has no network for. Unset, the pnpm path is unchanged. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
3.6 KiB
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-names/ # orchestra-themed session-handle generator (#23)
├── 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: `maestro`, `maestro-web`, `webFrontend`
nix/ # Home Manager module (`services.maestro`)
See docs/INSTALL.md for end-user install instructions.
The dated design docs under docs/superpowers/specs/ predate the single-host
refactor; they carry banners marking what no longer applies.
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
maestroscope. Example:feat(maestro): add Hello message round-trip test. cargo fmt+cargo clippy --all-targets -- -D warningsbefore every commit.- Integration tests use real
tmuxandgit. Don't mock them. Isolate via temp$HOMEandTMUX_TMPDIR.