import type { Writable } from 'node:stream'; import { type OutputStyle } from '@williamthorsen/nmr-core'; import type { ReplayLine } from './check-cache.js'; import type { ReportFormat } from './report-format.js'; /** * The ceiling a rendered verdict, its newline included, is held to. * * POSIX guarantees a write at or below `PIPE_BUF` reaches a pipe whole, and 512 is the smallest bound the * standard permits, so one write of a line this size cannot be interleaved by a concurrent scope under * `pnpm --recursive`. No Node API reports the platform's own bound, and a per-platform table would move the * truncation point from one machine to the next. The ceiling governs pipes: a terminal offers no such * guarantee at any size. */ export declare const VERDICT_LINE_LIMIT = 512; /** * What a command nmr ran came to, holding the facts a reporting line is rendered from rather than the line * itself, so a machine-readable rendering spends the same record a human-readable one does. * * A recalled pass carries its saving as a duration and not as a decision about whether to mention it: whether * one is worth naming belongs to rendering, and a consumer bypassing the renderer inherits neither the * threshold nor an obligation to restate it. */ export type Verdict = { command: string; scope: string; } & VerdictOutcome; /** * How a command ended, together with the facts that ending carries and no other does, and the trailing detail * a line reserves room for. * * A recalled pass carries the excerpts it replays rather than a composed detail string, so the marker naming * them a recording, and the ceiling they are held to, stay with the module that owns the line's grammar. */ export type VerdictOutcome = { detail?: string; } & ({ outcome: 'passed'; durationMs: number; } | { outcome: 'failed'; durationMs: number; exitCode: number; } | { outcome: 'recalled'; ageMs: number; savedMs: number; replay?: ReplayLine[]; } | { outcome: 'no-op'; reason: 'empty-override' | 'noop-override'; }); /** * Renders a verdict as the line nmr reports it on, without the newline that terminates it. * * The line ends without terminal punctuation and reserves its tail for `detail`, so a later change appends to * the grammar rather than rewriting it. A detail carrying nothing but line breaks takes its whole clause with * it, rather than leaving a separator pointing at nothing. * * The marker takes no padding column: every plain marker a verdict reaches for is four characters, so the * lines align by construction. `formatStatusLine` pads to a column that `BLOCK` widens, and no verdict is one. */ export declare function renderVerdict(verdict: Verdict, style: OutputStyle): string; /** * Renders a verdict as the JSON object a machine consumer reads, without the newline that terminates it. * * Held to the ceiling the prose line is held to, so one write still reaches a pipe whole where concurrent * scopes share a descriptor. Cuts land inside the record's text rather than across its structure, which is * what leaves the line parseable, and a record is fitted by rungs, each shedding what a reader can better * spare than the rung below it. What the ceiling costs is [documented](../docs/reporting.md#reporting-for-a-machine) * in the same order. */ export declare function serializeVerdict(verdict: Verdict): string; /** * Writes a verdict to a stream as a single write, which is what holds a line together when concurrent scopes * share one descriptor. Both renderings spend the one record, so neither can come to report what the other * does not. */ export declare function writeVerdict(verdict: Verdict, stream: Writable, format: ReportFormat, style: OutputStyle): void;