Skip to content

Latest commit

 

History

History
117 lines (86 loc) · 6.2 KB

File metadata and controls

117 lines (86 loc) · 6.2 KB

Development Setup

Roost has two active development surfaces:

  1. The Rust workspace at crates/ (roost-ipc, roost-vt, roost-osc, roost-cli, roost-linux, roost-iced).
  2. The Swift package at mac/ (the macOS UI, Roost.app).

Both link the same vendored libghostty-vt static archive built from third_party/ghostty/.

Prerequisites

Tool Use
mise Provisions Rust 1.97.1 + Zig 0.15.x at the pinned versions
Xcode Command Line Tools Builds the Mac UI (SwiftPM)
GTK4 + libadwaita dev packages Builds the Linux UI (Linux + macOS dev)
uv Builds the documentation site

See Installation for the per-platform package commands.

Initial build

git clone https://github.com/charliek/roost.git
cd roost
mise install                           # Rust + Zig
./third_party/ghostty/build.sh         # libghostty-vt — only needs Zig
~/.cargo/bin/cargo build --workspace   # all Rust crates
./mac/scripts/bundle.sh debug          # macOS .app bundle

third_party/ghostty/build.sh is the only step that needs Zig. After it finishes, normal Rust + Swift workflows work without invoking Zig again.

Iteration

Goal Command
Run the Linux UI (iced, what the package ships) ~/.cargo/bin/cargo run -p roost-iced
Run the Linux UI (GTK, in-repo dev/parity) ~/.cargo/bin/cargo run -p roost-linux
Run the Mac UI ./mac/scripts/bundle.sh debug && open mac/build/Roost.app
Smoke-test the CLI ~/.cargo/bin/cargo run -p roost-cli -- identify
Rust unit tests ~/.cargo/bin/cargo test --workspace --exclude roost-linux
Linux UI tests (GTK) ~/.cargo/bin/cargo test -p roost-linux (needs GTK)
Linux UI tests (iced) ~/.cargo/bin/cargo test -p roost-iced
Mac unit tests cd mac && swift test
Rust formatting ~/.cargo/bin/cargo fmt --all
Rust lint ~/.cargo/bin/cargo clippy --workspace --all-targets
Build the docs site make docs (or make docs-serve for live-reload at http://127.0.0.1:7070)

The IPC sockets live at:

OS Swift/AppKit GTK Iced (dev build)
macOS ~/Library/Caches/Roost/roost.sock ~/Library/Caches/Roost-gtk/roost.sock ~/Library/Caches/Roost-iced/roost.sock
Linux n/a $XDG_RUNTIME_DIR/roost/roost.sock $XDG_RUNTIME_DIR/roost-iced/roost.sock

Without XDG_RUNTIME_DIR, Linux falls back to /tmp/roost-<uid> for GTK and /tmp/roost-iced-<uid> for Iced. State, lock, and log paths use the same profile separation. Select a live UI with roostctl --target mac|gtk|iced.

Each UI writes a log file and tees to stdout. Iced uses ~/Library/Logs/Roost-iced/roost.log on macOS and $XDG_STATE_HOME/roost-iced/roost.log on Linux; its socket, lock, state, and log paths are distinct from Swift and GTK. roostctl --help and docs/reference/ipc.md document the wire surface.

Tests

Rust tests live next to the code they exercise. Major coverage:

Crate What's covered
roost-ipc Frame reader/writer, JSON wire vectors, target selection (probe alive + env precedence)
roost-osc OSC 9 / 777 streaming parser, ST terminator, hook suppression
roost-vt FFI smoke tests against the vendored libghostty-vt archive (gated on --features ffi)
roost-engine Workspace, PTY supervision, persistence, events, IPC dispatch, instance lock
roost-ui-model Config, theme, keybind, palette, provider, and agent projection models
roost-linux GTK presentation, native ports, input, and terminal rendering adapter — in-repo dev/parity UI
roost-iced iced presentation, native ports, input, and terminal rendering adapter — what the Linux package ships
roost-cli Escape decoder, shell quoter, target arg mapping

Mac tests are under mac/Tests/RoostTests/; they cover the workspace state machine, PTY supervisor lifecycle, IPC server framing, single-instance flock, renderer, OSC scanner, key encoder, drag/drop math, and tab pill state machine. They run in headless swift test (no NSWindow required for any covered surface).

Documentation site

Markdown sources live in docs/. Zensical builds them through uv:

make docs                # static site under site-build/ (`zensical build --strict`)
make docs-serve          # live-reload server at http://127.0.0.1:7070

uv sync --locked --group docs runs automatically; no global Python install needed beyond the uv binary. zensical serve --strict is unsupported — verify with make docs.

The voice for new docs is set in zensical.toml: professional + direct (no marketing), tables for option lists, code blocks with language hints, admonitions only for important notes/warnings, copy-pasteable examples, one topic per page.

Bumping the pinned Ghostty SHA

libghostty-vt's API is documented as unstable. Bumps land in their own commit:

  1. Edit third_party/ghostty/build.sh — update GHOSTTY_SHA.
  2. ./third_party/ghostty/build.sh --force to rebuild from the new SHA.
  3. Fix any FFI breakage in crates/roost-vt. The C symbols are listed in src/lib_vt.zig of the Ghostty source.
  4. Re-run cargo test --workspace and swift test from mac/.
  5. Commit with the SHA + date in the message.

If the bump also moves past Zig 0.15.x, drop the maybe_arm64_sdk_shim helper in third_party/ghostty/build.sh — it exists only because Zig 0.15.x links host artifacts as arm64-macos, which Apple's macOS 26+ SDK no longer exposes.

Code conventions

The full set is in CLAUDE.md at the repo root. Highlights:

  • Concrete types until duplication forces an interface — no premature Manager / Coordinator abstractions.
  • Errors are returned, not logged-and-swallowed. Log at the boundary that handles them.
  • Default to no comments. Add one when the why is non-obvious (a hidden constraint, a workaround, a tricky invariant).
  • UI calls happen on the main thread; background work marshals via glib::idle_add (Linux) or DispatchQueue.main / @MainActor (macOS).
  • The JSON IPC schema is the durable boundary — change crates/roost-ipc/src/messages.rs, update vectors under tests/ipc-vectors/, and bump the Swift mirror in mac/Sources/Roost/IPCMessages.swift in the same commit.