/** * Output formatting helpers. * * Plain text, not markdown. Dollar amounts are prominent. * Designed for AI consumption — concise, structured, parseable. */ /** * Format a dollar amount: $1.2K, $14K, $1.2M, etc. Sub-dollar amounts * expand precision so sample-size POC runs don't collapse to `$0.00` * and obscure which patterns are actually the most expensive. Anything * below $0.01 goes to 4 decimals; below $1 goes to 2. */ export declare function fmtDollar(amount: number): string; /** * C-policy dollar gating: present a dollar figure only when it is grounded in * the customer's real rate. Returns the formatted dollar when `rateSource` is * `customer_supplied` (or `snapshot`, a captured real rate); returns null for * `list_price` / `none` / unset, so headlines lead with volume (GB / %, always * exact) and append a dollar only when it is true. The chassis attaches a * list-price calibration callout for the non-grounded case. */ export declare function groundedDollar(amount: number, rateSource: 'customer_supplied' | 'list_price' | 'snapshot' | 'none' | undefined): string | null; /** Format a GB number with a sensible unit: MB < 1, GB < 1000, TB above. */ export declare function fmtGb(gb: number): string; /** * Format bytes as human-readable with 3 significant figures. * * Thresholds use DECIMAL units (KB=10^3, MB=10^6, GB=10^9, TB=10^12), * matching cost.ts's $/GB convention so the same byte value renders * the same volume in the same envelope as the dollars derived from it. * CloudWatch / Datadog / Splunk / Azure / GCP / Sumo all bill in * decimal GB, so this also matches what the customer sees on their * invoice. Decimal units are used because a GiB divisor under a GB label * understates the volume shown next to the dollars by ~6.87%. * * Using toPrecision(3) throughout so 115_577_921 bytes → * mb = 115.6 → gb = 0.1156 → "0.116 GB" (3 sig figs) */ export declare function fmtBytes(bytes: number): string; /** Format event count: 1.2B, 450M, 12K, etc. */ export declare function fmtCount(count: number): string; /** Format a pattern name for display: replace underscores with spaces. */ export declare function fmtPattern(pattern: string): string; /** * Normalize a pattern name for use in a PromQL `message_pattern="..."` selector. * * Reporter-side pattern labels are always snake_case (word_word_word), but the * display formatter renders them with spaces via `fmtPattern` for readability. * When an agent re-feeds a displayed pattern back into a tool, the spaces * round-trip into PromQL and the exact-match selector fails. This helper * reverses the display transform so round-trip calls land on the canonical * label value. */ export declare function normalizePattern(pattern: string): string; /** Format severity: standard display names (not truncated to 4 chars). */ export declare function fmtSeverity(sev: string): string; /** Format a percentage. */ export declare function fmtPct(value: number): string; /** * Format a percent-reduction value. Alias of `fmtPct` semantics with an * explicit name so headlines that lead with "% reduction" read in the * source the way they render. */ export declare function fmtPctReduction(value: number): string; /** * Render a low / expected / high percent triplet: "78% (72-84%)". * Used by percent-first headlines that surface the uncertainty band * around an expected reduction. */ export declare function fmtPctRange(low: number, expected: number, high: number): string; /** * Render a DisclosedDollarValue with its disclosure tail. This is the ONLY * formatter that may print a dollar number derived from a list rate — it * structurally cannot leave the disclosure off. * * - null → "—" * - source='unset' → "— (no $/GB rate configured)" * - source='list_price' → "$1.8K (at Splunk list price $5.00/GB — …)" * - source='customer_supplied' → "$1.8K" (no caveat; customer owns the rate) */ export declare function fmtDisclosedDollar(d: { value: number; source: 'list_price' | 'customer_supplied' | 'unset'; disclosure: string | null; } | null | undefined): string; /** Timeframe config. */ export interface Timeframe { /** Window length in days. Fractional for sub-day windows (e.g., 1h = 1/24). */ days: number; /** PromQL range expression, passed verbatim to queries (e.g., "15m", "1h", "7d"). */ range: string; /** Human-readable label for output rendering. */ label: string; /** * Baseline offsets for cost_drivers 3-window average (in days). Scaled to * match `days` so sub-day windows compare against other sub-day windows. */ baselineOffsets: number[]; } /** * Parse a timeframe string into a Timeframe config. * * Accepts: `15m`, `30m`, `1h`, `6h`, `12h`, `1d`, `7d`, `30d` — any number * of m/h/d suffixes where the resulting range is at least 1 minute and at * most 90 days. Sub-day windows (minutes/hours) are useful for incident * investigation; day-level windows for cost and trend analysis. */ export declare function parseTimeframe(input: string): Timeframe; /** Cost period label for output. Renders a short suffix matching the window size. */ export declare function costPeriodLabel(days: number): string;