@clidoc/vitepress
v1.1.1
Published
Publish a generated CLI reference in VitePress from an OpenCLI document
Maintainers
Readme
@clidoc/vitepress
Add an always-current CLI reference to your VitePress site. Generate pages and sidebar entries from your CLI's OpenCLI document instead of maintaining them by hand.
Install the publisher, parser, and VitePress:
npm install -D @clidoc/vitepress @clidoc/core vitepressExport an OpenCLI document from your CLI, for example with
mycli docgen --format yaml --output cli.ocs.yaml, using the docgen command from @clidoc/yargs, @clidoc/commander or @clidoc/oclif.
In docs/.vitepress/config.mts, with cli.ocs.yaml at the project root:
import { defineConfig } from 'vitepress';
import { parse } from '@clidoc/core';
import { writeVitePress } from '@clidoc/vitepress';
import { readFile } from 'node:fs/promises';
import { fileURLToPath } from 'node:url';
const document = parse(await readFile(new URL('../../cli.ocs.yaml', import.meta.url), 'utf8'));
const cliSidebar = await writeVitePress(document, {
outputDir: fileURLToPath(new URL('..', import.meta.url)),
basePath: '/cli',
});
export default defineConfig({
themeConfig: { sidebar: [{ text: 'CLI', items: cliSidebar }] },
});Keep handwritten pages in docs/. With basePath: '/cli', add only the
generated paths to .gitignore:
docs/cli.md
docs/cli/commands/
docs/.clidoc-generated.jsonRun npx vitepress dev docs to preview the site.
The output contains ordinary Markdown. VitePress's v-pre custom container
keeps CLI-authored Vue expressions literal while still rendering headings,
links, tables, and fenced code. basePath determines both routes and file
locations below outputDir. Regeneration removes only files recorded in
.clidoc-generated.json, leaving hand-written pages intact. On the first run
after upgrading from OpenCLI, it also removes stale pages listed in
.opencli-generated.json and deletes that legacy manifest.
< and > outside fenced code blocks and inline code spans are escaped to
entities, since v-pre stops Vue mustache interpolation but not its SFC
parser's tag scanning; as a result, HTML written in a description renders as
literal text rather than as markup on VitePress.
Command pages use the synopsis generated by @clidoc/core. Required values use
<value>, optional elements use [element], and repeatable elements use ....
The synopsis includes visible command flags and inherited global flags, and its
angle-bracket placeholders remain literal inside the fenced code block.
Generated command page filenames and sidebar links are stable and based on the
shared command routes. An ordinary binary-prefixed command such as
mycli deploy produces cli/commands/deploy.md and links to
/cli/commands/deploy when basePath is /cli. Names outside the readable
route form use a normalized prefix plus a deterministic hash suffix. This keeps
their URLs stable when unrelated commands are added while avoiding collisions.
Why / compared to alternatives
- Hand-written CLI reference pages go stale. These pages are regenerated from your CLI's own definitions (via a framework package), and your hand-written pages stay alongside them.
- Pasting
--helpoutput gives one unstructured block per command. Here each command gets its own page, usage synopsis, argument and flag tables, and a sidebar entry. oclif readmeupdates a README for oclif projects only. This publishes into a VitePress site from any CLI that can produce an OpenCLI document (Yargs, Commander, oclif).
Related packages
@clidoc/core: parse, validate and render the OpenCLI document.- Generate the document from your CLI with
@clidoc/yargs,@clidoc/commander,@clidoc/oclif. @clidoc/docusaurusfor Docusaurus.@clidoc/cli: validate the document first withclidoc validate.- Publishing guide and the demo site.
License
MIT. See LICENSE.
Author
Ben Houston, Sponsored by Land of Assets.
