/** * skills/model.ts * * The canonical skill model, hoisted into the SDK so every consumer parses, * serializes, and discloses skills the same way instead of each carrying its * own drifting copy. A skill is a Markdown document with a YAML-style * frontmatter block: * * --- * name: my-skill * description: One line the model reads to decide whether to open the skill. * --- * The full skill body in Markdown. * * PROGRESSIVE DISCLOSURE is the whole point of the split between the two parse * entry points here: * - `parseSkillIndex` reads ONLY the frontmatter (name + description + any * extra scalar/list keys) and never materializes the body. This is the * cheap "index line" a caller loads for every skill to decide which one is * relevant. * - `parseSkill` reads the full document including the body. This is the * expensive read a caller makes for exactly the one skill it decided to * invoke. * * The frontmatter parser is intentionally a small, well-defined subset of YAML * (scalar strings and single-line string lists) rather than a full YAML engine: * it is the exact shape skills use, it pulls in no dependency, and an * unsupported construct is surfaced as the raw string rather than guessed at. */ /** A JSON-ish frontmatter value: a scalar string or a list of strings. */ export type SkillFrontmatterValue = string | readonly string[]; /** Parsed frontmatter: the two reserved keys plus any extra author-supplied keys. */ export interface SkillFrontmatter { readonly name: string; readonly description: string; /** Every frontmatter key other than name/description, preserved verbatim. */ readonly metadata: Readonly>; } /** * The cheap "index line" of a skill: everything a caller needs to decide * whether to open it, and nothing more. Deliberately omits the body. */ export interface SkillIndexEntry extends SkillFrontmatter { /** Millisecond epoch of the skill's last modification, when the store knows it. */ readonly updatedAt?: number | undefined; } /** A fully-disclosed skill: its index line plus the Markdown body. */ export interface Skill extends SkillIndexEntry { readonly body: string; } /** * Parse only the frontmatter of a skill document, the cheap index-line read. * The body is never materialized. `updatedAt`, when known by the caller (e.g. * a file mtime), is threaded through unchanged. */ export declare function parseSkillIndex(text: string, updatedAt?: number): SkillIndexEntry; /** * Parse a full skill document, frontmatter plus the Markdown body. A single * leading blank line after the closing fence and a single trailing newline are * trimmed, so a body round-trips exactly through `serializeSkill` (which emits * one trailing newline) and a conventional newline-terminated file yields a * clean body. */ export declare function parseSkill(text: string, updatedAt?: number): Skill; /** * Serialize a skill back to its canonical `---` frontmatter + body Markdown * form. name and description are emitted first (in that order), then any extra * metadata keys in insertion order, so a round trip is stable. */ export declare function serializeSkill(skill: Skill): string; /** Project a full skill down to its index line (drops the body). */ export declare function toSkillIndexEntry(skill: SkillIndexEntry): SkillIndexEntry; /** The allowed shape of a skill name: a filesystem- and URL-safe slug. */ export declare const SKILL_NAME_PATTERN: RegExp; /** Whether a candidate skill name is well-formed (safe slug, non-empty). */ export declare function isValidSkillName(name: string): boolean; //# sourceMappingURL=model.d.ts.map