README.md
signaltty — native Linux workspace for parallel AI coding agents
A terminal multiplexer designed for agent-driven development: a persistent session server owns PTYs and state; a CLI and a native GTK4/libadwaita GUI attach as pure clients. Closing the UI never kills running agents.
Status: Phase 4 (extensibility) implemented and tested. All MVP phases (multiplexer core, agent awareness, native GUI, executable plugins) are done.
Quick start
| 1 | cargo build --workspace |
| 2 | ./target/debug/signaltty daemon # start the session server |
| 3 | ./target/debug/signaltty integration install claude # optional: agents typed inside a shell |
| 4 | ./target/debug/signaltty new --cwd ~/code/project -- codex |
| 5 | ./target/debug/signaltty new --cwd ~/code/project -- claude |
| 6 | ./target/debug/signaltty pane read <pane-id> |
| 7 | ./target/debug/signaltty pane attach <pane-id> # Ctrl+] to detach |
| 8 | ./target/debug/signaltty wait --pane <id> --until done |
| 9 | ./target/debug/signaltty pane resume <pane-id> # after restart, via native resume |
Note: codex trusts new hooks interactively ("Trust all and continue"
once per hook command); codex exec needs
--dangerously-bypass-hook-trust to fire untrusted hooks.
Global flags: --socket <path> (default
$XDG_RUNTIME_DIR/signaltty/signaltty.sock), --json (machine-readable
result object; resource-creating commands return opaque ids).
Architecture
| 1 | signaltty-server ── owns PTYs, processes, workspaces, scrollback, |
| 2 | lifecycle, attention, persistence, IPC |
| 3 | signaltty ───────── CLI client (same API as the GUI) |
| 4 | signaltty-gui ───── GTK4/libadwaita GUI: sidebar, tabs, splits, |
| 5 | VTE panes, attention rings, desktop notifications |
GUI system deps: libgtk-4-dev libadwaita-1-dev libvte-2.91-gtk4-dev (libadwaita ≥ 1.7; GUI crate only; server/CLI
build without them).
Install the desktop app
| 1 | ./contrib/install-desktop.sh install |
This builds the GUI in release mode and installs signaltty-gui in
~/.local/bin, the desktop entry in ~/.local/share/applications, the
AppStream metadata in ~/.local/share/metainfo, and both icons in
~/.local/share/icons/hicolor/scalable/apps. The installed desktop entry
launches the binary by its absolute path, so it works even when ~/.local/bin
is not on the desktop session's PATH. Sign out and back in if the launcher
does not refresh. The GUI connects to the signaltty server.
To remove these files:
| 1 | ./contrib/install-desktop.sh uninstall |
To close a workspace, use the close button on its sidebar row, or select it and choose Close Workspace from the main menu. Confirming stops its running terminals and agents. Closing the GUI window leaves them running.
GUI shortcuts (Ctrl+Shift, so plain Ctrl chords reach the terminal):
| Keys | Action |
|---|---|
| Ctrl+Shift+N / Ctrl+Shift+T | new workspace (folder · name · agent) / new tab |
| Ctrl+Shift+E / Ctrl+Shift+O | split right / split down |
| Ctrl+Shift+W | close pane |
| Ctrl+Shift+J | jump to the next pane that needs you |
| Ctrl+Shift+P | command palette and workspace search |
| Ctrl+Shift+R | rename the selected workspace |
| Ctrl+Shift+F | search the active terminal, with next/previous matches |
| Ctrl+Shift+Z | zoom the active pane, then restore its splits |
| Alt+1…9, Ctrl+PgUp/PgDn | switch tabs |
| F9 / F10 | toggle sidebar / main menu |
The main menu also offers Worktrees and Show Changes. Worktrees lists Git's registered checkouts and opens each as a workspace. Create a checkout on a new branch to isolate another agent's edits. Show Changes displays working-tree changes against HEAD, with per-file counts and binary/untracked labels. Pane zoom changes only the view; saved divider ratios stay intact.
The same checkout operations are available to scripts:
| 1 | signaltty worktree list --workspace my-project |
| 2 | signaltty worktree create --workspace my-project --path /absolute/feature --branch feature |
| 3 | signaltty worktree open --workspace my-project --path /absolute/feature |
| 4 | signaltty workspace close feature |
| 5 | signaltty worktree remove --workspace my-project --path /absolute/feature |
Closing a workspace preserves its checkout. Removal refuses the main checkout, dirty/locked checkouts and open workspace or live-process references; branches are kept. There is no force-removal fallback.
Claude and current Codex permission hooks show Allow once and Deny in the existing pane bar. The choice returns as native hook JSON. Timeout or a cancelled reporter grants nothing and leaves permission handling to the agent. Codex still requires its normal hook trust review. See agent integration.
Server → Workspace → Tab → Pane. Lifecycle (unknown/working/blocked/ done/idle/failed/exited) and attention (none/unread/input_required/ permission_required/warning/error) are independent first-class axes.
Docs: architecture · data model · lifecycle & attention · PTY · terminal research · GTK decision · agents · IPC schema · persistence · security · crates · roadmap & risks · plugins · ADRs.
Plugins live in ~/.config/signaltty/plugins/<name>/plugin.toml
(event hooks + runnable commands); examples in examples/plugins/,
orchestration recipe in examples/workflows/.
Layout
| 1 | crates/signaltty-core domain model (toolkit/async/OS-free) |
| 2 | crates/signaltty-proto signaltty/1 IPC envelopes, methods, events |
| 3 | crates/signaltty-term TerminalBackend trait, headless vt100 backend, |
| 4 | OSC 9/99/777 scanner, sanitizers |
| 5 | crates/signaltty-agent AgentAdapter trait + codex/claude/opencode/ |
| 6 | cursor/generic adapters, hook classification, |
| 7 | session identity, resume commands |
| 8 | crates/signaltty-server daemon: PTY manager, router, events, snapshots |
| 9 | crates/signaltty-cli CLI client incl. interactive attach |
| 10 | crates/signaltty-gui native GUI (sidebar/tabs/splits/VTE, |
| 11 | attention rings, next-unread, notifications) |
| 12 | crates/signaltty-testkit hermetic-server test harness (real PTYs) |
| 13 | contrib/ systemd user unit and desktop integration |
Run as a user service (recommended)
| 1 | mkdir -p ~/.config/systemd/user |
| 2 | cp contrib/signaltty-server.service ~/.config/systemd/user/ |
| 3 | systemctl --user daemon-reload |
| 4 | systemctl --user enable --now signaltty-server |
Development
| 1 | scripts/setup-dev.sh --system # Ubuntu 26.04; installs packages and pinned Rust components |
| 2 | scripts/verify.sh doctor |
| 3 | scripts/verify.sh full |
The development container uses the same setup. Other Linux distributions can
install equivalents of scripts/dev-packages.txt, then run scripts/setup-dev.sh.
See agent development for checks, evidence,
worktree isolation and native desktop verification limits.
Design rule
The server owns the processes, the terminal backend renders terminal state, agent adapters provide semantic agent state, notifications describe human attention, and the UI helps the user find the work that needs them.
Direct Claude, Codex, OpenCode and Cursor launches configure their status hooks
automatically, preserving existing configuration. Codex may still require native
/hooks trust review. Setup problems appear as notices while the terminal remains
usable. See agent integration.