@cli-schema/spec
v0.2.0
Published
TypeScript types, meta-schema, and validator for the CLI Schema specification (https://github.com/cli-schema/cli-schema)
Downloads
6,043
Readme
@cli-schema/spec
TypeScript types, the vendored meta-schema, and a validator for the CLI Schema specification v1 — the open standard for describing command-line interfaces in a language-agnostic, machine-readable way.
This is the only package in the cli-schema-js
monorepo with no CLI-framework dependency. It defines the shape of a CLI Schema document;
@cli-schema/commander is what actually
produces one from a real CLI.
Quickstart
npm install @cli-schema/specimport { validate, SCHEMA_VERSION, type CliSchema } from '@cli-schema/spec'
const doc: CliSchema = {
schemaVersion: SCHEMA_VERSION,
name: 'mytool',
version: '1.0.0',
}
const result = validate(doc)
if (!result.valid) throw new Error(JSON.stringify(result.errors, null, 2))That's the minimum: a document only needs schemaVersion, name, and version to be valid —
everything else (commands, parameters, environment, intent, ...) is optional enrichment.
Purpose
CLI help text is written for humans, completion scripts are hand-authored per shell, and AI agents guess flags. CLI Schema fixes this by defining one JSON document format that describes a program's commands, parameters, intent, auth requirements, environment dependencies, and output capabilities — so agents, IDEs, shell-completion generators, and docs tooling can all read the same document instead of re-deriving it.
@cli-schema/spec is the compile-time and runtime contract for that format: the types you build
a document against, and the validator you check it with before trusting it.
Features
- Full v1 type coverage — every object in the spec has a corresponding TypeScript interface:
CliSchema(root),Command,Namespace,Parameter,Constraint,Intent,Output,Environment,EnvVar,ConfigFile,DefaultHandler,Shortcut,Deprecation. - The normative meta-schema, vendored —
schema/cli-schema.meta-schema.jsonfrom the spec repo, re-exported at@cli-schema/spec/meta-schema.jsonfor tools that want the raw JSON Schema directly (e.g. to validate in a non-JS pipeline, or feed to a codegen tool). - A ready-to-use validator —
validate()/assertValid(), backed by ajv's 2020-12 dialect support. No need to wire up ajv yourself. inferIntentFromHttp— a small pure helper for CLIs that wrap HTTP APIs: derives a reasonable {@link Intent} from an HTTP verb (GET/HEAD→ safe & idempotent,PUT→ idempotent,DELETE→ destructive & idempotent,POST/PATCH→ unset, since their semantics are endpoint-specific).- Vendor extensions typed — every object that permits
x-prefixed fields (spec §14) is typed to accept them ([extension: \x-${string}`]: unknown), sox-my-tool: {...}type-checks withoutas any`.
Usage
Building a document by hand
The types double as documentation of the format — reach for the spec itself for full field semantics, but a well-populated document looks like:
import type { CliSchema } from '@cli-schema/spec'
const doc: CliSchema = {
schemaVersion: 1,
name: 'gh',
version: '2.45.0',
description: 'GitHub CLI — bring GitHub to your terminal',
requiresAuth: true,
authCommands: ['auth login', 'auth logout'],
reservedMetaCommands: ['__schema'],
commands: [
{
name: 'status',
summary: 'Print information about relevant issues, pull requests, and notifications',
intent: { destructive: false, idempotent: true, requiresAuth: true },
},
],
namespaces: [
{
segment: 'repo',
commands: [
{
name: 'delete',
path: ['repo'],
parameters: [
{ role: 'positional', name: 'repository', type: 'string', required: true },
{ role: 'confirmationSkip', name: 'yes', type: 'boolean', required: false },
],
intent: { destructive: true, idempotent: true, scope: 'global', requiresConfirmation: true },
},
],
},
],
}In practice you'll usually generate this from a live CLI rather than write it by hand — see
@cli-schema/commander.
Validating an untrusted document
Per spec §15, consumers should treat schema documents as untrusted input:
import { validate, assertValid } from '@cli-schema/spec'
const { valid, errors } = validate(untrustedDoc)
// errors is an ajv ErrorObject[] — empty when valid
assertValid(untrustedDoc) // throws with a formatted message if invalidReading the raw meta-schema
import metaSchema from '@cli-schema/spec/meta-schema.json' with { type: 'json' }Useful if you want to validate documents with your own ajv instance, a different validator entirely, or a non-JS tool.
Deriving intent from an HTTP verb
import { inferIntentFromHttp } from '@cli-schema/spec'
inferIntentFromHttp('DELETE') // { destructive: true, idempotent: true, scope: 'global' }
inferIntentFromHttp('POST') // undefined — annotate explicitly, semantics vary per endpointRelated packages
@cli-schema/zod— deriveParameters from Zod schemas@cli-schema/commander— generate a fullCliSchemafrom a live Commander tree
License
MIT
