/** * Extract manual pattern fields from a lesson body. * Pipeline 1 (Proposal 186 / ADR-058): zero-LLM compilation. * * Supported fields (case-insensitive, bold or plain): * **Pattern:** OR fenced ```yaml block below the marker (compound ast-grep) * **Engine:** regex | ast | ast-grep * **Scope:** glob, glob, !negated-glob * **Severity:** error | warning * **Message:** (#1265) */ export interface ManualPattern { /** * Flat pattern text. Empty string when the lesson provides a compound * `astGrepYamlRule` instead. The two fields are mutually exclusive at the * consumer level (buildManualRule picks whichever is set). */ pattern: string; engine: 'regex' | 'ast' | 'ast-grep'; fileGlobs?: string[]; severity: 'error' | 'warning'; /** Optional rich message for the compiled rule. Falls back to lesson heading if absent. */ message?: string; /** * Optional code snippet parsed from a `### Bad Example` markdown section in * the lesson body. Used by the compile-time smoke gate (ADR-087 / mmnto/totem#1408) * to verify the rule fires against its own bad example before landing in * compiled-rules.json. Empty blocks are treated as absent. The gate is not * required for Pipeline 1 rules in #1408 - a dry-run sweep precedes the flip. */ badExample?: string; /** * Compound ast-grep rule (NapiConfig shape) parsed from a fenced ```yaml * block immediately following the `**Pattern:**` marker. Mutually exclusive * with the flat `pattern` string. Only valid when `engine === 'ast-grep'`. * * Parsing contract: the fence must be tagged `yaml` (not bare ```). The * scan stops at the next bold-field marker or EOF so that downstream * sections (Message, Bad Example, narrative) can live freely below. */ astGrepYamlRule?: Record; } /** * Parse the declared severity from a lesson body's `**Severity:** error` / * `Severity: warning` prose convention (mmnto-ai/totem#1656). Returns the * normalized `'error' | 'warning'` value if declared, otherwise `undefined`. * * Reuses `extractField` for the prose-extraction rules (markdown-bold * tolerance, mandatory colon, case-insensitive match, line-anchored). Then * strips trailing markdown boundary markers and sentence punctuation so * common shapes like `**Severity: error.**` (full-line bold with period), * `**Severity:** error.` (trailing period on the value), and * `**Severity:** \`error\`` (backtick-wrapped value) all normalize to the * same token. Strict equality follows the strip so out-of-vocabulary tokens * (`info`, `critical`) still return `undefined` and preserve the * compile-pipeline's default fallback to `'warning'`. * * Added as a shared helper so the compile pipeline's declared-severity * override (in `compile-lesson.ts::compileLesson`) and the CLI's cloud-path * override (in `compile.ts`) normalize from a single source of truth. */ export declare function parseDeclaredSeverity(body: string): 'error' | 'warning' | undefined; export declare function extractField(body: string, field: string): string | undefined; /** * Extract a multi-line field value from a lesson body (#1265). * * Unlike `extractField` which captures only the first line, this captures from * the field marker line through subsequent continuation lines, stopping at * either the next BOLD `**Field:**` marker or EOF. Used for the `**Message:**` * field where remediation guidance often spans multiple paragraphs. * * Bare-colon prose (e.g. "Note: see above", "Fix: do X") is treated as * continuation, NOT a new field. Only `**bold**:` markers terminate the capture * — this matches markdown convention where structured fields are bolded and * unstructured prose is not. * * Returns the trimmed value, or `undefined` if the field is absent. */ export declare function extractMultilineField(body: string, field: string): string | undefined; /** * Extract the contents of a fenced code block that follows a `### Bad Example` * heading in a lesson body. Used by the compile-time smoke gate * (mmnto/totem#1408) to verify Pipeline 1 rules against their own bad * example. Mirrors `extractBadGoodSnippets` for Pipeline 3 but targets a * markdown heading rather than a bold field marker because Pipeline 1 * lessons conventionally use headings for worked examples. * * Returns `undefined` when: * - No `### Bad Example` heading is present * - The heading is present but no fenced code block follows before the * next heading or EOF * - The code block is empty * * Both ``` and ~~~ fence styles are accepted to stay aligned with * `extractCodeBlock`. */ export declare function extractBadExample(body: string): string | undefined; /** * Extract the contents of a fenced code block that follows a `### Good Example` * heading in a lesson body. Symmetric counterpart of `extractBadExample`, used * by the mmnto-ai/totem#1580 over-matching check: the compile-time smoke gate * runs the compiled rule against `goodExample` and rejects it if the pattern * fires. * * Returns `undefined` under the same conditions as `extractBadExample` (no * heading, no fence, empty block). Both fence styles (``` and ~~~) are * accepted for parity with `extractCodeBlock`. */ export declare function extractGoodExample(body: string): string | undefined; /** * Extract a yaml-tagged fenced code block following a `**Field:**` marker. * * Scan starts on the line after the field marker and stops at the first * subsequent bold-field marker (same terminator used by extractMultilineField) * or EOF. Only yaml-tagged fences (```yaml or ~~~yaml, case-insensitive) are * accepted — a bare ``` fence is ignored so lessons can still include prose * code blocks below the pattern without accidentally being parsed as a rule. * * Returns the parsed object on success. Returns null when: * - The field marker is absent * - No yaml fence appears before the next field marker or EOF * - The fence content fails to parse as YAML * - The parsed value is not a plain object (string / array / null rejected) * * Motivation: Pipeline 1 (manual) authoring for compound ast-grep rules * (`astGrepYamlRule` on CompiledRule). The flat string pattern captured by * extractField cannot carry nested `inside:` / `has:` / `not:` combinators; * a yaml fence can. Pack authors need a zero-LLM path to author compound * rules ahead of the 1.15.0 Pack Distribution milestone. */ export declare function extractYamlRuleAfterField(body: string, field: string): Record | null; /** * Parse the lesson body's `**Scope:**` prose declaration into a glob list. * * Splits on TOP-LEVEL commas only — commas nested inside `{...}` brace groups * are preserved as part of a single glob token, so brace-expanded patterns * like `**\/*.{ts,tsx}` and `!**\/*.{test,spec}.{ts,tsx}` survive intact for * `sanitizeFileGlobs` to expand downstream. Returns `undefined` when the field * is absent OR the value is empty / whitespace-only. Returns a non-empty * `string[]` otherwise; order is preserved as authored, `!`-prefixed * exclusion entries are kept verbatim. * * Used by both Pipeline 1 (`extractManualPattern`) and Pipeline 2/3 * (`buildCompiledRule` override path for mmnto-ai/totem#1665). */ export declare function parseDeclaredScope(body: string): string[] | undefined; /** * Set-of-strings equality on glob arrays. Order-insensitive, * duplicate-insensitive. Sign characters (`!` exclusion prefix) are part of * the string and matter for equality — `'!**\/*.test.*'` does not equal * `'**\/*.test.*'`. Used by mmnto-ai/totem#1665 divergence detection. */ export declare function isGlobSetEqual(a: readonly string[], b: readonly string[]): boolean; /** * Try to extract manual pattern fields from a lesson body. * Returns null if the lesson doesn't contain a Pattern: field. */ export declare function extractManualPattern(body: string): ManualPattern | null; /** * Extract ALL values for a repeated field from a lesson body. * Unlike extractField (first match only), this returns every match. * * Supports the same four forms as extractField (#1282): `**Field:**`, * `**Field**:`, `**Field:`, and plain `Field:`. */ export declare function extractAllFields(body: string, field: string): string[]; /** Strip surrounding backticks from an inline code value. */ export declare function stripInlineCode(value: string): string; export interface RuleExamples { hits: string[]; misses: string[]; } /** * Extract Example Hit/Miss lines from a lesson body. * Returns null if no examples are present (backward compatible). */ export declare function extractRuleExamples(body: string): RuleExamples | null; export interface BadGoodSnippets { bad: string[]; good: string[]; } /** * Extract Bad/Good code snippets from a lesson body (Pipeline 3). * Supports both fenced code blocks and inline text after the field. */ export declare function extractBadGoodSnippets(body: string): BadGoodSnippets | null; //# sourceMappingURL=lesson-pattern.d.ts.map