npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@clidoc/core

v1.1.1

Published

OpenCLI types, offline validation, and Markdown reference generation for CLI documentation

Readme

@clidoc/core

npm version npm downloads CI Coverage Documentation Discord

Parse, validate and render CLI documentation from one portable OpenCLI 1.0.0-alpha.14 document. This is the library underneath every clidoc package: use it directly if you already have an OpenCLI document, or pair it with a framework package to generate one from your CLI.

npm install @clidoc/core
import { parse, validate, renderMarkdown, generatePages } from '@clidoc/core';

const document = parse(sourceText); // JSON or YAML; throws on invalid input
const result = validate(document); // { valid, errors }
const markdown = renderMarkdown(document);
const pages = generatePages(document, { basePath: '/cli' });

The published package bundles the exact schema pinned in upstream/opencli/spec.schema.json, so validation works offline.

Where it fits

| You want to | Use | | ------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Generate a document from your CLI | @clidoc/yargs, @clidoc/commander or @clidoc/oclif | | Validate, render Markdown, completions or MCP tools from the shell | @clidoc/cli | | Publish reference pages in your docs site | @clidoc/docusaurus or @clidoc/vitepress |

See the API reference and the runnable demos.

Why clidoc

  • Compared to hand-written reference pages: the document comes from the same command definitions your CLI runs, so options and arguments can't drift from --help. Hand-written guides still sit alongside the generated pages.
  • Compared to --help output alone: you get a validated, structured document (JSON/YAML) that also renders to Markdown, shell completions and MCP tool definitions, not just terminal text.
  • Compared to oclif readme: that command targets oclif projects and writes into a README. clidoc's OpenCLI document is framework-neutral, so yargs, Commander and oclif CLIs share one pipeline and one set of docs-site integrations.

generatePages returns a landing page and one page per visible command. Each command page includes a generated usage synopsis: required values use <value>, optional elements use [element], and repeatable elements use .... The synopsis includes visible command flags and inherited global flags. Each page has id, title, path, and Markdown content. A command named <binary> foo-bar keeps the readable /commands/foo-bar route when its suffix is lowercase ASCII letters, digits, and single hyphens (up to 64 characters). Other names use a normalized readable prefix (up to 64 characters), a reserved ~, and a SHA-256 digest of the full command name. Each route depends only on its command name, so adding unrelated commands does not change existing URLs. The generator rejects a digest collision before returning any pages. This replaces the previous collision-dependent hash suffixes, so URLs for names outside the readable form may change. Landing links use the generated base path. The bundled JSON Schema is also available at @clidoc/core/schema.

validate checks documents against the vendored JSON Schema and, once that passes, against the logical rules ported from upstream's validate/validate.go: positional arguments must not place a required argument after an optional one, minItems/maxItems are only valid on variadic arguments and flags (with minItems <= maxItems), $FILE alternative sources must have a matching file declared in global.config, flag names and aliases must be unique per command, and group commands cannot declare args or flags. Errors use the same instancePath message shape as schema errors.

Adding author-supplied metadata

The framework packages generate a document from what your CLI's argument parser already knows, so things like examples, exitCodes, info.license/contact, install, and global config are usually missing. Add them with mergeDocument, then re-validate:

import { mergeDocument } from '@clidoc/core';

const documented = mergeDocument(document, {
  info: { license: { name: 'MIT', spdxId: 'MIT' } },
  install: [{ name: 'npm', command: 'npm i -g my-cli' }],
  commands: {
    'my-cli greet': {
      examples: [{ title: 'Basic', content: 'my-cli greet Ada' }],
      exitCodes: [{ code: 1, status: 'BAD_USER_INPUT_ERROR', summary: 'Missing name' }],
      flags: [{ name: 'language', alternativeSources: [{ type: '$ENV', property: 'LANG' }] }],
    },
  },
});

Plain objects (info, global, each command) merge recursively. Arrays replace the base array, except examples and exitCodes, which append, and flags/args, which are merged item-by-item matched by name — so you can add alternativeSources or a summary to one generated flag without repeating the rest of it. Commands not present in the generated document are added as-is. mergeDocument throws an Error listing every problem if the merged result fails schema validation.

Shell completion generation

generateCompletion(document, { shell: 'bash' | 'zsh' | 'fish', binary?: string }) validates an OpenCLI document and returns a standalone completion script. It supports nested commands, aliases, global/local flags, option and positional choices, and hidden entries, with no runtime dependency on Node or the target CLI. The optional binary overrides only the registered executable name. See the completion guide for activation, supported syntax, and limitations.

License

MIT. See LICENSE.

Author

Ben Houston, Sponsored by Land of Assets.