Skip to main content

CLI Reference — Vesanor

Complete reference for the vesanor command-line tool.


Installation

npm install -D @vesanor/cli

Run via npx:

npx vesanor [command] [options]

Commands

vesanor (default)

Run contracts against a provider. Reads config from .vesanor.yml, overridden by CLI flags.

npx vesanor
npx vesanor --provider openai --model gpt-4o-mini
npx vesanor --pack packs/my-pack --persist

vesanor init

Scaffold a new project with a config file and starter pack.

npx vesanor init

Creates:

  • .vesanor.yml — config file with defaults
  • packs/starter/ — a working contract pack

Skips files that already exist (never overwrites).

vesanor observe

Auto-generate contracts by observing live LLM behavior. Provide simple JSON observation specs (messages + tools), and Vesanor calls the provider, infers contract invariants from the response, and generates a full runnable pack.

npx vesanor observe --provider openai --model gpt-4o-mini
npx vesanor observe --provider anthropic --model claude-sonnet-4-6 --input specs/ --output packs/my-pack

Generated contracts have status: observed (draft) and must be reviewed before promotion to truth contracts. See the Observe Guide for the full workflow.

Observe-specific flags:

FlagDescriptionDefault
--provider <name>LLM provider: openai, anthropicRequired
--model <name>Model ID (e.g. gpt-4o-mini, claude-sonnet-4-6)Required
--input <dir>Directory containing observation spec JSON filesobserve/
--output <dir>Output directory for the generated packpacks/observed
--jsonForce JSON outputAuto-detect
--timeout_ms <ms>Timeout per provider call in milliseconds30000

Observation spec format:

Each .json file in the input directory defines one observation — the messages to send and the tools to make available:

{
"messages": [
{ "role": "user", "content": "What's the weather in San Francisco?" }
],
"tools": [
{
"name": "get_weather",
"description": "Get current weather for a location",
"parameters": {
"type": "object",
"properties": {
"location": { "type": "string" }
},
"required": ["location"]
}
}
]
}

Optional fields: tool_choice ("auto", "none", "required" — default "auto"), temperature (default 0), max_tokens (default 1024).

What gets generated:

For each successful observation:

  • contracts/<tool>.yaml — Contract with inferred invariants, marked status: observed
  • golden/<tool>.success.json — Golden fixture with boundary hashes
  • recordings/<tool>.success.recording.json — Recording file for replay

Pack-level files (generated once):

  • pack.yaml — Pack metadata listing all contracts
  • NeverNormalize.json — Standard normalization exclusions
  • nr-allowlist.json — Empty NR allowlist

Pretty output example:

  vesanor observe · openai/gpt-4o-mini · 3 specs

✓ get_weather → contracts/get_weather.yaml
✓ deploy_service → contracts/deploy_service.yaml
✗ send_email error: HTTP 401

2 contracts generated · 1 skipped

Next steps:
1. Review contracts in packs/observed/contracts/
2. Run: npx vesanor --pack packs/observed --provider recorded

vesanor promote

Promote an observed pack to a truth pack. Copies the pack directory and applies promotion transforms: removes status: observed from contracts, expands provider_modes to include live providers, and adds a promotion comment.

npx vesanor promote --from packs/observed --to packs/my-truth

Output:

Promoted packs/observed -> packs/my-truth

Next steps:
[ ] Review expect_tools — add/remove required tools
[ ] Review expected_tool_calls — tighten argument invariants
[ ] Adjust pass_threshold (currently 1.0)
[ ] Test: npx vesanor --pack packs/my-truth --provider openai --model gpt-4o
FlagDescriptionRequired
--from &lt;path&gt;Source observed pack directoryYes
--to &lt;path&gt;Destination truth pack directory (must not exist)Yes

After promoting, edit the contracts in packs/my-truth/contracts/ to tighten invariants. See the Promoting Contracts guide.

vesanor validate

Validate a pack's structure without running it. Checks that all files exist, contracts parse correctly, golden cases reference valid fixtures, and invariant paths are syntactically valid.

npx vesanor validate --pack packs/my-pack

Output:

Validating packs/my-pack...

pack.yaml OK
contracts/apt_triage.yaml OK
golden/apt_triage.success.json OK
recordings/ WARN: No recording files found.
NeverNormalize.json OK
nr-allowlist.json OK

Contract: apt_triage.yaml
expect_tools (6 tools) OK
expected_tool_calls (6 matchers) OK
pass_threshold: 0.85 OK
golden_cases (1 case) OK

Result: VALID (1 warning)
FlagDescriptionDefault
--pack &lt;path&gt;Pack directory to validateRequired
--jsonForce JSON outputAuto-detect

Exit codes: 0 = valid, 1 = errors found, 2 = usage error.

vesanor compare

Compare two run outputs side-by-side. Useful for evaluating whether a different model or provider is safer for your contracts.

npx vesanor --pack packs/my-truth --provider openai --model gpt-4o --json > /tmp/baseline.json
npx vesanor --pack packs/my-truth --provider openai --model gpt-4o-mini --json > /tmp/candidate.json
npx vesanor compare --baseline /tmp/baseline.json --candidate /tmp/candidate.json
FlagDescriptionRequired
--baseline &lt;path&gt;Path to baseline run JSON fileYes
--candidate &lt;path&gt;Path to candidate run JSON fileYes
--jsonForce JSON outputNo

vesanor sync

Sync reviewed contracts from the hosted dashboard to your local project. Downloads contracts, golden fixtures, and recordings into a vesanor/ directory. Uses content-addressed hashing to skip unchanged files.

npx vesanor sync                     # sync all contracts
npx vesanor sync --agent tax-router # sync single agent
npx vesanor sync --force # force re-sync (skip hash check)
FlagDescriptionDefault
--agent &lt;name&gt;Sync contracts for a specific agent onlyAll agents
--output &lt;dir&gt;Output directoryvesanor/
--forceSkip content-addressed hash check, re-download everythingfalse

Requires VESANOR_API_KEY.

vesanor doctor

Diagnose your Vesanor integration health. Checks local SDK state, hosted API connectivity, sync freshness, and produces a verdict.

npx vesanor doctor                         # full check
npx vesanor doctor --agent support-bot # check specific agent
npx vesanor doctor --no-network # local-only (skip hosted API)
npx vesanor doctor --hosted-only # hosted-only (skip local SDK)
npx vesanor doctor --strict # exit 1 on warnings
npx vesanor doctor --json # JSON output
FlagDescriptionDefault
--agent &lt;name&gt;Check a specific agentAll
--no-networkSkip hosted API checksfalse
--hosted-onlySkip local SDK checksfalse
--strictExit 1 on warnings (not just failures)false
--jsonForce JSON outputAuto-detect
--state_dir &lt;path&gt;Override SDK state directory.vesanor/runtime
--timeout_ms &lt;ms&gt;Hosted API request timeout10000

Exit codes: 0 = healthy, 1 = failures (or warnings with --strict), 2 = usage error.

vesanor models

List registered model families and aliases for a provider. Shows how model resolution works — which family patterns match, what request profile each family uses, and available shorthand aliases.

Also supports --check (registry coverage check against live provider API) and --probe (account model access check).

npx vesanor models --provider openai
npx vesanor models --provider anthropic
npx vesanor models --provider openai --json
npx vesanor models --check
npx vesanor models --provider openai --check
npx vesanor models --provider openai --probe
FlagDescriptionDefault
--provider &lt;name&gt;Provider: openai, anthropicRequired for list/probe
--checkCheck registry coverage against live provider APIfalse
--probeProbe account model access (accessible vs denied)false
--jsonForce JSON outputAuto-detect

--check fetches the provider's model listing API and tests each model ID against family patterns in the registry. Reports unmatched models. Exits non-zero if unmatched models are found. Without --provider, checks both OpenAI and Anthropic. Requires VESANOR_PROVIDER_KEY and/or ANTHROPIC_API_KEY.

--probe calls the provider API with your API key and reports which registered models (aliases and family matches) are accessible to your account vs denied. Useful for onboarding verification. Requires VESANOR_PROVIDER_KEY (or OPENAI_API_KEY / ANTHROPIC_API_KEY).

--resolve example (on the default run command, not models):

npx vesanor --provider openai --model 5.2 --resolve
  Model Resolution

Input: 5.2
Provider: openai
Resolved: gpt-5.2
Family: GPT-5
Source: alias
Token field: max_completion_tokens
Temperature: yes

Exits immediately after printing — no contracts are run. Useful for verifying how an alias or raw model ID resolves before committing it to .vesanor.yml.

Pretty output example (models --provider):

OpenAI — Registered Families

GPT-5 family match: ^gpt-5
token field: max_completion_tokens
temperature: yes

GPT-4 family match: ^gpt-4
token field: max_tokens
temperature: yes

O-series (reasoning) match: ^o[1-9]
token field: max_completion_tokens
temperature: no

Aliases:
5.2 → gpt-5.2
4o-mini → gpt-4o-mini

Any model matching a family prefix works automatically.
Unregistered models pass through with provider defaults.

vesanor help

Show help text with all flags and examples.

npx vesanor --help
npx vesanor -h
npx vesanor help

vesanor drift

Run drift detection against the current baseline.

npx vesanor drift

vesanor export-bundle

Export a replay bundle for offline verification.

npx vesanor export-bundle

vesanor replay-bundle

Replay a previously exported bundle.

npx vesanor replay-bundle

Options

Provider & model

FlagDescriptionDefault
--provider &lt;name&gt;LLM provider: openai, anthropic, recordedFrom .vesanor.yml
--model &lt;name&gt;Model ID or alias (e.g. gpt-4o-mini, opus-4, 5.2)From .vesanor.yml
--pack &lt;path&gt;Path to contract pack directorypacks/starter
--strict-modelFail if model has no matching family (instead of passthrough)false
--resolvePrint model resolution details and exit (no run)false

Execution

FlagDescriptionDefault
--persistWrite run artifacts to diskfalse
--capture-recordingsSave live responses as recordings/*.recording.jsonfalse
--draftRun observed contracts against live providers (skip provider_modes filter)false
--repeat &lt;n&gt;Run N times for determinism proof1
--only_contracts &lt;csv&gt;Filter to specific contract filenames (comma-separated)All contracts
--jsonForce JSON output (default for non-TTY)Auto-detect

Identity

FlagDescriptionDefault
--tenant_id &lt;id&gt;Tenant identifiert_default
--run_mode &lt;mode&gt;Run mode: manual, scheduled, cimanual

Timeouts & limits

FlagDescriptionDefault
--timeout_ms &lt;ms&gt;Timeout per contract in milliseconds30000
--retry_cap &lt;n&gt;Maximum retry attempts2
--max_contracts &lt;n&gt;Limit number of contracts to runAll

Shadow mode

FlagDescription
--shadow-captureEnable shadow capture for live provider runs
--shadow-provider &lt;name&gt;Shadow provider for comparison (openai, anthropic)
--shadow-model &lt;name&gt;Shadow model for comparison

Other

FlagDescription
--artifact_root &lt;path&gt;Override artifact storage directory
--side_effect_mode &lt;mode&gt;read_only or allow_all

Pushing to Dashboard

Set VESANOR_API_KEY to automatically push every run result to the hosted dashboard at app.vesanor.com:

export VESANOR_API_KEY=vsn_your_key_here
npx vesanor --pack packs/my-pack --provider openai --model gpt-4o-mini

Results appear in your dashboard within seconds. No additional flags needed — push is automatic when the API key is set.

  • Push is independent of --persist--persist writes artifacts to local disk (requires a database). Dashboard push works without it.
  • Push failure is non-fatal — if the push fails (network error, invalid key), the run still completes and results are printed to stdout. A warning is emitted to stderr.
  • Override the API URL with VESANOR_API_URL for self-hosted setups.

Get your API key from app.vesanor.com/signup or from Settings > API Keys in the dashboard.


Environment variables

VariableDescriptionRequired
VESANOR_API_KEYAPI key for pushing results to the dashboard (see above)For dashboard push
VESANOR_PROVIDER_KEYProvider API key (OpenAI or Anthropic)For live provider runs
OPENAI_API_KEYOpenAI API key (fallback if VESANOR_PROVIDER_KEY not set)Alternative for OpenAI
ANTHROPIC_API_KEYAnthropic API key (fallback if VESANOR_PROVIDER_KEY not set)Alternative for Anthropic
VESANOR_API_URLOverride API base URLNo (default: https://app.vesanor.com)
DATABASE_URLPostgreSQL connection string (local dev only)For local DB persistence

API keys always come from environment variables — never from .vesanor.yml or CLI flags.


Config file

Vesanor reads .vesanor.yml from the project root. CLI flags override config values.

pack: "./packs/starter"
provider: openai
model: gpt-4o-mini
persist: false
capture_recordings: false
draft: false
tenant_id: t_default
run_mode: manual
observe_input: "./observe"
observe_output: "./packs/observed"

All fields are optional. Missing fields use defaults.

Resolution order: CLI flags > .vesanor.yml > built-in defaults.


Output formats

Pretty (default for TTY)

  vesanor · openai/gpt-4o-mini · 4 contracts

✓ tool_call Pass a3f82c91
✓ function_call Pass b7d104e3
✓ structured_output Pass c9a2f156
✗ error_handling Fail e1b3d478 ← schema_payload

3/4 passed · 1 failed

results → https://app.vesanor.com/runs/r_8f3a2c

Each line shows: status indicator, contract name, pass/fail, 8-character fingerprint, and optional failure category.

The results → line appears when VESANOR_API_KEY is set and results are pushed to the dashboard.

JSON (default for pipes/CI, or --json)

Full structured output including traceability, step details, and all metadata. Suitable for parsing in CI pipelines.

npx vesanor --json | jq '.provider_run.steps[0].state'

Dashboard push

When VESANOR_API_KEY is set and a provider run completes, results are automatically pushed to the hosted dashboard at https://app.vesanor.com.

  • Push is independent of --persist — both can run simultaneously
  • Push failure warns to stderr but does not affect the exit code
  • Override the API URL with VESANOR_API_URL for local development

Determinism proof

Run contracts multiple times and compare fingerprints:

npx vesanor --repeat 3

Output includes a determinism_proof object showing whether each step produced identical fingerprints across all runs. Useful for verifying that provider responses are stable.


Exit codes

CodeMeaning
0All contracts passed
1One or more contracts failed, or a runtime error occurred
2Drift detection or unknown-rate gate failure

Examples

# Initialize a new project
npx vesanor init

# Run with defaults from .vesanor.yml
npx vesanor

# Run against OpenAI with a specific model
npx vesanor --provider openai --model gpt-4o-mini

# Run against Anthropic
npx vesanor --provider anthropic --model claude-sonnet-4-6

# Use model aliases (shorter names)
npx vesanor --provider openai --model 5.2
npx vesanor --provider anthropic --model opus-4

# Check how a model alias resolves
npx vesanor --provider anthropic --model opus-4 --resolve

# Strict mode: fail if model is not in registry
npx vesanor --provider openai --model gpt-4o-mini --strict-model

# List registered models and aliases for a provider
npx vesanor models --provider openai

# Check registry coverage against live provider API
npx vesanor models --check

# Check account model access
npx vesanor models --provider openai --probe

# Run against recorded fixtures (offline, deterministic)
npx vesanor --provider recorded

# Run specific contracts only
npx vesanor --only_contracts tool_call.yaml,function_call.yaml

# Prove determinism with 3 identical runs
npx vesanor --repeat 3

# Force JSON output for CI
npx vesanor --json

# Run and persist to local disk
npx vesanor --persist

# Capture live responses as recording files for replay
npx vesanor --provider openai --model gpt-4o-mini --capture-recordings

# Test observed contracts against a live provider without promoting first
npx vesanor --pack packs/observed --provider openai --model gpt-4o-mini --draft

# Shadow comparison: OpenAI primary, Anthropic shadow
npx vesanor --provider openai --model gpt-4o-mini \
--shadow-capture --shadow-provider anthropic --shadow-model claude-sonnet-4-6

# Auto-generate contracts from observation specs
npx vesanor observe --provider openai --model gpt-4o-mini

# Generate contracts with custom input/output directories
npx vesanor observe --provider anthropic --model claude-sonnet-4-6 \
--input specs/ --output packs/anthropic-observed

# Run the generated pack against recorded fixtures
npx vesanor --pack packs/observed --provider recorded

# Promote an observed pack to a truth pack
npx vesanor promote --from packs/observed --to packs/my-truth

# Validate pack structure without running
npx vesanor validate --pack packs/my-truth

# Compare two model runs
npx vesanor compare --baseline /tmp/gpt4o.json --candidate /tmp/gpt4o-mini.json

# Sync contracts from dashboard
npx vesanor sync

# Check integration health
npx vesanor doctor

# Show help
npx vesanor --help