vibeWorkflow
The vibeWorkflow
function creates multi-stage automation pipelines optimized for production use cases like CI/CD, deployments, and migrations. Unlike vibeTest
, workflows focus on execution rather than validation.
Signature
Section titled “Signature”function vibeWorkflow( name: string, fn: (ctx: WorkflowContext) => Promise<void>, options?: { timeout?: number; defaults?: { workspace?: string; model?: string; }; }): void;
Parameters
Section titled “Parameters”Parameter | Type | Description |
---|---|---|
name | string | Workflow name (displayed in reports) |
fn | (ctx: WorkflowContext) => Promise<void> | Workflow function receiving context |
options | object | Optional configuration |
options.timeout | number | Timeout in milliseconds (default: 600000 = 10 min) |
options.defaults | object | Default config for all stages |
options.defaults.workspace | string | Default workspace directory |
options.defaults.model | string | Default model for all stages |
Workflow Context (WorkflowContext)
Section titled “Workflow Context (WorkflowContext)”The workflow function receives a context object with:
Property | Type | Description |
---|---|---|
stage | (name, opts) => AgentExecution | Execute one stage |
files | CumulativeFileAccess | Cumulative file changes |
tools | CumulativeToolAccess | Cumulative tool calls |
timeline | CumulativeTimeline | Unified timeline |
until | (predicate, body, opts?) => Promise<RunResult[]> | Loop helper |
defaults | { workspace?, model? } | Default configuration |
See WorkflowContext → for complete interface.
Basic Usage
Section titled “Basic Usage”import { vibeWorkflow } from '@dao/vibe-check';
vibeWorkflow('deploy pipeline', async (wf) => { // Stage 1: Build const build = await wf.stage('build', { prompt: '/build --production' });
console.log('Build complete:', build.files.stats().total, 'files');
// Stage 2: Test const test = await wf.stage('test', { prompt: '/test' });
console.log('Tests:', test.tools.succeeded().length, 'passed');
// Stage 3: Deploy const deploy = await wf.stage('deploy', { prompt: '/deploy --production' });
console.log('Deployed!');});
Workflow Modifiers
Section titled “Workflow Modifiers”Like vibeTest
, workflows support modifiers:
vibeWorkflow.skip('not ready', async (wf) => { // Workflow is skipped});
vibeWorkflow.only('focus on this', async (wf) => { // Only this workflow runs});
vibeWorkflow.todo('implement later', async (wf) => { // Marked as TODO});
Stages
Section titled “Stages”Execute a Stage
Section titled “Execute a Stage”The wf.stage()
method executes one stage of the workflow:
const result = await wf.stage('stage-name', { prompt: 'What to do', model: 'claude-3-5-sonnet-latest', // Optional workspace: '/path/to/workspace', // Optional maxTurns: 10, // Optional // ... all RunAgentOptions});
Returns: AgentExecution
(thenable) that resolves to RunResult
Stage Naming
Section titled “Stage Naming”Use descriptive names that appear in logs:
await wf.stage('install-dependencies', { prompt: '/install' });await wf.stage('run-migrations', { prompt: '/migrate' });await wf.stage('deploy-to-production', { prompt: '/deploy' });
Output:
- Stage: install-dependencies (4.2s)- Stage: run-migrations (12.1s)- Stage: deploy-to-production (8.7s)
Cumulative State
Section titled “Cumulative State”Access data across all stages:
vibeWorkflow('multi-stage', async (wf) => { await wf.stage('stage1', { prompt: 'Create files' }); await wf.stage('stage2', { prompt: 'Modify files' });
// Get all files changed across both stages const allFiles = wf.files.allChanged(); console.log('Total files:', allFiles.length);
// Get files from specific stage const stage1Files = wf.files.byStage('stage1'); const stage2Files = wf.files.byStage('stage2');
console.log('Stage 1 changed:', stage1Files.length); console.log('Stage 2 changed:', stage2Files.length);});
API:
wf.files.allChanged()
- All files changed across all stageswf.files.byStage(name?)
- Files changed in specific stage (or current if omitted)
// Get all tool calls with stage contextconst allTools = wf.tools.all();
for (const { stage, call } of allTools) { console.log(`[${stage}] ${call.name}: ${call.ok ? '✓' : '✗'}`);}
API:
wf.tools.all()
- ReturnsArray<{ stage: string, call: ToolCall }>
Timeline
Section titled “Timeline”// Iterate over all events with stage contextfor await (const { stage, evt } of wf.timeline.events()) { console.log(`[${stage}] ${evt.type} at ${new Date(evt.timestamp).toISOString()}`);}
Loop Helper (until
)
Section titled “Loop Helper (until)”The until()
method enables retry logic and iterative workflows:
Signature
Section titled “Signature”wf.until( predicate: (latest: RunResult) => boolean | Promise<boolean>, body: () => Promise<RunResult>, opts?: { maxIterations?: number }): Promise<RunResult[]>
Parameters:
predicate
- Function that receives latest result, returnstrue
to stopbody
- Function to execute each iteration (returnsRunResult
)opts.maxIterations
- Maximum iterations (default: 10)
Returns: Array of RunResult
from all iterations
Basic Retry
Section titled “Basic Retry”vibeWorkflow('retry tests', async (wf) => { const results = await wf.until( (latest) => latest.tools.succeeded().length > 0, () => wf.stage('test', { prompt: '/test' }), { maxIterations: 3 } );
console.log(`Tests passed after ${results.length} attempts`);});
Convergence Loop
Section titled “Convergence Loop”vibeWorkflow('fix until clean', async (wf) => { const results = await wf.until( (latest) => latest.files.stats().total === 0, () => wf.stage('fix', { prompt: '/fix --auto' }), { maxIterations: 5 } );
console.log(`Converged after ${results.length} iterations`);});
Custom Condition
Section titled “Custom Condition”vibeWorkflow('deploy with health checks', async (wf) => { const results = await wf.until( async (latest) => { // Check if deployment succeeded const deployTool = latest.tools.all().find(t => t.name === 'Bash' && t.input.command?.includes('deploy') );
return deployTool?.ok ?? false; }, () => wf.stage('deploy-retry', { prompt: '/deploy --with-health-check' }), { maxIterations: 3 } );
const finalResult = results[results.length - 1]; console.log('Deployment:', finalResult.tools.succeeded().length > 0 ? '✓' : '✗');});
Default Configuration
Section titled “Default Configuration”Set defaults to avoid repetition:
vibeWorkflow('deployment', async (wf) => { // All stages inherit workspace and model from defaults await wf.stage('build', { prompt: '/build' // Uses defaults.workspace and defaults.model });
await wf.stage('test', { prompt: '/test' // Uses defaults.workspace and defaults.model });
// Override defaults for specific stage await wf.stage('deploy-docs', { prompt: '/deploy', workspace: '/path/to/docs-repo', // Override model: 'claude-3-5-haiku-latest' // Override });
}, { timeout: 600000, // 10 minutes defaults: { workspace: '/path/to/main-repo', model: 'claude-3-5-sonnet-latest' }});
Access defaults:
console.log('Workspace:', wf.defaults.workspace);console.log('Model:', wf.defaults.model);
Passing Data Between Stages
Section titled “Passing Data Between Stages”Via File System (Recommended)
Section titled “Via File System (Recommended)”vibeWorkflow('data passing', async (wf) => { // Stage 1: Write report await wf.stage('analyze', { prompt: 'Analyze code and write report.json' });
// Stage 2: Read report await wf.stage('fix', { prompt: 'Read report.json and fix all issues' });});
Via Bundle Directory
Section titled “Via Bundle Directory”vibeWorkflow('using bundles', async (wf) => { const analyze = await wf.stage('analyze', { prompt: 'Analyze code' });
// Pass bundle path to next stage await wf.stage('fix', { prompt: `Fix issues. See: ${analyze.bundleDir}/summary.json` });});
Via Context Parameter
Section titled “Via Context Parameter”vibeWorkflow('with context', async (wf) => { const analyze = await wf.stage('analyze', { prompt: 'Analyze code' });
// Pass full RunResult as context await wf.stage('fix', { prompt: 'Fix issues', context: analyze });});
Error Handling
Section titled “Error Handling”Workflows should handle errors gracefully (unlike tests that throw):
vibeWorkflow('resilient pipeline', async (wf) => { const build = await wf.stage('build', { prompt: '/build' });
if (build.tools.failed().length > 0) { console.error('Build failed:', build.tools.failed());
// Try recovery const recover = await wf.stage('recover', { prompt: '/fix-build-errors' });
if (recover.tools.failed().length > 0) { console.error('Recovery failed. Aborting.'); return; // Exit workflow } }
// Continue if build succeeded or recovery worked await wf.stage('deploy', { prompt: '/deploy' });});
Multi-Workspace Workflows
Section titled “Multi-Workspace Workflows”Some workflows span multiple repositories:
vibeWorkflow('full-stack deployment', async (wf) => { // Deploy backend await wf.stage('deploy-backend', { workspace: '/repos/backend', prompt: '/deploy --production' });
// Deploy frontend await wf.stage('deploy-frontend', { workspace: '/repos/frontend', prompt: '/deploy --production' });
// Update docs await wf.stage('update-docs', { workspace: '/repos/docs', prompt: '/update-version-info' });});
Examples
Section titled “Examples”CI/CD Pipeline
Section titled “CI/CD Pipeline”vibeWorkflow('ci/cd', async (wf) => { console.log('🚀 CI/CD Pipeline\n');
// Lint console.log('📝 Linting...'); const lint = await wf.stage('lint', { prompt: '/lint --fix' }); if (lint.tools.failed().length > 0) { console.error('❌ Lint failed'); return; } console.log('✅ Lint passed\n');
// Test console.log('🧪 Testing...'); const test = await wf.stage('test', { prompt: '/test' }); if (test.tools.failed().length > 0) { console.error('❌ Tests failed'); return; } console.log('✅ Tests passed\n');
// Build console.log('📦 Building...'); const build = await wf.stage('build', { prompt: '/build --production' }); if (build.tools.failed().length > 0) { console.error('❌ Build failed'); return; } console.log('✅ Build complete\n');
console.log('✅ Pipeline complete!');});
Database Migration
Section titled “Database Migration”vibeWorkflow('migrate database', async (wf) => { // Backup await wf.stage('backup', { prompt: '/backup database' });
// Migrate const migrate = await wf.stage('migrate', { prompt: '/migrate --production' });
// Verify const verify = await wf.stage('verify', { prompt: '/verify migration' });
// Rollback if failed if (verify.tools.failed().length > 0) { await wf.stage('rollback', { prompt: '/rollback migration' }); }});
Monorepo Refactor
Section titled “Monorepo Refactor”vibeWorkflow('monorepo refactor', async (wf) => { const packages = ['core', 'ui', 'api'];
for (const pkg of packages) { await wf.stage(`refactor-${pkg}`, { workspace: `/monorepo/packages/${pkg}`, prompt: '/refactor --modernize' }); }
// Update all dependencies await wf.stage('update-deps', { workspace: '/monorepo', prompt: '/update-deps --all-packages' });});
vibeTest vs vibeWorkflow
Section titled “vibeTest vs vibeWorkflow”Feature | vibeTest | vibeWorkflow |
---|---|---|
Purpose | Testing & evaluation | Production automation |
Assertions | ✅ expect() | ❌ No assertions |
Failure | Throws on error | Logs and continues |
Context | VibeTestContext | WorkflowContext |
Stages | ❌ No stage API | ✅ wf.stage() |
Loops | Manual | ✅ wf.until() |
Judge | ✅ Quality evaluation | ❌ Not typical |
Use Case | Benchmarking, validation | CI/CD, deployments |
See Also
Section titled “See Also”- WorkflowContext → - Complete context interface
- vibeTest → - For testing and evaluation
- runAgent() → - Agent execution options
- RunResult → - Captured execution data
- Your First Workflow → - Step-by-step tutorial
Related Guides
Section titled “Related Guides”- Building Workflows → - Advanced patterns
- Loop Patterns → - Mastering
until()
- Error Handling → - Production strategies