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

@yohn-jp/cli-canon

v0.1.7

Published

Internal canonical TypeScript framework for yohn-jp CLI products.

Readme

CLI Canon

Canonical TypeScript CLI contracts for yohn-jp products

@yohn-jp/cli-canon is the shared CLI foundation used to define a product command surface once and derive typed handlers, routing, help, discovery, invocation metadata, Skill projections, Path Canon, output behavior, and package certification from the same authority.

It is intentionally not a general-purpose CLI framework. Product-domain authorization, lifecycle/state-machine decisions, provider behavior, filesystem safety, transport authority, and domain schemas remain owned by each consumer.

Install

Requires Node.js 24 or newer and Zod 4.

npm install @yohn-jp/cli-canon zod

The package is a library and does not install a standalone CLI binary.

Quick start

import * as z from "zod";
import {
  bindHandlers,
  compileProduct,
  defineCommands,
  flag,
  option,
  positional,
  projectInvocation,
} from "@yohn-jp/cli-canon";
import { runNodeCli } from "@yohn-jp/cli-canon/node";

const commands = defineCommands({
  "document.render": {
    route: ["document", "render"],
    summary: "Render a document.",
    description: "Render a document to the selected output path.",
    examples: ["example document render input.md --out=out.html"],
    input: {
      file: positional(z.string(), { description: "Input document." }),
      target: positional(z.string(), {
        required: false,
        description: "Optional named target.",
      }),
      out: option("--out", z.string(), {
        aliases: ["-o"],
        required: true,
      }),
      format: option("--format", z.enum(["full", "json"]), {
        valueArity: "optional",
      }),
      json: flag("--json"),
    },
    result: z.object({ writtenFile: z.string() }),
  },
});

const handlers = bindHandlers(commands)({
  "document.render": ({ out }) => ({ writtenFile: out }),
});

const product = compileProduct({
  name: "example",
  commands,
  handlers,
  schemaProjectionCompleteness: "complete",
});

const result = await runNodeCli(product, ["document", "render", "input.md", "--out", "out.html"]);

const invocation = projectInvocation(product, "document.render", {
  file: "input.md",
  out: "out.html",
  json: true,
});

if (invocation.state === "ready") {
  console.log(invocation.value);
  // { executable: "example", argv: ["document", "render", ...] }
}

One authority, multiple projections

typed authoring declarations
          |
     compileProduct
          |
   CompiledProduct
    /   |    |    \
runtime help Skill discovery
          |
 invocation / Path / fixtures

A CLI fact is authored once. Routing, usage, progressive help, JSON discovery, Skill command metadata, and invocation argv are derived rather than maintained as parallel tables.

Package surfaces

| Import | Purpose | | ---------------------------- | --------------------------------------------------------- | | @yohn-jp/cli-canon | Authoring, compiler, projections, Path/Skill/Output Canon | | @yohn-jp/cli-canon/node | Node.js / Commander runtime adapter | | @yohn-jp/cli-canon/testing | Reusable source/built/packed certification primitives |

The root import is side-effect free. Commander is private to the Node adapter.

Command and grammar contract

CLI Canon supports:

  • nested command routes;
  • required and optional positionals;
  • flags and required/optional-value options;
  • aliases and repeatable options;
  • --name=value;
  • options declared with placement: "anywhere";
  • trailing rawArgs();
  • progressive root/domain/leaf help;
  • --help=full and --help=json;
  • deterministic JSON discovery.

Unsupported grammar fails closed rather than falling back to a second parser.

Current explicit limits:

  • orderedOptionGroups are rejected as UNSUPPORTED_GRAMMAR;
  • optionLookingValuePolicy: "reject" is rejected as UNSUPPORTED_GRAMMAR.

The default option-looking-value behavior remains Commander's consume semantics.

Invocation Canon

Executable invocation is a structured value, not a shell string:

{ executable: string, argv: string[] }

projectInvocation(product, commandId, bindings) derives argv from Command Canon. Missing required bindings produce a requires-input projection and do not expose executable argv.

Skill command bindings use the same projection through skillCommand(...); usage text is display-only and is never reparsed for execution.

Help, discovery, and public schemas

Text help and JSON discovery derive from the same compiled command graph.

For incremental migrations that must preserve an established terminal format, the Node adapter exposes a typed help-presentation hook. Canon still parses the help mode and resolves the target route; the adapter receives that resolved request plus scoped discovery metadata and may only render the product-specific terminal shape:

import { textOutput } from "@yohn-jp/cli-canon";
import { runNodeCli } from "@yohn-jp/cli-canon/node";

await runNodeCli(product, argv, {
  legacyRoutes,
  terminalAdapter: {
    help: ({ mode, request, discovery }) => textOutput(renderProductHelp({ mode, request, discovery })),
  },
});

This keeps help-mode parsing, route ownership, discovery composition, and command metadata in CLI Canon while allowing compatibility presentation without parsing Canon-rendered text.

Pass package metadata at composition time when package identity should be projected:

import packageMetadata from "./package.json" with { type: "json" };

const product = compileProduct({
  name: "document-cli",
  packageMetadata,
  schemaProjectionCompleteness: "complete",
  commands,
  handlers,
});

projectProductSchemas(product, "complete") projects framework-owned value contracts to JSON Schema. Unsupported complete projections fail explicitly. Use "structural-only" when a schema cannot claim equivalent complete validation.

Output contract

CLI Canon keeps exit status, stream, bytes, and failure classification together.

Machine JSON:

  • is complete or fails;
  • is never byte-truncated;
  • counts UTF-8 bytes including the final newline;
  • rejects non-finite numbers and unsupported JSON values instead of silently converting or omitting them.

Products may supply a typed domain-error adapter without moving domain error semantics into CLI Canon.

Skill Canon

Skills are intent-oriented projections over Command Canon and product-owned results. They may contain prose, command references, delegation, invariants, and opaque domain-result references.

Public Skill projections reject unknown commands, private commands, unknown delegated Skills, and delegation cycles at construction.

Skill text and JSON use the shared output policy. The default budget is 4096 UTF-8 bytes; over-budget output fails explicitly and is never truncated.

Path Canon

Path Canon models addresses, not permissions.

It supports derived Path IDs, parameters, file/directory kinds, parent references, explicit cwd/home/env/platform context, and ordered root strategies. Resolution is lexical and side-effect free; it does not create files, resolve authorization, or grant filesystem ownership.

Certification

@yohn-jp/cli-canon/testing provides reusable certification scenarios with:

  • stable scenario identity;
  • target command identity;
  • explicit input;
  • independent expected output;
  • required source/built/packed lanes;
  • optional setup.

The repository package gate builds one tarball, installs that exact artifact into an isolated consumer, and verifies exports, public types, root-import purity, and runtime behavior.

The current architecture-conformance baseline is recorded in test/architecture-conformance.md.

Architecture

The README is an entry point, not a second architecture authority.

| Authority | Scope | | ------------------------------------------------------- | --------------------------------------------------------------- | | Canonical architecture | Normative ownership, boundaries, and implementation rules | | Architecture design | Cross-product rationale, admission corpus, and migration design |

Releases

Release notes live under docs/releases/.

  • 0.1.7 — typed help-presentation compatibility hook for incremental migrations.
  • 0.1.6 — Canon-owned mixed-migration help/discovery and Node presentation surfaces.
  • 0.1.0 — initial public package release.
  • Releasing CLI Canon — bootstrap manual publish and subsequent OIDC release workflow.

Security

Report suspected vulnerabilities privately as described in SECURITY.md. Do not file sensitive vulnerability details in a public Issue.

Contributing

See CONTRIBUTING.md for the repository development, architecture, branch, verification, and pull request contracts. Participation is governed by the Code of Conduct.

Development

pnpm install --frozen-lockfile
pnpm run verify

pnpm run verify is the authoritative local verification entry point.

License

MIT — see LICENSE.