CLI reference
This page is the exhaustive, option-by-option reference for every scribpy
command, generated by reading src/scribpy/cli/main.py directly. For
workflow-level explanations — when to reach for which command, and how
commands compose — read Using the CLI and the
end-to-end demo instead; this page favors completeness
over narrative.
The Click entry point is:
scribpy [OPTIONS] COMMAND [ARGS]...
Global options:
| Option | Effect |
|---|---|
--version |
Print Scribpy's package version and exit. |
--help |
Print the command list and exit. |
Every subcommand also accepts --help, e.g. scribpy build --help prints
that command's own argument and option list without executing anything.
All commands use exit status 0 for success. validate and diagnose use 1
when blocking findings exist. Other expected domain or filesystem failures are
translated to a Click error with status 1: Click prints Error: <message> to
stderr and exits, so these failures are visible in scripts through both exit
status and stderr content. The seven commands map directly onto the seven
end-user Python functions documented in
Python API reference — each command is a thin
adapter, not a separate implementation, so behavior described there (default
values, raised exceptions, side effects) also holds for the CLI.
| Command | Wraps this Python call |
|---|---|
new |
scribpy.init_skeleton(...) |
scaffold |
scribpy.init_from_outline(...) |
validate |
scribpy.valid_report(...) |
diagnose |
scribpy.MarkdownCollection.from_tree(root).diagnose() |
build |
scribpy.MarkdownCollection.from_tree(root) + scribpy.concatenate(...) |
html |
scribpy.html_export(...) |
mkdocs-export |
scribpy.mkdocs_export(...) |
new
scribpy new [OPTIONS] OUTPUT_DIR
Create a minimal root manifest and index.md.
| Parameter | Type | Required | Default |
|---|---|---|---|
OUTPUT_DIR |
path | yes | — |
--title TEXT |
text | yes | — |
--author TEXT |
text | no | empty string |
--project-version TEXT |
text | no | 0.1.0 |
--help |
flag | no | — |
Output:
Created Scribpy project at OUTPUT_DIR
OUTPUT_DIR need not exist. Existing unrelated contents are not removed, but
an existing OUTPUT_DIR/scribpy.yml raises ScaffoldCollisionError.
scribpy new notes --title "Engineering Notes" --author "Ada"
This creates notes/scribpy.yml and notes/index.md. The manifest looks
like:
project:
title: Engineering Notes
author: Ada
version: 0.1.0
build:
toc: false
heading_numbering:
enabled: false
order:
- index.md
author is omitted from the written manifest when left at its default empty
string; version is always written, defaulting to 0.1.0 unless
--project-version overrides it. The generated build block explicitly
turns TOC and heading numbering off — enable them by editing the manifest
once your project has more than one page (see
Root manifest). index.md itself is a
one-line stub: # Engineering Notes. Use new for a project you intend to
grow by hand, one file at a time. If you already have an outline of your
intended structure (a Markdown file of nested headings), use scaffold
instead — it generates the whole tree in one step.
scribpy new notes --title "Engineering Notes" --author "Ada" \
--project-version "0.3.0"
scaffold
scribpy scaffold [OPTIONS] OUTLINE_PATH OUTPUT_DIR
Parse a headings-only outline and generate directories, stub pages, and local manifests.
| Parameter | Type | Required | Default |
|---|---|---|---|
OUTLINE_PATH |
existing file | yes | — |
OUTPUT_DIR |
path | yes | — |
--max-depth INTEGER |
integer 1–6 | no | 4 |
--help |
flag | no | — |
Output:
Scaffolded Scribpy project at OUTPUT_DIR
Expected failures include unreadable outline, invalid structure,
max-depth outside 1–6, sibling slug collision, and existing target manifest.
scribpy scaffold outline.md notes --max-depth 5
Given this outline:
# Engineering Handbook
## Getting Started
## Architecture
### Domain Model
### Pipeline
scaffold produces:
notes/
├── scribpy.yml # project.title: Engineering Handbook
├── index.md # "# Engineering Handbook"
├── getting-started.md # leaf heading -> stub file
└── architecture/ # heading with children -> subdirectory
├── scribpy.yml # title: Architecture, order: [domain-model.md, pipeline.md]
├── domain-model.md
└── pipeline.md
Headings are slugified for filenames and directory names (Domain Model →
domain-model), using the same slug function MkForge uses elsewhere in the
toolchain. A single top-level H1 becomes the project title and its direct
children become the root order; an outline with multiple H1s instead
produces a generic Project title with each H1 as a top-level entry. Every
generated stub file contains only its heading, ready to be filled in.
validate
scribpy validate [OPTIONS] ROOT
Run manifest inspection, MkForge Markdown verification, and collection diagnostics; render the complete report with Rich.
| Parameter | Type | Required | Default |
|---|---|---|---|
ROOT |
path | yes | — |
--help |
flag | no | — |
The command has no formatting, strictness, rule-selection, or output-file option. Use the Python API for structured report handling.
scribpy validate notes
status=$?
validate is the broadest check available: it inspects every reachable
manifest (root and folder), verifies every Markdown source through MkForge
(heading structure, front matter, image references), and runs the full
collection diagnostics engine — then renders everything as one Rich report
with render_validation_report. It always runs to completion and prints
findings even when there are zero errors, so it is safe to run on every
change, including in CI:
scribpy validate notes || exit 1
Because validate prints a formatted report and only signals pass/fail
through the exit code, prefer scribpy.validate_project() from Python when
your caller needs to branch on individual finding codes rather than parse
text output.
diagnose
scribpy diagnose [OPTIONS] ROOT
Load the collection, run default collection rules, and print the plain-text
summary. This does not replace the broader validate command.
| Parameter | Type | Required |
|---|---|---|
ROOT |
path | yes |
--help |
flag | no |
An invalid manifest, filesystem error, or decoding failure becomes a Click error. A diagnostic report containing errors exits 1 after printing findings.
scribpy diagnose notes
diagnose is narrower and faster than validate: it only runs the eight
default CollectionDiagnosticRule checks (see
Diagnostic reference) and skips
MkForge front-matter/heading verification and the broader manifest
inspection that validate performs. Reach for diagnose when you only care
about Markdown-structure and link/image problems — for example while
iterating quickly on a single page — and reach for validate before
publishing or in CI, where the fuller check matters more than speed.
validate |
diagnose |
|
|---|---|---|
| Manifest inspection | yes | no |
| MkForge Markdown verification | yes | no |
| Collection diagnostics (8 rules) | yes (adapted into ProjectDiagnostic) |
yes (raw CollectionDiagnostic) |
| Output | Rich table via render_validation_report |
plain-text report.summary() |
| Underlying call | scribpy.valid_report(root) |
MarkdownCollection.from_tree(root).diagnose() |
build
scribpy build [OPTIONS] ROOT OUTPUT
Assemble a project into one Markdown file.
| Parameter | Type | Required |
|---|---|---|
ROOT |
path | yes |
OUTPUT |
path | yes |
--help |
flag | no |
All policy options come from the root manifest; there are no CLI overrides for TOC, numbering, or renderer backends. The output parent is created. Successful output is:
Built Markdown document at OUTPUT
Expected errors include invalid Markdown/manifest, renderer failure, unimplemented PlantUML local backend, filesystem failure, and decoding failure.
scribpy build notes work/notes/document.md
build runs the full assembly pipeline described in
Assembly pipeline: heading
numbering (if enabled), internal link rewriting, TOC insertion (if
enabled), PlantUML/Mermaid rendering, and image collection — always in that
fixed order, always driven entirely by the project's scribpy.yml. The
output is one Markdown file plus an assets/ directory next to it holding
copied and generated images:
work/notes/
├── document.md
└── assets/
├── generated/
│ └── 3f9c2a…8b1e.png # diagram, named by content hash
└── logo.png # copied local image
If validation matters to you before committing to a build, chain validate
first — build itself still runs collection diagnostics internally and
raises InvalidMarkdownError on any error-level finding, but it does not
print the findings the way validate does:
scribpy validate notes && scribpy build notes work/notes/document.md
html
scribpy html [OPTIONS] SOURCE OUTPUT
Convert one already assembled Markdown file into standalone HTML.
| Parameter | Type | Required | Default |
|---|---|---|---|
SOURCE |
path | yes | — |
OUTPUT |
path | yes | — |
--toc-depth INTEGER |
integer | no | 3 |
--css FILE |
existing file | no | built-in CSS only |
--help |
flag | no | — |
SOURCE is not a project root. OUTPUT's parent must already exist.
toc-depth is relative to H1: 1 includes H2, 2 includes H2 and H3, and 3
includes through H4. The command reports:
Exported HTML document at OUTPUT
scribpy html work/notes/document.md work/notes/document.html \
--toc-depth 2 --css custom.css
html operates on an already-assembled document — normally build's
output, not a raw project source tree. It strips the Markdown TOC block
that build inserted (if any), converts the remaining Markdown to HTML,
and rebuilds the navigation from headings up to --toc-depth, presented as
a collapsible burger menu. All CSS and JavaScript are inlined into the HTML
file itself, but referenced images (assets/…) remain separate files next
to the HTML — copy the whole output directory, not just the .html file,
when distributing it. Run build then html back to back for a
one-command style pipeline:
scribpy build notes work/notes/document.md && \
scribpy html work/notes/document.md work/notes/document.html
mkdocs-export
scribpy mkdocs-export [OPTIONS] SOURCE OUTPUT
Export a Scribpy project as MkDocs input while keeping pages separate.
| Parameter | Type | Required |
|---|---|---|
SOURCE |
project-root path | yes |
OUTPUT |
destination-directory path | yes |
--help |
flag | no |
The command has no force, theme, serve, build, or deploy option. It refuses an
existing OUTPUT/mkdocs.yml. Successful output is:
Exported MkDocs project at OUTPUT
scribpy mkdocs-export notes work/notes/mkdocs-source
Unlike build, mkdocs-export runs directly against the project source
tree, not an assembled file, and never merges pages into one document.
Every source page is copied to docs/ at its original relative path with
its diagrams rendered and its images collected in place; links between
pages are left as ordinary Markdown paths — MkDocs resolves them at its own
build time, so Scribpy's link-rewriting and heading-numbering transforms do
not run for this output shape. Navigation (nav: in the generated
mkdocs.yml) mirrors the manifest hierarchy, using each page's first H1 as
its navigation label:
work/notes/mkdocs-source/
├── mkdocs.yml
└── docs/
├── index.md
└── architecture/
├── domain-model.md
└── assets/
└── generated/…
The generated mkdocs.yml only contains site_name, docs_dir, and
nav — no theme, plugins, or Material configuration. Add those yourself
before running mkdocs build or mkdocs serve on the result, or adapt this
project's own mkdocs.yml as a starting template.
Path validation behavior
Click existence-checks OUTLINE_PATH and --css because they use an existing
file type. Other path parameters are converted to pathlib.Path without early
existence checking; the called public API produces the relevant domain or
filesystem failure.