/** * The watch daemon's log — readable by a human by default, JSON when a machine * is going to read it. * * ── Why this is not just `createLogger()` ──────────────────────────────── * The engine's logger emits JSON to stdout, which is right for a server pod whose * output goes to Loki. This daemon's output goes somewhere different: a file on * the user's own laptop that THEY tail, that `chat-recall doctor` points them at, * and that is the first thing anyone reads when their sync looks wrong. And * `pino-pretty` is not a dependency of this package — the native-free guard keeps * the collector's dependency list minimal — so LOG_PRETTY silently falls back to * JSON here. * * Converting 48 `console.*` calls to JSON would therefore have made the one * surface a user actually reads unreadable, in exchange for structure nothing was * consuming. So: human-readable lines by default, identical in shape to what the * daemon has always printed, and `CHAT_RECALL_LOG_JSON=1` for an operator * shipping to Loki or Vector. * * ── What this buys over console.* ──────────────────────────────────────── * LEVELS `CHAT_RECALL_LOG_LEVEL=warn` silences the routine chatter. There * was no way to turn down a daemon that logs a heartbeat a minute. * STRUCTURE fields travel alongside the message, so the JSON mode is * genuinely parseable rather than a string to regex. * ONE PLACE the timestamp format, the level filter and the destination are * decided once instead of at 48 call sites. */ /** Ordered so a threshold comparison is a number comparison. */ declare const LEVELS: { readonly debug: 10; readonly info: 20; readonly warn: 30; readonly error: 40; }; export type LogLevel = keyof typeof LEVELS; export interface DaemonLog { debug(msg: string, fields?: Record): void; info(msg: string, fields?: Record): void; warn(msg: string, fields?: Record): void; error(msg: string, fields?: Record): void; } export declare const daemonLog: DaemonLog; export {}; //# sourceMappingURL=daemon-log.d.ts.map