import type { CadenceConfig, LogFormat, LogLevel } from '@manehorizons/cadence-types'; /** * The structured diagnostic logger (Phase 80, Post-v1.0 observability). * * Additive and default-OFF: writes only to **stderr** (never stdout — that is * the MCP protocol channel and the `--json` CLI channel), and emits nothing * unless a level above `silent` is configured. The write sink and clock are * injectable so tests stay deterministic and the stdout invariant is provable. * * Seams obtain a context-bound logger via `.child({ seam: 'gate' })`. */ /** Runtime dependencies of a {@link Logger}. */ export interface LoggerDeps { level: LogLevel; format: LogFormat; /** Receives one fully-formatted line per emitted record. */ write: (line: string) => void; /** Returns the timestamp stamped on each record (ISO-8601 by convention). */ now: () => string; } export declare class Logger { private readonly deps; private readonly bound; private readonly seam; constructor(deps: LoggerDeps, bound?: Record, seam?: string); /** Derive a child logger with additional bound context. A `seam` in `ctx` * sets/overrides the seam tag; all other keys merge into `fields`. The * parent is never mutated. */ child(ctx: { seam?: string; } & Record): Logger; error(msg: string, fields?: Record): void; warn(msg: string, fields?: Record): void; info(msg: string, fields?: Record): void; debug(msg: string, fields?: Record): void; trace(msg: string, fields?: Record): void; private emit; } /** Options for {@link createLogger}. Anything omitted is resolved from the * environment / sensible defaults. */ export interface CreateLoggerOptions { /** Force the level (skips env/config resolution). */ level?: LogLevel; /** Force the format (skips env/config resolution). */ format?: LogFormat; /** `config.logging.level` for resolution when `level` is not forced. */ configLevel?: LogLevel; /** `config.logging.format` for resolution when `format` is not forced. */ configFormat?: LogFormat; /** Environment source (defaults to `process.env`). */ env?: Record; /** Whether the diagnostic stream is a TTY (defaults to `process.stderr.isTTY`). */ isTTY?: boolean; /** Write sink (defaults to a line-terminated `process.stderr.write`). */ write?: (line: string) => void; /** Clock (defaults to `() => new Date().toISOString()`). */ now?: () => string; } /** Construct a {@link Logger}, resolving level/format via env > config > default. */ export declare function createLogger(opts?: CreateLoggerOptions): Logger; /** The lazily-created process-wide logger. Seams use * `getLogger().child({ seam })`. Phase 81 wires the seams; the entrypoint can * call {@link setLogger} once config is loaded to apply `config.logging`. */ export declare function getLogger(): Logger; /** Replace the process-wide logger (entrypoint config wiring; tests). */ export declare function setLogger(logger: Logger): void; /** Clear the process-wide logger so the next {@link getLogger} rebuilds it. */ export declare function resetLogger(): void; /** * Install the process-wide logger from `config.logging` (Phase 81). Called at * the entrypoints where config is loaded (CLI settle, hook dispatch, MCP serve) * so a persistent `logging` block takes effect. Env vars still win: * {@link createLogger} resolves `CADENCE_LOG_LEVEL`/`CADENCE_LOG_FORMAT` over * the config values passed here. */ export declare function configureLoggerFromConfig(config: Pick): Logger; //# sourceMappingURL=logger.d.ts.map