agent-orchestrator/agor-pty
2026-03-25 17:59:32 +01:00
..
clients/ts feat(electrobun): wire PTY daemon into terminal tabs via Electrobun RPC 2026-03-20 03:20:13 +01:00
native fix(electrobun): disable WebView during resize drag in C (prevents grab theft) 2026-03-25 17:59:32 +01:00
src fix(agor-pty): implement real PTY resize (TIOCSWINSZ via portable-pty) 2026-03-20 03:29:53 +01:00
Cargo.lock feat(agor-pty): complete PTY daemon — auth, sessions, output fanout 2026-03-20 03:10:49 +01:00
Cargo.toml feat(agor-pty): complete PTY daemon — auth, sessions, output fanout 2026-03-20 03:10:49 +01:00
README.md feat: agor-pty crate — standalone PTY multiplexer daemon (Phase 1 WIP) 2026-03-20 03:04:36 +01:00

agor-pty — PTY Multiplexer Daemon

Standalone Rust daemon that manages terminal sessions via Unix socket IPC. Portable across Tauri and Electrobun frontends.

Architecture

Frontend (Electrobun/Tauri)
    ↕ Unix Socket IPC (JSON-framed)
agor-ptyd (Rust daemon)
    ↕ PTY master FDs
Shell processes (/bin/bash, etc.)

Features

  • PTY multiplexing: single daemon manages all terminal sessions
  • Session persistence: sessions survive frontend disconnects/restarts
  • Multi-client: multiple frontends can connect and subscribe to session output
  • Auth: 256-bit token authentication per connection
  • Output fanout: PTY output fanned to all subscribed clients (non-blocking)
  • Graceful shutdown: SIGTERM/SIGINT cleanup

Usage

# Build
cd agor-pty && cargo build --release

# Run daemon
./target/release/agor-ptyd --verbose

# Custom socket directory
./target/release/agor-ptyd --socket-dir /tmp/agor-test

# Custom default shell
./target/release/agor-ptyd --shell /bin/zsh

IPC Protocol

JSON messages over Unix socket, newline-delimited.

Client → Daemon

  • Auth { token } — authenticate (must be first message)
  • CreateSession { id, shell, cwd, env, cols, rows } — spawn shell
  • WriteInput { session_id, data } — send input to PTY
  • Resize { session_id, cols, rows } — resize terminal
  • Subscribe { session_id } — receive output from session
  • Unsubscribe { session_id } — stop receiving output
  • CloseSession { session_id } — kill session
  • ListSessions — get all active sessions
  • Ping — keepalive

Daemon → Client

  • AuthResult { ok } — auth response
  • SessionCreated { session_id, pid } — session spawned
  • SessionOutput { session_id, data } — PTY output (base64)
  • SessionClosed { session_id, exit_code } — session ended
  • SessionList { sessions } — list response
  • Pong — keepalive response
  • Error { message } — error

Integration

As library (for Tauri)

use agor_pty::protocol::{ClientMessage, DaemonMessage};

TypeScript client (for Electrobun)

See clients/ts/ for the IPC client module.

Directory Structure

agor-pty/
├── Cargo.toml
├── README.md
├── src/
│   ├── main.rs        — daemon entry, CLI, signals
│   ├── lib.rs         — library re-exports
│   ├── protocol.rs    — IPC message types
│   ├── session.rs     — PTY session management
│   ├── daemon.rs      — Unix socket server
│   └── auth.rs        — token authentication
└── clients/
    └── ts/            — TypeScript IPC client (for Electrobun/Bun)