Skip to content

runAgent

The runAgent function executes a Claude Code agent and automatically captures all execution context (git state, file changes, tool calls, metrics). Available in both test context and as a standalone function.

function runAgent(opts: RunAgentOptions): AgentExecution

Returns: AgentExecution (thenable) that resolves to RunResult


ParameterTypeDefaultDescription
promptstring | AsyncIterable<SDKUserMessage>requiredUser prompt or multi-modal messages
modelstringDEFAULT_MODELModel to use (env: VIBE_DEFAULT_MODEL)
workspacestringcurrent dirWorkspace directory path
allowedToolsstring[]all toolsWhitelist of allowed tools
mcpServersRecord<string, MCPServerConfig>noneMCP server configurations
timeout Msnumber300000Timeout in milliseconds (5 min)
maxTurnsnumber20Maximum conversation turns
systemPromptstring | objectdefaultSystem prompt configuration
contextRunResultnonePrevious context to continue from

const result = await runAgent({
prompt: 'Refactor src/auth.ts'
});
console.log('Cost:', result.metrics.totalCostUsd);
console.log('Files:', result.files.stats().total);
const result = await runAgent({
prompt: 'Refactor auth.ts --add-tests',
model: 'claude-3-5-haiku-latest',
maxTurns: 10,
timeoutMs: 600000, // 10 minutes
workspace: '/path/to/repo'
});

Use the prompt() helper for images and files:

import { runAgent, prompt } from '@dao/vibe-check';
const result = await runAgent({
prompt: prompt({
text: 'Implement the feature from this PRD',
files: ['./docs/prd.md'],
images: ['./mockups/ui-design.png']
})
});

See prompt() → for details.


const result = await runAgent({
prompt: 'Read and summarize README.md',
allowedTools: ['Read'] // Only Read tool allowed
});
expect(result).toUseOnlyTools(['Read']);
const result = await runAgent({
prompt: 'Query database for user stats',
mcpServers: {
database: {
command: 'npx',
args: ['@modelcontextprotocol/server-postgres'],
env: {
POSTGRES_URL: process.env.DATABASE_URL
},
allowedTools: ['query', 'schema']
}
}
});

Pass previous result as context for multi-turn conversations:

// First run
const analyze = await runAgent({
prompt: 'Analyze this codebase'
});
// Second run with context
const fix = await runAgent({
prompt: 'Fix the issues you found',
context: analyze // Continues conversation
});

const result = await runAgent({
prompt: 'Write code',
systemPrompt: {
preset: 'default',
append: 'Follow company style guide. Use TypeScript strict mode.'
}
});
const result = await runAgent({
prompt: 'Task',
systemPrompt: 'You are a code reviewer. Be thorough and constructive.'
});

Register watchers before awaiting for fail-fast behavior:

const execution = runAgent({
prompt: '/refactor'
});
execution.watch(({ files, metrics }) => {
// Abort if protected files touched
expect(files.changed()).not.toContain('database/');
// Abort if budget exceeded
expect(metrics.totalCostUsd).toBeLessThan(5.0);
});
const result = await execution;

See AgentExecution.watch() →


const result = await runAgent({
model: 'claude-3-5-haiku-latest', // Cheaper
maxTurns: 5, // Fewer turns
prompt: 'Simple task'
});
expect(result).toStayUnderCost(0.10);
const result = await runAgent({
prompt: 'Complex refactoring with tests',
timeoutMs: 900000, // 15 minutes
maxTurns: 30
});
// Process multiple repos
const repos = ['/repo1', '/repo2', '/repo3'];
for (const workspace of repos) {
const result = await runAgent({
workspace,
prompt: '/update-deps'
});
console.log(`${workspace}:`, result.files.stats().total, 'files');
}

runAgent returns an AgentExecution object that:

  • Is awaitable: const result = await runAgent(...)
  • Supports watchers: execution.watch(fn)
  • Can be aborted: execution.abort('reason')

See AgentExecution → for complete API.