Package Exports
- @sourceborn/agent-cli-sdk
Readme
Agent CLI SDK
TypeScript SDK for orchestrating AI-powered CLI tools (Claude Code, OpenAI Codex) in development workflows.
Features
- Unified Interface: Common API for multiple AI CLI tools
- Type-Safe: Full TypeScript support with comprehensive type definitions
- Streaming Support: Real-time event streaming for both Claude and Codex
- Session Management: Resume and continue conversations (Claude)
- Structured Output: Extract and validate JSON responses with optional Zod schemas
- Error Handling: Standardized error types with recovery suggestions
- Workflow Utilities: Built-in helpers for sequential, parallel, and retry operations
- Auto-Detection: Automatically finds CLI binaries in your PATH
- Factory Pattern: Easy instantiation with sensible defaults
Prerequisites
- Node.js 22 or higher
- Claude Code CLI (for Claude adapter) - Download
- Codex CLI (for Codex adapter) - Install Instructions
Installation
pnpm add @sourceborn/agent-cli-sdk
# Optional: Install Zod for structured output validation
pnpm add zodOr with npm:
npm install @sourceborn/agent-cli-sdk
# Optional: Install Zod for structured output validation
npm install zodQuick Start
Basic Usage (Claude)
import { createClaudeAdapter } from '@sourceborn/agent-cli-sdk';
const claude = createClaudeAdapter();
const response = await claude.execute('Create a hello world function');
console.log(response.output);
console.log(`Session: ${response.sessionId}`);
console.log(`Duration: ${response.duration}ms`);Basic Usage (Codex)
import { createCodexAdapter } from '@sourceborn/agent-cli-sdk';
const codex = createCodexAdapter();
const response = await codex.execute('Review this code for security issues', {
fullAuto: true,
});
console.log(response.output);Streaming
const response = await claude.execute('Write a REST API', {
streaming: true,
onStream: (event) => {
if (event.type === 'message.chunk') {
process.stdout.write(event.data.content || '');
}
if (event.type === 'tool.started') {
console.log(`\nš§ Using ${event.data.toolName}...`);
}
},
});Multi-Agent Workflow
import { createClaudeAdapter, createCodexAdapter } from '@sourceborn/agent-cli-sdk';
const claude = createClaudeAdapter();
const codex = createCodexAdapter();
// Step 1: Generate code
const generated = await claude.execute('Create an email validator function');
// Step 2: Review with Codex
const review = await codex.execute('Review the email validator for security issues', {
fullAuto: true,
});
// Step 3: Apply improvements
const improved = await claude.execute(
`Apply these suggestions: ${review.output}`,
{ sessionId: generated.sessionId } // Resume session
);Structured Output with JSON Parsing
Extract and validate JSON responses from AI CLI tools with optional Zod schema validation.
Basic JSON Extraction
Extract JSON without validation:
const response = await claude.execute(
'Return a JSON object with keys: name, age, city',
{ responseSchema: true } // Auto-extract JSON without validation
);
console.log(response.output); // Parsed JSON object
console.log(response.raw.stdout); // Original text with JSONType-Safe Validation with Zod
Define and validate expected structure:
import { z } from 'zod';
const UserSchema = z.object({
name: z.string(),
age: z.number(),
city: z.string(),
});
const response = await claude.execute(
'Return user data for John, age 30, from NYC as JSON',
{ responseSchema: UserSchema }
);
// response.output is fully typed as { name: string; age: number; city: string }
console.log(response.output.name); // TypeScript knows this is a string
// Check validation results
if (response.metadata.validation?.success) {
console.log('Valid JSON:', response.output);
} else {
console.log('Validation errors:', response.metadata.validation?.errors);
console.log('Best effort parse:', response.output);
}Complex Nested Schemas
const WeatherSchema = z.object({
location: z.object({
city: z.string(),
country: z.string(),
}),
temperature: z.number(),
conditions: z.string(),
forecast: z.array(
z.object({
day: z.string(),
high: z.number(),
low: z.number(),
})
),
});
const response = await claude.execute(
'Return weather data for San Francisco with 3-day forecast',
{ responseSchema: WeatherSchema }
);Array Validation
const TaskSchema = z.object({
id: z.number(),
title: z.string(),
completed: z.boolean(),
});
const TaskListSchema = z.array(TaskSchema);
const response = await claude.execute(
'Return a JSON array of tasks',
{ responseSchema: TaskListSchema }
);
// response.output is typed as Array<{ id: number; title: string; completed: boolean }>Key Features
- Automatic JSON Extraction: Parses JSON from markdown code blocks or inline
- Optional Validation: Use
truefor extraction only, or provide Zod schema - Type Safety: TypeScript infers output type from Zod schema
- Graceful Failures: Returns best-effort data even if validation fails
- Original Text Preserved: Access raw output via
response.raw.stdout - Validation Metadata: Check
response.metadata.validationfor results
Example: Complete Workflow
import { createClaudeAdapter } from '@sourceborn/agent-cli-sdk';
import { z } from 'zod';
const claude = createClaudeAdapter();
// Define schema
const AnalysisSchema = z.object({
summary: z.string(),
issues: z.array(
z.object({
severity: z.enum(['low', 'medium', 'high']),
description: z.string(),
line: z.number().optional(),
})
),
recommendations: z.array(z.string()),
});
// Execute with validation
const response = await claude.execute(
'Analyze this code and return structured JSON with summary, issues, and recommendations',
{ responseSchema: AnalysisSchema }
);
// Type-safe access
if (response.metadata.validation?.success) {
console.log(`Found ${response.output.issues.length} issues`);
response.output.issues.forEach((issue) => {
console.log(`[${issue.severity}] ${issue.description}`);
});
}See examples/structured-output.ts for more examples.
API Reference
Factory Functions
createClaudeAdapter(config?)
Creates a Claude Code adapter instance.
Parameters:
config?: ClaudeConfig- Optional configuration
Returns: ClaudeAdapter
Example:
const claude = createClaudeAdapter({
apiKey: process.env.ANTHROPIC_API_KEY, // Optional
});createCodexAdapter(config?)
Creates a Codex adapter instance.
Parameters:
config?: CodexConfig- Optional configuration
Returns: CodexAdapter
Example:
const codex = createCodexAdapter({
apiKey: process.env.CODEX_API_KEY, // Optional
});Adapter Methods
execute(prompt, options?)
Execute a prompt with the AI adapter.
Parameters:
prompt: string- The prompt/instructionoptions?: ExecutionOptions- Execution options
Returns: Promise<ExecutionResponse>
Common Options:
streaming?: boolean- Enable streaming modeonStream?: (event: StreamEvent) => void- Streaming callbacktimeout?: number- Timeout in millisecondssessionId?: string- Resume a previous session (Claude only)responseSchema?: any | true- Extract/validate JSON (passtruefor extraction only, or Zod schema for validation)
Claude-Specific Options:
model?: string- Model to use (default: 'sonnet')permissionMode?: string- Permission mode ('acceptEdits', 'bypassPermissions', etc.)systemPrompt?: string- Custom system promptfallbackModel?: string- Fallback model if primary is overloaded
Codex-Specific Options:
model?: string- Model to use (default: 'gpt-5')fullAuto?: boolean- Enable full-auto modesandbox?: string- Sandbox mode ('read-only', 'workspace-write', 'danger-full-access')approvalPolicy?: string- Approval policy ('untrusted', 'on-failure', 'on-request', 'never')enableSearch?: boolean- Enable web searchimages?: string[]- Image file paths for multi-modal input
getCapabilities()
Get the capabilities supported by this adapter.
Returns: AdapterCapabilities
const caps = claude.getCapabilities();
console.log(caps.streaming); // true
console.log(caps.sessionManagement); // true
console.log(caps.toolCalling); // true
console.log(caps.multiModal); // falseWorkflow Utilities
sequential(operations)
Execute operations sequentially.
import { sequential } from '@sourceborn/agent-cli-sdk';
const results = await sequential([
() => claude.execute('Task 1'),
() => claude.execute('Task 2'),
() => claude.execute('Task 3'),
]);parallel(operations)
Execute operations in parallel.
import { parallel } from '@sourceborn/agent-cli-sdk';
const results = await parallel([
() => claude.execute('Task 1'),
() => codex.execute('Task 2'),
() => claude.execute('Task 3'),
]);retry(operation, options?)
Retry an operation with exponential backoff.
import { retry } from '@sourceborn/agent-cli-sdk';
const result = await retry(() => claude.execute('Generate code'), {
maxAttempts: 3,
initialDelay: 1000,
backoffMultiplier: 2,
});Configuration
Environment Variables
CLI Path Overrides
CLAUDE_CLI_PATH- Custom path to Claude CLI binaryCODEX_CLI_PATH- Custom path to Codex CLI binary
Authentication (Optional)
ANTHROPIC_API_KEY- Claude API key (alternative to OAuth)CLAUDE_CODE_OAUTH_TOKEN- Claude OAuth tokenCODEX_API_KEY- Codex API key (alternative to OAuth)
Authentication
Claude: Run claude setup-token or set ANTHROPIC_API_KEY
Codex: Run codex login or set CODEX_API_KEY
Error Handling
The SDK provides standardized error types:
import {
AuthenticationError,
CLINotFoundError,
TimeoutError,
ExecutionError,
} from '@sourceborn/agent-cli-sdk';
try {
const response = await claude.execute('Task');
} catch (error) {
if (error instanceof AuthenticationError) {
console.error('Not authenticated:', error.recovery);
} else if (error instanceof CLINotFoundError) {
console.error('CLI not found:', error.recovery);
} else if (error instanceof TimeoutError) {
console.error('Timed out. Session:', error.sessionId);
console.error('Partial output:', error.partialOutput);
}
}Examples
See the examples/ directory for complete examples:
examples/simple.ts- Basic single-agent usageexamples/multi-agent.ts- Multi-agent workflowexamples/ci-integration.ts- CI/CD pipeline integrationexamples/structured-output.ts- JSON extraction and validation
Run examples:
npx tsx examples/simple.ts
npx tsx examples/multi-agent.ts
npx tsx examples/ci-integration.ts src/index.ts
npx tsx examples/structured-output.tsArchitecture
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā Application Layer ā
ā (Your code using the SDK) ā
āāāāāāāāāāāāāāāāāāā¬āāāāāāāāāāāāāāāāāāāāāāāā
ā
āāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāāāāāāāā
ā SDK Layer ā
ā āāāāāāāāāāāāāāāā āāāāāāāāāāāāāāāā ā
ā ā Claude ā ā Codex ā ā
ā ā Adapter ā ā Adapter ā ā
ā āāāāāāāā¬āāāāāāāā āāāāāāāā¬āāāāāāāā ā
ā ā ā ā
ā āāāāāāāā¼āāāāāāāāāāāāāāāāāāāā¼āāāāāāāā ā
ā ā Common Adapter Interface ā ā
ā ā (execute, getCapabilities) ā ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
āāāāāāāāāāāāāāāāāāā¬āāāāāāāāāāāāāāāāāāāāāāāā
ā
āāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāāāāāāāā
ā CLI Layer ā
ā āāāāāāāāāāāāāāāā āāāāāāāāāāāāāāāā ā
ā ā claude CLI ā ā codex CLI ā ā
ā ā (--print ā ā (exec ā ā
ā ā --json) ā ā --json) ā ā
ā āāāāāāāāāāāāāāāā āāāāāāāāāāāāāāāā ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāDevelopment
# Install dependencies
pnpm install
# Build
pnpm build
# Run tests
pnpm test
# Lint
pnpm lint
# Format
pnpm formatValidations
pnpm checkContributing
See CONTRIBUTING.md for development guidelines.
License
MIT License - see LICENSE file for details.