> ## Documentation Index
> Fetch the complete documentation index at: https://docs.monolex.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Architecture: Daemon → Headless → PTY

> Three-layer architecture for persistent, headless, remotely accessible AI terminal sessions.

# Architecture: Daemon → Headless → PTY

PTY-for-AI is built on three layers.
Each layer does one thing and is independently replaceable.

## The Three Layers

```
┌───────────────────────────────────────────────────┐
│  Layer 3: Gateway / P2P                           │
│  Remote access. Cross-machine. Encrypted.         │
├───────────────────────────────────────────────────┤
│  Layer 2: Headless Server                         │
│  Network bridge. Grid rendering. Session relay.   │
├───────────────────────────────────────────────────┤
│  Layer 1: PTY Daemon                              │
│  Process management. PTY spawn. Unix sockets.     │
└───────────────────────────────────────────────────┘
```

## Layer 1: PTY Daemon

The foundation. A persistent process that spawns and manages PTY sessions.

**Responsibility**: Create terminal sessions, resize, close, list.
Nothing more.

**Protocol** (JSON over Unix socket):

```json theme={null}
{
  "type": "create-session",
  "cols": 120,
  "rows": 40,
  "shell": "/bin/zsh",
  "cwd": "/path/to/workspace"
}
```

Response:

```json theme={null}
{
  "success": true,
  "sessionId": "pty-abc123",
  "socketPath": "/path/to/session.sock"
}
```

**Key properties**:

* Runs as OS service (launchd on macOS, systemd on Linux)
* Survives terminal closures, reboots, SSH disconnects
* Each session has its own Unix socket for I/O
* Supports `cwd` and `shell` per session — this is how plugins work
* Binary is never modified. All extension happens externally.

## Layer 2: Headless Server

Bridges PTY sessions to the network without a GUI window.

**Responsibility**: Connect to gateway, relay terminal I/O, manage grid state.

**What it does**:

* Creates a PTY session via daemon (Layer 1)
* Renders terminal grid (VTE parsing)
* Connects to gateway via WebSocket
* Relays input/output between gateway and PTY
* Accepts `--default-cwd` and `--default-shell` from plugins

**What it doesn't do**:

* No window. No UI. No display.
* Does not modify terminal content.
* Does not interpret commands.

## Layer 3: Gateway / P2P

Remote access to headless sessions across machines and networks.

**Two paths**:

```
Path A: Gateway relay (Cloudflare)
  Client → WSS → session.monolex.ai → WSS → Headless → PTY

Path B: P2P (WebRTC DataChannel)
  Client → DTLS → direct → Headless → PTY
```

Gateway for reliability. P2P for when gateway is unreachable.
Both encrypted end-to-end.

## How Sessions Are Controlled

```bash theme={null}
# Write to session (type into terminal)
niia write --session <ID> $'your command\r'

# Wait for output to settle
niia wait-idle --session <ID>

# Read the response
niia get-answer --session <ID> "search text"
```

These commands work identically for local and remote sessions:

```bash theme={null}
# Local
niia write --session local-123 $'claude\r'

# Remote (same syntax, different session)
niia remote write MACHINE-B $'claude\r'
```

## Persistence Model

```
Traditional terminal:
  Open terminal → run command → close terminal → gone

PTY-for-AI:
  Daemon starts (boot) → sessions created → machine shuts down
  Machine starts → daemon auto-starts → sessions still accessible
```

The daemon is an OS service. It starts on boot and restarts on crash.
Sessions persist across:

* Terminal window closures
* SSH disconnects
* Network interruptions
* Application restarts

Only explicit session close or machine shutdown ends a session.

## Plugin Injection Points

Plugins transform session parameters **before** they reach the daemon.
The daemon never knows plugins exist.

```
Plugin Layer (niia CLI):
  --worktree feat-x  →  cwd = /tmp/niia-worktree-feat-x
  --sandbox          →  shell = sandbox-exec -p '...' /bin/zsh

                    ↓ transformed parameters

Daemon receives:
  CreateSession { cwd: "/tmp/niia-worktree-feat-x",
                  shell: "sandbox-exec ... /bin/zsh" }

Daemon just spawns. It doesn't know about worktrees or sandboxes.
```

This separation means:

* Daemon binary never changes (stable, signed, tested)
* New plugins are added to the CLI layer only
* Plugin development doesn't require daemon access
* Third-party plugins are possible (same interface)

## What Each Layer Knows

|                     | PTY Daemon    | Headless             | Gateway     |
| ------------------- | ------------- | -------------------- | ----------- |
| What CLI is running | ❌             | ❌                    | ❌           |
| Session cwd         | ✅ (at spawn)  | ✅ (passes to daemon) | ❌           |
| Terminal content    | ❌ (raw bytes) | ✅ (VTE parsed)       | ✅ (relayed) |
| Network access      | ❌             | ✅                    | ✅           |
| Which LLM           | ❌             | ❌                    | ❌           |

No layer knows which AI is running inside the PTY.
This is by design. LLM-agnostic at every level.
