agent-commander
v0.10.1
Published
A JavaScript library to control agents enclosed in CLI commands like Anthropic Claude Code CLI
Maintainers
Readme
agent-commander
JavaScript bindings and CLI tools for controlling AI coding agents through their native command-line interfaces.
This package supports Node.js, Bun, and Deno. It provides start-agent and stop-agent binaries plus a library API for process management, isolation, JSON streaming, model aliasing, and read-only planning mode.
Install
npm install agent-commandernpm install -g agent-commanderbun add agent-commanderFor Deno, import the module directly from the repository:
import { agent } from 'https://raw.githubusercontent.com/link-assistant/agent-commander/main/js/src/index.mjs';CLI
start-agent --tool claude --working-directory "/tmp/project" --prompt "Inspect this project"start-agent --tool claude --working-directory "/tmp/project" \
--prompt "Plan the change" --read-only --model opus --fallback-model sonnetstart-agent --tool codex --working-directory "/tmp/project" \
--prompt "Run a focused review" --isolation screen --screen-name review-agent --detachedCommon options:
--tool <name>:claude,codex,opencode,qwen,gemini, oragent--working-directory <path>: directory where the agent command runs--prompt <text>and--system-prompt <text>: user and system prompts--prompt-file <path>: read prompt input from a file for stdin-based tools--model <name>: tool-specific model alias or full model name--read-onlyor--plan-only: enforce native planning/no-write mode when supported--approve-each(alias--permission-mode ask): approve each command, relaying native permission prompts as normalized NDJSON (supported foragentandclaude)--tool-executable <path>: override the native executable for any supported tool--tool-env <KEY=VALUE>: add an environment variable to the native tool process, repeatable--tool-arg <arg>: append a raw native tool argument, repeatable--skip-default-safety-flags: suppress default autonomous safety bypass flags, including Qwen/Gemini--yolo--isolation <mode>:none,screen, ordocker--dry-run: print the command without executing it
Claude-specific options include --append-system-prompt, --fallback-model, --session-id, --fork-session, --verbose, and --replay-user-messages.
Library
import { agent } from 'agent-commander';
const controller = agent({
tool: 'claude',
workingDirectory: '/tmp/project',
prompt: 'Return a short implementation plan',
model: 'sonnet',
readOnly: true,
});
await controller.start({ attached: false });
const result = await controller.stop();
console.log(result.exitCode);
console.log(result.output.plain);
console.log(result.metadata);result.metadata is a normalized summary for claude, codex, opencode, and agent runs. It includes success and error classification, session ID, usage-limit reset details, result summary, cost estimates, stream token usage, optional model usage, and sub-agent call summaries.
Real TUI capture
Use captureAgentTui() when a test must exercise the same interactive terminal
interface a person sees. It supports claude, codex, opencode, agent,
gemini, and qwen without switching them to their JSON/headless modes:
import { captureAgentTui } from 'agent-commander';
const capture = await captureAgentTui({
tool: 'codex',
workingDirectory: '/tmp/project',
prompt: 'Inspect the failing test',
promptAfter: 'What do you want to work on?',
startupInteractions: [
{ after: 'Do you trust the contents of this directory?', key: 'ENTER' },
],
// Defaults to an 80×30 terminal whose rendered content is 4:3.
aspectRatio: 4 / 3,
interactions: [
{ after: 'Choose an option', key: 'DOWN' },
{ after: 'Second option', key: 'ENTER' },
{ after: 'Working', resize: { cols: 120, rows: 40 } },
],
stopMarker: 'Finished',
artifactDirectory: 'artifacts/codex',
artifactOptions: {
borderRadius: 0,
cellWidth: 9,
cellHeight: 18,
fontSize: 14,
padding: 12,
background: '#111827',
foreground: '#e5e7eb',
},
artifacts: ['svg', 'gif', 'cast', 'frames', 'transcript'],
});
console.log(capture.transcript);
console.log(capture.events); // normalized message and tool_call eventsThe result includes command-stream's unrolled transcript, settled frames, raw
asciicast event stream, and normalized semantic events. The artifact directory
contains transcript.txt, frames.json, session.cast, snapshot.svg, and
the self-contained animated recording.svg, plus recording.gif for consumers
that cannot animate SVG. Use artifacts to select bundle formats and
artifactOptions to customize renderer geometry and theme. Explicit cols and
rows override the default geometry. Partial artifacts are also written when
the terminal command times out.
For large generated prompts, pass promptFile or let the controller create a temporary prompt file automatically for claude, codex, opencode, agent, qwen, and gemini:
const controller = agent({
tool: 'codex',
workingDirectory: '/tmp/project',
promptFile: '/tmp/agent-prompt.txt',
model: 'gpt-5.5',
});Pass tool-specific options through toolOptions:
const controller = agent({
tool: 'claude',
workingDirectory: '/tmp/project',
prompt: 'Continue the previous investigation',
resume: 'abc123',
toolOptions: {
fallbackModel: 'sonnet',
appendSystemPrompt: 'Prefer concise findings.',
replayUserMessages: true,
},
});For parity with fast-moving native CLIs, pass raw executable, environment, and argument overrides for any supported tool through toolOptions:
const controller = agent({
tool: 'codex',
workingDirectory: '/tmp/project',
promptFile: '/tmp/agent-prompt.txt',
toolOptions: {
executable: '/opt/codex/bin/codex',
extraEnv: { CODEX_HOME: '/tmp/codex-home' },
extraArgs: ['--config', 'model_reasoning_effort="high"'],
skipDefaultSafetyFlags: true,
sandboxMode: 'workspace-write',
approvalMode: 'never',
},
});Shared Behavior
JavaScript and Rust expose the same core concepts:
- Tool selection and model alias mapping
none,screen, anddockerisolation modes- Dry-run command preview
- JSON/NDJSON output parsing for tools that support it
- Read-only planning mode for tools with enforceable native restrictions
- Per-command approval (ask mode) with a normalized
permission_request/permission_responserelay for tools with a drivable native handshake
See shared concepts for behavior that should stay aligned across both packages, including the per-command approval parity table.
Release Flow
JavaScript releases use Changesets:
npm run changeset
npm run changeset:version
npm run changeset:publishThe GitHub Release workflow publishes language-specific releases with js_ tags and [JavaScript] vX.Y.Z release names.
Test
npm test
npm run lint
npm run format:check