/** * Local context source parsing for `--context` / `--context-stdin` * (local-context plan, DESIGN.md D2/D3). * * D2 — pure, deterministic text analysis: `parseContextText` walks the * text once, building a positioned document-order stream of * (heading | question) items; `terms` and `subQueries` derive from that * stream while `headings` / `questions` are per-type projections. * `deriveSubQueries`, `buildBiasAppend`, and `slug` are pure helpers on * top of the same rules. * * D3 — `readContextSource` reads a file or stdin through an injected io * adapter (`readFile` / `readStdin`), enforces the raw byte cap before * decode, applies the NUL-in-first-8KiB binary heuristic, and returns * the decoded text plus its sha256. The module owns no fs access of its * own so tests and command handlers stay offline-friendly and stdin * reads stay owned by the invocation adapter. */ /** D3 (G2): byte cap applied to the raw read buffer before decode. */ export declare const MAX_CONTEXT_BYTES = 262144; /** D2.4: cap on derived sub-queries (the user query is not counted). */ export declare const MAX_SUBQUERIES = 8; /** D2.3: cap on derived focus terms. */ export declare const MAX_TERMS = 12; /** * D2.3: frozen stopword list. Membership tests use the derived * `STOPWORD_SET`; the frozen array is the shipped constant. */ export declare const STOPWORDS: readonly string[]; export interface ParsedContextText { /** In document order, deduped exact-trim (case-sensitive). */ readonly headings: readonly string[]; /** In document order, deduped exact, `?` stripped. */ readonly questions: readonly string[]; /** <= MAX_TERMS derived, deduped focus terms. */ readonly terms: readonly string[]; /** <= MAX_SUBQUERIES document-order interleaved stream (D2.4). */ readonly subQueries: readonly string[]; } /** * Parse context text into the D2 projections plus the derived streams. * * The walk is single-pass and deterministic: the interleaved * (heading | question) stream is built first (deduped, first-occurrence * positions), then `terms` and `subQueries` are derived from it. Lines * that match the heading pattern are headings even when they end with * `?`; question candidacy requires the raw line to end with `?` and be * at most 200 chars before stripping. */ export declare function parseContextText(text: string): ParsedContextText; /** * Pure helper producing the D2.4 stream directly; equivalent to * `parseContextText(text).subQueries` (it delegates there — the parser * computes the stream unconditionally in the same pass). */ export declare function deriveSubQueries(text: string): readonly string[]; /** D4: exact slug-equality key for section/heading matching. */ export declare function slug(value: string): string; /** * D2.5: bias/both query mutation. Returns the query unchanged when * there are no terms; otherwise appends ` (focus: )`, dropping * trailing terms until the appended segment fits MAX_BIAS_APPEND_CHARS * (at least one term is always retained). */ export declare function buildBiasAppend(query: string, terms: readonly string[]): string; /** D3: which source to read. */ export type ContextSourceKind = { readonly file: string; } | { readonly stdin: true; }; /** Injected io so the module stays test-offline and adapter-owned. */ export interface ContextSourceIo { readFile(filePath: string): Promise; /** * Reads at most `maxBytes` (plus the one chunk that crosses the bound): * the caller rejects any over-cap result, so implementations stop early * instead of draining an unbounded pipe into memory. */ readStdin(maxBytes: number): Promise; } export interface ContextSourceContent { readonly text: string; /** File source only (G6: always recorded; paths are not secrets). */ readonly path?: string; readonly sha256: string; readonly source: "file" | "stdin"; } export declare function readContextSource(kind: ContextSourceKind, io: ContextSourceIo): Promise; //# sourceMappingURL=context-file.d.ts.map