burgee
API reference

burgee/schema

Every export of burgee/schema, with its signature and doc comment: commandSchemaOf, inputSchemaOf, schemaOf, summaryOf, Manifest, plus 4 types.

burgee/schema — the schema surface and the manifest it reads, by itself. See index.ts.

import { commandSchemaOf, inputSchemaOf, schemaOf, … } from 'burgee/schema';

Functions

commandSchemaOf

function commandSchemaOf(node: CommandNode, root: string[]): CommandSchema;
ParameterType
nodeCommandNode
rootstring[]

Returns CommandSchema

inputSchemaOf

function inputSchemaOf(node: CommandNode): JsonSchema;
ParameterType
nodeCommandNode

Returns JsonSchema

schemaOf

function schemaOf(manifest: Manifest): ProgramSchema;
ParameterType
manifestManifest

Returns ProgramSchema

summaryOf

Above the budget (N13): every command by name and summary, and the drilling command for one in full.

function summaryOf(manifest: Manifest, budget: number): SchemaSummary;
ParameterType
manifestManifest
budgetnumber

Returns SchemaSummary

Classes

Manifest

class Manifest {
    readonly commands: CommandNode[];
    readonly plugins: Plugin[];
    /** The program's own name, which the user never types; `execute` strips it. */
    rootPath: string[];
    /** Reported by `--schema`, `--version` and the MCP handshake; the owning package.json otherwise (V4). */
    version?: string;
    /** With a prefix, every option reads `PREFIX_OPTION_NAME` unless it names its own env (V2). */
    envPrefix?: string;
    /** Config discovery is opt-in; the name is the file stem and the package.json field (V6). */
    config?: {
        name: string;
    };
    /** Characters of `--schema` output above which it is summarised (N13). */
    schemaBudget?: number;
    add(node: CommandNode): void;
    /**
     * Register a plugin, after the plugin host has read it (`plugin.ts`).
     *
     * Nothing is pushed until everything has been checked, so a refused plugin contributes no
     * command and leaves no half-registration behind: `use()` used to push first and read the
     * object afterwards, which is how `use(undefined)` became a `TypeError` one line later.
     */
    use(plugin: Plugin): void;
    /** `enforce: 'pre'` first, then unordered, then `'post'` — the Vite/Rolldown convention. */
    private ordered;
    /** Whether any registered plugin declares a hook at `stage` — so a run without one pays nothing. */
    declares(stage: HookStage): boolean;
    /**
     * `parse` (D-122): argv in, argv out, before the command is resolved. Each plugin, in
     * `enforce` order, is handed what the previous one returned; returning nothing keeps it.
     * A filter is matched against the typed argv, since no command has been resolved yet.
     */
    parse(argv: string[]): Promise<string[]>;
    fire(stage: Exclude<HookStage, 'parse'>, command: string, options: Record<string, unknown>): Promise<void>;
    find(path: string[]): CommandNode | undefined;
    /**
     * Longest-prefix match of argv against declared command paths. The root's own
     * name is not typed by the user, so it is skipped when matching.
     */
    resolve(argv: string[], root?: string[]): {
        node: CommandNode | undefined;
        rest: string[];
    };
}

Interfaces

CommandSchema

interface CommandSchema {
    /** The command as typed, without the program name: `config get`. */
    name: string;
    description?: string;
    summary?: string;
    /**
     * What running it does, or `'withheld'` — published either way, because an agent reading
     * the program as data is better served by *this exists and is not for you* than by a gap
     * it cannot tell from a command that does not exist (N6).
     */
    effects?: DeclaredEffects;
    /** What `--json=` selects from (N14), when the command declares it. */
    fields?: readonly string[];
    deprecated?: boolean | string;
    /** The heading it is listed under (M1). */
    group?: string;
    /** Its handler loads on dispatch (M2): this schema was complete without it. */
    lazy?: true;
    /** Which plugin contributed it (M3). */
    plugin?: string;
    arguments: ArgumentSpec[];
    options: Record<string, OptionSpec>;
    /**
     * The constraints between options (S2/S6), which `validate.ts` already enforces and the
     * schema did not publish. Without them an agent can only discover that `--a` conflicts
     * with `--b` by sending both and reading exit 2 — a round trip per constraint, and under
     * E1 an exit 2 means *rewrite the command*, so it may well send the same pair again.
     *
     * Omitted entirely when a command declares none, so a reader can tell "no constraints"
     * from "constraints not published".
     */
    relations?: PublishedRelation[];
    examples: Example[];
    /** The arguments and options as one JSON Schema object — what an MCP tool call takes. */
    inputSchema: JsonSchema;
}

JsonSchema

interface JsonSchema {
    type: 'object';
    properties: Record<string, JsonSchemaProperty>;
    required: string[];
    additionalProperties: false;
}

ProgramSchema

interface ProgramSchema {
    schemaVersion: 1;
    name: string;
    version?: string;
    description?: string;
    /**
     * F1 — what each exit code means, so an agent branches on the number without reading prose:
     * the contract's seven, the same table `ExitCode` exports.
     */
    exitCodes: Readonly<Record<string, number>>;
    commands: CommandSchema[];
    /**
     * J4 — the reserved surfaces a façade program declares for itself, which burgee therefore
     * withholds: the program wins, and this says so rather than leaving a caller to find the
     * surface missing. Absent when it shadows none. A native program cannot shadow them —
     * `defineProgram` refuses the names (V5) — so only the commander and yargs façades set it.
     */
    shadows?: ('--json' | '--mcp' | 'completion')[];
}

SchemaSummary

interface SchemaSummary {
    schemaVersion: 1;
    name: string;
    version?: string;
    description?: string;
    /** The full schema exceeded the budget; this lists every command and how to get one in full. */
    summarised: true;
    budget: number;
    commands: {
        name: string;
        summary?: string;
        effects?: DeclaredEffects;
    }[];
    hint: string;
}

On this page