Jump to
↵select↑↓navigateescclose

Reference

Command line

The eleven docusystem commands with their options, exit codes, environment variables, strictness rules and output conventions.

Updated
Tags
  • reference
  • cli
  • commands
On this page

The binary is docusystem, installed by the package @avunu/docusystem. Run it in the site folder (docs-site/): from its package.json scripts, with npx @avunu/docusystem <command>, or under Bun as bun --bun ./node_modules/.bin/docusystem. From the repository root, ./docs-site/node_modules/.bin/docusystem <command> runs the installed copy and finds ./docs-site on its own. It needs Node 22.19.0 or newer, or Bun 1.4 or newer.

Always write the scope in npx. The unscoped name docusystem is not this package: in a folder where the package is not installed, npx with the bare name fetches and runs whatever package owns it.

docusystem <command> [options]
CommandPurpose
initWrite the shell of a docs site into a repository
buildBuild the site into <site>/dist
checkWhat CI runs: a strict build, the contrast gate and a link crawl
devServe the site and rebuild when the Markdown changes
lintCheck the Markdown only, as file:line messages
linksCrawl an already built site
infoShow versions, folders, overrides and how to run Jx by hand
doctorCheck the repository against the maintainer checklist, offline
upgradeAfter an update, re-pin the workflows to the installed version
ejectCopy package files into overrides/ so that they can be changed
jxRun the pinned Jx CLI on the assembled project, for debugging

docusystem <command> --help prints the options of one command.

The site folder

Every command except init operates on a site folder, the folder that holds docusystem.config.json. It is resolved as:

  1. --site <dir>, else

  2. the current directory if it has the config, else

  3. ./docs-site if it has the config, else

  4. exit 1, listing what was searched.

Global options

OptionEffect
--site <dir>The site folder (every command except init, which takes --site-dir)
-v, --versionPrint the version and exit 0
-h, --helpPrint help and exit 0. With no command, help is printed too. After a command, that command's help

An unknown command or option prints a message and the help on standard error and exits 2. --strict together with --lenient is a usage error. Options with an empty value (--name "") are a usage error too.

Commands

init

Writes the shell of a docs site. Run it at the repository root or inside the site folder. It never creates docs-site/docs-site; from any other subfolder it exits 1 and says where to run it.

OptionMeaning
--site-dir <dir>Site folder, relative to the repository root. Default docs-site.
--name <text>, --tagline <text>, --license <id>Values it cannot infer from the catalog.
--slug <slug>The key in the avunu.net catalog; needed when several entries match and none is named like the repository.
--platform <platform>frappe, odoo, wordpress, nixos or general.
--repo <url>https://github.com/<owner>/<name>. Default: the origin remote.
--domain <domain>Default: the slug with _ written as -, plus .avunu.net.
--branch <name>Write the default branch into the config. Normally not written.
--docs <path>The Markdown folder, relative to the site folder. Default ../docs.
--from-readmeWhen docs/ has no README.md or index.md (any case), copy the repository's README there. Never overwrites, never moves.
--no-workflowDo not write the two caller workflows.
--no-dependabotDo not add Dependabot entries.
--no-patch-automergeDo not patch an existing Dependabot auto-merge workflow.
--workflow-sha <sha>Pin the workflows to this commit instead of resolving the tag of the installed version.
--forceOverwrite what init would refuse to overwrite.
--dry-runPrint every file and diff, write nothing.

What it does, in order:

  1. Infers the repository from the origin remote, the catalog entry whose repo matches (an error asking for --slug when several match), then slug, name, tagline, platform (else general), license and domain. A value it cannot infer is an error naming the option. Everything inferred is printed under "chosen for you". Existing config values win over inference, so running again never resets a tagline. When there is no docusystem.config.json but there is the earlier starter's docs.config.json, its values are read instead (the template's placeholder values are ignored), so the domain of a published site is kept; the new file is listed with a note that says so.

  2. Writes the config, indented the way the repository's formatter wants JSON (useTabs or tabWidth in .oxfmtrc.json or .prettierrc, else .editorconfig, else the root package.json, else two spaces; an existing file keeps its own); package.json when absent (when present it only adds the dependency and the three scripts, and exits 1 without --force if the file has a postinstall script or depends on any @jxsuite/* package; --force rewrites dependencies to the single package, the scripts to the three, and removes engines.bun); the .gitignore lines; the two caller workflows, with the commit of the tag v<installed version> found by git ls-remote https://github.com/Avunu/docusystem (the peeled ^{} line is preferred); the Dependabot entries; and the auto-merge patch.

  3. Refuses to overwrite an existing workflow that differs from its scaffold unless --force. If the commit cannot be resolved (offline, tag missing) it exits 1 and names --workflow-sha; it never falls back to a tag.

  4. Lists what the earlier starter left in the site folder (components/, layouts/, pages/, project.json, scripts/, data/, docs.config.json, README.md, a public/ of the package's own files, bun.lock) with what to do about each. init deletes nothing it did not write. See Migrating from the earlier starter.

  5. Prints "A maintainer still has to:" followed by the settings in Publishing, and "Next: cd docs-site && npm install && npm run check".

Exit codes: 0 wrote, or nothing to do; 1 cannot decide a value, refused to overwrite, or could not resolve the workflow commit; 2 usage.

init and upgrade need git on the PATH.

build

docusystem build [--strict | --lenient] [--refresh-catalog]

Runs steps 1 to 14 of the build pipeline and publishes <site>/dist. --strict and --lenient set the strictness. --refresh-catalog fetches the live project catalog instead of using the bundled one; it is the only network access a build can make.

Exit 0 ok; 1 problems (strict) or a failure; 3 environment.

check

docusystem check [--ci] [--refresh-catalog]

What CI runs: build (always strict), then the contrast gate and the link crawl. --lenient is a usage error. --ci is implied by GITHUB_ACTIONS=true: it adds GitHub annotations, a job summary and step outputs (see output conventions).

Exit 0 ok; 1 any step failed; 3 environment.

dev

docusystem dev [--port <n>]

Builds once, leniently (a failure of that first build exits 1), serves what would be deployed on 127.0.0.1:<port> (default 3000), rebuilds on change and live-reloads the browser. It exits 0 on SIGINT, SIGTERM or SIGHUP, and 1 when the first build failed or the port is busy. See the dev server.

lint

docusystem lint

The Markdown checks only, printed as level: file:line message, without building. Exit 0 when there are no errors, 1 otherwise.

docusystem links [dist]

Crawls an already built site; the default is <site>/dist. Exit 0 or 1.

info

docusystem info [--json] [--nav]

Prints the package and Jx versions, the runtime, the folders, the resolved branch, the overrides and the exact command that runs Jx by hand on the assembled project. --json prints it as JSON; --nav prints the sidebar tree. Exit 0.

doctor

docusystem doctor [--json]

The maintainer checklist as far as the repository shows it, offline: nothing touches the network. Prints the GitHub and DNS values still to be set. Exit 0 when there are no errors (warnings are allowed), 1 on any error. See doctor checks.

upgrade

docusystem upgrade [--dry-run] [--workflow-sha <sha>]

Re-pins both uses: lines of both caller workflows to the commit of the tag v<installed version>, appends missing Dependabot entries, and removes nothing else. Exit 0; 1 when the commit cannot be resolved.

eject

docusystem eject (<components/file> | <layouts/file> | <pages/file>)... | --all  [--force]

Copies package files into <site>/overrides/ and records each in overrides/.ejected.json with the version and sha256 it came from. Exit 0; 1 for an unknown file or when an override already exists (--force overwrites). See Customizing.

jx

docusystem jx <jx arguments...>

Assembles the project root (pipeline steps 1 to 8; docusystem itself builds nothing), then runs the pinned Jx CLI as jx <arguments> <root>, for example docusystem jx build --verbose. Everything after jx goes to Jx unchanged, so give --site before it. The exit code is Jx's. It is a debugging aid: jx dev and Jx Studio are not supported.

The root is assembled from empty on every run, so a file that Jx writes into it (such as the project.schema.json of jx schema) lasts only until the next docusystem command. jx build writes to <root>/dist, not to <site>/dist, and skips the post-build steps. jx validate does not work on the generated root, and prints a note saying why; see Looking inside a build.

Exit codes

CodeMeaning
0Success
1The command ran and found a problem: config, documents, build, checks or doctor errors
2Usage error
3Environment: Node older than 22.19.0; DOCUSYSTEM_WORKFLOW_CONTRACT set and different from the package's; or another docusystem process holds the lock (the message names its pid)

The environment gate runs before any other work.

Environment

VariableEffect
CI=trueImplies strict.
GITHUB_ACTIONS=trueImplies --ci for check.
DOCUSYSTEM_LENIENT=1Equals --lenient (ignored by check).
DOCUSYSTEM_BRANCHThe default branch; set by the reusable workflow.
DOCUSYSTEM_WORKFLOW_CONTRACTSet by docs-build.yml. A different value than the package's makes the CLI exit 3, naming the uses: line to change.
DOCUSYSTEM_CATALOG_URLA test hook for --refresh-catalog.
NO_COLORHonored.

Besides these, only GITHUB_STEP_SUMMARY and GITHUB_OUTPUT (with --ci), PATH and HOME are read.

Strictness

strict = !lenient && (--strict || CI=true)

check is always strict and dev is always lenient. Passing both --strict and --lenient is a usage error.

  • Strict. The build generates content.docs.links: "error", so Jx itself fails and lists every broken link. The build fails on any lint error, any Jx output line matching ^(Content\b|Warning:|Error), and any failed assertion. Nothing is published.

  • Lenient. The build generates links: "warn" and downgrades lint errors and those lines to warnings.

  • Never downgraded: config errors, a failing jx, failed output assertions and the contrast gate.

Leniency is a per-run flag for the first pass, not a file setting, and the reusable workflows expose no lenient input.

A lenient build (the default outside CI, and what dev always runs) can therefore print warnings and still fail: the output assertions run after the build and nothing relaxes them. A failure about a page names the page and the Markdown file it was built from, and the closing lines say that leniency does not reach it. The usual case is a raw HTML <a href> in Markdown: lint reports it with file:line, Jx writes an empty link, and the assertion "no page has an empty link" fails every build. The earlier starter published such a link without a word, so a repository that moves from the starter can meet this on its first build. Write [text](url); docusystem lint lists the places.

Output conventions

Every stage prints with one prefix: preflight:, assemble:, stage:, lint:, nav:, jx:, postbuild:, assert:, contrast:, links:, overrides: and catalog:.

With --ci, every error or warning that has a location is also printed as a GitHub annotation: ::error file=docs/x.md,line=N,title=<stage>::message, with %0A for newlines. check --ci then appends a summary to $GITHUB_STEP_SUMMARY, with the package and Jx versions, the runtime, overrides and the catalog source, so a red run can be read without a checkout. It writes dist=<absolute path>, page-url=https://<domain>/ and pages=<n> to $GITHUB_OUTPUT.

On a failed Jx run the build prints docusystem: jx build failed. The assembled project is <root>; run: <execPath> <jx.js> build <root> and everything it knows.

For docs/, overrides/ and public/: a symbolic link is followed only when its real path lies inside the repository root and not inside .git/, node_modules/, or the site's own .docusystem/ and dist/. Directory cycles are cut. Any other symbolic link is skipped and reported:

stage: docs/x.md is a symbolic link outside the repository: not published

Under strict, a skipped symbolic link is an error. Nothing the build writes is a symbolic link, except the links to the installed Jx packages inside the generated root.

Deletion policy

The CLI deletes only paths it computed from the site folder: <site>/.docusystem/** and <site>/dist. There is no --out option, so the published path is fixed.

Repository root and paths

The repository root is the nearest ancestor of the site folder that contains .git (a directory or a file), else the parent of the site folder. The docs folder (default ../docs) is resolved against the site folder and must lie inside the repository root.