Commit Graph
663 Commits
Author SHA1 Message Date
naps62-yolo 2b84783968 fix(maestro): drop stale wait_for_async import in attach test too
ci / rust (push) Has been cancelled
2026-05-24 16:17:28 +00:00
naps62-yolo fb2a0b1e6a fix(maestro): drop stale wait_for_async import in session_manager test
ci / rust (push) Failing after 1m14s
2026-05-24 16:10:18 +00:00
naps62-yolo 0624ad1257 style(maestro): apply cargo fmt
ci / rust (push) Failing after 1m15s
2026-05-24 15:53:35 +00:00
naps62-yolo f64d9312ee ci(maestro): drop container, install rustup + tmux on default image
ci / rust (push) Failing after 27s
`rust:1.83-bookworm` has no Node, which breaks `actions/checkout@v4`
(it's a JS action). The default gitea runner image has Node, so go back
to that and install rustup + tmux + git + build-essential ourselves.
2026-05-24 15:37:33 +00:00
naps62-yolo 22d079145f ci(maestro): fix runner image + trigger on linear/** branches
ci / rust (push) Failing after 26s
CI has been red since NAP-211 because docker.gitea.com/runner-images:
ubuntu-latest has no `rustup`; the toolchain install step exits 127.

- Use `rust:1.83-bookworm` as the job container so rustup + cargo + a
  stable toolchain are pre-installed
- Install `tmux` + `git` so the daemon integration tests can run
- Add `rustfmt` and `clippy` components
- Also trigger on pushes to `linear/**` so yolo branches see CI before
  they're merged
2026-05-24 15:24:44 +00:00
naps62-yolo ab9a5bf017 feat(maestro): wire daemon to registry + per-session WS stream
Completes the headless daemon stack for NAP-214.

- `config`: daemon TOML config (daemon_id, registry_url, bind_addr,
  token, state_dir, worktree_root) with sensible XDG defaults.
- `jwt`: HS256 verifier; the daemon validates per-attach JWTs locally
  with no callback to the registry. Also exposes `issue()` for tests.
- `pty::PtyBridge`: per-session FIFO + tokio broadcast pump. The FIFO is
  opened r+w so it never sees zero writers — stays alive across
  `pipe-pane` re-issues. Helper `pipe_pane_command()` builds the
  `cat >> <fifo>` shell line.
- `session::SessionManager`: authoritative live-session store. Creates
  worktrees (when requested), spawns tmux, mkfifo + pipe-pane, writes
  sidecar; tears it all down on kill. Emits diff events on a
  broadcast for the registry client. `recover()` adopts surviving
  `maestro-*` tmux sessions on startup and re-pipes them.
- `registry_client::RegistryClient`: persistent outbound WS to the
  registry with exponential backoff. Sends Hello → snapshot, drives a
  select loop that pumps inbound CreateSession/KillSession RPCs into
  the manager (replying with results), emits SessionAdded/Removed/
  Updated diffs from the manager, and heartbeats every 10s.
- `attach`: axum router mounting `WS /sessions/:id/stream?token=<jwt>`.
  Binary frames carry PTY bytes either way (subscribe to broadcast →
  send to client; receive from client → tmux send-keys -l). Text
  frames carry `ClientControl::{Resize,Ping,Pong}`.
- `bin/maestrod`: ties everything together, loads config from
  `MAESTROD_CONFIG` env or `~/.config/maestrod/config.toml`,
  recovers, spawns the registry client, binds the WS server.

Also adds `JwtClaims` to `maestro-protocol` so the daemon and the
future registry JWT issuer (NAP-215) agree on the wire shape.

Integration tests cover session manager round-trip + recovery + PTY
broadcast; attach endpoint JWT (bad/wrong-session/wrong-daemon),
PTY round-trip through real tmux, multi-attach broadcast, ping/pong;
registry client registration + snapshot + diff forwarding +
CreateSession RPC round-trip.

Closes NAP-214.
2026-05-24 15:22:36 +00:00
naps62-yolo c721b5ec62 feat(maestro): add registry daemon-side WS handler and state
ci / rust (push) Failing after 6s
Registry-side primitives for the daemon↔registry conversation. No
client-facing HTTP yet (that's NAP-215).

- `state::Registry`: in-memory store of connected daemons + a session
  catalog keyed by (daemon_id, session_id). Tracks pending CreateSession
  / KillSession RPCs so a single daemon connection can multiplex them.
- `handler::handle_socket`: per-connection loop that authenticates the
  Hello, applies snapshot/diff/heartbeat frames, and resolves matching
  *Result frames. Heartbeat watchdog is a `tokio::time::timeout` around
  the read side — no separate janitor task.
- `server::router_with_timeout`: axum router mounting `WS /daemon`. The
  timeout knob lets tests verify the 30s drop path in milliseconds.
- `token::ensure_token`: first-run bootstrap that generates a 256-bit
  hex token, prints it once to stderr, and persists it to
  `~/.config/maestro/registry.toml`.
- Outbound `create_session` / `kill_session` exposed as the internal
  API NAP-215's HTTP handlers will call.

Integration tests use a real axum server bound to `:0` and drive it via
`tokio-tungstenite`, covering: bad-token reject, snapshot accept, diff
apply (add/update/remove), heartbeat timeout dropping the daemon,
re-registration replacing the catalog, and a full CreateSession RPC
round-trip.

Closes NAP-213.
2026-05-24 13:42:00 +00:00
naps62-yolo 946aa384a0 feat(maestro): add daemon tmux/sidecar/worktree primitives
ci / rust (push) Failing after 3s
Local primitives for `maestrod`, no network code yet:

- `tmux`: subprocess wrapper around new-session, kill-session,
  list-sessions (filtered to maestro-*), send-keys -l, pipe-pane -o,
  resize-window, kill-server.
- `sidecar`: atomic JSON metadata store keyed by session UUID, with
  load_all for daemon restart recovery.
- `worktree`: `git worktree add -b` with collision-proof generated paths
  and `git worktree remove --force` for cleanup_on_kill.

Integration tests use real tmux (isolated via unique socket + temp
TMUX_TMPDIR) and real git (tmpdir repo).

Closes NAP-212.
2026-05-24 13:02:41 +00:00
naps62-yoloandClaude Opus 4.7 777d246aab feat(maestro): add maestro-protocol crate with wire types
ci / rust (push) Failing after 25s
Introduces the maestro-protocol crate (NAP-211): the shared serde
types that the daemon, registry, and clients all serialize across
WebSocket boundaries. Covers:

  - Session, SessionStatus
  - CreateSessionRequest with optional WorktreeSpec
  - RpcResult<T> reply envelope
  - DaemonOutbound (Hello, snapshot, add/remove/update,
    Heartbeat, request results)
  - DaemonInbound (Ack, Error, CreateSession, KillSession)
  - ClientControl text frames (Resize, Ping, Pong, Error)

Schema mirrors the wire-protocol tables in the design spec. Unit
tests round-trip every variant and assert tag/discriminator
stability so future renames break loudly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 12:35:16 +00:00
naps62-yoloandClaude Opus 4.7 de8db03a18 chore(maestro): scaffold cargo workspace and CI
Adds the empty Cargo workspace (resolver = 2, members = crates/*),
a stable rust-toolchain pin with rustfmt + clippy, and a Gitea
Actions pipeline that runs cargo fmt --check, clippy -D warnings,
and cargo test on every push/PR.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 12:35:08 +00:00
naps62-yoloandClaude Opus 4.7 dc963a27f7 docs(maestro): add repo-level CLAUDE.md
Orients future sessions and Linear-driven skills: points at the spec,
the Linear project, the dependency chain (NAP-211 is the starting
point), the target workspace layout, and conventions (TDD, conventional
commits with maestro scope, real tmux+git in integration tests, no
mocking).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 12:05:27 +00:00
naps62-yoloandClaude Opus 4.7 810a4fbc28 docs(maestro): make network layer agnostic in spec
Removes Tailscale assumptions from the design. Operator configures bind
addresses and is responsible for reachability + perimeter (Wireguard,
private LAN, or any other mechanism); maestro does not police the network
or terminate TLS itself.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 11:52:17 +00:00
naps62-yoloandClaude Opus 4.7 7af764c1a3 chore(maestro): initial scaffold and brainstorm spec
Adds .claude/linear.json for Linear-driven skills (Maestro project on
team Naps62) and the brainstorm design doc covering architecture, wire
protocol, session model, auth, and prototype scope boundary.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 11:51:03 +00:00