/** * Prompts embedded in source files. * * `check` and `diff` read `.txt`, `.md`, `.prompt` and `.tmpl`. Real prompts live * in TypeScript template literals, Python triple-quoted strings and YAML blocks, * so adopting Trazum has meant first refactoring them out into standalone files — * a change to somebody's application as the price of admission. * * **It reads a marker, it does not guess.** `// trazum:prompt` on the line before * the literal, and then the literal by delimiter matching. Guessing which string * in a file is a prompt is a heuristic, and a heuristic inside a tool used as a * CI gate produces failures on strings nobody meant to govern. A marker is one * line of noise in exchange for never being wrong about what it picked up. * * **Interpolation already works and is not a special case.** `${x}` inside a * template literal is exactly the placeholder shape `segment.ts` protects, so an * embedded prompt gets the same cache-prefix analysis, the same protection from * the rules, and the same `--reorder` treatment as a `{{x}}` template. Nothing * here has to know about it. * * **The honest limit:** a prompt assembled from concatenated pieces cannot be * read this way. `` `You are ${role}.` + rules.join('\n') `` is a prompt whose * text does not exist until it runs. This module declines it and says so rather * than governing the half it can see — a budget enforced against a fragment is a * green build for a prompt nobody measured. * * Scanned character by character rather than with a regex. The module it most * resembles shipped two quadratic patterns this week, and delimiter matching over * untrusted source is exactly the shape that goes wrong. */ export interface ExtractedPrompt { /** Name from `trazum:prompt `, or undefined when the marker was bare. */ name?: string; /** 1-based line of the marker comment, which is what an error should cite. */ line: number; /** The prompt text, delimiters removed and escapes resolved. */ text: string; /** The delimiter it was written with, so a writer could put it back. */ quote: '`' | '"' | "'" | '"""' | "'''"; /** Offsets of the text within the source, exclusive of the delimiters. */ start: number; end: number; } export interface DeclinedPrompt { line: number; /** * Why this marker produced nothing. * * `concatenated` is the interesting one: the text exists only at runtime. * `no-literal` means the marker was not followed by a string at all. * `unterminated` means the file ends inside the literal, which is a syntax * error in the source rather than a Trazum problem, but worth naming. */ reason: 'concatenated' | 'no-literal' | 'unterminated'; detail: string; } export interface ExtractionResult { prompts: ExtractedPrompt[]; declined: DeclinedPrompt[]; } /** * Finds every marked prompt in a source file. * * Returns what it found and what it refused, because a marker that produced * nothing is the case the author most needs to hear about: they asked for the * prompt to be governed and it is not being governed. */ export declare function extractPrompts(source: string): ExtractionResult; /** * A stable identifier for an embedded prompt, for budgets and reports. * * `src/prompts.ts#support` when the marker was named, `src/prompts.ts:12` when it * was not. Both are path-prefixed so the glob patterns in `trazum.config.json` * cover embedded prompts without learning a new syntax — `src/**` matches either. */ export declare function promptId(path: string, prompt: ExtractedPrompt): string; /** Whether a file is worth opening for extraction at all. */ export declare const SOURCE_EXTENSIONS: string[]; /** Cheap pre-filter: a source file with no marker has nothing to extract. */ export declare const hasMarker: (source: string) => boolean; //# sourceMappingURL=extract.d.ts.map