Skip to main content

The shio CLI

npx @viglet/shio --help

The shio command is the scripted path into an instance: it is what a CI job runs, what claude mcp add bridges to, and what you use when a shell is a better fit than an API call. Zero runtime dependencies, and every command prints its own flags:

shio verify --help # or: shio help verify

Connecting

FlagEnvironmentUsed by
--url <baseUrl>SHIO_URL (default http://localhost:2710)everything
--user / --passwordSHIO_USER / SHIO_PASSWORDpull, push, deploy (console Basic auth)
--token <token>SHIO_CDA_TOKENtypes, dev (a delivery token)

The commands

Start something

CommandDoes
shio init [name]Scaffold a Next.js site wired to the delivery API. --blueprint <name> takes the starter from the instance instead; add --site <site> to apply its content in the same command
shio blueprintsList the appliable starting points; shio blueprints <name> prints one package's parameters
shio marketplace <list|show|install|uninstall>The package catalogue: what this instance could install, and installing it. install needs an administrator. See Blueprints § Where more packages come from
shio import <file.zip>Clone an exchange package into this instance: how you accept a site somebody hands you

Discover

CommandDoes
shio contextThe agent context pack (model, sitemap and conventions) in one call. --out <file> writes it
shio resolve <address>Resolve post: / folder: / site: / id: to the object it names
shio impact <address>What a change to this template would affect: layouts, types, page counts
shio changesWhat changed, with a cursor to resume from (--since, --cursor)
shio rememberThe instance memory: bare lists it, <key> "<note>" writes one, --forget drops one, --site scopes it
shio mcpBridge stdio to this instance's MCP endpoint, claude mcp add shio -- shio mcp

The content model

CommandDoes
shio pullPost types into shio/post-types/*.json
shio pushLocal post types back to the instance (--dry-run, --check, --prune)
shio buildCompile local DSL/JSON post types to canonical JSON without touching the server (--out)
shio typesGenerate a TypeScript .d.ts from the live post types
shio deploypush then types

push and build compile TypeScript DSL sources to canonical JSON before diffing, so a model authored as typed TS and one hand-written as JSON push identically. --prune never removes a system type.

Content

CommandDoes
shio pull --contentProject the site to shio/content/** (three-way merge)
shio push --contentCompile the tree into a desired-state document and apply it
shio apply [file]Plan/apply a desired-state document, --dry-run, --check, - for stdin. --blueprint <name> --site <site> applies a package instead; --create-site makes the site in either mode
shio dev --contentWatch shio/content/** and sync both ways, logging events

See Content as Files for the tree, the sidecars and the merge.

Prove it works

CommandDoes
shio verifyThe content and route lint. Exits non-zero on an error: this is the CI gate. --strict fails on warnings too; --folder / --address / --since scope it; --baseline / --accept subtract findings you have accepted; --delivery adds the stronger proof that a published page is really served
shio digest <page>One page's structure: outline, landmarks, links, images
shio audit <page>What is wrong with a rendered page, as text with a selector each
shio snapshot <page>A PNG for a person, plus whether the page looks different
shio reportThe curator handoff: what changed, a preview link each, and the warnings as open questions, Markdown, for a PR body
shio diff --against publishedWhat a publish would change: which fields differ between each draft and the live row, per post. --address narrows it. Exits non-zero when anything would change, so a pipeline can gate on it

Two things about verify that matter in a pipeline: the report's notes are printed, because a run that quietly covered less than you think reads exactly like a clean pass; and --delivery appends its group rather than replacing --checks, since a caller who wants the stronger proof still wants the lint.

snapshot needs playwright, which is an optional dependency with a teaching error naming the install, @viglet/shio never drags a browser into your project. With pixelmatch and pngjs present the diff is per-pixel; without them it is byte-level, and the output says which. A changed page exits 0: a page looking different is usually the change you just made, and a gate there is one people wrap in || true. A site with no front end is photographed through the instance's own preview, and the output says the picture is a draft, because the image cannot.

What shio audit reports

Ten rules, and two lines the report prints whether or not anything is wrong. An error exits non-zero; a warning does not, so a pipeline can gate on the first without being stopped by the second.

RuleSeverityFires whenWhat to do
request-failederrorThe page asked for something — an image, a stylesheet, a script — and the server did not give itFix the URL or publish the asset. A missing stylesheet is why the rest of the report looks strange
console-errorerrorThe page threw in the browserRead the message: it is the finding, so this one carries no extra detail
region-scripterrorA region's JAVASCRIPT does not parseThe only field whose value is a program. It is shipped to the browser and never run in the JVM, so a region whose script is broken still renders, hashes, lints and verifies clean — this is the one check that runs it
overflowwarnA box is wider than the viewport at one of the tested widthsUsually a fixed width, a long unbroken string, or a table. Reported at the width where it is worst
contrastwarnText fails the WCAG AA ratio against its own backgroundDarken the text or lighten the background. Large and bold text has a lower floor, and --contrast overrides it
zero-sizewarnAn element occupies no spaceEither it should not be in the markup, or something it depends on did not load
collapsedwarnA box has children and no heightUsually a float or grid container that lost its layout
font-fallbackwarnA declared font was not available, so the browser substituted oneShip the font or accept the substitute. What you see locally is not what a reader sees
no-landmarkwarnThe page has no main, nav, header or footer at allAlmost always a page that lost its regions rather than a page that never had them
no-headingwarnThe page has no heading of any levelSame reading as no-landmark, and the two usually arrive together

The last two exist because the other eight measure what is there: a page that has lost most of itself has no overflow, perfect contrast, no collapsed box and nothing that fails to load. Emptiness scored clean.

Two lines are printed on every run, findings or not, for that same reason — a number nobody prints is a fact nobody joins:

  • shape: — the landmarks and the heading count, read once because they do not change with the viewport. An intact page reads main, navigation, contentinfo · 3 headings; the same page emptied reads no landmark · 2 headings. That difference is the whole answer to did this page keep its regions.
  • scripts: — how many region scripts were parsed. 0 region scripts is an answer: without it, a page carrying no script at all and a page where every script is fine would print the same nothing.

Each rule stops after a fixed number of findings per page load, and the report says so in a note: line naming the rule and how many it did not examine — a truncated run must not read as a clean one.

Replicate an existing site

CommandDoes
shio clone <url>Capture a site that already exists: an inventory, and no content
shio proposeWhich captured blocks could become sections, and what each would lose
shio convertApply the accepted plan: sections, theme and scripts, as drafts

See Replication.


In a pipeline

Three commands are gates, and the order they run in is the order the failures make sense in:

shio push --check # 1. does the model on the server match git?
shio push --content --check # 2. does the content match git?
shio verify # 3. is what is there internally consistent and reachable?

--check prints the plan, writes nothing, and exits non-zero when the plan is not empty, so a pull-request job fails on drift instead of silently reconciling it. verify exits non-zero on an error, which is what makes it the last gate rather than a report.

Every non-zero exit closes cleanly, so a piped run does not lose its last lines.


PageDescription
Content as FilesThe tree pull --content writes and the merge that protects it
BlueprintsThe packages init --blueprint and apply --blueprint install
Replicationclone, propose and convert end to end
The Agent SurfaceThe endpoints every command calls
MCP Servershio mcp, and connecting a client