View as Markdown

Scripting and automationLink to Scripting and automation

Pass --json to get machine-readable output instead of a formatted table. The flag suppresses console formatting and writes exactly one JSON document to stdout, newline-terminated. Log lines still go to stderr or the service log. The default level is WARNING, so INFO lines appear only with -v. Add 2>/dev/null when you want stdout alone.

Every command accepts --json except server warmup.

Read ok, error, and the process exit code, plus any per-item results the command returns. The command reference lists each command’s options. This page lists the exit codes.

Examples use the installed-tool form and call vaultspec-rag directly. If vaultspec-rag is a project dependency, prefix each command with uv run; see the installation guide for lane selection, including the standalone tool and no-install routes.

Before you startLink to Before you start

You need vaultspec-rag installed and a project indexed. See Installation for setup and Getting started for indexing your first project.

search and index talk to the running service. With --port unset, they read the port from the discovery record (see Service discovery); pass --port N to target a specific service. An unreachable service returns the port_unreachable error rather than silently running the work in-process. Start the service with vaultspec-rag server start. See Service mode for the full walkthrough and Service discovery for how the lookup resolves.

The envelope shapeLink to The envelope shape

Every --json response is one JSON object with ok and command, except install and uninstall. Those two print the shared vaultspec envelope (schema, status, data); see machine-readable output. For every other command, success includes data; failure includes error and message and may retain partial results in data. Error envelopes may also carry port or a remediation array.

command is an identifier for the operation rather than the command path you typed, and it is not always the subcommand’s name: search reports search, but server jobs reports service.jobs. It is not stable across a single command’s outcomes either. index reports index on the dry-run envelope, and one of its failure paths - an unreachable service port - reports indexing instead. So match on it only against a value you have observed for the exact command and outcome you are handling, and never assume the success and error envelopes of one command agree.

Success, with most per-hit fields elided:

File contents

{
  "ok": true,
  "command": "search",
  "data": {
    "request_id": "fccd0f1fb63343078dbc8f683aa314be",
    "results": [
      {
        "id": "audit/graph-embedding-round36-audit",
        "path": ".vault/audit/graph-embedding-round36-audit.md",
        "title": "Round 36: Graph/Embedding Domain Audit",
        "score": 0.8315700888633728,
        "snippet": "...",
        "source": "vault",
        "doc_type": "audit",
        "feature": "gpu-rag-stack"
      }
    ]
  }
}

data carries more than the hits, and two of its fields answer questions a script would otherwise shell out for. via names what served the query, so a run that quietly fell back to the local store is visible without checking the service separately. index_state describes the index the query actually ran against: indexed_count, the root it was built from, and target_matches, which is false when the index belongs to a different tree than the one you asked about. search_type, query and summary echo the request, and timing breaks the run into phases.

Error. The capture below was taken against a service on port 8799, which is not the default: an unreachable service on a stock install reports 8766. The port field always echoes the port the CLI tried, so read it as the one your own run used rather than as a number to copy.

File contents

{
  "ok": false,
  "command": "search",
  "error": "port_unreachable",
  "message": "Service on port 8799 is unreachable. The CLI will not silently run search locally; start the service or re-run with --allow-fallback (one local user only).",
  "port": 8799,
  "remediation": [
    "vaultspec-rag server status",
    "vaultspec-rag server start",
    "rerun with --allow-fallback (one user only)"
  ]
}

Parse a search with jqLink to Parse a search with jq

With that shape in hand, a search reduces to one jq path:

Command

vaultspec-rag search "graph rebuild race" --json \
  | jq -r '.data.results[].path'

data.results holds one object per hit. The fields you will usually want are id, path, title, score, snippet, and source. Each object also carries the retrieval metadata for its domain, such as doc_type, feature, and date for vault hits, or language, line_start, line_end, function_name, and class_name for code hits. Fields that do not apply to a hit are null rather than absent, so jq paths stay stable across domains.

A vault hit’s snippet is the passage that best answers the query, up to about 1,200 characters, and line_start/line_end give the file lines that hold it. section names the headings it sits under, such as Implementation > Migration. Read those lines, not the whole record:

Command

vaultspec-rag search "why was an idle timeout rejected" --type vault --json \
  | jq -r '.data.results[] | "\(.path):\(.line_start)-\(.line_end)  \(.section)"'

A vault index built before these fields existed reports full_reindex_required until it is rebuilt with vaultspec-rag index --rebuild --type vault; until then its hits carry null spans and a snippet cut from the start of the chunk.

Detect success vs errorLink to Detect success vs error

ok is true on success and false on error. Gate further work on it:

Command

out=$(vaultspec-rag search "graph rebuild race" --json)
if ! echo "$out" | jq -e '.ok' >/dev/null; then
  echo "$out" | jq -r '.error + ": " + .message' >&2
  exit 1
fi

That gate is right for the commands that answer a question, such as search and index. It is not the whole verdict for the diagnostics. server doctor sets ok from whether the dependencies and the service are ready, and computes its exit code from a second axis - a dead daemon, a declared-versus-observed mode mismatch, a version floor - so a host whose dependencies are all ready and whose install mode has drifted reports ok: true and exits 1. Gate a diagnostic on its exit code, and read ok for what it says.

For index migration, a failed collection makes the command fail. Inspect data.results to distinguish copied collections from skipped ones. See the migration result contract.

The message field is written for people and gets reworded. Branch on the error code:

Command

case $(echo "$out" | jq -r '.error // empty') in
  port_unreachable)   echo "service unreachable; retry or start it";;
  local_store_locked) echo "another process holds the lock, aborting"; exit 1;;
  stopped)            echo "service not running, start it first"; exit 3;;
  "")                 echo "ok";;
esac

port_unreachable is retryable and exits 1. For search you can also pass --allow-fallback to run in-process against the on-disk store under .vault/data/. index has no --allow-fallback flag: an unreachable service is a hard failure there, and its remediation array lists only server status and server start. To index locally on purpose, use index --borrow-gpu. It takes a borrower lease, pauses a compatible running service, and runs the work in this process.

Indexing returns when the job is admitted, not when it finishesLink to Indexing returns when the job is admitted, not when it finishes

With a service running, vaultspec-rag index hands the work to the service as a background job and returns immediately. ok: true means the job was admitted. It does not mean anything has been indexed:

File contents

{
  "ok": true,
  "command": "index",
  "data": {
    "via": "service",
    "source": "combined",
    "outcome": {"ok": true, "partial": false, "status": "queued", "domains": {}}
  }
}

Note "status": "queued". A script that reads that response as “indexing succeeded” will pass while indexing is still running, and will keep passing if the job later fails.

To watch the work itself, poll vaultspec-rag server jobs --json and read data.jobs[], where each job carries id, state, and a progress object with step, completed, and total. progress can be null, for example before a job starts. To check the result instead, read the index counts with status, as the CI example does.

Worked example: gate CI on index healthLink to Worked example: gate CI on index health

Fail the build when the code index is empty, which usually means misconfigured ignore globs or source roots.

Ask status for the index counts. It reports what is stored, so it answers the question index leaves open: did the work finish?

Command

#!/usr/bin/env bash
set -euo pipefail

out=$(vaultspec-rag status --json)

if ! echo "$out" | jq -e '.ok' >/dev/null; then
  echo "status failed: $(echo "$out" | jq -r '.error')" >&2
  exit 1
fi

code_chunks=$(echo "$out" | jq '.data.code_count')

if [ "$code_chunks" -eq 0 ]; then
  echo "code index is empty; check ignore globs and source roots" >&2
  exit 1
fi

status --json also reports vault_count and document_count, the installation (role, hardware and compute capability), the project’s features, and storage details. Gate on whichever domain your project populates. A repository with no preprocessing hooks configured has document_count at 0 legitimately, and document_count can be null when the count is unavailable, so test for null before you compare it. The compute capability is a stable token such as ready, cpu_only_build or not_applicable, so a script can tell a broken GPU environment from a client that needs none.

Exit codes and error stringsLink to Exit codes and error strings

The exit code is the coarse signal; the error string names the specific failure.

Code

Meaning

0

success

1

generic failure, including port_unreachable

2

usage error, such as an option the command does not accept

3

service stopped

4

service crashed or divergent

5

service starting: models loading, not yet serving

install and uninstall add one meaning to 2: the run completed but skipped a step it required consent for, such as the PyTorch configuration patch nobody was there to approve. A failed install exits 1 like any other failure. See installation.

Code 5 is retryable; wait and re-run. The error field carries a code such as port_unreachable, local_store_locked, or stopped. The table above is the list of exit codes. The CLI reference lists each command’s options.

Automatic re-indexingLink to Automatic re-indexing

A watcher keeps the index fresh, so a scripted pipeline does not need to call index on every run. The running service re-indexes incrementally as files change, and it is on by default. For headless or containerized deployments, set VAULTSPEC_RAG_WATCH_ENABLED=0 to run pull-only. Inspect and tune it with the vaultspec-rag server updates verbs. See Service mode for the watcher in full and Configuration for the environment variables.

Where to go nextLink to Where to go next

For anything else, see Support and license in the repo README.