Agent CLI Runtime is the dependable adapter layer you reach for when you do not want to build yet another coding agent.
Modern local coding agents (like Codex CLI, Claude Code, and OpenCode) already excel at planning, editing files, running tools, asking for permissions, and managing LLM loops. This runtime keeps those complex loops inside the user's installed CLI while giving product builders and developers a unified, typed Node.js/TypeScript API to programmatically orchestrate them.
Building developer tools with local coding agents usually means wrestling with non-standardized CLI flags, parsing chaotic terminal streams, managing subprocess timeouts, and dealing with permission leaks.
Agent CLI Runtime normalizes this chaotic landscape into a clean, predictable, and local-first execution layer:
| Subprocess Problem | Runtime Responsibility |
|---|---|
| CLI Fragmentation Users have different CLIs installed ( codex, claude, opencode) |
Auto-Detection Probes and detects available coding agent CLIs in the system. |
| Argument Limits Oversized prompts break command-line length limits (argv) |
Safe Prompt Transport Gracefully leverages stdin and temporary prompt files instead of argv. |
| Stream Inconsistency Every CLI outputs a different text/JSON format |
Event Stream Normalization Parses raw stdout/stderr into a single unified AgentEvent protocol. |
| Zombies & Hangs Headless runs can hang indefinitely on network stalls |
Lifecycle Management Enforces timeouts, inactivity limits, cancellation, and exit classification. |
| Privilege Escalation Agents can run arbitrary shell commands outside workspaces |
Explicit Sandboxing Enforces strict cwd, extraAllowedDirs, and permissionPolicy. |
- ๐ Automated CLI Detection: Programmatically probes local executables, CLI versions, auth states, model availability, and capabilities without mutating user configs.
- โก Unified Event Streaming: Stream text deltas, thinking logs, tool invocations, file operations, usage/costs, and errors through an async-iterable
AgentEventstream. - ๐พ Opt-In Durable Storage & Replay: Log run manifests and events to disk. Includes crash-recovery checks, single-writer lease protection (
runtime.lock.json), and store health/repair utilities. - ๐ฏ Task Graphs & Goal Scheduling: Built-in planner integration that validates task dependency graphs and executes tasks in serial or parallel with custom retry and backoff policies.
- ๐ก๏ธ Hardened Security & Redaction: Out-of-the-box credential sanitization that automatically redacts secrets, bearer tokens, home folders, and absolute paths from diagnostics and outputs.
- ๐ฉบ Production-Grade Diagnostics: Comprehensive, isolated diagnostics bundle exports with standardized error codes to make debugging failed agent runs trivial.
Install the library via npm:
npm install agent-cli-runtimeOr execute CLI commands on the fly using npx:
npx --package agent-cli-runtime agent-runtime agents --json
npx --package agent-cli-runtime agent-runtime conformance --mode fixtures --jsonInitialize the runtime and detect what coding agents are installed on the local machine:
import { createAgentRuntime } from "agent-cli-runtime";
const runtime = createAgentRuntime();
// Detect installed coding agents on the machine
const agents = await runtime.detect({
includeUnavailable: true,
});
console.log("Detected agents:", agents);Run a direct prompt and consume the normalized event stream in real-time:
const run = await runtime.run({
agentId: "codex",
cwd: process.cwd(),
prompt: "Add a focused regression test for the failing parser case.",
permissionPolicy: "workspace-write",
});
for await (const event of run.events) {
switch (event.type) {
case "text_delta":
process.stdout.write(event.text);
break;
case "tool_call":
console.log(`\n[Tool Invoked] ${event.name}`, event.input);
break;
case "thinking_delta":
process.stdout.write(`๐ญ ${event.text}`);
break;
case "error":
console.error(`\n[Error ${event.code}] ${event.message}`);
break;
case "run_finished":
console.log(`\n[Execution Finished] Result: ${event.result}`);
break;
}
}Execute complex objectives that are automatically broken down into dependency-aware task graphs by the planner:
const goal = await runtime.createGoal({
cwd: "/path/to/project",
objective: "Implement a focused parser regression fix and run tests.",
defaultAgentId: "codex",
permissionPolicy: "workspace-write",
maxConcurrentTasks: 2, // Allows independent tasks to run in parallel
retryPolicy: {
maxAttempts: 2,
retryableErrorCodes: ["AGENT_TIMEOUT", "AGENT_EXECUTION_FAILED"],
backoffMs: 500,
},
});
for await (const event of goal.events) {
if (event.type === "task_attempt_started") {
console.log(`Task ${event.taskId} Attempt ${event.attemptId} started.`);
}
if (event.type === "goal_finished") {
console.log(`Goal Finished. Status: ${event.result}`);
}
}The core runtime acts as a process orchestrator and event normalizer. Individual adapters encapsulate CLI-specific nuances, allowing the client application to interact with a single interface.
flowchart LR
App["Your Application / Daemon"] --> Runtime["Agent CLI Runtime"]
Runtime --> Registry["Adapter Registry"]
Registry --> Codex["Codex CLI Adapter"]
Registry --> Claude["Claude Code Adapter"]
Registry --> OpenCode["OpenCode Adapter"]
Codex --> Subprocess["Spawn CLI Subprocess"]
Claude --> Subprocess
OpenCode --> Subprocess
Subprocess --> Parser["Stream Parser"]
Parser --> Events["Unified AgentEvent Stream"]
Events --> App
Each adapter manages CLI-specific responsibilities:
- Version, auth, model, and capabilities probing.
- Subprocess argument (argv) and environment variables (env) mapping.
- Prompt transport selection (stdin, prompt files).
- Output stream parsing & noise isolation.
When calling createGoal, the planner output is parsed and validated against a strict JSON schema:
{
"tasks": [
{
"id": "T001",
"title": "Fix Parser Core",
"objective": "Identify and correct the off-by-one error in stream-parser.",
"dependencies": [],
"allowedFiles": ["src/parsers/stream-parser.ts"],
"validationCommands": ["npm test"],
"agentId": "codex",
"retryPolicy": {
"maxAttempts": 2,
"retryableErrorCodes": ["AGENT_TIMEOUT"],
"backoffMs": 250
}
}
]
}id,title, andobjectiveare mandatory strings.dependencies,allowedFiles, andvalidationCommandsare optional string arrays.- Task-level
retryPolicycan override global schedules.
By default, runs and goals are kept entirely in-memory. By passing a storageDir, the runtime enables durable local persistence:
const runtime = createAgentRuntime({
storageDir: "./.agent-runtime",
storage: { durability: "fsync" }, // Optional. Default is "relaxed"
});On-disk serialization uses a robust, append-friendly layout:
.agent-runtime/
runtime.lock.json # Single-writer concurrency lease
runs/
<runId>/
manifest.json # Run configuration metadata
events.jsonl # Append-only stream event log
goals/
<goalId>/
manifest.json # Goal objective & tasks configuration
events.jsonl # Append-only goal execution event log
- Single-Writer Lease: The
runtime.lock.jsonfile contains information about the active runtime (PID, host, heartbeat). A second runtime trying to gain write access to the same directory will be safely refused. - Crash Recovery: During start-up, active runs or goals owned by crashed, stale, or dead processes are safely marked as failed with an
AGENT_RUNTIME_INTERRUPTEDdiagnostic, ensuring your data history never lies about active state. - Corruption Isolation: Corrupted JSONL lines are safely skipped during replays and reported via diagnostics instead of failing the entire runtime initialization.
The package is intentionally environment-first to avoid mutating user files.
Specify custom binary locations using environment variables:
export CODEX_BIN=/absolute/path/to/codex
export CLAUDE_BIN=/absolute/path/to/claude
export OPENCODE_BIN=/absolute/path/to/opencodeConfigure Claude Code's Anthropic-compatible provider through environment variables:
export ANTHROPIC_BASE_URL=<anthropic-compatible-base-url>
export ANTHROPIC_MODEL=<model-name>
export ANTHROPIC_DEFAULT_OPUS_MODEL=<model-name>
export ANTHROPIC_DEFAULT_SONNET_MODEL=<model-name>
export ANTHROPIC_DEFAULT_HAIKU_MODEL=<model-name>
export CLAUDE_CODE_SUBAGENT_MODEL=<model-name>
export CLAUDE_CODE_EFFORT_LEVEL=<effort>
export ANTHROPIC_API_KEY=<your-secret-api-key>
โ ๏ธ Security Warning: Never write real token values or API keys directly into prompts, manifests, examples, or committed code files.
Subprocesses automatically inherit system network proxies:
export HTTPS_PROXY=http://127.0.0.1:7897
export HTTP_PROXY=http://127.0.0.1:7897The package ships with an agent-runtime CLI tool for administrative, testing, and debugging purposes.
# 1. Detection and Verification
agent-runtime agents # List detected coding agents
agent-runtime doctor # Diagnose current environment health
agent-runtime conformance --mode fake --json # Run conformance test suite using offline fakes
agent-runtime conformance --mode real --agent all --json # Certificate real CLI integration profiles
# 2. Subprocess Runs & Goals
agent-runtime run --agent codex --cwd . --prompt "Fix test" # Run interactive task
agent-runtime goal --agent codex --cwd . --prompt "Refactor" # Create a task graph goal
# 3. Persistent Storage Auditing
agent-runtime runs --storage-dir .agent-runtime --json # List saved runs
agent-runtime replay-run run_123 --storage-dir .agent-runtime --jsonl # Replay stream events
agent-runtime store-health --storage-dir .agent-runtime --json # Run database integrity scan
agent-runtime store-repair --storage-dir .agent-runtime --apply --json # Perform atomic repairs on event logs| Adapter | Binary | Transport | Stream Strategy | Status / Capabilities |
|---|---|---|---|---|
| Codex CLI | codex |
stdin | codex exec --json |
Fully supported. Timeout diagnostics categorize startup lags, and reconnect streams are parsed as statuses. |
| Claude Code | claude |
stdin JSONL | stream-json |
Basic detection supported. Advanced capabilities and authentication probe support is ongoing. |
| OpenCode | opencode |
stdin | JSON Stream | Supported. Stdin prompts verified on opencode 1.15.6. Read-only isolation profile is active. |
This runtime spawns and manages powerful coding agents on your local machine. We take safety extremely seriously:
- No Auto-Authentication: The runtime does NOT store credentials or log you into third-party services. It inherits authentication from your already authenticated local CLI tools.
- Sandbox Isolation: Probes run in clean, isolated temp directories to avoid polluting or reading your project workspace.
- Strict Redaction Engine: Automatically filters and redacts environment dumps, token variables, absolute home folder paths, and
Bearerkeywords before writing data to manifests or diagnostic exports. - Failed Adapter Isolation: A failure in one agent adapter (e.g., missing authentication for Claude Code) is caught gracefully and never crashes detection or execution of other adapters.
This project is in pre-alpha / developer preview.
agent-cli-runtime@0.1.0-alpha.6- Published corrective alpha release. Published on npm; npmalphaandlatestdist-tags both point at0.1.0-alpha.6. GitHub Releasev0.1.0-alpha.6exists as a prerelease with the npm registry tarball asset, andrelease:post-alpha:verifytarball parity passes.agent-cli-runtime@0.1.0-alpha.5- Published on npm. npmalphaandlatestdist-tags both point at0.1.0-alpha.6. GitHub Releasev0.1.0-alpha.5exists as a prerelease with the npm registry tarball asset, andrelease:post-alpha:verifytarball parity passes. Its immutable npm tarball contains stale package docs, so aggregate published verification (published:verify/published:verify:evidence) fails withregistry_packaged_docs_failed; alpha.5 is not final corrective release acceptance.agent-cli-runtime@0.1.0-alpha.4- Historical version published on npm. The immutable npm tarball contains stale release-prep package docs. GitHub Releasev0.1.0-alpha.4exists with the npm registry tarball asset, and GitHub Release tarball parity passes.agent-cli-runtime@0.1.0-alpha.3- Historical corrective pre-alpha release.agent-cli-runtime@0.1.0-alpha.2- Published historical version whose immutable npm tarball contains stale pre-publish package docs.agent-cli-runtime@0.1.0-alpha.1- Earlier published alpha with GitHub pre-releasev0.1.0-alpha.1.agent-cli-runtime@0.1.0-alpha.0- Deprecated because its immutable package docs shipped stale pre-publish status text.
npm registry metadata and GitHub Releases are the source of truth for available versions and dist-tags. Volatile run, target-SHA, registry, and artifact evidence stays outside the npm package under .release-evidence/. Future beta promotion or stable promotion requires fresh release evidence for that target, including package docs, registry state, GitHub Release parity, and published verification.
published:usability:audit is a repository-only post-publish audit script. It is intentionally excluded from npm package contents and verifies an already published package from the npm registry.
- M0: Design specification, documentation architecture, and core skeleton setup.
- M1: Subprocess runner implementation and fake-CLI test harness.
- M2: Codex CLI Adapter MVP.
- M3: Claude Code Adapter MVP.
- M4: OpenCode Adapter MVP.
- M5: Command Line Interface (
agent-runtimewrapper) anddoctorcommand. - M6: Public package boundaries, API/CLI schema contract lock, and release candidate validation checks.
For advanced integrations, refer to the following comprehensive specifications:
- SSOT (Single Source of Truth) โ Product intent and historical evidence records.
- API & CLI Contract Schema โ Stable failure taxonomies, event envelopes, and validation contracts.
- Daemon Embedding Guide โ Embedding the runtime in background processes.
- Real CLI Compatibility Matrix โ Supported flags and real smoke matrices.
- Publish Runbook & Checklist โ Step-by-step guidance for releasing new versions.
We welcome contributions! Please review CONTRIBUTING.md and SECURITY.md before submitting pull requests.
Licensed under the Apache License, Version 2.0 (Apache-2.0). See the LICENSE file for details.