This directory contains SDK examples (programmatic usage) and configuration examples (YAML files).
Use Visor from Node.js without shelling out.
# Build SDK first
npm run build:sdk
# Basic SDK examples
node examples/sdk-basic.mjs # Minimal (5 lines)
node examples/sdk-cjs.cjs # CommonJS
node examples/sdk-manual-config.mjs # Manual config
node examples/sdk-comprehensive.mjs # Complex with dependencies
# TypeScript (full type safety with SDK types)
npx tsc examples/sdk-typescript.ts --module esnext --target es2022 --moduleResolution bundler --esModuleInterop --skipLibCheck && node examples/sdk-typescript.jsInteractive calculator demonstrating human-in-the-loop workflows:
# Interactive calculator with table output
bun examples/calculator-sdk-real.ts
# Calculator with JSON output (programmatic processing)
bun examples/calculator-sdk-json.ts
# Fully automated calculator (for testing/automation)
bun examples/calculator-sdk-automated.ts
bun examples/calculator-sdk-automated.ts 10 5 + # With args
# YAML config version
./dist/index.js --config examples/calculator-config.yaml --message "10" --check get-number1Features demonstrated:
- ✅ Human input via
human-inputcheck type - ✅ Memory provider for state management
- ✅ JavaScript execution in memory provider
- ✅ Dependency chains with fail_if validation
- ✅ JSON output for programmatic processing
- ✅ Custom visualization in SDK scripts
- ✅ Suppressing stdout/stderr for clean JSON responses
See docs/sdk.md for full SDK documentation.
Example configurations demonstrating various Visor features and use cases.
quick-start-tags.yaml- Simple configuration showing basic tag usagevisor-with-tags.yaml- Comprehensive configuration with all tag featuresenhanced-config.yaml- Enhanced configuration with advanced features
routing-basic.yaml- Failure routing with retry + goto ancestorrouting-on-success.yaml- on_success post-steps + single jump-backrouting-foreach.yaml- forEach remediation with run + retryrouting-dynamic-js.yaml- Dynamic routing via goto_js/run_jsrouting-goto-event.yaml- Goto routing with event handling
if-conditions.yaml- Conditional execution with if statementsfor-loop-example.yaml- Loop iteration patternsforEach-example.yaml- ForEach iteration over collectionstransform-example.yaml- Data transformation between steps
ai-custom-tools-example.yaml- AI with custom shell-based tools via ephemeral MCP serversai-custom-tools-simple.yaml- Simplified AI custom tools exampleapi-tools-ai-example.yaml- AI check using reusable OpenAPI-backedtype: apitool bundles (includes embedded tests)ai-retry-fallback-config.yaml- AI with retry and fallback providersai-with-bash.yaml- AI check combined with bash command executionai-with-mcp.yaml- AI check with MCP tool integrationbedrock-config.yaml- AWS Bedrock AI provider configurationclaude-code-config.yaml- Claude Code SDK integration with MCP toolsfact-validator.yaml- AI-based fact validation workflow
mcp-provider-example.yaml- MCP provider with stdio/SSE/HTTP transportscustom-tools-example.yaml- Custom tool definitionsapi-tools-library.yaml- Reusable OpenAPI API tool bundle definitions (type: api)api-tools-mcp-example.yaml- MCP checks calling OpenAPI-generated operations from reusable API bundle (includes embedded tests)api-tools-inline-overlay-example.yaml- Inline/file OpenAPI overlay example with reusable API tools (includes embedded tests)tools-library.yaml- Reusable tool library (git, docker, npm, testing, code quality tools)reusable-tools.yaml- Patterns for reusable tool definitionsproject-with-tools.yaml- Project configuration with integrated tools
memory-counter.yaml- Basic memory counter implementationmemory-error-collection.yaml- Collecting errors in memory across stepsmemory-exec-js.yaml- JavaScript execution within memory providermemory-namespace-isolation.yaml- Memory namespace isolation between workflowsmemory-retry-counter.yaml- Retry logic with memory-based counter trackingmemory-state-machine.yaml- State machine implementation using memory
human-input-example.yaml- Interactive human-in-the-loop patternsbasic-human-input.yaml- Basic human input workflowcalculator-config.yaml- Interactive calculator with memory and validation
http-integration-config.yaml- HTTP API integration patternshttps-server-config.yaml- HTTPS server configurationwebhook-pipeline-config.yaml- Multi-pipeline webhook system (GitHub, JIRA integration)cron-webhook-config.yaml- Scheduled cron triggers with webhooks
git-checkout-basic.yaml- Basic git checkout operationsgit-checkout-compare.yaml- Git checkout with comparison workflowsgit-checkout-cross-repo.yaml- Cross-repository git operations
fail-if-simple.yaml- Simple fail_if conditionsfailure-conditions-basic.yaml- Basic failure condition patternsfailure-conditions-advanced.yaml- Advanced failure handling with complex conditionsfailure-conditions-github-style.yaml- GitHub-style failure conditionsfailure-conditions-migration.yaml- Migration patterns for failure conditions
sandbox-basic.yaml- Basic Docker sandbox with image modesandbox-cache.yaml- Sandbox with cache volume mountssandbox-dockerfile-inline.yaml- Sandbox with inline Dockerfilesandbox-env-passthrough.yaml- Sandbox environment variable passthroughsandbox-multi-env.yaml- Multiple sandbox environments per checksandbox-read-only.yaml- Read-only sandbox with network isolation
enterprise-policy/- OPA policy engine with role-based access control (Enterprise Edition -- requires license, contact hello@probelabs.com)
jira-simple-example.yaml- Simple JIRA integrationjira-single-issue-workflow.yaml- Single JIRA issue workflowjira-workflow-mcp.yaml- JIRA workflow with MCP toolsslack-simple-chat.yaml- Slack bot simple chat integration
session-reuse-config.yaml- Session reuse configurationsession-reuse-self.yaml- Self-referencing session reuse patternson-init-import-demo.yaml- On-init hooks with importsreusable-workflows.yaml- Reusable workflow patterns
outputs-raw-basic.yaml- Raw output formatting
github-workflow-with-tags.yml- Progressive code review workflow using tags
environments/visor.base.yaml- Base configuration with all check definitionsenvironments/visor.dev.yaml- Development environment (fast, local checks)environments/visor.staging.yaml- Staging environment (balanced checks)environments/visor.prod.yaml- Production environment (comprehensive validation)
workflows/calculator-workflow.yaml- Reusable calculator workflow with inputs/outputsworkflows/code-quality.yaml- Code quality workflow (linting, complexity, formatting)workflows/quick-pr-check.yaml- Quick PR validation workflowworkflows/workflow-composition-example.yaml- Workflow composition and state isolation demo
Start with the simple configuration:
# Copy the quick-start example
cp examples/quick-start-tags.yaml .visor.yaml
# Run local checks
visor --tags local,fast
# Run comprehensive checks
visor --tags remote,comprehensiveUse different configurations for different environments:
# Development
visor --config examples/environments/visor.dev.yaml
# Staging
visor --config examples/environments/visor.staging.yaml
# Production
visor --config examples/environments/visor.prod.yamlCopy the workflow to your repository:
cp examples/github-workflow-with-tags.yml .github/workflows/code-review.ymllocal- Runs on developer machinesremote- Runs in CI/CDdev- Development environmentstaging- Staging environmentprod- Production environment
fast- Completes in < 30 secondsslow- Takes > 30 secondscomprehensive- Thorough but time-consuming
security- Security-related checksperformance- Performance analysisquality- Code quality and styletesting- Test-related checksdocumentation- Documentation checks
critical- Must pass for deploymentoptional- Nice to have but not blockingexperimental- Beta features
# Fast security checks for local development
visor --tags local,fast,security
# All critical checks for production
visor --tags prod,critical
# Comprehensive review excluding experimental
visor --tags comprehensive --exclude-tags experimental
# Just the essentials
visor --tags critical,fasttag_filter:
include: ["local", "fast"]
exclude: ["slow", "experimental"]- Goal: Quick feedback during development
- Runtime: < 1 minute
- Use Case: Pre-commit hooks, local testing
tag_filter:
include: ["remote", "critical"]
exclude: ["experimental"]- Goal: Validate changes before merge
- Runtime: 2-5 minutes
- Use Case: GitHub Actions on PR
tag_filter:
include: ["staging", "comprehensive"]
exclude: ["experimental", "optional"]- Goal: Thorough validation before production
- Runtime: 5-10 minutes
- Use Case: Staging deployment pipeline
tag_filter:
include: ["prod", "critical", "comprehensive"]
exclude: ["experimental"]- Goal: Maximum confidence for production
- Runtime: 10+ minutes
- Use Case: Production deployment gate
Start with fast checks and progressively run more comprehensive ones:
# Stage 1: Critical issues (fail fast)
visor --tags critical,fast --fail-fast
# Stage 2: Security scan (if stage 1 passes)
visor --tags security --exclude-tags fast
# Stage 3: Comprehensive review (if all pass)
visor --tags comprehensive --exclude-tags security,criticalRun checks based on file changes:
steps:
frontend-checks:
tags: ["frontend", "conditional"]
on: [pr_opened]
if: "filesChanged.some(f => f.endsWith('.tsx'))"
backend-checks:
tags: ["backend", "conditional"]
on: [pr_opened]
if: "filesChanged.some(f => f.endsWith('.py'))"steps:
quick-scan:
tags: ["local", "fast"]
deep-scan:
tags: ["remote", "slow"]
depends_on: [quick-scan] # Only if quick-scan is included
report:
tags: ["reporting"]
depends_on: [quick-scan, deep-scan] # Uses whatever ran- Start Simple: Begin with
local/remoteorfast/slow - Be Consistent: Use the same tags across all projects
- Document Tags: Maintain a tag glossary in your docs
- Review Regularly: Audit and update tags as needs change
- Measure Impact: Track execution times and adjust tags accordingly
- Use
visor --helpto see all available options - Combine
--tagsand--exclude-tagsfor precise control - Set default
tag_filterin config to avoid repetition - Use environment-specific configs with
extendsfor DRY principles - Test tag filters with
--debugto see which checks run
# Run Slack bot (requires SLACK_BOT_TOKEN, SLACK_APP_TOKEN env vars)
visor --config examples/slack-simple-chat.yaml# Simple JIRA workflow
visor --config examples/jira-simple-example.yaml
# JIRA with MCP tools
visor --config examples/jira-workflow-mcp.yaml# Multi-pipeline webhook server
visor --config examples/webhook-pipeline-config.yaml
# Cron-triggered webhooks
visor --config examples/cron-webhook-config.yaml# Basic memory counter
visor --config examples/memory-counter.yaml
# State machine with memory
visor --config examples/memory-state-machine.yaml
# Retry logic with counter
visor --config examples/memory-retry-counter.yaml# AI with custom tools (ephemeral MCP servers)
visor --config examples/ai-custom-tools-example.yaml
# AI with bash execution
visor --config examples/ai-with-bash.yaml
# AWS Bedrock provider
visor --config examples/bedrock-config.yaml --provider bedrock
# Claude Code SDK integration
visor --config examples/claude-code-config.yaml# Basic Docker sandbox
visor --config examples/sandbox-basic.yaml
# Sandbox with cache volumes
visor --config examples/sandbox-cache.yaml
# Inline Dockerfile sandbox
visor --config examples/sandbox-dockerfile-inline.yaml
# Environment variable passthrough
visor --config examples/sandbox-env-passthrough.yaml
# Multiple sandbox environments
visor --config examples/sandbox-multi-env.yaml
# Read-only sandbox with network isolation
visor --config examples/sandbox-read-only.yaml# MCP provider with different transports
visor --config examples/mcp-provider-example.yaml
# Custom tools
visor --config examples/custom-tools-example.yamlImport and compose workflows:
# Use the calculator workflow
visor --config examples/workflows/calculator-workflow.yaml --input "num1=10" --input "num2=5" --input "operation=add"
# Code quality workflow
visor --config examples/workflows/code-quality.yaml --input "language=typescript"
# Quick PR check
visor --config examples/workflows/quick-pr-check.yaml --input "pr_type=feature"
# Workflow composition example (imports calculator-workflow)
visor --config examples/workflows/workflow-composition-example.yamlEnterprise Edition feature. Requires a Visor EE license. Contact hello@probelabs.com for licensing.
Role-based access control for checks, MCP tools, and AI capabilities using OPA (Open Policy Agent) policies:
# Install EE build
npm install @probelabs/visor@ee
# Set license
export VISOR_LICENSE="<your-jwt-token>"
# Run with policy enforcement
visor --config examples/enterprise-policy/visor.yamlSee examples/enterprise-policy/README.md for full documentation, configuration reference, and Rego policy examples.
- Main README - Complete Visor documentation
- Configuration Guide - Detailed config options
- GitHub Actions Guide - CI/CD integration
Interactive workflows with human-in-the-loop:
# Basic human input patterns
visor --config examples/human-input-example.yaml
# Interactive calculator (demonstrates memory + JS + human input)
visor --config examples/calculator-config.yaml
# Run with inline message
visor --config examples/human-input-example.yaml --check approval-gate --message "yes"
# Run with file input (auto-detected)
echo "yes" > approval.txt
visor --config examples/human-input-example.yaml --check approval-gate --message approval.txt
# Run with piped input
echo "yes" | visor --config examples/human-input-example.yaml --check approval-gateCalculator Example: The calculator demonstrates a complete workflow:
- Prompts for first number
- Prompts for second number
- Prompts for operation (+, -, *, /)
- Stores values in memory
- Calculates result using JavaScript
- Displays formatted result
SDK Usage:
Two SDK examples are provided:
-
calculator-sdk-real.ts- Complete, runnable SDK example:- Real imports from Visor SDK
- Config defined inline (no YAML needed)
- Custom readline-based input hook
- Full CheckExecutionEngine usage
- Works in interactive or automated mode
# Interactive mode ts-node examples/calculator-sdk-real.ts # Automated mode (for testing) ts-node examples/calculator-sdk-real.ts 42 7 +
-
calculator-sdk-example.ts- Documentation/template example:- Shows the structure and patterns
- Includes comments and explanations
- Generates YAML config for CLI usage
SDK Pattern:
import { HumanInputCheckProvider } from '../src/providers/human-input-check-provider';
import { CheckExecutionEngine } from '../src/check-execution-engine';
import { VisorConfig } from '../src/types/config';
// Define config inline
const config: VisorConfig = {
version: "1.0",
checks: {
"my-check": {
type: "human-input",
prompt: "Enter value:"
}
},
output: { pr_comment: { format: "markdown", group_by: "check", collapse: false } }
};
// Set custom hook
HumanInputCheckProvider.setHooks({
onHumanInput: async (request) => {
return await myCustomHandler(request);
}
});
// Run checks
const engine = new CheckExecutionEngine();
const results = await engine.executeChecks(prInfo, config, Object.keys(config.checks));Run the examples directly from the repo root:
# Basic retry + goto ancestor
npx -y @probelabs/visor@latest --config examples/routing-basic.yaml --output table
# on_success: run notify and jump back once to re-run unit-tests
npx -y @probelabs/visor@latest --config examples/routing-on-success.yaml --output table
# forEach remediation: mark missing items then retry
npx -y @probelabs/visor@latest --config examples/routing-foreach.yaml --output table
# Dynamic routing with *_js hooks
npx -y @probelabs/visor@latest --config examples/routing-dynamic-js.yaml --output tableNotes:
- These examples create small temporary files in the repo (prefixed with
.visor_demo_). Rungit clean -fdxor delete the files manually to reset. - The
routingblock supportsmax_loopsand default retry policies; step-level settings override defaults. - See
docs/failure-routing-rfc.mdfor full semantics.