CLI reference
Local conversion, review, validation, packing, diagnostics, and skill commands.
The primary binary is snabbsajt. Every site and skills command is local and
keyless. The commands under Connect a repository below are the only ones that
talk to SnabbSajt, and the credential they obtain is read-only.
Connect a repository
link, unlink and upgrade are in the CLI source for 0.4.0, which is not
published yet. Until it is, use snabbsajt connect (published in 0.3.0), which
does the same job with the site chosen in the browser instead of the terminal.
snabbsajt link [--site <slug|id>] [--yes] [--relink] [--status] [--json]
snabbsajt unlink [--json]link connects the directory you run it in to one of your sites. It prints a
short code, you approve the terminal once in the browser, and then you pick the
site right there in the terminal with the arrow keys. It writes two files and
nothing else:
| File | Secret? | What to do with it |
|---|---|---|
.snabbsajt.json | No — a site id and an API URL | Commit it. A colleague who clones the repo then only needs their own key. |
.env.local | Yes — SNABBSAJT_DELIVERY_TOKEN | Gitignore it. The CLI warns on stderr when it looks like you have not. |
Running link again in a linked directory offers to keep the link, choose a
different site, or unlink. Picking the same site again mints a fresh key, which
is what to do when a key has been revoked or a fresh clone has no .env.local.
The approval is single-use, expires after ten minutes, and can only ever
produce a read-only key for one site you own. It cannot read your content,
cannot write anything, and cannot publish. If you have editor access to someone
else's site but do not own it, link will say so and tell you to ask the owner —
only an owner can connect a site to a terminal.
unlink revokes the key first, then removes .snabbsajt.json and only the
SNABBSAJT_DELIVERY_TOKEN line from .env.local. If it cannot reach the server
it says the key may still be live rather than pretending otherwise.
Flags
| Flag | Effect |
|---|---|
--site <slug|id> | Pick without the prompt. Fails if nothing matches. |
--yes | Accept the only match; fails when there is more than one. |
--relink | Skip the menu and go straight to the picker. |
--status | Print the current link and exit. Writes nothing. Exit 1 when not linked. |
--json | Machine output. Never prompts — an ambiguous run exits 1 with a stable code. |
--json failures carry a code field that is safe to branch on:
ambiguous_site, no_sites, site_not_found, not_approved, ticket_expired,
token_limit, no_link. The human-readable error string may be reworded at
any time; the code will not.
Keep the CLI current
snabbsajt upgrade [--yes] [--json]After a command finishes, an out-of-date CLI prints a one-line notice on
stderr — never stdout, so it cannot corrupt a pipe. The check is cached for
24 hours in ~/.snabbsajt/update-check.json, times out after 1.5 seconds, and can
never delay or fail the command you actually ran. It sends nothing but a plain GET
to the public npm registry.
It stays silent under --json, without a TTY, when CI is set, when
SNABBSAJT_NO_UPDATE_CHECK=1 is set, and after a command that already failed.
upgrade works out how the CLI was installed and prints the right command for it.
It only runs a package manager after you explicitly say yes, the prompt defaults
to no, and it never edits a repository's package.json for you.
Import HTML
snabbsajt site import html <public-url|file.html|site.zip> [-o package-dir] [--json]Import WordPress
snabbsajt site import wordpress --url <public-url> --wxr <export.xml> --out <package-dir> [--json]Approve an import
snabbsajt site import approve <package-dir> --yes [--json]Approval refuses blocked reports and unexpected changes to the original deterministic report or generated site.
Namespaced package commands
snabbsajt site init <dir> [--template nextjs|html] [--json]
snabbsajt site validate <site.json|dir> [--json]
snabbsajt site inspect <site.json|dir> [--json]
snabbsajt site pack <dir> [-o bundle.zip] [--review-draft] [--json]
snabbsajt site doctor [--json]Skills
snabbsajt skills install --agent auto|codex|claude|all [--global] [--force] [--json]
snabbsajt skills list --agent auto|codex|claude|all [--global] [--json]
snabbsajt skills doctor --agent auto|codex|claude|all [--global] [--json]Project-local installation is the default. Modified skill files are preserved
unless --force is explicit, and a backup is created before replacement.
Compatibility alias
The @snabbsajt/site-kit package still exposes site-kit for hand-authored
packages. New import and skill workflows use snabbsajt.
Legacy site-kit commands
site-kit init
site-kit init <dir> [--template nextjs|html]Creates a starter package and refuses to overwrite an existing site.json.
site-kit validate
site-kit validate <site.json|dir>Checks the versioned envelope, section content, variants, caps, references, duplicate ids/slugs, and file names. A directory check also requires exactly one matching file for every declared asset and uploaded font.
The exit code is 0 when there are no errors. Warnings do not fail CI.
site-kit inspect
site-kit inspect <site.json|dir>Validates, then prints the business name, language, counts, and section types as JSON.
site-kit pack
site-kit pack <dir> [-o bundle.zip]Validates, checksums the embedded files, and creates the self-contained bundle accepted by SnabbSajt. Packing fails on missing or ambiguous files and on the total size cap.
Incremental (merge) import workflow
A second import can update an existing site instead of stacking up another draft. Packing is always whole-package — there is no flag to pack a subset of pages — because the merge itself decides what changes, by matching keys.
- Give every page and section a stable
externalKeyinsite.json(for example"home","home/hero").validateerrors on duplicate keys and warns on keyless sections (those are insert-only). - First import creates the site as usual.
- For an update, change the package and pack it as normal:
snabbsajt site pack <dir> -o site.zip - Merge that bundle into the existing site, either in the browser (below) or
with the
import_siteMCP tool'smergeIntoWebsiteId. New keys insert, unchanged keys no-op, untouched sections update in place, and sections the owner edited in the app are skipped as conflicts unless explicitly forced. Nothing is deleted, site settings/theme/fonts are untouched, and a restore point is taken before the first write.
Merge works in the browser too. On
/dashboard/importthe owner picks Update a website I already have, chooses the site, and gets a preview — what would be added, updated, left identical, and which sections they edited themselves and would keep — before anything is written. Confirming applies it; a switch in that card is the only way to overwrite their own edits (the equivalent offorceKeys). Theimport_siteMCP tool needs thecontent:writescope; it no longer requires the advanced-editor capability.
Hittade du inte svaret, eller stämmer något inte? Berätta det för oss.
Senast uppdaterad