@orkestrel/console 0.0.11 → 0.0.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,23 +1,23 @@
1
- import { EmitterErrorHandler } from '@orkestrel/emitter';
2
- import { EmitterHooks } from '@orkestrel/emitter';
3
- import { EmitterInterface } from '@orkestrel/emitter';
1
+ import type { EmitterErrorHandler } from '@orkestrel/emitter';
2
+ import type { EmitterHooks } from '@orkestrel/emitter';
3
+ import type { EmitterInterface } from '@orkestrel/emitter';
4
4
 
5
5
  /**
6
- * Pad (or, when over budget, truncate) `text` to exactly `target` VISIBLE columns, positioning
6
+ * Pads (or, when over budget, truncates) `text` to exactly `columns` visible columns, positioning
7
7
  * it by `alignment`. The width primitive the box / table renderers align every cell with.
8
8
  *
9
9
  * @remarks
10
10
  * Measures with {@link width} (visible code points, ANSI-aware), so a styled string aligns by
11
- * its visible content, not its escape codes. When `width(text) < target`, the deficit is added
11
+ * its visible content, not its escape codes. When `width(text) < columns`, the deficit is added
12
12
  * as spaces — all trailing (`left`), all leading (`right`), or split with the extra space on
13
- * the right (`center`). When `width(text) > target`, the VISIBLE characters are sliced to
14
- * `target` (a defensive guard — the renderers size columns to fit, so this is rarely hit; it
13
+ * the right (`center`). When `width(text) > columns`, the visible characters are sliced to
14
+ * `columns` (a defensive guard — the renderers size columns to fit, so this is rarely hit; it
15
15
  * slices the stripped text, so it never bisects an escape sequence into a broken half).
16
16
  *
17
17
  * @param text - The cell content (may be styled)
18
- * @param target - The visible column count to fit `text` into
19
- * @param alignment - Where to position `text` within the width; defaults to `left`
20
- * @returns `text` fitted to exactly `target` visible columns
18
+ * @param columns - The visible column count to fit `text` into
19
+ * @param alignment - Where to position `text` within that budget; defaults to `left`
20
+ * @returns `text` fitted to exactly `columns` visible columns
21
21
  *
22
22
  * @example
23
23
  * ```ts
@@ -26,12 +26,14 @@ import { EmitterInterface } from '@orkestrel/emitter';
26
26
  * align('hi', 5, 'center') // ' hi '
27
27
  * ```
28
28
  */
29
- export declare function align(text: string, target: number, alignment?: Alignment): string;
29
+ export declare function align(text: string, columns: number, alignment?: Alignment): string;
30
30
 
31
31
  /**
32
- * Horizontal text alignment within a fixed-width cell — the conventional three-value set a
33
- * {@link ColumnSpec} (and the box / separator title) aligns by. A value pair / set, not a
34
- * binary toggle (§4.4), so it stays a union.
32
+ * Names the horizontal text alignment within a fixed-width cell — `left` / `center` / `right`,
33
+ * the conventional set a {@link ColumnSpec} (and the box / separator title) aligns by.
34
+ *
35
+ * @remarks
36
+ * A value set rather than a binary toggle, so it stays a union.
35
37
  */
36
38
  export declare type Alignment = 'left' | 'center' | 'right';
37
39
 
@@ -39,13 +41,13 @@ export declare type Alignment = 'left' | 'center' | 'right';
39
41
  * Matches any ANSI/VT escape sequence — CSI (SGR color/style plus cursor/erase/scroll,
40
42
  * including colon-parameterized SGR), OSC / DCS / PM / APC / SOS string sequences
41
43
  * (titles, hyperlinks, device strings), the `nF` charset-select family, and the
42
- * two-byte `Fp` / `Fe` / `Fs` sequences (e.g. `ESC 7`, `ESC D`, `ESC c` RIS). Global, so
44
+ * two-byte `Fp` / `Fe` / `Fs` sequences (for example `ESC 7`, `ESC D`, `ESC c` RIS). Global, so
43
45
  * `strip` removes every occurrence.
44
46
  *
45
47
  * @remarks
46
- * A global `RegExp` carries a mutable `lastIndex`; a scan must build a FRESH `RegExp`
48
+ * A global `RegExp` carries a mutable `lastIndex`; a scan must build a fresh `RegExp`
47
49
  * from this one's `source` + `flags` rather than reuse this instance's `lastIndex`. This
48
- * is the canonical definition, not a shared scanner. The alternation is ORDERED so the
50
+ * is the canonical definition, not a shared scanner. The alternation is ordered so the
49
51
  * CSI / string-family arms (which can start with a byte a later single-byte arm would
50
52
  * also match) win first; every arm uses disjoint, non-nested character classes, so the
51
53
  * match is linear in input length — no catastrophic backtracking (ReDoS-safe) even on an
@@ -55,14 +57,15 @@ export declare type Alignment = 'left' | 'center' | 'right';
55
57
  export declare const ANSI_PATTERN: RegExp;
56
58
 
57
59
  /**
58
- * The cross-environment default {@link RendererInterface} — renders style DATA as ANSI
59
- * SGR escape codes, exactly as `Scheduler` is the `setTimeout` default for its seam. It
60
- * is the single styling output the whole console / terminal system uses in a terminal;
61
- * the browser `%c` / CSS renderer (the C-f branch) implements the SAME contract over
62
- * the SAME {@link Style}, so retargeting changes the renderer, never the style model.
60
+ * Implements the cross-environment default {@link RendererInterface} — renders style data as ANSI
61
+ * SGR escape codes, stateless and event-free.
63
62
  *
64
63
  * @remarks
65
- * - **Style is DATA in, SGR string out.** It reads the style's `foreground` /
64
+ * It is the single styling output the whole console / terminal system uses in a terminal; the
65
+ * browser `%c` / CSS renderer implements the same contract over the same {@link Style}, so
66
+ * retargeting changes the renderer, never the style model.
67
+ *
68
+ * - **Style is data in, SGR string out.** It reads the style's `foreground` /
66
69
  * `background` / `attributes` and emits one `ESC[…m` sequence whose parameters are the
67
70
  * mapped SGR numbers (foreground 30–37 / 90–97, background 40–47 / 100–107, attributes
68
71
  * 1 / 2 / 3 / 4 / 7 / 9), followed by `text`, terminated by the reset `ESC[0m`.
@@ -71,24 +74,25 @@ export declare const ANSI_PATTERN: RegExp;
71
74
  * - **`default` and unset colors emit no code** — a `default` (or absent) `foreground` /
72
75
  * `background` leaves the terminal's own ink.
73
76
  * - **The empty style and the empty string pass through** — when there is nothing to
74
- * apply (no colors, no attributes) or `text` is `''`, `text` is returned VERBATIM with
77
+ * apply (no colors, no attributes) or `text` is `''`, `text` is returned verbatim with
75
78
  * no escape codes, so an unstyled render never injects a stray reset.
76
79
  * - **Stateless and event-free** — no fields, no events; safe to share one instance.
77
80
  */
78
81
  export declare class ANSIRenderer implements RendererInterface {
79
82
  #private;
80
83
  /**
81
- * Wrap `text` in the SGR codes for `style`. Returns `text` unchanged when the style
84
+ * Wraps `text` in the SGR codes for `style`. Returns `text` unchanged when the style
82
85
  * is empty or `text` is `''`.
83
86
  */
84
87
  render(style: Style, text: string): string;
85
88
  }
86
89
 
87
90
  /**
88
- * A text-style attribute — the six standard SGR text effects.
91
+ * Names a text-style attribute — `bold` / `dim` / `italic` / `underline` / `inverse` /
92
+ * `strikethrough`, the standard SGR text effects.
89
93
  *
90
94
  * @remarks
91
- * Style as DATA: an `Attribute` is a name. The ANSI renderer maps each to its SGR
95
+ * Style as data: an `Attribute` is a name. The ANSI renderer maps each to its SGR
92
96
  * on-code (`bold` → 1, `dim` → 2, `italic` → 3, `underline` → 4, `inverse` → 7,
93
97
  * `strikethrough` → 9), composing several at once; a browser renderer maps the same
94
98
  * names to CSS (`font-weight`, `font-style`, `text-decoration`, …).
@@ -96,46 +100,76 @@ export declare class ANSIRenderer implements RendererInterface {
96
100
  export declare type Attribute = 'bold' | 'dim' | 'italic' | 'underline' | 'inverse' | 'strikethrough';
97
101
 
98
102
  /**
99
- * Each {@link Attribute}'s SGR "on" parameter — `bold` 1, `dim` 2, `italic` 3,
103
+ * Maps each {@link Attribute} to its SGR "on" parameter — `bold` 1, `dim` 2, `italic` 3,
100
104
  * `underline` 4, `inverse` 7, `strikethrough` 9. The renderer composes several by
101
105
  * joining their codes with `;` in one SGR sequence.
102
106
  */
103
107
  export declare const ATTRIBUTE_CODES: Readonly<Record<Attribute, number>>;
104
108
 
105
109
  /**
106
- * Every {@link Attribute}, frozen — the attributes the styler exposes as chainable
110
+ * Lists every {@link Attribute}, frozen — the attributes the styler exposes as chainable
107
111
  * accessors. The source of truth for the attribute axis.
108
112
  */
109
113
  export declare const ATTRIBUTES: readonly Attribute[];
110
114
 
111
115
  /**
112
- * Each {@link Color}'s SGR BACKGROUND parameter — the 8 base colors at 40–47 and their
116
+ * Maps each {@link Color} to its SGR background parameter — the 8 base colors at 40–47 and their
113
117
  * bright variants at 100–107. `default` is intentionally absent (it emits no code).
114
118
  */
115
119
  export declare const BACKGROUND_CODES: Readonly<Record<Exclude<Color, 'default'>, number>>;
116
120
 
117
121
  /**
118
- * The default EMPTY-cell glyph {@link import('./helpers.js').renderBar} draws the remaining run of a
119
- * progress bar with — the light-shade block `░` (U+2591). A single visible cell; a consumer overrides
120
- * it via {@link import('./types.js').ProgressBarOptions}`.empty`.
122
+ * Holds the default empty-cell glyph {@link import('./helpers.js').renderBar} draws the remaining
123
+ * run of a progress bar with — the light-shade block `░` (U+2591). A single visible cell; a
124
+ * consumer overrides it through {@link import('./types.js').BarOptions.empty}.
121
125
  */
122
126
  export declare const BAR_EMPTY = "\u2591";
123
127
 
124
128
  /**
125
- * The default FILLED-cell glyph {@link import('./helpers.js').renderBar} draws the completed run of a
126
- * progress bar with — the full block `█` (U+2588). A single visible cell; a consumer overrides it via
127
- * {@link import('./types.js').ProgressBarOptions}`.fill`.
129
+ * Holds the default filled-cell glyph {@link import('./helpers.js').renderBar} draws the completed
130
+ * run of a progress bar with — the full block `█` (U+2588). A single visible cell; a consumer
131
+ * overrides it through {@link import('./types.js').BarOptions.fill}.
128
132
  */
129
133
  export declare const BAR_FILL = "\u2588";
130
134
 
131
- /** The BEL control character (`U+0007`) that can terminate an OSC sequence. */
135
+ /**
136
+ * Configures the pure {@link import('./helpers.js').renderBar} renderer — a determinate progress
137
+ * bar string (`█████░░░░░ 50% (5/10)`), width-aware and styler-optional.
138
+ *
139
+ * @remarks
140
+ * - `current` / `total` — the filled fraction is `current / total`, clamped to `[0, total]` (a
141
+ * `current` past `total` renders a full bar, a negative one an empty bar) — so a caller's overrun
142
+ * never produces an over-long bar. A `total` of `0` (or below) renders a full bar (nothing to do).
143
+ * - `width` — the visible cell count of the bar track (the glyph run between no brackets); defaults
144
+ * to {@link DEFAULT_BAR_WIDTH}. The percentage + `(current/total)` count follow the track.
145
+ * - `fill` — the filled-cell glyph; defaults to {@link BAR_FILL} (`█`). `empty` — the empty-cell
146
+ * glyph; defaults to {@link BAR_EMPTY} (`░`). Sized in visible columns ({@link
147
+ * import('./helpers.js').width}), so a multi-cell glyph still yields a `width`-wide track.
148
+ * - `styler` — colors the filled run when supplied (the empty run + the trailing label stay plain);
149
+ * the layout is identical with or without color, since the track is measured on visible width.
150
+ * - `style` — an optional by-value style rendered through `styler` for the filled run.
151
+ */
152
+ export declare interface BarOptions {
153
+ readonly current: number;
154
+ readonly total: number;
155
+ readonly width?: number;
156
+ readonly fill?: string;
157
+ readonly empty?: string;
158
+ readonly styler?: StylerInterface;
159
+ readonly style?: Style;
160
+ }
161
+
162
+ /** Holds the bell control character (`U+0007`) that can terminate an OSC sequence. */
132
163
  export declare const BEL: string;
133
164
 
134
165
  /**
135
- * The complete {@link BorderChars} junction set for each {@link BorderStyle} — the standard
136
- * Unicode box-drawing glyphs at the four line weights. The renderers ({@link
137
- * import('./helpers.js').renderBox} / {@link import('./helpers.js').renderTable}) look the
138
- * style up here, so no glyph literal lives in a renderer. Deeply frozen.
166
+ * Holds the complete {@link BorderChars} junction set for each {@link BorderStyle} — the standard
167
+ * Unicode box-drawing glyphs at each line weight, deeply frozen.
168
+ *
169
+ * @remarks
170
+ * The renderers ({@link import('./helpers.js').renderBox} /
171
+ * {@link import('./helpers.js').renderTable}) look the style up here, so no glyph literal lives in
172
+ * a renderer.
139
173
  *
140
174
  * @remarks
141
175
  * `round` shares `single`'s edges and tees — only its corners differ (the rounded `╭╮╰╯`).
@@ -143,10 +177,13 @@ export declare const BEL: string;
143
177
  export declare const BORDER_CHARS: Readonly<Record<BorderStyle, BorderChars>>;
144
178
 
145
179
  /**
146
- * One complete box-drawing junction set for a {@link BorderStyle} — every glyph the box /
147
- * table renderers need to frame content and rule a table. Plain data (the value lives in
148
- * {@link BORDER_CHARS}); the renderers read these so no glyph literal is hard-coded in a
149
- * renderer.
180
+ * Represents one complete box-drawing junction set for a {@link BorderStyle} — the edges, the
181
+ * corners, and the `T` / cross junctions the box and table renderers need to frame content and
182
+ * rule a table.
183
+ *
184
+ * @remarks
185
+ * Plain data (the value lives in {@link BORDER_CHARS}); the renderers read these so no glyph
186
+ * literal is hard-coded in a renderer.
150
187
  *
151
188
  * @remarks
152
189
  * - `horizontal` / `vertical` — the edge run characters.
@@ -171,12 +208,13 @@ export declare interface BorderChars {
171
208
  }
172
209
 
173
210
  /**
174
- * A box-drawing border style — the four standard Unicode line weights the renderers frame
175
- * with. Each selects a full junction set in {@link BORDER_CHARS} (corners, edges, and the
176
- * `T` / cross junctions a table needs). A named, fixed set (an external-spec value family),
177
- * never a toggle — so it stays a union.
211
+ * Names a box-drawing border style — `single` / `double` / `round` / `heavy`, the standard
212
+ * Unicode line weights the renderers frame with, each selecting a full junction set in
213
+ * {@link BORDER_CHARS}.
178
214
  *
179
215
  * @remarks
216
+ * A named, fixed set (an external-spec value family) rather than a toggle, so it stays a union.
217
+ *
180
218
  * `single` (`┌─┐`), `double` (`╔═╗`), `round` (`╭─╮` — single edges, rounded corners), and
181
219
  * `heavy` (`┏━┓`). The renderer looks the style up in {@link BORDER_CHARS}; styling the
182
220
  * border (a color) is a separate, orthogonal concern handled by the optional `styler`.
@@ -184,14 +222,14 @@ export declare interface BorderChars {
184
222
  export declare type BorderStyle = 'single' | 'double' | 'round' | 'heavy';
185
223
 
186
224
  /**
187
- * Options for {@link import('./helpers.js').renderBox} — content framed in box-drawing
188
- * characters.
225
+ * Configures {@link import('./helpers.js').renderBox} — content framed in box-drawing characters. A
226
+ * `Reporter` supplies its own chrome style only when the caller gives neither `styler` nor `style`.
189
227
  *
190
228
  * @remarks
191
229
  * - `content` — the body text; embedded newlines split it into lines, each framed on its own
192
230
  * row. Every row is padded to the inner width measured by {@link import('./helpers.js').width}
193
- * (the VISIBLE width), so ANSI-styled content stays aligned inside the frame.
194
- * - `title` — an optional caption embedded in the TOP border.
231
+ * (the visible width), so ANSI-styled content stays aligned inside the frame.
232
+ * - `title` — an optional caption embedded in the top border.
195
233
  * - `padding` — horizontal cells of blank padding inside each vertical edge; defaults to
196
234
  * {@link DEFAULT_PADDING}.
197
235
  * - `border` — the {@link BorderStyle}; defaults to {@link DEFAULT_BORDER} (`single`).
@@ -213,32 +251,32 @@ export declare interface BoxOptions {
213
251
  }
214
252
 
215
253
  /**
216
- * An observable console interceptor (AGENTS §13) — it takes control of the global `console.*` on
217
- * the READ side. While `active`, every configured `console.x` call is captured as a frozen
254
+ * Implements an observable console interceptor — it takes control of the global `console.*` on
255
+ * the read side. While `active`, every configured `console.x` call is captured as a frozen
218
256
  * {@link CapturedMessage}, buffered (total + by level, bounded), emitted on `capture`, and — per
219
- * options — mirrored to the real console and/or forwarded to a {@link SinkInterface}.
257
+ * options — mirrored to the real console, forwarded to a {@link SinkInterface}, or both.
220
258
  *
221
259
  * @remarks
222
- * - **Snapshot-at-start (the no-capture-loop principle).** `start()` snapshots the CURRENT
260
+ * - **Snapshot-at-start (the no-capture-loop principle).** `start()` snapshots the current
223
261
  * `console[level]` for each configured {@link CaptureLevel}, then installs the wrappers. The
224
- * mirror writes through that snapshot — so our OWN console sink output (the Logger / Reporter,
262
+ * mirror writes through that snapshot — so our own console sink output (the Logger / Reporter,
225
263
  * which snapshot the real `console` at creation) is never recaptured: `Capture` catches
226
- * THIRD-PARTY `console.*`, not our writes. Create your loggers BEFORE installing a capture.
227
- * - **Idempotent + PROCESS-GLOBAL + NON-REENTRANT.** `start()` while already `active` is a no-op
228
- * (never double-patches); `stop()` while inactive is a no-op. It patches the ONE global
229
- * `console`, so at most ONE capture may be active at a time — running two concurrently
264
+ * third-party `console.*`, not our writes. Create your loggers before installing a capture.
265
+ * - **Idempotent + process-global + non-reentrant.** `start()` while already `active` is a no-op
266
+ * (never double-patches); `stop()` while inactive is a no-op. It patches the one global
267
+ * `console`, so at most one capture may be active at a time — running two concurrently
230
268
  * interleaves their buffers and clobbers each other's restore.
231
269
  * - **Bounded buffers.** `messages()` / `messages(level)` — the total buffer and each by-level
232
270
  * bucket are each capped at `limit`
233
271
  * (oldest dropped first), never unbounded — the same retention precedent as {@link Logger}.
234
- * - **Lifecycle (§10).** `start` / `stop` toggle interception (emitting `start` / `stop`);
272
+ * - **Lifecycle.** `start` / `stop` toggle interception (emitting `start` / `stop`);
235
273
  * `destroy()` stops (restoring `console`) then destroys the emitter.
236
274
  *
237
275
  * @example
238
276
  * ```ts
239
277
  * const capture = new Capture({ levels: ['warn', 'error'], mirror: true })
240
278
  * capture.start()
241
- * console.warn('third-party noise') // captured AND mirrored to the real console
279
+ * console.warn('third-party noise') // captured and mirrored to the real console
242
280
  * capture.messages('warn') // [{ level: 'warn', text: 'third-party noise', time: … }]
243
281
  * capture.stop() // console.warn restored
244
282
  * ```
@@ -257,9 +295,10 @@ export declare class Capture implements CaptureInterface {
257
295
  }
258
296
 
259
297
  /**
260
- * Each {@link CaptureLevel}'s {@link LogLevel} for the optional sink forward — the projection the
298
+ * Maps each {@link CaptureLevel} to its {@link LogLevel} for the optional sink forward — the projection the
261
299
  * Capture routes through when writing an intercepted call to a {@link
262
- * import('./types.js').SinkInterface} (`sink.write(text, CAPTURE_LEVEL_MAP[level])`). `warn` /
300
+ * import('./types.js').SinkInterface}. `sink.write(text, CAPTURE_LEVEL_MAP[level])` is the call
301
+ * this map backs. `warn` /
263
302
  * `error` / `debug` / `info` map to their matching {@link LogLevel}; `log` maps to `info` (a plain
264
303
  * console log is informational — the default stream), so a stream-aware sink routes `warn` / `error`
265
304
  * captures to the right stream. The source of truth for the capture-to-log projection.
@@ -267,7 +306,7 @@ export declare class Capture implements CaptureInterface {
267
306
  export declare const CAPTURE_LEVEL_MAP: Readonly<Record<CaptureLevel, LogLevel>>;
268
307
 
269
308
  /**
270
- * Every {@link CaptureLevel}, frozen — the `console.*` methods a {@link
309
+ * Lists every {@link CaptureLevel}, frozen — the `console.*` methods a {@link
271
310
  * import('./types.js').CaptureInterface} intercepts by default (and the source of truth for the
272
311
  * capture-level axis; drives exhaustive tests). The universal console methods: `log`, `info`,
273
312
  * `warn`, `error`, `debug`.
@@ -275,7 +314,7 @@ export declare const CAPTURE_LEVEL_MAP: Readonly<Record<CaptureLevel, LogLevel>>
275
314
  export declare const CAPTURE_LEVELS: readonly CaptureLevel[];
276
315
 
277
316
  /**
278
- * One captured console call — an immutable, serializable record of a single intercepted
317
+ * Represents one captured console call — an immutable, serializable record of a single intercepted
279
318
  * `console.*` invocation. A {@link CaptureInterface} builds one per call, freezes it, buffers it
280
319
  * (total + by level), and emits it on `capture`; every consumer reads this exact shape.
281
320
  *
@@ -296,108 +335,114 @@ export declare interface CapturedMessage {
296
335
  }
297
336
 
298
337
  /**
299
- * The observable events a {@link CaptureInterface} emits (AGENTS §13).
338
+ * Declares the observable events a {@link CaptureInterface} emits — `capture(message)` per
339
+ * intercepted call, plus the `start` and `stop` lifecycle signals.
300
340
  *
301
341
  * @remarks
302
- * - `capture` — the core event: fires for EVERY intercepted `console.*` call (one per call,
303
- * while active), carrying the frozen {@link CapturedMessage}. The hook a live console viewer /
304
- * tee rides.
305
- * - `start` / `stop` — the lifecycle signals: `start` fires when interception is installed (the
342
+ * - `capture` — fires for every intercepted `console.*` call (one per call, while active),
343
+ * carrying the frozen {@link CapturedMessage}. The hook a live console viewer / tee rides.
344
+ * - `start` / `stop` — `start` fires when interception is installed (the
306
345
  * first `start()` on an inactive capture), `stop` when it is torn down (a `stop()` on an active
307
346
  * capture, and from `destroy()`); both are pure signals (empty tuples) so a consumer can mirror
308
- * the global-patch lifecycle (e.g. log that capture is engaged). They earn their place by
347
+ * the global-patch lifecycle (for example log that capture is engaged). They earn their place by
309
348
  * bracketing the process-global side effect a consumer needs to observe.
310
349
  *
311
- * Listener isolation is the emitter's (§13): a listener throw routes to the emitter's `error`
350
+ * Listener isolation is the emitter's: a listener throw routes to the emitter's `error`
312
351
  * handler, never onto this map — so a buggy `capture` listener can never perturb interception (or
313
352
  * the underlying program's own `console.*` call). Declared as a `type` alias (not
314
- * `interface extends EventMap`, §4.5): a type-literal satisfies the `EventMap` constraint
353
+ * `interface extends EventMap`): a type-literal satisfies the `EventMap` constraint
315
354
  * structurally, whereas an interface lacks the index signature.
316
355
  */
317
356
  export declare type CaptureEventMap = {
318
- /** An intercepted `console.*` call — the frozen {@link CapturedMessage}. */
357
+ /** Fires on an intercepted `console.*` call — the frozen {@link CapturedMessage}. */
319
358
  readonly capture: readonly [message: CapturedMessage];
320
- /** Interception was installed (an inactive capture's `start()`). */
359
+ /** Fires after interception was installed (an inactive capture's `start()`). */
321
360
  readonly start: readonly [];
322
- /** Interception was torn down (an active capture's `stop()` / `destroy()`). */
361
+ /** Fires after interception was torn down (an active capture's `stop()` / `destroy()`). */
323
362
  readonly stop: readonly [];
324
363
  };
325
364
 
326
365
  /**
327
- * An observable console interceptor (AGENTS §13) — it takes control of the global `console.*` on
328
- * the READ side: while `active`, every configured `console.x` call is captured as a frozen
366
+ * Declares an observable console interceptor — it takes control of the global `console.*` on
367
+ * the read side: while `active`, every configured `console.x` call is captured as a frozen
329
368
  * {@link CapturedMessage}, buffered (total + by level, bounded), emitted on `capture`, and —
330
- * per options — mirrored to the real console and/or forwarded to a {@link SinkInterface}.
369
+ * per options — mirrored to the real console, forwarded to a {@link SinkInterface}, or both.
331
370
  *
332
371
  * @remarks
333
- * - **Snapshot-at-start.** `start()` snapshots the CURRENT `console[level]` for each configured
372
+ * - **Snapshot-at-start.** `start()` snapshots the current `console[level]` for each configured
334
373
  * {@link CaptureLevel}, then installs the wrappers. The mirror writes through that snapshot, so
335
- * our OWN console sink output (the Logger / Reporter, which snapshot the real `console` at
336
- * creation) is never recaptured — `Capture` catches THIRD-PARTY `console.*`, not our writes
337
- * (the no-capture-loop principle). Create your loggers BEFORE installing a capture.
374
+ * our own console sink output (the Logger / Reporter, which snapshot the real `console` at
375
+ * creation) is never recaptured — `Capture` catches third-party `console.*`, not our writes
376
+ * (the no-capture-loop principle). Create your loggers before installing a capture.
338
377
  * - **Idempotent + non-reentrant.** `start()` while already `active` is a no-op (it never
339
- * double-patches), and `stop()` while inactive is a no-op. It is PROCESS-GLOBAL — it patches the
340
- * one global `console` — so at most ONE capture may be active at a time; running two
378
+ * double-patches), and `stop()` while inactive is a no-op. It is process-global — it patches the
379
+ * one global `console` — so at most one capture may be active at a time; running two
341
380
  * concurrently interleaves their buffers and clobbers each other's restore.
342
381
  * - **Bounded buffers.** `messages()` returns a copy of the whole buffer (oldest first);
343
382
  * `messages(level)` a copy of one {@link CaptureLevel}'s bucket — each capped at `limit`
344
- * (oldest dropped first), never unbounded. `clear()` empties them (it does NOT stop interception).
345
- * - **Lifecycle (§10).** `start` / `stop` toggle interception; `destroy()` stops (restoring
383
+ * (oldest dropped first), never unbounded. `clear()` empties them (it does not stop interception).
384
+ * - **Lifecycle.** `start` / `stop` toggle interception; `destroy()` stops (restoring
346
385
  * `console`) then destroys the emitter (its listeners go).
347
386
  */
348
387
  export declare interface CaptureInterface {
349
388
  readonly emitter: EmitterInterface<CaptureEventMap>;
350
- /** Whether interception is currently installed (between `start()` and `stop()`). */
389
+ /** Reports whether interception is installed (between `start()` and `stop()`). */
351
390
  readonly active: boolean;
352
- /** Snapshot the configured `console.*` and install the interceptors — a no-op when already `active`. */
391
+ /** Snapshots the configured `console.*` and installs the interceptors — a no-op when already `active`. */
353
392
  start(): void;
354
- /** Restore the snapshot-original `console.*` — a no-op when not `active`. */
393
+ /** Restores the snapshot-original `console.*` — a no-op when not `active`. */
355
394
  stop(): void;
356
- /** A copy of the whole captured buffer, oldest first (capped at `limit`). */
395
+ /**
396
+ * Returns a copy of the whole captured buffer, oldest first (capped at `limit`), or — given
397
+ * a {@link CaptureLevel} — a copy of only that level's bucket.
398
+ */
357
399
  messages(): readonly CapturedMessage[];
358
- /** A copy of the captured buffer for ONE {@link CaptureLevel}, oldest first (capped at `limit`). */
400
+ /** Returns a copy of the captured buffer for one {@link CaptureLevel}, oldest first (capped at `limit`). */
359
401
  messages(level: CaptureLevel): readonly CapturedMessage[];
360
- /** Drop every buffered message (total + by level); does NOT stop interception. */
402
+ /** Drops every buffered message (total + by level); does not stop interception. */
361
403
  clear(): void;
362
- /** Tear down — `stop()` (restoring `console`) then destroy the emitter. */
404
+ /** Tears down — `stop()` (restoring `console`) then destroys the emitter. */
363
405
  destroy(): void;
364
406
  }
365
407
 
366
408
  /**
367
- * One intercepted `console` method — the names a {@link CaptureInterface} patches and reports
368
- * under. A fixed set keyed off the universal `console.*` methods (`console.log` / `info` / `warn`
369
- * / `error` / `debug`); a named value family (it indexes {@link CAPTURE_LEVEL_MAP} to a
370
- * {@link LogLevel} for the optional sink forward), never a binary toggle — so it stays a union.
409
+ * Identifies one intercepted `console` method — `log` / `info` / `warn` / `error` / `debug`, the
410
+ * names a {@link CaptureInterface} patches and reports under.
371
411
  *
372
412
  * @remarks
373
- * DISTINCT from {@link LogLevel}: a `CaptureLevel` names the ORIGINATING console method (which
413
+ * A named value family (it indexes {@link CAPTURE_LEVEL_MAP} to a {@link LogLevel} for the
414
+ * optional sink forward) rather than a binary toggle, so it stays a union.
415
+ *
416
+ * distinct from {@link LogLevel}: a `CaptureLevel` names the originating console method (which
374
417
  * `console.x` was called), not a severity threshold — there is no ordering and no gating (every
375
418
  * configured method is captured). `log` and `info` are separate methods (both default-stream),
376
419
  * mapped to the sink's default / `info` stream respectively; `warn` / `error` / `debug` map to
377
- * their matching {@link LogLevel}. The default configured set is {@link DEFAULT_CAPTURE_LEVELS}.
420
+ * their matching {@link LogLevel}. The default configured set is {@link CAPTURE_LEVELS}.
378
421
  */
379
422
  export declare type CaptureLevel = 'log' | 'info' | 'warn' | 'error' | 'debug';
380
423
 
381
424
  /**
382
- * Options for `createCapture` / the {@link CaptureInterface} constructor.
425
+ * Configures the {@link import('./Capture.js').Capture} constructor — the `on` / `error` emitter
426
+ * keys, the `levels` intercepted, the `mirror` pass-through, the `sink` forward, and the buffer
427
+ * `limit`.
383
428
  *
384
429
  * @remarks
385
- * - `on` — the reserved {@link EmitterHooks} key (§8): initial listeners for the
386
- * {@link CaptureEventMap}, wired at construction (e.g. `{ capture: (m) => tee(m) }`).
387
- * - `error` — the emitter's listener-error handler (§13); a listener throw routes here.
388
- * - `levels` — which `console.*` methods to intercept; defaults to {@link DEFAULT_CAPTURE_LEVELS}
389
- * (all five). Only the listed methods are patched — an unlisted method is left untouched and
390
- * its calls pass through normally.
391
- * - `mirror` — when `true`, each intercepted call is ALSO forwarded to the snapshot-original
430
+ * - `on` — the reserved {@link EmitterHooks} key: initial listeners for the
431
+ * {@link CaptureEventMap}, wired at construction (for example `{ capture: (m) => tee(m) }`).
432
+ * - `error` — the emitter's listener-error handler; a listener throw routes here.
433
+ * - `levels` — which `console.*` methods to intercept; defaults to {@link CAPTURE_LEVELS}. Only the
434
+ * listed methods are patched — an unlisted method is left untouched and its calls pass through
435
+ * normally.
436
+ * - `mirror` — when `true`, each intercepted call is also forwarded to the snapshot-original
392
437
  * `console` method, so the program's own console output still appears while being captured;
393
- * defaults to `false` (capture silently). Mirrors through the method snapshotted AT `start()`,
438
+ * defaults to `false` (capture silently). Mirrors through the method snapshotted at `start()`,
394
439
  * never the live (re-patched) one — no echo loop.
395
440
  * - `sink` — an optional {@link SinkInterface} each intercepted call is also written to
396
- * (`sink.write(text, level)` with the {@link CaptureLevel} mapped to a {@link LogLevel} via
441
+ * (`sink.write(text, level)` with the {@link CaptureLevel} mapped to a {@link LogLevel} through
397
442
  * {@link CAPTURE_LEVEL_MAP}), to tee captured output into the logging pipeline / a file. Absent
398
443
  * ⇒ no forward.
399
444
  * - `limit` — the bounded buffer cap: at most this many recent messages are retained per buffer
400
- * (the total buffer and EACH by-level bucket; oldest dropped first). Defaults to
445
+ * (the total buffer and each by-level bucket; oldest dropped first). Defaults to
401
446
  * {@link DEFAULT_CAPTURE_LIMIT}; never unbounded (a long capture can't grow without bound — the
402
447
  * same retention precedent as {@link LoggerInterface}).
403
448
  */
@@ -411,8 +456,8 @@ export declare interface CaptureOptions {
411
456
  }
412
457
 
413
458
  /**
414
- * The structured outcome of {@link import('./helpers.js').withCapture} — the wrapped function's
415
- * own return `value` plus the {@link CapturedMessage}s intercepted while it ran.
459
+ * Represents the structured outcome of {@link import('./factories.js').createCaptureResult} — the
460
+ * wrapped function's own return `value` plus the `messages` it logged while it ran.
416
461
  *
417
462
  * @remarks
418
463
  * - `value` — whatever the wrapped `fn` returned (its `T`).
@@ -425,7 +470,7 @@ export declare interface CaptureResult<T> {
425
470
  }
426
471
 
427
472
  /**
428
- * The cell at `index` of a (possibly ragged) row — `''` when the row is shorter than the
473
+ * Returns the cell at `index` of a (possibly ragged) row — `''` when the row is shorter than the
429
474
  * column count, so a short row pads out instead of throwing (the ragged-row guard
430
475
  * {@link renderTable} reads every cell through).
431
476
  *
@@ -436,31 +481,31 @@ export declare interface CaptureResult<T> {
436
481
  export declare function cellAt(row: readonly string[], index: number): string;
437
482
 
438
483
  /**
439
- * A named terminal color — the 8 standard base colors, their 8 bright variants, and
484
+ * Names a terminal color — the 8 standard base colors, their 8 bright variants, and
440
485
  * `default` (the target's own default ink, emitting no color code).
441
486
  *
442
487
  * @remarks
443
- * Style as DATA: a `Color` is a name, not an escape sequence. The renderer maps it to
488
+ * Style as data: a `Color` is a name, not an escape sequence. The renderer maps it to
444
489
  * its target's codes — the ANSI renderer to SGR 30–37 / 90–97 (foreground) and 40–47 /
445
- * 100–107 (background); a browser renderer maps the SAME names to CSS colors.
490
+ * 100–107 (background); a browser renderer maps the same names to CSS colors.
446
491
  * `default` means "leave the target's default" and contributes no code.
447
492
  */
448
493
  export declare type Color = 'black' | 'red' | 'green' | 'yellow' | 'blue' | 'magenta' | 'cyan' | 'white' | 'brightBlack' | 'brightRed' | 'brightGreen' | 'brightYellow' | 'brightBlue' | 'brightMagenta' | 'brightCyan' | 'brightWhite' | 'default';
449
494
 
450
495
  /**
451
- * Every named {@link Color} except `default`, frozen — the colors the styler exposes as
496
+ * Lists every named {@link Color} except `default`, frozen — the colors the styler exposes as
452
497
  * chainable accessors. The source of truth for the color axis; the styler drives its
453
498
  * accessors from this array so the literals live in one place.
454
499
  */
455
500
  export declare const COLORS: ReadonlyArray<Exclude<Color, 'default'>>;
456
501
 
457
502
  /**
458
- * One column of a {@link TableOptions} — its header label and how its cells align.
503
+ * Represents one column of a {@link TableOptions} — its header label and how its cells align.
459
504
  *
460
505
  * @remarks
461
506
  * - `label` — the header text shown in the table's first row.
462
507
  * - `align` — how this column's header and cells align within the column width; defaults to
463
- * {@link DEFAULT_ALIGN} (`left`). The column is sized to the widest VISIBLE content
508
+ * {@link DEFAULT_ALIGN} (`left`). The column is sized to the widest visible content
464
509
  * (header or any cell, measured by {@link import('./helpers.js').width}), so a styled cell
465
510
  * never breaks the column.
466
511
  */
@@ -470,12 +515,12 @@ export declare interface ColumnSpec {
470
515
  }
471
516
 
472
517
  /**
473
- * An error thrown by the console layer.
518
+ * Carries a {@link ConsoleErrorCode} and an optional `context` bag — the error the console layer
519
+ * throws for an internal invariant violated at a defensive guard.
474
520
  *
475
521
  * @remarks
476
- * Carries a {@link ConsoleErrorCode} and an optional `context` bag. Thrown for: an
477
- * internal invariant violated at a defensive, structurally-unreachable guard
478
- * (`INVARIANT`) — the one throw site in this codebase today.
522
+ * `INVARIANT` is the code for a guard that is structurally unreachable, so a `catch` branches on
523
+ * `error.code` rather than parsing the message.
479
524
  */
480
525
  export declare class ConsoleError extends Error {
481
526
  readonly code: ConsoleErrorCode;
@@ -484,280 +529,152 @@ export declare class ConsoleError extends Error {
484
529
  }
485
530
 
486
531
  /**
487
- * A machine-readable error code for a {@link import('./errors.js').ConsoleError}.
532
+ * Names the machine-readable error code a {@link import('./errors.js').ConsoleError} carries —
533
+ * `INVARIANT`, the only code the package throws.
488
534
  *
489
535
  * @remarks
490
- * `INVARIANT` an internal invariant / unreachable-guard was violated (a defensive
491
- * check that should be structurally impossible to trip). The sole code today; §21
492
- * forbids speculating a richer taxonomy before a second throw site exists.
536
+ * `INVARIANT` reports that an internal invariant or unreachable guard was violated a defensive
537
+ * check that is structurally impossible to trip.
493
538
  */
494
539
  export declare type ConsoleErrorCode = 'INVARIANT';
495
540
 
541
+ /**
542
+ * Names the console-method shape a {@link CaptureInterface} snapshots and swaps at the patch
543
+ * boundary — a variadic sink of arbitrary arguments.
544
+ *
545
+ * @remarks
546
+ * It is exactly the universal `console.log` / `info` / `warn` / `error` / `debug` signature, so it
547
+ * types the global `console` viewed as a record keyed by {@link CaptureLevel}. Every
548
+ * `CaptureLevel` is a real `Console` method, so `console` is assignable to that view with no type
549
+ * assertion, which keeps the global-patch boundary honest.
550
+ */
496
551
  export declare type ConsoleMethod = (...args: unknown[]) => void;
497
552
 
498
553
  /**
499
- * Matches every C0 control character EXCEPT `\t` / `\n` / `\r` (which are meaningful
554
+ * Matches every C0 control character except `\t` / `\n` / `\r` (which are meaningful
500
555
  * whitespace), plus DEL (`0x7F`) — the non-printing bytes {@link
501
556
  * import('./helpers.js').stripControls} removes. Global, ASCII-only source (no raw
502
557
  * control-character literal), so a scan builds a fresh `RegExp` the same way as
503
558
  * {@link ANSI_PATTERN} to avoid a mutated `lastIndex`.
504
559
  *
505
560
  * @remarks
506
- * Deliberately SEPARATE from {@link ANSI_PATTERN}: `strip()` must stay pure ANSI-escape
561
+ * Deliberately separate from {@link ANSI_PATTERN}: `strip()` must stay pure ANSI-escape
507
562
  * removal (width / alignment computations depend on it leaving raw C0 bytes alone), while
508
- * C0-stripping is an ADDITIONAL, orthogonal pass a non-TTY output sink applies on top.
563
+ * C0-stripping is an additional, orthogonal pass a non-TTY output sink applies on top.
509
564
  */
510
565
  export declare const CONTROL_PATTERN: RegExp;
511
566
 
512
567
  /**
513
- * Create the cross-environment default {@link RendererInterface} the ANSI / SGR
514
- * renderer that turns style DATA into terminal escape codes. The default behind
515
- * {@link createStyler}; construct one directly to render a {@link import('./types.js').Style}
516
- * without the fluent surface, or to share one instance across stylers.
568
+ * Runs `fn` with the global `console.*` captured for its duration, returning the function's `value`
569
+ * plus the {@link import('./types.js').CapturedMessage}s it logged the scoped, self-restoring
570
+ * ergonomic form of the {@link Capture} class.
517
571
  *
518
- * @returns A stateless ANSI {@link RendererInterface}
572
+ * @param fn - The async function to run under capture (returns `Promise<T>`)
573
+ * @param options - See {@link CaptureOptions} (`levels` / `mirror` / `sink` / `limit` / `on` /
574
+ * `error`); the capture is started for the duration of `fn` regardless
575
+ * @returns A `Promise<CaptureResult<T>>` — awaited, then `console` restored
576
+ *
577
+ * @remarks
578
+ * - **Always restores.** `start()` runs before `fn`; `destroy()` (which calls `stop()`) runs on
579
+ * every path — sync success, sync throw, and each async handler — so `console` is restored even
580
+ * if `fn` throws / rejects (the throw / rejection still propagates). The capture is local —
581
+ * created, used, and destroyed within the call.
582
+ * - **Sync vs async.** A `fn` returning a `Promise` is detected and awaited before `stop()`, so
583
+ * captures during the async work are included; a plain `fn` stops synchronously. The return type
584
+ * follows `fn`'s (overloaded).
585
+ * - **process-global caveat.** Like the {@link Capture} class, this patches the one global
586
+ * `console`. Concurrent `createCaptureResult` calls (or one around other capturing code)
587
+ * interleave — each captures every `console.*` call in flight, and the inner `stop()` restores
588
+ * whatever the outer had installed. Use it for sequential, scoped capture, not overlapping captures.
519
589
  *
520
590
  * @example
521
591
  * ```ts
522
- * import { createANSIRenderer } from '@src/core'
592
+ * import { createCaptureResult } from '@orkestrel/console'
523
593
  *
524
- * const renderer = createANSIRenderer()
525
- * renderer.render({ foreground: 'red', attributes: ['bold'] }, 'alert') // '\x1b[1;31malert\x1b[0m'
594
+ * // The async call is awaited before `console` is restored, so the capture covers the async work.
595
+ * const out = await createCaptureResult(async () => {
596
+ * console.warn('async noise')
597
+ * return 'done'
598
+ * })
599
+ * out.value // 'done'
600
+ * out.messages.map((m) => m.text) // ['async noise']
526
601
  * ```
527
602
  */
528
- export declare function createANSIRenderer(): RendererInterface;
603
+ export declare function createCaptureResult<T>(fn: () => Promise<T>, options?: CaptureOptions): Promise<CaptureResult<T>>;
529
604
 
530
605
  /**
531
- * Create an observable {@link CaptureInterface} console interception on the READ side. While
532
- * `active`, every configured `console.*` call is captured as a frozen
533
- * {@link import('./types.js').CapturedMessage}, buffered (total + by level, bounded), emitted on
534
- * `capture`, and — per options — mirrored to the real console and/or forwarded to a
535
- * {@link SinkInterface}.
606
+ * Runs `fn` with the global `console.*` captured for its duration, returning the function's `value`
607
+ * plus the {@link import('./types.js').CapturedMessage}s it logged, synchronously.
536
608
  *
609
+ * @param fn - The synchronous function to run under capture (returns `T`)
537
610
  * @param options - See {@link CaptureOptions}
538
- * @returns A {@link CaptureInterface} (inactive until `start()`)
539
- *
540
- * @remarks
541
- * - **Snapshot-at-start — no capture loop.** `start()` snapshots the CURRENT `console[level]` per
542
- * configured level, then patches; the mirror writes through that snapshot. Our OWN console sink
543
- * output (the Logger / Reporter, which snapshot `console` at creation) is never recaptured —
544
- * `Capture` catches THIRD-PARTY `console.*`, not our writes. Create your loggers FIRST.
545
- * - **PROCESS-GLOBAL + NON-REENTRANT.** It patches the one global `console`, so at most ONE
546
- * capture may be active at a time; two concurrent captures interleave and clobber each other's
547
- * restore. Prefer {@link withCapture} for a scoped, self-restoring capture.
548
- * - **Bounded.** `options.limit` (default {@link import('./constants.js').DEFAULT_CAPTURE_LIMIT})
549
- * caps both the total buffer and each by-level bucket; never unbounded.
611
+ * @returns A {@link CaptureResult}`<T>` `{ value, messages }`, with `console` already restored
550
612
  *
551
613
  * @example
552
614
  * ```ts
553
- * import { createCapture } from '@src/core'
615
+ * import { createCaptureResult } from '@orkestrel/console'
554
616
  *
555
- * const capture = createCapture({ levels: ['warn', 'error'] })
556
- * capture.start()
557
- * console.error('boom') // captured, NOT mirrored (mirror defaults to false)
558
- * capture.messages('error') // [{ level: 'error', text: 'boom', time: … }]
559
- * capture.stop()
617
+ * // The sync call returns the result directly — no `await`, `console` already restored.
618
+ * const { value, messages } = createCaptureResult(() => {
619
+ * console.log('working')
620
+ * return 42
621
+ * })
622
+ * value // 42
623
+ * messages.map((m) => m.text) // ['working']
560
624
  * ```
561
625
  */
562
- export declare function createCapture(options?: CaptureOptions): CaptureInterface;
626
+ export declare function createCaptureResult<T>(fn: () => T, options?: CaptureOptions): CaptureResult<T>;
563
627
 
564
628
  /**
565
- * Create the default {@link SinkInterface} — a console sink that routes by level and writes
566
- * through the `console` methods SNAPSHOTTED at creation. The default output target behind
567
- * {@link createLogger}.
629
+ * Creates the default {@link SinkInterface} — a console sink that routes by level and writes
630
+ * through the `console` methods snapshotted at creation. The default output target behind the
631
+ * {@link import('./loggers/Logger.js').Logger}.
568
632
  *
569
633
  * @returns A console {@link SinkInterface}
570
634
  *
571
635
  * @remarks
572
636
  * - **Snapshotted — no capture loop.** It captures `console.log` / `console.warn` /
573
- * `console.error` AT CALL TIME and writes through those references. So when a later
574
- * `Capture` (C-d) PATCHES `console.*`, this sink still reaches the REAL streams — the
637
+ * `console.error` at call time and writes through those references. So when a later
638
+ * `Capture` patches `console.*`, this sink still reaches the real streams — the
575
639
  * writer and the capturer never feed each other (the no-capture-loop principle). Create
576
- * the sink (or the logger) BEFORE installing a capture for this to hold.
640
+ * the sink (or the logger) before installing a capture for this to hold.
577
641
  * - **Routes by level.** `error` → the snapshotted `console.error`, `warn` →
578
642
  * `console.warn`, every other level → `console.log`. The `level` is supplied by the
579
- * logger; an omitted `level` goes to `console.log`.
643
+ * logger; an omitted `level` goes to `console.log`. The decision is
644
+ * {@link import('./helpers.js').selectWriter}'s, shared with the browser and server sinks.
580
645
  *
581
646
  * @example
582
647
  * ```ts
583
- * import { createConsoleSink } from '@src/core'
648
+ * import { createConsoleSink } from '@orkestrel/console'
584
649
  *
585
- * const sink = createConsoleSink() // snapshots console.* now
650
+ * const sink = createConsoleSink() // snapshots console.* at construction
586
651
  * sink.write('boom', 'error') // → the real console.error, even after a later console patch
587
652
  * ```
588
653
  */
589
654
  export declare function createConsoleSink(): SinkInterface;
590
655
 
591
656
  /**
592
- * Create an observable, leveled {@link LoggerInterface} — the entry point into structured
593
- * logging. Each `debug` / `info` / `warn` / `error` call builds a frozen
594
- * {@link import('./types.js').LogRecord}, gates it by severity, retains a bounded tail,
595
- * ALWAYS emits it on `entry` (the transport seam), and — unless `silent` — writes a styled
596
- * line to its sink.
597
- *
598
- * @param options - See {@link LoggerOptions}
599
- * @returns A {@link LoggerInterface}
600
- *
601
- * @remarks
602
- * - **Record + event = transport (§13).** Subscribe `logger.emitter.on('entry', …)` to tee
603
- * records to a file / JSON / remote transport; the event fires for every accepted record,
604
- * even when `silent` (silence suppresses only the SINK WRITE).
605
- * - **Bounded retention.** `entries()` returns the recent records, capped at `options.limit`
606
- * (default {@link DEFAULT_LOG_LIMIT}); never unbounded.
607
- * - **Sink + styler defaults.** `options.sink` defaults to {@link createConsoleSink} (the
608
- * snapshotted, level-routing console sink); `options.styler` to {@link createStyler} (ANSI).
609
- * Styling is orthogonal to level — a level only chooses a label color.
610
- *
611
- * @example
612
- * ```ts
613
- * import { createLogger } from '@src/core'
614
- *
615
- * const logger = createLogger({ name: 'http', level: 'info' })
616
- * logger.info('request', { method: 'GET', path: '/' })
617
- * logger.debug('verbose') // dropped — below the info threshold
618
- * ```
619
- */
620
- export declare function createLogger(options?: LoggerOptions): LoggerInterface;
621
-
622
- /**
623
- * Create an event-free {@link LoggerManagerInterface} — a §9 registry of named loggers plus
624
- * a convenience fan-out. It mints + stores {@link LoggerInterface}s keyed by name (its
625
- * defaults flowing into each), looks them up, removes them, and broadcasts a one-off log to
626
- * every registered logger.
627
- *
628
- * @param options - See {@link LoggerManagerOptions}
629
- * @returns A {@link LoggerManagerInterface}
657
+ * Creates the fluent, composable {@link StylerInterface} — ANSI by default, retargeted by a
658
+ * `renderer` and stripped of color by `enabled: false`.
630
659
  *
631
660
  * @remarks
632
- * - **Defaults flow in.** `options.level` / `sink` / `styler` / `limit` / `silent` are the
633
- * defaults flowed into every `register`ed logger unless that call's options override them.
634
- * - **Event-free.** The manager carries NO emitter (each registered logger owns its own
635
- * observable `emitter`) — it is a pure registry.
636
- *
637
- * @example
638
- * ```ts
639
- * import { createLoggerManager } from '@src/core'
640
- *
641
- * const loggers = createLoggerManager({ level: 'warn' })
642
- * loggers.register('http')
643
- * loggers.register('db', { level: 'debug' }) // overrides the default
644
- * loggers.warn('slow', { ms: 900 }) // fans out to both
645
- * ```
646
- */
647
- export declare function createLoggerManager(options?: LoggerManagerOptions): LoggerManagerInterface;
648
-
649
- /**
650
- * Create an update-driven, observable {@link ProgressInterface} — a live progress bar. Each
651
- * `update(current)` recomputes the bar, writes `\r` + bar to its sink, and emits `{ current, total }`
652
- * on `update`; `complete` / `failure` commit a final line. The leading `\r` is the sink's to redraw on —
653
- * a TTY sink (C-g) overwrites, a plain sink (C-f) degrades to a fresh line. NO self-timer — the caller
654
- * drives the bar.
655
- *
656
- * @param options - See {@link ProgressOptions} (`total` is required)
657
- * @returns A {@link ProgressInterface}
658
- *
659
- * @remarks
660
- * - **Universal + update-driven.** Built on the one styler + the one sink (no `node:*`, no
661
- * `process.stdout`); progress advances only when the caller reports it. `current` is always clamped
662
- * to `[0, total]`. `options.sink` defaults to {@link createConsoleSink}, `options.styler` to
663
- * {@link createStyler} (ANSI).
664
- * - **Observable (§13).** Subscribe `progress.emitter.on('update', …)` to mirror progress without a
665
- * terminal; `complete` signals a successful finish.
666
- *
667
- * @example
668
- * ```ts
669
- * import { createProgress } from '@src/core'
670
- *
671
- * const progress = createProgress({ total: 100, message: 'downloading' })
672
- * progress.update(40)
673
- * progress.complete('done')
674
- * ```
675
- */
676
- export declare function createProgress(options: ProgressOptions): ProgressInterface;
677
-
678
- /**
679
- * Create a lean, event-free {@link ReporterInterface} — the entry point into narrative
680
- * reporting. Each verb (`section` / `step` / `timing` / `status` / `table` / `tree` / `box` /
681
- * `line` / `blank`) formats through the shared styler + the pure layout renderers and writes to
682
- * the sink — human / build-run narration over the SAME substrate the logger uses.
683
- *
684
- * @param options - See {@link ReporterOptions}
685
- * @returns A {@link ReporterInterface}
686
- *
687
- * @remarks
688
- * - **One styler, one sink.** `options.styler` defaults to {@link createStyler} (ANSI) and
689
- * `options.sink` to {@link createConsoleSink} (the snapshotted, level-routing console sink) —
690
- * no second colorizer. A `status('error', …)` routes to the sink's error stream.
691
- * - **Width-aware.** `options.width` (default {@link DEFAULT_WIDTH}) sizes `section` and a
692
- * `box` with no explicit width; the renderers align on VISIBLE width so styled content keeps
693
- * its columns.
694
- * - **Event-free (§13).** The reporter carries no emitter — a pure formatting front-end, like
695
- * the renderers and `Scheduler`. Reach for a {@link createLogger} when you need observable,
696
- * leveled, transportable records instead.
697
- *
698
- * @example
699
- * ```ts
700
- * import { createReporter } from '@src/core'
701
- *
702
- * const reporter = createReporter()
703
- * reporter.section('Build')
704
- * reporter.step('bundling', { index: 2, total: 5 }) // [2/5] bundling
705
- * reporter.status('success', 'built in 1.2s') // ✔ built in 1.2s
706
- *
707
- * // Disable color (a non-TTY) — every line is plain.
708
- * const plain = createReporter({ styler: createStyler({ enabled: false }) })
709
- * ```
710
- */
711
- export declare function createReporter(options?: ReporterOptions): ReporterInterface;
712
-
713
- /**
714
- * Create a self-driving, observable {@link SpinnerInterface} — a live activity spinner. `start()`
715
- * arms a periodic timer that advances a glyph cycle, writing each `\r` + frame line to its sink and
716
- * emitting it on `frame`; `success` / `failure` commit a final `✔` / `✖` line. The leading `\r` is the
717
- * sink's to redraw on — a TTY sink (C-g) overwrites for a smooth animation, a plain sink (C-f)
718
- * degrades to a fresh line.
719
- *
720
- * @param options - See {@link SpinnerOptions}
721
- * @returns A {@link SpinnerInterface} (inactive until `start()`)
722
- *
723
- * @remarks
724
- * - **Universal + leak-free.** Built on `setInterval` + the one styler + the one sink (no `node:*`,
725
- * no `process.stdout`); the timer is ALWAYS cleared on `success` / `failure` / `stop` / `destroy`, so
726
- * it never leaks. `start()` is idempotent (no second timer while `active`).
727
- * - **Observable (§13).** Subscribe `spinner.emitter.on('frame', …)` to mirror the animation without
728
- * a terminal; `start` / `stop` bracket the timer lifecycle. `options.sink` defaults to
729
- * {@link createConsoleSink}, `options.styler` to {@link createStyler} (ANSI).
730
- *
731
- * @example
732
- * ```ts
733
- * import { createSpinner } from '@src/core'
734
- *
735
- * const spinner = createSpinner({ message: 'building' })
736
- * spinner.start()
737
- * spinner.success('built in 1.2s') // ✔ built in 1.2s — timer cleared, line committed
738
- * ```
739
- */
740
- export declare function createSpinner(options?: SpinnerOptions): SpinnerInterface;
741
-
742
- /**
743
- * Create the fluent, composable {@link StylerInterface} — the consumer-facing styling
744
- * API. It builds a {@link import('./types.js').Style} under the hood and renders it
745
- * through a {@link RendererInterface} (the ANSI default), so `styler.red.bold('hi')`
746
- * yields styled text. Chains are immutable, so a base styler is freely reusable.
661
+ * It builds a {@link import('./types.js').Style} under the hood and renders it through a
662
+ * {@link import('./types.js').RendererInterface}, so `styler.red.bold('hi')` yields styled text.
663
+ * Chains are immutable, so a base styler is freely reusable.
747
664
  *
748
665
  * @param options - See {@link StylerOptions}
749
666
  * @returns A base {@link StylerInterface}
750
667
  *
751
668
  * @remarks
752
669
  * - `options.renderer` swaps the output target without touching the style model — pass a
753
- * browser `%c` / CSS renderer (the C-f branch) to retarget; defaults to the ANSI
670
+ * browser `%c` / CSS renderer (the browser branch) to retarget; defaults to the ANSI
754
671
  * renderer (the cross-environment default).
755
672
  * - `options.enabled` is the no-color switch: when `false`, the styler returns text
756
- * VERBATIM (for a non-TTY, `NO_COLOR`, or piped output); defaults to `true`.
673
+ * verbatim (for a non-TTY, `NO_COLOR`, or piped output); defaults to `true`.
757
674
  *
758
675
  * @example
759
676
  * ```ts
760
- * import { createStyler } from '@src/core'
677
+ * import { createStyler } from '@orkestrel/console'
761
678
  *
762
679
  * const style = createStyler()
763
680
  * style.red.bold('error') // bold red
@@ -771,7 +688,7 @@ export declare function createSpinner(options?: SpinnerOptions): SpinnerInterfac
771
688
  export declare function createStyler(options?: StylerOptions): StylerInterface;
772
689
 
773
690
  /**
774
- * Create a {@link Theme} — the app-wide semantic style vocabulary, merged role by role over
691
+ * Creates a {@link Theme} — the app-wide semantic style vocabulary, merged role by role over
775
692
  * {@link DEFAULT_THEME}. Hand one theme to a logger / reporter / spinner / progress and every
776
693
  * surface speaks it; omit `options` for the defaults.
777
694
  *
@@ -779,8 +696,8 @@ export declare function createStyler(options?: StylerOptions): StylerInterface;
779
696
  * @returns A frozen {@link Theme}
780
697
  *
781
698
  * @remarks
782
- * - **Merges per ROLE, not per theme.** An omitted role keeps its default, and `levels` /
783
- * `statuses` merge per ENTRY — `{ levels: { warn: … } }` restyles the `warn` label and
699
+ * - **Merges per role, not per theme.** An omitted role keeps its default, and `levels` /
700
+ * `statuses` merge per entry — `{ levels: { warn: … } }` restyles the `warn` label and
784
701
  * leaves `debug` / `info` / `error` untouched.
785
702
  * - **Frozen and shareable.** The factory snapshots and deep-freezes every style leaf. The
786
703
  * returned theme and its `levels` / `statuses` records are frozen. Each status record is also
@@ -788,7 +705,7 @@ export declare function createStyler(options?: StylerOptions): StylerInterface;
788
705
  *
789
706
  * @example
790
707
  * ```ts
791
- * import { createStyler, createTheme } from '@src/core'
708
+ * import { createStyler, createTheme } from '@orkestrel/console'
792
709
  *
793
710
  * const styler = createStyler()
794
711
  * const theme = createTheme({
@@ -800,64 +717,70 @@ export declare function createStyler(options?: StylerOptions): StylerInterface;
800
717
  */
801
718
  export declare function createTheme(options?: ThemeOptions): Theme;
802
719
 
803
- /** The Control Sequence Introducer (`ESC[`) that opens every SGR sequence. */
720
+ /** Holds the Control Sequence Introducer (`ESC[`) that opens every SGR sequence. */
804
721
  export declare const CSI: string;
805
722
 
806
- /** The default cell {@link Alignment} a {@link import('./types.js').ColumnSpec} uses when none is given — `left`. */
723
+ /** Sets the default cell {@link Alignment} a {@link import('./types.js').ColumnSpec} uses when none is given — `left`. */
807
724
  export declare const DEFAULT_ALIGN: Alignment;
808
725
 
809
726
  /**
810
- * The default visible cell count of a progress-bar TRACK — the glyph run {@link
811
- * import('./helpers.js').renderBar} fills (and a {@link import('./types.js').ProgressInterface} sizes
812
- * its bar to). Thirty cells is a compact, terminal-friendly default; a consumer overrides it via
813
- * `options.width`. Distinct from {@link DEFAULT_WIDTH} (the renderers' 80-column line width) — a bar
814
- * track is one inline element, not a full-width rule.
727
+ * Sets the default visible cell count of a progress-bar track — the glyph run
728
+ * {@link import('./helpers.js').renderBar} fills, and the width a
729
+ * {@link import('./types.js').ProgressInterface} sizes its bar to. `30` cells.
730
+ *
731
+ * @remarks
732
+ * Thirty cells is a compact, terminal-friendly default; a consumer overrides it through
733
+ * `options.width`. It is distinct from {@link DEFAULT_WIDTH} (the renderers' 80-column line
734
+ * width) — a bar track is one inline element, not a full-width rule.
815
735
  */
816
736
  export declare const DEFAULT_BAR_WIDTH = 30;
817
737
 
818
- /** The default {@link BorderStyle} the box / table renderers frame with when none is given — `single`. */
738
+ /** Sets the default {@link BorderStyle} the box / table renderers frame with when none is given — `single`. */
819
739
  export declare const DEFAULT_BORDER: BorderStyle;
820
740
 
821
741
  /**
822
- * The default set of {@link CaptureLevel}s a Capture patches when `options.levels` is omitted —
823
- * all five universal `console.*` methods ({@link CAPTURE_LEVELS}). A consumer narrows it (e.g. just
824
- * `['warn', 'error']`) via `options.levels`.
825
- */
826
- export declare const DEFAULT_CAPTURE_LEVELS: readonly CaptureLevel[];
827
-
828
- /**
829
- * The default bounded-buffer cap for a {@link import('./types.js').CaptureInterface} — at most this
830
- * many recent {@link CapturedMessage}s are retained per buffer (the total buffer AND each by-level
831
- * bucket; oldest dropped first). Capture retention is ALWAYS bounded so a long-running capture can
832
- * never grow without bound (the same retention precedent as {@link DEFAULT_LOG_LIMIT}); a consumer
833
- * overrides it via `options.limit`.
742
+ * Sets the default bounded-buffer cap for a {@link import('./types.js').CaptureInterface} `1000`,
743
+ * so at most that many recent {@link CapturedMessage}s are retained per buffer (the total buffer
744
+ * and each by-level bucket; oldest dropped first) and retention is always bounded.
745
+ *
746
+ * @remarks
747
+ * A long-running capture can never grow without bound (the same retention precedent as
748
+ * {@link DEFAULT_LOG_LIMIT}); a consumer overrides the cap through `options.limit`.
834
749
  */
835
750
  export declare const DEFAULT_CAPTURE_LIMIT = 1000;
836
751
 
837
- /** The default {@link LogLevel} threshold a logger gates at when none is supplied — `info`. */
752
+ /** Sets the default {@link LogLevel} threshold a logger gates at when none is supplied — `info`. */
838
753
  export declare const DEFAULT_LOG_LEVEL: LogLevel;
839
754
 
840
755
  /**
841
- * The default bounded-retention cap for a {@link import('./types.js').LoggerInterface} — at
842
- * most this many recent records are kept (oldest dropped first). Retention is ALWAYS bounded
843
- * (never the unbounded buffer scsr leaked); a consumer overrides it via `options.limit`.
756
+ * Sets the default bounded-retention cap for a {@link import('./types.js').LoggerInterface} —
757
+ * `1000`, so at most that many recent records are kept and retention is always bounded.
758
+ *
759
+ * @remarks
760
+ * The oldest record is dropped after the cap is reached; a consumer overrides the cap through
761
+ * `options.limit`.
844
762
  */
845
763
  export declare const DEFAULT_LOG_LIMIT = 1000;
846
764
 
847
- /** The default horizontal padding inside a box's edges ({@link import('./helpers.js').renderBox}) — one cell. */
765
+ /** Sets the default horizontal padding inside a box's edges ({@link import('./helpers.js').renderBox}) — one cell. */
848
766
  export declare const DEFAULT_PADDING = 1;
849
767
 
850
768
  /**
851
- * The default timer period in milliseconds between a {@link import('./types.js').SpinnerInterface}'s
852
- * frames — the `setInterval` interval `start()` arms. Eighty milliseconds (≈12.5 frames/second) is
853
- * the conventional spinner cadence: fast enough to read as motion, slow enough not to thrash a
854
- * terminal. A consumer overrides it via `options.interval`.
769
+ * Sets the default timer period between a {@link import('./types.js').SpinnerInterface}'s frames —
770
+ * the `setInterval` interval `start()` arms, `80` ms (≈12.5 frames/second).
771
+ *
772
+ * @remarks
773
+ * That is the conventional spinner cadence: fast enough to read as motion, slow enough not to
774
+ * thrash a terminal. A consumer overrides it through `options.interval`.
855
775
  */
856
776
  export declare const DEFAULT_SPINNER_INTERVAL = 80;
857
777
 
858
778
  /**
859
- * The default {@link Theme} — every role bound to its default {@link Style}, deeply frozen.
860
- * The base {@link import('./factories.js').createTheme} merges over, and the theme every
779
+ * Holds the default {@link Theme} — every role bound to its default {@link Style}, assembled from
780
+ * {@link LEVEL_COLORS}, {@link STATUS_ICONS}, and {@link STATUS_COLORS} and deeply frozen.
781
+ *
782
+ * @remarks
783
+ * It is the base {@link import('./factories.js').createTheme} merges over, and the theme every
861
784
  * entity uses when none is supplied.
862
785
  *
863
786
  * @remarks
@@ -871,34 +794,34 @@ export declare const DEFAULT_SPINNER_INTERVAL = 80;
871
794
  export declare const DEFAULT_THEME: Theme;
872
795
 
873
796
  /**
874
- * The default visible column width for the width-aware renderers — the separator rule and a
797
+ * Sets the default visible column width for the width-aware renderers — the separator rule and a
875
798
  * {@link import('./helpers.js').renderBox} with no explicit `width`, and the reporter's
876
- * `section` rule. A sane terminal default (80 columns); a caller overrides it per-call or via
877
- * {@link import('./types.js').ReporterOptions}`.width`.
799
+ * `section` rule. A sane terminal default (80 columns); a caller overrides it per-call or through
800
+ * {@link import('./types.js').ReporterOptions.width}.
878
801
  */
879
802
  export declare const DEFAULT_WIDTH = 80;
880
803
 
881
804
  /**
882
- * The EMPTY {@link Style} — no foreground, no background, no attributes — frozen. The
805
+ * Holds the empty {@link Style} — no foreground, no background, no attributes — frozen. The
883
806
  * neutral starting point a base styler builds from, and what a renderer passes through
884
807
  * unchanged (it carries no codes). Deeply frozen, so it is safe to share as the base.
885
808
  */
886
809
  export declare const EMPTY_STYLE: Style;
887
810
 
888
811
  /**
889
- * The ESC control character (`U+001B`) that begins every ANSI escape sequence. Built
812
+ * Holds the escape control character (`U+001B`) that begins every ANSI escape sequence. Built
890
813
  * with `String.fromCharCode` so no raw control character appears in source.
891
814
  */
892
815
  export declare const ESC: string;
893
816
 
894
817
  /**
895
- * Each {@link Color}'s SGR FOREGROUND parameter — the 8 base colors at 30–37 and their
818
+ * Maps each {@link Color} to its SGR foreground parameter — the 8 base colors at 30–37 and their
896
819
  * bright variants at 90–97. `default` is intentionally absent (it emits no code).
897
820
  */
898
821
  export declare const FOREGROUND_CODES: Readonly<Record<Exclude<Color, 'default'>, number>>;
899
822
 
900
823
  /**
901
- * Stringify a captured `console.*` argument list into ONE line — the text of a {@link
824
+ * Stringifies a captured `console.*` argument list into one line — the text of a {@link
902
825
  * import('./types.js').CapturedMessage}. Each argument is rendered by {@link stringifyValue} and
903
826
  * the parts are space-joined, mirroring how a console concatenates its arguments.
904
827
  *
@@ -919,7 +842,7 @@ export declare const FOREGROUND_CODES: Readonly<Record<Exclude<Color, 'default'>
919
842
  export declare function formatArgs(args: readonly unknown[]): string;
920
843
 
921
844
  /**
922
- * Format a millisecond duration as a compact human string — `…ms` below one second, `…s`
845
+ * Formats a millisecond duration as a compact human string — `…ms` below one second, `…s`
923
846
  * (seconds to 2 decimal places) at or above one second. The timing rendering behind
924
847
  * {@link import('./types.js').ReporterInterface.timing}.
925
848
  *
@@ -933,7 +856,7 @@ export declare function formatArgs(args: readonly unknown[]): string;
933
856
  export declare function formatDuration(ms: number): string;
934
857
 
935
858
  /**
936
- * Format a {@link LogRecord} into a single styled line — the default human line layout a
859
+ * Formats a {@link LogRecord} into a single styled line — the default human line layout a
937
860
  * {@link import('./types.js').LoggerInterface} writes to its sink.
938
861
  *
939
862
  * @remarks
@@ -942,7 +865,7 @@ export declare function formatDuration(ms: number): string;
942
865
  * the originating logger's `name` in brackets (omitted when absent), the message, and the
943
866
  * structured `data` appended as compact JSON (omitted when absent / empty). Coloring flows
944
867
  * through the injected `styler`, so a disabled styler yields a plain line and a browser
945
- * `%c` styler (C-f) retargets it — the layout never changes. Pure: same record + styler →
868
+ * `%c` styler retargets it — the layout never changes. Pure: same record + styler →
946
869
  * same line.
947
870
  *
948
871
  * @param record - The {@link LogRecord} to render
@@ -963,10 +886,10 @@ export declare function formatDuration(ms: number): string;
963
886
  export declare function formatRecord(record: LogRecord, styler: StylerInterface, theme: Theme): string;
964
887
 
965
888
  /**
966
- * Format a {@link LogRecord}'s `time` (epoch milliseconds) as an ISO-8601 timestamp string.
889
+ * Formats a {@link LogRecord}'s `time` (epoch milliseconds) as an ISO-8601 timestamp string.
967
890
  *
968
891
  * @remarks
969
- * Deterministic and serializable — `new Date(time).toISOString()`, e.g.
892
+ * Deterministic and serializable — `new Date(time).toISOString()`, for example
970
893
  * `1716900000000 → '2024-05-28T12:40:00.000Z'`. The timestamp portion of the formatted log
971
894
  * line; kept a pure helper so the line layout and the logger stay decoupled.
972
895
  *
@@ -976,7 +899,8 @@ export declare function formatRecord(record: LogRecord, styler: StylerInterface,
976
899
  export declare function formatTime(time: number): string;
977
900
 
978
901
  /**
979
- * Snapshot and deeply freeze one {@link Style} value.
902
+ * Snapshots and deeply freezes one {@link Style} value, including an independent frozen copy of
903
+ * its `attributes`.
980
904
  *
981
905
  * @param style - The caller-owned style to snapshot
982
906
  * @returns A frozen style record with an independently frozen attributes list
@@ -993,10 +917,10 @@ export declare function formatTime(time: number): string;
993
917
  export declare function freezeStyle(style: Style): Style;
994
918
 
995
919
  /**
996
- * Narrow an unknown caught value to a {@link ConsoleError}.
920
+ * Narrows an unknown caught value to a {@link ConsoleError} — the guard a `catch` branches on.
997
921
  *
998
922
  * @param value - The value to test (typically a `catch` binding)
999
- * @returns `true` when `value` is a {@link ConsoleError}
923
+ * @returns True if `value` is a {@link ConsoleError}; false otherwise
1000
924
  *
1001
925
  * @example
1002
926
  * ```ts
@@ -1010,8 +934,8 @@ export declare function freezeStyle(style: Style): Style;
1010
934
  export declare function isConsoleError(value: unknown): value is ConsoleError;
1011
935
 
1012
936
  /**
1013
- * Each {@link LogLevel}'s default label {@link Color} — the level's VISUAL treatment, which
1014
- * is a styling choice ORTHOGONAL to the level itself (never a separate pseudo-level). The
937
+ * Maps each {@link LogLevel} to its default label {@link Color} — the level's visual treatment, which
938
+ * is a styling choice orthogonal to the level itself (never a separate pseudo-level). The
1015
939
  * logger colors the level label through its styler with these; swapping a color never
1016
940
  * changes leveling. `debug` is cyan, `info` blue, `warn` yellow, `error` red.
1017
941
  *
@@ -1022,32 +946,33 @@ export declare function isConsoleError(value: unknown): value is ConsoleError;
1022
946
  export declare const LEVEL_COLORS: Readonly<Record<LogLevel, Exclude<Color, 'default'>>>;
1023
947
 
1024
948
  /**
1025
- * Each {@link LogLevel}'s numeric SEVERITY — the ascending order the level gate compares
949
+ * Maps each {@link LogLevel} to its numeric severity — the ascending order the level gate compares
1026
950
  * through (`debug` 0 < `info` 1 < `warn` 2 < `error` 3). A record is kept when its level's
1027
951
  * severity is at or above the logger's threshold. The source of truth for level ordering.
1028
952
  */
1029
953
  export declare const LEVEL_SEVERITY: Readonly<Record<LogLevel, number>>;
1030
954
 
1031
955
  /**
1032
- * Every {@link LogLevel}, in ascending severity order — the levels a logger exposes as
956
+ * Lists every {@link LogLevel}, in ascending severity order — the levels a logger exposes as
1033
957
  * methods and the manager fans out to. The source of truth for the level axis (drives
1034
958
  * exhaustive tests); aligned with {@link LEVEL_SEVERITY}.
1035
959
  */
1036
- export declare const LEVELS: readonly LogLevel[];
960
+ export declare const LOG_LEVELS: readonly LogLevel[];
1037
961
 
1038
962
  /**
1039
- * The line layout a logger writes — one {@link LogRecord} plus the styling substrate in,
1040
- * one finished line out. {@link import('./helpers.js').formatRecord} is the default.
963
+ * Represents the line layout a logger writes — `(record, styler, theme) => string`, one
964
+ * {@link LogRecord} plus the styling substrate in and one finished line out.
965
+ * {@link import('./helpers.js').formatRecord} is the default.
1041
966
  *
1042
967
  * @param record - The frozen record to lay out
1043
968
  * @param styler - The logger's {@link StylerInterface} — color through it (and through
1044
969
  * {@link StylerInterface.render} for a {@link Theme} role) so a disabled styler yields a
1045
970
  * plain line with no second code path
1046
971
  * @param theme - The logger's {@link Theme} — the level label style, the chrome surround
1047
- * @returns The line to write, WITHOUT a trailing terminator (the sink's target supplies it)
972
+ * @returns The line to write, without a trailing terminator (the sink's target supplies it)
1048
973
  *
1049
974
  * @remarks
1050
- * The formatter owns the LINE; the `entry` event owns the RECORD. A transport that wants
975
+ * The formatter owns the line; the `entry` event owns the record. A transport that wants
1051
976
  * structure rides the event rather than parsing a line back out of this. A formatter throw
1052
977
  * propagates to the caller of `logger.info` and prevents that line's write, so keep it total.
1053
978
  * A manager fans out sequentially; a formatter throw stops the remaining loggers for that call.
@@ -1055,25 +980,25 @@ export declare const LEVELS: readonly LogLevel[];
1055
980
  export declare type LogFormatFunction = (record: LogRecord, styler: StylerInterface, theme: Theme) => string;
1056
981
 
1057
982
  /**
1058
- * An observable, leveled logger (AGENTS §13) — the entry point into the structured-logging
983
+ * Implements an observable, leveled logger — the entry point into the structured-logging
1059
984
  * pipeline. Each `debug` / `info` / `warn` / `error` call builds a frozen {@link LogRecord},
1060
- * gates it by severity, retains a bounded tail of accepted records, ALWAYS emits it on
985
+ * gates it by severity, retains a bounded tail of accepted records, always emits it on
1061
986
  * `entry` (the transport seam), and — unless `silent` — formats it into a styled line and
1062
987
  * writes it to its {@link SinkInterface}.
1063
988
  *
1064
989
  * @remarks
1065
- * - **Record + event = transport (§13).** An accepted record is frozen and emitted on
1066
- * `entry` BEFORE anything else observable — every file / JSON / remote transport rides
990
+ * - **Record + event = transport.** An accepted record is frozen and emitted on
991
+ * `entry` before anything else observable — every file / JSON / remote transport rides
1067
992
  * `emitter.on('entry')`. The event fires even when `silent`: silence suppresses only the
1068
- * SINK WRITE, never the record or the event, so transports keep flowing.
993
+ * sink write, never the record or the event, so transports keep flowing.
1069
994
  * - **Leveled gate.** A record whose {@link LogLevel} is below the logger's `level` threshold
1070
- * is dropped ENTIRELY — no record built past the level check, no event, no retention, no
995
+ * is dropped entirely — no record built past the level check, no event, no retention, no
1071
996
  * write (see {@link meetsLevel}).
1072
997
  * - **Bounded retention.** Accepted records accrue in a ring capped at `limit` (default
1073
998
  * {@link DEFAULT_LOG_LIMIT}); the oldest is dropped when full. `entries()` returns a copy,
1074
- * oldest first; `clear()` empties it. NEVER unbounded (scsr's leak).
999
+ * oldest first; `clear()` empties it. Never unbounded retention is capped at `limit`.
1075
1000
  * - **Styled write, orthogonal to level.** The line ({@link formatRecord}) is colored through
1076
- * the injected `styler` (the ANSI default, or a browser `%c` styler at C-f) — a level only
1001
+ * the injected `styler` (the ANSI default, or a browser `%c` styler) — a level only
1077
1002
  * chooses a label color; styling is not a level. A disabled styler yields a plain line.
1078
1003
  * - **Snapshotted sink.** The default {@link createConsoleSink} writes to the `console`
1079
1004
  * methods captured at creation, so a later `Capture` patching `console` can't loop the
@@ -1104,25 +1029,26 @@ export declare class Logger implements LoggerInterface {
1104
1029
  }
1105
1030
 
1106
1031
  /**
1107
- * The observable events a {@link LoggerInterface} emits (AGENTS §13) the transport seam.
1032
+ * Declares the observable events a {@link LoggerInterface} emits — `entry(record)` for every
1033
+ * accepted record, the transport seam.
1108
1034
  *
1109
1035
  * @remarks
1110
- * `entry` fires for EVERY accepted record (one that passed the level gate), carrying the
1111
- * frozen {@link LogRecord} — even when the logger is `silent` (silence suppresses only the
1112
- * SINK WRITE, never the event, so transports keep receiving records). Listener isolation is
1113
- * the emitter's (§13): a listener throw routes to the emitter's `error` handler, never onto
1036
+ * `entry` carries the frozen {@link LogRecord} and fires even when the logger is
1037
+ * `silent` (silence suppresses only the
1038
+ * sink write, never the event, so transports keep receiving records). Listener isolation is
1039
+ * the emitter's: a listener throw routes to the emitter's `error` handler, never onto
1114
1040
  * this map — so a buggy transport can never perturb logging.
1115
1041
  *
1116
- * Declared as a `type` alias (not `interface extends EventMap`, §4.5): a type-literal
1042
+ * Declared as a `type` alias (not `interface extends EventMap`): a type-literal
1117
1043
  * satisfies the `EventMap` constraint structurally, whereas an interface lacks the index signature.
1118
1044
  */
1119
1045
  export declare type LoggerEventMap = {
1120
- /** A record was logged (passed the level gate) — the frozen {@link LogRecord}. */
1046
+ /** Fires after a record was logged (passed the level gate) — the frozen {@link LogRecord}. */
1121
1047
  readonly entry: readonly [record: LogRecord];
1122
1048
  };
1123
1049
 
1124
1050
  /**
1125
- * An observable, leveled logger — builds a frozen {@link LogRecord} per call, gates it by
1051
+ * Declares an observable, leveled logger — builds a frozen {@link LogRecord} per call, gates it by
1126
1052
  * severity, retains a bounded tail, emits it on `entry`, and (unless silent) writes a
1127
1053
  * styled line to its {@link SinkInterface}.
1128
1054
  *
@@ -1130,7 +1056,7 @@ export declare type LoggerEventMap = {
1130
1056
  * - **Leveled.** Each of `debug` / `info` / `warn` / `error` builds a record at that
1131
1057
  * {@link LogLevel}; a record below the logger's `level` threshold is dropped entirely (no
1132
1058
  * event, no retention, no write).
1133
- * - **Transport seam (§13).** An accepted record ALWAYS fires `entry` (even when `silent`),
1059
+ * - **Transport seam.** An accepted record always fires `entry` (even when `silent`),
1134
1060
  * carrying the frozen {@link LogRecord} — the hook every file / JSON / remote transport rides.
1135
1061
  * - **Bounded retention.** `entries()` returns the recent records, capped at `limit` (oldest
1136
1062
  * dropped first) — never an unbounded buffer. `clear()` empties it.
@@ -1143,39 +1069,40 @@ export declare interface LoggerInterface {
1143
1069
  readonly emitter: EmitterInterface<LoggerEventMap>;
1144
1070
  readonly level: LogLevel;
1145
1071
  readonly name?: string;
1146
- /** Log at `debug` — dropped unless the logger's `level` is `debug`. */
1072
+ /** Logs at `debug` — dropped unless the logger's `level` is `debug`. */
1147
1073
  debug(message: string, data?: Record<string, unknown>): void;
1148
- /** Log at `info`. */
1074
+ /** Logs at `info`. */
1149
1075
  info(message: string, data?: Record<string, unknown>): void;
1150
- /** Log at `warn`. */
1076
+ /** Logs at `warn`. */
1151
1077
  warn(message: string, data?: Record<string, unknown>): void;
1152
- /** Log at `error`. */
1078
+ /** Logs at `error`. */
1153
1079
  error(message: string, data?: Record<string, unknown>): void;
1154
- /** The bounded tail of recent {@link LogRecord}s, oldest first (capped at `limit`). */
1080
+ /** Returns the bounded tail of recent {@link LogRecord}s, oldest first (capped at `limit`). */
1155
1081
  entries(): readonly LogRecord[];
1156
- /** Drop every retained record (does not touch listeners). */
1082
+ /** Drops every retained record (does not touch listeners). */
1157
1083
  clear(): void;
1158
- /** Tear down — clear retention and destroy the emitter. */
1084
+ /** Tears down — clears retention and destroys the emitter. */
1159
1085
  destroy(): void;
1160
1086
  }
1161
1087
 
1162
1088
  /**
1163
- * An event-free registry of named {@link Logger}s plus a convenience fan-out — the §9
1089
+ * Implements an event-free registry of named {@link Logger}s plus a convenience fan-out — the
1164
1090
  * manager over the logging layer (a registry, never observable itself; each {@link Logger}
1165
1091
  * owns its own `emitter`).
1166
1092
  *
1167
1093
  * @remarks
1168
- * - **Registry (§9).** Loggers live in an insertion-ordered `Map` keyed by `name`.
1094
+ * - **Registry.** Loggers live in an insertion-ordered `Map` keyed by `name`.
1169
1095
  * `register(name, options?)` mints a {@link Logger} named `name` — the manager's default
1170
1096
  * `level` / `sink` / `styler` / `theme` / `format` / `limit` / `silent` flow in unless
1171
- * `options` OVERRIDES them
1097
+ * `options` overrides them
1172
1098
  * (`name` is always the registry key, so any `options.name` is ignored) — stores it (a
1173
- * re-`register` of the same name OVERWRITES, last write wins), and returns it. `count` is
1099
+ * re-`register` of the same name overwrites, last write wins), and returns it. `count` is
1174
1100
  * the map size, `logger(name)` looks one up, `loggers()` lists them in insertion order.
1175
- * - **Removal (§9.2).** `remove()` clears ALL, `remove(name)` drops ONE (`true` if present),
1176
- * `remove(names)` drops a batch (`true` if any was removed).
1177
- * (Removal does NOT `destroy` the returned loggers a caller still holding one keeps using
1178
- * it; the manager simply stops tracking it.)
1101
+ * - **Removal.** `remove()` clears all, `remove(name)` drops one (`true` if present),
1102
+ * `remove(names)` drops a batch (`true` only when every name was present; an empty list
1103
+ * succeeds vacuously). Every listed name is attempted whatever the result.
1104
+ * (Removal does not `destroy` the returned loggers a caller still holding one keeps using
1105
+ * it; the manager stops tracking it.)
1179
1106
  * - **Fan-out.** `debug` / `info` / `warn` / `error(message, data?)` forward the one call to
1180
1107
  * every registered logger in insertion order; each gates / emits / writes per its own `level`
1181
1108
  * and `sink`. A formatter throw is a programmer error and propagates, stopping the remaining
@@ -1209,17 +1136,18 @@ export declare class LoggerManager implements LoggerManagerInterface {
1209
1136
  }
1210
1137
 
1211
1138
  /**
1212
- * An event-free registry of named {@link LoggerInterface}s plus a convenience fan-out — the
1213
- * §9 manager over the logging layer. It mints + stores loggers keyed by `name`, looks them
1214
- * up, removes them, and broadcasts a one-off log to EVERY registered logger.
1139
+ * Declares an event-free registry of named {@link LoggerInterface}s plus a convenience fan-out — the
1140
+ * manager over the logging layer. It mints + stores loggers keyed by `name`, looks them
1141
+ * up, removes them, and broadcasts a one-off log to every registered logger.
1215
1142
  *
1216
1143
  * @remarks
1217
- * - **Registry (§9).** `register(name, options?)` mints a {@link LoggerInterface} (named
1144
+ * - **Registry.** `register(name, options?)` mints a {@link LoggerInterface} (named
1218
1145
  * `name`, the manager's defaults flowing in unless `options` overrides them), stores it
1219
- * (a re-`register` of the same name OVERWRITES — last write wins), and returns it.
1146
+ * (a re-`register` of the same name overwrites — last write wins), and returns it.
1220
1147
  * `logger(name)` looks one up; `loggers()` lists them in insertion order; `count` is the size.
1221
- * - **Removal (§9.2).** `remove()` clears ALL, `remove(name)` drops ONE, `remove(names)` drops
1222
- * a batch (`true` when any was removed).
1148
+ * - **Removal.** `remove()` clears all, `remove(name)` drops one, `remove(names)` drops
1149
+ * a batch (`true` only when every name was present; an empty list succeeds vacuously).
1150
+ * Every listed name is attempted whatever the result.
1223
1151
  * - **Fan-out.** `debug` / `info` / `warn` / `error(message, data?)` forward the call to every
1224
1152
  * registered logger (each gates / emits / writes per its own `level` and `sink`).
1225
1153
  * - **Event-free.** No emitter, no events — each logger carries its own observability; the
@@ -1227,32 +1155,41 @@ export declare class LoggerManager implements LoggerManagerInterface {
1227
1155
  */
1228
1156
  export declare interface LoggerManagerInterface {
1229
1157
  readonly count: number;
1158
+ /**
1159
+ * Mints and stores a logger named `name`, the manager's defaults flowing in — a
1160
+ * re-register of the same name overwrites.
1161
+ */
1230
1162
  register(name: string, options?: LoggerOptions): LoggerInterface;
1163
+ /** Looks one registered logger up by name. */
1231
1164
  logger(name: string): LoggerInterface | undefined;
1165
+ /** Lists the registered loggers in insertion order. */
1232
1166
  loggers(): readonly LoggerInterface[];
1233
- /** Fan out a `debug` log to every registered logger. */
1167
+ /** Fans out a `debug` log to every registered logger. */
1234
1168
  debug(message: string, data?: Record<string, unknown>): void;
1235
- /** Fan out an `info` log to every registered logger. */
1169
+ /** Fans out an `info` log to every registered logger. */
1236
1170
  info(message: string, data?: Record<string, unknown>): void;
1237
- /** Fan out a `warn` log to every registered logger. */
1171
+ /** Fans out a `warn` log to every registered logger. */
1238
1172
  warn(message: string, data?: Record<string, unknown>): void;
1239
- /** Fan out an `error` log to every registered logger. */
1173
+ /** Fans out an `error` log to every registered logger. */
1240
1174
  error(message: string, data?: Record<string, unknown>): void;
1175
+ /**
1176
+ * Removes every registered logger with `remove()`, one with `remove(name)`, or a batch
1177
+ * with `remove(names)`.
1178
+ */
1241
1179
  remove(): void;
1242
1180
  remove(name: string): boolean;
1243
1181
  remove(names: readonly string[]): boolean;
1244
1182
  }
1245
1183
 
1246
1184
  /**
1247
- * Options for `createLoggerManager` / the {@link LoggerManagerInterface} constructor.
1185
+ * Configures the {@link import('./loggers/LoggerManager.js').LoggerManager} constructor — the
1186
+ * `level` / `sink` / `styler` / `theme` / `format` / `limit` / `silent` defaults flowed into every
1187
+ * logger it mints.
1248
1188
  *
1249
1189
  * @remarks
1250
- * The manager is an event-free registry (§9) — it carries NO emitter of its own (each
1251
- * registered {@link LoggerInterface} owns its observable `emitter`). These options supply
1252
- * the DEFAULTS flowed into every logger the manager mints, unless a per-`register` override
1253
- * wins: `level` (default threshold), `sink` (shared output target), `styler` (shared
1254
- * coloring), `theme` (semantic styles), `format` (line layout), `limit` (retention cap),
1255
- * and `silent`.
1190
+ * The manager is an event-free registry — it carries no emitter of its own (each
1191
+ * registered {@link LoggerInterface} owns its observable `emitter`). A per-`register`
1192
+ * override wins over any default supplied here.
1256
1193
  */
1257
1194
  export declare interface LoggerManagerOptions {
1258
1195
  readonly level?: LogLevel;
@@ -1265,13 +1202,15 @@ export declare interface LoggerManagerOptions {
1265
1202
  }
1266
1203
 
1267
1204
  /**
1268
- * Options for `createLogger` / the {@link LoggerInterface} constructor.
1205
+ * Configures the {@link import('./loggers/Logger.js').Logger} constructor — the `on` / `error`
1206
+ * emitter keys, the `level` threshold, the logger's `name`, the `sink` / `styler` / `theme` /
1207
+ * `format` line substrate, the retention `limit`, and the `silent` write switch.
1269
1208
  *
1270
1209
  * @remarks
1271
- * - `on` — the reserved {@link EmitterHooks} key (§8): initial listeners for the
1272
- * {@link LoggerEventMap}, wired at construction (e.g. `{ entry: (r) => sink2.write(...) }`).
1273
- * - `error` — the emitter's listener-error handler (§13); a listener throw routes here.
1274
- * - `level` — the severity THRESHOLD; records below it are dropped. Defaults to `info`.
1210
+ * - `on` — the reserved {@link EmitterHooks} key: initial listeners for the
1211
+ * {@link LoggerEventMap}, wired at construction (for example `{ entry: (r) => sink2.write(...) }`).
1212
+ * - `error` — the emitter's listener-error handler; a listener throw routes here.
1213
+ * - `level` — the severity threshold; records below it are dropped. Defaults to `info`.
1275
1214
  * - `name` — the logger's name, stamped onto every {@link LogRecord} (`record.name`) and
1276
1215
  * shown in the formatted line. A manager registers each logger under its name.
1277
1216
  * - `sink` — where formatted lines are written; defaults to
@@ -1284,7 +1223,7 @@ export declare interface LoggerManagerOptions {
1284
1223
  * {@link import('./helpers.js').formatRecord}.
1285
1224
  * - `limit` — the bounded retention cap: at most this many recent records are kept
1286
1225
  * (oldest dropped first). Defaults to {@link DEFAULT_LOG_LIMIT}; never unbounded.
1287
- * - `silent` — when `true`, suppresses the SINK WRITE only; `entry` still fires and the
1226
+ * - `silent` — when `true`, suppresses the sink write only; `entry` still fires and the
1288
1227
  * record is still retained. Defaults to `false`.
1289
1228
  */
1290
1229
  export declare interface LoggerOptions {
@@ -1301,21 +1240,21 @@ export declare interface LoggerOptions {
1301
1240
  }
1302
1241
 
1303
1242
  /**
1304
- * The severity level of a {@link LogRecord} — one coherent, ascending-severity scale.
1243
+ * Names the severity level of a {@link LogRecord} — one coherent, ascending scale, `debug` <
1244
+ * `info` < `warn` < `error`, that a {@link LoggerInterface} gates by threshold.
1305
1245
  *
1306
1246
  * @remarks
1307
- * Ordered least-to-most severe: `debug` < `info` < `warn` < `error`. A {@link LoggerInterface}
1308
- * gates by THRESHOLD a record at or above the logger's `level` is kept (and written),
1309
- * one below it is dropped (see {@link LEVEL_SEVERITY} for the numeric order). A level is a
1310
- * level — its visual treatment (color) is a separate styling concern, NEVER a pseudo-level
1247
+ * A record at or above the logger's `level` is kept (and written), one below it is
1248
+ * dropped (see {@link LEVEL_SEVERITY} for the numeric order). A level is a
1249
+ * level its visual treatment (color) is a separate styling concern, never a pseudo-level
1311
1250
  * like `success` / `ready`.
1312
1251
  */
1313
1252
  export declare type LogLevel = 'debug' | 'info' | 'warn' | 'error';
1314
1253
 
1315
1254
  /**
1316
- * One immutable, serializable log entry the universal record the whole logging system
1317
- * carries. A {@link LoggerInterface} builds one per call, freezes it, retains a bounded
1318
- * tail of them, and emits it on `entry`; every sink / transport consumes this exact shape.
1255
+ * Represents one immutable, serializable log entry. A {@link LoggerInterface} builds one per call,
1256
+ * freezes it, retains a bounded tail of them, and emits it on `entry`; every sink / transport
1257
+ * consumes this exact shape.
1319
1258
  *
1320
1259
  * @remarks
1321
1260
  * - `level` — the record's {@link LogLevel}.
@@ -1325,9 +1264,9 @@ export declare type LogLevel = 'debug' | 'info' | 'warn' | 'error';
1325
1264
  * - `name` — the originating logger's `name`, when it has one (a manager-registered logger
1326
1265
  * is keyed by name; an anonymous logger omits it).
1327
1266
  * - `data` — optional structured context (a flat `Record<string, unknown>`), absent when
1328
- * no context was supplied. The top-level object is a FROZEN COPY taken at log time (a
1267
+ * no context was supplied. The top-level object is a frozen copy taken at log time (a
1329
1268
  * later mutation of the caller's original object never reaches the retained record);
1330
- * nested values remain BY REFERENCE (only the top level is copied + frozen).
1269
+ * nested values remain by reference (only the top level is copied + frozen).
1331
1270
  * - The value is frozen at construction — a consumer reads it, never mutates it.
1332
1271
  */
1333
1272
  export declare interface LogRecord {
@@ -1339,17 +1278,17 @@ export declare interface LogRecord {
1339
1278
  }
1340
1279
 
1341
1280
  /**
1342
- * Whether a record at `level` passes a logger gated at `threshold` — i.e. its severity is
1343
- * at or above the threshold's.
1281
+ * Checks whether a record at `level` passes a logger gated at `threshold` — that is, its severity
1282
+ * is at or above the threshold's.
1344
1283
  *
1345
1284
  * @remarks
1346
- * The level gate (AGENTS §5 — the comparison lives here, not inlined in the logger). Reads
1285
+ * The level gate (the comparison lives here, not inlined in the logger). Reads
1347
1286
  * the ascending {@link LEVEL_SEVERITY} order: `meetsLevel('warn', 'error')` is `true`
1348
1287
  * (error ≥ warn), `meetsLevel('warn', 'info')` is `false` (info < warn).
1349
1288
  *
1350
1289
  * @param threshold - The logger's configured minimum {@link LogLevel}
1351
1290
  * @param level - The record's {@link LogLevel}
1352
- * @returns `true` when `level` is at least as severe as `threshold`
1291
+ * @returns True if `level` is at least as severe as `threshold`; false otherwise
1353
1292
  *
1354
1293
  * @example
1355
1294
  * ```ts
@@ -1360,12 +1299,12 @@ export declare interface LogRecord {
1360
1299
  export declare function meetsLevel(threshold: LogLevel, level: LogLevel): boolean;
1361
1300
 
1362
1301
  /**
1363
- * Color `text` through `styler`, or return it verbatim when `styler` is `undefined` the
1364
- * single optional-styling primitive every renderer applies to its border / title / connector
1365
- * glyphs (AGENTS §5 the ONE styler seam, shared, never re-hand-rolled per renderer).
1302
+ * Colors `text` through `styler` and an optional by-value {@link Style}, or returns it verbatim
1303
+ * when `styler` is `undefined` — the single optional-styling primitive every renderer applies to
1304
+ * its border / title / connector glyphs.
1366
1305
  *
1367
1306
  * @remarks
1368
- * The renderers all take an OPTIONAL `styler`: present ⇒ glyphs are colored, absent ⇒ plain.
1307
+ * The renderers all take an optional `styler`: present ⇒ glyphs are colored, absent ⇒ plain.
1369
1308
  * Folding that `styler === undefined ? text : styler(text)` ternary into one exported helper
1370
1309
  * keeps the renderers terse and the styling decision in one tested place. A disabled styler
1371
1310
  * (`enabled: false`) is still a styler — it returns its text verbatim — so passing one paints
@@ -1379,31 +1318,34 @@ export declare function meetsLevel(threshold: LogLevel, level: LogLevel): boolea
1379
1318
  export declare function paint(styler: StylerInterface | undefined, text: string, style?: Style): string;
1380
1319
 
1381
1320
  /**
1382
- * An update-driven, observable progress bar (AGENTS §13) — {@link update} recomputes the bar via
1383
- * {@link renderBar}, writes `\r` + bar to its {@link SinkInterface}, and emits the `{ current, total }`
1384
- * on `update`. The leading `\r` is what an overwrite-capable sink (the C-g TTY sink) redraws on; a
1385
- * plain sink (C-f) degrades to a fresh, non-overwriting line — the line-OVERWRITE is the SINK's job.
1386
- * UNIVERSAL — the one {@link StylerInterface} + the one {@link SinkInterface}, no `node:*`, no
1387
- * `process.stdout`. NO self-timer (unlike {@link import('./Spinner.js').Spinner}) — the caller drives it.
1321
+ * Implements an update-driven, observable progress bar — {@link update} recomputes the bar through
1322
+ * {@link renderBar}, writes `\r` + bar to its {@link SinkInterface}, and emits the `{ current,
1323
+ * total }` on `update`. No self-timer, unlike {@link import('./Spinner.js').Spinner} the caller
1324
+ * drives it.
1388
1325
  *
1389
1326
  * @remarks
1327
+ * The leading `\r` is what an overwrite-capable sink (the TTY sink) redraws on; a plain sink
1328
+ * degrades to a fresh, non-overwriting line — the line-overwrite is the sink's job. Universal —
1329
+ * the one {@link StylerInterface} + the one {@link SinkInterface}, no `node:*`, no
1330
+ * `process.stdout`.
1331
+ *
1390
1332
  * - **Update-driven.** Each {@link update} clamps `current` to `[0, total]`, renders the bar (filled
1391
- * to `current / total`, with the trailing `percent (current/total)` + message) via {@link renderBar},
1333
+ * to `current / total`, with the trailing `percent (current/total)` + message) through {@link renderBar},
1392
1334
  * emits `update`, and writes `'\r' + bar`. Progress advances only when the caller reports it.
1393
- * - **Outcome lines.** {@link complete} renders a FULL bar (`current = total`) + message, terminated by
1394
- * a newline, emits a final `update` then `complete`, and marks `completed`. {@link failure} renders the
1395
- * bar at its CURRENT fill + message + newline and routes to the sink's error stream (no `complete` —
1335
+ * - **Outcome lines.** {@link succeed} renders a full bar (`current = total`) + message, terminated by
1336
+ * a newline, emits a final `update` then `succeed`, and marks `succeeded`. {@link fail} renders the
1337
+ * bar at its current fill + message + newline and routes to the sink's error stream (no `succeed` —
1396
1338
  * the work did not finish). Both are terminal: a later {@link update} is ignored once `active` is false.
1397
- * - **Bounded.** `current` is always clamped to `[0, total]`; {@link completed} reports whether
1398
- * {@link complete} has run; {@link active} is `true` until a {@link complete} / {@link failure}.
1399
- * - **Lifecycle (§10).** {@link destroy} destroys the emitter (there is no timer to clear).
1339
+ * - **Bounded.** `current` is always clamped to `[0, total]`; {@link succeeded} reports whether
1340
+ * {@link succeed} has run; {@link active} is `true` until a {@link succeed} / {@link fail}.
1341
+ * - **Lifecycle.** {@link destroy} destroys the emitter (there is no timer to clear).
1400
1342
  *
1401
1343
  * @example
1402
1344
  * ```ts
1403
1345
  * const progress = new Progress({ total: 100, message: 'downloading' })
1404
1346
  * progress.update(40) // ████████████░░░░░░░░░░░░░░░░░░ 40% (40/100) downloading
1405
1347
  * progress.update(80, 'almost there')
1406
- * progress.complete('done') // a full bar, committed with a newline
1348
+ * progress.succeed('done') // a full bar, committed with a newline
1407
1349
  * ```
1408
1350
  */
1409
1351
  export declare class Progress implements ProgressInterface {
@@ -1411,125 +1353,102 @@ export declare class Progress implements ProgressInterface {
1411
1353
  constructor(options: ProgressOptions);
1412
1354
  get emitter(): EmitterInterface<ProgressEventMap>;
1413
1355
  get active(): boolean;
1414
- get completed(): boolean;
1356
+ get succeeded(): boolean;
1415
1357
  get current(): number;
1416
1358
  get total(): number;
1417
1359
  update(current: number, message?: string): void;
1418
- complete(message?: string): void;
1419
- failure(message?: string): void;
1360
+ succeed(message?: string): void;
1361
+ fail(message?: string): void;
1420
1362
  destroy(): void;
1421
1363
  }
1422
1364
 
1423
1365
  /**
1424
- * Options for the pure {@link import('./helpers.js').renderBar} renderera determinate progress
1425
- * bar string (`█████░░░░░ 50% (5/10)`), width-aware and styler-optional.
1366
+ * Declares the observable events a {@link ProgressInterface} emits`update(progress)` per
1367
+ * report, plus a `succeed` signal on a successful finish.
1426
1368
  *
1427
1369
  * @remarks
1428
- * - `current` / `total` the filled fraction is `current / total`, clamped to `[0, total]` (a
1429
- * `current` past `total` renders a full bar, a negative one an empty bar) — so a caller's overrun
1430
- * never produces an over-long bar. A `total` of `0` (or below) renders a full bar (nothing to do).
1431
- * - `width` — the visible cell count of the bar TRACK (the glyph run between no brackets); defaults
1432
- * to {@link DEFAULT_BAR_WIDTH}. The percentage + `(current/total)` count follow the track.
1433
- * - `fill` — the filled-cell glyph; defaults to {@link BAR_FILL} (`█`). `empty` — the empty-cell
1434
- * glyph; defaults to {@link BAR_EMPTY} (`░`). Sized in VISIBLE columns ({@link
1435
- * import('./helpers.js').width}), so a multi-cell glyph still yields a `width`-wide track.
1436
- * - `styler` — colors the FILLED run when supplied (the empty run + the trailing label stay plain);
1437
- * the layout is identical with or without color, since the track is measured on visible width.
1438
- * - `style` — an optional by-value style rendered through `styler` for the filled run.
1439
- */
1440
- export declare interface ProgressBarOptions {
1441
- readonly current: number;
1442
- readonly total: number;
1443
- readonly width?: number;
1444
- readonly fill?: string;
1445
- readonly empty?: string;
1446
- readonly styler?: StylerInterface;
1447
- readonly style?: Style;
1448
- }
1449
-
1450
- /**
1451
- * The observable events a {@link ProgressInterface} emits (AGENTS §13).
1452
- *
1453
- * @remarks
1454
- * - `update` — the core event: fires on every `update(current)` (and on `complete` / `failure`),
1370
+ * - `update` — fires on every `update(current)` (and on `succeed` / `fail`),
1455
1371
  * carrying the `{ current, total }` progress (the clamped `current`). The hook a non-sink consumer
1456
1372
  * rides to observe progress without a terminal.
1457
- * - `complete` — the terminal signal: fires once from `complete()` (a successful finish), a pure
1458
- * signal (empty tuple) so a consumer can observe the bar reaching its end. (`failure()` emits a final
1459
- * `update` and routes its line to the error stream, but is NOT a `complete` — completion means the
1460
- * work finished successfully.)
1373
+ * - `succeed` — the terminal signal: fires once from `succeed()` (a successful finish), a pure
1374
+ * signal (empty tuple) so a consumer can observe the bar reaching its end. (`fail()` emits a final
1375
+ * `update` and routes its line to the error stream, but is not a `succeed` — the bar's positive
1376
+ * outcome is the same word the spinner and the reporter use.)
1461
1377
  *
1462
- * Listener isolation is the emitter's (§13). Declared as a `type` alias (not
1463
- * `interface extends EventMap`, §4.5): a type-literal satisfies the `EventMap` constraint
1378
+ * Listener isolation is the emitter's. Declared as a `type` alias (not
1379
+ * `interface extends EventMap`): a type-literal satisfies the `EventMap` constraint
1464
1380
  * structurally, whereas an interface lacks the index signature.
1465
1381
  */
1466
1382
  export declare type ProgressEventMap = {
1467
- /** Progress advanced — the clamped `{ current, total }` (fires on `update` and on `complete` / `failure`). */
1468
- readonly update: readonly [progress: {
1469
- readonly current: number;
1470
- readonly total: number;
1471
- }];
1472
- /** The bar reached its end via `complete()` (a successful finish). */
1473
- readonly complete: readonly [];
1383
+ /** Reports progress advancing — the clamped `{ current, total }` (fires on `update` and on `succeed` / `fail`). */
1384
+ readonly update: readonly [progress: ProgressReport];
1385
+ /** Fires after the bar reached its end through `succeed()` (a successful finish). */
1386
+ readonly succeed: readonly [];
1474
1387
  };
1475
1388
 
1476
1389
  /**
1477
- * An update-driven, observable progress bar (AGENTS §13) — `update(current)` recomputes the bar via
1478
- * {@link import('./helpers.js').renderBar}, writes `\r` + bar to its {@link SinkInterface}, and emits
1479
- * the `{ current, total }` on `update`. The line-OVERWRITE is the sink's job (a TTY sink overwrites
1480
- * on the `\r`; a plain sink degrades to a fresh line). NO self-timer — the caller drives it.
1390
+ * Declares an update-driven, observable progress bar — `update(current)` recomputes the bar through
1391
+ * {@link import('./helpers.js').renderBar}, writes `\r` + bar to its {@link SinkInterface}, and
1392
+ * emits the `{ current, total }` on `update`. The line-overwrite is the sink's job (a TTY sink
1393
+ * overwrites on the `\r`; a plain sink degrades to a fresh line). No self-timer — the caller drives
1394
+ * it.
1481
1395
  *
1482
1396
  * @remarks
1483
1397
  * - **Update-driven.** Each `update(current, message?)` clamps `current` to `[0, total]`, renders
1484
1398
  * the bar (filled to `current / total`, with the trailing `percent (current/total)` + message),
1485
1399
  * emits `update`, and writes `'\r' + bar`. There is no internal timer (unlike {@link
1486
1400
  * SpinnerInterface}) — progress advances only when the caller reports it.
1487
- * - **Outcome lines.** `complete(message?)` renders a FULL bar (`current = total`) + message,
1488
- * terminated by a newline, emits a final `update` then `complete`, and marks `completed`.
1489
- * `failure(message?)` renders the bar at its CURRENT fill + message + newline and routes to the sink's
1490
- * error stream (no `complete` — the work did not finish). Both are terminal: a later `update` after
1491
- * a `complete` / `failure` is ignored (`active` is `false`).
1492
- * - **Bounded.** `current` is always clamped to `[0, total]`; `completed` reports whether
1493
- * `complete()` has run; `active` is `true` until a `complete` / `failure`.
1401
+ * - **Outcome lines.** `succeed(message?)` renders a full bar (`current = total`) + message,
1402
+ * terminated by a newline, emits a final `update` then `succeed`, and marks `succeeded`.
1403
+ * `fail(message?)` renders the bar at its current fill + message + newline and routes to the sink's
1404
+ * error stream (no `succeed` — the work did not finish). Both are terminal: a later `update` after
1405
+ * a `succeed` / `fail` is ignored (`active` is `false`).
1406
+ * - **Bounded.** `current` is always clamped to `[0, total]`; `succeeded` reports whether
1407
+ * `succeed()` has run; `active` is `true` until a `succeed` / `fail`.
1494
1408
  */
1495
1409
  export declare interface ProgressInterface {
1496
1410
  readonly emitter: EmitterInterface<ProgressEventMap>;
1497
- /** Whether the bar is still advancing (before any `complete()` / `failure()`). */
1411
+ /** Reports whether the bar is still advancing (before any `succeed()` / `fail()`). */
1498
1412
  readonly active: boolean;
1499
- /** Whether `complete()` has run (the bar finished successfully). */
1500
- readonly completed: boolean;
1501
- /** The current value, clamped to `[0, total]`. */
1413
+ /** Reports whether `succeed()` has run (the bar finished successfully). */
1414
+ readonly succeeded: boolean;
1415
+ /** Holds the current value, clamped to `[0, total]`. */
1502
1416
  readonly current: number;
1503
- /** The target value the bar fills toward. */
1417
+ /** Holds the target value the bar fills toward. */
1504
1418
  readonly total: number;
1505
- /** Report progress: clamp `current`, re-render the bar, emit `update`, write `\r` + bar. Ignored once terminal. */
1419
+ /**
1420
+ * Reports progress: clamps `current`, re-renders the bar, emits `update`, writes `\r` + bar.
1421
+ * Ignored after a terminal `succeed` or `fail`.
1422
+ */
1506
1423
  update(current: number, message?: string): void;
1507
- /** Finish successfully — render a FULL bar + newline, emit a final `update` then `complete`. */
1508
- complete(message?: string): void;
1509
- /** Finish unsuccessfully — render the bar at its current fill + newline to the error stream (no `complete`). */
1510
- failure(message?: string): void;
1511
- /** Tear down — destroy the emitter. */
1424
+ /** Finishes successfully — renders a full bar + newline, emits a final `update` then `succeed`. */
1425
+ succeed(message?: string): void;
1426
+ /** Finishes unsuccessfully — renders the bar at its current fill + newline to the error stream (no `succeed`). */
1427
+ fail(message?: string): void;
1428
+ /** Tears down — destroys the emitter. */
1512
1429
  destroy(): void;
1513
1430
  }
1514
1431
 
1515
1432
  /**
1516
- * Options for `createProgress` / the {@link ProgressInterface} constructor.
1433
+ * Configures the {@link import('./Progress.js').Progress} constructor — the `on` / `error` emitter
1434
+ * keys, the required `total`, the `message` shown, the bar's `width` / `fill` / `empty` glyphs, and
1435
+ * the `sink` / `styler` / `theme` line substrate.
1517
1436
  *
1518
1437
  * @remarks
1519
- * - `on` — the reserved {@link EmitterHooks} key (§8): initial listeners for the
1438
+ * - `on` — the reserved {@link EmitterHooks} key: initial listeners for the
1520
1439
  * {@link ProgressEventMap}, wired at construction.
1521
- * - `error` — the emitter's listener-error handler (§13); a listener throw routes here.
1522
- * - `total` — the value `current` advances toward (the `100%` point); the only REQUIRED option.
1440
+ * - `error` — the emitter's listener-error handler; a listener throw routes here.
1441
+ * - `total` — the value `current` advances toward (the `100%` point); the only required option.
1523
1442
  * - `message` — text shown after the bar; defaults to `''`. Overridden per-`update` and by a
1524
- * `complete` / `failure` argument.
1443
+ * `succeed` / `fail` argument.
1525
1444
  * - `width` — the bar track's visible cell count, handed to {@link import('./helpers.js').renderBar};
1526
1445
  * defaults to {@link DEFAULT_BAR_WIDTH}.
1527
1446
  * - `fill` / `empty` — the filled and empty track glyphs handed to
1528
1447
  * {@link import('./helpers.js').renderBar}; default to {@link BAR_FILL} / {@link BAR_EMPTY}.
1529
1448
  * - `sink` — where each `\r` + bar line is written; defaults to
1530
- * {@link import('./factories.js').createConsoleSink}. A TTY sink (C-g) overwrites on the `\r`.
1449
+ * {@link import('./factories.js').createConsoleSink}. A TTY sink overwrites on the `\r`.
1531
1450
  * - `styler` — the {@link StylerInterface} the filled run is colored through; defaults to
1532
- * {@link import('./factories.js').createStyler} (ANSI). The ONE styler the whole system shares.
1451
+ * {@link import('./factories.js').createStyler} (ANSI). The one styler the whole system shares.
1533
1452
  * - `theme` — the {@link Theme} supplying the filled run's accent role; defaults to
1534
1453
  * {@link DEFAULT_THEME}.
1535
1454
  */
@@ -1547,26 +1466,44 @@ export declare interface ProgressOptions {
1547
1466
  }
1548
1467
 
1549
1468
  /**
1550
- * Render a determinate progress bar stringa filled / empty glyph track followed by the percentage
1551
- * and the `(current/total)` count (`█████░░░░░ 50% (5/10)`). Pure: same {@link ProgressBarOptions}
1552
- * same string. The animation-layer sibling of the C-c `render*` renderers (box / table / tree /
1553
- * separator), shared so a {@link import('./types.js').ProgressInterface} and any direct caller draw
1554
- * the ONE bar never a second, hand-rolled one (AGENTS §5; scsr shipped three).
1469
+ * Reports one advance of a {@link ProgressInterface} the clamped payload carried by the `update`
1470
+ * event of {@link ProgressEventMap}.
1471
+ *
1472
+ * @remarks
1473
+ * `current` is always the value after clamping into `[0, total]`, so a listener never sees an
1474
+ * overrun or a negative. `total` is the bar's fixed target, repeated on every report so a listener
1475
+ * needs no reference to the bar itself. The same record is emitted from `update`, `succeed`, and
1476
+ * `fail`.
1477
+ */
1478
+ export declare interface ProgressReport {
1479
+ readonly current: number;
1480
+ readonly total: number;
1481
+ }
1482
+
1483
+ /**
1484
+ * Renders a determinate progress bar string — a filled / empty glyph track followed by the percentage
1485
+ * and the `(current/total)` count (`█████░░░░░ 50% (5/10)`). Pure and width-aware: same
1486
+ * {@link BarOptions} → same string.
1555
1487
  *
1556
1488
  * @remarks
1489
+ * It is the animation-layer sibling of the `render*` renderers (box / table / tree / separator),
1490
+ * shared so a {@link import('./types.js').ProgressInterface} and any direct caller draw the one
1491
+ * bar — never a second,
1492
+ * hand-rolled one.
1493
+ *
1557
1494
  * - **Fill fraction, clamped.** The filled cell count is `round((current / total) · width)` with
1558
1495
  * `current` clamped to `[0, total]`, so an overrun never over-fills and a negative never under-fills.
1559
- * A `total <= 0` renders a FULL track (there is nothing to fill toward — the work is trivially done).
1496
+ * A `total <= 0` renders a full track (there is nothing to fill toward — the work is trivially done).
1560
1497
  * - **Width-aware track.** The filled run is `fill` tiled to the filled cell count and the empty run
1561
- * `empty` tiled to the remainder, each via {@link repeatTo} — so the TRACK is exactly `width` VISIBLE
1498
+ * `empty` tiled to the remainder, each through {@link repeatTo} — so the track is exactly `width` visible
1562
1499
  * columns even for a multi-cell glyph (its escape codes / extra cells never break the width).
1563
- * - **Styling.** `options.styler` colors the FILLED run only (the empty run + the trailing
1500
+ * - **Styling.** `options.styler` colors the filled run only (the empty run + the trailing
1564
1501
  * `percent (count)` label stay plain), through {@link paint}; the layout is identical with or
1565
1502
  * without color, since the track is measured on visible width.
1566
- * - **Label.** The percentage is the rounded `current / total` (e.g. `50%`); the count is the CLAMPED
1503
+ * - **Label.** The percentage is the rounded `current / total` (for example `50%`); the count is the clamped
1567
1504
  * `current` over `total` (`(5/10)`), a single space separating the track, the percent, and the count.
1568
1505
  *
1569
- * @param options - See {@link ProgressBarOptions}
1506
+ * @param options - See {@link BarOptions}
1570
1507
  * @returns The rendered bar line (no trailing newline)
1571
1508
  *
1572
1509
  * @example
@@ -1575,22 +1512,22 @@ export declare interface ProgressOptions {
1575
1512
  * renderBar({ current: 10, total: 10, width: 4 }) // '████ 100% (10/10)'
1576
1513
  * ```
1577
1514
  */
1578
- export declare function renderBar(options: ProgressBarOptions): string;
1515
+ export declare function renderBar(options: BarOptions): string;
1579
1516
 
1580
1517
  /**
1581
- * Render `content` framed in box-drawing characters, optionally captioned, width-aware so
1518
+ * Renders `content` framed in box-drawing characters, optionally captioned, width-aware so
1582
1519
  * styled content stays aligned inside the frame. Pure: same {@link BoxOptions} → same string.
1583
1520
  *
1584
1521
  * @remarks
1585
- * - **Lines.** `content` is split on `\n` OR `\r\n`, so caller text written on Windows frames
1586
- * exactly as the same text written on POSIX; a LONE `\r` is kept inside its line (it is a
1522
+ * - **Lines.** `content` is split on `\n` or `\r\n`, so caller text written on Windows frames
1523
+ * exactly as the same text written on POSIX; a lone `\r` is kept inside its line (it is a
1587
1524
  * cursor control — the animation frame prefix — not a line separator). Each line is padded
1588
1525
  * (left-aligned) to the inner
1589
- * width by {@link align} — measured on VISIBLE width, so a styled line never breaks the
1526
+ * width by {@link align} — measured on visible width, so a styled line never breaks the
1590
1527
  * right edge. The inner width is the widest line's visible width (or `width − borders −
1591
1528
  * 2·padding` when an explicit `width` is given and is wider), plus `padding` blank cells
1592
1529
  * inside each {@link BorderChars.vertical} edge.
1593
- * - **Title.** An optional `title` is embedded in the TOP border (` title `), the remaining
1530
+ * - **Title.** An optional `title` is embedded in the top border (` title `), the remaining
1594
1531
  * top edge drawn as fill; a title wider than the inner width widens the box to fit it.
1595
1532
  * - **Border + styling.** The {@link BorderStyle} (`options.border`, default
1596
1533
  * {@link DEFAULT_BORDER}) selects the glyph set from {@link BORDER_CHARS}; `options.styler`
@@ -1604,21 +1541,21 @@ export declare function renderBar(options: ProgressBarOptions): string;
1604
1541
  export declare function renderBox(options: BoxOptions): string;
1605
1542
 
1606
1543
  /**
1607
- * A swappable style renderer — the seam that turns style DATA into output for ONE
1544
+ * Declares a swappable style renderer — the seam that turns style data into output for one
1608
1545
  * target. The cross-environment default is the ANSI renderer (SGR escape codes); a
1609
- * browser `%c` / CSS renderer implements the SAME contract over the SAME {@link Style}
1610
- * model, so it drops in without touching the style data (the C-f browser branch).
1546
+ * browser `%c` / CSS renderer implements the same contract over the same {@link Style}
1547
+ * model, so it drops in without touching the style data (the browser branch).
1611
1548
  */
1612
1549
  export declare interface RendererInterface {
1613
1550
  /**
1614
- * Render `text` wrapped in the target codes for `style`. The EMPTY style (no colors,
1551
+ * Renders `text` wrapped in the target codes for `style`. The empty style (no colors,
1615
1552
  * no attributes) and the empty string both return `text` unchanged — no wrapping.
1616
1553
  */
1617
1554
  render(style: Style, text: string): string;
1618
1555
  }
1619
1556
 
1620
1557
  /**
1621
- * Render a horizontal rule — an optional centered title embedded in a line of fill characters,
1558
+ * Renders a horizontal rule — an optional centered title embedded in a line of fill characters,
1622
1559
  * to a fixed visible width. Pure: same {@link SeparatorOptions} → same string.
1623
1560
  *
1624
1561
  * @remarks
@@ -1627,10 +1564,10 @@ export declare interface RendererInterface {
1627
1564
  * side) in the line, splitting the remaining fill between the two sides (the extra column,
1628
1565
  * when the remainder is odd, goes to the right). The visible width stays exactly `width`,
1629
1566
  * even when the title is styled (the title's escape codes don't count toward the budget) —
1630
- * a title at least as wide as `width` yields just the gapped title (no fill).
1567
+ * a title at least as wide as `width` yields only the gapped title (no fill).
1631
1568
  * - **Styling.** When `options.styler` is given, the fill runs (and the embedded title) are
1632
1569
  * colored through it; the layout is identical with or without color, since width is measured
1633
- * on the visible content (AGENTS — width-aware via {@link width}).
1570
+ * on the visible content (width-aware through {@link width}).
1634
1571
  *
1635
1572
  * @param options - See {@link SeparatorOptions}
1636
1573
  * @returns The rule line (no trailing newline)
@@ -1644,17 +1581,17 @@ export declare interface RendererInterface {
1644
1581
  export declare function renderSeparator(options: SeparatorOptions): string;
1645
1582
 
1646
1583
  /**
1647
- * Render a bordered grid of `columns` + `rows` with per-column alignment and width-aware
1584
+ * Renders a bordered grid of `columns` + `rows` with per-column alignment and width-aware
1648
1585
  * column sizing. Pure: same {@link TableOptions} → same string.
1649
1586
  *
1650
1587
  * @remarks
1651
- * - **Column sizing — visible width.** Each column is sized to the widest VISIBLE width
1588
+ * - **Column sizing — visible width.** Each column is sized to the widest visible width
1652
1589
  * ({@link width}) among its header label and its cells, so an already-styled cell never
1653
1590
  * breaks the column (its escape codes don't count toward the width).
1654
1591
  * - **Ragged rows.** A row shorter than the column count is padded with empty cells; a longer
1655
1592
  * row is truncated to the column count — a ragged input never throws.
1656
1593
  * - **Alignment.** Each cell is positioned by its column's {@link ColumnSpec.align} (default
1657
- * {@link DEFAULT_ALIGN}) via {@link align}.
1594
+ * {@link DEFAULT_ALIGN}) through {@link align}.
1658
1595
  * - **Frame.** The {@link BorderStyle} (`options.border`, default {@link DEFAULT_BORDER})
1659
1596
  * draws the outer frame, the header rule (a `teeRight … cross … teeLeft` line), and the
1660
1597
  * `vertical` column separators; `options.styler` colors the frame + header labels when
@@ -1667,8 +1604,8 @@ export declare function renderSeparator(options: SeparatorOptions): string;
1667
1604
  export declare function renderTable(options: TableOptions): string;
1668
1605
 
1669
1606
  /**
1670
- * Render a nested {@link TreeNode} tree with box-drawing connectors. Pure: same
1671
- * {@link TreeOptions} → same string.
1607
+ * Renders a nested {@link TreeNode} tree whose connectors derive from the chosen `border` set.
1608
+ * Pure: same {@link TreeOptions} → same string.
1672
1609
  *
1673
1610
  * @remarks
1674
1611
  * The `root` label is the unindented first line; its descendants are drawn beneath it with
@@ -1692,13 +1629,17 @@ export declare function renderTable(options: TableOptions): string;
1692
1629
  export declare function renderTree(options: TreeOptions): string;
1693
1630
 
1694
1631
  /**
1695
- * Render the connector-prefixed lines for a {@link TreeNode} list — the recursive core
1696
- * behind {@link renderTree}. Each child is drawn as `prefix` + its connector (`├─ ` for
1697
- * any but the last, `└─ ` for the last) + its label, with its own descendants recursed
1698
- * beneath under the carried guide (`│ ` under a non-last node, ` ` under the last).
1632
+ * Renders the connector-prefixed lines for a {@link TreeNode} list — the recursive core behind
1633
+ * {@link renderTree}, whose third options argument requires `border` and groups the optional
1634
+ * `styler` and `style`.
1699
1635
  *
1700
1636
  * @remarks
1701
- * A centralized, exported recursion branch (AGENTS §5) so it is directly testable and
1637
+ * Each child is drawn as `prefix` + its connector (`├─ ` for any but the last, `└─ ` for the
1638
+ * last) + its label, with its own descendants recursed beneath under the carried guide (`│ `
1639
+ * under a non-last node, ` ` under the last).
1640
+ *
1641
+ * @remarks
1642
+ * A centralized, exported recursion branch so it is directly testable and
1702
1643
  * reusable outside {@link renderTree}'s top-level `root.label` framing.
1703
1644
  *
1704
1645
  * @param nodes - The sibling {@link TreeNode}s to render at this depth
@@ -1716,17 +1657,17 @@ export declare function renderTree(options: TreeOptions): string;
1716
1657
  export declare function renderTreeChildren(nodes: readonly TreeNode[], prefix: string, options: Required<Pick<TreeOptions, 'border'>> & Pick<TreeOptions, 'style' | 'styler'>): readonly string[];
1717
1658
 
1718
1659
  /**
1719
- * Repeat `unit` until it fills exactly `count` VISIBLE columns, trimming a trailing partial
1660
+ * Repeats `unit` until it fills exactly `columns` visible columns, trimming a trailing partial
1720
1661
  * unit so the run is never over-wide — the fill primitive the separator + box edges draw with.
1721
1662
  *
1722
1663
  * @remarks
1723
1664
  * Counts in code points ({@link width}-consistent), so a multi-cell or astral `unit` is laid
1724
- * down whole and the result is sliced to exactly `count` visible columns. `count <= 0` (or an
1665
+ * down whole and the result is sliced to exactly `columns` visible columns. `columns <= 0` (or an
1725
1666
  * empty / zero-width `unit`) yields `''`.
1726
1667
  *
1727
1668
  * @param unit - The (possibly multi-character) fill unit
1728
- * @param count - The visible column count to fill
1729
- * @returns `unit` tiled to exactly `count` visible columns
1669
+ * @param columns - The visible column count to fill
1670
+ * @returns `unit` tiled to exactly `columns` visible columns
1730
1671
  *
1731
1672
  * @example
1732
1673
  * ```ts
@@ -1734,27 +1675,27 @@ export declare function renderTreeChildren(nodes: readonly TreeNode[], prefix: s
1734
1675
  * repeatTo('=-', 5) // '=-=-='
1735
1676
  * ```
1736
1677
  */
1737
- export declare function repeatTo(unit: string, count: number): string;
1678
+ export declare function repeatTo(unit: string, columns: number): string;
1738
1679
 
1739
1680
  /**
1740
- * A lean, event-free narrative reporter (AGENTS §13) — the composable verb set for human /
1741
- * build-run output. Each verb FORMATS its line through the shared {@link StylerInterface} and
1681
+ * Implements a lean, event-free narrative reporter — the composable verb set for human /
1682
+ * build-run output. Each verb formats its line through the shared {@link StylerInterface} and
1742
1683
  * the pure layout renderers ({@link renderSeparator} / {@link renderBox} / {@link renderTable}
1743
- * / {@link renderTree}) and WRITES it to a {@link SinkInterface} — the SAME styler + sink
1684
+ * / {@link renderTree}) and writes it to a {@link SinkInterface} — the same styler + sink
1744
1685
  * substrate the logger uses, never a second colorizer.
1745
1686
  *
1746
1687
  * @remarks
1747
- * - **A SMALL set, not a grab-bag.** `section` / `step` / `timing` / `status` / `table` /
1688
+ * - **A small set, not a grab-bag.** `section` / `step` / `timing` / `status` / `table` /
1748
1689
  * `tree` / `box` / `line` / `blank`. No spinner / bar (the animation chunk), no buffering /
1749
- * capture (the capture chunk), no level retention (the logger). Just format + write.
1750
- * - **`status` is a narrative OUTCOME, not a log level.** Its {@link StatusLevel} (`success` /
1690
+ * capture (the capture chunk), no level retention (the logger). Format and write, nothing more.
1691
+ * - **`status` is a narrative outcome, not a log level.** Its {@link StatusLevel} (`success` /
1751
1692
  * `error` / `warn` / `info`) is distinct from {@link import('./types.js').LogLevel}: an icon
1752
1693
  * supplied theme status icon + style, with `error` routed to the sink's
1753
1694
  * error stream (the `level` hint forwarded to {@link SinkInterface.write}) — there is no
1754
1695
  * gating and no severity ordering.
1755
1696
  * - **Width-aware.** `section` (and a `box` with no explicit `width`) lay out to the reporter's
1756
- * `#width`; the renderers measure on VISIBLE width (ANSI-aware), so styled content aligns.
1757
- * - **Event-free (§13).** No `#emitter` — a pure formatting front-end with no observable
1697
+ * `#width`; the renderers measure on visible width (ANSI-aware), so styled content aligns.
1698
+ * - **Event-free.** No `#emitter` — a pure formatting front-end with no observable
1758
1699
  * lifecycle (like the renderers and `Scheduler`). It is reusable and holds no per-call state.
1759
1700
  *
1760
1701
  * @example
@@ -1781,61 +1722,63 @@ export declare class Reporter implements ReporterInterface {
1781
1722
  }
1782
1723
 
1783
1724
  /**
1784
- * A lean, event-free narrative reporter — the composable verb set for human / build-run
1725
+ * Declares a lean, event-free narrative reporter — the composable verb set for human / build-run
1785
1726
  * output (sections, steps, timings, outcomes, tables, trees, boxes), formatting through the
1786
1727
  * shared {@link StylerInterface} + layout renderers and writing to a {@link SinkInterface}.
1787
1728
  *
1788
1729
  * @remarks
1789
- * - **A SMALL composable set**, not a grab-bag: `section` / `step` / `timing` / `status` /
1790
- * `table` / `tree` / `box` / `line` / `blank`. Coloring is the ONE styler; layout is the
1730
+ * - **A small composable set**, not a grab-bag: `section` / `step` / `timing` / `status` /
1731
+ * `table` / `tree` / `box` / `line` / `blank`. Coloring is the one styler; layout is the
1791
1732
  * pure renderers ({@link import('./helpers.js').renderSeparator} /
1792
1733
  * {@link import('./helpers.js').renderBox} / {@link import('./helpers.js').renderTable} /
1793
1734
  * {@link import('./helpers.js').renderTree}). No second colorizer, no spinner / bar (that
1794
1735
  * is the animation chunk), no buffering / capture (that is the capture chunk).
1795
1736
  * - **`status` is a narrative outcome, not a log level.** Its {@link StatusLevel} is
1796
- * `success` / `error` / `warn` / `info` (DISTINCT from {@link LogLevel}); `error` routes to
1737
+ * `success` / `error` / `warn` / `info` (distinct from {@link LogLevel}); `error` routes to
1797
1738
  * the sink's error stream.
1798
- * - **Event-free (§13).** No emitter — a pure formatting front-end. Each verb FORMATS then
1799
- * WRITES immediately; there is no retained state worth observing.
1739
+ * - **Event-free.** No emitter — a pure formatting front-end. Each verb formats then
1740
+ * writes immediately; there is no retained state worth observing.
1800
1741
  */
1801
1742
  export declare interface ReporterInterface {
1802
- /** Write a titled separator block — a section heading framed by a horizontal rule. */
1743
+ /** Writes a titled separator block — a section heading framed by a horizontal rule. */
1803
1744
  section(title: string): void;
1804
- /** Write a step line, optionally prefixed with its `[index/total]` {@link StepPosition}. */
1745
+ /** Writes a step line, optionally prefixed with its `[index/total]` {@link StepPosition}. */
1805
1746
  step(message: string, position?: StepPosition): void;
1806
- /** Write a timing line — `label … 1.23s` (sub-second shown as `…ms`). */
1747
+ /** Writes a timing line — `label … 1.23s` (sub-second shown as `…ms`). */
1807
1748
  timing(label: string, ms: number): void;
1808
- /** Write an icon + colored outcome line for `level` (`error` routes to the error stream). */
1749
+ /** Writes an icon + colored outcome line for `level` (`error` routes to the error stream). */
1809
1750
  status(level: StatusLevel, message: string): void;
1810
- /** Render a {@link TableOptions} grid through {@link import('./helpers.js').renderTable} and write it. */
1751
+ /** Renders a {@link TableOptions} grid through {@link import('./helpers.js').renderTable} and writes it. */
1811
1752
  table(options: TableOptions): void;
1812
- /** Render a {@link TreeOptions} tree through {@link import('./helpers.js').renderTree} and write it. */
1753
+ /** Renders a {@link TreeOptions} tree through {@link import('./helpers.js').renderTree} and writes it. */
1813
1754
  tree(options: TreeOptions): void;
1814
- /** Render a {@link BoxOptions} frame through {@link import('./helpers.js').renderBox} and write it. */
1755
+ /** Renders a {@link BoxOptions} frame through {@link import('./helpers.js').renderBox} and writes it. */
1815
1756
  box(options: BoxOptions): void;
1816
- /** Write one raw line, colored through the styler if any styling is embedded — no prefix, no icon. */
1757
+ /** Writes one raw line, colored through the styler if any styling is embedded — no prefix, no icon. */
1817
1758
  line(text: string): void;
1818
- /** Write `count` blank lines (default `1`). */
1759
+ /** Writes `count` blank lines (default `1`). */
1819
1760
  blank(count?: number): void;
1820
1761
  }
1821
1762
 
1822
1763
  /**
1823
- * Options for {@link createReporter} / the {@link ReporterInterface} constructor.
1764
+ * Configures the {@link import('./Reporter.js').Reporter} constructor the `sink` every line is
1765
+ * written to, the `styler` and `theme` it formats through, and the `width` its layouts measure
1766
+ * against.
1824
1767
  *
1825
1768
  * @remarks
1826
1769
  * - `sink` — where every formatted line is written; defaults to
1827
1770
  * {@link import('./factories.js').createConsoleSink} (the snapshotted, level-routing console
1828
- * sink) — the SAME seam the logger writes through. A `status('error', …)` passes the
1771
+ * sink) — the same seam the logger writes through. A `status('error', …)` passes the
1829
1772
  * `error` level so a stream-aware sink routes it to `stderr`.
1830
1773
  * - `styler` — the {@link StylerInterface} every line is colored through; defaults to
1831
- * {@link import('./factories.js').createStyler} (ANSI). The ONE styler the whole system
1774
+ * {@link import('./factories.js').createStyler} (ANSI). The one styler the whole system
1832
1775
  * shares — no second colorizer. A disabled styler yields plain narration.
1833
1776
  * - `theme` — the {@link Theme} supplying status, accent, and chrome roles; defaults to
1834
1777
  * {@link DEFAULT_THEME}.
1835
1778
  * - `width` — the default column width handed to the separator / box renderers (the section
1836
1779
  * rule, a `box` with no explicit width); defaults to {@link DEFAULT_WIDTH}.
1837
1780
  *
1838
- * Event-free (§13): the reporter has no `on` / `error` — it is a formatting front-end with no
1781
+ * Event-free: the reporter has no `on` / `error` — it is a formatting front-end with no
1839
1782
  * observable lifecycle, so (like the renderers and `Scheduler`) it carries no emitter.
1840
1783
  */
1841
1784
  export declare interface ReporterOptions {
@@ -1845,37 +1788,135 @@ export declare interface ReporterOptions {
1845
1788
  readonly width?: number;
1846
1789
  }
1847
1790
 
1848
- /** The full SGR reset sequence (`ESC[0m`) appended after a styled run. */
1791
+ /** Holds the full SGR reset sequence (`ESC[0m`) appended after a styled run. */
1849
1792
  export declare const RESET: string;
1850
1793
 
1851
- /** The SGR RESET parameter (0) — terminates a styled run, clearing all colors and attributes. */
1794
+ /** Holds the SGR RESET parameter (0) — terminates a styled run, clearing all colors and attributes. */
1852
1795
  export declare const RESET_CODE = 0;
1853
1796
 
1854
1797
  /**
1855
- * The number of milliseconds at or above which {@link import('./helpers.js').formatDuration}
1856
- * (and so `Reporter.timing`) switches from a `…ms` rendering to a `…s` (seconds, 2 d.p.)
1857
- * rendering exactly one second.
1798
+ * Implements the bounded, level-keyed retention engine the console and process captures buffer
1799
+ * through one capped total buffer
1800
+ * plus one capped bucket per level, generic over the record type each capture carries.
1801
+ *
1802
+ * @remarks
1803
+ * - **One engine, two captures.** The core `Capture` retains
1804
+ * {@link import('./types.js').CapturedMessage}s keyed by
1805
+ * {@link import('./types.js').CaptureLevel}, and the server `ProcessCapture` retains chunks keyed
1806
+ * by its stream level; both compose this, so their retention semantics cannot drift apart.
1807
+ * - **Bounded on both axes.** `add` appends to the total buffer and to the record's bucket, then
1808
+ * drops the oldest of whichever exceeded `limit`, so neither grows without bound.
1809
+ * - **Buckets are fixed at construction.** Only the levels passed to the constructor get a bucket.
1810
+ * A record at any other level still joins the total buffer, and `records(level)` for a level with
1811
+ * no bucket returns an empty list.
1812
+ * - **Copies out.** `records` returns a fresh list each call, so retained state is never reachable
1813
+ * for mutation through a returned value.
1814
+ *
1815
+ * @example
1816
+ * ```ts
1817
+ * const retention = new Retention<{ level: 'warn' | 'error'; text: string }>(['warn'], 2)
1818
+ * retention.add({ level: 'warn', text: 'first' })
1819
+ * retention.add({ level: 'error', text: 'second' }) // no bucket, still in the total buffer
1820
+ * retention.records().length // 2
1821
+ * retention.records('warn').map((record) => record.text) // ['first']
1822
+ * retention.clear()
1823
+ * retention.records() // []
1824
+ * ```
1825
+ */
1826
+ export declare class Retention<T extends {
1827
+ readonly level: string;
1828
+ }> implements RetentionInterface<T> {
1829
+ #private;
1830
+ constructor(levels: ReadonlyArray<T['level']>, limit: number);
1831
+ add(record: T): void;
1832
+ records(): readonly T[];
1833
+ records(level: T['level']): readonly T[];
1834
+ clear(): void;
1835
+ }
1836
+
1837
+ /**
1838
+ * Declares the bounded, level-keyed retention buffer a capture keeps its records in — one capped total
1839
+ * buffer plus one capped bucket per level configured at construction.
1840
+ *
1841
+ * @remarks
1842
+ * - **Bounded on both axes.** The total buffer and each bucket are capped at the same `limit`,
1843
+ * dropping the oldest record first, so neither can grow without bound.
1844
+ * - **Buckets are fixed at construction.** A record whose `level` has no bucket still joins the
1845
+ * total buffer, and `records(level)` for an unconfigured level returns an empty list rather than
1846
+ * failing.
1847
+ * - **Copies out.** Each `records` call returns a fresh list, so a caller can never mutate the
1848
+ * retained state through the value it receives.
1849
+ */
1850
+ export declare interface RetentionInterface<T extends {
1851
+ readonly level: string;
1852
+ }> {
1853
+ /**
1854
+ * Retains one record — appends it to the total buffer and to its level's bucket, evicting the
1855
+ * oldest of each past `limit`.
1856
+ */
1857
+ add(record: T): void;
1858
+ /**
1859
+ * Returns a copy of the whole retained buffer, oldest first, or — given a level — a copy of
1860
+ * that level's bucket, empty for a level with no bucket.
1861
+ */
1862
+ records(): readonly T[];
1863
+ /** Returns a copy of one level's bucket, oldest first; empty for a level with no bucket. */
1864
+ records(level: T['level']): readonly T[];
1865
+ /** Drops every retained record from the total buffer and every bucket. */
1866
+ clear(): void;
1867
+ }
1868
+
1869
+ /**
1870
+ * Sets the millisecond threshold at or above which {@link import('./helpers.js').formatDuration}
1871
+ * (and so `Reporter.timing`) switches from a `…ms` rendering to a `…s` (seconds, 2 d.p.) rendering
1872
+ * — `1000`, exactly one second.
1858
1873
  */
1859
1874
  export declare const SECOND_MS = 1000;
1860
1875
 
1861
- /** The default fill character {@link import('./helpers.js').renderSeparator} draws its rule with — `─`. */
1876
+ /**
1877
+ * Selects the member of a {@link WriterSet} a {@link LogLevel} routes to — `error` to `error`,
1878
+ * `warn` to `warn`, every other level and an omitted level to `log`.
1879
+ *
1880
+ * @remarks
1881
+ * The single owner of the level-to-target decision every sink backend shares, so core's console
1882
+ * sink, the browser `%c` sink, and the server stream sink cannot drift apart. A backend that sends
1883
+ * two levels to one destination passes the same member twice: the server sink routes `warn`
1884
+ * alongside `error` by supplying its error stream for both, which matches `console.warn` writing
1885
+ * to `stderr`. The member type is the caller's, so the same leaf selects a bound console method, a
1886
+ * stream target, or a per-target styling fact.
1887
+ *
1888
+ * @param level - The originating record's {@link LogLevel}, or `undefined` when the caller has none
1889
+ * @param writers - See {@link WriterSet}
1890
+ * @returns The member `level` routes to
1891
+ *
1892
+ * @example
1893
+ * ```ts
1894
+ * selectWriter('error', { log: 'stdout', warn: 'stderr', error: 'stderr' }) // 'stderr'
1895
+ * selectWriter('warn', { log: 'stdout', warn: 'stderr', error: 'stderr' }) // 'stderr'
1896
+ * selectWriter('debug', { log: 'stdout', warn: 'stderr', error: 'stderr' }) // 'stdout'
1897
+ * selectWriter(undefined, { log: 'stdout', warn: 'stderr', error: 'stderr' }) // 'stdout'
1898
+ * ```
1899
+ */
1900
+ export declare function selectWriter<T>(level: LogLevel | undefined, writers: WriterSet<T>): T;
1901
+
1902
+ /** Holds the default fill character {@link import('./helpers.js').renderSeparator} draws its rule with — `─`. */
1862
1903
  export declare const SEPARATOR_FILL = "\u2500";
1863
1904
 
1864
1905
  /**
1865
- * The single padding cell on each side of a separator's embedded title (` title `) — keeps the
1906
+ * Holds the single padding cell on each side of a separator's embedded title (` title `) — keeps the
1866
1907
  * title from butting against the rule. One space.
1867
1908
  */
1868
1909
  export declare const SEPARATOR_TITLE_GAP = " ";
1869
1910
 
1870
1911
  /**
1871
- * Options for {@link import('./helpers.js').renderSeparator} — a horizontal rule, optionally
1872
- * carrying a centered title.
1912
+ * Configures {@link import('./helpers.js').renderSeparator} — a horizontal rule, optionally
1913
+ * carrying a centered title. Every key is optional.
1873
1914
  *
1874
1915
  * @remarks
1875
- * - `title` — text to embed in the rule (e.g. a section heading). Omitted ⇒ an unbroken line.
1916
+ * - `title` — text to embed in the rule (for example a section heading). Omitted ⇒ an unbroken line.
1876
1917
  * - `width` — the visible column count of the whole rule; defaults to {@link DEFAULT_WIDTH}.
1877
1918
  * - `fill` — the single character the rule is drawn with; defaults to {@link SEPARATOR_FILL}
1878
- * (`─`). The VISIBLE width of the rule is `width` regardless of the fill's escape codes.
1919
+ * (`─`). The visible width of the rule is `width` regardless of the fill's escape codes.
1879
1920
  * - `styler` — colors the rule (and the embedded title) when supplied; the layout is
1880
1921
  * identical with or without it, since width is measured on the visible content.
1881
1922
  * - `style` — an optional by-value style rendered through `styler` for the rule and title.
@@ -1889,59 +1930,63 @@ export declare interface SeparatorOptions {
1889
1930
  }
1890
1931
 
1891
1932
  /**
1892
- * The minimal output primitive — the seam every formatted line is written through. A
1893
- * `Sink` is the ONE place text leaves the logging system; redirect output (to a file, a
1933
+ * Declares the minimal output primitive — the seam every formatted line is written through. A
1934
+ * `Sink` is the one place text leaves the logging system; redirect output (to a file, a
1894
1935
  * buffer, a test recorder, the browser `%c` path, a server TTY) by supplying a different
1895
1936
  * `SinkInterface`, with no change to the logger.
1896
1937
  *
1897
1938
  * @remarks
1898
1939
  * - **`write(text)` is the whole contract.** A custom sink (file / buffer / recorder)
1899
- * implements just `write(text)` and ignores the rest — the optional `level` exists ONLY so
1900
- * a stream-aware sink can ROUTE. The logger passes the originating record's {@link LogLevel}.
1940
+ * implements only `write(text)` and ignores the rest — the optional `level` exists only so
1941
+ * a stream-aware sink can route. The logger passes the originating record's {@link LogLevel}.
1901
1942
  * - **The default {@link import('./factories.js').createConsoleSink} routes by level** —
1902
1943
  * `error` → `console.error`, `warn` → `console.warn`, everything else → `console.log` — and
1903
- * writes to the UNDERLYING `console` methods SNAPSHOTTED at creation, so a later `Capture`
1944
+ * writes to the underlying `console` methods snapshotted at creation, so a later `Capture`
1904
1945
  * that patches `console` can never feed the sink's own output back into itself (the
1905
- * no-capture-loop principle). The same `level` seam lets the C-g server TTY sink send
1946
+ * no-capture-loop principle). The same `level` seam lets the server TTY sink send
1906
1947
  * `error` / `warn` to `stderr`.
1907
1948
  */
1908
1949
  export declare interface SinkInterface {
1909
1950
  /**
1910
- * Write one already-formatted chunk of output. `text` receives ONE LINE WITHOUT its
1911
- * terminator the sink's target supplies it (e.g. `console.log`; the server TTY sink
1912
- * appends one) — UNLESS `text` begins with `\r`: that is an in-place REDRAW frame (the
1913
- * Spinner / Progress animation protocol), written verbatim. A tick frame carries no
1914
- * terminator; a final frame carries its own.
1915
- * `level` is the originating record's {@link LogLevel} supplied so a stream-aware sink
1916
- * can route (e.g. `error` to `stderr`); a plain sink ignores it.
1951
+ * Writes one already-formatted chunk of output one line without its terminator, or a
1952
+ * `\r`-leading redraw frame written verbatim, routed by the optional `level`.
1953
+ *
1954
+ * @remarks
1955
+ * The sink's target supplies the terminator (for example `console.log`; the server TTY sink
1956
+ * appends one), unless `text` begins with `\r`: that is an in-place redraw frame (the
1957
+ * Spinner / Progress animation protocol). A tick frame carries no terminator; a final frame
1958
+ * carries its own. `level` is the originating record's {@link LogLevel} — supplied so a
1959
+ * stream-aware sink can route (for example `error` to `stderr`); a plain sink ignores it.
1917
1960
  */
1918
1961
  write(text: string, level?: LogLevel): void;
1919
1962
  }
1920
1963
 
1921
1964
  /**
1922
- * A self-driving, observable activity spinner (AGENTS §13) — a glyph cycle that advances on a
1965
+ * Implements a self-driving, observable activity spinner — a glyph cycle that advances on a
1923
1966
  * periodic timer, writing each `\r` + frame line to its {@link SinkInterface} and emitting it on
1924
- * `frame`. The leading `\r` is what an overwrite-capable sink (the C-g TTY sink) redraws on; a plain
1925
- * sink (C-f) degrades to a fresh, non-overwriting line — the line-OVERWRITE is the SINK's job, never
1926
- * the spinner's. UNIVERSAL — `setInterval` + the one {@link StylerInterface} + the one
1927
- * {@link SinkInterface}, no `node:*`, no `process.stdout`.
1967
+ * `frame`. The timer is always cleared on an outcome, so the spinner is leak-free.
1928
1968
  *
1929
1969
  * @remarks
1970
+ * The leading `\r` is what an overwrite-capable sink (the TTY sink) redraws on; a plain sink
1971
+ * degrades to a fresh, non-overwriting line — the line-overwrite is the sink's job, never the
1972
+ * spinner's. Universal — `setInterval` + the one {@link StylerInterface} + the one
1973
+ * {@link SinkInterface}, no `node:*`, no `process.stdout`.
1974
+ *
1930
1975
  * - **Self-driving but deterministically testable.** `start()` arms a `setInterval` that calls
1931
1976
  * {@link tick} each `interval`; each {@link tick} builds the styled `glyph + message` line for the
1932
1977
  * current frame, emits it on `frame`, writes `'\r' + line` to the sink, then advances the frame
1933
1978
  * index (wrapping). A test drives frames by calling {@link tick} directly, or arms a real short
1934
1979
  * `interval` and proves the timer arms / clears through the sink it writes to.
1935
- * - **Leak-free timer.** The interval is ALWAYS cleared on {@link success} / {@link failure} /
1980
+ * - **Leak-free timer.** The interval is always cleared on {@link succeed} / {@link fail} /
1936
1981
  * {@link stop} / {@link destroy} — `#handle` is the single source of `active`, set on arm and unset
1937
1982
  * on clear, so a spinner never leaks a running interval.
1938
1983
  * - **Idempotent `start`.** A {@link start} while already `active` is a no-op (it never arms a second
1939
1984
  * timer).
1940
- * - **Outcome lines.** {@link success} / {@link failure} clear the timer then write + emit a FINAL line —
1985
+ * - **Outcome lines.** {@link succeed} / {@link fail} clear the timer then write + emit a final line —
1941
1986
  * the supplied theme status icon + style (`✔` / `✖` by default) + the message — terminated
1942
- * by a newline (the activity is over; the line is committed, not overwritten). {@link failure} routes to
1987
+ * by a newline (the activity is over; the line is committed, not overwritten). {@link fail} routes to
1943
1988
  * the sink's error stream.
1944
- * - **Lifecycle (§10).** {@link stop} clears the timer and LEAVES the current line; {@link destroy}
1989
+ * - **Lifecycle.** {@link stop} clears the timer and leaves the current line; {@link destroy}
1945
1990
  * stops then destroys the emitter. {@link update} swaps the message and re-renders immediately when
1946
1991
  * `active`.
1947
1992
  *
@@ -1950,7 +1995,7 @@ export declare interface SinkInterface {
1950
1995
  * const spinner = new Spinner({ message: 'building' })
1951
1996
  * spinner.start() // arms the timer, paints the first frame to the sink
1952
1997
  * spinner.update('bundling') // message changes, re-rendered at once
1953
- * spinner.success('built in 1.2s') // ✔ built in 1.2s — timer cleared, line committed
1998
+ * spinner.succeed('built in 1.2s') // ✔ built in 1.2s — timer cleared, line committed
1954
1999
  * ```
1955
2000
  */
1956
2001
  export declare class Spinner implements SpinnerInterface {
@@ -1962,113 +2007,119 @@ export declare class Spinner implements SpinnerInterface {
1962
2007
  start(): void;
1963
2008
  tick(): void;
1964
2009
  update(message: string): void;
1965
- success(message?: string): void;
1966
- failure(message?: string): void;
2010
+ succeed(message?: string): void;
2011
+ fail(message?: string): void;
1967
2012
  stop(): void;
1968
2013
  destroy(): void;
1969
2014
  }
1970
2015
 
1971
2016
  /**
1972
- * The default spinner frame cycle a {@link import('./types.js').SpinnerInterface} advances through —
1973
- * the ten braille-pattern glyphs (U+2800 block) that read as a smoothly rotating dot, the universal
1974
- * terminal-spinner convention. Frozen; a consumer swaps the whole cycle via `options.frames`.
2017
+ * Holds the default spinner frame cycle a {@link import('./types.js').SpinnerInterface} advances
2018
+ * through — the braille-pattern glyphs (`⠋⠙⠹…`, the U+2800 block) that read as a smoothly rotating
2019
+ * dot.
1975
2020
  *
1976
2021
  * @remarks
2022
+ * The cycle is the universal terminal-spinner convention. Frozen; a consumer swaps the whole
2023
+ * cycle through `options.frames`.
2024
+ *
1977
2025
  * Braille glyphs are single visible cells, so every frame occupies one column — the spinner glyph
1978
2026
  * never shifts the message beside it as it advances. The source of truth for the default frame axis.
1979
2027
  */
1980
2028
  export declare const SPINNER_FRAMES: readonly string[];
1981
2029
 
1982
2030
  /**
1983
- * The observable events a {@link SpinnerInterface} emits (AGENTS §13).
2031
+ * Declares the observable events a {@link SpinnerInterface} emits — `frame(line)` per advance and
2032
+ * per outcome, plus the `start` and `stop` timer-lifecycle signals.
1984
2033
  *
1985
2034
  * @remarks
1986
- * - `frame` — the core event: fires once per advance (every `tick()`, whether driven by the internal
1987
- * timer or called directly) AND on the final `success` / `failure` line, carrying the rendered frame
1988
- * line (the SAME text written to the sink, minus the leading `\r`). The hook a non-sink consumer
2035
+ * - `frame` — fires once per advance (every `tick()`, whether driven by the internal
2036
+ * timer or called directly) and on the final `succeed` / `fail` line, carrying the rendered frame
2037
+ * line (the same text written to the sink, minus the leading `\r`). The hook a non-sink consumer
1989
2038
  * (a test, a remote mirror) rides to observe the animation without a terminal.
1990
2039
  * - `start` / `stop` — the lifecycle signals bracketing the internal timer: `start` fires when the
1991
2040
  * timer is armed (the first `start()` on an inactive spinner), `stop` when it is cleared (a
1992
- * `stop()` / `success()` / `failure()` on an active spinner, and from `destroy()`); both pure signals
2041
+ * `stop()` / `succeed()` / `fail()` on an active spinner, and from `destroy()`); both pure signals
1993
2042
  * (empty tuples) so a consumer can observe the activity lifecycle.
1994
2043
  *
1995
- * Listener isolation is the emitter's (§13): a listener throw routes to the emitter's `error`
1996
- * handler, never onto this map. Declared as a `type` alias (not `interface extends EventMap`, §4.5):
2044
+ * Listener isolation is the emitter's: a listener throw routes to the emitter's `error`
2045
+ * handler, never onto this map. Declared as a `type` alias (not `interface extends EventMap`):
1997
2046
  * a type-literal satisfies the `EventMap` constraint structurally, whereas an interface lacks the
1998
2047
  * index signature.
1999
2048
  */
2000
2049
  export declare type SpinnerEventMap = {
2001
- /** A frame was produced (a `tick()` advance or the final `success` / `failure` line) — the rendered line. */
2050
+ /** Fires after a frame was produced (a `tick()` advance or the final `succeed` / `fail` line) — the rendered line. */
2002
2051
  readonly frame: readonly [line: string];
2003
- /** The internal timer was armed (an inactive spinner's `start()`). */
2052
+ /** Fires after the internal timer was armed (an inactive spinner's `start()`). */
2004
2053
  readonly start: readonly [];
2005
- /** The internal timer was cleared (an active spinner's `stop()` / `success()` / `failure()` / `destroy()`). */
2054
+ /** Fires after the internal timer was cleared (an active spinner's `stop()` / `succeed()` / `fail()` / `destroy()`). */
2006
2055
  readonly stop: readonly [];
2007
2056
  };
2008
2057
 
2009
2058
  /**
2010
- * A self-driving, observable activity spinner (AGENTS §13) — a glyph cycle that advances on a
2059
+ * Declares a self-driving, observable activity spinner — a glyph cycle that advances on a
2011
2060
  * periodic timer, writing each `\r` + frame line to its {@link SinkInterface} and emitting it on
2012
- * `frame`. The line-OVERWRITE is the sink's job (a TTY sink overwrites on the `\r`; a plain sink
2061
+ * `frame`. The line-overwrite is the sink's job (a TTY sink overwrites on the `\r`; a plain sink
2013
2062
  * degrades to a fresh line).
2014
2063
  *
2015
2064
  * @remarks
2016
2065
  * - **Self-driving but deterministically testable.** `start()` arms a `setInterval` (universal — no
2017
2066
  * `node:*`) that calls `tick()` each `interval`; each `tick()` advances the frame index, builds the
2018
2067
  * styled `glyph + message` line, emits it on `frame`, and writes `'\r' + line` to the sink. A test
2019
- * drives frames by calling `tick()` directly (NO real clock) and proves the timer arms / clears
2020
- * with fake timers — the timer is ALWAYS cleared on `success` / `failure` / `stop` / `destroy`, so it
2068
+ * drives frames by calling `tick()` directly (no real clock) and proves the timer arms / clears
2069
+ * with fake timers — the timer is always cleared on `succeed` / `fail` / `stop` / `destroy`, so it
2021
2070
  * never leaks.
2022
2071
  * - **Idempotent `start`.** A `start()` while already `active` is a no-op (it never arms a second
2023
- * timer). `active` reflects whether the timer is currently armed.
2024
- * - **Outcome lines.** `success(message?)` / `failure(message?)` clear the timer, then write + emit a
2025
- * FINAL line — the theme's success / error status icon + style (`✔` / `✖` by default) + the
2072
+ * timer). `active` reflects whether the timer is armed.
2073
+ * - **Outcome lines.** `succeed(message?)` / `fail(message?)` clear the timer, then write + emit a
2074
+ * final line — the theme's success / error status icon + style (`✔` / `✖` by default) + the
2026
2075
  * message — terminated by a newline (the activity is over; the line is committed, not overwritten).
2027
- * `failure` routes to the sink's error stream.
2028
- * - **Lifecycle (§10).** `stop()` clears the timer and LEAVES the current line (no final write);
2076
+ * `fail` routes to the sink's error stream.
2077
+ * - **Lifecycle.** `stop()` clears the timer and leaves the current line (no final write);
2029
2078
  * `destroy()` stops then destroys the emitter. `update(message)` swaps the message (re-rendering
2030
2079
  * immediately when active, so the change shows without waiting for the next tick).
2031
2080
  */
2032
2081
  export declare interface SpinnerInterface {
2033
2082
  readonly emitter: EmitterInterface<SpinnerEventMap>;
2034
- /** Whether the internal timer is currently armed (between `start()` and `stop` / `success` / `failure`). */
2083
+ /** Reports whether the internal timer is armed (between `start()` and `stop` / `succeed` / `fail`). */
2035
2084
  readonly active: boolean;
2036
- /** The current message shown beside the glyph. */
2085
+ /** Holds the current message shown beside the glyph. */
2037
2086
  readonly message: string;
2038
- /** Arm the periodic timer and render the first frame — a no-op when already `active`. */
2087
+ /** Arms the periodic timer and renders the first frame — a no-op when already `active`. */
2039
2088
  start(): void;
2040
- /** Advance one frame: build the line, emit `frame`, and write `\r` + line to the sink. */
2089
+ /** Advances one frame: builds the line, emits `frame`, and writes `\r` + line to the sink. */
2041
2090
  tick(): void;
2042
- /** Change the message; re-renders immediately when `active` so the change shows at once. */
2091
+ /** Changes the message; re-renders immediately when `active` so the change shows at once. */
2043
2092
  update(message: string): void;
2044
- /** Stop with a SUCCESS line — clear the timer, write + emit `✔ message` + newline. */
2045
- success(message?: string): void;
2046
- /** Stop with a FAILURE line — clear the timer, write + emit `✖ message` + newline (error stream). */
2047
- failure(message?: string): void;
2048
- /** Clear the timer and LEAVE the current line (no final write) — a no-op when not `active`. */
2093
+ /** Stops with a success line — clears the timer, writes + emits `✔ message` + newline. */
2094
+ succeed(message?: string): void;
2095
+ /** Stops with an error line — clears the timer, writes + emits `✖ message` + newline (error stream). */
2096
+ fail(message?: string): void;
2097
+ /** Clears the timer and leaves the current line (no final write) — a no-op when not `active`. */
2049
2098
  stop(): void;
2050
- /** Tear down — `stop()` then destroy the emitter. */
2099
+ /** Tears down — `stop()` then destroys the emitter. */
2051
2100
  destroy(): void;
2052
2101
  }
2053
2102
 
2054
2103
  /**
2055
- * Options for `createSpinner` / the {@link SpinnerInterface} constructor.
2104
+ * Configures the {@link import('./Spinner.js').Spinner} constructor — the `on` / `error` emitter
2105
+ * keys, the `message` shown, the glyph `frames` and their `interval`, and the `sink` / `styler` /
2106
+ * `theme` line substrate.
2056
2107
  *
2057
2108
  * @remarks
2058
- * - `on` — the reserved {@link EmitterHooks} key (§8): initial listeners for the
2109
+ * - `on` — the reserved {@link EmitterHooks} key: initial listeners for the
2059
2110
  * {@link SpinnerEventMap}, wired at construction.
2060
- * - `error` — the emitter's listener-error handler (§13); a listener throw routes here.
2111
+ * - `error` — the emitter's listener-error handler; a listener throw routes here.
2061
2112
  * - `message` — the text shown beside the spinner glyph; defaults to `''` (a bare glyph). Changed
2062
- * live via `update(message)` and overridden by a `success` / `failure` argument.
2113
+ * live through `update(message)` and overridden by a `succeed` / `fail` argument.
2063
2114
  * - `frames` — the cycle of glyph frames the spinner advances through; defaults to
2064
2115
  * {@link SPINNER_FRAMES} (the braille set `⠋⠙⠹…`). Each `tick()` advances to the next, wrapping.
2065
2116
  * - `interval` — the timer period in milliseconds between frames; defaults to
2066
- * {@link DEFAULT_SPINNER_INTERVAL}. The timer is ALWAYS cleared on `success` / `failure` / `stop` /
2067
- * `destroy`, so it never leaks; tests drive frames deterministically via `tick()` (no real clock).
2117
+ * {@link DEFAULT_SPINNER_INTERVAL}. The timer is always cleared on `succeed` / `fail` / `stop` /
2118
+ * `destroy`, so it never leaks; tests drive frames deterministically through `tick()` (no real clock).
2068
2119
  * - `sink` — where each `\r` + frame line is written; defaults to
2069
- * {@link import('./factories.js').createConsoleSink}. A TTY sink (C-g) overwrites on the `\r`.
2120
+ * {@link import('./factories.js').createConsoleSink}. A TTY sink overwrites on the `\r`.
2070
2121
  * - `styler` — the {@link StylerInterface} the glyph is colored through; defaults to
2071
- * {@link import('./factories.js').createStyler} (ANSI). The ONE styler the whole system shares.
2122
+ * {@link import('./factories.js').createStyler} (ANSI). The one styler the whole system shares.
2072
2123
  * - `theme` — the {@link Theme} supplying the accent and outcome roles; defaults to
2073
2124
  * {@link DEFAULT_THEME}.
2074
2125
  */
@@ -2084,34 +2135,35 @@ export declare interface SpinnerOptions {
2084
2135
  }
2085
2136
 
2086
2137
  /**
2087
- * Each {@link StatusLevel}'s {@link Color} — the icon + message color a `status` line renders
2088
- * in (`success` green, `error` red, `warn` yellow, `info` blue). The VISUAL treatment of a
2138
+ * Maps each {@link StatusLevel} to its {@link Color} — the icon + message color a `status` line renders
2139
+ * in (`success` green, `error` red, `warn` yellow, `info` blue). The visual treatment of a
2089
2140
  * narrative outcome, colored through the reporter's styler; orthogonal to leveling, like
2090
2141
  * {@link LEVEL_COLORS}. Excludes `default` so each value indexes a real styler accessor.
2091
2142
  */
2092
2143
  export declare const STATUS_COLORS: Readonly<Record<StatusLevel, Exclude<Color, 'default'>>>;
2093
2144
 
2094
2145
  /**
2095
- * Each {@link StatusLevel}'s icon glyph — the leading mark a {@link
2146
+ * Maps each {@link StatusLevel} to its icon glyph — the leading mark a {@link
2096
2147
  * import('./types.js').ReporterInterface.status} outcome line shows: `success` ✔, `error` ✖,
2097
2148
  * `warn` ⚠, `info` ℹ. The narrative-outcome counterpart to a log level's label; frozen.
2098
2149
  */
2099
2150
  export declare const STATUS_ICONS: Readonly<Record<StatusLevel, string>>;
2100
2151
 
2101
2152
  /**
2102
- * Every {@link StatusLevel}, frozen — the outcomes a `status` line supports (drives exhaustive
2153
+ * Lists every {@link StatusLevel}, frozen — the outcomes a `status` line supports (drives exhaustive
2103
2154
  * tests). The source of truth for the status axis; aligned with {@link STATUS_ICONS} /
2104
2155
  * {@link STATUS_COLORS}.
2105
2156
  */
2106
2157
  export declare const STATUS_LEVELS: readonly StatusLevel[];
2107
2158
 
2108
2159
  /**
2109
- * A narrative outcome level — the four states {@link ReporterInterface.status} reports, each
2110
- * with its own icon + color ({@link STATUS_ICONS} / {@link STATUS_COLORS}).
2160
+ * Names a narrative outcome level — `success` / `error` / `warn` / `info`, the states
2161
+ * {@link ReporterInterface.status} reports, each with its own icon + color
2162
+ * ({@link STATUS_ICONS} / {@link STATUS_COLORS}).
2111
2163
  *
2112
2164
  * @remarks
2113
- * DISTINCT from {@link LogLevel} (`debug` / `info` / `warn` / `error`): a `StatusLevel` is a
2114
- * narrative OUTCOME (did the step success?), not a log SEVERITY threshold — there is no
2165
+ * distinct from {@link LogLevel} (`debug` / `info` / `warn` / `error`): a `StatusLevel` is a
2166
+ * narrative outcome (did the step success?), not a log severity threshold — there is no
2115
2167
  * ordering and no gating. `success` (`✔`, green), `error` (`✖`, red), `warn` (`⚠`, yellow),
2116
2168
  * `info` (`ℹ`, blue). `error` routes to the sink's error stream (the `level` hint passed to
2117
2169
  * {@link SinkInterface.write}); the other three go to the default stream.
@@ -2119,8 +2171,8 @@ export declare const STATUS_LEVELS: readonly StatusLevel[];
2119
2171
  export declare type StatusLevel = 'success' | 'error' | 'warn' | 'info';
2120
2172
 
2121
2173
  /**
2122
- * A step's position in a sequence — the `{ index, total }` a {@link ReporterInterface.step}
2123
- * renders as a `[2/5]` prefix.
2174
+ * Represents where one step sits in a sequence — what {@link ReporterInterface.step} renders as a
2175
+ * `[2/5]` prefix.
2124
2176
  *
2125
2177
  * @remarks
2126
2178
  * Both are 1-based for display (`{ index: 2, total: 5 }` ⇒ `[2/5]`); the reporter formats
@@ -2133,17 +2185,18 @@ export declare interface StepPosition {
2133
2185
  }
2134
2186
 
2135
2187
  /**
2136
- * Stringify ONE captured console argument into a line fragment — the per-argument rule behind
2188
+ * Stringifies one captured console argument into a line fragment — the per-argument rule behind
2137
2189
  * {@link formatArgs}: an `Error` → `name: message`, a plain object / array → circular-safe JSON,
2138
2190
  * anything else (string, number, boolean, `null`, `undefined`, symbol, function) → `String(value)`.
2139
2191
  *
2140
2192
  * @remarks
2141
- * - **Total + never throws.** Like a guard (§14), this never throws on adversarial input — a value
2193
+ * - **Total + never throws.** Like a guard, this never throws on adversarial input — a value
2142
2194
  * carrying a circular reference, a `BigInt`, or a throwing `toJSON` is rendered, not raised. The
2143
2195
  * `JSON.stringify` runs with a circular-guard replacer (a seen-set drops a back-reference as
2144
- * `'[Circular]'`); should `JSON.stringify` still throw (e.g. a `BigInt`), the value falls back to
2145
- * `String(value)`. So a `Capture` can never crash the program whose `console.*` it intercepts.
2146
- * - **`Error` first.** An `Error` renders as `name: message` (e.g. `TypeError: bad`) — the useful
2196
+ * `'[Circular]'`); if `JSON.stringify` still throws (for example on a `BigInt`), the value falls
2197
+ * back to `String(value)`. So a `Capture` can never crash the program whose `console.*` it
2198
+ * intercepts.
2199
+ * - **`Error` first.** An `Error` renders as `name: message` (for example `TypeError: bad`) — the useful
2147
2200
  * one-line form, since `JSON.stringify(error)` is `{}` (its fields are non-enumerable).
2148
2201
  * - **Objects → JSON.** A non-null `object` (including an array) is `JSON.stringify`d; a primitive
2149
2202
  * (or `null` / `undefined` / `function` / `symbol`) goes through `String`.
@@ -2164,11 +2217,11 @@ export declare interface StepPosition {
2164
2217
  export declare function stringifyValue(value: unknown): string;
2165
2218
 
2166
2219
  /**
2167
- * Remove every ANSI escape sequence from `text`, returning the plain visible string.
2220
+ * Removes every ANSI escape sequence from `text`, returning the plain visible string.
2168
2221
  *
2169
2222
  * @remarks
2170
- * Strips SGR color/style codes AND other CSI controls (cursor, erase) plus OSC
2171
- * sequences (titles, hyperlinks) — see {@link ANSI_PATTERN}. A FRESH `RegExp` is built
2223
+ * Strips SGR color/style codes and other CSI controls (cursor, erase) plus OSC
2224
+ * sequences (titles, hyperlinks) — see {@link ANSI_PATTERN}. A fresh `RegExp` is built
2172
2225
  * per call from the canonical pattern's `source` + `flags`, so the shared global
2173
2226
  * pattern's `lastIndex` is never mutated across calls (re-entrant and deterministic).
2174
2227
  *
@@ -2183,14 +2236,15 @@ export declare function stringifyValue(value: unknown): string;
2183
2236
  export declare function strip(text: string): string;
2184
2237
 
2185
2238
  /**
2186
- * Remove every non-printing C0 control character from `text` EXCEPT `\t` / `\n` / `\r`
2187
- * (meaningful whitespace), plus DEL — returning the sanitized string.
2239
+ * Removes every non-printing C0 control character from `text` except `\t` / `\n` / `\r`
2240
+ * (meaningful whitespace), plus DEL — a separate pass from {@link strip}, so `width` stays
2241
+ * untouched.
2188
2242
  *
2189
2243
  * @remarks
2190
- * Deliberately SEPARATE from {@link strip} (ANSI-escape removal only, so `width` /
2244
+ * Deliberately separate from {@link strip} (ANSI-escape removal only, so `width` /
2191
2245
  * `align` stay untouched) — this is the additional pass a non-TTY output sink applies
2192
2246
  * on top of `strip`, so a captured `\x07` bell or stray `\x00` never reaches a log file
2193
- * / non-terminal target. A FRESH `RegExp` is built per call from {@link CONTROL_PATTERN}'s
2247
+ * / non-terminal target. A fresh `RegExp` is built per call from {@link CONTROL_PATTERN}'s
2194
2248
  * `source` + `flags`, the same re-entrant idiom as `strip`.
2195
2249
  *
2196
2250
  * @param text - Any string, possibly carrying raw control bytes
@@ -2204,7 +2258,7 @@ export declare function strip(text: string): string;
2204
2258
  export declare function stripControls(text: string): string;
2205
2259
 
2206
2260
  /**
2207
- * Text style as DATA — a frozen, readonly record of a foreground color, a background
2261
+ * Represents text style as data — a frozen, readonly record of a foreground color, a background
2208
2262
  * color, and a set of text attributes. The single style value the whole console /
2209
2263
  * terminal system shares; a {@link RendererInterface} renders it for one target.
2210
2264
  *
@@ -2213,7 +2267,7 @@ export declare function stripControls(text: string): string;
2213
2267
  * emits a color code only for a set, non-`default` color.
2214
2268
  * - `attributes` is a de-duplicated, order-stable list (a set modelled as an array so
2215
2269
  * the value stays plain JSON data — no `Set` to clone or serialize). An empty list +
2216
- * no colors is the EMPTY style, which renders text unchanged.
2270
+ * no colors is the empty style, which renders text unchanged.
2217
2271
  * - The value is deeply frozen; compose a new style with the styler rather than mutating.
2218
2272
  */
2219
2273
  export declare interface Style {
@@ -2223,10 +2277,10 @@ export declare interface Style {
2223
2277
  }
2224
2278
 
2225
2279
  /**
2226
- * The fluent, composable styling surface — the consumer-facing API. It is BOTH a
2227
- * function (call it with text to render the accumulated style) AND a record of
2280
+ * Declares the fluent, composable styling surface — the consumer-facing API. It is both a
2281
+ * function (call it with text to render the accumulated style) and a record of
2228
2282
  * chainable accessors: every {@link Color} and {@link Attribute} is a getter returning a
2229
- * NEW styler with that token added, so `styler.red.bold('hi')` and
2283
+ * new styler with that token added, so `styler.red.bold('hi')` and
2230
2284
  * `styler.red(styler.bold('hi'))` both work and nothing is mutated.
2231
2285
  *
2232
2286
  * @remarks
@@ -2234,24 +2288,24 @@ export declare interface Style {
2234
2288
  * styler is reusable and the chains never interfere.
2235
2289
  * - Calling the styler builds the {@link Style} under the hood and renders it through the
2236
2290
  * injected renderer. When `enabled` is `false`, it returns the text verbatim.
2237
- * - `render` is the DATA door beside the accessor chain: it renders a {@link Style} value
2291
+ * - `render` is the data door beside the accessor chain: it renders a {@link Style} value
2238
2292
  * (a {@link Theme} role, say) merged over the accumulated style, so a caller styles by
2239
2293
  * value where the chain styles by name. Both go through the same renderer and the same
2240
2294
  * `enabled` switch.
2241
- * - `style` exposes the accumulated style DATA (the empty style on a base styler), and
2295
+ * - `style` exposes the accumulated style data (the empty style on a base styler), and
2242
2296
  * `enabled` reflects the switch — both inspectable and testable.
2243
2297
  * - A later color of the same channel wins (`styler.red.blue` is blue); a repeated
2244
2298
  * attribute is idempotent (`styler.bold.bold` carries one `bold`).
2245
2299
  */
2246
2300
  export declare interface StylerInterface {
2247
- /** Render the accumulated style around `text` (verbatim when `enabled` is `false`). */
2301
+ /** Renders the accumulated style around `text` (verbatim when `enabled` is `false`). */
2248
2302
  (text: string): string;
2249
- /** The accumulated style DATA — the empty style on a base styler. */
2303
+ /** Holds the accumulated style data — the empty style on a base styler. */
2250
2304
  readonly style: Style;
2251
- /** Whether styling is applied; when `false`, calls return text unchanged. */
2305
+ /** Reports whether styling is applied; when `false`, calls return text unchanged. */
2252
2306
  readonly enabled: boolean;
2253
2307
  /**
2254
- * Render `text` in `style` merged OVER the accumulated style — the by-value counterpart
2308
+ * Renders `text` in `style` merged over the accumulated style — the by-value counterpart
2255
2309
  * of the accessor chain, and the door a {@link Theme} role is applied through.
2256
2310
  *
2257
2311
  * @param style - The style to overlay; its colors win over the accumulated ones and its
@@ -2262,7 +2316,7 @@ export declare interface StylerInterface {
2262
2316
  *
2263
2317
  * @example
2264
2318
  * ```ts
2265
- * import { createStyler, DEFAULT_THEME } from '@src/core'
2319
+ * import { createStyler, DEFAULT_THEME } from '@orkestrel/console'
2266
2320
  *
2267
2321
  * const styler = createStyler()
2268
2322
  * styler.render(DEFAULT_THEME.levels.warn, 'WARN') // yellow
@@ -2295,14 +2349,15 @@ export declare interface StylerInterface {
2295
2349
  }
2296
2350
 
2297
2351
  /**
2298
- * Options for {@link createStyler}.
2352
+ * Configures {@link createStyler} — `renderer` selects the output target, defaulting to the ANSI
2353
+ * renderer, and `enabled` is the no-color switch, defaulting to `true`.
2299
2354
  *
2300
2355
  * @remarks
2301
- * - `renderer` — the {@link RendererInterface} every style renders through; defaults to
2302
- * the ANSI renderer (the cross-environment default), so the styler works unchanged in
2303
- * any terminal. Inject a browser `%c` renderer (C-f) to retarget with no other change.
2304
- * - `enabled` — the no-color switch. When `false`, the styler returns text VERBATIM
2305
- * (for a non-TTY, a `NO_COLOR` environment, or piped output); defaults to `true`.
2356
+ * - `renderer` — the {@link RendererInterface} every style renders through, so the styler
2357
+ * works unchanged in any terminal. Inject a browser `%c` renderer to retarget with no
2358
+ * other change.
2359
+ * - `enabled` — when `false`, the styler returns text verbatim, for a non-TTY, a
2360
+ * `NO_COLOR` environment, or piped output.
2306
2361
  */
2307
2362
  export declare interface StylerOptions {
2308
2363
  readonly renderer?: RendererInterface;
@@ -2310,8 +2365,9 @@ export declare interface StylerOptions {
2310
2365
  }
2311
2366
 
2312
2367
  /**
2313
- * Options for {@link import('./helpers.js').renderTable} — a bordered grid of columns + rows
2314
- * with per-column alignment and width-aware sizing.
2368
+ * Configures {@link import('./helpers.js').renderTable} — a bordered grid of columns + rows with
2369
+ * per-column alignment and width-aware sizing. A `Reporter` supplies its own chrome style only when
2370
+ * the caller gives neither `styler` nor `style`.
2315
2371
  *
2316
2372
  * @remarks
2317
2373
  * - `columns` — the {@link ColumnSpec}s, left to right; their `label`s form the header row.
@@ -2320,7 +2376,7 @@ export declare interface StylerOptions {
2320
2376
  * - `border` — the {@link BorderStyle} the frame + header rule + column separators draw in;
2321
2377
  * defaults to {@link DEFAULT_BORDER} (`single`).
2322
2378
  * - `styler` — colors the border + header labels when supplied; the cells are written as
2323
- * given (already-styled cells are honored — their VISIBLE width drives column sizing, never
2379
+ * given (already-styled cells are honored — their visible width drives column sizing, never
2324
2380
  * their raw `.length`).
2325
2381
  * - `style` — an optional by-value style rendered through `styler` for the frame and headers.
2326
2382
  */
@@ -2333,9 +2389,8 @@ export declare interface TableOptions {
2333
2389
  }
2334
2390
 
2335
2391
  /**
2336
- * The app-wide semantic style vocabulary — every role the console system styles, bound to a
2337
- * {@link Style} value. Pass one theme to a logger / reporter / spinner / progress and every
2338
- * surface speaks it.
2392
+ * Represents the app-wide semantic style vocabulary — each role bound to a {@link Style} value.
2393
+ * Pass one theme to a logger / reporter / spinner / progress and every surface speaks it.
2339
2394
  *
2340
2395
  * @remarks
2341
2396
  * - `levels` — the label style per {@link LogLevel} (a log line's severity label).
@@ -2345,7 +2400,7 @@ export declare interface TableOptions {
2345
2400
  * step prefix.
2346
2401
  * - `chrome` — the frame role: separators, box / table / tree connectors, and a log line's
2347
2402
  * timestamp / name / data surround.
2348
- * - A theme is the vocabulary the WHOLE application shares; a per-entity option (a
2403
+ * - A theme is the vocabulary the whole application shares; a per-entity option (a
2349
2404
  * `ProgressOptions.fill`, a `BoxOptions.border`) is the presentation of that one instance.
2350
2405
  * - A theme returned by {@link createTheme} is frozen with every {@link Style} leaf deeply
2351
2406
  * frozen, so one theme is safely shared across every entity.
@@ -2358,14 +2413,14 @@ export declare interface Theme {
2358
2413
  }
2359
2414
 
2360
2415
  /**
2361
- * Options for {@link createTheme} — the roles to override on {@link DEFAULT_THEME}.
2416
+ * Holds the options for {@link createTheme} — the roles to override on {@link DEFAULT_THEME}, a
2417
+ * status supplying its whole copied `{ icon, style }` record.
2362
2418
  *
2363
2419
  * @remarks
2364
- * Every key is optional and merges per ROLE, never per theme: an omitted role keeps its
2420
+ * Every key is optional and merges per role, never per theme: an omitted role keeps its
2365
2421
  * default, and `levels` / `statuses` merge per entry, so `{ levels: { warn: … } }` restyles
2366
- * the `warn` label and leaves the other three alone. A status override supplies its whole
2367
- * `{ icon, style }` record; {@link createTheme} snapshots and freezes that record and every
2368
- * style leaf it receives.
2422
+ * the `warn` label and leaves `debug`, `info`, and `error` alone. {@link createTheme}
2423
+ * snapshots and freezes each status record and every style leaf it receives.
2369
2424
  */
2370
2425
  export declare interface ThemeOptions {
2371
2426
  readonly levels?: Readonly<Partial<Record<LogLevel, Style>>>;
@@ -2375,12 +2430,12 @@ export declare interface ThemeOptions {
2375
2430
  }
2376
2431
 
2377
2432
  /**
2378
- * One narrative outcome's presentation — the icon glyph a {@link StatusLevel} shows and the
2433
+ * Represents one narrative outcome's presentation — the icon glyph a {@link StatusLevel} shows and the
2379
2434
  * {@link Style} the line renders in.
2380
2435
  *
2381
2436
  * @remarks
2382
2437
  * The themed counterpart of the {@link STATUS_ICONS} / {@link STATUS_COLORS} defaults: those
2383
- * two constants are the SOURCE of {@link DEFAULT_THEME}'s statuses. A status override supplies
2438
+ * two constants are the source of {@link DEFAULT_THEME}'s statuses. A status override supplies
2384
2439
  * the whole record — both `icon` and `style` — through {@link ThemeOptions}.
2385
2440
  */
2386
2441
  export declare interface ThemeStatus {
@@ -2389,7 +2444,7 @@ export declare interface ThemeStatus {
2389
2444
  }
2390
2445
 
2391
2446
  /**
2392
- * One node of a {@link TreeOptions} tree — a label plus optional children, recursively.
2447
+ * Represents one node of a {@link TreeOptions} tree — a label plus optional children, recursively.
2393
2448
  *
2394
2449
  * @remarks
2395
2450
  * - `label` — the node's text (a single visible line; it may already be styled).
@@ -2402,8 +2457,9 @@ export declare interface TreeNode {
2402
2457
  }
2403
2458
 
2404
2459
  /**
2405
- * Options for {@link import('./helpers.js').renderTree} — a nested {@link TreeNode} tree drawn
2406
- * with box-drawing connectors.
2460
+ * Configures {@link import('./helpers.js').renderTree} — a nested {@link TreeNode} tree drawn with
2461
+ * box-drawing connectors. A `Reporter` supplies its own chrome style only when the caller gives
2462
+ * neither `styler` nor `style`.
2407
2463
  *
2408
2464
  * @remarks
2409
2465
  * - `root` — the top {@link TreeNode}; its `label` is the unindented first line and its
@@ -2422,13 +2478,13 @@ export declare interface TreeOptions {
2422
2478
  }
2423
2479
 
2424
2480
  /**
2425
- * The visible width of `text` — its length after ANSI escapes are stripped, counted in
2481
+ * Measures how many visible columns `text` occupies — its length after ANSI escapes are stripped, counted in
2426
2482
  * Unicode code points (so an astral character such as an emoji counts as one, not the
2427
2483
  * two UTF-16 units `String.length` would report).
2428
2484
  *
2429
2485
  * @remarks
2430
2486
  * The basis for terminal layout (box / table / progress alignment): the column count a
2431
- * styled string occupies, independent of its escape codes. It does NOT account for
2487
+ * styled string occupies, independent of its escape codes. It does not account for
2432
2488
  * wide (CJK / fullwidth) glyphs occupying two cells — a deliberate, documented
2433
2489
  * simplification at this layer; callers needing east-asian width handle it above.
2434
2490
  *
@@ -2442,8 +2498,21 @@ export declare interface TreeOptions {
2442
2498
  */
2443
2499
  export declare function width(text: string): number;
2444
2500
 
2445
- export declare function withCapture<T>(fn: () => Promise<T>, options?: CaptureOptions): Promise<CaptureResult<T>>;
2446
-
2447
- export declare function withCapture<T>(fn: () => T, options?: CaptureOptions): CaptureResult<T>;
2501
+ /**
2502
+ * Groups the write targets a level-routing sink chooses between — each of the backend's own member
2503
+ * type.
2504
+ *
2505
+ * @remarks
2506
+ * The member type is the sink's own: a bound `console` method in core, a browser `%c` console
2507
+ * method, a stream target on the server, or any per-target fact routed the same way. A backend
2508
+ * that sends two levels to one place supplies the same member twice; that is how the server sink
2509
+ * routes `warn` alongside `error` to its error stream.
2510
+ * {@link import('./helpers.js').selectWriter} is the one place the level-to-member decision lives.
2511
+ */
2512
+ export declare interface WriterSet<T> {
2513
+ readonly log: T;
2514
+ readonly warn: T;
2515
+ readonly error: T;
2516
+ }
2448
2517
 
2449
2518
  export { }