Skip to main content

The Wall: Structured I/O vs PTY

Every AI coding CLI spawns subagents the same way: stdio: pipe. This creates a wall that limits what AI agents can do.

How Subagents Work Today

When Claude Code, Codex, or Gemini CLI spawn a subagent, they create a child process with piped stdin/stdout:
Parent AI → spawn(child, { stdio: ['pipe', 'pipe', 'pipe'] })
         → write JSON to stdin
         ← read JSON from stdout
         → parse response
This is structured I/O. The parent sends commands, the child responds with results. Clean, predictable, parseable. But it creates a hard boundary:
Subagent CAN:                    Subagent CANNOT:
✅ Call tools (Read, Write, Bash)  ❌ Run an interactive session
✅ Make API calls                  ❌ Control another CLI
✅ Read/write files                ❌ Type into a running process
✅ Execute shell commands          ❌ Read terminal output in real-time
                                   ❌ Use another AI as a worker
The child process receives JSON commands and returns JSON results. It never gets a terminal. It never sees a screen. It cannot interact.

The Workarounds

Every tool hits this wall and builds a workaround:

Claude Code: Teams (tmux panes)

Claude Code cannot make its subagents interactive, so it spawns entirely new CLI processes in tmux or iTerm2 panes:
Leader (Claude) → tmux split-pane → spawn new Claude CLI → file mailbox
Each teammate is a separate process with its own terminal. They communicate through JSON files on disk (mailbox pattern). Limitations:
  • Only Claude CLI can be a teammate
  • Requires tmux or iTerm2 installed
  • Communication is file-based (slow, no real-time)
  • Single machine only

Codex: Plugin for Claude Code

OpenAI built codex-plugin-cc to run Codex inside Claude Code:
Claude Code → subprocess → Node.js companion → Unix socket → Codex server
This is a thin bridge that shells out to Codex and returns text. Limitations:
  • One direction only (Codex → Claude)
  • Requires both tools installed
  • Per-pair integration (N² problem for N tools)
  • Single machine only

claude-squad: tmux Manager

An open-source tool that manages multiple AI CLIs in tmux sessions:
claude-squad → tmux → Claude | Codex | Gemini | Aider
Limitations:
  • Requires tmux
  • No headless mode (needs visible terminal)
  • No remote access
  • No daemon persistence

The N² Problem

When AI tools want to collaborate, the current approach requires a plugin for each pair:
Claude ↔ Codex    = codex-plugin-cc
Claude ↔ Gemini   = (doesn't exist)
Codex  ↔ Gemini   = (doesn't exist)
Claude ↔ Aider    = (doesn't exist)
...

N tools × N tools = N² plugins needed
Each plugin is a custom integration. Different protocol, different auth, different subprocess management.

PTY: The Way Through

A PTY (pseudo-terminal) is a real terminal — not a pipe. When a process runs in a PTY, it gets a screen, keyboard input, and interactive control.
Structured I/O:  process → pipe → JSON → pipe → process
PTY:             process → terminal → screen → keyboard → interactive
If you put an AI CLI in a PTY session, you can:
  • Type into it (send prompts)
  • Read its screen (get responses)
  • Run anything inside it (any CLI, any tool)
  • Control it programmatically (from another process)
PTY-for-AI:
  Daemon → PTY session → any CLI runs here

  niia write --session S "claude\r"     → types "claude" into terminal
  niia write --session S "hello\r"      → sends prompt
  niia get-answer --session S "hello"   → reads the response
The daemon doesn’t know what’s running inside. PTY-level control is inherently LLM-agnostic.

N² → N

With PTY-for-AI, you don’t need per-pair plugins:
NIIA PTY ← Claude
NIIA PTY ← Codex
NIIA PTY ← Gemini
NIIA PTY ← Aider
NIIA PTY ← any CLI

N tools × 1 interface = N connections
One interface controls all. The PTY is the universal adapter.

What This Enables

CapabilityStructured I/OPTY-for-AI
Heterogeneous teamsClaude + Gemini + Codex in one team
Cost routingModel selection onlyRoute to cheapest capable LLM
Provider failoverSystem stopsSwitch to different PTY session
Cross-machine teamsWorkers on different machines
Offline AILocal LLM in PTY session
AI controlling AIOne AI types into another’s terminal