Skip to content

CLI Reference

pH7x Systems edited this page Jul 21, 2026 · 6 revisions

CLI Reference

The cms command (package sardine-cms-cli, built on Typer). Every command accepts --project / -p to point at the project directory containing sardine.toml (defaults to the current directory). Missing project file exits with code 2.

cms init DIRECTORY

Scaffold a new project.

Option Default Meaning
--name My Sardine CMS Site name
--base-url https://example.com Canonical base URL
--languages pt-pt,es,fr,de Required target languages, comma-separated (EN is always the source)

cms seed [-p DIR] [--force]

Write the fictional starter content (Sardine Aerospace: 2 pages, 13 articles — one deliberately left in review with a missing DE translation — 4 media assets, 5 languages) with fixed timestamps so seeded projects build deterministically. Refuses to overwrite existing content (exit 3) unless --force is given.

cms validate [-p DIR]

Run the validation ruleset over the whole content set and print N error(s), M warning(s). Non-zero exit when errors exist. Rules: required translations, unique slugs per language, media references, mandatory EN alt text, known categories (see Content Model).

cms build [-p DIR]

Validate, then build the static site into the configured output directory (default _site/). Deterministic: same content → byte-identical output (the CLI prints the artifact digest).

cms export [-p DIR] [--target NAME]

Build plus target-specific extras:

Target Extras
generic (default) plain static files
swa staticwebapp.config.json (security headers, cache rules, 404 rewrite)
nginx nginx server config with security headers, container-ready layout

cms preview [-p DIR] [--port N]

Serve the built _site/ locally (default port 8000).

cms admin create-user USERNAME [--role ROLE] [--language CODE] [--force] [-p DIR]

Create an admin account in the project's storage — the only way to create the first account (no default credentials). Prompts for a 12–1024 character password twice (argon2id-hashed; only the hash is stored). Roles: editor | reviewer | publisher | admin. --language sets the account's panel language (en | pt-pt | es | fr | de). --force replaces an existing account and revokes all of its sessions; creating an account that already exists without it exits 3.

Exit codes

Code Meaning
0 success
1 validation errors (validate/build/export)
2 sardine.toml not found; cms init target already scaffolded; unknown import format; unknown extension for cms x; configuration errors (e.g. an unresolvable comments provider)
3 refusal to overwrite: cms seed on existing content, cms import into non-empty storage without --replace, create-user on an existing account without --force

cms dump [-p DIR] [--out DIR]

Write the portable source of truth — content.json plus markdown/<article>/<lang>.md — into --out (default portable/).

cms import SOURCE [-p DIR] [--format portable|wxr] [--replace]

Read content back into a project. --format portable (default) takes a cms dump directory and restores it losslessly — the round-trip is byte-verified by the test suite; this is the backup, the restore path and the way to move content between instances or storage engines. --format wxr takes a WXR 1.2 blog-export file (offline, DTD/entity declarations rejected) and converts its posts into articles ([ADR-0030]). Both refuse a non-empty storage without --replace (exit 3).

cms doctor [-p DIR]

Read-only diagnosis of the machinery around the content: configuration (theme, extensions, comments provider, Pillow when image_widths is configured), storage connectivity and schema level, content counts, referenced media files on disk, Python and package versions (lockstep). Exit 1 when any check fails; content problems remain cms validate's job.

cms x NAME [ARGS…] [-p DIR]

Run an activated extension's own CLI (ADR-0028): NAME is the extension name from the extensions = […] list in sardine.toml; everything after it is passed to the extension's Typer app. Unknown or inactive extension exits 2 (see Extensions).

Clone this wiki locally