import { type Finding } from './diff.js'; import { type ConfidenceSummary } from './confidence-ledger.js'; import { type ComparisonTruth } from './change-groups.js'; export { describeChange, colorName, tokenIndex, toHex } from './describe.js'; export { summarizeProps, prettyLabel, assessComparisonTruth } from './change-groups.js'; export type { ComparisonTruth } from './change-groups.js'; /** * Visual diff report: for every surface with findings, crop the before/after * full-page screenshots around the changed elements and write a markdown * report with side-by-side images plus the exact property changes. * * Cropping zooms out to the OUTERMOST changed element: changed paths that are * descendants of other changed paths are folded into their ancestor, nearby * regions are merged, and both sides are cropped at the SAME page rectangle (the * union of where the change sits on each side) so the pair lines up exactly — * the reviewer compares like-for-like instead of playing spot-the-difference. */ export type ReportOptions = { beforeDir: string; afterDir: string; outDir: string; /** Prefix for image URLs in report.md (default: relative paths). */ imageBaseUrl?: string; /** Padding around the union of changed rects (default 12px). */ pad?: number; /** Minimum crop size, for context around tiny changes (default 320×180). */ minWidth?: number; minHeight?: number; /** Crops taller than this are clamped (default 1600px). */ maxHeight?: number; /** * Changed-element footprint (max of its width/height, in px) at or below which a * magnified zoom crop is added so a sub-pixel change is visible by default * (default 64). Set to 0 to disable zoom crops. */ zoomBelow?: number; /** Max crop regions per surface before collapsing into one union crop (default 8). */ maxCrops?: number; /** * Row count at which a crop's property tables fold under a `
` toggle * (default 0 = always fold; the plain-English bullets and screenshot stay * visible). Set to e.g. 5 to keep small changes inline and fold only verbose * ones, or `Infinity` to never fold. */ foldDetailsAt?: number; /** * Include size/position-derived longhands (height, width, transform-origin…) * in the report. Off by default: on a reflow they change up the whole ancestor * chain and would anchor crops to the entire page. The certification differ * (`styleproof-diff`) always keeps them. */ includeLayoutNoise?: boolean; /** * Render the opt-in content layer (default OFF): a separate, ADVISORY section * listing elements whose own text changed, each with a before/after crop. * Requires captures taken with `captureText: true`; otherwise there's no text * to diff and the section is empty. Copy edits stay advisory. A wholesale * product-state flip (distinct mode labels, or a tree rewrite) withholds that * surface's style findings from certification so a reviewer is not asked to * approve a restyle the product did not make. Small copy edits next to a real * restyle still certify. */ includeContent?: boolean; /** * Byte ceiling for report.md so GitHub can always render it (its markdown viewer * refuses to render files past ~512 KB). Once the accumulated report would exceed * this, the remaining changed surfaces are listed as one-liners (name · change * count · crop link) instead of full property tables — the exhaustive per-row * detail is always kept in report.json and every crop in crops/, so nothing is * lost, just relocated. Default 400_000 (~0.4 MB). Set to Infinity to never cap. */ maxReportBytes?: number; }; export type ReportResult = { /** Surfaces carrying a reviewable change (excludes new, one-sided surfaces). */ changedSurfaces: number; /** New surfaces present on only one side, with no baseline to compare. */ newSurfaces: number; totalFindings: number; /** Advisory content-layer changes rendered (0 unless includeContent + captured text). Never gates. */ contentChanges: number; /** * Canonical comparison truth vs the certification differ. When * `rawOnlyNoReviewable` is true the report has no crops/sections but raw * computed-style deltas exist — callers must fail closed, never approve. */ comparison: ComparisonTruth; /** Presentation-vs-certification coherence. Any false value must fail closed. */ reportConsistency: ReportConsistency; /** * The head bundle's confidence badge (#399): completeness + per-status counts, * separate from the visual verdict. `completeness: 'unknown'` on bundles from * before the ledger existed — advisory, never a retroactive block. */ confidence: ConfidenceSummary; reportMdPath: string; reportJsonPath: string; }; export declare function excerptPair(before: string, after: string): [string, string]; export declare function propertyGlanceLine(findings: Finding[]): string; type ReportConsistency = { ok: true; reason: 'aligned'; } | { ok: false; reason: 'raw_only_no_reviewable' | 'presentation_collapsed_while_raw_reviewable'; }; /** Generate the public report. DOM structure is never part of certification. */ export declare function generateStyleMapReport(opts: ReportOptions): ReportResult; /** @internal Retains direct coverage of the low-level structural renderer. */ export declare function generateStructuralStyleMapReportForTesting(opts: ReportOptions): ReportResult;