/** * Lenient frontmatter reader — ONE reader for the SKILL.md / subagent `---` block, * shared by `scan` and the PreToolUse rail (`agent-runtime`). It is deliberately * fault-tolerant: it audits arbitrary third-party files, so it must never throw * and must salvage the few scalar/list fields it needs even from a block that * isn't valid YAML. * * The strategy is "real parser, with a safety net": try `js-yaml` (so block * scalars, quoted/multi-line values, and flow arrays parse correctly for free); * if the block isn't valid YAML, fall back to a regex salvage of the requested * field and record `malformed: true` (the signal the `frontmatter-valid` rule * reports). A single bad line therefore never blanks out a whole file's metadata. * * This replaces three divergent hand-parsers (the old `readField` in scan.ts and * the regex parse in agent-runtime.ts); `core/frontmatter.ts` is a DIFFERENT * concern (the Level-1 `vigiles:` rule block) and is untouched. */ /** * 🔴 `js-yaml` IS REQUIRED LAZILY, AND THAT IS A MEASUREMENT, NOT A STYLE. The * same wrapper is in `core/settings-codec.ts` and `core/markdown.ts` with the * reason recorded: a top-level import puts the parser into the module graph of * every HOOK DECISION, because the hook runtime reaches the adapter registry * and from there a layout. This module became reachable that way on 2026-09-21 * through `PluginLayout.instructionChain` (a rule's `paths:` frontmatter is * what decides whether it loads at launch) — measured by * `src/hook-runtime-graph.test.ts`: 37 modules became 71 with an eager import. * `tsc` lowers this to CommonJS, so the `require` does not run until a * frontmatter block is actually parsed, and {@link frontmatterBody}, which needs * no YAML at all, never triggers it. */ export declare const yaml: () => typeof import("js-yaml"); export interface FrontmatterRead { /** Parsed mapping when the block is valid YAML, else null (malformed or scalar). */ readonly data: Record | null; /** Raw text inside the leading `---` fences, or null when there's no block. */ readonly block: string | null; /** True when a leading `---` block EXISTS but is NOT valid YAML. */ readonly malformed: boolean; } /** * The markdown BODY — everything after the leading frontmatter block, or the * whole text when there is none. * * Lives here, beside {@link readFrontmatter}, because `BLOCK_RE` above is the * ONE statement of where frontmatter ends; a caller slicing the body for itself * would be a second one, free to disagree (and the header records what the * first one already has to know about BOMs and legacy stamp comments). */ export declare function frontmatterBody(markdown: string): string; /** Extract + parse the leading frontmatter block, never throwing. */ export declare function readFrontmatter(markdown: string): FrontmatterRead; /** * A top-level scalar field — from parsed YAML when valid, else a regex salvage * from the raw block (handling a block scalar `>`/`|` and a quoted value that * starts on the next indented line). */ export declare function frontmatterScalar(fm: FrontmatterRead, key: string): string | undefined; /** * A tool-list field (`tools:` / `disallowedTools:`) — an array or a comma list, * normalized to string[]. Returns `null` when the key is ABSENT (the "no * contract / inherits all" signal the rail honors) and `[]` when the key is * PRESENT but empty ("no tools"). Salvages from the raw block when YAML is * malformed, so the rail still reads the contract. */ export declare function frontmatterList(fm: FrontmatterRead, key: string): string[] | null; //# sourceMappingURL=frontmatter-read.d.ts.map