CLI reference
This is a complete reference for all Viv commands and flags.
Commands
viv submit
Begin a non-interactive debugging analysis. This is the primary command for analyzing a failing test case.
viv submit \
--artifact-path <path> \
--code-directory <path> \
[options]
| Flag | Description |
|---|---|
--artifact-path, -a | (Required) Path to the logs directory from the failing test case. |
--code-directory, -c | Path to a code directory. Can be specified multiple times for multiple code roots. Defaults to the current directory if no -c, -f, or -F flags are given. |
--filelist, -f | Path to a VCS-style filelist (.f file) with paths resolved relative to the current working directory (or --filelist-cwd if specified). Can be specified multiple times. |
--filelist-relative, -F | Path to a VCS-style filelist (.f file) with paths resolved relative to the filelist's own directory. Can be specified multiple times. |
--filelist-cwd | Override the working directory used to resolve relative paths in -f/--filelist entries. |
--filelist-path-map | Remap file path prefixes in filelists. Format: /old/path:/new/path. The first matching mapping wins. Can be specified multiple times. Requires -f or -F. |
--viv-md | Path to explicit VIV.md file(s) for context (can be specified multiple times). This supplements any VIV.md auto-discovered in code directories and in ~/.viv/VIV.md, and is useful when VIV.md cannot be placed in the code directory itself. This file does not need to be named VIV.md. |
--spec | Path to specification files or directories (PDF, markdown, text). Can be specified multiple times. Directories are recursively enumerated. Short navigational files (TOCs, indexes) are inlined into the agent's prompt. New or stale specs are force-ingested into the knowledge store before the agent runs, and the agent's system prompt receives a section telling it to prefer querying these specs via spec_index_lookup / spec_text_search before reaching for other knowledge-store content. A force-ingest of new specs can add several minutes to startup; progress is printed inline. |
--wave-server-logs <path> | Path to write waveform server (Rascal) logs for debugging. |
--export-markdown | Path to write a Markdown-formatted report of the results. |
--log-file, -l | Write analysis log to the given file (overwrites existing file; creates directories as needed). |
--quiet / --no-quiet | Only show the latest tool call instead of all tool calls. Default: show all (i.e., --no-quiet). Can also be set via quiet in config.json. |
--exit-on-finish / --no-exit-on-finish | Exit immediately after analysis completes instead of entering chat. Requires --log-file or --export-markdown so results are captured. Can also be set via exit_on_finish in config.json. |
--effort <fast|balanced|thorough> | Reasoning effort mode. Controls how much the model "thinks" before responding. Overrides reasoning_effort in config.json. See Reasoning effort. |
--lang <en|ko> | Output language for the bug description and fix steps. The agent loop itself still reasons in English to preserve reasoning quality; only the final summary artifacts switch language. Overrides language in config.json. |
--debug-log <path> | Path to write an IP-scrubbed debug log for customer support diagnostics. Records tool calls, truncation events, and agent events with all user data redacted. |
--max-timeout <seconds> | Maximum timeout in seconds for waveform server requests (default: 30). Increase for large waveform files in non-interactive mode. Values below 30 are clamped to 30. |
--analysis-timeout <seconds> | Wall-clock timeout for the agent analysis loop (default: 1800 = 30 minutes). Increase when deep investigations on slower models hit the limit; you'll see "Analysis timed out after Ns" instead of a real result. Can also be set via analysis_timeout in config.json. |
--disable-lsp | Disable the SV language server (slang-server). |
--verbose | Enable verbose output, including full configuration details. |
viv swarm
Run a parallel multi-hypothesis investigation. Viv automatically generates 3–5 hypotheses about the failure (always covering RTL bugs, testbench bugs, and spec ambiguity), then spawns one investigator agent per hypothesis. After all investigators finish, a synthesizer reads their reports and produces a unified bug description and debugging narrative.
viv swarm \
--artifact-path <path> \
--code-directory <path> \
[options]
| Flag | Description |
|---|---|
--artifact-path, -a | (Required) Path to the logs directory from the failing test case. |
--code-directory, -c | Path to a code directory. Can be specified multiple times. |
--filelist, -f | Path to a VCS-style filelist (.f file) with paths resolved relative to the current working directory (or --filelist-cwd if specified). Can be specified multiple times. |
--filelist-relative, -F | Path to a VCS-style filelist (.f file) with paths resolved relative to the filelist's own directory. Can be specified multiple times. |
--filelist-cwd | Override the working directory used to resolve relative paths in -f/--filelist entries. |
--filelist-path-map | Remap file path prefixes in filelists. Format: /old/path:/new/path. The first matching mapping wins. Can be specified multiple times. Requires -f or -F. |
--viv-md | Path to explicit VIV.md file(s) for context (can be specified multiple times). Supplements any VIV.md auto-discovered in code directories and ~/.viv/VIV.md. |
--spec | Path to specification files or directories (PDF, markdown, text). Can be specified multiple times. Directories are recursively enumerated. New or stale specs are force-ingested before any hypothesis fires, and every investigator's system prompt receives a section telling it to prefer querying these specs via spec_index_lookup / spec_text_search. A force-ingest of new specs can add several minutes to startup; progress is printed inline. |
--wave-server-logs <path> | Path to write waveform server (Rascal) logs for debugging. |
--export-markdown | Path to write a Markdown-formatted report of the results. |
--log-file, -l | Write analysis log to the given file (overwrites existing file; creates directories as needed). |
--exit-on-finish / --no-exit-on-finish | Exit immediately after analysis completes instead of entering chat. Requires --log-file or --export-markdown. Can also be set via exit_on_finish in config.json. |
--effort <fast|balanced|thorough> | Reasoning effort mode. Overrides reasoning_effort in config.json. See Reasoning effort. |
--lang <en|ko> | Output language for the synthesized bug description and fix steps. Investigators and the synthesizer still reason in English; only the final summary artifacts switch language. Overrides language in config.json. |
--debug-log <path> | Path to write an IP-scrubbed debug log for customer support diagnostics. |
--max-timeout <seconds> | Maximum timeout in seconds for waveform server requests (default: 30). Increase for large waveform files. |
--analysis-timeout <seconds> | Wall-clock timeout for each investigator's analysis loop (default: 1800 = 30 minutes). Can also be set via analysis_timeout in config.json. |
--disable-lsp | Disable the SV language server (slang-server). |
--verbose | Enable verbose output. |
How it differs from viv submit:
viv submitruns a single agent that investigates one path at a time.viv swarmruns 3–5 agents in parallel, each exploring a different hypothesis. This is more thorough but uses more API tokens.
The RTL investigator focuses primarily on design code, and the testbench investigator focuses primarily on testbench/scoreboard code, so the investigations are largely uncorrelated.
After the swarm finishes, the chat phase works the same as viv submit — you can ask follow-up questions, and the chat has access to all investigator findings.
viv chat
Start an interactive chat session with access to your code and artifacts, without running the automated analysis first. Useful for asking questions about your design or testbench directly.
viv chat \
--artifact-path <path> \
--code-directory <path> \
[options]
| Flag | Description |
|---|---|
--artifact-path, -a | (Required) Path to the logs directory. |
--code-directory, -c | Path to a code directory. Can be specified multiple times. |
--filelist, -f | Path to a VCS-style filelist (.f file) with paths resolved relative to the current working directory (or --filelist-cwd). Can be specified multiple times. |
--filelist-relative, -F | Path to a VCS-style filelist with paths resolved relative to the filelist's own directory. Can be specified multiple times. |
--filelist-cwd | Override the working directory for resolving relative paths in -f/--filelist entries. |
--filelist-path-map | Remap file path prefixes in filelists. Format: /old/path:/new/path. Can be specified multiple times. Requires -f or -F. |
--viv-md | Path to explicit VIV.md file(s) for context (can be specified multiple times). Supplements any VIV.md auto-discovered in code directories and ~/.viv/VIV.md. |
--spec | Path to specification files or directories (PDF, markdown, text). Can be specified multiple times. New or stale specs are force-ingested at chat startup so a later /analyze in the same session sees the same flagged-specs section the agent would have gotten on viv submit --spec. A force-ingest of new specs can add several minutes to startup; progress is printed inline. |
--quiet / --no-quiet | Only show the latest tool call instead of all tool calls. Default: show all. |
--verbose | Enable verbose output. |
viv history
Browse and resume previous debugging sessions. Opens an interactive list of past analyses, sorted by most recent. Select an entry to view its results and continue chatting with full conversation context.
viv history
Analysis results are saved automatically and can be browsed and resumed from this command.
viv init
Generate a VIV.md file for your project. This creates a markdown document describing your repository's structure, which helps Viv debug more efficiently.
viv init \
--code-directory <path> \
[options]
| Flag | Description |
|---|---|
--artifact-path, -a | Path to logs directory (helps Viv understand log file formats). |
--code-directory, -c | Path to a code directory. Can be specified multiple times. |
--verbose | Enable verbose output. |
See Writing a VIV.md for guidance on getting the most out of VIV.md.
viv health
Check system health, including waveform reader availability and configuration status.
viv health [--json]
| Flag | Description |
|---|---|
--json | Output machine-readable JSON. Always exits with code 0 when this flag is set. |
viv license
Manage your Viv license.
viv license info # Show current license details
viv license add # Interactively install a license
viv mcp
Manage Model Context Protocol (MCP) server connections. MCP servers provide Viv with access to third-party data sources during analysis. Both the current Streamable HTTP transport and the legacy HTTP+SSE transport are supported; viv mcp add auto-detects which one a given server speaks.
viv mcp add <server-url> # Connect a new MCP server
viv mcp list # List connected servers (shows transport per server)
viv mcp remove <server-id> # Disconnect a server
viv mcp add probes the server's transport (Streamable HTTP or legacy SSE) and persists the choice; you don't need to specify it. See the MCP server setup section of the overview for more details.
viv knowledge
Viv's project knowledge store persists across sessions, helping the agent remember specification file locations, block-to-spec mappings, and codebase facts. Viv's knowledge should work without much manual intervention. However, we provide the following commands to manage the knowledge store.
viv knowledge init -a <artifact-path> # Interactive: discover project structure from a sample artifact
viv knowledge list # Summary table of all projects
viv knowledge list --project myproj # Detailed table for a specific project
viv knowledge list -c /path/to/code # Resolve project from directory, show details
viv knowledge list spec # All projects, specs only (hides zero-count)
viv knowledge status # Show knowledge store health and counts
viv knowledge status <spec> # Per-spec lifecycle (path or hash prefix)
viv knowledge add-spec <path> # Manually add a specification file
viv knowledge add-spec <path> --force-rescan # Re-ingest a spec from scratch
viv knowledge add-spec "<notion-url>" # Ingest a single Notion page
viv knowledge notion-connect # Connect Viv to Notion with an access token
viv knowledge remove-spec <path|hash> # Remove a spec by file path or hash prefix
viv knowledge list-workspaces # List Notion workspaces that have ingested specs
viv knowledge remove-workspace [name|key] # Remove all specs from a Notion workspace
viv knowledge reset # Clear all knowledge for the current project
viv knowledge init
viv knowledge init -a <artifact-path> runs an interactive walkthrough that uses the LLM to discover a project's structure from a sample artifact (a log file or a logs directory from a representative simulation). Viv reads the artifact, proposes code roots and specification files, asks you to confirm or edit each one, and writes the result into the knowledge store so future viv submit / viv swarm runs start with the project already populated.
viv knowledge init -a ./sim_output
Requirements and caveats:
- An interactive terminal is required. The walkthrough exits with an error when stdin is not a TTY.
- Not supported on the
claudecodeprovider. Useviv knowledge add-spec(and let bootstrap pick up code roots on the nextviv submit/viv swarmrun) instead. - The
-a/--artifact-pathargument is required. Pass either a single log file or a directory; Viv enumerates the directory and samples representative files. - The
--projectflag and-c/--code-directoryflags still apply: pass--projectto force a specific project name, or-cto seed the candidate code roots.
viv knowledge notion-connect
viv knowledge notion-connect stores a Notion access token so viv knowledge add-spec "<notion-url>" can ingest Notion pages. The command walks you through creating a token, validates it with a live API call, and saves it to ~/.viv/notion-key.txt (you can also supply it via the NOTION_API_KEY environment variable, which takes precedence).
Two kinds of token are accepted, and Viv detects which one you pasted automatically — you don't need to declare it:
- Internal integration token — reads only the pages you explicitly share with the integration, in a single workspace. This is the most restrictive (least-privilege) option. Share pages with it via a page's
•••menu → Connections. Teamspace pages work as long as you're a member; for pages outside your personal workspace and not in a Teamspace, the workspace owner must grant youFull Accesson the pages you want to ingest (otherwise use a PAT). If you don't see the option to share a page with the integration, clickEdit accessand search for the page by name. - Personal access token (PAT) — acts as your own Notion account, so Viv can read any page you can open, including pages shared with you that live in other people's workspaces, with no per-page sharing. More convenient, but it grants Viv the same read access you have, so treat it like a password. One current limitation: a PAT can't fetch images uploaded to Notion (only externally-hosted ones), so extracting image content from pages with uploaded images needs an integration token.
After a successful connection (and on the overwrite prompt when reconnecting), Viv reports which kind of token is configured and the workspace it is connected to. Error messages adapt to the token type — for example, a "page not found" on a PAT advises checking your account's access to the page rather than sharing it with an integration.
Workspaces
Ingested Notion specs are namespaced by the workspace they came from, and each is tagged with it (e.g. [ws: Silogy]) when you list a single project's specs with viv knowledge list --project <name>. (The top-level viv knowledge list shows only per-project counts, not per-spec labels.)
Workspaces are identified by Notion's stable internal workspace ID when it's available — the normal case — so renaming a workspace or rotating its token keeps your specs in place, and two different workspaces are told apart even if they share a name. The key Viv stores on disk is an opaque hash of that ID — the raw workspace ID is never written to disk, and the key itself contains no workspace name; the human-readable name is stored separately, in plaintext, only to produce the [ws: …] label. In the uncommon case where Notion returns no workspace ID, Viv falls back to a hash of the workspace name plus the token's identity: still stable and opaque, but a rename or a token-type switch can move it, and two distinct workspaces sharing both a name and an identity can't be told apart.
When you reconnect with a token for a different workspace, Viv simply notes the switch — the previous workspace's specs are kept and stay labeled. (Reconnecting to the same workspace, e.g. after rotating a token, is silent.) To remove a workspace's specs, use the explicit commands below.
viv knowledge list-workspaces provides a read-only listing of every Notion workspace that has ingested specs, with its name, opaque key, spec count, and how many projects it spans. The currently-connected workspace is marked. Nothing is written or fetched.
viv knowledge remove-workspace [name|key] removes all of a workspace's specs across every project that ingested from it. Pass a workspace name, or the opaque key from list-workspaces (use the key to disambiguate when two workspaces share a name). With no argument, Viv shows an interactive picker. Add --dry-run to preview exactly what would be removed without changing anything. The command asks for confirmation before deleting and auto-declines in a non-interactive (CI / piped) shell. A spec whose content is still referenced elsewhere (another workspace, another project, or an in-progress ingest) is kept; only the now-orphaned references are dropped. It also reclaims any cached image (under .notion-cache/images/) that no remaining spec references — see Extracting image content for the details.
Note: specs are kept separate on disk and labeled by workspace, but the agent still consults specs from every connected workspace during analysis — namespacing is for organization, provenance, and targeted removal, not for hiding a workspace from the agent.
Single-page ingest and fail-fast behavior
add-spec ingests only the page you pass — it does not descend into child pages. Any child pages are reported at the end with a ready-to-run add-spec command each, so you can ingest the ones you want individually.
Ingest is all-or-nothing: if any part of the page can't be captured, the command fails loudly and produces no spec rather than a partial one that looks complete. A page that can't be ingested whole fails on:
- a database embedded in or linked from the page (its rows can't be ingested yet);
- blocks not shared with your token, or a fetch that was truncated because the page is very large;
- an image that can't be downloaded, rendered, or read by the vision model.
When a re-ingest fails and the page has likely changed (or its content is now permanently uncapturable — a deleted/too-large image, a page that grew past the truncation limit), the previous spec is deleted and the failure says so. When the failure looks recoverable instead (a rate limit, an expired image link, a wrong/under-scoped token, a transient network error), the previous spec is kept and the message tells you it's untouched. Either way the command exits non-zero and prints exactly what to do next.
File attachments (PDFs, etc.), bookmarks, and embeds are not ingested — the page still ingests, and each is left in place in the captured text as a labeled reference marker (e.g. [PDF: <filename>], [Bookmark — external URL not resolved]) so the agent knows it's there, but its contents aren't pulled in.
Full database ingestion (rendering all rows into a table and following each row's page) is not implemented yet; an individual database row is itself a Notion page, so you can ingest one by opening that row as a full page and passing its link to add-spec.
Extracting image content from Notion pages
When you ingest a Notion page, images embedded in it (screenshots, diagrams, waveforms, tables rendered as images) are run through the configured model's vision capability and their content is transcribed into the page's text, in place of the original  reference. This lets the digested content include what an image actually shows — text inside a screenshot, the fields of a register layout, the states in a diagram — instead of a link the agent can't follow.
A few things to know:
- On by default: Pass
--no-imagesto skip it. With extraction off, each image is still replaced by a[Image: <filename>]placeholder (the caption is kept, the expiring URL is dropped) — there is just no transcribed content. The flag applies only to Notion page ingestion; passing it on a local-file spec (PDF, markdown, text) is rejected with an error, since those have no embedded page images to extract. - Re-enabling is automatic: If you ingest a page with
--no-imagesand later re-run it without the flag, Viv re-fetches and extracts that page's images even though the page itself hasn't changed — you do not need--force-rescanjust to add images you previously skipped. Only that page is re-ingested (and its digest re-runs, since the transcribed image text becomes part of the content); unchanged pages without pending images still skip. - Privacy: When extraction is enabled, the image bytes are sent to whichever LLM provider Viv is configured to use (the same provider as your analyses). If your Notion images are sensitive and you do not want them leaving your machine, run with
--no-images. - Cost: The transcription of each distinct image is cached, keyed on the image's content. Re-ingesting an unchanged page fires no vision calls, and editing a page only pays for the images that actually changed. Pass
--force-rescanto ignore the cache and re-extract every image on the re-ingested pages from scratch. - Automatic cleanup: Cached image bytes and transcriptions live per project under
.notion-cache/images/, content-addressed and shared across pages and workspaces. Bothviv knowledge remove-specandviv knowledge remove-workspacereclaim any cached image that no remaining spec references — removing a spec frees the images only it used, andremove-workspaceadditionally sweeps up orphans left by edited/superseded pages. An image shared by two specs (or two workspaces) survives the first removal and is freed only when the last spec referencing it is gone. - Provider support: Extraction needs a vision-capable model —
gpt-5.4,claude-sonnet-4-6, or any served vision-capable Llama / vLLM checkpoint. On a text-only model, extraction is skipped automatically with a one-line notice and the rest of the ingest proceeds. - Supported formats: PNG, JPEG, GIF, WEBP, SVG, and TIFF. (SVG and TIFF are converted to PNG first — see below.) Any other format — PDF, HEIC, BMP, and so on — can't be transcribed, so the ingest fails: the page holds content Viv can't capture, and a partial spec is never written.
- SVG, TIFF, and oversized images: Vector (SVG) and TIFF images are converted to PNG first; very large images are downscaled to fit the provider's limits, though one whose pixel dimensions exceed ~300 megapixels is refused before decoding rather than downscaled. An image that still can't be processed (
unsupported format,too large,svg render failed,tiff decode failed) fails the ingest with the reason named, and the previous spec for the page is deleted (the image, and so the page, has changed in a way that can't be captured). (Two size cases are treated as recoverable instead — an oversized WEBP, and an image over the ~300-megapixel limit; see below.) - Empty images: When the model reads an image but finds nothing readable in it, the image is marked
[Image: <filename> — no content detected](no transcribed text) and called out by name in the ingest output. This is not a failure — an empty image is genuinely empty, so the ingest still succeeds. It's surfaced so you can confirm a blank image (e.g. a decorative divider) was meant to be there. - Non-technical images: A purely decorative or branding image — a company logo, banner, icon, team photo, reaction GIF, or a photograph of something unrelated to the document (food, scenery, people) — is not transcribed in full. It's marked
[Image: <filename> — non-technical: <short label>](e.g.company logo) and called out by name in the ingest output, so a real figure the model misclassified is noticed rather than silently dropped. The classification is deliberately conservative: when the model is unsure whether an image is technical, or decoration is mixed with any technical content, it extracts the image in full. Like empty images, this is not a failure. (Images transcribed before this behavior existed keep their cached full descriptions until a--force-rescan.) - Recoverable image failures: A download that timed out, an expired signed URL, an attachment that couldn't be resolved (common when you're on a personal access token rather than an integration token), an image whose pixel dimensions exceed ~300 megapixels (reported as
dimensions too large— shrink it and re-ingest), or a WEBP over ~4.5 MB (which can't be downscaled, so it's reported aswebp too large— re-save it as PNG/JPEG or shrink it) fails the ingest but keeps the previous spec — these are usually fixed by a re-run, a format conversion, or by switching tokens, and the message says so. - Blocked image hosts: Viv does not fetch an image that targets a loopback (
127.0.0.1,localhost), link-local, or cloud-metadata (169.254.169.254) address — including a public URL that redirects to one — and fails the ingest with ablocked hostreason. Public image hosts are unaffected, as are images self-hosted on a private network (RFC1918 ranges such as10.x/192.168.xand internal hostnames are allowed).
viv knowledge add-spec flags
| Flag | Default | Description |
|---|---|---|
--show-cost-estimate | off | PDF ingest only. Print the projected pages + input/output tokens + approximate dollar cost before ingest starts. Independent of the confirm-prompt threshold below. |
--allow-low-tmpfs | off | PDF ingest only. Bypass the tmpfs preflight check. Useful when ingesting on a host with a small /tmp and you have separately verified there is enough room for the rendered page images. |
--no-images | off | Notion ingest only. Skip vision extraction of image content (see above). Image references become URL-free placeholders with no transcribed content. Rejected with an error if passed on a local-file spec (PDF/markdown/text), which has no page images to extract. |
A pre-ingest confirm prompt fires automatically (no flag needed) when projected input tokens exceed knowledge_pdf_confirm_above_tokens from config.json (default 5,000,000). The prompt blocks the ingest until you answer y; declining returns without touching disk.
viv knowledge status <spec>
Pass a spec path or a 6-char hash prefix (as displayed in citations or viv knowledge list output) to get a per-spec lifecycle summary. Useful when an ingest looks stuck or you need to know whether to resume vs. force-rescan.
Sample output:
spec: a1b2c3 (pcie5.pdf)
producer: agentic
status: in_progress_partial — paused at section 880 of ~1474, page 762
last attempt: 2026-05-11 14:23:11 UTC
last error: per-batch wall-clock timeout fired (recoverable; resumes next ingest)
lock entries: 880
last ingest cost: ~2.1M input + ~890K output tokens (480s)
Only counts and lifecycle metadata surface — no spec content is read.
viv submit / viv chat / viv swarm retrieval-side flag
| Flag | Default | Description |
|---|---|---|
--accept-partial | off | Suppress in_progress_partial warnings in spec MCP tool output. The agent treats completed sections of a partially-ingested spec as authoritative and stops routing them through code_pdf_reader (or the source-PDF Read tool, on the Claude Code path). Per-run flag — does not affect future ingests. |
When run without --project, viv knowledge list shows a summary table of all projects with counts for specs, mappings, and facts. Use --project <name> to see a detailed table for a single project, with columns for ID, type, age, confidence, source (core/extended), and description. Passing -c <dir> without --project resolves the project from that directory.
Spec quality grade
Each fully-ingested spec carries a quality grade in the detailed viv knowledge list view, rendered as a [X.X/10] prefix on the spec's description. The grade aggregates the agentic producer's per-section confidence reports: a spec where every section came back high-confidence scores 10/10; medium and low sections drag the score down. Specs that haven't been ingested yet (auto-discovered candidates, pending ingests, or failed runs) render with [not ingested] instead, so it's easy to scan the list for "what still needs work."
A score with a trailing asterisk (e.g. [8.7/10 *]) means the post-ingest cross-check sample fell below threshold and the score was downgraded — the producer self-reported high confidence but an independent vision check disagreed. Cross-check runs on every successful agentic PDF ingest by default (5 sampled sections, capped at 10% of the spec's section count). Set knowledge_spec_cross_check_sample_size to 0 in config.json to opt out — useful on cost-constrained or rate-limited providers.
Spec citation note in exported markdown
When the agent cites at least one section the producer flagged as non-high-confidence (extraction_confidence: medium or low), --export-markdown includes a one-line Spec citation note in the metadata section saying how many such sections were touched and telling the reader to verify against the source PDF before treating those citations as authoritative. The agent still cites the section inline as usual; the note is purely a trust-loop signal so a reader scanning the export knows which citations to re-check.
PDF ingest requires a vision-capable model
viv knowledge add-spec on a PDF hard-errors when the active model is text-only, when pdftoppm is not on PATH, or when no API key is configured for the active provider. The previous behavior fell back to a pdfjs+regex extractor that produced degraded ingests downstream investigations trusted without realizing they were degraded; that fallback is gone, so PDF ingest is now vision-LLM-only.
To recover, switch to a vision-capable model (gpt-5.4, claude-sonnet-4-6, or any served vision-capable Llama / vLLM checkpoint), install pdftoppm (poppler-utils), or configure the provider's API key — whichever the error message names — and re-run. Markdown and text-format specs are unaffected; they don't need vision.
Bulk-adding specs with an AI agent
There's no autodetect-and-ingest workflow. The recommended pattern for onboarding multiple specs at once is to have your AI agent (Claude Code, Cursor, etc.) do the orchestration:
"Find all spec PDFs and markdown files under
docs/specs/and runviv knowledge add-spec <path>on each one. Skip anything that's already ingested."
Viv is the primitive; the agent is the bulk-orchestrator. This avoids the false-positive risk of an automated spec sniffer and lets you keep direct control over what enters your knowledge store.
remove-spec accepts either a file path or a hash prefix. If the hash prefix is ambiguous (matches multiple entries), Viv will ask you to provide more characters. When given a file path, Viv resolves the spec's absolute path and matches it by hash.
Relative paths passed to add-spec and remove-spec are resolved against the current working directory, not the project root. If your cwd at removal time differs from the cwd at insertion time, pass an absolute path — or, more conveniently, pass a hash prefix from viv knowledge list.
Both add-spec and remove-spec automatically detect the correct project by checking which project's known code roots contain the spec file. This means you can run these commands from any directory — you don't need to cd into the project first. The --project flag still takes precedence if specified, and Viv falls back to CWD-based detection if no project's roots match.
add-spec short-circuits when a prior ingest of the same spec finished cleanly — re-running on an already-ingested file is a no-op. Pass --force-rescan to wipe the existing digest and re-ingest from scratch. Use this when a content change preserved the file's mtime (for example after cp -p, a filesystem snapshot, or a hand-edit that the staleness scan didn't catch), or when you want to re-run extraction with a newer Viv version. For Notion pages, --force-rescan also re-extracts image content (the per-image vision cache is otherwise reused across runs).
The knowledge store is enabled by default. See Knowledge store in the configuration reference for details and storage options.
viv version
Print the current Viv version.
viv version
viv help
Show help information and a list of available commands.
viv help
Global flags
These flags can be used with any command:
| Flag | Description |
|---|---|
--config <path> | Path to a config.json file (replaces $HOME/.viv/config.json). |
--license <path> | Path to a license file (replaces $HOME/.viv/license). |
--api-key <key> | API key value passed directly on the command line. |
--api-key-file <path> | Path to a file containing the API key. |
--theme <dark|light> | Color theme. Default: auto-detected from terminal. |
--effort <fast|balanced|thorough> | Reasoning effort mode. Overrides reasoning_effort in config.json. See Reasoning effort. |
--lang <en|ko> | Output language for the bug description and fix steps. Overrides language in config.json. |
--project <name> | Explicit project name for the knowledge store. Overrides automatic detection from git remote. |
--api-key and --api-key-file are mutually exclusive. Use one or the other, not both.
Interactive mode
Running viv with no arguments launches an interactive menu where you can select from available actions (Submit, Generate VIV.md, Manage MCP servers, etc.) and follow guided prompts.
viv
Chat phase
After viv submit or viv swarm completes, Viv enters an interactive chat phase where you can ask follow-up questions. You can also enter chat directly with viv chat.
Exiting chat
To exit the chat phase, type any of the following: exit, /exit, quit, /quit, :q, :quit, or :exit. You can also press Ctrl+C. (After viv submit or viv swarm, Esc from the chat input reopens the results viewer rather than exiting; use Ctrl+C to quit. In viv chat, where there are no results to return to, Esc still exits.)
Slash commands
During the chat phase (after viv submit completes, or in viv chat), you can type slash commands to trigger special actions.
/analyze [hypothesis]
Re-run the full debugging analysis on the same artifact and code directories, without leaving the current session. Optionally provide a hypothesis to steer the investigation.
/analyze
/analyze the issue might be in the write-back stage
Viv will show a confirmation prompt with the paths it will analyze. After you confirm, a fresh analysis runs and the conversation continues with the new findings. Previous analyses from the same session are summarized and passed to the new run so Viv avoids re-investigating the same ground.
/fix
Apply the suggested fix from the analysis directly to your source files. Viv runs a focused agent pass that reads the fix steps, edits source files in place using string replacement, and shows inline diffs of what changed.
/fix
If /fix-patch was run first in the same session, /fix applies the cached patch instead of re-running the agent.
After /fix completes, you can run /fix-patch to save the same diffs as a patch file without a second LLM call.
/fix-patch
Generate a .patch file from the analysis fix steps without modifying your source files. The agent runs against temporary copies, and the validated patch is saved to ~/.viv/fix-logs/.
/fix-patch
If /fix was run first in the same session, /fix-patch writes the cached diffs directly without re-running the agent.
After /fix-patch completes, you can run /fix to apply the patch to your source files without a second LLM call.
/wave-explore
Open the waveform viewer for the current artifact.
/export [path]
Export the current analysis to a Markdown file. Optionally provide a file path; defaults to bug.md in the current directory.
/export
/export ./reports/analysis.md
If export_template is set in config.json, the export is formatted by the LLM according to your template. See the configuration reference for details.
Non-interactive usage
--exit-on-finish
Use --exit-on-finish to make Viv exit immediately after analysis completes, skipping the interactive results view and chat phase. This is useful for batch workflows where you want to run Viv from an interactive terminal but don't need the chat.
At least one output sink is required so that results are captured: --log-file (-l) or --export-markdown.
# Exit after analysis, saving results to a log file
viv submit -a ./logs -c ./rtl -l ./output.log --exit-on-finish
# Exit after analysis, saving a Markdown report
viv submit -a ./logs -c ./rtl --export-markdown ./report.md --exit-on-finish
You can set this as the default in config.json with "exit_on_finish": true, and override it per-run with --no-exit-on-finish.
Headless mode
When Viv detects that it is running in a non-interactive environment (i.e., stdin is not a TTY), it automatically switches to headless mode. This works for both viv submit and viv swarm, and is designed for CI/CD pipelines and scripted workflows.
Behavior
- Progress messages are written to
stderrso they don't interfere with the report output. - The final Markdown report is written to
stdout. - Viv exits with code
0on success and1on failure. - Interactive prompts (chat) are skipped.
- For
viv swarm, hypothesis generation and per-investigator progress are logged tostderr. - Use
--log-file(-l) to capture the full analysis log to a file in addition to the stdout report.
Example: CI pipeline usage
# Run Viv in a CI pipeline, capturing the report
viv submit \
--artifact-path ./test-logs \
--code-directory ./rtl \
--code-directory ./tb \
> bug-report.md 2>viv-progress.log
Example: swarm in CI
# Run a parallel investigation in CI
viv swarm \
--artifact-path ./test-logs \
--code-directory ./rtl \
--code-directory ./tb \
> swarm-report.md 2>swarm-progress.log
Example: export alongside headless output
# Save the report to a file and also export Markdown
viv submit \
--artifact-path ./test-logs \
--code-directory ./rtl \
--export-markdown ./report.md \
> /dev/null
Reasoning effort
The --effort flag controls how much reasoning the LLM performs at each step. This maps to the model's native reasoning/thinking mechanism (e.g., OpenAI's reasoning.effort, Claude's thinking budget). Each mode sets per-task reasoning levels tuned for a different speed/quality tradeoff.
| Mode | Behavior |
|---|---|
fast | Minimal reasoning across all tasks. Faster and cheaper, but may miss nuances in complex bugs. |
balanced | Uses Viv's default reasoning levels for each task type. Good for most debugging tasks. |
thorough | Maximum reasoning across all tasks. Best for complex multi-signal bugs, but slower and more expensive. |
When no --effort flag is provided, Viv uses its built-in defaults for each internal task type (equivalent to balanced).
# Run a quick, cheaper analysis
viv submit --effort fast --artifact-path ./logs --code-directory ./rtl
# Run a thorough analysis for a complex bug
viv submit --effort thorough --artifact-path ./logs --code-directory ./rtl
# Override via config.json instead of the CLI flag
# See the configuration reference for details
The --effort flag takes priority over the reasoning_effort setting in config.json. See the configuration reference for the config-based alternative.