gate4agent 0.2.0

Universal transport library for 6 CLI AI agents (Claude Code, Codex, Gemini, Cursor, OpenCode, OpenClaw). Unified TransportSession entry point with Pipe, PTY, and DaemonHarness transports.
Documentation

gate4agent

Universal Rust transport library for CLI AI agents. Spawn, stream, resume — for six different CLI agents through one unified API.

Not a harness. Not a sandbox. gate4agent is the thin wiring layer between your Rust app and the CLI agent's subprocess: spawn the binary, write the prompt, read structured events, resume by session id. That's it.

Supported CLI tools

Tool Transport Pipe mode Resume Notes
Claude Code Pipe + PTY ✓ stream-json --resume <id> Prompt via stdin
Codex Pipe + PTY --json exec resume <id> Requires --ask-for-approval never --skip-git-repo-check
Gemini Pipe + PTY ✓ stream-json ✗ (not in CLI)
Cursor Agent Pipe ✓ stream-json --resume <id> Claude-compatible schema
OpenCode (sst/opencode) Pipe --format json --session ses_XXX 5-event NDJSON schema
OpenClaw DaemonHarness ✓ via acpx ✓ (assumed) Requires running openclaw daemon + npm i -g acpx

Transport classes:

  • Pipe: spawn the CLI directly, read NDJSON over stdout
  • PTY: spawn inside a pseudo-terminal, scrape the screen with vt100 (for agents without structured output)
  • DaemonHarness: pre-probe a running daemon via raw TCP, then spawn the client binary over pipe

Quick start

use gate4agent::{TransportSession, SpawnOptions, CliTool, AgentEvent};
use std::path::PathBuf;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let opts = SpawnOptions {
        working_dir: PathBuf::from("."),
        prompt: "Say hello in 3 words".into(),
        resume_session_id: None,
        model: None,
        append_system_prompt: None,
        extra_args: vec![],
        env_vars: vec![],
    };

    let mut session = TransportSession::spawn(
        CliTool::ClaudeCode,
        &opts.working_dir.clone(),
        &opts.prompt.clone(),
        opts,
    )?;

    let rx = session.subscribe();
    while let Ok(event) = rx.recv() {
        match event {
            AgentEvent::Text { text, .. } => print!("{text}"),
            AgentEvent::SessionEnd { .. } => break,
            _ => {}
        }
    }
    Ok(())
}

Resume an existing session

let opts = SpawnOptions {
    resume_session_id: Some("abc-123-session".into()),
    ..opts
};

Each CLI handles resume in its own way — Codex swaps execexec resume <id>, Claude/Cursor use --resume <id>, OpenCode uses --session <ses_XXX>. gate4agent hides the difference behind SpawnOptions::resume_session_id.

DaemonHarness (OpenClaw)

OpenClaw requires a running daemon. gate4agent probes it via raw TCP (no HTTP client) before spawning the acpx client. If the daemon is down, TransportSession::spawn returns AgentError::DaemonNotRunning or DaemonProbeTimeout.

let session = TransportSession::spawn(CliTool::OpenClaw, &cwd, &prompt, opts)?;

Features

  • Single API for 6 CLIsTransportSession::spawn(tool, cwd, prompt, options)
  • SessionEnd synthesis — Codex has no terminal event; gate4agent synthesizes SessionEnd { result: "exit_code=N", is_error: N != 0 } on child exit
  • Raw TCP daemon probe — no reqwest, no HTTP client, std::net only
  • Transport-neutral eventsAgentEvent::{Text, ToolStart, ToolResult, Thinking, TurnComplete, SessionStart, SessionEnd}
  • Cross-platform — Windows (ConPTY + cmd /C argv wrapping) and Unix (POSIX PTY + bare exec)
  • Rate-limit detection — pattern-based session/daily/weekly limit detection per CLI
  • Zero new dependencies — gate4agent 0.2.0 added 3 CLIs, a daemon transport, and a unified session API without pulling in any new crate

Architecture

gate4agent/
├── src/
│   ├── lib.rs           — Library root, re-exports
│   ├── types.rs         — AgentEvent, CliTool, SessionConfig
│   ├── error.rs         — AgentError (DaemonNotRunning, DaemonProbeTimeout, ...)
│   ├── transport/       — ★ TransportSession, SpawnOptions, pipe_runner, daemon_runner
│   ├── cli/             — Per-tool spawn builders + parsers (claude, codex, gemini, cursor, opencode, openclaw)
│   ├── ndjson/          — NDJSON parsers per CLI
│   ├── parser/          — VTE + screen parser for PTY mode
│   ├── pty/             — PTY session (PtyWrapper, PtySession)
│   ├── pipe/            — Low-level PipeProcess (used internally by pipe_runner)
│   ├── daemon/          — TCP liveness probe (std::net only)
│   └── detection/       — Rate limit detection

Prerequisites

At least one CLI agent must be installed on the host. gate4agent does not install them.

CLI Install
Claude Code npm install -g @anthropic-ai/claude-code
Codex npm install -g @openai/codex
Gemini npm install -g @google/gemini-cli
Cursor Agent See https://cursor.com/docs/cli
OpenCode npm install -g opencode-ai (or see https://opencode.ai)
OpenClaw (via acpx) npm install -g acpx + running openclaw daemon

Versioning

  • 0.1.x — original 3-CLI library (Claude, Codex, Gemini)
  • 0.2.0 — breaking: 6 CLIs, TransportSession, AgentEvent renamed, PipeSession removed

See ROADMAP.md for what's next and DEBUGGING.md for known issues and mitigations.

Migration from 0.1.x to 0.2.0

  1. Events: AgentEvent::Pipe* → neutral names. Rename all match arms:

    • PipeTextText
    • PipeToolStartToolStart
    • PipeToolResultToolResult
    • PipeThinkingThinking
    • PipeTurnCompleteTurnComplete
    • PipeSessionStartSessionStart
    • PipeSessionEndSessionEnd
  2. Entry point: PipeSession::spawn(config, prompt, options)TransportSession::spawn(tool, cwd, prompt, SpawnOptions). PipeSession no longer exists.

  3. SpawnOptions: replaces PipeProcessOptions / ClaudeOptions. Fields: working_dir, prompt, resume_session_id, model, append_system_prompt, extra_args, env_vars.

  4. CliTool is now non-exhaustive in effect (3 new variants: Cursor, OpenCode, OpenClaw). Add arms or a _ => fallback.

  5. AgentError: new variants DaemonNotRunning { host, port, detail } and DaemonProbeTimeout { host, port, timeout_ms } — handle them when calling OpenClaw.

Support the Project

If you find this tool useful, consider supporting development:

Currency Network Address
USDT TRC20 TNxMKsvVLYViQ5X5sgCYmkzH4qjhhh5U7X
USDC Arbitrum 0xEF3B94Fe845E21371b4C4C5F2032E1f23A13Aa6e
ETH Ethereum 0xEF3B94Fe845E21371b4C4C5F2032E1f23A13Aa6e
BTC Bitcoin bc1qjgzthxja8umt5tvrp5tfcf9zeepmhn0f6mnt40
SOL Solana DZJjmH8Cs5wEafz5Ua86wBBkurSA4xdWXa3LWnBUR94c

License

MIT