export interface PatternStanzaRow { /** Canonical pattern label (snake_case) or a placeholder like (no-symbol). */ pattern: string; service: string; severity: string; bytes: number; /** Cost for the period (already scaled to periodSuffix). */ cost: number; /** Event count over the window, when available. */ events?: number; /** Portable cross-pillar join key. Shown to the human for paste-back. */ tenxHash?: string; /** Short flags rendered after the header, e.g. ['stale', 'no-symbol']. */ flags?: string[]; /** * Growth mode: when set, the metrics line shows `$base -> $now` * plus deltaLabel instead of a plain cost. Used by whats_changing. */ costBaseline?: number; /** Preformatted delta tag for growth mode, e.g. "+34%", "NEW". */ deltaLabel?: string; /** * Value the share-bar is scaled against. Defaults to bytes. Tools * whose magnitude is not volume (whats_changing ranks by $ delta) set * this so the bar reflects the metric that actually ranks the list. */ barValue?: number; /** * Volume-over-window samples. When present (>=2 points) the row * renders a trend sparkline + direction word INSTEAD of the static * share-bar (a flat scope-share bar is near-useless on a long-tailed * workload; "is this getting worse" is the question that matters). */ spark?: number[]; /** Preformatted "impacts" line: which services this pattern hits. */ impacts?: string; /** * A verbatim sample log line (already truncated) pulled from the * user's SIEM by exact tenx_hash. When present it leads the stanza * as the readable identity and the tokenized pattern is demoted to * a `pattern:` line. Ground truth, not fabrication. */ sample?: string; } /** Unicode sparkline scaled to the series own min..max. */ export declare function sparkline(vals: number[]): string; /** First-third vs last-third mean -> rising / falling / flat. */ export declare function trendWord(vals: number[]): string; export interface StanzaRenderOpts { /** e.g. "Top patterns", "Cost drivers". */ title: string; /** e.g. "all services" or a specific service name. */ scopeLabel: string; /** e.g. "last 24h". */ windowLabel: string; /** e.g. "/day", "/7d", "" . Appended to every dollar figure. */ periodSuffix: string; /** Total volume in scope (bar denominator + footer). */ scopeBytes?: number; /** Total cost in scope (footer). */ scopeCost?: number; /** Bytes actually shown (sum of the displayed rows), for reconciliation. */ shownBytes?: number; /** Distinct pattern count in scope (the "of M" in "N of M patterns"). */ totalPatternCount?: number; /** Preformatted annualized note, e.g. "~$1.9K/yr". Shown on Scope line. */ annualNote?: string; /** * Single dominant service: hoisted into the header, omitted from * every row header (it would be identical noise on each row). */ hoistedService?: string; /** Render per-service sections instead of one global ranking. */ groupByService?: boolean; /** * Skip the title + Scope summary lines (the legend and stanzas still * render). For callers that print their own header block, e.g. * whats_changing with its baseline/comparison framing. */ suppressHeader?: boolean; } /** Horizontal share bar: filled vs empty cells for a 0..1 fraction. */ export declare function shareBar(frac: number, width?: number): string; /** * Render the stanza list. Caller owns the title/caveat/agent-only blocks * around it; this produces just the header summary + the per-pattern * body (optionally grouped by service). */ export declare function renderPatternStanzas(rows: PatternStanzaRow[], opts: StanzaRenderOpts): string;