@autter/runtime-node 1.4.0 → 1.5.0

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.
@@ -0,0 +1,313 @@
1
+ /**
2
+ * Structural copy of OpenTelemetry's `Attributes` so runtime-core stays
3
+ * dependency-free (it is bundled into the zero-dependency edge package).
4
+ * Assignable both ways with `@opentelemetry/api`'s type.
5
+ */
6
+ type AttributeValue = string | number | boolean | Array<null | undefined | string> | Array<null | undefined | number> | Array<null | undefined | boolean>;
7
+ type Attributes = Record<string, AttributeValue | undefined>;
8
+
9
+ interface RedactOptions {
10
+ /**
11
+ * Extra patterns matched against lower-cased attribute KEYS; a match
12
+ * masks the whole value. Strings become case-insensitive substring
13
+ * patterns. Extends the built-in list.
14
+ */
15
+ additionalKeyPatterns?: (RegExp | string)[];
16
+ /**
17
+ * Extra patterns scrubbed inside string VALUES — attribute values,
18
+ * exception messages, stack traces, span status messages, URLs, log
19
+ * lines. Strings are compiled as case-insensitive regex sources. Every
20
+ * pattern is applied globally. Extends the built-in list.
21
+ */
22
+ additionalValuePatterns?: (RegExp | string)[];
23
+ /** Replacement token. Default "[redacted]". */
24
+ mask?: string;
25
+ /**
26
+ * Scrub email-shaped substrings from ALL string values, not just
27
+ * sensitive keys. Default true.
28
+ */
29
+ scrubEmailValues?: boolean;
30
+ /**
31
+ * Scrub Luhn-valid payment card numbers from all string values.
32
+ * Default true.
33
+ */
34
+ scrubCardNumbers?: boolean;
35
+ }
36
+ /**
37
+ * Return a copy of `attributes` with PII/secrets masked. Never mutates the
38
+ * input; non-string primitives pass through untouched; `undefined` values
39
+ * are dropped (OpenTelemetry rejects them).
40
+ */
41
+ declare function redactAttributes(attributes?: Attributes | null, options?: RedactOptions): Attributes;
42
+ /**
43
+ * Scrub secrets/PII embedded in one string — an error message, a stack
44
+ * trace, a URL, a log line. Same value patterns as redactAttributes().
45
+ */
46
+ declare function redactText(text: string, options?: RedactOptions): string;
47
+ /** A compiled redactor: callable for attribute bags, plus string and
48
+ * export-time helpers. */
49
+ interface Redactor$1 {
50
+ (attributes?: Attributes | null): Attributes;
51
+ /** Scrub one string (messages, stacks, URLs). Identity when disabled. */
52
+ text(value: string): string;
53
+ /**
54
+ * Export-time pass over attributes already on a span (set by any
55
+ * instrumentation, not just Autter's capture calls). Strings are
56
+ * value-scrubbed, string values under sensitive KEYS are masked, and
57
+ * numbers/booleans pass untouched — usage counters such as
58
+ * `ai.usage.promptTokens` must survive for cost tracking.
59
+ */
60
+ exported(attributes: Attributes): Attributes;
61
+ readonly enabled: boolean;
62
+ }
63
+
64
+ type RuntimeLogContextValue = string | number | boolean | null | undefined | RuntimeLogContextValue[] | {
65
+ [key: string]: RuntimeLogContextValue;
66
+ };
67
+ type RuntimeLogContext = Record<string, RuntimeLogContextValue>;
68
+ type RuntimeLogLevel = "debug" | "info" | "warning" | "error";
69
+ type RuntimeOutcome = "succeeded" | "failed" | "degraded" | "cancelled" | "pending";
70
+ type RuntimeOperationKind = "request" | "operation";
71
+
72
+ /**
73
+ * Structured, coded errors shared by every Autter Runtime server SDK.
74
+ *
75
+ * export const billingErrors = defineRuntimeErrors("billing", {
76
+ * declined: { status: 402, message: "Payment declined", expected: true,
77
+ * why: "The card issuer rejected the charge",
78
+ * fix: "Ask the customer for another card" },
79
+ * limit: ({ plan }: { plan: string }) => ({ status: 429, message: `Plan ${plan} limit reached` }),
80
+ * });
81
+ * throw billingErrors.limit({ plan: "free" }); // code "billing.limit"
82
+ *
83
+ * A code groups every occurrence into one issue (scheme "code-v1"), so codes
84
+ * must be stable, namespaced and low-cardinality: never ids, user data or
85
+ * secrets. Anything not matching CODE_PATTERN is dropped and the error
86
+ * groups by message exactly as before.
87
+ */
88
+ /** `namespace.key` with up to four segments, lower-case, max 80 characters. */
89
+ declare const CODE_PATTERN: RegExp;
90
+ interface RuntimeErrorDefinition {
91
+ /** Human-readable message. Safe to show to clients. */
92
+ message: string;
93
+ /** HTTP-ish status. Default 500 when the error reaches a response. */
94
+ status?: number;
95
+ /** Expected business failure (decline, validation): recorded, never an incident. */
96
+ expected?: boolean;
97
+ /** Declared cause, ≤ 1000 chars. Treated as a hypothesis by Autter's RCA. */
98
+ why?: string;
99
+ /** Declared remedy, ≤ 1000 chars. */
100
+ fix?: string;
101
+ /** Docs link, ≤ 500 chars. */
102
+ link?: string;
103
+ }
104
+ interface RuntimeErrorExtras {
105
+ /** Underlying error; becomes `exception.cause.N.*` (max 5 levels). */
106
+ cause?: unknown;
107
+ /** Debug-only details: redacted and attached to the span only, never to logs or client responses. */
108
+ internal?: Record<string, unknown>;
109
+ /** Override the catalog message for this throw. */
110
+ message?: string;
111
+ }
112
+ interface RuntimeErrorOptions extends RuntimeErrorDefinition {
113
+ /** Stable namespaced code, e.g. "inventory.reservation_timeout". */
114
+ code?: string;
115
+ /** Underlying error; becomes `exception.cause.N.*` (max 5 levels). */
116
+ cause?: unknown;
117
+ /** Debug-only details: redacted and attached to the span only, never to logs or client responses. */
118
+ internal?: Record<string, unknown>;
119
+ }
120
+ /** The fields Autter reads from any error (duck-typed). */
121
+ interface RuntimeErrorLike {
122
+ message?: string;
123
+ code?: string;
124
+ why?: string;
125
+ fix?: string;
126
+ link?: string;
127
+ status?: number;
128
+ expected?: boolean;
129
+ }
130
+ declare class RuntimeError extends Error implements RuntimeErrorLike {
131
+ readonly code?: string;
132
+ readonly why?: string;
133
+ readonly fix?: string;
134
+ readonly link?: string;
135
+ readonly status?: number;
136
+ readonly expected?: boolean;
137
+ /** Non-enumerable so JSON.stringify / loggers never serialise it. */
138
+ readonly internal?: Record<string, unknown>;
139
+ constructor(options: RuntimeErrorOptions | string);
140
+ /** Client-safe JSON (what `toClientError` returns, minus the wrapper). */
141
+ toJSON(): Record<string, unknown>;
142
+ }
143
+ type CatalogEntry = RuntimeErrorDefinition | ((args: any) => RuntimeErrorDefinition);
144
+ /** A typed factory for one catalog entry; `.code` is the namespaced code. */
145
+ type RuntimeErrorFactory<E> = E extends (args: infer A) => RuntimeErrorDefinition ? ((args: A, extras?: RuntimeErrorExtras) => RuntimeError) & {
146
+ readonly code: string;
147
+ } : ((extras?: RuntimeErrorExtras) => RuntimeError) & {
148
+ readonly code: string;
149
+ };
150
+ type RuntimeErrorCatalog<C extends Record<string, CatalogEntry>> = {
151
+ readonly [K in keyof C]: RuntimeErrorFactory<C[K]>;
152
+ };
153
+ /**
154
+ * Build typed error factories from a catalog. Each key becomes the code
155
+ * `${namespace}.${key}`; an invalid resulting code is dropped with a
156
+ * one-time warning (the factory still produces a normal RuntimeError).
157
+ */
158
+ declare function defineRuntimeErrors<const C extends Record<string, CatalogEntry>>(namespace: string, catalog: C): RuntimeErrorCatalog<C>;
159
+ /**
160
+ * True for any error carrying Autter's structured fields — a RuntimeError,
161
+ * or ANY object with a string `code`/`why`/`fix`/`link`, a numeric `status`
162
+ * (or `statusCode`) or a boolean `expected`. Existing error classes benefit
163
+ * without being rewritten.
164
+ */
165
+ declare function isRuntimeErrorLike(err: unknown): err is RuntimeErrorLike;
166
+ interface ErrorAttributeOptions {
167
+ /** Also emit `exception.cause.N.*` for the cause chain (default true). */
168
+ causes?: boolean;
169
+ }
170
+ /**
171
+ * Wire attributes for an error: `autter.error.code|why|fix|link|status|expected`
172
+ * and `exception.cause.N.type|message|code` (N = 1..5). Never includes
173
+ * `internal` — see `errorInternal`.
174
+ */
175
+ declare function errorAttributes(err: unknown, options?: ErrorAttributeOptions): Record<string, string | number | boolean>;
176
+ interface ClientErrorBody {
177
+ error: {
178
+ message: string;
179
+ code?: string;
180
+ why?: string;
181
+ fix?: string;
182
+ link?: string;
183
+ requestId?: string;
184
+ };
185
+ }
186
+ /**
187
+ * Client-safe JSON body for an error:
188
+ * `{ error: { message, code?, why?, fix?, link?, requestId? } }`.
189
+ * Never includes `internal`, stacks or causes. The message of an
190
+ * unstructured 5xx error (a plain `throw new Error(...)`) is replaced with a
191
+ * generic one, because it was never written for clients.
192
+ */
193
+ declare function toClientError(err: unknown, requestId?: string): ClientErrorBody;
194
+
195
+ /**
196
+ * One runtime record before it is encoded for any sink: an operation or
197
+ * request summary (`autter.event.type = "operation"`) or a plain log line.
198
+ * `attributes` are already redacted and bounded.
199
+ */
200
+ interface RuntimeEvent {
201
+ /** Epoch milliseconds. */
202
+ time: number;
203
+ level: RuntimeLogLevel;
204
+ message: string;
205
+ attributes: RuntimeLogContext;
206
+ traceId?: string;
207
+ spanId?: string;
208
+ }
209
+
210
+ /**
211
+ * Serialisable link from a producer operation to work it hands off (a queue
212
+ * job, another process): `{ v: 1, op, req?, traceparent? }`. Put it in the
213
+ * job payload; the consumer passes it as `withRuntimeOperation(..., { from })`.
214
+ */
215
+ interface RuntimeCarrier {
216
+ v: 1;
217
+ /** Producer operation id (becomes the consumer's `autter.operation.parent_id`). */
218
+ op: string;
219
+ /** Request id the work belongs to. */
220
+ req?: string;
221
+ /** W3C traceparent of the producer span (consumer links to it). */
222
+ traceparent?: string;
223
+ }
224
+
225
+ /**
226
+ * Where runtime records go. The logger pipeline is
227
+ * `enrich → redact/bound → sinks[]`; each sink receives the same immutable
228
+ * RuntimeEvent. Defaults: `[otlpSink(), consoleSink()]` (+ `fileSink()` when
229
+ * NODE_ENV=development). Sinks must never throw into application code.
230
+ */
231
+ interface RuntimeSink {
232
+ readonly name: string;
233
+ /** Called when the logger is (re)configured; null before init. */
234
+ start?(context: RuntimeSinkContext): void;
235
+ write(event: RuntimeEvent): void;
236
+ flush?(): Promise<void>;
237
+ shutdown?(): Promise<void>;
238
+ /** Records held in memory awaiting delivery. */
239
+ buffered?(): number;
240
+ /** @internal Receives every captureException call (testing sinks). */
241
+ exception?(record: CapturedException): void;
242
+ }
243
+ interface RuntimeSinkContext {
244
+ endpoint: string;
245
+ apiKey: string;
246
+ service: string;
247
+ environment: string;
248
+ release?: string;
249
+ /** SDK identity for the `telemetry.distro.*` resource attributes. */
250
+ distro?: {
251
+ name: string;
252
+ version: string;
253
+ };
254
+ }
255
+ interface CapturedException {
256
+ time: number;
257
+ error: unknown;
258
+ message: string;
259
+ type: string;
260
+ attributes: Record<string, unknown>;
261
+ operationId?: string;
262
+ requestId?: string;
263
+ }
264
+ interface OtlpSinkOptions {
265
+ /** Override the ingester base URL (default: the configured endpoint). */
266
+ endpoint?: string;
267
+ /** Override the ingest key (default: the configured apiKey). */
268
+ apiKey?: string;
269
+ }
270
+ /**
271
+ * OTLP/HTTP JSON export to `${endpoint}/v1/logs`. Bounded exactly like
272
+ * 1.4.0: 1000 records / 4 MiB buffered, 256 KiB per record, batches of 50
273
+ * (≤ 512 KiB), 3 attempts within a 10 s deadline, exponential back-off
274
+ * on failure, undelivered records reported at shutdown.
275
+ */
276
+ declare function otlpSink(options?: OtlpSinkOptions): RuntimeSink;
277
+ interface ConsoleSinkOptions {
278
+ /** Default: "pretty" unless NODE_ENV === "production", then "json". */
279
+ format?: "pretty" | "json";
280
+ /** Colourise pretty output. Default: stdout is a TTY and NO_COLOR is unset. */
281
+ color?: boolean;
282
+ /** Line writer. Default console.log. */
283
+ write?: (line: string) => void;
284
+ }
285
+ /**
286
+ * Console output. JSON lines (identical to 1.4.0) in production; a compact
287
+ * human-readable tree elsewhere, coloured only on a TTY.
288
+ */
289
+ declare function consoleSink(options?: ConsoleSinkOptions): RuntimeSink;
290
+ interface FileSinkOptions {
291
+ /** Directory for `YYYY-MM-DD.jsonl` files. Default ".autter/runtime" (cwd-relative). */
292
+ dir?: string;
293
+ /** Keep at most this many files (oldest deleted). Default 7. */
294
+ maxFiles?: number;
295
+ /** Start a new `YYYY-MM-DD.N.jsonl` file past this size. Default 10 MiB. */
296
+ maxBytes?: number;
297
+ }
298
+ /**
299
+ * NDJSON on local disk, one record per line, for coding agents and
300
+ * `autter logs --local`. Daily files (UTC), size rotation, bounded file
301
+ * count. Writes are synchronous appends (dev-sized volumes). Disables itself
302
+ * with one warning on read-only or permission-denied filesystems.
303
+ */
304
+ declare function fileSink(options?: FileSinkOptions): RuntimeSink;
305
+ interface MemorySink extends RuntimeSink {
306
+ readonly events: RuntimeEvent[];
307
+ readonly exceptions: CapturedException[];
308
+ clear(): void;
309
+ }
310
+ /** Keeps every record in memory — for tests (`@autter/runtime-node/testing`). */
311
+ declare function memorySink(): MemorySink;
312
+
313
+ export { otlpSink as A, redactAttributes as B, type CapturedException as C, redactText as D, toClientError as E, type FileSinkOptions as F, type MemorySink as M, type OtlpSinkOptions as O, type RuntimeEvent as R, type RuntimeOutcome as a, type RedactOptions as b, type Redactor$1 as c, type RuntimeLogLevel as d, type RuntimeOperationKind as e, type RuntimeSink as f, type RuntimeLogContext as g, type RuntimeCarrier as h, CODE_PATTERN as i, type ClientErrorBody as j, type ConsoleSinkOptions as k, RuntimeError as l, memorySink as m, type RuntimeErrorCatalog as n, type RuntimeErrorDefinition as o, type RuntimeErrorExtras as p, type RuntimeErrorFactory as q, type RuntimeErrorLike as r, type RuntimeErrorOptions as s, type RuntimeLogContextValue as t, type RuntimeSinkContext as u, consoleSink as v, defineRuntimeErrors as w, errorAttributes as x, fileSink as y, isRuntimeErrorLike as z };
@@ -0,0 +1,313 @@
1
+ /**
2
+ * Structural copy of OpenTelemetry's `Attributes` so runtime-core stays
3
+ * dependency-free (it is bundled into the zero-dependency edge package).
4
+ * Assignable both ways with `@opentelemetry/api`'s type.
5
+ */
6
+ type AttributeValue = string | number | boolean | Array<null | undefined | string> | Array<null | undefined | number> | Array<null | undefined | boolean>;
7
+ type Attributes = Record<string, AttributeValue | undefined>;
8
+
9
+ interface RedactOptions {
10
+ /**
11
+ * Extra patterns matched against lower-cased attribute KEYS; a match
12
+ * masks the whole value. Strings become case-insensitive substring
13
+ * patterns. Extends the built-in list.
14
+ */
15
+ additionalKeyPatterns?: (RegExp | string)[];
16
+ /**
17
+ * Extra patterns scrubbed inside string VALUES — attribute values,
18
+ * exception messages, stack traces, span status messages, URLs, log
19
+ * lines. Strings are compiled as case-insensitive regex sources. Every
20
+ * pattern is applied globally. Extends the built-in list.
21
+ */
22
+ additionalValuePatterns?: (RegExp | string)[];
23
+ /** Replacement token. Default "[redacted]". */
24
+ mask?: string;
25
+ /**
26
+ * Scrub email-shaped substrings from ALL string values, not just
27
+ * sensitive keys. Default true.
28
+ */
29
+ scrubEmailValues?: boolean;
30
+ /**
31
+ * Scrub Luhn-valid payment card numbers from all string values.
32
+ * Default true.
33
+ */
34
+ scrubCardNumbers?: boolean;
35
+ }
36
+ /**
37
+ * Return a copy of `attributes` with PII/secrets masked. Never mutates the
38
+ * input; non-string primitives pass through untouched; `undefined` values
39
+ * are dropped (OpenTelemetry rejects them).
40
+ */
41
+ declare function redactAttributes(attributes?: Attributes | null, options?: RedactOptions): Attributes;
42
+ /**
43
+ * Scrub secrets/PII embedded in one string — an error message, a stack
44
+ * trace, a URL, a log line. Same value patterns as redactAttributes().
45
+ */
46
+ declare function redactText(text: string, options?: RedactOptions): string;
47
+ /** A compiled redactor: callable for attribute bags, plus string and
48
+ * export-time helpers. */
49
+ interface Redactor$1 {
50
+ (attributes?: Attributes | null): Attributes;
51
+ /** Scrub one string (messages, stacks, URLs). Identity when disabled. */
52
+ text(value: string): string;
53
+ /**
54
+ * Export-time pass over attributes already on a span (set by any
55
+ * instrumentation, not just Autter's capture calls). Strings are
56
+ * value-scrubbed, string values under sensitive KEYS are masked, and
57
+ * numbers/booleans pass untouched — usage counters such as
58
+ * `ai.usage.promptTokens` must survive for cost tracking.
59
+ */
60
+ exported(attributes: Attributes): Attributes;
61
+ readonly enabled: boolean;
62
+ }
63
+
64
+ type RuntimeLogContextValue = string | number | boolean | null | undefined | RuntimeLogContextValue[] | {
65
+ [key: string]: RuntimeLogContextValue;
66
+ };
67
+ type RuntimeLogContext = Record<string, RuntimeLogContextValue>;
68
+ type RuntimeLogLevel = "debug" | "info" | "warning" | "error";
69
+ type RuntimeOutcome = "succeeded" | "failed" | "degraded" | "cancelled" | "pending";
70
+ type RuntimeOperationKind = "request" | "operation";
71
+
72
+ /**
73
+ * Structured, coded errors shared by every Autter Runtime server SDK.
74
+ *
75
+ * export const billingErrors = defineRuntimeErrors("billing", {
76
+ * declined: { status: 402, message: "Payment declined", expected: true,
77
+ * why: "The card issuer rejected the charge",
78
+ * fix: "Ask the customer for another card" },
79
+ * limit: ({ plan }: { plan: string }) => ({ status: 429, message: `Plan ${plan} limit reached` }),
80
+ * });
81
+ * throw billingErrors.limit({ plan: "free" }); // code "billing.limit"
82
+ *
83
+ * A code groups every occurrence into one issue (scheme "code-v1"), so codes
84
+ * must be stable, namespaced and low-cardinality: never ids, user data or
85
+ * secrets. Anything not matching CODE_PATTERN is dropped and the error
86
+ * groups by message exactly as before.
87
+ */
88
+ /** `namespace.key` with up to four segments, lower-case, max 80 characters. */
89
+ declare const CODE_PATTERN: RegExp;
90
+ interface RuntimeErrorDefinition {
91
+ /** Human-readable message. Safe to show to clients. */
92
+ message: string;
93
+ /** HTTP-ish status. Default 500 when the error reaches a response. */
94
+ status?: number;
95
+ /** Expected business failure (decline, validation): recorded, never an incident. */
96
+ expected?: boolean;
97
+ /** Declared cause, ≤ 1000 chars. Treated as a hypothesis by Autter's RCA. */
98
+ why?: string;
99
+ /** Declared remedy, ≤ 1000 chars. */
100
+ fix?: string;
101
+ /** Docs link, ≤ 500 chars. */
102
+ link?: string;
103
+ }
104
+ interface RuntimeErrorExtras {
105
+ /** Underlying error; becomes `exception.cause.N.*` (max 5 levels). */
106
+ cause?: unknown;
107
+ /** Debug-only details: redacted and attached to the span only, never to logs or client responses. */
108
+ internal?: Record<string, unknown>;
109
+ /** Override the catalog message for this throw. */
110
+ message?: string;
111
+ }
112
+ interface RuntimeErrorOptions extends RuntimeErrorDefinition {
113
+ /** Stable namespaced code, e.g. "inventory.reservation_timeout". */
114
+ code?: string;
115
+ /** Underlying error; becomes `exception.cause.N.*` (max 5 levels). */
116
+ cause?: unknown;
117
+ /** Debug-only details: redacted and attached to the span only, never to logs or client responses. */
118
+ internal?: Record<string, unknown>;
119
+ }
120
+ /** The fields Autter reads from any error (duck-typed). */
121
+ interface RuntimeErrorLike {
122
+ message?: string;
123
+ code?: string;
124
+ why?: string;
125
+ fix?: string;
126
+ link?: string;
127
+ status?: number;
128
+ expected?: boolean;
129
+ }
130
+ declare class RuntimeError extends Error implements RuntimeErrorLike {
131
+ readonly code?: string;
132
+ readonly why?: string;
133
+ readonly fix?: string;
134
+ readonly link?: string;
135
+ readonly status?: number;
136
+ readonly expected?: boolean;
137
+ /** Non-enumerable so JSON.stringify / loggers never serialise it. */
138
+ readonly internal?: Record<string, unknown>;
139
+ constructor(options: RuntimeErrorOptions | string);
140
+ /** Client-safe JSON (what `toClientError` returns, minus the wrapper). */
141
+ toJSON(): Record<string, unknown>;
142
+ }
143
+ type CatalogEntry = RuntimeErrorDefinition | ((args: any) => RuntimeErrorDefinition);
144
+ /** A typed factory for one catalog entry; `.code` is the namespaced code. */
145
+ type RuntimeErrorFactory<E> = E extends (args: infer A) => RuntimeErrorDefinition ? ((args: A, extras?: RuntimeErrorExtras) => RuntimeError) & {
146
+ readonly code: string;
147
+ } : ((extras?: RuntimeErrorExtras) => RuntimeError) & {
148
+ readonly code: string;
149
+ };
150
+ type RuntimeErrorCatalog<C extends Record<string, CatalogEntry>> = {
151
+ readonly [K in keyof C]: RuntimeErrorFactory<C[K]>;
152
+ };
153
+ /**
154
+ * Build typed error factories from a catalog. Each key becomes the code
155
+ * `${namespace}.${key}`; an invalid resulting code is dropped with a
156
+ * one-time warning (the factory still produces a normal RuntimeError).
157
+ */
158
+ declare function defineRuntimeErrors<const C extends Record<string, CatalogEntry>>(namespace: string, catalog: C): RuntimeErrorCatalog<C>;
159
+ /**
160
+ * True for any error carrying Autter's structured fields — a RuntimeError,
161
+ * or ANY object with a string `code`/`why`/`fix`/`link`, a numeric `status`
162
+ * (or `statusCode`) or a boolean `expected`. Existing error classes benefit
163
+ * without being rewritten.
164
+ */
165
+ declare function isRuntimeErrorLike(err: unknown): err is RuntimeErrorLike;
166
+ interface ErrorAttributeOptions {
167
+ /** Also emit `exception.cause.N.*` for the cause chain (default true). */
168
+ causes?: boolean;
169
+ }
170
+ /**
171
+ * Wire attributes for an error: `autter.error.code|why|fix|link|status|expected`
172
+ * and `exception.cause.N.type|message|code` (N = 1..5). Never includes
173
+ * `internal` — see `errorInternal`.
174
+ */
175
+ declare function errorAttributes(err: unknown, options?: ErrorAttributeOptions): Record<string, string | number | boolean>;
176
+ interface ClientErrorBody {
177
+ error: {
178
+ message: string;
179
+ code?: string;
180
+ why?: string;
181
+ fix?: string;
182
+ link?: string;
183
+ requestId?: string;
184
+ };
185
+ }
186
+ /**
187
+ * Client-safe JSON body for an error:
188
+ * `{ error: { message, code?, why?, fix?, link?, requestId? } }`.
189
+ * Never includes `internal`, stacks or causes. The message of an
190
+ * unstructured 5xx error (a plain `throw new Error(...)`) is replaced with a
191
+ * generic one, because it was never written for clients.
192
+ */
193
+ declare function toClientError(err: unknown, requestId?: string): ClientErrorBody;
194
+
195
+ /**
196
+ * One runtime record before it is encoded for any sink: an operation or
197
+ * request summary (`autter.event.type = "operation"`) or a plain log line.
198
+ * `attributes` are already redacted and bounded.
199
+ */
200
+ interface RuntimeEvent {
201
+ /** Epoch milliseconds. */
202
+ time: number;
203
+ level: RuntimeLogLevel;
204
+ message: string;
205
+ attributes: RuntimeLogContext;
206
+ traceId?: string;
207
+ spanId?: string;
208
+ }
209
+
210
+ /**
211
+ * Serialisable link from a producer operation to work it hands off (a queue
212
+ * job, another process): `{ v: 1, op, req?, traceparent? }`. Put it in the
213
+ * job payload; the consumer passes it as `withRuntimeOperation(..., { from })`.
214
+ */
215
+ interface RuntimeCarrier {
216
+ v: 1;
217
+ /** Producer operation id (becomes the consumer's `autter.operation.parent_id`). */
218
+ op: string;
219
+ /** Request id the work belongs to. */
220
+ req?: string;
221
+ /** W3C traceparent of the producer span (consumer links to it). */
222
+ traceparent?: string;
223
+ }
224
+
225
+ /**
226
+ * Where runtime records go. The logger pipeline is
227
+ * `enrich → redact/bound → sinks[]`; each sink receives the same immutable
228
+ * RuntimeEvent. Defaults: `[otlpSink(), consoleSink()]` (+ `fileSink()` when
229
+ * NODE_ENV=development). Sinks must never throw into application code.
230
+ */
231
+ interface RuntimeSink {
232
+ readonly name: string;
233
+ /** Called when the logger is (re)configured; null before init. */
234
+ start?(context: RuntimeSinkContext): void;
235
+ write(event: RuntimeEvent): void;
236
+ flush?(): Promise<void>;
237
+ shutdown?(): Promise<void>;
238
+ /** Records held in memory awaiting delivery. */
239
+ buffered?(): number;
240
+ /** @internal Receives every captureException call (testing sinks). */
241
+ exception?(record: CapturedException): void;
242
+ }
243
+ interface RuntimeSinkContext {
244
+ endpoint: string;
245
+ apiKey: string;
246
+ service: string;
247
+ environment: string;
248
+ release?: string;
249
+ /** SDK identity for the `telemetry.distro.*` resource attributes. */
250
+ distro?: {
251
+ name: string;
252
+ version: string;
253
+ };
254
+ }
255
+ interface CapturedException {
256
+ time: number;
257
+ error: unknown;
258
+ message: string;
259
+ type: string;
260
+ attributes: Record<string, unknown>;
261
+ operationId?: string;
262
+ requestId?: string;
263
+ }
264
+ interface OtlpSinkOptions {
265
+ /** Override the ingester base URL (default: the configured endpoint). */
266
+ endpoint?: string;
267
+ /** Override the ingest key (default: the configured apiKey). */
268
+ apiKey?: string;
269
+ }
270
+ /**
271
+ * OTLP/HTTP JSON export to `${endpoint}/v1/logs`. Bounded exactly like
272
+ * 1.4.0: 1000 records / 4 MiB buffered, 256 KiB per record, batches of 50
273
+ * (≤ 512 KiB), 3 attempts within a 10 s deadline, exponential back-off
274
+ * on failure, undelivered records reported at shutdown.
275
+ */
276
+ declare function otlpSink(options?: OtlpSinkOptions): RuntimeSink;
277
+ interface ConsoleSinkOptions {
278
+ /** Default: "pretty" unless NODE_ENV === "production", then "json". */
279
+ format?: "pretty" | "json";
280
+ /** Colourise pretty output. Default: stdout is a TTY and NO_COLOR is unset. */
281
+ color?: boolean;
282
+ /** Line writer. Default console.log. */
283
+ write?: (line: string) => void;
284
+ }
285
+ /**
286
+ * Console output. JSON lines (identical to 1.4.0) in production; a compact
287
+ * human-readable tree elsewhere, coloured only on a TTY.
288
+ */
289
+ declare function consoleSink(options?: ConsoleSinkOptions): RuntimeSink;
290
+ interface FileSinkOptions {
291
+ /** Directory for `YYYY-MM-DD.jsonl` files. Default ".autter/runtime" (cwd-relative). */
292
+ dir?: string;
293
+ /** Keep at most this many files (oldest deleted). Default 7. */
294
+ maxFiles?: number;
295
+ /** Start a new `YYYY-MM-DD.N.jsonl` file past this size. Default 10 MiB. */
296
+ maxBytes?: number;
297
+ }
298
+ /**
299
+ * NDJSON on local disk, one record per line, for coding agents and
300
+ * `autter logs --local`. Daily files (UTC), size rotation, bounded file
301
+ * count. Writes are synchronous appends (dev-sized volumes). Disables itself
302
+ * with one warning on read-only or permission-denied filesystems.
303
+ */
304
+ declare function fileSink(options?: FileSinkOptions): RuntimeSink;
305
+ interface MemorySink extends RuntimeSink {
306
+ readonly events: RuntimeEvent[];
307
+ readonly exceptions: CapturedException[];
308
+ clear(): void;
309
+ }
310
+ /** Keeps every record in memory — for tests (`@autter/runtime-node/testing`). */
311
+ declare function memorySink(): MemorySink;
312
+
313
+ export { otlpSink as A, redactAttributes as B, type CapturedException as C, redactText as D, toClientError as E, type FileSinkOptions as F, type MemorySink as M, type OtlpSinkOptions as O, type RuntimeEvent as R, type RuntimeOutcome as a, type RedactOptions as b, type Redactor$1 as c, type RuntimeLogLevel as d, type RuntimeOperationKind as e, type RuntimeSink as f, type RuntimeLogContext as g, type RuntimeCarrier as h, CODE_PATTERN as i, type ClientErrorBody as j, type ConsoleSinkOptions as k, RuntimeError as l, memorySink as m, type RuntimeErrorCatalog as n, type RuntimeErrorDefinition as o, type RuntimeErrorExtras as p, type RuntimeErrorFactory as q, type RuntimeErrorLike as r, type RuntimeErrorOptions as s, type RuntimeLogContextValue as t, type RuntimeSinkContext as u, consoleSink as v, defineRuntimeErrors as w, errorAttributes as x, fileSink as y, isRuntimeErrorLike as z };