/**
 * wireJson — the ONE rule for how an `Error` inside an event reaches a wire.
 *
 * An event payload typed `unknown` (a tool's `result`, a hand-built emit) can
 * carry an `Error` — often one a client library decorated: an axios error
 * carries `config.headers.authorization`, a fetch wrapper the request it made.
 * `JSON.stringify` writes an Error's OWN ENUMERABLE properties and nothing
 * else, so on the synchronous delivery path every sink that serialized an
 * event (the NDJSON file, CloudWatch / AgentCore, the audit export, X-Ray
 * metadata, OTel attributes, the console) wrote that bearer token — while the
 * detached path's `structuredClone` dropped the same properties and wrote
 * `{}`. Two delivery paths, two byte shapes, and the leaky one was the default.
 *
 * The rule, for every Error at any depth: **`{ name, message, code? }` plus a
 * bounded `cause` chain — nothing else.** `code` is kept only when it is a
 * string or a number (the classifier every error vocabulary branches on);
 * `cause` is kept when it is itself an Error (rendered by this rule, at most
 * {@link MAX_CAUSE_DEPTH} deep, a cycle cut) or a primitive; an object cause is
 * dropped for the same reason custom properties are. `stack` is dropped — it
 * was never written (non-enumerable) and it names file paths.
 *
 * Both paths use it, so both write the same bytes:
 *  - SYNCHRONOUS: every serializer of the record writes {@link toWireJson}
 *    instead of `JSON.stringify` — the sinks, the browser stream, the
 *    recording artifact and file sink, the bug-report bundle, the tool-result
 *    text (`test/architecture/wireJsonOnly.test.ts` keeps it that way). A
 *    replacer that reads the HOLDER's raw value, so an Error's own `toJSON`
 *    (a real `AxiosError`'s returns its config and stack) never pre-empts the
 *    rule, and every non-Error value serializes exactly as before.
 *  - DETACHED: `strategies/attach.ts · snapshotEvent` renders Errors with
 *    {@link withWireErrors} BEFORE it clones, so what a detached sink
 *    serializes is already the rendered shape — and a detached sink that does
 *    not serialize receives no Error it could read a custom property off.
 *
 * @example
 * ```ts
 * const err = Object.assign(new Error('upstream 401'), {
 *   code: 'ERR_BAD_REQUEST',
 *   config: { headers: { authorization: 'Bearer …' } },
 * });
 * toWireJson({ result: err });
 * // → '{"result":{"name":"Error","message":"upstream 401","code":"ERR_BAD_REQUEST"}}'
 * ```
 */
/** How many `cause` links are rendered before the chain is cut. */
export declare const MAX_CAUSE_DEPTH = 4;
/** What an Error becomes on a wire. */
export interface WireError {
    readonly name: string;
    readonly message: string;
    readonly code?: string | number;
    readonly cause?: WireError | string | number | boolean;
}
/**
 * Is `value` an Error? True when ANY of three checks says so:
 *  - `Error.isError` (Node ≥ 24, browsers): the internal slot — unspoofable,
 *    across realms; false, by spec, for a Proxy around an Error;
 *  - `instanceof Error`: catches that Proxy (its prototype passes through);
 *  - Node's `util.types.isNativeError`: the internal slot again, so an Error
 *    from another realm (`vm`) is caught on Node 20/22 where `Error.isError`
 *    does not exist. Reached through `process.getBuiltinModule` at call time
 *    (no import: this module ships to browsers, where it is simply absent).
 * The OR makes the answer the same on every runtime the package supports.
 * Never `Object.prototype.toString`: a plain object with
 * `[Symbol.toStringTag]: 'Error'` would pass that brand. Never throws — a
 * revoked Proxy answers `false`.
 */
export declare function isErrorValue(value: unknown): value is Error;
/**
 * Render one Error by the rule. Never throws: a throwing getter, a `message`
 * whose `toString` throws, a revoked Proxy — each reads as absent.
 */
export declare function wireError(error: Error): WireError;
/**
 * The `JSON.stringify` replacer that applies the rule — on the HOLDER's raw
 * value (`this[key]`), not on `value`. `JSON.stringify` calls `toJSON()` before
 * the replacer sees anything, and a real `AxiosError`'s `toJSON` returns its
 * `config` (request headers included) and `stack` as a plain object; a
 * replacer that read `value` would never see the Error at all. The root holder
 * is `{ '': value }`, so a root Error is covered too.
 */
export declare function wireReplacer(this: unknown, key: string, value: unknown): unknown;
/**
 * `JSON.stringify(value)` with every Error rendered by the rule. Same contract
 * otherwise, to the byte: it returns `undefined` for an unserializable root and
 * throws where `JSON.stringify` throws (a cycle, a BigInt) — so a sink keeps
 * its own handling of those.
 *
 * One stated difference in READS, not bytes: to see an Error behind a `toJSON`,
 * an ACCESSOR property (a getter, a Proxy's `get` trap) whose value is an
 * object is read twice, and a getter that answers differently on its second
 * read decides whether an Error is rendered. Data properties and primitives are
 * read once, as `JSON.stringify` reads them.
 */
export declare function toWireJson(value: unknown, space?: number): string;
/**
 * `value` with every Error it holds (in arrays and objects, at any depth up to
 * the walk bound) replaced by its {@link WireError} rendering. A value that
 * holds no Error is returned as the SAME reference — one read-only walk, no
 * allocation, which is every event but the rare one. A value that holds one is
 * copied whole (arrays and objects; everything else by reference), so a cycle
 * lands on the copy, never back on the original that still holds the Error.
 * Arrays, plain and class objects, Maps and Sets are entered; Dates, RegExps
 * and binary data are not. Never throws: a value it cannot read (a revoked
 * Proxy) is left as it is.
 */
export declare function withWireErrors<T>(value: T): T;
//# sourceMappingURL=wireJson.d.ts.map