CLI reference#
ovellum <subcommand> [flags]
Run via npx ovellum, via the package binary after install, or via your
package manager's task runner.
Subcommands#
| Subcommand | Status | Summary |
|---|---|---|
init | available | Scaffold a new project (config + starter content + .gitignore entry). |
build | available | Run the configured pipeline (parse + generate + merge, or build a site). |
diff | available | Compare current source against the last build's IR snapshot — preview what a rebuild would change. |
dev | available | Build, watch, serve, and live-reload connected browsers — the one-command dev loop. |
watch | available | Build, then rebuild on every change under input/ (debounced 300 ms). |
serve | available | Serve the built site over HTTP. No watch, no live reload. |
check | available | Validate config + check for broken internal links + flag unsafe URLs. |
upgrade | available | Check npm for a newer Ovellum and install it. |
orphans | available | List quarantined manual blocks (with --stale / --json). |
agents | available | Add or refresh the canonical "Ovellum docs" section in AGENTS.md / CLAUDE.md (idempotent; --check for CI). |
mcp | available | Run Ovellum as an MCP server over stdio so an AI agent can drive it. |
clean | available | Remove auto-generated outputs while preserving manual files (dry-run by default). |
snapshot | available | Freeze the current docs as a version: copy the latest content into <input>/<id>/ and print the config entry to add. |
ovellum init#
Scaffold a new project in the current (or given) directory. Refuses to
clobber an existing ovellum.config.json unless --force is passed.
Synopsis#
ovellum init [--cwd <dir>] [--yes] [--force]
Flags#
| Flag | Type | Default | Notes |
|---|---|---|---|
--cwd <dir> | path | process.cwd() | Project root. |
--yes, -y | boolean | false | Non-interactive: accept every default. Useful in CI / smoke tests. |
--force | boolean | false | Overwrite an existing ovellum.config.json. By default the command exits with 2. |
Prompts (interactive)#
- Project name — defaults to
package.json#nameor the folder name. - Mode —
manual(default),auto, orhybrid. - Site title — defaults to a title-cased project name.
- Description — used for
<meta name="description">. - (manual) Content dir / Output dir / Generate landing page?
- (auto / hybrid)
tsconfig/ Output dir. - Default theme —
auto,light, ordark.
Output#
Writes only files that don't already exist (unless --force):
ovellum.config.json<input>/index.md(manual + hybrid modes only) with a friendly starter.AGENTS.md— mode-aware instructions for AI coding agents (the protected-zone contract + commands). See Automation. When anAGENTS.mdalready exists, only the canonical "Ovellum docs" section is added or refreshed — the same upsert asovellum agents..gitignore— appends<output>/and.orphans/if absent.
Prints a numbered next-steps list keyed to the chosen mode.
Exit codes#
| Code | Meaning |
|---|---|
0 | Project initialized. |
2 | ovellum.config.json already exists; re-run with --force to replace. |
130 | User canceled the prompts (Ctrl-C). |
ovellum build#
Resolves the project's ovellum.config.*, runs the configured pipeline,
writes output to disk, prints a summary.
Synopsis#
ovellum build [--cwd <dir>] [--config <path>] [--drafts] [--out <dir>] [--base <path>] [--manifest]
Flags#
| Flag | Type | Default | Notes |
|---|---|---|---|
--cwd <dir> | path | process.cwd() | Project root. All paths in the config resolve relative to this. |
--config <path> | path | auto-discovered | Skip discovery and load this file directly. |
--drafts | flag | off | Include draft pages (normally excluded from a production build). |
--out <dir> | path | output config | Override the output directory for this build, without editing the config — point a CI/deploy pipeline at any folder (e.g. a repo's /docs). |
--base <path> | path | site.basePath | Override the base path the site is served from (e.g. /docs). Same effect as site.basePath, per-invocation. |
--manifest | flag | off | Write <output>/.ovellum/manifest.json — a hashed inventory of every built file (path, bytes, sha256) so a deploy tool can push only what changed and verify completeness. |
--json | flag | off | Emit the build summary as JSON (for CI / tooling); no decorative output. See Automation. |
--verbose | flag | off | Print config-resolution and per-stage / file-I/O detail to stderr (stdout is unchanged, so it composes with --json). |
Behavior by mode#
auto#
- Parse
input/to aDocProjectIR. - Render IR to Markdown.
- Write each output, overwriting any existing file.
hybrid (default)#
Same as auto, then for each generated file:
- If the existing output file is present, read it.
- If it carries
<!-- @manual:start -->blocks, run the merger. - Any block whose anchor no longer exists is written to
protect.orphanDir.
manual#
- Walk
input/for.mdfiles. - Render each to HTML (Markdown is sanitized — see Security).
- Build a sidebar nav and breadcrumb trail.
- Wrap each page in the default template (topbar, sidebar, ToC, prev/next, page meta).
- Write pretty URLs to
output/. - Copy
assets/ovellum.css+assets/ovellum.jsfrom the bundled template. - When
site.baseUrlis set, emitsitemap.xmlandfeed.xml. - When
site.search.enabledistrue, run Pagefind against the output and emitdist/pagefind/. - Emit AI-friendly output —
llms.txt, per-page.mdmirrors (andllms-full.txtif enabled). On by default; controlled bysite.ai.
Summary output#
Auto / hybrid#
ovellum build complete in 207ms
config: .../ovellum.config.json
mode: hybrid
sources: 2 ← input files parsed
written: 2 file(s) ← Markdown files written
merged: 1 file(s) ← hybrid only: files where a manual block was spliced
orphans: 0 ← hybrid only: blocks whose anchor disappeared
warnings: 0 ← real problems to act on (severity "warning")
notes: 1 ← benign notes (severity "info"); shown only when > 0
→ docs/format.md
→ docs/user.md
quarantined: ← only printed when orphans > 0
↪ .ovellum/orphans/2026-05-15_src-format.ts-padZero.md
ir: .ovellum/ir.json ← parsed IR snapshot, written every auto/hybrid build
Diagnostics are split by severity: warnings: counts real problems (orphaned
content, an asset skipped for safety, an unparseable date), notes: counts
benign info (drafts excluded, sitemap.xml skipped for a missing
site.baseUrl). Below the summary each is printed as a warning: / info:
line — real problems first, so they're never buried. --json carries the
same { message, severity } shape (see Automation).
Every auto/hybrid build also writes its parsed IR to .ovellum/ir.json at the
project root (beside .ovellum/orphans/) — a snapshot of the symbols, anchors,
and signatures it just read. It's build state, not deploy output, so it stays
at the project root regardless of --out, and .ovellum/ is gitignored by the
default scaffold. It's the foundation for upcoming source-diff, rename
detection, and anchor last-seen tracking; you can also read it yourself for any
tooling that needs a structured view of your API surface.
Manual#
ovellum build complete in 207ms
config: .../ovellum.config.json
mode: manual
output: dist/
pages: 5
warnings: 0
→ / (dist/index.html)
→ /configuration/ (dist/configuration/index.html)
→ /getting-started/ (dist/getting-started/index.html)
→ /guides/deploying/ (dist/guides/deploying/index.html)
→ /guides/theming/ (dist/guides/theming/index.html)
manifest: dist/.ovellum/manifest.json ← only with --manifest
Exit codes#
| Code | Meaning |
|---|---|
0 | Success. |
1 | Build error (parser failure, write failure, unknown mode). |
2 | Reserved for --strict (warnings promoted to errors). |
3 | ConfigError — config schema invalid, file not found, etc. |
stderr carries per-warning lines (warning: …). stdout carries the summary.
Examples#
# Build from the current directory
npx ovellum build
# Build a different project
npx ovellum build --cwd ./website
# Bypass config discovery
npx ovellum build --config ./config/ovellum.prod.ts
# Deploy-anywhere: build into a repo's /docs folder with a deploy manifest
npx ovellum build --out ./docs --base /docs --manifest
ovellum diff#
Compare the current source against the IR snapshot written by the last
build (.ovellum/ir.json) and report what a rebuild would change — added,
removed, and changed symbols, plus which output docs they'd touch. Writes
nothing; it's a preview, not a build. Auto/hybrid only (manual builds parse no
source and keep no IR).
It matches symbols by their stable anchor id. When an anchor disappears and a similar symbol appears (same kind, similar name, same signature shape), the two are paired as a likely rename instead of an unrelated removal + addition — the suggestion you'd act on after a refactor. Cosmetic edits that only shift line numbers are ignored — a change is reported only when the documented surface (signature, params, return, description, deprecation, JSDoc tags, export/visibility) actually differs.
Synopsis#
ovellum diff [--cwd <dir>] [--config <path>] [--json] [--exit-code]
Flags#
| Flag | Type | Default | Notes |
|---|---|---|---|
--cwd <dir> | path | process.cwd() | Project root. |
--config <path> | path | auto-discovered | Skip discovery and load this file directly. |
--json | boolean | false | Emit the diff as JSON ({ baselineGeneratedAt, added, removed, changed, renames, docs, hasChanges }) for CI / tooling. |
--exit-code | boolean | false | Exit 1 when changes are found (git-diff style). Without it, diff always exits 0 so it can be run informationally. |
--verbose | boolean | false | Print config-resolution and snapshot detail to stderr. |
Output#
ovellum diff — current source vs .ovellum/ir.json (built 2026-06-24T17:58:46.322Z)
+ 1 added - 0 removed ~ 1 changed → 1 renamed
likely renames:
→ src/date.ts::formatDate → src/date.ts::formatDateUTC (97%)
added:
+ src/math.ts::mul (function)
changed:
~ src/math.ts::add (function) signature, params
docs that would change:
~ docs/math.md (+1 ~1 -0)
When nothing differs:
ovellum diff — no changes since the last build (.ovellum/ir.json, <timestamp>).
Exit codes#
| Code | Meaning |
|---|---|
0 | Success — no changes, or changes printed without --exit-code. |
1 | Changes found with --exit-code, or no/unreadable snapshot to compare. |
3 | ConfigError — config schema invalid, file not found, etc. |
Example#
# See what a rebuild would change
npx ovellum build # records the baseline snapshot
# ...edit source...
npx ovellum diff # preview the impact
# Fail CI if docs would drift from source
npx ovellum diff --exit-code
ovellum dev#
The combined build + watch + serve + live-reload loop. The one command you want running while writing.
Synopsis#
ovellum dev [--cwd <dir>] [--config <path>] [--port <n>] [--host <addr>] [--no-drafts] [--verbose]
Flags#
| Flag | Type | Default | Notes |
|---|---|---|---|
--cwd <dir> | path | cwd | Project root. |
--config <path> | path | auto | Skip discovery and load this file directly. |
--port <n> | integer | 3000 | Starting port. If busy, auto-bumps up to 19 ports forward before giving up. |
--host <addr> | string | 127.0.0.1 | Bind address. Pass 0.0.0.0 to expose on the local network. |
--no-drafts | flag | drafts on | Hide draft pages locally, to preview exactly what production publishes. (watch takes --no-drafts too.) |
--verbose | flag | off | Log each request served as METHOD path → status (handy when debugging routing or 404s). |
Behavior#
- Loads the config and resolves
config.output(the build'sdist/dir). - Starts an HTTP server bound to
--host:--port. - Runs an initial build, then watches
input/and the config file for changes (same debounce asovellum watch— 300 ms). - On every successful rebuild, pushes a
reloadevent over Server-Sent Events to every connected browser tab; the injected client script callslocation.reload(). Ctrl-Cshuts down both the watcher and the server cleanly.
The injected reload script is added only for HTML responses, only when
dev is the running command. ovellum build output is never modified.
Output#
ovellum dev starting from .../ovellum.config.json
built 17 page(s) in 720ms
watching content for changes…
local: http://127.0.0.1:3000/
press Ctrl-C to exit.
After a save:
changed: content/getting-started.md
built 17 page(s) in 60ms
Exit codes#
| Code | Meaning |
|---|---|
0 | Clean shutdown (Ctrl-C). |
1 | Mode unsupported. dev is manual-only because auto/hybrid produce .md, not browsable HTML. Use ovellum watch for those modes. |
3 | Config invalid. |
Examples#
# Default: localhost:3000
npx ovellum dev
# Pick a port
npx ovellum dev --port 4000
# Expose to the LAN (useful for mobile testing)
npx ovellum dev --host 0.0.0.0
# Multi-site monorepo
npx ovellum dev --cwd ./website
ovellum serve#
Pure static-file server, no watching. Useful for previewing a production build exactly as it'll be served, or wiring into a process manager that handles rebuilds elsewhere.
Synopsis#
ovellum serve [--cwd <dir>] [--config <path>] [--port <n>] [--host <addr>]
Flags are identical to ovellum dev. The server reads from
config.output; if that directory doesn't exist, serve exits with
1 and points you at ovellum build or ovellum dev.
Differences vs. ovellum dev#
dev | serve | |
|---|---|---|
| Initial build | yes (via watcher) | no — requires existing dist/ |
| Watches files | yes | no |
| Injects reload script | yes | no |
| Cache headers | no-store | public, max-age=0 |
If you only want the server (e.g. you're running ovellum watch in
another shell yourself), serve is the right command.
ovellum check#
Validation pass only — no writes. Loads config, walks every .md file
under input/, extracts links via remark (so fenced code blocks are
correctly ignored), and verifies:
- Every internal link resolves to a real page URL in the sidebar nav.
- No link uses an unsafe URL scheme (
javascript:,vbscript:,data:,file:). Even thoughrenderMarkdownstrips these at render time,checkflags them here so authors can remove them at the source. - Every
::includetarget exists (resolved like the build: the page's locale tree first, then the default locale's) and stays inside the content directory. - On i18n sites (two or more
site.locales), translations are in sync with their source page — see Translation staleness.
Synopsis#
ovellum check [--cwd <dir>] [--config <path>] [--update-translations] [--json] [--strict]
Flags#
| Flag | Type | Default | Notes |
|---|---|---|---|
--cwd | string | cwd | Project root. |
--config | string | — | Path to ovellum.config.{ts,js,json}. |
--update-translations | boolean | false | Stamp each translated page's sourceHash to the current source, then exit. See below. |
--json | boolean | false | Emit results (or stamping outcome) as JSON; exit code unchanged. See Automation. |
--strict | boolean | false | Run extra validations — off by default. Any strict issue exits 1 like the rest. |
--verbose | boolean | false | Print config-resolution and scan detail to stderr. |
Strict mode (--strict)#
--strict adds three opt-in validations on top of the defaults:
- Positional protected zones — a
<!-- @manual:start -->with noid=. Id-less zones fall back to positional matching, so reordering can lose them; addid="...". (hybrid / auto) - Stale anchors — a
<!-- ovellum:anchor id="…" -->in a generated doc whose symbol no longer exists in the source (a delete or unrebuilt rename). Rebuild, or reattach the prose. (hybrid / auto) - Title-less pages — a page with neither a frontmatter
title:nor a top-level# heading, so it has no real title. (manual)
Strict issues are tagged [STRICT] in the output and counted under
strict issues: (and counts.strictIssues in --json).
Output#
Clean:
ovellum check complete in 76ms
config: .../ovellum.config.json
mode: manual
pages: 14
broken links: 0
unsafe schemes: 0
With issues:
ovellum check complete in 87ms
config: .../ovellum.config.json
mode: manual
pages: 14
broken links: 1
unsafe schemes: 1
details:
content/getting-started.md:42 [SECURITY] unsafe URL scheme 'javascript:' — link will be stripped by the HTML sanitizer (raw: javascript:alert(1))
content/getting-started.md:112 broken internal link to /no/such/page/ (raw: /no/such/page/)
Exit codes#
0clean1one or more issues found3config invalid
Behavior by mode#
Manual mode — walks input/ for .md files and validates every
internal link against the sidebar nav. On i18n sites this runs per-locale:
each content/<code>/ subtree builds its own locale-prefixed nav, and links are
checked against the union of all locales' URLs — so a /ja/… link, a
cross-locale /docs/… link to the default locale, and relative links all
resolve correctly.
Hybrid / auto mode — walks the output directory (the
auto-generated Markdown), validates every internal link against the
actual files on disk, and flags unsafe URL schemes the same way.
If the output dir doesn't exist, check exits 1 with a hint to
run ovellum build first.
Title-checking and id-less / stale-anchor validation are available via
--strict; orphan listing lives in
ovellum orphans.
Translation staleness#
On a site with two or more site.locales, check also verifies that each
translated page is in sync with the default-locale page it mirrors (matched by
identical path across the locale folders). Each translation carries a
sourceHash in its frontmatter — a fingerprint of the source page's body
(frontmatter excluded, line endings normalized). check recomputes it and
reports, tagged [i18n]:
- a translation whose source changed since it was stamped (stale);
- a translation missing its
sourceHash(never stamped); - a translation with no matching source page (orphan).
Any of these counts as an issue, so check exits 1 — CI catches drift. To
stamp (or re-stamp) the hashes after syncing a translation, run:
ovellum check --update-translations
It writes the current sourceHash into every translated page — touching only
that one frontmatter line — and exits 0. See the
i18n guide for the workflow.
ovellum watch#
Build, then watch input/ (and the config file) for changes and rebuild
on every change. Debounced at 300 ms with chokidar's
awaitWriteFinish enabled so partial writes don't trigger a half-state
rebuild. Works in every mode (manual, hybrid, auto) — the watcher
dispatches to the right build path automatically.
For the common "rebuild + serve + auto-refresh" loop (manual mode), you
almost certainly want ovellum dev instead. watch is
the primitive — useful when you want to run a different server (a CDN
emulator, a reverse proxy, your own process manager), pipe build
notifications somewhere, or you're in auto / hybrid mode (no HTML to
live-reload, just regenerated Markdown).
Synopsis#
ovellum watch [--cwd <dir>] [--config <path>]
Behavior#
- An initial build runs once on start.
- Changes to any file under
input/re-trigger the same pipeline. - Incremental rebuilds (auto / hybrid). After the first build, the watcher keeps the parser warm and re-parses only the files you changed, then rebuilds only the docs whose content actually changed — much faster on large codebases. The persisted IR snapshot still reflects the whole project, and hybrid protected zones are preserved exactly as in a full build. (Manual mode rebuilds the whole site, as before.)
- Changes to the config file itself reload it before the next build (and reset the warm parser, since include/exclude globs may have moved).
Ctrl-Cshuts the watcher down cleanly.
No HTTP server, no live reload — pair with ovellum serve in another
terminal, or hit a different static server of your choice.
ovellum upgrade#
Check the npm registry for a newer published ovellum and install it. The
command detects how Ovellum was installed (global vs. a local
devDependency, and which package manager) and runs the matching install
command.
It prefers the project's local dependency: when the current directory's
package.json declares ovellum (or it's already in node_modules), the
upgrade targets the project (… add -D ovellum@latest) even when invoked as the
global binary — and the package manager is read from the project's lockfile.
Only outside such a project does it fall back to a global install. The printed
line names the target, e.g. Update available: 0.10.0 → 0.10.1 (this project's local dependency).
Synopsis#
ovellum upgrade [--dry-run] [--yes]
Flags#
| Flag | Type | Default | Notes |
|---|---|---|---|
--dry-run | boolean | false | Print the upgrade command without running it. |
--yes, -y | boolean | false | Skip the confirmation prompt and run immediately. |
Behavior#
- If you're already on the latest version, it says so and exits
0. - Otherwise it prints
current → latestand the exact install command. - Interactively, it confirms before running (defaults to yes). With
--yesit runs without asking; with--dry-runit only prints. - In a non-interactive shell (no TTY) without
--yes, it prints the command and exits without running — it never silently mutates your environment in CI or scripts. - The install runs in a subprocess with inherited output;
ovellum upgradeexits with that process's exit code.
Update notice#
Independently of this command, Ovellum prints a one-line "update
available" notice after a command finishes when a newer version exists.
It's a courtesy only — nothing is installed without ovellum upgrade. The
check:
- hits npm at most once per
update.intervalHours(default 24h); the result is cached, so most runs do no network I/O; - is silent in CI, in non-interactive shells, when
NO_UPDATE_NOTIFIERis set, when--no-update-checkis passed, and whenupdate.checkisfalse; - never delays or fails a command — every error path is swallowed.
ovellum orphans#
List the quarantined manual blocks under
protect.orphanDir (default
.ovellum/orphans/). When a protected @manual block's anchor disappears
during a hybrid build, the prose is moved here instead of being lost;
ovellum orphans is how you review what's accumulated. Read-only — it writes
nothing.
For each orphan it shows the anchor id, the doc it lived in, when it was orphaned (and how long ago), the last build that still saw the anchor, and — when an IR snapshot exists — whether that anchor is back in the source (so the block could be reattached by hand) or gone.
Synopsis#
ovellum orphans [--cwd <dir>] [--config <path>] [--stale] [--json] [--reattach]
Flags#
| Flag | Type | Default | Notes |
|---|---|---|---|
--cwd <dir> | path | process.cwd() | Project root. |
--config <path> | path | auto-discovered | Skip discovery and load this file directly. |
--stale | boolean | false | Show only orphans older than protect.orphanRetention days (default 90) — the quarterly-review filter. |
--json | boolean | false | Emit the list as JSON ({ orphanDir, retentionDays, hasSnapshot, count, orphans[] }) for CI / tooling. |
--reattach | boolean | false | Interactively walk each orphan and reattach it, delete it, or skip (see below). Requires a terminal. |
Output#
ovellum orphans — 1 orphan in .ovellum/orphans/
src/math.ts::add
orphaned: 2026-06-24T18:25:19.412Z (today)
last seen: 2026-06-24T18:25:18.992Z
doc: docs/math.md
block id: why
anchor: gone from current source
file: .ovellum/orphans/2026-06-24_src-math.ts-add.md
Reattaching (--reattach)#
ovellum orphans --reattach walks the archive one orphan at a time and, for
each, offers to:
- Reattach it to a suggested anchor — the same anchor if the symbol is back
in the source, or a name-similar one if it was likely renamed (you can also
type a different anchor id). The prose is written into a
@manualprotected zone under that anchor, so the next build preserves it, and the archive file is removed. - Delete the orphan (with a confirmation), or skip it.
It reads the current anchors from the last build's
IR snapshot, so run ovellum build first. The reattach target
is a built doc, so the change lands exactly where a rebuild would keep it.
Exit codes#
| Code | Meaning |
|---|---|
0 | Success (including when there are no orphans). |
3 | ConfigError — config schema invalid, file not found, etc. |
ovellum mcp#
Run Ovellum as a Model Context Protocol
server over stdio, so an AI agent can drive it as a first-class tool. It speaks
newline-delimited JSON-RPC on stdin/stdout — point any MCP client at
ovellum mcp and it discovers the tools below. (No extra dependency: the server
is built into the CLI.)
Synopsis#
ovellum mcp [--cwd <dir>]
--cwd sets the project root the tools operate on (defaults to the current
directory). stdout is the protocol channel — don't pipe anything else
through it.
Tools#
| Tool | Reads / writes | What it does |
|---|---|---|
ovellum_query_symbol | reads IR | Look up a symbol by anchor id or name in .ovellum/ir.json — signature, source location, params, returns. |
ovellum_diff | reads IR | Added / removed / changed / renamed symbols vs the last build, and which docs would change. |
ovellum_check | reads | Validate the project: broken links, unsafe URL schemes, stale translations — counts + per-issue list. |
ovellum_list_orphans | reads | Quarantined manual blocks (optional stale filter), with reattachability vs the snapshot. |
ovellum_get_page | reads | The built Markdown for one page (the AI-friendly .md mirror), by path under the output dir. |
ovellum_search_docs | reads | Full-text search over the built docs; ranked pages with path, title, score, snippet. |
ovellum_build | writes docs | Run a build; returns the build summary. |
ovellum_write_zone | writes prose | Write Markdown into a protected @manual zone under an anchor id. The hybrid merge engine preserves it across the next regeneration — the same guarantee a human editing between @manual:start/end gets. Supports dryRun. |
ovellum_reattach | writes prose | Rescue an orphan: splice its prose under a target anchor (default: the suggested present-again / renamed one) and remove the archive, or delete it. The non-interactive orphans --reattach. |
ovellum_write_zone is the one no other docs server can offer: an agent
contributes hand-written prose that survives regeneration instead of being
overwritten on the next build. Survival requires
hybrid mode; in auto mode the block is written but
the next build overwrites it.
The IR-backed tools need a snapshot — run a build first (or call
ovellum_build) so .ovellum/ir.json exists.
Resources#
Beyond tools, the server exposes Ovellum's read surface as MCP resources — context an agent can pull directly:
| URI | What |
|---|---|
ovellum://llms.txt / ovellum://llms-full.txt | The AI index / corpus (when built). |
ovellum://page/{path} | A built page's Markdown by output-relative path (a resource template). |
ovellum://ir | The parsed IR snapshot (.ovellum/ir.json). |
ovellum://orphans | Quarantined manual blocks with age + reattachability. |
Prompts#
And curated prompts (guided workflows the client surfaces):
| Prompt | What |
|---|---|
set-up-ovellum | Scaffold docs and explain the hybrid contract. |
document-symbol (symbol) | Read a symbol, draft prose, and write it into a protected zone that survives regeneration. |
review-doc-drift | Diff against the snapshot and surface orphans to reattach. |
Example (Claude Code)#
claude mcp add ovellum -- npx ovellum mcp --cwd /path/to/project
ovellum clean#
Removes generated output while preserving anything you wrote by hand. Dry-run
by default — it lists what it would remove; pass --confirm to actually
delete.
ovellum clean [--cwd <dir>] [--config <path>] [--confirm] [--orphans]
What it removes, by mode:
manual— the whole output directory (dist/by default). It's 100% generated from your content; your.mdsources ininputare untouched.auto/hybrid— generated Markdown files, identified by theovellum: truefrontmatter the generator writes. Two things are always kept: files you authored by hand (noovellum: true), and any generated file that contains a@manualzone — that prose lives only in the file, so clean never deletes it.
Preserves .ovellum/orphans/ by default (committed hand-written prose); pass
--orphans to also remove the orphan archive. Deleting hand-written prose must
be deliberate, so it never happens without an explicit flag.
| Flag | Default | Description |
|---|---|---|
--confirm | off | Actually delete. Without it, clean is a dry run. |
--orphans | off | Also remove .ovellum/orphans/. |
ovellum snapshot#
Freeze the current docs as a version: copy the
latest content tree into <input>/<id>/, then print the site.versions entry
to add. The command never edits your config — a TypeScript config can't be
machine-edited safely, so the config change is always yours to make and review.
- On a versioned project, the source is the latest version's directory
(
content/<latest>/→content/<id>/); sibling versions are untouched. - On a project without
site.versions, the source is the content root (the new version directory and a nested output directory are skipped), and the output explains the one-time migration: oncesite.versionsis set, every version — including the latest — lives in its own directory.
Synopsis#
ovellum snapshot <id> [--cwd <dir>] [--config <path>] [--force]
Flags#
| Flag | Type | Default | Notes |
|---|---|---|---|
<id> | string | required | Version id — also the directory name and URL prefix (/1.0/). Letters, digits, ., _, -. |
--cwd <dir> | path | process.cwd() | Project root. |
--config <path> | path | auto-discovered | Skip discovery and load this file directly. |
--force | boolean | false | Overwrite an existing <input>/<id>/ directory. |
Exit codes#
| Code | Meaning |
|---|---|
0 | Snapshot written. |
2 | Invalid id, id already configured, or the target exists (without --force). |
3 | ConfigError — config schema invalid, file not found, etc. |
ovellum agents#
Add or refresh the canonical "Ovellum docs" section in the project's
top-level agent-instruction files — AGENTS.md and/or CLAUDE.md. The section
tells any coding agent how documentation works in this repository: which
directory is regenerated, the protected-zone contract (hybrid), which commands
to run and their exit codes, and where the MCP server is. Its content is
rendered from your config (mode, input, output, protect.orphanDir), so
it stays truthful as the project's setup changes.
The command is idempotent and surgical:
- Whichever of
AGENTS.md/CLAUDE.mdexists at the project root is updated — both when both exist. When neither does,AGENTS.mdis created containing only the section. - Only the
## Ovellum docssection (its heading through to the next#/##heading, or end of file) is replaced; everything around it is preserved verbatim. - When the section is already current, nothing is written — safe to re-run any time, from a hook, or in CI.
Synopsis#
ovellum agents [--cwd <dir>] [--config <path>] [--check]
Flags#
| Flag | Type | Default | Notes |
|---|---|---|---|
--cwd <dir> | path | process.cwd() | Project root. |
--config <path> | path | auto-discovered | Skip discovery and load this file directly. |
--check | boolean | false | Verify only: exit 1 if the section is missing or stale in any target file; write nothing. |
Output#
ovellum agents:
AGENTS.md Ovellum docs section updated
CLAUDE.md already current
Exit codes#
| Code | Meaning |
|---|---|
0 | Section written, or already current everywhere. |
1 | --check found a missing or stale section. |
3 | ConfigError — config schema invalid, file not found, etc. |
ovellum init performs the same upsert when an AGENTS.md
already exists, so a freshly scaffolded project and a long-lived one converge
on the same section.
Common flags#
These appear on most commands rather than as true globals:
| Flag | Where | Notes |
|---|---|---|
--cwd | all | Project root. |
--config | all build-ish commands | Path to the config file (auto-discovered otherwise). |
--json | build / check / diff | Machine-readable output. See Automation. |
--verbose | build / check / diff | Config-resolution + stage / file-I/O detail to stderr. |
--strict | check | Extra validations; any issue exits 1. |